|
|
@@ -0,0 +1,189 @@
|
|
|
+package com.chuanghai.repair.controller;
|
|
|
+
|
|
|
+import com.chuanghai.repair.entity.RepairsOrder;
|
|
|
+import com.chuanghai.repair.service.RepairsOrderService;
|
|
|
+import com.chuanghai.repair.service.RepairsWorkService;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import org.springframework.context.ApplicationListener;
|
|
|
+import org.springframework.context.event.ContextRefreshedEvent;
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Author: bingo
|
|
|
+ * @Date: 2022/2/25 星期五 21:33
|
|
|
+ * @Description: com.chuanghai.repair.controller
|
|
|
+ * @version: 1.0
|
|
|
+ *
|
|
|
+ * 该controller类实现了ApplicationListener<ContextRefreshedEvent> 接口
|
|
|
+ * 重写了onApplicationEvent方法,使项目启动之后自动执行该方法 实现订单自动分配
|
|
|
+ */
|
|
|
+@Api(tags = "自动派单管理")
|
|
|
+@RestController
|
|
|
+@RequestMapping("/auto")
|
|
|
+public class AutoSendOrderCentroller implements ApplicationListener<ContextRefreshedEvent> {
|
|
|
+
|
|
|
+ @Resource(name = "repairsOrderService")
|
|
|
+ private RepairsOrderService repairsOrderService;
|
|
|
+
|
|
|
+ @Resource(name = "repairsWorkService")
|
|
|
+ private RepairsWorkService repairsWorkService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 优化: 在订单表加个字段(订单类型 水电工 木工等)对应维修工的类型 根据未接单 订单类型 将木工订单分配给木工师傅
|
|
|
+ */
|
|
|
+ @ApiOperation("自动分配订单")
|
|
|
+ @PostMapping(value = "/autoSendOrder")
|
|
|
+ @Override
|
|
|
+ public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ //查询所有未接单的订单实体信息 优化:订单进行分类 木工 水电工
|
|
|
+ List<RepairsOrder> orderList = repairsOrderService.queryAllOrderNotReceive();
|
|
|
+ List<Task> taskList = new ArrayList<Task>();
|
|
|
+ //将订单实体信息中的订单ID存入任务集合中
|
|
|
+ for (RepairsOrder repairsOrder:orderList ) {
|
|
|
+ String orderId = repairsOrder.getOrderId();
|
|
|
+ taskList.add(new Task(orderId));
|
|
|
+ }
|
|
|
+ //查询所有在岗维修工 优化: 可将维修工分类 if判断分配同类型的订单 木工订单----木工师傅
|
|
|
+ List<String> workList = repairsWorkService.queryAllWork();
|
|
|
+ //在岗维修工人数
|
|
|
+ int threadCount = workList.size();
|
|
|
+ List[] taskPerThreadCount = distributeTasks(taskList, 2);
|
|
|
+ // System.out.println("实际要启动的工作线程:" + taskPerThreadCount.length);
|
|
|
+ for (int i = 0; i < taskPerThreadCount.length; i++) {
|
|
|
+ Thread workThread = new Task.WorkThread(taskPerThreadCount[i], i);
|
|
|
+ workThread.setName(workList.get(i));
|
|
|
+ workThread.start();
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 线程分配任务
|
|
|
+ * @param taskList
|
|
|
+ * @param threadCount
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static List[] distributeTasks(List<Task> taskList, int threadCount) {
|
|
|
+ // 每个线程至少要执行的任务数,如果不为零,则每个线程都会分到任务;
|
|
|
+ int minTaskCount = taskList.size() / threadCount;
|
|
|
+
|
|
|
+ // System.out.println(minTaskCount + " minTaskCount");
|
|
|
+ // 剩下的任务数,如果不为零,则依个添加到前面的线程中.
|
|
|
+ int remainTaskCount = taskList.size() % threadCount;
|
|
|
+
|
|
|
+ // System.out.println(remainTaskCount + " remainTaskCount");
|
|
|
+ // 实际要启动的线程个数,如果工作线程比较任务还多,则只需要启动与任务数相同的工作
|
|
|
+ // 线程,一对一工作,
|
|
|
+ int actualThreadCount = minTaskCount > 0 ? threadCount
|
|
|
+ : remainTaskCount;
|
|
|
+ // System.out.println(actualThreadCount + " actualThreadCount");
|
|
|
+ // 要启动的线程数组,以及每个线程执行的任务列表.
|
|
|
+ List<Task>[] taskListPerThread = new List[actualThreadCount];
|
|
|
+ int taskIndex = 0;
|
|
|
+ int remainIndces = remainTaskCount;
|
|
|
+ for (int i = 0, n = taskListPerThread.length; i < n; i++) {
|
|
|
+ taskListPerThread[i] = new ArrayList();
|
|
|
+ if (minTaskCount > 0) {
|
|
|
+ for (int j = taskIndex; j < minTaskCount + taskIndex; j++) {
|
|
|
+ taskListPerThread[i].add(taskList.get(j));
|
|
|
+ }
|
|
|
+ taskIndex += minTaskCount;
|
|
|
+ }
|
|
|
+ if (remainIndces > 0) {
|
|
|
+ taskListPerThread[i].add(taskList.get(taskIndex++));
|
|
|
+ remainIndces--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int i = 0, n = taskListPerThread.length; i < n; i++) {
|
|
|
+ System.out.println("线程 "
|
|
|
+ + i
|
|
|
+ + " 的任务数:"
|
|
|
+ + taskListPerThread[i].size()
|
|
|
+ + " 区间["
|
|
|
+ + taskListPerThread[i].get(0).getTaskId()
|
|
|
+ + ","
|
|
|
+ + taskListPerThread[i].get(taskListPerThread[i].size() - 1)
|
|
|
+ .getTaskId() + "]");
|
|
|
+ }
|
|
|
+ return taskListPerThread;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订单的任务队列
|
|
|
+ */
|
|
|
+ public static class Task {
|
|
|
+ private static final int READY = 0;
|
|
|
+ private static final int RUNNING = 1;
|
|
|
+ private static final int FINISHED = 2;
|
|
|
+ private int status;
|
|
|
+ private String taskId;
|
|
|
+
|
|
|
+ public Task(String taskid) {
|
|
|
+ this.status = READY;
|
|
|
+ this.taskId = taskid;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void execute() {
|
|
|
+ try {
|
|
|
+ setStatus(RUNNING);
|
|
|
+
|
|
|
+ System.out.println("当前的线程ID是:" + Thread.currentThread().getName()
|
|
|
+ + " 任务ID是:" + taskId);
|
|
|
+ Thread.sleep(2000);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ setStatus(FINISHED);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setStatus(int status) {
|
|
|
+ this.status = status;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getTaskId() {
|
|
|
+ return taskId;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 维修工的任务队列
|
|
|
+ */
|
|
|
+ public static class WorkThread extends Thread {
|
|
|
+ private List<Task> taskList = null;
|
|
|
+ private int threadId;
|
|
|
+
|
|
|
+ public WorkThread(List<Task> taskList, int threadid) {
|
|
|
+ this.taskList = taskList;
|
|
|
+ this.threadId = threadid;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ // TODO Auto-generated method stub
|
|
|
+ for (Task task : taskList) {
|
|
|
+ task.execute();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|