|
|
import axios from "axios";
import CryptoJS from "crypto-js";
/**
* ApiService 클래스
* - 재고 관리 시스템(IMS)의 모든 API 호출을 처리하는 중앙 서비스
* - 사용자 인증, 제품, 카테고리, 공급업체, 거래 등의 CRUD 작업 제공
* - 토큰 및 역할 정보를 암호화하여 로컬 스토리지에 저장
*/
class ApiService {
// API 서버의 기본 URL
static BASE_URL = "http://localhost:8080/api";
// AES 암호화에 사용되는 비밀키
static ENCRYPTION_KEY = "kitae-dev-inventory";
/**
* 데이터 암호화 기능
* @param {string} data - 암호화할 데이터
* @returns {string} AES 암호화된 문자열
*/
static encrypt(data) {
return CryptoJS.AES.encrypt(data, ApiService.ENCRYPTION_KEY).toString();
}
/**
* 데이터 복호화 기능
* @param {string} data - 복호화할 암호화된 데이터
* @returns {string} 복호화된 원본 문자열
*/
static decrypt(data) {
const bytes = CryptoJS.AES.decrypt(data, this.ENCRYPTION_KEY);
return bytes.toString(CryptoJS.enc.Utf8);
}
/**
* JWT 토큰을 암호화하여 로컬 스토리지에 저장
* @param {string} token - 저장할 JWT 토큰
*/
static saveToken(token) {
const encryptedToken = this.encrypt(token);
localStorage.setItem("token", encryptedToken)
}
/**
* 로컬 스토리지에서 암호화된 토큰을 가져와 복호화
* @returns {string|null} 복호화된 토큰 또는 null
*/
static getToken() {
const encryptedToken = localStorage.getItem("token");
if (!encryptedToken) return null;
return this.decrypt(encryptedToken);
}
/**
* 사용자 역할(Role)을 암호화하여 로컬 스토리지에 저장
* @param {string} role - 사용자 역할 (예: ADMIN, USER)
*/
static saveRole(role) {
const encryptedRole = this.encrypt(role);
localStorage.setItem("role", encryptedRole);
}
/**
* 로컬 스토리지에서 암호화된 역할을 가져와 복호화
* @returns {string|null} 복호화된 역할 또는 null
*/
static getRole() {
const encryptedRole = localStorage.getItem("role");
if (!encryptedRole) return null;
return this.decrypt(encryptedRole);
}
/**
* 로컬 스토리지에서 인증 정보(토큰, 역할) 제거
* 로그아웃 시 사용
*/
static clearAuth() {
localStorage.removeItem("token");
localStorage.removeItem("role");
}
/**
* API 요청에 필요한 HTTP 헤더 생성
* @returns {Object} Authorization 헤더와 Content-Type이 포함된 객체
*/
static getHeader() {
const token = this.getToken();
return {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
}
}
// ========== 사용자 인증 API ==========
/**
* 신규 사용자 회원가입
* @param {Object} registerData - 사용자 등록 정보 (이름, 이메일, 비밀번호 등)
* @returns {Promise<Object>} 등록된 사용자 정보
*/
static async registerUser(registerData) {
const response = await axios.post(`${this.BASE_URL}/auth/register`, registerData)
return response.data;
}
/**
* 사용자 로그인
* @param {Object} loginData - 로그인 정보 (이메일, 비밀번호)
* @returns {Promise<Object>} JWT 토큰 및 사용자 정보
*/
static async loginUser(loginData) {
const response = await axios.post(`${this.BASE_URL}/auth/login`, loginData)
return response.data;
}
// ========== 사용자 관리 API ==========
/**
* 모든 사용자 목록 조회 (관리자 전용)
* @returns {Promise<Array>} 전체 사용자 목록
*/
static async getAllUsers() {
const response = await axios.get(`${this.BASE_URL}/users/all`, {
headers: this.getHeader()
});
return response.data;
}
/**
* 현재 로그인한 사용자의 정보 조회
* @returns {Promise<Object>} 로그인된 사용자의 상세 정보
*/
static async getLoggedInUsesInfo() {
const response = await axios.get(`${this.BASE_URL}/users/current`, {
headers: this.getHeader()
});
return response.data;
}
/**
* 특정 사용자 정보 조회
* @param {number} userId - 조회할 사용자 ID
* @returns {Promise<Object>} 사용자 상세 정보
*/
static async getUserById(userId) {
const response = await axios.get(`${this.BASE_URL}/users/${userId}`, {
headers: this.getHeader()
});
return response.data;
}
/**
* 사용자 정보 수정
* @param {number} userId - 수정할 사용자 ID
* @param {Object} userData - 수정할 사용자 데이터
* @returns {Promise<Object>} 수정된 사용자 정보
*/
static async updateUser(userId, userData) {
const response = await axios.put(`${this.BASE_URL}/users/update/${userId}`, userData, {
headers: this.getHeader()
});
return response.data;
}
/**
* 사용자 삭제
* @param {number} userId - 삭제할 사용자 ID
* @returns {Promise<Object>} 삭제 결과
*/
static async deleteUser(userId) {
const response = await axios.delete(`${this.BASE_URL}/users/update/${userId}`, {
headers: this.getHeader()
});
return response.data;
}
// ========== 제품 관리 API ==========
/**
* 신규 제품 등록
* @param {FormData} formData - 제품 정보 및 이미지 파일
* @returns {Promise<Object>} 등록된 제품 정보
*/
static async addProduct(formData) {
// multipart/form-data를 사용하여 파일 업로드 처리
const response = await axios.post(`${this.BASE_URL}/products/add`, formData, {
headers: {
...this.getHeader(), // 기존 헤더에 추가
"Content-Type": "multipart/form-data" // 명시적 설정
}
});
return response.data;
}
/**
* 기존 제품 정보 수정
* @param {FormData} formData - 수정할 제품 정보 및 이미지 파일
* @returns {Promise<Object>} 수정된 제품 정보
*/
static async updateProduct(formData) {
// multipart/form-data를 사용하여 파일 업로드 처리
const response = await axios.put(`${this.BASE_URL}/products/update`, formData, {
headers: {
...this.getHeader(),
"Content-Type": "multipart/form-data"
}
});
return response.data;
}
/**
* 전체 제품 목록 조회
* @returns {Promise<Array>} 모든 제품 목록
*/
static async getAllProducts() {
const response = await axios.get(`${this.BASE_URL}/products/all`, {
headers: this.getHeader()
});
return response.data;
}
/**
* 특정 제품 상세 정보 조회
* @param {number} productId - 조회할 제품 ID
* @returns {Promise<Object>} 제품 상세 정보
*/
static async getProductById(productId) {
const response = await axios.get(`${this.BASE_URL}/products/${productId}`, {
headers: this.getHeader()
});
return response.data;
}
/**
* 제품 검색 기능
* @param {string} searchValue - 검색할 키워드
* @returns {Promise<Array>} 검색 결과 제품 목록
*/
static async searchProduct(searchValue) {
const response = await axios.get(`${this.BASE_URL}/products/search`, {
params: { searchValue }, // 쿼리 파라미터로 검색어 전달
headers: this.getHeader() // 기존 헤더 포함
});
return response.data;
}
/**
* 제품 삭제
* @param {number} productId - 삭제할 제품 ID
* @returns {Promise<Object>} 삭제 결과
*/
static async deleteProduct(productId) {
const response = await axios.delete(`${this.BASE_URL}/products/delete/${productId}`, {
headers: this.getHeader()
});
return response.data;
}
// ========== 카테고리 관리 API ==========
/**
* 신규 카테고리 생성
* @param {Object} category - 카테고리 정보 (이름, 설명 등)
* @returns {Promise<Object>} 생성된 카테고리 정보
*/
static async createCategory(category) {
const response = await axios.post(`${this.BASE_URL}/categories/add`, category, {
headers: this.getHeader()
})
return response.data;
}
/**
* 전체 카테고리 목록 조회
* @returns {Promise<Array>} 모든 카테고리 목록
*/
static async getAllCategory() {
const response = await axios.get(`${this.BASE_URL}/categories/all`, {
headers: this.getHeader()
})
return response.data;
}
/**
* 특정 카테고리 조회
* @param {number} categoryId - 조회할 카테고리 ID
* @returns {Promise<Object>} 카테고리 상세 정보
*/
static async getCategoryById(categoryId) {
const response = await axios.get(`${this.BASE_URL}/categories/${categoryId}`, {
headers: this.getHeader()
})
return response.data;
}
/**
* 카테고리 정보 수정
* @param {number} categoryId - 수정할 카테고리 ID
* @param {Object} categoryData - 수정할 카테고리 데이터
* @returns {Promise<Object>} 수정된 카테고리 정보
*/
static async updateCategory(categoryId, categoryData) {
const response = await axios.put(`${this.BASE_URL}/categories/update/${categoryId}`, categoryData, {
headers: this.getHeader()
})
return response.data;
}
/**
* 카테고리 삭제
* @param {number} categoryId - 삭제할 카테고리 ID
* @returns {Promise<Object>} 삭제 결과
*/
static async deleteCategory(categoryId) {
const response = await axios.delete(`${this.BASE_URL}/categories/delete/${categoryId}`, {
headers: this.getHeader()
})
return response.data;
}
// ========== 공급업체 관리 API ==========
/**
* 신규 공급업체 등록
* @param {Object} supplierData - 공급업체 정보 (이름, 연락처, 주소 등)
* @returns {Promise<Object>} 등록된 공급업체 정보
*/
static async addSupplier(supplierData) {
const response = await axios.post(`${this.BASE_URL}/suppliers/add`, supplierData, {
headers: this.getHeader()
})
return response.data;
}
/**
* 전체 공급업체 목록 조회
* @returns {Promise<Array>} 모든 공급업체 목록
*/
static async getAllSuppliers() {
const response = await axios.get(`${this.BASE_URL}/suppliers/all`, {
headers: this.getHeader()
})
return response.data;
}
/**
* 특정 공급업체 조회
* @param {number} supplierId - 조회할 공급업체 ID
* @returns {Promise<Object>} 공급업체 상세 정보
*/
static async getSupplierById(supplierId) {
const response = await axios.get(`${this.BASE_URL}/suppliers/${supplierId}`, {
headers: this.getHeader()
})
return response.data;
}
/**
* 공급업체 정보 수정
* @param {number} supplierId - 수정할 공급업체 ID
* @param {Object} supplierData - 수정할 공급업체 데이터
* @returns {Promise<Object>} 수정된 공급업체 정보
*/
static async updateSupplier(supplierId, supplierData) {
const response = await axios.put(`${this.BASE_URL}/suppliers/update/${supplierId}`, supplierData, {
headers: this.getHeader()
})
return response.data;
}
/**
* 공급업체 삭제
* @param {number} supplierId - 삭제할 공급업체 ID
* @returns {Promise<Object>} 삭제 결과
*/
static async deleteSupplier(supplierId) {
const response = await axios.delete(`${this.BASE_URL}/suppliers/delete/${supplierId}`, {
headers: this.getHeader()
})
return response.data;
}
// ========== 거래(Transaction) 관리 API ==========
/**
* 제품 구매(입고) 거래 등록
* @param {Object} body - 구매 거래 정보 (제품, 수량, 가격, 공급업체 등)
* @returns {Promise<Object>} 등록된 구매 거래 정보
*/
static async purchaseProduct(body) {
const response = await axios.post(`${this.BASE_URL}/transactions/purchase`, body, {
headers: this.getHeader()
})
return response.data;
}
/**
* 제품 판매(출고) 거래 등록
* @param {Object} body - 판매 거래 정보 (제품, 수량, 가격 등)
* @returns {Promise<Object>} 등록된 판매 거래 정보
*/
static async sellProduct(body) {
const response = await axios.post(`${this.BASE_URL}/transactions/sell`, body, {
headers: this.getHeader()
})
return response.data;
}
/**
* 제품 반품(공급업체로 반환) 거래 등록
* @param {Object} body - 반품 거래 정보 (제품, 수량, 반품 사유 등)
* @returns {Promise<Object>} 등록된 반품 거래 정보
*/
static async returnToSupplier(body) {
const response = await axios.post(`${this.BASE_URL}/transactions/return`, body, {
headers: this.getHeader()
})
return response.data;
}
/**
* 전체 거래 목록 조회 (필터링 옵션 포함)
* @param {string} filter - 거래 유형 필터 (예: PURCHASE, SELL, RETURN)
* @returns {Promise<Array>} 필터링된 거래 목록
*/
static async getAllTransactions(filter) {
const response = await axios.get(`${this.BASE_URL}/transactions/all`, {
headers: this.getHeader(),
params: { filter }
})
return response.data;
}
/**
* 특정 월/연도의 거래 내역 조회
* @param {number} month - 조회할 월 (1-12)
* @param {number} year - 조회할 연도
* @returns {Promise<Array>} 해당 기간의 거래 목록
*/
static async geTransactionsByMonthAndYear(month, year) {
const response = await axios.get(`${this.BASE_URL}/transactions/by-month-year`, {
headers: this.getHeader(),
params: {
month: month,
year: year
}
})
return response.data;
}
/**
* 특정 거래 상세 정보 조회
* @param {number} transactionId - 조회할 거래 ID
* @returns {Promise<Object>} 거래 상세 정보
*/
static async getTransactionById(transactionId) {
const response = await axios.get(`${this.BASE_URL}/transactions/${transactionId}`, {
headers: this.getHeader()
})
return response.data;
}
/**
* 거래 상태 변경
* @param {number} transactionId - 상태를 변경할 거래 ID
* @param {string} status - 새로운 거래 상태
* @returns {Promise<Object>} 변경된 거래 정보
*/
static async updateTransactionStatus(transactionId, status) {
const response = await axios.put(`${this.BASE_URL}/transactions/${transactionId}`, status, {
headers: this.getHeader()
})
return response.data;
}
// ========== 인증 상태 확인 유틸리티 ==========
/**
* 사용자 로그아웃 처리
* 로컬 스토리지에서 인증 정보를 제거
*/
static logout() {
this.clearAuth()
}
/**
* 사용자 인증 여부 확인
* @returns {boolean} 로그인 상태 여부 (true: 로그인됨, false: 로그아웃됨)
*/
static isAuthenticated() {
const token = this.getToken();
// !!를 사용하여 토큰 존재 여부를 boolean으로 변환
return !!token;
}
/**
* 관리자 권한 확인
* @returns {boolean} 관리자 권한 여부 (true: 관리자, false: 일반 사용자)
*/
static isAdmin() {
const role = this.getRole();
return role === "ADMIN";
}
}
export default ApiService;
