Przeglądaj źródła

Merge branch 'ht_requirement_318' into debug_ht

cldu 2 miesięcy temu
rodzic
commit
b9069ca952

+ 63 - 0
src/api/indicator/import.js

@@ -0,0 +1,63 @@
+import { get, post } from "@/api/index";
+
+export default {
+    /**
+     * 获取指标信息
+     * @param {String} params.IndexCode
+     * @returns 
+     */
+    getIndexInfo:params=>{
+        return get('/ht/v1/getIndexInfo',params)
+    },
+    /**
+     * 获取来源列表
+     * @returns 
+     */
+    getSourceList:params=>{
+        return get('/eta/v1/business_data/source/list',params)
+    },
+    /**
+     * 获取指标列表
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {String} params.KeyWord
+     * @param {String} params.SortColumn
+     * @param {String} params.SourceName
+     * @param {String} params.Frequency
+     * @param {String} params.SortOrder
+     * @returns 
+     */
+    getDataList:params=>{
+        return get('/eta/v1/business_data/list',params)
+    },
+    /**
+     * 获取指标数据列表
+     * @param {String} params.IndexCode
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @returns 
+     */
+    getBusDataList:params=>{
+        return get('/eta/v1/business_data/data/list',params)
+    },
+    /**
+     * 删除指标
+     * @param {Object} params
+     * @param {Array} params.DeleteList
+     * @param {Array} params.UnDeleteList
+     * @param {Array} params.DeleteAll
+     * @returns
+     */
+    busDataDelete:params=>{
+        return post('/eta/v1/business_data/del',params)
+    },
+    /**
+     * 添加指标推送
+     * @param {Object} params
+     * @param {String} params.IndexCode
+     * @returns
+     */
+    dataPush:params=>{
+        return post('/ht/v1/push',params)
+    },
+};

+ 6 - 0
src/api/indicator/index.js

@@ -0,0 +1,6 @@
+import apiIndicatorImport from './import'
+
+export {
+    apiIndicatorImport,
+}
+

+ 4 - 0
src/assets/svg/menu/import.svg

@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14 4.5V14H2V2H11.5L12.5 1H2C1.44772 1 1 1.44772 1 2V14C1 14.5523 1.44772 15 2 15H14C14.5523 15 15 14.5523 15 14V3.5L14 4.5ZM3.3999 11.9999C3.3999 11.7363 3.66853 11.5 3.9999 11.5H12C12.3314 11.5 12.5999 11.7495 12.5999 11.9999C12.5999 12.2503 12.3314 12.5 12 12.5H3.9999C3.66853 12.5 3.3999 12.2635 3.3999 11.9999Z"  fill="currentColor"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.0235 8.97609L7 4.33845L8.9568 6.32882L14.1957 1L15 1.81806L9.76107 7.14689L11.5829 9L7.0235 8.97609Z"  fill="currentColor"/>
+</svg>

+ 1 - 1
src/layout/components/HeaderWrap.vue

