保险、基金、银行等众多行业在做技术平台时都会需要一种能够准确了解用户操作行为的方式方法。诸如通过埋点、平台监控、视频可回溯等,通过技术手段,保存用户操作轨迹
,以此规范安全销售、平台健康检查、出现纠纷时可追溯、问题出现有证据。 为规范保险行业销售行为,zf出台相关政策:
在本人开发系统之前,全网似乎也有几家公司已经在推广销售双录系统,但是介于价格较高,且本人有兴趣挑战这种比较大型的平台系统。对未知领域充满无限好奇心的驱动力
使我一步一步将一套完整的视频可回溯项目比较完整的实现了。在此先给自己鼓个掌!👍👍😁
sdk应具备的能力:
sdk服务于sdk探针:
- 权限管理:菜单管理、角色管理、用户管理
- 可回溯管理:商户配置、录屏配置、视频列表、视频播放、sdk版本管理
项目采用tegg微服务方式,权限模块,公共模块,录屏模块,html模版view模块
最最核心是如何存储视频文件数据,思想和方法论是最关键的,前端只要用户操作每隔1s调一次接口,然后后端保存缓存文件。 本项目采取三段式分片定时任务处理数据存储,合并和压缩上传功能。
在不频繁处理数据库操作的基础思想下,定时任务分批处理。
这个地方,想了比较久,甚至过年开车回家,在路上就一直在想方案,也没想出来,年后回来,在某一刻想通了哈哈哈。就是这么神奇
贴一段核心代码
/**
** @Author: wangke
** @Date: 2024/02/08 20:03:59
** @Description: 查询videoProgress=2时 将 screenRecordVideos 视频txt文件压缩归档,场景就是,用户在订单完成后,迟迟没有支付,或者,很长时间才到达结束页,这时,结束页要再次归档
*/
async scheduleVideoFileZip(searchParams, type: number) {
const videoPath = this.config.recordEventDir + Constant.SCREEN_RECORD_VIDEO_DIR
const fileArr = zipFileFunc(videoPath)
setTimeout(async () => {
const deviceIdArr = []
if (!fileArr.length) return false
for (let i = 0; i < fileArr.length; i++) {
deviceIdArr.push(fileArr[i].split('.')[0] as never)
}
// 查找数据,然后将zip文件归档云存储
searchParams = { deviceId: deviceIdArr, ...searchParams } // 当数据库里有设备id时才存到oss上,避免脏数据归档
const videoList = await this.VideoListRepository.queryAll(searchParams)
if (videoList.length <= 0) return
for (let i = 0; i < videoList.length; i++) {
const txtFileName = videoList[i].deviceId + this.config.video_file_suffix
const zipFileName = videoList[i].deviceId + this.config.video_zip_file_suffix
const txtFileInfo = this.config.recordEventDir + Constant.SCREEN_RECORD_VIDEO_DIR + txtFileName
const fileInfo = this.config.recordEventDir + Constant.SCREEN_RECORD_VIDEO_DIR + zipFileName
if (await isExistFileFunc(txtFileInfo)) {
await Oss.ossPut('zip/' + dateFileDirFunc() + zipFileName, fileInfo)
const videoSize = getFileSize(fileInfo)
let videoParams = {
videoSize,
videoStatus: Constant.VIDEO_HAVE_MAKE,
videoUrl: 'zip/' + dateFileDirFunc() + zipFileName,
// videoUrl: ossRes.url
videoProgress: ''
}
if (type === 2) {
videoParams = { ...videoParams, videoProgress: '3' }
}
const updateRes = await this.VideoListRepository.update(videoList[i].deviceId, videoParams)
if (updateRes) {
fsync.unlinkSync(fileInfo)
type === 2 && fsync.unlinkSync(txtFileInfo)
}
}
}
}, 1000)
}
欢迎评论点赞支持,本人将不胜惶恐。本文由蜗牛老师开发Butterfly发布