/* 文件路径: data/DataManager.js */
// 导入基础数据解析函数
function resolveDataReferences(data, rawData) {
if (!data || typeof data !== 'object') {
return data;
}
// 创建一个新对象,避免直接修改原始数据
const result = Array.isArray(data) ? [] : {};
for (const key in data) {
if (data.hasOwnProperty(key)) {
result[key] = resolveDataReference(data[key], rawData);
}
}
return result;
}
function resolveDataReference(value, rawData) {
if (!value || typeof value !== 'object') {
return value;
}
// 检查是否是引用对象(包含_id属性)
if (typeof value._id !== 'undefined') {
// 获取关联实体类型和ID
const id = value._id;
// 处理关联实体
if (value.entityType) {
const collectionName = `${value.entityType}s`;
const collection = rawData[collectionName];
if (collection && Array.isArray(collection)) {
// 查找关联实体
const referencedEntity = collection.find(item => item.id === id);
if (referencedEntity) {
return referencedEntity;
}
}
}
// 如果找不到关联实体,返回原始ID
return { id };
}
// 递归处理嵌套对象
if (Array.isArray(value)) {
return value.map(item => resolveDataReference(item, rawData));
} else {
const result = {};
for (const key in value) {
if (value.hasOwnProperty(key)) {
result[key] = resolveDataReference(value[key], rawData);
}
}
return result;
}
}
// 导入基础依赖
import { DataManagerCRUD } from './DataManagerCRUD.js';
import { TransactionApi } from './TransactionApi.js';
import { LazyLoader } from './LazyLoader.js';
/**
* DataManager主类 - 整合了所有功能模块,提供完整的数据管理能力
* 保持与原有接口的完全兼容性
*/
class DataManager extends DataManagerCRUD {
constructor(options = {}) {
super(options);
// 初始化事务API
this.Transaction = new TransactionApi(this);
}
// 以下是业务特定的方法和实体获取器
/**
* 动态生成实体数据获取方法
*/
generateEntityGetters() {
this.entityTypes.forEach(entityType => {
// 创建驼峰式命名的方法名
const getterName = `get${entityType.charAt(0).toUpperCase() + entityType.slice(1)}s`;
// 只有在方法不存在的情况下才创建
if (!this[getterName]) {
this[getterName] = () => this.getEntity(`${entityType}s`);
}
});
}
// 实体快捷获取方法
getDingdans() { return this.getEntity('dingdans'); }
getBancais() { return this.getEntity('bancais'); }
getChanpins() { return this.getEntity('chanpins'); }
getZujians() { return this.getEntity('zujians'); }
getKucuns() { return this.getEntity('kucuns'); }
getUsers() { return this.getEntity('users'); }
getCaizhis() { return this.getEntity('caizhis'); }
getMupis() { return this.getEntity('mupis'); }
getDingdanBancais() { return this.getEntity('dingdan_bancais'); }
getJinhuos() { return this.getEntity('jinhuos'); }
getChanpinZujians() { return this.getEntity('chanpin_zujians'); }
getDingdanChanpins() { return this.getEntity('dingdan_chanpins'); }
// 业务方法
getChanpinsForDingdan(dingdanId) {
const dingdan = this._rawData.dingdans?.find(d => d?.id == dingdanId);
if (!dingdan) return [];
return (dingdan.dingdan_chanpin_list || [])
.map(dc => dc.chanpin)
.filter(c => c);
}
getZujiansForChanpin(chanpinId) {
const chanpin = this._rawData.chanpins?.find(c => c?.id == chanpinId);
if (!chanpin) return [];
return (chanpin.chanpin_zujian_list || [])
.map(cz => cz.zujian)
.filter(z => z);
}
getShengchanXiaohaoRecords() {
return this._rawData.jinhuos?.filter(jinhuo =>
jinhuo.the_type_of_operation === 2 && jinhuo.shuliang < 0
) || [];
}
getShengchanStatistics() {
const today = new Date().toISOString().split('T')[0];
const thisMonth = new Date().toISOString().substring(0, 7);
const consumptionRecords = this.getShengchanXiaohaoRecords();
const todayConsumption = consumptionRecords
.filter(record => record.date && record.date.startsWith(today))
.reduce((sum, record) => sum + Math.abs(record.shuliang), 0);
const monthConsumption = consumptionRecords
.filter(record => record.date && record.date.startsWith(thisMonth))
.reduce((sum, record) => sum + Math.abs(record.shuliang), 0);
const pendingOrders = this._rawData.dingdans?.filter(dingdan =>
!dingdan.deleted && dingdan.zhuangtai !== '已完成'
).length || 0;
const lowStockCount = this._rawData.kucuns?.filter(kucun =>
!kucun.deleted && kucun.shuliang < 10
).length || 0;
return {
today_consumption: todayConsumption,
month_consumption: monthConsumption,
pending_orders: pendingOrders,
low_stock_count: lowStockCount,
total_records: consumptionRecords.length
};
}
}
export { DataManager };
================================================================================
/* 文件路径: data/DataManagerCore.js */
/**
* DataManager核心模块 - 包含核心初始化和配置管理
*/
import { LazyLoader } from './LazyLoader.js';
import { IndexedDBManager } from './IndexedDBManager.js';
import { TransactionApi } from './TransactionApi.js';
/**
* 解析数据引用
*/
export function resolveDataReferences(data, allData) {
if (!data || typeof data !== 'object') {
return data;
}
if (Array.isArray(data)) {
return data.map(item => resolveDataReferences(item, allData));
}
const result = { ...data };
for (const key in result) {
if (result.hasOwnProperty(key) && key.endsWith('_id')) {
const refKey = key.replace('_id', '');
const collectionName = refKey.endsWith('s') ? refKey : `${refKey}s`;
if (allData[collectionName] && result[key]) {
const referencedItem = allData[collectionName].find(item => item.id == result[key]);
if (referencedItem) {
result[refKey] = referencedItem;
}
}
}
if (result.hasOwnProperty(key) && typeof result[key] === 'object' && result[key] !== null) {
result[key] = resolveDataReferences(result[key], allData);
}
}
return result;
}
/**
* 解析单个数据引用
*/
export function resolveDataReference(id, collection) {
if (!id || !collection || !Array.isArray(collection)) {
return null;
}
return collection.find(item => item.id == id) || null;
}
/**
* DataManager核心类
*/
export class DataManagerCore {
constructor(options = {}) {
this.baseUrl = options.baseUrl || '';
this.onProgressUpdate = options.onProgressUpdate || null;
this.onInitComplete = options.onInitComplete || null;
this._rawData = {};
this.callbacks = new Map();
this.isWebSocketConnected = false;
this.webSocketClient = null;
this.webSocketTopics = new Set();
// 初始化IndexedDB管理器
this.indexedDBManager = new IndexedDBManager();
// 初始化懒加载器
this.lazyLoader = new LazyLoader(this);
// 初始化事务API
this.Transaction = new TransactionApi(this);
// 合并默认配置和用户配置
this.entityConfigs = this.mergeEntityConfigs(options.entityConfigs || []);
this.entityTypes = this.entityConfigs.map(config => config.type);
this.entityConfigMap = this.createEntityConfigMap();
// 创建数据访问代理
this.data = this.createDataProxy();
}
/**
* 合并实体配置
*/
mergeEntityConfigs(customConfigs) {
const defaultEntityConfigs = [
{ type: 'dingdan', isCore: true, text: '订单' },
{ type: 'bancai', isCore: true, text: '板材' },
{ type: 'chanpin', isCore: true, text: '产品' },
{ type: 'zujian', isCore: true, text: '组件' },
{ type: 'kucun', isCore: true, text: '库存' },
{ type: 'user', isCore: true, text: '用户' },
{ type: 'caizhi', isCore: true, text: '材质' },
{ type: 'mupi', isCore: true, text: '木皮' },
{ type: 'dingdan_bancai', isCore: false, text: '订单板材' },
{ type: 'jinhuo', isCore: false, text: '进货' },
{ type: 'chanpin_zujian', isCore: false, text: '产品组件' },
{ type: 'dingdan_chanpin', isCore: false, text: '订单产品' }
];
// 创建配置映射以便快速查找
const configMap = new Map(defaultEntityConfigs.map(config => [config.type, config]));
// 合并用户配置
customConfigs.forEach(customConfig => {
if (configMap.has(customConfig.type)) {
// 合并现有配置
const existingConfig = configMap.get(customConfig.type);
configMap.set(customConfig.type, { ...existingConfig, ...customConfig });
} else {
// 添加新配置
configMap.set(customConfig.type, customConfig);
}
});
// 转换回数组
return Array.from(configMap.values());
}
/**
* 创建实体配置映射
*/
createEntityConfigMap() {
const configMap = new Map();
this.entityConfigs.forEach(config => {
configMap.set(config.type, config);
});
return configMap;
}
/**
* 获取实体配置
*/
getEntityConfig(entityType) {
return this.entityConfigMap.get(entityType) || {};
}
/**
* 创建空数据结构
*/
createEmptyData() {
const emptyData = {};
// 为每种实体类型创建空数组
this.entityTypes.forEach(entityType => {
const collectionName = `${entityType}s`;
emptyData[collectionName] = [];
});
// 添加特殊字段
emptyData._lastSync = null;
emptyData._isLoading = false;
return emptyData;
}
/**
* 创建数据访问代理
*/
createDataProxy() {
const self = this;
return new Proxy({}, {
get: (target, property) => {
// 懒加载数据
if (property in self._rawData) {
// 获取原始数据
const rawData = self._rawData[property];
// 如果是数组,为每个元素创建代理
if (Array.isArray(rawData)) {
return rawData.map(item => self.lazyLoader.createProxy(item, property.replace('s', '')));
}
return rawData;
}
return undefined;
},
set: (target, property, value) => {
self._rawData[property] = value;
return true;
}
});
}
/**
* 添加实体类型
*/
addEntityType(entityType, config = {}) {
// 检查是否已存在
if (this.entityTypes.includes(entityType)) {
console.warn(`实体类型${entityType}已存在`);
return;
}
// 添加到配置
const newConfig = {
type: entityType,
isCore: config.isCore || false,
text: config.text || entityType,
duplicateCheckRule: config.duplicateCheckRule || null
};
this.entityConfigs.push(newConfig);
this.entityTypes.push(entityType);
this.entityConfigMap.set(entityType, newConfig);
// 初始化集合
const collectionName = `${entityType}s`;
if (!this._rawData[collectionName]) {
this._rawData[collectionName] = [];
}
// 订阅WebSocket主题
if (this.isWebSocketConnected) {
this.webSocketClient.send(JSON.stringify({
type: 'subscribe',
topic: collectionName
}));
}
// 从IndexedDB加载数据
this.loadEntityFromIndexedDB(entityType);
}
/**
* 初始化DataManager
*/
async initialize() {
try {
// 初始化IndexedDB
await this.indexedDBManager.init();
// 内部初始化
await this._initializeInternal();
// 初始化WebSocket
if (this.baseUrl) {
this.initWebSocket();
}
// 初始化网络状态监听
this.initNetwork();
// 触发初始化完成回调
if (this.onInitComplete) {
this.onInitComplete();
}
} catch (error) {
console.error('DataManager初始化失败:', error);
throw error;
}
}
/**
* 内部初始化方法
*/
async _initializeInternal() {
try {
// 创建空数据结构
this._rawData = this.createEmptyData();
this._rawData._isLoading = true;
// 获取核心实体类型
const coreEntityTypes = this.entityConfigs
.filter(config => config.isCore)
.map(config => config.type);
// 并行加载核心实体数据
const loadPromises = coreEntityTypes.map(entityType =>
this.loadEntityFromIndexedDB(entityType)
);
await Promise.all(loadPromises);
// 标记加载完成
this._rawData._isLoading = false;
} catch (error) {
console.error('内部初始化失败:', error);
this._rawData._isLoading = false;
throw error;
}
}
}
================================================================================
/* 文件路径: data/DataManagerCRUD.js */
/**
* DataManager CRUD模块 - 包含实体的增删改查操作
*/
import { DataManagerNetwork } from './DataManagerNetwork.js';
/**
* DataManager CRUD类
*/
export class DataManagerCRUD extends DataManagerNetwork {
/**
* 注册回调函数
*/
registerCallback(event, callback) {
if (!this.callbacks.has(event)) {
this.callbacks.set(event, new Set());
}
this.callbacks.get(event).add(callback);
}
/**
* 取消注册回调函数
*/
unregisterCallback(event, callback) {
if (this.callbacks.has(event)) {
this.callbacks.get(event).delete(callback);
// 如果没有回调函数了,删除这个事件
if (this.callbacks.get(event).size === 0) {
this.callbacks.delete(event);
}
}
}
/**
* 触发回调函数
*/
triggerCallbacks(event, ...args) {
if (this.callbacks.has(event)) {
this.callbacks.get(event).forEach(callback => {
try {
callback(...args);
} catch (error) {
console.error(`触发回调函数时出错: event=${event}`, error);
}
});
}
}
/**
* 处理实体CRUD操作
*/
async crudOperation(operation, entityType, data) {
try {
const collectionName = this.getCollectionName(entityType);
// 触发操作开始回调
this.triggerCallbacks(`${operation}_start`, entityType, data);
// 检查网络连接
if (!navigator.onLine && operation !== 'delete') {
console.warn('网络连接已断开,尝试离线操作');
// 离线模式下处理
const result = await this.handleOfflineOperation(operation, entityType, data);
// 触发操作完成回调
this.triggerCallbacks(`${operation}_complete`, entityType, result);
return result;
}
// 在线模式下发送请求
const response = await fetch(`${this.baseUrl}/app/${operation}/${entityType}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status === 200) {
// 触发操作完成回调
this.triggerCallbacks(`${operation}_complete`, entityType, result.data);
return result.data;
} else {
throw new Error(result.text || `${operation}操作失败`);
}
} catch (error) {
console.error(`${operation}${entityType}失败:`, error);
// 触发操作失败回调
this.triggerCallbacks(`${operation}_error`, entityType, {
data,
error: error.message
});
throw error;
}
}
/**
* 处理离线操作
*/
async handleOfflineOperation(operation, entityType, data) {
try {
const collectionName = this.getCollectionName(entityType);
if (!this._rawData[collectionName]) {
this._rawData[collectionName] = [];
}
let result;
switch (operation) {
case 'add':
// 生成临时ID
const tempId = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const newItem = { ...data, id: tempId, isTemp: true };
// 添加到本地数据
this._rawData[collectionName].push(newItem);
// 保存到IndexedDB
await this.indexedDBManager.ensureCollection(collectionName);
await this.indexedDBManager.put(collectionName, newItem);
result = newItem;
break;
case 'update':
// 查找并更新本地数据
const index = this._rawData[collectionName].findIndex(item => item.id === data.id);
if (index !== -1) {
this._rawData[collectionName][index] = { ...this._rawData[collectionName][index], ...data };
// 保存到IndexedDB
await this.indexedDBManager.ensureCollection(collectionName);
await this.indexedDBManager.put(collectionName, this._rawData[collectionName][index]);
result = this._rawData[collectionName][index];
} else {
throw new Error('未找到要更新的实体');
}
break;
case 'delete':
// 查找并删除本地数据
const deleteIndex = this._rawData[collectionName].findIndex(item => item.id === data.id);
if (deleteIndex !== -1) {
const deletedItem = this._rawData[collectionName].splice(deleteIndex, 1)[0];
// 从IndexedDB删除
await this.indexedDBManager.ensureCollection(collectionName);
await this.indexedDBManager.delete(collectionName, data.id);
result = deletedItem;
} else {
throw new Error('未找到要删除的实体');
}
break;
default:
throw new Error(`不支持的离线操作: ${operation}`);
}
// 记录离线操作,以便网络恢复时同步
await this.recordOfflineOperation(operation, entityType, data);
return result;
} catch (error) {
console.error(`处理离线${operation}操作失败:`, error);
throw error;
}
}
/**
* 记录离线操作
*/
async recordOfflineOperation(operation, entityType, data) {
try {
// 获取现有离线操作
let offlineOperations = await this.indexedDBManager.getMetadata('offline_operations') || [];
// 添加新的离线操作
offlineOperations.push({
id: `offline_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
operation,
entityType,
data,
timestamp: new Date().toISOString()
});
// 保存离线操作
await this.indexedDBManager.setMetadata('offline_operations', offlineOperations);
} catch (error) {
console.error('记录离线操作失败:', error);
}
}
/**
* 更新本地数据
*/
updateLocalData(collectionName, data) {
try {
if (!this._rawData[collectionName]) {
this._rawData[collectionName] = [];
}
// 如果是数组,批量更新
if (Array.isArray(data)) {
data.forEach(item => this._updateSingleItem(collectionName, item));
} else {
// 单条更新
this._updateSingleItem(collectionName, data);
}
// 触发数据更新回调
this.triggerCallbacks('data_updated', collectionName, data);
// 异步保存到IndexedDB
this._saveToIndexedDBAsync(collectionName);
} catch (error) {
console.error(`更新本地数据失败: ${collectionName}`, error);
}
}
/**
* 更新单条数据
*/
_updateSingleItem(collectionName, data) {
if (!data || !data.id) {
return;
}
const index = this._rawData[collectionName].findIndex(item => item.id === data.id);
if (index !== -1) {
// 更新现有项
this._rawData[collectionName][index] = { ...this._rawData[collectionName][index], ...data };
} else {
// 如果不存在,添加新项
this._rawData[collectionName].push(data);
}
}
/**
* 添加本地数据
*/
addLocalData(collectionName, data) {
try {
if (!this._rawData[collectionName]) {
this._rawData[collectionName] = [];
}
// 如果是数组,批量添加
if (Array.isArray(data)) {
data.forEach(item => {
// 检查是否已存在
const exists = this._rawData[collectionName].some(existing => existing.id === item.id);
if (!exists) {
this._rawData[collectionName].push(item);
}
});
} else {
// 单条添加
const exists = this._rawData[collectionName].some(existing => existing.id === data.id);
if (!exists) {
this._rawData[collectionName].push(data);
}
}
// 触发数据添加回调
this.triggerCallbacks('data_added', collectionName, data);
// 异步保存到IndexedDB
this._saveToIndexedDBAsync(collectionName);
} catch (error) {
console.error(`添加本地数据失败: ${collectionName}`, error);
}
}
/**
* 删除本地数据
*/
deleteLocalData(collectionName, data) {
try {
if (!this._rawData[collectionName]) {
return;
}
// 如果提供了ID数组,批量删除
if (Array.isArray(data) && data.every(item => typeof item === 'string' || typeof item === 'number')) {
this._rawData[collectionName] = this._rawData[collectionName].filter(
item => !data.includes(item.id)
);
}
// 如果提供了ID,删除单条
else if (typeof data === 'string' || typeof data === 'number') {
this._rawData[collectionName] = this._rawData[collectionName].filter(
item => item.id !== data
);
}
// 如果提供了完整对象,根据ID删除
else if (data && data.id) {
this._rawData[collectionName] = this._rawData[collectionName].filter(
item => item.id !== data.id
);
}
// 触发数据删除回调
this.triggerCallbacks('data_deleted', collectionName, data);
// 异步保存到IndexedDB
this._saveToIndexedDBAsync(collectionName);
} catch (error) {
console.error(`删除本地数据失败: ${collectionName}`, error);
}
}
/**
* 异步保存到IndexedDB
*/
_saveToIndexedDBAsync(collectionName) {
this.indexedDBManager.ensureCollection(collectionName).then(() => {
const data = this._rawData[collectionName];
if (data && data.length > 0) {
this.indexedDBManager.putAll(collectionName, data).catch(error => {
console.error(`异步保存数据到IndexedDB失败: ${collectionName}`, error);
});
}
}).catch(error => {
console.error(`确保集合存在失败: ${collectionName}`, error);
});
}
/**
* 添加实体
*/
async addEntity(entity, data) {
// 检查重复数据
if (this.checkDuplicate(entity, data)) {
const config = this.getEntityConfig(entity);
const errorMsg = `${config.text || entity}数据重复`;
this.triggerCallbacks('duplicate_error', entity, { data, error: errorMsg });
throw new Error(errorMsg);
}
return this.crudOperation('add', entity, data);
}
/**
* 更新实体
*/
async updateEntity(entity, data) {
return this.crudOperation('update', entity, data);
}
/**
* 删除实体
*/
async deleteEntity(entity, id) {
return this.crudOperation('delete', entity, { id });
}
/**
* 事务操作
*/
async transactionalOperation(endpoint, data) {
return this.Transaction.execute(endpoint, data);
}
}
================================================================================
/* 文件路径: data/DataManagerNetwork.js */
/**
* DataManager网络模块 - 包含WebSocket连接和数据同步功能
*/
import { DataManagerStorage } from './DataManagerStorage.js';
/**
* DataManager网络类
*/
export class DataManagerNetwork extends DataManagerStorage {
/**
* 初始化WebSocket连接
*/
async initWebSocket() {
try {
// 检查是否已加载SockJS库
if (!window.SockJS) {
throw new Error('SockJS库未加载');
}
// 创建WebSocket客户端
const socketUrl = `${this.baseUrl}/ws`;
this.webSocketClient = new window.SockJS(socketUrl);
// 设置WebSocket事件处理程序
this.webSocketClient.onopen = () => {
console.log('WebSocket连接已建立');
this.isWebSocketConnected = true;
// 重新订阅所有主题
this.resubscribeWebSocketTopics();
// 触发连接成功回调
this.triggerCallbacks('websocket_connected');
};
this.webSocketClient.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
this.handleWebSocketMessage(message);
} catch (error) {
console.error('解析WebSocket消息失败:', error);
}
};
this.webSocketClient.onclose = () => {
console.log('WebSocket连接已关闭');
this.isWebSocketConnected = false;
// 触发连接关闭回调
this.triggerCallbacks('websocket_disconnected');
// 尝试重新连接
setTimeout(() => this.initWebSocket(), 5000);
};
this.webSocketClient.onerror = (error) => {
console.error('WebSocket连接错误:', error);
// 触发连接错误回调
this.triggerCallbacks('websocket_error', error);
};
} catch (error) {
console.error('初始化WebSocket失败:', error);
// 尝试重新连接
setTimeout(() => this.initWebSocket(), 5000);
}
}
/**
* 重新订阅所有WebSocket主题
*/
resubscribeWebSocketTopics() {
if (!this.isWebSocketConnected || !this.webSocketClient) {
return;
}
// 订阅所有实体类型集合
this.entityTypes.forEach(entityType => {
const collectionName = `${entityType}s`;
this.webSocketTopics.add(collectionName);
this.webSocketClient.send(JSON.stringify({
type: 'subscribe',
topic: collectionName
}));
});
}
/**
* 处理WebSocket消息
*/
handleWebSocketMessage(message) {
if (!message || !message.type) {
return;
}
try {
const { type, topic, data } = message;
// 根据消息类型处理
switch (type) {
case 'data_update':
this.updateLocalData(topic, data);
break;
case 'data_add':
this.addLocalData(topic, data);
break;
case 'data_delete':
this.deleteLocalData(topic, data);
break;
case 'progress_update':
if (this.onProgressUpdate && data.progress !== undefined) {
this.onProgressUpdate(data.progress);
}
break;
case 'sync_complete':
this.triggerCallbacks('sync_complete');
break;
case 'error':
console.error('WebSocket错误消息:', data);
this.triggerCallbacks('websocket_message_error', data);
break;
default:
console.log('接收到未知类型的WebSocket消息:', type);
break;
}
} catch (error) {
console.error('处理WebSocket消息时出错:', error);
}
}
/**
* 获取集合名称
*/
getCollectionName(entityType) {
return entityType.endsWith('s') ? entityType : `${entityType}s`;
}
/**
* 初始化网络状态监听
*/
initNetwork() {
// 监听网络状态变化
window.addEventListener('online', () => {
console.log('网络连接已恢复');
this.triggerCallbacks('network_online');
// 尝试重新同步数据
this.syncData();
});
window.addEventListener('offline', () => {
console.log('网络连接已断开');
this.triggerCallbacks('network_offline');
});
}
/**
* 同步实体数据
*/
async syncEntityData(entityType) {
try {
const collectionName = this.getCollectionName(entityType);
const config = this.getEntityConfig(entityType);
// 触发同步开始回调
this.triggerCallbacks('sync_start', entityType);
// 检查网络连接
if (!navigator.onLine) {
console.warn('网络连接已断开,无法同步数据');
this.triggerCallbacks('sync_error', entityType, { error: '网络连接已断开' });
return;
}
// 发送同步请求
const response = await fetch(`${this.baseUrl}/app/sync/${entityType}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status === 200 && Array.isArray(result.data)) {
// 更新本地数据
this._rawData[collectionName] = result.data;
// 保存到IndexedDB
await this.indexedDBManager.ensureCollection(collectionName);
await this.indexedDBManager.clear(collectionName);
await this.indexedDBManager.putAll(collectionName, result.data);
// 更新最后同步时间
this._rawData._lastSync = new Date().toISOString();
await this.indexedDBManager.setMetadata('lastSyncTime', this._rawData._lastSync);
// 触发同步完成回调
this.triggerCallbacks('sync_complete', entityType);
} else {
throw new Error(result.text || '同步数据失败');
}
} catch (error) {
console.error(`同步${entityType}数据失败:`, error);
this.triggerCallbacks('sync_error', entityType, { error: error.message });
}
}
/**
* 添加重复检查规则
*/
addDuplicateCheckRule(entityType, rule) {
const config = this.getEntityConfig(entityType);
if (config) {
config.duplicateCheckRule = rule;
}
}
/**
* 检查重复数据
*/
checkDuplicate(entityType, newData) {
const config = this.getEntityConfig(entityType);
if (!config.duplicateCheckRule || !newData) {
return false;
}
const { fields, isStrict } = config.duplicateCheckRule;
const collectionName = this.getCollectionName(entityType);
const collection = this._rawData[collectionName] || [];
return collection.some(item => {
// 如果是更新操作,跳过当前项
if (newData.id && item.id === newData.id) {
return false;
}
// 检查所有指定字段
return fields.every(field => {
if (isStrict) {
return item[field] === newData[field];
} else {
return item[field] && newData[field] &&
String(item[field]).toLowerCase() === String(newData[field]).toLowerCase();
}
});
});
}
/**
* 获取实体数据
*/
async fetchEntityData(entityType) {
try {
const response = await fetch(`${this.baseUrl}/app/data/${entityType}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status === 200 && Array.isArray(result.data)) {
const collectionName = this.getCollectionName(entityType);
this._rawData[collectionName] = result.data;
// 保存到IndexedDB
await this.indexedDBManager.ensureCollection(collectionName);
await this.indexedDBManager.clear(collectionName);
await this.indexedDBManager.putAll(collectionName, result.data);
return result.data;
} else {
throw new Error(result.text || '获取数据失败');
}
} catch (error) {
console.error(`获取${entityType}数据失败:`, error);
throw error;
}
}
/**
* 同步所有数据
*/
async syncData() {
try {
// 获取所有实体类型
const syncPromises = this.entityTypes.map(entityType =>
this.syncEntityData(entityType)
);
// 并行同步所有数据
await Promise.all(syncPromises);
// 触发全部同步完成回调
this.triggerCallbacks('all_sync_complete');
} catch (error) {
console.error('同步所有数据失败:', error);
this.triggerCallbacks('sync_all_error', { error: error.message });
}
}
/**
* 并行获取所有实体数据
*/
async fetchAll() {
try {
// 标记为加载中
this._rawData._isLoading = true;
// 获取所有实体类型
const entityPromises = this.entityTypes.map(entityType =>
this.fetchEntityData(entityType).catch(error => {
console.error(`获取${entityType}数据失败,但继续处理其他实体:`, error);
return null;
})
);
// 并行获取所有数据
await Promise.all(entityPromises);
// 标记加载完成
this._rawData._isLoading = false;
// 触发获取完成回调
this.triggerCallbacks('fetch_all_complete');
} catch (error) {
console.error('获取所有数据失败:', error);
this._rawData._isLoading = false;
this.triggerCallbacks('fetch_all_error', { error: error.message });
throw error;
}
}
}
================================================================================
/* 文件路径: data/DataManagerStorage.js */
/**
* DataManager存储模块 - 包含IndexedDB数据操作功能
*/
import { DataManagerCore } from './DataManagerCore.js';
/**
* DataManager存储类
*/
export class DataManagerStorage extends DataManagerCore {
/**
* 从IndexedDB加载单个实体类型数据
*/
async loadEntityFromIndexedDB(entityType) {
try {
const collectionName = `${entityType}s`;
// 确保集合存在
await this.indexedDBManager.ensureCollection(collectionName);
// 加载数据
const data = await this.indexedDBManager.getAll(collectionName);
if (data && data.length > 0) {
this._rawData[collectionName] = data;
// 解析数据引用
this.resolveDataReferencesForCollection(collectionName);
}
} catch (error) {
console.error(`从IndexedDB加载${entityType}数据失败:`, error);
}
}
/**
* 解析集合中的数据引用
*/
resolveDataReferencesForCollection(collectionName) {
if (!this._rawData[collectionName]) return;
const entityType = collectionName.replace('s', '');
this._rawData[collectionName] = this._rawData[collectionName].map(item => {
// 创建代理对象以实现懒加载
return this.lazyLoader.createProxy(item, entityType);
});
}
/**
* 保存数据到IndexedDB
*/
async saveDataToIndexedDB() {
try {
// 获取所有实体类型集合
const collectionKeys = Object.keys(this._rawData).filter(key =>
!key.startsWith('_') && Array.isArray(this._rawData[key])
);
// 使用Promise.all实现并行保存,但限制并发数
const batchSize = 3;
let savedCollections = 0;
for (let i = 0; i < collectionKeys.length; i += batchSize) {
const batch = collectionKeys.slice(i, i + batchSize);
// 处理当前批次中的每个集合
await Promise.all(batch.map(async key => {
const data = this._rawData[key];
if (data && data.length > 0) {
// 先清空再添加
await this.indexedDBManager.clear(key);
await this.indexedDBManager.putAll(key, data);
}
// 更新保存进度
savedCollections++;
const saveProgress = Math.floor((savedCollections / collectionKeys.length) * 20);
if (this.onProgressUpdate) {
this.onProgressUpdate(saveProgress);
}
}));
}
// 保存最后同步时间
this._rawData._lastSync = new Date().toISOString();
await this.indexedDBManager.setMetadata('lastSyncTime', this._rawData._lastSync);
} catch (error) {
console.error('保存数据到IndexedDB失败:', error);
}
}
/**
* 兼容旧代码,保留localStorage方法但内部使用IndexedDB
*/
loadDataFromStorage() {
this.loadDataFromIndexedDB();
}
saveDataToStorage() {
this.saveDataToIndexedDB();
}
/**
* 移除循环引用的辅助方法
*/
removeCircularReferences(obj, seen = new WeakSet()) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (seen.has(obj)) {
return {}; // 返回空对象而不是循环引用
}
seen.add(obj);
if (Array.isArray(obj)) {
return obj.map(item => this.removeCircularReferences(item, seen));
}
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = this.removeCircularReferences(obj[key], seen);
}
}
return result;
}
/**
* 从IndexedDB加载所有数据
*/
async loadDataFromIndexedDB() {
try {
// 标记为加载中
this._rawData._isLoading = true;
// 获取所有实体类型集合
const collectionKeys = this.entityTypes.map(type => `${type}s`);
// 并行加载所有数据,但限制并发数
const batchSize = 3;
let loadedCollections = 0;
for (let i = 0; i < collectionKeys.length; i += batchSize) {
const batch = collectionKeys.slice(i, i + batchSize);
await Promise.all(batch.map(async key => {
await this.indexedDBManager.ensureCollection(key);
const data = await this.indexedDBManager.getAll(key);
if (data && data.length > 0) {
this._rawData[key] = data;
}
// 更新加载进度
loadedCollections++;
const loadProgress = Math.floor((loadedCollections / collectionKeys.length) * 20);
if (this.onProgressUpdate) {
this.onProgressUpdate(loadProgress);
}
}));
}
// 加载最后同步时间
const lastSyncTime = await this.indexedDBManager.getMetadata('lastSyncTime');
if (lastSyncTime) {
this._rawData._lastSync = lastSyncTime;
}
// 标记加载完成
this._rawData._isLoading = false;
} catch (error) {
console.error('从IndexedDB加载数据失败:', error);
this._rawData._isLoading = false;
}
}
}
================================================================================
/* 文件路径: data/index.js */
// 数据管理模块主入口
// 导入核心模块
import { DataManager } from './DataManager.js';
import { DataManagerCore } from './DataManagerCore.js';
import { DataManagerStorage } from './DataManagerStorage.js';
import { DataManagerNetwork } from './DataManagerNetwork.js';
import { DataManagerCRUD } from './DataManagerCRUD.js';
// 导入辅助模块
import { LazyLoader } from './LazyLoader.js';
import { TransactionApi } from './TransactionApi.js';
import { IndexedDBManager } from './IndexedDBManager.js';
// 导出所有模块,方便外部使用
export {
DataManager,
DataManagerCore,
DataManagerStorage,
DataManagerNetwork,
DataManagerCRUD,
LazyLoader,
TransactionApi,
IndexedDBManager
};
// 提供默认导出,方便直接使用DataManager
export default DataManager;
================================================================================
/* 文件路径: data/IndexedDBManager.js */
/**
* IndexedDB工具类 - 用于大数据存储
*/
class IndexedDBManager {
constructor(dbName = 'appData', version = 1) {
this.dbName = dbName;
this.version = version;
this.db = null;
this.collections = new Set();
// 添加版本升级队列,解决IndexedDB不允许同时进行多个版本升级的问题
this.upgradeQueue = [];
this.isUpgrading = false;
}
/**
* 初始化数据库连接
*/
async init() {
return new Promise((resolve, reject) => {
if (this.db) {
resolve(this.db);
return;
}
// 不指定版本号,让浏览器自动使用最新版本
// 这样即使数据库版本高于代码中指定的版本,也能成功打开
const request = indexedDB.open(this.dbName);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 确保存储元数据的集合存在
if (!db.objectStoreNames.contains('metadata')) {
db.createObjectStore('metadata', { keyPath: 'key' });
}
// 更新版本号缓存
this.version = db.version;
};
request.onsuccess = (event) => {
this.db = event.target.result;
// 更新版本号缓存
this.version = this.db.version;
resolve(this.db);
};
request.onerror = (event) => {
console.error('IndexedDB初始化失败:', event.target.error);
reject(event.target.error);
};
});
}
/**
* 确保对象存储空间(集合)存在
*/
async ensureCollection(collectionName) {
// 如果是单个集合请求,使用队列处理
return this._ensureCollection(collectionName);
}
/**
* 批量确保多个对象存储空间存在
* 避免多次触发版本升级
*/
async batchEnsureCollections(collectionNames) {
if (!Array.isArray(collectionNames) || collectionNames.length === 0) {
return Promise.resolve([]);
}
// 首先确保数据库已初始化
const db = await this.init();
// 检查哪些集合已经存在,哪些需要创建
const existingCollections = new Set();
const collectionsToCreate = [];
for (const collectionName of collectionNames) {
if (this.collections.has(collectionName)) {
existingCollections.add(collectionName);
} else if (db.objectStoreNames.contains(collectionName)) {
this.collections.add(collectionName);
existingCollections.add(collectionName);
} else {
collectionsToCreate.push(collectionName);
}
}
// 如果有需要创建的集合,一次性创建
if (collectionsToCreate.length > 0) {
await this._batchCreateCollections(collectionsToCreate);
}
return [...existingCollections, ...collectionsToCreate];
}
/**
* 内部方法:确保单个集合存在(使用队列处理)
*/
async _ensureCollection(collectionName) {
try {
if (this.collections.has(collectionName)) {
return true;
}
const db = await this.init();
// 检查对象存储空间是否已存在
if (db.objectStoreNames.contains(collectionName)) {
this.collections.add(collectionName);
return true;
}
// 需要升级数据库来创建新的对象存储空间
// 使用队列确保一次只进行一个版本升级
return new Promise((resolve, reject) => {
// 将升级请求加入队列
this.upgradeQueue.push({
collectionName,
resolve,
reject
});
// 如果当前没有升级在进行,开始处理队列
if (!this.isUpgrading) {
this._processUpgradeQueue();
}
});
} catch (error) {
console.error(`ensureCollection方法执行错误:`, error);
// 出错时返回一个拒绝的Promise,保持返回类型一致
return Promise.reject(error);
}
}
/**
* 批量创建多个对象存储空间
* 整合到升级队列中,确保与其他升级操作不冲突
*/
async _batchCreateCollections(collectionNames) {
if (!collectionNames || collectionNames.length === 0) {
return Promise.resolve();
}
// 将批量创建请求作为一个队列项加入升级队列
return new Promise((resolve, reject) => {
// 将升级请求加入队列
this.upgradeQueue.push({
batchCollections: collectionNames,
resolve,
reject
});
// 如果当前没有升级在进行,开始处理队列
if (!this.isUpgrading) {
this._processUpgradeQueue();
}
});
}
/**
* 处理版本升级队列,确保一次只进行一个版本升级
* 支持单个集合和批量集合的创建
*/
async _processUpgradeQueue() {
if (this.isUpgrading || this.upgradeQueue.length === 0) {
return;
}
this.isUpgrading = true;
const queueItem = this.upgradeQueue.shift();
const { collectionName, batchCollections, resolve, reject } = queueItem;
try {
// 首先关闭现有连接,避免版本升级被阻塞
this.close();
// 重新初始化数据库以获取最新连接
const db = await this.init();
// 执行版本升级
const newVersion = db.version + 1;
// 判断是单个集合还是批量集合升级
const collectionsToCreate = batchCollections || [collectionName];
const isBatchOperation = !!batchCollections;
const request = indexedDB.open(this.dbName, newVersion);
// 处理版本升级被阻塞的情况
request.onblocked = (event) => {
console.warn(`数据库版本升级被阻塞,可能有其他打开的连接。尝试关闭所有连接...`);
// 再次关闭连接,确保没有其他连接阻止升级
this.close();
};
request.onupgradeneeded = (event) => {
const newDb = event.target.result;
// 创建所有需要的对象存储空间
for (const name of collectionsToCreate) {
if (!newDb.objectStoreNames.contains(name)) {
newDb.createObjectStore(name, { keyPath: 'id' });
}
}
};
request.onsuccess = (event) => {
this.db = event.target.result;
// 将所有创建的集合添加到缓存
for (const name of collectionsToCreate) {
this.collections.add(name);
}
resolve(true);
// 处理下一个队列项
this.isUpgrading = false;
this._processUpgradeQueue();
};
request.onerror = (event) => {
console.error(`${isBatchOperation ? `批量创建集合失败` : `创建集合${collectionName}失败`}:`, event.target.error);
reject(event.target.error);
// 即使出错,也要处理下一个队列项
this.isUpgrading = false;
this._processUpgradeQueue();
};
} catch (error) {
console.error(`处理队列项时发生错误:`, error);
reject(error);
// 即使出错,也要处理下一个队列项
this.isUpgrading = false;
this._processUpgradeQueue();
}
}
/**
* 执行IndexedDB事务
*/
async transaction(collectionName, mode, callback) {
try {
// 确保数据库已初始化
if (!this.db) {
await this.init();
}
// 确保集合存在
await this.ensureCollection(collectionName);
// 执行事务
return new Promise((resolve, reject) => {
try {
const transaction = this.db.transaction([collectionName], mode);
const store = transaction.objectStore(collectionName);
// 设置事务事件处理器
transaction.onerror = (event) => {
console.error(`IndexedDB事务错误: ${collectionName}`, event.target.error);
reject(event.target.error);
};
transaction.onabort = (event) => {
console.error(`IndexedDB事务中止: ${collectionName}`, event.target.error);
reject(event.target.error);
};
// 执行回调并处理返回结果
try {
const result = callback(store);
// 如果回调返回的是Promise,等待其完成
if (result instanceof Promise) {
result.then(resolve).catch(reject);
} else {
resolve(result);
}
} catch (callbackError) {
console.error(`回调执行出错: collection=${collectionName}`, callbackError);
reject(callbackError);
}
} catch (error) {
console.error('创建事务时出错:', error);
reject(error);
}
});
} catch (error) {
console.error(`IndexedDB事务失败: ${collectionName}`, error);
// 不抛出错误,而是返回一个被拒绝的Promise,确保上层调用者能捕获错误
return Promise.reject(error);
}
}
/**
* 存储单个实体
*/
async put(collectionName, entity) {
return this.transaction(collectionName, 'readwrite', (store) => {
return store.put(entity);
});
}
/**
* 存储多个实体
*/
async putAll(collectionName, entities) {
return this.transaction(collectionName, 'readwrite', (store) => {
return new Promise((resolve, reject) => {
const requests = entities.map(entity => store.put(entity));
let completed = 0;
requests.forEach(request => {
request.onsuccess = () => {
completed++;
if (completed === requests.length) {
resolve(entities.length);
}
};
request.onerror = (event) => {
reject(event.target.error);
};
});
});
});
}
/**
* 获取单个实体
*/
async get(collectionName, id) {
return this.transaction(collectionName, 'readonly', (store) => {
return store.get(id);
});
}
/**
* 获取所有实体
*/
async getAll(collectionName) {
return this.transaction(collectionName, 'readonly', (store) => {
return store.getAll();
});
}
/**
* 删除单个实体
*/
async delete(collectionName, id) {
return this.transaction(collectionName, 'readwrite', (store) => {
return store.delete(id);
});
}
/**
* 清空集合
*/
async clear(collectionName) {
return this.transaction(collectionName, 'readwrite', (store) => {
return store.clear();
});
}
/**
* 获取集合中实体的数量
*/
async count(collectionName) {
return this.transaction(collectionName, 'readonly', (store) => {
return store.count();
});
}
/**
* 查询实体
*/
async query(collectionName, query) {
return this.transaction(collectionName, 'readonly', (store) => {
const results = [];
const request = store.openCursor();
return new Promise((resolve, reject) => {
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// 执行查询条件
if (!query || this.matchesQuery(cursor.value, query)) {
results.push(cursor.value);
}
cursor.continue();
} else {
resolve(results);
}
};
request.onerror = (event) => {
reject(event.target.error);
};
});
});
}
/**
* 检查实体是否匹配查询条件
*/
matchesQuery(entity, query) {
for (const key in query) {
if (entity[key] !== query[key]) {
return false;
}
}
return true;
}
/**
* 存储元数据
*/
async setMetadata(key, value) {
return this.put('metadata', { key, value });
}
/**
* 获取元数据
*/
async getMetadata(key) {
const metadata = await this.get('metadata', key);
return metadata ? metadata.value : null;
}
/**
* 关闭数据库连接
*/
close() {
if (this.db) {
this.db.close();
this.db = null;
}
}
/**
* 删除整个数据库
*/
async deleteDatabase() {
return new Promise((resolve, reject) => {
this.close();
const request = indexedDB.deleteDatabase(this.dbName);
request.onsuccess = () => resolve(true);
request.onerror = (event) => reject(event.target.error);
});
}
}
export { IndexedDBManager };
================================================================================
/* 文件路径: data/LazyLoader.js */
/**
* 懒加载器 - Web版 (优化版)
* 修复了缓存键设计、集合名解析和数组处理问题
*/
class LazyLoader {
constructor(dataManager) {
this.dataManager = dataManager;
// 使用WeakMap避免内存泄漏
this.proxyCache = new WeakMap();
// 实体名到集合名的映射表
this.entityToCollectionMap = {
bancai: 'bancais',
dingdan: 'dingdans',
mupi: 'mupis',
chanpin: 'chanpins',
kucun: 'kucuns',
chanpin_zujian: 'chanpin_zujians',
dingdan_bancai: 'dingdan_bancais',
zujian: 'zujians',
caizhi: 'caizhis',
dingdan_chanpin: 'dingdan_chanpins',
user: 'users',
jinhuo: 'jinhuos'
};
}
/**
* 清除缓存
*/
clearCache() {
this.proxyCache = new WeakMap();
}
/**
* 创建数据代理
* @param {Object} item - 原始数据项
* @param {string} entityType - 实体类型
* @returns {Proxy} 代理对象
*/
createProxy(item, entityType) {
// 非对象直接返回
if (!item || typeof item !== 'object') return item;
// 检查是否已有代理
if (this.proxyCache.has(item)) {
return this.proxyCache.get(item);
}
const proxy = new Proxy(item, {
get: (target, prop) => {
// 直接返回基本属性
if (typeof prop === 'symbol' ||
prop.startsWith('_') ||
typeof target[prop] !== 'object') {
return target[prop];
}
const value = target[prop];
// 处理null值
if (value === null) return null;
// 处理数组关联
if (Array.isArray(value)) {
return value.map(relatedItem =>
this.resolveRelation(relatedItem, prop)
);
}
// 处理对象关联
else if (typeof value === 'object') {
return this.resolveRelation(value, prop);
}
return value;
},
set: (target, prop, value) => {
target[prop] = value;
return true;
}
});
// 缓存代理对象
this.proxyCache.set(item, proxy);
return proxy;
}
/**
* 解析关联对象
* @param {Object|string|number} relatedItem - 关联项
* @param {string} propName - 关联属性名
* @returns {Object} 解析后的关联对象
*/
resolveRelation(relatedItem, propName) {
// 基本类型直接返回
if (typeof relatedItem !== 'object' || relatedItem === null) {
return relatedItem;
}
// 去掉数字后缀 (如 mupi1 → mupi)
const basePropName = propName.replace(/\d/g, '');
// 获取实体类型
let entityType;
// 检查是否已在映射表中
if (this.entityToCollectionMap[basePropName]) {
entityType = basePropName;
} else {
// 尝试从集合名反向查找实体类型
entityType = Object.keys(this.entityToCollectionMap).find(
key => this.entityToCollectionMap[key] === basePropName
) || basePropName;
}
// 获取集合名
let collectionName;
// 检查映射表中是否有对应的集合名
if (this.entityToCollectionMap[entityType]) {
collectionName = this.entityToCollectionMap[entityType];
} else {
// 动态处理新的实体类型,默认添加's'后缀
collectionName = `${entityType}s`;
// 将新的映射关系添加到映射表中
this.entityToCollectionMap[entityType] = collectionName;
}
// 获取数据集合
const collection = this.dataManager._rawData[collectionName];
if (!collection) return relatedItem;
// 查找完整对象
const fullItem = collection.find(item => item?.id === relatedItem?.id);
if (!fullItem) return relatedItem;
// 返回代理对象
return this.createProxy(fullItem, entityType);
}
}
export { LazyLoader };
================================================================================
/* 文件路径: data/TransactionApi.js */
/**
* 事务API - Web版
* 负责处理所有事务相关的操作
*/
class TransactionApi {
constructor(dataManager) {
this.dataManager = dataManager;
this.baseUrl = dataManager.baseUrl;
}
/**
* 执行事务操作
* @param {string} endpoint - 事务端点
* @param {Object} data - 事务数据
* @returns {Promise} 操作结果
*/
async execute(endpoint, data) {
try {
const response = await fetch(`${this.baseUrl}/app/transactional/${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status !== 200) {
throw new Error(result.text || 'Transaction failed');
}
// 在WebSocket模式下,数据会自动更新,无需手动同步
// 仅触发事务成功回调
this.dataManager.triggerCallbacks('transaction_success', endpoint, result.data);
return result.data;
} catch (error) {
console.error(`Transaction ${endpoint} failed:`, error);
// 触发事务失败回调
this.dataManager.triggerCallbacks('transaction_error', endpoint, {
data,
error: error.message
});
throw error;
}
}
/**
* 库存编辑事务
* @param {Object} params - 事务参数
* @param {Number} params.kucunId - 库存ID
* @param {Number} params.newStock - 新的库存数量
* @param {Number} params.oldStock - 原库存数量
* @param {String} params.note - 备注信息
* @param {Number} params.userId - 用户ID
* @returns {Promise} 操作结果
*/
async updateStock(params) {
return this.execute('kucunbianji', params);
}
/**
* 生产消耗事务
* @param {Object} params - 生产消耗参数
* @returns {Promise} 操作结果
*/
async shengchanXiaohao(params) {
return this.execute('shengchanXiaohao', params);
}
/**
* 批量更新订单板材事务
* @param {Object} params - 批量更新参数
* @returns {Promise} 操作结果
*/
async batchUpdateDingdanBancai(params) {
return this.execute('batchUpdateDingdanBancai', params);
}
/**
* 提交订单板材采购事务
* @param {Object} params - 提交参数
* @returns {Promise} 操作结果
*/
async submitDingdanBancai(params) {
return this.execute('submitDingdanBancai', params);
}
/**
* 消耗订单板材事务
* @param {Object} params - 消耗参数
* @returns {Promise} 操作结果
*/
async consumeDingdanBancai(params) {
return this.execute('consumeDingdanBancai', params);
}
/**
* 采购订单板材事务
* @param {Object} params - 采购参数
* @returns {Promise} 操作结果
*/
async 采购DingdanBancai(params) {
return this.execute('采购DingdanBancai', params);
}
/**
* 保存所有数据事务
* @param {Object} params - 保存参数
* @returns {Promise} 操作结果
*/
async saveAll(params) {
try {
const response = await fetch(`${this.baseUrl}/app/save-all`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status !== 200) {
throw new Error(result.text || 'Save all failed');
}
// 在WebSocket模式下,数据会自动更新,无需手动同步
return result.data;
} catch (error) {
console.error('Save all failed:', error);
throw error;
}
}
}
export { TransactionApi };