qiangdanxitong/docs/一级需求部门功能开发文档.md
Your Name c99a927cca feat: 添加一级需求部门功能
- 新增一级需求部门类型和品牌关联管理
- 新增一级需求部门任务创建、审核、明细完善流程
- 新增一级需求部门数据分析模块
- 任务卡片显示一级需求人信息
- 部门管理增加品牌关联配置
2026-01-19 20:58:09 +08:00

820 lines
37 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一级需求部门功能开发文档
## 📋 需求概述
### 业务背景
当前系统中部门类型分为"需求部门"和"接单部门"。现需要新增"一级需求部门"类型,用于支持更上层的需求发起流程。一级需求部门可以发起简化的需求任务,由下级需求部门负责完善任务明细后再发布到设计部门。
### 核心功能
1. 新增"一级需求部门"部门类型
2. 一级需求部门可发起简化需求(任务明细可不填)
3. 需求部门可设置负责的品牌
4. 根据品牌自动路由到对应需求部门审核
5. 需求部门完善任务明细后继续原有流程
6. 任务卡片显示"一级部门需求人"信息
---
## 🔄 业务流程
### 一级需求部门发起任务流程
```
┌─────────────────┐
│ 一级需求部门用户 │
│ 发起需求 │
│ (可不填明细) │
└────────┬────────┘
│ 选择品牌
▼
┌─────────────────┐
│ 系统根据品牌 │
│ 路由到对应 │
│ 需求部门负责人 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 需求部门负责人 │
│ 审核需求 │
│ 指定成员完善 │
└────────┬────────┘
│ 审核通过
▼
┌─────────────────┐
│ 需求部门成员 │
│ 完善任务明细 │
│ 提交发布 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 进入原有流程 │
│ (需求部门审核 │
│ → 接单部门) │
└─────────────────┘
```
### 任务状态流转
| 阶段 | 状态 | 说明 |
|-----|------|------|
| 一级部门发起 | `pending_primary_approval` | 待一级审核(需求部门负责人审核) |
| 需求部门审核通过 | `pending_detail_completion` | 待完善明细 |
| 明细完善提交 | `pending_demand_approval` | 进入原有需求部门审核流程 |
### 积分流转逻辑
```
┌─────────────────────────────────────────────────────────────────┐
│ 积分流转说明 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 一级需求部门发起任务 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 校验一级部门积分 │ ← 积分不足则不允许发起 │
│ └────────┬────────┘ │
│ │ 积分充足 │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 暂不扣除积分 │ ← 等待需求部门审核 │
│ └────────┬────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ ▼ ▼ │
│ [审核通过] [审核驳回] │
│ │ │ │
│ │ ▼ │
│ │ ┌───────────┐ │
│ │ │ 不扣积分 │ ← 驳回不产生积分变动 │
│ │ └───────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 需求部门完善明细 │ │
│ │ 提交发布 │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 扣除一级部门积分 │ ← 只扣一级部门,不扣需求部门 │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 任务进入正常流程 │ │
│ └─────────────────┘ │
│ │
│ 【任务撤回/取消时】 │
│ 积分返还给一级需求部门(非需求部门) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
| 场景 | 一级部门积分 | 需求部门积分 |
|-----|------------|-------------|
| 一级部门发起任务 | 校验余额,暂不扣除 | 不变 |
| 需求部门审核驳回 | 不变 | 不变 |
| 需求部门完善后发布 | **扣除** | 不变 |
| 任务撤回/取消 | **返还** | 不变 |
| 任务完成 | 不变 | 不变 |
---
## 📊 数据库设计
### 0. 系统配置表 `sys_config` 新增配置项
```sql
-- 新增系统配置:一级需求部门是否允许填写任务明细
INSERT INTO sys_config (config_key, config_value, config_name, config_group, description, create_time)
VALUES ('primary_dept_can_fill_detail', 'false', '一级需求部门可填写明细', 'task', '开启后一级需求部门发布任务时可以填写任务明细,关闭后不允许填写', NOW());
```
| 配置项 | 默认值 | 说明 |
|-------|-------|------|
| primary_dept_can_fill_detail | false | 一级需求部门是否允许填写任务明细 |
### 1. 部门表 `sys_dept` 修改
```sql
-- 新增字段
ALTER TABLE sys_dept ADD COLUMN responsible_brand_ids VARCHAR(500) COMMENT '负责的品牌ID列表(逗号分隔)';
-- 修改 dept_type 字段说明
-- dept_type: primary_demand-一级需求部门, demand-需求部门, receiving-接单部门
```
| 字段名 | 类型 | 说明 |
|-------|------|------|
| responsible_brand_ids | VARCHAR(500) | 负责的品牌ID列表(逗号分隔),仅需求部门使用 |
### 2. 任务表 `task` 修改
```sql
-- 新增字段
ALTER TABLE task ADD COLUMN primary_publisher_id BIGINT COMMENT '一级部门发起人ID';
ALTER TABLE task ADD COLUMN primary_publisher_dept_id BIGINT COMMENT '一级部门ID';
ALTER TABLE task ADD COLUMN detail_completer_id BIGINT COMMENT '明细完善人ID';
ALTER TABLE task ADD COLUMN is_primary_task TINYINT DEFAULT 0 COMMENT '是否一级部门任务:0-否,1-是';
ALTER TABLE task ADD COLUMN detail_completed TINYINT DEFAULT 0 COMMENT '明细是否已完善:0-否,1-是';
```
| 字段名 | 类型 | 说明 |
|-------|------|------|
| primary_publisher_id | BIGINT | 一级部门发起人ID |
| primary_publisher_dept_id | BIGINT | 一级部门ID |
| detail_completer_id | BIGINT | 明细完善人ID(需求部门指定的成员) |
| is_primary_task | TINYINT | 是否一级部门任务:0-否,1-是 |
| detail_completed | TINYINT | 明细是否已完善:0-否,1-是 |
### 3. 新增品牌-部门关联表 `dept_brand_relation`
```sql
CREATE TABLE dept_brand_relation (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
dept_id BIGINT NOT NULL COMMENT '部门ID(需求部门)',
brand_id BIGINT NOT NULL COMMENT '品牌ID',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UNIQUE KEY uk_brand_id (brand_id), -- 一个品牌只能对应一个需求部门
INDEX idx_dept_id (dept_id)
) COMMENT '部门品牌负责关系表';
```
> ⚠️ **注意**:
> - `brand_id` 设置唯一索引,确保一个品牌只能被一个需求部门负责
> - **支持多品牌对应一个需求部门**:一个需求部门可以负责多个品牌
**品牌-部门关系示例**:
| 需求部门 | 负责品牌 |
|---------|---------|
| 设计一部 | 品牌A、品牌B、品牌C |
| 设计二部 | 品牌D、品牌E |
| 设计三部 | 品牌F |
---
## 🔧 后端开发
### 1. 实体类修改
#### Department.java
```java
// 新增字段
private String responsibleBrandIds; // 负责的品牌ID列表
// dept_type 可选值新增
// primary_demand - 一级需求部门
// demand - 需求部门
// receiving - 接单部门
```
#### Task.java
```java
// 新增字段
private Long primaryPublisherId; // 一级部门发起人ID
private Long primaryPublisherDeptId; // 一级部门ID
private Long detailCompleterId; // 明细完善人ID
private Integer isPrimaryTask; // 是否一级部门任务
private Integer detailCompleted; // 明细是否已完善
```
### 2. 新增实体类
#### DeptBrandRelation.java
```java
@TableName("dept_brand_relation")
public class DeptBrandRelation {
private Long id;
private Long deptId;
private Long brandId;
private LocalDateTime createTime;
}
```
### 3. Service 层修改
#### DepartmentService.java
```java
// 新增方法
// 根据品牌ID获取负责的需求部门
Department getDemandDeptByBrandId(Long brandId);
// 设置部门负责的品牌
void setDeptResponsibleBrands(Long deptId, List<Long> brandIds);
// 获取部门负责的品牌列表
List<Brand> getDeptResponsibleBrands(Long deptId);
```
#### TaskService.java
```java
// 新增方法
// 一级部门创建任务(简化版)
Task createPrimaryTask(TaskCreateDTO dto, Long userId);
// 需求部门审核一级任务并指定完善人
void approvePrimaryTask(Long taskId, Long completerId, Long approverId);
// 完善任务明细
void completeTaskDetail(Long taskId, TaskDetailDTO dto, Long userId);
```
### 4. Controller 层修改
#### TaskController.java
```java
// 新增接口
@PostMapping("/primary")
Result<Task> createPrimaryTask(@RequestBody TaskCreateDTO dto);
@PostMapping("/{id}/approve-primary")
Result<Void> approvePrimaryTask(@PathVariable Long id, @RequestParam Long completerId);
@PostMapping("/{id}/complete-detail")
Result<Void> completeTaskDetail(@PathVariable Long id, @RequestBody TaskDetailDTO dto);
```
#### DepartmentController.java
```java
// 新增接口
@PostMapping("/{id}/responsible-brands")
Result<Void> setResponsibleBrands(@PathVariable Long id, @RequestBody List<Long> brandIds);
@GetMapping("/{id}/responsible-brands")
Result<List<Brand>> getResponsibleBrands(@PathVariable Long id);
```
### 5. 审核状态新增
```java
// ApprovalStatus 新增状态
PENDING_PRIMARY_APPROVAL("pending_primary_approval", "待一级审核"),
PENDING_DETAIL_COMPLETION("pending_detail_completion", "待完善明细"),
```
### 6. 数据分析Service扩展
#### AnalyticsService.java
```java
// 新增方法
/**
* 获取一级需求部门统计数据
*/
PrimaryDeptStatisticsVO getPrimaryDeptStatistics(Long deptId, LocalDateTime startTime, LocalDateTime endTime);
/**
* 获取一级需求部门排名
*/
List<PrimaryDeptRankingVO> getPrimaryDeptRanking(LocalDateTime startTime, LocalDateTime endTime);
/**
* 获取一级需求流转效率分析
*/
PrimaryTaskFlowEfficiencyVO getPrimaryTaskFlowEfficiency(LocalDateTime startTime, LocalDateTime endTime);
/**
* 获取品牌任务分布(一级需求)
*/
List<BrandTaskDistributionVO> getPrimaryTaskBrandDistribution(LocalDateTime startTime, LocalDateTime endTime);
```
#### 新增VO类
```java
// PrimaryDeptStatisticsVO.java - 一级需求部门统计
public class PrimaryDeptStatisticsVO {
private Integer totalTasks; // 发起任务数
private Integer approvedTasks; // 审核通过数
private Integer rejectedTasks; // 审核驳回数
private BigDecimal consumedScore; // 消耗积分
private BigDecimal taskGrowthRate; // 任务增长率
private BigDecimal approvalGrowthRate; // 通过增长率
private BigDecimal rejectGrowthRate; // 驳回增长率
private BigDecimal scoreGrowthRate; // 积分增长率
}
// PrimaryDeptRankingVO.java - 一级需求部门排名
public class PrimaryDeptRankingVO {
private Integer rank; // 排名
private Long deptId; // 部门ID
private String deptName; // 部门名称
private Integer taskCount; // 发起任务数
private BigDecimal approvalRate; // 审核通过率
private BigDecimal consumedScore; // 消耗积分
private Double avgResponseHours; // 平均响应时间(小时)
}
// PrimaryTaskFlowEfficiencyVO.java - 一级需求流转效率
public class PrimaryTaskFlowEfficiencyVO {
private Double avgSubmitToReviewHours; // 发起到审核平均耗时
private Double avgReviewToCompleteHours; // 审核到完善平均耗时
private Double avgCompleteToPublishHours; // 完善到发布平均耗时
private Double avgPublishToFinishHours; // 发布到完成平均耗时
private Double avgTotalHours; // 平均总耗时
}
// BrandTaskDistributionVO.java - 品牌任务分布
public class BrandTaskDistributionVO {
private Long brandId; // 品牌ID
private String brandName; // 品牌名称
private Integer taskCount; // 任务数
private BigDecimal percentage; // 占比
private Long responsibleDeptId; // 负责部门ID
private String responsibleDeptName; // 负责部门名称
}
```
### 7. 数据分析Controller扩展
#### AnalyticsController.java
```java
// 新增接口
@GetMapping("/primary-dept/statistics")
@Operation(summary = "获取一级需求部门统计数据")
Result<PrimaryDeptStatisticsVO> getPrimaryDeptStatistics(
@RequestParam(required = false) Long deptId,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime
);
@GetMapping("/primary-dept/ranking")
@Operation(summary = "获取一级需求部门排名")
Result<List<PrimaryDeptRankingVO>> getPrimaryDeptRanking(
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime
);
@GetMapping("/primary-task/flow-efficiency")
@Operation(summary = "获取一级需求流转效率分析")
Result<PrimaryTaskFlowEfficiencyVO> getPrimaryTaskFlowEfficiency(
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime
);
@GetMapping("/primary-task/brand-distribution")
@Operation(summary = "获取品牌任务分布(一级需求)")
Result<List<BrandTaskDistributionVO>> getPrimaryTaskBrandDistribution(
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime
);
```
---
## 🎨 前端开发
### 1. 系统设置页面修改
#### 新增"一级需求部门设置"配置项
- **配置名称**:一级需求部门可填写任务明细
- **配置说明**:开启后一级需求部门发布任务时可以填写任务明细,关闭后不允许填写
- **控件类型**:开关(Switch)
- **默认值**:关闭
```
┌─────────────────────────────────────────────────────────────┐
│ 一级需求部门设置 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 一级需求部门可填写任务明细 [关闭 ○━━━━━━━━━━━○ 开启] │
│ │
│ 说明:关闭后,一级需求部门发布任务时无法填写任务明细, │
│ 任务明细将完全由需求部门成员填写。 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 2. 部门管理页面修改
#### 部门类型选择
- 新增"一级需求部门"选项
- 部门类型:一级需求部门 / 需求部门 / 接单部门
#### 需求部门设置
- 新增"负责品牌"多选配置
- 仅当部门类型为"需求部门"时显示
### 3. 任务发起页面修改
#### 一级需求部门用户
- 根据系统配置 `primary_dept_can_fill_detail` 控制任务明细区域
- **开启**:显示任务明细填写区域(选填)
- **关闭**:隐藏或禁用任务明细填写区域,显示提示"任务明细将由需求部门填写"
- 必填项:品牌、基本需求描述、积分预算
- 品牌选择后显示提示:"该任务将发送至 [XX部门] 审核"
#### 表单字段变化
| 字段 | 普通需求部门 | 一级需求部门(开启明细填写) | 一级需求部门(关闭明细填写) |
|-----|------------|---------------------------|---------------------------|
| 品牌 | 必填 | 必填 | 必填 |
| 任务标题 | 必填 | 必填 | 必填 |
| 需求描述 | 必填 | 必填 | 必填 |
| 任务明细 | 必填 | 选填 | **隐藏/禁用** |
| 预估积分 | 必填 | 必填 | 必填 |
| 附件 | 选填 | 选填 | 选填 |
| 指定设计师 | 可选 | **不支持** | **不支持** |
| 指定需求部门 | 可选 | **不支持**(通过品牌自动路由) | **不支持** |
> 💡 **系统配置**:`primary_dept_can_fill_detail`
> - **开启(true)**:一级需求部门可以选填任务明细
> - **关闭(false)**:一级需求部门不显示/禁用任务明细填写区域,明细完全由需求部门填写
#### 需求部门完善明细时的表单权限
| 字段 | 是否可编辑 | 说明 |
|-----|-----------|------|
| 品牌 | ❌ 不可编辑 | 一级部门已选定 |
| 任务标题 | ❌ 不可编辑 | 一级部门已填写 |
| 需求描述 | ❌ 不可编辑 | 一级部门已填写 |
| 预估积分 | ❌ 不可编辑 | 一级部门已填写 |
| 附件(基本) | ❌ 不可编辑 | 一级部门已上传 |
| 任务明细 | ✅ 可编辑 | 需求部门完善 |
| 明细附件 | ✅ 可编辑 | 需求部门补充 |
### 4. 任务大厅页面修改
#### 任务卡片
- 新增显示"一级部门需求人"字段(仅一级部门任务显示)
- 格式:`一级需求人: 张三 (运营一部)`
#### 筛选条件
- 新增"任务来源"筛选:全部 / 普通需求 / 一级需求
### 5. 需求部门工作台
#### 新增"待审核一级需求"列表
- 显示一级部门发起的待审核任务
- 操作:审核通过(指定完善人)/ 驳回
#### 新增"待完善明细"列表
- 显示被指定需要完善明细的任务
- 操作:编辑完善 / 提交发布
### 6. 审核流程页面
#### 一级任务审核弹窗
- 显示任务基本信息
- 选择完善人(需求部门成员下拉)
- 审核通过 / 驳回
### 7. 数据分析页面修改
#### 新增"一级需求部门统计"模块
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 一级需求部门统计 [本月 ▼] │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 发起任务数 │ │ 审核通过数 │ │ 审核驳回数 │ │ 消耗积分 │ │
│ │ 128 │ │ 115 │ │ 8 │ │ 12,580 │ │
│ │ ↑ 12.5% │ │ ↑ 15.2% │ │ ↓ 20.0% │ │ ↑ 18.3% │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
#### 一级需求部门排名
| 排名 | 部门名称 | 发起任务数 | 审核通过率 | 消耗积分 | 平均响应时间 |
|-----|---------|-----------|-----------|---------|-------------|
| 1 | 运营一部 | 45 | 95.2% | 4,580 | 2.3小时 |
| 2 | 运营二部 | 38 | 92.1% | 3,820 | 3.1小时 |
| 3 | 市场部 | 32 | 88.5% | 2,960 | 4.2小时 |
#### 一级需求流转效率分析
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 一级需求流转效率 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 发起 ──────► 审核 ──────► 完善 ──────► 发布 ──────► 完成 │
│ 2.3h 4.5h 1.2h 24.6h │
│ │
│ 平均总耗时:32.6 小时 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
#### 品牌任务分布(一级需求)
| 品牌 | 任务数 | 占比 | 负责部门 |
|-----|-------|-----|---------|
| 品牌A | 45 | 35.2% | 设计一部 |
| 品牌B | 32 | 25.0% | 设计一部 |
| 品牌C | 28 | 21.9% | 设计二部 |
| 其他 | 23 | 17.9% | - |
#### 统计指标说明
| 指标 | 计算方式 | 说明 |
|-----|---------|------|
| 发起任务数 | COUNT(is_primary_task = 1) | 一级部门发起的任务总数 |
| 审核通过率 | 通过数 / 总数 × 100% | 需求部门审核通过的比例 |
| 消耗积分 | SUM(score) WHERE is_primary_task = 1 | 一级部门消耗的总积分 |
| 平均响应时间 | AVG(审核时间 - 发起时间) | 需求部门响应一级需求的平均时间 |
| 平均完善时间 | AVG(完善提交时间 - 审核通过时间) | 明细完善的平均耗时 |
| 平均总耗时 | AVG(任务完成时间 - 发起时间) | 从发起到完成的平均时间 |
#### 数据筛选条件
- **时间范围**:今日 / 本周 / 本月 / 本季度 / 自定义
- **一级部门**:全部 / 指定部门
- **品牌**:全部 / 指定品牌
- **任务状态**:全部 / 进行中 / 已完成
---
## 📱 通知设计
> **核心原则**:一级需求部门的通知机制与需求部门完全一致,包括站内通知和钉钉通知
### 通知场景汇总
| 场景 | 通知对象 | 通知内容 | 通知方式 |
|-----|---------|---------|---------|
| 一级部门发起任务 | 品牌对应的需求部门负责人 | `[运营一部-张三] 发起了新的一级需求任务 [任务标题],请审核` | 站内 + 钉钉 |
| 需求部门审核通过 | 被指定的明细完善人 | `您被指定完善任务 [任务标题] 的明细,请尽快处理` | 站内 + 钉钉 |
| 需求部门审核通过 | 一级部门发起人 | `您发起的任务 [任务标题] 已通过审核,正在等待明细完善` | 站内 + 钉钉 |
| 需求部门驳回 | 一级部门发起人 | `您发起的任务 [任务标题] 被驳回,原因:[驳回原因]` | 站内 + 钉钉 |
| 明细完善提交 | 一级部门发起人 | `任务 [任务标题] 明细已完善,进入正常审核流程` | 站内 + 钉钉 |
| 任务进入审核流程 | 需求部门负责人 | `任务 [任务标题] 待审核` | 站内 + 钉钉 |
| 任务被抢单 | 一级部门发起人 | `任务 [任务标题] 已被设计师 YYY 抢单` | 站内 + 钉钉 |
| 任务完成 | 一级部门发起人 | `任务 [任务标题] 已完成` | 站内 + 钉钉 |
### 钉钉通知说明
一级需求部门成员的钉钉通知配置与需求部门**完全一致**:
1. **通知触发**:与需求部门相同的事件触发相同的通知
2. **通知格式**:使用相同的消息模板
3. **通知链接**:点击可跳转到任务详情页
4. **通知权限**:
- 一级部门发起人可收到自己任务的所有状态变更通知
- 与需求部门发起人收到的通知类型完全一致
### 通知模板示例
```
【任务状态变更】
任务名称:XXX
任务状态:待完善明细
操作人:张三
操作时间:2026-01-19 15:30:00
备注:请尽快完善任务明细
点击查看详情 >>
```
---
## ✅ 验收标准
### 功能验收
- [ ] 可以设置部门为"一级需求部门"类型
- [ ] 需求部门可以配置负责的品牌
- [ ] 一级需求部门用户可以发起简化需求(明细可不填)
- [ ] 一级需求部门发起任务需要有积分
- [ ] 任务根据品牌自动路由到对应需求部门
- [ ] 需求部门负责人可以审核并指定完善人
- [ ] 被指定人可以完善任务明细并提交
- [ ] 完善后的任务进入原有审核流程
- [ ] 任务卡片正确显示"一级部门需求人"
- [ ] 各环节通知正常发送
### 权限验收
- [ ] 只有一级需求部门用户可以发起一级需求
- [ ] 只有需求部门负责人可以审核一级需求
- [ ] 只有被指定的完善人可以编辑任务明细
- [ ] 积分校验正常(一级部门也需要有积分)
### 数据分析验收
- [ ] 一级需求部门统计卡片数据正确显示
- [ ] 一级需求部门排名列表正确排序
- [ ] 一级需求流转效率各阶段耗时正确计算
- [ ] 品牌任务分布占比正确
- [ ] 时间筛选功能正常工作
- [ ] 部门/品牌筛选功能正常工作
- [ ] 同比/环比增长率计算正确
### 数据验收
- [ ] 任务数据正确记录一级发起人信息
- [ ] 品牌-部门关联关系正确保存
- [ ] 积分扣减和返还逻辑正确
---
## 📅 开发计划(建议)
| 阶段 | 内容 | 预估工时 |
|-----|------|---------|
| 第一阶段 | 数据库设计与实体类修改 | 0.5天 |
| 第二阶段 | 后端Service和Controller开发(任务流程) | 1.5天 |
| 第三阶段 | 后端数据分析接口开发 | 1天 |
| 第四阶段 | 前端部门管理页面修改 | 0.5天 |
| 第五阶段 | 前端任务发起页面修改 | 1天 |
| 第六阶段 | 前端任务大厅和工作台修改 | 1天 |
| 第七阶段 | 前端数据分析页面修改 | 1天 |
| 第八阶段 | 通知功能开发 | 0.5天 |
| 第九阶段 | 联调测试 | 1天 |
| **合计** | | **8天** |
---
## 👁️ 一级需求部门权限说明
### 权限对比
| 功能模块 | 需求部门 | 一级需求部门 | 说明 |
|---------|---------|-------------|------|
| 任务大厅 | ✅ 可查看 | ✅ 可查看 | 相同 |
| 我发起的任务 | ✅ 可查看 | ✅ 可查看 | 相同 |
| 任务详情 | ✅ 可查看 | ✅ 可查看 | 相同 |
| 数据分析 | ✅ 可查看 | ✅ 可查看 | 相同 |
| 设计师大厅 | ✅ 可查看 | ✅ 可查看 | 相同 |
| 通知消息 | ✅ 可接收 | ✅ 可接收 | 相同 |
| 发起任务 | ✅ 完整表单 | ✅ 简化表单 | 一级部门明细可选/禁用 |
| 审核任务 | ✅ 可审核 | ❌ 不可审核 | 一级部门只发起不审核 |
| 完善明细 | ✅ 可完善 | ❌ 不可完善 | 一级部门任务由需求部门完善 |
| 指定设计师 | ✅ 可指定 | ❌ 不可指定 | 一级部门不支持 |
| 指定需求部门 | ✅ 可指定 | ❌ 不可指定 | 一级部门通过品牌路由 |
### 核心原则
> **一级需求部门的查看权限与需求部门完全一致**,仅在任务发起流程上有差异(简化表单、品牌路由)
---
## ⚠️ 注意事项
1. **积分逻辑**:一级需求部门发起任务时需要校验积分余额,积分从一级部门扣除
2. **品牌路由**:如果品牌没有对应的需求部门,需要给出明确提示
3. **权限控制**:严格控制各环节的操作权限,查看权限与需求部门一致
4. **数据兼容**:现有任务数据的 `is_primary_task` 默认为 0
5. **审核超时**:考虑是否需要增加审核超时提醒机制
---
## ✅ 已确认事项
| 序号 | 问题 | 确认结果 |
|-----|------|---------|
| 1 | 一级需求部门的积分池是独立的还是共用的? | **独立的**。一级需求部门任务只扣一级部门积分,需求部门完善明细后发布不扣需求部门积分 |
| 2 | 一级需求被驳回后,积分是否立即返还? | **是**。驳回后积分立即返还给一级需求部门 |
| 3 | 明细完善人是否可以修改一级部门填写的基本信息? | **不可以**。需求部门成员只能编辑任务明细,不能修改基本信息 |
| 4 | 一个品牌是否可以被多个需求部门负责? | **不可以**。一个品牌只能对应一个需求部门,但**一个需求部门可以负责多个品牌** |
| 5 | 是否需要支持一级部门直接指定需求部门? | **不支持**。一级需求部门不支持指定设计师和指定需求部门,只能通过品牌路由 |
---
## 🔍 系统集成复核
### 现有系统架构分析
#### 1. 部门类型(Department.deptType)
- **现有值**:`demand`(需求部门)、`receiving`(接单部门)
- **新增值**:`primary_demand`(一级需求部门)
- ✅ 兼容性良好,只需扩展枚举值
#### 2. 任务审批流程(Task.approvalStatus)
- **现有状态**:
- `pending_demand_approval` - 待需求部门审核
- `pending_receiving_approval` - 待接单部门审核
- `approved` - 已通过
- **新增状态**:
- `pending_primary_approval` - 待一级审核(需求部门审核一级任务)
- `pending_detail_completion` - 待完善明细
- ✅ 状态扩展,与现有流程兼容
#### 3. 积分扣除时机(现有逻辑)
- **现有逻辑**:接单部门审核通过后扣除积分(`TaskApprovalService.approveReceivingLevel`)
- **一级任务逻辑**:需求部门完善明细后发布时扣除一级部门积分
- ⚠️ 需要在 `TaskService` 中增加判断:如果是一级任务,扣除 `primaryPublisherDeptId` 的积分
#### 4. 任务创建权限检查(现有逻辑)
```java
// 现有代码检查 deptType == "demand"
if (!"demand".equals(department.getDeptType())) {
throw new BusinessException(ResultCode.FORBIDDEN, "只有需求部门可以发起任务");
}
```
- ⚠️ 需要修改为:`"demand".equals(deptType) || "primary_demand".equals(deptType)`
#### 5. 系统配置表(sys_config)
- **现有结构**:完全匹配,可直接使用
- **字段**:`config_key`, `config_value`, `config_group`, `config_name`, `description`, `value_type`
- ✅ 新增配置项完全兼容
#### 6. 前端部门类型选择(Settings.vue)
- **现有实现**:Radio 组件,`demand` / `receiving` 两个选项
- ⚠️ 需要增加 `primary_demand` 选项
- ⚠️ 需要增加"负责品牌"配置(仅需求部门显示)
### 需要特别注意的集成点
| 序号 | 集成点 | 现有代码位置 | 修改说明 |
|-----|-------|-------------|---------|
| 1 | 任务创建权限 | `TaskService.createTask()` | 允许 `primary_demand` 类型部门发起任务 |
| 2 | 任务创建权限 | `TaskService.createPipelineTask()` | 同上 |
| 3 | 积分扣除 | `TaskApprovalService.approveReceivingLevel()` | 一级任务扣除一级部门积分 |
| 4 | 积分返还 | `TaskService.withdrawTask()` | 一级任务返还给一级部门 |
| 5 | 审批流程初始化 | `TaskService.initApprovalStatus()` | 一级任务路由到需求部门 |
| 6 | 前端部门类型 | `Settings.vue` 部门表单 | 增加一级需求部门选项 |
| 7 | 前端任务发起 | `CreateTask.vue` | 根据部门类型调整表单 |
| 8 | 前端任务卡片 | `TaskHall.vue` | 显示一级需求人信息 |
### 数据库迁移脚本
```sql
-- V13__add_primary_demand_dept.sql
-- 1. 系统配置:一级需求部门是否允许填写任务明细
INSERT INTO sys_config (config_key, config_value, config_group, config_name, description, value_type, built_in, sort_order, create_time, update_time, deleted)
VALUES ('primary_dept_can_fill_detail', 'false', 'task', '一级需求部门可填写明细', '开启后一级需求部门发布任务时可以填写任务明细,关闭后不允许填写', 'boolean', 0, 100, NOW(), NOW(), 0);
-- 2. 部门表新增字段(用于需求部门设置负责品牌,备用)
-- 注意:主要使用 dept_brand_relation 表管理关系
-- ALTER TABLE sys_dept ADD COLUMN responsible_brand_ids VARCHAR(500) COMMENT '负责的品牌ID列表(逗号分隔)';
-- 3. 任务表新增字段
ALTER TABLE task ADD COLUMN primary_publisher_id BIGINT COMMENT '一级部门发起人ID';
ALTER TABLE task ADD COLUMN primary_publisher_dept_id BIGINT COMMENT '一级部门ID';
ALTER TABLE task ADD COLUMN detail_completer_id BIGINT COMMENT '明细完善人ID';
ALTER TABLE task ADD COLUMN is_primary_task TINYINT DEFAULT 0 COMMENT '是否一级部门任务:0-否,1-是';
ALTER TABLE task ADD COLUMN detail_completed TINYINT DEFAULT 0 COMMENT '明细是否已完善:0-否,1-是';
-- 4. 创建品牌-部门关联表
CREATE TABLE IF NOT EXISTS dept_brand_relation (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
dept_id BIGINT NOT NULL COMMENT '部门ID(需求部门)',
brand_id BIGINT NOT NULL COMMENT '品牌ID',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UNIQUE KEY uk_brand_id (brand_id),
INDEX idx_dept_id (dept_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门品牌负责关系表';
-- 5. 为现有任务设置默认值
UPDATE task SET is_primary_task = 0 WHERE is_primary_task IS NULL;
UPDATE task SET detail_completed = 1 WHERE detail_completed IS NULL;
```
### 风险评估
| 风险项 | 风险等级 | 缓解措施 |
|-------|---------|---------|
| 现有任务数据兼容 | 低 | 新增字段有默认值,不影响现有数据 |
| 审批流程复杂度增加 | 中 | 增加充分的状态校验和日志记录 |
| 积分扣除逻辑变更 | 中 | 增加单元测试,确保各场景积分正确 |
| 前端表单逻辑复杂 | 中 | 抽取公共组件,按部门类型条件渲染 |
---
**文档版本**:v1.2
**创建日期**:2026年1月19日
**最后更新**:2026年1月19日
**状态**:已确认,系统集成复核完成,待开发