frontend add

This commit is contained in:
shinmj
2021-10-21 09:03:17 +09:00
parent 8caa4bbc5a
commit cb9d50511e
443 changed files with 88282 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
import { SITE_ID } from '@constants/env'
import axios from 'axios'
/**
* 포털 서비스 배너 API URL
*/
const BANNER_URL = `/portal-service/api/v1/${SITE_ID}/banners`
export interface IMainBanner {
[key: string]: IBanner[]
}
export interface IBanner {
attachmentCode: string
bannerContent: string
bannerNo: number
bannerTitle: string
bannerTypeCode: string
uniqueId: string
newWindowAt: boolean
urlAddr: string
}
/**
* 배너 관리 서비스
*/
export const bannerService = {
getBanners: (bannerTypeCodes: string[], bannerCount: number) => {
return axios.get(`${BANNER_URL}/${bannerTypeCodes}/${bannerCount}`)
},
}

View File

@@ -0,0 +1,256 @@
import axios, { AxiosError } from 'axios'
import useSWR from 'swr'
import { common, Page, Pageable, SearchPayload, Sort } from './common'
/**
* 게시판 스킨 유형
*/
export const SKINT_TYPE_CODE_NORMAL = 'normal'
export const SKINT_TYPE_CODE_FAQ = 'faq'
export const SKINT_TYPE_CODE_QNA = 'qna'
export interface IMainBoard {
[key: number]: IBoard
}
/**
* 게시판 타입
*/
export interface IBoard {
boardNo: number
boardName: string
skinTypeCode: string
titleDisplayLength: number
postDisplayCount: number
pageDisplayCount: number
newDisplayDayCount: number
editorUseAt: boolean
userWriteAt: boolean
commentUseAt: boolean
uploadUseAt: boolean
uploadLimitCount: number
uploadLimitSize: number
posts: IPosts[]
}
/**
* 저장 시 데이터 타입
*/
export interface IPostsForm {
postsTitle: string
postsContent: string
attachmentCode?: string
}
export interface IPosts extends IPostsForm {
boardNo: number
postsNo?: number
noticeAt?: boolean
postsTitle: string
postsContent: string
postsAnswerContent?: string
attachmentCode?: string
createdBy?: string
createdName?: string
createdDate?: string
readCount?: number
deleteAt?: number
isNew?: boolean
commentCount?: number
prevPosts?: IPostsForm[]
nextPosts?: IPostsForm[]
}
export interface PostsPayload {
callback: () => any
errorCallback: (error: AxiosError) => void
boardNo?: number
postsNo?: number
data?: IPostsForm
}
export interface PostsReqPayload extends SearchPayload {
boardNo: number
postsNo: number
headers?: any
keywordType?: string
keyword?: string
}
export interface ICommentSearchProps {
boardNo: number
postsNo: number
_page: number
_mode: 'replace' | 'append' | 'until'
}
export interface ICommentPage {
empty: boolean
first: boolean
last: boolean
number: number
numberOfElements: number
pageable: Pageable
size: number
sort: Sort
totalElements: number
groupElements: number
totalPages: number
content: CommentSavePayload[] | []
}
export interface CommentSavePayload {
boardNo: number
postsNo: number
commentNo?: number
commentContent: string
commentAnswerContent?: string
groupNo?: number
parentCommentNo?: number
depthSeq: number
sortSeq?: number
deleteAt?: number
createdBy?: string
createdName?: string
createdDate?: string
mode?: 'none' | 'edit' | 'reply'
}
const BOARD_URL = '/board-service/api/v1/boards'
const POSTS_URL = '/board-service/api/v1/posts'
const COMMENT_URL = '/board-service/api/v1/comments'
export const boardService = {
getBoardById: (boardNo: number) => {
return axios.get(`${BOARD_URL}/${boardNo}`)
},
getMainPosts: (boardNos: number[], count: number) => {
return axios.get(`${POSTS_URL}/newest/${boardNos}/${count}`)
},
search: (
boardNo: number,
{ keywordType, keyword, size, page }: SearchPayload,
) =>
useSWR<Page, AxiosError>(
() =>
typeof boardNo === 'number' && boardNo > -1
? [
`${POSTS_URL}/list/${boardNo}?size=${size}&page=${page}`,
keywordType,
keyword,
]
: null,
url => common.fetcher(url, { keywordType, keyword }),
{ revalidateOnFocus: false, errorRetryCount: 0 },
),
getPostById: ({
boardNo,
postsNo,
keywordType,
keyword,
}: PostsReqPayload) => {
return axios.get(
`${POSTS_URL}/view/${boardNo}/${postsNo}?keywordType=${keywordType}&keyword=${keyword}`,
)
},
savePost: async ({
boardNo,
callback,
errorCallback,
data,
}: PostsPayload) => {
try {
const result = await axios.post(`${POSTS_URL}/save/${boardNo}`, data, {
headers: common.headers,
})
if (result) {
callback()
}
} catch (error) {
errorCallback(error)
}
},
updatePost: async ({
boardNo,
postsNo,
callback,
errorCallback,
data,
}: PostsPayload) => {
try {
const result = await axios.put(
`${POSTS_URL}/update/${boardNo}/${postsNo}`,
data,
{
headers: common.headers,
},
)
if (result) {
callback()
}
} catch (error) {
errorCallback(error)
}
},
removePost: async ({ callback, errorCallback, data }: PostsPayload) => {
try {
const result = await axios.put(`${POSTS_URL}/remove`, data, {
headers: common.headers,
})
if (result) {
callback()
}
} catch (error) {
errorCallback(error)
}
},
getComments: (boardNo: number, postsNo: number, size: number, page: number) =>
new Promise<ICommentPage>((resolve, rejects) => {
axios
.get(
`${COMMENT_URL}/list/${boardNo}/${postsNo}?size=${size}&page=${page}`,
)
.then(result => {
resolve(result.data)
})
.catch(e => rejects(e))
}),
getAllComments: (boardNo: number, postsNo: number) =>
new Promise<Page>((resolve, rejects) => {
axios
.get(`${COMMENT_URL}/all/${boardNo}/${postsNo}`)
.then(result => {
resolve(result.data)
})
.catch(e => rejects(e))
}),
saveComment: (comment: CommentSavePayload) => {
return new Promise<Page>((resolve, rejects) => {
axios
.post(`${COMMENT_URL}`, comment)
.then(result => {
resolve(result.data)
})
.catch(e => rejects(e))
})
},
updateComment: (comment: CommentSavePayload) => {
return new Promise<Page>((resolve, rejects) => {
axios
.post(`${COMMENT_URL}/update`, comment)
.then(result => {
resolve(result.data)
})
.catch(e => rejects(e))
})
},
deleteComment: ({ boardNo, postsNo, commentNo }: CommentSavePayload) => {
return new Promise<Page>((resolve, rejects) => {
axios
.delete(`${COMMENT_URL}/delete/${boardNo}/${postsNo}/${commentNo}`)
.then(result => {
resolve(result.data)
})
.catch(e => rejects(e))
})
},
}

