malfunction.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <template>
  2. <div class="global-variable">
  3. <div class="head">
  4. <ul>
  5. <li
  6. v-for="(item, index) in menuItems"
  7. :key="index"
  8. @click="activeTab = item.component"
  9. :class="{ active: activeTab === item.component }"
  10. >
  11. <span class="Simg"><img :src="item.icon" :alt="item.name" /></span>
  12. <span>{{ item.name }}</span>
  13. </li>
  14. </ul>
  15. </div>
  16. <div class="searchbox">
  17. <p>
  18. 单位:
  19. <selecttree
  20. size="small"
  21. style="width: 180px"
  22. placeholder="请选择所属公司"
  23. :list="parentOpt"
  24. type="1"
  25. v-model="companyCode"
  26. @change="parentChange"
  27. :defaultParentProps="{
  28. children: 'children',
  29. label: 'companyName',
  30. value: 'codeNumber',
  31. }"
  32. >
  33. </selecttree>
  34. </p>
  35. <p>
  36. 风机:
  37. <el-select
  38. size="small"
  39. style="width: 150px"
  40. v-model="unitvalue"
  41. @change="getchedian"
  42. placeholder="请选择"
  43. >
  44. <el-option
  45. v-for="item in unitoptions"
  46. :key="item.engineCode"
  47. :label="item.engineName"
  48. :value="item.engineCode"
  49. >
  50. </el-option>
  51. </el-select>
  52. </p>
  53. <p>
  54. 测点:
  55. <el-select v-model="monitoringvalue" size="small" clearable placeholder="请选择">
  56. <el-option
  57. v-for="item in monitoringoptions"
  58. :key="item.detectionPointEn"
  59. :label="item.detectionPointCn"
  60. :value="item.detectionPointEn"
  61. >
  62. </el-option>
  63. </el-select>
  64. </p>
  65. <p>
  66. 频率:
  67. <el-select v-model="frequencyvalue" size="small" clearable placeholder="请选择">
  68. <el-option
  69. v-for="item in frequencyoptions"
  70. :key="item"
  71. :label="item"
  72. :value="item"
  73. >
  74. </el-option>
  75. </el-select>
  76. </p>
  77. <p>
  78. 时间:
  79. <el-date-picker
  80. size="small"
  81. v-model="timevalue"
  82. type="datetimerange"
  83. range-separator="至"
  84. start-placeholder="开始日期"
  85. end-placeholder="结束日期"
  86. >
  87. </el-date-picker>
  88. </p>
  89. <el-button type="primary" size="small" @click="conditions(1)"
  90. >查询</el-button
  91. >
  92. <!-- <el-button type="primary" size="small">自动诊断</el-button> -->
  93. </div>
  94. <div class="main-body">
  95. <keep-alive>
  96. <component
  97. :is="activeTab"
  98. :codedata="codedata"
  99. :totalCount="totalCount"
  100. :totalPage="totalPage"
  101. @updatePage="handlePageChange"
  102. />
  103. </keep-alive>
  104. </div>
  105. </div>
  106. </template>
  107. <script>
  108. import * as FileSaver from "file-saver";
  109. import * as XLSX from "xlsx";
  110. import {
  111. getSysOrganizationAuthTreeByRoleId,
  112. windEngineGrouPage,
  113. queryDetectionDic,
  114. } from "@/api/ledger.js";
  115. import selecttree from "../../components/selecttree.vue";
  116. import Bearing from "./components/malfunction/bearing.vue";
  117. import Dissymmetry from "./components/malfunction/dissymmetry.vue";
  118. import Gear from "./components/malfunction/gear.vue";
  119. import Loose from "./components/malfunction/loose.vue";
  120. import Misalignment from "./components/malfunction/misalignment.vue";
  121. import Temperature from "./components/malfunction/temperature.vue";
  122. import axios from "axios";
  123. export default {
  124. components: {
  125. selecttree,
  126. Bearing,
  127. Dissymmetry,
  128. Gear,
  129. Loose,
  130. Misalignment,
  131. Temperature,
  132. },
  133. data() {
  134. return {
  135. activeTab: "Bearing", // 默认显示轴承诊断
  136. menuItems: [
  137. {
  138. name: "轴承诊断",
  139. icon: require("@/assets/img/ZC.png"),
  140. component: "Bearing",
  141. },
  142. {
  143. name: "齿轮诊断",
  144. icon: require("@/assets/img/SZ.png"),
  145. component: "Gear",
  146. },
  147. {
  148. name: "不对中诊断",
  149. icon: require("@/assets/img/DZ.png"),
  150. component: "Dissymmetry",
  151. },
  152. {
  153. name: "不平衡诊断",
  154. icon: require("@/assets/img/DC.png"),
  155. component: "Misalignment",
  156. },
  157. {
  158. name: "松动诊断",
  159. icon: require("@/assets/img/SD.png"),
  160. component: "Loose",
  161. },
  162. {
  163. name: "温度诊断",
  164. icon: require("@/assets/img/WD.png"),
  165. component: "Temperature",
  166. },
  167. ],
  168. unitvalue: "",
  169. unitoptions: [],
  170. companyCode: "",
  171. parentOpt: [],
  172. timevalue: [],
  173. startTime: "",
  174. endTime: "",
  175. monitoringvalue: "",
  176. monitoringoptions: [],
  177. frequencyvalue: "",
  178. frequencyoptions: [],
  179. codedata: [],
  180. totalCount: 0,
  181. totalPage: 0,
  182. page: "",
  183. };
  184. },
  185. created() {
  186. this.GETtree();
  187. },
  188. methods: {
  189. async GETtree() {
  190. const res = await getSysOrganizationAuthTreeByRoleId();
  191. const treedata = res.data;
  192. const processedData = this.processTreeData(treedata);
  193. this.parentOpt = processedData;
  194. this.defaultdata = res.data[0];
  195. },
  196. // 获取所属单位
  197. parentChange(data) {
  198. this.maplist = data;
  199. this.maplistArr = data;
  200. // 1. 检查关键数据
  201. if (!this.maplist?.codeNumber) {
  202. console.error("codeNumber 不存在!");
  203. return;
  204. }
  205. // 2. 发起第一个请求
  206. let paramsData = {
  207. fieldCode: this.maplist.codeNumber,
  208. pageNum: 1,
  209. pageSize: 99,
  210. };
  211. this.unitvalue = "";
  212. windEngineGrouPage(paramsData)
  213. .then((res) => {
  214. this.unitoptions = res.data.list;
  215. this.windCode = this.companyCode;
  216. })
  217. .catch((err) => {
  218. console.error("windEngineGrouPage 失败:", err);
  219. });
  220. // 3. 解析坐标逻辑(避免 return 终止函数)
  221. let shouldSkip = false;
  222. try {
  223. if (data.codeType === "field") {
  224. if (
  225. this.parseCoordinates(data.longitudeAndLatitudeString).length > 0
  226. ) {
  227. shouldSkip = true;
  228. }
  229. } else {
  230. data.children?.forEach((element) => {
  231. if (
  232. element.codeType === "field" &&
  233. this.parseCoordinates(element.longitudeAndLatitudeString).length >
  234. 0
  235. ) {
  236. shouldSkip = true;
  237. }
  238. });
  239. }
  240. } catch (err) {
  241. console.error("解析坐标出错:", err);
  242. }
  243. if (shouldSkip) {
  244. console.log("坐标已存在,跳过部分逻辑");
  245. }
  246. // 4. 确保第二个请求执行
  247. axios
  248. .get(
  249. `/ETLapi/waveData/getAllSamplingFrequency/${this.maplist.codeNumber}`
  250. )
  251. .then((res) => {
  252. this.frequencyoptions = res.data.datas;
  253. })
  254. .catch((err) => {
  255. console.error("第二个请求失败:", err);
  256. });
  257. },
  258. processTreeData(treeData) {
  259. const processedData = [];
  260. function processNode(node) {
  261. if (node.codeType === "field") {
  262. node.companyName = node.fieldName;
  263. }
  264. if (node.children && node.children.length > 0) {
  265. node.children.forEach((child) => {
  266. processNode(child);
  267. });
  268. }
  269. }
  270. treeData.forEach((root) => {
  271. processNode(root);
  272. processedData.push(root);
  273. });
  274. return processedData;
  275. },
  276. parseCoordinates(input) {
  277. if (input && typeof input === "string") {
  278. return input.split(",").map(Number);
  279. }
  280. return [];
  281. },
  282. // 风机
  283. getchedian(value) {
  284. queryDetectionDic({ engineCodes: value }).then((res) => {
  285. this.monitoringoptions = res.data;
  286. });
  287. },
  288. handlePageChange(page) {
  289. console.log(`接收到的当前页: ${page}`);
  290. // 更新当前页
  291. this.conditions(page); // 调用条件方法时传递页码
  292. },
  293. conditions(page) {
  294. const params = {
  295. samplingFrequency: this.frequencyvalue,
  296. windCode: this.maplist.codeNumber,
  297. windTurbineNumberList: [this.unitvalue],
  298. mesureNameList: [this.monitoringvalue],
  299. startTime: this.$formatDateTWO(this.timevalue[0]),
  300. endTime: this.$formatDateTWO(this.timevalue[1]),
  301. pageNo: page,
  302. pageSize: 10,
  303. };
  304. axios.post(`/ETLapi/waveData/getMesureDataWithSF`, params).then((res) => {
  305. this.codedata = res.data.datas;
  306. this.totalCount = res.data.totalCount;
  307. this.totalPage = res.data.totalPage;
  308. });
  309. },
  310. },
  311. };
  312. </script>
  313. <style lang="scss" scoped>
  314. .global-variable {
  315. padding: 10px;
  316. }
  317. .head {
  318. padding: 5px 0;
  319. display: flex;
  320. justify-content: space-between;
  321. ul {
  322. display: flex;
  323. width: 500px;
  324. height: 65px;
  325. justify-content: space-between;
  326. li {
  327. cursor: pointer;
  328. padding: 8px 12px 0 12px;
  329. border-radius: 4px;
  330. transition: all 0.3s;
  331. &:hover {
  332. background-color: #f0f0f0;
  333. }
  334. &.active {
  335. background-color: #e6f7ff;
  336. border-bottom: 2px solid var(--header-bg);
  337. span {
  338. color: var(--header-bg);
  339. font-weight: bold;
  340. }
  341. }
  342. .Simg {
  343. width: 30px;
  344. height: 30px;
  345. display: flex;
  346. align-items: center;
  347. justify-content: center;
  348. margin: 0 auto;
  349. img {
  350. max-width: 100%;
  351. max-height: 100%;
  352. }
  353. }
  354. span {
  355. display: block;
  356. font-size: 12px;
  357. font-weight: 600;
  358. text-align: center;
  359. margin-top: 5px;
  360. }
  361. }
  362. }
  363. }
  364. .searchbox {
  365. display: flex;
  366. margin-bottom: 10px;
  367. align-items: center;
  368. flex-wrap: wrap;
  369. padding-top: 10px;
  370. p {
  371. margin-right: 10px;
  372. margin-bottom: 0;
  373. //margin-top: 10px;
  374. display: flex;
  375. align-items: center;
  376. .el-select,
  377. .el-date-picker {
  378. margin-left: 10px;
  379. }
  380. }
  381. .el-select {
  382. width: 180px;
  383. }
  384. }
  385. .main-body {
  386. margin-top: 10px;
  387. // border: 1px solid #ebeef5;
  388. border-radius: 4px;
  389. padding: 10px;
  390. background: #fff;
  391. }
  392. .el-range-editor.el-input__inner {
  393. width: 370px;
  394. }
  395. </style>