From d51d8f28f1a9f32bd1049adf16520b0d49dd881e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zhaobing=E2=80=99?= Date: Sun, 8 Oct 2023 18:36:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=9B=BA=E4=BB=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 7 +- .../lib/controllers/firmwareUpgrade/index.js | 366 ++++++++++++++++++ api/app/lib/routes/firmwareUpgrade/index.js | 29 ++ api/app/lib/utils/dataRange.js | 7 +- api/config.js | 11 + web/client/src/layout/actions/global.js | 1 + web/client/src/layout/reducers/global.js | 2 + .../service/actions/firmwareUpgrade.js | 103 +++++ .../src/sections/service/actions/index.js | 3 +- .../service/components/addFirmwareModal.jsx | 152 ++++++++ .../service/components/cycAddmodal.jsx | 2 +- .../service/components/firmwareListModal.jsx | 86 ++++ .../components/maintenanceRecordModal.jsx | 4 +- .../service/components/recordModal.jsx | 2 +- .../service/containers/deviceManagement.jsx | 246 ++++++++++++ .../service/containers/firmwareLibrary.jsx | 135 +++++++ .../src/sections/service/containers/index.js | 5 +- .../service/containers/serviceRecord.jsx | 2 +- web/client/src/sections/service/nav-item.jsx | 9 + web/client/src/sections/service/routes.js | 21 +- web/client/src/utils/webapi.js | 17 +- web/config.js | 9 +- web/package.json | 2 +- web/routes/attachment/index.js | 3 +- 24 files changed, 1204 insertions(+), 20 deletions(-) create mode 100644 api/app/lib/controllers/firmwareUpgrade/index.js create mode 100644 api/app/lib/routes/firmwareUpgrade/index.js create mode 100644 web/client/src/sections/service/actions/firmwareUpgrade.js create mode 100644 web/client/src/sections/service/components/addFirmwareModal.jsx create mode 100644 web/client/src/sections/service/components/firmwareListModal.jsx create mode 100644 web/client/src/sections/service/containers/deviceManagement.jsx create mode 100644 web/client/src/sections/service/containers/firmwareLibrary.jsx diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index e78fb7e..d4f0c4b 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -40,8 +40,10 @@ // 测试 // "--apiEmisUrl http://10.8.30.161:1111", // "--apiEmisUrl http://10.8.30.161:31111/", - // "--apiEmisUrl https://pepca-demo.anxinyun.cn/_api", - "--apiEmisUrl http://localhost:14000", + "--apiEmisUrl https://pepca-demo.anxinyun.cn/_api", + // "--apiEmisUrl https://pep-ca.anxinyun.cn/_api", + + // "--apiEmisUrl http://localhost:14000", "--apiVcmpUrl http://localhost:4000", "--apiIotAuth http://localhost:4200", "--godUrl https://restapi.amap.com/v3", @@ -106,6 +108,7 @@ "--confirmAlarmAnxinUserId 1", "--vcmpAppId 5048b08d-c449-4d7f-b1ec-f741012aefe8", "--vcmpAppSecret 5ba8c0ab-9fbd-4f07-9817-c48017c3cbad", + "--apiCrawUrl http://218.3.126.49:30555/v1" //设备升级接口 ] }, { diff --git a/api/app/lib/controllers/firmwareUpgrade/index.js b/api/app/lib/controllers/firmwareUpgrade/index.js new file mode 100644 index 0000000..1148272 --- /dev/null +++ b/api/app/lib/controllers/firmwareUpgrade/index.js @@ -0,0 +1,366 @@ +'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') + `).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.query + const res= await ctx.app.fs.craw.get(ApiTable.getThingMessages,{query:{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).switch||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===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 +}; \ No newline at end of file diff --git a/api/app/lib/routes/firmwareUpgrade/index.js b/api/app/lib/routes/firmwareUpgrade/index.js new file mode 100644 index 0000000..d91ead1 --- /dev/null +++ b/api/app/lib/routes/firmwareUpgrade/index.js @@ -0,0 +1,29 @@ +'use strict'; + +const firmwareUpgrade = require('../../controllers/firmwareUpgrade'); + +module.exports = function (app, router, opts) { + app.fs.api.logAttr['GET/deviceType'] = { content: '获取设备型号', visible: true } + router.get('/deviceType', firmwareUpgrade.getDeviceType) + + app.fs.api.logAttr['GET/structure'] = { content: '获取结构物相关', visible: true } + router.get('/structure', firmwareUpgrade.getStruc) + + app.fs.api.logAttr['GET/firmware'] = { content: '获取固件包列表', visible: true } + router.get('/firmware', firmwareUpgrade.getFirmwares) + + // app.fs.api.logAttr['POST/upgradeFirmware'] = { content: '增加/覆盖固件包', visible: true } + // router.post('/upgradeFirmware', firmwareUpgrade.firmwareUpgrades) + + app.fs.api.logAttr['DELETE/deleteFirmware'] = { content: '删除固件包', visible: true } + router.delete('/deleteFirmware', firmwareUpgrade.deleteFirmware) + + app.fs.api.logAttr['GET/getThingMessages'] = { content: '获取设备信息', visible: true } + router.get('/getThingMessages', firmwareUpgrade.getThingMessages) + + app.fs.api.logAttr['POST/distributeConfiguration'] = { content: '下发配置(单个或批量)', visible: true } + router.post('/distributeConfiguration', firmwareUpgrade.distributeConfiguration) + + + +} \ No newline at end of file diff --git a/api/app/lib/utils/dataRange.js b/api/app/lib/utils/dataRange.js index e6cbfcb..7c399f3 100644 --- a/api/app/lib/utils/dataRange.js +++ b/api/app/lib/utils/dataRange.js @@ -11,7 +11,7 @@ module.exports = function (app, opts) { return role.some(r => r == 'SuperAdmin' || r == 'admin') } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - } + } } async function pomsWithPepRangeParams ({ ctx, pepProjectId, keywordTarget, keyword }) { @@ -90,6 +90,7 @@ module.exports = function (app, opts) { async function anxinStrucIdRange ({ ctx, pepProjectId, keywordTarget, keyword }) { const { clickHouse } = ctx.app.fs + const { pepProjectRes, bindRes, } = await pomsWithPepRangeParams({ ctx, pepProjectId, keywordTarget, keyword }) // 获取不重复的 安心云项目 id @@ -124,6 +125,7 @@ module.exports = function (app, opts) { t_project.id AS projectId, t_structure.id AS strucId, t_structure.name AS strucName, + t_structure.iota_thing_id as thingId, project_state FROM t_project @@ -175,7 +177,8 @@ module.exports = function (app, opts) { project: [{ id: s.projectId, }], - pomsProject: [] + pomsProject: [], + thingId:s.thingId } undelStruc.push(corStruc) } diff --git a/api/config.js b/api/config.js index d8b3d7a..327a8cd 100644 --- a/api/config.js +++ b/api/config.js @@ -61,6 +61,9 @@ args.option('caiyunKey', '彩云天气 apiKey'); args.option('vcmpAppId', '视频平台 应用 id') args.option('vcmpAppSecret', '视频平台 应用秘钥') +//设备升级 +args.option('apiCrawUrl', '设备升级') + const flags = args.parse(process.argv); const POMS_DB = process.env.POMS_DB || flags.pg; @@ -90,6 +93,9 @@ const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl; const API_VCMP_URL = process.env.API_VCMP_URL || flags.apiVcmpUrl; // iot鉴权平台 api const API_IOT_AUTH = process.env.API_IOT_AUTH || flags.apiIotAuth; +//设备升级 +const API_CRAW_URL = process.env.API_CRAW_URL || flags.apiCrawUrl; + // 高德地图的参数 const GOD_URL = process.env.GOD_URL || flags.godUrl || 'https://restapi.amap.com/v3'; @@ -153,6 +159,7 @@ const requireParams = { // CLICKHOUST_CAM_WORKFLOW, CONFIRM_ALARM_ANXIN_USER_ID, VCMP_APP_ID, VCMP_APP_SECRET, + API_CRAW_URL } Object.keys(requireParams).forEach(key => { @@ -260,6 +267,10 @@ const product = { pssaRequest: [{// name 会作为一个 request 出现在 ctx.app.fs name: 'axyRequest', root: API_ANXINYUN_URL + },{ + name:'craw', + root:API_CRAW_URL, + dataWord:'text' }, { name: 'emisRequest', root: API_EMIS_URL diff --git a/web/client/src/layout/actions/global.js b/web/client/src/layout/actions/global.js index a53555b..0967589 100644 --- a/web/client/src/layout/actions/global.js +++ b/web/client/src/layout/actions/global.js @@ -50,6 +50,7 @@ export function initApiRoot () { qiniu: res.qiniu, webEmis: res.webEmis, webOa: res.webOa, + crawapi:res.crawapi } }) }); diff --git a/web/client/src/layout/reducers/global.js b/web/client/src/layout/reducers/global.js index 84be4a5..40e847c 100644 --- a/web/client/src/layout/reducers/global.js +++ b/web/client/src/layout/reducers/global.js @@ -20,6 +20,7 @@ function global (state = { pomsEs: '', pomsNotebook: '', dcWeb: '', + crawapi:'', qiniu: {} }, action) { const payload = action.payload; @@ -52,6 +53,7 @@ function global (state = { qiniu: payload.qiniu, webEmis: payload.webEmis, webOa: payload.webOa, + crawapi:payload.crawapi }).toJS(); case PEPPROJECTID: return Immutable.fromJS(state).merge({ diff --git a/web/client/src/sections/service/actions/firmwareUpgrade.js b/web/client/src/sections/service/actions/firmwareUpgrade.js new file mode 100644 index 0000000..0910b66 --- /dev/null +++ b/web/client/src/sections/service/actions/firmwareUpgrade.js @@ -0,0 +1,103 @@ +'use strict'; + +import { ApiTable, basicAction } from '$utils' + +export function getDeviceType(query) { //获取设备型号 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query, + actionType: 'GET_DEVICE_TYPE', + url: `${ApiTable.getDeviceType}`, + msg: { option: '获取设备型号' }, + reducer: { + name: "deviceType", + params: { noClear: true } + } + }); +} + +export function getStruc(query) { //获取结构物以及设备类型 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query, + actionType: 'GET_STRUC', + url: `${ApiTable.getStruc}`, + msg: { option: '获取结构物以及设备类型' }, + reducer: { + name: "structAndDeviceType", + params: { noClear: true } + } + }); +} + +export function getFirmware(query) { //获取固件包 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query, + actionType: 'GET_FIRMWARE', + url: `${ApiTable.getFirmware}`, + msg: { option: '获取固件包' }, + reducer: { + name: "firmware", + params: { noClear: true } + } + }); +} + + +export function upgradeFirmware(query,data) { //增加/覆盖固件包 + return dispatch => basicAction({ + type: 'post', + dispatch: dispatch, + query, + data, + actionType: 'UPGRADE_FIRMWARE', + url: `${ApiTable.upgradeFirmware}`, + msg: { option: '增加/覆盖固件包' }, + + }); +} + + +export function deleteFirmware(query) { //删除固件包 + return dispatch => basicAction({ + type: 'delete', + dispatch: dispatch, + query, + actionType: 'DELETE_FIRMWARE', + url: `${ApiTable.deleteFirmware}`, + msg: { option: '删除固件包' }, + + }); +} + + +export function getThingMessages(query) { //获取固件包信息 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query, + actionType: 'GET_THING_MESSAGES', + url: `${ApiTable.getThingMessages}`, + msg: { option: '获取设备信息' }, + + }); +} + +export function distributeConfiguration(query,data) { //下发配置 + return dispatch => basicAction({ + type: 'post', + dispatch: dispatch, + query, + data, + actionType: 'DISTRIBUTE_CONNFIGURATION', + url: `${ApiTable.distributeConfiguration}`, + msg: { option: '下发配置'}, + + }); +} + + diff --git a/web/client/src/sections/service/actions/index.js b/web/client/src/sections/service/actions/index.js index 5e6815f..aa913ce 100644 --- a/web/client/src/sections/service/actions/index.js +++ b/web/client/src/sections/service/actions/index.js @@ -4,6 +4,7 @@ import * as emPush from './emPush' import * as redcord from './record' import * as maintenancePlan from './maintenancePlan' import * as equipment from './equipment' +import * as firmwareUpgrade from './firmwareUpgrade' export default { - ...emPush, ...redcord, ...maintenancePlan, ...equipment + ...emPush, ...redcord, ...maintenancePlan, ...equipment,...firmwareUpgrade } \ No newline at end of file diff --git a/web/client/src/sections/service/components/addFirmwareModal.jsx b/web/client/src/sections/service/components/addFirmwareModal.jsx new file mode 100644 index 0000000..313fa71 --- /dev/null +++ b/web/client/src/sections/service/components/addFirmwareModal.jsx @@ -0,0 +1,152 @@ +import React, { useState, useEffect, useRef } from 'react' +import { connect } from 'react-redux'; +import moment from 'moment' +import { Button, Table, Modal, Form,Notification,Upload } from '@douyinfe/semi-ui'; +import { IconUpload } from '@douyinfe/semi-icons'; +import request from 'superagent'; + +const AddFirmwareModal = (props) => { + const {modalVis,onCancel,crawapi,recordRow,actions,dispatch,qiniu} =props + const api = useRef(); + const {domain}=qiniu //七牛服务器地址 + const {service}=actions + const [uploadData, setUploadData] = useState({}) + const [options,setOptions]=useState([])//设备类型的下拉选项 + const [fileObj,setFileObj]=useState({})//文件对象 + const [fileUrl,setFileUrl]=useState()//文件地址 + const userId = JSON.parse(sessionStorage.getItem('pomsUser'))?.id + const [removeFlag,setRemoveFlag]=useState(false)//文件是否清除过 + useEffect(()=>{ + //获取设备类型 + dispatch(service.getDeviceType()).then((res) => { + setOptions( res.payload.data?.map(item=> { + return { + label:item.model, + value:item.id + } + })) + }) + },[]) + // console.log('xxxx1111',recordRow) + // console.log('xxxx11112',fileUrl) + + const okHandler= ()=>{ + // console.log('fileObj',fileObj) + api.current.validate().then(async (res)=>{ + // console.log('ressss',res) + // const query = { + // version:res?.versionNo, + // qiniu:domain, + // device_meta_id: res?.deviceName, + // tokenup: '22767e1f-db8d-4a1d-87d4-56347cf21247', + // wholeFile:fileUrl, + // } + // const body={ + // filePath:fileUrl, + // userId:userId, + // comment:res?.remark, + // deviceMetaName:options?.find(item=>item.value===res?.deviceName)?.label, + // fileObj:fileObj + // } + // dispatch(service.upgradeFirmware(query,body)).then(res=>{ + // }) + const responseData=await request.get(qiniu+'/'+fileUrl).responseType('blob') + const blobData = responseData.body; + request.post(crawapi+'/firmwareupgrade') + // .set('Content-Type','application/octet-stream') + .attach('file',blobData,fileObj?.name||'') + .field('filePath',removeFlag?fileUrl:recordRow?recordRow.filepath:fileUrl) + .field('userId', userId||'') + .field('comment',res?.remark||'') + .field('device_meta_name', options?.find(item=>item.value===res?.deviceName)?.label||'') + .query({ version:res?.versionNo,device_meta_id: res?.deviceName,token:'22767e1f-db8d-4a1d-87d4-56347cf21247'}) + .end((err, response) => { + if(response?.ok){ + setRemoveFlag(false) + onCancel() + }else{ + console.error('Superagent request failed:'); + + } + }) + + + + }) + } + + // function readFileAsBlob(file) { + // return new Promise((resolve, reject) => { + // const reader = new FileReader(); + // reader.onload = () => { + // const blob = new Blob([reader.result], { type: file.type }); + // resolve(blob); + // }; + + // reader.onerror = (error) => { + // reject(error); + // }; + + // reader.readAsArrayBuffer(file); + // }); + // } + + return <> + + +
api.current = formApi} labelCol={{ span: 7,offset:1}} wrapperCol={{span: 15,offset:1}} labelPosition='left' > + + + + { + setUploadData({}) + setRemoveFlag(true) + }} + onSuccess={ async(responseBody, file,all) => { + // console.log('file111',file) + setFileObj(file) + setFileUrl(responseBody?.uploaded) + setUploadData({ + name: file.name, + size: file.size, + url: responseBody?.uploaded, + uploadTime: moment().format("YYYY-MM-DD HH:mm:ss") + }) + }} + > + + + + +
+ + +
+ +} + + +function mapStateToProps (state) { + const { auth, global } = state; + return { + user: auth.user, + actions: global.actions, + crawapi: global.crawapi, + qiniu:global.qiniu, + + }; + } + +export default connect(mapStateToProps)(AddFirmwareModal) \ No newline at end of file diff --git a/web/client/src/sections/service/components/cycAddmodal.jsx b/web/client/src/sections/service/components/cycAddmodal.jsx index 54f5747..5dc67ae 100644 --- a/web/client/src/sections/service/components/cycAddmodal.jsx +++ b/web/client/src/sections/service/components/cycAddmodal.jsx @@ -15,7 +15,7 @@ const AddModal = (props) => { //编辑和新增的逻辑 const okHandler = () => { api.current.validate().then((res) => { - console.log(111, res, respondRecordData?.map(v => ({ value: v.id, label: v.sketch }))); + // console.log(111, res, respondRecordData?.map(v => ({ value: v.id, label: v.sketch }))); const query = { id: recordRow?.id, actualFinishTime: res.realityTime, diff --git a/web/client/src/sections/service/components/firmwareListModal.jsx b/web/client/src/sections/service/components/firmwareListModal.jsx new file mode 100644 index 0000000..ae9f550 --- /dev/null +++ b/web/client/src/sections/service/components/firmwareListModal.jsx @@ -0,0 +1,86 @@ +import React, { useState, useEffect, useRef } from 'react' +import { connect } from 'react-redux'; +import moment from 'moment' +import { Button, Table, Modal, Form } from '@douyinfe/semi-ui'; +import { IconUpload } from '@douyinfe/semi-icons'; + + +const firmwareListModal = (props) => { + const {modalVis,onCancel,apiRoot,recordRow,versionData,vData,actions,dispatch} =props + const api = useRef(); + const [uploadData, setUploadData] = useState({}) + const [data,setData]=useState() + const {service}=actions + const okHandler=()=>{ + api.current.validate().then((res)=>{ + const query = { + version:res?.type, + device_meta_id:data[0]?.device_meta_id, + tokenup: '22767e1f-db8d-4a1d-87d4-56347cf21247', + } + const body=[{thing_id:data[0]?.thing_id,device_ids:data?.map(item=>item.deviceId)}] + dispatch(service.distributeConfiguration(query,body)).then((res)=>{ + if(res.success) onCancel() + + }) + + // console.log('rexxxx',res) + }) + } + +useEffect(()=>{ + // console.log('versionData',vData,versionData) +if(recordRow&&recordRow.length&&versionData&&versionData.length&&vData&&vData.length){ + + //匹配设备id + const res= versionData?.filter(item=>recordRow?.some(p=>p.deviceId===item.deviceId))?.map(child=>{ + return { + device_meta_id:child.devicemetaId, + deviceId:child.deviceId, + thing_id:child.thingId, + firmwareNo:child.firmwareNo, + firmwareName:child.firmwareName, + versionList:vData.filter(n=>n.device_meta_id==child.devicemetaId) + } + }) + + setData(res) +} + +},[recordRow,versionData,vData]) +// console.log('recordRow1',recordRow,data) + + return <> + +
api.current = formApi} + labelCol={{ span: 7}} + wrapperCol={{span: 15}} + labelPosition='left' > + + {data&&data.length&&data[0].versionList&&data[0].versionList.length? + data[0].versionList.map((item,index)=>{`版本名称:${item.firmwareName}-版本号:${item.versionNo}`}) + :''} + + +
+ + +
+ +} + + +function mapStateToProps (state) { + const { auth, global } = state; + return { + user: auth.user, + actions: global.actions, + apiRoot: global.apiRoot + + }; + } + +export default connect(mapStateToProps)(firmwareListModal) \ No newline at end of file diff --git a/web/client/src/sections/service/components/maintenanceRecordModal.jsx b/web/client/src/sections/service/components/maintenanceRecordModal.jsx index 2822816..1feec13 100644 --- a/web/client/src/sections/service/components/maintenanceRecordModal.jsx +++ b/web/client/src/sections/service/components/maintenanceRecordModal.jsx @@ -15,14 +15,14 @@ const MaintenanceRecordModal = (props) => { const api = useRef(); useEffect(() => { - console.log('recordRow', recordRow); + // console.log('recordRow', recordRow); }, [recordRow]); const cancelHandler = () => { onClose(); }; const okHandler = () => { api.current.validate().then((res) => { - console.log('res1', res) + // console.log('res1', res) const query = { id: recordRow?.id, projectId:res.projectName, diff --git a/web/client/src/sections/service/components/recordModal.jsx b/web/client/src/sections/service/components/recordModal.jsx index 7114a37..61cc6e1 100644 --- a/web/client/src/sections/service/components/recordModal.jsx +++ b/web/client/src/sections/service/components/recordModal.jsx @@ -164,7 +164,7 @@ const RecordModal = (props) => { } function mapStateToProps (state) { const { auth, global, members, webSocket, addRecord } = state; - console.log(addRecord); + // console.log(addRecord); return { addRecord: addRecord.isRequesting, // user: auth.user, diff --git a/web/client/src/sections/service/containers/deviceManagement.jsx b/web/client/src/sections/service/containers/deviceManagement.jsx new file mode 100644 index 0000000..37f131b --- /dev/null +++ b/web/client/src/sections/service/containers/deviceManagement.jsx @@ -0,0 +1,246 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Button, Table, Popconfirm, Pagination,Select,Input,Switch,Notification,Progress } from '@douyinfe/semi-ui'; +import moment from 'moment' +import FirmwareListModal from '../components/firmwareListModal'; + + +const DeviceManagement = (props) => { + const {actions,dispatch,pepProjectId,user}=props + const {service}=actions + const [updataButtonDisabled,setUpdataButtonDisabled]=useState(true)//批量升级的按钮的显示与隐藏 + const [firmwareModalVis,setFirmwareModalVis]=useState(false) + const [strucAndDeviceType,setStrucAndDeviceType]=useState([])// + const [struc,setStruc]=useState([])// + const [deviceType,setDeviceType]=useState([])//设备类型的optionList + const [data,setData]=useState([])//列表数据 + const [thingIds,setThingIds]=useState([])//结构物id数组 + const [defaultVal,setDefaultVal]=useState('')//设备类型id + const [thingId,setThingId]=useState()//单个结构物id + const [searchVal,setSearchVal]=useState()//搜索框值 + const [recordRow,setRecordRow]=useState() + const [selectedRows,setSelectedRows]=useState([])//选择的key + const [selectdR,setSelectedR]=useState([])//选择行 + const [vData,setVData]=useState([])//版本信息 + const getData=(query)=>{ + dispatch(service.getThingMessages(query)).then((res)=>{ + if(res.success) { + setData(res.payload.data) + } + + }) + dispatch(service.getFirmware(query)).then(res=>{ + if(res.success) setVData(res.payload.data) + }) + } + useEffect(()=>{ + //结构物和设备类型 + dispatch(service.getStruc({pepProjectId})).then((res)=>{ + if(res.success) { + setStrucAndDeviceType( res.payload.data) + setStruc( res.payload.data?.map(item=>{ + return {label:item.strucName,value:item.thingId} + })) + setThingIds(res.payload.data?.map(item=>item.thingId)?.join(',')||'') + } + + }) + // console.log('xxxx111',user) + },[]) + useEffect(()=>{ + const query={thingIds} + getData(query) + },[thingIds]) + + const structChange =value => { + clearSelectedRows() + setUpdataButtonDisabled(true) + const deviceTypeList= strucAndDeviceType?.find(item=>item.thingId==value)?.deviceType?.map(child=>{ + return { + label:child.model, + value:child.id + } + })||[] + setDefaultVal('') + // console.log('event',deviceTypeList) + setDeviceType(deviceTypeList) + setThingId(value) + const query={thingIds:value,device_meta_id:defaultVal} + getData(query) + + }; + const deviceTypeChange=value=>{ + setUpdataButtonDisabled(true) + clearSelectedRows() + setDefaultVal(value) + const query={thingIds:thingId,device_meta_id:value} + getData(query) + // console.log(value,'event') + } + //清除结构物的逻辑 + const clearHandler=()=>{ + setUpdataButtonDisabled(true) + clearSelectedRows() + const query={thingIds} + getData(query) + + } + //清楚设备类型的逻辑 + const cleartypeHandler=()=>{ + setUpdataButtonDisabled(true) + clearSelectedRows() + setDefaultVal(null) + const query={thingIds:thingId} + getData(query) + } + //搜索按钮的逻辑 + const searchHandler=()=>{ + if(!thingId&&!defaultVal){ + const query={thingIds} + getData(query) + }else{ + const query={thingIds:thingId,device_meta_id:defaultVal,searchVal} + getData(query) + } + } + const clearSelectedRows = () => { + setSelectedRows([]); + }; + const rowSelection = { + selectedRowKeys: selectedRows, // 已选择的行的 keys + getCheckboxProps: record => ({ + name: record.name, + }), + + // onSelect: (record, selected) => { + // console.log(`select row: ${selected}`, record); + // }, + onSelectAll: (selected, selectedRows) => { + setUpdataButtonDisabled(!selectedRows.every(item=>selectedRows[0]?.deviceType===item.deviceType)) + }, + onChange: (selectedRowKeys, selectedRows) => { + setSelectedR(selectedRows) + setSelectedRows(selectedRowKeys) + // console.log('xxxx',selectedRows) + //选择之后,清空选择 + if(selectedRows&&selectedRows.length===0){ + setUpdataButtonDisabled(true) + } + //选择很多的时候,如果有设备型号不对应的情况 + if(selectedRows&&selectedRows.length>0){ + setUpdataButtonDisabled(!selectedRows.every(item=>selectedRows[0].deviceType===item.deviceType)) + } + + + }, + }; + + + + let columns=[{ + title: '序号', + render: (t, r, i) => { + return i + 1; + } + },{ + title: '设备名称', + dataIndex: 'deviceName' + },{ + title: '设备型号', + dataIndex: 'deviceType' + }, + { + title: '固件名称', + dataIndex: 'firmwareName' + }, + { + title: '固件版本号', + dataIndex: 'firmwareNo' + }, + { + title: '升级状态', + render:(_,record)=>{ + return record.status!=='未升级'&&record.status!=='升级成功'?:record.status + } + }, + { + title: '升级开关状态', + dataIndex: 'switchStatus' , + render:(_,record)=>{ + return + } + }, + { + title: '操作', + render:(_,record)=>{ + return
+ +
+ } + } + ] +return <>
+
+
+
+
设备管理
+
Device Management
+
+ + + + {setSearchVal(e)}}> + + +
+
+
+ {setFirmwareModalVis(false);setRecordRow(null)}}> +
+
+ +} + +function mapStateToProps (state) { + const { auth, global, getPush } = state; + return { + loading: getPush.isRequesting, + user: auth.user, + actions: global.actions, + pepProjectId:global.pepProjectId + }; + } + + export default connect(mapStateToProps)(DeviceManagement); \ No newline at end of file diff --git a/web/client/src/sections/service/containers/firmwareLibrary.jsx b/web/client/src/sections/service/containers/firmwareLibrary.jsx new file mode 100644 index 0000000..f911776 --- /dev/null +++ b/web/client/src/sections/service/containers/firmwareLibrary.jsx @@ -0,0 +1,135 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Button, Table, Popconfirm, Pagination,Input,Toast } from '@douyinfe/semi-ui'; +import moment from 'moment' +import AddFirmwareModal from '../components/addFirmwareModal' + + + +const FirmwareLibrary = (props) => { + const {actions,dispatch}=props + const [modalVis,setModalVis]=useState(false)//添加固件弹框的显示与隐藏 + const [recordRow,setRecordRow]=useState() + const [data,setData]=useState([])//列表数据 + const [searchVal,setSearchVal]=useState('')//存储搜索框的值 + const [users,setUsers]=useState([])//所有用户信息 + const {service}=actions + // console.log(data,'data1111') + const getData=(query)=>{ + dispatch(service.getFirmware(query)).then(res=>{ + if(res.success)setData(res.payload.data) + }) + } + useEffect(()=>{ + //获得已上传的固件列表 + getData() + //用户信息 + dispatch(service.getOrganizationUsers()).then(res=>{ + setUsers(res.payload.data) + }) + },[]) + + const searchHandler=()=>{ + const query={version:searchVal} + getData(query) + + } + const onConfirm = (record) => { + const query={version:record?.versionNo,device_meta_id:record?.device_meta_id,tokenup:'22767e1f-db8d-4a1d-87d4-56347cf21247'} + dispatch(service.deleteFirmware(query)).then(res=>{ + if(res.success) { + getData() + // Toast.success('删除成功'); + + } + + }) + }; + + const onCancel = () => { + Toast.warning('取消删除'); + }; +let columns=[{ + title: '序号', + render: (t, r, i) => { + return i + 1; + } +},{ + title: '固件名称', + dataIndex: 'firmwareName' +},{ + title: '设备型号', + dataIndex: 'deviceMetaName' +}, +{ + title: '版本号', + dataIndex: 'versionNo' +}, +{ + title: '上传时间', + dataIndex: 'uploadTime' +}, +{ + title: '上传人', + render:(_,record)=>{ + return {users?.find(item=>item.id==record.uploader)?.name||''} +} +}, +{ + title: '备注', + dataIndex: 'comment' +}, +{ + title: '操作', + render:(_,record)=>{ + return
onConfirm(record)} + onCancel={onCancel} + > + + + +
+ } +} + + + + +] + return <>
+
+
+
+
固件库
+
Firmware Library
+
+ {setSearchVal(e)}}> + + +
+
+
+ {getData({version:searchVal});setModalVis(false);setRecordRow(null)}}> +
+
+ + + +} + +function mapStateToProps (state) { + const { auth, global, getPush } = state; + // console.log('state1',state) + return { + loading: getPush.isRequesting, + user: auth.user, + actions: global.actions, + }; + } + + export default connect(mapStateToProps)(FirmwareLibrary); \ No newline at end of file diff --git a/web/client/src/sections/service/containers/index.js b/web/client/src/sections/service/containers/index.js index f50b383..a48ea58 100644 --- a/web/client/src/sections/service/containers/index.js +++ b/web/client/src/sections/service/containers/index.js @@ -8,5 +8,6 @@ import AppPush from './appPush'; import MaintenanceModel from './maintenanceModel'; import ServiceRecord from './serviceRecord'; import MaintenanceRecords from './maintenanceRecords'; - -export { ReportManagement, CyclePlan, TemporaryResponse, EmPush, AppPush, MaintenanceModel, ServiceRecord, MaintenanceRecords }; \ No newline at end of file +import FirmwareLibrary from './firmwareLibrary' +import DeviceManagement from './deviceManagement'; +export { ReportManagement, CyclePlan, TemporaryResponse, EmPush, AppPush, MaintenanceModel, ServiceRecord, MaintenanceRecords,DeviceManagement,FirmwareLibrary }; \ No newline at end of file diff --git a/web/client/src/sections/service/containers/serviceRecord.jsx b/web/client/src/sections/service/containers/serviceRecord.jsx index 7d0f7ca..5bcab7b 100644 --- a/web/client/src/sections/service/containers/serviceRecord.jsx +++ b/web/client/src/sections/service/containers/serviceRecord.jsx @@ -65,7 +65,7 @@ const Server = (props) => { const query = { sTime, eTime } - console.log('sTime', sTime, eTime) + // console.log('sTime', sTime, eTime) dispatch(service.calculability(query)).then((res) => { if (res.success) setCalculability((Math.round(res.payload.data * 10000)) / 100 + '%'); // console.log(res.payload.data,'dateee') }) diff --git a/web/client/src/sections/service/nav-item.jsx b/web/client/src/sections/service/nav-item.jsx index 92ad32d..d891eb5 100644 --- a/web/client/src/sections/service/nav-item.jsx +++ b/web/client/src/sections/service/nav-item.jsx @@ -57,6 +57,15 @@ export function getNavItem (user, dispatch) { icon: , to: '/service/serviceRecord/MaintenanceRecords', items: [{ itemKey:'MaintenanceRecords',to:'/service/serviceRecord/MaintenanceRecords',text:'维修记录'}] + }, + { + itemKey: 'firmwareUpgrade', + text: '固件升级', + icon: , + to: '/service/firmwareUpgrade/FirmwareLibrary', + items: [{ itemKey:'FirmwareLibrary',to:'/service/firmwareUpgrade/FirmwareLibrary',text:'固件库'}, + { itemKey:'DeviceManagement',to:'/service/firmwareUpgrade/DeviceManagement',text:'设备管理'} + ] } ] }, diff --git a/web/client/src/sections/service/routes.js b/web/client/src/sections/service/routes.js index d8293ab..67133bb 100644 --- a/web/client/src/sections/service/routes.js +++ b/web/client/src/sections/service/routes.js @@ -1,4 +1,4 @@ -import { ReportManagement, CyclePlan, TemporaryResponse, EmPush, AppPush, MaintenanceModel, ServiceRecord, MaintenanceRecords } from './containers'; +import { ReportManagement, CyclePlan, TemporaryResponse, EmPush, AppPush, MaintenanceModel, ServiceRecord, MaintenanceRecords,FirmwareLibrary,DeviceManagement } from './containers'; export default [{ type: 'inner', @@ -73,6 +73,23 @@ export default [{ component: MaintenanceRecords, breadcrumb: '维护记录', }] - }] + }, + { + path: '/firmwareUpgrade', + key: 'firmwareUpgrade', + breadcrumb: '固件升级', + childRoutes: [{ + path: '/FirmwareLibrary', + key: 'firmwareLibrary', + component: FirmwareLibrary, + breadcrumb: '固件库', + },{ + path: '/DeviceManagement', + key: 'deviceManagement', + component: DeviceManagement, + breadcrumb: '设备管理', + }] + } + ] } }]; \ No newline at end of file diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 809f0f5..7517af5 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -147,7 +147,21 @@ export const ApiTable = { respondRecord: 'respond-record', //待办工单 - workOrders:'unfinished' + workOrders:'unfinished', + //获取设备型号 + getDeviceType:'deviceType', + //结构物和对应设备类型 + getStruc:'structure', + //获取固件包列表 + getFirmware:'firmware', + //增加/覆盖固件包 + upgradeFirmware:'upgradeFirmware', + //删除固件包 + deleteFirmware:'deleteFirmware', + //获取设备信息 + getThingMessages:'getThingMessages', + //下发配置(批量单个) + distributeConfiguration:'distributeConfiguration' }; // 项企的接口 @@ -170,6 +184,7 @@ export const EmisApiTable = { } + export const RouteTable = { apiRoot: "/api/root", fileUpload: "/_upload/new", diff --git a/web/config.js b/web/config.js index ce7d83e..5f6e8fb 100644 --- a/web/config.js +++ b/web/config.js @@ -27,6 +27,8 @@ args.option('pomsEs', 'es监控 web'); args.option('pomsNotebook', 'notebook web'); args.option('dcWeb', '报表中心web'); +//硬件升级 +args.option('crawapi','硬件升级') // 七牛 args.option('qnak', 'qiniuAccessKey'); @@ -51,7 +53,7 @@ const POMS_PGHERO = process.env.POMS_PGHERO || flags.pomsPghero; const POMS_ES = process.env.POMS_ES || flags.pomsEs; const POMS_NOTEBOOK = process.env.POMS_NOTEBOOK || flags.pomsNotebook; const DC_WEB = process.env.DC_WEB || flags.dcWeb; - +const CRAW_API=process.env.CRAW_API || flags.crawapi; // 七牛 const ANXINCLOUD_QINIU_AK = process.env.ANXINCLOUD_QINIU_ACCESSKEY || flags.qnak; const ANXINCLOUD_QINIU_SK = process.env.ANXINCLOUD_QINIU_SECRETKEY || flags.qnsk; @@ -60,7 +62,7 @@ const ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE = process.env.ANXINCLOUD_QINIU_DOMA if ( - !API_URL + !API_URL|| !CRAW_API || !API_EMIS_URL || !WEB_EMIS_URL || !WEB_OA_URL || !API_ANXINYUN_URL || !POMS_MONITOR || !DC_WEB @@ -119,7 +121,8 @@ const product = { pomsNotebook: POMS_NOTEBOOK, dcWeb: DC_WEB, staticRoot: './client', - + crawapi:CRAW_API, + qiniu: { fetchUrl: '/_file-server', domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE diff --git a/web/package.json b/web/package.json index 13f960a..57d43b7 100644 --- a/web/package.json +++ b/web/package.json @@ -7,7 +7,7 @@ "test": "mocha", "start-vite": "cross-env NODE_ENV=developmentVite npm run start-params", "start": "cross-env NODE_ENV=development npm run start-params", - "start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://localhost:14000 --webEmisUrl http://localhost:5000 --webOaUrl http://10.8.30.161:8668 --qnak 5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu --qnsk w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5 --qnbkt anxinyun-test --qndmn http://test.resources.anxinyun.cn --iotVcmpWeb https://mediaconsole.ngaiot.com --pomsMonitor http://monitor.anxinyun.cn/goto/PaEDLE84z?orgId=1 --pomsKubesphere https://k8sadmin.anxinyun.cn/ --pomsAmbari https://ambari.anxinyun.cn/ --pomsKowl https://kafka.anxinyun.cn/ --pomsPghero https://pghero.anxinyun.cn/ --pomsEs https://esc.anxinyun.cn/ --pomsNotebook https://inotebook.anxinyun.cn/ --dcWeb https://fsiot-oamss.anxinyun.cn", + "start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://localhost:14000 --webEmisUrl http://localhost:5000 --webOaUrl http://10.8.30.161:8668 --qnak 5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu --qnsk w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5 --qnbkt anxinyun-test --qndmn http://test.resources.anxinyun.cn --iotVcmpWeb https://mediaconsole.ngaiot.com --pomsMonitor http://monitor.anxinyun.cn/goto/PaEDLE84z?orgId=1 --pomsKubesphere https://k8sadmin.anxinyun.cn/ --pomsAmbari https://ambari.anxinyun.cn/ --pomsKowl https://kafka.anxinyun.cn/ --pomsPghero https://pghero.anxinyun.cn/ --pomsEs https://esc.anxinyun.cn/ --pomsNotebook https://inotebook.anxinyun.cn/ --crawapi http://218.3.126.49:30555/v1 --dcWeb https://fsiot-oamss.anxinyun.cn", "deploy": "export NODE_ENV=production&& npm run build && node server", "build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js", "build": "cross-env NODE_ENV=production&&webpack --config webpack.config.prod.js" diff --git a/web/routes/attachment/index.js b/web/routes/attachment/index.js index b4e88ef..88d9b78 100644 --- a/web/routes/attachment/index.js +++ b/web/routes/attachment/index.js @@ -19,7 +19,7 @@ module.exports = { entry: function (app, router, opts) { const getApiRoot = async function (ctx) { - const { apiUrl, iotVcmpWeb, pomsMonitor, pomsKubesphere, pomsAmbari, pomsKowl, pomsPghero, pomsEs, pomsNotebook, dcWeb, qiniu, webEmis, webOa } = opts; + const { apiUrl, iotVcmpWeb, pomsMonitor, pomsKubesphere, pomsAmbari, pomsKowl, pomsPghero, pomsEs, pomsNotebook, dcWeb, qiniu, webEmis, webOa,crawapi } = opts; ctx.status = 200; ctx.body = { @@ -36,6 +36,7 @@ module.exports = { qiniu: qiniu, webEmis, webOa, + crawapi }; };