View File

@@ -0,0 +1,22 @@
import axios from 'axios'
/**
* 컨텐츠 데이터 타입
*/
export interface IContent {
contentName: string
contentRemark: string
contentValue: string
}
/**
* 포털 서비스 컨텐츠 API URL
*/
const CONTENT_URL = '/portal-service/api/v1/contents'
/**
* 컨텐츠 관리 서비스
*/
export const contentService = {
get: async (contentNo: number) => axios.get(`${CONTENT_URL}/${contentNo}`),
}

View File

@@ -0,0 +1,112 @@
import axios from 'axios'
export interface IFile {
key: string
file: File
}
export interface UploadInfoReqeust {
entityName?: string
entityId?: string
}
export interface IAttachmentResponse {
code: string
seq: number
id: string
originalFileName: string
physicalFileName: string
size: number
fileType: string
isDelete: boolean
createDate: Date
downloadCnt: number
entityId: string
entityName: string
}
export interface AttachmentSavePayload {
uniqueId: string
isDelete: boolean
}
export type UploadPayload = {
fileList?: IFile[]
attachmentCode?: string
info?: UploadInfoReqeust
list?: AttachmentSavePayload[]
}
const UPLOAD_API = '/portal-service/api/v1/attachments'
const DOWNLOAD_API = `/server/portal-service/api/v1/download`
let fileHeader = {
'Content-Type': 'multipart/form-data',
}
/**
* 파일 업로드 서비스
*/
export const fileService = {
url: UPLOAD_API,
downloadUrl: DOWNLOAD_API,
upload: async ({ fileList, attachmentCode, info, list }: UploadPayload) => {
let formData = new FormData()
fileList.map(item => {
formData.append('files', item.file)
})
if (info) {
formData.append(
'info',
new Blob([JSON.stringify(info)], { type: 'application/json' }),
)
}
if (list) {
formData.append(
'list',
new Blob([JSON.stringify(list)], { type: 'application/json' }),
)
}
// attachmentCode가 있는 경우 update라고 본다
if (attachmentCode) {
return axios.put(
`/server${UPLOAD_API}/upload/${attachmentCode}`,
formData,
{
headers: fileHeader,
},
)
}
// attachmentCode가 없는 경우 신규 저장
return axios.post(`/server${UPLOAD_API}/upload`, formData, {
headers: fileHeader,
})
},
save: async ({ attachmentCode, info, list }: UploadPayload) => {
let formData = new FormData()
formData.append(
'info',
new Blob([JSON.stringify(info)], { type: 'application/json' }),
)
formData.append(
'list',
new Blob([JSON.stringify(list)], { type: 'application/json' }),
)
return axios.put(`${UPLOAD_API}/${attachmentCode}`, formData, {
headers: fileHeader,
})
},
getAttachmentList: (attachmentCode: string) => {
return axios.get(`${UPLOAD_API}/${attachmentCode}`)
},
deleteAll: (attachmentCode: string) =>
axios.delete(`${UPLOAD_API}/${attachmentCode}/children`),
}

