接口获取任务详细

This commit is contained in:
WindowBird 2025-11-06 15:27:11 +08:00
parent 3c83302384
commit 881f8b990e
2 changed files with 273 additions and 21 deletions

View File

@ -72,3 +72,16 @@ export const getTaskList = ({ overdue, statusList, expireTimeStart, expireTimeEn
});
};
/**
* 获取任务详情
* @param {string} id 任务ID
* @returns {Promise} 返回任务详情
*/
export const getTaskDetail = (id) => {
return uni.$uv.http.get(`bst/task/${id}`, {
custom: {
auth: true // 启用 token 认证
}
});
};

View File

@ -29,7 +29,15 @@
</view>
<view class="info-item">
<text class="info-label">创建人</text>
<text class="info-value">{{ task.creator }}</text>
<view class="info-value-with-avatar">
<image
v-if="task.creatorAvatar"
:src="task.creatorAvatar"
class="creator-avatar"
mode="aspectFill"
/>
<text>{{ task.creator }}</text>
</view>
</view>
<view class="info-item">
<text class="info-label">负责人</text>
@ -81,7 +89,13 @@
<view class="submit-record-card" v-for="(record, index) in task.submitRecords" :key="index">
<view class="record-header">
<view class="user-info">
<view class="avatar-placeholder"></view>
<image
v-if="record.userAvatar"
:src="record.userAvatar"
class="avatar-img"
mode="aspectFill"
/>
<view v-else class="avatar-placeholder"></view>
<text class="user-name">{{ record.userName }}</text>
</view>
<view class="record-header-right">
@ -150,6 +164,7 @@ import { ref, onMounted, } from 'vue';
import { onLoad,onShow } from '@dcloudio/uni-app';
import { getStatusFromTagText, getTaskStatusType, getTaskStatusStyle } from '@/utils/taskConfig.js';
import { useTaskStore } from '@/store/task';
import { getTaskDetail } from '@/common/api.js';
//
const activeTab = ref('info');
@ -157,10 +172,12 @@ const showMenuIndex = ref(-1);
//
const formatTimeToChinese = (date) => {
if (!date) return '';
if (typeof date === 'string') {
//
date = new Date(date);
}
if (isNaN(date.getTime())) return '';
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
@ -173,6 +190,152 @@ const formatTimeToChinese = (date) => {
return `${year}${month}${day}${weekday} ${hour}:${minute}:${second}`;
};
// "2024-10-31 23:59:59" "2024-10-31"
const formatDate = (dateStr) => {
if (!dateStr) return '';
//
return dateStr.split(' ')[0];
};
// yyyy-MM-dd HH:mm:ss
const formatDateTime = (date) => {
if (!date) return '';
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
//
const calculateRemainingDays = (expireTime) => {
if (!expireTime) return null;
const expireDate = new Date(expireTime);
const now = new Date();
now.setHours(0, 0, 0, 0);
expireDate.setHours(0, 0, 0, 0);
const diffTime = expireDate.getTime() - now.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
};
//
const determineTaskStatus = (status, expireTime) => {
// 4 completed
const taskStatus = status !== undefined ? status : null;
const isCompleted = taskStatus === 4 ||
taskStatus === '4' ||
taskStatus === 'completed' ||
String(taskStatus) === '4';
if (isCompleted) {
return 'completed';
}
//
if (!expireTime) {
return 'pending';
}
const expireDate = new Date(expireTime);
const now = new Date();
// 0便
now.setHours(0, 0, 0, 0);
expireDate.setHours(23, 59, 59, 999);
//
if (expireDate.getTime() < now.getTime()) {
return 'overdue';
}
//
const diffTime = expireDate.getTime() - now.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
// 3
if (diffDays <= 3 && diffDays > 0) {
return 'imminent';
}
//
return 'pending';
};
//
const getStatusTags = (status, expireTime) => {
const taskStatus = determineTaskStatus(status, expireTime);
const tags = [];
if (taskStatus === 'completed') {
tags.push('已完成');
} else if (taskStatus === 'overdue') {
tags.push('已逾期', '紧急');
} else if (taskStatus === 'imminent') {
tags.push('即将逾期');
} else {
tags.push('待完成');
}
return tags;
};
// memberList
const getOwnerNames = (memberList) => {
if (!Array.isArray(memberList) || memberList.length === 0) return '';
return memberList.map(member => member.userName || member.name || '').filter(name => name).join('、');
};
//
const transformSubmitRecords = (submitList) => {
if (!Array.isArray(submitList) || submitList.length === 0) {
return [];
}
return submitList.map(item => {
//
let attachments = [];
if (item.attaches) {
try {
// attaches
const attachData = typeof item.attaches === 'string' ? JSON.parse(item.attaches) : item.attaches;
if (Array.isArray(attachData)) {
attachments = attachData.map(att => {
//
const fileName = att.name || att.fileName || '';
const filePath = att.path || att.url || att.filePath || '';
const isImage = /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(fileName);
return {
type: isImage ? 'image' : 'file',
name: fileName,
path: filePath
};
});
}
} catch (e) {
console.error('解析附件数据失败:', e);
}
}
return {
id: item.id || '',
userName: item.userName || '',
userAvatar: item.userAvatar || '',
time: formatTimeToChinese(item.createTime) || '',
content: item.remark || item.description || item.taskDescription || '', //
progress: null, // API
attachments: attachments,
showDelayBtn: false, //
canEdit: true //
};
});
};
//
const task = ref({
@ -308,13 +471,59 @@ const applyDelay = () => {
});
};
//
const loadTaskData = (taskId) => {
// taskId API
// 使
if (taskId) {
// taskId
console.log('加载任务数据:', taskId);
//
const loadTaskData = async (taskId) => {
if (!taskId) {
uni.showToast({
title: '任务ID不能为空',
icon: 'none'
});
return;
}
try {
//
uni.showLoading({
title: '加载中...'
});
// API
const res = await getTaskDetail(taskId);
console.log('任务详情数据:', res);
//
const taskStatus = res.status !== undefined ? res.status : null;
const expireTime = res.expireTime || null;
const statusTags = getStatusTags(taskStatus, expireTime);
//
const submitRecords = transformSubmitRecords(res.submitList || []);
//
task.value = {
id: res.id || taskId,
name: res.description || '任务名称',
project: res.projectName || '',
statusTags: statusTags,
deadline: expireTime ? expireTime : '无',
creator: res.createName || '',
creatorAvatar: res.createAvatar || '',
responsible: getOwnerNames(res.memberList || []),
publishTime: res.createTime ? formatTimeToChinese(res.createTime) : '',
content: res.description || '',
submitRecords: submitRecords,
// 使
rawData: res
};
uni.hideLoading();
} catch (err) {
console.error('加载任务详情失败:', err);
uni.hideLoading();
uni.showToast({
title: '加载任务详情失败',
icon: 'none'
});
}
};
@ -323,19 +532,26 @@ onLoad((options) => {
const taskId = options.id || options.taskId;
if (taskId) {
task.value.id = taskId;
// API
loadTaskData(taskId);
}
// Pinia store
const taskStore = useTaskStore();
const storedTask = taskStore.getTaskDetail;
if (storedTask) {
task.value = {
...task.value,
...storedTask
};
// store 使
// taskStore.clearTaskDetail();
} else {
// taskId Pinia store
const taskStore = useTaskStore();
const storedTask = taskStore.getTaskDetail;
if (storedTask) {
task.value = {
...task.value,
...storedTask
};
} else {
uni.showToast({
title: '缺少任务ID',
icon: 'none'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
}
});
@ -596,6 +812,29 @@ onShow(() => {
flex-shrink: 0;
}
.avatar-img {
width: 32px;
height: 32px;
border-radius: 50%;
flex-shrink: 0;
}
.info-value-with-avatar {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #333;
}
.creator-avatar {
width: 24px;
height: 24px;
border-radius: 50%;
flex-shrink: 0;
}
.user-name {
font-size: 15px;
color: #333;