zhaobing’
1 year ago
24 changed files with 1204 additions and 20 deletions
@ -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 |
||||
|
}; |
@ -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) |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -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: '下发配置'}, |
||||
|
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
@ -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 <> |
||||
|
<Modal visible={modalVis} onCancel={onCancel} title='固件上传' onOk={okHandler} > |
||||
|
|
||||
|
<Form initValues={{ |
||||
|
'firmwareName':recordRow?.firmwareName, |
||||
|
'deviceName':recordRow?.device_meta_id, |
||||
|
'versionNo':recordRow?.versionNo, |
||||
|
'files':recordRow?[{ url: `${domain}/${recordRow?.filepath}`, name: recordRow?.firmwareName }]:[], |
||||
|
'remark':recordRow?.remark |
||||
|
}} getFormApi={formApi => api.current = formApi} labelCol={{ span: 7,offset:1}} wrapperCol={{span: 15,offset:1}} labelPosition='left' > |
||||
|
<Form.Input field='firmwareName' label='固件版本名称:' style={{with:'80%'}} rules={[{ required: true, message: '固件版本名称必填' }]}></Form.Input> |
||||
|
<Form.Select field='deviceName' label='设备型号:' placeholder='请选择设备型号' optionList={options} rules={[{ required: true, message: '设备型号必填' }]}></Form.Select> |
||||
|
<Form.Input field='versionNo' label='版本号:' rules={[{ required: true, message: '版本号必填' }]}></Form.Input> |
||||
|
<Form.Upload limit={1} |
||||
|
action={`/_upload/attachments`} |
||||
|
field='files' label='文件上传' |
||||
|
rules={[{ required: true, message: '文件上传必填' }]} |
||||
|
onRemove={() => { |
||||
|
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") |
||||
|
}) |
||||
|
}} |
||||
|
> |
||||
|
<Button icon={<IconUpload />} theme="light"> |
||||
|
点击上传 |
||||
|
</Button> |
||||
|
</Form.Upload> |
||||
|
<Form.TextArea field='remark' label='备注:' placeholder='请输入项目介绍'></Form.TextArea> |
||||
|
|
||||
|
</Form> |
||||
|
|
||||
|
|
||||
|
</Modal> |
||||
|
</> |
||||
|
} |
||||
|
|
||||
|
|
||||
|
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) |
@ -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 <> |
||||
|
<Modal visible={modalVis} onCancel={onCancel} title='固件升级' onOk={okHandler}> |
||||
|
<Form initValues={{ |
||||
|
|
||||
|
}} |
||||
|
getFormApi={formApi => api.current = formApi} |
||||
|
labelCol={{ span: 7}} |
||||
|
wrapperCol={{span: 15}} |
||||
|
labelPosition='left' > |
||||
|
<Form.RadioGroup field="type" label='固件包' direction='vertical' rules={[{ required: true, message: '版本号必填' }]}> |
||||
|
{data&&data.length&&data[0].versionList&&data[0].versionList.length? |
||||
|
data[0].versionList.map((item,index)=><Form.Radio key={index} value={item.versionNo}>{`版本名称:${item.firmwareName}-版本号:${item.versionNo}`}</Form.Radio>) |
||||
|
:''} |
||||
|
|
||||
|
</Form.RadioGroup> |
||||
|
</Form> |
||||
|
|
||||
|
|
||||
|
</Modal> |
||||
|
</> |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function mapStateToProps (state) { |
||||
|
const { auth, global } = state; |
||||
|
return { |
||||
|
user: auth.user, |
||||
|
actions: global.actions, |
||||
|
apiRoot: global.apiRoot |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(firmwareListModal) |
@ -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!=='升级成功'?<Progress percent={parseFloat(record.updatePercentage||0)} showInfo></Progress>:record.status |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
title: '升级开关状态', |
||||
|
dataIndex: 'switchStatus' , |
||||
|
render:(_,record)=>{ |
||||
|
return <Switch disabled defaultChecked={record.switchStatus}></Switch> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
title: '操作', |
||||
|
render:(_,record)=>{ |
||||
|
return <div> |
||||
|
<Button type="secondary" onClick={()=>{ |
||||
|
if(record.switchStatus){ |
||||
|
setFirmwareModalVis(true) |
||||
|
setRecordRow([record]) |
||||
|
}else{ |
||||
|
Notification.info({ |
||||
|
title: '提示', |
||||
|
content: '请到安心云平台打开升级开关后进行升级。', |
||||
|
duration: 3, |
||||
|
}) |
||||
|
} |
||||
|
if(record.status!=='未升级'&&record.status!=='升级成功'){ |
||||
|
Notification.info({ |
||||
|
title: '提示', |
||||
|
content: '该设备仍在升级中,请在完成升级后再操作。', |
||||
|
duration: 3, |
||||
|
}) |
||||
|
} |
||||
|
}}>固件升级</Button> |
||||
|
</div> |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
return <><div style={{ background: '#FFFFFF', margin: '8px 12px', padding: '20px 20px 0px 20px' }}> |
||||
|
<div style={{ display: 'flex', alignItems: 'center' }}> |
||||
|
<div style={{ display: 'flex', alignItems: 'center',marginRight:30 }}> |
||||
|
<div style={{ width: 0, height: 20, borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div> |
||||
|
<div style={{ fontFamily: "YouSheBiaoTiHei", fontSize: 24, color: '#101531', marginLeft: 8 }}>设备管理</div> |
||||
|
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>Device Management</div> |
||||
|
</div> |
||||
|
<Select placeholder='请选择结构物' optionList={struc} filter showClear |
||||
|
onChange={structChange} |
||||
|
onClear={clearHandler} |
||||
|
style={{ width:300,marginRight:10}}> |
||||
|
</Select> |
||||
|
<Select placeholder='请选择设备型号' value={defaultVal} optionList={deviceType} |
||||
|
onClear={cleartypeHandler} |
||||
|
onChange={deviceTypeChange} |
||||
|
filter |
||||
|
showClear |
||||
|
style={{ width:300,marginRight:10}}></Select> |
||||
|
<Button style={{marginRight:10}} type="secondary" disabled={updataButtonDisabled} onClick={()=>{ |
||||
|
setFirmwareModalVis(true); |
||||
|
setRecordRow(selectdR) |
||||
|
}}>固件升级</Button> |
||||
|
<Input placeholder='请输入设备名称' style={{ width:300,marginRight:10}} onChange={(e)=>{setSearchVal(e)}}></Input> |
||||
|
<Button style={{marginRight:10}} type="secondary" theme='solid' |
||||
|
onClick={searchHandler} |
||||
|
>查询</Button> |
||||
|
|
||||
|
</div> |
||||
|
<div style={{marginTop:10}}> |
||||
|
<Table columns={columns} rowSelection={rowSelection} dataSource={data}></Table> |
||||
|
<FirmwareListModal vData={vData} versionData={data} modalVis={firmwareModalVis} recordRow={recordRow} onCancel={()=>{setFirmwareModalVis(false);setRecordRow(null)}}></FirmwareListModal> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
} |
||||
|
|
||||
|
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); |
@ -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 <span>{users?.find(item=>item.id==record.uploader)?.name||''}</span> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
title: '备注', |
||||
|
dataIndex: 'comment' |
||||
|
}, |
||||
|
{ |
||||
|
title: '操作', |
||||
|
render:(_,record)=>{ |
||||
|
return <div> <Popconfirm |
||||
|
title="确定是否要删除?" |
||||
|
onConfirm={()=>onConfirm(record)} |
||||
|
onCancel={onCancel} |
||||
|
> |
||||
|
<Button type="danger" theme='light'>删除</Button> |
||||
|
</Popconfirm> |
||||
|
<Button type="secondary" theme='solid' onClick={()=>{ |
||||
|
setModalVis(true); |
||||
|
setRecordRow(record) |
||||
|
}}>编辑</Button> |
||||
|
</div> |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
] |
||||
|
return <><div style={{ background: '#FFFFFF', margin: '8px 12px', padding: '20px 20px 0px 20px' }}> |
||||
|
<div style={{ display: 'flex', alignItems: 'center' }}> |
||||
|
<div style={{ display: 'flex', alignItems: 'center',marginRight:30 }}> |
||||
|
<div style={{ width: 0, height: 20, borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div> |
||||
|
<div style={{ fontFamily: "YouSheBiaoTiHei", fontSize: 24, color: '#101531', marginLeft: 8 }}>固件库</div> |
||||
|
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>Firmware Library</div> |
||||
|
</div> |
||||
|
<Input placeholder='请输入名称版本号' style={{ width:300,marginRight:10}} onChange={(e)=>{setSearchVal(e)}}></Input> |
||||
|
<Button style={{marginRight:10}} type="secondary" theme='solid' onClick={searchHandler}>查询</Button> |
||||
|
<Button type="secondary" theme='solid' onClick={()=>{setModalVis(true)}}>上传</Button> |
||||
|
</div> |
||||
|
<div style={{marginTop:10}}> |
||||
|
<Table columns={columns} pagination dataSource={data} ></Table> |
||||
|
<AddFirmwareModal modalVis={modalVis} recordRow={recordRow} onCancel={()=>{getData({version:searchVal});setModalVis(false);setRecordRow(null)}}></AddFirmwareModal> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
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); |
Loading…
Reference in new issue