|
@@ -0,0 +1,621 @@
|
|
|
+<template>
|
|
|
+ <!-- 风机原始数据统计表页面 -->
|
|
|
+ <div class="history-analyse">
|
|
|
+ <!-- 页面头部 multiple多选属性 -->
|
|
|
+ <div class="form-wrapper">
|
|
|
+ <div class="search-wrapper">
|
|
|
+ <div class="search-item">
|
|
|
+ <span class="label">报警类型:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-select
|
|
|
+ v-model="state.typeVal"
|
|
|
+ size="mini"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ @change="changeType"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in state.typeList"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item">
|
|
|
+ <span class="label">场站:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-select
|
|
|
+ size="mini"
|
|
|
+ v-model="state.changZhan"
|
|
|
+ @change="changeChangzhan"
|
|
|
+ placeholder="全部场站"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in changZhanArray"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item" v-if="state.typeVal !== 'booststation'">
|
|
|
+ <span class="label">型号:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-select
|
|
|
+ size="mini"
|
|
|
+ v-model="state.modelId"
|
|
|
+ @change="changeModel"
|
|
|
+ placeholder="全部型号"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in modelList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item" v-if="state.typeVal !== 'booststation'">
|
|
|
+ <span class="label">部件:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-select
|
|
|
+ v-model="state.components"
|
|
|
+ multiple
|
|
|
+ size="mini"
|
|
|
+ collapse-tags
|
|
|
+ clearable
|
|
|
+ placeholder="全部部件"
|
|
|
+ @change="changeComponents"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in componentList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.nemCode"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item" v-if="state.typeVal !== 'booststation'">
|
|
|
+ <span class="label">报警描述:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-select
|
|
|
+ v-model="state.alarmIds"
|
|
|
+ multiple
|
|
|
+ size="mini"
|
|
|
+ clearable
|
|
|
+ collapse-tags
|
|
|
+ placeholder="全部描述"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in state.alarmIdList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.description"
|
|
|
+ :value="item.alarmId"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item">
|
|
|
+ <span class="label">开始日期:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-date-picker
|
|
|
+ size="mini"
|
|
|
+ v-model="state.starttime"
|
|
|
+ type="datetime"
|
|
|
+ placeholder="选择日期"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item">
|
|
|
+ <span class="label">结束日期:</span>
|
|
|
+ <div class="search-content">
|
|
|
+ <el-date-picker
|
|
|
+ size="mini"
|
|
|
+ v-model="state.endtime"
|
|
|
+ type="datetime"
|
|
|
+ placeholder="选择日期"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="btns">
|
|
|
+ <el-button class="buttons" size="mini" round @click="getTableList"
|
|
|
+ >查询</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 页面下部---统计表 -->
|
|
|
+ <div class="table_all">
|
|
|
+ <div class="leftContent">
|
|
|
+ <span>{{ pageTitle }}</span>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ :data="state.tableData"
|
|
|
+ stripe
|
|
|
+ height="calc(100% - 40px)"
|
|
|
+ @sort-change="handleSort"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ prop="wtname"
|
|
|
+ label="设备编号"
|
|
|
+ align="center"
|
|
|
+ width="80"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ :label="item.label"
|
|
|
+ v-for="(item, index) in state.tHeard"
|
|
|
+ :key="index"
|
|
|
+ :prop="item"
|
|
|
+ header-align="center"
|
|
|
+ show-overflow-tooltip
|
|
|
+ sortable="custom"
|
|
|
+ >
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="bar">
|
|
|
+ <div
|
|
|
+ class="bar-percent"
|
|
|
+ :style="{
|
|
|
+ width:
|
|
|
+ row[`${item.code}_count`] || row[`${item.code}_time`]
|
|
|
+ ? (row[`${item.code}_count`] /
|
|
|
+ (row[`${item.code}_count`] +
|
|
|
+ row[`${item.code}_time`])) *
|
|
|
+ 100 +
|
|
|
+ 'px'
|
|
|
+ : '0px',
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+ <span class="value">{{ row[`${item.code}_count`] }} 次数</span>
|
|
|
+ </div>
|
|
|
+ <div class="bar">
|
|
|
+ <div
|
|
|
+ class="bar-percent"
|
|
|
+ :style="{
|
|
|
+ width:
|
|
|
+ row[`${item.code}_count`] || row[`${item.code}_time`]
|
|
|
+ ? (row[`${item.code}_time`] /
|
|
|
+ (row[`${item.code}_count`] +
|
|
|
+ row[`${item.code}_time`])) *
|
|
|
+ 100 +
|
|
|
+ 'px'
|
|
|
+ : '0px',
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+ <span class="value">{{ row[`${item.code}_time`] }} 分钟</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <el-dialog
|
|
|
+ v-model="dialogVisible"
|
|
|
+ width="80%"
|
|
|
+ :before-close="dialogClose"
|
|
|
+ custom-class="currentPdfDialogStyle"
|
|
|
+ >
|
|
|
+ <el-table
|
|
|
+ :data="DataDetail"
|
|
|
+ border
|
|
|
+ :cell-class-name="tableCell"
|
|
|
+ :header-row-class-name="tableRowClassName"
|
|
|
+ height="600px"
|
|
|
+ @row-click="handle"
|
|
|
+ >
|
|
|
+ <el-table-column prop="windturbineId" label="风机编号" align="center" />
|
|
|
+ <el-table-column prop="alarmName" label="报警名称" align="center" />
|
|
|
+ <el-table-column prop="alarmDate" label="时间" align="center" />
|
|
|
+ <el-table-column prop="type" label="类型(触发/解除)" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <!-- <span v-if="scope.row.type === 1">触发</span>
|
|
|
+ <span v-if="scope.row.type === 0">解除</span> -->
|
|
|
+ {{ scope.row.type === 1 ? "触发" : "解除" }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-dialog>
|
|
|
+ <!-- <el-pagination
|
|
|
+ small
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next"
|
|
|
+ :current-page="pageParam.pagenum"
|
|
|
+ :page-size="pageParam.pagesize"
|
|
|
+ :total="pageParam.total"
|
|
|
+ @current-change="changePage"
|
|
|
+ ></el-pagination> -->
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { useStore } from "vuex";
|
|
|
+import BASE from "@tools/basicTool.js";
|
|
|
+import {
|
|
|
+ ref,
|
|
|
+ onMounted,
|
|
|
+ watch,
|
|
|
+ reactive,
|
|
|
+ computed,
|
|
|
+ onUnmounted,
|
|
|
+ nextTick,
|
|
|
+} from "vue";
|
|
|
+import {
|
|
|
+ getAlarmCountList,
|
|
|
+ fetchModel,
|
|
|
+ fetchRelatePartAndAlarmType,
|
|
|
+ GetAlarmId,
|
|
|
+ getWpList,
|
|
|
+} from "@/api/zhbj/index.js";
|
|
|
+import dayjs from "dayjs";
|
|
|
+onMounted(() => {
|
|
|
+ getWpArray();
|
|
|
+ getequipmentmodel_list();
|
|
|
+ getfetchRelatePart();
|
|
|
+ // getTableList();
|
|
|
+});
|
|
|
+const pageTitle = "报警分析";
|
|
|
+const store = useStore();
|
|
|
+const changZhanArray = ref([]);
|
|
|
+const state = reactive({
|
|
|
+ typeVal: "windturbine",
|
|
|
+ typeList: [
|
|
|
+ {
|
|
|
+ label: "升压站",
|
|
|
+ value: "booststation",
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // label: "自定义",
|
|
|
+ // value: "custom",
|
|
|
+ // },
|
|
|
+ {
|
|
|
+ label: "风机",
|
|
|
+ value: "windturbine",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "光伏",
|
|
|
+ value: "inverter",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ tableData: [],
|
|
|
+ tHeard: [],
|
|
|
+ changZhan: "",
|
|
|
+ components: "", //部件
|
|
|
+ modelId: "", //型号
|
|
|
+ alarmIds: "",
|
|
|
+ alarmIdList: [],
|
|
|
+ modelListAll: {},
|
|
|
+ fetchListAll: {},
|
|
|
+ starttime: dayjs().startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ endtime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ dialogVisible: false,
|
|
|
+});
|
|
|
+
|
|
|
+const changeType = (value) => {
|
|
|
+ state.typeVal = value;
|
|
|
+ getWpArray();
|
|
|
+};
|
|
|
+
|
|
|
+const getWpArray = async () => {
|
|
|
+ const { data } = await getWpList(state.typeVal);
|
|
|
+ changZhanArray.value = data;
|
|
|
+ if (state.typeVal != "booststation") {
|
|
|
+ state.changZhan =
|
|
|
+ state.typeVal == "windturbine" ? "SXJ_KGDL_DJY_FDC_STA" : "";
|
|
|
+ } else {
|
|
|
+ state.changZhan = "";
|
|
|
+ state.modelId = "";
|
|
|
+ getTableList();
|
|
|
+ }
|
|
|
+};
|
|
|
+// 机型
|
|
|
+const getequipmentmodel_list = async () => {
|
|
|
+ const { data } = await fetchModel();
|
|
|
+ state.modelListAll = data;
|
|
|
+};
|
|
|
+//所属部件
|
|
|
+const getfetchRelatePart = async () => {
|
|
|
+ const { data } = await fetchRelatePartAndAlarmType();
|
|
|
+ state.fetchListAll = data;
|
|
|
+};
|
|
|
+//型号列表
|
|
|
+const modelList = computed(() => {
|
|
|
+ if (state.changZhan == "") {
|
|
|
+ return [];
|
|
|
+ } else {
|
|
|
+ return state.modelListAll[state.changZhan];
|
|
|
+ }
|
|
|
+});
|
|
|
+//部件列表
|
|
|
+const componentList = computed(() => {
|
|
|
+ if (state.changZhan == "") {
|
|
|
+ return [];
|
|
|
+ } else {
|
|
|
+ if (state.changZhan.includes("FDC")) {
|
|
|
+ return state.fetchListAll?.fjbj;
|
|
|
+ } else {
|
|
|
+ return state.fetchListAll?.gfbj;
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+watch(
|
|
|
+ () => [modelList, componentList],
|
|
|
+ (val) => {
|
|
|
+ if (state.typeVal != "booststation") {
|
|
|
+ let arr = val.map((item) => item.value);
|
|
|
+ if (arr[0] && arr[0].length && arr[1] && arr[1].length) {
|
|
|
+ state.modelId = [arr[0][0]?.nemCode];
|
|
|
+ let componenDefaultSelect =
|
|
|
+ arr[1]?.find((ele) => {
|
|
|
+ return ele.nemCode === "ZZ";
|
|
|
+ })?.nemCode || "";
|
|
|
+ componenDefaultSelect
|
|
|
+ ? (state.components = [componenDefaultSelect])
|
|
|
+ : arr[1]?.[0]?.nemCode
|
|
|
+ ? (state.components = [arr[1]?.[0]?.nemCode])
|
|
|
+ : (state.components = []);
|
|
|
+ getAlarmId();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ immediate: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+function changeModel(val) {
|
|
|
+ state.modelId = val;
|
|
|
+ getAlarmId();
|
|
|
+}
|
|
|
+function changeComponents(val) {
|
|
|
+ state.components = val;
|
|
|
+ getAlarmId();
|
|
|
+}
|
|
|
+function changeChangzhan(val) {
|
|
|
+ state.changZhan = val;
|
|
|
+ if (state.typeVal != "booststation") {
|
|
|
+ getAlarmId();
|
|
|
+ }
|
|
|
+}
|
|
|
+function getAlarmId() {
|
|
|
+ GetAlarmId({
|
|
|
+ components: state.components,
|
|
|
+ modelId: state.modelId,
|
|
|
+ wpId: state.changZhan,
|
|
|
+ }).then(({ data }) => {
|
|
|
+ state.alarmIdList = data;
|
|
|
+ state.alarmIds = [];
|
|
|
+ // state.alarmIds =
|
|
|
+ // data.length <= 5
|
|
|
+ // ? data.map((item) => item.alarmId)
|
|
|
+ // : data.slice(0, 5).map((item) => item.alarmId);
|
|
|
+ getTableList();
|
|
|
+ });
|
|
|
+}
|
|
|
+// 获取列表数据 调用接口
|
|
|
+function getTableList() {
|
|
|
+ if (state.components?.length) {
|
|
|
+ getAlarmCountList({
|
|
|
+ stationid: state.changZhan || "",
|
|
|
+ begin: state.starttime,
|
|
|
+ end: state.endtime,
|
|
|
+ timeType: "m",
|
|
|
+ components: state.typeVal === "booststation" ? "" : state.components,
|
|
|
+ modelId: state.modelId,
|
|
|
+ alarmIds: state.alarmIds,
|
|
|
+ alarmType: state.typeVal,
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.length) {
|
|
|
+ let tableData = [];
|
|
|
+ let tHeard = [];
|
|
|
+ let data = res;
|
|
|
+ data.forEach((pEle) => {
|
|
|
+ for (let wtId in pEle) {
|
|
|
+ let wtItem = data.find((tableItem) => {
|
|
|
+ return wtId === tableItem.windturbineId;
|
|
|
+ });
|
|
|
+ !wtItem && (wtItem = { wtId });
|
|
|
+ pEle[wtId].forEach((cEle) => {
|
|
|
+ let someRes = tHeard.some((findEle) => {
|
|
|
+ return findEle.label == cEle.alertText;
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!someRes) {
|
|
|
+ tHeard.push({
|
|
|
+ label: cEle.alertText,
|
|
|
+ code: cEle.alarmid,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ wtItem[`${cEle.alarmid}_count`] = cEle.count;
|
|
|
+ wtItem[`${cEle.alarmid}_time`] = cEle.time;
|
|
|
+ wtItem["wtname"] = cEle.windturbineCode;
|
|
|
+ });
|
|
|
+ tableData.push(wtItem);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ state.tHeard = tHeard;
|
|
|
+ state.tableData = tableData;
|
|
|
+ } else {
|
|
|
+ state.tHeard = [];
|
|
|
+ state.tableData = [];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ BASE.showMsg({
|
|
|
+ msg: "部件至少选择一项才可查询",
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleSort = function (val) {
|
|
|
+ let item = val.prop;
|
|
|
+ let list = JSON.parse(JSON.stringify(state.tableData));
|
|
|
+ if (val.order == "ascending") {
|
|
|
+ state.tableData = list.sort(compare(`${item.code}_count`));
|
|
|
+ } else if (val.order == "descending") {
|
|
|
+ state.tableData = list.sort(compare(`${item.code}_count`)).reverse();
|
|
|
+ }
|
|
|
+};
|
|
|
+//排序函数
|
|
|
+const compare = function (property) {
|
|
|
+ return function (a, b) {
|
|
|
+ var value1 = a[property];
|
|
|
+ var value2 = b[property];
|
|
|
+ return value1 - value2;
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+// // 单元格点击事件
|
|
|
+// handle(row, column, event, cell) {
|
|
|
+// let parts =
|
|
|
+// this.tHeard.find((ele) => {
|
|
|
+// return ele.label === column.label;
|
|
|
+// })?.parts || "";
|
|
|
+// getDialogData({
|
|
|
+// stationid: this.changZhan || "",
|
|
|
+// starttime: dayjs(this.starttime).format("YYYY-MM-DD"),
|
|
|
+// endtime: dayjs(this.endtime).format("YYYY-MM-DD"),
|
|
|
+// windturbineid: row.wtId,
|
|
|
+// parts,
|
|
|
+// }).then((res) => {
|
|
|
+// if (res && res.status === 20000) {
|
|
|
+
|
|
|
+// if (res.data.length) {
|
|
|
+// if (column.property !== "wtId") {
|
|
|
+// this.DataDetail = res.data;
|
|
|
+// let tableArr = [];
|
|
|
+// res.data.forEach((currentItem) => {
|
|
|
+// // if (currentItem.type === 1) {
|
|
|
+// // currentItem.type = '触发'
|
|
|
+// // }
|
|
|
+// // else if (currentItem.type === 0) {
|
|
|
+// // currentItem.type = '解除'
|
|
|
+// // }
|
|
|
+// tableArr.push(currentItem);
|
|
|
+// });
|
|
|
+
|
|
|
+// this.dialogVisible = true;
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// BASE.showMsg({
|
|
|
+// msg: "所选风机暂无数据",
|
|
|
+// });
|
|
|
+// }
|
|
|
+// }
|
|
|
+// });
|
|
|
+// },
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.history-analyse {
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ padding: 0 20px;
|
|
|
+ padding-bottom: 10px;
|
|
|
+ .form-wrapper ::v-deep {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding-top: 10px;
|
|
|
+ position: relative;
|
|
|
+ .search-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 14px;
|
|
|
+ font-family: Microsoft YaHei;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #b3b3b3;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ .search-item {
|
|
|
+ display: flex;
|
|
|
+ margin-right: 10px;
|
|
|
+ max-width: 450px;
|
|
|
+ align-items: center;
|
|
|
+ .label {
|
|
|
+ margin-right: 10px;
|
|
|
+ text-align: right;
|
|
|
+ white-space: nowrap;
|
|
|
+ // width: 60px;
|
|
|
+ }
|
|
|
+ .search-content {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .btns {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ margin-right: 10px;
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 53px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .buttons {
|
|
|
+ background-color: rgba(5, 187, 76, 0.2);
|
|
|
+ border: 1px solid #3b6c53;
|
|
|
+ color: #b3b3b3;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(5, 187, 76, 0.5);
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .table_all {
|
|
|
+ height: calc(100% - 47px);
|
|
|
+ width: 100%;
|
|
|
+ .leftContent {
|
|
|
+ width: 242px;
|
|
|
+ height: 41px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: url("~@/assets/imgs/title_left_bg1.png") no-repeat;
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-size: 16px;
|
|
|
+ font-family: Microsoft YaHei;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #05bb4c;
|
|
|
+ margin-left: 25px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-table {
|
|
|
+ .el-table__row {
|
|
|
+ td {
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ cursor: auto;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ height: 16px;
|
|
|
+ margin: 8px 0;
|
|
|
+
|
|
|
+ .bar-percent {
|
|
|
+ height: 100%;
|
|
|
+ background: #05bb4c;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|