Commit 49dd4d00 authored by alicewang's avatar alicewang

Merge branch 'master' into alice

# Conflicts:
#	Merchant Token Vault Management/backstage/wwwroot/css/style.css
parents a2d14cf6 e1cd39b5
...@@ -14,7 +14,7 @@ using System.Net.Http; ...@@ -14,7 +14,7 @@ using System.Net.Http;
namespace backstage.Controllers namespace backstage.Controllers
{ {
//[Authorize] //[Authorize]
public class HomeController : Controller public class HomeController : Controller
...@@ -39,23 +39,31 @@ namespace backstage.Controllers ...@@ -39,23 +39,31 @@ namespace backstage.Controllers
public async Task<IActionResult> Index() public async Task<IActionResult> Index()
{ {
ResultModel result = new ResultModel(); ResultModel result = new ResultModel();
return View(); return View();
} }
public IActionResult Error() public IActionResult Error()
{ {
return View(); return View();
} }
public IActionResult AccessDenied()
{
TempData["IsSuccess"] = false;
TempData["msg"] = "您沒有訪問此頁面的權限。";
return RedirectToAction("Index");
}
} }
......
...@@ -255,7 +255,7 @@ namespace backstage.Controllers ...@@ -255,7 +255,7 @@ namespace backstage.Controllers
return View(); return View();
} }
[Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> AddUsers([FromBody] JsonElement requestData) public async Task<IActionResult> AddUsers([FromBody] JsonElement requestData)
{ {
...@@ -530,6 +530,7 @@ namespace backstage.Controllers ...@@ -530,6 +530,7 @@ namespace backstage.Controllers
{ "field_id", field_id }, { "field_id", field_id },
}; };
#region list mask
var url = _config["IP"] + "/v2/vault/get"; var url = _config["IP"] + "/v2/vault/get";
var httpMethod = HttpMethod.Post; var httpMethod = HttpMethod.Post;
// 取得使用者的 "token" Claim 值 // 取得使用者的 "token" Claim 值
...@@ -585,10 +586,12 @@ namespace backstage.Controllers ...@@ -585,10 +586,12 @@ namespace backstage.Controllers
} }
} }
#endregion
return RedirectToAction("ListFields", queryString); return RedirectToAction("ListFields", queryString);
} }
//新增欄位 //新增欄位
[Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> CreateField(FieldForCreate FieldForCreate) public async Task<IActionResult> CreateField(FieldForCreate FieldForCreate)
{ {
...@@ -693,27 +696,25 @@ namespace backstage.Controllers ...@@ -693,27 +696,25 @@ namespace backstage.Controllers
} }
//新增MASK //新增MASK ajax
[Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> CreateMask(Mask mask, int merchant_id, int vault_id, int field_id) public async Task<ResultModel> CreateMask(IFormCollection form)
{ {
// 構建包含參數的查詢字串 var result = new ResultModel();
var queryString = new RouteValueDictionary {
{ "Merchant_id", merchant_id },
{ "vault_id", vault_id },
{ "field_id", field_id }
};
try try
{ {
var url = _config["IP"] + "/v2/vault"; var url = _config["IP"] + "/v2/vault";
if (string.IsNullOrEmpty(mask.name)) if (string.IsNullOrEmpty(form["name"]))
{ {
TempData["IsSuccess"] = false; result.IsSuccess = false;
TempData["msg"] = "名稱不能為空"; result.Message = "名稱不能為空";
return RedirectToAction("ListFields", queryString); return result;
} }
...@@ -722,32 +723,132 @@ namespace backstage.Controllers ...@@ -722,32 +723,132 @@ namespace backstage.Controllers
string token = User.FindFirstValue("token"); string token = User.FindFirstValue("token");
var setting = new var setting = new
{ {
mask=mask.mask, mask = Convert.ToInt32(form["mask"]),
size_init=mask.size_init, size_init = Convert.ToInt32(form["size_init"]),
size_end=mask.size_end size_end = Convert.ToInt32(form["size_end"])
}; };
var fieldData = new[] var fieldData = new[]
{ {
new new
{
action = "ADD",
field_id=Convert.ToInt32(form["field_id"]),
name=form["name"].ToString(),
type = Convert.ToInt32(form["type"]),
setting = System.Text.Json.JsonSerializer.Serialize(setting)
}
};
string namstext = form["name"];
var parameters = new Dictionary<string, string>
{
{ "Merchant_id",form["merchant_id"] },
{ "info","MASKS"},
{ "id", form["vault_id"]},
{ "data",JsonConvert.SerializeObject(fieldData)}
};
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
var Response = JsonConvert.DeserializeObject<Response>(apiResult.Data.ToString());
if (Response.r == 0)
{ {
action = "ADD", if (Response.failInfo == null)
field_id, {
mask.name, result.IsSuccess = true;
type = mask.type, result.Message = "Create success";
setting = setting return result;
}
result.IsSuccess = false;
result.Message = System.Text.RegularExpressions.Regex.Unescape(string.Join(", ", Response.failInfo));
return result;
}
else
{
result.IsSuccess = false;
result.Message = Response.m.ToString();
return result;
} }
}
}
catch (Exception e)
{
result.IsSuccess = false;
result.Message = e.Message + e.InnerException?.Message;
return result;
}
result.IsSuccess = false;
result.Message = "Create fail.";
return result;
//return View();
}
//刪除MASK ajax
[Authorize(Policy = "AdminOnly")]
[HttpPost]
public async Task<ResultModel> DeleteMask(IFormCollection form)
{
var result = new ResultModel();
try
{
var url = _config["IP"] + "/v2/vault";
if (string.IsNullOrEmpty(form["name"]))
{
result.IsSuccess = false;
result.Message = "名稱不能為空";
return result;
}
var httpMethod = HttpMethod.Post;
// 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token");
var setting = new
{
mask = Convert.ToInt32(form["mask"]),
size_init = Convert.ToInt32(form["size_init"]),
size_end = Convert.ToInt32(form["size_end"])
}; };
var fieldData = new[]
{
new
{
action = "MOD",
id=Convert.ToInt32(form["mask_id"]),
name=form["name"].ToString(),
type = Convert.ToInt32(form["type"]),
setting = System.Text.Json.JsonSerializer.Serialize(setting)
}
};
string namstext = form["name"];
var parameters = new Dictionary<string, string> var parameters = new Dictionary<string, string>
{ {
{ "Merchant_id", merchant_id.ToString() }, { "Merchant_id",form["merchant_id"] },
{ "info","MASKS"}, { "info","MASKS"},
{ "id", vault_id.ToString() }, { "id", form["vault_id"]},
{ "data",JsonConvert.SerializeObject(fieldData)} { "data",JsonConvert.SerializeObject(fieldData)}
}; };
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod); var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess) if (apiResult.IsSuccess)
{ {
...@@ -756,24 +857,23 @@ namespace backstage.Controllers ...@@ -756,24 +857,23 @@ namespace backstage.Controllers
{ {
if (Response.failInfo == null) if (Response.failInfo == null)
{ {
result.IsSuccess = true;
TempData["IsSuccess"] = true; result.Message = "Create success";
TempData["msg"] = "Create success"; return result;
return RedirectToAction("ListMasks", queryString);
} }
TempData["IsSuccess"] = false; result.IsSuccess = false;
TempData["msg"] = System.Text.RegularExpressions.Regex.Unescape(string.Join(", ", Response.failInfo)); result.Message = System.Text.RegularExpressions.Regex.Unescape(string.Join(", ", Response.failInfo));
return RedirectToAction("ListMasks", queryString); return result;
} }
else else
{ {
TempData["IsSuccess"] = false; result.IsSuccess = false;
TempData["msg"] = apiResult.Message; result.Message = Response.m.ToString();
return RedirectToAction("ListMasks", queryString); return result;
} }
...@@ -783,15 +883,154 @@ namespace backstage.Controllers ...@@ -783,15 +883,154 @@ namespace backstage.Controllers
catch (Exception e) catch (Exception e)
{ {
TempData["IsSuccess"] = false; result.IsSuccess = false;
TempData["msg"] = e.Message + e.InnerException?.Message; result.Message = e.Message + e.InnerException?.Message;
return RedirectToAction("ListMasks", queryString); return result;
} }
TempData["IsSuccess"] = false; result.IsSuccess = false;
TempData["msg"] = "Create fail."; result.Message = "Create fail.";
return RedirectToAction("ListMasks", queryString); return result;
}
//編輯MASK ajax
[Authorize(Policy = "AdminOnly")]
[HttpPost]
public async Task<ResultModel> EditMask(IFormCollection form)
{
var result = new ResultModel();
// var field_id = Convert.ToInt32(form["field_id"]);
// #region list mask
// var url = _config["IP"] + "/v2/vault/get";
// var httpMethod = HttpMethod.Post;
// // 取得使用者的 "token" Claim 值
// string token = User.FindFirstValue("token");
//var parameters = new Dictionary<string, string>
// {
// { "Merchant_id", form["Merchant_id"].ToString() },
// { "id", form["vault_id"].ToString() },
// { "info", "MASKS" }
// };
// var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
// if (apiResult.IsSuccess)
// {
// var FieldsResponse = JsonConvert.DeserializeObject<FieldsResponse>(apiResult.Data.ToString());
// if (FieldsResponse.r == 0)
// {
// if (FieldsResponse.fields.Count > 0)
// {
// var existField = FieldsResponse.fields.Where(f => f.id == field_id).FirstOrDefault();
// if (existField != null)
// {
// ViewBag.FieldName = existField.name;
// return View(existField.masks);
// }
// }
// }
// }
// #endregion
// try
// {
// var url = _config["IP"] + "/v2/vault";
// if (string.IsNullOrEmpty(form["name"]))
// {
// result.IsSuccess = false;
// result.Message = "名稱不能為空";
// return result;
// }
// var httpMethod = HttpMethod.Post;
// // 取得使用者的 "token" Claim 值
// string token = User.FindFirstValue("token");
// var setting = new
// {
// mask = Convert.ToInt32(form["mask"]),
// size_init = Convert.ToInt32(form["size_init"]),
// size_end = Convert.ToInt32(form["size_end"])
// };
// var fieldData = new[]
// {
// new
// {
// action = "ADD",
// field_id=Convert.ToInt32(form["field_id"]),
// name=form["name"].ToString(),
// type = Convert.ToInt32(form["type"]),
// setting = System.Text.Json.JsonSerializer.Serialize(setting)
// }
// };
// string namstext = form["name"];
// var parameters = new Dictionary<string, string>
// {
// { "Merchant_id",form["merchant_id"] },
// { "info","MASKS"},
// { "id", form["vault_id"]},
// { "data",JsonConvert.SerializeObject(fieldData)}
// };
// var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
// if (apiResult.IsSuccess)
// {
// var Response = JsonConvert.DeserializeObject<Response>(apiResult.Data.ToString());
// if (Response.r == 0)
// {
// if (Response.failInfo == null)
// {
// result.IsSuccess = true;
// result.Message = "Create success";
// return result;
// }
// result.IsSuccess = false;
// result.Message = System.Text.RegularExpressions.Regex.Unescape(string.Join(", ", Response.failInfo));
// return result;
// }
// else
// {
// result.IsSuccess = false;
// result.Message = Response.m.ToString();
// return result;
// }
// }
// }
// catch (Exception e)
// {
// result.IsSuccess = false;
// result.Message = e.Message + e.InnerException?.Message;
// return result;
// }
// result.IsSuccess = false;
// result.Message = "Create fail.";
return result;
} }
...@@ -880,6 +1119,7 @@ namespace backstage.Controllers ...@@ -880,6 +1119,7 @@ namespace backstage.Controllers
} }
[Authorize(Policy = "AdminOnly")]
[HttpGet] [HttpGet]
public async Task<IActionResult> CreateTokenVault() public async Task<IActionResult> CreateTokenVault()
{ {
...@@ -916,9 +1156,9 @@ namespace backstage.Controllers ...@@ -916,9 +1156,9 @@ namespace backstage.Controllers
return View(); return View();
} }
[Authorize(Policy = "AdminOnly")]
[HttpGet("/TokenVault/Edit/{id}")] [HttpGet("/TokenVault/Edit/{id}")]
public async Task<IActionResult> Edit(int id, [FromQuery] int merchantid)
public async Task<IActionResult> Edit(int id, [FromQuery] int merchantid)
{ {
#region 取得部門列表 #region 取得部門列表
var DepartmentsResponse = new DepartmentsResponse(); var DepartmentsResponse = new DepartmentsResponse();
...@@ -983,6 +1223,7 @@ namespace backstage.Controllers ...@@ -983,6 +1223,7 @@ namespace backstage.Controllers
return View(); return View();
} }
[Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> CreateTokenVault(TokenVaultForCreate tokenVault) public async Task<IActionResult> CreateTokenVault(TokenVaultForCreate tokenVault)
{ {
......
...@@ -21,7 +21,7 @@ using TokenVault_management.Models; ...@@ -21,7 +21,7 @@ using TokenVault_management.Models;
namespace backstage.Controllers namespace backstage.Controllers
{ {
public class UserController : Controller public class UserController : Controller
{ {
private readonly IHttpContextAccessor _httpContextAccessor; private readonly IHttpContextAccessor _httpContextAccessor;
...@@ -40,23 +40,198 @@ namespace backstage.Controllers ...@@ -40,23 +40,198 @@ namespace backstage.Controllers
_httpContextAccessor = httpContextAccessor; _httpContextAccessor = httpContextAccessor;
} }
[HttpGet] [HttpGet]
public async Task<IActionResult> Login() public async Task<IActionResult> Login()
{ {
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(User user, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(user);
}
//var u = await _UserRepository.Login(user);
var u = new UserLogin();
var url = _config["IP"];
var parameters = new Dictionary<string, string>
{
{ "username", user.username },
{ "pwd", user.pwd },
{ "reqPermFlag[0]","admin-login"}
};
var httpMethod = HttpMethod.Post;
int maxTry = 2;
int currentTry = 0;
while (currentTry < maxTry)
{
try
{
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
// API 呼叫成功,進行相應的處理
u = JsonConvert.DeserializeObject<UserLogin>(apiResult.Data.ToString());
if (u.r == 0 && !string.IsNullOrEmpty(u.token))
{
string role = "";
if (user.username == "theone")
{
role = "Admin";
}
else
{
#region admin/list
url = _config["IP"] + "/admin/list";
httpMethod = HttpMethod.Post;
var types = new[] { "admin" };
var types_data = new { inc = types };
role = "Merchant";
parameters = new Dictionary<string, string>
{
{ "token", u.token },
{ "types", JsonConvert.SerializeObject(types_data)},
};
apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
var adminResponse = new UserResponse();
if (apiResult.IsSuccess)
{
adminResponse = JsonConvert.DeserializeObject<UserResponse>(apiResult.Data.ToString());
if (adminResponse.r == 0)
{
var existAdmin = adminResponse.Users.Where(u => u.username == user.username).FirstOrDefault();
if (existAdmin != null)
{
if (existAdmin.enabled == 1)
role = "Admin";
}
}
}
#endregion
}
#region 寫入TOKEN
int LoginExpireMinute = Convert.ToInt32(_config["LoginExpireMinute"]);
string key = _config["TokenKey"];
var Cookieoptions = new CookieOptions();
////時間一到就會把Token從Cookie洗掉,如果Expires沒比API的Expires長,則每次Token過期都須重新登入
Cookieoptions.Expires = DateTime.Now.AddMinutes(LoginExpireMinute);
//Cookieoptions.SameSite = SameSiteMode.Strict;
Cookieoptions.HttpOnly = true;
var userClaims = new ClaimsIdentity(new[]
{
new Claim("username", user.username),
new Claim("token", u.token),
new Claim(ClaimTypes.Role, role),
}, CookieAuthenticationDefaults.AuthenticationScheme);
//將 ClaimsIdentity 設定給 ClaimsPrincipal (持有者)
ClaimsPrincipal principal = new ClaimsPrincipal(userClaims);
//登入動作
try
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
{
//是否可以被刷新
AllowRefresh = true,
// 設置了一個 1 天 有效期的持久化 cookie
IsPersistent = true, //IsPersistent = false,瀏覽器關閉即刻登出
//用戶頁面停留太久,逾期時間,在此設定的話會覆蓋Startup.cs裡的逾期設定
ExpiresUtc = DateTime.Now.AddMinutes(LoginExpireMinute),
});
}
catch (Exception ex)
{
logger.Trace(ex.Message + ex.InnerException?.Message);
}
#endregion
return RedirectToAction("Index", "Home");
}
else if (u.r == 65796)
{
currentTry++;
parameters["reqPermFlag[0]"] = "merchant-login";
continue;
}
else
{
TempData["IsSuccess"] = false;
TempData["msg"] = u.m;
return View(apiResult.Message);
}
}
else
{
// API 呼叫失敗,進行相應的錯誤處理
return BadRequest(apiResult.Message);
}
}
catch (Exception ex)
{
// 處理 API 呼叫發生的例外狀況
return StatusCode(500, $"API 呼叫發生錯誤:{ex.Message}");
}
}
TempData["IsSuccess"] = false;
TempData["msg"] = "發生錯誤";
return View(); return View();
} }
[Authorize] [Authorize]
[HttpGet] [HttpGet]
public async Task<IActionResult> ListUsers() public async Task<IActionResult> ListUsers()
{ {
var UserResponse = new UserResponse(); var UserResponse = new UserResponse();
// 取得使用者的 "token" Claim 值 // 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token"); string token = User.FindFirstValue("token");
...@@ -139,7 +314,6 @@ namespace backstage.Controllers ...@@ -139,7 +314,6 @@ namespace backstage.Controllers
public async Task<IActionResult> GetUser(int uid) public async Task<IActionResult> GetUser(int uid)
{ {
var url = _config["IP"] + "/user/get"; var url = _config["IP"] + "/user/get";
var httpMethod = HttpMethod.Post; var httpMethod = HttpMethod.Post;
...@@ -175,18 +349,18 @@ namespace backstage.Controllers ...@@ -175,18 +349,18 @@ namespace backstage.Controllers
{ {
if (!string.IsNullOrEmpty(GetUserResponse.user.username)) if (!string.IsNullOrEmpty(GetUserResponse.user.username))
{ {
var user = new User(); //var user = new User();
user.name = GetUserResponse.user.name; //user.name = GetUserResponse.user.name;
user.username = GetUserResponse.user.username; //user.username = GetUserResponse.user.username;
if (GetUserResponse.email != null) if (GetUserResponse.email != null)
user.email = GetUserResponse.email; GetUserResponse.user.email = GetUserResponse.email;
// 使用 JSON 解析工具將 JSON 字串轉換為物件 // 使用 JSON 解析工具將 JSON 字串轉換為物件
//var jsonObject = JsonConvert.DeserializeObject<Dictionary<string, string>>(apiResult.Data.ToString()); //var jsonObject = JsonConvert.DeserializeObject<Dictionary<string, string>>(apiResult.Data.ToString());
GetUserResponse.user.uid = uid;
//user.created_date = DateTime.Parse(jsonObject["created_date"]); //user.created_date = DateTime.Parse(jsonObject["created_date"]);
return View(user); return View(GetUserResponse.user);
} }
} }
else else
...@@ -213,20 +387,159 @@ namespace backstage.Controllers ...@@ -213,20 +387,159 @@ namespace backstage.Controllers
return View(); return View();
} }
/// <summary>
/// 修改密碼
/// </summary>
/// <returns></returns>
[Authorize]
[HttpGet]
public async Task<IActionResult> ChangePassword(string username, string returnUrl)
{
if (User.Identity.IsAuthenticated && User.IsInRole("Admin"))
{
// 使用者已驗證並具有 "admin" 角色
var url = _config["IP"] + "/user/list";
ViewBag.returnUrl = returnUrl;
var httpMethod = HttpMethod.Post;
// 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token");
var types = new[] { "all" };
var types_data = new { inc = types };
var parameters = new Dictionary<string, string>
{
{ "token", token },
{ "types",JsonConvert.SerializeObject( types_data)}
};
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
try
{
var UserResponse = JsonConvert.DeserializeObject<UserResponse>(apiResult.Data.ToString());
if (UserResponse.r == 0)
{
if (UserResponse.userCount > 0)
{
var existUser = UserResponse.Users.Where(u => u.username == username).FirstOrDefault();
if (existUser == null)
{
TempData["IsSuccess"] = false;
TempData["msg"] = "使用者不存在";
return Redirect("~" + returnUrl);
}
else
{
return View(existUser);
}
}
TempData["IsSuccess"] = false;
TempData["msg"] = "使用者不存在";
return Redirect("~" + returnUrl);
}
else if (UserResponse.r == 65537)
{
}
else
{
TempData["IsSuccess"] = false;
TempData["msg"] = "發生錯誤";
return RedirectToAction(returnUrl);
}
}
catch (Exception e)
{
TempData["IsSuccess"] = false;
TempData["msg"] = e.Message;
return Redirect("~" + returnUrl);
}
}
TempData["IsSuccess"] = false;
TempData["msg"] = "發生錯誤";
return Redirect("~" + returnUrl);
}
else {
ViewBag.returnUrl = returnUrl;
return View();
}
}
[Authorize] [Authorize]
[HttpPost]
public async Task<IActionResult> ChangePassword(User user, string returnUrl)
{
var url = _config["IP"] + "/admin/changepassword";
if (string.IsNullOrEmpty(user.password))
{
ModelState.AddModelError("Password", "密碼不能為空");
}
var httpMethod = HttpMethod.Post;
// 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token");
var parameters = new Dictionary<string, string>
{
{ "token", token },
{ "newpwd",user.newPassword}
};
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
var userAddResponse = JsonConvert.DeserializeObject<UserAddResponse>(apiResult.Data.ToString());
if (userAddResponse.r == 0)
{
TempData["IsSuccess"] = true;
TempData["msg"] = "更改密碼成功";
return RedirectToAction("ListUsers");
}
else
{
TempData["IsSuccess"] = false;
TempData["msg"] = JsonConvert.SerializeObject(userAddResponse.m);
return View(user);
}
}
return View();
}
[Authorize(Policy = "AdminOnly")]
[HttpGet] [HttpGet]
public async Task<IActionResult> CreateUser() public async Task<IActionResult> CreateUser()
{ {
return View(); return View();
} }
[Authorize] [Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> CreateUser(User user) public async Task<IActionResult> CreateUser(User user)
{ {
var url = _config["IP"] + "/user/add"; var url = _config["IP"] + "/user/add";
if (string.IsNullOrEmpty(user.password)) if (string.IsNullOrEmpty(user.password))
{ {
ModelState.AddModelError("Password", "密碼不能為空"); ModelState.AddModelError("Password", "密碼不能為空");
...@@ -274,7 +587,7 @@ namespace backstage.Controllers ...@@ -274,7 +587,7 @@ namespace backstage.Controllers
public async Task<IActionResult> GetUser(User user) public async Task<IActionResult> GetUser(User user)
{ {
// 取得使用者的 "token" Claim 值 // 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token"); string token = User.FindFirstValue("token");
...@@ -315,8 +628,8 @@ namespace backstage.Controllers ...@@ -315,8 +628,8 @@ namespace backstage.Controllers
var existName = UserResponse.Users.Where(u => u.name == user.name).FirstOrDefault(); var existName = UserResponse.Users.Where(u => u.name == user.name).FirstOrDefault();
if (existName != null) if (existName != null)
{ {
if(existName.uid!=user.uid) if (existName.uid != user.uid)
ModelState.AddModelError("name", "name重複"); ModelState.AddModelError("name", "name重複");
} }
//檢查username //檢查username
if (string.IsNullOrEmpty(user.username)) if (string.IsNullOrEmpty(user.username))
...@@ -337,20 +650,20 @@ namespace backstage.Controllers ...@@ -337,20 +650,20 @@ namespace backstage.Controllers
existUser.name = user.name; existUser.name = user.name;
existUser.username = user.username; existUser.username = user.username;
//檢查通過 //檢查通過
url = _config["IP"] + "/user/mod"; url = _config["IP"] + "/user/mod";
parameters = new Dictionary<string, string> parameters = new Dictionary<string, string>
{ {
{ "token", token }, { "token", token },
{ "data", JsonConvert.SerializeObject(user)} { "data", JsonConvert.SerializeObject(existUser)}
//{ "types", "{\"inc\":[\"all\"]}"} //{ "types", "{\"inc\":[\"all\"]}"}
}; };
apiResult = await _callApi.CallAPI(url, parameters, httpMethod); apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess) if (apiResult.IsSuccess)
{ {
TempData["IsSuccess"] = true; TempData["IsSuccess"] = true;
...@@ -358,7 +671,7 @@ namespace backstage.Controllers ...@@ -358,7 +671,7 @@ namespace backstage.Controllers
return RedirectToAction("ListUsers"); return RedirectToAction("ListUsers");
} }
TempData["IsSuccess"] = false; TempData["IsSuccess"] = false;
TempData["msg"] = "user_id不存在"; TempData["msg"] = "user_id不存在";
return View(existUser); return View(existUser);
...@@ -423,7 +736,7 @@ namespace backstage.Controllers ...@@ -423,7 +736,7 @@ namespace backstage.Controllers
public async Task<IActionResult> GetDepartment(int id) public async Task<IActionResult> GetDepartment(int id)
{ {
var url = _config["IP"] + "/merchant/get"; var url = _config["IP"] + "/merchant/get";
var httpMethod = HttpMethod.Post; var httpMethod = HttpMethod.Post;
// 取得使用者的 "token" Claim 值 // 取得使用者的 "token" Claim 值
...@@ -461,19 +774,19 @@ namespace backstage.Controllers ...@@ -461,19 +774,19 @@ namespace backstage.Controllers
return View(); return View();
} }
[Authorize] [Authorize(Policy = "AdminOnly")]
[HttpGet] [HttpGet]
public async Task<IActionResult> CreateDepartment() public async Task<IActionResult> CreateDepartment()
{ {
return View(); return View();
} }
[Authorize] [Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<IActionResult> CreateDepartment(DepartmentForCreate department) public async Task<IActionResult> CreateDepartment(DepartmentForCreate department)
{ {
var url = _config["IP"] + "/merchant/add"; var url = _config["IP"] + "/merchant/add";
if (string.IsNullOrEmpty(department.name)) if (string.IsNullOrEmpty(department.name))
{ {
ModelState.AddModelError("name", "部門名稱不能為空"); ModelState.AddModelError("name", "部門名稱不能為空");
...@@ -521,112 +834,6 @@ namespace backstage.Controllers ...@@ -521,112 +834,6 @@ namespace backstage.Controllers
} }
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(User user, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(user);
}
//var u = await _UserRepository.Login(user);
var u = new UserLogin();
var url = _config["IP"];
var parameters = new Dictionary<string, string>
{
{ "username", user.username },
{ "pwd", user.pwd },
{ "reqPermFlag[0]","admin-login"}
};
var httpMethod = HttpMethod.Post;
try
{
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
// API 呼叫成功,進行相應的處理
u = JsonConvert.DeserializeObject<UserLogin>(apiResult.Data.ToString());
if (u.r == 0 && !string.IsNullOrEmpty(u.token))
{
#region 寫入TOKEN
int LoginExpireMinute = Convert.ToInt32(_config["LoginExpireMinute"]);
string key = _config["TokenKey"];
var Cookieoptions = new CookieOptions();
////時間一到就會把Token從Cookie洗掉,如果Expires沒比API的Expires長,則每次Token過期都須重新登入
Cookieoptions.Expires = DateTime.Now.AddMinutes(LoginExpireMinute);
//Cookieoptions.SameSite = SameSiteMode.Strict;
Cookieoptions.HttpOnly = true;
var userClaims = new ClaimsIdentity(new[]
{
new Claim("username", user.username),
new Claim("token", u.token),
}, CookieAuthenticationDefaults.AuthenticationScheme);
//將 ClaimsIdentity 設定給 ClaimsPrincipal (持有者)
ClaimsPrincipal principal = new ClaimsPrincipal(userClaims);
//登入動作
try
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties()
{
//是否可以被刷新
AllowRefresh = true,
// 設置了一個 1 天 有效期的持久化 cookie
IsPersistent = true, //IsPersistent = false,瀏覽器關閉即刻登出
//用戶頁面停留太久,逾期時間,在此設定的話會覆蓋Startup.cs裡的逾期設定
ExpiresUtc = DateTime.Now.AddMinutes(LoginExpireMinute),
});
}
catch (Exception ex)
{
logger.Trace(ex.Message + ex.InnerException?.Message);
}
#endregion
return RedirectToAction("Index", "Home");
}
else
{
// API 呼叫失敗,進行相應的錯誤處理
return BadRequest(apiResult.Message);
}
}
else
{
// API 呼叫失敗,進行相應的錯誤處理
return BadRequest(apiResult.Message);
}
}
catch (Exception ex)
{
// 處理 API 呼叫發生的例外狀況
return StatusCode(500, $"API 呼叫發生錯誤:{ex.Message}");
}
}
/// <summary> /// <summary>
/// enable做兩件事情,user加入admin,並且enable=true, /// enable做兩件事情,user加入admin,並且enable=true,
...@@ -635,7 +842,7 @@ namespace backstage.Controllers ...@@ -635,7 +842,7 @@ namespace backstage.Controllers
/// <param name="uid"></param> /// <param name="uid"></param>
/// <param name="isAdmin"></param> /// <param name="isAdmin"></param>
/// <returns></returns> /// <returns></returns>
[Authorize] [Authorize(Policy = "AdminOnly")]
[HttpPost] [HttpPost]
public async Task<ResultModel> AdminAddAjax(int uid, bool isAdmin) public async Task<ResultModel> AdminAddAjax(int uid, bool isAdmin)
{ {
...@@ -783,7 +990,99 @@ namespace backstage.Controllers ...@@ -783,7 +990,99 @@ namespace backstage.Controllers
[Authorize(Policy = "AdminOnly")]
[HttpPost]
public async Task<ResultModel> UserEnableAjax(int uid, int enabled)
{
var result = new ResultModel();
// 取得使用者的 "token" Claim 值
string token = User.FindFirstValue("token");
#region user/list
var url = _config["IP"] + "/user/list";
var httpMethod = HttpMethod.Post;
var types = new[] { "all" };
var types_data = new { inc = types };
var parameters = new Dictionary<string, string>
{
{ "token", token },
{ "types", JsonConvert.SerializeObject(types_data)},
{ "email","1"},
{ "phone","1"}
//{ "types", "{\"inc\":[\"all\"]}"}
};
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
var UserResponse = JsonConvert.DeserializeObject<UserResponse>(apiResult.Data.ToString());
if (UserResponse.userCount > 0)
{
var existUser = UserResponse.Users.Where(u => u.uid == uid).FirstOrDefault();
if (existUser == null)
{
result.IsSuccess = false;
result.Message = "user_id不存在";
return result;
}
//檢查通過
url = _config["IP"] + "/user/mod";
var data = new
{
uid = uid,
enabled = enabled
};
parameters = new Dictionary<string, string>
{
{ "token", token },
{ "data", JsonConvert.SerializeObject(data) }
};
apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
var response = JsonConvert.DeserializeObject<Response>(apiResult.Data.ToString());
if (response.r == 0)
{
result.IsSuccess = true;
result.Message = "權限調整成功";
return result;
}
}
result.IsSuccess = false;
result.Message = "發生錯誤";
return result;
}
result.IsSuccess = false;
result.Message = "發生錯誤";
return result;
}
result.IsSuccess = false;
result.Message = "發生錯誤";
return result;
#endregion
}
[HttpGet] [HttpGet]
public async Task<IActionResult> Logout() public async Task<IActionResult> Logout()
{ {
...@@ -794,6 +1093,5 @@ namespace backstage.Controllers ...@@ -794,6 +1093,5 @@ namespace backstage.Controllers
} }
} }
} }
\ No newline at end of file
...@@ -18,6 +18,7 @@ namespace backstage.Models.Users ...@@ -18,6 +18,7 @@ namespace backstage.Models.Users
public string pwd { get; set; } public string pwd { get; set; }
//新增使用者用 //新增使用者用
public string password { get; set; } public string password { get; set; }
public string newPassword { get; set; }
public List<emaildata> email { get; set; } public List<emaildata> email { get; set; }
public int locked { get; set; } public int locked { get; set; }
......
...@@ -39,7 +39,8 @@ namespace backstage ...@@ -39,7 +39,8 @@ namespace backstage
services.AddControllersWithViews(); services.AddControllersWithViews();
services.AddAuthorization(); services.AddAuthorization();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie("Cookies", option => services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie("Cookies", option =>
{ {
option.Cookie.HttpOnly = true; option.Cookie.HttpOnly = true;
...@@ -47,11 +48,26 @@ namespace backstage ...@@ -47,11 +48,26 @@ namespace backstage
option.LogoutPath = new PathString("/User/Logout"); option.LogoutPath = new PathString("/User/Logout");
option.Cookie.Name = "backstage"; option.Cookie.Name = "backstage";
option.Cookie.SameSite = SameSiteMode.Strict; option.Cookie.SameSite = SameSiteMode.Strict;
option.Events = new CookieAuthenticationEvents
{
OnRedirectToAccessDenied = context =>
{
context.Response.Redirect("/Home/AccessDenied"); // 將使用者重新導向到 Home/AccessDenied
return Task.CompletedTask;
}
};
////�n�J���Įɶ� });
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
// 設定需要 "Admin" 角色的策略
policy.RequireRole("Admin");
});
}); });
// �N Session �s�b ASP.NET Core �O���餤
services.AddDistributedMemoryCache(); services.AddDistributedMemoryCache();
services.AddHttpContextAccessor(); services.AddHttpContextAccessor();
......
...@@ -9,69 +9,49 @@ ...@@ -9,69 +9,49 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div>
<div class="page-header">
<h3 class="page-title">數據統計</h3>
</div> </div>
@*<div class="row"> <div class="row">
<div class="col-lg-6 grid-margin stretch-card"> <div class="col-lg-4 col-md-6 grid-margin stretch-card dashboard-card">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h4 class="card-title">代辦事項</h4> <h4 class="card-title">Token Vault Entry 總數量</h4>
<div class="add-items d-flex"> <div class="card-content text-center">
<img src="images/admin-vault.svg" class="img-fuild">
<input id="new_task" type="text" class="form-control todo-list-input" placeholder="要做什麼呢?"> <p class="number text-center">200</p>
<button class="add btn btn-primary font-weight-bold todo-list-add-btn white-nowrap" id="add-task">新增</button>
</div> </div>
<div class="list-wrapper scrollbar"> </div>
<ul class="d-flex flex-column-reverse todo-list todo-list-custom"> </div>
</div>
</ul> <div class="col-lg-4 col-md-6 grid-margin stretch-card dashboard-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">本月新增 Token Vualt Entry 數量</h4>
<div class="card-content text-center">
<img src="/images/admin-vault-add.svg" class="img-fuild">
<p class="number text-center">10</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-6 grid-margin stretch-card">
<div class="col-lg-4 col-md-6 grid-margin stretch-card dashboard-card">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h4 class="card-title">本月修改 Token Vualt Entry 數量</h4>
<h4 class="card-title">購買項目到期提醒(前後一個月)</h4> <div class="card-content text-center">
<div class="table-scroll scrollbar"> <img src="/images/admin-vault-edit.svg" class="img-fuild">
<table class="table table-hover"> <p class="number text-center">7</p>
<thead>
<tr>
<th>到期日</th>
<th>項目</th>
<th>聯絡人</th>
<th>聯絡手機</th>
<th>登記姓名</th>
</tr>
</thead>
<tbody>
@if (ViewBag.ToBeExpired != null)
{
@foreach (var i in ViewBag.ToBeExpired)
{
<tr>
<td><label class="text-danger">@i.DueDate</label></td>
<td>@i.ItemName</td>
<td>@i.CustomerName</td>
<td>@i.CustomerPhone</td>
<td>@i.Name</td>
</tr>
}
}
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>*@
</div> </div>
...@@ -79,43 +59,12 @@ ...@@ -79,43 +59,12 @@
<script src="~/js/Home.js"></script> <script src="~/js/Home.js"></script>
<script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf"> <script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf">
var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg);
if (msg != '') {
showAlert(IsSuccess, msg);
}
@*$(function () {
let eventsArr = [];
let eventsTable = document.getElementById("eventsTable");
let trElems = eventsTable.getElementsByTagName("tr")
for (let tr of trElems) {
let tdElems = tr.getElementsByTagName("td");
let eventObj = {
id: tdElems[0].innerText,
title: tdElems[1].innerText,
start: tdElems[2].innerText,
};
eventsArr.push(eventObj);
}
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
locale: 'zh-cn',
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prevYear prev,next nextYear today',
center: 'title',
right: 'dayGridMonth timeGridWeek timeGridDay'
},
buttonText: {
today: '今天',
month: '月',
week: '周',
day: '日',
},
events: eventsArr
});
calendar.render();
})*@
</script> </script>
} }
\ No newline at end of file
...@@ -75,15 +75,15 @@ ...@@ -75,15 +75,15 @@
</div> </div>
</a> </a>
<div class="dropdown-menu navbar-dropdown" aria-labelledby="profileDropdown"> <div class="dropdown-menu navbar-dropdown" aria-labelledby="profileDropdown">
<a class="dropdown-item" asp-controller="User" asp-action="ChangePassword"> <a class="dropdown-item" asp-controller="User" asp-action="ChangePassword" asp-route-username="@Context.User.Claims.FirstOrDefault(m => m.Type == "username").Value" asp-route-returnUrl="@Context.Request.Path">
<i class="mdi mdi-lock-open mr-2"></i>更改密碼 <i class="mdi mdi-lock-open mr-2"></i>更改密碼
</a> </a>
<a class="dropdown-item" asp-controller="User" asp-action="Register"> @*<a class="dropdown-item" asp-controller="User" asp-action="Register">
<i class="mdi mdi-account-plus mr-2"></i>註冊管理員 <i class="mdi mdi-account-plus mr-2"></i>註冊管理員
</a> </a>*@
<a class="dropdown-item" asp-controller="UserManage" asp-action="GetUserManage"> @*<a class="dropdown-item" asp-controller="UserManage" asp-action="GetUserManage">
<i class="mdi mdi-account-details mr-2"></i>帳號管理 <i class="mdi mdi-account-details mr-2"></i>帳號管理
</a> </a>*@
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" asp-controller="User" asp-action="Logout"> <a class="dropdown-item" asp-controller="User" asp-action="Logout">
<i class="mdi mdi-logout mr-2 text-danger"></i>登出 <i class="mdi mdi-logout mr-2 text-danger"></i>登出
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
@{ @{
ViewData["Title"] = "TokenVault列表管理"; ViewData["Title"] = "TokenVault列表管理";
} }
@{
bool isAdmin = User.IsInRole("admin");
string disabledClass = isAdmin ? "" : "disabled";
}
<div class="page-header"> <div class="page-header">
<h3 class="page-title">TokenVault列表管理</h3> <h3 class="page-title">TokenVault列表管理</h3>
...@@ -11,7 +14,7 @@ ...@@ -11,7 +14,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
...@@ -23,7 +26,7 @@ ...@@ -23,7 +26,7 @@
<div class="col-md-12"> <div class="col-md-12">
<ul class="breadcrumb breadcrumb_memberGo"> <ul class="breadcrumb breadcrumb_memberGo">
<li class="breadcrumb-item active">資料代碼保險庫</li> <li class="breadcrumb-item active">資料代碼保險庫</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -38,7 +41,7 @@ ...@@ -38,7 +41,7 @@
</select> </select>
</div> </div>
<div class="col-md-auto"> <div class="col-md-auto">
<a type="button" class="btn btn-info float-right mb-2" asp-action="CreateTokenVault">Create</a> <a type="button" class="btn btn-info float-right mb-2 @disabledClass" asp-action="CreateTokenVault">Create</a>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
...@@ -149,7 +152,7 @@ ...@@ -149,7 +152,7 @@
$('#selectDepartmentList').change(function () { $('#selectDepartmentList').change(function () {
var selectedValue = $(this).val(); // 獲取選擇的值 var selectedValue = $(this).val(); // 獲取選擇的值
loadData(selectedValue); loadData(selectedValue);
}); });
// 定義 AJAX 請求函式,將選單值傳遞至後端並填入 tbody // 定義 AJAX 請求函式,將選單值傳遞至後端並填入 tbody
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
@{ @{
ViewData["Title"] = "Fields列表管理"; ViewData["Title"] = "Fields列表管理";
} }
@{
bool isAdmin = User.IsInRole("admin");
string disabledClass = isAdmin ? "" : "disabled";
}
@section header{ @section header{
<script> <script>
//欄位檢查 //欄位檢查
...@@ -39,7 +42,7 @@ ...@@ -39,7 +42,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
...@@ -75,7 +78,7 @@ ...@@ -75,7 +78,7 @@
</div> </div>
</div> </div>
<div style="float: right;"> <div style="float: right;">
<a type="button" class="btn btn-info float-right mb-2" data-toggle="modal" data-target="#myModal">Create</a> <a type="button" class="btn btn-info float-right mb-2 @disabledClass" data-toggle="modal" data-target="#myModal">Create</a>
</div> </div>
</div> </div>
<div> <div>
...@@ -129,8 +132,8 @@ ...@@ -129,8 +132,8 @@
</div> </div>
</div> </div>
<!-- MODAL --> <!-- MODAL -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
@{ @{
ViewData["Title"] = "Mask列表管理"; ViewData["Title"] = "Mask列表管理";
} }
@{
bool isAdmin = User.IsInRole("admin");
string disabledClass = isAdmin ? "" : "disabled";
}
<div class="page-header"> <div class="page-header">
<h3 class="page-title">Mask列表管理</h3> <h3 class="page-title">Mask列表管理</h3>
...@@ -11,7 +14,7 @@ ...@@ -11,7 +14,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
...@@ -57,7 +60,7 @@ ...@@ -57,7 +60,7 @@
</table> </table>
<div class="newBlock"> <div class="newBlock">
@*<button type="button" class="btn btn-mainblue-hollow" onclick="window.location.href='tokenVault_fields.html'"><img src="images/memberGo/apiKey/back_o_icons8-undo-90.png">返回</button>*@ @*<button type="button" class="btn btn-mainblue-hollow" onclick="window.location.href='tokenVault_fields.html'"><img src="images/memberGo/apiKey/back_o_icons8-undo-90.png">返回</button>*@
<button type="button" class="btn btn-mainblue-solid" data-toggle="modal" data-target="#new-field-mask"><img src="~/images/memberGo/add.png">新增遮罩</button> <button type="button" class="btn btn-mainblue-solid @disabledClass" data-toggle="modal" data-target="#new-field-mask"><img src="~/images/memberGo/add.png">新增遮罩</button>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
...@@ -73,6 +76,7 @@ ...@@ -73,6 +76,7 @@
<th style=" border-left: solid 1px #d9d9d9;">ID</th> <th style=" border-left: solid 1px #d9d9d9;">ID</th>
<th>名稱</th> <th>名稱</th>
<th>種類</th> <th>種類</th>
<th>遮罩</th>
<th>唯一值</th> <th>唯一值</th>
<th>設定</th> <th>設定</th>
<th>修改</th> <th>修改</th>
...@@ -86,17 +90,18 @@ ...@@ -86,17 +90,18 @@
<tr> <tr>
<td class="item">@m.id</td> <td class="item">@m.id</td>
<td class="mask_name">mask_name</td> <td class="mask_name">@m.name</td>
<td class="content">@m.type</td> <td class="content">@m.type</td>
<td class="content">@m.mask</td>
<td class="item">@(m.is_unique==1?"是":"否")</td> <td class="item">@(m.is_unique==1?"是":"否")</td>
<td class="content">@m.setting</td> <td class="content">@m.setting</td>
<td> <td>
<a data-toggle="modal" data-target="#edit-field-mask" title="修改"> <a class="editMaskBtn" data-toggle="modal" data-target="#edit-field-mask" title="修改">
<i class="fa-solid fa-pen-to-square"></i> <i class="fa-solid fa-pen-to-square"></i>
</a> </a>
</td> </td>
<td> <td>
<a data-toggle="modal" data-target="#delete-field-mask" title="刪除"> <a class="delMaskBtn" data-toggle="modal" data-target="#delete-field-mask" title="刪除">
<i class="fa-solid fa-trash-can"></i> <i class="fa-solid fa-trash-can"></i>
</a> </a>
</td> </td>
...@@ -137,26 +142,32 @@ ...@@ -137,26 +142,32 @@
</div> <!--END of div "modal-header"--> </div> <!--END of div "modal-header"-->
<div class="modal-body" style="padding-top:35px"> <div class="modal-body" style="padding-top:35px">
<form id="createMaskForm" class="form-horizontal0" method="post" autocomplete="off" > <form id="createMaskForm" class="form-horizontal0" method="post" autocomplete="off">
<div id="errorMsg" asp-validation-summary="All" class="text-danger"></div> <div id="errorMsg" asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<input hidden name="mask_id">
<input hidden name="merchant_id" value="@ViewBag.merchant_id">
<input hidden name="field_id" value="@ViewBag.field_id">
<input hidden name="vault_id" value="@ViewBag.vault_id">
</div>
<div class="form-group"> <div class="form-group">
<label class="control-labe" for="name">名稱:</label> <label class="control-labe required" for="name">名稱:</label>
<div class=""> <div class="">
<input type="text" name="name" class="form-control form-control-sm0"> <input type="text" name="name" class="form-control form-control-sm0" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-labe" for="">是否為唯一值:</label> <label class="control-labe" for="">是否為唯一值:</label>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="is_unique" id="uniqueY" value="option1" checked> <input class="form-check-input" type="radio" name="is_unique" id="uniqueY" value="1" checked>
<label class="form-check-label" for="uniqueY"> <label class="form-check-label" for="uniqueY">
</label> </label>
</div> </div>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="is_unique" id="uniqueN" value="option2"> <input class="form-check-input" type="radio" name="is_unique" id="uniqueN" value="0">
<label class="form-check-label" for="uniqueN"> <label class="form-check-label" for="uniqueN">
</label> </label>
...@@ -185,7 +196,7 @@ ...@@ -185,7 +196,7 @@
<label class="control-labe" for="userName">mask:</label> <label class="control-labe" for="userName">mask:</label>
<div class="form-group"> <div class="form-group">
<div class="dropdown bootstrap-select selecter form-control -tokenization"> <div class="dropdown bootstrap-select selecter form-control -tokenization">
<select title="請選擇mask(單選)" name="mask" class="selectpicker selecter form-control selectpicker-tokenization"> <select id="mask" title="請選擇mask(單選)" name="mask" class="selectpicker selecter form-control selectpicker-tokenization">
<option class="bs-title-option" value=""></option> <option class="bs-title-option" value=""></option>
<option>0</option> <option>0</option>
<option>1</option> <option>1</option>
...@@ -196,27 +207,27 @@ ...@@ -196,27 +207,27 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-labe" for="userName">size init:</label> <label class="control-labe required" for="userName">size init:</label>
<div class=""> <div class="">
<input type="number" name="size_init" class="form-control form-control-sm0"> <input type="number" name="size_init" class="form-control form-control-sm0" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-labe" for="userName">size end:</label> <label class="control-labe required" for="userName">size end:</label>
<div class=""> <div class="">
<input type="number" name="size_end" class="form-control form-control-sm0"> <input type="number" name="size_end" class="form-control form-control-sm0" required>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-labe" for="userName">to skip:</label> <label class="control-labe required" for="userName">to skip:</label>
<div class=""> <div class="">
<input type="text" name="toskip" class="form-control form-control-sm0"> <input type="text" name="toskip" class="form-control form-control-sm0" required>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="SubmitBlock"> <div class="SubmitBlock">
<button id="createMaskBtn" type="button" class="btn btn-mainblue-solid btnSubmit">新增</button> <button id="createMaskBtn" type="button" class="btn btn-mainblue-solid btnSubmit">送出</button>
<button type="button" class="btn btn-mainblue-hollow btnReset" data-dismiss="modal">取消</button> <button type="button" class="btn btn-mainblue-hollow btnReset" data-dismiss="modal">取消</button>
</div> </div>
</form> </form>
...@@ -233,8 +244,6 @@ ...@@ -233,8 +244,6 @@
</div> </div>
<!-- END of Modal--> <!-- END of Modal-->
<!--END of 新增遮罩 Popup Form--> <!--END of 新增遮罩 Popup Form-->
<!--刪除遮罩 Form--> <!--刪除遮罩 Form-->
<!-- Modal --> <!-- Modal -->
...@@ -258,7 +267,7 @@ ...@@ -258,7 +267,7 @@
</p> </p>
<div class="SubmitBlock SubmitBlock_sm"> <div class="SubmitBlock SubmitBlock_sm">
<button type="submit" class="btn btn-mainblue-solid" style="margin-right: 10px; width: 80px">確定</button> <button type="button" id="delMaskConfirmBtn" class="btn btn-mainblue-solid" style="margin-right: 10px; width: 80px">確定</button>
<button type="button" class="btn btn-mainblue-hollow" data-dismiss="modal" style="margin-right: 10px; width: 80px">取消</button> <button type="button" class="btn btn-mainblue-hollow" data-dismiss="modal" style="margin-right: 10px; width: 80px">取消</button>
</div> </div>
...@@ -284,47 +293,127 @@ ...@@ -284,47 +293,127 @@
$('document').ready(function () { $('document').ready(function () {
var msg = '@TempData["msg"]'; var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]'; var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg);
if (msg != '') { if (msg != '') {
showAlert(IsSuccess, msg); showAlert(IsSuccess, msg);
} }
//新增mask
$("#createMaskBtn").click(function (event) { $("#createMaskBtn").click(function (event) {
/* event.preventDefault();*/ $('#new-field-mask .modal-title').text('新增遮罩');
console.log('createMaskForm'); $.ajax({
var formData = { url: '/TokenVault/CreateMask',
mask: { type: 'POST',
name: $('input[name="name"]').val(), data: $('#createMaskForm').serialize(),
type: $('input[name="type"]').val(), success: function (data) {
is_unique: $('input[name="is_unique"]').val(), //console.log(data);
size_init: $('input[name="size_init"]').val(),
size_end: $('input[name="size_end"]').val(), showAlert(data.isSuccess, data.message);
mask: $('input[name="mask"]').val(), if (data.isSuccess) {
toskip: $('input[name="toskip"]').val(), $('#new-field-mask').modal('hide');
setTimeout(function () {
location.reload();
}, 2000);
}
}, },
merchant_id : parseInt('@ViewBag.Merchant_id'), error: function (xhr, status, error) {
vault_id : parseInt('@ViewBag.vault_id'), console.log(xhr.responseText);
field_id : parseInt('@ViewBag.field_id') showAlert(false, "發生錯誤");
}
});
})
//編輯mask
$(".editMaskBtn").click(function (event) {
var selectMaskId = 0;
selectMaskId = $(this).closest("tr").find("td:first").text();
console.log('selectMaskId=' + selectMaskId);
$('input[name="mask_id"]').val(selectMaskId);
$('#new-field-mask .modal-title').text('編輯遮罩');
var name = $("#memberGoTbl_masksList tr").filter(function () {
return $(this).find("td:first-child").text().trim() === selectMaskId;
}).find("td:nth-child(2)").text();
$("#new-field-mask input[name='name']").val(name);
var is_unique = $("#memberGoTbl_masksList tr").filter(function () {
return $(this).find("td:first-child").text().trim() === selectMaskId;
}).find("td:nth-child(5)").text();
$("#new-field-mask input[name='is_unique']").prop("checked", is_unique);
var type = $("#memberGoTbl_masksList tr").filter(function () {
return $(this).find("td:first-child").text().trim() === selectMaskId;
}).find("td:nth-child(3)").text();
$("#new-field-mask select[name='type'] option").filter(function () {
return $(this).val() === type;
}).prop("selected", true);
$('#new-field-mask').modal();
//$.ajax({
// url: '/TokenVault/EditMask',
// type: 'POST',
// data: $('#createMaskForm').serialize(),
// success: function (data) {
// //console.log(data);
// showAlert(data.isSuccess, data.message);
// if (data.isSuccess) {
// $('#new-field-mask').modal('hide');
// setTimeout(function () {
// location.reload();
// }, 2000);
// }
// },
// error: function (xhr, status, error) {
// console.log(xhr.responseText);
// showAlert(false, "發生錯誤");
// }
//});
})
//刪除mask
var selectMaskId = 0;
$('.delMaskBtn').click(function () {
selectMaskId = $(this).closest("tr").find("td:first").text();
console.log('selectMaskId=' + selectMaskId);
})
$('#delMaskConfirmBtn').click(function () {
var data = {
merchant_id:'@ViewBag.merchant_id',
vault_id:'@ViewBag.vault_id',
mask_id: selectMaskId
}; };
console.log('formData=' + JSON.stringify(formData));
// 提交表單
$.ajax({ $.ajax({
url: '/TokenVault/CreateMask', url: '/TokenVault/DeleteMask',
type: 'POST', type: 'POST',
data: JSON.stringify(formData), data: data,
contentType: "application/json; charset=utf-8", success: function (data) {
dataType: "json", //console.log(data);
success: function (response) {
// 處理成功回應 showAlert(data.isSuccess, data.message);
if (data.isSuccess) {
$('#delete-field-mask').modal('hide');
setTimeout(function () {
location.reload();
}, 2000);
}
}, },
error: function (error) { error: function (xhr, status, error) {
// 處理錯誤回應 console.log(xhr.responseText);
showAlert(false, "發生錯誤");
} }
}); });
}); })
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
@{ @{
ViewData["Title"] = "欄位Users列表管理"; ViewData["Title"] = "欄位Users列表管理";
} }
@{
bool isAdmin = User.IsInRole("admin");
string disabledClass = isAdmin ? "" : "disabled";
}
<div class="page-header"> <div class="page-header">
<h3 class="page-title">欄位Users列表管理</h3> <h3 class="page-title">欄位Users列表管理</h3>
...@@ -11,7 +14,7 @@ ...@@ -11,7 +14,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
...@@ -31,7 +34,7 @@ ...@@ -31,7 +34,7 @@
<div> <div>
<a type="button" class="btn btn-info float-right mb-2" data-toggle="modal" data-target="#myModal">Add User</a> <a type="button" class="btn btn-info float-right mb-2 @disabledClass" data-toggle="modal" data-target="#myModal">Add User</a>
<div class="rank-table"> <div class="rank-table">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped expense-color"> <table class="table table-striped expense-color">
...@@ -54,33 +57,35 @@ ...@@ -54,33 +57,35 @@
{ {
@foreach (var i in Model) @foreach (var i in Model)
{ {
<tr id="@i.id" class="expense-color"> <tr id="@i.id" class="expense-color">
<td>@i.id</td> <td>@i.id</td>
<td>@i.name</td> <td>@i.name</td>
<td>@i.username</td> <td>@i.username</td>
<td>@i.masksText</td> <td>@i.masksText</td>
<td> <td>
@if (i.allow_decrypt == 1) @if (i.allow_decrypt == 1)
{<span>&#x2714;</span>} {<span>&#x2714;</span>}
</td> </td>
<td> <td>
@if (i.allow_new == 1) @if (i.allow_new == 1)
{<span>&#x2714;</span>} {<span>&#x2714;</span>}
</td> </td>
<td> <td>
@if (i.allow_update == 1) @if (i.allow_update == 1)
{<span>&#x2714;</span>} {<span>&#x2714;</span>}
</td> </td>
<td>@if (i.allow_del == 1) <td>
{<span>&#x2714;</span>}</td> @if (i.allow_del == 1)
{<span>&#x2714;</span>}
<td>@i.default_mask_id</td> </td>
<td>
<td>@i.default_mask_id</td>
<a href="tokenVault_fields_users.html" class="btn btnPermission btn-sm">移除使用者</a> <td>
</td>
</tr> <a href="tokenVault_fields_users.html" class="btn btnPermission btn-sm">移除使用者</a>
} </td>
</tr>
}
} }
</tbody> </tbody>
...@@ -110,12 +115,12 @@ ...@@ -110,12 +115,12 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<select id="selectUser" class="form-control" asp-items="ViewBag.users"> <select id="selectUser" class="form-control" asp-items="ViewBag.users">
<!-- 其他用户选项 --> <!-- 其他用户选项 -->
</select> </select>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" id="confirmBtn" data-dismiss="modal">確認</button> <button type="button" class="btn btn-primary" id="confirmBtn" data-dismiss="modal">確認</button>
</div> </div>
</div> </div>
</div> </div>
......
@model backstage.Models.Users.User
@{
ViewData["Title"] = "更改密碼";
}
@{
bool isAdmin = User.IsInRole("Admin");
string displayStyle = isAdmin ? "" : "display:none;";
}
<!-- partial -->
<div class="page-header">
<h3 class="page-title">更改密碼</h3>
<input id="msg" hidden value="@TempData["msg"]" />
@if (TempData["isSuccess"] != null)
{
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
}
<div class="floating-msg" id="msgDiv"></div>
</div>
<div class="row">
<div class="col-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">更改密碼</h4>
<form class="forms-sample" method="post" asp-action="ChangePassword" asp-route-returnUrl="@ViewBag.returnUrl" autocomplete="off">
<div id="errorMsg" asp-validation-summary="All" class="text-danger"></div>
<input hidden asp-for="username" />
<p class="form-title card-description">帳號資訊</p>
<div class="row" style="@displayStyle">
<div class="col-md-4 form-group required">
<label asp-for="uid" class="col-form-label" for=""></label>
<input asp-for="uid" type="text" class="form-control" disabled>
</div>
<div class="col-md-4 form-group required">
<label asp-for="name" class="col-form-label" for=""></label>
<input asp-for="name" type="text" class="form-control" disabled>
</div>
<div class="col-md-4 form-group required">
<label asp-for="username" class="col-form-label" for=""></label>
<input asp-for="username" type="text" class="form-control" disabled>
</div>
</div>
<p class="form-title card-description">修改密碼</p>
<div class="row">
<div class="col-md-4 form-group required">
<label asp-for="password" class="col-form-label" for="">目前密碼</label>
<input asp-for="password" type="password" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-4 form-group required">
<label asp-for="newPassword" class="col-form-label">新密碼</label>
<input asp-for="newPassword" type="password" class="form-control" id="newPWD">
</div>
</div>
<div class="row">
<div class="col-md-4 form-group required">
<label class="col-form-label">確認新密碼</label>
<input class="form-control" type="password" id="confirmPWD">
<span id="passwordMatchError" class="text-danger" style="display: none;">兩次輸入的密碼不一致</span>
</div>
</div>
<button type="submit" class="btn btn-primary mr-2">送出</button>
<a type="button" class="btn btn-light" asp-action="Index" , asp-controller="Home">取消</a>
</form>
</div>
</div>
</div>
</div>
@section Scripts{
<script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf">
$(document).ready(function () {
var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg);
if (msg != '') {
showAlert(IsSuccess, msg);
}
$(".forms-sample").submit(function (event) {
event.preventDefault();
$('input').removeAttr('disabled');
this.submit();
});
$('#confirmPWD').keyup(function () {
var newPassword = $('#newPWD').val();
var confirmPassword = $(this).val();
if (newPassword !== confirmPassword) {
$('#passwordMatchError').show();
} else {
$('#passwordMatchError').hide();
}
});
})
</script>
}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 grid-margin stretch-card"> <div class="col-12 grid-margin stretch-card">
...@@ -44,44 +44,67 @@ ...@@ -44,44 +44,67 @@
</div> </div>
<div class="col-md-4 form-group "> <div class="col-md-4 form-group ">
<label asp-for="username" class="col-form-label" for="username"></label> <label asp-for="username" class="col-form-label" for="username"></label>
<input asp-for="username" class="form-control" id="username"> <input asp-for="username" class="form-control" id="username" disabled>
<span asp-validation-for="username" class="text-danger"></span> <span asp-validation-for="username" class="text-danger"></span>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@if (Model.email!=null) @if (Model.email != null)
@if (Model.email.Count > 0) {
for (int i = 0; i < Model.email.Count; i++)
{ {
@foreach (var item in Model.email)
{
<div class="col-md-2 form-group"> <div class="col-md-2 form-group">
<label asp-for="@item.type" class="col-form-label" for="item.type">type</label> <label asp-for="@Model.email[i].type" class="col-form-label" for="emailType">類型</label>
<input value="@item.type" class="form-control" /> <input name="email[@i].type" value="@Model.email[i].type" class="form-control" />
<span asp-validation-for="@item.type" class="text-danger"></span> <span asp-validation-for="@Model.email[i].type" class="text-danger"></span>
</div> </div>
<div class="col-md-6 form-group"> <div class="col-md-6 form-group">
<label asp-for="@item.email" class="col-form-label" for="item.email">email</label> <label asp-for="@Model.email[i].email" class="col-form-label" for="emailAddress">電子郵件</label>
<input value="@item.email" class="form-control" /> <input name="email[@i].email" value="@Model.email[i].email" class="form-control" />
<span asp-validation-for="@item.email" class="text-danger"></span> <span asp-validation-for="@Model.email[i].email" class="text-danger"></span>
</div> </div>
}
} }
}
</div> </div>
@*<div class="row"> <!--<div class="row" id="">
<div class="col-md-4 form-group "> <div class="col-md-2 form-group">
<label asp-for="password" class="col-form-label" for=""></label> <label class="col-form-label" >新增類型</label>-->
<input asp-for="password" type="text" class="form-control" id=""> @*<input name="email[@(Model.email != null ? Model.email.Count : 0)].type" class="form-control" />*@
<span asp-validation-for="password" class="text-danger"></span> <!--<input class="form-control" />
</div>
<div class="col-md-6 form-group">
<label class="col-form-label">新增電子郵件</label>-->
@*<input name="email[@(Model.email != null ? Model.email.Count : 0)].email" class="form-control" />*@
<!--<input class="form-control"/>
</div> </div>
</div>-->
<p class="form-title card-description">修改密碼</p>
<div class="row">
</div>*@ <div class="col-md-4 form-group required">
<label asp-for="password" class="col-form-label" for="">目前密碼</label>
<input asp-for="password" type="password" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-4 form-group required">
<label asp-for="newPassword" class="col-form-label">新密碼</label>
<input asp-for="newPassword" type="password" class="form-control" id="newPWD">
</div>
</div>
<div class="row">
<div class="col-md-4 form-group required">
<label class="col-form-label">確認新密碼</label>
<input class="form-control" type="password" id="confirmPWD">
<span id="passwordMatchError" class="text-danger" style="display: none;">兩次輸入的密碼不一致</span>
</div>
</div>
...@@ -105,15 +128,24 @@ ...@@ -105,15 +128,24 @@
if (msg != '') { if (msg != '') {
showAlert(IsSuccess, msg); showAlert(IsSuccess, msg);
} }
$(".forms-sample").submit(function (event) { $(".forms-sample").submit(function (event) {
event.preventDefault(); event.preventDefault();
$('input').removeAttr('disabled'); $('input').removeAttr('disabled');
this.submit(); this.submit();
}); });
}) })
</script> </script>
......
@model backstage.Models.Users.DepartmentsResponse @model backstage.Models.Users.DepartmentsResponse
@{
bool isAdmin = User.IsInRole("Admin");
string disabledClass = isAdmin ? "" : "disabled";
}
<div class="page-header"> <div class="page-header">
<h3 class="page-title">Department List</h3> <h3 class="page-title">Department List</h3>
...@@ -7,13 +11,13 @@ ...@@ -7,13 +11,13 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-12 grid-margin stretch-card"> <div class="col-lg-12 grid-margin stretch-card">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<a type="button" class="btn btn-info float-right mb-2" asp-action="CreateDepartment">Create</a> <a type="button" class="btn btn-info float-right mb-2 @disabledClass" asp-action="CreateDepartment">Create</a>
@*列表*@ @*列表*@
<div class=""> <div class="">
...@@ -23,8 +27,8 @@ ...@@ -23,8 +27,8 @@
<th>merchant_id</th> <th>merchant_id</th>
<th>name</th> <th>name</th>
@*<th>address</th> @*<th>address</th>
<th>country_id</th> <th>country_id</th>
<th>postcode</th>*@ <th>postcode</th>*@
<th>phone</th> <th>phone</th>
@*<th>fax</th>*@ @*<th>fax</th>*@
@*<th>vatid</th>*@ @*<th>vatid</th>*@
...@@ -36,8 +40,8 @@ ...@@ -36,8 +40,8 @@
<th>user_natid_verify</th> <th>user_natid_verify</th>
<th>enabled_transaction</th>*@ <th>enabled_transaction</th>*@
@*<th>merchant_type</th> @*<th>merchant_type</th>
<th>merchant_level</th> <th>merchant_level</th>
<th>tts</th>*@ <th>tts</th>*@
</tr> </tr>
...@@ -53,21 +57,21 @@ ...@@ -53,21 +57,21 @@
<td>@i.merchant_id</td> <td>@i.merchant_id</td>
<td>@i.name</td> <td>@i.name</td>
@*<td>@i.address</td> @*<td>@i.address</td>
<td>@i.country_id</td> <td>@i.country_id</td>
<td>@i.postcode</td>*@ <td>@i.postcode</td>*@
<td>@i.phone</td> <td>@i.phone</td>
@*<td>@i.fax</td>*@ @*<td>@i.fax</td>*@
@*<td>@i.vatid</td> @*<td>@i.vatid</td>
<td>@i.enabled</td>*@ <td>@i.enabled</td>*@
<td>@i.creation_date</td> <td>@i.creation_date</td>
@*<td>@i.vatid_verify</td> @*<td>@i.vatid_verify</td>
<td>@i.deposit_book_verify</td> <td>@i.deposit_book_verify</td>
<td>@i.user_natid_verify</td> <td>@i.user_natid_verify</td>
<td>@i.enabled_transaction</td>*@ <td>@i.enabled_transaction</td>*@
@*<td>@i.merchant_type</td> @*<td>@i.merchant_type</td>
<td>@i.merchant_level</td> <td>@i.merchant_level</td>
<td>@i.tts</td>*@ <td>@i.tts</td>*@
@*<td class="text-right"> @*<td class="text-right">
<a class="btn btn-primary" asp-action="EditEventItem" asp-route-id="@i.Id"><i class="mdi mdi-grease-pencil"></i>編輯</a> <a class="btn btn-primary" asp-action="EditEventItem" asp-route-id="@i.Id"><i class="mdi mdi-grease-pencil"></i>編輯</a>
...@@ -92,7 +96,7 @@ ...@@ -92,7 +96,7 @@
@section Scripts{ @section Scripts{
<script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf"> <script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf">
var msg = '@TempData["msg"]'; var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]'; var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg); console.log(IsSuccess + msg);
......
@model backstage.Models.Users.UserResponse @model backstage.Models.Users.UserResponse
@{
bool isAdmin = User.IsInRole("admin");
string disabledClass = isAdmin ? "" : "disabled";
}
<div class="page-header"> <div class="page-header">
<h3 class="page-title">User List</h3> <h3 class="page-title">User List</h3>
<input id="msg" hidden value="@TempData["msg"]" /> <input id="msg" hidden value="@TempData["msg"]" />
...@@ -7,7 +10,7 @@ ...@@ -7,7 +10,7 @@
{ {
<input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" /> <input id="isSuccess" hidden value="@TempData["isSuccess"].ToString()" />
} }
<div id="msgDiv"></div> <div class="floating-msg" id="msgDiv"></div>
</div> </div>
<div class="row"> <div class="row">
...@@ -15,7 +18,7 @@ ...@@ -15,7 +18,7 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div id="adminStatus" style="float: left;">User count:@ViewBag.userCount / Admin count:@ViewBag.adminCount </div> <div id="adminStatus" style="float: left;">User count:@ViewBag.userCount / Admin count:@ViewBag.adminCount </div>
<a type="button" class="btn btn-info float-right mb-2" asp-action="CreateUser">Create</a> <a type="button" class="btn btn-info float-right mb-2 @disabledClass" asp-action="CreateUser">Create</a>
@*列表*@ @*列表*@
<div class=""> <div class="">
...@@ -32,11 +35,11 @@ ...@@ -32,11 +35,11 @@
<th>enabled</th> <th>enabled</th>
<th>Admin</th> <th>Admin</th>
@*<th>birthdate</th> @*<th>birthdate</th>
<th>marital_status</th> <th>marital_status</th>
<th>gender</th> <th>gender</th>
<th>education</th> <th>education</th>
<th>natid</th> <th>natid</th>
<th>lang</th>*@ <th>lang</th>*@
</tr> </tr>
...@@ -48,41 +51,41 @@ ...@@ -48,41 +51,41 @@
@foreach (var i in Model.Users) @foreach (var i in Model.Users)
{ {
<tr data-user-id="@i.uid"> <tr data-user-id="@i.uid">
<td class="userRow">@i.uid</td> <td class="userRow">@i.uid</td>
<td class="userRow">@i.name</td> <td class="userRow">@i.name</td>
@*<td>@i.name_en</td>*@ @*<td>@i.name_en</td>*@
<td class="userRow">@i.username</td> <td class="userRow">@i.username</td>
@if (i.email != null) @if (i.email != null)
@if (i.email.Count > 0) @if (i.email.Count > 0)
{ {
<td>@i.email[0].email</td> <td>@i.email[0].email</td>
} }
else else
{ {
<td></td> <td></td>
} }
@*<td>@i.locked</td>*@ @*<td>@i.locked</td>*@
<td>@i.creation_date</td> <td>@i.creation_date</td>
<td> <input type="checkbox" class="toggleButton" @(i.enabled==1 ? "checked" : "") disabled></td> <td> <input type="checkbox" data-uid="@i.uid" class="toggleButton isEnable" @(i.enabled == 1 ? "checked" : "")></td>
<td> <input type="checkbox" data-uid="@i.uid" class="toggleButton isAdmin" @(i.isAdmin ? "checked" : "")></td> <td> <input type="checkbox" data-uid="@i.uid" class="toggleButton isAdmin" @(i.isAdmin ? "checked" : "")></td>
@*@if (i.isAdmin) @*@if (i.isAdmin)
{ <td>是</td>} { <td>是</td>}
else { <td></td>}*@ else { <td></td>}*@
@*<td>@i.birthdate</td> @*<td>@i.birthdate</td>
<td>@i.marital_status</td> <td>@i.marital_status</td>
<td>@i.gender</td> <td>@i.gender</td>
<td>@i.education</td> <td>@i.education</td>
<td>@i.natid</td> <td>@i.natid</td>
<td>@i.lang</td>*@ <td>@i.lang</td>*@
@*<td class="text-right"> @*<td class="text-right">
<a class="btn btn-primary" asp-action="EditEventItem" asp-route-id="@i.Id"><i class="mdi mdi-grease-pencil"></i>編輯</a> <a class="btn btn-primary" asp-action="EditEventItem" asp-route-id="@i.Id"><i class="mdi mdi-grease-pencil"></i>編輯</a>
<button class="btn btn-inverse-danger" id="eventItem-delete-btn" data-id="@i.Id" data-name="@i.Title"><i class="mdi mdi-delete-forever"></i>刪除</button> <button class="btn btn-inverse-danger" id="eventItem-delete-btn" data-id="@i.Id" data-name="@i.Title"><i class="mdi mdi-delete-forever"></i>刪除</button>
</td>*@ </td>*@
</tr> </tr>
} }
} }
...@@ -100,12 +103,12 @@ ...@@ -100,12 +103,12 @@
@section Scripts{ @section Scripts{
<script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf"> <script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf">
var msg = '@TempData["msg"]'; var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]'; var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg); console.log(IsSuccess + msg);
if (msg != '') { if (msg != '') {
showAlert(IsSuccess, msg); showAlert(IsSuccess, msg);
} }
$('.userRow').each(function () { $('.userRow').each(function () {
var uid = $(this).find('td:first-child').text(); // 獲取行中的 UID 值 var uid = $(this).find('td:first-child').text(); // 獲取行中的 UID 值
...@@ -124,7 +127,7 @@ ...@@ -124,7 +127,7 @@
size: 'small', size: 'small',
onSwitchChange: function (event, state) { onSwitchChange: function (event, state) {
var uid = $(this).data('uid'); var uid = $(this).data('uid');
var isAdmin = $(this).is(':checked'); var isAdmin = $(this).is(':checked')?1:0;
// 使用 AJAX 發送請求,處理狀態變更事件 // 使用 AJAX 發送請求,處理狀態變更事件
$.ajax({ $.ajax({
...@@ -134,6 +137,35 @@ ...@@ -134,6 +137,35 @@
success: function (response) { success: function (response) {
// 在成功回調中處理回應 // 在成功回調中處理回應
console.log(response); console.log(response);
showAlert(response.isSuccess, response.message)
},
error: function (error) {
// 在錯誤回調中處理錯誤
console.log(error);
}
});
}
});
$('.isEnable').bootstrapSwitch({
onText: 'ON',
offText: 'OFF',
onColor: 'success',
offColor: 'danger',
size: 'small',
onSwitchChange: function (event, state) {
var uid = $(this).data('uid');
var enabled = $(this).is(':checked') ? 1 : 0;;
// 使用 AJAX 發送請求,處理狀態變更事件
$.ajax({
url: '/User/UserEnableAjax',
type: 'POST',
data: { uid: uid, enabled: enabled },
success: function (response) {
// 在成功回調中處理回應
console.log(response);
showAlert(response.isSuccess,response.message)
}, },
error: function (error) { error: function (error) {
// 在錯誤回調中處理錯誤 // 在錯誤回調中處理錯誤
......
...@@ -110,7 +110,16 @@ ...@@ -110,7 +110,16 @@
<script src="~/lib/jquery-ui/jquery-ui.min.js"></script> <script src="~/lib/jquery-ui/jquery-ui.min.js"></script>
<!--END jquery ui datepicker--> <!--END jquery ui datepicker-->
<script src="~/js/jquery.ba-dotimeout.js"></script>
<script src="~/lib/jquery.ba-dotimeout.js"></script>
</body> </body>
</html> </html>
<script>
var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg);
if (msg != '') {
showAlert(IsSuccess, msg);
}
</script>
\ No newline at end of file
...@@ -19275,12 +19275,25 @@ tbody { ...@@ -19275,12 +19275,25 @@ tbody {
} }
.floating-msg {
position: fixed;
top: 80px;
right: 20px;
z-index: 9999;
background-color: transparent;
padding: 10px;
border: 0;
}
.dashboard-card .card-title {
margin-bottom: 40px;
}
/*版本號樣式*/ .dashboard-card .card-content img {
.versionNo { max-width: 160px;
color: #f2f2f2;
font-size: 0.825rem;
padding: 20px 16px 10px 16px
} }
.dashboard-card .card-content .number {
font-size: 5rem;
color: #35A9E1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment