| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605 |
- <template>
- <div class="global-variable">
- <div class="condition">
- <!-- <el-alert
- title="分析前请核对数据是否导入,点击查看是否导入即可查看"
- type="warning"
- show-icon
- >
- </el-alert> -->
- <el-form
- :inline="true"
- ref="ruleForm"
- :model="formInline"
- class="demo-form-inline"
- :rules="rules"
- >
- <el-form-item label="分析主题:" prop="analysisName">
- <el-input
- size="small"
- v-model="formInline.analysisName"
- placeholder="请输入分析主题"
- ></el-input>
- </el-form-item>
- <el-form-item label="风场名称:" prop="fieldName">
- <el-input
- size="small"
- v-model="formInline.fieldName"
- placeholder="请输入风场名称"
- ></el-input>
- </el-form-item>
- <el-form-item label="分析状态:" prop="analysisState">
- <el-select
- size="small"
- v-model="formInline.analysisState"
- placeholder="请选择分析状态"
- >
- <el-option
- v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="() => fetchData()" size="small"
- >查询</el-button
- >
- <el-button @click="reset('ruleForm')" size="small">重置</el-button>
- </el-form-item>
- <el-form-item class="right-align">
- <el-button @click="Newanalyse" size="small">创建分析</el-button>
- <el-button
- @click="examine"
- size="small"
- v-hasPermi="['home:offlinedata']"
- >查看导入数据</el-button
- >
- <el-button
- @click="handleAutoAsstessList"
- size="small"
- v-hasPermi="['home:performance:autoAssetss']"
- >查看自动分析列表</el-button
- >
- <!-- <el-button @click="handleDownLoadChart" size="small">下载</el-button> -->
- </el-form-item>
- </el-form>
- <!-- <div class="progress" v-if="downloadDisabled">
- <div class="progressText">文档生成进度:</div>
- <el-progress
- :percentage="progressPercent"
- :color="colors"
- ></el-progress>
- </div> -->
- </div>
- <div class="list-page">
- <el-table
- class="center-align-table"
- :data="tableData"
- border
- :cell-style="rowStyle"
- >
- <el-table-column
- align="center"
- label="分析主题"
- prop="analysisName"
- min-width="200"
- fixed
- >
- <template slot-scope="scope">
- <el-tooltip
- class="item"
- effect="dark"
- :content="scope.row.sketch || '暂无分析简述'"
- placement="top"
- >
- <span>{{ scope.row.analysisName }}</span>
- </el-tooltip>
- </template>
- </el-table-column>
- <el-table-column
- align="center"
- prop="fieldName"
- label="风场名称"
- min-width="200"
- >
- </el-table-column>
- <el-table-column
- prop="loginName"
- align="center"
- label="分析状态"
- min-width="150"
- >
- <template slot-scope="scope">
- <span v-if="scope.row.analysisState == -1">未关联</span>
- <span
- v-else-if="
- scope.row.analysisState == 20 && scope.row.errState == 0
- "
- style="color: #f90"
- >分析中</span
- >
- <span
- v-else-if="
- scope.row.errState == 1 && scope.row.analysisState == 30
- "
- style="color: #f00"
- >分析异常</span
- >
- <span
- v-else-if="scope.row.analysisState == 30"
- style="color: #4caf50"
- >分析完成</span
- >
- <span
- v-else-if="scope.row.analysisState == 10"
- style="color: #4caf50"
- >排队中</span
- >
- <span v-else>/</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="loginName"
- align="center"
- label="进度"
- min-width="150"
- >
- <template slot-scope="scope">
- <el-progress
- v-if="scope.row.analysisState == 20"
- :text-inside="true"
- :stroke-width="20"
- :percentage="scope.row.analysisProgress"
- :class="{
- 'indeterminate-progress': scope.row.analysisProgress < 100,
- 'animated-progress': true,
- }"
- ></el-progress>
- <span v-else>/</span>
- </template>
- </el-table-column>
- <el-table-column
- align="center"
- label="排队序号"
- prop="orderNum"
- min-width="200"
- >
- <template slot-scope="scope">
- <span> {{ scope.row.orderNum }}</span>
- </template>
- </el-table-column>
- <el-table-column
- align="center"
- label="数据类型名称"
- prop="dataTypeName"
- min-width="200"
- >
- </el-table-column>
- <el-table-column
- v-hasPermi="['home:performance:autoAssetss']"
- prop="onOffCall"
- align="center"
- label="自动分析状态"
- min-width="140"
- >
- <template slot-scope="scope">
- <span>
- {{
- scope.row.onOffCall == 0
- ? "暂停"
- : scope.row.onOffCall === 1
- ? "开启"
- : "/"
- }}</span
- >
- </template>
- </el-table-column>
- <el-table-column
- prop="roleName"
- align="center"
- label="异常信息"
- min-width="120"
- >
- <template slot-scope="scope">
- <el-button
- v-if="scope.row.errState == 1"
- @click="abnormalDialog(scope.row, '异常详情')"
- type="text"
- size="small"
- >异常详情</el-button
- >
- <span v-else>/</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="roleName"
- align="center"
- label="分析记录"
- min-width="120"
- >
- <template slot-scope="scope">
- <!-- 分析完成 -->
- <el-button
- v-if="scope.row.analysisState == 30 && scope.row.errState !== 1"
- @click="handleAssetssDetail(scope.row, '1')"
- type="text"
- size="small"
- >分析详情</el-button
- >
- <!-- 分析中 -->
- <el-button
- v-else-if="
- scope.row.analysisState == 20 && scope.row.errState == 0
- "
- @click="handleAssetssDetail(scope.row, '0')"
- type="text"
- size="small"
- >分析详情</el-button
- >
- <span v-else>/</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="reportVos"
- align="center"
- label="报告"
- min-width="120"
- >
- <template slot-scope="scope">
- <el-dropdown v-if="scope.row.reportVos.length > 0" trigger="click">
- <el-button type="text" size="small" class="el-dropdown-link">
- 查看报告
- </el-button>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item
- v-for="val in scope.row.reportVos"
- class="reportItemVal"
- >
- <div class="reportLeft">
- <span>{{ val.reportName }}</span>
- </div>
- <div class="reportRight">
- <el-button
- type="text"
- size="small"
- @click="detailReportAssetss(val)"
- >
- 查看
- </el-button>
- <el-button
- type="text"
- size="small"
- @click="downLoadeAssetss(val)"
- >
- 下载
- </el-button>
- </div>
- </el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- <span v-else>/</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="dataStartTime"
- align="center"
- label="开始时间"
- min-width="230"
- >
- </el-table-column>
- <el-table-column
- prop="dataEndTime"
- align="center"
- label="结束时间"
- min-width="230"
- >
- </el-table-column>
- <el-table-column
- prop="transition"
- align="center"
- fixed="right"
- label="操作"
- min-width="300"
- >
- <template slot-scope="scope">
- <!-- <el-button
- @click="handleDownLoadChartImage(scope.row)"
- type="text"
- size="small"
- :disabled="downloadDisabled"
- v-if="
- (scope.row.errState == 1 && scope.row.analysisState == 30) ||
- scope.row.analysisState == 30
- "
- >
- 下载图表
- </el-button> -->
- <el-button
- @click="handleDownLoadChart(scope.row)"
- type="text"
- size="small"
- :disabled="downloadDisabled"
- v-if="
- (scope.row.errState == 1 && scope.row.analysisState == 30) ||
- scope.row.analysisState == 30
- "
- >
- 下载报告
- </el-button>
- <!-- <el-button
- @click="abnormalDialog(scope.row, '上传报告')"
- type="text"
- size="small"
- >上传报告</el-button
- > -->
- <el-button
- @click="handleAssetss(scope.row)"
- type="text"
- :disabled="
- (scope.row.analysisState == 20 && scope.row.errState == 0) ||
- scope.row.analysisState == 10
- "
- size="small"
- >分析</el-button
- >
- <el-button
- @click="abnormalDialog(scope.row, '机组异常记录')"
- type="text"
- size="small"
- >机组异常记录</el-button
- >
- <el-button
- v-if="scope.row.analysisState == 10"
- @click="insertQueue(scope.row, 1)"
- type="text"
- size="small"
- >插队</el-button
- >
- <el-button
- v-if="scope.row.analysisState == 10"
- @click="insertQueue(scope.row, 0)"
- type="text"
- size="small"
- >取消插队</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- <div class="pagination-container">
- <el-pagination
- @current-change="handleCurrentChange"
- :current-page.sync="formInline.pageNum"
- layout="total, prev, pager, next"
- :page-size="formInline.pageSize"
- :total="formInline.totalSize"
- >
- </el-pagination>
- </div>
- </div>
- <!-- 弹出层 -->
- <!-- 异常信息 /机组异常记录 /上传报告-->
- <my-dialog
- :visible="dialogVisible"
- :title="title"
- :rowInfo="rowInfo"
- @confirm="handleConfirm"
- :errorInfo="errorInfo"
- @getTableList="fetchData"
- >
- <div slot="tableEl">
- <el-empty description="暂无数据"></el-empty>
- </div>
- </my-dialog>
- <!-- 查看报告详情 -->
- <el-dialog
- title="PDF 预览"
- :visible.sync="dialogReportVisible"
- :width="dialogWidth"
- class="pdfDialog"
- :before-close="handleCloses"
- >
- <span>
- <div
- style="
- float: right;
- color: #fff;
- cursor: pointer;
- position: absolute;
- left: 90%;
- top: 21px;
- "
- >
- <span
- v-if="dialogWidth === '80%'"
- @click="() => (dialogWidth = '100%')"
- >全屏查看</span
- >
- <span
- v-if="dialogWidth === '100%'"
- @click="() => (dialogWidth = '80%')"
- >还原</span
- >
- <!-- {{ isFullscreen ? "还原" : "全屏" }} -->
- </div>
- </span>
- <div class="pdf-container" ref="viewer">
- <iframe :src="pdfUrl" width="100%" height="100%"></iframe>
- </div>
- <div></div>
- </el-dialog>
- <!-- 创建分析弹出框 -->
- <el-dialog
- title="创建分析"
- :visible.sync="addDialogVisible"
- width="30%"
- :before-close="AddHandleCloses"
- >
- <el-form
- :model="addRuleForm"
- :rules="addRules"
- ref="addRuleForm"
- label-width="100px"
- class="add-ruleForm"
- >
- <el-form-item label="关联风场" prop="fieldCode">
- <el-select
- v-model="addRuleForm.fieldCode"
- placeholder="请选择关联风场"
- >
- <el-option
- :label="item.fieldName"
- v-for="item in fieldCodeList"
- :value="item.codeNumber"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="" prop="analysisName">
- <b style="color: #f00; font-size: 12px"
- >不填写分析主题,自动采用系统生成的主题!</b
- >
- </el-form-item>
- <el-form-item label="分析主题" prop="analysisName">
- <el-input v-model="addRuleForm.analysisName"></el-input>
- </el-form-item>
- <el-form-item label="分析简述" prop="sketch">
- <el-input type="textarea" v-model="addRuleForm.sketch"></el-input>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="addRuleFormSubmit">提交</el-button>
- <el-button @click="AddHandleCloses">取消</el-button>
- </el-form-item>
- </el-form>
- </el-dialog>
- </div>
- </template>
- <script>
- import MyDialog from "./components/dialogCom.vue";
- import { downloadPDF } from "@/utils/common";
- import {
- analysisResultList,
- addAnalysisResult,
- queryCodeNum,
- editPriority,
- analysisDetail,
- } from "@/api/performance";
- import { downloadDocx } from "@/utils/common";
- import { getFieldInfo } from "@/api/overview";
- import axios from "axios";
- import pLimit from "p-limit";
- import { allAnalysisType } from "./js/allAnalysisType";
- import { mapMutations, mapState } from "vuex";
- import {
- windEngineMillPage,
- getWindEngineGroupByFieldCode,
- } from "@/api/ledger.js";
- export default {
- components: {
- MyDialog,
- },
- data() {
- return {
- progress: {
- current: 0,
- total: 0,
- },
- colors: [
- { color: "#f56c6c", percentage: 20 },
- { color: "#e6a23c", percentage: 40 },
- { color: "#5cb87a", percentage: 60 },
- { color: "#1989fa", percentage: 80 },
- { color: "#6f7ad3", percentage: 100 },
- ],
- fileDataList: {},
- fieldInfo: {}, //风场信息
- firstLoad: false, // 是否是第一次加载
- fieldCodeList: [],
- addDialogVisible: false,
- dialogWidth: "80%",
- intervalId: null,
- startTime: null,
- maxPollingTime: 3 * 60 * 1000, //轮询最大时间
- dialogVisible: false,
- loadingView: false,
- loading: false, //数据加载中
- errorInfo: "",
- options: [
- {
- value: "-1",
- label: "未关联",
- },
- {
- value: "10",
- label: "排队中",
- },
- {
- value: "20",
- label: "分析中",
- },
- {
- value: "30",
- label: "已分析",
- },
- ],
- addRules: {
- fieldCode: [
- { required: true, message: "请选择关联风场", trigger: "change" },
- ],
- },
- addRuleForm: {
- fieldCode: "",
- analysisName: "",
- sketch: "",
- },
- rules: {
- fieldName: { trigger: "blur" },
- },
- roleList: [],
- formInline: {
- fieldName: undefined,
- pageNum: 1,
- pageSize: 10,
- totalSize: 0,
- analysisName: undefined,
- analysisState: undefined,
- },
- allAnalysis: [],
- tableData: [],
- rowInfo: {},
- title: "",
- viewerInstance: null, // PDF 文件 URL
- dialogReportVisible: false,
- pdfUrl: "",
- isPolling: false, // 轮询状态标识
- firstLoad: true, // 是否是第一次加载
- };
- },
- created() {
- this.firstLoad = true;
- window.addEventListener("message", this.handleMessage); //江
- this.fetchData();
- },
- computed: {
- ...mapState("settings", {
- downloadDisabled: "downloadDisabled",
- }),
- progressPercent() {
- if (this.progress.total === 0) return 0;
- return Math.round((this.progress.current / this.progress.total) * 100);
- },
- },
- methods: {
- ...mapMutations("settings", ["setDownloadDisabled"]),
- async postChartData(
- urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- typeChart,
- ) {
- try {
- if (itemField.analysisTypeName === "环境温度传感器") {
- console.log(itemField, "itemField");
- }
- const objectname =
- itemAnalysis.analysisTypeCode === "temperature_large_components"
- ? filterAnalysis.filterFileAddr +
- "/" +
- itemField.fieldEngineName +
- ".jpg"
- : itemField.engineTypeCode
- ? urlType + itemField.engineTypeCode + ".jpg"
- : urlType + itemField.fieldEngineName + ".jpg";
- const res = await axios.post(
- `/downLoadChart/chartServer/charts/${urlType}`,
- {
- fieldEngineCode: itemField.fieldEngineCode,
- bucketName: "bucket-zhzn",
- engineTypeCode: itemField.machineTypeCode,
- objectName:
- `charts/${row.fieldCode}/${row.batchCode}/${itemAnalysis.analysisTypeCode}/` +
- objectname,
- fieldInfo: this.fieldInfo,
- fileAddr: itemField.fileAddr,
- chartType:
- filterAnalysis.typeDocxName === "production_indicator_unit"
- ? "radar"
- : urlType,
- },
- );
- // 每完成 10% 提示一次(可调)
- const percent = Math.floor(
- (this.progress.current / this.progress.total) * 100,
- );
- if (percent % 5 === 0 && !this._shownPercents?.includes(percent)) {
- this._shownPercents = this._shownPercents || [];
- this._shownPercents.push(percent);
- this.$notify.info(
- `📈 已完成 ${percent}%/${this.progress.current}张,共 ${this.progress.total} 张图表`,
- );
- }
- let key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-${typeChart}`;
- if (urlType === "yawErrorBarSumChart") {
- key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles2`;
- if (!this.fileDataList["yawErrorRows"]) {
- this.$set(this.fileDataList, "yawErrorRows", []); // Vue 2 中响应式设置对象属性
- }
- this.fileDataList["yawErrorRows"] = res?.data?.data?.data;
- } else if (urlType === "yawErrorChart") {
- key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles1`;
- }
- if (filterAnalysis.typeDocxName === "production_indicator_all") {
- if (!this.fileDataList["rows"]) {
- this.$set(this.fileDataList, "rows", []); // Vue 2 中响应式设置对象属性
- }
- this.fileDataList["rows"] = res?.data?.data?.data;
- }
- if (itemField.engineTypeCode === "total_fault_result") {
- if (!this.fileDataList["faultRows"]) {
- this.$set(this.fileDataList, "faultRows", []); // Vue 2 中响应式设置对象属性
- }
- this.fileDataList["faultRows"] = res?.data?.data?.data;
- }
- if (itemField.engineTypeCode === "turbine_fault_result") {
- if (!this.fileDataList["windTurbineRows"]) {
- this.$set(this.fileDataList, "windTurbineRows", []); // Vue 2 中响应式设置对象属性
- }
- this.fileDataList["windTurbineRows"] = res?.data?.data?.data;
- }
- if (filterAnalysis.typeDocxName === "production_indicator_unit") {
- if (!this.fileDataList[key]) {
- this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
- }
- res?.data?.data?.imageUrls.map((imgval) => {
- this.fileDataList[key].push(imgval);
- });
- } else {
- if (!this.fileDataList[key]) {
- this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
- }
- this.fileDataList[key].push(res?.data?.data?.imageUrl);
- }
- } catch (err) {
- console.error("生成失败:", err);
- }
- },
- async handleDownLoadChartImage(row) {
- this.progress.current = 0;
- this.progress.total = 0;
- this.fileDataList = {};
- this.setDownloadDisabled(true);
- try {
- await this.getAllAnalysis(row.batchCode);
- await this.getFieldDetail(row.batchCode);
- this.$message.info("开始下载图片");
- const limit = pLimit(5); // 限制同时并发的请求数量为 5
- const tasks = [];
- for (const itemAnalysis of this.allAnalysis) {
- const filterAnalysis = allAnalysisType.filter(
- (itemType) => itemType.typeName === itemAnalysis.analysisTypeName,
- )[0];
- console.log(filterAnalysis, "filterAnalysis");
- if (itemAnalysis.generalFiles) {
- //这里过滤的是发电机温度的类型 在url 中是否能找到filterFileAddr
- for (const itemField of filterAnalysis.filterFileAddr
- ? itemAnalysis.generalFiles
- .filter((item) => item.fileAddr.endsWith(".json"))
- .filter((item) =>
- item.fileAddr.includes(filterAnalysis.filterFileAddr),
- ) || []
- : itemAnalysis.generalFiles) {
- //静态偏航误差 --通过allAnalysisType.js文件配置实现需求
- if (Array.isArray(filterAnalysis.generalFiles.urlType)) {
- filterAnalysis.generalFiles.urlType.map(
- (itemUrlType, indUrlType) => {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- itemUrlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- },
- );
- } else if (filterAnalysis.typeCode === "fault") {
- if (itemField.fileAddr.includes("turbine_fault_result")) {
- if (itemField.engineTypeCode === "turbine_fault_result") {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "faultUnitChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- } else {
- if (itemField.engineTypeCode === "total_fault_result") {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "faultAllChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- }
- } else if (filterAnalysis.typeCode === "production_indicator") {
- //总图全场
- if (
- itemField.fileAddr.includes(
- filterAnalysis.generalFiles.FileTypeFromUrl,
- )
- ) {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- filterAnalysis.generalFiles.urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- // 每完成 10% 提示一次(可调)
- }),
- );
- } else {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "radarChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- } else {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- filterAnalysis.generalFiles.urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- }
- }
- if (itemAnalysis.diagramRelations) {
- for (const itemField of filterAnalysis.filterFileAddr
- ? itemAnalysis.diagramRelations
- .filter((item) => item.fileAddr.endsWith(".json"))
- .filter((item) =>
- item.fileAddr.includes(filterAnalysis.filterFileAddr),
- ) || []
- : itemAnalysis.diagramRelations) {
- const urlType = Array.isArray(
- filterAnalysis.diagramRelations.urlType,
- )
- ? this.getFileTypeFromUrl(
- itemField.fileAddr,
- filterAnalysis.diagramRelations.FileTypeFromUrl,
- ) === filterAnalysis.diagramRelations.FileTypeFromUrl
- ? filterAnalysis.diagramRelations.urlType[0]
- : filterAnalysis.diagramRelations.urlType[1]
- : filterAnalysis.diagramRelations.urlType;
- tasks.push(
- limit(async () => {
- await this.postChartData(
- urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "diagramRelations",
- );
- this.progress.current++;
- }),
- );
- }
- }
- }
- this.progress.total = tasks.length;
- await Promise.all(tasks);
- const engineTypeList = await this.getEngineTypeList(
- this.fieldInfo.engineMillTypes,
- row.batchCode,
- );
- this.$notify.success("✅ 图表全部生成完成,开始下载图片...");
- const wordFilePath = await axios.post(
- "/downLoadChart/chartServer/charts/CopyFileImage",
- {
- fieldInfo: this.fieldInfo,
- dataTime: `${this.analysisInfo.dataStartTime}-${this.analysisInfo.dataEndTime}`,
- bucketName: "bucket-zhzn",
- objectName: `charts/${row.fieldCode}/${row.batchCode}`,
- engineTypeList: engineTypeList,
- chartsImages: {
- ...this.fileDataList,
- // "zn-techcn-replace-tags-data_integrity_minute-generalFiles": [
- // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_environment/bartotal_Mid.jpg",
- // ],
- // "zn-techcn-replace-tags-data_integrity_second-generalFiles": [
- // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_large_components/gearbox_low_speed_shaft_bearing_temperature/%2302.jpg",
- // "http://106.120.102.238:26900/bucket-zhzn/charts/WOF039800012/WOF039800012-WOB000002/temperature_environment/bartotal_Mid.jpg",
- // ],
- },
- },
- );
- // //下载minio 文件
- this.downloadZip(wordFilePath.data.data.url);
- // downloadDocx(
- // wordFilePath.data.data.url,
- // wordFilePath.data.data.fileName,
- // );
- this.$notify.success("🎉 图片已下载!");
- this.setDownloadDisabled(false);
- } catch (error) {
- console.log(error, "error");
- this.$notify.error("🎉 图片下载失败!");
- this.setDownloadDisabled(false);
- }
- },
- async downloadZip(url) {
- const res = await axios.get(url, {
- responseType: "blob",
- });
- const blob = new Blob([res.data], {
- type: "application/zip",
- });
- const link = document.createElement("a");
- link.href = URL.createObjectURL(blob);
- link.download = "charts_images.zip";
- document.body.appendChild(link);
- link.click();
- link.remove();
- },
- async handleDownLoadChart(row) {
- this.progress.current = 0;
- this.progress.total = 0;
- this.fileDataList = {};
- this.setDownloadDisabled(true);
- this.$notify.warning("开始生成 Word 文档...");
- try {
- await this.getAllAnalysis(row.batchCode);
- await this.getFieldDetail(row.batchCode);
- this.$message.info("开始生成word文档");
- const limit = pLimit(5); // 限制同时并发的请求数量为 5
- const tasks = [];
- let minioUrl = "";
- for (const itemAnalysis of this.allAnalysis) {
- const filterAnalysis = allAnalysisType.filter(
- (itemType) => itemType.typeName === itemAnalysis.analysisTypeName,
- )[0];
- if (itemAnalysis.generalFiles) {
- //这里过滤的是发电机温度的类型 在url 中是否能找到filterFileAddr
- for (const itemField of filterAnalysis.filterFileAddr
- ? itemAnalysis.generalFiles
- .filter((item) => item.fileAddr.endsWith(".json"))
- .filter((item) =>
- item.fileAddr.includes(filterAnalysis.filterFileAddr),
- ) || []
- : itemAnalysis.generalFiles) {
- minioUrl = new URL(itemField.fileAddr);
- //静态偏航误差 --通过allAnalysisType.js文件配置实现需求
- if (Array.isArray(filterAnalysis.generalFiles.urlType)) {
- filterAnalysis.generalFiles.urlType.map(
- (itemUrlType, indUrlType) => {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- itemUrlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- },
- );
- } else if (filterAnalysis.typeCode === "fault") {
- if (itemField.fileAddr.includes("turbine_fault_result")) {
- if (itemField.engineTypeCode === "turbine_fault_result") {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "faultUnitChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- } else {
- if (itemField.engineTypeCode === "total_fault_result") {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "faultAllChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- }
- } else if (filterAnalysis.typeCode === "production_indicator") {
- //总图全场
- if (
- itemField.fileAddr.includes(
- filterAnalysis.generalFiles.FileTypeFromUrl,
- )
- ) {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- filterAnalysis.generalFiles.urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- // 每完成 10% 提示一次(可调)
- }),
- );
- } else {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- "radarChart",
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- } else {
- tasks.push(
- limit(async () => {
- await this.postChartData(
- filterAnalysis.generalFiles.urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "generalFiles",
- );
- this.progress.current++;
- }),
- );
- }
- }
- }
- if (itemAnalysis.diagramRelations) {
- for (const itemField of filterAnalysis.filterFileAddr
- ? itemAnalysis.diagramRelations
- .filter((item) => item.fileAddr.endsWith(".json"))
- .filter((item) =>
- item.fileAddr.includes(filterAnalysis.filterFileAddr),
- ) || []
- : itemAnalysis.diagramRelations) {
- minioUrl = new URL(itemField.fileAddr);
- const urlType = Array.isArray(
- filterAnalysis.diagramRelations.urlType,
- )
- ? this.getFileTypeFromUrl(
- itemField.fileAddr,
- filterAnalysis.diagramRelations.FileTypeFromUrl,
- ) === filterAnalysis.diagramRelations.FileTypeFromUrl
- ? filterAnalysis.diagramRelations.urlType[0]
- : filterAnalysis.diagramRelations.urlType[1]
- : filterAnalysis.diagramRelations.urlType;
- tasks.push(
- limit(async () => {
- await this.postChartData(
- urlType,
- row,
- itemAnalysis,
- itemField,
- filterAnalysis,
- "diagramRelations",
- );
- this.progress.current++;
- }),
- );
- }
- }
- }
- this.progress.total = tasks.length;
- await Promise.all(tasks);
- const engineTypeList = await this.getEngineTypeList(
- this.fieldInfo.engineMillTypes,
- row.batchCode,
- );
- this.$notify.success("✅ 图表全部生成完成,开始生成 Word 文档...");
- const wordFilePath = await axios.post(
- "/downLoadChart/chartServer/charts/CopyFileCsv",
- {
- fieldInfo: this.fieldInfo,
- dataTime: `${this.analysisInfo.dataStartTime}-${this.analysisInfo.dataEndTime}`,
- bucketName: "bucket-zhzn",
- objectName: `charts/${row.fieldCode}/${row.batchCode}`,
- engineTypeList: engineTypeList,
- ...this.fileDataList,
- },
- );
- const path = wordFilePath.data.data.url.replace(
- /^https?:\/\/[^/]+/,
- "",
- );
- // //下载minio 文件
- downloadDocx(
- `${minioUrl.origin}${path}`,
- // wordFilePath.data.data.url,
- wordFilePath.data.data.fileName,
- );
- this.$notify.success("🎉 Word 文档生成并已下载!");
- this.setDownloadDisabled(false);
- } catch (error) {
- console.log(error, "error");
- this.$notify.error("🎉 Word 文档生成并下载失败!");
- this.setDownloadDisabled(false);
- }
- },
- async getEngineTypeList(typeList, batchCode) {
- return await Promise.all(
- typeList.map((item) => this.getEngineMillList(item, batchCode)),
- );
- },
- // 查询
- async getEngineMillList(machineTypeCode, batchCode) {
- let dataArr = {
- fieldCode: this.fieldInfo.fieldCode,
- batchCode: batchCode,
- };
- const fieldRes = await getWindEngineGroupByFieldCode(dataArr);
- const map = new Map();
- const uniqueList = [];
- for (const item of fieldRes.data.windEngineGroupVoList) {
- if (!map.has(item.millTypeCode)) {
- map.set(item.millTypeCode, true);
- uniqueList.push(item);
- }
- }
- let paramsData = {
- machineTypeCode: machineTypeCode || undefined,
- pageNum: 1,
- pageSize: 10,
- };
- this.loading = true;
- const res = await windEngineMillPage(paramsData);
- const filterMill = uniqueList.filter(
- (item) => item.millTypeCode === res.data.list[0].millTypeCode,
- );
- return { ...res.data.list[0], ratedPower: filterMill[0].ratedCapacity };
- },
- getFileTypeFromUrl(url, keyword) {
- return url.includes(keyword) ? keyword : "Unknown";
- },
- async getFieldDetail(batchCode) {
- const res = await getFieldInfo({ batchCode });
- this.fieldInfo = res.data.fieldInfo; //风场信息
- this.analysisInfo = res.data.analysisInfo;
- },
- //获取所有分析类型,分析结果接口
- async getAllAnalysis(batchCode) {
- const res = await analysisDetail({ batchCode });
- // console.log(res.data, "分析全部结果");
- this.allAnalysis = res.data;
- },
- //自动分析列表页面跳转
- handleAutoAsstessList() {
- window.open(
- this.$router.resolve({ path: "/home/performance/autoAssetss" }).href,
- "_blank",
- );
- },
- // 创建分析时请求
- async addRuleFormSubmit() {
- this.$refs.addRuleForm.validate(async (valid) => {
- if (valid) {
- try {
- const res = await addAnalysisResult(this.addRuleForm);
- if (res.code === 200) {
- this.$message({
- type: "success",
- message: "创建成功",
- });
- this.addDialogVisible = false;
- this.loading = false;
- this.isPolling = false;
- await this.fetchData();
- let obj = this.fieldCodeList.filter((itemS) => {
- if (itemS.codeNumber === this.addRuleForm.fieldCode) {
- return itemS;
- }
- });
- this.$router.push({
- path: "/home/performance/editAssets",
- query: {
- batchCode: this.tableData[0].batchCode,
- analysisTypeCode: this.tableData[0].analysisTypeCode,
- fieldEngineCode: this.tableData[0].fieldCode,
- fieldName: obj[0].fieldName,
- analysisName: this.addRuleForm.analysisName,
- },
- });
- }
- } catch (err) {
- console.error(err);
- }
- }
- });
- },
- AddHandleCloses(done) {
- this.$confirm("确认关闭?")
- .then((_) => {
- this.addDialogVisible = false;
- done();
- })
- .catch((_) => {});
- },
- //获取风场列表
- async getQueryCodeNumList() {
- this.loading = true;
- try {
- const result = await queryCodeNum();
- this.fieldCodeList = result.data.fieldCodeList;
- this.loading = false;
- } catch (error) {
- console.error(error);
- this.loading = false;
- }
- },
- handleCloses(done) {
- this.$confirm("确认关闭?")
- .then((_) => {
- done();
- })
- .catch((_) => {});
- },
- //查看pdf 文件
- detailReportAssetss(row) {
- this.dialogReportVisible = true;
- this.pdfUrl = row.reportAddr;
- },
- //下载pdf 文件
- downLoadeAssetss(row) {
- downloadPDF(row.reportAddr, row.reportName);
- },
- //插队接口
- async insertQueue(row, index) {
- this.$confirm(`确认插队?`, "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(async () => {
- const formData = new FormData();
- formData.append("batchCode", row.batchCode);
- formData.append("priority", index);
- const result = await editPriority(formData);
- if (result.code === 200) {
- this.$message({
- type: "success",
- message: "插队成功",
- });
- await this.fetchData();
- }
- })
- .catch(() => {});
- },
- //分析
- handleAssetss(row) {
- this.$router.push({
- path: "/home/performance/editAssets",
- query: {
- batchCode: row.batchCode,
- analysisTypeCode: row.analysisTypeCode,
- fieldEngineCode: row.fieldCode,
- fieldName: row.fieldName,
- analysisName: row.analysisName,
- },
- });
- },
- //分析详情
- handleAssetssDetail(row, state) {
- const navigateToDetails = () => {
- this.$router.push({
- path: "/home/performance/overview",
- query: {
- batchCode: row.batchCode,
- // analysisTypeCode: row.analysisTypeCode,
- fieldCode: row.fieldCode,
- },
- });
- };
- if (state === "0") {
- // 分析状态为分析中
- this.$confirm(
- "当前查看的分析记录为历史分析结果,最新分析记录还未分析完成不展示!",
- )
- .then(() => {
- navigateToDetails();
- })
- .catch(() => {});
- } else {
- navigateToDetails();
- }
- },
- abnormalDialog(row, title) {
- this.dialogVisible = true;
- if (title === "异常详情") {
- this.errorInfo = row.errInfo;
- this.rowInfo = {};
- } else if (title === "机组异常记录") {
- this.errorInfo = "";
- this.rowInfo = { ...row };
- } else if (title === "上传报告") {
- this.errorInfo = "";
- this.rowInfo = {};
- this.rowInfo.batchCode = row.batchCode;
- }
- this.title = title;
- },
- handleConfirm() {
- this.dialogVisible = false;
- },
- // 页码变化时才触发查询
- handleCurrentChange(val) {
- this.formInline.pageNum = val;
- this.fetchData();
- },
- // 修改 getTableList 方法,避免重复请求
- async getTableList() {
- // 如果正在请求中,跳过此次调用
- if (this.loading || this.isPolling) return;
- this.loading = true;
- try {
- const params = { ...this.formInline, totalSize: undefined };
- // 传递条件参数
- if (this.formInline.analysisState !== undefined) {
- params.analysisState = this.formInline.analysisState;
- }
- if (this.formInline.errState !== undefined) {
- params.errState = this.formInline.errState;
- }
- const result = await analysisResultList(params);
- this.tableData = result.data.list;
- this.formInline.totalSize = result.data.totalSize;
- } catch (error) {
- this.$message({
- type: "error",
- message: "请检查是否连接网络",
- });
- } finally {
- this.loading = false;
- }
- },
- // 改进 handleMessage,避免频繁请求
- handleMessage(event) {
- // 确保消息来自当前域
- if (event.origin !== window.location.origin) {
- return;
- }
- const { fieldName, analysisState, errState } = event.data;
- // 更新表单字段
- if (fieldName !== undefined) {
- this.formInline.fieldName = fieldName;
- }
- if (analysisState !== undefined) {
- this.formInline.analysisState = analysisState;
- }
- if (errState !== undefined) {
- this.formInline.errState = errState;
- }
- if (!this.loading) {
- if (this.firstLoad && (analysisState || errState || fieldName)) {
- // this.getTableList();
- this.startPolling();
- this.fetchData();
- }
- //
- }
- },
- rowStyle() {
- return "text-align:center";
- },
- // 重置
- reset(formName) {
- this.$refs[formName].resetFields();
- this.formInline.fieldName = "";
- this.formInline.analysisName = "";
- this.formInline.analysisState = "";
- this.formInline.errState = "";
- this.fetchData();
- },
- // fetchData 方法在轮询中调用
- async fetchData() {
- if (
- this.formInline.fieldName ||
- this.formInline.analysisState ||
- this.formInline.errState
- ) {
- this.firstLoad = false;
- }
- try {
- const result = await analysisResultList({
- ...this.formInline,
- totalSize: undefined,
- });
- this.tableData = result.data.list;
- this.formInline.totalSize = result.data.totalSize;
- } catch (error) {
- this.$message({
- type: "error",
- message: "请检查是否连接网络",
- });
- }
- },
- stopPolling() {
- // 停止轮询
- if (this.intervalId) {
- clearInterval(this.intervalId);
- this.intervalId = null;
- }
- this.isPolling = false;
- },
- // 启动轮询时,避免重复请求
- startPolling() {
- this.startTime = new Date().getTime();
- this.isPolling = true;
- this.intervalId = setInterval(() => {
- const currentTime = new Date().getTime();
- if (currentTime - this.startTime >= this.maxPollingTime) {
- this.stopPolling();
- } else {
- // 轮询期间不重复请求,检查是否可以调用 fetchData
- if (!this.loading) {
- this.fetchData();
- }
- }
- }, 10000); // 每10秒检查一次
- },
- //创建分析
- Newanalyse() {
- this.addDialogVisible = true;
- this.getQueryCodeNumList();
- },
- examine() {
- const targetUrl = this.$router.resolve({ name: "transition" }).href;
- window.open(targetUrl, "_blank");
- },
- },
- mounted() {
- this.startPolling();
- },
- beforeDestroy() {
- this.stopPolling();
- // 销毁消息监听器
- window.removeEventListener("message", this.handleMessage); //江
- },
- };
- </script>
- <style lang="scss" scoped>
- @keyframes striped-flow {
- from {
- background-position: 0 100px;
- }
- to {
- background-position: 1.25em 1.25em;
- }
- }
- .general {
- display: flex;
- flex-wrap: wrap;
- .condition {
- width: 50%;
- display: flex;
- p {
- width: 100px;
- text-align: right;
- line-height: 40px;
- }
- span {
- line-height: 40px;
- padding-left: 20px;
- }
- .el-select {
- width: 100%;
- margin-bottom: 20px;
- }
- .el-input {
- margin-bottom: 20px;
- }
- }
- }
- .progress {
- display: flex;
- align-items: center;
- position: fixed;
- top: 25px;
- right: 300px;
- .progressText {
- font-size: 14px;
- color: #606266;
- }
- .el-progress {
- width: 300px;
- }
- }
- .attachment {
- display: flex;
- padding-top: 10px;
- p {
- margin-right: 20px;
- color: #409eff;
- }
- }
- .add-ruleForm {
- .el-select {
- width: 100%;
- }
- }
- .addition {
- display: flex;
- justify-content: flex-end;
- margin-bottom: 10px;
- }
- .demo-ruleForm {
- .el-form-item {
- margin-bottom: 25px;
- }
- }
- ::v-deep .animated-progress .el-progress-bar__outer {
- height: 15px; /* Adjust height as needed */
- background-color: rgb(235, 238, 245);
- background-image: linear-gradient(
- 45deg,
- rgba(0, 0, 0, 0.1) 25%,
- transparent 25%,
- transparent 50%,
- rgba(0, 0, 0, 0.1) 50%,
- rgba(0, 0, 0, 0.1) 75%,
- transparent 75%,
- transparent
- );
- background-size: 1.25em 1.25em;
- animation: striped-flow 3s linear infinite;
- }
- .reportItemVal {
- display: flex;
- justify-content: space-between;
- align-items: center;
- .reportLeft {
- margin-right: 50px;
- }
- }
- ::v-deep .pdfDialog .el-dialog {
- height: 100vh;
- display: flex;
- flex-direction: column;
- margin: 0 auto !important;
- .el-dialog__body {
- // height: 100% !important;
- flex: 1;
- background: #fff;
- .pdf-container {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100% !important;
- }
- }
- }
- canvas {
- border: 1px solid #dcdfe6;
- }
- .right-align {
- white-space: nowrap;
- }
- </style>
|