Browse Source

feat:新增首页内容

confidence
杜贤金 3 years ago
parent
commit
357f824e89
  1. 14
      src/api/communication/flowpool.js
  2. 74
      src/api/wel/administrator.js
  3. 50
      src/api/wel/buser.js
  4. 132
      src/views/communicationmanage/flowpool/flowpool.vue
  5. 71
      src/views/communicationmanage/targetflowpool/targetflowpool.vue
  6. 708
      src/views/wel/component/Administrator.vue
  7. 524
      src/views/wel/component/Buser.vue
  8. 683
      src/views/wel/component/clientside.vue
  9. 14
      src/views/wel/index.vue

14
src/api/communication/flowpool.js

@ -47,3 +47,17 @@ export const update = (row) => {
})
}
//同步流量池
export const syncFlowPool = () => {
return request({
url: '/api/iot-sim/flowpool/syncFlowPool',
method: 'get',
})
}
//同步流量池使用量
export const syncFlowPoolUsage = () => {
return request({
url: '/api/iot-sim/flowpool/syncFlowPoolUsage',
method: 'get',
})
}

74
src/api/wel/administrator.js

@ -1,4 +1,5 @@
import request from '@/router/axios';
// ----- 卡状态start
//卡总数
export const cardTotal = () => {
return request({
@ -21,3 +22,76 @@ export const cardStatus = () => {
method: 'get',
})
}
// ----- 卡状态end
// ----- 元流量池监控start
export const getFlowPool = () => {
return request({
url: '/api/iot-sim/home/getFlowPool',
method: 'get',
})
}
// ----- 元流量池监控end
// -----设备接入总数start
export const getDeviceNum = () => {
return request({
url: '/api/iot-sim/home/getDeviceNum',
method: 'get',
})
}
// ----- 设备接入总数end
// -----日使用排名、月使用排名start
export const getUsage = (type) => {
return request({
url: '/api/iot-sim/home/getUsage',
method: 'get',
params: {
type
}
})
}
// ----- 日使用排名、月使用排名end
// -----日收款、月收款start
export const getMoney = (type) => {
return request({
url: '/api/iot-sim/home/getMoney',
method: 'get',
params: {
type
}
})
}
// ----- 日收款、月收款排名end
// -----:佣金申请数量 结算佣金数量start 1:佣金申请数量 2:结算佣金数量
export const getWithdrawal = (type) => {
return request({
url: '/api/iot-sim/home/getWithdrawal',
method: 'get',
params: {
type
}
})
}
// ----- 佣金申请数量 结算佣金数量end
// -----:echars使用量 start
export const getMonthUsage = () => {
return request({
url: '/api/iot-sim/home/getMonthUsage',
method: 'get',
})
}
// ----- echars使用量 end
// -----本月订单 本日订单 1:今天 5:本月
export const getOrderNum = (type) => {
return request({
url: '/api/iot-sim/home/getOrderNum',
method: 'get',
params: {
type
}
})
}
// ----- 本月订单 本日订单end

50
src/api/wel/buser.js

@ -0,0 +1,50 @@
import request from '@/router/axios';
//运营商卡数量
export const getOperatorCardNum = () => {
return request({
url: '/api/iot-sim/home/getOperatorCardNum',
method: 'get',
})
}
//卡状态
export const cardStatus = () => {
return request({
url: '/api/iot-sim/home/getSimStatus',
method: 'get',
})
}
// ----- 流量池监控start
export const getFlowPool = () => {
return request({
url: '/api/iot-sim/home/getPoolMonitoring',
method: 'get',
})
}
// -----:echars使用量 start
export const getTotalUsage = () => {
return request({
url: '/api/iot-sim/home/getTotalUsage',
method: 'get',
})
}
// -----日使用排名、月使用排名start
export const getUsage = (type) => {
return request({
url: '/api/iot-sim/home/getUsage',
method: 'get',
params: {
type
}
})
}
// ----- 日使用排名、月使用排名end
//剩余量
export const getCardSurplus = () => {
return request({
url: '/api/iot-sim/home/getCardSurplus',
method: 'get',
})
}

132
src/views/communicationmanage/flowpool/flowpool.vue

@ -19,19 +19,23 @@
@refresh-change="refreshChange"
@on-load="onLoad"
>
<template slot-scope="{ disabled, size, value }" slot="activationNumForm">
<el-input
:disabled="disabled"
:size="size"
v-model="value == -1 ? '-' : value"
></el-input>
<template slot="menuLeft">
<el-button
size="small"
type="primary"
icon="el-icon-refresh-right"
@click="handlesyncFlowPool"
>同步流量池
</el-button>
</template>
<template slot-scope="{ disabled, size, value }" slot="accountForm">
<el-input
:disabled="disabled"
:size="size"
v-model="value == '' ? '-' : value"
></el-input>
<template slot="menuLeft">
<el-button
size="small"
type="primary"
icon="el-icon-refresh-right"
@click="handlesyncFlowPoolUsage"
>同步流量池使用量
</el-button>
</template>
</avue-crud>
</basic-container>
@ -44,6 +48,8 @@ import {
add,
remove,
update,
syncFlowPool,
syncFlowPoolUsage,
} from "@/api/communication/flowpool";
import { mapGetters } from "vuex";
@ -82,7 +88,7 @@ export default {
prop: "channelId",
type: "select",
span: 12,
width: 100,
search: true,
dataType: "String",
dicUrl: "/api/iot-sim/channel/fillData",
@ -98,6 +104,22 @@ export default {
},
],
},
{
label: "接口类型",
type: "select",
dicUrl: "/api/iot-system/dict/dictionary?code=interface_type",
props: {
label: "dictValue",
value: "dictKey",
},
span: 12,
dataType: "number",
prop: "interfaceType",
search: true,
rules: [
{ required: true, message: "请选择接口类型", trigger: "change" },
],
},
{
label: "流量池编号",
prop: "code",
@ -129,11 +151,37 @@ export default {
],
},
{
label: "流量池总量",
label: "流量池总量(M)",
prop: "total",
span: 12,
addDisplay: false,
editDisplay: false,
searchLabelWidth: 90,
width: 115,
search: false,
hide: false,
type: "number",
rules: [
{
required: true,
message: "请输入流量池总量",
trigger: "blur",
},
{
pattern: /^\d+(\.\d+)?$/,
message: "请输入正确的流量池总量",
trigger: "blur",
},
],
},
{
label: "流量池使用量(M)",
prop: "usageM",
span: 12,
addDisplay: false,
editDisplay: false,
searchLabelWidth: 90,
width: 115,
search: false,
hide: false,
type: "number",
@ -154,7 +202,6 @@ export default {
label: "提醒阈值",
prop: "remindRatio",
span: 12,
searchLabelWidth: 90,
search: false,
hide: false,
@ -243,39 +290,52 @@ export default {
label: "已激活数量",
prop: "activationNum",
span: 12,
search: false,
hide: true,
addDisplay: false,
editDisplay: false,
formslot: true,
viewDisplay: true,
rules: [
{
required: true,
message: "请输入已激活数量",
trigger: "blur",
},
],
},
{
label: "未激活数量",
prop: "unactivatedNum",
span: 12,
search: false,
addDisplay: false,
editDisplay: false,
viewDisplay: true,
rules: [
{
pattern: /^\d+?$/,
message: "请输入正确的已激活数量",
required: true,
message: "请输入激活数量",
trigger: "blur",
},
],
},
{
label: "管理员名称",
prop: "account",
label: "超量是否停机所有流量卡",
prop: "isStopAll",
type: "select",
dicUrl: "/api/iot-system/dict/dictionary?code=yes_no",
props: {
label: "dictValue",
value: "dictKey",
},
dataType: "number",
span: 12,
search: false,
addDisplay: false,
editDisplay: false,
hide: true,
formslot: true,
rules: [
{
required: true,
message: "请输入管理员账号",
trigger: "blur",
message: "请选择是否停机所有流量卡",
trigger: "change",
},
],
},
@ -387,6 +447,22 @@ export default {
this.loading = false;
});
},
//
handlesyncFlowPool() {
syncFlowPool().then((res) => {
if (res.data.code == 200) {
this.onLoad(this.page, this.query);
}
});
},
//使
handlesyncFlowPoolUsage() {
syncFlowPoolUsage().then((res) => {
if (res.data.code == 200) {
this.onLoad(this.page, this.query);
}
});
},
},
};
</script>

