162 lines
12 KiB
TypeScript
162 lines
12 KiB
TypeScript
import axios from 'axios'
|
|
|
|
const api = axios.create({ baseURL: '' })
|
|
|
|
api.interceptors.request.use(config => {
|
|
const token = localStorage.getItem('esn_token')
|
|
if (token) config.headers.Authorization = `Bearer ${token}`
|
|
return config
|
|
})
|
|
|
|
api.interceptors.response.use(
|
|
res => res,
|
|
err => {
|
|
if (err.response?.status === 401) {
|
|
localStorage.removeItem('esn_token')
|
|
if (location.pathname !== '/login') location.href = '/login'
|
|
}
|
|
return Promise.reject(err)
|
|
}
|
|
)
|
|
|
|
export default api
|
|
|
|
const unwrap = (p: Promise<any>) => p.then(r => r.data?.data)
|
|
|
|
// ── Auth ──────────────────────────────────────────────────────────────────
|
|
export const login = (username: string, password: string) =>
|
|
api.post('/api/auth/login', { username, password })
|
|
export const getMe = () => api.get('/api/auth/me')
|
|
export const logout = () => api.post('/api/auth/logout')
|
|
|
|
// ── 2FA / OTP / 계정 보안 (마이페이지, access 토큰 필요) ─────────────────────
|
|
// 보안 불변: setup 응답(secret/qrImage)은 화면 표시용만 — 로그/저장 금지. raw 응답 반환(호출부 res.data.data).
|
|
export const otpSetup = () => api.post('/api/auth/otp/setup')
|
|
export const otpConfirm = (code: string) => api.post('/api/auth/otp/confirm', { code })
|
|
export const otpDisable = () => api.post('/api/auth/otp/disable')
|
|
export const changePassword = (currentPassword: string, newPassword: string) =>
|
|
api.post('/api/auth/change-password', { currentPassword, newPassword })
|
|
// 관리자 OTP 초기화 — 대상 사용자 OTP 해제(다음 로그인 시 재등록). 시크릿 미조회.
|
|
export const adminOtpReset = (id: number) => unwrap(api.post(`/api/users/${id}/otp-reset`))
|
|
|
|
// ── Auth: 로그인 보조 3종 (공개 — 회원가입 승인대기 / 아이디찾기 / 비밀번호 초기화) ──
|
|
export interface SignupReq {
|
|
username: string; password: string; name: string;
|
|
email: string; phone: string; tenantCode: string
|
|
}
|
|
export interface SignupRes { username: string; status: string }
|
|
export interface FindIdRes { found: boolean; maskedUsername: string }
|
|
|
|
export const signup = (d: SignupReq) =>
|
|
unwrap(api.post('/api/auth/signup', d)) as Promise<SignupRes>
|
|
export const findId = (name: string, email: string) =>
|
|
unwrap(api.post('/api/auth/find-id', { name, email })) as Promise<FindIdRes>
|
|
export const resetPassword = (username: string, name: string, email: string) =>
|
|
api.post('/api/auth/reset-password', { username, name, email })
|
|
|
|
// ── Dashboard ────────────────────────────────────────────────────────────
|
|
export const getDashboard = (tenantCode?: string) =>
|
|
unwrap(api.get(`/api/dashboard${tenantCode ? `?tenantCode=${tenantCode}` : ''}`))
|
|
|
|
// ── Tenants ──────────────────────────────────────────────────────────────
|
|
export const getTenants = () => unwrap(api.get('/api/tenants'))
|
|
export const createTenant = (d: object) => unwrap(api.post('/api/tenants', d))
|
|
export const updateTenant = (id: number, d: object) => unwrap(api.put(`/api/tenants/${id}`, d))
|
|
export const deleteTenant = (id: number) => api.delete(`/api/tenants/${id}`)
|
|
|
|
// ── Stores ───────────────────────────────────────────────────────────────
|
|
export const getStores = (params?: object) => unwrap(api.get('/api/stores', { params }))
|
|
export const getStore = (id: number) => unwrap(api.get(`/api/stores/${id}`))
|
|
export const createStore = (d: object) => unwrap(api.post('/api/stores', d))
|
|
export const updateStore = (id: number, d: object) => unwrap(api.put(`/api/stores/${id}`, d))
|
|
export const deleteStore = (id: number) => api.delete(`/api/stores/${id}`)
|
|
|
|
// ── Store Groups ─────────────────────────────────────────────────────────
|
|
export const getStoreGroups = (tenantCode?: string) =>
|
|
unwrap(api.get('/api/store-groups', { params: { tenantCode } }))
|
|
export const createStoreGroup = (d: object) => unwrap(api.post('/api/store-groups', d))
|
|
export const updateStoreGroup = (id: number, d: object) => unwrap(api.put(`/api/store-groups/${id}`, d))
|
|
export const deleteStoreGroup = (id: number) => api.delete(`/api/store-groups/${id}`)
|
|
|
|
// ── Templates ────────────────────────────────────────────────────────────
|
|
export const getTemplates = (params?: object) => unwrap(api.get('/api/templates', { params }))
|
|
export const createTemplate = (d: object) => unwrap(api.post('/api/templates', d))
|
|
export const updateTemplate = (id: number, d: object) => unwrap(api.put(`/api/templates/${id}`, d))
|
|
export const deleteTemplate = (id: number) => api.delete(`/api/templates/${id}`)
|
|
|
|
// ── POS CVT ──────────────────────────────────────────────────────────────
|
|
export const getPosCvt = (params?: object) => unwrap(api.get('/api/pos-cvt', { params }))
|
|
export const processPosCvt = (id: number) => unwrap(api.put(`/api/pos-cvt/${id}/process`))
|
|
export const ignorePosCvt = (id: number) => unwrap(api.put(`/api/pos-cvt/${id}/ignore`))
|
|
|
|
// ── Alarms ───────────────────────────────────────────────────────────────
|
|
export const getAlarms = (params?: object) => unwrap(api.get('/api/alarms', { params }))
|
|
export const createAlarm = (d: object) => unwrap(api.post('/api/alarms', d))
|
|
export const resolveAlarm = (id: number, resolution: string) =>
|
|
unwrap(api.put(`/api/alarms/${id}/resolve`, { resolution }))
|
|
export const deleteAlarm = (id: number) => api.delete(`/api/alarms/${id}`)
|
|
|
|
// ── HCore ────────────────────────────────────────────────────────────────
|
|
export const getHCore = (params?: object) => unwrap(api.get('/api/hcore', { params }))
|
|
export const updateHCoreStatus = (id: number, status: string) =>
|
|
unwrap(api.put(`/api/hcore/${id}/status`, { status }))
|
|
|
|
// ── Works ────────────────────────────────────────────────────────────────
|
|
export const getWorks = (params?: object) => unwrap(api.get('/api/works', { params }))
|
|
export const createWork = (d: object) => unwrap(api.post('/api/works', d))
|
|
export const updateWork = (id: number, d: object) => unwrap(api.put(`/api/works/${id}`, d))
|
|
export const deleteWork = (id: number) => api.delete(`/api/works/${id}`)
|
|
|
|
// ── Firmware ─────────────────────────────────────────────────────────────
|
|
export const getFirmware = (params?: object) => unwrap(api.get('/api/firmware', { params }))
|
|
export const createFirmware = (d: object) => unwrap(api.post('/api/firmware', d))
|
|
export const deleteFirmware = (id: number) => api.delete(`/api/firmware/${id}`)
|
|
|
|
// ── Users ────────────────────────────────────────────────────────────────
|
|
export const getUsers = (params?: object) => unwrap(api.get('/api/users', { params }))
|
|
export const createUser = (d: object) => unwrap(api.post('/api/users', d))
|
|
export const updateUser = (id: number, d: object) => unwrap(api.put(`/api/users/${id}`, d))
|
|
export const deleteUser = (id: number) => api.delete(`/api/users/${id}`)
|
|
|
|
// ── Products ─────────────────────────────────────────────────────────────
|
|
export const getProducts = (params?: object) => unwrap(api.get('/api/products', { params }))
|
|
export const createProduct = (d: object) => unwrap(api.post('/api/products', d))
|
|
export const updateProduct = (id: number, d: object) => unwrap(api.put(`/api/products/${id}`, d))
|
|
export const deleteProduct = (id: number) => api.delete(`/api/products/${id}`)
|
|
|
|
// ── Admin: 감사 로그 ───────────────────────────────────────────────────────
|
|
export const getAuditLogs = (params?: object) => unwrap(api.get('/api/admin/audit', { params }))
|
|
export const getAuditCount = (params?: object) => unwrap(api.get('/api/admin/audit/count', { params }))
|
|
|
|
// ── Admin: 시스템 설정 ─────────────────────────────────────────────────────
|
|
export const getSettings = (category?: string) =>
|
|
unwrap(api.get('/api/admin/settings', { params: category ? { category } : {} }))
|
|
export const updateSetting = (key: string, value: string) =>
|
|
unwrap(api.put(`/api/admin/settings/${encodeURIComponent(key)}`, { value }))
|
|
|
|
// ── Users (active toggle) ──────────────────────────────────────────────────
|
|
export const setUserActive = (id: number, active: boolean) =>
|
|
unwrap(api.put(`/api/users/${id}/active`, { active }))
|
|
|
|
// ── AI ───────────────────────────────────────────────────────────────────
|
|
export const analyzeAlarm = (d: object) => unwrap(api.post('/api/ai/analyze-alarm', d))
|
|
export const classifyPos = (d: object) => unwrap(api.post('/api/ai/classify-pos', d))
|
|
export const aiChat = (message: string) => unwrap(api.post('/api/ai/chat', { message }))
|
|
|
|
// ── AI 기법 (중앙 guardia-rag 경유 — 테넌트 격리) ─────────────────────────────
|
|
// X-Tenant-Code 헤더로 테넌트 격리. 토글 조회/변경 + 대표 기능(/agent·/structured) 경유.
|
|
export const ragToggles = (tenantCode?: string) =>
|
|
unwrap(api.get('/api/ai/rag/toggles', { params: { tenantCode } }))
|
|
export const ragUpdateToggle = (key: string, value: string | number | boolean, tenantCode?: string) =>
|
|
unwrap(api.put(`/api/ai/rag/toggles/${key}`, { value, tenantCode },
|
|
tenantCode ? { headers: { 'X-Tenant-Code': tenantCode } } : undefined))
|
|
export const ragAnalyzeAlarm = (d: object, tenantCode?: string) =>
|
|
unwrap(api.post('/api/ai/rag/analyze-alarm', d,
|
|
tenantCode ? { headers: { 'X-Tenant-Code': tenantCode } } : undefined))
|
|
export const ragClassifyPos = (d: object, tenantCode?: string) =>
|
|
unwrap(api.post('/api/ai/rag/classify-pos', d,
|
|
tenantCode ? { headers: { 'X-Tenant-Code': tenantCode } } : undefined))
|
|
export const ragFeedback = (d: object, tenantCode?: string) =>
|
|
unwrap(api.post('/api/ai/rag/feedback', d,
|
|
tenantCode ? { headers: { 'X-Tenant-Code': tenantCode } } : undefined))
|