Forráskód Böngészése

添加预约登记模块接口调用

lm 1 hónapja
szülő
commit
46b4e9f626

+ 28 - 8
src/baseComponents/Calendar.vue

@@ -10,20 +10,35 @@
 
             <!-- 自定义日期单元格 -->
                 <template #date-cell="{ data}">
-                <!--  -->
-                <span class="has_things">
-                    {{ data.day.split('-').pop() }}
-                </span>
+                    <span  :class="[props?.dateStatus?.find(item=>item.day == data.day)?.hasToDo ? 'has_to_do' : '',
+                        formatTime(selectedCalendarTime).split(' ')[0]== data.day ? '' : 'not_default_select'
+                    ]" >
+                        {{ data.day.split('-').pop() }}
+                    </span>
             </template>
         </el-calendar>
     </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
+import { onMounted, ref } from 'vue';
 import preBtnIcon from '@/assets/clientManage/pre_btn.png'
 import nextBtnIcon from '@/assets/clientManage/next_btn.png'
 
+import {formatTime} from '@/utils/timeRangeGet'
+
+interface DateStatusItm {
+    day:string,
+    hasToDo:Boolean
+}
+
+const props = defineProps({
+    dateStatus:{  // 所传日期项的待办状态
+        type:Array<DateStatusItm>,
+        default:[]
+    }
+})
+
 
 // 日历信息
 const selectedCalendarTime = defineModel('selectedCalendarTime')
