mirror of
https://gitee.com/beecue/fastbee.git
synced 2026-05-08 00:34:41 +08:00
更新
This commit is contained in:
324
vue/src/views/iot/netty/clients.vue
Normal file
324
vue/src/views/iot/netty/clients.vue
Normal file
@@ -0,0 +1,324 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card v-show="showSearch" style="margin-bottom: 6px">
|
||||
<el-form @submit.native.prevent :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
|
||||
<el-form-item label="客户端" prop="clientId">
|
||||
<el-input v-model="queryParams.clientId" placeholder="请输入客户端ID" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="isClient">
|
||||
<el-checkbox v-model="queryParams.isClient" true-label="1" false-label="0">只看设备端</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-tabs type="border-card" v-model="serverType" @tab-click="handleClick" style="flex: 1; height: 800px; margin-bottom: 5px">
|
||||
<el-tab-pane label="MQTT客户端" name="MQTT">
|
||||
<el-table v-loading="loading" :data="clientList">
|
||||
<el-table-column label="客户端ID" align="left" header-align="center" prop="clientId">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false" type="primary" @click.native="handleOpen(scope.row)">{{ scope.row.clientId }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" align="center" prop="type">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="danger" v-if="scope.row.clientId.indexOf('server') == 0">服务端</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.clientId.indexOf('web') == 0">Web端</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.clientId.indexOf('phone') == 0">移动端</el-tag>
|
||||
<el-tag type="info" v-else-if="scope.row.clientId.indexOf('test') == 0">测试端</el-tag>
|
||||
<el-tag type="primary" v-else>设备端</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="连接状态" align="center" prop="connected">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.connected">已连接</el-tag>
|
||||
<el-tag type="info" v-else>已断开</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="心跳(秒)" align="center" prop="keepAlive" width="100" />
|
||||
<el-table-column label="账号" align="center" prop="username" width="100px" />
|
||||
<el-table-column label="当前订阅数量" align="center" prop="topicCount" width="100" />
|
||||
<el-table-column label="连接时间" align="center" prop="connected_at" />
|
||||
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="clickClientOut(scope.row)">踢出</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- MQTT客户端详细 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||
<el-tabs v-model="activeName" tab-position="top" style="padding: 10px">
|
||||
<el-tab-pane name="subscribe">
|
||||
<span slot="label">订阅列表</span>
|
||||
<el-row :gutter="10" class="mb8"></el-row>
|
||||
<el-table :data="subscribeList" size="mini">
|
||||
<el-table-column label="主题" align="center" prop="topicName" />
|
||||
<el-table-column label="QoS" align="center" prop="qos" />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="TCP客户端" name="TCP">
|
||||
<el-table v-loading="loading" :data="clientList">
|
||||
<el-table-column label="客户端ID" align="left" header-align="center" prop="clientId"></el-table-column>
|
||||
<el-table-column label="类型" align="center" prop="type">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="danger" v-if="scope.row.clientId.indexOf('server') == 0">服务端</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.clientId.indexOf('web') == 0">Web端</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.clientId.indexOf('phone') == 0">移动端</el-tag>
|
||||
<el-tag type="info" v-else-if="scope.row.clientId.indexOf('test') == 0">测试端</el-tag>
|
||||
<el-tag type="primary" v-else>设备端</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="连接状态" align="center" prop="connected">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.connected">已连接</el-tag>
|
||||
<el-tag type="info" v-else>已断开</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="心跳(秒)" align="center" prop="keepAlive" width="100" />
|
||||
<el-table-column label="连接时间" align="center" prop="connected_at" />
|
||||
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="clickClientOut(scope.row)">踢出</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- MQTT客户端详细 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||
<el-tabs v-model="activeName" tab-position="top" style="padding: 10px">
|
||||
<el-tab-pane name="subscribe">
|
||||
<span slot="label">订阅列表</span>
|
||||
<el-row :gutter="10" class="mb8"></el-row>
|
||||
<el-table :data="subscribeList" size="mini">
|
||||
<el-table-column label="主题" align="center" prop="topicName" />
|
||||
<el-table-column label="QoS" align="center" prop="qos" />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 添加或修改订阅对话框 -->
|
||||
<el-dialog title="添加订阅" :visible.sync="subscribeOpen" width="800px" append-to-body>
|
||||
<el-form ref="subscribeForm" :model="subscribeForm" :rules="rules" label-width="60px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="主题" prop="topic">
|
||||
<el-input v-model="subscribeForm.topic" placeholder="请输入主题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Qos" prop="qos">
|
||||
<el-select v-model="subscribeForm.qos" placeholder="请选择消息类型">
|
||||
<el-option key="0" label="0" value="0"></el-option>
|
||||
<el-option key="1" label="1" value="1"></el-option>
|
||||
<el-option key="2" label="2" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">添 加 订 阅</el-button>
|
||||
<el-button @click="cancelSubscribe">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { clientOut, listNettyMqttClient } from '@/api/iot/netty';
|
||||
|
||||
export default {
|
||||
name: 'Category',
|
||||
data() {
|
||||
return {
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
loadSubscribeing: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 产品分类表格数据
|
||||
clientList: [],
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示添加订阅弹出层
|
||||
subscribeOpen: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
clientId: null,
|
||||
isClient: 0,
|
||||
serverCode: 'MQTT',
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 选中选项卡
|
||||
activeName: 'subscribe',
|
||||
//订阅列表数据
|
||||
subscribeList: [],
|
||||
//订阅数据
|
||||
subscribe: {
|
||||
topic: '',
|
||||
clientId: '',
|
||||
},
|
||||
//添加订阅表单参数
|
||||
subscribeForm: {
|
||||
qos: '0',
|
||||
},
|
||||
//客户端ID
|
||||
clientId: '',
|
||||
//服务协议类型
|
||||
serverType: 'MQTT',
|
||||
// 表单校验
|
||||
rules: {
|
||||
topic: [
|
||||
{
|
||||
required: true,
|
||||
message: '主题不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listNettyMqttClient(this.queryParams).then((response) => {
|
||||
this.clientList = response.data;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
/*将客户端踢出*/
|
||||
clickClientOut(row) {
|
||||
const params = { clientId: row.clientId };
|
||||
clientOut(params).then((res) => {
|
||||
//刷新列表
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
|
||||
/*tabs切换*/
|
||||
handleClick() {
|
||||
this.queryParams.serverCode = this.serverType;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
/** 查询客户端订阅列表 */
|
||||
getSubscribeList(clientId) {
|
||||
this.clientId = clientId;
|
||||
this.loadSubscribeing = true;
|
||||
getSubscriptionsByClientId(clientId).then((res) => {
|
||||
this.subscribeList = res.data.data;
|
||||
this.loadSubscribeing = false;
|
||||
});
|
||||
},
|
||||
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 断开客户端连接 */
|
||||
handleDelete(row) {
|
||||
const clientId = row.clientId;
|
||||
this.$modal
|
||||
.confirm('是否确认删除MQTT客户端编号为"' + clientId + '"的数据项?')
|
||||
.then(function () {
|
||||
return eliminateClient(clientId);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
//取消主题订阅
|
||||
handleUnsubscribe(row) {
|
||||
const clientId = row.clientId;
|
||||
const topic = row.topic;
|
||||
this.$modal
|
||||
.confirm('是否确认取消订阅主题为"' + topic + '"的数据项?')
|
||||
.then(function () {
|
||||
const param = {};
|
||||
param.topic = topic;
|
||||
param.clientId = clientId;
|
||||
return unsubscribe(param);
|
||||
})
|
||||
.then(() => {
|
||||
this.getSubscribeList(clientId);
|
||||
this.$modal.msgSuccess('取消订阅成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
//查看客户端详情
|
||||
handleOpen(row) {
|
||||
this.open = true;
|
||||
this.title = '详情';
|
||||
this.subscribeList = row.topics;
|
||||
console.log(this.subscribeList);
|
||||
},
|
||||
|
||||
//添加订阅
|
||||
handleAdd() {
|
||||
this.subscribeOpen = true;
|
||||
},
|
||||
//提交添加订阅表单
|
||||
submitForm() {
|
||||
this.subscribeForm.clientId = this.clientId;
|
||||
console.log(this.subscribeForm);
|
||||
this.$refs['subscribeForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
addSubscribe(this.subscribeForm).then((response) => {
|
||||
this.$modal.msgSuccess('新增订阅成功');
|
||||
this.subscribeOpen = false;
|
||||
this.getSubscribeList(this.clientId);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
cancelSubscribe() {
|
||||
this.subscribeOpen = false;
|
||||
this.resetForm('subscribeForm');
|
||||
//刷新列表
|
||||
this.getSubscribeList(this.clientId);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
346
vue/src/views/iot/netty/mqtt.vue
Normal file
346
vue/src/views/iot/netty/mqtt.vue
Normal file
@@ -0,0 +1,346 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card style="margin-bottom: 6px">
|
||||
<el-row :gutter="120">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
|
||||
<h3 style="font-weight: bold">Mqtt 统计指标</h3>
|
||||
<el-row :gutter="20" class="panel-group">
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 17px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-orange">
|
||||
<svg-icon icon-class="guide" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div>
|
||||
<div class="card-panel-text">发送消息</div>
|
||||
<count-to :start-val="0" :end-val="this.static['send_total']" :duration="3000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 18px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-green">
|
||||
<svg-icon icon-class="receiver" class-name="card-panel-icon" />
|
||||
</div>
|
||||
|
||||
<div class="card-panel-description">
|
||||
<div>
|
||||
<div class="card-panel-text">接收消息</div>
|
||||
<count-to :start-val="0" :end-val="this.static['receive_total']" :duration="3000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 17px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-orange">
|
||||
<svg-icon icon-class="authenticate" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">认证次数</div>
|
||||
<count-to :start-val="0" :end-val="this.static['auth_total']" :duration="1000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 18px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-green">
|
||||
<svg-icon icon-class="connect" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">连接次数</div>
|
||||
<count-to :start-val="0" :end-val="this.static['connect_total']" :duration="1000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 17px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-orange">
|
||||
<svg-icon icon-class="subscribe1" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">订阅次数</div>
|
||||
<count-to :start-val="0" :end-val="this.static['subscribe_total']" :duration="2000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 17px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-green">
|
||||
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div>
|
||||
<div class="card-panel-text">今日接收</div>
|
||||
<count-to :start-val="0" :end-val="this.static['today_received']" :duration="3000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="card-panel-col" style="margin-bottom: 17px">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-orange">
|
||||
<svg-icon icon-class="subscribe1" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">今日发送</div>
|
||||
<count-to :start-val="0" :end-val="this.static['today_send']" :duration="2000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="15" :xl="15">
|
||||
<div style="padding: 30px 0 85px">
|
||||
<div ref="pieTotal" style="height: 230px"></div>
|
||||
</div>
|
||||
<div ref="statsChart" style="height: 275px; margin: 20px 0 40px 0"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getNettyMqttStats, statisticNettyMqtt } from '@/api/iot/netty';
|
||||
import CountTo from 'vue-count-to';
|
||||
|
||||
export default {
|
||||
name: 'Mqtt',
|
||||
components: {
|
||||
CountTo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// mqtt状态数据
|
||||
stats: {},
|
||||
// mqtt统计信息
|
||||
static: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getMqttStats();
|
||||
this.statisticMqtt();
|
||||
},
|
||||
methods: {
|
||||
/** 查询mqtt统计*/
|
||||
statisticMqtt() {
|
||||
statisticNettyMqtt().then((response) => {
|
||||
this.static = response.data;
|
||||
this.totalMqtt();
|
||||
});
|
||||
},
|
||||
/** 查询mqtt状态数据*/
|
||||
getMqttStats() {
|
||||
getNettyMqttStats().then((response) => {
|
||||
this.stats = response.data;
|
||||
this.drawStats();
|
||||
});
|
||||
},
|
||||
// 绘制mqtt饼图
|
||||
totalMqtt() {
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
let myChart = this.$echarts.init(this.$refs.pieTotal);
|
||||
var option;
|
||||
option = {
|
||||
title: {
|
||||
text: 'Mqtt消息',
|
||||
left: 'left',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
},
|
||||
color: ['#E6A23C', '#F56C6C', '#DDD'],
|
||||
series: [
|
||||
{
|
||||
name: 'Mqtt消息 %',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
labelLine: {
|
||||
normal: {
|
||||
position: 'inner',
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: this.static['send_total'],
|
||||
name: '发送消息总数',
|
||||
},
|
||||
{
|
||||
value: this.static['receive_total'],
|
||||
name: '接收消息总数',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
},
|
||||
/** 绘制mqtt状态统计 */
|
||||
drawStats() {
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
let myChart = this.$echarts.init(this.$refs.statsChart);
|
||||
var option;
|
||||
|
||||
option = {
|
||||
title: {
|
||||
text: 'Mqtt 状态数据',
|
||||
textStyle: {
|
||||
fontSize: 18,
|
||||
color: '#000',
|
||||
fontWeight: 800,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
},
|
||||
legend: {},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, 0.01],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
axisLabel: {
|
||||
fontSize: 14,
|
||||
},
|
||||
data: ['连接数量', '会话数量', '订阅数量', '路由数量', '保留消息'],
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '当前数量',
|
||||
type: 'bar',
|
||||
data: [this.stats['connection_count'], this.stats['session_count'], this.stats['subscription_count'], this.stats['retain_count'], this.stats['retain_count']],
|
||||
itemStyle: {
|
||||
color: '#67C23A',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '累计总数',
|
||||
type: 'bar',
|
||||
data: [this.stats['connection_total'], this.stats['session_total'], this.stats['subscription_total'], this.stats['retain_total'], this.stats['retain_total']],
|
||||
itemStyle: {
|
||||
color: '#409EFF',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.panel-group {
|
||||
.card-panel-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card-panel {
|
||||
height: 68px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
color: #666;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 5px;
|
||||
//box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08);
|
||||
background-color: #fff;
|
||||
|
||||
&:hover {
|
||||
.card-panel-icon-wrapper {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icon-blue {
|
||||
background: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-green {
|
||||
background: #34bfa3;
|
||||
}
|
||||
|
||||
.icon-red {
|
||||
background: #f56c6c;
|
||||
}
|
||||
|
||||
.icon-orange {
|
||||
background: #e6a23c;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-blue {
|
||||
color: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-green {
|
||||
color: #34bfa3;
|
||||
}
|
||||
|
||||
.icon-red {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.icon-orange {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.card-panel-icon-wrapper {
|
||||
float: left;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
transition: all 0.38s ease-out;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.card-panel-icon {
|
||||
float: left;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.card-panel-description {
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
margin: 15px;
|
||||
margin-left: 0px;
|
||||
|
||||
.card-panel-text {
|
||||
line-height: 14px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
margin-bottom: 12px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.card-panel-num {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user