Both pages had toolbar buttons with no onClick handler. Added modal forms: - Checks: date + checker + optional detail rows (product + actual qty) - Adjusts: date + reason + required detail rows (product + adjust qty, negative to decrease) Also updated createStockCheck and createStockAdjust API function signatures from Partial<StockCheck/Adjust> to explicit typed request shapes. Fixed a go-zero validation bug: non-optional fields (checker, adjustReason) must be present in the JSON body; antd Form returns undefined for untouched inputs which JSON.stringify omits, causing 400. Solved by setting default empty strings in Form initialValues.
346 lines
16 KiB
TypeScript
346 lines
16 KiB
TypeScript
import { request } from '@umijs/max';
|
|
import type {
|
|
ApiResponse,
|
|
BoltInfo,
|
|
ColorDetailItem,
|
|
CurrentUser,
|
|
InventoryLog,
|
|
LoginParams,
|
|
LoginResult,
|
|
Menu,
|
|
OperationLog,
|
|
PaginatedData,
|
|
PaginationParams,
|
|
PanInfo,
|
|
PanInput,
|
|
Product,
|
|
ProductSummaryItem,
|
|
ProductTree,
|
|
PurchaseOrder,
|
|
PurchasePayment,
|
|
PurchaseReceipt,
|
|
PurchaseStatsByProductItem,
|
|
PurchaseStatsBySupplierItem,
|
|
PurchaseStatsSummary,
|
|
Relation,
|
|
RelationHistory,
|
|
Role,
|
|
StockAdjust,
|
|
StockCheck,
|
|
StockGroup,
|
|
StockSummary,
|
|
Supplier,
|
|
SystemConfig,
|
|
User,
|
|
} from '@/types/api';
|
|
|
|
// ── Auth ──────────────────────────────────────────
|
|
|
|
export const login = (data: LoginParams) =>
|
|
request<ApiResponse<LoginResult>>('/api/v1/auth/login', { method: 'POST', data });
|
|
|
|
export const logout = () =>
|
|
request<ApiResponse>('/api/v1/auth/logout', { method: 'POST' });
|
|
|
|
export const getUserInfo = () =>
|
|
request<ApiResponse<CurrentUser>>('/api/v1/auth/info', { method: 'GET' });
|
|
|
|
export const changePassword = (data: { oldPassword: string; newPassword: string }) =>
|
|
request<ApiResponse>('/api/v1/auth/password', { method: 'PUT', data });
|
|
|
|
// ── Users ─────────────────────────────────────────
|
|
|
|
export const listUsers = (params: PaginationParams & { username?: string; realName?: string }) =>
|
|
request<ApiResponse<PaginatedData<User>>>('/api/v1/system/users', { method: 'GET', params });
|
|
|
|
export const getUser = (id: string) =>
|
|
request<ApiResponse<User>>(`/api/v1/system/users/${id}`, { method: 'GET' });
|
|
|
|
export const createUser = (data: Partial<User> & { password?: string }) =>
|
|
request<ApiResponse>('/api/v1/system/users', { method: 'POST', data });
|
|
|
|
export const updateUser = (id: string, data: Partial<User>) =>
|
|
request<ApiResponse>(`/api/v1/system/users/${id}`, { method: 'PUT', data });
|
|
|
|
export const deleteUser = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/system/users/${id}`, { method: 'DELETE' });
|
|
|
|
export const updateUserStatus = (id: string, status: number) =>
|
|
request<ApiResponse>(`/api/v1/system/users/${id}/status`, { method: 'PUT', data: { status } });
|
|
|
|
// ── Roles ─────────────────────────────────────────
|
|
|
|
export const listRoles = (params?: PaginationParams & { roleName?: string }) =>
|
|
request<ApiResponse<PaginatedData<Role>>>('/api/v1/system/roles', { method: 'GET', params });
|
|
|
|
export const createRole = (data: Partial<Role>) =>
|
|
request<ApiResponse>('/api/v1/system/roles', { method: 'POST', data });
|
|
|
|
export const updateRole = (id: string, data: Partial<Role>) =>
|
|
request<ApiResponse>(`/api/v1/system/roles/${id}`, { method: 'PUT', data });
|
|
|
|
export const deleteRole = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/system/roles/${id}`, { method: 'DELETE' });
|
|
|
|
export const setRolePermissions = (id: string, menuIds: string[]) =>
|
|
request<ApiResponse>(`/api/v1/system/roles/${id}/permissions`, { method: 'PUT', data: { menuIds } });
|
|
|
|
// ── Menus ─────────────────────────────────────────
|
|
|
|
export const listMenus = () =>
|
|
request<ApiResponse<PaginatedData<Menu>>>('/api/v1/system/menus', { method: 'GET' });
|
|
|
|
export const createMenu = (data: Partial<Menu>) =>
|
|
request<ApiResponse>('/api/v1/system/menus', { method: 'POST', data });
|
|
|
|
export const updateMenu = (id: string, data: Partial<Menu>) =>
|
|
request<ApiResponse>(`/api/v1/system/menus/${id}`, { method: 'PUT', data });
|
|
|
|
export const deleteMenu = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/system/menus/${id}`, { method: 'DELETE' });
|
|
|
|
// ── Logs ──────────────────────────────────────────
|
|
|
|
export const listLogs = (params: PaginationParams & { username?: string; module?: string; operation?: string }) =>
|
|
request<ApiResponse<PaginatedData<OperationLog>>>('/api/v1/system/logs', { method: 'GET', params });
|
|
|
|
// ── Configs ───────────────────────────────────────
|
|
|
|
export const listConfigs = () =>
|
|
request<ApiResponse<PaginatedData<SystemConfig>>>('/api/v1/system/configs', { method: 'GET' });
|
|
|
|
export const updateConfig = (key: string, value: string) =>
|
|
request<ApiResponse>(`/api/v1/system/configs/${key}`, { method: 'PUT', data: { configValue: value } });
|
|
|
|
// ── Products ──────────────────────────────────────
|
|
|
|
export const listProducts = (params: PaginationParams & { productName?: string; spec?: string; color?: string }) =>
|
|
request<ApiResponse<PaginatedData<Product>>>('/api/v1/inventory/products', { method: 'GET', params });
|
|
|
|
export const getProduct = (id: string) =>
|
|
request<ApiResponse<Product>>(`/api/v1/inventory/products/${id}`, { method: 'GET' });
|
|
|
|
export const createProduct = (data: Partial<Product> & { pans?: PanInput[] }) =>
|
|
request<ApiResponse>('/api/v1/inventory/products', { method: 'POST', data });
|
|
|
|
export const updateProduct = (id: string, data: Partial<Product>) =>
|
|
request<ApiResponse>(`/api/v1/inventory/products/${id}`, { method: 'PUT', data });
|
|
|
|
export const deleteProduct = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/inventory/products/${id}`, { method: 'DELETE' });
|
|
|
|
export const exportProducts = () =>
|
|
request('/api/v1/inventory/products/export', { method: 'GET', responseType: 'blob' });
|
|
|
|
// ── Product Panels ────────────────────────────────
|
|
|
|
export const getProductSummary = () =>
|
|
request<ApiResponse<{ list: ProductSummaryItem[] }>>('/api/v1/inventory/products/summary', { method: 'GET' });
|
|
|
|
export const getColorDetail = (productName: string) =>
|
|
request<ApiResponse<{ list: ColorDetailItem[] }>>('/api/v1/inventory/products/colors', { method: 'GET', params: { productName } });
|
|
|
|
export const getProductTree = (id: string) =>
|
|
request<ApiResponse<ProductTree>>(`/api/v1/inventory/products/${id}/tree`, { method: 'GET' });
|
|
|
|
// ── Pan / Bolt CRUD ───────────────────────────────
|
|
|
|
export const listPans = (productId: string) =>
|
|
request<ApiResponse<{ list: PanInfo[] }>>(`/api/v1/inventory/products/${productId}/pans`, { method: 'GET' });
|
|
|
|
export const savePans = (productId: string, pans: PanInput[]) =>
|
|
request<ApiResponse>(`/api/v1/inventory/products/${productId}/pans`, { method: 'PUT', data: { pans } });
|
|
|
|
export const listBolts = (panId: string) =>
|
|
request<ApiResponse<{ list: BoltInfo[] }>>(`/api/v1/inventory/pans/${panId}/bolts`, { method: 'GET' });
|
|
|
|
export const saveBolts = (panId: string, lengths: string[]) =>
|
|
request<ApiResponse>(`/api/v1/inventory/pans/${panId}/bolts`, { method: 'PUT', data: { lengths } });
|
|
|
|
// ── Pan / Bolt dimension panels ───────────────────
|
|
|
|
export const listPanView = (params: {
|
|
page?: number;
|
|
pageSize?: number;
|
|
productName?: string;
|
|
position?: string;
|
|
}) =>
|
|
request<ApiResponse<{ total: number; list: import('@/types/api').PanListItem[] }>>(
|
|
'/api/v1/inventory/pans',
|
|
{ method: 'GET', params },
|
|
);
|
|
|
|
export const listBoltView = (params: {
|
|
page?: number;
|
|
pageSize?: number;
|
|
productName?: string;
|
|
position?: string;
|
|
}) =>
|
|
request<ApiResponse<{ total: number; list: import('@/types/api').BoltListItem[] }>>(
|
|
'/api/v1/inventory/bolts',
|
|
{ method: 'GET', params },
|
|
);
|
|
|
|
// ── Stocks ────────────────────────────────────────
|
|
|
|
export const getStockSummary = () =>
|
|
request<ApiResponse<StockSummary>>('/api/v1/inventory/stocks/summary', { method: 'GET' });
|
|
|
|
export const getStockByColor = () =>
|
|
request<ApiResponse<PaginatedData<StockGroup>>>('/api/v1/inventory/stocks/by-color', { method: 'GET' });
|
|
|
|
export const getStockByLocation = () =>
|
|
request<ApiResponse<PaginatedData<StockGroup>>>('/api/v1/inventory/stocks/by-location', { method: 'GET' });
|
|
|
|
// ── Stock Checks ──────────────────────────────────
|
|
|
|
export const listStockChecks = (params: PaginationParams) =>
|
|
request<ApiResponse<PaginatedData<StockCheck>>>('/api/v1/inventory/checks', { method: 'GET', params });
|
|
|
|
export const getStockCheck = (id: string) =>
|
|
request<ApiResponse<StockCheck>>(`/api/v1/inventory/checks/${id}`, { method: 'GET' });
|
|
|
|
export const createStockCheck = (data: {
|
|
checkDate: string;
|
|
checker?: string;
|
|
remark?: string;
|
|
details?: Array<{ productId: string; actualQuantity: string; remark?: string }>;
|
|
}) => request<ApiResponse<{ id: string }>>('/api/v1/inventory/checks', { method: 'POST', data });
|
|
|
|
export const confirmStockCheck = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/inventory/checks/${id}/confirm`, { method: 'POST' });
|
|
|
|
// ── Stock Adjusts ─────────────────────────────────
|
|
|
|
export const listStockAdjusts = (params: PaginationParams) =>
|
|
request<ApiResponse<PaginatedData<StockAdjust>>>('/api/v1/inventory/adjusts', { method: 'GET', params });
|
|
|
|
export const getStockAdjust = (id: string) =>
|
|
request<ApiResponse<StockAdjust>>(`/api/v1/inventory/adjusts/${id}`, { method: 'GET' });
|
|
|
|
export const createStockAdjust = (data: {
|
|
adjustDate: string;
|
|
adjustReason?: string;
|
|
remark?: string;
|
|
details?: Array<{ productId: string; adjustQuantity: string; remark?: string }>;
|
|
}) => request<ApiResponse<{ id: string }>>('/api/v1/inventory/adjusts', { method: 'POST', data });
|
|
|
|
export const approveStockAdjust = (id: string, action: number) =>
|
|
request<ApiResponse>(`/api/v1/inventory/adjusts/${id}/approve`, { method: 'POST', data: { action } });
|
|
|
|
// ── CRM Relations ─────────────────────────────────
|
|
|
|
export const listUpstream = (depth = 1) =>
|
|
request<ApiResponse<PaginatedData<Relation>>>('/api/v1/crm/graph/upstream', { method: 'GET', params: { depth } });
|
|
|
|
export const listDownstream = (depth = 1) =>
|
|
request<ApiResponse<PaginatedData<Relation>>>('/api/v1/crm/graph/downstream', { method: 'GET', params: { depth } });
|
|
|
|
export const createRelation = (data: {
|
|
fromTenantId: string;
|
|
toTenantId: string;
|
|
relationType: string;
|
|
validFrom?: string;
|
|
validTo?: string;
|
|
}) =>
|
|
request<ApiResponse>('/api/v1/crm/relationships', { method: 'POST', data });
|
|
|
|
export const updateRelation = (id: string, data: { status: number; validFrom?: string; validTo?: string }) =>
|
|
request<ApiResponse>(`/api/v1/crm/relationships/${id}`, { method: 'PUT', data });
|
|
|
|
export const listRelationHistory = (params?: PaginationParams) =>
|
|
request<ApiResponse<PaginatedData<RelationHistory>>>('/api/v1/crm/relationships/history', { method: 'GET', params });
|
|
|
|
// ── Suppliers ─────────────────────────────────────
|
|
|
|
export const listSuppliers = (params: PaginationParams & { supplierName?: string; status?: number }) =>
|
|
request<ApiResponse<PaginatedData<Supplier>>>('/api/v1/purchase/suppliers', { method: 'GET', params });
|
|
|
|
export const getSupplier = (id: string) =>
|
|
request<ApiResponse<Supplier>>(`/api/v1/purchase/suppliers/${id}`, { method: 'GET' });
|
|
|
|
export const createSupplier = (data: { supplierName: string; phone?: string; remark?: string }) =>
|
|
request<ApiResponse<{ id: string }>>('/api/v1/purchase/suppliers', { method: 'POST', data });
|
|
|
|
export const updateSupplier = (id: string, data: { supplierName?: string; phone?: string; status?: number; remark?: string }) =>
|
|
request<ApiResponse>(`/api/v1/purchase/suppliers/${id}`, { method: 'PUT', data });
|
|
|
|
export const deleteSupplier = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/purchase/suppliers/${id}`, { method: 'DELETE' });
|
|
|
|
// ── Purchase Orders ───────────────────────────────
|
|
|
|
export const listPurchaseOrders = (params: PaginationParams & { supplierId?: string; status?: number; startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<PaginatedData<PurchaseOrder>>>('/api/v1/purchase/orders', { method: 'GET', params });
|
|
|
|
export const getPurchaseOrder = (id: string) =>
|
|
request<ApiResponse<PurchaseOrder>>(`/api/v1/purchase/orders/${id}`, { method: 'GET' });
|
|
|
|
export const createPurchaseOrder = (data: {
|
|
supplierId: string;
|
|
orderDate: string;
|
|
purchaseBy?: string;
|
|
remark?: string;
|
|
details: Array<{ productId: string; productName: string; spec?: string; color?: string; quantity: string; unitPrice: string; remark?: string }>;
|
|
}) =>
|
|
request<ApiResponse<{ id: string }>>('/api/v1/purchase/orders', { method: 'POST', data });
|
|
|
|
export const updatePurchaseOrder = (id: string, data: object) =>
|
|
request<ApiResponse>(`/api/v1/purchase/orders/${id}`, { method: 'PUT', data });
|
|
|
|
export const confirmPurchaseOrder = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/purchase/orders/${id}/confirm`, { method: 'POST' });
|
|
|
|
export const cancelPurchaseOrder = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/purchase/orders/${id}/cancel`, { method: 'POST' });
|
|
|
|
// ── Purchase Receipts ─────────────────────────────
|
|
|
|
export const listPurchaseReceipts = (params: PaginationParams & { orderId?: string; status?: number; startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<PaginatedData<PurchaseReceipt>>>('/api/v1/purchase/receipts', { method: 'GET', params });
|
|
|
|
export const getPurchaseReceipt = (id: string) =>
|
|
request<ApiResponse<PurchaseReceipt>>(`/api/v1/purchase/receipts/${id}`, { method: 'GET' });
|
|
|
|
export const createPurchaseReceipt = (data: {
|
|
orderId: string;
|
|
receiptDate: string;
|
|
receivedBy?: string;
|
|
remark?: string;
|
|
details: Array<{ orderDetailId: string; productId: string; actualQty: string; unitCost?: string; remark?: string }>;
|
|
}) =>
|
|
request<ApiResponse<{ id: string }>>('/api/v1/purchase/receipts', { method: 'POST', data });
|
|
|
|
export const confirmPurchaseReceipt = (id: string) =>
|
|
request<ApiResponse>(`/api/v1/purchase/receipts/${id}/confirm`, { method: 'POST' });
|
|
|
|
// ── Purchase Payments ─────────────────────────────
|
|
|
|
export const listPurchasePayments = (params: PaginationParams & { orderId?: string; startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<PaginatedData<PurchasePayment>>>('/api/v1/purchase/payments', { method: 'GET', params });
|
|
|
|
export const createPurchasePayment = (data: {
|
|
orderId: string;
|
|
paymentDate: string;
|
|
amount: string;
|
|
paymentMethod?: string;
|
|
remark?: string;
|
|
}) =>
|
|
request<ApiResponse<{ id: string }>>('/api/v1/purchase/payments', { method: 'POST', data });
|
|
|
|
// ── Purchase Stats ────────────────────────────────
|
|
|
|
export const getPurchaseStatsSummary = (params: { startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<PurchaseStatsSummary>>('/api/v1/purchase/stats/summary', { method: 'GET', params });
|
|
|
|
export const getPurchaseStatsBySupplier = (params: { startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<{ list: PurchaseStatsBySupplierItem[] }>>('/api/v1/purchase/stats/by-supplier', { method: 'GET', params });
|
|
|
|
export const getPurchaseStatsByProduct = (params: { startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<{ list: PurchaseStatsByProductItem[] }>>('/api/v1/purchase/stats/by-product', { method: 'GET', params });
|
|
|
|
// ── Inventory Logs ────────────────────────────────
|
|
|
|
export const listInventoryLogs = (params: PaginationParams & { productId?: string; changeType?: number; startDate?: string; endDate?: string }) =>
|
|
request<ApiResponse<PaginatedData<InventoryLog>>>('/api/v1/inventory/logs', { method: 'GET', params });
|