123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632 |
- <template>
- <div class="w-full h-full workbench">
- <!-- 日历 -->
- <div class="w-full p16 backgroundThemeColor rounded-b-lg setCaleStrle">
- <van-calendar ref="calendarRef" :default-date="(new Date(dateConditions))" switch-mode="year-month"
- :show-title="false" :show-mark="false" :poppable="false" :show-confirm="false" :row-height="'3rem'"
- :min-date="minDate"
- :style="{ borderRadius: '0.3rem', height: expandAndCollapse ? (calendarHeight ? calendarHeight + 'px' : 'auto') : usePxToVwView(140) }"
- :formatter="formatter" @select="calendarSelect" @panel-change="calendarPanelChangeSet">
- <template #month-title></template>
- <template #bottom-info="day">
- <div class="flex justify-items-center">
- <div class="doT" v-if="day?.bottomInfo"></div>
- <!-- <div class="taskDot" v-if="day?.taskInfo"></div> -->
- </div>
- </template>
- </van-calendar>
- <div class="flex justify-center" @click="expandAndCollapseClick">
- <van-icon name="arrow-double-left" color="#fff" :size="usePxToVwView(20)" class="mt-3 expandAndCollapseIcon"
- :style="expandAndCollapse ? 'transform: rotate(90deg);' : 'transform: rotate(-90deg);'" />
- </div>
- </div>
- <!-- 日程安排 -->
- <div class="min-h-52 overflow-y-auto mt-5">
- <!-- 有数据的情况 -->
- <div class="w-full h-full flex flex-col items-center" v-if="visitorProgramList.length">
- <div class="w-full overflow-y-auto max-h-72 px-5 mb-5">
- <template v-for="item in visitorProgramList">
- <van-swipe-cell>
- <!-- 拜访计划 -->
- <template v-if="item.calendarType == 1">
- <div class="bg-[#0859d6] ra6 p-4 mb-4 text-[#fff]" @click="jumpToVisitorDetails(item)">
- <div class="w-full flex items-center justify-between">
- <div class="text-size-in font-bold text-[#fff]">{{ item.planName }}</div>
- <div :class="`labelTag ${item.finishState == 0 ? 'toBeCompleted' : 'completed'}`">{{ ['未完成',
- '已完成'][item.finishState] }}</div>
- </div>
- <div class="w-full flex items-center justify-between mt-4">
- <div class="text-[#fff]" style="width: 62%;">拜访目的: {{ item.visitGoalName }}</div>
- <div class="w-1/3 text-[#fff] flex items-center" style="width: 38%;">
- <van-icon name="user-circle-o" class="text-size-in mr-2" />
- {{ item.customName }}
- </div>
- </div>
- <div class="w-full flex items-center justify-between mt-4">
- <div class="w-2/3 text-[#fff]" style="width: 62%;">拜访时间: {{ item.visitTime }}</div>
- <div class="w-1/3 text-[#fff] flex items-center" style="width: 38%;">
- <van-icon name="phone-o" class="text-size-in mr-2" />
- {{ item?.companyPhone }}
- </div>
- </div>
- </div>
- </template>
- <!-- 任务 -->
- <template v-if="item.calendarType == 2 && false">
- <div class="bg-[#FFA35919] ra6 p-4 mb-4" @click="toEditTask(item)">
- <div class="w-full flex items-center justify-between">
- <div class="text-size-in font-bold text-[#474A56]">{{ item.taskName }}</div>
- <div :class="`labelTag ${taskStatus[item.status]?.type}`">
- {{ taskStatus[item.status]?.label }}
- </div>
- </div>
- <div class="w-full flex items-center justify-between mt-4" v-if="user.company.isSimple != 1">
- <div class="text-[#505050]" style="width: 100%;">优先级: {{ ['低','中','高'][item.priority] }}</div>
- </div>
- <div class="w-full flex items-center justify-between mt-4">
- <div class="text-[#505050]" style="width: 100%;">任务开始时间: {{ item.startDate }}</div>
- </div>
- <div class="w-full flex items-center justify-between mt-4">
- <div class="text-[#505050]" style="width: 100%;">任务截至时间: {{ item.endDate }}</div>
- </div>
- </div>
- </template>
-
- <template #right>
- <div class="flex items-center flex-col justify-around h-full bg-[#F9F0E9] ra-l6 py-4">
- <div class="buttonCircle text-white" @click.stop="jumpToAddNewVisitors(item)" v-if="item.calendarType == 1">
- <img src="/src/assets/image/edit.png" class="w-full h-full">
- </div>
- <div class="buttonCircle text-white" @click.stop="toEditTask(item)" v-if="item.calendarType == 2">
- <img src="/src/assets/image/edit.png" class="w-full h-full">
- </div>
- <div class="buttonCircle text-white" @click.stop="deleteVisitor(item)">
- <img src="/src/assets/image/delete.png" class="w-full h-full">
- </div>
- </div>
- </template>
- </van-swipe-cell>
- </template>
- </div>
- <!-- <van-button type="primary" icon="add-o" class="m-auto w-3/5" @click="addTaskPlanPopup = true">新增</van-button> -->
- <van-button type="primary" icon="add-o" class="m-auto w-3/5" @click="jumpToAddNewVisitors()">新增</van-button>
- </div>
- <!-- 没有数据的情况下 -->
- <div class="w-full h-full flex flex-col items-center justify-center" v-if="!visitorProgramList.length">
- <div class="schedulePicture mb-5">
- <img class="w-full h-full" src="/src/assets/image/schedule.png">
- </div>
- <div class="text-center text-[#C4C4C4] mb-5">您今天还没安排日程哦!</div>
- <van-button type="primary" class="m-auto w-3/5" @click="addTaskPlanPopup = true">马上安排</van-button>
- </div>
- </div>
- <!-- 拜访计划和任务的添加按钮 -->
- <van-popup v-model:show="addTaskPlanPopup" closeable destroy-on-close position="bottom">
- <div class="flex w-full flex-col p-12">
- <van-button type="primary" class="m-auto" @click="addTaskClick()">新增任务</van-button>
- <div class="h-6"></div>
- <van-button type="primary" class="m-auto" @click="jumpToAddNewVisitors()">新增计划</van-button>
- </div>
- </van-popup>
- <!-- 常用表单 -->
- <div class="mt-5" v-if="false">
- <div class="text-size-large text-[#000] pl16">常用表单</div>
- <div class="p16 pt-0 pb-0 flex justify-between overflow-x-auto">
- <div class="flex">
- <template v-for="item in commonModulesList">
- <div class="w80 bg-[#FFA359] h-28 rounded-md flex flex-col items-center justify-center"
- @click="jumpToAdd(item)">
- <div class="formImage">
- <img class="w-full h-full" src="/src/assets/image/form.png">
- </div>
- <div class="text-white">{{ item.moduleName }}</div>
- </div>
- </template>
- <div class="w80 bg-[#0859d6] h-28 rounded-md flex flex-col items-center justify-center"
- @click="showCommonForms = true">
- <div class="formImage">
- <img class="w-full h-full" src="/src/assets/image/more.png">
- </div>
- <div class="text-white">更多</div>
- </div>
- </div>
- </div>
- </div>
- <!-- 常用联系人 -->
- <div class="mt-3" v-if="false">
- <div class="text-size-large text-[#000] pl16">常用联系人</div>
- <div class="p16 pt-0 pb-0">
- <template v-if="topContactsList && topContactsList.length > 0">
- <template v-for="item in topContactsList">
- <div class="flex flex-row items-center rounded-md p-4 bg-white mb-5" @click="toContactDetails(item)">
- <div class="contactImage">
- <img class="w-full h-full" src="/src/assets/image/topContacts.png">
- </div>
- <div class="flex-1">{{ item.name }}</div>
- <div class="rightArrow">
- <van-icon name="arrow" />
- </div>
- </div>
- </template>
- </template>
- <template v-else>
- <van-empty description="暂无常用联系人" />
- </template>
- </div>
- </div>
- <!-- 添加常用表单 -->
- <van-popup v-model:show="showCommonForms" closeable destroy-on-close position="bottom" :style="{ height: '80%' }">
- <div class="px-5 flex flex-col h-full py-8">
- <div class="flex-1 overflow-y-auto">
- <div class="text-size-large mb-5">已添加表单</div>
- <div class="flex flex-wrap mb-2">
- <template v-for="(item) in commonExpressionsHaveBeenAdded" :key="item.id">
- <div class="w-1/4 flex flex-col items-center mb-4 relative">
- <div class="newModuleImage">
- <img class="w-full h-full" :src="returnImageAddress(item)" alt="">
- </div>
- <div class="mt-3 text-[#474A56]">{{ item.name }}</div>
- <div class="absolute -top-2 right-3" @click="operationForm('delete', item)">
- <van-icon name="clear" color="#EE0A24" :size="`${usePxToVwView(20)}`" />
- </div>
- </div>
- </template>
- </div>
- <div class="text-size-large mb-5">未添加表单</div>
- <div class="flex flex-wrap mb-2">
- <template v-for="(item) in commonExpressionsHaveBeenNodded" :key="item.id">
- <div class="w-1/4 flex flex-col items-center mb-4 relative">
- <div class="newModuleImage">
- <img class="w-full h-full" :src="returnImageAddress(item)" alt="">
- </div>
- <div class="mt-3 text-[#474A56]">{{ item.name }}</div>
- <div class="absolute -top-2 right-3" @click="operationForm('add', item)">
- <van-icon name="add" color="#07C160" :size="`${usePxToVwView(20)}`" />
- </div>
- </div>
- </template>
- </div>
- </div>
- <van-button type="primary" @click="saveCommonlyUsedForms()">保存</van-button>
- </div>
- </van-popup>
- </div>
- </template>
- <script setup>
- import { ref, onActivated, nextTick } from 'vue';
- import { showConfirmDialog } from 'vant';
- import { useLifecycle } from '@hooks/useCommon.js';
- import { DELETE_VISITOR_PLAN, GET_VISITOR_PLAN, GET_FREQUENTLY_USED_CONTACTS, GET_COMMONLY_USED_MODULES, SAVE_COMMONLY_USED_FORMS, GET_PLAN_CALENDAR, DELETE_TASK } from "@hooks/useApi";
- import { routingInfos } from "@utility/generalVariables.js";
- import usePxToVwView from "@hooks/usePxTransform.js";
- import useToast from "@hooks/useToast"
- import dayjs from 'dayjs';
- import requests from "@common/requests";
- import useRouterStore from "@store/useRouterStore.js";
- import useInfoStore from "@store/useInfoStore.js";
- const taskStatus = [
- { label: '未开始', type: 'infos' },
- { label: '进行中', type: 'primarys' },
- { label: '已完成', type: 'completed' },
- { label: '已超时', type: 'dangers' },
- ]
- const router = useRouterStore()
- const useInfo = useInfoStore()
- const user = useInfo.userInfo
- const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
- const expandAndCollapse = ref(true)
- const calendarHeight = ref(0)
- const calendarRef = ref()
- const dateConditions = ref(dayjs().format('YYYY-MM-DD'))
- const minDate = ref(new Date('2024-01-01'))
- const visitorProgramList = ref([])
- const topContactsList = ref([])
- const commonModulesList = ref([])
- const planCalendarList = ref([])
- const showCommonForms = ref(false)
- const commonExpressionsHaveBeenAdded = ref([])
- const commonExpressionsHaveBeenNodded = ref([])
- const areYouRequesting = ref(false)
- const displayFrequentlyUsedContacts = ref(false)
- const addTaskPlanPopup = ref(false)
- function addTaskClick() {
- addTaskPlanPopup.value = false
- const jumpTo = routingInfos['tasks']
- router.navigateTo({
- pathName: 'addEditor',
- success: () => {
- router.emit('addEditorParameter', {
- routerInfo: JSON.stringify(jumpTo)
- })
- }
- })
- }
- function toEditTask(row) {
- const jumpTo = routingInfos['tasks']
- let newRow = row
- delete newRow.taskLogs
- delete newRow.createDate
- router.navigateTo({
- pathName: 'addEditor',
- success: () => {
- router.emit('addEditorParameter', {
- routerInfo: JSON.stringify(jumpTo),
- filedValue: JSON.stringify(row),
- })
- }
- })
- }
- function calendarPanelChangeSet(data) {
- dateConditions.value = dayjs(data.date).format('YYYY-MM-DD')
- getVisitorPlan()
- setTimeout(() => {
- getPlanCalendarList()
- }, 1)
- }
- function jumpToAdd(rows) {
- const jumpTo = routingInfos[rows.path.replace('/', '')]
- router.navigateTo({
- pathName: 'addEditor',
- success: () => {
- router.emit('addEditorParameter', {
- routerInfo: JSON.stringify(jumpTo)
- })
- }
- })
- }
- function toContactDetails(item) {
- router.navigateTo({
- pathName: 'details',
- success: () => {
- router.emit('detailParameter', {
- routerInfo: JSON.stringify(routingInfos['contacts']),
- parameter: JSON.stringify(item)
- })
- }
- })
- }
- function saveCommonlyUsedForms() {
- if(commonExpressionsHaveBeenAdded.value.map(item => item.id).length <= 0) {
- toastText(`最少请选择一个常用表单!`)
- return
- }
- const moduleIds = commonExpressionsHaveBeenAdded.value.map(item => item.id).join(',')
- requests.post(SAVE_COMMONLY_USED_FORMS, { moduleIds }).then((res) => {
- toastSuccess('保存成功')
- getCommonlyUsedModules()
- showCommonForms.value = false
- })
- }
- function operationForm(type, row) {
- const itemIndex = commonExpressionsHaveBeenNodded.value.findIndex(item => item.path === row.path);
- if (type === 'add' && itemIndex !== -1) {
- const item = commonExpressionsHaveBeenNodded.value.splice(itemIndex, 1)[0];
- commonExpressionsHaveBeenAdded.value.push(item);
- }
- if (type === 'delete') {
- const itemIndex = commonExpressionsHaveBeenAdded.value.findIndex(item => item.path === row.path);
- if (itemIndex !== -1) {
- const item = commonExpressionsHaveBeenAdded.value.splice(itemIndex, 1)[0];
- commonExpressionsHaveBeenNodded.value.push(item);
- }
- }
- }
- function deleteVisitor(row) {
- const { id, planName, calendarType, taskName } = row
- const text = calendarType == 1 ? '访客' : '任务'
- const textMessage = calendarType == 1 ? '访客计划' : '任务'
- let formVal = {}
- calendarType == 1 ? formVal.planId = id : formVal.taskIds = id
- showConfirmDialog({
- title: `删除${text}`,
- message: `确定删除【${calendarType == 1 ? planName : taskName}】${textMessage}计划吗?`,
- }).then(() => {
- requests.post(calendarType == 1 ? DELETE_VISITOR_PLAN : DELETE_TASK, { ...formVal }).then((res) => {
- toastSuccess('删除成功')
- getVisitorPlan()
- }).catch((err) => {
- toastFail(err.msg ? err.msg : '删除失败')
- })
- })
- }
- function formatter(day) {
- const { date, bottomInfo } = day
- const currentDate = dayjs(date).format("YYYY-MM-DD");
- const rqiList = planCalendarList.value.filter(item => item.ymd === currentDate)
- day.bottomInfo = (rqiList.length > 0 ? true : false)
- day.taskInfo = (planCalendarList.value.find(item => item.currentDate === currentDate)?.taskDtoList.length > 0 ? true : false)
- return day
- }
- function calendarSelect(data) {
- dateConditions.value = dayjs(data).format("YYYY-MM-DD");
- getVisitorPlan()
- }
- function jumpToVisitorDetails(row) {
- router.navigateTo({
- pathName: 'visitorDetails',
- success: () => {
- router.emit('visitorDetailsParameter', {
- row: JSON.stringify(row || {})
- })
- }
- })
- }
- function jumpToAddNewVisitors(row) {
- addTaskPlanPopup.value = false
- router.navigateTo({
- pathName: 'addEditorVisitor',
- success: () => {
- router.emit('addEditorVisitorParameter', {
- row: JSON.stringify(row || {}),
- date: JSON.stringify(dateConditions.value || {})
- })
- }
- })
- }
- function returnImageAddress(rows) {
- const row = routingInfos[rows.path.replace('/', '')]
- return row && row.homeImage
- }
- function expandAndCollapseClick() {
- expandAndCollapse.value = !expandAndCollapse.value
- const dates = calendarRef.value.getSelectedDate()
- calendarRef.value.scrollToDate(new Date(dates))
- }
- function processForms() {
- const selectedForm = commonModulesList.value
- const allFormList = useInfo.modularList || []
- commonExpressionsHaveBeenAdded.value = allFormList.filter(item =>
- selectedForm.some(arrItem => arrItem.path === item.path)
- )
- commonExpressionsHaveBeenNodded.value = allFormList.filter(item =>
- !selectedForm.some(arrItem => arrItem.path === item.path)
- ).filter(item => item.path !== '/biReport')
- }
- function getVisitorPlan() {
- requests.post(GET_VISITOR_PLAN, {
- calenderDate: dayjs(dateConditions.value).format('YYYY-MM-DD')
- }).then((res) => {
- // visitorProgramList.value = res.data || []
- visitorProgramList.value = [
- ...(res.data.planList || []).map(item => {
- return {
- ...item,
- calendarType: 1,
- }
- }),
- ...(res.data.taskList || []).map(item => {
- return {
- ...item,
- calendarType: 2,
- }
- }),
- ]
- })
- }
- function getFrequentlyUsedContacts() {
- requests.post(GET_FREQUENTLY_USED_CONTACTS, {}).then((res) => {
- topContactsList.value = res.data
- })
- }
- function getCommonlyUsedModules() {
- requests.post(GET_COMMONLY_USED_MODULES, {}).then((res) => {
- commonModulesList.value = res.data
- processForms()
- })
- }
- function getPlanCalendarList() {
- const months = calendarRef.value.getSelectedDate()
- requests.post(GET_PLAN_CALENDAR, { ym: dayjs(months).format('YYYY-MM') }).then(({ data }) => {
- // planCalendarList.value = data.planList || []
- const newData = [
- ...(data.planList || []).map(item => {
- return {
- ...item,
- calendarType: 1,
- }
- }),
- ...(data.taskList || []).map(item => {
- return {
- ...item,
- calendarType: 2,
- }
- }),
- ]
- planCalendarList.value = newData
- })
- }
- function getAllData() {
- if (areYouRequesting.value) {
- return
- }
- displayFrequentlyUsedContacts.value = useInfo.modularList.filter(item => item.path === '/contacts').length
- areYouRequesting.value = true
- Promise.all([
- getPlanCalendarList(),
- getVisitorPlan(),
- getCommonlyUsedModules(),
- getFrequentlyUsedContacts(),
- ]).finally(() => {
- areYouRequesting.value = false
- })
- }
- useLifecycle({
- load: () => {
- getAllData()
- },
- init: () => {
- getAllData()
- setTimeout(() => {
- if (expandAndCollapse.value) {
- calendarHeight.value = calendarRef.value.$el.offsetHeight
- }
- }, 500)
- }
- });
- onActivated(() => {
- })
- </script>
- <style lang='scss' scoped>
- .p16 {
- padding: 16px;
- }
- .pl16 {
- padding-left: 16px;
- }
- .ra-l6 {
- border-top-left-radius: 6px;
- border-top-right-radius: 6px;
- }
- .w80 {
- width: 80px;
- margin-right: 12px;
- }
- .doT {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background-color: $themeColor;
- margin: auto;
- position: relative;
- top: 6px;
- }
- .taskDot {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background-color: #ff7300;
- margin: auto;
- position: relative;
- top: 6px;
- }
- .toBeCompleted {
- background: rgba($color: #F38B3C, $alpha: .1);
- border-color: #F38B3C;
- color: #F38B3C;
- }
- .completed {
- background: rgba($color: #07C160, $alpha: .1);
- border-color: #07C160;
- color: #07C160;
- }
- .infos {
- background: rgba($color: #909399, $alpha: .1);
- border-color: #909399;
- color: #909399;
- }
- .primarys {
- background: rgba($color: #0859d6, $alpha: .1);
- border-color: #0859d6;
- color: #0859d6;
- }
- .dangers {
- background: rgba($color: #F56C6C, $alpha: .1);
- border-color: #F56C6C;
- color: #F56C6C;
- }
- .labelTag {
- font-size: 10px;
- padding: 3px 8px;
- border-radius: 4px;
- border: 1px solid;
- }
- .formImage {
- width: 24px;
- height: 24px;
- margin-bottom: 12px;
- }
- .contactImage {
- width: 29px;
- height: 29px;
- border-radius: 50%;
- margin-right: 12px;
- }
- .rightArrow {
- font-size: 16px;
- }
- .schedulePicture {
- width: 48px;
- height: 51px;
- }
- .buttonCircle {
- width: 37px;
- height: 37px;
- margin: 0 14px;
- }
- .newModuleImage {
- width: 50px;
- height: 50px;
- border-radius: 10px;
- }
- .expandAndCollapseIcon {
- transition: 0.5s ease-in-out;
- }
- .setCaleStrle :deep(.van-calendar__month-title) {
- display: none;
- }
- .setCaleStrle :deep(.van-calendar__month) {
- padding: 0.8rem 0 0.5rem 0;
- }
- .setCaleStrle :deep(.van-calendar) {
- transition: 0.5s ease-in-out;
- }
- </style>
|