Browse Source

完善通知组件;完善用户注册组件

pull/1/head
cKey 6 years ago
parent
commit
2a7acb7b6c
  1. 25
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
  2. 1
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
  3. 24
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
  4. 16
      aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs
  5. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs
  6. 14
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs
  7. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
  8. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
  9. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
  10. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs
  11. 30
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs
  12. 13
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs
  13. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs
  14. 17
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
  15. 5
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
  16. 9
      vueJs/src/api/abpconfiguration.ts
  17. 112
      vueJs/src/components/Notification/index.vue
  18. 3
      vueJs/src/lang/zh.ts
  19. 2
      vueJs/src/store/modules/user.ts
  20. 3
      vueJs/src/views/admin/tenants/index.vue
  21. 3
      vueJs/src/views/admin/users/index.vue
  22. 13
      vueJs/src/views/login/index.vue
  23. 78
      vueJs/src/views/register/index.vue

25
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs

@ -10,11 +10,11 @@ namespace LINGYUN.Abp.MessageService.Controllers
[Route("api/app/notifications")]
public class NotificationController : AbpController
{
private readonly INotificationPublisher _notificationPublisher;
private readonly INotificationDispatcher _notificationDispatcher;
public NotificationController(
INotificationPublisher notificationPublisher)
INotificationDispatcher notificationDispatcher)
{
_notificationPublisher = notificationPublisher;
_notificationDispatcher = notificationDispatcher;
}
[HttpPost]
@ -24,17 +24,19 @@ namespace LINGYUN.Abp.MessageService.Controllers
var notificationInfo = new NotificationInfo
{
TenantId = null,
NotificationSeverity = NotificationSeverity.Success,
NotificationSeverity = notification.Severity,
NotificationType = NotificationType.Application,
Id = 164589598456654164,
Name = "TestApplicationNotofication"
Id = new Random().Next(int.MinValue, int.MaxValue),
Name = "TestApplicationNotofication",
CreationTime = Clock.Now
};
notificationInfo.Data.Properties["Title"] = notification.Title;
notificationInfo.Data.Properties["Message"] = notification.Message;
notificationInfo.Data.Properties["DateTime"] = notification.DateTime;
notificationInfo.Data.Properties["Severity"] = notification.Severity;
notificationInfo.Data.Properties["id"] = notificationInfo.Id.ToString();
notificationInfo.Data.Properties["title"] = notification.Title;
notificationInfo.Data.Properties["message"] = notification.Message;
notificationInfo.Data.Properties["datetime"] = Clock.Now;
notificationInfo.Data.Properties["severity"] = notification.Severity;
await _notificationPublisher.PublishAsync(notificationInfo, new List<Guid>() { notification.UserId });
await _notificationDispatcher.DispatcheAsync(notificationInfo);
}
}
@ -42,7 +44,6 @@ namespace LINGYUN.Abp.MessageService.Controllers
{
public Guid UserId { get; set; }
public string Title { get; set; }
public DateTime DateTime { get; set; } = DateTime.Now;
public string Message { get; set; }
public NotificationSeverity Severity { get; set; } = NotificationSeverity.Success;
}

1
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -30,6 +30,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj" />
<ProjectReference Include="..\modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj" />
<ProjectReference Include="..\modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj" />

24
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs

