Browse Source

Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial

release_0.0.2
wenlele 3 years ago
parent
commit
29244b7288
  1. 3
      code/VideoAccess-VCMP/api/.vscode/launch.json
  2. 16
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js
  3. 55
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  4. 3
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  5. 8
      code/VideoAccess-VCMP/api/app/lib/index.js
  6. 52
      code/VideoAccess-VCMP/api/app/lib/models/camera_remark.js
  7. 3
      code/VideoAccess-VCMP/api/app/lib/routes/camera/index.js
  8. 4
      code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiMsg.js
  9. 2
      code/VideoAccess-VCMP/api/app/lib/schedule/index.js
  10. 4
      code/VideoAccess-VCMP/api/app/lib/utils/token4yingshi.js
  11. 1
      code/VideoAccess-VCMP/api/config.js
  12. 2
      code/VideoAccess-VCMP/api/sequelize-automate.config.js
  13. 72
      code/VideoAccess-VCMP/script/0.0.1/0_init_db.sql
  14. BIN
      code/VideoAccess-VCMP/web/client/assets/video/remarks.mp4
  15. 1
      code/VideoAccess-VCMP/web/client/index.ejs
  16. 41
      code/VideoAccess-VCMP/web/client/src/components/textScroll.jsx
  17. 11
      code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/actions/camera.js
  18. 137
      code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/remarksModal.jsx
  19. 29
      code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/containers/camera.jsx
  20. 5
      code/VideoAccess-VCMP/web/client/src/utils/webapi.js
  21. 9
      code/VideoAccess-VCMP/web/webpack.config.prod.js

3
code/VideoAccess-VCMP/api/.vscode/launch.json

@ -20,10 +20,11 @@
"--redisPort 6379",
"--axyApiUrl http://127.0.0.1:4100",
"--iotAuthApi http://127.0.0.1:4200",
"--iotVideoServerUrl http://221.230.55.27:8081",
"--godUrl https://restapi.amap.com/v3",
"--godKey 21c2d970e1646bb9a795900dd00093ce",
"--mqttVideoServer mqtt://10.8.30.71:30883",
"--iotVideoServerUrl http://221.230.55.27:8081",
// "--iotVideoServerUrl http://10.8.30.59:8080",
"--cameraPlayWsHost ws://221.230.55.27:8081",
"--cameraPlayHttpFlvHost http://221.230.55.27:2020",
"--cameraPlayHlsHost http://221.230.55.27:8081",

16
code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js

@ -120,7 +120,11 @@ async function getNvrSteam (ctx) {
attributes: ['id', 'name', 'serialNo', 'cloudControl'],
where: {
nvrId: nvrRes.id
}
},
include: [{
model: models.CameraRemark,
attributes: ['remark']
}],
})
const cameraRes = await getGbCameraLevel3ByStreamId({ streamId })
@ -304,8 +308,8 @@ async function createIpcCamera (ctx) {
const gbCameraRes = await verifyIpcInfo({ serialNo })
storageData.sip = gbCameraRes.dataValues.sipip
storageData.gbId = gbCameraRes.dataValues.id
storageData.sip = gbCameraRes.sipip
storageData.gbId = gbCameraRes.id
if (handleCameraId) {
await models.Camera.update(storageData, {
@ -417,7 +421,11 @@ async function getCascadeSteam (ctx) {
attributes: ['id', 'name', 'serialNo'],
where: {
serialNo: { $in: allStreamid }
}
},
include: [{
model: models.CameraRemark,
attributes: ['remark']
}],
})
for (let c of cameraRes) {

55
code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js

@ -31,6 +31,9 @@ async function getCameraProject (ctx, next) {
}, {
model: models.SecretYingshi,
attributes: ['token']
}, {
model: models.CameraRemark,
attributes: ['remark']
}],
distinct: true
}
@ -307,6 +310,13 @@ async function del (ctx) {
transaction
})
await models.CameraRemark.destroy({
where: {
cameraId: cameraId
},
transaction
})
await models.Camera.destroy({
where: {
id: cameraId
@ -490,6 +500,50 @@ async function getKind (ctx) {
}
}
async function remark (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
let errMsg = undefined
try {
const { models } = ctx.fs.dc
const { cameraId, remark, } = ctx.request.body;
const cameraRes = await models.Camera.findOne({
where: {
id: cameraId
}
})
if (!cameraRes) {
errMsg = '摄像头不存在'
}
await models.CameraRemark.destroy({
where: {
cameraId
},
transaction
})
await models.CameraRemark.bulkCreate(remark.map(r => {
return {
cameraId,
remark: r
}
}), {
transaction
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
}
}
}
module.exports = {
getCameraProject,
getCamera,
@ -500,4 +554,5 @@ module.exports = {
cameraExport,
getAbility,
getKind,
remark,
};

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

@ -299,7 +299,8 @@ async function detail (ctx) {
}
const corUser = await ctx.app.fs.authRequest.get(`user/${nvrRes.createUserId}/message`, { query: { token } })
const serverDRes = (await ctx.app.fs.videoServerRequest.post(`gateway/plugins`) || '')
const serverDRes = (await ctx.app.fs.videoServerRequest.post(`gb28181/api/plugins`) || '')
// const serverDRes = (await ctx.app.fs.videoServerRequest.post(`gateway/plugins`) || '')
const serverDArr = JSON.parse(serverDRes.replace(/'/g, '"')) || []
const serverDConfig = serverDArr.find(s => s.Name == 'GB28181')
let serveD = {}

8
code/VideoAccess-VCMP/api/app/lib/index.js

@ -1,5 +1,7 @@
'use strict';
const fs = require('fs');
const path = require('path');
const utils = require('./utils')
const routes = require('./routes');
const redisConnect = require('./service/redis')
@ -51,4 +53,10 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
require('./models/secret_yingshi')(dc);
require('./models/gb_camera')(dc);
require('./models/ax_project')(dc);
require('./models/camera_remark')(dc);
// TODO 模型关系摘出来 初始化之后再定义关系才行
// fs.readdirSync(path.join(__dirname, '/models')).forEach((filename) => {
// require(`./models/${filename}`)(dc)
// });
};

52
code/VideoAccess-VCMP/api/app/lib/models/camera_remark.js

@ -0,0 +1,52 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraRemark = sequelize.define("cameraRemark", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_remark_id_uindex"
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false,
references: {
key: "id",
model: "camera"
}
},
remark: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "remark",
autoIncrement: false
}
}, {
tableName: "camera_remark",
comment: "",
indexes: []
});
dc.models.CameraRemark = CameraRemark;
const Camera = dc.models.Camera;
CameraRemark.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
Camera.hasMany(CameraRemark, { foreignKey: 'cameraId', sourceKey: 'id' });
return CameraRemark;
};

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

@ -70,4 +70,7 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/camera/kind'] = { content: '获取摄像头种类列表', visible: false };
router.get('/camera/kind', camera.getKind);
app.fs.api.logAttr['POST/camera/remark'] = { content: '编辑摄像头备注', visible: false };
router.post('/camera/remark', camera.remark);
};

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

@ -97,11 +97,12 @@ module.exports = function (app, opts) {
{
// interval: '0 0 4 */1 *',
// interval: '*/30 * * * *',
interval: '0 34 5 * * *',
interval: '0 34 5 1 * *',
immediate: true,
},
async () => {
try {
const startTime = moment()
const { models } = app.fs.dc
const { token4yingshi, getYingshiPlayUrl } = app.fs.utils
const secretRes = await models.SecretYingshi.findAll()
@ -137,6 +138,7 @@ module.exports = function (app, opts) {
}
}
}
console.info(`萤石设备 ${deviceList.length} 播放地址更新查询用时 ${moment().diff(startTime, 'seconds')} s`)
} catch (error) {
app.fs.logger.error(`sechedule: freshYingshiPlayUrl, error: ${error}`);
}

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

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

