Compare commits

..

17 Commits

Author SHA1 Message Date
橙子
7f4c7f607d Update README.md 2022-05-06 22:57:36 +08:00
橙子
994ba5dd1a Merge branch 'sqlsugar-dev' into sqlsugar 2022-05-06 22:56:40 +08:00
橙子
e3a06b28dd 更新数据库 2022-05-06 22:56:26 +08:00
橙子
10d512470e 合并冲突 2022-05-06 22:51:45 +08:00
橙子
c1d8040fd5 合并冲突 2022-05-06 22:49:12 +08:00
橙子
e4b81da386 Merge branch 'sqlsugar-dev' of https://gitee.com/ccnetcore/Yi into sqlsugar-dev 2022-05-06 22:47:35 +08:00
橙子
fd7360e6f4 预添加前端权限控制 2022-05-06 22:47:26 +08:00
chenchun
62f15e218e Merge branch 'sqlsugar-dev' into sqlsugar 2022-05-05 17:05:12 +08:00
chenchun
5c1b91f348 完善权限 2022-05-05 17:04:49 +08:00
橙子
378cbd580f Update README.md 2022-05-04 15:55:19 +08:00
橙子
3994f14010 通用对象查询封装、权限封装 2022-05-04 15:54:40 +08:00
橙子
e7f4e743e3 Update README.md 2022-05-03 19:42:47 +08:00
橙子
b934ce2893 添加文件操作 2022-05-03 19:40:13 +08:00
橙子
5eec076ea2 添加前端权限 2022-05-03 17:34:38 +08:00
橙子
ada36ebff5 Update README.md 2022-05-01 18:33:04 +08:00
橙子
d9543ca23c 添加修改密码及用户信息 2022-05-01 18:31:06 +08:00
橙子
3871eb3c84 Update README.md 2022-04-30 22:14:49 +08:00
34 changed files with 454 additions and 138 deletions

View File

@@ -22,7 +22,7 @@ Yi框架-一套与SqlSugar一样爽的.Net6低代码开源框架。
适合.Net6学习、Sqlsugar学习 、项目二次开发。 适合.Net6学习、Sqlsugar学习 、项目二次开发。
集大成者,终究轮子 集大成者,终究轮子
Yi框架最新版本标签`v1.0.8`,具体版本可以查看标签迭代 Yi框架最新版本标签`v1.1.3`,具体版本可以查看标签迭代
项目与Sqlsugar同步更新但这作者老杰哥代码天天爆肝到凌晨两点我们也尽量会跟上他的脚步。更新频繁所以可watching持续关注。 项目与Sqlsugar同步更新但这作者老杰哥代码天天爆肝到凌晨两点我们也尽量会跟上他的脚步。更新频繁所以可watching持续关注。

Binary file not shown.

View File

@@ -9,12 +9,40 @@
账户管理 账户管理
</summary> </summary>
</member> </member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.Login(Yi.Framework.DTOModel.LoginDto)">
<summary>
没啥说,登录
</summary>
<param name="loginDto"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.Register(Yi.Framework.DTOModel.RegisterDto)">
<summary>
没啥说,注册
</summary>
<param name="registerDto"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.GetUserAllInfo"> <member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.GetUserAllInfo">
<summary> <summary>
通过已登录的用户获取用户信息及菜单 通过已登录的用户获取用户信息及菜单
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.UpdatePassword(Yi.Framework.DTOModel.UpdatePasswordDto)">
<summary>
更新登录的用户密码
</summary>
<param name="updatePasswordDto"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.AccountController.UpdateUserByHttp(Yi.Framework.Model.Models.UserEntity)">
<summary>
更新已登录用户的用户信息
</summary>
<param name="user"></param>
<returns></returns>
</member>
<member name="T:Yi.Framework.ApiMicroservice.Controllers.BaseCrudController`1"> <member name="T:Yi.Framework.ApiMicroservice.Controllers.BaseCrudController`1">
<summary> <summary>
Json To Sql 类比模式,通用模型 Json To Sql 类比模式,通用模型
@@ -62,6 +90,34 @@
<param name="ids"></param> <param name="ids"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:Yi.Framework.ApiMicroservice.Controllers.FileController">
<summary>
文件
</summary>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.FileController.#ctor(Yi.Framework.Interface.IUserService,Microsoft.Extensions.Hosting.IHostEnvironment)">
<summary>
使用本地存储,未进行数据库记录
</summary>
<param name="iUserService"></param>
<param name="env"></param>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.FileController.Get(System.String,System.String)">
<summary>
文件下载
</summary>
<param name="type"></param>
<param name="fileName"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.FileController.Upload(System.String,Microsoft.AspNetCore.Http.IFormFile)">
<summary>
文件上传
</summary>
<param name="type"></param>
<param name="file"></param>
<returns></returns>
</member>
<member name="M:Yi.Framework.ApiMicroservice.Controllers.LogController.Add"> <member name="M:Yi.Framework.ApiMicroservice.Controllers.LogController.Add">
<summary> <summary>
自动分表,日志添加 自动分表,日志添加

View File

@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Yi.Framework.Common.Helper;
using Yi.Framework.Common.Models; using Yi.Framework.Common.Models;
using Yi.Framework.Core; using Yi.Framework.Core;
using Yi.Framework.DTOModel; using Yi.Framework.DTOModel;
@@ -22,28 +23,41 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// </summary> /// </summary>
[ApiController] [ApiController]
[Route("api/[controller]/[action]")] [Route("api/[controller]/[action]")]
public class AccountController :ControllerBase public class AccountController : ControllerBase
{ {
private IUserService _iUserService; private IUserService _iUserService;
private JwtInvoker _jwtInvoker; private JwtInvoker _jwtInvoker;
private ILogger _logger;
public AccountController(ILogger<UserEntity> logger, IUserService iUserService, JwtInvoker jwtInvoker) public AccountController(ILogger<UserEntity> logger, IUserService iUserService, JwtInvoker jwtInvoker)
{ {
_iUserService = iUserService; _iUserService = iUserService;
_jwtInvoker = jwtInvoker; _jwtInvoker = jwtInvoker;
_logger = logger;
} }
/// <summary>
/// 没啥说,登录
/// </summary>
/// <param name="loginDto"></param>
/// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public async Task<Result> Login(LoginDto loginDto) public async Task<Result> Login(LoginDto loginDto)
{ {
UserEntity user=new(); UserEntity user = new();
if (await _iUserService.Login(loginDto.UserName, loginDto.Password,o=> user=o)) if (await _iUserService.Login(loginDto.UserName, loginDto.Password, o => user = o))
{ {
return Result.Success("登录成功!").SetData(new { user, token = _jwtInvoker.GetAccessToken(user)}); var userRoleMenu= await _iUserService.GetUserAllInfo(user.Id);
return Result.Success("登录成功!").SetData(new { token = _jwtInvoker.GetAccessToken(userRoleMenu.User,userRoleMenu.Menus) });
} }
return Result.SuccessError("登录失败!用户名或者密码错误!"); return Result.SuccessError("登录失败!用户名或者密码错误!");
} }
/// <summary>
/// 没啥说,注册
/// </summary>
/// <param name="registerDto"></param>
/// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public async Task<Result> Register(RegisterDto registerDto) public async Task<Result> Register(RegisterDto registerDto)
@@ -56,19 +70,63 @@ namespace Yi.Framework.ApiMicroservice.Controllers
return Result.SuccessError("注册失败!用户名已存在!"); return Result.SuccessError("注册失败!用户名已存在!");
} }
[HttpPost]
public Result Logout()
{
return Result.Success("安全登出成功!");
}
/// <summary> /// <summary>
/// 通过已登录的用户获取用户信息及菜单 /// 通过已登录的用户获取用户信息及菜单
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Authorize]
public async Task<Result> GetUserAllInfo() public async Task<Result> GetUserAllInfo()
{ {
//通过鉴权jwt获取到用户的id //通过鉴权jwt获取到用户的id
var userId=HttpContext.GetCurrentUserEntityInfo(out _).Id; var userId = HttpContext.GetCurrentUserEntityInfo(out _).Id;
return Result.Success().SetData(await _iUserService.GetUserAllInfo(userId)); return Result.Success().SetData(await _iUserService.GetUserAllInfo(userId));
} }
/// <summary>
/// 更新登录的用户密码
/// </summary>
/// <param name="updatePasswordDto"></param>
/// <returns></returns>
[HttpPut]
public async Task<Result> UpdatePassword(UpdatePasswordDto updatePasswordDto)
{
var userId = HttpContext.GetCurrentUserEntityInfo(out _).Id;
var userEntiy = await _iUserService._repository.GetByIdAsync(userId);
//判断输入的老密码是否和原密码相同
if (_iUserService.JudgePassword(userEntiy, updatePasswordDto.OldPassword))
{
userEntiy.Password = updatePasswordDto.NewPassword;
userEntiy.BuildPassword();
return Result.Success().SetStatus(await _iUserService._repository.UpdateAsync(userEntiy));
}
return Result.SuccessError("原密码错误!");
}
/// <summary>
/// 更新已登录用户的用户信息
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpPut]
public async Task<Result> UpdateUserByHttp(UserEntity user)
{
//当然,密码是不能给他修改的
user.Password = null;
user.Salt = null;
//修改需要赋值上主键哦
user.Id = HttpContext.GetCurrentUserEntityInfo(out _).Id;
return Result.Success().SetStatus(await _iUserService._repository.UpdateIgnoreNullAsync(user));
}
} }
} }

View File

