Sfoglia il codice sorgente

批量移动图表

jwyu 10 mesi fa
parent
commit
7366defb86

+ 1 - 1
package.json

@@ -21,7 +21,7 @@
     "moment": "^2.30.1",
     "normalize.css": "^8.0.1",
     "tdesign-icons-vue-next": "^0.2.2",
-    "tdesign-vue-next": "^1.9.3",
+    "tdesign-vue-next": "^1.9.4",
     "vue": "^3.4.21",
     "vue-router": "^4.3.2"
   },

+ 4 - 4
pnpm-lock.yaml

@@ -35,8 +35,8 @@ dependencies:
     specifier: ^0.2.2
     version: 0.2.2(vue@3.4.21)
   tdesign-vue-next:
-    specifier: ^1.9.3
-    version: 1.9.3(vue@3.4.21)
+    specifier: ^1.9.4
+    version: 1.9.4(vue@3.4.21)
   vue:
     specifier: ^3.4.21
     version: 3.4.21
@@ -2735,8 +2735,8 @@ packages:
       vue: 3.4.21
     dev: false
 
-  /tdesign-vue-next@1.9.3(vue@3.4.21):
-    resolution: {integrity: sha512-mNne2lxoMnOeQbkc3zusvfsC+WZ02Dg5dCKzrVZJPh/RTKHrf+h+qphOduzApjLJ7Nd8hm5wPz3bMPIt5iLarw==}
+  /tdesign-vue-next@1.9.4(vue@3.4.21):
+    resolution: {integrity: sha512-mbm2mGzM8WKCkxhFnJa9xyAhaXoP7i/TlJrIFe45BqI8cF3EMHuI6+Bb+8c6V320FSLpmlhChishIC8rGPcWYA==}
     peerDependencies:
       vue: '>=3.1.0'
     dependencies:

+ 15 - 2
src/api/etaChart/etaChart.js

