This commit is contained in:
ygx
2026-03-07 20:11:25 +08:00
parent 8fab91c5c7
commit f7bbb5ee46
74 changed files with 6540 additions and 2636 deletions

35
src/api/module/factor.ts Normal file
View File

@@ -0,0 +1,35 @@
import { request } from "@/api/request";
/** 批次列表 */
export const fetchLoanBatch = (data: { page: number, size: number }) => request.post("/factor/v1/fetch/loan_batch", data);
/** 上报列表 */
export const fetchTransferWatch = (data: { page: number, size: number }) => request.post("/factor/v1/fetch/transfer_watch", data);
/** 回盘列表 */
export const fetchTransferDown = (data: { page: number, size: number }) => request.post("/factor/v1/fetch/transfer_down", data);
/** 放款数据列表 */
export const fetchDataFile = (data: { page: number, size: number }) => request.post("/factor/v1/fetch/data_file", data);
/** 回盘数据列表 */
export const fetchDataReply = (data: { page: number, size: number }) => request.post("/factor/v1/fetch/data_reply", data);
/** 贷款支付数据列表 */
export const fetchLoanPayment = (data: { page: number, size: number, status?: number }) => request.post("/factor/v1/fetch/loan_payment", data);
/** 获取日报数据 */
export const fetchOverviewReports = (data: { page: number, size: number }) => request.post("/factor/v1/reports/overview", data);
/** 获取日报数据 */
export const fetchDailyReports = (data: { page: number, size: number }) => request.post("/factor/v1/reports/days", data);
/** 获取周报数据 */
export const fetchWeeklyReports = (data: { page: number, size: number }) => request.post("/factor/v1/reports/weeks", data);
/** 获取月报数据 */
export const fetchMonthlyReports = (data: { page: number, size: number }) => request.post("/factor/v1/reports/months", data);
/** 获取批次详情 */
export const getLoanBatchDetail = (data: { batch_id: number }) => request.post(`/factor/v1/get/batch`,data);

39
src/api/module/pmn.ts Normal file
View File

@@ -0,0 +1,39 @@
import { request } from "@/api/request";
export interface MenuItem {
id?: number;
identity?: string;
code?: string;
description?: string;
menu_icon?: string;
menu_path?: string;
parent_id?: number | null;
title?: string;
title_en?: string;
type?: number;
sort_key?: number;
order?: number; // 排序字段(用于本地排序)
app_id?: number;
created_at?: string;
children?: MenuItem[];
is_web_page?: boolean; // 是否为网页
web_url?: string; // 嵌入的网页URL
}
/** 获取菜单 */
export const fetchMenu = (data: { page: number, size: number }) => request.post("/rbac2/v1/pmn/fetch", data, { needWorkspace: true });
/** 创建菜单 */
export const createMenu = (data: MenuItem) => request.post("/rbac2/v1/pmn/create", data, { needWorkspace: true });
/** 修改菜单 */
export const modifyMenu = (data: MenuItem) => request.post("/rbac2/v1/pmn/modify", data, { needWorkspace: true });
/** 删除菜单 */
export const deleteMenu = (data: { id: MenuItem['id'] }) => request.post("/rbac2/v1/pmn/del", data, { needWorkspace: true });
/** 更新菜单排序 */
export const updateMenuOrder = (data: { pmn_id: number, sort_key: number }[]) =>
request.post("/rbac2/v1/pmn/sort", data);
/** 用户-给指定用户设置权限 */
export const userPmn = (data: { code: string; list: { id: number, pmn_id: number }[] }) => request.post("/rbac2/v1/pmn/user_pmn", data, { needWorkspace: true });
/** 用户-给指定用户设置权限 */
export const userSetPmn = (data: { list: { id: number, pmn_id: number }[] }) => request.post("/rbac2/v1/pmn/user/set_pmn", data, { needWorkspace: true });

35
src/api/module/report.ts Normal file
View File

@@ -0,0 +1,35 @@
import { request } from "@/api/request";
/** 获取报表 */
export const fetchReports = (data: { page: number, size: number, keyword?: string }) => request.get("/api/v1/report/basics", { params: data });
/** 创建报表任务 */
export const fetchReportNewTask = (keyName:string,data: any) => request.post("/api/v1/report/task/new/"+keyName, data);
/** 获取报表基础信息详情 */
export const fetchReportBasicInfo = (id: string) => request.get(`/api/v1/report/basics/${id}`);
/** 获取指定报表的调度列表 */
export const fetchReportSchedules = (report_basic_id: string) => request.get(`/api/v1/report/schedules/${report_basic_id}`);
/** 批量创建报表调度 */
export const fetchReportSchedulesBatch = (data: any) => request.post("/api/v1/report/schedules/batch", data);
/** 获取指定报表的历史记录列表 */
export const fetchReportHistories = (report_basic_id: string) => request.get(`/api/v1/report/histories/${report_basic_id}?status=2`);
/** 获取报表历史记录列表 */
export const fetchReportHistoriesList = (data: { page: number, size: number, keyword?: string }) => request.get("/api/v1/report/histories", { params: data });
/** 获取邮件推送记录列表 */
export enum PushStatus {
/** 发送成功 */
Success = 1,
/** 发送失败 */
Failed = 2
}
export const fetchReportPushesList = (data: { page: number, size: number, keyword?: string, status?: PushStatus }) => request.get("/api/v1/report/pushes", { params: data });
/** 重新发送邮件 */
export const fetchReportPushesResend = (id: number) => request.post(`/api/v1/report/pushes/${id}`);

41
src/api/module/user.ts Normal file
View File

