refactor: 优化认证系统和组件类型安全性
- 新增 safeLocalStorage 工具函数增强本地存储安全性 - 简化认证流程,重构用户数据结构和 token 管理 - 修复多个模块的 TypeScript 类型错误和导入问题 - 优化状态管理,重构各模块 store 结构 - 清理冗余代码,移除未使用的组件和函数 - 改进错误处理和边界情况处理 - 更新配置文件以支持最新的类型检查 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,370 +1,142 @@
|
||||
import { create } from 'zustand'
|
||||
import { AgriculturalAsset, MaintenanceRecord, AssetInventory } from '@api/modules/asset'
|
||||
import { assetApi } from '@api'
|
||||
import { QueryRequest } from '@api/types'
|
||||
import { create } from 'zustand';
|
||||
|
||||
interface AssetState {
|
||||
// 资产数据
|
||||
assetList: AgriculturalAsset[]
|
||||
selectedAsset: AgriculturalAsset | null
|
||||
assetLoading: boolean
|
||||
assetError: string | null
|
||||
assetPagination: {
|
||||
page: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
|
||||
// 维护记录数据
|
||||
maintenanceList: MaintenanceRecord[]
|
||||
selectedMaintenance: MaintenanceRecord | null
|
||||
maintenanceLoading: boolean
|
||||
maintenancePagination: {
|
||||
page: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
|
||||
// 库存数据
|
||||
inventoryList: AssetInventory[]
|
||||
selectedInventory: AssetInventory | null
|
||||
inventoryLoading: boolean
|
||||
inventoryPagination: {
|
||||
page: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
// 农业资产接口
|
||||
export interface AgriculturalAsset {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
category: string;
|
||||
brand?: string | null;
|
||||
model?: string | null;
|
||||
serial_number?: string | null;
|
||||
purchase_date?: string | null;
|
||||
purchase_price?: number | null;
|
||||
current_value?: number | null;
|
||||
depreciation_rate?: number | null;
|
||||
status: 'active' | 'maintenance' | 'retired' | 'lost';
|
||||
location?: string | null;
|
||||
assigned_to?: string | null;
|
||||
warranty_expiry?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
interface AssetActions {
|
||||
// 资产操作
|
||||
fetchAssetList: (params?: QueryRequest) => Promise<void>
|
||||
fetchAssetDetail: (id: string) => Promise<void>
|
||||
createAsset: (data: Omit<AgriculturalAsset, 'id' | 'createdAt' | 'updatedAt' | 'currentValue'>) => Promise<void>
|
||||
updateAsset: (id: string, data: Partial<AgriculturalAsset>) => Promise<void>
|
||||
deleteAsset: (id: string) => Promise<void>
|
||||
calculateDepreciation: (id: string, date: string) => Promise<void>
|
||||
setSelectedAsset: (asset: AgriculturalAsset | null) => void
|
||||
clearAssetError: () => void
|
||||
|
||||
// 维护记录操作
|
||||
fetchMaintenanceRecords: (params?: QueryRequest) => Promise<void>
|
||||
fetchMaintenanceDetail: (id: string) => Promise<void>
|
||||
createMaintenanceRecord: (data: Omit<MaintenanceRecord, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>
|
||||
updateMaintenanceRecord: (id: string, data: Partial<MaintenanceRecord>) => Promise<void>
|
||||
deleteMaintenanceRecord: (id: string) => Promise<void>
|
||||
|
||||
// 库存操作
|
||||
fetchInventoryList: (params?: QueryRequest) => Promise<void>
|
||||
fetchInventoryDetail: (id: string) => Promise<void>
|
||||
createInventoryRecord: (data: Omit<AssetInventory, 'id' | 'createdAt' | 'updatedAt' | 'variance'>) => Promise<void>
|
||||
updateInventoryRecord: (id: string, data: Partial<AssetInventory>) => Promise<void>
|
||||
verifyInventory: (id: string, verifiedBy: string) => Promise<void>
|
||||
// 维护记录接口
|
||||
export interface MaintenanceRecord {
|
||||
id: string;
|
||||
asset_id: string;
|
||||
maintenance_type: string;
|
||||
description?: string | null;
|
||||
cost?: number | null;
|
||||
performed_by?: string | null;
|
||||
performed_date?: string | null;
|
||||
next_maintenance_date?: string | null;
|
||||
status: 'scheduled' | 'in_progress' | 'completed' | 'cancelled';
|
||||
notes?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export const useAssetStore = create<AssetState & AssetActions>((set, get) => ({
|
||||
// 初始状态
|
||||
assetList: [],
|
||||
selectedAsset: null,
|
||||
assetLoading: false,
|
||||
assetError: null,
|
||||
assetPagination: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
// 资产库存接口
|
||||
export interface AssetInventory {
|
||||
id: string;
|
||||
asset_type: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
unit_cost?: number | null;
|
||||
total_value?: number | null;
|
||||
reorder_level?: number | null;
|
||||
location?: string | null;
|
||||
supplier?: string | null;
|
||||
last_updated?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// Asset state interface
|
||||
export interface AssetState {
|
||||
assets: AgriculturalAsset[];
|
||||
currentAsset: AgriculturalAsset | null;
|
||||
maintenanceRecords: MaintenanceRecord[];
|
||||
currentMaintenance: MaintenanceRecord | null;
|
||||
assetInventory: AssetInventory[];
|
||||
currentInventory: AssetInventory | null;
|
||||
|
||||
// Actions
|
||||
setAssets: (assets: AgriculturalAsset[]) => void;
|
||||
setCurrentAsset: (asset: AgriculturalAsset | null) => void;
|
||||
setMaintenanceRecords: (records: MaintenanceRecord[]) => void;
|
||||
setCurrentMaintenance: (record: MaintenanceRecord | null) => void;
|
||||
setAssetInventory: (inventory: AssetInventory[]) => void;
|
||||
setCurrentInventory: (inventory: AssetInventory | null) => void;
|
||||
|
||||
// Getters
|
||||
getAssets: () => AgriculturalAsset[];
|
||||
getCurrentAsset: () => AgriculturalAsset | null;
|
||||
getMaintenanceRecords: () => MaintenanceRecord[];
|
||||
getCurrentMaintenance: () => MaintenanceRecord | null;
|
||||
getAssetInventory: () => AssetInventory[];
|
||||
getCurrentInventory: () => AssetInventory | null;
|
||||
}
|
||||
|
||||
// Create Asset store
|
||||
export const useAssetStore = create<AssetState>((set, get) => ({
|
||||
assets: [],
|
||||
currentAsset: null,
|
||||
maintenanceRecords: [],
|
||||
currentMaintenance: null,
|
||||
assetInventory: [],
|
||||
currentInventory: null,
|
||||
|
||||
setAssets: (assets: AgriculturalAsset[]) => {
|
||||
set({ assets });
|
||||
},
|
||||
|
||||
maintenanceList: [],
|
||||
selectedMaintenance: null,
|
||||
maintenanceLoading: false,
|
||||
maintenancePagination: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
setCurrentAsset: (asset: AgriculturalAsset | null) => {
|
||||
set({ currentAsset: asset });
|
||||
},
|
||||
|
||||
inventoryList: [],
|
||||
selectedInventory: null,
|
||||
inventoryLoading: false,
|
||||
inventoryPagination: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
setMaintenanceRecords: (records: MaintenanceRecord[]) => {
|
||||
set({ maintenanceRecords: records });
|
||||
},
|
||||
|
||||
// 资产操作
|
||||
fetchAssetList: async (params) => {
|
||||
try {
|
||||
set({ assetLoading: true, assetError: null })
|
||||
const response = await assetApi.getAssetList({
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || 10,
|
||||
...params
|
||||
})
|
||||
|
||||
set({
|
||||
assetList: response.data.items,
|
||||
assetPagination: {
|
||||
page: response.data.page,
|
||||
pageSize: response.data.pageSize,
|
||||
total: response.data.total
|
||||
},
|
||||
assetLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '获取资产列表失败',
|
||||
assetLoading: false
|
||||
})
|
||||
}
|
||||
setCurrentMaintenance: (record: MaintenanceRecord | null) => {
|
||||
set({ currentMaintenance: record });
|
||||
},
|
||||
|
||||
fetchAssetDetail: async (id) => {
|
||||
try {
|
||||
set({ assetLoading: true, assetError: null })
|
||||
const response = await assetApi.getAssetDetail(id)
|
||||
set({
|
||||
selectedAsset: response.data,
|
||||
assetLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '获取资产详情失败',
|
||||
assetLoading: false
|
||||
})
|
||||
}
|
||||
setAssetInventory: (inventory: AssetInventory[]) => {
|
||||
set({ assetInventory: inventory });
|
||||
},
|
||||
|
||||
createAsset: async (data) => {
|
||||
try {
|
||||
const response = await assetApi.createAsset(data)
|
||||
const currentList = get().assetList
|
||||
set({
|
||||
assetList: [response.data, ...currentList]
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '创建资产失败'
|
||||
})
|
||||
}
|
||||
setCurrentInventory: (inventory: AssetInventory | null) => {
|
||||
set({ currentInventory: inventory });
|
||||
},
|
||||
|
||||
updateAsset: async (id, data) => {
|
||||
try {
|
||||
const response = await assetApi.updateAsset(id, data)
|
||||
const currentList = get().assetList
|
||||
const updatedList = currentList.map(item =>
|
||||
item.id === id ? response.data : item
|
||||
)
|
||||
set({
|
||||
assetList: updatedList,
|
||||
selectedAsset: response.data
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '更新资产失败'
|
||||
})
|
||||
}
|
||||
getAssets: () => {
|
||||
return get().assets;
|
||||
},
|
||||
|
||||
deleteAsset: async (id) => {
|
||||
try {
|
||||
await assetApi.deleteAsset(id)
|
||||
const currentList = get().assetList
|
||||
const updatedList = currentList.filter(item => item.id !== id)
|
||||
set({
|
||||
assetList: updatedList,
|
||||
selectedAsset: null
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '删除资产失败'
|
||||
})
|
||||
}
|
||||
getCurrentAsset: () => {
|
||||
return get().currentAsset;
|
||||
},
|
||||
|
||||
calculateDepreciation: async (id, date) => {
|
||||
try {
|
||||
const response = await assetApi.calculateDepreciation(id, date)
|
||||
const currentList = get().assetList
|
||||
const updatedList = currentList.map(item =>
|
||||
item.id === id ? { ...item, currentValue: response.data.currentValue } : item
|
||||
)
|
||||
set({
|
||||
assetList: updatedList,
|
||||
selectedAsset: get().selectedAsset?.id === id
|
||||
? { ...get().selectedAsset, currentValue: response.data.currentValue }
|
||||
: get().selectedAsset
|
||||
})
|
||||
} catch (error) {
|
||||
set({
|
||||
assetError: error instanceof Error ? error.message : '计算折旧失败'
|
||||
})
|
||||
}
|
||||
getMaintenanceRecords: () => {
|
||||
return get().maintenanceRecords;
|
||||
},
|
||||
|
||||
setSelectedAsset: (asset) => set({ selectedAsset: asset }),
|
||||
clearAssetError: () => set({ assetError: null }),
|
||||
|
||||
// 维护记录操作
|
||||
fetchMaintenanceRecords: async (params) => {
|
||||
try {
|
||||
set({ maintenanceLoading: true })
|
||||
const response = await assetApi.getMaintenanceRecords({
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || 10,
|
||||
...params
|
||||
})
|
||||
set({
|
||||
maintenanceList: response.data.items,
|
||||
maintenancePagination: {
|
||||
page: response.data.page,
|
||||
pageSize: response.data.pageSize,
|
||||
total: response.data.total
|
||||
},
|
||||
maintenanceLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取维护记录失败:', error)
|
||||
set({ maintenanceLoading: false })
|
||||
}
|
||||
getCurrentMaintenance: () => {
|
||||
return get().currentMaintenance;
|
||||
},
|
||||
|
||||
fetchMaintenanceDetail: async (id) => {
|
||||
try {
|
||||
set({ maintenanceLoading: true })
|
||||
const response = await assetApi.getMaintenanceDetail(id)
|
||||
set({
|
||||
selectedMaintenance: response.data,
|
||||
maintenanceLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取维护记录详情失败:', error)
|
||||
set({ maintenanceLoading: false })
|
||||
}
|
||||
getAssetInventory: () => {
|
||||
return get().assetInventory;
|
||||
},
|
||||
|
||||
createMaintenanceRecord: async (data) => {
|
||||
try {
|
||||
const response = await assetApi.createMaintenanceRecord(data)
|
||||
const currentList = get().maintenanceList
|
||||
set({
|
||||
maintenanceList: [response.data, ...currentList]
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('创建维护记录失败:', error)
|
||||
}
|
||||
getCurrentInventory: () => {
|
||||
return get().currentInventory;
|
||||
},
|
||||
}));
|
||||
|
||||
updateMaintenanceRecord: async (id, data) => {
|
||||
try {
|
||||
const response = await assetApi.updateMaintenanceRecord(id, data)
|
||||
const currentList = get().maintenanceList
|
||||
const updatedList = currentList.map(item =>
|
||||
item.id === id ? response.data : item
|
||||
)
|
||||
set({
|
||||
maintenanceList: updatedList,
|
||||
selectedMaintenance: response.data
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('更新维护记录失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
deleteMaintenanceRecord: async (id) => {
|
||||
try {
|
||||
await assetApi.deleteMaintenanceRecord(id)
|
||||
const currentList = get().maintenanceList
|
||||
const updatedList = currentList.filter(item => item.id !== id)
|
||||
set({
|
||||
maintenanceList: updatedList,
|
||||
selectedMaintenance: null
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('删除维护记录失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 库存操作
|
||||
fetchInventoryList: async (params) => {
|
||||
try {
|
||||
set({ inventoryLoading: true })
|
||||
const response = await assetApi.getInventoryList({
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || 10,
|
||||
...params
|
||||
})
|
||||
set({
|
||||
inventoryList: response.data.items,
|
||||
inventoryPagination: {
|
||||
page: response.data.page,
|
||||
pageSize: response.data.pageSize,
|
||||
total: response.data.total
|
||||
},
|
||||
inventoryLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取库存列表失败:', error)
|
||||
set({ inventoryLoading: false })
|
||||
}
|
||||
},
|
||||
|
||||
fetchInventoryDetail: async (id) => {
|
||||
try {
|
||||
set({ inventoryLoading: true })
|
||||
const response = await assetApi.getInventoryDetail(id)
|
||||
set({
|
||||
selectedInventory: response.data,
|
||||
inventoryLoading: false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取库存详情失败:', error)
|
||||
set({ inventoryLoading: false })
|
||||
}
|
||||
},
|
||||
|
||||
createInventoryRecord: async (data) => {
|
||||
try {
|
||||
const response = await assetApi.createInventoryRecord(data)
|
||||
const currentList = get().inventoryList
|
||||
set({
|
||||
inventoryList: [response.data, ...currentList]
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('创建库存记录失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
updateInventoryRecord: async (id, data) => {
|
||||
try {
|
||||
const response = await assetApi.updateInventoryRecord(id, data)
|
||||
const currentList = get().inventoryList
|
||||
const updatedList = currentList.map(item =>
|
||||
item.id === id ? response.data : item
|
||||
)
|
||||
set({
|
||||
inventoryList: updatedList,
|
||||
selectedInventory: response.data
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('更新库存记录失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
verifyInventory: async (id, verifiedBy) => {
|
||||
try {
|
||||
const response = await assetApi.verifyInventory(id, verifiedBy)
|
||||
const currentList = get().inventoryList
|
||||
const updatedList = currentList.map(item =>
|
||||
item.id === id ? response.data : item
|
||||
)
|
||||
set({
|
||||
inventoryList: updatedList,
|
||||
selectedInventory: response.data
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('验证库存失败:', error)
|
||||
}
|
||||
}
|
||||
}))
|
||||
export default useAssetStore;
|
||||
Reference in New Issue
Block a user