Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
O
on-site-service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
external
on-site-service
Commits
b6f136eb
Commit
b6f136eb
authored
Jul 04, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: 小程序登录
parent
239f7354
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
365 additions
and
22 deletions
+365
-22
WeiXinController.java
...iteservice/miniapp/controller/weixn/WeiXinController.java
+71
-0
LoginDTO.java
.../onsiteservice/miniapp/controller/weixn/dto/LoginDTO.java
+46
-0
WxEncryptDTO.java
...iteservice/miniapp/controller/weixn/dto/WxEncryptDTO.java
+32
-0
UserService.java
...a/com/onsiteservice/miniapp/service/user/UserService.java
+11
-0
WeiXinService.java
...m/onsiteservice/miniapp/service/weixin/WeiXinService.java
+166
-0
MiniQrCodeDTO.java
...siteservice/miniapp/service/weixin/dto/MiniQrCodeDTO.java
+34
-0
application-dev.yaml
mini-app/src/main/resources/application-dev.yaml
+2
-2
application-prod.yaml
mini-app/src/main/resources/application-prod.yaml
+1
-1
application-sit.yaml
mini-app/src/main/resources/application-sit.yaml
+0
-8
application-test.yaml
mini-app/src/main/resources/application-test.yaml
+0
-9
application.yaml
mini-app/src/main/resources/application.yaml
+2
-2
No files found.
mini-app/src/main/java/com/onsiteservice/miniapp/controller/weixn/WeiXinController.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
controller
.
weixn
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
com.github.xiaoymin.knife4j.annotations.ApiSupport
;
import
com.onsiteservice.common.annotation.user.CurrentUserId
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.service.weixin.WeiXinService
;
import
com.onsiteservice.miniapp.service.weixin.dto.MiniQrCodeDTO
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.NonNull
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.annotation.Resource
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
/**
* 微信相关Controller
*/
@ApiSupport
(
order
=
2
)
@Api
(
tags
=
"微信小程序"
)
@RestController
@RequestMapping
(
"/weixin"
)
@Validated
@Slf4j
public
class
WeiXinController
{
@Resource
private
WxMaService
wxMaService
;
@Resource
private
WeiXinService
weiXinService
;
/**
* 微信登录
*/
@ApiOperation
(
value
=
"微信登录"
,
notes
=
"作者: 潘维吉"
)
@PostMapping
(
"/login"
)
public
Result
login
(
@RequestBody
@Validated
LoginDTO
loginDTO
)
{
return
weiXinService
.
userLogin
(
loginDTO
);
}
/**
* 获取微信用户绑定手机号信息
*/
@ApiOperation
(
value
=
"获取微信手机号"
,
notes
=
"作者: 潘维吉"
)
@PostMapping
(
"/phone"
)
public
Result
getPhone
(
@RequestBody
@Validated
WxEncryptDTO
wxEncryptDTO
,
@CurrentUserId
Long
userId
)
{
return
success
(
weiXinService
.
getPhone
(
wxEncryptDTO
,
userId
),
"获取用户绑定手机号信息成功"
);
}
/**
* 获取微信小程序码
* 文档: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
*/
@ApiOperation
(
value
=
"获取微信小程序码"
,
notes
=
"作者: 潘维吉"
)
@PostMapping
(
"/qr-code"
)
public
Result
getQrCode
(
@RequestBody
@NonNull
@Validated
MiniQrCodeDTO
miniQrCodeDTO
)
{
return
weiXinService
.
getQrCode
(
miniQrCodeDTO
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/controller/weixn/dto/LoginDTO.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
controller
.
weixn
.
dto
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
import
javax.validation.constraints.NotBlank
;
/**
* @author 潘维吉
* @date 2019-3-20 13:36
* 微信登录参数
* DTO 数据传输对象类 Bean是跟数据库有关的实体类,而DTO是与数据库无关的数据,只是为了数据显示时创建的中间层用于数据展示的
* DTO通常用于不同层(UI层、服务层或者域模型层)直接的数据传输,以隔离不同层,降低层间耦合
* DTO类来继承entity实体类,在DTO类里放一些业务字段,并提供get、set方法
* 当我们在业务逻辑层或者交互层用到一些数据库中不存在的字段时,我们就需要在DTO类里放这些字段
* 这些字段的意义就相当于一些经处理过的数据库字段,实质意义就是方便数据交互,提高效率
*/
@ApiModel
(
"微信登录参数"
)
@Getter
@Setter
@ToString
public
class
LoginDTO
{
@ApiModelProperty
(
value
=
"微信登录code"
,
required
=
true
)
@NotBlank
(
message
=
"微信code不能为空"
)
private
String
code
;
/* @ApiModelProperty(value = "微信登录用户信息")
@NotNull(message = "用户信息userInfo不能为null")
private Map userInfo;*/
@ApiModelProperty
(
value
=
"服务端获取数据 不可泄露给前端 存在风险"
,
hidden
=
true
)
private
String
sessionKey
;
private
String
encryptedData
;
private
String
iv
;
private
String
signature
;
private
String
rawData
;
}
mini-app/src/main/java/com/onsiteservice/miniapp/controller/weixn/dto/WxEncryptDTO.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
controller
.
weixn
.
dto
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
import
javax.validation.constraints.NotBlank
;
/**
* @author 潘维吉
* @date 2019-3-20 13:36
* 微信解密参数
*/
@ApiModel
(
description
=
"微信解密参数"
)
@Getter
@Setter
@ToString
public
class
WxEncryptDTO
{
@ApiModelProperty
(
value
=
"微信登录code"
)
@NotBlank
(
message
=
"微信code不能为空"
)
private
String
code
;
@ApiModelProperty
(
value
=
"服务端数据 不可泄露给前端 存在风险"
,
hidden
=
true
)
private
String
sessionKey
;
private
String
encryptedData
;
private
String
iv
;
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/user/UserService.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
service
.
user
;
import
com.onsiteservice.dao.common.AbstractMapper
;
import
com.onsiteservice.entity.user.User
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
@Service
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
class
UserService
extends
AbstractMapper
<
User
>
{
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/WeiXinService.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor
;
import
cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult
;
import
cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo
;
import
cn.binarywang.wx.miniapp.bean.WxMaUserInfo
;
import
com.google.common.collect.ImmutableMap
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
import
com.onsiteservice.entity.user.User
;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.service.user.UserService
;
import
com.onsiteservice.miniapp.service.weixin.dto.MiniQrCodeDTO
;
import
io.micrometer.core.instrument.util.StringUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
me.chanjar.weixin.common.error.WxErrorException
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
java.util.Map
;
import
java.util.Optional
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
fail
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
/**
* @author 潘维吉
* @date 2021-09-14 08:33
* 微信服务类
*/
@Slf4j
@Service
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
class
WeiXinService
{
@Resource
private
WxMaService
wxMaService
;
@Resource
private
UserService
userService
;
/**
* 用户信息解密 登录或注册一体
*/
public
Result
userLogin
(
LoginDTO
loginDTO
)
{
try
{
WxMaJscode2SessionResult
sessionResult
=
null
;
try
{
// 获取openid、unionid、session_key等
sessionResult
=
wxMaService
.
getUserService
().
getSessionInfo
(
loginDTO
.
getCode
());
}
catch
(
WxErrorException
e
)
{
throw
new
ServiceException
(
"微信小程序登录失败:"
+
e
.
getMessage
());
}
String
unionId
=
sessionResult
.
getUnionid
();
// unionId需要先在微信开放平台绑定平台
String
openId
=
sessionResult
.
getOpenid
();
String
sessionKey
=
sessionResult
.
getSessionKey
();
// 用户信息校验 wx.login重复登录 SessionKey可能失效
if
(!
wxMaService
.
getUserService
().
checkUserInfo
(
sessionKey
,
loginDTO
.
getRawData
(),
loginDTO
.
getSignature
()))
{
return
fail
(
"微信用户信息校验失败"
);
}
if
(
StringUtils
.
isBlank
(
unionId
))
{
return
fail
(
"unionId无法获取,登录失败"
);
}
// 解密用户信息
WxMaUserInfo
userInfo
=
wxMaService
.
getUserService
().
getUserInfo
(
sessionKey
,
loginDTO
.
getEncryptedData
(),
loginDTO
.
getIv
());
String
nickName
=
userInfo
.
getNickName
();
String
avatarUrl
=
userInfo
.
getAvatarUrl
();
// 是否存在用户
Optional
<
User
>
hasUser
=
Optional
.
ofNullable
(
userService
.
selectOneByProperty
(
"unionId"
,
unionId
));
if
(
hasUser
.
isPresent
())
{
User
user
=
hasUser
.
get
();
user
.
setNickName
(
nickName
);
user
.
setAvatar
(
avatarUrl
);
userService
.
updateByPrimaryKeySelective
(
user
);
// 关联导入IM账号
return
toLogin
(
user
,
user
.
getId
(),
"登录成功"
);
}
else
{
// 新增用户
User
user
=
User
.
builder
()
.
userName
(
nickName
)
.
nickName
(
nickName
)
.
unionId
(
unionId
)
.
openId
(
openId
)
.
avatar
(
avatarUrl
)
.
sex
(
Integer
.
parseInt
(
userInfo
.
getGender
()))
.
build
();
userService
.
insertSelective
(
user
);
return
toLogin
(
user
,
user
.
getId
(),
"注册成功"
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"登录失败:"
+
e
.
getMessage
());
throw
new
ServiceException
(
"登录失败"
);
}
}
/**
* 登录 通用代码重构封装
*/
private
Result
toLogin
(
User
user
,
Long
userId
,
String
msg
)
{
//生成一个token,保存用户登录状态
String
jwtToken
=
JwtManager
.
createToken
(
Map
.
of
(
JwtManager
.
USER_ID
,
userId
));
Map
<
String
,
Object
>
map
=
ImmutableMap
.
of
(
"token"
,
jwtToken
,
"userId"
,
userId
,
"userInfo"
,
user
);
return
success
(
map
,
msg
);
}
/**
* 获取微信用户绑定手机号信息
*/
public
WxMaPhoneNumberInfo
getPhone
(
WxEncryptDTO
wxEncryptDTO
,
Long
userId
)
{
WxMaJscode2SessionResult
json
=
null
;
try
{
json
=
wxMaService
.
getUserService
().
getSessionInfo
(
wxEncryptDTO
.
getCode
());
}
catch
(
WxErrorException
e
)
{
throw
new
ServiceException
(
"微信小程序异常:"
+
e
.
getMessage
());
}
wxEncryptDTO
.
setSessionKey
(
json
.
getSessionKey
());
// 解密手机号
try
{
WxMaPhoneNumberInfo
phoneInfo
=
wxMaService
.
getUserService
().
getPhoneNoInfo
(
wxEncryptDTO
.
getSessionKey
(),
wxEncryptDTO
.
getEncryptedData
(),
wxEncryptDTO
.
getIv
());
updatePhone
(
userId
,
phoneInfo
.
getPhoneNumber
());
return
phoneInfo
;
}
catch
(
Exception
e
)
{
log
.
error
(
"获取微信手机号失败:"
+
e
.
getMessage
());
throw
new
ServiceException
(
"获取微信手机号失败,请重试"
);
}
}
/**
* 获取微信小程序码
*/
public
Result
getQrCode
(
MiniQrCodeDTO
miniQrCodeDTO
)
{
try
{
// 获取base64数据
byte
[]
qrCode
=
wxMaService
.
getQrcodeService
().
createWxaCodeUnlimitBytes
(
miniQrCodeDTO
.
getScene
(),
miniQrCodeDTO
.
getPath
(),
miniQrCodeDTO
.
getWidth
(),
false
,
new
WxMaCodeLineColor
(
"0"
,
"0"
,
"0"
),
false
);
return
success
(
qrCode
,
"获取微信小程序码成功"
);
}
catch
(
Exception
e
)
{
throw
new
ServiceException
(
"获取微信小程序码失败"
);
}
}
/**
* 更新用户手机号
*/
private
void
updatePhone
(
Long
userId
,
String
phoneNumber
)
{
// 更新用户手机号
User
user
=
userService
.
selectByPrimaryKey
(
userId
);
user
.
setPhone
(
phoneNumber
);
userService
.
updateByPrimaryKeySelective
(
user
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/dto/MiniQrCodeDTO.java
0 → 100644
View file @
b6f136eb
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
dto
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
import
javax.validation.constraints.NotBlank
;
import
java.io.Serializable
;
/**
* @author 潘维吉
* @date 2021/10/9 17:09
* @email 406798106@qq.com
* @description
*/
@ApiModel
(
"微信生成小程序码参数"
)
@Getter
@Setter
@ToString
public
class
MiniQrCodeDTO
implements
Serializable
{
@ApiModelProperty
(
value
=
"场景(编码的路径参数 不加?分号)"
,
required
=
true
)
@NotBlank
(
message
=
"场景不能为空"
)
private
String
scene
;
@ApiModelProperty
(
value
=
"已经发布的小程序存在的页面路径(最前面不要填加 /, 不能携带参数, 不填默认跳主页面)"
)
private
String
path
;
@ApiModelProperty
(
value
=
"二维码的宽度(单位 px, 最小 280px, 最大 1280px 默认430px)"
)
private
Integer
width
;
}
mini-app/src/main/resources/application-dev.yaml
View file @
b6f136eb
...
...
@@ -2,8 +2,8 @@
spring
:
profiles
:
include
:
-
property-sales-ruchen-
common-dev
-
common-dev
logging
:
level
:
com.
property.sales.
app.mapper
:
debug
com.
onsiteservice.mini
app.mapper
:
debug
mini-app/src/main/resources/application-prod.yaml
View file @
b6f136eb
...
...
@@ -2,7 +2,7 @@
spring
:
profiles
:
include
:
-
property-sales-ruchen-
common-prod
-
common-prod
logging
:
config
:
classpath:logback-spring-prod.xml
mini-app/src/main/resources/application-sit.yaml
deleted
100644 → 0
View file @
239f7354
# 联调环境配置
spring
:
profiles
:
include
:
-
property-sales-ruchen-common-sit
#logging:
# config: classpath:logback-spring-sit.xml
mini-app/src/main/resources/application-test.yaml
deleted
100644 → 0
View file @
239f7354
# 测试环境配置
spring
:
profiles
:
include
:
-
property-sales-ruchen-common-test
mini-app/src/main/resources/application.yaml
View file @
b6f136eb
# 所有环境通用的配置
server
:
port
:
8080
port
:
9261
# 所有自定义项目工程配置值 在project下配置
project
:
...
...
@@ -18,7 +18,7 @@ project:
spring
:
profiles
:
include
:
-
onsite-service-
common
-
common
application
:
name
:
onsite-service-mini-app
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment