LifeSports Application(ReactNative & Nest.js) - 18. payment-service, UI
64632 ワード
#1支払ページ
決済ページを作成しましょう支払ページは、次の場合に使用できます.
1)管理職データ作成後直ちに支払う
2)大管データ生成後の次の日に支払う方法、次の日にデータを削除する方法
上記の例を考慮して、UIおよびRidexモジュールを最初に実装し、支払い-サービスおよびリース-サービスを変更します.
#2冗長モジュール
以前に作成した文書からrentalIdをPaymentScreenに移行したので、この値を受け入れ、拡張データを受信するモジュールを作成します.
import client from './client';
export const rental = ({
price,
borrower,
tel,
userId,
date,
time,
mapId,
mapName
}) => client.post('http://10.0.2.2:8000/rental-service/rental', {
price,
borrower,
tel,
userId,
date,
time,
mapId,
mapName
});
export const getRental = rentalId => client.get(`http://10.0.2.2:8000/rental-service/${rentalId}/rental`);
export const getRentals = userId => client.get(`http://10.0.2.2:8000/rental-service/${userId}/rentals`);
import { createAction, handleActions } from "redux-actions";
import createRequestSaga, { createRequestActionTypes } from "../lib/createRequestSaga";
import * as rentalAPI from '../lib/api/rental';
import { takeLatest } from "@redux-saga/core/effects";
const INITIALIZE = 'rental/INITIALIZE';
const [
GET_RENTAL,
GET_RENTAL_SUCCESS,
GET_RENTAL_FAILURE,
] = createRequestActionTypes('rental/GET_RENTAL');
const [
GET_RENTALS,
GET_RENTALS_SUCCESS,
GET_RENTALS_FAILURE
] = createRequestActionTypes('rental/GET_RENTALS');
export const getRental = createAction(GET_RENTAL, rentalId => rentalId);
export const getRentals = createAction(GET_RENTALS, userId => userId);
const getRentalSaga = createRequestSaga(GET_RENTAL, rentalAPI.getRental);
const getRentalsSaga = createRequestSaga(GET_RENTALS, rentalAPI.getRentals);
export function* rentalsSaga() {
yield takeLatest(GET_RENTAL, getRentalSaga);
yield takeLatest(GET_RENTALS, getRentalsSaga);
}
const initialState = {
rental: null,
rentals: null,
error: null,
};
const rentals = handleActions(
{
[INITIALIZE]: (state => initialState),
[GET_RENTAL_SUCCESS]: (state, { payload: rental }) => ({
...state,
rental
}),
[GET_RENTAL_FAILURE]: (state, { payload: error }) => ({
...state,
error
}),
[GET_RENTALS_SUCCESS]: (state, { payload: rentals }) => ({
...state,
rentals,
}),
[GET_RENTALS_FAILURE]: (state, { payload: error }) => ({
...state,
error,
}),
},
initialState,
);
export default rentals;
rentalIdをメディアとして拡張データをロードし、userIdをメディアとしてユーザーの拡張データをロードするモジュール.支払いモジュールを完了し、UIを作成します.import client from './client';
export const requestPayment = ({
paymentName,
payer,
rentalId,
price
}) => client.post('http://10.0.2.2:8000/payment-service/payment', {
paymentName,
payer,
rentalId,
price
});
export const getPayments = payer => client.get(`http://10.0.2.2:8000/payment-service/${payer}/payments`);
export const getPayment = paymentId => client.get(`http://10.0.2.2:8000/payment-service/${paymentId}/payment`);
これは支払請求モジュールです.import { createAction, handleActions } from "redux-actions";
import createRequestSaga, { createRequestActionTypes } from "../lib/createRequestSaga";
import * as paymentAPI from '../lib/api/payment';
import { takeLatest } from "@redux-saga/core/effects";
const CHANGE_FIELD = 'payment/CHANGE_FIELD';
const INITIAILIZE = 'payment/INITIALIZE';
const [
REQUEST_PAYMENT,
REQUEST_PAYMENT_SUCCESS,
REQUEST_PAYMENT_FAILURE,
] = createRequestActionTypes('payment/REQUEST_PAYMENT');
export const changeField = createAction(CHANGE_FIELD, ({
key,
value
}) => ({
key,
value
}));
export const initialize = createAction(INITIAILIZE);
export const requestPayment = createAction(REQUEST_PAYMENT, ({
paymentName,
payer,
rentalId,
price
}) => ({
paymentName,
payer,
rentalId,
price
}));
const requestPaymentSaga = createRequestSaga(REQUEST_PAYMENT, paymentAPI.requestPayment);
export function* paymentSaga() {
yield takeLatest(REQUEST_PAYMENT, requestPaymentSaga);
}
const intialState = {
paymentName: null,
payer: null,
rentalId: null,
price: null,
payment: null,
paymentError: null,
};
const payment = handleActions(
{
[INITIAILIZE]: state => intialState,
[CHANGE_FIELD]: (state, { payload: { key, value }}) => ({
...state,
[key]: value
}),
[REQUEST_PAYMENT_SUCCESS]: (state, { payload: payment }) => ({
...state,
payment
}),
[REQUEST_PAYMENT_FAILURE]: (state, { payload: paymentError }) => ({
...state,
paymentError
}),
},
intialState,
);
export default payment;
またpaymentモジュールを作成して、支払データをインポートします.import { createAction, handleActions } from "redux-actions";
import createRequestSaga, { createRequestActionTypes } from "../lib/createRequestSaga";
import * as paymentAPI from '../lib/api/payment';
import { takeLatest } from "@redux-saga/core/effects";
const INITIALIZE = 'payment/INITIALIZE';
const [
GET_PAYMENT,
GET_PAYMENT_SUCCESS,
GET_PAYMENT_FAILURE,
] = createRequestActionTypes('payment/GET_PAYMENT');
const [
GET_PAYMENTS,
GET_PAYMENTS_SUCCESS,
GET_PAYMENTS_FAILURE
] = createRequestActionTypes('payment/GET_PAYMENTS');
export const initialize = createAction(INITIALIZE);
export const getPayment = createAction(GET_PAYMENT, paymentId => paymentId);
export const getPayments = createAction(GET_PAYMENTS, payer => payer);
const getPaymentSaga = createRequestSaga(GET_PAYMENT, paymentAPI.getPayment);
const getPaymentsSaga = createRequestSaga(GET_PAYMENTS, paymentAPI.getPayments);
export function* paymentsSaga() {
yield takeLatest(GET_PAYMENT, getPaymentSaga);
yield takeLatest(GET_PAYMENTS, getPaymentsSaga);
}
const initialState = {
payment: null,
payments: null,
error: null,
};
const payments = handleActions(
{
[INITIALIZE]: (state => initialState),
[GET_PAYMENT_SUCCESS]: (state, { payload: payment }) => ({
...state,
payment
}),
[GET_PAYMENT_FAILURE]: (state, { payload: error }) => ({
...state,
error
}),
[GET_PAYMENTS_SUCCESS]: (state, { payload: payments }) => ({
...state,
payments,
}),
[GET_PAYMENTS_FAILURE]: (state, { payload: error }) => ({
...state,
error,
}),
},
initialState,
);
export default payments;
payment、rentalsモジュールが完了しました.支払いページUIを完了しましょう.#3 UI
import React, { useEffect } from 'react';
import { useNavigation, useRoute } from '@react-navigation/native';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { changeField, initialize, requestPayment } from '../../../modules/payment';
import StyledTextInput from '../../../styles/common/StyledTextInput';
import palette from '../../../styles/palette';
import { getRental } from '../../../modules/rentals';
import Loading from '../../../styles/common/Loading';
const PaymentFragment = () => {
const dispatch = useDispatch();
const route = useRoute();
const navigation = useNavigation();
const {
paymentName,
payer,
rentalId,
price,
payment,
paymentError,
rental,
error
} = useSelector(({
rentals,
payment,
}) => ({
paymentName: payment.paymentName,
payer: payment.payer,
rentalId: payment.rentalId,
price: payment.price,
payment: payment.payment,
paymentError: payment.paymentError,
rental: rentals.rental
}));
const onPayment = () => {
dispatch(requestPayment({
paymentName,
payer,
rentalId,
price
}));
};
useEffect(() => {
dispatch(getRental(route.params.rentalId));
}, [dispatch, route]);
useEffect(() => {
dispatch(changeField({
key: 'paymentName',
value: rental.mapName
}))
}, [dispatch, rental]);
useEffect(() => {
dispatch(changeField({
key: 'payer',
value: rental.borrower
}))
}, [dispatch, rental]);
useEffect(() => {
dispatch(changeField({
key: 'rentalId',
value: rental.rentalId
}))
}, [dispatch, rental]);
useEffect(() => {
dispatch(changeField({
key: 'price',
value: rental.price
}))
}, [dispatch, rental]);
useEffect(() => {
if(payment) {
navigation.goBack();
dispatch(initialize())
}
if(paymentError) {
// setError
}
}, [dispatch, payment]);
useEffect(() => {
if(error) {
// setError
}
}, [error]);
return(
rental ?
<View style={ styles.container }>
<View style={ styles.row } >
<Text style={ styles.label } >
대관 번호
</Text>
<StyledTextInput placeholderTextColor={ palette.black[0] }
value={ rental.rentalId }
/>
</View>
<View style={ styles.row }>
<Text style={ styles.label }>
결제 내역
</Text>
<StyledTextInput placeholderTextColor={ palette.gray[3] }
value={ rental.mapName }
/>
</View>
<View style={ styles.row }>
<Text style={ styles.label }>
결제 금액
</Text>
<StyledTextInput placeholderTextColor={ palette.gray[3] }
value={ rental.price.toString() }
/>
</View>
<View style={ styles.row }>
<Text style={ styles.label } >
사용자명
</Text>
<StyledTextInput placeholderTextColor={ palette.gray[3] }
value={ rental.borrower }
/>
</View>
<View style={ styles.row } >
<Text style={ styles.label }>
체육관 전화번호
</Text>
<StyledTextInput placeholderTextColor={ palette.gray[3] }
value={ rental.tel }
/>
</View>
<View style={ styles.row } >
<Text style={ styles.label } >
대관 날짜
</Text>
<StyledTextInput placeholderTextColor={ palette.gray[3] }
value={ rental.date + "\t" + rental.time }
/>
</View>
<View style={ styles.button_container }>
<TouchableOpacity style={ styles.shape }
onPress={ onPayment }
>
<Text style={ styles.font }>
결제하기
</Text>
</TouchableOpacity>
</View>
</View> : <Loading />
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
width: '90%',
height: '90%',
backgroundColor: palette.white[0],
},
row: {
flexDirection: 'row',
alignItems: 'center',
overflow: 'hidden'
},
label: {
fontWeight: 'bold',
padding: 10,
},
button_container: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 30
},
shape: {
justifyContent: 'center',
alignItems: 'center',
width: '80%',
height: 70,
backgroundColor: palette.blue[2]
},
font: {
justifyContent: 'center',
alignItems: 'center',
fontWeight: 'bold',
fontSize: 20,
color: palette.white[0]
}
});
export default PaymentFragment;
PaymentFragmentは、前ページから取得したrentalIdをメディアとして使用して、拡張データを取得する.次に、管理データがstateに格納されている場合は、useEffect hookを使用して支払いに必要なstate値を保存します.したがって、ステータス値を使用して支払いを行うことができます.import React from 'react';
import { StyleSheet, View } from 'react-native';
import PaymentContent from './components/PaymentFragment';
const PaymentScreen = () => {
return(
<View style={ styles.container }>
<PaymentContent />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
export default PaymentScreen;
import React from 'react';
import { StyleSheet, TextInput } from 'react-native';
import palette from '../palette';
const StyledTextInput = ({
inputAccessoryViewID,
placeholder,
placeholderTextColor,
onChange,
value
}) => {
return(
<TextInput style={ styles.input }
placeholder={ placeholder }
placeholderTextColor={ placeholderTextColor }
inputAccessoryViewID={ inputAccessoryViewID }
onChange={ onChange }
value={ value }
/>
);
};
const styles = StyleSheet.create({
input: {
width: 300,
height: 40,
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: palette.white[0],
color: palette.black[0],
fontSize: 15,
margin: 10,
},
});
export default StyledTextInput;
import 'react-native-gesture-handler';
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import MapScreen from '../../pages/map/MapScreen';
import DetailScreen from '../../pages/map/DetailScreen';
import PaymentScreen from '../../pages/payment/PaymentScreen';
const Stack = createStackNavigator();
const MapStackNavigation = () => {
return(
<Stack.Navigator>
<Stack.Screen name="Map"
component={ MapScreen }
options={{
headerShown: false,
}}
/>
<Stack.Screen name="Detail"
component={ DetailScreen }
/>
<Stack.Screen name="Payment"
component={ PaymentScreen }
/>
</Stack.Navigator>
);
};
export default MapStackNavigation;
私のページで詳細を拡大します.管理履歴のデータには、決済済みのデータと未決済のデータが含まれます.TCP層を介して支払いサービスと通信し,支払いデータと支払いデータを共にユーザに表示する.import React from 'react';
import {
StyleSheet,
View,
Text
} from 'react-native';
import palette from '../../styles/palette';
import MyRentalFramgment from './components/MyRentalFramgent';
const MyRentalScreen = () => {
return(
<View style={ styles.container }>
<MyRentalFramgment />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: palette.white[0],
},
});
export default MyRentalScreen;
import React, { useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { getRentals } from '../../../modules/rentals';
import Loading from '../../../styles/common/Loading';
import palette from '../../../styles/palette';
import MyRenalCard from './MyRentalCard';
const MyRentalFramgment = () => {
const dispatch = useDispatch();
const {
userId,
rentals
} = useSelector(({
user,
rentals
}) => ({
userId: user.user.userId,
rentals: rentals.rentals
}));
useEffect(() => {
dispatch(getRentals(userId));
}, [dispatch]);
return(
<View style={ styles.container }>
{
rentals ?
rentals.map((item, i) => {
return <MyRenalCard i={ i }
item={ item }
/>
}) : <Loading />
}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: palette.gray[2],
}
});
export default MyRentalFramgment;
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import palette from '../../../styles/palette';
const MyRenalCard = ({ item }) => {
return(
<View style={ styles.container }>
<Text style={ styles.font }>
{ item.date + " " + item.time }
</Text>
<Text style={ styles.font }>
{ item.mapName }
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
width: 350,
height: 50,
marginLeft: 30,
marginTop: 15,
marginBottom: 5,
borderRadius: 30,
backgroundColor: palette.gray[3]
},
font: {
fontWeight: 'bold',
fontSize: 15
}
});
export default MyRenalCard;
react本機の実施部分はすでに完了しており、レンタル-サービス、支払い-サービスをさらに実施します.#4 rental-service, payment-service
リース-サービスの応答.rental.tsvoクラスとレンタル.dto.tsdtoクラスに次のように追加します.
import { IsNumber, IsObject, IsString } from "class-validator";
export class ResponseRental {
...
payment: any;
}
import { IsNumber, IsObject, IsString } from "class-validator";
export class RentalDto {
...
payment: any;
}
大文字データとともに支払データも呼び出されるため、支払データを格納するための列である.axiosライブラリを使用して、他のサービスからデータを呼び出します.
npm install --save @nestjs/axios
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { MongooseModule } from '@nestjs/mongoose';
import { Rental, RentalSchema } from 'src/schema/rental.schema';
import { RentalService } from './rental.service';
@Module({
imports: [
MongooseModule.forFeature([{
name: Rental.name,
schema: RentalSchema,
}]),
HttpModule,
],
providers: [RentalService],
exports: [RentalService],
})
export class RentalModule {}
import { Body, Controller, Delete, Get, HttpStatus, Param, Patch, Post } from "@nestjs/common";
import { statusConstants } from "./constants/status.constant";
import { RentalService } from "./rental/rental.service";
import { RequestRental } from "./vo/request.rental";
import { ResponseRental } from "./vo/response.rental";
import { Builder } from 'builder-pattern';
import { RentalDto } from "./dto/rental.dto";
import { EventPattern } from "@nestjs/microservices";
@Controller('rental-service')
export class AppController {
constructor(private readonly rentalService: RentalService) {}
@Post('rental')
public async rental(@Body() vo: RequestRental): Promise<any> {
try {
const result: any = await this.rentalService.create(Builder(RentalDto).price(vo.price)
.borrower(vo.borrower)
.tel(vo.tel)
.userId(vo.userId)
.date(vo.date)
.time(vo.time)
.mapId(vo.mapId)
.mapName(vo.mapName)
.build());
if(result.status === statusConstants.ERROR) {
return await Object.assign({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: result.message
});
}
return await Object.assign({
statusCode: HttpStatus.CREATED,
payload: Builder(ResponseRental).rentalId(result.payload.rentalId)
.price(result.payload.price)
.borrower(result.payload.borrower)
.tel(result.payload.tel)
.userId(result.payload.userId)
.date(result.payload.date)
.time(result.payload.time)
.mapId(result.payload.mapId)
.mapName(result.payload.mapName)
.status(result.payload.status)
.build(),
message: "Successfully rental"
});
} catch(err) {
return await Object.assign({
statusCode: HttpStatus.BAD_REQUEST,
payload: null,
message: "Error message: " + err
});
}
}
@Get(':rentalId/rental')
public async getRental(@Param('rentalId') rentalId: string) {
try {
const result: any = await this.rentalService.getOne(rentalId);
if(result.status === statusConstants.ERROR) {
return await Object.assign({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: result.message
});
}
return await Object.assign({
statusCode: HttpStatus.OK,
payload: Builder(ResponseRental).rentalId(result.payload.rentalId)
.price(result.payload.price)
.borrower(result.payload.borrower)
.tel(result.payload.tel)
.userId(result.payload.userId)
.date(result.payload.date)
.time(result.payload.time)
.mapId(result.payload.mapId)
.mapName(result.payload.mapName)
.status(result.payload.status)
.build(),
message: "Get rental by rentalId"
});
} catch(e) {
return await Object.assign({
statusCode: HttpStatus.BAD_REQUEST,
payload: null,
message: e
});
}
}
@Get(':userId/rentals')
public async getRentals(@Param('userId') userId: string) {
try {
const result: any = await this.rentalService.getRentals(userId);
if(result.status === statusConstants.ERROR) {
return await Object.assign({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: result.message
});
}
const responseRentals: Array<ResponseRental> = [];
for(const el of result.payload) {
responseRentals.push(el);
}
return await Object.assign({
status: HttpStatus.OK,
payload: responseRentals,
message: "Get list by userId"
});
} catch(err) {
return await Object.assign({
status: HttpStatus.BAD_REQUEST,
payload: null,
message: "Error message: " + err
});
}
}
@Patch(':rentalId/rental')
public async expiredRental(@Param('rentalId') rentalId: string) {
try {
const result: any = await this.rentalService.expiredRental(rentalId);
if(result.status === statusConstants.ERROR) {
return await Object.assign({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: result.message
});
}
return await Object.assign({
statusCode: HttpStatus.OK,
payload: null,
message: "Successfully rental"
});
} catch(e) {
return await Object.assign({
statusCode: HttpStatus.BAD_REQUEST,
payload: null,
message: e
});
}
}
@EventPattern('PAYMENT_RESPONSE')
public async responsePayment(data: any): Promise<any> {
try {
if(data === 'FAILURE_PAYMENT') {
const result: any = await this.rentalService.deleteRental(Builder(RentalDto).rentalId(data.rentalId)
.build());
if(result.status === statusConstants.ERROR) {
return await Object.assign({
status: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: "Error message: " + result.message
});
}
return await Object.assign({
status: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: "Error message: " + data
});
}
const result: any = await this.rentalService.completeRental(Builder(RentalDto).rentalId(data.rentalId)
.build());
if(result.status === statusConstants.ERROR) {
return await Object.assign({
status: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: "Error message: " + result.message
});
}
return await Object.assign({
status: HttpStatus.OK,
payload: null,
message: "Successful complete rental!"
});
} catch(err) {
return await Object.assign({
status: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: "Error message: " + err
});
}
}
}
次にRentalServiceのgetRentalsメソッドを追加します.getRentalsは「拡大」リストにロードされ、id値に一致する支払データがdtoオブジェクトに含まれます.import { Inject, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { statusConstants } from 'src/constants/status.constant';
import { RentalDto } from 'src/dto/rental.dto';
import { Rental, RentalDocument } from 'src/schema/rental.schema';
import { Builder } from 'builder-pattern';
import { v4 as uuid } from 'uuid';
import { ResponseRental } from 'src/vo/response.rental';
import { status } from 'src/constants/rental.status';
import { HttpService } from '@nestjs/axios';
import { map, Observable } from 'rxjs';
import { AxiosResponse } from 'axios';
import { response } from 'express';
@Injectable()
export class RentalService {
constructor(
@InjectModel(Rental.name) private rentalModel: Model<RentalDocument>,
private httpService: HttpService
) {}
public async create(dto: RentalDto): Promise<any> {
try {
const entity: any = await new this.rentalModel(Builder(Rental).rentalId(uuid())
.price(dto.price)
.borrower(dto.borrower)
.tel(dto.tel)
.userId(dto.userId)
.date(dto.date)
.time(dto.time)
.mapId(dto.mapId)
.mapName(dto.mapName)
.status(status.PENDING)
.createdAt(new Date().toDateString())
.build())
.save();
if(!entity) {
return await Object.assign({
status: statusConstants.ERROR,
payload: null,
message: "rental-service: database error"
});
}
return await Object.assign({
status: statusConstants.SUCCESS,
payload: Builder(RentalDto).rentalId(entity.rentalId)
.price(entity.price)
.borrower(entity.borrower)
.tel(entity.tel)
.userId(entity.userId)
.date(entity.date)
.time(entity.time)
.mapId(entity.mapId)
.mapName(entity.mapName)
.status(entity.status)
.createdAt(entity.createdAt)
.build(),
message: "Successful transaction"
});
} catch(err) {
return Object.assign({
status: statusConstants.ERROR,
payload: null,
message: "rental-service: " + err
});
}
}
public async getOne(rentalId: string): Promise<any> {
try {
const result: any = await this.rentalModel.findOne({ rentalId: rentalId });
if(!result) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "Not rental data"
});
}
return await Object.assign({
statusCode: statusConstants.SUCCESS,
payload: Builder(RentalDto).rentalId(result.rentalId)
.price(result.price)
.borrower(result.borrower)
.tel(result.tel)
.userId(result.userId)
.date(result.date)
.time(result.time)
.mapId(result.mapId)
.mapName(result.mapName)
.status(result.status)
.createdAt(result.createdAt)
.build(),
message: "Success transcation",
});
} catch(err) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "map-service database: " + err,
});
}
}
public async getRentals(userId: string): Promise<any> {
try {
const result: any = await this.rentalModel.find({ userId: userId });
if(!result) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "Not rental datas"
});
}
const dtoRentals: Array<ResponseRental> = [];
for(const el of result) {
const payment = await this.httpService.get(`http://localhost:8000/payment-service/${el.rentalId}/payment-from-rental`)
.toPromise();
const dto = Builder(RentalDto).rentalId(el.rentalId)
.price(el.price)
.borrower(el.borrower)
.tel(el.tel)
.userId(el.userId)
.date(el.date)
.time(el.time)
.mapId(el.mapId)
.mapName(el.mapName)
.status(el.status)
.createdAt(el.createdAt)
.payment(payment.data.payload)
.build();
dtoRentals.push(dto);
}
return await Object.assign({
statusCode: statusConstants.SUCCESS,
payload: dtoRentals,
message: "Success transcation",
});
} catch(err) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "map-service database: " + err,
});
}
}
public async expiredRental(rentalId): Promise<any> {
try {
const result = await this.rentalModel.updateOne({ rentalId: rentalId }, { $set: { status: status.EXPIRED }});
if(!result) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "Not exist data",
});
}
return await Object.assign({
statusCode: statusConstants.SUCCESS,
payload: null,
message: "Success delete"
});
} catch(err) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "rental-service database: " + err,
});
}
}
public async deleteRental(dto: RentalDto): Promise<any> {
try {
const result = await this.rentalModel.deleteOne({ rentalId: dto.rentalId });
if(!result) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "Not exist data",
});
}
return await Object.assign({
statusCode: statusConstants.SUCCESS,
payload: null,
message: "Success delete"
});
} catch(err) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "rental-service database: " + err,
});
}
}
public async completeRental(dto: RentalDto): Promise<any> {
try {
const result = await this.rentalModel.updateOne({ rentalId: dto.rentalId }, { $set: { status: status.BEING }});
if(!result) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "Not exist data",
});
}
return await Object.assign({
statusCode: statusConstants.SUCCESS,
payload: null,
message: "Success update"
});
} catch(err) {
return await Object.assign({
statusCode: statusConstants.ERROR,
payload: null,
message: "rental-service database: " + err,
});
}
}
}
payment-serviceはgetRentalsメソッドのためにhttp://localhost:8000/payment-service/${el.rentalId}/payment-from-rental
endpointを作成します....
@Controller('payment-service')
export class AppController {
...
@Get(':rentalId/payment-from-rental')
public async getPaymentFromRental(@Param('rentalId') rentalId: string): Promise<any> {
try {
const result: any = await this.paymentService.getPaymentFromRental(rentalId);
console.log(result);
if(result.status === statusConstants.ERROR) {
return await Object.assign({
status: HttpStatus.INTERNAL_SERVER_ERROR,
payload: null,
message: "Error message: " + result.message
});
}
if(!result.payload) {
return await Object.assign({
status: HttpStatus.OK,
payload: null,
message: "Success get data"
});
}
return await Object.assign({
status: HttpStatus.OK,
payload: Builder(ResponsePayment).paymentName(result.payload.paymentName)
.payer(result.payload.payer)
.rentalId(result.payload.rentalId)
.paymentId(result.payload.paymentId)
.price(result.payload.price)
.createdAt(result.payload.createdAt)
.build(),
message: "Success get data"
});
} catch(err) {
return await Object.assign({
status: HttpStatus.BAD_GATEWAY,
payload: null,
message: "Error message: " + err,
});
}
}
}
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { InjectModel } from '@nestjs/mongoose';
import { Builder } from 'builder-pattern';
import { Model } from 'mongoose';
import { statusConstants } from 'src/constants/status.constants';
import { PaymentDto } from 'src/dto/payment.dto';
import { Payment, PaymentDocument } from 'src/schema/payment.schema';
import { v4 as uuid } from 'uuid';
@Injectable()
export class PaymentService {
...
public async getPaymentFromRental(data: any) {
try {
const entity: any = await this.paymentModel.findOne({ rentalId: data });
if(!entity) {
return await Object.assign({
status: statusConstants.SUCCESS,
payload: null,
message: "Not exist data"
});
}
return await Object.assign({
status: statusConstants.SUCCESS,
payload: Builder(PaymentDto).paymentId(entity.paymentId)
.paymentName(entity.paymentName)
.payer(entity.payer)
.price(entity.price)
.rentalId(entity.rentalId)
.createdAt(entity.createdAt)
.build(),
message: "Successful transaction"
});
} catch(err) {
return await Object.assign({
status: statusConstants.ERROR,
payload: null,
message: err
});
}
}
}
コードの作成が完了しました.payment-サービスのデータインポート状況をテストしましょう.試験は、userIdb 49 cad 9−1 d 76−41 b 2−abad−7 a 27 c 4394 ca、78 e 834 ff−f 270−4 a 9 e−9 b 30−1 a 44 daff 9469を基準として行った.
1) bb49cad9-1d76-41b2-abad-7a271c4394ca
このuserIdの場合、貸出ステータスはBEINGであり、支払データが存在することを示す.したがって、この場合、支払を支払済みと見なし、「大文字データ」履歴の支払完了に分類します.
2) 78e834ff-f270-4a9e-9b30-1a44daff9469
このuserIdの場合、借用ステータスはPENDINGであり、この場合、支払が行われていないとみなされ、「大管データ履歴」の「未決」に分類される.
簡単なテストを行い、次の記事では、管理者の履歴をより詳細なUI作成と関連付けます.
Reference
この問題について(LifeSports Application(ReactNative & Nest.js) - 18. payment-service, UI), 我々は、より多くの情報をここで見つけました https://velog.io/@biuea/LifeSports-ApplicationReactNative-Nest.js-18.-payment-service-UIテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol