Files
mkd/services/storageService.ts
2026-02-04 00:17:04 +05:00

273 lines
9.8 KiB
TypeScript
Executable File

import { Building, District } from "../types";
import { MOCK_BUILDINGS, MOCK_DISTRICTS } from "../constants";
const DB_KEY_BUILDINGS = 'mkd_buildings_v2';
const DB_KEY_DISTRICTS = 'mkd_districts_v2';
const DB_KEY_GLOBAL_PASSPORT_FIELDS = 'mkd_global_passport_fields';
export const storageService = {
// --- DISTRICTS ---
getDistricts: (): District[] => {
try {
const stored = localStorage.getItem(DB_KEY_DISTRICTS);
if (stored) {
const parsed = JSON.parse(stored);
return Array.isArray(parsed) ? parsed : [];
}
return [];
} catch (e) {
return [];
}
},
saveDistrict: (district: District): void => {
const all = storageService.getDistricts();
const index = all.findIndex(d => d.id === district.id);
let newAll;
if (index >= 0) {
newAll = [...all];
newAll[index] = district;
} else {
newAll = [...all, district];
}
localStorage.setItem(DB_KEY_DISTRICTS, JSON.stringify(newAll));
},
createDistrict: (data: Omit<District, 'id'>): District => {
const newDistrict: District = {
...data,
id: `d-${Date.now()}`
};
storageService.saveDistrict(newDistrict);
return newDistrict;
},
deleteDistrict: (id: string): void => {
const all = storageService.getDistricts();
const newAll = all.filter(d => d.id !== id);
localStorage.setItem(DB_KEY_DISTRICTS, JSON.stringify(newAll));
},
// --- BUILDINGS ---
getAllBuildings: (): Building[] => {
try {
const stored = localStorage.getItem(DB_KEY_BUILDINGS);
if (stored) {
const parsed = JSON.parse(stored);
return Array.isArray(parsed) ? parsed : [];
}
return [];
} catch (e) {
return [];
}
},
getBuildingsByDistrict: (districtId: string): Building[] => {
const all = storageService.getAllBuildings();
return all.filter(b => b.districtId === districtId);
},
getBuildingById: (id: string): Building | undefined => {
const all = storageService.getAllBuildings();
return all.find(b => b.id === id);
},
saveBuildingData: (updatedBuilding: Building): void => {
try {
const all = storageService.getAllBuildings();
const index = all.findIndex(b => b.id === updatedBuilding.id);
const toSave = {
...updatedBuilding,
isDirty: true,
lastSync: Date.now()
};
let newAll;
if (index >= 0) {
newAll = [...all];
newAll[index] = toSave;
} else {
newAll = [...all, toSave];
}
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(newAll));
} catch (e) {
console.error("Failed to save to storage", e);
}
},
createBuilding: (data: Partial<Building> & { address: string, districtId: string }): Building => {
const id = `b-${Date.now()}`;
const newBuilding: Building = {
id,
districtId: data.districtId,
imageUrl: data.imageUrl || 'https://picsum.photos/800/600',
nps: 0,
passport: {
address: data.address,
apartmentsCount: 0,
general: {
address: data.address,
fiasCode: '',
constructionYear: new Date().getFullYear(),
commissionYear: new Date().getFullYear(),
seriesType: 'Индивидуальный',
floors: 1,
undergroundFloors: 0,
totalArea: 0,
livingArea: 0,
nonLivingArea: 0,
commonArea: 0,
cadastralNumberBuild: '',
cadastralNumberLand: ''
},
construction: { foundationType: '', foundationMaterial: '', wallMaterial: '', floorMaterial: '', roofType: '', roofMaterial: '', roofArea: 0, facadeType: '', facadeInsulation: false, windowType: '' },
engineering: { heatingType: '', heatingWiring: '', hasITP: false, waterSupplyMaterial: '', waterSupplyType: '', sewerMaterial: '', electricityEntries: 1, hasVRU: false, gasType: '', ventilationType: '' },
odpu: { customFields: {} },
meters: [],
lifts: [],
land: { area: 0, hasPlayground: false, hasSportsGround: false, hasParking: false, hasFencing: false, hasContainerSite: false },
management: {
contractDate: '',
contractNumber: '',
servicesList: [],
tariffMaintenance: 0,
reserveFund: 5.00, // Значение по умолчанию 5%
serviceContracts: [] // Initialize empty array
},
...data.passport
},
staff: [],
entrances: [],
commonSections: [],
accounts: [],
financials: { balance: 0, debt: 0, collectionRate: 0, topDebtors: [], invoices: [] },
requests: { new: 0, inProgress: 0, overdue: 0 },
inspectionHistory: [],
tasks: [],
annualPlan: [],
inventory: [],
writeOffHistory: [],
residents: [],
reports: [],
isDirty: true,
...data
};
storageService.saveBuildingData(newBuilding);
return newBuilding;
},
deleteBuilding: (id: string): void => {
const all = storageService.getAllBuildings();
const newAll = all.filter(b => b.id !== id);
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(newAll));
},
syncWithServer: async (): Promise<boolean> => {
return new Promise((resolve) => {
setTimeout(() => {
const all = storageService.getAllBuildings();
const cleaned = all.map(b => ({ ...b, isDirty: false }));
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(cleaned));
resolve(true);
}, 1500);
});
},
clearLocal: () => {
localStorage.removeItem(DB_KEY_BUILDINGS);
localStorage.removeItem(DB_KEY_DISTRICTS);
},
// --- GLOBAL PASSPORT FIELDS (для всех домов) ---
getGlobalPassportFields: (): { [section: string]: { [fieldName: string]: { value: any; type: string; files?: string[] } } } => {
try {
const stored = localStorage.getItem(DB_KEY_GLOBAL_PASSPORT_FIELDS);
if (stored) return JSON.parse(stored);
return {};
} catch (e) {
return {};
}
},
saveGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string, fieldType: 'text' | 'number' | 'checkbox'): void => {
const globalFields = storageService.getGlobalPassportFields();
if (!globalFields[section]) {
globalFields[section] = {};
}
const defaultValue = fieldType === 'number' ? 0 : fieldType === 'checkbox' ? false : '';
globalFields[section][fieldName] = {
value: defaultValue,
type: fieldType,
files: []
};
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
// Применяем это поле ко всем домам
const allBuildings = storageService.getAllBuildings();
allBuildings.forEach(building => {
const sectionData = building.passport[section] as any;
const customFields = { ...(sectionData.customFields || {}) };
if (!customFields[fieldName]) {
customFields[fieldName] = {
value: defaultValue,
type: fieldType,
files: []
};
const updatedSection = { ...sectionData, customFields };
building.passport[section] = updatedSection as any;
}
});
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
},
updateGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string, value: any, files?: string[]): void => {
const globalFields = storageService.getGlobalPassportFields();
if (globalFields[section] && globalFields[section][fieldName]) {
globalFields[section][fieldName].value = value;
if (files !== undefined) {
globalFields[section][fieldName].files = files;
}
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
// Обновляем это поле во всех домах
const allBuildings = storageService.getAllBuildings();
allBuildings.forEach(building => {
const sectionData = building.passport[section] as any;
const customFields = { ...(sectionData.customFields || {}) };
if (customFields[fieldName]) {
customFields[fieldName].value = value;
if (files !== undefined) {
customFields[fieldName].files = files;
}
const updatedSection = { ...sectionData, customFields };
building.passport[section] = updatedSection as any;
}
});
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
}
},
deleteGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string): void => {
const globalFields = storageService.getGlobalPassportFields();
if (globalFields[section] && globalFields[section][fieldName]) {
delete globalFields[section][fieldName];
if (Object.keys(globalFields[section]).length === 0) {
delete globalFields[section];
}
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
// Удаляем это поле из всех домов
const allBuildings = storageService.getAllBuildings();
allBuildings.forEach(building => {
const sectionData = building.passport[section] as any;
const customFields = { ...(sectionData.customFields || {}) };
if (customFields[fieldName]) {
delete customFields[fieldName];
const updatedSection = { ...sectionData, customFields };
building.passport[section] = updatedSection as any;
}
});
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
}
}
};