bearing.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. <template>
  2. <div>
  3. <div class="TopBox">
  4. <div class="leftdiv">
  5. <div class="stateBox">
  6. <h4>轴承状态</h4>
  7. <div class="state">
  8. <p :style="{ backgroundColor: bearingStateColors.innerRing }">
  9. 轴承内圈状态
  10. </p>
  11. <p :style="{ backgroundColor: bearingStateColors.outerRing }">
  12. 轴承外圈状态
  13. </p>
  14. <p :style="{ backgroundColor: bearingStateColors.rollingElement }">
  15. 轴承滚动体状态
  16. </p>
  17. <p :style="{ backgroundColor: bearingStateColors.cage }">
  18. 轴承保持架状态
  19. </p>
  20. </div>
  21. <el-button
  22. type="primary"
  23. size="small"
  24. @click="automaticDiagnosis"
  25. class="btn-auto"
  26. >自动诊断</el-button
  27. >
  28. </div>
  29. <div class="Btn">
  30. <div style="height: 200px">
  31. <bing :result="result"> </bing>
  32. </div>
  33. <div class="minp">
  34. <p class="PText">
  35. <span><i class="color1"></i>正常</span
  36. ><span><i class="color2"></i>报警</span
  37. ><span><i class="color3"></i>危险</span>
  38. </p>
  39. <h4>诊断步骤:</h4>
  40. <p>1、选择振动测点与起止时间,点击“查询”;</p>
  41. <p>2、对轴承“参数设置”输入相关信息;</p>
  42. <p>3、点击“自动诊断”输出最终轴承状态结果。</p>
  43. </div>
  44. </div>
  45. </div>
  46. <div class="rightdiv">
  47. <el-table
  48. ref="multipleTable"
  49. :data="tableData"
  50. tooltip-effect="dark"
  51. style="width: 100%"
  52. height="250"
  53. >
  54. <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
  55. <el-table-column prop="timeStamp" label="时间" align="center" width="150">
  56. </el-table-column>
  57. <el-table-column
  58. prop="samplingFrequency"
  59. label="采样频率(Hz)"
  60. align="center"
  61. >
  62. </el-table-column>
  63. <el-table-column
  64. prop="rotationalSpeed"
  65. label="转速(rpm)"
  66. align="center"
  67. >
  68. </el-table-column>
  69. <el-table-column
  70. prop="innerRingFault"
  71. label="轴承内圈故障"
  72. align="center"
  73. >
  74. </el-table-column>
  75. <el-table-column
  76. prop="outerRingFault"
  77. label="轴承外圈故障"
  78. align="center"
  79. >
  80. </el-table-column>
  81. <el-table-column
  82. prop="rollingElementFault"
  83. label="轴承滚动体故障"
  84. align="center"
  85. >
  86. </el-table-column>
  87. <el-table-column
  88. prop="cageFault"
  89. label="轴承保持架故障"
  90. align="center"
  91. >
  92. </el-table-column>
  93. </el-table>
  94. <div class="fenye">
  95. <p><span>故障状态代码说明:</span>0代表正常,1代表报警,2代表危险</p>
  96. <el-pagination
  97. @current-change="handleCurrentChange"
  98. :current-page="currentPage"
  99. layout="total, prev, pager, next, jumper"
  100. :total="totalCount"
  101. :page-size="10"
  102. ></el-pagination>
  103. </div>
  104. </div>
  105. </div>
  106. <div class="bottomBox">
  107. <div class="BtLeft">
  108. <h4>轴承状态趋势图</h4>
  109. <el-empty
  110. v-if="this.xData.length === 0 || this.yData.length === 0"
  111. description="暂无数据"
  112. style="padding: 17px 0"
  113. ></el-empty>
  114. <Eecharts
  115. v-else
  116. style="height: 250px"
  117. :xData="xData"
  118. :yData="yData"
  119. :yNames="[
  120. '轴承内圈状态',
  121. '轴承外圈状态',
  122. '轴承滚动体状态',
  123. '轴承保持架状态',
  124. ]"
  125. yAxisName="轴承故障状态"
  126. ></Eecharts>
  127. </div>
  128. <div class="BtRight">
  129. <h4>参数设置</h4>
  130. <div class="BtRightDiv">
  131. <p class="BtRightP">
  132. 发动机到轴承测点转速传动比<span
  133. ><el-input
  134. v-model="transmissionRatio"
  135. size="small"
  136. v-number-only
  137. ></el-input
  138. ></span>
  139. </p>
  140. <h4>滚动轴承参数输入</h4>
  141. <div class="canshu">
  142. <p class="BtRightP">
  143. <span class="label-text">轴承节圆直径D(mm)</span>
  144. <span
  145. ><el-input
  146. v-model="bearingPitchDiameter"
  147. size="small"
  148. v-number-only
  149. ></el-input
  150. ></span>
  151. </p>
  152. <p class="BtRightP">
  153. <span class="label-text">滚动体直径d(mm)</span>
  154. <span
  155. ><el-input
  156. v-model="rollingElementDiameter"
  157. size="small"
  158. v-number-only
  159. ></el-input
  160. ></span>
  161. </p>
  162. <p class="BtRightP">
  163. <span class="label-text">滚动体个数Z(个)</span>
  164. <span
  165. ><el-input
  166. v-model="rollingElementCount"
  167. size="small"
  168. v-number-only
  169. ></el-input
  170. ></span>
  171. </p>
  172. <p class="BtRightP">
  173. <span class="label-text">接触角α(°)</span>
  174. <span
  175. ><el-input
  176. v-model="contactAngle"
  177. size="small"
  178. v-number-only
  179. ></el-input
  180. ></span>
  181. </p>
  182. </div>
  183. <h4>报警阈值输入</h4>
  184. <div class="canshu">
  185. <p class="BtRightP">
  186. <span class="label-text">振动速度报警阈值(mm/s)</span>
  187. <span
  188. ><el-input
  189. v-model="vibrationSpeedAlarmThreshold"
  190. size="small"
  191. v-number-only
  192. ></el-input
  193. ></span>
  194. </p>
  195. <p class="BtRightP">
  196. <span class="label-text">振动速度危险阈值(mm/s)</span>
  197. <span
  198. ><el-input
  199. v-model="vibrationSpeedDangerThreshold"
  200. size="small"
  201. v-number-only
  202. ></el-input
  203. ></span>
  204. </p>
  205. <p class="BtRightP">
  206. <span class="label-text">包络总值报警阈值(gE)</span>
  207. <span
  208. ><el-input
  209. v-model="envelopeTotalAlarmThreshold"
  210. size="small"
  211. v-number-only
  212. ></el-input
  213. ></span>
  214. </p>
  215. <p class="BtRightP">
  216. <span class="label-text">包络总值危险阈值(gE)</span>
  217. <span
  218. ><el-input
  219. v-model="envelopeTotalDangerThreshold"
  220. size="small"
  221. v-number-only
  222. ></el-input
  223. ></span>
  224. </p>
  225. </div>
  226. </div>
  227. </div>
  228. </div>
  229. </div>
  230. </template>
  231. <script>
  232. import Eecharts from "./Eecharts.vue";
  233. import bing from "./bing.vue";
  234. import { cacheEntryPossiblyAdded } from "plotly.js-dist";
  235. export default {
  236. components: { Eecharts, bing },
  237. props: {
  238. codedata: {
  239. type: Array,
  240. default: () => [],
  241. },
  242. totalCount: {
  243. type: Number,
  244. default: 0,
  245. },
  246. totalPage: {
  247. type: Number,
  248. default: 0,
  249. },
  250. },
  251. data() {
  252. return {
  253. tableData: [],
  254. // 添加新的数据属性用于绑定输入框的值
  255. transmissionRatio: "",
  256. bearingPitchDiameter: "",
  257. rollingElementDiameter: "",
  258. rollingElementCount: "",
  259. contactAngle: "",
  260. vibrationSpeedAlarmThreshold: "",
  261. vibrationSpeedDangerThreshold: "",
  262. envelopeTotalAlarmThreshold: "",
  263. envelopeTotalDangerThreshold: "",
  264. // 分页
  265. currentPage: 1,
  266. total: 1,
  267. xData: [],
  268. yData: [],
  269. // 颜色判断
  270. bearingStateColors: {
  271. innerRing: "#80808057",
  272. outerRing: "#80808057",
  273. rollingElement: "#80808057",
  274. cage: "#80808057",
  275. },
  276. hasError: false, // 标志是否已经显示过错误提示
  277. result: {},
  278. };
  279. },
  280. created() {},
  281. watch: {
  282. codedata: {
  283. handler(newVal) {
  284. this.tableData = newVal;
  285. },
  286. immediate: true, // 组件创建时立刻执行一次
  287. deep: true, // 如果 codedata 是复杂对象,建议加上
  288. },
  289. },
  290. methods: {
  291. toggleSelection(rows) {
  292. if (rows) {
  293. rows.forEach((row) => {
  294. this.$refs.multipleTable.toggleRowSelection(row);
  295. });
  296. } else {
  297. this.$refs.multipleTable.clearSelection();
  298. }
  299. },
  300. handleSelectionChange(val) {
  301. this.multipleSelection = val;
  302. },
  303. handleCurrentChange(val) {
  304. console.log(`当前页: ${val}`);
  305. this.currentPage = val; // 子组件内部更新当前页
  306. this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
  307. },
  308. automaticDiagnosis() {
  309. // 验证必填项
  310. const requiredFields = [
  311. { field: this.transmissionRatio, name: "发动机到轴承测点转速传动比" },
  312. { field: this.bearingPitchDiameter, name: "轴承节圆直径D(mm)" },
  313. { field: this.rollingElementDiameter, name: "滚动体直径d(mm)" },
  314. { field: this.rollingElementCount, name: "滚动体个数Z(个)" },
  315. { field: this.contactAngle, name: "接触角α(°)" },
  316. {
  317. field: this.vibrationSpeedAlarmThreshold,
  318. name: "振动速度报警阈值(mm/s)",
  319. },
  320. {
  321. field: this.vibrationSpeedDangerThreshold,
  322. name: "振动速度危险阈值(mm/s)",
  323. },
  324. {
  325. field: this.envelopeTotalAlarmThreshold,
  326. name: "包络总值报警阈值(gE)",
  327. },
  328. {
  329. field: this.envelopeTotalDangerThreshold,
  330. name: "包络总值危险阈值(gE)",
  331. },
  332. ];
  333. // 记录是否已弹出过错误提示
  334. let hasError = false;
  335. // 只检查必填项的字段是否为空
  336. // for (const { field, name } of requiredFields) {
  337. // if (!field && !hasError) {
  338. // // 弹出提示并标记已经出现错误提示
  339. // this.$message.error(`${name} 是必填项`);
  340. // hasError = true; // 标记已经弹出过错误提示
  341. // return; // 停止执行后续逻辑
  342. // }
  343. // }
  344. // 如果验证通过,继续执行后续逻辑
  345. const newProps = this.tableData.map(() => ({
  346. innerRingFault: Math.floor(Math.random() * 3).toString(),
  347. outerRingFault: Math.floor(Math.random() * 3).toString(),
  348. rollingElementFault: Math.floor(Math.random() * 3).toString(),
  349. cageFault: Math.floor(Math.random() * 3).toString(),
  350. }));
  351. this.tableData.forEach((row, index) => {
  352. this.$set(this.tableData, index, {
  353. ...row,
  354. ...newProps[index], // 用每一行自己生成的随机数
  355. });
  356. });
  357. const faultValues = [
  358. ...this.tableData.map((record) => record.innerRingFault),
  359. ...this.tableData.map((record) => record.outerRingFault),
  360. ...this.tableData.map((record) => record.rollingElementFault),
  361. ...this.tableData.map((record) => record.cageFault),
  362. ];
  363. // 统计各个值出现的次数
  364. const counter = faultValues.reduce((acc, value) => {
  365. acc[value] = (acc[value] || 0) + 1;
  366. return acc;
  367. }, {});
  368. // 构造统计结果对象
  369. this.result = {
  370. 1: counter["0"] || 0,
  371. 2: counter["1"] || 0,
  372. 3: counter["2"] || 0,
  373. };
  374. // 更新颜色状态
  375. const fields = [
  376. { key: "innerRingFault", colorKey: "innerRing" },
  377. { key: "outerRingFault", colorKey: "outerRing" },
  378. { key: "rollingElementFault", colorKey: "rollingElement" },
  379. { key: "cageFault", colorKey: "cage" },
  380. ];
  381. fields.forEach(({ key, colorKey }) => {
  382. const values = newProps.map((item) => Number(item[key]));
  383. const maxVal = Math.max(...values);
  384. let color = "#80808057"; // 默认灰色
  385. if (maxVal === 0) color = "#8AE359"; // 无故障
  386. else if (maxVal === 1) color = "#EECB5F"; // 警告
  387. else if (maxVal === 2) color = "#F7715F"; // 危险
  388. this.bearingStateColors[colorKey] = color; // 更新颜色
  389. });
  390. // 更新趋势图数据
  391. // 更新趋势图数据(用tableData,不是newProps)
  392. this.xData = this.tableData.map((item) => item.timeStamp);
  393. this.yData = fields.map(({ key }) =>
  394. this.tableData.map((item) => Number(item[key]))
  395. );
  396. },
  397. },
  398. };
  399. </script>
  400. <style lang="scss" scoped>
  401. h4 {
  402. margin-bottom: 5px;
  403. font-weight: 600;
  404. }
  405. .TopBox {
  406. height: 280px;
  407. display: flex;
  408. justify-content: space-around;
  409. .leftdiv {
  410. width: 39%;
  411. display: flex;
  412. justify-content: space-around;
  413. .stateBox {
  414. .state {
  415. display: flex;
  416. flex-direction: column;
  417. justify-content: center; /* 整体居中 */
  418. align-items: center;
  419. height: 200px;
  420. gap: 20px; /* 控制间距 */
  421. p {
  422. width: 150px;
  423. height: 40px;
  424. background: rgb(227, 227, 227);
  425. color: rgb(50, 50, 50);
  426. text-align: center;
  427. align-content: center;
  428. font-weight: 600;
  429. }
  430. }
  431. .btn-auto {
  432. margin-top: 10px;
  433. width: 100%;
  434. }
  435. }
  436. .Btn {
  437. width: 50%;
  438. display: flex;
  439. flex-direction: column; /* 垂直排列 */
  440. justify-content: space-between; /* 顶部和底部对齐 */
  441. min-height: 100px; /* 确保容器有足够高度 */
  442. margin: 10px 0;
  443. .PText {
  444. display: flex;
  445. justify-content: space-around;
  446. span {
  447. display: flex;
  448. align-items: center;
  449. i {
  450. width: 30px;
  451. height: 15px;
  452. margin-right: 5px;
  453. }
  454. .color1 {
  455. background-color: #8AE359;
  456. }
  457. .color2 {
  458. background-color: #EECB5F ;
  459. }
  460. .color3 {
  461. background-color: #F7715F;
  462. }
  463. }
  464. }
  465. margin: 10px 0;
  466. .minp {
  467. font-size: 12px;
  468. margin-top: auto; /* 自动推到最底部 */
  469. }
  470. }
  471. }
  472. .rightdiv {
  473. width: 60%;
  474. .fenye {
  475. display: flex;
  476. justify-content: space-between;
  477. margin: 5px 0;
  478. font-size: 12px;
  479. line-height: 30px;
  480. span {
  481. font-weight: 600;
  482. }
  483. }
  484. }
  485. }
  486. .bottomBox {
  487. display: flex;
  488. justify-content: space-around;
  489. margin-top: 10px;
  490. .BtLeft {
  491. border: 1px solid rgb(231, 231, 231);
  492. width: 49%;
  493. padding: 10px;
  494. }
  495. .BtRight {
  496. width: 49%;
  497. border: 1px solid rgb(231, 231, 231);
  498. padding: 10px;
  499. .BtRightDiv {
  500. padding: 0 10px;
  501. h4 {
  502. font-size: 14px;
  503. }
  504. .BtRightP {
  505. line-height: 30px;
  506. font-size: 12px;
  507. display: flex;
  508. margin-bottom: 5px;
  509. width: 50%;
  510. span {
  511. margin-left: 10px;
  512. .el-input {
  513. width: 100px;
  514. }
  515. }
  516. .label-text {
  517. width: 140px;
  518. }
  519. }
  520. .canshu {
  521. display: flex;
  522. flex-wrap: wrap;
  523. justify-content: space-between;
  524. }
  525. }
  526. }
  527. }
  528. ::v-deep .el-table__cell {
  529. padding: 2px 0;
  530. font-size: 12px;
  531. }
  532. </style>