@ -87,30 +87,6 @@ namespace LINGYUN.Abp.MessageService
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
Configure<JwtBearerOptions>(options =>
{
// 处理signalr某些请求由querystring发送请求令牌
// https://docs.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1
options.Authority = configuration["AuthServer:Authority"];
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
// If the request is for our hub...
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/signalr-hubs/notifications")))
{
// Read the token out of the query string
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
context.Services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{

16
aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Utils/SnowflakeIdGenerator.cs

@ -0,0 +1,16 @@
using DotNetCore.CAP.Internal;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.MessageService.Utils
{
[Dependency(ServiceLifetime.Singleton, TryRegister = true)]
[ExposeServices(typeof(ISnowflakeIdGenerator))]
public class SnowflakeIdGenerator : ISnowflakeIdGenerator
{
public long Create()
{
return SnowflakeId.Default().NextId();
}
}
}

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs

@ -59,13 +59,15 @@ namespace LINGYUN.Abp.Account
var userEmail = input.EmailAddress ?? input.PhoneNumber + "@abp.io";
var userName = input.UserName ?? input.PhoneNumber;
var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id);
user.Name = input.Name ?? input.PhoneNumber;
var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id)
{
Name = input.Name ?? input.PhoneNumber
};
(await UserManager.CreateAsync(user, input.Password)).CheckErrors();
await UserManager.ChangePhoneNumberAsync(user, input.PhoneNumber, input.VerifyCode);
await UserManager.SetEmailAsync(user, userEmail);
await UserManager.AddDefaultRolesAsync(user);
(await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
(await UserManager.SetEmailAsync(user, userEmail)).CheckErrors();
(await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
await Cache.RemoveAsync(phoneVerifyCacheKey);

14
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs

@ -2,7 +2,6 @@
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Users;
namespace LINGYUN.Abp.Notifications.SignalR.Hubs
@ -14,11 +13,20 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs
protected INotificationStore NotificationStore => LazyGetRequiredService(ref _notificationStore);
[HubMethodName("GetNotification")]
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync(NotificationReadState readState = NotificationReadState.UnRead)
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync(
NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10)
{
var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState);
var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState, maxResultCount);
return new ListResultDto<NotificationInfo>(userNotifications);
}
[HubMethodName("ChangeState")]
public virtual async Task ChangeStateAsync(long id, NotificationReadState readState = NotificationReadState.Read)
{
await NotificationStore.ChangeUserNotificationReadStateAsync(CurrentTenant.Id, CurrentUser.GetId(), id, readState);
}
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="2.8.0" />
<PackageReference Include="Volo.Abp.Json" Version="2.8.0" />
</ItemGroup>
</Project>

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs

@ -24,6 +24,8 @@ namespace LINGYUN.Abp.Notifications
Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId);
Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable<Guid> userIds);
Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId);
Task<NotificationInfo> GetNotificationOrNullAsync(Guid? tenantId, long notificationId);

4
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs

@ -23,9 +23,9 @@ namespace LINGYUN.Abp.Notifications.Internal
// 获取用户订阅列表
var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notification.TenantId, notification.Name);
// 持久化用户订阅通知
// 持久化用户通知
var subscriptionUserIds = userSubscriptions.Select(us => us.UserId);
await _notificationStore.InsertUserSubscriptionAsync(notification.TenantId, subscriptionUserIds, notification.Name);
await _notificationStore.InsertUserNotificationsAsync(notification, subscriptionUserIds);
// 发布用户通知
await _notificationPublisher.PublishAsync(notification, subscriptionUserIds);

4
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs

@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
namespace LINGYUN.Abp.Notifications
{
@ -6,6 +7,7 @@ namespace LINGYUN.Abp.Notifications
{
public Guid? TenantId { get; set; }
public string Name { get; set; }
[JsonConverter(typeof(HexLongConverter))]
public long Id { get; set; }
public NotificationData Data { get; set; }
public DateTime CreationTime { get; set; }

30
aspnet-core/modules/common/LINGYUN.Abp.Notifications/Newtonsoft/Json/HexLongConverter.cs

@ -0,0 +1,30 @@
using System;
namespace Newtonsoft.Json
{
public class HexLongConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long v = value is ulong ? (long)(ulong)value : (long)value;
writer.WriteValue(v.ToString());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string value = reader.Value as string;
long lValue = long.Parse(value);
return typeof(ulong) == objectType ? (object)(ulong)lValue : lValue;
}
public override bool CanConvert(Type objectType)
{
switch (objectType.FullName)
{
case "System.Int64":
case "System.UInt64":
return true;
default:
return false;
}
}
}
}

13
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDomainModule.cs