View File

@@ -0,0 +1,64 @@
import { ACCESS_TOKEN, AUTH_USER_ID, CLAIM_NAME } from '@constants/env'
import axios from 'axios'
const JWT_EXPIRED_TIME = 1800000
const LOGIN_SERVICE_URL = `/api/login/user-service`
const LOGIN_URL = `/login`
const CLIENT_REFRESH_URL = '/api/login/user-service/api/v1/users/token/refresh'
export interface ILogin {
email?: string
password?: string
isRemember?: boolean
provider: 'email' | 'google' | 'naver' | 'kakao'
token?: string
name?: string
}
const onSuccessLogin = (result: any) => {
axios.defaults.headers.common[CLAIM_NAME] = result[ACCESS_TOKEN]
axios.defaults.headers.common[AUTH_USER_ID] = result[AUTH_USER_ID]
// access-token 만료 1분 전에 로그인 연장
setTimeout(loginSerivce.silentRefresh, JWT_EXPIRED_TIME - 60000)
}
export const loginSerivce = {
login: (data: ILogin) => {
return new Promise<string>(async (resolve, reject) => {
try {
const result = await fetch(LOGIN_SERVICE_URL + LOGIN_URL, {
method: 'POST',
body: JSON.stringify(data),
})
if (result.status === 200) {
onSuccessLogin(await result.json())
resolve('success')
} else {
reject('noAuth')
}
} catch (error) {
reject(error)
}
})
},
silentRefresh: async () => {
try {
const result = await fetch(CLIENT_REFRESH_URL, {
method: 'PUT',
})
if (result) {
onSuccessLogin(await result.json())
}
} catch (error) {
console.warn('refresh token 만료로 인한 로그아웃!!!!')
fetch('/api/v1/token')
.then(res => {
console.warn('fetch', res)
})
.catch(error => {
console.warn('fetch error', error)
})
}
},
}

View File

@@ -0,0 +1,17 @@
import { MODE } from '@constants/env'
import useSWR from 'swr'
import { common } from './common'
const siteId = MODE === 'sm' ? '3' : '2'
const MENU_API = `/portal-service/api/v1/menu-roles/${siteId}`
const CODE_API = `/portal-service/api/v1/code-details/skin_type_code/codes`
export const menuService = {
getMenus: () => {
return useSWR(MENU_API, common.fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
})
},
}

View File

@@ -0,0 +1,22 @@
import axios from 'axios'
export interface IPolicy {
id: number
type: string
title: string
isUse: boolean
regDate: Date
contents: string
}
const POLICY_API = '/portal-service/api/v1/policies'
/**
* 이용약관 관리 서비스
*/
export const policyService = {
url: POLICY_API,
getLatest: (type: string) => {
return axios.get(`${POLICY_API}/latest/${type}`)
},
}

View File

@@ -0,0 +1,22 @@
import axios from 'axios'
/**
* 개인정보처리방침 데이터 타입
*/
export interface IPrivacy {
privacyNo: number
privacyTitle: string
privacyContent: string
}
/**
* 포털 서비스 개인정보처리방침 API URL
*/
const PRIVACY_URL = '/portal-service/api/v1/privacies'
/**
* 개인정보처리방침 관리 서비스
*/
export const privacyService = {
alluse: async () => axios.get(`${PRIVACY_URL}/all/use`),
}

View File

