瀏覽代碼

fix: 拜访日历

B1 4 月之前
父節點
當前提交
aef097c1f9

+ 8 - 0
src/api/customer-manage/index.js

@@ -12,3 +12,11 @@ export const fetchCustomerHeaderInfo = (id) => {
     method: 'get',
   });
 };
+
+export const fetchVisitCalendar = (params) => {
+  return request({
+    url: `/supports/xxxxxxxx`,
+    method: 'get',
+    params,
+  });
+};

文件差異過大導致無法顯示
+ 1 - 0
src/assets/images/customer-manage/company.svg


文件差異過大導致無法顯示
+ 19 - 0
src/assets/images/customer-manage/gold-s.svg


+ 141 - 0
src/views/customer-manage/visit-calendar/components/calendarDetail/index.vue

@@ -0,0 +1,141 @@
+<template>
+  <div class="detail-container">
+    <div class="detail-empty" v-if="!calendarDetail.length">
+      <a-empty :image="simpleImage" />
+    </div>
+    <a-timeline v-else>
+      <a-timeline-item>
+        <div class="timeline-item-container">
+          <div class="item-header">
+            <span>2025-05-12 周三 10:30</span>
+            <span>提前提醒:<span class="high-light">2</span>天</span>
+          </div>
+          <a-card :bodyStyle="{ padding: '10px' }">
+            <div class="card-container">
+              <div class="card-title">拜访计划的标题信息拜访计划的标题信息,拜访计划的标题信息拜访计划的标题信息</div>
+              <div class="card-company">
+                <img :src="companyIcon" />
+                <span class="company-name">中国大唐集团有限公司</span>
+                <div class="company-tag-1-container">
+                  <img class="tag1-icon" :src="goldsIcon" />
+                  <div class="company-tag-1">S级客户</div>
+                </div>
+                <div class="company-tag-2">业主单位</div>
+              </div>
+              <div class="card-desc">
+                <span>项目:</span>
+                <span>项目名称信息展示位置在这里</span>
+              </div>
+              <div class="card-desc">
+                <span>目的:</span>
+                <span>拜访目的信息展示位置在这里显示,很长的话就折行显示</span>
+              </div>
+              <div class="card-desc">
+                <span>地址:</span>
+                <span>省市区+具体地址信息显示在这里</span>
+              </div>
+              <div class="card-desc">
+                <span>责任人:</span>
+                <span>刘嘉嘉</span>
+              </div>
+            </div>
+            <template #actions>
+              <div @click="">取消日程</div>
+              <div @click="" :style="{ color: token.colorPrimary }">日程完成</div>
+            </template>
+          </a-card>
+        </div>
+      </a-timeline-item>
+      <a-timeline-item color="gray">Solve initial network problems 2015-09-01</a-timeline-item>
+    </a-timeline>
+    {{ type }}
+  </div>
+</template>
+<script setup>
+  import { Empty, theme, message } from 'ant-design-vue';
+  import companyIcon from '/@/assets/images/customer-manage/company.svg';
+  import goldsIcon from '/@/assets/images/customer-manage/gold-s.svg';
+
+  const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
+  const { useToken } = theme;
+  const { token } = useToken();
+
+  const props = defineProps({
+    type: {
+      required: true,
+      default: 0,
+    },
+    calendarDetail: {
+      required: true,
+      default: [{}],
+    },
+  });
+</script>
+<style lang="scss" scoped>
+  .detail-container {
+    height: 100%;
+    padding: 4px;
+    .detail-empty {
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .timeline-item-container {
+      display: flex;
+      flex-direction: column;
+      .item-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .high-light {
+          color: v-bind('token.colorPrimary');
+        }
+      }
+      .card-container {
+        display: flex;
+        flex-direction: column;
+        gap: 6px;
+        .card-title {
+          font-size: 14px;
+          font-weight: bold;
+        }
+        .card-company {
+          display: flex;
+          align-items: center;
+          gap: 4px;
+          .company-name {
+            font-weight: 500;
+          }
+          .company-tag-1,
+          .company-tag-2 {
+            font-size: 10px;
+            padding: 2px 8px;
+            border-radius: 4px;
+          }
+          .company-tag-1-container {
+            position: relative;
+            padding-left: 25px;
+            .tag1-icon {
+              position: absolute;
+              top: 50%;
+              left: 9px;
+              transform: translateY(-50%);
+            }
+          }
+          .company-tag-1 {
+            color: #ce7700;
+            background-color: #ffe7cb;
+          }
+          .company-tag-2 {
+            color: #378eff;
+            background-color: #ddefff;
+          }
+        }
+        .card-desc {
+          color: #535c74;
+        }
+      }
+    }
+  }
+</style>