71
src/views/communicationmanage/targetflowpool/targetflowpool.vue

@ -19,20 +19,6 @@
@refresh-change="refreshChange"
@on-load="onLoad"
>
<template slot-scope="{ disabled, size, value }" slot="activationNumForm">
<el-input
:disabled="disabled"
:size="size"
v-model="value == -1 ? '-' : value"
></el-input>
</template>
<template slot-scope="{ disabled, size, value }" slot="accountForm">
<el-input
:disabled="disabled"
:size="size"
v-model="value == '' ? '-' : value"
></el-input>
</template>
</avue-crud>
</basic-container>
</template>
@ -102,13 +88,13 @@ export default {
label: "目标流量池编号",
prop: "code",
span: 12,
width: 105,
searchLabelWidth: 90,
search: false,
rules: [
{
required: true,
message: "请输入设备序列号",
message: "请输入目标流量池编号",
trigger: "blur",
},
],
@ -117,7 +103,7 @@ export default {
label: "目标流量池名称",
prop: "name",
span: 12,
width: 105,
searchLabelWidth: 130,
search: true,
rules: [
@ -129,11 +115,37 @@ export default {
],
},
{
label: "目标流量池总量",
label: "流量池总量(M)",
prop: "total",
span: 12,
searchLabelWidth: 90,
search: false,
addDisplay: false,
editDisplay: false,
hide: false,
type: "number",
rules: [
{
required: true,
message: "请输入流量池总量",
trigger: "blur",
},
{
pattern: /^\d+(\.\d+)?$/,
message: "请输入正确的流量池总量",
trigger: "blur",
},
],
},
{
label: "流量池使用量(M)",
prop: "usageM",
span: 12,
addDisplay: false,
editDisplay: false,
searchLabelWidth: 90,
width: 115,
search: false,
hide: false,
type: "number",
@ -154,7 +166,6 @@ export default {
label: "提醒阈值",
prop: "remindRatio",
span: 12,
searchLabelWidth: 90,
search: false,
hide: false,
@ -206,7 +217,6 @@ export default {
},
dataType: "number",
prop: "type",
searchLabelWidth: 140,
search: false,
rules: [
@ -222,7 +232,6 @@ export default {
label: "单卡最大使用量(M)",
prop: "maxUsage",
span: 12,
search: false,
hide: true,
type: "number",
@ -239,43 +248,35 @@ export default {
},
],
},
{
label: "已激活数量",
prop: "activationNum",
span: 12,
search: false,
hide: true,
addDisplay: false,
editDisplay: false,
formslot: true,
viewDisplay: true,
rules: [
{
required: true,
message: "请输入已激活数量",
trigger: "blur",
},
{
pattern: /^\d+?$/,
message: "请输入正确的已激活数量",
trigger: "blur",
},
],
},
{
label: "管理员名称",
prop: "account",
label: "未激活数量",
prop: "unactivatedNum",
span: 12,
search: false,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
hide: true,
formslot: true,
viewDisplay: true,
rules: [
{
required: true,
message: "请输入管理员账号",
message: "请输入未激活数量",
trigger: "blur",
},
],

708
src/views/wel/component/Administrator.vue

@ -1,27 +1,699 @@
<template>
<div class="app-container">
<div class="dashboard-container">
<div class="dashboard-text">欢迎访问物联网平台</div>
<div>
<img src="@/assets/shouye.png" alt class="dashboard-img" />
<basic-container>
<div class="app-container">
<div class="cardTotal">
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-select
v-model="cardtype"
placeholder="请选择"
size="small"
@change="handleCardType"
>
<el-option
v-for="(item, index) in cardType"
:key="index"
:label="item"
:value="item"
>
</el-option>
</el-select>
</div>
<div id="cardTotalmain" style="width: 100%; height: 165px"></div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>元流量池监控</span>
</div>
<div
class="foolbox"
v-for="(item, index) in foolmonitoring"
:key="index"
>
<div class="top">
<div class="name">{{ item.name }}</div>
<div class="G">{{ item.totalM }}M</div>
</div>
<div class="progress">
<el-progress
:text-inside="true"
:stroke-width="18"
:percentage="item.ratio"
:status="Number(item.ratio) > 80 ? 'warning' : ''"
></el-progress>
</div>
</div>
</el-card>
<el-card class="box-card"> </el-card>
</div>
<div class="statistics">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>设备接入总数</span>
</div>
<div class="device">{{ getDeviceNumsObj }}</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>会员总数</span>
</div>
<div class="water">
<div>
<div class="number">0</div>
<div class="water-name">企业</div>
</div>
<div>
<div class="number">0</div>
<div class="water-name">个人</div>
</div>
</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>销售情况</span>
</div>
<div class="water">
<div>
<div class="number">0</div>
<div class="water-name">累计销售</div>
</div>
<div>
<div class="number">0</div>
<div class="water-name">本年销售</div>
</div>
<div>
<div class="number">0</div>
<div class="water-name">本月销售</div>
</div>
</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>佣金总计</span>
</div>
<div class="water">
<div>
<div class="number">0</div>
<div class="water-name">已支付</div>
</div>
<div>
<div class="number">0</div>
<div class="water-name">未支付</div>
</div>
</div>
</el-card>
</div>
<div class="tabs">
<el-card class="box-card">
<div class="tabs-box">
<div class="useTypeBox">
<div
v-for="(item, index) in useType"
:key="index"
:class="useIndex == index ? 'useType color' : 'useType nocolor'"
@click="handleTabs(index)"
>
{{ item.name }}
</div>
</div>
</div>
<!-- 总使用量 -->
<div class="totaluse" v-show="useIndex == 0">
<div class="left">
<div id="useEchars" style="width: 100%; height: 300px"></div>
</div>
<div class="right">
<div
class="show-box"
v-for="(item, index) in totaluseoptions"
:key="index"
>
<div class="show">
<div>
<div class="title">{{ item.name }}</div>
<div class="content">{{ item.money }}</div>
</div>
</div>
</div>
</div>
</div>
<!-- 销售排行 -->
<div class="rank" v-show="useIndex != 0">
<div class="rank-box">
<div
class="rankList"
v-for="(item, index) in rankListArr"
:key="index"
>
<div class="left">
<div class="index">{{ index + 1 }}</div>
</div>
<div class="right">
<div class="phone">{{ item.iccid }}</div>
<div class="num">{{ item.usage }}(M)</div>
</div>
</div>
</div>
</div>
</el-card>
</div>
</div>
</div>
</basic-container>
</template>
<script>
import * as echarts from "echarts";
import {
cardTotal,
operatorCard,
cardStatus,
getFlowPool,
getDeviceNum,
getUsage,
getMoney,
getWithdrawal,
getMonthUsage,
getOrderNum,
} from "@/api/wel/administrator";
export default {
data() {
return {
cardtype: "卡总数",
cardType: ["卡总数", "运营商卡数量", "出库卡状态"],
cardData: [],
month: [],
usage: [],
useIndex: 0,
useType: [
{
name: "总使用量",
},
{
name: "销售排名",
},
{
name: "月使用排名",
},
{
name: "日使用排名",
},
],
//
foolmonitoring: [],
//
getDeviceNumsObj: 0,
//echars
totaluseoptions: [
{
name: "本日收款",
money: "0",
},
{
name: "本月收款",
money: "0",
},
{
name: "本日订单数量",
money: "0",
},
{
name: "本月订单数量",
money: "0",
},
{
name: "佣金提现申请",
money: "0",
},
{
name: "结算佣金数",
money: "0",
},
],
//使使
rankListArr: [],
};
},
created() {
this.cardTotals();
this.getFlowPools(); //
this.getDeviceNums(); //
this.getMoneys();
this.getMoneyss();
this.getWithdrawals();
this.getWithdrawalss();
this.getMonthUsages();
this.getOrderNums();
this.getOrderNumss();
},
mounted() {},
methods: {
//
handleCardType(e) {
if (e == "卡总数") {
this.cardTotals();
} else if (e == "运营商卡数量") {
this.operatorCards();
} else if (e == "出库卡状态") {
this.cardStatuss();
}
},
//
cardTotals() {
cardTotal().then((res) => {
if (res.data.code == 200) {
(this.cardData = [
{
name: "出库数量",
value: res.data.data.deliver,
},
{
name: "未出库数量",
value: res.data.data.notDeliver,
},
]),
this.cardTotal();
}
});
},
<style scoped>
.dashboard-container {
width: 100%;
text-align: center;
//
operatorCards() {
operatorCard().then((res) => {
if (res.data.code == 200) {
this.cardData = [
{
name: "山东省移动",
value: res.data.data.shanDongShengYiDong,
},
{
name: "山东省电信",
value: res.data.data.shanDongShengDianXin,
},
{
name: "华为电信",
value: res.data.data.huaWeiDianXin,
},
{
name: "济南历城移动",
value: res.data.data.jiNanLiChengYiDong,
},
{
name: "北京移动",
value: res.data.data.beiJingYiDong,
},
{
name: "济南天桥移动",
value: res.data.data.jiNanTianQiaoYiDong,
},
];
this.cardTotal();
}
});
},
//
cardStatuss() {
cardStatus().then((res) => {
console.log(res, 3);
if (res.data.code == 200) {
this.cardData = [
{
name: "已激活",
value: res.data.data.inUse,
},
{
name: "未激活",
value: res.data.data.unused,
},
{
name: "停机",
value: res.data.data.shutdown,
},
{
name: "其他",
value: res.data.data.other,
},
];
this.cardTotal();
}
});
},
//
cardTotal() {
let chartDom = document.getElementById("cardTotalmain");
let myChart = echarts.init(chartDom);
let option;
option = {
tooltip: {
trigger: "item",
},
legend: {
type: "scroll",
orient: "vertical",
right: 0,
},
series: [
{
type: "pie",
radius: ["60%", "90%"],
center: ["40%", "50%"],
avoidLabelOverlap: false,
label: {
show: false,
position: "left",
},
labelLine: {
show: false,
},
data: this.cardData,
},
],
};
option && myChart.setOption(option);
},
//
getFlowPools() {
getFlowPool().then((res) => {
if (res.data.code == 200) {
this.foolmonitoring = res.data.data;
}
});
},
//
getDeviceNums() {
getDeviceNum().then((res) => {
if (res.data.code == 200) {
this.getDeviceNumsObj = res.data.data;
}
});
},
//使echars
useEchars() {
let chartDoms = document.getElementById("useEchars");
let myCharts = echarts.init(chartDoms);
let options;
options = {
xAxis: {
name: "月",
type: "category",
boundaryGap: false,
data: this.month,
},
yAxis: {
type: "value",
name: "M",
},
series: [
{
data: this.usage,
type: "line",
areaStyle: {},
},
],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
},
};
options && myCharts.setOption(options);
},
//
handleTabs(index) {
this.useIndex = index;
if (index == 2) {
this.getUsages(2);
} else if (index == 3) {
this.getUsages(1);
}
},
//使使 type 2:1
getUsages(type) {
getUsage(type).then((res) => {
if (res.data.code == 200) {
this.rankListArr = res.data.data;
}
});
},
// type 2:1
getMoneys() {
getMoney(1).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[0].money = res.data.data;
}
});
},
getMoneyss() {
getMoney(2).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[1].money = res.data.data;
}
});
},
//
getOrderNums() {
getOrderNum(1).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[2].money = res.data.data.total;
}
});
},
getOrderNumss() {
getOrderNum(5).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[3].money = res.data.data.total;
}
});
},
//
getWithdrawals() {
getWithdrawal(1).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[4].money = res.data.data;
}
});
},
getWithdrawalss() {
getWithdrawal(2).then((res) => {
if (res.data.code == 200) {
this.totaluseoptions[5].money = res.data.data;
}
});
},
//使
getMonthUsages() {
getMonthUsage().then((res) => {
let month = [];
let usage = [];
if (res.data.code == 200) {
res.data.data.forEach((element) => {
month.push(element.month);
usage.push(element.usage);
});
this.month = month;
this.usage = usage;
this.useEchars();
}
});
},
},
};
</script>
<style scoped lang="scss">
.cardTotal {
display: flex;
justify-content: space-between;
.box-card {
width: 32%;
height: 250px;
overflow: auto;
.foolbox {
margin-top: 2px;
.top {
display: flex;
justify-content: space-between;
.name {
font-size: 13px;
color: #666;
font-weight: bold;
}
}
.roundtop {
display: flex;
justify-content: space-around;
}
.round {
display: flex;
justify-content: center;
}
.progress {
margin-top: 1px;
}
}
}
}
.dashboard-text {
color: #333;
font-size: 25px;
margin-top: 15%;
.clearfix {
font-size: 17px;
font-weight: bold;
color: #666;
}
.dashboard-img {
margin-top: 40px;
width: 25%;
height: 25%;
//
.statistics {
display: flex;
justify-content: space-between;
margin-top: 12px;
.box-card {
width: 24%;
.device {
font-size: 34px;
display: flex;
justify-content: center;
align-items: center;
height: 90px;
font-weight: bold;
color: rgb(66, 125, 169);
}
.water {
height: 90px;
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
.number {
font-size: 19px;
font-weight: bold;
color: rgb(66, 125, 169);
}
.water-name {
margin-top: 9px;
font-size: 16px;
font-weight: 500;
color: rgb(66, 125, 169);
}
}
}
}
//
.tabs {
margin-top: 10px;
width: 100%;
.tabs-box {
.useTypeBox {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-around;
.useType {
cursor: pointer;
padding-bottom: 13px;
}
.color {
border-bottom: 2px solid blueviolet;
color: "blueviolet";
}
.nocolor {
border-bottom: 2px solid white;
}
}
}
.totaluse {
display: flex;
.left {
flex: 4;
}
.right {
flex: 2;
margin-top: 20px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
.show-box {
width: 46%;
height: 80px;
background: #427da9;
border-radius: 14px;
display: flex;
justify-content: center;
align-items: center;
.show {
width: 92%;
height: 70px;
background: #427da9;
border-radius: 14px;
border: 1px solid white;
color: white;
display: flex;
justify-content: center;
align-items: center;
.title {
font-size: 14px;
}
.content {
font-size: 18px;
text-align: center;
}
}
}
}
}
.rank {
width: 100%;
height: 300px;
margin: 0 auto;
.rank-box {
width: 90%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.rankList {
display: flex;
width: 50%;
margin-top: 15px;
.left {
width: 13%;
height: 40px;
background: #427da9;
.index {
color: white;
text-align: center;
font-size: 16px;
line-height: 40px;
font-weight: bold;
}
}
.right {
width: 80%;
height: 40px;
background: #f2f2f2;
display: flex;
align-items: center;
justify-content: space-around;
color: #427da9;
font-weight: 700;
.phone {
width: 60%;
}
.num {
width: 20%;
}
}
}
}
}
}
</style>

524
src/views/wel/component/Buser.vue

@ -0,0 +1,524 @@
<template>
<basic-container>
<div class="app-container">
<div class="cardTotal">
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-select
v-model="cardtype"
placeholder="请选择"
size="small"
@change="handleCardType"
>
<el-option
v-for="(item, index) in cardType"
:key="index"
:label="item"
:value="item"
>
</el-option>
</el-select>
</div>
<div id="cardTotalmain" style="width: 100%; height: 165px"></div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>流量池监控</span>
</div>
<div
class="foolbox"
v-for="(item, index) in foolmonitoring"
:key="index"
>
<div class="top">
<div class="name">{{ item.name }}</div>
<div class="G">{{ item.totalM }}M</div>
</div>
<div class="progress">
<el-progress
:text-inside="true"
:stroke-width="18"
:percentage="item.ratio"
:status="Number(item.ratio) > 80 ? 'warning' : ''"
></el-progress>
</div>
</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>流量剩余量</span>
</div>
<div class="foolbox">
<div class="top">
<el-table :data="residueListArr" style="width: 100%">
<el-table-column prop="iccid" label="ICCID"> </el-table-column>
<el-table-column prop="surplus" label="剩余量(M)" align="right">
</el-table-column>
</el-table>
</div>
</div>
</el-card>
</div>
<div class="tabs">
<el-card class="box-card">
<div class="tabs-box">
<div class="useTypeBox">
<div
v-for="(item, index) in useType"
:key="index"
:class="useIndex == index ? 'useType color' : 'useType nocolor'"
@click="handleTabs(index)"
>
{{ item.name }}
</div>
</div>
</div>
<!-- 总使用量 -->
<div class="totaluse" v-show="useIndex == 0">
<div class="left">
<div id="useEchars" style="width: 100%; height: 300px"></div>
</div>
</div>
<!-- 销售排行 -->
<div class="rank" v-show="useIndex != 0">
<div class="rank-box">
<div
class="rankList"
v-for="(item, index) in rankListArr"
:key="index"
>
<div class="left">
<div class="index">{{ index + 1 }}</div>
</div>
<div class="right">
<div class="phone">{{ item.iccid }}</div>
<div class="num">{{ item.usage }}(M)</div>
</div>
</div>
</div>
</div>
</el-card>
</div>
</div>
</basic-container>
</template>
<script>
import * as echarts from "echarts";
import {
getOperatorCardNum,
cardStatus,
getFlowPool,
getTotalUsage,
getUsage,
getCardSurplus,
} from "@/api/wel/buser";
export default {
data() {
return {
cardtype: "运营商卡数量",
cardType: ["运营商卡数量", "出库卡状态"],
cardData: [],
month: [],
usage: [],
useIndex: 0,
useType: [
{
name: "总使用量",
},
{
name: "月使用排名",
},
{
name: "日使用排名",
},
],
//
foolmonitoring: [],
//
residueListArr: [],
//
//使使
rankListArr: [],
};
},
created() {
this.operatorCards();
this.getFlowPools(); //
this.getTotalUsages(); //使
this.getCardSurpluss(); //
},
mounted() {},
methods: {
//
handleCardType(e) {
if (e == "运营商卡数量") {
this.operatorCards();
} else if (e == "出库卡状态") {
this.cardStatuss();
}
},
//
operatorCards() {
getOperatorCardNum().then((res) => {
if (res.data.code == 200) {
this.cardData = [
{
name: "中国移动",
value: res.data.data.mobile,
},
{
name: "中国联通",
value: res.data.data.unicom,
},
{
name: "中国电信",
value: res.data.data.telecom,
},
];
this.cardTotal();
}
});
},
//
cardStatuss() {
cardStatus().then((res) => {
if (res.data.code == 200) {
this.cardData = [
{
name: "已激活",
value: res.data.data.inUse,
},
{
name: "未激活",
value: res.data.data.unused,
},
{
name: "停机",
value: res.data.data.shutdown,
},
{
name: "其他",
value: res.data.data.other,
},
];
this.cardTotal();
}
});
},
//
cardTotal() {
let chartDom = document.getElementById("cardTotalmain");
let myChart = echarts.init(chartDom);
let option;
option = {
tooltip: {
trigger: "item",
},
legend: {
type: "scroll",
orient: "vertical",
right: 0,
},
series: [
{
type: "pie",
radius: ["60%", "90%"],
center: ["40%", "50%"],
avoidLabelOverlap: false,
label: {
show: false,
position: "left",
},
labelLine: {
show: false,
},
data: this.cardData,
},
],
};
option && myChart.setOption(option);
},
//
getFlowPools() {
getFlowPool().then((res) => {
if (res.data.code == 200) {
this.foolmonitoring = res.data.data;
}
});
},
//
getCardSurpluss() {
getCardSurplus().then((res) => {
if (res.data.code == 200) {
this.residueListArr = res.data.data;
}
});
},
//使echars
useEchars() {
let chartDoms = document.getElementById("useEchars");
let myCharts = echarts.init(chartDoms);
let options;
options = {
xAxis: {
name: "月",
type: "category",
boundaryGap: false,
data: this.month,
},
yAxis: {
type: "value",
name: "M",
},
series: [
{
data: this.usage,
type: "line",
areaStyle: {},
},
],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
},
};
options && myCharts.setOption(options);
},
//
handleTabs(index) {
this.useIndex = index;
if (index == 1) {
this.getUsages(2);
} else if (index == 2) {
this.getUsages(1);
}
},
//使使 type 2:1
getUsages(type) {
getUsage(type).then((res) => {
if (res.data.code == 200) {
this.rankListArr = res.data.data;
}
});
},
//使
getTotalUsages() {
getTotalUsage().then((res) => {
let month = [];
let usage = [];
if (res.data.code == 200) {
res.data.data.forEach((element) => {
month.push(element.month);
usage.push(element.usage);
});
this.month = month;
this.usage = usage;
this.useEchars();
}
});
},
},
};
</script>
<style scoped lang="scss">
.cardTotal {
display: flex;
justify-content: space-between;
.box-card {
width: 32%;
height: 250px;
overflow: auto;
.foolbox {
.top {
display: flex;
justify-content: space-between;
.name {
font-size: 13px;
color: #666;
font-weight: bold;
}
}
.roundtop {
display: flex;
justify-content: space-around;
}
.round {
display: flex;
justify-content: center;
}
.progress {
margin-top: 1px;
}
}
}
}
.clearfix {
font-size: 17px;
font-weight: bold;
color: #666;
}
//
.statistics {
display: flex;
justify-content: space-between;
margin-top: 12px;
.box-card {
width: 24%;
.device {
font-size: 34px;
display: flex;
justify-content: center;
align-items: center;
height: 90px;
font-weight: bold;
color: rgb(66, 125, 169);
}
.water {
height: 90px;
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
.number {
font-size: 19px;
font-weight: bold;
color: rgb(66, 125, 169);
}
.water-name {
margin-top: 9px;
font-size: 16px;
font-weight: 500;
color: rgb(66, 125, 169);
}
}
}
}
//
.tabs {
margin-top: 10px;
width: 100%;
.tabs-box {
.useTypeBox {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-around;
.useType {
cursor: pointer;
padding-bottom: 13px;
}
.color {
border-bottom: 2px solid blueviolet;
color: "blueviolet";
}
.nocolor {
border-bottom: 2px solid white;
}
}
}
.totaluse {
display: flex;
.left {
flex: 4;
}
.right {
flex: 2;
margin-top: 20px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
.show-box {
width: 46%;
height: 80px;
background: #427da9;
border-radius: 14px;
display: flex;
justify-content: center;
align-items: center;
.show {
width: 92%;
height: 70px;
background: #427da9;
border-radius: 14px;
border: 1px solid white;
color: white;
display: flex;
justify-content: center;
align-items: center;
.title {
font-size: 14px;
}
.content {
font-size: 18px;
text-align: center;
}
}
}
}
}
.rank {
width: 100%;
height: 300px;
margin: 0 auto;
.rank-box {
width: 90%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.rankList {
display: flex;
width: 50%;
margin-top: 15px;
.left {
width: 13%;
height: 40px;
background: #427da9;
.index {
color: white;
text-align: center;
font-size: 16px;
line-height: 40px;
font-weight: bold;
}
}
.right {
width: 80%;
height: 40px;
background: #f2f2f2;
display: flex;
align-items: center;
justify-content: space-around;
color: #427da9;
font-weight: 700;
.phone {
width: 60%;
}
.num {
width: 20%;
}
}
}
}
}
}
</style>

683
src/views/wel/component/clientside.vue

@ -1,368 +1,409 @@
<template>
<div>
<div class="infos">
<el-card>
<div class="title">
<span class="icon el-icon-tickets"></span>
客户信息
</div>
<div class="content">
<div>
客户名称 <span>{{ form.tenantName }}</span>
</div>
<div>
联系人 <span>{{ form.linkman }}</span>
<basic-container>
<div class="container">
<div class="top">
<el-card class="Turnover">
<div slot="header" class="clearfix">
<span>交易额</span>
</div>
<div>
联系电话 <span>{{ form.contactNumber }}</span>
</div>
</div>
</el-card>
<el-card>
<div class="title">
<span class="icon el-icon-star-off"></span>
金额
</div>
<div class="content">
<div>
账户额度
<span>{{ printFn(form.balance / 10000) }} <span>()</span> </span>
</div>
<div>
授信余额
<span
>{{ printFn(form.creditBalance / 10000) }}<span>()</span></span
<div class="money">9999</div>
<div class="timeChange">
<div
:class="timeIndex == index ? 'timebox' : 'timebox nocolor'"
v-for="(item, index) in time"
:key="index"
@click="handleTime(index)"
>
{{ item }}
</div>
</div>
<div>
授信额度
<span
>{{ printFn(form.creditAmount / 10000) }}<span>()</span></span
>
</div>
</div>
</el-card>
<el-card>
<div class="title">
<span class="icon el-icon-coin"></span>
Open API
</div>
<div class="content">
<div>
AppID <span>{{ form.tenantId }}</span>
</div>
<div class="secret">
AppSecret
<span> ****** </span>
<a class="reset" @click="handAppSecret">查看</a>
</div>
<div>
生成时间 <span>{{ form.apiSecretTime }}</span>
</el-card>
<div class="message">
<div class="message-box">
<el-card class="card">
<div slot="header" class="clearfix">
<span>客服消息</span>
</div>
<div class="content">
<div class="left">
<i class="icon el-icon-service"></i>
</div>
<div class="right">
<div class="num">99</div>
<div class="status">+2.3% <span>同比昨日</span></div>
</div>
</div>
</el-card>
<el-card class="card">
<div slot="header" class="clearfix">
<span>待发货</span>
</div>
<div class="content">
<div class="left" style="background-color: #ff8b89">
<i class="icon el-icon-truck"></i>
</div>
<div class="right">
<div class="num">99</div>
<div class="status">+2.3% <span>同比昨日</span></div>
</div>
</div>
</el-card>
<el-card class="card">
<div slot="header" class="clearfix">
<span>历史订单</span>
</div>
<div class="content">
<div class="left" style="background-color: #42d6bd">
<i class="icon el-icon-truck"></i>
</div>
<div class="right">
<div class="num">99</div>
<div class="status">+2.3% <span>同比昨日</span></div>
</div>
</div>
</el-card>
</div>
</div>
</el-card>
<el-card>
<div class="title">
<span class="icon el-icon-user"></span>
白名单
</div>
<div class="content">
<div style="display:flex">
<div> IP </div>
<div style=" word-wrap:break-word; word-break:break-all;margin-left: 10px;">{{ form.ipWhiteLists }}</div>
<div class="order">
<el-card class="ordercards">
<div class="left">
<div class="title">动态订单</div>
<div class="lines"></div>
<vue-seamless-scroll
:data="listData"
:class-option="optionHover"
class="orderShow"
>
<div
class="content"
v-for="(item, index) in listData"
:key="index"
>
{{ item.content }}
</div>
</vue-seamless-scroll>
</div>
</el-card>
</div>
</div>
</el-card>
</div>
<!-- 显示密钥 -->
<el-dialog
title="客户密钥"
:visible.sync="secret"
width="30%"
:before-close="closeSecret"
append-to-body
>
<div class="descriptions">
<div
class="item-body"
:style="{ width: width ? width : '100%' }"
:key="label"
v-for="{ label, value, width, render } in seArr"
>
<div class="label">{{ label }}</div>
<div class="value">
<div ref="code">{{ value }}</div>
<div style="padding-left: 15px">
<el-button
class="tag-read"
type="text"
:data-clipboard-text="value"
@click="copy"
>复制</el-button
</div>
<div class="bottom">
<el-card class="data">
<div id="dataChars"></div>
</el-card>
<el-card class="sales">
<div class="title">商品销量</div>
<div>
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="date" label="排名"> </el-table-column>
<el-table-column prop="name" label="商品名称"> </el-table-column>
<el-table-column
prop="address"
label="销量"
sortable
align="right"
>
</div>
<Render v-if="render" :render="render" />
</el-table-column>
</el-table>
</div>
</div>
</el-card>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="secret = false"> </el-button>
</span>
</el-dialog>
</div>
</div>
</basic-container>
</template>
<script>
import { mapGetters } from "vuex";
import { getdetail } from "@/api/dashboard/index.js";
import Render from "@/components/Render/index.vue";
import Clipboard from "clipboard";
import * as math from "mathjs";
import * as echarts from "echarts";
export default {
components: {
Render,
},
data() {
return {
form: {
tenantName: "",
createTime: "",
creditBalance: 0,
creditAmount: 0,
apiSecretTime: "",
balance: "",
tenantId: "",
apiSecret: "",
linkman: "",
contactNumber: "",
ipWhiteLists: "",
},
secret: false, //
};
},
computed: {
...mapGetters(["userInfo"]),
//
seArr() {
return [
time: ["本月", "本日"],
timeIndex: 0,
listData: [
{
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
{
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
{
label: "App ID",
value: this.form.tenantId,
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
{
label: "AppSecret",
value: this.form.apiSecret,
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
];
{
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
{
content:
"2022-06-01 16:01:01用户123343434提交了一份19.9G流量套餐的商品购买",
},
],
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: 11,
},
{
date: "2016-05-04",
name: "王小虎",
address: 23,
},
{
date: "2016-05-01",
name: "王小虎",
address: 134,
},
{
date: "2016-05-03",
name: "王小虎",
address: 44,
},
],
};
},
computed: {
optionHover() {
return {
step: 0.5, //
limitMoveNum: 1, // this.dataList.length
hoverStop: true, // stop
direction: 1, // 0 1 2 3
openWatch: true, // dom
singleHeight: 0, // (0) direction => 0/1
singleWidth: 0, // (0) direction => 2/3
waitTime: 1000, // (1000ms)
};
},
},
created() {
this.detail(this.userInfo.tenant_id);
mounted() {
this.dataEchars();
},
methods: {
//
detail(id) {
getdetail(id).then((res) => {
if (res.data.code == 200) {
this.form = res.data.data;
}
});
},
//
handAppSecret() {
this.secret = true;
},
//
copy() {
var clipboard = new Clipboard(".tag-read");
clipboard.on("success", (e) => {
this.$message.success("复制成功");
clipboard.destroy();
});
clipboard.on("error", (e) => {
//
console.log("该浏览器不支持自动复制");
// a6e49f3ead9daa1f1a09e9d9ddb79b31
clipboard.destroy();
});
dataEchars() {
var chartDom = document.getElementById("dataChars");
var myChart = echarts.init(chartDom);
var option;
option = {
title: {
text: "实时数据",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
},
legend: {
data: ["套餐销售数量", "机器销售数量"],
},
toolbox: {
feature: {
saveAsImage: {},
},
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
boundaryGap: false,
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
],
yAxis: [
{
type: "value",
},
],
series: [
{
name: "套餐销售数量",
type: "line",
stack: "Total",
areaStyle: {},
emphasis: {
focus: "series",
},
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: "机器销售数量",
type: "line",
stack: "Total",
areaStyle: {},
emphasis: {
focus: "series",
},
data: [220, 182, 191, 234, 290, 330, 310],
},
],
};
option && myChart.setOption(option);
},
printFn(value) {
const precision = 14;
return Number(math.format(value, precision));
handleTime(index) {
this.timeIndex = index;
},
},
};
</script>
<style scoped lang="scss">
.infos {
width: 100%;
display: flex;
flex-wrap: wrap;
.el-card {
width: 30%;
.container {
.clearfix {
font-size: 17px;
font-weight: bold;
color: #333;
}
.top {
display: flex;
margin-left: 2%;
margin-top: 15px;
.content {
color: #555555;
font-size: 14px;
line-height: 3;
span {
margin-left: 10px;
}
.reset {
cursor: pointer;
margin: 0 20px;
color: blueviolet;
}
height: 230px;
justify-content: space-between;
.Turnover {
width: 20%;
height: 100%;
.ki-bar:first-child {
margin-top: 20px;
}
.ki-bar {
.money {
color: #427da9;
font-size: 32px;
margin-top: 30px;
text-align: center;
font-weight: bolder;
}
.secret {
.timeChange {
margin-top: 40px;
display: flex;
span {
width: 0;
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
align-items: center;
justify-content: center;
font-size: 14px;
margin-top: 50px;
.timebox {
text-align: center;
line-height: 25px;
background: #025fa7;
width: 60px;
height: 25px;
border-radius: 20px;
color: white;
}
.nocolor {
background: white;
color: #333;
}
}
}
}
}
.title {
color: #000c17;
font-weight: bold;
display: flex;
align-items: center;
padding-bottom: 20px;
.icon {
margin-right: 10px;
}
}
.hide {
visibility: hidden;
}
.bar-title {
color: #555555;
font-size: 14px;
display: flex;
align-items: baseline;
.label {
font-size: 16px;
font-weight: bold;
margin-right: 20px;
}
span {
font-size: 14px;
font-weight: normal;
}
}
.tips {
color: #cccccc;
margin-left: 10px;
}
.el-date-editor {
margin-left: auto;
}
.device {
margin-top: 20px;
display: flex;
.el-card:first-child {
flex: 1;
margin-right: 20px;
}
.el-card:last-child {
flex: 2;
padding-right: 20px;
}
.ki-bar,
.line-chart {
margin-top: 25px;
}
.not-active {
margin-top: 30px;
.message {
width: 78%;
height: 100%;
.message-box {
width: 100%;
height: 50%;
display: flex;
justify-content: space-between;
.card {
height: 100%;
width: 32%;
.content {
display: flex;
align-items: center;
.left {
width: 40px;
height: 40px;
background: #449add;
border-radius: 7px;
text-align: center;
line-height: 40px;
.icon {
font-size: 23px;
color: white;
}
}
.right {
margin-left: 20px;
.num {
font-size: 22px;
font-weight: bold;
color: #427da9;
}
.status {
font-size: 16px;
}
}
}
}
}
.order {
margin-top: 1%;
width: 100%;
height: 46%;
span {
font-size: 14px;
margin-left: 10px;
.ordercards {
height: 100%;
width: 100%;
overflow: hidden;
.left {
display: flex;
height: 50%;
.title {
width: 45px;
height: 45px;
font-size: 19px;
color: #333;
font-weight: bold;
text-align: center;
}
.lines {
width: 2px;
height: 60px;
background: #025fa7;
margin-left: 40px;
}
.orderShow {
margin-left: 40px;
.content {
font-size: 14px;
padding-bottom: 20px;
color: #333;
}
}
}
}
}
}
}
}
.message {
margin-top: 20px;
display: flex;
.title {
margin-bottom: 30px;
}
.el-card {
flex: 1;
}
.el-card:first-child {
margin-right: 20px;
}
.month {
font-size: 14px;
margin-top: 15px;
}
}
.descriptions {
display: flex;
flex-wrap: wrap;
border-left: 1px solid #ecedee;
border-top: 1px solid #ecedee;
.item-body {
.bottom {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
.label {
color: #73777a;
width: 80px;
background-color: #fbfbfc;
display: flex;
align-items: center;
}
.value {
color: #373d41;
width: 0;
flex: 1;
display: flex;
align-items: center;
height: 420px;
justify-content: space-between;
.data {
width: 68%;
#dataChars {
width: 100%;
height: 400px;
}
}
.label,
.value {
font-size: 12px;
padding: 8px;
display: flex;
align-items: center;
border-right: 1px solid #ecedee;
border-bottom: 1px solid #ecedee;
.sales {
width: 30%;
.title {
color: #333;
font-weight: bold;
font-size: 17px;
}
}
}
}

14
src/views/wel/index.vue

@ -1,27 +1,29 @@
<template>
<!-- <div class="app-container"> -->
<!-- <Clinent v-if="userInfo.tenant_id != '000000'" /> -->
<!-- <Administrator v-else /> -->
<!-- <Clinent></Clinent> -->
<!-- </div> -->
<div class="app-container">
<Buser v-if="userInfo.tenant_id != '000000'" />
<Administrator v-else />
<!-- <Buser v-else /> -->
</div>
<!-- <div class="app-container">
<div class="dashboard-container">
<div class="dashboard-text">欢迎访问物联网管理后台</div>
<div>
<img src="@/assets/shouye.png" alt class="dashboard-img" />
</div>
</div>
</div>
</div> -->
</template>
<script>
import { mapGetters } from "vuex";
import Clinent from "./component/clientside.vue";
import Administrator from "./component/Administrator.vue";
import Buser from "./component/Buser.vue";
export default {
components: {
Clinent,
Administrator,
Buser,
},
data() {
return {};

Loading…
Cancel
Save