import type { MesPdArchiveApi } from '#/api/mes/pd/archive';
|
import type { MesPdBomApi } from '#/api/mes/pd/bom';
|
import type { MesPdDocumentApi } from '#/api/mes/pd/document';
|
import type { MesPdDrawingReviewApi } from '#/api/mes/pd/drawing-review';
|
import type { MesPdProjectApi } from '#/api/mes/pd/project';
|
import type { MesPdTaskApi } from '#/api/mes/pd/task';
|
import type { MesPdVersionChangeApi } from '#/api/mes/pd/version-change';
|
import type { MesPdWorkflowApi } from '#/api/mes/pd/workflow';
|
|
import { MesPdDrawingReviewStatusEnum, MesPdDocumentTypeEnum, MesPdProjectStatusEnum } from '#/packages/constants/src';
|
|
import {
|
pdMockArchives,
|
pdMockBomLines,
|
pdMockDocuments,
|
pdMockDrawingReviews,
|
pdMockProjects,
|
pdMockSeq,
|
pdMockTasks,
|
pdMockVersionChanges,
|
pdMockWorkflows,
|
} from './seed';
|
import { mockDelay, mockNextCode, mockPage } from './utils';
|
|
function matchLike(value: unknown, keyword?: string): boolean {
|
if (!keyword) {
|
return true;
|
}
|
return String(value ?? '')
|
.toLowerCase()
|
.includes(String(keyword).toLowerCase());
|
}
|
|
function syncProjectRef(project: MesPdProjectApi.Project) {
|
const ref = {
|
projectCode: project.code,
|
projectName: project.name,
|
productCode: project.productCode,
|
productName: project.productName,
|
version: project.version,
|
};
|
pdMockTasks.forEach((task) => {
|
if (task.projectId === project.id) {
|
Object.assign(task, ref);
|
}
|
});
|
pdMockDrawingReviews.forEach((item) => {
|
if (item.projectId === project.id) {
|
Object.assign(item, ref);
|
}
|
});
|
pdMockVersionChanges.forEach((item) => {
|
if (item.projectId === project.id) {
|
Object.assign(item, ref);
|
}
|
});
|
}
|
|
const WORKFLOW_STEPS = [
|
'发起任务',
|
'发布任务',
|
'上传资料',
|
'资料审核',
|
'归档',
|
] as const;
|
|
function initWorkflow(projectId: number, designerName?: string) {
|
pdMockWorkflows[projectId] = WORKFLOW_STEPS.map((nodeName, index) => ({
|
id: projectId * 10 + index,
|
projectId,
|
nodeName,
|
operatorName: index === 0 ? designerName : undefined,
|
status: index === 0 ? 1 : 0,
|
operateTime: index === 0 ? Date.now() : undefined,
|
}));
|
}
|
|
function advanceWorkflow(projectId: number, completedStep: string, operatorName?: string) {
|
const nodes = pdMockWorkflows[projectId];
|
if (!nodes) {
|
return;
|
}
|
const completedIndex = nodes.findIndex((n) => n.nodeName === completedStep);
|
if (completedIndex >= 0) {
|
nodes[completedIndex]!.status = 1;
|
nodes[completedIndex]!.operateTime = Date.now();
|
if (operatorName) {
|
nodes[completedIndex]!.operatorName = operatorName;
|
}
|
}
|
const next = nodes[completedIndex + 1];
|
if (next) {
|
next.status = 2;
|
if (operatorName) {
|
next.operatorName = operatorName;
|
}
|
}
|
}
|
|
function createDocumentReviews(projectId: number, project: MesPdProjectApi.Project) {
|
const docs = pdMockDocuments.filter((d) => d.projectId === projectId);
|
for (const doc of docs) {
|
const exists = pdMockDrawingReviews.some((r) => r.documentId === doc.id);
|
if (exists) {
|
continue;
|
}
|
const reviewId = pdMockSeq.drawingReview++;
|
pdMockDrawingReviews.push({
|
id: reviewId,
|
code: mockNextCode('DR-2026', reviewId),
|
projectId,
|
projectCode: project.code,
|
projectName: project.name,
|
documentId: doc.id,
|
documentName: doc.name,
|
documentVersion: doc.version,
|
reviewerName: project.reviewerName,
|
status: MesPdDrawingReviewStatusEnum.PENDING,
|
createTime: Date.now(),
|
});
|
}
|
}
|
|
export const pdMockStore = {
|
// ---------- 设计项目 ----------
|
getProjectPage(params: MesPdProjectApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockProjects, params, (item) => {
|
return (
|
matchLike(item.code, params.code) &&
|
matchLike(item.name, params.name) &&
|
matchLike(item.productCode, params.productCode) &&
|
(params.status === undefined || item.status === params.status)
|
);
|
}),
|
);
|
},
|
|
getProject(id: number) {
|
const project = pdMockProjects.find((item) => item.id === id);
|
if (!project) {
|
return Promise.reject(new Error('设计任务不存在'));
|
}
|
return mockDelay({ ...project });
|
},
|
|
createProject(data: MesPdProjectApi.Project) {
|
const id = pdMockSeq.project++;
|
const project: MesPdProjectApi.Project = {
|
...data,
|
id,
|
code: data.code || mockNextCode('DT-2026', id),
|
status: MesPdProjectStatusEnum.DRAFT,
|
createTime: Date.now(),
|
};
|
pdMockProjects.unshift(project);
|
initWorkflow(id, project.designerName);
|
return mockDelay(id);
|
},
|
|
updateProject(data: MesPdProjectApi.Project) {
|
const index = pdMockProjects.findIndex((item) => item.id === data.id);
|
if (index < 0) {
|
return Promise.reject(new Error('设计任务不存在'));
|
}
|
pdMockProjects[index] = { ...pdMockProjects[index], ...data };
|
syncProjectRef(pdMockProjects[index]!);
|
return mockDelay(undefined);
|
},
|
|
deleteProject(id: number) {
|
const index = pdMockProjects.findIndex((item) => item.id === id);
|
if (index >= 0) {
|
pdMockProjects.splice(index, 1);
|
}
|
return mockDelay(undefined);
|
},
|
|
publishProject(id: number) {
|
const project = pdMockProjects.find((item) => item.id === id);
|
if (!project || project.status !== MesPdProjectStatusEnum.DRAFT) {
|
return Promise.reject(new Error('仅草稿状态可发布'));
|
}
|
project.status = MesPdProjectStatusEnum.DESIGNING;
|
advanceWorkflow(id, '发起任务', project.designerName);
|
advanceWorkflow(id, '发布任务', project.designerName);
|
return mockDelay(undefined);
|
},
|
|
submitProjectReview(id: number) {
|
const project = pdMockProjects.find((item) => item.id === id);
|
if (!project || project.status !== MesPdProjectStatusEnum.DESIGNING) {
|
return Promise.reject(new Error('请先发布任务并上传资料'));
|
}
|
const docCount = pdMockDocuments.filter((d) => d.projectId === id).length;
|
if (docCount === 0) {
|
return Promise.reject(new Error('请先上传设计资料'));
|
}
|
project.status = MesPdProjectStatusEnum.REVIEWING;
|
createDocumentReviews(id, project);
|
advanceWorkflow(id, '上传资料', project.designerName);
|
advanceWorkflow(id, '资料审核', project.reviewerName);
|
return mockDelay(undefined);
|
},
|
|
approveProject(id: number) {
|
const project = pdMockProjects.find((item) => item.id === id);
|
if (!project || project.status !== MesPdProjectStatusEnum.REVIEWING) {
|
return Promise.reject(new Error('当前状态不可审核通过'));
|
}
|
const pending = pdMockDrawingReviews.filter(
|
(r) =>
|
r.projectId === id &&
|
r.status === MesPdDrawingReviewStatusEnum.PENDING,
|
);
|
if (pending.length > 0) {
|
return Promise.reject(new Error('尚有资料未完成审核'));
|
}
|
project.status = MesPdProjectStatusEnum.APPROVED;
|
const nodes = pdMockWorkflows[id];
|
const reviewNode = nodes?.find((n) => n.nodeName === '资料审核');
|
if (reviewNode) {
|
reviewNode.status = 1;
|
reviewNode.operateTime = Date.now();
|
}
|
const archiveNode = nodes?.find((n) => n.nodeName === '归档');
|
if (archiveNode) {
|
archiveNode.status = 2;
|
}
|
return mockDelay(undefined);
|
},
|
|
archiveProject(id: number) {
|
const project = pdMockProjects.find((item) => item.id === id);
|
if (!project) {
|
return Promise.reject(new Error('设计任务不存在'));
|
}
|
if (project.status !== MesPdProjectStatusEnum.APPROVED) {
|
return Promise.reject(new Error('仅审核通过的任务可归档'));
|
}
|
project.status = MesPdProjectStatusEnum.ARCHIVED;
|
project.actualFinishDate = Date.now();
|
const archiveId = pdMockSeq.archive++;
|
pdMockArchives.unshift({
|
id: archiveId,
|
code: mockNextCode('AR-2026', archiveId),
|
projectId: project.id,
|
projectCode: project.code,
|
projectName: project.name,
|
productCode: project.productCode,
|
productName: project.productName,
|
version: project.version,
|
archiveStatus: 1,
|
archiveTime: Date.now(),
|
archiverName: project.designerName,
|
documentCount: pdMockDocuments.filter((d) => d.projectId === id).length,
|
bomCount: pdMockDocuments.filter(
|
(d) =>
|
d.projectId === id &&
|
d.documentType === MesPdDocumentTypeEnum.BOM,
|
).length,
|
storagePath: `/archive/2026/${project.productCode}/${project.version}`,
|
createTime: Date.now(),
|
});
|
advanceWorkflow(id, '归档', project.designerName);
|
const archiveNode = pdMockWorkflows[id]?.find((n) => n.nodeName === '归档');
|
if (archiveNode) {
|
archiveNode.status = 1;
|
archiveNode.operateTime = Date.now();
|
}
|
return mockDelay(undefined);
|
},
|
|
// ---------- 归档台账 ----------
|
getArchivePage(params: MesPdArchiveApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockArchives, params, (item) => {
|
return (
|
matchLike(item.code, params.code) &&
|
matchLike(item.projectCode, params.projectCode) &&
|
matchLike(item.productCode, params.productCode) &&
|
(params.archiveStatus === undefined ||
|
item.archiveStatus === params.archiveStatus)
|
);
|
}),
|
);
|
},
|
|
getArchive(id: number) {
|
const archive = pdMockArchives.find((item) => item.id === id);
|
if (!archive) {
|
return Promise.reject(new Error('归档记录不存在'));
|
}
|
return mockDelay({ ...archive });
|
},
|
|
// ---------- 任务 ----------
|
getTaskPage(params: MesPdTaskApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockTasks, params, (item) => {
|
return (
|
item.projectId === params.projectId &&
|
matchLike(item.code, params.code) &&
|
matchLike(item.taskName, params.taskName) &&
|
(params.status === undefined || item.status === params.status)
|
);
|
}),
|
);
|
},
|
|
getTask(id: number) {
|
const task = pdMockTasks.find((item) => item.id === id);
|
if (!task) {
|
return Promise.reject(new Error('设计任务不存在'));
|
}
|
return mockDelay({ ...task });
|
},
|
|
createTask(data: MesPdTaskApi.Task) {
|
const id = pdMockSeq.task++;
|
const project = pdMockProjects.find((p) => p.id === data.projectId);
|
const task: MesPdTaskApi.Task = {
|
...data,
|
id,
|
code: data.code || mockNextCode('TK-2026', id),
|
projectCode: project?.code,
|
projectName: project?.name,
|
status: data.status ?? 0,
|
createTime: Date.now(),
|
};
|
pdMockTasks.unshift(task);
|
return mockDelay(id);
|
},
|
|
updateTask(data: MesPdTaskApi.Task) {
|
const index = pdMockTasks.findIndex((item) => item.id === data.id);
|
if (index < 0) {
|
return Promise.reject(new Error('设计任务不存在'));
|
}
|
pdMockTasks[index] = { ...pdMockTasks[index], ...data };
|
return mockDelay(undefined);
|
},
|
|
deleteTask(id: number) {
|
const index = pdMockTasks.findIndex((item) => item.id === id);
|
if (index >= 0) {
|
pdMockTasks.splice(index, 1);
|
}
|
return mockDelay(undefined);
|
},
|
|
dispatchTask(data: MesPdTaskApi.DispatchParams) {
|
const task = pdMockTasks.find((item) => item.id === data.id);
|
if (task) {
|
task.status = 1;
|
task.planFinishDate = data.planFinishDate;
|
task.remark = data.remark;
|
}
|
return mockDelay(undefined);
|
},
|
|
completeTask(id: number) {
|
const task = pdMockTasks.find((item) => item.id === id);
|
if (task) {
|
task.status = 3;
|
task.actualFinishDate = Date.now();
|
}
|
return mockDelay(undefined);
|
},
|
|
// ---------- 资料 ----------
|
getDocumentPage(params: MesPdDocumentApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockDocuments, params, (item) => {
|
return (
|
item.projectId === params.projectId &&
|
(params.documentType === undefined ||
|
item.documentType === params.documentType) &&
|
(params.version === undefined || item.version === params.version) &&
|
matchLike(item.name, params.name)
|
);
|
}),
|
);
|
},
|
|
getDocument(id: number) {
|
const doc = pdMockDocuments.find((item) => item.id === id);
|
if (!doc) {
|
return Promise.reject(new Error('设计资料不存在'));
|
}
|
return mockDelay({ ...doc });
|
},
|
|
createDocument(data: MesPdDocumentApi.Document) {
|
const id = pdMockSeq.document++;
|
pdMockDocuments.unshift({
|
...data,
|
id,
|
uploaderName: data.uploaderName ?? '当前用户',
|
createTime: Date.now(),
|
});
|
return mockDelay(id);
|
},
|
|
updateDocument(data: MesPdDocumentApi.Document) {
|
const index = pdMockDocuments.findIndex((item) => item.id === data.id);
|
if (index < 0) {
|
return Promise.reject(new Error('设计资料不存在'));
|
}
|
pdMockDocuments[index] = { ...pdMockDocuments[index], ...data };
|
return mockDelay(undefined);
|
},
|
|
deleteDocument(id: number) {
|
const index = pdMockDocuments.findIndex((item) => item.id === id);
|
if (index >= 0) {
|
pdMockDocuments.splice(index, 1);
|
}
|
return mockDelay(undefined);
|
},
|
|
// ---------- BOM ----------
|
getBomPage(params: MesPdBomApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockBomLines, params, (item) => {
|
return (
|
item.projectId === params.projectId &&
|
matchLike(item.itemCode, params.itemCode) &&
|
matchLike(item.itemName, params.itemName)
|
);
|
}),
|
);
|
},
|
|
createBomLine(data: MesPdBomApi.BomLine) {
|
const id = pdMockSeq.bom++;
|
pdMockBomLines.unshift({ ...data, id, createTime: Date.now() });
|
return mockDelay(id);
|
},
|
|
updateBomLine(data: MesPdBomApi.BomLine) {
|
const index = pdMockBomLines.findIndex((item) => item.id === data.id);
|
if (index < 0) {
|
return Promise.reject(new Error('BOM 行不存在'));
|
}
|
pdMockBomLines[index] = { ...pdMockBomLines[index], ...data };
|
return mockDelay(undefined);
|
},
|
|
deleteBomLine(id: number) {
|
const index = pdMockBomLines.findIndex((item) => item.id === id);
|
if (index >= 0) {
|
pdMockBomLines.splice(index, 1);
|
}
|
return mockDelay(undefined);
|
},
|
|
// ---------- 图纸审核 ----------
|
getDrawingReviewPage(params: MesPdDrawingReviewApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockDrawingReviews, params, (item) => {
|
return (
|
item.projectId === params.projectId &&
|
matchLike(item.code, params.code) &&
|
(params.status === undefined || item.status === params.status)
|
);
|
}),
|
);
|
},
|
|
getDrawingReview(id: number) {
|
const row = pdMockDrawingReviews.find((item) => item.id === id);
|
if (!row) {
|
return Promise.reject(new Error('图纸审核单不存在'));
|
}
|
return mockDelay({ ...row });
|
},
|
|
reviewDrawing(data: MesPdDrawingReviewApi.ReviewParams) {
|
const row = pdMockDrawingReviews.find((item) => item.id === data.id);
|
if (row) {
|
row.status = data.status;
|
row.reviewComment = data.reviewComment;
|
row.reviewTime = Date.now();
|
}
|
return mockDelay(undefined);
|
},
|
getVersionChangePage(params: MesPdVersionChangeApi.PageParams) {
|
return mockDelay(
|
mockPage(pdMockVersionChanges, params, (item) => {
|
return (
|
item.projectId === params.projectId &&
|
matchLike(item.code, params.code) &&
|
(params.changeType === undefined ||
|
item.changeType === params.changeType)
|
);
|
}),
|
);
|
},
|
|
getVersionChange(id: number) {
|
const row = pdMockVersionChanges.find((item) => item.id === id);
|
if (!row) {
|
return Promise.reject(new Error('版本变更单不存在'));
|
}
|
return mockDelay({ ...row });
|
},
|
|
createVersionChange(data: MesPdVersionChangeApi.VersionChange) {
|
const id = pdMockSeq.versionChange++;
|
const project = pdMockProjects.find((p) => p.id === data.projectId);
|
pdMockVersionChanges.unshift({
|
...data,
|
id,
|
code: data.code || mockNextCode('VC-2026', id),
|
projectCode: project?.code,
|
projectName: project?.name,
|
applicantName: data.applicantName ?? '当前用户',
|
createTime: Date.now(),
|
});
|
return mockDelay(id);
|
},
|
|
updateVersionChange(data: MesPdVersionChangeApi.VersionChange) {
|
const index = pdMockVersionChanges.findIndex((item) => item.id === data.id);
|
if (index < 0) {
|
return Promise.reject(new Error('版本变更单不存在'));
|
}
|
pdMockVersionChanges[index] = { ...pdMockVersionChanges[index], ...data };
|
return mockDelay(undefined);
|
},
|
|
deleteVersionChange(id: number) {
|
const index = pdMockVersionChanges.findIndex((item) => item.id === id);
|
if (index >= 0) {
|
pdMockVersionChanges.splice(index, 1);
|
}
|
return mockDelay(undefined);
|
},
|
|
approveVersionChange(id: number) {
|
const row = pdMockVersionChanges.find((item) => item.id === id);
|
const project = pdMockProjects.find((p) => p.id === row?.projectId);
|
if (row && project && row.toVersion) {
|
project.version = row.toVersion;
|
}
|
return mockDelay(undefined);
|
},
|
|
// ---------- 流程 ----------
|
getWorkflowList(projectId: number) {
|
return mockDelay(pdMockWorkflows[projectId] ?? []);
|
},
|
};
|