2023. 10. 29. 17:54ㆍGithub 프로젝트/음식점 포스 프로그램
지난 시간에는 고객 정보와 로그 관련 API를 연동 작업을 진행 하였습니다.
또한 React-Query와 Recoil 사용 하는 방법에 대해서도 알아가 보았는데, 이번 시간에는 마저 못한 부분 중 하나인 음식 정보 및 계좌 정보를 Front-End 개발자에게 넘겨줄 각각 인터페이스 개발을 이어서 진행 해보겠습니다.
github: https://github.com/BerkleyLim/foodstor_pos
1. 계좌 정보 및 입출금 내역
- 사용자 계좌 정보 조회 => (이 프로젝트에서는 1명의 회원만 조회)
- URI :/api/account/{uno}
- Method : GET
- Request : uno
- Response : ano, uno, userMoney
- 계좌 입출금 서비스
- URI : /api/account/change
- Method : POST
- Request : ano, uno, userMoney
- Response : 없음
이 경우, 조회 시 필요한 계좌 금액, 입출금 필요합니다.
2. 계좌 조회 API 연동 코드
<Bank.tsx>
// 리액트 Query 작성
// (결론 : 로그인 할때만 쓰자!, 실시간 갱신에 좋으나, 기기에 따라 로딩 속도가 오래 걸린다.)
// 공통으로 쓰기
const fetchSelect = () => {
const uno = (!!userInfo?.uno) ? userInfo?.uno : 0
fetch('http://localhost:8080/api/account/'+uno).then(
(res) => res.json()
).then( (res) => {
console.log(res)
setBankInfo(res)
}).catch((e) => console.log(e))
}
// React Query에 사용할 객체 저장
const queries = [
{
queryKey: ['userAccount',1],
queryFn: () => {
fetchSelect();
}
}
]
const selectQueries = useQueries(queries);
3. 계좌 입출금 API 연동 코드
<Bank.tsx>
const changeMoney = useMutation(async (update:UserBankInfoVo) => {
const response = await fetch('http://localhost:8080/api/account/change', {
method: 'POST',
body: JSON.stringify(update),
headers: {
'Content-Type': 'application/json'
}
})
return response
}, {
onSuccess: (data) => {
console.log(data)
console.log("성공")
fetchSelect();
}
});
4. 계좌 입출금 로그 조회
=> 로그 조회 부분의 대한 코드는 이전 페이지 참조
5. 음식 주문 API 연동 (계좌 조회)
- 음식 메뉴 전체 조회
- URI :/api/food/
- Method : GET
- Request : null
- Response : 리스트 [fno, foodMenu, foodPrice, vat]
- 음식 주문시 계좌 출금
- URI :/api/food/purchase
- Method : POST
- Request : uno, fno, pageNo, pageEventTitle, pageEventView, crtTime
- Response : 없음
- 음식 주문 연동 API
// api 전송 (계좌 어데이트 )
const purchaseMoney = useMutation(async (update:FoodTypeVo) => {
const response = await fetch('http://localhost:8080/api/food/purchase', {
method: 'POST',
body: JSON.stringify(update),
headers: {
'Content-Type': 'application/json'
}
})
return response
}, {
onSuccess: () => {
console.log("구입 성공")
fetchSelect();
}
});
- 버튼 클릭시 음식 주문 이벤트 발생 시작점
// 구입 시 선택
const purchaseFood = (f: any | Object) => {
/** 구입의 대한 로그에 담는다 */
const foodTypeVo: FoodTypeVo = {
fno: f?.fno,
uno: userInfo.uno,
pageNo: 4,
pageEventTitle: "음식 주문",
pageEventView: "음식 주문 : " + f?.foodMenu + "[" + (f?.foodPrice + f?.VAT) + "원], 잔액[" + (bankInfo?.userMoney as number - f?.foodPrice - f?.VAT) + "원]",
crtTime: JSON.stringify(today),
}
purchaseMoney.mutate(foodTypeVo)
}
- 음식 주문 이벤트 후, 진입 시 React-Query로 API 호출부
// 공통으로 쓰기
const fetchSelect = () => {
const uno = (!!userInfo?.uno) ? userInfo?.uno : 0
fetch('http://localhost:8080/api/account/'+uno).then(
(res) => res.json()
).then( (res) => {
console.log(res)
setBankInfo(res)
}).catch((e) => console.log(e))
}
6. 음식 주문 이벤트 결과
7. TypeScript 형식에 맞게 Interface 설정 (음식주문 및 계좌 입출금)
<foodState.tsx>
import {atom} from 'recoil'
export interface FoodTypeVo {
// userInfoVo에 담을 변수
uno: number,
fno: number,
pageNo: number,
pageEventTitle: string,
pageEventView: string,
crtTime: string
}
export interface FoodType {
fno: number
,foodMenu: string
,foodPrice: number
,VAT: number
};
export const foodState = atom({
key: 'food',
default: [
{
fno: 1
, foodMenu: '장어구이'
, foodPrice: 5000
, VAT: 500
},
{
fno: 2
, foodMenu: '피자'
, foodPrice: 10000
, VAT: 1000
},
{
fno: 3
, foodMenu: '치즈스틱'
, foodPrice: 3000
, VAT: 300
},
{
fno: 4
, foodMenu: '로스트비프'
, foodPrice: 15000
, VAT: 1500
},
{
fno: 5
, foodMenu: '감자튀김'
, foodPrice: 4000
, VAT: 400
},
] as FoodType[]
});
<userBankInfoState.tsx>
import {atom} from 'recoil'
export interface UserBankInfoVo {
// userInfoVo에 담을 변수
uno: Number,
userMoney: Number,
pageNo: Number,
pageEventTitle: String,
pageEventView: String,
crtTime: String
}
export interface UserBankInfoType {
bno: Number
,userMoney: Number
};
export const userBankInfoState = atom({
key: 'userBankInfo',
default: {
bno: 0
, userMoney: 0
} as UserBankInfoType
});
8. 작업 끝나면, 모든 데이터 값 날리기
- 회원 정보, 로그, 계좌 정보 (전체) => 이 프로젝트에서는 연습용 프로젝트이고, 1명의 회원만 존재하여 진행
- URI :/api/user/info/insert/user/info
- Method : POST
- Request : 없음
- Response : 없음
이 경우, 회원이 사용한 이벤트 목록과, 사용자 정보, 계좌 정보 초기화 시킨다.
Recoil과 DB Table 초기화 하는 방식으로 적용함 (백엔드 부분은 controller service 개발 로그 부분 참조)
프론트엔드 <menuIndex.tsx>
const navigate = useNavigate();
// default 값으로 reset용
const resetUserInfo = useResetRecoilState(userInfoState);
const resetLogInfo = useResetRecoilState(logInfoState);
const resetUserBankInfo = useResetRecoilState(userBankInfoState);
// 리액트 쿼리로 남김
// 유저 정보 제거
const deleteUserInfo = useMutation(async (removeData) => {
const response = await fetch('http://localhost:8080/api/user/info/delete/user/info', {
method: 'POST',
body: JSON.stringify(removeData),
headers: {
'Content-Type': 'application/json'
}
});
return response;
}, {
onSuccess: () => {
resetUserInfo();
resetUserBankInfo();
resetLogInfo();
}
});
const pageMoveClick = (url:any) => {
if (url === '/inputuserinfo') {
// recoil state 값 default 초기화
// 유저 정보 초기화
// 계좌 초기화
// 로그 초기화
deleteUserInfo.mutate()
}
navigate(url);
}
마치며,
지금까지 작업에 필요한 모든 API를 연동 시켰습니다.
지금까지의 작업을 토대로 기본 개발은 끝이 났으며, 주니어 개발자 수준으로 맞춰서 개발을 진행 해 왔으며, 실제 현업에서는 완벽하게 개발을 진행하는 것으로 목표로 두고, 항상 최악의 경우를 고려하여 개발을 진행을 하는 것으로 목적으로 두어야 한다고 생각이 듭니다.
이 프로젝트에서는 개발자로써 기본으로 해야하는 과정으로 진행해 나갔으며, 지금까지 개발해 나간 것들 기준으로 했을 경우 개선을 많이 해야 한다고 생각합니다.
이것으로 프로젝트를 마치며, 추가적인 개선 상황 (Recoil-Persist 를 이용하여 새로 고침 시 state 값 초기화 방지)를 추가 개발을 적용 시키며, 모바일 버전에서 사용 가능한 환경으로 구현해 나가겠으며, 시간이 되어진다면 React Native를 활용하여 Native 단이나 지금 만든 React 프로젝트에서 WebView로 연동하여 나아가보겠습니다.