feat(版本): 优化概览与只读状态

关键改动:

- 增加需求排序和版本只读状态规则及测试

- 完善版本概览阶段耗时、项目页和工作台展示

- 优化小宝预警请求节流、建议状态和风险过滤

Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
Script Generator
2026-06-30 18:18:18 +08:00
parent 3d3d56697a
commit eef3c8f000
32 changed files with 1072 additions and 289 deletions

View File

@@ -27,9 +27,10 @@ interface Props {
bugId: string;
onClose: () => void;
contextLabel?: string;
readOnly?: boolean;
}
export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
export function BugDetailDrawer({ bugId, onClose, contextLabel, readOnly = false }: Props) {
const { bugs, changeStatus, transferBug } = useBugStore();
const { testCases } = useTestCaseStore();
const { requirements } = useRequirementStore();
@@ -73,16 +74,19 @@ export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
}, [bug.logs, bug.title, members]);
const handleTransition = (to: BugStatus) => {
if (readOnly) return;
if (to === 'fixed') { setShowResolutionInput(true); return; }
changeStatus(bug.id, to, operator);
};
const confirmFix = () => {
if (readOnly) return;
changeStatus(bug.id, 'fixed', operator, { resolution: resolution.trim() || undefined });
setShowResolutionInput(false);
};
const handleTransfer = () => {
if (readOnly) return;
if (!transferTo) return;
transferBug(bug.id, transferTo, operator, transferRemark.trim() || undefined);
setShowTransfer(false);
@@ -135,7 +139,7 @@ export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
<span className="text-[11px] text-[var(--ink-muted)]">{bug.priority}</span>
</div>
{nextStatuses.length > 0 && !showResolutionInput && isCurrentAssignee && (
{nextStatuses.length > 0 && !showResolutionInput && isCurrentAssignee && !readOnly && (
<div className="flex items-center gap-2 pt-1 flex-wrap">
<ChevronRight className="h-3.5 w-3.5 text-[var(--ink-muted)]" />
{nextStatuses.map((s) => (
@@ -150,11 +154,11 @@ export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
)}
</div>
)}
{nextStatuses.length > 0 && !showResolutionInput && !isCurrentAssignee && (
{nextStatuses.length > 0 && !showResolutionInput && !isCurrentAssignee && !readOnly && (
<div className="text-[11px] text-[var(--ink-muted)] pt-1"> {assigneeName}</div>
)}
{showResolutionInput && (
{showResolutionInput && !readOnly && (
<div className="space-y-2 pt-1">
<input value={resolution} onChange={(e) => setResolution(e.target.value)} placeholder="修复说明" className="h-8 w-full rounded-lg border border-[var(--line)] px-3 text-[12px] focus:border-[var(--accent)] focus:outline-none" autoFocus />
<div className="flex gap-2">
@@ -164,7 +168,7 @@ export function BugDetailDrawer({ bugId, onClose, contextLabel }: Props) {
</div>
)}
{showTransfer && (
{showTransfer && !readOnly && (
<div className="space-y-2 pt-1 border-t border-[var(--line)]">
<div className="text-[11px] text-[var(--ink-muted)]"></div>
<FilterSelect

View File

@@ -22,9 +22,10 @@ import type { BugStatus, BugSeverity } from '@/lib/bug';
interface Props {
versionId: string;
requirementIds: string[];
readOnly?: boolean;
}
export function BugTab({ versionId, requirementIds }: Props) {
export function BugTab({ versionId, requirementIds, readOnly = false }: Props) {
const { bugs, fetchBugs } = useBugStore();
const { testCases, fetchTestCases } = useTestCaseStore();
const { requirements } = useRequirementStore();
@@ -159,7 +160,7 @@ export function BugTab({ versionId, requirementIds }: Props) {
{total > 20 && <Pagination total={total} page={page} pageSize={pageSize} onChange={setPage} onPageSizeChange={setPageSize} />}
{selectedBugId && <BugDetailDrawer bugId={selectedBugId} onClose={() => setSelectedBugId(null)} />}
{selectedBugId && <BugDetailDrawer bugId={selectedBugId} readOnly={readOnly} onClose={() => setSelectedBugId(null)} />}
</div>
);
}