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