From 79c36a5addd77460a96bc888250d3d331acbafaa Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 6 May 2019 20:28:17 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=89=8D=E7=AB=AF=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=95=86=E5=93=81=E5=88=97=E8=A1=A8=20-=20=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=EF=BC=9A=E5=B0=86=E5=95=86=E5=93=81=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9A=84=20Service=20=E6=94=B9=E6=88=90=E6=9C=89=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E5=BC=82=E5=B8=B8=E6=97=B6=EF=BC=8C=E6=8A=9B=E5=87=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=20CommonResult=20-=20=E5=90=8E=E7=AB=AF=EF=BC=9A?= =?UTF-8?q?=E5=B0=86=E6=90=9C=E7=B4=A2=E6=A8=A1=E5=9D=97=E7=9A=84=20Servic?= =?UTF-8?q?e=20=E6=94=B9=E6=88=90=E6=9C=89=E4=B8=9A=E5=8A=A1=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=97=B6=EF=BC=8C=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E8=BF=94=E5=9B=9E=20Common?= =?UTF-8?q?Result?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../models/product/productSpuAddOrUpdate.js | 9 + .../src/models/product/productSpuList.js | 110 ++++- admin-web/src/pages/Admin/AdminList.js | 1 - .../src/pages/Product/ProductCategoryList.js | 1 + admin-web/src/pages/Product/ProductSpuList.js | 411 ++++++++++++++---- admin-web/src/services/product.js | 7 + .../config/GlobalExceptionHandler.java | 43 +- .../common/framework/vo/RestResult.java | 57 --- docs/guides/功能列表/功能列表-H5 商城.md | 36 +- docs/guides/功能列表/功能列表-管理后台.md | 25 +- .../order/biz/service/CartServiceImpl.java | 20 +- .../order/biz/service/OrderServiceImpl.java | 16 +- .../application/config/MVCConfiguration.java | 18 +- .../admins/AdminsProductAttrController.java | 25 +- .../AdminsProductCategoryController.java | 18 +- .../admins/AdminsProductSpuController.java | 38 +- .../users/UsersProductSpuController.java | 8 +- .../convert/ProductAttrConvert.java | 12 +- .../convert/ProductCategoryConvert.java | 3 +- .../convert/ProductSpuConvert.java | 13 +- .../vo/admins/AdminsProductSpuPageVO.java | 4 +- .../mall/product/api/ProductAttrService.java | 24 +- .../product/api/ProductCategoryService.java | 14 +- .../mall/product/api/ProductSpuService.java | 19 +- .../mall/product/api/bo/ProductSpuPageBO.java | 4 +- .../product/api/dto/ProductSpuPageDTO.java | 6 + .../mall/product/dao/ProductSpuMapper.java | 2 + .../service/ProductAttrServiceImpl.java | 87 ++-- .../service/ProductCategoryServiceImpl.java | 51 +-- .../service/ProductSpuServiceImpl.java | 140 +++--- .../resources/mapper/ProductSpuMapper.xml | 12 + .../UsersProductRecommendController.java | 2 +- .../users/UsersProductSearchController.java | 6 +- .../mall/search/api/ProductSearchService.java | 9 +- .../mq/PayTransactionPaySuccessConsumer.java | 5 +- .../biz/service/ProductSearchServiceImpl.java | 26 +- .../service/ProductSearchServiceImplTest.java | 2 +- .../AdminAccessLogInterceptor.java | 2 +- 39 files changed, 788 insertions(+), 500 deletions(-) delete mode 100644 common/common-framework/src/main/java/cn/iocoder/common/framework/vo/RestResult.java diff --git a/README.md b/README.md index df87b8e82..f4ac6fe44 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ * 整体的功能如下图:![功能图](http://static.iocoder.cn/mall%20%E5%8A%9F%E8%83%BD%E5%9B%BE-min.png) > 功能图,和实际后端模块拆分,并不是绝对对应。 + * [功能列表 - H5 商城](https://gitee.com/zhijiantianya/onemall/blob/master/docs/guides/%E5%8A%9F%E8%83%BD%E5%88%97%E8%A1%A8/%E5%8A%9F%E8%83%BD%E5%88%97%E8%A1%A8-H5%20%E5%95%86%E5%9F%8E.md) + * [功能列表 - 管理后台](https://gitee.com/zhijiantianya/onemall/blob/master/docs/guides/%E5%8A%9F%E8%83%BD%E5%88%97%E8%A1%A8/%E5%8A%9F%E8%83%BD%E5%88%97%E8%A1%A8-%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0.md) * 交流群:[传送门](http://www.iocoder.cn/mall-user-group/?vip&gitee) > 一起交流,Get 知识。 diff --git a/admin-web/src/models/product/productSpuAddOrUpdate.js b/admin-web/src/models/product/productSpuAddOrUpdate.js index bfbf544ed..7f2ac9664 100644 --- a/admin-web/src/models/product/productSpuAddOrUpdate.js +++ b/admin-web/src/models/product/productSpuAddOrUpdate.js @@ -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); } diff --git a/admin-web/src/models/product/productSpuList.js b/admin-web/src/models/product/productSpuList.js index a8a5e0d15..9cd6c9338 100644 --- a/admin-web/src/models/product/productSpuList.js +++ b/admin-web/src/models/product/productSpuList.js @@ -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, + }; + } }, }; diff --git a/admin-web/src/pages/Admin/AdminList.js b/admin-web/src/pages/Admin/AdminList.js index 8823253d2..91206b454 100644 --- a/admin-web/src/pages/Admin/AdminList.js +++ b/admin-web/src/pages/Admin/AdminList.js @@ -137,7 +137,6 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch, } // 搜索表单 -// TODO 芋艿,有没办法换成上面那种写法 const SearchForm = Form.create()(props => { const { form, diff --git a/admin-web/src/pages/Product/ProductCategoryList.js b/admin-web/src/pages/Product/ProductCategoryList.js index 076c078d0..a2e40be2e 100644 --- a/admin-web/src/pages/Product/ProductCategoryList.js +++ b/admin-web/src/pages/Product/ProductCategoryList.js @@ -123,6 +123,7 @@ function List({ dataSource, loading, dispatch, columns={columns} loading={loading} rowKey="id" + pagination={false} dataSource={dataSource} /> ) } diff --git a/admin-web/src/pages/Product/ProductSpuList.js b/admin-web/src/pages/Product/ProductSpuList.js index c90659bd4..12242bac3 100644 --- a/admin-web/src/pages/Product/ProductSpuList.js +++ b/admin-web/src/pages/Product/ProductSpuList.js @@ -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 => {text}, + // }, + { + title: '商品名称', + dataIndex: 'name', + }, + { + title: '商品分类', + dataIndex: 'cid', + render: value => getCategoryName(value, categoryTree), + }, + { + title: '商品主图', + dataIndex: 'picUrls', + render(val) { + return ; + }, + }, + { + title: '商品库存', + dataIndex: 'quantity' + }, + { + title: '排序值', + dataIndex: 'sort', + }, + { + title: '创建时间', + dataIndex: 'createTime', + render: val => {moment(val).format('YYYY-MM-DD')}, + }, + { + title: '操作', + width: 200, + render: (text, record) => ( + + {/* this.handleModalVisible(true, 'update', record)}>更新*/} + redirectToUpdate(record.id)}>编辑 + + handleSortModalVisible(true, record)}> + 排序 + + + ), + }, + ]; + + // console.log(pagination); + + return ( +
+ + + + + + + + ) +} + +// 搜索表单 +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 ( + + + + + {getFieldDecorator('name')()} + + + + + {getFieldDecorator('cid')( + + )} + + + + + + + + + + + ); +}); + +// + +// 新建 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 ( + handleModalVisible()} + > + + + {form.getFieldDecorator('sort', { + rules: [{ required: true, message: '请输入排序值!' }], + initialValue: formVals.sort, + })()} + + + + ); +}); + // 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 => {text}, - }, - { - 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', - sorter: true, - render: val => {moment(val).format('YYYY-MM-DD')}, - }, - { - title: '操作', - width: 200, - render: (text, record) => ( - - {/* this.handleModalVisible(true, 'update', record)}>更新*/} - this.redirectToUpdate(record.id)}>更新 - - ), - }, - ]; + // 搜索表单属性 + 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 ( @@ -138,7 +397,9 @@ class ProductSpuList extends PureComponent { -
+ + + ); diff --git a/admin-web/src/services/product.js b/admin-web/src/services/product.js index 197378fc1..1f120516e 100644 --- a/admin-web/src/services/product.js +++ b/admin-web/src/services/product.js @@ -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', diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/config/GlobalExceptionHandler.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/config/GlobalExceptionHandler.java index 69ab784fd..ebe57cc7d 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/config/GlobalExceptionHandler.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/config/GlobalExceptionHandler.java @@ -2,8 +2,9 @@ package cn.iocoder.common.framework.config; import cn.iocoder.common.framework.constant.SysErrorCodeEnum; import cn.iocoder.common.framework.exception.ServiceException; -import cn.iocoder.common.framework.util.ExceptionUtil; import cn.iocoder.common.framework.vo.CommonResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -11,20 +12,32 @@ import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolationException; -import java.lang.reflect.UndeclaredThrowableException; @ControllerAdvice public class GlobalExceptionHandler { + private Logger logger = LoggerFactory.getLogger(getClass()); + + // 逻辑异常 @ResponseBody @ExceptionHandler(value = ServiceException.class) public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) { + logger.debug("[serviceExceptionHandler]", ex); return CommonResult.error(ex.getCode(), ex.getMessage()); } + // Spring MVC 参数不正确 + @ResponseBody + @ExceptionHandler(value = MissingServletRequestParameterException.class) + public CommonResult missingServletRequestParameterExceptionHandler(HttpServletRequest req, MissingServletRequestParameterException ex) { + logger.warn("[missingServletRequestParameterExceptionHandler]", ex); + return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage() + ":" + ex.getMessage()); + } + @ResponseBody @ExceptionHandler(value = ConstraintViolationException.class) public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) { + logger.info("[constraintViolationExceptionHandler]", ex); // TODO 芋艿,后续要想一个更好的方式。 // 拼接详细报错 StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下:"); @@ -33,34 +46,12 @@ public class GlobalExceptionHandler { + detailMessage.toString()); } - @ResponseBody - @ExceptionHandler(value = UndeclaredThrowableException.class) - public CommonResult undeclaredThrowableExceptionHandler(HttpServletRequest req, UndeclaredThrowableException e) { - // 尝试获得 ServiceException 异常。如果是,则使用 serviceExceptionHandler 方法处理。 - ServiceException serviceException = ExceptionUtil.getServiceException(e); - if (serviceException != null) { - return serviceExceptionHandler(req, serviceException); - } - // 尝试获得 ConstraintViolationException 异常。如果是, - ConstraintViolationException constraintViolationException = ExceptionUtil.getConstraintViolationException(e); - if (constraintViolationException != null) { - return constraintViolationExceptionHandler(req, constraintViolationException); - } - // 获得不到,使用 异常日志 方法处理。 - return resultExceptionHandler(req, e); - } - @ResponseBody @ExceptionHandler(value = Exception.class) public CommonResult resultExceptionHandler(HttpServletRequest req, Exception e) { - // TODO 翻译不同的异常 - if (e instanceof MissingServletRequestParameterException) { - return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage() + ":" + e.getMessage()); - } - // TODO 异常日志 - e.printStackTrace(); + logger.error("[resultExceptionHandler]", e); // 返回 return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage()); } -} \ No newline at end of file +} diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/vo/RestResult.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/vo/RestResult.java deleted file mode 100644 index 813af6b80..000000000 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/vo/RestResult.java +++ /dev/null @@ -1,57 +0,0 @@ -package cn.iocoder.common.framework.vo; - -public class RestResult { - - /** - * 错误码 - */ - private Integer code; - /** - * 错误提示 - */ - private String message; - /** - * 返回数据 - */ - private Object data; - - public static RestResult error(Integer code, String message) { - RestResult result = new RestResult(); - result.code = code; - result.message = message; - return result; - } - - public static RestResult ok(Object data) { - RestResult result = new RestResult(); - result.code = 0; - result.data = data; - result.message = ""; - return result; - } - - public Integer getCode() { - return code; - } - - public void setCode(Integer code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - -} \ No newline at end of file diff --git a/docs/guides/功能列表/功能列表-H5 商城.md b/docs/guides/功能列表/功能列表-H5 商城.md index 1b7b7cdcb..35897da11 100644 --- a/docs/guides/功能列表/功能列表-H5 商城.md +++ b/docs/guides/功能列表/功能列表-H5 商城.md @@ -1,30 +1,30 @@ 如下是 onemall 的功能列表。 * 当功能被完成时,会标记已完成。 -* 未完成的功能,欢迎一起来开发。 +* 未完成的功能,欢迎一起来开发,特别是【待认领】的任务。 -- [ ] 首页 +- [x] 首页 - 商品相关 - - [ ] 分类列表 - - [ ] 商品搜索 - - [ ] 商品列表(基于分类) + - [x] 分类列表 + - [x] 商品搜索 + - [x] 商品列表(基于分类) - [ ] 商品列表(基于促销活动) - - [ ] 商品详情 - - [ ] 商品收藏 + - [x] 商品详情 + - [ ] 商品收藏【待认领】 - 订单相关 - - [ ] 下单(直接购买) - - [ ] 下单(购物车购买) + - [x] 下单(直接购买) + - [x] 下单(购物车购买) - [ ] 下单(拼团) - - [ ] 订单列表 - - [ ] 订单详情 - - [ ] 支付 + - [x] 订单列表 + - [x] 订单详情 + - [x] 支付 - [ ] 退款 - - [ ] 购物车 - - [ ] 收获地址 + - [x] 购物车 + - [x] 收获地址 - 营销相关 - - [ ] 优惠劵 - - [ ] 优惠码 + - [x] 优惠劵 + - [ ] 优惠码【待认领】 - 用户相关 - - [ ] 登陆 - - [ ] 注册 + - [x] 登陆 + - [x] 注册 - [ ] 个人信息 diff --git a/docs/guides/功能列表/功能列表-管理后台.md b/docs/guides/功能列表/功能列表-管理后台.md index 7dd3ab874..e75d50734 100644 --- a/docs/guides/功能列表/功能列表-管理后台.md +++ b/docs/guides/功能列表/功能列表-管理后台.md @@ -1,33 +1,33 @@ 如下是 onemall 的功能列表。 * 当功能被完成时,会标记已完成。 -* 未完成的功能,欢迎一起来开发。 +* 未完成的功能,欢迎一起来开发,特别是【待认领】的任务。 -- [ ] 概述 TODO -- [ ] 数据分析 +- [ ] 概述 TODO【待认领】 +- [ ] 数据分析【待认领】 - [ ] TODO 未开始 -- [ ] 店铺资产 +- [ ] 店铺资产【待认领】 - [ ] TODO 未开始 - [ ] 商品管理 - [x] 发布商品 - - [ ] 商品管理 + - [x] 商品列表 - [x] 展示类目 - - [ ] 品牌管理 + - [ ] 品牌管理【待认领】 - [ ] 订单管理 - [ ] 销售单 - [ ] 售后单 - - [ ] 订单评价 + - [ ] 订单评价【待认领】 - [ ] 会员管理 - - [ ] 会员资料 + - [ ] 会员资料【待认领】 - TODO 需要补充 - [ ] 营销管理 - [ ] 广告管理 - [ ] 优惠劵 - - [ ] 优惠码 + - [ ] 优惠码【待认领】 - [ ] 商品推荐 - [ ] 满减送活动 - [ ] 限制折扣活动 - - [ ] 团购活动 + - [ ] 团购活动【待认领】 - [ ] 系统管理 - [ ] 员工管理 - [ ] 角色管理 @@ -35,4 +35,7 @@ - [ ] 短信管理 - [ ] 短信模板 - [ ] 发送日志 - - [ ] 操作日志 + - [ ] 用户访问日志 + - [ ] 员工访问日志 + - [ ] 员工操作日志 + - [ ] 异常日志 diff --git a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java index f9c4c0f1e..0719ef374 100644 --- a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java +++ b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java @@ -50,11 +50,7 @@ public class CartServiceImpl implements CartService { @SuppressWarnings("Duplicates") public CommonResult add(Integer userId, Integer skuId, Integer quantity) { // 查询 SKU 是否合法 - CommonResult skuResult = productSpuService.getProductSku(skuId); - if (skuResult.isError()) { - return CommonResult.error(skuResult); - } - ProductSkuBO sku = skuResult.getData(); + ProductSkuBO sku = productSpuService.getProductSku(skuId); if (sku == null || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用 return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode()); @@ -93,11 +89,7 @@ public class CartServiceImpl implements CartService { @SuppressWarnings("Duplicates") public CommonResult updateQuantity(Integer userId, Integer skuId, Integer quantity) { // 查询 SKU 是否合法 - CommonResult skuResult = productSpuService.getProductSku(skuId); - if (skuResult.isError()) { - return CommonResult.error(skuResult); - } - ProductSkuBO sku = skuResult.getData(); + ProductSkuBO sku = productSpuService.getProductSku(skuId); if (sku == null || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用 return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode()); @@ -160,7 +152,7 @@ public class CartServiceImpl implements CartService { // 校验商品都存在 Map calcOrderItemMap = calcOrderPriceDTO.getItems().stream() .collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item)); // KEY:skuId - List skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet()).getData(); + List skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet()); if (skus.size() != calcOrderPriceDTO.getItems().size()) { return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode()); } @@ -210,11 +202,7 @@ public class CartServiceImpl implements CartService { @SuppressWarnings("Duplicates") public CommonResult calcSkuPrice(Integer skuId) { // 查询 SKU 是否合法 - CommonResult skuResult = productSpuService.getProductSku(skuId); - if (skuResult.isError()) { - return CommonResult.error(skuResult); - } - ProductSkuBO sku = skuResult.getData(); + ProductSkuBO sku = productSpuService.getProductSku(skuId); if (sku == null || CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用 return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode()); diff --git a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java index 38808005a..ce73c0c19 100644 --- a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java +++ b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java @@ -218,28 +218,20 @@ public class OrderServiceImpl implements OrderService { // 获取商品信息 Set skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet()); - CommonResult> productResult = productSpuService.getProductSkuDetailList(skuIds); - - // 校验商品信息 - if (productResult.isError()) { - return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_SKU_FAIL.getCode()); - } - if (productResult.getData() == null) { - return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_SKU_NOT_EXISTENT.getCode()); - } - if (orderItemDTOList.size() != productResult.getData().size()) { + List productList = productSpuService.getProductSkuDetailList(skuIds); + if (orderItemDTOList.size() != productList.size()) { // 校验获得的数量,是否匹配 return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_GOODS_INFO_INCORRECT.getCode()); } // 价格计算 - CommonResult calcOrderPriceResult = calcOrderPrice(productResult.getData(), orderCreateDTO); + CommonResult calcOrderPriceResult = calcOrderPrice(productList, orderCreateDTO); if (calcOrderPriceResult.isError()) { return CommonResult.error(calcOrderPriceResult); } CalcOrderPriceBO calcOrderPrice = calcOrderPriceResult.getData(); // 设置 orderItem - Map productSpuBOMap = productResult.getData() + Map productSpuBOMap = productList .stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合 Map priceItemMap = new HashMap<>(); calcOrderPrice.getItemGroups().forEach(itemGroup -> diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/config/MVCConfiguration.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/config/MVCConfiguration.java index bfba70c60..494ac25e7 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/config/MVCConfiguration.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/config/MVCConfiguration.java @@ -2,15 +2,22 @@ package cn.iocoder.mall.product.application.config; import cn.iocoder.common.framework.config.GlobalExceptionHandler; import cn.iocoder.common.framework.servlet.CorsFilter; +import cn.iocoder.mall.admin.sdk.interceptor.AdminAccessLogInterceptor; +import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.web.servlet.config.annotation.*; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @EnableWebMvc @Configuration -@Import(value = {GlobalExceptionHandler.class}) // 统一全局返回 +@Import(value = {GlobalExceptionHandler.class, // 统一全局返回 + AdminSecurityInterceptor.class, AdminAccessLogInterceptor.class}) public class MVCConfiguration implements WebMvcConfigurer { // @Autowired @@ -19,9 +26,16 @@ public class MVCConfiguration implements WebMvcConfigurer { // @Reference // private OAuth2Service oauth2Service; + @Autowired + private AdminSecurityInterceptor adminSecurityInterceptor; + @Autowired + private AdminAccessLogInterceptor adminAccessLogInterceptor; + @Override public void addInterceptors(InterceptorRegistry registry) { // registry.addInterceptor(securityInterceptor); + registry.addInterceptor(adminAccessLogInterceptor).addPathPatterns("/admins/**"); + registry.addInterceptor(adminSecurityInterceptor).addPathPatterns("/admins/**"); } @Override diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java index a6e57dbe6..cbf31d969 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; +import static cn.iocoder.common.framework.vo.CommonResult.*; @RestController @RequestMapping("admins") @@ -40,18 +41,18 @@ public class AdminsProductAttrController { // 创建 ProductAttrPageDTO 对象 ProductAttrPageDTO productAttrPageDTO = new ProductAttrPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize); // 查询分页 - CommonResult result = productAttrService.getProductAttrPage(productAttrPageDTO); + ProductAttrPageBO result = productAttrService.getProductAttrPage(productAttrPageDTO); // 返回结果 - return ProductAttrConvert.INSTANCE.convert2(result); + return success(ProductAttrConvert.INSTANCE.convert2(result)); } @GetMapping("/attr/tree") @ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。") public CommonResult> tree() { // 查询全列表 - CommonResult> result = productAttrService.getProductAttrList(); + List result = productAttrService.getProductAttrList(); // 返回结果 - return ProductAttrConvert.INSTANCE.convert(result); + return success(ProductAttrConvert.INSTANCE.convert(result)); } @PostMapping("/attr/add") @@ -63,9 +64,9 @@ public class AdminsProductAttrController { // 创建 ProductAttrAddDTO 对象 ProductAttrAddDTO productAttrAddDTO = new ProductAttrAddDTO().setName(name); // 添加 - CommonResult result = productAttrService.addProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrAddDTO); + ProductAttrBO result = productAttrService.addProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrAddDTO); // 返回结果 - return ProductAttrConvert.INSTANCE.convert3(result); + return success(ProductAttrConvert.INSTANCE.convert3(result)); } @PostMapping("/attr/update") @@ -79,7 +80,7 @@ public class AdminsProductAttrController { // 创建 ProductAttrUpdateDTO 对象 ProductAttrUpdateDTO productAttrUpdateDTO = new ProductAttrUpdateDTO().setId(id).setName(name); // 更新 - return productAttrService.updateProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrUpdateDTO); + return success(productAttrService.updateProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrUpdateDTO)); } @PostMapping("/attr/update_status") @@ -90,7 +91,7 @@ public class AdminsProductAttrController { }) public CommonResult updateAttrStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status) { - return productAttrService.updateProductAttrStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status); + return success(productAttrService.updateProductAttrStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status)); } // TODO 芋艿 暂时不考虑 delete Attr 。因为关联逻辑比较多 @@ -106,9 +107,9 @@ public class AdminsProductAttrController { // 创建 ProductAttrValueAddDTO 对象 ProductAttrValueAddDTO productAttrValueAddDTO = new ProductAttrValueAddDTO().setAttrId(attrId).setName(name); // 添加 - CommonResult result = productAttrService.addProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueAddDTO); + ProductAttrValueBO result = productAttrService.addProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueAddDTO); // 返回结果 - return ProductAttrConvert.INSTANCE.convert4(result); + return success(ProductAttrConvert.INSTANCE.convert4(result)); } @PostMapping("/attr_value/update") @@ -122,7 +123,7 @@ public class AdminsProductAttrController { // 创建 ProductAttrValueUpdateDTO 对象 ProductAttrValueUpdateDTO productAttrValueUpdateDTO = new ProductAttrValueUpdateDTO().setId(id).setName(name); // 更新 - return productAttrService.updateProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueUpdateDTO); + return success(productAttrService.updateProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueUpdateDTO)); } @PostMapping("/attr_value/update_status") @@ -132,7 +133,7 @@ public class AdminsProductAttrController { }) public CommonResult updateAttrValueStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status) { - return productAttrService.updateProductAttrValueStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status); + return success(productAttrService.updateProductAttrValueStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status)); } // TODO 芋艿 暂时不考虑 delete Attr Value 。因为关联逻辑比较多 diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductCategoryController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductCategoryController.java index 0e5d83990..9f0465289 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductCategoryController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductCategoryController.java @@ -10,11 +10,11 @@ import cn.iocoder.mall.product.api.dto.ProductCategoryUpdateDTO; import cn.iocoder.mall.product.application.convert.ProductCategoryConvert; import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO; import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryVO; -import org.apache.dubbo.config.annotation.Reference; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; +import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -24,6 +24,8 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static cn.iocoder.common.framework.vo.CommonResult.success; + @RestController @RequestMapping("admins/category") @Api("商品分类") @@ -36,7 +38,7 @@ public class AdminsProductCategoryController { @GetMapping("/tree") @ApiOperation("获得分类树结构") public CommonResult> tree() { - List productCategories = productCategoryService.getAll().getData(); + List productCategories = productCategoryService.getAll(); // 创建 ProductCategoryTreeNodeVO Map Map treeNodeMap = productCategories.stream().collect(Collectors.toMap(ProductCategoryBO::getId, ProductCategoryConvert.Admins.INSTANCE::convert)); // 处理父子关系 @@ -56,7 +58,7 @@ public class AdminsProductCategoryController { .filter(node -> node.getPid().equals(ProductCategoryConstants.PID_ROOT)) .sorted(Comparator.comparing(AdminsProductCategoryTreeNodeVO::getSort)) .collect(Collectors.toList()); - return CommonResult.success(rootNodes); + return success(rootNodes); } @PostMapping("/add") @@ -77,9 +79,9 @@ public class AdminsProductCategoryController { ProductCategoryAddDTO productCategoryAddDTO = new ProductCategoryAddDTO().setPid(pid).setName(name) .setDescription(description).setPicUrl(picUrl).setSort(sort); // 创建商品分类 - CommonResult result = productCategoryService.addProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO); + ProductCategoryBO result = productCategoryService.addProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO); // 返回结果 - return ProductCategoryConvert.Admins.INSTANCE.convert2(result); + return success(ProductCategoryConvert.Admins.INSTANCE.convert2(result)); } @PostMapping("/update") @@ -102,7 +104,7 @@ public class AdminsProductCategoryController { ProductCategoryUpdateDTO productCategoryAddDTO = new ProductCategoryUpdateDTO().setId(id).setPid(pid).setName(name) .setDescription(description).setPicUrl(picUrl).setSort(sort); // 更新商品分类 - return productCategoryService.updateProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO); + return success(productCategoryService.updateProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO)); } @PostMapping("/update_status") @@ -113,14 +115,14 @@ public class AdminsProductCategoryController { }) public CommonResult updateStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status) { - return productCategoryService.updateProductCategoryStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status); + return success(productCategoryService.updateProductCategoryStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status)); } @PostMapping("/delete") @ApiOperation(value = "删除商品分类") @ApiImplicitParam(name = "id", value = "商品分类编号", required = true, example = "1") public CommonResult delete(@RequestParam("id") Integer id) { - return productCategoryService.deleteProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), id); + return success(productCategoryService.deleteProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), id)); } } diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java index 6ca7d9b54..ed4e65a6b 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java @@ -12,19 +12,21 @@ import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO; import cn.iocoder.mall.product.application.convert.ProductSpuConvert; import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO; import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuPageVO; -import org.apache.dubbo.config.annotation.Reference; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; +import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.util.List; +import static cn.iocoder.common.framework.vo.CommonResult.success; + @RestController @RequestMapping("admins") @Api("商品 SPU + SKU") @@ -47,7 +49,6 @@ public class AdminsProductSpuController { @ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"), @ApiImplicitParam(name = "visible", value = "是否上架商品(是否可见)", required = true, example = "true"), @ApiImplicitParam(name = "skuStr", value = "SKU 字符串", required = true, example = "[{\"attrs\": [1,3 ], \"price\": 1, \"quantity\": 100, \"picUrl\": \"http://www.iocoder.cn\"}]"), - }) public CommonResult add(@RequestParam("name") String name, @RequestParam("sellPoint") String sellPoint, @@ -61,9 +62,9 @@ public class AdminsProductSpuController { .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class)); // 保存商品 - CommonResult result = productSpuService.addProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuAddDTO); + ProductSpuDetailBO result = productSpuService.addProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuAddDTO); // 返回结果 - return ProductSpuConvert.INSTANCE.convert(result); + return success(ProductSpuConvert.INSTANCE.convert(result)); } @PostMapping("/spu/update") @@ -77,7 +78,6 @@ public class AdminsProductSpuController { @ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"), @ApiImplicitParam(name = "visible", value = "是否上架商品(是否可见)", required = true, example = "true"), @ApiImplicitParam(name = "skuStr", value = "SKU 字符串", required = true, example = "[{\"attrs\": [1,3 ], \"price\": 1, \"quantity\": 100, \"picUrl\": \"http://www.iocoder.cn\"}]"), - }) public CommonResult update(@RequestParam("id") Integer id, @RequestParam("name") String name, @@ -92,14 +92,15 @@ public class AdminsProductSpuController { .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class)); // 更新商品 - return productSpuService.updateProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuUpdateDTO); + productSpuService.updateProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuUpdateDTO); + return success(true); } @PostMapping("/spu/update_sort") @ApiOperation("更新商品的排序") public CommonResult updateSort(@RequestParam("id") Integer id, @RequestParam("sort") Integer sort) { - return productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort); + return success(productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort)); } // TODO 芋艿,删除功能暂时不做。主要原因是,关联的数据太多。删除带来的问题会比较大 @@ -109,22 +110,37 @@ public class AdminsProductSpuController { @ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "商品名称,模糊匹配", example = "小王"), @ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"), + @ApiImplicitParam(name = "status", value = "状态", example = "可选值:1-在售中;2-已售罄;3-仓库中;"), + @ApiImplicitParam(name = "cid", value = "商品分类编号", example = "10"), @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"), }) public CommonResult spuPage(@RequestParam(value = "name", required = false) String name, + @RequestParam(value = "status") Integer status, + @RequestParam(value = "cid", required = false) Integer cid, @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { // 创建 ProductSpuPageDTO 对象 - ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize); - CommonResult result = productSpuService.getProductSpuPage(productSpuPageDTO); - return ProductSpuConvert.INSTANCE.convert2(result); + ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setName(name).setCid(cid).setPageNo(pageNo).setPageSize(pageSize); + switch (status) { + case 1: + productSpuPageDTO.setVisible(true).setHasQuantity(true); + break; + case 2: + productSpuPageDTO.setVisible(true).setHasQuantity(false); + break; + case 3: + productSpuPageDTO.setVisible(false); + break; + } + ProductSpuPageBO result = productSpuService.getProductSpuPage(productSpuPageDTO); + return success(ProductSpuConvert.INSTANCE.convert2(result)); } @GetMapping("/spu/info") @ApiOperation("商品 SPU 明细") @ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100") public CommonResult info(@RequestParam("id") Integer id) { - return ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id)); + return success(ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id))); } private List parseSkus(String skuStr, Class clazz) { diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductSpuController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductSpuController.java index 190a23d1a..4cfaf4021 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductSpuController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductSpuController.java @@ -19,6 +19,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import static cn.iocoder.common.framework.vo.CommonResult.success; + @RestController @RequestMapping("users/spu") @Api("商品 SPU + SKU") @@ -33,7 +35,7 @@ public class UsersProductSpuController { @ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100") @PermitAll public CommonResult info(@RequestParam("id") Integer id) { - return ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id)); + return success(ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id))); } @GetMapping("/page") @@ -52,9 +54,9 @@ public class UsersProductSpuController { ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setCid(cid).setVisible(true) .setPageNo(pageNo).setPageSize(pageSize); // 查询分页 - CommonResult result = productSpuService.getProductSpuPage(productSpuPageDTO); + ProductSpuPageBO result = productSpuService.getProductSpuPage(productSpuPageDTO); // 返回结果 - return ProductSpuConvert.INSTANCE.convert3(result); + return success(ProductSpuConvert.INSTANCE.convert3(result)); } } diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductAttrConvert.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductAttrConvert.java index 00201f43a..2d9a9f9e2 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductAttrConvert.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductAttrConvert.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.product.application.convert; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.bo.ProductAttrBO; import cn.iocoder.mall.product.api.bo.ProductAttrPageBO; import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO; @@ -21,18 +20,15 @@ public interface ProductAttrConvert { ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class); @Mappings({}) - CommonResult convert2(CommonResult result); + AdminsProductAttrPageVO convert2(ProductAttrPageBO result); @Mappings({}) - CommonResult> convert(CommonResult> result); + List convert(List result); @Mappings({}) AdminsProductAttrVO convert3(ProductAttrBO productAttrBO); @Mappings({}) - CommonResult convert3(CommonResult productAttrBO); + AdminsProductAttrValueVO convert4(ProductAttrValueBO productAttrValueBO); - @Mappings({}) - CommonResult convert4(CommonResult productAttrValueBO); - -} \ No newline at end of file +} diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductCategoryConvert.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductCategoryConvert.java index 1b44f6a67..dab9af54e 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductCategoryConvert.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductCategoryConvert.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.product.application.convert; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.bo.ProductCategoryBO; import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO; import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryVO; @@ -35,7 +34,7 @@ public interface ProductCategoryConvert { AdminsProductCategoryTreeNodeVO convert(ProductCategoryBO category); @Mappings({}) - CommonResult convert2(CommonResult result); + AdminsProductCategoryVO convert2(ProductCategoryBO result); } diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java index c566f073d..d3e88ee39 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.product.application.convert; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSpuPageBO; import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO; @@ -19,16 +18,16 @@ public interface ProductSpuConvert { @Mappings({}) AdminsProductSpuDetailVO convert(ProductSpuDetailBO productSpuDetailBO); - @Mappings({}) - CommonResult convert(CommonResult result); +// @Mappings({}) +// CommonResult convert(CommonResult result); @Mappings({}) - CommonResult convert2(CommonResult result); + AdminsProductSpuPageVO convert2(ProductSpuPageBO result); @Mappings({}) - CommonResult convert3(CommonResult result); + UsersProductSpuPageVO convert3(ProductSpuPageBO result); @Mappings({}) - CommonResult convert4(CommonResult result); + UsersProductSpuDetailVO convert4(ProductSpuDetailBO result); -} \ No newline at end of file +} diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuPageVO.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuPageVO.java index f81151a9b..c83583d2c 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuPageVO.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuPageVO.java @@ -13,8 +13,8 @@ import java.util.List; public class AdminsProductSpuPageVO { @ApiModelProperty(value = "spu 数组", required = true) - private List spus; + private List list; @ApiModelProperty(value = "总数", required = true) - private Integer count; + private Integer total; } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductAttrService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductAttrService.java index 00dc3a588..afad70ff6 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductAttrService.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductAttrService.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.product.api; -import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.common.framework.constant.CommonStatusEnum; +import cn.iocoder.common.framework.validator.InEnum; import cn.iocoder.mall.product.api.bo.ProductAttrBO; import cn.iocoder.mall.product.api.bo.ProductAttrPageBO; import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO; @@ -11,7 +12,7 @@ import java.util.List; public interface ProductAttrService { - CommonResult getProductAttrPage(ProductAttrPageDTO productAttrPageDTO); + ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO); /** * 获得规格属性数组 @@ -20,19 +21,20 @@ public interface ProductAttrService { * * @return 规格属性数组 */ - CommonResult> getProductAttrList(); + List getProductAttrList(); - CommonResult addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO); + ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO); - CommonResult updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO); + Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO); - CommonResult updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status); + Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status); + ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO); - CommonResult addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO); + Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO); - CommonResult updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO); + Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status); - CommonResult updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status); - -} \ No newline at end of file +} diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductCategoryService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductCategoryService.java index ec8972ca0..695ee8c45 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductCategoryService.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductCategoryService.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.product.api; -import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.common.framework.constant.CommonStatusEnum; +import cn.iocoder.common.framework.validator.InEnum; import cn.iocoder.mall.product.api.bo.ProductCategoryBO; import cn.iocoder.mall.product.api.dto.ProductCategoryAddDTO; import cn.iocoder.mall.product.api.dto.ProductCategoryUpdateDTO; @@ -27,14 +28,15 @@ public interface ProductCategoryService { /** * @return 返回所有产品分类们 */ - CommonResult> getAll(); + List getAll(); - CommonResult addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO); + ProductCategoryBO addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO); - CommonResult updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO); + Boolean updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO); - CommonResult updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status); + Boolean updateProductCategoryStatus(Integer adminId, Integer productCategoryId, + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status); - CommonResult deleteProductCategory(Integer admin, Integer productCategoryId); + Boolean deleteProductCategory(Integer admin, Integer productCategoryId); } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java index b2968d8dc..3f5ed28ad 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.product.api; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.bo.*; import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO; import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO; @@ -11,7 +10,7 @@ import java.util.List; public interface ProductSpuService { - CommonResult getProductSpuDetail(Integer id); + ProductSpuDetailBO getProductSpuDetail(Integer id); /** * 增量获得商品列表,按照 lastId 递增获得 @@ -20,20 +19,20 @@ public interface ProductSpuService { * @param limit 大小 * @return 商品列表 */ - CommonResult> getProductSpuDetailListForSync(Integer lastId, Integer limit); + List getProductSpuDetailListForSync(Integer lastId, Integer limit); - CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO); + ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO); - CommonResult> getProductSpuList(Collection ids); + List getProductSpuList(Collection ids); - CommonResult getProductSku(Integer id); + ProductSkuBO getProductSku(Integer id); - CommonResult> getProductSkuDetailList(Collection ids); + List getProductSkuDetailList(Collection ids); - CommonResult addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO); + ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO); - CommonResult updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO); + void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO); - CommonResult updateProductSpuSort(Integer adminId, Integer spuId, Integer sort); + Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort); } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java index a32ef38ef..c969b94fd 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java @@ -16,10 +16,10 @@ public class ProductSpuPageBO implements Serializable { /** * Spu 数组 */ - private List spus; + private List list; /** * 总量 */ - private Integer count; + private Integer total; } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java index 604841b2d..0893adb9e 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java @@ -26,6 +26,12 @@ public class ProductSpuPageDTO { * 是否可见 */ private Boolean visible; + /** + * 是否有库存 + * + * 允许为空。空时,不进行筛选 + */ + private Boolean hasQuantity; @NotNull(message = "页码不能为空") private Integer pageNo; diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java index 71294dd20..07867572c 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java @@ -32,11 +32,13 @@ public interface ProductSpuMapper { List selectListByNameLikeOrderBySortAsc(@Param("name") String name, @Param("cid") Integer cid, @Param("visible") Boolean visible, + @Param("hasQuantity") Boolean hasQuantity, @Param("offset") Integer offset, @Param("limit") Integer limit); Integer selectCountByNameLike(@Param("name") String name, @Param("cid") Integer cid, + @Param("hasQuantity") Boolean hasQuantity, @Param("visible") Boolean visible); } diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java index 4d3003e53..7aee46afe 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java @@ -1,9 +1,7 @@ package cn.iocoder.mall.product.service; import cn.iocoder.common.framework.constant.DeletedStatusEnum; -import cn.iocoder.common.framework.constant.SysErrorCodeEnum; import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.ProductAttrService; import cn.iocoder.mall.product.api.bo.*; import cn.iocoder.mall.product.api.constant.ProductAttrConstants; @@ -37,16 +35,16 @@ public class ProductAttrServiceImpl implements ProductAttrService { @Autowired private ProductAttrValueMapper productAttrValueMapper; - public CommonResult> validProductAttrAndValue(Set productAttrValueIds, boolean validStatus) { + public List validProductAttrAndValue(Set productAttrValueIds, boolean validStatus) { // 首先,校验规格值 List attrValues = productAttrValueMapper.selectListByIds(productAttrValueIds); if (attrValues.size() != productAttrValueIds.size()) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); } if (validStatus) { for (ProductAttrValueDO attrValue : attrValues) { // 同时,校验下状态 if (ProductAttrConstants.ATTR_STATUS_DISABLE.equals(attrValue.getStatus())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); } } } @@ -54,25 +52,24 @@ public class ProductAttrServiceImpl implements ProductAttrService { Set attrIds = attrValues.stream().map(ProductAttrValueDO::getAttrId).collect(Collectors.toSet()); List attrs = productAttrMapper.selectListByIds(attrIds); if (attrs.size() != attrIds.size()) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); } if (validStatus) { for (ProductAttrDO attr : attrs) { // 同时,校验下状态 if (ProductAttrConstants.ATTR_VALUE_STATUS_DISABLE.equals(attr.getStatus())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); } } } // 返回成功 Map attrMap = attrs.stream().collect(Collectors.toMap(ProductAttrDO::getId, productAttrDO -> productAttrDO)); // ProductAttrDO 的映射,方便查找。 - List result = attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO() + return attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO() .setAttrId(productAttrValueDO.getAttrId()).setAttrName(attrMap.get(productAttrValueDO.getAttrId()).getName()) .setAttrValueId(productAttrValueDO.getId()).setAttrValueName(productAttrValueDO.getName())).collect(Collectors.toList()); - return CommonResult.success(result); } @Override - public CommonResult getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) { + public ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) { ProductAttrPageBO productAttrPageBO = new ProductAttrPageBO(); // 查询分页数据 int offset = productAttrPageDTO.getPageNo() * productAttrPageDTO.getPageSize(); @@ -90,16 +87,16 @@ public class ProductAttrServiceImpl implements ProductAttrService { } } // 返回结果 - return CommonResult.success(productAttrPageBO); + return productAttrPageBO; } @Override - public CommonResult> getProductAttrList() { + public List getProductAttrList() { // 查询所有开启的规格数组 List attrs = ProductAttrConvert.INSTANCE.convert3(productAttrMapper.selectListByStatus(ProductAttrConstants.ATTR_STATUS_ENABLE)); // 如果为空,则返回空 if (attrs.isEmpty()) { - return CommonResult.success(Collections.emptyList()); + return Collections.emptyList(); } // 将规格值拼接上去 List attrValues = productAttrValueMapper.selectListByStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE); @@ -107,14 +104,14 @@ public class ProductAttrServiceImpl implements ProductAttrService { for (ProductAttrSimpleBO productAttrSimpleBO : attrs) { productAttrSimpleBO.setValues(ProductAttrConvert.INSTANCE.convert4(((attrValueMap).get(productAttrSimpleBO.getId())))); } - return CommonResult.success(attrs); + return attrs; } @Override - public CommonResult addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) { + public ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) { // 校验规格名不重复 if (productAttrMapper.selectByName(productAttrAddDTO.getName()) != null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode()); } // 插入到数据库 ProductAttrDO productAttrDO = ProductAttrConvert.INSTANCE.convert(productAttrAddDTO) @@ -123,54 +120,50 @@ public class ProductAttrServiceImpl implements ProductAttrService { productAttrDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()); productAttrMapper.insert(productAttrDO); // 返回成功 - return CommonResult.success(ProductAttrConvert.INSTANCE.convert(productAttrDO)); + return ProductAttrConvert.INSTANCE.convert(productAttrDO); } @Override - public CommonResult updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) { + public Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) { // 校验存在 if (productAttrMapper.selectById(productAttrUpdateDTO.getId()) == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); } // 校验规格名不重复 ProductAttrDO existsAttrDO = productAttrMapper.selectByName(productAttrUpdateDTO.getName()); if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrUpdateDTO.getId())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode()); } // 更新到数据库 ProductAttrDO updateProductAttr = ProductAttrConvert.INSTANCE.convert(productAttrUpdateDTO); productAttrMapper.update(updateProductAttr); // 返回成功 - return CommonResult.success(true); + return true; } @Override - public CommonResult updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) { - // 校验参数 - if (!isValidAttrStatus(status)) { - return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓 - } + public Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) { // 校验存在 ProductAttrDO productAttrDO = productAttrMapper.selectById(productAttrId); if (productAttrDO == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode()); } // 校验状态 if (productAttrDO.getStatus().equals(status)) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_STATUS_EQUALS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_STATUS_EQUALS.getCode()); } // 更新到数据库 ProductAttrDO updateProductAttr = new ProductAttrDO().setId(productAttrId).setStatus(status); productAttrMapper.update(updateProductAttr); // 返回成功 - return CommonResult.success(true); + return true; } @Override - public CommonResult addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) { + public ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) { // 校验规格名不重复 if (productAttrValueMapper.selectByAttrIdAndName(productAttrValueAddDTO.getAttrId(), productAttrValueAddDTO.getName()) != null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode()); } // 插入到数据库 ProductAttrValueDO productAttrValueDO = ProductAttrConvert.INSTANCE.convert(productAttrValueAddDTO) @@ -179,58 +172,44 @@ public class ProductAttrServiceImpl implements ProductAttrService { productAttrValueDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()); productAttrValueMapper.insert(productAttrValueDO); // 返回成功 - return CommonResult.success(ProductAttrConvert.INSTANCE.convert2(productAttrValueDO)); + return ProductAttrConvert.INSTANCE.convert2(productAttrValueDO); } @Override - public CommonResult updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) { + public Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) { // 校验存在 ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueUpdateDTO.getId()); if (productAttrValueDO == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); } // 校验规格名不重复 ProductAttrValueDO existsAttrDO = productAttrValueMapper.selectByAttrIdAndName(productAttrValueDO.getAttrId(), productAttrValueUpdateDTO.getName()); if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrValueUpdateDTO.getId())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode()); } // 更新到数据库 ProductAttrValueDO updateProductValue = ProductAttrConvert.INSTANCE.convert(productAttrValueUpdateDTO); productAttrValueMapper.update(updateProductValue); // 返回成功 - return CommonResult.success(true); + return true; } @Override - public CommonResult updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) { - // 校验参数 - if (!isValidAttrValueStatus(status)) { - return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓 - } + public Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) { // 校验存在 ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueId); if (productAttrValueDO == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode()); } // 校验状态 if (productAttrValueDO.getStatus().equals(status)) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_STATUS_EQUALS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_STATUS_EQUALS.getCode()); } // 更新到数据库 ProductAttrValueDO updateProductAttrValue = new ProductAttrValueDO().setId(productAttrValueId).setStatus(status); productAttrValueMapper.update(updateProductAttrValue); // 返回成功 - return CommonResult.success(true); - } - - private boolean isValidAttrStatus(Integer status) { - return ProductAttrConstants.ATTR_STATUS_ENABLE.equals(status) - || ProductAttrConstants.ATTR_STATUS_DISABLE.equals(status); - } - - private boolean isValidAttrValueStatus(Integer status) { - return ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE.equals(status) - || ProductAttrConstants.ATTR_VALUE_STATUS_DISABLE.equals(status); + return true; } } diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductCategoryServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductCategoryServiceImpl.java index 8b3e9bd93..e2ebaba6d 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductCategoryServiceImpl.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductCategoryServiceImpl.java @@ -1,9 +1,7 @@ package cn.iocoder.mall.product.service; import cn.iocoder.common.framework.constant.DeletedStatusEnum; -import cn.iocoder.common.framework.constant.SysErrorCodeEnum; import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.ProductCategoryService; import cn.iocoder.mall.product.api.bo.ProductCategoryBO; import cn.iocoder.mall.product.api.constant.ProductCategoryConstants; @@ -40,13 +38,13 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } @Override - public CommonResult> getAll() { + public List getAll() { List categoryList = productCategoryMapper.selectList(); - return CommonResult.success(ProductCategoryConvert.INSTANCE.convertToBO(categoryList)); + return ProductCategoryConvert.INSTANCE.convertToBO(categoryList); } @Override - public CommonResult addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) { + public ProductCategoryBO addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) { // 校验父分类 validParent(productCategoryAddDTO.getPid()); // 保存到数据库 @@ -57,62 +55,58 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { productCategoryMapper.insert(productCategory); // TODO 操作日志 // 返回成功 - return CommonResult.success(ProductCategoryConvert.INSTANCE.convertToBO(productCategory)); + return ProductCategoryConvert.INSTANCE.convertToBO(productCategory); } @Override - public CommonResult updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) { + public Boolean updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) { // 校验父分类 validParent(productCategoryUpdateDTO.getPid()); // 校验不能设置自己为父分类 if (productCategoryUpdateDTO.getId().equals(productCategoryUpdateDTO.getPid())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_SELF.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_SELF.getCode()); } // 校验父分类是否存在 if (!ProductCategoryConstants.PID_ROOT.equals(productCategoryUpdateDTO.getPid()) && productCategoryMapper.selectById(productCategoryUpdateDTO.getPid()) == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode()); } // 更新到数据库 ProductCategoryDO updateProductCategory = ProductCategoryConvert.INSTANCE.convert(productCategoryUpdateDTO); productCategoryMapper.update(updateProductCategory); // TODO 操作日志 - return CommonResult.success(true); + return true; } @Override - public CommonResult updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status) { - // 校验参数 - if (!isValidStatus(status)) { - return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓 - } + public Boolean updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status) { // 校验分类是否存在 ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId); if (productCategory == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); } // 如果状态相同,则返回错误 if (productCategory.getStatus().equals(status)) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_STATUS_EQUALS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_STATUS_EQUALS.getCode()); } // 更新商品分类 ProductCategoryDO updateProductCategory = new ProductCategoryDO() .setId(productCategoryId).setStatus(status); productCategoryMapper.update(updateProductCategory); // TODO 操作日志 - return CommonResult.success(true); + return true; } @Override - public CommonResult deleteProductCategory(Integer admin, Integer productCategoryId) { + public Boolean deleteProductCategory(Integer admin, Integer productCategoryId) { // 校验分类是否存在 ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId); if (productCategory == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); } // 只有禁用的商品分类才可以删除 if (ProductCategoryConstants.STATUS_ENABLE.equals(productCategory.getStatus())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_DELETE_ONLY_DISABLE.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_DELETE_ONLY_DISABLE.getCode()); } // TODO 芋艿:考虑下,是否需要判断下该分类下是否有商品 // TODO 芋艿,需要补充下,还有子分类 @@ -122,30 +116,25 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { updateProductCategory.setDeleted(DeletedStatusEnum.DELETED_YES.getValue()); productCategoryMapper.update(updateProductCategory); // TODO 操作日志 - return CommonResult.success(true); + return true; } public ProductCategoryDO getProductCategory(Integer productCategoryId) { return productCategoryMapper.selectById(productCategoryId); } - public CommonResult validProductCategory(Integer productCategoryId) { + public ProductCategoryDO validProductCategory(Integer productCategoryId) { // 校验分类是否存在 ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId); if (productCategory == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode()); } // 只有禁用的商品分类才可以删除 if (ProductCategoryConstants.STATUS_DISABLE.equals(productCategory.getStatus())) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_MUST_ENABLE.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_MUST_ENABLE.getCode()); } // 返回结果 - return CommonResult.success(productCategory); - } - - private boolean isValidStatus(Integer status) { - return ProductCategoryConstants.STATUS_ENABLE.equals(status) - || ProductCategoryConstants.STATUS_DISABLE.equals(status); + return productCategory; } private void validParent(Integer pid) { diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java index 7c3208297..fb46f965c 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java @@ -4,7 +4,6 @@ import cn.iocoder.common.framework.constant.DeletedStatusEnum; import cn.iocoder.common.framework.util.CollectionUtil; import cn.iocoder.common.framework.util.ServiceExceptionUtil; import cn.iocoder.common.framework.util.StringUtil; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.ProductSpuService; import cn.iocoder.mall.product.api.bo.*; import cn.iocoder.mall.product.api.constant.ProductCategoryConstants; @@ -56,11 +55,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { // } @Override - public CommonResult getProductSpuDetail(Integer id) { + public ProductSpuDetailBO getProductSpuDetail(Integer id) { // 校验商品 spu 存在 ProductSpuDO spu = productSpuMapper.selectById(id); if (spu == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); } // 获得商品分类分类 ProductCategoryDO category = productCategoryService.getProductCategory(spu.getCid()); @@ -70,55 +69,48 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 获得规格 Set productAttrValueIds = new HashSet<>(); skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ","))); - CommonResult> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds, + List attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds, false); // 读取规格时,不考虑规格是否被禁用 // 返回成功 - return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(), category)); + return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category); } @Override - public CommonResult> getProductSpuDetailListForSync(Integer lastId, Integer limit) { + public List getProductSpuDetailListForSync(Integer lastId, Integer limit) { // TODO 芋艿,这里目前是一个一个进行计算,后续需要优化下 // 查询下一批商品编号集合 List spuIds = productSpuMapper.selectIdListByIdGt(lastId, limit); if (spuIds.isEmpty()) { - return CommonResult.success(Collections.emptyList()); + return Collections.emptyList(); } // 查询每个商品明细 - List spus = spuIds.stream().map(id -> getProductSpuDetail(id).getData()).collect(Collectors.toList()); // TODO 芋艿,此处相当于是 N 个查询,后续要优化。 - return CommonResult.success(spus); + List spus = spuIds.stream().map(id -> getProductSpuDetail(id)).collect(Collectors.toList()); // TODO 芋艿,此处相当于是 N 个查询,后续要优化。 + return spus; } @Override - public CommonResult addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) { - CommonResult result = addProductSpu0(adminId, productSpuAddDTO); + public ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) { + ProductSpuDetailBO productSpuDetailBO = addProductSpu0(adminId, productSpuAddDTO); // 如果新增生成,发送创建商品 Topic 消息 - if (result.isSuccess()) { - // TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞 - sendProductUpdateMessage(result.getData().getId()); - } - return result; + // TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞 + sendProductUpdateMessage(productSpuDetailBO.getId()); + // 返回成功 + return productSpuDetailBO; } @SuppressWarnings("Duplicates") @Transactional - public CommonResult addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) { + public ProductSpuDetailBO addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) { // 校验商品分类分类存在 - CommonResult validCategoryResult = productCategoryService.validProductCategory(productSpuAddDTO.getCid()); - if (validCategoryResult.isError()) { - return CommonResult.error(validCategoryResult); - } - if (ProductCategoryConstants.PID_ROOT.equals(validCategoryResult.getData().getPid())) { // 商品只能添加到二级分类下 - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode()); + ProductCategoryDO category = productCategoryService.validProductCategory(productSpuAddDTO.getCid()); + if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下 + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode()); } // 校验规格是否存在 Set productAttrValueIds = new HashSet<>(); productSpuAddDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs())); - CommonResult> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds + List attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds , true); // 读取规格时,需要考虑规格是否被禁用 - if (validAttrResult.isError()) { - return CommonResult.error(validAttrResult); - } // 保存 Spu ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(productSpuAddDTO) .setPicUrls(StringUtil.join(productSpuAddDTO.getPicUrls(), ",")) @@ -138,55 +130,40 @@ public class ProductSpuServiceImpl implements ProductSpuService { return sku; }).collect(Collectors.toList()); // 校验 Sku 规格 - CommonResult validProductSkuResult = validProductSku(productSpuAddDTO.getSkus(), validAttrResult.getData()); - if (validProductSkuResult.isError()) { -// return CommonResult.error(validProductSkuResult); - throw ServiceExceptionUtil.exception(validProductSkuResult.getCode()); - } + validProductSku(productSpuAddDTO.getSkus(), attrAndValuePairList); + // 插入 SKU 到数据库 productSkuMapper.insertList(skus); // 返回成功 - return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(), - validCategoryResult.getData())); + return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category); } @Override - public CommonResult updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) { - CommonResult result = updateProductSpu0(adminId, productSpuUpdateDTO); - if (result.isSuccess()) { - // TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞 - sendProductUpdateMessage(productSpuUpdateDTO.getId()); - } - return result; + public void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) { + // 更新商品 + updateProductSpu0(adminId, productSpuUpdateDTO); + // TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞 + sendProductUpdateMessage(productSpuUpdateDTO.getId()); } @SuppressWarnings("Duplicates") @Transactional - public CommonResult updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) { + public void updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) { // 校验 Spu 是否存在 if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); } // 校验商品分类分类存在 - CommonResult validCategoryResult = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid()); - if (validCategoryResult.isError()) { - return CommonResult.error(validCategoryResult); - } - if (ProductCategoryConstants.PID_ROOT.equals(validCategoryResult.getData().getPid())) { // 商品只能添加到二级分类下 - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode()); + ProductCategoryDO category = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid()); + if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下 + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode()); } // 校验规格是否存在 Set productAttrValueIds = new HashSet<>(); productSpuUpdateDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs())); - CommonResult> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds, + List attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds, true); // 读取规格时,需要考虑规格是否被禁用 - if (validAttrResult.isError()) { - return CommonResult.error(validAttrResult); - } // 校验 Sku 规格 - CommonResult validProductSkuResult = validProductSku(productSpuUpdateDTO.getSkus(), validAttrResult.getData()); - if (validProductSkuResult.isError()) { - return CommonResult.error(validProductSkuResult); - } + validProductSku(productSpuUpdateDTO.getSkus(), attrAndValuePairList); // 更新 Spu ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO) .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ",")); @@ -228,14 +205,13 @@ public class ProductSpuServiceImpl implements ProductSpuService { if (!deleteSkus.isEmpty()) { productSkuMapper.updateToDeleted(deleteSkus); } - return CommonResult.success(true); } @Override - public CommonResult updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) { + public Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) { // 校验 Spu 是否存在 if (productSpuMapper.selectById(spuId) == null) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); } // 更新排序 ProductSpuDO updateSpu = new ProductSpuDO().setId(spuId).setSort(sort); @@ -243,54 +219,55 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 修改成功,发送商品 Topic 消息 sendProductUpdateMessage(spuId); // 返回成功 - return CommonResult.success(true); + return true; } @Override - public CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) { + public ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) { ProductSpuPageBO productSpuPage = new ProductSpuPageBO(); // 查询分页数据 int offset = (productSpuPageDTO.getPageNo() - 1) * productSpuPageDTO.getPageSize(); - productSpuPage.setSpus(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc( - productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getVisible(), + productSpuPage.setList(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc( + productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(), productSpuPageDTO.getVisible(), offset, productSpuPageDTO.getPageSize()))); // 查询分页总数 - productSpuPage.setCount(productSpuMapper.selectCountByNameLike(productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getVisible())); + productSpuPage.setTotal(productSpuMapper.selectCountByNameLike(productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(), + productSpuPageDTO.getVisible())); // 返回结果 - return CommonResult.success(productSpuPage); + return productSpuPage; } @Override - public CommonResult> getProductSpuList(Collection ids) { + public List getProductSpuList(Collection ids) { List spus = productSpuMapper.selectByIds(ids); - return CommonResult.success(ProductSpuConvert.INSTANCE.convert(spus)); + return ProductSpuConvert.INSTANCE.convert(spus); } @Override - public CommonResult getProductSku(Integer id) { + public ProductSkuBO getProductSku(Integer id) { ProductSkuDO sku = productSkuMapper.selectById(id); - return CommonResult.success(ProductSpuConvert.INSTANCE.convert4(sku)); + return ProductSpuConvert.INSTANCE.convert4(sku); } @Override - public CommonResult> getProductSkuDetailList(Collection ids) { + public List getProductSkuDetailList(Collection ids) { // 查询 SKU 数组 List skus = productSkuMapper.selectByIds(ids); if (skus.isEmpty()) { - return CommonResult.success(Collections.emptyList()); + return Collections.emptyList(); } // 查询 SPU 数组 List spus = productSpuMapper.selectByIds(skus.stream().map(ProductSkuDO::getSpuId).collect(Collectors.toSet())); if (spus.isEmpty()) { - return CommonResult.success(Collections.emptyList()); + return Collections.emptyList(); } // 获得规格 Set productAttrValueIds = new HashSet<>(); skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ","))); - CommonResult> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds, + List attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds, false); // 读取规格时,不考虑规格是否被禁用 // 返回成功 - return CommonResult.success(ProductSpuConvert.INSTANCE.convert3(skus, spus, validAttrResult.getData())); + return ProductSpuConvert.INSTANCE.convert3(skus, spus, attrAndValuePairList); } /** @@ -300,33 +277,34 @@ public class ProductSpuServiceImpl implements ProductSpuService { * @param productAttrDetailBOs 商品规格明细数组 * @return 是否校验通过 */ - private CommonResult validProductSku(List productSkuAddDTOs, List productAttrDetailBOs) { + private Boolean validProductSku(List productSkuAddDTOs, List productAttrDetailBOs) { // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号 Map productAttrDetailBOMap = productAttrDetailBOs.stream().collect( Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO)); // 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) { - Set attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()).collect(Collectors.toSet()); + Set attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()) + .collect(Collectors.toSet()); if (attrIds.size() != sku.getAttrs().size()) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode()); } } // 2. 再校验,每个 Sku 的规格值的数量,是一致的。 int attrSize = productSkuAddDTOs.get(0).getAttrs().size(); for (int i = 1; i < productSkuAddDTOs.size(); i++) { if (attrSize != productSkuAddDTOs.get(i).getAttrs().size()) { - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS.getCode()); } } // 3. 最后校验,每个 Sku 之间不是重复的 Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) { if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败,说明重复 - return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode()); + throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode()); } } // 校验通过 - return CommonResult.success(true); + return true; } /** diff --git a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml index 96d9b1311..2632f011b 100644 --- a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml +++ b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml @@ -104,6 +104,12 @@ AND visible = #{visible} + + AND quantity > 0 + + + AND quantity = 0 + AND deleted = 0 ORDER BY sort ASC @@ -124,6 +130,12 @@ AND visible = #{visible} + + AND quantity > 0 + + + AND quantity = 0 + AND deleted = 0 diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java index 77e2b6a80..0dd016e81 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java @@ -43,7 +43,7 @@ public class UsersProductRecommendController { null, CommonStatusEnum.ENABLE.getValue()).getData(); // 获得商品集合 List spus = productSpuService.getProductSpuList( - productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet())).getData(); + productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet())); Map spuMap = spus.stream().collect(Collectors.toMap(ProductSpuBO::getId, account -> account)); // 组合结果,返回 Multimap result = HashMultimap.create(); diff --git a/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java b/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java index cd5768202..8a74b5729 100644 --- a/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java +++ b/search/search-application/src/main/java/cn/iocoder/mall/search/application/controller/users/UsersProductSearchController.java @@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Collections; +import static cn.iocoder.common.framework.vo.CommonResult.success; + @RestController @RequestMapping("users/product") @Api("商品搜索") @@ -39,7 +41,7 @@ public class UsersProductSearchController { productSearchPageDTO.setSorts(Collections.singletonList(new SortingField(sortField, sortOrder))); } // 执行搜索 - return productSearchService.getSearchPage(productSearchPageDTO); + return success(productSearchService.getSearchPage(productSearchPageDTO)); } @GetMapping("/condition") // TODO 芋艿,后面把 BO 改成 VO @@ -48,7 +50,7 @@ public class UsersProductSearchController { ProductConditionDTO productConditionDTO = new ProductConditionDTO().setKeyword(keyword) .setFields(Collections.singleton(ProductConditionDTO.FIELD_CATEGORY)); // 执行搜索 - return productSearchService.getSearchCondition(productConditionDTO); + return success(productSearchService.getSearchCondition(productConditionDTO)); } } diff --git a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java index 6a79c4bd9..ca4f714a0 100644 --- a/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java +++ b/search/search-service-api/src/main/java/cn/iocoder/mall/search/api/ProductSearchService.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.search.api; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.search.api.bo.ProductConditionBO; import cn.iocoder.mall.search.api.bo.ProductPageBO; import cn.iocoder.mall.search.api.dto.ProductConditionDTO; @@ -8,7 +7,7 @@ import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO; public interface ProductSearchService { - CommonResult rebuild(); + Integer rebuild(); /** * 构建商品的搜索索引 @@ -16,10 +15,10 @@ public interface ProductSearchService { * @param id 商品编号 * @return 构建结果 */ - CommonResult save(Integer id); + Boolean save(Integer id); - CommonResult getSearchPage(ProductSearchPageDTO searchPageDTO); + ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO); - CommonResult getSearchCondition(ProductConditionDTO conditionDTO); + ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO); } diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java index 498cd1693..81d4fa6e9 100644 --- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java +++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java @@ -1,6 +1,5 @@ package cn.iocoder.mall.search.biz.mq; -import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.message.ProductUpdateMessage; import cn.iocoder.mall.search.api.ProductSearchService; import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; @@ -21,8 +20,8 @@ public class PayTransactionPaySuccessConsumer implements RocketMQListener result = productSearchService.save(message.getId()); - Assert.isTrue(result.isSuccess(), String.format("重构商品 ES 索引,必然成功。实际结果是 %s", result)); + Boolean result = productSearchService.save(message.getId()); + Assert.isTrue(result, String.format("重构商品 ES 索引,必然成功。实际结果是 %s", result)); } } diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java index c481271fe..d9c212e18 100644 --- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java +++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java @@ -55,14 +55,12 @@ public class ProductSearchServiceImpl implements ProductSearchService { private CartService cartService; @Override - public CommonResult rebuild() { + public Integer rebuild() { // TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构 Integer lastId = null; int rebuildCounts = 0; while (true) { - CommonResult> result = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE); - Assert.isTrue(result.isSuccess(), "获得商品列表必然成功"); - List spus = result.getData(); + List spus = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE); rebuildCounts += spus.size(); // 存储到 ES 中 List products = spus.stream().map(this::convert).collect(Collectors.toList()); @@ -75,19 +73,18 @@ public class ProductSearchServiceImpl implements ProductSearchService { } } // 返回成功 - return CommonResult.success(rebuildCounts); + return rebuildCounts; } @Override - public CommonResult save(Integer id) { + public Boolean save(Integer id) { // 获得商品性情 - CommonResult result = productSpuService.getProductSpuDetail(id); - Assert.isTrue(result.isSuccess(), "获得商品详情必然成功"); + ProductSpuDetailBO result = productSpuService.getProductSpuDetail(id); // 存储到 ES 中 - ESProductDO product = convert(result.getData()); + ESProductDO product = convert(result); productRepository.save(product); // 返回成功 - return CommonResult.success(Boolean.TRUE); + return true; } @SuppressWarnings("OptionalGetWithoutIsPresent") @@ -102,16 +99,15 @@ public class ProductSearchServiceImpl implements ProductSearchService { } @Override - public CommonResult getSearchPage(ProductSearchPageDTO searchPageDTO) { + public ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO) { checkSortFieldInvalid(searchPageDTO.getSorts()); // 执行查询 Page searchPage = productRepository.search(searchPageDTO.getCid(), searchPageDTO.getKeyword(), searchPageDTO.getPageNo(), searchPageDTO.getPageSize(), searchPageDTO.getSorts()); // 转换结果 - ProductPageBO resultPage = new ProductPageBO() + return new ProductPageBO() .setList(ProductSearchConvert.INSTANCE.convert(searchPage.getContent())) .setTotal((int) searchPage.getTotalElements()); - return CommonResult.success(resultPage); } private void checkSortFieldInvalid(List sorts) { @@ -123,7 +119,7 @@ public class ProductSearchServiceImpl implements ProductSearchService { } @Override - public CommonResult getSearchCondition(ProductConditionDTO conditionDTO) { + public ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO) { // 创建 ES 搜索条件 NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); // 筛选 @@ -161,7 +157,7 @@ public class ProductSearchServiceImpl implements ProductSearchService { condition.getCategories().forEach(category -> category.setName(categoryMap.get(category.getId()).getName())); } // 返回结果 - return CommonResult.success(condition); + return condition; } } diff --git a/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java b/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java index bc6626dc1..3cb6d38f8 100644 --- a/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java +++ b/search/search-service-impl/src/test/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImplTest.java @@ -18,7 +18,7 @@ public class ProductSearchServiceImplTest { @Test public void testRebuild() { - int counts = productSearchService.rebuild().getData(); + int counts = productSearchService.rebuild(); System.out.println("重建数量:" + counts); System.out.println(productRepository.count()); diff --git a/system/system-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java b/system/system-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java index 57476d6ad..a7a036bbb 100644 --- a/system/system-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java +++ b/system/system-sdk/src/main/java/cn/iocoder/mall/admin/sdk/interceptor/AdminAccessLogInterceptor.java @@ -33,7 +33,7 @@ public class AdminAccessLogInterceptor extends HandlerInterceptorAdapter { */ private static final ThreadLocal ADMIN_ID = new ThreadLocal<>(); - @Reference(lazy = true) + @Reference(validation = "true") @Autowired(required = false) // TODO 芋艿,初始化时,会存在 spring boot 启动时,服务无法引用的情况,先暂时这么解决。 private AdminAccessLogService adminAccessLogService;