添加注册信息
parent
adb489a8e4
commit
e2c185ce66
33
pom.xml
33
pom.xml
|
@ -11,51 +11,62 @@
|
||||||
<version>3.6.3</version>
|
<version>3.6.3</version>
|
||||||
|
|
||||||
<artifactId>four-auth</artifactId>
|
<artifactId>four-auth</artifactId>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
four-auth认证授权
|
four-auth认证授权
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- SpringCloud Alibaba Nacos -->
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringCloud Alibaba Nacos Config -->
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringCloud Alibaba Sentinel -->
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringBoot Web -->
|
<!-- SpringBoot Web -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringBoot Actuator -->
|
<!-- SpringBoot Actuator -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- RuoYi Common Security-->
|
<!-- RuoYi Common Security-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.four</groupId>
|
<groupId>com.four</groupId>
|
||||||
<artifactId>four-common-security</artifactId>
|
<artifactId>four-common-security</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.four</groupId>
|
||||||
|
<artifactId>four-common-duck</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 邮箱依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>${project.artifactId}</finalName>
|
<finalName>${project.artifactId}</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -72,5 +83,5 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package com.four.auth.controller;
|
package com.four.auth.controller;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.four.auth.form.HealthRegisterBody;
|
||||||
|
import com.four.auth.service.SysMailService;
|
||||||
|
import com.four.common.duck.interrogation.RegistrationInformation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import com.four.auth.form.LoginBody;
|
import com.four.auth.form.LoginBody;
|
||||||
import com.four.auth.form.RegisterBody;
|
import com.four.auth.form.RegisterBody;
|
||||||
import com.four.auth.service.SysLoginService;
|
import com.four.auth.service.SysLoginService;
|
||||||
|
@ -32,6 +33,9 @@ public class TokenController
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysLoginService sysLoginService;
|
private SysLoginService sysLoginService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysMailService sysMailService;
|
||||||
|
|
||||||
@PostMapping("login")
|
@PostMapping("login")
|
||||||
public R<?> login(@RequestBody LoginBody form)
|
public R<?> login(@RequestBody LoginBody form)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +81,8 @@ public class TokenController
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("register")
|
@PostMapping("register")
|
||||||
public R<?> register(@RequestBody RegisterBody registerBody)
|
public R<?> register(@RequestBody RegisterBody registerBody)
|
||||||
{
|
{
|
||||||
|
@ -84,4 +90,23 @@ public class TokenController
|
||||||
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
|
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("healthRegisterBody")
|
||||||
|
public R<?> healthRegisterBody(@RequestBody HealthRegisterBody healthRegisterBody){
|
||||||
|
|
||||||
|
sysMailService.verifyCode(healthRegisterBody.getEmail(),healthRegisterBody.getCode());
|
||||||
|
|
||||||
|
sysLoginService.healthRegister(healthRegisterBody);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/sendCode/{email}")
|
||||||
|
public R<?> sendCode(@PathVariable String email){
|
||||||
|
sysMailService.sendCode(email);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
package com.four.auth.form;
|
||||||
|
|
||||||
|
public class HealthRegisterBody extends LoginBody{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邀请码
|
||||||
|
* */
|
||||||
|
private String invitationCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 真实姓名
|
||||||
|
* */
|
||||||
|
private String realName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人简历
|
||||||
|
* */
|
||||||
|
private String personalResume;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 形象地址
|
||||||
|
* */
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属医院
|
||||||
|
*/
|
||||||
|
private String affiliatedHospital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 擅长领域
|
||||||
|
* */
|
||||||
|
private String areaExpertise;
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
* */
|
||||||
|
private String nickName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 职称id
|
||||||
|
* */
|
||||||
|
private Long professionalTitleDoctorId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
* */
|
||||||
|
private String sex;
|
||||||
|
|
||||||
|
public HealthRegisterBody(String invitationCode, String realName, String personalResume, String avatar, String affiliatedHospital, String nickName, Long professionalTitleDoctorId, String sex) {
|
||||||
|
this.invitationCode = invitationCode;
|
||||||
|
this.realName = realName;
|
||||||
|
this.personalResume = personalResume;
|
||||||
|
this.avatar = avatar;
|
||||||
|
this.affiliatedHospital = affiliatedHospital;
|
||||||
|
this.nickName = nickName;
|
||||||
|
this.professionalTitleDoctorId = professionalTitleDoctorId;
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HealthRegisterBody{" +
|
||||||
|
"invitationCode='" + invitationCode + '\'' +
|
||||||
|
", realName='" + realName + '\'' +
|
||||||
|
", personalResume='" + personalResume + '\'' +
|
||||||
|
", avatar='" + avatar + '\'' +
|
||||||
|
", affiliatedHospital='" + affiliatedHospital + '\'' +
|
||||||
|
", nickName='" + nickName + '\'' +
|
||||||
|
", professionalTitleDoctorId=" + professionalTitleDoctorId +
|
||||||
|
", sex='" + sex + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public HealthRegisterBody() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Long getProfessionalTitleDoctorId() {
|
||||||
|
return professionalTitleDoctorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfessionalTitleDoctorId(Long professionalTitleDoctorId) {
|
||||||
|
this.professionalTitleDoctorId = professionalTitleDoctorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSex(String sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAreaExpertise() {
|
||||||
|
return areaExpertise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAreaExpertise(String areaExpertise) {
|
||||||
|
this.areaExpertise = areaExpertise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvitationCode(String invitationCode) {
|
||||||
|
this.invitationCode = invitationCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealName(String realName) {
|
||||||
|
this.realName = realName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonalResume(String personalResume) {
|
||||||
|
this.personalResume = personalResume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar(String avatar) {
|
||||||
|
this.avatar = avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAffiliatedHospital(String affiliatedHospital) {
|
||||||
|
this.affiliatedHospital = affiliatedHospital;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickName(String nickName) {
|
||||||
|
this.nickName = nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInvitationCode() {
|
||||||
|
return invitationCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealName() {
|
||||||
|
return realName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersonalResume() {
|
||||||
|
return personalResume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvatar() {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAffiliatedHospital() {
|
||||||
|
return affiliatedHospital;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName() {
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,12 +18,40 @@ public class LoginBody
|
||||||
*/
|
*/
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
|
||||||
|
private Long roleId;
|
||||||
|
private String code;
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername()
|
||||||
{
|
{
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getRoleId() {
|
||||||
|
return roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoleId(Long roleId) {
|
||||||
|
this.roleId = roleId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.four.auth.service;
|
package com.four.auth.service;
|
||||||
|
|
||||||
|
import com.four.auth.form.HealthRegisterBody;
|
||||||
|
import com.four.auth.form.RegisterBody;
|
||||||
import org.apache.catalina.Contained;
|
import org.apache.catalina.Contained;
|
||||||
import org.apache.catalina.User;
|
import org.apache.catalina.User;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -19,6 +21,7 @@ import com.four.common.security.utils.SecurityUtils;
|
||||||
import com.four.system.api.RemoteUserService;
|
import com.four.system.api.RemoteUserService;
|
||||||
import com.four.system.api.domain.SysUser;
|
import com.four.system.api.domain.SysUser;
|
||||||
import com.four.system.api.model.LoginUser;
|
import com.four.system.api.model.LoginUser;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
@ -198,4 +201,57 @@ public class SysLoginService
|
||||||
recordLogService.recordLogininfor(userName,Constants.LOGIN_SUCCESS,"登录成功");
|
recordLogService.recordLogininfor(userName,Constants.LOGIN_SUCCESS,"登录成功");
|
||||||
return dataInfo;
|
return dataInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void healthRegister(HealthRegisterBody healthRegisterBody) {
|
||||||
|
|
||||||
|
if(StringUtils.isAllBlank(healthRegisterBody.getUsername(),healthRegisterBody.getPassword())){
|
||||||
|
throw new ServiceException("用户/密码必须填写");
|
||||||
|
}
|
||||||
|
if(healthRegisterBody.getPassword().length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| healthRegisterBody.getPassword().length()> UserConstants.PASSWORD_MAX_LENGTH){
|
||||||
|
throw new ServiceException("密码长度必须在5到20个字符");
|
||||||
|
}
|
||||||
|
SysUser sysUser = new SysUser();
|
||||||
|
sysUser.setRoleId(healthRegisterBody.getRoleId());
|
||||||
|
sysUser.setUserName(healthRegisterBody.getUserName());
|
||||||
|
sysUser.setEmail(healthRegisterBody.getEmail());
|
||||||
|
sysUser.setNickName(healthRegisterBody.getNickName());
|
||||||
|
sysUser.setPassword(SecurityUtils.encryptPassword(healthRegisterBody.getPassword()));
|
||||||
|
|
||||||
|
if(healthRegisterBody.getRoleId() == 100){
|
||||||
|
|
||||||
|
//职称Id
|
||||||
|
sysUser.setRoleId(healthRegisterBody.getRoleId());
|
||||||
|
|
||||||
|
//真实姓名
|
||||||
|
sysUser.setNickName(healthRegisterBody.getNickName());
|
||||||
|
|
||||||
|
//个人简历
|
||||||
|
sysUser.setPersonalResume(healthRegisterBody.getPersonalResume());
|
||||||
|
|
||||||
|
//所属医院
|
||||||
|
sysUser.setAffiliatedHospital(healthRegisterBody.getAffiliatedHospital());
|
||||||
|
|
||||||
|
//area_expertise
|
||||||
|
sysUser.setAreaExpertise(healthRegisterBody.getAreaExpertise());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(healthRegisterBody.getRoleId() == 101){
|
||||||
|
/**
|
||||||
|
* 邀请码
|
||||||
|
* */
|
||||||
|
sysUser.setInvitationCode(healthRegisterBody.getInvitationCode());
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
* */
|
||||||
|
sysUser.setSex(healthRegisterBody.getSex());
|
||||||
|
}
|
||||||
|
System.out.println(sysUser);
|
||||||
|
R<?> registerResult = remoteUserService.healthRegister(sysUser, SecurityConstants.INNER);
|
||||||
|
if(R.FAIL == registerResult.getCode()){
|
||||||
|
throw new ServiceException(registerResult.getMsg());
|
||||||
|
}
|
||||||
|
recordLogService.recordLogininfor(healthRegisterBody.getEmail(), Constants.REGISTER,"注册成功");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.four.auth.service;
|
||||||
|
|
||||||
|
import com.four.common.core.constant.SecurityConstants;
|
||||||
|
import com.four.common.core.domain.R;
|
||||||
|
import com.four.common.core.exception.ServiceException;
|
||||||
|
import com.four.common.core.utils.StringUtils;
|
||||||
|
import com.four.common.redis.service.RedisService;
|
||||||
|
import com.four.system.api.RemoteUserService;
|
||||||
|
import com.four.system.api.model.LoginUser;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SysMailService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JavaMailSender javaMailSender;
|
||||||
|
public void verifyCode(String email, String code) {
|
||||||
|
if(StringUtils.isAnyBlank(email) || StringUtils.isAllBlank(code)){
|
||||||
|
throw new ServiceException("邮箱验证码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断缓存中是否存在验证码
|
||||||
|
String verifyCode = redisService.getCacheObject(email);
|
||||||
|
if(StringUtils.isAllBlank(verifyCode)){
|
||||||
|
throw new ServiceException("请先获取验证码");
|
||||||
|
}
|
||||||
|
|
||||||
|
//验证码校验
|
||||||
|
if(!code.equals(verifyCode)){
|
||||||
|
throw new ServiceException("验证码错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendCode(String email) {
|
||||||
|
if(StringUtils.isAllBlank(email)){
|
||||||
|
throw new ServiceException("邮箱为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String verifyCode = redisService.getCacheObject(email);
|
||||||
|
if(!StringUtils.isAnyBlank(verifyCode)){
|
||||||
|
throw new ServiceException("验证码已发送,请稍后重试");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
R<LoginUser> userInfoByEmail = remoteUserService.getUserInfoByEmail(email, SecurityConstants.INNER);
|
||||||
|
if(!StringUtils.isNull(userInfoByEmail.getData())){
|
||||||
|
throw new ServiceException("该邮箱:" + email + "已被注册");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
verifyCode = RandomStringUtils.randomNumeric(4);
|
||||||
|
|
||||||
|
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||||
|
try {
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||||
|
helper.setFrom("1733802689@qq.com");
|
||||||
|
helper.setText(verifyCode);
|
||||||
|
helper.setTo(email);
|
||||||
|
helper.setSubject("我来发邮件来了");
|
||||||
|
javaMailSender.send(mimeMessage);
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
throw new ServiceException("邮箱服务出错了:{}" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
redisService.setCacheObject(email,verifyCode,5L, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,3 +25,14 @@ spring:
|
||||||
# 共享配置
|
# 共享配置
|
||||||
shared-configs:
|
shared-configs:
|
||||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
mail:
|
||||||
|
host: smtp.qq.com
|
||||||
|
port: 587
|
||||||
|
username: 1733802689@qq.com
|
||||||
|
password: lqttdbsoccpvbgjj
|
||||||
|
defaultencoding: UTF-8
|
||||||
|
properties:
|
||||||
|
mail:
|
||||||
|
smtp:
|
||||||
|
socketFactoryClass: javax.net.ssl.SSLSocketFactory
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue