3 次代码提交 59568f9829 ... f5b02739cf

作者 SHA1 备注 提交日期
  lm f5b02739cf 添加我的客户详情-联系人详情静态页面 4 天之前
  lm 058a449f7d 添加我的客户静态页面 4 天之前
  lm c0bc4b8df1 修改客户跟进页面交互 4 天之前

二进制
src/assets/icon/edit.png


+ 10 - 0
src/assets/icon/edit.svg

@@ -0,0 +1,10 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="/&#231;&#188;&#150;&#232;&#190;&#145;/16" clip-path="url(#clip0_15512_7134)">
+<path id="Vector" d="M3.33325 12H6.15992C6.24766 12.0005 6.33463 11.9837 6.41586 11.9505C6.49708 11.9173 6.57096 11.8685 6.63325 11.8067L11.2466 7.18667L13.1399 5.33333C13.2024 5.27136 13.252 5.19762 13.2858 5.11638C13.3197 5.03515 13.3371 4.94801 13.3371 4.86C13.3371 4.77199 13.3197 4.68486 13.2858 4.60362C13.252 4.52238 13.2024 4.44864 13.1399 4.38667L10.3133 1.52667C10.2513 1.46418 10.1775 1.41458 10.0963 1.38074C10.0151 1.34689 9.92793 1.32947 9.83992 1.32947C9.75191 1.32947 9.66477 1.34689 9.58353 1.38074C9.50229 1.41458 9.42856 1.46418 9.36658 1.52667L7.48658 3.41333L2.85992 8.03333C2.79813 8.09563 2.74925 8.16951 2.71607 8.25073C2.68289 8.33195 2.66608 8.41893 2.66659 8.50667V11.3333C2.66659 11.5101 2.73682 11.6797 2.86185 11.8047C2.98687 11.9298 3.15644 12 3.33325 12ZM9.83992 2.94L11.7266 4.82667L10.7799 5.77333L8.89325 3.88667L9.83992 2.94ZM3.99992 8.78L7.95325 4.82667L9.83992 6.71333L5.88658 10.6667H3.99992V8.78ZM13.9999 13.3333H1.99992C1.82311 13.3333 1.65354 13.4036 1.52851 13.5286C1.40349 13.6536 1.33325 13.8232 1.33325 14C1.33325 14.1768 1.40349 14.3464 1.52851 14.4714C1.65354 14.5964 1.82311 14.6667 1.99992 14.6667H13.9999C14.1767 14.6667 14.3463 14.5964 14.4713 14.4714C14.5963 14.3464 14.6666 14.1768 14.6666 14C14.6666 13.8232 14.5963 13.6536 14.4713 13.5286C14.3463 13.4036 14.1767 13.3333 13.9999 13.3333Z" fill="#666666"/>
+</g>
+<defs>
+<clipPath id="clip0_15512_7134">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

二进制
src/assets/icon/exchange.png


二进制
src/assets/icon/log.png


二进制
src/assets/icon/people_edit.png


二进制
src/assets/icon/people_move.png


+ 5 - 0
src/baseComponents/Dialog.vue

@@ -5,6 +5,7 @@
             v-model="props.visible" 
             :width="props.width ? props.width : '420px'"
             :close-on-click-modal="false"
+            :align-center="verticalCenter"
         >
             <div class="dialog_default">
                 <slot name="default" >
