- 前端:完善商品列表
- 后端:将商品模块的 Service 改成有业务异常时,抛出异常,而不是返回 CommonResult - 后端:将搜索模块的 Service 改成有业务异常时,抛出异常,而不是返回 CommonResult
This commit is contained in:
@@ -62,6 +62,9 @@ export default {
|
||||
const response = yield call(productSpuInfo, {
|
||||
id: payload,
|
||||
});
|
||||
if (response.code !== 0) {
|
||||
return;
|
||||
}
|
||||
// 响应
|
||||
let skus = [];
|
||||
let attrTree = [];
|
||||
@@ -193,6 +196,9 @@ export default {
|
||||
*add({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productSpuAdd, body);
|
||||
if (response.code !== 0) {
|
||||
return;
|
||||
}
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
@@ -205,6 +211,9 @@ export default {
|
||||
*update({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productSpuUpdate, body);
|
||||
if (response.code !== 0) {
|
||||
return;
|
||||
}
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
import { message } from 'antd';
|
||||
import { productSpuPage, productCategoryAdd, productCategoryUpdate, productCategoryUpdateStatus, productCategoryDelete } from '../../services/product';
|
||||
import { productSpuPage, productSpuUpdateSort } from '../../services/product';
|
||||
import {routerRedux} from "dva/router";
|
||||
import PaginationHelper from '../../../helpers/PaginationHelper';
|
||||
|
||||
const SEARCH_PARAMS_DEFAULT = {
|
||||
name: '',
|
||||
status: 1,
|
||||
cid: undefined,
|
||||
};
|
||||
|
||||
export default {
|
||||
namespace: 'productSpuList',
|
||||
|
||||
state: {
|
||||
// 分页列表相关
|
||||
list: [],
|
||||
listLoading: false,
|
||||
pagination: PaginationHelper.defaultPaginationConfig,
|
||||
searchParams: SEARCH_PARAMS_DEFAULT,
|
||||
|
||||
// 添加 or 修改表单相关
|
||||
// modalVisible: false,
|
||||
// modalType: undefined, // 'add' or 'update' 表单
|
||||
formVals: {}, // 当前表单值
|
||||
// modalLoading: false,
|
||||
|
||||
|
||||
sortModalVisible: false, // 修改排序弹窗
|
||||
sortModalLoading: false, // 修改排序的加载
|
||||
},
|
||||
|
||||
effects: {
|
||||
@@ -35,19 +56,76 @@ export default {
|
||||
},
|
||||
*redirectToUpdate({ payload }, { call, put }) {
|
||||
// const { callback, body } = payload;
|
||||
debugger;
|
||||
yield put(routerRedux.replace('/product/product-spu-update?id=' + payload));
|
||||
},
|
||||
*page({ payload }, { call, put }) {
|
||||
// const { queryParams } = payload;
|
||||
const response = yield call(productSpuPage, payload);
|
||||
message.info('查询成功!');
|
||||
// const response = yield call(productSpuPage, payload);
|
||||
// message.info('查询成功!');
|
||||
// yield put({
|
||||
// type: 'treeSuccess',
|
||||
// payload: {
|
||||
// list: response.data,
|
||||
// },
|
||||
// });
|
||||
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'treeSuccess',
|
||||
type: 'changeListLoading',
|
||||
payload: true,
|
||||
});
|
||||
|
||||
// 请求
|
||||
const response = yield call(productSpuPage, payload);
|
||||
// 响应
|
||||
yield put({
|
||||
type: 'setAll',
|
||||
payload: {
|
||||
list: response.data,
|
||||
list: response.data.list,
|
||||
pagination: PaginationHelper.formatPagination(response.data, payload),
|
||||
searchParams: {
|
||||
name: payload.name,
|
||||
status: payload.status,
|
||||
cid: payload.cid,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// 隐藏加载中
|
||||
yield put({
|
||||
type: 'changeListLoading',
|
||||
payload: false,
|
||||
});
|
||||
},
|
||||
*updateSort({ payload }, { call, put }) {
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'changeSortModalLoading',
|
||||
payload: true,
|
||||
});
|
||||
|
||||
// 请求
|
||||
const { callback, body } = payload;
|
||||
// 响应
|
||||
const response = yield call(productSpuUpdateSort, body);
|
||||
if(response.code === 0) {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'page',
|
||||
payload: {
|
||||
...this.state.pagination,
|
||||
...this.state.searchParams,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 隐藏加载中
|
||||
yield put({
|
||||
type: 'changeSortModalLoading',
|
||||
payload: false,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -58,5 +136,25 @@ export default {
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
// 修改加载中的状态
|
||||
changeSortModalLoading(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
sortModalLoading: payload,
|
||||
};
|
||||
},
|
||||
changeListLoading(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
listLoading: payload,
|
||||
};
|
||||
},
|
||||
// 设置所有属性
|
||||
setAll(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -137,7 +137,6 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
// TODO 芋艿,有没办法换成上面那种写法
|
||||
const SearchForm = Form.create()(props => {
|
||||
const {
|
||||
form,
|
||||
|
||||
@@ -123,6 +123,7 @@ function List({ dataSource, loading, dispatch,
|
||||
columns={columns}
|
||||
loading={loading}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
dataSource={dataSource} />
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,19 +3,305 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { connect } from 'dva';
|
||||
import moment from 'moment';
|
||||
import { Card, Form, Input, Spin, Button, Modal, message, Table, Divider, Tree } from 'antd';
|
||||
import {
|
||||
Card,
|
||||
Form,
|
||||
Input,
|
||||
Row,
|
||||
Col,
|
||||
Button,
|
||||
Modal,
|
||||
message,
|
||||
Table,
|
||||
Divider,
|
||||
Tree,
|
||||
Tabs,
|
||||
TreeSelect,
|
||||
Spin,
|
||||
InputNumber
|
||||
} from 'antd';
|
||||
const TabPane = Tabs.TabPane;
|
||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||
|
||||
import styles from './ProductSpuList.less';
|
||||
import PaginationHelper from "../../../helpers/PaginationHelper";
|
||||
import PicturesWall from "../../components/Image/PicturesWall";
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { TreeNode } = Tree;
|
||||
|
||||
// 列表
|
||||
function List({ dataSource, loading, pagination, searchParams, dispatch,
|
||||
categoryTree, handleSortModalVisible}) {
|
||||
|
||||
const handleTabsChange = (value) => {
|
||||
dispatch({
|
||||
type: 'productSpuList/page',
|
||||
payload: {
|
||||
...searchParams,
|
||||
status: value,
|
||||
...PaginationHelper.defaultPayload,
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
function onPageChange(page) { // 翻页
|
||||
dispatch({
|
||||
type: 'productSpuList/page',
|
||||
payload: {
|
||||
pageNo: page.current,
|
||||
pageSize: page.pageSize,
|
||||
...searchParams
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const redirectToUpdate = (spuId) => {
|
||||
dispatch({
|
||||
type: 'productSpuList/redirectToUpdate',
|
||||
payload: spuId,
|
||||
});
|
||||
};
|
||||
|
||||
const getCategoryName = (cid, array) => {
|
||||
// debugger;
|
||||
for (let i in array) {
|
||||
// debugger;
|
||||
const node = array[i];
|
||||
if (node.id === cid) {
|
||||
return node.name;
|
||||
}
|
||||
if (!node.children) {
|
||||
continue;
|
||||
}
|
||||
let name = getCategoryName(cid, node.children);
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
// {
|
||||
// title: 'id',
|
||||
// dataIndex: 'id',
|
||||
// render: text => <strong>{text}</strong>,
|
||||
// },
|
||||
{
|
||||
title: '商品名称',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '商品分类',
|
||||
dataIndex: 'cid',
|
||||
render: value => getCategoryName(value, categoryTree),
|
||||
},
|
||||
{
|
||||
title: '商品主图',
|
||||
dataIndex: 'picUrls',
|
||||
render(val) {
|
||||
return <img width={120} src={val[0]} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '商品库存',
|
||||
dataIndex: 'quantity'
|
||||
},
|
||||
{
|
||||
title: '排序值',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: 200,
|
||||
render: (text, record) => (
|
||||
<Fragment>
|
||||
{/*<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>*/}
|
||||
<a onClick={() => redirectToUpdate(record.id)}>编辑</a>
|
||||
<Divider type="vertical"/>
|
||||
<a onClick={() => handleSortModalVisible(true, record)}>
|
||||
排序
|
||||
</a>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
// console.log(pagination);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tabs defaultActiveKey={searchParams.status} onChange={handleTabsChange}>
|
||||
<TabPane tab="在售中" key={1} />
|
||||
<TabPane tab="已售罄" key={2} />
|
||||
<TabPane tab="已下架" key={3} />
|
||||
</Tabs>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
rowKey="id"
|
||||
pagination={pagination}
|
||||
onChange={onPageChange}
|
||||
loading={loading} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
const SearchForm = Form.create()(props => {
|
||||
const {
|
||||
form,
|
||||
form: { getFieldDecorator },
|
||||
dispatch,
|
||||
searchParams,
|
||||
categoryTree,
|
||||
} = props;
|
||||
|
||||
function search() {
|
||||
dispatch({
|
||||
type: 'productSpuList/page',
|
||||
payload: {
|
||||
...PaginationHelper.defaultPayload,
|
||||
...searchParams,
|
||||
...form.getFieldsValue(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交搜索
|
||||
function handleSubmit(e) {
|
||||
// 阻止默认事件
|
||||
e.preventDefault();
|
||||
// 提交搜索
|
||||
search();
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
function handleReset() {
|
||||
// 重置表单
|
||||
form.resetFields();
|
||||
// 执行搜索
|
||||
search();
|
||||
}
|
||||
|
||||
// 处理分类筛选
|
||||
const buildSelectTree = (list) => {
|
||||
return list.map(item => {
|
||||
let children = [];
|
||||
if (item.children) {
|
||||
children = buildSelectTree(item.children);
|
||||
}
|
||||
return {
|
||||
title: item.name,
|
||||
value: item.id,
|
||||
key: item.id,
|
||||
children,
|
||||
selectable: item.pid > 0
|
||||
};
|
||||
});
|
||||
};
|
||||
let categoryTreeSelect = buildSelectTree(categoryTree);
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit} layout="inline">
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="商品名称">
|
||||
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="商品名称">
|
||||
{getFieldDecorator('cid')(
|
||||
<TreeSelect
|
||||
showSearch
|
||||
style={{ width: 200 }}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
treeData={categoryTreeSelect}
|
||||
placeholder="请选择"
|
||||
/>
|
||||
)}
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col md={8} sm={24}>
|
||||
<span className={styles.submitButtons}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
查询
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={handleReset}>
|
||||
重置
|
||||
</Button>
|
||||
</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
);
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
// 新建 form 表单
|
||||
const UpdateSortForm = Form.create()(props => {
|
||||
const { dispatch, loading, modalVisible, form, handleModalVisible, formVals } = props;
|
||||
|
||||
const okHandle = () => {
|
||||
form.validateFields((err, fields) => {
|
||||
if (err) return;
|
||||
dispatch({
|
||||
type: 'productSpuList/updateSort',
|
||||
payload: {
|
||||
body: {
|
||||
id: formVals.id,
|
||||
...fields,
|
||||
},
|
||||
callback: () => {
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
// 提示
|
||||
message.success('编辑排序成功');
|
||||
// 关闭弹窗
|
||||
handleModalVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const title = '编辑排序值';
|
||||
const okText = '确定';
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
title={title}
|
||||
visible={modalVisible}
|
||||
onOk={okHandle}
|
||||
okText={okText}
|
||||
onCancel={() => handleModalVisible()}
|
||||
>
|
||||
<Spin spinning={loading}>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="排序值">
|
||||
{form.getFieldDecorator('sort', {
|
||||
rules: [{ required: true, message: '请输入排序值!' }],
|
||||
initialValue: formVals.sort,
|
||||
})(<InputNumber placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
</Spin>
|
||||
</Modal>
|
||||
);
|
||||
});
|
||||
|
||||
// productSpuList
|
||||
@connect(({ productSpuList, loading }) => ({
|
||||
productSpuList,
|
||||
list: productSpuList.list.spus,
|
||||
loading: loading.models.productSpuList,
|
||||
@connect(({ productSpuList, productCategoryList }) => ({
|
||||
...productSpuList,
|
||||
// list: productSpuList.list.spus,
|
||||
// loading: loading.models.productSpuList,
|
||||
categoryTree: productCategoryList.list,
|
||||
}))
|
||||
|
||||
@Form.create()
|
||||
@@ -30,14 +316,19 @@ class ProductSpuList extends PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
// 查询初始数据
|
||||
dispatch({
|
||||
type: 'productSpuList/page',
|
||||
payload: {
|
||||
name: '',
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
status: 1,
|
||||
...PaginationHelper.defaultPayload,
|
||||
},
|
||||
});
|
||||
// 获得商品分类
|
||||
dispatch({
|
||||
type: 'productCategoryList/tree',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
|
||||
redirectToAdd = () => {
|
||||
@@ -47,82 +338,50 @@ class ProductSpuList extends PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
redirectToUpdate = (spuId) => {
|
||||
handleSortModalVisible = (sortModalVisible, record) => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'productSpuList/redirectToUpdate',
|
||||
payload: spuId,
|
||||
type: 'productSpuList/setAll',
|
||||
payload: {
|
||||
sortModalVisible,
|
||||
formVals: record || {}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
// debugger;
|
||||
const { list, data } = this.props;
|
||||
const { dispatch,
|
||||
list, listLoading, searchParams, pagination,
|
||||
categoryTree, formVals,
|
||||
sortModalLoading, sortModalVisible, } = this.props;
|
||||
|
||||
// const { pageNo, pageSize, count, roleTreeData, checkedKeys, assignModalLoading } = data;
|
||||
const { modalVisible, modalType, initValues, roleAssignVisible } = this.state;
|
||||
|
||||
const parentMethods = {
|
||||
handleAdd: this.handleAdd,
|
||||
handleModalVisible: this.handleModalVisible,
|
||||
modalType,
|
||||
initValues,
|
||||
// 列表属性
|
||||
const listProps = {
|
||||
dataSource: list,
|
||||
pagination,
|
||||
searchParams,
|
||||
dispatch,
|
||||
categoryTree,
|
||||
loading: listLoading,
|
||||
handleSortModalVisible: this.handleSortModalVisible, // Func
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
dataIndex: 'id',
|
||||
render: text => <strong>{text}</strong>,
|
||||
},
|
||||
{
|
||||
title: '商品名称',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '商品分类',
|
||||
dataIndex: 'cid'
|
||||
},
|
||||
{
|
||||
title: '商品主图',
|
||||
dataIndex: 'picUrls',
|
||||
render(val) {
|
||||
return <img width={120} src={val[0]} />;
|
||||
// return 'TODO';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '商品库存',
|
||||
dataIndex: 'quantity'
|
||||
},
|
||||
{
|
||||
title: '排序值',
|
||||
dataIndex: 'sort',
|
||||
render: sort => <span>{sort}</span>,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
sorter: true,
|
||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: 200,
|
||||
render: (text, record) => (
|
||||
<Fragment>
|
||||
{/*<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>*/}
|
||||
<a onClick={() => this.redirectToUpdate(record.id)}>更新</a>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
];
|
||||
// 搜索表单属性
|
||||
const searchFormProps = {
|
||||
dispatch,
|
||||
categoryTree,
|
||||
searchParams,
|
||||
};
|
||||
|
||||
// const paginationProps = {
|
||||
// current: pageNo,
|
||||
// pageSize: pageSize,
|
||||
// total: count,
|
||||
// };
|
||||
// 添加 or 编辑表单属性
|
||||
// debugger;
|
||||
const updateSortFormProps = {
|
||||
modalVisible: sortModalVisible,
|
||||
formVals,
|
||||
dispatch,
|
||||
loading: sortModalLoading,
|
||||
handleModalVisible: this.handleSortModalVisible, // Func
|
||||
};
|
||||
|
||||
return (
|
||||
<PageHeaderWrapper title="">
|
||||
@@ -138,7 +397,9 @@ class ProductSpuList extends PureComponent {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Table columns={columns} dataSource={list} rowKey="id" />
|
||||
<SearchForm {...searchFormProps} />
|
||||
<List {...listProps} />
|
||||
<UpdateSortForm {...updateSortFormProps} />
|
||||
</Card>
|
||||
</PageHeaderWrapper>
|
||||
);
|
||||
|
||||
@@ -58,6 +58,13 @@ export async function productSpuUpdate(params) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function productSpuUpdateSort(params) {
|
||||
return request(`/product-api/admins/spu/update_sort?${stringify(params)}`, {
|
||||
method: 'POST',
|
||||
body: {},
|
||||
});
|
||||
}
|
||||
|
||||
export async function productSpuInfo(params) {
|
||||
return request(`/product-api/admins/spu/info?${stringify(params)}`, {
|
||||
method: 'GET',
|
||||
|
||||
Reference in New Issue
Block a user