assetssMag.vue 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  1. <template>
  2. <div class="global-variable">
  3. <div class="condition">
  4. <!-- <el-alert
  5. title="分析前请核对数据是否导入,点击查看是否导入即可查看"
  6. type="warning"
  7. show-icon
  8. >
  9. </el-alert> -->
  10. <el-form
  11. :inline="true"
  12. ref="ruleForm"
  13. :model="formInline"
  14. class="demo-form-inline"
  15. :rules="rules"
  16. >
  17. <el-form-item label="分析主题:" prop="analysisName">
  18. <el-input
  19. size="small"
  20. v-model="formInline.analysisName"
  21. placeholder="请输入分析主题"
  22. ></el-input>
  23. </el-form-item>
  24. <el-form-item label="风场名称:" prop="fieldName">
  25. <el-input
  26. size="small"
  27. v-model="formInline.fieldName"
  28. placeholder="请输入风场名称"
  29. ></el-input>
  30. </el-form-item>
  31. <el-form-item label="分析状态:" prop="analysisState">
  32. <el-select
  33. size="small"
  34. v-model="formInline.analysisState"
  35. placeholder="请选择分析状态"
  36. >
  37. <el-option
  38. v-for="item in options"
  39. :key="item.value"
  40. :label="item.label"
  41. :value="item.value"
  42. >
  43. </el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item>
  47. <el-button type="primary" @click="() => fetchData()" size="small"
  48. >查询</el-button
  49. >
  50. <el-button @click="reset('ruleForm')" size="small">重置</el-button>
  51. </el-form-item>
  52. <el-form-item class="right-align">
  53. <el-button @click="Newanalyse" size="small">创建分析</el-button>
  54. <el-button
  55. @click="examine"
  56. size="small"
  57. v-hasPermi="['home:offlinedata']"
  58. >查看导入数据</el-button
  59. >
  60. <el-button
  61. @click="handleAutoAsstessList"
  62. size="small"
  63. v-hasPermi="['home:performance:autoAssetss']"
  64. >查看自动分析列表</el-button
  65. >
  66. <!-- <el-button @click="handleDownLoadChart" size="small">下载</el-button> -->
  67. </el-form-item>
  68. </el-form>
  69. <!-- <div class="progress" v-if="downloadDisabled">
  70. <div class="progressText">文档生成进度:</div>
  71. <el-progress
  72. :percentage="progressPercent"
  73. :color="colors"
  74. ></el-progress>
  75. </div> -->
  76. </div>
  77. <div class="list-page">
  78. <el-table
  79. class="center-align-table"
  80. :data="tableData"
  81. border
  82. :cell-style="rowStyle"
  83. >
  84. <el-table-column
  85. align="center"
  86. label="分析主题"
  87. prop="analysisName"
  88. min-width="200"
  89. fixed
  90. >
  91. <template slot-scope="scope">
  92. <el-tooltip
  93. class="item"
  94. effect="dark"
  95. :content="scope.row.sketch || '暂无分析简述'"
  96. placement="top"
  97. >
  98. <span>{{ scope.row.analysisName }}</span>
  99. </el-tooltip>
  100. </template>
  101. </el-table-column>
  102. <el-table-column
  103. align="center"
  104. prop="fieldName"
  105. label="风场名称"
  106. min-width="200"
  107. >
  108. </el-table-column>
  109. <el-table-column
  110. prop="loginName"
  111. align="center"
  112. label="分析状态"
  113. min-width="150"
  114. >
  115. <template slot-scope="scope">
  116. <span v-if="scope.row.analysisState == -1">未关联</span>
  117. <span
  118. v-else-if="
  119. scope.row.analysisState == 20 && scope.row.errState == 0
  120. "
  121. style="color: #f90"
  122. >分析中</span
  123. >
  124. <span
  125. v-else-if="
  126. scope.row.errState == 1 && scope.row.analysisState == 30
  127. "
  128. style="color: #f00"
  129. >分析异常</span
  130. >
  131. <span
  132. v-else-if="scope.row.analysisState == 30"
  133. style="color: #4caf50"
  134. >分析完成</span
  135. >
  136. <span
  137. v-else-if="scope.row.analysisState == 10"
  138. style="color: #4caf50"
  139. >排队中</span
  140. >
  141. <span v-else>/</span>
  142. </template>
  143. </el-table-column>
  144. <el-table-column
  145. prop="loginName"
  146. align="center"
  147. label="进度"
  148. min-width="150"
  149. >
  150. <template slot-scope="scope">
  151. <el-progress
  152. v-if="scope.row.analysisState == 20"
  153. :text-inside="true"
  154. :stroke-width="20"
  155. :percentage="scope.row.analysisProgress"
  156. :class="{
  157. 'indeterminate-progress': scope.row.analysisProgress < 100,
  158. 'animated-progress': true,
  159. }"
  160. ></el-progress>
  161. <span v-else>/</span>
  162. </template>
  163. </el-table-column>
  164. <el-table-column
  165. align="center"
  166. label="排队序号"
  167. prop="orderNum"
  168. min-width="200"
  169. >
  170. <template slot-scope="scope">
  171. <span> {{ scope.row.orderNum }}</span>
  172. </template>
  173. </el-table-column>
  174. <el-table-column
  175. align="center"
  176. label="数据类型名称"
  177. prop="dataTypeName"
  178. min-width="200"
  179. >
  180. </el-table-column>
  181. <el-table-column
  182. v-hasPermi="['home:performance:autoAssetss']"
  183. prop="onOffCall"
  184. align="center"
  185. label="自动分析状态"
  186. min-width="140"
  187. >
  188. <template slot-scope="scope">
  189. <span>
  190. {{
  191. scope.row.onOffCall == 0
  192. ? "暂停"
  193. : scope.row.onOffCall === 1
  194. ? "开启"
  195. : "/"
  196. }}</span
  197. >
  198. </template>
  199. </el-table-column>
  200. <el-table-column
  201. prop="roleName"
  202. align="center"
  203. label="异常信息"
  204. min-width="120"
  205. >
  206. <template slot-scope="scope">
  207. <el-button
  208. v-if="scope.row.errState == 1"
  209. @click="abnormalDialog(scope.row, '异常详情')"
  210. type="text"
  211. size="small"
  212. >异常详情</el-button
  213. >
  214. <span v-else>/</span>
  215. </template>
  216. </el-table-column>
  217. <el-table-column
  218. prop="roleName"
  219. align="center"
  220. label="分析记录"
  221. min-width="120"
  222. >
  223. <template slot-scope="scope">
  224. <!-- 分析完成 -->
  225. <el-button
  226. v-if="scope.row.analysisState == 30 && scope.row.errState !== 1"
  227. @click="handleAssetssDetail(scope.row, '1')"
  228. type="text"
  229. size="small"
  230. >分析详情</el-button
  231. >
  232. <!-- 分析中 -->
  233. <el-button
  234. v-else-if="
  235. scope.row.analysisState == 20 && scope.row.errState == 0
  236. "
  237. @click="handleAssetssDetail(scope.row, '0')"
  238. type="text"
  239. size="small"
  240. >分析详情</el-button
  241. >
  242. <span v-else>/</span>
  243. </template>
  244. </el-table-column>
  245. <el-table-column
  246. prop="reportVos"
  247. align="center"
  248. label="报告"
  249. min-width="120"
  250. >
  251. <template slot-scope="scope">
  252. <el-dropdown v-if="scope.row.reportVos.length > 0" trigger="click">
  253. <el-button type="text" size="small" class="el-dropdown-link">
  254. 查看报告
  255. </el-button>
  256. <el-dropdown-menu slot="dropdown">
  257. <el-dropdown-item
  258. v-for="val in scope.row.reportVos"
  259. class="reportItemVal"
  260. >
  261. <div class="reportLeft">
  262. <span>{{ val.reportName }}</span>
  263. </div>
  264. <div class="reportRight">
  265. <el-button
  266. type="text"
  267. size="small"
  268. @click="detailReportAssetss(val)"
  269. >
  270. 查看
  271. </el-button>
  272. <el-button
  273. type="text"
  274. size="small"
  275. @click="downLoadeAssetss(val)"
  276. >
  277. 下载
  278. </el-button>
  279. </div>
  280. </el-dropdown-item>
  281. </el-dropdown-menu>
  282. </el-dropdown>
  283. <span v-else>/</span>
  284. </template>
  285. </el-table-column>
  286. <el-table-column
  287. prop="dataStartTime"
  288. align="center"
  289. label="开始时间"
  290. min-width="230"
  291. >
  292. </el-table-column>
  293. <el-table-column
  294. prop="dataEndTime"
  295. align="center"
  296. label="结束时间"
  297. min-width="230"
  298. >
  299. </el-table-column>
  300. <el-table-column
  301. prop="transition"
  302. align="center"
  303. fixed="right"
  304. label="操作"
  305. min-width="300"
  306. >
  307. <template slot-scope="scope">
  308. <!-- <el-button
  309. @click="handleDownLoadChartImage(scope.row)"
  310. type="text"
  311. size="small"
  312. :disabled="downloadDisabled"
  313. v-if="
  314. (scope.row.errState == 1 && scope.row.analysisState == 30) ||
  315. scope.row.analysisState == 30
  316. "
  317. >
  318. 下载图表
  319. </el-button> -->
  320. <el-button
  321. @click="handleDownLoadChart(scope.row)"
  322. type="text"
  323. size="small"
  324. :disabled="downloadDisabled"
  325. v-if="
  326. (scope.row.errState == 1 && scope.row.analysisState == 30) ||
  327. scope.row.analysisState == 30
  328. "
  329. >
  330. 下载报告
  331. </el-button>
  332. <!-- <el-button
  333. @click="abnormalDialog(scope.row, '上传报告')"
  334. type="text"
  335. size="small"
  336. >上传报告</el-button
  337. > -->
  338. <el-button
  339. @click="handleAssetss(scope.row)"
  340. type="text"
  341. :disabled="
  342. (scope.row.analysisState == 20 && scope.row.errState == 0) ||
  343. scope.row.analysisState == 10
  344. "
  345. size="small"
  346. >分析</el-button
  347. >
  348. <el-button
  349. @click="abnormalDialog(scope.row, '机组异常记录')"
  350. type="text"
  351. size="small"
  352. >机组异常记录</el-button
  353. >
  354. <el-button
  355. v-if="scope.row.analysisState == 10"
  356. @click="insertQueue(scope.row, 1)"
  357. type="text"
  358. size="small"
  359. >插队</el-button
  360. >
  361. <el-button
  362. v-if="scope.row.analysisState == 10"
  363. @click="insertQueue(scope.row, 0)"
  364. type="text"
  365. size="small"
  366. >取消插队</el-button
  367. >
  368. </template>
  369. </el-table-column>
  370. </el-table>
  371. <div class="pagination-container">
  372. <el-pagination
  373. @current-change="handleCurrentChange"
  374. :current-page.sync="formInline.pageNum"
  375. layout="total, prev, pager, next"
  376. :page-size="formInline.pageSize"
  377. :total="formInline.totalSize"
  378. >
  379. </el-pagination>
  380. </div>
  381. </div>
  382. <!-- 弹出层 -->
  383. <!-- 异常信息 /机组异常记录 /上传报告-->
  384. <my-dialog
  385. :visible="dialogVisible"
  386. :title="title"
  387. :rowInfo="rowInfo"
  388. @confirm="handleConfirm"
  389. :errorInfo="errorInfo"
  390. @getTableList="fetchData"
  391. >
  392. <div slot="tableEl">
  393. <el-empty description="暂无数据"></el-empty>
  394. </div>
  395. </my-dialog>
  396. <!-- 查看报告详情 -->
  397. <el-dialog
  398. title="PDF 预览"
  399. :visible.sync="dialogReportVisible"
  400. :width="dialogWidth"
  401. class="pdfDialog"
  402. :before-close="handleCloses"
  403. >
  404. <span>
  405. <div
  406. style="
  407. float: right;
  408. color: #fff;
  409. cursor: pointer;
  410. position: absolute;
  411. left: 90%;
  412. top: 21px;
  413. "
  414. >
  415. <span
  416. v-if="dialogWidth === '80%'"
  417. @click="() => (dialogWidth = '100%')"
  418. >全屏查看</span
  419. >
  420. <span
  421. v-if="dialogWidth === '100%'"
  422. @click="() => (dialogWidth = '80%')"
  423. >还原</span
  424. >
  425. <!-- {{ isFullscreen ? "还原" : "全屏" }} -->
  426. </div>
  427. </span>
  428. <div class="pdf-container" ref="viewer">
  429. <iframe :src="pdfUrl" width="100%" height="100%"></iframe>
  430. </div>
  431. <div></div>
  432. </el-dialog>
  433. <!-- 创建分析弹出框 -->
  434. <el-dialog
  435. title="创建分析"
  436. :visible.sync="addDialogVisible"
  437. width="30%"
  438. :before-close="AddHandleCloses"
  439. >
  440. <el-form
  441. :model="addRuleForm"
  442. :rules="addRules"
  443. ref="addRuleForm"
  444. label-width="100px"
  445. class="add-ruleForm"
  446. >
  447. <el-form-item label="关联风场" prop="fieldCode">
  448. <el-select
  449. v-model="addRuleForm.fieldCode"
  450. placeholder="请选择关联风场"
  451. >
  452. <el-option
  453. :label="item.fieldName"
  454. v-for="item in fieldCodeList"
  455. :value="item.codeNumber"
  456. ></el-option>
  457. </el-select>
  458. </el-form-item>
  459. <el-form-item label="" prop="analysisName">
  460. <b style="color: #f00; font-size: 12px"
  461. >不填写分析主题,自动采用系统生成的主题!</b
  462. >
  463. </el-form-item>
  464. <el-form-item label="分析主题" prop="analysisName">
  465. <el-input v-model="addRuleForm.analysisName"></el-input>
  466. </el-form-item>
  467. <el-form-item label="分析简述" prop="sketch">
  468. <el-input type="textarea" v-model="addRuleForm.sketch"></el-input>
  469. </el-form-item>
  470. <el-form-item>
  471. <el-button type="primary" @click="addRuleFormSubmit">提交</el-button>
  472. <el-button @click="AddHandleCloses">取消</el-button>
  473. </el-form-item>
  474. </el-form>
  475. </el-dialog>
  476. </div>
  477. </template>
  478. <script>
  479. import MyDialog from "./components/dialogCom.vue";
  480. import { downloadPDF } from "@/utils/common";
  481. import {
  482. analysisResultList,
  483. addAnalysisResult,
  484. queryCodeNum,
  485. editPriority,
  486. analysisDetail,
  487. } from "@/api/performance";
  488. import { downloadDocx } from "@/utils/common";
  489. import { getFieldInfo } from "@/api/overview";
  490. import axios from "axios";
  491. import pLimit from "p-limit";
  492. import { allAnalysisType } from "./js/allAnalysisType";
  493. import { mapMutations, mapState } from "vuex";
  494. import {
  495. windEngineMillPage,
  496. getWindEngineGroupByFieldCode,
  497. } from "@/api/ledger.js";
  498. export default {
  499. components: {
  500. MyDialog,
  501. },
  502. data() {
  503. return {
  504. progress: {
  505. current: 0,
  506. total: 0,
  507. },
  508. colors: [
  509. { color: "#f56c6c", percentage: 20 },
  510. { color: "#e6a23c", percentage: 40 },
  511. { color: "#5cb87a", percentage: 60 },
  512. { color: "#1989fa", percentage: 80 },
  513. { color: "#6f7ad3", percentage: 100 },
  514. ],
  515. fileDataList: {},
  516. fieldInfo: {}, //风场信息
  517. firstLoad: false, // 是否是第一次加载
  518. fieldCodeList: [],
  519. addDialogVisible: false,
  520. dialogWidth: "80%",
  521. intervalId: null,
  522. startTime: null,
  523. maxPollingTime: 3 * 60 * 1000, //轮询最大时间
  524. dialogVisible: false,
  525. loadingView: false,
  526. loading: false, //数据加载中
  527. errorInfo: "",
  528. options: [
  529. {
  530. value: "-1",
  531. label: "未关联",
  532. },
  533. {
  534. value: "10",
  535. label: "排队中",
  536. },
  537. {
  538. value: "20",
  539. label: "分析中",
  540. },
  541. {
  542. value: "30",
  543. label: "已分析",
  544. },
  545. ],
  546. addRules: {
  547. fieldCode: [
  548. { required: true, message: "请选择关联风场", trigger: "change" },
  549. ],
  550. },
  551. addRuleForm: {
  552. fieldCode: "",
  553. analysisName: "",
  554. sketch: "",
  555. },
  556. rules: {
  557. fieldName: { trigger: "blur" },
  558. },
  559. roleList: [],
  560. formInline: {
  561. fieldName: undefined,
  562. pageNum: 1,
  563. pageSize: 10,
  564. totalSize: 0,
  565. analysisName: undefined,
  566. analysisState: undefined,
  567. },
  568. allAnalysis: [],
  569. tableData: [],
  570. rowInfo: {},
  571. title: "",
  572. viewerInstance: null, // PDF 文件 URL
  573. dialogReportVisible: false,
  574. pdfUrl: "",
  575. isPolling: false, // 轮询状态标识
  576. firstLoad: true, // 是否是第一次加载
  577. };
  578. },
  579. created() {
  580. this.firstLoad = true;
  581. window.addEventListener("message", this.handleMessage); //江
  582. this.fetchData();
  583. },
  584. computed: {
  585. ...mapState("settings", {
  586. downloadDisabled: "downloadDisabled",
  587. }),
  588. progressPercent() {
  589. if (this.progress.total === 0) return 0;
  590. return Math.round((this.progress.current / this.progress.total) * 100);
  591. },
  592. },
  593. methods: {
  594. ...mapMutations("settings", ["setDownloadDisabled"]),
  595. async postChartData(
  596. urlType,
  597. row,
  598. itemAnalysis,
  599. itemField,
  600. filterAnalysis,
  601. typeChart,
  602. ) {
  603. try {
  604. if (itemField.analysisTypeName === "环境温度传感器") {
  605. console.log(itemField, "itemField");
  606. }
  607. const objectname =
  608. itemAnalysis.analysisTypeCode === "temperature_large_components"
  609. ? filterAnalysis.filterFileAddr +
  610. "/" +
  611. itemField.fieldEngineName +
  612. ".jpg"
  613. : itemField.engineTypeCode
  614. ? urlType + itemField.engineTypeCode + ".jpg"
  615. : urlType + itemField.fieldEngineName + ".jpg";
  616. const res = await axios.post(
  617. `/downLoadChart/chartServer/charts/${urlType}`,
  618. {
  619. fieldEngineCode: itemField.fieldEngineCode,
  620. bucketName: "bucket-zhzn",
  621. engineTypeCode: itemField.machineTypeCode,
  622. objectName:
  623. `charts/${row.fieldCode}/${row.batchCode}/${itemAnalysis.analysisTypeCode}/` +
  624. objectname,
  625. fieldInfo: this.fieldInfo,
  626. fileAddr: itemField.fileAddr,
  627. chartType:
  628. filterAnalysis.typeDocxName === "production_indicator_unit"
  629. ? "radar"
  630. : urlType,
  631. },
  632. );
  633. // 每完成 10% 提示一次(可调)
  634. const percent = Math.floor(
  635. (this.progress.current / this.progress.total) * 100,
  636. );
  637. if (percent % 5 === 0 && !this._shownPercents?.includes(percent)) {
  638. this._shownPercents = this._shownPercents || [];
  639. this._shownPercents.push(percent);
  640. this.$notify.info(
  641. `📈 已完成 ${percent}%/${this.progress.current}张,共 ${this.progress.total} 张图表`,
  642. );
  643. }
  644. let key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-${typeChart}`;
  645. if (urlType === "yawErrorBarSumChart") {
  646. key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles2`;
  647. if (!this.fileDataList["yawErrorRows"]) {
  648. this.$set(this.fileDataList, "yawErrorRows", []); // Vue 2 中响应式设置对象属性
  649. }
  650. this.fileDataList["yawErrorRows"] = res?.data?.data?.data;
  651. } else if (urlType === "yawErrorChart") {
  652. key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles1`;
  653. }
  654. if (filterAnalysis.typeDocxName === "production_indicator_all") {
  655. if (!this.fileDataList["rows"]) {
  656. this.$set(this.fileDataList, "rows", []); // Vue 2 中响应式设置对象属性
  657. }
  658. this.fileDataList["rows"] = res?.data?.data?.data;
  659. }
  660. if (itemField.engineTypeCode === "total_fault_result") {
  661. if (!this.fileDataList["faultRows"]) {
  662. this.$set(this.fileDataList, "faultRows", []); // Vue 2 中响应式设置对象属性
  663. }
  664. this.fileDataList["faultRows"] = res?.data?.data?.data;
  665. }
  666. if (itemField.engineTypeCode === "turbine_fault_result") {
  667. if (!this.fileDataList["windTurbineRows"]) {
  668. this.$set(this.fileDataList, "windTurbineRows", []); // Vue 2 中响应式设置对象属性
  669. }
  670. this.fileDataList["windTurbineRows"] = res?.data?.data?.data;
  671. }
  672. if (filterAnalysis.typeDocxName === "production_indicator_unit") {
  673. if (!this.fileDataList[key]) {
  674. this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
  675. }
  676. res?.data?.data?.imageUrls.map((imgval) => {
  677. this.fileDataList[key].push(imgval);
  678. });
  679. } else {
  680. if (!this.fileDataList[key]) {
  681. this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
  682. }
  683. this.fileDataList[key].push(res?.data?.data?.imageUrl);
  684. }
  685. } catch (err) {
  686. console.error("生成失败:", err);
  687. }
  688. },
  689. async handleDownLoadChartImage(row) {
  690. this.progress.current = 0;
  691. this.progress.total = 0;
  692. this.fileDataList = {};
  693. this.setDownloadDisabled(true);
  694. try {
  695. await this.getAllAnalysis(row.batchCode);
  696. await this.getFieldDetail(row.batchCode);
  697. this.$message.info("开始下载图片");
  698. const limit = pLimit(5); // 限制同时并发的请求数量为 5
  699. const tasks = [];
  700. for (const itemAnalysis of this.allAnalysis) {
  701. const filterAnalysis = allAnalysisType.filter(
  702. (itemType) => itemType.typeName === itemAnalysis.analysisTypeName,
  703. )[0];
  704. console.log(filterAnalysis, "filterAnalysis");
  705. if (itemAnalysis.generalFiles) {
  706. //这里过滤的是发电机温度的类型 在url 中是否能找到filterFileAddr
  707. for (const itemField of filterAnalysis.filterFileAddr
  708. ? itemAnalysis.generalFiles
  709. .filter((item) => item.fileAddr.endsWith(".json"))
  710. .filter((item) =>
  711. item.fileAddr.includes(filterAnalysis.filterFileAddr),
  712. ) || []
  713. : itemAnalysis.generalFiles) {
  714. //静态偏航误差 --通过allAnalysisType.js文件配置实现需求
  715. if (Array.isArray(filterAnalysis.generalFiles.urlType)) {
  716. filterAnalysis.generalFiles.urlType.map(
  717. (itemUrlType, indUrlType) => {
  718. tasks.push(
  719. limit(async () => {
  720. await this.postChartData(
  721. itemUrlType,
  722. row,
  723. itemAnalysis,
  724. itemField,
  725. filterAnalysis,
  726. "generalFiles",
  727. );
  728. this.progress.current++;
  729. }),
  730. );
  731. },
  732. );
  733. } else if (filterAnalysis.typeCode === "fault") {
  734. if (itemField.fileAddr.includes("turbine_fault_result")) {
  735. if (itemField.engineTypeCode === "turbine_fault_result") {
  736. tasks.push(
  737. limit(async () => {
  738. await this.postChartData(
  739. "faultUnitChart",
  740. row,
  741. itemAnalysis,
  742. itemField,
  743. filterAnalysis,
  744. "generalFiles",
  745. );
  746. this.progress.current++;
  747. }),
  748. );
  749. }
  750. } else {
  751. if (itemField.engineTypeCode === "total_fault_result") {
  752. tasks.push(
  753. limit(async () => {
  754. await this.postChartData(
  755. "faultAllChart",
  756. row,
  757. itemAnalysis,
  758. itemField,
  759. filterAnalysis,
  760. "generalFiles",
  761. );
  762. this.progress.current++;
  763. }),
  764. );
  765. }
  766. }
  767. } else if (filterAnalysis.typeCode === "production_indicator") {
  768. //总图全场
  769. if (
  770. itemField.fileAddr.includes(
  771. filterAnalysis.generalFiles.FileTypeFromUrl,
  772. )
  773. ) {
  774. tasks.push(
  775. limit(async () => {
  776. await this.postChartData(
  777. filterAnalysis.generalFiles.urlType,
  778. row,
  779. itemAnalysis,
  780. itemField,
  781. filterAnalysis,
  782. "generalFiles",
  783. );
  784. this.progress.current++;
  785. // 每完成 10% 提示一次(可调)
  786. }),
  787. );
  788. } else {
  789. tasks.push(
  790. limit(async () => {
  791. await this.postChartData(
  792. "radarChart",
  793. row,
  794. itemAnalysis,
  795. itemField,
  796. filterAnalysis,
  797. "generalFiles",
  798. );
  799. this.progress.current++;
  800. }),
  801. );
  802. }
  803. } else {
  804. tasks.push(
  805. limit(async () => {
  806. await this.postChartData(
  807. filterAnalysis.generalFiles.urlType,
  808. row,
  809. itemAnalysis,
  810. itemField,
  811. filterAnalysis,
  812. "generalFiles",
  813. );
  814. this.progress.current++;
  815. }),
  816. );
  817. }
  818. }
  819. }
  820. if (itemAnalysis.diagramRelations) {
  821. for (const itemField of filterAnalysis.filterFileAddr
  822. ? itemAnalysis.diagramRelations
  823. .filter((item) => item.fileAddr.endsWith(".json"))
  824. .filter((item) =>
  825. item.fileAddr.includes(filterAnalysis.filterFileAddr),
  826. ) || []
  827. : itemAnalysis.diagramRelations) {
  828. const urlType = Array.isArray(
  829. filterAnalysis.diagramRelations.urlType,
  830. )
  831. ? this.getFileTypeFromUrl(
  832. itemField.fileAddr,
  833. filterAnalysis.diagramRelations.FileTypeFromUrl,
  834. ) === filterAnalysis.diagramRelations.FileTypeFromUrl
  835. ? filterAnalysis.diagramRelations.urlType[0]
  836. : filterAnalysis.diagramRelations.urlType[1]
  837. : filterAnalysis.diagramRelations.urlType;
  838. tasks.push(
  839. limit(async () => {
  840. await this.postChartData(
  841. urlType,
  842. row,
  843. itemAnalysis,
  844. itemField,
  845. filterAnalysis,
  846. "diagramRelations",
  847. );
  848. this.progress.current++;
  849. }),
  850. );
  851. }
  852. }
  853. }
  854. this.progress.total = tasks.length;
  855. await Promise.all(tasks);
  856. const engineTypeList = await this.getEngineTypeList(
  857. this.fieldInfo.engineMillTypes,
  858. row.batchCode,
  859. );
  860. this.$notify.success("✅ 图表全部生成完成,开始下载图片...");
  861. const wordFilePath = await axios.post(
  862. "/downLoadChart/chartServer/charts/CopyFileImage",
  863. {
  864. fieldInfo: this.fieldInfo,
  865. dataTime: `${this.analysisInfo.dataStartTime}-${this.analysisInfo.dataEndTime}`,
  866. bucketName: "bucket-zhzn",
  867. objectName: `charts/${row.fieldCode}/${row.batchCode}`,
  868. engineTypeList: engineTypeList,
  869. chartsImages: {
  870. ...this.fileDataList,
  871. // "zn-techcn-replace-tags-data_integrity_minute-generalFiles": [
  872. // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_environment/bartotal_Mid.jpg",
  873. // ],
  874. // "zn-techcn-replace-tags-data_integrity_second-generalFiles": [
  875. // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_large_components/gearbox_low_speed_shaft_bearing_temperature/%2302.jpg",
  876. // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_environment/bartotal_Mid.jpg",
  877. // ],
  878. },
  879. },
  880. );
  881. // //下载minio 文件
  882. this.downloadZip(wordFilePath.data.data.url);
  883. // downloadDocx(
  884. // wordFilePath.data.data.url,
  885. // wordFilePath.data.data.fileName,
  886. // );
  887. this.$notify.success("🎉 图片已下载!");
  888. this.setDownloadDisabled(false);
  889. } catch (error) {
  890. console.log(error, "error");
  891. this.$notify.error("🎉 图片下载失败!");
  892. this.setDownloadDisabled(false);
  893. }
  894. },
  895. async downloadZip(url) {
  896. const res = await axios.get(url, {
  897. responseType: "blob",
  898. });
  899. const blob = new Blob([res.data], {
  900. type: "application/zip",
  901. });
  902. const link = document.createElement("a");
  903. link.href = URL.createObjectURL(blob);
  904. link.download = "charts_images.zip";
  905. document.body.appendChild(link);
  906. link.click();
  907. link.remove();
  908. },
  909. async handleDownLoadChart(row) {
  910. this.progress.current = 0;
  911. this.progress.total = 0;
  912. this.fileDataList = {};
  913. this.setDownloadDisabled(true);
  914. this.$notify.warning("开始生成 Word 文档...");
  915. try {
  916. await this.getAllAnalysis(row.batchCode);
  917. await this.getFieldDetail(row.batchCode);
  918. this.$message.info("开始生成word文档");
  919. const limit = pLimit(5); // 限制同时并发的请求数量为 5
  920. const tasks = [];
  921. let minioUrl = "";
  922. for (const itemAnalysis of this.allAnalysis) {
  923. const filterAnalysis = allAnalysisType.filter(
  924. (itemType) => itemType.typeName === itemAnalysis.analysisTypeName,
  925. )[0];
  926. if (itemAnalysis.generalFiles) {
  927. //这里过滤的是发电机温度的类型 在url 中是否能找到filterFileAddr
  928. for (const itemField of filterAnalysis.filterFileAddr
  929. ? itemAnalysis.generalFiles
  930. .filter((item) => item.fileAddr.endsWith(".json"))
  931. .filter((item) =>
  932. item.fileAddr.includes(filterAnalysis.filterFileAddr),
  933. ) || []
  934. : itemAnalysis.generalFiles) {
  935. minioUrl = new URL(itemField.fileAddr);
  936. //静态偏航误差 --通过allAnalysisType.js文件配置实现需求
  937. if (Array.isArray(filterAnalysis.generalFiles.urlType)) {
  938. filterAnalysis.generalFiles.urlType.map(
  939. (itemUrlType, indUrlType) => {
  940. tasks.push(
  941. limit(async () => {
  942. await this.postChartData(
  943. itemUrlType,
  944. row,
  945. itemAnalysis,
  946. itemField,
  947. filterAnalysis,
  948. "generalFiles",
  949. );
  950. this.progress.current++;
  951. }),
  952. );
  953. },
  954. );
  955. } else if (filterAnalysis.typeCode === "fault") {
  956. if (itemField.fileAddr.includes("turbine_fault_result")) {
  957. if (itemField.engineTypeCode === "turbine_fault_result") {
  958. tasks.push(
  959. limit(async () => {
  960. await this.postChartData(
  961. "faultUnitChart",
  962. row,
  963. itemAnalysis,
  964. itemField,
  965. filterAnalysis,
  966. "generalFiles",
  967. );
  968. this.progress.current++;
  969. }),
  970. );
  971. }
  972. } else {
  973. if (itemField.engineTypeCode === "total_fault_result") {
  974. tasks.push(
  975. limit(async () => {
  976. await this.postChartData(
  977. "faultAllChart",
  978. row,
  979. itemAnalysis,
  980. itemField,
  981. filterAnalysis,
  982. "generalFiles",
  983. );
  984. this.progress.current++;
  985. }),
  986. );
  987. }
  988. }
  989. } else if (filterAnalysis.typeCode === "production_indicator") {
  990. //总图全场
  991. if (
  992. itemField.fileAddr.includes(
  993. filterAnalysis.generalFiles.FileTypeFromUrl,
  994. )
  995. ) {
  996. tasks.push(
  997. limit(async () => {
  998. await this.postChartData(
  999. filterAnalysis.generalFiles.urlType,
  1000. row,
  1001. itemAnalysis,
  1002. itemField,
  1003. filterAnalysis,
  1004. "generalFiles",
  1005. );
  1006. this.progress.current++;
  1007. // 每完成 10% 提示一次(可调)
  1008. }),
  1009. );
  1010. } else {
  1011. tasks.push(
  1012. limit(async () => {
  1013. await this.postChartData(
  1014. "radarChart",
  1015. row,
  1016. itemAnalysis,
  1017. itemField,
  1018. filterAnalysis,
  1019. "generalFiles",
  1020. );
  1021. this.progress.current++;
  1022. }),
  1023. );
  1024. }
  1025. } else {
  1026. tasks.push(
  1027. limit(async () => {
  1028. await this.postChartData(
  1029. filterAnalysis.generalFiles.urlType,
  1030. row,
  1031. itemAnalysis,
  1032. itemField,
  1033. filterAnalysis,
  1034. "generalFiles",
  1035. );
  1036. this.progress.current++;
  1037. }),
  1038. );
  1039. }
  1040. }
  1041. }
  1042. if (itemAnalysis.diagramRelations) {
  1043. for (const itemField of filterAnalysis.filterFileAddr
  1044. ? itemAnalysis.diagramRelations
  1045. .filter((item) => item.fileAddr.endsWith(".json"))
  1046. .filter((item) =>
  1047. item.fileAddr.includes(filterAnalysis.filterFileAddr),
  1048. ) || []
  1049. : itemAnalysis.diagramRelations) {
  1050. minioUrl = new URL(itemField.fileAddr);
  1051. const urlType = Array.isArray(
  1052. filterAnalysis.diagramRelations.urlType,
  1053. )
  1054. ? this.getFileTypeFromUrl(
  1055. itemField.fileAddr,
  1056. filterAnalysis.diagramRelations.FileTypeFromUrl,
  1057. ) === filterAnalysis.diagramRelations.FileTypeFromUrl
  1058. ? filterAnalysis.diagramRelations.urlType[0]
  1059. : filterAnalysis.diagramRelations.urlType[1]
  1060. : filterAnalysis.diagramRelations.urlType;
  1061. tasks.push(
  1062. limit(async () => {
  1063. await this.postChartData(
  1064. urlType,
  1065. row,
  1066. itemAnalysis,
  1067. itemField,
  1068. filterAnalysis,
  1069. "diagramRelations",
  1070. );
  1071. this.progress.current++;
  1072. }),
  1073. );
  1074. }
  1075. }
  1076. }
  1077. this.progress.total = tasks.length;
  1078. await Promise.all(tasks);
  1079. const engineTypeList = await this.getEngineTypeList(
  1080. this.fieldInfo.engineMillTypes,
  1081. row.batchCode,
  1082. );
  1083. this.$notify.success("✅ 图表全部生成完成,开始生成 Word 文档...");
  1084. const wordFilePath = await axios.post(
  1085. "/downLoadChart/chartServer/charts/CopyFileCsv",
  1086. {
  1087. fieldInfo: this.fieldInfo,
  1088. dataTime: `${this.analysisInfo.dataStartTime}-${this.analysisInfo.dataEndTime}`,
  1089. bucketName: "bucket-zhzn",
  1090. objectName: `charts/${row.fieldCode}/${row.batchCode}`,
  1091. engineTypeList: engineTypeList,
  1092. ...this.fileDataList,
  1093. },
  1094. );
  1095. const path = wordFilePath.data.data.url.replace(
  1096. /^https?:\/\/[^/]+/,
  1097. "",
  1098. );
  1099. // //下载minio 文件
  1100. downloadDocx(
  1101. `${minioUrl.origin}${path}`,
  1102. // wordFilePath.data.data.url,
  1103. wordFilePath.data.data.fileName,
  1104. );
  1105. this.$notify.success("🎉 Word 文档生成并已下载!");
  1106. this.setDownloadDisabled(false);
  1107. } catch (error) {
  1108. console.log(error, "error");
  1109. this.$notify.error("🎉 Word 文档生成并下载失败!");
  1110. this.setDownloadDisabled(false);
  1111. }
  1112. },
  1113. async getEngineTypeList(typeList, batchCode) {
  1114. return await Promise.all(
  1115. typeList.map((item) => this.getEngineMillList(item, batchCode)),
  1116. );
  1117. },
  1118. // 查询
  1119. async getEngineMillList(machineTypeCode, batchCode) {
  1120. let dataArr = {
  1121. fieldCode: this.fieldInfo.fieldCode,
  1122. batchCode: batchCode,
  1123. };
  1124. const fieldRes = await getWindEngineGroupByFieldCode(dataArr);
  1125. const map = new Map();
  1126. const uniqueList = [];
  1127. for (const item of fieldRes.data.windEngineGroupVoList) {
  1128. if (!map.has(item.millTypeCode)) {
  1129. map.set(item.millTypeCode, true);
  1130. uniqueList.push(item);
  1131. }
  1132. }
  1133. let paramsData = {
  1134. machineTypeCode: machineTypeCode || undefined,
  1135. pageNum: 1,
  1136. pageSize: 10,
  1137. };
  1138. this.loading = true;
  1139. const res = await windEngineMillPage(paramsData);
  1140. const filterMill = uniqueList.filter(
  1141. (item) => item.millTypeCode === res.data.list[0].millTypeCode,
  1142. );
  1143. return { ...res.data.list[0], ratedPower: filterMill[0].ratedCapacity };
  1144. },
  1145. getFileTypeFromUrl(url, keyword) {
  1146. return url.includes(keyword) ? keyword : "Unknown";
  1147. },
  1148. async getFieldDetail(batchCode) {
  1149. const res = await getFieldInfo({ batchCode });
  1150. this.fieldInfo = res.data.fieldInfo; //风场信息
  1151. this.analysisInfo = res.data.analysisInfo;
  1152. },
  1153. //获取所有分析类型,分析结果接口
  1154. async getAllAnalysis(batchCode) {
  1155. const res = await analysisDetail({ batchCode });
  1156. // console.log(res.data, "分析全部结果");
  1157. this.allAnalysis = res.data;
  1158. },
  1159. //自动分析列表页面跳转
  1160. handleAutoAsstessList() {
  1161. window.open(
  1162. this.$router.resolve({ path: "/home/performance/autoAssetss" }).href,
  1163. "_blank",
  1164. );
  1165. },
  1166. // 创建分析时请求
  1167. async addRuleFormSubmit() {
  1168. this.$refs.addRuleForm.validate(async (valid) => {
  1169. if (valid) {
  1170. try {
  1171. const res = await addAnalysisResult(this.addRuleForm);
  1172. if (res.code === 200) {
  1173. this.$message({
  1174. type: "success",
  1175. message: "创建成功",
  1176. });
  1177. this.addDialogVisible = false;
  1178. this.loading = false;
  1179. this.isPolling = false;
  1180. await this.fetchData();
  1181. let obj = this.fieldCodeList.filter((itemS) => {
  1182. if (itemS.codeNumber === this.addRuleForm.fieldCode) {
  1183. return itemS;
  1184. }
  1185. });
  1186. this.$router.push({
  1187. path: "/home/performance/editAssets",
  1188. query: {
  1189. batchCode: this.tableData[0].batchCode,
  1190. analysisTypeCode: this.tableData[0].analysisTypeCode,
  1191. fieldEngineCode: this.tableData[0].fieldCode,
  1192. fieldName: obj[0].fieldName,
  1193. analysisName: this.addRuleForm.analysisName,
  1194. },
  1195. });
  1196. }
  1197. } catch (err) {
  1198. console.error(err);
  1199. }
  1200. }
  1201. });
  1202. },
  1203. AddHandleCloses(done) {
  1204. this.$confirm("确认关闭?")
  1205. .then((_) => {
  1206. this.addDialogVisible = false;
  1207. done();
  1208. })
  1209. .catch((_) => {});
  1210. },
  1211. //获取风场列表
  1212. async getQueryCodeNumList() {
  1213. this.loading = true;
  1214. try {
  1215. const result = await queryCodeNum();
  1216. this.fieldCodeList = result.data.fieldCodeList;
  1217. this.loading = false;
  1218. } catch (error) {
  1219. console.error(error);
  1220. this.loading = false;
  1221. }
  1222. },
  1223. handleCloses(done) {
  1224. this.$confirm("确认关闭?")
  1225. .then((_) => {
  1226. done();
  1227. })
  1228. .catch((_) => {});
  1229. },
  1230. //查看pdf 文件
  1231. detailReportAssetss(row) {
  1232. this.dialogReportVisible = true;
  1233. this.pdfUrl = row.reportAddr;
  1234. },
  1235. //下载pdf 文件
  1236. downLoadeAssetss(row) {
  1237. downloadPDF(row.reportAddr, row.reportName);
  1238. },
  1239. //插队接口
  1240. async insertQueue(row, index) {
  1241. this.$confirm(`确认插队?`, "提示", {
  1242. confirmButtonText: "确定",
  1243. cancelButtonText: "取消",
  1244. type: "warning",
  1245. })
  1246. .then(async () => {
  1247. const formData = new FormData();
  1248. formData.append("batchCode", row.batchCode);
  1249. formData.append("priority", index);
  1250. const result = await editPriority(formData);
  1251. if (result.code === 200) {
  1252. this.$message({
  1253. type: "success",
  1254. message: "插队成功",
  1255. });
  1256. await this.fetchData();
  1257. }
  1258. })
  1259. .catch(() => {});
  1260. },
  1261. //分析
  1262. handleAssetss(row) {
  1263. this.$router.push({
  1264. path: "/home/performance/editAssets",
  1265. query: {
  1266. batchCode: row.batchCode,
  1267. analysisTypeCode: row.analysisTypeCode,
  1268. fieldEngineCode: row.fieldCode,
  1269. fieldName: row.fieldName,
  1270. analysisName: row.analysisName,
  1271. },
  1272. });
  1273. },
  1274. //分析详情
  1275. handleAssetssDetail(row, state) {
  1276. const navigateToDetails = () => {
  1277. this.$router.push({
  1278. path: "/home/performance/overview",
  1279. query: {
  1280. batchCode: row.batchCode,
  1281. // analysisTypeCode: row.analysisTypeCode,
  1282. fieldCode: row.fieldCode,
  1283. },
  1284. });
  1285. };
  1286. if (state === "0") {
  1287. // 分析状态为分析中
  1288. this.$confirm(
  1289. "当前查看的分析记录为历史分析结果,最新分析记录还未分析完成不展示!",
  1290. )
  1291. .then(() => {
  1292. navigateToDetails();
  1293. })
  1294. .catch(() => {});
  1295. } else {
  1296. navigateToDetails();
  1297. }
  1298. },
  1299. abnormalDialog(row, title) {
  1300. this.dialogVisible = true;
  1301. if (title === "异常详情") {
  1302. this.errorInfo = row.errInfo;
  1303. this.rowInfo = {};
  1304. } else if (title === "机组异常记录") {
  1305. this.errorInfo = "";
  1306. this.rowInfo = { ...row };
  1307. } else if (title === "上传报告") {
  1308. this.errorInfo = "";
  1309. this.rowInfo = {};
  1310. this.rowInfo.batchCode = row.batchCode;
  1311. }
  1312. this.title = title;
  1313. },
  1314. handleConfirm() {
  1315. this.dialogVisible = false;
  1316. },
  1317. // 页码变化时才触发查询
  1318. handleCurrentChange(val) {
  1319. this.formInline.pageNum = val;
  1320. this.fetchData();
  1321. },
  1322. // 修改 getTableList 方法,避免重复请求
  1323. async getTableList() {
  1324. // 如果正在请求中,跳过此次调用
  1325. if (this.loading || this.isPolling) return;
  1326. this.loading = true;
  1327. try {
  1328. const params = { ...this.formInline, totalSize: undefined };
  1329. // 传递条件参数
  1330. if (this.formInline.analysisState !== undefined) {
  1331. params.analysisState = this.formInline.analysisState;
  1332. }
  1333. if (this.formInline.errState !== undefined) {
  1334. params.errState = this.formInline.errState;
  1335. }
  1336. const result = await analysisResultList(params);
  1337. this.tableData = result.data.list;
  1338. this.formInline.totalSize = result.data.totalSize;
  1339. } catch (error) {
  1340. this.$message({
  1341. type: "error",
  1342. message: "请检查是否连接网络",
  1343. });
  1344. } finally {
  1345. this.loading = false;
  1346. }
  1347. },
  1348. // 改进 handleMessage,避免频繁请求
  1349. handleMessage(event) {
  1350. // 确保消息来自当前域
  1351. if (event.origin !== window.location.origin) {
  1352. return;
  1353. }
  1354. const { fieldName, analysisState, errState } = event.data;
  1355. // 更新表单字段
  1356. if (fieldName !== undefined) {
  1357. this.formInline.fieldName = fieldName;
  1358. }
  1359. if (analysisState !== undefined) {
  1360. this.formInline.analysisState = analysisState;
  1361. }
  1362. if (errState !== undefined) {
  1363. this.formInline.errState = errState;
  1364. }
  1365. if (!this.loading) {
  1366. if (this.firstLoad && (analysisState || errState || fieldName)) {
  1367. // this.getTableList();
  1368. this.startPolling();
  1369. this.fetchData();
  1370. }
  1371. //
  1372. }
  1373. },
  1374. rowStyle() {
  1375. return "text-align:center";
  1376. },
  1377. // 重置
  1378. reset(formName) {
  1379. this.$refs[formName].resetFields();
  1380. this.formInline.fieldName = "";
  1381. this.formInline.analysisName = "";
  1382. this.formInline.analysisState = "";
  1383. this.formInline.errState = "";
  1384. this.fetchData();
  1385. },
  1386. // fetchData 方法在轮询中调用
  1387. async fetchData() {
  1388. if (
  1389. this.formInline.fieldName ||
  1390. this.formInline.analysisState ||
  1391. this.formInline.errState
  1392. ) {
  1393. this.firstLoad = false;
  1394. }
  1395. try {
  1396. const result = await analysisResultList({
  1397. ...this.formInline,
  1398. totalSize: undefined,
  1399. });
  1400. this.tableData = result.data.list;
  1401. this.formInline.totalSize = result.data.totalSize;
  1402. } catch (error) {
  1403. this.$message({
  1404. type: "error",
  1405. message: "请检查是否连接网络",
  1406. });
  1407. }
  1408. },
  1409. stopPolling() {
  1410. // 停止轮询
  1411. if (this.intervalId) {
  1412. clearInterval(this.intervalId);
  1413. this.intervalId = null;
  1414. }
  1415. this.isPolling = false;
  1416. },
  1417. // 启动轮询时,避免重复请求
  1418. startPolling() {
  1419. this.startTime = new Date().getTime();
  1420. this.isPolling = true;
  1421. this.intervalId = setInterval(() => {
  1422. const currentTime = new Date().getTime();
  1423. if (currentTime - this.startTime >= this.maxPollingTime) {
  1424. this.stopPolling();
  1425. } else {
  1426. // 轮询期间不重复请求,检查是否可以调用 fetchData
  1427. if (!this.loading) {
  1428. this.fetchData();
  1429. }
  1430. }
  1431. }, 10000); // 每10秒检查一次
  1432. },
  1433. //创建分析
  1434. Newanalyse() {
  1435. this.addDialogVisible = true;
  1436. this.getQueryCodeNumList();
  1437. },
  1438. examine() {
  1439. const targetUrl = this.$router.resolve({ name: "transition" }).href;
  1440. window.open(targetUrl, "_blank");
  1441. },
  1442. },
  1443. mounted() {
  1444. this.startPolling();
  1445. },
  1446. beforeDestroy() {
  1447. this.stopPolling();
  1448. // 销毁消息监听器
  1449. window.removeEventListener("message", this.handleMessage); //江
  1450. },
  1451. };
  1452. </script>
  1453. <style lang="scss" scoped>
  1454. @keyframes striped-flow {
  1455. from {
  1456. background-position: 0 100px;
  1457. }
  1458. to {
  1459. background-position: 1.25em 1.25em;
  1460. }
  1461. }
  1462. .general {
  1463. display: flex;
  1464. flex-wrap: wrap;
  1465. .condition {
  1466. width: 50%;
  1467. display: flex;
  1468. p {
  1469. width: 100px;
  1470. text-align: right;
  1471. line-height: 40px;
  1472. }
  1473. span {
  1474. line-height: 40px;
  1475. padding-left: 20px;
  1476. }
  1477. .el-select {
  1478. width: 100%;
  1479. margin-bottom: 20px;
  1480. }
  1481. .el-input {
  1482. margin-bottom: 20px;
  1483. }
  1484. }
  1485. }
  1486. .progress {
  1487. display: flex;
  1488. align-items: center;
  1489. position: fixed;
  1490. top: 25px;
  1491. right: 300px;
  1492. .progressText {
  1493. font-size: 14px;
  1494. color: #606266;
  1495. }
  1496. .el-progress {
  1497. width: 300px;
  1498. }
  1499. }
  1500. .attachment {
  1501. display: flex;
  1502. padding-top: 10px;
  1503. p {
  1504. margin-right: 20px;
  1505. color: #409eff;
  1506. }
  1507. }
  1508. .add-ruleForm {
  1509. .el-select {
  1510. width: 100%;
  1511. }
  1512. }
  1513. .addition {
  1514. display: flex;
  1515. justify-content: flex-end;
  1516. margin-bottom: 10px;
  1517. }
  1518. .demo-ruleForm {
  1519. .el-form-item {
  1520. margin-bottom: 25px;
  1521. }
  1522. }
  1523. ::v-deep .animated-progress .el-progress-bar__outer {
  1524. height: 15px; /* Adjust height as needed */
  1525. background-color: rgb(235, 238, 245);
  1526. background-image: linear-gradient(
  1527. 45deg,
  1528. rgba(0, 0, 0, 0.1) 25%,
  1529. transparent 25%,
  1530. transparent 50%,
  1531. rgba(0, 0, 0, 0.1) 50%,
  1532. rgba(0, 0, 0, 0.1) 75%,
  1533. transparent 75%,
  1534. transparent
  1535. );
  1536. background-size: 1.25em 1.25em;
  1537. animation: striped-flow 3s linear infinite;
  1538. }
  1539. .reportItemVal {
  1540. display: flex;
  1541. justify-content: space-between;
  1542. align-items: center;
  1543. .reportLeft {
  1544. margin-right: 50px;
  1545. }
  1546. }
  1547. ::v-deep .pdfDialog .el-dialog {
  1548. height: 100vh;
  1549. display: flex;
  1550. flex-direction: column;
  1551. margin: 0 auto !important;
  1552. .el-dialog__body {
  1553. // height: 100% !important;
  1554. flex: 1;
  1555. background: #fff;
  1556. .pdf-container {
  1557. display: flex;
  1558. justify-content: center;
  1559. align-items: center;
  1560. height: 100% !important;
  1561. }
  1562. }
  1563. }
  1564. canvas {
  1565. border: 1px solid #dcdfe6;
  1566. }
  1567. .right-align {
  1568. white-space: nowrap;
  1569. }
  1570. </style>