Browse Source

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

release_0.0.1
wenlele 3 years ago
parent
commit
1d6877ce2d
  1. 10
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  2. 4
      code/VideoAccess-VCMP/api/app/lib/index.js
  3. 40
      code/VideoAccess-VCMP/api/app/lib/models/ax_project.js
  4. 25
      code/VideoAccess-VCMP/api/app/lib/service/socket.js
  5. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/loginBackground.png
  6. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/loginbg.png
  7. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/password.png
  8. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/username.png
  9. 2
      code/VideoAccess-VCMP/web/client/src/app.jsx
  10. 5
      code/VideoAccess-VCMP/web/client/src/layout/actions/global.js
  11. 9
      code/VideoAccess-VCMP/web/client/src/layout/actions/index.js
  12. 33
      code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js
  13. 10
      code/VideoAccess-VCMP/web/client/src/layout/components/header/index.jsx
  14. 5
      code/VideoAccess-VCMP/web/client/src/layout/index.jsx
  15. 15
      code/VideoAccess-VCMP/web/client/src/layout/reducers/global.js
  16. 4
      code/VideoAccess-VCMP/web/client/src/layout/reducers/index.js
  17. 21
      code/VideoAccess-VCMP/web/client/src/layout/reducers/webSocket.js
  18. 4
      code/VideoAccess-VCMP/web/client/src/sections/auth/actions/auth.js
  19. 5
      code/VideoAccess-VCMP/web/client/src/sections/auth/actions/index.js
  20. 61
      code/VideoAccess-VCMP/web/client/src/sections/auth/containers/login.jsx
  21. 7
      code/VideoAccess-VCMP/web/client/src/sections/auth/style.less
  22. 3
      code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx
  23. 19
      code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx
  24. 8
      code/VideoAccess-VCMP/web/package.json

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

@ -46,8 +46,12 @@ async function edit (ctx, next) {
async function get (ctx) {
const models = ctx.fs.dc.models;
try {
const { limit, offset, orderBy, orderDirection } = ctx.query
const { limit, page, orderBy, orderDirection } = ctx.query
let findOption = {
attributes: { exclude: ['delete'] },
where: {
delete: false,
},
order: [
[orderBy || 'id', orderDirection || 'DESC']
]
@ -55,8 +59,8 @@ async function get (ctx) {
if (limit) {
findOption.limit = limit
}
if (offset) {
findOption.offset = offset
if (page && limit) {
findOption.offset = page * limit
}
const res = await models.Nvr.findAll(findOption)

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

@ -2,6 +2,7 @@
const routes = require('./routes');
const redisConnect = require('./service/redis')
const socketConect = require('./service/socket')
const authenticator = require('./middlewares/authenticator');
// const apiLog = require('./middlewares/api-log');
const businessRest = require('./middlewares/business-rest');
@ -13,7 +14,9 @@ module.exports.entry = function (app, router, opts) {
app.fs.api.authAttr = app.fs.api.authAttr || {};
app.fs.api.logAttr = app.fs.api.logAttr || {};
// 顺序固定 ↓
redisConnect(app, opts)
socketConect(app, opts)
router.use(authenticator(app, opts));
// router.use(businessRest(app, router, opts));
@ -28,4 +31,5 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
require('./models/camera')(dc);
require('./models/nvr')(dc);
require('./models/vender')(dc);
require('./models/ax_project')(dc);
};

40
code/VideoAccess-VCMP/api/app/lib/models/ax_project.js

@ -0,0 +1,40 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const AxProject = sequelize.define("axProject", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: false,
unique: "ax_project_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
}
}, {
tableName: "ax_project",
comment: "",
indexes: []
});
const Nvr = dc.models.Nvr;
// Nvr.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
// User.hasMany(Nvr, { foreignKey: 'userId', sourceKey: 'id' });
dc.models.AxProject = AxProject;
return AxProject;
};

25
code/VideoAccess-VCMP/api/app/lib/service/socket.js

@ -0,0 +1,25 @@
'use strict';
module.exports = async function factory (app, opts) {
app.socket.on('connection', async (socket) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已连接:' + socket.id);
socket.on('disconnecting', async (reason) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已断开连接:' + reason);
})
})
// 使用测试 保持链接
// setInterval(async () => {
// // const { connected } = app.socket.sockets
// // const roomId = 'ROOM_' + Math.random()
// // if (connected) {
// // for (let c in connected) {
// // connected[c].join(roomId)
// // }
// // app.socket.to(roomId).emit('TEST', { someProperty: `【星域 ROOM:${roomId}】呼叫自然选择号!!!`, })
// // }
// app.socket.emit('TEST', { someProperty: '【广播】呼叫青铜时代号!!!', })
// }, 1000)
}

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/loginBackground.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/loginbg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/password.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/username.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

2
code/VideoAccess-VCMP/web/client/src/app.jsx

@ -3,7 +3,7 @@
import React, { useEffect } from 'react';
import Layout from './layout';
import Auth from './sections/auth';
// import Example from './sections/example';
import Example from './sections/example';
import EquipmentWarehouse from './sections/equipmentWarehouse';
const App = props => {

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

@ -2,8 +2,6 @@
import { RouteRequest } from '@peace/utils';
import { RouteTable } from '$utils'
// import io from 'socket.io-client';
export const INIT_LAYOUT = 'INIT_LAYOUT';
export function initLayout (title, copyright, sections, actions) {
return {
@ -35,9 +33,6 @@ export function initApiRoot () {
return dispatch => {
RouteRequest.get(RouteTable.apiRoot).then(res => {
localStorage.setItem('apiRoot', res.root);
// const socket = io('ws://127.0.0.1:4000', () => { });
dispatch({
type: INIT_API_ROOT,
payload: {

9
code/VideoAccess-VCMP/web/client/src/layout/actions/index.js

@ -0,0 +1,9 @@
'use strict';
import * as global from './global'
import * as socket from './webSocket';
export default {
...global,
...socket,
};

33
code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js

@ -0,0 +1,33 @@
'use strict';
import io from 'socket.io-client';
export const INIT_WEB_SOCKET = 'INIT_WEB_SOCKET'
export function initWebSocket ({ ioUrl, token }) {
if (!ioUrl) {
ioUrl = localStorage.getItem('apiRoot')
}
if (!token) {
const user = sessionStorage.getItem('user')
if (user) {
token = JSON.parse(user).token
}
}
if (!ioUrl || !token) {
return {
type: '',
}
}
return dispatch => {
const socket = io(ioUrl, {
query: {
token: token
},
});
dispatch({
type: INIT_WEB_SOCKET,
payload: {
socket: socket
}
})
}
}

10
code/VideoAccess-VCMP/web/client/src/layout/components/header/index.jsx

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { Nav } from '@douyinfe/semi-ui';
const Header = props => {
const { dispatch, history, user, actions } = props
const { dispatch, history, user, actions, socket } = props
return (
<div style={{ position: 'relative', height: 60, minWidth: 520 }}>
@ -20,6 +20,9 @@ const Header = props => {
<Nav mode={'horizontal'} onClick={({ itemKey }) => {
if (itemKey == 'logout') {
dispatch(actions.auth.logout(user));
if (socket) {
socket.disconnect()
}
history.push(`/signin`);
}
}}>
@ -33,10 +36,11 @@ const Header = props => {
};
function mapStateToProps (state) {
const { global, auth } = state;
const { global, auth, webSocket } = state;
return {
actions: global.actions,
user: auth.user
user: auth.user,
socket: webSocket.socket
};
}

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

@ -8,14 +8,14 @@ import { ConnectedRouter } from 'connected-react-router'
import { Layout, NoMatch } from './containers';
import { Switch, Route } from "react-router-dom";
import { ConfigProvider } from '@douyinfe/semi-ui';
import * as layoutActions from './actions/global';
import layoutActions from './actions';
import zhCN from '@douyinfe/semi-ui/lib/es/locale/source/zh_CN';
import { basicReducer } from '@peace/utils';
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
const { initLayout, initApiRoot, resize } = layoutActions;
const { initLayout, initApiRoot, resize, initWebSocket } = layoutActions;
const Root = props => {
const { sections, title, copyright } = props;
@ -124,6 +124,7 @@ const Root = props => {
store.dispatch(initLayout(title, copyright, sections, actions));
store.dispatch(resize(document.body.clientHeight, document.body.clientWidth));
store.dispatch(actions.auth.initAuth());
store.dispatch(initWebSocket({}))
store.dispatch(initApiRoot())
const combineRoutes = flatRoutes(innerRoutes);

15
code/VideoAccess-VCMP/web/client/src/layout/reducers/global.js

@ -1,6 +1,6 @@
'use strict';
import Immutable from 'immutable';
import { INIT_LAYOUT, RESIZE } from '../actions/global';
import { INIT_LAYOUT, RESIZE, INIT_API_ROOT } from '../actions/global';
function global (state = {
title: '',
@ -9,7 +9,8 @@ function global (state = {
actions: {},
plugins: {},
clientHeight: 768,
clientWidth: 1024
clientWidth: 1024,
apiRoot: '',
}, action) {
const payload = action.payload;
switch (action.type) {
@ -19,15 +20,17 @@ function global (state = {
clientWidth: payload.clientWidth
}).toJS();
case INIT_LAYOUT:
return {
return Immutable.fromJS(state).merge({
title: payload.title,
copyright: payload.copyright,
sections: payload.sections,
actions: payload.actions,
plugins: payload.plugins,
clientHeight: state.clientHeight,
detailsComponent: null
};
}).toJS();
case INIT_API_ROOT:
return Immutable.fromJS(state).merge({
apiRoot: payload.apiRoot,
}).toJS();
default:
return state;
}

4
code/VideoAccess-VCMP/web/client/src/layout/reducers/index.js

@ -7,9 +7,11 @@
'use strict';
import global from './global';
import webSocket from './webSocket'
import ajaxResponse from './ajaxResponse';
export default {
global,
ajaxResponse
webSocket,
ajaxResponse,
};

21
code/VideoAccess-VCMP/web/client/src/layout/reducers/webSocket.js

@ -0,0 +1,21 @@
'use strict';
import * as actionTypes from '../actions/webSocket';
import Immutable from 'immutable';
const initState = {
socket: null,
};
function webSocket (state = initState, action) {
const payload = action.payload;
switch (action.type) {
case actionTypes.INIT_WEB_SOCKET:
return Immutable.fromJS(state).merge({
socket: payload.socket,
}).toJS();
default:
return state;
}
}
export default webSocket;

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

@ -41,13 +41,13 @@ export function login (username, password) {
return AuthRequest.post(ApiTable.login, { username, password })
.then(user => {
sessionStorage.setItem('user', JSON.stringify(user));
dispatch({
return dispatch({
type: LOGIN_SUCCESS,
payload: { user: user },
});
}, error => {
let { body } = error.response;
dispatch({
return dispatch({
type: LOGIN_ERROR,
payload: {
error: body && body.message ? body.message : '登录失败'

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

@ -1,8 +1,5 @@
/**
* Created by liu.xinyi
* on 2016/4/1.
*/
'use strict';
import auth from './auth';
export default {

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

@ -3,10 +3,12 @@ import React, { useEffect, useRef } from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { Form, Button, Toast } from '@douyinfe/semi-ui';
import { login } from '../actions/auth';
import { login, LOGIN_SUCCESS } from '../actions/auth';
import { IconLock,IconUser } from '@douyinfe/semi-icons';
import '../style.less'
const Login = props => {
const { dispatch, user, error, isRequesting } = props
const { dispatch, user, error, actions, apiRoot, isRequesting } = props
const form = useRef();
useEffect(() => {
@ -25,25 +27,54 @@ const Login = props => {
return (
<div style={{
height: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundImage:"url('/assets/images/background/loginBackground.png')",
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
position: 'relative',
}}>
<div style={{
width: 400,
height: 410,
padding: 30,
width: 446,
height: 348,
padding: '45px 60px',
backgroundImage:"url('/assets/images/background/loginbg.png')",
backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat',
position: 'absolute',
top: '33.89%',
right: '16.43%',
}}>
<p style={{ fontSize: 21, fontWeight: 'bold', textAlign: 'center' }}>飞尚物联</p>
<div style={{width:113,height:24,marginTop:3,marginLeft:5}}>
<img src="/assets/images/background/user_login.png" alt="" style={{width:'100%',height:'100%'}}/>
</div>
<Form
onSubmit={values => {
dispatch(login(values.username, values.password))
dispatch(login(values.username, values.password)).then(res => {
const data = res.payload.user
dispatch(actions.layout.initWebSocket({ ioUrl: apiRoot, token: data.token }))
})
}}
getFormApi={formApi => form.current = formApi}
>
<Form.Input field='username' label='用户名' />
<Form.Input field='password' mode="password" autoComplete="" label='密码' />
<Button htmlType='submit' block theme="solid" >登录</Button>
<Form.Input
className='inputbgc'
field='username'
noLabel={true}
label='用户名'
placeholder='请输入账号'
prefix={<IconUser style={{color:'#1859C1',marginRight:14,marginLeft:8}}/>}
style={{background:'rgba(24, 89, 193, 0.08)',height:40,marginTop:26}}
/>
<Form.Input
field='password'
noLabel={true}
mode="password"
autoComplete=""
placeholder='请输入密码'
label='密码'
prefix={<IconLock style={{color:'#1859C1',marginRight:14,marginLeft:8}}/>}
style={{background:'rgba(24, 89, 193, 0.08)',height:40}}
/>
<Button htmlType='submit' block theme="solid" style={{marginTop:17,height:40,backgroundColor:'#1859C1'}}>立即登录</Button>
</Form>
</div>
</div>
@ -51,10 +82,12 @@ const Login = props => {
}
function mapStateToProps (state) {
const { auth } = state;
const { auth, global } = state;
return {
user: auth.user,
error: auth.error,
actions: global.actions,
apiRoot: global.apiRoot,
isRequesting: auth.isRequesting
}
}

7
code/VideoAccess-VCMP/web/client/src/sections/auth/style.less

@ -0,0 +1,7 @@
input:-webkit-autofill{
-webkit-text-fill-color:black !important;
-webkit-box-shadow: 0 0 0px 1000px transparent inset !important;
box-shadow: 0 0 0px 1000px transparent inset !important;
background-color:transparent;
transition: background-color 50000s ease-in-out 0s;
}

3
code/VideoAccess-VCMP/web/client/src/sections/equipmentWarehouse/components/nvrModal.jsx

@ -6,7 +6,6 @@ function nvrModal(props){
const {modalName}=props
const { dispatch, actions, user, loading,vender,close } = props;
const nvrData = props.nvrData||{}//
// console.log('nvrDatanvrDatanvrData',nvrData);
const form = useRef();
const [visible, setVisible] = useState(false);//
const [isloading,setloading] = useState(false);//loading
@ -52,7 +51,6 @@ function nvrModal(props){
if(nvrData.id){
valuesObj.id=nvrData.id
}
console.log('valuesObjvaluesObj',valuesObj);
setformObj(valuesObj)
setloading(true);
setTimeout(() => {
@ -71,7 +69,6 @@ function nvrModal(props){
.catch(errors=>{//
console.log('errors',errors);
})
}
else{
dispatch(actions.equipmentWarehouse.addchangeNvr(formObj)).then(res => {

19
code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx

@ -5,13 +5,25 @@ import '../style.less'
const { Meta } = Card;
const Example = (props) => {
const { dispatch, actions, user, loading } = props
const { dispatch, actions, user, loading, socket } = props
useEffect(() => {
// ACTION
dispatch(actions.example.getMembers(user.orgId))
}, [])
// websocket 使
useEffect(() => {
if (socket) {
socket.on('TEST', function (msg) {
console.info(msg);
});
return () => {
socket.off("TEST");
}
}
}, [socket])
return (
<Spin tip="biubiubiu~" spinning={loading}>
<div id='example'>
@ -33,12 +45,13 @@ const Example = (props) => {
}
function mapStateToProps (state) {
const { auth, global, members } = state;
const { auth, global, members, webSocket } = state;
return {
loading: members.isRequesting,
user: auth.user,
actions: global.actions,
members: members.data
members: members.data,
socket: webSocket.socket
};
}

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

@ -44,10 +44,12 @@
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"style-loader": "^2.0.0",
"vite": "^2.9.5",
"webpack": "^5.3.2",
"webpack-bundle-analyzer": "^4.1.0",
"webpack-cli": "^4.2.0",
"webpack-dev-middleware": "^4.0.2",
"webpack-dev-server": "^3.11.2",
"webpack-hot-middleware": "^2.25.0"
},
"dependencies": {
@ -66,8 +68,8 @@
"moment": "^2.22.0",
"npm": "^7.20.6",
"perfect-scrollbar": "^1.5.5",
"superagent": "^6.1.0",
"vite": "^2.9.5",
"webpack-dev-server": "^3.11.2"
"socket.io-client": "^4.5.0",
"socket.io-parser": "^4.2.0",
"superagent": "^6.1.0"
}
}

Loading…
Cancel
Save