Files
ys-app/src/pages/business/CRM/scheduler/taskPlanList.vue
2026-01-09 11:37:46 +08:00

413 lines
9.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="con-body">
<view class="con-bg">
<!-- 头部 -->
<customHeader ref="customHeaderRef" :title="!searchShow ? '任务计划查看' : '搜索'"
:leftFlag="true" :rightFlag="true" @back="handleBack"
:searchType="searchShow ? 1 : undefined">
<!-- <template #right v-if="!searchShow">
<view class="head-right" @click="handleRead">
<img :src="'static/images/icon-clean@2x.png'" />清除未读
</view>
</template> -->
</customHeader>
<!-- 高度来避免头部遮挡 -->
<view class="top-height"></view>
<!-- 搜索处理 -->
<customSearch v-if="searchShow" :searchKeywords="searchText" :searchType="searchTypeObj"
:checkTypeObj="notictTypeCheck" @confirm="handleSearchConfirm">
</customSearch>
<view class="search" v-else @click="handleSearchFocus">
<view class="search-bg">
<view class="search-left">
{{ notictTypeCheck.name ? notictTypeCheck.name : '全部' }}
</view>
<view class="search-right">
<input class="uni-input" v-model="inputval" placeholder="请输入您想查询的内容"
placeholder-class="search-color" />
</view>
</view>
</view>
<!-- 正文内容 -->
<!-- 分页部分 -->
<mescroll-uni v-if="!searchShow" ref="mescrollRef" @init="mescrollInit"
@down="downCallback" @up="upCallback" :up="upOption" :down="downOption"
:fixed="false" textColor="#ffffff" bgColor="#ffffff" class="scroll-h"
:class="{ 'loading-scroll': cssFlag }">
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index"
@click="showDetail(item)">
<view>
<view class="report-list">
<view class="title" style="font-size: 30rpx">
主线任务{{ item.taskName }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
计划内容{{ item.planContent }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
计划开始时间{{ item.plannedStartTime }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
计划结束时间{{ item.plannedCompTime }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
次数{{ item.num }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
频率提醒{{ item.reminderCount }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
完成状态{{ item.completionCount }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
是否超时{{ item.planStatus }}
</view>
<view class="r-left"
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
审批状态
<label v-if="item.approvalStatus == '0'" style="color: #cf0000;">{{ item.approvalStatus }}</label>
<label v-else-if="item.approvalStatus == '1'" style="color: #00cf00;">{{ item.approvalStatus }}</label>
<label v-else style="color: #60a0ff;">{{ item.approvalStatus }}</label>
</view>
</view>
</view>
</view>
</mescroll-uni>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
watch
} from 'vue'
import customHeader from '@/components/customHeader.vue'
import customSearch from '@/components/customSearch.vue'
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
import {
getNavBarPaddingTop
} from '@/utils/system.js'
import {
TaskPlanList
} from '@/api/crm/api_ys.js'
import {
onLoad,
onShow,
onUnload,
onHide
} from '@dcloudio/uni-app'
// 获取导航栏高度用于内容区域padding
const navBarPaddingTop = ref(0);
onMounted(() => {
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
uni.$on('updateStatus', markVisited)
})
// 搜索处理
let searchShow = ref(false);
let searchText = ref(undefined);
let searchTypeObj = ref({
typeId: 3,
typeName: '消息类型'
});
let notictTypeCheck = ref({}); //选中类型
// 查询列表
let list = ref([]);
// 新增状态变量存储搜索条件
const inputval = ref(''); // 搜索内容
let searchValue = ref(null)
//监视查询的内容的变化
watch(searchValue, (newValue, oldValue) => {
//变化了之后,重新查询内容
var data = {
pageNum: 1,
pageSize: 10,
};
TaskPlanList(data).then(res => {
if (res.code == 200) {
//设置列表数据
list.value = res.rows;
}
})
})
onHide(() => {
searchShow.value = false;
})
// 搜索返回操作
const handleBack = () => {
searchShow.value = false;
}
// 获取input 焦点跳转
const handleSearchFocus = () => {
searchShow.value = true;
}
// 搜索完返回处理
const handleSearchConfirm = (param1, param2) => {
// console.log(param1,param2)
notictTypeCheck.value = param1.value;
inputval.value = param2.value || '';
searchValue.value = param2.value;
// 重置mescroll触发刷新
if (mescrollRef.value) {
mescrollRef.value.resetUpScroll();
}
searchShow.value = false;
}
const mescrollRef = ref(null);
const upOption = ref({
page: {
num: 0,
size: 10
},
noMoreSize: 5,
empty: {
tip: '~ 空空如也 ~',
icon: "../../../../static/images/mescroll-empty.png"
},
textLoading: '加载中...',
textNoMore: '已经到底了'
});
const downOption = ref({
auto: true,
textInOffset: '下拉刷新',
textOutOffset: '释放更新',
textLoading: '刷新中...'
});
let cssFlag = ref(false); //控制样式
const mescrollInit = (mescroll) => {
cssFlag.value = true;
mescrollRef.value = mescroll;
};
// 下拉刷新
const downCallback = async (mescroll) => {
try {
setTimeout(async () => {
const res = await getTaskPlanList(1, upOption.value.page.size);
cssFlag.value = false;
list.value = res.list;
mescroll.resetUpScroll();
}, 500);
} catch (error) {
mescroll.endErr();
} finally {
setTimeout(async () => {
mescroll.endSuccess();
}, 500);
}
}
// 上拉加载更多
const upCallback = async (mescroll) => {
try {
setTimeout(async () => {
const res = await getTaskPlanList(mescroll.num, mescroll.size,
inputval.value);
if (mescroll.num === 1) {
list.value = res.list;
} else {
list.value.push(...res.list);
}
mescroll.endBySize(res.list.length, res.total);
}, 500);
} catch (error) {
mescroll.endErr();
}
}
// 获取数据列表
const getTaskPlanList = (pageNum, pageSize) => {
return new Promise(async (resolve) => {
let param = {
pageNum,
pageSize,
// 添加搜索条件参数
searchInput: inputval.value
}
let res = await TaskPlanList(param);
resolve({
list: res.rows,
total: res.total
});
});
}
function showDetail(item) {
uni.navigateTo({
url: "/pages/business/CRM/scheduler/taskViewingDetail?data=" + encodeURIComponent(
JSON
.stringify(item))
})
}
onUnload(() => {
uni.$off('updateStatus')
})
const markVisited = (informationId) => {
const newList = [...list.value].map(item => {
if (item.informationId == informationId) {
return {
...item,
myselfBrowsing: 1
};
}
return item;
});
list.value = newList;
};
</script>
<style scoped>
.all-body {
/* #ifdef APP-PLUS */
top: 150rpx;
height: calc(100vh - 75px);
/* #endif */
/* #ifndef APP-PLUS */
top: 120rpx;
height: calc(100vh);
/* #endif */
}
.search {
display: flex;
}
.search .btn-search {
border: none;
background: none;
line-height: normal;
color: #fff;
line-height: 56rpx !important;
padding: 10rpx 0 0;
text-align: left;
cursor: pointer;
}
.search .btn-search::after {
display: none;
}
.search .custom-search {
width: 80%;
}
.search .custom-search.uni-searchbar {
padding-right: 0 !important;
}
.scroll-h {
/* #ifdef APP-PLUS */
height: calc(100vh - 120px);
/* #endif */
/* #ifndef APP-PLUS */
height: calc(100vh - 110px);
/* #endif */
}
.white-bg {
padding-bottom: 10rpx;
}
.search_center {
display: flex;
align-items: center;
border: none;
flex: 1;
height: 70rpx;
margin-left: 20rpx;
padding-left: 20rpx;
border-radius: 32.5rpx;
background-color: #f5f5f5;
.search_icon {
width: 30rpx;
height: 30rpx;
margin-right: 22rpx;
}
.category {
display: flex;
align-items: center;
margin-right: 16rpx;
padding-right: 16rpx;
border-right: 2rpx solid #D4D4D4;
position: relative;
text {
font-size: 13px;
margin-left: 10rpx;
margin-right: 10rpx;
}
image {
margin-top: 4rpx;
width: 20rpx;
height: 11rpx;
}
.pop {
position: absolute;
top: 50rpx;
background: #FFFFFF;
box-shadow: 0px 0px 40rpx 0px rgba(59, 59, 59, 0.2);
border-radius: 12rpx;
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx;
z-index: 100;
max-height: 566rpx;
overflow-y: auto;
text {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #333333;
white-space: nowrap;
margin: 10rpx 0;
line-height: 56rpx;
}
}
.pop_arrow {
position: absolute;
top: 48rpx;
z-index: 999;
&::after {
position: absolute;
content: "";
left: 68rpx;
top: -26rpx;
border: 14rpx solid #fff;
border-color: transparent transparent #fff transparent;
}
}
}
}
</style>