index.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. <template>
  2. <div class="app-container">
  3. <div class="dark-el-input dark-el-button">
  4. <el-form ref="queryForm" size="small" :inline="true" popper-class="cpp-popper">
  5. <el-form-item label="预测日期">
  6. <el-date-picker
  7. :clearable="false"
  8. v-model="dateTime"
  9. type="date"
  10. :picker-options="expireDateOption"
  11. placeholder="选择生成日期">
  12. </el-date-picker>
  13. </el-form-item>
  14. <el-form-item label="场站名称">
  15. <el-select v-model="stationCode" placeholder="请选择" popper-class="cpp-popper">
  16. <el-option
  17. v-for="item in stationList"
  18. :key="item.value"
  19. :label="item.label"
  20. :value="item.value">
  21. </el-option>
  22. </el-select>
  23. </el-form-item>
  24. <el-form-item>
  25. <el-button type="primary" size="small" style="margin-left: 5px" icon="el-icon-search" @click="dataQuery">
  26. 查询
  27. </el-button>
  28. </el-form-item>
  29. </el-form>
  30. </div>
  31. <el-row>
  32. <el-col :span="7">
  33. <div class="divDescribe">调控策略</div>
  34. <div class="divDescribe">调控截止时间:{{ this.dqEndTime }}</div>
  35. <div class="divDescribe">调控方式:调控值=原始值*系数+数值</div>
  36. <div class="divDescribeBtn">
  37. <div class="dark-el-input dark-el-button">
  38. <el-button type="primary" size="small" style="margin-left: 5px" @click="quickUse">一键应用</el-button>
  39. <el-button type="primary" size="small" style="margin-left: 5px" @click="usualSet">设为常用</el-button>
  40. </div>
  41. </div>
  42. <div class="divTable">
  43. <el-table
  44. :data="tableData"
  45. height="550px"
  46. :loading="loading"
  47. size="mini"
  48. style="width: 100%">
  49. <el-table-column
  50. prop="time"
  51. header-align="center"
  52. align="center"
  53. label="时间"
  54. >
  55. </el-table-column>
  56. <el-table-column
  57. prop="xs"
  58. header-align="center"
  59. align="center"
  60. label="系数">
  61. <template slot-scope="scope">
  62. <vxe-input type="number" v-model="scope.row.xs" size="small" style="width:100%" min="0"
  63. placeholder="" @change="setValueByManual(scope.row,scope.$index)"></vxe-input>
  64. </template>
  65. </el-table-column>
  66. <el-table-column
  67. prop="sz"
  68. header-align="center"
  69. align="center"
  70. label="数值">
  71. <template slot-scope="scope">
  72. <vxe-input type="number" v-model="scope.row.sz" size="small" style="width:100%"
  73. placeholder="" @change="setValueByManual(scope.row,scope.$index)"></vxe-input>
  74. </template>
  75. </el-table-column>
  76. <el-table-column
  77. prop="ysValue"
  78. header-align="center"
  79. align="center"
  80. label="原始值">
  81. </el-table-column>
  82. <el-table-column
  83. prop="tkValue"
  84. header-align="center"
  85. align="center"
  86. label="调控值"
  87. :max="capacity"
  88. :min="0"
  89. >
  90. </el-table-column>
  91. </el-table>
  92. </div>
  93. <div class="tkBtn">
  94. <div class="dark-el-input dark-el-button">
  95. <el-button type="primary" size="small" style="margin-left: 5px" @click="tkDialog">调控功率</el-button>
  96. </div>
  97. </div>
  98. </el-col>
  99. <el-col :span="17">
  100. <div style="float:left;width: 95%;height: 750px" id="tkcharts"></div>
  101. </el-col>
  102. </el-row>
  103. <div class="dark-el-dialog">
  104. <el-dialog :visible.sync="usualOpen" :before-close="cancelUsual" :close-on-click-modal="false" width="450px"
  105. height="600px">
  106. <el-form ref="usualForm" :model="usualForm" width="430px" label-width="70px">
  107. <el-row class="mb4">
  108. <el-col :span="24">
  109. <el-form-item label="常用名称" prop="name">
  110. <el-input style="width: 100%" v-model="usualForm.usualName" maxlength="15" popper-class="cpp-popper"/>
  111. </el-form-item>
  112. </el-col>
  113. </el-row>
  114. <el-row class="mb4">
  115. <el-col>
  116. <div style="color: #fff">保存常用名可以在一键应用中找到历史调控策略。</div>
  117. </el-col>
  118. </el-row>
  119. </el-form>
  120. <div slot="footer" class="dialog-footer">
  121. <el-button type="primary" @click="commitUsual">确 定</el-button>
  122. <el-button @click="cancelUsual">取 消</el-button>
  123. </div>
  124. </el-dialog>
  125. </div>
  126. <div class="dark-el-dialog">
  127. <el-dialog :visible.sync="tkOpen" :close-on-click-modal="false" width="700px" height="600px">
  128. <div class="flex" style="color:#ffffff;">
  129. 确认对
  130. <span style="background: #d3a4ff">{{ this.tkrq }}</span>
  131. 日,
  132. <span style="background: #d3a4ff">{{ this.stationName }}</span>
  133. 的短期功率调控,调控后数据将下发到对应场站上报调度。
  134. </div>
  135. <div slot="footer" class="dialog-footer">
  136. <el-button type="primary" @click="tkCommit">确 定</el-button>
  137. <el-button @click="tkCancel">取 消</el-button>
  138. </div>
  139. </el-dialog>
  140. </div>
  141. <!-- 策略选择弹窗 -->
  142. <div class="dark-el-dialog">
  143. <el-dialog :visible.sync="quickUseOpen" :before-close="cancelQuickUse" :close-on-click-modal="false"
  144. style="height: calc(100% - 50px)">
  145. <div class="reg-config-container flex justify-between">
  146. <div class="reg-config-con">
  147. <span class="flex justify-center dialog-text-title">策略选择</span>
  148. <!-- 策略列表 -->
  149. <div class="reg-config flex">
  150. <div class="reg-config-radio" style="margin-top: 15px">
  151. <el-radio v-model="vradio" label="1" @click.native.prevent="radioChange('1')">快捷选择历史策略:
  152. </el-radio>
  153. </div>
  154. <div class="flex-column reg-config-btu">
  155. <!-- 循环生成按钮 -->
  156. <el-button
  157. v-for="(button, index) in buttons"
  158. :key="index"
  159. @click="handleButtonClick(button.usualName)"
  160. >
  161. {{ button.usualName }}
  162. </el-button>
  163. </div>
  164. </div>
  165. <div class="reg-config flex items-center">
  166. <div class="reg-config-radio">
  167. <el-radio v-model="vradio" label="2" @click.native.prevent="radioChange('2')">选择历史策略:</el-radio>
  168. </div>
  169. <div>
  170. <el-select ref="selectUsualName" v-model="usualId" placeholder="请选择" popper-class="cpp-popper"
  171. :disabled="disabled" @change="changeUsualName">
  172. <el-option
  173. v-for="item in usualList"
  174. :key="item.id"
  175. :label="item.usualName"
  176. :value="item.id">
  177. </el-option>
  178. </el-select>
  179. </div>
  180. </div>
  181. <div id="currentSelectFunction" style="display: none;margin-top: 30px;margin-left: 24px;" class="reg-config flex items-center">
  182. <div>当前选择策略:</div>
  183. <div style="width: 215px">
  184. {{ this.currentStrategy }}
  185. </div>
  186. <div>
  187. <el-button @click="trialPreview">预览</el-button>
  188. <el-button @click="trialDelete">删除</el-button>
  189. </div>
  190. </div>
  191. <div slot="footer" class="reg-dialog-footer">
  192. <el-button type="primary" @click="quickUseCommit">一键应用</el-button>
  193. <el-button @click="cancelQuickUse">取 消</el-button>
  194. </div>
  195. </div>
  196. <!-- <el-divider direction="vertical" style="height: calc(100% - 30px)"></el-divider>-->
  197. <div>
  198. <!-- 预览表格 -->
  199. <span class="flex justify-center dialog-text-title">预览策略展示</span>
  200. <el-table
  201. :data="trialData"
  202. height="550px"
  203. :loading="loading"
  204. size="mini"
  205. style="width: 100%;margin-top: 13px;">
  206. <el-table-column
  207. prop="time"
  208. header-align="center"
  209. align="center"
  210. label="时间"
  211. >
  212. </el-table-column>
  213. <el-table-column
  214. prop="xs"
  215. header-align="center"
  216. align="center"
  217. label="系数">
  218. </el-table-column>
  219. <el-table-column
  220. prop="sz"
  221. header-align="center"
  222. align="center"
  223. label="数值">
  224. </el-table-column>
  225. <el-table-column
  226. prop="ysValue"
  227. header-align="center"
  228. align="center"
  229. label="原始值">
  230. </el-table-column>
  231. <el-table-column
  232. prop="tkValue"
  233. header-align="center"
  234. align="center"
  235. label="调控值"
  236. :max="capacity"
  237. :min="0"
  238. >
  239. </el-table-column>
  240. </el-table>
  241. </div>
  242. </div>
  243. </el-dialog>
  244. </div>
  245. </div>
  246. </template>
  247. <script>
  248. import * as echarts from "echarts";
  249. export default {
  250. name: 'inverterinfo',
  251. data() {
  252. return {
  253. dqEndTime: '',
  254. markLineData: new Array(),
  255. visualMapPieces: new Array(),
  256. trialData: [],
  257. disabled: true,
  258. vradio: '1',
  259. buttons: new Array(),
  260. usualId: '',
  261. usualList: [],
  262. currentStrategy: '',
  263. stationName: '',
  264. tkrq: '',
  265. quickUseOpen: false,
  266. tkOpen: false,
  267. usualOpen: false,
  268. usualForm: {
  269. usualName: undefined
  270. },
  271. expireDateOption: {
  272. disabledDate(time) {
  273. return time.getTime() < Date.now()
  274. }
  275. },
  276. loading: false,
  277. symbolSize: 8,
  278. capacity: '',
  279. tkData: [],
  280. tableData: [],
  281. hoursArray: [],
  282. chart: null,
  283. form: [],
  284. dateTime: new Date(new Date().toLocaleDateString()).getTime() + (60 * 60 * 24 * 1000),
  285. stationList: [],
  286. stationCode: '',
  287. ysData: [],
  288. refUpData: [],
  289. refDownData: [],
  290. chartOption: {
  291. backgroundColor: 'transparent',
  292. title: {
  293. top: 20,
  294. text: '短期调控曲线',
  295. textStyle: {
  296. fontWeight: 'normal',
  297. fontSize: 16,
  298. },
  299. left: 'center'
  300. },
  301. tooltip: {
  302. trigger: 'axis',
  303. axisPointer: {
  304. lineStyle: {
  305. color: '#57617B'
  306. }
  307. }
  308. },
  309. legend: {
  310. top: 20,
  311. icon: 'rect',
  312. itemWidth: 14,
  313. itemHeight: 5,
  314. itemGap: 13,
  315. data: ['原始值', '调控值', '参考值上限', '参考值下限'],
  316. right: '4%',
  317. textStyle: {
  318. fontSize: 12,
  319. // color: this.lineColor
  320. },
  321. selected: {
  322. '原始值': true,
  323. '调控值': true,
  324. '参考值上限': true,
  325. '参考值下限': true,
  326. }
  327. },
  328. dataZoom: [{
  329. show: true,
  330. realtime: true,
  331. start: 0,
  332. end: 100,
  333. left: "15%",
  334. right: "15%",
  335. throttle: 50
  336. }, {
  337. type: 'inside'
  338. }],
  339. grid: {
  340. top: 100,
  341. left: '2%',
  342. right: '2%',
  343. bottom: '10%',
  344. containLabel: true
  345. },
  346. xAxis: [{
  347. type: 'category',
  348. boundaryGap: false,
  349. axisLine: {onZero: false},
  350. }],
  351. yAxis: [{
  352. type: 'value',
  353. name: 'MW',
  354. axisTick: {
  355. show: false
  356. },
  357. axisLabel: {
  358. margin: 10,
  359. textStyle: {
  360. fontSize: 14
  361. }
  362. },
  363. splitLine: {
  364. lineStyle: {
  365. color: '#57617B'
  366. }
  367. }
  368. }],
  369. series: [{
  370. name: '原始值',
  371. type: 'line',
  372. smooth: true,
  373. symbol: 'circle',
  374. symbolSize: 5,
  375. showSymbol: false,
  376. connectNulls: true,
  377. lineStyle: {
  378. normal: {
  379. width: 2
  380. }
  381. },
  382. itemStyle: {
  383. normal: {
  384. color: 'rgb(219,50,51)',
  385. borderWidth: 12
  386. }
  387. },
  388. data: this.ysData
  389. },
  390. {
  391. id: 'a',
  392. name: '调控值',
  393. type: 'line',
  394. showSymbol: false,
  395. smooth: true,
  396. symbol: 'circle',
  397. symbolSize: 10,
  398. connectNulls: true,
  399. lineStyle: {
  400. normal: {
  401. color: 'rgb(0,136,212)',
  402. width: 2
  403. }
  404. },
  405. itemStyle: {
  406. normal: {
  407. color: 'rgb(0,136,212)',
  408. borderWidth: 50
  409. }
  410. },
  411. data: []
  412. },
  413. {
  414. name: '参考值上限',
  415. type: 'line',
  416. smooth: true,
  417. symbol: 'circle',
  418. connectNulls: true,
  419. symbolSize: 5,
  420. showSymbol: false,
  421. lineStyle: {
  422. normal: {
  423. width: 2,
  424. type: 'dashed' //设置线条类型
  425. }
  426. },
  427. itemStyle: {
  428. normal: {
  429. color: '#00FF00',
  430. borderWidth: 12
  431. }
  432. },
  433. data: this.refUpData
  434. },
  435. {
  436. name: '参考值下限',
  437. type: 'line',
  438. smooth: true,
  439. symbol: 'circle',
  440. connectNulls: true,
  441. symbolSize: 5,
  442. showSymbol: false,
  443. lineStyle: {
  444. normal: {
  445. width: 2,
  446. type: 'dashed' //设置线条类型
  447. }
  448. },
  449. itemStyle: {
  450. normal: {
  451. color: 'rgb(167,27,189)',
  452. borderWidth: 12
  453. }
  454. },
  455. data: this.refDownData
  456. },
  457. ]
  458. }
  459. }
  460. },
  461. created() {
  462. this.getStationCode()
  463. this.getDqEndTime()
  464. },
  465. mounted() {
  466. this.initChart()
  467. },
  468. beforeDestroy() {
  469. if (!this.chart) {
  470. return
  471. }
  472. this.chart.dispose()
  473. this.chart = null
  474. },
  475. computed: {},
  476. methods: {
  477. // 策略名称下拉框选择
  478. changeUsualName(id) {
  479. const item = this.usualList.find(item => item.id == id)
  480. let usualName = item ? item.usualName : ''
  481. this.currentStrategy = usualName
  482. document.getElementById("currentSelectFunction").style.display = ''
  483. },
  484. radioChange(radioValue) {
  485. document.getElementById("currentSelectFunction").style.display = 'none'
  486. this.currentStrategy = ''
  487. this.trialData = []
  488. if (radioValue == '1') {
  489. this.vradio = '1'
  490. this.usualId = ''
  491. this.disabled = true
  492. } else {
  493. this.vradio = '2'
  494. this.disabled = false
  495. }
  496. },
  497. // 默认常用按钮事件
  498. handleButtonClick(usualName) {
  499. if (this.vradio == '1') {
  500. // 执行常用按钮点击
  501. this.currentStrategy = usualName
  502. document.getElementById("currentSelectFunction").style.display = ''
  503. }
  504. },
  505. async executeTrial() {
  506. const param = {
  507. "usualName": this.currentStrategy,
  508. "stationCode": this.tableData[0].stationCode,
  509. "time": new Date(this.tableData[0].forecastDate).getTime()
  510. }
  511. // 获取策略名称的系数和数值
  512. await this.$axios.get('/dqRegulationController/trialData', {params: param}).then(response => {
  513. this.trialData = response.data
  514. })
  515. },
  516. // 删除按钮点击
  517. trialDelete() {
  518. if (this.currentStrategy == '') {
  519. this.$message.warning("请选择策略名称进行删除!")
  520. return
  521. }
  522. this.$confirm('是否确认删除【' + this.currentStrategy + '】?', '提示', {
  523. confirmButtonText: '确定',
  524. cancelButtonText: '取消',
  525. type: 'warning'
  526. }).then(() => {
  527. // 提交名称及系数配置
  528. const formData = new FormData()
  529. formData.append('usualName', this.currentStrategy)
  530. this.$axios.post('/dqUsualController/deleteUsual', formData, {
  531. headers: {
  532. 'Content-Type': 'multipart/form-data' // 设置请求头,确保服务器正确解析 FormData
  533. }
  534. }).then((res) => {
  535. this.$message.success('删除策略成功!')
  536. document.getElementById("currentSelectFunction").style.display = "none"
  537. this.trialData = []
  538. // 重新渲染下拉框
  539. this.renderUsual()
  540. }).catch((error) => {
  541. })
  542. })
  543. },
  544. // 预览按钮点击
  545. trialPreview() {
  546. if (this.currentStrategy == '') {
  547. this.$message.warning("请选择策略名称进行预览!")
  548. return
  549. }
  550. this.executeTrial()
  551. },
  552. // 一键应用中确定
  553. async quickUseCommit() {
  554. if (this.currentStrategy == '') {
  555. this.$message.warning("请选择策略进行应用!")
  556. return
  557. }
  558. await this.executeTrial()
  559. // 将列表数据赋值给底层列表
  560. this.tableData = this.trialData
  561. // 将预算的调控曲线赋值给底层曲线上
  562. let tkArray = new Array()
  563. for (var i = 0; i < this.tableData.length; i++) {
  564. let array = new Array()
  565. array.push(this.tableData[i].time)
  566. array.push(this.tableData[i].tkValue)
  567. tkArray.push(array)
  568. }
  569. this.tkData = tkArray
  570. this.chartOption.series[1].data = this.tkData
  571. this.chart.setOption(this.chartOption)
  572. //再调用updatePosition
  573. this.updatePosition()
  574. this.cancelQuickUse()
  575. },
  576. // 一键应用中取消按钮
  577. cancelQuickUse() {
  578. this.quickUseOpen = false;
  579. this.trialData = []
  580. this.currentStrategy = ''
  581. this.buttons = []
  582. this.vradio = '1'
  583. this.disabled = true
  584. document.getElementById("currentSelectFunction").style.display = 'none'
  585. },
  586. renderUsual() {
  587. this.buttons = []
  588. this.usualId = ''
  589. this.currentStrategy = ''
  590. // 先获取常用下拉框
  591. this.$axios.get('/dqUsualController/getUsualList').then(response => {
  592. this.usualList = response.data
  593. if (this.usualList.length > 0) {
  594. // 循环list,将前5个给默认常用,将第1个默认选中下拉框
  595. for (let i = 0; i < this.usualList.length; i++) {
  596. if (i < 5) {
  597. this.buttons.push(this.usualList[i])
  598. }
  599. }
  600. }
  601. })
  602. },
  603. quickUse() {
  604. if (this.tableData.length == 0) {
  605. this.$message.warning("调控列表为空,不能操作!")
  606. return
  607. }
  608. this.renderUsual()
  609. this.quickUseOpen = true
  610. },
  611. // 点击设为常用按钮触发
  612. usualSet() {
  613. if (this.tableData.length == 0) {
  614. this.$message.warning("调控列表为空,不能操作!")
  615. return
  616. }
  617. this.usualOpen = true
  618. },
  619. // 设为常用弹出框保存按钮
  620. commitUsual() {
  621. if (this.tableData == undefined || this.tableData.length == 0) {
  622. this.$message.warning("请查询列表才可以设为常用!")
  623. return
  624. }
  625. if (this.usualForm.usualName == null || this.usualForm.usualName == '' || this.usualForm.usualName == undefined) {
  626. this.$message.warning("请输入常用名称!")
  627. return
  628. } else {
  629. let tempUsualName = this.usualForm.usualName.trim()
  630. if (tempUsualName == '') {
  631. this.$message.warning("请输入常用名称!")
  632. return
  633. }
  634. // 提交名称及系数配置
  635. const param = {
  636. "tempShortRegulationDtoList": this.tableData,
  637. "usualName": tempUsualName
  638. }
  639. this.$axios.post('/dqUsualController/saveUsual', param).then((res) => {
  640. this.$message.success('常用策略保存成功!')
  641. this.usualOpen = false
  642. this.resetUsual()
  643. }).catch((error) => {
  644. })
  645. }
  646. },
  647. // 表单重置
  648. resetUsual() {
  649. this.usualForm = {
  650. usualName: undefined,
  651. },
  652. this.resetForm("usualForm");
  653. },
  654. // 取消按钮
  655. cancelUsual() {
  656. this.usualOpen = false;
  657. this.resetUsual();
  658. },
  659. tkDialog() {
  660. // 判断截止时间,超出时间不允许调控
  661. const now = new Date();
  662. if (now.getTime() > new Date(this.dqEndTime)) {
  663. this.$message.warning("截止时间已过,不能进行调控!")
  664. return
  665. }
  666. if (this.tableData.length == 0) {
  667. this.$message.warning("调控列表为空,不能操作!")
  668. return
  669. }
  670. const date = new Date(this.dateTime); // 如果long是毫秒
  671. const year = date.getFullYear();
  672. const month = (date.getMonth() + 1).toString().padStart(2, '0');
  673. const day = date.getDate().toString().padStart(2, '0');
  674. this.tkrq = `${year}-${month}-${day}`; // 根据需要可以添加时间部分
  675. const item = this.stationList.find(item => item.value === this.stationCode)
  676. this.stationName = item ? item.label : ''
  677. this.tkOpen = true
  678. },
  679. tkCancel() {
  680. this.tkOpen = false
  681. },
  682. // 调控列表提交
  683. tkCommit() {
  684. if (this.tableData.length == 0) {
  685. this.$message.warning("调控列表为空,不能进行提交!")
  686. return
  687. }
  688. // 判断系数和数值2个字段是否有为空
  689. for (let i = 0; i < this.tableData.length; i++) {
  690. if (isNaN(this.tableData[i].tkValue)) {
  691. this.$message.warning(this.tableData[i].time + "存在空值,不能进行提交!")
  692. return
  693. }
  694. }
  695. // 保存调控值列表
  696. this.$axios.post('/dqRegulationController/updateDqRegulation', this.tableData).then((res) => {
  697. this.$message.success('调控功率保存成功!')
  698. // this.dataQuery()
  699. }).catch((error) => {
  700. })
  701. this.tkOpen = false
  702. },
  703. //通过表格内系数或固定值修改 生成曲线以及最终预测结果
  704. setValueByManual(row, index) {
  705. if (row.xs !== undefined && row.sz !== undefined) {
  706. // 计算调控值
  707. row.tkValue = parseFloat((parseFloat(row.ysValue) * parseFloat(row.xs) + parseFloat(row.sz)).toFixed(2))
  708. if (row.tkValue < 0) {
  709. row.tkValue = 0
  710. }
  711. if (row.tkValue > this.capacity) {
  712. row.tkValue = this.capacity
  713. }
  714. // 赋值给表格
  715. this.tableData[index] = row
  716. // 遍历tableData封装调控曲线数组
  717. let tkArray = new Array()
  718. for (var i = 0; i < this.tableData.length; i++) {
  719. let array = new Array()
  720. array.push(this.tableData[i].time)
  721. array.push(this.tableData[i].tkValue)
  722. tkArray.push(array)
  723. }
  724. this.tkData = tkArray
  725. this.chartOption.series[1].data = this.tkData
  726. this.chart.setOption(this.chartOption)
  727. //再调用updatePosition
  728. this.updatePosition()
  729. }
  730. },
  731. dataQuery() {
  732. this.loading = true
  733. let queryParams = {
  734. "stationCode": this.stationCode,
  735. "time": Math.round(this.dateTime),
  736. }
  737. this.$axios.get('/dqRegulationController/queryData', {params: queryParams}).then(response => {
  738. this.chart.clear()
  739. this.capacity = response.data.electricField.capacity
  740. this.tableData = response.data.tempShortRegulationList
  741. this.ysData = response.data.ysData
  742. this.refUpData = response.data.refUpData
  743. this.refDownData = response.data.refDownData
  744. this.tkData = response.data.tkDataList
  745. this.draData()
  746. this.loading = false
  747. }).catch(() => {
  748. this.tableData = []
  749. this.ysData = []
  750. this.refUpData = []
  751. this.refDownData = []
  752. this.tkData = []
  753. this.chart.clear()
  754. this.chartOption.series[0].data = this.ysData
  755. this.chartOption.series[1].data = this.tkData
  756. this.chartOption.series[2].data = this.refUpData
  757. this.chartOption.series[3].data = this.refDownData
  758. this.chart.setOption(this.chartOption)
  759. this.loading = false
  760. });
  761. },
  762. draData() {
  763. let this1 = this;
  764. this.chartOption.series[0].data = this.ysData
  765. this.chartOption.series[1].data = this.tkData
  766. this.chartOption.series[2].data = this.refUpData
  767. this.chartOption.series[3].data = this.refDownData
  768. let myChart = this.chart
  769. let cap = this.capacity
  770. setTimeout(function () {
  771. myChart.setOption({
  772. graphic: this1.tkData.map(function (item, dataIndex) {
  773. return {
  774. type: 'circle',
  775. position: myChart.convertToPixel('grid', item),
  776. shape: {
  777. cx: 0,
  778. cy: 0,
  779. r: 10
  780. },
  781. invisible: true,
  782. draggable: true,
  783. ondrag: function (dx, dy,) {
  784. this1.onPointDragging(dataIndex, [item[0], dx.offsetY], cap);
  785. },
  786. onmousemove: function () {
  787. this1.showTooltip(dataIndex);
  788. },
  789. onmouseout: function () {
  790. this1.hideTooltip(dataIndex);
  791. },
  792. z: 100
  793. };
  794. })
  795. });
  796. }, 0);
  797. // window.addEventListener('resize', this1.updatePosition);
  798. myChart.on('dataZoom', this1.updatePosition);
  799. // 拖动曲线后,将数值重新赋值给表格
  800. this.chartOption.yAxis[0].max = this.capacity
  801. myChart.setOption(this.chartOption)
  802. },
  803. updatePosition() {
  804. let this1 = this;
  805. let myChart = this.chart
  806. myChart.setOption({
  807. graphic: this1.tkData.map(function (item, dataIndex) {
  808. return {
  809. position: myChart.convertToPixel('grid', item)
  810. };
  811. })
  812. });
  813. },
  814. showTooltip(dataIndex) {
  815. let myChart = this.chart
  816. myChart.dispatchAction({
  817. type: 'showTip',
  818. seriesIndex: 0,
  819. dataIndex: dataIndex
  820. });
  821. },
  822. hideTooltip(dataIndex) {
  823. let myChart = this.chart
  824. myChart.dispatchAction({
  825. type: 'hideTip'
  826. });
  827. },
  828. onPointDragging(dataIndex, pos, capacity) {
  829. let this1 = this;
  830. let myChart = this.chart
  831. this1.tkData[dataIndex][1] = myChart.convertFromPixel('grid', pos)[1].toFixed(2);
  832. if (myChart.convertFromPixel('grid', pos)[1].toFixed(2) > capacity) {
  833. this1.tkData[dataIndex][1] = capacity
  834. }
  835. if (myChart.convertFromPixel('grid', pos)[1].toFixed(2) < 0) {
  836. this1.tkData[dataIndex][1] = 0
  837. }
  838. // 赋值调控值字段
  839. this1.tableData[dataIndex].tkValue = this1.tkData[dataIndex][1]
  840. // 根据调控值更新表格中数值字段,数值=调控值-(原始值*系数)
  841. this1.tableData[dataIndex].sz = (this1.tkData[dataIndex][1] - (this1.tableData[dataIndex].ysValue * this1.tableData[dataIndex].xs)).toFixed(2)
  842. myChart.setOption(this.chartOption)
  843. // Update data
  844. myChart.setOption({
  845. series: [
  846. {
  847. id: 'a',
  848. data: this1.tkData,
  849. }
  850. ]
  851. });
  852. this.updatePosition()
  853. },
  854. // 获取短期截止时间
  855. getDqEndTime() {
  856. this.$axios({url: '/dqRegulationController/getDqEndTime', method: 'get'}).then(response => {
  857. this.dqEndTime = response.data
  858. })
  859. },
  860. getStationCode() {
  861. this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
  862. this.stationList = response.data
  863. if (this.stationList.length > 0) {
  864. this.stationCode = this.stationList[0].value
  865. }
  866. })
  867. },
  868. initChart() {
  869. for (let i = 0; i < 24 * 60; i += 15) {
  870. let hours = Math.floor(i / 60);
  871. let minutes = i % 60;
  872. this.hoursArray.push(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`);
  873. }
  874. this.chartOption.xAxis[0].data = this.hoursArray
  875. this.chart = echarts.init(document.getElementById('tkcharts'), 'dark')
  876. this.chart.setOption(this.chartOption)
  877. },
  878. }
  879. }
  880. </script>
  881. <style scoped>
  882. .divDescribe {
  883. position: relative;
  884. top: 20px; /* 向下移动15px */
  885. width: 100%;
  886. text-align: center
  887. }
  888. .divDescribeBtn {
  889. position: relative;
  890. top: 25px; /* 向下移动15px */
  891. width: 100%;
  892. text-align: right
  893. }
  894. .divTable {
  895. position: relative;
  896. top: 30px; /* 向下移动15px */
  897. width: 100%;
  898. text-align: center
  899. }
  900. .tkBtn {
  901. position: relative;
  902. top: 50px; /* 向下移动15px */
  903. width: 100%;
  904. text-align: center
  905. }
  906. .dialog-text-title {
  907. font-size: 16px;
  908. font-weight: bold;
  909. }
  910. .reg-config-container {
  911. height: 100%;
  912. }
  913. .reg-config-con {
  914. width: 50%;
  915. position: relative;
  916. }
  917. .reg-config {
  918. margin-top: 5px;
  919. }
  920. .reg-config-radio {
  921. width: 150px;
  922. }
  923. .reg-config-btu {
  924. width: 215px;
  925. //height: 190px;
  926. margin-top: 5px;
  927. }
  928. .reg-dialog-footer {
  929. position: absolute;
  930. bottom: 0;
  931. left: 35%;
  932. //text-align: center;
  933. }
  934. /deep/ .reg-config-btu .el-button:first-child {
  935. margin-top: 5px;
  936. }
  937. /deep/ .reg-config-btu .el-button {
  938. margin-top: 10px;
  939. }
  940. /deep/ .reg-config-btu .el-button:last-child {
  941. margin-bottom: 10px;
  942. }
  943. /deep/ .reg-config-btu .el-button + .el-button {
  944. margin-left: 0px;
  945. }
  946. </style>