Browse Source

我的收藏模块

yujinwen 4 months ago
parent
commit
c671bf0478

+ 2 - 0
src/api/etaChart/index.js

@@ -1,5 +1,7 @@
 import apiETAChart from './etaChart'
 import apiETAChart from './etaChart'
+import apiETAChartUser from './user'
 
 
 export {
 export {
     apiETAChart,
     apiETAChart,
+    apiETAChartUser
 }
 }

+ 43 - 0
src/api/etaChart/user.js

@@ -0,0 +1,43 @@
+import {get,post} from '@/api/index'
+
+// 图表用户模块
+export default{
+  // 新增分类
+  addClassify:(params)=>{
+    return post('/chart_collect/classify/add',params)
+  },
+  // 编辑分类
+  editClassify:(params)=>{
+    return post('/chart_collect/classify/edit',params)
+  },
+  // 移动分类
+  moveClassify:(params)=>{
+    return post('/chart_collect/classify/move',params)
+  },
+  // 删除分类
+  deleteClassify:(params)=>{
+    return post('/chart_collect/classify/delete',params)
+  },
+  // 分类列表
+  classifyList:(params)=>{
+    return get('/chart_collect/classify/list',params)
+  },
+
+  // 收藏图表
+  chartCollect:(params)=>{
+    return post('/chart_collect/add',params)
+  },
+  // 取消收藏图表
+  chartCollectCancel:(params)=>{
+    return post('/chart_collect/delete',params)
+  },
+  // 收藏图表列表数据
+  chartCollectList:(params)=>{
+    return get('/chart_collect/list',params)
+  },
+  // 批量转移图表
+  chartCollectBatchMove:(params)=>{
+    return post('/chart_collect/modify_chart_classify',params)
+  },
+  
+}

BIN
src/assets/icons/pop_close.png


+ 1 - 1
src/components/SelectChartCreator.vue

@@ -16,7 +16,7 @@ const userProps = {
   children: 'ChildrenList'
   children: 'ChildrenList'
 }
 }
 const userOpts = ref([])
 const userOpts = ref([])
