Commit aeac15f4 authored by 杨鑫's avatar 杨鑫

Merge branch 'feature/commodity-properties' into 'master'

Feature/commodity properties

See merge request !62
parents 7eefd136 24e5ad8c
...@@ -14,5 +14,6 @@ module.exports = { ...@@ -14,5 +14,6 @@ module.exports = {
'@typescript-eslint/no-unused-vars': ['off'], '@typescript-eslint/no-unused-vars': ['off'],
'import/no-unresolved': 0, 'import/no-unresolved': 0,
'import/extensions': 0, 'import/extensions': 0,
'no-unused-expressions': ['error', { allowShortCircuit: true }],
}, },
}; };
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 = 'xyqb';
const envAPi = { const envAPi = {
api: 'https://security-xyqb.liangkebang.net', //'https://security-xyqb.liangkebang.net', api: `https://security-${environment}.liangkebang.net`,
kdspOpApi: 'https://sc-merchant-api-xyqb.liangkebang.net', kdspOpApi: `https://sc-merchant-api-${environment}.liangkebang.net`,
kdspApi: 'https://sc-merchant-api-xyqb.liangkebang.net', kdspApi: `https://sc-merchant-api-${environment}.liangkebang.net`,
goodsApi: 'https://sc-merchant-api-xyqb.liangkebang.net', goodsApi: `https://sc-merchant-api-${environment}.liangkebang.net`,
// kdspOpApi: 'https://kdsp-operation-xyqb.liangkebang.net', querysApi: `https://sc-merchant-api-${environment}.liangkebang.net/admin/merchant/sc-settlement`,
// kdspApi: 'https://sc-op-api-xyqb.liangkebang.net', prologueDomain: `https://mall-${environment}.liangkebang.net`,
// goodsApi: 'https://sc-op-api-xyqb.liangkebang.net', qiniuHost: `https://kdspstatic.q-gp.com/`,
querysApi: 'https://sc-merchant-api-sc.liangkebang.net', opapiHost: `https://yxm-gateway-${environment}.liangkebang.net`,
// goodsApi: '//192.168.188.111:7000',
prologueDomain: 'https://mall-sc.liangkebang.net',
// qiniuHost: 'https://appsync.lkbang.net',
qiniuHost: 'https://kdspstatic.q-gp.com/',
opapiHost: 'https://opapi-sc.liangkebang.net',
}; };
const prodApi = { const prodApi = {
...@@ -26,7 +21,7 @@ const prodApi = { ...@@ -26,7 +21,7 @@ const prodApi = {
goodsApi: 'https://sc-merchant-api.q-gp.com', // 线上环境打包域名 goodsApi: 'https://sc-merchant-api.q-gp.com', // 线上环境打包域名
qiniuHost: 'https://kdspstatic.q-gp.com/', qiniuHost: 'https://kdspstatic.q-gp.com/',
// talos 后面要下线 // talos 后面要下线
opapiHost: '//talos.xyqb.com', opapiHost: '//gw.yxmie.com',
// opapiHost: 'https://opapi.q-gp.com', // opapiHost: 'https://opapi.q-gp.com',
// querysApi: 'https://sc-settlement-api.q-gp.com', // querysApi: 'https://sc-settlement-api.q-gp.com',
querysApi: 'https://sc-merchant-api.q-gp.com/admin/merchant/sc-settlement', querysApi: 'https://sc-merchant-api.q-gp.com/admin/merchant/sc-settlement',
......
...@@ -2,7 +2,13 @@ ...@@ -2,7 +2,13 @@
import { Form } from '@ant-design/compatible'; import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css'; import '@ant-design/compatible/assets/index.css';
import { MinusCircleOutlined, PlusOutlined, RestOutlined } from '@ant-design/icons'; import {
MinusCircleOutlined,
PlusOutlined,
RestOutlined,
DownOutlined,
UpOutlined,
} from '@ant-design/icons';
import { import {
Modal, Modal,
Table, Table,
...@@ -37,6 +43,7 @@ import { ...@@ -37,6 +43,7 @@ import {
addGoods, addGoods,
editGoods, editGoods,
queryAllAfterAddress, queryAllAfterAddress,
apiGetAttribute,
} from '../service'; } from '../service';
import styles from '../style.less'; import styles from '../style.less';
import Upload from '../../components/sortablUpload'; import Upload from '../../components/sortablUpload';
...@@ -68,17 +75,31 @@ class goodsManage extends Component { ...@@ -68,17 +75,31 @@ class goodsManage extends Component {
productType: 1, productType: 1,
confirmLoading: false, confirmLoading: false,
afterAddressList: {}, afterAddressList: {},
// isAttrLoading: false,
categoryAttrs: [], // 获取类目下属性
}; };
componentDidMount() { componentDidMount() {
this.getSpecData(); this.getSpecData();
this.getBrandData(); this.getBrandData();
this.getAfterAddressData(); this.getAfterAddressData();
const { initData = {} } = this.props;
const isEdit = Object.keys(initData).length !== 0;
if (isEdit) {
this.getAttribute(
initData.thirdCategoryId || initData.secondCategoryId || initData.firstCategoryId,
);
}
} }
componentWillReceiveProps() { // componentWillReceiveProps(nextProps) {
this.setState({ isCancel: false }); // if (nextProps.visible && !this.state.isAttrLoading) {
} // this.setState({
// isAttrLoading: true,
// });
// }
// this.setState({ isCancel: false });
// }
// 获取售后地址 // 获取售后地址
getAfterAddressData = async () => { getAfterAddressData = async () => {
...@@ -204,8 +225,24 @@ class goodsManage extends Component { ...@@ -204,8 +225,24 @@ class goodsManage extends Component {
this.setState({ initForm }); 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 => { treeChange = value => {
this.setState({ categoryId: value[value.length - 1], initCascader: value }); const cid = value[value.length - 1];
this.setState({ categoryId: cid, initCascader: value });
if (value.length === 3) {
this.getAttribute(cid);
}
}; };
remove = (flag, k) => { remove = (flag, k) => {
...@@ -350,6 +387,18 @@ class goodsManage extends Component { ...@@ -350,6 +387,18 @@ class goodsManage extends Component {
}); });
}; };
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 => { confirm = async isContinue => {
const { const {
...@@ -359,6 +408,7 @@ class goodsManage extends Component { ...@@ -359,6 +408,7 @@ class goodsManage extends Component {
} = this.props; } = this.props;
const { editData, productType } = this.state; const { editData, productType } = this.state;
validateFields(async (errors, values) => { validateFields(async (errors, values) => {
console.log('values :>> ', values);
if (!values.afterAddressId) { if (!values.afterAddressId) {
notification.error({ notification.error({
message: '请选择售后地址', message: '请选择售后地址',
...@@ -390,6 +440,45 @@ class goodsManage extends Component { ...@@ -390,6 +440,45 @@ class goodsManage extends Component {
}); });
} }
}); });
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 => ({ await this.setState(prev => ({
confirmLoading: true, confirmLoading: true,
createData: { createData: {
...@@ -406,6 +495,7 @@ class goodsManage extends Component { ...@@ -406,6 +495,7 @@ class goodsManage extends Component {
specs, specs,
character: values.character, character: values.character,
afterAddressId: values.afterAddressId, afterAddressId: values.afterAddressId,
attributeApplyList,
}, },
})); }));
const data = initData.id const data = initData.id
...@@ -475,6 +565,70 @@ class goodsManage extends Component { ...@@ -475,6 +565,70 @@ class goodsManage extends Component {
this.BatchSetting.formRef.current.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) => { validateToInputName = (rule, value, callback) => {
if (value.trim().length < 2) { if (value.trim().length < 2) {
callback(new Error('商品名称不可小于2个字符')); callback(new Error('商品名称不可小于2个字符'));
...@@ -515,6 +669,10 @@ class goodsManage extends Component { ...@@ -515,6 +669,10 @@ class goodsManage extends Component {
labelCol: { span: 2 }, labelCol: { span: 2 },
wrapperCol: { span: 22 }, wrapperCol: { span: 22 },
}; };
const formItemAttr = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const { const {
colorImg, colorImg,
productType, productType,
...@@ -525,6 +683,7 @@ class goodsManage extends Component { ...@@ -525,6 +683,7 @@ class goodsManage extends Component {
} = this.state; } = this.state;
const skuSpeFirstKeys = initData.firstSpecList || []; const skuSpeFirstKeys = initData.firstSpecList || [];
const skuSpeSecondKeys = initData.secondSpecList || []; const skuSpeSecondKeys = initData.secondSpecList || [];
const skuOldAttr = initData.productAttributeApplyList?.oldProductAttributeApplyList || [];
const treeDataArray = productType === 2 ? virtualTreeData : treeData; const treeDataArray = productType === 2 ? virtualTreeData : treeData;
const brandListArray = productType === 2 ? brandList : normalBrandList; const brandListArray = productType === 2 ? brandList : normalBrandList;
dataInit(this.state.editData); dataInit(this.state.editData);
...@@ -534,11 +693,6 @@ class goodsManage extends Component { ...@@ -534,11 +693,6 @@ class goodsManage extends Component {
if (isEdit && !initData.editData[0]?.firstSpec && !initData.editData[0]?.secondSpec) { if (isEdit && !initData.editData[0]?.firstSpec && !initData.editData[0]?.secondSpec) {
colorKeys = colorKeys.length > 1 ? colorKeys.filter(item => item !== 'null') : colorKeys; colorKeys = colorKeys.length > 1 ? colorKeys.filter(item => item !== 'null') : colorKeys;
} }
const optionsWithDisabled = [
{ label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange', disabled: false },
];
return ( return (
<Modal <Modal
...@@ -721,6 +875,103 @@ class goodsManage extends Component { ...@@ -721,6 +875,103 @@ class goodsManage extends Component {
: ''} : ''}
</Row> </Row>
</Card> </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}> <Card className={styles.card} bordered={false}>
<Row> <Row>
<FormItem label="一级规格"> <FormItem label="一级规格">
...@@ -760,7 +1011,7 @@ class goodsManage extends Component { ...@@ -760,7 +1011,7 @@ class goodsManage extends Component {
value={k} value={k}
disabled disabled
placeholder="请输入规格名称" placeholder="请输入规格名称"
style={{ width: '15%', margin: 5 }} style={{ width: '15%', margin: '5px 5px 28px 5px' }}
/> />
), ),
)} )}
...@@ -785,6 +1036,7 @@ class goodsManage extends Component { ...@@ -785,6 +1036,7 @@ class goodsManage extends Component {
{firstKeys.length > 0 ? ( {firstKeys.length > 0 ? (
<MinusCircleOutlined <MinusCircleOutlined
className="dynamic-delete-button" className="dynamic-delete-button"
style={{ marginBottom: 0 }}
onClick={() => this.remove('firstKeys', k)} onClick={() => this.remove('firstKeys', k)}
/> />
) : null} ) : null}
...@@ -835,7 +1087,7 @@ class goodsManage extends Component { ...@@ -835,7 +1087,7 @@ class goodsManage extends Component {
value={k} value={k}
disabled disabled
placeholder="请输入规格名称" placeholder="请输入规格名称"
style={{ width: '15%', margin: 5 }} style={{ width: '15%', margin: '5px 5px 28px 5px' }}
/> />
))} ))}
{secondKeys.map(k => ( {secondKeys.map(k => (
......
import React, { useState, useEffect } from 'react';
import { Modal, Button } from 'antd';
import { apiQueryLastAuditRecord } from '../service';
const InfoAudit = props => {
const [audit, setAudit] = useState({});
const getRecord = async () => {
const res = await apiQueryLastAuditRecord(props.skuInfo.skuId);
if (res && res.data) {
console.log('res :>> ', res);
setAudit(res.data);
}
};
const getContent = () => {
const obj = {
1: '-',
2: '审核通过',
3: `审核拒绝,${audit.rejectReason}`,
};
if (audit) {
return obj[audit.status] || '';
}
return '';
};
useEffect(() => {
if (props.visible) {
getRecord();
}
}, [props.visible]);
return (
<Modal
title="商品信息变更审核"
visible={props.visible}
closable={false}
footer={[
audit.status === 3 &&
props.canEditable &&
(props.skuInfo.state === 4 ||
(props.skuInfo.state >= 5 && props.skuInfo.updateState !== 1)) && (
<Button key="back" type="primary" onClick={() => props.onEdit()}>
再次编辑
</Button>
),
<Button key="close" onClick={() => props.onCancel()}>
关闭
</Button>,
]}
>
<p>审核状态:{audit.statusDesc}</p>
<p>申请时间:{audit.createdAt}</p>
<p>审核结果:{getContent()}</p>
</Modal>
);
};
export default InfoAudit;
import { Form } from '@ant-design/compatible'; import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css'; import '@ant-design/compatible/assets/index.css';
import { Card, Pagination, Table, notification, Drawer, Spin, Button } from 'antd'; import { Card, Pagination, Table, notification, Drawer, Spin, Button, Modal } from 'antd';
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 { sortBy } from 'lodash';
import { da } from 'date-fns/locale';
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';
...@@ -27,6 +26,7 @@ import { column, JDSHOPID, ProcessEditData } from './staticdata'; ...@@ -27,6 +26,7 @@ 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 { GOOD_MANAGE } from '@/../config/permission.config'; import { GOOD_MANAGE } from '@/../config/permission.config';
...@@ -58,6 +58,8 @@ class goodsManage extends Component { ...@@ -58,6 +58,8 @@ class goodsManage extends Component {
serviceVisble: false, serviceVisble: false,
serviceData: {}, serviceData: {},
visibleAuditModal: false,
auditRow: {}, // 查看审核信息使用
}; };
currentLog = null; currentLog = null;
...@@ -495,18 +497,20 @@ class goodsManage extends Component { ...@@ -495,18 +497,20 @@ class goodsManage extends Component {
title="商品预览" title="商品预览"
></iframe> ></iframe>
</Drawer> </Drawer>
<CreateModal {this.state.createVisible && (
initData={this.state.initData} <CreateModal
visible={this.state.createVisible} initData={this.state.initData}
onCancel={() => { visible={this.state.createVisible}
this.setState({ createVisible: false, initData: {} }); onCancel={() => {
}} this.setState({ createVisible: false, initData: {} });
query={() => this.handleSearch()} }}
shopList={this.filterShopList(this.shopList, Object.keys(this.state.initData).length)} query={() => this.handleSearch()}
treeData={this.state.treeData} shopList={this.filterShopList(this.shopList, Object.keys(this.state.initData).length)}
virtualTreeData={this.state.virtualTreeData} treeData={this.state.treeData}
specListData={this.state.specListData} virtualTreeData={this.state.virtualTreeData}
></CreateModal> specListData={this.state.specListData}
></CreateModal>
)}
<UpdateStock <UpdateStock
visible={this.state.updateStockVisible} visible={this.state.updateStockVisible}
...@@ -537,6 +541,22 @@ class goodsManage extends Component { ...@@ -537,6 +541,22 @@ class goodsManage extends Component {
specListData={this.state.specListData} specListData={this.state.specListData}
/> />
</Spin> </Spin>
<InfoAudit
visible={this.state.visibleAuditModal}
skuInfo={this.state.auditRow}
canEditable={this.canEditable}
onCancel={() => {
this.setState({ visibleAuditModal: false, auditRow: {} });
}}
onEdit={() => {
this.setState({ visibleAuditModal: false, auditRow: {} });
if (this.state.auditRow.type === 4) {
this.serviceVisbleChange(this.state.auditRow);
} else {
this.onUpdateInfo(this.state.auditRow);
}
}}
/>
</PageHeaderWrapper> </PageHeaderWrapper>
); );
} }
......
...@@ -9,6 +9,10 @@ const headers = { ...@@ -9,6 +9,10 @@ const headers = {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
}; };
/**
* 商品列表
* yapi: http://yapi.quantgroups.com/project/389/interface/api/23814
*/
export async function searchList(params) { export async function searchList(params) {
return request.post('/product/api/merchant/page', { return request.post('/product/api/merchant/page', {
prefix: goodsApi, prefix: goodsApi,
...@@ -42,6 +46,16 @@ export async function getBrandList() { ...@@ -42,6 +46,16 @@ export async function getBrandList() {
}); });
} }
// 获取类目关联属性
export async function apiGetAttribute(categoryId) {
const data = await request.get(
`/api/kdsp/category/template/ref/attribute/detail?categoryId=${categoryId}`,
{
prefix: goodsApi,
},
);
return data;
}
// 编辑--获取详情 // 编辑--获取详情
export async function spuDetail(params) { export async function spuDetail(params) {
return request.post('/product/api/merchant/detail', { return request.post('/product/api/merchant/detail', {
...@@ -73,6 +87,15 @@ export async function categoryList() { ...@@ -73,6 +87,15 @@ export async function categoryList() {
prefix: goodsApi, prefix: goodsApi,
}); });
} }
/**
* 商品分类
* type 商品类型:1-实物类,2-虚拟类,4-服务类
* */
export async function apiCategoryListType(type) {
return request.get(`/product/category/getByProductType/${type}`, {
prefix: goodsApi,
});
}
// 批量修改 // 批量修改
export async function uploadFile(file) { export async function uploadFile(file) {
...@@ -240,3 +263,9 @@ export const apiChangeStateGoods = async params => { ...@@ -240,3 +263,9 @@ export const apiChangeStateGoods = async params => {
}); });
return data; return data;
}; };
// 查询sku最后一条审核记录
export const apiQueryLastAuditRecord = skuId =>
request.get(`/api/kdsp/sku/last/audit/record?skuId=${skuId}`, {
prefix: goodsApi,
});
...@@ -3,7 +3,7 @@ import { Button, Badge, Switch, Modal } from 'antd'; ...@@ -3,7 +3,7 @@ import { Button, Badge, Switch, Modal } from 'antd';
import { ExclamationCircleOutlined } from '@ant-design/icons'; import { ExclamationCircleOutlined } from '@ant-design/icons';
import styles from './style.less'; import styles from './style.less';
import { resetTime } from '../../utils/utils'; import { resetTime } from '../../utils/utils';
import { apiChangeStateGoods } from './service'; import { apiChangeStateGoods, apiQueryLastAuditRecord } from './service';
const { confirm } = Modal; const { confirm } = Modal;
...@@ -50,6 +50,12 @@ export function column() { ...@@ -50,6 +50,12 @@ export function column() {
}, },
}); });
}; };
const onShowAudit = row => {
this.setState({
auditRow: row,
visibleAuditModal: true,
});
};
return [ return [
{ {
...@@ -183,7 +189,15 @@ export function column() { ...@@ -183,7 +189,15 @@ export function column() {
render: (_, row) => ( render: (_, row) => (
<div> <div>
<p>{row.state >= 5 ? '审核通过' : _}</p> <p>{row.state >= 5 ? '审核通过' : _}</p>
<p>{row.updateStateDesc || '_ _'}</p> <div>
{row.updateState ? (
<Button onClick={() => onShowAudit(row)} type="link">
{row.updateStateDesc}
</Button>
) : (
'--'
)}
</div>
</div> </div>
), ),
}, },
......
...@@ -110,3 +110,19 @@ ...@@ -110,3 +110,19 @@
color: #d9363e; color: #d9363e;
line-height: 1; line-height: 1;
} }
.cardTitle {
padding: 15px;
font-weight: bold;
font-size: 18px;
}
.stateAuditTxt {
color: #1890ff;
cursor: pointer;
}
.attrbox {
max-height: 384px;
overflow: hidden;
}
.attrboxMore {
max-height: max-content;
}
...@@ -46,19 +46,21 @@ class PicturesWall extends React.Component { ...@@ -46,19 +46,21 @@ class PicturesWall extends React.Component {
}; };
customRequest = ({ file, onError, onSuccess }) => { customRequest = ({ file, onError, onSuccess }) => {
let filename = '';
let suffix = '';
if (file.name) { if (file.name) {
const lastFile = file.name.split('.'); const index = file.name.lastIndexOf('.');
const index = lastFile.length - 1; filename = file.name.substr(0, index);
suffix = file.name.substr(index + 1, file.name.length - 1);
const types = ['pdf', 'doc', 'docx', 'zip', 'rar', 'png', 'jpeg']; const types = ['pdf', 'doc', 'docx', 'zip', 'rar', 'png', 'jpeg'];
if (!types.includes(lastFile[index])) { if (!types.includes(suffix)) {
message.error('文件格式错误!'); message.error('文件格式错误!');
return; return;
} }
} }
const vm = this; const vm = this;
const name = file.name + file.uid;
// eslint-disable-next-line new-cap // eslint-disable-next-line new-cap
const data = file.name + new Date().getTime(); const data = `${filename}-${new Date().getTime()}.${suffix}`;
const observable = qiniu.upload(file, data, token); const observable = qiniu.upload(file, data, token);
const observer = { const observer = {
next() { next() {
......
...@@ -172,7 +172,6 @@ const EditFormTable = forwardRef((props, ref) => { ...@@ -172,7 +172,6 @@ const EditFormTable = forwardRef((props, ref) => {
return ( return (
<> <>
<Form form={form} scrollToFirstError component={false}> <Form form={form} scrollToFirstError component={false}>
{/* <Button onClick={onCheck}>测试</Button> */}
<EditableContext.Provider value={form}> <EditableContext.Provider value={form}>
<Table <Table
scroll={{ y: 300, x: 1000 }} scroll={{ y: 300, x: 1000 }}
......
...@@ -24,10 +24,24 @@ const FormRuleSetting = forwardRef((props, ref) => { ...@@ -24,10 +24,24 @@ const FormRuleSetting = forwardRef((props, ref) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const customer = useContext(ServiceContext); const customer = useContext(ServiceContext);
// 判断是否有禁用的店铺 禁用店铺不显示
const getIsInShops = arr => {
const list = [];
arr.forEach(item => {
supplierIdList.some(s => +s.id === +item) && list.push(item);
});
return list;
};
useEffect(() => { useEffect(() => {
if (customer.isEdit) { if (customer.isEdit) {
if (!editData) return; if (!editData) return;
form.setFieldsValue(editData); const goodInfo = Object.assign({}, editData);
if (goodInfo.shopIds) {
const shopIds = getIsInShops(editData.shopIds);
goodInfo.shopIds = shopIds;
}
form.setFieldsValue(goodInfo);
} }
}, [customer.isEdit, editData]); }, [customer.isEdit, editData]);
...@@ -98,7 +112,14 @@ const FormRuleSetting = forwardRef((props, ref) => { ...@@ -98,7 +112,14 @@ const FormRuleSetting = forwardRef((props, ref) => {
label="适用门店" label="适用门店"
rules={[{ required: true, message: '请选择适用门店!', type: 'array' }]} rules={[{ required: true, message: '请选择适用门店!', type: 'array' }]}
> >
<Select mode="multiple" placeholder="请选择适用门店"> <Select
mode="multiple"
placeholder="请选择适用门店"
showSearch
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{(supplierIdList || []).map(item => ( {(supplierIdList || []).map(item => (
<Option value={+item.id} key={item.id}> <Option value={+item.id} key={item.id}>
{item.name} {item.name}
......
...@@ -142,6 +142,7 @@ const FormRuleVPictures = forwardRef((props, ref) => { ...@@ -142,6 +142,7 @@ const FormRuleVPictures = forwardRef((props, ref) => {
> >
<UploadImage <UploadImage
disabled={customer.isService} disabled={customer.isService}
multiple={false}
name="commonImageList" name="commonImageList"
limit={imgConfig.commonImageList.limit} limit={imgConfig.commonImageList.limit}
pictures={commonImageList} pictures={commonImageList}
......
...@@ -192,21 +192,25 @@ const UploadImage = forwardRef((props, ref) => { ...@@ -192,21 +192,25 @@ const UploadImage = forwardRef((props, ref) => {
</ReactSortable> </ReactSortable>
)} )}
</div> </div>
<Upload {limit !== null && fileList.length >= limit ? (
{...uploadParams} ''
disabled={Boolean(disabled)} ) : (
multiple={multiple} <Upload
name={name} {...uploadParams}
customRequest={() => {}} disabled={Boolean(disabled)}
listType="picture-card" multiple={multiple}
beforeUpload={defaultBeforeUpload} name={name}
fileList={fileList} customRequest={() => {}}
onPreview={handlePreview} listType="picture-card"
onRemove={handleRemove} beforeUpload={defaultBeforeUpload}
showUploadList={false} fileList={fileList}
> onPreview={handlePreview}
{limit !== null && fileList.length >= limit ? null : UploadButton} onRemove={handleRemove}
</Upload> showUploadList={false}
>
{UploadButton}
</Upload>
)}
<Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}> <Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} /> <img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal> </Modal>
......
...@@ -236,7 +236,7 @@ export const StaticColumns = customer => [ ...@@ -236,7 +236,7 @@ export const StaticColumns = customer => [
min: 0, min: 0,
}, },
roleRules: { required: true }, roleRules: { required: true },
disabeldRender: () => customer.isService, disabeldRender: v => v.id && customer.isService,
}, },
{ {
title: '库存预警', title: '库存预警',
......
...@@ -4,6 +4,9 @@ import config from '../../config/env.config'; ...@@ -4,6 +4,9 @@ import config from '../../config/env.config';
export async function qiniuToken() { export async function qiniuToken() {
const data = await request.get('/api/kdsp/common/upload/token', { const data = await request.get('/api/kdsp/common/upload/token', {
prefix: config.opapiHost, prefix: config.opapiHost,
headers: {
'qg-tenant-id': 560761,
},
}); });
return data?.data?.token; return data?.data?.token;
} }
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