实现公告和逾期任务的混排(排序依照:公告的创建时间与逾期任务的逾期时间进行混排)--目前负责人仅取一个

This commit is contained in:
WindowBird 2025-11-21 14:17:14 +08:00
parent 9e8d582e4c
commit 362dda52b0
2 changed files with 185 additions and 26 deletions

View File

@ -77,35 +77,67 @@
<!-- </view>-->
<!-- </view>-->
<!-- 公告事项 -->
<!-- 公告和逾期任务合并列表 -->
<view class="announcement-section">
<view class="announcement-header">
<text class="announcement-title-header">公告</text>
<text class="announcement-title-header">公告与逾期任务</text>
<text class="announcement-view-all" @click.stop="viewAllAnnouncements">查看全部</text>
</view>
<view class="announcement-item task-card-base task-card-announcement" v-for="announcement in announcements" :key="announcement.id" @click="viewAnnouncement(announcement)">
<view class="announcement-content-wrapper">
<view class="announcement-title-row">
<text class="announcement-title">{{ announcement.title }}</text>
<view class="announcement-tags">
<view class="announcement-tag tag-pinned" v-if="announcement.top">置顶</view>
<view class="announcement-tag tag-general" v-if="announcement.level === '1'">一般</view>
<view class="announcement-tag tag-important" v-if="announcement.level === '2'">重要</view>
<view class="announcement-tag tag-urgent" v-if="announcement.level === '3'">紧急</view>
<scroll-view class="merged-list-scroll" scroll-y>
<view
v-for="item in mergedList"
:key="`${item.type}-${item.id}`"
class="merged-item"
>
<!-- 公告样式 -->
<view
v-if="item.type === 'announcement'"
class="announcement-item task-card-base task-card-announcement"
@click="viewAnnouncement(item)"
>
<view class="announcement-content-wrapper">
<view class="announcement-title-row">
<text class="announcement-title">{{ item.title }}</text>
<view class="announcement-tags">
<view class="announcement-tag tag-pinned" v-if="item.top">置顶</view>
<view class="announcement-tag tag-general" v-if="item.level === '1'">一般</view>
<view class="announcement-tag tag-important" v-if="item.level === '2'">重要</view>
<view class="announcement-tag tag-urgent" v-if="item.level === '3'">紧急</view>
</view>
</view>
<view class="announcement-meta">
<view class="announcement-meta-item">
<text class="announcement-meta-icon">👤</text>
<text class="announcement-meta-text">{{ item.userName }}</text>
</view>
<view class="announcement-meta-item">
<text class="announcement-meta-icon">🕐</text>
<text class="announcement-meta-text">{{ item.createTime }}</text>
</view>
</view>
</view>
</view>
<view class="announcement-meta">
<view class="announcement-meta-item">
<text class="announcement-meta-icon">👤</text>
<text class="announcement-meta-text">{{ announcement.userName }}</text>
<!-- 逾期任务卡片样式 -->
<view
v-else-if="item.type === 'overdue'"
class="overdue-task-card task-card-base"
@click="goToTaskDetail(item)"
>
<view class="overdue-task-header">
<view class="overdue-task-owner-tag" v-if="item.firstOwner">
{{ item.firstOwner }}
</view>
</view>
<view class="announcement-meta-item">
<text class="announcement-meta-icon">🕐</text>
<text class="announcement-meta-text">{{ announcement.createTime }}</text>
<view class="overdue-task-title">{{ item.description }}</view>
<view class="overdue-task-footer">
<text class="overdue-task-project">{{ item.project }}</text>
<text class="overdue-task-status">逾期{{ item.overdueDays }}</text>
<text class="overdue-task-date">{{ item.date }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 项目状态 -->
@ -269,46 +301,70 @@ const getOwnerNames = (memberList) => {
return memberList.map(member => member.userName || member.name || '').filter(name => name).join('、');
};
//
const calculateOverdueDays = (expireTime) => {
if (!expireTime) return 0;
const expireDate = new Date(expireTime);
const now = new Date();
now.setHours(0, 0, 0, 0);
expireDate.setHours(0, 0, 0, 0);
const diffTime = now.getTime() - expireDate.getTime();
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
return diffDays > 0 ? diffDays : 0;
};
//
const loadOverdueTasks = async () => {
try {
const res = await getTaskList({ overdue: true, statusList: [1, 2] });
const res = await getTaskList({ overdue: true,pageNum:1,pageSize:100, statusList: [1, 2] });
console.log('逾期任务列表加载成功:', res);
// { total: 27, rows: [...], code: 200, msg: "" }
if (res && res.rows && Array.isArray(res.rows)) {
overdueTasks.value = res.rows.map((item) => {
const overdueDays = calculateOverdueDays(item.expireTime);
return {
id: item.id || '',
date: formatDate(item.expireTime) || '',
project: item.projectName || '',
description: item.description || '',
owner: getOwnerNames(item.memberList) || '',
releaseTime: formatDate(item.createTime) || ''
releaseTime: formatDate(item.createTime) || '',
expireTime: item.expireTime || '', //
overdueDays: overdueDays,
type: 'overdue' //
};
});
} else if (res && res.data && Array.isArray(res.data)) {
// data
overdueTasks.value = res.data.map((item) => {
const overdueDays = calculateOverdueDays(item.expireTime);
return {
id: item.id || '',
date: formatDate(item.expireTime) || '',
project: item.projectName || '',
description: item.description || '',
owner: getOwnerNames(item.memberList) || '',
releaseTime: formatDate(item.createTime) || ''
releaseTime: formatDate(item.createTime) || '',
expireTime: item.expireTime || '',
overdueDays: overdueDays,
type: 'overdue'
};
});
} else if (res && Array.isArray(res)) {
//
overdueTasks.value = res.map((item) => {
const overdueDays = calculateOverdueDays(item.expireTime);
return {
id: item.id || '',
date: formatDate(item.expireTime) || '',
project: item.projectName || '',
description: item.description || '',
owner: getOwnerNames(item.memberList) || '',
releaseTime: formatDate(item.createTime) || ''
releaseTime: formatDate(item.createTime) || '',
expireTime: item.expireTime || '',
overdueDays: overdueDays,
type: 'overdue'
};
});
} else {
@ -324,7 +380,7 @@ const loadOverdueTasks = async () => {
//
const loadAnnouncements = async () => {
try {
const res = await getNoticeList({ pageNum: 1, pageSize: 2 });
const res = await getNoticeList({ pageNum: 1, pageSize: 10 }); // 便
console.log('公告列表加载成功:', res);
if (res && res.rows && Array.isArray(res.rows)) {
@ -336,7 +392,8 @@ const loadAnnouncements = async () => {
userName: item.userName || '',
createTime: item.createTime || '',
top: item.top || false,
level: item.level || ''
level: item.level || '',
type: 'announcement' //
};
});
} else {
@ -348,6 +405,43 @@ const loadAnnouncements = async () => {
}
};
//
const mergedList = computed(() => {
const list = [];
//
announcements.value.forEach(item => {
list.push({
...item,
sortTime: item.createTime || '' // 使
});
});
//
overdueTasks.value.forEach(item => {
list.push({
...item,
sortTime: item.expireTime || '', // 使
firstOwner: item.owner ? item.owner.split('、')[0] : '' //
});
});
//
list.sort((a, b) => {
if (!a.sortTime && !b.sortTime) return 0;
if (!a.sortTime) return 1; //
if (!b.sortTime) return -1; //
const timeA = new Date(a.sortTime).getTime();
const timeB = new Date(b.sortTime).getTime();
if (isNaN(timeA) && isNaN(timeB)) return 0;
if (isNaN(timeA)) return 1;
if (isNaN(timeB)) return -1;
return timeB - timeA;
});
return list;
});
//
const loadDashboardData = async () => {
try {
@ -759,6 +853,71 @@ const getTagCustomStyle = (status) => {
margin-top: 8px;
}
//
.merged-list-scroll {
height: 30vh;
width: 100%;
}
.merged-item {
margin-bottom: 12px;
}
//
.overdue-task-card {
padding: 16px;
display: flex;
flex-direction: column;
gap: 12px;
}
.overdue-task-header {
display: flex;
align-items: center;
}
.overdue-task-owner-tag {
background: linear-gradient(135deg, #b794f6 0%, #9f7aea 100%);
color: #fff;
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
white-space: nowrap;
}
.overdue-task-title {
font-size: 16px;
font-weight: 500;
color: #333;
line-height: 1.5;
margin-top: 4px;
}
.overdue-task-footer {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.overdue-task-project {
font-size: 12px;
color: #4a90e2;
}
.overdue-task-status {
font-size: 12px;
color: #f56c6c;
font-weight: 500;
}
.overdue-task-date {
font-size: 12px;
color: #666;
margin-left: auto;
}
.section-header {
display: flex;
align-items: center;

View File

@ -11,7 +11,7 @@ export const Request = () => {
uni.$uv.http.setConfig((config) => {
/* config 为默认全局配置*/
config.baseURL = 'http://192.168.1.4:4001'; /* 根域名 */
// config.baseURL = 'https://pm.ccttiot.com/prod-api'; /* 根域名 */
config.baseURL = 'https://pm.ccttiot.com/prod-api'; /* 根域名 */
return config
})