feat: 实现前端组件库和API服务基础架构
refactor: 移除废弃的AGI策略演进服务 fix: 修正磁盘I/O指标字段命名 chore: 更新项目依赖版本 test: 添加前后端集成测试用例 docs: 更新AI模块接口文档 style: 统一审计日志字段命名规范 perf: 优化Redis订阅连接错误处理 build: 配置多项目工作区结构 ci: 添加Vite开发服务器CORS支持
This commit is contained in:
196
dashboard/src/models/StateManagement.ts
Normal file
196
dashboard/src/models/StateManagement.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
// FE-OP002: 前端状态管理优化
|
||||
import { createStore, combineReducers, applyMiddleware } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
import { createLogger } from 'redux-logger';
|
||||
|
||||
// 定义状态类型
|
||||
interface AppState {
|
||||
user: UserState;
|
||||
products: ProductState;
|
||||
orders: OrderState;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
interface UserState {
|
||||
isLoggedIn: boolean;
|
||||
userInfo: any;
|
||||
token: string | null;
|
||||
}
|
||||
|
||||
interface ProductState {
|
||||
list: any[];
|
||||
selected: any | null;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
interface OrderState {
|
||||
list: any[];
|
||||
selected: any | null;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
// 定义初始状态
|
||||
const initialState: AppState = {
|
||||
user: {
|
||||
isLoggedIn: false,
|
||||
userInfo: null,
|
||||
token: null,
|
||||
},
|
||||
products: {
|
||||
list: [],
|
||||
selected: null,
|
||||
loading: false,
|
||||
},
|
||||
orders: {
|
||||
list: [],
|
||||
selected: null,
|
||||
loading: false,
|
||||
},
|
||||
loading: false,
|
||||
error: null,
|
||||
};
|
||||
|
||||
// 定义action类型
|
||||
const SET_LOADING = 'SET_LOADING';
|
||||
const SET_ERROR = 'SET_ERROR';
|
||||
const CLEAR_ERROR = 'CLEAR_ERROR';
|
||||
|
||||
// User actions
|
||||
const SET_USER = 'SET_USER';
|
||||
const LOGOUT = 'LOGOUT';
|
||||
|
||||
// Product actions
|
||||
const SET_PRODUCTS = 'SET_PRODUCTS';
|
||||
const SET_SELECTED_PRODUCT = 'SET_SELECTED_PRODUCT';
|
||||
const SET_PRODUCTS_LOADING = 'SET_PRODUCTS_LOADING';
|
||||
|
||||
// Order actions
|
||||
const SET_ORDERS = 'SET_ORDERS';
|
||||
const SET_SELECTED_ORDER = 'SET_SELECTED_ORDER';
|
||||
const SET_ORDERS_LOADING = 'SET_ORDERS_LOADING';
|
||||
|
||||
// Action creators
|
||||
export const setLoading = (loading: boolean) => ({ type: SET_LOADING, payload: loading });
|
||||
export const setError = (error: string) => ({ type: SET_ERROR, payload: error });
|
||||
export const clearError = () => ({ type: CLEAR_ERROR });
|
||||
|
||||
// User action creators
|
||||
export const setUser = (userInfo: any, token: string) => ({ type: SET_USER, payload: { userInfo, token } });
|
||||
export const logout = () => ({ type: LOGOUT });
|
||||
|
||||
// Product action creators
|
||||
export const setProducts = (products: any[]) => ({ type: SET_PRODUCTS, payload: products });
|
||||
export const setSelectedProduct = (product: any | null) => ({ type: SET_SELECTED_PRODUCT, payload: product });
|
||||
export const setProductsLoading = (loading: boolean) => ({ type: SET_PRODUCTS_LOADING, payload: loading });
|
||||
|
||||
// Order action creators
|
||||
export const setOrders = (orders: any[]) => ({ type: SET_ORDERS, payload: orders });
|
||||
export const setSelectedOrder = (order: any | null) => ({ type: SET_SELECTED_ORDER, payload: order });
|
||||
export const setOrdersLoading = (loading: boolean) => ({ type: SET_ORDERS_LOADING, payload: loading });
|
||||
|
||||
// Reducers
|
||||
const userReducer = (state = initialState.user, action: any) => {
|
||||
switch (action.type) {
|
||||
case SET_USER:
|
||||
return {
|
||||
...state,
|
||||
isLoggedIn: true,
|
||||
userInfo: action.payload.userInfo,
|
||||
token: action.payload.token,
|
||||
};
|
||||
case LOGOUT:
|
||||
return initialState.user;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const productsReducer = (state = initialState.products, action: any) => {
|
||||
switch (action.type) {
|
||||
case SET_PRODUCTS:
|
||||
return {
|
||||
...state,
|
||||
list: action.payload,
|
||||
};
|
||||
case SET_SELECTED_PRODUCT:
|
||||
return {
|
||||
...state,
|
||||
selected: action.payload,
|
||||
};
|
||||
case SET_PRODUCTS_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: action.payload,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const ordersReducer = (state = initialState.orders, action: any) => {
|
||||
switch (action.type) {
|
||||
case SET_ORDERS:
|
||||
return {
|
||||
...state,
|
||||
list: action.payload,
|
||||
};
|
||||
case SET_SELECTED_ORDER:
|
||||
return {
|
||||
...state,
|
||||
selected: action.payload,
|
||||
};
|
||||
case SET_ORDERS_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: action.payload,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const appReducer = (state = initialState, action: any) => {
|
||||
switch (action.type) {
|
||||
case SET_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: action.payload,
|
||||
};
|
||||
case SET_ERROR:
|
||||
return {
|
||||
...state,
|
||||
error: action.payload,
|
||||
};
|
||||
case CLEAR_ERROR:
|
||||
return {
|
||||
...state,
|
||||
error: null,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
// 组合reducers
|
||||
const rootReducer = combineReducers({
|
||||
user: userReducer,
|
||||
products: productsReducer,
|
||||
orders: ordersReducer,
|
||||
app: appReducer,
|
||||
});
|
||||
|
||||
// 中间件
|
||||
const middleware = [thunk];
|
||||
|
||||
// 开发环境添加logger
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const logger = createLogger();
|
||||
middleware.push(logger);
|
||||
}
|
||||
|
||||
// 创建store
|
||||
const store = createStore(rootReducer, applyMiddleware(...middleware));
|
||||
|
||||
export type RootState = ReturnType<typeof rootReducer>;
|
||||
export default store;
|
||||
53
dashboard/src/models/global.ts
Normal file
53
dashboard/src/models/global.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
interface UserInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
interface GlobalState {
|
||||
user: UserInfo | null;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
theme: 'light' | 'dark';
|
||||
}
|
||||
|
||||
const useGlobalModel = () => {
|
||||
const [state, setState] = useState<GlobalState>({
|
||||
user: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
theme: 'light',
|
||||
});
|
||||
|
||||
const setUser = useCallback((user: UserInfo | null) => {
|
||||
setState(prev => ({ ...prev, user }));
|
||||
}, []);
|
||||
|
||||
const setLoading = useCallback((loading: boolean) => {
|
||||
setState(prev => ({ ...prev, loading }));
|
||||
}, []);
|
||||
|
||||
const setError = useCallback((error: string | null) => {
|
||||
setState(prev => ({ ...prev, error }));
|
||||
}, []);
|
||||
|
||||
const toggleTheme = useCallback(() => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
theme: prev.theme === 'light' ? 'dark' : 'light',
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return {
|
||||
...state,
|
||||
setUser,
|
||||
setLoading,
|
||||
setError,
|
||||
toggleTheme,
|
||||
};
|
||||
};
|
||||
|
||||
export default useGlobalModel;
|
||||
3
dashboard/src/models/index.ts
Normal file
3
dashboard/src/models/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { default as useGlobalModel } from './global';
|
||||
export { default as useProductModel } from './product';
|
||||
export { default as useOrderModel } from './order';
|
||||
91
dashboard/src/models/order.ts
Normal file
91
dashboard/src/models/order.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
interface OrderItem {
|
||||
id: string;
|
||||
productId: string;
|
||||
productName: string;
|
||||
quantity: number;
|
||||
price: number;
|
||||
}
|
||||
|
||||
interface Order {
|
||||
id: string;
|
||||
orderNo: string;
|
||||
customerId: string;
|
||||
customerName: string;
|
||||
totalAmount: number;
|
||||
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled';
|
||||
items: OrderItem[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
interface OrderState {
|
||||
orders: Order[];
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
currentOrder: Order | null;
|
||||
pagination: {
|
||||
current: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
const useOrderModel = () => {
|
||||
const [state, setState] = useState<OrderState>({
|
||||
orders: [],
|
||||
loading: false,
|
||||
error: null,
|
||||
currentOrder: null,
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const setOrders = useCallback((orders: Order[]) => {
|
||||
setState(prev => ({ ...prev, orders }));
|
||||
}, []);
|
||||
|
||||
const setLoading = useCallback((loading: boolean) => {
|
||||
setState(prev => ({ ...prev, loading }));
|
||||
}, []);
|
||||
|
||||
const setError = useCallback((error: string | null) => {
|
||||
setState(prev => ({ ...prev, error }));
|
||||
}, []);
|
||||
|
||||
const setCurrentOrder = useCallback((order: Order | null) => {
|
||||
setState(prev => ({ ...prev, currentOrder: order }));
|
||||
}, []);
|
||||
|
||||
const setPagination = useCallback((pagination: OrderState['pagination']) => {
|
||||
setState(prev => ({ ...prev, pagination }));
|
||||
}, []);
|
||||
|
||||
const updateOrderStatus = useCallback((orderId: string, status: Order['status']) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
orders: prev.orders.map(order =>
|
||||
order.id === orderId ? { ...order, status, updatedAt: new Date().toISOString() } : order
|
||||
),
|
||||
currentOrder: prev.currentOrder?.id === orderId
|
||||
? { ...prev.currentOrder, status, updatedAt: new Date().toISOString() }
|
||||
: prev.currentOrder,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return {
|
||||
...state,
|
||||
setOrders,
|
||||
setLoading,
|
||||
setError,
|
||||
setCurrentOrder,
|
||||
setPagination,
|
||||
updateOrderStatus,
|
||||
};
|
||||
};
|
||||
|
||||
export default useOrderModel;
|
||||
104
dashboard/src/models/product.ts
Normal file
104
dashboard/src/models/product.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
stock: number;
|
||||
category: string;
|
||||
status: 'active' | 'inactive';
|
||||
}
|
||||
|
||||
interface ProductState {
|
||||
products: Product[];
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
currentProduct: Product | null;
|
||||
pagination: {
|
||||
current: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
const useProductModel = () => {
|
||||
const [state, setState] = useState<ProductState>({
|
||||
products: [],
|
||||
loading: false,
|
||||
error: null,
|
||||
currentProduct: null,
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const setProducts = useCallback((products: Product[]) => {
|
||||
setState(prev => ({ ...prev, products }));
|
||||
}, []);
|
||||
|
||||
const setLoading = useCallback((loading: boolean) => {
|
||||
setState(prev => ({ ...prev, loading }));
|
||||
}, []);
|
||||
|
||||
const setError = useCallback((error: string | null) => {
|
||||
setState(prev => ({ ...prev, error }));
|
||||
}, []);
|
||||
|
||||
const setCurrentProduct = useCallback((product: Product | null) => {
|
||||
setState(prev => ({ ...prev, currentProduct: product }));
|
||||
}, []);
|
||||
|
||||
const setPagination = useCallback((pagination: ProductState['pagination']) => {
|
||||
setState(prev => ({ ...prev, pagination }));
|
||||
}, []);
|
||||
|
||||
const updateProduct = useCallback((updatedProduct: Product) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
products: prev.products.map(product =>
|
||||
product.id === updatedProduct.id ? updatedProduct : product
|
||||
),
|
||||
currentProduct: prev.currentProduct?.id === updatedProduct.id
|
||||
? updatedProduct
|
||||
: prev.currentProduct,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const addProduct = useCallback((newProduct: Product) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
products: [newProduct, ...prev.products],
|
||||
pagination: {
|
||||
...prev.pagination,
|
||||
total: prev.pagination.total + 1,
|
||||
},
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const deleteProduct = useCallback((productId: string) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
products: prev.products.filter(product => product.id !== productId),
|
||||
pagination: {
|
||||
...prev.pagination,
|
||||
total: prev.pagination.total - 1,
|
||||
},
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return {
|
||||
...state,
|
||||
setProducts,
|
||||
setLoading,
|
||||
setError,
|
||||
setCurrentProduct,
|
||||
setPagination,
|
||||
updateProduct,
|
||||
addProduct,
|
||||
deleteProduct,
|
||||
};
|
||||
};
|
||||
|
||||
export default useProductModel;
|
||||
Reference in New Issue
Block a user