Commit f6aec18f authored by 沈翠玲's avatar 沈翠玲

数字大屏

parent 9f733ce0
...@@ -32,3 +32,19 @@ export const getTractRecordDayHoursTotal = (params) => { ...@@ -32,3 +32,19 @@ export const getTractRecordDayHoursTotal = (params) => {
export const getFourFollowTypeTotal = (params) => { export const getFourFollowTypeTotal = (params) => {
return request.get('/mock/getFourFollowTypeTotal', params); return request.get('/mock/getFourFollowTypeTotal', params);
}; };
//
export const getTractRecordFollowRate = (params) => {
return request.get('/mock/getTractRecordFollowRate', params);
};
// 事件类型统计
export const getNetTypeTotal = (params) => {
return request.get('/mock/getNetTypeTotal', params);
};
// AI安全趋势预测
export const getAISecurityTotal = (params) => {
return request.get('/mock/getAISecurityTotal', params);
};
// Ⅲ级安全监测
export const getSecurityTotal = (params) => {
return request.get('/mock/getSecurityTotal', params);
};
\ No newline at end of file
...@@ -9,7 +9,7 @@ export const saveUser = (data) => { ...@@ -9,7 +9,7 @@ export const saveUser = (data) => {
}; };
export const getUserPage = (params) => { export const getUserPage = (params) => {
return request.get('/user/page', params); return request.get('/user/page', params, {cancel: false});
}; };
export const deleteUsers = (ids) => { export const deleteUsers = (ids) => {
......
...@@ -6,14 +6,41 @@ ...@@ -6,14 +6,41 @@
</div> </div>
<div class="flex flex-col items-end justify-center flex-1"> <div class="flex flex-col items-end justify-center flex-1">
<p>安全守护</p> <p>安全守护</p>
<p><span class="green">789</span></p> <p><span class="green">{{datas.securityDays}}</span></p>
<p>成功拦截攻击</p> <p>成功拦截攻击</p>
<p><span class="red">2823</span></p> <p><span class="red">{{datas.interceptAttackDays}}</span></p>
</div> </div>
</div> </div>
</template> </template>
<script setup></script> <script setup>
import { getSecurityTotal } from '@/api/dataScreenMock';
import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
const load = ref(false);
const timer1 = ref();
const datas = ref({});
const query = () => {
load.value = true;
getSecurityTotal().then(res=> {
load.value = false;
if (res.success && res.result && res.result.length) {
datas.value = res.result[0]
}
})
}
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box { .box {
width: 100%; width: 100%;
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
type: 'bar', type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!! xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%', barGap: '-100%',
barWidth: '25%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
show: true, show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值 //label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值 //在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'], position: [0, '-108%'],
rich: { rich: {
//富文本 //富文本
white: { white: {
...@@ -190,7 +190,7 @@ ...@@ -190,7 +190,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -233,7 +233,7 @@ ...@@ -233,7 +233,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '0', //统计条宽度 barWidth: 1, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
type: 'bar', type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!! xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%', barGap: '-100%',
barWidth: '25%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -150,7 +150,7 @@ ...@@ -150,7 +150,7 @@
show: true, show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值 //label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值 //在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'], position: [0, '-108%'],
rich: { rich: {
//富文本 //富文本
white: { white: {
...@@ -177,7 +177,7 @@ ...@@ -177,7 +177,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '0', //统计条宽度 barWidth: 1, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
} else { } else {
const param = {}; const param = {};
if (props.tenant !== '全部') { if (props.tenant !== '全部') {
param['tenantId'] = props.tenant; param['tenant'] = props.tenant;
} }
load.value = true; load.value = true;
getTractRecordDayHoursTotal(param) getTractRecordDayHoursTotal(param)
......
...@@ -8,178 +8,205 @@ ...@@ -8,178 +8,205 @@
<script setup> <script setup>
import ECharts from '@/components/ECharts/index.vue'; import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config'; import echarts from '@/components/ECharts/config';
import { getAISecurityTotal } from '@/api/dataScreenMock';
const option = { import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
tooltip: {}, const load = ref(false);
grid: { const timer1 = ref();
top: '8%', const datas = ref([]);
left: '1%', const query = () => {
right: '1%', load.value = true;
bottom: '1%', getAISecurityTotal().then(res=> {
containLabel: true, load.value = false;
}, if (res.success) {
legend: { datas.value = res.result
itemGap: 50, }
data: ['注册总量', '最新注册量'], })
textStyle: { }
color: '#f9f9f9', onBeforeUnmount(() => {
borderColor: '#fff', if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const option = computed(() => {
return {
tooltip: {},
grid: {
top: '18%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
}, },
}, legend: {
xAxis: [ itemGap: 50,
{ data: ['注册总量', '最新注册量'],
type: 'category', textStyle: {
boundaryGap: true, color: '#f9f9f9',
axisLine: { borderColor: '#fff',
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
}, },
axisLabel: { },
//坐标轴刻度标签的相关设置 xAxis: [
textStyle: { {
color: '#d1e6eb', type: 'category',
margin: 15, boundaryGap: true,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: '#d1e6eb',
margin: 15,
},
},
axisTick: {
show: false,
}, },
data: datas.value.map(v => v.xdata),
}, },
axisTick: { ],
show: false, yAxis: [
{
type: 'value',
min: 0,
// max: 140,
splitNumber: 7,
splitLine: {
show: true,
lineStyle: {
color: '#0a3256',
},
},
axisLine: {
show: false,
},
axisLabel: {
margin: 20,
textStyle: {
color: '#d1e6eb',
},
},
axisTick: {
show: false,
},
}, },
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'], ],
}, series: [
], {
yAxis: [ name: '注册总量',
{ type: 'line',
type: 'value', // smooth: true, //是否平滑曲线显示
min: 0, // symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
// max: 140, showAllSymbol: true,
splitNumber: 7, symbol: 'emptyCircle',
splitLine: { symbolSize: 6,
show: true,
lineStyle: { lineStyle: {
color: '#0a3256', normal: {
color: '#28ffb3', // 线条颜色
},
borderColor: '#f0f',
}, },
}, label: {
axisLine: { show: true,
show: false, position: 'top',
}, textStyle: {
axisLabel: { color: '#fff',
margin: 20, },
textStyle: {
color: '#d1e6eb',
}, },
}, itemStyle: {
axisTick: { normal: {
show: false, color: '#28ffb3',
}, },
},
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
normal: {
color: '#28ffb3', // 线条颜色
}, },
borderColor: '#f0f', tooltip: {
}, show: false,
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
}, },
}, areaStyle: {
itemStyle: { //区域填充样式
normal: { normal: {
color: '#28ffb3', //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(0,154,120,1)',
},
{
offset: 1,
color: 'rgba(0,0,0, 0)',
},
],
false
),
shadowColor: 'rgba(53,142,215, 0.9)', //阴影颜色
shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
},
}, },
data: datas.value.map(v => v.total),
}, },
tooltip: { {
show: false, name: '最新注册量',
}, type: 'bar',
areaStyle: { barWidth: 20,
//区域填充样式 tooltip: {
normal: { show: false,
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(0,154,120,1)',
},
{
offset: 1,
color: 'rgba(0,0,0, 0)',
},
],
false
),
shadowColor: 'rgba(53,142,215, 0.9)', //阴影颜色
shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
}, },
}, label: {
data: [393, 438, 485, 631, 689, 824, 987], show: true,
}, position: 'top',
{ textStyle: {
name: '最新注册量', color: '#fff',
type: 'bar', },
barWidth: 20,
tooltip: {
show: false,
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
}, },
}, itemStyle: {
itemStyle: { normal: {
normal: { // barBorderRadius: 5,
// barBorderRadius: 5, // color: new echarts.graphic.LinearGradient(
// color: new echarts.graphic.LinearGradient( // 0, 0, 0, 1,
// 0, 0, 0, 1, // [{
// [{ // offset: 0,
// offset: 0, // color: '#14c8d4'
// color: '#14c8d4' // },
// }, // {
// { // offset: 1,
// offset: 1, // color: '#43eec6'
// color: '#43eec6' // }
// } // ]
// ] // )
// ) color: function (params) {
color: function (params) { var colorList = [
var colorList = [ '#0ec1ff',
'#0ec1ff', '#10cdff',
'#10cdff', '#12daff',
'#12daff', '#15ebff',
'#15ebff', '#17f8ff',
'#17f8ff', '#1cfffb',
'#1cfffb', '#1dfff1',
'#1dfff1', ];
]; return colorList[params.dataIndex];
return colorList[params.dataIndex]; },
}, },
}, },
data: datas.value.map(v => v.newTotal),
}, },
data: [200, 382, 102, 267, 186, 315, 316], ],
}, };
], });
}; query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.echarts { .echarts {
......
...@@ -5,21 +5,39 @@ ...@@ -5,21 +5,39 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue';
import ECharts from '@/components/ECharts/index.vue'; import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config'; import echarts from '@/components/ECharts/config';
import { getNetTypeTotal } from '@/api/dataScreenMock';
import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
const load = ref(false);
const timer1 = ref();
const datas = ref([]);
var myColor = ['#81E7ED']; var myColor = ['#81E7ED'];
var dataLine = [40, 56, 23, 15, 15]; var positionLeft = 30,
var positionLeft = 20,
max = 100 + positionLeft; max = 100 + positionLeft;
var g_cellBar0_y = var g_cellBar0_y =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC'; 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC';
var g_cellBarImg0_y = new Image(); var g_cellBarImg0_y = new Image();
g_cellBarImg0_y.src = g_cellBar0_y; g_cellBarImg0_y.src = g_cellBar0_y;
const query = () => {
var option = { load.value = true;
getNetTypeTotal().then(res=> {
load.value = false;
if (res.success) {
datas.value = res.result
}
})
}
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const option = computed(() => {
return {
grid: [ grid: [
{ {
left: '0%', left: '0%',
...@@ -48,7 +66,7 @@ ...@@ -48,7 +66,7 @@
}, },
}, },
z: 10, z: 10,
data: ['HTTP', '弱口令破解', 'XSS', 'SQL注入', '暴力破解'], data: datas.value.map(v => v.name),
}, },
{ {
axisTick: 'none', axisTick: 'none',
...@@ -63,7 +81,7 @@ ...@@ -63,7 +81,7 @@
}, },
}, },
z: 10, z: 10,
data: [40, 56, 23, 15, 15], data: datas.value.map(v => v.value),
}, },
{ {
axisLine: { axisLine: {
...@@ -94,7 +112,7 @@ ...@@ -94,7 +112,7 @@
type: 'bar', type: 'bar',
stack: 'b', stack: 'b',
yAxisIndex: 0, yAxisIndex: 0,
data: dataLine, data: datas.value.map(v => v.value),
label: { label: {
normal: { normal: {
show: false, show: false,
...@@ -152,7 +170,7 @@ ...@@ -152,7 +170,7 @@
position: 'right', position: 'right',
distance: 10, distance: 10,
formatter: function (data) { formatter: function (data) {
return dataLine[data.dataIndex] + '%'; return datas.value.map(v => v.value)[data.dataIndex] + '%';
}, },
textStyle: { textStyle: {
color: '#ffffff', color: '#ffffff',
...@@ -172,7 +190,14 @@ ...@@ -172,7 +190,14 @@
z: 0, z: 0,
}, },
], ],
}; };
});
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -6,14 +6,41 @@ ...@@ -6,14 +6,41 @@
</div> </div>
<div class="flex flex-col items-end justify-center flex-1"> <div class="flex flex-col items-end justify-center flex-1">
<p>安全守护</p> <p>安全守护</p>
<p><span class="green">789</span></p> <p><span class="green">{{datas.securityDays}}</span></p>
<p>成功拦截攻击</p> <p>成功拦截攻击</p>
<p><span class="red">2823</span></p> <p><span class="red">{{datas.interceptAttackDays}}</span></p>
</div> </div>
</div> </div>
</template> </template>
<script setup></script> <script setup>
import { getSecurityTotal } from '@/api/dataScreenMock';
import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
const load = ref(false);
const timer1 = ref();
const datas = ref({});
const query = () => {
load.value = true;
getSecurityTotal().then(res=> {
load.value = false;
if (res.success && res.result && res.result.length) {
datas.value = res.result[0]
}
})
}
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box { .box {
width: 100%; width: 100%;
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
type: 'bar', type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!! xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%', barGap: '-100%',
barWidth: '25%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
show: true, show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值 //label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值 //在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'], position: [0, '-108%'],
rich: { rich: {
//富文本 //富文本
white: { white: {
...@@ -190,7 +190,7 @@ ...@@ -190,7 +190,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -233,7 +233,7 @@ ...@@ -233,7 +233,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '0', //统计条宽度 barWidth: 1, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
type: 'bar', type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!! xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%', barGap: '-100%',
barWidth: '25%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -150,7 +150,7 @@ ...@@ -150,7 +150,7 @@
show: true, show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值 //label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值 //在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'], position: [0, '-108%'],
rich: { rich: {
//富文本 //富文本
white: { white: {
...@@ -177,7 +177,7 @@ ...@@ -177,7 +177,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '42%', //统计条宽度 barWidth: 20, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
show: true, show: true,
type: 'bar', type: 'bar',
barGap: '-100%', barGap: '-100%',
barWidth: '0', //统计条宽度 barWidth: 1, //统计条宽度
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 30, barBorderRadius: 30,
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
} else { } else {
const param = {}; const param = {};
if (props.tenant !== '全部') { if (props.tenant !== '全部') {
param['tenantId'] = props.tenant; param['tenant'] = props.tenant;
} }
load.value = true; load.value = true;
getTractRecordDayHoursTotal(param) getTractRecordDayHoursTotal(param)
......
...@@ -8,178 +8,205 @@ ...@@ -8,178 +8,205 @@
<script setup> <script setup>
import ECharts from '@/components/ECharts/index.vue'; import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config'; import echarts from '@/components/ECharts/config';
import { getAISecurityTotal } from '@/api/dataScreenMock';
const option = { import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
tooltip: {}, const load = ref(false);
grid: { const timer1 = ref();
top: '8%', const datas = ref([]);
left: '1%', const query = () => {
right: '1%', load.value = true;
bottom: '1%', getAISecurityTotal().then(res=> {
containLabel: true, load.value = false;
}, if (res.success) {
legend: { datas.value = res.result
itemGap: 50, }
data: ['注册总量', '最新注册量'], })
textStyle: { }
color: '#f9f9f9', onBeforeUnmount(() => {
borderColor: '#fff', if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const option = computed(() => {
return {
tooltip: {},
grid: {
top: '18%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
}, },
}, legend: {
xAxis: [ itemGap: 50,
{ data: ['注册总量', '最新注册量'],
type: 'category', textStyle: {
boundaryGap: true, color: '#f9f9f9',
axisLine: { borderColor: '#fff',
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
}, },
axisLabel: { },
//坐标轴刻度标签的相关设置 xAxis: [
textStyle: { {
color: '#d1e6eb', type: 'category',
margin: 15, boundaryGap: true,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: '#d1e6eb',
margin: 15,
},
},
axisTick: {
show: false,
}, },
data: datas.value.map(v => v.xdata),
}, },
axisTick: { ],
show: false, yAxis: [
{
type: 'value',
min: 0,
// max: 140,
splitNumber: 7,
splitLine: {
show: true,
lineStyle: {
color: '#0a3256',
},
},
axisLine: {
show: false,
},
axisLabel: {
margin: 20,
textStyle: {
color: '#d1e6eb',
},
},
axisTick: {
show: false,
},
}, },
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'], ],
}, series: [
], {
yAxis: [ name: '注册总量',
{ type: 'line',
type: 'value', // smooth: true, //是否平滑曲线显示
min: 0, // symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
// max: 140, showAllSymbol: true,
splitNumber: 7, symbol: 'emptyCircle',
splitLine: { symbolSize: 6,
show: true,
lineStyle: { lineStyle: {
color: '#0a3256', normal: {
color: '#28ffb3', // 线条颜色
},
borderColor: '#f0f',
}, },
}, label: {
axisLine: { show: true,
show: false, position: 'top',
}, textStyle: {
axisLabel: { color: '#fff',
margin: 20, },
textStyle: {
color: '#d1e6eb',
}, },
}, itemStyle: {
axisTick: { normal: {
show: false, color: '#28ffb3',
}, },
},
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
normal: {
color: '#28ffb3', // 线条颜色
}, },
borderColor: '#f0f', tooltip: {
}, show: false,
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
}, },
}, areaStyle: {
itemStyle: { //区域填充样式
normal: { normal: {
color: '#28ffb3', //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(0,154,120,1)',
},
{
offset: 1,
color: 'rgba(0,0,0, 0)',
},
],
false
),
shadowColor: 'rgba(53,142,215, 0.9)', //阴影颜色
shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
},
}, },
data: datas.value.map(v => v.total),
}, },
tooltip: { {
show: false, name: '最新注册量',
}, type: 'bar',
areaStyle: { barWidth: 20,
//区域填充样式 tooltip: {
normal: { show: false,
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(0,154,120,1)',
},
{
offset: 1,
color: 'rgba(0,0,0, 0)',
},
],
false
),
shadowColor: 'rgba(53,142,215, 0.9)', //阴影颜色
shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
}, },
}, label: {
data: [393, 438, 485, 631, 689, 824, 987], show: true,
}, position: 'top',
{ textStyle: {
name: '最新注册量', color: '#fff',
type: 'bar', },
barWidth: 20,
tooltip: {
show: false,
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
}, },
}, itemStyle: {
itemStyle: { normal: {
normal: { // barBorderRadius: 5,
// barBorderRadius: 5, // color: new echarts.graphic.LinearGradient(
// color: new echarts.graphic.LinearGradient( // 0, 0, 0, 1,
// 0, 0, 0, 1, // [{
// [{ // offset: 0,
// offset: 0, // color: '#14c8d4'
// color: '#14c8d4' // },
// }, // {
// { // offset: 1,
// offset: 1, // color: '#43eec6'
// color: '#43eec6' // }
// } // ]
// ] // )
// ) color: function (params) {
color: function (params) { var colorList = [
var colorList = [ '#0ec1ff',
'#0ec1ff', '#10cdff',
'#10cdff', '#12daff',
'#12daff', '#15ebff',
'#15ebff', '#17f8ff',
'#17f8ff', '#1cfffb',
'#1cfffb', '#1dfff1',
'#1dfff1', ];
]; return colorList[params.dataIndex];
return colorList[params.dataIndex]; },
}, },
}, },
data: datas.value.map(v => v.newTotal),
}, },
data: [200, 382, 102, 267, 186, 315, 316], ],
}, };
], });
}; query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.echarts { .echarts {
......
...@@ -5,21 +5,39 @@ ...@@ -5,21 +5,39 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue';
import ECharts from '@/components/ECharts/index.vue'; import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config'; import echarts from '@/components/ECharts/config';
import { getNetTypeTotal } from '@/api/dataScreenMock';
import { reactive, ref, watch, computed, onBeforeUnmount } from 'vue';
const load = ref(false);
const timer1 = ref();
const datas = ref([]);
var myColor = ['#81E7ED']; var myColor = ['#81E7ED'];
var dataLine = [40, 56, 23, 15, 15]; var positionLeft = 30,
var positionLeft = 20,
max = 100 + positionLeft; max = 100 + positionLeft;
var g_cellBar0_y = var g_cellBar0_y =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC'; 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC';
var g_cellBarImg0_y = new Image(); var g_cellBarImg0_y = new Image();
g_cellBarImg0_y.src = g_cellBar0_y; g_cellBarImg0_y.src = g_cellBar0_y;
const query = () => {
var option = { load.value = true;
getNetTypeTotal().then(res=> {
load.value = false;
if (res.success) {
datas.value = res.result
}
})
}
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const option = computed(() => {
return {
grid: [ grid: [
{ {
left: '0%', left: '0%',
...@@ -48,7 +66,7 @@ ...@@ -48,7 +66,7 @@
}, },
}, },
z: 10, z: 10,
data: ['HTTP', '弱口令破解', 'XSS', 'SQL注入', '暴力破解'], data: datas.value.map(v => v.name),
}, },
{ {
axisTick: 'none', axisTick: 'none',
...@@ -63,7 +81,7 @@ ...@@ -63,7 +81,7 @@
}, },
}, },
z: 10, z: 10,
data: [40, 56, 23, 15, 15], data: datas.value.map(v => v.value),
}, },
{ {
axisLine: { axisLine: {
...@@ -94,7 +112,7 @@ ...@@ -94,7 +112,7 @@
type: 'bar', type: 'bar',
stack: 'b', stack: 'b',
yAxisIndex: 0, yAxisIndex: 0,
data: dataLine, data: datas.value.map(v => v.value),
label: { label: {
normal: { normal: {
show: false, show: false,
...@@ -152,7 +170,7 @@ ...@@ -152,7 +170,7 @@
position: 'right', position: 'right',
distance: 10, distance: 10,
formatter: function (data) { formatter: function (data) {
return dataLine[data.dataIndex] + '%'; return datas.value.map(v => v.value)[data.dataIndex] + '%';
}, },
textStyle: { textStyle: {
color: '#ffffff', color: '#ffffff',
...@@ -172,7 +190,14 @@ ...@@ -172,7 +190,14 @@
z: 0, z: 0,
}, },
], ],
}; };
});
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
</div> </div>
<div class="header-ct"> <div class="header-ct">
<div class="header-ct-title"> <div class="header-ct-title">
<span>数字经营看板</span> <span>不良资产综合管理平台</span>
</div> </div>
</div> </div>
<div class="header-ri"> <div class="header-ri">
...@@ -41,20 +41,20 @@ ...@@ -41,20 +41,20 @@
<div class="dataScreen-top"> <div class="dataScreen-top">
<div class="dataScreen-main-title"> <div class="dataScreen-main-title">
<img src="./images/baohu.png" alt="" style="height: 35px" /> <img src="./images/baohu.png" alt="" style="height: 35px" />
Ⅲ级安全监测 三级等保安全监测
</div> </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<AgeRatioChart :isAdmin="isAdmin" :tenantId="tenantId" /> <AgeRatioChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div> </div>
</div> </div>
<div class="dataScreen-center"> <div class="dataScreen-center">
<div class="dataScreen-main-title"> 事件类型统计 </div> <div class="dataScreen-main-title"> 数据安全防护 </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<RealTimeAccessChart :isAdmin="isAdmin" :tenantId="tenantId" /> <RealTimeAccessChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div> </div>
</div> </div>
<div class="dataScreen-bottom"> <div class="dataScreen-bottom">
<div class="dataScreen-main-title"> AI安全趋势预测 </div> <div class="dataScreen-main-title"> 客户注册数据 </div>
<div class="dataScreen-main-chart"> <div class="dataScreen-main-chart">
<PlatformSourceChart :isAdmin="isAdmin" :tenantId="tenantId" /> <PlatformSourceChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div> </div>
...@@ -74,7 +74,6 @@ ...@@ -74,7 +74,6 @@
</div> </div>
</div> </div>
<div class="dataScreen-map" v-else> <div class="dataScreen-map" v-else>
<div class="dataScreen-map-title">当日跟进分析</div>
<MaleFemaleRatioChart :tenantId="tenantId" /> <MaleFemaleRatioChart :tenantId="tenantId" />
</div> </div>
<div class="dataScreen-cb"> <div class="dataScreen-cb">
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
<div class="view-account-form"> <div class="view-account-form">
<el-form ref="formRef" :model="formInline" :rules="rules" size="large"> <el-form ref="formRef" :model="formInline" :rules="rules" size="large">
<el-form-item prop="username"> <el-form-item prop="username">
<el-input v-model="formInline.username" placeholder="Please Input"> <el-input v-model="formInline.username" placeholder="请输入账号">
<template #prefix> <template #prefix>
<el-icon size="20"><User /></el-icon> <el-icon size="20"><User /></el-icon>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input v-model="formInline.password" placeholder="Please Input" :type="passwordType"> <el-input v-model="formInline.password" placeholder="请输入密码" :type="passwordType">
<template #prefix> <template #prefix>
<el-icon size="20"><Lock /></el-icon> <el-icon size="20"><Lock /></el-icon>
</template> </template>
......
...@@ -13,7 +13,18 @@ ...@@ -13,7 +13,18 @@
<el-form ref="ruleFormRef" :model="ruleForm" class="demo-ruleForm" label-width="80px"> <el-form ref="ruleFormRef" :model="ruleForm" class="demo-ruleForm" label-width="80px">
<el-form-item label="收件人:" prop="content"> <el-form-item label="收件人:" prop="content">
<div class="flex items-center w-full"> <div class="flex items-center w-full">
<el-input v-model="ruleForm.username" disabled style="width: 97%" /> <el-select
v-model="ruleForm.userid"
multiple
style="width: 97%"
>
<el-option
v-for="item in ruleForm.receivers"
:key="item.value"
:label="item.username"
:value="item.id"
/>
</el-select>
<el-icon @click="chooseUSER" class="cursor-pointer" style="width: 3%" <el-icon @click="chooseUSER" class="cursor-pointer" style="width: 3%"
><Plus ><Plus
/></el-icon> /></el-icon>
...@@ -64,27 +75,40 @@ ...@@ -64,27 +75,40 @@
const envs = getAppEnvConfig(); const envs = getAppEnvConfig();
const url = envs.VITE_GLOB_API_URL_PREFIX + '/sys/upload'; const url = envs.VITE_GLOB_API_URL_PREFIX + '/sys/upload';
const ruleFormRef = ref(); const ruleFormRef = ref();
const users = ref([]); const current = ref({});
const ruleForm = reactive({ const ruleForm = reactive({
content: '', content: '',
id: '',
title: '', title: '',
receivers: [], receivers: [],
username: '', userid: [],
}); });
const editValue = ref(''); const editValue = ref('');
const hanldeConfirm = (row) => { const hanldeConfirm = (row) => {
ruleForm.receivers = row; // const selects = [...ruleForm.receivers, ...row]
ruleForm.username = row.map((v) => v.username); if (row) {
row.forEach(item => {
const index = ruleForm.receivers.findIndex(v => v.id === item.id)
if (index === -1) {
ruleForm.receivers.push(item)
}
})
}
// ruleForm.receivers = row;
ruleForm.userid = ruleForm.receivers.map((v) => v.id);
}; };
const save = () => { const save = () => {
saveMesage({ saveMesage({
...current.value,
title: ruleForm.title, title: ruleForm.title,
content: ruleForm.content, content: ruleForm.content,
id: ruleForm.id,
status: 'normal', status: 'normal',
messageType: 'system', messageType: 'system',
sendType: 'user', sendType: 'user',
receiversIds: ruleForm.receivers.map((v) => v.id), receiversIds: ruleForm.userid,
}).then((res) => { }).then((res) => {
showModal.value = false; showModal.value = false;
emits('success'); emits('success');
...@@ -98,30 +122,29 @@ ...@@ -98,30 +122,29 @@
ruleForm.content = value; ruleForm.content = value;
}; };
const openModal = (row) => { const openModal = (row) => {
console.log('asdas', row);
if (row) { if (row) {
current.value = row;
ruleForm.content = row.content; ruleForm.content = row.content;
editValue.value = row.content; editValue.value = row.content;
ruleForm.title = row.title; ruleForm.title = row.title;
ruleForm.id = row.id;
ruleForm.receivers = []; ruleForm.receivers = [];
if (row.receiversIds) { if (row.receiversIds) {
row.receiversIds.forEach((element) => { row.receiversIds.forEach((element) => {
console.log('userModalRef.value?.tableData', userModalRef.value?.tableData);
const item = userModalRef.value?.tableData.find((ii) => ii.id === element); const item = userModalRef.value?.tableData.find((ii) => ii.id === element);
console.log('item', item);
if (item) { if (item) {
ruleForm.receivers.push(item); ruleForm.receivers.push(item);
} }
}); });
console.log('ruleForm.receivers', ruleForm.receivers); ruleForm.userid = ruleForm.receivers.map((v) => v.id);
ruleForm.username = ruleForm.receivers.map((v) => v.username).join(',');
} }
} else { } else {
ruleForm.content = ''; ruleForm.content = '';
current.value = {}
editValue.value = ''; editValue.value = '';
ruleForm.title = ''; ruleForm.title = '';
ruleForm.receivers = []; ruleForm.receivers = [];
ruleForm.username = ''; ruleForm.userid = [];
} }
showModal.value = true; showModal.value = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment