index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. <template>
  2. <div class="lzTarget-container">
  3. <div class="left-cont minHeight">
  4. <div class="left-top">
  5. <!-- <el-button type="primary" plain size="medium" @click="exportClick" :loading="btnload">导出Excel</el-button> -->
  6. <el-button style="width:100%;" type="primary" plain size="medium" @click="exportClick" :loading="btnload">导出Excel</el-button>
  7. <el-autocomplete
  8. style="margin: 20px 0;width:100%;"
  9. prefix-icon="el-icon-search"
  10. v-model="leftSearchVal"
  11. :fetch-suggestions="handleLeftSearch"
  12. :trigger-on-focus="false"
  13. placeholder="指标名称/指标ID"
  14. @select="handleSelectLeftSearchval"
  15. popper-class="el-autocomplete-suggestion-data-entry"
  16. clearable>
  17. <template slot-scope="scope">
  18. <div v-if="scope.item.nodata" style="text-align:center">暂无数据</div>
  19. <div v-else>
  20. {{scope.item.IndexName}}
  21. </div>
  22. </template>
  23. </el-autocomplete>
  24. </div>
  25. <!-- <ul class="classify-list">
  26. <li
  27. :class="[
  28. 'classify-item',
  29. { act: select_classify === item.BreedShortName },
  30. ]"
  31. v-for="item in classifyList"
  32. :key="item.BreedShortName"
  33. @click="changeClassify(item.BreedShortName)"
  34. >
  35. {{ item.BreedShortName }}
  36. </li>
  37. </ul> -->
  38. <div>
  39. <el-tree
  40. class="filter-tree"
  41. :data="classifyList"
  42. node-key="ClassifyId"
  43. :current-node-key="select_node"
  44. :props="defaultProps"
  45. default-expand-all
  46. :default-checked-keys="[select_classify]"
  47. :filter-node-method="filterNode"
  48. ref="coalTree"
  49. highlight-current
  50. @node-click="clickClassify"
  51. >
  52. </el-tree>
  53. </div>
  54. </div>
  55. <div class="right-cont minHeight"
  56. v-loading="dataloading"
  57. element-loading-text="获取数据中...">
  58. <div
  59. class="right-box"
  60. v-infinite-scroll="loadNext"
  61. :infinite-scroll-disabled="!haveMore"
  62. :infinite-scroll-immediate="false"
  63. v-if="rightShow"
  64. >
  65. <div class="data-header">
  66. <lz-table :tableOption="tableOption" tableType="header" ref="table" source="coal"/>
  67. </div>
  68. <div class="data-cont" v-if="dateArr.length">
  69. <lz-table
  70. :tableOption="tableOption"
  71. tableType="data"
  72. :dateArr="dateArr"
  73. source="coal"
  74. />
  75. </div>
  76. <div v-else class="nodata"></div>
  77. </div>
  78. <div class="frequency-list" v-if="rightShow">
  79. <el-button
  80. type="primary"
  81. class="frequency-btn"
  82. :plain="select_frequency !== item.key"
  83. v-for="item in frequencyList"
  84. :key="item.key"
  85. @click="changeFrequency(item.key)"
  86. >{{ item.label }}</el-button
  87. >
  88. </div>
  89. </div>
  90. </div>
  91. </template>
  92. <script>
  93. import lzTable from '@/components/lzTable.vue';
  94. import { coalDataInterface } from '@/api/api.js';
  95. export default {
  96. name: '',
  97. components: { lzTable },
  98. watch: {
  99. select_classify_name(newval) {
  100. console.info("watch");
  101. console.info(newval)
  102. console.info(this.isAuto)
  103. if(!this.isAuto) return
  104. this.select_frequency = '';
  105. this.page_no = 1;
  106. newval && this.getFrequency();
  107. },
  108. select_frequency(newval) {
  109. console.info("watch");
  110. console.info(newval)
  111. console.info(this.isAuto)
  112. if(!this.isAuto) return
  113. this.page_no = 1;
  114. newval && this.getDataList();
  115. },
  116. },
  117. data() {
  118. return {
  119. dataloading: false,
  120. rightShow: false,
  121. exportBase:process.env.API_ROOT+'/entry/export/coalList',//中国煤炭网数据导出接口
  122. defaultProps:{
  123. label: 'ClassifyName',
  124. children: 'Child',
  125. },
  126. classifyList: [],
  127. select_frequency: '',
  128. frequencyType: new Map([
  129. [1, '日度'],
  130. [2, '周度'],
  131. [3, '旬度'],
  132. [4, '月度'],
  133. [5, '季度'],
  134. [6, '年度'],
  135. [99, '无固定频率'],
  136. ]),
  137. frequencyList: [],
  138. tableOption: [],
  139. dateArr: [],//最长的日期数组
  140. btnload: false,
  141. page_size: 20,
  142. page_no: 1,
  143. haveMore: false,
  144. leftSearchVal:'',//左侧搜索值
  145. leftSearchTradeCode:'', //如果是搜索选择的 则有此code
  146. select_quota:'', // 选择的指标名
  147. select_Unit:'', // 选择的单位
  148. select_UpdateTime:'', // 更新时间
  149. select_classify: '',//选择的分类id
  150. select_classify_name: '',//选择的分类名称
  151. select_node:0,
  152. isAuto:true, // 改变分类时是否自动获取数据
  153. };
  154. },
  155. methods: {
  156. /* 获取分类 */
  157. getClassify() {
  158. coalDataInterface.classifyList().then((res) => {
  159. if (res.Ret !== 200) return;
  160. this.classifyList = res.Data || [];
  161. this.select_classify =
  162. this.select_classify || this.classifyList[0].ClassifyId;
  163. this.select_classify_name=this.classifyList[0].Child[0].ClassifyName
  164. this.$nextTick(()=>{
  165. this.select_node = this.classifyList[0].Child[0].ClassifyId;
  166. this.$refs.coalTree.setCurrentKey(this.select_node);
  167. console.info("select_node")
  168. console.info(this.select_node)
  169. })
  170. });
  171. },
  172. /* 获取频度 */
  173. getFrequency(defaultSelect) {
  174. coalDataInterface
  175. .frequencyList({
  176. ClassifyId: Number(this.select_classify),
  177. })
  178. .then((res) => {
  179. if (res.Ret !== 200) return;
  180. this.frequencyList =
  181. res.Data ?
  182. res.Data.map((item) => {
  183. console.info(this.frequencyType.get(item.Frequency))
  184. return {
  185. label: this.frequencyType.get(item.Frequency),
  186. key: item.Frequency,
  187. };
  188. }) : [];
  189. console.info(this.frequencyList)
  190. //设置当前选中的频度,若传入有默认选项则选中默认频度,否则选中列表第一个
  191. this.select_frequency = defaultSelect||this.frequencyList.length ? this.frequencyList[0].key : '';
  192. !this.frequencyList.length && this.nodataDeal();
  193. //如果有默认频度,结束后恢复watcher
  194. this.$nextTick(()=>{
  195. if(defaultSelect) this.isAuto=true
  196. })
  197. });
  198. },
  199. /* 获取数据 */
  200. getDataList() {
  201. this.dataloading = true;
  202. coalDataInterface
  203. .dataList({
  204. PageSize: this.page_size,
  205. CurrentIndex: this.page_no,
  206. ClassifyId: Number(this.select_classify),
  207. GroupName:this.select_classify_name,
  208. Frequency: this.frequencyType.get(this.select_frequency),
  209. })
  210. .then((res) => {
  211. this.rightShow = true;
  212. if (res.Ret !== 200) return;
  213. // 找出最多的页码 判断是否还有数据
  214. let page_arrs = res.Data.map(item => item.Paging.Pages);
  215. let totalPage = Math.max.apply(Math,page_arrs);
  216. this.haveMore = this.page_no < totalPage ? true : false;
  217. // 合并数据
  218. if(this.page_no === 1) {
  219. this.tableOption = res.Data;
  220. }else {
  221. this.tableOption.forEach(item => {
  222. res.Data.forEach(_item => {
  223. if(item.IndexCode === _item.IndexCode) {
  224. item.DataList = [...item.DataList,..._item.DataList];
  225. }
  226. })
  227. })
  228. }
  229. // 找出所有指标中数据的日期做多的那个 拆出日期数组 用来遍历表格行 ---错误逻辑
  230. // 合并所有指标中的日期 作为日期数组
  231. let arr = res.Data.map((item) => {
  232. return item.DataList;
  233. });
  234. let obj = [];
  235. for(let i of arr) {
  236. for(let j of i) {
  237. obj.push(j.DataTime)
  238. }
  239. }
  240. let arr2 = [...new Set(obj)].sort().reverse();
  241. let concatArr = [...new Set([...this.dateArr,...arr2])].sort().reverse();
  242. this.dateArr = this.page_no === 1 ? arr2 : concatArr;
  243. /* 不满6个追加6个空的显示一排 别问 问就是为了美观 */
  244. if(res.Data.length < 7) for( let i = 0; i < 7;i++ ) {
  245. this.tableOption.push({
  246. DataList:[]
  247. })
  248. if(this.tableOption.length >= 7) break;
  249. }
  250. //数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
  251. if(this.dateArr.length < 12) for( let i = 0; i < 12;i++ ) {
  252. this.dateArr.push('')
  253. if(this.dateArr.length >= 12) break;
  254. }
  255. this.dataloading = false;
  256. this.page_no ===1 && this.$nextTick(() => {
  257. this.initWidth()
  258. })
  259. });
  260. },
  261. // 获取单个指标数据
  262. async getTargetDataList(e) {
  263. this.dataloading = true;
  264. try{
  265. const res = await coalDataInterface.getTargetDataList({
  266. IndexCode:this.leftSearchTradeCode
  267. })
  268. this.rightShow = true;
  269. if(res.Ret!==200) return
  270. // 设置为没有更多数据
  271. this.haveMore = false
  272. this.select_Unit=res.Data[0].Unit
  273. this.select_classify=res.Data[0].ClassifyId
  274. this.select_UpdateTime=res.Data[0].ModifyTime
  275. // 合并数据
  276. // this.tableOption = [{
  277. // DataList:res.Data.DataList,
  278. // ...e
  279. // }];
  280. this.tableOption=res.Data
  281. // 这里是单个指标所以不用合并日期
  282. // const arr=res.Data.map(item=>item.DataTime)
  283. let arr=[]
  284. res.Data.forEach(item=>{
  285. item.DataList.forEach(_item=>{
  286. arr.push(_item.DataTime)
  287. })
  288. })
  289. this.dateArr=[...new Set(arr)].sort().reverse()
  290. /* 不满6个追加6个空的显示一排 别问 问就是为了美观 */
  291. for( let i = 0; i < 7;i++ ) {
  292. this.tableOption.push({
  293. DataList:[]
  294. })
  295. if(this.tableOption.length >= 7) break;
  296. }
  297. //数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
  298. if(this.dateArr.length < 12) for( let i = 0; i < 12;i++ ) {
  299. this.dateArr.push('')
  300. if(this.dateArr.length >= 12) break;
  301. }
  302. this.dataloading = false;
  303. this.initWidth()
  304. }catch(err){
  305. console.log(err);
  306. }
  307. },
  308. loadNext() {
  309. this.page_no ++;
  310. this.getDataList();
  311. },
  312. /* 改变品种 */
  313. clickClassify(node,parentNode) {
  314. // console.info("node")
  315. // console.info(node)
  316. // console.info(parentNode)
  317. if(parentNode.level==1) return
  318. this.isAuto=true
  319. this.select_classify = parentNode.parent.data.ClassifyId;
  320. this.select_classify_name = parentNode.data.ClassifyName;
  321. this.leftSearchVal=''
  322. this.leftSearchTradeCode=''
  323. this.select_quota=''
  324. this.select_Unit=''
  325. this.select_UpdateTime=''
  326. },
  327. /* 改变频度 */
  328. changeFrequency(key) {
  329. this.select_frequency = key;
  330. this.leftSearchVal=''
  331. },
  332. initWidth() {
  333. $('.right-box')[0].style.width = this.$refs.table.$el.clientWidth + 5 + 'px';
  334. $('.right-box')[0].scrollTop = 0;
  335. $('.right-box')[0].scrollLeft = 0;
  336. },
  337. /* 无频度的异常显示处理 7*12*/
  338. nodataDeal() {
  339. this.tableOption = [];this.dateArr=[];
  340. for( let i = 0; i < 7;i++ ) {
  341. this.tableOption.push({
  342. DataList:[]
  343. })
  344. if(this.tableOption.length >= 7) break;
  345. }
  346. for( let i = 0; i < 12;i++ ) {
  347. this.dateArr.push('')
  348. if(this.dateArr.length >= 12) break;
  349. }
  350. },
  351. /* 钢联数据导出 */
  352. exportClick() {
  353. this.btnload = true;
  354. // var iframe = document.createElement("iframe")
  355. // iframe.style.display = "none";
  356. // iframe.src = this.exportLzapi;
  357. // document.body.appendChild(iframe);
  358. const link = document.createElement("a")
  359. link.href=this.exportCoalApi
  360. link.download=''
  361. link.click()
  362. console.log({
  363. QuotaName:this.select_quota,
  364. IndexCode:this.leftSearchTradeCode,
  365. TypeName:this.select_classify_name,
  366. sendBreedName: this.escapeStr(this.select_classify_name),
  367. Frequency:this.select_frequency,
  368. UnitName:this.select_Unit,
  369. ModifyTime:this.select_UpdateTime,
  370. url:this.exportGlapi
  371. });
  372. setTimeout(()=> {
  373. this.btnload = false;
  374. },5000)
  375. },
  376. //左侧搜索
  377. async handleLeftSearch(query,cb){
  378. cb([])
  379. if(!query) return
  380. const res=await coalDataInterface.getTargetListByName({
  381. Keyword:query,
  382. })
  383. if(res.Ret===200){
  384. let arr=res.Data||[]
  385. if(!arr.length){
  386. cb([{nodata:true}])
  387. }else{
  388. cb(arr)
  389. }
  390. }
  391. },
  392. // 选中左侧搜索值
  393. handleSelectLeftSearchval(e){
  394. console.info("handleSelectLeftSearchval")
  395. console.info(e)
  396. if(!e.IndexCode) return
  397. this.rightShow=false
  398. this.select_frequency=e.FrequencyName
  399. this.select_classify=e.BreedShortName
  400. this.leftSearchTradeCode=e.IndexCode
  401. this.leftSearchVal=e.IndexName
  402. this.select_quota=e.IndexName
  403. this.select_Unit=e.UnitName
  404. this.select_UpdateTime=e.UpdateTime
  405. this.select_classify_name=''
  406. // 关闭watcher
  407. this.isAuto=false
  408. //this.getFrequency(e.FrequencyName)
  409. // 获取单独指标数据
  410. this.getTargetDataList(e)
  411. // this.getDataList()
  412. this.$nextTick(()=>{
  413. this.rightShow=true
  414. this.handleScrollLeftWrap()
  415. })
  416. },
  417. // 左侧滚动
  418. handleScrollLeftWrap(){
  419. // let top=$('.act')[0].offsetTop
  420. // $('.classify-list').animate({
  421. // "scrollTop": top-200
  422. // })
  423. },
  424. // 对[# ;]转义
  425. escapeStr(str){
  426. return str.replace(/#/g,escape('#')).replace(/;/g,escape(';'))
  427. },
  428. },
  429. computed: {
  430. exportCoalApi() {
  431. // 钢联数据导出接口
  432. let urlStr=this.exportBase
  433. // token
  434. urlStr+=`?${localStorage.getItem('auth')||''}`
  435. // 指标名称参数
  436. urlStr+=`&IndexName=${this.select_quota}`
  437. // 指标id
  438. urlStr+=`&IndexCode=${this.leftSearchTradeCode}`
  439. // 分类id
  440. urlStr+=`&ClassifyId=${this.select_classify}`
  441. // 分类名称
  442. urlStr+=`&TypeName=${this.select_classify_name}`
  443. // 频度
  444. urlStr+=`&Frequency=${this.select_frequency}`
  445. // 单位
  446. urlStr+=`&UnitName=${this.select_Unit}`
  447. // 修改时间
  448. urlStr+=`&ModifyTime=${this.select_UpdateTime}`
  449. return this.escapeStr(urlStr)
  450. }
  451. },
  452. created() {},
  453. mounted() {
  454. this.getClassify();
  455. },
  456. };
  457. </script>
  458. <style lang="scss">
  459. .lzTarget-container{
  460. // .is-checked{
  461. // .is-current{
  462. // background-color: #f0f2f5;
  463. // }
  464. // }
  465. .el-tree-node{
  466. .el-tree-node__children{
  467. .el-tree-node__content{
  468. white-space: normal;
  469. min-height: 26px;
  470. height: auto;
  471. margin-bottom: 5px;
  472. }
  473. }
  474. }
  475. .el-tree-node__content{
  476. // min-height: 26px;
  477. // white-space: normal;
  478. }
  479. }
  480. </style>
  481. <style lang="scss" scoped>
  482. .lzTarget-container {
  483. display: flex;
  484. * {
  485. box-sizing: border-box;
  486. }
  487. .minHeight {
  488. height: calc(100vh - 120px);
  489. background-color: #fff;
  490. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
  491. border-radius: 4px;
  492. }
  493. div::-webkit-scrollbar {
  494. width: 5px !important;
  495. }
  496. .left-cont {
  497. min-width: 250px;
  498. margin-right: 20px;
  499. padding: 30px 0;
  500. // overflow: hidden;
  501. .left-top {
  502. padding: 0 20px;
  503. }
  504. .filter-tree {
  505. padding: 0 20px;
  506. /* margin-top: 20px; */
  507. height: calc(100vh - 280px);
  508. overflow-y: auto;
  509. .classify-item {
  510. font-size: 14px;
  511. color: #666;
  512. margin-bottom: 20px;
  513. &:hover {
  514. cursor: pointer;
  515. color: #409eff;
  516. }
  517. &.act {
  518. color: #409eff;
  519. }
  520. }
  521. }
  522. }
  523. .right-cont {
  524. width: 80%;
  525. padding: 30px;
  526. .right-box {
  527. max-width: 100%;
  528. max-height: calc(100vh - 230px);
  529. border-left: 1px solid #dcdfe6;
  530. border-right: 1px solid #dcdfe6;
  531. overflow: auto;
  532. .data-header {
  533. width: 100%;
  534. position: sticky;
  535. top: 0;
  536. z-index: 2;
  537. }
  538. .data-cont {
  539. height: calc(100vh - 444px);
  540. }
  541. .nodata {
  542. height: calc(100vh - 460px);
  543. border: 1px solid #dcdfe6;
  544. font-size: 16px;
  545. color: #999;
  546. }
  547. }
  548. .frequency-list {
  549. margin-top: 20px;
  550. display: flex;
  551. flex-wrap: wrap;
  552. .frequency-btn {
  553. width: 112px;
  554. margin: 0 30px 10px 0;
  555. }
  556. }
  557. }
  558. }
  559. </style>