feat: 添加注册功能

This commit is contained in:
橙子
2023-03-28 22:23:00 +08:00
parent 2ff8aef1bf
commit 5458819ef5
20 changed files with 299 additions and 28 deletions

View File

@@ -19,9 +19,16 @@ export function login(username, password, code, uuid) {
} }
// 注册方法 // 注册方法
export function register(data) { export function register(userName,password,phone,code,uuid) {
const data = {
userName,
password,
phone,
code,
uuid
}
return request({ return request({
url: '/register', url: '/account/register',
headers: { headers: {
isToken: false isToken: false
}, },

View File

@@ -1,4 +1,4 @@
import { login, logout, getInfo } from '@/apis/accountApi' import { login, logout, getInfo,register } from '@/apis/accountApi'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
const useUserStore = defineStore('user', const useUserStore = defineStore('user',
@@ -75,7 +75,22 @@ const useUserStore = defineStore('user',
reject(error) reject(error)
}) })
}) })
} },
// 注册
register(userInfo) {
const userName = userInfo.userName.trim()
const password = userInfo.password.trim()
const phone = userInfo.phone;
const uuid = userInfo.uuid;
const code=userInfo.code;
return new Promise((resolve, reject) => {
register(userName,password,phone,code,uuid).then(response => {
resolve(response);
}).catch(error => {
reject(error)
})
})
},
}, },
}) })

View File

@@ -3,24 +3,27 @@
<h1>{{configStore.name}}-登录</h1> <h1>{{configStore.name}}-登录</h1>
<div class="login-form"> <div class="login-form">
<div class="username form-item"> <div class="username form-item">
<span>使用邮箱或者手机号</span> <span>使用账号或者手机号</span>
<input type="text" class="input-item" v-model="loginForm.userName"> <input type="text" class="input-item" v-model="loginForm.userName">
</div> </div>
<div class="password form-item"> <div class="password form-item">
<span>密码</span> <span>密码</span>
<input type="password" class="input-item" v-model="loginForm.password"> <input type="password" class="input-item" v-model="loginForm.password">
</div> </div>
<RouterLink to="/register" > 没有账号前往注册</RouterLink>
<button class="login-btn" @click="login"> </button> <button class="login-btn" @click="login"> </button>
<button class="login-btn" @click="guestlogin">游客临时登录</button> <button class="login-btn" @click="guestlogin">游客临时登录</button>
</div> </div>
<RouterLink to="/register"> 没有账号前往注册</RouterLink>
<div class="divider"> <div class="divider">
<span class="line"></span> <span class="line"></span>
<span class="divider-text">其他方式登录</span> <span class="divider-text">其他方式登录</span>
<span class="line"></span> <span class="line"></span>
</div> </div>
<div class="other-login-wrapper"> <div class="other-login-wrapper">
<div class="other-login-item"> <div class="other-login-item">
<img src="@/assets/login_images/QQ.png" alt=""> <img src="@/assets/login_images/QQ.png" alt="">

View File

