'use strict'; const request = require('superagent'); const moment = require('moment') const http = require('http'); const ApiTable = { getFirmwares:'firmwareupgrade/getPkg', firmwareUpgrade:'firmwareupgrade', getThingMessages:'firmwareupgrade/getThingMessages', distributeConfiguration:'firmwareupgrade/redisSet' } //设备维护记录 async function getDeviceType (ctx) { try { // const { models } = ctx.fs.dc // const sequelize = ctx.fs.dc.ORM const { clickHouse } = ctx.app.fs const rlst = await clickHouse.iot.query(` SELECT id,model FROM DeviceMeta WHERE model in ('FS-YTSW','FS-YTDZ-GD','FS-iFWL-ZXSJ','ZSJ-iVW08','FS-Q90-NHB1-HC','FS-RTU-P4-SL','FS-RTU-SL','FS-V08','FS-M24','FS-LPWAN08','FS-RTU-SL','FS-RTU-P4-SL') `).toPromise() ctx.body=rlst||[] ctx.status=200 }catch(error){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `查询设备型号失败` } } } //查询结构物 async function getStruc (ctx) { try { const { clickHouse } = ctx.app.fs // const { models } = ctx.fs.dc // const sequelize = ctx.fs.dc.ORM const { pepProjectId, keywordTarget, keyword} = ctx.query const { utils: {anxinStrucIdRange } } = ctx.app.fs let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId, keywordTarget, keyword }) // console.log('anxinStruc1',anxinStruc) let thingIds=new Set() if(anxinStruc&&anxinStruc.length){ anxinStruc.map(item=>thingIds.add(item.thingId)) } let deviceType= thingIds.size ? await clickHouse.iot.query(` SELECT distinct dm.id id,dm.model model,dc.thingId thingId FROM Device dc INNER JOIN DeviceMeta dm ON dm.id=dc.deviceMetaId WHERE dc.thingId in (${[...thingIds].map(id => `'${id}'`).join(',')},'-000')` ).toPromise() :[] let rslt=[] if(deviceType&&deviceType.length&&anxinStruc&&anxinStruc.length){ rslt= anxinStruc.map(item=>{ item.deviceType=deviceType.filter(child=>child.thingId===item.thingId) return item }) } // //返回数据结构示例 // // [ {strucId: s.strucId, // // strucName: s.strucName, // // projectId: s.projectId, // // project: [{ id: s.projectId,}], // // pomsProject: [], // // deviceType:[{}] // // }] ctx.body=rslt||[] ctx.status=200 }catch(error){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `查询结构物以及设备类型失败` } } } async function getFirmwares (ctx) { const query = ctx.query // console.log('query1',query) try{ const res=await ctx.app.fs.craw.get(ApiTable.getFirmwares,{query}) // console.log('666x1111',res) let rslt=[] if(res){ if( JSON.parse(res).msg){ JSON.parse(JSON.parse(res).msg)&&JSON.parse(JSON.parse(res).msg).length?JSON.parse(JSON.parse(res).msg).map(item=>{ // console.log('xxxx',item) rslt.push( {device_meta_id:item.device_meta_id, deviceMetaName:item.device_meta_name, versionNo:item.version, firmwareName:item.filename, filepath:item.filepath, uploader:item.userid, comment:item.comment, uploadTime:moment(item.UpdatedTime).format('YYYY-MM-DD'), fileObj:item.Bin }) }):[] } } ctx.body=rslt ctx.status=200 }catch(error){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `查询固件包列表失败` } } } function getFileAsBuffer(remoteFileUrl) { return new Promise((resolve, reject) => { // 发起 HTTP 请求 http.get(remoteFileUrl, (response) => { if (response.statusCode !== 200) { reject(new Error(`HTTP请求失败,状态码:${response.statusCode}`)); return; } const buffers = []; // 监听数据流 response.on('data', (chunk) => { buffers.push(chunk); }); // 数据传输完成 response.on('end', () => { // 将文件数据合并为一个 Buffer const fileData = Buffer.concat(buffers); // 返回文件内容的 Buffer resolve(fileData); }); // 处理请求错误 response.on('error', (error) => { reject(error); }); }); }); } //增加/覆盖固件包 async function firmwareUpgrades (ctx) { try{ const {qiniu,version,tokenup,device_meta_id,wholeFile} = ctx.query const {deviceMetaName,filePath,userId,fileObj,comment} = ctx.request.body const url=qiniu+'/'+wholeFile // 发起 GET 请求以获取文件 // console.log('url1',url) // var data = fs.readFileSync(url, "utf-8"); // console.log('xxxx111',data) request.get(url).responseType('blob').end((err, response) => { if (err) { console.error('Superagent request error:', err); return; } if (response.ok) { const blobData = response.body // console.log('xxxxx1',response) request.post('http://218.3.126.49:30555/v1/firmwareupgrade') // .set('Content-Type','application/octet-stream') .attach('file',blobData,fileObj.name||'') .field('filePath', filePath||'') .field('userId', userId||'') .field('comment',comment||'') .field('device_meta_name',deviceMetaName||'') .query({ version,device_meta_id,token:tokenup}) .then((resolve, reject) => { return (err, res) => { if (err) { reject(err); } else { resolve(res); } }; }) } }) // const ressss= await request.get(url).end(function(err, sourceResponse) { // console.log('xxx2',sourceResponse) // if (err) { // console.error('文件获取失败:', err); // return; // } // 从响应中获取文件内容 // const fileContent = sourceResponse.body; // // 创建一个 POST 请求以上传文件 // request // .post(ApiTable.firmwareUpgrade) // .field('caption', 'My cats') // 其他表单字段 // .attach('file', fileContent, 'file.jpeg') // 将文件添加为表单字段 // .end(function(err, targetResponse) { // if (err) { // console.error('上传失败:', err); // return; // } // // 处理目标服务器的响应 // console.log('上传成功'); // console.log(targetResponse.text); // }); // }); // console.log('xxx1',ressss) // console.log('query1111', ctx.query) // const fileObj=await getFileAsBuffer(qiniu+'/'+wholeFile) // console.log('xx1',fileObj) // const file=qiniu+'/'+wholeFile // console.log('xxxx666',deviceMetaName) // const {files}=await parse(fileObjq) // const file=files[0] // const res=await ctx.app.fs.craw.post(ApiTable.firmwareUpgrade, // {query:{version,token:tokenup,device_meta_id}, // data:{deviceMetaName,filePath,userId,fileObjq}, // header:{ 'Content-Type':'multipart/form-data'}}) // const formData = new FormData(ApiTable.firmwareUpgrade,{query:{version,token:tokenup,device_meta_id},data:{deviceMetaName,filePath,userId,file},header:{ // 'Content-Type':'multipart/form-data; boundary=--------------------------033155845889797072451758' // }}); // // 添加普通字段到 FormData // // formData.append('device_meta_name', device_meta_name); // // formData.append('filePath', filePath); // // formData.append('userId', userId) // // formData.append('file', fileObj); // // console.log('fileObj',formData) // // const body= ctx.request.body // // const fileData = await getFileAsBase64(qiniu+'/'+wholeFile); // // const res=await ctx.app.fs.craw.post1(ApiTable.firmwareUpgrade,userId,filePath,{query:{version:version,token:tokenup,device_meta_id:device_meta_id},data:fileObj}) ctx.body={} ctx.status=200 }catch(error){ // console.log('xx1111',error) ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `增加/覆盖固件包失败` } } } async function deleteFirmware(ctx){ const {version,device_meta_id,tokenup}=ctx.query try{ await ctx.app.fs.craw.delete(ApiTable.firmwareUpgrade,{query:{version,device_meta_id,token:tokenup}}) ctx.status=204 }catch(eror){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `删除固件包失败` } } } async function getThingMessages(ctx){ try{ const {thingIds,device_meta_id,searchVal}=ctx.request.body const res= await ctx.app.fs.craw.post(ApiTable.getThingMessages,{data:{thingIds,device_meta_id}}) // console.log('xxxxxx',res) let rslt=[] if(res){ JSON.parse(res).data&&JSON.parse(res).data.length?JSON.parse(res).data.map(item=>{ if( item.devices&& item.devices.length){ item.devices.map(child=>{ // console.log('childx',child) rslt.push({ key:child.id, thingId:item.thingId, devicemetaId:child.deviceMetaId||'', deviceType:JSON.parse(child.properties).productType||'', deviceName:child.name||'', firmwareName:child.fileName||'', firmwareNo:child.updateVersion||'', status:child.updateState||'', updatePercentage:child.updatePercentage||'', switchStatus:JSON.parse(child.properties).update||false, deviceId:child.id }) // console.log('xxxx2',child.properties) // console.log('xxxx2',child) }) } // console.log('xxxx1',item) }):[] } let result if(searchVal&&rslt&&rslt.length){ result= rslt.filter(item=>item.deviceName.includes(searchVal) ) } if(!searchVal){ result=rslt } ctx.body=result ctx.status=200 }catch(error){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `查询结构物状态失败` } } } async function distributeConfiguration(ctx){ try{ const {version,device_meta_id,tokenup}=ctx.query const res= await ctx.app.fs.craw.post(ApiTable.distributeConfiguration,{query:{version,device_meta_id,token:tokenup},data:JSON.stringify(ctx.request.body)}) if(res){ ctx.body=JSON.parse(res) ctx.status=200 }else{ ctx.status=400 ctx.body = { message: `下发配置失败` } } }catch(error){ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) ctx.status = 400 ctx.body = { message: `下发配置失败` } } } module.exports = { getDeviceType, getStruc, getFirmwares, firmwareUpgrades, deleteFirmware, getThingMessages, distributeConfiguration };