Procházet zdrojové kódy

1. 修复暗黑下表格固定列会和其他表格数据重叠的问题
2. 对接指标数据的维度筛选,维度列表显示

yanglzh před 1 měsícem
rodič
revize
e0603ad6a5

+ 1 - 0
src/api/datahub/index.ts

@@ -129,5 +129,6 @@ export default {
     edit: (data: object) => put('/indicator/edit', data),
     publish: (code: string) => post('/indicator/publish', { code }),
     unpublish: (code: string) => post('/indicator/unpublish', { code }),
+    getDimensionValues: (params: object) => get('/indicator/getDimensionValues', params),
   }
 }

+ 6 - 8
src/theme/dark.scss

@@ -274,8 +274,7 @@
 
 	.el-table__body-wrapper tr td.el-table-fixed-column--left,
 	.el-table__body-wrapper tr td.el-table-fixed-column--right {
-		background-color: none !important;
-		background: none !important;
+		background-color: var(--next-bg-main-color) !important;
 	}
 
 	.add-flag-container {
@@ -530,14 +529,13 @@
 
 // API开发 API定义 暗黑模式兼容
 .tab-navigation li.active {
-	background-color: var(--next-border-color-light)!important;
+	background-color: var(--next-border-color-light) !important;
 }
 .tab-navigation li:hover {
-	background-color: transparent!important;
-
+	background-color: transparent !important;
 }
 .path-prefix {
-	background-color: transparent!important;
+	background-color: transparent !important;
 	border-color: var(--next-border-color-light) !important;
 }
 .form-section-title {
@@ -549,9 +547,9 @@
 .group-tree-container {
 	border-color: var(--next-border-color-light) !important;
 }
-.api-edit  .el-dialog__footer .dialog-footer {
+.api-edit .el-dialog__footer .dialog-footer {
 	border-top-color: var(--next-border-color-light) !important;
-} 
+}
 .monaco-editor-wrapper {
 	border-color: var(--next-border-color-light) !important;
 }

+ 8 - 5
src/theme/index.scss

@@ -9,11 +9,10 @@
 @import './fast.scss';
 @import './form-create.scss';
 
-
 // 自定义指令 v-auth 增加 v-disabled 的类
-.v-disabled{
-  pointer-events: none;
-  opacity: 0.7;
+.v-disabled {
+	pointer-events: none;
+	opacity: 0.7;
 }
 
 .no-wrap {
@@ -23,4 +22,8 @@
 }
 .text-no-wrap {
 	white-space: nowrap;
-}
+}
+
+.el-form--inline .el-form-item {
+	margin-right: 10px;
+}

+ 49 - 54
src/views/system/datahub/indicator/component/data.vue

@@ -1,16 +1,25 @@
 <template>
-  <el-dialog v-model="visible" :title="`指标数据 - ${title}`" width="850px" :close-on-click-modal="false" destroy-on-close>
+  <el-dialog v-model="visible" :title="`指标数据 - ${title}`" width="1000px" :close-on-click-modal="false" destroy-on-close>
     <div v-if="visible">
       <el-form :inline="true" class="toolbar">
         <el-form-item>
           <el-input v-model="query.searchValue" placeholder="输入指标值或原始值" clearable style="width: 160px" />
         </el-form-item>
-        <el-form-item label="时间范围">
+        <el-form-item label="">
           <el-date-picker v-model="query.dateRange" type="datetimerange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 380px" />
         </el-form-item>
-        <!-- <el-form-item label="维度筛选">
-          <el-select v-model="dimensionSelectedText" style="width: 120px" placeholder="全部维度" />
-        </el-form-item> -->
+        <el-form-item label="">
+          <el-select v-model="dimensionsKey" style="width: 110px" placeholder="全部维度" clearable @change="handleDimensionChange">
+            <el-option v-for="item in dimensions" :key="item.code" :label="item.name" :value="item.code" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="" v-if="dimensionsKey">
+          <el-date-picker v-if="dimensionsType === 'date'" v-model="dimensionsValue" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 140px" placeholder="选择日期" />
+          <el-select v-else-if="dimensionsType === 'text'" v-model="dimensionsValue" style="width: 120px" placeholder="选择维度值">
+            <el-option v-for="item in dimensionsValues" :key="item" :label="item.name" :value="item" />
+          </el-select>
+          <el-input v-else type="number" v-model="dimensionsValue" style="width: 120px" placeholder="输入维度值" />
+        </el-form-item>
         <el-form-item label="">
           <el-button type="primary" :icon="Filter" @click="fetchList(1)">筛选</el-button>
           <!-- <el-button @click="exportData">导出</el-button> -->
@@ -21,25 +30,18 @@
         <el-table-column label="时间" align="center" prop="collectionTime" width="180" />
         <el-table-column v-if="detail.computeStrategy !== 'aggregation'" prop="value" :label="`指标值${detail.unit ? ' (' + detail.unit + ')' : ''}`" min-width="140" align="center" />
         <template v-else>
-          <el-table-column prop="maxValue" :label="`最大值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" />
-          <el-table-column prop="minValue" :label="`最小值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" />
-          <el-table-column prop="avgValue" :label="`平均值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" />
-          <el-table-column prop="sumValue" :label="`总和${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" />
-          <el-table-column prop="countValue" label="数量值" align="center" />
+          <el-table-column prop="maxValue" :label="`最大值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" min-width="140" />
+          <el-table-column prop="minValue" :label="`最小值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" min-width="140" />
+          <el-table-column prop="avgValue" :label="`平均值${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" min-width="140" />
+          <el-table-column prop="sumValue" :label="`总和${detail.unit ? ' (' + detail.unit + ')' : ''}`" align="center" min-width="140" />
+          <el-table-column prop="countValue" label="数量值" align="center" min-width="140" />
         </template>
-        <!-- <el-table-column label="原始值" width="120" align="left">
-          <template #default="scope">{{ scope.row.rawValue ?? scope.row.originValue ?? "-" }}</template>
-        </el-table-column> -->
-        <!-- <el-table-column label="监测点" prop="monitorPoint" width="120" align="left"> </el-table-column>
-        <el-table-column label="深度" prop="depth" width="120" align="left"> </el-table-column>
-        <el-table-column label="设备" prop="device" width="120" align="left"> </el-table-column>
-        <el-table-column v-for="k in dimKeys" :key="k" :label="dimNameMap[k] || k" min-width="120" show-overflow-tooltip>
-          <template #default="scope">{{ (scope.row.dimensions && scope.row.dimensions[k]) ?? scope.row[k] ?? "-" }}</template>
-        </el-table-column> -->
+
+        <el-table-column v-for="item in dimensions" :key="item.code" :label="item.name" align="center" :prop="`dimensionValues.${item.code}`" min-width="140" />
       </el-table>
 
       <div class="pager flex-end">
-        <el-pagination background layout="prev, pager, next, ->, total, sizes" :page-sizes="[20, 50, 100, 200]" :total="total" :page-size="query.pageSize" :current-page="query.pageNum" @current-change="(p:number)=>fetchList(p)" @size-change="(s:number)=>{query.pageSize=s;fetchList(1)}" />
+        <el-pagination background layout="prev, pager, next, ->, total, sizes" :page-sizes="[1, 20, 50, 100]" :total="total" :page-size="query.pageSize" :current-page="query.pageNum" @current-change="(p:number)=>fetchList(p)" @size-change="(s:number)=>{query.pageSize=s;fetchList(1)}" />
       </div>
     </div>
   </el-dialog>
@@ -53,6 +55,11 @@ import api from "/@/api/datahub";
 
 const visible = ref(false);
 const loading = ref(false);
+const dimensions = ref<any[]>([]);
+const dimensionsValues = ref<any[]>([]);
+const dimensionsKey = ref("");
+const dimensionsType = ref("");
+const dimensionsValue = ref("");
 const code = ref("");
 const title = ref("");
 const detail = reactive<any>({}); // 详情含 unit/维度等
@@ -63,48 +70,35 @@ const total = ref(0);
 const query = reactive({
   searchValue: "",
   keyWord: "",
+  dimensions: "",
   year: "",
   accurate: "h",
   dateRange: [],
   pageNum: 1,
-  pageSize: 20,
+  pageSize: 10,
 });
 
-const dimensionFilters = reactive<Record<string, any>>({});
+function handleDimensionChange(value: string) {
+  if (!value) {
+    dimensionsValues.value = [];
+    dimensionsValue.value = "";
+    dimensionsType.value = "";
+    return;
+  }
 
-const dimKeys = computed(() => {
-  const set = new Set<string>();
-  list.value.forEach((row: any) => {
-    if (row?.dimensions && typeof row.dimensions === "object") {
-      Object.keys(row.dimensions).forEach((k) => set.add(k));
-    }
-  });
-  return Array.from(set);
-});
-const dimNameMap = computed<Record<string, string>>(() => {
-  const map: Record<string, string> = {};
-  (detail.dimensions || []).forEach((d: any) => {
-    map[d.key || d.name] = d.name || d.key;
+  dimensionsType.value = dimensions.value.find((item) => item.code === value)?.valueType || "";
+
+  api.indicator.getDimensionValues({ code: code.value, dimensionCode: value }).then((res: any) => {
+    dimensionsValues.value = res?.values || [];
   });
-  return map;
-});
-const dimensionSelectedText = computed(() => {
-  const entries = Object.entries(dimensionFilters).filter(([, v]) => v !== "" && v !== undefined && v !== null);
-  if (!entries.length) return "全部维度";
-  return entries.map(([k, v]) => `${dimNameMap.value[k] || k}:${v}`).join(";");
-});
+}
 
 function buildParams() {
   const params: any = {
     ...query,
     code: code.value,
   };
-  // 维度 JSON 字符串
-  const dims: Record<string, any> = {};
-  Object.entries(dimensionFilters).forEach(([k, v]) => {
-    if (v !== "" && v !== undefined && v !== null) dims[k] = v;
-  });
-  if (Object.keys(dims).length) params.dimensions = JSON.stringify(dims);
+  if (dimensionsKey.value && dimensionsValue.value) params.dimensions = { [dimensionsKey.value]: dimensionsValue.value };
   return params;
 }
 
@@ -117,6 +111,11 @@ function fetchDetail() {
 }
 
 function fetchList(p?: number) {
+  if (dimensionsKey.value && !dimensionsValue.value) {
+    ElMessage.warning("请选择或输入维度值");
+    return;
+  }
+
   if (typeof p === "number") query.pageNum = p;
   loading.value = true;
   const params = buildParams();
@@ -136,16 +135,12 @@ function open(row: any) {
   code.value = row?.code || "";
   title.value = `${row?.name || "-"} (${code.value})`;
   visible.value = true;
+  dimensions.value = row?.dimensions || [];
   // 清空筛选
-  Object.assign(query, { searchValue: "", keyWord: "", year: "", startTime: "", endTime: "", accurate: "", accurateRanges: "", orderBy: "", pageNum: 1, pageSize: 20 });
-  Object.keys(dimensionFilters).forEach((k) => delete (dimensionFilters as any)[k]);
+  Object.assign(query, { searchValue: "", keyWord: "", year: "", startTime: "", endTime: "", accurate: "", accurateRanges: "", orderBy: "", pageNum: 1, pageSize: 10 });
   fetchDetail().then(() => fetchList(1));
 }
 
-function exportData() {
-  ElMessage.info("导出功能请在接口确定后接入");
-}
-
 defineExpose({ open });
 </script>
 

+ 5 - 4
src/views/system/datahub/indicator/component/edit.vue

@@ -148,10 +148,11 @@
         </el-form-item>
         <el-form-item label="维度值类型" prop="valueType">
           <el-select v-model="dimDialog.form.valueType" placeholder="请选择值类型" style="width: 100%">
-            <el-option label="字符串" value="string" />
-            <el-option label="数值" value="number" />
-            <el-option label="布尔" value="boolean" />
-            <el-option label="时间" value="datetime" />
+            <el-option label="整数" value="int" />
+            <el-option label="长整数" value="long" />
+            <el-option label="双精度浮点数" value="double" />
+            <el-option label="字符串" value="text" />
+            <el-option label="日期" value="date" />
           </el-select>
         </el-form-item>
         <el-form-item label="维度描述" prop="description">

+ 16 - 16
src/views/system/datahub/indicator/index.vue

@@ -25,7 +25,7 @@
             <el-icon><ele-Search /></el-icon>
             查询
           </el-button>
-          <el-button type="primary" class="ml10" @click="addOrEdit()">
+          <el-button type="primary" class="ml10" @click="addOrEdit()" v-auth="'add'">
             <el-icon><ele-FolderAdd /></el-icon>
             新增指标
           </el-button>
@@ -33,37 +33,37 @@
       </el-form>
 
       <el-table :data="tableData" style="width: 100%" row-key="code" v-loading="loading">
-        <el-table-column label="指标编号" prop="code" align="left" min-width="200">
+        <el-table-column label="指标编号" v-col="'id'" align="left" min-width="200">
           <template #default="scope">
             <el-link type="primary" :underline="false">{{ scope.row.code }}</el-link>
           </template>
         </el-table-column>
-        <el-table-column label="指标名称" prop="name" min-width="200" show-overflow-tooltip />
-        <el-table-column label="指标类型" prop="type" width="120" align="center">
+        <el-table-column label="指标名称" v-col="'name'" prop="name" min-width="200" show-overflow-tooltip />
+        <el-table-column label="指标类型" v-col="'type'" prop="type" width="120" align="center">
           <template #default="scope">
             <el-tag size="small">{{ scope.row.tagInfo?.[0]?.name || "-" }}</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="单位" prop="unit" width="100" align="center" />
-        <el-table-column label="维度数" align="center" width="100">
+        <el-table-column label="单位" v-col="'unit'" prop="unit" width="100" align="center" />
+        <el-table-column label="维度数" v-col="'dimensions'" align="center" width="100">
           <template #default="scope">
-            <el-tag size="small" type="info">{{ (scope.row.dimensions?.length) || 0 }}</el-tag>
+            <el-tag size="small" type="info">{{ scope.row.dimensions?.length || 0 }}</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="状态" prop="status" width="100" align="center">
+        <el-table-column label="状态" v-col="'status'" prop="status" width="100" align="center">
           <template #default="scope">
             <el-tag size="small" :type="scope.row.status == '1' ? 'success' : 'danger'">{{ scope.row.status == "1" ? "已发布" : "未发布" }}</el-tag>
           </template>
         </el-table-column>
-        <el-table-column prop="createdAt" label="创建时间" align="center" width="180" />
-        <el-table-column label="操作" align="center" width="220" fixed="right">
+        <el-table-column v-col="'createdAt'" prop="createdAt" label="创建时间" align="center" width="180" />
+        <el-table-column label="操作" align="center" width="220" fixed="right" v-col="'handle'">
           <template #default="scope">
-            <el-button size="small" text type="primary" v-if="scope.row.status == '0'" @click="publish(scope.row)">发布</el-button>
-            <el-button size="small" text type="warning" v-else @click="unpublish(scope.row)">取消发布</el-button>
-            <el-button size="small" text type="primary" @click="openDetail(scope.row)">详情</el-button>
-            <el-button size="small" text type="success" @click="openData(scope.row)">数据</el-button>
-            <el-button size="small" text type="primary" @click="addOrEdit(scope.row)">编辑</el-button>
-            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+            <el-button size="small" text type="primary" v-if="scope.row.status == '0'" @click="publish(scope.row)" v-auth="'publish'">发布</el-button>
+            <el-button size="small" text type="warning" v-else @click="unpublish(scope.row)" v-auth="'publish'">取消发布</el-button>
+            <el-button size="small" text type="primary" @click="openDetail(scope.row)" v-auth="'detail'">详情</el-button>
+            <el-button size="small" text type="success" @click="openData(scope.row)" v-auth="'data'">数据</el-button>
+            <el-button size="small" text type="primary" @click="addOrEdit(scope.row)" v-auth="'edit'">编辑</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)" v-auth="'del'">删除</el-button>
           </template>
         </el-table-column>
       </el-table>