模拟数据生成

This commit is contained in:
guoshengxiong 2025-05-24 16:49:31 +08:00
parent aae75e0900
commit 9fb4d2bfea
15 changed files with 300 additions and 90 deletions

View File

@ -179,10 +179,19 @@ public class AmmeterRecordDetailController {
List<String> devIdList = StrUtil.split(config.getDevSns(), ",");
ThreadLocalRandom random = ThreadLocalRandom.current();
List<AmmeterRecordDetail> datas = new ArrayList<>();
DateUtil.range(config.getStartTime(), config.getEndTime(), DateField.DAY_OF_MONTH)
DateField unit = null;
if (config.getDataVolume() == 1) {
unit = DateField.DAY_OF_MONTH;
} else if (config.getDataVolume() == 2) {
unit = DateField.WEEK_OF_YEAR;
} else if (config.getDataVolume() == 3) {
unit = DateField.MONTH;
} else if (config.getDataVolume() == 4) {
unit = DateField.YEAR;
}
DateUtil.range(config.getStartTime(), config.getEndTime(), unit)
.forEach(date -> {
BigDecimal use = NumberUtil.roundDown(random.nextDouble(config.getDegreeBegin().doubleValue(), Math.nextUp(config.getDegreeEnd().doubleValue())), 2);
BigDecimal useTotal = BigDecimal.ZERO;
for (String devId : devIdList) {
AmmeterRecordDetail data = new AmmeterRecordDetail();
data.setAmmeterNo(devId);

View File

@ -23,7 +23,7 @@
AND a.add_time &lt;= CONCAT(DATE_FORMAT(#{param.addTime_end}, '%Y-%m-%d'), ' 23:59:59')
</if>
<if test="param.mockDesc == '1'.toString()">
order by a.mock_time desc
order by a.mock_time desc,a.id desc
</if>
<if test="param.mockDesc != '1'.toString()">
order by a.add_time desc

View File

@ -53,6 +53,14 @@
<!--AND a.recive_time &lt;=CONCAT(DATE_FORMAT(#{param.endTime},'%Y-%m-%d'),' 23:59:59')-->
AND a.recive_time &lt;=#{param.endTime}
</if>
<if test="param.reciveTime_begin != null and param.reciveTime_begin != ''">
<!--AND a.recive_time &gt;=CONCAT(DATE_FORMAT(#{param.reciveTime_begin},'%Y-%m-%d'),' 00:00:00')-->
AND a.recive_time &gt;=#{param.reciveTime_begin}
</if>
<if test="param.reciveTime_end != null and param.reciveTime_end != ''">
<!--AND a.recive_time &lt;=CONCAT(DATE_FORMAT(#{param.reciveTime_end},'%Y-%m-%d'),' 23:59:59')-->
AND a.recive_time &lt;=#{param.reciveTime_end}
</if>
<if test="param.mockDesc == '1'.toString()">
order by a.mock_time desc
</if>

View File

@ -1,18 +1,16 @@
package com.zhgd.xmgl.modules.car.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* @Description: 车辆冲洗实时数据
* @author pds
@ -71,12 +69,21 @@ public class CarWashCurrentData implements Serializable {
@Excel(name = "告警类型,1车辆绕行,2冲洗时间不足,3未冲洗,4其他,5正常冲洗", width = 15)
@ApiModelProperty(value = "告警类型,1车辆绕行,2冲洗时间不足,3未冲洗,4其他,5正常冲洗")
private java.lang.String alarmType;
/**离开工地视频地址*/
/**
* 离开工地视频地址
*/
@Excel(name = "离开工地视频地址", width = 15)
@ApiModelProperty(value = "离开工地视频地址")
private java.lang.String leaveVedioUrl;
/**车型*/
/**
* 车型
*/
@Excel(name = "车型", width = 15)
@ApiModelProperty(value = "车型")
private java.lang.String vehicleType;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "模拟生成时间")
private java.util.Date mockTime;
}

View File

@ -21,6 +21,11 @@
<if test="param.endTime != null and param.endTime != ''">
AND a.capture_time &lt;=CONCAT(DATE_FORMAT(#{param.endTime},'%Y-%m-%d'),' 23:59:59')
</if>
<if test="param.mockDesc == '1'.toString()">
order by a.mock_time desc
</if>
<if test="param.mockDesc != '1'.toString()">
order by a.capture_time desc
</if>
</select>
</mapper>

View File

@ -70,4 +70,7 @@ public class ConcreteMonitorCurrentData implements Serializable {
@ApiModelProperty(value = "报警等级1 紧急告警2 重要告警3 次要告警4 提示告警5 正常")
private Integer alarmLevel;
@TableField(exist = false)
@ApiModelProperty(value = "设备名称")
private String devName;
}

View File

@ -67,7 +67,9 @@
<select id="queryPageList" resultType="com.zhgd.xmgl.modules.concrete.entity.ConcreteMonitorCurrentData">
select * from (
select t.*
,cmd.dev_name
from concrete_monitor_current_data t
left join concrete_monitor_dev cmd on t.dev_sn = cmd.dev_sn
)t
${ew.customSqlSegment}
</select>

View File

@ -194,24 +194,33 @@ public class MechanicalEquipmentPositionDataController {
List<String> devSnList = StrUtil.split(config.getDevSns(), ",");
ThreadLocalRandom random = ThreadLocalRandom.current();
List<MechanicalEquipmentPositionData> datas = new ArrayList<>();
List<double[]> trajectorys = new ArrayList<>();
List<Point> points = new ArrayList<>();
List<List<double[]>> trajectorys = new ArrayList<>();
List<List<Point>> points = new ArrayList<>();
List<List<Date>> randomTimeLists = new ArrayList<>();
for (String devSn : devSnList) {
if (config.getRangeType() == 1) {
trajectorys = CircleTrajectoryGenerator.generateSpiralTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum());
trajectorys.add(CircleTrajectoryGenerator.generateRandomCircleTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum()));
} else {
points = PolygonTrajectoryGenerator.generateTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001);
points.add(PolygonTrajectoryGenerator.generateRandomTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001));
}
List<Date> randomTimes = new ArrayList<>();
for (int i = 0; i < config.getDevGenerateNum(); i++) {
randomTimes.add(new Date(random.nextLong(config.getStartTime().getTime(), config.getEndTime().getTime() + 1)));
}
randomTimes.sort(Comparator.comparing(Date::getTime));
randomTimeLists.add(randomTimes);
}
int j = 0;
for (String devSn : devSnList) {
List<double[]> doubles = trajectorys.size() > 0 ? trajectorys.get(j) : new ArrayList<>();
List<Point> points1 = points.size() > 0 ? points.get(j) : new ArrayList<>();
List<Date> randomTimes = randomTimeLists.get(j);
j++;
for (int i = 0; i < config.getDevGenerateNum(); i++) {
MechanicalEquipmentPositionData data = new MechanicalEquipmentPositionData();
data.setDevSn(devSn);
data.setLatitude(config.getRangeType() == 1 ? trajectorys.get(i)[0] : points.get(i).getLat());
data.setLongitude(config.getRangeType() == 1 ? trajectorys.get(i)[1] : points.get(i).getLng());
data.setLatitude(config.getRangeType() == 1 ? doubles.get(i)[0] : points1.get(i).getLat());
data.setLongitude(config.getRangeType() == 1 ? doubles.get(i)[1] : points1.get(i).getLng());
data.setUploadTime(randomTimes.get(i));
EntityUtils.setRandomDoubleInt(config.getSpeedBegin(), config.getSpeedEnd(), data::setSpeed, random);
EntityUtils.setRandomDoubleInt(config.getEquipmentPowerBegin(), config.getEquipmentPowerEnd(), data::setEquipmentPower, random);

View File

@ -195,40 +195,49 @@ public class SafetyHatAlarmController {
List<String> devSnList = StrUtil.split(config.getDevSns(), ",");
ThreadLocalRandom random = ThreadLocalRandom.current();
List<SafetyHatAlarm> datas = new ArrayList<>();
List<double[]> trajectorys = new ArrayList<>();
List<Point> points = new ArrayList<>();
List<List<double[]>> trajectorys = new ArrayList<>();
List<List<Point>> points = new ArrayList<>();
List<List<Date>> randomTimeLists = new ArrayList<>();
for (String devSn : devSnList) {
if (config.getRangeType() == 1) {
trajectorys = CircleTrajectoryGenerator.generateSpiralTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum());
trajectorys.add(CircleTrajectoryGenerator.generateRandomCircleTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum()));
} else {
points = PolygonTrajectoryGenerator.generateTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001);
}
List<String> alarmTypes = new ArrayList<>();
if (StrUtil.isNotBlank(config.getAlarmTypes())) {
alarmTypes = StrUtil.split(config.getAlarmTypes(), ",");
points.add(PolygonTrajectoryGenerator.generateRandomTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001));
}
List<Date> randomTimes = new ArrayList<>();
for (int i = 0; i < config.getDevGenerateNum(); i++) {
randomTimes.add(new Date(random.nextLong(config.getStartTime().getTime(), config.getEndTime().getTime() + 1)));
}
randomTimes.sort(Comparator.comparing(Date::getTime));
randomTimeLists.add(randomTimes);
}
int j = 0;
List<String> alarmTypes = new ArrayList<>();
if (StrUtil.isNotBlank(config.getAlarmTypes())) {
alarmTypes = StrUtil.split(config.getAlarmTypes(), ",");
}
for (String devSn : devSnList) {
List<double[]> doubles = trajectorys.size() > 0 ? trajectorys.get(j) : new ArrayList<>();
List<Point> points1 = points.size() > 0 ? points.get(j) : new ArrayList<>();
List<Date> randomTimes = randomTimeLists.get(j);
j++;
SafetyHatDev dev = devSnMap.get(devSn);
for (int i = 0; i < config.getDevGenerateNum(); i++) {
SafetyHatAlarm alarm = new SafetyHatAlarm();
alarm.setWorkerInfoId(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoId).orElse(null));
alarm.setWorkerInfoName(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoName).orElse(null));
alarm.setDevSn(devSn);
alarm.setAlarmTime(randomTimes.get(i));
SafetyHatAlarm data = new SafetyHatAlarm();
data.setWorkerInfoId(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoId).orElse(null));
data.setWorkerInfoName(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoName).orElse(null));
data.setDevSn(devSn);
data.setAlarmTime(randomTimes.get(i));
if (alarmTypes.size() > 0) {
alarm.setAlarmType(Integer.valueOf(alarmTypes.get(random.nextInt(alarmTypes.size()))));
data.setAlarmType(Integer.valueOf(alarmTypes.get(random.nextInt(alarmTypes.size()))));
}
alarm.setAlarmInfo(ParamEnum.getStr(ParamEnum.SafetyHatAlarmAlarmType.values(), alarm.getAlarmType()));
alarm.setProjectSn(config.getProjectSn());
alarm.setLatitude(config.getRangeType() == 1 ? trajectorys.get(i)[0] : points.get(i).getLat());
alarm.setLongitude(config.getRangeType() == 1 ? trajectorys.get(i)[1] : points.get(i).getLng());
alarm.setFenceId(dev.getFenceId());
alarm.setType(1);
datas.add(alarm);
data.setAlarmInfo(ParamEnum.getStr(ParamEnum.SafetyHatAlarmAlarmType.values(), data.getAlarmType()));
data.setProjectSn(config.getProjectSn());
data.setLatitude(config.getRangeType() == 1 ? doubles.get(i)[0] : points1.get(i).getLat());
data.setLongitude(config.getRangeType() == 1 ? doubles.get(i)[1] : points1.get(i).getLng());
data.setFenceId(dev.getFenceId());
data.setType(1);
datas.add(data);
}
}
if (CollUtil.isNotEmpty(datas)) {

View File

@ -301,32 +301,41 @@ public class SafetyHatDataController {
List<String> devSnList = StrUtil.split(config.getDevSns(), ",");
ThreadLocalRandom random = ThreadLocalRandom.current();
List<SafetyHatData> datas = new ArrayList<>();
List<double[]> trajectorys = new ArrayList<>();
List<Point> points = new ArrayList<>();
List<List<double[]>> trajectorys = new ArrayList<>();
List<List<Point>> points = new ArrayList<>();
List<List<Date>> randomTimeLists = new ArrayList<>();
for (String devSn : devSnList) {
if (config.getRangeType() == 1) {
trajectorys = CircleTrajectoryGenerator.generateSpiralTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum());
trajectorys.add(CircleTrajectoryGenerator.generateRandomCircleTrajectory(config.getLatitude(), config.getLongitude(), config.getAreaRadius(), config.getDevGenerateNum()));
} else {
points = PolygonTrajectoryGenerator.generateTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001);
points.add(PolygonTrajectoryGenerator.generateRandomTrajectoryInPolygon(config.getFenceShape(), config.getDevGenerateNum(), 0.001));
}
List<Date> randomTimes = new ArrayList<>();
for (int i = 0; i < config.getDevGenerateNum(); i++) {
randomTimes.add(new Date(random.nextLong(config.getStartTime().getTime(), config.getEndTime().getTime() + 1)));
}
randomTimes.sort(Comparator.comparing(Date::getTime));
randomTimeLists.add(randomTimes);
}
int j = 0;
for (String devSn : devSnList) {
List<double[]> doubles = trajectorys.size() > 0 ? trajectorys.get(j) : new ArrayList<>();
List<Point> points1 = points.size() > 0 ? points.get(j) : new ArrayList<>();
List<Date> randomTimes = randomTimeLists.get(j);
j++;
SafetyHatDev dev = devSnMap.get(devSn);
for (int i = 0; i < config.getDevGenerateNum(); i++) {
SafetyHatData hatData = new SafetyHatData();
hatData.setWorkerInfoId(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoId).orElse(null));
hatData.setWorkerInfoName(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoName).orElse(null));
hatData.setDevSn(devSn);
hatData.setLatitude(config.getRangeType() == 1 ? trajectorys.get(i)[0] : points.get(i).getLat());
hatData.setLongitude(config.getRangeType() == 1 ? trajectorys.get(i)[1] : points.get(i).getLng());
hatData.setUploadTime(randomTimes.get(i));
hatData.setProjectSn(config.getProjectSn());
hatData.setIsPlatformData(0);
hatData.setType(1);
datas.add(hatData);
SafetyHatData data = new SafetyHatData();
data.setWorkerInfoId(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoId).orElse(null));
data.setWorkerInfoName(Optional.ofNullable(dev).map(SafetyHatDev::getWorkerInfoName).orElse(null));
data.setDevSn(devSn);
data.setLatitude(config.getRangeType() == 1 ? doubles.get(i)[0] : points1.get(i).getLat());
data.setLongitude(config.getRangeType() == 1 ? doubles.get(i)[1] : points1.get(i).getLng());
data.setUploadTime(randomTimes.get(i));
data.setProjectSn(config.getProjectSn());
data.setIsPlatformData(0);
data.setType(1);
datas.add(data);
}
}
if (CollUtil.isNotEmpty(datas)) {

View File

@ -2,6 +2,7 @@ package com.zhgd.xmgl.modules.safetyhat.generator;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class CircleTrajectoryGenerator {
private static final double EARTH_RADIUS = 6371000; // 地球半径
@ -43,4 +44,45 @@ public class CircleTrajectoryGenerator {
}
return trajectory;
}
/**
* 生成圆内随机轨迹均匀分布在圆内
*
* @param latCenter 圆心纬度
* @param lngCenter 圆心经度
* @param radius 半径
* @param numPoints 生成点数
* @return 轨迹点列表 [[lat1,lng1], [lat2,lng2], ...]
*/
public static List<double[]> generateRandomCircleTrajectory(
double latCenter, double lngCenter, double radius, int numPoints) {
List<double[]> trajectory = new ArrayList<>();
double latRad = Math.toRadians(latCenter);
Random random = new Random();
for (int i = 0; i < numPoints; i++) {
// 1. 生成均匀分布的随机距离和角度
double distance = radius * Math.sqrt(random.nextDouble());
double angle = 2 * Math.PI * random.nextDouble();
// 2. 球面坐标转换与螺旋方法相同
double angularDistance = distance / EARTH_RADIUS;
// 计算新纬度
double latNew = Math.toDegrees(Math.asin(
Math.sin(latRad) * Math.cos(angularDistance) +
Math.cos(latRad) * Math.sin(angularDistance) * Math.cos(angle)
));
// 计算新经度
double deltaLng = Math.atan2(
Math.sin(angle) * Math.sin(angularDistance) * Math.cos(latRad),
Math.cos(angularDistance) - Math.sin(latRad) * Math.sin(Math.toRadians(latNew))
);
double lngNew = lngCenter + Math.toDegrees(deltaLng);
trajectory.add(new double[]{latNew, lngNew});
}
return trajectory;
}
}

View File

@ -100,9 +100,97 @@ public class PolygonTrajectoryGenerator {
return inside;
}
/**
* 生成随机的多边形内的轨迹
*
* @param polygonPoints 多边形顶点格式"lng|lat,lng|lat,..."
* @param numPoints 生成的点数
* @param stepSize 步长单位控制轨迹密度
* @return 轨迹点列表
*/
public static List<Point> generateRandomTrajectoryInPolygon(String polygonPoints, int numPoints, double stepSize) {
// 解析多边形顶点
List<Point> polygon = parsePolygon(polygonPoints);
if (polygon.isEmpty() || numPoints <= 0) {
return new ArrayList<>();
}
// 计算多边形边界
double minLng = Double.MAX_VALUE, maxLng = Double.MIN_VALUE;
double minLat = Double.MAX_VALUE, maxLat = Double.MIN_VALUE;
for (Point p : polygon) {
minLng = Math.min(minLng, p.getLng());
maxLng = Math.max(maxLng, p.getLng());
minLat = Math.min(minLat, p.getLat());
maxLat = Math.max(maxLat, p.getLat());
}
Random random = new Random();
List<Point> trajectory = new ArrayList<>();
// 1. 在多边形内随机选择一个起点
Point currentPoint = getRandomPointInPolygon(polygon, minLng, maxLng, minLat, maxLat, random);
trajectory.add(currentPoint);
// 2. 随机行走生成轨迹
for (int i = 1; i < numPoints; i++) {
// 随机方向 (0到2π之间的角度)
double angle = random.nextDouble() * 2 * Math.PI;
// 计算新点的位置
double newLng = currentPoint.getLng() + Math.cos(angle) * stepSize;
double newLat = currentPoint.getLat() + Math.sin(angle) * stepSize;
Point newPoint = new Point(newLng, newLat);
// 检查新点是否在多边形内如果不在则重新生成方向
int attempts = 0;
while (!isPointInPolygon(newPoint, polygon) && attempts < 100) {
angle = random.nextDouble() * 2 * Math.PI;
newLng = currentPoint.getLng() + Math.cos(angle) * stepSize;
newLat = currentPoint.getLat() + Math.sin(angle) * stepSize;
newPoint = new Point(newLng, newLat);
attempts++;
}
// 如果在多次尝试后仍然找不到多边形内的点则减小步长
if (attempts >= 100) {
stepSize *= 0.9;
i--; // 重试当前点
continue;
}
trajectory.add(newPoint);
currentPoint = newPoint;
}
return trajectory;
}
/**
* 在多边形内随机生成一个点
*/
private static Point getRandomPointInPolygon(List<Point> polygon, double minLng, double maxLng,
double minLat, double maxLat, Random random) {
Point point;
int attempts = 0;
do {
double lng = minLng + random.nextDouble() * (maxLng - minLng);
double lat = minLat + random.nextDouble() * (maxLat - minLat);
point = new Point(lng, lat);
attempts++;
// 防止无限循环设置最大尝试次数
if (attempts > 1000) {
// 如果无法找到多边形内的随机点返回多边形第一个点作为后备
return new Point(polygon.get(0).getLng(), polygon.get(0).getLat());
}
} while (!isPointInPolygon(point, polygon));
return point;
}
public static void main(String[] args) {
String polygon = "114.147143|22.674244,114.163176|22.673248,114.159862|22.665211,114.141131|22.667274,114.142904|22.669692";
List<Point> trajectory = PolygonTrajectoryGenerator.generateTrajectoryInPolygon(polygon, 50, 0.001);
List<Point> trajectory = PolygonTrajectoryGenerator.generateRandomTrajectoryInPolygon(polygon, 50, 0.001);
for (Point p : trajectory) {
System.out.printf("经度: %.6f, 纬度: %.6f%n", p.getLng(), p.getLat());

View File

@ -20,6 +20,15 @@
and t.day >= concat(#{p.month},'-01')
and t.day <![CDATA[<=]]> concat(#{p.month},'31')
</if>
<if test="p.day_begin != null and p.day_begin != ''">
and t.day >= #{p.day_begin}
</if>
<if test="p.day_end != null and p.day_end != ''">
and t.day &lt;= if(LENGTH(#{p.day_end}) = 10,
CONCAT(DATE_FORMAT(
#{p.day_end}, '%Y-%m-%d'), ' 23:59:59'),
#{p.day_end})
</if>
<if test="p.mockDesc == '1'.toString()">
order by t.mock_time desc
</if>

View File

@ -172,7 +172,17 @@ public class WaterMeterRecordDetailController {
List<String> devIdList = StrUtil.split(config.getDevSns(), ",");
ThreadLocalRandom random = ThreadLocalRandom.current();
List<WaterMeterRecordDetail> datas = new ArrayList<>();
DateUtil.range(config.getStartTime(), config.getEndTime(), DateField.DAY_OF_MONTH)
DateField unit = null;
if (config.getDataVolume() == 1) {
unit = DateField.DAY_OF_MONTH;
} else if (config.getDataVolume() == 2) {
unit = DateField.WEEK_OF_YEAR;
} else if (config.getDataVolume() == 3) {
unit = DateField.MONTH;
} else if (config.getDataVolume() == 4) {
unit = DateField.YEAR;
}
DateUtil.range(config.getStartTime(), config.getEndTime(), unit)
.forEach(date -> {
BigDecimal use = NumberUtil.roundDown(random.nextDouble(config.getUseTonnageBegin().doubleValue(), Math.nextUp(config.getUseTonnageEnd().doubleValue())), 2);
BigDecimal useTotal = BigDecimal.ZERO;

View File

@ -22,7 +22,7 @@
AND a.add_time &lt;= CONCAT(DATE_FORMAT(#{param.addTime_end}, '%Y-%m-%d'), ' 23:59:59')
</if>
<if test="param.mockDesc == '1'.toString()">
order by a.mock_time desc
order by a.mock_time desc,a.id desc
</if>
<if test="param.mockDesc != '1'.toString()">
order by a.add_time desc