+ 1 - 1
src/views/customer-manage/visit-calendar/components/stateTabs/index.vue

@@ -6,7 +6,7 @@
   </div>
 </template>
 
-<script setup lang="ts">
+<script setup>
   import { theme, message } from 'ant-design-vue';
 
   const { useToken } = theme;

+ 123 - 28
src/views/customer-manage/visit-calendar/index.vue

@@ -1,7 +1,41 @@
 <template>
   <div class="page">
     <div class="page-left">
-      <a-calendar v-model:value="calendarValue">
+      <div class="search-bar">
+        <a-form :model="queryForm" @finish="searchData" layout="inline" autocomplete="off" :colon="false">
+          <a-form-item label="营销团队范围">
+            <a-select style="width: 180px" v-model:value="queryForm.teamScope" placeholder="请选择营销团队范围">
+              <a-select-option :value="1">范围1</a-select-option>
+              <a-select-option :value="2">范围2</a-select-option>
+            </a-select>
+          </a-form-item>
+          <a-form-item label="营销经理">
+            <a-select style="width: 180px" v-model:value="queryForm.manager" placeholder="请选择营销经理">
+              <a-select-option :value="1">经理1</a-select-option>
+              <a-select-option :value="2">经理2</a-select-option>
+            </a-select>
+          </a-form-item>
+          <a-form-item>
+            <a-button type="primary" html-type="submit">查询</a-button>
+            <a-button style="margin-left: 10px" @click="resetForm">重置</a-button>
+          </a-form-item>
+        </a-form>
+      </div>
+      <a-calendar v-model:value="queryForm.date" @change="handleCalendarChange" valueFormat="YYYY-MM-DD">
+        <template #headerRender="{ value }">
+          <div class="calendar-header">
+            <div class="header-date">{{ dayjs(value).format('YYYY-MM') }}</div>
+            <a-space-compact>
+              <a-button type="primary" @click="handleSwitchDate('PREV')" ghost>
+                <LeftOutlined />
+              </a-button>
+              <a-button type="primary" @click="handleSwitchDate('TODAY')">今天</a-button>
+              <a-button type="primary" @click="handleSwitchDate('NEXT')" ghost>
+                <RightOutlined />
+              </a-button>
+            </a-space-compact>
+          </div>
+        </template>
         <template #dateCellRender="{ current }">
           <div class="events" v-if="getListData(current).total > 0">
             <div class="events-total">共计{{ getListData(current).total }}项任务</div>
@@ -17,46 +51,59 @@
             </div>
           </div>
         </template>
-        <template #monthCellRender="{ current }">
-          <div v-if="getMonthData(current)" class="notes-month">
-            <!-- <section>{{ getMonthData(current) }}</section>
-            <span>Backlog number</span> -->
-          </div>
-        </template>
       </a-calendar>
     </div>
     <div class="page-right">
       <div class="line-1">
         <a-input-search v-model:value="searchValue" placeholder="请输入日程内容" enter-button="搜索" @search="onSearch" />
-        <a-button type="primary" ghost>添加日程</a-button>
+        <a-button :icon="h(PlusSquareOutlined)" type="primary">创建计划</a-button>
       </div>
       <div class="line-2">
         <StateTabs v-model:value="taskState" :options="taskOptions" />
       </div>
       <div class="line-content">
-        <template v-if="taskState === 0">
-          <div>待完成</div>
-        </template>
-        <template v-if="taskState === 1">
-          <div>已完成</div>
-        </template>
+        <CalendarDetail :type="taskState" :data="calendarDetail" />
       </div>
     </div>
   </div>
 </template>
