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){ console.log(entity);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); 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;----------------
if (entity.__isProxy){ console.log(entity);return entity;}这里面输出的.有__isProxy属性,但没有一个是代理类型的,输出里面分的清------------{shuliang: 14, bancai: {…}, id: 41, lastUpdated: “2025-07-02T11:54:16.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 15, bancai: {…}, id: 42, lastUpdated: “2025-07-02T11:54:43.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 55, bancai: {…}, id: 43, lastUpdated: “2025-07-02T12:52:09.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 17, bancai: {…}, id: 44, lastUpdated: “2025-07-02T12:52:39.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 48, bancai: {…}, id: 45, lastUpdated: “2025-07-02T11:57:27.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 20, bancai: {…}, id: 46, lastUpdated: “2025-07-02T11:57:48.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 51, bancai: {…}, id: 47, lastUpdated: “2025-07-24T15:57:11.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 7, bancai: {…}, id: 49, lastUpdated: “2025-07-03T03:38:24.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 17, bancai: {…}, id: 53, lastUpdated: “2025-07-02T13:14:51.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 31, bancai: {…}, id: 54, lastUpdated: “2025-07-03T02:09:29.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 32, bancai: {…}, id: 55, lastUpdated: “2025-07-02T13:16:39.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 66, bancai: {…}, id: 56, lastUpdated: “2025-07-02T13:17:01.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 42, bancai: {…}, id: 57, lastUpdated: “2025-07-02T13:17:46.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 70, bancai: {…}, id: 58, lastUpdated: “2025-07-02T13:18:02.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 6, bancai: {…}, id: 59, lastUpdated: “2025-07-02T13:17:23.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 24, bancai: {…}, id: 60, lastUpdated: “2025-07-03T02:09:54.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 9, bancai: {…}, id: 68, lastUpdated: “2025-07-03T02:11:24.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 15, bancai: {…}, id: 70, lastUpdated: “2025-07-03T02:12:03.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 56, bancai: {…}, id: 72, lastUpdated: “2025-07-03T03:30:27.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 56, bancai: null, id: 74, lastUpdated: “2025-07-03T03:30:58.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 22, bancai: {…}, id: 76, lastUpdated: “2025-07-24T16:29:28.000+00:00”, deleted: false, …}
index.js? [sm]:124 undefined
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 200, id: 5, lastUpdated: “2025-07-01T07:41:38.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 220, id: 6, lastUpdated: “2025-07-01T12:30:48.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 200, id: 7, lastUpdated: “2025-07-01T12:35:02.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 300, id: 8, lastUpdated: “2025-07-01T12:37:58.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 40, id: 9, lastUpdated: “2025-07-01T12:43:26.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 1, id: 10, lastUpdated: “2025-07-01T15:03:30.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 1, id: 11, lastUpdated: “2025-07-01T15:05:22.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 1, id: 12, lastUpdated: “2025-07-01T15:05:29.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 200, id: 13, lastUpdated: “2025-07-02T12:45:01.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 30, id: 14, lastUpdated: “2025-07-02T12:56:20.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 500, id: 15, lastUpdated: “2025-07-02T13:05:53.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 500, id: 16, lastUpdated: “2025-07-02T13:06:30.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 500, id: 17, lastUpdated: “2025-07-02T13:19:41.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 200, id: 32, lastUpdated: “2025-07-03T02:08:44.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {dingdan: {…}, chanpin: {…}, shuliang: 5000, id: 33, lastUpdated: “2025-07-03T03:25:03.000+00:00”, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 72, bancai: {…}, id: 2, lastUpdated: “2025-07-02T12:49:30.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 42, bancai: {…}, id: 3, lastUpdated: “2025-07-02T12:49:54.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 6, bancai: {…}, id: 4, lastUpdated: “2025-07-01T12:53:36.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 52, bancai: {…}, id: 6, lastUpdated: “2025-07-02T13:16:15.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 69, bancai: {…}, id: 8, lastUpdated: “2025-07-03T03:27:48.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 73, bancai: {…}, id: 11, lastUpdated: “2025-07-02T12:50:33.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 15, bancai: {…}, id: 12, lastUpdated: “2025-07-01T12:52:12.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 14, bancai: {…}, id: 29, lastUpdated: “2025-07-02T11:39:00.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 9, bancai: {…}, id: 31, lastUpdated: “2025-07-02T11:40:49.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 28, bancai: {…}, id: 33, lastUpdated: “2025-07-02T12:51:06.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 48, bancai: {…}, id: 37, lastUpdated: “2025-07-02T12:51:36.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 4, bancai: {…}, id: 38, lastUpdated: “2025-07-02T11:47:50.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 18, bancai: {…}, id: 39, lastUpdated: “2025-07-02T11:48:23.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 12, bancai: {…}, id: 40, lastUpdated: “2025-07-02T11:48:55.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 14, bancai: {…}, id: 41, lastUpdated: “2025-07-02T11:54:16.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 15, bancai: {…}, id: 42, lastUpdated: “2025-07-02T11:54:43.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 55, bancai: {…}, id: 43, lastUpdated: “2025-07-02T12:52:09.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 17, bancai: {…}, id: 44, lastUpdated: “2025-07-02T12:52:39.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 48, bancai: {…}, id: 45, lastUpdated: “2025-07-02T11:57:27.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 20, bancai: {…}, id: 46, lastUpdated: “2025-07-02T11:57:48.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 51, bancai: {…}, id: 47, lastUpdated: “2025-07-24T15:57:11.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 7, bancai: {…}, id: 49, lastUpdated: “2025-07-03T03:38:24.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 17, bancai: {…}, id: 53, lastUpdated: “2025-07-02T13:14:51.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 31, bancai: {…}, id: 54, lastUpdated: “2025-07-03T02:09:29.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 32, bancai: {…}, id: 55, lastUpdated: “2025-07-02T13:16:39.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 66, bancai: {…}, id: 56, lastUpdated: “2025-07-02T13:17:01.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 42, bancai: {…}, id: 57, lastUpdated: “2025-07-02T13:17:46.000+00:00”, deleted: false, …}
MiniProgramDataManager.js? [sm]:70 {shuliang: 70, bancai: {…}, id: 58, lastUpdated: “2025-07-02T13:18:02.000+00:00”, deleted: false, …}
最新发布