优化日报模块

This commit is contained in:
hero920103 committed 2026-10-22 00:27:26 +08:00
1 parent 79d5ae6b66
commit 51fd90fc51
17 files changed
+1767 -257

No files matched your search

@@ -25,7 +25,25 @@
</div>
<div class="head-actions">
<el-button
v-if="detail.can_edit"
v-if="detail.report.status === 0 && detail.can_edit"
link
type="success"
:loading="submittingReport"
@click="handleSubmitReport"
>
提交
</el-button>
<el-button
v-if="detail.report.status === 1 && detail.can_withdraw"
link
type="warning"
:loading="withdrawing"
@click="handleWithdraw"
>
撤销提交
</el-button>
<el-button
v-if="detail.report.status === 0 && detail.can_edit"
link
type="primary"
@click="$emit('edit', detail.report)"
@@ -33,7 +51,7 @@
编辑
</el-button>
<el-button
v-if="detail.can_delete"
v-if="detail.report.status === 0 && detail.can_delete"
link
type="danger"
@click="handleDeleteReport"
@@ -43,6 +61,13 @@
</div>
</div>
<div
v-if="detail.is_author && detail.report.status === 1 && !detail.can_withdraw"
class="lock-tip"
>
日报已提交并锁定;超出补写窗口后不再支持撤销提交
</div>
<section class="detail-section">
<h4>今日完成</h4>
<div class="section-text">{{ detail.report.today_done || '—' }}</div>
@@ -74,6 +99,29 @@
</div>
</section>
<section v-if="detail.histories?.length" class="detail-section">
<h4>修改痕迹 <span class="comment-count">{{ detail.histories.length }}</span></h4>
<div class="history-list">
<div v-for="h in detail.histories" :key="h.id" class="history-item">
<div class="history-head">
<el-tag
:type="h.action === 2 ? 'success' : 'warning'"
size="small"
effect="plain"
>
{{ h.action === 2 ? '重新提交' : '撤销提交' }}
</el-tag>
<span class="history-time">{{ h.create_time }}</span>
</div>
<div class="history-text">
<div><span class="history-label">今日完成:</span>{{ h.today_done || '—' }}</div>
<div><span class="history-label">明日计划:</span>{{ h.tomorrow_plan || '—' }}</div>
<div><span class="history-label">问题与建议:</span>{{ h.issues || '—' }}</div>
</div>
</div>
</div>
</section>
<section class="detail-section comment-section">
<h4>评论 <span class="comment-count">{{ detail.comments.length }}</span></h4>
@@ -155,6 +203,8 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { Paperclip } from '@element-plus/icons-vue'
import {
getDailyReportDetail,
saveDailyReport,
withdrawDailyReport,
addDailyReportComment,
deleteDailyReportComment,
deleteDailyReport
@@ -171,6 +221,8 @@ const detail = ref(null)
const commentText = ref('')
const replyTo = ref(null)
const submitting = ref(false)
const submittingReport = ref(false)
const withdrawing = ref(false)
watch(
() => props.reportId,
@@ -201,6 +253,62 @@ function startReply(comment) {
replyTo.value = { id: comment.id, user_name: comment.user_name }
}
// 草稿直接在详情页提交:提交后内容锁定,需撤销提交才能再改。
async function handleSubmitReport() {
try {
await ElMessageBox.confirm(
'提交后日报将锁定,如需修改需先撤销提交。确定提交这条日报吗?',
'提交日报',
{ type: 'warning', confirmButtonText: '提交', cancelButtonText: '取消' }
)
} catch {
return
}
submittingReport.value = true
try {
const report = detail.value.report
await saveDailyReport({
date: report.report_date,
today_done: report.today_done || '',
tomorrow_plan: report.tomorrow_plan || '',
issues: report.issues || '',
attachments: JSON.stringify(report.attachments || []),
submit: true
})
ElMessage.success('日报已提交')
await loadDetail()
emit('changed')
} catch (err) {
ElMessage.error(err?.message || '提交失败')
} finally {
submittingReport.value = false
}
}
// 撤销提交:退回草稿并留存修改痕迹,修改后可重新提交。
async function handleWithdraw() {
try {
await ElMessageBox.confirm(
'撤销提交后日报退回草稿,本次提交的内容会作为修改痕迹保留,修改完成后需重新提交。确定撤销吗?',
'撤销提交',
{ type: 'warning', confirmButtonText: '撤销提交', cancelButtonText: '取消' }
)
} catch {
return
}
withdrawing.value = true
try {
await withdrawDailyReport(props.reportId)
ElMessage.success('已撤销提交,可修改后重新提交')
await loadDetail()
emit('changed')
} catch (err) {
ElMessage.error(err?.message || '撤销提交失败')
} finally {
withdrawing.value = false
}
}
async function submitComment() {
const content = commentText.value.trim()
if (!content) {
@@ -321,6 +429,53 @@ function formatSize(size) {
gap: 4px;
}
.lock-tip {
margin-top: 10px;
padding: 8px 12px;
border-radius: 6px;
background: var(--el-color-warning-light-9, #fdf6ec);
font-size: 12px;
color: var(--el-color-warning, #e6a23c);
}
.history-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.history-item {
padding: 10px 12px;
border: 1px dashed #ebeef5;
border-radius: 6px;
background: #fafafa;
}
.history-head {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
}
.history-time {
margin-left: auto;
color: #c0c4cc;
}
.history-text {
margin-top: 6px;
font-size: 13px;
line-height: 1.7;
color: #606266;
white-space: pre-wrap;
word-break: break-word;
}
.history-label {
color: #909399;
}
.detail-section {
padding: 14px 0;
border-bottom: 1px dashed #ebeef5;
@@ -470,10 +625,24 @@ html.dark & {
.comment-time,
.file-size,
.comment-disabled,
.history-label,
.reply-banner {
color: var(--el-text-color-secondary);
}
.history-item {
background: var(--el-fill-color-light);
border-color: var(--el-border-color-lighter);
}
.history-text {
color: var(--el-text-color-regular);
}
.lock-tip {
background: var(--el-color-warning-light-9);
}
.attachment-item,
.comment-item {
background: var(--el-fill-color-light);