Commit 57b2a597 authored by 伊藤雄大's avatar 伊藤雄大

Merge branch 'itou' into 'develop'

諸々改善 See merge request !2
parents 8f6af295 3ee07dcc
{
"typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular/standalone"]
"files.exclude": {
"amplify/.config": true,
"amplify/**/*-parameters.json": true,
"amplify/**/amplify.state": true,
"amplify/**/transform.conf.json": true,
"amplify/#current-cloud-backend": true,
"amplify/backend/amplify-meta.json": true,
"amplify/backend/awscloudformation": true
},
"typescript.preferences.autoImportFileExcludePatterns": [
"@ionic/angular/common",
"@ionic/angular/standalone"
]
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -16,17 +16,19 @@
"@angular/animations": "^18.0.0",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/core": "^18.1.1",
"@angular/forms": "^18.0.0",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/router": "^18.0.0",
"@aws-amplify/ui-angular": "^5.0.16",
"@capacitor/app": "6.0.0",
"@capacitor/core": "6.1.0",
"@capacitor/haptics": "6.0.0",
"@capacitor/keyboard": "6.0.1",
"@capacitor/status-bar": "6.0.0",
"@ionic/angular": "^8.0.0",
"aws-amplify": "^6.4.0",
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"ionicons": "^7.0.0",
......@@ -41,7 +43,7 @@
"@angular-eslint/eslint-plugin-template": "^18.0.0",
"@angular-eslint/schematics": "^18.0.0",
"@angular-eslint/template-parser": "^18.0.0",
"@angular/cli": "^18.0.0",
"@angular/cli": "^18.1.1",
"@angular/compiler-cli": "^18.0.0",
"@angular/language-service": "^18.0.0",
"@capacitor/cli": "6.1.0",
......
......@@ -9,7 +9,11 @@ import { AppRoutingModule } from './app-routing.module';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent]
})
......
......@@ -36,7 +36,7 @@
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<input type="button" id="addcard" class="common-button rounded" style="margin-top:20px;" value="追加" />
<ion-button id="addcard" class="common-button" style="margin-top:20px;">追加</ion-button>
<ion-alert trigger="addcard" header="この内容で追加してよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickAddCard($event)"></ion-alert>
</ion-col>
......
import { Component } from '@angular/core';
import { RouteService } from '../services/route.service';
import { CardService } from '../services/card.service';
import { CreditCardModel } from '../model/credit-card.model';
/**
* クレジットカード登録画面
......@@ -36,8 +38,9 @@ export class CardRegistPage {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param cardService クレジットカードサービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private cardService: CardService) { }
/**
* 閉じる
......@@ -51,6 +54,15 @@ export class CardRegistPage {
* @param event イベント
*/
onClickAddCard(event: any): void {
//クレジットカード登録
let model: CreditCardModel = new CreditCardModel();
model.cardNumber = this.cardMonth ? this.cardMonth : "";
model.cardOwner = this.cardOwner ? this.cardOwner : "";
model.cardMonth = this.cardMonth ? this.cardMonth : "";
model.cardYear = this.cardYear ? this.cardYear : "";
model.cvc = this.cvc ? this.cvc : "";
this.cardService.regist(this.routeService.customerId, model);
this.routeService.navigateCardSelect();
}
}
<div class="rounded border">
<table width="100%">
<tr>
<td colspan="2">
<table width="100%">
<tr>
<td style="width:75%;padding-top:10px;padding-left:10px;">
<span>クレジットカード</span>
</td>
<!-- td style="padding-top:10px;">
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col colspan="2">
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col style="width:75%;padding-top:8px;padding-left:10px;">
<ion-label>クレジットカード</ion-label>
</ion-col>
<ion-col size="auto" style="padding-top:8px;">
<div class="common-link" (click)="onClickPass()">定期券</div>
</td -->
<td align="right" style="padding-top:10px;padding-right:10px;">
<i class="bi bi-trash3" (click)="onClickTrash()"></i>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="padding-left:10px;padding-top:10px;">
<span>カード番号</span>
</td>
<td style="padding-top:10px;">
<span>****&nbsp;****&nbsp;****&nbsp;{{creditCardModel?.cardNumber}}</span>
</td>
</tr>
<tr>
<td style="padding-left:10px;padding-top:10px;">
<span>カード名義人</span>
</td>
<td style="padding-top:10px;">
<span>{{creditCardModel?.cardOwner}}</span>
</td>
</tr>
<tr>
<td style="padding-left:10px;padding-top:10px;padding-bottom:10px;">
<span>有効期限</span>
</td>
<td style="padding-top:10px;padding-bottom:10px;">
<span>{{creditCardModel?.cardYear}}年{{creditCardModel?.cardMonth}}月</span>
</td>
</tr>
</table>
</ion-col>
<ion-col size="auto" align="right" style="padding-top:10px;padding-right:10px;">
<ion-icon name="trash-outline"></ion-icon>
</ion-col>
</ion-row>
</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-grid class="ion-no-padding">
<ion-row>
<ion-col size="auto">
@switch (creditCardModel?.cardKind) {
@case (0) {
<div class="jcb"></div>
}
@case (1) {
<div class="visa"></div>
}
@case (2) {
<div class="master"></div>
}
@case (3) {
<div class="amex"></div>
}
@case (4) {
<div class="diners"></div>
}
}
</ion-col>
<ion-col style="padding-left:10px;padding-top:8px;padding-right:8px;">
<ion-label>****&nbsp;****&nbsp;****&nbsp;{{creditCardModel?.cardNumber}}</ion-label>
</ion-col>
</ion-row>
</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>
</ion-col>
<ion-col style="padding-top:10px;padding-bottom:10px;">
<ion-label>{{creditCardModel?.cardYear}}年{{creditCardModel?.cardMonth}}月</ion-label>
</ion-col>
</ion-row>
</ion-grid>
</div>
\ No newline at end of file
.visa {
background-image: url('../../../assets/icon/visa.png');
background-repeat: no-repeat;
width: 53px;
height: 34px;
}
.master {
background-image: url('../../../assets/icon/mastercard.png');
background-repeat: no-repeat;
width: 53px;
height: 34px;
}
.jcb {
background-image: url('../../../assets/icon/jcb.png');
background-repeat: no-repeat;
width: 44px;
height: 34px;
}
.amex {
background-image: url('../../../assets/icon/amex.png');
background-repeat: no-repeat;
width: 34px;
height: 34px;
}
.diners {
background-image: url('../../../assets/icon/diners.png');
background-repeat: no-repeat;
width: 47px;
height: 34px;
}
\ No newline at end of file
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CreditCardModel } from 'src/app/model/credit-card.model';
/**
......@@ -9,6 +10,9 @@ import { CreditCardModel } from 'src/app/model/credit-card.model';
selector: 'app-card-info',
templateUrl: './card-info.component.html',
styleUrls: ['./card-info.component.scss'],
imports: [
IonicModule
]
})
export class CardInfoComponent {
//クレジットカード情報
......
......@@ -17,8 +17,8 @@ import { CardInfoComponent } from './card-info/card-info.component';
FormsModule,
IonicModule,
CardSelectPageRoutingModule,
HeaderComponent,
CardInfoComponent
CardInfoComponent,
HeaderComponent
],
declarations: [CardSelectPage]
})
......
......@@ -11,7 +11,7 @@
</div>
}
</div>
<div style="margin-top:10px;text-align:center;" (click)="onClickAddCard()">
<span class="add-link">+&nbsp;クレジットカードを追加する</span>
<div role="button" style="margin-top:10px;text-align:center;" class="add-link" (click)="onClickAddCard()">
<span>+&nbsp;クレジットカードを追加する</span>
</div>
</ion-content>
\ No newline at end of file
.add-link {
color: #0CACCD;
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { CreditCardModel } from '../model/credit-card.model';
import { CardService } from '../services/card.service';
/**
* クレジットカード選択
......@@ -15,30 +16,25 @@ export class CardSelectPage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param cardService クレジットカードサービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private cardService: CardService) { }
/**
* 初期化
*/
ngOnInit(): void {
this.cardList = new Array();
for (let i = 0; i < 2; i++) {
let model: CreditCardModel = new CreditCardModel();
let value = 1234 + i;
model.cardNumber = String(value);
model.cardOwner = "TARO YAMADA";
model.cardYear = "2023";
model.cardMonth = "02";
this.cardList.push(model);
}
this.cardList = this.cardService.getList(this.routeService.customerId);
}
/**
* 戻る
*/
onClickBack(): void {
this.routeService.navigateMenu();
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
}
/**
......@@ -53,7 +49,7 @@ export class CardSelectPage implements OnInit {
* @param model クレジットカード情報
*/
onClickPass(model: CreditCardModel): void {
this.routeService.navigatePassSelect(model.cardNumber);
this.routeService.navigatePassSelect(model.tokenId, model.cardNumber);
}
/**
......@@ -61,6 +57,6 @@ export class CardSelectPage implements OnInit {
* @param model クレジットカード情報
*/
onClickTrash(model: CreditCardModel): void {
this.cardService.delete(model.tokenId);
}
}
......@@ -3,21 +3,25 @@
<div style="margin-left:10px;padding-top:5px;">タッチ決済サービス</div>
}
@if (mode === 2) {
<div style="margin-left:10px;padding-top:5px;" (click)="onClickBack()"></div>
<div style="margin-left:5px;padding-top:5px;" (click)="onClickBack()">
<ion-icon name="chevron-back-outline" size="large"></ion-icon>
</div>
}
@if (mode === 1) {
<div style="margin-right:10px;padding-top:5px;" (click)="onClickClose()"></div>
<div style="margin-right:10px;padding-top:5px;" (click)="onClickClose()">
<ion-icon name="close-outline" size="large"></ion-icon>
</div>
}
@if (mode === 3) {
<table width="100%">
<tr>
<td style="padding-top:5px;">
<ion-grid width="100%">
<ion-row>
<ion-col style="padding-top:3px;text-align:right;">
<div (click)="onClickLogout()">ログアウト</div>
</td>
<td style="padding-top:5px;padding-left:5px;padding-right:10px;width:20px;">
<i class="bi bi-gear" (click)="onClickSetting()"></i>
</td>
</tr>
</table>
</ion-col>
<ion-col style="padding-top:5px;padding-left:5px;padding-right:10px;" size="auto">
<ion-icon name="settings-outline"></ion-icon>
</ion-col>
</ion-row>
</ion-grid>
}
</div>
\ No newline at end of file
......@@ -7,3 +7,16 @@
.right-align {
text-align: right;
}
.back {
content: "";
display: block;
width: 12px;
height: 12px;
position: absolute;
top: calc(50% - 2px); //ボーダーの太さ分を引く
border-top: solid 2px;
border-right: solid 2px;
transform: rotate(225deg);
color: inherit;
}
\ No newline at end of file
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Component, EventEmitter, Input, NgModule, Output } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { RouteService } from 'src/app/services/route.service';
/**
......@@ -8,7 +9,10 @@ import { RouteService } from 'src/app/services/route.service';
standalone: true,
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
styleUrls: ['./header.component.scss'],
imports: [
IonicModule
]
})
export class HeaderComponent {
//モード(0:通常,1:閉じる,2:戻る,3:ログアウト)
......@@ -46,6 +50,8 @@ export class HeaderComponent {
* 利用者情報更新
*/
onClickSetting(): void {
this.routeService.navigateUserRegist();
if (this.routeService.customerId) {
this.routeService.navigateUserRegist(1, this.routeService.customerId);
}
}
}
<div class="border rounded">
<table width="100%">
<tr>
<td style="padding-left:10px;">
<input class="form-check-input" type="checkbox" (change)="onChangeSelect($event)">
</td>
<td>
<table width="100%">
<tr>
<td colspan="2" style="padding-top:10px;">
{{model.getonStopName}}→{{model.getoffStopName}}
</td>
</tr>
<tr>
<td style="padding-top:10px;">
<span>乗車</span>
</td>
<td style="padding-top:10px;">
{{model.getonDt}}
</td>
</tr>
<tr>
<td style="padding-top:10px;">
<span>降車</span>
</td>
<td style="padding-top:10px;">
{{model.getoffDt}}
</td>
</tr>
<tr>
<td style="padding-top:10px;padding-bottom:10px;">
<span>請求金額</span>
</td>
<td style="padding-top:10px;padding-bottom:10px;">
{{amountStr}}円
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
\ No newline at end of file
<div class="border rounded">
<ion-grid class="</ion-label>">
<ion-row>
<ion-col style="padding-left:10px;" size="auto">
<ion-checkbox class="form-check-input" style="margin-top:80px;"
(change)="onChangeSelect($event)"></ion-checkbox>
</ion-col>
<ion-col>
<ion-grid class="</ion-label>">
<ion-row>
<ion-col style="padding-top:10px;">
<ion-label>{{model.getonStopName}}→{{model.getoffStopName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;" size="auto">
<div style="width:80px;">乗車</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{model.getonDt}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;" size="auto">
<div style="width:80px;">降車</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{model.getoffDt}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;padding-bottom:10px;" size="auto">
<div style="width:80px;">請求金額</div>
</ion-col>
<ion-col style="padding-top:10px;padding-bottom:10px;">
<ion-label>{{amountStr}}円</ion-label>
</ion-col>
</ion-row>
</ion-grid>
</ion-col>
</ion-row>
</ion-grid>
</div>
\ No newline at end of file
import { Component, Input, OnInit } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { DenyListModel } from 'src/app/model/deny-list.model';
import { RouteService } from 'src/app/services/route.service';
/**
* 拒否リスト情報
......@@ -10,6 +10,9 @@ import { RouteService } from 'src/app/services/route.service';
selector: 'app-deny-info',
templateUrl: './deny-info.component.html',
styleUrls: ['./deny-info.component.scss'],
imports: [
IonicModule
]
})
export class DenyInfoComponent implements OnInit {
@Input() model: DenyListModel = new DenyListModel();
......
......@@ -9,7 +9,7 @@ import { DenyListPageRoutingModule } from './deny-list-routing.module';
import { DenyListPage } from './deny-list.page';
import { HeaderComponent } from '../common/header/header.component';
import { DenyInfoComponent } from './component/deny-info/deny-info.component';
import { DenyInfoComponent } from './deny-info/deny-info.component';
@NgModule({
imports: [
......@@ -17,8 +17,8 @@ import { DenyInfoComponent } from './component/deny-info/deny-info.component';
FormsModule,
IonicModule,
DenyListPageRoutingModule,
HeaderComponent,
DenyInfoComponent
DenyInfoComponent,
HeaderComponent
],
declarations: [DenyListPage]
})
......
......@@ -9,7 +9,7 @@
</div>
}
<div style="margin-top:20px;text-align:center;">
<ion-input type="button" id="delreq" class="common-button rounded" style="margin-top:20px;" value="削除依頼" />
<ion-button id="delreq" class="common-button rounded" style="margin-top:20px;">削除依頼</ion-button>
<ion-alert trigger="delreq" header="拒否リストからの削除を依頼しますか?" [buttons]="confirmButtons"
(didDismiss)="onClickDelreq($event)"></ion-alert>
</div>
......
import { Component, OnInit, QueryList, ViewChildren } from '@angular/core';
import { DenyListModel } from '../model/deny-list.model';
import { RouteService } from '../services/route.service';
import { DenyInfoComponent } from './component/deny-info/deny-info.component';
import { DenyInfoComponent } from './deny-info/deny-info.component';
import { DenylistService } from '../services/denylist.service';
/**
* 拒否リスト
*/
@Component({
selector: 'app-deny-list',
templateUrl: './deny-list.page.html',
......@@ -28,24 +32,16 @@ export class DenyListPage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param denyListService 拒否リストサービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private denyListService: DenylistService) { }
/**
* 初期化
*/
ngOnInit() {
this.denyList = new Array();
for (let i = 0; i < 4; i++) {
let denyListModel = new DenyListModel();
let str = String(i);
denyListModel.getonStopId = str;
denyListModel.getonStopName = "XXXX停留所";
denyListModel.getoffStopName = "YYYYY停留所";
denyListModel.getonDt = "2024/06/20 10:00:01";
denyListModel.getoffDt = "2024/06/20 10:30:02";
denyListModel.amount = 1000;
this.denyList.push(denyListModel);
if (this.routeService.customerId) {
this.denyList = this.denyListService.getList(this.routeService.customerId);
}
}
......@@ -53,7 +49,9 @@ export class DenyListPage implements OnInit {
* 戻る
*/
onClickBack(): void {
this.routeService.navigateMenu();
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
}
/**
......@@ -61,14 +59,19 @@ export class DenyListPage implements OnInit {
*/
onClickDelreq(event: any): void {
if (event.detail.role === 'confirm') {
let req: DenyListModel[] = [];
this.denyInfoList?.forEach(child => {
let model = child.getModel();
if (model.select) {
//拒否リスト削除依頼
req.push(model);
}
});
this.denyListService.reqDelete(req);
}
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
this.routeService.navigateMenu();
}
}
......@@ -3,17 +3,24 @@
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<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>
<div class="common-link" (click)="onClickPrev()"><前の10件</div>
<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 class="ion-text-right">
<div class="common-link" (click)="onClickNext()">次の10件></div>
<ion-col style="padding-top:8px;">
<ion-icon role="button" name="chevron-forward-outline" size="large" (click)="onClickAfter()"></ion-icon>
</ion-col>
</ion-row>
</ion-grid>
<ion-grid style="margin-top:20px;">
@for (history of historyList;track history.getonoffDt) {
<ion-row>
<ion-col size="auto">
......
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { HistoryModel } from '../model/history.model';
import { HistoryService } from '../services/history.service';
/**
* 乗車履歴閲覧画面
......@@ -11,6 +12,7 @@ import { HistoryModel } from '../model/history.model';
styleUrls: ['./history.page.scss'],
})
export class HistoryPage implements OnInit {
searchDate?: string;
//乗車履歴
historyList?: HistoryModel[];
......@@ -18,57 +20,76 @@ export class HistoryPage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param historyService 乗降履歴サービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private historyService: HistoryService) { }
/**
* 初期化
*/
ngOnInit() {
this.historyList = new Array();
for (let i = 0; i < 10; i++) {
let historyModel: HistoryModel = new HistoryModel();
let str = String(i);
historyModel.getonoffDt = "2024/06/19 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;
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.historyList.push(historyModel);
}
let historyModel: HistoryModel = new HistoryModel();
historyModel.getonoffDt = "2024/06/19 17:10:10";
historyModel.kind = "1";
historyModel.stopName = "XXXX停留所";
historyModel.status = 0;
this.historyList.push(historyModel);
}
/**
* 戻る
*/
onClickBack(): void {
this.routeService.navigateMenu();
if (this.routeService.customerId) {
this.routeService.navigateMenu(this.routeService.customerId);
}
}
/**
* 前の10件
* 前日へ
*/
onClickPrev(): void {
onClickBefore() {
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);
}
}
}
/**
* 次の10件
* 翌日へ
*/
onClickNext(): void {
onClickAfter() {
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);
}
}
}
/**
* 日付指定
* @param event イベント情報
*/
onChangeDate(event: any): void {
if (this.routeService.customerId) {
this.historyList = this.historyService.getHistoryList(this.routeService.customerId, event.target.value);
}
}
}
......@@ -11,7 +11,7 @@ const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forChild(routes), HeaderComponent],
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomePageRoutingModule { }
......@@ -6,14 +6,14 @@
<ion-row>
<ion-col>
<ion-item>
<ion-input label="メールアドレス" [value]="email"></ion-input>
<ion-input type="email" label="メールアドレス" [(ngModel)]="email" [maxlength]="50"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-item>
<ion-input type="password" label="パスワード" [value]="password">
<ion-input type="password" label="パスワード" [(ngModel)]="password" [maxlength]="20">
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
</ion-input>
</ion-item>
......@@ -21,18 +21,18 @@
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<input type="button" class="common-button rounded" style="margin-top:20px;" value="ログイン"
(click)="onClickLogin()" />
<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 class="common-link" style="font-size:12px;margin-top:20px;" (click)="onClickRegist()">初めての方はこちら</div>
<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 class="common-link" style="font-size:12px;" (click)="onClickPassword()">パスワードを忘れた方はこちら</div>
<div role="button" class="common-link" style="font-size:12px;" (click)="onClickPassword()">パスワードを忘れた方はこちら</div>
</ion-col>
</ion-row>
</ion-grid>
......
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { LoginService } from '../services/login.service';
/**
* ログイン画面
......@@ -9,7 +10,7 @@ import { RouteService } from '../services/route.service';
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
export class HomePage implements OnInit {
//メールアドレス
email?: string;
//パスワード
......@@ -18,21 +19,43 @@ export class HomePage {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param loginService ログイン処理サービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private loginService: LoginService) { }
/**
* 初期化
*/
ngOnInit(): void {
this.email = "";
this.password = "";
}
/**
* ログイン
*/
onClickLogin(): void {
this.routeService.navigateMenu();
if (!this.email) {
alert("メールアドレスが入力されていません")
return;
}
if (!this.password) {
alert("パスワードが入力されていません");
return;
}
if (this.loginService.login(this.email, this.password)) {
//TODO
this.routeService.navigateMenu("0000");
}
}
/**
* 利用者登録
*/
onClickRegist(): void {
this.routeService.navigateUserRegist();
this.routeService.navigateUserRegist(0, "");
}
/**
......
......@@ -6,20 +6,19 @@
<ion-grid>
<ion-row>
<ion-col>
<input type="button" class="rounded menu-button" style="margin-top:20px;" value="クレジットカード一覧"
(click)="onClickCardSelect()" />
<ion-button class="rounded menu-button" style="margin-top:20px;"
(click)="onClickCardSelect()">クレジットカード一覧</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<input type="button" class="rounded menu-button" style="margin-top:10px;" value="乗降履歴"
(click)="onClickHistory()" />
<ion-button class="rounded menu-button" style="margin-top:10px;" (click)="onClickHistory()">乗降履歴</ion-button>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<input type="button" class="rounded menu-button" style="margin-top:10px;" value="拒否リスト"
(click)="onClickDenyList()" />
<ion-button class="rounded menu-button" style="margin-top:10px;" value=""
(click)="onClickDenyList()">拒否リスト</ion-button>
</ion-col>
</ion-row>
</ion-grid>
......
.menu-button {
width: 100%;
height: 60px;
--width: 100%;
--height: 60px;
--background: #f0f0f0;
--color: black;
}
\ No newline at end of file
/**
* 定期券情報
*/
export class CommuterPassModel {
//トークンID
tokenId?: string;
//定期券ID
commuterPassId?: string;
//事業者ID
agencyId: string = "";
//経路ID
routeId: string = "";
//経路名
......
......@@ -2,7 +2,13 @@
* クレジットカード情報
*/
export class CreditCardModel {
//カード番号(下4桁)
//トークンID
tokenId?: string;
//カード種類(0:JCB,1:VISA,2:MASTER,3:AMEX,4:DINERS)
cardKind?: number;
//カード番号(登録時全番号、それ以外下4桁)
cardNumber: string = "";
//カード名義人
......@@ -13,4 +19,7 @@ export class CreditCardModel {
//有効期限-月
cardMonth: string = "";
//CVC
cvc: string = "";
}
\ No newline at end of file
/**
* 拒否リスト情報
*/
export class DenyListModel {
//選択状態
select: boolean = false;
......
/**
* 乗降履歴情報
*/
export class HistoryModel {
//乗降日時
getonoffDt?: string;
......
/**
* 払戻情報
*/
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
......@@ -3,7 +3,7 @@
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-grid class="ion-no-padding" style="margin-top:20px;">
<ion-row>
<ion-col style="margin-left:20px;">
<ion-label>路線</ion-label>&nbsp;
......@@ -11,78 +11,78 @@
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>使用期間</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.useTermName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>料金区分</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.privateRangeName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>使用開始日</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.startDate}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>乗車区間(変更前)</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.getonStopName}}~{{commuterPassModel?.getoffStopName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-item>
<ion-select label="乗車停留所" [value]="getonStopId">
<ion-select label="乗車停留所" [(ngModel)]="getonStopId" (ionChange)="onChangeGetOn($event)">
@for (kv of stopList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-item>
<ion-select label="区間" [value]="getoffStopId">
<ion-select label="区間" [(ngModel)]="getoffStopId" (ionChange)="onChangeGetOff($event)">
@for (kv of stopList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>購入金額</ion-label>
</ion-col>
<ion-col class="ion-text-center">
<ion-label>{{purchasePrice|number}}円</ion-label>
<ion-col class="ion-text-right" style="margin-top:10px;">
<ion-label style="margin-right:20px;">{{purchasePrice|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>払戻金額</ion-label>
</ion-col>
<ion-col class="ion-text-center">
<ion-label>{{refundPrice|number}}円</ion-label>
<ion-col class="ion-text-right" style="margin-top:10px;">
<ion-label style="margin-right:20px;">{{refundPrice|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-input type="button" id="change" class="common-button rounded" style="margin-top:20px;" value="変更" />
<ion-col class="ion-text-center" style="margin-top:20px;">
<ion-button id="change" class="common-button rounded">変更</ion-button>
<ion-alert trigger="change" header="選択されているクレジットカードで支払い、または、払い戻ししますが、よろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickChange($event)"></ion-alert>
</ion-col>
......
import { Component, Input, OnInit } from '@angular/core';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { RouteService } from '../services/route.service';
import { PassService } from '../services/pass.service';
/**
* 定期券区間変更画面
......@@ -39,8 +40,9 @@ export class PassChangePage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param passService 定期券サービス
*/
constructor(private routeService: RouteService) {
constructor(private routeService: RouteService, private passService: PassService) {
this.cardNumber = routeService.cardNumber;
this.commuterPassModel = routeService.commuterPassModel;
}
......@@ -50,10 +52,12 @@ export class PassChangePage implements OnInit {
*/
ngOnInit(): void {
//停留所一覧
this.stopList = new Map();
for (let i = 0; i < 5; i++) {
let str = String(i + 1);
this.stopList.set(str, "停留所" + str);
if (this.commuterPassModel) {
this.stopList = this.passService.getStopList(this.commuterPassModel?.agencyId, this.commuterPassModel?.routeId);
this.getonStopId = this.commuterPassModel.getonStopId;
this.getoffStopId = this.commuterPassModel.getoffStopId;
this.purchasePrice = this.passService.calcPassAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, this.commuterPassModel.useTermId, this.commuterPassModel.priceRangeId, this.getonStopId, this.getoffStopId);
this.refundPrice = this.passService.calcRefundAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, this.commuterPassModel.startDate, this.commuterPassModel.useTermId, this.commuterPassModel.priceRangeId, this.commuterPassModel.getonStopId, this.commuterPassModel.getoffStopId, this.purchasePrice);
}
}
......@@ -70,7 +74,32 @@ export class PassChangePage implements OnInit {
onClickChange(event: any): void {
if (event.detail.role === 'confirm') {
//定期券区間変更
if (this.commuterPassModel) {
this.commuterPassModel.getonStopId = this.getonStopId ? this.getonStopId : "";
this.commuterPassModel.getoffStopId = this.getoffStopId ? this.getoffStopId : "";
this.passService.change(this.commuterPassModel);
}
}
this.routeService.navigatePassSelect(this.cardNumber);
}
/**
* 乗車停留所選択
* @param event イベント情報
*/
onChangeGetOn(event: any): void {
if (this.commuterPassModel) {
this.purchasePrice = this.passService.calcPassAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, this.commuterPassModel.useTermId, this.commuterPassModel.priceRangeId, event.target.value, this.getoffStopId);
}
}
/**
* 降車停留所選択
* @param event イベント情報
*/
onChangeGetOff(event: any): void {
if (this.commuterPassModel) {
this.purchasePrice = this.passService.calcPassAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, this.commuterPassModel.useTermId, this.commuterPassModel.priceRangeId, this.getonStopId, event.target.value);
}
}
}
......@@ -3,7 +3,7 @@
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-grid class="ion-no-padding" style="margin-top:20px;">
<ion-row>
<ion-col style="margin-left:20px;">
<ion-label>路線</ion-label>&nbsp;
......@@ -11,56 +11,56 @@
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-item>
<ion-select label="使用期間" [value]="useTermId">
<ion-select label="使用期間" [(ngModel)]="useTermId" (ionChange)="onChangeTerm($event)">
@for (kv of useTermList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>料金区分</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.privateRangeName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:15px;">
<ion-label>使用開始日</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-datetime-button datetime="datetime"></ion-datetime-button>
<ion-modal [keepContentsMounted]="true">
<ng-template>
<ion-datetime id="datetime" presentation="date" [value]="startDate"></ion-datetime>
<ion-datetime id="datetime" presentation="date" [(ngModel)]="startDate"></ion-datetime>
</ng-template>
</ion-modal>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>乗車区間</ion-label>
</ion-col>
<ion-col>
<ion-col style="margin-top:10px;">
<ion-label>{{commuterPassModel?.getonStopName}}~{{commuterPassModel?.getoffStopName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>支払金額</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{price|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-input type="button" id="continue" class="common-button rounded" style="margin-top:20px;" value="継続" />
<ion-col class="ion-text-center" style="margin-top:20px;">
<ion-button id="continue" class="common-button rounded">継続</ion-button>
<ion-alert trigger="continue" header="選択されているクレジットカードで支払いをしてよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickContinue($event)"></ion-alert>
</ion-col>
......
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { PassService } from '../services/pass.service';
/**
* 定期券継続画面
......@@ -37,8 +38,9 @@ export class PassContinuePage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param passService 定期券サービス
*/
constructor(private routeService: RouteService) {
constructor(private routeService: RouteService, private passService: PassService) {
this.cardNumber = routeService.cardNumber;
this.commuterPassModel = routeService.commuterPassModel;
}
......@@ -48,10 +50,11 @@ export class PassContinuePage implements OnInit {
*/
ngOnInit(): void {
//使用期間一覧
this.useTermList = new Map();
this.useTermList.set("1", "1ヶ月");
this.useTermList.set("2", "3ヶ月");
this.useTermList.set("6", "6ヶ月");
if (this.commuterPassModel) {
this.useTermList = this.passService.getUseTermList(this.commuterPassModel?.agencyId);
this.useTermId = this.commuterPassModel.useTermId;
this.price = this.passService.calcPassAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, this.useTermId, this.commuterPassModel.priceRangeId, this.commuterPassModel.getonStopId, this.commuterPassModel.getoffStopId);
}
}
/**
......@@ -67,7 +70,22 @@ export class PassContinuePage implements OnInit {
onClickContinue(event: any): void {
if (event.detail.role === 'confirm') {
//定期券継続
if (this.commuterPassModel) {
this.commuterPassModel.useTermId = this.useTermId ? this.useTermId : "";
this.commuterPassModel.startDate = this.startDate ? this.startDate : "";
this.passService.continue(this.commuterPassModel);
}
}
this.routeService.navigatePassSelect(this.cardNumber);
}
/**
* 使用期間選択
* @param event イベント情報
*/
onChangeTerm(event: any): void {
if (this.commuterPassModel) {
this.price = this.passService.calcPassAmount(this.commuterPassModel.agencyId, this.commuterPassModel.routeId, event.target.value, this.commuterPassModel.priceRangeId, this.commuterPassModel.getonStopId, this.commuterPassModel.getoffStopId);
}
}
}
......@@ -3,7 +3,7 @@
</ion-header>
<ion-content [fullscreen]="true">
<ion-grid>
<ion-grid class="ion-no-padding" style="margin-top:20px;">
<ion-row>
<ion-col style="margin-left:20px;">
<ion-label>乗車区間</ion-label>
......@@ -13,48 +13,48 @@
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>購入金額</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-label>{{purchasePrice|number}}円</ion-label>
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{purchaseAmount|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>普通運賃</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-label>{{normalFare|number}}円</ion-label>
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{standardFare|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>使用日数</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-label>{{useDays}}日</ion-label>
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{usedDays}}日</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>払戻手数料</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{refundFee|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="margin-left:20px;">
<ion-col style="margin-left:20px;margin-top:10px;">
<ion-label>払戻金額</ion-label>
</ion-col>
<ion-col class="ion-text-right" style="margin-right:20px;">
<ion-label>{{refundPrice|number}}円</ion-label>
<ion-col class="ion-text-right" style="margin-right:20px;margin-top:10px;">
<ion-label>{{refundAmount|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-input type="button" id="refund" class="common-button rounded" style="margin-top:20px;" value="払戻" />
<ion-col class="ion-text-center" style="margin-top:20px;">
<ion-button id="refund" class="common-button rounded">払戻</ion-button>
<ion-alert trigger="refund" header="選択されているクレジットカードで払い戻ししてよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickRefund($event)"></ion-alert>
</ion-col>
......
import { Component, OnInit } from '@angular/core';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { RouteService } from '../services/route.service';
import { PassService } from '../services/pass.service';
import { RefundModel } from '../model/refund.model';
/**
* 定期券払戻画面
......@@ -26,21 +28,22 @@ export class PassRefundPage implements OnInit {
//定期券情報
commuterPassModel?: CommuterPassModel;
//購入金額
purchasePrice: number = 0;
purchaseAmount: number = 0;
//普通運賃
normalFare: number = 0;
standardFare: number = 0;
//使用日数
useDays: number = 0;
usedDays: number = 0;
//払戻手数料
refundFee: number = 0;
//払戻金額
refundPrice: number = 0;
refundAmount: number = 0;
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param passService 定期券サービス
*/
constructor(private routeService: RouteService) {
constructor(private routeService: RouteService, private passService: PassService) {
this.cardNumber = routeService.cardNumber;
this.commuterPassModel = routeService.commuterPassModel;
}
......@@ -49,11 +52,14 @@ export class PassRefundPage implements OnInit {
* 初期化
*/
ngOnInit(): void {
this.purchasePrice = 40000;
this.normalFare = 200;
this.useDays = 30;
this.refundFee = 500;
this.refundPrice = 10500;
if (this.commuterPassModel && this.commuterPassModel.commuterPassId) {
let model: RefundModel = this.passService.getRefund(this.commuterPassModel.commuterPassId);
this.purchaseAmount = model.purchaseAmount ? model.purchaseAmount : 0;
this.standardFare = model.standardFare ? model.standardFare : 0;
this.usedDays = model.usedDays ? model.usedDays : 0;
this.refundFee = model.refundFee ? model.refundFee : 0;
this.refundAmount = model.refundAmount ? model.refundAmount : 0;
}
}
/**
......@@ -68,7 +74,10 @@ export class PassRefundPage implements OnInit {
*/
onClickRefund(event: any): void {
if (event.detail.role === 'confirm') {
//定期券継続
//定期券払戻
if (this.commuterPassModel) {
this.passService.refund(this.commuterPassModel);
}
}
this.routeService.navigatePassSelect(this.cardNumber);
}
......
......@@ -7,9 +7,9 @@
<ion-row>
<ion-col>
<ion-item>
<ion-select label="路線" [value]="routeId">
<ion-select label="路線" [(ngModel)]="routeId" (ionChange)="onChangeRoute($event)">
@for (kv of routeList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
......@@ -18,9 +18,9 @@
<ion-row>
<ion-col>
<ion-item>
<ion-select label="使用期間" [value]="useTermId">
<ion-select label="使用期間" [(ngModel)]="useTermId" (ionChange)="onChangeTerm($event)">
@for (kv of useTermList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
......@@ -29,9 +29,9 @@
<ion-row>
<ion-col>
<ion-item>
<ion-select label="料金区分" [value]="priceRangeId">
<ion-select label="料金区分" [(ngModel)]="priceRangeId" (ionChange)="onChangeRange($event)">
@for (kv of priceRangeList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
......@@ -45,7 +45,8 @@
<ion-datetime-button datetime="datetime"></ion-datetime-button>
<ion-modal [keepContentsMounted]="true">
<ng-template>
<ion-datetime id="datetime" presentation="date" [value]="startDate"></ion-datetime>
<ion-datetime id="datetime" presentation="date" [(ngModel)]="startDate"
[showDefaultButtons]="true"></ion-datetime>
</ng-template>
</ion-modal>
</ion-col>
......@@ -53,9 +54,9 @@
<ion-row>
<ion-col>
<ion-item>
<ion-select label="乗車停留所" [value]="getonStopId">
<ion-select label="乗車停留所" [(ngModel)]="getonStopId" (ionChange)="onChangeGetOn($event)">
@for (kv of stopList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
......@@ -64,25 +65,25 @@
<ion-row>
<ion-col>
<ion-item>
<ion-select label="区間" [value]="getoffStopId">
<ion-select label="区間" [(ngModel)]="getoffStopId" (ionChange)="onChangeGetOff($event)">
@for (kv of stopList|keyvalue;track kv.key) {
<ion-select-option value="kv.key">{{kv.value}}</ion-select-option>
<ion-select-option [value]="kv.key">{{kv.value}}</ion-select-option>
}
</ion-select>
</ion-item>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-label>支払金額</ion-label>
<ion-col>
<ion-label style="margin-left:16px;">支払金額</ion-label>
</ion-col>
<ion-col class="ion-text-center">
<ion-label>{{price|number}}円</ion-label>
<ion-col class="ion-text-right">
<ion-label style="margin-right:20px;">{{price|number}}円</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-input type="button" id="addpass" class="common-button rounded" style="margin-top:20px;" value="追加" />
<ion-button id="addpass" class="common-button rounded" style="margin-top:20px;">追加</ion-button>
<ion-alert trigger="addpass" header="選択されているクレジットカードで支払いをしてよろしいですか?" [buttons]="confirmButtons"
(didDismiss)="onClickAdd($event)"></ion-alert>
</ion-col>
......
import { KeyValue } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { RouteService } from '../services/route.service';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { PassService } from '../services/pass.service';
/**
* 定期券登録画面
......@@ -46,42 +47,79 @@ export class PassRegistPage implements OnInit {
getoffStopId?: string;
//支払金額
price: number = 0;
//事業者ID
agencyId: string = "";
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param passService 定期券サービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private passService: PassService) { }
/**
* 初期化
*/
ngOnInit(): void {
//路線一覧
this.routeList = new Map();
for (let i = 0; i < 5; i++) {
let str = String(i + 1);
this.routeList.set(str, "路線" + str);
}
//TODO 事業者IDはどうやって決める?
this.routeList = this.passService.getRouteList(this.agencyId);
this.routeId = this.routeList.keys().next().value;
//使用期間一覧
this.useTermList = new Map();
this.useTermList.set("1", "1ヶ月");
this.useTermList.set("2", "3ヶ月");
this.useTermList.set("6", "6ヶ月");
this.useTermList = this.passService.getUseTermList(this.agencyId);
this.useTermId = this.useTermList.keys().next().value;
//料金区分一覧
this.priceRangeList = new Map();
this.priceRangeList.set("1", "大人");
this.priceRangeList.set("2", "小児");
this.priceRangeList.set("3", "学生");
this.priceRangeList = this.passService.getPriceRangeList(this.agencyId);
this.priceRangeId = this.priceRangeList.keys().next().value;
//停留所一覧
this.stopList = new Map();
for (let i = 0; i < 5; i++) {
let str = String(i + 1);
this.stopList.set(str, "停留所" + str);
this.stopList = this.passService.getStopList(this.agencyId, this.routeList.values().next().value);
this.getonStopId = this.stopList.keys().next().value;
this.getoffStopId = this.stopList.keys().next().value;
}
/**
* 路線選択
* @param event イベント情報
*/
onChangeRoute(event: any): void {
this.stopList = this.passService.getStopList(this.agencyId, event.target.value);
this.price = this.passService.calcPassAmount(this.agencyId, event.target.value, this.useTermId, this.priceRangeId, this.getonStopId, this.getoffStopId);
}
/**
* 使用期間選択
* @param event イベント情報
*/
onChangeTerm(event: any): void {
this.price = this.passService.calcPassAmount(this.agencyId, this.routeId, event.target.value, this.priceRangeId, this.getonStopId, this.getoffStopId);
}
/**
* 料金区分選択
* @param event イベント情報
*/
onChangeRange(event: any): void {
this.price = this.passService.calcPassAmount(this.agencyId, this.routeId, this.useTermId, event.target.value, this.getonStopId, this.getoffStopId);
}
/**
* 乗車停留所選択
* @param event イベント情報
*/
onChangeGetOn(event: any): void {
this.price = this.passService.calcPassAmount(this.agencyId, this.routeId, this.useTermId, this.priceRangeId, event.target.value, this.getoffStopId);
}
/**
* 降車停留所選択
* @param event イベント情報
*/
onChangeGetOff(event: any): void {
this.price = this.passService.calcPassAmount(this.agencyId, this.routeId, this.useTermId, this.priceRangeId, this.getonStopId, event.target.value);
}
/**
......@@ -97,6 +135,15 @@ export class PassRegistPage implements OnInit {
onClickAdd(event: any): void {
if (event.detail.role === 'confirm') {
//定期券登録
let model: CommuterPassModel = new CommuterPassModel();
model.tokenId = this.routeService.tokenId;
model.routeId = this.routeId ? this.routeId : "";
model.startDate = this.startDate ? this.startDate : "";
model.useTermId = this.useTermId ? this.useTermId : "";
model.priceRangeId = this.priceRangeId ? this.priceRangeId : "";
model.getonStopId = this.getonStopId ? this.getonStopId : "";
model.getoffStopId = this.getoffStopId ? this.getoffStopId : "";
this.passService.regist(model);
}
this.routeService.navigatePassSelect(this.routeService.cardNumber);
}
......
<div class="rounded border">
<table width="100%">
<tr>
<td>
<table width="100%">
<tr>
<td colspan="2" style="padding-top:10px;padding-left:10px;">
{{model?.routeName}}
</td>
</tr>
<tr>
<td style="padding-top:10px;padding-left:10px;">
<span>使用開始日</span>
</td>
<td style="padding-top:10px;">
{{model?.startDate}}
</td>
</tr>
<tr>
<td style="padding-top:10px;padding-left:10px;">
<span>使用期間</span>
</td>
<td style="padding-top:10px;">
{{model?.useTermName}}
</td>
</tr>
<tr>
<td style="padding-top:10px;padding-left:10px;">
<span>料金区分</span>
</td>
<td style="padding-top:10px;">
{{model?.privateRangeName}}
</td>
</tr>
<tr>
<td style="padding-top:10px;padding-left:10px;padding-bottom:10px;">
<span>乗車区間</span>
</td>
<td style="padding-top:10px;padding-bottom:10px;">
{{model?.getonStopName}}~{{model?.getoffStopName}}
</td>
</tr>
</table>
</td>
<td style="vertical-align: top;padding-top:20px;padding-right:10px;">
<table>
<tr>
<td>
<div class="common-link" (click)="onClickChange()">変更</div>
<div class="common-link" (click)="onClickContinue()">継続</div>
<div class="common-link" (click)="onClickRefund()">払戻</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
\ No newline at end of file
<div class="rounded border">
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col>
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col style="padding-top:10px;padding-left:10px;">
<ion-label>{{model?.routeName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;padding-left:10px;" size="auto">
<div style="width:120px;">使用開始日</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{model?.startDate}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;padding-left:10px;" size="auto">
<div style="width:120px;">使用期間</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{model?.useTermName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;padding-left:10px;" size="auto">
<div style="width:120px;">料金区分</div>
</ion-col>
<ion-col style="padding-top:10px;">
<ion-label>{{model?.privateRangeName}}</ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col style="padding-top:10px;padding-left:10px;padding-bottom:10px;" size="auto">
<div style="width:120px;">乗車区間</div>
</ion-col>
<ion-col style="padding-top:10px;padding-bottom:10px;">
<ion-label>{{model?.getonStopName}}~{{model?.getoffStopName}}</ion-label>
</ion-col>
</ion-row>
</ion-grid>
</ion-col>
<ion-col style="vertical-align: top;padding-top:20px;padding-right:10px;" size="auto">
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col size="auto">
<div class="common-link" (click)="onClickChange()">変更</div>
<div class="common-link" (click)="onClickContinue()">継続</div>
<div class="common-link" (click)="onClickRefund()">払戻</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-col>
</ion-row>
</ion-grid>
</div>
\ No newline at end of file
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CommuterPassModel } from 'src/app/model/commuter-pass.model';
/**
......@@ -9,6 +10,9 @@ import { CommuterPassModel } from 'src/app/model/commuter-pass.model';
selector: 'app-pass-info',
templateUrl: './pass-info.component.html',
styleUrls: ['./pass-info.component.scss'],
imports: [
IonicModule
]
})
export class PassInfoComponent {
@Input() model?: CommuterPassModel;
......
......@@ -10,16 +10,15 @@ import { PassSelectPage } from './pass-select.page';
import { HeaderComponent } from '../common/header/header.component';
import { PassInfoComponent } from './component/pass-info/pass-info.component';
import { PassInfoComponent } from './pass-info/pass-info.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
PassSelectPageRoutingModule,
HeaderComponent,
PassInfoComponent
PassInfoComponent,
HeaderComponent
],
declarations: [PassSelectPage]
})
......
......@@ -22,7 +22,7 @@
</div>
}
</div>
<div style="margin-top:10px;text-align:center;" (click)="onClickAddPass()">
<span class="add-link">+&nbsp;定期券を追加する</span>
<div role="button" style="margin-top:10px;text-align:center;" class="add-link" (click)="onClickAddPass()">
<span>+&nbsp;定期券を追加する</span>
</div>
</ion-content>
\ No newline at end of file
.add-link {
color: #0CACCD;
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { RouteService } from '../services/route.service';
import { PassService } from '../services/pass.service';
/**
* 定期券選択画面
......@@ -19,8 +20,9 @@ export class PassSelectPage implements OnInit {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param passServiec 定期券サービス
*/
constructor(private routeService: RouteService) {
constructor(private routeService: RouteService, private passService: PassService) {
this.cardNumber = routeService.cardNumber;
}
......@@ -28,19 +30,8 @@ export class PassSelectPage implements OnInit {
* 初期化
*/
ngOnInit() {
this.commuterPassList = new Array();
for (let i = 0; i < 2; i++) {
let model: CommuterPassModel = new CommuterPassModel();
model.routeId = "00000" + String(i);
model.routeName = "【◯◯◯系統】XXXXX→XXXXX行き";
model.startDate = "2024/07/01";
model.useTermId = "2";
model.useTermName = "3ヶ月";
model.priceRangeId = "0";
model.privateRangeName = "大人";
model.getonStopName = "XXXXX";
model.getoffStopName = "XXXXX";
this.commuterPassList.push(model);
if (this.routeService.tokenId) {
this.commuterPassList = this.passService.getList(this.routeService.tokenId);
}
}
......
......@@ -29,8 +29,7 @@
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<input type="button" class="common-button rounded" style="margin-top:20px;" value="更新"
(click)="onClickUpdate()" />
<ion-button class="common-button rounded" style="margin-top:20px;" (click)="onClickUpdate()">更新</ion-button>
</ion-col>
</ion-row>
</ion-grid>
......
import { Component } from '@angular/core';
import { RouteService } from '../services/route.service';
import { UserService } from '../services/user.service';
/**
* パスワード更新画面
......@@ -18,8 +19,9 @@ export class PasswordUpdatePage {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param userService 利用者サービス
*/
constructor(private routeService: RouteService) { }
constructor(private routeService: RouteService, private userService: UserService) { }
/**
* 閉じる
......@@ -33,7 +35,7 @@ export class PasswordUpdatePage {
*/
onClickUpdate(): void {
//パスワード更新
this.userService.changePassword(this.email, this.password);
this.routeService.navigateHome();
}
}
import { TestBed } from '@angular/core/testing';
import { CardService } from './card.service';
describe('CardService', () => {
let service: CardService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CardService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { CreditCardModel } from '../model/credit-card.model';
/**
* クレジットカードサービス
*/
@Injectable({
providedIn: 'root'
})
export class CardService {
/**
* コンストラクタ
*/
constructor() { }
/**
* クレジットカード情報一覧取得
* @param customerId 利用者ID
*/
getList(customerId?: string): 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";
cardList.push(model);
}
return cardList;
}
/**
* クレジットカード情報登録
* @param customerId 利用者ID
* @param model クレジットカード情報
*/
regist(customerId?: string, model?: CreditCardModel) {
//TODO
}
/**
* クレジットカード情報削除
* @param tokenId トークンID
*/
delete(tokenId?: string): void {
//TODO
}
}
import { TestBed } from '@angular/core/testing';
import { DenylistService } from './denylist.service';
describe('DenylistService', () => {
let service: DenylistService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DenylistService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { DenyListModel } from '../model/deny-list.model';
/**
* 拒否リストサービス
*/
@Injectable({
providedIn: 'root'
})
export class DenylistService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 拒否リスト取得
* @param customerId 利用者ID
*/
getList(customerId: string): DenyListModel[] {
//TODO
let denyList = new Array();
for (let i = 0; i < 4; i++) {
let denyListModel = new DenyListModel();
let str = String(i);
denyListModel.getonStopId = str;
denyListModel.getonStopName = "XXXX停留所";
denyListModel.getoffStopName = "YYYYY停留所";
denyListModel.getonDt = "2024/06/20 10:00:01";
denyListModel.getoffDt = "2024/06/20 10:30:02";
denyListModel.amount = 1000;
denyList.push(denyListModel);
}
return denyList;
}
/**
* 拒否リスト削除依頼
* @param list 依頼対象
*/
reqDelete(list: DenyListModel[]): void {
//TODO
}
}
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';
/**
* 乗降履歴サービス
*/
@Injectable({
providedIn: 'root'
})
export class HistoryService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 乗降履歴一覧取得
* @param customerId 利用者ID
* @param searchDate 検索対象日
* @returns 乗降履歴一覧
*/
getHistoryList(customerId: string, searchDate?: string): 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;
}
}
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 { from, Observable } from 'rxjs';
/**
* ログインサービス
*/
@Injectable({
providedIn: 'root'
})
export class LoginService {
/**
* コンストラクタ
*/
constructor() { }
/**
* ログインサービス
* @param email メールアドレス
* @param password パスワード
* @returns ログイン結果
*/
public login(email: string, password: string): boolean {
// TODO
return true;
}
}
import { TestBed } from '@angular/core/testing';
import { PassService } from './pass.service';
describe('PassService', () => {
let service: PassService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PassService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { CommuterPassModel } from '../model/commuter-pass.model';
import { RefundModel } from '../model/refund.model';
/**
* 定期券サービス
*/
@Injectable({
providedIn: 'root'
})
export class PassService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 定期一覧取得
* @param tokenId トークンID
*/
getList(tokenId: string): CommuterPassModel[] {
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;
}
/**
* 定期券登録
* @param model 定期券情報
*/
regist(model: CommuterPassModel): void {
//TODO
}
/**
* 定期券区間変更
* @param model 定期券情報
*/
change(model: CommuterPassModel): void {
//TODO
}
/**
* 定期券継続
* @param model 定期券情報
*/
continue(model: CommuterPassModel): void {
//TODO
}
/**
* 定期券払戻
* @param model 定期券情報
*/
refund(model: CommuterPassModel): void {
//TODO
}
/**
* 路線一覧取得
* @param agencyId 事業者ID
* @returns 路線一覧
*/
getRouteList(agencyId: string): Map<string, string> {
//路線一覧
let routeList = new Map();
for (let i = 0; i < 5; i++) {
let str = String(i + 1);
routeList.set(str, "路線" + str);
}
return routeList;
}
/**
* 使用期間一覧取得
* @param agencyId 事業者ID
* @returns 使用期間一覧
*/
getUseTermList(agencyId: string): Map<string, string> {
let useTermList = new Map();
useTermList.set("1", "1ヶ月");
useTermList.set("3", "3ヶ月");
useTermList.set("6", "6ヶ月");
return useTermList;
}
/**
* 料金区分一覧取得
* @param agencyId 事業者ID
* @returns 料金区分一覧
*/
getPriceRangeList(agencyId: string): Map<string, string> {
let priceRangeList = new Map();
priceRangeList.set("1", "大人");
priceRangeList.set("2", "小児");
priceRangeList.set("3", "学生");
return priceRangeList;
}
/**
* 停留所一覧取得
* @param agencyId 事業者ID
* @param routeId 路線ID
* @returns 停留所一覧
*/
getStopList(agencyId: string, routeId: string): Map<string, string> {
let stopList = new Map();
for (let i = 0; i < 5; i++) {
let str = String(i + 1);
stopList.set(str, "停留所" + str);
}
return stopList;
}
/**
* 定期券料金計算
*
* @param agencyId 事業者ID
* @param routeId 路線ID
* @param useTermId 使用期間
* @param priceRangeId 料金区分
* @param getonStopId 乗車停留所
* @param getoffStopId 降車停留所
*/
calcPassAmount(agencyId: string, routeId?: string, useTermId?: string, priceRangeId?: string, getonStopId?: string, getoffStopId?: string): number {
//TODO
//以下はダミー
//通常運賃
let getonStop = Number(getonStopId);
let getoffStop = Number(getoffStopId);
let unit = (getoffStop - getonStop) >= 0 ? (getoffStop - getonStop) : (getonStop - getoffStop);
unit = unit * 100;
let one = unit * 30 * 0.75;
let three = one * 3 * 0.95;
let six = one * 6 * 0.9;
let ret = 0;
if (useTermId == "1") {
ret = one;
} else if (useTermId == "2") {
ret = three;
} else {
ret = six;
}
if (priceRangeId == "2") {
ret = ret * 0.5;
} else if (priceRangeId == "3") {
ret = ret * 0.6;
}
return Math.floor(ret);
}
/**
* 定期券払戻料金計算
* @param agencyId 事業者ID
* @param routeId 路線ID
* @param startDate 使用開始日
* @param useTermId 使用期間
* @param priceRangeId 料金区分
* @param getonStopId 乗車停留所ID
* @param getoffStopId 降車停留所ID
*/
calcRefundAmount(agencyId: string, routeId?: string, startDate?: string, useTermId?: string, priceRangeId?: string, getonStopId?: string, getoffStopId?: string, purchaseAmount?: number): number {
//TODO
//以下はダミー
//通常運賃
let getonStop = Number(getonStopId);
let getoffStop = Number(getoffStopId);
let unit = (getoffStop - getonStop) >= 0 ? (getoffStop - getonStop) : (getonStop - getoffStop);
unit = unit * 100;
if (priceRangeId == "2") {
unit = unit * 0.5;
} else if (priceRangeId == "3") {
unit = unit * 0.6;
}
//残日数計算
let termDay = 0;
let now = new Date();
if (startDate) {
let start = new Date(startDate);
termDay = (now.getTime() - start.getTime()) / 86400000;
}
if (useTermId == "1") {
termDay = 30 - termDay;
} else if (useTermId == "3") {
termDay = 90 - termDay;
} else if (useTermId == "6") {
termDay = 180 - termDay;
}
let amount = 0;
if (purchaseAmount) {
amount = purchaseAmount - (termDay * unit) - 500;
}
amount = amount < 0 ? 0 : amount;
return Math.floor(amount);
}
/**
* 払戻情報取得
* @param commuterPassId 定期券ID
*/
getRefund(commuterPassId: string): RefundModel {
//TODO
//↓以下はダミー
let ret = new RefundModel();
ret.purchaseAmount = this.calcPassAmount("", "", "3", "1", "1", "5");
//通常運賃
let getonStop = 1;
let getoffStop = 5;
let unit = (getoffStop - getonStop) >= 0 ? (getoffStop - getonStop) : (getonStop - getoffStop);
ret.standardFare = unit * 100;
//使用日数計算
let now = new Date();
let start = new Date("2024/07/01");
ret.usedDays = Math.floor((now.getTime() - start.getTime()) / 86400000);
//残日数
let termDay = 90 - ret.usedDays;
//払戻手数料
ret.refundFee = 500;
let amount = ret.purchaseAmount - (termDay * ret.standardFare) - ret.refundFee;
amount = amount < 0 ? 0 : amount;
ret.refundAmount = Math.floor(amount);
return ret;
}
}
......@@ -15,6 +15,15 @@ export class RouteService {
//定期券情報
commuterPassModel?: CommuterPassModel;
//モード
mode: number = 0;
//利用者ID
customerId?: string;
//トークンID
tokenId?: string;
/**
* コンストラクタ
* @param router Router
......@@ -30,8 +39,11 @@ export class RouteService {
/**
* 利用者登録画面へ遷移
* @param mode 0:登録、1:更新
*/
navigateUserRegist() {
navigateUserRegist(mode: number, customerId: string) {
this.mode = mode;
this.customerId = customerId;
this.router.navigate(['user-regist']);
}
......@@ -45,7 +57,8 @@ export class RouteService {
/**
* メニュー画面へ遷移
*/
navigateMenu() {
navigateMenu(customerId: string) {
this.customerId = customerId;
this.router.navigate(['menu']);
}
......@@ -67,7 +80,8 @@ export class RouteService {
* 定期券選択画面へ遷移
* @param cardNumber カード番号
*/
navigatePassSelect(cardNumber?: string) {
navigatePassSelect(tokenId?: string, cardNumber?: string) {
this.tokenId = tokenId;
this.cardNumber = cardNumber;
this.router.navigate(['pass-select']);
}
......
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';
/**
* 利用者サービス
*/
@Injectable({
providedIn: 'root'
})
export class UserService {
/**
* コンストラクタ
*/
constructor() { }
/**
* 利用者情報取得
* @param customerId 利用者ID
*/
getInfo(customerId: string): 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;
}
/**
* 利用者情報登録
* @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
}
}
......@@ -7,21 +7,21 @@
<ion-row>
<ion-col>
<ion-item>
<ion-input label="氏名" [value]="name"></ion-input>
<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 label="フリガナ" [value]="nameKana"></ion-input>
<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"></ion-input>
<ion-input type="tel" label="電話番号" [value]="phoneNumber" [maxlength]="20"></ion-input>
</ion-item>
</ion-col>
</ion-row>
......@@ -29,7 +29,7 @@
<ion-col>
@if (mode === 0) {
<ion-item>
<ion-input type="email" label="メールアドレス" [value]="email"></ion-input>
<ion-input type="email" label="メールアドレス" [value]="email" [maxlength]="50"></ion-input>
</ion-item>
} @else {
<ion-label>メールアドレス</ion-label><ion-label>{{email}}</ion-label>
......@@ -39,7 +39,7 @@
<ion-row>
<ion-col>
<ion-item>
<ion-input type="password" label="パスワード" [value]="password">
<ion-input type="password" label="パスワード" [value]="password" [maxlength]="20">
<ion-input-password-toggle slot="end"></ion-input-password-toggle>
</ion-input>
</ion-item>
......@@ -55,18 +55,18 @@
<ion-row>
@if (mode === 0) {
<ion-col class="ion-text-center">
<input type="button" id="regist" class="common-button rounded" style="margin-top:20px;" value="登録" />
<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">
<input type="button" id="update" class="common-button rounded" style="margin-top:20px;" value="更新" />
<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">
<input type="button" id="withdraw" class="common-button rounded" style="margin-top:20px;" value="退会" />
<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>
......
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';
/**
* 利用者登録画面
......@@ -9,7 +11,7 @@ import { RouteService } from '../services/route.service';
templateUrl: './user-regist.page.html',
styleUrls: ['./user-regist.page.scss'],
})
export class UserRegistPage {
export class UserRegistPage implements OnInit {
//モード(0:登録、1:更新)
mode: number = 0;
//氏名
......@@ -22,6 +24,8 @@ export class UserRegistPage {
email?: string;
//パスワード
password?: string;
//利用者ID
customerId?: string;
public confirmButtons = [
{
......@@ -37,8 +41,26 @@ export class UserRegistPage {
/**
* コンストラクタ
* @param routeService 画面遷移サービス
* @param userService 利用者情報サービス
*/
constructor(private routeService: RouteService) { }
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.name = model.name;
this.nameKana = model.nameKana;
this.phoneNumber = model.phoneNumber;
this.email = model.email;
this.password = model.password;
}
}
/**
* 閉じる
......@@ -54,6 +76,13 @@ export class UserRegistPage {
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();
}
......@@ -65,6 +94,14 @@ export class UserRegistPage {
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();
}
......@@ -76,8 +113,10 @@ export class UserRegistPage {
onClickWithdraw(event: any): void {
if (event.detail.role === 'confirm') {
//退会
if (this.customerId) {
this.userService.withdraw(this.customerId);
}
}
this.routeService.navigateHome();
}
}
......@@ -37,14 +37,18 @@
@import "@ionic/angular/css/palettes/dark.system.css";
.common-button {
background-color: #F19024;
color: white;
height: 40px;
padding-left: 20px;
padding-right: 20px;
--background: #F19024;
--color: white;
--height: 40px;
--padding-left: 20px;
--padding-right: 20px;
}
.common-link {
text-decoration: underline;
color: #0CACCD;
}
.add-link {
color: #0CACCD;
}
\ No newline at end of file
......@@ -53,3 +53,8 @@ import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
(window as any).global = window;
(window as any).process = {
env: { DEBUG: undefined },
};
\ No newline at end of file
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./out-tsc/app",
"types": []
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"types": [
"node"
],
"module": "es2020",
"lib": [
"es2018",
"dom"
]
},
"files": [
"src/main.ts",
......@@ -11,5 +27,11 @@
],
"include": [
"src/**/*.d.ts"
]
],
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
\ 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