完成页面应用管理、用户管理
This commit is contained in:
parent
791f7d48f3
commit
57554f1ae3
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FAuth.Extensions;
|
||||
using FAuth.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FAuth.Controllers.api
|
||||
|
|
|
@ -51,14 +51,14 @@ namespace FAuth.Controllers.api
|
|||
/// <summary>
|
||||
/// 删除一个应用
|
||||
/// </summary>
|
||||
/// <param name="appName">应用名称</param>
|
||||
/// <param name="id">应用编号</param>
|
||||
/// <returns>删除结果</returns>
|
||||
[HttpPost]
|
||||
public bool RemoveApp(string appName) {
|
||||
if(appName.IsNullOrEmpty()) {
|
||||
throw new ApiArgumentNullException(nameof(appName));
|
||||
public bool RemoveApp(int id) {
|
||||
if(id == 1) {
|
||||
throw new ApiException("系统应用不可以删除");
|
||||
}
|
||||
var qu = this.Db.Apps.Where(m => m.Name == appName);
|
||||
var qu = this.Db.Apps.Where(m => m.Id == id);
|
||||
foreach(var item in qu) {
|
||||
this.Db.Entry(item).State = EntityState.Deleted;
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ namespace FAuth.Controllers.api
|
|||
if(this.Account.IsNotSystemAdmin(adminTicket)) {
|
||||
throw new ApiException("需要提供管理员票据");
|
||||
}
|
||||
var list = this.Cache.GetObj<List<Apps>>("");
|
||||
var qu = this.Db.Apps;
|
||||
return qu.ToList();
|
||||
}
|
||||
|
|
|
@ -113,21 +113,36 @@ namespace FAuth.Controllers.api
|
|||
/// <summary>
|
||||
/// 获取用户信息列表
|
||||
/// </summary>
|
||||
/// <param name="userName">登录用户名</param>
|
||||
/// <param name="name">用户名</param>
|
||||
/// <returns>用户信息列表</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<UserInfo>),200)]
|
||||
public IEnumerable<UserInfo> GetUsers() {
|
||||
var key = "FAuth:Users";
|
||||
var obj = this.Cache?.GetObj<List<UserInfo>>(key);
|
||||
if(obj == null) {
|
||||
obj = this.Db.Users
|
||||
.Select(m => new UserInfo {
|
||||
Id = m.Id,
|
||||
UserName = m.UserName,
|
||||
}).ToList();
|
||||
this.Cache?.SetCache(key,obj,new TimeSpan(0,5,0));
|
||||
public IEnumerable<UserInfo> GetUsers(string userName,string name) {
|
||||
var key = $"FAuth:Users:userName:{userName}:name:{name}";
|
||||
List<UserInfo> result = null;// this.Cache?.GetObj<List<UserInfo>>(key);
|
||||
if(result == null) {
|
||||
var qu = this.Db.Users
|
||||
.Select(m => new UserInfo {
|
||||
Id = m.Id,
|
||||
UserName = m.UserName,
|
||||
Name = m.Name,
|
||||
LastLoginDatetime = m.LastLoginDatetime,
|
||||
Status =
|
||||
!m.LastLoginDatetime.HasValue ? "未登陆" :
|
||||
!m.LastLogoutDatetime.HasValue ? "在线" :
|
||||
m.LastLoginDatetime.Value > m.LastLogoutDatetime.Value ? "在线" : "离线",
|
||||
});
|
||||
if(userName.IsNotNullOrEmpty()) {
|
||||
qu = qu.Where(m => m.UserName == userName);
|
||||
}
|
||||
if(name.IsNotNullOrEmpty()) {
|
||||
qu = qu.Where(m => m.Name == name);
|
||||
}
|
||||
result = qu.ToList();
|
||||
this.Cache?.SetCache(key,result,new TimeSpan(0,5,0));
|
||||
}
|
||||
return obj;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -163,7 +178,8 @@ namespace FAuth.Controllers.api
|
|||
/// <param name="password">用户密码</param>
|
||||
/// <returns>是否成功</returns>
|
||||
[HttpPost]
|
||||
public bool AddNewUser(string adminTicket,string userName,string name,string password) {
|
||||
[ProducesResponseType(typeof(UserInfo),200)]
|
||||
public UserInfo AddNewUser(string adminTicket,string userName,string name,string password) {
|
||||
if(adminTicket is null)
|
||||
throw new ApiArgumentNullException(nameof(adminTicket));
|
||||
if(userName is null)
|
||||
|
@ -186,7 +202,12 @@ namespace FAuth.Controllers.api
|
|||
this.Db.Entry(nUser).State = EntityState.Added;
|
||||
this.Db.SaveChangesAsync().Wait();
|
||||
this.Logger.LogInformation($"用户{nUser.Id}:{nUser.UserName}:{nUser.Name}添加成功!");
|
||||
return true;
|
||||
return new UserInfo {
|
||||
Id = nUser.Id,
|
||||
UserName = nUser.UserName,
|
||||
Name = nUser.Name,
|
||||
LastLoginDatetime = nUser.LastLoginDatetime,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -218,5 +239,24 @@ namespace FAuth.Controllers.api
|
|||
this.Db.SaveChangesAsync().Wait();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户
|
||||
/// </summary>
|
||||
/// <param name="adminTicket">管理员凭据</param>
|
||||
/// <param name="id">要删除的用户编号</param>
|
||||
/// <returns>删除结果</returns>
|
||||
[HttpPost, ProducesResponseType(typeof(ApiBoolResult),200)]
|
||||
public ApiBoolResult RemoveUser(string adminTicket,int id) {
|
||||
var user = this.Account.TicketDryptor.Decrypt(adminTicket);
|
||||
if(user.Id == id) {
|
||||
throw new ApiException("当前用户不能删除");
|
||||
}
|
||||
this.Db.Users.Attach(new FUser {
|
||||
Id = id,
|
||||
}).State = EntityState.Deleted;
|
||||
this.Db.SaveChangesAsync().Wait();
|
||||
return new ApiBoolResult { Result = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using Falcon.Extend;
|
||||
using FAuth.Extensions;
|
||||
using FAuth.Extensions.Account;
|
||||
using FAuth.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using api = FAuth.Controllers.api;
|
||||
|
||||
namespace FAuth.Controllers.web
|
||||
{
|
||||
/// <summary>
|
||||
/// Ó¦ÓÿØÖÆÆ÷
|
||||
/// </summary>
|
||||
public class AppController:WebControllerBase<AppController>
|
||||
{
|
||||
public AccountHelper Account { get; set; }
|
||||
|
||||
public AppController(ILogger<AppController> logger,IServiceProvider service) : base(logger,service) {
|
||||
this.Account = this.Services.GetService<AccountHelper>();
|
||||
}
|
||||
|
||||
public IActionResult Index() {
|
||||
return PartialView();
|
||||
}
|
||||
|
||||
public IActionResult AddNew() {
|
||||
return PartialView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using FAuth.Models;
|
||||
using FAuth.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using api = FAuth.Controllers.api;
|
||||
using Falcon.Extend;
|
||||
|
||||
namespace FAuth.Controllers.web
|
||||
{
|
||||
|
|
13
FAuth/Models/ApiBoolResult.cs
Normal file
13
FAuth/Models/ApiBoolResult.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace FAuth.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// api返回bool结果
|
||||
/// </summary>
|
||||
public class ApiBoolResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool Result { get; set; }
|
||||
}
|
||||
}
|
|
@ -26,5 +26,9 @@ namespace FAuth.Models
|
|||
/// 上次登录时间
|
||||
/// </summary>
|
||||
public DateTimeOffset? LastLoginDatetime { get; set; }
|
||||
/// <summary>
|
||||
/// 账户状态
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace FAuth
|
|||
db.InitSync().Wait();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
//app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
|
||||
|
|
28
FAuth/Views/App/AddNew.cshtml
Normal file
28
FAuth/Views/App/AddNew.cshtml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<fieldset id="app_addNew">
|
||||
<legend>新增应用</legend>
|
||||
<label>应用名称:<input type="text" v-model="appName" /></label>
|
||||
<label>应用说明:<input type="text" v-model="description" /></label>
|
||||
<input type="button" value="提交" v-on:click="submit" />
|
||||
</fieldset>
|
||||
<script type="text/javascript">
|
||||
mydata.app_new = new Vue({
|
||||
el: '#app_addNew',
|
||||
data: {
|
||||
userTicket: myJs.getTicket(),
|
||||
appName: "",
|
||||
description: "",
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
debugger;
|
||||
var url = myJs.url.app.AddNewApp;
|
||||
myJs.post(url, { appName: this.appName, description: this.description }, function (d) {
|
||||
if (mydata.app_index.rows) mydata.app_index.rows.push(d);
|
||||
$("#app_addNew").html("");
|
||||
}, function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,7 +1,70 @@
|
|||
|
||||
@{
|
||||
ViewData["Title"] = "Index";
|
||||
}
|
||||
|
||||
<h1>AppController Index</h1>
|
||||
|
||||
<div id="app_index">
|
||||
<fieldset>
|
||||
<legend>查询应用</legend>
|
||||
<label>应用名称:<input type="text" name="appName" v-model="appNameValue" /></label>
|
||||
<input type="button" value="查询" id="search" v-on:click="search" />
|
||||
<a fajax-updata="#newdlg" asp-controller="app" asp-action="AddNew">新增</a>
|
||||
</fieldset>
|
||||
<table class="table" v-if="rows.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>应用编号</td>
|
||||
<td>应用名称</td>
|
||||
<td>说明</td>
|
||||
<td>操作</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="r in rows">
|
||||
<td>{{r.Id}}</td>
|
||||
<td>{{r.Name}}</td>
|
||||
<td>{{r.Description}}</td>
|
||||
<td><input type="button" value="删除" v-on:click="remove(r.Id)" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="newdlg"></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
mydata.app_index = new Vue({
|
||||
el: '#app_index',
|
||||
data: {
|
||||
userTicket: myJs.getTicket(),
|
||||
appNameValue: "全部",
|
||||
rows: [],
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
if (this.appNameValue == "全部" || this.appNameValue == "") {
|
||||
var url = myJs.url.app.GetAppList;
|
||||
myJs.get(url, { adminTicket: this.userTicket }, function (d) {
|
||||
mydata.app_index.rows = d;
|
||||
}, function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
} else {
|
||||
var url = myJs.url.app.GetApps;
|
||||
myJs.post(url, { adminTicket: this.userTicket, appName: this.appNameValue, }, function (d) {
|
||||
mydata.app_index.rows = new Array(d);
|
||||
}, function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
}
|
||||
},
|
||||
remove(id) {
|
||||
var url = myJs.url.app.RemoveApp;
|
||||
myJs.post(url, { id: id }, function (d) {
|
||||
var nArr = [];
|
||||
$.each(mydata.app_index.rows, function () {
|
||||
if (this.Id != id) {
|
||||
nArr.push(this);
|
||||
}
|
||||
});
|
||||
mydata.app_index.rows = nArr;
|
||||
}, function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -62,57 +62,57 @@
|
|||
</div>
|
||||
</footer>
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/vue/vue.min.js"></script>
|
||||
<script src="~/lib/jquery.cookie/jquery.cookie-1.4.1.min.js"></script>
|
||||
<script src="~/lib/jquery.unobtrusive-ajax/jquery.unobtrusive-ajax.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
//设置用户key
|
||||
myJs.userKey="@CKD.Value.UserKey";
|
||||
//设置用户key
|
||||
myJs.userKey = "@CKD.Value.UserKey";
|
||||
|
||||
//刷新用户条
|
||||
function RefreshUserBar() {
|
||||
var ticket =myJs.getTicket();
|
||||
if (!ticket) {
|
||||
//刷新用户条
|
||||
function RefreshUserBar() {
|
||||
var ticket =myJs.getTicket();
|
||||
if (!ticket) {
|
||||
$("#logout").hide();
|
||||
$("#login").show();
|
||||
}
|
||||
if (ticket) {
|
||||
var url = "/api/User/GetUserByTicket";
|
||||
var data = { ticket: ticket };
|
||||
myJs.get(url, data, function (d) {
|
||||
$("#userName").html(d.Name);
|
||||
$("#logout").show();
|
||||
$("#login").hide();
|
||||
}, function (c,i,m) {
|
||||
$("#logout").hide();
|
||||
$("#login").show();
|
||||
}
|
||||
if (ticket) {
|
||||
var url = "/api/User/GetUserByTicket";
|
||||
var data = { ticket: ticket };
|
||||
myJs.get(url, data, function (d) {
|
||||
$("#userName").html(d.Name);
|
||||
$("#logout").show();
|
||||
$("#login").hide();
|
||||
}, function (c,i,m) {
|
||||
$("#logout").hide();
|
||||
$("#login").show();
|
||||
myJs.msg(m);
|
||||
myJs.removeTicket();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
var ticket = myJs.getTicket();
|
||||
var url = "/api/User/Logout";
|
||||
var data = { ticket: ticket };
|
||||
myJs.post(url, data, function (d) {
|
||||
myJs.removeTicket(ticket);
|
||||
RefreshUserBar();
|
||||
}, function (s,i,m) {
|
||||
myJs.msg(m);
|
||||
myJs.msg(m);
|
||||
myJs.removeTicket();
|
||||
});
|
||||
}
|
||||
$(function () {
|
||||
RefreshUserBar();
|
||||
}
|
||||
|
||||
$("#logOut").click(function () {
|
||||
logOut();
|
||||
return false;
|
||||
});
|
||||
function logOut() {
|
||||
var ticket = myJs.getTicket();
|
||||
var url = "/api/User/Logout";
|
||||
var data = { ticket: ticket };
|
||||
myJs.post(url, data, function (d) {
|
||||
myJs.removeTicket(ticket);
|
||||
RefreshUserBar();
|
||||
}, function (s,i,m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
}
|
||||
$(function () {
|
||||
RefreshUserBar();
|
||||
$("#logOut").click(function () {
|
||||
logOut();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@RenderSection("Scripts",required: false)
|
||||
</body>
|
||||
|
|
|
@ -1,7 +1,81 @@
|
|||
|
||||
@{
|
||||
ViewData["Title"] = "Index";
|
||||
}
|
||||
|
||||
<h1>User Index</h1>
|
||||
|
||||
<div id="user_index">
|
||||
<fieldset>
|
||||
<legend>用户查询</legend>
|
||||
<label>登录名:<input type="text" v-model="userName" /></label>
|
||||
<label>用户名:<input type="text" v-model="name" /></label>
|
||||
<input type="button" v-on:click="userSearch" value="查询" />
|
||||
<input type="button" v-on:click="clear" value="清空" />
|
||||
<input type="button" v-on:click="addNew" value="新增" />
|
||||
</fieldset>
|
||||
<table class="table" v-if="tableShow">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>用户编号</th>
|
||||
<th>用户登录名</th>
|
||||
<th>用户姓名</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="u in users">
|
||||
<td>{{u.Id}}</td>
|
||||
<td>{{u.UserName}}</td>
|
||||
<td>{{u.Name}}</td>
|
||||
<td>{{u.Status}}</td>
|
||||
<td><input type="button" value="删除" v-on:click="removeUser(u.Id)" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var userIndex = new Vue({
|
||||
el: "#user_index",
|
||||
data: {
|
||||
userName: "",
|
||||
name: "",
|
||||
tableShow: false,
|
||||
users: [],
|
||||
ticket: myJs.getTicket(),
|
||||
},
|
||||
methods: {
|
||||
userSearch() {
|
||||
myJs.get(myJs.url.user.GetUsers, { userName: this.userName, name: this.name, }, function (d) {
|
||||
userIndex.users = d;
|
||||
userIndex.tableShow = true;
|
||||
}, function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
});
|
||||
},
|
||||
clear() {
|
||||
this.userName = "";
|
||||
this.name = "";
|
||||
this.tableShow = false;
|
||||
this.users = [];
|
||||
},
|
||||
addNew() {
|
||||
debugger;
|
||||
myJs.post(myJs.url.user.AddNewUser, {
|
||||
adminTicket: this.ticket,
|
||||
userName: this.userName,
|
||||
name: this.name,
|
||||
password: this.userName,
|
||||
}, function (d) {
|
||||
userIndex.users.push(d);
|
||||
userIndex.tableShow = true;
|
||||
});
|
||||
},
|
||||
removeUser(id) {
|
||||
myJs.post(myJs.url.user.RemoveUser, { adminTicket: this.ticket, id: id }, function (d) {
|
||||
var nArr = [];
|
||||
$.each(userIndex.users, function () {
|
||||
if (this.Id != id) {
|
||||
nArr.push(this);
|
||||
}
|
||||
});
|
||||
userIndex.users = nArr;
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -68,4 +68,4 @@ body {
|
|||
width: 100%;
|
||||
white-space: nowrap;
|
||||
line-height: 60px; /* Vertically center the text there */
|
||||
}
|
||||
}
|
|
@ -1,9 +1,4 @@
|
|||
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
||||
|
||||
var myJs = {};
|
||||
var myJs = {};
|
||||
myJs.get = function (url, data, success, error) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
|
@ -13,6 +8,11 @@ myJs.get = function (url, data, success, error) {
|
|||
success(d);
|
||||
},
|
||||
error: function (d) {
|
||||
if (!error) {
|
||||
error = function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
};
|
||||
}
|
||||
error(d.status, d.responseJSON.Id, d.responseJSON.Message)
|
||||
},
|
||||
});
|
||||
|
@ -26,6 +26,11 @@ myJs.post = function (url, data, success, error) {
|
|||
success(d);
|
||||
},
|
||||
error: function (d) {
|
||||
if (!error) {
|
||||
error = function (s, i, m) {
|
||||
myJs.msg(m);
|
||||
};
|
||||
}
|
||||
error(d.status, d.responseJSON.Id, d.responseJSON.Message)
|
||||
},
|
||||
});
|
||||
|
@ -42,4 +47,21 @@ myJs.getTicket = function () {
|
|||
//移除用户登录票据
|
||||
myJs.removeTicket = function () {
|
||||
$.removeCookie(myJs.userKey);
|
||||
}
|
||||
}
|
||||
|
||||
myJs.url = {
|
||||
app: {
|
||||
AddNewApp: "api/app/AddNewApp",
|
||||
RemoveApp: "api/app/RemoveApp",
|
||||
GetApps: "api/app/GetApps",
|
||||
GetAppList: "api/app/GetAppList",
|
||||
},
|
||||
user: {
|
||||
GetUsers: "/api/User/GetUsers",
|
||||
AddNewUser: "/api/User/AddNewUser",
|
||||
RemoveUser: "/api/User/RemoveUser",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
var mydata = {}
|
7
FAuth/wwwroot/js/vmTemplate.js
Normal file
7
FAuth/wwwroot/js/vmTemplate.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
var vm = new Vue({
|
||||
el: "div",
|
||||
data: {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
});
|
11972
FAuth/wwwroot/lib/vue/vue.js
Normal file
11972
FAuth/wwwroot/lib/vue/vue.js
Normal file
File diff suppressed because it is too large
Load Diff
6
FAuth/wwwroot/lib/vue/vue.min.js
vendored
Normal file
6
FAuth/wwwroot/lib/vue/vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user