@@ -62,11 +77,14 @@ const selectDate = (val) => {
                 &.is-today{
                     color: #2E64FA;
                 }
-                &.prev .el-calendar-day span.has_things{
+
+                &.prev .el-calendar-day span.has_to_do,
+                &.next .el-calendar-day span.has_to_do{
                     &::after{
                         background-color: #a8abb2;
                     }
                 }
+
                 &.is-selected{
                     background-color: transparent;
                     .el-calendar-day{
@@ -77,12 +95,14 @@ const selectDate = (val) => {
                                 background-color: #2E64FA;
                             }
 
-                            &.has_things::after{
+                            &.has_to_do::after{
                                     background-color: #fff;
                             }
                         }
                     }
                 }
+
+
                 .el-calendar-day{
                     display: flex;
                     justify-content: center;
@@ -101,7 +121,7 @@ const selectDate = (val) => {
                         height: 40px;
                         border-radius: 50%;
 
-                        &.has_things{
+                        &.has_to_do{
                             position: relative;
                             &::after{
                                 position: absolute;

+ 0 - 6
src/views/appointmentAndTodo/appointmentRegister/formDialog.ts

@@ -52,12 +52,6 @@ export const appointmentFormItemList = ref([
         style: {  }
 
     },
-    {
-        key: 'todoTime',
-        label: '待办时间',
-        type: 'text',
-        style: { }
-    },
     {
         key: 'cancelReason',
         label: '取消原因',

+ 102 - 94
src/views/appointmentAndTodo/appointmentRegister/index.vue

@@ -1,12 +1,16 @@
+<!-- 预约登记 -->
 <template>
-    <div>
-        <SearchBlock :searchList="blockSearchList"></SearchBlock>
-            <div class="page_jg_20"></div>
+    <div class="appointment_register" >
+        <SearchBlock :searchList="blockSearchList" 
+            @searchChange="HandleSearchChange">
+        </SearchBlock>
+        <div class="page_jg_20" style="flex-shrink: 0;"></div>
 
+        <div style="overflow: auto;">
             <TimeNavLine v-for="(item,index) in appointmentList" 
                 :key="item.id" 
                 :navIcon="item.navIcon" 
-                :navTime="item.navTime" 
+                :navTime="item.orderDatetime" 
                 :timeDesc="item.timeDesc"
                 :timeDescClass="appointmentStatusToClass(item.timeDesc)"
                 :isFirst="index === 0"
@@ -15,62 +19,77 @@
                     <FollowCard :cardList="[{...(item.desc)}]">
                         <template #operation="{row}">
                             <div class="table_row_option">
-                                <span class="button_delete" @click="OpenCancelAppointmentDialog(row,item)">取消预约</span>
+                                <span v-if="item.orderStatus !== 2" class="button_delete" @click="OpenCancelAppointmentDialog(row,item)">取消预约</span>
                                 <span class="option_button_editor" @click="OpenAppointmentDialog(row,item)">查看详情</span>
                             </div>
                         </template>
 
                         <template #additional="{row}">
                             <div class="cancel_reason" v-if="item.timeDesc === '已取消'">
-                                <span>取消原因:{{ item.cancelReason }}  </span>
+                                <span>取消原因:{{ item.cancelRemark }}  </span>
                             </div>
                         </template>
 
                     </FollowCard>
                 </template>
             </TimeNavLine>
-      
-    <!-- 查看预约详情弹窗 -->
-    <FormDialog :defaultFormData="appointmentDefaultFormData" 
-            title="查看详情" :submitLoading="false" 
-            :formItemList="appointmentFormItemList" 
-            :visible="appointmentDialogVisible"
-            @close="CloseAppointmentDialog"
-            @confirm="CloseAppointmentDialog">
-    </FormDialog>
-
-    <!-- 取消预约弹窗 -->
-    <FormDialog 
-        class="cancel_appointment_dialog"
-        :defaultFormData="cancelAppointmentDefaultFormData"
-        title="取消预约" :submitLoading="false"
-        :formItemList="cancelAppointmentFormItemList"
-        :visible="cancelAppointmentDialogVisible"
-        @close="CloseCancelAppointmentDialog"
-        @confirm="HandleCancelAppointmentConfirm">
-        <template #form_pre>
-            <div class="desc">
-                {{ cancelAppointmentDefaultFormData.appointmentTime}} {{ cancelAppointmentDefaultFormData.school}}
-            </div>
-        </template>
-    </FormDialog>
+        </div>
+        
+        <!-- 查看预约详情弹窗 -->
+        <FormDialog :defaultFormData="appointmentDefaultFormData" 
+                title="查看详情" :submitLoading="false" 
+                :formItemList="appointmentFormItemList" 
+                :visible="appointmentDialogVisible"
+                @close="CloseAppointmentDialog"
+                @confirm="CloseAppointmentDialog">
+        </FormDialog>
+
+        <!-- 取消预约弹窗 -->
+        <FormDialog 
+            class="cancel_appointment_dialog"
+            :defaultFormData="cancelAppointmentDefaultFormData"
+            title="取消预约" :submitLoading="false"
+            :formItemList="cancelAppointmentFormItemList"
+            :visible="cancelAppointmentDialogVisible"
+            @close="CloseCancelAppointmentDialog"
+            @confirm="HandleCancelAppointmentConfirm">
+            <template #form_pre>
+                <div class="desc">
+                    {{ cancelAppointmentDefaultFormData.appointmentTime}} {{ cancelAppointmentDefaultFormData.school}}
+                </div>
+            </template>
+        </FormDialog>
 
     </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
 
 import SearchBlock from '@/baseComponents/SearchBlock.vue';
 import TimeNavLine from '@/baseComponents/TimeNavLine.vue';
 import FollowCard from '@/components/FollowCard.vue';
-import schoolIcon from '@/assets/clientManage/school.png'
 import FormDialog from '@/baseComponents/FormDialog.vue';
 import {appointmentFormItemList,cancelAppointmentFormItemList} from './formDialog'
 
 
 import {blockSearchList} from './searchBlock'
 
+const props = defineProps({
+    appointmentList:{
+        type:Array,
+        required:true
+    },
+    followerList:{
+        type:Array
+    },
+    orderStatusList:{
+        type:Array
+    },
+})
+
+const emit = defineEmits(['searchChange'])
+
 
 const appointmentStatusToClass =  (status)=>{
     switch(status){
@@ -83,65 +102,18 @@ const appointmentStatusToClass =  (status)=>{
     }
 }
 
-const appointmentList = ref([
-    {
-        id:1,
-        navTime: '14:00',
-        navIcon:schoolIcon,
-        timeDesc: '待开始',
-        navTitle:'北京市第一中学',
-        cancelReason:'',
-
-
-        desc:{
-            id:1,
-            headerTitleList:['北京市区第一中学'],
-            headerTags:[],
-            taskType:'',
-            middleDesc:['跟进人员:张三','角色:校长','联系人:王德态'],
-            bottomDesc:'跟进内容:9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT',
+// 筛选项触发的变化
+const HandleSearchChange = (params,key)=>{
+    blockSearchList.value = blockSearchList.value.map(item=>{
+        switch(item.key){
+            case key:
+                item.defaultValue = params[key]
+                break
         }
-        
-    },
-    {
-        id:2,
-        navTime: '14:00',
-        navIcon:schoolIcon,
-        timeDesc: '已取消',
-        navTitle:'北京市第一中学',
-        cancelReason:'时间冲突',
-        desc:{
-            id:1,
-            headerTitleList:['北京市区第一中学'],
-            headerTags:[],
-            taskType:'',
-            productType:'大数据诊断平台',
-            middleDesc:['跟进人员:张三','角色:校长','联系人:王德态'],
-            bottomDesc:'跟进内容:9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT',
-        }
-    },
-    {
-        id:2,
-        navTime: '14:00',
-        navIcon:schoolIcon,
-        timeDesc: '已结束',
-        navTitle:'北京市第一中学',
-        cancelReason:'时间冲突',
-        desc:{
-            id:1,
-            headerTitleList:['北京市区第一中学'],
-            headerTags:[],
-            taskType:'',
-            productType:'大数据诊断平台',
-            middleDesc:['跟进人员:张三','角色:校长','联系人:王德态'],
-            bottomDesc:'跟进内容:9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT9:50会议室,所有管理层一起参会,准备PPT',
-        }
-    },
-])
-
-
-
-
+        return item
+    })
+    emit('searchChange',params,key)
+}
 
 /**
  * 查看预约详情弹窗
@@ -159,8 +131,8 @@ const OpenAppointmentDialog = (row,navItm)=>{
         position:row.middleDesc[1].split(':')[1],
         content:row.bottomDesc.split(':')[1],
         appointmentType:'预约',
-        appointmentTime:navItm.navTime,
-        cancelReason:''
+        appointmentTime:navItm.orderDatetime,
+        cancelReason:navItm.cancelRemark,
     }
     appointmentDialogVisible.value = true
 }
@@ -179,7 +151,7 @@ const OpenCancelAppointmentDialog = (row,navItm)=>{
     cancelAppointmentDialogVisible.value = true
     cancelAppointmentDefaultFormData.value = {
         school:row.headerTitleList[0],
-        appointmentTime:navItm.navTime,
+        appointmentTime:navItm.orderDatetime,
         cancelReason:''
     }
 }
@@ -192,12 +164,48 @@ const HandleCancelAppointmentConfirm = (params)=>{
     CloseCancelAppointmentDialog()
 }
 
+watch(()=>props.followerList,(newVal)=>{
+    if(newVal){
+        blockSearchList.value = blockSearchList.value.map(item=>{
+            if(item.key == 'follower'){
+                item.options = [
+                    {label:'全部',value:'all'},
+                    ...newVal,
+                ]
+            }
+            return item
+        })
+    }
+})
+
+watch(()=>props.orderStatusList,(newVal)=>{
+    if(newVal){
+        blockSearchList.value = blockSearchList.value.map(item=>{
+            if(item.key == 'appointmentStatus'){
+                item.options = [
+                    {label:'全部',value:'all'},
+                    ...newVal,
+                ]
+            }
+            return item
+        })
+    }
+
+})
+
 </script>
 
 
 
 <style lang="scss" scoped>
 
+.appointment_register{
+    flex: 1 1;
+    overflow: auto;
+    display: flex;
+    flex-direction: column;
+}
+
 
 .time_nav_line{
     :deep(.follow_card){

+ 2 - 15
src/views/appointmentAndTodo/appointmentRegister/searchBlock.ts

@@ -6,26 +6,13 @@ export const blockSearchList = ref([
     key: 'follower',
     type: 'single', 
     defaultValue: 'all',
-    options: [
-      { label: '全部', value: 'all' },
-      { label: '章泽析', value: 'zhang_zexi' },
-      { label: '朱云', value: 'zhu_yun' },
-      { label: '陈思怡', value: 'chen_siyi' },
-      { label: '陈雅琪', value: 'chen_yaqi' },
-      { label: '付文杰', value: 'fu_wenjie' },
-      { label: '刘懂', value: 'liu_dong' }
-    ]
+    options: []
   },
   {
     label: '预约状态',
     key: 'appointmentStatus',
     type: 'single',
     defaultValue: 'all',
-    options: [
-      { label: '全部', value: 'all' },
-      { label: '待开始', value: 'pending' },
-      { label: '已结束', value: 'finished' },
-      { label: '已取消', value: 'cancelled' }
-    ]
+    options: []
   }
 ]);

+ 145 - 21
src/views/appointmentAndTodo/index.vue

@@ -1,33 +1,39 @@
 <template>
     <div class="main_container">
-        <div class="calendar" >
-            <Calendar v-model:selectedCalendarTime="selectedCalendarTime"></Calendar>
+
+        <!-- 日历——预约总览 -->
+        <div v-if="defaultTabType == 'appointment'"  class="calendar" >
+            <Calendar v-model:selectedCalendarTime="selectedCalendarTime" 
+                :dateStatus="dateStatus">
+            </Calendar>
+
+            <!-- {{ selectedCalendarTime }} -->
              <div class="calendar_desc"> 
                 <div class="calendar_desc_title">
-                    <span class="date_desc">7月预约</span>
-                    <span class="total_count">共20条</span>
+                    <span class="date_desc">{{dayjs().month() + 1}}月预约</span>
+                    <span class="total_count">共{{currentMonthAppointment.totalCount}}条</span>
                 </div>
                 <div class="calendar_desc_content">
                     <div class="active">
-                        <span class="num">10</span>
+                        <span class="num">{{ currentMonthAppointment.waitStart }}</span>
                         <span>待开始</span>
                     </div>
                     <div class="split_line"></div>
                     <div class="completed">
-                        <span class="num">10</span>
+                        <span class="num">{{ currentMonthAppointment.end }}</span>
                         <span>已结束</span>
                     </div>
                     <div class="split_line"></div>
                     <div class="cancelled">
-                        <span class="num">10</span>
+                        <span class="num">{{ currentMonthAppointment.cancel }}</span>
                         <span>已取消</span>
                     </div>
                 </div>
              </div>
         </div>
 
-        <div class="detail_content" style="flex:1 1">
-            <div class="page_item appointment_todo">
+        <div class="detail_content">
+            <div class="page_item appointment_todo" :style="defaultTabType === 'appointment' ? {flex:'1 1'} : {}">
                 <div class="page_search">
                     <div class="search_content">
                         <div class="content_left">
@@ -36,13 +42,17 @@
                                 :defaultTabKey="defaultTabType"
                                 @tabChange="HandleTypeChange">
                             </TabSearch>
-                            <FormSearchGroup v-if="defaultTabType === 'appointment'" :searchList="formSearchList" @searchChange=""></FormSearchGroup>
-                          
+                            <!-- 预约登记筛选条件 -->
+                            <FormSearchGroup v-if="defaultTabType === 'appointment'" 
+                                :searchList="formSearchList" 
+                                @searchChange="HandleSearchChange">
+                            </FormSearchGroup>
                         </div>
-                        <div class="content_right" style="flex:1 1">
+
+                        <!-- 待办登记展示信息 -->
+                        <div  v-if="defaultTabType === 'todo'" class="content_right" style="flex:1 1">
                             <!-- 日历导航 头-->
                             <CalendarDateSelectHeader 
-                                v-if="defaultTabType === 'todo'"
                                 v-model:currentYear="currentYear"
                                 v-model:currentMonth="currentMonth"
                             ></CalendarDateSelectHeader>
@@ -50,11 +60,18 @@
                     </div>
                 </div>
                 <!-- 预约登记 -->
-                <AppointmentRegister  style="margin-top: 16px" v-if="defaultTabType === 'appointment'"></AppointmentRegister>
+                <AppointmentRegister  
+                    v-if="defaultTabType === 'appointment'" 
+                    :appointmentList="appointmentList"
+                    :followerList="followerList"
+                    :orderStatusList="orderStatusList"
+                    @searchChange="HandleSearchChange">
+                </AppointmentRegister>
             </div>
 
             <!-- 待办登记 -->
-            <div class="page_item"  style="padding:10px" v-if="defaultTabType === 'todo'">
+            <div v-if="defaultTabType === 'todo'" 
+                class="page_item"  style="padding:10px">
                 <TodoRegister 
                     v-model:currentYear="currentYear"
                     v-model:currentMonth="currentMonth"
@@ -66,7 +83,10 @@
 
 
 <script setup lang="ts">
-import { ref, onMounted } from 'vue';
+import { ref, onMounted, watch } from 'vue';
+import dayjs from 'dayjs';
+
+
 import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
 import TabSearch from '@/baseComponents/TabSearch.vue';
 import {tabSearchList} from './tabSearch'
@@ -77,6 +97,10 @@ import AppointmentRegister from './appointmentRegister/index.vue'
 import TodoRegister from './toDoRegister/index.vue'
 import CalendarDateSelectHeader from '@/components/CalendarTodoList/CalendarDateSelectHeader.vue';
 
+import {formatTime} from '@/utils/timeRangeGet'
+import schoolIcon from '@/assets/clientManage/school.png'
+
+
 import {
     getToDoTaskApi,
     updateToDoTaskApi,
@@ -94,7 +118,7 @@ const HandleTypeChange = (val)=>{
 }
 
 // 当前选中的日历信息
-const selectedCalendarTime =ref()
+const selectedCalendarTime =ref(null)
 
 const currentYear = ref(new Date().getFullYear())
 const currentMonth = ref(new Date().getMonth() + 1 )
@@ -102,20 +126,115 @@ const currentMonth = ref(new Date().getMonth() + 1 )
 /**
  * 处理日期的选择
  */
+
+ const currentMonthAppointment = ref({
+    totalCount:0,
+    waitStart:0,
+    end:0,
+    cancel:0,
+
+ })
+ const dateStatus = ref([])  // 当月的日程状态
+ const appointmentList = ref([])
+ const followerList = ref([])
+ const orderStatusList = ref([])
+
+const searchParams = ref({
+    follower:'all',
+    appointmentStatus:'all',
+    queryStr:'',
+
+})
+const HandleSearchChange = async (params,key)=>{
+    searchParams.value = {
+        ...searchParams.value,
+        ...params
+    }
+    await GetAppointmentList()
+    
+}
 // 查询预约登记信息
 const GetAppointmentList = async ()=>{
     let params = {
-        "datetime": "",
-        "userId": '',
-        "orderStatus": '',
-        "queryStr": ""
+        datetime: formatTime(selectedCalendarTime.value).split(' ')[0],
+        userId: searchParams.value.follower == 'all' ? '' : searchParams.value.follower,
+        orderStatus: searchParams.value.appointmentStatus == 'all' ? '' : searchParams.value.appointmentStatus,
+        queryStr: searchParams.value.queryStr
     }
     let res = await getAppointmentListApi(params)
     if(res?.code == 200){
         // 待完善
+        const {selectData,dataList,dateList,status0Count, status1Count, status2Count, totalCount } = res?.data
+        currentMonthAppointment.value = {
+            totalCount:totalCount,
+            waitStart:status0Count,
+            end:status1Count,
+            cancel:status2Count
+        }
+
+        dateStatus.value = dateList.map(item=>{
+            return {
+                day:item.day,
+                hasToDo:item.status === 1 ? true : false  
+            }
+        })
+
+        appointmentList.value = dataList?.map(item=>{
+            return {
+                desc:{
+                    id:item.id,
+                    headerTitleList:[item.customerName],
+                    headerTags:[],
+                    taskType:'',
+                    productType:item.productName,
+                    middleDesc:[`跟进人员:${item.claimUserName}`,
+                                `角色:${item.positionName}`,
+                                `联系人:${item.customerPersonName}`,
+                                `地址:${item.address}`,
+                            ],
+                    bottomDesc:`跟进内容:${item.followContent}`,
+                },
+                ...item,
+                navIcon:schoolIcon,
+                timeDesc:appointmentStatusToName(item.orderStatus),
+                // id:item.id,
+                // navTime: item.orderDatetime,
+                // navTitle:item.customerName,
+                // cancelReason:item.cancelRemark, 
+            }
+        })
+
+        const {memberData,orderStatusData}  = selectData || {}
+        followerList.value = memberData?.map(item=>{
+            return {
+                label:item.username,
+                value:item.id
+            }
+        })
+        orderStatusList.value = orderStatusData?.map(item=>{
+            return {
+                label:item.name,
+                value:item.status
+            }
+        })
+    }
+}
+
+const appointmentStatusToName = (status)=>{
+    switch(status){
+        case 0:
+            return '待开始'
+        case 1:
+            return '已结束'
+        case 2:
+            return '已取消'
     }
 }
 
+watch(()=>selectedCalendarTime.value, async(newVal)=>{
+    await GetAppointmentList()
+})
+
 onMounted(async ()=>{
     await GetAppointmentList()
 })
@@ -196,9 +315,14 @@ onMounted(async ()=>{
         flex:1 1;
         display: flex;
         flex-direction: column;
+        overflow: auto;
         gap:10px;
         .appointment_todo{
+            overflow: auto;
             padding:16px;
+            display: flex;
+            flex-direction: column;
+            gap:16px;
         }
     }
 }