前端:商品列表

This commit is contained in:
YunaiV 2019-03-16 20:31:13 +08:00
parent a901dd5dff
commit 45b2497c80
6 changed files with 147 additions and 176 deletions

View File

@ -0,0 +1,74 @@
import { message } from 'antd';
import { productSpuPage, productCategoryAdd, productCategoryUpdate, productCategoryUpdateStatus, productCategoryDelete } from '../../services/product';
export default {
namespace: 'productSpuList',
state: {
list: [],
},
effects: {
*add({ payload }, { call, put }) {
const { callback, body } = payload;
const response = yield call(productCategoryAdd, body);
if (callback) {
callback(response);
}
yield put({
type: 'tree',
payload: {},
});
},
*update({ payload }, { call, put }) {
const { callback, body } = payload;
const response = yield call(productCategoryUpdate, body);
if (callback) {
callback(response);
}
yield put({
type: 'tree',
payload: {},
});
},
*updateStatus({ payload }, { call, put }) {
const { callback, body } = payload;
const response = yield call(productCategoryUpdateStatus, body);
if (callback) {
callback(response);
}
yield put({
type: 'tree',
payload: {},
});
},
*delete({ payload }, { call, put }) {
const response = yield call(productCategoryDelete, payload);
message.info('删除成功!');
yield put({
type: 'tree',
payload: {},
});
},
*page({ payload }, { call, put }) {
const { queryParams } = payload;
const response = yield call(productSpuPage, queryParams);
message.info('查询成功!');
yield put({
type: 'treeSuccess',
payload: {
list: response.data,
},
});
},
},
reducers: {
treeSuccess(state, { payload }) {
return {
...state,
...payload,
};
},
},
};

View File

