zhaobing’
1 year ago
48 changed files with 2711 additions and 17 deletions
@ -0,0 +1,178 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
|
||||
|
|
||||
|
async function getThingsDeploy (ctx) { |
||||
|
let rslt = {instances:{}}, errStatus = null; |
||||
|
let error = { name: 'FindError', message: '获取设备部署信息失败' }; |
||||
|
let structList=[] |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models |
||||
|
const res=await models.ProjectBind.findAll() |
||||
|
if(res.length){ |
||||
|
res.map(item=>{ |
||||
|
structList.push({axyId:item.dataValues.axyProjectId,id:item.dataValues.id}) |
||||
|
}) |
||||
|
console.log('structList[id]',structList['gruop']) |
||||
|
|
||||
|
for(let id in structList){ |
||||
|
let iotaResponse = await ctx.app.fs.iotRequest.get(`things/${structList[id].axyId}/deploys`) |
||||
|
if (JSON.parse(iotaResponse)) { |
||||
|
for (const ids in JSON.parse(iotaResponse).instances) { |
||||
|
const instances = JSON.parse(iotaResponse).instances[ids]; |
||||
|
if (instances.type === 's.d') { |
||||
|
instances.instance.structId = structList[id].axyId; |
||||
|
instances.instance.xjId= structList[id].id |
||||
|
rslt.instances = Object.assign(rslt.instances, { [ids]: instances }) |
||||
|
} |
||||
|
} |
||||
|
error = null; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}else{ |
||||
|
throw '没有绑定的安心云结构物的数据!!!' |
||||
|
} |
||||
|
} catch (err) { |
||||
|
errStatus = err.status |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`) |
||||
|
} |
||||
|
if (error) { |
||||
|
if (errStatus == 404) { |
||||
|
ctx.status = 200; |
||||
|
ctx.body = { |
||||
|
'instances': null |
||||
|
}; |
||||
|
} else { |
||||
|
ctx.status = errStatus; |
||||
|
ctx.body = error; |
||||
|
} |
||||
|
} else { |
||||
|
ctx.status = 200; |
||||
|
ctx.body = rslt |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function getThingStatus (ctx) { |
||||
|
let structList = [] |
||||
|
let result=[] |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models |
||||
|
const rslt=await models.ProjectBind.findAll() |
||||
|
if(rslt.length){ |
||||
|
rslt.map(item=>{ |
||||
|
structList.push(item.dataValues.axyProjectId) |
||||
|
}) |
||||
|
for(let id in structList){ |
||||
|
if(id!='group'){ |
||||
|
let iotaResponse = await ctx.app.fs.craw.get('thing/status', { query: { thingId:structList[id] } }) |
||||
|
result = [...result,...JSON.parse(iotaResponse)] |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}else{ |
||||
|
throw '没有绑定的安心云结构物的数据!!!' |
||||
|
} |
||||
|
ctx.status = 200 |
||||
|
if (result) { |
||||
|
ctx.body = result |
||||
|
} |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 200 |
||||
|
ctx.body = [] |
||||
|
} |
||||
|
} |
||||
|
//查询物联网卡相关信息
|
||||
|
async function getCardInfo (ctx) { |
||||
|
try{ |
||||
|
let rlst = [] |
||||
|
const { clickHouse } = ctx.app.fs |
||||
|
const { database: iota } = clickHouse.iot.opts.config |
||||
|
const {structIds}=ctx.request.body |
||||
|
if (structIds && structIds.length) { |
||||
|
const id = `(${structIds.map(item => `'${item.id}'`).join(',')})` |
||||
|
rlst = await clickHouse.dataAlarm.query(` |
||||
|
with tmp as ( SELECT cs.DeviceId as deviceId, |
||||
|
cs.CardNo as cardNo, |
||||
|
cs.PType as pType, |
||||
|
cs.Status as status, |
||||
|
cs.Total as total, |
||||
|
cs.Allowance as allowance, |
||||
|
cs.Time as time |
||||
|
FROM alarm.CardStatus cs |
||||
|
WHERE cs.DeviceId in ${id} |
||||
|
ORDER BY cs.Time DESC |
||||
|
LIMIT 1) |
||||
|
SELECT t.*,d.thingId,d.name FROM tmp t |
||||
|
LEFT JOIN ${iota}.Device d |
||||
|
ON Device.id = t.deviceId` ).toPromise()
|
||||
|
ctx.status = 200 |
||||
|
ctx.body = rlst |
||||
|
}else{ |
||||
|
ctx.status = 200 |
||||
|
ctx.body = rlst |
||||
|
} |
||||
|
|
||||
|
}catch(error){ |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
"message": "查询物联网卡相关信息失败" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
async function createInvoke (ctx, next) { |
||||
|
let error = { name: 'CreateError', message: '命令下发失败' }; |
||||
|
const {searchId,data} = ctx.request.body |
||||
|
let rslt=[] |
||||
|
try { |
||||
|
if(searchId&&searchId.length&&Array.isArray(searchId)){ |
||||
|
for(let id in searchId){ |
||||
|
if(id!='group'){ |
||||
|
let dataToIota = { |
||||
|
deviceId:searchId[id].deviceId, |
||||
|
dimCapId:searchId[id].sid, |
||||
|
thingId:searchId[id].structId, |
||||
|
timeout: 300000 |
||||
|
} |
||||
|
let iotaResponse = await ctx.app.fs.iotInvoke.post(`capabilities/invoke`, {data:dataToIota}) |
||||
|
rslt.push({...searchId[id],...iotaResponse}) |
||||
|
error = null |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}else{ |
||||
|
|
||||
|
let iotaResponse = await ctx.app.fs.iotInvoke.post(`capabilities/invoke`, {data:searchId}) |
||||
|
rslt = iotaResponse |
||||
|
error = null; |
||||
|
} |
||||
|
} catch (err) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); |
||||
|
} |
||||
|
if (error) { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = error; |
||||
|
} else { |
||||
|
ctx.status = 200; |
||||
|
ctx.body = rslt; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
getThingsDeploy, |
||||
|
getThingStatus, |
||||
|
getCardInfo, |
||||
|
createInvoke |
||||
|
} |
||||
|
|
@ -0,0 +1,32 @@ |
|||||
|
'use strict' |
||||
|
|
||||
|
async function findDetailBySNCard(ctx, next) { |
||||
|
try { |
||||
|
const { card } = ctx.params |
||||
|
const models = ctx.fs.dc.models |
||||
|
let option = { |
||||
|
attributes: ['id', 'name', 'equipment_no'], |
||||
|
where: { equipmentNo: {$like: `%${card}%`} }, |
||||
|
include: [ |
||||
|
{ |
||||
|
required: true, //inner join
|
||||
|
model: models.Project, |
||||
|
attributes: ['id', 'name'], |
||||
|
}, |
||||
|
], |
||||
|
} |
||||
|
const rlst = await models.Point.findAll(option) |
||||
|
ctx.body = rlst |
||||
|
ctx.status = 200 |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
message: '根据设备sn号查询相关信息失败', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
findDetailBySNCard, |
||||
|
} |
@ -0,0 +1,141 @@ |
|||||
|
'use strict' |
||||
|
const moment = require('moment') |
||||
|
|
||||
|
let axyTokenCache = { |
||||
|
token: null, |
||||
|
orgId: null, |
||||
|
expireTime: null, //过期时间
|
||||
|
} |
||||
|
|
||||
|
async function getAnxinyunToken(ctx) { |
||||
|
try { |
||||
|
if (!axyTokenCache.token || moment() > moment(axyTokenCache.expireTime)) { |
||||
|
if (ctx.app.fs.opts.axyProject.split('/').length === 3) { |
||||
|
const dataToAxy = { |
||||
|
p: ctx.app.fs.opts.axyProject.split('/')[0], |
||||
|
username: ctx.app.fs.opts.axyProject.split('/')[1], |
||||
|
password: ctx.app.fs.opts.axyProject.split('/')[2], |
||||
|
} |
||||
|
const axyResponse = await ctx.app.fs.anxinyun.post('project/login', { data: dataToAxy }) |
||||
|
if (axyResponse.authorized) { |
||||
|
axyTokenCache.token = axyResponse.token //放进缓存
|
||||
|
axyTokenCache.orgId = axyResponse.orgId //放进缓存
|
||||
|
axyTokenCache.expireTime = moment().add(1, 'hour').format('YYYY-MM-DD HH:mm:ss') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return axyTokenCache |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`sechedule: laborAttendance, error: ${error}`) |
||||
|
} |
||||
|
} |
||||
|
//调用安心云结构物接口
|
||||
|
async function findAnxinyunProject(ctx, next) { |
||||
|
try { |
||||
|
let { type, url, params = {} } = ctx.request.body |
||||
|
let data = await getAnxinyunToken(ctx) |
||||
|
if (url && url.indexOf('{orgId}') != -1) { |
||||
|
url = url.replace(`{orgId}`, data.orgId) |
||||
|
} |
||||
|
const res = await ctx.app.fs.anxinyun[type](`${url}?token=${data.token}`, { |
||||
|
data: params.data || {}, |
||||
|
query: params.query || {}, |
||||
|
}) |
||||
|
ctx.status = 200 |
||||
|
ctx.body = res |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
message: '查询安心云项目失败', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
async function addorEditRelation(ctx, next) { |
||||
|
let err='' |
||||
|
const { axyProjectId, structrueId, id } = ctx.request.body |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models |
||||
|
//编辑
|
||||
|
if (id) { |
||||
|
const res=await models.ProjectBind.findOne({ where: { id,axyProjectId,structureId:structrueId } }) |
||||
|
if(res){ |
||||
|
err='所选安心云结构物和巡检结构物重复!!!' |
||||
|
throw '所选安心云结构物和巡检结构物重复!!!' |
||||
|
} |
||||
|
await models.ProjectBind.update({ axyProjectId, structrueId }, { where: { id } }) |
||||
|
ctx.status = 204 |
||||
|
} else { |
||||
|
//新增
|
||||
|
const res= await models.ProjectBind.findOne({ where: { axyProjectId,structureId:structrueId } }) |
||||
|
if(res){ |
||||
|
err='所选安心云结构物和巡检结构物重复!!!' |
||||
|
throw '所选安心云结构物和巡检结构物重复!!!' |
||||
|
} |
||||
|
await models.ProjectBind.create({ axyProjectId, structureId:structrueId }) |
||||
|
ctx.status = 204 |
||||
|
} |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
message: err?err:id?'编辑失败':'新增失败', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function getRelationList(ctx, next) { |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models |
||||
|
const { limit, page, startTime, endTime } = ctx.query |
||||
|
let options = { |
||||
|
where: {}, |
||||
|
} |
||||
|
if (limit) { |
||||
|
options.limit = Number(limit) |
||||
|
} |
||||
|
if (page && limit) { |
||||
|
options.offset = Number(page) * Number(limit) |
||||
|
} |
||||
|
if (startTime && endTime) { |
||||
|
options.where.inspectTm = { $between: [startTime, endTime] } |
||||
|
} |
||||
|
const res = await models.ProjectBind.findAndCountAll(options) |
||||
|
ctx.body = res |
||||
|
ctx.status = 200 |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
message: '查询关联关系列表失败', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function deleteRelation(ctx, next) { |
||||
|
const {id} = ctx.params |
||||
|
try { |
||||
|
const models = ctx.fs.dc.models |
||||
|
const res = await models.ProjectBind.findOne({ where: { id:Number(id) } }) |
||||
|
if (!res) { |
||||
|
throw 'id不存在' |
||||
|
} |
||||
|
await models.ProjectBind.destroy({ where: { id:Number(id) } }) |
||||
|
ctx.status = 200 |
||||
|
} catch (error) { |
||||
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
||||
|
ctx.status = 400 |
||||
|
ctx.body = { |
||||
|
message: '关联关系列表失败', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
findAnxinyunProject, |
||||
|
addorEditRelation, |
||||
|
getRelationList, |
||||
|
deleteRelation, |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
/* eslint-disable*/ |
||||
|
'use strict'; |
||||
|
|
||||
|
module.exports = dc => { |
||||
|
const DataTypes = dc.ORM; |
||||
|
const sequelize = dc.orm; |
||||
|
const ProjectBind = sequelize.define("project_bind", { |
||||
|
id: { |
||||
|
type: DataTypes.INTEGER, |
||||
|
allowNull: false, |
||||
|
defaultValue: null, |
||||
|
comment: null, |
||||
|
primaryKey: true, |
||||
|
field: "id", |
||||
|
autoIncrement: true, |
||||
|
}, |
||||
|
axyProjectId: { |
||||
|
type: DataTypes.STRING, |
||||
|
allowNull: true, |
||||
|
defaultValue: null, |
||||
|
comment: '安心云项目id', |
||||
|
primaryKey: false, |
||||
|
field: "axy_project_id", |
||||
|
autoIncrement: false |
||||
|
}, |
||||
|
structureId: { |
||||
|
type: DataTypes.INTEGER, |
||||
|
allowNull: true, |
||||
|
defaultValue: null, |
||||
|
comment: '结构物id', |
||||
|
primaryKey: false, |
||||
|
field: "structure_id", |
||||
|
autoIncrement: false |
||||
|
}, |
||||
|
|
||||
|
}, { |
||||
|
tableName: "project_bind", |
||||
|
comment: "", |
||||
|
indexes: [] |
||||
|
}); |
||||
|
dc.models.ProjectBind = ProjectBind; |
||||
|
return ProjectBind; |
||||
|
}; |
@ -0,0 +1,19 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
const AIOTOverview = require('../../controllers/AIOTOverview/AIOTOverview'); |
||||
|
|
||||
|
module.exports = function (app, router, opts) { |
||||
|
app.fs.api.logAttr['GET/things/deploy'] = { content: '获取智能断路器', visible: true }; |
||||
|
router.get('/things/deploy', AIOTOverview.getThingsDeploy); |
||||
|
|
||||
|
app.fs.api.logAttr['GET/things/status'] = { content: '获取设备在离线', visible: true }; |
||||
|
router.get('/things/status', AIOTOverview.getThingStatus); |
||||
|
|
||||
|
app.fs.api.logAttr['POST/things/card'] = { content: '获取物联网卡相关信息', visible: true }; |
||||
|
router.post('/things/card', AIOTOverview.getCardInfo); |
||||
|
|
||||
|
//空开设备查询状态和开关设备
|
||||
|
app.fs.api.logAttr['POST/capabilities/invoke'] = { content: '及时采集', visible: true }; |
||||
|
router.post('/capabilities/invoke', AIOTOverview.createInvoke); |
||||
|
|
||||
|
}; |
@ -0,0 +1,8 @@ |
|||||
|
'use strict' |
||||
|
|
||||
|
const groundDisasterInspection = require('../../controllers/groundDisasterInspection/groundDisasterInspection') |
||||
|
|
||||
|
module.exports = function (app, router, opts) { |
||||
|
app.fs.api.logAttr['GET/card/detail/:card'] = { content: '根据sn号查询相应的点位信息和结构物信息', visible: true } |
||||
|
router.get('card/detail/:card', groundDisasterInspection.findDetailBySNCard) |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
const projectBind = require('../../controllers/projectBind/projectBind'); |
||||
|
|
||||
|
module.exports = function (app, router, opts) { |
||||
|
|
||||
|
app.fs.api.logAttr['POST/anxinyun/project/list'] = { content: '获取安心云项目列表', visible: false } |
||||
|
router.post('/anxinyun/project/list', projectBind.findAnxinyunProject) |
||||
|
|
||||
|
app.fs.api.logAttr['POST/anxinyun/project/relation'] = { content: '新增或编辑项目映射关系', visible: false } |
||||
|
router.post('/anxinyun/project/relation', projectBind.addorEditRelation) |
||||
|
|
||||
|
app.fs.api.logAttr['GET/anxinyun/project/relation/list'] = { content: '获取项目映射关系列表', visible: false } |
||||
|
router.get('/anxinyun/project/relation/list', projectBind.getRelationList) |
||||
|
|
||||
|
app.fs.api.logAttr['DELETE/anxinyun/project/relation/:id'] = { content: '删除项目映射关系', visible: false } |
||||
|
router.delete('/anxinyun/project/relation/:id', projectBind.deleteRelation) |
||||
|
|
||||
|
} |
@ -0,0 +1,163 @@ |
|||||
|
// package/AIOTOverview/AIOTOverview.js
|
||||
|
import { getThingsDeploy, getThingsStatus, getCardInfo,getRelationList} from "../../utils/getApiUrl"; |
||||
|
import { Request } from "../../common"; |
||||
|
const moment = require("../../utils/moment"); |
||||
|
|
||||
|
Page({ |
||||
|
|
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
data: [],//用电设备数据
|
||||
|
normal: 0,//正常
|
||||
|
abnormal: 0,//异常
|
||||
|
unknown: 0,//未知
|
||||
|
iotCardNormal: 0,//物联网卡正常
|
||||
|
iotCardNonactivated: 0,//物联网卡欠费
|
||||
|
iotCardHalt: 0,//物联网卡停机
|
||||
|
iotaCardData: [],//物联网卡数据
|
||||
|
searchId:[], |
||||
|
}, |
||||
|
//跳转流量监控明细
|
||||
|
navigatorToFlow() { |
||||
|
const jsonData = JSON.stringify(this.data.iotaCardData) |
||||
|
wx.navigateTo({ |
||||
|
url: `/package/AIOTOverview/flowMonitoring/flowMonitoring?data=` + encodeURIComponent(jsonData) |
||||
|
}) |
||||
|
}, |
||||
|
//跳转用电监控明细
|
||||
|
navigatorToEle() { |
||||
|
const jsonData2 = JSON.stringify(this.data.searchId) |
||||
|
wx.navigateTo({ |
||||
|
url: `/package/AIOTOverview/electricityMonitoring/electricityMonitoring?data2=${encodeURIComponent(jsonData2)}` |
||||
|
}) |
||||
|
}, |
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
async onLoad(options) { |
||||
|
wx.showLoading({ title: '加载中...' }); |
||||
|
const that = this |
||||
|
const devices = await Request.get(getThingsDeploy()) |
||||
|
const status = await Request.get(getThingsStatus()) |
||||
|
const rslt = await Request.get(getRelationList()) |
||||
|
let deviceId = [] //空开电源设备的id
|
||||
|
let deviceAll = [] |
||||
|
let searchId=[]//查询e9c设备状态的id
|
||||
|
let controlId=[] |
||||
|
if (devices) { |
||||
|
const dataList = devices |
||||
|
for (const id in dataList.instances) { |
||||
|
const instances = dataList?.instances[id] |
||||
|
if (instances.type == 's.d' && instances?.instance?.properties) { |
||||
|
deviceAll.push({ id, name: instances.instance?.properties?.name, structId: instances.instance?.structId }) |
||||
|
if (instances.type == 's.d' && instances.instance.properties.deviceType == 'sensor') { |
||||
|
if (instances.instance.properties.model == 'E9C') { |
||||
|
for (const key in instances?.instance?.interfaces) { |
||||
|
const d=Object.values(instances?.instance?.interfaces[key]?.capabilities) |
||||
|
if(d&&d.length){ |
||||
|
searchId.push({deviceId:id,cid:d[1]?.dimension?.id,sid:d[0]?.dimension?.id,name: instances.instance?.properties?.name, structId: instances.instance?.structId }) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (instances?.instance?.properties?.model == 'JG-RTU-S270') { |
||||
|
deviceId.push({ id, name: instances.instance?.properties?.name, structId: instances.instance?.structId,xjId:instances.instance?.xjId }) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
if (status && status.length) { |
||||
|
const data = deviceId.map(item => { |
||||
|
return { |
||||
|
deviceId: item.id, |
||||
|
name: item.name, |
||||
|
status: status.find(q => q.deviceId == item.id)?.status, |
||||
|
structId: item?.structId, |
||||
|
xjId:item.xjId |
||||
|
} |
||||
|
}) |
||||
|
deviceAll.push({ id: '012ccc98-c99d-445e-8397-6da1b4567533', name: '设备二', structId: 'df48d7c5-d902-47b1-b671-d88d546ba3e4' }) |
||||
|
if (deviceAll && deviceAll.length) { |
||||
|
Request.post(getCardInfo(), { structIds: deviceAll }).then(res => { |
||||
|
if (res) { |
||||
|
if(rslt.rows.length){ |
||||
|
controlId=res.map(item=>{ |
||||
|
return { |
||||
|
...item, |
||||
|
xjId:rslt.rows.find(q=>q.axyProjectId==item.thingId)?.id |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
that.setData({ |
||||
|
iotaCardData: controlId, |
||||
|
iotCardNormal: res?.filter(item => item.status == 0)?.length, |
||||
|
iotCardNonactivated: res?.filter(item => item.status == 1)?.length, |
||||
|
iotCardHalt: res?.filter(item => item.status == 2)?.length, |
||||
|
searchId:searchId |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
that.setData({ |
||||
|
data, |
||||
|
normal: data?.filter(item => item.status == 1)?.length, |
||||
|
unknown: data?.filter(item => item.status == -1)?.length, |
||||
|
abnormal: data?.filter(item => item.status == 0)?.length |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
wx.hideLoading() |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面初次渲染完成 |
||||
|
*/ |
||||
|
onReady() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面显示 |
||||
|
*/ |
||||
|
onShow() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面隐藏 |
||||
|
*/ |
||||
|
onHide() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面卸载 |
||||
|
*/ |
||||
|
onUnload() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面相关事件处理函数--监听用户下拉动作 |
||||
|
*/ |
||||
|
onPullDownRefresh() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面上拉触底事件的处理函数 |
||||
|
*/ |
||||
|
onReachBottom() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 用户点击右上角分享 |
||||
|
*/ |
||||
|
onShareAppMessage() { |
||||
|
|
||||
|
} |
||||
|
}) |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"navigationBarTitleText": "AIOT总览", |
||||
|
"usingComponents": { |
||||
|
"van-button": "@vant/weapp/button/index" |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
<!--package/AIOTOverview/AIOTOverview.wxml--> |
||||
|
|
||||
|
<view> |
||||
|
<!--用电设备状态总览--> |
||||
|
<view class="card"> |
||||
|
<view class="top"> |
||||
|
<view style="display: flex; align-items: center;"> |
||||
|
<text class="fontStyle">用电设备状态总览</text> |
||||
|
</view> |
||||
|
<view class="detailStyle"> |
||||
|
<van-button type="info" round size="small" bindtap="navigatorToEle">查看详情</van-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="card-content"> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left" style="font-weight: bold;">设备数量</view> |
||||
|
<view class="content-right" style="font-weight: bold;">{{data.length}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">正常设备</view> |
||||
|
<view class="content-right">{{normal+'个'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">异常设备</view> |
||||
|
<view class="content-right" style="color:red">{{abnormal+'个'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">未知</view> |
||||
|
<view class="content-right">{{unknown+'个'}}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!--物联网卡状态总览--> |
||||
|
<view class="card"> |
||||
|
<view class="top"> |
||||
|
<view style="display: flex; align-items: center;"> |
||||
|
<text class="fontStyle">物联网卡状态总览</text> |
||||
|
</view> |
||||
|
<view class="detailStyle"> |
||||
|
<van-button type="info" round size="small" bindtap="navigatorToFlow">查看详情</van-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="card-content"> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left" style="font-weight: bold;">设备数量</view> |
||||
|
<view class="content-right" style="font-weight: bold;">{{iotaCardData.length+'个'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">正常</view> |
||||
|
<view class="content-right">{{iotCardNormal+'个'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">未激活</view> |
||||
|
<view class="content-right">{{iotCardNonactivated+'个'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">停机</view> |
||||
|
<view class="content-right" style="color:red">{{iotCardHalt+'个'}}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
@ -0,0 +1,52 @@ |
|||||
|
/* package/AIOTOverview/AIOTOverview.wxss */ |
||||
|
|
||||
|
|
||||
|
.card { |
||||
|
position: relative; |
||||
|
background-color: #fff; |
||||
|
border: 1px solid #ddd; |
||||
|
border-radius: 8px; |
||||
|
/* padding: 10px; */ |
||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
||||
|
margin: 12px 12px; |
||||
|
} |
||||
|
|
||||
|
.top { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
padding: 10px; |
||||
|
|
||||
|
/* background-position: bottom; */ |
||||
|
} |
||||
|
|
||||
|
.card-content { |
||||
|
padding: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.card-left { |
||||
|
margin-left: 23px; |
||||
|
margin-bottom: 10px; |
||||
|
font-weight: 500; |
||||
|
font-size: 16px; |
||||
|
color: #000000d9; |
||||
|
} |
||||
|
.detail{ |
||||
|
margin:10px 0 |
||||
|
} |
||||
|
.card-right { |
||||
|
margin-right: 18px; |
||||
|
margin-bottom: 10px; |
||||
|
color: #1684FF; |
||||
|
} |
||||
|
.fontStyle { |
||||
|
font-family: PingFangSC-Medium; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.content-left { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.content-right { |
||||
|
font-size: 14px; |
||||
|
text-align: right; |
||||
|
} |
@ -0,0 +1,147 @@ |
|||||
|
// package/AIOTOverview/electricityMonitoring/electricityMonitoring.js
|
||||
|
import { getProjectList,getRelationList,createInvoke} from "../../../utils/getApiUrl" |
||||
|
import {Request} from "../../../common" |
||||
|
|
||||
|
Page({ |
||||
|
|
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
structList:[ ], |
||||
|
curStruId: 'all', // 选中结构物id
|
||||
|
list:[],//断路器设备list
|
||||
|
listCopy:[], |
||||
|
}, |
||||
|
onClose(e) { |
||||
|
// 获取报告
|
||||
|
// this.getPatrolReport();
|
||||
|
}, |
||||
|
switch1Change(e){ |
||||
|
wx.showLoading({ title: '加载中...' }); |
||||
|
const item=e.currentTarget.dataset.item |
||||
|
let searchId={ |
||||
|
deviceId:item.deviceId, |
||||
|
dimCapId:item.cid, |
||||
|
thingId:item.structId, |
||||
|
timeout: 300000, |
||||
|
param:e.detail.value?'开':'关' |
||||
|
} |
||||
|
Request.post(createInvoke(),{data:searchId}).then(res=>{ |
||||
|
if(res){ |
||||
|
wx.hideLoading() |
||||
|
}else{ |
||||
|
wx.hideLoading() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
}, |
||||
|
onStruChange(e) { |
||||
|
if (e.detail) { |
||||
|
let data = [] |
||||
|
if (e.detail === 'all') { |
||||
|
data = this.data.listCopy |
||||
|
} else { |
||||
|
data = this.data.listCopy.filter(item => item.xjId === e.detail) |
||||
|
} |
||||
|
this.setData({ |
||||
|
curStruId: e.detail, |
||||
|
list: data |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
async onLoad(options) { |
||||
|
wx.showLoading({ title: '加载中...' }); |
||||
|
const searchId= JSON.parse(decodeURIComponent(options.data2)) |
||||
|
let data={ |
||||
|
searchId |
||||
|
} |
||||
|
let listt=[] |
||||
|
//智能断路器的设备的状态
|
||||
|
const res1 =await Request.post(createInvoke(),data) |
||||
|
//获取结构物列表(巡检)
|
||||
|
// console.log('getProjectList',getProjectList)
|
||||
|
const res=await Request.get(getProjectList()) |
||||
|
const rslt=await Request.get(getRelationList()) |
||||
|
if(res.rows.length&&rslt.rows.length){ |
||||
|
const data=res.rows.map(item=>{ |
||||
|
return { |
||||
|
value: rslt.rows.find(q => item.id === q.structureId)?.structureId, |
||||
|
text:item.name |
||||
|
} |
||||
|
}) |
||||
|
if(res1&&res1.length){ |
||||
|
listt=res1.map(item=>{ |
||||
|
const c=rslt.rows?.find(q => q.axyProjectId == item.structId)?.structureId |
||||
|
return { |
||||
|
...item, |
||||
|
structName: res.rows.find(p=>p.id==c)?.name, |
||||
|
xjId: rslt.rows?.find(q => q.axyProjectId == item.structId)?.structureId |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
data.unshift({text: '全部', value: 'all' }) |
||||
|
this.setData({ |
||||
|
structList:data, |
||||
|
list:listt, |
||||
|
listCopy:listt |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
wx.hideLoading() |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面初次渲染完成 |
||||
|
*/ |
||||
|
onReady() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面显示 |
||||
|
*/ |
||||
|
onShow() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面隐藏 |
||||
|
*/ |
||||
|
onHide() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面卸载 |
||||
|
*/ |
||||
|
onUnload() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面相关事件处理函数--监听用户下拉动作 |
||||
|
*/ |
||||
|
onPullDownRefresh() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面上拉触底事件的处理函数 |
||||
|
*/ |
||||
|
onReachBottom() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 用户点击右上角分享 |
||||
|
*/ |
||||
|
onShareAppMessage() { |
||||
|
|
||||
|
} |
||||
|
}) |
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
|
||||
|
"navigationBarTitleText": "用电监控", |
||||
|
"usingComponents": { |
||||
|
"van-button": "@vant/weapp/button/index", |
||||
|
"van-cell": "@vant/weapp/cell/index", |
||||
|
"van-cell-group": "@vant/weapp/cell-group/index", |
||||
|
"van-dropdown-menu": "@vant/weapp/dropdown-menu/index", |
||||
|
"van-dropdown-item": "@vant/weapp/dropdown-item/index", |
||||
|
"van-empty": "@vant/weapp/empty/index", |
||||
|
"van-switch": "@vant/weapp/switch/index" |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
<!--package/AIOTOverview/electricityMonitoring/electricityMonitoring.wxml--> |
||||
|
<view> |
||||
|
<!--结构物选择器--> |
||||
|
<view class="select"> |
||||
|
<van-dropdown-menu active-color="#1989fa"> |
||||
|
<van-dropdown-item title="{{ '结构物' }}" bind:close="onClose" bind:change="onStruChange" value="{{ curStruId }}" options="{{ structList }}" /> |
||||
|
</van-dropdown-menu> |
||||
|
</view> |
||||
|
<!--渲染列表--> |
||||
|
<view wx:if="{{list.length}}"> |
||||
|
<view class="card" wx:for="{{list}}" wx:key='index'> |
||||
|
<!--头部--> |
||||
|
<view class="top"> |
||||
|
<view style="display: flex; align-items: center;"> |
||||
|
<text class="fontStyle">{{item.structName}}</text> |
||||
|
</view> |
||||
|
<view> |
||||
|
<switch disabled="{{!item.data.data||item.data.data.info&&item.data.data.info.includes('离线')}}" bindchange="switch1Change" data-item="{{item}}"/> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!--内容部分--> |
||||
|
<view class="card-content"> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left" style="font-weight: bold;">{{item.name}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">运行状态</view> |
||||
|
<view class="content-right" wx:if="{{!item.data.data}}">{{'离线'}}</view> |
||||
|
<view class="content-right" wx:if="{{item.data.data.info&&item.data.data.info.includes('离线')}}">{{'离线'}}</view> |
||||
|
<view class="content-right" wx:if="{{item.data.data.info&&item.data.data.info.includes('正常')}}">{{'正常'}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">电源状态</view> |
||||
|
<view class="content-right" wx:if="{{!item.data.data}}">{{'离线'}}</view> |
||||
|
<view class="content-right" wx:if="{{item.data.data.info&&item.data.data.info.includes('离线')}}">{{'离线'}}</view> |
||||
|
<view class="content-right" wx:if="{{item.data.data.info&&item.data.data.info.includes('正常')}}">{{'正常'}}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view wx:else> |
||||
|
<van-empty description="暂无数据" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
|
@ -0,0 +1,64 @@ |
|||||
|
/* package/AIOTOverview/electricityMonitoring/electricityMonitoring.wxss */ |
||||
|
.select { |
||||
|
width: 50%; |
||||
|
} |
||||
|
|
||||
|
.select .van-dropdown-menu { |
||||
|
box-shadow: none |
||||
|
} |
||||
|
|
||||
|
/* package/AIOTOverview/AIOTOverview.wxss */ |
||||
|
|
||||
|
|
||||
|
.card { |
||||
|
position: relative; |
||||
|
background-color: #fff; |
||||
|
border: 1px solid #ddd; |
||||
|
border-radius: 8px; |
||||
|
/* padding: 10px; */ |
||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
||||
|
margin: 12px 12px; |
||||
|
} |
||||
|
|
||||
|
.top { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
padding: 10px; |
||||
|
|
||||
|
/* background-position: bottom; */ |
||||
|
} |
||||
|
|
||||
|
.card-content { |
||||
|
padding: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.card-left { |
||||
|
margin-left: 23px; |
||||
|
margin-bottom: 10px; |
||||
|
font-weight: 500; |
||||
|
font-size: 16px; |
||||
|
color: #000000d9; |
||||
|
} |
||||
|
|
||||
|
.detail { |
||||
|
margin: 10px 0 |
||||
|
} |
||||
|
|
||||
|
.card-right { |
||||
|
margin-right: 18px; |
||||
|
margin-bottom: 10px; |
||||
|
color: #1684FF; |
||||
|
} |
||||
|
|
||||
|
.fontStyle { |
||||
|
font-family: PingFangSC-Medium; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.content-left { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.content-right { |
||||
|
font-size: 14px; |
||||
|
text-align: right; |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
// package/AIOTOverview/flowMonitoring/flowMonitoring.js
|
||||
|
import { getProjectList, getRelationList } from "../../../utils/getApiUrl"; |
||||
|
import { Request } from "../../../common"; |
||||
|
const moment = require("../../../utils/moment"); |
||||
|
Page({ |
||||
|
|
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
structList: [], |
||||
|
curStruId: 'all', // 选中结构物id
|
||||
|
cardData: [], |
||||
|
cardDataCopy: [] |
||||
|
}, |
||||
|
onClose(e) { |
||||
|
// 获取报告
|
||||
|
// this.getPatrolReport();
|
||||
|
}, |
||||
|
onStruChange(e) { |
||||
|
if (e.detail) { |
||||
|
let data = [] |
||||
|
if (e.detail === 'all') { |
||||
|
data = this.data.cardDataCopy |
||||
|
} else { |
||||
|
data = this.data.cardDataCopy.filter(item => item.xjId === e.detail) |
||||
|
} |
||||
|
this.setData({ |
||||
|
curStruId: e.detail, |
||||
|
cardData: data |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
async onLoad(options) { |
||||
|
let dd = [] |
||||
|
const complexArray = JSON.parse(decodeURIComponent(options.data)) |
||||
|
//获取结构物列表(巡检)
|
||||
|
const res = await Request.get(getProjectList()) |
||||
|
const rslt = await Request.get(getRelationList()) |
||||
|
if (res.rows.length && rslt.rows.length) { |
||||
|
const data = res.rows.map(item => { |
||||
|
return { |
||||
|
value: rslt.rows.find(q => item.id === q.structureId)?.id, |
||||
|
text: item.name |
||||
|
} |
||||
|
}) |
||||
|
data.unshift({ text: '全部', value: 'all' }) |
||||
|
if (complexArray && complexArray.length) { |
||||
|
dd = complexArray.map(item => { |
||||
|
return { |
||||
|
...item, |
||||
|
structName: data?.find(q => q.value == item.xjId)?.text |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
this.setData({ |
||||
|
structList: data, |
||||
|
cardData:dd , |
||||
|
cardDataCopy:dd |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面初次渲染完成 |
||||
|
*/ |
||||
|
onReady() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面显示 |
||||
|
*/ |
||||
|
onShow() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面隐藏 |
||||
|
*/ |
||||
|
onHide() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面卸载 |
||||
|
*/ |
||||
|
onUnload() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面相关事件处理函数--监听用户下拉动作 |
||||
|
*/ |
||||
|
onPullDownRefresh() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面上拉触底事件的处理函数 |
||||
|
*/ |
||||
|
onReachBottom() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 用户点击右上角分享 |
||||
|
*/ |
||||
|
onShareAppMessage() { |
||||
|
|
||||
|
} |
||||
|
}) |
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"navigationBarTitleText": "流量监控", |
||||
|
"usingComponents": { |
||||
|
"van-button": "@vant/weapp/button/index", |
||||
|
"van-cell": "@vant/weapp/cell/index", |
||||
|
"van-cell-group": "@vant/weapp/cell-group/index", |
||||
|
"van-dropdown-menu": "@vant/weapp/dropdown-menu/index", |
||||
|
"van-dropdown-item": "@vant/weapp/dropdown-item/index", |
||||
|
"van-empty": "@vant/weapp/empty/index" |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<!--package/AIOTOverview/flowMonitoring/flowMonitoring.wxml--> |
||||
|
<view> |
||||
|
<!--结构物选择器--> |
||||
|
<view class="select"> |
||||
|
<van-dropdown-menu active-color="#1989fa"> |
||||
|
<van-dropdown-item title="{{ '结构物' }}" bind:close="onClose" bind:change="onStruChange" value="{{ curStruId }}" options="{{ structList }}" /> |
||||
|
</van-dropdown-menu> |
||||
|
</view> |
||||
|
<!--渲染列表--> |
||||
|
<view wx:if="{{cardData.length}}"> |
||||
|
<view class="card" wx:for="{{cardData}}" wx:key='index'> |
||||
|
<view> |
||||
|
<!--头部--> |
||||
|
<view class="top"> |
||||
|
<view style="display: flex; align-items: center;"> |
||||
|
<text class="fontStyle">{{item.structName}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!--内容部分--> |
||||
|
<view class="card-content"> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left" style="font-weight: bold;">{{item.name}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail"> |
||||
|
<view class="content-left">物联卡号:{{item.cardNo}}</view> |
||||
|
<view class="content-right">套餐类型:{{item.pType}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail content"> |
||||
|
<view wx:if="{{item.status==0}}" class="content-left">卡状态:正常</view> |
||||
|
<view wx:if="{{item.status==1}}" class="content-left">卡状态:未激活</view> |
||||
|
<view wx:if="{{item.status==2}}" class="content-left">卡状态:停机</view> |
||||
|
<view class="content-right">套餐总量:{{item.total}}</view> |
||||
|
</view> |
||||
|
<view class="row flex flex-between detail content"> |
||||
|
<view class="content-left">卡余额:{{item.allowance}}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view wx:else> |
||||
|
<van-empty description="暂无数据" /> |
||||
|
</view> |
||||
|
</view> |
@ -0,0 +1,70 @@ |
|||||
|
/* package/AIOTOverview/flowMonitoring/flowMonitoring.wxss */ |
||||
|
|
||||
|
|
||||
|
.select { |
||||
|
width: 50%; |
||||
|
} |
||||
|
|
||||
|
.select .van-dropdown-menu { |
||||
|
box-shadow: none |
||||
|
} |
||||
|
|
||||
|
/* package/AIOTOverview/AIOTOverview.wxss */ |
||||
|
|
||||
|
|
||||
|
.card { |
||||
|
position: relative; |
||||
|
background-color: #fff; |
||||
|
border: 1px solid #ddd; |
||||
|
border-radius: 8px; |
||||
|
/* padding: 10px; */ |
||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
||||
|
margin: 12px 12px; |
||||
|
} |
||||
|
|
||||
|
.top { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
padding: 10px; |
||||
|
|
||||
|
/* background-position: bottom; */ |
||||
|
} |
||||
|
|
||||
|
.card-content { |
||||
|
padding: 0 10px; |
||||
|
} |
||||
|
|
||||
|
.card-left { |
||||
|
margin-left: 23px; |
||||
|
margin-bottom: 10px; |
||||
|
font-weight: 500; |
||||
|
font-size: 16px; |
||||
|
color: #000000d9; |
||||
|
} |
||||
|
|
||||
|
.detail { |
||||
|
margin: 10px 0 |
||||
|
} |
||||
|
|
||||
|
.card-right { |
||||
|
margin-right: 18px; |
||||
|
margin-bottom: 10px; |
||||
|
color: #1684FF; |
||||
|
} |
||||
|
|
||||
|
.fontStyle { |
||||
|
font-family: PingFangSC-Medium; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.content-left { |
||||
|
font-size: 12px; |
||||
|
width: 60%; |
||||
|
} |
||||
|
|
||||
|
.content-right { |
||||
|
font-size: 12px; |
||||
|
text-align: left; |
||||
|
width: 40%; |
||||
|
|
||||
|
} |
@ -0,0 +1,530 @@ |
|||||
|
// package/report/report.js
|
||||
|
|
||||
|
import { getPointList,getPatrolTemplates,getPatrolTemplate,getTemplates,reportQuest,getPatrolPlan,getStructuresList,getDetail } from "../../utils/getApiUrl"; |
||||
|
import {Request} from "../../common"; |
||||
|
const moment = require("../../utils/moment"); |
||||
|
|
||||
|
Page({ |
||||
|
data: { |
||||
|
sms:'',//设备号
|
||||
|
sList:[],//根据sn号查询的结构物列表
|
||||
|
structListIndex: undefined,//结构物id
|
||||
|
struct:'',//结构物
|
||||
|
pointList:[],//点位列表
|
||||
|
pointIndex:undefined,//点位索引
|
||||
|
list:[],//初始数据
|
||||
|
pointVis:false,//点位输入框的可见性
|
||||
|
formVis:false,//表单项可见性
|
||||
|
handleObj:'',//处理对象
|
||||
|
handleGoal:'',//处理目的
|
||||
|
installLocation:'',//安装位置
|
||||
|
rtuNo:'',//RTU编号
|
||||
|
isPlanState: false, |
||||
|
structList: [],//结构物列表
|
||||
|
data:[],//巡检计划的数据(包括点位,设备等等)
|
||||
|
patrolTemplate:[],//巡检模板
|
||||
|
templateData:[],//巡检模板总数居
|
||||
|
patrolTemplateIndex:undefined,//巡检模板索引
|
||||
|
itemData: '', // 点位
|
||||
|
address: '', // 当前位置
|
||||
|
imgUrl: getApp().globalData.imgUrl, |
||||
|
checkItems: [], // 检查项
|
||||
|
inspectContentArr: [], // 巡检内容
|
||||
|
isCommitting: false, |
||||
|
}, |
||||
|
|
||||
|
//卡号接收
|
||||
|
onInputChange(e){ |
||||
|
this.setData({ |
||||
|
sms:e.detail, |
||||
|
sList:[] |
||||
|
}) |
||||
|
}, |
||||
|
//根据sn号搜索
|
||||
|
searchDetail(){ |
||||
|
const id=this.data.sms |
||||
|
if(id){ |
||||
|
Request.get(getDetail(id)).then(res => { |
||||
|
if(res){ |
||||
|
//结构物
|
||||
|
if(!res.length){ |
||||
|
wx.showToast({ |
||||
|
title: '未查询到相关数据', |
||||
|
icon: 'none', |
||||
|
duration: 1500 |
||||
|
}) |
||||
|
return; |
||||
|
} |
||||
|
const uniqueResults = res.reduce((acc, item) => { |
||||
|
const existingItem = acc.find(project => project.id === item.project.id); |
||||
|
if (!existingItem) { |
||||
|
acc.push({ |
||||
|
id: item.project.id, |
||||
|
name: item.project.name |
||||
|
}); |
||||
|
} |
||||
|
return acc |
||||
|
}, []) |
||||
|
this.setData({ |
||||
|
sList:uniqueResults, |
||||
|
list:res |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
//点位改变函数
|
||||
|
pointChange(e){ |
||||
|
const that = this |
||||
|
// that.getPatrolTemplate()
|
||||
|
Request.get(getPatrolTemplates()).then(res=>{ |
||||
|
if(res){ |
||||
|
const rlst=res.rows?.map(item=>{return { |
||||
|
id:item.id, |
||||
|
name:item.name |
||||
|
}}) |
||||
|
that.setData({patrolTemplate:rlst,templateData:res.rows, |
||||
|
pointIndex:e.detail.value, |
||||
|
formVis:true, |
||||
|
inspectContentArr:[], |
||||
|
patrolTemplateIndex:null |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
//整理设备和检查项
|
||||
|
getPatrolTemplate(templateId,pointDevices=[]) { |
||||
|
const that=this |
||||
|
Request.get(getPatrolTemplate(templateId)).then(res => { |
||||
|
const checkItems = res.rows[0].checkItems; |
||||
|
let inspectContentArr = []; |
||||
|
// 有绑定设备的点位,每个设备都要检查各个检查项
|
||||
|
if (pointDevices.length) { |
||||
|
pointDevices.forEach(device => { |
||||
|
inspectContentArr.push({ |
||||
|
deviceName: device.name, |
||||
|
deviceId: device.id, |
||||
|
checkItems: checkItems.map(c => ({ |
||||
|
id: `${device.id}-${c.id}`, |
||||
|
name: c.name, |
||||
|
isNormal: true, |
||||
|
msgInp: null, |
||||
|
level: null, |
||||
|
imgs: [], |
||||
|
})) |
||||
|
}) |
||||
|
}); |
||||
|
} else { |
||||
|
inspectContentArr.push({ |
||||
|
checkItems: checkItems.map(c => ({ |
||||
|
id: c.id, |
||||
|
name: c.name, |
||||
|
isNormal: true, |
||||
|
msgInp: null, |
||||
|
level: null, |
||||
|
imgs: [], |
||||
|
})) |
||||
|
}) |
||||
|
} |
||||
|
this.setData({ |
||||
|
checkItems, |
||||
|
inspectContentArr: inspectContentArr, |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
//收集输入框的值
|
||||
|
input1Change(e){ |
||||
|
const that = this |
||||
|
that.setData({handleObj:e.detail}) |
||||
|
}, |
||||
|
input2Change(e){ |
||||
|
const that = this |
||||
|
that.setData({handleGoal:e.detail}) |
||||
|
}, |
||||
|
input3Change(e){ |
||||
|
const that = this |
||||
|
that.setData({installLocation:e.detail}) |
||||
|
}, |
||||
|
input4Change(e){ |
||||
|
const that = this |
||||
|
that.setData({rtuNo:e.detail}) |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
|
||||
|
// 预览图片
|
||||
|
previewImg: function (e) { |
||||
|
const { deviceidx, itemidx, index } = e.currentTarget.dataset; |
||||
|
// 所有图片
|
||||
|
const imgs = this.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; |
||||
|
const newImgs = imgs.map(i => this.data.imgUrl + i); |
||||
|
wx.previewImage({ |
||||
|
// 当前显示图片
|
||||
|
current: newImgs[index], |
||||
|
// 所有图片
|
||||
|
urls: newImgs |
||||
|
}) |
||||
|
}, |
||||
|
//结构物改变函数
|
||||
|
structChange(event) { |
||||
|
const that = this |
||||
|
const projectId=that.data.sList.find(item=>item.id==that.data?.sList[Number(event.detail.value)].id)?.id |
||||
|
const query={projectId} |
||||
|
Request.get(getPointList(query)).then(res => { |
||||
|
if(res){ |
||||
|
that.setData({data:res}) |
||||
|
} |
||||
|
}) |
||||
|
that.setData({ |
||||
|
pointVis:false, |
||||
|
pointList:[],//选择结构物后先置空先前的点位列表
|
||||
|
formVis:false, |
||||
|
pointIndex:null, |
||||
|
inspectContentArr:[] |
||||
|
}) |
||||
|
const rlst=that.data.list?.filter(item=>item.project.id==projectId)?.map(item=>{ |
||||
|
return { |
||||
|
id: item.id, |
||||
|
name: item.name |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
that.setData({ |
||||
|
structListIndex:event.detail.value, |
||||
|
pointList:rlst, |
||||
|
pointVis:true |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
|
||||
|
//选择异常或者正常
|
||||
|
handleChangeTwo(e) { |
||||
|
const { deviceidx, itemidx } = e.currentTarget.dataset; |
||||
|
let nextInspectContentArr = this.data.inspectContentArr; |
||||
|
|
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].isNormal = e.detail; |
||||
|
if (e.detail) { // 清除异常数据
|
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].msgInp = null; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].level = null; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = []; |
||||
|
} |
||||
|
this.setData({ inspectContentArr: nextInspectContentArr }) |
||||
|
}, |
||||
|
//返回前一页
|
||||
|
bindCancel() { |
||||
|
wx.navigateBack(); |
||||
|
}, |
||||
|
// 开始巡检录入
|
||||
|
addPatrolRecord: function () { |
||||
|
const that = this; |
||||
|
if (that.data.isCommitting) { return } |
||||
|
let { |
||||
|
rtuNo, |
||||
|
installLocation, |
||||
|
handleGoal, |
||||
|
handleObj, |
||||
|
patrolTemplate, |
||||
|
patrolTemplateIndex, |
||||
|
structListIndex, |
||||
|
pointIndex, |
||||
|
inspectContentArr, |
||||
|
pointList, |
||||
|
sList |
||||
|
} = that.data; |
||||
|
let alarm = false; |
||||
|
|
||||
|
|
||||
|
if (!patrolTemplateIndex) { |
||||
|
wx.showToast({ |
||||
|
title: '请选择模板', |
||||
|
icon: 'none', |
||||
|
duration: 1500 |
||||
|
}) |
||||
|
return; |
||||
|
} |
||||
|
if (!pointIndex) { |
||||
|
wx.showToast({ |
||||
|
title: '请选择点位', |
||||
|
icon: 'none', |
||||
|
duration: 1500 |
||||
|
}) |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
let reportArr = inspectContentArr.map(d => ({ ...d, alarm:d.checkItems.some(q=>q.isNormal==false)?true:false })) |
||||
|
for (const d of reportArr[0]?.checkItems) { |
||||
|
if (d.isNormal === null) { |
||||
|
wx.showToast({ |
||||
|
title: '请填写完整', |
||||
|
icon: 'none', |
||||
|
duration: 1500 |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
if ((!d.isNormal) && (!d.level || !d.msgInp)) { |
||||
|
wx.showToast({ |
||||
|
title: '异常项必须输入巡查详情和选择严重等级', |
||||
|
icon: 'none', |
||||
|
duration: 2000 |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
if (d.isNormal === false) { |
||||
|
alarm = true; // 巡检记录异常
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const { id, name, departmentId, deptName } = wx.getStorageSync('userInfo'); |
||||
|
const newData = that.data.data.map((item) => { |
||||
|
// let pointDevices=[]
|
||||
|
// item.devices.map(child=>{
|
||||
|
// const {pointDevice,...newItem } = child;
|
||||
|
// pointDevices.push({device:newItem,deviceId:pointDevice.deviceId})
|
||||
|
// })
|
||||
|
// 使用对象的解构赋值去掉 project 和 devices 属性
|
||||
|
const { project, devices, ...newItem } = item; |
||||
|
// return {...newItem,pointDevices}
|
||||
|
return {...newItem} |
||||
|
|
||||
|
}); |
||||
|
const nextItemData=newData.find(item=>item.id===pointList[pointIndex].id) |
||||
|
let datas = { |
||||
|
patrolPlanId: -1, |
||||
|
pointId: sList[pointIndex].id, |
||||
|
inspectionTime: moment().format('YYYY-MM-DD HH:mm:ss'), |
||||
|
points: { |
||||
|
user: { id, name, department: { id: departmentId, name: deptName } }, |
||||
|
project: sList[structListIndex], |
||||
|
itemData:nextItemData, |
||||
|
inspectContent: reportArr, |
||||
|
aboutDisaster:{ rtuNo, |
||||
|
installLocation, |
||||
|
handleGoal, |
||||
|
handleObj} |
||||
|
}, |
||||
|
alarm, |
||||
|
projectId: sList[structListIndex].id |
||||
|
} |
||||
|
wx.showLoading({ title: '提交中...' }); |
||||
|
that.setData({ isCommitting: true }); |
||||
|
Request.post(reportQuest(), datas).then(res => { |
||||
|
wx.hideLoading(); |
||||
|
that.setData({ isCommitting: false }); |
||||
|
wx.showToast({ |
||||
|
title: '提交成功', |
||||
|
icon: 'success' |
||||
|
}) |
||||
|
setTimeout(() => { |
||||
|
that.bindCancel(); |
||||
|
}, 1500) |
||||
|
}) |
||||
|
}, |
||||
|
//多张图片上传
|
||||
|
uploadImg: function (data, deviceidx, itemidx) { |
||||
|
wx.showLoading({ |
||||
|
title: '上传中...', |
||||
|
mask: true, |
||||
|
}) |
||||
|
let that = this, |
||||
|
i = data.i ? data.i : 0, |
||||
|
success = data.success ? data.success : 0, |
||||
|
fail = data.fail ? data.fail : 0; |
||||
|
let imgs = that.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; |
||||
|
wx.uploadFile({ |
||||
|
url: data.url, |
||||
|
filePath: data.path[i], |
||||
|
name: 'file', |
||||
|
success: (resp) => { |
||||
|
wx.hideLoading(); |
||||
|
success++; |
||||
|
let str = JSON.parse(resp.data) // 返回的结果,可能不同项目结果不一样
|
||||
|
str = str.uploaded |
||||
|
if (imgs.length >= 20) { |
||||
|
let nextInspectContentArr = that.data.inspectContentArr; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = imgs; |
||||
|
that.setData({ inspectContentArr: nextInspectContentArr }); |
||||
|
return false; |
||||
|
} else { |
||||
|
imgs.push(str); |
||||
|
let nextInspectContentArr = that.data.inspectContentArr; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = imgs; |
||||
|
that.setData({ inspectContentArr: nextInspectContentArr }); |
||||
|
} |
||||
|
}, |
||||
|
fail: (res) => { |
||||
|
fail++; |
||||
|
console.log('fail:' + i + "fail:" + fail); |
||||
|
}, |
||||
|
complete: () => { |
||||
|
i++; |
||||
|
if (i == data.path.length) { // 当图片传完时,停止调用
|
||||
|
console.log('执行完毕'); |
||||
|
console.log('成功:' + success + " 失败:" + fail); |
||||
|
} else { // 若图片还没有传完,则继续调用函数
|
||||
|
data.i = i; |
||||
|
data.success = success; |
||||
|
data.fail = fail; |
||||
|
that.uploadImg(data, deviceidx, itemidx); // 递归,回调自己
|
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
// 上传图片
|
||||
|
chooseImg: function (e) { // 这里是选取图片的方法
|
||||
|
const { deviceidx, itemidx } = e.currentTarget.dataset; |
||||
|
const that = this; |
||||
|
let pics = []; |
||||
|
const detailPics = that.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; |
||||
|
if (detailPics.length >= 20) { |
||||
|
wx.showToast({ |
||||
|
title: '最多选择20张图片上传', |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
wx.chooseMedia({ |
||||
|
count: 20, // 基础库2.25.0前,最多可支持9个文件,2.25.0及以后最多可支持20个文件
|
||||
|
mediaType: ['image'], // 文件类型
|
||||
|
sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
|
||||
|
sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
|
||||
|
success: function (res) { |
||||
|
const imgs = res.tempFiles; |
||||
|
for (let i = 0; i < imgs.length; i++) { |
||||
|
if (res.tempFiles[i].size > 15728640) { |
||||
|
wx.showToast({ title: '图片大于15M,不可上传', icon: 'none' }); |
||||
|
return; |
||||
|
} |
||||
|
const fileNameArr = res.tempFiles[i].tempFilePath.split('.'); |
||||
|
const extension = res.tempFiles[i].tempFilePath.split('.')[fileNameArr.length - 1]; |
||||
|
if (extension !== 'jpg' && extension !== 'png' && extension !== 'jpeg') { |
||||
|
wx.showToast({ title: '只能上传jpg、jpeg、png格式的图片', icon: 'none' }); |
||||
|
return; |
||||
|
} |
||||
|
pics.push(imgs[i].tempFilePath) |
||||
|
} |
||||
|
that.uploadImg({ |
||||
|
url: getApp().globalData.webUrl + '_upload/attachments/project', // 图片上传的接口
|
||||
|
path: pics, // 选取的图片的地址数组
|
||||
|
}, deviceidx, itemidx); |
||||
|
}, |
||||
|
}) |
||||
|
}, |
||||
|
// 删除图片
|
||||
|
deleteImg: function (e) { |
||||
|
const { deviceidx, itemidx, index } = e.currentTarget.dataset; |
||||
|
let imgs = this.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; |
||||
|
imgs.splice(index, 1); |
||||
|
let nextInspectContentArr = this.data.inspectContentArr; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = imgs; |
||||
|
this.setData({ inspectContentArr: nextInspectContentArr }) |
||||
|
}, |
||||
|
// 巡查详情
|
||||
|
bindInput: function (e) { |
||||
|
const { deviceidx, itemidx } = e.currentTarget.dataset; |
||||
|
let nextInspectContentArr = this.data.inspectContentArr; |
||||
|
|
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].msgInp = e.detail.value; |
||||
|
this.setData({ inspectContentArr: nextInspectContentArr }) |
||||
|
}, |
||||
|
|
||||
|
handleChangeThree(e) { |
||||
|
const { deviceidx, itemidx } = e.currentTarget.dataset; |
||||
|
let nextInspectContentArr = this.data.inspectContentArr; |
||||
|
nextInspectContentArr[deviceidx].checkItems[itemidx].level = e.detail; |
||||
|
this.setData({ inspectContentArr: nextInspectContentArr }) |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
//巡检模板改变
|
||||
|
patrolTemplateChange(e){ |
||||
|
const that=this |
||||
|
that.getPatrolTemplate(that.data.patrolTemplate[e.detail.value].id) |
||||
|
that.setData({ |
||||
|
patrolTemplateIndex:e.detail.value |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
bindShowMsg() { |
||||
|
this.setData({ |
||||
|
select: !this.data.select |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
mySelect(e) { |
||||
|
var name = e.currentTarget.dataset.name |
||||
|
this.setData({ |
||||
|
tihuoWay: name, |
||||
|
select: false |
||||
|
}) |
||||
|
}, |
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
// data: {
|
||||
|
|
||||
|
// },
|
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
onLoad(options) { |
||||
|
const that=this |
||||
|
wx.setNavigationBarTitle({ |
||||
|
title: options.key, |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面初次渲染完成 |
||||
|
*/ |
||||
|
onReady() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面显示 |
||||
|
*/ |
||||
|
onShow() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面隐藏 |
||||
|
*/ |
||||
|
onHide() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面卸载 |
||||
|
*/ |
||||
|
onUnload() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面相关事件处理函数--监听用户下拉动作 |
||||
|
*/ |
||||
|
onPullDownRefresh() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面上拉触底事件的处理函数 |
||||
|
*/ |
||||
|
onReachBottom() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 用户点击右上角分享 |
||||
|
*/ |
||||
|
onShareAppMessage() { |
||||
|
|
||||
|
} |
||||
|
}) |
@ -0,0 +1,25 @@ |
|||||
|
{ |
||||
|
"navigationBarBackgroundColor": "#1979ff", |
||||
|
"navigationBarTextStyle": "white", |
||||
|
"navigationBarTitleText": "地灾巡检", |
||||
|
"enablePullDownRefresh": false, |
||||
|
"componentFramework": "glass-easel", |
||||
|
"usingComponents": { |
||||
|
"van-button": "@vant/weapp/button/index", |
||||
|
"van-field": "@vant/weapp/field/index", |
||||
|
"van-cell": "@vant/weapp/cell/index", |
||||
|
"van-cell-group": "@vant/weapp/cell-group/index", |
||||
|
"van-picker": "@vant/weapp/picker/index", |
||||
|
"van-popup": "@vant/weapp/popup/index", |
||||
|
"van-icon": "@vant/weapp/icon/index", |
||||
|
"van-collapse": "@vant/weapp/collapse/index", |
||||
|
"van-collapse-item": "@vant/weapp/collapse-item/index", |
||||
|
"van-divider": "@vant/weapp/divider/index", |
||||
|
"t-cell-group": "tdesign-miniprogram/cell-group/cell-group", |
||||
|
"t-cell": "tdesign-miniprogram/cell/cell", |
||||
|
"t-picker": "tdesign-miniprogram/picker/picker", |
||||
|
"t-picker-item": "tdesign-miniprogram/picker-item/picker-item", |
||||
|
"van-radio": "@vant/weapp/radio/index", |
||||
|
"van-radio-group": "@vant/weapp/radio-group/index" |
||||
|
} |
||||
|
} |
@ -0,0 +1,95 @@ |
|||||
|
<view class="popBox"> |
||||
|
<view> |
||||
|
<van-cell-group class="mission-card"> |
||||
|
<van-cell-group> |
||||
|
<van-field value="{{ sms }}" bind:input="onInputChange" center clearable label="设备SN号" placeholder="设备SN号" border="{{ false }}" use-button-slot> |
||||
|
<van-button slot="button" size="small" type="info" bindtap="searchDetail"> |
||||
|
搜索 |
||||
|
</van-button> |
||||
|
</van-field> |
||||
|
</van-cell-group> |
||||
|
<van-cell wx:if="{{sList.length}}"> |
||||
|
<view style="display:flex"> |
||||
|
<view class="fs-cell-title" style="">结构物:</view> |
||||
|
<picker style="width:100%;text-align:left" bindchange="structChange" data-type='jiegouwu' value="{{0}}" range="{{sList}}" range-key="name"> |
||||
|
<view class="fs-cell-content" style="width:100%"> |
||||
|
{{structListIndex||structListIndex==0?sList[structListIndex].name:'请选择'}} |
||||
|
<van-icon name="arrow" style="float:right;position:relative; top:4px" /> |
||||
|
</view> |
||||
|
</picker> |
||||
|
</view> |
||||
|
</van-cell> |
||||
|
<van-cell wx:if="{{pointVis}}"> |
||||
|
<view style="display:flex"> |
||||
|
<view class="fs-cell-title" style="">当前点位:</view> |
||||
|
<picker style="width:100%;text-align:left" bindchange="pointChange" data-type='point' value="{{0}}" range="{{pointList}}" range-key="name"> |
||||
|
<view class="fs-cell-content" style="width:100%"> |
||||
|
{{pointIndex||pointIndex==0?pointList[pointIndex].name:'请选择'}} |
||||
|
<van-icon name="arrow" style="float:right;position:relative; top:4px" /> |
||||
|
</view> |
||||
|
</picker> |
||||
|
</view> |
||||
|
</van-cell> |
||||
|
<!--表单项渲染--> |
||||
|
<view wx:if="{{formVis}}"> |
||||
|
<van-cell-group > |
||||
|
<van-field value="{{handleObj}}" bind:change="input1Change" type="textarea" autosize label="排查及处理对象:" placeholder="排查及处理对象" accordion title-width="110px" /> |
||||
|
<van-field value="{{ handleGoal }}" bind:change="input2Change" type="textarea" autosize label="排查及处理目的:" placeholder="排查及处理目的" accordion title-width="110px"/> |
||||
|
<van-field value="{{ installLocation }}" bind:change="input3Change" type="textarea" autosize label="安装位置:" placeholder="安装位置" accordion /> |
||||
|
<van-field value="{{ rtuNo }}" type="textarea" bind:change="input4Change" autosize label="RTU编号:" placeholder="RTU编号" accordion /> |
||||
|
</van-cell-group> |
||||
|
<van-cell > |
||||
|
<view style="display:flex"> |
||||
|
<view class="fs-cell-title">巡检模板:</view> |
||||
|
<picker style="width:100%;text-align:left" bindchange="patrolTemplateChange" data-type='template' value="{{0}}" range="{{patrolTemplate}}" range-key="name"> |
||||
|
<view class="fs-cell-content" style="width:100%"> |
||||
|
{{patrolTemplateIndex||patrolTemplateIndex==0?patrolTemplate[patrolTemplateIndex].name:'请选择'}} |
||||
|
<van-icon name="arrow" style="float:right;position:relative; top:4px" /> |
||||
|
</view> |
||||
|
</picker> |
||||
|
</view> |
||||
|
</van-cell> |
||||
|
</view> |
||||
|
</van-cell-group> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 渲染巡检内容 --> |
||||
|
<view wx:for="{{inspectContentArr}}" wx:key="id" wx:for-item="device" wx:for-index="deviceidx"> |
||||
|
<view wx:if="{{device.deviceName}}" class="flex flex-start" style="height: 40px">{{device.deviceName}}</view> |
||||
|
<view wx:for="{{device.checkItems}}" wx:key="id" wx:for-index="itemidx"> |
||||
|
<view class="flex-between"> |
||||
|
<view class="item-name">{{item.name}}:</view> |
||||
|
<van-radio-group style="padding:10px 15px;" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" bindchange="handleChangeTwo" value="{{item.isNormal}}"> |
||||
|
<van-radio style="margin-right: 20px;" class="radio-text" color="#1979ff" name="{{true}}">正常</van-radio> |
||||
|
<van-radio class="radio-text" checked-color="#CC0000" name="{{false}}">异常</van-radio> |
||||
|
</van-radio-group> |
||||
|
</view> |
||||
|
<view class="divider" /> |
||||
|
<van-radio-group class="flex-end" style="padding:10px 15px;" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" bindchange="handleChangeThree" wx:if="{{item.isNormal === false}}"> |
||||
|
<van-radio style="margin-right: 20px;" class="radio-text" checked-color="#FF9900" name="轻微">轻微</van-radio> |
||||
|
<van-radio style="margin-right: 20px;" class="radio-text" checked-color="#FF3300" name="中度">中度</van-radio> |
||||
|
<van-radio class="radio-text" checked-color="#990000" name="严重">严重</van-radio> |
||||
|
</van-radio-group> |
||||
|
<textarea class="textarea" placeholder="请输入巡查详情" maxlength="-1" wx:if="{{item.isNormal === false}}" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" bindinput="bindInput" /> |
||||
|
<view class="weui-uploader" style="padding: 20rpx 30rpx;overflow-y:scroll;" wx:if="{{item.isNormal === false}}"> |
||||
|
<view class="img-v weui-uploader__bd" style="overflow:hidden;"> |
||||
|
<view class="pic" wx:for="{{item.imgs}}" wx:for-item="img" wx:key="*this"> |
||||
|
<image class="weui-uploader__img showImg" src="{{imgUrl + img}}" data-index="{{index}}" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" mode="aspectFill" bindtap="previewImg"> |
||||
|
<icon type="cancel" class="delete-btn" data-index="{{index}}" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" catchtap="deleteImg" /> |
||||
|
</image> |
||||
|
</view> |
||||
|
<!-- 用来提示用户上传图片 --> |
||||
|
<view class="weui-uploader__input-box pic" data-item="{{item.name}}" data-deviceidx="{{deviceidx}}" data-itemidx="{{itemidx}}" bindtap="chooseImg"> |
||||
|
<image class="upload" src="/images/upload.png" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="divider" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="btnBox"> |
||||
|
<view class="cancel" bindtap="bindCancel">取消</view> |
||||
|
<view class="submit" bindtap="addPatrolRecord">提交</view> |
||||
|
</view> |
||||
|
</view> |
@ -0,0 +1,132 @@ |
|||||
|
.divider { |
||||
|
width: 100%; |
||||
|
height: 0px; |
||||
|
border-top: 1px solid #F5F5F5; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.flex-between { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.flex-end { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.popBox { |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
z-index: 1000; |
||||
|
background: #fff; |
||||
|
width: 95%; |
||||
|
margin-left: -356rpx; |
||||
|
padding: 20rpx 0; |
||||
|
} |
||||
|
|
||||
|
.item-name { |
||||
|
margin: 20rpx 0 0 30rpx; |
||||
|
} |
||||
|
|
||||
|
.btnBox { |
||||
|
padding: 50px 30rpx; |
||||
|
overflow: hidden; |
||||
|
font-size: 30rpx; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.cancel { |
||||
|
width: 38vw; |
||||
|
height: 42px; |
||||
|
line-height: 42px; |
||||
|
text-align: center; |
||||
|
background: #fff; |
||||
|
border: 1px solid #006BE3; |
||||
|
border-radius: 24px; |
||||
|
font-weight: 600; |
||||
|
font-size: 16px; |
||||
|
color: #1684FF; |
||||
|
} |
||||
|
|
||||
|
.submit { |
||||
|
width: 38vw; |
||||
|
height: 42px; |
||||
|
line-height: 42px; |
||||
|
text-align: center; |
||||
|
background: #1684FF; |
||||
|
border: 1px solid #006BE3; |
||||
|
border-radius: 24px; |
||||
|
font-weight: 600; |
||||
|
font-size: 16px; |
||||
|
color: #FFFFFF; |
||||
|
} |
||||
|
|
||||
|
.pic { |
||||
|
float: left; |
||||
|
position: relative; |
||||
|
margin-right: 8px; |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.showImg { |
||||
|
width: 160rpx; |
||||
|
height: 160rpx; |
||||
|
} |
||||
|
|
||||
|
.delete-btn { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
} |
||||
|
|
||||
|
.upload { |
||||
|
width: 63px; |
||||
|
height: 63px; |
||||
|
} |
||||
|
|
||||
|
.block { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
width: 18px; |
||||
|
height: 18px; |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
|
||||
|
.radio-text { |
||||
|
font-size: 14px; |
||||
|
color: #323233; |
||||
|
} |
||||
|
|
||||
|
.van-radio-group { |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.textarea { |
||||
|
width: 84%; |
||||
|
margin: 0 auto; |
||||
|
padding: 20rpx; |
||||
|
height: 120rpx; |
||||
|
border: 1px solid #61616166; |
||||
|
} |
||||
|
.mission-card-title { |
||||
|
background-color: #fff; |
||||
|
overflow: auto; |
||||
|
padding: 24rpx 16px; |
||||
|
display: flex; |
||||
|
align-items: center |
||||
|
} |
||||
|
.fs-cell-title { |
||||
|
max-width: 6.2em; |
||||
|
min-width: 6.2em; |
||||
|
margin-right: 12px; |
||||
|
text-align: left; |
||||
|
color: var(--field-label-color, #646566) |
||||
|
} |
||||
|
|
||||
|
.fs-cell-content { |
||||
|
color: var(--field-input-text-color, #323233) |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
|
||||
|
'use strict'; |
||||
|
import projectBinding from './projectBinding' |
||||
|
export default { |
||||
|
...projectBinding |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
'use strict'; |
||||
|
import { basicAction } from '@peace/utils' |
||||
|
import { ApiTable } from '$utils' |
||||
|
|
||||
|
export function getanxinyunProject(data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
dispatch: dispatch, |
||||
|
data, |
||||
|
actionType: 'GET_ANXINYUN_PROJECT', |
||||
|
url: `${ApiTable.getanxinyunProject}`, |
||||
|
msg: { error: '获取安心云结构物失败' }, |
||||
|
reducer: { name: 'anxinyunProject'} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
export function addorEditRelation(data) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'post', |
||||
|
dispatch: dispatch, |
||||
|
data, |
||||
|
actionType: 'ADD_OR_EDIT_RELATION', |
||||
|
url: `${ApiTable.addorEditRelation}`, |
||||
|
msg: { option:data?.id? '编辑绑定关系':'新增绑定关系' }, |
||||
|
// reducer: { name: 'anxinyunProject'}
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function getRelation(query) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'get', |
||||
|
query, |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'GET_RELATION', |
||||
|
url: `${ApiTable.getRelation}`, |
||||
|
msg: { error:'查询项目映射关系失败' }, |
||||
|
reducer: { name: 'relation'} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
export function delRelation(id) { |
||||
|
return dispatch => basicAction({ |
||||
|
type: 'delete', |
||||
|
dispatch: dispatch, |
||||
|
actionType: 'DEL_RELATION', |
||||
|
url: ApiTable.delRelation.replace('{id}', id), |
||||
|
msg: { option:'删除项目映射关系' }, |
||||
|
// reducer: { name: 'anxinyunProject'}
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
export default{ |
||||
|
getanxinyunProject, |
||||
|
getRelation, |
||||
|
addorEditRelation, |
||||
|
delRelation |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
import React, { useRef,useState,useEffect } from 'react' |
||||
|
import { Button, Form } from 'antd' |
||||
|
import { connect } from 'react-redux'; |
||||
|
import { InfoCircleOutlined } from '@ant-design/icons' |
||||
|
import { ModalForm, ProFormSelect, ProFormText, ProFormDatePicker } from '@ant-design/pro-form' |
||||
|
import moment from 'moment' |
||||
|
function RelationModal(props) { |
||||
|
const { title, triggerRender, editData = null, onFinish, devices,actions,dispatch,proejctListOpt,structureListOpt } = props |
||||
|
const{projectBinding}=actions |
||||
|
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } } |
||||
|
const initialValues = editData? { ...editData,} : {} |
||||
|
const [form] = Form.useForm() |
||||
|
const formRef = useRef() |
||||
|
|
||||
|
|
||||
|
return ( |
||||
|
<ModalForm |
||||
|
formRef={formRef} |
||||
|
title={title || ''} |
||||
|
initialValues={initialValues} |
||||
|
trigger={triggerRender ? triggerRender : <Button type='primary'>{title || ''}</Button>} |
||||
|
layout='horizontal' |
||||
|
grid={true} |
||||
|
{...formItemLayout} |
||||
|
modalProps={{ |
||||
|
destroyOnClose: true, |
||||
|
onCancel: () => {}, |
||||
|
}} |
||||
|
onFinish={async values => { |
||||
|
// console.log('values1',editData)
|
||||
|
let value={ |
||||
|
anxinyunProject:values?.anxinyunProject, |
||||
|
structName:values?.structName, |
||||
|
id:initialValues?initialValues.key:null |
||||
|
} |
||||
|
return onFinish && (await onFinish(value)) |
||||
|
// return true;
|
||||
|
}} |
||||
|
width={500}> |
||||
|
<ProFormSelect |
||||
|
rules={[{ required: true, message: '安心云结构物' }]} |
||||
|
showSearch |
||||
|
options={proejctListOpt?.map(s => { |
||||
|
return { label: s.label, value: s.value } |
||||
|
})} |
||||
|
name='anxinyunProject' |
||||
|
label='安心云结构物' |
||||
|
/> |
||||
|
<ProFormSelect |
||||
|
rules={[{ required: true, message: '关联结构物' }]} |
||||
|
showSearch |
||||
|
options={structureListOpt?.map(s => { |
||||
|
return { label: s.label, value: s.value } |
||||
|
})} |
||||
|
name='structName' |
||||
|
label='关联结构物' |
||||
|
/> |
||||
|
</ModalForm> |
||||
|
) |
||||
|
} |
||||
|
function mapStateToProps(state) { |
||||
|
const {auth, global, device } = state; |
||||
|
return { |
||||
|
loading: device.isRequesting, |
||||
|
clientHeight: global.clientHeight, |
||||
|
actions: global.actions, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
export const DEVICE_TYPES = [ |
||||
|
'安防系统', |
||||
|
'厨房系统', |
||||
|
'电梯', |
||||
|
'供电系统', |
||||
|
'空调', |
||||
|
'排水系统', |
||||
|
'水系统', |
||||
|
'通道门禁', |
||||
|
'通风系统', |
||||
|
'通信系统', |
||||
|
'显示视频', |
||||
|
'消防系统', |
||||
|
'照明系统', |
||||
|
] |
||||
|
export default connect(mapStateToProps)(RelationModal) |
@ -0,0 +1,5 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import ProjectBinding from './projectBinding' |
||||
|
|
||||
|
export { ProjectBinding }; |
@ -0,0 +1,304 @@ |
|||||
|
import React, { useEffect, useState, useRef, useMemo } from 'react' |
||||
|
import { Spin, Popconfirm, message, Button, Input, Select } from 'antd' |
||||
|
import { connect } from 'react-redux' |
||||
|
import ProTable from '@ant-design/pro-table' |
||||
|
import moment from 'moment' |
||||
|
import RelationModal from '../components/relationModal' |
||||
|
function ProjectBinding(props) { |
||||
|
const {loading, clientHeight, actions, dispatch, devices,anxinyunProjectLoading,relationLoading } = props |
||||
|
const { projectBinding, projectRegime } = actions |
||||
|
const tableRef = useRef() |
||||
|
const proTableFormRef = useRef() |
||||
|
const [proejctListOpt, setProjectListOpt] = useState([])//安心云结构物
|
||||
|
const [structureListOpt, setStructureListOpt] = useState([])//巡检结构物
|
||||
|
const [dataSource, setDataSource] = useState([]) |
||||
|
// const [dataCopy,setDataCopy]=useState([])
|
||||
|
const [tableParams, setTableParams] = useState({}) |
||||
|
// const fetchData = async () => {
|
||||
|
// let data={
|
||||
|
// url:"users/{orgId}/projects",
|
||||
|
// type:"get"
|
||||
|
// }
|
||||
|
// dispatch(projectBinding.getanxinyunProject(data)).then(async res=>{
|
||||
|
// if(res.success){
|
||||
|
// const d=res.payload.data?.map(item=>{
|
||||
|
// return {
|
||||
|
// label:item?.projects[0]?.name,
|
||||
|
// value:item?.projects[0]?.id
|
||||
|
// }
|
||||
|
// })
|
||||
|
// setProjectListOpt(d)
|
||||
|
// const r2= await dispatch(projectRegime.getProjectList())
|
||||
|
// const dp=r2.pauseStatemap(item=>{
|
||||
|
// return {
|
||||
|
// label:item?.name,
|
||||
|
// value:item?.id
|
||||
|
// }
|
||||
|
// })
|
||||
|
// setStructureListOpt(dp)
|
||||
|
// const r= await dispatch(projectBinding.getRelation())
|
||||
|
// const list = r?.payload?.data?.rows?.map(item=>{
|
||||
|
// return {
|
||||
|
// key: item.id,
|
||||
|
// anxinyunProject:d?.find(q=>q.value===item.axyProjectId)?.label,
|
||||
|
// structName:dp?.find(q=>q.value===item.structureId)?.label
|
||||
|
// }
|
||||
|
// })
|
||||
|
// setDataSource(list)
|
||||
|
// }
|
||||
|
// })
|
||||
|
|
||||
|
// }
|
||||
|
//初始化
|
||||
|
useEffect(() => { |
||||
|
let data = { |
||||
|
url:'organizations/{orgId}/structures', |
||||
|
// url: 'users/{orgId}/projects',
|
||||
|
type: 'get', |
||||
|
} |
||||
|
dispatch(projectBinding.getanxinyunProject(data)).then(res => { |
||||
|
if (res.success) { |
||||
|
const d = res.payload.data?.map(item => { |
||||
|
return { |
||||
|
label: item?.name, |
||||
|
value: item?.iotaThingId, |
||||
|
} |
||||
|
}) |
||||
|
setProjectListOpt(d) |
||||
|
} |
||||
|
}) |
||||
|
dispatch(projectRegime.getProjectList()).then(res => { |
||||
|
if (res.success) { |
||||
|
const dp = res.payload.data?.rows?.map(item => { |
||||
|
return { |
||||
|
label: item?.name, |
||||
|
value: item?.id, |
||||
|
} |
||||
|
}) |
||||
|
setStructureListOpt(dp) |
||||
|
} |
||||
|
}) |
||||
|
}, []) |
||||
|
const queryData = () => { |
||||
|
dispatch(projectBinding.getRelation()).then(res => { |
||||
|
if (res.success) { |
||||
|
const list = res?.payload?.data?.rows?.map(item => { |
||||
|
return { |
||||
|
key: item.id, |
||||
|
anxinyunProject: proejctListOpt?.find(q => q.value === item.axyProjectId)?.value, |
||||
|
structName: structureListOpt?.find(q => q.value === item.structureId)?.value, |
||||
|
} |
||||
|
}) |
||||
|
setDataSource(list) |
||||
|
// setDataCopy(list)
|
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
useEffect(() => { |
||||
|
if (proejctListOpt && structureListOpt && proejctListOpt.length && structureListOpt.length) { |
||||
|
queryData() |
||||
|
} |
||||
|
}, [proejctListOpt, structureListOpt]) |
||||
|
|
||||
|
const onFinish = async values => { |
||||
|
const dataToSave = { axyProjectId: values?.anxinyunProject, structrueId: values?.structName, id: values?.id } |
||||
|
return dispatch(projectBinding.addorEditRelation(dataToSave)).then(res => { |
||||
|
if (res.success) { |
||||
|
queryData() |
||||
|
// tableRef.current.reload()
|
||||
|
return true |
||||
|
} else { |
||||
|
return false |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
//删除按钮
|
||||
|
const handleDelete = id => { |
||||
|
dispatch(projectBinding.delRelation(id)).then(res => { |
||||
|
if (res.success) { |
||||
|
queryData() |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const filterOption = (input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase()) |
||||
|
|
||||
|
const columns = [ |
||||
|
{ |
||||
|
title: '安心云结构物', |
||||
|
dataIndex: 'anxinyunProject', |
||||
|
ellipsis: true, |
||||
|
valueType: 'select', |
||||
|
fieldProps: { |
||||
|
options: proejctListOpt, |
||||
|
}, |
||||
|
renderFormItem: () => ( |
||||
|
<Select |
||||
|
showSearch |
||||
|
// style={{paddingLeft:10}}
|
||||
|
allowClear |
||||
|
placeholder='请选择' |
||||
|
options={proejctListOpt?.map(item => ({ label: item.label, value: item.value }))} |
||||
|
filterOption={filterOption} |
||||
|
optionFilterProp='children'></Select> |
||||
|
), |
||||
|
// fieldProps: {
|
||||
|
// showSearch: true,
|
||||
|
// defaultValue: '',
|
||||
|
// },
|
||||
|
// onFilter: (value, record) => record.name.includes(value),
|
||||
|
// search:false
|
||||
|
}, |
||||
|
{ |
||||
|
title: '结构物名称', |
||||
|
dataIndex: 'structName', |
||||
|
ellipsis: true, |
||||
|
valueType: 'select', |
||||
|
fieldProps: { |
||||
|
options: structureListOpt, |
||||
|
}, |
||||
|
renderFormItem: () => ( |
||||
|
<Select |
||||
|
showSearch |
||||
|
// style={{paddingLeft:10}}
|
||||
|
allowClear |
||||
|
placeholder='请选择' |
||||
|
options={structureListOpt?.map(item => ({ label: item.label, value: item.value }))} |
||||
|
filterOption={filterOption} |
||||
|
optionFilterProp='children'></Select> |
||||
|
), |
||||
|
// fieldProps: {
|
||||
|
// showSearch: true,
|
||||
|
// defaultValue: '',
|
||||
|
// },
|
||||
|
// search:false
|
||||
|
valueType: 'select', |
||||
|
fieldProps: { |
||||
|
options: structureListOpt, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '操作', |
||||
|
width: 160, |
||||
|
key: 'option', |
||||
|
valueType: 'option', |
||||
|
render: (text, record) => { |
||||
|
const options = [] |
||||
|
options.push( |
||||
|
<RelationModal |
||||
|
proejctListOpt={proejctListOpt} |
||||
|
triggerRender={<a>修改映射关系</a>} |
||||
|
editData={record} |
||||
|
structureListOpt={structureListOpt} |
||||
|
title='修改映射关系' |
||||
|
onFinish={onFinish} |
||||
|
key='editModel' |
||||
|
/> |
||||
|
) |
||||
|
|
||||
|
options.push( |
||||
|
<Popconfirm |
||||
|
key='del' |
||||
|
placement='top' |
||||
|
title='是否确认删除映射关系?' |
||||
|
onConfirm={() => handleDelete(record.key)} |
||||
|
okText='是' |
||||
|
cancelText='否'> |
||||
|
<a>删除</a> |
||||
|
</Popconfirm> |
||||
|
) |
||||
|
|
||||
|
return options |
||||
|
}, |
||||
|
}, |
||||
|
] |
||||
|
// useMemo(()=>{
|
||||
|
|
||||
|
// })
|
||||
|
|
||||
|
const tableDatas = useMemo(() => { |
||||
|
const { anxinyunProject, structName } = tableParams |
||||
|
let rslt = dataSource |
||||
|
rslt = rslt |
||||
|
.filter(s => (anxinyunProject ? (s.anxinyunProject ? s.anxinyunProject === anxinyunProject : false) : true)) |
||||
|
?.filter(s => (structName ? (s.structName ? s.structName === structName : false) : true)) |
||||
|
return rslt |
||||
|
}) |
||||
|
|
||||
|
// const searchHandler=()=>{
|
||||
|
// const anxinyunProject=proTableFormRef.current.getFieldsValue()?.anxinyunProject
|
||||
|
// const structName=proTableFormRef.current.getFieldsValue()?.structName
|
||||
|
// setDataSource(
|
||||
|
// dataCopy.filter(f =>
|
||||
|
// (!anxinyunProject || f.anxinyunProject?.includes(anxinyunProject)) &&
|
||||
|
// (!structName || f?.structName === structName)
|
||||
|
// )
|
||||
|
// )
|
||||
|
|
||||
|
// }
|
||||
|
|
||||
|
return ( |
||||
|
<Spin spinning={anxinyunProjectLoading||relationLoading}> |
||||
|
<div id='patrol-record' className='global-main'> |
||||
|
{/* <Spin spinning={loading}> */} |
||||
|
<div style={{ marginBottom: 19 }}> |
||||
|
<div className='top' style={{ marginBottom: 19 }}> |
||||
|
<div className='title'> |
||||
|
<span className='line'></span> |
||||
|
<span className='cn'>项目绑定</span> |
||||
|
<span className='en'> PROJECT</span> |
||||
|
</div> |
||||
|
<div></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<RelationModal |
||||
|
structureListOpt={structureListOpt} |
||||
|
proejctListOpt={proejctListOpt} |
||||
|
triggerRender={<Button type='primary'>新增</Button>} |
||||
|
title='新增映射关系' |
||||
|
onFinish={onFinish} |
||||
|
key='addModel' |
||||
|
/> |
||||
|
<ProTable |
||||
|
formRef={proTableFormRef} |
||||
|
rowKey='id' |
||||
|
options={false} |
||||
|
request={async params => { |
||||
|
setTableParams(params) |
||||
|
return { |
||||
|
data: [], |
||||
|
success: true, |
||||
|
} |
||||
|
}} |
||||
|
actionRef={tableRef} |
||||
|
columns={columns} |
||||
|
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
||||
|
dataSource={tableDatas || []} |
||||
|
search={{ |
||||
|
labelWidth: 100, |
||||
|
|
||||
|
}} |
||||
|
// search={{
|
||||
|
// optionRender: ({searchText, resetText}, {form}, dom) => [
|
||||
|
// <Button type="primary" onClick={searchHandler}>查询</Button>,
|
||||
|
// ]
|
||||
|
// }}
|
||||
|
></ProTable> |
||||
|
{/* </Spin> */} |
||||
|
</div> |
||||
|
</Spin> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { auth, global, device,anxinyunProject, relation} = state |
||||
|
return { |
||||
|
loading: device.isRequesting, |
||||
|
clientHeight: global.clientHeight, |
||||
|
actions: global.actions, |
||||
|
relationLoading:relation.isRequesting, |
||||
|
anxinyunProjectLoading:anxinyunProject.isRequesting, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(ProjectBinding) |
@ -0,0 +1,15 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
import reducers from './reducers'; |
||||
|
import routes from './routes'; |
||||
|
import actions from './actions'; |
||||
|
import { getNavItem } from './nav-item'; |
||||
|
|
||||
|
export default { |
||||
|
key: 'projectBinding', |
||||
|
name: '项目绑定', |
||||
|
reducers: reducers, |
||||
|
routes: routes, |
||||
|
actions: actions, |
||||
|
getNavItem: getNavItem |
||||
|
}; |
@ -0,0 +1,13 @@ |
|||||
|
import React from 'react'; |
||||
|
import { Link } from 'react-router-dom'; |
||||
|
import { Menu } from 'antd'; |
||||
|
import { Func } from '$utils'; |
||||
|
export function getNavItem(user, dispatch) { |
||||
|
return ( |
||||
|
<Menu.Item icon={<img src='/assets/images/menu/device.png' style={{ width: 24, height: 24 }} />} |
||||
|
key="projectBinding"> |
||||
|
<Link to="/projectBinding">项目绑定</Link> |
||||
|
</Menu.Item> |
||||
|
|
||||
|
); |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
export default { |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
'use strict'; |
||||
|
import { ProjectBinding } from './containers'; |
||||
|
|
||||
|
export default [{ |
||||
|
type: 'inner', |
||||
|
route: { |
||||
|
path: '/projectBinding', |
||||
|
key: 'projectBinding', |
||||
|
breadcrumb: '项目绑定', |
||||
|
component: ProjectBinding, |
||||
|
|
||||
|
} |
||||
|
}]; |
Loading…
Reference in new issue