vibration.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. <template>
  2. <div class="global-variable">
  3. <div class="head">
  4. <div class="headleft">
  5. <div @click="generate('1')" class="picture">
  6. <img src="@/assets/analyse/03.png" alt="" />
  7. <p>时域图</p>
  8. </div>
  9. <div @click="generate('2')" class="picture">
  10. <img src="@/assets/analyse/04.png" alt="" />
  11. <p>频谱图</p>
  12. </div>
  13. <div @click="generate('3')" class="picture">
  14. <img src="@/assets/analyse/01.png" alt="" />
  15. <p>包络谱图</p>
  16. </div>
  17. <div @click="tendency" class="picture">
  18. <img src="@/assets/analyse/02.png" alt="" />
  19. <p>趋势图</p>
  20. </div>
  21. </div>
  22. <div class="headright">
  23. <img src="@/assets/analyse/07.png" alt="全部缩小" @click="suoxiao" />
  24. <img src="@/assets/analyse/05.png" alt="全部展开" @click="zhankai" />
  25. <img src="@/assets/analyse/06.png" alt="全部关闭" @click="guanbi" />
  26. </div>
  27. </div>
  28. <div class="searchbox">
  29. <p>
  30. 单位:
  31. <selecttree
  32. size="small"
  33. style="width: 180px"
  34. placeholder="请选择所属公司"
  35. :list="parentOpt"
  36. type="1"
  37. v-model="companyCode"
  38. @change="parentChange"
  39. :defaultParentProps="{
  40. children: 'children',
  41. label: 'companyName',
  42. value: 'codeNumber',
  43. }"
  44. >
  45. </selecttree>
  46. </p>
  47. <p>
  48. 风机:
  49. <el-select
  50. style="width: 150px"
  51. v-model="unitvalue"
  52. @change="getchedian"
  53. placeholder="请选择"
  54. size="small"
  55. >
  56. <el-option
  57. v-for="item in unitoptions"
  58. :key="item.engineCode"
  59. :label="item.engineName"
  60. :value="item.engineCode"
  61. >
  62. </el-option>
  63. </el-select>
  64. </p>
  65. <p>
  66. 测点:
  67. <el-select
  68. v-model="monitoringvalue"
  69. clearable
  70. size="small"
  71. placeholder="请选择"
  72. >
  73. <el-option
  74. v-for="item in monitoringoptions"
  75. :key="item.itemKey"
  76. :label="item.itemValue"
  77. :value="item.itemKey"
  78. >
  79. </el-option>
  80. </el-select>
  81. </p>
  82. <p>
  83. 时间:
  84. <el-date-picker
  85. v-model="timevalue"
  86. type="datetimerange"
  87. range-separator="至"
  88. start-placeholder="开始日期"
  89. end-placeholder="结束日期"
  90. size="small"
  91. >
  92. </el-date-picker>
  93. </p>
  94. <el-button type="primary" size="small" @click="conditions"
  95. >查询</el-button
  96. >
  97. <el-button size="small" @click="outputFile">导出</el-button>
  98. </div>
  99. <div class="main-body">
  100. <div class="data-map">
  101. <div
  102. class="chart-area"
  103. v-for="(item, index) in fourList"
  104. :key="item.index"
  105. @mouseover="setCurrent(item.rowData)"
  106. @mouseleave="setCurrent(oldCurrentRow)"
  107. >
  108. <div class="dialog-actions">
  109. <p>{{ item.name }}</p>
  110. <span>
  111. <i
  112. class="el-icon-minus"
  113. @click="lessen(index)"
  114. style="cursor: pointer; margin-right: 10px"
  115. ></i>
  116. <i
  117. class="el-icon-full-screen"
  118. @click="amplifier(index)"
  119. style="cursor: pointer; margin-right: 10px"
  120. ></i>
  121. <i
  122. class="el-icon-close"
  123. @click="close(index)"
  124. style="cursor: pointer"
  125. ></i>
  126. </span>
  127. </div>
  128. <div
  129. class="subject"
  130. :class="{
  131. minimized: item.isMinimized,
  132. }"
  133. v-loading="item.loading"
  134. >
  135. <!-- {{ item.rowData }} -->
  136. <p v-if="item.name != '趋势图'">
  137. 测点路径:{{
  138. NewgetDetectionPointCn(item?.rowData?.mesurePointName)
  139. }}-{{ item?.rowData?.windTurbineNumber }}
  140. <span>采样频率: {{ item?.rowData?.samplingFrequency }}(Hz)</span>
  141. <span
  142. >发电机转速: {{ item?.rowData?.rotationalSpeed }}(rpm)
  143. </span>
  144. <span>采样时间: {{ item?.rowData?.timeStamp }} </span>
  145. <!-- <span>有效值: {{XrmsValue}} (m/s2)</span> -->
  146. </p>
  147. <!-- {{ samplingTime }} -->
  148. <div v-if="item.name === '时域图'">
  149. <timedomaincharts
  150. :timeListTwo="item.timeListTwo"
  151. :currentIndex="currentIndex"
  152. :activeIndex="index"
  153. :tableDataList="tableDataList"
  154. :ids="[currentRow.id]"
  155. :currentRow="currentRow"
  156. :windCode="windCode"
  157. @update:currentIndex="handleCurrentIndexUpdate"
  158. @update-previous-row="goToPreviousRow"
  159. @update-next-row="goToNextRow"
  160. @handleLoading="handleLoading"
  161. ></timedomaincharts>
  162. </div>
  163. <div v-if="item.name === '频谱图'">
  164. <spectrogramcharts
  165. @updateXrms="handleXrmsUpdate"
  166. :spectrumListTwo="item.spectrumListTwo"
  167. :currentIndex="currentIndex"
  168. :tableDataList="tableDataList"
  169. :activeIndex="index"
  170. :ids="[currentRow.id]"
  171. :currentRow="currentRow"
  172. :windCode="windCode"
  173. @update:currentIndex="handleCurrentIndexUpdate"
  174. @update-previous-row="goToPreviousRow"
  175. @update-next-row="goToNextRow"
  176. @handleLoading="handleLoading"
  177. ></spectrogramcharts>
  178. </div>
  179. <div v-if="item.name === '包络谱图'">
  180. <envelopecharts
  181. @updateXrms="handleXrmsUpdate"
  182. :envelopeListTwo="item.envelopeListTwo"
  183. :currentIndex="currentIndex"
  184. :tableDataList="tableDataList"
  185. :activeIndex="index"
  186. :currentRow="currentRow"
  187. :ids="[currentRow.id]"
  188. :windCode="windCode"
  189. @update:currentIndex="handleCurrentIndexUpdate"
  190. @update-previous-row="goToPreviousRow"
  191. @update-next-row="goToNextRow"
  192. @update:modelValue="handleModelUpdate"
  193. @handleLoading="handleLoading"
  194. ></envelopecharts>
  195. </div>
  196. <div v-if="item.name === '趋势图'">
  197. <tendencycharts
  198. :qsList="qsList"
  199. :activeIndex="index"
  200. ></tendencycharts>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. <div class="data-origin">
  206. <el-table
  207. height="600"
  208. ref="singleTable"
  209. :data="tableDataList"
  210. :current-row-key="currentIndex"
  211. @current-change="handleCurrentChange"
  212. highlight-current-row
  213. style="width: 100%"
  214. :row-class-name="tableRowClassName"
  215. id="Table1"
  216. >
  217. <el-table-column type="index" label="排序" fixed> </el-table-column>
  218. <el-table-column prop="timeStamp" label="采样时间" width="180px">
  219. </el-table-column>
  220. <el-table-column label="测点名称" width="150px">
  221. <template slot-scope="scope">
  222. {{
  223. pointNameMap[scope.row.mesurePointName] ||
  224. scope.row.mesurePointName
  225. }}
  226. </template>
  227. </el-table-column>
  228. <!-- <el-table-column prop="companyName" label="场站">
  229. {{ getCompanyLabel(scope.row.companyCode) }}
  230. </el-table-column> -->
  231. <el-table-column prop="windTurbineNumber" label="风机" width="120px">
  232. </el-table-column>
  233. <el-table-column
  234. prop="samplingFrequency"
  235. label="采样频率(Hz)"
  236. align="center"
  237. width="120px"
  238. >
  239. </el-table-column>
  240. <el-table-column
  241. prop="rotationalSpeed"
  242. label="发电机转速(rpm)"
  243. align="center"
  244. width="150px"
  245. >
  246. </el-table-column>
  247. </el-table>
  248. </div>
  249. </div>
  250. </div>
  251. </template>
  252. <script>
  253. import * as FileSaver from "file-saver";
  254. import * as XLSX from "xlsx";
  255. import {
  256. getSysOrganizationAuthTreeByRoleId,
  257. windEngineGrouPage,
  258. queryDetectionDic,
  259. } from "@/api/ledger.js";
  260. import selecttree from "../../components/selecttree.vue";
  261. import envelopecharts from "./components/envelopecharts.vue";
  262. import spectrogramcharts from "./components/spectrogramcharts.vue";
  263. import tendencycharts from "./components/tendencycharts.vue";
  264. import timedomaincharts from "./components/timedomaincharts.vue";
  265. import axios from "axios";
  266. // 放在 <script> 外部
  267. export default {
  268. components: {
  269. envelopecharts,
  270. spectrogramcharts,
  271. tendencycharts,
  272. timedomaincharts,
  273. selecttree,
  274. },
  275. data() {
  276. return {
  277. chartData: [],
  278. chartLabels: [],
  279. unitvale: "",
  280. company: "",
  281. companyoptions: [],
  282. unitvalue: "",
  283. unitoptions: [],
  284. monitoringvalue: "",
  285. monitoringoptions: [
  286. // {
  287. // detectionPointEn: "name",
  288. // detectionPointCn: "中文",
  289. // },
  290. ],
  291. fourList: [],
  292. currentRow: null, // 用于存储当前选中的行
  293. currentIndex: 0,
  294. isChartVisible: false,
  295. parentOpt: [],
  296. defaultdata: {},
  297. companyCode: "",
  298. windCode: "",
  299. maplist: {},
  300. timevalue: [], // 绑定 el-date-picker 的值
  301. startTime: "", // 开始时间
  302. endTime: "", // 结束时间
  303. tableDataList: [],
  304. samplingTime: "", // 采样时间
  305. timeListTwo: {},
  306. spectrumList: {},
  307. envelopeList: {},
  308. qsList: {},
  309. CdNamw: "",
  310. chartsData: {},
  311. shuju: {},
  312. spectrumListTwo: {},
  313. envelopeListTwo: {},
  314. oldCurrentRow: {},
  315. XrmsValue: 0, // 默认值
  316. pointNameMap: {
  317. main_bearing_radial_vertical_vibration: "主轴承径向垂直振动",
  318. main_bearing_radial_vibration: "主轴承径向振动",
  319. main_bearing_radial_horizontal_vibration: "主轴承径向水平振动",
  320. main_bearing_axial_vibration: "主轴承轴向振动",
  321. front_main_bearing_radial_vertical_vibration: "前主轴承径向垂直振动",
  322. front_main_bearing_radial_vibration: "前主轴承径向振动",
  323. front_main_bearing_radial_horizontal_vibration: "前主轴承径向水平振动",
  324. front_main_bearing_axial_vibration: "前主轴承轴向振动",
  325. generator_radial_1_vibration: "发电机径向1振动",
  326. generator_radial_2_vibration: "发电机径向2振动",
  327. generator_speed: "发电机转速",
  328. generator_non_drive_end_radial_vibration: "发电机非驱动端径向振动",
  329. generator_drive_end_radial_vibration: "发电机驱动端径向振动",
  330. rear_main_bearing_radial_vertical_vibration: "后主轴承径向垂直振动",
  331. rear_main_bearing_radial_vibration: "后主轴承径向振动",
  332. rear_main_bearing_radial_horizontal_vibration: "后主轴承径向水平振动",
  333. rear_main_bearing_axial_vibration: "后主轴承轴向振动",
  334. stator_radial_horizontal_vibration: "定子径向水平振动",
  335. gearbox_first_stage_planet_large_ring_radial_vibration:
  336. "齿轮箱一级行星级大齿圈径向振动",
  337. gearbox_first_stage_planet_radial_vibration: "齿轮箱一级行星级径向振动",
  338. gearbox_third_stage_planet_radial_vibration: "齿轮箱三级行星级径向振动",
  339. gearbox_second_stage_planet_large_ring_radial_vibration:
  340. "齿轮箱二级行星级大齿圈径向振动",
  341. gearbox_second_stage_planet_radial_vibration:
  342. "齿轮箱二级行星级径向振动",
  343. gearbox_second_stage_planet_axial_vibration: "齿轮箱二级行星级轴向振动",
  344. gearbox_low_speed_shaft_output_end_radial_vibration:
  345. "齿轮箱低速轴输出端径向振动",
  346. gearbox_input_end_radial_vibration: "齿轮箱输入端径向振动",
  347. gearbox_output_shaft_axial_vibration: "齿轮箱输出轴轴向振动",
  348. gearbox_high_speed_shaft_output_end_radial_vibration:
  349. "齿轮箱高速轴输出端径向振动",
  350. gearbox_high_speed_shaft_output_end_axial_vibration:
  351. "齿轮箱高速轴输出端轴向振动",
  352. },
  353. };
  354. },
  355. created() {
  356. this.GETtree();
  357. },
  358. watch: {
  359. // 监听 timeList 的变化
  360. currentRow(newVal, oldVal) {
  361. if (newVal) {
  362. // console.log(newVal, oldVal);
  363. this.oldCurrentRow = oldVal;
  364. } else {
  365. console.error("currentRow is undefined or null");
  366. }
  367. },
  368. },
  369. methods: {
  370. handleXrmsUpdate(value) {
  371. this.XrmsValue = value; // 更新有效值
  372. },
  373. handleLoading(currentRow, loading, activeIndex, params) {
  374. if (loading) {
  375. this.$set(this.fourList[activeIndex], "loading", loading);
  376. return;
  377. }
  378. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  379. this.$set(this.fourList[activeIndex], "loading", false);
  380. },
  381. onRowClick(row) {
  382. this.currentRow = row; // 选中行数据
  383. },
  384. getDetectionPointCn(detectionPointEn) {
  385. const point = this.monitoringoptions?.find(
  386. (option) => option.detectionPointEn === detectionPointEn
  387. );
  388. return point ? point?.detectionPointCn : null; // 如果没有找到对应项,返回 null
  389. },
  390. NewgetDetectionPointCn(key) {
  391. return this.pointNameMap[key] || key;
  392. },
  393. getCompanyLabel(companyCode) {
  394. const selectedOption = this.parentOpt?.find(
  395. (option) => option.codeNumber === companyCode
  396. );
  397. return selectedOption ? selectedOption.companyName : ""; // Return companyName or empty string if not found
  398. },
  399. // 获取风场
  400. async GETtree() {
  401. const res = await getSysOrganizationAuthTreeByRoleId();
  402. const treedata = res.data;
  403. const processedData = this.processTreeData(treedata);
  404. this.parentOpt = processedData;
  405. this.defaultdata = res.data[0];
  406. },
  407. parentChange(data) {
  408. this.maplist = data;
  409. this.maplistArr = data;
  410. let paramsData = {
  411. fieldCode: this.maplist.codeNumber,
  412. pageNum: 1,
  413. pageSize: 99,
  414. };
  415. this.unitvalue = "";
  416. this.monitoringvalue = "";
  417. // 获取风机
  418. windEngineGrouPage(paramsData).then((res) => {
  419. this.unitoptions = res.data.list;
  420. this.windCode = this.companyCode;
  421. });
  422. if (data.codeType === "field") {
  423. if (this.parseCoordinates(data.longitudeAndLatitudeString).length > 0) {
  424. return;
  425. }
  426. } else {
  427. const dataMapList = data.children;
  428. dataMapList.forEach((element) => {
  429. if (
  430. this.parseCoordinates(element.longitudeAndLatitudeString).length >
  431. 0 &&
  432. element.codeType === "field"
  433. ) {
  434. return;
  435. }
  436. });
  437. }
  438. },
  439. processTreeData(treeData) {
  440. const processedData = [];
  441. function processNode(node) {
  442. if (node.codeType === "field") {
  443. node.companyName = node.fieldName;
  444. }
  445. if (node.children && node.children.length > 0) {
  446. node.children.forEach((child) => {
  447. processNode(child);
  448. });
  449. }
  450. }
  451. treeData.forEach((root) => {
  452. processNode(root);
  453. processedData.push(root);
  454. });
  455. return processedData;
  456. },
  457. parseCoordinates(input) {
  458. if (input && typeof input === "string") {
  459. return input.split(",").map(Number);
  460. }
  461. // debugger;
  462. return [];
  463. },
  464. // 获取测点
  465. getchedian(value) {
  466. axios
  467. .post(
  468. `/ETLapi/waveData/getAllMesurePointName/${this.companyCode}/${value}`
  469. )
  470. .then((res) => {
  471. this.monitoringvalue = "";
  472. if (res.data.code === 500) {
  473. this.monitoringoptions = []; // 清空旧数据
  474. this.$message({
  475. message: res.data.message || "未知错误",
  476. type: "warning",
  477. });
  478. return;
  479. }
  480. if (res.data.code === 200) {
  481. const datas = Array.isArray(res.data.datas) ? res.data.datas : [];
  482. this.monitoringoptions = datas;
  483. if (datas.length === 0) {
  484. this.$message({
  485. message: "暂无数据",
  486. type: "warning",
  487. });
  488. }
  489. }
  490. })
  491. .catch((err) => {
  492. console.error("请求失败", err);
  493. this.monitoringoptions = []; // 防止报错后保持旧数据
  494. });
  495. },
  496. handleModelUpdate(data) {
  497. // 将子组件的值作为查询参数传递给查询接口
  498. this.xiaoval = data.xiaoval;
  499. this.daval = data.daval;
  500. },
  501. // 上一条数据
  502. goToPreviousRow(type, activeIndex) {
  503. if (this.tableDataList.length === 0) return;
  504. // 更新当前索引,向前循环
  505. this.currentIndex =
  506. this.currentIndex === 0
  507. ? this.tableDataList.length - 1
  508. : this.currentIndex - 1;
  509. const currentRow = this.tableDataList[this.currentIndex];
  510. this.setCurrent(currentRow);
  511. const params = {
  512. ids: currentRow.id,
  513. windCode: this.companyCode,
  514. // windCode: "SKF001",
  515. };
  516. // 根据type加载不同的数据
  517. if (type === 1) {
  518. // Type 1: 加载时域数据
  519. this.$set(this.fourList[activeIndex], "loading", true);
  520. params.analysisType = "time";
  521. axios
  522. .post("/AnalysisMulti/analysis/time", params)
  523. .then((res) => {
  524. const timeListTwo = JSON.parse(res.data);
  525. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  526. this.$set(this.fourList[activeIndex], "timeListTwo", timeListTwo);
  527. })
  528. .catch((error) => {
  529. console.error("Error fetching time domain data:", error);
  530. })
  531. .finally(() => {
  532. this.$set(this.fourList[activeIndex], "loading", false);
  533. });
  534. } else if (type === 2) {
  535. // Type 2: 加载频域数据
  536. this.$set(this.fourList[activeIndex], "loading", true);
  537. params.analysisType = "frequency";
  538. axios
  539. .post("/AnalysisMulti/analysis/frequency", params)
  540. .then((res) => {
  541. const spectrumListTwo = JSON.parse(res.data);
  542. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  543. this.$set(
  544. this.fourList[activeIndex],
  545. "spectrumListTwo",
  546. spectrumListTwo
  547. );
  548. })
  549. .catch((error) => {
  550. console.error("Error fetching frequency domain data:", error);
  551. })
  552. .finally(() => {
  553. this.$set(this.fourList[activeIndex], "loading", false);
  554. });
  555. } else if (type === 3) {
  556. // Type 3: 加载包络分析数据
  557. this.$set(this.fourList[activeIndex], "loading", true);
  558. params.analysisType = "envelope";
  559. params.fmin = this.xiaoval; // 最小频率参数
  560. params.fmax = this.daval; // 最大频率参数
  561. axios
  562. .post("/AnalysisMulti/analysis/envelope", params)
  563. .then((res) => {
  564. const envelopeListTwo = JSON.parse(res.data);
  565. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  566. this.$set(
  567. this.fourList[activeIndex],
  568. "envelopeListTwo",
  569. envelopeListTwo
  570. );
  571. })
  572. .catch((error) => {
  573. console.error("Error fetching envelope analysis data:", error);
  574. })
  575. .finally(() => {
  576. this.$set(this.fourList[activeIndex], "loading", false);
  577. });
  578. } else {
  579. console.warn("Unknown type provided:", type);
  580. }
  581. },
  582. // 下一条数据,向后循环
  583. goToNextRow(type, activeIndex) {
  584. if (this.tableDataList.length === 0) return;
  585. // 更新当前索引
  586. this.currentIndex =
  587. this.currentIndex === this.tableDataList.length - 1
  588. ? 0
  589. : this.currentIndex + 1;
  590. const currentRow = this.tableDataList[this.currentIndex];
  591. this.setCurrent(currentRow);
  592. const params = {
  593. ids: currentRow.id,
  594. // windCode: "SKF001",
  595. windCode: this.companyCode,
  596. };
  597. // 根据type加载不同的数据
  598. if (type === 1) {
  599. // Type 1: 加载时域数据
  600. this.$set(this.fourList[activeIndex], "loading", true);
  601. params.analysisType = "time";
  602. axios
  603. .post("/AnalysisMulti/analysis/time", params)
  604. .then((res) => {
  605. const timeListTwo = JSON.parse(res.data);
  606. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  607. this.$set(this.fourList[activeIndex], "timeListTwo", timeListTwo);
  608. })
  609. .catch((error) => {
  610. console.error("Error fetching time data:", error);
  611. })
  612. .finally(() => {
  613. this.$set(this.fourList[activeIndex], "loading", false);
  614. });
  615. } else if (type === 2) {
  616. // Type 2: 加载频域数据
  617. this.$set(this.fourList[activeIndex], "loading", true);
  618. params.analysisType = "frequency";
  619. axios
  620. .post("/AnalysisMulti/analysis/frequency", params)
  621. .then((res) => {
  622. const spectrumListTwo = JSON.parse(res.data);
  623. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  624. this.$set(
  625. this.fourList[activeIndex],
  626. "spectrumListTwo",
  627. spectrumListTwo
  628. );
  629. })
  630. .catch((error) => {
  631. console.error("Error fetching frequency data:", error);
  632. })
  633. .finally(() => {
  634. this.$set(this.fourList[activeIndex], "loading", false);
  635. });
  636. } else if (type === 3) {
  637. // Type 3: 加载包络分析数据
  638. this.$set(this.fourList[activeIndex], "loading", true);
  639. params.analysisType = "envelope";
  640. params.fmin = this.xiaoval; // 最小频率
  641. params.fmax = this.daval; // 最大频率
  642. axios
  643. .post("/AnalysisMulti/analysis/envelope", params)
  644. .then((res) => {
  645. const envelopeListTwo = JSON.parse(res.data);
  646. this.$set(this.fourList[activeIndex], "rowData", currentRow);
  647. this.$set(
  648. this.fourList[activeIndex],
  649. "envelopeListTwo",
  650. envelopeListTwo
  651. );
  652. })
  653. .catch((error) => {
  654. console.error("Error fetching envelope analysis data:", error);
  655. })
  656. .finally(() => {
  657. this.$set(this.fourList[activeIndex], "loading", false);
  658. });
  659. }
  660. },
  661. // 更新父组件的 currentIndex
  662. handleCurrentIndexUpdate(newIndex) {
  663. this.currentIndex = newIndex;
  664. this.handleCurrentChange(newIndex);
  665. },
  666. tableRowClassName({ row }) {
  667. if (row === this.currentRow) {
  668. return "current-row-highlight"; // 自定义的高亮类名
  669. }
  670. return "";
  671. },
  672. // setCurrent(row) {
  673. // this.currentRow = row; // 设置当前行
  674. // },
  675. // 当前所在行高亮提示
  676. setCurrent(row) {
  677. if (!row) {
  678. return false;
  679. }
  680. this.$refs.singleTable.setCurrentRow(row);
  681. },
  682. // 当前单选
  683. handleCurrentChange(val) {
  684. this.currentRow = val;
  685. const index = this.tableDataList.indexOf(val);
  686. this.currentIndex = index; // 更新当前索引
  687. },
  688. generate(type) {
  689. if (!this.currentRow) {
  690. this.$message.warning("请先选择数据");
  691. return;
  692. }
  693. const nameMap = {
  694. 1: "时域图", // Time Domain Chart
  695. 2: "频谱图", // Spectrogram Chart
  696. 3: "包络谱图", // Envelope Spectrum Chart
  697. };
  698. const chartName = nameMap[type];
  699. if (chartName) {
  700. const newItem = {
  701. name: chartName,
  702. isMinimized: false,
  703. id: `chart-${Date.now()}`,
  704. };
  705. this.fourList.push(newItem);
  706. }
  707. },
  708. tendency() {
  709. if (this.tableDataList.length === 0) {
  710. this.$message.warning("数据为空,无法生成图表");
  711. return;
  712. }
  713. const newItem = {
  714. name: "趋势图",
  715. isMinimized: false,
  716. id: `chart-${Date.now()}`,
  717. };
  718. const params = {
  719. ids: this.tableDataList.map((item) => item.id),
  720. // windCode: "SKF001",
  721. windCode: this.companyCode,
  722. analysisType: "trend",
  723. };
  724. axios
  725. .post("/AnalysisMulti/analysis/trend", params)
  726. .then((res) => {
  727. let jsonStr = res.data;
  728. // ① 仅字符串才处理
  729. if (typeof jsonStr === "string") {
  730. // ② 将 "NaN" 或裸 NaN 替换为 null(更安全的方式)
  731. jsonStr = jsonStr.replace(/\bNaN\b/g, "null"); // 替换裸 NaN
  732. }
  733. // ③ 再解析为对象
  734. this.qsList = JSON.parse(jsonStr);
  735. this.fourList.push(newItem);
  736. })
  737. .catch((error) => {
  738. console.error("趋势图接口报错:", error);
  739. });
  740. },
  741. conditions() {
  742. const params = {
  743. windCode: this.maplist.codeNumber,
  744. windTurbineNumberList: [this.unitvalue],
  745. mesureNameList: [this.monitoringvalue],
  746. startTime: this.$formatDateTWO(this.timevalue[0]),
  747. endTime: this.$formatDateTWO(this.timevalue[1]),
  748. };
  749. // const params = {
  750. // endTime: "2024-07-02 00:00:00",
  751. // mesureNameList: ["gearbox_input_end_radial_vibration"],
  752. // startTime: "2024-07-01 00:00:00",
  753. // windCode: "SKF001",
  754. // windTurbineNumberList: ["F004"],
  755. // };
  756. const areParamsValid = (params) => {
  757. return (
  758. params.endTime &&
  759. params.startTime &&
  760. params.mesureNameList?.length > 0 &&
  761. params.windCode &&
  762. params.windTurbineNumberList?.length > 0
  763. );
  764. };
  765. if (areParamsValid(params)) {
  766. axios
  767. .post("/ETLapi/waveData/getMesureData", params)
  768. .then((res) => {
  769. this.tableDataList = res.data.datas;
  770. })
  771. .catch((error) => {
  772. console.error("Error:", error);
  773. // Handle the error here
  774. });
  775. } else {
  776. this.$message({
  777. message: "请填写全部条件",
  778. type: "warning",
  779. });
  780. }
  781. },
  782. // 缩小
  783. lessen(index) {
  784. if (!this.fourList[index].isMinimized) {
  785. this.fourList[index].isMinimized = true;
  786. }
  787. },
  788. // 放大
  789. amplifier(index) {
  790. const item = this.fourList[index];
  791. if (item.isMinimized) {
  792. item.isMinimized = false;
  793. }
  794. },
  795. // 关闭
  796. close(index) {
  797. this.fourList.splice(index, 1);
  798. },
  799. zhankai() {
  800. this.fourList.forEach((item) => {
  801. item.isMinimized = false;
  802. });
  803. },
  804. suoxiao() {
  805. this.fourList.forEach((item) => {
  806. item.isMinimized = true;
  807. });
  808. },
  809. guanbi() {
  810. this.fourList = [];
  811. },
  812. outputFile() {
  813. var ws1 = XLSX.utils.table_to_book(document.querySelector("#Table1")); //对应要导出的表格id
  814. var wbOut = XLSX.write(ws1, {
  815. bookType: "xlsx",
  816. bookSST: true,
  817. type: "array",
  818. });
  819. try {
  820. FileSaver.saveAs(
  821. new Blob([wbOut], { type: "application/octet-stream" }),
  822. "demo.xlsx"
  823. );
  824. } catch (e) {
  825. if (typeof console !== "undefined") console.log(e, wbOut);
  826. }
  827. return wbOut;
  828. },
  829. },
  830. };
  831. </script>
  832. <style lang="scss" scoped>
  833. .head {
  834. // border-top: 5px solid #088080;
  835. // border-bottom: 5px solid #088080;
  836. padding: 5px 0;
  837. display: flex;
  838. justify-content: space-between;
  839. .headleft {
  840. display: flex;
  841. .picture {
  842. cursor: pointer;
  843. display: inline-block;
  844. text-align: center;
  845. margin: 0 20px;
  846. font-size: 12px;
  847. img {
  848. width: 50px;
  849. height: 20px;
  850. }
  851. }
  852. }
  853. .headright {
  854. line-height: 38px;
  855. img {
  856. width: 20px;
  857. height: 20px;
  858. margin: 0 10px;
  859. cursor: pointer;
  860. }
  861. }
  862. }
  863. .searchbox {
  864. display: flex;
  865. margin: 10px 0;
  866. p {
  867. margin-right: 10px;
  868. }
  869. .el-select {
  870. width: 180px;
  871. }
  872. }
  873. .dialog-actions {
  874. text-align: right;
  875. padding: 0 10px;
  876. display: flex;
  877. justify-content: space-between;
  878. position: relative;
  879. }
  880. .subject {
  881. height: 350px;
  882. // overflow: hidden;
  883. // overflow-y: auto;
  884. transition: all 0.3s ease;
  885. padding: 0 10px;
  886. p {
  887. font-size: 10px;
  888. }
  889. }
  890. .main-body {
  891. display: flex;
  892. justify-content: space-between;
  893. align-items: flex-start;
  894. .data-map {
  895. width: 60%;
  896. .chart-area {
  897. margin-bottom: 10px;
  898. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
  899. &:hover {
  900. box-shadow: 0 2px 4px rgb(8, 128, 128, 0.13),
  901. 0 0 6px rgb(8, 128, 128, 0.11);
  902. // border: 1px solid #088080;
  903. }
  904. }
  905. }
  906. .data-map::-webkit-scrollbar {
  907. display: none; /* 隐藏滚动条 */
  908. }
  909. .data-origin {
  910. width: 39%;
  911. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
  912. }
  913. }
  914. .subject.minimized {
  915. height: 0px; /* Adjust height when minimized */
  916. overflow: hidden;
  917. }
  918. // ::v-deep .current-row td {
  919. // background-color: rgba(147, 226, 226, 0.2) !important; /* 高亮的背景颜色 */
  920. // color: #088080;
  921. // font-weight: 600;
  922. // }
  923. .el-input__inner {
  924. width: 340px;
  925. }
  926. </style>