index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. <script setup name="prepare">
  2. import excelCop from '@/components/excel.vue'
  3. import treeCop from '@/components/tree.vue'
  4. import barChartCop from './components/barChart.vue'
  5. import SubmitBtn from '@/components/SubmitBtn.vue'
  6. import { ref, nextTick, onActivated, onMounted, reactive } from 'vue'
  7. import request from '@/api/axios.js'
  8. import { ElMessage } from 'element-plus'
  9. import util from "@tools/util";
  10. import CurrentScatterChart from './components/current-scatter-chart.vue'
  11. // import dotRes from '@/data/dot.json'
  12. // import tableRes from '@/data/table.json'
  13. // import areaDataRes from '@/data/areaData.json'
  14. /**配置参数 */
  15. const treeHeight = ref(window.innerHeight - 160 + 'px') //tree高度
  16. const excelHeight = ref(window.innerHeight - 160 + 'px') //excel高度
  17. const tableHeight = ref(window.innerHeight - 160 + 'px')
  18. /**excel 开始 */
  19. const excelCheckboxShow = ref(false)
  20. const excelCheckIds = ref([])
  21. const excelList = ref([])
  22. const funExcelChange = async (obj) => { //点击excel项时
  23. return false
  24. }
  25. const funExcelCheckChange = ({ checkArr, data }) => { //bug
  26. excelCheckIds.value = checkArr
  27. funSubmit()
  28. }
  29. /**prepare tree 开始 */
  30. const treeData = ref([])
  31. const actTreeNode = ref(null) //当前激活的treeNode
  32. const funRepeatMap = (arr, type='fitting') => {
  33. return arr.map(o => {
  34. if (o.children) {
  35. const findIndex = o.children.findIndex(p => !!p.type)
  36. if (findIndex !== -1) {
  37. o.childs = o.children
  38. o.children = []
  39. if(!actTreeNode.value && type === 'fitting'){ //判断当且仅有process获取tree时 赋值
  40. actTreeNode.value = o
  41. }
  42. }
  43. }
  44. return {
  45. ...o,
  46. children: o.children ? funRepeatMap(o.children, type) : []
  47. }
  48. })
  49. }
  50. const funGetTree = async () => {
  51. const res = await request.get("/power/fitting/tree")
  52. treeData.value = funRepeatMap(res.data)
  53. excelList.value = []
  54. }
  55. const funCurrentChange = ({ current, currentNode }) => {
  56. excelCheckboxShow.value = true
  57. if (current.childs) {
  58. excelList.value = current.childs.map(o => {
  59. return {
  60. id: o.id,
  61. interval: o.interval,
  62. path: o.path,
  63. prepareid: o.prepareid,
  64. station: o.station,
  65. time: o.time,
  66. type: o.type,
  67. windturbine: o.windturbine,
  68. name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
  69. }
  70. })
  71. } else {
  72. excelList.value = []
  73. }
  74. }
  75. const funTreeCheckChange = ({ current, checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) => { //tree change -> excel change
  76. funCurrentChange({ current, currentNode: '' })
  77. const checkIds = []
  78. if (checkedNodes.length) {
  79. for (const node of checkedNodes) {
  80. if (node.childs && node.childs.length) {
  81. for (const child of node.childs) {
  82. checkIds.push(child.id)
  83. }
  84. }
  85. }
  86. }
  87. excelCheckIds.value = checkIds
  88. funSubmit()
  89. }
  90. /**search 开始 */
  91. const funSubmit = async () => {
  92. if (!excelCheckIds.value.length) {
  93. ElMessage.error('请勾选要预处理的项')
  94. return false
  95. }
  96. wtData.value = []
  97. const params = {
  98. ids: excelCheckIds.value.join(',')
  99. }
  100. const res = await request.get('/power/fitting/line', { params: params })
  101. if (res.code === 200) {
  102. seriesData.value = []
  103. if(res.data.bzgl){
  104. seriesData.value.push(
  105. {
  106. name: "保证功率",
  107. type: "line",
  108. symbol: "line", //设定为实心点
  109. symbolSize: 0, //设定实心点的大小
  110. smooth: true, //这个是把线变成曲线
  111. data: res.data.bzgl || [],
  112. xAxisIndex: 0,
  113. },
  114. )
  115. }
  116. if(res.data.sjgl?.length){
  117. for(const wtObj of res.data.sjgl){
  118. seriesData.value.push(
  119. {
  120. name: wtObj.obj.windturbine + "\n实际功率",
  121. type: "line",
  122. symbol: "line", //设定为实心点
  123. symbolSize: 0, //设定实心点的大小
  124. smooth: true, //这个是把线变成曲线
  125. data: wtObj.sjgl || [],
  126. xAxisIndex: 0,
  127. },
  128. )
  129. wtData.value.push(wtObj.obj)
  130. }
  131. }
  132. }
  133. }
  134. /**chart Data */
  135. const avgObj = reactive({ //平均cpz等
  136. cpavg: '',
  137. frequency: '',
  138. pcratio: ''
  139. })
  140. const xAxisData = ref([])
  141. const chartRef = ref() //chart 的ref
  142. const seriesData = ref([])
  143. const isChartArea = ref(false) // 用来控制图表是否区域划分
  144. const dataSet = ref('')
  145. const funChartSelect = async (batch) => {
  146. return false
  147. }
  148. const funChartArea = () => {
  149. if (seriesData.value?.length) {
  150. // 获取数据后 展示dialog table 数据
  151. wtDialog.value = true
  152. if (!isChartArea.value) {
  153. // 请求一下
  154. seriesData.value[0] = {
  155. ...seriesData.value[0],
  156. markLine: {
  157. symbol: 'none',
  158. label: {
  159. show: false
  160. },
  161. lineStyle: {
  162. color: 'rgba(96,174,255, 1)'
  163. },
  164. data: [
  165. {
  166. xAxis: 3,
  167. valueIndex: 0,
  168. },
  169. {
  170. xAxis: 5,
  171. valueIndex: 0
  172. },
  173. {
  174. xAxis: 10,
  175. valueIndex: 0
  176. },
  177. {
  178. xAxis: 12,
  179. valueIndex: 0
  180. },
  181. {
  182. xAxis: 25,
  183. valueIndex: 0
  184. },
  185. ]
  186. },
  187. markArea: {
  188. label: {
  189. fontSize: util.vh(12),
  190. },
  191. itemStyle: {
  192. color: 'rgba(236,245,255, 0)'
  193. },
  194. emphasis: {
  195. itemStyle: {
  196. color: 'rgba(96,174,255, 0.5)'
  197. }
  198. },
  199. data: [
  200. [
  201. {
  202. name: `3~5m`,
  203. xAxis: 3,
  204. },
  205. {
  206. xAxis: 5,
  207. }
  208. ],
  209. [
  210. {
  211. name: `5~10m`,
  212. xAxis: 5,
  213. },
  214. {
  215. xAxis: 10,
  216. }
  217. ],
  218. [
  219. {
  220. name: `10~12m`,
  221. xAxis: 10,
  222. },
  223. {
  224. xAxis: 12,
  225. }
  226. ],
  227. [
  228. {
  229. name: `12~25m`,
  230. xAxis: 12,
  231. },
  232. {
  233. xAxis: 25,
  234. }
  235. ],
  236. ]
  237. },
  238. }
  239. isChartArea.value = true
  240. } else {
  241. seriesData.value[0] = {
  242. ...seriesData.value[0],
  243. markLine: null,
  244. markArea: null,
  245. }
  246. isChartArea.value = false
  247. }
  248. }
  249. }
  250. const funTimeArea = async () => {
  251. if(seriesData.value?.length){
  252. //获取数据
  253. const res = await request.get('/power/fitting/time',{params: {ids: excelCheckIds.value.join(',')}})
  254. console.log(res)
  255. if(res.code===200){
  256. barxAxis.data = []
  257. barSeries.value = [{
  258. name: "3~5m功率",
  259. type: "bar",
  260. stack: 'a',
  261. data: [],
  262. },{
  263. name: "5~10m功率",
  264. type: "bar",
  265. stack: 'a',
  266. data: [],
  267. },{
  268. name: "10~12m功率",
  269. type: "bar",
  270. stack: 'a',
  271. data: [],
  272. },{
  273. name: "12~25m全功率",
  274. type: "bar",
  275. stack: 'a',
  276. data: [],
  277. },{
  278. name: "不运行",
  279. type: "bar",
  280. stack: 'a',
  281. data: [],
  282. }]
  283. for(const wtObj of res.data){
  284. barxAxis.data.push(wtObj.wtId)
  285. for(const timeKey in wtObj.time){
  286. barSeries.value[timeKey].data.push((wtObj.time[timeKey]/60).toFixed(0))
  287. }
  288. }
  289. tmDialog.value = true
  290. }
  291. }
  292. }
  293. /**dialog 数据 */
  294. const wtDialog = ref(false)
  295. const wtData = ref([])
  296. /**tmdialog 数据 */
  297. const tmDialog = ref(false)
  298. const barxAxis = reactive({
  299. type: 'category',
  300. data: [],
  301. splitLine: {
  302. show: false
  303. },
  304. axisTick: {
  305. show: true
  306. }
  307. })
  308. const baryAxis = ref({
  309. type: 'value',
  310. name: '小时',
  311. splitLine: {
  312. show: false
  313. },
  314. axisTick: {
  315. show: true
  316. }
  317. })
  318. const barSeries = ref([{
  319. name: "3~5m功率",
  320. type: "bar",
  321. stack: 'a',
  322. data: [],
  323. },{
  324. name: "5~10m功率",
  325. type: "bar",
  326. stack: 'a',
  327. data: [],
  328. },{
  329. name: "10~12m功率",
  330. type: "bar",
  331. stack: 'a',
  332. data: [],
  333. },{
  334. name: "12~25m全功率",
  335. type: "bar",
  336. stack: 'a',
  337. data: [],
  338. },{
  339. name: "不运行",
  340. type: "bar",
  341. stack: 'a',
  342. data: [],
  343. }])
  344. /**created */
  345. // funGetTree()
  346. // funGetProcessTree()
  347. /**mounted */
  348. onMounted(() => {
  349. tableHeight.value = window.innerHeight - 160 + 'px'
  350. excelHeight.value = window.innerHeight - 160 + 'px'
  351. treeHeight.value = window.innerHeight - 160 + 'px'
  352. window.addEventListener('resize', () => {
  353. tableHeight.value = window.innerHeight - 160 + 'px'
  354. excelHeight.value = window.innerHeight - 160 + 'px'
  355. treeHeight.value = window.innerHeight - 160 + 'px'
  356. })
  357. /**test */
  358. // funExcelChange({
  359. // id: 1,
  360. // name: 'excel',
  361. // type: 'fitting',
  362. // })
  363. })
  364. /**activated */
  365. onActivated(() => {
  366. funGetTree()
  367. })
  368. </script>
  369. <template>
  370. <div class="bg-white py-[10px] px-[10px] s-dialog-body">
  371. <el-dialog draggable width="1000px" v-model="tmDialog" title="时间占比">
  372. <bar-chart-cop height="700px" width="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
  373. </el-dialog>
  374. <el-dialog draggable v-model="wtDialog" title="曲线偏差率">
  375. <el-table :data="wtData" row-key="id" :max-height="550">
  376. <el-table-column property="windturbine" align="center" label="风机" />
  377. <el-table-column
  378. property="pc5ratio"
  379. sortable
  380. align="center"
  381. label="3~5m"
  382. />
  383. <el-table-column
  384. property="pc10ratio"
  385. sortable
  386. align="center"
  387. label="5~10m"
  388. />
  389. <el-table-column
  390. property="pc12ratio"
  391. sortable
  392. align="center"
  393. label="10~12m"
  394. />
  395. <el-table-column
  396. property="pc25ratio"
  397. sortable
  398. align="center"
  399. label="12~25m"
  400. />
  401. <el-table-column
  402. property="pcratio"
  403. sortable
  404. align="center"
  405. label="3~25m"
  406. />
  407. </el-table>
  408. </el-dialog>
  409. <div
  410. class="
  411. relative
  412. shadow
  413. rounded-[6px]
  414. shadow-blue-500
  415. px-[10px]
  416. pt-[20px]
  417. pb-[10px]
  418. "
  419. >
  420. <div class="text-[14px] absolute top-[-7px] text-[#B3B3B3] left-[20px]">
  421. 数据展示
  422. </div>
  423. <el-row :gutter="10">
  424. <el-col :span="5">
  425. <tree-cop
  426. :data="treeData"
  427. @checkChange="funTreeCheckChange"
  428. :show-checkbox="true"
  429. :height="treeHeight"
  430. @currentChange="funCurrentChange"
  431. @refresh="funGetTree"
  432. ></tree-cop>
  433. </el-col>
  434. <el-col :span="3">
  435. <excel-cop
  436. :checkIds="excelCheckIds"
  437. :showCheckbox="excelCheckboxShow"
  438. :data="excelList"
  439. :height="excelHeight"
  440. @excelChange="funExcelChange"
  441. @checkChange="funExcelCheckChange"
  442. ></excel-cop>
  443. </el-col>
  444. <el-col :span="16">
  445. <div class="px-[10px] shadow rounded-[6px] shadow-blue-500">
  446. <SubmitBtn
  447. class="absolute right-[106px] top-[6px] z-10"
  448. desc="区域划分"
  449. @click="funChartArea"
  450. ></SubmitBtn>
  451. <SubmitBtn
  452. class="absolute right-[16px] top-[6px] z-10"
  453. desc="时间占比"
  454. @click="funTimeArea"
  455. ></SubmitBtn>
  456. <div
  457. :style="{
  458. height:
  459. typeof tableHeight === 'string'
  460. ? tableHeight
  461. : tableHeight + 'px',
  462. }"
  463. class="p-[10px]"
  464. >
  465. <CurrentScatterChart
  466. ref="chartRef"
  467. width="100%"
  468. :height="`calc( ${tableHeight} - 40px )`"
  469. chartTitle=""
  470. :xAxisData="xAxisData"
  471. :yAxisData="{ splitLine: { show: false } }"
  472. :seriesData="seriesData"
  473. :showLegend="true"
  474. :brushSelected="!isChartArea"
  475. :dataSet="dataSet"
  476. @getSelected="funChartSelect"
  477. />
  478. </div>
  479. </div>
  480. </el-col>
  481. </el-row>
  482. </div>
  483. </div>
  484. </template>
  485. <style scoped>
  486. .s-dialog-body /deep/ .el-dialog__body{
  487. padding: 0px 20px;
  488. }
  489. </style>