@@ -18,7 +18,7 @@ const breadcrumbArr=computed(()=>{
     temarr.splice(1,0,{title:arr[1].meta.from,path:arr[1].meta.fromPath})
   }
   if(arr[1]){
-    if(['消息推送管理','客户反馈','图片资源库'].includes(arr[1].meta.title)){
+    if(['消息推送管理','客户反馈','图片资源库','一期指标导入'].includes(arr[1].meta.title)){
         return [{title:arr[1].meta.title}]
     }
   }

+ 2 - 1
src/layout/components/LeftWrap.vue

@@ -109,7 +109,8 @@ function getMenuIcon(item){
         '/mediaMgt/pictureLib':'menu/piclib',
         '/customer/feedbackList':'menu/feedback',
         '/system':'menu/setting',
-        '/riskLevel':'menu/risklevel'
+        '/riskLevel':'menu/risklevel',
+        '/indicator/indicatorImport':'menu/import',
     }
     return iconMap[item]||'menu/setting'
 

+ 22 - 0
src/router/modules/indicator.js

@@ -0,0 +1,22 @@
+import LayoutIndex from '@/layout/Index.vue'
+
+export default[
+  {
+    path:'/indicator',
+    component:LayoutIndex,
+    name:'indicatorIndex',
+    meta:{
+      title:'指标管理'
+    },
+    children:[
+      {
+        path:'indicatorImport',
+        component:()=>import('@/views/indicator/IndicatorImport.vue'),
+        name:'IndicatorImport',
+        meta:{
+            title:'一期指标导入'
+        }
+      },
+    ]
+  }
+]

+ 443 - 0
src/views/indicator/IndicatorImport.vue

@@ -0,0 +1,443 @@
+<script setup>
+import { ref, reactive, nextTick } from 'vue'
+import { apiIndicatorImport } from '@/api/indicator'
+import { Search } from '@element-plus/icons-vue'
+import addEbdDialog from './components/addEbdDialog.vue';
+import edbDetailDialog from './components/edbDetailDialog.vue';
+import { ElMessage , ElMessageBox } from 'element-plus'
+import {usePermission} from '@/hooks/permission'
+const {hasPermission}=usePermission()
+
+const tableRef = ref();
+const tableLoading = ref(false);
+const total = ref(0);
+const tableData = ref([]);
+const sourceOptions = ref([]);
+const isSelectAll = ref(false);//真正意义上的全选或不全选
+const checkedList = ref([]);//不全选勾选中的 或 全选取消勾的
+const selectionReactCancel = ref(false);//手动设置选中中
+const filterObj = reactive({
+    page_no: 1,
+    pageSize: 10,
+    source: '',
+    frequency: '',
+    keyWord: '',
+    sortParam:'',
+    sortType:'',
+    checkAll: false, //控制全选显示状态
+    checkSome: false
+});
+const isAddToBaseDia = ref(false);
+const lookEdbInfo = ref({});
+const isLookDataDia = ref(false);
+
+const frequencyOptions = [
+    { label:'日度',val: '日度' },
+    { label:'周度',val: '周度' },
+    { label:'旬度',val: '旬度' },
+    { label:'月度',val: '月度' },
+    { label:'季度',val: '季度' },
+    { label:'半年度',val: '半年度' },
+    { label:'年度',val: '年度' },
+];
+
+const tableColums = [
+          {
+            label: '指标ID',
+            key: 'IndexCode',
+          },
+         {
+            label: '指标名称',
+            key: 'IndexName',
+          },
+          {
+            label: '频度',
+            key: 'Frequency',
+          },
+          {
+            label: '单位',
+            key: 'Unit',
+          },
+          {
+            label: '渠道',
+            key: 'SourceName',
+          },
+          {
+            label: '指标开始时间',
+            key: 'StartDate',
+            sortable:true,
+          },
+          {
+            label: '指标最新时间',
+            key: 'EndDate',
+            sortable:true,
+          },
+          {
+            label: '入库时间',
+            sortable:true,
+            key: 'CreateTime'
+          },
+          {
+            label: '操作',
+            key: 'handle'
+          },
+
+        ]
+
+
+async function getSource(){
+    let res = await apiIndicatorImport.getSourceList();
+    if(res.Ret!==200 ) return
+    sourceOptions.value = res.Data || [];
+}
+
+function filterChange(val){
+    filterObj.page_no = 1;
+    if(!val) {
+        isSelectAll.value = false
+        checkedList.value = []
+        filterObj.checkAll = false
+        filterObj.checkSome = false
+    }
+    getTableData(val?'filter':'')
+}
+
+function pageChange(page){
+    filterObj.page_no = page;
+    getTableData('pageChange')
+}
+
+function handleSortChange({prop,order}){
+    const propMap={
+          'StartDate':'start_date',
+          'EndDate':'end_date',
+          'CreateTime':'create_time'
+      }
+      filterObj.sortParam = order?propMap[prop]||'':''
+      filterObj.sortType = order?order==='ascending'?'asc':'desc':''
+      filterChange()
+}
+
+async function getTableData(type='pageChange'){
+    const { frequency,page_no,pageSize,keyWord,source,sortParam,sortType } = filterObj;
+    let params = {
+        Frequency: frequency,
+        CurrentIndex: page_no,
+        PageSize: pageSize,
+        KeyWord: keyWord,
+        SourceName: source,
+        SortColumn: sortParam,
+        SortOrder: sortType
+    }
+    tableLoading.value = true;
+    let res = await apiIndicatorImport.getDataList(params);
+    tableLoading.value = false;
+    if(res.Ret != 200) return;
+    const { Data } = res;
+    tableData.value = Data.List || [];
+    total.value = Data.Paging.Totals;
+
+    await nextTick();
+    if(type==='filter'){
+        listCheckAllChange(true)
+    }else {
+        checkedSomeSelection()
+    }
+};
+
+function listCheckAllChange(value){
+    checkedList.value = [];
+    isSelectAll.value = value;
+    tableRef.value?.clearSelection();
+    value && (tableRef.value?.toggleAllSelection());
+}
+
+function checkedSomeSelection(){
+    selectionReactCancel.value=true
+    if(!isSelectAll.value){
+        checkedList.value.map(_ =>{
+            let row = tableData.value.find(item => item.IndexCode==_.IndexCode)
+            if(row){ //设置部分选中
+                setTimeout(()=>{
+                    tableRef.value?.toggleRowSelection(row,true)
+                },20)
+            }
+        })
+    }else{
+        tableRef.value?.toggleAllSelection()
+        checkedList.value.map(_ =>{
+            let row = tableData.value.find(item => item.IndexCode==_.IndexCode)
+            if(row){ //设置部分不勾选
+                setTimeout(()=>{
+                    tableRef.value?.toggleRowSelection(row,false)
+                },20)
+            }
+        })
+    }
+    setTimeout(()=>{
+        selectionReactCancel.value=false
+    },30)
+}
+
+function selectHandle(selection,row){
+    if(selectionReactCancel.value) return 
+    //当前项是选中还是取消选
+    let haveChecked = selection.some(_ => _.IndexCode === row.IndexCode);
+    // //全选取消选和不全选选中才有意义
+    if((haveChecked&&!isSelectAll.value) || (!haveChecked&&isSelectAll.value)) {
+      checkedList.value.push(row)
+    }else {
+      checkedList.value=checkedList.value.filter(_ => _.IndexCode!==row.IndexCode)
+    }
+}
+
+function selectAllPageHandle(selection){
+    if(selectionReactCancel.value) return 
+    //当前页是选中还是取消
+    let haveChecked = selection && selection.length>0;
+    //全选取消选和不全选选中才有意义
+    if((haveChecked&&!isSelectAll.value) || (!haveChecked&&isSelectAll.value)) {
+        checkedList.value = [...checkedList.value,...tableData.value]
+    }else {
+        let pageIds = tableData.value.map(_ => _.IndexCode);
+        checkedList.value = checkedList.value.filter(_ => !pageIds.includes(_.IndexCode))
+    }
+}
+
+function selectionChange(){
+    if(selectionReactCancel.value) return
+    //设置全选框状态 选中 半选 不选
+    setTimeout(()=>{
+        checkedList.value = checkedList.value.filter((item, index, arr) => { //数组去重
+            return arr.findIndex((_) => _.IndexCode == item.IndexCode) == index;
+        });
+        //全选
+        if(
+            (checkedList.value.length===total.value&&total.value>0 && (!isSelectAll.value))
+            || (checkedList.value.length === 0 && isSelectAll.value)
+        ){
+            filterObj.checkAll = true
+            filterObj.checkSome = false
+        //不选
+        }else if(
+            (checkedList.value.length === 0 && (!isSelectAll.value))
+            || (checkedList.value.length === total.value && isSelectAll.value)
+        ){
+            filterObj.checkAll = false
+            filterObj.checkSome = false
+        //半选
+        }else{
+            filterObj.checkAll = false
+            filterObj.checkSome = true
+        }
+    },1)
+}
+
+function lookDataHandle(item){
+    lookEdbInfo.value = item;
+    isLookDataDia.value =  true;
+}
+
+function deleteItem(item){
+    ElMessageBox.confirm(
+    `确定要删除该指标吗`,
+    '提示',
+    {
+      confirmButtonText: '确认',
+      cancelButtonText: '取消',
+      type: 'warning',
+    }
+  )
+    .then(async () => {
+        let res = await apiIndicatorImport.busDataDelete({
+            DeleteList:[item.IndexCode],
+            UnDeleteList:[],
+            DeleteAll:false,
+        });
+        if(res.Ret != 200) return;
+        if(res.Data.NoDeleteEdbCodeList && res.Data.NoDeleteEdbCodeList.length > 0){
+           ElMessage.error('该指标已加到指标库,不支持删除')
+        } else {
+           ElMessage.success('删除成功');
+           getTableData();
+        }
+    })
+    .catch(() => {})
+}
+
+function batchDelete(){
+    let num = !isSelectAll.value ? checkedList.value?.length || 0 : total.value - (checkedList.value?.length || 0);
+    if(!num) return ElMessage.warning('请先选择指标');
+    ElMessageBox.confirm(
+    `已选择${num}个指标,操作删除后不可撤销,确认删除吗?`,
+    '提示',
+    {
+      confirmButtonText: '确认',
+      cancelButtonText: '取消',
+      type: 'warning',
+    }
+  )
+    .then(async () => {
+        let lists = checkedList.value.map(_=>_.IndexCode) || [];
+        let params = {
+            DeleteAll: isSelectAll.value,
+            DeleteList: !isSelectAll.value ? lists : [],
+            UnDeleteList: isSelectAll.value ? lists : [],
+        } 
+        let res = await apiIndicatorImport.busDataDelete(params);
+        if(res.Data.NoDeleteEdbCodeList && res.Data.NoDeleteEdbCodeList.length > 0){
+           ElMessage.error(`${res.Data.NoDeleteEdbCodeList.join('、')}已加到指标库,不支持删除`)
+        } else {
+           ElMessage.success('批量删除成功');
+        }
+        getTableData();
+    })
+    .catch(() => {})
+}
+
+getSource();
+getTableData('init');
+</script>
+
+<template>
+    <div class="indicator-import-wrap">
+        <div class="header">
+            <div class="left">
+                <el-select
+                    v-model="filterObj.source"
+                    @change="filterChange"
+                    placeholder="请选择渠道"
+                    clearable
+                    size="large"
+                    style="width: 230px;"
+                    >
+                    <el-option 
+                        v-for="item in sourceOptions" 
+                        :key="item.EdbBusinessSourceId" 
+                        :label="item.SourceName" 
+                        :value="item.SourceName"
+                    />
+                </el-select>
+
+                <el-select
+                    v-model="filterObj.frequency"
+                    @change="filterChange"
+                    placeholder="请选择频度"
+                    clearable
+                    size="large"
+                    style="width: 230px;"
+                >
+                    <el-option v-for="item in frequencyOptions" :key="item.val" :label="item.label" :value="item.val"/>
+                </el-select>
+
+                <el-input 
+                    v-model="filterObj.keyWord" 
+                    placeholder="指标ID/指标名称"
+                    @change="filterChange"
+                    clearable
+                    style="width: 250px;"
+                    size="large"
+                    :prefix-icon="Search"
+                    >
+                </el-input>
+
+                <el-checkbox 
+                    v-model="filterObj.checkAll"
+                    :indeterminate="filterObj.checkSome"
+                    :disabled="tableData.length===0"
+                    style="margin-left:20px" 
+                    @change="listCheckAllChange"
+                >列表全选</el-checkbox>
+
+            </div>
+            <div class="right">
+                <el-button type="primary" size="large" style="padding:12px 30px;" @click="isAddToBaseDia = true" v-if="hasPermission('indicatorImport:add')">添加指标</el-button>
+                <el-button type="primary" size="large" plain style="padding:12px 30px;" v-if="hasPermission('indicatorImport:batchDelete')" @click="batchDelete">批量删除</el-button>
+            </div>
+        </div>
+        <div class="main" v-if="hasPermission('indicatorImport:view')">
+            <el-table
+                :data="tableData"
+                ref="tableRef"
+                element-loading-text="加载中..."
+                v-loading="tableLoading"
+                border
+                style="margin:20px 0"
+                @sort-change="handleSortChange"
+                @select="selectHandle" 
+                @select-all="selectAllPageHandle"
+                @selection-change="selectionChange"
+            >
+                <el-table-column
+                    type="selection"
+                    width="55"
+                />
+                <el-table-column
+                    v-for="item in tableColums"
+                    :key="item.label"
+                    :label="item.label"
+                    :prop="item.key"
+                    :width="item.widthsty"
+                    :min-width="item.minwidthsty"
+                    :sortable="item.sortable?true:false"
+                    align="center"
+                >
+                    <template #default="{row}">
+                    <template v-if="item.key==='handle'">
+                        <el-button type="primary" @click="lookDataHandle(row)" link v-if="hasPermission('indicatorImport:detail')">查看详情</el-button>
+                        <el-button type="danger" link v-if="hasPermission('indicatorImport:delete')" @click="deleteItem(row)">删除</el-button>
+                    </template>
+
+                    <template v-else-if="item.key==='IndexName'">
+                        <span style="white-space: pre-wrap;">{{ row.IndexName }}</span>
+                    </template>
+
+                    <span v-else>{{ row[item.key] }}</span>
+                    </template>
+                </el-table-column>
+                
+                <template #empty>
+                    <el-empty description="暂无数据" />
+                </template>
+            </el-table>
+
+            <el-pagination
+                background
+                layout="total,prev,pager,next,jumper"
+                :current-page="filterObj.page_no"
+                :page-size="filterObj.pageSize"
+                :total="total"
+                @current-change="pageChange"
+                style=" justify-content: flex-end;border-top: none;"
+            />
+
+        </div>
+        <el-empty v-else description="暂无权限"></el-empty>
+    </div>
+    <addEbdDialog v-model:show="isAddToBaseDia" @success="filterChange"></addEbdDialog>
+    <edbDetailDialog v-model:isShow="isLookDataDia" :edbInfo="lookEdbInfo"></edbDetailDialog>
+</template>
+
+<style scoped lang="scss">
+.indicator-import-wrap{
+    min-height: calc(100vh - 120px);
+    background-color: #fff;
+    border: 1px solid #c8cdd9;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, .05);
+    padding: 20px;
+    box-sizing: border-box;
+    overflow: auto;
+    .header{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        flex-wrap: wrap;
+        .left,.right {
+            display: flex;
+            align-items: center;
+            gap: 14px;
+        }
+    }
+}
+</style>

+ 207 - 0
src/views/indicator/components/addEbdDialog.vue

@@ -0,0 +1,207 @@
+<script setup>
+import { ref, reactive, nextTick, watch } from 'vue'
+import { apiIndicatorImport } from '@/api/indicator'
+import { ElMessage } from 'element-plus'
+const ruleFormRef = ref();
+const show = defineModel('show', { type: Boolean, default: false });
+const formData = reactive({
+    IndexCode:'',
+    IndexName:'',
+    Frequency:'',
+    Unit:'',
+    StartDate:'',
+    EndDate:'',
+});
+const tableData = ref([]);
+const dataList = ref([]);
+const showData = ref(false);
+const dataLoading = ref(false);
+const saveLoading = ref(false);
+const emits = defineEmits(["success"]);
+
+watch(show,(val)=>{
+  if(val) closeDialog();
+})
+
+const frequencyOptions = [
+    { label:'日度',val: '日度' },
+    { label:'周度',val: '周度' },
+    { label:'旬度',val: '旬度' },
+    { label:'月度',val: '月度' },
+    { label:'季度',val: '季度' },
+    { label:'半年度',val: '半年度' },
+    { label:'年度',val: '年度' },
+];
+
+const tableColums = [
+    {
+        label: '指标ID',
+        key: 'IndexCode',
+    },
+    {
+        label: '起始时间',
+        key: 'StartDate',
+    },
+    {
+        label: '结束时间',
+        key: 'EndDate',
+    },
+];
+
+const rules = reactive({
+    IndexCode: [{required: true,message: '请输入指标ID',trigger: 'change'}],
+    // IndexName: [{required: true,message: '请输入指标名称',trigger: 'change'}],
+    // Frequency: [{required: true,message: '请选择频度',trigger: 'change'}],
+    // Unit: [{required: true,message: '请输入单位',trigger: 'change'}],
+});
+
+function closeDialog(){
+    ruleFormRef.value?.resetFields();
+    formData.IndexCode = '';
+    formData.IndexName = '';
+    formData.Frequency = '';
+    formData.Unit = '';
+    formData.StartDate = '';
+    formData.EndDate = '';
+    tableData.value = [];
+    dataList.value = [];
+    showData.value = false;
+    dataLoading.value = false;
+    saveLoading.value = false;
+};
+
+async function getIndexDetail(){
+    if(!formData.IndexCode) return;
+    dataLoading.value = true;
+    let res = await apiIndicatorImport.getIndexInfo({
+        IndexCode:formData.IndexCode
+    });
+    dataLoading.value = false;
+    if(res.Ret != 200) return;
+    const { Data } = res;
+    formData.IndexName = Data.IndexName;
+    formData.Frequency = Data.Frequency;
+    formData.Unit = Data.Unit;
+    formData.StartDate = Data.StartDate;
+    formData.EndDate = Data.EndDate;
+    dataList.value = Data.DataList || [];
+    tableData.value = [{
+        StartDate:formData.StartDate,
+        EndDate:formData.EndDate,
+        IndexCode:formData.IndexCode
+    }]
+    showData.value = true;
+}
+
+async function confirm(){
+   await ruleFormRef.value?.validate();
+//    if(!showData.value) return ElMessage.warning('请在数据搜索之后再进行添加操作');
+   saveLoading.value = true; 
+   let res = await apiIndicatorImport.dataPush({ IndexCode:formData.IndexCode });
+   saveLoading.value = false;
+   if(res.Ret != 200) return;
+   ElMessage.success('添加成功')
+   emits('success');
+   show.value = false;
+}
+
+</script>
+
+<template>
+    <el-dialog
+        v-model="show"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        width="75%"
+        draggable
+        title="添加指标"
+        @close="closeDialog"
+        style="min-width: 900px;overflow: auto;"
+    >
+        <el-form ref="ruleFormRef" :model="formData" size="large" @submit.prevent class="form-wrap" :rules="rules">
+            <el-form-item label="指标ID" :style="showData?`flex:1`:`width:300px;`" prop="IndexCode">
+                <el-input v-model="formData.IndexCode" placeholder="请输入指标ID" @change="getIndexDetail" clearable/>
+            </el-form-item>
+            <el-form-item label="指标名称" style="flex: 1;" v-if="showData" prop="IndexName">
+                <el-input v-model="formData.IndexName" placeholder="请输入指标名称" clearable :disabled="true"/>
+            </el-form-item>
+            <el-form-item label="频度" style="flex: 1;" v-if="showData" prop="Frequency">
+                <el-select
+                    v-model="formData.Frequency"
+                    placeholder="请选择频度"
+                    clearable
+                    :disabled="true"
+                >
+                    <el-option v-for="item in frequencyOptions" :key="item.val" :label="item.label" :value="item.val"/>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="单位" style="flex: 1;" v-if="showData" prop="Unit">
+                <el-input v-model="formData.Unit" placeholder="请输入单位" clearable :disabled="true"/>
+            </el-form-item>
+        </el-form>
+        <div class="main" v-loading="dataLoading">
+            <el-table
+                :data="tableData"
+                border
+            >
+                <el-table-column
+                    v-for="item in tableColums"
+                    :key="item.label"
+                    :label="item.label"
+                    :width="item.widthsty"
+                    :min-width="item.minwidthsty"
+                    align="center"
+                    >
+                    <template #default="scope">
+                        <span>{{ scope.row[item.key] }}</span>
+                    </template>
+                </el-table-column>
+                <template #empty>
+                    <el-empty description="暂无数据" />
+                </template>
+            </el-table>
+            <div v-if="dataList && dataList.length" class="value-ul" ref="valueUl">
+                 <div v-for="(item,index) in dataList" :key="index + 1" class="ul-content">
+                     <div>{{ item.Date }}</div>
+                     <div>{{ item.Value }}</div>
+                 </div>
+            </div>
+        </div>
+        <div class="footer">
+            <el-button @click="show = false" size="large" style="width: 100px;">取 消</el-button>
+            <el-button type="primary" size="large" style="width: 100px;margin-left: 20px;" @click="confirm" :loading="saveLoading">确定</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+.form-wrap{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 37px;
+}
+.main {
+    .value-ul{
+        height: 300px;
+        margin-top: 0;
+        border-bottom: 1px solid #EBEFF6;
+        border-left: 1px solid #EBEFF6;
+        border-right: 1px solid #EBEFF6;
+        overflow-y: auto;
+        .ul-content{
+            display: flex;
+            align-items: center;
+            justify-content: space-around;
+            line-height: 40px;
+            color: #666;
+        }
+    }
+}
+.footer{
+    margin: 80px 0 40px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+</style>

+ 181 - 0
src/views/indicator/components/edbDetailDialog.vue

@@ -0,0 +1,181 @@
+<script setup>
+import { ref, reactive, watch } from 'vue'
+import { apiIndicatorImport } from '@/api/indicator'
+const isShow = defineModel('isShow', { type: Boolean, default: false });
+const valueUl = ref();
+const props = defineProps({
+    edbInfo:{
+        type:Object,
+        default:()=>{},
+    }
+})
+
+const tableColums = [
+    {
+        label: '指标ID',
+        key: 'IndexCode',
+    },
+    {
+        label: '指标名称',
+        key: 'IndexName',
+    },
+    {
+        label: '指标开始时间',
+        key: 'StartDate',
+    },
+    {
+        label: '指标最新时间',
+        key: 'EndDate',
+    },
+]
+
+const tableData = ref([]);
+const dataList = ref([]);
+const page_no = ref(1);
+const haveMore = ref(true);
+const dataLoading = ref(false);
+
+watch(isShow,(newval)=>{
+  if(!newval) return;
+  tableData.value = [props.edbInfo];
+  getData();
+})
+
+async function getData(){
+    const params = {
+        CurrentIndex: page_no.value,
+        PageSize: 10,
+        IndexCode: props.edbInfo.IndexCode
+    };
+    dataLoading.value = true;
+    let res = await apiIndicatorImport.getBusDataList(params)
+    dataLoading.value = false;
+    if(res.Ret!==200) return
+    haveMore.value = page_no.value  < res.Data.Paging.Pages ? true : false;
+    let data = res.Data.List||[];
+    dataList.value = page_no.value===1 ? data : dataList.value.concat(data);
+}
+
+function cancelHandle(){
+    page_no.value = 1;
+    tableData.value = [];
+    dataList.value = [];
+    haveMore.value = true;
+    valueUl.value && (valueUl.value.scrollTop=0);
+    dataLoading.value = false;
+    isShow.value = false;
+}
+
+function scrollHandle(e) {
+    const dom = e.target
+    let scrollTop = dom.scrollTop; //滑入屏幕上方的高度
+    let windowHeitht = dom.clientHeight; //页面的高度
+    let scrollHeight = dom.scrollHeight; //整个div的高度
+    let total = Math.ceil(scrollTop + windowHeitht);
+    if(total >= scrollHeight && haveMore.value){
+        if(dataLoading.value) return;
+        page_no.value ++;
+        getData();
+    }
+}
+</script>
+
+<template>
+    <el-dialog
+        v-model="isShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        width="75%"
+        draggable
+        title="查看数据"
+        @close="cancelHandle"
+        style="min-width: 800px;overflow: auto;"
+    >
+        <div class="main">
+            <el-table
+                :data="tableData"
+                style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);"
+                border
+            >
+                <el-table-column
+                    v-for="item in tableColums"
+                    :key="item.label"
+                    :label="item.label"
+                    :width="item.widthsty"
+                    :min-width="item.minwidthsty"
+                    align="center"
+                >
+                <template #default="scope">
+                    <span>{{ scope.row[item.key] }}</span>
+                </template>
+                </el-table-column>
+            </el-table>
+            <div 
+                class="value-ul" 
+                ref="valueUl" 
+                @scroll="scrollHandle" 
+                v-if="dataList.length"
+            >
+                <div
+                    class="value-item"
+                    v-for="(item,index) in dataList"
+                    :key="index + 1"
+                >
+                <span class="value-label">
+                    <span style="position: relative;">
+                    <i class="new-tag" v-if="index===0"></i>
+                    {{item.DataTime}}
+                    </span>
+                </span>
+                <span class="value-label" style="min-width:200px;text-align:center;">
+                    <span class="value-style">{{item.Value}}</span>
+                </span>
+                </div>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+.main {
+    padding: 20px 0 40px 0;
+    .value-ul {
+        height: 300px;
+        margin-top: 10px;
+        border-bottom: 1px solid #EBEFF6;
+        overflow-y: auto;
+        .value-item {
+            padding: 10px 0;
+            border: 1px solid #dcdfe6;
+            border-bottom: none;
+            display: flex;
+            justify-content: space-around;
+        >span{
+            padding:0 16px;
+            box-sizing: border-box;
+        }
+        .value-label {
+            position: relative;
+            color: #666;
+        }
+        
+        .new-tag {
+            width: 6px;
+            height: 6px;
+            display: inline-block;
+            position: absolute;
+            left: -12px;
+            top: 50%;
+            transform: translateY(-50%);
+            border-radius: 50%;
+            background: #f00;
+        }
+        }
+        .nodata {
+            text-align: center;
+            padding: 40px 0;
+            color: #999;
+        }
+    }
+}
+</style>