const { formatExportStamp, isCancelError, loadSelectedFile, saveTextFileToChat } = require('../../repositories/file.js') const { getWxApi, pickFields } = require('../../utils/base-utils.js') const { cloneImportedGroup, getRegisterJsonValue } = require('../../domain/parameter-groups/model.js') const { SOURCE_GROUP_FIELDS, SOURCE_REGISTER_FIELDS, STRUCT_REGISTER_FIELDS } = require('../../domain/parameter-groups/constants.js') const { PROTOCOL_MODE, isModbusProtocolMode } = require('../../domain/protocol-mode.js') const STORAGE_KEY = 'parameter-groups-json' const JSON_DOCUMENT_TYPE = 'parameter-groups' const JSON_SCHEMA_VERSION = 2 function toPersistedGroups(groups = []) { return groups.map((group) => ({ layout: group.layout, name: group.name, ...(group.pollEnabled === false ? { pollEnabled: false } : {}), registerType: group.registerType, startAddress: group.startAddress, quantity: group.quantity, registers: group.registers.map((register) => ({ dataType: register.dataType, defaultValue: register.defaultValue, conversionFormula: register.conversionFormula, isStructField: register.isStructField, name: register.name, maxValue: register.maxValue, minValue: register.minValue, textByteLength: register.textByteLength, remark: register.remark, unit: register.unit, value: getRegisterJsonValue(register), ...pickFields(register, STRUCT_REGISTER_FIELDS), ...pickFields(register, SOURCE_REGISTER_FIELDS) })), ...pickFields(group, SOURCE_GROUP_FIELDS) })) } function toJsonData(groups = [], options = {}) { const jsonData = { groups: toPersistedGroups(groups), type: JSON_DOCUMENT_TYPE, version: JSON_SCHEMA_VERSION } if (options.includeExportedAt) { jsonData.exportedAt = new Date().toISOString() } return jsonData } function toJsonText(groups = [], options = {}) { return JSON.stringify(toJsonData(groups, options), null, 2) } function normalizeProtocolMode(protocolMode) { return isModbusProtocolMode(protocolMode) ? PROTOCOL_MODE.MODBUS_RTU : PROTOCOL_MODE.STORAGE_ACCESS } function getProtocolStorageKey(protocolMode) { return `${STORAGE_KEY}:${normalizeProtocolMode(protocolMode)}` } function parseJsonGroups(jsonText) { const parsed = typeof jsonText === 'string' ? JSON.parse(jsonText) : jsonText const groups = Array.isArray(parsed) ? parsed : (Array.isArray(parsed && parsed.groups) ? parsed.groups : parsed && parsed.parameterGroups) if (parsed && parsed.type && parsed.type !== JSON_DOCUMENT_TYPE) { throw new Error('JSON 文件不是参数组配置') } if (parsed && parsed.version && parsed.version !== JSON_SCHEMA_VERSION) { throw new Error('JSON 版本不兼容') } if (!Array.isArray(groups)) { throw new Error('JSON 中没有找到寄存器组数组') } return groups } function readStoredGroups(protocolMode = PROTOCOL_MODE.STORAGE_ACCESS) { const wxApi = getWxApi() if (typeof wxApi.getStorageSync !== 'function') return [] try { const storageKey = getProtocolStorageKey(protocolMode) const jsonText = wxApi.getStorageSync(storageKey) if (jsonText) return parseJsonGroups(jsonText).map(cloneImportedGroup) } catch (error) { return [] } return [] } function persistGroups(groups = [], protocolMode = PROTOCOL_MODE.STORAGE_ACCESS) { const wxApi = getWxApi() if (typeof wxApi.setStorageSync !== 'function') return try { wxApi.setStorageSync(getProtocolStorageKey(protocolMode), toJsonText(groups)) } catch (error) {} } function getShareFileName() { return `parameter-groups-${formatExportStamp()}.json` } async function loadGroupsFromMessageFile() { const file = await loadSelectedFile('auto', { encoding: 'utf8', extensionMessage: '请选择 .json 寄存器配置文件', extensions: ['json'], fallbackName: 'parameter-groups.json' }) return parseJsonGroups(file.text).map(cloneImportedGroup) } async function saveGroupsToChat(groups = []) { if (!groups.length) { throw new Error('没有可保存的寄存器组') } const jsonText = toJsonText(groups, { includeExportedAt: true }) const result = await saveTextFileToChat(getShareFileName(), jsonText) return { count: groups.length, ...result } } module.exports = { JSON_DOCUMENT_TYPE, JSON_SCHEMA_VERSION, STORAGE_KEY, isCancelError, loadGroupsFromMessageFile, parseJsonGroups, persistGroups, readStoredGroups, saveGroupsToChat, toJsonData, toJsonText }