18 KiB
18 KiB
4. 任务智能分配算法
任务分配是系统中的关键业务流程,我实现了一个智能分配算法,能够根据多种因素为任务选择最合适的网格员。该算法综合考虑了地理距离、当前负载、专业匹配度和历史表现等因素。
关键代码展示:
@Service
@RequiredArgsConstructor
public class TaskAssignmentServiceImpl implements TaskAssignmentService {
private final TaskRepository taskRepository;
private final UserAccountRepository userAccountRepository;
private final GridService gridService;
private final WorkerStatsService workerStatsService;
/**
* 为任务推荐最合适的网格员
* 综合考虑地理距离、当前负载、专业匹配度和历史表现
*/
@Override
public UserAccount recommendWorkerForTask(Task task, List<UserAccount> availableWorkers) {
if (availableWorkers.isEmpty()) {
return null;
}
// 权重配置
final double DISTANCE_WEIGHT = 0.4; // 地理距离权重
final double LOAD_WEIGHT = 0.3; // 当前负载权重
final double SKILL_WEIGHT = 0.2; // 专业匹配度权重
final double PERFORMANCE_WEIGHT = 0.1; // 历史表现权重
// 任务位置
Point taskLocation = new Point(task.getGridX(), task.getGridY());
// 计算每个网格员的评分
Map<UserAccount, Double> workerScores = new HashMap<>();
for (UserAccount worker : availableWorkers) {
// 1. 地理距离评分
Point workerLocation = new Point(worker.getGridX(), worker.getGridY());
double distance = calculateDistance(workerLocation, taskLocation);
double maxDistance = 10.0; // 最大考虑距离
double distanceScore = Math.max(0, maxDistance - distance) / maxDistance;
// 2. 当前负载评分
int currentTasks = taskRepository.countByAssigneeIdAndStatusIn(
worker.getId(), Arrays.asList(TaskStatus.ASSIGNED, TaskStatus.IN_PROGRESS));
int maxTasks = 5; // 最大任务数
double loadScore = (double)(maxTasks - currentTasks) / maxTasks;
// 3. 专业匹配度评分
double skillScore = calculateSkillMatch(worker, task);
// 4. 历史表现评分
double completionRate = workerStatsService.getCompletionRate(worker.getId());
double qualityRating = workerStatsService.getAverageQualityRating(worker.getId());
double performanceScore = (completionRate * 0.7) + (qualityRating * 0.3);
// 5. 综合评分
double totalScore = (distanceScore * DISTANCE_WEIGHT) +
(loadScore * LOAD_WEIGHT) +
(skillScore * SKILL_WEIGHT) +
(performanceScore * PERFORMANCE_WEIGHT);
workerScores.put(worker, totalScore);
}
// 选择评分最高的网格员
return workerScores.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}
/**
* 计算两点间的距离
* 使用曼哈顿距离,适合网格化的城市环境
*/
private double calculateDistance(Point a, Point b) {
return Math.abs(a.x() - b.x()) + Math.abs(a.y() - b.y());
}
/**
* 计算网格员技能与任务的匹配度
* 返回0-1之间的分数,1表示完全匹配
*/
private double calculateSkillMatch(UserAccount worker, Task task) {
// 获取工人的技能列表
List<String> workerSkills = worker.getSkills();
if (workerSkills == null || workerSkills.isEmpty()) {
return 0.0;
}
// 根据任务类型确定所需技能
List<String> requiredSkills = determineRequiredSkills(task);
if (requiredSkills.isEmpty()) {
return 1.0; // 如果任务没有特定技能要求,则任何工人都完全匹配
}
// 计算匹配的技能数量
long matchedSkillsCount = requiredSkills.stream()
.filter(skill -> workerSkills.contains(skill))
.count();
// 返回匹配率
return (double) matchedSkillsCount / requiredSkills.size();
}
/**
* 根据任务类型确定所需技能
*/
private List<String> determineRequiredSkills(Task task) {
List<String> skills = new ArrayList<>();
// 根据污染类型添加相关技能
switch (task.getPollutionType()) {
case AIR:
skills.add("air_quality_monitoring");
skills.add("emissions_control");
break;
case WATER:
skills.add("water_sampling");
skills.add("water_treatment");
break;
case SOIL:
skills.add("soil_testing");
skills.add("land_remediation");
break;
case NOISE:
skills.add("noise_measurement");
skills.add("sound_insulation");
break;
default:
skills.add("general_environmental");
}
// 根据严重程度添加额外技能
if (task.getSeverityLevel() == SeverityLevel.HIGH ||
task.getSeverityLevel() == SeverityLevel.CRITICAL) {
skills.add("emergency_response");
}
return skills;
}
}
实现要点分析:
- 多因素加权评分: 算法综合考虑了地理距离、当前负载、专业匹配度和历史表现四个因素,通过加权计算得出每个网格员的综合得分。
- 技能匹配机制: 根据任务的污染类型和严重程度,动态确定所需的技能列表,然后与网格员的技能进行匹配,计算匹配度。
- 可配置权重: 各因素的权重可以根据实际需求进行调整,使得算法更加灵活和适应性强。
- 流式API: 使用Java 8的Stream API进行最大值查找,代码简洁且高效。
程序流程图:
flowchart TD
A[开始] --> B[获取可用网格员列表]
B --> C{列表为空?}
C -->|是| D[返回null]
C -->|否| E[遍历每个网格员]
E --> F[计算地理距离评分]
F --> G[计算当前负载评分]
G --> H[计算专业匹配度评分]
H --> I[计算历史表现评分]
I --> J[计算综合评分]
J --> K[记录网格员评分]
K --> L{所有网格员已处理?}
L -->|否| E
L -->|是| M[返回评分最高的网格员]
3.3.3 界面展示与成果展示
在前端实现方面,我采用了Vue 3和Element Plus组件库,打造了美观、易用且响应式的用户界面。下面展示几个核心界面及其功能实现。
1. 主管工作台 - 反馈审核与任务分配
界面功能说明:
- 左侧反馈列表: 展示所有待审核的反馈,支持按状态、类型和严重程度进行筛选。
- 右侧反馈详情: 显示选中反馈的详细信息,包括标题、描述、位置和附件等。
- 智能推荐: 系统自动推荐最合适的网格员,并显示推荐理由。
- 手动分配: 主管可以覆盖系统推荐,手动选择其他网格员。
- 批量操作: 支持批量审核和分配功能,提高工作效率。
前端代码实现:
<template>
<div class="supervisor-dashboard">
<el-row :gutter="20">
<!-- 左侧反馈列表 -->
<el-col :span="8">
<el-card class="feedback-list">
<template #header>
<div class="card-header">
<span>待处理反馈 ({{ totalItems }})</span>
<el-input
v-model="searchQuery"
placeholder="搜索反馈..."
prefix-icon="el-icon-search"
clearable
@input="handleSearch"
/>
</div>
</template>
<el-table
v-loading="loading"
:data="feedbackList"
@row-click="handleRowClick"
highlight-current-row
>
<el-table-column prop="eventId" label="事件ID" width="120" />
<el-table-column prop="title" label="标题" show-overflow-tooltip />
<el-table-column prop="severityLevel" label="严重程度" width="100">
<template #default="scope">
<el-tag :type="getSeverityType(scope.row.severityLevel)">
{{ scope.row.severityLevel }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="120">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.status)">
{{ getStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
background
layout="prev, pager, next"
:total="totalItems"
:page-size="pageSize"
@current-change="handlePageChange"
/>
</div>
</el-card>
</el-col>
<!-- 右侧反馈详情 -->
<el-col :span="16">
<el-card v-if="selectedFeedback" class="feedback-detail">
<template #header>
<div class="card-header">
<span>反馈详情</span>
<div>
<el-button
type="success"
icon="el-icon-check"
@click="handleApprove"
:disabled="!canApprove"
>
批准
</el-button>
<el-button
type="danger"
icon="el-icon-close"
@click="handleReject"
:disabled="!canReject"
>
拒绝
</el-button>
</div>
</div>
</template>
<el-descriptions :column="2" border>
<el-descriptions-item label="标题">{{ selectedFeedback.title }}</el-descriptions-item>
<el-descriptions-item label="事件ID">{{ selectedFeedback.eventId }}</el-descriptions-item>
<el-descriptions-item label="污染类型">{{ selectedFeedback.pollutionType }}</el-descriptions-item>
<el-descriptions-item label="严重程度">
<el-tag :type="getSeverityType(selectedFeedback.severityLevel)">
{{ selectedFeedback.severityLevel }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="提交时间">{{ formatDate(selectedFeedback.createdAt) }}</el-descriptions-item>
<el-descriptions-item label="位置">{{ selectedFeedback.textAddress }}</el-descriptions-item>
<el-descriptions-item label="描述" :span="2">
{{ selectedFeedback.description }}
</el-descriptions-item>
</el-descriptions>
<!-- 附件展示 -->
<div v-if="selectedFeedback.attachments && selectedFeedback.attachments.length > 0" class="attachments">
<h3>附件</h3>
<el-image
v-for="(attachment, index) in selectedFeedback.attachments"
:key="index"
:src="attachment.filePath"
:preview-src-list="getImageUrls()"
fit="cover"
class="attachment-image"
/>
</div>
<!-- 任务分配表单 -->
<div v-if="selectedFeedback.status === 'PENDING_ASSIGNMENT'" class="assignment-form">
<h3>分配任务</h3>
<el-form :model="assignmentForm" label-width="120px">
<el-form-item label="选择网格员">
<el-select v-model="assignmentForm.workerId" placeholder="选择网格员">
<el-option
v-for="worker in availableWorkers"
:key="worker.id"
:label="worker.name"
:value="worker.id"
>
<div class="worker-option">
<span>{{ worker.name }}</span>
<small>
{{ worker.isRecommended ? '(系统推荐)' : '' }}
{{ worker.currentTasks }} 个任务
</small>
</div>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleAssign" :loading="assignLoading">
分配任务
</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
<el-empty v-else description="请选择一个反馈" />
</el-col>
</el-row>
</div>
</template>
2. 网格员工作台 - 任务执行
界面功能说明:
- 任务列表: 展示分配给当前网格员的所有任务,按状态和截止日期排序。
- 任务详情: 显示选中任务的详细信息,包括位置、描述和附件等。
- 路径规划: 集成A*寻路算法,为网格员提供从当前位置到任务地点的最优路径。
- 任务提交: 提供表单和文件上传功能,让网格员提交任务处理结果。
3. 决策支持看板
界面功能说明:
- 核心KPI: 展示关键业务指标,如反馈总数、任务完成率、平均处理时长等。
- 热力图: 基于地理位置的问题密度热力图,直观展示问题高发区域。
- 趋势图: 展示过去30天的反馈和任务数量趋势,帮助决策者了解系统运行状况。
- 分布图: 展示不同类型问题的分布情况,帮助决策者了解问题类型分布。
前端代码实现:
<template>
<div class="dashboard-container">
<el-row :gutter="20" class="kpi-row">
<el-col :span="6" v-for="(item, index) in kpiData" :key="index">
<el-card shadow="hover" class="kpi-card">
<div class="kpi-icon">
<i :class="item.icon"></i>
</div>
<div class="kpi-content">
<div class="kpi-value">{{ item.value }}</div>
<div class="kpi-label">{{ item.label }}</div>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="chart-row">
<el-col :span="16">
<el-card shadow="hover">
<template #header>
<div class="card-header">
<span>问题热力图</span>
<el-select v-model="mapFilter" placeholder="筛选" size="small">
<el-option label="全部问题" value="ALL" />
<el-option label="空气污染" value="AIR" />
<el-option label="水污染" value="WATER" />
<el-option label="噪音污染" value="NOISE" />
</el-select>
</div>
</template>
<div class="map-container">
<heatmap-component :data="heatmapData" :filter="mapFilter" />
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="chart-card">
<template #header>
<div class="card-header">
<span>问题类型分布</span>
</div>
</template>
<div class="chart-container">
<pie-chart :data="typeDistribution" />
</div>
</el-card>
<el-card shadow="hover" class="chart-card" style="margin-top: 20px;">
<template #header>
<div class="card-header">
<span>任务完成情况</span>
</div>
</template>
<div class="chart-container">
<progress-chart :data="taskCompletionData" />
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="chart-row">
<el-col :span="24">
<el-card shadow="hover">
<template #header>
<div class="card-header">
<span>过去30天趋势</span>
<el-radio-group v-model="trendType" size="small">
<el-radio-button label="feedback">反馈数量</el-radio-button>
<el-radio-button label="tasks">任务数量</el-radio-button>
<el-radio-button label="completion">完成率</el-radio-button>
</el-radio-group>
</div>
</template>
<div class="chart-container">
<trend-chart :data="trendData" :type="trendType" />
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
3.3.4 实现成果总结
通过系统实现阶段的工作,我成功地将系统设计阶段规划的功能转化为了可运行的代码,实现了环境监督系统的核心功能。主要成果包括:
- 创新的数据持久化方案: 设计并实现了基于JSON文件的数据存储服务,简化了系统部署,同时提供了类似JPA的操作接口。
- 高效的A*寻路算法: 实现了能够考虑地图障碍物的A*寻路算法,为网格员提供最优路径规划。
- 智能的任务分配算法: 开发了综合考虑多种因素的任务分配算法,能够为任务选择最合适的执行者。
- 完整的反馈管理流程: 实现了反馈提交、AI审核、人工审核和任务创建的完整流程,支持多条件查询和文件上传。
- 直观的用户界面: 设计并实现了美观、易用且响应式的用户界面,包括主管工作台、网格员工作台和决策支持看板等。
这些实现成果不仅满足了系统需求分析阶段定义的功能要求,也体现了系统设计阶段规划的架构和模块划分。系统的实现充分考虑了可维护性、可扩展性和用户体验,为后续的系统测试和部署奠定了坚实的基础。


