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

数字大屏

parent 9f733ce0
......@@ -32,3 +32,19 @@ export const getTractRecordDayHoursTotal = (params) => {
export const 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) => {
};
export const getUserPage = (params) => {
return request.get('/user/page', params);
return request.get('/user/page', params, {cancel: false});
};
export const deleteUsers = (ids) => {
......
......@@ -6,14 +6,41 @@
</div>
<div class="flex flex-col items-end justify-center flex-1">
<p>安全守护</p>
<p><span class="green">789</span></p>
<p><span class="green">{{datas.securityDays}}</span></p>
<p>成功拦截攻击</p>
<p><span class="red">2823</span></p>
<p><span class="red">{{datas.interceptAttackDays}}</span></p>
</div>
</div>
</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>
.box {
width: 100%;
......
......@@ -99,7 +99,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -151,7 +151,7 @@
type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%',
barWidth: '25%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -163,7 +163,7 @@
show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'],
position: [0, '-108%'],
rich: {
//富文本
white: {
......@@ -190,7 +190,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -233,7 +233,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '0', //统计条宽度
barWidth: 1, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......
......@@ -86,7 +86,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -138,7 +138,7 @@
type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%',
barWidth: '25%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -150,7 +150,7 @@
show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'],
position: [0, '-108%'],
rich: {
//富文本
white: {
......@@ -177,7 +177,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -220,7 +220,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '0', //统计条宽度
barWidth: 1, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......
......@@ -55,7 +55,7 @@
} else {
const param = {};
if (props.tenant !== '全部') {
param['tenantId'] = props.tenant;
param['tenant'] = props.tenant;
}
load.value = true;
getTractRecordDayHoursTotal(param)
......
......@@ -8,178 +8,205 @@
<script setup>
import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config';
const option = {
tooltip: {},
grid: {
top: '8%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
},
legend: {
itemGap: 50,
data: ['注册总量', '最新注册量'],
textStyle: {
color: '#f9f9f9',
borderColor: '#fff',
import { getAISecurityTotal } 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;
getAISecurityTotal().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 {
tooltip: {},
grid: {
top: '18%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
},
},
xAxis: [
{
type: 'category',
boundaryGap: true,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
legend: {
itemGap: 50,
data: ['注册总量', '最新注册量'],
textStyle: {
color: '#f9f9f9',
borderColor: '#fff',
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: '#d1e6eb',
margin: 15,
},
xAxis: [
{
type: 'category',
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月'],
},
],
yAxis: [
{
type: 'value',
min: 0,
// max: 140,
splitNumber: 7,
splitLine: {
show: true,
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
color: '#0a3256',
normal: {
color: '#28ffb3', // 线条颜色
},
borderColor: '#f0f',
},
},
axisLine: {
show: false,
},
axisLabel: {
margin: 20,
textStyle: {
color: '#d1e6eb',
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
},
},
},
axisTick: {
show: false,
},
},
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
normal: {
color: '#28ffb3', // 线条颜色
itemStyle: {
normal: {
color: '#28ffb3',
},
},
borderColor: '#f0f',
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
tooltip: {
show: false,
},
},
itemStyle: {
normal: {
color: '#28ffb3',
areaStyle: {
//区域填充样式
normal: {
//线性渐变,前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,
},
areaStyle: {
//区域填充样式
normal: {
//线性渐变,前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, 设置图形的阴影效果。
{
name: '最新注册量',
type: 'bar',
barWidth: 20,
tooltip: {
show: false,
},
},
data: [393, 438, 485, 631, 689, 824, 987],
},
{
name: '最新注册量',
type: 'bar',
barWidth: 20,
tooltip: {
show: false,
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
},
},
},
itemStyle: {
normal: {
// barBorderRadius: 5,
// color: new echarts.graphic.LinearGradient(
// 0, 0, 0, 1,
// [{
// offset: 0,
// color: '#14c8d4'
// },
// {
// offset: 1,
// color: '#43eec6'
// }
// ]
// )
color: function (params) {
var colorList = [
'#0ec1ff',
'#10cdff',
'#12daff',
'#15ebff',
'#17f8ff',
'#1cfffb',
'#1dfff1',
];
return colorList[params.dataIndex];
itemStyle: {
normal: {
// barBorderRadius: 5,
// color: new echarts.graphic.LinearGradient(
// 0, 0, 0, 1,
// [{
// offset: 0,
// color: '#14c8d4'
// },
// {
// offset: 1,
// color: '#43eec6'
// }
// ]
// )
color: function (params) {
var colorList = [
'#0ec1ff',
'#10cdff',
'#12daff',
'#15ebff',
'#17f8ff',
'#1cfffb',
'#1dfff1',
];
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>
<style lang="scss" scoped>
.echarts {
......
......@@ -5,21 +5,39 @@
</template>
<script setup>
import { ref } from 'vue';
import ECharts from '@/components/ECharts/index.vue';
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 dataLine = [40, 56, 23, 15, 15];
var positionLeft = 20,
var positionLeft = 30,
max = 100 + positionLeft;
var g_cellBar0_y =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC';
var g_cellBarImg0_y = new Image();
g_cellBarImg0_y.src = g_cellBar0_y;
var option = {
const query = () => {
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: [
{
left: '0%',
......@@ -48,7 +66,7 @@
},
},
z: 10,
data: ['HTTP', '弱口令破解', 'XSS', 'SQL注入', '暴力破解'],
data: datas.value.map(v => v.name),
},
{
axisTick: 'none',
......@@ -63,7 +81,7 @@
},
},
z: 10,
data: [40, 56, 23, 15, 15],
data: datas.value.map(v => v.value),
},
{
axisLine: {
......@@ -94,7 +112,7 @@
type: 'bar',
stack: 'b',
yAxisIndex: 0,
data: dataLine,
data: datas.value.map(v => v.value),
label: {
normal: {
show: false,
......@@ -152,7 +170,7 @@
position: 'right',
distance: 10,
formatter: function (data) {
return dataLine[data.dataIndex] + '%';
return datas.value.map(v => v.value)[data.dataIndex] + '%';
},
textStyle: {
color: '#ffffff',
......@@ -172,7 +190,14 @@
z: 0,
},
],
};
};
});
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script>
<style lang="scss" scoped>
......
......@@ -5,13 +5,26 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, onBeforeUnmount, computed } from 'vue';
import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config';
const Tenantlist = ref([]);
import { getTenantPage } from '@/api/tenant';
var option = {
import { getTractRecordFollowRate } from '@/api/dataScreenMock';
const load = ref(false);
const treeValue = ref([]);
const timer1 = ref();
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const props = defineProps({
isAdmin: Boolean,
tenantId: [String, Number, Object],
});
var option = computed(() => {
return {
tooltip: {
formatter: '{b}:<br />完成率: {c}%',
},
......@@ -25,321 +38,7 @@
// 注意,最外层是一个数组,而非从某个根节点开始。
{
value: 100,
children: [
{
value: 85, // value字段的值,对应到面积大小。
// 也可以是数组,如 [2323, 43, 55],则数组第一项对应到面积大小。
// 数组其他项可以用于额外的视觉映射,详情参见 series-treemp.levels。
id: 'someid-1', // id 不是必须设置的。
// 但是如果想使用 API 来改变某个节点,需要用 id 来定位。
name: '测试调解中心2', // 显示在矩形中的描述文字。
children: [
{ value: 75, id: 'someid-31', name: '批次1' },
{
value: 80,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 95,
id: 'someid-34',
name: '批次4',
},
{
value: 85,
id: 'someid-31',
name: '批次5',
},
// ...
],
label: {
// 此节点特殊的 label 定义(如果需要的话)。
// ... // label的格式参见 series-treemap.label。
},
itemStyle: {
// 此节点特殊的 itemStyle 定义(如果需要的话)。
// ... // label的格式参见 series-treemap.itemStyle。
},
},
{
value: 80,
id: 'someid-2',
name: '西南调节中心',
children: [
{ value: 85, id: 'someid-31', name: '武汉' },
{
value: 78,
id: 'someid-32',
name: '咸宁',
},
{
value: 90,
id: 'someid-33',
name: '鄂州',
},
{
value: 86,
id: 'someid-34',
name: '荆州',
},
{
value: 85,
id: 'someid-31',
name: '宜昌',
},
// ...
],
},
{
value: 78,
id: 'someid-2',
name: '雄安调解中心',
children: [
{ value: 75, id: 'someid-54', name: '批次1' },
{
value: 85,
id: 'someid-99',
name: '批次2',
},
// ...
],
},
{
value: 89,
id: 'someid-3',
name: '广元调解中心',
children: [
{ value: 94, id: 'someid-31', name: '批次1' },
{
value: 85,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 86,
id: 'someid-34',
name: '批次4',
},
{
value: 79,
id: 'someid-31',
name: '批次5',
},
// ...
],
},
{
value: 85,
id: 'someid-4',
name: '乐山调解中心',
children: [
{ value: 87, id: 'someid-31', name: '批次1' },
{
value: 86,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
// ...
],
},
{
value: 70,
id: 'someid-2',
name: '合作商测试1',
children: [
{ value: 85, id: 'someid-31', name: '批次1' },
// ...
],
},
{
value: 80,
id: 'someid-2',
name: '测试调解中心',
children: [
{ value: 84, id: 'someid-31', name: '批次1' },
{
value: 95,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 85,
id: 'someid-34',
name: '批次4',
},
{
value: 86,
id: 'someid-31',
name: '批次5',
},
{
value: 79,
id: 'someid-31',
name: '批次6',
},
// ...
],
},
{
value: 90,
id: 'someid-2',
name: '德阳调解中心',
children: [
{ value: 80, id: 'someid-31', name: '批次1' },
{
value: 78,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 88,
id: 'someid-34',
name: '批次4',
},
// ...
],
},
{
value: 91,
id: 'someid-2',
name: '遂宁调解中心',
children: [
{ value: 85, id: 'someid-31', name: '批次1' },
{
value: 85,
id: 'someid-32',
name: '批次2',
},
{
value: 77,
id: 'someid-33',
name: '批次3',
},
{
value: 86,
id: 'someid-34',
name: '批次4',
},
{
value: 85,
id: 'someid-31',
name: '批次5',
},
// ...
],
},
{
value: 70,
id: 'someid-2',
name: '雅安调解中心',
children: [
{ value: 87, id: 'someid-31', name: '批次A' },
{
value: 85,
id: 'someid-32',
name: '批次B',
},
{
value: 90,
id: 'someid-33',
name: '批次c',
},
// ...
],
},
{
value: 75,
id: 'someid-2',
name: '自贡调解中心',
children: [
{ value: 70, id: 'someid-31', name: '批次A1' },
{
value: 90,
id: 'someid-32',
name: '批次A2',
},
{
value: 80,
id: 'someid-33',
name: '批次A3',
},
{
value: 75,
id: 'someid-34',
name: '批次A4',
},
{
value: 85,
id: 'someid-31',
name: '批次A5',
},
// ...
],
},
{
value: 74,
id: 'someid-2',
name: '绵阳调解中心',
children: [
{ value: 70, id: 'someid-31', name: '批次B1' },
{
value: 70,
id: 'someid-32',
name: '批次B2',
},
{
value: 90,
id: 'someid-33',
name: '批次B3',
},
{
value: 72,
id: 'someid-34',
name: '批次B4',
},
{
value: 73,
id: 'someid-31',
name: '批次B5',
},
// ...
],
},
],
children: treeValue.value,
},
// {
// value: [23, 59, 12]
......@@ -395,7 +94,27 @@
],
},
],
};
});
const param = {};
if (!props.isAdmin) {
param['tenant'] = props.tenantId;
}
const query = () => {
load.value = true;
getTractRecordFollowRate(param).then((res) => {
if (res.result) {
load.value = false;
treeValue.value = res.result
}
});
};
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script>
<style lang="scss" scoped>
......
......@@ -6,14 +6,41 @@
</div>
<div class="flex flex-col items-end justify-center flex-1">
<p>安全守护</p>
<p><span class="green">789</span></p>
<p><span class="green">{{datas.securityDays}}</span></p>
<p>成功拦截攻击</p>
<p><span class="red">2823</span></p>
<p><span class="red">{{datas.interceptAttackDays}}</span></p>
</div>
</div>
</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>
.box {
width: 100%;
......
......@@ -99,7 +99,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -151,7 +151,7 @@
type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%',
barWidth: '25%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -163,7 +163,7 @@
show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'],
position: [0, '-108%'],
rich: {
//富文本
white: {
......@@ -190,7 +190,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -233,7 +233,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '0', //统计条宽度
barWidth: 1, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......
......@@ -86,7 +86,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -138,7 +138,7 @@
type: 'bar',
xAxisIndex: 1, //代表使用第二个X轴刻度!!!!!!!!!!!!!!!!!!!!!!!!
barGap: '-100%',
barWidth: '25%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -150,7 +150,7 @@
show: true,
//label 的position位置可以是top bottom left,right,也可以是固定值
//在这里需要上下统一对齐,所以用固定值
position: [0, '-160%'],
position: [0, '-108%'],
rich: {
//富文本
white: {
......@@ -177,7 +177,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '42%', //统计条宽度
barWidth: 20, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......@@ -220,7 +220,7 @@
show: true,
type: 'bar',
barGap: '-100%',
barWidth: '0', //统计条宽度
barWidth: 1, //统计条宽度
itemStyle: {
normal: {
barBorderRadius: 30,
......
......@@ -55,7 +55,7 @@
} else {
const param = {};
if (props.tenant !== '全部') {
param['tenantId'] = props.tenant;
param['tenant'] = props.tenant;
}
load.value = true;
getTractRecordDayHoursTotal(param)
......
......@@ -8,178 +8,205 @@
<script setup>
import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config';
const option = {
tooltip: {},
grid: {
top: '8%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
},
legend: {
itemGap: 50,
data: ['注册总量', '最新注册量'],
textStyle: {
color: '#f9f9f9',
borderColor: '#fff',
import { getAISecurityTotal } 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;
getAISecurityTotal().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 {
tooltip: {},
grid: {
top: '18%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true,
},
},
xAxis: [
{
type: 'category',
boundaryGap: true,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: '#f9f9f9',
},
legend: {
itemGap: 50,
data: ['注册总量', '最新注册量'],
textStyle: {
color: '#f9f9f9',
borderColor: '#fff',
},
axisLabel: {
//坐标轴刻度标签的相关设置
textStyle: {
color: '#d1e6eb',
margin: 15,
},
xAxis: [
{
type: 'category',
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月'],
},
],
yAxis: [
{
type: 'value',
min: 0,
// max: 140,
splitNumber: 7,
splitLine: {
show: true,
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
color: '#0a3256',
normal: {
color: '#28ffb3', // 线条颜色
},
borderColor: '#f0f',
},
},
axisLine: {
show: false,
},
axisLabel: {
margin: 20,
textStyle: {
color: '#d1e6eb',
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
},
},
},
axisTick: {
show: false,
},
},
],
series: [
{
name: '注册总量',
type: 'line',
// smooth: true, //是否平滑曲线显示
// symbol:'circle', // 默认是空心圆(中间是白色的),改成实心圆
showAllSymbol: true,
symbol: 'emptyCircle',
symbolSize: 6,
lineStyle: {
normal: {
color: '#28ffb3', // 线条颜色
itemStyle: {
normal: {
color: '#28ffb3',
},
},
borderColor: '#f0f',
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
tooltip: {
show: false,
},
},
itemStyle: {
normal: {
color: '#28ffb3',
areaStyle: {
//区域填充样式
normal: {
//线性渐变,前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,
},
areaStyle: {
//区域填充样式
normal: {
//线性渐变,前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, 设置图形的阴影效果。
{
name: '最新注册量',
type: 'bar',
barWidth: 20,
tooltip: {
show: false,
},
},
data: [393, 438, 485, 631, 689, 824, 987],
},
{
name: '最新注册量',
type: 'bar',
barWidth: 20,
tooltip: {
show: false,
},
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
},
},
},
itemStyle: {
normal: {
// barBorderRadius: 5,
// color: new echarts.graphic.LinearGradient(
// 0, 0, 0, 1,
// [{
// offset: 0,
// color: '#14c8d4'
// },
// {
// offset: 1,
// color: '#43eec6'
// }
// ]
// )
color: function (params) {
var colorList = [
'#0ec1ff',
'#10cdff',
'#12daff',
'#15ebff',
'#17f8ff',
'#1cfffb',
'#1dfff1',
];
return colorList[params.dataIndex];
itemStyle: {
normal: {
// barBorderRadius: 5,
// color: new echarts.graphic.LinearGradient(
// 0, 0, 0, 1,
// [{
// offset: 0,
// color: '#14c8d4'
// },
// {
// offset: 1,
// color: '#43eec6'
// }
// ]
// )
color: function (params) {
var colorList = [
'#0ec1ff',
'#10cdff',
'#12daff',
'#15ebff',
'#17f8ff',
'#1cfffb',
'#1dfff1',
];
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>
<style lang="scss" scoped>
.echarts {
......
......@@ -5,21 +5,39 @@
</template>
<script setup>
import { ref } from 'vue';
import ECharts from '@/components/ECharts/index.vue';
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 dataLine = [40, 56, 23, 15, 15];
var positionLeft = 20,
var positionLeft = 30,
max = 100 + positionLeft;
var g_cellBar0_y =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAoCAYAAAAhf6DEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA6SURBVEhLY2x8/vY/A4mg3zwcTDOBSTLBqGYSwahmEsGoZhLBqGYSwahmEsGoZhLBqGYSwZDUzMAAAJldBMF2UASmAAAAAElFTkSuQmCC';
var g_cellBarImg0_y = new Image();
g_cellBarImg0_y.src = g_cellBar0_y;
var option = {
const query = () => {
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: [
{
left: '0%',
......@@ -48,7 +66,7 @@
},
},
z: 10,
data: ['HTTP', '弱口令破解', 'XSS', 'SQL注入', '暴力破解'],
data: datas.value.map(v => v.name),
},
{
axisTick: 'none',
......@@ -63,7 +81,7 @@
},
},
z: 10,
data: [40, 56, 23, 15, 15],
data: datas.value.map(v => v.value),
},
{
axisLine: {
......@@ -94,7 +112,7 @@
type: 'bar',
stack: 'b',
yAxisIndex: 0,
data: dataLine,
data: datas.value.map(v => v.value),
label: {
normal: {
show: false,
......@@ -152,7 +170,7 @@
position: 'right',
distance: 10,
formatter: function (data) {
return dataLine[data.dataIndex] + '%';
return datas.value.map(v => v.value)[data.dataIndex] + '%';
},
textStyle: {
color: '#ffffff',
......@@ -172,7 +190,14 @@
z: 0,
},
],
};
};
});
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script>
<style lang="scss" scoped>
......
......@@ -5,13 +5,26 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, onBeforeUnmount, computed } from 'vue';
import ECharts from '@/components/ECharts/index.vue';
import echarts from '@/components/ECharts/config';
const Tenantlist = ref([]);
import { getTenantPage } from '@/api/tenant';
var option = {
import { getTractRecordFollowRate } from '@/api/dataScreenMock';
const load = ref(false);
const treeValue = ref([]);
const timer1 = ref();
onBeforeUnmount(() => {
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
});
const props = defineProps({
isAdmin: Boolean,
tenantId: [String, Number, Object],
});
var option = computed(() => {
return {
tooltip: {
formatter: '{b}:<br />完成率: {c}%',
},
......@@ -25,321 +38,7 @@
// 注意,最外层是一个数组,而非从某个根节点开始。
{
value: 100,
children: [
{
value: 85, // value字段的值,对应到面积大小。
// 也可以是数组,如 [2323, 43, 55],则数组第一项对应到面积大小。
// 数组其他项可以用于额外的视觉映射,详情参见 series-treemp.levels。
id: 'someid-1', // id 不是必须设置的。
// 但是如果想使用 API 来改变某个节点,需要用 id 来定位。
name: '测试调解中心2', // 显示在矩形中的描述文字。
children: [
{ value: 75, id: 'someid-31', name: '批次1' },
{
value: 80,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 95,
id: 'someid-34',
name: '批次4',
},
{
value: 85,
id: 'someid-31',
name: '批次5',
},
// ...
],
label: {
// 此节点特殊的 label 定义(如果需要的话)。
// ... // label的格式参见 series-treemap.label。
},
itemStyle: {
// 此节点特殊的 itemStyle 定义(如果需要的话)。
// ... // label的格式参见 series-treemap.itemStyle。
},
},
{
value: 80,
id: 'someid-2',
name: '西南调节中心',
children: [
{ value: 85, id: 'someid-31', name: '武汉' },
{
value: 78,
id: 'someid-32',
name: '咸宁',
},
{
value: 90,
id: 'someid-33',
name: '鄂州',
},
{
value: 86,
id: 'someid-34',
name: '荆州',
},
{
value: 85,
id: 'someid-31',
name: '宜昌',
},
// ...
],
},
{
value: 78,
id: 'someid-2',
name: '雄安调解中心',
children: [
{ value: 75, id: 'someid-54', name: '批次1' },
{
value: 85,
id: 'someid-99',
name: '批次2',
},
// ...
],
},
{
value: 89,
id: 'someid-3',
name: '广元调解中心',
children: [
{ value: 94, id: 'someid-31', name: '批次1' },
{
value: 85,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 86,
id: 'someid-34',
name: '批次4',
},
{
value: 79,
id: 'someid-31',
name: '批次5',
},
// ...
],
},
{
value: 85,
id: 'someid-4',
name: '乐山调解中心',
children: [
{ value: 87, id: 'someid-31', name: '批次1' },
{
value: 86,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
// ...
],
},
{
value: 70,
id: 'someid-2',
name: '合作商测试1',
children: [
{ value: 85, id: 'someid-31', name: '批次1' },
// ...
],
},
{
value: 80,
id: 'someid-2',
name: '测试调解中心',
children: [
{ value: 84, id: 'someid-31', name: '批次1' },
{
value: 95,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 85,
id: 'someid-34',
name: '批次4',
},
{
value: 86,
id: 'someid-31',
name: '批次5',
},
{
value: 79,
id: 'someid-31',
name: '批次6',
},
// ...
],
},
{
value: 90,
id: 'someid-2',
name: '德阳调解中心',
children: [
{ value: 80, id: 'someid-31', name: '批次1' },
{
value: 78,
id: 'someid-32',
name: '批次2',
},
{
value: 90,
id: 'someid-33',
name: '批次3',
},
{
value: 88,
id: 'someid-34',
name: '批次4',
},
// ...
],
},
{
value: 91,
id: 'someid-2',
name: '遂宁调解中心',
children: [
{ value: 85, id: 'someid-31', name: '批次1' },
{
value: 85,
id: 'someid-32',
name: '批次2',
},
{
value: 77,
id: 'someid-33',
name: '批次3',
},
{
value: 86,
id: 'someid-34',
name: '批次4',
},
{
value: 85,
id: 'someid-31',
name: '批次5',
},
// ...
],
},
{
value: 70,
id: 'someid-2',
name: '雅安调解中心',
children: [
{ value: 87, id: 'someid-31', name: '批次A' },
{
value: 85,
id: 'someid-32',
name: '批次B',
},
{
value: 90,
id: 'someid-33',
name: '批次c',
},
// ...
],
},
{
value: 75,
id: 'someid-2',
name: '自贡调解中心',
children: [
{ value: 70, id: 'someid-31', name: '批次A1' },
{
value: 90,
id: 'someid-32',
name: '批次A2',
},
{
value: 80,
id: 'someid-33',
name: '批次A3',
},
{
value: 75,
id: 'someid-34',
name: '批次A4',
},
{
value: 85,
id: 'someid-31',
name: '批次A5',
},
// ...
],
},
{
value: 74,
id: 'someid-2',
name: '绵阳调解中心',
children: [
{ value: 70, id: 'someid-31', name: '批次B1' },
{
value: 70,
id: 'someid-32',
name: '批次B2',
},
{
value: 90,
id: 'someid-33',
name: '批次B3',
},
{
value: 72,
id: 'someid-34',
name: '批次B4',
},
{
value: 73,
id: 'someid-31',
name: '批次B5',
},
// ...
],
},
],
children: treeValue.value,
},
// {
// value: [23, 59, 12]
......@@ -395,7 +94,27 @@
],
},
],
};
});
const param = {};
if (!props.isAdmin) {
param['tenant'] = props.tenantId;
}
const query = () => {
load.value = true;
getTractRecordFollowRate(param).then((res) => {
if (res.result) {
load.value = false;
treeValue.value = res.result
}
});
};
query();
timer1.value = setInterval(() => {
if (!load.value) {
query();
}
}, 6000);
</script>
<style lang="scss" scoped>
......
......@@ -7,7 +7,7 @@
</div>
<div class="header-ct">
<div class="header-ct-title">
<span>数字经营看板</span>
<span>不良资产综合管理平台</span>
</div>
</div>
<div class="header-ri">
......@@ -41,20 +41,20 @@
<div class="dataScreen-top">
<div class="dataScreen-main-title">
<img src="./images/baohu.png" alt="" style="height: 35px" />
Ⅲ级安全监测
三级等保安全监测
</div>
<div class="dataScreen-main-chart">
<AgeRatioChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div>
</div>
<div class="dataScreen-center">
<div class="dataScreen-main-title"> 事件类型统计 </div>
<div class="dataScreen-main-title"> 数据安全防护 </div>
<div class="dataScreen-main-chart">
<RealTimeAccessChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div>
</div>
<div class="dataScreen-bottom">
<div class="dataScreen-main-title"> AI安全趋势预测 </div>
<div class="dataScreen-main-title"> 客户注册数据 </div>
<div class="dataScreen-main-chart">
<PlatformSourceChart :isAdmin="isAdmin" :tenantId="tenantId" />
</div>
......@@ -74,7 +74,6 @@
</div>
</div>
<div class="dataScreen-map" v-else>
<div class="dataScreen-map-title">当日跟进分析</div>
<MaleFemaleRatioChart :tenantId="tenantId" />
</div>
<div class="dataScreen-cb">
......
......@@ -12,14 +12,14 @@
<div class="view-account-form">
<el-form ref="formRef" :model="formInline" :rules="rules" size="large">
<el-form-item prop="username">
<el-input v-model="formInline.username" placeholder="Please Input">
<el-input v-model="formInline.username" placeholder="请输入账号">
<template #prefix>
<el-icon size="20"><User /></el-icon>
</template>
</el-input>
</el-form-item>
<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>
<el-icon size="20"><Lock /></el-icon>
</template>
......
......@@ -13,7 +13,18 @@
<el-form ref="ruleFormRef" :model="ruleForm" class="demo-ruleForm" label-width="80px">
<el-form-item label="收件人:" prop="content">
<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%"
><Plus
/></el-icon>
......@@ -64,27 +75,40 @@
const envs = getAppEnvConfig();
const url = envs.VITE_GLOB_API_URL_PREFIX + '/sys/upload';
const ruleFormRef = ref();
const users = ref([]);
const current = ref({});
const ruleForm = reactive({
content: '',
id: '',
title: '',
receivers: [],
username: '',
userid: [],
});
const editValue = ref('');
const hanldeConfirm = (row) => {
ruleForm.receivers = row;
ruleForm.username = row.map((v) => v.username);
// const selects = [...ruleForm.receivers, ...row]
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 = () => {
saveMesage({
...current.value,
title: ruleForm.title,
content: ruleForm.content,
id: ruleForm.id,
status: 'normal',
messageType: 'system',
sendType: 'user',
receiversIds: ruleForm.receivers.map((v) => v.id),
receiversIds: ruleForm.userid,
}).then((res) => {
showModal.value = false;
emits('success');
......@@ -98,30 +122,29 @@
ruleForm.content = value;
};
const openModal = (row) => {
console.log('asdas', row);
if (row) {
current.value = row;
ruleForm.content = row.content;
editValue.value = row.content;
ruleForm.title = row.title;
ruleForm.id = row.id;
ruleForm.receivers = [];
if (row.receiversIds) {
row.receiversIds.forEach((element) => {
console.log('userModalRef.value?.tableData', userModalRef.value?.tableData);
const item = userModalRef.value?.tableData.find((ii) => ii.id === element);
console.log('item', item);
if (item) {
ruleForm.receivers.push(item);
}
});
console.log('ruleForm.receivers', ruleForm.receivers);
ruleForm.username = ruleForm.receivers.map((v) => v.username).join(',');
ruleForm.userid = ruleForm.receivers.map((v) => v.id);
}
} else {
ruleForm.content = '';
current.value = {}
editValue.value = '';
ruleForm.title = '';
ruleForm.receivers = [];
ruleForm.username = '';
ruleForm.userid = [];
}
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