Browse Source

添加首页模块

master
dengyinhuan 2 years ago
parent
commit
91fbc45086
  1. 64
      api/app/lib/controllers/patrolManage/yujingguanli.js
  2. 11
      api/app/lib/routes/patrolManage/yujingguanli.js
  3. 2
      api/config.js
  4. 1
      script/1.0.4/schema/4.updata_patrol_record_issue__handle.sql
  5. 3
      web/client/src/app.js
  6. 1
      web/client/src/sections/auth/containers/login.js
  7. 2
      web/client/src/sections/patrolManage/actions/index.js
  8. 13
      web/client/src/sections/patrolManage/actions/yujingguanli.js
  9. 45
      web/client/src/sections/patrolManage/components/xiafagaojin.js
  10. 44
      web/client/src/sections/patrolManage/containers/yujingguanli.js
  11. 4
      web/client/src/sections/patrolManage/nav-item.js
  12. 9
      web/client/src/sections/shouye/actions/index.js
  13. 9
      web/client/src/sections/shouye/containers/index.js
  14. 62
      web/client/src/sections/shouye/containers/shouye.js
  15. 15
      web/client/src/sections/shouye/index.js
  16. 21
      web/client/src/sections/shouye/nav-item.js
  17. 5
      web/client/src/sections/shouye/reducers/index.js
  18. 32
      web/client/src/sections/shouye/routes.js
  19. 20
      web/client/src/sections/shouye/style.less
  20. 1
      web/client/src/utils/webapi.js

64
api/app/lib/controllers/patrolManage/yujingguanli.js

@ -0,0 +1,64 @@
'use strict';
async function varfiyCode(ctx) {
try {
const { models } = ctx.fs.dc;
const { pushBySms, pushByEmail } = ctx.app.fs.utils
const { phone, type ,email} = ctx.request.body
// 伪造的请求可能由相同的sig参数组成
// const checkSigUsed = await models.PhoneValidateCode.findOne({
// where: { sig: sig }
// });
// if (checkSigUsed) {
// throw '参数错误!'
// }
// // 验证sig正确性
// const checkSig = Hex.stringify(SHA1(phone + r));
// if (!r || !sig || sig != checkSig) {
// throw '参数错误!'
// }
let varifyCode = ''
for (let i = 0; i < 6; i++) {
varifyCode += Math.floor(Math.random() * 10)
}
if(type.includes(1)){
await pushBySms({
phone: phone,
templateCode: 'SMS_261950020',
templateParam: {
code: varifyCode
},
})
}
if(type.includes(2)){
await pushByEmail({
email: email,
title: '测试',
text:'你知道吗'
})
}
// await models.PhoneValidateCode.create({
// phone: phone,
// code: varifyCode,
// sig: sig,
// expired: moment().add(10, 'minutes').format('YYYY-MM-DD HH:mm:ss')
// })
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : '获取验证码失败'
}
}
}
module.exports = {
varfiyCode,
// pushByEmail
}

11
api/app/lib/routes/patrolManage/yujingguanli.js

@ -0,0 +1,11 @@
'use strict';
const yujingguanli = require('../../controllers/patrolManage/yujingguanli');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/yujingguanli'] = { content: '下发预警邮件', visible: true };
router.post('/yujingguanli', yujingguanli.varfiyCode);
};

2
api/config.js

