| | |
| | | <template> |
| | | <div :class="prefixCls" > |
| | | <div class="mb-20px"> |
| | | <div class="mb-10px flex justify-between flex-items-center"> |
| | | <div class="relative"> |
| | | <a-dropdown :trigger="['click']"> |
| | | <a-tooltip placement="top"> |
| | | <template #title> |
| | | <span>切换商机</span> |
| | | </template> |
| | | <Icon |
| | | icon="iconamoon:swap" |
| | | class="cursor-pointer" |
| | | @click="" |
| | | :size="16" |
| | | /> |
| | | </a-tooltip> |
| | | <template #overlay> |
| | | <a-menu |
| | | v-model:selectedKeys="selectedBusinessTitleKeys" |
| | | style="width: 220px" |
| | | @click="handleBusinessTitleClick" |
| | | :items="businessTitleArray" |
| | | > |
| | | </a-menu> |
| | | </template> |
| | | </a-dropdown> |
| | | <span class="font-bold ml-5px">{{ businessTitle }}</span> |
| | | </div> |
| | | <a-dropdown :trigger="['click']"> |
| | | <MoreOutlined class="cursor-pointer mr-10px"/> |
| | | <template #overlay> |
| | | <a-menu> |
| | | <a-menu-item key="0" @click="editBusiness"> |
| | | <span >编辑商机信息</span> |
| | | </a-menu-item> |
| | | <a-menu-item key="1" @click="addBusiness"> |
| | | <span>新建商机</span> |
| | | </a-menu-item> |
| | | <a-menu-item key="2" @click="removeBusiness">删除商机</a-menu-item> |
| | | </a-menu> |
| | | </template> |
| | | </a-dropdown> |
| | | </div> |
| | | <a-row :gutter="12"> |
| | | <a-col :span="10" class="font-size-13px"> |
| | | 销售金额 <span class="c-gray-4">CNY 0.00</span> |
| | | </a-col> |
| | | <a-col :span="10" class="font-size-13px"> |
| | | 结束日期 <span class="c-red-5">2024-10-30</span> |
| | | </a-col> |
| | | <a-col :span="4" class="font-size-13px"> |
| | | 备注 <span class="c-gray-4">--</span> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | <div class="mb-20px"> |
| | | <a-button type="primary" shape="round" block @click="openFollowUpModal"> |
| | | <template #icon> |
| | | <PlusCircleOutlined /> |
| | |
| | | 添加跟进 |
| | | </a-button> |
| | | </div> |
| | | <div ref="wrapEl"> |
| | | <div class="mb-20px flex justify-between flex-items-center"> |
| | | <span class="font-bold">共 {{totalData}} 条</span> |
| | | <TreeSelect |
| | | v-model:value="currentDynamicType" |
| | | :dropdownStyle="{color: 'red'}" |
| | | style="width: 120px" |
| | | placeholder="Please select" |
| | | :allow-clear="false" |
| | | :bordered="false" |
| | | tree-default-expand-all |
| | | :tree-data="dynamicTypeTree" |
| | | @change="handleDynamicTypeChange" |
| | | > |
| | | </TreeSelect> |
| | | <div class="mb-20px"> |
| | | <ScheduleDetailModal @register="registerScheduleModal"></ScheduleDetailModal> |
| | | <div class="mb-10px flex justify-between flex-items-center"> |
| | | <span class="font-bold">计划日程</span> |
| | | <a-button shape="round" @click="openScheduleModal">添加日程</a-button> |
| | | </div> |
| | | <Timeline > |
| | | <TimelineItem v-for="item in dynamicList" :key="item.id"> |
| | | <Row> |
| | | <Col span="16" class="c-gray-4"> |
| | | <div> |
| | | <template v-for="(item,index) in scheduleList" :key="item.id"> |
| | | <a-row class="cursor-pointer mb-10px" :gutter="12" @click="handleScheduleRowClick" :data-index="index"> |
| | | <a-col span="10" > |
| | | <a-avatar class="mb-3px" :size="10" :style="'background-color:'+ item.color" ></a-avatar> |
| | | <span class="ml-5px c-blue">{{ item.beginTime }}</span> |
| | | </a-col> |
| | | <a-col span="14"> |
| | | <span>{{ item.cluesName }}</span> |
| | | </a-col> |
| | | </a-row> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | <div ref="loadingEl"> |
| | | <div class="mb-20px flex justify-between flex-items-center"> |
| | | <span class="font-bold">历史动态</span> |
| | | |
| | | <!-- <a-tree-select--> |
| | | <!-- v-model:value="currentDynamicType"--> |
| | | <!-- :dropdownStyle="{color: 'red'}"--> |
| | | <!-- style="width: 120px"--> |
| | | <!-- placeholder="Please select"--> |
| | | <!-- :allow-clear="false"--> |
| | | <!-- :bordered="false"--> |
| | | <!-- tree-default-expand-all--> |
| | | <!-- :tree-data="dynamicTypeTree"--> |
| | | <!-- @change="handleDynamicTypeChange"--> |
| | | <!-- >--> |
| | | <!-- </a-tree-select>--> |
| | | </div> |
| | | <div class="mb-20px"> |
| | | <a-radio-group size="default" v-model:value="currentDynamicType"> |
| | | <a-radio-button value="0">全部({{totalData}})</a-radio-button> |
| | | <a-radio-button value="1">跟进记录({{totalData}})</a-radio-button> |
| | | <a-radio-button value="2">往来邮件({{totalData}})</a-radio-button> |
| | | <a-radio-button value="3">聊天记录({{totalData}})</a-radio-button> |
| | | <a-radio-button value="4">其他({{totalData}})</a-radio-button> |
| | | </a-radio-group> |
| | | <!-- <a-button type="primary">全部({{totalData}})</a-button>--> |
| | | <!-- <a-button type="primary">跟进记录({{totalData}})</a-button>--> |
| | | <!-- <a-button type="primary">往来邮件({{totalData}})</a-button>--> |
| | | <!-- <a-button type="primary">聊天记录({{totalData}})</a-button>--> |
| | | <!-- <a-button type="primary">其他({{totalData}})</a-button>--> |
| | | |
| | | </div> |
| | | <a-timeline > |
| | | <a-timeline-item v-for="item in dynamicList" :key="item.id"> |
| | | <a-row> |
| | | <a-col span="16" class="c-gray-4"> |
| | | {{item.cluesName}} |
| | | </Col> |
| | | <Col :offset="2" span="6" class="c-gray-4"> |
| | | </a-col> |
| | | <a-col :offset="2" span="6" class="c-gray-4"> |
| | | {{item.privateTime}} |
| | | </Col> |
| | | </Row> |
| | | </a-col> |
| | | </a-row> |
| | | <div> |
| | | {{item.failStatusName}} |
| | | </div> |
| | | <div> |
| | | <ImagePreviewGroup> |
| | | <a-image-preview-group> |
| | | <template v-for="(img,index) in item.imageList" :key="index"> |
| | | <Image :width="100" class="pr-10px" :src="img" /> |
| | | <a-image :width="100" class="pr-10px" :src="img" /> |
| | | </template> |
| | | </ImagePreviewGroup> |
| | | </a-image-preview-group> |
| | | </div> |
| | | </TimelineItem> |
| | | </Timeline> |
| | | </a-timeline-item> |
| | | </a-timeline> |
| | | </div> |
| | | |
| | | <!-- show-size-changer--> |
| | | <!-- show-quick-jumper--> |
| | | <!-- :show-total="total => `共 ${total} 条数据`"--> |
| | | <Pagination |
| | | <a-pagination |
| | | class="text-right" |
| | | v-model:current="currentPage" |
| | | v-model:page-size="pageSize" |
| | |
| | | </div> |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import { Timeline,Row,Col,ImagePreviewGroup,Image,Pagination,TreeSelect } from 'ant-design-vue'; |
| | | import { |
| | | Timeline, |
| | | Row, |
| | | Col, |
| | | ImagePreviewGroup, |
| | | Image, |
| | | Pagination, |
| | | TreeSelect, |
| | | } from 'ant-design-vue'; |
| | | import Icon from '@/components/Icon/Icon.vue'; |
| | | import { applicationList } from './data'; |
| | | import {cluesDynamicApi} from "@/api/clues/dynamic"; |
| | | import {ref,unref,getCurrentInstance} from "vue"; |
| | | import {useLoading} from "@/components/Loading"; |
| | | import {PlusCircleOutlined} from "@ant-design/icons-vue"; |
| | | import {PlusCircleOutlined, PlusOutlined, SettingOutlined} from "@ant-design/icons-vue"; |
| | | import {treeOptionsListApi} from "@/api/demo/tree"; |
| | | import EventBus from "@/utils/eventBus"; |
| | | const TimelineItem = Timeline.Item; |
| | | import {MoreOutlined} from "@ant-design/icons-vue"; |
| | | import {BasicHelp} from "@/components/Basic"; |
| | | import {log} from "vxe-table"; |
| | | import {useModal} from "@/components/Modal"; |
| | | import ScheduleDetailModal from "@/views/clues/components/drawer/ScheduleDetail.vue"; |
| | | import {projectList} from "@/views/clues/components/drawer/data"; |
| | | import {cluesListApi} from "@/api/clues/table"; |
| | | // const TimelineItem = Timeline.Item; |
| | | |
| | | const prefixCls = 'clues-tab-dynamic'; |
| | | const prefixCls = 'customer-tab-dynamic'; |
| | | |
| | | let scheduleList = ref([] as any[]); |
| | | let dynamicList = ref([] as any[]); |
| | | let totalData = ref(0); |
| | | |
| | | let currentPage = ref(1); |
| | | let pageSize = ref(10); |
| | | |
| | | |
| | | |
| | | const handlePageChange = (current: number, size: number) => { |
| | | currentPage.value = current; |
| | |
| | | }; |
| | | // let _this = getCurrentInstance(); |
| | | |
| | | let businessTitle = ref('新商机'); |
| | | let selectedBusinessTitleKeys = ref('1'); |
| | | let businessTitleArray = ref([ |
| | | { |
| | | key: '1', |
| | | label: '新商机', |
| | | title: '新商机', |
| | | }, |
| | | { |
| | | key: '2', |
| | | label: '订单确认', |
| | | title: '订单确认', |
| | | }, |
| | | { |
| | | key: '3', |
| | | label: '有意向', |
| | | title: '有意向', |
| | | }, |
| | | { |
| | | key: '4', |
| | | label: '测试新的机会', |
| | | title: '测试新的机会', |
| | | }, |
| | | ]); |
| | | function handleBusinessTitleClick(e){ |
| | | Logger.log('handleBusinessTitleClick',e); |
| | | selectedBusinessTitleKeys.value = e?.key; |
| | | businessTitle.value = e?.item?.title; |
| | | } |
| | | |
| | | // 日程相关 |
| | | const [registerScheduleModal, {openModal, setModalProps}] = useModal(); |
| | | const openScheduleModal = () => { |
| | | Logger.log('点击openScheduleModal'); |
| | | EventBus.emit('openScheduleModal', { |
| | | title: '新建任务', |
| | | content: '新建任务内容' |
| | | }); |
| | | }; |
| | | function handleScheduleRowClick(e) { |
| | | let index = e?.currentTarget?.dataset?.index; |
| | | Logger.log('handleScheduleRowClick', scheduleList.value[index]); |
| | | openModal(true, { |
| | | // record, |
| | | // isUpdate: true, |
| | | }); |
| | | } |
| | | getCustomerScheduleList(); |
| | | async function getCustomerScheduleList(){ |
| | | let params = { |
| | | page: 1, |
| | | pageSize: 10, |
| | | }; |
| | | try { |
| | | let res = await cluesListApi(params) |
| | | Logger.log('cluesListApi...',res); |
| | | // console.log(_this); |
| | | // _this.$set(dynamicList,res.items) |
| | | scheduleList.value = res.items; |
| | | |
| | | } catch (e) { |
| | | Logger.error(e); |
| | | } finally { |
| | | } |
| | | } |
| | | |
| | | |
| | | // 动态类型treeData |
| | | let currentDynamicType = ref('0-0'); |
| | | let currentDynamicType = ref('0'); |
| | | let dynamicTypeTree = ref([]); |
| | | getTreeData(); |
| | | async function getTreeData() { |
| | |
| | | } |
| | | |
| | | // 动态列表加载 |
| | | const wrapEl = ref<ElRef>(null); |
| | | const loadingEl = ref<ElRef>(null); |
| | | const [openWrapLoading, closeWrapLoading] = useLoading({ |
| | | target: wrapEl, |
| | | target: loadingEl, |
| | | props: { |
| | | tip: '加载中...', |
| | | absolute: true, |
| | | }, |
| | | }); |
| | | // 动态列表数据 |
| | | getCluesDynamicData(); |
| | | async function getCluesDynamicData(){ |
| | | setTimeout(()=>{ |
| | | getCustomerDynamicList(); |
| | | },50) |
| | | async function getCustomerDynamicList(){ |
| | | openWrapLoading(); |
| | | let params = { |
| | | page: currentPage.value, |
| | |
| | | closeWrapLoading(); |
| | | } |
| | | } |
| | | |
| | | |
| | | </script> |
| | | <style lang="less"> |
| | | .clues-tab-dynamic { |
| | | .customer-tab-dynamic { |
| | | .ant-select-arrow{ |
| | | color: #000; |
| | | } |