123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- <template>
- <div class="global-variable">
- <!-- tab 切换 -->
- <el-tabs v-model="activeName" @tab-click="handleClick">
- <el-tab-pane
- v-for="item in menuItems"
- :key="item.component"
- :label="item.name"
- :name="item.component"
- />
- </el-tabs>
- <!-- 查询条件 -->
- <div class="searchbox">
- <p>
- 单位:
- <selecttree
- size="small"
- style="width: 180px"
- placeholder="请选择所属公司"
- :list="tabConditions[activeTab].parentOpt"
- type="1"
- v-model="tabConditions[activeTab].companyCode"
- @change="parentChange"
- :defaultParentProps="{
- children: 'children',
- label: 'companyName',
- value: 'codeNumber',
- }"
- />
- </p>
- <p>
- 风机:
- <el-select
- size="small"
- style="width: 150px"
- v-model="tabConditions[activeTab].unitvalue"
- @change="getchedian"
- placeholder="请选择"
- >
- <el-option
- v-for="item in tabConditions[activeTab].unitoptions"
- :key="item.engineCode"
- :label="item.engineName"
- :value="item.engineCode"
- />
- </el-select>
- </p>
- <p>
- 测点:
- <el-select
- v-model="tabConditions[activeTab].monitoringvalue"
- size="small"
- clearable
- placeholder="请选择"
- :disabled="activeTab === 'Temperature'"
- >
- <el-option
- v-for="item in tabConditions[activeTab].monitoringoptions"
- :key="item.itemKey"
- :label="item.itemValue"
- :value="item.itemKey"
- />
- </el-select>
- </p>
- <p>
- 采样频率:
- <el-select
- v-model="tabConditions[activeTab].frequencyvalue"
- size="small"
- clearable
- placeholder="请选择"
- :disabled="activeTab === 'Temperature'"
- >
- <el-option
- v-for="item in tabConditions[activeTab].frequencyoptions"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </p>
- <p>
- 时间:
- <el-date-picker
- size="small"
- v-model="tabConditions[activeTab].timevalue"
- type="datetimerange"
- range-separator="至"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- />
- <!-- :picker-options="datePickerOptions" -->
- </p>
- <el-button
- type="primary"
- size="small"
- @click="onSearchClick"
- class="search-btn"
- >查询</el-button
- >
- </div>
- <!-- 动态组件内容 -->
- <div class="main-body">
- <keep-alive>
- <component
- ref="activeComponent"
- :is="activeTab"
- :codedata="tabData[activeTab].codedata"
- v-bind="
- activeTab === 'Temperature'
- ? { echartsdata: tabData.Temperature.echartsdata }
- : {}
- "
- :totalCount="tabData[activeTab].totalCount"
- :totalPage="tabData[activeTab].totalPage"
- :fieldCode="tabConditions[activeTab].companyCode"
- :windTurbineNumber="tabConditions[activeTab].unitvalue"
- @updatePage="handlePageChange"
- />
- </keep-alive>
- </div>
- </div>
- </template>
- <script>
- import * as FileSaver from "file-saver";
- import * as XLSX from "xlsx";
- import {
- getSysOrganizationAuthTreeByRoleId,
- windEngineGrouPage,
- queryDetectionDic,
- } from "@/api/ledger.js";
- import selecttree from "../../components/selecttree.vue";
- import Bearing from "./components/malfunction/bearing.vue";
- import Dissymmetry from "./components/malfunction/dissymmetry.vue";
- import Gear from "./components/malfunction/gear.vue";
- import Loose from "./components/malfunction/loose.vue";
- import Misalignment from "./components/malfunction/misalignment.vue";
- import Temperature from "./components/malfunction/temperature.vue";
- import axios from "axios";
- export default {
- components: {
- selecttree,
- Bearing,
- Dissymmetry,
- Gear,
- Loose,
- Misalignment,
- Temperature,
- },
- data() {
- return {
- activeTab: "Bearing",
- activeName: "Bearing",
- menuItems: [
- {
- name: "轴承诊断",
- icon: require("@/assets/img/ZC.png"),
- component: "Bearing",
- },
- {
- name: "齿轮诊断",
- icon: require("@/assets/img/SZ.png"),
- component: "Gear",
- },
- {
- name: "不对中诊断",
- icon: require("@/assets/img/DZ.png"),
- component: "Dissymmetry",
- },
- {
- name: "不平衡诊断",
- icon: require("@/assets/img/DC.png"),
- component: "Misalignment",
- },
- {
- name: "松动诊断",
- icon: require("@/assets/img/SD.png"),
- component: "Loose",
- },
- {
- name: "温度诊断",
- icon: require("@/assets/img/WD.png"),
- component: "Temperature",
- },
- ],
- tabConditions: {
- Bearing: {},
- Gear: {},
- Dissymmetry: {},
- Misalignment: {},
- Loose: {},
- Temperature: {},
- },
- tabData: {
- Bearing: { codedata: [], totalCount: 0, totalPage: 0 },
- Gear: { codedata: [], totalCount: 0, totalPage: 0 },
- Dissymmetry: { codedata: [], totalCount: 0, totalPage: 0 },
- Misalignment: { codedata: [], totalCount: 0, totalPage: 0 },
- Loose: { codedata: [], totalCount: 0, totalPage: 0 },
- Temperature: {
- codedata: [],
- totalCount: 0,
- totalPage: 0,
- echartsdata: {},
- },
- },
- datePickerOptions: {
- onPick: ({ minDate, maxDate }) => {
- if (minDate && !maxDate) {
- const maxTime = new Date(
- minDate.getTime() + 30 * 24 * 60 * 60 * 1000
- );
- this.datePickerOptions.disabledDate = (time) => {
- return (
- time.getTime() < minDate.getTime() ||
- time.getTime() > maxTime.getTime()
- );
- };
- } else {
- this.datePickerOptions.disabledDate = () => false;
- }
- },
- disabledDate: () => false,
- },
- };
- },
- created() {
- for (const key in this.tabConditions) {
- this.tabConditions[key] = this.defaultCondition();
- }
- this.GETtree();
- },
- methods: {
- defaultCondition() {
- return {
- unitvalue: "",
- unitoptions: [],
- companyCode: "",
- parentOpt: [],
- timevalue: [],
- monitoringvalue: "",
- monitoringoptions: [],
- frequencyvalue: "",
- frequencyoptions: [],
- };
- },
- handleClick(tab) {
- this.activeTab = tab.name;
- },
- async GETtree() {
- const res = await getSysOrganizationAuthTreeByRoleId();
- const treedata = res.data;
- const processed = this.processTreeData(treedata);
- for (const key in this.tabConditions) {
- this.tabConditions[key].parentOpt = processed;
- }
- },
- parentChange(data) {
- const condition = this.tabConditions[this.activeTab];
- if (!data?.codeNumber) return;
- condition.unitvalue = "";
- condition.monitoringvalue = "";
- condition.frequencyvalue = "";
- windEngineGrouPage({
- fieldCode: data.codeNumber,
- pageNum: 1,
- pageSize: 99,
- }).then((res) => {
- condition.unitoptions = res.data.list;
- });
- axios
- .get(`/ETLapi/waveData/getAllSamplingFrequency/${data.codeNumber}`)
- .then((res) => {
- condition.frequencyoptions = (res.data.datas || [])
- .map(item => Number(item))
- .filter(num => num >= 12800)
- .map(num => num.toString());
- });
- condition.companyCode = data.codeNumber;
- },
- getchedian(value) {
- const condition = this.tabConditions[this.activeTab];
- const companyCode = condition.companyCode;
- axios
- .post(`/ETLapi/waveData/getAllMesurePointName/${companyCode}/${value}`)
- .then((res) => {
- condition.monitoringvalue = "";
- if (res.data.code === 500) {
- condition.monitoringoptions = [];
- this.$message({
- message: "当前风场不存在测点和采样频率数据" || "未知错误",
- type: "warning",
- });
- return;
- }
- if (res.data.code === 200) {
- const datas = Array.isArray(res.data.datas) ? res.data.datas : [];
- condition.monitoringoptions = datas;
- if (datas.length === 0) {
- this.$message({ message: "暂无数据", type: "warning" });
- }
- }
- })
- .catch((err) => {
- console.error("测点请求失败:", err);
- condition.monitoringoptions = [];
- });
- },
- processTreeData(treeData) {
- const processedData = [];
- function processNode(node) {
- if (node.codeType === "field") {
- node.companyName = node.fieldName;
- }
- if (node.children && node.children.length > 0) {
- node.children.forEach(processNode);
- }
- }
- treeData.forEach((root) => {
- processNode(root);
- processedData.push(root);
- });
- return processedData;
- },
- onSearchClick() {
- this.conditions(1, false); // 主动查询,第一页,非分页触发
- },
- handlePageChange(page) {
- this.conditions(page, true); // true 表示分页触发
- },
- conditions(page, isPageChange = false) {
- const tab = this.activeTab;
- this.$nextTick(() => {
- const comp = this.$refs.activeComponent;
- if (comp && typeof comp.reset === "function") {
- comp.reset();
- }
- });
- // 把后面接口请求部分放进延迟里,确保 reset 先执行完成
- setTimeout(() => {
- const condition = this.tabConditions[tab];
- if (tab === "Temperature") {
- const temperature = {
- windCode: condition.companyCode,
- windTurbineNumberList: [condition.unitvalue],
- startTime: this.$formatDateTWO(condition.timevalue[0]),
- endTime: this.$formatDateTWO(condition.timevalue[1]),
- pageNo: page,
- pageSize: 500,
- };
- const loading = this.$loading({
- lock: true,
- text: "温度诊断数据加载中,请稍候…",
- spinner: "el-icon-loading",
- background: "rgba(0, 0, 0, 0.8)",
- });
- const emptyEchartsData = {
- gearbox_oil: { timestamps: [], values: [] },
- generator_drive_end: { timestamps: [], values: [] },
- generator_nondrive_end: { timestamps: [], values: [] },
- main_bearing: { timestamps: [], values: [] },
- };
- const trendRequest = () => {
- const trendStart = performance.now();
- return axios
- .post("/AnalysisMulti/SPRT/trend", temperature)
- .then((res) => {
- const trendEnd = performance.now();
- console.log(
- `温度诊断 trend 接口耗时: ${(
- (trendEnd - trendStart) /
- 1000
- ).toFixed(2)}s`
- );
- const echartsdata = res.data.data || {};
- this.tabData[tab].echartsdata = echartsdata;
- })
- .catch((err) => {
- console.error("趋势图请求失败:", err);
- this.$message.error("温度趋势图数据请求失败,请稍后再试");
- });
- };
- const thresholdStart = performance.now();
- const thresholdReq = axios
- .post("/AnalysisMulti/temperature/threshold", temperature)
- .then((res) => {
- const thresholdEnd = performance.now();
- console.log(
- `温度诊断 threshold 接口耗时: ${(
- (thresholdEnd - thresholdStart) /
- 1000
- ).toFixed(2)}s`
- );
- const data = res.data.data.records || [];
- this.tabData[tab].codedata = data;
- this.tabData[tab].totalCount = res.data.data.totalSize || 0;
- if (!data.length) {
- this.$message.warning("暂无诊断数据");
- this.tabData[tab].echartsdata = emptyEchartsData;
- return Promise.resolve("skip trend");
- }
- return isPageChange ? Promise.resolve() : trendRequest();
- })
- .catch((err) => {
- console.error("温度诊断请求失败:", err);
- this.$message.error("温度诊断数据请求失败,请稍后再试");
- });
- Promise.resolve(thresholdReq).finally(() => {
- loading.close();
- });
- } else {
- const params = {
- samplingFrequency: condition.frequencyvalue,
- windCode: condition.companyCode,
- windTurbineNumberList: [condition.unitvalue],
- mesureNameList: [condition.monitoringvalue],
- startTime: this.$formatDateTWO(condition.timevalue[0]),
- endTime: this.$formatDateTWO(condition.timevalue[1]),
- pageNo: page,
- pageSize: 10,
- };
- const startTime = performance.now();
- axios
- .post("/ETLapi/waveData/getMesureDataWithSF", params)
- .then((res) => {
- const endTime = performance.now();
- console.log(
- `其他 tab 接口请求耗时: ${(endTime - startTime).toFixed(2)}ms`
- );
- const data = res.data || {};
- this.tabData[tab].codedata = data.datas || [];
- this.tabData[tab].totalCount = data.totalCount || 0;
- this.tabData[tab].totalPage = data.totalPage || 0;
- });
- }
- }, 300); // 延迟100毫秒执行接口请求逻辑
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .global-variable {
- padding: 10px;
- }
- .head {
- padding: 5px 0;
- display: flex;
- justify-content: space-between;
- ul {
- display: flex;
- width: 500px;
- height: 65px;
- justify-content: space-between;
- li {
- cursor: pointer;
- padding: 8px 12px 0 12px;
- border-radius: 4px;
- transition: all 0.3s;
- &:hover {
- background-color: #f0f0f0;
- }
- &.active {
- background-color: #e6f7ff;
- border-bottom: 2px solid var(--header-bg);
- span {
- color: var(--header-bg);
- font-weight: bold;
- }
- }
- .Simg {
- width: 30px;
- height: 30px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 0 auto;
- img {
- max-width: 100%;
- max-height: 100%;
- }
- }
- span {
- display: block;
- font-size: 12px;
- font-weight: 600;
- text-align: center;
- margin-top: 5px;
- }
- }
- }
- }
- .searchbox {
- display: flex;
- margin-bottom: 10px;
- align-items: center;
- flex-wrap: wrap;
- // padding-top: 10px;
- p {
- margin-right: 10px;
- margin-bottom: 0;
- margin-top: 10px;
- display: flex;
- align-items: center;
- .el-select,
- .el-date-picker {
- margin-left: 10px;
- }
- }
- .el-select {
- width: 180px;
- }
- .search-btn {
- margin-top: 10px;
- }
- }
- .main-body {
- margin-top: 10px;
- // border: 1px solid #ebeef5;
- border-radius: 4px;
- padding: 10px;
- background: #fff;
- }
- .el-range-editor.el-input__inner {
- width: 370px;
- }
- /* 放在你的组件 <style scoped> 或全局样式里 */
- .custom-loading-style .el-loading-spinner i {
- font-size: 26px;
- color: #409eff; /* Element UI 主色调,更柔和 */
- }
- .custom-loading-style .el-loading-text {
- font-size: 14px;
- color: #303133;
- letter-spacing: 0.5px;
- }
- </style>
|