Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
f46a4f70
提交
f46a4f70
authored
4月 22, 2019
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
前端:整理首页
前端:修复订单列表和详情价格展示错误 前端:H5 页面的登陆拦截补充 后端 + 前端:增加 refreshToken 刷新 accessToken
上级
3e156b18
隐藏空白字符变更
内嵌
并排
正在显示
28 个修改的文件
包含
292 行增加
和
105 行删除
+292
-105
proxy.dev.js
admin-web/config/proxy/proxy.dev.js
+1
-1
cache.js
admin-web/src/utils/cache.js
+3
-4
request.js
mobile-web/src/config/request.js
+39
-6
router.js
mobile-web/src/config/router.js
+18
-9
index.vue
mobile-web/src/page/page/index.vue
+38
-17
detail.vue
mobile-web/src/page/product/detail.vue
+13
-3
info.vue
mobile-web/src/page/user/order/info.vue
+8
-4
list.vue
mobile-web/src/page/user/order/list.vue
+2
-2
cache.js
mobile-web/src/utils/cache.js
+19
-11
UsersCartController.java
...der/application/controller/users/UsersCartController.java
+2
-0
OrderBO.java
...i/src/main/java/cn/iocoder/mall/order/api/bo/OrderBO.java
+21
-5
OrderInfoBO.java
...c/main/java/cn/iocoder/mall/order/api/bo/OrderInfoBO.java
+21
-4
pom.xml
product/product-application/pom.xml
+6
-0
UsersProductCategoryController.java
...tion/controller/users/UsersProductCategoryController.java
+1
-1
UsersProductSpuController.java
...plication/controller/users/UsersProductSpuController.java
+1
-2
UsersBannerController.java
...n/application/controller/users/UsersBannerController.java
+1
-1
UsersProductRecommendController.java
...ion/controller/users/UsersProductRecommendController.java
+1
-1
PassportController.java
...user/application/controller/users/PassportController.java
+11
-6
PassportConvert.java
...ocoder/mall/user/application/convert/PassportConvert.java
+8
-5
UsersAccessTokenVO.java
...er/mall/user/application/vo/users/UsersAccessTokenVO.java
+20
-0
UsersMobileRegisterVO.java
...mall/user/application/vo/users/UsersMobileRegisterVO.java
+1
-1
OAuth2Service.java
...src/main/java/cn/iocoder/mall/user/api/OAuth2Service.java
+2
-3
UserErrorCodeEnum.java
.../cn/iocoder/mall/user/api/constant/UserErrorCodeEnum.java
+8
-6
OAuth2AccessTokenMapper.java
...cn/iocoder/mall/user/biz/dao/OAuth2AccessTokenMapper.java
+3
-2
OAuth2RefreshTokenMapper.java
...n/iocoder/mall/user/biz/dao/OAuth2RefreshTokenMapper.java
+3
-2
OAuth2ServiceImpl.java
...a/cn/iocoder/mall/user/biz/service/OAuth2ServiceImpl.java
+25
-5
OAuth2AccessTokenMapper.xml
...mpl/src/main/resources/mapper/OAuth2AccessTokenMapper.xml
+8
-2
OAuth2RefreshTokenMapper.xml
...pl/src/main/resources/mapper/OAuth2RefreshTokenMapper.xml
+8
-2
没有找到文件。
admin-web/config/proxy/proxy.dev.js
浏览文件 @
f46a4f70
...
...
@@ -2,7 +2,7 @@
export
default
{
'/admin-api/'
:
{
target
:
'http://1
80.167.213.26
:18083/'
,
target
:
'http://1
27.0.0.1
:18083/'
,
// target: 'http://180.167.213.26:18083/',
changeOrigin
:
true
,
pathRewrite
:
{},
...
...
admin-web/src/utils/cache.js
浏览文件 @
f46a4f70
...
...
@@ -3,8 +3,8 @@
// localStorage 操作
const
cacheKeys
=
{
accessTokenKey
:
'accessToken'
,
refreshTokenKey
:
'refreshToken'
,
ACCESS_TOKEN
:
'accessToken'
,
REFRESH_TOKEN
:
'refreshToken'
,
};
///
...
...
@@ -49,4 +49,4 @@ function removeLocalStorage(key) {
}
catch
(
e
)
{
throw
new
Error
(
`localStorage 设置错误!
${
e
}
`
);
}
}
\ No newline at end of file
}
mobile-web/src/config/request.js
浏览文件 @
f46a4f70
import
axios
from
'axios'
import
{
baseUrl
,
dataSources
}
from
'./env'
;
import
datas
from
'../data/data'
;
import
{
getAccessToken
}
from
'../utils/cache.js'
;
import
{
getAccessToken
,
getRefreshToken
}
from
'../utils/cache.js'
;
import
{
Dialog
}
from
'vant'
;
import
{
setLoginToken
}
from
"../utils/cache"
;
const
serviceRouter
=
function
(
requestUrl
)
{
function
getConfig
()
{
...
...
@@ -75,8 +76,9 @@ const serviceRouter = function(requestUrl) {
// });
// }
// }
const
config
=
getConfig
();
// TODO 芋艿,临时加下。
// const createServer = doCreateServer(config);
const
indexOf
=
requestUrl
.
indexOf
(
"/"
,
1
);
const
_urlPrefix
=
requestUrl
.
substring
(
0
,
indexOf
);
...
...
@@ -130,9 +132,10 @@ const servicef = function (parameter) {
return
service
(
parameter
);
};
service
.
interceptors
.
request
.
use
(
config
=>
{
// 记录下原始请求的地址
config
.
originUrl
=
config
.
url
;
// Do something before request is sent
// if (store.getters.token) {
// // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
...
...
@@ -144,7 +147,8 @@ service.interceptors.request.use(
let
url
=
config
.
url
=
config
.
url
.
replace
(
`
${
prefix
}
`
,
target
);
// TODO 芋艿,这些 url 不用增加认证 token 。可能这么写,有点脏,后面看看咋优化下。
if
(
url
.
indexOf
(
'user-api/users/passport/mobile/send_register_code'
)
!==
-
1
||
url
.
indexOf
(
'user-api/users/passport/mobile/register'
)
!==
-
1
)
{
||
url
.
indexOf
(
'user-api/users/passport/mobile/register'
)
!==
-
1
||
url
.
indexOf
(
'user-api/users/passport/refresh_token'
)
!==
-
1
)
{
return
config
;
}
...
...
@@ -152,7 +156,6 @@ service.interceptors.request.use(
if
(
getAccessToken
())
{
config
.
headers
[
'Authorization'
]
=
`Bearer
${
getAccessToken
()}
`
;
}
return
config
},
error
=>
{
...
...
@@ -162,6 +165,30 @@ service.interceptors.request.use(
}
);
function
refreshToken
(
lastResponse
)
{
// TODO 芋艿,可能会存在多个异步 callback 的情况。
let
refreshToken
=
getRefreshToken
();
return
servicef
({
url
:
'/user-api/users/passport/refresh_token'
,
method
:
'post'
,
params
:
{
refreshToken
}
}).
then
(
data
=>
{
// 设置新的 accessToken
setLoginToken
(
data
.
accessToken
,
data
.
refreshToken
);
// 重新发起请求
let
config
=
lastResponse
.
config
;
return
servicef
({
url
:
config
.
originUrl
,
method
:
config
.
method
,
params
:
{
...
config
.
params
,
}
});
});
}
// response interceptor
service
.
interceptors
.
response
.
use
(
//response => response,
...
...
@@ -194,7 +221,11 @@ service.interceptors.response.use(
// TODO token 过期
// TODO 需要拿 refresh token 置换
if
(
code
===
1001001012
)
{
if
(
code
===
1001001011
// 访问令牌不存在
||
code
===
1001001013
// 访问令牌已失效
||
code
===
1001001021
// 刷新令牌不存在
||
code
===
1001001022
// 刷新令牌已过期
||
code
===
1001001023
)
{
// 刷新令牌已失效
Dialog
.
confirm
({
title
:
'系统提示'
,
message
:
res
.
message
,
...
...
@@ -210,6 +241,8 @@ service.interceptors.response.use(
}
}
});
}
else
if
(
code
===
1001001012
)
{
// 访问令牌已过期
return
refreshToken
(
response
);
}
else
{
Dialog
.
alert
({
title
:
'系统提示'
,
...
...
mobile-web/src/config/router.js
浏览文件 @
f46a4f70
...
...
@@ -66,21 +66,24 @@ const routes = [
path
:
'/user/address'
,
component
:
()
=>
import
(
'../page/user/address/list'
),
meta
:
{
title
:
'我的地址'
title
:
'我的地址'
,
requireAuth
:
true
,
}
},
{
path
:
'/user/address/edit'
,
component
:
()
=>
import
(
'../page/user/address/edit'
),
meta
:
{
title
:
'修改地址'
title
:
'修改地址'
,
requireAuth
:
true
,
}
},
{
path
:
'/user/favorite'
,
component
:
()
=>
import
(
'../page/user/favorite/list'
),
meta
:
{
title
:
'我的收藏'
title
:
'我的收藏'
,
requireAuth
:
true
,
}
},
{
...
...
@@ -102,21 +105,24 @@ const routes = [
path
:
'/user/order/:id'
,
component
:
()
=>
import
(
'../page/user/order/list'
),
meta
:
{
title
:
'我的订单'
title
:
'我的订单'
,
requireAuth
:
true
,
}
},
{
path
:
'/user/order/info/:id'
,
component
:
()
=>
import
(
'../page/user/order/info'
),
meta
:
{
title
:
'我的订单'
title
:
'我的订单'
,
requireAuth
:
true
,
}
},
{
path
:
'/user/order/logistics/:id'
,
component
:
()
=>
import
(
'../page/user/order/logistics'
),
meta
:
{
title
:
'订单追踪'
title
:
'订单追踪'
,
requireAuth
:
true
,
}
},
{
...
...
@@ -172,7 +178,8 @@ const routes = [
name
:
'cart'
,
component
:
()
=>
import
(
'../page/cart/index'
),
meta
:
{
title
:
'购物车'
title
:
'购物车'
,
requireAuth
:
true
,
}
},
{
...
...
@@ -187,7 +194,8 @@ const routes = [
path
:
'/order/success'
,
component
:
()
=>
import
(
'../page/shipping/order-success'
),
meta
:
{
title
:
'确认订单'
title
:
'确认订单'
,
requireAuth
:
true
,
}
},
{
...
...
@@ -208,7 +216,8 @@ const routes = [
path
:
'/pay'
,
component
:
()
=>
import
(
'../page/pay/index'
),
meta
:
{
title
:
'收银台'
title
:
'收银台'
,
requireAuth
:
true
,
}
}
];
...
...
mobile-web/src/page/page/index.vue
浏览文件 @
f46a4f70
...
...
@@ -12,15 +12,37 @@
</a>
</van-swipe-item>
</van-swipe>
<van-panel
title=
"新品推荐"
>
<van-row
style=
"text-align: center"
>
<van-col
span=
"8"
>
<router-link
to=
"/category"
>
<van-icon
name=
"http://static.iocoder.cn/icons8-medium-priority-45.png"
/>
<div
style=
"font-size:12px;margin-top: -10px;"
>
分类
</div>
</router-link>
</van-col>
<van-col
span=
"8"
>
<router-link
to=
"/category"
>
<van-icon
name=
"http://static.iocoder.cn/icons8-sun-45.png"
/>
<div
style=
"font-size:12px;margin-top: -10px;"
>
热卖
</div>
</router-link>
</van-col>
<van-col
span=
"8"
>
<router-link
to=
"/category"
>
<van-icon
name=
"http://static.iocoder.cn/icons8-new-45.png"
/>
<div
style=
"font-size:12px;margin-top: -10px;"
>
新品
</div>
</router-link>
</van-col>
</van-row>
<van-panel
title=
"新品推荐"
>
<!--
<product
:data=
"productRecommends['1']"
></product>
-->
<div
v-for=
"(product,i) in productRecommends['1']"
:key=
"i"
>
<div
style=
"height: 70px;"
v-for=
"(product,i) in productRecommends['1']"
:key=
"i"
>
<product-card
:product=
'product'
@
click=
"showProduct(product)"
/>
</div>
</van-panel>
<van-panel
title=
"热卖推荐"
>
<div
v-for=
"(product,i) in productRecommends['2']"
:key=
"i"
>
<div
style=
"height: 70px;"
v-for=
"(product,i) in productRecommends['2']"
:key=
"i"
>
<product-card
:product=
'product'
@
click=
"showProduct(product)"
/>
</div>
</van-panel>
...
...
@@ -28,21 +50,20 @@
</div>
</
template
>
<
script
>
import
"../../assets/style/index.css"
;
import
whitespace
from
"../../components/page/whitespace.vue"
;
import
pageLine
from
"../../components/page/line.vue"
;
import
pageText
from
"../../components/page/text.vue"
;
import
notice
from
"../../components/page/notice.vue"
;
import
search
from
"../../components/page/search.vue"
;
import
pageTitle
from
"../../components/page/title.vue"
;
import
cube
from
"../../components/page/cube.vue"
;
import
imageAd
from
"../../components/page/imageAd.vue"
;
import
imageText
from
"../../components/page/imageText.vue"
;
import
product
from
"../../components/page/product.vue"
;
import
{
GetPage
}
from
"../../api/page.js"
;
import
{
getBannerList
,
getProductRecommendList
}
from
'../../api/promotion.js'
;
import
"../../assets/style/index.css"
;
import
whitespace
from
"../../components/page/whitespace.vue"
;
import
pageLine
from
"../../components/page/line.vue"
;
import
pageText
from
"../../components/page/text.vue"
;
import
notice
from
"../../components/page/notice.vue"
;
import
search
from
"../../components/page/search.vue"
;
import
pageTitle
from
"../../components/page/title.vue"
;
import
cube
from
"../../components/page/cube.vue"
;
import
imageAd
from
"../../components/page/imageAd.vue"
;
import
imageText
from
"../../components/page/imageText.vue"
;
import
product
from
"../../components/page/product.vue"
;
import
{
getBannerList
,
getProductRecommendList
}
from
'../../api/promotion.js'
;
export
default
{
export
default
{
name
:
"page"
,
components
:{
whitespace
,
...
...
mobile-web/src/page/product/detail.vue
浏览文件 @
f46a4f70
...
...
@@ -174,6 +174,7 @@
import
{
getProductSpuInfo
}
from
'../../api/product'
;
import
{
addCart
,
countCart
,
getCartCalcSkuPrice
}
from
'../../api/order'
;
import
{
Dialog
}
from
'vant'
;
import
{
checkLogin
}
from
"../../utils/cache"
;
export
default
{
components
:
{},
...
...
@@ -316,6 +317,13 @@
});
},
onAddCartClicked
(
data
)
{
if
(
!
checkLogin
())
{
Dialog
.
alert
({
title
:
'系统提示'
,
message
:
'未登陆用户,暂时不支持使用购物车'
,
});
return
;
}
const
{
selectedNum
}
=
data
;
// debugger;
addCart
(
data
.
selectedSkuComb
.
id
,
selectedNum
).
then
(
data
=>
{
...
...
@@ -398,9 +406,11 @@
this
.
doCalcSkuPrice
(
this
.
initialSku
.
id
);
});
// 获得购物车数量
countCart
().
then
(
data
=>
{
this
.
cartCount
=
data
;
})
if
(
checkLogin
())
{
countCart
().
then
(
data
=>
{
this
.
cartCount
=
data
;
})
}
}
};
</
script
>
...
...
mobile-web/src/page/user/order/info.vue
浏览文件 @
f46a4f70
...
...
@@ -39,15 +39,16 @@
</van-cell-group>
<div
style=
"height:15px;"
></div>
<van-cell-group
class=
"total"
>
<van-cell
title=
"商品总额"
:value=
"orderInfo.price"
/>
<van-cell
title=
"运费"
:value=
"'+' + orderInfo.logisticsPrice / 100"
/>
<van-cell
title=
"实付金额"
:value=
"orderInfo.payAmount"
style=
"font-weight: 700;"
/>
<van-cell
title=
"商品总额"
:value=
"orderInfo.buyPrice / 100.0"
/>
<van-cell
title=
"运费"
:value=
"'+' + orderInfo.logisticsPrice / 100.0"
/>
<van-cell
title=
"折扣"
:value=
"- orderInfo.discountPrice / 100.0"
/>
<van-cell
title=
"实付金额"
:value=
"orderInfo.presentPrice / 100.0"
style=
"font-weight: 700;"
/>
</van-cell-group>
<div
class=
"footer"
>
<div
class=
"munu"
>
<van-button
v-if=
"orderInfo.status === 3 "
size=
"small"
>
退货
</van-button>
<van-button
v-if=
"orderInfo.status === 3 "
size=
"small"
v-on:click=
"clickConfirmReceiving(orderId)"
>
确认收货
</van-button>
<van-button
v-if=
"orderInfo.status === 1 "
size=
"small"
type=
"danger"
>
支付
</van-button>
<van-button
v-if=
"orderInfo.status === 1 "
size=
"small"
type=
"danger"
@
click=
"goPay(orderInfo.id)"
>
支付
</van-button>
</div>
</div>
</div>
...
...
@@ -88,6 +89,9 @@
this
.
queryOrderPage
(
this
.
queryParams
)
})
},
goPay
(
itemId
)
{
this
.
$router
.
push
(
'/pay?appId=POd4RC6a&orderId='
+
itemId
+
'&returnUrl='
+
encodeURI
(
'/user/order/info/'
+
itemId
));
},
},
mounted
()
{
const
{
id
}
=
this
.
$route
.
params
;
...
...
mobile-web/src/page/user/order/list.vue
浏览文件 @
f46a4f70
...
...
@@ -33,7 +33,7 @@
</router-link>
</div>
<div
slot=
"footer"
class=
"footer"
>
<span
class=
"total"
>
总价:
{{
item
.
p
ayAmount
/
100
}}
元
</span>
<span
class=
"total"
>
总价:
{{
item
.
p
resentPrice
/
100
}}
元
</span>
<router-link
:to=
"'/user/order/logistics/'+item.orderid"
>
<van-button
v-if=
"[3,4,5].indexOf(item.status) != -1"
size=
"small"
>
查看物流
</van-button>
</router-link>
...
...
@@ -114,7 +114,7 @@
state
:
`
${
statusArray
[
order
.
status
]}
`
,
status
:
order
.
status
,
products
,
p
ayAmount
:
order
.
payAmount
,
p
resentPrice
:
order
.
presentPrice
,
};
});
...
...
mobile-web/src/utils/cache.js
浏览文件 @
f46a4f70
...
...
@@ -3,32 +3,41 @@
// localStorage 操作
const
cacheKeys
=
{
accessTokenKey
:
'accessToken'
,
refreshTokenKey
:
'refreshToken'
,
ACCESS_TOKEN
:
'accessToken'
,
REFRESH_TOKEN
:
'refreshToken'
,
};
///
/// 设置 loginToken,分为 accessToken 和 refreshToken
export
function
checkLogin
()
{
let
accessToken
=
getAccessToken
();
return
accessToken
&&
accessToken
.
length
>
0
;
}
export
function
setLoginToken
(
accessToken
,
refreshToken
)
{
setLocalStorage
(
cacheKeys
.
accessTokenKey
,
accessToken
);
setLocalStorage
(
cacheKeys
.
refreshTokenKey
,
refreshToken
);
setLocalStorage
(
cacheKeys
.
ACCESS_TOKEN
,
accessToken
);
setLocalStorage
(
cacheKeys
.
REFRESH_TOKEN
,
refreshToken
);
}
export
function
getLoginToken
()
{
const
res
=
{};
res
[
cacheKeys
.
accessTokenKey
]
=
getLocalStorage
(
cacheKeys
.
accessTokenKey
);
res
[
cacheKeys
.
refreshTokenKey
]
=
getLocalStorage
(
cacheKeys
.
refreshTokenKey
);
res
[
cacheKeys
.
ACCESS_TOKEN
]
=
getLocalStorage
(
cacheKeys
.
ACCESS_TOKEN
);
res
[
cacheKeys
.
REFRESH_TOKEN
]
=
getLocalStorage
(
cacheKeys
.
REFRESH_TOKEN
);
return
res
;
}
export
function
clearLoginToken
()
{
removeLocalStorage
(
cacheKeys
.
accessTokenKey
);
removeLocalStorage
(
cacheKeys
.
refreshTokenKey
);
removeLocalStorage
(
cacheKeys
.
ACCESS_TOKEN
);
removeLocalStorage
(
cacheKeys
.
REFRESH_TOKEN
);
}
export
function
getAccessToken
()
{
return
getLocalStorage
(
cacheKeys
.
accessTokenKey
);
return
getLocalStorage
(
cacheKeys
.
ACCESS_TOKEN
);
}
export
function
getRefreshToken
()
{
return
getLocalStorage
(
cacheKeys
.
REFRESH_TOKEN
);
}
///
...
...
@@ -56,4 +65,4 @@ function removeLocalStorage(key) {
}
catch
(
e
)
{
throw
new
Error
(
`localStorage 设置错误!
${
e
}
`
);
}
}
\ No newline at end of file
}
order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java
浏览文件 @
f46a4f70
...
...
@@ -13,6 +13,7 @@ import cn.iocoder.mall.order.application.vo.UsersCartDetailVO;
import
cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO
;
import
cn.iocoder.mall.promotion.api.CouponService
;
import
cn.iocoder.mall.promotion.api.bo.CouponCardAvailableBO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -144,6 +145,7 @@ public class UsersCartController {
}
@GetMapping
(
"/calc_sku_price"
)
@PermitAll
public
CommonResult
<
UsersCalcSkuPriceVO
>
calcSkuPrice
(
@RequestParam
(
"skuId"
)
Integer
skuId
)
{
// 计算 sku 的价格
CommonResult
<
CalcSkuPriceBO
>
calcSkuPriceResult
=
cartService
.
calcSkuPrice
(
skuId
);
...
...
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/OrderBO.java
浏览文件 @
f46a4f70
...
...
@@ -25,16 +25,32 @@ public class OrderBO implements Serializable {
* 用户编号
*/
private
Integer
userId
;
/**
* 物流id
*/
private
Integer
orderLogisticsId
;
/**
* 订单编号
*/
private
String
orderNo
;
/**
* 交易金额
* 购买(商品)总金额,单位:分
*/
private
Integer
buyPrice
;
/**
* 优惠总金额,单位:分。
*/
private
Integer
discountPrice
;
/**
* 物流金额 (分)
*/
private
Integer
logisticsPrice
;
/**
* 最终金额,单位:分
*
* buyPrice + logisticsPrice - discountPrice = presentPrice
*/
private
Integer
presentPrice
;
/**
* 实际已支付金额,单位:分
*
* 初始时,金额为 0 。等到支付成功后,会进行更新。
*/
private
Integer
payAmount
;
...
...
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/OrderInfoBO.java
浏览文件 @
f46a4f70
...
...
@@ -16,22 +16,39 @@ import java.util.Date;
@Accessors
(
chain
=
true
)
public
class
OrderInfoBO
implements
Serializable
{
/**
* id
*/
private
Integer
id
;
/**
* 订单编号
*/
private
String
orderNo
;
/**
*
价格(分)
*
购买(商品)总金额,单位:分
*/
private
Integer
p
rice
;
private
Integer
buyP
rice
;
/**
*
交易金额
*
优惠总金额,单位:分。
*/
private
Integer
payAmount
;
private
Integer
discountPrice
;
/**
* 物流金额 (分)
*/
private
Integer
logisticsPrice
;
/**
* 最终金额,单位:分
*
* buyPrice + logisticsPrice - discountPrice = presentPrice
*/
private
Integer
presentPrice
;
/**
* 实际已支付金额,单位:分
*
* 初始时,金额为 0 。等到支付成功后,会进行更新。
*/
private
Integer
payAmount
;
/**
* 付款时间(待发货)
*/
...
...
product/product-application/pom.xml
浏览文件 @
f46a4f70
...
...
@@ -85,6 +85,12 @@
<groupId>
io.springfox
</groupId>
<artifactId>
springfox-swagger-ui
</artifactId>
</dependency>
<dependency>
<groupId>
cn.iocoder.mall
</groupId>
<artifactId>
user-sdk
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
...
...
product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductCategoryController.java
浏览文件 @
f46a4f70
...
...
@@ -5,6 +5,7 @@ import cn.iocoder.mall.product.api.ProductCategoryService;
import
cn.iocoder.mall.product.api.bo.ProductCategoryBO
;
import
cn.iocoder.mall.product.application.convert.ProductCategoryConvert
;
import
cn.iocoder.mall.product.application.vo.users.UsersProductCategoryVO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -14,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.security.PermitAll
;
import
java.util.List
;
@RestController
...
...
product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/UsersProductSpuController.java
浏览文件 @
f46a4f70
...
...
@@ -7,6 +7,7 @@ import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
import
cn.iocoder.mall.product.application.convert.ProductSpuConvert
;
import
cn.iocoder.mall.product.application.vo.users.UsersProductSpuDetailVO
;
import
cn.iocoder.mall.product.application.vo.users.UsersProductSpuPageVO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -17,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.security.PermitAll
;
@RestController
@RequestMapping
(
"users/spu"
)
@Api
(
"商品 SPU + SKU"
)
...
...
promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersBannerController.java
浏览文件 @
f46a4f70
...
...
@@ -6,6 +6,7 @@ import cn.iocoder.mall.promotion.api.BannerService;
import
cn.iocoder.mall.promotion.api.bo.BannerBO
;
import
cn.iocoder.mall.promotion.application.convert.BannerConvert
;
import
cn.iocoder.mall.promotion.application.vo.users.UsersBannerVO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
...
...
@@ -13,7 +14,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.security.PermitAll
;
import
java.util.Comparator
;
import
java.util.List
;
...
...
promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java
浏览文件 @
f46a4f70
...
...
@@ -8,6 +8,7 @@ import cn.iocoder.mall.promotion.api.ProductRecommendService;
import
cn.iocoder.mall.promotion.api.bo.ProductRecommendBO
;
import
cn.iocoder.mall.promotion.application.convert.ProductRecommendConvert
;
import
cn.iocoder.mall.promotion.application.vo.users.UsersProductRecommendVO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
com.google.common.collect.HashMultimap
;
import
com.google.common.collect.Multimap
;
...
...
@@ -17,7 +18,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.security.PermitAll
;
import
java.util.Collection
;
import
java.util.Comparator
;
import
java.util.List
;
...
...
user/user-application/src/main/java/cn/iocoder/mall/user/application/controller/users/PassportController.java
浏览文件 @
f46a4f70
...
...
@@ -2,12 +2,13 @@ package cn.iocoder.mall.user.application.controller.users;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.user.application.convert.PassportConvert
;
import
cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO
;
import
cn.iocoder.mall.user.sdk.annotation.PermitAll
;
import
cn.iocoder.mall.user.api.MobileCodeService
;
import
cn.iocoder.mall.user.api.OAuth2Service
;
import
cn.iocoder.mall.user.api.UserService
;
import
cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO
;
import
cn.iocoder.mall.user.application.vo.users.MobileRegisterVO
;
import
cn.iocoder.mall.user.application.vo.users.
Users
MobileRegisterVO
;
import
com.alibaba.dubbo.config.annotation.Reference
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -44,8 +45,8 @@ public class PassportController {
@ApiImplicitParam
(
name
=
"mobile"
,
value
=
"手机号"
,
required
=
true
,
example
=
"15601691300"
),
@ApiImplicitParam
(
name
=
"code"
,
value
=
"验证码"
,
required
=
true
,
example
=
"9999"
)
})
public
CommonResult
<
MobileRegisterVO
>
mobileRegister
(
@RequestParam
(
"mobile"
)
String
mobile
,
@RequestParam
(
"code"
)
String
code
)
{
public
CommonResult
<
Users
MobileRegisterVO
>
mobileRegister
(
@RequestParam
(
"mobile"
)
String
mobile
,
@RequestParam
(
"code"
)
String
code
)
{
CommonResult
<
OAuth2AccessTokenBO
>
result
=
oauth2Service
.
getAccessToken
(
mobile
,
code
);
return
PassportConvert
.
INSTANCE
.
convert
(
result
);
}
...
...
@@ -74,7 +75,12 @@ public class PassportController {
return
null
;
}
// TODO 功能:刷新 token
@PermitAll
@PostMapping
(
"/refresh_token"
)
// TODO 功能:刷新 token
public
CommonResult
<
UsersAccessTokenVO
>
refreshToken
(
@RequestParam
(
"refreshToken"
)
String
refreshToken
)
{
CommonResult
<
OAuth2AccessTokenBO
>
result
=
oauth2Service
.
refreshToken
(
refreshToken
);
return
PassportConvert
.
INSTANCE
.
convert2
(
result
);
}
// TODO 功能:退出,销毁 token
}
\ No newline at end of file
}
user/user-application/src/main/java/cn/iocoder/mall/user/application/convert/PassportConvert.java
浏览文件 @
f46a4f70
...
...
@@ -2,7 +2,8 @@ package cn.iocoder.mall.user.application.convert;
import
cn.iocoder.common.framework.vo.CommonResult
;
import
cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO
;
import
cn.iocoder.mall.user.application.vo.users.MobileRegisterVO
;
import
cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO
;
import
cn.iocoder.mall.user.application.vo.users.UsersMobileRegisterVO
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.Mappings
;
import
org.mapstruct.factory.Mappers
;
...
...
@@ -13,9 +14,12 @@ public interface PassportConvert {
PassportConvert
INSTANCE
=
Mappers
.
getMapper
(
PassportConvert
.
class
);
@Mappings
({})
MobileRegisterVO
convert
(
OAuth2AccessTokenBO
oauth2AccessTokenBO
);
Users
MobileRegisterVO
convert
(
OAuth2AccessTokenBO
oauth2AccessTokenBO
);
@Mappings
({})
CommonResult
<
MobileRegisterVO
>
convert
(
CommonResult
<
OAuth2AccessTokenBO
>
oauth2AccessTokenBO
);
CommonResult
<
Users
MobileRegisterVO
>
convert
(
CommonResult
<
OAuth2AccessTokenBO
>
oauth2AccessTokenBO
);
}
\ No newline at end of file
@Mappings
({})
CommonResult
<
UsersAccessTokenVO
>
convert2
(
CommonResult
<
OAuth2AccessTokenBO
>
result
);
}
user/user-application/src/main/java/cn/iocoder/mall/user/application/vo/users/UsersAccessTokenVO.java
0 → 100644
浏览文件 @
f46a4f70
package
cn
.
iocoder
.
mall
.
user
.
application
.
vo
.
users
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
@ApiModel
(
"认证令牌 VO"
)
@Data
@Accessors
(
chain
=
true
)
public
class
UsersAccessTokenVO
{
@ApiModelProperty
(
value
=
"访问令牌"
,
required
=
true
,
example
=
"2e3d7635c15e47e997611707a237859f"
)
private
String
accessToken
;
@ApiModelProperty
(
value
=
"刷新令牌"
,
required
=
true
,
example
=
"d091e7c35bbb4313b0f557a6ef23d033"
)
private
String
refreshToken
;
@ApiModelProperty
(
value
=
"过期时间,单位:秒"
,
required
=
true
,
example
=
"2879"
)
private
Integer
expiresIn
;
}
user/user-application/src/main/java/cn/iocoder/mall/user/application/vo/users/MobileRegisterVO.java
→
user/user-application/src/main/java/cn/iocoder/mall/user/application/vo/users/
Users
MobileRegisterVO.java
浏览文件 @
f46a4f70
...
...
@@ -8,7 +8,7 @@ import lombok.experimental.Accessors;
@ApiModel
(
"手机注册结果 VO"
)
@Data
@Accessors
(
chain
=
true
)
public
class
MobileRegisterVO
{
public
class
Users
MobileRegisterVO
{
@ApiModelProperty
(
value
=
"访问令牌"
,
required
=
true
,
example
=
"2e3d7635c15e47e997611707a237859f"
)
private
String
accessToken
;
...
...
user/user-service-api/src/main/java/cn/iocoder/mall/user/api/OAuth2Service.java
浏览文件 @
f46a4f70
...
...
@@ -17,8 +17,8 @@ public interface OAuth2Service {
*/
CommonResult
<
OAuth2AuthenticationBO
>
checkToken
(
String
accessToken
);
// TODO @see 刷新 token
CommonResult
<
OAuth2AccessTokenBO
>
refreshToken
(
String
refreshToken
);
// TODO @see 移除 token
}
\ No newline at end of file
}
user/user-service-api/src/main/java/cn/iocoder/mall/user/api/constant/UserErrorCodeEnum.java
浏览文件 @
f46a4f70
...
...
@@ -12,10 +12,13 @@ public enum UserErrorCodeEnum {
OAUTH2_INVALID_GRANT_BAD_CREDENTIALS
(
1001001001
,
"密码不正确"
),
// 暂时没用到
OAUTH2_INVALID_GRANT_USERNAME_NOT_FOUND
(
1001001002
,
"账号不存在"
),
// 暂时没用到
OAUTH2_INVALID_GRANT
(
1001001010
,
""
),
// 预留
OAUTH_INVALID_TOKEN_NOT_FOUND
(
1001001011
,
"访问令牌不存在"
),
OAUTH_INVALID_TOKEN_EXPIRED
(
1001001012
,
"访问令牌已过期"
),
OAUTH_INVALID_TOKEN_INVALID
(
1001001013
,
"访问令牌已失效"
),
OAUTH_INVALID_TOKEN
(
1001001020
,
""
),
// 预留
OAUTH_INVALID_ACCESS_TOKEN_NOT_FOUND
(
1001001011
,
"访问令牌不存在"
),
OAUTH_INVALID_ACCESS_TOKEN_EXPIRED
(
1001001012
,
"访问令牌已过期"
),
OAUTH_INVALID_ACCESS_TOKEN_INVALID
(
1001001013
,
"访问令牌已失效"
),
OAUTH_INVALID_REFRESH_TOKEN
(
1001001020
,
""
),
// 预留
OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND
(
1001001021
,
"刷新令牌不存在"
),
OAUTH_INVALID_REFRESH_TOKEN_EXPIRED
(
1001001022
,
"访问令牌已过期"
),
OAUTH_INVALID_REFRESH_TOKEN_INVALID
(
1001001023
,
"刷新令牌已失效"
),
// ========== 用户模块 ==========
USER_MOBILE_NOT_REGISTERED
(
1001002000
,
"手机号未注册用户"
),
...
...
@@ -54,4 +57,4 @@ public enum UserErrorCodeEnum {
return
message
;
}
}
\ No newline at end of file
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dao/OAuth2AccessTokenMapper.java
浏览文件 @
f46a4f70
...
...
@@ -13,4 +13,6 @@ public interface OAuth2AccessTokenMapper {
void
updateToInvalidByUserId
(
@Param
(
"userId"
)
Integer
userId
);
}
\ No newline at end of file
void
updateToInvalidByRefreshToken
(
@Param
(
"refreshToken"
)
String
refreshToken
);
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dao/OAuth2RefreshTokenMapper.java
浏览文件 @
f46a4f70
...
...
@@ -11,4 +11,6 @@ public interface OAuth2RefreshTokenMapper {
void
updateToInvalidByUserId
(
@Param
(
"userId"
)
Integer
userId
);
}
\ No newline at end of file
OAuth2RefreshTokenDO
selectById
(
@Param
(
"id"
)
String
id
);
}
user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/service/OAuth2ServiceImpl.java
浏览文件 @
f46a4f70
...
...
@@ -82,18 +82,39 @@ public class OAuth2ServiceImpl implements OAuth2Service {
public
CommonResult
<
OAuth2AuthenticationBO
>
checkToken
(
String
accessToken
)
throws
ServiceException
{
OAuth2AccessTokenDO
accessTokenDO
=
oauth2AccessTokenMapper
.
selectByTokenId
(
accessToken
);
if
(
accessTokenDO
==
null
)
{
// 不存在
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_TOKEN_NOT_FOUND
.
getCode
());
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_
ACCESS_
TOKEN_NOT_FOUND
.
getCode
());
}
if
(
accessTokenDO
.
getExpiresTime
().
getTime
()
<
System
.
currentTimeMillis
())
{
// 已过期
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_TOKEN_EXPIRED
.
getCode
());
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_
ACCESS_
TOKEN_EXPIRED
.
getCode
());
}
if
(!
accessTokenDO
.
getValid
())
{
// 无效
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_TOKEN_INVALID
.
getCode
());
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_
ACCESS_
TOKEN_INVALID
.
getCode
());
}
// 转换返回
return
CommonResult
.
success
(
OAuth2Convert
.
INSTANCE
.
convertToAuthentication
(
accessTokenDO
));
}
@Override
public
CommonResult
<
OAuth2AccessTokenBO
>
refreshToken
(
String
refreshToken
)
{
OAuth2RefreshTokenDO
refreshTokenDO
=
oauth2RefreshTokenMapper
.
selectById
(
refreshToken
);
// 校验刷新令牌是否合法
if
(
refreshTokenDO
==
null
)
{
// 不存在
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND
.
getCode
());
}
if
(
refreshTokenDO
.
getExpiresTime
().
getTime
()
<
System
.
currentTimeMillis
())
{
// 已过期
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_REFRESH_TOKEN_EXPIRED
.
getCode
());
}
if
(!
refreshTokenDO
.
getValid
())
{
// 无效
return
ServiceExceptionUtil
.
error
(
UserErrorCodeEnum
.
OAUTH_INVALID_REFRESH_TOKEN_INVALID
.
getCode
());
}
// 标记 refreshToken 对应的 accessToken 都不合法
oauth2AccessTokenMapper
.
updateToInvalidByRefreshToken
(
refreshToken
);
// 创建访问令牌
OAuth2AccessTokenDO
oauth2AccessTokenDO
=
createOAuth2AccessToken
(
refreshTokenDO
.
getUserId
(),
refreshTokenDO
.
getId
());
// 转换返回
return
CommonResult
.
success
(
OAuth2Convert
.
INSTANCE
.
convertToAccessTokenWithExpiresIn
(
oauth2AccessTokenDO
));
}
/**
* 移除用户对应的 Token
*
...
...
@@ -134,4 +155,4 @@ public class OAuth2ServiceImpl implements OAuth2Service {
return
UUID
.
randomUUID
().
toString
().
replaceAll
(
"-"
,
""
);
}
}
\ No newline at end of file
}
user/user-service-impl/src/main/resources/mapper/OAuth2AccessTokenMapper.xml
浏览文件 @
f46a4f70
...
...
@@ -26,4 +26,11 @@
AND valid = 1
</update>
</mapper>
\ No newline at end of file
<update
id=
"updateToInvalidByRefreshToken"
parameterType=
"String"
>
UPDATE oauth2_access_token
SET valid = 0
WHERE refresh_token = #{refreshToken}
AND valid = 1
</update>
</mapper>
user/user-service-impl/src/main/resources/mapper/OAuth2RefreshTokenMapper.xml
浏览文件 @
f46a4f70
...
...
@@ -17,4 +17,11 @@
AND valid = 1
</update>
</mapper>
\ No newline at end of file
<select
id=
"selectById"
parameterType=
"String"
resultType=
"OAuth2RefreshTokenDO"
>
SELECT
id, user_id, valid, expires_time, create_time
FROM oauth2_refresh_token
WHERE id = #{id}
</select>
</mapper>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论