chore: 初始化uniapp前端项目基础框架

新增项目配置、静态资源、工具类、状态管理、API接口、组件库集成等全套基础代码,完成项目初始化搭建
This commit is contained in:
zhangtao
2026-08-02 03:49:27 +08:00
parent 7f8320d3ed
commit 3c9b77f994
278 changed files with 55387 additions and 2 deletions
+46
View File
@@ -0,0 +1,46 @@
/// <reference types='./globals.d.ts' />
/* tslint:disable */
/* eslint-disable */
/**
* Swagger Petstore - OpenAPI 3.0 - version 1.0.27
*
* This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about
Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we&#x27;ve switched to the design first approach!
You can now help us improve the API whether it&#x27;s by making changes to the definition itself or to the code.
That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
Some useful links:
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
*
* OpenAPI version: 3.0.4
*
* Contact:
*
* NOTE: This file is auto generated by the alova's vscode plugin.
*
* https://alova.js.org/devtools/vscode
*
* **Do not edit the file manually.**
*/
export default {
'pet.updatePet': ['PUT', '/pet'],
'pet.addPet': ['POST', '/pet'],
'pet.findPetsByStatus': ['GET', '/pet/findByStatus'],
'pet.findPetsByTags': ['GET', '/pet/findByTags'],
'pet.getPetById': ['GET', '/pet/{petId}'],
'pet.updatePetWithForm': ['POST', '/pet/{petId}'],
'pet.deletePet': ['DELETE', '/pet/{petId}'],
'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'],
'store.getInventory': ['GET', '/store/inventory'],
'store.placeOrder': ['POST', '/store/order'],
'store.getOrderById': ['GET', '/store/order/{orderId}'],
'store.deleteOrder': ['DELETE', '/store/order/{orderId}'],
'user.createUser': ['POST', '/user'],
'user.createUsersWithListInput': ['POST', '/user/createWithList'],
'user.loginUser': ['GET', '/user/login'],
'user.logoutUser': ['GET', '/user/logout'],
'user.getUserByName': ['GET', '/user/{username}'],
'user.updateUser': ['PUT', '/user/{username}'],
'user.deleteUser': ['DELETE', '/user/{username}']
};
+106
View File
@@ -0,0 +1,106 @@
/*
* @Author: weisheng
* @Date: 2025-04-17 15:58:11
* @LastEditTime: 2025-06-15 21:47:22
* @LastEditors: weisheng
* @Description: Alova response and error handlers
* @FilePath: /wot-starter/src/api/core/handlers.ts
*/
import type { Method } from 'alova'
import router from '@/router'
// Custom error class for API errors
export class ApiError extends Error {
code: number
data?: any
constructor(message: string, code: number, data?: any) {
super(message)
this.name = 'ApiError'
this.code = code
this.data = data
}
}
// Define a type for the expected API response structure
interface ApiResponse {
code: number
msg?: string
data?: any
success?: boolean
total?: number
more?: boolean
}
// Handle successful responses
export async function handleAlovaResponse(
response: UniApp.RequestSuccessCallbackResult | UniApp.UploadFileSuccessCallbackResult | UniApp.DownloadSuccessData,
) {
const globalToast = useGlobalToast()
// Extract status code and data from UniApp response
const { statusCode, data } = response as UniNamespace.RequestSuccessCallbackResult
// 处理401/403错误(如果不是在handleAlovaResponse中处理的)
if ((statusCode === 401 || statusCode === 403)) {
// 如果是未授权错误,清除用户信息并跳转到登录页
globalToast.error({ msg: '登录已过期,请重新登录!', duration: 500 })
const timer = setTimeout(() => {
clearTimeout(timer)
router.replaceAll({ name: 'login' })
}, 500)
throw new ApiError('登录已过期,请重新登录!', statusCode, data)
}
// Handle HTTP error status codes
if (statusCode >= 400) {
globalToast.error(`Request failed with status: ${statusCode}`)
throw new ApiError(`Request failed with status: ${statusCode}`, statusCode, data)
}
// The data is already parsed by UniApp adapter
const json = data as ApiResponse
// Log response in development
if (import.meta.env.MODE === 'development') {
console.log('[Alova Response]', json)
}
// Return data for successful responses
return json
}
// Handle request errors
export function handleAlovaError(error: any, method: Method) {
const globalToast = useGlobalToast()
// Log error in development
if (import.meta.env.MODE === 'development') {
console.error('[Alova Error]', error, method)
}
// 处理401/403错误(如果不是在handleAlovaResponse中处理的)
if (error instanceof ApiError && (error.code === 401 || error.code === 403)) {
// 如果是未授权错误,清除用户信息并跳转到登录页
globalToast.error({ msg: '登录已过期,请重新登录!', duration: 500 })
const timer = setTimeout(() => {
clearTimeout(timer)
router.replaceAll({ name: 'login' })
}, 500)
throw new ApiError('登录已过期,请重新登录!', error.code, error.data)
}
// Handle different types of errors
if (error.name === 'NetworkError') {
globalToast.error('网络错误,请检查您的网络连接')
}
else if (error.name === 'TimeoutError') {
globalToast.error('请求超时,请重试')
}
else if (error instanceof ApiError) {
globalToast.error(error.message || '请求失败')
}
else {
globalToast.error('发生意外错误')
}
throw error
}
+55
View File
@@ -0,0 +1,55 @@
import AdapterUniapp from '@alova/adapter-uniapp'
import { createAlova } from 'alova'
import vueHook from 'alova/vue'
import mockAdapter from '../mock/mockAdapter'
import { handleAlovaError, handleAlovaResponse } from './handlers'
export const alovaInstance = createAlova({
baseURL: import.meta.env.VITE_API_BASE_URL || 'https://petstore3.swagger.io/api/v3',
...AdapterUniapp({
mockRequest: mockAdapter,
}),
statesHook: vueHook,
beforeRequest: (method) => {
// Add content type for POST/PUT/PATCH requests
if (['POST', 'PUT', 'PATCH'].includes(method.type)) {
method.config.headers['Content-Type'] = 'application/json'
}
// Add timestamp to prevent caching for GET requests
if (method.type === 'GET' && CommonUtil.isObj(method.config.params)) {
method.config.params._t = Date.now()
}
// Log request in development
if (import.meta.env.MODE === 'development') {
console.log(`[Alova Request] ${method.type} ${method.url}`, method.data || method.config.params)
console.log(`[API Base URL] ${import.meta.env.VITE_API_BASE_URL}`)
console.log(`[Environment] ${import.meta.env.VITE_ENV_NAME}`)
}
},
// Response handlers
responded: {
// Success handler
onSuccess: handleAlovaResponse,
// Error handler
onError: handleAlovaError,
// Complete handler - runs after success or error
onComplete: async () => {
// Any cleanup or logging can be done here
},
},
// We'll use the middleware in the hooks
// middleware is not directly supported in createAlova options
// Default request timeout (10 seconds)
timeout: 60000,
// 设置为null即可全局关闭全部请求缓存
cacheFor: null,
})
export default alovaInstance
+92
View File
@@ -0,0 +1,92 @@
/**
* 延迟加载中间件
* 延迟显示加载状态,防止快速请求导致的闪烁
* @param delay 显示加载状态前的延迟时间(毫秒)
* @returns Alova 中间件
*/
export function createDelayLoadingMiddleware(delay = 300) {
return async (context: any, next: any) => {
context.controlLoading()
const { loading } = context.proxyStates
const timer = setTimeout(() => {
loading.v = true
}, delay)
await next()
loading.v = false
clearTimeout(timer)
}
}
/**
* 全局加载中间件
* 为所有请求显示全局加载指示器,支持延迟显示
*
* 使用示例:
* ```typescript
* // 1. 基本用法
* const { send: submit } = useRequest(method, {
* middleware: createGlobalLoadingMiddleware()
* });
*
* // 2. 自定义延迟时间和加载文本
* const { send: submit } = useRequest(method, {
* middleware: createGlobalLoadingMiddleware({
* delay: 500, // 延迟 500ms 显示加载指示器,防止闪烁
* loadingText: '正在提交...', // 自定义加载文本
* })
* });
* ```
*
* @param options 加载选项
* @param options.delay 显示加载指示器前的延迟时间(毫秒),默认 300ms
* @param options.loadingText 加载指示器显示的文本,默认为 'Loading...'
* @returns Alova 中间件
*/
export function createGlobalLoadingMiddleware(options: {
delay?: number
loadingText?: string
} = {}) {
const {
delay = 0,
loadingText = 'Loading...',
} = options
return async (ctx: any, next: any) => {
// 自行控制loading
ctx.controlLoading()
const globalLoading = useGlobalLoading()
let timer: ReturnType<typeof setTimeout> | null = null
// 如果delay为0或未设置,直接显示loading
if (delay <= 0) {
globalLoading.loading(loadingText)
}
else {
// 延迟特定时间显示全局loading
timer = setTimeout(() => {
globalLoading.loading(loadingText)
}, delay)
}
try {
await next()
}
finally {
// 清除定时器并关闭loading
if (timer) {
clearTimeout(timer)
}
globalLoading.close()
}
}
}
// 导出延迟加载中间件作为默认中间件
export const defaultMiddleware = createDelayLoadingMiddleware()
export default defaultMiddleware
+118
View File
@@ -0,0 +1,118 @@
/* tslint:disable */
/* eslint-disable */
/**
* Swagger Petstore - OpenAPI 3.0 - version 1.0.27
*
* This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about
Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we&#x27;ve switched to the design first approach!
You can now help us improve the API whether it&#x27;s by making changes to the definition itself or to the code.
That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
Some useful links:
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
*
* OpenAPI version: 3.0.4
*
* Contact:
*
* NOTE: This file is auto generated by the alova's vscode plugin.
*
* https://alova.js.org/devtools/vscode
*
* **Do not edit the file manually.**
*/
import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova';
import { Method } from 'alova';
import apiDefinitions from './apiDefinitions';
const cache = Object.create(null);
const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova<AlovaGenerics>, configMap: any) => {
const apiPathKey = array.join('.') as keyof typeof apiDefinitions;
if (cache[apiPathKey]) {
return cache[apiPathKey];
}
// create a new proxy instance
const proxy = new Proxy(function () {}, {
get(_, property) {
// record the target property, so that it can get the completed accessing paths
const newArray = [...array, property];
// always return a new proxy to continue recording accessing paths.
return createFunctionalProxy(newArray, alovaInstance, configMap);
},
apply(_, __, [config]) {
const apiItem = apiDefinitions[apiPathKey];
if (!apiItem) {
throw new Error(`the api path of \`${apiPathKey}\` is not found`);
}
const mergedConfig = {
...configMap[apiPathKey],
...config
};
const [method, url] = apiItem;
const pathParams = mergedConfig.pathParams;
const urlReplaced = url!.replace(/\{([^}]+)\}/g, (_, key) => {
const pathParam = pathParams[key];
return pathParam;
});
delete mergedConfig.pathParams;
let data = mergedConfig.data;
if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') {
let hasBlobData = false;
const formData = new FormData();
for (const key in data) {
if (Array.isArray(data[key])) {
for (const ele of data[key]) {
formData.append(key, ele);
if (ele instanceof Blob) {
hasBlobData = true;
}
}
} else {
formData.append(key, data[key]);
if (data[key] instanceof Blob) {
hasBlobData = true;
}
}
}
data = hasBlobData ? formData : data;
}
return new Method(method!.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data);
}
});
cache[apiPathKey] = proxy;
return proxy;
};
export const createApis = (alovaInstance: Alova<AlovaGenerics>, configMap: any) => {
const Apis = new Proxy({} as Apis, {
get(_, property) {
return createFunctionalProxy([property], alovaInstance, configMap);
}
});
return Apis;
};
export const mountApis = (Apis: Apis) => {
// define global variable `Apis`
(globalThis as any).Apis = Apis;
};
type MethodConfig<T> = AlovaMethodCreateConfig<
(typeof import('./index'))['alovaInstance'] extends Alova<infer AG> ? AG : any,
any,
T
>;
type APISofParameters<Tag extends string, Url extends string> = Tag extends keyof Apis
? Url extends keyof Apis[Tag]
? Apis[Tag][Url] extends (...args: any) => any
? Parameters<Apis[Tag][Url]>
: any
: any
: any;
type MethodsConfigMap = {
[P in keyof typeof import('./apiDefinitions').default]?: MethodConfig<
P extends `${infer Tag}.${infer Url}` ? Parameters<NonNullable<APISofParameters<Tag, Url>[0]>['transform']>[0] : any
>;
};
export const withConfigType = <Config extends MethodsConfigMap>(config: Config) => config;
+1058
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
// Import the core alova instance
import alovaInstance from './core/instance'
// Export the global Apis object from the generated code
import { createApis, withConfigType } from './createApis'
// Export the alova instance for direct use if needed
export { alovaInstance }
// Configure method options for specific APIs
export const $$userConfigMap = withConfigType({})
// Create the global Apis object
const Apis = createApis(alovaInstance, $$userConfigMap)
// Export both default and named export for AutoImport
export default Apis
export { Apis }
+107
View File
@@ -0,0 +1,107 @@
# API Mock 数据
本目录包含了项目中使用的 API 模拟数据,用于开发和测试环境。
## 目录结构
```
mock/
├── modules/ # 按模块分类的模拟数据
│ ├── common.ts # 通用模拟处理
│ ├── loginInterface.ts # 登录相关接口的模拟数据
│ ├── mdataInterface.ts # 主数据相关接口的模拟数据
│ ├── vehsaleusesignInterface.ts # 车销使用签收相关接口的模拟数据
│ ├── vehsaleusesignarvInterface.ts # 车销使用签收到货相关接口的模拟数据
│ ├── user.ts # 用户相关的模拟数据
│ ├── university.ts # 大学相关的模拟数据
│ └── feedback.ts # 反馈相关的模拟数据
├── utils/ # 工具目录
│ ├── index.ts # 工具导出文件
│ └── generators.ts # 模拟数据生成工具
└── mockAdapter.ts # 模拟适配器配置
```
## 使用方法
模拟数据已经通过 `@alova/mock` 和 `@alova/adapter-uniapp` 集成到项目中。在开发环境中,API 请求会自动使用模拟数据进行响应。
### 启用/禁用模拟
在 `mockAdapter.ts` 中,可以通过修改 `enable` 选项来启用或禁用模拟:
```typescript
const mockAdapter = createAlovaMockAdapter(allMocks, {
// ...
enable: true, // 设置为 false 可禁用模拟
// ...
})
```
### 添加新的模拟数据
1. 在 `modules` 目录下创建新的模块文件或在现有文件中添加
2. 使用 `defineMock` 函数定义模拟数据
3. 在 `mockAdapter.ts` 中导入并添加到 `allMocks` 数组中
示例:
```typescript
// modules/example.ts
import { defineMock } from '@alova/mock'
// mockAdapter.ts
import exampleMocks from './modules/example'
export default defineMock({
'[GET]/api/example': () => {
return {
code: 200,
data: { /* 模拟数据 */ },
message: 'success'
}
}
})
const allMocks = [
// ...
exampleMocks
]
```
## 模拟数据生成工具
在 `utils/generators.ts` 中提供了一系列用于生成模拟数据的工具函数,可以在各个模块中复用:
```typescript
import { generateMockData } from '../utils'
// 生成随机ID
const id = generateMockData.id()
// 生成随机名称
const name = generateMockData.name('前缀')
// 生成随机数组
const array = generateMockData.array(index => ({
id: generateMockData.id(),
name: generateMockData.name(`项目${index}`)
}), 10)
// 生成基础响应对象
const response = generateMockData.baseResponse(data)
// 生成列表响应对象
const listResponse = generateMockData.listResponse(items, total, more)
// 生成业务对象
const user = generateMockData.user()
const goods = generateMockData.goods(0)
const vehSaleEmp = generateMockData.vehSaleEmp(0)
```
## 注意事项
1. 模拟数据应尽量接近真实数据结构,以便于开发和测试
2. 对于需要保持一致性的数据(如ID引用),可以使用固定值而非随机生成
3. 可以使用请求参数来定制模拟响应,例如分页、筛选等
4. 模拟数据应包含各种场景,包括成功和失败的情况
+436
View File
@@ -0,0 +1,436 @@
import Apis from '@/api'
/**
* Pet模块演示
* 演示宠物相关API的使用
*/
export class PetDemo {
// 获取所有可用的宠物
static async getAvailablePets() {
console.log('=== 获取可用宠物 ===')
try {
const pets = await Apis.pet.findPetsByStatus({
params: { status: 'available' },
}).send()
console.log('可用宠物列表:', pets)
return pets
}
catch (error) {
console.error('获取宠物失败:', error)
}
}
// 获取特定宠物信息
static async getPetById(petId: number) {
console.log(`=== 获取宠物 ${petId} 的信息 ===`)
try {
const pet = await Apis.pet.getPetById({
pathParams: { petId },
}).send()
console.log('宠物信息:', pet)
return pet
}
catch (error) {
console.error('获取宠物信息失败:', error)
}
}
// 添加新宠物
static async addNewPet() {
console.log('=== 添加新宠物 ===')
try {
const newPet = await Apis.pet.addPet({
data: {
name: 'Buddy',
category: { id: 1, name: 'Dogs' },
status: 'available',
photoUrls: ['https://example.com/buddy.jpg'],
tags: [
{ id: 1, name: 'friendly' },
{ id: 2, name: 'trained' },
],
},
}).send()
console.log('新添加的宠物:', newPet)
return newPet
}
catch (error) {
console.error('添加宠物失败:', error)
}
}
// 测试宠物不存在的情况
static async testPetNotFound() {
console.log('=== 测试宠物不存在的情况 ===')
try {
await Apis.pet.getPetById({
pathParams: { petId: 404 },
}).send()
}
catch (error) {
console.log('预期的404错误:', error)
}
}
// 删除宠物(需要API密钥)
static async deletePet(petId: number, apiKey: string = 'special-key') {
console.log(`=== 删除宠物 ${petId} ===`)
try {
const result = await Apis.pet.deletePet({
pathParams: { petId },
headers: { api_key: apiKey },
}).send()
console.log('删除结果:', result)
return result
}
catch (error) {
console.error('删除宠物失败:', error)
}
}
}
/**
* Store模块演示
* 演示商店相关API的使用
*/
export class StoreDemo {
// 获取库存信息
static async getInventory() {
console.log('=== 获取库存信息 ===')
try {
const inventory = await Apis.store.getInventory().send()
console.log('库存信息:', inventory)
return inventory
}
catch (error) {
console.error('获取库存失败:', error)
}
}
// 下单购买宠物
static async placeOrder(petId: number, quantity: number = 1) {
console.log('=== 下单购买宠物 ===')
try {
const order = await Apis.store.placeOrder({
data: {
petId,
quantity,
shipDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), // 7天后发货
status: 'placed',
complete: false,
},
}).send()
console.log('订单信息:', order)
return order
}
catch (error) {
console.error('下单失败:', error)
}
}
// 获取订单信息
static async getOrderById(orderId: number) {
console.log(`=== 获取订单 ${orderId} 信息 ===`)
try {
const order = await Apis.store.getOrderById({
pathParams: { orderId },
}).send()
console.log('订单详情:', order)
return order
}
catch (error) {
console.error('获取订单失败:', error)
}
}
// 测试无效订单ID
static async testInvalidOrderId() {
console.log('=== 测试无效订单ID ===')
try {
await Apis.store.getOrderById({
pathParams: { orderId: 999 },
}).send()
}
catch (error) {
console.log('预期的400错误:', error)
}
}
// 删除订单
static async deleteOrder(orderId: number) {
console.log(`=== 删除订单 ${orderId} ===`)
try {
const result = await Apis.store.deleteOrder({
pathParams: { orderId },
}).send()
console.log('删除结果:', result)
return result
}
catch (error) {
console.error('删除订单失败:', error)
}
}
}
/**
* User模块演示
* 演示用户相关API的使用
*/
export class UserDemo {
// 用户登录
static async login(username: string = 'admin', password: string = 'admin') {
console.log('=== 用户登录 ===')
try {
const loginResult = await Apis.user.loginUser({
params: { username, password },
}).send()
console.log('登录结果:', loginResult)
return loginResult
}
catch (error) {
console.error('登录失败:', error)
}
}
// 获取用户信息
static async getUserInfo(username: string) {
console.log(`=== 获取用户 ${username} 信息 ===`)
try {
const user = await Apis.user.getUserByName({
pathParams: { username },
}).send()
console.log('用户信息:', user)
return user
}
catch (error) {
console.error('获取用户信息失败:', error)
}
}
// 创建新用户
static async createUser(userData: any = {}) {
console.log('=== 创建新用户 ===')
try {
const newUser = await Apis.user.createUser({
data: {
username: 'newuser',
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
password: 'password123',
phone: '1234567890',
userStatus: 1,
...userData,
},
}).send()
console.log('新用户:', newUser)
return newUser
}
catch (error) {
console.error('创建用户失败:', error)
}
}
// 更新用户信息
static async updateUser(username: string, updateData: any) {
console.log(`=== 更新用户 ${username} 信息 ===`)
try {
const updatedUser = await Apis.user.updateUser({
pathParams: { username },
data: updateData,
}).send()
console.log('更新后的用户:', updatedUser)
return updatedUser
}
catch (error) {
console.error('更新用户失败:', error)
}
}
// 测试用户不存在的情况
static async testUserNotFound() {
console.log('=== 测试用户不存在的情况 ===')
try {
await Apis.user.getUserByName({
pathParams: { username: 'notfound' },
}).send()
}
catch (error) {
console.log('预期的404错误:', error)
}
}
// 批量创建用户
static async createUsersWithArray() {
console.log('=== 批量创建用户(数组) ===')
try {
const result = await Apis.user.createUsersWithListInput({
data: [
{
username: 'user1',
firstName: 'User',
lastName: 'One',
email: 'user1@example.com',
password: 'password',
phone: '1111111111',
userStatus: 1,
},
{
username: 'user2',
firstName: 'User',
lastName: 'Two',
email: 'user2@example.com',
password: 'password',
phone: '2222222222',
userStatus: 1,
},
],
}).send()
console.log('批量创建结果:', result)
return result
}
catch (error) {
console.error('批量创建用户失败:', error)
}
}
// 用户登出
static async logout() {
console.log('=== 用户登出 ===')
try {
const result = await Apis.user.logoutUser().send()
console.log('登出结果:', result)
return result
}
catch (error) {
console.error('登出失败:', error)
}
}
}
/**
* 综合演示
* 演示完整的业务流程
*/
export class FullDemo {
// 完整的宠物商店购买流程
static async completePetStorePurchaseFlow() {
console.log('\n🎯 开始完整的宠物商店购买流程演示\n')
// 1. 用户登录
const loginResult = await UserDemo.login('admin', 'admin')
if (!loginResult)
return
// 2. 查看库存
const inventory = await StoreDemo.getInventory()
console.log('\n📦 当前库存状态:', inventory)
// 3. 浏览可用宠物
const availablePets = await PetDemo.getAvailablePets()
if (!availablePets || availablePets.length === 0) {
console.log('❌ 没有可用的宠物')
return
}
// 4. 选择第一个宠物
const selectedPet = availablePets[0]
console.log('\n🐕 选择的宠物:', selectedPet)
// 5. 查看宠物详情
if (selectedPet?.id) {
await PetDemo.getPetById(selectedPet.id)
}
// 6. 下单购买
const order = selectedPet?.id ? await StoreDemo.placeOrder(selectedPet.id, 1) : null
if (!order)
return
// 7. 查看订单详情
if (order?.id) {
await StoreDemo.getOrderById(order.id)
}
// 8. 获取用户信息
await UserDemo.getUserInfo('admin')
console.log('\n✅ 完整流程演示结束')
}
// 错误处理演示
static async errorHandlingDemo() {
console.log('\n⚠️ 开始错误处理演示\n')
// 测试各种错误情况
await PetDemo.testPetNotFound()
await StoreDemo.testInvalidOrderId()
await UserDemo.testUserNotFound()
console.log('\n✅ 错误处理演示结束')
}
// CRUD操作演示
static async crudDemo() {
console.log('\n🔄 开始CRUD操作演示\n')
// 创建
const newPet = await PetDemo.addNewPet()
const newUser = await UserDemo.createUser({ username: 'testuser' })
// 读取
if (newPet?.id)
await PetDemo.getPetById(newPet.id)
if (newUser)
await UserDemo.getUserInfo('testuser')
// 更新
if (newUser) {
await UserDemo.updateUser('testuser', {
firstName: 'Updated',
lastName: 'User',
})
}
// 删除
if (newPet?.id)
await PetDemo.deletePet(newPet.id)
console.log('\n✅ CRUD操作演示结束')
}
}
// 导出演示运行器
export async function runMockDemo() {
console.log('🚀 开始Mock数据演示\n')
try {
// 运行完整流程演示
await FullDemo.completePetStorePurchaseFlow()
// 运行错误处理演示
await FullDemo.errorHandlingDemo()
// 运行CRUD演示
await FullDemo.crudDemo()
console.log('\n🎉 所有演示完成!')
}
catch (error) {
console.error('演示过程中发生错误:', error)
}
}
// 如果直接运行此文件,执行演示
if (typeof window !== 'undefined') {
// 在浏览器环境中,可以在控制台调用
(window as any).runMockDemo = runMockDemo;
(window as any).PetDemo = PetDemo;
(window as any).StoreDemo = StoreDemo;
(window as any).UserDemo = UserDemo
console.log('Mock演示函数已加载到全局对象,可在控制台调用:')
console.log('- runMockDemo() - 运行完整演示')
console.log('- PetDemo.* - 宠物模块演示')
console.log('- StoreDemo.* - 商店模块演示')
console.log('- UserDemo.* - 用户模块演示')
}
+52
View File
@@ -0,0 +1,52 @@
/*
* @Author: weisheng
* @Date: 2025-04-17 16:21:36
* @LastEditTime: 2025-06-15 22:48:04
* @LastEditors: weisheng
* @Description: Mock适配器配置 - 集成所有模块的mock数据
* @FilePath: /wot-starter/src/api/mock/mockAdapter.ts
* 记得注释
*/
import { uniappMockResponse, uniappRequestAdapter } from '@alova/adapter-uniapp'
import { createAlovaMockAdapter } from '@alova/mock'
// 导入所有mock模块
import commonMocks from './modules/common'
import petMocks from './modules/pet'
import storeMocks from './modules/store'
import userMocks from './modules/user'
const canUseGroupLogger =
typeof console !== 'undefined'
&& typeof console.groupCollapsed === 'function'
&& typeof console.groupEnd === 'function'
// 合并所有mock定义
const allMocks = [
commonMocks,
petMocks,
storeMocks,
userMocks,
]
// 创建mock适配器
const mockAdapter = createAlovaMockAdapter(allMocks, {
// 使用uniapp请求适配器处理非mock请求
httpAdapter: uniappRequestAdapter,
// 使用uniapp mock响应适配器
onMockResponse: uniappMockResponse,
// 根据环境变量启用/禁用mock
enable: true,
// 添加延迟以模拟网络延迟 (200-600ms)
delay: Math.random() * 400 + 200,
// 在开发环境下打印mock请求日志
mockRequestLogger: import.meta.env.MODE === 'development' && canUseGroupLogger,
// 路径匹配模式 - 使用完整路径匹配
matchMode: 'pathname',
})
export default mockAdapter
@@ -0,0 +1,30 @@
/*
* @Author: weisheng
* @Date: 2023-05-20 10:00:00
* @LastEditTime: 2025-06-26 21:59:35
* @LastEditors: weisheng
* @Description: 通用mock处理
* @FilePath: /wot-starter/src/api/mock/modules/common.ts
*/
import { defineMock } from '@alova/mock'
import { generateMockData } from '../utils/generators'
export default defineMock({
// 通用GET请求处理
'[GET]/*': (_params: any, matchedUrl: string) => {
console.log(`[Mock] GET ${matchedUrl}`, _params)
return generateMockData.baseResponse({
message: `Mock response for GET ${matchedUrl}`,
params: _params,
})
},
// 通用POST请求处理
'[POST]/*': (_params: any, matchedUrl: string) => {
console.log(`[Mock] POST ${matchedUrl}`, _params)
return generateMockData.baseResponse({
message: `Mock response for POST ${matchedUrl}`,
params: _params,
})
},
})
+239
View File
@@ -0,0 +1,239 @@
/*
* @Author: weisheng
* @Date: 2025-06-15 14:25:00
* @LastEditTime: 2025-06-26 21:59:38
* @LastEditors: weisheng
* @Description: Pet Store - Pet相关接口的mock数据
* @FilePath: /wot-starter/src/api/mock/modules/pet.ts
*/
import { defineMock } from '@alova/mock'
import { generateMockData } from '../utils/generators'
// 宠物状态枚举
const PET_STATUS = ['available', 'pending', 'sold'] as const
type PetStatus = typeof PET_STATUS[number]
// 宠物类别
const PET_CATEGORIES = [
{ id: 1, name: 'Dogs' },
{ id: 2, name: 'Cats' },
{ id: 3, name: 'Birds' },
{ id: 4, name: 'Fish' },
{ id: 5, name: 'Reptiles' },
]
// 宠物标签
const PET_TAGS = [
{ id: 1, name: 'friendly' },
{ id: 2, name: 'playful' },
{ id: 3, name: 'calm' },
{ id: 4, name: 'energetic' },
{ id: 5, name: 'trained' },
{ id: 6, name: 'house-trained' },
]
// 生成宠物对象
function generatePet(id?: number, status?: PetStatus) {
const petId = id || generateMockData.number(1, 10000)
const category = PET_CATEGORIES[generateMockData.number(0, PET_CATEGORIES.length - 1)]
const tags = generateMockData.array(() => PET_TAGS[generateMockData.number(0, PET_TAGS.length - 1)], generateMockData.number(1, 3))
return {
id: petId,
category,
name: generateMockData.name('Pet'),
photoUrls: generateMockData.array(
index => `https://example.com/pet/${petId}/photo${index + 1}.jpg`,
generateMockData.number(1, 3),
),
tags,
status: status || PET_STATUS[generateMockData.number(0, PET_STATUS.length - 1)],
}
}
export default defineMock({
// 上传宠物图片
'[POST]/pet/{petId}/uploadImage': ({ params, data }) => {
console.log(`[Mock] POST /pet/${params.petId}/uploadImage`, data)
return {
code: 200,
type: 'success',
message: `Image uploaded successfully for pet ${params.petId}`,
data: {
petId: params.petId,
imageUrl: `https://example.com/pet/${params.petId}/uploaded-${Date.now()}.jpg`,
},
}
},
// 添加新宠物
'[POST]/pet': ({ data }) => {
console.log('[Mock] POST /pet', data)
const newPet = {
...data,
id: generateMockData.number(10001, 20000),
}
return newPet
},
// 更新宠物信息
'[PUT]/pet': ({ data }) => {
console.log('[Mock] PUT /pet', data)
if (!data.id) {
return {
status: 400,
body: {
code: 400,
message: 'Pet ID is required',
},
}
}
return {
...data,
updatedAt: generateMockData.datetime(),
}
},
// 根据状态查找宠物
'[GET]/pet/findByStatus': ({ query }) => {
console.log('[Mock] GET /pet/findByStatus', query)
const status = query.status as PetStatus
const validStatuses = Array.isArray(status) ? status : [status]
// 验证状态
const invalidStatuses = validStatuses.filter(s => !PET_STATUS.includes(s as PetStatus))
if (invalidStatuses.length > 0) {
return {
status: 400,
body: {
code: 400,
message: `Invalid status value: ${invalidStatuses.join(', ')}`,
},
}
}
// 生成符合状态的宠物列表
const pets = generateMockData.array(
index => generatePet(undefined, validStatuses[index % validStatuses.length] as PetStatus),
generateMockData.number(5, 15),
)
return pets
},
// 根据ID获取宠物
'[GET]/pet/{petId}': ({ params }) => {
console.log(`[Mock] GET /pet/${params.petId}`)
const petId = Number.parseInt(params.petId)
if (Number.isNaN(petId)) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid pet ID',
},
}
}
// 模拟宠物不存在的情况
if (petId === 404) {
return {
status: 404,
body: {
code: 404,
message: 'Pet not found',
},
}
}
return generatePet(petId)
},
// 使用表单数据更新宠物
'[POST]/pet/{petId}': ({ params, data }) => {
console.log(`[Mock] POST /pet/${params.petId}`, data)
const petId = Number.parseInt(params.petId)
if (Number.isNaN(petId)) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid pet ID',
},
}
}
// 模拟宠物不存在的情况
if (petId === 404) {
return {
status: 404,
body: {
code: 404,
message: 'Pet not found',
},
}
}
const updatedPet = {
...generatePet(petId),
...data,
updatedAt: generateMockData.datetime(),
}
return updatedPet
},
// 删除宠物
'[DELETE]/pet/{petId}': ({ params, headers }) => {
console.log(`[Mock] DELETE /pet/${params.petId}`, headers)
const petId = Number.parseInt(params.petId)
if (Number.isNaN(petId)) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid pet ID',
},
}
}
// 检查API密钥
if (!headers.api_key) {
return {
status: 401,
body: {
code: 401,
message: 'API key is required',
},
}
}
// 模拟宠物不存在的情况
if (petId === 404) {
return {
status: 404,
body: {
code: 404,
message: 'Pet not found',
},
}
}
return {
code: 200,
message: `Pet ${petId} deleted successfully`,
}
},
}, true)
+173
View File
@@ -0,0 +1,173 @@
/*
* @Author: weisheng
* @Date: 2025-06-15 14:30:00
* @LastEditTime: 2025-06-15 14:30:00
* @LastEditors: weisheng
* @Description: Pet Store - Store相关接口的mock数据
* @FilePath: /wot-starter/src/api/mock/modules/store.ts
*/
import { defineMock } from '@alova/mock'
import { generateMockData } from '../utils/generators'
// 订单状态枚举
const ORDER_STATUS = ['placed', 'approved', 'delivered'] as const
type OrderStatus = typeof ORDER_STATUS[number]
// 生成订单对象
function generateOrder(id?: number, status?: OrderStatus) {
const orderId = id || generateMockData.number(1, 10000)
return {
id: orderId,
petId: generateMockData.number(1, 1000),
quantity: generateMockData.number(1, 10),
shipDate: generateMockData.datetime(generateMockData.number(1, 30)), // 1-30天后发货
status: status || ORDER_STATUS[generateMockData.number(0, ORDER_STATUS.length - 1)],
complete: generateMockData.boolean(),
}
}
export default defineMock({
// 获取库存
'[GET]/store/inventory': () => {
console.log('[Mock] GET /store/inventory')
// 生成随机库存数据
const inventory: Record<string, number> = {}
// 为不同状态生成库存数量
ORDER_STATUS.forEach((status) => {
inventory[status] = generateMockData.number(0, 100)
})
// 添加一些额外的状态
inventory.pending = generateMockData.number(0, 50)
inventory.sold = generateMockData.number(0, 200)
inventory.available = generateMockData.number(10, 300)
return inventory
},
// 下单购买宠物
'[POST]/store/order': ({ data }) => {
console.log('[Mock] POST /store/order', data)
// 验证必填字段
if (!data.petId) {
return {
status: 400,
body: {
code: 400,
message: 'Pet ID is required',
},
}
}
if (!data.quantity || data.quantity <= 0) {
return {
status: 400,
body: {
code: 400,
message: 'Quantity must be greater than 0',
},
}
}
// 创建新订单
const newOrder = {
id: generateMockData.number(10001, 20000),
petId: data.petId,
quantity: data.quantity,
shipDate: data.shipDate || generateMockData.datetime(generateMockData.number(1, 7)), // 默认7天内发货
status: 'placed' as OrderStatus,
complete: false,
}
return newOrder
},
// 根据ID获取订单
'[GET]/store/order/{orderId}': ({ params }) => {
console.log(`[Mock] GET /store/order/${params.orderId}`)
const orderId = Number.parseInt(params.orderId)
if (Number.isNaN(orderId)) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid order ID',
},
}
}
// 模拟订单不存在的情况
if (orderId === 404) {
return {
status: 404,
body: {
code: 404,
message: 'Order not found',
},
}
}
// 模拟无效订单ID的情况(订单ID必须在1-10之间)
if (orderId < 1 || orderId > 10) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid ID supplied',
},
}
}
return generateOrder(orderId)
},
// 删除订单
'[DELETE]/store/order/{orderId}': ({ params }) => {
console.log(`[Mock] DELETE /store/order/${params.orderId}`)
const orderId = Number.parseInt(params.orderId)
if (Number.isNaN(orderId)) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid order ID',
},
}
}
// 模拟订单不存在的情况
if (orderId === 404) {
return {
status: 404,
body: {
code: 404,
message: 'Order not found',
},
}
}
// 模拟无效订单ID的情况
if (orderId < 1) {
return {
status: 400,
body: {
code: 400,
message: 'Invalid ID supplied',
},
}
}
return {
code: 200,
message: `Order ${orderId} deleted successfully`,
}
},
}, true)
+304
View File
@@ -0,0 +1,304 @@
/*
* @Author: weisheng
* @Date: 2025-06-15 14:35:00
* @LastEditTime: 2025-06-27 09:43:25
* @LastEditors: weisheng
* @Description: Pet Store - User相关接口的mock数据
* @FilePath: /wot-starter/src/api/mock/modules/user.ts
*/
import { defineMock } from '@alova/mock'
import { generateMockData } from '../utils/generators'
// 用户状态枚举
const USER_STATUS = [0, 1, 2] // 0: 离线, 1: 在线, 2: 忙碌
type UserStatus = typeof USER_STATUS[number]
// 生成用户对象
function generateUser(username?: string, status?: UserStatus) {
const baseUsername = username || generateMockData.name('user').toLowerCase()
return {
id: generateMockData.number(1, 10000),
username: baseUsername,
firstName: generateMockData.name('First'),
lastName: generateMockData.name('Last'),
email: `${baseUsername}@example.com`,
password: 'password123', // 在实际应用中不应该返回密码
phone: `1${generateMockData.number(1000000000, 9999999999)}`,
userStatus: CommonUtil.isDef(status) ? status : USER_STATUS[generateMockData.number(0, USER_STATUS.length - 1)],
}
}
// 模拟用户数据库
const mockUsers = generateMockData.array(index => generateUser(`user${index + 1}`), 10)
export default defineMock({
// 批量创建用户(数组输入)
'[POST]/user/createWithArray': ({ data }) => {
console.log('[Mock] POST /user/createWithArray', data)
if (!Array.isArray(data)) {
return {
status: 400,
body: {
code: 400,
message: 'Input should be an array of users',
},
}
}
// 验证每个用户对象
for (const user of data) {
if (!user.username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required for all users',
},
}
}
}
return {
code: 200,
message: `Successfully created ${data.length} users`,
}
},
// 批量创建用户(列表输入)
'[POST]/user/createWithList': ({ data }) => {
console.log('[Mock] POST /user/createWithList', data)
if (!Array.isArray(data)) {
return {
status: 400,
body: {
code: 400,
message: 'Input should be a list of users',
},
}
}
// 验证每个用户对象
for (const user of data) {
if (!user.username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required for all users',
},
}
}
}
return {
code: 200,
message: `Successfully created ${data.length} users from list`,
}
},
// 用户登录
'[GET]/user/login': ({ query }) => {
console.log('[Mock] GET /user/login', query)
const { username, password } = query
if (!username || !password) {
return {
status: 400,
body: {
code: 400,
message: 'Username and password are required',
},
}
}
// 模拟登录验证
if (username === 'admin' && password === 'admin') {
return {
code: 200,
message: 'logged in user session',
token: `mock_token_${Date.now()}`,
expiresIn: 3600, // 1小时
user: generateUser('admin', 1),
}
}
// 模拟用户名密码错误
if (username === 'invalid' || password === 'invalid') {
return {
status: 400,
body: {
code: 400,
message: 'Invalid username/password supplied',
},
}
}
// 默认成功登录
return {
code: 200,
message: 'logged in user session',
token: `mock_token_${Date.now()}`,
expiresIn: 3600,
user: generateUser(username as string, 1),
}
},
// 用户登出
'[GET]/user/logout': () => {
console.log('[Mock] GET /user/logout')
return {
code: 200,
message: 'ok',
}
},
// 根据用户名获取用户
'[GET]/user/{username}': ({ params }) => {
console.log(`[Mock] GET /user/${params.username}`)
const username = params.username
if (!username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required',
},
}
}
// 模拟用户不存在的情况
if (username === 'notfound') {
return {
status: 404,
body: {
code: 404,
message: 'User not found',
},
}
}
// 从模拟数据库中查找用户
const existingUser = mockUsers.find(user => user.username === username)
if (existingUser) {
return existingUser
}
// 生成新用户
return generateUser(username)
},
// 更新用户信息
'[PUT]/user/{username}': ({ params, data }) => {
console.log(`[Mock] PUT /user/${params.username}`, data)
const username = params.username
if (!username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required',
},
}
}
// 模拟用户不存在的情况
if (username === 'notfound') {
return {
status: 404,
body: {
code: 404,
message: 'User not found',
},
}
}
// 更新用户信息
const updatedUser = {
...generateUser(username),
...data,
username, // 确保用户名不被修改
updatedAt: generateMockData.datetime(),
}
return updatedUser
},
// 删除用户
'[DELETE]/user/{username}': ({ params }) => {
console.log(`[Mock] DELETE /user/${params.username}`)
const username = params.username
if (!username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required',
},
}
}
// 模拟用户不存在的情况
if (username === 'notfound') {
return {
status: 404,
body: {
code: 404,
message: 'User not found',
},
}
}
return {
code: 200,
message: `User ${username} deleted successfully`,
}
},
// 创建用户
'[POST]/user': ({ data }) => {
console.log('[Mock] POST /user', data)
if (!data.username) {
return {
status: 400,
body: {
code: 400,
message: 'Username is required',
},
}
}
// 检查用户名是否已存在
const existingUser = mockUsers.find(user => user.username === data.username)
if (existingUser) {
return {
status: 409,
body: {
code: 409,
message: 'Username already exists',
},
}
}
// 创建新用户
const newUser = {
...generateUser(),
...data,
id: generateMockData.number(20001, 30000),
createdAt: generateMockData.datetime(),
}
return newUser
},
}, true)
@@ -0,0 +1,142 @@
/*
* @Author: weisheng
* @Date: 2023-05-20 10:00:00
* @LastEditTime: 2025-05-21 15:46:14
* @LastEditors: weisheng
* @Description: Mock数据生成工具
* @FilePath: /lsym-cx-mini/src/api/mock/utils/generators.ts
*/
// 模拟数据生成工具函数
export const generateMockData = {
// 生成随机ID
id: (): number => Math.floor(Math.random() * 10000),
// 生成随机名称
name: (prefix = '名称'): string => `${prefix}_${Math.floor(Math.random() * 1000)}`,
// 生成随机代码
code: (prefix = 'CODE'): string => `${prefix}_${Math.floor(Math.random() * 1000)}`,
// 生成随机日期
// 可以传入天数偏移,负数表示过去的日期,正数表示未来的日期
date: (dayOffset = 0): string => {
const date = new Date()
if (dayOffset !== 0) {
date.setDate(date.getDate() + dayOffset)
}
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
},
// 生成随机时间
// 可以传入天数偏移,负数表示过去的日期,正数表示未来的日期
datetime: (dayOffset = 0): string => {
const date = new Date()
if (dayOffset !== 0) {
date.setDate(date.getDate() + dayOffset)
}
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`
},
// 生成随机布尔值
boolean: (): boolean => Math.random() > 0.5,
// 生成随机数字
number: (min = 0, max = 100): number => Math.floor(Math.random() * (max - min)) + min,
// 生成随机数组
array: <T>(generator: (index: number) => T, length = 10): T[] => {
const result: T[] = []
for (let i = 0; i < length; i++) {
result.push(generator(i))
}
return result
},
// 生成基础响应对象
baseResponse: <T>(data: T = null as unknown as T, code = 2000, msg = '操作成功') => ({
code,
data,
msg,
}),
// 生成列表响应对象
listResponse: <T>(data: T[] = [], total = data.length, more = false, code = 2000, msg = '操作成功') => ({
code,
data,
total,
more,
msg,
}),
// 生成GCN对象
gcn: (_index?: number) => ({
gid: generateMockData.id(),
code: generateMockData.code('ORG'),
name: generateMockData.name('组织'),
}),
// 生成员工对象
faEmp: (index: number) => ({
gid: generateMockData.id(),
code: generateMockData.code('EMP'),
name: generateMockData.name('员工'),
org: generateMockData.gcn(index),
}),
// 生成车销业务员对象
vehSaleEmp: (index: number) => ({
gid: generateMockData.id(),
code: generateMockData.code('VSE'),
name: generateMockData.name('车销业务员'),
faEmp: generateMockData.faEmp(index),
org: generateMockData.gcn(index),
wms: generateMockData.gcn(index),
}),
// 生成权限对象
permission: (index: number) => ({
module: `module_${index}`,
moduleName: `模块${index}`,
roleId: `role_${index}`,
state: 1,
}),
// 生成代码名称对象
codeName: (index: number, prefix = '线路') => ({
code: generateMockData.code(`LINE_${index}`),
name: `${prefix}${index}`,
}),
// 生成用户对象
user: (roleCode = '01') => ({
permissions: generateMockData.array(generateMockData.permission, 5),
sortLines: generateMockData.array(generateMockData.codeName, 3),
token: `mock_token_${Date.now()}`,
roleCode, // 添加roleCode字段:01-车销业务员,02-仓管
vehSaleEmp: generateMockData.vehSaleEmp(0),
}),
// 生成商品对象
goods: (index: number) => ({
gid: generateMockData.id(),
code: generateMockData.code('GOODS'),
name: generateMockData.name('商品'),
gdCode: generateMockData.code('GDCODE'),
spec: `规格${index}`,
munit: '个',
price: generateMockData.number(1, 1000) / 100,
qpc: generateMockData.number(1, 10),
qpcStr: `${generateMockData.number(1, 10)}个/箱`,
qty: generateMockData.number(1, 100),
qtyStr: `${generateMockData.number(1, 100)}个`,
busInvQty: generateMockData.number(1, 100),
advUseSignQty: generateMockData.number(1, 100),
version: 1,
}),
// 单据状态,可选值为:0 | 100 | 1300 | 300 | 110 | 1310
stat: (): number => {
const stats = [100, 1300, 300, 110, 1310]
return stats[generateMockData.number(0, stats.length - 1)]
},
}
+85
View File
@@ -0,0 +1,85 @@
/**
* AI 聊天 API 模块(对应后端 module_ai 插件)
*/
import { http } from '@/http'
const AI_BASE = '/ai/chat'
export const ChatAPI = {
/** 获取会话列表 */
getSessions(params?: Record<string, any>): Promise<PageResult<ChatSession>> {
return http.Get(`${AI_BASE}/list`, params)
},
/** 创建会话 */
createSession(title?: string): Promise<ChatSession> {
return http.Post(`${AI_BASE}/create`, { title: title || '新对话' })
},
/** 获取会话详情(含消息列表) */
getDetail(sessionId: number): Promise<{ messages: ChatMessage[] }> {
return http.Get(`${AI_BASE}/detail/${sessionId}`)
},
/** 更新会话标题 */
updateSession(sessionId: number, data: Record<string, any>): Promise<void> {
return http.Put(`${AI_BASE}/update/${sessionId}`, data)
},
/** 删除会话 */
removeSession(ids: number[]): Promise<void> {
return http.Delete(`${AI_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 发送消息 (非流式) */
sendMessage(sessionId: number, content: string): Promise<ChatMessage> {
return http.Post(`${AI_BASE}/ai-chat`, { session_id: sessionId, content })
},
/** 获取 AI 模型配置列表 */
getModels(): Promise<AIModelConfig[]> {
return http.Get(`${AI_BASE}/model`)
},
/** 新增 AI 模型配置 */
createModel(data: AIModelForm): Promise<AIModelConfig> {
return http.Post(`${AI_BASE}/model`, data)
},
/** 更新 AI 模型配置 */
updateModel(configId: number, data: AIModelForm): Promise<AIModelConfig> {
return http.Put(`${AI_BASE}/model/${configId}`, data)
},
/** 删除 AI 模型配置 */
deleteModel(configId: number): Promise<void> {
return http.Delete(`${AI_BASE}/model/${configId}`)
},
/** 切换激活的 AI 模型配置 */
activateModel(configId: number): Promise<void> {
return http.Post(`${AI_BASE}/model/${configId}/activate`)
},
}
/* ==================== 类型定义 ==================== */
export interface ChatSession {
id: number
session_name?: string
title?: string
created_at?: number
}
export interface ChatMessage {
id?: string
role: string
content: string
created_at?: number
time?: string
}
export interface AIModelForm {
name: string
base_url: string
api_key: string
model_id: string
temperature?: number
}
export interface AIModelConfig extends AIModelForm {
config_id: number
is_active?: boolean
created_time?: string
updated_time?: string
}
@@ -0,0 +1,86 @@
/**
* 示例 API 模块(对应后端 module_example 插件)
*/
import { http } from '@/http'
const DEMO_BASE = '/example/demo'
export const DemoAPI = {
/** 示例分页列表 */
getPage(query?: DemoPageQuery): Promise<PageResult<DemoTable>> {
return http.Get(`${DEMO_BASE}/list`, query)
},
/** 示例详情 */
getDetail(id: number): Promise<DemoTable> {
return http.Get(`${DEMO_BASE}/detail/${id}`)
},
/** 创建示例 */
create(data: DemoForm): Promise<void> {
return http.Post(`${DEMO_BASE}/create`, data)
},
/** 更新示例 */
update(id: number, data: DemoForm): Promise<void> {
return http.Put(`${DEMO_BASE}/update/${id}`, data)
},
/** 删除示例 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${DEMO_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 批量设置示例状态 */
batchStatus(data: BatchType): Promise<void> {
return http.Patch(`${DEMO_BASE}/status/batch`, data)
},
/** 导出示例 */
exportDemo(query?: DemoPageQuery): Promise<unknown> {
return http.Post(`${DEMO_BASE}/export`, query)
},
/** 下载导入模板 */
downloadTemplate(): Promise<unknown> {
return http.Post(`${DEMO_BASE}/download/template`)
},
/** 导入示例数据 */
importDemo(body: Record<string, any>): Promise<void> {
return http.Post(`${DEMO_BASE}/import`, body, {
headers: { 'Content-Type': 'multipart/form-data' },
})
},
}
/* ==================== 类型定义 ==================== */
export interface DemoPageQuery extends PageQuery {
name?: string
status?: number
}
export interface DemoTable {
id?: number
name?: string
status?: number
description?: string
int_val?: number
bigint_val?: number
float_val?: number
bool_val?: boolean
date_val?: string
time_val?: string
datetime_val?: string
text_val?: string
json_val?: Record<string, any>
}
export interface DemoForm {
id?: number
name?: string
status?: number
description?: string
int_val?: number
bigint_val?: number
float_val?: number
bool_val?: boolean
date_val?: string
time_val?: Date | string
datetime_val?: Date | string
text_val?: string
json_val?: Record<string, any>
}
@@ -0,0 +1,71 @@
/**
* 代码生成 API 模块(对应后端 module_generator 插件)
*/
import { http } from '@/http'
const GEN_BASE = '/generator/gencode'
export const GencodeAPI = {
/** 查询业务表列表 */
getPage(params?: Record<string, any>): Promise<PageResult<GenTableItem>> {
return http.Get(`${GEN_BASE}/list`, params)
},
/** 查询数据库表列表 */
getDbTables(params?: Record<string, any>): Promise<PageResult<DbTableItem>> {
return http.Get(`${GEN_BASE}/db/list`, params)
},
/** 导入表结构 */
importTable(tableName: string): Promise<void> {
return http.Post(`${GEN_BASE}/import`, { table_name: tableName })
},
/** 获取业务表详情 */
getDetail(id: number): Promise<GenTableItem> {
return http.Get(`${GEN_BASE}/detail/${id}`)
},
/** 编辑业务表 */
update(id: number, data: Partial<GenTableItem>): Promise<GenTableItem> {
return http.Put(`${GEN_BASE}/update/${id}`, data)
},
/** 删除业务表 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${GEN_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 批量生成代码 (返回 zip) */
batchGenerate(ids: number[]): Promise<unknown> {
return http.Patch(`${GEN_BASE}/batch/output`, { ids })
},
/** 预览代码 */
preview(id: number): Promise<string | Record<string, any>> {
return http.Get(`${GEN_BASE}/preview/${id}`)
},
/** 同步数据库 */
syncDb(tableName: string): Promise<void> {
return http.Post(`${GEN_BASE}/sync_db/${tableName}`)
},
}
/* ==================== 类型定义 ==================== */
export interface GenTableItem {
id: number
table_name: string
table_comment?: string
class_name?: string
package_name?: string
module_name?: string
business_name?: string
function_name?: string
sub_table_name?: string
sub_table_fk_name?: string
parent_menu_id?: number
description?: string
created_time?: string
updated_time?: string
}
export interface DbTableItem {
table_name?: string
name?: string
table_comment?: string
comment?: string
}
@@ -0,0 +1,59 @@
import { http } from '@/http'
const MONITOR_BASE = '/monitor'
/**
* 缓存监控 API
* 与 web 端 module_monitor/cache.ts 对齐
*/
export const CacheAPI = {
getInfo(): Promise<CacheInfo> {
return http.Get(`${MONITOR_BASE}/cache/info`)
},
getNames(): Promise<string[]> {
return http.Get(`${MONITOR_BASE}/cache/get/names`)
},
getKeys(cacheName: string): Promise<string[]> {
return http.Get(`${MONITOR_BASE}/cache/get/keys/${cacheName}`)
},
getValue(cacheName: string, cacheKey: string): Promise<unknown> {
return http.Get(`${MONITOR_BASE}/cache/get/value/${cacheName}/${cacheKey}`)
},
deleteName(cacheName: string): Promise<void> {
return http.Delete(`${MONITOR_BASE}/cache/delete/name/${cacheName}`)
},
deleteKey(cacheKey: string): Promise<void> {
return http.Delete(`${MONITOR_BASE}/cache/delete/key/${cacheKey}`)
},
clear(): Promise<void> {
return http.Delete(`${MONITOR_BASE}/cache/clear`)
},
}
export interface CacheInfo {
db_size?: number
command_stats?: Record<string, any>[]
info?: Record<string, any>
// computed from info dict
keys_count?: number
hit_rate?: string
used_memory?: string
}
export interface CommandStats {
name: string
value: string
}
export interface RedisInfo {
redis_version: string
redis_mode: string
tcp_port: number
connected_clients: number
uptime_in_days: number
used_memory_human: string
maxmemory_human: string
aof_enabled: string
instantaneous_input_kbps: number
instantaneous_output_kbps: number
}
@@ -0,0 +1,30 @@
import { http } from '@/http'
const MONITOR_BASE = '/monitor'
/**
* 运营大盘 API
* 与 web 端 module_monitor/dashboard.ts 对齐
*/
export const DashboardAPI = {
getStats(): Promise<DashboardStats> {
return http.Get(`${MONITOR_BASE}/online/stats`)
},
}
export interface RecentLoginItem {
username: string
status: number
login_time: string
login_ip?: string
login_location?: string
}
export interface DashboardStats {
online_users: number
total_users: number
today_login_count: number
today_unique_users: number
week_user_created: number
recent_logins: RecentLoginItem[]
}
@@ -0,0 +1,57 @@
import { http } from '@/http'
const MONITOR_BASE = '/monitor'
/**
* 在线用户 API
* 与 web 端 module_monitor/online.ts 对齐(补全完整字段)
*/
export const OnlineAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<OnlineUserItem>> {
return http.Get(`${MONITOR_BASE}/online/list`, params)
},
getCurrent(): Promise<OnlineUserItem[]> {
return http.Get(`${MONITOR_BASE}/online/current`)
},
forceLogout(token: string): Promise<void> {
return http.Delete(`${MONITOR_BASE}/online/delete`, { token })
},
clear(): Promise<void> {
return http.Delete(`${MONITOR_BASE}/online/clear`)
},
getStats(): Promise<DashboardStats> {
return http.Get(`${MONITOR_BASE}/online/stats`)
},
}
export interface OnlineUserItem {
session_id?: string
user_id?: number
is_superuser?: boolean
user_name?: string
name?: string
ipaddr?: string
login_location?: string
login_time?: string
login_type?: string
os?: string
browser?: string
user_status?: number
}
export interface DashboardStats {
online_users: number
total_users: number
today_login_count: number
today_unique_users: number
week_user_created: number
recent_logins: RecentLoginItem[]
}
export interface RecentLoginItem {
username: string
status: number
login_time: string
login_ip?: string
login_location?: string
}
@@ -0,0 +1,57 @@
import { http } from '@/http'
const MONITOR_BASE = '/monitor'
/**
* 资源管理 API
* 与 web 端 module_monitor/resource.ts 对齐(补全完整字段)
*/
export const ResourceAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<ResourceItem>> {
return http.Get(`${MONITOR_BASE}/resource/list`, params)
},
getDetail(id: number): Promise<ResourceItem> {
return http.Get(`${MONITOR_BASE}/resource/detail/${id}`)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${MONITOR_BASE}/resource/delete`, { ids: JSON.stringify(ids) })
},
upload(path: string, filePath: string, fileName: string): Promise<ResourceUploadSchema> {
return http.Post(`${MONITOR_BASE}/resource/upload`, { path, file_path: filePath, file_name: fileName })
},
download(id: number): Promise<{ url: string }> {
return http.Get(`${MONITOR_BASE}/resource/download`, { params: { id } })
},
mkdir(path: string, name: string): Promise<void> {
return http.Post(`${MONITOR_BASE}/resource/mkdir`, { path, name })
},
rename(id: number, newName: string): Promise<void> {
return http.Post(`${MONITOR_BASE}/resource/rename`, { id, new_name: newName })
},
move(id: number, targetPath: string): Promise<void> {
return http.Post(`${MONITOR_BASE}/resource/move`, { id, target_path: targetPath })
},
copy(id: number, targetPath: string): Promise<void> {
return http.Post(`${MONITOR_BASE}/resource/copy`, { id, target_path: targetPath })
},
}
export interface ResourceItem {
id: number
name: string
file_url: string
relative_path: string
is_file: boolean
is_dir: boolean
size?: number | null
created_time?: string
modified_time?: string
is_hidden?: boolean
}
export interface ResourceUploadSchema {
file_path?: string
file_name?: string
origin_name?: string
file_url?: string
}
@@ -0,0 +1,57 @@
import { http } from '@/http'
const MONITOR_BASE = '/monitor'
/**
* 服务器监控 API
* 与 web 端 module_monitor/server.ts 对齐(补全完整字段)
*/
export const ServerAPI = {
getInfo(): Promise<ServerInfo> {
return http.Get(`${MONITOR_BASE}/server/info`)
},
}
export interface CpuInfo {
used_percent: number
cores: number
model: string
cpu_num?: number
used?: number
sys?: number
free?: number
}
export interface MemoryInfo {
total: string
used: string
used_percent: number
free?: string
usage?: number
}
export interface DiskInfo {
total: string
used: string
used_percent: number
}
export interface OsInfo {
name: string
hostname: string
uptime: string
}
export interface JvmInfo {
version: string
used: string
used_percent: number
}
export interface ServerInfo {
cpu?: CpuInfo
memory?: MemoryInfo
disk?: DiskInfo
os?: OsInfo
jvm?: JvmInfo
}
+112
View File
@@ -0,0 +1,112 @@
import { http } from '@/http'
import { ContentTypeEnum } from '@/http/tools/enum'
const AUTH_BASE_URL = '/system/auth'
/** 方案提供方 */
export type OAuthProvider = 'wechat' | 'qq' | 'github' | 'gitee'
/**
* 认证 API
* 与 web 端 module_system/auth.ts 对齐(完整字段定义)
*/
const AuthAPI = {
/**
* 登录
* @param body 登录表单数据
* @returns 登录结果
*/
login(body: LoginFormData): Promise<LoginResult> {
return http.Post(`${AUTH_BASE_URL}/login`, body, {
headers: {
'Content-Type': ContentTypeEnum.FORM_URLENCODED,
},
meta: { ignoreAuth: true },
})
},
/**
* 刷新令牌
* @param body 刷新令牌请求体
* @returns 新的访问令牌
*/
refreshToken(body: RefreshToekenBody): Promise<LoginResult> {
return http.Post(`${AUTH_BASE_URL}/token/refresh`, body, { meta: { ignoreAuth: true } })
},
/**
* 获取验证码
* @returns 验证码信息
*/
getCaptcha(): Promise<CaptchaInfo> {
// 添加随机参数防止缓存
const timestamp = new Date().getTime()
return http.Get(`${AUTH_BASE_URL}/captcha/get?timestamp=${timestamp}`, { meta: { ignoreAuth: true } })
},
/**
* 登出
* @param body 登出请求体
*/
logout(body: LogoutBody): Promise<void> {
return http.Post(`${AUTH_BASE_URL}/logout`, body)
},
/**
* 获取第三方 OAuth 登录跳转 URL
* @param provider oauth 提供商: wechat / qq / github / gitee
* @returns 跳转 URL
*/
getOAuthLoginUrl(provider: OAuthProvider): Promise<{ url: string }> {
return http.Get(`${AUTH_BASE_URL}/oauth/${provider}/login`, { meta: { ignoreAuth: true } })
},
/**
* 滑块验证码完成
* 后端仅标记 captcha_key 状态为 verified,不校验 x 坐标值(x 为占位字段)
* @param data 验证数据
* @param data.captcha_key 验证码 key
* @param data.x 滑块 x 坐标(占位,后端未使用)
* @returns 验证结果 { captcha_key, verified }
*/
completeSliderCaptcha(data: { captcha_key: string, x: number }): Promise<{ captcha_key: string, verified: boolean }> {
return http.Post(`${AUTH_BASE_URL}/captcha/slider/complete`, data, { meta: { ignoreAuth: true } })
},
}
export default AuthAPI
/** 登录表单数据 */
export interface LoginFormData {
username: string
password: string
captcha_key?: string
captcha?: string
remember?: boolean
login_type?: string
}
/** 刷新令牌请求体 */
export interface RefreshToekenBody {
refresh_token: string
}
/** JWT 响应 */
export interface LoginResult {
access_token: string
refresh_token: string
token_type: string
expires_in: number
}
/** 验证码信息(滑块模式:img_base 为空字符串) */
export interface CaptchaInfo {
enable: boolean
key: string
img_base: string
}
/** 退出登录操作 */
export interface LogoutBody {
token: string
}
@@ -0,0 +1,52 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 部门管理 API
* 与 web 端 module_system/dept.ts 对齐(完整字段定义)
*/
export const DeptAPI = {
getTree(search?: DeptQuery): Promise<DeptItem[]> {
return http.Get(`${SYSTEM_BASE}/dept/tree`, search)
},
getDetail(id: number): Promise<DeptItem> {
return http.Get(`${SYSTEM_BASE}/dept/detail/${id}`)
},
create(data: DeptForm): Promise<DeptItem> {
return http.Post(`${SYSTEM_BASE}/dept/create`, data)
},
update(id: number, data: DeptForm): Promise<DeptItem> {
return http.Put(`${SYSTEM_BASE}/dept/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/dept/delete`, { ids: JSON.stringify(ids) })
},
batchStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/dept/status/batch`, data)
},
}
export interface DeptQuery {
name?: string
status?: string
}
export interface DeptForm extends BaseFormType {
name?: string
code: string
parent_id?: number
order?: number
leader?: string
phone?: string
email?: string
status?: number
description?: string
}
export interface DeptItem extends BaseType, DeptForm {
id: number
parent_name?: string
children?: DeptItem[]
}
@@ -0,0 +1,80 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 字典管理 API
* 与 web 端 module_system/dict.ts 对齐(完整字段定义)
*/
export const DictAPI = {
getTypePage(params?: Record<string, any>): Promise<PageResult<DictTypeItem>> {
return http.Get(`${SYSTEM_BASE}/dict/type/list`, params)
},
getTypeDetail(id: number): Promise<DictTypeItem> {
return http.Get(`${SYSTEM_BASE}/dict/type/detail/${id}`)
},
createType(data: DictTypeForm): Promise<DictTypeItem> {
return http.Post(`${SYSTEM_BASE}/dict/type/create`, data)
},
updateType(id: number, data: DictTypeForm): Promise<DictTypeItem> {
return http.Put(`${SYSTEM_BASE}/dict/type/update/${id}`, data)
},
removeType(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/dict/type/delete`, { ids: JSON.stringify(ids) })
},
batchTypeStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/dict/type/status/batch`, data)
},
getTypeOptions(): Promise<DictTypeItem[]> {
return http.Get(`${SYSTEM_BASE}/dict/type/optionselect`)
},
getDataPage(params?: Record<string, any>): Promise<PageResult<DictDataItem>> {
return http.Get(`${SYSTEM_BASE}/dict/data/list`, params)
},
getDataDetail(id: number): Promise<DictDataItem> {
return http.Get(`${SYSTEM_BASE}/dict/data/detail/${id}`)
},
createData(data: DictDataForm): Promise<DictDataItem> {
return http.Post(`${SYSTEM_BASE}/dict/data/create`, data)
},
updateData(id: number, data: DictDataForm): Promise<DictDataItem> {
return http.Put(`${SYSTEM_BASE}/dict/data/update/${id}`, data)
},
removeData(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/dict/data/delete`, { ids: JSON.stringify(ids) })
},
batchDataStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/dict/data/status/batch`, data)
},
getDataByType(dictType: string): Promise<DictDataItem[]> {
return http.Get(`${SYSTEM_BASE}/dict/data/info/${dictType}`)
},
}
export interface DictTypeForm extends BaseFormType {
dict_name?: string
dict_type?: string
status?: number
description?: string
}
export interface DictTypeItem extends BaseType, DictTypeForm {
id: number
dict_type: string
}
export interface DictDataForm extends BaseFormType {
dict_sort?: number
dict_label?: string
dict_value?: string
dict_type?: string
dict_type_id?: number
css_class?: string
list_class?: string
is_default?: boolean | string
status?: number
description?: string
}
export interface DictDataItem extends BaseType, DictDataForm {}
+57
View File
@@ -0,0 +1,57 @@
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 日志管理 API(操作日志 + 登录日志)
* 与 web 端 module_system/log.ts 对齐(完整字段定义)
*/
export const OperationLogAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<OplogItem>> {
return http.Get(`${SYSTEM_BASE}/log/operation/list`, params)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/log/operation/delete`, { ids: JSON.stringify(ids) })
},
getDetail(id: number): Promise<OplogItem> {
return http.Get(`${SYSTEM_BASE}/log/operation/detail/${id}`)
},
exportLog(params?: Record<string, any>): Promise<unknown> {
return http.Post(`${SYSTEM_BASE}/log/export`, params)
},
}
export const LoginLogAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<LoginLogItem>> {
return http.Get(`${SYSTEM_BASE}/log/login/list`, params)
},
getDetail(id: number): Promise<LoginLogItem> {
return http.Get(`${SYSTEM_BASE}/log/login/detail/${id}`)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/log/login/delete`, { ids: JSON.stringify(ids) })
},
}
export interface OplogItem extends BaseType {
username?: string
status?: number
description?: string
request_path?: string
request_method?: string
request_payload?: Record<string, unknown> | string
request_ip?: string
response_code?: number
response_json?: Record<string, unknown> | string
process_time?: string
}
export interface LoginLogItem extends BaseType {
username?: string
login_ip?: string
login_location?: string
request_browser?: string
request_os?: string
status?: string | number
msg?: string
}
@@ -0,0 +1,71 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 菜单管理 API
* 与 web 端 module_system/menu.ts 对齐(完整字段定义)
*/
export const MenuAPI = {
getTree(params?: MenuQuery): Promise<MenuItem[]> {
return http.Get(`${SYSTEM_BASE}/menu/tree`, params)
},
getDetail(id: number): Promise<MenuItem> {
return http.Get(`${SYSTEM_BASE}/menu/detail/${id}`)
},
create(data: MenuForm): Promise<MenuItem> {
return http.Post(`${SYSTEM_BASE}/menu/create`, data)
},
update(id: number, data: MenuForm): Promise<MenuItem> {
return http.Put(`${SYSTEM_BASE}/menu/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/menu/delete`, { ids: JSON.stringify(ids) })
},
batchStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/menu/status/batch`, data)
},
}
export interface MenuQuery {
name?: string
status?: number
type?: number
menu_client?: 'web' | 'app'
}
export interface MenuForm extends BaseFormType {
name?: string
type: number
icon?: string
order?: number
permission?: string
route_name?: string
route_path?: string
component_path?: string
redirect?: string
parent_id?: number
keep_alive?: boolean
hidden?: boolean
always_show?: boolean
title?: string
params?: { key: string, value: string }[]
affix?: boolean
link?: string
is_iframe?: boolean
is_hide_tab?: boolean
active_path?: string
show_badge?: boolean
show_text_badge?: string
scope?: 'web' | 'app'
client?: 'pc' | 'app'
status?: number
description?: string
}
export interface MenuItem extends BaseType, MenuForm {
id: number
parent_name?: string
children?: MenuItem[]
}
@@ -0,0 +1,42 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 公告管理 API
* 与 web 端 module_system/notice.ts 对齐(完整字段定义)
*/
export const NoticeAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<NoticeItem>> {
return http.Get(`${SYSTEM_BASE}/notice/list`, params)
},
getDetail(id: number): Promise<NoticeItem> {
return http.Get(`${SYSTEM_BASE}/notice/detail/${id}`)
},
create(data: NoticeForm): Promise<NoticeItem> {
return http.Post(`${SYSTEM_BASE}/notice/create`, data)
},
update(id: number, data: NoticeForm): Promise<NoticeItem> {
return http.Put(`${SYSTEM_BASE}/notice/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/notice/delete`, { ids: JSON.stringify(ids) })
},
batchStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/notice/status/batch`, data)
},
getAvailable(): Promise<NoticeItem[]> {
return http.Get(`${SYSTEM_BASE}/notice/available`)
},
}
export interface NoticeForm extends BaseFormType {
notice_title?: string
notice_type?: string
notice_content?: string
status?: number
description?: string
}
export interface NoticeItem extends BaseType, NoticeForm {}
@@ -0,0 +1,27 @@
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 参数配置 API
* 与 web 端 module_system/params.ts 对齐(完整字段定义)
*/
export const ParamsAPI = {
getInfo(): Promise<ParamsItem[]> {
return http.Get(`${SYSTEM_BASE}/param/info`)
},
update(id: number, data: ParamsForm): Promise<ParamsItem> {
return http.Put(`${SYSTEM_BASE}/param/update/${id}`, data)
},
}
export interface ParamsForm extends BaseFormType {
config_name?: string
config_key?: string
config_value?: string
config_type?: boolean
status?: number
description?: string
}
export interface ParamsItem extends BaseType, ParamsForm {}
@@ -0,0 +1,47 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 岗位管理 API
* 与 web 端 module_system/position.ts 对齐(完整字段定义)
*/
export const PositionAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<PositionItem>> {
return http.Get(`${SYSTEM_BASE}/position/list`, params)
},
getDetail(id: number): Promise<PositionItem> {
return http.Get(`${SYSTEM_BASE}/position/detail/${id}`)
},
create(data: PositionForm): Promise<PositionItem> {
return http.Post(`${SYSTEM_BASE}/position/create`, data)
},
update(id: number, data: PositionForm): Promise<PositionItem> {
return http.Put(`${SYSTEM_BASE}/position/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/position/delete`, { ids: JSON.stringify(ids) })
},
batchStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/position/status/batch`, data)
},
getOptions(): Promise<{ value: number, label: string }[]> {
return http.Get(`${SYSTEM_BASE}/position/options`)
},
exportPositions(params?: Record<string, any>): Promise<unknown> {
return http.Post(`${SYSTEM_BASE}/position/export`, params)
},
}
export interface PositionForm extends BaseFormType {
name?: string
code?: string
order?: number
status?: number
description?: string
}
export interface PositionItem extends BaseType, PositionForm {
id: number
}
@@ -0,0 +1,80 @@
import type { BatchSetStatus } from './user'
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 角色管理 API
* 与 web 端 module_system/role.ts 对齐(完整字段定义)
*/
export const RoleAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<RoleItem>> {
return http.Get(`${SYSTEM_BASE}/role/list`, params)
},
getDetail(id: number): Promise<RoleItem> {
return http.Get(`${SYSTEM_BASE}/role/detail/${id}`)
},
create(data: RoleForm): Promise<RoleItem> {
return http.Post(`${SYSTEM_BASE}/role/create`, data)
},
update(id: number, data: RoleForm): Promise<RoleItem> {
return http.Put(`${SYSTEM_BASE}/role/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/role/delete`, { ids: JSON.stringify(ids) })
},
batchStatus(data: BatchSetStatus): Promise<void> {
return http.Patch(`${SYSTEM_BASE}/role/status/batch`, data)
},
setPermission(data: RolePermissionForm): Promise<void> {
return http.Put(`${SYSTEM_BASE}/role/permission`, data)
},
getOptions(): Promise<{ value: number, label: string }[]> {
return http.Get(`${SYSTEM_BASE}/role/options`)
},
exportRoles(params?: Record<string, any>): Promise<unknown> {
return http.Post(`${SYSTEM_BASE}/role/export`, params)
},
}
export interface RoleForm extends BaseFormType {
name?: string
code: string
order?: number
data_scope?: number
status?: number
description?: string
}
export interface RoleItem extends BaseType, RoleForm {
id: number
menus?: MenuItem[]
depts?: DeptItem[]
}
export interface RolePermissionForm {
role_ids: number[]
menu_ids: number[]
dept_ids: number[]
data_scope: number
}
/* 菜单表(角色权限回显用) */
export interface MenuItem extends BaseType {
id?: number
name?: string
type?: number
permission?: string
parent_id?: number
status?: number
description?: string
children?: MenuItem[]
}
/* 部门树(角色权限回显用) */
export interface DeptItem extends BaseType {
id?: number
name?: string
parent_id?: number
children?: DeptItem[]
}
@@ -0,0 +1,70 @@
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 工单管理 API
* 与 web 端 module_system/ticket.ts 对齐(完整字段定义)
*/
export const TicketAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<TicketItem>> {
return http.Get(`${SYSTEM_BASE}/ticket/list`, params)
},
getDetail(id: number): Promise<TicketItem> {
return http.Get(`${SYSTEM_BASE}/ticket/detail/${id}`)
},
create(data: TicketForm): Promise<TicketItem> {
return http.Post(`${SYSTEM_BASE}/ticket/create`, data)
},
update(id: number, data: Record<string, any>): Promise<TicketItem> {
return http.Put(`${SYSTEM_BASE}/ticket/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/ticket/delete`, { ids: JSON.stringify(ids) })
},
batch(data: { ids: number[], status: number, assigned_id?: number }): Promise<void> {
return http.Put(`${SYSTEM_BASE}/ticket/batch`, data)
},
exportTickets(params?: Record<string, any>): Promise<unknown> {
return http.Post(`${SYSTEM_BASE}/ticket/export`, params)
},
getComments(ticketId: number, params?: Record<string, any>): Promise<PageResult<TicketComment>> {
return http.Get(`${SYSTEM_BASE}/ticket/${ticketId}/comments`, params)
},
createComment(ticketId: number, data: { content: string }): Promise<TicketComment> {
return http.Post(`${SYSTEM_BASE}/ticket/${ticketId}/comments`, data)
},
}
export interface TicketForm extends BaseFormType {
title: string
ticket_content?: string
summary?: string
ticket_type: string
images?: string
reply?: string
assigned_id?: number
status?: number
description?: string
}
export interface TicketItem extends BaseType {
title?: string
ticket_content?: string
summary?: string
ticket_type?: string
status?: string | number
assigned_id?: number
assigned_by?: CommonType
images?: string
reply?: string
description?: string
}
export interface TicketComment extends BaseType {
ticket_id?: number
user_id?: number
username?: string
content?: string
created_by_name?: string
}
+329
View File
@@ -0,0 +1,329 @@
import { http } from '@/http'
import { ContentTypeEnum } from '@/http/tools/enum'
const USER_BASE_URL = '/system/user'
/**
* 用户管理 API
* 与 web 端 module_system/user.ts 对齐(完整字段定义)
*/
const UserAPI = {
/**
* 个人中心用户信息
*
* @returns 登录用户昵称、头像信息,包括角色和权限
*/
getCurrentUserInfo(): Promise<UserInfo> {
return http.Get(`${USER_BASE_URL}/current/info`)
},
/**
* 当前用户头像上传
*
* @param body
* @returns 上传后的文件路径
*/
uploadCurrentUserAvatar(body: Record<string, any>): Promise<UploadFileResult> {
return http.Post(`${USER_BASE_URL}/current/avatar/upload`, body, {
headers: {
'Content-Type': ContentTypeEnum.FORM_DATA,
},
})
},
/**
* 修改个人中心用户信息
*
* @param body
* @returns 修改后的用户信息
*/
updateCurrentUserInfo(body: UserProfileForm): Promise<UserInfo> {
return http.Put(`${USER_BASE_URL}/current/info/update`, body)
},
/**
* 修改个人中心用户密码
*
* @param body
* @returns 修改后的用户信息
*/
changeCurrentUserPassword(body: PasswordChangeForm): Promise<void> {
return http.Put(`${USER_BASE_URL}/current/password/change`, body)
},
/**
* 注册用户
*
* @param body
* @returns 忘记密码结果
*/
registerUser(body: RegisterForm): Promise<void> {
return http.Post(`${USER_BASE_URL}/register`, body)
},
/**
* 忘记密码
*
* @param body
* @returns 忘记密码结果
*/
forgetPassword(body: ForgetPasswordForm): Promise<void> {
return http.Post(`${USER_BASE_URL}/password/forget`, body)
},
/**
* 重置用户密码
*
* @param id 用户ID
* @param body 新密码
* @param body.password 新密码
*/
resetPassword(id: number, body: { password: string }): Promise<void> {
return http.Put(`${USER_BASE_URL}/password/reset/${id}`, body)
},
/**
* 批量修改用户状态
*
* @param body 批量操作参数
* @param body.ids 用户ID列表
* @param body.status 目标状态
*/
batchStatus(body: BatchSetStatus): Promise<void> {
return http.Patch(`${USER_BASE_URL}/status/batch`, body)
},
/**
* 导出用户
*
* @param params 导出参数
*/
exportUsers(params?: Record<string, any>): Promise<unknown> {
return http.Post(`${USER_BASE_URL}/export`, params)
},
/**
* 获取用户导入模板
*/
getImportTemplate(): Promise<unknown> {
return http.Get(`${USER_BASE_URL}/import/template`)
},
/**
* 导入用户数据
*
* @param body 导入数据
*/
importData(body: Record<string, any>): Promise<void> {
return http.Post(`${USER_BASE_URL}/import/data`, body)
},
/**
* 获取用户分页列表
*
* @param queryParams 查询参数
*/
getUserPage(queryParams: UserPageQuery): Promise<PageResult<UserInfo>> {
return http.Get(`${USER_BASE_URL}/list`, queryParams)
},
/**
* 获取用户表单详情
*
* @param userId 用户ID
* @returns 用户表单详情
*/
getUserDetail(userId: number): Promise<UserForm> {
return http.Get(`${USER_BASE_URL}/detail/${userId}`)
},
/**
* 添加用户
*
* @param body 用户表单数据
*/
addUser(body: UserForm): Promise<void> {
return http.Post(`${USER_BASE_URL}/create`, body)
},
/**
* 修改用户
*
* @param body 用户表单数据
*/
updateUser(body: UserForm): Promise<void> {
return http.Put(`${USER_BASE_URL}/update`, body)
},
/**
* 删除用户
*
* @param ids 用户ID数组
*/
deleteUser(ids: number[]): Promise<void> {
return http.Delete(`${USER_BASE_URL}/delete`, ids)
},
}
export default UserAPI
/* 忘记密码表单 */
export interface ForgetPasswordForm {
username: string
new_password: string
confirmPassword: string
}
/* 注册表单 */
export interface RegisterForm {
username: string
password: string
confirmPassword: string
}
/* 分页查询表单 */
export interface UserPageQuery extends PageQuery {
username?: string
name?: string
mobile?: string
email?: string
dept_id?: number
status?: number
start_time?: string
end_time?: string
}
/* 搜索选择器数据类型 */
export interface searchSelectDataType {
name?: string
status?: number
}
/* 用户表单 */
export interface UserForm extends BaseFormType {
username?: string
name?: string
dept_id?: number
dept_name?: string
role_ids?: number[]
role_names?: string[]
position_ids?: number[]
position_names?: string[]
password?: string
gender?: number
email?: string
mobile?: string
is_superuser?: boolean
status?: number
description?: string
}
/* 登录用户信息 */
export interface UserInfo extends BaseType {
username?: string
name?: string
avatar?: string
email?: string
mobile?: string
gender?: string
password?: string
menus?: MenuTable[]
dept?: deptTreeType
dept_id?: deptTreeType['id']
dept_name?: deptTreeType['name']
roles?: roleSelectorType[]
role_names?: roleSelectorType['name'][]
role_ids?: roleSelectorType['id'][]
positions?: positionSelectorType[]
position_names?: positionSelectorType['name'][]
position_ids?: positionSelectorType['id'][]
is_superuser?: boolean
last_login?: string
gitee_login?: string
github_login?: string
wx_login?: string
qq_login?: string
status?: number
description?: string
}
/* 菜单表 */
export interface MenuTable extends BaseType {
name?: string
type?: number
icon?: string
order?: number
permission?: string
route_name?: string
route_path?: string
component_path?: string
redirect?: string
parent_id?: number
parent_name?: string
keep_alive?: boolean
hidden?: boolean
always_show?: boolean
title?: string
params?: { key: string, value: string }[]
affix?: boolean
status?: number
description?: string
children?: MenuTable[]
}
/* 部门树 */
export interface deptTreeType {
id?: number
name?: string
parent_id?: number
children?: deptTreeType[]
}
/* 角色选择器 */
export interface roleSelectorType {
id?: number
name?: string
status?: number
description?: string
}
/* 职位选择器 */
export interface positionSelectorType {
id?: number
name?: string
status?: number
description?: string
}
/* 个人中心用户信息表单 */
export interface UserProfileForm extends BaseFormType {
name?: string
gender?: string
mobile?: string
email?: string
username?: string
dept_name?: string
positions?: positionSelectorType[]
roles?: roleSelectorType[]
avatar?: string
created_time?: string
}
/* 修改密码表单 */
export interface PasswordChangeForm {
old_password: string
new_password: string
confirm_password: string
}
/* 重置密码表单 */
export interface ResetPasswordForm {
id: number
password: string
}
/* 批量设置状态 */
export interface BatchSetStatus {
ids: number[]
status: number
}
@@ -0,0 +1,45 @@
import { http } from '@/http'
const SYSTEM_BASE = '/system'
/**
* 版本发布管理 API
* 与 web 端 module_system/version.ts 对齐(完整字段定义)
*/
export const VersionAPI = {
getPage(params?: Record<string, any>): Promise<PageResult<VersionItem>> {
return http.Get(`${SYSTEM_BASE}/versions/list`, params)
},
/** 获取已发布版本列表(无需认证) */
getPublished(): Promise<VersionItem[]> {
return http.Get(`${SYSTEM_BASE}/versions/published`)
},
getDetail(id: number): Promise<VersionItem> {
return http.Get(`${SYSTEM_BASE}/versions/detail/${id}`)
},
create(data: VersionForm): Promise<VersionItem> {
return http.Post(`${SYSTEM_BASE}/versions/create`, data)
},
update(id: number, data: VersionForm): Promise<VersionItem> {
return http.Put(`${SYSTEM_BASE}/versions/update/${id}`, data)
},
remove(ids: number[]): Promise<void> {
return http.Delete(`${SYSTEM_BASE}/versions/delete`, { ids: JSON.stringify(ids) })
},
setStatus(id: number, status: number): Promise<void> {
return http.Put(`${SYSTEM_BASE}/versions/${id}/status`, { status })
},
}
export interface VersionForm extends BaseFormType {
version?: string
title?: string
date?: string
content?: string
description?: string
sort?: number
status?: number
require_re_login?: boolean
}
export interface VersionItem extends BaseType, VersionForm {}
@@ -0,0 +1,114 @@
/**
* 定时任务 API 模块(对应后端 `plugin.module_task.cronjob.job`)
* 包含: 调度器管理 / 任务管理 / 任务执行日志
*/
import { http } from '@/http'
const JOB_BASE = '/task/cronjob/job'
/* ==================== 调度器管理 ==================== */
export const SchedulerAPI = {
/** 获取调度器状态 */
getStatus(): Promise<SchedulerStatus> {
return http.Get(`${JOB_BASE}/scheduler/status`)
},
/** 获取调度器任务列表 */
getJobs(): Promise<SchedulerJob[]> {
return http.Get(`${JOB_BASE}/scheduler/jobs`)
},
/** 启动调度器 */
start(): Promise<void> {
return http.Post(`${JOB_BASE}/scheduler/start`)
},
/** 暂停调度器 */
pause(): Promise<void> {
return http.Post(`${JOB_BASE}/scheduler/pause`)
},
/** 恢复调度器 */
resume(): Promise<void> {
return http.Post(`${JOB_BASE}/scheduler/resume`)
},
/** 关闭调度器 */
shutdown(): Promise<void> {
return http.Post(`${JOB_BASE}/scheduler/shutdown`)
},
/** 清空所有任务 */
clear(): Promise<void> {
return http.Delete(`${JOB_BASE}/scheduler/jobs/clear`)
},
/** 获取调度器控制台信息 */
getConsole(): Promise<unknown> {
return http.Get(`${JOB_BASE}/scheduler/console`)
},
}
/* ==================== 任务管理 ==================== */
export const JobAPI = {
/** 暂停任务 */
pause(jobId: string): Promise<void> {
return http.Post(`${JOB_BASE}/task/pause/${jobId}`)
},
/** 恢复任务 */
resume(jobId: string): Promise<void> {
return http.Post(`${JOB_BASE}/task/resume/${jobId}`)
},
/** 立即执行任务 */
run(jobId: string): Promise<void> {
return http.Post(`${JOB_BASE}/task/run/${jobId}`)
},
/** 修改任务 */
modify(jobId: string, data: Record<string, any>): Promise<void> {
return http.Put(`${JOB_BASE}/task/modify/${jobId}`, data)
},
/** 移除任务 */
remove(jobId: string): Promise<void> {
return http.Delete(`${JOB_BASE}/task/remove/${jobId}`)
},
}
/* ==================== 任务执行日志 ==================== */
export const JobLogAPI = {
/** 查询执行日志列表 */
getPage(params?: Record<string, any>): Promise<PageResult<JobLogItem>> {
return http.Get(`${JOB_BASE}/log/list`, params)
},
/** 获取执行日志详情 */
getDetail(id: number): Promise<JobLogItem> {
return http.Get(`${JOB_BASE}/log/detail/${id}`)
},
/** 删除执行日志 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${JOB_BASE}/log/delete`, { ids: JSON.stringify(ids) })
},
}
/* ==================== 类型定义 ==================== */
export interface SchedulerStatus {
status?: string
is_running?: boolean
running: boolean
job_count: number
}
export interface SchedulerJob {
id: string
name: string
status?: string
next_run_time?: string
trigger?: string
func?: string
args?: any[]
}
export interface JobLogItem {
id: number
job_name?: string
job_id?: string
status?: string
result?: string
error_msg?: string
start_time?: string
end_time?: string
created_time?: string
}
@@ -0,0 +1,70 @@
/**
* 任务节点 API 模块(对应后端 `plugin.module_task.cronjob.node`)
*/
import { http } from '@/http'
const NODE_BASE = '/task/cronjob/node'
/* ==================== 任务节点 ==================== */
export const NodeAPI = {
/** 获取节点列表(选项) */
getOptions(): Promise<NodeOption[]> {
return http.Get(`${NODE_BASE}/options`)
},
/** 获取节点详情 */
getDetail(id: number): Promise<NodeItem> {
return http.Get(`${NODE_BASE}/detail/${id}`)
},
/** 节点分页列表 */
getPage(params?: Record<string, any>): Promise<PageResult<NodeItem>> {
return http.Get(`${NODE_BASE}/list`, params)
},
/** 创建节点 */
create(data: NodeForm): Promise<NodeItem> {
return http.Post(`${NODE_BASE}/create`, data)
},
/** 修改节点 */
update(id: number, data: NodeForm): Promise<NodeItem> {
return http.Put(`${NODE_BASE}/update/${id}`, data)
},
/** 删除节点 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${NODE_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 清空节点 */
clear(_id?: number): Promise<void> {
return http.Delete(`${NODE_BASE}/clear`)
},
/** 调试节点 */
execute(id: number): Promise<unknown> {
return http.Post(`${NODE_BASE}/execute/${id}`)
},
/** 批量设置节点状态 */
batchStatus(data: { ids: number[], status: number }): Promise<void> {
return http.Patch(`${NODE_BASE}/status/batch`, data)
},
}
/* ==================== 类型定义 ==================== */
export interface NodeOption {
value: number
label: string
path: string
}
export interface NodeForm {
name: string
host: string
port: number
type: string
description?: string
}
export interface NodeItem extends NodeForm {
id: number
status?: string
task_count?: number
created_time?: string
updated_time?: string
}
@@ -0,0 +1,100 @@
/**
* 工作流流程 API 模块(对应后端 `plugin.module_task.workflow.flow`)
* 与 web 端 module_task/workflow/flow.ts 对齐(完整字段定义)
*/
import { http } from '@/http'
const FLOW_BASE = '/task/workflow/flow'
/* ==================== 流程编排 ==================== */
export const WorkflowAPI = {
/** 工作流详情 */
getDetail(id: number): Promise<WorkflowItem> {
return http.Get(`${FLOW_BASE}/detail/${id}`)
},
/** 工作流列表 */
getPage(params?: Record<string, any>): Promise<PageResult<WorkflowItem>> {
return http.Get(`${FLOW_BASE}/list`, params)
},
/** 创建工作流 */
create(data: WorkflowForm): Promise<WorkflowItem> {
return http.Post(`${FLOW_BASE}/create`, data)
},
/** 更新工作流 */
update(id: number, data: WorkflowForm): Promise<WorkflowItem> {
return http.Put(`${FLOW_BASE}/update/${id}`, data)
},
/** 删除工作流 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${FLOW_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 发布工作流 */
publish(id: number): Promise<void> {
return http.Post(`${FLOW_BASE}/publish/${id}`)
},
/** 执行工作流 */
execute(data: WorkflowExecuteForm): Promise<WorkflowExecuteResult> {
return http.Post(`${FLOW_BASE}/execute`, data)
},
}
/* ==================== 类型定义 ==================== */
export interface WorkflowPageQuery extends PageQuery {
name?: string
code?: string
status?: number
}
export interface WorkflowForm {
name: string
description?: string
nodes?: WorkflowNode[]
edges?: WorkflowEdge[]
}
export interface WorkflowItem extends WorkflowForm {
id: number
status?: string
version?: number
created_time?: string
updated_time?: string
}
export interface WorkflowPublishForm {
remark?: string
}
export interface WorkflowExecuteForm {
workflow_id: number
variables?: Record<string, any>
business_key?: string
job_id?: number
}
export interface WorkflowExecuteResult {
workflow_id: number
workflow_name: string
status: number
start_time?: string
end_time?: string
variables?: Record<string, any>
node_results?: Record<string, any>
error?: string
}
export interface WorkflowNode {
id?: string
type: string
label?: string
position?: { x: number, y: number }
data?: Record<string, any>
}
export interface WorkflowEdge {
id?: string
source: string
target: string
label?: string
condition?: string
}
@@ -0,0 +1,60 @@
/**
* 工作流节点类型 API 模块(对应后端 `plugin.module_task.workflow.nodes`)
*/
import { http } from '@/http'
const NODES_BASE = '/task/workflow/nodes'
/* ==================== 工作流节点类型 ==================== */
export const WorkflowNodeTypeAPI = {
/** 节点选项 */
getOptions(): Promise<WorkflowNodeTypeOption[]> {
return http.Get(`${NODES_BASE}/options`)
},
/** 节点详情 */
getDetail(id: number): Promise<WorkflowNodeTypeItem> {
return http.Get(`${NODES_BASE}/detail/${id}`)
},
/** 节点列表 */
getPage(params?: Record<string, any>): Promise<PageResult<WorkflowNodeTypeItem>> {
return http.Get(`${NODES_BASE}/list`, params)
},
/** 创建节点 */
create(data: WorkflowNodeTypeForm): Promise<WorkflowNodeTypeItem> {
return http.Post(`${NODES_BASE}/create`, data)
},
/** 更新节点 */
update(id: number, data: WorkflowNodeTypeForm): Promise<WorkflowNodeTypeItem> {
return http.Put(`${NODES_BASE}/update/${id}`, data)
},
/** 删除节点 */
remove(ids: number[]): Promise<void> {
return http.Delete(`${NODES_BASE}/delete`, { ids: JSON.stringify(ids) })
},
/** 节点选择列表 */
getSelect(): Promise<WorkflowNodeTypeOption[]> {
return http.Get(`${NODES_BASE}/select`)
},
}
/* ==================== 类型定义 ==================== */
export interface WorkflowNodeTypeOption {
value: number
label: string
type: string
}
export interface WorkflowNodeTypeForm {
name: string
type: string
handler_path?: string
params_schema?: Record<string, any>
description?: string
}
export interface WorkflowNodeTypeItem extends WorkflowNodeTypeForm {
id: number
created_time?: string
updated_time?: string
}