fix: 物联卡引导页菜单、按钮权限

This commit is contained in:
blp 2023-02-07 10:13:52 +08:00
parent 355bc6df64
commit 619d21f3f1
2 changed files with 445 additions and 413 deletions

View File

@ -70,6 +70,7 @@
<Guide title="流量统计"> <Guide title="流量统计">
<template #extra> <template #extra>
<TimeSelect <TimeSelect
key="flow-static"
:type="'week'" :type="'week'"
:quickBtnList="quickBtnList" :quickBtnList="quickBtnList"
@change="getEcharts" @change="getEcharts"
@ -93,6 +94,7 @@
<Guide title="流量使用TOP10"> <Guide title="流量使用TOP10">
<template #extra> <template #extra>
<TimeSelect <TimeSelect
key="flow-top10"
:quickBtn="false" :quickBtn="false"
:type="'week'" :type="'week'"
@change="getTopRang" @change="getTopRang"

View File

@ -1,85 +1,90 @@
<!-- 物联卡-首页 --> <!-- 物联卡-首页 -->
<template> <template>
<page-container> <page-container>
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="14"> <a-col :span="14">
<div class="home-guide"> <div class="home-guide">
<Guide title="物联卡引导"></Guide> <Guide title="物联卡引导"></Guide>
<div <div
class="home-guide-items" class="home-guide-items"
:style="`grid-template-columns: repeat(${ :style="`grid-template-columns: repeat(${
guideList ? guideList.length : 1 guideList ? guideList.length : 1
}, 1fr);`" }, 1fr);`"
> >
<div <div
v-for="(item, index) in guideList" v-for="(item, index) in guideList"
:key="index" :key="index"
class="home-guide-item step-bar arrow-2 pointer" class="home-guide-item step-bar arrow-2 pointer"
@click="jumpPage(item)" @click="jumpPage(item)"
> >
<div class="item-english">{{ item.english }}</div> <div class="item-english">{{ item.english }}</div>
<div class="item-title">{{ item.name }}</div> <div class="item-title">{{ item.name }}</div>
<div class="item-index"> <div class="item-index">
<img :src="Image[index + 1]" /> <img :src="Image[index + 1]" />
</div> </div>
</div> </div>
</div> </div>
</div>
</a-col>
<a-col :span="10">
<div class="home-statistics">
<Guide title="基础统计">
<template #extra>
<span class="extra-text">详情</span>
</template>
</Guide>
<div class="home-statistics-body">
<div class="home-guide-item">
<div class="item-english">昨日流量统计</div>
<div class="item-title">{{ currentSource }} M</div>
<div
class="item-index-echarts"
style="height: 75px; width: 110px"
>
<div class="chart" ref="todayFlowChart"></div>
</div>
</div>
<div class="home-guide-item">
<div class="item-english">物联卡</div>
<div class="item-content">
<div
v-for="iten in pieChartData"
:key="iten.key"
class="item-node"
>
<div class="item-node-text">
{{ iten.value }}
</div>
<div :class="`state ${iten.className}`">
{{ iten.name }}
</div>
</div> </div>
</div> </a-col>
<div <a-col :span="10">
class="item-index-echarts" <div class="home-statistics">
style="height: 75px; width: 110px" <Guide title="基础统计">
> <template #extra>
<div class="chart" ref="iotCardChart"></div> <span class="extra-text" @click="jumpDashboard"
</div> >详情</span
</div> >
</div> </template>
</div> </Guide>
</a-col> <div class="home-statistics-body">
<a-col :span="24" style="min-height: 580px"> <div class="home-guide-item">
<div class="home-body"> <div class="item-english">昨日流量统计</div>
<Guide title="平台架构图" english="PLATFORM ARCHITECTURE DIAGRAM" /> <div class="item-title">{{ currentSource }} M</div>
<div class="home-body-img"> <div
<img :src="getImage('/iot-card/iotcard-home.png')" /> class="item-index-echarts"
</div> style="height: 75px; width: 110px"
</div> >
</a-col> <div class="chart" ref="todayFlowChart"></div>
</a-row> </div>
</page-container> </div>
<div class="home-guide-item">
<div class="item-english">物联卡</div>
<div class="item-content">
<div
v-for="iten in pieChartData"
:key="iten.key"
class="item-node"
>
<div class="item-node-text">
{{ iten.value }}
</div>
<div :class="`state ${iten.className}`">
{{ iten.name }}
</div>
</div>
</div>
<div
class="item-index-echarts"
style="height: 75px; width: 110px"
>
<div class="chart" ref="iotCardChart"></div>
</div>
</div>
</div>
</div>
</a-col>
<a-col :span="24" style="min-height: 580px">
<div class="home-body">
<Guide
title="平台架构图"
english="PLATFORM ARCHITECTURE DIAGRAM"
/>
<div class="home-body-img">
<img :src="getImage('/iot-card/iotcard-home.png')" />
</div>
</div>
</a-col>
</a-row>
</page-container>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -89,220 +94,245 @@ import { message } from 'ant-design-vue';
import moment from 'moment'; import moment from 'moment';
import { queryFlow, list } from '@/api/iot-card/home'; import { queryFlow, list } from '@/api/iot-card/home';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { useMenuStore } from '@/store/menu';
import { usePermissionStore } from '@/store/permission';
const router = useRouter(); const router = useRouter();
const { proxy } = <any>getCurrentInstance(); const { proxy } = <any>getCurrentInstance();
interface GuideItemProps { interface GuideItemProps {
key: string; key: string;
name: string; name: string;
english: string; english: string;
url: string; url: string;
param?: Record<string, any>; param?: Record<string, any>;
index?: number; index?: number;
auth: boolean; auth: boolean;
} }
const menuHasPermission = useMenuStore().hasPermission;
const btnHasPermission = usePermissionStore().hasPermission;
//
const dashBoardUrl = menuHasPermission('/iot-card/Dashboard');
const platformUrl = menuHasPermission('/iot-card/Platform/Detail');
const recordUrl = menuHasPermission('/iot-card/Record');
const cardUrl = menuHasPermission('/iot-card/CardManagement');
//
const paltformPermission = btnHasPermission(`/iot-card/Platform:add`);
const cardPermission = btnHasPermission(`/iot-card/CardManagement:add`);
const Image = { const Image = {
1: getImage('/home/1.png'), 1: getImage('/home/1.png'),
2: getImage('/home/2.png'), 2: getImage('/home/2.png'),
3: getImage('/home/3.png'), 3: getImage('/home/3.png'),
}; };
const guideList = [ const guideList = [
{ {
key: 'EQUIPMENT', key: 'EQUIPMENT',
name: '平台对接', name: '平台对接',
english: 'STEP1', english: 'STEP1',
auth: '', auth: paltformPermission,
url: '', url: platformUrl,
}, },
{ {
key: 'SCREEN', key: 'SCREEN',
name: '物联卡管理', name: '物联卡管理',
english: 'STEP2', english: 'STEP2',
auth: '', auth: !!cardPermission,
url: '', url: cardUrl,
param: { save: true }, param: { save: true },
}, },
{ {
key: 'CASCADE', key: 'CASCADE',
name: '操作记录', name: '操作记录',
english: 'STEP3', english: 'STEP3',
auth: '', auth: !!recordUrl,
url: '', url: recordUrl,
}, },
]; ];
const currentSource = ref<number>(0); const currentSource = ref<number>(0);
const barChartData = ref<any[]>([]); const barChartData = ref<any[]>([]);
const pieChartData = ref<any[]>([ const pieChartData = ref<any[]>([
{ {
key: 'using', key: 'using',
name: '正常', name: '正常',
value: 0, value: 0,
className: 'normal', className: 'normal',
}, },
{ {
key: 'toBeActivated', key: 'toBeActivated',
name: '未激活', name: '未激活',
value: 0, value: 0,
className: 'notActive', className: 'notActive',
}, },
{ {
key: 'deactivate', key: 'deactivate',
name: '停用', name: '停用',
value: 0, value: 0,
className: 'stopped', className: 'stopped',
}, },
]); ]);
const jumpPage = (data: GuideItemProps) => { const jumpPage = (data: GuideItemProps) => {
if (data.url && data.auth) { if (data.url && data.auth) {
router.push(`${data.url}`, data.param); router.push({ path: `${data.url}`, ...data.param });
} else { } else {
message.warning('暂无权限,请联系管理员'); message.warning('暂无权限,请联系管理员');
} }
};
const jumpDashboard = () => {
if (dashBoardUrl) {
router.push(`${dashBoardUrl}`);
} else {
message.warning('暂无权限,请联系管理员');
}
}; };
/** /**
* 获取昨日流量消耗 * 获取昨日流量消耗
*/ */
const getTodayFlow = async () => { const getTodayFlow = async () => {
const beginTime = moment().subtract(1, 'days').startOf('day').valueOf(); const beginTime = moment().subtract(1, 'days').startOf('day').valueOf();
const endTime = moment().subtract(1, 'days').endOf('day').valueOf(); const endTime = moment().subtract(1, 'days').endOf('day').valueOf();
const resp: any = await queryFlow(beginTime, endTime, { orderBy: 'date' }); const resp: any = await queryFlow(beginTime, endTime, { orderBy: 'date' });
resp.result.map((item: any) => { resp.result.map((item: any) => {
currentSource.value += parseFloat(item.value.toFixed(2)); currentSource.value += parseFloat(item.value.toFixed(2));
}); });
}; };
/** /**
* 获取最近15天流量消耗统计图数据 * 获取最近15天流量消耗统计图数据
*/ */
const get15DaysTrafficConsumption = async () => { const get15DaysTrafficConsumption = async () => {
const beginTime = moment().subtract(15, 'days').startOf('day').valueOf(); const beginTime = moment().subtract(15, 'days').startOf('day').valueOf();
const endTime = moment().subtract(1, 'days').endOf('day').valueOf(); const endTime = moment().subtract(1, 'days').endOf('day').valueOf();
const resp: any = await queryFlow(beginTime, endTime, { orderBy: 'date' }); const resp: any = await queryFlow(beginTime, endTime, { orderBy: 'date' });
barChartData.value = resp.result barChartData.value = resp.result
.map((item: any) => ({ .map((item: any) => ({
...item, ...item,
})) }))
.reverse(); .reverse();
createBarChart(); createBarChart();
}; };
/** /**
* 获取物联卡状态数据 * 获取物联卡状态数据
*/ */
const getStateCard = async () => { const getStateCard = async () => {
Promise.all( Promise.all(
pieChartData.value.map((item) => { pieChartData.value.map((item) => {
const params = { const params = {
terms: [ terms: [
{ {
terms: [ terms: [
{ {
column: 'cardStateType', column: 'cardStateType',
termType: 'eq', termType: 'eq',
value: item.key, value: item.key,
}, },
], ],
}, },
], ],
}; };
return list(params); return list(params);
}), }),
) )
.then((resp) => { .then((resp) => {
resp.forEach((i: any, index) => { resp.forEach((i: any, index) => {
if (i.success) { if (i.success) {
pieChartData.value[index].value = i.result.total; pieChartData.value[index].value = i.result.total;
} }
}); });
createPieChart(); createPieChart();
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);
}); });
}; };
/** /**
* 最近15天流量消耗统计图 * 最近15天流量消耗统计图
*/ */
const createBarChart = () => { const createBarChart = () => {
const myChart = echarts.init(proxy.$refs.todayFlowChart); const myChart = echarts.init(proxy.$refs.todayFlowChart);
const options = { const options = {
tooltip: {}, tooltip: {},
xAxis: { xAxis: {
show: false, show: false,
data: barChartData.value.map((m) => m.date), data: barChartData.value.map((m) => m.date),
}, },
yAxis: { yAxis: {
show: false, show: false,
}, },
series: [ series: [
{ {
name: '流量消耗', name: '流量消耗',
type: 'bar', type: 'bar',
color: '#FACD89', color: '#FACD89',
// barWidth: '5%', // // barWidth: '5%', //
showBackground: true, // showBackground: true, //
data: barChartData.value.map((m) => parseFloat(m.value.toFixed(2))), data: barChartData.value.map((m) =>
}, parseFloat(m.value.toFixed(2)),
], ),
}; },
myChart.setOption(options); ],
window.addEventListener('resize', function () { };
myChart.resize(); myChart.setOption(options);
}); window.addEventListener('resize', function () {
myChart.resize();
});
}; };
/** /**
* 物联卡饼图 * 物联卡饼图
*/ */
const createPieChart = () => { const createPieChart = () => {
nextTick(() => { nextTick(() => {
const myChart = echarts.init(proxy.$refs.iotCardChart); const myChart = echarts.init(proxy.$refs.iotCardChart);
const options = { const options = {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: '{b}: {c} ({d}%)', formatter: '{b}: {c} ({d}%)',
},
color: ['#85a5ff', '#f29b55', '#c4c4c4'],
series: [
{
name: '',
type: 'pie',
avoidLabelOverlap: true, //
radius: ['50%', '90%'],
center: ['50%', '50%'],
itemStyle: {
borderColor: 'rgba(255,255,255,1)',
borderWidth: 2,
},
label: {
normal: {
show: false,
}, },
}, color: ['#85a5ff', '#f29b55', '#c4c4c4'],
data: pieChartData.value, series: [
}, {
], name: '',
}; type: 'pie',
myChart.setOption(options); avoidLabelOverlap: true, //
window.addEventListener('resize', function () { radius: ['50%', '90%'],
myChart.resize(); center: ['50%', '50%'],
itemStyle: {
borderColor: 'rgba(255,255,255,1)',
borderWidth: 2,
},
label: {
normal: {
show: false,
},
},
data: pieChartData.value,
},
],
};
myChart.setOption(options);
window.addEventListener('resize', function () {
myChart.resize();
});
}); });
});
}; };
watch( watch(
barChartData.value, barChartData.value,
() => { () => {
createBarChart(); createBarChart();
}, },
{ deep: true }, { deep: true },
); );
getTodayFlow(); getTodayFlow();
@ -312,230 +342,230 @@ getStateCard();
<style scoped lang="less"> <style scoped lang="less">
.home-base { .home-base {
position: relative; position: relative;
padding: 24px 16px; padding: 24px 16px;
background-color: #fff; background-color: #fff;
} }
.home-guide { .home-guide {
margin-bottom: 24px; margin-bottom: 24px;
padding: 24px 16px; padding: 24px 16px;
background-color: #fff; background-color: #fff;
.home-guide-items { .home-guide-items {
display: grid; display: grid;
grid-column-gap: 56px; grid-column-gap: 56px;
} }
} }
.home-guide-item { .home-guide-item {
position: relative;
padding: 16px;
background: linear-gradient(
135.62deg,
#f6f7fd 22.27%,
rgba(255, 255, 255, 0.86) 91.82%
);
border-radius: 2px;
box-shadow: 0 4px 18px #efefef;
.state {
position: relative; position: relative;
padding-left: 8px; padding: 16px;
&::before { background: linear-gradient(
position: absolute; 135.62deg,
top: 7px; #f6f7fd 22.27%,
left: 0; rgba(255, 255, 255, 0.86) 91.82%
display: inline-block; );
width: 6px; border-radius: 2px;
height: 6px; box-shadow: 0 4px 18px #efefef;
margin-right: 2px; .state {
content: ''; position: relative;
padding-left: 8px;
&::before {
position: absolute;
top: 7px;
left: 0;
display: inline-block;
width: 6px;
height: 6px;
margin-right: 2px;
content: '';
}
&.normal::before {
background: #85a5ff;
}
&.notActive::before {
background: #f29b55;
}
&.stopped::before {
background: #c4c4c4;
}
} }
&.normal::before {
background: #85a5ff; &.pointer {
cursor: pointer;
} }
&.notActive::before {
background: #f29b55; .item-english {
color: #4f4f4f;
} }
&.stopped::before {
background: #c4c4c4; .item-content {
display: flex;
margin-top: 15px;
width: 80%;
} }
}
&.pointer { .item-node {
cursor: pointer; min-width: 58px;
} margin-right: 8px;
z-index: 1;
.item-english { .item-node-text {
color: #4f4f4f; font-size: 14px;
} font-weight: bold;
}
.item-content {
display: flex;
margin-top: 15px;
width: 80%;
}
.item-node {
min-width: 58px;
margin-right: 8px;
z-index: 1;
.item-node-text {
font-size: 14px;
font-weight: bold;
} }
}
.item-title { .item-title {
margin: 20px 0; margin: 20px 0;
color: @text-color; color: @text-color;
font-weight: 700; font-weight: 700;
font-size: 20px; font-size: 20px;
} }
.item-index { .item-index {
position: absolute; position: absolute;
right: 10%; right: 10%;
bottom: 0; bottom: 0;
} }
.item-index-echarts { .item-index-echarts {
.item-index; .item-index;
right: 12px; right: 12px;
bottom: 5%; bottom: 5%;
z-index: 0; z-index: 0;
width: 50%; width: 50%;
.chart { .chart {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
} }
}
} }
.home-body { .home-body {
.home-base; .home-base;
min-height: 444px; min-height: 444px;
margin-bottom: 24px; margin-bottom: 24px;
// padding-bottom: 26.5%; // padding-bottom: 26.5%;
padding-bottom: 30%; padding-bottom: 30%;
overflow: hidden; overflow: hidden;
border-bottom: 1px solid #2f54eb; border-bottom: 1px solid #2f54eb;
.home-body-img { .home-body-img {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
height: 100%; height: 100%;
> img { > img {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
} }
}
} }
.home-statistics { .home-statistics {
.home-base; .home-base;
.extra-text { .extra-text {
cursor: pointer; cursor: pointer;
color: @primary-color; color: @primary-color;
} }
.home-statistics-body { .home-statistics-body {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 24px; gap: 24px;
} }
} }
.step-item-after { .step-item-after {
position: absolute; position: absolute;
top: 50%; top: 50%;
right: -60px; right: -60px;
width: 60px; width: 60px;
height: 40px; height: 40px;
transform: translateY(-50%); transform: translateY(-50%);
content: ' '; content: ' ';
} }
.home-step { .home-step {
.home-base; .home-base;
.home-step-items { .home-step-items {
display: grid; display: grid;
grid-column-gap: 66px; grid-column-gap: 66px;
.step-item { .step-item {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.step-item-title { .step-item-title {
position: relative; position: relative;
padding: 16px 24px; padding: 16px 24px;
color: #333; color: #333;
font-weight: bold; font-weight: bold;
font-size: 14px; font-size: 14px;
background-color: #f8f9fd; background-color: #f8f9fd;
cursor: pointer; cursor: pointer;
.step-item-img { .step-item-img {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
z-index: 1; z-index: 1;
height: 100%; height: 100%;
img { img {
height: 100%; height: 100%;
} }
}
> span {
position: relative;
z-index: 2;
}
}
.step-item-content {
flex-grow: 1;
height: auto;
padding: 24px;
border-right: 1px solid #e5edf4;
border-bottom: 1px solid #e5edf4;
border-left: 1px solid #e5edf4;
}
} }
> span {
position: relative;
z-index: 2;
}
}
.step-item-content {
flex-grow: 1;
height: auto;
padding: 24px;
border-right: 1px solid #e5edf4;
border-bottom: 1px solid #e5edf4;
border-left: 1px solid #e5edf4;
}
} }
}
} }
.step-bar { .step-bar {
position: relative; position: relative;
&.arrow-1 { &.arrow-1 {
&:not(:last-child) { &:not(:last-child) {
&::after { &::after {
.step-item-after; .step-item-after;
background: url('/images/home/arrow-1.png') no-repeat center; background: url('/images/home/arrow-1.png') no-repeat center;
} }
}
} }
}
&.arrow-2 { &.arrow-2 {
&:not(:last-child) { &:not(:last-child) {
&::after { &::after {
.step-item-after; .step-item-after;
background: url('/images/home/arrow-2.png') no-repeat center; background: url('/images/home/arrow-2.png') no-repeat center;
} }
}
} }
}
} }
</style> </style>