1187 lines
39 KiB
TypeScript
1187 lines
39 KiB
TypeScript
declare namespace Api {
|
||
/**
|
||
* namespace Project
|
||
*
|
||
* backend api module: "project/project"
|
||
*/
|
||
namespace Project {
|
||
/** 项目状态编码 */
|
||
type ProjectStatusCode = 'pending' | 'active' | 'paused' | 'completed' | 'cancelled' | 'archived';
|
||
|
||
/** 项目状态动作编码 */
|
||
type ProjectStatusActionCode = 'auto_start' | 'pause' | 'resume' | 'complete' | 'cancel' | 'reopen' | 'archive';
|
||
|
||
/** 项目设置基础信息 */
|
||
interface ProjectSettingBaseInfo {
|
||
/** 项目 ID */
|
||
id: string;
|
||
/** 项目编码 */
|
||
projectCode: string;
|
||
/** 项目名称 */
|
||
projectName: string;
|
||
/** 项目方向字典值 */
|
||
directionCode: string;
|
||
/** 项目类型字典值 */
|
||
projectType: string;
|
||
/** 所属产品 ID */
|
||
productId: string | null;
|
||
/** 所属产品名称 */
|
||
productName: string | null;
|
||
/** 项目负责人用户昵称 */
|
||
managerUserNickname: string | null;
|
||
/** 项目负责人用户 ID */
|
||
managerUserId: string | null;
|
||
/** 项目状态编码 */
|
||
statusCode: ProjectStatusCode;
|
||
/** 计划开始日期 */
|
||
plannedStartDate: string | null;
|
||
/** 计划结束日期 */
|
||
plannedEndDate: string | null;
|
||
/** 实际开始日期 */
|
||
actualStartDate: string | null;
|
||
/** 实际结束日期 */
|
||
actualEndDate: string | null;
|
||
/** 项目说明 */
|
||
projectDesc: string | null;
|
||
/** 最近一次状态动作原因 */
|
||
lastStatusReason: string | null;
|
||
}
|
||
|
||
/** 项目生命周期动作 */
|
||
interface ProjectLifecycleAction {
|
||
actionCode: Exclude<ProjectStatusActionCode, 'auto_start'>;
|
||
actionName: string;
|
||
needReason: boolean;
|
||
}
|
||
|
||
/** 项目生命周期信息 */
|
||
interface ProjectLifecycleInfo {
|
||
statusCode: ProjectStatusCode;
|
||
lastStatusReason: string | null;
|
||
availableActions: ProjectLifecycleAction[];
|
||
}
|
||
|
||
/** 执行状态编码 */
|
||
type ProjectExecutionStatusCode = 'pending' | 'active' | 'paused' | 'completed' | 'cancelled';
|
||
|
||
/** 执行动作编码 */
|
||
type ProjectExecutionActionCode = 'start' | 'pause' | 'resume' | 'cancel' | 'complete';
|
||
|
||
/** 任务状态编码 */
|
||
type ProjectTaskStatusCode = 'pending' | 'active' | 'paused' | 'completed' | 'cancelled';
|
||
|
||
/** 任务动作编码 */
|
||
type ProjectTaskActionCode = 'auto_start' | 'pause' | 'resume' | 'complete' | 'cancel';
|
||
|
||
interface LifecycleAction<ActionCode extends string = string> {
|
||
actionCode: ActionCode;
|
||
actionName: string;
|
||
needReason: boolean;
|
||
}
|
||
|
||
interface StatusBoardItem {
|
||
statusCode: string;
|
||
statusName: string;
|
||
count: number;
|
||
sort: number;
|
||
terminal?: boolean;
|
||
}
|
||
|
||
interface StatusBoard {
|
||
total: number;
|
||
items: StatusBoardItem[];
|
||
}
|
||
|
||
interface ProjectExecution {
|
||
id: string;
|
||
projectId: string;
|
||
projectRequirementId: string | null;
|
||
/** 关联项目需求名称(service 层批量回填;未关联 = null) */
|
||
projectRequirementName: string | null;
|
||
/** 关联项目需求状态编码(pending_confirm/pending_review/implementing/accepted/closed/rejected/cancelled) */
|
||
projectRequirementStatusCode: string | null;
|
||
executionName: string;
|
||
executionType: string | null;
|
||
ownerId: string;
|
||
ownerNickname?: string | null;
|
||
statusCode: ProjectExecutionStatusCode;
|
||
statusName: string | null;
|
||
terminal: boolean;
|
||
allowEdit: boolean;
|
||
availableActions: LifecycleAction<ProjectExecutionActionCode>[];
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
actualStartDate: string | null;
|
||
actualEndDate: string | null;
|
||
progressRate: number;
|
||
/** 优先级字典 value(rdms_req_priority):"0" P0 / "1" P1(默认)/ "2" P2 / "3" P3,数字越小越高 */
|
||
priority: string;
|
||
/** 优先级标签预留字段;当前后端不填、永远为 null,前端按 priority 自译 */
|
||
priorityName: string | null;
|
||
executionDesc: string | null;
|
||
lastStatusReason: string | null;
|
||
createTime: string;
|
||
updateTime: string;
|
||
}
|
||
|
||
interface ExecutionAssignee {
|
||
id: string;
|
||
executionId: string;
|
||
userId: string;
|
||
userNickname?: string | null;
|
||
joinedAt: string | null;
|
||
removedAt: string | null;
|
||
removedReason: string | null;
|
||
}
|
||
|
||
/** 执行协办人变更事件类型 */
|
||
type ExecutionAssigneeActionType = 'join' | 'inactive' | 'owner_transfer_in' | 'owner_transfer_out';
|
||
|
||
/** 执行协办人变更历史 */
|
||
interface ExecutionAssigneeLog {
|
||
id: string;
|
||
executionId: string;
|
||
actionType: ExecutionAssigneeActionType;
|
||
userId: string;
|
||
userNicknameSnapshot: string | null;
|
||
operatorUserId: string;
|
||
operatorNicknameSnapshot: string | null;
|
||
actionTime: string;
|
||
reason: string | null;
|
||
}
|
||
|
||
type ExecutionAssigneeLogSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
actionTypes: ExecutionAssigneeActionType[];
|
||
userId: string;
|
||
startTime: string;
|
||
endTime: string;
|
||
}
|
||
>;
|
||
|
||
/** 通用附件元数据(任务 / 工时等域共用,规则见 AttachmentValidator) */
|
||
interface AttachmentItem {
|
||
/**
|
||
* 文件 ID(infra_file.id 字符串形式)。
|
||
* 用于会话级清理时调用 DELETE /system/file/delete?id=xxx 删除孤儿文件。
|
||
*/
|
||
fileId: string;
|
||
url: string;
|
||
name: string;
|
||
size?: number;
|
||
contentType?: string;
|
||
}
|
||
|
||
/** 任务详情 / 分页响应里嵌入的活跃协办人引用(按加入时间正序) */
|
||
interface TaskAssigneeRef {
|
||
id: string;
|
||
userId: string;
|
||
nickname: string;
|
||
/** 加入时间,5.6 路径返;5.3 嵌入路径不返,留 undefined */
|
||
joinedAt?: string | null;
|
||
}
|
||
|
||
/** 协办人变更事件类型(5.9 actionType) */
|
||
type TaskAssigneeActionType = 'join' | 'inactive';
|
||
|
||
/** 协办人变更日志 */
|
||
interface TaskAssigneeLog {
|
||
id: string;
|
||
taskId: string;
|
||
actionType: TaskAssigneeActionType;
|
||
userId: string;
|
||
userNicknameSnapshot: string | null;
|
||
operatorUserId: string;
|
||
operatorNicknameSnapshot: string | null;
|
||
actionTime: string;
|
||
reason: string | null;
|
||
}
|
||
|
||
type TaskAssigneeLogSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
actionTypes: TaskAssigneeActionType[];
|
||
userId: string;
|
||
startTime: string;
|
||
endTime: string;
|
||
}
|
||
>;
|
||
|
||
/** 5.7 加入协办人入参 */
|
||
interface CreateTaskAssigneeParams {
|
||
userId: string;
|
||
}
|
||
|
||
/** 5.8 退出协办人入参 */
|
||
interface InactiveTaskAssigneeParams {
|
||
reason: string;
|
||
}
|
||
|
||
interface ProjectTask {
|
||
id: string;
|
||
projectId: string;
|
||
executionId: string;
|
||
/** 所属执行名称;跨执行查询必有,单执行查询可缺省 */
|
||
executionName?: string | null;
|
||
/** 所属执行状态编码;跨执行查询必有,单执行查询可缺省(用于灰显已完成执行的任务行) */
|
||
executionStatusCode?: ProjectExecutionStatusCode | null;
|
||
parentTaskId: string | null;
|
||
/** 所属执行关联的项目需求 ID(透传,未关联 = null) */
|
||
projectRequirementId: string | null;
|
||
/** 所属执行关联的项目需求名称(透传,未关联 = null;跨执行查询永远为 null,前端不在跨执行视角展示) */
|
||
projectRequirementName: string | null;
|
||
/** 所属执行关联的项目需求状态编码(同上) */
|
||
projectRequirementStatusCode: string | null;
|
||
taskTitle: string;
|
||
type: string;
|
||
ownerId: string;
|
||
ownerNickname?: string | null;
|
||
/** 所属执行的负责人 userId(按钮可见度公式用);跨执行查询永远为 null,按钮判定退化为只看权限码 */
|
||
executionOwnerId: string | null;
|
||
/** 父任务负责人 userId(一级任务为 null) */
|
||
parentTaskOwnerId: string | null;
|
||
statusCode: ProjectTaskStatusCode;
|
||
statusName: string | null;
|
||
terminal: boolean;
|
||
allowEdit: boolean;
|
||
availableActions: LifecycleAction<ProjectTaskActionCode>[];
|
||
progressRate: number;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
actualStartDate: string | null;
|
||
actualEndDate: string | null;
|
||
/** 优先级字典 value(rdms_req_priority):"0" P0 / "1" P1(默认)/ "2" P2 / "3" P3,数字越小越高 */
|
||
priority: string;
|
||
/** 优先级标签预留字段;当前后端不填、永远为 null,前端按 priority 自译 */
|
||
priorityName: string | null;
|
||
taskDesc: string | null;
|
||
lastStatusReason: string | null;
|
||
assignees?: TaskAssigneeRef[] | null;
|
||
attachments?: AttachmentItem[] | null;
|
||
/** 已填报工时合计,单位小时(0.5 颗粒,BigDecimal)。逻辑删除的工时不计入。 */
|
||
totalSpentHours?: number | null;
|
||
createTime: string;
|
||
updateTime: string;
|
||
}
|
||
|
||
/**
|
||
* 执行截止时间范围(基于 plannedEndDate):overdue 逾期 / today 今天到期 / thisWeek 本周到期。
|
||
* 与任务侧 dueRange 同口径,后端三档均排除终态执行(已完成 / 已取消);未知值 = 不过滤。
|
||
*/
|
||
type ProjectExecutionDueRange = 'overdue' | 'today' | 'thisWeek';
|
||
|
||
/**
|
||
* 项目执行分页入参(`GET /project/project/{projectId}/executions/page`)。
|
||
*
|
||
* - `involveUserId` / `ownerId` 互斥:同传后端不报错但语义变 AND,前端切视角时务必清另一字段。
|
||
* - 不传 `involveUserId` 且不传 `ownerId` = 项目下全部执行。
|
||
* - `dueRange` 按计划结束日期过滤,与其它参数 AND;详见 ProjectExecutionDueRange。
|
||
*/
|
||
type ProjectExecutionSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
keyword: string;
|
||
executionType: string;
|
||
/** "我参与"语义:当前用户作为 owner 或活跃协办;与 ownerId 二选一 */
|
||
involveUserId: string;
|
||
/** 仅作为 owner 匹配;与 involveUserId 二选一 */
|
||
ownerId: string;
|
||
statusCode: string;
|
||
/** 优先级筛选(字典 value:String "0"~"3"),不传 = 全部档位 */
|
||
priority: string;
|
||
dueRange: ProjectExecutionDueRange;
|
||
updateTime: string[];
|
||
}
|
||
>;
|
||
|
||
type ProjectExecutionStatusBoardParams = CommonType.RecordNullable<{
|
||
keyword: string;
|
||
executionType: string;
|
||
/** "我参与"语义:当前用户作为 owner 或活跃协办;与 ownerId 二选一 */
|
||
involveUserId: string;
|
||
/** 仅作为 owner 匹配;与 involveUserId 二选一 */
|
||
ownerId: string;
|
||
/** 截止时间范围过滤,传入后各状态分组计数均在该范围内统计(口径同 page) */
|
||
dueRange: ProjectExecutionDueRange;
|
||
updateTime: string[];
|
||
}>;
|
||
|
||
/** 工作台「我负责的执行」(跨项目)查询入参 */
|
||
type MyExecutionSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
/** 预留:单状态精确过滤,不传走后端默认口径 */
|
||
statusCode: string;
|
||
/** 预留:执行名称模糊匹配 */
|
||
keyword: string;
|
||
}
|
||
>;
|
||
|
||
/** 工作台「我负责的执行」单项(跨项目聚合,owner 恒为当前登录用户) */
|
||
interface MyExecutionItem {
|
||
/** 执行 ID(雪花 ID,字符串) */
|
||
id: string;
|
||
executionName: string;
|
||
/** 所属项目 */
|
||
projectId: string;
|
||
projectName: string;
|
||
/** 执行状态编码:pending / active / paused */
|
||
statusCode: string;
|
||
/** 执行状态名称 */
|
||
statusName: string | null;
|
||
/** 优先级字典 value(rdms_req_priority,"0"~"3") */
|
||
priority: string;
|
||
/** 计划起止(YYYY-MM-DD) */
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
/** 实际起止(YYYY-MM-DD) */
|
||
actualStartDate: string | null;
|
||
actualEndDate: string | null;
|
||
/** 进度(0-100 整数) */
|
||
progressRate: number;
|
||
/** 关联项目需求 */
|
||
projectRequirementId: string | null;
|
||
projectRequirementName: string | null;
|
||
}
|
||
|
||
/** 工作台「我的项目」查询入参(我参与的 / 我负责的 共用) */
|
||
type MyProjectSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
/** 预留:项目名称/编码模糊关键字,后端本期不过滤 */
|
||
keyword: string;
|
||
}
|
||
>;
|
||
|
||
/** 工作台「我参与的项目」单项(成员视角,附带我的角色与任务量) */
|
||
interface MyParticipatedProjectItem {
|
||
/** 项目 ID(字符串) */
|
||
id: string;
|
||
name: string;
|
||
/** 项目编码,可空 */
|
||
code: string | null;
|
||
/** 项目状态编码(如 active) */
|
||
statusCode: string;
|
||
/** 项目状态名称,可空 */
|
||
statusName: string | null;
|
||
/** 项目整体进度 0-100 */
|
||
progress: number;
|
||
/** 我在该项目中的角色名(多角色拼接),可空 */
|
||
myRole: string | null;
|
||
/** 我负责的任务总数(按负责人,含已完成) */
|
||
myTaskCount: number;
|
||
/** 我负责的未完成任务数 */
|
||
myPendingTaskCount: number;
|
||
}
|
||
|
||
/** 工作台「我负责的项目」成员负载子项 */
|
||
interface MyOwnedProjectMember {
|
||
/** 成员用户 ID(字符串) */
|
||
userId: string;
|
||
/** 成员姓名/昵称,可空 */
|
||
userName: string | null;
|
||
/** 该成员在本项目下进行中任务数(按负责人) */
|
||
activeTaskCount: number;
|
||
}
|
||
|
||
/** 工作台「我负责的项目」单项(项目负责人视角,附聚合统计与成员负载) */
|
||
interface MyOwnedProjectItem {
|
||
/** 项目 ID(字符串) */
|
||
id: string;
|
||
name: string;
|
||
/** 项目编码,可空 */
|
||
code: string | null;
|
||
/** 项目整体进度 0-100 */
|
||
progress: number;
|
||
/** 我在该项目中的角色名,可空 */
|
||
myRole: string | null;
|
||
/** 项目计划结束日期 YYYY-MM-DD,可空 */
|
||
plannedEndDate: string | null;
|
||
/** 项目下进行中执行数 */
|
||
executionCount: number;
|
||
/** 项目下进行中任务数 */
|
||
taskCount: number;
|
||
/** 项目下逾期任务数 */
|
||
overdueCount: number;
|
||
/** 项目当前有效成员数(多角色去重) */
|
||
memberCount: number;
|
||
/** 成员负载列表(无成员为 []) */
|
||
members: MyOwnedProjectMember[];
|
||
}
|
||
|
||
/** 创建执行入参(含 ownerId + assigneeUserIds) */
|
||
interface CreateProjectExecutionParams {
|
||
executionName: string;
|
||
executionType: string;
|
||
ownerId: string;
|
||
projectRequirementId: string | null;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
/** 优先级字典 value,必填,String "0"~"3" */
|
||
priority: string;
|
||
executionDesc: string | null;
|
||
assigneeUserIds?: string[];
|
||
}
|
||
|
||
/** 执行创建/编辑弹层 emit 的统一 payload(创建时含 ownerId + assigneeUserIds;编辑时不含) */
|
||
type SaveProjectExecutionParams = CreateProjectExecutionParams;
|
||
|
||
/** 编辑执行入参(不含 ownerId / assigneeUserIds) */
|
||
interface UpdateProjectExecutionParams {
|
||
executionName: string;
|
||
executionType: string;
|
||
projectRequirementId: string | null;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
/** 优先级字典 value,必填,String "0"~"3" */
|
||
priority: string;
|
||
executionDesc: string | null;
|
||
}
|
||
|
||
interface ChangeExecutionOwnerParams {
|
||
newOwnerId: string;
|
||
reason: string | null;
|
||
}
|
||
|
||
interface ChangeExecutionStatusParams {
|
||
actionCode: ProjectExecutionActionCode;
|
||
reason: string | null;
|
||
}
|
||
|
||
interface CreateExecutionAssigneeParams {
|
||
userId: string;
|
||
}
|
||
|
||
interface InactiveExecutionAssigneeParams {
|
||
reason: string;
|
||
}
|
||
|
||
type ProjectTaskSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
keyword: string;
|
||
parentTaskId: string;
|
||
ownerId: string;
|
||
statusCode: string;
|
||
/** 优先级筛选(字典 value:String "0"~"3"),不传 = 全部档位 */
|
||
priority: string;
|
||
updateTime: string[];
|
||
}
|
||
>;
|
||
|
||
type ProjectTaskStatusBoardParams = CommonType.RecordNullable<{
|
||
keyword: string;
|
||
parentTaskId: string;
|
||
ownerId: string;
|
||
updateTime: string[];
|
||
}>;
|
||
|
||
/**
|
||
* 任务看板按状态分组的分页入参。
|
||
*
|
||
* - `statusCode` 缺省 → 返回该执行下任务状态字典中的全部状态(即使该状态下当前没有任务,也要回该列、`total=0`、`list=[]`)。
|
||
* - 传入数组 → 只返回这些状态的列。
|
||
* - `pageNo` / `pageSize` 应用到所有返回的状态(同一页码下各状态各自分页),前端不需要"每列独立 pageNo"。
|
||
*/
|
||
type ProjectTaskBoardPageParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
statusCode: string[];
|
||
keyword: string;
|
||
parentTaskId: string;
|
||
ownerId: string;
|
||
/** 优先级筛选(字典 value:String "0"~"3"),不传 = 全部档位 */
|
||
priority: string;
|
||
updateTime: string[];
|
||
}
|
||
>;
|
||
|
||
interface ProjectTaskBoardColumn {
|
||
statusCode: string;
|
||
statusName: string;
|
||
sort: number;
|
||
terminal?: boolean;
|
||
list: ProjectTask[];
|
||
total: number;
|
||
}
|
||
|
||
interface ProjectTaskBoardPage {
|
||
items: ProjectTaskBoardColumn[];
|
||
}
|
||
|
||
/** 截止时间快速选项(跨执行接口专属) */
|
||
type ProjectTaskDueRange = 'overdue' | 'today' | 'thisWeek';
|
||
|
||
/** 跨执行任务排序字段 */
|
||
type ProjectTaskCrossSortBy = 'plannedEndDate' | 'priority' | 'updateTime' | 'createTime';
|
||
|
||
type ProjectTaskCrossSortOrder = 'asc' | 'desc';
|
||
|
||
/**
|
||
* 项目级跨执行任务分页入参(`GET /project/project/{projectId}/tasks/page`)。
|
||
*
|
||
* - `involveUserId` / `ownerId` 互斥:同传只 `ownerId` 生效(后端 SQL 双重过滤)。
|
||
* - `executionIds` 不传 = 项目内全部执行;空数组 `[]` = 明确返空。
|
||
* - `executionInvolveUserId` = 限定到"该用户参与的执行"(owner 或活跃执行协办);未参与任何执行时返空;
|
||
* 与 `executionIds` 同传为 AND。用它表达"我参与的执行"范围,无需前端先查执行 id 再回传。
|
||
* - `executionStatusCodes` 在任务可见性之上叠加"任务所属执行状态 ∈ 白名单"过滤;多值 OR;
|
||
* 与 `executionIds` 同传时为 AND。详见 `docs/debt/跨执行任务接口-按执行状态过滤-契约调整.html`。
|
||
* - 不传 `involveUserId / ownerId` 且无 `project:task:query` 权限时,后端静默降级为"自己有身份的范围",不抛 403。
|
||
*/
|
||
type ProjectTaskCrossSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
keyword: string;
|
||
executionIds: string[];
|
||
/**
|
||
* 执行成员过滤:该用户作为执行 owner 或活跃执行协办人的执行 → 其下任务;未参与任何执行时返空。
|
||
* 与 `involveUserId`(任务成员)正交,可同传取交集。
|
||
*/
|
||
executionInvolveUserId: string;
|
||
/** 任务所属执行的状态白名单(用于左侧执行池按状态 chip 切换时的任务范围过滤) */
|
||
executionStatusCodes: ProjectExecutionStatusCode[];
|
||
/** "我参与"语义:当前用户作为 owner 或活跃协办;与 ownerId 二选一 */
|
||
involveUserId: string;
|
||
/** 仅作为 owner 匹配;与 involveUserId 二选一 */
|
||
ownerId: string;
|
||
statusCodes: ProjectTaskStatusCode[];
|
||
/** 优先级字典 value("0"~"3") */
|
||
priority: string;
|
||
parentTaskId: string;
|
||
dueRange: ProjectTaskDueRange;
|
||
/** 更新时间范围 [start, end],格式 yyyy-MM-dd HH:mm:ss */
|
||
updateTime: string[];
|
||
sortBy: ProjectTaskCrossSortBy;
|
||
sortOrder: ProjectTaskCrossSortOrder;
|
||
}
|
||
>;
|
||
|
||
/** 项目级跨执行任务状态看板入参(与 page 同口径但不含 pageNo/pageSize/statusCodes/sortBy/sortOrder) */
|
||
type ProjectTaskCrossStatusBoardParams = Omit<
|
||
ProjectTaskCrossSearchParams,
|
||
'pageNo' | 'pageSize' | 'statusCodes' | 'sortBy' | 'sortOrder'
|
||
>;
|
||
|
||
/** 项目级跨执行任务看板分页入参 */
|
||
type ProjectTaskCrossBoardPageParams = Omit<ProjectTaskCrossSearchParams, 'sortBy' | 'sortOrder'>;
|
||
|
||
/** 项目级"今日小条"汇总入参 */
|
||
interface ProjectTaskSummaryParams {
|
||
/** 默认 mine(不传也走 mine);all 必须有 project:task:query 权限,否则 403 */
|
||
scope?: 'mine' | 'all';
|
||
}
|
||
|
||
/**
|
||
* 项目级"今日小条"汇总响应(`GET /project/project/{projectId}/tasks/summary`)。
|
||
*
|
||
* 数字一致性:dueThisWeek 的范围与 page?dueRange=thisWeek 完全一致(本周一~本周日)。
|
||
* today / weekStart / weekEnd 直接展示,不要前端再算"今天/本周一"(服务器时区为 Asia/Shanghai)。
|
||
*/
|
||
interface ProjectTaskSummary {
|
||
overdue: number;
|
||
dueToday: number;
|
||
dueThisWeek: number;
|
||
doneThisWeek: number;
|
||
today: string;
|
||
weekStart: string;
|
||
weekEnd: string;
|
||
}
|
||
|
||
interface SaveProjectTaskParams {
|
||
parentTaskId: string | null;
|
||
taskTitle: string;
|
||
type: string;
|
||
ownerId: string | null;
|
||
progressRate?: number;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
/** 优先级字典 value,必填,String "0"~"3" */
|
||
priority: string;
|
||
taskDesc: string | null;
|
||
/** 仅创建任务时生效,编辑接口静默忽略;userId 必须是当前有效执行协办人且不能等于 ownerId */
|
||
assigneeUserIds?: string[];
|
||
/** 编辑语义:null 保留原值 / [] 清空 / [...] 整体替换 */
|
||
attachments?: AttachmentItem[] | null;
|
||
}
|
||
|
||
interface ChangeTaskStatusParams {
|
||
actionCode: ProjectTaskActionCode;
|
||
reason: string | null;
|
||
}
|
||
|
||
/** 任务工时记录 */
|
||
interface TaskWorklog {
|
||
id: string;
|
||
taskId: string;
|
||
userId: string;
|
||
userNickname: string | null;
|
||
/** 段起始日期(含),YYYY-MM-DD;单天=与 endDate 相等 */
|
||
startDate: string;
|
||
/** 段结束日期(含),YYYY-MM-DD;单天=与 startDate 相等 */
|
||
endDate: string;
|
||
/** 本次填报小时数(BigDecimal,0.5 颗粒,> 0) */
|
||
durationHours: number;
|
||
/** 本次填报进度(0~100,scale=2) */
|
||
progressRate: number;
|
||
/** 难度,来自字典 rdms_task_item_worklog_difficulty */
|
||
difficulty: string;
|
||
/** 后端预留字段,目前始终为 null,前端按 difficulty + 字典 cache 自译 */
|
||
difficultyName?: string | null;
|
||
workContent: string | null;
|
||
attachments?: AttachmentItem[] | null;
|
||
createTime: string;
|
||
updateTime: string;
|
||
}
|
||
|
||
type TaskWorklogSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
userId: string;
|
||
startDate: string;
|
||
endDate: string;
|
||
/** 完成难度筛选,等值匹配;不传 = 全部 */
|
||
difficulty: string;
|
||
}
|
||
>;
|
||
|
||
interface SaveTaskWorklogParams {
|
||
/** 段起始日期(含),YYYY-MM-DD */
|
||
startDate: string;
|
||
/** 段结束日期(含),YYYY-MM-DD;不得早于 startDate */
|
||
endDate: string;
|
||
/** 本次填报小时数,> 0 且 0.5 整数倍 */
|
||
durationHours: number;
|
||
/** 本次填报进度(0~100,scale=2,必填) */
|
||
progressRate: number;
|
||
/** 难度,来自字典 rdms_task_item_worklog_difficulty */
|
||
difficulty: string;
|
||
workContent?: string | null;
|
||
/** 编辑语义:null 保留原值 / [] 清空 / [...] 替换 */
|
||
attachments?: AttachmentItem[] | null;
|
||
}
|
||
|
||
/** 项目设置参数 */
|
||
interface ProjectSettings {
|
||
baseInfo: ProjectSettingBaseInfo;
|
||
lifecycle: ProjectLifecycleInfo;
|
||
}
|
||
|
||
/** 项目设置基础信息参数 */
|
||
interface UpdateProjectSettingBaseInfoParams {
|
||
projectName: string;
|
||
directionCode: string;
|
||
projectType: string;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
projectDesc: string | null;
|
||
}
|
||
|
||
/** 项目成员状态 */
|
||
type ProjectMemberStatus = 0 | 1;
|
||
|
||
interface PageParams {
|
||
pageNo: number;
|
||
pageSize: number;
|
||
}
|
||
|
||
interface PageResult<T = any> {
|
||
total: number;
|
||
list: T[];
|
||
}
|
||
|
||
/** 项目入口页概览统计 */
|
||
interface ProjectOverviewSummary {
|
||
/** 项目状态数量映射,key 为后端状态编码 */
|
||
statusCounts: Record<string, number>;
|
||
}
|
||
|
||
interface Project {
|
||
/** 项目 ID */
|
||
id: string;
|
||
/** 项目编码 */
|
||
projectCode: string;
|
||
/** 项目名称 */
|
||
projectName: string;
|
||
/** 项目方向字典值 */
|
||
directionCode: string;
|
||
/** 项目类型字典值 */
|
||
projectType: string;
|
||
/** 所属产品 ID */
|
||
productId: string | null;
|
||
/** 所属产品名称 */
|
||
productName?: string | null;
|
||
/** 项目负责人用户 ID */
|
||
managerUserId: string;
|
||
/** 项目负责人用户昵称 */
|
||
managerUserNickname?: string | null;
|
||
/** 项目状态编码 */
|
||
statusCode: ProjectStatusCode;
|
||
/** 计划开始日期 */
|
||
plannedStartDate: string | null;
|
||
/** 计划结束日期 */
|
||
plannedEndDate: string | null;
|
||
/** 实际开始日期 */
|
||
actualStartDate: string | null;
|
||
/** 实际结束日期 */
|
||
actualEndDate: string | null;
|
||
/** 进度百分比 */
|
||
progressRate: number;
|
||
/** 项目说明 */
|
||
projectDesc: string | null;
|
||
/** 最近一次状态动作原因 */
|
||
lastStatusReason: string | null;
|
||
/** 创建时间 */
|
||
createTime: string;
|
||
/** 更新时间 */
|
||
updateTime: string;
|
||
}
|
||
|
||
interface ProjectContext {
|
||
currentProject: {
|
||
id: string;
|
||
projectCode: string;
|
||
projectName: string;
|
||
projectType: string;
|
||
productId: string | null;
|
||
managerUserId: string;
|
||
statusCode: ProjectStatusCode;
|
||
};
|
||
currentRole: {
|
||
roleId: string | null;
|
||
roleCode: string | null;
|
||
roleName: string | null;
|
||
guestFlag: boolean;
|
||
};
|
||
navs: Array<{
|
||
id: string;
|
||
name: string;
|
||
path: string;
|
||
icon: string;
|
||
sort: number;
|
||
}>;
|
||
buttons: string[];
|
||
}
|
||
|
||
interface ProjectMember {
|
||
/** 成员关系 ID */
|
||
id: string;
|
||
/** 用户 ID */
|
||
userId: string;
|
||
/** 用户昵称 */
|
||
userNickname: string;
|
||
/** 角色 ID */
|
||
roleId: string;
|
||
/** 角色名称 */
|
||
roleName: string;
|
||
/** 角色编码 */
|
||
roleCode: string;
|
||
/** 是否项目负责人 */
|
||
managerFlag: boolean;
|
||
/** 成员状态 */
|
||
status: ProjectMemberStatus;
|
||
/** 加入时间 */
|
||
joinedTime: string;
|
||
/** 退出时间 */
|
||
leftTime: string | null;
|
||
/** 备注 */
|
||
remark: string | null;
|
||
}
|
||
|
||
/** 项目搜索参数 */
|
||
type ProjectSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> & {
|
||
keyword: string;
|
||
directionCode: string;
|
||
projectType: string;
|
||
productId: string;
|
||
managerUserId: string;
|
||
statusCode: ProjectStatusCode;
|
||
updateTime: string[];
|
||
}
|
||
>;
|
||
|
||
/** 创建/保存项目参数 */
|
||
type SaveProjectParams = Pick<Project, 'projectName' | 'directionCode' | 'projectType' | 'projectDesc'> & {
|
||
projectCode: string | null;
|
||
productId: string | null;
|
||
managerUserId: string;
|
||
plannedStartDate: string | null;
|
||
plannedEndDate: string | null;
|
||
actualStartDate?: string | null;
|
||
actualEndDate?: string | null;
|
||
};
|
||
|
||
/** 更新项目参数 */
|
||
type UpdateProjectParams = { id: string } & SaveProjectParams;
|
||
|
||
/** 变更项目状态参数 */
|
||
interface ChangeProjectStatusParams {
|
||
id: string;
|
||
actionCode: ProjectStatusActionCode;
|
||
reason: string | null;
|
||
}
|
||
|
||
/** 删除项目参数 */
|
||
interface DeleteProjectParams {
|
||
id: string;
|
||
projectName: string;
|
||
confirmText: string;
|
||
reason: string;
|
||
}
|
||
|
||
/** 删除执行入参 */
|
||
interface DeleteProjectExecutionParams {
|
||
/** 二次确认:必须与当前执行名称完全一致 */
|
||
executionName: string;
|
||
/** 删除确认口令:接受 "删除" 或 "DELETE" */
|
||
confirmText: string;
|
||
/** 删除原因,写入审计日志 */
|
||
reason: string;
|
||
}
|
||
|
||
/** 删除任务入参 */
|
||
interface DeleteProjectTaskParams {
|
||
/** 二次确认:必须与当前任务名称完全一致 */
|
||
taskName: string;
|
||
/** 删除确认口令:接受 "删除" 或 "DELETE" */
|
||
confirmText: string;
|
||
/** 删除原因,写入审计日志 */
|
||
reason: string;
|
||
}
|
||
|
||
/** 执行删除预检(spec §2.1:判断是否需要走重型确认弹层) */
|
||
interface ProjectExecutionDeletePrecheck {
|
||
/** 该执行下任务总数(含子孙,含 completed),展示用 */
|
||
taskCount: number;
|
||
/** taskCount > 0 视为 true */
|
||
hasDependentData: boolean;
|
||
}
|
||
|
||
/** 任务删除预检(spec §2.1) */
|
||
interface ProjectTaskDeletePrecheck {
|
||
/** 直接子任务数 */
|
||
childTaskCount: number;
|
||
/** 工作日志条数 */
|
||
worklogCount: number;
|
||
/** childTaskCount + worklogCount > 0 视为 true */
|
||
hasDependentData: boolean;
|
||
}
|
||
|
||
/** 创建项目成员参数 */
|
||
interface CreateProjectMemberParams {
|
||
userId: string;
|
||
roleId: string;
|
||
remark: string | null;
|
||
previousManagerUserId?: string | null;
|
||
previousManagerRoleId?: string | null;
|
||
}
|
||
|
||
/** 更新项目成员参数 */
|
||
interface UpdateProjectMemberParams {
|
||
roleId: string;
|
||
reason: string | null;
|
||
remark: string | null;
|
||
previousManagerUserId?: string | null;
|
||
previousManagerRoleId?: string | null;
|
||
}
|
||
|
||
/** 移出项目成员参数 */
|
||
interface InactiveProjectMemberParams {
|
||
reason: string | null;
|
||
}
|
||
|
||
/**
|
||
* 批量新增项目成员参数
|
||
*
|
||
* 刻意不复用 CreateProjectMemberParams:批量接口不承担"项目负责人交接"语义,
|
||
* 后端兜底拒绝 roleId 为项目负责人角色的项。
|
||
*/
|
||
interface BatchCreateProjectMembersParams {
|
||
members: Array<{
|
||
userId: string;
|
||
roleId: string;
|
||
remark?: string | null;
|
||
}>;
|
||
}
|
||
|
||
/** 批量移出项目成员参数 */
|
||
interface BatchInactiveProjectMembersParams {
|
||
memberIds: string[];
|
||
reason?: string | null;
|
||
}
|
||
|
||
/**
|
||
* 项目创建(含初始团队)原子接口参数
|
||
*
|
||
* 新增项目两步向导提交的载荷。经理成员也由前端聚合到 members 数组中。
|
||
*/
|
||
interface CreateProjectWithTeamParams {
|
||
project: SaveProjectParams;
|
||
members: CreateProjectMemberParams[];
|
||
/** 关注人 user_id 数组(选填);后端按 (user, object, role) 三元组幂等写入 project_watcher 角色 */
|
||
watcherUserIds?: string[];
|
||
}
|
||
|
||
// ========== 项目需求相关类型定义 ==========
|
||
/** 项目需求状态编码 */
|
||
type ProjectRequirementStatusCode =
|
||
| 'pending_claim'
|
||
| 'pending_review'
|
||
| 'reviewed'
|
||
| 'review_rejected'
|
||
| 'implementing'
|
||
| 'accepted'
|
||
| 'closed'
|
||
| 'rejected'
|
||
| 'cancelled';
|
||
|
||
/** 项目需求状态动作编码 */
|
||
type ProjectRequirementStatusActionCode =
|
||
| 'claim_to_review'
|
||
| 'claim_to_implement'
|
||
| 'pass_review'
|
||
| 'reject_review'
|
||
| 'start_implement'
|
||
| 'accept'
|
||
| 'cancel'
|
||
| 'close'
|
||
| 'reject';
|
||
|
||
/** 项目需求来源类型 */
|
||
type ProjectRequirementSourceType = 'manual' | 'work_order' | 'product_requirement';
|
||
|
||
/** 项目需求优先级 */
|
||
type ProjectRequirementPriority = 0 | 1 | 2 | 3;
|
||
|
||
/** 是否需要评审 */
|
||
type ProjectRequirementReviewRequired = 0 | 1;
|
||
|
||
interface ProjectRequirement {
|
||
/** 需求 ID */
|
||
id: string;
|
||
/** 所属项目 ID */
|
||
projectId: string;
|
||
/** 父需求 ID,0 表示顶级需求 */
|
||
parentId: string;
|
||
/** 所属模块 ID */
|
||
moduleId: string;
|
||
/** 是否需要评审 */
|
||
reviewRequired: ProjectRequirementReviewRequired;
|
||
/** 需求标题 */
|
||
title: string;
|
||
/** 需求描述 */
|
||
description?: string | null;
|
||
/** 附件列表 */
|
||
attachments?: AttachmentItem[] | null;
|
||
/** 需求分类字典值 */
|
||
category: string;
|
||
/** 需求分类名称 */
|
||
categoryName?: string | null;
|
||
/** 需求来源类型 */
|
||
sourceType: ProjectRequirementSourceType;
|
||
/** 来源业务 ID */
|
||
sourceBizId?: string | null;
|
||
/** 优先级 */
|
||
priority: ProjectRequirementPriority;
|
||
/** 优先级名称 */
|
||
priorityName?: string | null;
|
||
/** 当前状态编码 */
|
||
statusCode: ProjectRequirementStatusCode;
|
||
/** 当前状态名称 */
|
||
statusName?: string | null;
|
||
/** 最近一次状态动作原因 */
|
||
lastStatusReason?: string | null;
|
||
/** 提出人用户 ID */
|
||
proposerId: string;
|
||
/** 提出人昵称 */
|
||
proposerNickname?: string | null;
|
||
/** 当前处理人用户 ID */
|
||
currentHandlerUserId?: string | null;
|
||
/** 当前处理人昵称 */
|
||
currentHandlerUserNickname?: string | null;
|
||
/** 预期完成日期 */
|
||
expectedTime?: string | null;
|
||
/** 排序值 */
|
||
sort: number;
|
||
/** 项目需求进度(BigDecimal,0.00 ~ 1.00;HALF_UP 两位小数)。读时聚合,后端不接受写入。 */
|
||
progressRate: number;
|
||
/** 创建时间 */
|
||
createTime: string;
|
||
/** 更新时间 */
|
||
updateTime: string;
|
||
/** 子需求列表 */
|
||
children?: ProjectRequirement[];
|
||
}
|
||
|
||
interface ProjectRequirementModule {
|
||
/** 模块 ID */
|
||
id: string;
|
||
/** 父模块 ID,0 表示顶级 */
|
||
parentId: string;
|
||
/** 所属项目 ID */
|
||
projectId: string;
|
||
/** 模块名称 */
|
||
moduleName: string;
|
||
/** 模块说明 */
|
||
remark?: string | null;
|
||
/** 图标 */
|
||
icon?: string | null;
|
||
/** 排序值 */
|
||
sort: number;
|
||
/** 子模块列表 */
|
||
children?: ProjectRequirementModule[];
|
||
}
|
||
|
||
interface ProjectRequirementStatusDict {
|
||
/** 状态编码 */
|
||
statusCode: string;
|
||
/** 状态名称 */
|
||
statusName: string;
|
||
/** 排序值 */
|
||
sort: number;
|
||
/** 是否初始状态 */
|
||
initialFlag: boolean;
|
||
/** 是否终态 */
|
||
terminalFlag: boolean;
|
||
/** 是否允许编辑 */
|
||
allowEdit: boolean;
|
||
}
|
||
|
||
interface ProjectRequirementLifecycleAction {
|
||
actionCode: ProjectRequirementStatusActionCode;
|
||
actionName: string;
|
||
toStatusCode: string;
|
||
toStatusName: string;
|
||
needReason: boolean;
|
||
}
|
||
|
||
interface ProjectRequirementBatchReqVO {
|
||
projectId: string;
|
||
requirementIds: string[];
|
||
}
|
||
|
||
interface ProjectRequirementAllowedTransitionBatchRespVO {
|
||
requirementId: string;
|
||
transitions: ProjectRequirementLifecycleAction[];
|
||
}
|
||
|
||
type ProjectRequirementReviewConclusion = 0 | 1;
|
||
|
||
interface ProjectRequirementReviewAttendeeItem {
|
||
userId: string;
|
||
nickname: string;
|
||
}
|
||
|
||
interface ProjectRequirementReview {
|
||
id: string;
|
||
objectType: 'project_requirement';
|
||
requirementId: string;
|
||
operatorId: string;
|
||
conclusion: ProjectRequirementReviewConclusion;
|
||
reviewContent?: string | null;
|
||
requirementEstimatedHours?: number | string | null;
|
||
attendees?: ProjectRequirementReviewAttendeeItem[];
|
||
attachments?: AttachmentItem[] | null;
|
||
reviewTime?: string | null;
|
||
createTime?: string;
|
||
updateTime?: string;
|
||
}
|
||
|
||
interface ProjectRequirementReviewSubmitParams {
|
||
projectId: string;
|
||
requirementId: string;
|
||
operatorId: string;
|
||
conclusion: ProjectRequirementReviewConclusion;
|
||
reviewContent?: string | null;
|
||
requirementEstimatedHours?: number | string | null;
|
||
attendees?: ProjectRequirementReviewAttendeeItem[];
|
||
attachments?: AttachmentItem[] | null;
|
||
reviewTime?: string | null;
|
||
}
|
||
|
||
/** 项目需求分页查询参数 */
|
||
type ProjectRequirementSearchParams = CommonType.RecordNullable<
|
||
Pick<PageParams, 'pageNo' | 'pageSize'> &
|
||
Pick<
|
||
ProjectRequirement,
|
||
'moduleId' | 'parentId' | 'category' | 'priority' | 'statusCode' | 'currentHandlerUserId' | 'sourceType'
|
||
> & {
|
||
projectId: string;
|
||
title: string;
|
||
}
|
||
>;
|
||
|
||
/** 创建项目需求参数 */
|
||
type SaveProjectRequirementParams = Pick<
|
||
ProjectRequirement,
|
||
| 'projectId'
|
||
| 'moduleId'
|
||
| 'reviewRequired'
|
||
| 'title'
|
||
| 'description'
|
||
| 'attachments'
|
||
| 'category'
|
||
| 'priority'
|
||
| 'proposerId'
|
||
| 'proposerNickname'
|
||
| 'currentHandlerUserId'
|
||
| 'currentHandlerUserNickname'
|
||
| 'expectedTime'
|
||
| 'sort'
|
||
>;
|
||
|
||
/** 更新项目需求参数 */
|
||
type UpdateProjectRequirementParams = { id: string } & SaveProjectRequirementParams;
|
||
|
||
/** 变更项目需求状态参数 */
|
||
interface ChangeProjectRequirementStatusParams {
|
||
id: string;
|
||
projectId: string;
|
||
actionCode: string;
|
||
reason?: string | null;
|
||
}
|
||
|
||
/** 关闭项目需求参数 */
|
||
interface CloseProjectRequirementParams {
|
||
id: string;
|
||
projectId: string;
|
||
reason: string;
|
||
}
|
||
|
||
/** 拆分项目需求参数 */
|
||
type SplitProjectRequirementParams = Pick<
|
||
ProjectRequirement,
|
||
| 'parentId'
|
||
| 'projectId'
|
||
| 'moduleId'
|
||
| 'reviewRequired'
|
||
| 'title'
|
||
| 'description'
|
||
| 'attachments'
|
||
| 'category'
|
||
| 'priority'
|
||
| 'proposerId'
|
||
| 'proposerNickname'
|
||
| 'currentHandlerUserId'
|
||
| 'currentHandlerUserNickname'
|
||
| 'expectedTime'
|
||
| 'sort'
|
||
>;
|
||
|
||
/** 删除项目需求参数 */
|
||
interface DeleteProjectRequirementParams {
|
||
id: string;
|
||
projectId: string;
|
||
}
|
||
|
||
/** 保存项目需求模块参数 */
|
||
interface SaveProjectRequirementModuleParams {
|
||
id?: string;
|
||
projectId: string;
|
||
parentId?: string | null;
|
||
moduleName: string;
|
||
remark?: string | null;
|
||
icon?: string | null;
|
||
sort?: number;
|
||
}
|
||
|
||
/** 删除项目需求模块参数 */
|
||
interface DeleteProjectRequirementModuleParams {
|
||
id?: string;
|
||
projectId: string;
|
||
}
|
||
}
|
||
}
|