| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854 |
- <template>
- <div class="mainBox">
- <!-- 搜索区域 -->
- <div class="searchBox">
- <div>
- <!-- 添加一个按钮触发事件 -->
- <!-- <el-button type="primary" @click="playTTS()">请求音频</el-button> -->
- <!-- 对比时间:
- <el-date-picker
- v-model="lastTimes"
- type="daterange"
- unlink-panels
- range-separator="到"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- disabled
- size="large"
- style="margin-right: 30px"
- /> -->
- 搜索时间:
- <el-date-picker
- v-model="nowTimes"
- type="daterange"
- unlink-panels
- range-separator="到"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- :shortcuts="shortcutsFun"
- size="large"
- />
- </div>
- </div>
- <!-- 服务调用card -->
- <div class="flex">
- <card
- v-for="item in TopCardDatas"
- :key="item.name"
- class="card flex"
- :title="item.name"
- :value="item.value"
- :growth="item.growth"
- :iconColor="item.iconColor"
- :upStatus="item.upStatus"
- />
- </div>
- <!-- 服务类信息统计 -->
- <div class="bigCard">
- <div class="bigCard_title">服务类信息统计</div>
- <div class="tools">
- <el-button>
- <el-icon><Upload /></el-icon> 导出数据
- </el-button>
- <el-button type="primary">
- <el-icon><TrendCharts /></el-icon>
- 详细报告
- </el-button>
- </div>
- <div class="flex">
- <div style="width: 48%; height: 400px">
- <EchartsDome :chartOption="chartOptions['服务调用趋势']" title="服务调用趋势" />
- </div>
- <div style="width: 48%; height: 400px">
- <EchartsDome title="服务类别分布" :chartOption="chartOptions['服务类别分布']" />
- </div>
- </div>
- <div style="width: 100%; height: 400px">
- <Table title="服务调用TOP10" :tableData="tableDatas" />
- </div>
- </div>
- <!-- 委办信息统计 -->
- <div class="bigCard">
- <div class="bigCard_title">委办信息统计</div>
- <div class="flex">
- <div style="width: 28%; height: 400px">
- <EchartsDome :chartOption="chartOptions['委办分布']" title="委办分布" />
- </div>
- <div style="width: 68%; height: 400px">
- <EchartsDome
- :chartOption="chartOptions['委办活跃度趋势']"
- title="委办活跃度趋势"
- />
- </div>
- </div>
- <!-- <div style="width: 100%; height: 400px">
- <EchartsDome :chartOption="chartOptions['用户部门分布']" title="用户部门分布" />
- </div> -->
- </div>
- <!-- 应用类信息统计 -->
- <div class="bigCard">
- <div class="bigCard_title">应用类信息统计</div>
- <div class="flex">
- <div style="width: 58%; height: 400px">
- <EchartsDome
- :chartOption="chartOptions['热点应用TOP10排名']"
- title="热点应用TOP10排名"
- />
- </div>
- <div style="width: 38%; height: 400px">
- <EchartsDome :chartOption="chartOptions['应用状态分布']" title="应用状态分布" />
- </div>
- </div>
- </div>
- <!-- 数据类信息统计 -->
- <div class="bigCard">
- <div class="bigCard_title">数据类信息统计</div>
- <div class="flex">
- <div style="width: 50%; height: 400px">
- <EchartsDome :chartOption="chartOptions['数据类别分布']" title="数据类别分布" />
- </div>
- <div style="width: 50%; height: 400px">
- <EchartsDome :chartOption="chartOptions['数据质量评分']" title="数据质量评分" />
- </div>
- </div>
- </div>
- <!-- 区级特色信息统计 -->
- <div class="bigCard">
- <div class="bigCard_title">区级特色信息统计</div>
- <div class="flex" style="margin-top: 20px">
- <div class="flex_column" style="width: 28%; height: 420px">
- <card
- class="card2 flex"
- :title="'服务机构总数'"
- value="8"
- :growth="'较上个月增长了12%'"
- iconColor="#2563db"
- :upStatus="1"
- />
- <card
- class="card2 flex"
- :title="'服务总数'"
- value="100"
- :growth="'较上个月下降了12%'"
- iconColor="#16a34a"
- :upStatus="-1"
- />
- <card
- class="card2 flex"
- :title="'服务调用总次数'"
- value="1000"
- :growth="'较上个月增长了12%'"
- iconColor="#9333ea"
- :upStatus="1"
- />
- </div>
- <div style="width: 68%; height: 420px">
- <EchartsDome :chartOption="chartOptions['服务调用趋势']" title="服务调用趋势" />
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import card from "@/components/yxgl/card.vue";
- import EchartsDome from "@/components/yxgl/EchartsDome.vue";
- import Table from "@/components/yxgl/table.vue";
- import appCenter from "@/api/appCenter";
- import { color } from "echarts";
- export default {
- name: "",
- components: {
- card,
- EchartsDome,
- Table,
- },
- data() {
- return {
- // 比较的时间范围(默认60天到30天前,主要跟nowTimes有关系)
- lastTimes: [],
- // 当前选中的时间范围
- nowTimes: [],
- TopCardDatas: [
- {
- name: "委办总数",
- value: "-",
- growth: "--",
- iconColor: "#2563db",
- iconName: "OfficeBuilding",
- upStatus: 0,
- },
- {
- name: "系统总数",
- value: "-",
- growth: "--",
- iconColor: "#16a34a",
- iconName: "WalletFilled",
- upStatus: 0,
- },
- {
- name: "服务总数",
- value: "-",
- growth: "--",
- iconColor: "#9333ea",
- iconName: "TrendCharts",
- upStatus: 0,
- },
- {
- name: "服务调用总数",
- value: "-",
- growth: "--",
- iconColor: "#ca8a04",
- iconName: "TrendCharts",
- upStatus: 0,
- },
- ],
- shortcutsFun: this.shortcuts(),
- chartOptions: {},
- tableDatas: [],
- };
- },
- watch: {
- nowTimes: {
- handler(newVal, oldVal) {
- if (newVal !== oldVal && newVal.length > 0) {
- // 计算出比较的时间范围
- this.lastTimes = [
- this.$moment(
- new Date(
- new Date(newVal[0]).setTime(
- new Date(newVal[0]).getTime() -
- (newVal[1] - newVal[0]) -
- 24 * 60 * 60 * 1000
- )
- )
- ).format("YYYY-MM-DD 00:00:00"),
- this.$moment(new Date(newVal[0])).format("YYYY-MM-DD 00:00:00"),
- ];
- this.initChart();
- }
- },
- deep: true,
- // immediate: true,
- },
- },
- mounted() {
- this.$nextTick(() => {
- this.nowTimes = [
- new Date(new Date().setTime(new Date() - 3600 * 1000 * 24 * 30)),
- new Date(),
- ];
- });
- },
- methods: {
- playTTS() {
- const url = "http://192.168.2.8:8008/api/tts/audio";
- fetch(url, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- text: `纸扎铺的灯笼
- 深巷尽头的纸扎铺,夜半总飘出灯笼光。
- 我加班晚归,撞见铺门虚掩,昏黄的灯笼悬在檐下,穗子无风自动。老板低头扎纸人,指尖翻飞,纸人眉眼竟和巷口失踪的外卖员一模一样。
- “要灯笼吗?” 他头也不抬,声音像揉皱的黄纸。
- 我拔腿就跑,身后传来细碎的脚步声。回头看,那盏灯笼悠悠跟着,灯笼里的烛火,映出一张纸糊的脸。
- 次日清晨,巷口多了一盏新灯笼,上面贴着我的名字。`,
- }),
- })
- .then((response) => response.blob()) // 转换为Blob对象
- .then((blob) => {
- const audio = new Audio();
- const blobUrl = window.URL.createObjectURL(blob);
- audio.src = blobUrl;
- audio.play();
- audio.onended = () => {
- window.URL.revokeObjectURL(blobUrl);
- };
- })
- .catch((error) => {
- console.error("TTS请求失败:", error);
- });
- },
- initChart() {
- // 获取运行管理页面数据
- appCenter
- .getAllYxglDatas({
- nowTimes: [
- this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD 00:00:00"),
- this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD 23:59:59"),
- ],
- lastTimes: this.lastTimes,
- })
- .then((res) => {
- if (res && res.code == 200) {
- this.TopCardDatas = res.content.TopCardDatas;
- this.dataToOption(
- "服务调用趋势",
- "line",
- [...res.content.serviceCountTrend],
- {
- legend: { data: ["调用次数"] },
- xData: [],
- xKey: "key",
- xFormart: "YYYY-MM-DD",
- yAxis: {
- type: "value",
- name: "调用次数",
- axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
- },
- yData: {
- key: "value",
- name: "调用次数",
- color: "#42a5f5",
- data: [],
- yAxisIndex: 0,
- },
- }
- );
- // 初始化服务类别分布,这个地方需要先根据serviceType进行groupBy统计调用次数
- this.dataToOption("服务类别分布", "pie", [...res.content.serviceCountType], {
- pieKey: { value: "value", name: "key" },
- pieData: [],
- });
- // 服务调用TOP10《cPathComment+cUnit,调用次数》
- let serviceDatas = [];
- serviceDatas = res.content.serviceCountTop;
- // 排序
- serviceDatas.sort((a, b) => b.c_count - a.c_count);
- this.initTableDatas(serviceDatas.slice(0, 10));
- // 委办分布
- this.dataToOption("委办分布", "pie", [...res.content.serviceCountUnit], {
- pieKey: { value: "value", name: "key" },
- pieData: [],
- legend: {
- bottom: 10,
- },
- radius: "60%",
- padAngle: 0,
- borderRadius: 0,
- label: {},
- });
- // 先清洗一下res.content.serviceCountUnitTrend
- let serviceCountUnitTrend = [];
- serviceCountUnitTrend = res.content.serviceCountUnitTrend;
- let serviceCountUnitTrendLegend = [];
- let itemData = serviceCountUnitTrend[0];
- for (let key in itemData) {
- if (key !== "key") {
- serviceCountUnitTrendLegend.push(key);
- }
- }
- this.dataToOption(
- "委办活跃度趋势",
- "line",
- [...res.content.serviceCountUnitTrend],
- {
- legend: { data: serviceCountUnitTrendLegend },
- xData: [],
- xKey: "key",
- xFormart: "YYYY-MM-DD",
- yAxis: {
- type: "value",
- axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
- },
- yDatas: { auto: true },
- }
- );
- let serviceDatas2 = [];
- serviceDatas2 = res.content.serviceCountApplicationTop;
- // 排序
- serviceDatas2.sort((a, b) => a.c_count - b.c_count);
- // 用户部门分布
- this.dataToOption("热点应用TOP10排名", "bar", serviceDatas2.slice(0, 10), {
- showLegend: false,
- xData: [],
- xKey: "c_application",
- yData: {
- key: "c_count",
- name: "调用次数",
- color: "#42a5f5",
- data: [],
- },
- });
- // 数据类别分布
- if (res.content.dataTypes && res.content.dataTypes.length > 0) {
- this.dataToOption("数据类别分布", "pie", [...res.content.dataTypes], {
- pieKey: { value: "count", name: "service_name" },
- pieData: [],
- legend: {
- bottom: 10,
- },
- radius: "60%",
- padAngle: 0,
- borderRadius: 0,
- label: {},
- });
- }
- // console.log("getAllYxglDatas", res);
- }
- });
- // 应用状态分布,cloumnId:1659
- appCenter
- .getDmsDataList({
- columnId: 1659,
- pageSize: 1000,
- page: 0,
- })
- .then((res) => {
- if (res.code == 200) {
- let dmsDatas = res.content.data;
- let tableDatas = [];
- // 根据状态进行groupBy统计个数
- let statusMap = {};
- dmsDatas.forEach((item) => {
- if (statusMap[item.appstauts + ""]) {
- statusMap[item.appstauts + ""] += 1;
- } else {
- statusMap[item.appstauts + ""] = 1;
- }
- });
- // 转换为数组
- for (let key in statusMap) {
- if (statusMap[key] && key) {
- tableDatas.push({
- name: this.$getDmsTypes("appstatus", key),
- value: statusMap[key],
- });
- }
- }
- this.dataToOption("应用状态分布", "pie", tableDatas, {
- pieKey: { value: "value", name: "name" },
- pieData: [],
- });
- } else {
- this.$message({
- type: "error",
- message: "服务器忙碌,请稍后重试!",
- });
- }
- });
- this.dataToOption("数据质量评分", "radar", null, null);
- },
- /**
- * 数据转换为图表选项
- * @param title 图表标题
- * @param type 图表类型
- * @param datas 原始数据
- * @param keyRule 解析规则
- */
- async dataToOption(title, type, datas, keyRule) {
- // 根据规则解析数据
- if (keyRule) {
- datas.forEach((item) => {
- // 有的图表没有X轴
- if (keyRule.xKey) {
- if (keyRule.xFormart) {
- item[keyRule.xKey] = this.$moment(item[keyRule.xKey]).format(
- keyRule.xFormart
- );
- }
- keyRule.xData.push(item[keyRule.xKey]);
- }
- if (keyRule.yData) {
- keyRule.yData.data.push(item[keyRule.yData.key]);
- keyRule.series = [
- {
- name: keyRule.yData.name,
- type: "line",
- smooth: true,
- data: keyRule.yData.data,
- lineStyle: {
- color: keyRule.yData.color ? keyRule.yData.color : "",
- type: keyRule.yData.ifDashed ? "dashed" : "",
- }, // 蓝色线条
- itemStyle: keyRule.yData.color,
- symbol: "circle", // 节点形状
- symbolSize: 6, // 节点大小
- },
- ];
- }
- if (keyRule.yDatas) {
- // 先根据lenged得到data集合
- for (let name of keyRule.legend.data) {
- if (keyRule.yDatas[name]) {
- keyRule.yDatas[name].data.push(item[name]);
- } else {
- keyRule.yDatas[name] = {
- name: name,
- data: [item[name]],
- };
- }
- }
- }
- if (keyRule.pieKey) {
- keyRule.pieData.push({
- value: item[keyRule.pieKey.value],
- name: item[keyRule.pieKey.name],
- });
- }
- });
- // 专门用来处理多y数据的series
- if (keyRule.yDatas) {
- keyRule.series = [];
- for (let name of keyRule.legend.data) {
- keyRule.series.push({
- name: name,
- type: "line",
- smooth: true,
- data: keyRule.yDatas[name].data,
- symbol: "circle", // 节点形状
- symbolSize: 6, // 节点大小
- });
- }
- }
- }
- let _option = {};
- switch (type) {
- case "line":
- // 折线图基础
- _option = {
- legend: {
- data: keyRule.legend.data,
- },
- tooltip: {
- show: true,
- trigger: "axis",
- axisPointer: { type: "shadow" },
- },
- // 默认样式
- xAxis: {
- type: "category",
- data: keyRule.xData,
- axisTick: { show: false }, // 隐藏刻度
- splitLine: { show: false }, // 隐藏分割线
- axisLabel: {
- color: "#F2F3F5cc", // 字体颜色(支持十六进制、RGB、颜色名)
- fontSize: 14, // 可选:字体大小
- fontWeight: "normal", // 可选:字体粗细
- },
- },
- yAxis: {
- type: "value",
- axisLabel: {
- color: "#42a5f5cc", // 字体颜色(支持十六进制、RGB、颜色名)
- fontSize: 14, // 可选:字体大小
- fontWeight: "normal", // 可选:字体粗细
- },
- splitLine: { lineStyle: { color: "#42a5f532" } },
- },
- series: keyRule.series,
- };
- break;
- case "pie":
- // 饼状图
- _option = {
- tooltip: {
- trigger: "item",
- },
- legend: keyRule.legend
- ? keyRule.legend
- : {
- orient: "vertical",
- top: "50%",
- right: 10,
- },
- series: [
- {
- name: title,
- type: "pie",
- radius: keyRule.radius ? keyRule.radius : ["40%", "70%"],
- avoidLabelOverlap: false,
- padAngle: keyRule.padAngle != undefined ? keyRule.padAngle : 5,
- itemStyle: {
- borderRadius:
- keyRule.borderRadius != undefined ? keyRule.borderRadius : 10,
- },
- label:
- keyRule.label != undefined
- ? keyRule.label
- : {
- show: false,
- position: "center",
- },
- emphasis: {
- label: {
- show: true,
- fontSize: 20,
- fontWeight: "bold",
- },
- },
- labelLine: {
- show: true,
- },
- data: keyRule.pieData,
- },
- ],
- };
- break;
- case "bar":
- // 柱状图
- _option = {
- tooltip: {
- trigger: "axis",
- axisPointer: {
- type: "shadow",
- },
- },
- legend: {
- show: keyRule.showLegend ? keyRule.showLegend : false,
- data: keyRule.legend,
- },
- xAxis: {
- type: "value",
- axisLabel: {
- color: "#42a5f5cc", // 字体颜色(支持十六进制、RGB、颜色名)
- fontSize: 14, // 可选:字体大小
- fontWeight: "normal", // 可选:字体粗细
- },
- splitLine: { lineStyle: { color: "#42a5f532" } },
- },
- yAxis: {
- type: "category",
- data: keyRule.xData,
- axisLabel: {
- color: "#F2F3F5cc", // 字体颜色(支持十六进制、RGB、颜色名)
- fontSize: 14, // 可选:字体大小
- fontWeight: "normal", // 可选:字体粗细
- },
- },
- series: [
- {
- name: keyRule.yData.name,
- type: "bar",
- label: {
- show: true,
- },
- emphasis: {
- focus: "series",
- },
- data: keyRule.yData.data,
- },
- ],
- };
- break;
- default:
- // 雷达图
- _option = {
- tooltip: {
- trigger: "axis",
- },
- legend: {
- show: false,
- left: "center",
- },
- radar: [
- {
- indicator: [
- { name: "健壮性", max: 100 },
- { name: "完整性", max: 100 },
- { name: "一致性", max: 100 },
- { name: "及时性", max: 100 },
- { name: "准确性", max: 100 },
- ],
- },
- ],
- series: [
- {
- type: "radar",
- areaStyle: {},
- data: [
- {
- value: [93, 85, 92, 95, 93],
- name: "",
- },
- ],
- },
- ],
- };
- break;
- }
- this.chartOptions[title] = _option;
- },
- // 服务调用列表
- initTableDatas(serviceTypeDatas2) {
- this.tableDatas = serviceTypeDatas2;
- },
- // 时间范围自定义时间
- shortcuts() {
- return [
- {
- text: "当天",
- value: () => {
- const end = new Date();
- const start = new Date();
- return [start, end];
- },
- },
- {
- text: "最近7天",
- value: () => {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
- return [start, end];
- },
- },
- {
- text: "最近30天",
- value: () => {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 29);
- return [start, end];
- },
- },
- {
- text: "最近90天",
- value: () => {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
- return [start, end];
- },
- },
- {
- text: "最近1年",
- value: () => {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 364);
- return [start, end];
- },
- },
- ];
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .mainBox {
- width: calc(100% - 60px);
- margin: 30px;
- & > div {
- margin: 20px 0;
- display: flex;
- }
- .card {
- width: calc(25% - 56px);
- border-radius: 5px;
- padding: 20px 18px;
- // background: #00000032;
- background: rgba(255, 255, 255, 0.1);
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
- }
- .card2 {
- width: 100%;
- border-radius: 5px;
- padding: 20px 18px;
- // background: rgba(255, 255, 255, 0.1);
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
- }
- .bigCard {
- width: calc(100% - 36px);
- border-radius: 5px;
- padding: 20px 18px;
- // background: #00000032;
- position: relative;
- flex-direction: column;
- background: rgba(255, 255, 255, 0.1);
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
- .tools {
- position: absolute;
- top: 20px;
- right: 20px;
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
- }
- &_title {
- font-size: 20px;
- font-weight: bold;
- }
- }
- .flex {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- }
- .flex_column {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: flex-start;
- box-sizing: border-box;
- }
- .searchBox {
- width: 100%;
- height: 50px;
- line-height: 50px;
- text-align: center;
- font-size: 20px;
- font-weight: bold;
- flex-direction: row-reverse;
- display: flex;
- }
- }
- // 日期选择框样式
- .demo-date-picker {
- display: flex;
- width: 100%;
- padding: 0;
- flex-wrap: wrap;
- }
- .demo-date-picker .block {
- padding: 1.5rem 0;
- text-align: center;
- border-right: solid 1px var(--el-border-color);
- flex: 1;
- min-width: 400px;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- .demo-date-picker .block:last-child {
- border-right: none;
- }
- .demo-date-picker .demonstration {
- display: block;
- color: var(--el-text-color-secondary);
- font-size: 14px;
- margin-bottom: 1rem;
- }
- @media screen and (max-width: 1200px) {
- .demo-date-picker .block {
- flex: 0 0 100%;
- padding: 1rem 0;
- min-width: auto;
- border-right: none;
- border-bottom: solid 1px var(--el-border-color);
- }
- .demo-date-picker .block:last-child {
- border-bottom: none;
- }
- }
- </style>
|