Commit ac8d5ed5 authored by litengwei's avatar litengwei

双规小程序接口

parent 6ec982ef
......@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import java.util.Date;
import java.util.List;
public class AppPointCheckRespone {
private long pointId;
......@@ -13,15 +14,47 @@ public class AppPointCheckRespone {
private String pointNo;
public String getTaskStatus() {
return taskStatus;
}
public void setTaskStatus(String taskStatus) {
this.taskStatus = taskStatus;
}
private Date checkTime;
private Date beginTime;
private Date endTime;
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
private String pointStatus;
private String planName;
private String taskStatus;
private String departmentName;
private String username;
private Date checkTime;
private String strCheckTime;
......
......@@ -73,6 +73,20 @@ public class PlanTask extends BasicEntity {
private int status;
/**
* 状态:0-有效;1-无效
*/
@Column(name="risk_status")
private int riskStatus;
public int getRiskStatus() {
return riskStatus;
}
public void setRiskStatus(int riskStatus) {
this.riskStatus = riskStatus;
}
/**
* 可执行人,一个或多个,多个用,隔开
*/
@Column(name="user_id")
......
......@@ -368,6 +368,13 @@ public class XJConstant {
public static final String YES = "是";
public static final String NOT = "否";
public static final String RISK = "有风险";
public static final String NORISK = "无风险";
public static final String NOUSE = "不涉及";
public static final int RISK_NUM = 1;
public static final int NORISK_NUM = 2;
public static final String INPUT_ITEM_OK_SCORE = "OkScore";
public static final String INPUT_ITEM_NOT_SCORE = "NoScore";
......
......@@ -2,6 +2,7 @@ package com.yeejoin.amos.patrol.business.controller;
import com.alibaba.fastjson.JSON;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.patrol.business.constants.XJConstant;
import com.yeejoin.amos.patrol.business.dao.mapper.CheckMapper;
......@@ -32,6 +33,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -43,8 +45,11 @@ import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.*;
......@@ -172,11 +177,28 @@ public class CheckController extends AbstractBaseController {
return CommonResponseUtil.success(list);
}
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "一键提交巡检任务", notes = "一键提交巡检任务<font color='blue'>手机app</font>")
@RequestMapping(value = "/saveRecordAll", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
public ResponseModel<Object> saveCheckRecordAll(@RequestParam String ids) {
String[] idArr = ids.split(",");
try {
for (String str:idArr
) {
planTaskService.handleAll(str);
}
} catch (Exception e) {
return ResponseHelperUtil.buildErrorResponse("提交失败:"+e.getMessage());
}
return ResponseHelper.buildResponse("提交成功");
}
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "保存巡检记录<font color='blue'>手机app</font>", notes = "保存巡检记录<font color='blue'>手机app</font>")
@RequestMapping(value = "/saveRecordNew", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
public CommonResponse saveCheckRecordNew(
public ResponseModel<Object> saveCheckRecordNew(
@ApiParam(value = "检查信息", required = false) @RequestBody(required = true) CheckRecordParam requestParam) {
Toke token = new Toke();
token.setProduct(request.getHeader("product"));
......@@ -200,15 +222,15 @@ public class CheckController extends AbstractBaseController {
try {
if (planTask != null) {
if (!ToolUtils.transBeanList(planTask.getUserId()).contains(userId.toString())) {
return CommonResponseUtil.failure("无权执行该任务");
return ResponseHelper.buildResponse("无权执行该任务");
}
if (!requestParam.getIsOffline()) {
statu = planTask.getFinishStatus();
if (!requestParam.getIsOffline() && statu == PlanTaskFinishStatusEnum.OVERTIME.getValue()) {
return CommonResponseUtil.failure("任务已超时,上传失败!");
return ResponseHelper.buildResponse("任务已超时,上传失败!");
}else if( statu == PlanTaskFinishStatusEnum.FINISHED.getValue()){
return CommonResponseUtil.failure("任务已完成!");
return ResponseHelper.buildResponse("任务已完成!");
}
}
......@@ -218,7 +240,7 @@ public class CheckController extends AbstractBaseController {
int beginCompareTo = checkTime.compareTo(beginTime);
int endCompareTo = checkTime.compareTo(endTime);
if(beginCompareTo == -1 || endCompareTo == 1){
return CommonResponseUtil.failure("请在计划时间内完成任务!");
return ResponseHelper.buildResponse("请在计划时间内完成任务!");
}
}
int count = checkService.checkHasRecord(requestParam);
......@@ -246,43 +268,43 @@ public class CheckController extends AbstractBaseController {
}
CheckDto checkDto = checkService.saveCheckRecordNew(requestParam,token);
if(StringUtil.isNotEmpty(checkDto)){
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
CompletableFuture<Void> getAddressTask = CompletableFuture.runAsync(() -> {
// 解决异步任务拿不到ThreadLocal里的数据
RequestContextHolder.setRequestAttributes(requestAttributes);
// asyncTaskf(checkDto.getCheckId());
try {
asyncTask.pushCheckInfoTo3D(checkDto.getCheckId());
} catch (InterruptedException e) {
e.printStackTrace();
}
Toke toke= remoteSecurityService.getServerToken();
messageService.pushCheckMessage(toke.getToke(),toke.getProduct(),toke.getAppKey(),checkDto.getCheckId());
});
}
List<Map<String, Object>> checkInputItems = checkMapper.queryCheckInputItemsByCheckId(checkDto.getCheckId());
publishDataToMessage(checkInputItems);
is.pointCheckInfoPushToB(checkDto.getCheckId());
//数字换流站页面刷新
try {
webMqttComponent.publish(patrolTopic, "");
}catch (Exception e){
log.error("数字换流站页面推送失败-----------"+e.getMessage());
}
return CommonResponseUtil.success(checkDto);
// if(StringUtil.isNotEmpty(checkDto)){
//
// RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// CompletableFuture<Void> getAddressTask = CompletableFuture.runAsync(() -> {
// // 解决异步任务拿不到ThreadLocal里的数据
// RequestContextHolder.setRequestAttributes(requestAttributes);
// // asyncTaskf(checkDto.getCheckId());
// try {
// asyncTask.pushCheckInfoTo3D(checkDto.getCheckId());
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// Toke toke= remoteSecurityService.getServerToken();
// messageService.pushCheckMessage(toke.getToke(),toke.getProduct(),toke.getAppKey(),checkDto.getCheckId());
// });
//
// }
//
// List<Map<String, Object>> checkInputItems = checkMapper.queryCheckInputItemsByCheckId(checkDto.getCheckId());
// publishDataToMessage(checkInputItems);
// is.pointCheckInfoPushToB(checkDto.getCheckId());
// //数字换流站页面刷新
// try {
// webMqttComponent.publish(patrolTopic, "");
//
// }catch (Exception e){
// log.error("数字换流站页面推送失败-----------"+e.getMessage());
// }
return ResponseHelper.buildResponse(checkDto);
} else {
return CommonResponseUtil.success("无需重新巡检");
return ResponseHelperUtil.buildErrorResponse("无需重新巡检");
}
} catch (Exception e) {
e.printStackTrace();
// TODO Auto-generated catch block
log.error(e.getMessage());
return CommonResponseUtil.failure("数据提交失败");
return ResponseHelperUtil.buildErrorResponse("数据提交失败");
}
}
......@@ -562,6 +584,30 @@ public class CheckController extends AbstractBaseController {
}
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "获取巡检日历数据<font color='blue'>手机app</font>", notes = "获取巡检日历数据<font color='blue'>手机app</font>")
@PostMapping(value = "/checkCalendarForWx", produces = "application/json;charset=UTF-8")
public ResponseModel<Object> checkCalendarForWx(
@ApiParam(value = "查询条件", required = false) @RequestParam(required = false) String checkTime,
@RequestParam(required = true) String type) {
try {
String userId = RequestContext.getExeUserId();
ReginParams reginParams = getSelectedOrgInfo();
String loginOrgCode = reginParams.getPersonIdentity().getBizOrgCode();
if(StringUtils.isBlank(checkTime)) {
checkTime = DateUtils.dateFormat(new Date(), null);
}
Map<String, Object> map = checkService.checkCalendarNew(checkTime,loginOrgCode,type,userId);
return ResponseHelper.buildResponse(map);
} catch (Exception e) {
e.printStackTrace();
return ResponseHelperUtil.buildErrorResponse(e.getMessage());
}
}
// @TycloudOperation(ApiLevel = UserType.AGENCY)
// @ApiOperation(value = "上传检查记录图片<font color='blue'>手机app</font>", notes = "上传检查记录图片<font color='blue'>手机app</font>")
......
......@@ -48,6 +48,8 @@ import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
......@@ -679,8 +681,8 @@ public class InputItemController extends AbstractBaseController {
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "获取检查分类", notes = "获取检查分类")
@GetMapping(value = "/checkClassify")
public CommonResponse getCheckClassify() {
return CommonResponseUtil.success(inputItemService.getCheckClassify(getToken(), getProduct(), getAppKey(), DictTypeEnum.CHECK_CLASSIFY.getCode()));
public ResponseModel<Object> getCheckClassify() {
return ResponseHelper.buildResponse(inputItemService.getCheckClassify(getToken(), getProduct(), getAppKey(), DictTypeEnum.CHECK_CLASSIFY.getCode()));
}
/*******新增接口************/
......
......@@ -41,6 +41,7 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import javax.servlet.http.HttpServletRequest;
......@@ -101,13 +102,13 @@ public class PlanTaskController extends AbstractBaseController {
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "根据用户条件查询所有计划任务(<font color='blue'>手机app</font>)", notes = "根据用户条件查询所有计划任务(<font color='blue'>手机app</font>)")
@RequestMapping(value = "/queryPlanTaskNew", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
public CommonResponse qryLoginUserPlanTaskNew(
public ResponseModel<Object> qryLoginUserPlanTaskNew(
@ApiParam(value = "查询条件") @RequestBody(required = false) List<CommonRequest> queryRequests,
@ApiParam(value = "分页参数", defaultValue = "current=0&pageSize=10或pageNumber0&pageSize=10") CommonPageable pageable) {
HashMap<String, Object> params = new HashMap<String, Object>();
ReginParams reginParams = getSelectedOrgInfo();
PlanTaskPageParamUtil.fillPlanTask(queryRequests, params);
params.put("orgCode", reginParams.getPersonIdentity().getCompanyBizOrgCode());
params.put("orgCode", reginParams.getPersonIdentity().getBizOrgCode());
params.put("pageSize", pageable.getPageSize());
params.put("offset", pageable.getPageNumber() * pageable.getPageSize());
if (ObjectUtils.isEmpty(params.get("orderBy"))) {
......@@ -118,10 +119,10 @@ public class PlanTaskController extends AbstractBaseController {
}
try {
Page<Map<String, Object>> page = planTaskService.getPlanTasks(getToken(), getProduct(), getAppKey(), params);
return CommonResponseUtil.success(page);
return ResponseHelper.buildResponse(page);
} catch (Exception e) {
e.printStackTrace();
return CommonResponseUtil.failure(e.getMessage());
return ResponseHelperUtil.buildErrorResponse(e.getMessage());
}
}
......@@ -561,13 +562,13 @@ public class PlanTaskController extends AbstractBaseController {
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "根据计划任务ID查询计划任务详情和任务点(<font color='blue'>手机app</font>)", notes = "根据计划任务ID查询计划任务详情和任务点(<font color='blue'>手机app</font>)")
@RequestMapping(value = "/queryPlanTaskByIdNew", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
public CommonResponse qryPlanTaskByIdNew(
public ResponseModel<Object> qryPlanTaskByIdNew(
@ApiParam(value = "巡检计划任务ID", required = true) @RequestParam(required = true) Long planTaskId) {
try {
Map<String, Object> response = new HashMap<String, Object>();
Map task = planTaskService.queryPlanTaskById(planTaskId);
if (ObjectUtils.isEmpty(task) || ObjectUtils.isEmpty(task.get("planTaskId"))) {
return CommonResponseUtil.failure("该计划已刷新,请重新选择!!!");
return ResponseHelperUtil.buildErrorResponse("该计划已刷新,请重新选择!!!");
}
List points = planTaskService.getPlanTaskPoints(planTaskId);
......@@ -580,9 +581,9 @@ public class PlanTaskController extends AbstractBaseController {
task.put("checkDate", sdf.format(task.get("checkDate") != null ? sdf.parse(task.get("checkDate").toString()) : new Date()));
response.put("planTask", task);
response.put("points", points);
return CommonResponseUtil.success(response);
return ResponseHelper.buildResponse(response);
} catch (Exception e) {
return CommonResponseUtil.failure(e.getMessage());
return ResponseHelperUtil.buildErrorResponse(e.getMessage());
}
}
......@@ -615,7 +616,7 @@ public class PlanTaskController extends AbstractBaseController {
// @Authorization(ingore = true)
@ApiOperation(value = "根据计划任务ID和点ID初始化巡检页面(<font color='blue'>手机app</font>)", notes = "根据计划任务ID和点ID初始化巡检页面((<font color='blue'>手机app</font>)")
@RequestMapping(value = "/v2/initPlanTaskNew", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
public CommonResponse qryPlanTaskDetailByIdInVersion2New(
public ResponseModel<Object> qryPlanTaskDetailByIdInVersion2New(
@ApiParam(value = "巡检计划任务ID") @RequestParam(required = false) Long planTaskId,
@ApiParam(value = "巡检点id", required = true) @RequestParam Long pointId) {
try {
......@@ -628,23 +629,23 @@ public class PlanTaskController extends AbstractBaseController {
params.put("planTaskId", planTaskId);
List<CodeOrderVo> list = planTaskService.queryCodeOrderVo(params);
if (ObjectUtils.isEmpty(list)) {
return CommonResponseUtil.failure("该计划已刷新,请重新选择!!!");
return ResponseHelperUtil.buildErrorResponse("该计划已刷新,请重新选择!!!");
}
if (list.get(0).getStatus() == PlanTaskFinishStatusEnum.OVERTIME.getValue()) {
return CommonResponseUtil.failure("任务已超时!");
return ResponseHelperUtil.buildErrorResponse("任务已超时!");
}
if (list.get(0).getStatus() == PlanTaskFinishStatusEnum.FINISHED.getValue()) {
return CommonResponseUtil.failure("任务已结束!");
return ResponseHelperUtil.buildErrorResponse("任务已结束!");
}
//2.顺序执行->按照点planTaskId,查询出所有点并按照orderNo排序,判断上一个点的执行情况
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getPointId().longValue() == pointId) {
if (!PlanTaskDetailStatusEnum.NOTSTARTED.getValue().equals(list.get(i).getIsFinish())) {
return CommonResponseUtil.failure("任务已结束!");
return ResponseHelperUtil.buildErrorResponse("任务已结束!");
}
if (TaskIsOrderEnum.ISORDER.getValue().equals(list.get(0).getInOrder())) {
if (i > 0 && PlanTaskDetailStatusEnum.NOTSTARTED.getValue().equals(list.get(i - 1).getIsFinish())) {
return CommonResponseUtil.failure("请按顺序执行!");
return ResponseHelperUtil.buildErrorResponse("请按顺序执行!");
}
}
}
......@@ -661,7 +662,7 @@ public class PlanTaskController extends AbstractBaseController {
response.put("class", pointClassify);
response.put("checkItem", pointService.getClassifyRiskDescMap(inputItems));
log.info(JSONObject.toJSONString(response));
return CommonResponseUtil.success(response);
return ResponseHelper.buildResponse(response);
} else {
Point point = pointService.queryPointById(pointId);
JSONObject inputItems = pointService.getClassifyRiskDescMap(pointId);
......@@ -670,11 +671,11 @@ public class PlanTaskController extends AbstractBaseController {
response.put("class", catalogs);
response.put("point", point);
log.info(JSONObject.toJSONString(response));
return CommonResponseUtil.success(response);
return ResponseHelper.buildResponse(response);
}
} catch (Exception e) {
log.error("请求异常", e);
return CommonResponseUtil.failure(e.getMessage());
return ResponseHelperUtil.buildErrorResponse(e.getMessage());
}
}
......@@ -908,18 +909,18 @@ public class PlanTaskController extends AbstractBaseController {
@TycloudOperation(ApiLevel = UserType.AGENCY)
@ApiOperation(value = "根据任务id和点id获取“未开始”任务点详情(<font color='blue'>手机app</font>)", notes = "根据任务id和点id获取“未开始”任务点详情(<font color='blue'>手机app</font>)")
@RequestMapping(value = "/queryPointPlanTaskDetail", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
public CommonResponse queryPointPlanTaskDetail(
public ResponseModel<Object> queryPointPlanTaskDetail(
@ApiParam(value = "巡检计划任务ID", required = true) @RequestParam(required = true) Long planTaskId,
@ApiParam(value = "巡检点ID", required = true) @RequestParam(required = true) Long pointId) {
try {
AppPointCheckRespone result = planTaskService.queryPointPlanTaskDetail(getToken(), getProduct(), getAppKey(), planTaskId, pointId);
if (ObjectUtils.isEmpty(result)) {
return CommonResponseUtil.failure("该计划巡检点已更新,请退回重新选择");
return ResponseHelperUtil.buildErrorResponse("该计划巡检点已更新,请退回重新选择");
}
return CommonResponseUtil.success(result);
return ResponseHelper.buildResponse(result);
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure(e.getMessage());
return ResponseHelperUtil.buildErrorResponse(e.getMessage());
}
}
......
......@@ -47,6 +47,8 @@ public interface CheckMapper extends BaseMapper {
*/
List<Map<String,Object>> calendarData(CheckRecordParam param);
List<Map<String,Object>> planCount(String checkTime, String orgCode,String type,String userId);
List<Map<String, Object>> queryRecordByPointId(HashMap<String, Object> req);
Map<String, Object> queryCheckById(@Param(value="checkId") int checkId);
......
package com.yeejoin.amos.patrol.business.dao.repository;
import com.yeejoin.amos.patrol.dao.entity.Plan;
import com.yeejoin.amos.patrol.dao.entity.PlanTask;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Repository("planDao")
public interface IPlanDao extends BaseDao<Plan, Long> {
......@@ -36,4 +38,7 @@ public interface IPlanDao extends BaseDao<Plan, Long> {
List<Plan> findByOriginalIds(List<String> originalIds);
@Transactional
@Query(value = "select * from p_plan where id = (?1) and is_delete = 0", nativeQuery = true)
Optional<Plan> findById(Long id);
}
\ No newline at end of file
......@@ -12,6 +12,8 @@ public class PointCheckDetailBo {
private String pointStatus;
private String taskStatus;
private String planName;
private long routeId;
......@@ -22,6 +24,26 @@ public class PointCheckDetailBo {
private Date checkTime;
private Date beginTime;
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
private Date endTime;
private long checkId;
private String checkRemark;
......@@ -60,6 +82,14 @@ public class PointCheckDetailBo {
private String planTaskId;
public String getTaskStatus() {
return taskStatus;
}
public void setTaskStatus(String taskStatus) {
this.taskStatus = taskStatus;
}
public String getPlanTaskId() {
return planTaskId;
}
......
......@@ -313,6 +313,9 @@ public class CheckServiceImpl implements ICheckService {
} else if (XJConstant.INPUT_ITEM_TEXT.equals(inputItem.getItemType())) {
checkInput = paraseText(checkInput, inputItem.getDataJson(), item, inputItem.getIsScore());
}
if(XJConstant.RISK.equals(checkInput.getInputValue())) {
planTask.setRiskStatus(XJConstant.RISK_NUM);
}
if (XJConstant.NO.equals(checkInput.getIsOk())) {
String classifyName = pointClassifyName != null ? pointClassifyName + "-" : "";
error += (classifyName + inputItem.getName() + "=" + (ObjectUtils.isEmpty(item.getInputValue()) ? "" : item.getInputValue()) + ";");
......@@ -345,6 +348,11 @@ public class CheckServiceImpl implements ICheckService {
equipmentInputItemRoList.add(equipmentInputItemRo);
}
}
if(ObjectUtils.isEmpty(planTask.getRiskStatus())) {
planTask.setRiskStatus(XJConstant.NORISK_NUM);
}
planTaskDao.saveAndFlush(planTask);
if (!ObjectUtils.isEmpty(error) && error.endsWith(";")) {
error.substring(0, error.length() - 1);
check.setIsOk(CheckStatusEnum.UNQUALIFIED.getCode());
......@@ -659,52 +667,52 @@ public class CheckServiceImpl implements ICheckService {
checkInputList.add(checkInput);
}
//规则请求结果
checkInputList.forEach(checkInput -> {
InputItem inputItem = inputItemDao.findById(checkInput.getInputId()).get();
for (int i = 0; i < equipmentInputItemRoList.size(); i++) {
if (inputItem.getItemNo().equals(equipmentInputItemRoList.get(i).getCheckContent())) {
equipmentInputItemRoList.get(i).setCheckInputId(Long.valueOf(checkInput.getId()).toString());
}
}
});
equipmentHandlerService.getRulesCheckResult(equipmentInputItemRoList, token);
// checkInputList.forEach(checkInput -> {
// InputItem inputItem = inputItemDao.findById(checkInput.getInputId()).get();
// for (int i = 0; i < equipmentInputItemRoList.size(); i++) {
// if (inputItem.getItemNo().equals(equipmentInputItemRoList.get(i).getCheckContent())) {
// equipmentInputItemRoList.get(i).setCheckInputId(Long.valueOf(checkInput.getId()).toString());
// }
// }
// });
// equipmentHandlerService.getRulesCheckResult(equipmentInputItemRoList, token);
if (imgList.size() > 0) {
checkService.saveCheckImg(imgList);
}
if (check.getPlanTaskId() > 0) {
planTaskDetailMapper.finishTaskDetail(Long.parseLong(detail.get("planTaskDetailId").toString()), requestParam.getPointId(), requestParam.getPlanTaskId(), requestParam.getUserId());
// planTaskDetailMapper.finishTaskDetail(Long.parseLong(detail.get("planTaskDetailId").toString()), requestParam.getPointId(), requestParam.getPlanTaskId(), requestParam.getUserId());
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
planTaskMapper.reformStatistics(requestParam.getUserId(), sdf.format(new Date()), requestParam.getOrgCode());
}
if(check.getPlanId()!=0) {
// 任务完成、同步修改待办任务状态
Plan plan = planService.queryPlanById(check.getPlanId());
if (!ObjectUtils.isEmpty(plan) && plan.getIsSingleExecution()) {
// 单人执行
updateTaskStatus(plan.getId(), requestParam.getUserId());
} else {
// 多人执行
updateTaskStatus(plan.getId(), null);
}
}
// if(check.getPlanId()!=0) {
// // 任务完成、同步修改待办任务状态
// Plan plan = planService.queryPlanById(check.getPlanId());
// if (!ObjectUtils.isEmpty(plan) && plan.getIsSingleExecution()) {
// // 单人执行
// updateTaskStatus(plan.getId(), requestParam.getUserId());
// } else {
// // 多人执行
// updateTaskStatus(plan.getId(), null);
// }
// }
CheckDto checkDto= new CheckDto(check.getId(), unqualifiedcheckItemList);
// 巡检站端与中心级数据同步
Check finalCheck = check;
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
// 事物提交后业务逻辑
patrolDataSyncService.checkDataSync(finalCheck);
patrolDataSyncService.checkInputDataSync(checkInputList);
Map<String, Object> map = new HashMap<>();
map.put("idList", checkInputList.stream().map(CheckInput::getId).collect(Collectors.toList()));
List<CheckInputSyncBo> checkInputSyncBoList = checkInputMapper.getCheckInputSyncBoList(map);
patrolDataSyncService.checkInputBoDataSync(checkInputSyncBoList);
}
});
// Check finalCheck = check;
// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
// @Override
// public void afterCommit() {
// // 事物提交后业务逻辑
// patrolDataSyncService.checkDataSync(finalCheck);
// patrolDataSyncService.checkInputDataSync(checkInputList);
//
// Map<String, Object> map = new HashMap<>();
// map.put("idList", checkInputList.stream().map(CheckInput::getId).collect(Collectors.toList()));
// List<CheckInputSyncBo> checkInputSyncBoList = checkInputMapper.getCheckInputSyncBoList(map);
// patrolDataSyncService.checkInputBoDataSync(checkInputSyncBoList);
// }
// });
return checkDto;
} catch (Exception e) {
e.printStackTrace();
......@@ -834,10 +842,10 @@ public class CheckServiceImpl implements ICheckService {
if (validateName.equals(item.getInputValue())) {
if (validateIsOk.equals(XJConstant.YES) || validateIsOk.equals(XJConstant.OK)) {
checkInput.setIsOk(XJConstant.OK);
checkInput.setInputValue(XJConstant.YES);
checkInput.setInputValue(item.getInputValue());
} else {
checkInput.setIsOk(XJConstant.NO);
checkInput.setInputValue(XJConstant.NOT);
checkInput.setInputValue(item.getInputValue());
}
score = OkScore;
break;
......@@ -1229,6 +1237,14 @@ public class CheckServiceImpl implements ICheckService {
}
@Override
public Map<String, Object> checkCalendarNew(String checkTime, String orgCode,String type,String userId) {
Map<String, Object> result = new HashMap<>();
List<Map<String, Object>> list = checkMapper.planCount(checkTime, orgCode, type, userId);
result.put("calendarData", list);
return result;
}
@Override
public List<CheckInfoVo> getCheckInfoList(String toke,String product,String appKey,CheckInfoPageParam param) {
List<CheckInfoVo> list= checkMapper.getCheckInfo(param);
......
......@@ -34,6 +34,8 @@ import com.yeejoin.amos.patrol.business.util.Toke;
import com.yeejoin.amos.patrol.business.util.WordTemplateUtils;
import com.yeejoin.amos.patrol.business.vo.*;
import com.yeejoin.amos.patrol.common.enums.NotifyBusinessTypeEum;
import com.yeejoin.amos.patrol.common.enums.PlanTaskDetailIsFinishEnum;
import com.yeejoin.amos.patrol.common.enums.PlanTaskDetailStatusEnum;
import com.yeejoin.amos.patrol.core.common.request.CommonPageable;
import com.yeejoin.amos.patrol.core.common.response.AppCheckInputRespone;
import com.yeejoin.amos.patrol.core.common.response.AppPointCheckRespone;
......@@ -95,6 +97,8 @@ public class PlanTaskServiceImpl implements IPlanTaskService {
@Autowired
IPlanDao iplanDao;
@Autowired
IPlanTaskDetailDao iPlanTaskDetailDao;
@Autowired
private ICheckDao checkDao;
@Autowired
private RemoteSecurityService remoteSecurityService;
......@@ -1131,6 +1135,32 @@ public class PlanTaskServiceImpl implements IPlanTaskService {
}
@Override
public void handleAll(String id) {
Optional<Plan> byId = iplanDao.findById(Long.valueOf(id));
Plan plan = byId.get();
List<PlanTask> planTaskList = iplanTaskDao.findByPlanId(plan.getId());
for (PlanTask p : planTaskList
) {
p.setFinishStatus(XJConstant.TASK_STATUS_FINISH);
p.setRiskStatus(XJConstant.NORISK_NUM);
iplanTaskDao.saveAndFlush(p);
List<PlanTaskDetail> planTaskDetails = iPlanTaskDetailDao.findAllByTaskNoAndStatus(p.getId(), PlanTaskDetailStatusEnum.NOTSTARTED.getValue());
if (!planTaskDetails.isEmpty()) {
planTaskDetails.stream().forEach(action -> {
action.setIsFinish(PlanTaskDetailIsFinishEnum.FINISHED.getValue());
action.setStatus(PlanTaskDetailStatusEnum.QUALIFIED.getValue());
iPlanTaskDetailDao.saveAndFlush(action);
});
}
// 生成巡检记录
jobService.createCheckRecord(p);
}
}
@Override
public List getPlanTaskInfo(HashMap<String, Object> param) {
return planTaskMapper.getPlanTaskByPointId(param);
}
......@@ -1423,29 +1453,11 @@ public class PlanTaskServiceImpl implements IPlanTaskService {
public AppPointCheckRespone queryPointPlanTaskDetail(String toke, String product, String appKey, Long planTaskId, Long pointId) {
AppPointCheckRespone pointCheckRespone = new AppPointCheckRespone();
Check check = checkDao.findByPlanTaskIdAndPointId(planTaskId, pointId);
if (check != null) {
pointCheckRespone = checkService.queryCheckPointDetail(toke, product, appKey, check.getId());
} else {
PointCheckDetailBo planPointInfo = planTaskMapper.getPointPlanTaskInfo(planTaskId, pointId);
PointCheckDetailBo planPointInfo = planTaskMapper.getPointPlanTaskInfo(planTaskId, pointId);
pointCheckRespone.setTaskStatus(planPointInfo.getTaskStatus());
if (planPointInfo != null) {
List<String> userIds = Arrays.asList(planPointInfo.getUsername().split(","));
List<AgencyUserModel> userModelList = remoteSecurityService.listUserByUserIds(toke, product, appKey, planPointInfo.getUsername());
Map<String, String> userModelMap = userModelList.stream().collect(Collectors.toMap(AgencyUserModel::getUserId, AgencyUserModel::getRealName, (k1, k2) -> k2));
if (userModelMap != null) {
List<String> userNameList = new ArrayList<>();
for (String userId : userIds) {
userNameList.add(userModelMap.get(userId));
}
userNameList.remove("");
userNameList.remove(null);
pointCheckRespone.setUsername(Joiner.on(",").join(userNameList));
}
DepartmentModel departmentBo = remoteSecurityService.getDepartmentByDeptId(toke, product, appKey, planPointInfo.getUsername());
if (departmentBo != null) {
pointCheckRespone.setDepartmentName(departmentBo.getDepartmentName());
}
pointCheckRespone.setPointId(pointId);
pointCheckRespone.setPointName(planPointInfo.getPointName());
pointCheckRespone.setPointNo(planPointInfo.getPointNo());
......@@ -1460,6 +1472,12 @@ public class PlanTaskServiceImpl implements IPlanTaskService {
input.setDataJson(action.getDataJson());
input.setIsMultiline(action.getIsMultiline());
input.setIsMust(action.getIsMust());
for (CheckInput ck :check.getCheckInput()
) {
if(ck.getInputId().toString().equals(String.valueOf(action.getCheckInputId()))) {
input.setInputValue(ck.getInputValue());
}
}
input.setItemType(action.getItemType());
input.setOrderNo(action.getOrderNo());
input.setPictureJson(action.getPictureJson());
......@@ -1475,9 +1493,6 @@ public class PlanTaskServiceImpl implements IPlanTaskService {
}
});
pointCheckRespone.setAppCheckInput(appResponeMap);
} else {
return null;
}
}
return pointCheckRespone;
......
......@@ -80,6 +80,14 @@ public interface ICheckService {
Map<String, Object> checkCalendar(CheckRecordParam requestParam);
/**
* 巡检统计
*
* @param requestParam
* @return
*/
Map<String, Object> checkCalendarNew(String time, String orgCode,String type,String userId);
/**
* 根据点ID查询点巡检记录 手机APP
*
* @param req
......
......@@ -89,6 +89,13 @@ public interface IPlanTaskService {
void disablePlanTask(Long[] routeIds);
/**
* 任务列表一键提交
*
* @param id
*/
void handleAll(String id);
/**
* app 根据条件查询用户权限内所有当前巡检计划任务
* @param params
* @return
......
package com.yeejoin.amos.patrol.business.util;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import javax.servlet.http.HttpServletRequest;
public class ResponseHelperUtil {
public ResponseHelperUtil() {
}
public static <T> ResponseModel<T> buildErrorResponse(T t) {
ResponseModel<T> response = new ResponseModel();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
response.setResult(t);
response.setDevMessage("ERROR");
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setTraceId(RequestContext.getTraceId());
response.setPath(request.getServletPath());
return response;
}
}
......@@ -62,6 +62,6 @@ public interface IJobService {
*/
public void msgJobPerform(long msgId,String jobType,String jobName);
public void createCheckRecord(PlanTask planTask);
}
......@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.MessageModel;
import com.yeejoin.amos.patrol.business.bo.CheckInputSyncBo;
......@@ -411,6 +413,149 @@ public class JobService implements IJobService {
});
}
/**
* 创建检查记录
*
* @param planTask
*/
public void createCheckRecord(PlanTask planTask) {
List<PlanTaskPointInputItemBo> planTaskPointInputItems = planTaskMapper.getPlanTaskPointInputItemByPlanTaskId(planTask.getId(), PlanTaskDetailStatusEnum.OMISSION.getValue());
Map<Long, Check> checkMap = new HashMap<>();
Set<Long> checkIds = new HashSet<Long>();
Map<String, String> deptMap = new HashMap<>();
StringBuffer deptName = new StringBuffer();
StringBuffer deptId = new StringBuffer();
StringBuffer userName = new StringBuffer();
if (planTask.getUserDept().indexOf(",") > 0) {
List<String> ids = Arrays.asList(planTask.getUserId().split(","));
List<String> depts = Arrays.asList(planTask.getUserDept().split(","));
depts.stream().forEach(dept -> {
deptMap.put(dept.substring(0, dept.indexOf("@")), dept.substring(dept.indexOf("@") + 1));
deptId.append(dept.substring(dept.indexOf("@") + 1)).append(",");
});
Set<String> departmentOrgCode = new HashSet<>();
for (String key : deptMap.keySet()) {
departmentOrgCode.add(deptMap.get(key));
}
StringBuffer deptIds = new StringBuffer();
Iterator it = departmentOrgCode.iterator();
while (it.hasNext()) {
deptIds.append(it.next()).append(",");
}
String realNames = "";
FeignClientResult<AgencyUserModel> agencyUserModelsDate = Privilege.agencyUserClient.queryByUserId(planTask.getUserId());
AgencyUserModel agencyUserModel = agencyUserModelsDate.getResult();
// FeignClientResult<List<Map<String, Object>>> departmentModeldate = jcsFeignClient.selectByIdDeptList(deptIds.toString().substring(0, deptIds.toString().length() - 1));
// List<Map<String, Object>> departmentModels = departmentModeldate.getResult();
if (agencyUserModel != null) {
realNames = agencyUserModel.getRealName().join(",");
userName.append(realNames);
}
// if (!departmentModels.isEmpty()) {
//// String departmentName = departmentModels.stream().map(map -> map.get("bizOrgName").toString()).collect(Collectors.joining(","));
//// deptName.append(departmentName);
// }
} else {
String realNames = "";
deptId.append(planTask.getUserDept().substring(planTask.getUserDept().indexOf("@") + 1)).append(",");
deptMap.put(planTask.getUserDept().substring(0, planTask.getUserDept().indexOf("@")), planTask.getUserDept().substring(planTask.getUserDept().indexOf("@") + 1));
// FeignClientResult<List<Map<String, Object>>> departmentModeldate = jcsFeignClient.selectByIdDeptList(deptMap.get(planTask.getUserId()));
// List<Map<String, Object>> departmentModel = departmentModeldate.getResult();
//
// if (departmentModel.size() > 0) {
// departmentModel.stream().forEach(model -> {
// deptName.append(model.get("bizOrgName").toString());
// });
// } else {
// deptName.append("其他").append(",");
// }
FeignClientResult<AgencyUserModel> agencyUserModelsDate = Privilege.agencyUserClient.queryByUserId(planTask.getUserId());
AgencyUserModel agencyUserModel = agencyUserModelsDate.getResult();
if (agencyUserModel != null) {
realNames = agencyUserModel.getRealName().join(",");
userName.append(realNames);
}
userName.append(realNames);
}
List<Check> checkList = new ArrayList<>();
List<Long> checkInputIdList = new ArrayList<>();
for (PlanTaskPointInputItemBo arg : planTaskPointInputItems) {
Check check = new Check();
if (checkMap.get(arg.getPointId()) == null) {
check.setOrgCode(arg.getOrgCode());
check.setUserId(planTask.getUserId());
int len = userName.toString().indexOf(",");
if (len != -1) {
check.setUserName(userName.toString());
} else {
check.setUserName(userName.toString());
}
// check.setDepId(deptId.toString().substring(0, deptId.length() - 1));
// check.setDepName(deptName.toString());
check.setPointId(arg.getPointId());
check.setPointName(arg.getPointName());
check.setRouteName(arg.getRouteName());
check.setPlanName(arg.getPlanName());
check.setErrorClassify(arg.getClassifyName());
check.setUploadTime(new Date());
check.setPlanId(arg.getPlanId());
check.setPlanTaskId(arg.getPlanTaskId());
check.setPlanTaskDetailId(arg.getPlanTaskDetailId());
check.setRouteId(arg.getRouteId());
check.setCheckTime(arg.getEndTime());
check.setIsOk(CheckStatusEnum.QUALIFIED.getCode());
try {
check = iCheckDao.save(check);
} catch (InnerInvokException e) {
e.printStackTrace();
}
iCheckDao.flush();
checkList.add(check);
checkMap.put(arg.getPointId(), check);
checkIds.add(check.getId());
} else {
check = checkMap.get(arg.getPointId());
}
if (arg.getInputItemId() != null) {
CheckInput checkInput = new CheckInput();
checkInput.setCheckId(check.getId());
checkInput.setInputId(arg.getInputItemId());
checkInput.setIsOk(CheckStatusEnum.QUALIFIED.getCode());
checkInput.setRoutePointItemId(arg.getRoutePointItemId());
checkInput.setOrderNo(arg.getOrderNo());
checkInput.setOrgCode(arg.getOrgCode());
checkInput.setInputName(arg.getInputName());
checkInput.setPointClassifyId(arg.getClassifyId());
checkInput.setPointClassifyName(arg.getClassifyName());
CheckInput checkInput1 = iCheckInputDao.saveAndFlush(checkInput);
checkInputIdList.add(checkInput1.getId());
}
}
// String usrIds = planTask.getUserId();
// if (!ObjectUtils.isEmpty(usrIds)) {
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// String[] ids = usrIds.split(",");
// for (String userId : usrIds.split(",")) {
// if (ObjectUtils.isEmpty(userId)) {
// continue;
// }
// planTaskMapper.reformStatistics(userId, sdf.format(new Date()), planTask.getOrgCode());
// }
// }
}
private void removeJob(String jobName) {
log.debug("removeJob==jobName==" + jobName);
QuartzManager.removeJob(jobName);
......
......@@ -545,12 +545,38 @@
DATE_FORMAT(check_time, '%Y-%m') = #{checkTime}
<if test="userId!=null and userId!=0">AND FIND_IN_SET(#{userId}, user_id)>0</if>
<if test="routeId!=null and routeId!=0">AND route_id = #{routeId}</if>
<!-- <if test="orgCode!=null">AND org_code LIKE #{orgCode}</if>-->
<!-- <if test="orgCode!=null">AND org_code LIKE #{orgCode}</if>-->
<if test="orgCode!=null">AND org_code LIKE concat(#{orgCode},'%') </if>
GROUP BY is_ok,time
ORDER BY time
</select>
<select id="planCount" resultType="Map">
SELECT
SUM ( CASE WHEN pt.finish_status = '0' THEN ( CASE WHEN pl.plan_type = #{type} THEN 1 ELSE 0 END) ELSE 0 END ) notStart,
SUM ( CASE WHEN pt.finish_status = '2' THEN ( CASE WHEN pl.plan_type = #{type} THEN ( CASE WHEN pt.risk_status = '1' THEN 1 ELSE 0 END) ELSE 0 END) ELSE 0 END ) riskEnd,
SUM ( CASE WHEN pt.finish_status = '2' THEN ( CASE WHEN pl.plan_type = #{type} THEN ( CASE WHEN pt.risk_status = '2' THEN 1 ELSE 0 END) ELSE 0 END) ELSE 0 END ) noRiskEnd,
SUM ( CASE WHEN pt.finish_status = '3' THEN ( CASE WHEN pl.plan_type = #{type} THEN 1 ELSE 0 END) ELSE 0 END ) timeOut,
(
CASE
WHEN '2' = #{type} THEN date_part('week',pt.check_date) ELSE ( DATE_FORMAT ( pt.check_date, ( CASE WHEN '1' = #{type} THEN '%Y-%m-%d' ELSE '%Y-%m' END ) ) )
END
) stime,
pl.plan_type as type
FROM
p_plan_task pt left join p_plan pl on pt.plan_id = pl.id
WHERE
pl.plan_type = #{type}
<if test="type!=null and type==1">AND DATE_FORMAT(pt.check_date, '%Y-%m') = left(#{checkTime}, 7) </if>
<if test="type!=null and type==2">AND DATE_FORMAT(pt.check_date, '%Y-%m') = left(#{checkTime}, 7)</if>
<if test="type!=null and type==3">DATE_FORMAT(pt.check_date, '%Y') = left(#{checkTime}, 4)</if>
<if test="userId!=null and userId!=0">AND FIND_IN_SET(#{userId}, pt.user_id)>0</if>
<!-- <if test="orgCode!=null">AND org_code LIKE #{orgCode}</if>-->
<if test="orgCode!=null">AND pt.org_code LIKE concat(#{orgCode}::text,'%') </if>
GROUP BY stime
order by stime desc
</select>
<select id="queryRecordByPointId" resultType="Map" parameterType="Map">
SELECT
......
......@@ -230,7 +230,8 @@
pt.point_num taskPlanNum,
pt.finish_num finshNum,
pt.user_name userName,
pt.user_dept userDept
pt.user_dept userDept,
p.plan_type
FROM
p_plan_task pt
......@@ -268,7 +269,8 @@
pt.point_num taskPlanNum,
pt.finish_num finshNum,
pt.user_name userName,
pt.user_dept userDept
pt.user_dept userDept,
p.plan_type
FROM
p_plan_task pt
INNER JOIN p_plan p ON pt.plan_id = p.id
......@@ -278,11 +280,12 @@
<sql id="plan-task-app-where">
<where>
<if test="userId != null and userId > 0 "> and find_in_set(#{userId},a.userId)>0</if>
<if test="type != null and type !='' "> and a.plan_type = #{type}</if>
<if test="routeId != null and routeId > 0 "> and a.route_id = #{routeId} </if>
<if test="checkDate != null and checkDate != '' "> and a.beginTime <![CDATA[<=]]> #{checkDate} and a.endTime <![CDATA[>=]]> #{checkDate} </if>
<if test="finishStatus != null"> and a.finishStatus = #{finishStatus}</if>
<if test="orgCode != null and orgCode !=''" >
and a.OrgCode LIKE CONCAT( #{orgCode}, '%' )
and a.OrgCode LIKE CONCAT( #{orgCode}::text, '%' )
</if>
<!-- <if test="departmentId != null and departmentId != 0 ">and a.userDept like concat('%', #{departmentId}, '%')</if>-->
<if test="startTime != null and startTime != '' and endTime != null and endTime != '' ">
......@@ -667,7 +670,8 @@
ppl.dept_id checkDepartmentId,
ppt.user_id userId,
ppt.user_name userName,
pptd.status pointStatus
pptd.status pointStatus,
pptd.is_finish taskStatus
FROM
p_plan_task_detail pptd
LEFT JOIN p_plan_task ppt ON pptd.task_no = ppt.id
......
......@@ -5,7 +5,7 @@
<!-- 根据ID获取路线点的项信息 -->
<select id="getInputItemById" resultType="com.yeejoin.amos.patrol.business.vo.PointInputItemVo">
SELECT
ii.*, prpi.point_classify_id as 'classifyIds',prpi.id routePointItemId
ii.*, prpi.point_classify_id classifyIds,prpi.id routePointItemId
FROM
p_input_item ii
LEFT JOIN p_point_inputitem pii ON pii.input_item_id = ii.id
......@@ -23,7 +23,7 @@
) prp
WHERE
prp.route_point_id = prpi.route_point_id
and !FIND_IN_SET(pii.id, ifnull(prp.exclude_items, 0))
and FIND_IN_SET(pii.id, ifnull(prp.exclude_items, 0)) = 0
</select>
<resultMap id="routePointInputItemMap" type="com.yeejoin.amos.patrol.dao.entity.PointInputItem">
......
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