peng.peng 1 year ago
parent
commit
f9ab13b203
  1. 6
      api/app/lib/controllers/auth/index.js
  2. 8
      api/app/lib/controllers/member/index.js
  3. 39
      api/app/lib/controllers/superScreen/community.js
  4. 1
      api/app/lib/middlewares/authenticator.js
  5. 3
      api/app/lib/routes/superScreen/community.js
  6. 1
      api/package.json
  7. BIN
      super-screen/client/assets/images/homepage/communtity/arrow_right.png
  8. BIN
      super-screen/client/assets/images/homepage/communtity/notice.png
  9. 102
      super-screen/client/src/sections/community-safty/components/city-safty.js
  10. 42
      super-screen/client/src/sections/community-safty/components/style.less
  11. 8
      web/client/src/layout/components/header/index.js
  12. 4
      web/client/src/sections/auth/containers/login.js

6
api/app/lib/controllers/auth/index.js

@ -2,6 +2,7 @@
const Hex = require('crypto-js/enc-hex');
const SHA1 = require('crypto-js/sha1');
const MD5 = require('crypto-js/md5');
const CryptoJS = require('crypto-js');
const moment = require('moment');
const uuid = require('uuid');
@ -11,10 +12,11 @@ async function login (ctx, next) {
const models = ctx.fs.dc.models;
const params = ctx.request.body;
let userRes = null
if (params.username && params.password) {
const password = Hex.stringify(MD5(params.password));
const secretKey = 'freesun';
const decryptedPassword = CryptoJS.AES.decrypt(params.password, secretKey).toString(CryptoJS.enc.Utf8);
const password = Hex.stringify(MD5(decryptedPassword));
userRes = await models.User.findOne({
attributes: { exclude: ['password'] },
where: {

8
api/app/lib/controllers/member/index.js

@ -1,6 +1,7 @@
'use strict';
const Hex = require('crypto-js/enc-hex');
const MD5 = require('crypto-js/md5');
const CryptoJS = require('crypto-js');
function getUserList(opts) {
return async function (ctx, next) {
@ -83,14 +84,17 @@ function editUser(opts) {
const { id } = ctx.params;
const body = ctx.request.body;
if (body.oldpassword) {
const password = Hex.stringify(MD5(body.oldpassword));
const secretKey = 'freesun';
const decryptedOldPassword = CryptoJS.AES.decrypt(body.oldpassword, secretKey).toString(CryptoJS.enc.Utf8);
const decryptedPassword = CryptoJS.AES.decrypt(body.password, secretKey).toString(CryptoJS.enc.Utf8);
const password = Hex.stringify(MD5(decryptedOldPassword));
const checkPwd = await models.User.findOne({ where: { id: id, password } });
if (!checkPwd) {
ctx.status = 400;
ctx.body = { message: '旧密码错误' }
} else {
await models.User.update(
{ password: Hex.stringify(MD5(body.password)) },
{ password: Hex.stringify(MD5(decryptedPassword)) },
{ where: { id: id, } }
)
ctx.status = 204;

39
api/app/lib/controllers/superScreen/community.js

@ -1,4 +1,6 @@
'use strict';
const request = require("superagent");
const cheerio = require('cheerio');
function getPersonAge(opts) {
return async function (ctx, next) {
@ -145,9 +147,44 @@ function getHomeInfo(opts) {
}
}
function getFgjvNotice(opts) {
return async function (ctx, next) {
let errMsg = { message: '获取房管局通知失败' }
try {
let rslt = [];
const res = await request.get('https://www.nc.gov.cn/ncszf/fgjv/2021_nav_list.shtml');
const $ = cheerio.load(res.text);
$('div.pageList-line ul').children('li').each(function (i, elem) {
if (i >= 5) return false;
let obj = {};
const a = $(this).find('a');
obj.title = a.text();
obj.time = $(this).find('span').text();
obj.link = 'https://www.nc.gov.cn' + a.attr('href');
rslt.push(obj);
});
const promistArr = rslt.map(obj => request.get(obj.link));
const detailRes = await Promise.all(promistArr);
for (let i = 0; i < rslt.length; i++) {
const detail$ = cheerio.load(detailRes[i].text);
const temp = detail$('ucapcontent').text().trim().substring(0, 50).replace(/\n/g, "");
rslt[i].detail = temp;
}
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = errMsg
}
}
}
module.exports = {
getPersonAge,
getHomePerson,
getHomeInfo
getHomeInfo,
getFgjvNotice
}

1
api/app/lib/middlewares/authenticator.js

@ -73,6 +73,7 @@ let isPathExcluded = function (opts, path, method) {
excludeOpts.push({ p: '/person/age', o: 'GET' });
excludeOpts.push({ p: '/home/person', o: 'GET' });
excludeOpts.push({ p: '/community/info', o: 'GET' });
excludeOpts.push({ p: '/community/fgjv/notice', o: 'GET' });
excludes = new ExcludesUrls(excludeOpts);
}

3
api/app/lib/routes/superScreen/community.js

@ -16,4 +16,7 @@ module.exports = function (app, router, opts, AuthCode) {
app.fs.api.logAttr['GET/community/info'] = { content: '获取社区房屋统计信息', visible: true };
router.get('/community/info', community.getHomeInfo(opts));
//获取房管局通知
app.fs.api.logAttr['GET/community/fgjv/notice'] = { content: '获取房管局通知', visible: true };
router.get('/community/fgjv/notice', community.getFgjvNotice(opts));
};

1
api/package.json

@ -18,6 +18,7 @@
"ali-oss": "^6.17.1",
"args": "^3.0.7",
"better-xlsx": "^0.7.6",
"cheerio": "^1.0.0-rc.12",
"clickhouse": "^2.6.0",
"crypto-js": "^4.0.0",
"diskinfo": "0.0.3",

BIN
super-screen/client/assets/images/homepage/communtity/arrow_right.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
super-screen/client/assets/images/homepage/communtity/notice.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

102
super-screen/client/src/sections/community-safty/components/city-safty.js

@ -8,60 +8,88 @@ import './style.less';
function CitySafty(props) {
const { waterLevelAlarms } = props;
const { data: fireAlarms = [] } = useFsRequest({ url: ApiTable.getFireAlarmList });
// const { data: fireAlarms = [] } = useFsRequest({ url: ApiTable.getFireAlarmList });
const getContent = () => {
return <div className='_city_safty'>
{fireAlarms.map(s => {
const handled = s?.state == 2
return <div className={handled ? 'alarm_handle' : 'alarm_unhandle'}>
<div className='handle_img' />
<div className='alarm_content'>
<div className='alarm_bg'>
<div className='alarm_title1'>{moment(s.createTime).format('YYYY-MM-DD HH:mm:ss')}</div>
<div className='alarm_title2' style={{ color: handled ? '#FFF' : '#24DCF7' }}>{handled ? '已处理' : '处理中'}</div>
</div>
<div className='alarm_text'>
<div>
<Tooltip title={s?.location}>
<div className='alarm_title1'>事件地点: {s?.location?.length > 20 ? s?.location.substring(0, 20) + '...' : s?.location}</div>
</Tooltip>
</div>
<div className='alarm_title1'>警情类型: {s?.type}</div>
</div>
</div>
</div>
})}
const { data: fgjvNoticeList = [] } = useFsRequest({ url: 'community/fgjv/notice' });
</div>
}
// const getContent = () => {
// return <div className='_city_safty'>
// {fireAlarms.map(s => {
// const handled = s?.state == 2
// return <div className={handled ? 'alarm_handle' : 'alarm_unhandle'}>
// <div className='handle_img' />
// <div className='alarm_content'>
// <div className='alarm_bg'>
// <div className='alarm_title1'>{moment(s.createTime).format('YYYY-MM-DD HH:mm:ss')}</div>
// <div className='alarm_title2' style={{ color: handled ? '#FFF' : '#24DCF7' }}>{handled ? '已处理' : '处理中'}</div>
// </div>
// <div className='alarm_text'>
// <div>
// <Tooltip title={s?.location}>
// <div className='alarm_title1'>事件地点: {s?.location?.length > 20 ? s?.location.substring(0, 20) + '...' : s?.location}</div>
// </Tooltip>
// </div>
// <div className='alarm_title1'>警情类型: {s?.type}</div>
// </div>
// </div>
// </div>
// })}
const renderList = () => <div className='_city_safty'>
// </div>
// }
// const renderList = () => <div className='_city_safty'>
// {
// waterLevelAlarms?.map(a => <div className={a.alarms[0]?.state >= 3 ? 'alarm_handle' : 'alarm_unhandle'}>
// <div className='handle_img' />
// <div className='alarm_content'>
// <div className='alarm_bg'>
// <Tooltip title={a.alarms[0]?.source?.name}>
// <div className='alarm_title1'>{a.alarms[0]?.source?.name}</div>
// </Tooltip>
// <div className='alarm_title2' style={{ color: a.alarms[0]?.state >= 3 ? '#FFEA00' : '#FF2C2C' }}>{convertLevelToLabel(a.alarms[0]?.level)}</div>
// </div>
// <div className='alarm_text'>{a.alarms[0]?.content}</div>
// </div>
// </div>)
// }
// </div>
const renderFgjvList = () => <div className='_city_safty'>
{
waterLevelAlarms?.map(a => <div className={a.alarms[0]?.state >= 3 ? 'alarm_handle' : 'alarm_unhandle'}>
<div className='handle_img' />
<div className='alarm_content'>
fgjvNoticeList?.map(n => <div className={'notice_list'}>
<div className='notice_img' />
<div className='notice_content'>
<div className='alarm_bg'>
<Tooltip title={a.alarms[0]?.source?.name}>
<div className='alarm_title1'>{a.alarms[0]?.source?.name}</div>
<Tooltip title={n.title}>
<div className='alarm_title1'>{n.title}</div>
</Tooltip>
<div className='alarm_title2' style={{ color: a.alarms[0]?.state >= 3 ? '#FFEA00' : '#FF2C2C' }}>{convertLevelToLabel(a.alarms[0]?.level)}</div>
<div
className='alarm_title2 pointer'
style={{ color: '#09D5FF' }}
onClick={() => { window.open(n.link) }}
>
去查看<img className='arrow' src='/assets/images/homepage/communtity/arrow_right.png' />
</div>
</div>
<div className='alarm_text'>{a.alarms[0]?.content}</div>
<div className='notice_text'>{n.detail}</div>
</div>
</div>)
}
</div>
const dataSource = fireAlarms.concat(waterLevelAlarms || [])
// const dataSource = fireAlarms.concat(waterLevelAlarms || [])
const dataSource = fgjvNoticeList
return <Box title={"城市安全"} >
return <Box title={"政务信息查看"} >
{
dataSource?.length > 0 ? <AutoRollComponent
canScroll={dataSource?.length > 2}
content={<>
{renderList()}
{getContent()}
{/* {renderList()} */}
{/* {getContent()} */}
{renderFgjvList()}
</>}
divHeight={240}
divId={`community-right-top`} />

42
super-screen/client/src/sections/community-safty/components/style.less

@ -483,5 +483,47 @@
color: #FFFFFF;
letter-spacing: 0;
}
.arrow {
display: inline-block;
margin-left: 2px;
width: 10px;
height: 10px;
}
}
.notice_list {
display: flex;
height: 89px;
margin-bottom: 20px;
.notice_img {
width: 101px;
height: 89px;
background: url('/assets/images/homepage/communtity/notice.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.notice_content {
width: calc(100% - 120px);
display: flex;
flex-direction: column;
justify-content: center;
.notice_text {
padding-left: 16px;
padding-right: 16px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; // 控制多行的行数
-webkit-box-orient: vertical;
}
}
}
.pointer {
cursor: pointer;
}
}

8
web/client/src/layout/components/header/index.js

@ -3,6 +3,7 @@ import React from 'react';
import { Menu } from 'antd';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import CryptoJS from 'crypto-js';
import styles from './style.css';
import {
MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined
@ -12,7 +13,12 @@ const Header = props => {
const { dispatch, history, user, pathname, toggleCollapsed, collapsed, actions } = props
const onFinish = async (values) => {
const dataToSave = { ...values }
const secretKey = "freesun";
const dataToSave = {
...values,
oldpassword: CryptoJS.AES.encrypt(values.oldpassword, secretKey).toString(),
password: CryptoJS.AES.encrypt(values.password, secretKey).toString(),
}
return dispatch(
actions.memberManagement.modifyUser(user.id, dataToSave, values?.msg || ''),
).then((res) => {

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

@ -4,6 +4,7 @@ import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import SHA1 from 'crypto-js/sha1';
import Hex from 'crypto-js/enc-hex';
import CryptoJS from 'crypto-js';
import { ApiTable } from '$utils'
import { Request } from '@peace/utils'
import { Button, Input, Form, Row, Col, message, Tabs } from 'antd';
@ -72,7 +73,8 @@ const Login = props => {
payload: { error: '请输入账号名和密码' }
});
setInputChanged(false)
dispatch(login({ username, password }));
const secretKey = "freesun";
dispatch(login({ username, password: CryptoJS.AES.encrypt(password, secretKey).toString() }));
} else {
if (!phone || !code)
dispatch({

Loading…
Cancel
Save