committed by
GitHub
99 changed files with 41991 additions and 157 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web |
|||
{ |
|||
[DependsOn(typeof(Volo.Abp.Account.Web.AbpAccountWebModule))] |
|||
public class AbpAccountWebModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<AssemblyName>LINGYUN.Abp.Account.Web</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Account.Web</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
<RootNamespace>LINGYUN.Abp.Account.Web</RootNamespace> |
|||
<IsPackable>true</IsPackable> |
|||
<OutputType>Library</OutputType> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Pages\**\*.js" /> |
|||
<EmbeddedResource Include="Pages\**\*.css" /> |
|||
<Content Remove="Pages\**\*.js" /> |
|||
<Content Remove="Pages\**\*.css" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Account.Web" Version="3.2.0" /> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.6" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Folder Include="Pages\Account\" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,4 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:63675", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"LINGYUN.Abp.Account.Web": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "http://localhost:5000", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
# LINGYUN.Abp.Account.Web |
|||
|
|||
重写用户账户相关页面 |
|||
|
|||
## 配置使用 |
|||
|
|||
|
|||
```csharp |
|||
[DependsOn(typeof(LINGYUN.Abp.Account.Web.AbpAccountWebModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
// other |
|||
} |
|||
``` |
|||
@ -0,0 +1,71 @@ |
|||
/* 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. */ |
|||
|
|||
a.navbar-brand { |
|||
white-space: normal; |
|||
text-align: center; |
|||
word-break: break-all; |
|||
} |
|||
|
|||
/* Provide sufficient contrast against white background */ |
|||
a { |
|||
color: #0366d6; |
|||
} |
|||
|
|||
.btn-primary { |
|||
color: #fff; |
|||
background-color: #1b6ec2; |
|||
border-color: #1861ac; |
|||
} |
|||
|
|||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link { |
|||
color: #fff; |
|||
background-color: #1b6ec2; |
|||
border-color: #1861ac; |
|||
} |
|||
|
|||
/* Sticky footer styles |
|||
-------------------------------------------------- */ |
|||
html { |
|||
font-size: 14px; |
|||
} |
|||
@media (min-width: 768px) { |
|||
html { |
|||
font-size: 16px; |
|||
} |
|||
} |
|||
|
|||
.border-top { |
|||
border-top: 1px solid #e5e5e5; |
|||
} |
|||
.border-bottom { |
|||
border-bottom: 1px solid #e5e5e5; |
|||
} |
|||
|
|||
.box-shadow { |
|||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); |
|||
} |
|||
|
|||
button.accept-policy { |
|||
font-size: 1rem; |
|||
line-height: inherit; |
|||
} |
|||
|
|||
/* Sticky footer styles |
|||
-------------------------------------------------- */ |
|||
html { |
|||
position: relative; |
|||
min-height: 100%; |
|||
} |
|||
|
|||
body { |
|||
/* Margin bottom by footer height */ |
|||
margin-bottom: 60px; |
|||
} |
|||
.footer { |
|||
position: absolute; |
|||
bottom: 0; |
|||
width: 100%; |
|||
white-space: nowrap; |
|||
line-height: 60px; /* Vertically center the text there */ |
|||
} |
|||
|
After Width: | Height: | Size: 31 KiB |
@ -0,0 +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.
|
|||
@ -0,0 +1,22 @@ |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2011-2018 Twitter, Inc. |
|||
Copyright (c) 2011-2018 The Bootstrap Authors |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,331 @@ |
|||
/*! |
|||
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) |
|||
* Copyright 2011-2019 The Bootstrap Authors |
|||
* Copyright 2011-2019 Twitter, Inc. |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) |
|||
*/ |
|||
*, |
|||
*::before, |
|||
*::after { |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
html { |
|||
font-family: sans-serif; |
|||
line-height: 1.15; |
|||
-webkit-text-size-adjust: 100%; |
|||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); |
|||
} |
|||
|
|||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { |
|||
display: block; |
|||
} |
|||
|
|||
body { |
|||
margin: 0; |
|||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; |
|||
font-size: 1rem; |
|||
font-weight: 400; |
|||
line-height: 1.5; |
|||
color: #212529; |
|||
text-align: left; |
|||
background-color: #fff; |
|||
} |
|||
|
|||
[tabindex="-1"]:focus { |
|||
outline: 0 !important; |
|||
} |
|||
|
|||
hr { |
|||
box-sizing: content-box; |
|||
height: 0; |
|||
overflow: visible; |
|||
} |
|||
|
|||
h1, h2, h3, h4, h5, h6 { |
|||
margin-top: 0; |
|||
margin-bottom: 0.5rem; |
|||
} |
|||
|
|||
p { |
|||
margin-top: 0; |
|||
margin-bottom: 1rem; |
|||
} |
|||
|
|||
abbr[title], |
|||
abbr[data-original-title] { |
|||
text-decoration: underline; |
|||
-webkit-text-decoration: underline dotted; |
|||
text-decoration: underline dotted; |
|||
cursor: help; |
|||
border-bottom: 0; |
|||
-webkit-text-decoration-skip-ink: none; |
|||
text-decoration-skip-ink: none; |
|||
} |
|||
|
|||
address { |
|||
margin-bottom: 1rem; |
|||
font-style: normal; |
|||
line-height: inherit; |
|||
} |
|||
|
|||
ol, |
|||
ul, |
|||
dl { |
|||
margin-top: 0; |
|||
margin-bottom: 1rem; |
|||
} |
|||
|
|||
ol ol, |
|||
ul ul, |
|||
ol ul, |
|||
ul ol { |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
dt { |
|||
font-weight: 700; |
|||
} |
|||
|
|||
dd { |
|||
margin-bottom: .5rem; |
|||
margin-left: 0; |
|||
} |
|||
|
|||
blockquote { |
|||
margin: 0 0 1rem; |
|||
} |
|||
|
|||
b, |
|||
strong { |
|||
font-weight: bolder; |
|||
} |
|||
|
|||
small { |
|||
font-size: 80%; |
|||
} |
|||
|
|||
sub, |
|||
sup { |
|||
position: relative; |
|||
font-size: 75%; |
|||
line-height: 0; |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
sub { |
|||
bottom: -.25em; |
|||
} |
|||
|
|||
sup { |
|||
top: -.5em; |
|||
} |
|||
|
|||
a { |
|||
color: #007bff; |
|||
text-decoration: none; |
|||
background-color: transparent; |
|||
} |
|||
|
|||
a:hover { |
|||
color: #0056b3; |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
a:not([href]):not([tabindex]) { |
|||
color: inherit; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { |
|||
color: inherit; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
a:not([href]):not([tabindex]):focus { |
|||
outline: 0; |
|||
} |
|||
|
|||
pre, |
|||
code, |
|||
kbd, |
|||
samp { |
|||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; |
|||
font-size: 1em; |
|||
} |
|||
|
|||
pre { |
|||
margin-top: 0; |
|||
margin-bottom: 1rem; |
|||
overflow: auto; |
|||
} |
|||
|
|||
figure { |
|||
margin: 0 0 1rem; |
|||
} |
|||
|
|||
img { |
|||
vertical-align: middle; |
|||
border-style: none; |
|||
} |
|||
|
|||
svg { |
|||
overflow: hidden; |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
table { |
|||
border-collapse: collapse; |
|||
} |
|||
|
|||
caption { |
|||
padding-top: 0.75rem; |
|||
padding-bottom: 0.75rem; |
|||
color: #6c757d; |
|||
text-align: left; |
|||
caption-side: bottom; |
|||
} |
|||
|
|||
th { |
|||
text-align: inherit; |
|||
} |
|||
|
|||
label { |
|||
display: inline-block; |
|||
margin-bottom: 0.5rem; |
|||
} |
|||
|
|||
button { |
|||
border-radius: 0; |
|||
} |
|||
|
|||
button:focus { |
|||
outline: 1px dotted; |
|||
outline: 5px auto -webkit-focus-ring-color; |
|||
} |
|||
|
|||
input, |
|||
button, |
|||
select, |
|||
optgroup, |
|||
textarea { |
|||
margin: 0; |
|||
font-family: inherit; |
|||
font-size: inherit; |
|||
line-height: inherit; |
|||
} |
|||
|
|||
button, |
|||
input { |
|||
overflow: visible; |
|||
} |
|||
|
|||
button, |
|||
select { |
|||
text-transform: none; |
|||
} |
|||
|
|||
select { |
|||
word-wrap: normal; |
|||
} |
|||
|
|||
button, |
|||
[type="button"], |
|||
[type="reset"], |
|||
[type="submit"] { |
|||
-webkit-appearance: button; |
|||
} |
|||
|
|||
button:not(:disabled), |
|||
[type="button"]:not(:disabled), |
|||
[type="reset"]:not(:disabled), |
|||
[type="submit"]:not(:disabled) { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
button::-moz-focus-inner, |
|||
[type="button"]::-moz-focus-inner, |
|||
[type="reset"]::-moz-focus-inner, |
|||
[type="submit"]::-moz-focus-inner { |
|||
padding: 0; |
|||
border-style: none; |
|||
} |
|||
|
|||
input[type="radio"], |
|||
input[type="checkbox"] { |
|||
box-sizing: border-box; |
|||
padding: 0; |
|||
} |
|||
|
|||
input[type="date"], |
|||
input[type="time"], |
|||
input[type="datetime-local"], |
|||
input[type="month"] { |
|||
-webkit-appearance: listbox; |
|||
} |
|||
|
|||
textarea { |
|||
overflow: auto; |
|||
resize: vertical; |
|||
} |
|||
|
|||
fieldset { |
|||
min-width: 0; |
|||
padding: 0; |
|||
margin: 0; |
|||
border: 0; |
|||
} |
|||
|
|||
legend { |
|||
display: block; |
|||
width: 100%; |
|||
max-width: 100%; |
|||
padding: 0; |
|||
margin-bottom: .5rem; |
|||
font-size: 1.5rem; |
|||
line-height: inherit; |
|||
color: inherit; |
|||
white-space: normal; |
|||
} |
|||
|
|||
progress { |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
[type="number"]::-webkit-inner-spin-button, |
|||
[type="number"]::-webkit-outer-spin-button { |
|||
height: auto; |
|||
} |
|||
|
|||
[type="search"] { |
|||
outline-offset: -2px; |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
[type="search"]::-webkit-search-decoration { |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
::-webkit-file-upload-button { |
|||
font: inherit; |
|||
-webkit-appearance: button; |
|||
} |
|||
|
|||
output { |
|||
display: inline-block; |
|||
} |
|||
|
|||
summary { |
|||
display: list-item; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
template { |
|||
display: none; |
|||
} |
|||
|
|||
[hidden] { |
|||
display: none !important; |
|||
} |
|||
/*# sourceMappingURL=bootstrap-reboot.css.map */ |
|||
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@ |
|||
/*! |
|||
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) |
|||
* Copyright 2011-2019 The Bootstrap Authors |
|||
* Copyright 2011-2019 Twitter, Inc. |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) |
|||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} |
|||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */ |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@ |
|||
Copyright (c) .NET Foundation. All rights reserved. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use |
|||
these files except in compliance with the License. You may obtain a copy of the |
|||
License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software distributed |
|||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
|||
CONDITIONS OF ANY KIND, either express or implied. See the License for the |
|||
specific language governing permissions and limitations under the License. |
|||
@ -0,0 +1,432 @@ |
|||
// Unobtrusive validation support library for jQuery and jQuery Validate
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|||
// @version v3.2.11
|
|||
|
|||
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ |
|||
/*global document: false, jQuery: false */ |
|||
|
|||
(function (factory) { |
|||
if (typeof define === 'function' && define.amd) { |
|||
// AMD. Register as an anonymous module.
|
|||
define("jquery.validate.unobtrusive", ['jquery-validation'], factory); |
|||
} else if (typeof module === 'object' && module.exports) { |
|||
// CommonJS-like environments that support module.exports
|
|||
module.exports = factory(require('jquery-validation')); |
|||
} else { |
|||
// Browser global
|
|||
jQuery.validator.unobtrusive = factory(jQuery); |
|||
} |
|||
}(function ($) { |
|||
var $jQval = $.validator, |
|||
adapters, |
|||
data_validation = "unobtrusiveValidation"; |
|||
|
|||
function setValidationValues(options, ruleName, value) { |
|||
options.rules[ruleName] = value; |
|||
if (options.message) { |
|||
options.messages[ruleName] = options.message; |
|||
} |
|||
} |
|||
|
|||
function splitAndTrim(value) { |
|||
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); |
|||
} |
|||
|
|||
function escapeAttributeValue(value) { |
|||
// As mentioned on http://api.jquery.com/category/selectors/
|
|||
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); |
|||
} |
|||
|
|||
function getModelPrefix(fieldName) { |
|||
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); |
|||
} |
|||
|
|||
function appendModelPrefix(value, prefix) { |
|||
if (value.indexOf("*.") === 0) { |
|||
value = value.replace("*.", prefix); |
|||
} |
|||
return value; |
|||
} |
|||
|
|||
function onError(error, inputElement) { // 'this' is the form element
|
|||
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), |
|||
replaceAttrValue = container.attr("data-valmsg-replace"), |
|||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; |
|||
|
|||
container.removeClass("field-validation-valid").addClass("field-validation-error"); |
|||
error.data("unobtrusiveContainer", container); |
|||
|
|||
if (replace) { |
|||
container.empty(); |
|||
error.removeClass("input-validation-error").appendTo(container); |
|||
} |
|||
else { |
|||
error.hide(); |
|||
} |
|||
} |
|||
|
|||
function onErrors(event, validator) { // 'this' is the form element
|
|||
var container = $(this).find("[data-valmsg-summary=true]"), |
|||
list = container.find("ul"); |
|||
|
|||
if (list && list.length && validator.errorList.length) { |
|||
list.empty(); |
|||
container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); |
|||
|
|||
$.each(validator.errorList, function () { |
|||
$("<li />").html(this.message).appendTo(list); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function onSuccess(error) { // 'this' is the form element
|
|||
var container = error.data("unobtrusiveContainer"); |
|||
|
|||
if (container) { |
|||
var replaceAttrValue = container.attr("data-valmsg-replace"), |
|||
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; |
|||
|
|||
container.addClass("field-validation-valid").removeClass("field-validation-error"); |
|||
error.removeData("unobtrusiveContainer"); |
|||
|
|||
if (replace) { |
|||
container.empty(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function onReset(event) { // 'this' is the form element
|
|||
var $form = $(this), |
|||
key = '__jquery_unobtrusive_validation_form_reset'; |
|||
if ($form.data(key)) { |
|||
return; |
|||
} |
|||
// Set a flag that indicates we're currently resetting the form.
|
|||
$form.data(key, true); |
|||
try { |
|||
$form.data("validator").resetForm(); |
|||
} finally { |
|||
$form.removeData(key); |
|||
} |
|||
|
|||
$form.find(".validation-summary-errors") |
|||
.addClass("validation-summary-valid") |
|||
.removeClass("validation-summary-errors"); |
|||
$form.find(".field-validation-error") |
|||
.addClass("field-validation-valid") |
|||
.removeClass("field-validation-error") |
|||
.removeData("unobtrusiveContainer") |
|||
.find(">*") // If we were using valmsg-replace, get the underlying error
|
|||
.removeData("unobtrusiveContainer"); |
|||
} |
|||
|
|||
function validationInfo(form) { |
|||
var $form = $(form), |
|||
result = $form.data(data_validation), |
|||
onResetProxy = $.proxy(onReset, form), |
|||
defaultOptions = $jQval.unobtrusive.options || {}, |
|||
execInContext = function (name, args) { |
|||
var func = defaultOptions[name]; |
|||
func && $.isFunction(func) && func.apply(form, args); |
|||
}; |
|||
|
|||
if (!result) { |
|||
result = { |
|||
options: { // options structure passed to jQuery Validate's validate() method
|
|||
errorClass: defaultOptions.errorClass || "input-validation-error", |
|||
errorElement: defaultOptions.errorElement || "span", |
|||
errorPlacement: function () { |
|||
onError.apply(form, arguments); |
|||
execInContext("errorPlacement", arguments); |
|||
}, |
|||
invalidHandler: function () { |
|||
onErrors.apply(form, arguments); |
|||
execInContext("invalidHandler", arguments); |
|||
}, |
|||
messages: {}, |
|||
rules: {}, |
|||
success: function () { |
|||
onSuccess.apply(form, arguments); |
|||
execInContext("success", arguments); |
|||
} |
|||
}, |
|||
attachValidation: function () { |
|||
$form |
|||
.off("reset." + data_validation, onResetProxy) |
|||
.on("reset." + data_validation, onResetProxy) |
|||
.validate(this.options); |
|||
}, |
|||
validate: function () { // a validation function that is called by unobtrusive Ajax
|
|||
$form.validate(); |
|||
return $form.valid(); |
|||
} |
|||
}; |
|||
$form.data(data_validation, result); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
$jQval.unobtrusive = { |
|||
adapters: [], |
|||
|
|||
parseElement: function (element, skipAttach) { |
|||
/// <summary>
|
|||
/// Parses a single HTML element for unobtrusive validation attributes.
|
|||
/// </summary>
|
|||
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
|
|||
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
|
|||
/// validation to the form. If parsing just this single element, you should specify true.
|
|||
/// If parsing several elements, you should specify false, and manually attach the validation
|
|||
/// to the form when you are finished. The default is false.</param>
|
|||
var $element = $(element), |
|||
form = $element.parents("form")[0], |
|||
valInfo, rules, messages; |
|||
|
|||
if (!form) { // Cannot do client-side validation without a form
|
|||
return; |
|||
} |
|||
|
|||
valInfo = validationInfo(form); |
|||
valInfo.options.rules[element.name] = rules = {}; |
|||
valInfo.options.messages[element.name] = messages = {}; |
|||
|
|||
$.each(this.adapters, function () { |
|||
var prefix = "data-val-" + this.name, |
|||
message = $element.attr(prefix), |
|||
paramValues = {}; |
|||
|
|||
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
|
|||
prefix += "-"; |
|||
|
|||
$.each(this.params, function () { |
|||
paramValues[this] = $element.attr(prefix + this); |
|||
}); |
|||
|
|||
this.adapt({ |
|||
element: element, |
|||
form: form, |
|||
message: message, |
|||
params: paramValues, |
|||
rules: rules, |
|||
messages: messages |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
$.extend(rules, { "__dummy__": true }); |
|||
|
|||
if (!skipAttach) { |
|||
valInfo.attachValidation(); |
|||
} |
|||
}, |
|||
|
|||
parse: function (selector) { |
|||
/// <summary>
|
|||
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
|
|||
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
|
|||
/// attribute values.
|
|||
/// </summary>
|
|||
/// <param name="selector" type="String">Any valid jQuery selector.</param>
|
|||
|
|||
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
|
|||
// element with data-val=true
|
|||
var $selector = $(selector), |
|||
$forms = $selector.parents() |
|||
.addBack() |
|||
.filter("form") |
|||
.add($selector.find("form")) |
|||
.has("[data-val=true]"); |
|||
|
|||
$selector.find("[data-val=true]").each(function () { |
|||
$jQval.unobtrusive.parseElement(this, true); |
|||
}); |
|||
|
|||
$forms.each(function () { |
|||
var info = validationInfo(this); |
|||
if (info) { |
|||
info.attachValidation(); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
adapters = $jQval.unobtrusive.adapters; |
|||
|
|||
adapters.add = function (adapterName, params, fn) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
|
|||
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
|
|||
/// mmmm is the parameter name).</param>
|
|||
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
|
|||
/// attributes into jQuery Validate rules and/or messages.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
if (!fn) { // Called with no params, just a function
|
|||
fn = params; |
|||
params = []; |
|||
} |
|||
this.push({ name: adapterName, params: params, adapt: fn }); |
|||
return this; |
|||
}; |
|||
|
|||
adapters.addBool = function (adapterName, ruleName) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation rule has no parameter values.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
|||
/// of adapterName will be used instead.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, function (options) { |
|||
setValidationValues(options, ruleName || adapterName, true); |
|||
}); |
|||
}; |
|||
|
|||
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
|
|||
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
|
|||
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
|||
/// have a minimum value.</param>
|
|||
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
|
|||
/// have a maximum value.</param>
|
|||
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
|
|||
/// have both a minimum and maximum value.</param>
|
|||
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
|||
/// contains the minimum value. The default is "min".</param>
|
|||
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
|
|||
/// contains the maximum value. The default is "max".</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { |
|||
var min = options.params.min, |
|||
max = options.params.max; |
|||
|
|||
if (min && max) { |
|||
setValidationValues(options, minMaxRuleName, [min, max]); |
|||
} |
|||
else if (min) { |
|||
setValidationValues(options, minRuleName, min); |
|||
} |
|||
else if (max) { |
|||
setValidationValues(options, maxRuleName, max); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
adapters.addSingleVal = function (adapterName, attribute, ruleName) { |
|||
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
|
|||
/// the jQuery Validate validation rule has a single value.</summary>
|
|||
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
|
|||
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
|
|||
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
|
|||
/// The default is "val".</param>
|
|||
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
|
|||
/// of adapterName will be used instead.</param>
|
|||
/// <returns type="jQuery.validator.unobtrusive.adapters" />
|
|||
return this.add(adapterName, [attribute || "val"], function (options) { |
|||
setValidationValues(options, ruleName || adapterName, options.params[attribute]); |
|||
}); |
|||
}; |
|||
|
|||
$jQval.addMethod("__dummy__", function (value, element, params) { |
|||
return true; |
|||
}); |
|||
|
|||
$jQval.addMethod("regex", function (value, element, params) { |
|||
var match; |
|||
if (this.optional(element)) { |
|||
return true; |
|||
} |
|||
|
|||
match = new RegExp(params).exec(value); |
|||
return (match && (match.index === 0) && (match[0].length === value.length)); |
|||
}); |
|||
|
|||
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { |
|||
var match; |
|||
if (nonalphamin) { |
|||
match = value.match(/\W/g); |
|||
match = match && match.length >= nonalphamin; |
|||
} |
|||
return match; |
|||
}); |
|||
|
|||
if ($jQval.methods.extension) { |
|||
adapters.addSingleVal("accept", "mimtype"); |
|||
adapters.addSingleVal("extension", "extension"); |
|||
} else { |
|||
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
|
|||
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
|
|||
// validating the extension, and ignore mime-type validations as they are not supported.
|
|||
adapters.addSingleVal("extension", "extension", "accept"); |
|||
} |
|||
|
|||
adapters.addSingleVal("regex", "pattern"); |
|||
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); |
|||
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); |
|||
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); |
|||
adapters.add("equalto", ["other"], function (options) { |
|||
var prefix = getModelPrefix(options.element.name), |
|||
other = options.params.other, |
|||
fullOtherName = appendModelPrefix(other, prefix), |
|||
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; |
|||
|
|||
setValidationValues(options, "equalTo", element); |
|||
}); |
|||
adapters.add("required", function (options) { |
|||
// jQuery Validate equates "required" with "mandatory" for checkbox elements
|
|||
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { |
|||
setValidationValues(options, "required", true); |
|||
} |
|||
}); |
|||
adapters.add("remote", ["url", "type", "additionalfields"], function (options) { |
|||
var value = { |
|||
url: options.params.url, |
|||
type: options.params.type || "GET", |
|||
data: {} |
|||
}, |
|||
prefix = getModelPrefix(options.element.name); |
|||
|
|||
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { |
|||
var paramName = appendModelPrefix(fieldName, prefix); |
|||
value.data[paramName] = function () { |
|||
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); |
|||
// For checkboxes and radio buttons, only pick up values from checked fields.
|
|||
if (field.is(":checkbox")) { |
|||
return field.filter(":checked").val() || field.filter(":hidden").val() || ''; |
|||
} |
|||
else if (field.is(":radio")) { |
|||
return field.filter(":checked").val() || ''; |
|||
} |
|||
return field.val(); |
|||
}; |
|||
}); |
|||
|
|||
setValidationValues(options, "remote", value); |
|||
}); |
|||
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { |
|||
if (options.params.min) { |
|||
setValidationValues(options, "minlength", options.params.min); |
|||
} |
|||
if (options.params.nonalphamin) { |
|||
setValidationValues(options, "nonalphamin", options.params.nonalphamin); |
|||
} |
|||
if (options.params.regex) { |
|||
setValidationValues(options, "regex", options.params.regex); |
|||
} |
|||
}); |
|||
adapters.add("fileextensions", ["extensions"], function (options) { |
|||
setValidationValues(options, "extension", options.params.extensions); |
|||
}); |
|||
|
|||
$(function () { |
|||
$jQval.unobtrusive.parse(document); |
|||
}); |
|||
|
|||
return $jQval.unobtrusive; |
|||
})); |
|||
File diff suppressed because one or more lines are too long
@ -0,0 +1,22 @@ |
|||
The MIT License (MIT) |
|||
===================== |
|||
|
|||
Copyright Jörn Zaefferer |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
THE SOFTWARE. |
|||
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -0,0 +1,36 @@ |
|||
Copyright JS Foundation and other contributors, https://js.foundation/ |
|||
|
|||
This software consists of voluntary contributions made by many |
|||
individuals. For exact contribution history, see the revision history |
|||
available at https://github.com/jquery/jquery |
|||
|
|||
The following license applies to all parts of this software except as |
|||
documented below: |
|||
|
|||
==== |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining |
|||
a copy of this software and associated documentation files (the |
|||
"Software"), to deal in the Software without restriction, including |
|||
without limitation the rights to use, copy, modify, merge, publish, |
|||
distribute, sublicense, and/or sell copies of the Software, and to |
|||
permit persons to whom the Software is furnished to do so, subject to |
|||
the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be |
|||
included in all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
|
|||
==== |
|||
|
|||
All files located in the node_modules and external directories are |
|||
externally maintained libraries used by this software which have their |
|||
own licenses; we recommend you read them, as their terms may differ from |
|||
the terms above. |
|||
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimDto : EntityDto<Guid> |
|||
{ |
|||
public string ClaimType { get; set; } |
|||
|
|||
public string ClaimValue { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimTypeCreateDto : IdentityClaimTypeCreateOrUpdateBaseDto |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(IdentityClaimTypeConsts), nameof(IdentityClaimTypeConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
public bool IsStatic { get; set; } |
|||
|
|||
public IdentityClaimValueType ValueType { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimTypeCreateOrUpdateBaseDto : ExtensibleObject |
|||
{ |
|||
public bool Required { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(IdentityClaimTypeConsts), nameof(IdentityClaimTypeConsts.MaxRegexLength))] |
|||
public string Regex { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(IdentityClaimTypeConsts), nameof(IdentityClaimTypeConsts.MaxRegexDescriptionLength))] |
|||
public string RegexDescription { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(IdentityClaimTypeConsts), nameof(IdentityClaimTypeConsts.MaxDescriptionLength))] |
|||
public string Description { get; set; } |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimTypeDto : ExtensibleEntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public bool Required { get; set; } |
|||
|
|||
public bool IsStatic { get; set; } |
|||
|
|||
public string Regex { get; set; } |
|||
|
|||
public string RegexDescription { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public IdentityClaimValueType ValueType { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimTypeGetByPagedDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityClaimTypeUpdateDto : IdentityClaimTypeCreateOrUpdateBaseDto |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityRoleClaimCreateDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityRoleClaimConsts), nameof(IdentityRoleClaimConsts.MaxClaimTypeLength))] |
|||
public string ClaimType { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityRoleClaimConsts), nameof(IdentityRoleClaimConsts.MaxClaimValueLength))] |
|||
public string ClaimValue { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityRoleClaimDeleteDto : IdentityRoleClaimCreateDto |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityRoleClaimUpdateDto : IdentityRoleClaimCreateDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityRoleClaimConsts), nameof(IdentityRoleClaimConsts.MaxClaimValueLength))] |
|||
public string NewClaimValue { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityUserClaimCreateDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityUserClaimConsts), nameof(IdentityUserClaimConsts.MaxClaimTypeLength))] |
|||
public string ClaimType { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityUserClaimConsts), nameof(IdentityUserClaimConsts.MaxClaimValueLength))] |
|||
public string ClaimValue { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityUserClaimDeleteDto : IdentityUserClaimCreateDto |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityUserClaimUpdateDto : IdentityUserClaimCreateDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(IdentityUserClaimConsts), nameof(IdentityUserClaimConsts.MaxClaimValueLength))] |
|||
public string NewClaimValue { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public interface IIdentityClaimTypeAppService : |
|||
ICrudAppService< |
|||
IdentityClaimTypeDto, |
|||
Guid, |
|||
IdentityClaimTypeGetByPagedDto, |
|||
IdentityClaimTypeCreateDto, |
|||
IdentityClaimTypeUpdateDto> |
|||
{ |
|||
Task<ListResultDto<IdentityClaimTypeDto>> GetAllListAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
public class IdentityErrorCodes |
|||
{ |
|||
public const string StaticClaimTypeChange = "Volo.Abp.Identity:020005"; |
|||
public const string StaticClaimTypeDeletion = "Volo.Abp.Identity:020006"; |
|||
} |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[Authorize(IdentityPermissions.IdentityClaimType.Default)] |
|||
public class IdentityClaimTypeAppService : IdentityAppServiceBase, IIdentityClaimTypeAppService |
|||
{ |
|||
protected IdenityClaimTypeManager IdenityClaimTypeManager { get; } |
|||
|
|||
protected IIdentityClaimTypeRepository IdentityClaimTypeRepository { get; } |
|||
|
|||
public IdentityClaimTypeAppService( |
|||
IdenityClaimTypeManager idenityClaimTypeManager, |
|||
IIdentityClaimTypeRepository identityClaimTypeRepository) |
|||
{ |
|||
IdenityClaimTypeManager = idenityClaimTypeManager; |
|||
IdentityClaimTypeRepository = identityClaimTypeRepository; |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.IdentityClaimType.Create)] |
|||
public virtual async Task<IdentityClaimTypeDto> CreateAsync(IdentityClaimTypeCreateDto input) |
|||
{ |
|||
if (await IdentityClaimTypeRepository.AnyAsync(input.Name)) |
|||
{ |
|||
throw new UserFriendlyException(L["IdentityClaimTypeAlreadyExists", input.Name]); |
|||
} |
|||
var identityClaimType = new IdentityClaimType( |
|||
GuidGenerator.Create(), |
|||
input.Name, |
|||
input.Required, |
|||
input.IsStatic, |
|||
input.Regex, |
|||
input.RegexDescription, |
|||
input.Description, |
|||
input.ValueType |
|||
); |
|||
identityClaimType = await IdenityClaimTypeManager.CreateAsync(identityClaimType); |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityClaimType, IdentityClaimTypeDto>(identityClaimType); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.IdentityClaimType.Delete)] |
|||
public virtual async Task DeleteAsync(Guid id) |
|||
{ |
|||
var identityClaimType = await IdentityClaimTypeRepository.FindAsync(id); |
|||
if (identityClaimType == null) |
|||
{ |
|||
return; |
|||
} |
|||
CheckDeletionClaimType(identityClaimType); |
|||
await IdentityClaimTypeRepository.DeleteAsync(identityClaimType); |
|||
} |
|||
|
|||
public virtual async Task<IdentityClaimTypeDto> GetAsync(Guid id) |
|||
{ |
|||
var identityClaimType = await IdentityClaimTypeRepository.FindAsync(id); |
|||
|
|||
return ObjectMapper.Map<IdentityClaimType, IdentityClaimTypeDto>(identityClaimType); |
|||
} |
|||
|
|||
public virtual async Task<ListResultDto<IdentityClaimTypeDto>> GetAllListAsync() |
|||
{ |
|||
var identityClaimTypes = await IdentityClaimTypeRepository |
|||
.GetListAsync(); |
|||
|
|||
return new ListResultDto<IdentityClaimTypeDto>( |
|||
ObjectMapper.Map<List<IdentityClaimType>, List<IdentityClaimTypeDto>>(identityClaimTypes)); |
|||
} |
|||
|
|||
public virtual async Task<PagedResultDto<IdentityClaimTypeDto>> GetListAsync(IdentityClaimTypeGetByPagedDto input) |
|||
{ |
|||
var identityClaimTypeCount = await IdentityClaimTypeRepository.GetCountAsync(input.Filter); |
|||
|
|||
var identityClaimTypes = await IdentityClaimTypeRepository |
|||
.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter); |
|||
|
|||
return new PagedResultDto<IdentityClaimTypeDto>(identityClaimTypeCount, |
|||
ObjectMapper.Map<List<IdentityClaimType>, List<IdentityClaimTypeDto>>(identityClaimTypes)); |
|||
} |
|||
|
|||
[Authorize(IdentityPermissions.IdentityClaimType.Update)] |
|||
public virtual async Task<IdentityClaimTypeDto> UpdateAsync(Guid id, IdentityClaimTypeUpdateDto input) |
|||
{ |
|||
var identityClaimType = await IdentityClaimTypeRepository.GetAsync(id); |
|||
CheckChangingClaimType(identityClaimType); |
|||
identityClaimType.Required = input.Required; |
|||
if (!string.Equals(identityClaimType.Regex, input.Regex, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
identityClaimType.Regex = input.Regex; |
|||
} |
|||
if (!string.Equals(identityClaimType.RegexDescription, input.RegexDescription, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
identityClaimType.RegexDescription = input.RegexDescription; |
|||
} |
|||
if (!string.Equals(identityClaimType.Description, input.Description, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
identityClaimType.Description = input.Description; |
|||
} |
|||
|
|||
identityClaimType = await IdenityClaimTypeManager.UpdateAsync(identityClaimType); |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<IdentityClaimType, IdentityClaimTypeDto>(identityClaimType); |
|||
} |
|||
|
|||
protected virtual void CheckChangingClaimType(IdentityClaimType claimType) |
|||
{ |
|||
if (claimType.IsStatic) |
|||
{ |
|||
throw new BusinessException(IdentityErrorCodes.StaticClaimTypeChange); |
|||
} |
|||
} |
|||
|
|||
protected virtual void CheckDeletionClaimType(IdentityClaimType claimType) |
|||
{ |
|||
if (claimType.IsStatic) |
|||
{ |
|||
throw new BusinessException(IdentityErrorCodes.StaticClaimTypeDeletion); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[RemoteService(true, Name = IdentityRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("identity")] |
|||
[ControllerName("Role")] |
|||
[Route("api/identity/roles")] |
|||
public class IIdentityRoleController : AbpController, IIdentityRoleAppService |
|||
{ |
|||
protected IIdentityRoleAppService RoleAppService { get; } |
|||
public IIdentityRoleController( |
|||
IIdentityRoleAppService roleAppService) |
|||
{ |
|||
RoleAppService = roleAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task<ListResultDto<OrganizationUnitDto>> GetOrganizationUnitsAsync(Guid id) |
|||
{ |
|||
return await RoleAppService.GetOrganizationUnitsAsync(id); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task SetOrganizationUnitsAsync(Guid id, IdentityRoleAddOrRemoveOrganizationUnitDto input) |
|||
{ |
|||
await RoleAppService.SetOrganizationUnitsAsync(id, input); |
|||
} |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[RemoteService(true, Name = IdentityRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("identity")] |
|||
[ControllerName("User")] |
|||
[Route("api/identity/users")] |
|||
public class IIdentityUserController : AbpController, IIdentityUserAppService |
|||
{ |
|||
protected IIdentityUserAppService UserAppService { get; } |
|||
public IIdentityUserController( |
|||
IIdentityUserAppService userAppService) |
|||
{ |
|||
UserAppService = userAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task<ListResultDto<OrganizationUnitDto>> GetOrganizationUnitsAsync(Guid id) |
|||
{ |
|||
return await UserAppService.GetOrganizationUnitsAsync(id); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task UpdateOrganizationUnitsAsync(Guid id, IdentityUserOrganizationUnitUpdateDto input) |
|||
{ |
|||
await UserAppService.UpdateOrganizationUnitsAsync(id, input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[RemoteService(true, Name = IdentityRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("identity")] |
|||
[ControllerName("ClaimType")] |
|||
[Route("api/identity/claim-types")] |
|||
public class IdentityClaimTypeController : AbpController, IIdentityClaimTypeAppService |
|||
{ |
|||
protected IIdentityClaimTypeAppService IdentityClaimTypeAppService { get; } |
|||
public IdentityClaimTypeController(IIdentityClaimTypeAppService identityClaimTypeAppService) |
|||
{ |
|||
IdentityClaimTypeAppService = identityClaimTypeAppService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
public virtual async Task<IdentityClaimTypeDto> CreateAsync(IdentityClaimTypeCreateDto input) |
|||
{ |
|||
return await IdentityClaimTypeAppService.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
public virtual async Task DeleteAsync(Guid id) |
|||
{ |
|||
await IdentityClaimTypeAppService.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("actived-list")] |
|||
public virtual async Task<ListResultDto<IdentityClaimTypeDto>> GetAllListAsync() |
|||
{ |
|||
return await IdentityClaimTypeAppService.GetAllListAsync(); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual async Task<IdentityClaimTypeDto> GetAsync(Guid id) |
|||
{ |
|||
return await IdentityClaimTypeAppService.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual async Task<PagedResultDto<IdentityClaimTypeDto>> GetListAsync(IdentityClaimTypeGetByPagedDto input) |
|||
{ |
|||
return await IdentityClaimTypeAppService.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
public virtual async Task<IdentityClaimTypeDto> UpdateAsync(Guid id, IdentityClaimTypeUpdateDto input) |
|||
{ |
|||
return await IdentityClaimTypeAppService.UpdateAsync(id, input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[RemoteService(true, Name = IdentityRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("identity")] |
|||
[ControllerName("Role")] |
|||
[Route("api/identity/roles")] |
|||
public class IdentityRoleController : AbpController, IIdentityRoleAppService |
|||
{ |
|||
protected IIdentityRoleAppService RoleAppService { get; } |
|||
public IdentityRoleController( |
|||
IIdentityRoleAppService roleAppService) |
|||
{ |
|||
RoleAppService = roleAppService; |
|||
} |
|||
|
|||
#region OrganizationUnit
|
|||
|
|||
[HttpGet] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task<ListResultDto<OrganizationUnitDto>> GetOrganizationUnitsAsync(Guid id) |
|||
{ |
|||
return await RoleAppService.GetOrganizationUnitsAsync(id); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task SetOrganizationUnitsAsync(Guid id, IdentityRoleAddOrRemoveOrganizationUnitDto input) |
|||
{ |
|||
await RoleAppService.SetOrganizationUnitsAsync(id, input); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Claim
|
|||
|
|||
[HttpGet] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task<ListResultDto<IdentityClaimDto>> GetClaimsAsync(Guid id) |
|||
{ |
|||
return await RoleAppService.GetClaimsAsync(id); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task AddClaimAsync(Guid id, IdentityRoleClaimCreateDto input) |
|||
{ |
|||
await RoleAppService.AddClaimAsync(id, input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task UpdateClaimAsync(Guid id, IdentityRoleClaimUpdateDto input) |
|||
{ |
|||
await RoleAppService.UpdateClaimAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task DeleteClaimAsync(Guid id, IdentityRoleClaimDeleteDto input) |
|||
{ |
|||
await RoleAppService.DeleteClaimAsync(id, input); |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Identity; |
|||
|
|||
namespace LINGYUN.Abp.Identity |
|||
{ |
|||
[RemoteService(true, Name = IdentityRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("identity")] |
|||
[ControllerName("User")] |
|||
[Route("api/identity/users")] |
|||
public class IdentityUserController : AbpController, IIdentityUserAppService |
|||
{ |
|||
protected IIdentityUserAppService UserAppService { get; } |
|||
public IdentityUserController( |
|||
IIdentityUserAppService userAppService) |
|||
{ |
|||
UserAppService = userAppService; |
|||
} |
|||
|
|||
#region OrganizationUnit
|
|||
|
|||
[HttpGet] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task<ListResultDto<OrganizationUnitDto>> GetOrganizationUnitsAsync(Guid id) |
|||
{ |
|||
return await UserAppService.GetOrganizationUnitsAsync(id); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("organization-units/{id}")] |
|||
public virtual async Task UpdateOrganizationUnitsAsync(Guid id, IdentityUserOrganizationUnitUpdateDto input) |
|||
{ |
|||
await UserAppService.UpdateOrganizationUnitsAsync(id, input); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Claim
|
|||
|
|||
[HttpGet] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task<ListResultDto<IdentityClaimDto>> GetClaimsAsync(Guid id) |
|||
{ |
|||
return await UserAppService.GetClaimsAsync(id); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task AddClaimAsync(Guid id, IdentityUserClaimCreateDto input) |
|||
{ |
|||
await UserAppService.AddClaimAsync(id, input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task UpdateClaimAsync(Guid id, IdentityUserClaimUpdateDto input) |
|||
{ |
|||
await UserAppService.UpdateClaimAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("claims/{id}")] |
|||
public virtual async Task DeleteClaimAsync(Guid id, IdentityUserClaimDeleteDto input) |
|||
{ |
|||
await UserAppService.DeleteClaimAsync(id, input); |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -1,8 +1,8 @@ |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app-identityserver", |
|||
"name": "auth-identityserver", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.basic": "^3.1.2" |
|||
"@abp/aspnetcore.mvc.ui.theme.basic": "^3.2.0" |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
var abp = abp || {}; |
|||
(function () { |
|||
|
|||
if (!luxon) { |
|||
throw "abp/luxon library requires the luxon library included to the page!"; |
|||
} |
|||
|
|||
/* TIMING *************************************************/ |
|||
|
|||
abp.timing = abp.timing || {}; |
|||
|
|||
var setObjectValue = function (obj, property, value) { |
|||
if (typeof property === "string") { |
|||
property = property.split('.'); |
|||
} |
|||
|
|||
if (property.length > 1) { |
|||
var p = property.shift(); |
|||
setObjectValue(obj[p], property, value); |
|||
} else { |
|||
obj[property[0]] = value; |
|||
} |
|||
} |
|||
|
|||
var getObjectValue = function (obj, property) { |
|||
return property.split('.').reduce((a, v) => a[v], obj) |
|||
} |
|||
|
|||
abp.timing.convertFieldsToIsoDate = function (form, fields) { |
|||
for (var field of fields) { |
|||
var dateTime = luxon.DateTime |
|||
.fromFormat( |
|||
getObjectValue(form, field), |
|||
abp.localization.currentCulture.dateTimeFormat.shortDatePattern, |
|||
{locale: abp.localization.currentCulture.cultureName} |
|||
); |
|||
|
|||
if (!dateTime.invalid) { |
|||
setObjectValue(form, field, dateTime.toFormat("yyyy-MM-dd HH:mm:ss")) |
|||
} |
|||
} |
|||
|
|||
return form; |
|||
} |
|||
|
|||
})(jQuery); |
|||
Binary file not shown.
@ -0,0 +1,93 @@ |
|||
import ApiService from './serviceBase' |
|||
import { ExtensibleEntity, ExtensibleObject, ListResultDto, PagedAndSortedResultRequestDto, PagedResultDto } from './types' |
|||
|
|||
const IdentityServiceUrl = process.env.VUE_APP_BASE_API |
|||
|
|||
export default class ClaimTypeApiService { |
|||
public static createClaimType(payload: IdentityClaimTypeCreate) { |
|||
const _url = '/api/identity/claim-types' |
|||
return ApiService.Post<IdentityClaimType>(_url, payload, IdentityServiceUrl) |
|||
} |
|||
|
|||
public static getActivedClaimTypes() { |
|||
const _url = '/api/identity/claim-types/actived-list' |
|||
return ApiService.Get<ListResultDto<IdentityClaimType>>(_url, IdentityServiceUrl) |
|||
} |
|||
|
|||
public static getClaimTypes(payload: IdentityClaimTypeGetByPaged) { |
|||
let _url = '/api/identity/claim-types?' |
|||
_url += 'filter=' + payload.filter |
|||
_url += '&sorting=' + payload.sorting |
|||
_url += '&skipCount=' + payload.skipCount |
|||
_url += '&maxResultCount=' + payload.maxResultCount |
|||
return ApiService.Get<PagedResultDto<IdentityClaimType>>(_url, IdentityServiceUrl) |
|||
} |
|||
|
|||
public static getClaimType(id: string) { |
|||
const _url = '/api/identity/claim-types/' + id |
|||
return ApiService.Get<IdentityClaimType>(_url, IdentityServiceUrl) |
|||
} |
|||
|
|||
public static updateClaimType(id: string, payload: IdentityClaimTypeUpdate) { |
|||
const _url = '/api/identity/claim-types/' + id |
|||
return ApiService.Put<IdentityClaimType>(_url, payload, IdentityServiceUrl) |
|||
} |
|||
|
|||
public static deleteClaimType(id: string) { |
|||
const _url = '/api/identity/claim-types/' + id |
|||
return ApiService.Delete(_url, IdentityServiceUrl) |
|||
} |
|||
} |
|||
|
|||
export enum IdentityClaimValueType { |
|||
String = 0, |
|||
Int = 1, |
|||
Boolean = 2, |
|||
DateTime = 3 |
|||
} |
|||
|
|||
export class IdentityClaimType extends ExtensibleEntity<string> { |
|||
name!: string |
|||
required!: boolean |
|||
isStatic!: boolean |
|||
regex?: string |
|||
regexDescription?: string |
|||
description?: string |
|||
valueType!: IdentityClaimValueType |
|||
} |
|||
|
|||
export class IdentityClaimTypeCreateOrUpdateBase extends ExtensibleObject { |
|||
required = false |
|||
regex?: string = '' |
|||
regexDescription?: string = '' |
|||
description?: string = '' |
|||
} |
|||
|
|||
export class IdentityClaimTypeCreate extends IdentityClaimTypeCreateOrUpdateBase { |
|||
name!: string |
|||
isStatic!: boolean |
|||
valueType!: IdentityClaimValueType |
|||
|
|||
constructor( |
|||
name: string, |
|||
isStatic = false, |
|||
valueType = IdentityClaimValueType.String |
|||
) { |
|||
super() |
|||
this.name = name |
|||
this.isStatic = isStatic |
|||
this.valueType = valueType |
|||
} |
|||
} |
|||
|
|||
export class IdentityClaimTypeUpdate extends IdentityClaimTypeCreateOrUpdateBase { |
|||
} |
|||
|
|||
export class IdentityClaimTypeGetByPaged extends PagedAndSortedResultRequestDto { |
|||
filter = '' |
|||
|
|||
constructor() { |
|||
super() |
|||
this.sorting = 'name' |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
/* eslint-disable */ |
|||
/* tslint:disable */ |
|||
// @ts-ignore
|
|||
import icon from 'vue-svgicon' |
|||
icon.register({ |
|||
'claim-type': { |
|||
width: 128, |
|||
height: 128, |
|||
viewBox: '0 0 1024 1024', |
|||
data: '<path pid="0" _fill="#333" d="M384 268.8c0-17.067 0-25.6 4.267-29.867 4.266-8.533 8.533-12.8 17.066-17.066 8.534-8.534 12.8-8.534 34.134-8.534 17.066-25.6 42.666-42.666 72.533-42.666s59.733 17.066 72.533 42.666c17.067 0 25.6 0 34.134 4.267 8.533 4.267 12.8 8.533 17.066 17.067C640 243.2 640 247.467 640 268.8l-8.533-12.8h51.2C729.6 256 768 294.4 768 341.333v256c0 12.8-8.533 21.334-21.333 21.334s-21.334-8.534-21.334-21.334v-256c0-25.6-17.066-42.666-42.666-42.666h-59.734l17.067-12.8c0 17.066 0 25.6-4.267 29.866-4.266 8.534-8.533 12.8-17.066 17.067-8.534 8.533-12.8 8.533-34.134 8.533H435.2c-17.067 0-21.333 0-29.867-4.266-8.533-4.267-12.8-8.534-17.066-17.067C384 311.467 384 307.2 384 285.867l17.067 12.8h-59.734c-25.6 0-42.666 17.066-42.666 42.666V768c0 25.6 17.066 42.667 42.666 42.667h341.334c25.6 0 42.666-17.067 42.666-42.667v-42.667c0-12.8 8.534-21.333 21.334-21.333S768 712.533 768 725.333V768c0 46.933-38.4 85.333-85.333 85.333H341.333C294.4 853.333 256 814.933 256 768V341.333C256 294.4 294.4 256 341.333 256h51.2L384 268.8zm42.667 0v8.533c0 12.8 8.533 21.334 21.333 21.334h128c12.8 0 21.333-8.534 21.333-21.334V256H588.8c-17.067 0-29.867-8.533-38.4-21.333-8.533-12.8-21.333-21.334-38.4-21.334s-29.867 8.534-38.4 21.334c-4.267 12.8-21.333 21.333-34.133 21.333h-12.8v12.8zm192 200.533H405.333C392.533 469.333 384 460.8 384 448s8.533-21.333 21.333-21.333h213.334c12.8 0 21.333 8.533 21.333 21.333s-8.533 21.333-21.333 21.333zm0 128H405.333C392.533 597.333 384 588.8 384 576s8.533-21.333 21.333-21.333h213.334c12.8 0 21.333 8.533 21.333 21.333s-8.533 21.333-21.333 21.333zm0 128H405.333C392.533 725.333 384 716.8 384 704s8.533-21.333 21.333-21.333h213.334c12.8 0 21.333 8.533 21.333 21.333s-8.533 21.333-21.333 21.333z"/>' |
|||
} |
|||
}) |
|||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,230 @@ |
|||
<template> |
|||
<el-dialog |
|||
v-el-draggable-dialog |
|||
width="800px" |
|||
:visible="showDialog" |
|||
:title="title" |
|||
custom-class="modal-form" |
|||
:show-close="false" |
|||
:close-on-click-modal="false" |
|||
:close-on-press-escape="false" |
|||
@close="onFormClosed(false)" |
|||
> |
|||
<el-form |
|||
ref="claimTypeForm" |
|||
:model="claimType" |
|||
label-width="120px" |
|||
:rules="claimTypeRules" |
|||
> |
|||
<el-form-item |
|||
prop="name" |
|||
:label="$t('AbpIdentity.IdentityClaim:Name')" |
|||
> |
|||
<el-input |
|||
v-model="claimType.name" |
|||
:disabled="isEditClaimType" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="description" |
|||
:label="$t('AbpIdentity.IdentityClaim:Description')" |
|||
> |
|||
<el-input |
|||
v-model="claimType.description" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="regex" |
|||
:label="$t('AbpIdentity.IdentityClaim:Regex')" |
|||
> |
|||
<el-input |
|||
v-model="claimType.regex" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="regexDescription" |
|||
:label="$t('AbpIdentity.IdentityClaim:RegexDescription')" |
|||
> |
|||
<el-input |
|||
v-model="claimType.regexDescription" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="valueType" |
|||
:label="$t('AbpIdentity.IdentityClaim:ValueType')" |
|||
> |
|||
<el-select |
|||
v-model="claimType.valueType" |
|||
style="width: 100%" |
|||
:disabled="isEditClaimType" |
|||
> |
|||
<el-option |
|||
v-for="valueType in claimValueTypes" |
|||
:key="valueType.name" |
|||
:label="valueType.name" |
|||
:value="valueType.value" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="required" |
|||
:label="$t('AbpIdentity.IdentityClaim:Required')" |
|||
> |
|||
<el-switch |
|||
v-model="claimType.required" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="isStatic" |
|||
:label="$t('AbpIdentity.IdentityClaim:IsStatic')" |
|||
> |
|||
<el-switch |
|||
v-model="claimType.isStatic" |
|||
:disabled="isEditClaimType" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button |
|||
class="cancel" |
|||
style="width:100px" |
|||
@click="onFormClosed(false)" |
|||
> |
|||
{{ $t('global.cancel') }} |
|||
</el-button> |
|||
<el-button |
|||
class="confirm" |
|||
type="primary" |
|||
style="width:100px" |
|||
@click="onSave" |
|||
> |
|||
{{ $t('global.confirm') }} |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Form } from 'element-ui' |
|||
import ClaimTypeApiService, { |
|||
IdentityClaimType, |
|||
IdentityClaimValueType, |
|||
IdentityClaimTypeCreate, |
|||
IdentityClaimTypeUpdate, |
|||
IdentityClaimTypeCreateOrUpdateBase |
|||
} from '@/api/cliam-type' |
|||
import { Component, Vue, Prop, Watch } from 'vue-property-decorator' |
|||
|
|||
@Component({ |
|||
name: 'CreateOrUpdateCliamTypeForm' |
|||
}) |
|||
export default class CreateOrUpdateCliamTypeForm extends Vue { |
|||
@Prop({ default: '' }) |
|||
private claimTypeId!: string |
|||
|
|||
@Prop({ default: '' }) |
|||
private title!: string |
|||
|
|||
@Prop({ default: false }) |
|||
private showDialog!: boolean |
|||
|
|||
private hasChanged = false |
|||
private claimType = new IdentityClaimType() |
|||
private claimValueTypes = [ |
|||
{ name: 'Boolean', value: IdentityClaimValueType.Boolean }, |
|||
{ name: 'DateTime', value: IdentityClaimValueType.DateTime }, |
|||
{ name: 'Int', value: IdentityClaimValueType.Int }, |
|||
{ name: 'String', value: IdentityClaimValueType.String } |
|||
] |
|||
|
|||
private claimTypeRules = { |
|||
name: [ |
|||
{ required: true, message: this.l('pleaseInputBy', { key: this.l('AbpIdentity.IdentityClaim:Name') }), trigger: 'blur' } |
|||
], |
|||
valueType: [ |
|||
{ required: true, message: this.l('pleaseSelectBy', { key: this.l('AbpIdentity.IdentityClaim:ValueType') }), trigger: 'blur' } |
|||
] |
|||
} |
|||
|
|||
get isEditClaimType() { |
|||
if (this.claimTypeId) { |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
|
|||
@Watch('claimTypeId') |
|||
private onClaimTypeIdChanged() { |
|||
this.handleGetClaimType() |
|||
} |
|||
|
|||
@Watch('showDialog', { immediate: true }) |
|||
private onShowDialogChanged() { |
|||
this.handleGetClaimType() |
|||
} |
|||
|
|||
private handleGetClaimType() { |
|||
this.hasChanged = false |
|||
if (this.showDialog && this.claimTypeId) { |
|||
ClaimTypeApiService.getClaimType(this.claimTypeId).then(res => { |
|||
this.claimType = res |
|||
}) |
|||
} |
|||
} |
|||
|
|||
private onSave() { |
|||
const claimTypeForm = this.$refs.claimTypeForm as Form |
|||
claimTypeForm.validate(valid => { |
|||
if (valid) { |
|||
if (this.isEditClaimType) { |
|||
const updatePayload = new IdentityClaimTypeUpdate() |
|||
this.updateClaimTypeByInput(updatePayload) |
|||
ClaimTypeApiService.updateClaimType(this.claimTypeId, updatePayload).then(res => { |
|||
this.claimType = res |
|||
this.hasChanged = true |
|||
this.$message.success(this.l('global.successful')) |
|||
}) |
|||
} else { |
|||
const createPayload = new IdentityClaimTypeCreate(this.claimType.name, this.claimType.isStatic, this.claimType.valueType) |
|||
this.updateClaimTypeByInput(createPayload) |
|||
ClaimTypeApiService.createClaimType(createPayload).then(() => { |
|||
claimTypeForm.resetFields() |
|||
this.hasChanged = true |
|||
this.$message.success(this.l('global.successful')) |
|||
this.onFormClosed(true) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onFormClosed(changed: boolean) { |
|||
const claimTypeForm = this.$refs.claimTypeForm as Form |
|||
claimTypeForm.resetFields() |
|||
this.hasChanged = this.hasChanged ? this.hasChanged : changed |
|||
this.$emit('closed', this.hasChanged) |
|||
} |
|||
|
|||
private updateClaimTypeByInput(claimType: IdentityClaimTypeCreateOrUpdateBase) { |
|||
claimType.regex = this.claimType.regex |
|||
claimType.regexDescription = this.claimType.regexDescription |
|||
claimType.required = this.claimType.required |
|||
claimType.description = this.claimType.description |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.confirm { |
|||
position: absolute; |
|||
right: 10px; |
|||
} |
|||
.cancel { |
|||
position: absolute; |
|||
right: 120px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,252 @@ |
|||
<template> |
|||
<div class="app-container"> |
|||
<div class="filter-container"> |
|||
<label |
|||
class="radio-label" |
|||
style="padding-left:0;" |
|||
>{{ $t('global.queryFilter') }}</label> |
|||
<el-input |
|||
v-model="dataFilter.filter" |
|||
:placeholder="$t('global.filterString')" |
|||
style="width: 250px;margin-left: 10px;" |
|||
class="filter-item" |
|||
/> |
|||
<el-button |
|||
class="filter-item" |
|||
style="margin-left: 10px; text-alignt" |
|||
type="primary" |
|||
@click="refreshPagedData" |
|||
> |
|||
{{ $t('global.searchList') }} |
|||
</el-button> |
|||
<el-button |
|||
class="filter-item" |
|||
type="primary" |
|||
:disabled="!checkPermission(['AbpIdentity.IdentityClaimTypes.Create'])" |
|||
@click="handleCreateClaimType" |
|||
> |
|||
{{ $t('AbpIdentity.AddClaim') }} |
|||
</el-button> |
|||
</div> |
|||
|
|||
<el-table |
|||
v-loading="dataLoading" |
|||
row-key="id" |
|||
:data="dataList" |
|||
stripe |
|||
border |
|||
fit |
|||
highlight-current-row |
|||
@sort-change="handleSortChange" |
|||
> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:Name')" |
|||
prop="name" |
|||
sortable |
|||
width="300px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.name }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:ValueType')" |
|||
prop="valueType" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.valueType | claimValueTypeFilter }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:Description')" |
|||
prop="description" |
|||
sortable |
|||
min-width="100%" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.description }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:Regex')" |
|||
prop="regex" |
|||
sortable |
|||
width="200px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.regex }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:Required')" |
|||
prop="required" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-switch |
|||
v-model="row.required" |
|||
disabled |
|||
/> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.IdentityClaim:IsStatic')" |
|||
prop="isStatic" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-switch |
|||
v-model="row.isStatic" |
|||
disabled |
|||
/> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('operaActions')" |
|||
align="center" |
|||
width="260px" |
|||
fixed="right" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-button |
|||
:disabled="!allowedEditClaim(row)" |
|||
size="mini" |
|||
type="primary" |
|||
@click="handleUpdateClaimType(row)" |
|||
> |
|||
{{ $t('AbpIdentity.UpdateClaim') }} |
|||
</el-button> |
|||
<el-button |
|||
:disabled="!allowedDeleteClaim(row)" |
|||
size="mini" |
|||
type="danger" |
|||
@click="handleDeleteClaimType(row)" |
|||
> |
|||
{{ $t('AbpIdentity.DeleteClaim') }} |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<pagination |
|||
v-show="dataTotal>0" |
|||
:total="dataTotal" |
|||
:page.sync="currentPage" |
|||
:limit.sync="pageSize" |
|||
@pagination="refreshPagedData" |
|||
/> |
|||
|
|||
<create-or-update-cliam-type-form |
|||
:title="editClaimTypeTitle" |
|||
:claim-type-id="editClaimTypeId" |
|||
:show-dialog="showClaimTypeDialog" |
|||
@closed="onClaimTypeDialogClosed" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { checkPermission } from '@/utils/permission' |
|||
import { abpPagerFormat } from '@/utils' |
|||
import Pagination from '@/components/Pagination/index.vue' |
|||
import DataListMiXin from '@/mixins/DataListMiXin' |
|||
import Component, { mixins } from 'vue-class-component' |
|||
import CreateOrUpdateCliamTypeForm from './components/CreateOrUpdateCliamTypeForm.vue' |
|||
import ClaimTypeApiService, { IdentityClaimType, IdentityClaimTypeGetByPaged, IdentityClaimValueType } from '@/api/cliam-type' |
|||
|
|||
const valueTypeMap: { [key: number]: string } = { |
|||
[IdentityClaimValueType.String]: 'String', |
|||
[IdentityClaimValueType.Boolean]: 'Boolean', |
|||
[IdentityClaimValueType.DateTime]: 'DateTime', |
|||
[IdentityClaimValueType.Int]: 'Int' |
|||
} |
|||
|
|||
@Component({ |
|||
name: 'ClaimType', |
|||
components: { |
|||
Pagination, |
|||
CreateOrUpdateCliamTypeForm |
|||
}, |
|||
filters: { |
|||
claimValueTypeFilter(valueType: IdentityClaimValueType) { |
|||
return valueTypeMap[valueType] |
|||
} |
|||
}, |
|||
methods: { |
|||
checkPermission |
|||
} |
|||
}) |
|||
export default class ClaimType extends mixins(DataListMiXin) { |
|||
private editClaimTypeId = '' |
|||
private editClaimTypeTitle = '' |
|||
private showClaimTypeDialog = false |
|||
public dataFilter = new IdentityClaimTypeGetByPaged() |
|||
|
|||
mounted() { |
|||
this.refreshPagedData() |
|||
} |
|||
|
|||
get allowedEditClaim() { |
|||
return (claimType: IdentityClaimType) => { |
|||
return !claimType.isStatic && checkPermission(['AbpIdentity.IdentityClaimTypes.Update']) |
|||
} |
|||
} |
|||
|
|||
get allowedDeleteClaim() { |
|||
return (claimType: IdentityClaimType) => { |
|||
return !claimType.isStatic && checkPermission(['AbpIdentity.IdentityClaimTypes.Delete']) |
|||
} |
|||
} |
|||
|
|||
protected processDataFilter() { |
|||
this.dataFilter.skipCount = abpPagerFormat(this.currentPage, this.pageSize) |
|||
} |
|||
|
|||
protected getPagedList() { |
|||
return ClaimTypeApiService.getClaimTypes(this.dataFilter) |
|||
} |
|||
|
|||
private handleCreateClaimType() { |
|||
this.editClaimTypeId = '' |
|||
this.editClaimTypeTitle = this.l('AbpIdentity.IdentityClaim:New') |
|||
this.showClaimTypeDialog = true |
|||
} |
|||
|
|||
private handleUpdateClaimType(claimType: IdentityClaimType) { |
|||
this.editClaimTypeId = claimType.id |
|||
this.editClaimTypeTitle = this.l('AbpIdentity.ClaimSubject', { 0: claimType.name }) |
|||
this.showClaimTypeDialog = true |
|||
} |
|||
|
|||
private handleDeleteClaimType(claimType: IdentityClaimType) { |
|||
this.$confirm(this.l('AbpIdentity.WillDeleteClaim', { 0: claimType.name }), |
|||
this.l('AbpUi.AreYouSure'), { |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
ClaimTypeApiService.deleteClaimType(claimType.id).then(() => { |
|||
this.$message.success(this.l('global.successful')) |
|||
this.refreshPagedData() |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onClaimTypeDialogClosed(changed: boolean) { |
|||
this.showClaimTypeDialog = false |
|||
if (changed) { |
|||
this.refreshPagedData() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -0,0 +1,297 @@ |
|||
<template> |
|||
<el-dialog |
|||
v-el-draggable-dialog |
|||
width="800px" |
|||
:visible="showDialog" |
|||
:title="title" |
|||
custom-class="modal-form" |
|||
:show-close="false" |
|||
:close-on-click-modal="true" |
|||
:close-on-press-escape="true" |
|||
@close="onFormClosed(false)" |
|||
> |
|||
<el-form |
|||
ref="userClaimForm" |
|||
:model="editUserClaim" |
|||
label-width="120px" |
|||
:rules="userClaimRules" |
|||
> |
|||
<el-form-item |
|||
prop="claimType" |
|||
:label="$t('AbpIdentity.DisplayName:ClaimType')" |
|||
> |
|||
<el-select |
|||
v-model="editUserClaim.claimType" |
|||
style="width: 100%" |
|||
@change="onClaimTypeChanged" |
|||
> |
|||
<el-option |
|||
v-for="claim in claimTypes" |
|||
:key="claim.id" |
|||
:label="claim.name" |
|||
:value="claim.name" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
prop="claimValue" |
|||
:label="$t('AbpIdentity.DisplayName:ClaimValue')" |
|||
> |
|||
<el-input |
|||
v-if="hasStringValueType(editUserClaim.claimType)" |
|||
v-model="editUserClaim.claimValue" |
|||
type="text" |
|||
/> |
|||
<el-input |
|||
v-else-if="hasIntegerValueType(editUserClaim.claimType)" |
|||
v-model="editUserClaim.claimValue" |
|||
type="number" |
|||
/> |
|||
<el-switch |
|||
v-else-if="hasBooleanValueType(editUserClaim.claimType)" |
|||
v-model="editUserClaim.claimValue" |
|||
/> |
|||
<el-date-picker |
|||
v-else-if="hasDateTimeValueType(editUserClaim.claimType)" |
|||
v-model="editUserClaim.claimValue" |
|||
type="datetime" |
|||
style="width: 100%" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
style="text-align: center;" |
|||
label-width="0px" |
|||
> |
|||
<el-button |
|||
type="primary" |
|||
style="width:180px" |
|||
@click="onSave" |
|||
> |
|||
{{ $t('AbpIdentity.AddClaim') }} |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-table |
|||
row-key="id" |
|||
:data="userClaims" |
|||
border |
|||
fit |
|||
highlight-current-row |
|||
style="width: 100%;" |
|||
> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.DisplayName:ClaimType')" |
|||
prop="claimType" |
|||
sortable |
|||
width="150px" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ row.claimType }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('AbpIdentity.DisplayName:ClaimValue')" |
|||
prop="claimValue" |
|||
sortable |
|||
min-width="100%" |
|||
align="center" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<span>{{ claimValue(row.claimType, row.claimValue) }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column |
|||
:label="$t('operaActions')" |
|||
align="center" |
|||
width="150px" |
|||
> |
|||
<template slot-scope="{row}"> |
|||
<el-button |
|||
:disabled="!checkPermission(['AbpIdentity.Users.ManageClaims'])" |
|||
size="mini" |
|||
type="danger" |
|||
@click="handleDeleteUserClaim(row)" |
|||
> |
|||
{{ $t('AbpIdentity.DeleteClaim') }} |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { dateFormat } from '@/utils/index' |
|||
import { checkPermission } from '@/utils/permission' |
|||
import { Component, Vue, Prop, Watch } from 'vue-property-decorator' |
|||
import UserService, { UserClaim, UserClaimCreateOrUpdate, UserClaimDelete } from '@/api/users' |
|||
import ClaimTypeApiService, { IdentityClaimType, IdentityClaimValueType } from '@/api/cliam-type' |
|||
import { Form } from 'element-ui' |
|||
|
|||
@Component({ |
|||
name: 'UserClaimCreateOrUpdateForm', |
|||
methods: { |
|||
checkPermission |
|||
} |
|||
}) |
|||
export default class UserClaimCreateOrUpdateForm extends Vue { |
|||
@Prop({ default: '' }) |
|||
private userId!: string |
|||
|
|||
@Prop({ default: '' }) |
|||
private title!: string |
|||
|
|||
@Prop({ default: false }) |
|||
private showDialog!: boolean |
|||
|
|||
private editUserClaim = new UserClaimCreateOrUpdate() |
|||
private userClaims = new Array<UserClaim>() |
|||
private claimTypes = new Array<IdentityClaimType>() |
|||
|
|||
private userClaimRules = {} |
|||
|
|||
get cliamType() { |
|||
return (claimName: string) => { |
|||
const claimIndex = this.claimTypes.findIndex(cliam => cliam.name === claimName) |
|||
if (claimIndex >= 0) { |
|||
return this.claimTypes[claimIndex].valueType |
|||
} |
|||
return IdentityClaimValueType.String |
|||
} |
|||
} |
|||
|
|||
get claimValue() { |
|||
return (type: string, value: string) => { |
|||
const valueType = this.cliamType(type) |
|||
switch (valueType) { |
|||
case IdentityClaimValueType.Int : |
|||
case IdentityClaimValueType.String : |
|||
return value |
|||
case IdentityClaimValueType.Boolean : |
|||
return value.toLowerCase() === 'true' |
|||
case IdentityClaimValueType.DateTime : |
|||
return dateFormat(new Date(value), 'YYYY-mm-dd HH:MM:SS') |
|||
} |
|||
} |
|||
} |
|||
|
|||
get hasStringValueType() { |
|||
return (claimName: string) => { |
|||
return this.cliamType(claimName) === IdentityClaimValueType.String |
|||
} |
|||
} |
|||
|
|||
get hasBooleanValueType() { |
|||
return (claimName: string) => { |
|||
return this.cliamType(claimName) === IdentityClaimValueType.Boolean |
|||
} |
|||
} |
|||
|
|||
get hasDateTimeValueType() { |
|||
return (claimName: string) => { |
|||
return this.cliamType(claimName) === IdentityClaimValueType.DateTime |
|||
} |
|||
} |
|||
|
|||
get hasIntegerValueType() { |
|||
return (claimName: string) => { |
|||
return this.cliamType(claimName) === IdentityClaimValueType.Int |
|||
} |
|||
} |
|||
|
|||
@Watch('userId') |
|||
private onUserIdChanged() { |
|||
if (this.userId && this.showDialog) { |
|||
this.handleGetUserClaims() |
|||
} |
|||
} |
|||
|
|||
mounted() { |
|||
this.handleGetClaimTypes() |
|||
this.handleGetUserClaims() |
|||
this.userClaimRules = { |
|||
claimType: [ |
|||
{ required: true, message: this.l('pleaseSelectBy', { key: this.l('AbpIdentity.DisplayName:ClaimType') }), trigger: 'blur' } |
|||
], |
|||
claimValue: [ |
|||
{ required: true, message: this.l('pleaseInputBy', { key: this.l('AbpIdentity.DisplayName:ClaimValue') }), trigger: 'blur' } |
|||
] |
|||
} |
|||
} |
|||
|
|||
private handleGetClaimTypes() { |
|||
ClaimTypeApiService.getActivedClaimTypes().then(res => { |
|||
this.claimTypes = res.items |
|||
}) |
|||
} |
|||
|
|||
private handleGetUserClaims() { |
|||
if (this.userId) { |
|||
UserService.getUserClaims(this.userId).then(res => { |
|||
this.userClaims = res.items |
|||
}) |
|||
} |
|||
} |
|||
|
|||
private handleDeleteUserClaim(claim: UserClaim) { |
|||
this.$confirm(this.l('AbpIdentity.DeleteClaim'), |
|||
this.l('AbpUi.AreYouSure'), { |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
const deleteClaim = new UserClaimDelete() |
|||
deleteClaim.claimType = claim.claimType |
|||
deleteClaim.claimValue = claim.claimValue |
|||
UserService.deleteUserClaim(this.userId, deleteClaim).then(() => { |
|||
this.$message.success(this.l('global.successful')) |
|||
const claimIndex = this.userClaims.findIndex(uc => uc.id === claim.id) |
|||
this.userClaims.splice(claimIndex, 1) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
// TODO: 可以简化为一个组件,通过组件来实现用户/客户端等的声明类型 |
|||
private onClaimTypeChanged() { |
|||
const valueType = this.cliamType(this.editUserClaim.claimType) |
|||
switch (valueType) { |
|||
case IdentityClaimValueType.Int : |
|||
this.editUserClaim.claimValue = '0' |
|||
break |
|||
case IdentityClaimValueType.String : |
|||
this.editUserClaim.claimValue = '' |
|||
break |
|||
case IdentityClaimValueType.Boolean : |
|||
this.editUserClaim.claimValue = 'false' |
|||
break |
|||
case IdentityClaimValueType.DateTime : |
|||
this.editUserClaim.claimValue = '' |
|||
break |
|||
} |
|||
} |
|||
|
|||
private onSave() { |
|||
const userClaimForm = this.$refs.userClaimForm as Form |
|||
userClaimForm.validate(valid => { |
|||
if (valid) { |
|||
UserService.addUserClaim(this.userId, this.editUserClaim).then(() => { |
|||
this.$message.success(this.$t('global.successful').toString()) |
|||
userClaimForm.resetFields() |
|||
this.handleGetUserClaims() |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
private onFormClosed(changed: boolean) { |
|||
const userClaimForm = this.$refs.userClaimForm as Form |
|||
userClaimForm.resetFields() |
|||
this.$emit('closed', changed) |
|||
} |
|||
|
|||
private l(name: string, values?: any[] | { [key: string]: any }) { |
|||
return this.$t(name, values).toString() |
|||
} |
|||
} |
|||
</script> |
|||
Loading…
Reference in new issue