diff --git a/admin-web/src/models/product/productSpuList.js b/admin-web/src/models/product/productSpuList.js new file mode 100644 index 000000000..d4492f3cb --- /dev/null +++ b/admin-web/src/models/product/productSpuList.js @@ -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, + }; + }, + }, +}; diff --git a/admin-web/src/pages/Product/ProductSpuList.js b/admin-web/src/pages/Product/ProductSpuList.js index 6adf813c8..6435529fc 100644 --- a/admin-web/src/pages/Product/ProductSpuList.js +++ b/admin-web/src/pages/Product/ProductSpuList.js @@ -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 ( - - {renderTreeNodes(item.children)} - - ); - } - return ; - }); - }; - - const renderModalContent = treeData => { - const RenderTreeNodes = renderTreeNodes(treeData); - if (RenderTreeNodes) { - return ( - - {form.getFieldDecorator('name', {})( - - {renderTreeNodes(treeData)} - - )} - - ); - } else { - return null; - } - }; - - const okHandle = () => { - form.validateFields((err, fieldsValue) => { - if (err) return; - form.resetFields(); - handleOk({ - fields: fieldsValue, - }); - }); - }; - - return ( - handleModalVisible()} - > - {renderModalContent(treeData)} - - ); -}); - // roleList -@connect(({ roleList, loading }) => ({ - roleList, - list: roleList.list, - data: roleList, - loading: loading.models.resourceList, +@connect(({ productSpuList, loading }) => ({ + productSpuList, + list: productSpuList.list.spus, + loading: loading.models.productSpuList, })) + @Form.create() -class RoleList extends PureComponent { +class ProductSpuList extends PureComponent { state = { modalVisible: false, modalType: 'add', //add update @@ -140,7 +68,7 @@ class RoleList extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'roleList/query', + type: 'productSpuList/page', payload: { name: '', 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 }) => { const { dispatch, data } = this.props; 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() { + // debugger; 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 parentMethods = { @@ -284,9 +144,30 @@ class RoleList extends PureComponent { render: text => {text}, }, { - title: '名称', + title: '商品名称', dataIndex: 'name', }, + { + title: '商品分类', + dataIndex: 'cid' + }, + { + title: '商品主图', + dataIndex: 'picUrls', + render(val) { + return ; + // return 'TODO'; + }, + }, + { + title: '商品库存', + dataIndex: 'quantity' + }, + { + title: '排序值', + dataIndex: 'sort', + render: sort => {sort}, + }, { title: '创建时间', dataIndex: 'createTime', @@ -299,25 +180,19 @@ class RoleList extends PureComponent { render: (text, record) => ( this.handleModalVisible(true, 'update', record)}>更新 - - this.handleAssignModalVisible(true, record)}>分配权限 - - this.handleDelete(record)}> - 删除 - ), }, ]; - const paginationProps = { - current: pageNo, - pageSize: pageSize, - total: count, - }; + // const paginationProps = { + // current: pageNo, + // pageSize: pageSize, + // total: count, + // }; return ( - + @@ -326,25 +201,16 @@ class RoleList extends PureComponent { type="primary" onClick={() => this.handleModalVisible(true, 'add', {})} > - 新建 + 发布商品 - this.handleAssignModalVisibleClose(false)} - /> ); } } -export default RoleList; +export default ProductSpuList; diff --git a/admin-web/src/services/product.js b/admin-web/src/services/product.js index 402a2c3e7..1981c18d3 100644 --- a/admin-web/src/services/product.js +++ b/admin-web/src/services/product.js @@ -1,7 +1,7 @@ import { stringify } from '@/utils/request.qs'; import request from '@/utils/request'; -// dictionary +// product category export async function productCategoryTree(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)}`, { method: 'POST', }); +} + +// product spu + +export async function productSpuPage(params) { + return request(`/product-api/admins/spu/page?${stringify(params)}`, { + method: 'GET', + }); } \ No newline at end of file diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java index 78c92406c..1011dbd62 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java @@ -22,6 +22,8 @@ public class AdminsProductSpuVO { private Integer cid; @ApiModelProperty(value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn") private List picUrls; + @ApiModelProperty(value = "库存数量", required = true, example = "10") + private Integer quantity; // ========== 其他信息 ========= @ApiModelProperty(value = "是否上架商品(是否可见)", required = true, example = "true") @@ -101,4 +103,13 @@ public class AdminsProductSpuVO { return this; } + public Integer getQuantity() { + return quantity; + } + + public AdminsProductSpuVO setQuantity(Integer quantity) { + this.quantity = quantity; + return this; + } + } \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java index b8a97365a..711e7bfb1 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java @@ -55,6 +55,12 @@ public class ProductSpuBO { * 目前的计算方式是,以 Sku 最小价格为准 */ private Integer price; + /** + * 库存数量 + * + * 目前的计算方式是,以 Sku 库存累加为准 + */ + private Integer quantity; public Integer getId() { return id; @@ -137,4 +143,12 @@ public class ProductSpuBO { return this; } + public Integer getQuantity() { + return quantity; + } + + public ProductSpuBO setQuantity(Integer quantity) { + this.quantity = quantity; + return this; + } } \ No newline at end of file diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java index ee0243a86..2f2f5c0c6 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java @@ -40,8 +40,6 @@ public class ProductSpuDO extends BaseDO { */ private String picUrls; - // TODO 价格库存 - // TODO 运费信息 // ========== 其他信息 =========