dev #14384 Правка ошибок отображения WPA КофеЛайк: add auth service to store information about user and fix getUserInfo
This commit is contained in:
parent
e20cd30a54
commit
4e0a41b644
@ -1 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
<p-toast position="top-center"></p-toast>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RouteConfigLoadStart, Router } from '@angular/router';
|
||||
import { AuthService } from './services/auth.service';
|
||||
import { CookiesService } from './services/cookies.service';
|
||||
import { JsonrpcService, RpcService } from './services/jsonrpc.service';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -15,7 +15,8 @@ export class AppComponent implements OnInit {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private cookiesService: CookiesService,
|
||||
private jsonRpcService: JsonrpcService
|
||||
private jsonRpcService: JsonrpcService,
|
||||
private authService: AuthService,
|
||||
) {
|
||||
this.router.events.subscribe((x) => {
|
||||
if (x instanceof RouteConfigLoadStart && x.route.path === '') {
|
||||
@ -48,6 +49,9 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.authService.authorized) {
|
||||
this.authService.getUserInfo();
|
||||
}
|
||||
this.getAdditionalInfo().subscribe({
|
||||
next: (value) => {
|
||||
this.cookiesService.setCookie('presentation-option', value?.data?.interface_id || 'default')
|
||||
|
||||
@ -1,93 +1,93 @@
|
||||
import {OrderStatus, Page, PageCode, lvlPeriod} from "./interface/data";
|
||||
import { OrderStatus, Page, PageCode, lvlPeriod } from "./interface/data";
|
||||
|
||||
export const PageList: Page[] = [
|
||||
{
|
||||
code: PageCode.Auth,
|
||||
name: 'Вход',
|
||||
resName: 'auth',
|
||||
onSideBar: false,
|
||||
},
|
||||
{
|
||||
code: PageCode.Orders,
|
||||
name: 'Заказы',
|
||||
resName: 'orders',
|
||||
onSideBar: true,
|
||||
},
|
||||
{
|
||||
code: PageCode.Auth,
|
||||
name: 'Вход',
|
||||
resName: 'auth',
|
||||
onSideBar: false,
|
||||
},
|
||||
{
|
||||
code: PageCode.Orders,
|
||||
name: 'Заказы',
|
||||
resName: 'orders',
|
||||
onSideBar: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const PageListWithBonus: Page[] = [
|
||||
{
|
||||
code: PageCode.Auth,
|
||||
name: 'Вход',
|
||||
resName: 'auth',
|
||||
onSideBar: false,
|
||||
},
|
||||
{
|
||||
code: PageCode.BonusProgram,
|
||||
name: 'Ваша карта лояльности',
|
||||
description: '',
|
||||
resName: 'bonus-program',
|
||||
onSideBar: true,
|
||||
},
|
||||
{
|
||||
code: PageCode.Orders,
|
||||
name: 'Ваши чеки',
|
||||
description: '',
|
||||
resName: 'orders',
|
||||
onSideBar: true,
|
||||
},
|
||||
{
|
||||
code: PageCode.UserData,
|
||||
name: 'Заполнить анкету',
|
||||
description: '',
|
||||
resName: 'user-data',
|
||||
onSideBar: true
|
||||
},
|
||||
{
|
||||
code: PageCode.RefSystem,
|
||||
name: 'Пригласить друга',
|
||||
description: '',
|
||||
resName: 'ref-system',
|
||||
onSideBar: true,
|
||||
}
|
||||
{
|
||||
code: PageCode.Auth,
|
||||
name: 'Вход',
|
||||
resName: 'auth',
|
||||
onSideBar: false,
|
||||
},
|
||||
{
|
||||
code: PageCode.BonusProgram,
|
||||
name: 'Ваша карта лояльности',
|
||||
description: '',
|
||||
resName: 'bonus-program',
|
||||
onSideBar: true,
|
||||
},
|
||||
{
|
||||
code: PageCode.Orders,
|
||||
name: 'Ваши чеки',
|
||||
description: '',
|
||||
resName: 'orders',
|
||||
onSideBar: true,
|
||||
},
|
||||
{
|
||||
code: PageCode.UserData,
|
||||
name: 'Заполнить анкету',
|
||||
description: '',
|
||||
resName: 'user-data',
|
||||
onSideBar: true
|
||||
},
|
||||
{
|
||||
code: PageCode.RefSystem,
|
||||
name: 'Пригласить друга',
|
||||
description: '',
|
||||
resName: 'ref-system',
|
||||
onSideBar: true,
|
||||
}
|
||||
];
|
||||
|
||||
export const orderStatuses: OrderStatus = {
|
||||
'Cancelled': 'Отменен',
|
||||
'InProcessing': 'В обработке',
|
||||
'Unconfirmed': 'Принят',
|
||||
'WaitCooking': 'Принят',
|
||||
'ReadyForCooking': 'Принят',
|
||||
'CookingStarted': 'Готовится',
|
||||
'CookingCompleted': 'Приготовлен',
|
||||
'Waiting': 'В пути',
|
||||
'OnWay': 'В пути',
|
||||
'Delivered': 'Выполнен',
|
||||
'Closed': 'Выполнен',
|
||||
'Cancelled': 'Отменен',
|
||||
'InProcessing': 'В обработке',
|
||||
'Unconfirmed': 'Принят',
|
||||
'WaitCooking': 'Принят',
|
||||
'ReadyForCooking': 'Принят',
|
||||
'CookingStarted': 'Готовится',
|
||||
'CookingCompleted': 'Приготовлен',
|
||||
'Waiting': 'В пути',
|
||||
'OnWay': 'В пути',
|
||||
'Delivered': 'Выполнен',
|
||||
'Closed': 'Выполнен',
|
||||
};
|
||||
|
||||
export const lvlPeriods: lvlPeriod[] = [
|
||||
{
|
||||
percent: 3,
|
||||
start: 0,
|
||||
end: 1600,
|
||||
color: '#f2c94c'
|
||||
},
|
||||
{
|
||||
percent: 6,
|
||||
start: 1601,
|
||||
end: 3600,
|
||||
color: '#f2994a'
|
||||
},
|
||||
{
|
||||
percent: 10,
|
||||
start: 3601,
|
||||
end: 8600,
|
||||
color: '#6fcf97'
|
||||
},
|
||||
{
|
||||
percent: 15,
|
||||
start: 8601,
|
||||
color: '#6fcf97'
|
||||
},
|
||||
]
|
||||
{
|
||||
percent: 3,
|
||||
start: 0,
|
||||
end: 1600,
|
||||
color: '#f2c94c'
|
||||
},
|
||||
{
|
||||
percent: 6,
|
||||
start: 1601,
|
||||
end: 3600,
|
||||
color: '#f2994a'
|
||||
},
|
||||
{
|
||||
percent: 10,
|
||||
start: 3601,
|
||||
end: 8600,
|
||||
color: '#6fcf97'
|
||||
},
|
||||
{
|
||||
percent: 15,
|
||||
start: 8601,
|
||||
color: '#6fcf97'
|
||||
},
|
||||
]
|
||||
|
||||
@ -6,7 +6,7 @@ export enum PageCode {
|
||||
UserData,
|
||||
}
|
||||
|
||||
export interface Moment extends moment.Moment {}
|
||||
export interface Moment extends moment.Moment { }
|
||||
|
||||
export interface Page {
|
||||
code: PageCode;
|
||||
@ -74,10 +74,10 @@ export interface OrderStatus {
|
||||
}
|
||||
|
||||
export interface lvlPeriod {
|
||||
percent: number;
|
||||
start: number;
|
||||
end?: number;
|
||||
color: string;
|
||||
percent: number;
|
||||
start: number;
|
||||
end?: number;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface DeliveryType {
|
||||
@ -179,3 +179,32 @@ export interface UserData {
|
||||
city: string;
|
||||
phone: string | null;
|
||||
}
|
||||
|
||||
export interface UserInfoCategory {
|
||||
id: string;
|
||||
isActive: boolean;
|
||||
isDefaultForNewGuests: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface UserInfoWallet {
|
||||
id: string;
|
||||
name: string;
|
||||
programType: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface UserInfoWalletBalance {
|
||||
balance: number;
|
||||
wallet: UserInfoWallet;
|
||||
}
|
||||
|
||||
export interface UserInfo {
|
||||
OrdersSum: number;
|
||||
categories: UserInfoCategory[];
|
||||
customer_level: number;
|
||||
id: string;
|
||||
name: string | null;
|
||||
phone: string;
|
||||
walletBalances: UserInfoWalletBalance[];
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { IndexComponent } from './components/index/index.component';
|
||||
import { GuestCardComponent } from './pages/guest-card/guest-card.component';
|
||||
import { AuthGuard } from 'src/app/guards/auth-guard.guard';
|
||||
import { LoginComponent } from './pages/login/login.component';
|
||||
|
||||
@ -1,63 +1,55 @@
|
||||
<app-navbar title="Карта гостя" [backEvent]="showBack ? logout : undefined"></app-navbar>
|
||||
<p-toast position="top-center"></p-toast>
|
||||
<ng-container *ngIf="!this.loyaltyProgram.purchaseData.$loading && customerInfo">
|
||||
<ng-container *ngIf="!authService.loading && authService.userInfo">
|
||||
<div class="guest-card">
|
||||
<div class="top-info">
|
||||
<div class="top-info__level">
|
||||
<p id="level">Уровень {{ loyaltyProgram.currentLvl }}</p>
|
||||
<p id="level-percent">Кэшбек {{ loyaltyProgram.currentLvlPeriod.percent }}%</p>
|
||||
<p id="level">Уровень {{ authService.userInfo.customer_level }}</p>
|
||||
<p id="level-percent">Кэшбек {{ authService.currentLvlPeriod.percent }}%</p>
|
||||
</div>
|
||||
<p class="top-info__bonus">
|
||||
{{ Math.floor(loyaltyProgram.getBalanceAmount(customerInfo?.walletBalances)) }}
|
||||
{{ Math.floor(authService.getBalanceAmount(authService.userInfo.walletBalances)) }}
|
||||
бонусов
|
||||
</p>
|
||||
</div>
|
||||
<div class="guest-card__qr" (click)="qrCodeClick()">
|
||||
<ng-container *ngIf="customerInfo">
|
||||
<qr-code
|
||||
[value]="customerInfo?.phone?.substr(1) || 'Данные не найдены'"
|
||||
[margin]="0"
|
||||
[size]="qrCodeSize"
|
||||
errorCorrectionLevel="H"
|
||||
></qr-code>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!customerInfo">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
<div class="guest-card__qr" (click)="qrCodeClick()">
|
||||
<qr-code
|
||||
[value]="authService.userInfo?.phone?.substr(1) || 'Данные не найдены'"
|
||||
[margin]="0"
|
||||
[size]="qrCodeSize"
|
||||
errorCorrectionLevel="H"
|
||||
></qr-code>
|
||||
</div>
|
||||
<div class="guest-card__user-description">
|
||||
<p>
|
||||
<ng-container *ngIf="loyaltyProgram.currentLvlPeriod.end">
|
||||
<ng-container *ngIf="authService.currentLvlPeriod.end">
|
||||
Осталось купить на сумму
|
||||
<span class="price">{{
|
||||
loyaltyProgram.currentLvlPeriod.end -
|
||||
(customerInfo.OrdersSum) +
|
||||
authService.currentLvlPeriod.end -
|
||||
(authService.userInfo.OrdersSum) +
|
||||
1
|
||||
}}</span>
|
||||
рублей, тогда кэшбек будет
|
||||
<span class="percent"
|
||||
>{{ loyaltyProgram.getNextLevel().percent }}%</span
|
||||
>{{ authService.getNextLevel().percent }}%</span
|
||||
>
|
||||
с
|
||||
{{
|
||||
loyaltyProgram.purchaseData.currentPeriod[1]
|
||||
authService.purchaseData.currentPeriod[1]
|
||||
.locale("ru")
|
||||
.format("D MMMM")
|
||||
}}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!loyaltyProgram.currentLvlPeriod.end">
|
||||
<ng-container *ngIf="!authService.currentLvlPeriod.end">
|
||||
У Вас последний уровень бонусной программы. Процент начисляемых
|
||||
бонусов:
|
||||
{{ loyaltyProgram.currentLvlPeriod.percent }}%
|
||||
{{ authService.currentLvlPeriod.percent }}%
|
||||
</ng-container>
|
||||
</p>
|
||||
</div>
|
||||
<span id="bonuses-condition"></span>
|
||||
<app-last-order
|
||||
[lastOrder]="loyaltyProgram.purchaseData.lastPurchase"
|
||||
[loading]="loyaltyProgram.purchaseData.$loading"
|
||||
[lastOrder]="authService.purchaseData.lastPurchase"
|
||||
[loading]="authService.loading"
|
||||
></app-last-order>
|
||||
<a class="guest-card__loyalty-program" routerLink="loyality-program"
|
||||
>Подробнее о правилах <br />
|
||||
@ -66,12 +58,12 @@
|
||||
</div>
|
||||
<app-footer></app-footer>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!customerInfo && !loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container *ngIf="!authService.loading && !authService.userInfo">
|
||||
<div class="not-found">
|
||||
<p>Данные недоступны, попробуйте позже</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="loyaltyProgram.purchaseData.$loading">
|
||||
<ng-container *ngIf="authService.loading">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="spinner; context: { $implicit: 85 }"
|
||||
></ng-container>
|
||||
|
||||
@ -6,10 +6,10 @@ import { ExitComponent } from 'src/app/components/exit/exit.component';
|
||||
import { CookiesService } from 'src/app/services/cookies.service';
|
||||
import { WpJsonService } from 'src/app/services/wp-json.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { LoyaltyProgramService } from 'src/app/services/loyalty-program.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { MessagingService } from 'src/app/services/messaging.service';
|
||||
import { DeviceType, getTypeDevice } from 'src/app/utils';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-guest-card',
|
||||
@ -19,7 +19,6 @@ import { DeviceType, getTypeDevice } from 'src/app/utils';
|
||||
export class GuestCardComponent implements OnInit {
|
||||
public qrCodeSize: number = 85;
|
||||
private isQrCodeClicked: boolean = false;
|
||||
public customerInfo!: any;
|
||||
public Math: Math = Math;
|
||||
public showBack: boolean = false;
|
||||
|
||||
@ -27,39 +26,16 @@ export class GuestCardComponent implements OnInit {
|
||||
private _bottomSheet: MatBottomSheet,
|
||||
public cookiesService: CookiesService,
|
||||
private router: Router,
|
||||
private wpJsonService: WpJsonService,
|
||||
public loyaltyProgram: LoyaltyProgramService,
|
||||
private wpJsonService: WpJsonService,
|
||||
private messagingService: MessagingService,
|
||||
private messageService: MessageService,
|
||||
public authService: AuthService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.showBack = getTypeDevice() === DeviceType.android;
|
||||
const token = this.cookiesService.getItem('token');
|
||||
|
||||
|
||||
this.requestPermission();
|
||||
|
||||
this.loyaltyProgram.purchaseData.$loading = true;
|
||||
this.wpJsonService
|
||||
.getCustomerInfo(
|
||||
environment.systemId,
|
||||
token || '',
|
||||
environment.icardProxy
|
||||
)
|
||||
.subscribe({
|
||||
next: (value) => {
|
||||
this.customerInfo = value.customer_info;
|
||||
|
||||
this.cookiesService.setCookie('phone-number', this.customerInfo?.phone?.substr(2))
|
||||
this.loyaltyProgram.setCurrentLvl(this.customerInfo.OrdersSum);
|
||||
|
||||
this.loyaltyProgram.getLastPurchase(
|
||||
environment.systemId,
|
||||
token || '',
|
||||
this.customerInfo.id
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
requestPermission() {
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
Используя приложение, вы принимаете <a href="https://docs.google.com/document/d/1tOZyI9DKerQpMY_N-hMExMB15j2F98E3VDqwIVMkk4I">условия</a>
|
||||
и соглашаетесь на получение рекламно-информационных сообщений
|
||||
</p>
|
||||
<button [disabled]="phoneForm.invalid">Принять участие</button>
|
||||
<button [disabled]="phoneForm.invalid && phoneForm.touched">Принять участие</button>
|
||||
</form>
|
||||
|
||||
<ng-template #smsCode>
|
||||
|
||||
@ -1,25 +1,20 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { CookiesService } from 'src/app/services/cookies.service';
|
||||
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.scss'],
|
||||
})
|
||||
export class LoginComponent implements OnInit, AfterViewInit {
|
||||
export class LoginComponent implements OnInit {
|
||||
public isShowNumber: boolean = true;
|
||||
public phoneForm = new FormGroup({
|
||||
name: new FormControl('', []),
|
||||
@ -35,19 +30,12 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
timeLeft: number = 0;
|
||||
|
||||
constructor(
|
||||
private cookiesService: CookiesService,
|
||||
private authService: AuthService,
|
||||
private router: Router,
|
||||
private jsonrpc: JsonrpcService,
|
||||
private messageService: MessageService,
|
||||
private _snackBar: MatSnackBar,
|
||||
private jsonRpcService: JsonrpcService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
}
|
||||
|
||||
@ViewChild('field', { static: false }) field!: ElementRef;
|
||||
@ViewChild('field1', { static: false }) field1!: ElementRef;
|
||||
@ViewChild('field2', { static: false }) field2!: ElementRef;
|
||||
@ -112,47 +100,14 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
submitNumber() {
|
||||
const data = this.phoneForm.value;
|
||||
this.isShowNumber = false;
|
||||
if (this.timeLeft) {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: `Отправить повторно можно через ${this.timeLeft}с`,
|
||||
});
|
||||
if (this.phoneForm.invalid) {
|
||||
this.phoneForm.markAsTouched();
|
||||
|
||||
return;
|
||||
}
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'sendVerifyByPhone',
|
||||
params: [data.phone],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code !== 0) {
|
||||
this._snackBar.open('Произошла ошибка! Попробуйте позже', '', {
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
if (result.code === 0) {
|
||||
this.timeLeft = 60;
|
||||
const interval = setInterval(() => {
|
||||
if (this.timeLeft > 0) {
|
||||
this.timeLeft--;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
this.isShowNumber = false;
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error: ', error);
|
||||
},
|
||||
});
|
||||
const data = this.phoneForm.value;
|
||||
this.authService.sendVerifyByPhone(data.phone!);
|
||||
this.isShowNumber = false;
|
||||
setTimeout(() => {
|
||||
this.field.nativeElement.focus();
|
||||
}, 0);
|
||||
@ -160,56 +115,10 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||
|
||||
submitCode() {
|
||||
const data = this.codeForm.value;
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getTokenByPhone',
|
||||
params: [this.phoneForm.value.phone, Object.values(data).join('')],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code === 0) {
|
||||
this.cookiesService.setCookie('token', result?.data?.token);
|
||||
this.jsonRpcService.rpc(
|
||||
{
|
||||
method: 'updateAdditionalInfo',
|
||||
params: [
|
||||
{
|
||||
first_name: this.phoneForm.value.name,
|
||||
birth_day: '01.01.1999'
|
||||
},
|
||||
],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
).subscribe({
|
||||
next: (value) => {
|
||||
this.router.navigate(['/'], {
|
||||
queryParams: {
|
||||
token: result?.data?.token,
|
||||
},
|
||||
});
|
||||
},
|
||||
error: (err) => {
|
||||
console.error(err);
|
||||
const phoneData = this.phoneForm.value;
|
||||
|
||||
}
|
||||
})
|
||||
// this.phoneConfirmed.emit(null);
|
||||
} else if (result.code === 230) {
|
||||
this._snackBar.open('Неверный код!', '', {
|
||||
duration: 3000,
|
||||
});
|
||||
// this.errorConfirmCode = true;
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
},
|
||||
});
|
||||
this.authService.submitCode(
|
||||
Object.values(data).join(''), phoneData.phone!, phoneData.name!);
|
||||
}
|
||||
|
||||
backToPhoneForm = () => {
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
<app-navbar title="Программа лояльности" [backEvent]="goBack"></app-navbar>
|
||||
|
||||
<ng-container *ngIf="loyaltyProgram.currentLvlPeriod">
|
||||
<ng-container *ngIf="authService.currentLvlPeriod">
|
||||
<div class="loyality-program">
|
||||
<app-accordion header="Условия начисления бонусов">
|
||||
<p>
|
||||
Ваш текущий уровень {{ loyaltyProgram.currentLvl }},
|
||||
поэтому вам начисляется {{ loyaltyProgram.currentLvlPeriod.percent }}% от суммы покупки.
|
||||
Ваш текущий уровень {{ authService.userInfo?.customer_level }},
|
||||
поэтому вам начисляется {{ authService.currentLvlPeriod.percent }}% от суммы покупки.
|
||||
</p>
|
||||
<p>
|
||||
Смена уровня произойдет в начале следующего квартала,
|
||||
{{ loyaltyProgram.purchaseData.currentPeriod[1]
|
||||
{{ authService.purchaseData.currentPeriod[1]
|
||||
.locale("ru")
|
||||
.format("DD.MM.YY") }}.
|
||||
</p>
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { lvlPeriod } from 'src/app/interface/data';
|
||||
import { lvlPeriods } from 'src/app/app.constants';
|
||||
import { LoyaltyProgramService } from 'src/app/services/loyalty-program.service';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'loyality-program',
|
||||
templateUrl: './loyality-program.component.html',
|
||||
styleUrls: ['./loyality-program.component.scss'],
|
||||
})
|
||||
export class LoyalityProgramComponent implements OnInit {
|
||||
export class LoyalityProgramComponent {
|
||||
constructor(
|
||||
private _location: Location,
|
||||
public loyaltyProgram: LoyaltyProgramService,
|
||||
public authService: AuthService,
|
||||
) { }
|
||||
|
||||
public lvlPeriods: lvlPeriod[] = lvlPeriods;
|
||||
@ -20,10 +20,4 @@ export class LoyalityProgramComponent implements OnInit {
|
||||
goBack = () => {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.loyaltyProgram.currentLvlPeriod == null) {
|
||||
this._location.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
258
angular/src/app/services/auth.service.ts
Normal file
258
angular/src/app/services/auth.service.ts
Normal file
@ -0,0 +1,258 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CookiesService } from './cookies.service';
|
||||
import { WpJsonService } from './wp-json.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { JsonrpcService, RpcService } from './jsonrpc.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { UserInfo, Purchase, lvlPeriod, UserInfoWalletBalance } from '../interface/data';
|
||||
import { lvlPeriods } from 'src/app/app.constants';
|
||||
import moment, { Moment } from 'moment-timezone';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
export interface IPurchaseData {
|
||||
currentPeriod: Moment[];
|
||||
lastPeriod: Moment[];
|
||||
currentAmount?: number;
|
||||
lastPurchase?: Purchase;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AuthService {
|
||||
public purchaseData: IPurchaseData = {
|
||||
currentPeriod: [],
|
||||
lastPeriod: [],
|
||||
lastPurchase: undefined,
|
||||
};
|
||||
userInfo?: UserInfo;
|
||||
loading: boolean = false;
|
||||
error: any;
|
||||
timeLeft: number = 0;
|
||||
|
||||
get currentLvlPeriod(): lvlPeriod {
|
||||
return lvlPeriods[this.userInfo ? this.userInfo.customer_level - 1 : 0];
|
||||
}
|
||||
|
||||
constructor(
|
||||
private cookiesService: CookiesService,
|
||||
private wpJsonService: WpJsonService,
|
||||
private jsonrpc: JsonrpcService,
|
||||
private messageService: MessageService,
|
||||
private router: Router,
|
||||
) {
|
||||
this.getCurrentQuarterOfYear();
|
||||
}
|
||||
|
||||
get token(): string | undefined {
|
||||
return this.cookiesService.getItem('token');
|
||||
}
|
||||
|
||||
get authorized(): boolean {
|
||||
return !!this.token;
|
||||
}
|
||||
|
||||
getUserInfo() {
|
||||
const token = this.cookiesService.getItem('token');
|
||||
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
this.wpJsonService
|
||||
.getCustomerInfo(
|
||||
environment.systemId,
|
||||
token,
|
||||
environment.icardProxy,
|
||||
)
|
||||
.subscribe({
|
||||
next: (value) => {
|
||||
if (value && value.customer_info && value.customer_info.errorCode === 'Customer_CustomerNotFound') {
|
||||
this.wpJsonService.newCustomer(
|
||||
environment.systemId,
|
||||
token,
|
||||
environment.icardProxy,
|
||||
)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.getUserInfo();
|
||||
}
|
||||
})
|
||||
} else if (value && value.error && value.error.code > 1) {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Произошла ошибка! Попробуйте позже',
|
||||
});
|
||||
} else if (value && value.customer_info) {
|
||||
this.userInfo = value.customer_info;
|
||||
|
||||
this.cookiesService.setCookie('phone-number', this.userInfo!.phone?.slice(2));
|
||||
}
|
||||
},
|
||||
error: (e) => {
|
||||
this.error = e;
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
sendVerifyByPhone(phone: string) {
|
||||
if (this.timeLeft) {
|
||||
this.messageService.add({
|
||||
severity: 'custom',
|
||||
summary: `Отправить повторно можно через ${this.timeLeft}с`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'sendVerifyByPhone',
|
||||
params: [phone],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code !== 0) {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Произошла ошибка! Попробуйте позже',
|
||||
});
|
||||
}
|
||||
if (result.code === 0) {
|
||||
this.timeLeft = 60;
|
||||
const interval = setInterval(() => {
|
||||
if (this.timeLeft > 0) {
|
||||
this.timeLeft--;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error: ', error);
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
submitCode(code: string, phone: string, name: string) {
|
||||
this.loading = true;
|
||||
this.jsonrpc
|
||||
.rpc(
|
||||
{
|
||||
method: 'getTokenByPhone',
|
||||
params: [phone, code],
|
||||
},
|
||||
RpcService.authService,
|
||||
false
|
||||
)
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
if (result.code === 0) {
|
||||
this.cookiesService.setCookie('token', result?.data?.token);
|
||||
this.jsonrpc.rpc(
|
||||
{
|
||||
method: 'updateAdditionalInfo',
|
||||
params: [
|
||||
{
|
||||
first_name: name,
|
||||
birth_day: '01.01.1999'
|
||||
},
|
||||
],
|
||||
},
|
||||
RpcService.authService,
|
||||
true
|
||||
).subscribe({
|
||||
next: (value) => {
|
||||
this.router.navigate(['/']);
|
||||
this.getUserInfo();
|
||||
},
|
||||
error: (err) => {
|
||||
console.error(err);
|
||||
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
}
|
||||
})
|
||||
} else if (result.code === 230) {
|
||||
this.messageService.add({
|
||||
severity: 'error',
|
||||
summary: 'Неверный код!',
|
||||
});
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentQuarterOfYear() {
|
||||
const quarters = [
|
||||
[
|
||||
moment().subtract(1, 'years').endOf('year').subtract(3, 'months'),
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
moment().startOf('year').add(6, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(6, 'months'),
|
||||
moment().startOf('year').add(9, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(9, 'months'),
|
||||
moment().startOf('year').add(12, 'months'),
|
||||
],
|
||||
];
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (moment().isBetween(quarters[i][0], quarters[i][1])) {
|
||||
this.purchaseData.lastPeriod = quarters[i - 1];
|
||||
this.purchaseData.currentPeriod = quarters[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getNextLevel(): lvlPeriod {
|
||||
if (this.userInfo?.customer_level === lvlPeriods.length) {
|
||||
return lvlPeriods[lvlPeriods.length - 1];
|
||||
}
|
||||
return this.userInfo && lvlPeriods[this.userInfo?.customer_level] || lvlPeriods[0];
|
||||
}
|
||||
|
||||
getLastPurchase(userInfo: UserInfo) {
|
||||
this.wpJsonService.getLastPurchase(environment.systemId, this.token!).subscribe({
|
||||
next: (res) => {
|
||||
this.purchaseData.lastPurchase = res[userInfo.id][0];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getBalanceAmount(loyaltyPrograms: UserInfoWalletBalance[]) {
|
||||
return (loyaltyPrograms || []).reduce((accumulator, currentValue) => {
|
||||
if (currentValue.wallet.name !== 'Федеральная программа лояльности') {
|
||||
return accumulator
|
||||
}
|
||||
return accumulator + currentValue.balance;
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
@ -1,107 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import moment from 'moment';
|
||||
import { Moment, Purchase, lvlPeriod } from '../interface/data';
|
||||
import { lvlPeriods } from '../app.constants';
|
||||
import { WpJsonService } from './wp-json.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface IPurchaseData {
|
||||
currentPeriod: Moment[];
|
||||
lastPeriod: Moment[];
|
||||
currentAmount?: number;
|
||||
$loading: boolean;
|
||||
lastPurchase?: Purchase;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LoyaltyProgramService {
|
||||
public purchaseData: IPurchaseData = {
|
||||
currentPeriod: [],
|
||||
lastPeriod: [],
|
||||
$loading: false,
|
||||
lastPurchase: undefined,
|
||||
};
|
||||
|
||||
public currentLvl: number = 1;
|
||||
public currentLvlPeriod!: lvlPeriod;
|
||||
public lvlPeriods: lvlPeriod[] = lvlPeriods;
|
||||
|
||||
constructor(
|
||||
private wpJsonService: WpJsonService,
|
||||
) {
|
||||
this.getCurrentQuarterOfYear();
|
||||
}
|
||||
|
||||
getCurrentQuarterOfYear() {
|
||||
const quarters = [
|
||||
[
|
||||
moment().subtract(1, 'years').endOf('year').subtract(3, 'months'),
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(10, 'days'),
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(3, 'months'),
|
||||
moment().startOf('year').add(6, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(6, 'months'),
|
||||
moment().startOf('year').add(9, 'months'),
|
||||
],
|
||||
[
|
||||
moment().startOf('year').add(9, 'months'),
|
||||
moment().startOf('year').add(12, 'months'),
|
||||
],
|
||||
];
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (moment().isBetween(quarters[i][0], quarters[i][1])) {
|
||||
this.purchaseData.lastPeriod = quarters[i - 1];
|
||||
this.purchaseData.currentPeriod = quarters[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getBalanceAmount(loyaltyPrograms: any[]) {
|
||||
return (loyaltyPrograms || []).reduce((accumulator, currentValue) => {
|
||||
if (currentValue.wallet.name !== 'Федеральная программа лояльности') {
|
||||
return accumulator
|
||||
}
|
||||
return accumulator + currentValue.balance;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
setCurrentLvl(currentAmount: number) {
|
||||
const index = this.lvlPeriods.findIndex(
|
||||
(item) =>
|
||||
item.start <= currentAmount && currentAmount <= (item.end || Infinity)
|
||||
)!;
|
||||
if (index != -1) {
|
||||
this.currentLvlPeriod = this.lvlPeriods[index];
|
||||
this.currentLvl = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
getNextLevel(): lvlPeriod {
|
||||
if(this.currentLvl == this.lvlPeriods.length) {
|
||||
return lvlPeriods[this.currentLvl - 1];
|
||||
}
|
||||
return lvlPeriods[this.currentLvl];
|
||||
}
|
||||
|
||||
getLastPurchase(systemId: string, token: string, customerId: string) {
|
||||
this.purchaseData.$loading = true;
|
||||
this.wpJsonService.getLastPurchase(systemId, token).subscribe({
|
||||
next: (res) => {
|
||||
this.purchaseData.lastPurchase = res[customerId][0];
|
||||
},
|
||||
complete: () => {
|
||||
this.purchaseData.$loading = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,7 @@ import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||
import { CookiesService } from "./cookies.service";
|
||||
import { Observable, of, switchMap } from "rxjs";
|
||||
import { JsonRpcBody } from "./jsonrpc.service";
|
||||
import { DeliveryType, AcceptedOrder, Product, Purchase } from "../interface/data";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { DeliveryType, AcceptedOrder, Product } from "../interface/data";
|
||||
|
||||
export enum Method {
|
||||
|
||||
@ -22,7 +21,6 @@ export class WpJsonService {
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private cookiesService: CookiesService,
|
||||
private route: ActivatedRoute,
|
||||
) { }
|
||||
|
||||
getDeliveryTypes(): Observable<DeliveryType[]> {
|
||||
@ -42,18 +40,7 @@ export class WpJsonService {
|
||||
}
|
||||
|
||||
getCustomerInfo(systemId: string, token: string, url: string): Observable<any> {
|
||||
return this._request(`customer_info/${systemId}/${token}/`, 'GET', null, false, url).pipe(
|
||||
switchMap((response) => {
|
||||
// TODO: typescript compile optional chaining ('response?.customer_info?.errorCode') without check ('response.customer_info.errorCode')
|
||||
if (response && response.customer_info && response.customer_info.errorCode !== 'Customer_CustomerNotFound') {
|
||||
return of(response)
|
||||
} else {
|
||||
return this.newCustomer(systemId, token, url).pipe(
|
||||
switchMap(() => this.getCustomerInfo(systemId, token, url))
|
||||
)
|
||||
}
|
||||
})
|
||||
)
|
||||
return this._request(`customer_info/${systemId}/${token}/`, 'GET', null, false, url);
|
||||
}
|
||||
|
||||
getLastPurchase(systemId: string, token: string): Observable<any> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user