-<script lang="ts" setup>
-  import { ref, reactive } from 'vue';
-  import { Dayjs } from 'dayjs';
-  import StateTabs from './components/stateTabs/index.vue';
+<script setup>
+  import dayjs from 'dayjs';
+  import { ref, reactive, h, onMounted, watch } from 'vue';
   import { theme, message } from 'ant-design-vue';
+  import { PlusSquareOutlined } from '@ant-design/icons-vue';
+
+  import { fetchVisitCalendar } from '/@/api/customer-manage/index.js';
+  import StateTabs from './components/stateTabs/index.vue';
+  import CalendarDetail from './components/calendarDetail/index.vue';
 
   const { useToken } = theme;
   const { token } = useToken();
 
+  const queryForm = reactive({
+    teamScope: undefined,
+    manager: undefined,
+    date: dayjs().format('YYYY-MM-DD'),
+  });
+
+  function fetchVisitCalendarData() {
+    console.log('fetchVisitCalendarData', queryForm);
+    // fetchVisitCalendar(queryForm).then((res) => {});
+  }
+
+  onMounted(fetchVisitCalendarData);
+
+  watch(
+    () => ({ date: queryForm.date }),
+    () => {
+      fetchVisitCalendarData();
+    },
+    { deep: true }
+  );
+
   // left
-  const calendarValue = ref<Dayjs>('');
 
-  const getListData = (value: Dayjs) => {
+  const getListData = (value) => {
     let listData;
     switch (value.date()) {
       case 7:
@@ -96,37 +143,84 @@
     return listData ?? { total: 0, details: [] };
   };
 
-  const getMonthData = (value: Dayjs) => {
+  const getMonthData = (value) => {
     if (value.month() === 8) {
       return 1394;
     }
   };
+
+  function handleSwitchDate(type) {
+    switch (type) {
+      case 'PREV':
+        queryForm.date = dayjs(queryForm.date).subtract(1, 'day').format('YYYY-MM-DD');
+        break;
+
+      case 'TODAY':
+        queryForm.date = dayjs().format('YYYY-MM-DD');
+        break;
+
+      case 'NEXT':
+        queryForm.date = dayjs(queryForm.date).add(1, 'day').format('YYYY-MM-DD');
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  function searchData() {
+    fetchVisitCalendarData();
+  }
+
+  function resetForm() {
+    queryForm.teamScope = undefined;
+    queryForm.manager = undefined;
+    fetchVisitCalendarData();
+  }
+
+  function handleCalendarChange(date) {
+    console.log('handleCalendarChange', date);
+  }
   // right
   // line-1
-  const searchValue = ref<string>('');
+  const searchValue = ref('');
 
-  const onSearch = (searchValue: string) => {
+  const onSearch = (searchValue) => {
     console.log('use searchValue', searchValue);
     console.log('or use this.searchValue', searchValue.value);
   };
   // line-2
-  const taskState = ref<number>(0);
-  const taskOptions = reactive<IKeyValue[]>([
+  const taskState = ref(0);
+  const taskOptions = reactive([
     { key: 0, label: '待完成', count: 0 },
     { key: 1, label: '已完成', count: 0 },
   ]);
+  // line-3
+  const calendarDetail = reactive([]);
 </script>
 <style lang="scss" scoped>
+  .search-bar {
+    margin-bottom: 14px;
+  }
+  .calendar-header {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    gap: 20px;
+    .header-date {
+      font-size: 16px;
+      font-weight: bold;
+    }
+  }
   .events {
     display: flex;
     flex-direction: column;
     gap: 4px;
     .events-total {
-      // v-bind('token.colorPrimary');
       display: flex;
       align-items: center;
-      justify-content: center;
-      padding: 4px 0 4px 4px;
+      padding: 4px 0 4px 6px;
       border-left: 2px solid v-bind('token.colorPrimary');
       border-top-right-radius: 6px;
       border-bottom-right-radius: 6px;
@@ -186,6 +280,7 @@
         gap: 8px;
       }
       .line-content {
+        flex: 1;
       }
     }
   }

部分文件因文件數量過多而無法顯示