提交代码

dev
姜玉琦 2024-06-27 01:14:12 +08:00
parent 689f0ad2a6
commit e68c873e1e
8 changed files with 691 additions and 35 deletions

BIN
public/sxyz.ico 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,25 @@
import request from '@/utils/requestOthers'
const getDict = (dictName) => {
let key = 'dict_' + dictName;
let obj = window.jhcaches[key];
if (obj && obj.length > 0) {
return new Promise((resolve) => {
resolve(obj);
})
} else {
return new Promise(async (resolve) => {
let data = await request({
url: `/publics/aiBox/dicts`,
method: 'get'
});
let obj = data.data || [];
if (obj && obj.length > 0) {
window.jhcaches[key] = obj;
}
resolve(obj);
});
}
}
export default getDict;

View File

@ -0,0 +1,29 @@
import request from '@/utils/requestOthers'
const listView=(deptId,projectId)=> {
return request({
url: `/publics/aiBox/v1/listView?deptId=${deptId||0}&projectId=${projectId||0}&pageSize=20&pageNum=1`,
method: 'get'
})
}
const list=(data,pageNum,pageSize)=> {
return request({
url: `/publics/aiBox/list?pageNum=${pageNum}&pageSize=${pageSize}`,
data:data,
method: 'post'
})
}
const groupCountByAlarmType=(deptId,projectId,now)=> {
return request({
url: `/publics/aiBox/groupCountByAlarmType?deptId=${deptId||0}&projectId=${projectId||0}&now=${now}`,
method: 'get'
})
}
export default{
list,
listView,
groupCountByAlarmType
}

View File

@ -20,6 +20,8 @@ import standard from './standard/index'
import flow from './flow/index'
import video from './video/index'
import aiBoxVideo from './video/aiBoxVideo'
import gzAiBoxVideo from './gzaiBox/index'
import gzDict from './gzaiBox/dict'
import plan from './plan/index'
import periodical from './periodical/index'
import engin from './engin'
@ -51,5 +53,7 @@ export default {
flow,
plan,
downFile:download,
engin
engin,
gzAiBoxVideo,
gzDict
}

View File

