//{ 实体类的关联和属性列表
// "entities": {
// "Dingdan": {
// "properties": {
// "id": "Integer",
// "number": "String",
// "xiadan": "Date",
// "jiaohuo": "Date",
// "dingdan_chanpins": "List<Dingdan_chanpin> (OneToMany)",
// "dingdan_chanpins_zujians": "List<Dingdan_chanpin_zujian> (OneToMany)"
// },
// "relations": [
// "关联订单产品(Dingdan_chanpin)",
// "关联订单组件(Dingdan_chanpin_zujian)"
// ]
// },
// "Dingdan_chanpin": {
// "properties": {
// "id": "Integer",
// "shuliang": "Integer"
// },
// "relations": [
// "多对一关联订单(Dingdan)",
// "多对一关联产品(Chanpin)"
// ]
// },
// "Dingdan_chanpin_zujian": {
// "properties": {
// "id": "Integer",
// "shuliang": "Integer"
// },
// "relations": [
// "多对一关联订单(Dingdan)",
// "多对一关联组件(Chanpin_zujian)",
// "多对一关联板材(Bancai)"
// ]
// },
// "Jinhuo": {
// "properties": {
// "id": "Integer",
// "shuliang": "Integer",
// "date": "Date"
// },
// "relations": [
// "多对一关联订单(Dingdan)",
// "多对一关联产品(Chanpin)",
// "多对一关联组件(Zujian)",
// "多对一关联板材(Bancai)",
// "多对一关联用户(User)"
// ]
// },
// "Kucun": {
// "properties": {
// "id": "Integer",
// "shuliang": "Long"
// },
// "relations": [
// "一对一关联板材(Bancai)"
// ]
// },
// "Mupi": {
// "properties": {
// "id": "Integer",
// "name": "String",
// "you": "Boolean"
// },
// "relations": [
// "被板材关联(Bancai - mupi1/mupi2)"
// ]
// },
// "User": {
// "properties": {
// "id": "Integer",
// "name": "String",
// "andy": "String",
// "pass": "String",
// "role": "int"
// }
// },
// "Zujian": {
// "properties": {
// "id": "Integer",
// "name": "String"
// },
// "relations": [
// "一对多关联产品组件(Chanpin_zujian)"
// ]
// },
// "Bancai": {
// "properties": {
// "id": "Integer",
// "houdu": "Double"
// },
// "relations": [
// "多对一关联材质(Caizhi)",
// "多对一关联木皮(Mupi - mupi1/mupi2)",
// "一对一关联库存(Kucun)"
// ]
// },
// "Caizhi": {
// "properties": {
// "id": "Integer",
// "name": "String"
// },
// "relations": [
// "一对多关联板材(Bancai)"
// ]
// },
// "Chanpin": {
// "properties": {
// "id": "Integer",
// "bianhao": "String"
// },
// "relations": [
// "一对多关联订单产品(Dingdan_chanpin)",
// "一对多关联产品组件(Chanpin_zujian)"
// ]
// },
// "Chanpin_zujian": {
// "properties": {
// "id": "Integer",
// "one_howmany": "Double"
// },
// "relations": [
// "多对一关联产品(Chanpin)",
// "多对一关联组件(Zujian)",
// "多对一关联板材(Bancai)"
// ]
// }
// },
// "relationsSummary": [
// "订单(Dingdan) 1:N 订单产品(Dingdan_chanpin)",
// "订单(Dingdan) 1:N 订单组件(Dingdan_chanpin_zujian)",
// "产品(Chanpin) 1:N 产品组件(Chanpin_zujian)",
// "组件(Zujian) 1:N 产品组件(Chanpin_zujian)",
// "板材(Bancai) 1:1 库存(Kucun)",
// "材质(Caizhi) 1:N 板材(Bancai)"
// ]
//}
/**
* 解析数据关联关系,将ID引用转换为对象引用
* @param {Object} data - 从后端加载的原始数据
* @returns {Object} - 处理后的数据,包含完整的对象关联
*//**
* 解析数据关联关系,将ID引用转换为对象引用
* @param {Object} data - 从后端加载的原始数据
* @returns {Object} - 处理后的数据,包含完整的对象关联
*/
function resolveDataReferences(data) {
// 创建ID映射表
const idMaps = {};
Object.keys(data).forEach(key => {
// 确保数据存在且是数组
if (Array.isArray(data[key])) {
idMaps[key] = new Map();
data[key].forEach(item => idMaps[key].set(item.id, item));
}
});
// 处理多对一和一对一关系
const resolveRef = (source, sourceKey, targetKey, propertyName) => {
// 确保源数据存在且是数组
if (!Array.isArray(source)) return;
source.forEach(item => {
// 确保关联属性存在且有id
if (item[propertyName] && item[propertyName].id) {
const refId = item[propertyName].id;
// 确保目标映射存在
if (!idMaps[targetKey]) return;
const target = idMaps[targetKey].get(refId);
if (target) {
item[propertyName] = target;
// 建立反向引用(一对多关系)
if (!target[sourceKey]) target[sourceKey] = [];
if (!target[sourceKey].includes(item)) {
target[sourceKey].push(item);
}
}
}
});
};
// 处理一对多关系(直接创建关联数组)
const resolveOneToMany = (sourceKey, targetKey, propertyName) => {
// 确保源数据存在
if (!Array.isArray(data[sourceKey]) || !Array.isArray(data[targetKey])) return;
const sourceItems = data[sourceKey];
sourceItems.forEach(source => {
if (!source[propertyName]) source[propertyName] = [];
});
data[targetKey].forEach(target => {
// 确保关联属性存在
if (target[sourceKey]?.id) {
const sourceId = target[sourceKey].id;
// 确保源映射存在
if (!idMaps[sourceKey]) return;
const source = idMaps[sourceKey].get(sourceId);
if (source && source[propertyName]) {
source[propertyName].push(target);
}
}
});
};
// 处理特定关联关系 - 添加空值检查
if (data.dingdans && data.dingdan_chanpins) {
resolveOneToMany('dingdans', 'dingdan_chanpins', 'dingdan_chanpins');
resolveRef(data.dingdan_chanpins, 'dingdans', 'dingdans', 'dingdan');
}
if (data.dingdans && data.dingdan_chanpin_zujians) {
resolveOneToMany('dingdans', 'dingdan_chanpin_zujians', 'dingdan_chanpin_zujians');
resolveRef(data.dingdan_chanpin_zujians, 'dingdans', 'dingdans', 'dingdan');
}
if (data.chanpins && data.chanpin_zujians) {
resolveOneToMany('chanpins', 'chanpin_zujians', 'chanpin_zujians');
resolveRef(data.chanpin_zujians, 'chanpins', 'chanpins', 'chanpin');
}
if (data.zujians && data.chanpin_zujians) {
resolveOneToMany('zujians', 'chanpin_zujians', 'chanpin_zujians');
resolveRef(data.chanpin_zujians, 'zujians', 'zujians', 'zujian');
}
if (data.caizhis && data.bancais) {
resolveOneToMany('caizhis', 'bancais', 'bancais');
resolveRef(data.bancais, 'caizhis', 'caizhis', 'caizhi');
}
if (data.bancais && data.kucuns) {
resolveRef(data.bancais, 'kucuns', 'kucuns', 'kucun');
}
if (data.kucuns && data.bancais) {
resolveRef(data.kucuns, 'bancais', 'bancais', 'bancai');
}
if (data.bancais && data.mupis) {
resolveRef(data.bancais, 'mupis', 'mupis', 'mupi1');
resolveRef(data.bancais, 'mupis', 'mupis', 'mupi2');
}
if (data.dingdan_chanpins && data.chanpins) {
resolveRef(data.dingdan_chanpins, 'chanpins', 'chanpins', 'chanpin');
}
if (data.dingdan_chanpin_zujians && data.chanpin_zujians) {
resolveRef(data.dingdan_chanpin_zujians, 'chanpin_zujians', 'chanpin_zujians', 'chanpin_zujian');
}
if (data.dingdan_chanpin_zujians && data.bancais) {
resolveRef(data.dingdan_chanpin_zujians, 'bancais', 'bancais', 'bancai');
}
if (data.jinhuos) {
// 进货 ↔ 相关实体 (多对一)
['dingdans', 'chanpins', 'zujians', 'bancais', 'users'].forEach(entity => {
if (data[entity]) {
resolveRef(data.jinhuos, entity, entity, entity.slice(0, -1));
}
});
}
return data;
}
/**
* 数据管理器类,负责与后端API通信并管理数据
*/
class DataManager {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.data = {
bancais: [],
dingdans: [],
mupis: [],
chanpins: [],
kucuns: [],
dingdan_chanpin_zujians: [],
chanpin_zujians: [],
zujians: [],
caizhis: [],
dingdan_chanpins: [],
users: []
};
this.isSyncing = false;
this.lastSync = null;
// 回调注册表
this.callbacks = {
// 全局回调
all: [],
// 按实体类型分类的回调
bancais: [],
dingdan: [],
mupi: [],
chanpin: [],
kucun: [],
dingdan_chanpin_zujian: [],
chanpin_zujian: [],
zujian: [],
caizhi: [],
dingdan_chanpin: [],
user: []
// ...其他实体
};
}
/**
* 获取所有数据
* @returns {Promise<boolean>} 是否成功
*/
async fetchAll() {
console.log(this)
try {
const response = await fetch(`${this.baseUrl}/app/all`);
if (!response.ok) throw new Error('Network response was not ok');
const result = await response.json();
if (result.status !== 200) throw new Error(result.text || 'API error');
const resolvedData = resolveDataReferences(result.data);
// 更新本地数据
Object.keys(this.data).forEach(key => {
if (resolvedData[key]) {
this.data[key] = resolvedData[key];
}
});
this.lastSync = new Date();
return true;
} catch (error) {
console.error('Fetch error:', error);
return false;
}
}
/**
* 注册回调函数
* @param {string} entity - 实体类型(如'bancai')或'all'表示全局回调
* @param {Function} callback - 回调函数,参数为(operation, data)
*/
registerCallback(entity, callback) {
if (!this.callbacks[entity]) {
this.callbacks[entity] = [];
}
this.callbacks[entity].push(callback);
}
/**
* 移除回调函数
* @param {string} entity - 实体类型单数性质
* @param {Function} callback - 要移除的回调函数
*/
unregisterCallback(entity, callback) {
if (!this.callbacks[entity]) return;
const index = this.callbacks[entity].indexOf(callback);
if (index !== -1) {
this.callbacks[entity].splice(index, 1);
}
}
/**
* 触发回调
* @param {string} operation - 操作类型('add', 'update', 'delete')
* @param {string} entity - 实体类型单数性质
* @param {Object} data - 相关数据
*/
triggerCallbacks(operation, entity, data) {
// 触发全局回调
this.callbacks.all.forEach(cb => cb(operation, entity, data));
// 触发特定实体回调
if (this.callbacks[entity]) {
this.callbacks[entity].forEach(cb => cb(operation, data));
}
}
/**
* 执行CRUD操作并触发回调
*/
async crudOperation(operation, entity, data) {
try {
const response = await fetch(`${this.baseUrl}/app/${operation}/${entity}`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Network response was not ok');
const result = await response.json();
if (result.status !== 200) throw new Error(result.text || 'API error');
// 触发操作成功的回调
this.triggerCallbacks(operation, entity, data);
// 自动同步数据
this.syncData();
return result;
} catch (error) {
console.error('CRUD error:', error);
// 触发操作失败的回调
this.triggerCallbacks(`${operation}_error`, entity, {
data,
error: error.message
});
throw error;
}
}
/**
* 执行CRUD操作
* @param {string} operation - 'add', 'delete', 'update'
* @param {string} entity - 实体名称单数性质(小写)
* @param {Object} data - 要发送的数据 后端要求数据格式为{属性: "值", 关联对象: {id:0}, 关联对象集: [{id:0}]}
* @returns {Promise<Object>} 响应结果
*/
async crudOperation(operation, entity, data) {
try {
const response = await fetch(`${this.baseUrl}/app/${operation}/${entity}`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Network response was not ok');
const result = await response.json();
if (result.status !== 200) throw new Error(result.text || 'API error');
// 触发操作成功的回调
this.triggerCallbacks(operation, entity, data);
// 自动同步数据
this.syncData();
return result;
} catch (error) {
console.error('CRUD error:', error);
// 触发操作失败的回调
this.triggerCallbacks(`${operation}_error`, entity, {
data,
error: error.message
});
throw error;
}
}
/**
* 自动同步数据(防止频繁请求)
*/
async syncData() {
if (this.isSyncing) return;
// 距离上次同步超过5秒才执行新同步
if (this.lastSync && new Date() - this.lastSync < 5000) {
setTimeout(() => this.syncData(), 5000 - (new Date() - this.lastSync));
return;
}
this.isSyncing = true;
try {
await this.fetchAll();
} finally {
this.isSyncing = false;
}
}
/**
* 添加实体
* @param {string} entity - 实体名称单数性质
* @param {Object} data - 实体数据
*/
async addEntity(entity, data) {
return this.crudOperation('add', entity, data);
}
/**
* 更新实体
* @param {string} entity - 实体名称单数性质
* @param {Object} data - 实体数据(必须包含id)
*/
async updateEntity(entity, data) {
return this.crudOperation('update', entity, data);
}
/**
* 删除实体
* @param {string} entity - 实体名称单数性质
* @param {number} id - 实体ID
*/
async deleteEntity(entity, id) {
return this.crudOperation('delete', entity, {id});
}
}
export { DataManager };
// 创建单例实例
//const dataManager = new DataManager('http://127.0.0.1:8080/KuCun2');
//// 初始化时获取所有数据
//dataManager.fetchAll().then(() => {
// console.log('Initial data loaded');
//});
// 导出数据对象,外部可以直接访问 data.bancais, data.dingdans 等
//export const data = dataManager.data;
//// 导出操作方法
//export const addEntity = dataManager.addEntity.bind(dataManager);
//export const updateEntity = dataManager.updateEntity.bind(dataManager);
//export const deleteEntity = dataManager.deleteEntity.bind(dataManager);
//export const fetchAll = dataManager.fetchAll.bind(dataManager);监控数据变化触发回调,不是后台回调触发
最新发布