feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
import request from './request'
export interface LoginRes {
access_token: string
refresh_token: string
token_type: string
expires_in: number
}
export interface UserInfo {
id: number
username: string
email?: string
real_name?: string
phone?: string
is_active: boolean
is_superuser: boolean
dept?: { id: number; name: string }
roles: { id: number; name: string; code: string }[]
}
export function login(username: string, password: string): Promise<LoginRes> {
return request.post('/auth/login', { username, password })
}
export function getMe(): Promise<UserInfo> {
return request.get('/users/me')
}
+78
View File
@@ -0,0 +1,78 @@
import request from './request'
export interface CategoryItem {
id: number
parent_id?: number
level: number
code: string
name: string
description?: string
sort_order: number
children?: CategoryItem[]
}
export interface DataLevel {
id: number
code: string
name: string
description?: string
color: string
control_requirements?: Record<string, any>
}
export interface RecognitionRule {
id: number
template_id: number
category_id?: number
level_id?: number
rule_type: string
rule_name?: string
rule_content: string
target_field: string
priority: number
is_active: boolean
hit_count: number
category_name?: string
level_name?: string
level_color?: string
}
export function getCategoryTree() {
return request.get('/classifications/categories/tree')
}
export function createCategory(data: Partial<CategoryItem>) {
return request.post('/classifications/categories', data)
}
export function updateCategory(id: number, data: Partial<CategoryItem>) {
return request.put(`/classifications/categories/${id}`, data)
}
export function deleteCategory(id: number) {
return request.delete(`/classifications/categories/${id}`)
}
export function getDataLevels() {
return request.get('/classifications/levels')
}
export function getRules(params?: { template_id?: number; keyword?: string; page?: number; page_size?: number }) {
return request.get('/classifications/rules', { params })
}
export function createRule(data: Partial<RecognitionRule>) {
return request.post('/classifications/rules', data)
}
export function updateRule(id: number, data: Partial<RecognitionRule>) {
return request.put(`/classifications/rules/${id}`, data)
}
export function deleteRule(id: number) {
return request.delete(`/classifications/rules/${id}`)
}
export function getTemplates() {
return request.get('/classifications/templates')
}
+49
View File
@@ -0,0 +1,49 @@
import request from './request'
export interface DataSourceItem {
id: number
name: string
source_type: string
host?: string
port?: number
database_name?: string
username?: string
status: string
created_at: string
}
export interface DataSourceForm {
name: string
source_type: string
host?: string
port?: number
database_name?: string
username?: string
password?: string
extra_params?: string
dept_id?: number
}
export function getDataSources(params?: { page?: number; page_size?: number; keyword?: string }) {
return request.get('/datasources', { params })
}
export function createDataSource(data: DataSourceForm) {
return request.post('/datasources', data)
}
export function updateDataSource(id: number, data: Partial<DataSourceForm>) {
return request.put(`/datasources/${id}`, data)
}
export function deleteDataSource(id: number) {
return request.delete(`/datasources/${id}`)
}
export function testConnection(data: Partial<DataSourceForm>) {
return request.post('/datasources/test-connection', data)
}
export function syncMetadata(sourceId: number) {
return request.post(`/metadata/sync/${sourceId}`)
}
+29
View File
@@ -0,0 +1,29 @@
import request from './request'
export interface TreeNode {
id: number
name: string
type: string
children?: TreeNode[]
meta?: Record<string, any>
}
export interface DataColumn {
id: number
table_id: number
name: string
data_type?: string
length?: number
comment?: string
is_nullable: boolean
sample_data?: string
created_at: string
}
export function getMetadataTree(sourceId?: number) {
return request.get('/metadata/tree', { params: { source_id: sourceId } })
}
export function getColumns(params: { table_id?: number; keyword?: string; page?: number; page_size?: number }) {
return request.get('/metadata/columns', { params })
}
+39
View File
@@ -0,0 +1,39 @@
import request from './request'
export interface ProjectItem {
id: number
name: string
template_id: number
status: string
description?: string
target_source_ids?: string
planned_start?: string
planned_end?: string
created_at: string
stats?: {
total: number
auto: number
manual: number
reviewed: number
}
}
export function getProjects(params?: { page?: number; page_size?: number; keyword?: string }) {
return request.get('/projects', { params })
}
export function getProject(id: number) {
return request.get(`/projects/${id}`)
}
export function createProject(data: { name: string; template_id: number; target_source_ids?: string; description?: string }) {
return request.post('/projects', null, { params: data })
}
export function deleteProject(id: number) {
return request.delete(`/projects/${id}`)
}
export function autoClassifyProject(id: number) {
return request.post(`/projects/${id}/auto-classify`)
}
+45
View File
@@ -0,0 +1,45 @@
import axios, { type AxiosError, type InternalAxiosRequestConfig } from 'axios'
import { ElMessage } from 'element-plus'
const request = axios.create({
baseURL: (import.meta as any).env?.VITE_API_BASE_URL || '/api/v1',
timeout: 30000,
})
request.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem('pdg_token')
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
}
)
request.interceptors.response.use(
(response) => {
const res = response.data
if (res.code !== 200) {
ElMessage.error(res.message || '请求失败')
return Promise.reject(new Error(res.message))
}
return res.data
},
(error: AxiosError) => {
const status = error.response?.status
if (status === 401) {
ElMessage.error('登录已过期,请重新登录')
localStorage.removeItem('pdg_token')
localStorage.removeItem('pdg_refresh')
window.location.href = '/login'
} else {
ElMessage.error((error.response?.data as any)?.message || '网络错误')
}
return Promise.reject(error)
}
)
export default request
+37
View File
@@ -0,0 +1,37 @@
import request from './request'
export interface TaskItem {
id: number
name: string
project_id: number
status: string
deadline?: string
created_at: string
}
export interface TaskResultItem {
result_id: number
column_id: number
column_name: string
data_type?: string
comment?: string
table_name?: string
database_name?: string
source_name?: string
category_id?: number
category_name?: string
level_id?: number
level_name?: string
level_color?: string
source: string
confidence: number
status: string
}
export function getMyTasks(params?: { status?: string }) {
return request.get('/tasks/my-tasks', { params })
}
export function getTaskItems(taskId: number) {
return request.get(`/tasks/my-tasks/${taskId}/items`)
}