123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618 |
- <template>
- <!-- 国家统计局 -->
- <div class="national-data-base-wrap">
- <div class="nav-bar">
- <div class="nav-list">
- <el-menu
- default-active="hgyd"
- mode="horizontal"
- active-text-color="#409EFF"
- @select="menuSelect"
- >
- <template v-for="item in menuList">
- <template v-if="item.Children">
- <el-submenu
- :key="item.Dbcode"
- :index="item.Dbcode"
- :popper-append-to-body="true"
- >
- <template slot="title">{{ item.Dbname }}</template>
- <el-menu-item
- v-for="subItem in item.Children"
- :key="subItem.Dbcode"
- :index="subItem.Dbcode"
- >
- {{ subItem.Dbname }}
- </el-menu-item>
- </el-submenu>
- </template>
- <el-menu-item v-else :key="item.Dbcode" :index="item.Dbcode">
- {{ item.Dbname }}
- </el-menu-item>
- </template>
- </el-menu>
- </div>
- <el-button v-permission="permissionBtn.dataSourcePermission.gjtjjData_export"
- type="primary" :disabled="isDisabled" @click="handleExport"
- >导出</el-button
- >
- </div>
- <div class="data-show-cotainer" v-loading="searchLoading">
- <span
- class="slide-btn-icon"
- :class="{'slide-left':isLeftWrapShow,'slide-right':!isLeftWrapShow}"
- @click="isLeftWrapShow = !isLeftWrapShow"
- >
- <i :class="{'el-icon-d-arrow-left':isLeftWrapShow,'el-icon-d-arrow-right':!isLeftWrapShow}"></i>
- </span>
- <div class="data-list-wrap wrap" v-show="isLeftWrapShow">
- <p class="sub-menu-title" v-if="currentMenu">{{ currentMenu.label }}</p>
- <div class="search-box">
- <el-select
- filterable
- remote
- placeholder="指标名称/指标ID"
- v-model="searchValue"
- :remote-method="searchHandle"
- value-key="IndexCode"
- clearable
- >
- <i slot="prefix" class="el-input__icon el-icon-search"></i>
- <el-option
- v-for="item in searchOptions"
- :key="item.IndexCode"
- :label="item.IndexName"
- :value="item"
- />
- </el-select>
- </div>
- <div class="data-list">
- <el-tree
- lazy
- :load="loadTree"
- ref="dataTree"
- :data="treeData"
- :props="treeProps"
- node-key="ClassifyId"
- :default-expanded-keys="defaultShowNodes"
- highlight-current
- v-loading="treeDataLoading"
- @current-change="changeNode"
- >
- </el-tree>
- </div>
- </div>
- <div
- class="data-table-wrap wrap"
- v-if="tableShow"
- v-loading="tableLoading"
- >
- <div class="select-box" v-if="tableShow && areaSelect">
- <el-select v-model="areaSelect" @change="areaSelectChange">
- <el-option
- v-for="item in selectOptions"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </div>
- <div class="data-table">
- <div class="table-header">
- <lz-table
- tableType="header"
- :tableOption="tableOption"
- source="smm"
- />
- </div>
- <div class="table-container">
- <lz-table
- tableType="data"
- :dateArr="tableDate"
- :tableOption="tableOption"
- source="smm"
- />
- </div>
- </div>
- </div>
- <div class="data-table-wrap wrap nodata-cont" v-else>
- <tableNoData text="暂无数据"/>
- </div>
- </div>
- </div>
- </template>
- <script>
- import lzTable from "../../../components/lzTable.vue";
- import { nationalInterface } from "@/api/api.js";
- export default {
- components: { lzTable },
- data() {
- return {
- isLeftWrapShow:true,
- /* menu */
- menuList: [], //菜单列表
- currentMenu: null, //当前选择的菜单
- /* search */
- searchValue: null, //搜索选中值
- searchOptions: [], //搜索结果
- searchLoading: false,
- /* select */
- areaSelect: null, //地区选择值
- selectOptions: [], //地区选项
- /* tree */
- treeData: [], //树形结构数据
- treeProps: {
- label: "ClassifyName",
- children: "Children",
- isLeaf: "isLeaf", //懒加载需要显式定义叶子节点标识
- }, //覆盖默认的props
- currentNode: null, //当前选择的节点
- defaultShowNodes: [], //默认展开的节点列表
- searchTreeData: [], //暂时性存放指标列表数据
- treeDataLoading: false,
- /* lz-table */
- tableOption: [],
- tableDate: [],
- tableShow: false,
- tableLoading: false,
- };
- },
- watch: {
- //找到所有父级节点,展开并选中对应项
- async searchValue(newVal) {
- if (newVal && newVal instanceof Object) {
- this.searchLoading = true;
- const { ClassifyId, IndexId, Reg } = newVal;
- const { ParentIds } = this.getNodeData(ClassifyId);
- //获取指标列表
- const nodeDataList = await this.getIndexData(ClassifyId);
- //暂存指标列表
- this.searchTreeData = nodeDataList;
- const nodeData = Reg.length
- ? nodeDataList.find(
- (node) =>
- Number((node.ClassifyId + "").split("-")[0]) === ClassifyId &&
- (node.ChildrenIndexIds.includes(IndexId) ||
- node.IndexId === IndexId)
- )
- : nodeDataList.find((node) => node.IndexId === IndexId);
- this.defaultShowNodes = [...ParentIds, ClassifyId];
- this.$nextTick(() => {
- nodeData && this.$refs.dataTree.setCurrentKey(nodeData.ClassifyId);
- const node = this.$refs.dataTree.getNode(nodeData.ClassifyId);
- //改变区域
- this.areaSelect = Reg.length ? Reg : null;
- //改变节点会触发loadTree/getTableData
- node && this.changeNode(node.data, node);
- setTimeout(() => {
- //滚动到高亮节点位置
- const dom = document.querySelector(".el-tree-node.is-current");
- const parentDom = document.querySelector(".data-list");
- if (!dom || !parentDom) {
- this.searchLoading = false;
- return;
- }
- if (dom.offsetTop > parentDom.offsetHeight) {
- //parentDom.scrollTop = dom.offsetTop - parentDom.offsetHeight/2
- parentDom.scrollTo({
- top: dom.offsetTop - parentDom.offsetHeight / 2,
- left: 0,
- behavior: "smooth",
- });
- }
- this.searchLoading = false;
- }, 300);
- });
- this.searchOptions = [];
- }
- },
- //切换菜单
- currentMenu(newVal) {
- if (newVal) {
- this.treeDataLoading = true;
- this.getTreeData();
- }
- },
- },
- computed: {
- //当节点不为可导出数据时,按钮禁用
- isDisabled() {
- if (!this.currentNode) return true;
- const { isLeaf } = this.currentNode;
- const { IsParent } = this.currentNode.data;
- if (!isLeaf && IsParent !== 0) return true;
- if (!this.tableShow) return true;
- return false;
- },
- },
- methods: {
- //获取菜单
- getMenuList() {
- nationalInterface.getMenuList().then((res) => {
- if (res.Ret !== 200) return;
- this.menuList = res.Data
- ? res.Data.map((item) => {
- if (item.Dbname === "地区数据") {
- item.Dbcode = "dqsj";
- }
- if (item.Dbname === "国际数据") {
- item.Dbcode = "gjsj";
- }
- return item;
- })
- : [];
- this.currentMenu = {
- label: this.menuList[0].Dbname,
- key: this.menuList[0].Dbcode,
- };
- });
- },
- //切换菜单
- menuSelect(key, keyPath) {
- if (key === this.currentMenu.key) return;
- this.initOptions();
- const menu = this.menuList.find((m) => m.Dbcode === keyPath[0]);
- if (keyPath.length > 1) {
- const menuItem = menu.Children.find((i) => i.Dbcode === key);
- this.currentMenu = {
- label: menuItem.Dbname,
- key,
- };
- } else {
- this.currentMenu = {
- label: menu.Dbname,
- key,
- };
- }
- },
- //切换地区
- areaSelectChange(value) {
- //console.log('change')
- this.currentNode && this.getTableData(this.currentNode.data);
- },
- //重置配置项
- initOptions() {
- this.tableShow = false;
- this.searchValue = null;
- this.currentNode = null;
- this.areaSelect = null;
- },
- //获取指标分类列表
- getTreeData() {
- const { key } = this.currentMenu;
- nationalInterface
- .getClassifyList({
- Dbcode: key,
- })
- .then((res) => {
- if (res.Ret !== 200) return;
- this.treeData = res.Data;
- this.treeDataLoading = false;
- });
- },
- //搜索指标
- searchHandle(KeyWord) {
- //console.log('search',KeyWord)
- if (!KeyWord) return;
- nationalInterface
- .getIndexList({
- Dbcode: this.currentMenu.key,
- Keywords: KeyWord,
- })
- .then((res) => {
- if (res.Ret !== 200) return;
- if (res.Data) {
- this.searchOptions = res.Data.List || [];
- }
- });
- },
- //加载树形数据
- async loadTree(node, resolve) {
- if (node.data.IsParent === 0) {
- //调用接口加载指标 如果已有暂存的数据就不重复请求
- const treeData = this.searchTreeData.length
- ? this.searchTreeData
- : await this.getIndexData(node.data.ClassifyId);
- this.searchTreeData = [];
- node.data.isLoad = true;
- this.currentNode &&
- this.currentNode.data.ClassifyId === node.data.ClassifyId &&
- this.getTableData(node.data);
- return resolve(treeData);
- }
- if (node.isLeaf) {
- return resolve([]);
- }
- if (node.level === 0) {
- return resolve(this.treeData);
- }
- if (node.level > 0) {
- //根据ClassifyId加载对应分类数据
- const { nodeData } = this.getNodeData(node.data.ClassifyId);
- return resolve(nodeData);
- }
- },
- //根据ClassifyId获取对应层级数据
- getNodeData(ClassifyId) {
- let nodeData = [];
- let ParentIds = [];
- const getChildren = (data, id) => {
- data.map((item) => {
- if (item.ClassifyId === id) {
- nodeData = item.Children;
- ParentIds = item.ParentIds;
- } else {
- if (item.Children) {
- getChildren(item.Children, id);
- }
- }
- });
- };
- getChildren(this.treeData, ClassifyId);
- return { nodeData, ParentIds };
- },
- //根据ClassifyId获取指标列表及区域数据
- async getIndexData(ClassifyId) {
- const { key } = this.currentMenu;
- let indexData = [];
- const res = await nationalInterface.getIndexList({
- Dbcode: key,
- ClassifyId: Number((ClassifyId + "").split("-")[0]),
- });
- if (res.Ret !== 200) return [];
- if (res.Data) {
- const { List, RegList } = res.Data;
- indexData = List
- ? List.map((item) => {
- item.ClassifyName = item.IndexName;
- item.ClassifyId = item.ClassifyId + "-" + item.IndexId;
- item.isLeaf = true;
- return item;
- })
- : [];
- //地区数据
- this.selectOptions = RegList || [];
- this.areaSelect = this.selectOptions.length ? RegList[0] : null;
- }
- return indexData;
- },
- //获取指标/指标列表数据
- getTableData(data) {
- this.tableLoading = true;
- const { IndexId, ClassifyId } = data;
- nationalInterface
- .getIndexDetail({
- ClassifyId: Number((ClassifyId + "").split("-")[0]),
- IndexId: IndexId ? IndexId : "", //不加IndexId获取的是指标列表数据
- Reg: this.areaSelect ? this.areaSelect : "",
- })
- .then((res) => {
- if (res.Ret !== 200) return;
- //转换成lzTable的格式
- const { totalTableOption, totalTableDate } = this.formatTableListData(
- res.Data || []
- );
- this.tableOption = totalTableOption;
- this.tableDate = totalTableDate;
- this.tableShow = true;
- this.tableLoading = false;
- this.$nextTick(() => {
- //将table-wrap的scroll置顶
- const tableWrap = document.querySelector(".data-table");
- tableWrap.scrollTo({
- top: 0,
- left: 0,
- behavior: "smooth",
- });
- });
- });
- },
- //格式化单个指标数据
- formatTableData(data) {
- let tableOption = [],
- tableDate = [];
- tableOption = data;
- //获取data中的日期作为tableDate
- tableDate = data.DataList
- ? data.DataList.map((item) => {
- return item.DataTime || "";
- })
- : [];
- return { tableOption, tableDate };
- },
- //格式化指标分类数据
- formatTableListData(data) {
- let totalTableOption = [],
- totalTableDate = [];
- data.forEach((item) => {
- const { tableOption, tableDate } = this.formatTableData(item);
- totalTableOption.push(tableOption);
- totalTableDate = totalTableDate.concat(tableDate);
- });
- //totalTableDate 去重
- totalTableDate = [...new Set(totalTableDate)].sort().reverse();
- //数据长度补空
- //tableOption不满7个,补充至7个
- if (totalTableOption.length < 7) {
- const padding = 7 - totalTableOption.length;
- for (let i = 0; i < padding; i++) {
- totalTableOption.push({
- DataList: [],
- });
- }
- }
- //tableDate不满12个 补充至12个
- if (totalTableDate.length < 12) {
- const padding = 12 - totalTableDate.length;
- for (let i = 0; i < padding; i++) {
- totalTableDate.push("");
- }
- }
- return { totalTableOption, totalTableDate };
- },
- //切换选中节点
- async changeNode(data, node) {
- this.currentNode = node;
- if (node.isLeaf) {
- this.getTableData(data);
- }
- if (data.IsParent === 0) {
- //获取地区数据
- data.isLoad && (await this.getIndexData(data.ClassifyId));
- data.isLoad && this.getTableData(data);
- } else {
- this.tableShow = false;
- }
- },
- //处理导出指标的url
- handleExport() {
- const exportBase =
- process.env.VUE_APP_API_ROOT +
- "/datamanage/base_from_national_statistics/index_detail";
- const auth = localStorage.getItem("auth") || "";
- const { ClassifyId, IndexId } = this.currentNode.data;
- const classifyId = IndexId ? "" : ClassifyId;
- const indexId = IndexId ? IndexId : "";
- const reg = this.areaSelect ? this.areaSelect : "";
- const urlStr =
- `${exportBase}` +
- `?ClassifyId=${classifyId}` +
- `&IndexId=${indexId}` +
- `&Reg=${reg}` +
- `&IsExport=true` +
- `&${auth}`;
- console.log("check url", urlStr);
- this.exportData(urlStr);
- },
- //导出指标
- exportData(url) {
- const link = document.createElement("a");
- link.href = url;
- link.download = "";
- link.click();
- },
- },
- created() {
- this.getMenuList();
- },
- mounted() {},
- };
- </script>
- <style lang="scss">
- .national-data-base-wrap {
- .el-submenu {
- .el-submenu__title {
- border-bottom: none !important;
- transition: background-color 0.3s, color 0.3s;
- }
- &.is-active {
- i {
- color: #409eff;
- }
- }
- }
- .el-tree-node {
- .el-tree-node__children {
- .el-tree-node__content {
- white-space: normal;
- min-height: 26px;
- height: auto;
- margin-bottom: 5px;
- }
- }
- }
- }
- </style>
- <style scoped lang="scss">
- .national-data-base-wrap {
- .nav-bar {
- display: flex;
- background-color: white;
- border: 1px solid #dcdfe6;
- box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.08);
- border-radius: 4px;
- align-items: center;
- margin-bottom: 20px;
- .nav-list {
- margin-right: 30px;
- flex: 1;
- ul {
- border-bottom: none;
- li {
- border-bottom: none;
- }
- }
- }
- .el-button {
- width: 120px;
- height: 40px;
- margin-right: 20px;
- }
- }
- .data-show-cotainer {
- display: flex;
- position: relative;
- .slide-btn-icon{
- &.slide-left{
- left:385px;
- }
- &.slide-right{
- left: 0;
- }
- }
- .wrap {
- height: calc(100vh - 194px);
- background-color: white;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- padding: 20px;
- box-sizing: border-box;
- }
- .data-list-wrap {
- min-width: 400px;
- width: 400px;
- margin-right: 20px;
- .sub-menu-title {
- font-size: 16px;
- font-weight: bold;
- margin-bottom: 20px;
- }
- .search-box {
- .el-select {
- width: 100%;
- }
- }
- .data-list {
- margin-top: 20px;
- height: calc(100vh - 333px);
- overflow-y: auto;
- }
- }
- .data-table-wrap {
- flex: 1;
- .select-box {
- .el-select {
- width: 240px;
- }
- margin-bottom: 20px;
- }
- .data-table {
- overflow: auto;
- border-left: 1px solid #dcdfe6;
- border-right: 1px solid #dcdfe6;
- width: 100%;
- height: calc(100vh - 292px);
- .table-header,
- .table-container {
- width: 1000px; //让data-table出滚动条,只要小于7*179(lz-table-td min-width)
- }
- }
- &.nodata-cont {
- text-align: center;
- }
- }
- }
- }
- </style>
|