diff --git a/src/apis/project/personnel-dispatch.ts b/src/apis/project/personnel-dispatch.ts new file mode 100644 index 0000000..617c763 --- /dev/null +++ b/src/apis/project/personnel-dispatch.ts @@ -0,0 +1,98 @@ +import type * as T from './type' +import http from '@/utils/http' + +export type * from './type' + +const BASE_URL = '/project-member' + +// ==================== 项目看板相关接口 ==================== + +/** @desc 获取项目看板统计数据 */ +export function getProjectKanbanStats() { + return http.get(`${BASE_URL}/kanban/stats`) +} + +/** @desc 获取项目看板数据 */ +export function getProjectKanbanData() { + return http.get(`${BASE_URL}/kanban/data`) +} + +/** @desc 获取项目详情 */ +export function getProjectDetail(id: string | number) { + return http.get(`${BASE_URL}/project/${id}/detail`) +} + +// ==================== 团队成员管理 ==================== + +/** @desc 获取项目团队成员列表(支持筛选、分页、搜索) */ +export function getProjectTeamMembers(params: T.TeamMemberQuery) { + const { projectId, ...queryParams } = params + return http.get(`${BASE_URL}/project/${projectId}/team-members`, { params: queryParams }) +} + +/** @desc 创建团队成员 */ +export function createTeamMember(data: T.CreateTeamMemberForm) { + return http.post(`${BASE_URL}/team-member`, data) +} + +/** @desc 更新团队成员信息(支持更新状态) */ +export function updateTeamMember(id: string | number, data: T.UpdateTeamMemberForm) { + return http.put(`${BASE_URL}/team-member/${id}`, data) +} + +/** @desc 删除团队成员(支持单个或批量删除) */ +export function deleteTeamMembers(ids: string | number | (string | number)[]) { + const idArray = Array.isArray(ids) ? ids : [ids] + return http.del(`${BASE_URL}/team-member/batch`, { data: { ids: idArray } }) +} + +/** @desc 导入团队成员数据 */ +export function importTeamMembers(projectId: string | number, file: File) { + const formData = new FormData() + formData.append('file', file) + formData.append('projectId', projectId.toString()) + return http.post(`${BASE_URL}/team-member/import`, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** @desc 导出团队成员数据 */ +export function exportTeamMembers(params: T.TeamMemberExportQuery) { + return http.get(`${BASE_URL}/team-member/export`, { + params, + responseType: 'blob' + }) +} + +/** @desc 下载导入模板 */ +export function downloadImportTemplate() { + return http.get(`${BASE_URL}/team-member/template`, { + responseType: 'blob' + }) +} + +// ==================== 项目需求管理 ==================== + +/** @desc 获取项目需求列表 */ +export function getProjectRequirements(projectId: string | number) { + return http.get(`${BASE_URL}/project/${projectId}/requirements`) +} + +/** @desc 发布项目需求 */ +export function createProjectRequirement(data: T.CreateProjectRequirementForm) { + return http.post(`${BASE_URL}/requirement`, data) +} + +/** @desc 更新项目需求状态 */ +export function updateRequirementStatus(data: T.UpdateRequirementStatusForm) { + return http.patch(`${BASE_URL}/requirement/status`, data) +} + +/** @desc 删除项目需求 */ +export function deleteProjectRequirement(requirementId: string | number) { + return http.del(`${BASE_URL}/requirement/${requirementId}`) +} + + \ No newline at end of file diff --git a/src/apis/project/type.ts b/src/apis/project/type.ts index 32bc3b7..c15d7e8 100644 --- a/src/apis/project/type.ts +++ b/src/apis/project/type.ts @@ -85,4 +85,250 @@ export interface TaskQuery { status?: string } -export interface TaskPageQuery extends TaskQuery, PageQuery {} \ No newline at end of file +export interface TaskPageQuery extends TaskQuery, PageQuery {} + +// ==================== 人员调度相关类型 ==================== + +/** 项目看板统计数据 */ +export interface ProjectKanbanStats { + totalProjectsCount: string + pendingProjectCount: string + inProgressProjectCount: string + completedProjectCount: string + auditedProjectCount: string + acceptedProjectCount: string + totalTurbineCount: string + pendingTurbineCount: string + inProgressTurbineCount: string + completedTurbineCount: string + auditedTurbineCount: string + acceptedTurbineCount: string + totalTaskCount: string + pendingTaskCount: string + inProgressTaskCount: string + completedTaskCount: string + totalMemberCount: string + projectManagerCount: string + safetyOfficerCount: string + qualityOfficerCount: string + constructorCount: string + teamLeaderCount: string +} + +/** 项目看板数据 */ +export interface ProjectKanbanData { + inProgressProjects: never[] + preparingProjects: ProjectCard[] + ongoingProjects: ProjectCard[] + pendingProjects: ProjectCard[] +} + +/** 项目卡片信息 */ +export interface ProjectCard { + id: string | number + name: string + status: 'preparing' | 'ongoing' | 'pending' + budget: number + manager: string + teamSize: number + preparationProgress?: number + progress?: number + startDate?: string + endDate?: string + plannedStartDate?: string + alerts?: ProjectAlert[] + teamMembers: TeamMemberResp[] + requirements: ProjectRequirementResp[] +} + +/** 项目异常信息 */ +export interface ProjectAlert { + type: 'cost' | 'personnel' | 'schedule' | 'quality' + message: string +} + +/** 项目详情响应 */ +export interface ProjectDetailResp extends ProjectCard { + // 继承ProjectCard的所有字段,可以添加更多详情字段 +} + +/** 团队成员响应 */ +export interface TeamMemberResp { + id: string | number + name: string + position: string + phone?: string + email?: string + avatar?: string + joinDate?: string + performance?: number + remark?: string + status?: 'available' | 'busy' | 'offline' +} + +/** 后端返回的团队成员数据结构 */ +export interface BackendTeamMemberResp { + memberId: string + projectId: string + projectName: string + turbineId: string | null + turbineName: string | null + taskGroupId: string | null + taskGroupName: string | null + taskId: string | null + taskName: string | null + userId: string + name: string + phone: string | null + email: string | null + position: string + status: 'ACTIVE' | 'BUSY' | 'OFFLINE' + skills: string + joinDate: string + remark: string + userAccount: string + userAvatar: string | null + roleType: string + roleTypeDesc: string + jobCode: string + jobCodeDesc: string + jobDesc: string + leaveDate: string | null + statusDesc: string +} + +/** 团队成员查询参数(支持筛选、分页、搜索) */ +export interface TeamMemberQuery extends PageQuery { + projectId: string | number + name?: string // 姓名搜索 + position?: string // 岗位筛选 + status?: string // 状态筛选 + joinDateStart?: string // 入职日期开始 + joinDateEnd?: string // 入职日期结束 + sortBy?: 'name' | 'position' | 'joinDate' | 'status' // 排序字段 + sortOrder?: 'asc' | 'desc' // 排序方向 +} + +/** 团队成员导出查询参数(不包含分页) */ +export interface TeamMemberExportQuery { + projectId: string | number + name?: string // 姓名搜索 + position?: string // 岗位筛选 + status?: string // 状态筛选 + joinDateStart?: string // 入职日期开始 + joinDateEnd?: string // 入职日期结束 + sortBy?: 'name' | 'position' | 'joinDate' | 'status' // 排序字段 + sortOrder?: 'asc' | 'desc' // 排序方向 +} + +/** 创建团队成员表单 */ +export interface CreateTeamMemberForm { + projectId: string | number + name: string + phone: string + email?: string + position: string + status?: 'available' | 'busy' | 'offline' + joinDate?: string + remark?: string +} + +/** 更新团队成员表单 */ +export interface UpdateTeamMemberForm { + name?: string + phone?: string + email?: string + position?: string + status?: 'available' | 'busy' | 'offline' + joinDate?: string + remark?: string +} + + + +/** 批量操作表单 */ +export interface BatchOperationForm { + ids: (string | number)[] + operation: 'delete' | 'updateStatus' + status?: 'available' | 'busy' | 'offline' +} + +/** 导入结果响应 */ +export interface ImportResultResp { + success: boolean + totalCount: number + successCount: number + failCount: number + errors?: Array<{ + row: number + message: string + }> +} + +/** 人员需求响应 */ +export interface PersonnelRequirementResp { + id: string | number + title: string + type: 'personnel' | 'equipment' + position?: string + equipmentType?: string + count: number + skills: string[] + description?: string + priority: 'low' | 'medium' | 'high' + status: 'pending' | 'recruiting' | 'completed' + createTime: string + updateTime: string +} + +/** 创建需求表单 */ +export interface CreateRequirementForm { + projectId: string | number + type: 'personnel' | 'equipment' + position?: string + equipmentType?: string + count: number + skills: string[] + description?: string + priority: 'low' | 'medium' | 'high' +} + +/** 简化项目需求响应类型 */ +export interface ProjectRequirementResp { + id: string | number + title: string + description: string + priority: 'low' | 'medium' | 'high' + status: 'pending' | 'recruiting' | 'completed' + createTime: string + updateTime: string +} + +/** 简化创建项目需求表单类型 */ +export interface CreateProjectRequirementForm { + projectId: string | number + description: string + priority: 'low' | 'medium' | 'high' +} + +/** 更新需求状态表单 */ +export interface UpdateRequirementStatusForm { + requirementId: string | number + status: 'pending' | 'recruiting' | 'completed' +} + + + +/** 分页查询基础参数 */ +export interface PageQuery { + page: number + pageSize: number +} + +/** 分页响应 */ +export interface PageRes { + list: T[] + total: number + page: number + pageSize: number +} \ No newline at end of file diff --git a/src/router/route.ts b/src/router/route.ts index ba06fd2..99cb49e 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -830,6 +830,29 @@ export const systemRoutes: RouteRecordRaw[] = [ }, ], }, + + //项目中控台 + { + path: '/project-management/projects/personnel-dispatch', + name: 'PersonnelDispatch', + component: () => import('@/views/project-management/personnel-dispatch/index.vue'), + meta: { + title: '项目中控台', + icon: 'user-group', + hidden: false, + }, + }, + + { + path: '/project-management/personnel-dispatch/construction-personnel', + name: 'ConstructionPersonnel', + component: () => import('@/views/project-management/personnel-dispatch/construction-personnel.vue'), + meta: { + title: '团队成员管理', + icon: 'user', + hidden: true, + }, + }, ], }, diff --git a/src/views/project-management/personnel-dispatch/construction-personnel.vue b/src/views/project-management/personnel-dispatch/construction-personnel.vue new file mode 100644 index 0000000..f891def --- /dev/null +++ b/src/views/project-management/personnel-dispatch/construction-personnel.vue @@ -0,0 +1,952 @@ + + + + + + \ No newline at end of file diff --git a/src/views/project-management/personnel-dispatch/index.vue b/src/views/project-management/personnel-dispatch/index.vue new file mode 100644 index 0000000..7903e24 --- /dev/null +++ b/src/views/project-management/personnel-dispatch/index.vue @@ -0,0 +1,1372 @@ + + + + + + \ No newline at end of file