class LazyLoader {
constructor(dataManager) {
this.dataManager = dataManager;
this.cache = new Map();
this.entityTypeMap = {
bancai: ‘bancais’,
dingdan: ‘dingdans’,
mupi: ‘mupis’,
chanpin: ‘chanpins’,
kucun: ‘kucuns’,
dingdan_bancai: ‘dingdan_bancais’,
chanpin_zujian: ‘chanpin_zujians’,
zujian: ‘zujians’,
caizhi: ‘caizhis’,
dingdan_chanpin: ‘dingdan_chanpins’,
user: ‘users’,
jinhuo: ‘jinhuos’
};
this.r=true;this.t=true;this.y=true;
}
createProxy(entity, entityType) {
// 1. 优先检查缓存
const cacheKey = ${entityType}_${entity.id};
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
// 2. 代理检测简化 const handler = { get: (target, prop, receiver) => { // 特殊属性处理 if (prop === 'id') return target.id; const value = Reflect.get(target, prop, receiver); target[prop]=value; // 基本类型直接返回 if (typeof value !== 'object' || value === null) { return value; } // 处理数组引用 if (Array.isArray(value)) { const refType = this.getReferenceType(prop); target[prop]= refType ? this.loadReferences(value, refType) : value; } // 处理对象引用 const refType = this.getReferenceType(prop); if (refType) { //console.log(refType) target[prop]= this.loadReference(value, refType); } // 普通对象:检查是否需要创建嵌套代理 if (!value.__isProxy) { // 创建嵌套对象的代理 target[prop]=this.createProxy(value, this.getEntityTypeFromRef(prop)); } return target[prop]; } }; if (entity.__isProxy){ return entity;} const proxy = new Proxy(entity, handler); proxy.__isProxy = true; // 3. 创建后立即缓存 this.cache.set(cacheKey, proxy); return proxy;
}
getEntityTypeFromRef(prop) {
const baseProp = prop.replace(/\d/g, ‘’);
return baseProp in this.entityTypeMap ?
this.entityTypeMap[baseProp] :
${baseProp}s;
}
getReferenceType(prop) {
const baseProp = prop.replace(/\d/g, ‘’);
if (this.entityTypeMap[baseProp]) return this.entityTypeMap[baseProp];
const pluralProp = `${baseProp}s`; if (this.dataManager._rawData[pluralProp]) return pluralProp; return null;
}
loadReference(ref, refType) {
if (!ref?.id)
const cacheKey = `${refType}_${ref.id}`; // 4. 统一使用缓存机制 if (this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } const entities = this.dataManager._rawData[refType] || []; const entity = entities.find(e => e.id === ref.id); if (!entity) { console.warn(`Entity not found: ${refType} with id ${ref.id}`); return ref; } // 5. 使用createProxy确保代理一致性 const prosty= this.createProxy(entity, refType); console.log(prosty) return prosty
}
loadReferences(refs, refType) {
return refs.map(ref => this.loadReference(ref, refType));
}
resolveReferences(entity) {
for (const attr in entity) {
const refType = this.getReferenceType(attr);
if (!refType) continue;
if (Array.isArray(entity[attr])) { entity[attr] = entity[attr].map(item => this.dataManager._rawData[refType]?.find(e => e.id === item.id) || item ); } else if (entity[attr]?.id) { entity[attr] = this.dataManager._rawData[refType]?.find(e => e.id === entity[attr].id) || entity[attr]; } } return entity;
}
clearCache() {
this.cache.clear();
}
}
class MiniProgramDataManager {
constructor(baseUrl = ‘’) {
this.baseUrl = baseUrl;
this.debug = true;
this.networkAvailable = false;
this.isSyncing = false;
this.lastSync = null;
this.syncInterval = 5 * 60 * 1000;
this.storageKey = ‘miniProgramData’;
this._rawData = this.createEmptyData(); this.lazyLoader = new LazyLoader(this); this.callbacks = { all: [], bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], chanpin_zujians: [], dingdan_bancais: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [] }; this.initNetwork(); this.loadDataFromStorage(); this.startAutoSync();
}
createEmptyData() {
return {
bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [],
dingdan_bancais: [], chanpin_zujians: [], zujians: [], caizhis: [],
dingdan_chanpins: [], users: [], jinhuos: [],
_lastModified: null, _lastSync: null
};
}
get data() {
const handler = {
get: (target, prop) => {
if (prop.startsWith(‘_’)) return target[prop];
if (Array.isArray(target[prop])) {
return target[prop].map(item =>
this.lazyLoader.createProxy(item, prop.replace(/s$/, ‘’))
);
}
return target[prop];
},
set: (target, prop, value) => {
target[prop] = value;
return true;
}
};
return new Proxy(this._rawData, handler);
}
async initialize() {
try {
await this.syncData();
return true;
} catch (error) {
if (this._rawData._lastSync) return true;
throw error;
}
}
startAutoSync() {
this.autoSyncTimer = setInterval(() => {
!this.isSyncing && this.syncData();
}, this.syncInterval);
}
stopAutoSync() {
clearInterval(this.autoSyncTimer);
}
async initNetwork() {
try {
const { networkType } = await wx.getNetworkType();
this.networkAvailable = networkType !== ‘none’;
} catch {
this.networkAvailable = false;
}
}
async syncData() {
if (this.isSyncing) return;
this.isSyncing = true;
try { const since = this._rawData._lastSync; await this.fetchAll(since); this.lazyLoader.clearCache(); this.saveDataToStorage(); this.triggerCallbacks('refresh', 'all', this.data); } catch (error) { console.error('Sync failed:', error); this.triggerCallbacks('sync_error', 'all', { error }); if (!this._rawData._lastSync) throw error; } finally { this.isSyncing = false; }
}
async fetchAll(since) {
try {
const params = since ? { since } : {};
const resolvedData = this.baseUrl
? await this.request(‘/app/all’, ‘GET’, params)
: this.createEmptyData();
Object.keys(this._rawData).forEach(key => { if (key.startsWith('_') || !resolvedData[key]) return; if (since) { resolvedData[key].forEach(newItem => { const index = this._rawData[key].findIndex(item => item.id === newItem.id); index >= 0 ? this._rawData[key][index] = newItem : this._rawData[key].push(newItem); }); } else { this._rawData[key] = resolvedData[key]; } }); this._rawData._lastSync = new Date().toISOString(); this.saveDataToStorage(); return true; } catch (error) { console.error('Fetch error:', error); this.triggerCallbacks('fetch_error', 'all', { error }); throw error; }
}
async request(url, method, data, retryCount = 3) {
return new Promise((resolve, reject) => {
const fullUrl = ${this.baseUrl}${url};
const requestTask = () => { wx.request({ url: fullUrl, method, data, header: { 'Content-Type': 'application/json' }, success: (res) => { if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data.data); } else { const err = new Error(res.data?.message || 'API error'); retryCount > 1 ? setTimeout(requestTask, 1000, retryCount - 1) : reject(err); } }, fail: (err) => { retryCount > 1 ? setTimeout(requestTask, 1000, retryCount - 1) : reject(new Error(`Network error: ${err.errMsg}`)); } }); }; requestTask(); });
}
registerCallback(entity, callback) {
this.callbacks[entity]?.push(callback) || this.callbacks.all.push(callback);
}
unregisterCallback(entity, callback) {
const arr = this.callbacks[entity] || this.callbacks.all;
const index = arr.indexOf(callback);
if (index !== -1) arr.splice(index, 1);
}
triggerCallbacks(operation, entity, data) {
this.callbacks.all.forEach(cb => cb(operation, entity, data));
this.callbacks[entity]?.forEach(cb => cb(operation, data));
}
async crudOperation(operation, entity, data) {
try {
const result = await this.request(/app/${operation}/${entity}, ‘POST’, data);
this.updateLocalData(operation, entity, result || data);
this.triggerCallbacks(operation, entity, result || data);
return result;
} catch (error) {
this.triggerCallbacks(${operation}_error, entity, { data, error });
throw error;
}
}
updateLocalData(operation, entity, data) {
const key = ${entity}s;
const collection = this._rawData[key] || [];
switch (operation) { case 'add': collection.push(data); break; case 'update': const index = collection.findIndex(item => item.id === data.id); index >= 0 ? collection[index] = data : collection.push(data); break; case 'delete': const deleteIndex = collection.findIndex(item => item.id === data.id); if (deleteIndex >= 0) collection.splice(deleteIndex, 1); break; } this._rawData._lastModified = new Date().toISOString(); this.lazyLoader.clearCache(); this.saveDataToStorage();
}
loadDataFromStorage() {
try {
const storedData = wx.getStorageSync(this.storageKey);
if (storedData) this._rawData = storedData;
} catch (error) {
console.error(‘Storage load error:’, error);
}
}
saveDataToStorage() {
try {
wx.setStorageSync(this.storageKey, this._rawData);
} catch (error) {
console.error(‘Storage save error:’, error);
wx.showToast({ title: ‘数据保存失败’, icon: ‘none’ });
}
}
async addEntity(entity, data) {
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) {
try {
await this.request(/app/Transactional/${endpoint}, ‘POST’, data);
await this.syncData();
return true;
} catch (error) {
this.triggerCallbacks(‘transaction_error’, endpoint, { data, error });
throw error;
}
}
}
module.exports = MiniProgramDataManager;----------------------------------------------------------------------------------
const prosty= this.createProxy(entity, refType);
console.log(prosty)/*这段输出有的是代理的有的不是/
return prosty------------------------------------------------{number: "2025-31", xiadan: "2025-06-28T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(0), id: 1, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}caizhi: {id: 1}deleted: falsedeletedAt: nullhoudu: 15id: 1kucun: nulllastUpdated: "2025-06-29T19:58:31.000+00:00"mupi1: {id: 1}mupi2: {id: 1}__isProxy: true__proto__: Object
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(2), bianhao: "AN-1210", chanpin_zujian: Array(1), id: 1, lastUpdated: "2025-06-29T19:58:34.000+00:00", …}
MiniProgramDataManager.js? [sm]:117 Proxy {name: "侧板", chanping_zujian: Array(3), id: 1, lastUpdated: "2025-06-29T19:58:38.000+00:00", deleted: false, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {number: "2025-034", xiadan: "2025-07-01T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(5), id: 3, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-33", xiadan: null, jiaohuo: null, dingdan_chanpin: Array(3), id: 2, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-034增加单", xiadan: "2025-07-02T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(1), id: 4, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-031", xiadan: "2025-07-02T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(1), id: 5, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-036", xiadan: "2025-06-13T00:00:00.000+00:00", jiaohuo: "2025-07-13T00:00:00.000+00:00", dingdan_chanpin: Array(2), id: 6, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-037", xiadan: "2025-06-16T00:00:00.000+00:00", jiaohuo: "2025-07-16T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 7, …}
MiniProgramDataManager.js? [sm]:117 {number: "2025-038", xiadan: "2025-06-17T00:00:00.000+00:00", jiaohuo: "2025-08-17T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 8, …}
MiniProgramDataManager.js? [sm]:117 {number: "梦5", xiadan: "2025-07-03T00:00:00.000+00:00", jiaohuo: "2025-08-03T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 44, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 3, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 3, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 3, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 5, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 5, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 12, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 18, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 18, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 Proxy {bancai: Array(34), name: "纤维板", id: 1, lastUpdated: "2025-06-29T19:58:33.000+00:00", deleted: false, …}
MiniProgramDataManager.js? [sm]:117 Proxy {you: true, name: "桃花心", bancaisForMupi1: Array(10), bancaisForMupi2: Array(4), id: 1, …}
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(2), bianhao: "AN-1140", chanpin_zujian: Array(1), id: 3, lastUpdated: "2025-07-01T07:39:46.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(2), bianhao: "AN-1133", chanpin_zujian: Array(0), id: 4, lastUpdated: "2025-07-01T12:30:30.000+00:00", …}
2index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1157", chanpin_zujian: Array(0), id: 5, lastUpdated: "2025-07-01T12:34:49.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1159", chanpin_zujian: Array(0), id: 6, lastUpdated: "2025-07-01T12:37:35.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1212", chanpin_zujian: Array(0), id: 7, lastUpdated: "2025-07-01T12:43:09.000+00:00", …}
31index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 3, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1081-H", chanpin_zujian: Array(0), id: 8, lastUpdated: "2025-07-02T13:05:30.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 Proxy {you: false, name: "无", bancaisForMupi1: Array(0), bancaisForMupi2: Array(5), id: 3, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 5, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AP-1109-H", chanpin_zujian: Array(0), id: 9, lastUpdated: "2025-07-02T13:06:11.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 Proxy {you: false, name: "香杉", bancaisForMupi1: Array(7), bancaisForMupi2: Array(0), id: 4, …}
MiniProgramDataManager.js? [sm]:117 Proxy {you: false, name: "桃花芯", bancaisForMupi1: Array(16), bancaisForMupi2: Array(11), id: 2, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 18, kucun: null, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 5, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 12, kucun: null, …}
2index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 6, kucun: null, …}
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AP-1278", chanpin_zujian: Array(0), id: 10, lastUpdated: "2025-07-02T13:19:23.000+00:00", …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 Proxy {you: false, name: "杂皮", bancaisForMupi1: Array(0), bancaisForMupi2: Array(6), id: 5, …}
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AP-1271", chanpin_zujian: Array(0), id: 11, lastUpdated: "2025-07-02T13:23:57.000+00:00", …}
2index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 9, kucun: null, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 Proxy {you: true, name: "杂皮20C", bancaisForMupi1: Array(0), bancaisForMupi2: Array(4), id: 7, …}
MiniProgramDataManager.js? [sm]:117 {caizhi: {…}, mupi1: {…}, mupi2: {…}, houdu: 15, kucun: null, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1032", chanpin_zujian: Array(1), id: 13, lastUpdated: "2025-07-03T03:24:33.000+00:00", …}
MiniProgramDataManager.js? [sm]:117 Proxy {name: "底板", chanping_zujian: Array(1), id: 2, lastUpdated: "2025-07-03T03:25:49.000+00:00", deleted: false, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:117 {dingdan_chanpin: Array(1), bianhao: "AN-1208", chanpin_zujian: Array(1), id: 2, lastUpdated: "2025-06-30T07:09:34.000+00:00", …}
材质名字都是空的
最新发布