Pārlūkot izejas kodu

添加赢单申请审核弹窗

lm 4 dienas atpakaļ
vecāks
revīzija
f02bb53c9c

+ 130 - 0
src/baseComponents/PreviewDialog.vue

@@ -0,0 +1,130 @@
+<template>
+<div class="page_dialog">
+    <!-- v-model="previewVisible" -->
+    <!-- append-to-body -->
+    <!-- style="max-height: 90vh;overflow: auto;max-width: 900px;" -->
+    <el-dialog
+        @close="HandleDialogClose"
+        class="preview_dialog el_button"
+        :model-value="props.previewVisible"
+        :width="dialogWidth ? dialogWidth : '80%'"
+        :title="props.title || '附件预览'"
+        :align-center="true"
+    >
+        <div class="custom">
+            <!-- 内部 class="preview_introduce" -->
+            <slot></slot>
+        </div>
+      
+        <template v-if="props.customFooter" #footer>
+            <slot name="close">
+                <el-button @click="HandleDialogClose" class="button_border_gray cancel" >取 消</el-button>
+            </slot>
+            <slot name="footer"></slot>
+            <slot name="confirm">
+                <el-button :disabled="props.disabledConfirm" :loading="props.submitLoading"  @click="props.disabledConfirm ? '' : HandleConfirmCheck()" class="button_background"  >确 定</el-button>
+            </slot>
+        </template>
+    </el-dialog>
+</div>
+</template> 
+
+<script setup lang="ts">
+const props = defineProps({
+    title:{
+        type:String
+    },
+    customFooter:{
+        type:Boolean,
+        required:false
+    },
+    previewVisible:{
+        type:Boolean,
+        required:true
+    },
+    submitLoading:{
+      type:Boolean,
+      default:false,
+    },
+    disabledConfirm:{
+        type:Boolean,
+        default:false
+    },
+    dialogWidth:{
+        type:String,
+    }
+})
+
+const emit = defineEmits(['close','confirm'])
+
+
+const HandleDialogClose = ()=>{
+    emit('close')
+    console.log('弹窗关闭===')
+    // previewVisible.value = false
+}
+
+const HandleConfirmCheck = async () => {
+    emit('confirm')
+}
+
+</script>
+
+
+<style lang="scss" scoped>
+.preview_dialog{
+    overflow: auto;
+    border-radius: 8px;
+    padding: 0;
+}
+:deep(.el-dialog__header) {
+    width: 100%;
+    height: 48px;
+    line-height: 48px;
+    text-indent: 20px;
+    background-color: #f5f7fa;
+    border-bottom: 1px solid #f5f7fa;
+    border-top-right-radius: 8px;
+    border-top-left-radius: 8px;
+    padding: 0 !important;
+    text-align: left;
+    .el-dialog__title {
+    font-weight: 600;
+    font-size: 16px;
+    color: #303133;
+    }
+    button:focus, button:focus-visible {
+    outline: none;
+    }
+}
+//饿了么内容样式覆盖
+:deep(.el-dialog__body) {
+    overflow: auto;
+    font-weight: 400;
+    font-size: 16px;
+    color: #333;
+    padding: 20px;
+    width: 100%;
+    margin: auto;
+
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-start;
+    max-height: calc(90vh - 50px - 66px);
+    
+    .custom{
+        .preview_introduce{
+            background-color: #fafafa;
+            border: solid #e9e9e9 1px !important;
+            padding:10px;
+            margin-bottom: 10px;
+            border-radius: 8px;
+            display: flex;
+            flex-direction: row;
+            justify-content: flex-start;
+            align-items: flex-start;
+        }
+    }
+}
+
+</style>

+ 249 - 9
src/views/customerFollowUp/index.vue

@@ -4,10 +4,11 @@
             <div class="page_search">
                 <div class="search_content">
                     <div class="content_left">
-                        <SearchBlock :searchList="searchList" >
+                        <SearchBlock :searchList="searchList"  @searchChange="HandleBlockSearchChange">
                             <template #rowItem-time>
                                 <el-date-picker
-                                    style="height: 28px;flex-grow: 0;"
+                                    v-if="searchParams.time == 'custom'"
+                                    style="height: 28px;flex-grow: 0;width: 225px;"
                                     v-model="startAndEndTime"
                                     type="daterange"
                                     range-separator="至"
@@ -19,7 +20,10 @@
                         </SearchBlock>
                     </div>
                     <div class="content_right">
-                        <el-button class="delete_button_border_no_bg">赢单申请</el-button>
+                        <el-button class="delete_button_border_no_bg" @click="OpenAuditDialog">
+                            赢单申请
+                            <span class="bubble">{{ winnerOrderNum }}</span>
+                        </el-button>
                         <el-button class="button_border">操作日志</el-button>
                     </div>
                 </div>
@@ -33,7 +37,7 @@
                     defaultValue:'',
                     disabled:false
                 }
-            ]"/>
+            ]" @searchChange="HandleBlurSearchChange"/>
             <Table :currentPage="currentPage" :pageSize="pageSize" :totalNum="totalNum" 
                 :tableColumns="tableColumns" :tableData="tableData">
                 <template #num="{currentIndex}">
@@ -52,21 +56,77 @@
             </Table>
 
         </div>