@@ -32,7 +32,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
[Permission($"{nameof(T)}:get:one")] [Permission($"{nameof(T)}:get:list")]
[HttpGet] [HttpGet]
public virtual async Task<Result> GetById(long id) public virtual async Task<Result> GetById(long id)
{ {
@@ -55,7 +55,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// </summary> /// </summary>
/// <param name="queryCondition"></param> /// <param name="queryCondition"></param>
/// <returns></returns> /// <returns></returns>
[Permission($"{nameof(T)}:get:page")] [Permission($"{nameof(T)}:get:list")]
[HttpPost] [HttpPost]
public virtual async Task<Result> PageList(QueryPageCondition queryCondition) public virtual async Task<Result> PageList(QueryPageCondition queryCondition)
{ {
@@ -91,7 +91,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// </summary> /// </summary>
/// <param name="ids"></param> /// <param name="ids"></param>
/// <returns></returns> /// <returns></returns>
[Permission($"{nameof(T)}:delete:list")] [Permission($"{nameof(T)}:del")]
[HttpDelete] [HttpDelete]
public virtual async Task<Result> DeleteList(List<long> ids) public virtual async Task<Result> DeleteList(List<long> ids)
{ {

View File

@@ -0,0 +1,95 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Yi.Framework.Common.Models;
using Yi.Framework.Interface;
using Yi.Framework.WebCore;
namespace Yi.Framework.ApiMicroservice.Controllers
{
/// <summary>
/// 文件
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class FileController : ControllerBase
{
private IUserService _iUserService;
private readonly IHostEnvironment _env;
/// <summary>
/// 使用本地存储,未进行数据库记录
/// </summary>
/// <param name="iUserService"></param>
/// <param name="env"></param>
public FileController(IUserService iUserService, IHostEnvironment env)
{
_iUserService = iUserService;
_env = env;
}
/// <summary>
/// 文件下载
/// </summary>
/// <param name="type"></param>
/// <param name="fileName"></param>
/// <returns></returns>
[Route("/api/{type}/{fileName}")]
[HttpGet]
public IActionResult Get(string type, string fileName)
{
try
{
var path = Path.Combine($"wwwroot/{type}", fileName);
var stream = System.IO.File.OpenRead(path);
var MimeType = Common.Helper.MimeHelper.GetMimeMapping(fileName);
return new FileStreamResult(stream, MimeType);
}
catch
{
return new NotFoundResult();
}
}
/// <summary>
/// 文件上传
/// </summary>
/// <param name="type"></param>
/// <param name="file"></param>
/// <returns></returns>
[Route("/api/Upload/{type}")]
[HttpPost]
public async Task<Result> Upload(string type, IFormFile file)
{
try
{
string filename = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
using (var stream = new FileStream(Path.Combine($"wwwroot/{type}", filename), FileMode.CreateNew, FileAccess.Write))
{
await file.CopyToAsync(stream);
}
return Result.Success().SetData(filename);
}
catch
{
return Result.Error();
}
}
//[HttpGet]
//public async Task<IActionResult> ExportFile()
//{
// var userdata = await _userService.GetAllEntitiesTrueAsync();
// var userList = userdata.ToList();
// List<string> header = new() { "用户", "密码", "头像", "昵称", "邮箱", "ip", "年龄", "个人介绍", "地址", "手机", "角色" };
// var filename = Common.Helper.ExcelHelper.CreateExcelFromList(userList, header, _env.ContentRootPath.ToString());
// var MimeType = Common.Helper.MimeHelper.GetMimeMapping(filename);
// return new FileStreamResult(new FileStream(Path.Combine(_env.ContentRootPath+@"/wwwroot/excel", filename), FileMode.Open),MimeType);
//}
}
}

View File

@@ -45,7 +45,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
// 特点:化繁为简!意框架仓储代理上下文对象,用起来就是爽,但最好按规范来爽! // 特点:化繁为简!意框架仓储代理上下文对象,用起来就是爽,但最好按规范来爽!
// 规范:控制器不建议使用切换仓储方法、控制器严禁使用DB上下文对象其它怎么爽怎么来 // 规范控制器严禁使用DB上下文对象其它怎么爽怎么来
public async Task<Result> DbTest() public async Task<Result> DbTest()
{ {
//非常好使用UserService的特有方法 //非常好使用UserService的特有方法
@@ -60,7 +60,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
//挺不错,依赖注入其他仓储 //挺不错,依赖注入其他仓储
await _iRoleService._repository.GetListAsync(); await _iRoleService._repository.GetListAsync();
//不建议操作,直接切换其他仓储 //还行,直接切换其他仓储,怎么爽怎么来
await _iUserService._repository.ChangeRepository<Repository<RoleEntity>>().GetListAsync(); await _iUserService._repository.ChangeRepository<Repository<RoleEntity>>().GetListAsync();
//最好不要直接操作Db对象 //最好不要直接操作Db对象
@@ -74,7 +74,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
//简单语句不推荐! //简单语句不推荐使用sql
public async Task<Result> SqlTest() public async Task<Result> SqlTest()
{ {
return Result.Success().SetData(await _iUserService._repository.UseSqlAsync<UserEntity>("select * from User")); return Result.Success().SetData(await _iUserService._repository.UseSqlAsync<UserEntity>("select * from User"));

View File

@@ -41,7 +41,7 @@
"PolicyName": "permission", "PolicyName": "permission",
"DefaultScheme": "Bearer", "DefaultScheme": "Bearer",
"IsHttps": false, "IsHttps": false,
"Expiration": 30, "Expiration": 300,
"ReExpiration": 3000 "ReExpiration": 3000
}, },
"RedisConnOptions": { "RedisConnOptions": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -36,6 +36,14 @@ namespace Yi.Framework.Common.Models
} }
public Result SetStatus(bool _status) public Result SetStatus(bool _status)
{ {
if (_status)
{
this.message = "操作成功";
}
else
{
this.message = "操作失败";
}
this.status = _status; this.status = _status;
return this; return this;
} }

View File

@@ -23,15 +23,15 @@ namespace Yi.Framework.Core
} }
public string GetRefreshToken(UserEntity user) public string GetRefreshToken(UserEntity user)
{ {
return this.GetToken(_JWTTokenOptions.ReExpiration, user, true); return this.GetToken(_JWTTokenOptions.ReExpiration, user,null, true);
} }
public string GetAccessToken(UserEntity user) public string GetAccessToken(UserEntity user,HashSet<MenuEntity> menus)
{ {
return this.GetToken(_JWTTokenOptions.Expiration, user); return this.GetToken(_JWTTokenOptions.Expiration, user, menus);
} }
private string GetToken(int minutes, UserEntity user, bool isRefresh = false) private string GetToken(int minutes, UserEntity user, HashSet<MenuEntity> menus,bool isRefresh = false)
{ {
List<Claim> claims = new List<Claim>(); List<Claim> claims = new List<Claim>();
claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}")); claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"));
@@ -39,8 +39,11 @@ namespace Yi.Framework.Core
claims.Add(new Claim(JwtRegisteredClaimNames.Sid, user.Id.ToString())); claims.Add(new Claim(JwtRegisteredClaimNames.Sid, user.Id.ToString()));
//-----------------------------以下从user的权限表中添加权限-----------------------例如: //-----------------------------以下从user的权限表中添加权限-----------------------例如:
claims.Add(new Claim("permission", "userentity:get:list"));
claims.Add(new Claim("permission", "userentity:get:one")); foreach (var m in menus)
{
claims.Add(new Claim("permission", m.PermissionCode));
}
if (isRefresh) if (isRefresh)
{ {

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.DTOModel
{
public class UpdatePasswordDto
{
public string NewPassword { get; set; }
public string OldPassword { get; set; }
}
}

View File

@@ -67,5 +67,13 @@ namespace Yi.Framework.Interface
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
Task<UserRoleMenuDto> GetUserAllInfo(long userId); Task<UserRoleMenuDto> GetUserAllInfo(long userId);
/// <summary>
/// 判断用户密码是否和原密码相同
/// </summary>
/// <param name="user"></param>
/// <param name="password"></param>
/// <returns></returns>
bool JudgePassword(UserEntity user, string password);
} }
} }

View File

@@ -78,7 +78,7 @@ namespace Yi.Framework.Model.Models
/// ///
///</summary> ///</summary>
[SugarColumn(ColumnName="Icon" )] [SugarColumn(ColumnName="Icon" )]
public long? Icon { get; set; } public string Icon { get; set; }
/// <summary> /// <summary>
/// ///
///</summary> ///</summary>

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Yi.Framework.Common.Helper;
using Yi.Framework.DTOModel; using Yi.Framework.DTOModel;
using Yi.Framework.Interface; using Yi.Framework.Interface;
using Yi.Framework.Model.Models; using Yi.Framework.Model.Models;
@@ -132,8 +133,15 @@ namespace Yi.Framework.Service
userRoleMenu.User = user; userRoleMenu.User = user;
return userRoleMenu; return userRoleMenu;
}
public bool JudgePassword(UserEntity user,string password)
{
if (user.Password == MD5Helper.SHA2Encode(password, user.Salt))
{
return true;
}
return false;
} }
} }
} }

