fix(产品管理、项目管理、登录密码校验、工作报告): 修复用户们提出的一系列问题。
This commit is contained in:
@@ -558,7 +558,9 @@ function resolveTaskMetrics(metricsText: string, fallback?: Partial<StructuredTa
|
||||
.filter(Boolean);
|
||||
const priorityText = metricsText.match(/\bP\d+\b/iu)?.[0] || metricParts.find(item => /^P?\d+$/iu.test(item));
|
||||
const priority = normalizePriorityCode(priorityText || (useFallback ? fallback?.priority : undefined));
|
||||
const progressText = metricsText.match(/进度\s*(\d+(?:\.\d+)?)%/u)?.[1];
|
||||
const progressText =
|
||||
metricsText.match(/进度\s*(\d+(?:\.\d+)?)%/u)?.[1] ||
|
||||
metricParts.find(item => /^\d+(?:\.\d+)?%$/u.test(item))?.replace(/%$/u, '');
|
||||
const hoursText = metricsText.match(/(\d+(?:\.\d+)?)h/u)?.[1];
|
||||
|
||||
return {
|
||||
@@ -591,7 +593,7 @@ function toReviewItem(item: Api.WorkReport.Common.PersonalReportReviewItem): Rev
|
||||
: escapeHtml(item.contentText || '').replace(/\n/g, '<br>') || EMPTY_TEXT,
|
||||
contentSections,
|
||||
reflection: item.reflectionText || '',
|
||||
removable: false,
|
||||
removable: true,
|
||||
source: item
|
||||
};
|
||||
}
|
||||
@@ -728,6 +730,13 @@ function removePlanItem(index: number) {
|
||||
if (item?.sourceIndex !== undefined) props.model.planItems.splice(item.sourceIndex, 1);
|
||||
}
|
||||
|
||||
function removeReviewItem(index: number) {
|
||||
const item = reviewItems.value[index];
|
||||
if (!item?.source) return;
|
||||
const sourceIndex = props.model.reviewItems.indexOf(item.source);
|
||||
if (sourceIndex >= 0) props.model.reviewItems.splice(sourceIndex, 1);
|
||||
}
|
||||
|
||||
function focusEditField(key: string) {
|
||||
activeEditField.value = key;
|
||||
}
|
||||
@@ -736,9 +745,19 @@ function blurEditField(key: string) {
|
||||
if (activeEditField.value === key) activeEditField.value = '';
|
||||
}
|
||||
|
||||
function isStructuredEditorUnchanged(text: string, sections: StructuredSection[] | undefined, showHours = false) {
|
||||
if (!sections?.length) return false;
|
||||
return normalizeEditorText(text) === createStructuredTextV2(sections, showHours);
|
||||
}
|
||||
|
||||
function syncRichContent(item: ReviewItem, event: Event) {
|
||||
const target = event.currentTarget as HTMLElement;
|
||||
if (!item.source) return;
|
||||
if (isStructuredEditorUnchanged(target.innerText, item.contentSections, true)) {
|
||||
item.source.contentJson = createSectionsJson(item.contentSections || []);
|
||||
item.source.contentText = createStructuredTextV2(item.contentSections || [], true);
|
||||
return;
|
||||
}
|
||||
const sections = parseStructuredSectionsFromEditorV2(
|
||||
target,
|
||||
item.contentSections || [],
|
||||
@@ -751,6 +770,11 @@ function syncRichContent(item: ReviewItem, event: Event) {
|
||||
function syncRichTarget(item: PlanItem, event: Event) {
|
||||
const target = event.currentTarget as HTMLElement;
|
||||
if (!item.source) return;
|
||||
if (isStructuredEditorUnchanged(target.innerText, item.targetSections)) {
|
||||
item.source.targetJson = createSectionsJson(item.targetSections || []);
|
||||
item.source.targetText = createStructuredTextV2(item.targetSections || []);
|
||||
return;
|
||||
}
|
||||
const sections = parseStructuredSectionsFromEditorV2(
|
||||
target,
|
||||
item.targetSections || [],
|
||||
@@ -836,7 +860,7 @@ function syncRichSupport(item: PlanItem, event: Event) {
|
||||
confirm-button-text="删除"
|
||||
cancel-button-text="取消"
|
||||
width="220"
|
||||
@confirm="reviewItems.splice(index, 1)"
|
||||
@confirm="removeReviewItem(index)"
|
||||
>
|
||||
<template #reference>
|
||||
<button class="item-remove-btn" aria-label="删除回顾">×</button>
|
||||
|
||||
@@ -127,7 +127,7 @@ function toWorkItem(item: Api.WorkReport.Project.ProjectReportItem, index: numbe
|
||||
}
|
||||
|
||||
const currentWorks = computed<WorkItem[]>(() => {
|
||||
return (props.model.currentItems || []).map((item, index) => toWorkItem(item, index, false));
|
||||
return (props.model.currentItems || []).map((item, index) => toWorkItem(item, index, true));
|
||||
});
|
||||
|
||||
const nextPlans = computed<WorkItem[]>(() => {
|
||||
@@ -273,6 +273,11 @@ function removePlanItem(index: number) {
|
||||
if (item?.sourceIndex !== undefined) props.model.nextItems.splice(item.sourceIndex, 1);
|
||||
}
|
||||
|
||||
function removeCurrentWorkItem(index: number) {
|
||||
const item = currentWorks.value[index];
|
||||
if (item?.sourceIndex !== undefined) props.model.currentItems.splice(item.sourceIndex, 1);
|
||||
}
|
||||
|
||||
function startTitleEdit(item: WorkItem) {
|
||||
titleEditSnapshot.value[item.id] = item.title;
|
||||
}
|
||||
@@ -288,9 +293,9 @@ function notifyTitleSaved(item: WorkItem) {
|
||||
item.title = nextTitle;
|
||||
if (item.source) item.source.itemTitle = nextTitle;
|
||||
delete titleEditSnapshot.value[item.id];
|
||||
if (nextTitle !== previousTitle) {
|
||||
ElMessage.success('名称已成功修改');
|
||||
}
|
||||
// if (nextTitle !== previousTitle) {
|
||||
// ElMessage.success('名称已成功修改');
|
||||
// }
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -373,7 +378,7 @@ function notifyTitleSaved(item: WorkItem) {
|
||||
<div class="review-grid layout-row">
|
||||
<div v-if="!currentWorks.length">{{ EMPTY_TEXT }}</div>
|
||||
<div v-for="(item, index) in currentWorks" :key="item.id" class="review-card compact-work-card">
|
||||
<div class="review-card-head">
|
||||
<div class="review-card-head" :class="{ 'no-remove': item.removable === false }">
|
||||
<span class="row-index">{{ index + 1 }}</span>
|
||||
<div class="review-title-readonly">
|
||||
<div class="work-title-line">
|
||||
@@ -390,6 +395,18 @@ function notifyTitleSaved(item: WorkItem) {
|
||||
<span class="meta-chip">共 {{ item.hours }}h</span>
|
||||
</div>
|
||||
</div>
|
||||
<ElPopconfirm
|
||||
v-if="item.removable !== false && !isReadonly"
|
||||
title="确认删除这条工作内容吗?"
|
||||
confirm-button-text="删除"
|
||||
cancel-button-text="取消"
|
||||
width="220"
|
||||
@confirm="removeCurrentWorkItem(index)"
|
||||
>
|
||||
<template #reference>
|
||||
<button class="item-remove-btn" aria-label="删除工作内容">×</button>
|
||||
</template>
|
||||
</ElPopconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -727,10 +744,7 @@ function notifyTitleSaved(item: WorkItem) {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.review-card-head {
|
||||
grid-template-columns: 28px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.review-card-head.no-remove,
|
||||
.plan-card-head.no-remove {
|
||||
grid-template-columns: 28px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
@@ -725,7 +725,7 @@ function toReviewItem(item: Api.WorkReport.Common.PersonalReportReviewItem): Rev
|
||||
contentSections,
|
||||
contentTasks,
|
||||
reflection: item.reflectionText || '',
|
||||
removable: false,
|
||||
removable: true,
|
||||
source: item
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user