23 changed files with 1456 additions and 191 deletions
@ -1,4 +1,5 @@ |
|||||
export default { |
export default { |
||||
enableLocale: false, |
enableLocale: false, |
||||
baseURL: "http://dev.ccwin-in.com:10582/api", |
baseURL: "http://dev.ccwin-in.com:10582/api", |
||||
|
//baseURL: "http://localhost:10130/api",
|
||||
}; |
}; |
||||
|
@ -0,0 +1,113 @@ |
|||||
|
const messages = { |
||||
|
default: "%s验证失败", |
||||
|
required: "%s是必填项", |
||||
|
enum: "%s必须是%s之一", |
||||
|
whitespace: "%s不能为空", |
||||
|
// date: {
|
||||
|
// format: '%s date %s is invalid for format %s',
|
||||
|
// parse: '%s date could not be parsed, %s is invalid ',
|
||||
|
// invalid: '%s date %s is invalid',
|
||||
|
// },
|
||||
|
types: { |
||||
|
string: "%s不是有效的字符串", |
||||
|
method: "%s不是有效的函数", |
||||
|
array: "%s不是有效的数组", |
||||
|
object: "%s不是有效的对象", |
||||
|
number: "%s不是有效的数字", |
||||
|
date: "%s不是有效的日期", |
||||
|
boolean: "%s不是有效的布尔值", |
||||
|
integer: "%s不是有效的整数", |
||||
|
float: "%s不是有效的浮点数", |
||||
|
regexp: "%s不是有效的正则表达式", |
||||
|
email: "%s不是有效的邮箱", |
||||
|
url: "%s不是有效的 url", |
||||
|
hex: "%s不是有效的十六进制", |
||||
|
}, |
||||
|
string: { |
||||
|
len: "%s长度必须是%s", |
||||
|
min: "%s最小长度为%s", |
||||
|
max: "%s最大长度为%s", |
||||
|
range: "%s长度必须在%s和%s之间", |
||||
|
}, |
||||
|
number: { |
||||
|
len: "%s必须等于%s", |
||||
|
min: "%s不小于%s", |
||||
|
max: "%s不大于%s", |
||||
|
range: "%s必须在%s和%s之间", |
||||
|
}, |
||||
|
array: { |
||||
|
len: "%s的数量必须是%s", |
||||
|
min: "%s的数量不小于%s", |
||||
|
max: "%s的数量不大于%s", |
||||
|
range: "%s的数量必须在%s和%s之间", |
||||
|
}, |
||||
|
pattern: { |
||||
|
mismatch: "%s的值 %s 不匹配模式 %s", |
||||
|
}, |
||||
|
clone: function clone() { |
||||
|
const cloned = JSON.parse(JSON.stringify(this)); |
||||
|
cloned.clone = this.clone; |
||||
|
return cloned; |
||||
|
}, |
||||
|
//
|
||||
|
compare: "%s 和 %s 输入必须一致", |
||||
|
true: "%s必须选中", |
||||
|
remote: "%s远程验证失败", |
||||
|
}; |
||||
|
|
||||
|
const validators = { |
||||
|
compare(rule, value, callback, source, options) { |
||||
|
const errors = []; |
||||
|
if (value && value !== rule.data[rule.compare]) { |
||||
|
const message = format(options.messages.compare, rule.title, rule.schema.properties[rule.compare].title); |
||||
|
errors.push(new Error(message)); |
||||
|
} |
||||
|
callback(errors); |
||||
|
}, |
||||
|
true(rule, value, callback, source, options) { |
||||
|
const errors = []; |
||||
|
if (!value) { |
||||
|
const message = format(options.messages.true, rule.title); |
||||
|
errors.push(new Error(message)); |
||||
|
} |
||||
|
callback(errors); |
||||
|
}, |
||||
|
remote(rule, value, callback, source, options) { |
||||
|
const errors = []; |
||||
|
const message = format(options.messages.remote, rule.title); |
||||
|
if (!value) { |
||||
|
callback(errors); |
||||
|
} else { |
||||
|
const config = { |
||||
|
url: rule.url, |
||||
|
method: rule.method ?? "get", |
||||
|
}; |
||||
|
const data = { [rule.field]: value }; |
||||
|
if (config.method === "get") { |
||||
|
config.params = data; |
||||
|
} else { |
||||
|
config.data = data; |
||||
|
} |
||||
|
request |
||||
|
.request(config) |
||||
|
.then((response) => { |
||||
|
if (response.status === 200) { |
||||
|
if (response.data.code) { |
||||
|
if (response.data.code !== 200) { |
||||
|
errors.push(new Error(1 + response.data.message)); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
errors.push(new Error(2 + response.data)); |
||||
|
} |
||||
|
callback(errors); |
||||
|
}) |
||||
|
.catch((o) => { |
||||
|
errors.push(o.response?.data?.message ?? message ?? o.message); |
||||
|
callback(errors); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export { messages }; |
@ -0,0 +1,55 @@ |
|||||
|
using IdentityModel.Client; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
|
||||
|
namespace BaseService.UserManagement |
||||
|
{ |
||||
|
[Route("api/base/token")] |
||||
|
public class UserAppService : ApplicationService |
||||
|
{ |
||||
|
private readonly IHttpClientFactory _httpClientFactory; |
||||
|
private readonly IConfiguration _configuration; |
||||
|
|
||||
|
public UserAppService(IHttpClientFactory httpClientFactory, IConfiguration configuration) |
||||
|
{ |
||||
|
this._httpClientFactory = httpClientFactory; |
||||
|
this._configuration = configuration; |
||||
|
} |
||||
|
|
||||
|
[HttpPost, AllowAnonymous, IgnoreAntiforgeryToken] |
||||
|
public async Task<TokenResponse> CreateAsync(LoginModel model) |
||||
|
{ |
||||
|
var address = _configuration["AuthServer:Authority"]; |
||||
|
var clientId = _configuration["AuthServer:ClientId"]; |
||||
|
var clientSecret = _configuration["AuthServer:ClientSecret"]; |
||||
|
|
||||
|
var result = await _httpClientFactory.CreateClient().RequestPasswordTokenAsync(new PasswordTokenRequest |
||||
|
{ |
||||
|
Address = $"{address.TrimEnd('/')}/connect/token", |
||||
|
GrantType = "password", |
||||
|
ClientId = clientId, |
||||
|
ClientSecret = clientSecret, |
||||
|
UserName = model.UserName, |
||||
|
Password = model.Password |
||||
|
}).ConfigureAwait(false); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public class LoginModel |
||||
|
{ |
||||
|
[Display] |
||||
|
[Required] |
||||
|
public string UserName { get; set; } |
||||
|
|
||||
|
[Display] |
||||
|
[Required] |
||||
|
public string Password { get; set; } |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"version": 1, |
||||
|
"isRoot": true, |
||||
|
"tools": { |
||||
|
"dotnet-ef": { |
||||
|
"version": "7.0.8", |
||||
|
"commands": [ |
||||
|
"dotnet-ef" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 307 KiB |
File diff suppressed because it is too large
Loading…
Reference in new issue