@ -48,87 +48,15 @@ const CreateForm = Form.create()(props => {
); );
}); });
// 角色分配
const AssignModal = Form.create()(props => {
const {
modalVisible,
form,
handleOk,
handleModalVisible,
treeData,
checkedKeys,
loading,
handleCheckBoxClick,
} = props;
const renderTreeNodes = data => {
return data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode title={item.title} key={item.key} dataRef={item} />;
});
};
const renderModalContent = treeData => {
const RenderTreeNodes = renderTreeNodes(treeData);
if (RenderTreeNodes) {
return (
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="角色名">
{form.getFieldDecorator('name', {})(
<Tree
defaultExpandAll={true}
checkable={true}
multiple={true}
checkedKeys={checkedKeys}
onCheck={handleCheckBoxClick}
>
{renderTreeNodes(treeData)}
</Tree>
)}
</FormItem>
);
} else {
return null;
}
};
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleOk({
fields: fieldsValue,
});
});
};
return (
<Modal
destroyOnClose
title="更新权限"
visible={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
<Spin spinning={loading}>{renderModalContent(treeData)}</Spin>
</Modal>
);
});
// roleList // roleList
@connect(({ roleList, loading }) => ({ @connect(({ productSpuList, loading }) => ({
roleList, productSpuList,
list: roleList.list, list: productSpuList.list.spus,
data: roleList, loading: loading.models.productSpuList,
loading: loading.models.resourceList,
})) }))
@Form.create() @Form.create()
class RoleList extends PureComponent { class ProductSpuList extends PureComponent {
state = { state = {
modalVisible: false, modalVisible: false,
modalType: 'add', //add update modalType: 'add', //add update
@ -140,7 +68,7 @@ class RoleList extends PureComponent {
componentDidMount() { componentDidMount() {
const { dispatch } = this.props; const { dispatch } = this.props;
dispatch({ dispatch({
type: 'roleList/query', type: 'productSpuList/page',
payload: { payload: {
name: '', name: '',
pageNo: 0, pageNo: 0,
@ -157,51 +85,6 @@ class RoleList extends PureComponent {
}); });
}; };
handleAssignModalVisible = (flag, record) => {
const { dispatch } = this.props;
dispatch({
type: 'roleList/queryRoleAssign',
payload: {
id: record.id,
},
});
this.setState({
roleAssignVisible: !!flag,
roleAssignRecord: record,
});
};
handleAssignModalVisibleClose(flag) {
this.setState({
roleAssignVisible: !!flag,
});
}
handleAssignCheckBoxClick = checkedKeys => {
const { dispatch } = this.props;
const newCheckedKeys = checkedKeys.map(item => {
return parseInt(item);
});
dispatch({
type: 'roleList/changeCheckedKeys',
payload: newCheckedKeys,
});
};
handleAssignOK = () => {
const { dispatch, data } = this.props;
const { roleAssignRecord } = this.state;
dispatch({
type: 'roleList/roleAssignResource',
payload: {
id: roleAssignRecord.id,
resourceIds: data.checkedKeys,
roleTreeData: data.roleTreeData,
},
});
this.handleAssignModalVisibleClose(false);
};
handleAdd = ({ fields, modalType, initValues }) => { handleAdd = ({ fields, modalType, initValues }) => {
const { dispatch, data } = this.props; const { dispatch, data } = this.props;
const queryParams = { const queryParams = {
@ -240,34 +123,11 @@ class RoleList extends PureComponent {
} }
}; };
handleDelete(row) {
const { dispatch, data } = this.props;
const queryParams = {
pageNo: data.pageNo,
pageSize: data.pageSize,
};
Modal.confirm({
title: `确认删除?`,
content: `${row.name}`,
onOk() {
dispatch({
type: 'roleList/delete',
payload: {
body: {
id: row.id,
},
queryParams,
},
});
},
onCancel() {},
});
}
render() { render() {
// debugger;
const { list, data } = this.props; const { list, data } = this.props;
const { pageNo, pageSize, count, roleTreeData, checkedKeys, assignModalLoading } = data; // const { pageNo, pageSize, count, roleTreeData, checkedKeys, assignModalLoading } = data;
const { modalVisible, modalType, initValues, roleAssignVisible } = this.state; const { modalVisible, modalType, initValues, roleAssignVisible } = this.state;
const parentMethods = { const parentMethods = {
@ -284,9 +144,30 @@ class RoleList extends PureComponent {
render: text => <strong>{text}</strong>, render: text => <strong>{text}</strong>,
}, },
{ {
title: '名称', title: '商品名称',
dataIndex: 'name', 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: '创建时间', title: '创建时间',
dataIndex: 'createTime', dataIndex: 'createTime',
@ -299,25 +180,19 @@ class RoleList extends PureComponent {
render: (text, record) => ( render: (text, record) => (
<Fragment> <Fragment>
<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a> <a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>
<Divider type="vertical" />
<a onClick={() => this.handleAssignModalVisible(true, record)}>分配权限</a>
<Divider type="vertical" />
<a className={styles.tableDelete} onClick={() => this.handleDelete(record)}>
删除
</a>
</Fragment> </Fragment>
), ),
}, },
]; ];
const paginationProps = { // const paginationProps = {
current: pageNo, // current: pageNo,
pageSize: pageSize, // pageSize: pageSize,
total: count, // total: count,
}; // };
return ( return (
<PageHeaderWrapper title="查询表格"> <PageHeaderWrapper title="">
<Card bordered={false}> <Card bordered={false}>
<div className={styles.tableList}> <div className={styles.tableList}>
<div className={styles.tableListOperator}> <div className={styles.tableListOperator}>
@ -326,25 +201,16 @@ class RoleList extends PureComponent {
type="primary" type="primary"
onClick={() => this.handleModalVisible(true, 'add', {})} onClick={() => this.handleModalVisible(true, 'add', {})}
> >
新建 发布商品
</Button> </Button>
</div> </div>
</div> </div>
<Table columns={columns} dataSource={list} rowKey="id" /> <Table columns={columns} dataSource={list} rowKey="id" />
</Card> </Card>
<CreateForm {...parentMethods} modalVisible={modalVisible} /> <CreateForm {...parentMethods} modalVisible={modalVisible} />
<AssignModal
loading={assignModalLoading}
treeData={roleTreeData}
checkedKeys={checkedKeys}
handleOk={this.handleAssignOK}
modalVisible={roleAssignVisible}
handleCheckBoxClick={this.handleAssignCheckBoxClick}
handleModalVisible={() => this.handleAssignModalVisibleClose(false)}
/>
</PageHeaderWrapper> </PageHeaderWrapper>
); );
} }
} }
export default RoleList; export default ProductSpuList;

View File

@ -1,7 +1,7 @@
import { stringify } from '@/utils/request.qs'; import { stringify } from '@/utils/request.qs';
import request from '@/utils/request'; import request from '@/utils/request';
// dictionary // product category
export async function productCategoryTree(params) { export async function productCategoryTree(params) {
return request(`/product-api/admins/category/tree?${stringify(params)}`, { return request(`/product-api/admins/category/tree?${stringify(params)}`, {
@ -34,4 +34,12 @@ export async function productCategoryDelete(params) {
return request(`/product-api/admins/category/delete?${stringify(params)}`, { return request(`/product-api/admins/category/delete?${stringify(params)}`, {
method: 'POST', method: 'POST',
}); });
}
// product spu
export async function productSpuPage(params) {
return request(`/product-api/admins/spu/page?${stringify(params)}`, {
method: 'GET',
});
} }

View File

@ -22,6 +22,8 @@ public class AdminsProductSpuVO {
private Integer cid; private Integer cid;
@ApiModelProperty(value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn") @ApiModelProperty(value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn")
private List<String> picUrls; private List<String> picUrls;
@ApiModelProperty(value = "库存数量", required = true, example = "10")
private Integer quantity;
// ========== 其他信息 ========= // ========== 其他信息 =========
@ApiModelProperty(value = "是否上架商品(是否可见)", required = true, example = "true") @ApiModelProperty(value = "是否上架商品(是否可见)", required = true, example = "true")
@ -101,4 +103,13 @@ public class AdminsProductSpuVO {
return this; return this;
} }
public Integer getQuantity() {
return quantity;
}
public AdminsProductSpuVO setQuantity(Integer quantity) {
this.quantity = quantity;
return this;
}
} }

View File

@ -55,6 +55,12 @@ public class ProductSpuBO {
* 目前的计算方式是 Sku 最小价格为准 * 目前的计算方式是 Sku 最小价格为准
*/ */
private Integer price; private Integer price;
/**
* 库存数量
*
* 目前的计算方式是 Sku 库存累加为准
*/
private Integer quantity;
public Integer getId() { public Integer getId() {
return id; return id;
@ -137,4 +143,12 @@ public class ProductSpuBO {
return this; return this;
} }
public Integer getQuantity() {
return quantity;
}
public ProductSpuBO setQuantity(Integer quantity) {
this.quantity = quantity;
return this;
}
} }

View File

@ -40,8 +40,6 @@ public class ProductSpuDO extends BaseDO {
*/ */
private String picUrls; private String picUrls;
// TODO 价格库存
// TODO 运费信息 // TODO 运费信息
// ========== 其他信息 ========= // ========== 其他信息 =========