H1-H10 优化OCR实时体验闭环
这个提交包含在:
@@ -0,0 +1,104 @@
|
||||
const { EventEmitter } = require("node:events");
|
||||
|
||||
function uniqueStrings(values) {
|
||||
return Array.from(
|
||||
new Set(
|
||||
(Array.isArray(values) ? values : [])
|
||||
.map((value) => (typeof value === "string" ? value.trim() : ""))
|
||||
.filter(Boolean),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function createAppEventBus() {
|
||||
const emitter = new EventEmitter();
|
||||
emitter.setMaxListeners(500);
|
||||
let sequence = 0;
|
||||
|
||||
return {
|
||||
publish(event) {
|
||||
const payload = {
|
||||
id: `${Date.now()}-${++sequence}`,
|
||||
createdAt: new Date().toISOString(),
|
||||
...event,
|
||||
audienceEmployeeIds: uniqueStrings(event?.audienceEmployeeIds),
|
||||
};
|
||||
emitter.emit("event", payload);
|
||||
return payload;
|
||||
},
|
||||
subscribe(handler) {
|
||||
emitter.on("event", handler);
|
||||
return () => emitter.off("event", handler);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildInvoiceUpdatedEvent({
|
||||
invoiceId,
|
||||
status,
|
||||
updatedAt = null,
|
||||
audienceEmployeeIds = [],
|
||||
}) {
|
||||
return {
|
||||
type: "invoice.updated",
|
||||
invoiceId,
|
||||
status,
|
||||
updatedAt: updatedAt ?? new Date().toISOString(),
|
||||
audienceEmployeeIds: uniqueStrings(audienceEmployeeIds),
|
||||
};
|
||||
}
|
||||
|
||||
function publishInvoiceUpdated(fastify, event) {
|
||||
if (!fastify?.appEvents || typeof fastify.appEvents.publish !== "function") {
|
||||
return null;
|
||||
}
|
||||
return fastify.appEvents.publish(buildInvoiceUpdatedEvent(event));
|
||||
}
|
||||
|
||||
function canReceiveEvent(employee, event, options = {}) {
|
||||
if (!employee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event?.type === "invoice.updated" && options.canManageInvoice) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const audience = uniqueStrings(event?.audienceEmployeeIds);
|
||||
if (!audience.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return audience.includes(employee.id);
|
||||
}
|
||||
|
||||
function toClientEvent(event) {
|
||||
if (!event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (event.type === "invoice.updated") {
|
||||
return {
|
||||
id: event.id,
|
||||
type: event.type,
|
||||
invoiceId: event.invoiceId,
|
||||
status: event.status ?? null,
|
||||
updatedAt: event.updatedAt ?? event.createdAt ?? null,
|
||||
createdAt: event.createdAt ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
id: event.id,
|
||||
type: event.type,
|
||||
createdAt: event.createdAt ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildInvoiceUpdatedEvent,
|
||||
canReceiveEvent,
|
||||
createAppEventBus,
|
||||
publishInvoiceUpdated,
|
||||
toClientEvent,
|
||||
};
|
||||
在新工单中引用
屏蔽一个用户