@@ -0,0 +1,41 @@
import { request } from "@/api/request";
import { LoginRequest, UserItem } from "../types";
/** 登录 */
export const login = (data: LoginRequest) => request.post("/rbac2/v1/login", data);
/** 登出 */
export const logout = () => request.post("/rbac2/v1/logout");
/** 获取菜单列表 */
export const getMenuList = () => request.post("/rbac2/v1/user/menu");
/** 创建用户 */
export const createUser = (data: UserItem) => request.post("/rbac2/v1/user/create", data, { needWorkspace: true });
/** 获取用户详情 */
export const getUserDetail = (data: UserItem) => request.post("/rbac2/v1/user/detail", data);
/** 获取用户列表 */
export const fetchUserList = (data: { page: number, size: number, keyword?: string }) => request.post("/rbac2/v1/user/fetch", data);
/** 修改用户 */
export const modifyUser = (data: UserItem) => request.post("/rbac2/v1/user/modify", data);
/** 删除用户 */
export const deleteUser = (data: { id: UserItem['id'] }) => request.post("/rbac2/v1/user/del", data);
/** 获取所有权限【树形】 */
export const getUserPmnTree = (data: { id: UserItem['id'] }) => request.post("/rbac2/v1/user/pmn_tree", data);
/** 用户-获取所有权限【平面】 */
export const userPmn = (data: { id: UserItem['id'], workspace: string }) => request.post("/rbac2/v1/user/pmn", data, { needWorkspace: true });
/** 用户-给指定用户设置权限 */
export const userSetPmn = (data: { list: { id: number, pmn_id: number }[] }) => request.post("/rbac2/v1/user/set_pmn", data, { needWorkspace: true });
/** 用户-给指定用户编辑权限 */
export const userModifyPmn = (data: { id: UserItem['id'], list: number[] }) => request.post("/rbac2/v1/user/modify_pmn", data, { needWorkspace: true });
/** 重置密码(短信) */
export const resetUserPassword = (data: {
/** 账号 */
account: string;
/** 验证码 */
code: string;
/** 密码 */
password: string;
/** 手机号 */
phone: string;
}) => request.post("/rbac2/v1/reset", data);

91
src/api/request.ts Normal file
View File

@@ -0,0 +1,91 @@
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig
} from "axios";
import { v4 as uuidv4 } from 'uuid';
import SafeStorage, { AppStorageKey } from "@/utils/safeStorage";
console.log('import.meta.env.VITE_API_BASE_UR:', import.meta.env.VITE_API_BASE_URL)
// 1. 创建axios实例
const instance: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000,
headers: {
"Content-Type": "application/json",
"Workspace": import.meta.env.VITE_APP_WORKSPACE,
"Request-Id": uuidv4(),
},
});
// 2. 请求拦截器
instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 添加认证token示例
const token = SafeStorage.get(AppStorageKey.TOKEN);
if (token) {
config.headers.Authorization = token as string;
}
return config;
},
(error) => Promise.reject(error)
);
// 3. 响应拦截器
instance.interceptors.response.use(
(response: AxiosResponse) => {
// 统一处理响应数据格式[2](@ref)
if (response.data.status === 401) {
// token过期处理
SafeStorage.clearAppStorage();
window.location.href = "/auth/login";
}
return response.data; // 直接返回核心数据[1](@ref)
},
(error) => {
if (error?.response?.data?.error === 'Token has expired') {
// token过期处理
SafeStorage.clearAppStorage();
window.location.href = "/auth/login";
}
// 统一错误处理
console.error("API Error:", error.message);
return Promise.reject(error);
}
);
// 4. 封装核心请求方法
interface RequestConfig extends AxiosRequestConfig {
data?: unknown;
needWorkspace?: boolean;
}
export const request = {
get<T = any>(url: string, config?: RequestConfig): Promise<T> {
return instance.get(url, config);
},
post<T = any>(url: string, data = {}, config?: RequestConfig): Promise<T> {
let params: any
if (config?.needWorkspace) {
params = { workspace: import.meta.env.VITE_APP_WORKSPACE, ...data };
} else {
params = data;
}
return instance.post(url, params, config);
},
put<T = any>(url: string, data = {}, config?: RequestConfig): Promise<T> {
let params: any
if (config?.needWorkspace) {
params = { workspace: import.meta.env.VITE_APP_WORKSPACE, ...data };
} else {
params = data;
}
return instance.put(url, params, config);
},
delete<T = any>(url: string, config?: RequestConfig): Promise<T> {
return instance.delete(url, config);
}
};
export default instance;

39
src/api/types.ts Normal file
View File

@@ -0,0 +1,39 @@
/** 登录请求参数 */
export interface LoginRequest {
/** 账号 */
account: string
/** 密码 */
password: string
}
/** 登录表单数据 */
export interface LoginData {
account: string
password: string
}
/** 用户信息 */
export interface UserItem {
id?: number
username?: string
nickname?: string
email?: string
phone?: string
avatar?: string
status?: number
created_at?: string
updated_at?: string
}
/** 登录响应 */
export interface LoginResponse {
token: string
user?: UserItem
}
/** 通用响应结构 */
export interface ApiResponse<T = any> {
status: number
data: T
message?: string
}

View File

@@ -1,27 +0,0 @@
import { UserState } from '@/store/modules/user/types'
import axios from 'axios'
import type { RouteRecordNormalized } from 'vue-router'
export interface LoginData {
username: string
password: string
}
export interface LoginRes {
token: string
}
export function login(data: LoginData) {
return axios.post<LoginRes>('/api/user/login', data)
}
export function logout() {
return axios.post<LoginRes>('/api/user/logout')
}
export function getUserInfo() {
return axios.post<UserState>('/api/user/info')
}
export function getMenuList() {
return axios.post<RouteRecordNormalized[]>('/api/user/menu')
}