+
+        <PreviewDialog 
+            dialogWidth="1000px"
+            class="audit_dialog"
+            :previewVisible="auditDialogVisible"  
+            title="审核申请" 
+            :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>
+
+
+            <template #close>
+                <el-button @click="CloseAuditDialog" class="button_background" >关闭</el-button>
+            </template>
+            <template #confirm><i></i></template>
+        </PreviewDialog>
+
     </div>
 </template>
 
 
 <script setup lang="ts">
-import { ref } from 'vue';
+import { computed, ref } from 'vue';
 import SearchBlock from '@/baseComponents/SearchBlock.vue';
 import {searchList} from './searchBlock'
 import Table from '@/baseComponents/Table.vue';
 import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
 
+import PreviewDialog from '@/baseComponents/PreviewDialog.vue';
 import {tableColumns} from './table'
+import TabSearch from '@/baseComponents/TabSearch.vue';
 
-
-// 表格数据有关内容
+/**
+ * 1. 表格数据有关内容
+ */
 const tableData = ref([
     {
         id: 1,
@@ -123,12 +183,98 @@ const pageSize = ref(20)
 const totalNum = ref(0)
 
 
-
-// 筛选项有关数据
+/**
+ * 2.筛选项有关数据
+ */
 const startAndEndTime = ref()
 const searchParams = ref({})
+const HandleBlockSearchChange = (params,key)=>{
+    searchParams.value = {
+        ...searchParams.value,
+        ...params
+    }
+}
+const HandleBlurSearchChange = (params,key)=>{
+    // console.log('blurl--',params)
+    searchParams.value = {
+        ...searchParams.value,
+        ...params
+    }
+}
 
+/**
+ * 3. 赢单申请有关数据
+ */
+const winnerOrderNum = ref(5)
 
+// 审核弹窗数据
+const auditDialogVisible = ref(false)
+const defaultAuditStatus = ref(0)
+
+const waitAuditNum = ref(0)
+const auditPassNum = ref(0)
+const auditRejectNum = ref(0)
+const tabList = computed(()=>[
+    {
+        label:'待审核',
+        key:0,
+        suffix:waitAuditNum.value,
+    },
+    {
+        label:'已通过',
+        key:1,
+        suffix:auditPassNum.value,
+    },
+    {
+        label:'已驳回',
+        key:2,
+        suffix:auditRejectNum.value,
+    },
+
+])
+
+const auditList = ref([
+    {
+        id:'1',
+        followUpTime: '26-02-19 19:00',
+        schoolName: '北京师达学校',
+        followUpProduct: '大数据精准教学',
+        followUpStatus: '赢单',
+        followUpUser: '张三',
+        contactPerson: '严谨',
+        jobTitle: '校长',
+        followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文'
+    },
+    {
+        id:'2',
+        followUpTime: '26-02-19 19:00',
+        schoolName: '北京师达学校',
+        followUpProduct: '大数据精准教学',
+        followUpStatus: '赢单',
+        followUpUser: '张三',
+        contactPerson: '严谨',
+        jobTitle: '校长',
+        followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京\n文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号'
+    },
+     {
+        id:'3',
+        followUpTime: '26-02-19 19:00',
+        schoolName: '北京师达学校',
+        followUpProduct: '大数据精准教学',
+        followUpStatus: '赢单',
+        followUpUser: '张三',
+        contactPerson: '严谨',
+        jobTitle: '校长',
+        followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京\n文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号'
+    }
+])
+
+const OpenAuditDialog = ()=>{
+    auditDialogVisible.value = true
+}
+const CloseAuditDialog = ()=>{
+    auditDialogVisible.value = false
+}
 </script>
 
 
@@ -140,7 +286,101 @@ const searchParams = ref({})
 .content_right{
     align-self: flex-start;
     flex-wrap: wrap;
+    gap:20px !important;
 
+    .delete_button_border_no_bg{
+        position: relative;
+        .bubble{
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            position: absolute;
+            top:-10px;
+            right: -10px;
+            width: 20px;
+            height: 20px;
+            font-size: 12px;
+            background: #F56C6C;
+            border-radius: 50%;
+            color: white;
+        }
+    }
 }
 
+
+.audit_dialog{
+    :deep(.el-dialog__body){
+        max-height: 500px;
+        min-height: 500px;
+    }
+
+}
+.audit_list_container {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    margin-top: 16px;
+
+    .audit_card {
+        border-radius: 8px 8px 8px 8px;
+        border: 1px solid #EBEEF5;
+        padding: 12px 16px;
+        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-size: 14px;
+                font-weight: 600;
+                color: #333333;
+
+                .status_tag {
+                    padding:4px 8px;
+                    font-weight: 400;
+                    font-size: 12px;
+                    background: rgba(46,100,250,0.1);
+                    border-radius: 4px 4px 4px 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;
+        }
+    }
+}
+
+
+
 </style>

+ 1 - 1
src/views/customerFollowUp/searchBlock.ts

@@ -1,6 +1,6 @@
 import { ref } from "vue";
 
-export const searchList = ref<SearchBlockItem[]>([
+export const searchList = ref([
     {
         label: '时间',
         key: 'time',

+ 1 - 1
src/views/userPrivilegeManagement/permissionManage/table.ts

@@ -28,7 +28,7 @@ export const userTableColumns = ref([
 export const tableColumns = ref([
     {
         name: 'region', // 对应“项目组”列,通常作为行头
-        label: '项目组',
+        label: '项目组(分组名称)',
         width: '80',
         fixed: 'left', // 建议固定首列,防止横向滚动时看不清区域
         align: 'center',