Commit 3866af04 authored by wujiang's avatar wujiang

修改车辆管理新需求接口

parent 77924dc6
package com.yeejoin.equipmanage.common.entity;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yeejoin.equipmanage.common.entity.publics.BaseEntity;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentOnCarAppVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* 消防车信息
*
......@@ -22,7 +28,7 @@ import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("wl_car")
@TableName(value="wl_car",autoResultMap = true)
@ApiModel(value = "Car对象", description = "消防车信息")
public class Car extends BaseEntity {
......@@ -177,11 +183,48 @@ public class Car extends BaseEntity {
private Integer totalTravel;
@TableField(exist = false)
private double longtitude;
private double longitude;
@TableField(exist = false)
private double latitude;
@TableField(exist = false)
private Integer speed;
@ApiModelProperty(value = "配备方式")
private String deployment;
@ApiModelProperty(value = "配备日期")
private String deployDate;
@ApiModelProperty(value = "配备日期区间")
@TableField(typeHandler = FastjsonTypeHandler.class )
private List<String> deployDateRange;
@ApiModelProperty(value = "排量")
private String displacement;
@ApiModelProperty(value = "车辆产权单位")
private String ownership;
@ApiModelProperty(value = "编号")
private String code;
@ApiModelProperty(value = "扩展字段1")
private String extra1;
@ApiModelProperty(value = "扩展字段2")
private String extra2;
@ApiModelProperty(value = "扩展字段3")
private String extra3;
@ApiModelProperty(value = "扩展字段4")
private String extra4;
@TableField(exist = false)
private String iotMeasurement;
@TableField(exist = false)
private String iotDeviceName;
}
......@@ -83,4 +83,5 @@ public class WlCarMileage extends BaseEntity {
@TableField(exist = false)
private long carId;
}
......@@ -2,7 +2,7 @@ package com.yeejoin.equipmanage.common.entity.dto;
import java.util.List;
import com.yeejoin.equipmanage.common.entity.WlCarMileage;
import com.yeejoin.equipmanage.common.dto.WlCarMileageDto;
import lombok.Data;
@Data
......@@ -14,6 +14,6 @@ public class CarTravelDto {
Integer totalTravel;
List<WlCarMileage> records;
List<WlCarMileageDto> records;
}
......@@ -1419,4 +1419,11 @@ public class CarController extends AbstractBaseController {
public ResponseModel<Object> getQRCode(long id) throws Exception {
return ResponseHelper.buildResponse(iCarService.getQRCode(id));
}
@TycloudOperation(ApiLevel = UserType.AGENCY)
@RequestMapping(value = "/location", method = RequestMethod.GET)
@ApiOperation(httpMethod = "GET", value = "获取二维码图片", notes = "获取二维码图片")
public ResponseModel<Object> location() throws Exception {
return ResponseHelper.buildResponse(iCarService.location());
}
}
package com.yeejoin.equipmanage.controller;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yeejoin.equipmanage.common.dto.WlCarMileageDto;
import com.yeejoin.equipmanage.common.entity.WlCarMileage;
import com.yeejoin.equipmanage.common.entity.dto.CarTravelDto;
import com.yeejoin.equipmanage.common.utils.NameUtils;
import com.yeejoin.equipmanage.service.IWlCarMileageService;
import com.yeejoin.equipmanage.utils.BeanUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
......@@ -159,15 +165,24 @@ public class WlCarMileageController {
pageBean = new Page<>(pageNum, pageSize);
}
Page<WlCarMileage> page = iWlCarMileageService.page(pageBean, wlCarMileage);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
CarTravelDto carTravelDto = new CarTravelDto();
carTravelDto.setRecords(page.getRecords());
carTravelDto.setTotal(page.getTotal());
long totalTime = 0;
int totalTravel = 0;
List<WlCarMileageDto> list = new ArrayList<WlCarMileageDto>();
for (WlCarMileage wl : page.getRecords()) {
WlCarMileageDto wlCarMileageDto = new WlCarMileageDto();
wl.setTime(millisToStringShort(wl.getTakeTime()));
totalTravel += wl.getTravel();
totalTime += wl.getTakeTime();
BeanUtil.copyPropertiesIgnoreNull(wl, wlCarMileageDto);
wlCarMileageDto.setStartTime(sdf.format(wl.getStartTime()));
wlCarMileageDto.setEndTime(sdf.format(wl.getEndTime()));
list.add(wlCarMileageDto);
}
carTravelDto.setRecords(list);
// // 初始化format格式
// SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
// // 设置时区,跳过此步骤会默认设置为"GMT+08:00" 得到的结果会多出来8个小时
......@@ -190,6 +205,8 @@ public class WlCarMileageController {
strBuilder.append(0);
}
strBuilder.append(temp / hper).append(":");
} else {
strBuilder.append("00").append(":");
}
temp = temp % hper;
if (temp / mper > 0) {
......@@ -197,6 +214,8 @@ public class WlCarMileageController {
strBuilder.append(0);
}
strBuilder.append(temp / mper).append(":");
} else {
strBuilder.append("00").append(":");
}
temp = temp % mper;
if (temp / sper > 0) {
......@@ -204,6 +223,8 @@ public class WlCarMileageController {
strBuilder.append(0);
}
strBuilder.append(temp / sper);
} else {
strBuilder.append("00");
}
return strBuilder.toString();
......@@ -220,4 +241,17 @@ public class WlCarMileageController {
public List<Coordinate> travel(long id) {
return iWlCarMileageService.getCoordinateList(id);
}
/**
* 获取日历
*
* @return
*/
@RequestMapping(value = "/calendar", method = RequestMethod.GET)
@ApiOperation(httpMethod = "GET", value = "获取日历", notes = "获取日历")
@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
public Map<String, Boolean> calendar(@RequestParam("id") long id,
@DateTimeFormat(pattern = "yyyy-MM") @RequestParam("date") Date date) {
return iWlCarMileageService.getCalender(id, date);
}
}
......@@ -190,4 +190,6 @@ public interface ICarService extends IService<Car> {
void iotrefreshStaData();
IPage getQRCode(Long id);
List<Car> location();
}
package com.yeejoin.equipmanage.service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
......@@ -20,4 +22,6 @@ public interface IWlCarMileageService extends IService<WlCarMileage> {
Integer totalMileage(String iotCode);
List<Coordinate> getCoordinateList(long id);
Map<String,Boolean> getCalender(long id,Date date);
}
......@@ -27,6 +27,7 @@ import com.yeejoin.equipmanage.common.entity.dto.CarDto;
import com.yeejoin.equipmanage.common.entity.publics.BaseEntity;
import com.yeejoin.equipmanage.common.entity.vo.CarIndexVo;
import com.yeejoin.equipmanage.common.entity.vo.CarPropertyVo;
import com.yeejoin.equipmanage.common.entity.vo.EquipTypeImgAmountVO;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentSpecificVo;
import com.yeejoin.equipmanage.common.enums.*;
import com.yeejoin.equipmanage.common.exception.CommonException;
......@@ -1348,8 +1349,10 @@ public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarS
equipment.setEquipmentCategory(equipmentCategoryMapper.selectById(equipment.getCategoryId()));
}
car.setEquipment(equipment);
car.setCountryName(
iSystemDicService.getOne(new QueryWrapper<SystemDic>().eq("id", car.getCountry())).getName());
if( car.getCountry()!=null) {
car.setCountryName(
iSystemDicService.getOne(new QueryWrapper<SystemDic>().eq("id", car.getCountry())).getName());
}
if (!ObjectUtils.isEmpty(car.getChassisCountry())) {
car.setChassisCountryName(iSystemDicService
.getOne(new QueryWrapper<SystemDic>().eq("id", car.getChassisCountry())).getName());
......@@ -1360,7 +1363,10 @@ public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarS
List<Equipment> equipment1 = iEquipmentService.listByCategoryId(equipment.getCategoryId());
car.setUnit(equipment1.get(0).getUnit());
car.setCategoryId(equipment.getCategoryId());
car.setImportStr(car.getIsImport() ? "进口" : "国产");
if(car.getIsImport()!=null)
{
car.setImportStr(car.getIsImport() ? "进口" : "国产");
}
if (!ObjectUtils.isEmpty(car.getIotCode())) {
Integer totalTravel = iWlCarMileageService.totalMileage(car.getIotCode());
car.setTotalTravel(totalTravel);
......@@ -1368,6 +1374,12 @@ public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarS
.getOne(new LambdaQueryWrapper<WlCarMileage>().eq(WlCarMileage::getIotCode, car.getIotCode())
.orderByDesc(WlCarMileage::getEndTime).last("limit 1"));
car.setSpeed(last != null ? last.getEndSpeed() : null);
//产品 和 设备 各8位
if(car.getIotCode().length()>=16)
{
car.setIotMeasurement(car.getIotCode().substring(0, 8));
car.setIotDeviceName(car.getIotCode().substring(8, car.getIotCode().length()));
}
}
return car;
}
......@@ -1710,4 +1722,22 @@ public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarS
page.setRecords(list);
return page;
}
@Override
public List<Car> location() {
List<Car> list = this.list();
list.forEach(x -> {
if (!ObjectUtils.isEmpty(x.getIotCode())) {
WlCarMileage last = iWlCarMileageService
.getOne(new LambdaQueryWrapper<WlCarMileage>().eq(WlCarMileage::getIotCode, x.getIotCode())
.orderByDesc(WlCarMileage::getEndTime).last("limit 1"));
if(last!=null)
{
x.setLongitude(last.getEndLongitude());
x.setLatitude(last.getEndLatitude());
}
}
});
return list;
}
}
......@@ -254,72 +254,72 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
@Override
@Transactional(rollbackFor = Exception.class)
public void handlerMqttIncrementMessage(String topic, String message) {
TopicEntityVo topicEntity = new TopicEntityVo();
topicEntity.setTopic(topic);
topicEntity.setMessage(message);
int endIndex = topic.lastIndexOf("/");
String iotCode = topic.substring(0, endIndex).replace("/", "");
topicEntity.setIotCode(iotCode);
List<EquipmentSpecificVo> eqIotCodeList = iEquipmentSpecificSerivce.getEquipAndCarIotcodeByIotcode(iotCode);
if (eqIotCodeList.isEmpty()) {
log.info("该数据{}不存在!", iotCode);
return;
}
if (eqIotCodeList.size() > 1) {
log.info("有重复的{}数据!", iotCode);
}
//给 iot服务 推送消息 插数据到 influxdb
if (isSendIot) {
mqttSendGateway.sendToMqtt("influxdb/" + topic.substring(0, endIndex), message);
}
EquipmentSpecificVo vo = eqIotCodeList.get(0);
topicEntity.setType(vo.getType());
topicEntity.setCode(vo.getCode());
JSONObject json = JSONObject.parseObject(message);
Iterator it = json.entrySet().iterator();
List<IotDataVO> iotDatalist = new ArrayList<>();
String traceId = "";
while (it.hasNext()) {
IotDataVO iotDataVO = new IotDataVO();
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
String key = entry.getKey();
Object value = entry.getValue();
iotDataVO.setKey(key);
iotDataVO.setValue(value);
if ("traceId".equalsIgnoreCase(key)) {
traceId = value.toString();
continue;
}
iotDatalist.add(iotDataVO);
}
if (ObjectUtils.isEmpty(iotDatalist)) {
return;
}
log.info(String.format("收到mqtt消息:%s", message));
// 发送emq消息转kafka
JSONObject jsonObject = new JSONObject();
jsonObject.put("topic", topic);
jsonObject.put("data",message);
try {
emqKeeper.getMqttClient().publish("emq.iot.created",jsonObject.toString().getBytes(),1,false);
} catch (MqttException e) {
log.info(String.format("发送eqm转kafka消息失败:%s", e.getMessage()));
}
if (!StringUtils.isEmpty(traceId)) {
String finalTraceId = traceId;
List<IotDataVO> collect = iotDatalist.stream().map(x -> {
x.setTraceId(finalTraceId);
return x;
}).collect(Collectors.toList());
realTimeDateProcessing(topicEntity, collect, vo);
} else {
realTimeDateProcessing(topicEntity, iotDatalist,vo);
}
//
// TopicEntityVo topicEntity = new TopicEntityVo();
// topicEntity.setTopic(topic);
// topicEntity.setMessage(message);
// int endIndex = topic.lastIndexOf("/");
// String iotCode = topic.substring(0, endIndex).replace("/", "");
// topicEntity.setIotCode(iotCode);
// List<EquipmentSpecificVo> eqIotCodeList = iEquipmentSpecificSerivce.getEquipAndCarIotcodeByIotcode(iotCode);
// if (eqIotCodeList.isEmpty()) {
// log.info("该数据{}不存在!", iotCode);
// return;
// }
// if (eqIotCodeList.size() > 1) {
// log.info("有重复的{}数据!", iotCode);
// }
// //给 iot服务 推送消息 插数据到 influxdb
// if (isSendIot) {
// mqttSendGateway.sendToMqtt("influxdb/" + topic.substring(0, endIndex), message);
// }
// EquipmentSpecificVo vo = eqIotCodeList.get(0);
// topicEntity.setType(vo.getType());
// topicEntity.setCode(vo.getCode());
//
// JSONObject json = JSONObject.parseObject(message);
// Iterator it = json.entrySet().iterator();
// List<IotDataVO> iotDatalist = new ArrayList<>();
// String traceId = "";
// while (it.hasNext()) {
// IotDataVO iotDataVO = new IotDataVO();
// Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
// String key = entry.getKey();
// Object value = entry.getValue();
// iotDataVO.setKey(key);
// iotDataVO.setValue(value);
// if ("traceId".equalsIgnoreCase(key)) {
// traceId = value.toString();
// continue;
// }
// iotDatalist.add(iotDataVO);
// }
// if (ObjectUtils.isEmpty(iotDatalist)) {
// return;
// }
// log.info(String.format("收到mqtt消息:%s", message));
//
// // 发送emq消息转kafka
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("topic", topic);
// jsonObject.put("data",message);
//
// try {
// emqKeeper.getMqttClient().publish("emq.iot.created",jsonObject.toString().getBytes(),1,false);
// } catch (MqttException e) {
// log.info(String.format("发送eqm转kafka消息失败:%s", e.getMessage()));
// }
//
// if (!StringUtils.isEmpty(traceId)) {
// String finalTraceId = traceId;
// List<IotDataVO> collect = iotDatalist.stream().map(x -> {
// x.setTraceId(finalTraceId);
// return x;
// }).collect(Collectors.toList());
// realTimeDateProcessing(topicEntity, collect, vo);
// } else {
// realTimeDateProcessing(topicEntity, iotDatalist,vo);
// }
}
/**
......
package com.yeejoin.equipmanage.service.impl;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.restful.utils.ResponseModel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeejoin.equipmanage.common.entity.Car;
import com.yeejoin.equipmanage.common.entity.WlCarMileage;
import com.yeejoin.equipmanage.controller.Coordinate;
import com.yeejoin.equipmanage.fegin.IotFeign;
import com.yeejoin.equipmanage.mapper.WlCarMileageMapper;
import com.yeejoin.equipmanage.service.ICarService;
import com.yeejoin.equipmanage.service.IWlCarMileageService;
/**
......@@ -30,6 +39,9 @@ public class WlCarMileageServiceImpl extends ServiceImpl<WlCarMileageMapper, WlC
@Autowired
IotFeign iotFeign;
@Autowired
ICarService iCarService;
@Override
public Page<WlCarMileage> page(Page<WlCarMileage> page, WlCarMileage wlCarMileage) {
return this.baseMapper.page(page, wlCarMileage);
......@@ -43,25 +55,103 @@ public class WlCarMileageServiceImpl extends ServiceImpl<WlCarMileageMapper, WlC
@Override
public List<Coordinate> getCoordinateList(long id) {
WlCarMileage wlCarMileage = this.getById(id);
String iotCode = wlCarMileage.getIotCode();
String iotCode = wlCarMileage.getIotCode();
String measurement = "0THMcLKR";
String deviceName = iotCode.replace(measurement, "");
ResponseModel<List<Object>> result = iotFeign.getLiveData(measurement, deviceName,
wlCarMileage.getStartTime(), wlCarMileage.getEndTime());
// 由于iot存在毫秒故结束时间要+1秒 iot+1秒有bug还是查不到 +2秒
ResponseModel<List<Object>> result = iotFeign.getLiveData(measurement, deviceName, wlCarMileage.getStartTime(),
new Date(wlCarMileage.getEndTime().getTime()));
List<Object> list = result.getResult();
List<Coordinate> coordinateList = new ArrayList<Coordinate>();
if (list != null) {
for (Object object : list) {
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(object));
Coordinate coordinate = new Coordinate();
List<Double> lnglat = new ArrayList<Double>();
lnglat.add(jsonObject.getDoubleValue("FireCar_Longitude"));
lnglat.add(jsonObject.getDoubleValue("FireCar_Latitude"));
coordinate.setLnglat(lnglat);
coordinate.setSpeed(jsonObject.getIntValue("FireCar_Speed"));
coordinateList.add(coordinate);
if (jsonObject.get("FireCar_Longitude") != null && jsonObject.get("FireCar_Latitude") != null) {
Coordinate coordinate = new Coordinate();
List<Double> lnglat = new ArrayList<Double>();
lnglat.add(jsonObject.getDoubleValue("FireCar_Longitude"));
lnglat.add(jsonObject.getDoubleValue("FireCar_Latitude"));
coordinate.setLnglat(lnglat);
coordinate.setSpeed(jsonObject.getIntValue("FireCar_Speed"));
coordinateList.add(coordinate);
}
}
}
// 倒序坐标变为正序
Collections.reverse(list);
return coordinateList;
}
@Override
public Map<String, Boolean> getCalender(long id, Date date) {
List<String> daylist = new ArrayList<String>();
Map<String, Boolean> map =new HashMap<>();
Car car = iCarService.getById(id);
if (car == null || car.getIotCode() == null || date == null) {
return map;
}
Calendar c = Calendar.getInstance();
// 获取上一个月
c.setTime(date);
c.add(Calendar.MONTH, -1);
daylist.addAll(getDayByMonth(c.getTime()));
// 获取当月
c.setTime(date);
daylist.addAll(getDayByMonth(c.getTime()));
// 获取下一个月
c.setTime(date);
c.add(Calendar.MONTH, 1);
daylist.addAll(getDayByMonth(c.getTime()));
List<Map<String, Object>> hasList = this
.listMaps(new QueryWrapper<WlCarMileage>().select("COUNT(1) AS count,date").lambda().eq(WlCarMileage::getIotCode, car.getIotCode())
.between(WlCarMileage::getDate, daylist.get(0), daylist.get(daylist.size() - 1))
.groupBy(WlCarMileage::getDate));
Map<String, Object> hasMap = new HashMap<>();
for (Map<String, Object> mapOne : hasList) {
hasMap.put(String.valueOf(mapOne.get("date")), mapOne.get("count"));
}
for (String day : daylist) {
boolean has = false;
if (hasMap.containsKey(day)) {
has = true;
}
map.put(day, has);
}
return map;
}
public static List<String> getDayByMonth(Date date) {
List<String> data = new ArrayList<>();
try {
Calendar c = Calendar.getInstance();
c.setTime(date);
// 获取当前的年份
int year = c.get(Calendar.YEAR);
// 获取当前的月份(需要加1才是现在的月份)
int month = c.get(Calendar.MONTH) + 1;
// 获取本月的总天数
int dayCount = c.getActualMaximum(Calendar.DAY_OF_MONTH);
// 定义时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 开始日期为当前年月拼接1号
Date startDate = sdf.parse(year + "-" + month + "-01");
// 结束日期为当前年月拼接该月最大天数
Date endDate = sdf.parse(year + "-" + month + "-" + dayCount);
// 设置calendar的开始日期
c.setTime(startDate);
// 当前时间小于等于设定的结束时间
while (c.getTime().compareTo(endDate) <= 0) {
String time = sdf.format(c.getTime());
data.add(time);
// 当前日期加1
c.add(Calendar.DATE, 1);
}
} catch (ParseException e) {
e.printStackTrace();
}
return data;
}
}
......@@ -8,7 +8,25 @@
<select id="page"
resultType="com.yeejoin.equipmanage.common.entity.WlCarMileage">
SELECT*,date AS name,DATE_FORMAT(from_unixtime(take_time),'%H:%i:%s') AS time FROM wl_car_mileage
SELECT
wl_car_mileage.id,
wl_car_mileage.iot_code,
travel,
date,
start_time,
end_time,
take_time,
start_name,
end_name,
start_longitude,
start_latitude,
end_longitude,
end_latitude,
start_speed,
end_speed,
wl_car_mileage.create_date,
date AS name
FROM wl_car_mileage
LEFT JOIN wl_car ON wl_car.iot_code = wl_car_mileage.iot_code
<where>
<if test="wlCarMileage.carId != null">
......
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