Commit e3d6c24e authored by Jason's avatar Jason

切換語言 還沒完成

parent a54d3bf7
......@@ -11,6 +11,9 @@ using backstage.Helpers;
using backstage.Models;
using System.Net.Http;
using System.Security.Claims;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Http;
namespace backstage.Controllers
{
......@@ -32,6 +35,15 @@ namespace backstage.Controllers
_callApi = callApi;
}
public async Task<IActionResult> token()
{
// 確認使用者是否已經登入
if (User.Identity.IsAuthenticated)
{
return Ok( User.FindFirstValue("token"));
}
return Ok();
}
......@@ -47,6 +59,21 @@ namespace backstage.Controllers
}
public IActionResult ChangeLanguage(string lang)
{
// 設置所選語言
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(lang)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
// 重新導向到先前的頁面或首頁
return LocalRedirect("~/");
}
public IActionResult Error()
{
return View();
......
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using backstage.Helpers;
using backstage.Models.Keys;
using System.Net.Http;
using System.Security.Claims;
namespace backstage.Controllers
{
[Authorize]
public class KeyController : Controller
{
private readonly IConfiguration _config;
private readonly ICallApi _callApi;
/// <summary>
/// 讀取組態用
/// </summary>
public KeyController(IConfiguration config, ICallApi callApi)
{
_config = config;
_callApi = callApi;
}
[Authorize(Policy = "AdminOnly")]
public async Task<IActionResult> ListKeys()
{
var ListKeysResponse = new ListKeysResponse();
#region key/list
var url = _config["IP"] + "/security/key/list";
var httpMethod = HttpMethod.Post;
var parameters = new Dictionary<string, string>
{
};
var apiResult = await _callApi.CallAPI(url, parameters, httpMethod);
if (apiResult.IsSuccess)
{
try
{
ListKeysResponse = JsonConvert.DeserializeObject<ListKeysResponse>(apiResult.Data.ToString());
if (ListKeysResponse.r == 0)
{
return View(ListKeysResponse.d);
}
else
{
TempData["IsSuccess"] = false;
TempData["msg"] = ListKeysResponse.m;
return View();
}
}
catch (Exception e)
{
TempData["IsSuccess"] = false;
TempData["msg"] = e.Message+e.InnerException?.Message;
return View();
}
}
TempData["IsSuccess"] = false;
TempData["msg"] = apiResult.Message;
return View();
#endregion
}
}
}
\ No newline at end of file
......@@ -56,7 +56,7 @@ namespace backstage.Controllers
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(User user, string returnUrl)
{
logger.Info("test");
if (!ModelState.IsValid)
{
return View(user);
......@@ -204,12 +204,14 @@ namespace backstage.Controllers
else
{
// API 呼叫失敗,進行相應的錯誤處理
logger.Debug(apiResult.Message);
return BadRequest(apiResult.Message);
}
}
catch (Exception ex)
{
// 處理 API 呼叫發生的例外狀況
logger.Debug(ex.Message);
return StatusCode(500, $"API 呼叫發生錯誤:{ex.Message}");
}
}
......@@ -218,7 +220,7 @@ namespace backstage.Controllers
TempData["IsSuccess"] = false;
TempData["msg"] = "發生錯誤";
logger.Debug("login error");
return View();
......@@ -771,7 +773,7 @@ namespace backstage.Controllers
}
[Authorize]
[Authorize(Policy = "AdminOnly")]
[HttpGet("/User/GetDepartment/{id}")]
public async Task<IActionResult> GetDepartment(int id)
{
......@@ -802,7 +804,7 @@ namespace backstage.Controllers
else
{
TempData["IsSuccess"] = false;
TempData["msg"] = "使用者不存在";
TempData["msg"] = apiResult.Message;
return RedirectToAction("ListUsers");
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace backstage.Models.Keys
{
public class Key
{
public int id { get; set; }
public string name { get; set; }
public string encryption { get; set; }
public DateTime lastUpdate { get; set; }
public int active { get; set; }
public string expiration { get; set; }
}
public class ListKeysResponse
{
public int r { get; set; }
public string m { get; set; }
public List<Key> d { get; set; }
public string flags { get; set; }
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
......@@ -18,7 +18,8 @@ using Microsoft.Extensions.Options;
using backstage.Helpers;
using backstage.Models;
using System.Globalization;
using Microsoft.AspNetCore.Localization;
namespace backstage
{
......@@ -47,7 +48,7 @@ namespace backstage
option.LoginPath = new PathString("/User/Login");
option.LogoutPath = new PathString("/User/Logout");
option.Cookie.Name = "backstage";
option.Cookie.SameSite = SameSiteMode.None;
option.Cookie.SameSite = SameSiteMode.Strict;
option.Events = new CookieAuthenticationEvents
{
OnRedirectToAccessDenied = context =>
......@@ -87,7 +88,15 @@ namespace backstage
});
services.AddScoped<ICallApi, CallApi>();
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(
options =>
{
var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("zh") };
options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
}
......@@ -137,7 +146,9 @@ namespace backstage
app.UseAuthorization(); // 將 app.UseAuthorization() 放在 app.UseRouting() 之後
//�ҥ� cookie ��h�\��
app.UseCookiePolicy();
app.UseRequestLocalization(app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
......
......@@ -169,6 +169,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\Controllers\" />
<Folder Include="wwwroot\lib\fonts\bootstrap\" />
</ItemGroup>
......
@model List<backstage.Models.Keys.Key>
@{
ViewData["Title"] = "Keys列表管理";
}
@{
bool isAdmin = User.IsInRole("Admin");
string disabledClass = isAdmin ? "" : "disabled";
}
@section header{
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
}
<div class="page-header">
<h3 class="page-title">Keys列表管理</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-lg-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-12">
<ul class="breadcrumb breadcrumb_memberGo">
@*<li class="breadcrumb-item active"><a asp-action="List" asp-route-merchantId="@ViewBag.Merchant_id">資料代碼保險庫</a></li>
<li class="breadcrumb-item active"><a asp-action="ListFields" asp-route-merchant_id="@ViewBag.Merchant_id" asp-route-vault_id="@ViewBag.vault_id">欄位資料</a></li>*@
<li class="breadcrumb-item active">API金鑰管理 - 專案管理</li>
</ul>
</div>
</div>
<div class="table-responsive">
<!--交易紀錄列表 table-->
<table class="table table-striped table-hover" id="memberGoTbl_newProjec">
<thead>
<tr>
<th colspan="7">專案列表</th>
</tr>
</thead>
<tbody>
<tr>
<th style=" border-left: solid 0.1px #d9d9d9;">專案ID</th>
<th>專案名稱</th>
<th>建立日期</th>
<th>狀態</th>
<th>修改</th>
<th style=" border-right: solid 0.1px #d9d9d9;">刪除</th>
</tr>
@if (Model!=null)
@if (Model.Count > 0)
{
foreach (var k in Model)
{
<tr>
<td>@k.id</td>
<td><a asp-action="" title="進入App管理">@k.name</a></td>
<td>@k.lastUpdate</td>
<td>@(k.active==1?"使用中":"停用")</td>
<td>
<a data-toggle="modal" data-target="#editProject" title="修改">
<i class="fa-solid fa-pen-to-square"></i>
</a>
</td>
<td>
<a data-toggle="modal" data-target="#deleteProject" title="刪除">
<i class="fa-solid fa-trash-can"></i>
</a>
</td>
</tr>
}
}
</tbody>
</table>
<!--End of APIKey管理 table-->
</div>
</div>
</div>
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myModalLabel">選擇使用者</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<select id="selectUser" class="form-control" asp-items="ViewBag.users">
<!-- 其他用户选项 -->
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="confirmBtn" data-dismiss="modal">確認</button>
</div>
</div>
</div>
</div>
@section Scripts{
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script nonce="KUY8VewuvyUYVEIvEFue4vwyiuf">
$('document').ready(function () {
var msg = '@TempData["msg"]';
var IsSuccess = '@TempData["IsSuccess"]';
console.log(IsSuccess + msg);
if (msg != '') {
showAlert(IsSuccess, msg);
}
$(".custom-tooltip").tooltip({
items: "[data-tooltip]",
content: function () {
return $(this).attr("data-tooltip");
},
tooltipClass: "custom-tooltip-width"
});
$("#confirmBtn").on("click", function () {
// 確認按鈕被點擊時的處理程式碼
// 在這裡呼叫您的 API
var merchant_id = parseInt('@ViewBag.Merchant_id');
var vault_id = parseInt('@ViewBag.vault_id');
var field_id = parseInt('@ViewBag.field_id');
var selectedUser = parseInt($("#selectUser").val()); // 替換為您實際使用的選取元素的 ID
$.ajax({
url: "/TokenVault/Addusers",
method: "POST",
contentType: "application/json",
data: JSON.stringify({ Merchant_id: merchant_id, vault_id: vault_id, field_id: field_id, user_id: selectedUser}),
success: function (response) {
// API 呼叫成功的處理程式碼
},
error: function (xhr, status, error) {
// API 呼叫失敗的處理程式碼
}
});
});
})
</script>
}
\ No newline at end of file
......@@ -78,12 +78,13 @@
<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>更改密碼
</a>
@*<a class="dropdown-item" asp-controller="User" asp-action="Register">
<i class="mdi mdi-account-plus mr-2"></i>註冊管理員
</a>*@
@*<a class="dropdown-item" asp-controller="UserManage" asp-action="GetUserManage">
<i class="mdi mdi-account-details mr-2"></i>帳號管理
</a>*@
<a class="dropdown-item" asp-controller="User" asp-action="Register">
<i class="mdi mdi-account-plus mr-2"></i>Setting備份
</a>
<a class="dropdown-item" asp-controller="" asp-action="">
<i class="mdi mdi-account-details mr-2"></i>Data備份
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" asp-controller="User" asp-action="Logout">
<i class="mdi mdi-logout mr-2 text-danger"></i>登出
......@@ -139,7 +140,7 @@
<i class="mdi mdi-earth"></i>
</a>
<div class="dropdown-menu dropdown-menu-right navbar-dropdown preview-list" aria-labelledby="languageDropdown">
<a class="dropdown-item preview-item">
<a class="dropdown-item preview-item" href="/Home/ChangeLanguage?lang=en">>
<div class="preview-thumbnail">
<div class="preview-icon languageIcon">
<img src="/images/icon-lan-en-80.jpg">
......@@ -150,13 +151,13 @@
</div>
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item preview-item">
<a class="dropdown-item preview-item" href="/Home/ChangeLanguage?lang=zh">>
<div class="preview-thumbnail">
<div class="preview-icon languageIcon">
<img src="/images/icon-lan-cn-80.jpg">
</div>
</div>
<div class="preview-item-content d-flex align-items-start flex-column justify-content-center">
<div class="preview-item-content d-flex align-items-start flex-column justify-content-center">
<h6 class="preview-subject font-weight-normal mb-1">中文</h6>
</div>
</a>
......@@ -216,7 +217,7 @@
</a>
<div class="collapse" id="FinancialRecordExpenses">
<ul class="nav flex-column sub-menu">
<li class="nav-item"> <a class="nav-link" asp-controller="" asp-action="">Key列表</a></li>
<li class="nav-item"> <a class="nav-link" asp-controller="Key" asp-action="ListKeys">Key列表</a></li>
@*<li class="nav-item"> <a class="nav-link" asp-controller="FinancialRecordExpenses" asp-action="List">支出紀錄管理</a></li>*@
</ul>
</div>
......
......@@ -60,7 +60,7 @@
</table>
<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-solid @disabledClass" data-toggle="modal" data-target="#new-field-mask"><img src="~/images/memberGo/add.png">新增遮罩</button>
<button id="NewMaskBtn" 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 class="table-responsive">
......@@ -135,7 +135,7 @@
<!--
<button type="button" class="close" data-dismiss="modal">&times;</button>
-->
<h3 class="modal-title">
<h3 class="modal-title" >
新增遮罩
</h3>
......@@ -295,8 +295,18 @@
}
//新增mask
$("#createMaskBtn").click(function (event) {
$("#NewMaskBtn").click(function (event) {
console.log('NewMaskBtn')
$('#new-field-mask .modal-title').text('新增遮罩');
$('#new-field-mask input:not([name="mask_id"], [name="merchant_id"], [name="field_id"], [name="vault_id"])').val('');
})
//送出新mask
$("#createMaskBtn").click(function (event) {
$.ajax({
url: '/TokenVault/CreateMask',
type: 'POST',
......
......@@ -9,6 +9,7 @@
},
"AllowedHosts": "*",
"IP": "http://118.163.142.162:8082",
//"IP": "http://192.168.1.172:8082",
"key": "backstage2019-0149849165168"
}
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