| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- const fs = require('fs');
- const path = require('path');
- const { categoryDir, latestPath } = require('./output-paths');
- function devicesDir() {
- return categoryDir('devices');
- }
- function deviceFilePath(guid) {
- return path.join(devicesDir(), `${guid}.json`);
- }
- function safeReadJson(filePath, fallback = null) {
- try {
- if (!filePath || !fs.existsSync(filePath)) return fallback;
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
- } catch {
- return fallback;
- }
- }
- function atomicWriteJson(filePath, data) {
- const dir = path.dirname(filePath);
- fs.mkdirSync(dir, { recursive: true });
- const tmpPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`;
- try {
- fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), 'utf8');
- fs.renameSync(tmpPath, filePath);
- } catch (err) {
- try { fs.unlinkSync(tmpPath); } catch {}
- throw err;
- }
- return filePath;
- }
- function readDeviceBrokerMapping() {
- const dir = devicesDir();
- if (!fs.existsSync(dir)) return {};
- const mapping = {};
- for (const file of fs.readdirSync(dir)) {
- if (!file.endsWith('.json')) continue;
- const guid = file.replace(/\.json$/, '');
- const data = safeReadJson(path.join(dir, file));
- if (data && data.guid) {
- mapping[data.guid] = data;
- } else if (data) {
- mapping[guid] = { ...data, guid };
- }
- }
- return mapping;
- }
- function writeDeviceBrokerMapping(mapping) {
- const dir = devicesDir();
- fs.mkdirSync(dir, { recursive: true });
- for (const [guid, record] of Object.entries(mapping)) {
- atomicWriteJson(deviceFilePath(guid), { ...record, guid });
- }
- return dir;
- }
- function resolveBrokerIdForGuid(guid) {
- if (!guid) return null;
- const record = safeReadJson(deviceFilePath(guid));
- return record && record.brokerId ? record.brokerId : null;
- }
- function resolveWecomUserIdForGuid(guid) {
- if (!guid) return null;
- const record = safeReadJson(deviceFilePath(guid));
- return record && record.wecomUserId ? record.wecomUserId : null;
- }
- function resolveBrokerIdForWecomUserId(wecomUserId) {
- if (!wecomUserId) return null;
- const mapping = readDeviceBrokerMapping();
- for (const record of Object.values(mapping)) {
- if (record.wecomUserId === wecomUserId && record.brokerId) {
- return record.brokerId;
- }
- }
- return null;
- }
- function resolveWecomUserIdForBrokerId(brokerId) {
- if (!brokerId) return null;
- const mapping = readDeviceBrokerMapping();
- for (const record of Object.values(mapping)) {
- if (record.brokerId === brokerId && record.wecomUserId) {
- return record.wecomUserId;
- }
- }
- return null;
- }
- function recordDeviceGuid(guid, detail = {}) {
- if (!guid) return null;
- const filePath = deviceFilePath(guid);
- const existing = safeReadJson(filePath) || {};
- const record = {
- ...existing,
- guid,
- wecomUserId: detail.wecomUserId || existing.wecomUserId || undefined,
- nickname: detail.nickname || existing.nickname || undefined,
- brokerId: detail.brokerId || existing.brokerId || undefined,
- recordedAt: existing.recordedAt || new Date().toISOString()
- };
- if (detail.wecomUserId || detail.nickname || detail.brokerId) {
- record.updatedAt = new Date().toISOString();
- }
- atomicWriteJson(filePath, record);
- return record;
- }
- function bindBrokerToGuid(guid, brokerId) {
- if (!guid) return null;
- return recordDeviceGuid(guid, { brokerId });
- }
- module.exports = {
- readDeviceBrokerMapping,
- writeDeviceBrokerMapping,
- resolveBrokerIdForGuid,
- resolveWecomUserIdForGuid,
- resolveBrokerIdForWecomUserId,
- resolveWecomUserIdForBrokerId,
- recordDeviceGuid,
- bindBrokerToGuid,
- deviceFilePath
- };
|