Browse Source

提取跟进/日志卡片公共组件

lm 7 hours ago
parent
commit
3820c33e56
2 changed files with 187 additions and 131 deletions
  1. 139 0
      src/components/FollowCard.vue
  2. 48 131
      src/views/customerFollowUp/index.vue

+ 139 - 0
src/components/FollowCard.vue

@@ -0,0 +1,139 @@
+<template>
+    <ul class="audit_list_container">
+        <li 
+            v-for="(item, index) in auditList" 
+            :key="item.id"
+            class="audit_card"
+        >
+            <!-- 头部内容 -->
+            <div class="card_header">
+                <!-- 左侧基本信息 -->
+                <div class="header_left">
+                    <span v-for="(titleItm,index) in item.headerTitleList" :key="index">{{ titleItm }}</span>
+                    <template v-if="item.headerTags?.length > 0">
+                        <el-tag v-for="(tag,index) in item.headerTags" 
+                                :key="index" 
+                                type="success" effect="light" size="small" 
+                                class="status_tag">
+                            {{ tag }}
+                        </el-tag>
+                    </template>
+                    
+                </div>
+                <!-- 右侧操作信息 -->
+                <div class="header_right">
+                    <slot name="operation" :row="item">
+                        <el-button class="delete_button_border_no_bg">驳回赢单</el-button>
+                        <el-button class="button_border">通过赢单</el-button>
+                    </slot>
+                </div>
+            </div>
+            <!-- 2. 中部描述信息-->
+            <div v-if="item.middleDesc?.length > 0" class="card_info">
+                <span v-for="(desc,index) in item.middleDesc" :key="index">{{ desc }}</span>
+            </div>
+            <!-- 3. 底部内容 -->
+            <div class="card_content">
+                {{ item.bottomDesc }}
+            </div>
+        </li>
+    </ul>
+</template>
+
+<script setup lang="ts">
+
+interface AuditItm {
+    id:string | number,
+    headerTitleList:Array<string>,
+    headerTags:Array<string>,
+    middleDesc:Array<string>,
+    bottomDesc:string,
+}
+
+const props = defineProps({
+    auditList:{
+        type:Array<AuditItm>,
+        required:true
+    },
+})
+
+
+
+</script>
+
+
+<style lang="scss" scoped>
+.audit_list_container {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+
+    .audit_card {
+        border-radius: 8px 8px 8px 8px;
+        border: 1px solid #EBEEF5;
+        display: flex;
+        flex-direction: column;
+        gap:8px;
+
+        /* 顶部布局 */
+        .card_header{
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            gap:10px;
+
+            .header_left {
+                display: flex;
+                align-items: center;
+                gap:8px;
+                font-weight: 600;
+                color: #333333;
+
+                .status_tag {
+                    height: 25px;
+                    padding:0 8px;
+                    font-weight: 400;
+                    font-size: 12px;
+                    background: rgba(46,100,250,0.1);
+                    border-radius: 4px;
+                    color: #2E64FA;
+                }
+            }
+            .header_right{
+                display: flex;
+                gap:16px;
+                .el-button{
+                    margin:0 !important;
+                }
+            }
+        }
+
+        /* 中部布局 */
+        .card_info {
+            display: flex;
+            align-items: center;
+            gap:11px;
+            font-weight: 400;
+            font-size: 12px;
+            color: #333333;
+        }
+
+        /* 底部内容布局 */
+        .card_content {
+            font-weight: 400;
+            font-size: 12px;
+            color: #999999;
+        }
+    }
+}
+
+.audit_list_container{
+    .audit_card{
+        padding: 12px 16px;
+        .header_left {
+            font-size: 14px;
+        }
+    }
+}
+
+</style>

+ 48 - 131
src/views/customerFollowUp/index.vue

@@ -66,41 +66,9 @@
             :customFooter="true"
             @close="CloseAuditDialog">
             <TabSearch :tabList="tabList" :defaultTabKey="defaultAuditStatus" tab-type="box" />
-            <ul class="audit_list_container">
-                <li 
-                    v-for="(item, index) in auditList" 
-                    :key="item.id"
-                    class="audit_card"
-                >
-                    <!-- 1. 顶部信息栏:时间、学校、产品、状态标签 -->
-                    <div class="card_header">
-                        <div class="header_left">
-                            <span class="time_text">{{ item.followUpTime }}</span>
-                            <span class="school_name">{{ item.schoolName }}</span>
-                            <span class="product_name">{{ item.followUpProduct }}</span>
-                            <!-- 使用 el-tag 模拟“赢单”状态 -->
-                            <el-tag type="success" effect="light" size="small" class="status_tag">
-                                {{ item.followUpStatus }}
-                            </el-tag>
-                        </div>
-                        <div class="header_right">
-                            <el-button class="delete_button_border_no_bg">驳回赢单</el-button>
-                            <el-button class="button_border">通过赢单</el-button>
-                        </div>
-                    </div>
-
-                    <!-- 2. 中部人员信息:跟进人、联系人、职务 -->
-                    <div class="card_info">
-                        <span>跟进人:{{ item.followUpUser }}</span>
-                        <span>联系人:{{ item.contactPerson }}</span>
-                        <span>职务:{{ item.jobTitle }}</span>
-                    </div>
-                    <!-- 3. 底部跟进内容 -->
-                    <div class="card_content">
-                        跟进内容:{{ item.followUpContent }}
-                    </div>
-                </li>
-            </ul>
+            
+            <FollowCard  :auditList="finalAuditRenderData"></FollowCard>
+          
             <template #close>
                 <el-button @click="CloseAuditDialog" class="button_background" >关闭</el-button>
             </template>