@@ -37,6 +38,10 @@
 import warnIcon from '@/assets/icon/warn.svg'
 const emit  = defineEmits(['close','confirm'])
 const props = defineProps({
+    verticalCenter:{
+        type:Boolean,
+        default:false
+    },
     visible:{
         type:Boolean,
         required:true

+ 5 - 4
src/baseComponents/FormDialog.vue

@@ -8,6 +8,7 @@
       :width="props.width || '480px'"
       :close-on-click-modal="false"
       class="el_button"
+      :align-center="verticalCenter"
     >
 
     <slot name="form_pre"></slot>
@@ -602,6 +603,10 @@ interface formItemProperty {
 }
 
 const props = defineProps({
+    verticalCenter:{
+      type:Boolean,
+      default:true
+    },
     width:{
       required:false,
     },
@@ -1149,10 +1154,6 @@ const HandleFilePreview = (params)=>{
   flex-grow: 0 !important;
   :deep(.el-dialog) {
     // margin: calc(min(50px,5vh)) auto calc(min(50px,5vh));
-    margin:0 !important;
-    top: 50% !important;
-    left: 50% !important; /* 若需水平居中可加上此行 */
-    transform: translate(-50%, -50%); /* 核心:基于自身宽高反向偏移 */
   }
   :deep(.el-dialog__body){
     // 后续会在不同页面动态变化

+ 44 - 0
src/baseComponents/TopBackNav.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="page_item top_header">
+        <div class="top_left">
+            <slot name="back">
+                <el-button class="button_default_background" @click="router.go(-1)">
+                    <el-icon class="img"><ArrowLeftBold /></el-icon>
+                    返回
+                </el-button>
+            </slot>
+        </div>
+        <div class="top_right">
+            <slot name="topRight"></slot>
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+
+const router = useRouter()
+
+</script>
+
+<style lang="scss" scoped>
+
+
+.top_header{
+    display: flex;
+    align-items: flex-start;
+    justify-content: flex-start;
+    gap:20px;
+    .top_left{
+        display: flex;
+        align-items: center;
+        gap:40px;
+        :deep(.button_default_background){
+            padding:8px 10px;
+            >span{
+                gap:4px;
+            }
+        }
+    }
+}
+</style>

+ 7 - 2
src/layout/index.vue

@@ -8,14 +8,19 @@
 <!-- vue3 setup -->
 <script setup lang="ts">
 import {computed,ref} from 'vue'
+import { useStore } from 'vuex'
+import { useRoute } from 'vue-router'
 import Header from './components/header.vue'
 import AppMain from './components/AppMain.vue'
 
-import { useStore } from 'vuex'
-
 const store = useStore()
+const route = useRoute()
+
 // 此处要根据登录用户的权限 分条件展示 不同的内容
 const menuList =  computed(()=>{
+  if(route.path.startsWith('/main/myCustomerDetail')){
+    return []
+  }
   return store.state.siderNav
 })
 

+ 5 - 0
src/router/index.ts

@@ -41,6 +41,11 @@ const routes: Array<RouteRecordRaw> = [
         name: 'myCustomer',   //我的客户
         component: () => import('../views/myCustomer/index.vue')
       },
+      {
+        path: 'myCustomerDetail',
+        name: 'myCustomerDetail',   //我的客户
+        component: () => import('../views/myCustomer/myCustomerDetail/index.vue')
+      },
       {
         path: 'customerFollowUp',
         name: 'customerFollowUp',   //客户跟进

+ 57 - 27
src/views/customerFollowUp/index.vue

@@ -145,29 +145,41 @@
 
 
             <!-- 日志列表 -->
-            <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>
+                <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>
-                    </div>
-
-                    <!-- 3. 底部跟进内容 -->
-                    <div class="card_content">
-                        操作内容:{{ item.operationContent }}
-                    </div>
-                </li>
-            </ul>
-
+                        <!-- 2. 底部内容 -->
+                        <div class="card_content">
+                            操作内容:{{ item.operationContent }}
+                        </div>
+                    </li>
+                </ul>
+
+                <div class="page_pagination">
+                    <span style="flex:1 1;color: #666666;font-size: 14px;">共 {{ logTotalNum  }} 条数据</span>
+                    <!-- background layout="sizes, prev, pager, next"  -->
+                    <el-pagination 
+                        :current-page="logCurrentPage" 
+                        :page-size="logPageSize" 
+                        :page-sizes="[20, 50, 100]" 
+                        background layout="sizes, prev, pager, next" 
+                        :total="Number(logTotalNum)" 
+                        @current-change="(val)=>HandleLogPaginaionChange({type:'currentPage',val})" 
+                        @size-change="(val)=>HandleLogPaginaionChange({type:'pageSize',val})" />
+                </div>
+            </div>
 
             <template #close>
                 <el-button @click="CloseOperationLogDialog" class="button_background" >关闭</el-button>
@@ -343,7 +355,6 @@ const CloseAuditDialog = ()=>{
 /**
  * 4. 操作日志有关数据
  */
-const operationLogDialogVisible = ref(false)
 const operationLogList = ref([
     {
         id:1,
@@ -387,7 +398,7 @@ const operationLogList = ref([
     }
 ]);
 
-//操作日志搜索项
+//操作日志搜索项 及操作
 const logSearchParams = ref({})
 const HandleLogBlockSearchChange = (params,key)=>{
     logSearchParams.value = {
@@ -400,8 +411,10 @@ const HandleLogBlurSearchChange = (params,key)=>{
         ...listSearchParams.value,
         ...params
     }
-}
+} 
 
+// 操作日志弹窗数据 及相关操作 
+const operationLogDialogVisible = ref(false)
 const OpenOperationLogDialog = ()=>{
     operationLogDialogVisible.value = true
 }
@@ -409,6 +422,21 @@ const CloseOperationLogDialog = ()=>{
     operationLogDialogVisible.value = false
 }
 
+// 日志分页有关数据 及操作
+const logCurrentPage = ref(1)
+const logPageSize = ref(20)
+const logTotalNum = ref(0)
+const HandleLogPaginaionChange = (params)=>{
+    const {type,val} = params
+    if(type == 'currentPage'){
+        // 处理页面跳转
+
+    }else if(type == 'pageSize'){
+        // 处理页容量
+    }
+}
+
+
 </script>
 
 
@@ -484,11 +512,12 @@ const CloseOperationLogDialog = ()=>{
                 color: #333333;
 
                 .status_tag {
-                    padding:4px 8px;
+                    height: 25px;
+                    padding:0 8px;
                     font-weight: 400;
                     font-size: 12px;
                     background: rgba(46,100,250,0.1);
-                    border-radius: 4px 4px 4px 4px;
+                    border-radius: 4px;
                     color: #2E64FA;
                 }
             }
@@ -528,6 +557,7 @@ const CloseOperationLogDialog = ()=>{
         }
     }
 }
+
 .log_list_container{
     .audit_card{
         padding:8px 12px;

+ 10 - 10
src/views/customerFollowUp/table.ts

@@ -6,7 +6,7 @@ export const tableColumns = ref([
         name: 'num',
         label: '序号',
         width: '60',
-        fixed: '',
+        fixed: 'left',
         align: 'center',
         minWidth: '',
         custom: true,
@@ -16,7 +16,7 @@ export const tableColumns = ref([
         name: 'customerType',
         label: '客户类型',
         width: '100',
-        fixed: '',
+        fixed: 'left',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -25,7 +25,7 @@ export const tableColumns = ref([
         name: 'schoolName',
         label: '学校名称',
         width: '150',
-        fixed: '',
+        fixed: 'left',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -34,7 +34,7 @@ export const tableColumns = ref([
         name: 'contactPerson',
         label: '联系人',
         width: '100',
-        fixed: '',
+        fixed: 'left',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -43,7 +43,7 @@ export const tableColumns = ref([
         name: 'jobTitle',
         label: '职务',
         width: '80',
-        fixed: '',
+        fixed: 'left',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -88,7 +88,7 @@ export const tableColumns = ref([
         name: 'followUpUser',
         label: '跟进人员',
         width: '100',
-        fixed: '',
+        fixed: 'right',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -97,7 +97,7 @@ export const tableColumns = ref([
         name: 'followUpProduct',
         label: '跟进产品',
         width: '120',
-        fixed: '',
+        fixed: 'right',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -106,7 +106,7 @@ export const tableColumns = ref([
         name: 'followUpStatus',
         label: '跟进状态',
         width: '100',
-        fixed: '',
+        fixed: 'right',
         align: 'center',
         minWidth: '',
         custom: false,
@@ -115,7 +115,7 @@ export const tableColumns = ref([
         name: 'followUpContent',
         label: '跟进内容',
         width: '200',
-        fixed: '',
+        fixed: 'right',
         align: 'left',
         minWidth: '', 
         custom: true,
@@ -124,7 +124,7 @@ export const tableColumns = ref([
         name: 'followUpTime',
         label: '跟进时间',
         width: '160',
-        fixed: '',
+        fixed: 'right',
         align: 'center',
         minWidth: '',
         custom: false,

+ 124 - 2
src/views/myCustomer/index.vue

@@ -1,15 +1,137 @@
 <template>
-    <div>
-        我的客户
+    <div class="main_container">
+        <div class="page_item end_item">
+            <div class="page_search">
+                <div class="search_content">
+                    <div class="content_left">
+                        <SearchBlock :searchList="headerSearchList"  @searchChange="HandleBlockSearchChange" />
+                    </div>
+                </div>
+            </div>
+            <FormSearchGroup :searchList="[
+                {
+                    key:'queryStr',
+                    type:'input',
+                    placeholder:'请输入关键字搜索',
+                    hidden:false,
+                    defaultValue:'',
+                    disabled:false
+                }
+            ]" @searchChange="HandleBlurSearchChange"/>
+
+
+            <Table :currentPage="currentPage" :pageSize="pageSize" :totalNum="totalNum" 
+                :tableColumns="tableColumns" :tableData="tableData">
+                <template #num="{currentIndex}">
+                    {{ (currentPage - 1) * pageSize + currentIndex }}
+                </template>
+                
+                <template #followUpContent="{row}">
+                    <span class="two_line_ellipsis">{{ row.followUpContent }}</span>
+                </template>
+
+                <template #operation="{row}">
+                    <div class="table_row_option">
+                        <span class="option_button_editor">编辑</span>
+                        <span class="option_button_editor" @click="GoToDetail(row)">详情</span>
+                    </div>
+                </template>
+            </Table>
+
+        </div>
     </div>
 </template>
 
 
 <script setup lang="ts">
+import { computed, ref } from 'vue';
+import { useRouter } from 'vue-router';
+import SearchBlock from '@/baseComponents/SearchBlock.vue';
+import {headerSearchList} from './searchBlock'
+import Table from '@/baseComponents/Table.vue';
+import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
+import {tableColumns} from './table'
+
+
+const router = useRouter()
+/**
+ * 1. 默认列表 表格数据有关内容
+ */
+const tableData = ref([
+    {
+        id: 1,
+        customerType: '首单客户',
+        schoolName: '流星花园学校',
+        educationStage: '中学',
+        provinceName: '北京市',
+        cityName: '西城区',
+        groupName: '小组',
+        owner: '张三',
+        claimTime: '2026-03-11',
+        lastFollowUpTime: '2026-03-11'
+    },
+    {
+        id: 2,
+        customerType: '首单客户',
+        schoolName: '北京师达',
+        educationStage: '中学',
+        provinceName: '北京市',
+        cityName: '西城区',
+        groupName: '小组',
+        owner: '张三',
+        claimTime: '2026-03-11',
+        lastFollowUpTime: '2026-03-11'
+    },
+    {
+        id: 3,
+        customerType: '首单客户',
+        schoolName: '北京五十七中学',
+        educationStage: '中学',
+        provinceName: '北京市',
+        cityName: '西城区',
+        groupName: '小组',
+        owner: '张三',
+        claimTime: '2025-11-01',
+        lastFollowUpTime: '2025-11-01'
+    }
+]);
+const currentPage = ref(1)
+const pageSize = ref(20)
+const totalNum = ref(0)
+
+
+/**
+ * 2.默认列表 筛选项有关数据
+ */
+const listSearchParams = ref({})
+const HandleBlockSearchChange = (params,key)=>{
+    listSearchParams.value = {
+        ...listSearchParams.value,
+        ...params
+    }
+}
+const HandleBlurSearchChange = (params,key)=>{
+    // console.log('blurl--',params)
+    listSearchParams.value = {
+        ...listSearchParams.value,
+        ...params
+    }
+}
+
+/**
+ * 3. 表格操作
+ */
+const GoToDetail = (row)=>{
+    router.push(`myCustomerDetail?id=${row.id}`)
+}
+
 
 </script>
 
 
 <style lang="scss" scoped>
+.end_item{
+    gap:16px;
+}
 
 </style>

+ 11 - 0
src/views/myCustomer/myCustomerDetail/contactDetail/formSearchGroup.ts

@@ -0,0 +1,11 @@
+import { ref } from 'vue';
+
+
+export const formSearchList = ref([
+    {
+        key:'queryStr',
+        type:'input',
+        placeholder:'请输入关键字搜索',
+        defaultValue:'',
+    },
+])

+ 92 - 0
src/views/myCustomer/myCustomerDetail/contactDetail/index.vue

@@ -0,0 +1,92 @@
+<template>
+    <div class="end_item">
+        <SearchBlock :searchList="blockSearchList" class="search_block">
+            <template #position>
+                <FormSearchGroup  :searchList="formSearchList" />
+            </template>
+        </SearchBlock>
+        <Table :currentPage="currentPage" 
+            :pageSize="pageSize" :totalNum="totalNum" 
+            :tableColumns="tableColumns" 
+            :tableData="tableData">
+            <template #num="{currentIndex}">
+                {{ (currentPage - 1) * pageSize + currentIndex }}
+            </template>
+            <template #operation="{row}">
+                <div class="table_row_option">
+                    <span class="option_button_editor">写跟进</span>
+                    <span class="option_button_editor">编辑</span>
+                    <span class="el_button_delete">删除</span>
+                </div>
+            </template>
+        </Table>
+    </div>
+</template>
+
+
+<script setup lang="ts">
+import { ref } from 'vue';
+
+import SearchBlock from '@/baseComponents/SearchBlock.vue';
+import {blockSearchList} from'./searchBlock'
+import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
+import {formSearchList} from './formSearchGroup'
+import Table from '@/baseComponents/Table.vue';
+import {tableColumns} from './table'
+
+
+
+const currentPage = ref(1)
+const pageSize = ref(20)
+const totalNum = ref(0)
+
+
+const tableData = ref([
+  {
+    id: '1',
+    name: '严谨',
+    jobTitle: '校长',
+    mobilePhone: '172****9908',
+    officePhone: '17287889908',
+    remark: '备注文案',
+    lastFollowUpTime: '26-08-19 19:00',
+    creator: '李四',
+    createTime: '26-08-19 17:00'
+  },
+  {
+    id: '2',
+    name: '王诗雅',
+    jobTitle: '校长',
+    mobilePhone: '172****9908',
+    officePhone: '-', // 图片中显示为横杠
+    remark: '备注文案',
+    lastFollowUpTime: '26-08-19 19:00',
+    creator: '李四',
+    createTime: '26-08-19 17:00'
+  },
+  {
+    id: '3',
+    name: '赵子涵',
+    jobTitle: '教学校长',
+    mobilePhone: '172****9908',
+    officePhone: '172****9908', // 图片中该号码也进行了脱敏处理
+    remark: '备注文案',
+    lastFollowUpTime: '26-08-19 19:00',
+    creator: '李四',
+    createTime: '26-08-19 17:00'
+  }
+]);
+</script>
+
+
+<style lang="scss" scoped>
+ .end_item{
+        :deep(.search_block){
+            margin-bottom: 16px;
+            .content_left{
+                align-items: center;
+            }
+        }
+    }
+
+</style>

+ 17 - 0
src/views/myCustomer/myCustomerDetail/contactDetail/searchBlock.ts

@@ -0,0 +1,17 @@
+import { ref } from 'vue';
+
+export const blockSearchList = ref([
+    {
+        label: '职务',
+        key: 'position',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '校长', value: 'schoolMaster' },
+            { label: '教学校长', value: 'principalOfTheSchool' },
+            { label: '教务主任', value: 'deanOfStudies' },
+            { label: '信息主任', value: 'informationDirector' },
+        ],
+        defaultValue: 'all'
+    }
+])

+ 85 - 0
src/views/myCustomer/myCustomerDetail/contactDetail/table.ts

@@ -0,0 +1,85 @@
+import { ref } from 'vue';
+
+export const tableColumns = ref([
+  {
+    name: 'num',
+    label: '序号',
+    width: '60',
+    align: 'center',
+    custom: true,
+    hidden: false
+  },
+  {
+    name: 'name',
+    label: '姓名',
+    width: '100',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'jobTitle',
+    label: '职务',
+    width: '120',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'mobilePhone',
+    label: '手机号',
+    width: '140',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'officePhone',
+    label: '办公电话',
+    width: '140',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'remark',
+    label: '备注',
+    width: '150', 
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'lastFollowUpTime',
+    label: '上次跟进时间',
+    width: '180',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'creator',
+    label: '创建人',
+    width: '100',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'createTime',
+    label: '创建时间',
+    width: '180',
+    align: 'center',
+    custom: false,
+    hidden: false
+  },
+  {
+    name: 'operation',
+    label: '操作',
+    width: '150',
+    fixed: 'right', 
+    align: 'center',
+    custom: true, 
+    hidden: false
+  }
+]);

+ 125 - 0
src/views/myCustomer/myCustomerDetail/index.vue

@@ -0,0 +1,125 @@
+<template>
+    <div class="main_container">
+        <TopBackNav>
+            <template #topRight>
+                <div class="header_content">
+                    <span>{{ customerBaseMsg.schoolName }}</span>
+                    <el-tag type="success" effect="light" size="small" class="status_tag">
+                        {{ customerBaseMsg.customerType }}
+                    </el-tag>
+                </div>
+                <div class="desc">
+                    <span>学段:{{ customerBaseMsg.educationStage }}</span>
+                    <span>省份:{{ customerBaseMsg.province }}</span>
+                    <span>地区:{{ customerBaseMsg.district }}</span>
+                    <span>地址:{{ customerBaseMsg.address }}</span>
+                    <span>归属人:{{ customerBaseMsg.owner }}</span>
+                    <span>认领时间:{{ customerBaseMsg.claimTime }}</span>
+                    <span>上次跟进时间:{{ customerBaseMsg.lastFollowUpTime }}</span>
+                </div>
+                <div class="action">
+                    <el-button class="button_background"><img :src="peopleEditIcon" alt=""> 写跟进</el-button>
+                    <el-button class="button_border"><img :src="addIcon" alt=""> 新增联系人</el-button>
+                    <el-button class="button_refresh"><img :src="editIcon" alt=""> 编辑</el-button>
+                    <el-button class="button_refresh"><img :src="poepleMoveIcon" alt=""> 转至公海</el-button>
+                    <el-button class="button_refresh"><img :src="exchangeIcon" alt=""> 转让</el-button>
+                    <el-button class="button_refresh"><img :src="logIcon" alt=""> 操作记录</el-button>
+                </div>
+            </template>
+        </TopBackNav>
+
+        <div class="page_item bottom_detail end_item">
+            <TabSearch :defaultTabKey="defaultShowTab" 
+                tabType="line" :tabList="tabList" 
+                @tabChange="HandleTabChange"
+                />
+            <div class="page_solid_line" />
+            <div class="page_jg_20"></div>
+            <ContactDetail v-if="defaultShowTab === 'contactDetails'"></ContactDetail>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import TopBackNav from '@/baseComponents/TopBackNav.vue';
+import addIcon from '@/assets/icon/add.svg';
+import peopleEditIcon from '@/assets/icon/people_edit.png'
+import poepleMoveIcon from '@/assets/icon/people_move.png'
+import editIcon from '@/assets/icon/edit.svg'
+import exchangeIcon from '@/assets/icon/exchange.png'
+import logIcon from '@/assets/icon/log.png'
+import TabSearch from '@/baseComponents/TabSearch.vue';
+import {tabList} from './tabSearch'
+import ContactDetail from './contactDetail/index.vue'
+
+const customerBaseMsg = ref({
+  schoolName: '北京市第一零九中学',
+  customerType: '首单客户',
+  educationStage: '九年一贯',
+  province: '北京',
+  district: '东城区',
+  address: '北京市东城区葱店西街56号',
+  owner: '张三',
+  claimTime: '2024-09-20',
+  lastFollowUpTime: '2025-03-12'
+});
+
+const defaultShowTab = ref('contactDetails')
+const HandleTabChange = (val)=>{
+    defaultShowTab.value = val
+}
+
+</script>
+
+
+
+<style lang="scss" scoped>
+.main_container{
+    gap:16px;
+
+    :deep(.top_right){
+        flex: 1 1;
+        .header_content{
+            display: flex;
+            align-items: center;
+            gap:10px;
+            font-weight: 600;
+            font-size: 20px;
+            color: #333333;
+            line-height: 28px;
+            .status_tag{
+                height: 25px;
+                border-radius: 4px ;
+                padding:0 8px;
+                font-weight: 400;
+                font-size: 12px;
+                color: #2E64FA;
+                background: rgba(46,100,250,0.1);
+            }
+        }
+        .desc{
+            display: flex;
+            gap:5px 16px;
+            flex-wrap: wrap;
+            font-size: 12px;
+            color: #999999;
+            margin-top: 8px;
+            margin-bottom: 16px;
+        }
+
+        .action{
+            display: flex;
+            gap:16px;
+            .el-button{
+                margin:0;
+                img{
+                    width: 16px;
+                    height: 16px;
+                    margin-right: 4px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 13 - 0
src/views/myCustomer/myCustomerDetail/tabSearch.ts

@@ -0,0 +1,13 @@
+import { ref } from 'vue';
+
+
+export const  tabList = ref([
+    {
+        label:'信息概览',
+        key:'messageOverview',
+    },
+    {
+        label:'联系人详情',
+        key:'contactDetails',
+    },
+])

+ 96 - 0
src/views/myCustomer/searchBlock.ts

@@ -0,0 +1,96 @@
+import { ref } from "vue";
+
+// 默认列表头部筛选配置
+export const headerSearchList = ref([
+    {
+        label: '类型',
+        key: 'type',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '首单客户', value: 'first_order' },
+            { label: '存量客户', value: 'existing_customer' },
+        ],
+        defaultValue: 'all'
+    },
+    {
+        label: '学段',
+        key: 'education_stage',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '幼儿园', value: 'kindergarten' },
+            { label: '小学', value: 'primary_school' },
+            { label: '初中', value: 'junior_high' },
+            { label: '高中', value: 'senior_high' },
+            { label: '完全中学', value: 'complete_middle' },
+            { label: '九年一贯', value: 'nine_year' },
+            { label: '十二年一贯', value: 'twelve_year' },
+            { label: '职高', value: 'vocational_high' },
+            { label: '大学', value: 'university' },
+        ],
+        defaultValue: 'all'
+    },
+    {
+        label: '省份',
+        key: 'province',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '北京', value: 'beijing' },
+            { label: '上海', value: 'shanghai' },
+            { label: '天津', value: 'tianjin' },
+            { label: '广东', value: 'guangdong' },
+            { label: '广西', value: 'guangxi' },
+        ],
+        defaultValue: 'all'
+    },
+    {
+        label: '地区',
+        key: 'region',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '东城区', value: 'dongcheng' },
+            { label: '西城区', value: 'xicheng' },
+            { label: '海淀区', value: 'haidian' },
+            { label: '朝阳区', value: 'chaoyang' },
+            { label: '丰台区', value: 'fengtai' },
+            { label: '石景山区', value: 'shijingshan' },
+        ],
+        defaultValue: 'all'
+    },
+    {
+        label: '分组',
+        key: 'group',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '分组1', value: 'group1' },
+            { label: '分组2', value: 'group2' },
+            { label: '分组3', value: 'group3' },
+            { label: '分组4', value: 'group4' },
+            { label: '分组5', value: 'group5' },
+            { label: '分组6', value: 'group6' },
+        ],
+        defaultValue: 'all'
+    },
+    {
+        label: '人员',
+        key: 'personnel',
+        type: 'single',
+        options: [
+            { label: '全部', value: 'all' },
+            { label: '马丁', value: 'martin' },
+            { label: '王诗雅', value: 'wangshiya' },
+            { label: '王梓木', value: 'wangzimu' },
+            { label: '殷思源', value: 'yinsiyuan' },
+            { label: '付文杰', value: 'fuwenjie' },
+            { label: '李润曦', value: 'lirunxi' },
+        ],
+        defaultValue: 'all'
+    },
+]);
+
+
+

+ 106 - 0
src/views/myCustomer/table.ts

@@ -0,0 +1,106 @@
+import { ref } from "vue";
+
+
+export const tableColumns = ref([
+    {
+        name: 'num',
+        label: '序号',
+        width: '60',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'customerType',
+        label: '客户类型',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'schoolName',
+        label: '学校名称',
+        width: '150',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'educationStage',
+        label: '学段',
+        width: '80',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'provinceName',
+        label: '省份',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'cityName',
+        label: '城市',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'groupName',
+        label: '分组',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'owner',
+        label: '归属人',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+
+    {
+        name: 'claimTime',
+        label: '认领时间',
+        width: '160',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+
+    {
+        name: 'lastFollowUpTime',
+        label: '上次跟进时间',
+        width: '160',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'operation',
+        label: '操作',
+        width: '80',
+        fixed: 'right',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    }
+]);