@@ -4,17 +4,21 @@
<div class="login-form"> <div class="login-form">
<div class="username form-item"> <div class="username form-item">
<span>登录账号</span> <span>登录账号</span>
<input type="text" class="input-item" v-model="loginForm.userName"> <input type="text" class="input-item" v-model="registerForm.userName">
</div> </div>
<div class="username form-item"> <div class="username form-item">
<span>手机号</span> <span>手机号</span>
<input type="text" class="input-item" v-model="loginForm.userName"> <input style="width: 70%;" type="text" class="input-item" v-model="registerForm.phone">
<button v-if="!isSendCaptcha" style="width: 30%;background-color: #C14949;" class="login-btn" @click="captcha" >验证码</button>
<button v-else style="width: 30%;background-color:#F0F2F5;" class="login-btn" >已发送</button>
</div> </div>
<div class="password form-item"> <div class="password form-item">
<span>密码</span> <span>密码</span>
<input type="password" class="input-item" v-model="loginForm.password"> <input type="password" class="input-item" v-model="registerForm.password">
</div> </div>
<button class="login-btn" @click="login">注册</button> <RouterLink to="/login" > 已有账号前往登录</RouterLink>
<button class="login-btn" @click="register">注册</button>
</div> </div>
<div class="divider"> <div class="divider">
<span class="line"></span> <span class="line"></span>
@@ -32,7 +36,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import { reactive ,ref} from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import useUserStore from '@/stores/user.js' import useUserStore from '@/stores/user.js'
import useConfigStore from "@/stores/config"; import useConfigStore from "@/stores/config";
@@ -40,24 +44,34 @@ const configStore= useConfigStore();
const userStore = useUserStore(); const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const loginForm = reactive({ const registerForm = reactive({
userName: "", userName: "",
password: "", password: "",
uuid: "", uuid: "",
code: "" code: ""
}) })
const login = async () => { const isSendCaptcha=ref(false)
const response = await userStore.login(loginForm).catch((e) => {
loginForm.password = ""; //验证码
const captcha=async()=>{
isSendCaptcha.value=true;
}
const register = async () => {
const response = await userStore.register(registerForm).catch((e) => {
registerForm.userName = "";
registerForm.password = "";
}); });
//成功
if (response!=undefined) { if (response!=undefined) {
ElMessage({ ElMessage({
message: `您好${loginForm.userName},登录成功`, message: `恭喜!${registerForm.userName}注册成功!请登录!`,
type: 'success', type: 'success',
}) })
const redirect = route.query?.redirect ?? '/index' const redirect = route.query?.redirect ?? '/login'
router.push(redirect) router.push(redirect)
} }

View File

@@ -27,7 +27,7 @@ namespace Yi.Framework.Core.Sqlsugar.Extensions
//使用上下文对象 //使用上下文对象
public static void AddDbSqlsugarContextServer(this IServiceCollection services) public static void AddDbSqlsugarContextServer(this IServiceCollection services)
{ {
services.AddTransient<ISqlSugarClient>(x => x.GetRequiredService<SqlSugarDbContext>().SqlSugarClient); services.AddSingleton<ISqlSugarClient>(x => x.GetRequiredService<SqlSugarDbContext>().SqlSugarClient);
services.AddSingleton<SqlSugarDbContext>(); services.AddSingleton<SqlSugarDbContext>();
} }

View File

@@ -57,7 +57,7 @@ namespace Yi.Framework.Core.Sqlsugar
}); });
} }
#endregion #endregion
SqlSugarClient = new SqlSugarClient(new ConnectionConfig() SqlSugarClient = new SqlSugarScope(new ConnectionConfig()
{ {
//准备添加分表分库 //准备添加分表分库
DbType = dbConnOptions.DbType ?? DbType.Sqlite, DbType = dbConnOptions.DbType ?? DbType.Sqlite,

View File

@@ -14,9 +14,9 @@
"DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle" ], "DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle" ],
"DbConnOptions": { "DbConnOptions": {
//"Url": "DataSource=yi-sqlsugar-dev.db", "Url": "DataSource=yi-sqlsugar-dev.db",
"Url": "server=106.52.94.217;port=3306;database=yi-bbs-dev;user id=root;password=Qz52013142020.", //"Url": "server=106.52.94.217;port=3306;database=yi-bbs-dev;user id=root;password=Qz52013142020.",
"DbType": "Mysql", "DbType": "Sqlite",
"EnabledDbSeed": true, "EnabledDbSeed": true,
"EnabledReadWrite": false, "EnabledReadWrite": false,
"EnabledCodeFirst": true, "EnabledCodeFirst": true,

View File

@@ -14,9 +14,9 @@
"DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle" ], "DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle" ],
"DbConnOptions": { "DbConnOptions": {
//"Url": "DataSource=yi-sqlsugar-dev.db", "Url": "DataSource=yi-sqlsugar-dev.db",
"Url": "server=106.52.94.217;port=3306;database=yi-bbs-dev;user id=root;password=Qz52013142020.", //"Url": "server=106.52.94.217;port=3306;database=yi-bbs-dev;user id=root;password=Qz52013142020.",
"DbType": "Mysql", "DbType": "Sqlite",
"EnabledDbSeed": true, "EnabledDbSeed": true,
"EnabledReadWrite": false, "EnabledReadWrite": false,
"EnabledCodeFirst": true, "EnabledCodeFirst": true,

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.RBAC.Application.Contracts.Identity.Dtos.Account
{
public class PhoneCaptchaImageDto
{
public string Phone { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.RBAC.Application.Contracts.Identity.Dtos.Account
{
public class RegisterDto
{
//电话号码根据code的表示来获取
/// <summary>
/// 账号
/// </summary>
public string UserName { get; set; } = string.Empty;
/// <summary>
/// 密码
/// </summary>
public string Password { get; set; } = string.Empty;
/// <summary>
/// 唯一标识码
/// </summary>
public string? Uuid { get; set; }
/// <summary>
/// 电话
/// </summary>
public long Phone { get; set; }
/// <summary>
/// 验证码
/// </summary>
public string? Code { get; set; }
}
}

View File

@@ -13,6 +13,5 @@ namespace Yi.RBAC.Application.Contracts.Identity
/// </summary> /// </summary>
public interface IUserService : ICrudAppService<UserGetOutputDto, UserGetListOutputDto, long, UserGetListInputVo, UserCreateInputVo, UserUpdateInputVo> public interface IUserService : ICrudAppService<UserGetOutputDto, UserGetListOutputDto, long, UserGetListInputVo, UserCreateInputVo, UserUpdateInputVo>
{ {
} }
} }

View File

@@ -4,6 +4,31 @@
<name>Yi.RBAC.Application.Contracts</name> <name>Yi.RBAC.Application.Contracts</name>
</assembly> </assembly>
<members> <members>
<member name="P:Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto.UserName">
<summary>
账号
</summary>
</member>
<member name="P:Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto.Password">
<summary>
密码
</summary>
</member>
<member name="P:Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto.Uuid">
<summary>
唯一标识码
</summary>
</member>
<member name="P:Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto.Phone">
<summary>
电话
</summary>
</member>
<member name="P:Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto.Code">
<summary>
验证码
</summary>
</member>
<member name="T:Yi.RBAC.Application.Contracts.Identity.Dtos.DeptCreateInputVo"> <member name="T:Yi.RBAC.Application.Contracts.Identity.Dtos.DeptCreateInputVo">
<summary> <summary>
Dept输入创建对象 Dept输入创建对象

View File

@@ -29,6 +29,7 @@ using Yi.RBAC.Domain.Shared.Identity.ConstClasses;
using Yi.RBAC.Domain.Shared.Identity.Dtos; using Yi.RBAC.Domain.Shared.Identity.Dtos;
using Yi.RBAC.Domain.Shared.Identity.Etos; using Yi.RBAC.Domain.Shared.Identity.Etos;
using System.Net.WebSockets; using System.Net.WebSockets;
using Yi.Framework.Uow;
namespace Yi.RBAC.Application.Identity namespace Yi.RBAC.Application.Identity
{ {
@@ -52,6 +53,19 @@ namespace Yi.RBAC.Application.Identity
[Autowired] [Autowired]
private IDistributedEventBus _distributedEventBus { get; set; } private IDistributedEventBus _distributedEventBus { get; set; }
[Autowired]
private IUserService _userService { get; set; }
[Autowired]
private UserManager _userManager { get; set; }
[Autowired]
private IUnitOfWorkManager _unitOfWorkManager { get; set; }
/// <summary> /// <summary>
/// 登录 /// 登录
/// </summary> /// </summary>
@@ -66,9 +80,9 @@ namespace Yi.RBAC.Application.Identity
//获取用户信息 //获取用户信息
var userInfo = await _userRepository.GetUserAllInfoAsync(user.Id); var userInfo = await _userRepository.GetUserAllInfoAsync(user.Id);
if (userInfo.PermissionCodes.Count == 0) if (userInfo.RoleCodes.Count == 0)
{ {
throw new UserFriendlyException(UserConst.); throw new UserFriendlyException(UserConst.);
} }
//这里抛出一个登录的事件 //这里抛出一个登录的事件
@@ -86,6 +100,71 @@ namespace Yi.RBAC.Application.Identity
return new { Token = token }; return new { Token = token };
} }
/// <summary>
/// 注册 手机验证码
/// </summary>
/// <returns></returns>
public async Task<object> PostPhoneCaptchaImage(PhoneCaptchaImageDto input)
{
//生成一个4位数的验证码
//发送短信同时生成uuid
//key 电话号码 value:验证码+uuid
return new { uuid = Guid.NewGuid() };
}
/// <summary>
/// 注册,需要验证码通过
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<object> PostRegisterAsync(RegisterDto input)
{
if (input.UserName == UserConst.Admin)
{
throw new UserFriendlyException("用户名无效注册!");
}
if (input.UserName.Length < 2)
{
throw new UserFriendlyException("账号名需大于等于2位");
}
if (input.Password.Length<6)
{
throw new UserFriendlyException("密码需大于等于6位");
}
//效验验证码,根据电话号码获取 value比对验证码已经uuid
//输入的用户名与电话号码都不能在数据库中存在
UserEntity user = new();
var isExist = await _userRepository.IsAnyAsync(x =>
x.UserName == input.UserName
|| x.Phone == input.Phone
|| x.UserName == input.Phone.ToString()
|| x.Phone.ToString() == input.UserName);
if (isExist)
{
throw new UserFriendlyException("用户已存在,注册失败");
}
using (var uow = _unitOfWorkManager.CreateContext())
{
var newUser = new UserEntity(input.UserName, input.Password, input.Phone);
var entity = await _userRepository.InsertReturnEntityAsync(newUser);
//赋上一个初始角色
var roleRepository = uow.GetRepository<RoleEntity>();
var role = await roleRepository.GetFirstAsync(x => x.RoleName == UserConst.GuestRoleName);
if (role is not null)
{
await _userManager.GiveUserSetRoleAsync(new List<long> { entity.Id }, new List<long> { role.Id });
}
uow.Commit();
}
return true;
}
/// <summary> /// <summary>
/// 查询已登录的账户信息 /// 查询已登录的账户信息
/// </summary> /// </summary>

View File

@@ -11,6 +11,19 @@
<param name="input"></param> <param name="input"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Yi.RBAC.Application.Identity.AccountService.PostPhoneCaptchaImage(Yi.RBAC.Application.Contracts.Identity.Dtos.Account.PhoneCaptchaImageDto)">
<summary>
注册 手机验证码
</summary>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Application.Identity.AccountService.PostRegisterAsync(Yi.RBAC.Application.Contracts.Identity.Dtos.Account.RegisterDto)">
<summary>
注册,需要验证码通过
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Application.Identity.AccountService.Get"> <member name="M:Yi.RBAC.Application.Identity.AccountService.Get">
<summary> <summary>
查询已登录的账户信息 查询已登录的账户信息

View File

@@ -17,9 +17,13 @@ namespace Yi.RBAC.Domain.Shared.Identity.ConstClasses
public const string _密码为空 = "密码为空,添加失败!"; public const string _密码为空 = "密码为空,添加失败!";
public const string _用户存在 = "用户已经存在,添加失败!"; public const string _用户存在 = "用户已经存在,添加失败!";
public const string = "登录禁用!该用户分配无任何权限,无意义登录!"; public const string = "登录禁用!该用户分配无任何权限,无意义登录!";
public const string = "登录禁用!该用户分配无任何角色,无意义登录!";
public const string Admin = "cc"; public const string Admin = "cc";
public const string AdminRolesCode = "admin"; public const string AdminRolesCode = "admin";
public const string AdminPermissionCode = "*:*:*"; public const string AdminPermissionCode = "*:*:*";
public const string GuestRoleName = "guest";
public const string CommonRoleName = "common";
} }
} }

View File

@@ -45,6 +45,31 @@ namespace Yi.RBAC.Domain.DataSeeds
}; };
entities.Add(role2); entities.Add(role2);
RoleEntity role3 = new RoleEntity()
{
Id = SnowflakeHelper.NextId,
RoleName = "普通用户",
RoleCode = "common",
DataScope = DataScopeEnum.ALL,
OrderNum = 1,
Remark = "正常用户",
IsDeleted = false
};
entities.Add(role3);
RoleEntity role4 = new RoleEntity()
{
Id = SnowflakeHelper.NextId,
RoleName = "游客用户",
RoleCode = "guest",
DataScope = DataScopeEnum.ALL,
OrderNum = 1,
Remark = "可简单浏览",
IsDeleted = false
};
entities.Add(role4);
return entities; return entities;
} }
} }