View File

@@ -3,6 +3,7 @@ using Microsoft.IdentityModel.JsonWebTokens;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Yi.Framework.WebCore.AttributeExtend namespace Yi.Framework.WebCore.AttributeExtend
@@ -40,11 +41,24 @@ namespace Yi.Framework.WebCore.AttributeExtend
var perList = context.HttpContext.User.Claims.Where(u => u.Type == "permission").Select(u=> u.Value.ToString().ToLower()). ToList(); var perList = context.HttpContext.User.Claims.Where(u => u.Type == "permission").Select(u=> u.Value.ToString().ToLower()). ToList();
//判断权限是否存在Redis中,或者jwt中 //判断权限是否存在Redis中,或者jwt中
//if (perList.Contains(permission.ToLower())) //进行正则表达式的匹配以code开头
//{ Regex regex = new Regex($"^{permission.ToLower()}");
// result = true; foreach (var p in perList)
//} {
result = true; //过滤多余的标签
p.Replace("Entity","");
p.Replace("entity","");
if (regex.IsMatch(p))
{
result = true;
break;
}
}
//用户的增删改查直接可以user:*即可
//这里暂时全部放行即可
result = true;
if (!result) if (!result)

View File

@@ -37,21 +37,14 @@ namespace Yi.Framework.WebCore
long resId = 0; long resId = 0;
try try
{ {
claimlist = httpContext.AuthenticateAsync().Result.Principal.Claims; claimlist = httpContext.AuthenticateAsync().Result.Principal.Claims;
resId = Convert.ToInt64(claimlist.FirstOrDefault(u => u.Type == JwtRegisteredClaimNames.Sid).Value); resId = Convert.ToInt64(claimlist.FirstOrDefault(u => u.Type == JwtRegisteredClaimNames.Sid).Value);
} }
catch catch
{ {
throw new Exception("未授权Token鉴权失败"); throw new Exception("未授权Token鉴权失败");
} }
menuIds = claimlist.Where(u => u.Type == "menuIds").ToList().Select(u => new Guid(u.Value)).ToList(); menuIds = claimlist.Where(u => u.Type == "menuIds").ToList().Select(u => new Guid(u.Value)).ToList();
return new UserEntity() return new UserEntity()
{ {
Id = resId, Id = resId,

View File

@@ -35,11 +35,11 @@ export default {
method: 'post', method: 'post',
}) })
}, },
changePassword(user, newPassword) { updatePassword(oldPassword, newPassword) {
return myaxios({ return myaxios({
url: `/Account/changePassword`, url: `/Account/updatePassword`,
method: 'put', method: 'put',
data: { user, newPassword } data: { oldPassword, newPassword }
}) })
}, },
getUserAllInfo() getUserAllInfo()
@@ -48,6 +48,14 @@ export default {
url: `/Account/getUserAllInfo`, url: `/Account/getUserAllInfo`,
method: 'get' method: 'get'
}) })
},
updateUserByHttp(user)
{
return myaxios({
url: `/Account/updateUserByHttp`,
method: 'put',
data:user
})
} }
} }

