[feat] - add authen and display transaction data

This commit is contained in:
2023-11-02 18:56:12 +07:00
parent 21af45bfa6
commit 0c5cf749bb
19 changed files with 355 additions and 34 deletions

View File

@@ -14,6 +14,8 @@ export interface MENU {
isChecked?: boolean;
}
export const ROLE_ADMIN = 'admin'
export const NOT_ADMIN = 'not-admin'
export const MENU: MENU[] = [
{
name: 'Manage',
@@ -21,6 +23,7 @@ export const MENU: MENU[] = [
permission: 'manage',
icon: 'bi bi-card-checklist',
params: [],
roles: [ROLE_ADMIN],
badge: '',
type: 'collapsable',
children: [
@@ -32,6 +35,7 @@ export const MENU: MENU[] = [
icon: '',
params: [],
badge: '',
roles: [ROLE_ADMIN],
},
]
},
@@ -41,6 +45,7 @@ export const MENU: MENU[] = [
permission: 'report',
icon: 'bi bi-file-bar-graph',
params: [],
roles:[ROLE_ADMIN,NOT_ADMIN],
badge: '',
type: 'collapsable',
children: [
@@ -50,8 +55,9 @@ export const MENU: MENU[] = [
permission: 'transactions',
type: 'link',
icon: '',
params: [],
params: [ROLE_ADMIN,NOT_ADMIN],
badge: '',
roles: [],
},
]
},
@@ -61,6 +67,7 @@ export const MENU: MENU[] = [
permission: 'setting',
icon: 'bi bi-gear-fill',
params: [],
roles: [ROLE_ADMIN],
badge: '',
type: 'collapsable',
children: [
@@ -68,6 +75,7 @@ export const MENU: MENU[] = [
name: 'Banner',
link: 'setting/banner',
permission: 'banner',
roles: [ROLE_ADMIN],
type: 'link',
icon: '',
params: [],
@@ -76,6 +84,7 @@ export const MENU: MENU[] = [
{
name: 'Promotion',
link: 'setting/promotion',
roles: [ROLE_ADMIN],
permission: 'promotion',
type: 'link',
icon: '',

View File

@@ -7,7 +7,12 @@ import {catchError, Observable, throwError} from 'rxjs';
@Injectable()
export class AppRequestInterceptor implements HttpInterceptor {
constructor(private router: Router,private appService: AppService) {}
constructor(
private router: Router,
private appService: AppService
) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.appService.token();

View File

@@ -9,14 +9,14 @@
<form #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<div class="auth-card-body">
<mat-form-field>
<input matInput type="text" name="loginname" [(ngModel)]="dataForm.loginname" #loginname="ngModel"
<input matInput type="text" name="loginname" [(ngModel)]="cathayForm.userName" #loginname="ngModel"
placeholder="Username" required>
<i matSuffix class="bi bi-person-circle"></i>
<mat-error *ngIf="isFieldValid(ngf, loginname)">กรุณากรอกข้อมูล</mat-error>
</mat-form-field>
<div style="height: 10px;"></div>
<mat-form-field>
<input matInput type="password" name="password" [(ngModel)]="dataForm.password"
<input matInput type="password" name="password" [(ngModel)]="cathayForm.password"
#password="ngModel" placeholder="Password" required>
<i matSuffix class="bi bi-key"></i>
<mat-error *ngIf="isFieldValid(ngf, password)">กรุณากรอกข้อมูล</mat-error>

View File

@@ -6,6 +6,7 @@ import { AuthService } from 'src/app/core/service/auth/auth.service';
import { lastValueFrom } from 'rxjs';
import { EAction, EText } from 'src/app/@config/app';
import { CathayAuthService } from 'src/app/core/service/auth/cathay-auth.service';
import { ROLE_ADMIN } from 'src/app/@config/menus';
@Component({
@@ -32,21 +33,25 @@ export class LoginComponent implements OnInit {
ngOnInit() {
if (!environment.production) {
this.dataForm = {
username: 'admin',
password: 'admin',
}
}
// if (!environment.production) {
// this.dataForm = {
// username: 'admin',
// password: 'admin',
// }
// }
}
async onSubmit(form: any) {
if (!form.valid) return false;
try {
const result = await lastValueFrom(this.authService.login(this.dataForm));
const cathayResult: any = await lastValueFrom(this.cathayAuthService.login(this.cathayForm));
// const result = await lastValueFrom(this.authService.login(this.dataForm));
let cathayResult: any = await lastValueFrom(this.cathayAuthService.login(this.cathayForm));
cathayResult = {
...cathayResult,
isAdmin: cathayResult.token.userName == ROLE_ADMIN ? true : false
}
this.appService.setToken(cathayResult.token.token)
this.appService.setAuth(result);
this.appService.setAuth(cathayResult);
return this.router.navigate(['/pages']);
} catch (err) {
return this.appService.message(EAction.ERROR, EText.NO_DATA);

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { TransactionService } from './transaction.service';
describe('TransactionService', () => {
let service: TransactionService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(TransactionService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,18 @@
import { BaseList } from './../../base/base-list';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BaseService } from 'src/app/core/base/base-service';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class TransactionService extends BaseService {
constructor(
public http: HttpClient
) {
super('', http)
this.fullUrl = `${environment.CATHAYAPIURL}/v2/Payment/getTransaction`
}
}

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { UserCathayService } from './user-cathay.service';
describe('UserCathayService', () => {
let service: UserCathayService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserCathayService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,21 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { BaseService } from '../../base/base-service';
@Injectable({
providedIn: 'root'
})
export class UserCathayService extends BaseService {
constructor(
public http: HttpClient
) {
super('', http)
this.fullUrl = `${environment.CATHAYAPIURL}/v1/user`
}
getUserCathay(payerUid: string){
return super.get(payerUid)
}
}

View File

@@ -16,8 +16,8 @@
<nav class="main-menu-nav">
<ng-template #menuTemplate let-menus>
<div *ngFor="let item of menus; let i = index">
<ng-container *ngIf="roleCheck(item.permission)">
<ng-container [ngSwitch]="item.type">
<ng-container *ngIf="roleCheck(item?.permission)">
<ng-container [ngSwitch]="item?.type">
<ng-container *ngSwitchCase="'heading'">
<div class="menu-heading">{{ item.name }}</div>
</ng-container>

View File

@@ -1,7 +1,7 @@
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppService } from '../../app.service';
import { MENU } from "../../@config/menus";
import { MENU, NOT_ADMIN, ROLE_ADMIN } from "../../@config/menus";
@Component({
selector: 'app-pages-layouts',
@@ -35,6 +35,20 @@ export class PagesLayoutsComponent implements OnInit {
}
async initAuth() {
this.auth = this.app.auth();
console.log(this.auth.isAdmin)
this.menus = this.menus.map(r => {
if(this.auth.isAdmin){
if(r.roles.includes(ROLE_ADMIN)) return {
...r,
children: r.children.length ? r.children.filter(c => r.roles.includes(ROLE_ADMIN)) : []
}
} else {
if(r.roles.includes(NOT_ADMIN)) return {
...r,
children: r.children.length ? r.children.filter(c => r.roles.includes(NOT_ADMIN)) : []
}
}
})
if (!this.permissionCheck) {
// const users = await lastValueFrom(this.app.get(`${API.users}/getById/${this.auth.id}`));

View File

@@ -1 +1 @@
<app-list [reportList]="report$ | async"></app-list>
<app-list [reportList]="report$ | async" (onSearch)="onSearchTransaction($event)"></app-list>

View File

@@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { Observable, map } from 'rxjs';
import { ReportService } from 'src/app/core/service/common/report.service';
import { TransactionService } from 'src/app/core/service/transaction/transaction.service';
@Component({
selector: 'app-transactions',
@@ -10,8 +11,34 @@ import { ReportService } from 'src/app/core/service/common/report.service';
export class TransactionsContainer {
report$ = new Observable();
constructor(
private reportService: ReportService
private transactionSV: TransactionService
) {
this.report$ = this.reportService.getAll()
// this.report$ = this.transactionSV.getAll()
}
onSearchTransaction(event) {
let { createDatefrom, createDateto } = event
let req = {
"id": "",
"payeeUserAccountId": "",
"payerUserAccountId": "",
"invoiceId": "",
"referencE1": "",
"referencE2": "",
"referencE3": "",
"paymentStatus": "",
"paymentChannel": "",
"qrId": "",
"createDatefrom": createDatefrom,
"createDateto": createDateto,
"sattleDate": "",
"voidDate": "",
"refundDate": "",
"cancelDate": ""
}
this.report$ = this.transactionSV.add(req).pipe(map( (e: any) => e.data))
}
}

View File

@@ -16,18 +16,23 @@
</div>
<div class="col-span-2 xl:col-span-3 xl:order-2">
<mat-form-field >
<input matInput [matDatepicker]="startDate" placeholder="วันที่ชำระ" (dateChange)="test()" />
<input matInput [matDatepicker]="startDate" placeholder="วันที่ชำระ" [(ngModel)]="request.createDatefrom" required/>
<mat-datepicker-toggle [for]="startDate" matSuffix></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-2 xl:col-span-3 xl:order-2">
<mat-form-field >
<input matInput [matDatepicker]="endDate" placeholder="ถึงวันที่" (dateChange)="test()"/>
<input matInput [matDatepicker]="endDate" placeholder="ถึงวันที่" [(ngModel)]="request.createDateto" required/>
<mat-datepicker-toggle [for]="endDate" matSuffix></mat-datepicker-toggle>
<mat-datepicker #endDate></mat-datepicker>
</mat-form-field>
</div>
<button type="button" class="btn btn-create" (click)="emitSearch()">
<i class="bi bi-plus"></i>
ค้นหา
</button>
</div>
</div>
@@ -36,7 +41,9 @@
<table class="table table-main" mat-table [dataSource]="reportList" matSort>
<tr mat-header-row *matHeaderRowDef="['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']"></tr>
<tr mat-row *matRowDef="let row; columns: ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'];"></tr>
<tr class="mat-row" *matNoDataRow>
<td class="no-data" colspan="100%">ไม่มีข้อมูล</td>
</tr>
<ng-container matColumnDef="1">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>ลำดับ</th>
<td mat-cell *matCellDef="let item; let i = index" width="150" class="tac">{{getIndex(i)}}</td>
@@ -89,7 +96,7 @@
<ng-container matColumnDef="10">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>paymentStatus</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{ item.referencE3 }}</div>
<div class="b-color-green"> {{ item.paymentStatus }}</div>
</td>
</ng-container>
<ng-container matColumnDef="11">
@@ -120,7 +127,7 @@
<th mat-header-cell *matHeaderCellDef width="80">More Detail</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item">
<div class="item" (click)="openDialog(item.payerUserAccountId)">
<i class="bi bi-file-earmark-text icon-doc"></i>
</div>
</div>

View File

@@ -1,17 +1,50 @@
import { Component, Input } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { EAction, EText } from 'src/app/@config/app';
import { AppService } from 'src/app/app.service';
import { BaseList } from 'src/app/core/base/base-list';
import { TransactionDialogComponent } from '../transaction-dialog/transaction-dialog.component';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.scss']
})
export class ListComponent {
export class ListComponent extends BaseList implements OnChanges {
@Input() reportList: any = [];
constructor() {
@Output() onSearch = new EventEmitter()
request = {
createDatefrom: null,
createDateto: null
}
test(){
console.log('test')
constructor(
private appSV: AppService,
private dialog: MatDialog,
) {
super()
}
ngOnChanges(changes: SimpleChanges): void {
if('reportList' in changes){
this.reportList = this.updateMatTable(changes.reportList.currentValue || [])
}
}
emitSearch(){
if(!this.request.createDatefrom){
return this.appSV.message('info', 'โปรดเลือกวันที่ชำระ')
}
if(!this.request.createDateto){
return this.appSV.message('info', 'โปรดเลือกวันที่ถึงวันที่')
}
this.onSearch.emit(this.request)
}
openDialog(payerUserAccountId){
console.log(payerUserAccountId)
this.dialogConfig.data.ids = payerUserAccountId
const dialogRef = this.dialog.open(TransactionDialogComponent,this.dialogConfig);
}
}

View File

@@ -0,0 +1,90 @@
<form class="dialog-main form-dialog" autocomplete="off">
<div class="dialog-main">
<div class="dialog-header flex justify-between">
<h2>More Detail</h2>
<mat-icon mat-dialog-close class="cursor-pointer">clear</mat-icon>
</div>
<div class="dialog-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">User Name: </mat-label>
<span class="col-span-7">
{{ userInformation?.userName || '-'}}
</span>
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">ชื่อเต็ม</mat-label>
<span class="col-span-7">
{{ userInformation?.fullName || '-'}}
</span>
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">อีเมล์</mat-label>
<span class="col-span-7">
{{ userInformation?.email || '-'}}
</span>
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">เบอร์โทรศัพท์</mat-label>
<span class="col-span-7">
{{ userInformation?.phoneNumber || '-'}}
</span>
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">เลขบัตรกดเงินสด</mat-label>
<span class="col-span-7">
{{ userInformation?.personalCardId || '-'}}
</span>
<!-- <mat-form-field class="col-span-7">
<input matInput formControlName="birth_date" [matDatepicker]="birthdate" readonly />
<mat-datepicker-toggle [for]="birthdate" disabled matSuffix></mat-datepicker-toggle>
<mat-datepicker #birthdate></mat-datepicker>
</mat-form-field> -->
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<!-- <mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">วันบัตรหมดอายุ</mat-label>
<mat-form-field class="col-span-7">
<input matInput formControlName="exp_date" [matDatepicker]="expdate" readonly />
<mat-datepicker-toggle [for]="expdate" disabled matSuffix></mat-datepicker-toggle>
<mat-datepicker #expdate></mat-datepicker>
</mat-form-field> -->
<span class="col-span-1"></span>
</div>
</div>
<div class="col-span-full">
<div class="lg:flex lg:flex-col grid grid-cols-9 gap-2">
<!-- <mat-label class="col-span-1 lg:text-left lg:self-auto text-right self-center mr-4">เลขหลังบัตร</mat-label>
<mat-form-field class="col-span-7">
<input matInput required formControlName="code_back_card" readonly type="text">
</mat-form-field> -->
<span class="col-span-1"></span>
</div>
</div>
</div>
</div>
</div>
</form>
<!-- <pre>{{form.getRawValue() | json}}</pre> -->

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TransactionDialogComponent } from './transaction-dialog.component';
describe('TransactionDialogComponent', () => {
let component: TransactionDialogComponent;
let fixture: ComponentFixture<TransactionDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TransactionDialogComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(TransactionDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,35 @@
import { CDialogConfig } from './../../../../../@common/interface/Dialog';
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Router, ActivatedRoute } from '@angular/router';
import { IDialogConfigData } from 'src/app/@common/interface/Dialog';
import { EAction } from 'src/app/@config/app';
import { AppService } from 'src/app/app.service';
import { KycService } from 'src/app/core/service/common/kyc.service';
import { UserCathayService } from 'src/app/core/service/users/user-cathay.service';
@Component({
selector: 'app-transaction-dialog',
templateUrl: './transaction-dialog.component.html',
styleUrls: ['./transaction-dialog.component.scss']
})
export class TransactionDialogComponent {
userInformation
constructor(
public dialogRef: MatDialogRef<TransactionDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
public router: Router,
public activatedRoute: ActivatedRoute,
public fb: FormBuilder,
private userCathaySV: UserCathayService
) {
this.userCathaySV.getUserCathay(this.data.ids)
.subscribe((data: any) => this.userInformation = {...data.data})
}
}

View File

@@ -5,6 +5,7 @@ import { NgModule } from "@angular/core";
import { ListComponent } from "./presenter/list/list.component";
import { TransactionsRouter } from "./router/router";
import { TransactionsContainer } from "./container/transactions/transactions.container";
import { TransactionDialogComponent } from './presenter/transaction-dialog/transaction-dialog.component';
const routes: Routes = [
@@ -24,7 +25,8 @@ const routes: Routes = [
declarations: [
TransactionsRouter,
TransactionsContainer,
ListComponent
ListComponent,
TransactionDialogComponent
],
imports: [
AppSharedModule,