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
6369ae4c5e
  1. 21
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js
  2. 44
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  3. 17
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  4. 9
      code/VideoAccess-VCMP/web/client/src/components/videoPlay.jsx
  5. 59
      code/VideoAccess-VCMP/web/client/src/layout/actions/global.js
  6. 49
      code/VideoAccess-VCMP/web/client/src/layout/components/sider/index.jsx
  7. 4
      code/VideoAccess-VCMP/web/client/src/layout/containers/layout/index.jsx
  8. 8
      code/VideoAccess-VCMP/web/client/src/layout/index.jsx
  9. 6
      code/VideoAccess-VCMP/web/client/src/sections/auth/actions/auth.js
  10. 7
      code/VideoAccess-VCMP/web/client/src/sections/auth/containers/login.jsx
  11. 2
      code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/containers/camera.jsx
  12. 3
      code/VideoAccess-VCMP/web/client/src/utils/index.js
  13. 51
      code/VideoAccess-VCMP/web/client/src/utils/webapi.js
  14. 145
      code/VideoAccess-VCMP/web/config.js
  15. 2
      code/VideoAccess-VCMP/web/package.json
  16. 151
      code/VideoAccess-VCMP/web/routes/attachment/index.js

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

@ -350,10 +350,11 @@ async function getCascadeSipList (ctx) {
const { models } = ctx.fs.dc const { models } = ctx.fs.dc
const sipListRes = await models.GbCamera.findAll({ const sipListRes = await models.GbCamera.findAll({
attributes: ['id', 'streamid'], attributes: ['id', 'sipip'],
where: { where: {
level: 0, level: 0,
ipctype: '级联', ipctype: '级联',
sipip: { $ne: null }
} }
}) })
ctx.status = 200; ctx.status = 200;
@ -383,7 +384,9 @@ async function verifyCascadeCamera (ctx) {
async function createCascadeCamera (ctx) { async function createCascadeCamera (ctx) {
let errMsg = '添加级联摄像头信息失败' let errMsg = '添加级联摄像头信息失败'
const transaction = await ctx.fs.dc.orm.transaction();
try { try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api const { userId, token } = ctx.fs.api
const { sip, externalDomain, cascadeType } = ctx.request.body const { sip, externalDomain, cascadeType } = ctx.request.body
const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs
@ -396,7 +399,8 @@ async function createCascadeCamera (ctx) {
await models.Camera.findAll({ await models.Camera.findAll({
where: { where: {
type: 'cascade', type: 'cascade',
serialNo: { $in: allCameraIds } serialNo: { $in: allCameraIds },
delete: false
} }
}) : [] }) : []
let addData = [] let addData = []
@ -410,13 +414,19 @@ async function createCascadeCamera (ctx) {
} }
const added = addedCmeraRes.some(ac => ac.streamid == c.streamid) const added = addedCmeraRes.some(ac => ac.streamid == c.streamid)
if (added) { if (added) {
updateData.push({ let data = {
...storageData, ...storageData,
id: added.id, id: added.id,
}
updateData.push(data)
await models.Camera.update(data, {
where: { id: added.id },
transaction
}) })
} else { } else {
addData.push({ addData.push({
...storageData, ...storageData,
type: 'cascade',
serialNo: c.streamid, serialNo: c.streamid,
createTime: moment().format(), createTime: moment().format(),
createUserId: userId, createUserId: userId,
@ -424,8 +434,13 @@ async function createCascadeCamera (ctx) {
}) })
} }
} }
await models.Camera.bulkCreate(addData, {
transaction
})
await transaction.commit();
ctx.status = 204; ctx.status = 204;
} catch (error) { } catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400; ctx.status = 400;
ctx.body = { ctx.body = {

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

@ -5,7 +5,7 @@ const moment = require('moment')
async function getCameraProject (ctx, next) { async function getCameraProject (ctx, next) {
try { try {
const models = ctx.fs.dc.models; const models = ctx.fs.dc.models;
const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId } = ctx.query const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId, externalDomain } = ctx.query
const { userId, token } = ctx.fs.api const { userId, token } = ctx.fs.api
let findOption = { let findOption = {
@ -22,9 +22,13 @@ async function getCameraProject (ctx, next) {
model: models.CameraKind model: models.CameraKind
}, { }, {
model: models.Nvr, model: models.Nvr,
where: nvrId ? {
id: nvrId
} : {},
required: Boolean(nvrId), required: Boolean(nvrId),
attributes: ['id', 'name', 'serialNo'] attributes: ['id', 'name', 'serialNo']
}] }],
distinct: true
} }
let abilityFind = { let abilityFind = {
model: models.CameraAbility model: models.CameraAbility
@ -36,11 +40,15 @@ async function getCameraProject (ctx, next) {
findOption.offset = page * limit findOption.offset = page * limit
} }
if (keyword) { if (keyword) {
findOption.where.$or = [{ findOption.where.name = { $like: `%${keyword}%` }
name: { $like: `%${keyword}%` } // findOption.where.$or = [
}, { // {
serialNo: { $like: `%${keyword}%` } // name: { $like: `%${keyword}%` }
}] // },
// // {
// // serialNo: { $like: `%${keyword}%` }
// // }
// ]
} }
if (type) { if (type) {
findOption.where.type = type findOption.where.type = type
@ -53,12 +61,18 @@ async function getCameraProject (ctx, next) {
abilityId: abilityId abilityId: abilityId
} }
} }
if (externalDomain) {
findOption.where.externalDomain = externalDomain
}
findOption.include.push(abilityFind) findOption.include.push(abilityFind)
const cameraRes = await models.Camera.findAll(findOption) const cameraRes = await models.Camera.findAll(findOption)
const total = await models.Camera.count({
where: findOption.where delete findOption.order
}) delete findOption.limit
delete findOption.offset
delete findOption.attributes
const total = await models.Camera.count(findOption)
let cameraIds = [] let cameraIds = []
let createUserIds = new Set() let createUserIds = new Set()
@ -80,12 +94,10 @@ async function getCameraProject (ctx, next) {
: [] : []
for (let { dataValues: camera } of cameraRes) { for (let { dataValues: camera } of cameraRes) {
const corBindCamera = axbindCameraRes.find(b => b.cameraId == camera.id) const corBindCamera = axbindCameraRes.filter(b => b.cameraId == camera.id)
if (corBindCamera) { camera.station = corBindCamera.reduce((station, c) => {
camera.station = corBindCamera.stations return station.concat.apply(station, c.stations)
} else { }, [])
camera.station = []
}
const corUser = corUsers.find(u => u.id == camera.createUserId) const corUser = corUsers.find(u => u.id == camera.createUserId)
camera.createUser = { camera.createUser = {

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

@ -132,7 +132,24 @@ async function get (ctx) {
findOption.where.venderId = venderId findOption.where.venderId = venderId
} }
if (state) { if (state) {
const onLineMap = {
ON: ['ON', 'ONLINE'],
OFF: ['OFF'],
// UNKONW: [],
DISABLED: []
}
let unknowState = []
for (let k in onLineMap) {
unknowState = unknowState.concat(onLineMap[k])
}
gbNvrOption.where = {
online: state == 'UNKONW' ?
{ $notIn: unknowState }
: { $in: onLineMap[state] }
}
gbNvrOption.required = true
} }
findOption.include.push(gbNvrOption) findOption.include.push(gbNvrOption)

9
code/VideoAccess-VCMP/web/client/src/components/videoPlay.jsx

@ -12,7 +12,12 @@ const VideoPlay = ({ height, width }) => {
const [operationState, setoperationState] = useState() const [operationState, setoperationState] = useState()
const operation = [{ const operation = [{
key: 'control', key: 'control',
click: () => { console.log(121212); } click: () => {
console.log(object);
const nextOperationState = JSON.parse(JSON.stringify(operationState))
nextOperationState['control'].select = !nextOperationState['control'].select
setoperationState(nextOperationState)
}
}, { }, {
key: 'talk', key: 'talk',
click: () => { console.log(121212); } click: () => { console.log(121212); }
@ -98,7 +103,7 @@ const VideoPlay = ({ height, width }) => {
}}>123</Col> }}>123</Col>
<Col span={15} style={{}}> <Col span={15} style={{}}>
<div style={{ paddingRight: 12 }}> <div style={{ paddingRight: 12 }}>
<TextScroll content={['asdadasdasdasdasdasd','123123']} duration={6} /> <TextScroll content={['asdadasdasdasdasdasd', '123123']} duration={6} />
</div> </div>
</Col> </Col>
</Row> </Row>

59
code/VideoAccess-VCMP/web/client/src/layout/actions/global.js

@ -4,41 +4,42 @@ import { RouteTable } from '$utils'
export const INIT_LAYOUT = 'INIT_LAYOUT'; export const INIT_LAYOUT = 'INIT_LAYOUT';
export function initLayout (title, copyright, sections, actions) { export function initLayout (title, copyright, sections, actions) {
return { return {
type: INIT_LAYOUT, type: INIT_LAYOUT,
payload: { payload: {
title, title,
copyright, copyright,
sections, sections,
actions actions
} }
}; };
} }
export const RESIZE = 'RESIZE'; export const RESIZE = 'RESIZE';
export function resize (clientHeight, clientWidth) { export function resize (clientHeight, clientWidth) {
const headerHeight = 60 const headerHeight = 60
const footerHeight = 0 const footerHeight = 0
return { return {
type: RESIZE, type: RESIZE,
payload: { payload: {
clientHeight: clientHeight - headerHeight - footerHeight, clientHeight: clientHeight - headerHeight - footerHeight,
clientWidth: clientWidth clientWidth: clientWidth
} }
} }
} }
export const INIT_API_ROOT = 'INIT_API_ROOT'; export const INIT_API_ROOT = 'INIT_API_ROOT';
export function initApiRoot () { export function initApiRoot () {
return dispatch => { return dispatch => {
RouteRequest.get(RouteTable.apiRoot).then(res => { return RouteRequest.get(RouteTable.apiRoot).then(res => {
localStorage.setItem('apiRoot', res.root); localStorage.setItem('apiRoot', JSON.stringify(res));
dispatch({ return dispatch({
type: INIT_API_ROOT, type: INIT_API_ROOT,
payload: { payload: {
apiRoot: res.root apiRoot: res.root,
} iotAuthWeb: res.iotAuthWeb
}) }
}); })
} });
}
} }

49
code/VideoAccess-VCMP/web/client/src/layout/components/sider/index.jsx

@ -6,7 +6,7 @@ import { push } from 'react-router-redux';
let scrollbar = null let scrollbar = null
const Sider = props => { const Sider = props => {
const { collapsed, clientHeight, dispatch } = props const { collapsed, clientHeight, dispatch, pathname } = props
const [items, setItems] = useState([]) const [items, setItems] = useState([])
const [selectedKeys, setSelectedKeys] = useState([]) const [selectedKeys, setSelectedKeys] = useState([])
const [openKeys, setOpenKeys] = useState([]) const [openKeys, setOpenKeys] = useState([])
@ -14,6 +14,27 @@ const Sider = props => {
useEffect(() => { useEffect(() => {
const { sections, dispatch, user } = props; const { sections, dispatch, user } = props;
let nextItems = [] let nextItems = []
const initKeys = (items, lastKeys) => {
for (let it of items) {
if (it.to && it.to == pathname) {
lastKeys.selectedKeys.push(it.itemKey)
return lastKeys
} else if (it.items && it.items.length) {
const preLastKeys = JSON.parse(JSON.stringify(lastKeys))
preLastKeys.openKeys.push(it.itemKey)
const nextKeys = initKeys(it.items, JSON.parse(JSON.stringify(preLastKeys)))
if (nextKeys.selectedKeys.length > preLastKeys.selectedKeys.length || nextKeys.openKeys.length > preLastKeys.openKeys.length) {
return nextKeys
}
}
}
return lastKeys
return {
selectedKeys: [],
openKeys: []
}
}
for (let c of sections) { for (let c of sections) {
if (typeof c.getNavItem == 'function') { if (typeof c.getNavItem == 'function') {
let item = c.getNavItem(user, dispatch); let item = c.getNavItem(user, dispatch);
@ -24,13 +45,25 @@ const Sider = props => {
} }
setItems(nextItems) setItems(nextItems)
const lastSelectedKeys = localStorage.getItem('vcmp_selected_sider') const { selectedKeys, openKeys } = initKeys(
if (lastSelectedKeys) { nextItems,
setSelectedKeys(JSON.parse(lastSelectedKeys)) {
} selectedKeys: [],
const lastOpenKeys = localStorage.getItem('vcmp_open_sider') openKeys: []
if (lastOpenKeys) { }
setOpenKeys(JSON.parse(lastOpenKeys)) )
if (selectedKeys.length || openKeys.length) {
setSelectedKeys(selectedKeys)
setOpenKeys(openKeys)
} else {
const lastSelectedKeys = localStorage.getItem('vcmp_selected_sider')
if (lastSelectedKeys) {
setSelectedKeys(JSON.parse(lastSelectedKeys))
}
const lastOpenKeys = localStorage.getItem('vcmp_open_sider')
if (lastOpenKeys) {
setOpenKeys(JSON.parse(lastOpenKeys))
}
} }
scrollbar = new PerfectScrollbar('#page-slider', { suppressScrollX: true }); scrollbar = new PerfectScrollbar('#page-slider', { suppressScrollX: true });

4
code/VideoAccess-VCMP/web/client/src/layout/containers/layout/index.jsx

@ -90,9 +90,7 @@ const LayoutContainer = props => {
}}> }}>
<video <video
autoPlay loop muted autoPlay loop muted
style={{ style={{}}
// width: "100%", objectFit: "cover", objectPosition: 'left top', height: 'calc(100vh - 4px)'
}}
src="/assets/video/cross_loading.mp4" src="/assets/video/cross_loading.mp4"
type="video/mp4" type="video/mp4"
/> />

8
code/VideoAccess-VCMP/web/client/src/layout/index.jsx

@ -83,7 +83,7 @@ const Root = props => {
} }
} }
useEffect(() => { useEffect(async () => {
let innerRoutes = [] let innerRoutes = []
let outerRoutes = [] let outerRoutes = []
let reducers = {} let reducers = {}
@ -126,8 +126,8 @@ const Root = props => {
store.dispatch(resize(document.body.clientHeight, document.body.clientWidth)); store.dispatch(resize(document.body.clientHeight, document.body.clientWidth));
store.dispatch(actions.auth.initAuth()); store.dispatch(actions.auth.initAuth());
store.dispatch(initWebSocket({})) store.dispatch(initWebSocket({}))
store.dispatch(initApiRoot()) const resourceRoot = await store.dispatch(initApiRoot())
console.log(resourceRoot);
const combineRoutes = flatRoutes(innerRoutes); const combineRoutes = flatRoutes(innerRoutes);
setInnerRoutes(combineRoutes) setInnerRoutes(combineRoutes)
@ -163,7 +163,7 @@ const Root = props => {
setAuthCrossLoading(false) setAuthCrossLoading(false)
}); });
setAuthCrossLoading(false) // setAuthCrossLoading(false)
}, []) }, [])
return ( return (

6
code/VideoAccess-VCMP/web/client/src/sections/auth/actions/auth.js

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import { ApiTable, AuthRequest } from '$utils' import { ApiTable, AxyRequest } from '$utils'
export const INIT_AUTH = 'INIT_AUTH'; export const INIT_AUTH = 'INIT_AUTH';
export function initAuth (userData) { export function initAuth (userData) {
@ -42,7 +42,7 @@ export function login (username, password) {
// }, // },
// }); // });
return AuthRequest.post(ApiTable.login, { username, password }) return AxyRequest.post(ApiTable.login, { username, password, domain: 'anxinyun' })
.then(user => { .then(user => {
sessionStorage.setItem('user', JSON.stringify(user)); sessionStorage.setItem('user', JSON.stringify(user));
return dispatch({ return dispatch({
@ -64,7 +64,7 @@ export function login (username, password) {
export const LOGOUT = 'LOGOUT'; export const LOGOUT = 'LOGOUT';
export function logout () { export function logout () {
const user = JSON.parse(sessionStorage.getItem('user')) const user = JSON.parse(sessionStorage.getItem('user'))
AuthRequest.put(ApiTable.logout, { AxyRequest.post(ApiTable.logout, {
token: user.token token: user.token
}); });
sessionStorage.removeItem('user'); sessionStorage.removeItem('user');

7
code/VideoAccess-VCMP/web/client/src/sections/auth/containers/login.jsx

@ -48,9 +48,10 @@ const Login = props => {
width: 446, width: 446,
height: 348, height: 348,
padding: '45px 60px', padding: '45px 60px',
backgroundImage: "url('/assets/images/background/loginbg.png')", // backgroundImage: "url('/assets/images/background/loginbg.png')",
backgroundSize: '100% 100%', // backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat', // backgroundRepeat: 'no-repeat',
background: 'linear-gradient(rgba(255,255,255,1),rgba(255,255,255,.3))',
position: 'absolute', position: 'absolute',
top: '33.89%', top: '33.89%',
right: '16.43%', right: '16.43%',

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

@ -717,7 +717,7 @@ const CameraHeader = (props) => {
"" ""
)} )}
{ {
// <VideoPlayModal visible={true} /> <VideoPlayModal visible={true} />
} }
</> </>
); );

3
code/VideoAccess-VCMP/web/client/src/utils/index.js

@ -1,7 +1,7 @@
'use strict'; 'use strict';
import { isAuthorized } from './func'; import { isAuthorized } from './func';
import { AuthorizationCode } from './authCode'; import { AuthorizationCode } from './authCode';
import { ApiTable, RouteTable, AuthRequest } from './webapi' import { ApiTable, RouteTable, AuthRequest, AxyRequest } from './webapi'
export { export {
isAuthorized, isAuthorized,
@ -11,4 +11,5 @@ export {
ApiTable, ApiTable,
RouteTable, RouteTable,
AuthRequest, AuthRequest,
AxyRequest,
} }

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

@ -2,38 +2,39 @@
import { ProxyRequest } from "@peace/utils"; import { ProxyRequest } from "@peace/utils";
export const AuthRequest = new ProxyRequest("_auth"); export const AuthRequest = new ProxyRequest("_auth");
export const AxyRequest = new ProxyRequest("_axy");
export const ApiTable = { export const ApiTable = {
login: "login", login: "login",
logout: "logout", logout: "logout",
getEnterprisesMembers: "enterprises/{enterpriseId}/members", getEnterprisesMembers: "enterprises/{enterpriseId}/members",
getNvr: "nvr", getNvr: "nvr",
getVender: "vender", getVender: "vender",
nvr: "nvr", nvr: "nvr",
delNvr: "nvr/{nvrId}", delNvr: "nvr/{nvrId}",
getNvrDetails: "nvr/detail/{nvrId}", //获取nvr详情 getNvrDetails: "nvr/detail/{nvrId}", //获取nvr详情
getExport: "camera/export", //nvr表格数据导出 getExport: "camera/export", //nvr表格数据导出
getCheck:"nvr/verify", //校验nvr信息 getCheck: "nvr/verify", //校验nvr信息
getCamera: "camera/project", // 获取摄像头列表 getCamera: "camera/project", // 获取摄像头列表
putForbidden: "camera/banned", //禁用摄像头 putForbidden: "camera/banned", //禁用摄像头
delCamera:"camera/{cameraId}", //删除摄像头 delCamera: "camera/{cameraId}", //删除摄像头
getCameraDetails: "camera/{cameraId}/detail", //获取摄像头详情 getCameraDetails: "camera/{cameraId}/detail", //获取摄像头详情
getCameraKind: "camera/kind", //获取摄像头种类列表 getCameraKind: "camera/kind", //获取摄像头种类列表
getAbility: "/camera/ability", //获取摄像头能力列表 getAbility: "/camera/ability", //获取摄像头能力列表
postCameraYingshi: "camera/create/yingshi", //创建萤石摄像头 postCameraYingshi: "camera/create/yingshi", //创建萤石摄像头
postCameraIpc: "camera/create/ipc", //创建IPC摄像头 postCameraIpc: "camera/create/ipc", //创建IPC摄像头
getVideoStreaming:"camera/nvr_stream", //获取NVR视频流 getVideoStreaming: "camera/nvr_stream", //获取NVR视频流
postCameraNvr:"camera/create/nvr", //记录NVR摄像头 postCameraNvr: "camera/create/nvr", //记录NVR摄像头
getCascadeSIP:"camera/sip_list/cascade", //获取级联摄像头sip列表 getCascadeSIP: "camera/sip_list/cascade", //获取级联摄像头sip列表
postAddCascade:"camera/create/cascade" , //添加级联摄像头 postAddCascade: "camera/create/cascade", //添加级联摄像头
}; };
export const RouteTable = { export const RouteTable = {
apiRoot: "/api/root", apiRoot: "/api/root",
fileUpload: "/_upload/new", fileUpload: "/_upload/new",
cleanUpUploadTrash: "/_upload/cleanup", cleanUpUploadTrash: "/_upload/cleanup",
}; };

145
code/VideoAccess-VCMP/web/config.js

@ -13,87 +13,98 @@ dev && console.log('\x1B[33m%s\x1b[0m', '请遵循并及时更新 readme.md,
args.option(['p', 'port'], '启动端口'); args.option(['p', 'port'], '启动端口');
args.option(['u', 'api-url'], 'webapi的URL'); args.option(['u', 'api-url'], 'webapi的URL');
args.option('apiAuthUrl', 'IOT 鉴权 api'); args.option('apiAuthUrl', 'IOT 鉴权 api');
args.option('apiAnxinyunUrl', '安心云 api');
args.option('iotAuthWeb', 'IOT 鉴权 web');
const flags = args.parse(process.argv); const flags = args.parse(process.argv);
const API_URL = process.env.API_URL || flags.apiUrl; const API_URL = process.env.API_URL || flags.apiUrl;
const API_AUTH_URL = process.env.API_AUTH_URL || flags.apiAuthUrl; const API_AUTH_URL = process.env.API_AUTH_URL || flags.apiAuthUrl;
const IOT_AUTH_WEB = process.env.IOT_AUTH_WEB || flags.iotAuthWeb;
const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.apiAnxinyunUrl;
if (!API_URL) { if (!API_URL || !API_ANXINYUN_URL || !API_AUTH_URL) {
console.log('缺少启动参数,异常退出'); console.log('缺少启动参数,异常退出');
args.showHelp(); args.showHelp();
process.exit(-1); process.exit(-1);
} }
const product = { const product = {
port: flags.port || 8080, port: flags.port || 8080,
staticDirs: [path.join(__dirname, './client')], staticDirs: [path.join(__dirname, './client')],
mws: [{ mws: [{
entry: require('./middlewares/proxy').entry, entry: require('./middlewares/proxy').entry,
opts: { opts: {
host: API_URL, host: API_URL,
match: /^\/_api\//, match: /^\/_api\//,
} }
}, { }, {
entry: require('./middlewares/proxy').entry, entry: require('./middlewares/proxy').entry,
opts: { opts: {
host: API_AUTH_URL, host: API_AUTH_URL,
match: /^\/_auth\//, match: /^\/_auth\//,
} }
}, { }, {
entry: require('./routes').entry, entry: require('./middlewares/proxy').entry,
opts: { opts: {
apiUrl: API_URL, host: API_ANXINYUN_URL,
staticRoot: './client', match: /^\/_axy\//,
} }
}, { }, {
entry: require('./client').entry,// 静态信息 entry: require('./routes').entry,
opts: {} opts: {
}], apiUrl: API_URL,
logger: { iotAuthWeb: IOT_AUTH_WEB,
level: 'debug', staticRoot: './client',
json: false, }
filename: path.join(__dirname, 'log', 'runtime.txt'), }, {
colorize: true, entry: require('./client').entry,// 静态信息
maxsize: 1024 * 1024 * 5, opts: {}
rotationFormat: false, }],
zippedArchive: true, logger: {
maxFiles: 10, level: 'debug',
prettyPrint: true, json: false,
label: '', filename: path.join(__dirname, 'log', 'runtime.txt'),
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'), colorize: true,
eol: os.EOL, maxsize: 1024 * 1024 * 5,
tailable: true, rotationFormat: false,
depth: null, zippedArchive: true,
showLevel: true, maxFiles: 10,
maxRetries: 1 prettyPrint: true,
} label: '',
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'),
eol: os.EOL,
tailable: true,
depth: null,
showLevel: true,
maxRetries: 1
}
}; };
let config; let config;
if (dev) { if (dev) {
config = { config = {
port: product.port, port: product.port,
staticDirs: product.staticDirs, staticDirs: product.staticDirs,
mws: product.mws mws: product.mws
.concat([ .concat([
vite ? vite ?
{ {
entry: require('./middlewares/vite-dev').entry, entry: require('./middlewares/vite-dev').entry,
opts: {} opts: {}
} }
: :
{ {
entry: require('./middlewares/webpack-dev').entry, entry: require('./middlewares/webpack-dev').entry,
opts: {} opts: {}
} }
]) ])
, ,
logger: product.logger logger: product.logger
} }
config.logger.filename = path.join(__dirname, 'log', 'development.txt'); config.logger.filename = path.join(__dirname, 'log', 'development.txt');
} else { } else {
config = product; config = product;
} }
module.exports = config;//区分开发和发布 module.exports = config;//区分开发和发布

2
code/VideoAccess-VCMP/web/package.json

@ -7,7 +7,7 @@
"test": "mocha", "test": "mocha",
"start-vite": "cross-env NODE_ENV=developmentVite npm run start-params", "start-vite": "cross-env NODE_ENV=developmentVite npm run start-params",
"start": "cross-env NODE_ENV=development npm run start-params", "start": "cross-env NODE_ENV=development npm run start-params",
"start-params": "node server -p 5000 -u http://10.8.30.7:4000 --apiAuthUrl http://10.8.30.7:4200", "start-params": "node server -p 5000 -u http://10.8.30.7:4000 --apiAuthUrl http://10.8.30.7:4200 --apiAnxinyunUrl http://10.8.30.7:4100 --iotAuthWeb http://localhost:5200",
"deploy": "export NODE_ENV=production&& npm run build && node server", "deploy": "export NODE_ENV=production&& npm run build && node server",
"build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js", "build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js",
"build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js" "build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js"

151
code/VideoAccess-VCMP/web/routes/attachment/index.js

@ -5,88 +5,91 @@ const path = require('path')
const fs = require('fs'); const fs = require('fs');
const ext = { const ext = {
project: [".txt", ".dwg", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".png", ".jpg", ".svg"], project: [".txt", ".dwg", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".png", ".jpg", ".svg"],
report: [".doc", ".docx", ".xls", ".xlsx", ".pdf"], report: [".doc", ".docx", ".xls", ".xlsx", ".pdf"],
data: [".txt", ".xls", ".xlsx"], data: [".txt", ".xls", ".xlsx"],
image: [".png", ".jpg", ".svg"], image: [".png", ".jpg", ".svg"],
three: [".js"], three: [".js"],
video: [".mp4"], video: [".mp4"],
bpmn: [".bpmn", ".bpmn20.xml", ".zip", ".bar"], bpmn: [".bpmn", ".bpmn20.xml", ".zip", ".bar"],
app: [".apk"] app: [".apk"]
} }
module.exports = { module.exports = {
entry: function (app, router, opts) { entry: function (app, router, opts) {
const getApiRoot = async function (ctx) { const getApiRoot = async function (ctx) {
const { apiUrl } = opts; const { apiUrl, iotAuthWeb } = opts;
ctx.status = 200; ctx.status = 200;
ctx.body = { root: apiUrl }; ctx.body = {
}; root: apiUrl,
iotAuthWeb
let upload = async function (ctx, next) { };
try { };
const { files } = await parse(ctx.req);
const file = files[0];
const extname = path.extname(file.filename).toLowerCase();
const fileType = ctx.query.type || "image";
const fileFolder = ctx.query.fileFolder || 'common';
if (ext[fileType].indexOf(extname) < 0) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'UploadFailed', message: '文件格式无效' });
return;
}
const date = new Date().toLocaleDateString();
const time = new Date().getTime();
let fileName = time + '_' + file.filename;
let saveFile = path.join(__dirname, '../../', `/client/assets/files/${fileFolder}`, fileName);
const pathUrl = `./client/assets/files/${fileFolder}`;
const res1 = fs.existsSync(`./client/assets/files/${fileFolder}`); let upload = async function (ctx, next) {
!res1 && fs.mkdirSync(`./client/assets/files/${fileFolder}`); try {
const res = fs.existsSync(pathUrl); const { files } = await parse(ctx.req);
!res && fs.mkdirSync(pathUrl); const file = files[0];
let stream = fs.createWriteStream(saveFile); const extname = path.extname(file.filename).toLowerCase();
fs.createReadStream(file.path).pipe(stream); const fileType = ctx.query.type || "image";
stream.on('error', function (err) { const fileFolder = ctx.query.fileFolder || 'common';
app.fs.logger.log('error', '[Upload Heatmap]', err); if (ext[fileType].indexOf(extname) < 0) {
}); ctx.status = 400;
ctx.status = 200; ctx.body = JSON.stringify({ name: 'UploadFailed', message: '文件格式无效' });
ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' }; return;
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload error.' };
} }
} const date = new Date().toLocaleDateString();
const time = new Date().getTime();
let fileName = time + '_' + file.filename;
let saveFile = path.join(__dirname, '../../', `/client/assets/files/${fileFolder}`, fileName);
const pathUrl = `./client/assets/files/${fileFolder}`;
let remove = async function (ctx, next) { const res1 = fs.existsSync(`./client/assets/files/${fileFolder}`);
try { !res1 && fs.mkdirSync(`./client/assets/files/${fileFolder}`);
const fkeys = ctx.request.body; const res = fs.existsSync(pathUrl);
let removeUrl = path.join(__dirname, '../../', './client', fkeys.url); !res && fs.mkdirSync(pathUrl);
const res = fs.existsSync(removeUrl); let stream = fs.createWriteStream(saveFile);
if (!res) { fs.createReadStream(file.path).pipe(stream);
ctx.status = 400; stream.on('error', function (err) {
ctx.body = JSON.stringify({ name: 'DeleteFailed', message: '文件地址不存在' }); app.fs.logger.log('error', '[Upload Heatmap]', err);
return; });
} ctx.status = 200;
fs.unlink(removeUrl, function (error) { ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' };
if (error) { } catch (err) {
console.log(error); ctx.status = 500;
} ctx.fs.logger.error(err);
}) ctx.body = { err: 'upload error.' };
ctx.status = 200; }
ctx.body = { name: 'DeleteSuccess.', message: '删除成功' }; }
} catch (err) {
ctx.status = 500; let remove = async function (ctx, next) {
ctx.fs.logger.error(err); try {
ctx.body = { err: 'upload cleanup error.' }; const fkeys = ctx.request.body;
let removeUrl = path.join(__dirname, '../../', './client', fkeys.url);
const res = fs.existsSync(removeUrl);
if (!res) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'DeleteFailed', message: '文件地址不存在' });
return;
} }
} fs.unlink(removeUrl, function (error) {
if (error) {
console.log(error);
}
})
ctx.status = 200;
ctx.body = { name: 'DeleteSuccess.', message: '删除成功' };
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload cleanup error.' };
}
}
router.get('/api/root', getApiRoot); router.get('/api/root', getApiRoot);
router.post('/_upload/new', upload); router.post('/_upload/new', upload);
router.delete('/_upload/cleanup', remove); router.delete('/_upload/cleanup', remove);
} }
}; };

Loading…
Cancel
Save