Commit d2960ac7 authored by 武广's avatar 武广

feat: 添加库存审核提交功能

parent f0aca99e
......@@ -2,7 +2,7 @@ const isProduction = process.env.NODE_ENV === 'production';
const isPre = process.env.PRE_ENV === 'pre';
const envAPi = {
api: '//backstms-yxm.liangkebang.net',
api: 'https://backstms-yxm.liangkebang.net',
kdspOpApi: 'https://kdsp-operation-yxm.liangkebang.net',
kdspApi: 'https://sc-op-api-yxm.liangkebang.net',
goodsApi: 'https://sc-op-api-yxm.liangkebang.net',
......
......@@ -5,15 +5,19 @@ import {
Select,
notification,
Upload,
Tag,
Cascader,
InputNumber,
Popover,
Divider,
} from 'antd';
import React, { Component } from 'react';
import React, { Component, useState } from 'react';
import { connect } from 'dva';
import { saveAs } from 'file-saver';
import { format } from 'date-fns';
import styles from '../style.less';
import { stateList } from '../staticdata';
import { apiGoodsInfosExport } from '../service';
const FormItem = Form.Item;
const { Option } = Select;
......@@ -23,6 +27,10 @@ const { Option } = Select;
class goodsManage extends Component {
formRef = React.createRef();
state = {
loading: false,
};
componentDidMount() {
this.props.onRef(this);
this.handleSearch();
......@@ -59,6 +67,33 @@ class goodsManage extends Component {
this.props.setArea(isAll, type);
};
// 验证是否可以修改库存
checkEnableUpdateStock = () => {
if (this.props.selectNum) {
this.props.checkStock();
} else {
notification.info({ message: '请选择' });
}
};
// 导出明细
onExportGoodsInfo = async () => {
this.setState({
loading: true,
});
const form = this.formRef?.current?.getFieldValue();
const res = await apiGoodsInfosExport(form);
this.setState({
loading: false,
});
if (res) {
const blob = new Blob([res]);
saveAs(blob, `商品明细-${format(new Date(), 'yyyyMMdd')}.xlsx`);
} else {
notification.error({ message: '下载失败' });
}
};
render() {
const { treeData } = this.props;
const selectW = { width: 250 };
......@@ -81,6 +116,10 @@ class goodsManage extends Component {
<Button style={{ border: 'none' }} onClick={() => this.setArea(0, 'after')}>
勾选商品售后地址设置
</Button>
<br />
<Button style={{ border: 'none' }} onClick={() => this.checkEnableUpdateStock()}>
勾选商品库存修改
</Button>
</div>
);
// const uploadProps = {
......@@ -166,16 +205,21 @@ class goodsManage extends Component {
<Button onClick={() => this.onReset()} type="primary" className={styles.button}>
重置
</Button>
<Button
loading={this.state.loading}
onClick={() => this.onExportGoodsInfo()}
className={styles.button}
>
导出
</Button>
</FormItem>
<FormItem style={{ float: 'right' }}>
<Popover content={content} onVisibleChange={this.handleVisibleChange}>
<Button type="primary" className={styles.button}>
批量操作
批量设置
</Button>
</Popover>
<Button type="primary" className={styles.button} onClick={this.addSpu}>
新增商品
</Button>
{this.props.selectNum > 0 && <Tag color="green">已选商品 {this.props.selectNum}</Tag>}
{/* <Button
className={styles.button}
type="primary"
......
......@@ -2,21 +2,24 @@ import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Modal, InputNumber, notification, Input, Radio } from 'antd';
import React from 'react';
import { updateStock } from '../service';
import { apiCreateGoodsLog } from '../service';
import styles from '../style.less';
const UpdateStock = props => {
const { getFieldDecorator, validateFields, resetFields, getFieldValue } = props.form;
const valueInfo = props.info;
getFieldDecorator('stockChangeType', { initialValue: 1 });
getFieldDecorator('changeType', { initialValue: 1 });
const submit = async () => {
validateFields(async (err, { stock, changeReason, stockChangeType }) => {
validateFields(async (err, { stock, changeReason, changeType }) => {
if (err) return;
const error = await updateStock({
stock,
id: valueInfo.id,
const error = await apiCreateGoodsLog({
afterChange: stock,
// id: valueInfo.id,
supplierId: valueInfo.supplierId,
stockChangeType,
productIdType: 2,
changeType,
changeReason,
productIds: valueInfo.id ? [valueInfo.id] : props.skuIds,
});
if (!error) {
notification.success({ message: '操作成功!' });
......@@ -31,7 +34,7 @@ const UpdateStock = props => {
};
const formItemLayout = {
labelCol: {
span: 8,
span: 6,
},
wrapperCol: {
span: 16,
......@@ -40,23 +43,25 @@ const UpdateStock = props => {
const validatorCallback = (rule, value, callback) => {
// 减库存存时,校验可售库存-输入值>=0,即可售库存不可为负;
const stockChangeType = getFieldValue('stockChangeType');
const changeType = getFieldValue('changeType');
const increment = valueInfo.marketableStock - value;
return !stockChangeType && increment < 0 ? callback(new Error(rule.message)) : callback();
return +changeType === 29 && increment < 0 ? callback(new Error(rule.message)) : callback();
};
return (
<Modal title="修改库存" visible={props.visible} onCancel={onCancel} onOk={submit} width={400}>
<Modal title="修改库存" visible={props.visible} onCancel={onCancel} onOk={submit} width={500}>
<Form {...formItemLayout}>
<Form.Item label="变更类型:">
{getFieldDecorator('stockChangeType', {
{getFieldDecorator('changeType', {
rules: [{ required: true, message: '请选择类型!' }],
})(
<Radio.Group>
<Radio value={1}>增库存</Radio>
<Radio value={0}>减库存</Radio>
<Radio value={28}>增库存</Radio>
<Radio value={29}>减库存</Radio>
<Radio value={30}>使用新值</Radio>
</Radio.Group>,
)}
<div className={styles.stockTip}>库存变更审批通过后生效</div>
</Form.Item>
<Form.Item label="库存数:">
{getFieldDecorator('stock', {
......@@ -73,6 +78,7 @@ const UpdateStock = props => {
initialValue: valueInfo.changeReason,
})(<Input.TextArea />)}
</Form.Item>
{valueInfo.state === 4 && <div className={styles.stockErrMsg}>审核中</div>}
</Form>
</Modal>
);
......
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Card, Pagination, Table, notification, Drawer, Spin } from 'antd';
import { Card, Pagination, Table, notification, Drawer, Spin, Button } from 'antd';
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva';
......@@ -18,6 +18,7 @@ import {
getTemplateList,
specList,
queryAllAfterAddress,
apiEnableUpdataStock,
} from './service';
import LogModal from './LogModal';
import CreateModal from './createModal';
......@@ -218,6 +219,29 @@ class goodsManage extends Component {
filterShopList = (list = [], isEdit) =>
list.filter(item => isEdit || !JDSHOPID.includes(item.id));
// 验证是否可以修改库存
checkEnableUpdateStock = async (row = {}) => {
let ids = '';
if (row && row.skuId) {
ids = row.skuId;
} else {
ids = this.state.selectedRowKeys.join(',');
}
if (ids) {
const res = await apiEnableUpdataStock(ids);
if (res.data) {
if (res.data.allResult || res.data.successSkuIds?.length) {
this.openModal(row, 1);
} else {
const message = res.data.failedInfoList[0]?.message || '未存在可修改库存的商品';
notification.info({ message });
}
}
} else {
notification.info({ message: '请选择' });
}
};
openModal = (
{
skuId,
......@@ -228,6 +252,7 @@ class goodsManage extends Component {
supplierId,
stock,
productStock,
state,
},
isStock,
) => {
......@@ -246,6 +271,7 @@ class goodsManage extends Component {
marketPrice,
salePrice,
supplierId,
state,
},
});
};
......@@ -302,6 +328,13 @@ class goodsManage extends Component {
return (
<PageHeaderWrapper>
<Spin spinning={this.state.createloading}>
<Button
type="primary"
className={styles.button}
onClick={() => this.setState({ createVisible: true, initData: {} })}
>
新增商品
</Button>
<Card>
<SearchForm
handleSearch={this.handleSearch}
......@@ -312,7 +345,9 @@ class goodsManage extends Component {
}}
treeData={this.state.treeData}
shopList={this.shopList}
addSpu={() => this.setState({ createVisible: true, initData: {} })}
checkStock={this.checkEnableUpdateStock}
// addSpu={() => this.setState({ createVisible: true, initData: {} })}
selectNum={selectedRowKeys.length}
setArea={(isALL, type) => this.setArea(isALL, type)}
/>
</Card>
......@@ -383,6 +418,7 @@ class goodsManage extends Component {
<UpdateStock
visible={this.state.updateStockVisible}
skuIds={this.state.selectedRowKeys}
info={this.state.priceInfo}
onCancel={this.cancel}
/>
......
......@@ -197,3 +197,44 @@ export async function getAfterAddress(params) {
});
return data;
}
/**
* 商品是否可以做库存变更
* skuIds: 多个用英文逗号隔开
*/
export const apiEnableUpdataStock = skuIds =>
request.get(`/api/kdsp/sku/can/stockChange?skuIds=${skuIds}`, {
prefix: goodsApi,
});
// 商品明细导出
export const apiGoodsInfosExport = params =>
request.post('/api/kdsp/sku/export', {
prefix: goodsApi,
data: params,
responseType: 'arrayBuffer',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
});
// 新建商品审核记录
export const apiCreateGoodsLog = params =>
request.post('/api/kdsp/product/audit/create', {
data: params,
prefix: goodsApi,
});
// 查询库存变更记录(未审核状态)
export const apiStockChangeLog = params =>
request.post('/product/change/audit/stockChange/page', {
data: params,
prefix: goodsApi,
});
// 审核商品变更记录
export const apiCheckStockChangeLog = params =>
request.post('/product/change/audit/audit', {
data: params,
prefix: goodsApi,
});
......@@ -107,13 +107,16 @@ export function column() {
align: 'center',
sorter: (a, b) => a.stock - b.stock,
render: (_, row) => {
// const stockView =
// row.state !== 4 ? (
// <a onClick={() => this.openModal(row, 'productStock')}>{row.productStock}</a>
// ) : (
// <span>{row.productStock}</span>
// );
const stockView = row.productStock;
// const stockView = row.productStock;
const stockView = (
<Button
type="link"
onClick={() => this.checkEnableUpdateStock(row)}
style={{ padding: 0 }}
>
{row.productStock}
</Button>
);
return (
<>
<p>当前库存:{stockView}</p>
......
......@@ -99,3 +99,14 @@
.sizeTitle {
font-size: 12px;
}
.stockTip {
color: #999;
line-height: 1;
}
.stockErrMsg {
box-sizing: border-box;
padding-left: 25%;
color: #d9363e;
line-height: 1;
}
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