View File

@@ -1,8 +1,8 @@
import myaxios from '@/util/myaxios' import myaxios from '@/util/myaxios'
export default { export default {
EditIcon(file) { UploadImage(file) {
return myaxios({ return myaxios({
url: '/File/EditIcon', url: '/Upload/image',
method: 'post', method: 'post',
headers: { "Content-Type": "multipart/form-data" }, headers: { "Content-Type": "multipart/form-data" },
data: file data: file

View File

@@ -1,22 +1,11 @@
import myaxios from '@/util/myaxios' import myaxios from '@/util/myaxios'
import {objctToDic} from '@/util/objctHandle'
export default { export default {
getList() { getList() {
return myaxios({ return myaxios({
url: '/Role/GetList', url: '/Role/GetList',
method: 'post', method: 'post',
data: { data: objctToDic()
parameters: [
{
key: "isDeleted",
value: "0",
type: 0
}
],
orderBys: [
"id"
]
}
}) })
}, },
giveRoleSetMenu(roleList, menuList) { giveRoleSetMenu(roleList, menuList) {

View File

@@ -1,14 +1,5 @@
import myaxios from '@/util/myaxios' import myaxios from '@/util/myaxios'
export default { export default {
SetRoleByUser(userIds, roleIds) {
return myaxios({
url: '/User/SetRoleByUser',
method: 'post',
data: { "ids1": userIds, "ids2": roleIds }
})
},
GetUserInRolesByHttpUser() { GetUserInRolesByHttpUser() {
return myaxios({ return myaxios({

View File

@@ -1,22 +1,11 @@
import myaxios from '@/util/myaxios' import myaxios from '@/util/myaxios'
import {objctToDic} from '@/util/objctHandle'
export default { export default {
getItem(url) { getItem(url) {
return myaxios({ return myaxios({
url: url, url: url,
method: 'post', method: 'post',
data: { data: objctToDic()
parameters: [
{
key: "isDeleted",
value: "0",
type: 0
}
],
orderBys: [
"id"
]
}
}) })
}, },
addItem(url, data) { addItem(url, data) {

View File

@@ -53,8 +53,7 @@
item-text="menuName" item-text="menuName"
> >
<template v-slot:append="{ item }"> <template v-slot:append="{ item }">
<v-btn class="mr-2">编号:{{ item.id }}</v-btn> <v-btn v-show="item.menuType==1" class="mr-2">权限:{{ item.permissionCode }}</v-btn>
<v-btn class="mr-2">权限:{{ item.permissionCode }}</v-btn>
<!-- <v-btn class="mr-2">图标:{{ item.icon }}</v-btn> --> <!-- <v-btn class="mr-2">图标:{{ item.icon }}</v-btn> -->
<!-- <v-btn class="mr-2">路由:{{ item.router }}</v-btn> --> <!-- <v-btn class="mr-2">路由:{{ item.router }}</v-btn> -->
<!-- <v-btn v-if="item.mould" class="mr-2">接口名:{{ item.mould.mould_name }}</v-btn> <!-- <v-btn v-if="item.mould" class="mr-2">接口名:{{ item.mould.mould_name }}</v-btn>

View File

@@ -1,8 +1,9 @@
import { getToken, setToken, getUser, setUser, removeToken } from '../../util/usertoken' import { getPer, setPer, getToken, setToken, getUser, setUser, removeToken } from '../../util/usertoken'
import accountApi from "@/api/accountApi" import accountApi from "@/api/accountApi"
//再导入axion请求 //再导入axion请求
const state = { //状态 const state = { //状态
per: getPer(),
token: getToken(), token: getToken(),
user: getUser(), user: getUser(),
dark: false, dark: false,
@@ -20,19 +21,24 @@ const state = { //状态
'https://s1.ax1x.com/2022/03/26/qdNnbD.jpg', 'https://s1.ax1x.com/2022/03/26/qdNnbD.jpg',
'https://s1.ax1x.com/2022/03/26/qdNMUH.jpg', 'https://s1.ax1x.com/2022/03/26/qdNMUH.jpg',
'https://s1.ax1x.com/2022/03/26/qdNKVe.jpg', 'https://s1.ax1x.com/2022/03/26/qdNKVe.jpg',
'https://s1.ax1x.com/2022/03/26/qdNmDO.jpg' 'https://s1.ax1x.com/2022/03/26/qdNmDO.jpg'
], ],
notifications: [], notifications: [],
rtl: false rtl: false
} }
const mutations = { //变化//载荷 const mutations = { //变化//载荷
SET_PER(state, per) {
state.per = per
setPer(per)
},
SET_TOKEN(state, token) { SET_TOKEN(state, token) {
state.token = token state.token = token
setToken(token) setToken(token)
}, },
SET_USER(state, user) { SET_USER(state, user) {
state.user = user state.user = user
console.log(user)
setUser(user) setUser(user)
}, },
SetGradient(state, gradient) { SetGradient(state, gradient) {
@@ -45,7 +51,7 @@ const mutations = { //变化//载荷
//在action中可以配合axios进行权限判断 //在action中可以配合axios进行权限判断
const actions = { //动作 const actions = { //动作
setIcon({ commit, state }, icon) { SetIcon({ commit, state }, icon) {
state.user.icon = icon state.user.icon = icon
commit('SET_USER', state.user) commit('SET_USER', state.user)
}, },
@@ -78,9 +84,22 @@ const actions = { //动作
accountApi.login(form.username.trim(), form.password.trim()).then(resp => { accountApi.login(form.username.trim(), form.password.trim()).then(resp => {
if (resp.status) { if (resp.status) {
commit('SET_TOKEN', resp.data.token) commit('SET_TOKEN', resp.data.token)
commit('SET_USER', resp.data.user)
accountApi.getUserAllInfo().then(resp2=>{
commit('SET_USER', resp2.data.user)
var code=[];
resp2.data.menus.forEach(element => {
code.push(element.permissionCode)
});
commit('SET_PER', code)
resolv(resp)
})
} }
resolv(resp)
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })

View File

@@ -0,0 +1,29 @@
//匹配菜单让code变成路由
const menuDic=
{
"user:get:list": "/admuser",
"role:get:list": "/admrole",
"menu:get:list":"/admmenu",
"rolemenu:set:list":"/admrolemenu"
}
//匹配按钮,判断是否有按钮存在
const btnDic=
{
"user:add":"",
"user:update":"",
"user:del":"",
}
export default {menuDic,btnDic};
//菜单可以区分使用code来进行匹配
//记得:关于*的使用,要单独判断
//比如,
//按钮是user:*或者*:*:*直接全部放行即可
//菜单就不一样了,如果是*:*:*
//有两种方案:
//1:直接使用一个默认的全部菜单(会和后端给的菜单冲突)
//2:前端直接无视,*:*:*相当于只管后端权限(如果后端没有配置菜单前端将没有菜单了)
//如果查询找到的是user:*,可以先把*全部替换成get:list再进行比对即可

View File

@@ -8,6 +8,11 @@ export function deepCopy(obj) {
//转换数据,0是相等1是模糊查询 //转换数据,0是相等1是模糊查询
export function objctToDic(object, isByPage) { export function objctToDic(object, isByPage) {
if (object == undefined) {
object = {};
}
if (isByPage) { if (isByPage) {
var paramPage = { var paramPage = {
"index": object.pageIndex, "index": object.pageIndex,
@@ -19,8 +24,8 @@ export function objctToDic(object, isByPage) {
var newData = deepCopy(object); var newData = deepCopy(object);
delete newData.pageIndex; delete newData.pageIndex;
delete newData.pageSize; delete newData.pageSize;
var newList = [Object.keys(newData).map(val => { var newList = [Object.keys(newData).map(val => {
return { return {
key: val, key: val,
value: object[val], value: object[val],
@@ -30,11 +35,9 @@ export function objctToDic(object, isByPage) {
//过滤封装 //过滤封装
newList[0].forEach((item, index) => { newList[0].forEach((item, index) => {
if(item.value.length>0) if (item.value.length > 0) {
{ if (item.key == 'isDeleted') {
if(item.key=='isDeleted') item.type = 0;
{
item.type=0;
} }
paramPage.parameters.push(item); paramPage.parameters.push(item);
} }
@@ -55,11 +58,9 @@ export function objctToDic(object, isByPage) {
} }
})] })]
thisList[0].forEach((item, index) => { thisList[0].forEach((item, index) => {
if(item.value.length>0) if (item.value.length > 0) {
{ if (item.key == 'isDeleted') {
if(item.key=='isDeleted') item.type = 0;
{
item.type=0;
} }
params.parameters.push(item); params.parameters.push(item);
} }

View File

@@ -1,18 +1,30 @@
const TOKEN_KEY = "token_key" const TOKEN_KEY = "token_key"
const USER_KEY = "user_key" const USER_KEY = "user_key"
const PER_KEY="per_key"
export function getToken() { export function getToken() {
return localStorage.getItem(TOKEN_KEY) return localStorage.getItem(TOKEN_KEY)
} }
export function setToken(token) {
return localStorage.setItem(TOKEN_KEY, token)
}
export function getUser() { export function getUser() {
return JSON.parse(localStorage.getItem(USER_KEY)) return JSON.parse(localStorage.getItem(USER_KEY))
} }
export function getPer() {
return JSON.parse(localStorage.getItem(PER_KEY))
}
export function setToken(token) {
return localStorage.setItem(TOKEN_KEY, token)
}
export function setUser(user) { export function setUser(user) {
return localStorage.setItem(USER_KEY, JSON.stringify(user)) return localStorage.setItem(USER_KEY, JSON.stringify(user))
} }
export function setPer(per) {
return localStorage.setItem(PER_KEY, JSON.stringify(per))
}
export function removeToken() { export function removeToken() {
localStorage.removeItem(TOKEN_KEY) localStorage.removeItem(TOKEN_KEY)
localStorage.removeItem(USER_KEY) localStorage.removeItem(USER_KEY)
localStorage.removeItem(PER_KEY)
} }

View File

@@ -59,6 +59,9 @@ export default {
}); });
}, },
init() { init() {
//这里可以遍历后台的菜单code根据对应的菜单code来给axiosUrls的增删改查赋值即可
this.axiosUrls = { this.axiosUrls = {
get: "/user/GetList", get: "/user/GetList",
update: "/user/Update", update: "/user/Update",
@@ -101,7 +104,7 @@ export default {
axiosUrls: {}, axiosUrls: {},
headers: [ headers: [
{ text: "用户名", value: "userName", sortable: false }, { text: "用户名", value: "userName", sortable: false },
{ text: "密码", value: "password", sortable: false },
{ text: "图标", value: "icon", sortable: false }, { text: "图标", value: "icon", sortable: false },
{ text: "昵称", value: "nick", sortable: true }, { text: "昵称", value: "nick", sortable: true },
{ text: "邮箱", value: "email", sortable: true }, { text: "邮箱", value: "email", sortable: true },

View File

@@ -133,7 +133,7 @@ export default {
}; };
}, },
login() { login() {
this.loader = "true"; this.loader = true;
this.btn_dis=true; this.btn_dis=true;
this.$store.dispatch("Login", this.form).then((resp) => { this.$store.dispatch("Login", this.form).then((resp) => {
if (resp.status) { if (resp.status) {

View File

@@ -3,7 +3,10 @@
<v-row justify="center"> <v-row justify="center">
<v-col cols="12" md="4"> <v-col cols="12" md="4">
<app-card class="mt-4 text-center"> <app-card class="mt-4 text-center">
<ccAvatar :size="128" class="rounded-circle elevation-6 mt-n12 d-inline-block"></ccAvatar> <ccAvatar
:size="128"
class="rounded-circle elevation-6 mt-n12 d-inline-block"
></ccAvatar>
<v-card-text class="text-center"> <v-card-text class="text-center">
<h6 class="text-h6 mb-2 text--secondary"> <h6 class="text-h6 mb-2 text--secondary">
@@ -13,13 +16,19 @@
<h4 class="text-h4 mb-3 text--primary">{{ userInfo.nick }}</h4> <h4 class="text-h4 mb-3 text--primary">{{ userInfo.nick }}</h4>
<p class="text--secondary">{{ userInfo.introduction }}</p> <p class="text--secondary">{{ userInfo.introduction }}</p>
<input <input
type="file" type="file"
ref="imgFile" ref="imgFile"
@change="uploadImage()" @change="uploadImage()"
class="d-none" class="d-none"
/> />
<v-btn class="mr-4" @click="choiceImg" color="primary" min-width="100" rounded> <v-btn
class="mr-4"
@click="choiceImg"
color="primary"
min-width="100"
rounded
>
编辑头像 编辑头像
</v-btn> </v-btn>
<v-btn color="primary" min-width="100" rounded> 绑定QQ </v-btn> <v-btn color="primary" min-width="100" rounded> 绑定QQ </v-btn>
@@ -230,7 +239,7 @@
<v-text-field <v-text-field
style="width: 80%" style="width: 80%"
label="原密码" label="原密码"
v-model="editInfo.password" v-model="oldPassword"
outlined outlined
clearable clearable
></v-text-field> ></v-text-field>
@@ -263,7 +272,6 @@
<script> <script>
import fileApi from "../api/fileApi"; import fileApi from "../api/fileApi";
import userApi from "../api/userApi";
import accountApi from "../api/accountApi"; import accountApi from "../api/accountApi";
export default { export default {
name: "UserProfileView", name: "UserProfileView",
@@ -272,17 +280,18 @@ export default {
userInfo: {}, userInfo: {},
editInfo: {}, editInfo: {},
newPassword: "", newPassword: "",
oldPassword: "",
dis_newPassword: true, dis_newPassword: true,
roleInfo:[], roleInfo: [],
menuInfo: [], menuInfo: [],
}), }),
created() { created() {
this.init(); this.init();
}, },
watch: { watch: {
editInfo: { oldPassword: {
handler(val, oldVal) { handler(val, oldVal) {
if (val.password.length > 0) { if (val != "") {
this.dis_newPassword = false; this.dis_newPassword = false;
} else { } else {
this.dis_newPassword = true; this.dis_newPassword = true;
@@ -294,50 +303,60 @@ export default {
methods: { methods: {
save() { save() {
accountApi if (this.newPassword != "") {
.changePassword(this.editInfo, this.newPassword) accountApi
.then((resp) => { .updatePassword(this.oldPassword, this.newPassword)
if (resp.status) { .then((resp) => {
this.$dialog.notify.error(resp.msg, { if (resp.status) {
position: "top-right", this.$dialog.notify.success(resp.message, {
timeout: 5000, position: "top-right",
}); timeout: 5000,
} else { });
this.$dialog.notify.success(resp.msg, { } else {
position: "top-right", this.$dialog.notify.error(resp.message, {
timeout: 5000, position: "top-right",
}); timeout: 5000,
} });
}
this.init();
});
} else {
accountApi.updateUserByHttp(this.editInfo).then((resp) => {
this.init(); this.init();
}); });
}
}, },
init() { init() {
this.newPassword = ""; this.newPassword = "";
this.oldPassword = "";
accountApi.getUserAllInfo().then((resp) => { accountApi.getUserAllInfo().then((resp) => {
this.userInfo = resp.data.user; this.userInfo = resp.data.user;
this.userInfo.password = ""; this.userInfo.password = "";
this.editInfo = Object.assign({}, this.userInfo); this.editInfo = Object.assign({}, this.userInfo);
this.roleInfo=resp.data.roles; this.roleInfo = resp.data.roles;
this.menuInfo = resp.data.menus; this.menuInfo = resp.data.menus;
this.$store.commit('SET_USER',this.userInfo) this.$store.commit("SET_USER", this.userInfo);
}); });
}, },
choiceImg() { choiceImg() {
this.$refs.imgFile.dispatchEvent(new MouseEvent("click")); this.$refs.imgFile.dispatchEvent(new MouseEvent("click"));
}, },
uploadImage() { uploadImage() {
//修改头像需要先上传头像修改editInfo的头像信息即可
const file = this.$refs.imgFile.files[0]; const file = this.$refs.imgFile.files[0];
let formData = new FormData(); let formData = new FormData();
formData.append("file", file); formData.append("file", file);
fileApi.EditIcon(formData).then(resp=>{
this.init();
this.$dialog.notify.success(resp.msg, {
position: "top-right",
timeout: 5000,
});
})
},
fileApi.UploadImage(formData).then((resp) => {
this.editInfo.icon=resp.data
this.$dialog.notify.success("头像加载成功,点击保存以设置", {
position: "top-right",
timeout: 5000,
});
this.$store.dispatch("SetIcon", this.editInfo.icon)
});
},
}, },
}; };
</script> </script>