Browse Source

数据推送

release_1.1.2
巴林闲侠 3 years ago
parent
commit
3f08d7e86f
  1. 11
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_log.js
  2. 253
      code/VideoAccess-VCMP/api/app/lib/schedule/cameraStatePush.js
  3. 4
      code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiMsg.js
  4. 3
      code/VideoAccess-VCMP/api/app/lib/schedule/index.js
  5. 8
      code/VideoAccess-VCMP/api/app/lib/utils/push.js
  6. 25
      code/VideoAccess-VCMP/api/config.js
  7. 3
      code/VideoAccess-VCMP/script/1.1.2/schema/2.update_push_log.sql

11
code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_log.js

@ -68,7 +68,16 @@ module.exports = dc => {
primaryKey: false,
field: "timing",
autoIncrement: false
}
},
noticeWay: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: false,
defaultValue: null,
comment: "通知方式 offline / online / timing",
primaryKey: false,
field: "notice_way",
autoIncrement: false
},
}, {
tableName: "camera_status_push_log",
comment: "",

253
code/VideoAccess-VCMP/api/app/lib/schedule/cameraStatePush.js

@ -6,11 +6,11 @@ module.exports = function (app, opts) {
interval: '* */15 * * * *',
// interval: '*/15 * * * * *',
immediate: false,
proRun: false,
proRun: true,
},
async () => {
try {
const { models } = app.fs.dc
const { models, ORM: sequelize } = app.fs.dc
const { pushBySms, pushByEmail } = app.fs.utils
const configRes = await models.CameraStatusPushConfig.findAll({
where: {
@ -50,8 +50,6 @@ module.exports = function (app, opts) {
order: [['time', 'ASC']],
})
if (offlineStatusRes.length) {
const cameraStatusMap = {}
// 当前逻辑
@ -60,27 +58,27 @@ module.exports = function (app, opts) {
for (let s of offlineStatusRes) {
if (cameraStatusMap[s.cameraId]) {
cameraStatusMap.status.push({
cameraId: s.cameraId,
status: s.status,
time: s.time,
})
} else {
cameraStatusMap[s.cameraId] = {
status: [{
cameraId: s.cameraId,
status: s.status,
time: s.time,
}],
cameraId: s.cameraId,
name: s.camera.name,
}
}
}
let offArr = []
let onArr = []
for (let k in Object.keys(cameraStatusMap).sort()) {
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,
})
@ -88,9 +86,10 @@ module.exports = function (app, opts) {
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.status[onLineIndex].cameraId,
name: data.status[onLineIndex].name,
cameraId: data.cameraId,
name: data.name,
time: data.status[onLineIndex].time,
}
if (onLineLastOffIndex >= 0) {
@ -110,37 +109,57 @@ module.exports = function (app, opts) {
})
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,
}
// 离线推送
if (offArr.length && c.noticeWay && c.noticeWay.includes('offline')) {
if (c.pushWay == 'email') {
// 邮件
let text = `${corUser[0].namePresent}】账号下的设备,截止【${moment(timeNow).format('YYYY年HH时mm分')}】,有${offArr.length}个设备掉线:\n`
let text = `${corUser[0].namePresent}】账号下的设备,截止【${moment(timeNow).format('MM月DD日 HH时mm分')}】,有${offArr.length}个设备掉线:\n`
text += offArr.map(o => `${o.name}】于【${o.time}】掉线,`).join('\n')
text += `\n请及时处理!`
await pushByEmail({
email: receiver,
title: '',
title: '尚视设备离线通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
} else if (c.pushWay == 'phone') {
// 短信
let text = `${corUser[0].namePresent}】账号下的`
let templateParam = {
name: corUser[0].namePresent,
}
let useTempCode = 'SMS_247900122'
// let text = `【${corUser[0].namePresent}】账号下的`
if (offArr.length == 1) {
text += `${offArr[0].name}】离线,请及时处理!【${moment(offArr[0].time).format('YYYY年HH时mm分')}`
// text += `【${offArr[0].name}】离线,请及时处理!【${moment(offArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${offArr[0].name}`
templateParam.time = 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}个摄像头离线`
// text += `等${offArr.length}个摄像头离线`
templateParam.deviceCount = offArr.length
useTempCode = 'SMS_247985123'
}
text += `,请及时处理!【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}`
templateParam.deviceName = text
// text += `,请及时处理!【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】`
templateParam.time = `${moment().format('MM月DD日HH时mm分')} -${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}`
}
await pushBySms({
phone: receiver,
templateCode: '',
templateParam: '',
text
templateCode: useTempCode,
templateParam: templateParam,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
}
}
@ -148,38 +167,202 @@ module.exports = function (app, opts) {
if (onArr.length && c.noticeWay && c.noticeWay.includes('online')) {
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.CameraStatus.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']],
// })
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].namePresent}】账号下的设备:\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].namePresent}】账号下的`
let templateParam = {
name: corUser[0].namePresent,
}
let useTempCode = 'SMS_247820204'
if (onArr.length == 1) {
// text += `【${onArr[0].name}】已恢复上线,请及时处理!【${moment(onArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${onArr[0].name}`
templateParam.time = moment(onArr[0].time).format('MM月DD日 HH时mm分')
} else {
let text = ''
text += onArr.map(o => `${o.name}`).join('')
if (text.length > 35) {
text = text.substring(0, 35) + '...'
// text += `等${onArr.length}个摄像头已恢复上线!`
templateParam.deviceCount = onArr.length
useTempCode = 'SMS_247825189'
}
templateParam.deviceName = text
// text += `【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】!`
templateParam.time = `${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: ['online'], camera: onArr.map(o => o.cameraId) })
}
}
}
}
} catch (error) {
console.error(error);
}
}
)
// }
// 摄像头离线定时统计推送
const cameraOnlineTimingPush = app.fs.scheduleInit(
{
interval: '* */5 * * * *',
// interval: '*/10 * * * * *', // dev
immediate: false,
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) {
// 查配置信息所对应的摄像头15min内的在离线状态
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].namePresent}】账号下的设备,截止${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].namePresent}】账号下截止${moment(timeNow).format('YYYY年MM月DD日 HH时')},有${offlineRes.length}个设备掉线,请及时处理!`
await pushBySms({
phone: receiver,
templateCode: 'SMS_247785195',
templateParam: JSON.stringify({
name: corUser[0].namePresent,
time: moment(timeNow).format('YYYY年MM月DD日 HH时'),
deviceCount: offlineRes.length,
}),
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['timing'] })
}
}
}
}
console.log('cameraOnlinePush')
} catch (error) {
console.error(error);
}
}
)
return {
cameraOnlinePush,
cameraOnlineTimingPush,
}
}

4
code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiMsg.js

@ -4,8 +4,8 @@ const moment = require('moment')
module.exports = function (app, opts) {
const freshYingshiState = app.fs.scheduleInit(
{
interval: '* */5 * * * *',
// interval: '*/10 * * * *',
// interval: '* */5 * * * *',
interval: '*/10 * * * *',
immediate: false,
proRun: true,
},

3
code/VideoAccess-VCMP/api/app/lib/schedule/index.js

@ -9,6 +9,9 @@ module.exports = async function (app, opts) {
const scheduleInit = ({
interval, immediate, proRun,
}, callback) => {
if (proRun && opts.dev) {
return;
}
const j = nodeSchedule.scheduleJob(interval, callback);
if (immediate && (!proRun || (proRun && !opts.dev))) {
setTimeout(callback, 0)

8
code/VideoAccess-VCMP/api/app/lib/utils/push.js

@ -16,9 +16,9 @@ module.exports = function (app, opts) {
});
const SendSmsRes = await client.request('SendSms', {
"PhoneNumbers": `${phone.join(',')}`,//接收短信的手机号码。
"SignName": "安心云",//短信签名名称。必须是已添加、并通过审核的短信签名。
"TemplateCode": "SMS_216403225",//短信模板ID。必须是已添加、并通过审核的短信签名;且发送国际/港澳台消息时,请使用国际/港澳台短信模版。
"TemplateParam": `{"code":${code}}`//短信模板变量对应的实际值,JSON格式。
"SignName": "尚视",//短信签名名称。必须是已添加、并通过审核的短信签名。
"TemplateCode": templateCode,//短信模板ID。必须是已添加、并通过审核的短信签名;且发送国际/港澳台消息时,请使用国际/港澳台短信模版。
"TemplateParam": JSON.stringify(templateParam)//短信模板变量对应的实际值,JSON格式。
}, {
method: 'POST'
});
@ -43,7 +43,7 @@ module.exports = function (app, opts) {
// send mail with defined transport object
await transporter.sendMail({
from: 'grazing-stars@qq.com', // sender address
from: `${opts.email.sender.name}<${opts.email.sender.address}>`, // sender address
to: email.join(','), // list of receivers 逗号分隔字符串
subject: title, // Subject line
text: text, // plain text body

25
code/VideoAccess-VCMP/api/config.js

@ -115,23 +115,14 @@ const product = {
accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S'
},
email: {
// enabled: true,
// host: 'smtp.exmail.qq.com',
// port: 465,
// sender: {
// name: '知物云',
// address: 'no-reply@zhiwucloud.com',
// password: 'Zwy123456_'
// },
// enabled: true,
// host: 'smtp.exmail.qq.com',
// port: 465,
// sender: {
// name: '知物云',
// address: 'no-reply@zhiwucloud.com',
// password: 'Zwy123456_'
// }
enabled: true,
host: 'smtp.exmail.qq.com',
port: 465,
sender: {
name: '尚视',
address: 'no-reply@zhiwucloud.com',
password: 'Zwy123456_'
}
},
pssaRequest: [
{// name 会作为一个 request 出现在 ctx.app.fs

3
code/VideoAccess-VCMP/script/1.1.2/schema/2.update_push_log.sql

@ -0,0 +1,3 @@
alter table camera_status_push_log
add notice_way varchar[];
Loading…
Cancel
Save