@ -1,34 +1,490 @@
<template>
<div>
AI- 广州
<div class="project-aivideo">
<div class="screen-content">
<el-row>
<el-col :span="6">
<module-one-1-1 label="今日预警" style="position: relative">
<!-- <div
style="transform: scale(0.8); position: relative; top: -40px; left: -70px"
> -->
<project-overview-chart
:key="'ai1' + overviewDay"
:sp="''"
txtTop="12"
gifTop="8px"
:maintitle="overviewTotalDay"
:legend-opt="legendOpt1"
:typedata="typeDistributionDataDay"
:text="overviewTextDay"
:width="580"
:height="180"
:fn="changeChart1"
></project-overview-chart>
<!-- </div> -->
</module-one-1-1>
<module-one-2-1 label="预警概况" style="position: relative">
<!-- <div
class="scroll"
style="max-height: 580px; overflow-y: auto; margin-top: 20px"
>
<table class="tb-list1">
<tr>
<th>排名</th>
<th>项目名称</th>
<th>预警数量</th>
<th>预警占比</th>
</tr>
<tr
v-for="(it, idx) in orderList"
:key="idx"
class="tr-cmd"
@click="doStandardDlg(it)"
>
<td>{{ it.ord }}</td>
<td>{{ it.projectName }}</td>
<td>{{ it.value }}</td>
<td>{{ it.percent.toFixed(2) }}%</td>
</tr>
</table>
</div> -->
<project-overview-chart
:key="'ai2' + overview"
:sp="''"
:maintitle="overviewTotal"
:legend-opt="legendOpt2"
:typedata="typeDistributionData"
:text="overviewText"
:width="580"
:height="180"
:fn="changeChart1"
></project-overview-chart>
</module-one-2-1>
</el-col>
<el-col :span="18">
<module-one-1-3 label="今日预警详情" :key="todayKey" style="position: relative">
<div class="today-list ai-list" v-if="todayList.length > 0">
<div v-for="(it, idx) in todayList" :key="idx" class="today-item ai-item">
<div class="item-left">
<el-image
style="width: 180px; height: 100px"
:src="baseUrl + it.imageUrl + '.min.jpg'"
:preview-src-list="[baseUrl + it.imageUrl]"
>
</el-image>
</div>
<div class="item-right">
<div class="item-row">
<div>预警名称:</div>
<div style="color: rgba(1, 169, 255, 1)">{{ it.alarmTypeName }}</div>
</div>
<div class="item-row">
<div>预警时间:</div>
<div style="color: rgba(1, 169, 255, 1)">{{ it.createTime }}</div>
</div>
</div>
</div>
</div>
<el-pagination
v-if="todayList.length > 0"
layout="total,prev, pager, next"
:hide-on-single-page="false"
@current-change="handleTodayCurrentChange"
:total="todayPage.total"
:page-size="todayPage.pageSize"
:current-page.sync="todayPage.pageIndex"
class="bg-pagination"
></el-pagination>
<div
v-if="todayList.length == 0"
style="text-align: center; margin-top: 20px"
>
<img src="images/nodata.png" style="width: 240px" />
<div style="text-align: center">暂无数据</div>
</div>
</module-one-1-3>
<module-one-2-3 label="预警概况明细" style="position: relative">
<div style="position: absolute; right: 0px; top: 4px">
<el-date-picker
class="bg-date-picker"
v-model="selDate"
type="daterange"
popper-class="bg-date-picker-pop"
:editable="false"
@change="dtChange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</div>
<div class="ai-nav">
<div
class="nav-item ai-content-nav-con ai-content-nav"
:class="selType == 0 ? 'active' : ''"
@click="doSelType(0)"
>
全部
</div>
<div
class="nav-item ai-content-nav-con ai-content-nav"
:class="selType == it.dictValue ? 'active' : ''"
@click="doSelType(it.dictValue)"
v-for="(it, idx) in aiTypes"
:key="idx"
>
{{ it.dictLabel }}
</div>
</div>
<div class="data-list">
<div class="ai-list" v-if="listDatas.length > 0">
<div v-for="(it, idx) in listDatas" :key="idx" class="today-item ai-item">
<div class="item-left">
<el-image
style="width: 180px; height: 100px"
:src="baseUrl + it.imageUrl + '.min.jpg'"
:preview-src-list="[baseUrl + it.imageUrl]"
>
</el-image>
</div>
<div class="item-right">
<div class="item-row">
<div>预警名称:</div>
<div style="color: rgba(1, 169, 255, 1)">
{{ it.alarmTypeName }}
</div>
</div>
<div class="item-row">
<div>预警时间:</div>
<div style="color: rgba(1, 169, 255, 1)">{{ it.createTime }}</div>
</div>
</div>
</div>
</div>
<el-pagination
v-if="listDatas.length > 0"
layout="total,prev, pager, next"
:hide-on-single-page="false"
@current-change="handleListCurrentChange"
:total="listPage.total"
:page-size="listPage.pageSize"
:current-page.sync="listPage.pageIndex"
class="bg-pagination"
></el-pagination>
<div
v-if="listDatas.length == 0"
style="text-align: center; margin-top: 100px"
>
<img src="images/nodata.png" style="width: 240px" />
<div style="text-align: center">暂无数据</div>
</div>
</div>
</module-one-2-3>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'JhbigscreenAiGz',
data() {
return {
};
},
mounted() {
document.body.classList.add("no-header");
},
beforeDestroy(){
document.body.classList.remove("no-header");
},
methods: {
},
};
</script>
<style lang="less">
body.no-header{
.main-header{
display: none;
</div>
</template>
<script>
import "../../components/module/module-one-1-3";
import "../../components/module/module-one-2-1";
import "../../components/module/module-one-1-1";
import "../../components/module/module-one-2-3";
import debounce from "lodash.debounce";
export default {
data() {
return {
baseUrl: "http://62.234.3.186:8087/YanZhuGZAI",
//
overview: 0,
overviewDay: 0,
overviewInterval: "",
overviewTotal: 0,
legendOpt1: {
icon: "rect",
textStyle: {
fontSize: 9,
color: "#c3dbfd",
rich: {
name: {
color: "#c3dbfd",
padding: [0, 0, 0, 0],
},
percent: {
color: "#f73647",
},
},
},
},
legendOpt2: {
icon: "rect",
padding: [0, 0, 0, 0],
textStyle: {
fontSize: 9,
color: "#c3dbfd",
rich: {
name: {
color: "#c3dbfd",
padding: [0, 0, 0, 0],
},
percent: {
color: "#4676FD",
},
},
},
},
overviewText: "累计预警",
//
typeDistributionData: [],
overviewTextDay: "今日预警",
overviewTotalDay: 0,
typeDistributionDataDay: [],
orderList: [],
todayPage: {
pageSize: 6,
pageIndex: 1,
total: 0,
},
listPage: {
pageSize: 12,
pageIndex: 1,
total: 0,
},
todayList: [],
todayKey: 0,
listDatas: [],
listKey: 0,
selDate: [],
aiTypes: [],
selType: 0,
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
mounted() {
document.body.classList.add("no-header");
this.$api.gzDict("aibox_alarm_type").then((d) => {
this.aiTypes = d || [];
});
let dt1 = this.$dt(+new Date() - 30 * 24 * 3600 * 1000);
let dt2 = this.$dt(new Date());
this.selDate = [dt1, dt2];
document.title = "广湛高铁文昌隧道AI预警";
document.querySelector('link[rel="icon"]').setAttribute("href", "sxyz.ico");
this.init();
},
beforeDestroy() {
document.body.classList.remove("no-header");
},
methods: {
doSelType(n) {
if (this.selType != n) {
this.selType = n;
this.listPage.pageIndex = 1;
this.loadList();
}
},
dtChange(init) {
this.listPage.pageIndex = 1;
this.loadList();
},
changeChart1(opt) {
opt.title.padding = [60, 0, 0, 145];
return opt;
},
init() {
this.getAiVideoAlertorTypeCount();
//this.groupCountByProject();
this.todayPage.pageIndex = 1;
this.loadTodayList();
this.listPage.pageIndex = 1;
this.selType = 0;
this.loadList();
},
handleTodayCurrentChange(n) {
this.todayPage.pageIndex = n;
this.loadTodayList();
},
handleListCurrentChange(n) {
this.listPage.pageIndex = n;
this.loadList();
},
loadList() {
let postData = {
projectDeptId: 1,
projectId: 1,
params: {
beginTime: this.selDate[0],
endTime: this.selDate[1],
},
};
if (this.selType != 0) {
postData.alarmType = this.selType;
}
this.$api.gzAiBoxVideo
.list(postData, this.listPage.pageIndex, this.listPage.pageSize)
.then((d) => {
this.listPage.total = d.total || 0;
this.listDatas = d.rows || [];
this.listKey++;
});
},
loadTodayList() {
let postData = {
projectDeptId: 1,
projectId: 1,
params: {
date: new Date(),
},
};
this.$api.gzAiBoxVideo
.list(postData, this.todayPage.pageIndex, this.todayPage.pageSize)
.then((d) => {
this.todayPage.total = d.total || 0;
this.todayList = d.rows || [];
this.todayKey++;
});
},
// groupCountByProject() {
// this.$api.gzAiBoxVideo
// .groupCountByProject(0, null)
// .then((d) => {
// let sum = 0;
// let tmps = (d.data || []).map((it, idx) => {
// it.ord = idx + 1;
// it.percent = 0;
// sum += it.value;
// return it;
// });
// tmps.forEach((it) => {
// it.percent = (it.value * 100.0) / sum;
// });
// this.orderList = tmps;
// });
// },
getAiVideoAlertorTypeCount() {
//
this.$api.gzAiBoxVideo.groupCountByAlarmType(1, 1, "Y").then((response) => {
if (response.data) {
let sum = 0;
response.data.forEach((datum) => {
sum += datum.value;
});
this.overviewTotalDay = sum;
this.typeDistributionDataDay = response.data;
this.overviewDay++;
}
});
//
this.$api.gzAiBoxVideo.groupCountByAlarmType(1, 1, "N").then((response) => {
if (response.data) {
let sum = 0;
response.data.forEach((datum) => {
sum += datum.value;
});
this.overviewTotal = sum;
this.typeDistributionData = response.data;
this.overview++;
}
});
},
},
};
</script>
<style lang="less" scope>
body.no-header {
.main-header {
display: none;
}
</style>
}
.project-aivideo {
.chart-overview-gif {
top: 37px !important;
left: 93px;
}
.tb-list1 {
margin: 12px;
width: calc(100% - 24px);
border-collapse: collapse;
border: solid 1px #ffffff52;
th {
font-size: 14px;
border: solid 1px #ffffff52;
line-height: 60px;
}
td {
font-size: 12px;
text-align: center;
border: solid 1px #ffffff52;
line-height: 40px;
}
}
.ai-list {
padding: 0px 24px 8px;
.ai-item {
display: inline-flex;
margin: 12px 12px 0px 0px;
width: calc(33% - 12px);
color: #ccc;
line-height: 24px;
.item-right {
padding-left: 12px;
}
}
}
.data-list {
.ai-list {
.ai-item {
margin-bottom: 8px;
}
}
}
.ai-nav {
padding: 12px;
.nav-item {
display: inline-block;
margin-left: 12px;
text-align: center;
padding: 0px 8px;
&:first-child {
margin-left: 0px;
}
}
}
}
</style>

View File

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/yanZhu_GZAI']
const whiteList = ['/yanZhuGZAI']
router.beforeEach((to, from, next) => {
NProgress.start()

View File

@ -121,9 +121,8 @@ const routes = [
component: () => import(/* webpackChunkName: "video" */ '../pages/photography.vue')
},
{
path: '/yanZhu_GZAI',
name: 'yanZhu_GZAI',
meta:{nav:63,},
path: '/yanZhuGZAI',
name: 'yanZhuGZAI',
component: () => import(/* webpackChunkName: "gzaiBox" */ '../pages/gzaiBox/index.vue')
}
]

View File

@ -0,0 +1,143 @@
import axios from 'axios'
import { Notification, Message, Loading } from 'element-ui'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: "http://62.234.3.186:8087/YanZhuGZAI",
// 超时
timeout: 200000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交';
console.warn("--->",s_data,requestObj.data,s_url)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
Message({ message: "权限不足,请登录后重试!", type: 'error' })
return Promise.reject('error')
} else if (code === 500) {
if(msg.indexOf('重复提交')==-1){
Message({ message: msg, type: 'error' })
}
return Promise.reject(new Error(msg))
} else if (code === 601) {
if(msg.indexOf('重复提交')==-1){
Message({ message: msg, type: 'warning' })
}
return Promise.reject('error')
} else if (code !== 200) {
if(msg.indexOf('重复提交')==-1){
Notification.error({ title: msg })
}
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
if(message.indexOf('重复提交')==-1){
Message({ message: message, type: 'error', duration: 5 * 1000 })
}
return Promise.reject(error)
}
)
// 通用下载方法
export function download(url, params, filename, config={}) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
return axios({
url:url,
method:"get",
params:params||{},
responseType: 'blob',
...config
}).then(async ({data}) => {
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
})
}
export { axios,service}
export default service