@@ -1,7 +1,7 @@
 import {get,post} from '@/api/index'
 
 export default{
-    /* 图表分类
+    /* 图表分类(包含图表)
      * ParentId:0 表示查询未分类目录下的内容,-1表示查询所有一级目录
     */
     classifyList:params=>{
@@ -23,8 +23,16 @@ export default{
     classifySort:params=>{
         return post('/chart/classify/move',params)
     },
+    // 获取所有的分类数据(不包含图表)
+    classifyNoChart:()=>{
+        return get('/chart/classify/tree',{})
+    },
+    // 批量移动图表
+    moveChartBatch:params=>{
+        return post('/chart/modify_chart_classify',params)
+    },
 
-    // 图列表
+    // 图列表(根据分类获取的)
     chartList:params=>{
         return get('/chart/classify/chart_list',params)
     },
@@ -39,6 +47,11 @@ export default{
     // 指标溯源
     getEdbSource:params=>{
         return get('/edb/trace',params)
+    },
+
+    // 纯图表列表接口
+    chartListFilter:params=>{
+        return get('/chart/list',params)
     }
 
 

+ 1 - 1
src/styles/common.scss

@@ -10,7 +10,7 @@ div,ul,li{
 }
 
 input{
-    display: block;
+    display: inline-block;
     border: none;
     box-sizing: border-box;
 }

+ 1 - 1
src/views/etaChart/components/ChartWrap.vue

@@ -139,7 +139,7 @@ function handleGoEdbSource(data) {
       </div>
       <div class="table-wrap">
         <t-table
-          row-key="index"
+          row-key="ChartInfoId"
           :data="tableData"
           :columns="columns"
           bordered

+ 12 - 1
src/views/etaChart/components/ClassifyWrap.vue

@@ -6,6 +6,7 @@ import {apiSystemCommon} from '@/api/system'
 import { ElTree } from 'element-plus'
 import 'element-plus/es/components/tree/style/css'
 import {useClassify} from '../hooks/useClassify'
+import MoveClassify from './MoveClassify.vue'
 
 const emits = defineEmits(['change','filter'])
 
@@ -306,6 +307,8 @@ function handleDropOver(b, a, i, e) {
   })
 }
 
+const showBatchMove=ref(false)
+
 </script>
 
 <template>
@@ -427,6 +430,10 @@ function handleDropOver(b, a, i, e) {
       <t-icon name="add-rectangle" />
       <span>添加图表分类</span>
     </div>
+    <div class="classify-add-box" @click="showBatchMove = true">
+      <t-icon name="add-rectangle" />
+      <span>编辑图表分类</span>
+    </div>
   </div>
   <!-- 编辑分类 -->
   <t-dialog
@@ -463,6 +470,9 @@ function handleDropOver(b, a, i, e) {
       </t-form-item>
     </t-form>
   </t-dialog>
+
+  <!-- 批量移动图表 -->
+  <MoveClassify v-model:show="showBatchMove" @success="getClassify"/>
 </template>
 
 <style lang="scss">
@@ -510,7 +520,7 @@ function handleDropOver(b, a, i, e) {
   }
   .classify-list-box {
     padding-top: 10px;
-    height: calc(100vh - 260px);
+    height: calc(100vh - 300px);
     overflow-y: auto;
     .classify-item-box {
       flex: 1;
@@ -530,6 +540,7 @@ function handleDropOver(b, a, i, e) {
     }
   }
   .classify-add-box {
+    padding-top: 20px;
     cursor: pointer;
     display: flex;
     align-items: center;

+ 287 - 0
src/views/etaChart/components/MoveClassify.vue

@@ -0,0 +1,287 @@
+<script setup>
+import { computed, reactive, ref, watch } from 'vue'
+import { apiSystemCommon } from '@/api/system'
+import { apiETAChart } from '@/api/etaChart'
+import { SearchIcon } from 'tdesign-icons-vue-next';
+
+const show = defineModel('show', { type: Boolean, default: false })
+const emits=defineEmits(['success'])
+
+const filterState = reactive({
+  classify: '',
+  user: '',
+  searchVal: '',
+  checkAll: false,
+  targetClassify: ''
+})
+
+const userProps = {
+  label: 'RealName',
+  value: 'AdminId',
+  children: 'ChildrenList'
+}
+const userOpts = ref([])
+async function getCompanyUserData() {
+  const res = await apiSystemCommon.companyUserList()
+  if (res.Ret === 200) {
+    userOpts.value = res.Data.List || []
+  }
+}
+getCompanyUserData()
+
+
+const classifyTreeKeys = {
+  label: 'ChartClassifyName',
+  value: 'ChartClassifyId',
+  children: 'Children',
+}
+const classifyOpts = ref([])
+async function getClassifyOpts() {
+  const res = await apiETAChart.classifyNoChart()
+  if (res.Ret === 200) {
+    classifyOpts.value = res.Data.AllNodes || []
+  }
+}
+getClassifyOpts()
+
+
+const pagination = ref({
+  current: 1,
+  pageSize: 20,
+  defaultPageSize: 20,
+  total: 0,
+  pageSizeOptions: [],
+})
+const tableColumns = [
+  {
+    colKey: 'row-select',
+    type: 'multiple',
+    width: 50,
+  },
+  {
+    colKey: 'ChartClassifyName',
+    title: '图表名称',
+    align: 'center'
+  },
+  {
+    colKey: 'Company',
+    title: '机构',
+    width: '120',
+    align: 'center'
+  },
+  {
+    colKey: 'SysUserRealName',
+    title: '创建人',
+    width: '120',
+    align: 'center'
+  }
+]
+const tableData = ref([])
+async function getChartList() {
+  const res = await apiETAChart.chartListFilter({
+    ChartClassifyIds: filterState.classify ? filterState.classify.join(',') : '',
+    PageSize: pagination.value.defaultPageSize,
+    CurrentIndex: pagination.value.current,
+    SysUserIds: filterState.user ? filterState.user.join(',') : '',
+    ChartName: filterState.searchVal
+  })
+  if (res.Ret === 200) {
+    tableData.value = res.Data.AllNodes || []
+    pagination.value.total = res.Data.Paging.Totals
+
+    if(filterState.checkAll){
+      handleClickCheckAll(filterState.checkAll)
+    }
+  }
+}
+getChartList()
+
+function handlePageChange(pageInfo) {
+  pagination.value.current = pageInfo.current
+  getChartList()
+}
+function handleRefreshList() {
+  pagination.value.current = 1
+  getChartList()
+}
+watch(
+  [() => filterState.classify, () => filterState.user],
+  () => {
+    handleRefreshList()
+  }
+)
+
+const indeterminate=computed(()=>{
+  if(filterState.checkAll) return false
+  if(selectedRowKeys.value.length>0) return true
+})
+const selectedRowKeys = ref([])
+function tableSelectChange(value, ctx) {
+  selectedRowKeys.value = value
+  if(ctx.type==="uncheck"&&filterState.checkAll){
+    filterState.checkAll=false
+  }
+  if(ctx.type==='check'&&selectedRowKeys.value.length>0){
+    filterState.indeterminate=true
+  }
+}
+
+function handleClickCheckAll(check) {
+  if(check){
+    // 全选
+    selectedRowKeys.value=[]
+    tableData.value.forEach(item=>{
+      selectedRowKeys.value.push(item.ChartInfoId)
+    })
+  }else{
+    selectedRowKeys.value=[]
+  }
+}
+
+
+function handleConfirmClassify() {
+  if(!filterState.checkAll&&selectedRowKeys.value.length===0){
+    MessagePlugin.warning('请选择要移动的图表')
+    return
+  }
+  if(!filterState.targetClassify){
+    MessagePlugin.warning('请选择要移动至的分类')
+    return
+  }
+  const params={
+    SelectAll: filterState.checkAll,
+    ChartClassifyIds: filterState.classify ? filterState.classify.join(',') : '', //多个分类id用英文逗号拼接
+    SysUserIds: filterState.user ? filterState.user.join(',') : '',
+    ChartName: filterState.searchVal, //图表名称
+    ChartInfoIds: selectedRowKeys.value.join(','), //选中的图表ID
+    ChartClassifyId: filterState.targetClassify//新分类ID
+  }
+  console.log(params);
+  apiETAChart.moveChartBatch(params).then(res=>{
+    if(res.Ret===200){
+      MessagePlugin.success('操作成功')
+      filterState.classify=''
+      filterState.user=''
+      filterState.searchVal=''
+      filterState.checkAll=false
+      filterState.targetClassify=''
+      pagination.value.current=1
+      tableData.value=[]
+      selectedRowKeys.value=[]
+      show.value=false
+      emits('success')
+    }
+  })
+}
+
+</script>
+
+<template>
+  <t-dialog
+    v-model:visible="show"
+    header="编辑图表分类"
+    draggable
+    attach="body"
+    width="800px"
+    :confirm-on-enter="true"
+    :on-confirm="handleConfirmClassify"
+    class="batch-move-classify-wrap"
+  >
+    <div class="select-classify-wrap">
+      <div class="top-wrap">
+        <span class="label">待选图表</span>
+        <!-- tdesign 有bug 清空选择会触发多次 他们已经修复了但是还没发版 暂时用watch来代替下 -->
+        <!-- @change="handleRefreshList" -->
+        <t-cascader
+          v-model="filterState.classify"
+          :options="classifyOpts"
+          :keys="classifyTreeKeys"
+          multiple
+          :min-collapsed-num="1"
+          clearable
+          :showAllLevels="false"
+          placeholder="图表分类"
+        />
+        <!-- @change="handleRefreshList" -->
+        <t-cascader
+          v-model="filterState.user"
+          :options="userOpts"
+          :keys="userProps"
+          multiple
+          :minCollapsedNum="1"
+          clearable
+          filterable
+          :showAllLevels="false"
+          placeholder="创建人"
+        />
+        <t-input
+          v-model="filterState.searchVal"
+          placeholder="图表名称"
+          @change="handleRefreshList"
+        >
+          <template #prefix-icon>
+            <SearchIcon />
+          </template>
+        </t-input>
+        <t-checkbox
+          style="flex-shrink: 0"
+          :indeterminate="indeterminate"
+          v-model="filterState.checkAll"
+          @change="handleClickCheckAll"
+          >全选</t-checkbox
+        >
+      </div>
+      <div class="table-wrap">
+        <t-table
+          row-key="ChartInfoId"
+          :data="tableData"
+          :columns="tableColumns"
+          bordered
+          :pagination="pagination"
+          cell-empty-content="-"
+          resizable
+          max-height="500"
+          v-model:selectedRowKeys="selectedRowKeys"
+          @select-change="tableSelectChange"
+          @page-change="handlePageChange"
+        >
+        </t-table>
+      </div>
+      <div class="top-wrap">
+        <span class="label">移动至新分类</span>
+        <t-cascader
+          v-model="filterState.targetClassify"
+          :options="classifyOpts"
+          :keys="classifyTreeKeys"
+          placeholder="图表分类"
+          style="width: 300px"
+          check-strictly
+        />
+      </div>
+    </div>
+  </t-dialog>
+</template>
+
+<style lang="scss">
+.batch-move-classify-wrap {
+  .t-dialog__footer {
+    text-align: center;
+  }
+}
+</style>
+<style lang="scss" scoped>
+.select-classify-wrap {
+  .top-wrap {
+    display: flex;
+    align-items: center;
+    gap: 0 10px;
+    .label {
+      flex-shrink: 0;
+      color: #333;
+    }
+  }
+  .table-wrap {
+    margin: 20px 0;
+  }
+}
+</style>