assetssMag.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. <template>
  2. <div class="global-variable">
  3. <div class="condition">
  4. <el-form
  5. :inline="true"
  6. ref="ruleForm"
  7. :model="formInline"
  8. class="demo-form-inline"
  9. :rules="rules"
  10. >
  11. <el-form-item label="风场名称:" prop="fieldName">
  12. <el-input
  13. size="small"
  14. v-model="formInline.fieldName"
  15. placeholder="请输入风场名称"
  16. ></el-input>
  17. </el-form-item>
  18. <el-form-item>
  19. <el-button type="primary" @click="onSubmit" size="small"
  20. >查询</el-button
  21. >
  22. <el-button @click="reset('ruleForm')" size="small">重置</el-button>
  23. </el-form-item>
  24. </el-form>
  25. </div>
  26. <div class="list-page">
  27. <el-table
  28. v-loading="loading"
  29. class="center-align-table"
  30. :data="tableData"
  31. border
  32. :cell-style="rowStyle"
  33. >
  34. <el-table-column
  35. align="center"
  36. fixed
  37. prop="fieldName"
  38. label="风场名称"
  39. min-width="200"
  40. >
  41. </el-table-column>
  42. <el-table-column
  43. align="center"
  44. label="批次名称"
  45. prop="batchName"
  46. min-width="200"
  47. >
  48. </el-table-column>
  49. <el-table-column
  50. prop="loginName"
  51. align="center"
  52. label="进度"
  53. min-width="150"
  54. >
  55. <template slot-scope="scope">
  56. <el-progress
  57. v-if="scope.row.analysisState == 20"
  58. :text-inside="true"
  59. :stroke-width="20"
  60. :percentage="scope.row.analysisProgress"
  61. :class="{
  62. 'indeterminate-progress': scope.row.analysisProgress < 100,
  63. 'animated-progress': true,
  64. }"
  65. ></el-progress>
  66. <span v-else>/</span>
  67. </template>
  68. </el-table-column>
  69. <el-table-column
  70. prop="loginName"
  71. align="center"
  72. label="分析状态"
  73. min-width="150"
  74. >
  75. <template slot-scope="scope">
  76. <span v-if="scope.row.analysisState == -1">未分析</span>
  77. <span
  78. v-else-if="
  79. scope.row.analysisState == 20 && scope.row.errState == 0
  80. "
  81. style="color: #f90"
  82. >分析中</span
  83. >
  84. <span v-else-if="scope.row.errState == 1" style="color: #f00"
  85. >分析异常</span
  86. >
  87. <span
  88. v-else-if="scope.row.analysisState == 30"
  89. style="color: #4caf50"
  90. >分析完成</span
  91. >
  92. <span
  93. v-else-if="scope.row.analysisState == 10"
  94. style="color: #4caf50"
  95. >排队中</span
  96. >
  97. <span v-else>/</span>
  98. </template>
  99. </el-table-column>
  100. <el-table-column
  101. prop="errState"
  102. align="center"
  103. label="异常状态"
  104. min-width="120"
  105. >
  106. <template slot-scope="scope">
  107. <span>
  108. {{
  109. scope.row.errState == 0 && scope.row.analysisState !== -1
  110. ? "未异常"
  111. : scope.row.errState === 1
  112. ? "异常"
  113. : "/"
  114. }}</span
  115. >
  116. </template>
  117. </el-table-column>
  118. <el-table-column
  119. prop="roleName"
  120. align="center"
  121. label="异常信息"
  122. min-width="120"
  123. >
  124. <template slot-scope="scope">
  125. <el-button
  126. v-if="scope.row.errState == 1"
  127. @click="abnormalDialog(scope.row, '异常详情')"
  128. type="text"
  129. size="small"
  130. >异常详情</el-button
  131. >
  132. <span v-else>/</span>
  133. </template>
  134. </el-table-column>
  135. <el-table-column
  136. prop="roleName"
  137. align="center"
  138. label="分析记录"
  139. min-width="120"
  140. >
  141. <template slot-scope="scope">
  142. <!-- 分析完成 -->
  143. <el-button
  144. v-if="scope.row.analysisState == 30 && scope.row.errState !== 1"
  145. @click="handleAssetssDetail(scope.row, '1')"
  146. type="text"
  147. size="small"
  148. >分析详情</el-button
  149. >
  150. <!-- 分析中 -->
  151. <el-button
  152. v-else-if="
  153. scope.row.analysisState == 20 && scope.row.errState == 0
  154. "
  155. @click="handleAssetssDetail(scope.row, '0')"
  156. type="text"
  157. size="small"
  158. >分析详情</el-button
  159. >
  160. <span v-else>/</span>
  161. </template>
  162. </el-table-column>
  163. <el-table-column
  164. prop="reportVos"
  165. align="center"
  166. label="报告"
  167. min-width="120"
  168. >
  169. <template slot-scope="scope">
  170. <el-dropdown v-if="scope.row.reportVos.length > 0" trigger="click">
  171. <el-button type="text" size="small" class="el-dropdown-link">
  172. 查看报告
  173. </el-button>
  174. <el-dropdown-menu slot="dropdown">
  175. <el-dropdown-item
  176. v-for="val in scope.row.reportVos"
  177. class="reportItemVal"
  178. >
  179. <div class="reportLeft">
  180. <span>{{ val.reportName }}</span>
  181. </div>
  182. <div class="reportRight">
  183. <el-button
  184. type="text"
  185. size="small"
  186. @click="detailReportAssetss(val)"
  187. >
  188. 查看
  189. </el-button>
  190. <el-button
  191. type="text"
  192. size="small"
  193. @click="downLoadeAssetss(val)"
  194. >
  195. 下载
  196. </el-button>
  197. </div>
  198. </el-dropdown-item>
  199. </el-dropdown-menu>
  200. </el-dropdown>
  201. <span v-else>/</span>
  202. <!-- <el-button type="text" size="small">
  203. {{
  204. scope.row.errState == 0 && scope.row.analysisState !== -1
  205. ? "查看报告"
  206. : "/"
  207. }}
  208. </el-button> -->
  209. </template>
  210. </el-table-column>
  211. <el-table-column
  212. prop="createTime"
  213. align="center"
  214. label="创建时间"
  215. min-width="230"
  216. >
  217. </el-table-column>
  218. <el-table-column
  219. prop="transition"
  220. align="center"
  221. fixed="right"
  222. label="操作"
  223. min-width="300"
  224. >
  225. <template slot-scope="scope">
  226. <el-button
  227. @click="abnormalDialog(scope.row, '上传报告')"
  228. type="text"
  229. size="small"
  230. >上传报告</el-button
  231. >
  232. <el-button
  233. @click="handleAssetss(scope.row)"
  234. type="text"
  235. size="small"
  236. >分析</el-button
  237. >
  238. <el-button
  239. @click="abnormalDialog(scope.row, '异常描述')"
  240. type="text"
  241. size="small"
  242. >异常描述</el-button
  243. >
  244. <el-button
  245. @click="HandleOnOffAuto(scope.row)"
  246. type="text"
  247. size="small"
  248. >{{
  249. scope.row.onOffCall === 0 ? "开启自动分析" : "关闭自动分析"
  250. }}</el-button
  251. >
  252. </template>
  253. </el-table-column>
  254. </el-table>
  255. <div class="pagination-container">
  256. <el-pagination
  257. @current-change="handleCurrentChange"
  258. :current-page.sync="formInline.pageNum"
  259. layout="total, prev, pager, next"
  260. :page-size="formInline.pageSize"
  261. :total="formInline.totalSize"
  262. >
  263. </el-pagination>
  264. </div>
  265. </div>
  266. <!-- 弹出层 -->
  267. <!-- 异常信息 /异常描述 /上传报告-->
  268. <my-dialog
  269. :visible="dialogVisible"
  270. :title="title"
  271. :rowInfo="rowInfo"
  272. @confirm="handleConfirm"
  273. @getTableList="fetchData"
  274. >
  275. <div slot="tableEl">
  276. <el-empty description="暂无数据"></el-empty>
  277. </div>
  278. </my-dialog>
  279. <!-- 查看报告详情 -->
  280. <el-dialog
  281. title="PDF 预览"
  282. :visible.sync="dialogReportVisible"
  283. width="80%"
  284. class="pdfDialog"
  285. >
  286. <div class="pdf-container" ref="viewer">
  287. <iframe :src="pdfUrl" width="100%" height="100%"></iframe>
  288. </div>
  289. </el-dialog>
  290. </div>
  291. </template>
  292. <script>
  293. import MyDialog from "./components/dialogCom.vue";
  294. import { downloadPDF } from "@/utils/common";
  295. import { getAnalysisResultList, onOffAutoAnalysis } from "@/api/performance";
  296. export default {
  297. components: {
  298. MyDialog,
  299. },
  300. data() {
  301. return {
  302. intervalId: null,
  303. startTime: null,
  304. maxPollingTime: 5 * 60 * 1000, //轮询最大时间
  305. dialogVisible: false,
  306. loadingView: false,
  307. loading: false, //数据加载中
  308. errorInfo: "",
  309. rules: {
  310. fieldName: { trigger: "blur" },
  311. },
  312. roleList: [],
  313. formInline: {
  314. fieldName: undefined,
  315. pageNum: 1,
  316. pageSize: 10,
  317. totalSize: 0,
  318. },
  319. tableData: [],
  320. rowInfo: {},
  321. title: "",
  322. viewerInstance: null, // PDF 文件 URL
  323. dialogReportVisible: false,
  324. pdfUrl: "",
  325. };
  326. },
  327. created() {
  328. this.getTableList();
  329. },
  330. methods: {
  331. //查看pdf 文件
  332. detailReportAssetss(row) {
  333. console.log(row.reportAddr);
  334. this.dialogReportVisible = true;
  335. this.pdfUrl = row.reportAddr;
  336. },
  337. //下载pdf 文件
  338. downLoadeAssetss(row) {
  339. downloadPDF(row.reportAddr, row.reportName);
  340. },
  341. async HandleOnOffAuto(row) {
  342. try {
  343. const form = new FormData();
  344. form.append("batchCode", row.batchCode);
  345. form.append("onOffCall", row.onOffCall === 0 ? 1 : 0);
  346. const res = await onOffAutoAnalysis(form);
  347. if (res.code === 200) {
  348. this.getTableList();
  349. this.$message({
  350. type: "success",
  351. message: `${row.onOffCall === 0 ? "开启" : "关闭"}成功`,
  352. });
  353. }
  354. } catch (err) {
  355. console.error(err);
  356. }
  357. },
  358. //分析
  359. handleAssetss(row) {
  360. this.$router.push({
  361. path: "/home/performance/editAssets",
  362. query: {
  363. batchCode: row.batchCode,
  364. analysisTypeCode: row.analysisTypeCode,
  365. fieldEngineCode: row.fieldCode,
  366. },
  367. });
  368. },
  369. //分析详情
  370. handleAssetssDetail(row, state) {
  371. const navigateToDetails = () => {
  372. this.$router.push({
  373. path: "/home/performance/assetssDetail",
  374. query: {
  375. batchCode: row.batchCode,
  376. // analysisTypeCode: row.analysisTypeCode,
  377. fieldCode: row.fieldCode,
  378. },
  379. });
  380. };
  381. if (state === "0") {
  382. // 分析状态为分析中
  383. this.$confirm(
  384. "当前查看的分析记录为历史分析结果,最新分析记录还未分析完成不展示!"
  385. )
  386. .then(() => {
  387. navigateToDetails();
  388. })
  389. .catch(() => {});
  390. } else {
  391. navigateToDetails();
  392. }
  393. },
  394. abnormalDialog(row, title) {
  395. this.dialogVisible = true;
  396. if (title === "异常详情") {
  397. this.errorInfo = row.errInfo;
  398. this.rowInfo = {};
  399. } else if (title === "异常描述") {
  400. this.errorInfo = "";
  401. this.rowInfo = { ...row };
  402. } else if (title === "上传报告") {
  403. this.errorInfo = "";
  404. this.rowInfo = {};
  405. this.rowInfo.batchCode = row.batchCode;
  406. }
  407. this.title = title;
  408. },
  409. handleConfirm() {
  410. this.dialogVisible = false;
  411. },
  412. //分页数据切换
  413. handleCurrentChange(val) {
  414. this.formInline.pageNum = val;
  415. this.getTableList();
  416. },
  417. async getTableList() {
  418. try {
  419. this.loading = true;
  420. const result = await getAnalysisResultList({
  421. ...this.formInline,
  422. totalSize: undefined,
  423. });
  424. this.tableData = result.data.list;
  425. this.formInline.totalSize = result.data.totalSize;
  426. this.loading = false;
  427. } catch (error) {
  428. this.$message({
  429. type: "error",
  430. message: "请检查是否连接网络",
  431. });
  432. }
  433. },
  434. rowStyle() {
  435. return "text-align:center";
  436. },
  437. // 查询
  438. onSubmit() {
  439. this.getTableList();
  440. },
  441. // 重置
  442. reset(formName) {
  443. this.$refs[formName].resetFields();
  444. this.getTableList();
  445. },
  446. async fetchData() {
  447. try {
  448. console.log("更新 表格");
  449. const result = await getAnalysisResultList({
  450. ...this.formInline,
  451. totalSize: undefined,
  452. });
  453. this.tableData = result.data.list;
  454. this.formInline.totalSize = result.data.totalSize;
  455. } catch (error) {
  456. this.$message({
  457. type: "error",
  458. message: "请检查是否连接网络",
  459. });
  460. }
  461. },
  462. stopPolling() {
  463. if (this.intervalId) {
  464. clearInterval(this.intervalId);
  465. this.intervalId = null;
  466. }
  467. },
  468. startPolling() {
  469. this.startTime = new Date().getTime();
  470. this.intervalId = setInterval(() => {
  471. const currentTime = new Date().getTime();
  472. if (currentTime - this.startTime >= this.maxPollingTime) {
  473. this.stopPolling();
  474. } else {
  475. this.fetchData();
  476. }
  477. }, 10000); // 每10秒调用一次
  478. },
  479. },
  480. mounted() {
  481. this.startPolling();
  482. },
  483. beforeDestroy() {
  484. this.stopPolling();
  485. },
  486. };
  487. </script>
  488. <style lang="scss" scoped>
  489. @keyframes striped-flow {
  490. from {
  491. background-position: 0 100px;
  492. }
  493. to {
  494. background-position: 1.25em 1.25em;
  495. }
  496. }
  497. .general {
  498. display: flex;
  499. flex-wrap: wrap;
  500. .condition {
  501. width: 50%;
  502. display: flex;
  503. p {
  504. width: 100px;
  505. text-align: right;
  506. line-height: 40px;
  507. }
  508. span {
  509. line-height: 40px;
  510. padding-left: 20px;
  511. }
  512. .el-select {
  513. width: 100%;
  514. margin-bottom: 20px;
  515. }
  516. .el-input {
  517. margin-bottom: 20px;
  518. }
  519. }
  520. }
  521. .attachment {
  522. display: flex;
  523. padding-top: 10px;
  524. p {
  525. margin-right: 20px;
  526. color: #409eff;
  527. }
  528. }
  529. .addition {
  530. display: flex;
  531. justify-content: flex-end;
  532. margin-bottom: 10px;
  533. }
  534. .demo-ruleForm {
  535. .el-form-item {
  536. margin-bottom: 25px;
  537. }
  538. }
  539. ::v-deep .animated-progress .el-progress-bar__outer {
  540. height: 15px; /* Adjust height as needed */
  541. background-color: rgb(235, 238, 245);
  542. background-image: linear-gradient(
  543. 45deg,
  544. rgba(0, 0, 0, 0.1) 25%,
  545. transparent 25%,
  546. transparent 50%,
  547. rgba(0, 0, 0, 0.1) 50%,
  548. rgba(0, 0, 0, 0.1) 75%,
  549. transparent 75%,
  550. transparent
  551. );
  552. background-size: 1.25em 1.25em;
  553. animation: striped-flow 3s linear infinite;
  554. }
  555. .reportItemVal {
  556. display: flex;
  557. justify-content: space-between;
  558. align-items: center;
  559. .reportLeft {
  560. margin-right: 50px;
  561. }
  562. }
  563. ::v-deep .pdfDialog .el-dialog {
  564. height: 90% !important;
  565. margin: 0 auto !important;
  566. .el-dialog__body {
  567. height: 100% !important;
  568. .pdf-container {
  569. display: flex;
  570. justify-content: center;
  571. align-items: center;
  572. height: 90% !important;
  573. }
  574. }
  575. }
  576. canvas {
  577. border: 1px solid #dcdfe6;
  578. }
  579. </style>