Commit 8a62313e authored by 高滢's avatar 高滢
parents 887a4a0a 77a664da
......@@ -27,8 +27,6 @@ public class CarReviewTask implements Serializable {
@TableField(exist = false)
public static final String TASK_STATUS_NONE = "NONE";
@TableField(exist = false)
public static final String TASK_STATUS_NEW = "NEW";
@TableField(exist = false)
......@@ -55,7 +53,7 @@ public class CarReviewTask implements Serializable {
/**
* 任务状态(PENDING、FINISH)
*/
@ApiModelProperty("任务状态[NONE、NEW、PENDING、FINISH]")
@ApiModelProperty("任务状态[NEW、PENDING、FINISH]")
private String taskStatus;
/**
......
......@@ -24,7 +24,9 @@ import java.util.List;
public class Task {
@TableField(exist = false)
public static final String STATUS_NEW = "NEW";
public static final String STATUS_RUNNABLE = "RUNNABLE";
@TableField(exist = false)
public static final String STATUS_RUNNING = "RUNNING";
@TableField(exist = false)
public static final String STATUS_FINISH = "FINISH";
......@@ -59,6 +61,9 @@ public class Task {
@ApiModelProperty("任务状态(NEW、FINISH)")
private String taskStatus;
@ApiModelProperty("下一个节点 SUB_TASK_SRAIF(体系审查子任务)、SUB_TASK_TRFIS(车辆实验子任务)、SUB_TASK_GRFIS(车辆问卷子任务)")
private String nextNode;
@ApiModelProperty("产品名称")
private String productName;
......
......@@ -19,4 +19,8 @@ public interface TaskMapper extends BaseMapper<Task> {
List<TaskFindPendingResponse> findPending(TaskFindPendingRequest request);
List<Task> findFinish(TaskFindFinishRequest request);
Long findByCarReviewTaskId(@Param("carReviewId") Long carReviewId);
Long findBySystemReviewTaskId(@Param("systemReviewId") Long systemReviewId);
}
......@@ -36,4 +36,6 @@ public interface TaskService extends IService<Task> {
void editTask(TaskEditRequest request);
void deleteTask(TaskDeleteRequest request);
void startTask(TaskStartRequest request);
}
......@@ -93,8 +93,6 @@ public class CarReviewTaskServiceImpl extends ServiceImpl<CarReviewTaskMapper, C
.setFile(standard.getFile());
if (request.getReview()) {
task.setTaskStatus(CarReviewTask.TASK_STATUS_NEW);
} else {
task.setTaskStatus(CarReviewTask.TASK_STATUS_NONE);
}
carReviewTaskService.save(task);
......
package com.ruoyi.service.impl;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.domain.CarReviewTask;
import com.ruoyi.service.StrategyCarReviewTask;
import com.ruoyi.web.response.CarReviewTaskViewResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class StrategyCarReviewTaskNone implements StrategyCarReviewTask, InitializingBean {
@Autowired
private StrategyCarReviewTaskContext strategyCarReviewTaskContext;
@Autowired
private ApplicationContext applicationContext;
@Override
public CarReviewTaskViewResponse doView(CarReviewTask carReviewTask) {
throw new ServiceException("不能查看一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doStartReview(CarReviewTask carReviewTask) {
throw new ServiceException("不能开始一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doConfirmReview(CarReviewTask carReviewTask) {
throw new ServiceException("不能确认一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void doSubmitReview(CarReviewTask carReviewTask,String imagesUrl) {
throw new ServiceException("不能提交一个不存在的任务", HttpStatus.ERROR);
}
@Override
public void afterPropertiesSet() throws Exception {
strategyCarReviewTaskContext.putResource(CarReviewTask.TASK_STATUS_NONE, applicationContext.getBean(this.getClass()));
}
}
......@@ -8,6 +8,7 @@ import com.ruoyi.domain.*;
import com.ruoyi.mapper.CarReviewTaskMapper;
import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.TaskMapper;
import com.ruoyi.service.ReviewDetailsResultService;
import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.service.ReviewStandardService;
......@@ -19,6 +20,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.swing.table.TableModel;
import java.util.Date;
import java.util.List;
import java.util.Map;
......@@ -38,6 +40,9 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi
@Autowired
private CarReviewTaskMapper carReviewTaskMapper;
@Autowired
private TaskMapper taskMapper;
// SIGNED状态下
// 1.standard字段使用task中归档的问卷
// 2.不查询场景变更任务
......@@ -77,7 +82,12 @@ public class StrategyCarReviewTaskSigned implements StrategyCarReviewTask, Initi
// 4. 保存签名图片地址
carReviewTask.setImagesUrl(imagesUrl);
// 5.再找带该子任务所属的总任务,将总任务的状态由 RUNNING 改回 RUNNABLE
Task task = taskMapper.selectById(taskMapper.findByCarReviewTaskId(carReviewTask.getId()));
task.setTaskStatus(Task.STATUS_RUNNABLE);
carReviewTaskMapper.updateById(carReviewTask);
taskMapper.updateById(task);
}
......
......@@ -8,6 +8,7 @@ import com.ruoyi.domain.*;
import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.SystemReviewTaskMapper;
import com.ruoyi.mapper.TaskMapper;
import com.ruoyi.service.ReviewDetailsResultService;
import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.service.ReviewStandardService;
......@@ -38,6 +39,9 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask,
@Autowired
private SystemReviewTaskMapper systemReviewTaskMapper;
@Autowired
private TaskMapper taskMapper;
@Override
public void doStart(SystemReviewTask systemReviewTask) {
......@@ -67,7 +71,12 @@ public class StrategySystemReviewTaskSigned implements StrategySystemReviewTask,
// 4.保存签名图片地址
systemReviewTask.setImagesUrl(imagesUrl);
// 5.再找带该子任务所属的总任务,将总任务的状态由 RUNNING 改回 RUNNABLE
Task task = taskMapper.selectById(taskMapper.findBySystemReviewTaskId(systemReviewTask.getId()));
task.setTaskStatus(Task.STATUS_RUNNABLE);
systemReviewTaskMapper.updateById(systemReviewTask);
taskMapper.updateById(task);
}
@Override
......
......@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Transactional
@Service
......@@ -86,37 +87,42 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
Task task = new Task();
task.setTaskInitiator(initiator.getNickName());
task.setTaskInitiatorDept(initiator.getDept().getDeptName());
task.setTaskStatus(Task.STATUS_NEW);
task.setTaskStatus(Task.STATUS_RUNNABLE);
task.setLeaderId(leader.getUserId());
task.setLeader(leader.getName());
task.setCreateTime(new Date());
task.setName(standard.getName());
task.setStandardNo(standard.getStandardNo());
task.setFile(standard.getFile());
AutomobileEnterprise automobileEnterprise = automobileEnterpriseMapper.selectById(request.getProductionId());
task.setProductionEnterprise(automobileEnterprise.getEnterpriseName());
BeanUtils.copyBeanProp(task, request);
AutomobileEnterprise automobileEnterprise = automobileEnterpriseMapper.selectAutomobileEnterpriseById(request.getProductionId());
task.setProductionEnterprise(automobileEnterprise.getEnterpriseName());
Long systemReviewTaskId = null;
Long carReviewTaskId = null;
if (request.getTaskList().contains(Task.SUB_TASK_SRAIF)) {
// 保存体系审查任务
systemReviewTaskId = saveSystemReview(request,initiator,standard,leader);
String nextNode = null;
if(request.getTaskList().contains(Task.SUB_TASK_TRFIS)) {
nextNode = Task.SUB_TASK_TRFIS;
}
if (request.getTaskList().contains(Task.SUB_TASK_GRFIS)) {
if(request.getTaskList().contains(Task.SUB_TASK_GRFIS)) {
// 保存车型审查问卷任务
carReviewTaskId = saveCarReview(request,initiator,standard,leader);
nextNode = Task.SUB_TASK_GRFIS;;
task.setCarReviewTaskId(saveCarReview(request,initiator,standard,leader));
}
if(request.getTaskList().contains(Task.SUB_TASK_SRAIF)) {
// 保存体系审查任务
nextNode = Task.SUB_TASK_SRAIF;
task.setSystemReviewTaskId(saveSystemReview(request,initiator,standard,leader));
}
task.setCarReviewTaskId(carReviewTaskId);
task.setSystemReviewTaskId(systemReviewTaskId);
task.setNextNode(nextNode);
taskService.save(task);
// 构建并保存该任务所关联的审核组信息
for(TaskUserRelation auditor : auditors) {
auditor.setTaskId(task.getId());
}
taskUserRelationService.saveBatch(auditors);
}
......@@ -178,6 +184,31 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
taskMapper.deleteById(request.getId());
}
@Override
public void startTask(TaskStartRequest request) {
Task task = taskMapper.selectById(request.getId());
SystemReviewTaskStartRequest systemRequest = new SystemReviewTaskStartRequest();
systemRequest.setTaskId(task.getSystemReviewTaskId());
CarReviewTaskStartRequest carRequest = new CarReviewTaskStartRequest();
carRequest.setTaskId(task.getCarReviewTaskId());
if (Objects.equals(task.getNextNode(), Task.SUB_TASK_SRAIF)) {
systemReviewTaskService.start(systemRequest);
task.setTaskStatus(Task.STATUS_RUNNING);
task.setNextNode(Task.SUB_TASK_GRFIS);
taskMapper.updateById(task);
} else if (Objects.equals(task.getNextNode(), Task.SUB_TASK_GRFIS)) {
carReviewTaskService.startReviewTask(carRequest);
task.setTaskStatus(Task.STATUS_RUNNING);
task.setNextNode(Task.SUB_TASK_TRFIS);
taskMapper.updateById(task);
}
}
public Long saveSystemReview(TaskCreateRequest request,SysUser initiator,Standard standard,TaskUserRelation leader) {
// 构建并保存任务信息
......@@ -207,11 +238,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
.setTaskNo(request.getTaskNo())
.setTaskInitiator(initiator.getNickName())
.setTaskInitiatorDept(initiator.getDept().getDeptName())
.setTaskStatus(taskList.contains(Task.SUB_TASK_GRFIS) ? CarReviewTask.TASK_STATUS_NEW : CarReviewTask.TASK_STATUS_NONE)
.setTaskStatus(CarReviewTask.TASK_STATUS_NEW)
.setLeaderId(leader.getUserId())
.setLeader(leader.getName())
.setCreateTime(new Date())
.setTaskBeginTime(new Date())
.setStandardId(standard.getId())
.setName(standard.getName())
.setStandardNo(standard.getStandardNo())
......
......@@ -109,4 +109,15 @@ public class TaskController extends BaseController {
return R.ok();
}
@ApiOperation("开始任务")
@Trace
@Tags({@Tag(key = "param", value = "arg[0]"), @Tag(key = "result", value = "returnedObj")})
@Log(title = "开始任务", businessType = BusinessType.UPDATE)
@RequestMapping(method = RequestMethod.POST, value = "/startTask")
public R<String> startTask(@Validated @RequestBody TaskStartRequest request) {
taskService.startTask(request);
return R.ok();
}
}
package com.ruoyi.web.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "TaskStartRequest", description = "开始任务")
@Data
public class TaskStartRequest {
@ApiModelProperty("ID")
private Long id;
}
......@@ -32,6 +32,9 @@ public class TaskFindPendingResponse {
@ApiModelProperty("任务状态(NEW、PENDING、FINISH)")
private String taskStatus;
@ApiModelProperty("下一个节点 SUB_TASK_SRAIF(体系审查子任务)、SUB_TASK_TRFIS(车辆实验子任务)、SUB_TASK_GRFIS(车辆问卷子任务)")
private String nextNode;
@ApiModelProperty("总任务开始时间")
private Date taskBeginTime;
......
......@@ -11,6 +11,7 @@
<result property="taskNo" column="task_no" jdbcType="VARCHAR"/>
<result property="taskName" column="task_name" jdbcType="VARCHAR"/>
<result property="taskStatus" column="task_status" jdbcType="VARCHAR"/>
<result property="nextNode" column="next_node" jdbcType="VARCHAR"/>
<result property="productName" column="product_name" jdbcType="VARCHAR"/>
<result property="productModel" column="product_model" jdbcType="VARCHAR"/>
<result property="entrustedUnit" column="entrusted_unit" jdbcType="VARCHAR"/>
......@@ -49,6 +50,7 @@
<result property="taskNo" column="task_no" jdbcType="VARCHAR"/>
<result property="taskName" column="task_name" jdbcType="VARCHAR"/>
<result property="taskStatus" column="task_status" jdbcType="VARCHAR"/>
<result property="nextNode" column="next_node" jdbcType="VARCHAR"/>
<result property="taskBeginTime" column="task_begin_time" jdbcType="TIMESTAMP"/>
<result property="systemTaskBeginTime" column="system_task_begin_time" jdbcType="TIMESTAMP"/>
<result property="systemTaskEndTime" column="system_task_end_time" jdbcType="TIMESTAMP"/>
......@@ -62,7 +64,7 @@
<select id="findList" parameterType="com.ruoyi.web.request.TaskListRequest" resultMap="BaseResultMap">
SELECT id, system_review_task_id, car_review_task_id,
task_no,task_name,task_status,product_name,product_model,
task_no,task_name,task_status,next_node,product_name,product_model,
entrusted_unit,entrusted_unit_address,entrusted_unit_phone,
entrusted_unit_code,car_type,car_identification_code,
confidentiality_level,sample_name,production_id,production_enterprise,
......@@ -87,6 +89,7 @@
t.task_no,t.task_name,t.task_status,
t.leader_id,t.leader,
t.task_begin_time,
t.next_node,
srt.task_begin_time system_task_begin_time,
srt.task_end_time system_task_end_time,
srt.task_status review_status,
......@@ -128,6 +131,16 @@
</if>
</where>
</select>
<select id="findByCarReviewTaskId" resultType="java.lang.Long">
SELECT id
FROM t_task
WHERE system_review_task_id = #{systemReviewId}
</select>
<select id="findBySystemReviewTaskId" resultType="java.lang.Long">
SELECT id
FROM t_task
WHERE car_review_task_id = #{carReviewId}
</select>
</mapper>
......@@ -71,6 +71,12 @@
<version>9.0.0</version>
</dependency>
<!-- SpringBoot Websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.ruoyi.framework.websocket;
import java.util.concurrent.Semaphore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 信号量相关处理
*
* @author ruoyi
*/
public class SemaphoreUtils
{
/**
* SemaphoreUtils 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class);
/**
* 获取信号量
*
* @param semaphore
* @return
*/
public static boolean tryAcquire(Semaphore semaphore)
{
boolean flag = false;
try
{
flag = semaphore.tryAcquire();
}
catch (Exception e)
{
LOGGER.error("获取信号量异常", e);
}
return flag;
}
/**
* 释放信号量
*
* @param semaphore
*/
public static void release(Semaphore semaphore)
{
try
{
semaphore.release();
}
catch (Exception e)
{
LOGGER.error("释放信号量异常", e);
}
}
}
package com.ruoyi.framework.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* websocket 配置
*
* @author ruoyi
*/
@Configuration
public class WebSocketConfig
{
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
package com.ruoyi.framework.websocket;
import java.util.concurrent.Semaphore;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* websocket 消息处理
*
* @author ruoyi
*/
@Component
@ServerEndpoint("/websocket/{userid}")
public class WebSocketServer
{
/**
* WebSocketServer 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
/**
* 默认最多允许同时在线人数100
*/
public static int socketMaxOnlineCount = 100;
private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("userid") Long userid) throws Exception
{
boolean semaphoreFlag = false;
// 尝试获取信号量
semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
if (!semaphoreFlag)
{
// 未获取到信号量
LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
session.close();
}
else
{
// 添加用户
WebSocketUsers.put(session.getId(), session, userid);
LOGGER.info("\n 建立连接 - {}", session);
LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
WebSocketUsers.sendMessageToUserByText(session, "连接成功");
}
}
/**
* 连接关闭时处理
*/
@OnClose
public void onClose(Session session)
{
LOGGER.info("\n 关闭连接 - {}", session);
// 移除用户
WebSocketUsers.remove(session.getId());
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 抛出异常时处理
*/
@OnError
public void onError(Session session, Throwable exception) throws Exception
{
if (session.isOpen())
{
// 关闭连接
session.close();
}
String sessionId = session.getId();
LOGGER.info("\n 连接异常 - {}", sessionId);
LOGGER.info("\n 异常信息 - {}", exception);
// 移出用户
WebSocketUsers.remove(sessionId);
// 获取到信号量则需释放
SemaphoreUtils.release(socketSemaphore);
}
/**
* 服务器接收到客户端消息时调用的方法
*/
@OnMessage
public void onMessage(String message, Session session)
{
String msg = message.replace("你", "我").replace("吗", "");
WebSocketUsers.sendMessageToUserByText(session, msg);
}
}
package com.ruoyi.framework.websocket;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* websocket 客户端用户集
*
* @author ruoyi
*/
public class WebSocketUsers
{
/**
* WebSocketUsers 日志控制器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
/**
* 用户集
*/
private static Map<String, WebSocketSession> USERS = new ConcurrentHashMap();
/**
* 存储用户
*
* @param key 唯一键
* @param session 用户信息
*/
public static void put(String key, Session session, Long userId)
{
USERS.put(key, new WebSocketSession(userId, session));
}
/**
* 移出用户
*
* @param key 键
*/
public static boolean remove(String key)
{
LOGGER.info("\n 正在移出用户 - {}", key);
WebSocketSession remove = USERS.remove(key);
if (remove != null)
{
boolean containsValue = USERS.containsValue(remove);
LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功");
return containsValue;
}
else
{
return true;
}
}
/**
* 获取在线用户列表
*
* @return 返回用户集合
*/
public static Map<String, WebSocketSession> getUsers()
{
return USERS;
}
/**
* 群发消息文本消息
*
* @param message 消息内容
*/
public static void sendMessageToUsersByText(String message)
{
Collection<WebSocketSession> values = USERS.values();
for (WebSocketSession value : values)
{
sendMessageToUserByText(value.getSession(), message);
}
}
/**
* 发送文本消息
*
* @param session 用户session
* @param message 消息内容
*/
public static void sendMessageToUserByText(Session session, String message)
{
if (session != null)
{
try
{
session.getBasicRemote().sendText(message);
}
catch (IOException e)
{
LOGGER.error("\n[发送消息异常]", e);
}
}
else
{
LOGGER.info("\n[你已离线]");
}
}
/**
* 发送文本消息
*
* @param userId 用户id
* @param message 消息内容
*/
public static void sendMessageToUserByUserId(Long userId, String message) {
Map<String, WebSocketSession> users = getUsers();
for(String key : users.keySet()) {
WebSocketSession webSocketSession = users.get(key);
if(webSocketSession.getUserId().equals(userId)) {
sendMessageToUserByText(webSocketSession.getSession(), message);
}
}
}
private static class WebSocketSession {
private Long userId;
private Session session;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WebSocketSession that = (WebSocketSession) o;
return Objects.equals(userId, that.userId) && Objects.equals(session, that.session);
}
@Override
public int hashCode() {
return Objects.hash(userId, session);
}
public WebSocketSession(Long userId, Session session) {
this.userId = userId;
this.session = session;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment