From 9d07f88e8caa8e54f7ee427ae31c786d5c14b9bd Mon Sep 17 00:00:00 2001 From: kuaifan Date: Wed, 28 Oct 2026 13:03:01 +0000 Subject: [PATCH] =?UTF-8?q?perf(task):=20=E7=A7=BB=E5=8A=A8=E7=AB=AF?= =?UTF-8?q?=E6=89=93=E5=BC=80=E4=BB=BB=E5=8A=A1=E8=AF=A6=E6=83=85=E6=97=B6?= =?UTF-8?q?=E5=85=88=E6=92=AD=E6=94=BE=E6=89=93=E5=BC=80=E5=8A=A8=E7=94=BB?= =?UTF-8?q?=E5=86=8D=E6=8C=82=E8=BD=BD=E5=86=85=E5=AE=B9=EF=BC=8C=E6=8C=82?= =?UTF-8?q?=E8=BD=BD=E5=89=8D=E6=98=BE=E7=A4=BA=E4=BB=BB=E5=8A=A1=E5=A4=B4?= =?UTF-8?q?=E9=83=A8=E3=80=81=E6=A0=87=E9=A2=98=E4=B8=8E=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E9=AA=A8=E6=9E=B6=E5=8D=A0=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../js/pages/manage/components/TaskModal.vue | 113 +++++++++++++++++- .../sass/pages/components/task-detail.scss | 95 +++++++++++++++ 2 files changed, 205 insertions(+), 3 deletions(-) diff --git a/resources/assets/js/pages/manage/components/TaskModal.vue b/resources/assets/js/pages/manage/components/TaskModal.vue index 2367409d5..6f8efb68c 100644 --- a/resources/assets/js/pages/manage/components/TaskModal.vue +++ b/resources/assets/js/pages/manage/components/TaskModal.vue @@ -8,7 +8,73 @@ :fullscreen="windowPortrait" :beforeClose="onBeforeClose" class-name="common-task-modal"> - + + +
+
+
+
+ + +
+
+ {{taskData.flow_item_name}} +
+
+ {{$L('已归档')}} +
+ +
+ +
+
+
+
+
{{taskData.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -21,14 +87,44 @@ export default { name: "TaskModal", components: {TaskDetail}, + data() { + return { + contentReady: false, + } + }, + computed: { - ...mapState(['taskId']), + ...mapState(['taskId', 'cacheProjects', 'cacheColumns']), ...mapGetters(['taskData']), show() { return this.taskId > 0 }, + projectName() { + const {project_id, project_name} = this.taskData + if (!project_id) { + return '' + } + if (project_name) { + return project_name + } + const project = this.cacheProjects.find(({id}) => id == project_id) + return project ? project.name : '' + }, + + columnName() { + const {column_id, column_name} = this.taskData + if (!column_id) { + return '' + } + if (column_name) { + return column_name + } + const column = this.cacheColumns.find(({id}) => id == column_id) + return column ? column.name : '' + }, + styles() { return this.windowPortrait ? { width: '100%', @@ -42,6 +138,17 @@ export default { watch: { show(v) { $A.eeuiAppSetScrollDisabled(v && this.windowPortrait) + if (v) { + if (!this.windowPortrait) { + this.contentReady = true + return + } + // 任务详情渲染较重,等打开动画开始(交由合成线程执行)后再挂载,避免动画首帧被阻塞 + this.contentReady = false + requestAnimationFrame(_ => requestAnimationFrame(_ => { + this.contentReady = this.show + })) + } } }, @@ -61,7 +168,7 @@ export default { }, checkUpdate() { if (this.show) { - this.$refs.taskDetail.checkUpdate(true); + this.$refs.taskDetail?.checkUpdate(true); return true; } }, diff --git a/resources/assets/sass/pages/components/task-detail.scss b/resources/assets/sass/pages/components/task-detail.scss index 7f8a2fd5e..6fca52575 100644 --- a/resources/assets/sass/pages/components/task-detail.scss +++ b/resources/assets/sass/pages/components/task-detail.scss @@ -1187,3 +1187,98 @@ body.window-portrait { } } } + +// 任务详情挂载前的占位与骨架(见 TaskModal.vue) +.task-detail-placeholder { + .task-info { + .scroller { + flex: 1; + padding: 0 5px; + .title { + .placeholder-title { + font-weight: 500; + font-size: 24px; + padding: 5px 1px; + line-height: 1.4; + color: #606266; + word-break: break-all; + } + } + .placeholder-skeleton { + // 尺寸与 TaskDetail 真实布局对齐(描述每行 24px、属性行 36px + 10px 间距),加载完成时不跳动 + padding: 10px 1px 0; + animation: task-skeleton-animation 1.4s ease-in-out infinite; + .skeleton-line, + .skeleton-label, + .skeleton-tag, + .skeleton-avatar { + flex-shrink: 0; + background-color: #f0f0f0; + } + .skeleton-line, + .skeleton-label { + height: 12px; + border-radius: 6px; + } + .skeleton-desc { + // 每行占 24px,与描述行高一致 + margin-bottom: 12px; + .skeleton-line { + margin: 6px 0; + } + } + .skeleton-add { + display: flex; + align-items: center; + height: 38px; + margin-top: 12px; + } + .skeleton-row { + display: flex; + align-items: center; + height: 36px; + padding-left: 107px; + position: relative; + & + .skeleton-row { + margin-top: 10px; + } + .skeleton-label { + position: absolute; + top: 12px; + left: 0; + } + .skeleton-tag { + width: 72px; + height: 22px; + border-radius: 4px; + } + .skeleton-avatar { + width: 26px; + height: 26px; + margin-right: 6px; + border-radius: 50%; + } + &.multi { + height: 54px; + align-items: flex-start; + .skeleton-values { + padding-top: 11px; + .skeleton-line + .skeleton-line { + margin-top: 12px; + } + } + } + } + } + } + } +} + +@keyframes task-skeleton-animation { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.7; + } +}