- 前端:完善商品列表
- 后端:将商品模块的 Service 改成有业务异常时,抛出异常,而不是返回 CommonResult - 后端:将搜索模块的 Service 改成有业务异常时,抛出异常,而不是返回 CommonResultpull/1/head
parent
2519cf000e
commit
79c36a5add
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
* 整体的功能如下图:![功能图](http://static.iocoder.cn/mall%20%E5%8A%9F%E8%83%BD%E5%9B%BE-min.png)
|
* 整体的功能如下图:![功能图](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)
|
* 交流群:[传送门](http://www.iocoder.cn/mall-user-group/?vip&gitee)
|
||||||
> 一起交流,Get 知识。
|
> 一起交流,Get 知识。
|
||||||
|
|
|
@ -62,6 +62,9 @@ export default {
|
||||||
const response = yield call(productSpuInfo, {
|
const response = yield call(productSpuInfo, {
|
||||||
id: payload,
|
id: payload,
|
||||||
});
|
});
|
||||||
|
if (response.code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 响应
|
// 响应
|
||||||
let skus = [];
|
let skus = [];
|
||||||
let attrTree = [];
|
let attrTree = [];
|
||||||
|
@ -193,6 +196,9 @@ export default {
|
||||||
*add({ payload }, { call, put }) {
|
*add({ payload }, { call, put }) {
|
||||||
const { callback, body } = payload;
|
const { callback, body } = payload;
|
||||||
const response = yield call(productSpuAdd, body);
|
const response = yield call(productSpuAdd, body);
|
||||||
|
if (response.code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response);
|
callback(response);
|
||||||
}
|
}
|
||||||
|
@ -205,6 +211,9 @@ export default {
|
||||||
*update({ payload }, { call, put }) {
|
*update({ payload }, { call, put }) {
|
||||||
const { callback, body } = payload;
|
const { callback, body } = payload;
|
||||||
const response = yield call(productSpuUpdate, body);
|
const response = yield call(productSpuUpdate, body);
|
||||||
|
if (response.code !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response);
|
callback(response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,33 @@
|
||||||
import { message } from 'antd';
|
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 {routerRedux} from "dva/router";
|
||||||
|
import PaginationHelper from '../../../helpers/PaginationHelper';
|
||||||
|
|
||||||
|
const SEARCH_PARAMS_DEFAULT = {
|
||||||
|
name: '',
|
||||||
|
status: 1,
|
||||||
|
cid: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespace: 'productSpuList',
|
namespace: 'productSpuList',
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
|
// 分页列表相关
|
||||||
list: [],
|
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: {
|
effects: {
|
||||||
|
@ -35,19 +56,76 @@ export default {
|
||||||
},
|
},
|
||||||
*redirectToUpdate({ payload }, { call, put }) {
|
*redirectToUpdate({ payload }, { call, put }) {
|
||||||
// const { callback, body } = payload;
|
// const { callback, body } = payload;
|
||||||
debugger;
|
|
||||||
yield put(routerRedux.replace('/product/product-spu-update?id=' + payload));
|
yield put(routerRedux.replace('/product/product-spu-update?id=' + payload));
|
||||||
},
|
},
|
||||||
*page({ payload }, { call, put }) {
|
*page({ payload }, { call, put }) {
|
||||||
// const { queryParams } = payload;
|
// const { queryParams } = payload;
|
||||||
const response = yield call(productSpuPage, payload);
|
// const response = yield call(productSpuPage, payload);
|
||||||
message.info('查询成功!');
|
// message.info('查询成功!');
|
||||||
|
// yield put({
|
||||||
|
// type: 'treeSuccess',
|
||||||
|
// payload: {
|
||||||
|
// list: response.data,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 显示加载中
|
||||||
yield put({
|
yield put({
|
||||||
type: 'treeSuccess',
|
type: 'changeListLoading',
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求
|
||||||
|
const response = yield call(productSpuPage, payload);
|
||||||
|
// 响应
|
||||||
|
yield put({
|
||||||
|
type: 'setAll',
|
||||||
payload: {
|
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,
|
...payload,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
// 修改加载中的状态
|
||||||
|
changeSortModalLoading(state, { payload }) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sortModalLoading: payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
changeListLoading(state, { payload }) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
listLoading: payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 设置所有属性
|
||||||
|
setAll(state, { payload }) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -137,7 +137,6 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 搜索表单
|
// 搜索表单
|
||||||
// TODO 芋艿,有没办法换成上面那种写法
|
|
||||||
const SearchForm = Form.create()(props => {
|
const SearchForm = Form.create()(props => {
|
||||||
const {
|
const {
|
||||||
form,
|
form,
|
||||||
|
|
|
@ -123,6 +123,7 @@ function List({ dataSource, loading, dispatch,
|
||||||
columns={columns}
|
columns={columns}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
pagination={false}
|
||||||
dataSource={dataSource} />
|
dataSource={dataSource} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,305 @@
|
||||||
import React, { PureComponent, Fragment } from 'react';
|
import React, { PureComponent, Fragment } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import moment from 'moment';
|
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 PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||||
|
|
||||||
import styles from './ProductSpuList.less';
|
import styles from './ProductSpuList.less';
|
||||||
|
import PaginationHelper from "../../../helpers/PaginationHelper";
|
||||||
|
import PicturesWall from "../../components/Image/PicturesWall";
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { TreeNode } = Tree;
|
const { TreeNode } = Tree;
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
function List({ dataSource, loading, pagination, searchParams, dispatch,
|
||||||
|
categoryTree, handleSortModalVisible}) {
|
||||||
|
|
||||||
|
const handleTabsChange = (value) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'productSpuList/page',
|
||||||
|
payload: {
|
||||||
|
...searchParams,
|
||||||
|
status: value,
|
||||||
|
...PaginationHelper.defaultPayload,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPageChange(page) { // 翻页
|
||||||
|
dispatch({
|
||||||
|
type: 'productSpuList/page',
|
||||||
|
payload: {
|
||||||
|
pageNo: page.current,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...searchParams
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const redirectToUpdate = (spuId) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'productSpuList/redirectToUpdate',
|
||||||
|
payload: spuId,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCategoryName = (cid, array) => {
|
||||||
|
// debugger;
|
||||||
|
for (let i in array) {
|
||||||
|
// debugger;
|
||||||
|
const node = array[i];
|
||||||
|
if (node.id === cid) {
|
||||||
|
return node.name;
|
||||||
|
}
|
||||||
|
if (!node.children) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let name = getCategoryName(cid, node.children);
|
||||||
|
if (name) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
// {
|
||||||
|
// title: 'id',
|
||||||
|
// dataIndex: 'id',
|
||||||
|
// render: text => <strong>{text}</strong>,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: '商品名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '商品分类',
|
||||||
|
dataIndex: 'cid',
|
||||||
|
render: value => getCategoryName(value, categoryTree),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '商品主图',
|
||||||
|
dataIndex: 'picUrls',
|
||||||
|
render(val) {
|
||||||
|
return <img width={120} src={val[0]} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '商品库存',
|
||||||
|
dataIndex: 'quantity'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序值',
|
||||||
|
dataIndex: 'sort',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 200,
|
||||||
|
render: (text, record) => (
|
||||||
|
<Fragment>
|
||||||
|
{/*<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>*/}
|
||||||
|
<a onClick={() => redirectToUpdate(record.id)}>编辑</a>
|
||||||
|
<Divider type="vertical"/>
|
||||||
|
<a onClick={() => handleSortModalVisible(true, record)}>
|
||||||
|
排序
|
||||||
|
</a>
|
||||||
|
</Fragment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// console.log(pagination);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Tabs defaultActiveKey={searchParams.status} onChange={handleTabsChange}>
|
||||||
|
<TabPane tab="在售中" key={1} />
|
||||||
|
<TabPane tab="已售罄" key={2} />
|
||||||
|
<TabPane tab="已下架" key={3} />
|
||||||
|
</Tabs>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={dataSource}
|
||||||
|
rowKey="id"
|
||||||
|
pagination={pagination}
|
||||||
|
onChange={onPageChange}
|
||||||
|
loading={loading} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const SearchForm = Form.create()(props => {
|
||||||
|
const {
|
||||||
|
form,
|
||||||
|
form: { getFieldDecorator },
|
||||||
|
dispatch,
|
||||||
|
searchParams,
|
||||||
|
categoryTree,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
dispatch({
|
||||||
|
type: 'productSpuList/page',
|
||||||
|
payload: {
|
||||||
|
...PaginationHelper.defaultPayload,
|
||||||
|
...searchParams,
|
||||||
|
...form.getFieldsValue(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交搜索
|
||||||
|
function handleSubmit(e) {
|
||||||
|
// 阻止默认事件
|
||||||
|
e.preventDefault();
|
||||||
|
// 提交搜索
|
||||||
|
search();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置搜索
|
||||||
|
function handleReset() {
|
||||||
|
// 重置表单
|
||||||
|
form.resetFields();
|
||||||
|
// 执行搜索
|
||||||
|
search();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理分类筛选
|
||||||
|
const buildSelectTree = (list) => {
|
||||||
|
return list.map(item => {
|
||||||
|
let children = [];
|
||||||
|
if (item.children) {
|
||||||
|
children = buildSelectTree(item.children);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: item.name,
|
||||||
|
value: item.id,
|
||||||
|
key: item.id,
|
||||||
|
children,
|
||||||
|
selectable: item.pid > 0
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let categoryTreeSelect = buildSelectTree(categoryTree);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form onSubmit={handleSubmit} layout="inline">
|
||||||
|
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
|
||||||
|
<Col md={8} sm={24}>
|
||||||
|
<FormItem label="商品名称">
|
||||||
|
{getFieldDecorator('name')(<Input placeholder="请输入" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={8} sm={24}>
|
||||||
|
<FormItem label="商品名称">
|
||||||
|
{getFieldDecorator('cid')(
|
||||||
|
<TreeSelect
|
||||||
|
showSearch
|
||||||
|
style={{ width: 200 }}
|
||||||
|
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||||
|
treeData={categoryTreeSelect}
|
||||||
|
placeholder="请选择"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</FormItem>
|
||||||
|
</Col>
|
||||||
|
<Col md={8} sm={24}>
|
||||||
|
<span className={styles.submitButtons}>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
查询
|
||||||
|
</Button>
|
||||||
|
<Button style={{ marginLeft: 8 }} onClick={handleReset}>
|
||||||
|
重置
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// 新建 form 表单
|
||||||
|
const UpdateSortForm = Form.create()(props => {
|
||||||
|
const { dispatch, loading, modalVisible, form, handleModalVisible, formVals } = props;
|
||||||
|
|
||||||
|
const okHandle = () => {
|
||||||
|
form.validateFields((err, fields) => {
|
||||||
|
if (err) return;
|
||||||
|
dispatch({
|
||||||
|
type: 'productSpuList/updateSort',
|
||||||
|
payload: {
|
||||||
|
body: {
|
||||||
|
id: formVals.id,
|
||||||
|
...fields,
|
||||||
|
},
|
||||||
|
callback: () => {
|
||||||
|
// 清空表单
|
||||||
|
form.resetFields();
|
||||||
|
// 提示
|
||||||
|
message.success('编辑排序成功');
|
||||||
|
// 关闭弹窗
|
||||||
|
handleModalVisible();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const title = '编辑排序值';
|
||||||
|
const okText = '确定';
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
destroyOnClose
|
||||||
|
title={title}
|
||||||
|
visible={modalVisible}
|
||||||
|
onOk={okHandle}
|
||||||
|
okText={okText}
|
||||||
|
onCancel={() => handleModalVisible()}
|
||||||
|
>
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="排序值">
|
||||||
|
{form.getFieldDecorator('sort', {
|
||||||
|
rules: [{ required: true, message: '请输入排序值!' }],
|
||||||
|
initialValue: formVals.sort,
|
||||||
|
})(<InputNumber placeholder="请输入" />)}
|
||||||
|
</FormItem>
|
||||||
|
</Spin>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// productSpuList
|
// productSpuList
|
||||||
@connect(({ productSpuList, loading }) => ({
|
@connect(({ productSpuList, productCategoryList }) => ({
|
||||||
productSpuList,
|
...productSpuList,
|
||||||
list: productSpuList.list.spus,
|
// list: productSpuList.list.spus,
|
||||||
loading: loading.models.productSpuList,
|
// loading: loading.models.productSpuList,
|
||||||
|
categoryTree: productCategoryList.list,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@Form.create()
|
@Form.create()
|
||||||
|
@ -30,14 +316,19 @@ class ProductSpuList extends PureComponent {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
// 查询初始数据
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'productSpuList/page',
|
type: 'productSpuList/page',
|
||||||
payload: {
|
payload: {
|
||||||
name: '',
|
status: 1,
|
||||||
pageNo: 1,
|
...PaginationHelper.defaultPayload,
|
||||||
pageSize: 20,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// 获得商品分类
|
||||||
|
dispatch({
|
||||||
|
type: 'productCategoryList/tree',
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectToAdd = () => {
|
redirectToAdd = () => {
|
||||||
|
@ -47,82 +338,50 @@ class ProductSpuList extends PureComponent {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
redirectToUpdate = (spuId) => {
|
handleSortModalVisible = (sortModalVisible, record) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'productSpuList/redirectToUpdate',
|
type: 'productSpuList/setAll',
|
||||||
payload: spuId,
|
payload: {
|
||||||
|
sortModalVisible,
|
||||||
|
formVals: record || {}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// debugger;
|
const { dispatch,
|
||||||
const { list, data } = this.props;
|
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 listProps = {
|
||||||
|
dataSource: list,
|
||||||
const parentMethods = {
|
pagination,
|
||||||
handleAdd: this.handleAdd,
|
searchParams,
|
||||||
handleModalVisible: this.handleModalVisible,
|
dispatch,
|
||||||
modalType,
|
categoryTree,
|
||||||
initValues,
|
loading: listLoading,
|
||||||
|
handleSortModalVisible: this.handleSortModalVisible, // Func
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
// 搜索表单属性
|
||||||
{
|
const searchFormProps = {
|
||||||
title: 'id',
|
dispatch,
|
||||||
dataIndex: 'id',
|
categoryTree,
|
||||||
render: text => <strong>{text}</strong>,
|
searchParams,
|
||||||
},
|
};
|
||||||
{
|
|
||||||
title: '商品名称',
|
|
||||||
dataIndex: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '商品分类',
|
|
||||||
dataIndex: 'cid'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '商品主图',
|
|
||||||
dataIndex: 'picUrls',
|
|
||||||
render(val) {
|
|
||||||
return <img width={120} src={val[0]} />;
|
|
||||||
// return 'TODO';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '商品库存',
|
|
||||||
dataIndex: 'quantity'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '排序值',
|
|
||||||
dataIndex: 'sort',
|
|
||||||
render: sort => <span>{sort}</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '创建时间',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
sorter: true,
|
|
||||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
width: 200,
|
|
||||||
render: (text, record) => (
|
|
||||||
<Fragment>
|
|
||||||
{/*<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>*/}
|
|
||||||
<a onClick={() => this.redirectToUpdate(record.id)}>更新</a>
|
|
||||||
</Fragment>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// const paginationProps = {
|
// 添加 or 编辑表单属性
|
||||||
// current: pageNo,
|
// debugger;
|
||||||
// pageSize: pageSize,
|
const updateSortFormProps = {
|
||||||
// total: count,
|
modalVisible: sortModalVisible,
|
||||||
// };
|
formVals,
|
||||||
|
dispatch,
|
||||||
|
loading: sortModalLoading,
|
||||||
|
handleModalVisible: this.handleSortModalVisible, // Func
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHeaderWrapper title="">
|
<PageHeaderWrapper title="">
|
||||||
|
@ -138,7 +397,9 @@ class ProductSpuList extends PureComponent {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Table columns={columns} dataSource={list} rowKey="id" />
|
<SearchForm {...searchFormProps} />
|
||||||
|
<List {...listProps} />
|
||||||
|
<UpdateSortForm {...updateSortFormProps} />
|
||||||
</Card>
|
</Card>
|
||||||
</PageHeaderWrapper>
|
</PageHeaderWrapper>
|
||||||
);
|
);
|
||||||
|
|
|
@ -58,6 +58,13 @@ export async function productSpuUpdate(params) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function productSpuUpdateSort(params) {
|
||||||
|
return request(`/product-api/admins/spu/update_sort?${stringify(params)}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function productSpuInfo(params) {
|
export async function productSpuInfo(params) {
|
||||||
return request(`/product-api/admins/spu/info?${stringify(params)}`, {
|
return request(`/product-api/admins/spu/info?${stringify(params)}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
@ -2,8 +2,9 @@ package cn.iocoder.common.framework.config;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
||||||
import cn.iocoder.common.framework.exception.ServiceException;
|
import cn.iocoder.common.framework.exception.ServiceException;
|
||||||
import cn.iocoder.common.framework.util.ExceptionUtil;
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
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.MissingServletRequestParameterException;
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
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.servlet.http.HttpServletRequest;
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
|
||||||
|
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
// 逻辑异常
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ExceptionHandler(value = ServiceException.class)
|
@ExceptionHandler(value = ServiceException.class)
|
||||||
public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) {
|
public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) {
|
||||||
|
logger.debug("[serviceExceptionHandler]", ex);
|
||||||
return CommonResult.error(ex.getCode(), ex.getMessage());
|
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
|
@ResponseBody
|
||||||
@ExceptionHandler(value = ConstraintViolationException.class)
|
@ExceptionHandler(value = ConstraintViolationException.class)
|
||||||
public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) {
|
public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) {
|
||||||
|
logger.info("[constraintViolationExceptionHandler]", ex);
|
||||||
// TODO 芋艿,后续要想一个更好的方式。
|
// TODO 芋艿,后续要想一个更好的方式。
|
||||||
// 拼接详细报错
|
// 拼接详细报错
|
||||||
StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下:");
|
StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下:");
|
||||||
|
@ -33,34 +46,12 @@ public class GlobalExceptionHandler {
|
||||||
+ detailMessage.toString());
|
+ 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
|
@ResponseBody
|
||||||
@ExceptionHandler(value = Exception.class)
|
@ExceptionHandler(value = Exception.class)
|
||||||
public CommonResult resultExceptionHandler(HttpServletRequest req, Exception e) {
|
public CommonResult resultExceptionHandler(HttpServletRequest req, Exception e) {
|
||||||
// TODO 翻译不同的异常
|
logger.error("[resultExceptionHandler]", e);
|
||||||
if (e instanceof MissingServletRequestParameterException) {
|
|
||||||
return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage() + ":" + e.getMessage());
|
|
||||||
}
|
|
||||||
// TODO 异常日志
|
|
||||||
e.printStackTrace();
|
|
||||||
// 返回
|
// 返回
|
||||||
return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
|
return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,30 +1,30 @@
|
||||||
如下是 onemall 的功能列表。
|
如下是 onemall 的功能列表。
|
||||||
|
|
||||||
* 当功能被完成时,会标记已完成。
|
* 当功能被完成时,会标记已完成。
|
||||||
* 未完成的功能,欢迎一起来开发。
|
* 未完成的功能,欢迎一起来开发,特别是【待认领】的任务。
|
||||||
|
|
||||||
- [ ] 首页
|
- [x] 首页
|
||||||
- 商品相关
|
- 商品相关
|
||||||
- [ ] 分类列表
|
- [x] 分类列表
|
||||||
- [ ] 商品搜索
|
- [x] 商品搜索
|
||||||
- [ ] 商品列表(基于分类)
|
- [x] 商品列表(基于分类)
|
||||||
- [ ] 商品列表(基于促销活动)
|
- [ ] 商品列表(基于促销活动)
|
||||||
- [ ] 商品详情
|
- [x] 商品详情
|
||||||
- [ ] 商品收藏
|
- [ ] 商品收藏【待认领】
|
||||||
- 订单相关
|
- 订单相关
|
||||||
- [ ] 下单(直接购买)
|
- [x] 下单(直接购买)
|
||||||
- [ ] 下单(购物车购买)
|
- [x] 下单(购物车购买)
|
||||||
- [ ] 下单(拼团)
|
- [ ] 下单(拼团)
|
||||||
- [ ] 订单列表
|
- [x] 订单列表
|
||||||
- [ ] 订单详情
|
- [x] 订单详情
|
||||||
- [ ] 支付
|
- [x] 支付
|
||||||
- [ ] 退款
|
- [ ] 退款
|
||||||
- [ ] 购物车
|
- [x] 购物车
|
||||||
- [ ] 收获地址
|
- [x] 收获地址
|
||||||
- 营销相关
|
- 营销相关
|
||||||
- [ ] 优惠劵
|
- [x] 优惠劵
|
||||||
- [ ] 优惠码
|
- [ ] 优惠码【待认领】
|
||||||
- 用户相关
|
- 用户相关
|
||||||
- [ ] 登陆
|
- [x] 登陆
|
||||||
- [ ] 注册
|
- [x] 注册
|
||||||
- [ ] 个人信息
|
- [ ] 个人信息
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
如下是 onemall 的功能列表。
|
如下是 onemall 的功能列表。
|
||||||
|
|
||||||
* 当功能被完成时,会标记已完成。
|
* 当功能被完成时,会标记已完成。
|
||||||
* 未完成的功能,欢迎一起来开发。
|
* 未完成的功能,欢迎一起来开发,特别是【待认领】的任务。
|
||||||
|
|
||||||
- [ ] 概述 TODO
|
- [ ] 概述 TODO【待认领】
|
||||||
- [ ] 数据分析
|
- [ ] 数据分析【待认领】
|
||||||
- [ ] TODO 未开始
|
- [ ] TODO 未开始
|
||||||
- [ ] 店铺资产
|
- [ ] 店铺资产【待认领】
|
||||||
- [ ] TODO 未开始
|
- [ ] TODO 未开始
|
||||||
- [ ] 商品管理
|
- [ ] 商品管理
|
||||||
- [x] 发布商品
|
- [x] 发布商品
|
||||||
- [ ] 商品管理
|
- [x] 商品列表
|
||||||
- [x] 展示类目
|
- [x] 展示类目
|
||||||
- [ ] 品牌管理
|
- [ ] 品牌管理【待认领】
|
||||||
- [ ] 订单管理
|
- [ ] 订单管理
|
||||||
- [ ] 销售单
|
- [ ] 销售单
|
||||||
- [ ] 售后单
|
- [ ] 售后单
|
||||||
- [ ] 订单评价
|
- [ ] 订单评价【待认领】
|
||||||
- [ ] 会员管理
|
- [ ] 会员管理
|
||||||
- [ ] 会员资料
|
- [ ] 会员资料【待认领】
|
||||||
- TODO 需要补充
|
- TODO 需要补充
|
||||||
- [ ] 营销管理
|
- [ ] 营销管理
|
||||||
- [ ] 广告管理
|
- [ ] 广告管理
|
||||||
- [ ] 优惠劵
|
- [ ] 优惠劵
|
||||||
- [ ] 优惠码
|
- [ ] 优惠码【待认领】
|
||||||
- [ ] 商品推荐
|
- [ ] 商品推荐
|
||||||
- [ ] 满减送活动
|
- [ ] 满减送活动
|
||||||
- [ ] 限制折扣活动
|
- [ ] 限制折扣活动
|
||||||
- [ ] 团购活动
|
- [ ] 团购活动【待认领】
|
||||||
- [ ] 系统管理
|
- [ ] 系统管理
|
||||||
- [ ] 员工管理
|
- [ ] 员工管理
|
||||||
- [ ] 角色管理
|
- [ ] 角色管理
|
||||||
|
@ -35,4 +35,7 @@
|
||||||
- [ ] 短信管理
|
- [ ] 短信管理
|
||||||
- [ ] 短信模板
|
- [ ] 短信模板
|
||||||
- [ ] 发送日志
|
- [ ] 发送日志
|
||||||
- [ ] 操作日志
|
- [ ] 用户访问日志
|
||||||
|
- [ ] 员工访问日志
|
||||||
|
- [ ] 员工操作日志
|
||||||
|
- [ ] 异常日志
|
||||||
|
|
|
@ -50,11 +50,7 @@ public class CartServiceImpl implements CartService {
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public CommonResult<Boolean> add(Integer userId, Integer skuId, Integer quantity) {
|
public CommonResult<Boolean> add(Integer userId, Integer skuId, Integer quantity) {
|
||||||
// 查询 SKU 是否合法
|
// 查询 SKU 是否合法
|
||||||
CommonResult<ProductSkuBO> skuResult = productSpuService.getProductSku(skuId);
|
ProductSkuBO sku = productSpuService.getProductSku(skuId);
|
||||||
if (skuResult.isError()) {
|
|
||||||
return CommonResult.error(skuResult);
|
|
||||||
}
|
|
||||||
ProductSkuBO sku = skuResult.getData();
|
|
||||||
if (sku == null
|
if (sku == null
|
||||||
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
||||||
|
@ -93,11 +89,7 @@ public class CartServiceImpl implements CartService {
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public CommonResult<Boolean> updateQuantity(Integer userId, Integer skuId, Integer quantity) {
|
public CommonResult<Boolean> updateQuantity(Integer userId, Integer skuId, Integer quantity) {
|
||||||
// 查询 SKU 是否合法
|
// 查询 SKU 是否合法
|
||||||
CommonResult<ProductSkuBO> skuResult = productSpuService.getProductSku(skuId);
|
ProductSkuBO sku = productSpuService.getProductSku(skuId);
|
||||||
if (skuResult.isError()) {
|
|
||||||
return CommonResult.error(skuResult);
|
|
||||||
}
|
|
||||||
ProductSkuBO sku = skuResult.getData();
|
|
||||||
if (sku == null
|
if (sku == null
|
||||||
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
||||||
|
@ -160,7 +152,7 @@ public class CartServiceImpl implements CartService {
|
||||||
// 校验商品都存在
|
// 校验商品都存在
|
||||||
Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap = calcOrderPriceDTO.getItems().stream()
|
Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap = calcOrderPriceDTO.getItems().stream()
|
||||||
.collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item)); // KEY:skuId
|
.collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item)); // KEY:skuId
|
||||||
List<ProductSkuDetailBO> skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet()).getData();
|
List<ProductSkuDetailBO> skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet());
|
||||||
if (skus.size() != calcOrderPriceDTO.getItems().size()) {
|
if (skus.size() != calcOrderPriceDTO.getItems().size()) {
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode());
|
||||||
}
|
}
|
||||||
|
@ -210,11 +202,7 @@ public class CartServiceImpl implements CartService {
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public CommonResult<CalcSkuPriceBO> calcSkuPrice(Integer skuId) {
|
public CommonResult<CalcSkuPriceBO> calcSkuPrice(Integer skuId) {
|
||||||
// 查询 SKU 是否合法
|
// 查询 SKU 是否合法
|
||||||
CommonResult<ProductSkuBO> skuResult = productSpuService.getProductSku(skuId);
|
ProductSkuBO sku = productSpuService.getProductSku(skuId);
|
||||||
if (skuResult.isError()) {
|
|
||||||
return CommonResult.error(skuResult);
|
|
||||||
}
|
|
||||||
ProductSkuBO sku = skuResult.getData();
|
|
||||||
if (sku == null
|
if (sku == null
|
||||||
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
|| CommonStatusEnum.DISABLE.getValue().equals(sku.getStatus())) { // sku 被禁用
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_SKU_NOT_FOUND.getCode());
|
||||||
|
|
|
@ -218,28 +218,20 @@ public class OrderServiceImpl implements OrderService {
|
||||||
|
|
||||||
// 获取商品信息
|
// 获取商品信息
|
||||||
Set<Integer> skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet());
|
Set<Integer> skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet());
|
||||||
CommonResult<List<ProductSkuDetailBO>> productResult = productSpuService.getProductSkuDetailList(skuIds);
|
List<ProductSkuDetailBO> productList = productSpuService.getProductSkuDetailList(skuIds);
|
||||||
|
if (orderItemDTOList.size() != productList.size()) { // 校验获得的数量,是否匹配
|
||||||
// 校验商品信息
|
|
||||||
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()) {
|
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_GOODS_INFO_INCORRECT.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_GOODS_INFO_INCORRECT.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 价格计算
|
// 价格计算
|
||||||
CommonResult<CalcOrderPriceBO> calcOrderPriceResult = calcOrderPrice(productResult.getData(), orderCreateDTO);
|
CommonResult<CalcOrderPriceBO> calcOrderPriceResult = calcOrderPrice(productList, orderCreateDTO);
|
||||||
if (calcOrderPriceResult.isError()) {
|
if (calcOrderPriceResult.isError()) {
|
||||||
return CommonResult.error(calcOrderPriceResult);
|
return CommonResult.error(calcOrderPriceResult);
|
||||||
}
|
}
|
||||||
CalcOrderPriceBO calcOrderPrice = calcOrderPriceResult.getData();
|
CalcOrderPriceBO calcOrderPrice = calcOrderPriceResult.getData();
|
||||||
|
|
||||||
// 设置 orderItem
|
// 设置 orderItem
|
||||||
Map<Integer, ProductSkuDetailBO> productSpuBOMap = productResult.getData()
|
Map<Integer, ProductSkuDetailBO> productSpuBOMap = productList
|
||||||
.stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合
|
.stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合
|
||||||
Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>();
|
Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>();
|
||||||
calcOrderPrice.getItemGroups().forEach(itemGroup ->
|
calcOrderPrice.getItemGroups().forEach(itemGroup ->
|
||||||
|
|
|
@ -2,15 +2,22 @@ package cn.iocoder.mall.product.application.config;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.config.GlobalExceptionHandler;
|
import cn.iocoder.common.framework.config.GlobalExceptionHandler;
|
||||||
import cn.iocoder.common.framework.servlet.CorsFilter;
|
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.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
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
|
@EnableWebMvc
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import(value = {GlobalExceptionHandler.class}) // 统一全局返回
|
@Import(value = {GlobalExceptionHandler.class, // 统一全局返回
|
||||||
|
AdminSecurityInterceptor.class, AdminAccessLogInterceptor.class})
|
||||||
public class MVCConfiguration implements WebMvcConfigurer {
|
public class MVCConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
// @Autowired
|
// @Autowired
|
||||||
|
@ -19,9 +26,16 @@ public class MVCConfiguration implements WebMvcConfigurer {
|
||||||
// @Reference
|
// @Reference
|
||||||
// private OAuth2Service oauth2Service;
|
// private OAuth2Service oauth2Service;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AdminSecurityInterceptor adminSecurityInterceptor;
|
||||||
|
@Autowired
|
||||||
|
private AdminAccessLogInterceptor adminAccessLogInterceptor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
// registry.addInterceptor(securityInterceptor);
|
// registry.addInterceptor(securityInterceptor);
|
||||||
|
registry.addInterceptor(adminAccessLogInterceptor).addPathPatterns("/admins/**");
|
||||||
|
registry.addInterceptor(adminSecurityInterceptor).addPathPatterns("/admins/**");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import static cn.iocoder.common.framework.vo.CommonResult.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("admins")
|
@RequestMapping("admins")
|
||||||
|
@ -40,18 +41,18 @@ public class AdminsProductAttrController {
|
||||||
// 创建 ProductAttrPageDTO 对象
|
// 创建 ProductAttrPageDTO 对象
|
||||||
ProductAttrPageDTO productAttrPageDTO = new ProductAttrPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize);
|
ProductAttrPageDTO productAttrPageDTO = new ProductAttrPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize);
|
||||||
// 查询分页
|
// 查询分页
|
||||||
CommonResult<ProductAttrPageBO> result = productAttrService.getProductAttrPage(productAttrPageDTO);
|
ProductAttrPageBO result = productAttrService.getProductAttrPage(productAttrPageDTO);
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return ProductAttrConvert.INSTANCE.convert2(result);
|
return success(ProductAttrConvert.INSTANCE.convert2(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/attr/tree")
|
@GetMapping("/attr/tree")
|
||||||
@ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
@ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
||||||
public CommonResult<List<AdminsProductAttrSimpleVO>> tree() {
|
public CommonResult<List<AdminsProductAttrSimpleVO>> tree() {
|
||||||
// 查询全列表
|
// 查询全列表
|
||||||
CommonResult<List<ProductAttrSimpleBO>> result = productAttrService.getProductAttrList();
|
List<ProductAttrSimpleBO> result = productAttrService.getProductAttrList();
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return ProductAttrConvert.INSTANCE.convert(result);
|
return success(ProductAttrConvert.INSTANCE.convert(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/attr/add")
|
@PostMapping("/attr/add")
|
||||||
|
@ -63,9 +64,9 @@ public class AdminsProductAttrController {
|
||||||
// 创建 ProductAttrAddDTO 对象
|
// 创建 ProductAttrAddDTO 对象
|
||||||
ProductAttrAddDTO productAttrAddDTO = new ProductAttrAddDTO().setName(name);
|
ProductAttrAddDTO productAttrAddDTO = new ProductAttrAddDTO().setName(name);
|
||||||
// 添加
|
// 添加
|
||||||
CommonResult<ProductAttrBO> 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")
|
@PostMapping("/attr/update")
|
||||||
|
@ -79,7 +80,7 @@ public class AdminsProductAttrController {
|
||||||
// 创建 ProductAttrUpdateDTO 对象
|
// 创建 ProductAttrUpdateDTO 对象
|
||||||
ProductAttrUpdateDTO productAttrUpdateDTO = new ProductAttrUpdateDTO().setId(id).setName(name);
|
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")
|
@PostMapping("/attr/update_status")
|
||||||
|
@ -90,7 +91,7 @@ public class AdminsProductAttrController {
|
||||||
})
|
})
|
||||||
public CommonResult<Boolean> updateAttrStatus(@RequestParam("id") Integer id,
|
public CommonResult<Boolean> updateAttrStatus(@RequestParam("id") Integer id,
|
||||||
@RequestParam("status") Integer status) {
|
@RequestParam("status") Integer status) {
|
||||||
return productAttrService.updateProductAttrStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status);
|
return success(productAttrService.updateProductAttrStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿 暂时不考虑 delete Attr 。因为关联逻辑比较多
|
// TODO 芋艿 暂时不考虑 delete Attr 。因为关联逻辑比较多
|
||||||
|
@ -106,9 +107,9 @@ public class AdminsProductAttrController {
|
||||||
// 创建 ProductAttrValueAddDTO 对象
|
// 创建 ProductAttrValueAddDTO 对象
|
||||||
ProductAttrValueAddDTO productAttrValueAddDTO = new ProductAttrValueAddDTO().setAttrId(attrId).setName(name);
|
ProductAttrValueAddDTO productAttrValueAddDTO = new ProductAttrValueAddDTO().setAttrId(attrId).setName(name);
|
||||||
// 添加
|
// 添加
|
||||||
CommonResult<ProductAttrValueBO> 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")
|
@PostMapping("/attr_value/update")
|
||||||
|
@ -122,7 +123,7 @@ public class AdminsProductAttrController {
|
||||||
// 创建 ProductAttrValueUpdateDTO 对象
|
// 创建 ProductAttrValueUpdateDTO 对象
|
||||||
ProductAttrValueUpdateDTO productAttrValueUpdateDTO = new ProductAttrValueUpdateDTO().setId(id).setName(name);
|
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")
|
@PostMapping("/attr_value/update_status")
|
||||||
|
@ -132,7 +133,7 @@ public class AdminsProductAttrController {
|
||||||
})
|
})
|
||||||
public CommonResult<Boolean> updateAttrValueStatus(@RequestParam("id") Integer id,
|
public CommonResult<Boolean> updateAttrValueStatus(@RequestParam("id") Integer id,
|
||||||
@RequestParam("status") Integer status) {
|
@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 。因为关联逻辑比较多
|
// TODO 芋艿 暂时不考虑 delete Attr Value 。因为关联逻辑比较多
|
||||||
|
|
|
@ -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.convert.ProductCategoryConvert;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO;
|
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryVO;
|
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.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.dubbo.config.annotation.Reference;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("admins/category")
|
@RequestMapping("admins/category")
|
||||||
@Api("商品分类")
|
@Api("商品分类")
|
||||||
|
@ -36,7 +38,7 @@ public class AdminsProductCategoryController {
|
||||||
@GetMapping("/tree")
|
@GetMapping("/tree")
|
||||||
@ApiOperation("获得分类树结构")
|
@ApiOperation("获得分类树结构")
|
||||||
public CommonResult<List<AdminsProductCategoryTreeNodeVO>> tree() {
|
public CommonResult<List<AdminsProductCategoryTreeNodeVO>> tree() {
|
||||||
List<ProductCategoryBO> productCategories = productCategoryService.getAll().getData();
|
List<ProductCategoryBO> productCategories = productCategoryService.getAll();
|
||||||
// 创建 ProductCategoryTreeNodeVO Map
|
// 创建 ProductCategoryTreeNodeVO Map
|
||||||
Map<Integer, AdminsProductCategoryTreeNodeVO> treeNodeMap = productCategories.stream().collect(Collectors.toMap(ProductCategoryBO::getId, ProductCategoryConvert.Admins.INSTANCE::convert));
|
Map<Integer, AdminsProductCategoryTreeNodeVO> 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))
|
.filter(node -> node.getPid().equals(ProductCategoryConstants.PID_ROOT))
|
||||||
.sorted(Comparator.comparing(AdminsProductCategoryTreeNodeVO::getSort))
|
.sorted(Comparator.comparing(AdminsProductCategoryTreeNodeVO::getSort))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return CommonResult.success(rootNodes);
|
return success(rootNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
|
@ -77,9 +79,9 @@ public class AdminsProductCategoryController {
|
||||||
ProductCategoryAddDTO productCategoryAddDTO = new ProductCategoryAddDTO().setPid(pid).setName(name)
|
ProductCategoryAddDTO productCategoryAddDTO = new ProductCategoryAddDTO().setPid(pid).setName(name)
|
||||||
.setDescription(description).setPicUrl(picUrl).setSort(sort);
|
.setDescription(description).setPicUrl(picUrl).setSort(sort);
|
||||||
// 创建商品分类
|
// 创建商品分类
|
||||||
CommonResult<ProductCategoryBO> 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")
|
@PostMapping("/update")
|
||||||
|
@ -102,7 +104,7 @@ public class AdminsProductCategoryController {
|
||||||
ProductCategoryUpdateDTO productCategoryAddDTO = new ProductCategoryUpdateDTO().setId(id).setPid(pid).setName(name)
|
ProductCategoryUpdateDTO productCategoryAddDTO = new ProductCategoryUpdateDTO().setId(id).setPid(pid).setName(name)
|
||||||
.setDescription(description).setPicUrl(picUrl).setSort(sort);
|
.setDescription(description).setPicUrl(picUrl).setSort(sort);
|
||||||
// 更新商品分类
|
// 更新商品分类
|
||||||
return productCategoryService.updateProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO);
|
return success(productCategoryService.updateProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), productCategoryAddDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/update_status")
|
@PostMapping("/update_status")
|
||||||
|
@ -113,14 +115,14 @@ public class AdminsProductCategoryController {
|
||||||
})
|
})
|
||||||
public CommonResult<Boolean> updateStatus(@RequestParam("id") Integer id,
|
public CommonResult<Boolean> updateStatus(@RequestParam("id") Integer id,
|
||||||
@RequestParam("status") Integer status) {
|
@RequestParam("status") Integer status) {
|
||||||
return productCategoryService.updateProductCategoryStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status);
|
return success(productCategoryService.updateProductCategoryStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
@ApiOperation(value = "删除商品分类")
|
@ApiOperation(value = "删除商品分类")
|
||||||
@ApiImplicitParam(name = "id", value = "商品分类编号", required = true, example = "1")
|
@ApiImplicitParam(name = "id", value = "商品分类编号", required = true, example = "1")
|
||||||
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
||||||
return productCategoryService.deleteProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), id);
|
return success(productCategoryService.deleteProductCategory(AdminSecurityContextHolder.getContext().getAdminId(), id));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.convert.ProductSpuConvert;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuPageVO;
|
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.JavaType;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.dubbo.config.annotation.Reference;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("admins")
|
@RequestMapping("admins")
|
||||||
@Api("商品 SPU + SKU")
|
@Api("商品 SPU + SKU")
|
||||||
|
@ -47,7 +49,6 @@ public class AdminsProductSpuController {
|
||||||
@ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"),
|
@ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"),
|
||||||
@ApiImplicitParam(name = "visible", value = "是否上架商品(是否可见)", required = true, example = "true"),
|
@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\"}]"),
|
@ApiImplicitParam(name = "skuStr", value = "SKU 字符串", required = true, example = "[{\"attrs\": [1,3 ], \"price\": 1, \"quantity\": 100, \"picUrl\": \"http://www.iocoder.cn\"}]"),
|
||||||
|
|
||||||
})
|
})
|
||||||
public CommonResult<AdminsProductSpuDetailVO> add(@RequestParam("name") String name,
|
public CommonResult<AdminsProductSpuDetailVO> add(@RequestParam("name") String name,
|
||||||
@RequestParam("sellPoint") String sellPoint,
|
@RequestParam("sellPoint") String sellPoint,
|
||||||
|
@ -61,9 +62,9 @@ public class AdminsProductSpuController {
|
||||||
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
|
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
|
||||||
.setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class));
|
.setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class));
|
||||||
// 保存商品
|
// 保存商品
|
||||||
CommonResult<ProductSpuDetailBO> 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")
|
@PostMapping("/spu/update")
|
||||||
|
@ -77,7 +78,6 @@ public class AdminsProductSpuController {
|
||||||
@ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"),
|
@ApiImplicitParam(name = "picUrls", value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn"),
|
||||||
@ApiImplicitParam(name = "visible", value = "是否上架商品(是否可见)", required = true, example = "true"),
|
@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\"}]"),
|
@ApiImplicitParam(name = "skuStr", value = "SKU 字符串", required = true, example = "[{\"attrs\": [1,3 ], \"price\": 1, \"quantity\": 100, \"picUrl\": \"http://www.iocoder.cn\"}]"),
|
||||||
|
|
||||||
})
|
})
|
||||||
public CommonResult<Boolean> update(@RequestParam("id") Integer id,
|
public CommonResult<Boolean> update(@RequestParam("id") Integer id,
|
||||||
@RequestParam("name") String name,
|
@RequestParam("name") String name,
|
||||||
|
@ -92,14 +92,15 @@ public class AdminsProductSpuController {
|
||||||
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
|
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
|
||||||
.setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class));
|
.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")
|
@PostMapping("/spu/update_sort")
|
||||||
@ApiOperation("更新商品的排序")
|
@ApiOperation("更新商品的排序")
|
||||||
public CommonResult<Boolean> updateSort(@RequestParam("id") Integer id,
|
public CommonResult<Boolean> updateSort(@RequestParam("id") Integer id,
|
||||||
@RequestParam("sort") Integer sort) {
|
@RequestParam("sort") Integer sort) {
|
||||||
return productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort);
|
return success(productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿,删除功能暂时不做。主要原因是,关联的数据太多。删除带来的问题会比较大
|
// TODO 芋艿,删除功能暂时不做。主要原因是,关联的数据太多。删除带来的问题会比较大
|
||||||
|
@ -109,22 +110,37 @@ public class AdminsProductSpuController {
|
||||||
@ApiImplicitParams({
|
@ApiImplicitParams({
|
||||||
@ApiImplicitParam(name = "name", value = "商品名称,模糊匹配", example = "小王"),
|
@ApiImplicitParam(name = "name", value = "商品名称,模糊匹配", example = "小王"),
|
||||||
@ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
|
@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"),
|
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
|
||||||
})
|
})
|
||||||
public CommonResult<AdminsProductSpuPageVO> spuPage(@RequestParam(value = "name", required = false) String name,
|
public CommonResult<AdminsProductSpuPageVO> 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 = "pageNo", defaultValue = "0") Integer pageNo,
|
||||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||||
// 创建 ProductSpuPageDTO 对象
|
// 创建 ProductSpuPageDTO 对象
|
||||||
ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize);
|
ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setName(name).setCid(cid).setPageNo(pageNo).setPageSize(pageSize);
|
||||||
CommonResult<ProductSpuPageBO> result = productSpuService.getProductSpuPage(productSpuPageDTO);
|
switch (status) {
|
||||||
return ProductSpuConvert.INSTANCE.convert2(result);
|
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")
|
@GetMapping("/spu/info")
|
||||||
@ApiOperation("商品 SPU 明细")
|
@ApiOperation("商品 SPU 明细")
|
||||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||||
public CommonResult<AdminsProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
public CommonResult<AdminsProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||||
return ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id));
|
return success(ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> List<T> parseSkus(String skuStr, Class<T> clazz) {
|
private <T> List<T> parseSkus(String skuStr, Class<T> clazz) {
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("users/spu")
|
@RequestMapping("users/spu")
|
||||||
@Api("商品 SPU + SKU")
|
@Api("商品 SPU + SKU")
|
||||||
|
@ -33,7 +35,7 @@ public class UsersProductSpuController {
|
||||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||||
return ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id));
|
return success(ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
|
@ -52,9 +54,9 @@ public class UsersProductSpuController {
|
||||||
ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setCid(cid).setVisible(true)
|
ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setCid(cid).setVisible(true)
|
||||||
.setPageNo(pageNo).setPageSize(pageSize);
|
.setPageNo(pageNo).setPageSize(pageSize);
|
||||||
// 查询分页
|
// 查询分页
|
||||||
CommonResult<ProductSpuPageBO> result = productSpuService.getProductSpuPage(productSpuPageDTO);
|
ProductSpuPageBO result = productSpuService.getProductSpuPage(productSpuPageDTO);
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return ProductSpuConvert.INSTANCE.convert3(result);
|
return success(ProductSpuConvert.INSTANCE.convert3(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.product.application.convert;
|
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.ProductAttrBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
||||||
|
@ -21,18 +20,15 @@ public interface ProductAttrConvert {
|
||||||
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
|
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<AdminsProductAttrPageVO> convert2(CommonResult<ProductAttrPageBO> result);
|
AdminsProductAttrPageVO convert2(ProductAttrPageBO result);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<List<AdminsProductAttrSimpleVO>> convert(CommonResult<List<ProductAttrSimpleBO>> result);
|
List<AdminsProductAttrSimpleVO> convert(List<ProductAttrSimpleBO> result);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
AdminsProductAttrVO convert3(ProductAttrBO productAttrBO);
|
AdminsProductAttrVO convert3(ProductAttrBO productAttrBO);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<AdminsProductAttrVO> convert3(CommonResult<ProductAttrBO> productAttrBO);
|
AdminsProductAttrValueVO convert4(ProductAttrValueBO productAttrValueBO);
|
||||||
|
|
||||||
@Mappings({})
|
}
|
||||||
CommonResult<AdminsProductAttrValueVO> convert4(CommonResult<ProductAttrValueBO> productAttrValueBO);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.product.application.convert;
|
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.api.bo.ProductCategoryBO;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO;
|
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryTreeNodeVO;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryVO;
|
import cn.iocoder.mall.product.application.vo.admins.AdminsProductCategoryVO;
|
||||||
|
@ -35,7 +34,7 @@ public interface ProductCategoryConvert {
|
||||||
AdminsProductCategoryTreeNodeVO convert(ProductCategoryBO category);
|
AdminsProductCategoryTreeNodeVO convert(ProductCategoryBO category);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<AdminsProductCategoryVO> convert2(CommonResult<ProductCategoryBO> result);
|
AdminsProductCategoryVO convert2(ProductCategoryBO result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.product.application.convert;
|
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.ProductSpuDetailBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
||||||
|
@ -19,16 +18,16 @@ public interface ProductSpuConvert {
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
AdminsProductSpuDetailVO convert(ProductSpuDetailBO productSpuDetailBO);
|
AdminsProductSpuDetailVO convert(ProductSpuDetailBO productSpuDetailBO);
|
||||||
|
|
||||||
@Mappings({})
|
// @Mappings({})
|
||||||
CommonResult<AdminsProductSpuDetailVO> convert(CommonResult<ProductSpuDetailBO> result);
|
// CommonResult<AdminsProductSpuDetailVO> convert(CommonResult<ProductSpuDetailBO> result);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<AdminsProductSpuPageVO> convert2(CommonResult<ProductSpuPageBO> result);
|
AdminsProductSpuPageVO convert2(ProductSpuPageBO result);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<UsersProductSpuPageVO> convert3(CommonResult<ProductSpuPageBO> result);
|
UsersProductSpuPageVO convert3(ProductSpuPageBO result);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
CommonResult<UsersProductSpuDetailVO> convert4(CommonResult<ProductSpuDetailBO> result);
|
UsersProductSpuDetailVO convert4(ProductSpuDetailBO result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ import java.util.List;
|
||||||
public class AdminsProductSpuPageVO {
|
public class AdminsProductSpuPageVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "spu 数组", required = true)
|
@ApiModelProperty(value = "spu 数组", required = true)
|
||||||
private List<AdminsProductSpuVO> spus;
|
private List<AdminsProductSpuVO> list;
|
||||||
@ApiModelProperty(value = "总数", required = true)
|
@ApiModelProperty(value = "总数", required = true)
|
||||||
private Integer count;
|
private Integer total;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.mall.product.api;
|
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.ProductAttrBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
||||||
|
@ -11,7 +12,7 @@ import java.util.List;
|
||||||
|
|
||||||
public interface ProductAttrService {
|
public interface ProductAttrService {
|
||||||
|
|
||||||
CommonResult<ProductAttrPageBO> getProductAttrPage(ProductAttrPageDTO productAttrPageDTO);
|
ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得规格属性数组
|
* 获得规格属性数组
|
||||||
|
@ -20,19 +21,20 @@ public interface ProductAttrService {
|
||||||
*
|
*
|
||||||
* @return 规格属性数组
|
* @return 规格属性数组
|
||||||
*/
|
*/
|
||||||
CommonResult<List<ProductAttrSimpleBO>> getProductAttrList();
|
List<ProductAttrSimpleBO> getProductAttrList();
|
||||||
|
|
||||||
CommonResult<ProductAttrBO> addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO);
|
ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO);
|
Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> 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<ProductAttrValueBO> addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO);
|
Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
|
Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId,
|
||||||
|
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status);
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.mall.product.api;
|
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.bo.ProductCategoryBO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductCategoryAddDTO;
|
import cn.iocoder.mall.product.api.dto.ProductCategoryAddDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductCategoryUpdateDTO;
|
import cn.iocoder.mall.product.api.dto.ProductCategoryUpdateDTO;
|
||||||
|
@ -27,14 +28,15 @@ public interface ProductCategoryService {
|
||||||
/**
|
/**
|
||||||
* @return 返回所有产品分类们
|
* @return 返回所有产品分类们
|
||||||
*/
|
*/
|
||||||
CommonResult<List<ProductCategoryBO>> getAll();
|
List<ProductCategoryBO> getAll();
|
||||||
|
|
||||||
CommonResult<ProductCategoryBO> addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO);
|
ProductCategoryBO addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO);
|
Boolean updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status);
|
Boolean updateProductCategoryStatus(Integer adminId, Integer productCategoryId,
|
||||||
|
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status);
|
||||||
|
|
||||||
CommonResult<Boolean> deleteProductCategory(Integer admin, Integer productCategoryId);
|
Boolean deleteProductCategory(Integer admin, Integer productCategoryId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.product.api;
|
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.bo.*;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
||||||
|
@ -11,7 +10,7 @@ import java.util.List;
|
||||||
|
|
||||||
public interface ProductSpuService {
|
public interface ProductSpuService {
|
||||||
|
|
||||||
CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id);
|
ProductSpuDetailBO getProductSpuDetail(Integer id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增量获得商品列表,按照 lastId 递增获得
|
* 增量获得商品列表,按照 lastId 递增获得
|
||||||
|
@ -20,20 +19,20 @@ public interface ProductSpuService {
|
||||||
* @param limit 大小
|
* @param limit 大小
|
||||||
* @return 商品列表
|
* @return 商品列表
|
||||||
*/
|
*/
|
||||||
CommonResult<List<ProductSpuDetailBO>> getProductSpuDetailListForSync(Integer lastId, Integer limit);
|
List<ProductSpuDetailBO> getProductSpuDetailListForSync(Integer lastId, Integer limit);
|
||||||
|
|
||||||
CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
||||||
|
|
||||||
CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids);
|
List<ProductSpuBO> getProductSpuList(Collection<Integer> ids);
|
||||||
|
|
||||||
CommonResult<ProductSkuBO> getProductSku(Integer id);
|
ProductSkuBO getProductSku(Integer id);
|
||||||
|
|
||||||
CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids);
|
List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids);
|
||||||
|
|
||||||
CommonResult<ProductSpuDetailBO> addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
|
ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
|
void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
|
||||||
|
|
||||||
CommonResult<Boolean> updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@ public class ProductSpuPageBO implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Spu 数组
|
* Spu 数组
|
||||||
*/
|
*/
|
||||||
private List<ProductSpuBO> spus;
|
private List<ProductSpuBO> list;
|
||||||
/**
|
/**
|
||||||
* 总量
|
* 总量
|
||||||
*/
|
*/
|
||||||
private Integer count;
|
private Integer total;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,12 @@ public class ProductSpuPageDTO {
|
||||||
* 是否可见
|
* 是否可见
|
||||||
*/
|
*/
|
||||||
private Boolean visible;
|
private Boolean visible;
|
||||||
|
/**
|
||||||
|
* 是否有库存
|
||||||
|
*
|
||||||
|
* 允许为空。空时,不进行筛选
|
||||||
|
*/
|
||||||
|
private Boolean hasQuantity;
|
||||||
|
|
||||||
@NotNull(message = "页码不能为空")
|
@NotNull(message = "页码不能为空")
|
||||||
private Integer pageNo;
|
private Integer pageNo;
|
||||||
|
|
|
@ -32,11 +32,13 @@ public interface ProductSpuMapper {
|
||||||
List<ProductSpuDO> selectListByNameLikeOrderBySortAsc(@Param("name") String name,
|
List<ProductSpuDO> selectListByNameLikeOrderBySortAsc(@Param("name") String name,
|
||||||
@Param("cid") Integer cid,
|
@Param("cid") Integer cid,
|
||||||
@Param("visible") Boolean visible,
|
@Param("visible") Boolean visible,
|
||||||
|
@Param("hasQuantity") Boolean hasQuantity,
|
||||||
@Param("offset") Integer offset,
|
@Param("offset") Integer offset,
|
||||||
@Param("limit") Integer limit);
|
@Param("limit") Integer limit);
|
||||||
|
|
||||||
Integer selectCountByNameLike(@Param("name") String name,
|
Integer selectCountByNameLike(@Param("name") String name,
|
||||||
@Param("cid") Integer cid,
|
@Param("cid") Integer cid,
|
||||||
|
@Param("hasQuantity") Boolean hasQuantity,
|
||||||
@Param("visible") Boolean visible);
|
@Param("visible") Boolean visible);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package cn.iocoder.mall.product.service;
|
package cn.iocoder.mall.product.service;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
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.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
|
||||||
import cn.iocoder.mall.product.api.ProductAttrService;
|
import cn.iocoder.mall.product.api.ProductAttrService;
|
||||||
import cn.iocoder.mall.product.api.bo.*;
|
import cn.iocoder.mall.product.api.bo.*;
|
||||||
import cn.iocoder.mall.product.api.constant.ProductAttrConstants;
|
import cn.iocoder.mall.product.api.constant.ProductAttrConstants;
|
||||||
|
@ -37,16 +35,16 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ProductAttrValueMapper productAttrValueMapper;
|
private ProductAttrValueMapper productAttrValueMapper;
|
||||||
|
|
||||||
public CommonResult<List<ProductAttrAndValuePairBO>> validProductAttrAndValue(Set<Integer> productAttrValueIds, boolean validStatus) {
|
public List<ProductAttrAndValuePairBO> validProductAttrAndValue(Set<Integer> productAttrValueIds, boolean validStatus) {
|
||||||
// 首先,校验规格值
|
// 首先,校验规格值
|
||||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectListByIds(productAttrValueIds);
|
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectListByIds(productAttrValueIds);
|
||||||
if (attrValues.size() != productAttrValueIds.size()) {
|
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) {
|
if (validStatus) {
|
||||||
for (ProductAttrValueDO attrValue : attrValues) { // 同时,校验下状态
|
for (ProductAttrValueDO attrValue : attrValues) { // 同时,校验下状态
|
||||||
if (ProductAttrConstants.ATTR_STATUS_DISABLE.equals(attrValue.getStatus())) {
|
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<Integer> attrIds = attrValues.stream().map(ProductAttrValueDO::getAttrId).collect(Collectors.toSet());
|
Set<Integer> attrIds = attrValues.stream().map(ProductAttrValueDO::getAttrId).collect(Collectors.toSet());
|
||||||
List<ProductAttrDO> attrs = productAttrMapper.selectListByIds(attrIds);
|
List<ProductAttrDO> attrs = productAttrMapper.selectListByIds(attrIds);
|
||||||
if (attrs.size() != attrIds.size()) {
|
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) {
|
if (validStatus) {
|
||||||
for (ProductAttrDO attr : attrs) { // 同时,校验下状态
|
for (ProductAttrDO attr : attrs) { // 同时,校验下状态
|
||||||
if (ProductAttrConstants.ATTR_VALUE_STATUS_DISABLE.equals(attr.getStatus())) {
|
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<Integer, ProductAttrDO> attrMap = attrs.stream().collect(Collectors.toMap(ProductAttrDO::getId, productAttrDO -> productAttrDO)); // ProductAttrDO 的映射,方便查找。
|
Map<Integer, ProductAttrDO> attrMap = attrs.stream().collect(Collectors.toMap(ProductAttrDO::getId, productAttrDO -> productAttrDO)); // ProductAttrDO 的映射,方便查找。
|
||||||
List<ProductAttrAndValuePairBO> result = attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO()
|
return attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO()
|
||||||
.setAttrId(productAttrValueDO.getAttrId()).setAttrName(attrMap.get(productAttrValueDO.getAttrId()).getName())
|
.setAttrId(productAttrValueDO.getAttrId()).setAttrName(attrMap.get(productAttrValueDO.getAttrId()).getName())
|
||||||
.setAttrValueId(productAttrValueDO.getId()).setAttrValueName(productAttrValueDO.getName())).collect(Collectors.toList());
|
.setAttrValueId(productAttrValueDO.getId()).setAttrValueName(productAttrValueDO.getName())).collect(Collectors.toList());
|
||||||
return CommonResult.success(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductAttrPageBO> getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) {
|
public ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) {
|
||||||
ProductAttrPageBO productAttrPageBO = new ProductAttrPageBO();
|
ProductAttrPageBO productAttrPageBO = new ProductAttrPageBO();
|
||||||
// 查询分页数据
|
// 查询分页数据
|
||||||
int offset = productAttrPageDTO.getPageNo() * productAttrPageDTO.getPageSize();
|
int offset = productAttrPageDTO.getPageNo() * productAttrPageDTO.getPageSize();
|
||||||
|
@ -90,16 +87,16 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return CommonResult.success(productAttrPageBO);
|
return productAttrPageBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<List<ProductAttrSimpleBO>> getProductAttrList() {
|
public List<ProductAttrSimpleBO> getProductAttrList() {
|
||||||
// 查询所有开启的规格数组
|
// 查询所有开启的规格数组
|
||||||
List<ProductAttrSimpleBO> attrs = ProductAttrConvert.INSTANCE.convert3(productAttrMapper.selectListByStatus(ProductAttrConstants.ATTR_STATUS_ENABLE));
|
List<ProductAttrSimpleBO> attrs = ProductAttrConvert.INSTANCE.convert3(productAttrMapper.selectListByStatus(ProductAttrConstants.ATTR_STATUS_ENABLE));
|
||||||
// 如果为空,则返回空
|
// 如果为空,则返回空
|
||||||
if (attrs.isEmpty()) {
|
if (attrs.isEmpty()) {
|
||||||
return CommonResult.success(Collections.emptyList());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 将规格值拼接上去
|
// 将规格值拼接上去
|
||||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectListByStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE);
|
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectListByStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE);
|
||||||
|
@ -107,14 +104,14 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
||||||
for (ProductAttrSimpleBO productAttrSimpleBO : attrs) {
|
for (ProductAttrSimpleBO productAttrSimpleBO : attrs) {
|
||||||
productAttrSimpleBO.setValues(ProductAttrConvert.INSTANCE.convert4(((attrValueMap).get(productAttrSimpleBO.getId()))));
|
productAttrSimpleBO.setValues(ProductAttrConvert.INSTANCE.convert4(((attrValueMap).get(productAttrSimpleBO.getId()))));
|
||||||
}
|
}
|
||||||
return CommonResult.success(attrs);
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductAttrBO> addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) {
|
public ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) {
|
||||||
// 校验规格名不重复
|
// 校验规格名不重复
|
||||||
if (productAttrMapper.selectByName(productAttrAddDTO.getName()) != null) {
|
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)
|
ProductAttrDO productAttrDO = ProductAttrConvert.INSTANCE.convert(productAttrAddDTO)
|
||||||
|
@ -123,54 +120,50 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
||||||
productAttrDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
productAttrDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
productAttrMapper.insert(productAttrDO);
|
productAttrMapper.insert(productAttrDO);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductAttrConvert.INSTANCE.convert(productAttrDO));
|
return ProductAttrConvert.INSTANCE.convert(productAttrDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) {
|
public Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
if (productAttrMapper.selectById(productAttrUpdateDTO.getId()) == null) {
|
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());
|
ProductAttrDO existsAttrDO = productAttrMapper.selectByName(productAttrUpdateDTO.getName());
|
||||||
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrUpdateDTO.getId())) {
|
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);
|
ProductAttrDO updateProductAttr = ProductAttrConvert.INSTANCE.convert(productAttrUpdateDTO);
|
||||||
productAttrMapper.update(updateProductAttr);
|
productAttrMapper.update(updateProductAttr);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) {
|
public Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) {
|
||||||
// 校验参数
|
|
||||||
if (!isValidAttrStatus(status)) {
|
|
||||||
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓
|
|
||||||
}
|
|
||||||
// 校验存在
|
// 校验存在
|
||||||
ProductAttrDO productAttrDO = productAttrMapper.selectById(productAttrId);
|
ProductAttrDO productAttrDO = productAttrMapper.selectById(productAttrId);
|
||||||
if (productAttrDO == null) {
|
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)) {
|
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);
|
ProductAttrDO updateProductAttr = new ProductAttrDO().setId(productAttrId).setStatus(status);
|
||||||
productAttrMapper.update(updateProductAttr);
|
productAttrMapper.update(updateProductAttr);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductAttrValueBO> addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) {
|
public ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) {
|
||||||
// 校验规格名不重复
|
// 校验规格名不重复
|
||||||
if (productAttrValueMapper.selectByAttrIdAndName(productAttrValueAddDTO.getAttrId(), productAttrValueAddDTO.getName()) != null) {
|
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)
|
ProductAttrValueDO productAttrValueDO = ProductAttrConvert.INSTANCE.convert(productAttrValueAddDTO)
|
||||||
|
@ -179,58 +172,44 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
||||||
productAttrValueDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
productAttrValueDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
productAttrValueMapper.insert(productAttrValueDO);
|
productAttrValueMapper.insert(productAttrValueDO);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductAttrConvert.INSTANCE.convert2(productAttrValueDO));
|
return ProductAttrConvert.INSTANCE.convert2(productAttrValueDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) {
|
public Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueUpdateDTO.getId());
|
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueUpdateDTO.getId());
|
||||||
if (productAttrValueDO == null) {
|
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());
|
ProductAttrValueDO existsAttrDO = productAttrValueMapper.selectByAttrIdAndName(productAttrValueDO.getAttrId(), productAttrValueUpdateDTO.getName());
|
||||||
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrValueUpdateDTO.getId())) {
|
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);
|
ProductAttrValueDO updateProductValue = ProductAttrConvert.INSTANCE.convert(productAttrValueUpdateDTO);
|
||||||
productAttrValueMapper.update(updateProductValue);
|
productAttrValueMapper.update(updateProductValue);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) {
|
public Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) {
|
||||||
// 校验参数
|
|
||||||
if (!isValidAttrValueStatus(status)) {
|
|
||||||
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓
|
|
||||||
}
|
|
||||||
// 校验存在
|
// 校验存在
|
||||||
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueId);
|
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueId);
|
||||||
if (productAttrValueDO == null) {
|
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)) {
|
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);
|
ProductAttrValueDO updateProductAttrValue = new ProductAttrValueDO().setId(productAttrValueId).setStatus(status);
|
||||||
productAttrValueMapper.update(updateProductAttrValue);
|
productAttrValueMapper.update(updateProductAttrValue);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(true);
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package cn.iocoder.mall.product.service;
|
package cn.iocoder.mall.product.service;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
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.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
|
||||||
import cn.iocoder.mall.product.api.ProductCategoryService;
|
import cn.iocoder.mall.product.api.ProductCategoryService;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
|
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
|
||||||
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;
|
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;
|
||||||
|
@ -40,13 +38,13 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<List<ProductCategoryBO>> getAll() {
|
public List<ProductCategoryBO> getAll() {
|
||||||
List<ProductCategoryDO> categoryList = productCategoryMapper.selectList();
|
List<ProductCategoryDO> categoryList = productCategoryMapper.selectList();
|
||||||
return CommonResult.success(ProductCategoryConvert.INSTANCE.convertToBO(categoryList));
|
return ProductCategoryConvert.INSTANCE.convertToBO(categoryList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductCategoryBO> addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) {
|
public ProductCategoryBO addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) {
|
||||||
// 校验父分类
|
// 校验父分类
|
||||||
validParent(productCategoryAddDTO.getPid());
|
validParent(productCategoryAddDTO.getPid());
|
||||||
// 保存到数据库
|
// 保存到数据库
|
||||||
|
@ -57,62 +55,58 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||||
productCategoryMapper.insert(productCategory);
|
productCategoryMapper.insert(productCategory);
|
||||||
// TODO 操作日志
|
// TODO 操作日志
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductCategoryConvert.INSTANCE.convertToBO(productCategory));
|
return ProductCategoryConvert.INSTANCE.convertToBO(productCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) {
|
public Boolean updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) {
|
||||||
// 校验父分类
|
// 校验父分类
|
||||||
validParent(productCategoryUpdateDTO.getPid());
|
validParent(productCategoryUpdateDTO.getPid());
|
||||||
// 校验不能设置自己为父分类
|
// 校验不能设置自己为父分类
|
||||||
if (productCategoryUpdateDTO.getId().equals(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())
|
if (!ProductCategoryConstants.PID_ROOT.equals(productCategoryUpdateDTO.getPid())
|
||||||
&& productCategoryMapper.selectById(productCategoryUpdateDTO.getPid()) == null) {
|
&& 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);
|
ProductCategoryDO updateProductCategory = ProductCategoryConvert.INSTANCE.convert(productCategoryUpdateDTO);
|
||||||
productCategoryMapper.update(updateProductCategory);
|
productCategoryMapper.update(updateProductCategory);
|
||||||
// TODO 操作日志
|
// TODO 操作日志
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status) {
|
public Boolean updateProductCategoryStatus(Integer adminId, Integer productCategoryId, Integer status) {
|
||||||
// 校验参数
|
|
||||||
if (!isValidStatus(status)) {
|
|
||||||
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓
|
|
||||||
}
|
|
||||||
// 校验分类是否存在
|
// 校验分类是否存在
|
||||||
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
||||||
if (productCategory == null) {
|
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)) {
|
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()
|
ProductCategoryDO updateProductCategory = new ProductCategoryDO()
|
||||||
.setId(productCategoryId).setStatus(status);
|
.setId(productCategoryId).setStatus(status);
|
||||||
productCategoryMapper.update(updateProductCategory);
|
productCategoryMapper.update(updateProductCategory);
|
||||||
// TODO 操作日志
|
// TODO 操作日志
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> deleteProductCategory(Integer admin, Integer productCategoryId) {
|
public Boolean deleteProductCategory(Integer admin, Integer productCategoryId) {
|
||||||
// 校验分类是否存在
|
// 校验分类是否存在
|
||||||
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
||||||
if (productCategory == null) {
|
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())) {
|
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 芋艿:考虑下,是否需要判断下该分类下是否有商品
|
||||||
// TODO 芋艿,需要补充下,还有子分类
|
// TODO 芋艿,需要补充下,还有子分类
|
||||||
|
@ -122,30 +116,25 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||||
updateProductCategory.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
updateProductCategory.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||||
productCategoryMapper.update(updateProductCategory);
|
productCategoryMapper.update(updateProductCategory);
|
||||||
// TODO 操作日志
|
// TODO 操作日志
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductCategoryDO getProductCategory(Integer productCategoryId) {
|
public ProductCategoryDO getProductCategory(Integer productCategoryId) {
|
||||||
return productCategoryMapper.selectById(productCategoryId);
|
return productCategoryMapper.selectById(productCategoryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonResult<ProductCategoryDO> validProductCategory(Integer productCategoryId) {
|
public ProductCategoryDO validProductCategory(Integer productCategoryId) {
|
||||||
// 校验分类是否存在
|
// 校验分类是否存在
|
||||||
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
||||||
if (productCategory == null) {
|
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())) {
|
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);
|
return productCategory;
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValidStatus(Integer status) {
|
|
||||||
return ProductCategoryConstants.STATUS_ENABLE.equals(status)
|
|
||||||
|| ProductCategoryConstants.STATUS_DISABLE.equals(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validParent(Integer pid) {
|
private void validParent(Integer pid) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||||
import cn.iocoder.common.framework.util.CollectionUtil;
|
import cn.iocoder.common.framework.util.CollectionUtil;
|
||||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.common.framework.util.StringUtil;
|
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.ProductSpuService;
|
||||||
import cn.iocoder.mall.product.api.bo.*;
|
import cn.iocoder.mall.product.api.bo.*;
|
||||||
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;
|
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;
|
||||||
|
@ -56,11 +55,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id) {
|
public ProductSpuDetailBO getProductSpuDetail(Integer id) {
|
||||||
// 校验商品 spu 存在
|
// 校验商品 spu 存在
|
||||||
ProductSpuDO spu = productSpuMapper.selectById(id);
|
ProductSpuDO spu = productSpuMapper.selectById(id);
|
||||||
if (spu == null) {
|
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());
|
ProductCategoryDO category = productCategoryService.getProductCategory(spu.getCid());
|
||||||
|
@ -70,55 +69,48 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
// 获得规格
|
// 获得规格
|
||||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
false); // 读取规格时,不考虑规格是否被禁用
|
false); // 读取规格时,不考虑规格是否被禁用
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(), category));
|
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<List<ProductSpuDetailBO>> getProductSpuDetailListForSync(Integer lastId, Integer limit) {
|
public List<ProductSpuDetailBO> getProductSpuDetailListForSync(Integer lastId, Integer limit) {
|
||||||
// TODO 芋艿,这里目前是一个一个进行计算,后续需要优化下
|
// TODO 芋艿,这里目前是一个一个进行计算,后续需要优化下
|
||||||
// 查询下一批商品编号集合
|
// 查询下一批商品编号集合
|
||||||
List<Integer> spuIds = productSpuMapper.selectIdListByIdGt(lastId, limit);
|
List<Integer> spuIds = productSpuMapper.selectIdListByIdGt(lastId, limit);
|
||||||
if (spuIds.isEmpty()) {
|
if (spuIds.isEmpty()) {
|
||||||
return CommonResult.success(Collections.emptyList());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 查询每个商品明细
|
// 查询每个商品明细
|
||||||
List<ProductSpuDetailBO> spus = spuIds.stream().map(id -> getProductSpuDetail(id).getData()).collect(Collectors.toList()); // TODO 芋艿,此处相当于是 N 个查询,后续要优化。
|
List<ProductSpuDetailBO> spus = spuIds.stream().map(id -> getProductSpuDetail(id)).collect(Collectors.toList()); // TODO 芋艿,此处相当于是 N 个查询,后续要优化。
|
||||||
return CommonResult.success(spus);
|
return spus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSpuDetailBO> addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
public ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
||||||
CommonResult<ProductSpuDetailBO> result = addProductSpu0(adminId, productSpuAddDTO);
|
ProductSpuDetailBO productSpuDetailBO = addProductSpu0(adminId, productSpuAddDTO);
|
||||||
// 如果新增生成,发送创建商品 Topic 消息
|
// 如果新增生成,发送创建商品 Topic 消息
|
||||||
if (result.isSuccess()) {
|
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
||||||
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
sendProductUpdateMessage(productSpuDetailBO.getId());
|
||||||
sendProductUpdateMessage(result.getData().getId());
|
// 返回成功
|
||||||
}
|
return productSpuDetailBO;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommonResult<ProductSpuDetailBO> addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
public ProductSpuDetailBO addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
||||||
// 校验商品分类分类存在
|
// 校验商品分类分类存在
|
||||||
CommonResult<ProductCategoryDO> validCategoryResult = productCategoryService.validProductCategory(productSpuAddDTO.getCid());
|
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuAddDTO.getCid());
|
||||||
if (validCategoryResult.isError()) {
|
if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下
|
||||||
return CommonResult.error(validCategoryResult);
|
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
||||||
}
|
|
||||||
if (ProductCategoryConstants.PID_ROOT.equals(validCategoryResult.getData().getPid())) { // 商品只能添加到二级分类下
|
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
|
||||||
}
|
}
|
||||||
// 校验规格是否存在
|
// 校验规格是否存在
|
||||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||||
productSpuAddDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
productSpuAddDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds
|
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds
|
||||||
, true); // 读取规格时,需要考虑规格是否被禁用
|
, true); // 读取规格时,需要考虑规格是否被禁用
|
||||||
if (validAttrResult.isError()) {
|
|
||||||
return CommonResult.error(validAttrResult);
|
|
||||||
}
|
|
||||||
// 保存 Spu
|
// 保存 Spu
|
||||||
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(productSpuAddDTO)
|
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(productSpuAddDTO)
|
||||||
.setPicUrls(StringUtil.join(productSpuAddDTO.getPicUrls(), ","))
|
.setPicUrls(StringUtil.join(productSpuAddDTO.getPicUrls(), ","))
|
||||||
|
@ -138,55 +130,40 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
return sku;
|
return sku;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
// 校验 Sku 规格
|
// 校验 Sku 规格
|
||||||
CommonResult<Boolean> validProductSkuResult = validProductSku(productSpuAddDTO.getSkus(), validAttrResult.getData());
|
validProductSku(productSpuAddDTO.getSkus(), attrAndValuePairList);
|
||||||
if (validProductSkuResult.isError()) {
|
// 插入 SKU 到数据库
|
||||||
// return CommonResult.error(validProductSkuResult);
|
|
||||||
throw ServiceExceptionUtil.exception(validProductSkuResult.getCode());
|
|
||||||
}
|
|
||||||
productSkuMapper.insertList(skus);
|
productSkuMapper.insertList(skus);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(),
|
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||||
validCategoryResult.getData()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
public void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
||||||
CommonResult<Boolean> result = updateProductSpu0(adminId, productSpuUpdateDTO);
|
// 更新商品
|
||||||
if (result.isSuccess()) {
|
updateProductSpu0(adminId, productSpuUpdateDTO);
|
||||||
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
||||||
sendProductUpdateMessage(productSpuUpdateDTO.getId());
|
sendProductUpdateMessage(productSpuUpdateDTO.getId());
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommonResult<Boolean> updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
public void updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
||||||
// 校验 Spu 是否存在
|
// 校验 Spu 是否存在
|
||||||
if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) {
|
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<ProductCategoryDO> validCategoryResult = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
|
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
|
||||||
if (validCategoryResult.isError()) {
|
if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下
|
||||||
return CommonResult.error(validCategoryResult);
|
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
||||||
}
|
|
||||||
if (ProductCategoryConstants.PID_ROOT.equals(validCategoryResult.getData().getPid())) { // 商品只能添加到二级分类下
|
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
|
||||||
}
|
}
|
||||||
// 校验规格是否存在
|
// 校验规格是否存在
|
||||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||||
productSpuUpdateDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
productSpuUpdateDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
true); // 读取规格时,需要考虑规格是否被禁用
|
true); // 读取规格时,需要考虑规格是否被禁用
|
||||||
if (validAttrResult.isError()) {
|
|
||||||
return CommonResult.error(validAttrResult);
|
|
||||||
}
|
|
||||||
// 校验 Sku 规格
|
// 校验 Sku 规格
|
||||||
CommonResult<Boolean> validProductSkuResult = validProductSku(productSpuUpdateDTO.getSkus(), validAttrResult.getData());
|
validProductSku(productSpuUpdateDTO.getSkus(), attrAndValuePairList);
|
||||||
if (validProductSkuResult.isError()) {
|
|
||||||
return CommonResult.error(validProductSkuResult);
|
|
||||||
}
|
|
||||||
// 更新 Spu
|
// 更新 Spu
|
||||||
ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
|
ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
|
||||||
.setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
|
.setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
|
||||||
|
@ -228,14 +205,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
if (!deleteSkus.isEmpty()) {
|
if (!deleteSkus.isEmpty()) {
|
||||||
productSkuMapper.updateToDeleted(deleteSkus);
|
productSkuMapper.updateToDeleted(deleteSkus);
|
||||||
}
|
}
|
||||||
return CommonResult.success(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
|
public Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
|
||||||
// 校验 Spu 是否存在
|
// 校验 Spu 是否存在
|
||||||
if (productSpuMapper.selectById(spuId) == null) {
|
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);
|
ProductSpuDO updateSpu = new ProductSpuDO().setId(spuId).setSort(sort);
|
||||||
|
@ -243,54 +219,55 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
// 修改成功,发送商品 Topic 消息
|
// 修改成功,发送商品 Topic 消息
|
||||||
sendProductUpdateMessage(spuId);
|
sendProductUpdateMessage(spuId);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) {
|
public ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) {
|
||||||
ProductSpuPageBO productSpuPage = new ProductSpuPageBO();
|
ProductSpuPageBO productSpuPage = new ProductSpuPageBO();
|
||||||
// 查询分页数据
|
// 查询分页数据
|
||||||
int offset = (productSpuPageDTO.getPageNo() - 1) * productSpuPageDTO.getPageSize();
|
int offset = (productSpuPageDTO.getPageNo() - 1) * productSpuPageDTO.getPageSize();
|
||||||
productSpuPage.setSpus(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc(
|
productSpuPage.setList(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc(
|
||||||
productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getVisible(),
|
productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(), productSpuPageDTO.getVisible(),
|
||||||
offset, productSpuPageDTO.getPageSize())));
|
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
|
@Override
|
||||||
public CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids) {
|
public List<ProductSpuBO> getProductSpuList(Collection<Integer> ids) {
|
||||||
List<ProductSpuDO> spus = productSpuMapper.selectByIds(ids);
|
List<ProductSpuDO> spus = productSpuMapper.selectByIds(ids);
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert(spus));
|
return ProductSpuConvert.INSTANCE.convert(spus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSkuBO> getProductSku(Integer id) {
|
public ProductSkuBO getProductSku(Integer id) {
|
||||||
ProductSkuDO sku = productSkuMapper.selectById(id);
|
ProductSkuDO sku = productSkuMapper.selectById(id);
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert4(sku));
|
return ProductSpuConvert.INSTANCE.convert4(sku);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids) {
|
public List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids) {
|
||||||
// 查询 SKU 数组
|
// 查询 SKU 数组
|
||||||
List<ProductSkuDO> skus = productSkuMapper.selectByIds(ids);
|
List<ProductSkuDO> skus = productSkuMapper.selectByIds(ids);
|
||||||
if (skus.isEmpty()) {
|
if (skus.isEmpty()) {
|
||||||
return CommonResult.success(Collections.emptyList());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 查询 SPU 数组
|
// 查询 SPU 数组
|
||||||
List<ProductSpuDO> spus = productSpuMapper.selectByIds(skus.stream().map(ProductSkuDO::getSpuId).collect(Collectors.toSet()));
|
List<ProductSpuDO> spus = productSpuMapper.selectByIds(skus.stream().map(ProductSkuDO::getSpuId).collect(Collectors.toSet()));
|
||||||
if (spus.isEmpty()) {
|
if (spus.isEmpty()) {
|
||||||
return CommonResult.success(Collections.emptyList());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 获得规格
|
// 获得规格
|
||||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
false); // 读取规格时,不考虑规格是否被禁用
|
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 商品规格明细数组
|
* @param productAttrDetailBOs 商品规格明细数组
|
||||||
* @return 是否校验通过
|
* @return 是否校验通过
|
||||||
*/
|
*/
|
||||||
private CommonResult<Boolean> validProductSku(List<ProductSkuAddOrUpdateDTO> productSkuAddDTOs, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
private Boolean validProductSku(List<ProductSkuAddOrUpdateDTO> productSkuAddDTOs, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
||||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||||
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
|
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
|
||||||
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
||||||
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
|
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
|
||||||
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
||||||
Set<Integer> attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()).collect(Collectors.toSet());
|
Set<Integer> attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
if (attrIds.size() != sku.getAttrs().size()) {
|
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 的规格值的数量,是一致的。
|
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
|
||||||
int attrSize = productSkuAddDTOs.get(0).getAttrs().size();
|
int attrSize = productSkuAddDTOs.get(0).getAttrs().size();
|
||||||
for (int i = 1; i < productSkuAddDTOs.size(); i++) {
|
for (int i = 1; i < productSkuAddDTOs.size(); i++) {
|
||||||
if (attrSize != productSkuAddDTOs.get(i).getAttrs().size()) {
|
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 之间不是重复的
|
// 3. 最后校验,每个 Sku 之间不是重复的
|
||||||
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
|
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
|
||||||
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
||||||
if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败,说明重复
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -104,6 +104,12 @@
|
||||||
<if test="visible != null">
|
<if test="visible != null">
|
||||||
AND visible = #{visible}
|
AND visible = #{visible}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="hasQuantity == true">
|
||||||
|
AND quantity > 0
|
||||||
|
</if>
|
||||||
|
<if test="hasQuantity == false">
|
||||||
|
AND quantity = 0
|
||||||
|
</if>
|
||||||
AND deleted = 0
|
AND deleted = 0
|
||||||
</where>
|
</where>
|
||||||
ORDER BY sort ASC
|
ORDER BY sort ASC
|
||||||
|
@ -124,6 +130,12 @@
|
||||||
<if test="visible != null">
|
<if test="visible != null">
|
||||||
AND visible = #{visible}
|
AND visible = #{visible}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="hasQuantity == true">
|
||||||
|
AND quantity > 0
|
||||||
|
</if>
|
||||||
|
<if test="hasQuantity == false">
|
||||||
|
AND quantity = 0
|
||||||
|
</if>
|
||||||
AND deleted = 0
|
AND deleted = 0
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class UsersProductRecommendController {
|
||||||
null, CommonStatusEnum.ENABLE.getValue()).getData();
|
null, CommonStatusEnum.ENABLE.getValue()).getData();
|
||||||
// 获得商品集合
|
// 获得商品集合
|
||||||
List<ProductSpuBO> spus = productSpuService.getProductSpuList(
|
List<ProductSpuBO> spus = productSpuService.getProductSpuList(
|
||||||
productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet())).getData();
|
productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet()));
|
||||||
Map<Integer, ProductSpuBO> spuMap = spus.stream().collect(Collectors.toMap(ProductSpuBO::getId, account -> account));
|
Map<Integer, ProductSpuBO> spuMap = spus.stream().collect(Collectors.toMap(ProductSpuBO::getId, account -> account));
|
||||||
// 组合结果,返回
|
// 组合结果,返回
|
||||||
Multimap<Integer, UsersProductRecommendVO> result = HashMultimap.create();
|
Multimap<Integer, UsersProductRecommendVO> result = HashMultimap.create();
|
||||||
|
|
|
@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("users/product")
|
@RequestMapping("users/product")
|
||||||
@Api("商品搜索")
|
@Api("商品搜索")
|
||||||
|
@ -39,7 +41,7 @@ public class UsersProductSearchController {
|
||||||
productSearchPageDTO.setSorts(Collections.singletonList(new SortingField(sortField, sortOrder)));
|
productSearchPageDTO.setSorts(Collections.singletonList(new SortingField(sortField, sortOrder)));
|
||||||
}
|
}
|
||||||
// 执行搜索
|
// 执行搜索
|
||||||
return productSearchService.getSearchPage(productSearchPageDTO);
|
return success(productSearchService.getSearchPage(productSearchPageDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/condition") // TODO 芋艿,后面把 BO 改成 VO
|
@GetMapping("/condition") // TODO 芋艿,后面把 BO 改成 VO
|
||||||
|
@ -48,7 +50,7 @@ public class UsersProductSearchController {
|
||||||
ProductConditionDTO productConditionDTO = new ProductConditionDTO().setKeyword(keyword)
|
ProductConditionDTO productConditionDTO = new ProductConditionDTO().setKeyword(keyword)
|
||||||
.setFields(Collections.singleton(ProductConditionDTO.FIELD_CATEGORY));
|
.setFields(Collections.singleton(ProductConditionDTO.FIELD_CATEGORY));
|
||||||
// 执行搜索
|
// 执行搜索
|
||||||
return productSearchService.getSearchCondition(productConditionDTO);
|
return success(productSearchService.getSearchCondition(productConditionDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.search.api;
|
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.ProductConditionBO;
|
||||||
import cn.iocoder.mall.search.api.bo.ProductPageBO;
|
import cn.iocoder.mall.search.api.bo.ProductPageBO;
|
||||||
import cn.iocoder.mall.search.api.dto.ProductConditionDTO;
|
import cn.iocoder.mall.search.api.dto.ProductConditionDTO;
|
||||||
|
@ -8,7 +7,7 @@ import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
|
||||||
|
|
||||||
public interface ProductSearchService {
|
public interface ProductSearchService {
|
||||||
|
|
||||||
CommonResult<Integer> rebuild();
|
Integer rebuild();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建商品的搜索索引
|
* 构建商品的搜索索引
|
||||||
|
@ -16,10 +15,10 @@ public interface ProductSearchService {
|
||||||
* @param id 商品编号
|
* @param id 商品编号
|
||||||
* @return 构建结果
|
* @return 构建结果
|
||||||
*/
|
*/
|
||||||
CommonResult<Boolean> save(Integer id);
|
Boolean save(Integer id);
|
||||||
|
|
||||||
CommonResult<ProductPageBO> getSearchPage(ProductSearchPageDTO searchPageDTO);
|
ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO);
|
||||||
|
|
||||||
CommonResult<ProductConditionBO> getSearchCondition(ProductConditionDTO conditionDTO);
|
ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.iocoder.mall.search.biz.mq;
|
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.product.api.message.ProductUpdateMessage;
|
||||||
import cn.iocoder.mall.search.api.ProductSearchService;
|
import cn.iocoder.mall.search.api.ProductSearchService;
|
||||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||||
|
@ -21,8 +20,8 @@ public class PayTransactionPaySuccessConsumer implements RocketMQListener<Produc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(ProductUpdateMessage message) {
|
public void onMessage(ProductUpdateMessage message) {
|
||||||
CommonResult<Boolean> result = productSearchService.save(message.getId());
|
Boolean result = productSearchService.save(message.getId());
|
||||||
Assert.isTrue(result.isSuccess(), String.format("重构商品 ES 索引,必然成功。实际结果是 %s", result));
|
Assert.isTrue(result, String.format("重构商品 ES 索引,必然成功。实际结果是 %s", result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,14 +55,12 @@ public class ProductSearchServiceImpl implements ProductSearchService {
|
||||||
private CartService cartService;
|
private CartService cartService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Integer> rebuild() {
|
public Integer rebuild() {
|
||||||
// TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构
|
// TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构
|
||||||
Integer lastId = null;
|
Integer lastId = null;
|
||||||
int rebuildCounts = 0;
|
int rebuildCounts = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
CommonResult<List<ProductSpuDetailBO>> result = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE);
|
List<ProductSpuDetailBO> spus = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE);
|
||||||
Assert.isTrue(result.isSuccess(), "获得商品列表必然成功");
|
|
||||||
List<ProductSpuDetailBO> spus = result.getData();
|
|
||||||
rebuildCounts += spus.size();
|
rebuildCounts += spus.size();
|
||||||
// 存储到 ES 中
|
// 存储到 ES 中
|
||||||
List<ESProductDO> products = spus.stream().map(this::convert).collect(Collectors.toList());
|
List<ESProductDO> 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
|
@Override
|
||||||
public CommonResult<Boolean> save(Integer id) {
|
public Boolean save(Integer id) {
|
||||||
// 获得商品性情
|
// 获得商品性情
|
||||||
CommonResult<ProductSpuDetailBO> result = productSpuService.getProductSpuDetail(id);
|
ProductSpuDetailBO result = productSpuService.getProductSpuDetail(id);
|
||||||
Assert.isTrue(result.isSuccess(), "获得商品详情必然成功");
|
|
||||||
// 存储到 ES 中
|
// 存储到 ES 中
|
||||||
ESProductDO product = convert(result.getData());
|
ESProductDO product = convert(result);
|
||||||
productRepository.save(product);
|
productRepository.save(product);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(Boolean.TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
@ -102,16 +99,15 @@ public class ProductSearchServiceImpl implements ProductSearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductPageBO> getSearchPage(ProductSearchPageDTO searchPageDTO) {
|
public ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO) {
|
||||||
checkSortFieldInvalid(searchPageDTO.getSorts());
|
checkSortFieldInvalid(searchPageDTO.getSorts());
|
||||||
// 执行查询
|
// 执行查询
|
||||||
Page<ESProductDO> searchPage = productRepository.search(searchPageDTO.getCid(), searchPageDTO.getKeyword(),
|
Page<ESProductDO> searchPage = productRepository.search(searchPageDTO.getCid(), searchPageDTO.getKeyword(),
|
||||||
searchPageDTO.getPageNo(), searchPageDTO.getPageSize(), searchPageDTO.getSorts());
|
searchPageDTO.getPageNo(), searchPageDTO.getPageSize(), searchPageDTO.getSorts());
|
||||||
// 转换结果
|
// 转换结果
|
||||||
ProductPageBO resultPage = new ProductPageBO()
|
return new ProductPageBO()
|
||||||
.setList(ProductSearchConvert.INSTANCE.convert(searchPage.getContent()))
|
.setList(ProductSearchConvert.INSTANCE.convert(searchPage.getContent()))
|
||||||
.setTotal((int) searchPage.getTotalElements());
|
.setTotal((int) searchPage.getTotalElements());
|
||||||
return CommonResult.success(resultPage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSortFieldInvalid(List<SortingField> sorts) {
|
private void checkSortFieldInvalid(List<SortingField> sorts) {
|
||||||
|
@ -123,7 +119,7 @@ public class ProductSearchServiceImpl implements ProductSearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductConditionBO> getSearchCondition(ProductConditionDTO conditionDTO) {
|
public ProductConditionBO getSearchCondition(ProductConditionDTO conditionDTO) {
|
||||||
// 创建 ES 搜索条件
|
// 创建 ES 搜索条件
|
||||||
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
|
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
|
||||||
// 筛选
|
// 筛选
|
||||||
|
@ -161,7 +157,7 @@ public class ProductSearchServiceImpl implements ProductSearchService {
|
||||||
condition.getCategories().forEach(category -> category.setName(categoryMap.get(category.getId()).getName()));
|
condition.getCategories().forEach(category -> category.setName(categoryMap.get(category.getId()).getName()));
|
||||||
}
|
}
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return CommonResult.success(condition);
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class ProductSearchServiceImplTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRebuild() {
|
public void testRebuild() {
|
||||||
int counts = productSearchService.rebuild().getData();
|
int counts = productSearchService.rebuild();
|
||||||
System.out.println("重建数量:" + counts);
|
System.out.println("重建数量:" + counts);
|
||||||
|
|
||||||
System.out.println(productRepository.count());
|
System.out.println(productRepository.count());
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class AdminAccessLogInterceptor extends HandlerInterceptorAdapter {
|
||||||
*/
|
*/
|
||||||
private static final ThreadLocal<Integer> ADMIN_ID = new ThreadLocal<>();
|
private static final ThreadLocal<Integer> ADMIN_ID = new ThreadLocal<>();
|
||||||
|
|
||||||
@Reference(lazy = true)
|
@Reference(validation = "true")
|
||||||
@Autowired(required = false) // TODO 芋艿,初始化时,会存在 spring boot 启动时,服务无法引用的情况,先暂时这么解决。
|
@Autowired(required = false) // TODO 芋艿,初始化时,会存在 spring boot 启动时,服务无法引用的情况,先暂时这么解决。
|
||||||
private AdminAccessLogService adminAccessLogService;
|
private AdminAccessLogService adminAccessLogService;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue