feat(resource): 初始化权限数据并实现资源管理接口

- 新增初始化系统权限的SQL脚本,包含菜单权限、按钮权限及角色权限分配
- 实现资源管理RestController,支持资源的增删改查操作
- 资源接口支持分页查询、按ID查询以及状态和数量更新
- 增加资源预算汇总、即将到位资源和待审批资源查询接口
- 新增资源更新请求DTO,支持详细的资源属性修改及负责人自动匹配功能
- 权限检查基于注解实现,保障接口安全性与权限控制有效性
This commit is contained in:
2026-03-31 17:37:16 +08:00
parent b4f2ea2df2
commit a4ad01ba64
3 changed files with 399 additions and 24 deletions

View File

@@ -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;

View File

@@ -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<Page<Map<String, Object>>> 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<Map<String, Object>> page = new Page<>(pageNum, pageSize);
List<Map<String, Object>> 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<Resource> 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<Long> 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<Void> 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<Void> 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<Void> 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<Void> 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<List<Map<String, Object>>> getBudgetSummary(@RequestParam Long projectId) {
List<Map<String, Object>> stats = resourceMapper.selectResourceBudgetSummary(projectId);
return ResultUtils.success("查询成功", stats);
}
/**
* 查询即将到位的资源
*/
@SaCheckPermission("project:resource:view")
@GetMapping("/pending-arrival")
public BaseResponse<List<Resource>> getPendingArrivalResources(
@RequestParam Long projectId,
@RequestParam(defaultValue = "7") int days) {
List<Resource> resources = resourceMapper.selectPendingArrivalResources(projectId, days);
return ResultUtils.success("查询成功", resources);
}
/**
* 查询待审批的资源申请
*/
@SaCheckPermission("project:resource:view")
@GetMapping("/pending-approval")
public BaseResponse<List<Map<String, Object>>> getPendingApprovalResources(
@RequestParam(required = false) Long projectId) {
List<Map<String, Object>> resources = resourceMapper.selectPendingApprovalResources(projectId);
return ResultUtils.success("查询成功", resources);
}
}

View File

@@ -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<String> tags;
/**
* 扩展数据
*/
private Object extraData;
}