4
code/VideoAccess-VCMP/api/app/lib/utils/token4yingshi.js

@ -81,8 +81,8 @@ module.exports = function (app, opts) {
}
const typeMap = {
// live: 1,
cloud: 2,
local: 3
local: 2,
cloud: 3
}
let playUrl = {

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

@ -81,6 +81,7 @@ const product = {
}, {
entry: require('./app').entry,
opts: {
dev,
exclude: [], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
redis: {
host: IOTA_REDIS_SERVER_HOST,

2
code/VideoAccess-VCMP/api/sequelize-automate.config.js

@ -26,7 +26,7 @@ module.exports = {
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['camera_ability_bind'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
tables: ['camera_remark'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面

72
code/VideoAccess-VCMP/script/0.0.1/0_init_db.sql

@ -12,7 +12,7 @@
Target Server Version : 90515
File Encoding : 65001
Date: 20/06/2022 14:41:32
Date: 06/07/2022 11:45:25
*/
@ -38,6 +38,17 @@ MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for camera_remark_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."camera_remark_id_seq";
CREATE SEQUENCE "public"."camera_remark_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for gbCamera_id_seq
-- ----------------------------
@ -151,7 +162,8 @@ CREATE TABLE "public"."camera" (
"model" varchar(128) COLLATE "pg_catalog"."default",
"kind_id" int4,
"yingshi_secret_id" int4,
"gb_id" int4
"gb_id" int4,
"top_serial_no" varchar(128) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "public"."camera"."type" IS '设备类型:yingshi - 萤石;nvr - NVR摄像头;ipc - IPC 网络摄像头;cascade - 级联摄像头';
@ -171,6 +183,7 @@ COMMENT ON COLUMN "public"."camera"."forbidden" IS '是否禁用';
COMMENT ON COLUMN "public"."camera"."recycle_time" IS '放入回收站时间';
COMMENT ON COLUMN "public"."camera"."delete" IS '是否彻底删除';
COMMENT ON COLUMN "public"."camera"."model" IS '型号';
COMMENT ON COLUMN "public"."camera"."top_serial_no" IS 'gb设备 level=0 的 steamid ';
-- ----------------------------
-- Table structure for camera_ability
@ -221,6 +234,17 @@ INSERT INTO "public"."camera_kind" VALUES (1, '枪机');
INSERT INTO "public"."camera_kind" VALUES (2, '球机');
INSERT INTO "public"."camera_kind" VALUES (1314, '其他');
-- ----------------------------
-- Table structure for camera_remark
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera_remark";
CREATE TABLE "public"."camera_remark" (
"id" int4 NOT NULL DEFAULT nextval('camera_remark_id_seq'::regclass),
"camera_id" int4 NOT NULL,
"remark" varchar(256) COLLATE "pg_catalog"."default" NOT NULL
)
;
-- ----------------------------
-- Table structure for gbCamera
-- ----------------------------
@ -240,9 +264,11 @@ CREATE TABLE "public"."gbCamera" (
"Sipip" varchar(255) COLLATE "pg_catalog"."default",
"ipctype" varchar(255) COLLATE "pg_catalog"."default",
"registerTime" varchar(255) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
"updateTime" varchar(255) COLLATE "pg_catalog"."default"
"updateTime" varchar(255) COLLATE "pg_catalog"."default",
"playUrl" jsonb
)
;
COMMENT ON COLUMN "public"."gbCamera"."playUrl" IS '播放地址集合';
-- ----------------------------
-- Table structure for nvr
@ -286,9 +312,9 @@ CREATE TABLE "public"."secret_yingshi" (
-- ----------------------------
-- Records of secret_yingshi
-- ----------------------------
INSERT INTO "public"."secret_yingshi" VALUES (3, 'd0704fb9d5d14a6682c1c1d592c12512', '93d023269495b86be62cdfdcf34a6cd1', 'at.67z1cfi515oyuu8p4wtgnr6e8dd7qwe4-6bg4tycrsw-0evcx34-xh1ks80et', '1656293969344');
INSERT INTO "public"."secret_yingshi" VALUES (1, '5d16a667e1c2423d9d0d634f781810b4', '0cc4e1ec4e6a53ea3dabeb09cd5f468b', 'at.4p2f551n58eb9cjdd8vr4uuh1j4ozdjn-9gvmswjpa7-1y5juuk-gochbasv0', '1656294553279');
INSERT INTO "public"."secret_yingshi" VALUES (2, '3ea2b502f6804d64b43e4cb3d135665c', '331c85c5b7ce76179f6eb7dccb8aeb27', 'at.9q4woxj71nkmckb9d2xe1yoycc81fd4l-2a45fk76s4-0qvuhi2-j5bvk57lp', '1656293899796');
INSERT INTO "public"."secret_yingshi" VALUES (2, '3ea2b502f6804d64b43e4cb3d135665c', '331c85c5b7ce76179f6eb7dccb8aeb27', 'at.culo424j9drz8atx9uikeq5e2mzkhnhx-490csubqrh-1o3hcaz-szuvfax6f', '1657681218109');
INSERT INTO "public"."secret_yingshi" VALUES (3, 'd0704fb9d5d14a6682c1c1d592c12512', '93d023269495b86be62cdfdcf34a6cd1', 'at.1y2mk5fh2myswbkp017pmvdi0v1zbdrw-5j39z78wsp-0x4vi2j-a3mxjlt32', '1657683606281');
INSERT INTO "public"."secret_yingshi" VALUES (1, '5d16a667e1c2423d9d0d634f781810b4', '0cc4e1ec4e6a53ea3dabeb09cd5f468b', 'at.9gq3xwwbazkk33y177ucqtk936bmd0sz-41x4xf24sh-1cn7x82-4lf7davve', '1657681803201');
-- ----------------------------
-- Table structure for t_upload_comm_http
@ -326,14 +352,18 @@ INSERT INTO "public"."vender" VALUES (1314, '其他');
-- ----------------------------
ALTER SEQUENCE "public"."camera_ability_bind_id_seq"
OWNED BY "public"."camera_ability_bind"."id";
SELECT setval('"public"."camera_ability_bind_id_seq"', 35, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."camera_id_seq"
OWNED BY "public"."camera"."id";
SELECT setval('"public"."camera_id_seq"', 314, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."camera_remark_id_seq"
OWNED BY "public"."camera_remark"."id";
-- ----------------------------
-- Alter sequences owned by
@ -343,14 +373,12 @@ SELECT setval('"public"."gbCamera_id_seq"', 2, false);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
SELECT setval('"public"."gb_id_seq"', 38, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."nvr_id_seq"
OWNED BY "public"."nvr"."id";
SELECT setval('"public"."nvr_id_seq"', 69, true);
-- ----------------------------
-- Alter sequences owned by
@ -431,10 +459,27 @@ CREATE UNIQUE INDEX "camera_kind_id_uindex" ON "public"."camera_kind" USING btre
-- ----------------------------
ALTER TABLE "public"."camera_kind" ADD CONSTRAINT "camera_kind_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera_remark
-- ----------------------------
CREATE UNIQUE INDEX "camera_remark_id_uindex" ON "public"."camera_remark" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera_remark
-- ----------------------------
ALTER TABLE "public"."camera_remark" ADD CONSTRAINT "camera_remark_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table gbCamera
-- ----------------------------
ALTER TABLE "public"."gbCamera" ADD CONSTRAINT "gbCamera_pkey" PRIMARY KEY ("id");
ALTER TABLE "public"."gbCamera" ADD CONSTRAINT "gbCamera1_copy1_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table gbCamera1
-- ----------------------------
ALTER TABLE "public"."gbCamera1" ADD CONSTRAINT "gbCamera_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table nvr
@ -491,6 +536,11 @@ ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_vender_id_fk" FOREIGN KEY (
ALTER TABLE "public"."camera_ability_bind" ADD CONSTRAINT "camera_ability_bind_camera_ability_id_fk" FOREIGN KEY ("ability_id") REFERENCES "public"."camera_ability" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "public"."camera_ability_bind" ADD CONSTRAINT "camera_ability_bind_camera_id_fk" FOREIGN KEY ("camera_id") REFERENCES "public"."camera" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ----------------------------
-- Foreign Keys structure for table camera_remark
-- ----------------------------
ALTER TABLE "public"."camera_remark" ADD CONSTRAINT "camera_remark_camera_id_fk" FOREIGN KEY ("camera_id") REFERENCES "public"."camera" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ----------------------------
-- Foreign Keys structure for table nvr
-- ----------------------------

BIN
code/VideoAccess-VCMP/web/client/assets/video/remarks.mp4

Binary file not shown.

1
code/VideoAccess-VCMP/web/client/index.ejs

@ -6,6 +6,7 @@
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<script src="/assets/js/jessibuca/jessibuca.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_14797_10.b43556420cacd0119dedf94deff663bb.js"></script>
</head>
<body>

41
code/VideoAccess-VCMP/web/client/src/components/textScroll.jsx

@ -3,19 +3,40 @@ import moment from 'moment'
import './textScroll.less'
function TextScroll (props) {
const { content, duration } = props
const [showContent, setShowContent] = useState('1231231')
const [timer, setTimer] = useState(null)
const { content, duration,roll } = props
const [showContent, setShowContent] = useState('')
const showIndex = useRef(0)
console.log(content);
const initialization = useRef(false)
const cancel = useRef(false)
useEffect(() => {
if (content.length) {
if(roll){
let contentParent = document.getElementById('marquee_box')
document.getElementById('contentPMakeUp').style.width = contentParent.clientWidth + 'px'
const contentP = document.getElementById('contentP')
contentP.style.visibility = 'visible'
setShowContent(content[0])
window.cancelAnimationFrame(cancel.current)
contentParent.scrollLeft = 0
initialization.current=false
showIndex.current = 0
}
else{
let repeatTime = moment()
let refreshTime = moment()
const scroll = () => {
let contentParent = document.getElementById('marquee_box')
document.getElementById('contentPMakeUp').style.width = contentParent.clientWidth + 'px'
//
// if(!showContent&&!initialization.current){
if(!initialization.current){
const contentP = document.getElementById('contentP')
contentParent.scrollLeft = 0
setShowContent(content[showIndex.current])
showIndex.current = (showIndex.current + 1) % content.length
contentP.style.visibility = 'visible'
initialization.current=true
}
//
if (moment().diff(refreshTime) > 1000 / 60) {
const contentP = document.getElementById('contentP')
@ -37,14 +58,16 @@ function TextScroll (props) {
}
refreshTime = moment()
}
window.requestAnimationFrame(scroll)
let text = null
text=window.requestAnimationFrame(scroll)
cancel.current=text
}
window.requestAnimationFrame(scroll)
}
}, [])
}
}, [content,roll])
return (
<div className="marquee_box" id='marquee_box' style={{ overflow: 'hidden' }} >
<div className="marquee_box" id='marquee_box' style={{ overflow: 'hidden',color:'#F9F9F9' }} >
<p style={{ position: 'relative', left: 24 }}>
<p id='contentP' style={{ display: 'inline-block', visibility: 'hidden' }}>{showContent}</p>
<p id='contentPMakeUp' style={{ width: 0, display: 'inline-block' }}></p>

11
code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/actions/camera.js

@ -208,3 +208,14 @@ export function postVerifyYingshi(data) {
msg: { option: "" }, //获取级联视频流
});
}
export function postCameraRemark(data) {
return (dispatch) =>
basicAction({
type: "post",
dispatch: dispatch,
data,
actionType: "POST_CAMERA_REMARK",
url: `${ApiTable.postCameraRemark}`,
msg: { option: "摄像头备注" }, //编辑摄像头备注
});
}

137
code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/remarksModal.jsx

@ -0,0 +1,137 @@
import React, { useState, useRef, useEffect } from "react";
import { connect } from "react-redux";
import { Modal, Spin,Input } from "@douyinfe/semi-ui";
import TextScroll from "../../../components/textScroll";
function remarksModal (props) {
const {
close,
visible,
rowId,
dispatch,
actions
} = props;
const { equipmentWarehouse } = actions;
const [ScrollList, setScrollList] = useState([{num:'01',value:''},{num:'02',value:''},{num:'03',value:''}]); //
const [showScrollList, setShowScrollList] = useState([]); //
const [roll,setroll] = useState(false);
const [showValueNum,setShowValueNum] = useState(0);
const valueNum = useRef(0);
// useEffect(() => {
// setShowScrollList([
// '76',
// '111111111111111111111111111111111111111111111111111111'
// ])
// }, []);
function handleOk () {
//
dispatch(
equipmentWarehouse.postCameraRemark({
cameraId:rowId,
remark:showScrollList
})
).then((res) => {
close();
})
}
function handleAfterClose () {
//
}
function handleCancel () {
close();
//
}
function onChange(value,num){
valueNum.current=0
let myScrollList=ScrollList
myScrollList[num].value=value
setScrollList(myScrollList);
setShowScrollList([value])
for (let index = 0; index < myScrollList.length; index++) {
if(myScrollList[index].value){
valueNum.current=valueNum.current+1
}
}
setShowValueNum(valueNum.current);
}
function onFocus(num){
setShowScrollList([ScrollList[num].value])
setroll(true)
}
function onBlur(){
setShowScrollList([])
let myScrollList = []
for (let index = 0; index < ScrollList.length; index++) {
if(ScrollList[index].value){
myScrollList.push(ScrollList[index].value)
}
}
setShowScrollList(myScrollList)
setroll(false)
}
return (
<>
<Modal
title="备注管理"
okText="确定"
cancelText="取消"
visible={visible}
onOk={handleOk}
width={763}
afterClose={handleAfterClose}
onCancel={handleCancel}
>
<div style={{margin:"2px 14px 18px 29px",display:'flex'}}>
<div style={{width:394}}>
<div style={{display:'flex'}}>
<div style={{color:'#1859C1',fontWeight: 600}}>请添加备注信息</div>
<div>{showValueNum}/3</div>
</div>
<div style={{marginTop:8}}>
{ScrollList.map((item, index) => (
<div key={index} style={{marginTop:12}}>
<Input
prefix={<div style={{color: 'rgba(0, 0, 0, 0.75)',margin:'0px 12px'}}>{item.num}</div>}
value={item.value}
onChange={(value)=>onChange(value,index)}
onFocus={()=>onFocus(index)}
onBlur={onBlur}
maxLength={25}
showClear></Input>
</div>
))}
</div>
</div>
<div style={{width:306,marginLeft:20,position: ""}}>
<div style={{ position: "absolute",background:'rgba(0, 0, 0, 0.15)',width:306}}>
<TextScroll content={showScrollList} roll={roll} duration={6} />
</div>
<video
id="cameraBanner"
autoPlay
loop
muted
style={{ width: 306,height:185, objectFit: "cover", }}
src="/assets/video/remarks.mp4"
type="video/mp4"
/>
</div>
</div>
</Modal>
</>
);
}
function mapStateToProps (state) {
const { auth, global, members, CameraKind, CameraAbility } = state;
return {
loading: members.isRequesting,
user: auth.user,
actions: global.actions,
CameraKind: CameraKind.data || [],
CameraAbility: CameraAbility.data || [],
};
}
export default connect(mapStateToProps)(remarksModal);

29
code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/containers/camera.jsx

@ -16,6 +16,7 @@ import {
import { SimpleFileDownButton, VideoPlayModal } from "$components";
import "../style.less";
import CameraModal from "../components/cameraModal";
import RemarksModal from "../components/remarksModal";
import Setup from "../components/setup";
import SideSheets from "../components/sideSheet";
import { skeletonScreen } from "../components/skeletonScreen";
@ -24,6 +25,7 @@ import { accessType } from "./nvr";
const CameraHeader = (props) => {
const { dispatch, actions, user, loading, equipmentWarehouseCamera } = props;
const [cameraModal, setCameraModal] = useState(false);
const [remarksModal,setRemarksModal] = useState(false);
const [videoPlay, setVideoPlay] = useState(false);
const [modalName, setModalName] = useState("");
const [setup, setSetup] = useState(false);
@ -279,6 +281,22 @@ const CameraHeader = (props) => {
>
<Button theme="borderless">删除</Button>
</Popconfirm>
<Button
theme="borderless"
onClick={() => {
setVideoObj({
type:'remarks',
// serialNo: row.serialNo,
// yingshiToken: row.secretYingshi.token,
// playUrlSd: row.gbCamera.playUrl.liveUrl.sd.ezopen,
// playUrlHd: row.gbCamera.playUrl.liveUrl.hd.ezopen,
})
setRowId(row.id);
setRemarksModal(true)
}}
>
备注
</Button>
</div>
);
},
@ -822,6 +840,17 @@ const CameraHeader = (props) => {
}} />
: ""
}
{
remarksModal?
<RemarksModal
visible={true}
rowId={rowId}
close={() => {
setRemarksModal(false)
setRowId()
}} >
</RemarksModal>:''
}
</>
);
};

5
code/VideoAccess-VCMP/web/client/src/utils/webapi.js

@ -25,7 +25,7 @@ export const ApiTable = {
delCamera: "camera/{cameraId}", //删除摄像头
getCameraDetails: "camera/{cameraId}/detail", //获取摄像头详情
getCameraKind: "camera/kind", //获取摄像头种类列表
getAbility: "/camera/ability", //获取摄像头能力列表
getAbility: "camera/ability", //获取摄像头能力列表
postCameraYingshi: "camera/create/yingshi", //创建萤石摄像头
postCameraIpc: "camera/create/ipc", //创建IPC摄像头
getVideoStreaming: "camera/nvr_stream", //获取NVR视频流
@ -36,8 +36,9 @@ export const ApiTable = {
postVerifyYingshi: "camera/verify/yingshi", //验证萤石摄像头信息
postVerifyIpc: "camera/verify/ipc", //验证IPC摄像头信息
postVerifyCascade: "camera/verify/cascade", //验证级联摄像头信息
getCascadeStream: "/camera/cascade_stream", //获取级联视频流
getCascadeStream: "camera/cascade_stream", //获取级联视频流
uploadYingshiVoice: 'camera/yingshi_voice/upload', //上传萤石语音
postCameraRemark: 'camera/remark',//编辑摄像头备注
};
export const VideoServeApi = {

9
code/VideoAccess-VCMP/web/webpack.config.prod.js

@ -1,6 +1,7 @@
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const SemiWebpackPlugin = require('@douyinfe/semi-webpack-plugin').default;
const PATHS = {
app: path.join(__dirname, 'client/src'),
@ -30,7 +31,13 @@ module.exports = {
new HtmlWebpackPlugin({
filename: '../index.html',
template: './client/index.ejs'
})
}),
new SemiWebpackPlugin({
theme: {
name: '@semi-bot/semi-theme-fscamera',
include: '~@semi-bot/semi-theme-fscamera/scss/local.scss'
}
}),
],
optimization: {
splitChunks: {

Loading…
Cancel
Save