@@ -0,0 +1,213 @@
import { common, Page, SearchPayload } from '@service'
import axios, { AxiosError } from 'axios'
import useSWR from 'swr'
const LIST_API_URL = (categoryId: ValueType) =>
`/reserve-item-service/api/v1/${categoryId}/reserve-items`
const ITEM_API_URL = `/reserve-item-service/api/v1/reserve-items`
const REQUEST_API_URL = '/reserve-request-service/api/v1/requests'
const CODE_API_URL = `/portal-service/api/v1/code-details`
const LOCATION_API_URL = '/reserve-item-service/api/v1/locations'
const RESERVE_API_URL = '/reserve-check-service/api/v1'
interface ReserveSearchPayload extends SearchPayload {
categoryId?: ValueType
locationId?: ValueType
userId?: string
}
export interface IMainItem {
[key: string]: IReserveItemMain[]
}
export interface IReserveItemMain {
reserveItemId: number
reserveItemName: string
categoryId: string
categoryName: string
startDate: string
endDate: string
isPossible: boolean
}
export interface ILocation {
locationId?: number
locationName: string
sortSeq: number
isUse: boolean
}
export interface ICode {
codeId: string
codeName: string
sortSeq: number
}
export interface IReserveItem {
reserveItemId: number
reserveItemName: string
locationId: number
location: ILocation
categoryId: string
categoryName: string
totalQty: number
inventoryQty: number
operationStartDate: string
operationEndDate: string
reserveMethodId: string
reserveMethodName: string
reserveMeansId: string
reserveMeansName: string
requestStartDate: string
requestEndDate: string
isPeriod: true
periodMaxCount: number
externalUrl: string
selectionMeansId: string
selectionMeansName: string
isPaid: true
usageCost: number
isUse: true
purpose: string
address: string
targetId: string
targetName: string
excluded: string
homepage: string
contact: string
managerDept: string
managerName: string
managerContact: string
isPossible: boolean
}
export interface ReserveSavePayload {
reserveId: string
reserveItemId: number
locationId: number
categoryId: string
totalQty: number
reserveMethodId: string
reserveMeansId: string
operationStartDate: string
operationEndDate: string
requestStartDate: string
requestEndDate: string
isPeriod: boolean
periodMaxCount: number
reserveQty: number
reservePurposeContent: string
attachmentCode: string
reserveStartDate: string
reserveEndDate: string
reserveStatusId: string
userId: string
userContactNo: string
userEmail: string
}
export interface IReserve {
reserveId: string
reserveItemId: number
reserveItem: IReserveItem
reserveQty: number
reserveStartDate: string
reserveEndDate: string
reservePurposeContent: string
attachmentCode: string
reserveStatusId: string
userId: string
userName: string
userContactNo: string
userEmail: string
}
export const reserveService = {
requestApiUrl: REQUEST_API_URL,
search: ({
keywordType,
keyword,
size,
page,
categoryId,
locationId,
}: ReserveSearchPayload) =>
useSWR<Page, AxiosError>(
[
`${LIST_API_URL(categoryId)}?size=${size}&page=${page}`,
keywordType,
keyword,
locationId,
categoryId,
],
url =>
common.fetcher(url, {
keywordType,
keyword,
locationId,
categoryId,
isUse: true,
}),
{ revalidateOnFocus: false, errorRetryCount: 0 },
),
getCode: (codeId: string) =>
axios.get(`${CODE_API_URL}/${codeId}/codes`, {
headers: common.headers,
}),
getLocation: () =>
axios.get(`${LOCATION_API_URL}/combo`, {
headers: common.headers,
}),
getItem: (reserveItemId: number) =>
axios.get(`${ITEM_API_URL}/relations/${reserveItemId}`),
getCountInventory: (
reserveItemId: number,
startDate: string,
endDate: string,
) =>
axios.get(
`${RESERVE_API_URL}/reserves/${reserveItemId}/inventories?startDate=${startDate}&endDate=${endDate}`,
{
data: {
startDate,
endDate,
},
},
),
createAudit: (data: ReserveSavePayload) =>
axios.post(`${REQUEST_API_URL}/evaluates`, data),
create: (data: ReserveSavePayload) => axios.post(REQUEST_API_URL, data),
getMainItems: (count: number) => axios.get(`${ITEM_API_URL}/latest/${count}`),
searchUserReserve: ({
userId,
size,
page,
keywordType,
keyword,
locationId,
categoryId,
}: ReserveSearchPayload) =>
useSWR(
[
`${RESERVE_API_URL}/${userId}/reserves?size=${size}&page=${page}`,
keywordType,
keyword,
locationId,
categoryId,
],
url =>
common.fetcher(url, {
keywordType,
keyword,
locationId,
categoryId,
}),
{ revalidateOnFocus: false, errorRetryCount: 0 },
),
getReserve: (reserveId: string) =>
axios.get(`${RESERVE_API_URL}/reserves/${reserveId}`),
cancel: (reserveId: string, reason: ValueType) =>
axios.put(`${RESERVE_API_URL}/reserves/cancel/${reserveId}`, {
reasonCancelContent: reason,
}),
}

