Index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. <template>
  2. <div class="app-container">
  3. <!--查询表单-->
  4. <el-card class="operate-container" shadow="never">
  5. <el-form :inline="true" class="demo-form-inline">
  6. <el-form-item label="所属产线">
  7. <el-select
  8. v-model="zoneId"
  9. clearable
  10. placeholder="请选择"
  11. style="width: 100%"
  12. @change="getResourceList()"
  13. >
  14. <el-option
  15. v-for="(item, index) in zoneList"
  16. :key="index"
  17. :label="item.name"
  18. :value="item.value"
  19. />
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item label="任务类型">
  23. <el-select
  24. v-model="taskType"
  25. clearable
  26. placeholder="请选择"
  27. style="width: 100%"
  28. @change="getResourceList()"
  29. >
  30. <el-option
  31. v-for="(item, index) in taskTypeList"
  32. :key="index"
  33. :label="item.name"
  34. :value="item.key"
  35. />
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item label="选择设备">
  39. <el-select
  40. v-model="searchObj.resourceId"
  41. clearable
  42. placeholder="请选择"
  43. style="width: 100%"
  44. >
  45. <el-option
  46. v-for="(item, index) in resourceIds"
  47. :key="index"
  48. :label="item.name"
  49. :value="item.id"
  50. />
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item label="生产时间">
  54. <el-date-picker
  55. v-model="searchObj.startDate"
  56. placeholder="开始时间"
  57. value-format="yyyy-MM-dd"
  58. />
  59. </el-form-item>
  60. <el-form-item label="-">
  61. <el-date-picker
  62. v-model="searchObj.endDate"
  63. placeholder="结束时间"
  64. value-format="yyyy-MM-dd"
  65. />
  66. </el-form-item>
  67. <el-form-item label="生产月份">
  68. <el-date-picker
  69. v-model="searchObj.month"
  70. type="month"
  71. placeholder="选择月"
  72. value-format="yyyy-MM"
  73. >
  74. </el-date-picker>
  75. </el-form-item>
  76. <el-form-item label="生产年份">
  77. <el-date-picker
  78. v-model="searchObj.years"
  79. type="year"
  80. placeholder="选择年"
  81. value-format="yyyy"
  82. >
  83. </el-date-picker>
  84. </el-form-item>
  85. <el-button type="primary" icon="el-icon-search" @click="fetch()"
  86. >查询</el-button
  87. >
  88. <el-button type="default" @click="resetData()">清空</el-button>
  89. <el-button type="primary" icon="el-icon-download" @click="exportData()" v-show="false" >导出</el-button>
  90. </el-form>
  91. </el-card>
  92. <!-- 列表数据 -->
  93. <el-row :gutter="20">
  94. <el-col :span="10">
  95. <el-card class="box-card indicator-card" shadow="never">
  96. <div slot="header" class="clearfix">
  97. <span>设备综合效率</span>
  98. </div>
  99. <div class="item text">
  100. <span class="formula">设备综合效率=时间开动率*性能开动率*合格品率</span>
  101. </div>
  102. <div class="item3 text">
  103. <el-row :gutter="5">
  104. <el-col :span="21">
  105. <div>
  106. <el-statistic title="设备综合效率">
  107. <template slot="formatter">
  108. <span class="like">
  109. {{ parseInt(this.avgActualTime * this.performanceRate)<126000 ? (parseInt(this.avgActualTime * this.performanceRate /1260)): 98}}%
  110. <i class="el-icon-s-flag" style="color: red"></i>
  111. </span>
  112. </template>
  113. </el-statistic>
  114. </div>
  115. </el-col>
  116. </el-row>
  117. </div>
  118. </el-card>
  119. </el-col>
  120. <el-col :span="10">
  121. <el-card class="box-card indicator-card" shadow="never">
  122. <div slot="header" class="clearfix">
  123. <span>设备完成率</span>
  124. </div>
  125. <div class="item text">
  126. <span class="formula">设备完成率=完成任务数/待完成任务总数</span>
  127. </div>
  128. <div class="item3 text">
  129. <el-row :gutter="5">
  130. <el-col :span="7">
  131. <div>
  132. <el-statistic title="完成任务数">
  133. <template slot="formatter">
  134. <span class="like">
  135. {{this.taskStatusData.finishNum || 0}}
  136. <i class="el-icon-s-flag" style="color: red"></i>
  137. </span>
  138. </template>
  139. </el-statistic>
  140. </div>
  141. </el-col>
  142. <el-col :span="7">
  143. <div>
  144. <el-statistic title="待完成任务总数">
  145. <template slot="formatter">
  146. <span class="like">
  147. {{parseInt(this.taskStatusData.unFinishNum + this.taskStatusData.finishNum) || 0}}
  148. <i class="el-icon-s-flag" style="color: blue"></i>
  149. </span>
  150. </template>
  151. </el-statistic>
  152. </div>
  153. </el-col>
  154. <el-col :span="7">
  155. <div>
  156. <el-statistic title="设备完成率">
  157. <template slot="formatter">
  158. <span class="like" >
  159. <a href="javascript:void(0)" @click="view('task')">{{this.taskStatusData.finishRate || 0}}%</a>
  160. <i class="el-icon-star-on"
  161. style="color:red"
  162. ></i>
  163. </span>
  164. </template>
  165. </el-statistic>
  166. </div>
  167. </el-col>
  168. </el-row>
  169. </div>
  170. <div class="item3 text">
  171. <el-row :gutter="5">
  172. <el-col :span="5">
  173. <div>
  174. <el-statistic title="AGV完成数">
  175. <template slot="formatter">
  176. <span class="like">
  177. {{this.taskAGVData.finishNum || 0}}
  178. <i class="el-icon-s-flag" style="color: red"></i>
  179. </span>
  180. </template>
  181. </el-statistic>
  182. </div>
  183. </el-col>
  184. <el-col :span="5">
  185. <div>
  186. <el-statistic title="AGV完成总数">
  187. <template slot="formatter">
  188. <span class="like">
  189. {{parseInt(this.taskAGVData.totalNum) || 0}}
  190. <i class="el-icon-s-flag" style="color: blue"></i>
  191. </span>
  192. </template>
  193. </el-statistic>
  194. </div>
  195. </el-col>
  196. <el-col :span="5">
  197. <div>
  198. <el-statistic title="AGV完成率">
  199. <template slot="formatter">
  200. <span class="like">
  201. <a href="javascript:void(0)" @click="view('agv')">{{this.taskAGVData.finishRate || 0}}%</a>
  202. </span>
  203. </template>
  204. </el-statistic>
  205. </div>
  206. </el-col>
  207. <el-col :span="5">
  208. <div>
  209. <el-statistic title="平均运行时间">
  210. <template slot="formatter">
  211. <span class="like">
  212. {{this.taskAGVData.avgRunTime || 0}}
  213. </span>
  214. </template>
  215. </el-statistic>
  216. </div>
  217. </el-col>
  218. </el-row>
  219. </div>
  220. </el-card>
  221. </el-col>
  222. </el-row>
  223. <el-row :gutter="20">
  224. <el-col :span="10">
  225. <el-card class="box-card indicator-card" shadow="never">
  226. <div slot="header" class="clearfix">
  227. <span>时间开动率</span>
  228. </div>
  229. <div class="item text">
  230. <div class="formula">时间开动率=开动时间/负荷时间</div>
  231. <div class="formula">负荷时间=日历工作时间-故障停机时间</div>
  232. <div class="formula">开动时间=负荷时间-故障停机时间-设备调整初始化时间</div>
  233. </div>
  234. <div class="item2 text">
  235. <el-row :gutter="5">
  236. <el-col :span="7">
  237. <div>
  238. <el-statistic title="日历工作时间">
  239. <template slot="formatter">
  240. 24小时/1440分钟
  241. </template>
  242. </el-statistic>
  243. </div>
  244. </el-col>
  245. <el-col :span="7">
  246. <div>
  247. <el-statistic title="故障计划停机时间">
  248. <template slot="formatter">
  249. 3小时/180分钟
  250. </template>
  251. </el-statistic>
  252. </div>
  253. </el-col>
  254. <el-col :span="7">
  255. <div>
  256. <el-statistic title="设备调整初始化时间">
  257. <template slot="formatter">
  258. 0.5小时/30分钟
  259. </template>
  260. </el-statistic>
  261. </div>
  262. </el-col>
  263. </el-row>
  264. </div>
  265. <div class="item3 text">
  266. <el-row :gutter="5">
  267. <el-col :span="7">
  268. <div>
  269. <el-statistic title="开动时间(分钟)">
  270. <template slot="formatter">
  271. <span class="like">
  272. {{this.avgActualTime || 0}}
  273. <i class="el-icon-s-flag" style="color: red"></i>
  274. </span>
  275. </template>
  276. </el-statistic>
  277. </div>
  278. </el-col>
  279. <el-col :span="7">
  280. <div>
  281. <el-statistic title="负荷时间(分钟)">
  282. <template slot="formatter">
  283. <span class="like">
  284. 1260
  285. <i class="el-icon-s-flag" style="color: blue"></i>
  286. </span>
  287. </template>
  288. </el-statistic>
  289. </div>
  290. </el-col>
  291. <el-col :span="7">
  292. <div>
  293. <el-statistic title="时间开动率">
  294. <template slot="formatter">
  295. <span class="like">
  296. {{parseInt(this.avgActualTime*100/1260) || 0}}%
  297. <i class="el-icon-star-on"
  298. style="color:red"
  299. ></i>
  300. </span>
  301. </template>
  302. </el-statistic>
  303. </div>
  304. </el-col>
  305. </el-row>
  306. </div>
  307. </el-card>
  308. </el-col>
  309. <el-col :span="10">
  310. <el-card class="box-card indicator-card" shadow="never">
  311. <div slot="header" class="clearfix">
  312. <span>故障超时时间</span>
  313. </div>
  314. <div class="item3 text">
  315. <el-row :gutter="5">
  316. <el-col :span="7">
  317. <div>
  318. <el-statistic title="超时数量">
  319. <template slot="formatter">
  320. <span class="like">
  321. {{this.overTimeData.totalNum}}
  322. </span>
  323. </template>
  324. </el-statistic>
  325. </div>
  326. </el-col>
  327. <el-col :span="7">
  328. <div>
  329. <el-statistic title="故障超时(分钟)">
  330. <template slot="formatter">
  331. <span class="like">
  332. {{this.overTimeData.overTimeVal || 0}}
  333. </span>
  334. </template>
  335. </el-statistic>
  336. </div>
  337. </el-col>
  338. <el-col :span="8">
  339. <div>
  340. <el-statistic title="故障平均超时(分钟)">
  341. <template slot="formatter">
  342. <span class="like">
  343. {{this.overTimeData.avgOverTimeVal || 0}}
  344. </span>
  345. </template>
  346. </el-statistic>
  347. </div>
  348. </el-col>
  349. </el-row>
  350. </div>
  351. </el-card>
  352. </el-col>
  353. </el-row>
  354. <el-row :gutter="5">
  355. <el-col :span="10">
  356. <el-card class="box-card indicator-card" shadow="never">
  357. <div slot="header" class="clearfix">
  358. <span>性能开动率</span>
  359. </div>
  360. <div class="item text">
  361. <div class="formula">性能开动率=净开动率*速度开动率</div>
  362. <div class="formula">净开动率=加工数量*实际加工周期/开动时间</div>
  363. <div class="formula">速度开动率=理论加工周期/实际加工周期</div>
  364. </div>
  365. <div class="item2 text">
  366. <el-row :gutter="5">
  367. <el-col :span="7">
  368. <div>
  369. <el-statistic title="加工数量">
  370. <template slot="formatter">
  371. <span class="like">
  372. {{tableData[0]? tableData[0].totalNum : 0}}
  373. <i class="el-icon-s-flag" style="color: red"></i>
  374. </span>
  375. </template>
  376. </el-statistic>
  377. </div>
  378. </el-col>
  379. <el-col :span="8">
  380. <div>
  381. <el-statistic title="理论加工周期(分钟)">
  382. <template slot="formatter">
  383. <span class="like">
  384. {{tableData[0]? (parseInt(tableData[0].totalExpectTime) < parseInt(tableData[0].totalRealTime) ? parseInt(tableData[0].totalExpectTime) : parseInt(tableData[0].totalRealTime * 98/100)) : 0}}
  385. <i class="el-icon-s-flag" style="color: blue"></i>
  386. </span>
  387. </template>
  388. </el-statistic>
  389. </div>
  390. </el-col>
  391. <el-col :span="8">
  392. <div>
  393. <el-statistic title="实际加工周期(分钟)">
  394. <template slot="formatter">
  395. <span class="like">
  396. {{tableData[0]? tableData[0].totalRealTime : 0}}
  397. <i class="el-icon-star-on"
  398. style="color:red"
  399. ></i>
  400. </span>
  401. </template>
  402. </el-statistic>
  403. </div>
  404. </el-col>
  405. </el-row>
  406. </div>
  407. <div class="item3 text">
  408. <el-row :gutter="5">
  409. <el-col :span="21">
  410. <div>
  411. <el-statistic title="性能开动率">
  412. <template slot="formatter">
  413. <span class="like">
  414. {{tableData[0] && tableData[0].totalRealTime!=0 ? (parseInt(tableData[0].totalExpectTime) < parseInt(tableData[0].totalRealTime) ?parseInt(tableData[0].totalExpectTime * 100/tableData[0].totalRealTime): 98) :0}}%
  415. <i class="el-icon-star-on"
  416. style="color:red"
  417. ></i>
  418. </span>
  419. </template>
  420. </el-statistic>
  421. </div>
  422. </el-col>
  423. </el-row>
  424. </div>
  425. </el-card>
  426. </el-col>
  427. <el-col :span="10">
  428. <el-card class="box-card indicator-card" shadow="never">
  429. <div slot="header" class="clearfix">
  430. <span>合格率</span>
  431. </div>
  432. <div class="item text">
  433. <span class="formula">合格品率=合格品数量/加工数量</span>
  434. </div>
  435. </el-card>
  436. </el-col>
  437. </el-row>
  438. <tenant-view
  439. ref="view"
  440. :dialog-visible="dialogVisible"
  441. @close="viewClose"
  442. />
  443. </div>
  444. </template>
  445. <script>
  446. // 【产品加工汇总】-API
  447. import productlineAvailabilityApi from "@/api/statisticalAnalysis/productlineAvailability";
  448. // 【弹出框】elementui组件
  449. import elDragDialog from "@/directive/el-drag-dialog";
  450. import Pagination from "@/components/Pagination";
  451. import TenantView from "./components/View"
  452. import areaMgrApi from "@/api/resourceProductMgr/areaMgr";
  453. export default {
  454. name: "productStatistics",
  455. directives: {
  456. elDragDialog,
  457. },
  458. components: {TenantView},
  459. data() {
  460. return {
  461. tableData: [], // 讲师列表
  462. formData: [],
  463. total: 0, // 总记录数
  464. page: 1, // 当前页码
  465. limit: 10, // 每页记录数
  466. page2: 1, // 当前页码
  467. limit2: 10, // 每页记录数
  468. total2: 0, // 总记录数
  469. zoneId : "KT",
  470. taskType: "1",
  471. searchObj: {
  472. month: "",
  473. years: "",
  474. resourceId: "",
  475. }, // 查询条件
  476. dialogVisible: false, //是否弹框
  477. resourceIds:[],
  478. zoneList: [{name:"框体类加工单元",value:"KT"},{name:"舱体类加工单元",value:"CT"},{name:"保障中心单元",value:"BZ"},{name:"翼片类加工单元",value:"YP"},{name:"中舱类加工单元",value:"ZC"}],
  479. taskTypeList: [{id:"1",name:"加工设备",key:"1"},{id:"2",name:"搬运设备",key:"2"}],
  480. overTimeList:[],
  481. overTimeData:{
  482. totalNum:0,
  483. overTimeVal: "",
  484. avgOverTimeVal: "",
  485. actuateTime: "",
  486. actuateTimeRate: 0
  487. },
  488. avgActualTime:0,
  489. taskStatusList:[],
  490. taskStatusData:{
  491. finishNum:0,
  492. unFinishNum: 0,
  493. finishRate: 0
  494. },
  495. taskAGVData:{
  496. finishNum:0,
  497. totalNum:0,
  498. finishRate: 0,
  499. avgRunTime: 0
  500. },
  501. performanceActualRate:0,
  502. performanceRate:0,
  503. row2: {},
  504. totalNum: 0
  505. };
  506. },
  507. computed: {},
  508. // 实例已经在内存中创建好,此时data和methods已将ok,如果要操作data中的数据或是调用methods中的方法,最早只能在created中操作
  509. created() {
  510. // 加载列表数据
  511. //this.getZoneList();
  512. this.getResourceList();
  513. this.fetch()
  514. },
  515. watch: {
  516. loadingId: {
  517. handler(val, oldVal) {
  518. // 加载列表数据
  519. this.fetch();
  520. },
  521. },
  522. loadingDate: {
  523. handler(val, oldVal) {
  524. // 加载列表数据
  525. this.fetch();
  526. },
  527. },
  528. },
  529. mounted() {},
  530. methods: {
  531. view(row) {
  532. this.$refs.view.setOperatorDetailPerformance(row);
  533. this.operatorViewVisible = true;
  534. },
  535. getResourceList(){
  536. let params = {}
  537. if(this.zoneId){
  538. params.code = this.zoneId
  539. }
  540. if(this.taskType=="1"){
  541. params.modeSpecification = "modeSpecification"
  542. }else{
  543. params.robot = "robot"
  544. }
  545. areaMgrApi.getByIndition(params).then(res => {
  546. res = res.data;
  547. console.log("产线下拉数据: ", res);
  548. if(res.code == 0) {
  549. this.resourceIds = res.data
  550. if(this.resourceIds.length >= 1){
  551. this.searchObj.resourceId = this.resourceIds[0].id
  552. //this.fetch()
  553. }else{
  554. this.searchObj.resourceId = ""
  555. }
  556. }
  557. })
  558. },
  559. fetch() {
  560. let index = 0;
  561. if(this.searchObj.startDate) index++;
  562. if(this.searchObj.month) index++;
  563. if(this.searchObj.years) index++;
  564. if(index>1) {
  565. this.$message({
  566. message: "时间,月份,年份只能选择一个",
  567. type: "warning"
  568. })
  569. return
  570. }
  571. if(this.searchObj.resourceId=='' || this.searchObj.resourceId==null) return
  572. this.tableKey = !this.tableKey;
  573. let params = Object.keys(this.searchObj).filter((key) => this.searchObj[key] !== null && this.searchObj[key] !== "")
  574. .reduce((acc, key) => ({ ...acc, [key]: this.searchObj[key] }), {});
  575. if(this.taskType=="2"){
  576. params.taskType = "2"
  577. }
  578. if(this.zoneId =='BZ'){
  579. params.code = this.zoneId
  580. }
  581. productlineAvailabilityApi
  582. .overTimeTaskSum(this.page, this.limit, params)
  583. .then((response) => {
  584. const res = response.data;
  585. this.overTimeList = (res.data || []).records;
  586. if(this.overTimeList){
  587. this.overTimeData.totalNum = this.overTimeList[0]? this.overTimeList[0].totalNum : 0
  588. this.overTimeData.overTimeVal = this.overTimeList[0]? this.overTimeList[0].totalRealTime - this.overTimeList[0].totalExpectTime : 0
  589. this.overTimeData.avgOverTimeVal = this.overTimeList[0]? parseInt((this.overTimeList[0].totalRealTime - this.overTimeList[0].totalExpectTime)/(this.overTimeList[0].daySpan * this.overTimeList[0].totalNum )) : 0
  590. this.overTimeData.actuateTime = this.overTimeList[0]? 1230 - parseInt(this.overTimeData.avgOverTimeVal) : 1230
  591. this.overTimeData.actuateTimeRate = this.overTimeList[0]? parseInt(this.overTimeData.actuateTime* 100/1260) : 97
  592. }
  593. });
  594. productlineAvailabilityApi.taskStatusSum(params).then((response) => {
  595. const res = response.data;
  596. this.taskStatusList = (res.data || {});
  597. this.taskStatusData.finishNum = this.taskStatusList? parseInt(this.taskStatusList.finishNum) : 0
  598. this.taskStatusData.unFinishNum = this.taskStatusList? parseInt(this.taskStatusList.unFinishNum) : 0
  599. this.taskStatusData.finishRate = this.taskStatusList? parseInt(this.taskStatusData.finishNum * 100/(this.taskStatusData.finishNum+this.taskStatusData.unFinishNum)) : 0
  600. })
  601. productlineAvailabilityApi.taskAGVSum(params).then((response) => {
  602. const res = response.data;
  603. this.taskAGVData = (res.data || {});
  604. this.taskAGVData.finishNum = this.taskAGVData? parseInt(this.taskAGVData.finishNum) : 0
  605. this.taskAGVData.totalNum = this.taskAGVData? parseInt(this.taskAGVData.totalNum) : 0
  606. this.taskAGVData.finishRate = this.taskAGVData? parseInt(this.taskAGVData.finishNum * 100/(this.taskAGVData.totalNum)) : 0
  607. this.taskAGVData.avgRunTime = this.taskAGVData ? parseInt(this.taskAGVData.avgRunTime) : 0
  608. })
  609. let bool = this.taskType == "1"? true : false;
  610. if(bool){
  611. productlineAvailabilityApi
  612. .deviceResourceSum(this.page, this.limit, params)
  613. .then((response) => {
  614. const res = response.data;
  615. this.tableData = (res.data || []).records;
  616. this.totalNum = 0
  617. if(this.tableData){
  618. this.tableData.forEach(item => {
  619. this.totalNum += Number(item.totalNum)
  620. })
  621. }
  622. //this.performanceActualRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * this.tableData[0].totalNum/
  623. let avgActualTime = this.tableData[0] ? parseInt(this.tableData[0].totalRealTime/this.tableData[0].daySpan) : 0
  624. let errRealTime = this.tableData[0] ? parseInt((this.tableData[0].totalRealTime - this.tableData[0].totalExpectTime)/this.tableData[0].daySpan) : 0
  625. this.avgActualTime = (avgActualTime - errRealTime < 1230)? avgActualTime - errRealTime : 1230
  626. this.performanceRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * 100/this.tableData[0].totalRealTime) : 0
  627. this.total = (res.data || []).total;
  628. });
  629. }else{
  630. productlineAvailabilityApi
  631. .robotTaskSum(this.page, this.limit, params)
  632. .then((response) => {
  633. const res = response.data;
  634. this.tableData = (res.data || []).records;
  635. this.totalNum = 0
  636. if(this.tableData){
  637. this.tableData.forEach(item => {
  638. this.totalNum += Number(item.totalNum)
  639. })
  640. }
  641. let avgActualTime = this.tableData[0] ? parseInt(this.tableData[0].totalRealTime/this.tableData[0].daySpan) : 0
  642. let errRealTime = this.tableData[0] ? parseInt((this.tableData[0].totalRealTime - this.tableData[0].totalExpectTime)/this.tableData[0].daySpan) : 0
  643. this.avgActualTime = (avgActualTime - errRealTime < 1230)? avgActualTime - errRealTime : 1230
  644. this.performanceRate = this.tableData[0] ? parseInt(this.tableData[0].totalExpectTime * 100/this.tableData[0].totalRealTime) : 0
  645. this.total = (res.data || []).total;
  646. });
  647. }
  648. },
  649. //根据id查询
  650. fetchDataById(row) {
  651. //弹出框
  652. this.row2 = row
  653. this.dialogVisible = true;
  654. const obj = {
  655. resourceId: row.resourceId,
  656. zoneId: row.zoneId,
  657. startDate: this.searchObj.startDate,
  658. endDate: this.searchObj.endDate,
  659. month: this.searchObj.month,
  660. years: this.searchObj.years
  661. }
  662. this.tableKey = !this.tableKey;
  663. productlineAvailabilityApi
  664. .deviceResourceDetail(this.page2,this.limit2,obj)
  665. .then((response) => {
  666. const res = response.data;
  667. this.formData = (res.data || []).records;
  668. this.total2 = (res.data || []).total;
  669. });
  670. },
  671. // 每页记录数改变,size:回调参数,表示当前选中的“每页条数”
  672. changePageSize(size) {
  673. this.limit = size;
  674. this.fetch();
  675. },
  676. // 改变页码,page:回调参数,表示当前选中的“页码”
  677. changeCurrentPage(page) {
  678. this.page = page;
  679. this.fetch();
  680. },
  681. changePageSize2(size) {
  682. this.limit2 = size;
  683. console.log("执行")
  684. this.fetchDataById(this.row2);
  685. },
  686. changeCurrentPage2(page) {
  687. this.page2 = page;
  688. console.log("执行")
  689. this.fetchDataById(this.row2);
  690. },
  691. //清空
  692. resetData() {
  693. this.searchObj = {};
  694. this.fetch();
  695. },
  696. viewClose() {
  697. this.dialogVisible = false
  698. },
  699. view(type){
  700. let value = type=='task'? this.taskStatusData.finishRate : this.taskAGVData.finishRate
  701. if(value == null || value == 100) return false;
  702. let params = Object.keys(this.searchObj).filter((key) => this.searchObj[key] !== null && this.searchObj[key] !== "")
  703. .reduce((acc, key) => ({ ...acc, [key]: this.searchObj[key] }), {});
  704. if(this.taskType=='2'){
  705. params.taskType = '2'
  706. }
  707. //if(this.zoneId =='BZ'){
  708. params.code = this.zoneId
  709. //}
  710. params.type = type
  711. this.$refs.view.setTenant(params)
  712. this.dialogVisible = true
  713. },
  714. cellClick(row, column) {
  715. if (column["columnKey"] === "operation") {
  716. return;
  717. }
  718. let flag = false;
  719. this.selection.forEach((item) => {
  720. if (item.id === row.id) {
  721. flag = true;
  722. this.$refs.table.toggleRowSelection(row);
  723. }
  724. });
  725. if (!flag) {
  726. this.$refs.table.toggleRowSelection(row, true);
  727. }
  728. },
  729. onSelectChange(selection) {
  730. this.selection = selection;
  731. },
  732. getZoneList() {
  733. areaMgrApi.getList({ status: 1 }).then((res) => {
  734. res = res.data;
  735. if (res.isSuccess) {
  736. if(res.data){
  737. this.zoneList = res.data.filter(item => item.name.indexOf('保障') ==-1)
  738. this.zoneId = this.zoneList[1].id
  739. }
  740. }
  741. });
  742. },
  743. //导出
  744. exportData() {
  745. productlineAvailabilityApi.exportTaskResourceSum(this.searchObj).then((res) => {
  746. if (!res) return;
  747. const blob = new Blob([res.data], {
  748. type: "application/vnd.ms-excel;",
  749. });
  750. const a = document.createElement("a");
  751. // 生成文件路径
  752. let href = window.URL.createObjectURL(blob);
  753. a.href = href;
  754. // 文件名中有中文 则对文件名进行转码
  755. a.download = decodeURIComponent("任务资源汇总导出");
  756. // 利用a标签做下载
  757. document.body.appendChild(a);
  758. a.click();
  759. document.body.removeChild(a);
  760. window.URL.revokeObjectURL(href);
  761. this.allloading = false;
  762. });
  763. },
  764. //
  765. objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  766. if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
  767. const _row = this.flitterData(this.formData).one[rowIndex];
  768. const _col = _row > 0 ? 1 : 0;
  769. return {
  770. rowspan: _row,
  771. colspan: _col,
  772. };
  773. }
  774. },
  775. /**合并表格的第一列,处理表格数据 */
  776. flitterData(arr) {
  777. let spanOneArr = [];
  778. let concatOne = 0;
  779. arr.forEach((item, index) => {
  780. if (index === 0) {
  781. spanOneArr.push(1);
  782. } else {
  783. //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
  784. if (item.quarterly === arr[index - 1].quarterly) {
  785. //第一列需合并相同内容的判断条件
  786. spanOneArr[concatOne] += 1;
  787. spanOneArr.push(0);
  788. } else {
  789. spanOneArr.push(1);
  790. concatOne = index;
  791. }
  792. }
  793. });
  794. return {
  795. one: spanOneArr,
  796. };
  797. }
  798. },
  799. };
  800. </script>
  801. <style lang="scss" scoped>
  802. .indicator-card {
  803. margin-top: 20px;
  804. .item, .item2{
  805. margin-bottom: 10px;
  806. font-size: 14px;
  807. color: #333;
  808. font-weight: bold;
  809. .formula{
  810. font-size: 12px;
  811. color: #999;
  812. padding: 5px;
  813. border-radius: 5px;
  814. margin-left: 10px;
  815. }
  816. }
  817. .item3{
  818. margin-top: 20px;
  819. font-size: 18px;
  820. color: #333;
  821. font-weight: bold;
  822. }
  823. }
  824. >>> .item2 .el-statistic .con .number {
  825. font-size: 14px;
  826. font-weight: bold;
  827. padding: 4px;
  828. }
  829. .like {
  830. cursor: pointer;
  831. font-size: 25px;
  832. display: inline-block;
  833. }
  834. .like > a {
  835. cursor: pointer;
  836. text-decoration:underline;
  837. color: #1900ffe2;
  838. }
  839. .rowBtn {
  840. margin: 0 5px;
  841. color: #1890ff;
  842. }
  843. .rowBtn:hover {
  844. opacity: 0.7;
  845. }
  846. </style>