You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

377 lines
18 KiB

const moment = require('moment')
module.exports = function (app, opts) {
const cameraOnlinePush = app.fs.scheduleInit(
{
interval: '0 */15 * * * *',
// interval: '* */1 * * * *',
// interval: '*/5 * * * * *',
immediate: false,
proRun: true,
},
async () => {
try {
const { models, ORM: sequelize } = app.fs.dc
const { pushBySms, pushByEmail } = app.fs.utils
const configRes = await models.CameraStatusPushConfig.findAll({
where: {
forbidden: false
},
include: [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
],
})
const timeNow = moment().startOf('minute').format()
for (let c of configRes) {
console.log('上下线推送方式', c.pushWay,);
// 查配置信息所对应的摄像头15min内的在离线状态
const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
const offlineStatusRes = await models.CameraStatusOfflineLog.findAll({
where: {
cameraId: { $in: cameraIds },
// !!! 時間限制
time: {
$between: [moment(timeNow).subtract(15, 'minutes').format(), timeNow]
}
},
include: [{
model: models.Camera,
attributes: ['name']
}],
order: [['time', 'ASC']],
})
console.log('上下线推送路线记录', offlineStatusRes);
if (offlineStatusRes.length) {
const cameraStatusMap = {}
// 当前逻辑
// 只要最后状态是离线 就做离线推送
// 只要出现一次上线 就做上线推送
for (let s of offlineStatusRes) {
if (cameraStatusMap[s.cameraId]) {
cameraStatusMap[s.cameraId].status.push({
status: s.status,
time: s.time,
})
} else {
cameraStatusMap[s.cameraId] = {
status: [{
status: s.status,
time: s.time,
}],
cameraId: s.cameraId,
name: s.camera.name,
}
}
}
let offArr = []
let onArr = []
for (let k of Object.keys(cameraStatusMap).sort()) {
const data = cameraStatusMap[k]
if (data.status[0].status == 'OFF') {
offArr.push({
cameraId: data.cameraId,
name: data.name,
time: data.status[0].time,
})
}
const onLineIndex = data.status.findIndex(s => s.status == 'ON')
if (onLineIndex >= 0) {
const onLineLastOffIndex = data.status.findIndex((s, i) => s.status == 'OFF' && i > onLineIndex)
// 当前在线记录的上一次离线记录
let onlineData = {
cameraId: data.cameraId,
name: data.name,
time: data.status[onLineIndex].time,
}
if (onLineLastOffIndex >= 0) {
onlineData.offTime = data.status[onLineLastOffIndex].time
}
onArr.push(onlineData)
}
}
// 查当前配置由谁配置
const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
query: {
// TODO 这里拿不到 token 去鉴权 怎么能系统间鉴权呢
// 暂时取消了鉴权系统对这里的判断
token: ''
}
})
const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
const logData = {
pushConfigId: c.id,
receiver: receiver,
timing: c.timing,
time: moment(timeNow).format(),
pushWay: c.pushWay,
// camera: cameraIds,
}
// 离线推送
console.log('上下线推送数据', offArr, onArr);
console.log('上下线推送接收', receiver);
if (offArr.length && c.noticeWay && c.noticeWay.includes('offline') && receiver.length) {
if (c.pushWay == 'email') {
// 邮件
let text = `${corUser[0].username}】账号下的设备,截止【${moment(timeNow).format('MM月DD日 HH时mm分')}】,新增${offArr.length}个设备掉线:\n`
text += offArr.map(o => `${o.name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`).join('\n')
text += `\n请及时处理!`
await pushByEmail({
email: receiver,
title: '尚视设备离线通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
} else if (c.pushWay == 'phone') {
// 短信
let templateParam = {
name: `${corUser[0].username}`,
}
let useTempCode = 'SMS_248205074'
// let text = `【${corUser[0].username}】账号下的`
if (offArr.length == 1) {
// text += `【${offArr[0].name}】离线,请及时处理!【${moment(offArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${offArr[0].name}`
templateParam.timeRange = moment(offArr[0].time).format('MM月DD日 HH时mm分')
} else {
let text = ''
text += offArr.map(o => `${o.name}`).join('')
if (text.length > 35) {
text = text.substring(0, 35) + '...'
// text += `等${offArr.length}个摄像头离线`
templateParam.deviceCount = offArr.length
useTempCode = 'SMS_248250074'
}
templateParam.deviceName = text
// text += `,请及时处理!【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】`
templateParam.timeRange = `${moment().format('MM月DD日HH时mm分')} -${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}`
}
await pushBySms({
phone: receiver,
templateCode: useTempCode,
templateParam: templateParam,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
}
}
// 上线推送
if (onArr.length && c.noticeWay && c.noticeWay.includes('online') && receiver.length) {
if (c.pushWay == 'email') {
// 邮件
const outTimeCameraOff = onArr.filter(a => !a.offTime)
if (outTimeCameraOff.length) {
let cameraIds = outTimeCameraOff.map(a => a.cameraId)
const lastOfflineRes = await models.CameraStatusOfflineLog.findAll({
where: {
cameraId: { $in: cameraIds },
status: 'OFF',
time: {
$lt: moment(timeNow).subtract(15, 'minutes').format()
}
},
group: ['cameraId'],
attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
})
for (let a of onArr) {
if (!a.offTime) {
const lastOffline = lastOfflineRes.find(l => l.cameraId == a.cameraId)
if (lastOffline) {
a.offTime = lastOffline.time
}
}
}
}
let text = `${corUser[0].username}】账号下的设备:\n`
text += onArr.map(o => `${o.name}】于【${moment(o.offTime).format('MM月DD日HH时mm分')}】掉线,【${moment(o.time).format('MM月DD日HH时mm分')}】已恢复`).join('\n')
await pushByEmail({
email: receiver,
title: '尚视设备上线通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
} else if (c.pushWay == 'phone') {
// 短信
// let text = `【${corUser[0].username}】账号下的`
let templateParam = {
name: `${corUser[0].username}`,
}
let useTempCode = 'SMS_248250073'
if (onArr.length == 1) {
// text += `【${onArr[0].name}】已恢复上线,请及时处理!【${moment(onArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${onArr[0].name}`
templateParam.date = moment(onArr[0].time).format('MM月DD日 HH时mm分')
} else {
let text = ''
text += onArr.map(o => `${o.name}`).join('')
let timeRange = `${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】!`
if (text.length > 35) {
text = text.substring(0, 35) + '...'
// text += `等${onArr.length}个摄像头已恢复上线!`
templateParam.deviceCount = onArr.length
useTempCode = 'SMS_248120080'
templateParam.timeRange = timeRange
} else {
templateParam.date = timeRange
}
templateParam.deviceName = text
}
await pushBySms({
phone: receiver,
templateCode: useTempCode,
templateParam: templateParam,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
}
}
}
}
} catch (error) {
console.error('15min 上下线推送错误:', error);
}
}
)
// 摄像头离线定时统计推送
const cameraOnlineTimingPush = app.fs.scheduleInit(
{
interval: '0 */5 * * * *',
// interval: '*/10 * * * * *', // dev
immediate: false,
// immediate: true, // dev
proRun: true,
},
async () => {
try {
const { models, ORM: sequelize } = app.fs.dc
const { pushBySms, pushByEmail } = app.fs.utils
const timeNow = moment().format()
const configRes = await models.CameraStatusPushConfig.findAll({
where: {
forbidden: false,
noticeWay: {
$contains: ['timing']
},
// !!! 此时此刻
timing: moment(timeNow).format('HH:mm')
},
include: [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
],
})
for (let c of configRes) {
// 查配置信息所对应的摄像头在离线状态
const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
const offlineRes = await models.Camera.findAll({
where: {
id: { $in: cameraIds },
},
attributes: ['id', 'name'],
include: [{
model: models.GbCamera,
attributes: ['id', 'online'],
required: true,
where: {
online: 'OFF'
}
}],
})
if (offlineRes.length) {
// 查当前配置由谁配置
const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
query: {
token: ''
}
})
const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
if (receiver.length) {
const logData = {
pushConfigId: c.id,
receiver: receiver,
timing: c.timing,
time: moment(timeNow).format(),
pushWay: c.pushWay,
camera: offlineRes.map(o => o.id),
}
if (c.pushWay == 'email') {
// 邮件
const offlineTimeRes = await models.CameraStatusOfflineLog.findAll({
attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
where: {
cameraId: { $in: offlineRes.map(oc => oc.id) },
status: 'OFF',
},
group: ['cameraId'],
})
if (offlineTimeRes.length) {
let text = `${corUser[0].username}】账号下的设备,截止${moment(timeNow).format('MM月DD日 HH时mm分')},新增${offlineRes.length}个设备掉线:\n`
text += offlineTimeRes.map(o => {
let corCamera = offlineRes.find(c => c.id == o.cameraId)
if (corCamera) {
return `${(corCamera || {}).name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`
}
return ''
}).join('\n')
text += `\n请及时处理!`
await pushByEmail({
email: receiver,
title: '尚视设备离线定时统计通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['timing'] })
}
} else if (c.pushWay == 'phone') {
// 短信
// let text = `【${corUser[0].username}】账号下截止${moment(timeNow).format('YYYY年MM月DD日 HH时')},有${offlineRes.length}个设备掉线,请及时处理!`
await pushBySms({
phone: receiver,
templateCode: 'SMS_248095009',
templateParam: {
name: corUser[0].username,
time: moment(timeNow).format('YYYY年MM月DD日 HH时'),
deviceCount: offlineRes.length,
},
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['timing'] })
}
}
}
}
} catch (error) {
console.error(error);
}
}
)
return {
cameraOnlinePush,
cameraOnlineTimingPush,
}
}