Commit 3a4b2113 authored by 伊藤雄大's avatar 伊藤雄大

2024/10/24

デザインに合わせたプロトタイプ作成
parent 41461481
......@@ -29,6 +29,11 @@
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
},
{
"glob": "**/*.json",
"input": "src/data",
"output": "data"
}
],
"styles": [
......@@ -116,6 +121,11 @@
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
},
{
"glob": "**/*.json",
"input": "src/data",
"output": "data"
}
],
"styles": [
......@@ -150,7 +160,8 @@
"cli": {
"schematicCollections": [
"@ionic/angular-toolkit"
]
],
"analytics": false
},
"schematics": {
"@ionic/angular-toolkit:component": {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -13,56 +13,56 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^18.2.2",
"@angular/common": "^18.2.2",
"@angular/compiler": "^18.2.2",
"@angular/core": "^18.2.2",
"@angular/forms": "^18.2.2",
"@angular/platform-browser": "^18.2.2",
"@angular/platform-browser-dynamic": "^18.2.2",
"@angular/router": "^18.2.2",
"@aws-amplify/ui-angular": "^5.0.19",
"@angular/animations": "^18.2.8",
"@angular/common": "^18.2.8",
"@angular/compiler": "^18.2.8",
"@angular/core": "^18.2.8",
"@angular/forms": "^18.2.8",
"@angular/platform-browser": "^18.2.8",
"@angular/platform-browser-dynamic": "^18.2.8",
"@angular/router": "^18.2.8",
"@aws-amplify/ui-angular": "^5.0.29",
"@capacitor/app": "6.0.1",
"@capacitor/core": "6.1.2",
"@capacitor/haptics": "6.0.1",
"@capacitor/keyboard": "6.0.2",
"@capacitor/status-bar": "6.0.1",
"@ionic/angular": "^8.2.7",
"aws-amplify": "^6.5.3",
"@ionic/angular": "^8.3.3",
"aws-amplify": "^6.6.6",
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"ionicons": "^7.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.7.0",
"zone.js": "~0.15.0"
"ionicons": "^7.4.0",
"rxjs": "~7.8.1",
"tslib": "^2.8.0",
"zone.js": "~0.14.10"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.2.1",
"@angular-eslint/builder": "^18.3.0",
"@angular-eslint/eslint-plugin": "^18.3.0",
"@angular-eslint/eslint-plugin-template": "^18.3.0",
"@angular-eslint/schematics": "^18.3.0",
"@angular-eslint/template-parser": "^18.3.0",
"@angular/cli": "^18.2.1",
"@angular/compiler-cli": "^18.2.2",
"@angular/language-service": "^18.2.2",
"@angular-devkit/build-angular": "^18.2.9",
"@angular-eslint/builder": "^18.4.0",
"@angular-eslint/eslint-plugin": "^18.4.0",
"@angular-eslint/eslint-plugin-template": "^18.4.0",
"@angular-eslint/schematics": "^18.4.0",
"@angular-eslint/template-parser": "^18.4.0",
"@angular/cli": "^18.2.9",
"@angular/compiler-cli": "^18.2.8",
"@angular/language-service": "^18.2.8",
"@capacitor/cli": "6.1.2",
"@ionic/angular-toolkit": "^11.0.1",
"@types/jasmine": "~5.1.0",
"@typescript-eslint/eslint-plugin": "^8.3.0",
"@typescript-eslint/parser": "^8.3.0",
"eslint": "^9.9.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsdoc": "^50.2.2",
"@ionic/angular-toolkit": "^12.1.1",
"@types/jasmine": "~5.1.4",
"@typescript-eslint/eslint-plugin": "^8.11.0",
"@typescript-eslint/parser": "^8.11.0",
"eslint": "^9.13.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsdoc": "^50.4.3",
"eslint-plugin-prefer-arrow": "1.2.3",
"jasmine-core": "~5.2.0",
"jasmine-core": "~5.4.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-coverage": "~2.2.1",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.5.4"
"typescript": "^5.5.4"
},
"description": "An Ionic project"
}
\ No newline at end of file
......@@ -11,18 +11,6 @@ const routes: Routes = [
redirectTo: 'home',
pathMatch: 'full'
},
{
path: 'user-regist',
loadChildren: () => import('./user-regist/user-regist.module').then(m => m.UserRegistPageModule)
},
{
path: 'password-update',
loadChildren: () => import('./password-update/password-update.module').then(m => m.PasswordUpdatePageModule)
},
{
path: 'menu',
loadChildren: () => import('./menu/menu.module').then(m => m.MenuPageModule)
},
{
path: 'card-select',
loadChildren: () => import('./card-select/card-select.module').then(m => m.CardSelectPageModule)
......@@ -39,10 +27,6 @@ const routes: Routes = [
path: 'pass-regist',
loadChildren: () => import('./pass-regist/pass-regist.module').then(m => m.PassRegistPageModule)
},
{
path: 'history',
loadChildren: () => import('./history/history.module').then(m => m.HistoryPageModule)
},
{
path: 'claim-list',
loadChildren: () => import('./claim-list/claim-list.module').then(m => m.ClaimListPageModule)
......
......@@ -7,6 +7,8 @@ import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
imports: [
......@@ -14,7 +16,7 @@ import { AppRoutingModule } from './app-routing.module';
IonicModule.forRoot(),
AppRoutingModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, provideHttpClient(withInterceptorsFromDi())],
bootstrap: [AppComponent]
})
export class AppModule { }
<ion-header [translucent]="true">
<ion-header>
<app-header [mode]="1" (clickClose)="onClickClose()"></app-header>
</ion-header>
......
......@@ -5,23 +5,46 @@
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col style="width:75%;padding-top:8px;padding-left:10px;">
<ion-label>クレジットカード</ion-label>
@switch (creditCardModel?.cardKind) {
@case (0) {
<ion-label>JCB</ion-label>
}
@case (1) {
<ion-label>Visa</ion-label>
}
@case (2) {
<ion-label>MasterCard</ion-label>
}
@case (3) {
<ion-label>AmericanExpress</ion-label>
}
@case (4) {
<ion-label>Diners</ion-label>
}
}
</ion-col>
<ion-col style="padding-top:8px;">
<ion-col style="padding-top:8px;padding-right:10px;">
@if (creditCardModel?.denyStatus == 1 && creditCardModel?.deleteDeny == 0) {
<div id="denyStatus" role="button" class="text-decoration-underline" style="color:red;">
拒否リスト登録</div>
<ion-alert trigger="denyStatus" header="拒否リスト削除しますか?" [buttons]="confirmButtons"
<div [id]="denyStatusId" role="button" class="text-decoration-underline label-orange"
style="text-align:right;">
拒否リスト削除</div>
<ion-alert [trigger]="denyStatusId" header="拒否リスト削除しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickDenyStatus($event)"></ion-alert>
} @else if (creditCardModel?.denyStatus == 1 && creditCardModel?.deleteDeny == 1) {
<div id="deleteDeny" role="button" class="text-decoration-underline" style="color:red;">
拒否リスト削除依頼</div>
<ion-alert trigger="deleteDeny" header="拒否リスト削除依頼を取消しますか?" [buttons]="confirmButtons"
<div [id]="deleteDenyId" role="button" class="text-decoration-underline label-orange"
style="text-align:right;">
依賴取消</div>
<div class="label-gray" style="font-size:12px;text-align:right;">
拒否リスト削除依賴済
</div>
<ion-alert [trigger]="deleteDenyId" header="拒否リスト削除依頼を取消しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickDenyStatus($event)"></ion-alert>
}
</ion-col>
<ion-col size="auto" align="right" style="padding-top:10px;padding-right:10px;">
<ion-icon name="trash-outline"></ion-icon>
<input type="button" [id]="deleteCardId" class="btn btn-outline-dark" value="削除">
<ion-alert [trigger]="deleteCardId" header="クレジットカードを削除しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickTrash($event)"></ion-alert>
</ion-col>
</ion-row>
</ion-grid>
......@@ -29,7 +52,7 @@
</ion-row>
<ion-row>
<ion-col style="padding-left:10px;padding-top:10px;" size="auto">
<div style="width:120px;">カード番号</div>
<div class="label-blue" style="width:120px;">カード番号</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-grid class="ion-no-padding">
......@@ -60,20 +83,12 @@
</ion-grid>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-left:10px;padding-top:10px;" size="auto">
<div style="width:120px;">カード名義人</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{creditCardModel?.cardOwner}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-left:10px;padding-top:10px;padding-bottom:10px;" size="auto">
<div style="width:120px;">有効期限</div>
<div class="label-blue" style="width:120px;">カード名義人</div>
</ion-col>
<ion-col style="padding-top:10px;padding-bottom:10px;">
<ion-label>{{creditCardModel?.cardYear}}年{{creditCardModel?.cardMonth}}月</ion-label>
<ion-label>{{creditCardModel?.cardOwner}}</ion-label>
</ion-col>
</ion-row>
</ion-grid>
......
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CreditCardModel } from 'src/app/model/credit-card.model';
......@@ -14,7 +14,7 @@ import { CreditCardModel } from 'src/app/model/credit-card.model';
IonicModule
]
})
export class CardInfoComponent {
export class CardInfoComponent implements OnInit {
//クレジットカード情報
@Input() creditCardModel?: CreditCardModel;
@Output() clickDenyStatus: EventEmitter<void> = new EventEmitter();
......@@ -31,11 +31,21 @@ export class CardInfoComponent {
},
];
denyStatusId?: string;
deleteDenyId?: string;
deleteCardId?: string;
/**
* コンストラクタ
*/
constructor() { }
ngOnInit(): void {
this.denyStatusId = "denuStatus" + this.creditCardModel?.cardNumber;
this.deleteDenyId = "deleteDeny" + this.creditCardModel?.cardNumber;
this.deleteCardId = "deleteCard" + this.creditCardModel?.cardNumber;
}
/**
* 拒否リスト状態
*/
......@@ -48,7 +58,7 @@ export class CardInfoComponent {
/**
* 削除
*/
onClickTrash(): void {
onClickTrash(event: any): void {
this.clickTrash.emit();
}
}
<ion-header [translucent]="true">
<ion-header>
<app-header [mode]="2" (clickBack)="onClickBack()"></app-header>
</ion-header>
......@@ -11,7 +11,7 @@
</div>
}
</div>
<div role="button" style="margin-top:10px;text-align:center;" class="add-link" (click)="onClickAddCard()">
<span>+&nbsp;クレジットカードを追加する</span>
<div role="button" style="margin-top:20px;text-align:center;" class="label-orange" (click)="onClickAddCard()">
<span>クレジットカードを追加する<ion-icon name="add-circle-outline"></ion-icon></span>
</div>
</ion-content>
\ No newline at end of file
......@@ -35,9 +35,7 @@ export class CardSelectPage implements OnInit {
* 戻る
*/
onClickBack(): void {
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
this.routeService.navigateHome();
}
/**
......
<div class="border rounded">
<ion-card>
<ion-grid>
<ion-row>
<ion-col>
<ion-grid>
<ion-row>
<ion-col style="padding-top:5px;">
<ion-label>{{model.agencyName}}</ion-label>
</ion-col>
<ion-col size="auto">
@if (model.ngFlag == 1) {
<ion-label class="" style="color:red;">前回NG</ion-label>
}
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:5px;" size="auto">
<div style="width:80px;">乗車日時</div>
<ion-label style="font-size:16px;">{{model.agencyName}}</ion-label>
</ion-col>
<ion-col style="padding-top:5px;">
<ion-label>{{model.getonDt | customDatetime}}</ion-label>
</ion-col>
<ion-col size="auto">
<ion-col style="text-align:right;">
@if (model.cancelRequest == 0) {
<div role="button" id="cancelReq" class="text-decoration-underline" (click)="onClickBefCancelReq()">取消依頼
<div role="button" id="cancelReq" class="text-decoration-underline label-orange"
(click)="onClickBefCancelReq()">取消依頼
</div>
<ion-alert [isOpen]="isCancelOpen" header="取消依頼しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickCancelReq($event)"></ion-alert>
} @else {
<div role="button" id="cancelReqDone" class="text-decoration-underline" (click)="onClickBefCancelReq()">
<div role="button" id="cancelReqDone" class="text-decoration-underline label-orange"
(click)="onClickBefCancelReq()">
取消依頼済</div>
<ion-alert [isOpen]="isCancelOpen" header="取消依頼を解除しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickCancelReq($event)"></ion-alert>
......@@ -35,53 +21,111 @@
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:5px;" size="auto">
<div style="width:80px;">降車日時</div>
</ion-col>
<ion-col style="padding-top:5px;">
<ion-label>{{model.getoffDt | customDatetime}}</ion-label>
</ion-col>
<ion-col>
<table width="100%">
<tr>
<td>
<ion-label class="label-blue">請求結果</ion-label>
</td>
<td>
<ion-label>{{model.result}}</ion-label>
</td>
<td style="width:120px;"></td>
</tr>
<tr>
<td>
<ion-label class="label-blue">購入日</ion-label>
</td>
<td>
<ion-label>{{model.earningDate | customDate}}</ion-label>
</td>
<td style="width:120px;"></td>
</tr>
<tr>
@if (model.ngFlag == 1) {
<ion-col size="auto">
<td>
<ion-label class="label-red">カードご利用額</ion-label>
</td>
<td>
<ion-label class="label-red">{{model.amount | number}}円</ion-label>
</td>
<td style="width:120px;">
@if (model.payRequest == 0) {
<div role="button" id="payReq" class="text-decoration-underline" (click)="onClickBefPayReq()">支払要求</div>
<input type="button" id="payReq" class="btn pay-button" (click)="onClickBefPayReq()" value="支払要求">
<ion-alert [isOpen]="isPayOpen" header="支払要求しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickPayReq($event)"></ion-alert>
} @else {
<div role="button" id="payReqDone" class="text-decoration-underline" (click)="onClickBefPayReq()">支払要求済
<input type="button" id="payReqDone" class="btn pay-button" (click)="onClickBefPayReq()" value="支払要求取消">
<div class="label-gray" style="font-size:12px;text-align:right;">
支払要求済
</div>
<ion-alert [isOpen]="isPayOpen" header="支払要求を解除しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickPayReq($event)"></ion-alert>
}
</ion-col>
</td>
} @else {
<td>
<ion-label class="label-blue">カードご利用額</ion-label>
</td>
<td>
<ion-label>{{model.amount | number}}円</ion-label>
</td>
<td style="width:120px;"></td>
}
</ion-row>
<ion-row>
<ion-col style="padding-top:5px;" size="auto">
<div style="width:80px;">処理日時</div>
</ion-col>
<ion-col style="padding-top:5px;">
<ion-label>{{model.processDt | customDatetime}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:5px;" size="auto">
<div style="width:80px;">売上日</div>
</ion-col>
<ion-col style="padding-top:5px;">
<ion-label>{{model.earningDate | customDate}}</ion-label>
</tr>
</table>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:5px;padding-bottom:5px;" size="auto">
<div style="width:80px;">請求金額</div>
</ion-col>
<ion-col style="padding-top:5px;padding-bottom:5px;">
<ion-label>{{model.amount | number}}円</ion-label>
</ion-col>
</ion-row>
</ion-grid>
<ion-col>
<ion-accordion-group>
<ion-accordion value="detail">
<ion-item slot="header" style="text-align:center;">
<ion-label>内訳</ion-label>
</ion-item>
<div class="ion-padding" slot="content">
@for (detail of model.detailList;track detail.getonDt) {
<ion-card>
<table width="100%" style="margin:20px;">
<tr>
<td>
<ion-label>{{detail.routeName}}</ion-label>
</td>
<td>
<ion-label>{{detail.getonStopName}}~{{detail.getoffStopName}}</ion-label>
</td>
</tr>
<tr>
<td>
<ion-label>乗車日時:</ion-label>
</td>
<td>
<ion-label>{{detail.getonDt | customDatetime}}</ion-label>
</td>
</tr>
<tr>
<td>
<ion-label>降車日時:</ion-label>
</td>
<td>
<ion-label>{{detail.getoffDt | customDatetime}}</ion-label>
</td>
</tr>
<tr>
<td>
<ion-label>料  金:</ion-label>
</td>
<td>
<ion-label>{{detail.price|number}}円</ion-label>
</td>
</tr>
</table>
</ion-card>
}
</div>
</ion-accordion>
</ion-accordion-group>
</ion-col>
</ion-row>
</ion-grid>
</div>
\ No newline at end of file
</ion-card>
\ No newline at end of file
.pay-button {
color: #f5404b;
background-color: #fef5f6;
}
.label-red {
color: #f5404b;
}
\ No newline at end of file
<ion-header [translucent]="true">
<ion-header>
<app-header [mode]="2" (clickBack)="onClickBack()"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
@for(model of claimList;track model.agencyId) {
<ion-grid>
<ion-row>
<ion-col style="text-align:center;">
<div (click)="onClickPrev()">
<ion-icon name="chevron-back-outline" size="large" class="label-blue"></ion-icon>
</div>
</ion-col>
<ion-col size="auto">
<ion-datetime-button datetime="datetime"></ion-datetime-button>
<ion-modal [keepContentsMounted]="true">
<ng-template>
<ion-datetime id="datetime" presentation="date"></ion-datetime>
</ng-template>
</ion-modal>
</ion-col>
<ion-col style="text-align:center;">
<div (click)="onClickNext()">
<ion-icon name="chevron-forward-outline" size="large" class="label-blue"></ion-icon>
</div>
</ion-col>
</ion-row>
</ion-grid>
@for(model of claimList;track model.tokenId) {
<div style="margin-top:10px;margin-left:10px;margin-right:10px;">
<app-claim-info [model]="model" (clickPayReq)="onClickPayReq($event)"
(clickCancelReq)="onClickCancelReq($event)"></app-claim-info>
......
......@@ -27,8 +27,6 @@ export class ClaimListPage implements OnInit {
//請求一覧
claimList?: ClaimListModel[];
@ViewChildren(ClaimInfoComponent) claimInfoList?: QueryList<ClaimInfoComponent>;
/**
* コンストラクタ
* @param routeService 画面遷移サービス
......@@ -40,21 +38,17 @@ export class ClaimListPage implements OnInit {
* 初期化
*/
ngOnInit() {
if (this.routeService.customerId) {
//this.claimList = this.claimListService.getList(this.routeService.customerId);
this.claimListService.getList(this.routeService.customerId).subscribe((ret: ClaimListModel[]) => {
this.claimListService.getList("").subscribe((ret: ClaimListModel[]) => {
this.claimList = ret;
});
}
}
/**
* 戻る
*/
onClickBack(): void {
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
this.routeService.navigateHome();
}
/**
......@@ -64,7 +58,7 @@ export class ClaimListPage implements OnInit {
onClickPayReq(model: ClaimListModel): void {
if (this.claimList) {
for (let i = 0; i < this.claimList.length; i++) {
if (this.claimList[i].tokenId === model.tokenId && this.claimList[i].getonDt === model.getonDt) {
if (this.claimList[i].tokenId === model.tokenId && this.claimList[i].earningDate === model.earningDate) {
this.claimList[i].payRequest = this.claimList[i].payRequest === 0 ? 1 : 0;
break;
}
......@@ -79,11 +73,19 @@ export class ClaimListPage implements OnInit {
onClickCancelReq(model: ClaimListModel): void {
if (this.claimList) {
for (let i = 0; i < this.claimList.length; i++) {
if (this.claimList[i].tokenId === model.tokenId && this.claimList[i].getonDt === model.getonDt) {
if (this.claimList[i].tokenId === model.tokenId && this.claimList[i].earningDate === model.earningDate) {
this.claimList[i].cancelRequest = this.claimList[i].cancelRequest === 0 ? 1 : 0;
break;
}
}
}
}
onClickPrev(): void {
}
onClickNext(): void {
}
}
<div class="title-label" [class.right-align]="mode === 1 || mode === 3">
@if (mode === 0) {
<div style="margin-left:10px;padding-top:5px;">タッチ決済サービス</div>
}
<div class="title-label" [class.right-align]="mode === 1">
@if (mode === 2) {
<div style="margin-left:5px;padding-top:5px;" (click)="onClickBack()">
<div style="margin-left:5px;" (click)="onClickBack()">
<table>
<tr>
<td style="padding-top:5px;">
<ion-icon name="chevron-back-outline" size="large"></ion-icon>
</td>
<td>
<span style="font-size:20px;">Back</span>
</td>
</tr>
</table>
</div>
}
@if (mode === 1) {
......@@ -12,16 +18,4 @@
<ion-icon name="close-outline" size="large"></ion-icon>
</div>
}
@if (mode === 3) {
<ion-grid width="100%">
<ion-row>
<ion-col style="padding-top:3px;text-align:right;">
<div (click)="onClickLogout()">ログアウト</div>
</ion-col>
<ion-col style="padding-top:5px;padding-left:5px;padding-right:10px;" size="auto" (click)="onClickSetting()">
<ion-icon name="settings-outline"></ion-icon>
</ion-col>
</ion-row>
</ion-grid>
}
</div>
\ No newline at end of file
.title-label {
background-color: #0CACCD;
background-color: #0DACCD;
color: white;
height: 40px;
}
......
......@@ -46,12 +46,4 @@ export class HeaderComponent {
this.routeService.navigateHome();
}
/**
* 利用者情報更新
*/
onClickSetting(): void {
if (this.routeService.customerId) {
this.routeService.navigateUserRegist(1, this.routeService.customerId);
}
}
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HistoryPage } from './history.page';
const routes: Routes = [
{
path: '',
component: HistoryPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class HistoryPageRoutingModule {}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HistoryPageRoutingModule } from './history-routing.module';
import { HistoryPage } from './history.page';
import { HeaderComponent } from '../common/header/header.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HistoryPageRoutingModule,
HeaderComponent
],
declarations: [HistoryPage]
})
export class HistoryPageModule { }
<ion-header [translucent]="true">
<app-header [mode]="2" (clickBack)="onClickBack()"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid style="margin-top:20px;">
<ion-row>
<ion-col class="ion-text-right" style="padding-top:8px;">
<ion-icon role="button" name="chevron-back-outline" size="large" (click)="onClickBefore()"></ion-icon>
</ion-col>
<ion-col>
<ion-datetime-button style="width:160px;" datetime="datetime"></ion-datetime-button>
<ion-modal [keepContentsMounted]="true">
<ng-template>
<ion-datetime id="datetime" presentation="date" [(ngModel)]="searchDate" [showDefaultButtons]="true"
(ionChange)="onChangeDate($event)"></ion-datetime>
</ng-template>
</ion-modal>
</ion-col>
<ion-col style="padding-top:8px;">
<ion-icon role="button" name="chevron-forward-outline" size="large" (click)="onClickAfter()"></ion-icon>
</ion-col>
</ion-row>
@for (history of historyList;track history.getonoffDt) {
<ion-row>
<ion-col size="auto">
<ion-label>{{history.getonoffDt}}</ion-label>
</ion-col>
<ion-col size="auto">
@if (history.kind === "1") {
<ion-label>乗車</ion-label>
} @else {
<ion-label>降車</ion-label>
}
</ion-col>
<ion-col size="auto">
<ion-label>{{history.stopName}}</ion-label>
</ion-col>
<ion-col>
@if (history.kind === "1") {
@if (history.status === 0) {
<ion-label>乗車中</ion-label>
}
} @else {
<ion-label>{{history.fare|number}}円</ion-label>
}
</ion-col>
</ion-row>
}
</ion-grid>
</ion-content>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HistoryPage } from './history.page';
describe('HistoryPage', () => {
let component: HistoryPage;
let fixture: ComponentFixture<HistoryPage>;
beforeEach(() => {
fixture = TestBed.createComponent(HistoryPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { HistoryModel } from '../model/history.model';
import { HistoryService } from '../services/history.service';
/**
* 乗車履歴閲覧画面
*/
@Component({
selector: 'app-history',
templateUrl: './history.page.html',
styleUrls: ['./history.page.scss'],
})
export class HistoryPage implements OnInit {
searchDate?: string;
//乗車履歴
historyList?: HistoryModel[];
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param historyService 乗降履歴サービス
*/
constructor(private routeService: RouteService, private historyService: HistoryService) { }
/**
* 初期化
*/
ngOnInit(): void {
this.searchDate = (new Date()).toLocaleDateString("ja-JP", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).split("/").join("-");
if (this.routeService.customerId) {
//this.historyList = this.historyService.getHistoryList(this.routeService.customerId, this.searchDate);
this.historyService.getHistoryList(this.routeService.customerId, this.searchDate).subscribe((ret: HistoryModel[]) => {
this.historyList = ret;
});
}
}
/**
* 戻る
*/
onClickBack(): void {
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
}
/**
* 前日へ
*/
onClickBefore(): void {
if (this.searchDate) {
let date = new Date(this.searchDate);
date.setDate(date.getDate() - 1);
this.searchDate = date.toLocaleDateString("ja-JP", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).split("/").join("-");
if (this.routeService.customerId) {
//this.historyList = this.historyService.getHistoryList(this.routeService.customerId, this.searchDate);
this.historyService.getHistoryList(this.routeService.customerId, this.searchDate).subscribe((ret: HistoryModel[]) => {
this.historyList = ret;
});
}
}
}
/**
* 翌日へ
*/
onClickAfter(): void {
if (this.searchDate) {
let date = new Date(this.searchDate);
date.setDate(date.getDate() + 1);
this.searchDate = date.toLocaleDateString("ja-JP", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).split("/").join("-");
if (this.routeService.customerId) {
//this.historyList = this.historyService.getHistoryList(this.routeService.customerId, this.searchDate);
this.historyService.getHistoryList(this.routeService.customerId, this.searchDate).subscribe((ret: HistoryModel[]) => {
this.historyList = ret;
});
}
}
}
/**
* 日付指定
* @param event イベント情報
*/
onChangeDate(event: any): void {
if (this.routeService.customerId) {
//this.historyList = this.historyService.getHistoryList(this.routeService.customerId, event.target.value);
this.historyService.getHistoryList(this.routeService.customerId, this.searchDate).subscribe((ret: HistoryModel[]) => {
this.historyList = ret;
});
}
}
}
<ion-header [translucent]="true">
<app-header [mode]="0"></app-header>
<ion-header>
<app-header [mode]="3"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="email" label="メールアドレス" [(ngModel)]="email" [maxlength]="50"></ion-input>
</ion-item>
<ion-button class="rounded menu-button" style="margin-top:20px;"
(click)="onClickCardSelect()">クレジットカード一覧</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="password" label="パスワード" [(ngModel)]="password" [maxlength]="20">
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
</ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-button class="common-button rounded" style="margin-top:20px;" (click)="onClickLogin()">ログイン</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<div role="button" class="common-link" style="font-size:12px;margin-top:20px;" (click)="onClickRegist()">
初めての方はこちら</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<div role="button" class="common-link" style="font-size:12px;" (click)="onClickPassword()">パスワードを忘れた方はこちら</div>
<ion-button class="rounded menu-button" style="margin-top:10px;" value=""
(click)="onClickClaimList()">請求一覧</ion-button>
</ion-col>
</ion-row>
</ion-grid>
......
#container {
text-align: center;
position: absolute;
left: 0;
right: 0;
top: 50%;
transform: translateY(-50%);
}
#container strong {
font-size: 20px;
line-height: 26px;
}
#container p {
font-size: 16px;
line-height: 22px;
color: #8c8c8c;
margin: 0;
}
#container a {
text-decoration: none;
.menu-button {
width: 100%;
height: 60px;
--width: 100%;
--height: 60px;
--background: #f0f0f0;
--color: black;
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { LoginService } from '../services/login.service';
/**
* ログイン画面
......@@ -10,61 +9,33 @@ import { LoginService } from '../services/login.service';
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
//メールアドレス
email?: string;
//パスワード
password?: string;
export class HomePage {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param loginService ログイン処理サービス
* @param routeServive 画面遷移サービス
*/
constructor(private routeService: RouteService, private loginService: LoginService) { }
constructor(private routeServive: RouteService) { }
/**
* 初期化
*/
ngOnInit(): void {
this.email = "";
this.password = "";
}
/**
* ログイン
* ログアウト
*/
onClickLogin(): void {
if (!this.email) {
alert("メールアドレスが入力されていません")
return;
}
if (!this.password) {
alert("パスワードが入力されていません");
return;
}
this.loginService.login(this.email, this.password).subscribe((ret: boolean) => {
//TODO
if (ret) {
this.routeService.navigateMenu("0000");
}
});
onClickLogout(): void {
this.routeServive.navigateHome();
}
/**
* 利用者登録
* クレジットカード選択
*/
onClickRegist(): void {
this.routeService.navigateUserRegist(0, "");
onClickCardSelect(): void {
this.routeServive.navigateCardSelect();
}
/**
* パスワード更新
* 請求一覧
*/
onClickPassword(): void {
this.routeService.navigatePasswordUpdate();
onClickClaimList(): void {
this.routeServive.navigateClaimList();
}
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MenuPage } from './menu.page';
const routes: Routes = [
{
path: '',
component: MenuPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class MenuPageRoutingModule {}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { MenuPageRoutingModule } from './menu-routing.module';
import { MenuPage } from './menu.page';
import { HeaderComponent } from '../common/header/header.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
MenuPageRoutingModule,
HeaderComponent
],
declarations: [MenuPage]
})
export class MenuPageModule { }
<ion-header [translucent]="true">
<app-header [mode]="3" (clickLogout)="onClickLogout()"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-row>
<ion-col>
<ion-button class="rounded menu-button" style="margin-top:20px;"
(click)="onClickCardSelect()">クレジットカード一覧</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-button class="rounded menu-button" style="margin-top:10px;" (click)="onClickHistory()">乗降履歴</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-button class="rounded menu-button" style="margin-top:10px;" value=""
(click)="onClickClaimList()">請求一覧</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
\ No newline at end of file
.menu-button {
width: 100%;
height: 60px;
--width: 100%;
--height: 60px;
--background: #f0f0f0;
--color: black;
}
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MenuPage } from './menu.page';
describe('MenuPage', () => {
let component: MenuPage;
let fixture: ComponentFixture<MenuPage>;
beforeEach(() => {
fixture = TestBed.createComponent(MenuPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component } from '@angular/core';
import { RouteService } from '../services/route.service';
/**
* メニュー画面
*/
@Component({
selector: 'app-menu',
templateUrl: './menu.page.html',
styleUrls: ['./menu.page.scss'],
})
export class MenuPage {
/**
* コンストラクタ
* @param routeServive 画面遷移サービス
*/
constructor(private routeServive: RouteService) { }
/**
* ログアウト
*/
onClickLogout(): void {
this.routeServive.navigateHome();
}
/**
* クレジットカード選択
*/
onClickCardSelect(): void {
this.routeServive.navigateCardSelect();
}
/**
* 乗降履歴
*/
onClickHistory(): void {
this.routeServive.navigateHistory();
}
/**
* 請求一覧
*/
onClickClaimList(): void {
this.routeServive.navigateClaimList();
}
}
......@@ -8,14 +8,10 @@ export class ClaimListModel {
agencyId?: string;
//事業者名
agencyName?: string;
//処理日時
processDt?: string;
//売上日
earningDate?: string;
//乗車日時
getonDt?: string;
//降車日時
getoffDt?: string;
//請求結果
result?: string;
//請求金額
amount: number = 0;
//NGフラグ
......@@ -24,4 +20,21 @@ export class ClaimListModel {
payRequest: number = 0;
//取消依頼
cancelRequest: number = 0;
detailList?: ClaimDetailModel[];
}
export class ClaimDetailModel {
//路線名
routeName?: string;
//乗車停留所名
getonStopName?: string;
//降車停留所名
getoffStopName?: string;
//乗車日時
getonDt?: string;
//降車日時
getoffDt?: string;
//料金
price: number = 0;
}
\ No newline at end of file
/**
* 乗降履歴情報
*/
export class HistoryModel {
//乗降日時
getonoffDt?: string;
//乗車/降車
kind?: string;
//停留所ID
stopId?: string;
//停留所名
stopName?: string;
//運賃
fare?: number;
//ステータス
status?: number;
}
\ No newline at end of file
/**
* 払戻情報
*/
export class RefundModel {
//乗車停留所
getonStopId?: string;
//降車停留所
getoffStopId?: string;
//購入金額
purchaseAmount?: number;
//通常運賃
standardFare?: number;
//使用日数
usedDays?: number;
//払戻手数料
refundFee?: number;
//払戻額
refundAmount?: number;
}
\ No newline at end of file
/**
* 利用者情報
*/
export class UserInfoModel {
//利用者ID
customerId?: string;
//氏名
name?: string;
//フリガナ
nameKana?: string;
//電話番号
phoneNumber?: string;
//メールアドレス
email?: string;
//パスワード
password?: string;
}
\ No newline at end of file
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PasswordUpdatePage } from './password-update.page';
const routes: Routes = [
{
path: '',
component: PasswordUpdatePage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class PasswordUpdatePageRoutingModule {}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { PasswordUpdatePageRoutingModule } from './password-update-routing.module';
import { PasswordUpdatePage } from './password-update.page';
import { HeaderComponent } from '../common/header/header.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
PasswordUpdatePageRoutingModule,
HeaderComponent
],
declarations: [PasswordUpdatePage]
})
export class PasswordUpdatePageModule { }
<ion-header [translucent]="true">
<app-header [mode]="1" (clickClose)="onClickClose()"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="email" label="メールアドレス" [value]="email"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="password" label="パスワード" [value]="password">
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
</ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-right">
<ion-label style="margin-right:20px;">
<span style="font-size:12px;">※パスワードは、8文字以上としてください</span>
</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-button class="common-button rounded" style="margin-top:20px;" (click)="onClickUpdate()">更新</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PasswordUpdatePage } from './password-update.page';
describe('PasswordUpdatePage', () => {
let component: PasswordUpdatePage;
let fixture: ComponentFixture<PasswordUpdatePage>;
beforeEach(() => {
fixture = TestBed.createComponent(PasswordUpdatePage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component } from '@angular/core';
import { RouteService } from '../services/route.service';
import { UserService } from '../services/user.service';
/**
* パスワード更新画面
*/
@Component({
selector: 'app-password-update',
templateUrl: './password-update.page.html',
styleUrls: ['./password-update.page.scss'],
})
export class PasswordUpdatePage {
//メールアドレス
email?: string;
//パスワード
password?: string;
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param userService 利用者サービス
*/
constructor(private routeService: RouteService, private userService: UserService) { }
/**
* 閉じる
*/
onClickClose(): void {
this.routeService.navigateHome();
}
/**
* 更新
*/
onClickUpdate(): void {
//パスワード更新
this.userService.changePassword(this.email, this.password);
this.routeService.navigateHome();
}
}
import { Injectable } from '@angular/core';
import { CreditCardModel } from '../model/credit-card.model';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
/**
* クレジットカードサービス
......@@ -9,37 +10,19 @@ import { Observable } from 'rxjs';
providedIn: 'root'
})
export class CardService {
readonly cardUrl = './data/card.json';
/**
* コンストラクタ
*/
constructor() { }
constructor(private http: HttpClient) { }
/**
* クレジットカード情報一覧取得
* @param customerId 利用者ID
*/
getList(customerId?: string): Observable<CreditCardModel[]> {
//TODO
let cardList = new Array();
for (let i = 0; i < 2; i++) {
let model: CreditCardModel = new CreditCardModel();
let value = 1234 + i;
model.tokenId = String(value);
model.cardKind = i;
model.cardNumber = String(value);
model.cardOwner = "TARO YAMADA";
model.cardYear = "2023";
model.cardMonth = "02";
if (i == 1) {
model.denyStatus = 1;
}
model.deleteDeny = 0;
cardList.push(model);
}
//return cardList;
return new Observable<CreditCardModel[]>(o => {
o.next(cardList);
})
return this.http.get<CreditCardModel[]>(this.cardUrl);
}
/**
......
import { Injectable } from '@angular/core';
import { ClaimListModel } from '../model/claim-list.model';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
/**
* 請求一覧サービス
......@@ -9,10 +10,12 @@ import { Observable } from 'rxjs';
providedIn: 'root'
})
export class ClaimlistService {
readonly claimUrl = './data/claimlist.json';
/**
* コンストラクタ
*/
constructor() { }
constructor(private http: HttpClient) { }
/**
* 請求一覧取得
......@@ -20,28 +23,7 @@ export class ClaimlistService {
* @return 請求一覧
*/
getList(customerId: string): Observable<ClaimListModel[]> {
//TODO
let claimList = new Array();
for (let i = 0; i < 2; i++) {
let claimListModel = new ClaimListModel();
let str = String(i);
claimListModel.tokenId = "token001";
claimListModel.agencyId = str;
claimListModel.agencyName = "XXXXバス";
claimListModel.processDt = "20240620103002";
claimListModel.earningDate = "20240620";
claimListModel.getonDt = "2024062010000" + str;
claimListModel.getoffDt = "20240620103004";
claimListModel.amount = 1000;
if (i == 1) {
claimListModel.ngFlag = 1;
}
claimList.push(claimListModel);
}
//return claimList;
return new Observable<ClaimListModel[]>(o => {
o.next(claimList);
});
return this.http.get<ClaimListModel[]>(this.claimUrl);
}
/**
......
import { TestBed } from '@angular/core/testing';
import { HistoryService } from './history.service';
describe('HistoryService', () => {
let service: HistoryService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(HistoryService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { HistoryModel } from '../model/history.model';
import { Observable } from 'rxjs';
/**
* 乗降履歴サービス
*/
@Injectable({
providedIn: 'root'
})
export class HistoryService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 乗降履歴一覧取得
* @param customerId 利用者ID
* @param searchDate 検索対象日
* @returns 乗降履歴一覧
*/
getHistoryList(customerId: string, searchDate?: string): Observable<HistoryModel[]> {
//TODO
let historyList = new Array();
for (let i = 0; i < 10; i++) {
let historyModel: HistoryModel = new HistoryModel();
let str = String(i);
if (searchDate) {
let ymd: string[] = searchDate?.split("-");
historyModel.getonoffDt = ymd[0] + "/" + ymd[1] + "/" + ymd[2] + " 17:08:1" + str;
} else {
historyModel.getonoffDt = "2024/07/01 17:08:1" + str;
}
historyModel.stopId = str;
if (i % 2 == 0) {
historyModel.kind = "1";
historyModel.stopName = "XXXX停留所";
historyModel.status = 1;
} else {
historyModel.kind = "2";
historyModel.stopName = "YYYY停留所";
historyModel.fare = 200;
historyModel.status = 1;
}
historyList.push(historyModel);
}
let historyModel: HistoryModel = new HistoryModel();
if (searchDate) {
let ymd: string[] = searchDate?.split("-");
historyModel.getonoffDt = ymd[0] + "/" + ymd[1] + "/" + ymd[2] + " 17:10:10";
} else {
historyModel.getonoffDt = "2024/07/01 17:10:10";
}
historyModel.kind = "1";
historyModel.stopName = "XXXX停留所";
historyModel.status = 0;
historyList.push(historyModel);
//return historyList;
return new Observable<HistoryModel[]>(o => {
o.next(historyList);
});
}
}
import { TestBed } from '@angular/core/testing';
import { LoginService } from './login.service';
describe('LoginService', () => {
let service: LoginService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LoginService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
/**
* ログインサービス
*/
@Injectable({
providedIn: 'root'
})
export class LoginService {
/**
* コンストラクタ
*/
constructor() { }
/**
* ログインサービス
* @param email メールアドレス
* @param password パスワード
* @returns ログイン結果
*/
public login(email: string, password: string): Observable<boolean> {
// TODO
return new Observable<boolean>(o => {
o.next(true);
});
}
}
import { Injectable } from '@angular/core';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { RefundModel } from '../model/refund.model';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
/**
* 定期券サービス
......@@ -10,10 +10,12 @@ import { Observable } from 'rxjs';
providedIn: 'root'
})
export class PassService {
readonly passUrl = "./data/pass.json";
/**
* コンストラクタ
*/
constructor() { }
constructor(private http: HttpClient) { }
/**
* 定期一覧取得
......@@ -22,28 +24,7 @@ export class PassService {
*/
getList(tokenId: string): Observable<CommuterPassModel[]> {
//TODO
let commuterPassList = new Array();
for (let i = 0; i < 2; i++) {
let model: CommuterPassModel = new CommuterPassModel();
model.tokenId = tokenId;
model.commuterPassId = String(i + 1);
model.routeId = "00000" + String(i);
model.routeName = "【◯◯◯系統】XXXXX→XXXXX行き";
model.startDate = "2024/07/01";
model.useTermId = "3";
model.useTermName = "3ヶ月";
model.priceRangeId = "1";
model.privateRangeName = "大人";
model.getonStopId = "1";
model.getonStopName = "停留所1";
model.getoffStopId = "5";
model.getoffStopName = "停留所5";
commuterPassList.push(model);
}
//return commuterPassList;
return new Observable<CommuterPassModel[]>(o => {
o.next(commuterPassList);
});
return this.http.get<CommuterPassModel[]>(this.passUrl);
}
/**
......@@ -52,27 +33,7 @@ export class PassService {
*/
getListNoCard(): Observable<CommuterPassModel[]> {
//TODO
let commuterPassList = new Array();
for (let i = 0; i < 2; i++) {
let model: CommuterPassModel = new CommuterPassModel();
model.commuterPassId = String(i + 1);
model.routeId = "00000" + String(i);
model.routeName = "【◯◯◯系統】XXXXX→XXXXX行き";
model.startDate = "2024/07/01";
model.useTermId = "3";
model.useTermName = "3ヶ月";
model.priceRangeId = "1";
model.privateRangeName = "大人";
model.getonStopId = "1";
model.getonStopName = "停留所1";
model.getoffStopId = "5";
model.getoffStopName = "停留所5";
commuterPassList.push(model);
}
//return commuterPassList;
return new Observable<CommuterPassModel[]>(o => {
o.next(commuterPassList);
});
return this.http.get<CommuterPassModel[]>(this.passUrl);
}
......
......@@ -37,31 +37,6 @@ export class RouteService {
this.router.navigate(['home']);
}
/**
* 利用者登録画面へ遷移
* @param mode 0:登録、1:更新
*/
navigateUserRegist(mode: number, customerId: string) {
this.mode = mode;
this.customerId = customerId;
this.router.navigate(['user-regist']);
}
/**
* パスワード更新画面へ遷移
*/
navigatePasswordUpdate() {
this.router.navigate(['password-update'])
}
/**
* メニュー画面へ遷移
*/
navigateMenu(customerId: string) {
this.customerId = customerId;
this.router.navigate(['menu']);
}
/**
* クレジットカード選択画面へ遷移
*/
......@@ -93,40 +68,6 @@ export class RouteService {
this.router.navigate(['pass-regist']);
}
/**
* 定期券区間変更画面へ遷移
* @param commuterPassModel 定期券情報
*/
navigatePassChange(commuterPassModel: CommuterPassModel) {
this.commuterPassModel = commuterPassModel;
this.router.navigate(['pass-change']);
}
/**
* 定期券継続画面へ遷移
* @param commuterPassModel 定期券情報
*/
navigatePassContinue(commuterPassModel: CommuterPassModel) {
this.commuterPassModel = commuterPassModel;
this.router.navigate(['pass-continue']);
}
/**
* 定期券払戻画面へ遷移
* @param commuterPassModel 定期券情報
*/
navigatePassRefund(commuterPassModel: CommuterPassModel) {
this.commuterPassModel = commuterPassModel;
this.router.navigate(['pass-refund']);
}
/**
* 乗車履歴画面へ遷移
*/
navigateHistory() {
this.router.navigate(['history']);
}
/**
* 請求一覧画面へ遷移
*/
......
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { UserInfoModel } from '../model/user-info.model';
import { Observable } from 'rxjs';
/**
* 利用者サービス
*/
@Injectable({
providedIn: 'root'
})
export class UserService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 利用者情報取得
* @param customerId 利用者ID
*/
getInfo(customerId: string): Observable<UserInfoModel> {
let model: UserInfoModel = new UserInfoModel();
//TODO ダミー
model.name = "山田 太郎"
model.nameKana = "ヤマダ タロウ";
model.phoneNumber = "09012345678";
model.email = "yamada_tarou@test.com";
model.password = "password00";
//return model;
return new Observable<UserInfoModel>(o => {
o.next(model);
});
}
/**
* 利用者情報登録
* @param model 利用者情報
*/
regist(model: UserInfoModel): void {
//TODO
}
/**
* 利用者情報更新
* @param model 利用者情報
*/
update(model: UserInfoModel): void {
//TODO
}
/**
* 利用者退会
* @param customerId 利用者ID
*/
withdraw(customerId: string): void {
//TODO
}
/**
* パスワード変更
* @param email メールアドレス
* @param password パスワード
*/
changePassword(email?: string, password?: string): void {
//TODO
}
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { UserRegistPage } from './user-regist.page';
const routes: Routes = [
{
path: '',
component: UserRegistPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class UserRegistPageRoutingModule {}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { UserRegistPageRoutingModule } from './user-regist-routing.module';
import { UserRegistPage } from './user-regist.page';
import { HeaderComponent } from '../common/header/header.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
UserRegistPageRoutingModule,
HeaderComponent
],
declarations: [UserRegistPage]
})
export class UserRegistPageModule { }
<ion-header [translucent]="true">
<app-header [mode]="1" (clickClose)="onClickClose()"></app-header>
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="text" label="氏名" [value]="name" [maxlength]="30"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="text" label="フリガナ" [value]="nameKana" [maxlength]="30"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="tel" label="電話番号" [value]="phoneNumber" [maxlength]="20"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
@if (mode === 0) {
<ion-item>
<ion-input type="email" label="メールアドレス" [value]="email" [maxlength]="50"></ion-input>
</ion-item>
} @else {
<ion-label>メールアドレス</ion-label><ion-label>{{email}}</ion-label>
}
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="password" label="パスワード" [value]="password" [maxlength]="20">
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
</ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-right">
<ion-label style="margin-right:20px;">
<span style="font-size:12px;">※パスワードは、8文字以上としてください</span>
</ion-label>
</ion-col>
</ion-row>
<ion-row>
@if (mode === 0) {
<ion-col class="ion-text-center">
<ion-button id="regist" class="common-button rounded" style="margin-top:20px;">登録</ion-button>
<ion-alert trigger="regist" header="この内容で登録してよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickRegist($event)"></ion-alert>
</ion-col>
} @else {
<ion-col class="ion-text-center">
<ion-button id="update" class="common-button rounded" style="margin-top:20px;">更新</ion-button>
<ion-alert trigger="update" header="この内容で更新してよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickUpdate($event)"></ion-alert>
</ion-col>
<ion-col class="ion-text-center">
<ion-button id="withdraw" class="common-button rounded" style="margin-top:20px;">退会</ion-button>
<ion-alert trigger="withdraw" header="退会してよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickWithdraw($event)"></ion-alert>
</ion-col>
}
</ion-row>
</ion-grid>
</ion-content>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserRegistPage } from './user-regist.page';
describe('UserRegistPage', () => {
let component: UserRegistPage;
let fixture: ComponentFixture<UserRegistPage>;
beforeEach(() => {
fixture = TestBed.createComponent(UserRegistPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { UserService } from '../services/user.service';
import { UserInfoModel } from '../model/user-info.model';
/**
* 利用者登録画面
*/
@Component({
selector: 'app-user-regist',
templateUrl: './user-regist.page.html',
styleUrls: ['./user-regist.page.scss'],
})
export class UserRegistPage implements OnInit {
//モード(0:登録、1:更新)
mode: number = 0;
//氏名
name?: string;
//フリガナ
nameKana?: string;
//電話番号
phoneNumber?: string;
//メールアドレス
email?: string;
//パスワード
password?: string;
//利用者ID
customerId?: string;
public confirmButtons = [
{
text: 'いいえ',
role: 'cancel'
},
{
text: 'はい',
role: 'confirm'
},
];
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param userService 利用者情報サービス
*/
constructor(private routeService: RouteService, private userService: UserService) {
this.mode = routeService.mode;
this.customerId = routeService.customerId;
}
/**
* 初期処理
*/
ngOnInit(): void {
if (this.customerId) {
//let model: UserInfoModel = this.userService.getInfo(this.customerId);
this.userService.getInfo(this.customerId).subscribe((model: UserInfoModel) => {
this.name = model.name;
this.nameKana = model.nameKana;
this.phoneNumber = model.phoneNumber;
this.email = model.email;
this.password = model.password;
});
}
}
/**
* 閉じる
*/
onClickClose(): void {
this.routeService.navigateHome();
}
/**
* 登録
* @param event イベント情報
*/
onClickRegist(event: any): void {
if (event.detail.role === 'confirm') {
//利用者情報登録
let model: UserInfoModel = new UserInfoModel();
model.name = this.name;
model.nameKana = this.nameKana;
model.phoneNumber = this.phoneNumber;
model.email = this.email;
model.password = this.password;
this.userService.regist(model);
}
this.routeService.navigateHome();
}
/**
* 更新
* @param event イベント情報
*/
onClickUpdate(event: any): void {
if (event.detail.role === 'confirm') {
//利用者情報更新
let model: UserInfoModel = new UserInfoModel();
model.customerId = this.customerId;
model.name = this.name;
model.nameKana = this.nameKana;
model.phoneNumber = this.phoneNumber;
model.email = this.email;
model.password = this.password;
this.userService.update(model);
}
this.routeService.navigateHome();
}
/**
* 退会
* @param event イベント情報
*/
onClickWithdraw(event: any): void {
if (event.detail.role === 'confirm') {
//退会
if (this.customerId) {
this.userService.withdraw(this.customerId);
}
}
this.routeService.navigateHome();
}
}
src/assets/icon/mastercard.png

9.2 KB | W: | H:

src/assets/icon/mastercard.png

2.4 KB | W: | H:

src/assets/icon/mastercard.png
src/assets/icon/mastercard.png
src/assets/icon/mastercard.png
src/assets/icon/mastercard.png
  • 2-up
  • Swipe
  • Onion skin
[
{
"tokenId": "00001",
"cardKind": 1,
"cardNumber": "1234",
"cardOwner": "TARO YAMADA",
"cardYear": "2027",
"cardMonth": "02",
"cvc": "",
"denyStatus": 0,
"deleteDeny": 0
},
{
"tokenId": "00002",
"cardKind": 2,
"cardNumber": "5678",
"cardOwner": "HANAKO YAMADA",
"cardYear": "2026",
"cardMonth": "03",
"cvc": "",
"denyStatus": 1,
"deleteDeny": 0
}
]
\ No newline at end of file
[
{
"tokenId": "00001",
"agencyId": "00001",
"agencyName": "XXXXバス",
"earningDate": "20240620",
"amount": 1000,
"result": "承認",
"ngFlag": 0,
"payRequest": 0,
"cancelRequest": 0,
"detailList": [
{
"routeName": "◯◯◯◯線",
"getonStopName": "A停留所",
"getoffStopName": "B停留所",
"getonDt": "20240620100001",
"getoffDt": "20240620103004",
"price": 400
},
{
"routeName": "◯◯◯◯線",
"getonStopName": "B停留所",
"getoffStopName": "C停留所",
"getonDt": "20240621100001",
"getoffDt": "20240621103004",
"price": 600
}
]
},
{
"tokenId": "00002",
"agencyId": "00001",
"agencyName": "XXXXバス",
"processDt": "20240621103002",
"earningDate": "20240621",
"amount": 2000,
"ngFlag": 1,
"payRequest": 0,
"cancelRequest": 0,
"detailList": [
{
"routeName": "◯◯◯◯線",
"getonStopName": "A停留所",
"getoffStopName": "B停留所",
"getonDt": "20240620100001",
"getoffDt": "20240620103004",
"price": 600
},
{
"routeName": "◯◯◯◯線",
"getonStopName": "B停留所",
"getoffStopName": "C停留所",
"getonDt": "20240621100001",
"getoffDt": "20240621103004",
"price": 500
}
]
}
]
\ No newline at end of file
[
{
"tokenId": "00001",
"commuterPassId": "00001",
"agencyId": "00001",
"routeId": "00001",
"routeName": "【◯◯◯系統】XXXXX→XXXXX行き",
"startDate": "2024/07/01",
"useTermId": "3",
"useTermName": "3ヶ月",
"priceRangeId": "1",
"privateRangeName": "大人",
"getonStopId": "1",
"getonStopName": "停留所1",
"getoffStopId": "5",
"getoffStopName": "停留所5"
},
{
"tokenId": "00001",
"commuterPassId": "00002",
"agencyId": "00001",
"routeId": "00002",
"routeName": "【◯◯◯系統】XXXXX→XXXXX行き",
"startDate": "2024/07/02",
"useTermId": "6",
"useTermName": "6ヶ月",
"priceRangeId": "1",
"privateRangeName": "大人",
"getonStopId": "2",
"getonStopName": "停留所2",
"getoffStopId": "7",
"getoffStopName": "停留所7"
}
]
\ No newline at end of file
......@@ -36,19 +36,15 @@
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
@import "@ionic/angular/css/palettes/dark.system.css";
.common-button {
--background: #F19024;
--color: white;
--height: 40px;
--padding-left: 20px;
--padding-right: 20px;
.label-orange {
color: #FC9422;
}
.common-link {
text-decoration: underline;
color: #0CACCD;
.label-blue {
color: #0DACCD;
}
.add-link {
color: #0CACCD;
.label-gray {
color: #828DA4;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment