diff --git a/code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js b/code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js
index 611ef3a..3594158 100644
--- a/code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js
+++ b/code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js
@@ -29,14 +29,24 @@ async function check (ctx) {
}
async function edit (ctx, next) {
- let errMsg = '创建应用失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body;
- if (data.id) {
+ let findOption = { where: { name: data.name } }
+
+ if (data.appId) {
+ findOption.where.id = { $ne: data.appId }
+ }
+
+ const applicationRes = await models.Application.findOne(findOption)
+ if (applicationRes) {
+ throw '已有相同应用名称'
+ }
+
+ if (data.appId) {
// 修改
const storageData = Object.assign({}, data,)
await models.Application.update(storageData, {
@@ -66,7 +76,7 @@ async function edit (ctx, next) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
- message: errMsg
+ message: typeof error == 'string' ? error : undefined
}
}
}
@@ -74,11 +84,11 @@ async function edit (ctx, next) {
async function get (ctx) {
try {
const models = ctx.fs.dc.models;
- const { userId } = ctx.fs.api
+ const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection } = ctx.query
let findOption = {
where: {
- createUserId: userId,
+ // createUserId: userId,
},
order: [
[orderBy || 'id', orderDirection || 'DESC'] //查询排序
@@ -91,12 +101,30 @@ async function get (ctx) {
if (page && limit) {
findOption.offset = page * limit
}
- const nvrRes = await models.Application.findAndCountAll(findOption)
+ const applicationRes = await models.Application.findAndCountAll(findOption)
+
+
+ let createUserIds = new Set()
+ let cameraIds = []
+ for (let c of applicationRes.rows) {
+ cameraIds.push(c.id)
+ createUserIds.add(c.createUserId)
+ }
+
+ // 查用户信息
+ const createUserRes = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
+
+ for (let { dataValues: n } of applicationRes.rows) {
+ const corCreateUser = createUserRes.find(u => u.id == n.createUserId)
+ n.createUser = {
+ name: corCreateUser ? corCreateUser.username : ''
+ }
+ }
ctx.status = 200;
ctx.body = {
- total: nvrRes.count,
- data: nvrRes.rows
+ total: applicationRes.count,
+ data: applicationRes.rows
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
@@ -133,8 +161,15 @@ async function del (ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
+ const { token } = ctx.fs.api
const { appId } = ctx.params
+ const { appKey } = await models.Application.findOne({
+ where: {
+ id: appId
+ },
+ }) || {}
+
await models.Application.destroy({
where: {
id: appId
@@ -142,6 +177,10 @@ async function del (ctx, next) {
transaction
})
+ await ctx.app.fs.authRequest.delete(`oauth2/token/invalidate_all`, {
+ query: { token, appKey }
+ })
+
await transaction.commit();
ctx.status = 204;
} catch (error) {
diff --git a/code/VideoAccess-VCMP/web/client/src/sections/application/actions/application.js b/code/VideoAccess-VCMP/web/client/src/sections/application/actions/application.js
index e884e54..6472ddf 100644
--- a/code/VideoAccess-VCMP/web/client/src/sections/application/actions/application.js
+++ b/code/VideoAccess-VCMP/web/client/src/sections/application/actions/application.js
@@ -3,40 +3,52 @@
import { basicAction } from "@peace/utils";
import { ApiTable } from "$utils";
-export function getCamera(query) {
- return (dispatch) =>
- basicAction({
- type: "get",
- dispatch: dispatch,
- actionType: "GET_APPLICATION",
- query: query,
- url: `${ApiTable.getCamera}`,
- msg: { option: "获取摄像头列表信息" },
- reducer: { name: "applicationData", params: { noClear: true } },
- });
+export function getApplication (query) {
+ return (dispatch) =>
+ basicAction({
+ type: "get",
+ dispatch: dispatch,
+ actionType: "GET_APPLICATION",
+ query: query,
+ url: `${ApiTable.getApplication}`,
+ msg: { option: "获取应用信息" },
+ reducer: { name: "applicationData", params: { noClear: true } },
+ });
}
-export function putForbidden(data, forbidden) {
- return (dispatch) =>
- basicAction({
- type: "put",
- dispatch: dispatch,
- actionType: "PUT_APPLICATION",
- data,
- url: `${ApiTable.putForbidden}`,
- msg: { option: forbidden ? "启用" : "禁用" }, //禁用摄像头
- reducer: {},
- });
+export function putApplication (data) {
+ return (dispatch) =>
+ basicAction({
+ type: "put",
+ dispatch: dispatch,
+ actionType: "PUT_APPLICATION",
+ data,
+ url: `${ApiTable.putApplication}`,
+ msg: { option: data?.forbidden ? "启用" : "禁用" }, //禁用摄像头
+ reducer: {},
+ });
}
-export function delCamera(orgId) {
- return (dispatch) =>
- basicAction({
- type: "del",
- dispatch: dispatch,
- actionType: "DEL_APPLICATION",
- url: `${ApiTable.delCamera.replace("{cameraId}", orgId)}`,
- msg: { option: "设备会被存放在“设备回收站”中,删除" }, //删除摄像头
- reducer: {},
- });
+export function delApplication (orgId) {
+ return (dispatch) =>
+ basicAction({
+ type: "del",
+ dispatch: dispatch,
+ actionType: "DEL_APPLICATION",
+ url: `${ApiTable.delApplication.replace("{appId}", orgId)}`,
+ msg: { option: "删除" }, //删除应用
+ reducer: {},
+ });
+}
+
+export function postApplication (data) {
+ return (dispatch) =>
+ basicAction({
+ type: "post",
+ dispatch: dispatch,
+ data,
+ actionType: "POST_CHANGE_NVR",
+ msg: { option: data?.appId ? "修改" : "添加" },
+ url: `${ApiTable.postApplication}`,
+ });
}
\ No newline at end of file
diff --git a/code/VideoAccess-VCMP/web/client/src/sections/application/components/applyModal.jsx b/code/VideoAccess-VCMP/web/client/src/sections/application/components/applyModal.jsx
index a363bb5..d73cd5c 100644
--- a/code/VideoAccess-VCMP/web/client/src/sections/application/components/applyModal.jsx
+++ b/code/VideoAccess-VCMP/web/client/src/sections/application/components/applyModal.jsx
@@ -2,79 +2,85 @@ import React, { useState, useEffect, useRef } from "react";
import { connect } from "react-redux";
import { Button, Form, Modal, } from "@douyinfe/semi-ui";
-const ApplyModal = ({ close, modalName, visible }) => {
- const form = useRef();
+const ApplyModal = ({ dispatch, actions, close, modalName, visible, appData }) => {
+ const { applicationCenter } = actions;
+ const appDatas = appData || {}
+ const form = useRef();
-
- const handleOk = () => {
- form.current
- .validate()
- .then((values) => {
- console.log(values);
- // close()
+ const handleOk = () => {
+ form.current
+ .validate()
+ .then((values) => {
+ if (appDatas?.id) {
+ values.appId = appDatas?.id
+ }
+ dispatch(applicationCenter.postApplication(values)).then((res) => {
+ console.log(res);
+ if (res.success) {
+ close()
+ form.current.reset()
+ }
})
+ })
+ }
- }
-
- return close()}
- onOk={handleOk}
- >
-
-
- {[{ name: 'web', id: 'web' }, { name: 'app', id: 'app' }, { name: '小程序', id: '小程序' }, { name: '其他', id: '其他' }].map((item, index) => (
-
- {item.name}
-
- ))}
-
-
-
+ return { close(); form.current.reset() }}
+ onOk={handleOk}
+ >
+
+
+ {[{ name: 'web', value: 'web' }, { name: 'app', value: 'app' }, { name: '小程序', value: 'wxapp' }, { name: '其他', value: 'other' }].map((item, index) => (
+
+ {item.name}
+
+ ))}
+
+
+
}
function mapStateToProps (state) {
- const { auth, global, members } = state;
- return {
- loading: members.isRequesting,
- user: auth.user,
- actions: global.actions,
- global: global,
- members: members.data,
- };
+ const { auth, global, members } = state;
+ return {
+ loading: members.isRequesting,
+ user: auth.user,
+ actions: global.actions,
+ global: global,
+ members: members.data,
+ };
}
export default connect(mapStateToProps)(ApplyModal);
diff --git a/code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx b/code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx
index 73bffbd..5327461 100644
--- a/code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx
+++ b/code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx
@@ -3,15 +3,15 @@ import { connect } from "react-redux";
import moment from "moment";
import qs from "qs";
import {
- Button,
- Form,
- Table,
- Pagination,
- Popover,
- Tag,
- Skeleton,
- Popconfirm,
- Row,
+ Button,
+ Form,
+ Table,
+ Pagination,
+ Popover,
+ Tag,
+ Skeleton,
+ Popconfirm,
+ Row,
} from "@douyinfe/semi-ui";
import { SimpleFileDownButton, VideoPlayModal, SkeletonScreen, Setup } from "$components";
// import "../style.less";
@@ -22,349 +22,368 @@ import ApplyModal from "../components/applyModal";
import '../style.less'
const ApplicationCenter = (props) => {
- const { dispatch, actions, user, loading, equipmentWarehouseCamera } = props;
- // const { equipmentWarehouse } = actions;
- const [cameraModal, setCameraModal] = useState(false);
- const [remarksModal, setRemarksModal] = useState(false);
- const [videoPlay, setVideoPlay] = useState(false);
- const [modalName, setModalName] = useState(false); //创建或修改
- const [setup, setSetup] = useState(false); //表格设置是否显现
- const [applyModal, setApplyModal] = useState(false);
- const [cameraSetup, setcameraSetup] = useState(false);
- const [setupp, setSetupp] = useState([]);
- const [venderList, setvenderList] = useState([]); //厂商信息
- const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
- const [search, setSearch] = useState({}); //搜索条件
- const [rowId, setRowId] = useState(); //表格数据id
- const [cameraData, setCameraData] = useState({}); //表格传递数据
- const [modify, setModify] = useState(false); //修改
- const [parentCamera, setParentCamera] = useState(""); //级联摄像头父级设备
- const [addNvr, setAddNvr] = useState(false); //nvr页面传递参数打开NVR摄像头添加弹框
- const [nvrNumber, setNvrNumber] = useState();
- const [videoObj, setVideoObj] = useState(); //播放条件
- const [axyData, setAxyData] = useState();
- const [cameraRemarks, setCameraRemarks] = useState([]);//备注
- const api = useRef();
- const searchData = useRef({})
- const limits = useRef(); //每页实际条数
- const page = useRef(query.page);
- const deviceClickb = useRef(true)
- const APPLICATION = "application";
+ const { dispatch, actions, user, loading, applicationData } = props;
+ const { applicationCenter } = actions;
+ const [modalName, setModalName] = useState(false); //创建或修改
+ const [setup, setSetup] = useState(false); //表格设置是否显现
+ const [applyModal, setApplyModal] = useState(false);
+ const [setupp, setSetupp] = useState([]);
+ const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
+ const [appData, setAppData] = useState(null); //应用id
+ const APPLICATION = 'application'
+ const pageLimit = useRef({ limit: 10, page: 0 });
+ const limits = useRef(); //每页实际条数
+ const columns = [
+ {
+ title: "序号",
+ dataIndex: "",
+ render: (text, r, index) => {
+ return index + 1;
+ },
+ },
+ {
+ title: "应用名称",
+ dataIndex: "name",
+ key: "name",
+ render: (text, r, index) => {
+ return r?.name.length > 8 ? `${r?.name.substr(0, 8)}...` : r?.name
+ },
- const columns = [
- {
- title: "序号",
- dataIndex: "",
- render: (text, r, index) => {
- return index + 1;
- },
- },
- {
- title: "应用名称",
- dataIndex: "name",
- key: "name",
- },
- {
- title: "APPID",
- dataIndex: "appId",
- key: "appId",
-
- },
- {
- title: "Secret Key",
- dataIndex: "secretKey",
- key: "secretKey",
+ },
+ {
+ title: "APPID",
+ dataIndex: "appKey",
+ key: "appId",
- },
- {
- title: "操作",
- width: "20%",
- dataIndex: "",
- render: (_, row) => {
- return (
-
-
- {row.forbidden ? (
-
- ) : (
-
{
+ },
+ {
+ title: "操作",
+ width: "20%",
+ dataIndex: "",
+ render: (_, row) => {
+ return (
+
+
+ {row?.forbidden ? (
+
+ ) : (
+
禁用后,应用系统引入的页面及能力将会暂时失效,请谨慎操作。 }
+ arrowPointAtCenter={false}
+ showArrow={true}
+ position="topRight"
+ onConfirm={() => {
+ dispatch(applicationCenter.putApplication({ appId: row?.id, forbidden: !row?.forbidden })).then(() => {
+ setQuery({ limit: pageLimit.current.limit, page: pageLimit.current.page })
+ })
+ }}
+ >
+
+
+ )}
+
删除后,应用系统引入的页面及能力将会永久失效,请谨慎操作。 }
+ arrowPointAtCenter={false}
+ width={300}
+ showArrow={true}
+ position="topRight"
+ onConfirm={() => {
+ dispatch(applicationCenter.delApplication(row?.id)).then(() => {
+ if (pageLimit.current.page > 0 && limits.current < 2) {
+ setQuery({ limit: pageLimit.current.limit, page: pageLimit.current.page - 1 })
+ } else {
+ setQuery({ limit: pageLimit.current.limit, page: pageLimit.current.page })
+ }
+ })
+ }}
+ >
+
+
- }}
- >
-
-
- )}
- {
+
+ );
+ },
+ }
+ ];
- }}
- >
-
-
+ //获取表格属性设置
+ function attribute () {
+ const arr = localStorage.getItem(APPLICATION)
+ ? JSON.parse(localStorage.getItem(APPLICATION))
+ : [];
-
- );
+ const column = [
+ {
+ title: "创建时间",
+ dataIndex: "createTime",
+ key: "createTime",
+ render: (_, r, index) => {
+ return r?.createUser?.name
},
- }
- ];
-
- //获取表格属性设置
- function attribute () {
- const arr = localStorage.getItem(APPLICATION)
- ? JSON.parse(localStorage.getItem(APPLICATION))
- : [];
-
- const column = [
- {
- title: "创建时间",
- dataIndex: "createTime",
- key: "createTime",
+ },
+ {
+ title: "创建账号",
+ dataIndex: "createUserId",
+ key: "account",
+ render: (_, r, index) => {
+ return moment(r.createTime).format("YYYY-MM-DD HH:MM:SS");
},
- {
- title: "创建账号",
- dataIndex: "account",
- key: "account",
-
+ },
+ {
+ title: "应用类型",
+ dataIndex: "type",
+ key: "applicationType",
+ render: (_, r, index) => {
+ const type = r?.type?.map((item, index) => item + ';')
+ return type
},
- {
- title: "应用类型",
- dataIndex: "applicationType",
- key: "applicationType",
+ },
+ ];
- },
- ];
+ for (let i = 0; i < arr.length; i++) {
+ let colum = column.filter((item) => {
+ return item.key === arr[i];
+ });
+ columns.splice(i + 4, 0, colum[0]);
+ }
+ setSetupp(columns);
+ }
+ const tableList = [//表格属性
+ {
+ title: '详情信息',
+ list: [
+ { name: "创建时间", value: "createTime" },
+ { name: "创建账号", value: "account" },
+ { name: "应用类型", value: "applicationType" },
+ ]
+ },
+ ];
- for (let i = 0; i < arr.length; i++) {
- let colum = column.filter((item) => {
- return item.key === arr[i];
- });
- columns.splice(i + 4, 0, colum[0]);
- }
- setSetupp(columns);
- }
- const tableList = [//表格属性
- {
- title: '详情信息',
- list: [
- { name: "创建时间", value: "createTime" },
- { name: "创建账号", value: "account" },
- { name: "应用类型", value: "applicationType" },
- ]
- },
- ];
+ //获取应用信息
+ const details = (data) => {
+ pageLimit.current = query
+ dispatch(applicationCenter.getApplication(pageLimit.current)).then((res) => {
+ limits.current = res.payload.data.data.length
+ });
+ }
+ useEffect(() => {
+ details()
+ }, [query])
- useEffect(() => {
- //初始化表格显示设置
- localStorage.getItem(APPLICATION) == null
- ? localStorage.setItem(
- APPLICATION,
- JSON.stringify(["createTime",])
- )
- : "";
- attribute();
- }, [])
- return (
- <>
-
-
-
-
- 应用管理
-
-
- 创建接口对应子系统的APPID及能力调用时所需的秘钥。
-
-
{
- setApplyModal(true)
- }}
- >
- 创建应用
-
-
+ useEffect(() => {
+ //初始化表格显示设置
+ localStorage.getItem(APPLICATION) == null
+ ? localStorage.setItem(
+ APPLICATION,
+ JSON.stringify(["createTime",])
+ )
+ : "";
+ attribute();
+ }, [])
+ return (
+ <>
+
+
+
+
+ 应用管理
+
+
+ 创建接口对应子系统的APPID及能力调用时所需的秘钥。
+
+
{
+ setApplyModal(true)
+ }}
+ >
+ 创建应用
+
-
-
-
- 应用列表
-
-
-
- {/*
*/}
-
-
-
- s)}
- dataSource={[{ name: 'csadca', }]}
- bordered={false}
- empty="暂无数据"
- style={{
- padding: "0px 20px",
- }}
- pagination={false}
- />
-
-
-
- 共{100}个设备
-
-
{
- setQuery({ limit: pageSize, page: currentPage - 1 });
- page.current = currentPage - 1
- }}
- />
-
-
+
+
+
+
+ 应用列表
+
+
+
+ {/*
*/}
+
+
+ s)}
+ dataSource={applicationData.data}
+ bordered={false}
+ empty="暂无数据"
+ style={{
+ padding: "0px 20px",
+ }}
+ pagination={false}
+ />
+
+
+
+ 共{applicationData.total}个设备
+
+
{
+ setQuery({ limit: pageSize, page: currentPage - 1 });
+ pageLimit.current = { limit: pageSize, page: currentPage - 1 }
+ }}
+ />
+
+
+
- {/*表格设置*/}
- {setup ? (
- {
- setSetup(false);
- attribute();
- }}
- />
- ) : (
- ""
- )}
+ {/*表格设置*/}
+ {setup ? (
+ {
+ setSetup(false);
+ attribute();
+ }}
+ />
+ ) : (
+ ""
+ )}
- {applyModal ? (
- {
- setApplyModal(false)
- setModalName(false)
- }}
- />
- ) : (
- ""
- )}
+ {applyModal ? (
+ {
+ setApplyModal(false)
+ setModalName(false)
+ setAppData(null)
+ details()
+ }}
+ />
+ ) : (
+ ""
+ )}
- >
- )
+ >
+ )
}
function mapStateToProps (state) {
- const { auth } = state;
- return {
- user: auth.user,
- };
+ const { global, applicationData } = state;
+ return {
+ actions: global.actions,
+ applicationData: applicationData.data || {}
+ };
}
export default connect(mapStateToProps)(ApplicationCenter);
diff --git a/code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx b/code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx
index 9947708..ebee457 100644
--- a/code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx
+++ b/code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx
@@ -43,7 +43,6 @@ function nvrModal(props) {
.validate()
.then((values) => {
//表单校验
- console.log(values)
let valuesObj = JSON.parse(JSON.stringify(values));
valuesObj.longitude = values.position.split(",")[0];
valuesObj.latitude = values.position.split(",")[1];
diff --git a/code/VideoAccess-VCMP/web/client/src/utils/webapi.js b/code/VideoAccess-VCMP/web/client/src/utils/webapi.js
index efc5a40..af5543e 100644
--- a/code/VideoAccess-VCMP/web/client/src/utils/webapi.js
+++ b/code/VideoAccess-VCMP/web/client/src/utils/webapi.js
@@ -38,20 +38,27 @@ export const ApiTable = {
postVerifyCascade: "camera/verify/cascade", //验证级联摄像头信息
getCascadeStream: "camera/cascade_stream", //获取级联视频流
uploadYingshiVoice: 'camera/yingshi_voice/upload', //上传萤石语音
- postCameraRemark: 'camera/remark',//编辑摄像头备注
+ postCameraRemark: 'camera/remark',//编辑摄像头备注
//获取状态码
- getStatus: 'status',//获取状态码
- putStatueBanned:'status/banned',//禁用状态码自定义
- postStatusResolve:'status/resolve',//编辑解决方案
- postStatusCustom:'status/custom',//自定义状态码释义
- getStatusSimpleAll:'status/simple_all',//获取全部状态码简略信息
- getCameraListAll:'camera/listAll',//获取所有摄像头信息
- getStatusPush:'status/push',//获取推送配置
- putSasdtatusPush:'status/push',//编辑推送配置
- delPush:'status/push/{configId}',//删除推送配置
- putPushBanned:'status/push/banned',//禁用推送配置
- getPushCopy:'status/push/{configId}/copy',//复制推送配置
- getPushLog:'/status/push/{configId}/log',//获取推送记录
+ getStatus: 'status',//获取状态码
+ putStatueBanned: 'status/banned',//禁用状态码自定义
+ postStatusResolve: 'status/resolve',//编辑解决方案
+ postStatusCustom: 'status/custom',//自定义状态码释义
+ getStatusSimpleAll: 'status/simple_all',//获取全部状态码简略信息
+ getCameraListAll: 'camera/listAll',//获取所有摄像头信息
+ getStatusPush: 'status/push',//获取推送配置
+ putSasdtatusPush: 'status/push',//编辑推送配置
+ delPush: 'status/push/{configId}',//删除推送配置
+ putPushBanned: 'status/push/banned',//禁用推送配置
+ getPushCopy: 'status/push/{configId}/copy',//复制推送配置
+ getPushLog: '/status/push/{configId}/log',//获取推送记录
+
+
+ //应用管理
+ getApplication: '/application', //获取应用信息
+ putApplication: '/application', //禁用应用
+ delApplication: '/application/{appId}', //删除应用
+ postApplication: '/application', //创建/修改应用
};
export const VideoServeApi = {