@ -1,9 +1,18 @@
using Volo.Abp.Modularity;
using LINGYUN.Abp.MessageService.Mapper;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.MessageService
{
[DependsOn(typeof(AbpAutoMapperModule))]
public class AbpMessageServiceDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<MessageServiceDomainAutoMapperProfile>(validate: true);
});
}
}
}

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs

@ -8,6 +8,8 @@ namespace LINGYUN.Abp.MessageService.Notifications
{
public interface IUserNotificationRepository : IBasicRepository<UserNotification, long>
{
Task InsertUserNotificationsAsync(IEnumerable<UserNotification> userNotifications);
Task<UserNotification> GetByIdAsync(Guid userId, long notificationId);
Task<List<Notification>> GetNotificationsAsync(Guid userId, NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10);

17
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs

@ -155,7 +155,11 @@ namespace LINGYUN.Abp.MessageService.Notifications
{
using (CurrentTenant.Change(notification.TenantId))
{
var notify = new Notification(SnowflakeIdGenerator.Create(), notification.Name,
var notifyId = SnowflakeIdGenerator.Create();
// 保存主键,防止前端js long类型溢出
notification.Data["id"] = notifyId.ToString();
var notify = new Notification(notifyId, notification.Name,
notification.Data.GetType().AssemblyQualifiedName,
JsonSerializer.Serialize(notification.Data), notification.NotificationSeverity)
{
@ -235,5 +239,16 @@ namespace LINGYUN.Abp.MessageService.Notifications
using (CurrentTenant.Change(tenantId))
return await UserSubscribeRepository.UserSubscribeExistsAysnc(notificationName, userId);
}
public async Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable<Guid> userIds)
{
var userNofitications = new List<UserNotification>();
foreach(var userId in userIds)
{
var userNofitication = new UserNotification(notification.Id, userId);
userNofitications.Add(userNofitication);
}
await UserNotificationRepository.InsertUserNotificationsAsync(userNofitications);
}
}
}

5
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs

@ -20,6 +20,11 @@ namespace LINGYUN.Abp.MessageService.Notifications
{
}
public async Task InsertUserNotificationsAsync(IEnumerable<UserNotification> userNotifications)
{
await DbSet.AddRangeAsync(userNotifications);
}
public async Task ChangeUserNotificationReadStateAsync(Guid userId, long notificationId, NotificationReadState readState)
{
var userNofitication = await GetByIdAsync(userId, notificationId);

9
vueJs/src/api/abpconfiguration.ts

@ -90,6 +90,8 @@ export interface IAbpConfiguration {
multiTenancy: MultiTenancy
objectExtensions: any
setting: Setting
getSetting(key: string): string | undefined
}
export class AbpConfiguration implements IAbpConfiguration {
@ -111,4 +113,11 @@ export class AbpConfiguration implements IAbpConfiguration {
this.multiTenancy = new MultiTenancy()
this.currentTenant = new CurrentTenant()
}
public getSetting(key: string) {
if (this.setting.values && this.setting.values[key]) {
return this.setting.values[key]
}
return undefined
}
}

112
vueJs/src/components/Notification/index.vue

@ -1,11 +1,15 @@
<template>
<el-dropdown>
<div>
<el-dropdown trigger="click">
<el-badge
:value="notifications.length"
class="item"
:hidden="notifications.length<=0"
>
<svg-icon
name="message"
class="message-icon"
/>
</div>
</el-badge>
<el-dropdown-menu slot="dropdown">
<div
class="app-container"
@ -16,25 +20,28 @@
>
<el-tab-pane
label="通知"
>
<div
style="overflow-x: hidden;overflow-y: auto;"
class="notification"
>
<List
size="small"
>
<ListItem
v-for="(notify, index) in notifications"
:key="index"
v-for="(notify) in notifications"
:key="notify.id"
>
<ListItemMeta
:title="notify.Message"
:description="formatDateTime(notify.DateTime)"
avatar="ios-person"
:title="notify.message"
:description="formatDateTime(notify.datetime)"
@click="handleClickNotification(notify.id)"
>
<template slot="avatar">
<Avatar
icon="ios-person"
/>
</template>
</ListItemMeta>
</ListItem>
</List>
</div>
</el-tab-pane>
<el-tab-pane label="消息">
消息系统
@ -50,6 +57,7 @@ import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@micros
import { Component, Vue } from 'vue-property-decorator'
import { UserModule } from '@/store/modules/user'
import { dateFormat } from '@/utils/index'
import { MessageType } from 'element-ui/types/message'
enum Severity {
success = 0,
@ -59,11 +67,17 @@ enum Severity {
fatal = 40
}
enum ReadState {
Read = 0,
UnRead = 1
}
class Notification {
Title!: string
Message!: string
DateTime!: Date
Severity!: Severity
id!: string
title!: string
message!: string
datetime!: Date
severity!: Severity
}
@Component({
@ -82,14 +96,14 @@ export default class extends Vue {
}
private renderIconType(item: any) {
if (item.Severity !== Severity.success) {
if (item.severity !== Severity.success) {
return ' el-icon-circle-close'
}
return ' el-icon-circle-check'
}
private renderIconStyle(item: any) {
if (item.Severity !== Severity.success) {
if (item.severity !== Severity.success) {
return 'backgroundColor: #f56a00'
}
return 'backgroundColor: #87d068'
@ -104,9 +118,7 @@ export default class extends Vue {
console.log('start signalr connection...')
if (!this.connection) {
const builder = new HubConnectionBuilder()
console.log(builder)
const userToken = UserModule.token.replace('Bearer ', '')
console.log(userToken)
this.connection = builder
.withUrl('/signalr-hubs/signalr-hubs/notifications', { accessTokenFactory: () => userToken })
.withAutomaticReconnect({ nextRetryDelayInMilliseconds: () => 60000 })
@ -118,7 +130,16 @@ export default class extends Vue {
})
}
if (this.connection.state !== HubConnectionState.Connected) {
this.connection.start()
this.connection.start().then(() => {
this.connection.invoke('GetNotification', ReadState.UnRead, 10).then(result => {
console.log(result)
result.items.forEach((notify: any) => {
const notification = notify.data.properties
notification.id = notify.id
this.notifications.push(notification)
})
})
})
}
}
@ -132,14 +153,53 @@ export default class extends Vue {
private onNotificationReceived(data: any) {
console.log('received signalr message...')
console.log(data)
this.notifications.push(data.data.properties)
this.$notify.success(data.data.properties.message)
const notification = data.data.properties
this.pushUserNotification(notification)
this.$notify({
title: notification.title,
message: notification.message,
type: this.getNofiyType(data.notificationSeverity)
})
}
private handleClickNotification(notificationId: string) {
console.log('handleClickNotification')
this.connection.invoke('ChangeState', notificationId, ReadState.Read).then(() => {
const removeNotifyIndex = this.notifications.findIndex(n => n.id === notificationId)
this.notifications.splice(removeNotifyIndex)
})
}
private pushUserNotification(notification: any) {
if (this.notifications.length === 20) {
this.notifications.shift()
}
this.notifications.push(notification)
}
private getNofiyType(severity: Severity) {
const mapNotifyType: {[key: number]: MessageType } = {
0: 'success',
10: 'info',
20: 'warning',
30: 'error',
40: 'error'
}
return mapNotifyType[severity]
}
}
</script>
<style scoped>
.el-scrollbar__wrap{
overflow-x: hidden;
<style lang="scss">
.item {
margin-top: 0px;
margin-right: 10px;
}
.item.el-dropdown-selfdefine > .el-badge__content.el-badge__content--undefined.is-fixed {
top: 10px;
}
.notification > .ivu-list.ivu-list-small.ivu-list-horizontal.ivu-list-split{
max-height: 200px;
overflow: auto;
}
</style>

3
vueJs/src/lang/zh.ts

@ -90,6 +90,9 @@ export default {
login: {
title: '系统登录',
logIn: '登录',
register: '注册',
notAccount: '没有账户?',
existsAccount: '已有账户?',
userLogin: '用户密码登录',
phoneLogin: '手机免密登录',
tenantName: '租户',

2
vueJs/src/store/modules/user.ts

@ -137,7 +137,7 @@ class User extends VuexModule implements IUserState {
@Action
public RefreshSession() {
return new Promise((resolve, reject) => {
const token = getItem(tokenKey)
const token = getItem(refreshTokenKey)
if (token) {
UserApiService.refreshToken(token).then(result => {
const token = result.token_type + ' ' + result.access_token

3
vueJs/src/views/admin/tenants/index.vue

@ -78,7 +78,7 @@
<el-table-column
:label="$t('global.lastModificationTime')"
prop="lastModificationTime"
width="170px"
width="230px"
align="center"
>
<template slot-scope="{row}">
@ -93,6 +93,7 @@
:label="$t('global.operaActions')"
align="center"
width="250px"
min-width="250px"
fixed="right"
>
<template slot-scope="{row}">

3
vueJs/src/views/admin/users/index.vue

@ -327,9 +327,6 @@ export default class extends Vue {
vertical-align: top;
margin-left: 20px;
}
.el-dropdown + .el-dropdown {
margin-left: 15px;
}
.el-icon-arrow-down {
font-size: 12px;
}

13
vueJs/src/views/login/index.vue

@ -105,14 +105,15 @@
</el-tab-pane>
</el-tabs>
<el-form-item
v-show="selfRegistration"
label-width="100px"
label="没有用户?"
:label="$t('login.notAccount')"
>
<el-link
type="success"
@click="handleRedirectRegister"
>
注册
{{ $t('login.register') }}
</el-link>
</el-form-item>
@ -169,6 +170,14 @@ export default class extends Vue {
return AbpConfigurationModule.configuration.multiTenancy.isEnabled
}
get selfRegistration() {
const selfRegister = AbpConfigurationModule.configuration.setting.values['Abp.Account.IsSelfRegistrationEnabled']
if (selfRegister) {
return selfRegister === 'true'
}
return false
}
private validatePhoneNumberValue = (rule: any, value: string, callback: any) => {
const phoneReg = /^1[34578]\d{9}$/
if (!value || !phoneReg.test(value)) {

78
vueJs/src/views/register/index.vue

@ -2,8 +2,8 @@
<div class="login-container">
<el-form
ref="formLogin"
:model="loginForm"
:rules="loginFormRules"
:model="registerForm"
:rules="registerFormRules"
label-position="left"
label-width="0px"
class="demo-ruleForm login-page"
@ -17,14 +17,14 @@
<el-form-item label-width="0px">
<tenant-box
v-if="isMultiEnabled"
v-model="loginForm.tenantName"
v-model="registerForm.tenantName"
/>
</el-form-item>
<el-form-item
prop="username"
>
<el-input
v-model="loginForm.username"
v-model="registerForm.username"
prefix-icon="el-icon-user"
type="text"
auto-complete="off"
@ -38,13 +38,13 @@
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
v-model="registerForm.password"
prefix-icon="el-icon-lock"
:type="passwordType"
:placeholder="$t('global.pleaseInputBy', {key: $t('login.password')})"
name="password"
tabindex="2"
@keyup.enter.native="handleUserLogin"
@keyup.enter.native="handleUserRegister"
/>
<span
class="show-pwd"
@ -58,7 +58,7 @@
>
<el-input
ref="loginItemPhone"
v-model="loginForm.phoneNumber"
v-model="registerForm.phoneNumber"
prefix-icon="el-icon-mobile-phone"
type="text"
maxlength="11"
@ -72,7 +72,7 @@
<el-row>
<el-col :span="16">
<el-input
v-model="loginForm.verifyCode"
v-model="registerForm.verifyCode"
auto-complete="off"
:placeholder="$t('global.pleaseInputBy', {key: $t('login.phoneVerifyCode')})"
prefix-icon="el-icon-key"
@ -93,13 +93,13 @@
</el-form-item>
<el-form-item
label-width="100px"
label="已有用户?"
:label="$t('login.existsAccount')"
>
<el-link
type="success"
@click="handleRedirectLogin"
>
登录
{{ $t('login.logIn') }}
</el-link>
</el-form-item>
@ -107,10 +107,10 @@
<el-button
type="primary"
style="width:100%;"
:loading="logining"
@click="handleUserLogin"
:loading="registing"
@click="handleUserRegister"
>
{{ $t('login.logIn') }}
{{ $t('login.register') }}
</el-button>
</el-form-item>
</el-form>
@ -120,7 +120,6 @@
<script lang="ts">
import { Input } from 'element-ui'
import { Route } from 'vue-router'
import { UserModule } from '@/store/modules/user'
import { Dictionary } from 'vue-router/types/router'
import TenantBox from '@/components/TenantBox/index.vue'
import LangSelect from '@/components/LangSelect/index.vue'
@ -136,15 +135,14 @@ import { AbpConfigurationModule } from '@/store/modules/abp'
}
})
export default class extends Vue {
private loginType = 'password'
private passwordType = 'password'
private redirect?: string
private sendTimer: any
private sending = false
private sendButtonName = this.l('login.sendVerifyCode')
private logining = false
private loginForm = {
private registing = false
private registerForm = {
tenantName: '',
username: '',
password: '',
@ -165,7 +163,7 @@ export default class extends Vue {
}
}
private loginFormRules = {
private registerFormRules = {
username: [
{
required: true, message: this.l('global.pleaseInputBy', { key: this.l('login.username') }), trigger: 'blur'
@ -219,33 +217,23 @@ export default class extends Vue {
this.$router.replace('login')
}
private handleUserLogin() {
private handleUserRegister() {
const frmLogin = this.$refs.formLogin as any
frmLogin.validate(async(valid: boolean) => {
if (valid) {
this.logining = true
this.registing = true
try {
if (this.loginType === 'password') {
const userLogin = {
tenantName: this.loginForm.tenantName,
username: this.loginForm.username,
password: this.loginForm.password
}
await UserModule.Login(userLogin)
this.$router.push({
path: this.redirect || '/'
})
} else {
const phoneLogin = {
tenantName: this.loginForm.tenantName,
phoneNumber: this.loginForm.phoneNumber,
verifyCode: this.loginForm.verifyCode
}
await UserModule.PhoneLogin(phoneLogin)
this.$router.push({
path: this.redirect || '/'
const userRegister = new UserRegisterData()
userRegister.phoneNumber = this.registerForm.phoneNumber
userRegister.verifyCode = this.registerForm.verifyCode
userRegister.name = this.registerForm.username
userRegister.userName = this.registerForm.username
userRegister.password = this.registerForm.password
UserService.userRegister(userRegister).then(() => {
this.handleRedirectLogin()
}).finally(() => {
this.resetLoginButton()
})
}
} catch {
this.resetLoginButton()
}
@ -259,8 +247,8 @@ export default class extends Vue {
if (!errorMsg) {
this.sending = true
const phoneVerify = new PhoneVerify()
phoneVerify.phoneNumber = this.loginForm.phoneNumber
phoneVerify.verifyType = VerifyType.signin
phoneVerify.phoneNumber = this.registerForm.phoneNumber
phoneVerify.verifyType = VerifyType.register
UserService.sendPhoneVerifyCode(phoneVerify).then(() => {
let interValTime = 60
const sendingName = this.l('login.afterSendVerifyCode')
@ -281,17 +269,13 @@ export default class extends Vue {
})
}
private handleLoginTabChanged(tab: any) {
this.loginType = tab.paneName === '1' ? 'phone' : 'password'
}
private l(name: string, values?: any[] | { [key: string]: any }) {
return this.$t(name, values).toString()
}
private resetLoginButton() {
setTimeout(() => {
this.logining = false
this.registing = false
}, 0.5 * 1000)
}
}

Loading…
Cancel
Save