Commit f6b66695 authored by beisir's avatar beisir

Merge branch 'master' into feature-afterSalesRefund

parents b847690b 8ebe9dd6
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const isPre = process.env.PRE_ENV === 'pre'; const isPre = process.env.PRE_ENV === 'pre';
const environment = 'yxm2'; const environment = 'xyqb';
const envAPi = { const envAPi = {
api: `https://security-${environment}.liangkebang.net`, //'https://security-xyqb.liangkebang.net', api: `https://security-${environment}.liangkebang.net`, //'https://security-xyqb.liangkebang.net',
kdspOpApi: `https://sc-merchant-api-${environment}.liangkebang.net`, kdspOpApi: `https://sc-merchant-api-${environment}.liangkebang.net`,
...@@ -9,7 +9,7 @@ const envAPi = { ...@@ -9,7 +9,7 @@ const envAPi = {
querysApi: `https://sc-merchant-api-${environment}.liangkebang.net/admin/merchant/sc-settlement`, querysApi: `https://sc-merchant-api-${environment}.liangkebang.net/admin/merchant/sc-settlement`,
prologueDomain: `https://mall-${environment}.liangkebang.net`, prologueDomain: `https://mall-${environment}.liangkebang.net`,
qiniuHost: 'https://kdspstatic.q-gp.com/', qiniuHost: 'https://kdspstatic.q-gp.com/',
opapiHost: `https://opapi-${environment}.liangkebang.net`, opapiHost: `https://gw.yxmie.com`,
wsApi: `wss://push-${environment}.liangkebang.net`, wsApi: `wss://push-${environment}.liangkebang.net`,
msgApi: `https://msgapi-${environment}.liangkebang.net`, msgApi: `https://msgapi-${environment}.liangkebang.net`,
}; };
......
import React, { useEffect, useRef, useState } from 'react';
import { Select, Space, Divider, Input, Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import styles from './index.less';
const CustomSelect = props => {
const [name, setName] = useState('');
const [items, setItems] = useState([]);
const inputRef = useRef(null);
const onNameChange = e => {
setName(e.target.value);
};
const addItem = e => {
e.preventDefault();
const v = name.trim();
if (v) {
setItems([...items, { name: v }]);
setName('');
setTimeout(() => {
// eslint-disable-next-line no-unused-expressions
inputRef.current?.focus();
}, 0);
}
};
const onChange = e => {
props.onChange(e);
};
useEffect(() => {
setItems(props.options);
}, [props.options]);
return (
<Select
mode={props.mode}
maxTagTextLength={8}
allowClear
value={props.value}
onChange={onChange}
dropdownRender={menu => (
<>
{menu}
{props.isCustom && (
<>
<Divider className={styles.SelectDivider} />
<Space className={styles.SelectSpace}>
<Input
className={styles.SelectInput}
placeholder="请输入自定义属性"
ref={inputRef}
value={name}
maxLength={30}
onChange={onNameChange}
/>
<Button type="primary" icon={<PlusOutlined />} onClick={addItem} />
</Space>
</>
)}
</>
)}
options={items.map(item => ({ label: item.name, value: JSON.stringify(item) }))}
></Select>
);
};
export default CustomSelect;
.SelectDivider {
margin: 8px 0;
}
.SelectSpace {
width: 100%;
padding: 0 8px 4px;
:global {
.ant-space-item:first-child {
width: 100%;
}
}
}
.SelectInput {
width: 100%;
}
...@@ -98,6 +98,7 @@ const Complex = props => { ...@@ -98,6 +98,7 @@ const Complex = props => {
setLoading(true); setLoading(true);
const res = await apiGetBussinessMsgList(data, params); const res = await apiGetBussinessMsgList(data, params);
setLoading(false); setLoading(false);
if (!res) return;
if (res.code !== '0000') { if (res.code !== '0000') {
notification.error(res.msg); notification.error(res.msg);
return; return;
......
...@@ -149,6 +149,7 @@ const Simple = props => { ...@@ -149,6 +149,7 @@ const Simple = props => {
setLoading(true); setLoading(true);
const res = await apiGetBussinessMsgList(data, params); const res = await apiGetBussinessMsgList(data, params);
setLoading(false); setLoading(false);
if (!res) return;
if (res.code !== '0000') { if (res.code !== '0000') {
notification.error(res.msg); notification.error(res.msg);
return; return;
......
/* eslint-disable no-param-reassign */
import { Form, Select, Input, InputNumber, Button } from 'antd';
import React, { Component } from 'react';
// import styles from '../style.less';
const { Option } = Select;
const FormItem = Form.Item;
class goodsManage extends Component {
formRef = React.createRef();
componentDidMount() {
this.props.onRef(this);
}
setFiled = flag => {
const form = this.formRef.current;
if (flag === 'firstKeys') {
form.setFieldsValue({ firstSpecValue: '' });
return;
}
form.setFieldsValue({ secondSpecValue: '' });
};
batchSetting = () => {
const { editData, isEdit } = this.props;
const form = this.formRef.current;
const data = form.getFieldsValue();
if (!data.firstSpecValue && !data.secondSpecValue) {
editData.forEach(item => {
item.marketPrice = data.marketPrice;
// if (!isEdit) item.productStock = data.productStock; // 编辑状态不可修改库存
item.productStock = data.productStock;
item.supplyPrice = data.supplyPrice;
item.weight = data.weight;
item.productStockWarning = data.productStockWarning;
});
}
if (data.firstSpecValue && !data.secondSpecValue) {
editData.forEach(item => {
if (item.firstSpecValue === data.firstSpecValue) {
item.marketPrice = data.marketPrice;
item.productStock = data.productStock;
item.supplyPrice = data.supplyPrice;
item.weight = data.weight;
item.productStockWarning = data.productStockWarning;
}
});
}
if (!data.firstSpecValue && data.secondSpecValue) {
editData.forEach(item => {
if (item.secondSpecValue === data.secondSpecValue) {
item.marketPrice = data.marketPrice;
item.productStock = data.productStock;
item.supplyPrice = data.supplyPrice;
item.weight = data.weight;
item.productStockWarning = data.productStockWarning;
}
});
}
if (data.firstSpecValue && data.secondSpecValue) {
editData.forEach(item => {
if (
item.firstSpecValue === data.firstSpecValue &&
item.secondSpecValue === data.secondSpecValue
) {
item.marketPrice = data.marketPrice;
item.productStock = data.productStock;
item.supplyPrice = data.supplyPrice;
item.weight = data.weight;
item.productStockWarning = data.productStockWarning;
}
});
}
this.props.batchSetting(editData);
};
render() {
const {
firstSpes = [],
secondSpecs = [],
firstSpesName = '',
secondSpesName = '',
productType,
isEdit,
isService,
} = this.props;
return (
<Form layout="inline" ref={this.formRef}>
<FormItem name="firstSpecValue">
<Select allowClear style={{ width: 120 }} placeholder={firstSpesName}>
{firstSpes.length > 0 &&
firstSpes.map(
item =>
item &&
typeof item === 'string' && (
<Option key={item} value={item}>
{item}
</Option>
),
)}
</Select>
</FormItem>
<FormItem name="secondSpecValue">
<Select allowClear style={{ width: 120 }} placeholder={secondSpesName}>
{secondSpecs.length &&
secondSpecs.map(
item =>
item &&
typeof item === 'string' && (
<Option key={item} value={item}>
{item}
</Option>
),
)}
</Select>
</FormItem>
<FormItem name="supplyPrice">
<Input placeholder="供货价" style={{ width: 100 }} />
</FormItem>
<FormItem name="marketPrice">
<Input placeholder="市场价" style={{ width: 100 }} />
</FormItem>
{/* <FormItem>
{getFieldDecorator('salePrice', {})(
<Input placeholder="销售价" style={{ width: 100 }} />,
)}
</FormItem> */}
{productType === 1 && (
<FormItem name="weight">
<InputNumber
precision={3}
max={999999.999}
// eslint-disable-next-line radix
placeholder="重量"
style={{ width: 130 }}
/>
</FormItem>
)}
<FormItem name="productStock">
<InputNumber
precision={0}
step={1}
// eslint-disable-next-line radix
formatter={val => parseInt(val, '10') || ''}
placeholder="库存"
style={{ width: 100 }}
/>
</FormItem>
{productType === 1 && (
<FormItem name="productStockWarning">
<InputNumber
placeholder="库存预警"
maxLength={5}
min={0}
precision={0}
style={{ width: 100 }}
/>
</FormItem>
)}
<FormItem>
<Button type="primary" htmlType="submit" onClick={this.batchSetting} disabled={isService}>
批量设置
</Button>
</FormItem>
</Form>
);
}
}
export default goodsManage;
import { Row, Col, Button } from 'antd';
import React, { Component } from 'react';
import styles from '../style.less';
// eslint-disable-next-line react/prefer-stateless-function
class ButtonGroup extends Component {
render() {
const { initData, confirmLoading } = this.props;
return (
<Row type="flex" justify="center" align="middle" gutter={20}>
<Col>
<Button type="primary" onClick={() => this.props.onCancel()} className={styles.logBtn}>
取消
</Button>
</Col>
<Col key="submit">
<Button
type="primary"
onClick={() => this.props.confirm()}
className={styles.logBtn}
loading={confirmLoading}
disabled={confirmLoading}
>
提交
</Button>
</Col>
{initData && !Object.keys(initData).length && (
<Col key="submit-add">
<Button
type="primary"
onClick={() => this.props.confirm(true)}
className={styles.logBtn}
loading={confirmLoading}
disabled={confirmLoading}
>
提交并继续添加
</Button>
</Col>
)}
</Row>
);
}
}
export default ButtonGroup;
/* eslint-disable no-param-reassign */
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import {
MinusCircleOutlined,
PlusOutlined,
RestOutlined,
DownOutlined,
UpOutlined,
} from '@ant-design/icons';
import {
Modal,
Table,
Button,
Select,
Input,
Row,
Col,
Checkbox,
notification,
Cascader,
Popover,
Card,
Radio,
} from 'antd';
import React, { Component } from 'react';
import SuperSelect from 'antd-virtual-select';
import _ from 'lodash';
import ButtonGroup from './buttonGroup';
import {
normFile,
editColumns,
specValidate,
dataInit,
validateSpuInfo,
createEditData,
} from './mixin';
import {
getSpecList,
getJdPicList,
getBrandList,
addGoods,
editGoods,
queryAllAfterAddress,
apiGetAttribute,
} from '../service';
import styles from '../style.less';
import Upload from '../../components/sortablUpload';
import BatchSetting from './batchSetting';
import SkuNameChange from './skuNameChange';
import { productTypeList } from '../staticdata';
const FormItem = Form.Item;
const { Option } = Select;
class goodsManage extends Component {
state = {
// step: 1,
// editStep: 1,
categoryId: null, // 类目选择
specList: [], // 规格
normalBrandList: [], // 品牌
brandList: [], // 虚拟商品的 品牌
editData: [], // sku表格
createData: {}, // 返显
count: -1, // 规格值起始序号+1
colorImg: {}, // 一级规格是颜色时,color: [imgList]
initForm: {}, // 返显
isCancel: false,
initCascader: null,
batchDeleteImgObj: {},
editRow: {},
editRowIndex: null,
skuNameVisible: false,
productType: 1,
confirmLoading: false,
afterAddressList: {},
// isAttrLoading: false,
categoryAttrs: [], // 获取类目下属性
};
componentDidMount() {
this.getSpecData();
this.getBrandData();
this.getAfterAddressData();
const { initData = {} } = this.props;
const isEdit = Object.keys(initData).length !== 0;
if (isEdit) {
this.getAttribute(
initData.thirdCategoryId || initData.secondCategoryId || initData.firstCategoryId,
);
}
}
// componentWillReceiveProps(nextProps) {
// if (nextProps.visible && !this.state.isAttrLoading) {
// this.setState({
// isAttrLoading: true,
// });
// }
// this.setState({ isCancel: false });
// }
// 获取售后地址
getAfterAddressData = async () => {
const data = await queryAllAfterAddress();
if (data) {
this.setState({ afterAddressList: data.data.records });
}
};
// 获取规格列表
getSpecData = async () => {
try {
const { data } = await getSpecList();
if (data) {
this.setState({ specList: data });
}
} catch (e) {
console.log(e);
}
};
inputChange = (value, key, index) => {
this.setState(prev => {
prev.editData[index][key] = value;
return { editData: prev.editData };
});
};
// eslint-disable-next-line consistent-return
getJdPicList = async row => {
// 获取图片需要设置轮播图和详情图
const {
form: { setFieldsValue, getFieldsValue },
} = this.props;
const { detailImageList = [] } = getFieldsValue(['detailImageList']);
if (!row.skuLink) {
return notification.warning({ message: '请输入京东链接再获取图片' });
}
const { firstSpecId, firstSpecValue, secondSpecId, secondSpecValue, skuLink } = row;
const data = await getJdPicList({
firstSpecId,
firstSpecValue,
secondSpecId,
secondSpecValue,
skuLink,
jdSkuInfoUrl: row.skuLink,
});
if (!data) return false;
const detailList = data.detailList || [];
const { colorImg, editData } = this.state;
colorImg[data.firstSpecValue] = colorImg[data.firstSpecValue]
? colorImg[data.firstSpecValue].concat(data.carouseList || [])
: data.carouseList || [];
editData.forEach(i => {
i.imageList = colorImg[i.firstSpecValue];
return i;
});
this.setState(
() => ({ colorImg, editData }),
() => {
setFieldsValue({
[`imageList[${data.firstSpecValue}]`]: this.state.colorImg[data.firstSpecValue],
detailImageList: [...detailImageList, ...detailList],
});
},
);
};
changeName = name => {
const { editData } = this.state;
editData[this.state.editRowIndex].name = name;
this.setState({ editData, skuNameVisible: false });
};
openSkuNameModal = (row, index) => {
this.setState({
editRowIndex: index,
editRow: row,
skuNameVisible: true,
});
};
getBrandData = async () => {
try {
const { data } = await getBrandList();
const list = data && data.filter(item => item.name === '虚拟商品');
this.setState({ normalBrandList: data, brandList: list });
} catch (e) {
console.log(e);
}
};
changeStep = () => {
const {
form: { setFieldsValue },
initData,
} = this.props;
initData.editData.forEach(item => {
item.third = item.thirdSkuNo;
});
if (Object.keys(initData).length) {
this.setState({
initForm: initData,
editData: initData.editData,
productType: initData.productType,
});
setFieldsValue({
detailImageList: initData.detailImageList || [],
imageList: initData.imageList || {},
});
}
};
// 选择规格
specChange = (flag, specName) => {
const { initForm } = this.state;
if (flag === 'first') {
initForm.firstSpecName = specName;
this.setState({ initForm });
return;
}
initForm.secondSpecName = specName;
this.setState({ initForm });
};
// 获取属性
getAttribute = async categoryId => {
const res = await apiGetAttribute(categoryId);
let categoryAttrs = [];
if (res && res.data && res.data.length) {
categoryAttrs = res.data;
}
this.setState({
categoryAttrs,
});
};
treeChange = value => {
const cid = value[value.length - 1];
this.setState({ categoryId: cid, initCascader: value });
if (value.length === 3) {
this.getAttribute(cid);
}
};
remove = (flag, k) => {
const { form } = this.props;
const keys = form.getFieldValue(flag);
if (flag === 'firstKeys') {
form.setFieldsValue(
{
firstKeys: keys.filter(key => key !== k),
},
() => {
const firstKeys = form.getFieldValue('firstKeys');
const first = form.getFieldValue('first');
form.setFieldsValue({
first: _.pick({ first, firstKeys }),
});
},
);
this.BatchSetting.setFiled(flag);
return;
}
form.setFieldsValue(
{
secondKeys: keys.filter(key => key !== k),
},
() => {
const secondKeys = form.getFieldValue('secondKeys');
const second = form.getFieldValue('second');
form.setFieldsValue({
second: _.pick({ second, secondKeys }),
});
},
);
this.BatchSetting.setFiled(flag);
};
add = flag => {
const { form } = this.props;
if (flag === 'firstKeys' && !form.getFieldValue('firstSpecId')) {
notification.error({
message: '请先选择一级规格数据',
});
return;
}
if (flag === 'secondKeys' && !form.getFieldValue('secondSpecId')) {
notification.error({
message: '请先选择二级规格数据',
});
return;
}
const keys = form.getFieldValue(flag);
const nextKeys = keys.concat(+this.state.count + 1);
this.setState(prev => ({ count: +prev.count + 1 }));
if (flag === 'firstKeys') {
form.setFieldsValue({
firstKeys: nextKeys,
});
return;
}
form.setFieldsValue({
secondKeys: nextKeys,
});
};
imgChange = (data, spec) => {
const { colorImg } = this.state;
colorImg[spec] = data;
this.setState({ colorImg });
this.setState(prev => ({
editData: prev.editData.map(item => {
if (`${item.firstSpecValue}` === spec) {
item.imageList = prev.colorImg[spec];
}
return item;
}),
}));
};
batchSet = editData => {
this.setState({ editData });
};
pullImg = (data, spec) => {
this.imgChange(data, spec);
const { form } = this.props;
form.setFieldsValue({
[`imageList[${spec}]`]: data,
});
};
createShopInfo = isEdit => {
const {
form: { getFieldsValue },
initData,
} = this.props;
const values = getFieldsValue();
const editData = createEditData(values, initData);
this.setState({ editData });
};
deleteImg = () => {
const {
form: { setFieldsValue },
} = this.props;
const { batchDeleteImgObj, colorImg, editData } = this.state;
const deleteKeys = Object.keys(batchDeleteImgObj);
deleteKeys.map(spec => {
if (batchDeleteImgObj[spec]) {
batchDeleteImgObj[spec] = false;
if (spec === 'detailImageList') {
setFieldsValue({
detailImageList: [],
});
return false;
}
if (spec === 'commonImageList') {
setFieldsValue({
commonImageList: [],
});
return false;
}
colorImg[spec] = [];
editData.map(item => {
if (item.firstSpecValue === spec) {
item.imageList = [];
}
return item;
});
setFieldsValue({
[`imageList[${spec}]`]: [],
});
}
return spec;
});
this.setState({ colorImg, editData, batchDeleteImgObj });
};
chooseRollImg = spec => {
this.setState(state => {
state.batchDeleteImgObj[spec] = !state.batchDeleteImgObj[spec];
return { batchDeleteImgObj: state.batchDeleteImgObj };
});
};
deal = attr => {
try {
const json = JSON.parse(attr);
if (typeof json === 'object' && this.checkInAttrList(json.attributeValueId)) {
return json;
}
return { attributeValueName: json };
} catch {
return { attributeValueName: attr };
}
};
// 最终提交
confirm = async isContinue => {
const {
form: { validateFields },
initData,
specListData,
} = this.props;
const { editData, productType } = this.state;
validateFields(async (errors, values) => {
console.log('values :>> ', values);
if (!values.afterAddressId) {
notification.error({
message: '请选择售后地址',
});
}
let imgErr = false;
if (!errors) {
if (validateSpuInfo(values, initData, editData, productType)) return;
editData.forEach(item => {
item.productStockWarning = item.productStockWarning < 0 ? 0 : item.productStockWarning;
if (!item.imageList || !item.imageList.length) {
item.imageList = values.commonImageList || [];
}
if (!item.imageList || !item.imageList.length) {
imgErr = true;
}
});
// 虚拟商品时不校验必 滑动图不全,请检查!
if (imgErr && productType === 1) {
notification.error({ message: '滑动图不全,请检查!' });
return;
}
const specs = [];
specListData.forEach(item => {
if (values.hasOwnProperty(item.specId)) {
specs.push({
specId: item.specId,
specValues: values[item.specId] || [],
});
}
});
const attributeApplyList = [];
let isMaxLength = false;
if (values.attributeApplyList && values.attributeApplyList.length) {
values.attributeApplyList.forEach(item => {
const key = Object.keys(item)[0];
let attrs = item[key];
if (Array.isArray(item[key])) {
attrs = [];
item[key].forEach(attr => {
const json = this.deal(attr);
if (!json) {
return;
}
// eslint-disable-next-line no-unused-expressions
json.attributeValueName.length > 30 && (isMaxLength = true);
attrs.push(json);
});
} else {
const json = this.deal(item[key]);
if (!json) {
return;
}
// eslint-disable-next-line no-unused-expressions
json.attributeValueName.length > 30 && (isMaxLength = true);
attrs = [json];
}
attributeApplyList.push({
attributeId: key.replace('attr', ''),
attributeApplyValueList: attrs,
});
});
if (isMaxLength) {
notification.error({
message: '自定义属性不能超过30个字符',
});
return;
}
}
await this.setState(prev => ({
confirmLoading: true,
createData: {
id: initData.id || '',
name: values.name,
items: prev.editData,
brandId: values.brandId,
supplierId: null,
detailImageList: values.detailImageList,
commonImageList: values.commonImageList || [],
categoryId: prev.categoryId ? prev.categoryId : initData?.thirdCategoryId,
// productType: values.productType,
type: values.productType,
specs,
character: values.character,
afterAddressId: values.afterAddressId,
attributeApplyList,
},
}));
const data = initData.id
? await editGoods(this.state.createData)
: await addGoods(this.state.createData);
if (data.businessCode === '0000') {
notification.success({
message: '商品保存成功!',
});
this.props.query();
if (isContinue) {
this.setState({
editData: [], // sku表格
createData: {}, // 返显
count: -1, // 规格值起始序号+1
colorImg: {}, // 一级规格是颜色时,color: [imgList]
initForm: {}, // 返显
confirmLoading: false,
initCascader: null,
});
this.props.form.resetFields();
return;
}
this.onCancel();
}
this.setState({
confirmLoading: false,
});
}
});
};
onCancel = () => {
this.setState(
{
categoryId: null, // 类目选择
editData: [], // sku表格
createData: {}, // 返显
count: -1, // 规格值起始序号+1
colorImg: {}, // 一级规格是颜色时,color: [imgList]
initForm: {}, // 返显
isCancel: true,
initCascader: null,
productType: 1,
},
() => {
this.BatchSetting.formRef.current.resetFields();
this.props.form.resetFields();
this.props.onCancel();
},
);
};
bundleRadioChange = event => {
this.setState({
categoryId: null, // 类目选择
editData: [], // sku表格
createData: {}, // 返显
count: -1, // 规格值起始序号+1
colorImg: {}, // 一级规格是颜色时,color: [imgList]
initForm: {}, // 返显
isCancel: true,
initCascader: null,
productType: event.target.value,
});
this.props.form.resetFields();
this.BatchSetting.formRef.current.resetFields();
};
/**
* 获取下拉框类型
* supportCustomValue:是否支持自定义:1 是 0 否
* optionType:选项类型:1 单选 2 多选
*/
getMode = (supportCustomValue, optionType) => {
if (+supportCustomValue.code === 1) {
return 'tags';
}
if (+optionType.code === 2) {
return 'multiple';
}
return 'default';
};
// 验证是否失效属性(已失效的商品不显示)
checkInAttrList = id =>
this.state.categoryAttrs.some(item => item.valueList.some(v => +v.id === +id));
// 获取初始化属性数据
getInitAttrValue = (id, supportCustomValue, optionType) => {
const skuAttr = this.props.initData.productAttributeApplyList?.productAttributeApplyList || [];
const v = skuAttr.filter(item => id === item.productAttributeId);
if (
v.length &&
v[0].productAttributeApplyValueList &&
v[0].productAttributeApplyValueList.length
) {
const values = [];
v[0].productAttributeApplyValueList.forEach(attr => {
if (+attr.attributeValueId) {
if (this.checkInAttrList(attr.attributeValueId)) {
values.push(
JSON.stringify({
attributeValueId: attr.attributeValueId,
attributeValueName: attr.attributeValueName,
}),
);
}
} else {
values.push(attr.attributeValueName);
}
return values;
});
if (+supportCustomValue.code === 1 || +optionType.code === 2) {
return values;
}
if (v[0].productAttributeApplyValueList.length) {
const atvalue = v[0].productAttributeApplyValueList[0];
if (this.checkInAttrList(atvalue.attributeValueId)) {
return JSON.stringify({
attributeValueId: atvalue.attributeValueId,
attributeValueName: atvalue.attributeValueName,
});
}
}
return '';
}
if (+supportCustomValue.code === 1 || +optionType.code === 2) {
return [];
}
return '';
};
validateToInputName = (rule, value, callback) => {
if (value.trim().length < 2) {
callback(new Error('商品名称不可小于2个字符'));
}
callback();
};
render() {
const { visible, form, initData = {}, treeData, virtualTreeData, specListData } = this.props;
const isEdit = Object.keys(initData).length !== 0;
// 是否仅编辑卖点和服务
const isService = initData.state && initData.state !== 4;
const { getFieldDecorator, getFieldsValue } = form;
getFieldDecorator('firstKeys', { initialValue: [] });
getFieldDecorator('secondKeys', { initialValue: [] });
const { first = [], second, commonImageList, firstKeys, secondKeys, name } = getFieldsValue();
const isFirstSame = specValidate(first, initData.firstSpecList, initData.id);
const isSecondSame = specValidate(second, initData.secondSpecList, initData.id);
if (isFirstSame) first.pop();
if (isSecondSame) second.pop();
let colorKeys = isEdit
? initData?.firstSpecList?.concat(first || this.state.initForm.first || [])
: first || this.state.initForm.first || [];
if (isEdit && !Object.keys(this.state.initForm).length && !this.state.isCancel) {
this.changeStep(1);
}
const isJDGoods = initData.id && initData.pageProductType && +initData.pageProductType !== 1;
const initCascader = isEdit
? [initData.firstCategoryId, initData.secondCategoryId, initData.thirdCategoryId]
: this.state.initCascader;
const formItemLayout = {
labelCol: {
span: 5,
},
};
const formItemProduct = {
labelCol: { span: 2 },
wrapperCol: { span: 22 },
};
const formItemAttr = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const {
colorImg,
productType,
normalBrandList,
brandList,
confirmLoading,
afterAddressList,
} = this.state;
const skuSpeFirstKeys = initData.firstSpecList || [];
const skuSpeSecondKeys = initData.secondSpecList || [];
const skuOldAttr = initData.productAttributeApplyList?.oldProductAttributeApplyList || [];
const treeDataArray = productType === 2 ? virtualTreeData : treeData;
const brandListArray = productType === 2 ? brandList : normalBrandList;
dataInit(this.state.editData);
const filterOption = (input, op) => op.props.children.includes(input);
// ---------------------驳回编辑规格时候,过滤掉colors中为null的数据---------------------
if (isEdit && !initData.editData[0]?.firstSpec && !initData.editData[0]?.secondSpec) {
colorKeys = colorKeys.length > 1 ? colorKeys.filter(item => item !== 'null') : colorKeys;
}
return (
<Modal
title={initData.id ? '修改商品' : '新增商品'}
visible={visible}
footer={null}
onCancel={this.onCancel}
width="1050px"
bodyStyle={{ background: 'rgb(247 249 249)' }}
>
<Form name="horizontal_login">
<div>
<Card className={styles.card} bordered={false}>
<Row type="flex" gutter={24}>
<Col span={24}>
<Form.Item label="商品类型:" {...formItemProduct}>
{getFieldDecorator('productType', {
initialValue: productType,
rules: [{ required: true, message: '请选择商品类型' }],
})(
<Radio.Group disabled={isEdit || isService} onChange={this.bundleRadioChange}>
{productTypeList.map(item => (
<Radio key={item.value} value={item.value} disabled={item.disabled}>
{item.label}
</Radio>
))}
</Radio.Group>,
)}
</Form.Item>
</Col>
<Col span={24}>
<FormItem label="类目:" {...formItemProduct}>
{getFieldDecorator('categoryId', {
initialValue: initCascader,
rules: [
{
required: true,
message: '请选择类目',
},
],
})(
<Cascader
style={{ width: 690 }}
changeOnSelect
showSearch
placeholder="请选择类目,支持模糊搜索"
fieldNames={{ label: 'name', value: 'id', children: 'children' }}
options={treeDataArray}
onChange={(val, label, ext) => this.treeChange(val, label, ext)}
disabled={isService}
/>,
)}
</FormItem>
</Col>
</Row>
</Card>
<Card className={styles.card} bordered={false}>
<Row
gutter={10}
style={{ background: '#fff', borderRadius: '6px', padding: '20px 0 5px 0' }}
>
<Col span={10}>
<FormItem label="商品品牌:" {...formItemLayout}>
{getFieldDecorator('brandId', {
initialValue: this.state.initForm.brandId,
rules: [
{
required: true,
message: '请选择商品品牌',
},
],
})(
<Select
allowClear
showSearch
style={{ width: 280 }}
filterOption={filterOption}
placeholder="请选择商品品牌,支持模糊搜索"
disabled={isService}
>
{brandListArray?.length &&
brandListArray.map(item => (
<Option key={item.id} value={item.id}>
{item.name}
</Option>
))}
</Select>,
)}
</FormItem>
</Col>
<span style={{ display: 'inline-block', lineHeight: '35px', color: '#999' }}>
若需新增品牌请联系业务员
</span>
</Row>
<Row type="flex">
<Col span={24}>
<Popover content={name} trigger="hover">
<FormItem label="商品名称:" labelCol={{ span: 2 }}>
{getFieldDecorator('name', {
initialValue: initData.name,
validateTrigger: ['onBlur'],
rules: [
{
required: true,
message: '请输入商品名称',
},
{
validator: this.validateToInputName,
},
],
})(
<Input
style={{ width: 690 }}
maxLength={100}
placeholder="请输入商品名称"
allowClear
disabled={isService}
/>,
)}
</FormItem>
</Popover>
{isJDGoods && (
<div className={styles.warning}>
*本列表的商品名称仅供搜索使用,不在前端作展示。若要修改APP端展示的商品名称,请在商品信息中修改。
</div>
)}
</Col>
<Col span={24}>
<FormItem label="商品卖点:" labelCol={{ span: 2 }}>
{getFieldDecorator('character', {
initialValue: initData.character,
rules: [
{
required: true,
message: '请输入商品卖点',
},
],
})(
<Input
style={{ width: 690 }}
maxLength={50}
placeholder="卖点最优可填写3个词,12个字。前后用空格加竖杠分隔,例: 莹莹剔透 | 粒粒优选 | 易煮易熟"
allowClear
/>,
)}
</FormItem>
</Col>
<Col span={10}>
<FormItem label="售后地址" {...formItemLayout}>
{getFieldDecorator('afterAddressId', {
initialValue: this.state.initForm.afterAddressId,
rules: [
{
required: true,
message: '请选择售后地址',
},
],
})(
<Select allowClear style={{ width: 280 }} placeholder="请选择售后地址">
{afterAddressList?.length &&
afterAddressList.map(item => (
<Option key={item.id} value={item.id}>
{item.addressName}
</Option>
))}
</Select>,
)}
</FormItem>
</Col>
{specListData.length
? specListData.map((item, index) => (
<Col key={item.specId} span={24}>
<FormItem label={item.specName} labelCol={{ span: 2 }}>
{getFieldDecorator(`${item.specId}`, {
initialValue: initData[item.specId],
})(<Checkbox.Group options={item.specValues} />)}
</FormItem>
</Col>
))
: ''}
</Row>
</Card>
{/* 商品属性 */}
<Card className={styles.card} bordered={false}>
<div className={styles.cardTitle}>商品属性</div>
<div
className={styles.attrbox + (this.state.isMore ? styles.attrboxMore : '')}
more={this.state.isMore}
>
<Row>
{this.state.categoryAttrs.length > 0 &&
this.state.categoryAttrs.map((k, i) => (
<Col span={12} key={k.id}>
<FormItem label={k.name} {...formItemAttr} key={k.id}>
{getFieldDecorator(`attributeApplyList[${i}]['attr${k.id}']`, {
initialValue: this.getInitAttrValue(
k.id,
k.supportCustomValue,
k.optionType,
), // +k.supportCustomValue.code === 1 || +k.optionType.code === 2 ? [] : '',
validateTrigger: ['onChange'],
rules:
+k.required.code === 1
? [
{
required: true,
type:
+k.supportCustomValue.code === 1 || +k.optionType.code === 2
? 'array'
: 'string',
message: '请选择',
},
]
: [],
})(
<Select
mode={this.getMode(k.supportCustomValue, k.optionType)}
maxTagTextLength={8}
allowClear
>
{k.valueList &&
k.valueList.length &&
k.valueList.map(a => (
<Option
key={a.id}
value={JSON.stringify({
attributeValueId: a.id,
attributeValueName: a.name,
})}
>
{a.name}
</Option>
))}
</Select>,
)}
</FormItem>
</Col>
))}
</Row>
</div>
{this.state.categoryAttrs.length > 12 && (
<div>
<Button
type="link"
onClick={() =>
this.setState(state => ({
isMore: !state.isMore,
}))
}
>
{this.state.isMore ? '收起' : '展示更多'}
{this.state.isMore ? <UpOutlined /> : <DownOutlined />}
</Button>
</div>
)}
{skuOldAttr.length > 0 && (
<div>
<Row>注:以下商品属性已失效,请使用新的属性</Row>
<Row>
{skuOldAttr.map(s => (
<Col span={12} key={s.id}>
<FormItem
label={s.productAttributeName}
{...formItemAttr}
required={false}
key={s.id}
>
{s.productAttributeApplyValueList
.map(item => item.attributeValueName)
.join('')}
</FormItem>
</Col>
))}
</Row>
</div>
)}
</Card>
<Card className={styles.card} bordered={false}>
<Row>
<FormItem label="一级规格">
{getFieldDecorator('firstSpecId', {
initialValue: this.state.initForm.firstSpecId,
})(
<Select
allowClear
showSearch
style={{ width: 200 }}
placeholder="请选择一级规格"
disabled={(isEdit && initData.firstSpecId) || isService}
onChange={(val, option) =>
this.specChange('first', option?.props.children, val)
}
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{this.state.specList.length &&
this.state.specList.map(item => (
<Option value={item.specId} key={item.specId}>
{item.specName}
</Option>
))}
</Select>,
)}
</FormItem>
</Row>
<Row type="flex">
{skuSpeFirstKeys.length > 0 &&
skuSpeFirstKeys.map(
k =>
k !== 'null' && (
<Input
key={k}
value={k}
disabled
placeholder="请输入规格名称"
style={{ width: '15%', margin: '5px 5px 28px 5px' }}
/>
),
)}
{firstKeys.map(k => (
<FormItem label="" required={false} key={k}>
{getFieldDecorator(`first[${k}]`, {
initialValue: this.state.initForm.first && this.state.initForm.first[k],
validateTrigger: ['onChange', 'onBlur'],
rules: [
{
required: true,
message: '请输入',
},
],
})(
<Input
key={k}
placeholder="请输入规格名称"
style={{ width: '60%', marginRight: 8 }}
/>,
)}
{firstKeys.length > 0 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ marginBottom: 0 }}
onClick={() => this.remove('firstKeys', k)}
/>
) : null}
</FormItem>
))}
<FormItem>
<Button
type="dashed"
disabled={isJDGoods}
onClick={() => this.add('firstKeys')}
style={{ textAlign: 'center' }}
>
<PlusOutlined />
</Button>
</FormItem>
</Row>
<Row>
<FormItem label="二级规格">
{getFieldDecorator('secondSpecId', {
initialValue: this.state.initForm.secondSpecId,
})(
<Select
allowClear
showSearch
disabled={(isEdit && initData.secondSpecId) || isService}
placeholder="请选择二级规格"
style={{ width: 200 }}
onChange={(val, option) => this.specChange('second', option?.props.children)}
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{this.state.specList.length &&
this.state.specList.map(item => (
<Option key={item.specId} value={item.specId}>
{item.specName}
</Option>
))}
</Select>,
)}
</FormItem>
</Row>
<Row type="flex">
{skuSpeSecondKeys.length > 0 &&
skuSpeSecondKeys.map(k => (
<Input
key={k}
value={k}
disabled
placeholder="请输入规格名称"
style={{ width: '15%', margin: '5px 5px 28px 5px' }}
/>
))}
{secondKeys.map(k => (
<FormItem label="" required={false} key={k}>
{getFieldDecorator(`second[${k}]`, {
initialValue:
(this.state.initForm.second && this.state.initForm.second[k]) || '',
validateTrigger: ['onChange', 'onBlur'],
})(<Input key={k} style={{ width: '60%', marginRight: 8 }} />)}
{secondKeys.length > 0 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => this.remove('secondKeys', k)}
/>
) : null}
</FormItem>
))}
<FormItem>
<Button
type="dashed"
onClick={() => this.add('secondKeys')}
style={{ textAlign: 'center' }}
disabled={isJDGoods}
>
<PlusOutlined />
</Button>
</FormItem>
</Row>
</Card>
<Row>
<Button
type="primary"
className={styles.logBtn}
onClick={() => this.createShopInfo(isEdit)}
disabled={isService}
>
生成商品信息
</Button>
</Row>
<BatchSetting
firstSpes={first ? skuSpeFirstKeys.concat(first) : skuSpeFirstKeys}
secondSpecs={skuSpeSecondKeys.concat(second || [])}
onRef={ref => {
this.BatchSetting = ref;
}}
editData={this.state.editData}
firstSpesName={this.state.initForm.firstSpecName}
secondSpesName={this.state.initForm.secondSpecName}
batchSetting={this.batchSet}
productType={productType}
isEdit={isEdit}
isJDGoods={isJDGoods}
isService={isService}
/>
<Row>
<Table
bordered
// rowKey={r => r.thirdSkuNo}
pagination={false}
scroll={{ y: 300, x: 1200 }}
dataSource={this.state.editData}
columns={editColumns(
{
getJdPicList: this.getJdPicList,
inputChange: this.inputChange,
openModal: this.openSkuNameModal,
productType,
},
this.state.editData?.length ? this.state.editData[0] : null,
this.state.initForm.firstSpecName,
this.state.initForm.secondSpecName,
isJDGoods,
isEdit,
isService,
)}
/>
</Row>
<Row>
<Col span={24}>
<Button
type="danger"
size="small"
onClick={this.deleteImg}
style={{ marginTop: '10px' }}
icon={<RestOutlined />}
>
图片批量删除
</Button>
</Col>
<Col span={1}>
<Checkbox
value="commonImageList"
checked={this.state.batchDeleteImgObj.commonImageList}
style={{ marginTop: '12px' }}
onChange={() => this.chooseRollImg('commonImageList')}
></Checkbox>
</Col>
<Col span={23} className={styles.imgBorder}>
<p className={styles.ptop}>
公共滑动图:
<span className={styles.sizeTitle}>(图片最大上传2M)</span>
</p>
<FormItem>
{getFieldDecorator('commonImageList', {
initialValue: this.state.initForm.commonImageList,
valuePropName: 'fileList',
getValueFromEvent: normFile,
})(<Upload isDisabled={isService} />)}
</FormItem>
</Col>
{colorKeys.length > 0 &&
colorKeys.map(color => {
if (JSON.stringify(color) === '{}') return [];
if ((color !== null && !color) || (color && !color.trim())) return [];
return [
<Col span={1}>
<Checkbox
value={color}
checked={this.state.batchDeleteImgObj[color]}
style={{ marginTop: '12px' }}
onChange={() => this.chooseRollImg(color)}
></Checkbox>
</Col>,
<Col span={23} className={styles.imgBorder}>
<p className={styles.ptop}>
{`滑动图${color === 'null' ? '' : `(${color})`}:`}
<span className={styles.sizeTitle}>(图片最大上传2M)</span>
</p>
<FormItem key={color}>
{getFieldDecorator(`imageList[${color}]`, {
initialValue:
this.state.initForm.imageList && this.state.initForm.imageList[color],
valuePropName: 'fileList',
getValueFromEvent: normFile,
})(
<Upload
isDisabled={isService}
onChange={val => this.imgChange(val, color)}
/>,
)}
<Button
disabled={colorImg[color]?.length}
size="small"
type="primary"
className={styles.pullBtn}
onClick={() => this.pullImg(commonImageList, color)}
>
拉取公共图像
</Button>
</FormItem>
</Col>,
];
})}
</Row>
<Row>
<Col span={1}>
<Checkbox
value="detailImageList"
checked={this.state.batchDeleteImgObj.detailImageList}
style={{ marginTop: '12px' }}
onChange={() => this.chooseRollImg('detailImageList')}
></Checkbox>
</Col>
<Col span={23} className={styles.imgBorder}>
<p className={styles.ptop}>
详情图:
<span className={styles.sizeTitle}>(图片最大上传2M)</span>
</p>
<FormItem>
{getFieldDecorator('detailImageList', {
initialValue: this.state.initForm.detailImageList,
valuePropName: 'fileList',
getValueFromEvent: normFile,
rules: [
{
required: productType !== 2,
message: '请上传详情图',
},
],
})(<Upload isDisabled={isService} />)}
</FormItem>
</Col>
</Row>
</div>
</Form>
<ButtonGroup
key="button-group"
initData={initData}
changeStep={this.changeStep}
onCancel={this.onCancel}
confirm={this.confirm}
confirmLoading={confirmLoading}
></ButtonGroup>
<SkuNameChange
visible={this.state.skuNameVisible}
data={this.state.editRow.name}
changeSkuName={data => this.changeName(data)}
onCancle={() => this.setState({ skuNameVisible: false })}
></SkuNameChange>
</Modal>
);
}
}
export default Form.create()(goodsManage);
/* eslint-disable no-param-reassign */
import React from 'react';
import { Input, Button, notification, Popover, InputNumber } from 'antd';
import { sortBy } from 'lodash';
const CHECK_OBJECT = {
supplyPrice: '供货价',
marketPrice: '市场价',
productStock: '库存',
thirdSkuNo: '商品自编码',
};
export function normFile(fileList) {
return fileList;
}
export function specValidate(editArr, initArr, isEdit, msg) {
let isSame = false;
if (editArr && editArr.length) {
const list = isEdit ? editArr.concat(initArr) : editArr;
list.forEach((i, index) => {
const index1 = list.indexOf(i);
if (index1 !== index) {
isSame = true;
}
});
}
if (isSame && msg) {
notification.error({
message: msg,
});
}
return isSame;
}
export function createNewList(first, second, firstSpecId, secondSpecId) {
const list = [];
const sku = {
weight: '',
productStockWarning: '',
marketPrice: '',
// salePrice: '',
supplyPrice: '',
// stock: '',
productStock: '',
thirdSkuNo: '',
skuLink: '',
imageList: [],
};
if (first && first.length) {
// 一级规格有值时,生成的编辑表格
first.forEach(fir => {
const copy = Object.assign({}, sku);
copy.firstSpecId = firstSpecId;
copy.firstSpecValue = fir;
if (second.length) {
second.forEach(sec => {
const copySec = Object.assign({}, copy);
copySec.secondSpecId = secondSpecId;
copySec.secondSpecValue = sec;
list.push(copySec);
});
return;
}
console.log(copy);
list.push(copy);
});
} else if (second.length) {
// 缺少一级规格值,只有二级规格值时,生成的编辑表格
second.forEach(sec => {
const copy = Object.assign({}, sku);
copy.secondSpecId = secondSpecId;
copy.secondSpecValue = sec;
list.push(copy);
});
} else {
// 缺少一级和二级规格时生成的编辑表格
list.push(sku);
}
return list;
}
export function createEditData(values, initData) {
// console.log(values);
let list = null;
const first = values.first?.filter(item => item && !item.match(/^[ ]*$/)) || [];
const second =
(values.second && values.second.filter(item => item && !item.match(/^[ ]*$/))) || [];
const newFirst = first.concat(initData.firstSpecList || []);
const isFirstSame = specValidate(
first,
initData.firstSpecList,
initData.id,
'一级规格值不可重复',
);
const isSecondSame = specValidate(
second,
initData.secondSpecList,
initData.id,
'二级规格值不可重复',
);
if (!isFirstSame && !isSecondSame) {
if (!initData.id) {
list = createNewList(first, second, values.firstSpecId, values.secondSpecId);
} else {
const list1 = first.length
? createNewList(first, initData.secondSpecList, values.firstSpecId, values.secondSpecId)
: [];
const list2 = second.length
? createNewList(newFirst, second, values.firstSpecId, values.secondSpecId)
: [];
// console.log('list1=================>', list1);
// console.log('list2=================>', list2);
// console.log('initData===========>', initData);
// console.log('first===========>', first);
// console.log('second===========>', second);
// 初次添加规格时没有选择规格,添加一条没有规格的商品,被驳回之后编辑时选择规格之后需要重新创建
// 编辑时回显时的id需要给重新创建的数据第一条加上 回显的id
if (!initData.editData[0]?.firstSpec && !initData.editData[0]?.secondSpec) {
// 这种情况出现时items中只有一条数据,且没有一级规格和二级规格
// 第一次无规格时,重新生成的数据,必须保留第一条数据的id是items里面第一条数据的id
list = createNewList(first, second, values.firstSpecId, values.secondSpecId);
list[0].id = initData.editData[0].id;
} else if (initData.editData[0]?.firstSpec && !initData.editData[0]?.secondSpec) {
// console.log('只有一级规格================>');
// 只有一级规格的情况下需要
// 重新更具规格创建表格,但是需要把历史记录赋值给表格的其中几项
// 其中新建的记录和历史编辑记录
const createList = createNewList(
[...initData.firstSpecList, ...first],
second,
values.firstSpecId,
values.secondSpecId,
);
const setp = createList.length / initData.firstSpecList.concat(first).length;
list = createList.map((item, index) => {
if (index % setp === 0) {
const newItem =
initData.editData.find(val => val.firstSpecValue === item.firstSpecValue) || {};
item = Object.assign({}, item, newItem, {
secondSpec: initData.secondSpecName,
secondSpecId: item.secondSpecId,
secondSpecValue: item.secondSpecValue,
length: setp,
});
}
return item;
});
list = sortBy(list, item => item.firstSpecValue);
} else {
list = sortBy(initData.editData.concat(list1.concat(list2)), item => item.firstSpecValue);
}
}
console.log(list);
}
return list;
}
export function validateSpuInfo(values, initData, editData, productType) {
const newCheckObject =
productType === 1 ? { ...CHECK_OBJECT, weight: '重量(kg)' } : { ...CHECK_OBJECT };
const checkKey = Object.keys(newCheckObject);
const checkString = [];
editData.forEach((item, index) => {
item.thirdSkuNo = item.third;
const rowCheckString = checkKey.reduce((checkMessage, val, ind) => {
const checkItem = item[val];
if (checkItem === null || checkItem === undefined || checkItem === '') {
checkMessage += `${newCheckObject[val]}; `;
}
return checkMessage;
}, '');
if (rowCheckString) {
checkString.push(<div key={index.toString()}>{`第${index + 1}行: ${rowCheckString}`}</div>);
}
});
if (checkString.length) {
notification.warning({
message: '请完善表格:',
description: checkString,
});
return true;
}
return false;
}
export function dataInit(list) {
if (!list || !list.length) return;
const obj = {};
let finialList = [];
list.forEach(item => {
obj[item.firstSpecValue] = [];
});
list.forEach(item => obj[item.firstSpecValue].push(item));
const keys = Object.keys(obj);
keys.forEach(key => {
obj[key].forEach((i, index) => {
if (index === 0) {
i.length = obj[key].length;
}
});
finialList = finialList.concat(obj[key]);
return finialList;
});
}
export function verify(initData, categoryId) {
if (categoryId || (initData && initData.thirdCategoryId)) {
return true;
}
notification.error({
message: '请选择三级类目',
});
return false;
}
export function editColumns(
methods,
firstData,
firstSpec,
secondSpec,
isJDGoods,
isEdit,
isService,
) {
const { getJdPicList, inputChange, openModal, productType } = methods;
if (!firstData) return [];
const arr = [
{
title: '供货价',
align: 'center',
key: 'supplyPrice',
dataIndex: 'supplyPrice',
width: 100,
render: (val, row, index) => (
<InputNumber
defaultValue={val}
value={val}
precision={2}
min={0}
onChange={value => inputChange(value, 'supplyPrice', index)}
disabled={isJDGoods || isService}
/>
),
},
{
title: '市场价',
align: 'center',
key: 'marketPrice',
dataIndex: 'marketPrice',
width: 100,
render: (val, row, index) => (
<InputNumber
defaultValue={val}
value={val}
precision={2}
min={0}
onChange={value => inputChange(value, 'marketPrice', index)}
disabled={isService}
/>
),
},
{
title: '库存',
align: 'center',
key: 'productStock',
dataIndex: 'productStock',
width: 100,
render: (val, row, index) => (
<InputNumber
value={val}
precision={0}
min={0}
onChange={value => inputChange(value, 'productStock', index)}
disabled={isService}
/>
),
},
{
title: '商品自编码',
align: 'center',
dataIndex: 'third',
key: 'third',
width: 100,
render: (val, row, index) => (
<Input
value={val}
className={`third ${index}`}
defaultValue={val}
onChange={evt => inputChange(evt.target.value, 'third', index)}
disabled={isService}
/>
),
},
{
title: '京东链接',
align: 'center',
key: 'skuLink',
dataIndex: 'skuLink',
width: 80,
render: (val, row, index) => (
<Popover content={val} trigger="hover">
{
<Input
value={val}
className={`skuLink ${index}`}
defaultValue={val}
onChange={evt => inputChange(evt.target.value, 'skuLink', index)}
disabled={isService}
/>
}
</Popover>
),
},
{
title: '操作',
align: 'center',
key: 'option',
dataIndex: 'option',
width: 100,
render: (_, row, index) => (
<div>
{row.skuLink && (
<Button type="primary" size="small" onClick={() => getJdPicList(row)}>
拉图片
</Button>
)}
{isJDGoods && (
<Button
type="primary"
size="small"
style={{ marginTop: '5px' }}
onClick={() => openModal(row, index)}
disabled={isService}
>
修改sku名称
</Button>
)}
</div>
),
},
];
if (productType === 1) {
// 如果是实体商品添加重量
arr.splice(2, 0, {
title: '重量(kg)',
align: 'center',
key: 'weight',
dataIndex: 'weight',
width: 120,
render: (val, row, index) => (
<InputNumber
style={{ width: '100%' }}
value={val}
min={0}
max={999999.999}
precision={3}
onChange={value => inputChange(value, 'weight', index)}
disabled={isService}
/>
),
});
arr.splice(4, 0, {
title: '库存预警',
align: 'center',
key: 'productStockWarning',
dataIndex: 'productStockWarning',
width: 90,
render: (val, row, index) => (
<InputNumber
defaultValue={0}
value={val}
maxLength={5}
min={0}
precision={0}
onChange={value => inputChange(value, 'productStockWarning', index)}
disabled={isService}
/>
),
});
}
if (secondSpec && firstData.secondSpecValue) {
arr.unshift({
title: secondSpec,
align: 'center',
key: 'secondSpecValue',
dataIndex: 'secondSpecValue',
width: 100,
});
}
if (firstSpec && firstData.firstSpecValue) {
arr.unshift({
title: firstSpec,
dataIndex: 'firstSpecValue',
key: 'firstSpecValue',
align: 'center',
width: 100,
render: (val, row) => {
const obj = {
children: val,
props: {},
};
if (row.length) {
obj.props.rowSpan = row.length;
} else {
obj.props.rowSpan = 0;
}
return obj;
},
});
}
if (isEdit && isJDGoods) {
arr.splice(arr.length - 1, 0, {
title: 'sku名称',
align: 'center',
key: 'name',
dataIndex: 'name',
width: 100,
render: val => (
<Popover content={val} trigger="hover">
<a>查看名称</a>
</Popover>
),
});
}
return arr;
}
export const goodsType = [
{
name: '普通商品',
value: 1,
},
{
name: '虚拟商品',
value: 2,
},
{
name: '电子卡券',
value: 3,
},
];
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Input, Modal } from 'antd';
import React, { Component } from 'react';
const { TextArea } = Input;
const FormItem = Form.Item;
// import styles from '../style.less';
class goodsManage extends Component {
// componentDidMount() {
// this.props.onRef(this);
// }
handleOk = () => {
const { form } = this.props;
form.validateFields((err, values) => {
if (!err) {
this.props.changeSkuName(values.name);
this.props.form.resetFields();
}
});
};
handleCancel = () => {
this.props.form.resetFields();
this.props.onCancle();
};
render() {
const { data, visible, form } = this.props;
const { getFieldDecorator } = form;
return (
<Modal title="" visible={visible} onOk={this.handleOk} onCancel={this.handleCancel}>
<Form>
<FormItem label="sku名称">
{getFieldDecorator('name', {
initialValue: data,
rules: [
{
required: true,
message: '请输入',
},
],
})(<TextArea autoSize={{ minRows: 2, maxRows: 6 }} allowClear />)}
</FormItem>
</Form>
</Modal>
);
}
}
export default Form.create()(goodsManage);
...@@ -4,7 +4,6 @@ import { Card, Pagination, Table, notification, Drawer, Spin, Button, Modal } fr ...@@ -4,7 +4,6 @@ import { Card, Pagination, Table, notification, Drawer, Spin, Button, Modal } fr
import React, { Component } from 'react'; import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva'; import { connect } from 'dva';
import { sortBy } from 'lodash';
import styles from './style.less'; import styles from './style.less';
import LocalStroage from '@/utils/localStorage'; import LocalStroage from '@/utils/localStorage';
import configApi from '../../../config/env.config'; import configApi from '../../../config/env.config';
...@@ -21,12 +20,11 @@ import { ...@@ -21,12 +20,11 @@ import {
apiQueryLastChangeLog, apiQueryLastChangeLog,
} from './service'; } from './service';
import LogModal from './LogModal'; import LogModal from './LogModal';
import CreateModal from './createModal';
import { column, JDSHOPID, ProcessEditData } from './staticdata'; import { column, JDSHOPID, ProcessEditData } from './staticdata';
import SearchForm from './SearchForm'; import SearchForm from './SearchForm';
import TempleatModal from './TempleatModal'; import TempleatModal from './TempleatModal';
import ServiceGoods from '../ServiceGoods'; import ServiceGoods from '../ServiceGoods';
import InfoAudit from './createModal/infoAudit'; import InfoAudit from './infoAudit';
import { GOOD_MANAGE } from '@/../config/permission.config'; import { GOOD_MANAGE } from '@/../config/permission.config';
...@@ -44,9 +42,7 @@ class goodsManage extends Component { ...@@ -44,9 +42,7 @@ class goodsManage extends Component {
priceInfo: {}, priceInfo: {},
logVisible: false, logVisible: false,
previewVisible: false, previewVisible: false,
createVisible: false, // 新增or编辑普通商品modal
updateStockVisible: false, updateStockVisible: false,
initData: {},
createloading: false, createloading: false,
specListData: [], specListData: [],
templeatModalVisible: false, templeatModalVisible: false,
...@@ -126,64 +122,6 @@ class goodsManage extends Component { ...@@ -126,64 +122,6 @@ class goodsManage extends Component {
this.handleSearch(); this.handleSearch();
}; };
onUpdateInfo = async ({ state, spuId, productType }) => {
this.setState({
createloading: true,
});
const { data, msg } = await spuDetail({ id: spuId }); // spuId
if (data) {
data.state = state;
data.pageProductType = productType;
data.categoryId = data.thirdCategoryId;
data.firstSpecId = data.skuList[0].firstSpecId;
data.secondSpecId = data.skuList[0].secondSpecId;
data.firstSpecName = data.skuList[0].firstSpec;
data.secondSpecName = data.skuList[0].secondSpec;
data.firstSpecList = [];
data.secondSpecList = [];
data.colorKeys = [];
data.carouseList.forEach(i => {
if (i.specValue) {
data.colorKeys.push(i.specValue);
}
});
data.skuList.forEach(i => {
if (data.firstSpecList.indexOf(i.firstSpecValue) === -1) {
data.firstSpecList.push(`${i.firstSpecValue}`);
}
if (i.secondSpecValue && data.secondSpecList.indexOf(i.secondSpecValue) === -1) {
data.secondSpecList.push(i.secondSpecValue);
}
});
data.specs.forEach(item => {
const arr = [];
if (item.specValues.length) {
item.specValues.forEach(childItem => {
arr.push(childItem.value);
});
}
data[item.specId] = arr;
});
data.imageList = [];
data.carouseList.forEach(i => {
data.imageList[`${i.specValue}`] = i.skuSpecImageList || [];
});
data.editData = sortBy(data.skuList, item => item.firstSpecValue);
this.setState({
initData: data,
createVisible: true,
createloading: false,
});
} else {
this.setState({
createloading: false,
});
notification.warning({
message: msg,
});
}
};
onLoad = error => { onLoad = error => {
if (!error) { if (!error) {
notification.success({ message: '操作成功' }); notification.success({ message: '操作成功' });
...@@ -389,6 +327,11 @@ class goodsManage extends Component { ...@@ -389,6 +327,11 @@ class goodsManage extends Component {
} }
}; };
onEdit = () => {
this.setState({ visibleAuditModal: false, auditRow: {} });
this.serviceVisbleChange(this.state.auditRow);
};
render() { render() {
const { const {
goodsManage: { tableData = {} }, goodsManage: { tableData = {} },
...@@ -405,30 +348,18 @@ class goodsManage extends Component { ...@@ -405,30 +348,18 @@ class goodsManage extends Component {
this.canEditable = permissions[GOOD_MANAGE.EDITABLE]; this.canEditable = permissions[GOOD_MANAGE.EDITABLE];
return ( return (
<PageHeaderWrapper> <PageHeaderWrapper>
{canAddNormal || canAddService ? (
<Button
type="primary"
className={styles.button}
onClick={() => this.serviceVisbleClose(true)}
>
新增商品
</Button>
) : (
''
)}
<Spin spinning={this.state.createloading}> <Spin spinning={this.state.createloading}>
{canAddNormal ? (
<Button
type="primary"
className={styles.button}
onClick={() => this.setState({ createVisible: true, initData: {} })}
>
新增商品
</Button>
) : (
''
)}
{canAddService ? (
<Button
type="primary"
className={styles.button}
onClick={() => this.serviceVisbleClose(true)}
>
新增服务类商品
</Button>
) : (
''
)}
<Card> <Card>
<SearchForm <SearchForm
handleSearch={this.handleSearch} handleSearch={this.handleSearch}
...@@ -440,7 +371,6 @@ class goodsManage extends Component { ...@@ -440,7 +371,6 @@ class goodsManage extends Component {
treeData={this.state.treeData} treeData={this.state.treeData}
shopList={this.shopList} shopList={this.shopList}
checkStock={this.checkEnableUpdateStock} checkStock={this.checkEnableUpdateStock}
// addSpu={() => this.setState({ createVisible: true, initData: {} })}
selectNum={selectedRowKeys.length} selectNum={selectedRowKeys.length}
setArea={(isALL, type) => this.setArea(isALL, type)} setArea={(isALL, type) => this.setArea(isALL, type)}
/> />
...@@ -497,20 +427,6 @@ class goodsManage extends Component { ...@@ -497,20 +427,6 @@ class goodsManage extends Component {
title="商品预览" title="商品预览"
></iframe> ></iframe>
</Drawer> </Drawer>
{this.state.createVisible && (
<CreateModal
initData={this.state.initData}
visible={this.state.createVisible}
onCancel={() => {
this.setState({ createVisible: false, initData: {} });
}}
query={() => this.handleSearch()}
shopList={this.filterShopList(this.shopList, Object.keys(this.state.initData).length)}
treeData={this.state.treeData}
virtualTreeData={this.state.virtualTreeData}
specListData={this.state.specListData}
></CreateModal>
)}
<UpdateStock <UpdateStock
visible={this.state.updateStockVisible} visible={this.state.updateStockVisible}
...@@ -530,33 +446,30 @@ class goodsManage extends Component { ...@@ -530,33 +446,30 @@ class goodsManage extends Component {
isType={this.state.isType} isType={this.state.isType}
templateList={this.state.templateList} templateList={this.state.templateList}
/> />
{/* '894048258062' */} {this.state.serviceVisble && (
<ServiceGoods <ServiceGoods
visible={this.state.serviceVisble} visible={this.state.serviceVisble}
onChange={this.serviceVisbleClose} onChange={this.serviceVisbleClose}
SourceData={this.state.serviceData} SourceData={this.state.serviceData}
shopList={this.shopList} shopList={this.shopList}
categoryList={this.state.treeData} categoryList={this.state.treeData}
virtualCategoryList={this.state.virtualTreeData} virtualCategoryList={this.state.virtualTreeData}
specListData={this.state.specListData} specListData={this.state.specListData}
/> permissions={permissions}
/>
)}
</Spin> </Spin>
<InfoAudit {this.state.visibleAuditModal && (
visible={this.state.visibleAuditModal} <InfoAudit
skuInfo={this.state.auditRow} visible={this.state.visibleAuditModal}
canEditable={this.canEditable} skuInfo={this.state.auditRow}
onCancel={() => { canEditable={this.canEditable}
this.setState({ visibleAuditModal: false, auditRow: {} }); onCancel={() => {
}} this.setState({ visibleAuditModal: false, auditRow: {} });
onEdit={() => { }}
this.setState({ visibleAuditModal: false, auditRow: {} }); onEdit={this.onEdit}
if (this.state.auditRow.type === 4) { />
this.serviceVisbleChange(this.state.auditRow); )}
} else {
this.onUpdateInfo(this.state.auditRow);
}
}}
/>
</PageHeaderWrapper> </PageHeaderWrapper>
); );
} }
......
...@@ -215,11 +215,7 @@ export function column() { ...@@ -215,11 +215,7 @@ export function column() {
size="small" size="small"
className={styles.button} className={styles.button}
onClick={() => { onClick={() => {
if (row.type === 4) { this.serviceVisbleChange(row);
this.serviceVisbleChange(row);
} else {
this.onUpdateInfo(row);
}
}} }}
> >
修改 修改
...@@ -364,6 +360,7 @@ export const ProcessEditData = (data, row) => { ...@@ -364,6 +360,7 @@ export const ProcessEditData = (data, row) => {
id: data.id, id: data.id,
productType: data.productType, productType: data.productType,
pageProductType: row.productType, pageProductType: row.productType,
productAttributeApplyList: data.productAttributeApplyList,
infoMation: { infoMation: {
...specsParams, ...specsParams,
brandId: data.brandId, brandId: data.brandId,
......
...@@ -75,6 +75,11 @@ ...@@ -75,6 +75,11 @@
.pictureWrapper { .pictureWrapper {
position: relative; position: relative;
:global {
.ant-form-item-label > label {
word-break: break-all;
}
}
} }
.pullImage { .pullImage {
position: absolute; position: absolute;
...@@ -164,3 +169,13 @@ ...@@ -164,3 +169,13 @@
} }
} }
} }
.attrbox {
max-height: 384px;
overflow: hidden;
}
.attrboxMore {
max-height: max-content;
}
.btnMore {
text-align: center;
}
import React, { useState } from 'react'; import React from 'react';
import { Select, Form, InputNumber, Input, Button, Popover } from 'antd'; import { Select, Form, InputNumber, Input, Button, Popover } from 'antd';
import commonStyle from '../common.less'; import commonStyle from '../common.less';
...@@ -108,7 +108,12 @@ export const CreateFormInput = props => { ...@@ -108,7 +108,12 @@ export const CreateFormInput = props => {
return ( return (
<> <>
{record.skuLink && ( {record.skuLink && (
<Button type="primary" size="small" onClick={() => onClickEvent('cloneImg', record)}> <Button
type="primary"
size="small"
disabled={props.disabled}
onClick={() => onClickEvent('cloneImg', record)}
>
拉图片 拉图片
</Button> </Button>
)} )}
......
...@@ -115,7 +115,18 @@ const EditFormTable = forwardRef((props, ref) => { ...@@ -115,7 +115,18 @@ const EditFormTable = forwardRef((props, ref) => {
tableList: newDataSource, tableList: newDataSource,
}); });
}; };
const onClickEvent = () => {}; const onClickEvent = (type, row) => {
// 点击拉取京东图片功能
if (type === 'cloneImg') {
customer.onEventBus(type, row);
return;
}
// 修改sku名称
if (type === 'updateName') {
rowOnClickEvent(row);
}
};
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
onCheck, onCheck,
...@@ -174,8 +185,8 @@ const EditFormTable = forwardRef((props, ref) => { ...@@ -174,8 +185,8 @@ const EditFormTable = forwardRef((props, ref) => {
<Form form={form} scrollToFirstError component={false}> <Form form={form} scrollToFirstError component={false}>
<EditableContext.Provider value={form}> <EditableContext.Provider value={form}>
<Table <Table
scroll={{ y: 300, x: 1000 }} scroll={{ y: 320, x: 1000 }}
height={300} height={320}
pagination={false} pagination={false}
size="small" size="small"
bordered bordered
......
/* eslint-disable consistent-return */
import React, { forwardRef, useState, useEffect, useImperativeHandle } from 'react';
import { Form, Row, Col, Button } from 'antd';
import { unstable_batchedUpdates } from 'react-dom';
import { UpOutlined, DownOutlined } from '@ant-design/icons';
import styles from '../common.less';
import { apiGetAttribute } from '../service';
import CustomSelect from '@/components/CustomSelect';
const FormAttr = forwardRef((props, ref) => {
const [form] = Form.useForm();
const [isMore, setIsMome] = useState(false);
const [categoryAttrs, setCategoryAttrs] = useState([]);
const [skuOldAttr, setSkuOldAttr] = useState([]);
const [initAttrData, setInitAttrData] = useState({});
const formItemAttr = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const onChangeMore = () => {
setIsMome(!isMore);
};
// 验证是否失效属性(已失效的商品不显示)
const checkInAttrList = (id, categoryList) =>
categoryList.some(item => item.valueList.some(v => +v.id === +id));
// 获取初始化属性数据
const getInitAttrValue = categoryList => {
const skuAttr = props.initData.productAttributeApplyList?.productAttributeApplyList || [];
const obj = {
initValue: {},
};
const key = 'productAttributeApplyValueList';
skuAttr.forEach(item => {
if (item[key].length) {
let values = +item.optionType.code === 1 ? '' : [];
obj[item.productAttributeId] = [];
item[key].forEach(attr => {
const { attributeValueId, attributeValueName } = attr;
const json = {
attributeValueId,
attributeValueName,
name: attributeValueName,
};
if (attributeValueId === 0 || checkInAttrList(attributeValueId, categoryList)) {
const v = JSON.stringify(json);
if (attributeValueId === 0) {
obj[item.productAttributeId].push(json);
}
// eslint-disable-next-line no-unused-expressions
+item.optionType.code === 1 ? (values = v) : values.push(v);
}
});
obj.initValue[item.productAttributeId] = values;
}
});
return obj;
};
// 获取属性
const getAttribute = async categoryId => {
const res = await apiGetAttribute(categoryId);
if (res && res.data && res.data.length) {
let initValue = {
initValue: {},
};
if (props.initData) {
if (props.initData.productAttributeApplyList?.oldProductAttributeApplyList) {
const oattr = props.initData.productAttributeApplyList;
setSkuOldAttr((oattr && oattr.oldProductAttributeApplyList) || []);
}
if (props.initData.productAttributeApplyList?.productAttributeApplyList) {
initValue = getInitAttrValue(res.data);
}
}
res.data.forEach(item => {
item.valueList = item.valueList.map(v => ({
attributeValueId: v.id,
attributeValueName: v.name,
name: v.name,
}));
if (initValue[item.id] && initValue[item.id].length) {
item.valueList.push(...initValue[item.id]);
}
});
unstable_batchedUpdates(() => {
setInitAttrData(initValue.initValue);
setCategoryAttrs(res.data);
});
} else {
setInitAttrData({});
setCategoryAttrs([]);
}
};
// 获取下拉框类型
const getMode = optionType => (+optionType.code === 2 ? 'multiple' : 'default');
// 获取下拉框校验
const getAttrRules = k => {
if (+k.required.code === 1) {
return [
{
required: true,
type: +k.optionType.code === 2 ? 'array' : 'string',
message: '请选择',
},
];
}
return [];
};
// 处理下拉框返回值
const deal = attr => {
try {
const json = JSON.parse(attr);
if (json.attributeValueId) {
return json;
}
return { attributeValueName: json.name };
} catch {
return { attributeValueName: attr };
}
};
const onCheck = async () => {
try {
const values = await form.validateFields();
const attributeApplyList = [];
// eslint-disable-next-line no-restricted-syntax
for (const key in values) {
if (values.hasOwnProperty(key) && values[key]) {
let attrs = values[key];
if (Array.isArray(values[key])) {
attrs = [];
values[key].forEach(attr => {
if (typeof attr !== 'undefined') {
attrs.push(deal(attr));
}
});
} else {
const json = deal(values[key]);
json && (attrs = [json]);
}
attributeApplyList.push({
attributeId: key,
attributeApplyValueList: attrs,
});
}
}
return {
temp: 'attributeApplyList',
attributeApplyList,
};
} catch (errorInfo) {
return null;
}
};
useEffect(() => {
const ids = props.categoryIds;
if (ids && ids.length) {
getAttribute(ids[ids.length - 1]);
} else {
setInitAttrData({});
setCategoryAttrs([]);
}
}, [props.categoryIds]);
useImperativeHandle(ref, () => ({
onCheck,
reset: form.resetFields,
}));
return (
<>
<div className={styles.attrbox + (isMore ? styles.attrboxMore : '')}>
{categoryAttrs.length > 0 && (
<Form form={form} initialValues={initAttrData}>
<Row>
{categoryAttrs.map(k => (
<Col span={12} key={k.id}>
<Form.Item
label={k.name}
name={k.id}
{...formItemAttr}
key={k.id}
rules={getAttrRules(k)}
>
<CustomSelect
options={k.valueList || []}
isCustom={+k.supportCustomValue.code === 1}
mode={getMode(k.optionType)}
/>
</Form.Item>
</Col>
))}
</Row>
</Form>
)}
</div>
{categoryAttrs.length > 12 && (
<div className={styles.btnMore}>
<Button type="link" onClick={onChangeMore}>
{isMore ? (
<>
收起 <UpOutlined />
</>
) : (
<>
展示更多 <DownOutlined />
</>
)}
</Button>
</div>
)}
{skuOldAttr.length > 0 && (
<div>
<Row>注:以下商品属性已失效,请使用新的属性</Row>
<Row>
{skuOldAttr.map(s => (
<Col span={12} key={s.id}>
<Form.Item
label={s.productAttributeName}
{...formItemAttr}
required={false}
key={s.id}
>
{s.productAttributeApplyValueList.map(item => item.attributeValueName).join('')}
</Form.Item>
</Col>
))}
</Row>
</div>
)}
</>
);
});
export default FormAttr;
...@@ -83,9 +83,6 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -83,9 +83,6 @@ const FormInformationBasic = forwardRef((props, ref) => {
}} }}
scrollToFirstError scrollToFirstError
> >
{/* <Button type="primary" onClick={onCheck}>
测试
</Button> */}
<Form.Item <Form.Item
name="categoryId" name="categoryId"
label="商品类目" label="商品类目"
...@@ -93,8 +90,10 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -93,8 +90,10 @@ const FormInformationBasic = forwardRef((props, ref) => {
> >
<Cascader <Cascader
placeholder="请选择商品类目!" placeholder="请选择商品类目!"
disabled={customer.isEdit && customer.isNormal}
showSearch={{ filter: filterCategoryOptions }} showSearch={{ filter: filterCategoryOptions }}
fieldNames={{ label: 'name', value: 'id', children: 'children' }} fieldNames={{ label: 'name', value: 'id', children: 'children' }}
onChange={props.onCategoryChange}
options={newCategoryList[customer.productType]} options={newCategoryList[customer.productType]}
/> />
</Form.Item> </Form.Item>
...@@ -106,8 +105,8 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -106,8 +105,8 @@ const FormInformationBasic = forwardRef((props, ref) => {
extra="若需新增品牌请联系业务员" extra="若需新增品牌请联系业务员"
> >
<Select <Select
disabled={customer.isService}
showSearch showSearch
disabled={customer.isDisabled}
placeholder="请选择商品品牌" placeholder="请选择商品品牌"
filterOption={fileterBrandOptions} filterOption={fileterBrandOptions}
> >
...@@ -126,14 +125,9 @@ const FormInformationBasic = forwardRef((props, ref) => { ...@@ -126,14 +125,9 @@ const FormInformationBasic = forwardRef((props, ref) => {
{ required: true, min: 2, message: '请输入最少两个字符的商品名称!', whitespace: true }, { required: true, min: 2, message: '请输入最少两个字符的商品名称!', whitespace: true },
]} ]}
> >
<Input placeholder="请输入商品名称" /> <Input placeholder="请输入商品名称" disabled={customer.isDisabled} />
</Form.Item> </Form.Item>
</Popover> </Popover>
{customer.isJDGoods && (
<Button key="jdMsg" danger type="text">
*本列表的商品名称仅供搜索使用,不在前端作展示。若要修改APP端展示的商品名称,请在商品信息中修改。
</Button>
)}
{!customer.isCard && ( {!customer.isCard && (
<Form.Item <Form.Item
name="character" name="character"
......
...@@ -58,7 +58,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -58,7 +58,7 @@ const SpecificationTemplate = (props, _) => {
const handleChange = (val, option) => { const handleChange = (val, option) => {
const optionSpecName = option ? option.specName : null; const optionSpecName = option ? option.specName : null;
form.setFieldsValue({ [selectName]: optionSpecName }); form.setFieldsValue({ [selectName]: optionSpecName });
// onChange(); onChange();
}; };
const inputOnblurEvent = event => { const inputOnblurEvent = event => {
...@@ -77,11 +77,14 @@ const SpecificationTemplate = (props, _) => { ...@@ -77,11 +77,14 @@ const SpecificationTemplate = (props, _) => {
return; return;
} }
addCallback(); addCallback();
onChange();
}; };
const bundlePlusRemoveSpecEvent = (removeCallback, fieldName) => { const bundlePlusRemoveSpecEvent = (removeCallback, fieldName) => {
removeCallback(fieldName); removeCallback(fieldName);
form.setFieldsValue({
bacthFirst: undefined,
bacthSecon: undefined,
});
const timer = setTimeout(() => { const timer = setTimeout(() => {
onChange(); onChange();
clearTimeout(timer); clearTimeout(timer);
...@@ -92,7 +95,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -92,7 +95,7 @@ const SpecificationTemplate = (props, _) => {
<> <>
<Form.Item name={formName} label={label}> <Form.Item name={formName} label={label}>
<Select <Select
disabled={customer.isEdit} disabled={customer.isEdit && customer.isNormal}
allowClear allowClear
options={specList} options={specList}
style={{ width: 200 }} style={{ width: 200 }}
...@@ -114,8 +117,9 @@ const SpecificationTemplate = (props, _) => { ...@@ -114,8 +117,9 @@ const SpecificationTemplate = (props, _) => {
{fields.map((field, index) => ( {fields.map((field, index) => (
<Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}> <Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}>
{() => ( {() => (
<Space key={field.key} align="baseline"> <Space key={`space_${field.key}`} align="baseline">
<Form.Item <Form.Item
key={`item_${field.key}`}
style={{ marginLeft: 10 }} style={{ marginLeft: 10 }}
name={[field.name, specName]} name={[field.name, specName]}
rules={[ rules={[
...@@ -143,6 +147,7 @@ const SpecificationTemplate = (props, _) => { ...@@ -143,6 +147,7 @@ const SpecificationTemplate = (props, _) => {
</Form.Item> </Form.Item>
{!(specDataList[index] && specDataList[index].id) && ( {!(specDataList[index] && specDataList[index].id) && (
<MinusCircleOutlined <MinusCircleOutlined
key={`minus_${field.key}`}
onClick={() => bundlePlusRemoveSpecEvent(remove, field.name)} onClick={() => bundlePlusRemoveSpecEvent(remove, field.name)}
/> />
)} )}
...@@ -150,8 +155,8 @@ const SpecificationTemplate = (props, _) => { ...@@ -150,8 +155,8 @@ const SpecificationTemplate = (props, _) => {
)} )}
</Form.Item> </Form.Item>
))} ))}
{fields.length < 3 && ( {(!customer.isCard || fields.length < 3) && !customer.isDisabled && (
<Form.Item noStyle> <Form.Item noStyle key="btnpush">
<Button <Button
style={{ marginLeft: 10, marginBottom: 24 }} style={{ marginLeft: 10, marginBottom: 24 }}
type="dashed" type="dashed"
...@@ -202,7 +207,12 @@ const CreateBatchFormItems = ({ specInitValue, batchChange, editRef, defaultColu ...@@ -202,7 +207,12 @@ const CreateBatchFormItems = ({ specInitValue, batchChange, editRef, defaultColu
fieldNames={{ label: 'secondSpecValue', value: 'secondSpecValue' }} fieldNames={{ label: 'secondSpecValue', value: 'secondSpecValue' }}
/> />
{formItems.concat( {formItems.concat(
<Button key="batch" type="primary" onClick={batchChange}> <Button
key="batch"
type="primary"
disabled={customer.isEdit && customer.isNormal}
onClick={batchChange}
>
批量设置 批量设置
</Button>, </Button>,
)} )}
...@@ -225,20 +235,54 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -225,20 +235,54 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
const [mergeTable, setMergeTable] = useState(false); const [mergeTable, setMergeTable] = useState(false);
const insertSpecID = items => {
const sids = items.filter(item => item.id);
if (sids.length !== skuList.length) {
let i = 0;
const ids = skuList.reduce((prev, cur) => {
if (!sids.includes(cur.id)) {
prev.push(cur.id);
}
return prev;
}, []);
items.forEach(item => {
if (!item.id && i < ids.length) {
item.id = ids[i++];
}
});
}
};
const onCheck = async () => { const onCheck = async () => {
try { try {
const setMealContent = await packageRef.current.onCheck(); let setMealContent = '';
if (customer.isCard) {
setMealContent = await packageRef.current.onCheck();
}
const values = await form.validateFields(); const values = await form.validateFields();
if (!values.firstSpecValue || !values.firstSpecValue.length) {
values.firstSpecId = null;
values.firstSpec = '';
}
if (!values.secondSpecValue || !values.secondSpecValue.length) {
values.secondSpecId = null;
values.secondSpec = '';
}
const items = await editRef.current.onCheck(); const items = await editRef.current.onCheck();
if (!setMealContent) { if (customer.isCard && !setMealContent) {
notification.open({ notification.open({
message: '提示', message: '提示',
description: '请添加正确的套餐信息!', description: '请添加正确的套餐信息!',
}); });
return null; return null;
} }
if (items && setMealContent) { if (items && items.length) {
return { ...values, items, setMealContent, temp: 'infoSpecData' }; if (customer.isEdit && skuList.length) {
insertSpecID(items);
}
const obj = { ...values, items, temp: 'infoSpecData' };
customer.isCard && setMealContent && (obj.setMealContent = setMealContent);
return obj;
} }
notification.open({ notification.open({
message: '提示', message: '提示',
...@@ -267,7 +311,6 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -267,7 +311,6 @@ const FormPriceOrStock = forwardRef((props, ref) => {
inputType: 'text', inputType: 'text',
}); });
} }
const dynamicColumns = [...columsData, ...StaticColumns(customer)]; const dynamicColumns = [...columsData, ...StaticColumns(customer)];
setDefaultColumns(dynamicColumns); setDefaultColumns(dynamicColumns);
}; };
...@@ -278,8 +321,10 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -278,8 +321,10 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const cleanValues = { const cleanValues = {
firstValues: cleanArray(values.firstSpecValue || []), firstValues: cleanArray(values.firstSpecValue || []),
secondValues: cleanArray(values.secondSpecValue || []), secondValues: cleanArray(values.secondSpecValue || []),
firstSpecId: values.firstSpecId, firstSpecId:
secondSpecId: values.secondSpecId, values.firstSpecValue && values.firstSpecValue.length ? values.firstSpecId : null,
secondSpecId:
values.secondSpecValue && values.secondSpecValue.length ? values.secondSpecId : null,
}; };
const { inIdList: fisrtInIdList, noIdList: fisrtNoIdList } = filterSkuNotIdList( const { inIdList: fisrtInIdList, noIdList: fisrtNoIdList } = filterSkuNotIdList(
...@@ -288,7 +333,6 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -288,7 +333,6 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const { inIdList: secndInIdList, noIdList: secndNoIdList } = filterSkuNotIdList( const { inIdList: secndInIdList, noIdList: secndNoIdList } = filterSkuNotIdList(
cleanValues.secondValues, cleanValues.secondValues,
); );
const createSkuList = createProductData( const createSkuList = createProductData(
{ {
firstSpecId: cleanValues.firstSpecId, firstSpecId: cleanValues.firstSpecId,
...@@ -299,23 +343,25 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -299,23 +343,25 @@ const FormPriceOrStock = forwardRef((props, ref) => {
secndNoIdList, secndNoIdList,
}, },
customer.isEdit, customer.isEdit,
skuList,
); );
CreateColumnsEvent(values); CreateColumnsEvent(values);
// 没有规格默认创建一条数据
if (!cleanValues.firstSpecId && !createSkuList.secondSpecId) { if (!cleanValues.firstSpecId && !createSkuList.secondSpecId) {
setTableData([...createSkuList]); setTableData([...createSkuList]);
return; return;
} }
// 是否合并单元格
setMergeTable(Boolean(cleanValues.secondValues.length)); setMergeTable(Boolean(cleanValues.secondValues.length));
setTableData(fliterSkuListSortData([...skuList, ...createSkuList])); setTableData(fliterSkuListSortData([...createSkuList]));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
}; };
const batchChange = () => { const batchChange = () => {
const batchItem = form.getFieldValue('batchItem'); const values = form.getFieldsValue();
const bacthFirst = form.getFieldValue('bacthFirst'); const { batchItem, bacthFirst, bacthSecon } = values;
const bacthSecon = form.getFieldValue('bacthSecon');
const resetObject = batchTableSourceData({ batchItem, tableData, bacthSecon, bacthFirst }); const resetObject = batchTableSourceData({ batchItem, tableData, bacthSecon, bacthFirst });
setTableData(resetObject); setTableData(resetObject);
}; };
...@@ -323,6 +369,8 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -323,6 +369,8 @@ const FormPriceOrStock = forwardRef((props, ref) => {
const onSpecificationEvent = async () => { const onSpecificationEvent = async () => {
try { try {
const values = await form.validateFields(); const values = await form.validateFields();
console.log('values :>> ', values);
console.log('cleanArray(values.secondSpecValue) :>> ', cleanArray(values.secondSpecValue));
const cleanValues = { const cleanValues = {
firstSpec: values.firstSpec, firstSpec: values.firstSpec,
firstSpecId: values.firstSpecId, firstSpecId: values.firstSpecId,
...@@ -348,10 +396,12 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -348,10 +396,12 @@ const FormPriceOrStock = forwardRef((props, ref) => {
); );
onSpecChange(firstSpecValueList); onSpecChange(firstSpecValueList);
} }
onFinish();
}; };
const seconOnChangeEvent = async () => { const seconOnChangeEvent = async () => {
await onSpecificationEvent(); await onSpecificationEvent();
onFinish();
}; };
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
...@@ -400,16 +450,18 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -400,16 +450,18 @@ const FormPriceOrStock = forwardRef((props, ref) => {
specList={specList} specList={specList}
specDataList={specInitValue.secondSpecValue} specDataList={specInitValue.secondSpecValue}
/> />
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 20 }}> {/* <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 20 }}>
<Button type="primary" onClick={onFinish}> <Button type="primary" onClick={onFinish}>
生成商品信息 生成商品信息
</Button> </Button>
</div> */}
<div>
<CreateBatchFormItems
batchChange={batchChange}
specInitValue={specInitValue}
defaultColumns={defaultColumns}
/>
</div> </div>
<CreateBatchFormItems
batchChange={batchChange}
specInitValue={specInitValue}
defaultColumns={defaultColumns}
/>
</Form> </Form>
<EditFormTable <EditFormTable
ref={editRef} ref={editRef}
...@@ -420,8 +472,8 @@ const FormPriceOrStock = forwardRef((props, ref) => { ...@@ -420,8 +472,8 @@ const FormPriceOrStock = forwardRef((props, ref) => {
/> />
{customer.isCard && ( {customer.isCard && (
<> <>
<Title title="套餐内容" /> <Title title="套餐内容" key="tctitle" />
<FormPackage ref={packageRef} initData={tableData} /> <FormPackage ref={packageRef} initData={tableData} key="tc" />
</> </>
)} )}
</> </>
......
...@@ -92,19 +92,14 @@ const FormRuleSetting = forwardRef((props, ref) => { ...@@ -92,19 +92,14 @@ const FormRuleSetting = forwardRef((props, ref) => {
> >
<Form.Item name="purchaseTime" label="购买时间" {...rangeConfig}> <Form.Item name="purchaseTime" label="购买时间" {...rangeConfig}>
<RangePicker <RangePicker
showTime={{
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
}}
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
defaultPickerValue={[nowDateTime, nowDateTimeEnd]} defaultPickerValue={[nowDateTime, nowDateTimeEnd]}
/> />
</Form.Item> </Form.Item>
<Form.Item name="useTime" label="有效期" {...rangeConfig}> <Form.Item name="useTime" label="有效期" {...rangeConfig}>
<RangePicker <RangePicker
showTime={{
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
}}
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
defaultPickerValue={[nowDateTime, nowDateTimeEnd]}
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
......
/* eslint-disable guard-for-in */
/* eslint-disable no-restricted-syntax */
import React, { useState, useEffect, useContext, forwardRef, useImperativeHandle } from 'react'; import React, { useState, useEffect, useContext, forwardRef, useImperativeHandle } from 'react';
import { Form, Button } from 'antd'; import { Form, Button } from 'antd';
import { ServiceContext } from '../context'; import { ServiceContext } from '../context';
...@@ -15,6 +17,9 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -15,6 +17,9 @@ const FormRuleVPictures = forwardRef((props, ref) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const customer = useContext(ServiceContext); const customer = useContext(ServiceContext);
const typeConfig = TaskList(customer.canAddService, customer.canAddNormal);
const [{ imgConfig }] = typeConfig.filter(item => item.type === customer.productType);
useEffect(() => { useEffect(() => {
if (customer.isEdit) { if (customer.isEdit) {
if (editData) { if (editData) {
...@@ -64,7 +69,16 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -64,7 +69,16 @@ const FormRuleVPictures = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
onCheck, onCheck,
setFieldsValue: form.setFieldsValue, setFieldsValue: obj => {
setDetailImageList(obj.detailImageList || []);
for (const key in obj.imageList) {
if (!obj.imageList[key]) {
obj.imageList[key] = [];
}
}
setImageList(obj.imageList || {});
form.setFieldsValue(obj);
},
getFieldsValue: form.getFieldsValue, getFieldsValue: form.getFieldsValue,
reset: () => { reset: () => {
form.resetFields(); form.resetFields();
...@@ -97,6 +111,14 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -97,6 +111,14 @@ const FormRuleVPictures = forwardRef((props, ref) => {
}); });
}; };
// 拉取公共图片
const onPullCommonImg = key => {
const cimg = form.getFieldValue('commonImageList');
const obj = { ...imageList };
obj[key] = cimg;
setImageList(obj);
};
const onDetailSuccessImageList = imgList => { const onDetailSuccessImageList = imgList => {
setDetailImageList(imgList); setDetailImageList(imgList);
form.setFieldsValue({ form.setFieldsValue({
...@@ -104,11 +126,13 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -104,11 +126,13 @@ const FormRuleVPictures = forwardRef((props, ref) => {
}); });
}; };
const [{ imgConfig }] = TaskList.filter(item => item.type === customer.productType);
return ( return (
<Form <Form
form={form} form={form}
{...formItemLayout} labelCol={{ flex: '110px' }}
labelAlign="right"
labelWrap
colon
initialValues={{ initialValues={{
commonImageList: [], commonImageList: [],
cardImageList: [], cardImageList: [],
...@@ -141,9 +165,12 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -141,9 +165,12 @@ const FormRuleVPictures = forwardRef((props, ref) => {
]} ]}
> >
<UploadImage <UploadImage
disabled={customer.isService} multiple={!customer.isCard}
multiple={false} maxWidth={customer.isCard ? 0 : 1200}
maxHeight={customer.isCard ? 0 : 1200}
superTips="公共滑动图尺寸不可大于 1200*1200"
name="commonImageList" name="commonImageList"
disabled={customer.isDisabled}
limit={imgConfig.commonImageList.limit} limit={imgConfig.commonImageList.limit}
pictures={commonImageList} pictures={commonImageList}
setPictureList={list => onCommonSuccessEvent(list)} setPictureList={list => onCommonSuccessEvent(list)}
...@@ -163,9 +190,9 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -163,9 +190,9 @@ const FormRuleVPictures = forwardRef((props, ref) => {
]} ]}
> >
<UploadImage <UploadImage
disabled={customer.isService}
name="cardImageList" name="cardImageList"
limit={imgConfig.cardImageList.limit} limit={imgConfig.cardImageList.limit}
disabled={customer.isDisabled}
pictures={cardImageList} pictures={cardImageList}
setPictureList={list => onCardSuccessImageList(list)} setPictureList={list => onCardSuccessImageList(list)}
/> />
...@@ -184,16 +211,23 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -184,16 +211,23 @@ const FormRuleVPictures = forwardRef((props, ref) => {
extra={imgConfig.imageList.renderExtra()} extra={imgConfig.imageList.renderExtra()}
> >
<UploadImage <UploadImage
disabled={customer.isService}
name={key} name={key}
limit={11} limit={11}
disabled={customer.isDisabled}
pictures={imageList[key]} pictures={imageList[key]}
setPictureList={list => onPictureSuccessEvent(list, key)} setPictureList={list => onPictureSuccessEvent(list, key)}
/> />
</Form.Item> </Form.Item>
<Button className={commonStyle.pullImage} type="primary"> {!imageList[key]?.length && (
拉取公共图 <Button
</Button> disabled={imageList[key]?.length}
className={commonStyle.pullImage}
onClick={() => onPullCommonImg(key)}
type="primary"
>
拉取公共图
</Button>
)}
</div> </div>
))} ))}
<Form.Item <Form.Item
...@@ -209,9 +243,11 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -209,9 +243,11 @@ const FormRuleVPictures = forwardRef((props, ref) => {
extra={imgConfig.detailImageList.renderExtra()} extra={imgConfig.detailImageList.renderExtra()}
> >
<UploadImage <UploadImage
disabled={customer.isService}
limit={imgConfig.detailImageList.limit} limit={imgConfig.detailImageList.limit}
maxWidth={customer.isCard ? 0 : 800}
superTips="详情图宽度不可大于800"
name="detailImageList" name="detailImageList"
disabled={customer.isDisabled}
pictures={detailImageList} pictures={detailImageList}
setPictureList={list => onDetailSuccessImageList(list)} setPictureList={list => onDetailSuccessImageList(list)}
/> />
......
...@@ -5,6 +5,7 @@ import commonStyle from '../common.less'; ...@@ -5,6 +5,7 @@ import commonStyle from '../common.less';
export const TaskTypeSelect = props => { export const TaskTypeSelect = props => {
const customer = useContext(ServiceContext); const customer = useContext(ServiceContext);
const typeConfig = TaskList(customer.canAddService, customer.canAddNormal);
const selectTabs = task => { const selectTabs = task => {
if (!customer.isEdit) { if (!customer.isEdit) {
props.onChange(task); props.onChange(task);
...@@ -13,7 +14,7 @@ export const TaskTypeSelect = props => { ...@@ -13,7 +14,7 @@ export const TaskTypeSelect = props => {
return ( return (
<div className={commonStyle.prodcutContent}> <div className={commonStyle.prodcutContent}>
{TaskList.map(task => { {typeConfig.map(task => {
const activeClassName = props.productType === task.type ? commonStyle.activeCard : ''; const activeClassName = props.productType === task.type ? commonStyle.activeCard : '';
if (task.hide) return null; if (task.hide) return null;
return ( return (
......
...@@ -72,26 +72,83 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -72,26 +72,83 @@ const UploadImage = forwardRef((props, ref) => {
const freshFiles = fileList?.filter(ele => ele.uid !== file.uid); const freshFiles = fileList?.filter(ele => ele.uid !== file.uid);
bundleChange(freshFiles); bundleChange(freshFiles);
}; };
const checkFile = file =>
new Promise(resolve => { const cleanArray = (actual = []) =>
const curType = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase(); actual.reduce((prev, cur) => {
const fileType = ['jpg', 'jpeg', 'png']; cur && prev.push(cur);
if (!fileType.includes(curType)) { return prev;
notification.open({ }, []);
message: file.name,
description: '图片格式须为jpg、jpeg、png!', const warningTip = description => {
}); notification.warning({
return resolve(null); message: '图片上传失败',
description,
});
};
const getBase64 = (img, callback) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
};
const ImageInfo = file =>
new Promise((resolve, reject) => {
const LtMB = file.size / 1024 / 1024;
if (LtMB > 2) {
warningTip(`[${file.name}] 图片不可以大于2MB`);
resolve(null);
} }
if (file.size > MAX_FILE_SIZE * UNIT) { getBase64(file, url => {
notification.open({ const image = new Image();
message: file.name, image.addEventListener('load', () => {
description: `单个图片大小不能超过${MAX_FILE_SIZE}M!`, const { width } = image;
const { height } = image;
file.width = width;
file.height = height;
file.LtMB = LtMB;
resolve(file);
});
image.addEventListener('error', () => {
warningTip(`${file.name}图片上传失败!`);
resolve(null);
}); });
return resolve(null); image.src = url;
});
});
const CheckImageInfoList = async files => {
const promiseImage = files.map(file => ImageInfo(file));
const clearImage = await Promise.all(promiseImage);
return cleanArray(clearImage);
};
const isUploadNext = async imgFileList => {
const filterImage = imgFileList.filter(img => {
if (
(imgOptions.maxWidth && img.width > imgOptions.maxWidth) ||
(imgOptions.maxHeight && img.height > imgOptions.maxHeight)
) {
warningTip(`[${img.name}] ${imgOptions.superTips}`);
return false;
}
return true;
});
return filterImage;
};
const checkFile = files => {
const fileType = ['jpg', 'jpeg', 'png'];
const filterImage = files.filter(file => {
const curType = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
if (!fileType.includes(curType)) {
warningTip('图片格式须为jpg、jpeg、png!');
return false;
} }
return resolve(file); return true;
}); });
return filterImage;
};
const imageLoading = (file, ret) => const imageLoading = (file, ret) =>
new Promise(resolve => { new Promise(resolve => {
...@@ -119,12 +176,14 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -119,12 +176,14 @@ const UploadImage = forwardRef((props, ref) => {
}); });
return Upload.LIST_IGNORE; return Upload.LIST_IGNORE;
} }
const fileAll = fileArray.map(item => checkFile(item)); const flies = checkFile(fileArray);
const checkFiles = (await Promise.all(fileAll)).filter(item => item !== null); const optionsArray = await CheckImageInfoList(flies);
const checkFiles = await isUploadNext(optionsArray);
try { try {
if (checkFiles.length) { if (checkFiles.length) {
setUploadLoading(true); setUploadLoading(true);
const res = await merchantUpload(checkFiles); const res = await merchantUpload(checkFiles);
console.log('res :>> ', res);
if (res.data) { if (res.data) {
const proFiles = (res.data || []).map((urlItem, urlIndex) => const proFiles = (res.data || []).map((urlItem, urlIndex) =>
imageLoading(checkFiles[urlIndex], urlItem), imageLoading(checkFiles[urlIndex], urlItem),
...@@ -176,10 +235,12 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -176,10 +235,12 @@ const UploadImage = forwardRef((props, ref) => {
onClick={() => handlePreview(item)} onClick={() => handlePreview(item)}
/> */} /> */}
<EyeOutlined className={styles.maskIcon} onClick={() => handlePreview(item)} /> <EyeOutlined className={styles.maskIcon} onClick={() => handlePreview(item)} />
<DeleteOutlined {!disabled && (
className={styles.maskIcon} <DeleteOutlined
onClick={() => handleRemove(item)} className={styles.maskIcon}
/> onClick={() => handleRemove(item)}
/>
)}
{/* <Icon {/* <Icon
type="delete" type="delete"
className={styles.maskIcon} className={styles.maskIcon}
......
...@@ -7,12 +7,12 @@ export const formItemLayout = { ...@@ -7,12 +7,12 @@ export const formItemLayout = {
}, },
}; };
export const TaskList = [ export const TaskList = (canAddService, canAddNormal) => [
{ {
name: '实体商品', name: '实体商品',
type: 1, type: 1,
desc: '物流发货', desc: '物流发货',
hide: true, hide: !canAddNormal,
imgConfig: { imgConfig: {
commonImageList: { commonImageList: {
title: '公共滑动图', title: '公共滑动图',
...@@ -37,7 +37,7 @@ export const TaskList = [ ...@@ -37,7 +37,7 @@ export const TaskList = [
name: '虚拟商品', name: '虚拟商品',
type: 2, type: 2,
desc: '无需物流', desc: '无需物流',
hide: true, hide: !canAddNormal,
imgConfig: { imgConfig: {
commonImageList: { commonImageList: {
title: '公共滑动图', title: '公共滑动图',
...@@ -58,38 +58,11 @@ export const TaskList = [ ...@@ -58,38 +58,11 @@ export const TaskList = [
}, },
}, },
}, },
// {
// name: '电子卡卷',
// type: 3,
// desc: '无需物流',
// hide: true,
// imgConfig: {
// commonImageList: {
// title: '封面图片',
// rule: true,
// limit: 11,
// renderExtra(leng) {
// return `建议尺寸: ##宽##高 (${leng} / 1) `;
// },
// },
// imageList: {
// rule: true,
// limit: 1,
// },
// detailImageList: {
// title: '商品图片',
// rule: true,
// limit: null,
// renderExtra() {
// return '请上传商品图!';
// },
// },
// },
// },
{ {
name: '电子卡卷', name: '电子卡卷',
type: 4, type: 4,
desc: '无需物流', desc: '无需物流',
hide: !canAddService,
imgConfig: { imgConfig: {
commonImageList: { commonImageList: {
title: '封面图片', title: '封面图片',
...@@ -165,7 +138,7 @@ export const StaticColumns = customer => [ ...@@ -165,7 +138,7 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: () => customer.isJDGoods, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '佣金费率', title: '佣金费率',
...@@ -188,7 +161,7 @@ export const StaticColumns = customer => [ ...@@ -188,7 +161,7 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '销售价', title: '销售价',
...@@ -201,6 +174,7 @@ export const StaticColumns = customer => [ ...@@ -201,6 +174,7 @@ export const StaticColumns = customer => [
precision: 2, precision: 2,
min: 0, min: 0,
}, },
disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '重量(kg)', title: '重量(kg)',
...@@ -219,7 +193,7 @@ export const StaticColumns = customer => [ ...@@ -219,7 +193,7 @@ export const StaticColumns = customer => [
precision: 3, precision: 3,
max: 999999.999, max: 999999.999,
}, },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '库存', title: '库存',
...@@ -236,7 +210,10 @@ export const StaticColumns = customer => [ ...@@ -236,7 +210,10 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: v => v.id && customer.isService, disabeldRender: record => {
if (record.stock === null) return false;
return customer.isEdit && customer.isNormal;
},
}, },
{ {
title: '库存预警', title: '库存预警',
...@@ -244,13 +221,12 @@ export const StaticColumns = customer => [ ...@@ -244,13 +221,12 @@ export const StaticColumns = customer => [
editable: true, editable: true,
batchRole: [1], batchRole: [1],
role: [1, 4], role: [1, 4],
roleRules: { required: true },
roleProps: { roleProps: {
min: 0, min: 0,
precision: 0, precision: 0,
maxLength: 5, maxLength: 5,
}, },
// disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '商品自编码', title: '商品自编码',
...@@ -259,7 +235,7 @@ export const StaticColumns = customer => [ ...@@ -259,7 +235,7 @@ export const StaticColumns = customer => [
role: [1, 2], role: [1, 2],
inputType: 'input', inputType: 'input',
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '京东链接', title: '京东链接',
...@@ -268,7 +244,7 @@ export const StaticColumns = customer => [ ...@@ -268,7 +244,7 @@ export const StaticColumns = customer => [
role: [1, 2], role: [1, 2],
inputType: 'input', inputType: 'input',
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isService, disabeldRender: () => customer.isDisabled,
}, },
{ {
title: 'sku名称', title: 'sku名称',
...@@ -277,6 +253,7 @@ export const StaticColumns = customer => [ ...@@ -277,6 +253,7 @@ export const StaticColumns = customer => [
role: customer.isEdit && customer.isJDGoods ? [1, 2] : [], role: customer.isEdit && customer.isJDGoods ? [1, 2] : [],
inputType: 'btnText', inputType: 'btnText',
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isDisabled,
}, },
{ {
title: '操作', title: '操作',
...@@ -286,8 +263,10 @@ export const StaticColumns = customer => [ ...@@ -286,8 +263,10 @@ export const StaticColumns = customer => [
inputType: 'option', inputType: 'option',
roleProps: { roleProps: {
isJDGoods: customer.isJDGoods, isJDGoods: customer.isJDGoods,
disabled: customer.isDisabled,
min: 0, min: 0,
}, },
roleRules: { required: false }, roleRules: { required: false },
disabeldRender: () => customer.isDisabled,
}, },
]; ];
import React, { useState, useRef, useEffect, useCallback } from 'react'; import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Spin, Button, Modal, message, notification } from 'antd'; import { Spin, Button, Modal, message, notification } from 'antd';
import { ConsoleSqlOutlined } from '@ant-design/icons';
import { Title, WrapperContainer } from './components/CommonTemplate'; import { Title, WrapperContainer } from './components/CommonTemplate';
import { TaskTypeSelect } from './components/TaskTypeSelect'; import { TaskTypeSelect } from './components/TaskTypeSelect';
import FormInformationBasic from './components/FormInformationBasic'; import FormInformationBasic from './components/FormInformationBasic';
...@@ -8,12 +7,12 @@ import FormPriceOrStock from './components/FormPriceOrStock'; ...@@ -8,12 +7,12 @@ import FormPriceOrStock from './components/FormPriceOrStock';
import FormRuleSetting from './components/FormRuleSetting'; import FormRuleSetting from './components/FormRuleSetting';
import FormRuleVPictures from './components/FormRuleVPictures'; import FormRuleVPictures from './components/FormRuleVPictures';
import FormSettlementOthers from './components/FormSettlementOthers'; import FormSettlementOthers from './components/FormSettlementOthers';
import FormAttr from './components/FormAttr';
import { import {
merchantBrandList, merchantBrandList,
merchantSpecList, merchantSpecList,
afterSalesAddrsPage, afterSalesAddrsPage,
merchantgetJdPicList, merchantgetJdPicList,
supplierListQuery,
shopGetBySupplierId, shopGetBySupplierId,
merchantProductAdd, merchantProductAdd,
merchantProductEdit, merchantProductEdit,
...@@ -21,6 +20,7 @@ import { ...@@ -21,6 +20,7 @@ import {
} from './service'; } from './service';
import { isUrl, filterSendData, clearCurrent } from './utils'; import { isUrl, filterSendData, clearCurrent } from './utils';
import { ServiceContext } from './context'; import { ServiceContext } from './context';
import { GOOD_MANAGE } from '@/../config/permission.config';
/** /**
* 服务商品改造-商品模块 * 服务商品改造-商品模块
...@@ -28,17 +28,21 @@ import { ServiceContext } from './context'; ...@@ -28,17 +28,21 @@ import { ServiceContext } from './context';
* @returns ReactDOM * @returns ReactDOM
*/ */
const ServiceGoods = options => { const ServiceGoods = options => {
const { SourceData, categoryList, virtualCategoryList, specListData } = options; const { SourceData, categoryList, virtualCategoryList, specListData, permissions } = options;
const canAddService = permissions[GOOD_MANAGE.ADD_SERVICE_GOODS];
const canAddNormal = permissions[GOOD_MANAGE.ADD_NORMAL_GOODS];
const basicRef = useRef(null); const basicRef = useRef(null);
const stockRef = useRef(null); const stockRef = useRef(null);
const settingRef = useRef(null); const settingRef = useRef(null);
const picturesRef = useRef(null); const picturesRef = useRef(null);
const settleOtrRef = useRef(null); const settleOtrRef = useRef(null);
const attrRef = useRef(null);
const [pageId, setPageId] = useState(null); const [pageId, setPageId] = useState(null);
const [categoryIds, setCategoryIds] = useState([]); // 商品品类ID
const [isEdit, setIsEdit] = useState(false); // 是否是编辑状态 const [isEdit, setIsEdit] = useState(false); // 是否是编辑状态
const [productType, setProductType] = useState(4); // 商品状态 const [productType, setProductType] = useState(canAddNormal ? 1 : 4); // 商品状态
const [pageLoading, setPageLoading] = useState(false); // 页面加载状态 const [pageLoading, setPageLoading] = useState(false); // 页面加载状态
const [afterAddressList, setAfterAddressList] = useState([]); // 售后地址 const [afterAddressList, setAfterAddressList] = useState([]); // 售后地址
const [supplierIdList, setSupplierIdList] = useState([]); // 适用们店列表 const [supplierIdList, setSupplierIdList] = useState([]); // 适用们店列表
...@@ -47,8 +51,14 @@ const ServiceGoods = options => { ...@@ -47,8 +51,14 @@ const ServiceGoods = options => {
const [specList, setSpecList] = useState([]); // 规格列表 const [specList, setSpecList] = useState([]); // 规格列表
const [editData, setEditData] = useState({}); // 编辑保存数据 const [editData, setEditData] = useState({}); // 编辑保存数据
const [newCategoryList, setNewCategoryList] = useState({}); const [newCategoryList, setNewCategoryList] = useState({});
// const [shopList, setShopList] = useState([]); // 供应商列表 const [checkFormList] = useState([
const [checkFormList] = useState([basicRef, stockRef, settingRef, settleOtrRef, picturesRef]); basicRef,
attrRef,
stockRef,
settingRef,
settleOtrRef,
picturesRef,
]);
const [specKeyList, setSpecKeyList] = useState([]); // 记录一级规格key字段 const [specKeyList, setSpecKeyList] = useState([]); // 记录一级规格key字段
...@@ -56,6 +66,7 @@ const ServiceGoods = options => { ...@@ -56,6 +66,7 @@ const ServiceGoods = options => {
const productChange = task => { const productChange = task => {
setProductType(task.type); setProductType(task.type);
setCategoryIds([]);
const timer = setTimeout(() => { const timer = setTimeout(() => {
resetForm(); resetForm();
clearTimeout(timer); clearTimeout(timer);
...@@ -94,13 +105,6 @@ const ServiceGoods = options => { ...@@ -94,13 +105,6 @@ const ServiceGoods = options => {
} }
}; };
// const getSupplierListResponse = async () => {
// if (!shopList.length) {
// const result = await supplierListQuery();
// console.log('=================>result', result);
// setShopList(result.data);
// }
// };
const sendMerchantProductHttpRequest = async sendData => { const sendMerchantProductHttpRequest = async sendData => {
try { try {
setPageLoading(true); setPageLoading(true);
...@@ -125,7 +129,6 @@ const ServiceGoods = options => { ...@@ -125,7 +129,6 @@ const ServiceGoods = options => {
}; };
const shopGetByProductType = async type => { const shopGetByProductType = async type => {
console.log(newCategoryList[type]);
if (!newCategoryList[type]?.length) { if (!newCategoryList[type]?.length) {
const result = await getByProductType(type); const result = await getByProductType(type);
setNewCategoryList({ setNewCategoryList({
...@@ -133,12 +136,12 @@ const ServiceGoods = options => { ...@@ -133,12 +136,12 @@ const ServiceGoods = options => {
[type]: result.data || [], [type]: result.data || [],
}); });
} }
// console.log(result);
}; };
const submitEvent = async () => { const submitEvent = async () => {
const checkPromiseList = clearCurrent(checkFormList).map(({ current }) => current.onCheck()); const checkPromiseList = clearCurrent(checkFormList).map(({ current }) => current.onCheck());
const resuslt = await Promise.all(checkPromiseList); const resuslt = await Promise.all(checkPromiseList);
console.log('resuslt :>> ', resuslt);
if (!resuslt.includes(null)) { if (!resuslt.includes(null)) {
const params = resuslt.reduce((origin, item) => { const params = resuslt.reduce((origin, item) => {
const { temp, ...other } = item; const { temp, ...other } = item;
...@@ -149,6 +152,7 @@ const ServiceGoods = options => { ...@@ -149,6 +152,7 @@ const ServiceGoods = options => {
if (isEdit) { if (isEdit) {
sendData.id = pageId; sendData.id = pageId;
} }
console.log('sendData :>> ', sendData);
sendMerchantProductHttpRequest(sendData); sendMerchantProductHttpRequest(sendData);
} }
}; };
...@@ -160,11 +164,9 @@ const ServiceGoods = options => { ...@@ -160,11 +164,9 @@ const ServiceGoods = options => {
const detailList = result.detailList || []; const detailList = result.detailList || [];
const newImageList = imageList[result.firstSpecValue]; const newImageList = imageList[result.firstSpecValue];
const carouseList = result.carouseList || []; const carouseList = result.carouseList || [];
imageList[result.firstSpecValue] = newImageList imageList[result.firstSpecValue] =
? [...newImageList, ...carouseList] (newImageList ? [...newImageList, ...carouseList] : carouseList) || [];
: carouseList;
picturesRef.current.setFieldsValue({ picturesRef.current.setFieldsValue({
// [`imageList[${data.firstSpecValue}]`]: this.state.colorImg[data.firstSpecValue],
imageList, imageList,
detailImageList: [...detailImageList, ...detailList], detailImageList: [...detailImageList, ...detailList],
}); });
...@@ -178,7 +180,6 @@ const ServiceGoods = options => { ...@@ -178,7 +180,6 @@ const ServiceGoods = options => {
} }
setPageLoading(true); setPageLoading(true);
await shopGetBySupplierIdResponse(); await shopGetBySupplierIdResponse();
// await getSupplierListResponse();
await getMerchantBrandList(); await getMerchantBrandList();
await getAfterSalesAddrsPage(); await getAfterSalesAddrsPage();
await getMerchantSpecList(); await getMerchantSpecList();
...@@ -186,7 +187,7 @@ const ServiceGoods = options => { ...@@ -186,7 +187,7 @@ const ServiceGoods = options => {
setEditData(SourceData); setEditData(SourceData);
setPageId(SourceData.id); setPageId(SourceData.id);
setProductType(SourceData.productType); setProductType(SourceData.productType);
// changeCheckList(SourceData.productType); setCategoryIds(SourceData.infoMation.categoryId || []);
setIsEdit(true); setIsEdit(true);
} }
setPageLoading(false); setPageLoading(false);
...@@ -199,6 +200,10 @@ const ServiceGoods = options => { ...@@ -199,6 +200,10 @@ const ServiceGoods = options => {
} }
}, [productType, options.visible]); }, [productType, options.visible]);
useEffect(() => {
setProductType(canAddNormal ? 1 : 4);
}, [canAddNormal]);
const onSpecCommonImgEvent = useCallback( const onSpecCommonImgEvent = useCallback(
keys => { keys => {
setSpecKeyList(keys); setSpecKeyList(keys);
...@@ -225,13 +230,21 @@ const ServiceGoods = options => { ...@@ -225,13 +230,21 @@ const ServiceGoods = options => {
}); });
} }
}; };
const onCategoryChange = e => {
setCategoryIds(e);
};
const providerValue = { const providerValue = {
pageId, pageId,
isEdit, isEdit,
productType, productType,
canAddService, // 是否可以添加服务商品(电子卡券)
canAddNormal, // 是否可以添加实物商品
isCard: productType === 4, isCard: productType === 4,
isService: SourceData.state && SourceData.state !== 4, // 0, "商品删除" 1, "新建" 2, "提交审核" 3, "待审核" 4, "驳回" 5, "未上架" 6, "已上架" 7, "已下架"
isNormal: SourceData.state && SourceData.state !== 4, // 商品不是驳回状态
// 当商品进行编辑 & 类型不为电子卡券 & 商品状态不为驳回 禁用当前功能
isDisabled: isEdit && productType !== 4 && SourceData.state && SourceData.state !== 4,
isJDGoods: isEdit && SourceData.pageProductType && +SourceData.pageProductType !== 1, isJDGoods: isEdit && SourceData.pageProductType && +SourceData.pageProductType !== 1,
onEventBus, onEventBus,
}; };
...@@ -270,8 +283,14 @@ const ServiceGoods = options => { ...@@ -270,8 +283,14 @@ const ServiceGoods = options => {
brandList={brandList} brandList={brandList}
afterAddressList={afterAddressList} afterAddressList={afterAddressList}
specListData={specListData} specListData={specListData}
onCategoryChange={onCategoryChange}
/> />
{[1, 2].includes(productType) && [
<Title title="商品属性" key="attrtitle" />,
<FormAttr key="attr" ref={attrRef} categoryIds={categoryIds} initData={editData} />,
]}
<Title title="价格与库存" /> <Title title="价格与库存" />
<FormPriceOrStock <FormPriceOrStock
ref={stockRef} ref={stockRef}
......
...@@ -97,3 +97,9 @@ export const getByProductType = type => ...@@ -97,3 +97,9 @@ export const getByProductType = type =>
prefix: goodsApi, prefix: goodsApi,
headers, headers,
}); });
// 获取类目关联属性
export const apiGetAttribute = categoryId =>
request.get(`/api/kdsp/category/template/ref/attribute/detail?categoryId=${categoryId}`, {
prefix: goodsApi,
});
...@@ -107,10 +107,10 @@ const filterItems = (type, props) => { ...@@ -107,10 +107,10 @@ const filterItems = (type, props) => {
export const filterSendData = (type, params) => { export const filterSendData = (type, params) => {
console.log('===============>生成数据', params); console.log('===============>生成数据', params);
const { infoMation, infoImageData } = params; const { infoMation, infoImageData, attributeApplyList } = params;
const items = filterItems(type, params); const items = filterItems(type, params);
const commonImageList = type === 4 ? [] : infoImageData.commonImageList; const commonImageList = type === 4 ? [] : infoImageData.commonImageList;
return { const obj = {
type, type,
items, items,
name: infoMation.name, name: infoMation.name,
...@@ -123,6 +123,10 @@ export const filterSendData = (type, params) => { ...@@ -123,6 +123,10 @@ export const filterSendData = (type, params) => {
detailImageList: infoImageData.detailImageList, detailImageList: infoImageData.detailImageList,
commonImageList, commonImageList,
}; };
if (attributeApplyList && attributeApplyList.attributeApplyList) {
obj.attributeApplyList = attributeApplyList.attributeApplyList;
}
return obj;
}; };
export const fliterSkuListSortData = list => { export const fliterSkuListSortData = list => {
...@@ -178,29 +182,38 @@ const createInitSkuItems = () => ({ ...@@ -178,29 +182,38 @@ const createInitSkuItems = () => ({
name: null, name: null,
}); });
export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { const getSecordValue = (firstSpecValue, sec, skuList = []) =>
skuList.find(
sku =>
sku.firstSpecValue === firstSpecValue &&
(!sku.secondSpecValue || sku.secondSpecValue === sec.secondSpecValue),
);
export const createSkuListData = (first, second, firstSpecId, secondSpecId, skuList) => {
const list = []; const list = [];
const skuItem = createInitSkuItems(); const skuItem = createInitSkuItems();
console.log(first, second, firstSpecId, secondSpecId);
if (first && first.length) { if (first && first.length) {
// 一级规格有值时,生成的编辑表格 // 一级规格有值时,生成的编辑表格
first.forEach(fir => { first.forEach(fir => {
const copy = { ...skuItem }; let copy = { ...skuItem };
copy.firstSpecId = firstSpecId; copy.firstSpecId = firstSpecId;
copy.firstSpecValue = fir.firstSpecValue; copy.firstSpecValue = fir.firstSpecValue;
// console.log(copy);
if (second.length) { if (second.length) {
second.forEach(sec => { second.forEach(sec => {
const copySec = { ...copy }; const v = getSecordValue(fir.firstSpecValue, sec, skuList);
const copySec = v || { ...copy };
copySec.secondSpecId = secondSpecId; copySec.secondSpecId = secondSpecId;
copySec.secondSpecValue = sec.secondSpecValue; copySec.secondSpecValue = sec.secondSpecValue;
delete copySec.rowSpanCount;
list.push(copySec); list.push(copySec);
}); });
return; return;
} }
const v = getSecordValue(`${fir.firstSpecValue}`, {}, skuList);
if (v) {
copy = { ...v };
}
list.push(copy); list.push(copy);
}); });
} else if (second && second.length) { } else if (second && second.length) {
...@@ -211,6 +224,8 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { ...@@ -211,6 +224,8 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => {
copy.secondSpecValue = sec.secondSpecValue; copy.secondSpecValue = sec.secondSpecValue;
list.push(copy); list.push(copy);
}); });
} else if (skuList && skuList.length) {
list.push(...skuList);
} else { } else {
// 缺少一级和二级规格时生成的编辑表格 // 缺少一级和二级规格时生成的编辑表格
list.push(skuItem); list.push(skuItem);
...@@ -218,7 +233,7 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => { ...@@ -218,7 +233,7 @@ export const createSkuListData = (first, second, firstSpecId, secondSpecId) => {
return list; return list;
}; };
export const createProductData = (props, isEdit) => { export const createProductData = (props, isEdit, skuList) => {
const { const {
firstSpecId, firstSpecId,
secondSpecId, secondSpecId,
...@@ -227,20 +242,13 @@ export const createProductData = (props, isEdit) => { ...@@ -227,20 +242,13 @@ export const createProductData = (props, isEdit) => {
fisrtInIdList, fisrtInIdList,
secndInIdList, secndInIdList,
} = props; } = props;
const newFirstList = fisrtNoIdList.concat(fisrtInIdList || []);
let list = []; let list = [];
// if (!isFirstSame && !isSecondSame) { if (isEdit) {
if (!isEdit) { const newFirstList = fisrtNoIdList.concat(fisrtInIdList || []);
list = createSkuListData(fisrtNoIdList, secndNoIdList, firstSpecId, secondSpecId); const newSecondList = secndInIdList.concat(secndNoIdList || []);
list = createSkuListData(newFirstList, newSecondList, firstSpecId, secondSpecId, skuList);
} else { } else {
const list1 = fisrtNoIdList.length list = createSkuListData(fisrtNoIdList, secndNoIdList, firstSpecId, secondSpecId);
? createSkuListData(fisrtNoIdList, secndInIdList, firstSpecId, secondSpecId)
: [];
const list2 = secndNoIdList.length
? createSkuListData(newFirstList, secndNoIdList, firstSpecId, secondSpecId)
: [];
list = [...list1, ...list2];
} }
// }
return list; return list;
}; };
...@@ -94,7 +94,9 @@ class Socket extends EventEmitter { ...@@ -94,7 +94,9 @@ class Socket extends EventEmitter {
} }
}, 5000); }, 5000);
}; };
reconnect(); if (process.env.NODE_ENV === 'production') {
reconnect();
}
}; };
onerror = e => { onerror = e => {
...@@ -126,9 +128,9 @@ class Socket extends EventEmitter { ...@@ -126,9 +128,9 @@ class Socket extends EventEmitter {
// 保持连接-默认每3分钟重置一下服务器关闭时间 // 保持连接-默认每3分钟重置一下服务器关闭时间
heartBeat(time) { heartBeat(time) {
console.log('ws: call heartBeat', new Date().getTime()); // console.log('ws: call heartBeat', new Date().getTime());
this.heartBeatTimer = setTimeout(() => { this.heartBeatTimer = setTimeout(() => {
console.log('ws: sent heart beat', new Date().getTime()); // console.log('ws: sent heart beat', new Date().getTime());
this.sendMessage('HeartBeat'); this.sendMessage('HeartBeat');
this.heartBeat(time); this.heartBeat(time);
}, time || 45000); }, time || 45000);
......
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