@ -94,7 +94,7 @@ const product = {
host: 'smtp.exmail.qq.com',
port: 465,
sender: {
name: '中鼎服务',
name: '运维服务',
address: 'fsiot@free-sun.com.cn',
password: 'Fs2689'
}

1
script/1.0.4/schema/4.updata_patrol_record_issue__handle.sql

@ -1,4 +1,5 @@
ALTER TABLE patrol_record_issue_handle ADD yanshoushijian timestamp(6);
ALTER TABLE patrol_record_issue_handle ADD yanshoucishu integer;
ALTER TABLE patrol_record_issue_handle ADD yujingshijian timestamp(6);
ALTER TABLE patrol_record_issue_handle ADD yujingafchishu integer;
ALTER TABLE patrol_record_issue_handle ADD isgaojing bool;

3
web/client/src/app.js

@ -8,6 +8,7 @@ import ProjectRegime from './sections/projectRegime';
import Organization from './sections/organization';
import PatrolManage from './sections/patrolManage';
import IssueHandle from './sections/issueHandle'
import Shouye from './sections/shouye';
import { Func } from '$utils';
const App = props => {
const { projectName } = props
@ -19,7 +20,7 @@ const App = props => {
return (
<Layout
title={projectName}
sections={[Auth, ProjectRegime, Safetymanage, Organization, PatrolManage, IssueHandle]}
sections={[Auth,Shouye, ProjectRegime, Safetymanage, Organization, PatrolManage, IssueHandle]}
/>
)

1
web/client/src/sections/auth/containers/login.js

@ -31,6 +31,7 @@ const Login = props => {
const [form] = Form.useForm();
const tourl = () => {
return '/shouye'
if (Func.isAuthorized("STRU_INFO_CONFIG")) {
return '/projectRegime/information'
}

2
web/client/src/sections/patrolManage/actions/index.js

@ -5,6 +5,7 @@ import * as record from './record'
import * as report from './report'
import * as template from './template'
import * as checkItems from './checkItems'
import * as yujingguanli from './yujingguanli'
export default {
...plan,
@ -12,4 +13,5 @@ export default {
...report,
...template,
...checkItems,
...yujingguanli
}

13
web/client/src/sections/patrolManage/actions/yujingguanli.js

@ -0,0 +1,13 @@
import { basicAction } from '@peace/utils'
import { ApiTable } from '$utils'
export function putxinxi (data) {
return dispatch => basicAction({
type: 'post',
data,
dispatch: dispatch,
actionType: 'PUT_XINXI',
url: ApiTable.yujingguanli,
msg: { option: '发送信息' },
});
}

45
web/client/src/sections/patrolManage/components/xiafagaojin.js

@ -2,15 +2,17 @@ import { Button, Form, Input, Modal, Select, DatePicker,Checkbox } from 'antd';
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template';
import {putxinxi} from '../actions/yujingguanli'
import moment from 'moment';
const { RangePicker } = DatePicker;
const { TextArea } = Input;
const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, checkItemsGroup }) => {
const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, checkItemsGroup,userlist }) => {
const [form] = Form.useForm();
const shigutypes = [{value:1,label: '邮件告警'},
{value:2,label:'短信告警'}]
console.log(userlist,'userlist')
return (
<Modal
visible={visible}
@ -25,31 +27,16 @@ const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, che
form
.validateFields()
.then((values) => {
const params = {
...values,
}
if (type === 'create') {
dispatch(createPatrolTemplate(params)).then(res => {
if (res.success) {
tableRef.current.reload();
form.resetFields();
onCancel();
}
})
} else {
dispatch(updatePatrolTemplate({
...params,
id: curRecord.id
})).then(res => {
if (res.success) {
tableRef.current.reload();
form.resetFields();
onCancel();
}
console.log('user,',userlist)
let usedata = userlist.filter(i=>i?.username===values.name)
console.log(usedata,'usedata')
dispatch(putxinxi({phone:[params.name],email:[usedata[0]?.email],type:params.type})).then(res=>{
console.log(res,'res')
})
}
console.log(params,'params')
})
.catch((info) => {
console.log('Validate Failed:', info);
@ -60,22 +47,20 @@ const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, che
form={form}
// layout="vertical"
name="form_in_modal"
initialValues={{
...curRecord,
checkItems: curRecord?.checkItems?.map(c => c.id)
}}
labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} offe
labelCol={{ span: 5 }} wrapperCol={{ span: 19 }}
>
<Form.Item
name="name"
label="告警接收人"
rules={[
{ required: true, message: '请输入告警接收人' },
{ required: true, message: '请输入用户账号' },
]}
>
<Input />
<Select options={userlist?.map(i=>({value:i?.username,label:i?.name}))}></Select>
</Form.Item>
<Form.Item label="告警方式">
<Form.Item label="告警方式"
name="type">
<Checkbox.Group options={shigutypes}/>
</Form.Item>
</Form>

44
web/client/src/sections/patrolManage/containers/yujingguanli.js

@ -3,11 +3,12 @@ import { connect } from 'react-redux';
import { Button, Popconfirm, Tag,Tabs } from 'antd';
import ProTable from '@ant-design/pro-table';
import Xiafagaojin from '../components/xiafagaojin';
import {getDepUser} from '../../organization/actions/user'
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template';
import { getCheckItemsGroup } from '../actions/checkItems';
import moment from 'moment';
function YujingGuanli (props) {
const { dispatch, user,actions } = props;
const { dispatch, user,actions,depUser} = props;
const tableRef = useRef();
const format = 'YYYY-MM-DD HH:mm:ss'
const { patrolManage } = actions
@ -35,29 +36,30 @@ function YujingGuanli (props) {
if (res.success) {
console.log(res,'水平')
let obj = {}
res?.payload?.data?.map(i=>{
if(obj[i?.points?.project?.id]){
// if(obj[i?.points?.project?.id.toString()][i.pointId.toString()]){
// obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=obj[i?.points?.project?.id.toString()][i.pointId.toString()].num+i?.patrolRecordIssueHandles[0]?.state==6?1:0
// res?.payload?.data?.map(i=>{
// if(obj[i?.points?.project?.id]){
// // if(obj[i?.points?.project?.id.toString()][i.pointId.toString()]){
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=obj[i?.points?.project?.id.toString()][i.pointId.toString()].num+i?.patrolRecordIssueHandles[0]?.state==6?1:0
// // }else{
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=i?.patrolRecordIssueHandles[0]?.state==6?1:0
// // }
// obj[i?.points?.project?.id]?.push({pointId:i.pointId,pointname:i.points.itemData.name})
// // i?patrolRecordIssueHandles[0]?.state==6
// obj[i?.points?.project?.id].num= obj[i?.points?.project?.id].num + i?.patrolRecordIssueHandles[0]?.state==6 ?1:0
// }else{
// obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=i?.patrolRecordIssueHandles[0]?.state==6?1:0
// }
obj[i?.points?.project?.id].push({pointId:i.pointId,pointname:i.points.itemData.name})
// i?patrolRecordIssueHandles[0]?.state==6
obj[i?.points?.project?.id].num= obj[i?.points?.project?.id].num + i?.patrolRecordIssueHandles[0]?.state==6 ?1:0
}else{
obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:i?.patrolRecordIssueHandles[0]?.state==6 ?1:0 }
// obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:i?.patrolRecordIssueHandles[0]?.state==6 ?1:0 }
}
console.log(obj,'obj')
})
// }
// console.log(obj,'obj')
// })
}
})
}
console.log(depUser,'depUser')
useEffect(() => {
// dispatch(patrolManage.records(`patrolRecord/all/null/null/true/null`)).then(res=>{
// let obj = {}
@ -81,7 +83,7 @@ function YujingGuanli (props) {
// console.log(obj,'obj')
// console.log(res,'res')
// })
dispatch(getDepUser())
queryData()
dispatch(getCheckItemsGroup())
}, [])
@ -187,11 +189,12 @@ console.log(tableList,'tablist')
]}
/>
{
visible ?
visible &&depUser.filter(i=>i.username&&i.email).length!==0 ?
<Xiafagaojin
visible={visible}
type={type}
curRecord={curRecord}
userlist={depUser.filter(i=>i.username&&i.email)}
onCancel={() => {
setVisible(false);
setCurRecord({})
@ -204,10 +207,11 @@ console.log(tableList,'tablist')
}
function mapStateToProps (state) {
const { auth, global } = state
const { auth, global ,depUser} = state
return {
user: auth.user,
actions: global.actions,
depUser: depUser.data || [],
}
}
export default connect(mapStateToProps)(YujingGuanli);

4
web/client/src/sections/patrolManage/nav-item.js

@ -26,9 +26,9 @@ export function getNavItem (user, dispatch) {
{Func.isAuthorized('CHECKMOULD') && <Menu.Item key="patrolTemplate">
<Link to="/patrolManage/patrolTemplate">巡检模板</Link>
</Menu.Item>}
{/* { <Menu.Item key="yujingguanli">
{ <Menu.Item key="yujingguanli">
<Link to="/patrolManage/yujingguanli">预警管理</Link>
</Menu.Item>} */}
</Menu.Item>}
</SubMenu>
);
}

9
web/client/src/sections/shouye/actions/index.js

@ -0,0 +1,9 @@
'use strict';
export default {
}

9
web/client/src/sections/shouye/containers/index.js

@ -0,0 +1,9 @@
'use strict';
import Shouye from './shouye'
export { Shouye };

62
web/client/src/sections/shouye/containers/shouye.js

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Spin, Card, Form, Input, Select, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
import moment from "moment";
import '../style.less';
import { push } from 'react-router-redux';
import { Model } from 'echarts';
const Information = (props) => {
const { dispatch, actions, user, loading } = props
const topdata =[]
return (
<>
<div className='shouyetop'>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
</div>
</>
)
}
function mapStateToProps (state) {
const { auth, global } = state;
return {
user: auth.user,
actions: global.actions,
};
}
export default connect(mapStateToProps)(Information);

15
web/client/src/sections/shouye/index.js

@ -0,0 +1,15 @@
'use strict';
import reducers from './reducers';
import routes from './routes';
import actions from './actions';
import { getNavItem } from './nav-item';
export default {
key: 'shouye',
name: '首页',
reducers: reducers,
routes: routes,
actions: actions,
getNavItem: getNavItem
};

21
web/client/src/sections/shouye/nav-item.js

@ -0,0 +1,21 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Menu } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
import { Func } from '$utils';
const SubMenu = Menu.SubMenu;
export function getNavItem (user, dispatch) {
// return <SubMenu key="shouye" icon={<SettingOutlined />} title={'首页'}>
// {/* {Func.isAuthorized('STRU_INFO_CONFIG') &&<Menu.Item key="information">
// <Link to="/projectRegime/information">结构物基础信息管理</Link>
// </Menu.Item>}
// {Func.isAuthorized('QR_CODE_CONFIG') &&<Menu.Item key="qrCode">
// <Link to="/projectRegime/qrCode">二维码管理</Link>
// </Menu.Item>} */}
// </SubMenu>
return <Menu.Item key="shouye">
<Link to="/shouye">首页</Link>
</Menu.Item>
}

5
web/client/src/sections/shouye/reducers/index.js

@ -0,0 +1,5 @@
'use strict';
export default {
}

32
web/client/src/sections/shouye/routes.js

@ -0,0 +1,32 @@
'use strict';
import { Shouye } from './containers';
export default [{
type: 'inner',
route: {
path: '/shouye',
key: 'shouye',
breadcrumb: '首页',
component: Shouye,
// 不设置 component 则面包屑禁止跳转
// childRoutes: [{
// path: '/information',
// key: 'information',
// breadcrumb: '结构物基础信息管理',
// component: Information,
// childRoutes: [ {
// path: '/:id',
// key: ':id',
// component: Point,
// breadcrumb: '点位',
// },
// ]
// }, {
// path: '/qrCode',
// key: 'qrCode',
// component: QrCode,
// breadcrumb: '二维码管理',
// },
// ]
}
}];

20
web/client/src/sections/shouye/style.less

@ -0,0 +1,20 @@
.shouyetop{
display: flex;
justify-content: space-between;
.shouyetopitem{
width: 25%;
display: flex;
justify-content: space-between;
box-shadow: 0 0 10px #F0F2F5;
border:1px solid #F0F2F5;
color: rgba(0, 0, 0, 0.45);
font-size: 1.875rem;
height: 7.125rem;
.shouyetopitem-left{
width: 50%;
}
.shouyetopitem-right{
width: 50%;
}
}
}

1
web/client/src/utils/webapi.js

@ -64,6 +64,7 @@ export const ApiTable = {
delCheckTask: '/delcheckTask/:id',
addPatrolRecordIssueHandle: 'patrolRecord/issue/handle',
modifyPatrolRecordIssueHandle: 'patrolRecord/issue/handle/{id}',
yujingguanli:'/yujingguanli',
//协调申请
getCoordinateList: 'risk/coordinate',

Loading…
Cancel
Save