const { query, queryOne } = require('../../db'); const { nextId } = require('../../id'); const TABLE = 'measurement_control_point'; function pageParams(input = {}) { const rawPageNum = Number(input.pageNum || 1); const rawPageSize = Number(input.pageSize || 10); const pageNum = Number.isFinite(rawPageNum) ? Math.max(Math.trunc(rawPageNum), 1) : 1; const pageSize = Number.isFinite(rawPageSize) ? Math.max(Math.trunc(rawPageSize), 1) : 10; return { pageNum, pageSize, offset: (pageNum - 1) * pageSize }; } function tableData(rows, total) { return { code: 200, msg: '查询成功', rows, total }; } function mapRow(row) { if (!row) return null; return { id: row.id, pointCode: row.point_code, pointName: row.point_name, measuringDeviceId: row.measuring_device_id, measuringDeviceName: row.measuring_device_name, parameterName: row.parameter_name, parameterNameLabel: row.parameter_name_label, standardUnit: row.standard_unit, conversionFactor: row.conversion_factor === null || row.conversion_factor === undefined ? null : Number(row.conversion_factor), originalUnit: row.original_unit, collectionCycle: row.collection_cycle, dataType: row.data_type, registerAddress: row.register_address, status: row.status, createTime: row.create_time, updateTime: row.update_time, delFlag: row.del_flag }; } function normalizeBody(body = {}) { const conversionFactor = body.conversionFactor === '' || body.conversionFactor === undefined || body.conversionFactor === null ? null : Number(body.conversionFactor); if (conversionFactor !== null && !Number.isFinite(conversionFactor)) { throw new Error('换算倍率必须是数字'); } if (!body.measuringDeviceId) throw new Error('所属计量器具不能为空'); return { pointCode: body.pointCode || null, pointName: body.pointName || null, measuringDeviceId: body.measuringDeviceId, parameterName: body.parameterName || null, standardUnit: body.standardUnit || null, conversionFactor, originalUnit: body.originalUnit || null, collectionCycle: body.collectionCycle || null, dataType: body.dataType || null, registerAddress: body.registerAddress || null, status: body.status || null }; } const selectSql = ` select mcp.*, md.device_name as measuring_device_name, em.metric_name as parameter_name_label from ${TABLE} mcp left join measuring_device md on md.id = mcp.measuring_device_id left join ( select type, collection_field, substring_index(group_concat(metric_name order by id separator '||'), '||', 1) as metric_name from energy_metric_library where collection_field is not null and collection_field <> '' group by type, collection_field ) em on em.type collate utf8mb4_general_ci = md.device_type collate utf8mb4_general_ci and em.collection_field collate utf8mb4_general_ci = mcp.parameter_name collate utf8mb4_general_ci `; async function list(params = {}) { const page = pageParams(params); const where = ["mcp.del_flag = '0'"]; const sqlParams = {}; if (params.pointCode) { where.push('mcp.point_code like :pointCode'); sqlParams.pointCode = `%${String(params.pointCode).trim()}%`; } if (params.pointName) { where.push('mcp.point_name like :pointName'); sqlParams.pointName = `%${String(params.pointName).trim()}%`; } if (params.measuringDeviceId) { where.push('mcp.measuring_device_id = :measuringDeviceId'); sqlParams.measuringDeviceId = String(params.measuringDeviceId); } if (params.parameterName) { where.push('mcp.parameter_name = :parameterName'); sqlParams.parameterName = String(params.parameterName); } const whereSql = `where ${where.join(' and ')}`; const totalRow = await queryOne(`select count(*) as total from ${TABLE} mcp ${whereSql}`, sqlParams); const rows = await query( `${selectSql} ${whereSql} order by mcp.create_time desc, mcp.id desc limit ${page.pageSize} offset ${page.offset}`, sqlParams ); return tableData(rows.map(mapRow), Number(totalRow?.total || 0)); } async function get(id) { if (!id) throw new Error('ID不能为空'); return mapRow(await queryOne( `${selectSql} where mcp.id = :id and mcp.del_flag = '0' limit 1`, { id } )); } async function add(body = {}) { const id = body.id ? String(body.id) : nextId(); const data = normalizeBody(body); await query( `insert into ${TABLE} (id, point_code, point_name, measuring_device_id, parameter_name, standard_unit, conversion_factor, original_unit, collection_cycle, data_type, register_address, status, create_time, update_time, del_flag) values (:id, :pointCode, :pointName, :measuringDeviceId, :parameterName, :standardUnit, :conversionFactor, :originalUnit, :collectionCycle, :dataType, :registerAddress, :status, now(), now(), '0')`, { id, ...data } ); return id; } async function update(body = {}) { if (!body.id) throw new Error('ID不能为空'); const data = normalizeBody(body); await query( `update ${TABLE} set point_code = :pointCode, point_name = :pointName, measuring_device_id = :measuringDeviceId, parameter_name = :parameterName, standard_unit = :standardUnit, conversion_factor = :conversionFactor, original_unit = :originalUnit, collection_cycle = :collectionCycle, data_type = :dataType, register_address = :registerAddress, status = :status, update_time = now() where id = :id and del_flag = '0'`, { id: body.id, ...data } ); } async function remove(ids) { const list = String(ids || '').split(',').map((item) => item.trim()).filter(Boolean); if (!list.length) return; const params = {}; const placeholders = list.map((id, index) => { params[`id${index}`] = id; return `:id${index}`; }); await query( `update ${TABLE} set del_flag = '1', update_time = now() where id in (${placeholders.join(', ')})`, params ); } module.exports = { list, get, add, update, remove };