@@ -146,26 +114,9 @@
 
             <!-- 日志列表 -->
             <div>
-                <ul class="log_list_container">
-                    <li 
-                        v-for="(item, index) in operationLogList" 
-                        :key="item.id"
-                        class="audit_card">
-                        <!-- 1. 顶部信息栏 -->
-                        <div class="card_header">
-                            <div class="header_left">
-                                <span class="time_text">{{ item.operationTime }}</span>
-                                <span class="school_name">{{ item.operatorName }}</span>
-                                <span class="school_name">{{ item.schoolName }}</span>
-                                <span class="product_name">{{ item.operationType }}</span>
-                            </div>
-                        </div>
-                        <!-- 2. 底部内容 -->
-                        <div class="card_content">
-                            操作内容:{{ item.operationContent }}
-                        </div>
-                    </li>
-                </ul>
+                <FollowCard class="log_list_container"  :auditList="finalOperationLogRenderData">
+                    <template #operation><i></i></template>
+                </FollowCard>
 
                 <div class="page_pagination">
                     <span style="flex:1 1;color: #666666;font-size: 14px;">共 {{ logTotalNum  }} 条数据</span>
@@ -203,6 +154,9 @@ import PreviewDialog from '@/baseComponents/PreviewDialog.vue';
 import {tableColumns} from './table'
 import TabSearch from '@/baseComponents/TabSearch.vue';
 
+import FollowCard from '@/components/FollowCard.vue';
+
+
 /**
  * 1. 默认列表 表格数据有关内容
  */
@@ -345,6 +299,28 @@ const auditList = ref([
     }
 ])
 
+const finalAuditRenderData = computed(()=>{
+    return auditList.value.map(item=>{
+        return {
+            headerTitleList:[
+                item.followUpTime,
+                item.schoolName,
+                item.followUpProduct
+            ],
+            headerTags:[
+                item.followUpStatus,
+            ],
+            middleDesc:[
+                `跟进人:${item.followUpUser}`,
+                `联系人:${item.contactPerson}`,
+                `职务:${item.jobTitle}`
+            ],
+            bottomDesc:`跟进内容:${item.followUpContent}`
+        }
+    })
+})
+
+
 const OpenAuditDialog = ()=>{
     auditDialogVisible.value = true
 }
@@ -398,6 +374,22 @@ const operationLogList = ref([
     }
 ]);
 
+const finalOperationLogRenderData = computed(()=>{
+    return operationLogList.value.map(item=>{
+        return {
+            headerTitleList:[
+                item.operationTime,
+                item.operatorName,
+                item.schoolName,
+                item.operationType
+            ],
+            headerTags:[],
+            middleDesc:[],
+            bottomDesc:`操作内容:${item.operationContent}`
+        }
+    })
+})
+
 //操作日志搜索项 及操作
 const logSearchParams = ref({})
 const HandleLogBlockSearchChange = (params,key)=>{
@@ -484,81 +476,7 @@ const HandleLogPaginaionChange = (params)=>{
     }
 }
 
-.log_list_container,
-.audit_list_container {
-    display: flex;
-    flex-direction: column;
-    gap: 16px;
-
-    .audit_card {
-        border-radius: 8px 8px 8px 8px;
-        border: 1px solid #EBEEF5;
-        display: flex;
-        flex-direction: column;
-        gap:8px;
-
-        /* 顶部布局 */
-        .card_header{
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            gap:10px;
-
-            .header_left {
-                display: flex;
-                align-items: center;
-                gap:8px;
-                font-weight: 600;
-                color: #333333;
-
-                .status_tag {
-                    height: 25px;
-                    padding:0 8px;
-                    font-weight: 400;
-                    font-size: 12px;
-                    background: rgba(46,100,250,0.1);
-                    border-radius: 4px;
-                    color: #2E64FA;
-                }
-            }
-            .header_right{
-                display: flex;
-                gap:16px;
-                .el-button{
-                    margin:0 !important;
-                }
-            }
-        }
-
-        /* 中部布局 */
-        .card_info {
-            display: flex;
-            align-items: center;
-            gap:11px;
-            font-weight: 400;
-            font-size: 12px;
-            color: #333333;
-        }
-
-        /* 底部内容布局 */
-        .card_content {
-            font-weight: 400;
-            font-size: 12px;
-            color: #999999;
-        }
-    }
-}
-
-.audit_list_container{
-    .audit_card{
-        padding: 12px 16px;
-        .header_left {
-            font-size: 14px;
-        }
-    }
-}
-
-.log_list_container{
+:deep(.log_list_container){
     .audit_card{
         padding:8px 12px;
         .header_left{
@@ -567,5 +485,4 @@ const HandleLogPaginaionChange = (params)=>{
     }
 }
 
-
 </style>