View File

@@ -0,0 +1,12 @@
import axios from 'axios'
import { common } from './common'
const STATISTICS_API = `/portal-service/api/v1/statistics`
export const statisticsService = {
save: (uuid: string) => {
return axios.post(`${STATISTICS_API}/${uuid}`, {
Headers: common.headers,
})
},
}

View File

@@ -0,0 +1,137 @@
import axios from 'axios'
/**
* 사용자 서비스 사용자 API URL
*/
const USER_URL = '/user-service/api/v1/users'
export interface IUser {
email: string
password?: string
userName: string
token?: string
}
// 비밀번호 찾기로 변경
export interface IUserFindPassword {
emailAddr?: string
userName?: string
password?: string
tokenValue?: string
}
// 사용자 검증
export interface IVerification {
provider: string
password?: string
token?: string
}
// 마이페이지 비밀번호 변경
interface IUserUpdatePassword extends IVerification {
newPassword: string
}
// 마이페이지 회원정보 변경
interface IUserUpdate extends IVerification {
email: string
userName: string
}
/**
* 사용자 관리 서비스
*/
export const userService = {
existsEmail: (email: string, userId?: string) =>
new Promise<boolean>((resolve, rejects) => {
axios
// .get(`${USER_URL}/exists?email=${email}`)
.post(`${USER_URL}/exists`, { email, userId })
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
join: (user: IUser) =>
new Promise<boolean>((resolve, rejects) => {
axios
.post(`${USER_URL}/join`, user)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
findPassword: (userFindPassword: IUserFindPassword) =>
new Promise<boolean>((resolve, rejects) => {
axios
.post(`${USER_URL}/password/find`, userFindPassword)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
getFindPassword: (token: string) => {
return axios.get(`${USER_URL}/password/valid/${token}`)
},
changePassword: (userFindPassword: IUserFindPassword) =>
new Promise<boolean>((resolve, rejects) => {
axios
.put(`${USER_URL}/password/change`, userFindPassword)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
updatePassword: (userUpdatePassword: IUserUpdatePassword) =>
new Promise<boolean>((resolve, rejects) => {
axios
.put(`${USER_URL}/password/update`, userUpdatePassword)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
matchPassword: (password: string) =>
new Promise<boolean>((resolve, rejects) => {
axios
.post(`${USER_URL}/password/match`, { password })
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
updateInfo: (userId: string, userUpdate: IUserUpdate) =>
new Promise<boolean>((resolve, rejects) => {
axios
.put(`${USER_URL}/info/${userId}`, userUpdate)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
leave: (userLeave: IVerification) =>
new Promise<boolean>((resolve, rejects) => {
axios
.post(`${USER_URL}/leave`, userLeave)
.then(result => {
resolve(result.data)
})
.catch(e => {
rejects(e)
})
}),
}

View File

@@ -0,0 +1,58 @@
import { CUSTOM_HEADER_SITE_ID_KEY } from '@constants'
import { SITE_ID } from '@constants/env'
import axios from 'axios'
let headers = {
'Content-Type': 'application/json',
}
headers[CUSTOM_HEADER_SITE_ID_KEY] = SITE_ID
export interface Sort {
empty: boolean
sorted: boolean
unsorted: boolean
}
export interface Pageable {
offset: number
pageNumber: number
pageSize: number
paged: boolean
unpaged: boolean
sort: Sort
}
export interface Page {
empty: boolean
first: boolean
last: boolean
number: number
numberOfElements: number
pageable: Pageable
size: number
sort: Sort
totalElements: number
totalPages: number
content: any[] | []
}
export interface SearchPayload {
keywordType?: ValueType
keyword?: ValueType
size?: number
page?: number
}
const fetcher = async (url: string, param: {}) => {
const res = await axios.get(url, {
params: param,
headers,
})
return res.data
}
export const common = {
headers,
fetcher,
}

View File

@@ -0,0 +1,12 @@
export * from './common'
export * from './Menu'
export * from './Banner'
export * from './Board'
export * from './Content'
export * from './File'
export * from './Login'
export * from './Statistics'
export * from './Privacy'
export * from './Policy'
export * from './User'
export * from './Reserve'