View File

@@ -66,6 +66,27 @@ namespace Yi.RBAC.Domain.DataSeeds
user2.BuildPassword(); user2.BuildPassword();
entities.Add(user2); entities.Add(user2);
UserEntity user3 = new UserEntity()
{
Id = SnowFlakeSingle.Instance.NextId(),
Name = "游客",
UserName = "guest",
Nick = "测试",
Password = "123456",
Email = "454313500@qq.com",
Phone = 15900000000,
Sex = SexEnum.Woman,
Address = "深圳",
Age = 18,
Introduction = "临时游客",
OrderNum = 1,
Remark = "懒得创账号",
State = true
};
user3.BuildPassword();
entities.Add(user3);
return entities; return entities;
} }
} }

View File

@@ -17,6 +17,20 @@ namespace Yi.RBAC.Domain.Identity.Entities
[SugarTable("User")] [SugarTable("User")]
public class UserEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum,IState public class UserEntity : IEntity<long>, ISoftDelete, IAuditedObject, IOrderNum,IState
{ {
public UserEntity( )
{
}
public UserEntity(string userName,string password,long phone,string nick="萌新" )
{
Id = SnowflakeHelper.NextId;
UserName=userName;
Password=password;
Phone = phone;
Nick = nick;
BuildPassword();
}
/// <summary> /// <summary>
/// 主键 /// 主键
/// </summary> /// </summary>