-const userVal =defineModel('value')
+const userVal =defineModel('value',{type:[String,Array],default:[]})
 async function getCompanyUserData() {
 async function getCompanyUserData() {
   const res = await apiSystemCommon.companyUserList()
   const res = await apiSystemCommon.companyUserList()
   if (res.Ret === 200) {
   if (res.Ret === 200) {

+ 11 - 1
src/layout/Index.vue

@@ -1,4 +1,14 @@
 <script setup>
 <script setup>
+import {confirmDialog} from '@/plugin/dialog.jsx'
+
+
+async function handleLoginOut(){
+	await confirmDialog({
+    header:'提示',
+    body: '是否确认退出当前账号',
+		confirmBtn:'确认退出'
+  }); 
+}
 
 
 </script>
 </script>
 
 
@@ -27,7 +37,7 @@
 							<span>我的收藏</span>
 							<span>我的收藏</span>
 							<t-icon class="arrow-right" name="chevron-right-s" style="font-size:20px"></t-icon>
 							<t-icon class="arrow-right" name="chevron-right-s" style="font-size:20px"></t-icon>
 						</div>
 						</div>
-						<div class="flex my-fav-box" style="color:#D54941">
+						<div class="flex my-fav-box" style="color:#D54941" @click="handleLoginOut">
 							<t-icon name="logout" style="font-size:20px"></t-icon>
 							<t-icon name="logout" style="font-size:20px"></t-icon>
 							<span>退出登录</span>
 							<span>退出登录</span>
 						</div>
 						</div>

+ 2 - 2
src/plugin/dialog.jsx

@@ -9,11 +9,11 @@ export function confirmDialog(props){
   </div>
   </div>
   return new Promise((resolve,reject)=>{
   return new Promise((resolve,reject)=>{
     const confirmDia = DialogPlugin.confirm({
     const confirmDia = DialogPlugin.confirm({
+      confirmBtn: '确定',
+      cancelBtn: '取消',
       ...props,
       ...props,
       className:'dialog-confirm-pop',
       className:'dialog-confirm-pop',
       header:headerHtml,
       header:headerHtml,
-      confirmBtn: '确定',
-      cancelBtn: '取消',
       onConfirm: ({ e }) => {
       onConfirm: ({ e }) => {
         resolve(true)
         resolve(true)
         confirmDia.destroy();
         confirmDia.destroy();

+ 2 - 0
src/styles/tdesign.scss

@@ -20,6 +20,7 @@
   }
   }
   .t-dialog__footer{
   .t-dialog__footer{
     padding: 40px;
     padding: 40px;
+    text-align: center;
   }
   }
 }
 }
 
 
@@ -38,6 +39,7 @@
   }
   }
   .t-dialog__footer{
   .t-dialog__footer{
     padding: 20px;
     padding: 20px;
+    text-align: right;
   }
   }
 }
 }
 
 

+ 12 - 7
src/views/etaChart/components/ChartDetailPop.vue

@@ -71,8 +71,7 @@ watch(
     closeOnOverlayClick
     closeOnOverlayClick
     destroyOnClose
     destroyOnClose
     class="chart-detail-pop-wrap"
     class="chart-detail-pop-wrap"
-  >
-    <t-icon name="close" class="close-btn"></t-icon>
+  > 
     <div class="flex top-box">
     <div class="flex top-box">
       <div class="chart-name">{{chartInfo?.ChartName}}</div>
       <div class="chart-name">{{chartInfo?.ChartName}}</div>
       <svg-icon name="star" style="font-size:20px;cursor: pointer;"></svg-icon>
       <svg-icon name="star" style="font-size:20px;cursor: pointer;"></svg-icon>
@@ -109,15 +108,21 @@ watch(
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .chart-detail-pop-wrap{
 .chart-detail-pop-wrap{
-  .close-btn{
+  :global(.chart-detail-pop-wrap .t-dialog__position::after){
+    content:'';
+    background-image: url('@/assets/icons/pop_close.png');
+    background-size: cover;
+    width: 48px;
+    height: 48px;
+    display: block;
     position: absolute;
     position: absolute;
-    top: -20px;
-    right: -100px;
+    right: calc(10vw - 70px);
+    top: calc(20vh - 30px);
   }
   }
-  :global(.t-dialog__header){
+  :global(.chart-detail-pop-wrap .t-dialog__header){
     display: none;
     display: none;
   }
   }
-  :global(.t-dialog__body){
+  :global(.chart-detail-pop-wrap .t-dialog__body){
     padding: 0 !important;
     padding: 0 !important;
   }
   }
   .top-box{
   .top-box{

+ 7 - 1
src/views/etaChart/components/chartList/ChartBox.vue

@@ -3,6 +3,7 @@ import { apiETAChart } from '@/api/etaChart'
 import { useChartRender } from '@/hooks/chart/render'
 import { useChartRender } from '@/hooks/chart/render'
 import { onUnmounted, useTemplateRef } from 'vue'
 import { onUnmounted, useTemplateRef } from 'vue'
 import ChartDetailPop from '../ChartDetailPop.vue'
 import ChartDetailPop from '../ChartDetailPop.vue'
+import CollectChart from '@/views/user/favorite/components/CollectChart.vue'
 
 
 const { options, axisLimitState, chartRender, setLimitData, isUseSelfLimit } = useChartRender()
 const { options, axisLimitState, chartRender, setLimitData, isUseSelfLimit } = useChartRender()
 
 
@@ -93,13 +94,15 @@ onUnmounted(()=>{
 
 
 const showChartDetailPop=ref(false)
 const showChartDetailPop=ref(false)
 
 
+const showCollectChart=ref(false)
+
 </script>
 </script>
 
 
 <template>
 <template>
   <div class="flex chart-list-item-box" ref="compRef">
   <div class="flex chart-list-item-box" ref="compRef">
     <div class="flex top-box">
     <div class="flex top-box">
       <div class="text-ellipsis--l1 title">{{props.chartData.ChartClassifyName}}</div>
       <div class="text-ellipsis--l1 title">{{props.chartData.ChartClassifyName}}</div>
-      <svg-icon name="star" style="font-size:20px;cursor: pointer;"></svg-icon>
+      <svg-icon name="star" style="font-size:20px;cursor: pointer;" @click="showCollectChart=true"></svg-icon>
       <svg-icon name="full_screen" style="font-size:20px;margin-left:20px;cursor: pointer;" @click="showChartDetailPop=true"></svg-icon>
       <svg-icon name="full_screen" style="font-size:20px;margin-left:20px;cursor: pointer;" @click="showChartDetailPop=true"></svg-icon>
     </div>
     </div>
     <div class="chart-render-wrap" v-loading="loading">
     <div class="chart-render-wrap" v-loading="loading">
@@ -133,6 +136,9 @@ const showChartDetailPop=ref(false)
 
 
   <!-- 图表详情弹窗 -->
   <!-- 图表详情弹窗 -->
   <ChartDetailPop v-model:show="showChartDetailPop" :chartInfoId="chartInfo?.ChartInfoId"/>
   <ChartDetailPop v-model:show="showChartDetailPop" :chartInfoId="chartInfo?.ChartInfoId"/>
+
+  <!-- 收藏图表 -->
+  <CollectChart v-model:show="showCollectChart" :data="chartInfo"/>
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 79 - 27
src/views/user/favorite/components/ClassifyWrap.vue

@@ -1,9 +1,27 @@
-<script setup lang='jsx'>
-import { useTemplateRef } from "vue";
+<script setup>
+import {apiETAChartUser} from '@/api/etaChart'
+import { useTemplateRef, watch } from "vue";
 import EditClassify from './EditClassify.vue'
 import EditClassify from './EditClassify.vue'
+import MoveChart from './MoveChart.vue'
 import {confirmDialog} from '@/plugin/dialog.jsx'
 import {confirmDialog} from '@/plugin/dialog.jsx'
+import { MessagePlugin } from 'tdesign-vue-next';
 
 
-const classifyOpts=[
+const emits=defineEmits(['change'])
+
+const selecClassify=ref(0)
+function handleClassifyItemClick({node}){
+  selecClassify.value=node.value
+}
+
+watch(
+  ()=>selecClassify.value,
+  ()=>{
+    console.log("分类改变");
+    emits('change',selecClassify.value)
+  }
+)
+
+const classifyActions=[
   {
   {
     content:'重命名',
     content:'重命名',
     value:'rename',
     value:'rename',
@@ -18,32 +36,40 @@ const classifyOpts=[
     action: (node) => handleDeleteClassify(node),
     action: (node) => handleDeleteClassify(node),
   }
   }
 ]
 ]
-const classifyList=ref([
-  {
-    value:1,
-    label:1
-  },
-  {
-    value:2,
-    label:2
-  },
-  {
-    value:3,
-    label:3
+const classifyList=ref([])
+// 获取分类
+async function getClassifyList(){
+  const res=await apiETAChartUser.classifyList()
+  if(res.Ret!==200)return
+  const arr=res.Data?.List||[]
+  classifyList.value=arr
+  if(arr.length>0){
+    selecClassify.value=arr[0].CollectClassifyId
   }
   }
-])
-
-
-const treeIns=useTemplateRef('treeIns')
-function handleSortEnd({node}){
-  const resArr=treeIns.value.getTreeData()//移动后的数组
-  const moveTargetIndex=treeIns.value.getIndex(node.value)//被拖动的元素拖动后的位置
 }
 }
+getClassifyList()
 
 
+// 移动排序
+const treeIns=useTemplateRef('treeIns')
 // dropPosition -1放在dropNode前面 0里面 1后面
 // dropPosition -1放在dropNode前面 0里面 1后面
 function handleAllowDrop({dropNode, dropPosition}){
 function handleAllowDrop({dropNode, dropPosition}){
   if(dropPosition===0) return false//不允许向里面拖动
   if(dropPosition===0) return false//不允许向里面拖动
 }
 }
+async function handleSortEnd({node}){
+  const resArr=treeIns.value.getTreeData()//移动后的数组
+  const moveTargetIndex=treeIns.value.getIndex(node.value)//被拖动的元素拖动后的位置
+  const params={
+    PrevCollectClassifyId:moveTargetIndex===0?0:resArr[moveTargetIndex-1].CollectClassifyId,
+    NextCollectClassifyId:moveTargetIndex===resArr.length-1?0:resArr[moveTargetIndex+1].CollectClassifyId,
+    CollectClassifyId:node.value
+  }
+  const res=await apiETAChartUser.moveClassify(params)
+  if(res.Ret!==200){
+    getClassifyList()
+    return
+  }
+  MessagePlugin.success("移动成功")
+}
 
 
 
 
 // 删除分类
 // 删除分类
@@ -52,16 +78,24 @@ async function handleDeleteClassify(node){
     header:'提示',
     header:'提示',
     body: '若删除该分类,则分类下关联的所有图表将被全部删除,是否继续?',
     body: '若删除该分类,则分类下关联的所有图表将被全部删除,是否继续?',
   });
   });
-
+  const res=await apiETAChartUser.deleteClassify({
+    CollectClassifyId:node.value
+  })
+  if(res.Ret!==200) return
+  MessagePlugin.success('删除成功')
+  getClassifyList()
 }
 }
 
 
 const showEditClassify=ref(false)
 const showEditClassify=ref(false)
 const activeClassifyData=ref(null)
 const activeClassifyData=ref(null)
-// 点击操作
+// 点击分类的操作
 function clickHandler(option,node){
 function clickHandler(option,node){
   option.action(node);
   option.action(node);
 }
 }
 
 
+// 转移分类
+const showMoveChart=ref(false)
+
 </script>
 </script>
 
 
 <template>
 <template>
@@ -70,21 +104,30 @@ function clickHandler(option,node){
     <div class="classify-tree">
     <div class="classify-tree">
       <t-tree
       <t-tree
         ref="treeIns"
         ref="treeIns"
+        :actived="[selecClassify]"
         :data="classifyList"
         :data="classifyList"
+        :keys="{value:'CollectClassifyId',label:'ClassifyName'}"
         activable
         activable
         transition
         transition
         draggable
         draggable
         :allow-drop="handleAllowDrop"
         :allow-drop="handleAllowDrop"
         :onDragEnd="handleSortEnd"
         :onDragEnd="handleSortEnd"
+        :onClick="handleClassifyItemClick"
       >
       >
         <template #icon>
         <template #icon>
           <t-icon name="drag-move" style="font-size:20px"></t-icon>
           <t-icon name="drag-move" style="font-size:20px"></t-icon>
         </template>
         </template>
         <template #operations="{node}">
         <template #operations="{node}">
-          <t-dropdown :options="classifyOpts" trigger="hover" @click="clickHandler($event,node)">
+          <t-dropdown :options="classifyActions" trigger="hover" @click="clickHandler($event,node)">
             <t-icon name="more" style="font-size:20px"></t-icon>
             <t-icon name="more" style="font-size:20px"></t-icon>
           </t-dropdown>
           </t-dropdown>
         </template>
         </template>
+        <template #empty>
+          <div style="text-align:center">
+            <img style="width:50%" src="@/assets/imgs/nodata.png" alt="">
+            <div>暂无数据</div>
+          </div>
+        </template>
       </t-tree>
       </t-tree>
     </div>
     </div>
     <div>
     <div>
@@ -92,14 +135,20 @@ function clickHandler(option,node){
         <t-icon name="add-rectangle" size="20px"></t-icon>
         <t-icon name="add-rectangle" size="20px"></t-icon>
         <span>添加分类</span>
         <span>添加分类</span>
       </div>
       </div>
-      <div class="opt-item">
+      <div class="opt-item" @click="showMoveChart=true">
         <t-icon name="swap" size="20px"></t-icon>
         <t-icon name="swap" size="20px"></t-icon>
         <span>转移分类</span>
         <span>转移分类</span>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
   <!-- 新增\编辑分类 -->
   <!-- 新增\编辑分类 -->
-  <EditClassify v-model:show="showEditClassify" :data="activeClassifyData"/>
+  <EditClassify 
+    v-model:show="showEditClassify" 
+    :data="activeClassifyData" 
+    @change="getClassifyList"
+  />
+  <!-- 转移分类 -->
+  <MoveChart v-model:show="showMoveChart" :classifyOpts="classifyList"/>
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -117,6 +166,9 @@ function clickHandler(option,node){
     flex: 1;
     flex: 1;
     overflow-y: auto;
     overflow-y: auto;
     padding-bottom: 30px;
     padding-bottom: 30px;
+    :deep(.t-is-active){
+      background-color: var(--td-brand-color-light);
+    }
     :deep(.t-tree__icon){
     :deep(.t-tree__icon){
       margin-left: 20px;
       margin-left: 20px;
     }
     }

+ 117 - 0
src/views/user/favorite/components/CollectChart.vue

@@ -0,0 +1,117 @@
+<script setup>
+import { apiETAChartUser } from '@/api/etaChart'
+import { MessagePlugin } from 'tdesign-vue-next'
+import EditClassify from './EditClassify.vue'
+
+
+
+const show = defineModel('show', { type: Boolean, default: false })
+const emits = defineEmits(['change'])
+
+const props = defineProps({
+  data: {
+    type: [null, Object],
+    default: null
+  }
+})
+
+const selectClassify = ref('')
+const classifyOpts = ref([])
+async function getClassifyOpts() {
+  const res = await apiETAChartUser.classifyList()
+  if (res.Ret !== 200) return
+  const arr = res.Data?.List || []
+  classifyOpts.value = arr
+}
+
+const showEditClassify=ref(false)
+
+watch(
+  () => show.value,
+  (n) => {
+    if (n) {
+      selectClassify.value = ''
+      getClassifyOpts()
+    }
+  }
+)
+
+async function handleSave(){
+  if(!selectClassify.value){
+    MessagePlugin.warning('请选择分类')
+    return
+  }
+  const res=await apiETAChartUser.chartCollect({
+    ChartInfoId:props.data.ChartInfoId,
+    CollectClassifyId:selectClassify.value
+  })
+  if(res.Ret!==200) return
+  MessagePlugin.success('收藏成功')
+  show.value=false
+}
+
+
+</script>
+
+<template>
+  <t-dialog
+    v-model:visible="show"
+    attach="body"
+    width="500px"
+    :header="'选择我的分类'"
+    closeOnOverlayClick
+    destroyOnClose
+    class="collect-chart-pop"
+  >
+    <div class="classify-wrap">
+      <t-tag
+        :theme="selectClassify===item.CollectClassifyId?'primary':'default'"
+        :variant="selectClassify===item.CollectClassifyId?'':'outline'"
+        v-for="item in classifyOpts"
+        :key="item.CollectClassifyId"
+        @click="selectClassify=item.CollectClassifyId"
+        >{{ item.ClassifyName }}</t-tag
+      >
+    </div>
+    <div class="add_btn" @click="showEditClassify=true">
+      <t-icon name="add-circle"></t-icon>
+      <span>新增</span>
+    </div>
+    <template #footer>
+      <div class="bottom-btn">
+        <t-button theme="default" @click="show = false">取消</t-button>
+        <t-button type="submit" @click="handleSave">确定</t-button>
+      </div>
+    </template>
+  </t-dialog>
+
+  <!-- 新增\编辑分类 -->
+  <EditClassify 
+    v-model:show="showEditClassify" 
+    :data="null" 
+    @change="getClassifyOpts"
+  />
+</template>
+
+<style lang="scss" scoped>
+.collect-chart-pop{
+  .classify-wrap{
+    padding: 20px;
+    border-radius: 4px;
+    border: 1px dashed var(--border-color);
+    display: flex;
+    flex-wrap: wrap;
+    gap: 5px;
+  }
+  .add_btn{
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    color: var(--td-brand-color);
+    font-size: 16px;
+    gap: 0 5px;
+    cursor: pointer;
+  }
+}
+
+</style>

+ 14 - 2
src/views/user/favorite/components/EditClassify.vue

@@ -1,9 +1,12 @@
 <script setup>
 <script setup>
 import { useTemplateRef } from "vue"
 import { useTemplateRef } from "vue"
+import {apiETAChartUser} from '@/api/etaChart'
+import {MessagePlugin} from 'tdesign-vue-next'
 
 
 
 
 
 
 const show = defineModel('show', { type: Boolean, default: false })
 const show = defineModel('show', { type: Boolean, default: false })
+const emits=defineEmits(['change'])
 
 
 const props = defineProps({
 const props = defineProps({
   data: {
   data: {
@@ -22,7 +25,16 @@ const formIns=useTemplateRef('formIns')
 async function handleSave(){
 async function handleSave(){
   const validRes=await formIns.value.validate()
   const validRes=await formIns.value.validate()
   if(validRes!==true) return
   if(validRes!==true) return
-
+  const res=props.data?await apiETAChartUser.editClassify({
+    ClassifyName:formData.classifyName,
+    CollectClassifyId:props.data.CollectClassifyId
+  }): await apiETAChartUser.addClassify({
+    ClassifyName:formData.classifyName
+  })
+  if(res.Ret!==200) return
+  MessagePlugin.success(props.data?'编辑成功':'新增成功')
+  show.value=false
+  emits('change')
 }
 }
 
 
 
 
@@ -34,7 +46,7 @@ watch(
       return
       return
     }
     }
     if(n&&props.data){
     if(n&&props.data){
-
+      formData.classifyName=props.data.ClassifyName
     }
     }
   }
   }
 )
 )

+ 141 - 5
src/views/user/favorite/components/MoveChart.vue

@@ -1,7 +1,80 @@
 <script setup>
 <script setup>
+import { apiETAChartUser } from '@/api/etaChart'
+import { SearchIcon } from 'tdesign-icons-vue-next'
+
 const show = defineModel('show', { type: Boolean, default: false })
 const show = defineModel('show', { type: Boolean, default: false })
 
 
-async function handleSave(){
+
+const props=defineProps({
+  classifyOpts:{
+    type:Array,
+    default:()=>[]
+  }
+})
+
+
+const selectClassify = ref('')
+const keyword = ref('')
+const checkAll = ref(false)
+
+const columns=[
+  {
+    colKey: 'row-select',
+    type: 'multiple',
+    width: 50,
+  },
+  {
+    colKey: 'ChartName',
+    title: '图表名称',
+    align: 'center'
+  },
+  {
+    colKey: 'UserId',
+    title: '创建人',
+    width: '120',
+    align: 'center'
+  },
+  
+]
+const tableData=ref([])
+const pagination = ref({
+  defaultPageSize: 20,
+  total: 0,
+  current: 1,
+  showPageSize:false
+});
+async function getChartList(){
+  const res=await apiETAChartUser.chartCollectList({
+    CollectClassifyIds:selectClassify.value,
+    Keyword:keyword.value,
+    PageSize:pagination.value.defaultPageSize,
+    CurrentIndex:pagination.value.current
+  })
+  if(res.Ret!==200) return
+  const arr=res.Data.List||[]
+  pagination.value.total=res.Data.Paging.Totals
+  tableData.value=arr
+}
+watch(
+  ()=>show.value,
+  (n)=>{
+    if(n){
+      getChartList()
+    }
+  }
+)
+
+function onPageChange(){
+
+}
+
+const selectedRowKeys = ref([]);
+function handleTableSelectChange(value, ctx){
+  selectedRowKeys.value=value
+}
+
+const newClassify=ref('')
+async function handleSave() {
 
 
 }
 }
 
 
@@ -12,12 +85,75 @@ async function handleSave(){
   <t-dialog
   <t-dialog
     v-model:visible="show"
     v-model:visible="show"
     attach="body"
     attach="body"
-    width="500px"
+    width="850px"
     header="转移分类(ETA社区分类)"
     header="转移分类(ETA社区分类)"
     closeOnOverlayClick
     closeOnOverlayClick
     destroyOnClose
     destroyOnClose
-    class="classify-edit-pop"
+    class="chart-move-pop"
   >
   >
-    
+    <div class="flex top-filter-wrap">
+      <t-select
+        v-model="selectClassify"
+        placeholder="图表分类"
+        style="max-width: 235px"
+      >
+        <t-option
+          v-for="item in props.classifyOpts"
+          :key="item.CollectClassifyId"
+          :label="item.ClassifyName"
+          :value="item.CollectClassifyId"
+        ></t-option>
+      </t-select>
+      <t-input placeholder="请输入图表名称" style="max-width: 600px">
+        <template #prefixIcon>
+          <SearchIcon />
+        </template>
+      </t-input>
+      <t-checkbox style="flex-shrink: 0" v-model="checkAll">全选</t-checkbox>
+    </div>
+    <t-table
+      row-key="ChartCollectId"
+      :data="tableData"
+      :columns="columns"
+      bordered
+      hover
+      max-height="500"
+      resizable
+      :selected-row-keys="selectedRowKeys"
+      :pagination="pagination"
+      @page-change="onPageChange"
+      @select-change="handleTableSelectChange"
+    >
+    </t-table>
+    <div class="flex" style="align-items:center;gap:0 10px">
+      <span>移动至新分类</span>
+      <t-select
+        v-model="newClassify"
+        placeholder="图表分类"
+        style="max-width: 235px"
+      >
+        <t-option
+          v-for="item in props.classifyOpts"
+          :key="item.CollectClassifyId"
+          :label="item.ClassifyName"
+          :value="item.CollectClassifyId"
+        ></t-option>
+      </t-select>
+    </div>
+    <template #footer>
+      <div class="bottom-btn" style="text-align: center">
+        <t-button theme="default" @click="show = false">取消</t-button>
+        <t-button type="submit" @click="handleSave">确认</t-button>
+      </div>
+    </template>
   </t-dialog>
   </t-dialog>
-</template>
+</template>
+
+<style lang="scss" scoped>
+.chart-move-pop {
+  .top-filter-wrap {
+    gap: 10px;
+    margin-bottom: 20px;
+  }
+}
+</style>

+ 75 - 10
src/views/user/favorite/etaChart.vue

@@ -1,6 +1,53 @@
 <script setup>
 <script setup>
 import {SearchIcon} from 'tdesign-icons-vue-next'
 import {SearchIcon} from 'tdesign-icons-vue-next'
 import ClassifyWrap from './components/ClassifyWrap.vue'
 import ClassifyWrap from './components/ClassifyWrap.vue'
+import {apiETAChartUser} from '@/api/etaChart'
+import ChartDetailPop from '@/views/etaChart/components/ChartDetailPop.vue'
+
+let classifyId=0
+const SysUserIds=ref([])
+const keyword=ref('')
+const chartList=ref([])
+const page=ref(1)
+const pageSize=ref(30)
+const total=ref(0)
+const finished=ref(false)
+async function getChartList(){
+  const res=await apiETAChartUser.chartCollectList({
+    CollectClassifyIds:classifyId,
+    SysUserIds:SysUserIds.value.join(','),
+    Keyword:keyword.value,
+    PageSize:pageSize.value,
+    CurrentIndex:page.value
+  })
+  if(res.Ret!==200) return
+  const arr=res.Data.List||[]
+  total.value=res.Data.Paging.Totals
+  finished.value=res.Data.Paging.IsEnd
+  chartList.value=arr
+}
+
+function onPageChange(){
+
+}
+function refreshList(){
+  page.value=1
+  chartList.value=[]
+  getChartList()
+}
+function handleClassifyChange(e){
+  classifyId=e
+  console.log('gafkdsf');
+  refreshList()
+}
+
+
+const showChartDetailPop=ref(false)
+const activeChartInfo=ref(null)
+function handleShowChartDetail(e){
+  activeChartInfo.value=e
+  showChartDetailPop.value=true
+}
 
 
 </script>
 </script>
 
 
@@ -11,36 +58,54 @@ import ClassifyWrap from './components/ClassifyWrap.vue'
         <span @click="$router.push('/etaChart/index')">研究图库 ></span>
         <span @click="$router.push('/etaChart/index')">研究图库 ></span>
         <span>我的收藏</span>
         <span>我的收藏</span>
       </div>
       </div>
-      <ClassifyWrap />
+      <ClassifyWrap @change="handleClassifyChange"/>
     </div>
     </div>
     <div class="flex right-wrap">
     <div class="flex right-wrap">
       <div class="flex top-filter">
       <div class="flex top-filter">
-        <select-chart-creator style="width:300px" size="large" />
-        <t-input placeholder="请输入图表名称" size="large" style="max-width:600px">
+        <select-chart-creator v-model="SysUserIds" @change="refreshList" style="width:300px" size="large" />
+        <t-input 
+          v-model="keyword" 
+          placeholder="请输入图表名称" 
+          size="large" 
+          style="max-width:600px"
+          clearable
+          @change="refreshList"
+        >
           <template #prefixIcon>
           <template #prefixIcon>
             <SearchIcon />
             <SearchIcon />
           </template>
           </template>
         </t-input>
         </t-input>
       </div>
       </div>
-      <div class="chart-list-wrap">
+      <empty-wrap v-if="finished&&chartList.length===0" />
+      <div class="chart-list-wrap" v-else>
         <ul class="flex chart-list">
         <ul class="flex chart-list">
-          <li class="bg-white chart-item" v-for="item in 30" :key="item">
+          <li class="bg-white chart-item" v-for="item in chartList" :key="item.ChartCollectId">
             <div class="flex chart-name">
             <div class="flex chart-name">
-              <div class="text-ellipsis--l1 name">图表名称</div>
+              <div class="text-ellipsis--l1 name">{{item.ChartName}}</div>
               <svg-icon name="star_fill" style="font-size:20px;cursor: pointer;"></svg-icon>
               <svg-icon name="star_fill" style="font-size:20px;cursor: pointer;"></svg-icon>
-              <svg-icon name="full_screen" style="font-size:20px;margin-left:20px;cursor: pointer;"></svg-icon>
+              <svg-icon name="full_screen" style="font-size:20px;margin-left:20px;cursor: pointer;" @click="handleShowChartDetail(item)"></svg-icon>
             </div>
             </div>
-            <img class="chart-img" src="" alt="">
+            <img class="chart-img" :src="item.ChartImage" alt="">
             <div class="time">
             <div class="time">
               <span>收藏时间:</span>
               <span>收藏时间:</span>
-              <span>{{formatTime(new Date(),'YYYY-MM-DD HH:mm:ss')}}</span>
+              <span>{{formatTime(item.CollectTime,'YYYY-MM-DD HH:mm:ss')}}</span>
             </div>
             </div>
           </li>
           </li>
         </ul>
         </ul>
-
+        <t-pagination
+          v-model="page"
+          :pageSize="pageSize"
+          :total="total"
+          :totalContent="false"
+          :showPageSize="false"
+          @current-change="onPageChange"
+        />
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
+
+  <!-- 图表详情弹窗 -->
+  <ChartDetailPop v-model:show="showChartDetailPop" :chartInfoId="activeChartInfo?.ChartInfoId"/>
 </template>
 </template>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>