| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- <script lang="ts" setup>
- import { ref, reactive, onMounted, inject } from "vue";
- import { useRouter, useRoute } from "vue-router";
- import { VueDraggable } from 'vue-draggable-plus';
- import { MOD, OBTAIN_KANBAN_VIEW_DATA, PANEL_MOBILE_DATA, URL_STAGEIDNEXT } from '../api'
- import { Loading, MoreFilled } from '@element-plus/icons-vue'
- import { post, get, uploadFile } from "@/utils/request";
- import SvgIcon from "@/components/svgIcon/index.vue";
- import { formatDate, formatDateTime } from "@/utils/times";
- const emit = defineEmits()
- const router = useRouter()
- const viewList = ref<viewListInterface[]>([])
- const excessiveData = ref<any>({})
- const selectionStage = ref<number>()
- const switchingStagesVisable = ref(false)
- const allLoading = reactive({
- kanbanViewLoading: false,
- switchingStagesLoading: false
- })
- onMounted(() => {
- getKanbanViewData();
- })
- function promotionStage() {
- const item = viewList.value.find((item: any) => item.id == selectionStage.value)
- const { id: stageId, label: stageValue } = item as any
- allLoading.switchingStagesLoading = true
- post(URL_STAGEIDNEXT, { id: excessiveData.value.id, stageId, stageValue }).then(() => {
- switchingStagesVisable.value = false
- getKanbanViewData()
- }).finally(() => {
- allLoading.switchingStagesLoading = false
- })
- }
- function switchingStages(row: any) {
- excessiveData.value = row
- switchingStagesVisable.value = true
- }
- function onChange(e: any) {
- const data = {
- id: e.data.id,
- oldIndex: e.oldIndex,
- newIndex: e.newIndex,
- oldStagesId: e.from.id,
- newStagesId: e.to.id
- }
- setDataLoading(viewList.value, data.newStagesId, data.id, true)
- post(PANEL_MOBILE_DATA, { ...data }).then(() => {
- getKanbanViewData()
- }).finally(() => {
- setDataLoading(viewList.value, data.newStagesId, data.id, false)
- })
- }
- function setDataLoading(list: any, targetLevel_1Id: number | string, targetLevel_2Id: number | string, flag: boolean) {
- for (let i = 0; i < list.length; i++) {
- if (list[i].id == targetLevel_1Id) {
- for (let j = 0; j < list[i].list.length; j++) {
- if (list[i].list[j].id == targetLevel_2Id) {
- list[i].list[j].loadData = flag;
- }
- }
- }
- }
- }
- function selectData(_value: boolean, _row: any) {
- let data = [...viewList.value].flatMap(item =>
- item.list.filter(subItem => subItem.multipleChoice)
- );
- let newData = JSON.parse(JSON.stringify(data))
- newData.forEach((item: any) => {
- delete item.multipleChoice
- delete item.loadData
- });
- emit('kanbanViewClick', 'multipleChoice', newData)
- }
- function deteleItem(row: any) {
- emit('kanbanViewClick', 'delete', row)
- }
- function editItem(row: any) {
- emit('kanbanViewClick', 'edit', row)
- }
- function addTaskItem(row: any) {
- emit('kanbanViewClick', 'addTask', row)
- }
- function toDetailPath(row: any) {
- router.push({
- path: `${MOD}/detail`,
- query: { id: row.id }
- })
- }
- function searchDashboardView(row: businessOpportunityFormType) {
- getKanbanViewData(row || {})
- }
- function getKanbanViewData(formVal: any = {}) { // 获取看板视图数据
- allLoading.kanbanViewLoading = true
- post(OBTAIN_KANBAN_VIEW_DATA, { ...formVal }).then(res => {
- res.data.forEach((item: any) => {
- item.list = setArrList(item.list)
- })
- emit('kanbanViewClick', 'multipleChoice', [])
- viewList.value = res.data || []
- }).finally(() => {
- allLoading.kanbanViewLoading = false
- })
- }
- function setArrList(value: any) {
- const val = Array.isArray(value) ? value : []
- return val.map((item: any) => {
- return {
- ...item,
- expectedTransactionDate: item.expectedTransactionDate ? formatDate(new Date(item.expectedTransactionDate)) : '',
- multipleChoice: false,
- loadData: false
- }
- })
- }
- defineExpose({
- searchDashboardView,
- });
- </script>
- <template>
- <div class="w-full h-full overflow-auto flex pb-3 scroll-bar" v-loading="allLoading.kanbanViewLoading">
- <template v-if="viewList.length > 0">
- <div class="w-auto h-full" v-for="(item, index) in viewList" :key="index">
- <div class="h-full flex flex-col mx-3 w-72">
- <div class="w-full flex justify-between px-3 py-3">
- <div class="w-9/12">
- <div class="w-auto px-4 py-1 text-white rounded-2xl" :style="{ backgroundColor: item.color }">
- {{ item.label }}
- </div>
- </div>
- <div class="w-2/12 text-right">{{ item.length }}</div>
- </div>
- <VueDraggable v-model="item.list" class="flex-1 overflow-y-auto overflow-x-hidden scroll-bar" :animation="150"
- group="people" @update="onChange" @add="onChange" :id="item.id">
- <div
- class="break-words border border-inherit rounded h-72 mx-3 my-3 p-3 shadow-md hover:shadow-xl duration-300 ease-in-out cursor-pointer"
- v-for="(subItem, subIndex) in item.list" :key="subIndex" v-loading="subItem.loadData">
- <div class="w-full text-left text-lg flex flex-row items-center" :style="{ color: item.color }">
- <el-checkbox v-model="subItem.multipleChoice" class="pr-2" size="large"
- @change="(val: any) => selectData(val, subItem)" />
- <div class="flex-1 truncate" @click.stop="toDetailPath(subItem)" v-ellipsis-tooltip>
- {{ subItem.name }}
- </div>
- <el-dropdown placement="bottom-start">
- <el-link :icon="MoreFilled" :underline="false"></el-link>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click="addTaskItem(subItem)">新建任务</el-dropdown-item>
- <el-dropdown-item @click="switchingStages(subItem)">切换阶段</el-dropdown-item>
- <el-dropdown-item @click="editItem(subItem)">编辑</el-dropdown-item>
- <el-dropdown-item @click="deteleItem(subItem)">删除</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- <div class="flex items-center mt-4">
- <SvgIcon name="kehu" :size="20" class="mr-2" />
- {{ subItem.customerName }}
- </div>
- <div class="flex items-center mt-4">
- <SvgIcon name="lianxiren" :size="20" color="#606266" class="mr-2" />
- {{ subItem.contactsName }}
- </div>
- <div class="flex items-center mt-4">
- <SvgIcon name="fuzeren" :size="20" color="#606266" class="mr-2" />
- {{ subItem.inchargerName }}
- </div>
- <div class="flex items-center mt-4">
- ¥ {{ subItem.amountOfMoney || 0 }}
- </div>
- <div class="flex items-center mt-4">
- {{ subItem.expectedTransactionDate }}
- </div>
- </div>
- </VueDraggable>
- </div>
- </div>
- </template>
- <template v-if="viewList.length == 0">
- <div class="w-full h-full flex items-center justify-center">
- <el-empty description="暂无数据" />
- </div>
- </template>
- <!-- 弹窗 -->
- <el-dialog width="700px" v-model="switchingStagesVisable" append-to-body :show-close="false">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">切换阶段</h4>
- <div>
- <el-button type="primary" @click="promotionStage()" :loading="allLoading.switchingStagesLoading">保存</el-button>
- <el-button @click="switchingStagesVisable = false">取消</el-button>
- </div>
- </div>
- </template>
- <div class="h-[80px] flex flex-col pt-5">
- <div class="flex flex-row w-full items-center">
- <div class="w-[100px] mr-2 text-right">切换阶段:</div>
- <div class="flex-1">
- <el-select v-model="selectionStage" placeholder="请选择" style="width: 240px">
- <el-option v-for="item in viewList" :key="item.id" :label="item.label" :value="item.id" />
- </el-select>
- </div>
- </div>
- </div>
- </el-dialog>
- </div>
- </template>
- <style lang="scss" scoped></style>
|