diff --git a/docs/dev-ops/pgsql/sql/init_permissions.sql b/docs/dev-ops/pgsql/sql/init_permissions.sql index e4c829e..297cbfd 100644 --- a/docs/dev-ops/pgsql/sql/init_permissions.sql +++ b/docs/dev-ops/pgsql/sql/init_permissions.sql @@ -13,22 +13,22 @@ -- 系统管理菜单(parent_id 为 NULL 表示顶级菜单) INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (1, NULL, 'system:manage', '系统管理', 1, '/system', 'Layout', 'Setting', 1, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 用户管理菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (2, 1, 'system:user', '用户管理', 1, '/system/user', 'system/user/index', 'User', 1, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 角色管理菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (3, 1, 'system:role', '角色管理', 1, '/system/role', 'system/role/index', 'Role', 2, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 权限管理菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (4, 1, 'system:permission', '权限管理', 1, '/system/permission', 'system/permission/index', 'Lock', 3, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 2. 插入用户管理相关按钮权限 @@ -42,7 +42,7 @@ VALUES (104, 2, 'system:user:update', '修改用户', 2, '/api/v1/system/user', 'PUT', 4, 1, 1, NOW(), NOW(), 0), (105, 2, 'system:user:delete', '删除用户', 2, '/api/v1/system/user/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), (106, 2, 'system:user:bindRole', '绑定角色', 2, '/api/v1/system/user/*/roles', 'POST', 6, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 3. 插入角色管理相关按钮权限 @@ -56,7 +56,7 @@ VALUES (204, 3, 'system:role:update', '修改角色', 2, '/api/v1/system/role', 'PUT', 4, 1, 1, NOW(), NOW(), 0), (205, 3, 'system:role:delete', '删除角色', 2, '/api/v1/system/role/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), (206, 3, 'system:role:bindPermission', '分配权限', 2, '/api/v1/system/role/*/permissions', 'POST', 6, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 4. 插入权限管理相关按钮权限 @@ -70,7 +70,7 @@ VALUES (304, 4, 'system:permission:update', '修改权限', 2, '/api/v1/system/permission', 'PUT', 4, 1, 1, NOW(), NOW(), 0), (305, 4, 'system:permission:delete', '删除权限', 2, '/api/v1/system/permission/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), (306, 4, 'system:permission:tree', '权限树', 2, '/api/v1/system/permission/tree', 'GET', 6, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 5. 插入项目管理相关权限(三级结构) @@ -79,12 +79,12 @@ VALUES -- 一级:项目管理菜单(parent_id 为 NULL 表示顶级菜单) INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (10, NULL, 'project:manage', '项目管理', 1, '/project', 'Layout', 'Project', 2, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 二级:项目中心菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (11, 10, 'project:center', '项目中心', 1, '/project/center', 'project/center/index', 'Folder', 1, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 三级:项目中心按钮权限 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, api_url, api_method, sort_order, visible, status, create_time, update_time, deleted) @@ -94,19 +94,19 @@ VALUES (1003, 11, 'project:center:create', '创建项目', 2, '/api/v1/project', 'POST', 3, 1, 1, NOW(), NOW(), 0), (1004, 11, 'project:center:update', '编辑项目', 2, '/api/v1/project', 'PUT', 4, 1, 1, NOW(), NOW(), 0), (1005, 11, 'project:center:delete', '删除项目', 2, '/api/v1/project/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 二级:我的项目菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (12, 10, 'project:my', '我的项目', 1, '/project/my', 'project/my/index', 'User', 2, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 三级:我的项目按钮权限 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, api_url, api_method, sort_order, visible, status, create_time, update_time, deleted) VALUES (1101, 12, 'project:my:list', '我的项目列表', 2, '/api/v1/project/my/list', 'GET', 1, 1, 1, NOW(), NOW(), 0), (1102, 12, 'project:my:view', '查看我的项目', 2, '/api/v1/project/my/*', 'GET', 2, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 6. 插入任务管理相关权限(三级结构) @@ -115,7 +115,7 @@ VALUES -- 二级:任务管理菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (13, 10, 'project:task', '任务管理', 1, '/project/task', 'project/task/index', 'Task', 3, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 三级:任务管理按钮权限 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, api_url, api_method, sort_order, visible, status, create_time, update_time, deleted) @@ -127,7 +127,7 @@ VALUES (1205, 13, 'project:task:delete', '删除任务', 2, '/api/v1/task/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), (1206, 13, 'project:task:my', '我的任务', 2, '/api/v1/task/my-tasks', 'GET', 6, 1, 1, NOW(), NOW(), 0), (1207, 13, 'project:task:stats', '任务统计', 2, '/api/v1/task/stats/*', 'GET', 7, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ -- 7. 插入里程碑管理相关权限(三级结构) @@ -136,7 +136,7 @@ VALUES -- 二级:里程碑管理菜单 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) VALUES (14, 10, 'project:milestone', '里程碑管理', 1, '/project/milestone', 'project/milestone/index', 'Flag', 4, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- 三级:里程碑管理按钮权限 INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, api_url, api_method, sort_order, visible, status, create_time, update_time, deleted) @@ -147,10 +147,30 @@ VALUES (1304, 14, 'project:milestone:update', '修改里程碑', 2, '/api/v1/milestone', 'PUT', 4, 1, 1, NOW(), NOW(), 0), (1305, 14, 'project:milestone:delete', '删除里程碑', 2, '/api/v1/milestone/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), (1306, 14, 'project:milestone:stats', '里程碑统计', 2, '/api/v1/milestone/stats/*', 'GET', 6, 1, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; -- ============================================ --- 8. 插入系统角色 +-- 8. 插入资源管理相关权限(三级结构) +-- ============================================ + +-- 二级:资源管理菜单 +INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, path, component, icon, sort_order, visible, status, create_time, update_time, deleted) +VALUES (15, 10, 'project:resource', '资源管理', 1, '/project/resource', 'project/resource/index', 'Box', 5, 1, 1, NOW(), NOW(), 0) +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; + +-- 三级:资源管理按钮权限 +INSERT INTO sys_permission (id, parent_id, permission_code, permission_name, permission_type, api_url, api_method, sort_order, visible, status, create_time, update_time, deleted) +VALUES + (1401, 15, 'project:resource:list', '资源列表', 2, '/api/v1/resource/list', 'GET', 1, 1, 1, NOW(), NOW(), 0), + (1402, 15, 'project:resource:view', '查看资源', 2, '/api/v1/resource/*', 'GET', 2, 1, 1, NOW(), NOW(), 0), + (1403, 15, 'project:resource:create', '新增资源', 2, '/api/v1/resource', 'POST', 3, 1, 1, NOW(), NOW(), 0), + (1404, 15, 'project:resource:update', '修改资源', 2, '/api/v1/resource', 'PUT', 4, 1, 1, NOW(), NOW(), 0), + (1405, 15, 'project:resource:delete', '删除资源', 2, '/api/v1/resource/*', 'DELETE', 5, 1, 1, NOW(), NOW(), 0), + (1406, 15, 'project:resource:stats', '资源统计', 2, '/api/v1/resource/stats/*', 'GET', 6, 1, 1, NOW(), NOW(), 0) +ON CONFLICT (id) DO UPDATE SET permission_code = EXCLUDED.permission_code, permission_name = EXCLUDED.permission_name; + +-- ============================================ +-- 9. 插入系统角色 -- ============================================ INSERT INTO sys_role (id, role_code, role_name, role_type, description, data_scope, sort_order, status, create_time, update_time, deleted) @@ -159,28 +179,43 @@ VALUES (2, 'project_manager', '项目经理', 'system', '负责项目管理', 4, 2, 1, NOW(), NOW(), 0), (3, 'team_leader', '团队负责人', 'system', '负责团队管理', 4, 3, 1, NOW(), NOW(), 0), (4, 'member', '普通成员', 'system', '普通项目成员', 3, 4, 1, NOW(), NOW(), 0) - ON CONFLICT (id) DO UPDATE SET role_code = EXCLUDED.role_code, role_name = EXCLUDED.role_name; +ON CONFLICT (id) DO UPDATE SET role_code = EXCLUDED.role_code, role_name = EXCLUDED.role_name; -- ============================================ --- 9. 给admin角色分配所有权限 +-- 10. 给admin角色分配所有权限 -- ============================================ INSERT INTO sys_role_permission (role_id, permission_id, create_time) SELECT 1, id, NOW() FROM sys_permission WHERE deleted = 0 - ON CONFLICT DO NOTHING; +ON CONFLICT DO NOTHING; -- ============================================ --- 10. 给项目经理分配项目相关权限 +-- 11. 给项目经理分配项目相关权限 +-- 包括:项目中心、我的项目、任务管理、里程碑管理、资源管理等所有 project: 开头的权限 -- ============================================ INSERT INTO sys_role_permission (role_id, permission_id, create_time) SELECT 2, id, NOW() FROM sys_permission WHERE permission_code LIKE 'project:%' AND deleted = 0 - ON CONFLICT DO NOTHING; +ON CONFLICT DO NOTHING; -- ============================================ --- 11. 给普通成员分配查看权限 +-- 12. 给普通成员分配查看权限 +-- 包括:所有列表和查看权限(如 project:task:list, project:task:view 等) -- ============================================ INSERT INTO sys_role_permission (role_id, permission_id, create_time) SELECT 4, id, NOW() FROM sys_permission WHERE permission_code LIKE '%:view' OR permission_code LIKE '%:list' AND deleted = 0 - ON CONFLICT DO NOTHING; +ON CONFLICT DO NOTHING; + +-- ============================================ +-- 13. 给团队负责人分配任务和资源管理权限(除删除外) +-- ============================================ + +INSERT INTO sys_role_permission (role_id, permission_id, create_time) +SELECT 3, id, NOW() FROM sys_permission +WHERE permission_code IN ( + 'project:task:list', 'project:task:view', 'project:task:create', 'project:task:update', 'project:task:my', 'project:task:stats', + 'project:milestone:list', 'project:milestone:view', 'project:milestone:create', 'project:milestone:update', 'project:milestone:stats', + 'project:resource:list', 'project:resource:view', 'project:resource:create', 'project:resource:update', 'project:resource:stats' + ) AND deleted = 0 +ON CONFLICT DO NOTHING; diff --git a/src/main/java/cn/yinlihupo/controller/project/ResourceController.java b/src/main/java/cn/yinlihupo/controller/project/ResourceController.java new file mode 100644 index 0000000..a07c797 --- /dev/null +++ b/src/main/java/cn/yinlihupo/controller/project/ResourceController.java @@ -0,0 +1,231 @@ +package cn.yinlihupo.controller.project; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.yinlihupo.common.core.BaseResponse; +import cn.yinlihupo.common.util.ResultUtils; +import cn.yinlihupo.domain.dto.ResourceUpdateRequest; +import cn.yinlihupo.domain.entity.Resource; +import cn.yinlihupo.domain.entity.SysUser; +import cn.yinlihupo.mapper.ResourceMapper; +import cn.yinlihupo.mapper.SysUserMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +/** + * 资源管理控制器 + */ +@Slf4j +@RestController +@RequestMapping("/api/v1/resource") +@RequiredArgsConstructor +public class ResourceController { + + private final ResourceMapper resourceMapper; + private final SysUserMapper sysUserMapper; + + /** + * 分页查询资源列表 + */ + @SaCheckPermission("project:resource:list") + @GetMapping("/list") + public BaseResponse>> list( + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize, + @RequestParam(required = false) Long projectId, + @RequestParam(required = false) String resourceType, + @RequestParam(required = false) String status, + @RequestParam(required = false) String keyword) { + + Page> page = new Page<>(pageNum, pageSize); + List> records = resourceMapper.selectResourcePageWithResponsible( + projectId, resourceType, status, keyword); + + page.setRecords(records); + page.setTotal(records.size()); + + return ResultUtils.success("查询成功", page); + } + + /** + * 根据ID查询资源详情 + */ + @SaCheckPermission("project:resource:view") + @GetMapping("/{id}") + public BaseResponse getById(@PathVariable Long id) { + Resource resource = resourceMapper.selectById(id); + if (resource == null || resource.getDeleted() == 1) { + return ResultUtils.error("资源不存在"); + } + return ResultUtils.success("查询成功", resource); + } + + /** + * 新增资源 + */ + @SaCheckPermission("project:resource:create") + @PostMapping + public BaseResponse create(@RequestBody Resource resource) { + if (resource.getProjectId() == null) { + return ResultUtils.error("项目ID不能为空"); + } + if (!StringUtils.hasText(resource.getResourceName())) { + return ResultUtils.error("资源名称不能为空"); + } + + // 设置默认值 + if (resource.getStatus() == null) { + resource.setStatus("planned"); + } + if (resource.getCurrency() == null) { + resource.setCurrency("CNY"); + } + + resourceMapper.insert(resource); + log.info("新增资源成功, id: {}, resourceName: {}", resource.getId(), resource.getResourceName()); + return ResultUtils.success("新增成功", resource.getId()); + } + + /** + * 修改资源 + */ + @SaCheckPermission("project:resource:update") + @PutMapping + public BaseResponse update(@RequestBody ResourceUpdateRequest request) { + if (request.getId() == null) { + return ResultUtils.error("资源ID不能为空"); + } + + Resource exist = resourceMapper.selectById(request.getId()); + if (exist == null || exist.getDeleted() == 1) { + return ResultUtils.error("资源不存在"); + } + + // 将DTO转换为实体 + Resource resource = new Resource(); + BeanUtils.copyProperties(request, resource); + + // 如果传递了responsibleName,根据姓名查询用户ID + if (StringUtils.hasText(request.getResponsibleName())) { + SysUser user = sysUserMapper.selectByRealName(request.getResponsibleName()); + if (user != null) { + resource.setResponsibleId(user.getId()); + log.debug("资源负责人 '{}' 匹配到用户 ID: {}", request.getResponsibleName(), user.getId()); + } else { + log.warn("资源负责人 '{}' 未在系统中找到匹配的用户", request.getResponsibleName()); + } + } + + // 不更新敏感字段 + resource.setCreateTime(null); + resource.setDeleted(null); + resource.setResourceCode(null); + + resourceMapper.updateById(resource); + log.info("修改资源成功, id: {}", resource.getId()); + return ResultUtils.success("修改成功", null); + } + + /** + * 删除资源 + */ + @SaCheckPermission("project:resource:delete") + @DeleteMapping("/{id}") + public BaseResponse delete(@PathVariable Long id) { + Resource resource = resourceMapper.selectById(id); + if (resource == null || resource.getDeleted() == 1) { + return ResultUtils.error("资源不存在"); + } + + resourceMapper.deleteById(id); + log.info("删除资源成功, id: {}", id); + return ResultUtils.success("删除成功", null); + } + + /** + * 更新资源状态 + */ + @SaCheckPermission("project:resource:update") + @PutMapping("/{id}/status") + public BaseResponse updateStatus(@PathVariable Long id, @RequestParam String status) { + Resource resource = resourceMapper.selectById(id); + if (resource == null || resource.getDeleted() == 1) { + return ResultUtils.error("资源不存在"); + } + + resource.setStatus(status); + + // 如果状态变为已到货,设置实际到位日期 + if ("arrived".equals(status) || "in_use".equals(status) || "completed".equals(status)) { + if (resource.getActualArriveDate() == null) { + resource.setActualArriveDate(java.time.LocalDate.now()); + } + } + + resourceMapper.updateById(resource); + log.info("更新资源状态成功, id: {}, status: {}", id, status); + return ResultUtils.success("更新成功", null); + } + + /** + * 更新资源数量 + */ + @SaCheckPermission("project:resource:update") + @PutMapping("/{id}/quantity") + public BaseResponse updateQuantity(@PathVariable Long id, + @RequestParam BigDecimal actualQuantity) { + if (actualQuantity == null || actualQuantity.compareTo(BigDecimal.ZERO) < 0) { + return ResultUtils.error("实际数量不能为负数"); + } + + Resource resource = resourceMapper.selectById(id); + if (resource == null || resource.getDeleted() == 1) { + return ResultUtils.error("资源不存在"); + } + + resource.setActualQuantity(actualQuantity); + resourceMapper.updateById(resource); + log.info("更新资源数量成功, id: {}, actualQuantity: {}", id, actualQuantity); + return ResultUtils.success("更新成功", null); + } + + /** + * 查询资源预算汇总 + */ + @SaCheckPermission("project:resource:stats") + @GetMapping("/stats/budget") + public BaseResponse>> getBudgetSummary(@RequestParam Long projectId) { + List> stats = resourceMapper.selectResourceBudgetSummary(projectId); + return ResultUtils.success("查询成功", stats); + } + + /** + * 查询即将到位的资源 + */ + @SaCheckPermission("project:resource:view") + @GetMapping("/pending-arrival") + public BaseResponse> getPendingArrivalResources( + @RequestParam Long projectId, + @RequestParam(defaultValue = "7") int days) { + List resources = resourceMapper.selectPendingArrivalResources(projectId, days); + return ResultUtils.success("查询成功", resources); + } + + /** + * 查询待审批的资源申请 + */ + @SaCheckPermission("project:resource:view") + @GetMapping("/pending-approval") + public BaseResponse>> getPendingApprovalResources( + @RequestParam(required = false) Long projectId) { + List> resources = resourceMapper.selectPendingApprovalResources(projectId); + return ResultUtils.success("查询成功", resources); + } +} diff --git a/src/main/java/cn/yinlihupo/domain/dto/ResourceUpdateRequest.java b/src/main/java/cn/yinlihupo/domain/dto/ResourceUpdateRequest.java new file mode 100644 index 0000000..5c311ba --- /dev/null +++ b/src/main/java/cn/yinlihupo/domain/dto/ResourceUpdateRequest.java @@ -0,0 +1,109 @@ +package cn.yinlihupo.domain.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +/** + * 资源更新请求DTO + */ +@Data +public class ResourceUpdateRequest { + + /** + * 资源ID(必填) + */ + private Long id; + + /** + * 资源类型: human-人力, material-物料, equipment-设备, software-软件, finance-资金, other-其他 + */ + private String resourceType; + + /** + * 资源名称 + */ + private String resourceName; + + /** + * 资源描述 + */ + private String description; + + /** + * 规格型号 + */ + private String specification; + + /** + * 单位 + */ + private String unit; + + /** + * 计划数量 + */ + private BigDecimal planQuantity; + + /** + * 实际数量 + */ + private BigDecimal actualQuantity; + + /** + * 单价 + */ + private BigDecimal unitPrice; + + /** + * 币种 + */ + private String currency; + + /** + * 供应商/来源 + */ + private String supplier; + + /** + * 状态: planned-计划中, requested-已申请, approved-已批准, procuring-采购中, arrived-已到货, in_use-使用中, completed-已完成 + */ + private String status; + + /** + * 计划到位日期 + */ + private LocalDate planArriveDate; + + /** + * 实际到位日期 + */ + private LocalDate actualArriveDate; + + /** + * 负责人ID(直接传递ID时使用) + */ + private Long responsibleId; + + /** + * 负责人姓名(根据姓名自动匹配用户ID) + */ + private String responsibleName; + + /** + * 存放位置 + */ + private String location; + + /** + * 标签 + */ + private List tags; + + /** + * 扩展数据 + */ + private Object extraData; +}