Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
junh_eee(이준희) | 3269298ba3 | 8 months ago |
junh_eee(이준희) | 33cb319d96 | 8 months ago |
13 changed files with 429 additions and 3 deletions
@ -0,0 +1,31 @@ |
|||||||
|
import { getDroneList } from '@/redux/features/basis/drone/droneThunk'; |
||||||
|
import { useAppSelector } from '@/redux/hooks'; |
||||||
|
import { AppDispatch } from '@/redux/store'; |
||||||
|
import { useEffect } from 'react'; |
||||||
|
import { useDispatch } from 'react-redux'; |
||||||
|
|
||||||
|
export default function Drone() { |
||||||
|
const dispatch = useDispatch<AppDispatch>(); |
||||||
|
const droneList = useAppSelector(state => state.drone.list); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log(droneList, '---list'); |
||||||
|
}, [droneList]); |
||||||
|
|
||||||
|
const handler = () => { |
||||||
|
dispatch( |
||||||
|
getDroneList({ |
||||||
|
groupId: 'C807F9', |
||||||
|
page: 1 |
||||||
|
}) |
||||||
|
); |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
main |
||||||
|
<div style={{ background: '#ff00ff', width: '100px' }} onClick={handler}> |
||||||
|
Redux-toolkit |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
'use client'; |
||||||
|
|
||||||
|
import Drone from './drone'; |
||||||
|
|
||||||
|
export default function Home() { |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Drone /> |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
import { createSlice } from '@reduxjs/toolkit'; |
||||||
|
import { InitDroneState } from './droneState'; |
||||||
|
import { getDroneList, getIdntfList } from './droneThunk'; |
||||||
|
|
||||||
|
const droneSlice = createSlice({ |
||||||
|
name: 'droneSlice', |
||||||
|
initialState: InitDroneState, |
||||||
|
reducers: {}, |
||||||
|
extraReducers: builder => { |
||||||
|
builder.addCase(getDroneList.fulfilled, (state, action) => { |
||||||
|
const { data, count } = action.payload; |
||||||
|
state.list = data.items; |
||||||
|
state.total = data.total; |
||||||
|
state.count = count; |
||||||
|
}); |
||||||
|
builder.addCase(getIdntfList.fulfilled, (state, action) => { |
||||||
|
const { data, count } = action.payload; |
||||||
|
state.listIdntf = data; |
||||||
|
state.idntfCount = count; |
||||||
|
state.isRefreshIdntf = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
export const droneReducer = droneSlice.reducer; |
@ -0,0 +1,71 @@ |
|||||||
|
export const InitDroneState = { |
||||||
|
list: undefined, |
||||||
|
count: 0, |
||||||
|
detail: undefined, |
||||||
|
searchParams: '', |
||||||
|
selectData: undefined, |
||||||
|
listIdntf: undefined, |
||||||
|
idntfCount: 0, |
||||||
|
isRefreshIdntf: false, |
||||||
|
page: 1, |
||||||
|
total: 0 |
||||||
|
}; |
||||||
|
|
||||||
|
export interface DroneState { |
||||||
|
list: DroneData[] | undefined; |
||||||
|
count: number | 0; |
||||||
|
detail: DroneData | undefined; |
||||||
|
searchParams: string | ''; |
||||||
|
selectData: SelectData | undefined; |
||||||
|
listIdntf: IdntfData[] | undefined; |
||||||
|
idntfCount: number | 0; |
||||||
|
isRefreshIdntf: boolean | false; |
||||||
|
page: number | 1; |
||||||
|
total: number | 0; |
||||||
|
} |
||||||
|
|
||||||
|
export interface SelectData { |
||||||
|
groupId: string; |
||||||
|
groupNm: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface DroneData { |
||||||
|
groupId: string; |
||||||
|
arcrftSno: number; |
||||||
|
arcrftHght: number; |
||||||
|
arcrftLngth: number; |
||||||
|
arcrftModelNm: string; |
||||||
|
arcrftTypeCd: string; |
||||||
|
arcrftWdth: number; |
||||||
|
arcrftWght: number; |
||||||
|
cameraYn: string; |
||||||
|
createDt: Date; |
||||||
|
createUserId: string; |
||||||
|
insrncYn: string; |
||||||
|
prdctCmpnNm: string; |
||||||
|
prdctDate: Date; |
||||||
|
prdctNum: string; |
||||||
|
takeoffWght: number; |
||||||
|
updateDt: Date; |
||||||
|
updateUserId: string; |
||||||
|
imageUrl: string; |
||||||
|
wghtTypeCd: string; |
||||||
|
idntfNum: string; |
||||||
|
newIdntfNum: string; |
||||||
|
idntfTypeCd: string; |
||||||
|
ownerSno: number; |
||||||
|
ownerNm: string; |
||||||
|
hpno: string; |
||||||
|
telno: string; |
||||||
|
useYn: string; |
||||||
|
file: FileList; |
||||||
|
} |
||||||
|
|
||||||
|
export interface IdntfData { |
||||||
|
idntfNum: string; |
||||||
|
newIdntfNum: string; |
||||||
|
isSave: boolean; |
||||||
|
updateDt: Date; |
||||||
|
createDt: Date; |
||||||
|
cstmrSno: number; |
||||||
|
} |
@ -0,0 +1,146 @@ |
|||||||
|
import axios from '../../../../utils/axiosInterceptor'; |
||||||
|
import qs from 'qs'; |
||||||
|
|
||||||
|
import { createAsyncThunk } from '@reduxjs/toolkit'; |
||||||
|
import { DroneData } from './droneState'; |
||||||
|
|
||||||
|
// 드론 목록 조회
|
||||||
|
export const getDroneList = createAsyncThunk( |
||||||
|
'basis/getDroneList', |
||||||
|
async (data: any) => { |
||||||
|
try { |
||||||
|
const queryString = qs.stringify(data, { |
||||||
|
addQueryPrefix: true, |
||||||
|
arrayFormat: 'repeat' |
||||||
|
}); |
||||||
|
const res = await axios.get(`api/bas/dron/list${queryString}`); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 드론 상세 조회
|
||||||
|
export const getDroneDetail = createAsyncThunk( |
||||||
|
'basis/getDroneDetail', |
||||||
|
async (id: number) => { |
||||||
|
try { |
||||||
|
const res = await axios.get(`api/bas/dron/detail/${id}`); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 드론 생성
|
||||||
|
export const createDrone = createAsyncThunk( |
||||||
|
'basis/createDrone', |
||||||
|
async (data: DroneData) => { |
||||||
|
try { |
||||||
|
const res = await axios.post('api/bas/dron/create', data); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 드론 수정
|
||||||
|
export const updateDrone = createAsyncThunk( |
||||||
|
'basis/updateDrone', |
||||||
|
async (data: DroneData) => { |
||||||
|
try { |
||||||
|
const res = await axios.put('api/bas/dron/update', data); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 드론 삭제
|
||||||
|
export const deleteDrone = createAsyncThunk( |
||||||
|
'basis/deleteDrone', |
||||||
|
async (id: number) => { |
||||||
|
try { |
||||||
|
const res = await axios.delete(`api/bas/dron/delete/${id}`); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 식별장치 목록 조회
|
||||||
|
export const getIdntfList = createAsyncThunk( |
||||||
|
'basis/getIdntfList', |
||||||
|
async (id: number) => { |
||||||
|
try { |
||||||
|
const res = await axios.get(`api/bas/dron/idntf/list/${id}`); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 식별장치 수정
|
||||||
|
export const updateIdntf = createAsyncThunk( |
||||||
|
'basis/updateIdntf', |
||||||
|
async (item: { id: number; data: any[] }) => { |
||||||
|
try { |
||||||
|
const res = await axios.put(`/api/bas/dron/idntf/update/${item.id}`, { |
||||||
|
idntfNum: item.data[0].idntfNum, |
||||||
|
ownerNm: item.data[0].ownerNm, |
||||||
|
hpno: item.data[0].hpno |
||||||
|
}); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 식별장치 삭제
|
||||||
|
export const deleteIdntf = createAsyncThunk( |
||||||
|
'basis/deleteIdntf', |
||||||
|
async (id: string) => { |
||||||
|
try { |
||||||
|
const res = await axios.delete(`api/bas/dron/idntf/delete/${id}`); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 식별장치 생성
|
||||||
|
export const createIdntf = createAsyncThunk( |
||||||
|
'basis/createIdntf', |
||||||
|
async (item: { data: any[]; arcrftSno: number }) => { |
||||||
|
try { |
||||||
|
const res = await axios.post('api/bas/dron/idntf/create', item); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// 파일 업로드
|
||||||
|
export const fileUpload = createAsyncThunk( |
||||||
|
'basis/fileUpload', |
||||||
|
async (file: any) => { |
||||||
|
try { |
||||||
|
let form = new FormData(); |
||||||
|
form.append('file', file); |
||||||
|
|
||||||
|
const res = await axios.post('api/file/upload', form); |
||||||
|
return res.data; |
||||||
|
} catch (error) { |
||||||
|
console.error(error); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
@ -0,0 +1,7 @@ |
|||||||
|
import { AppDispatch, store } from './store'; |
||||||
|
import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux'; |
||||||
|
|
||||||
|
type RootState = ReturnType<typeof store.getState>; |
||||||
|
|
||||||
|
export const useAppDispatch = () => useDispatch<AppDispatch>(); |
||||||
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; |
@ -0,0 +1,10 @@ |
|||||||
|
'use client'; |
||||||
|
import { store } from './store'; |
||||||
|
import { Provider } from 'react-redux'; |
||||||
|
|
||||||
|
type Props = { |
||||||
|
children: React.ReactNode; |
||||||
|
}; |
||||||
|
export default function ReduxProvider({ children }: Props) { |
||||||
|
return <Provider store={store}>{children}</Provider>; |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
import { combineReducers } from '@reduxjs/toolkit'; |
||||||
|
import { droneReducer } from './features/basis/drone/droneSlice'; |
||||||
|
|
||||||
|
const rootReducer = (state: any, action: any) => { |
||||||
|
const combineReducer = combineReducers({ |
||||||
|
drone: droneReducer |
||||||
|
}); |
||||||
|
|
||||||
|
return combineReducer(state, action); |
||||||
|
}; |
||||||
|
export default rootReducer; |
@ -0,0 +1,9 @@ |
|||||||
|
import { configureStore } from '@reduxjs/toolkit'; |
||||||
|
import rootReducer from './rootReducer'; |
||||||
|
|
||||||
|
export const store = configureStore({ |
||||||
|
reducer: rootReducer |
||||||
|
}); |
||||||
|
|
||||||
|
export type RootState = ReturnType<typeof store.getState>; |
||||||
|
export type AppDispatch = typeof store.dispatch; |
@ -0,0 +1,27 @@ |
|||||||
|
import axios, { AxiosInstance } from 'axios'; |
||||||
|
import { getAccessToken } from './jwtToken'; |
||||||
|
import { store } from '@/redux/store'; |
||||||
|
|
||||||
|
const axiosInstance: AxiosInstance = axios.create({ |
||||||
|
baseURL: 'http://121.190.193.50:6081/' |
||||||
|
}); |
||||||
|
|
||||||
|
axiosInstance.interceptors.request.use( |
||||||
|
async config => { |
||||||
|
config.headers['Authorization'] = |
||||||
|
'palnet eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJwYWxuZXQiLCJjc3RtclNubyI6MiwiZXhwIjoxNzA4MzA2Nzg4LCJ1c2VySWQiOiJwYWxuZXQiLCJpYXQiOjE3MDY0OTIzODh9.X5S5oF5ZWcTK6FwjpVAfRwffuwLeCHUssn1OEJbsSFJDzi-Vp_DdnfgIvWAM1ry97VmNfFsT9bpX8XhE4dRnWg'; |
||||||
|
// let accessToken = await getAccessToken();
|
||||||
|
|
||||||
|
// config.headers['Authorization'] = accessToken;
|
||||||
|
// // alert(JSON.stringify(config.headers));
|
||||||
|
// // store.dispatch({
|
||||||
|
// // // type: GLOBAL_LOADING
|
||||||
|
// // });
|
||||||
|
return config; |
||||||
|
}, |
||||||
|
error => { |
||||||
|
return Promise.reject(error); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
export default axiosInstance; |
@ -0,0 +1,20 @@ |
|||||||
|
import Cookies, { CookieAttributes, CookiesStatic } from 'js-cookie'; |
||||||
|
|
||||||
|
const CookieStorageBuilder = (cookies: CookiesStatic) => ({ |
||||||
|
setCookie: (key: string, value: string, options?: CookieAttributes) => |
||||||
|
cookies.set(key, value, { |
||||||
|
path: '/', |
||||||
|
secure: process.env.NODE_ENV === 'production' ? false : false, |
||||||
|
sameSite: 'Lax', |
||||||
|
...options |
||||||
|
}), |
||||||
|
getCookie: (key: string) => cookies.get(key), |
||||||
|
removeCookie: (key: string) => cookies.remove(key) |
||||||
|
}); |
||||||
|
|
||||||
|
export const cookieStorage = CookieStorageBuilder(Cookies); |
||||||
|
|
||||||
|
const COOKIE_BASE_NAME = 'palnet'; |
||||||
|
|
||||||
|
export const COOKIE_ACCESS_TOKEN = `${COOKIE_BASE_NAME}_accs`; |
||||||
|
export const COOKIE_REFRESH_TOKEN = `${COOKIE_BASE_NAME}_rfrs`; |
@ -0,0 +1,51 @@ |
|||||||
|
import decode from 'jwt-decode'; |
||||||
|
import { |
||||||
|
cookieStorage, |
||||||
|
COOKIE_ACCESS_TOKEN, |
||||||
|
COOKIE_REFRESH_TOKEN |
||||||
|
} from './cookie'; |
||||||
|
|
||||||
|
const JWT_FLEFIX = 'palnet '; |
||||||
|
export const checkTokenExpired = (token?: string) => { |
||||||
|
return true; |
||||||
|
// const decodedToken = decode<LoginData>(token as string);
|
||||||
|
|
||||||
|
// if (parseInt(decodedToken.exp) < dayjs().unix()) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
|
}; |
||||||
|
|
||||||
|
export const getAccessToken = async () => { |
||||||
|
let token = cookieStorage.getCookie(COOKIE_ACCESS_TOKEN); |
||||||
|
|
||||||
|
if (!token || token == undefined || token == 'undefined') { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
// if (checkTokenExpired(token)) {
|
||||||
|
// //freshtoken 으로 재발급 진행.
|
||||||
|
// const refreshToken = getRefreshToken();
|
||||||
|
// //const isRefresh = store.getState()?.authState?.isRefresh;
|
||||||
|
|
||||||
|
// if (refreshToken) {
|
||||||
|
// // if (!store.getState()?.authState?.isRefresh) {
|
||||||
|
// const decodeToken = decode<LoginData>(token as string);
|
||||||
|
// const cstmrSno: number = decodeToken.cstmrSno;
|
||||||
|
|
||||||
|
// const { data, errorCode } = await refreshTokenAPI(cstmrSno, refreshToken);
|
||||||
|
// if (errorCode === '-101') {
|
||||||
|
// cookieStorage.setCookie(COOKIE_REFRESH_TOKEN, '');
|
||||||
|
// }
|
||||||
|
// //REFHRESTH 토큰 넣기
|
||||||
|
// cookieStorage.setCookie(COOKIE_ACCESS_TOKEN, data.accessToken);
|
||||||
|
// cookieStorage.setCookie(COOKIE_REFRESH_TOKEN, data.refreshToken);
|
||||||
|
// token = data.refreshToken;
|
||||||
|
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return JWT_FLEFIX + token; |
||||||
|
}; |
Loading…
Reference in new issue