@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
328 lines (326 loc) • 10.3 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/server/modules/floor-plan/index.ts
var floor_plan_exports = {};
__export(floor_plan_exports, {
FloorPlanModule: () => FloorPlanModule
});
module.exports = __toCommonJS(floor_plan_exports);
var import_BaseModule = require("../../../modules/BaseModule");
var import_types = require("./types");
var FLOOR_PLAN_SYNC_DEBOUNCE_MS = 3e3;
var FloorPlanModule = class extends import_BaseModule.BaseModule {
constructor(name, version) {
super(name, version);
this.defaultName = "floor_plan";
this.defaultVersion = "1.0.0";
this.pendingSyncMessages = [];
}
async initialize(core, options) {
var _a;
this.core = core;
this.store = options.store;
if (Array.isArray((_a = options == null ? void 0 : options.initialState) == null ? void 0 : _a.list) && options.initialState.list.length > 0) {
this.store.list = options.initialState.list;
this.syncMaps();
this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.store.list);
} else {
this.store.list = [];
this.store.map = /* @__PURE__ */ new Map();
this.store.codeMap = /* @__PURE__ */ new Map();
}
this.request = core.getPlugin("request");
const appPlugin = core.getPlugin("app");
if (appPlugin) {
const app = appPlugin.getApp();
this.logger = app.logger;
}
this.initFloorPlanDataSource();
this.setupFloorPlanSync();
}
logInfo(title, metadata) {
var _a, _b;
try {
(_b = (_a = this.logger) == null ? void 0 : _a.addLog) == null ? void 0 : _b.call(_a, {
type: "info",
title: `[FloorPlanModule] ${title}`,
metadata: metadata || {}
});
} catch {
}
}
logWarning(title, metadata) {
var _a, _b;
try {
(_b = (_a = this.logger) == null ? void 0 : _a.addLog) == null ? void 0 : _b.call(_a, {
type: "warning",
title: `[FloorPlanModule] ${title}`,
metadata: metadata || {}
});
} catch {
}
}
logError(title, metadata) {
var _a, _b;
try {
(_b = (_a = this.logger) == null ? void 0 : _a.addLog) == null ? void 0 : _b.call(_a, {
type: "error",
title: `[FloorPlanModule] ${title}`,
metadata: metadata || {}
});
} catch {
}
}
idKey(id) {
return String(id);
}
syncMaps() {
this.store.map = /* @__PURE__ */ new Map();
this.store.codeMap = /* @__PURE__ */ new Map();
for (const item of this.store.list) {
if ((item == null ? void 0 : item.id) == null)
continue;
const key = this.idKey(item.id);
this.store.map.set(key, item);
if (item.code) {
this.store.codeMap.set(String(item.code), item);
}
}
}
/** 与接口约定一致:sort 升序,id 降序 */
getSortedList() {
return [...this.store.list].sort((a, b) => {
const sortDiff = Number(a.sort ?? 0) - Number(b.sort ?? 0);
if (sortDiff !== 0)
return sortDiff;
return Number(b.id) - Number(a.id);
});
}
getById(id) {
return this.store.map.get(this.idKey(id));
}
getByCode(code) {
return this.store.codeMap.get(String(code));
}
replaceStore(list) {
this.store.list = list.map((i) => ({ ...i }));
this.syncMaps();
}
mergeItems(items) {
if (items.length === 0)
return;
const byId = new Map(this.store.map);
for (const item of items) {
if ((item == null ? void 0 : item.id) == null)
continue;
byId.set(this.idKey(item.id), { ...item });
}
this.store.list = Array.from(byId.values());
this.syncMaps();
}
removeByIds(ids) {
if (ids.length === 0)
return;
const set = new Set(ids.map((id) => this.idKey(id)));
this.store.list = this.store.list.filter((p) => !set.has(this.idKey(p.id)));
this.syncMaps();
}
async loadListFromServer() {
try {
const res = await this.request.get(
`/schedule/floor-plan`,
{},
{ isShopApi: true }
);
const body = res;
const raw = (body == null ? void 0 : body.data) !== void 0 ? body.data : body;
const list = Array.isArray(raw) ? raw : [];
return list;
} catch (e) {
this.logWarning("loadListFromServer 失败", {
error: e instanceof Error ? e.message : String(e)
});
return [];
}
}
async fetchByIdFromServer(id) {
try {
const res = await this.request.get(
`/schedule/floor-plan/${id}`,
{},
{ isShopApi: true }
);
const body = res;
const data = (body == null ? void 0 : body.data) !== void 0 ? body.data : body;
return data && typeof data === "object" ? data : null;
} catch {
return null;
}
}
async fetchByCodeFromServer(code) {
try {
const enc = encodeURIComponent(code);
const res = await this.request.get(
`/schedule/floor-plan/code/${enc}`,
{},
{ isShopApi: true }
);
const body = res;
const data = (body == null ? void 0 : body.data) !== void 0 ? body.data : body;
return data && typeof data === "object" ? data : null;
} catch {
return null;
}
}
async preload() {
this.logInfo("开始预加载平面图列表");
const list = await this.loadListFromServer();
if (list.length > 0) {
this.replaceStore(list);
this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.getSortedList());
this.logInfo("预加载完成", { count: list.length });
} else {
this.logWarning("预加载完成但列表为空");
}
}
initFloorPlanDataSource() {
var _a, _b;
const Ctor = (_b = (_a = this.core.serverOptions) == null ? void 0 : _a.All_DATA_SOURCES) == null ? void 0 : _b.FloorPlanDataSource;
if (!Ctor) {
this.logWarning("FloorPlanDataSource 不可用,跳过 pubsub 同步");
return;
}
this.floorPlanDataSource = new Ctor();
this.logInfo("FloorPlanDataSource 实例已创建");
}
setupFloorPlanSync() {
if (!this.floorPlanDataSource)
return;
const flush = () => {
if (this.syncTimer)
clearTimeout(this.syncTimer);
this.syncTimer = setTimeout(() => {
this.processFloorPlanSyncMessages();
}, FLOOR_PLAN_SYNC_DEBOUNCE_MS);
};
this.floorPlanDataSource.run({
pubsub: {
callback: (res) => {
const data = (res == null ? void 0 : res.data) || res;
if (!data || data.module !== "floor_plan")
return;
this.pendingSyncMessages.push({ ...data });
flush();
}
}
}).catch((err) => {
this.logError("setupFloorPlanSync: DataSource run 出错", {
error: err instanceof Error ? err.message : String(err)
});
});
this.logInfo("floor_plan pubsub 订阅已建立");
}
async processFloorPlanSyncMessages() {
var _a, _b;
const messages = [...this.pendingSyncMessages];
this.pendingSyncMessages = [];
if (messages.length === 0)
return;
this.logInfo("processFloorPlanSyncMessages 开始", { count: messages.length });
let changed = false;
const deleteIds = [];
const bodyItems = [];
let needFullList = false;
const partialIds = /* @__PURE__ */ new Set();
for (const msg of messages) {
if (msg.operation === "delete" || msg.action === "delete") {
if ((_a = msg.ids) == null ? void 0 : _a.length) {
deleteIds.push(...msg.ids);
} else if (msg.id != null) {
deleteIds.push(msg.id);
}
continue;
}
const body = msg.body;
const hasBody = body && typeof body === "object" && Object.keys(body).length > 0 && body.id != null;
if (hasBody) {
bodyItems.push(body);
continue;
}
if (msg.ids && msg.ids.length > 1) {
needFullList = true;
continue;
}
if (((_b = msg.ids) == null ? void 0 : _b.length) === 1) {
partialIds.add(msg.ids[0]);
} else if (msg.id != null) {
partialIds.add(msg.id);
}
}
const uniqueDeletes = [...new Set(deleteIds)];
if (uniqueDeletes.length > 0) {
this.removeByIds(uniqueDeletes);
changed = true;
}
if (bodyItems.length > 0) {
this.mergeItems(bodyItems);
changed = true;
}
if (needFullList) {
const list = await this.loadListFromServer();
this.replaceStore(list);
changed = true;
} else if (partialIds.size > 0) {
const fetched = [];
for (const id of partialIds) {
const one = await this.fetchByIdFromServer(id);
if (one)
fetched.push(one);
}
if (fetched.length > 0) {
this.mergeItems(fetched);
changed = true;
}
}
if (changed) {
this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.getSortedList());
this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlanSyncCompleted, null);
}
}
async clear() {
this.store.list = [];
this.store.map.clear();
this.store.codeMap.clear();
}
destroy() {
var _a;
if (this.syncTimer) {
clearTimeout(this.syncTimer);
this.syncTimer = void 0;
}
this.pendingSyncMessages = [];
if ((_a = this.floorPlanDataSource) == null ? void 0 : _a.destroy) {
this.floorPlanDataSource.destroy();
}
super.destroy();
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
FloorPlanModule
});