<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sixkery</groupId>
<artifactId>blog-es</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>blog-es</name>
<description>demo project for spring boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热启动-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <!–Spring Data Rest–>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-rest</artifactId>-->
<!-- </dependency>-->
<!-- <!–Spring Data Hal测试工具–>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-rest-hal-browser</artifactId>-->
<!-- </dependency>-->
<!--spring data 操作es-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.sixkery.controller;
import com.alibaba.fastjson.JSON;
import com.sixkery.entity.es.CDR;
import com.sixkery.entity.es.EmployeeInfo;
import com.sixkery.entity.es.Measure;
import com.sixkery.repository.CDRRepository;
import io.netty.util.internal.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@RestController
@Slf4j
@RequestMapping("/cdr")
public class CDRController {
@Autowired
private CDRRepository cdrRepository;
@Resource
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@RequestMapping("/batchSave")
public String init() throws Exception {
CDR cdr = JSON.parseObject(json, CDR.class);
List<CDR> list = new ArrayList<>();
cdr.setId(System.currentTimeMillis());
cdr.setServerTimeZone(ZoneId.getAvailableZoneIds().iterator().next());
cdr.setStationTimeZone(ZoneId.getAvailableZoneIds().iterator().next());
cdr.setServiceFee(new BigDecimal("1912.21"));
cdr.setStopReason("远程停止");
cdr.setCdrStatus(1);
cdr.setCdrId("AU" + System.currentTimeMillis());
cdr.setUpdateBy(-1L);
cdr.setTotalAmount(new BigDecimal("1212.21"));
cdr.setBizMode(2);
cdr.setActualServiceFee(new BigDecimal("112.21"));
for (int i = 0; i < 10; i++) {
Measure measure = new Measure();
measure.setChargeTime(System.currentTimeMillis() + 10000);
measure.setCurrent(new BigDecimal("32.24").add(new BigDecimal("" + i)));
measure.setVoltage(new BigDecimal("12.12").add(new BigDecimal("" + i)));
measure.setSoc(new BigDecimal("121.21").add(new BigDecimal("" + i)));
cdr.getMeasures().add(measure);
}
list.add(cdr);
cdrRepository.saveAll(list);
return "success -> " + list.size();
}
@GetMapping("/listAll")
public Iterable<CDR> all() {
Iterable<CDR> all = cdrRepository.findAll();
return all;
}
@PostMapping("/search/{size}/{page}")
public SearchPage<CDR> search(@RequestBody CDR employeeInfo, @PathVariable(required = false) Integer size, @PathVariable(required = false) Integer page) {
PageRequest pageRequest = PageRequest.of(Optional.ofNullable(page).orElse(0), Optional.ofNullable(size).orElse(10));
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()
.and(new Criteria("cdrId").startsWith(employeeInfo.getCdrId()))
.and(new Criteria("pileId").is(employeeInfo.getPileId()))
.and(new Criteria("cdrStatus").is(employeeInfo.getCdrStatus()))
.and(new Criteria("telephone").contains(employeeInfo.getTelephone()))
.and(new Criteria("memberName").contains(employeeInfo.getMemberName()))
// .and(new Criteria("startDateTime").greaterThanEqual(employeeInfo.getStartDateTime()))
// .and(new Criteria("startDateTime").lessThanEqual(employeeInfo.getStopDateTime()))
, pageRequest);
SearchHits<CDR> searchHits = elasticsearchRestTemplate.search(criteriaQuery, CDR.class);
SearchPage<CDR> searchPage = SearchHitSupport.searchPageFor(searchHits, pageRequest);
return searchPage;
}
@PostMapping("/findByCdrId")
public Page<CDR> findByCdrId(@RequestBody CDR cdr) {
Page<CDR> search = cdrRepository.findByCdrIdStartingWith(cdr.getCdrId(), Pageable.unpaged());
return search;
}
String json = "{\n" +
" \"id\": 4567890,\n" +
" \"cdrId\": \"AU1649235779527\",\n" +
" \"telephone\": \"18676543456\",\n" +
" \"memberName\": \"老李\",\n" +
" \"locationId\": 12,\n" +
" \"startDateTime\": 1649235779527,\n" +
" \"stopDateTime\": 1649235779527,\n" +
" \"authId\": 21,\n" +
" \"authMethod\": \"auth\",\n" +
" \"meterId\": 12,\n" +
" \"currency\": \"CNY\",\n" +
" \"totalCost\": 1212.21,\n" +
" \"totalEnergy\": null,\n" +
" \"totalTime\": 121221,\n" +
" \"totalParkingTime\": 12121,\n" +
" \"remark\": \"这里是备注信息\",\n" +
" \"cdrStatus\": 1,\n" +
" \"chargingMode\": 0,\n" +
" \"stopReason\": \"远程停止\",\n" +
" \"bizMode\": 2,\n" +
" \"duration\": 10000,\n" +
" \"displayDuration\": \"10秒\",\n" +
" \"startSoc\": 1212,\n" +
" \"stopSoc\": 3333,\n" +
" \"startNumber\": 243,\n" +
" \"stopNumber\": 323,\n" +
" \"totalEnergyFee\": 23.2,\n" +
" \"actualTotalEnergyFee\": 2383.32,\n" +
" \"serviceFee\": 1212.21,\n" +
" \"actualServiceFee\": 112.21,\n" +
" \"timeFee\": 32.9,\n" +
" \"startFee\": 23.8,\n" +
" \"totalAmount\": 1212.21,\n" +
" \"discountAmount\": 232.92,\n" +
" \"paymentAmount\": 33.2,\n" +
" \"stationTimeZone\": null,\n" +
" \"serverTimeZone\": null,\n" +
" \"merchantId\": 12,\n" +
" \"memberId\": 12,\n" +
" \"stationId\": 12,\n" +
" \"pileId\": 12,\n" +
" \"gunId\": 12,\n" +
" \"createBy\": 121,\n" +
" \"createTime\": 1649235779527,\n" +
" \"updateBy\": -1,\n" +
" \"updateTime\": 1649235799527,\n" +
" \"measures\": [\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 121.21,\n" +
" \"current\": 32.24,\n" +
" \"voltage\": 12.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 122.21,\n" +
" \"current\": 33.24,\n" +
" \"voltage\": 13.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 123.21,\n" +
" \"current\": 34.24,\n" +
" \"voltage\": 14.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 124.21,\n" +
" \"current\": 35.24,\n" +
" \"voltage\": 15.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 125.21,\n" +
" \"current\": 36.24,\n" +
" \"voltage\": 16.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 126.21,\n" +
" \"current\": 37.24,\n" +
" \"voltage\": 17.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 127.21,\n" +
" \"current\": 38.24,\n" +
" \"voltage\": 18.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 128.21,\n" +
" \"current\": 39.24,\n" +
" \"voltage\": 19.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 129.21,\n" +
" \"current\": 40.24,\n" +
" \"voltage\": 20.12\n" +
" },\n" +
" {\n" +
" \"chargeTime\": 1649235779527,\n" +
" \"soc\": 130.21,\n" +
" \"current\": 41.24,\n" +
" \"voltage\": 21.12\n" +
" }\n" +
" ]\n" +
"}";
}
package com.sixkery.entity.es;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* @Field(type=FieldType.Text, analyzer=“ik_max_word”) 表示该字段是一个文本,并作最大程度拆分,默认建立索引
* @Field(type=FieldType.Text,index=false) 表示该字段是一个文本,不建立索引
* @Field(type=FieldType.Date) 表示该字段是一个文本,日期类型,默认不建立索引
* @Field(type=FieldType.Long) 表示该字段是一个长整型,默认建立索引
* @Field(type=FieldType.Keyword) 表示该字段内容是一个文本并作为一个整体不可分,默认建立索引
* @Field(type=FieldType.Float) 表示该字段内容是一个浮点类型并作为一个整体不可分,默认建立索引
* <p>
* date 、float、long都是不能够被拆分的
*/
@Data
@Document(indexName = "cdr", indexStoreType = "_doc", useServerConfiguration = true, createIndex = true)
@TypeAlias("cdr")
public class CDR {
/**
* 主键
*/
@Id
private Long id;
/**
* uniquely identifies the cdr within the cpos platform
*/
@Field(type = FieldType.Keyword)
private String cdrId;
@Field(type = FieldType.Text,index = false)
private String displayDuration;
@Field(type = FieldType.Keyword)
private String telephone;
@Field(type = FieldType.Keyword)
private String memberName;
/**
* 场站外键id
*/
@Field(type = FieldType.Long)
private Long locationId;
/**
* start timestamp of the charging session.
*/
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
private Long startDateTime;
/**
* stop timestamp of the charging session.
*/
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
private Long stopDateTime;
/**
* reference to a token, identified by the auth_id field
*/
@Field(type = FieldType.Text)
private String authId;
/**
* auth_request,whitelist
*/
@Field(type = FieldType.Text)
private String authMethod;
/**
* identification of the meter inside the charge point.
*/
@Field(type = FieldType.Text)
private String meterId;
/**
* currency of the cdr in iso 4217 code.
*/
@Field(type = FieldType.Text)
private String currency;
/**
* total cost (excluding vat)
*/
private BigDecimal totalCost;
/**
* total energy charged, in kwh.
*/
private BigDecimal totalEnergy;
/**
* total duration of this session (including the duration
*/
private BigDecimal totalTime;
/**
* total duration during this session that the ev is not
*/
private BigDecimal totalParkingTime;
/**
* optional remark, can be used to provide addition
*/
@Field(type = FieldType.Text)
private String remark;
/**
* 订单状态 1.创建 2.充电中 3.待支付,4.支付中 5.已支付 6.待评价 8.关闭
*/
private int cdrStatus;
/**
* 充电模式(充电策略)
*/
private int chargingMode;
/**
* 停止原因
*/
@Field(type = FieldType.Text)
private String stopReason;
/**
* 业务模式 即chargetype 1 charge via pos; 2 待定
*/
private int bizMode;
/**
* 充电时长毫秒
*/
private Long duration;
/**
* 开始soc
*/
private Long startSoc;
/**
* 结束soc
*/
private Long stopSoc;
/**
* 总起示值
*/
private Long startNumber;
/**
* 总止示值
*/
private Long stopNumber;
/**
* 总电费(元)
*/
private BigDecimal totalEnergyFee;
/**
* 实际总电费(元)
*/
private BigDecimal actualTotalEnergyFee;
/**
* 服务费(元)
*/
private BigDecimal serviceFee;
/**
* 实际服务费(元)
*/
@Field(type = FieldType.Double)
private BigDecimal actualServiceFee;
/**
* 时长费(元)
*/
private BigDecimal timeFee;
/**
* 启动费(元)
*/
private BigDecimal startFee;
/**
* 账单金额(消费金额)
*/
private BigDecimal totalAmount;
/**
* 折扣金额
*/
private BigDecimal discountAmount;
/**
* 实收金额
*/
private BigDecimal paymentAmount;
/**
* 站点时区
*/
@Field(type = FieldType.Text)
private String stationTimeZone;
/**
* 服务器时区
*/
@Field(type = FieldType.Text)
private String serverTimeZone;
/**
* 商家id
*/
@Field(type = FieldType.Long)
private Long merchantId;
/**
* 客户(member)
*/
@Field(type = FieldType.Long)
private Long memberId;
/**
* 充电站id
*/
@Field(type = FieldType.Long)
private Long stationId;
/**
* 充桩号id
*/
@Field(type = FieldType.Long)
private Long pileId;
/**
* 充桩枪id
*/
@Field(type = FieldType.Long)
private Long gunId;
/**
* 创建人
*/
@Field(type = FieldType.Long)
private Long createBy;
/**
* 创建时间
*/
@Field(type = FieldType.Long)
private Long createTime;
/**
* 更新人
*/
@Field(type = FieldType.Long)
private Long updateBy;
/**
* 更新时间
*/
@Field(type = FieldType.Long)
private Long updateTime;
/**
* 充电中的监控
*/
private List<Measure> measures = new ArrayList<>();
}
package com.sixkery;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author sixkery
*/
@SpringBootApplication
public class BlogEsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(BlogEsApplication.class, args);
String[] beanDefinitionNames = run.getBeanDefinitionNames();
for(String s : beanDefinitionNames){
System.out.println(s);
}
}
}
package com.sixkery.entity.es;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Measure {
private Long chargeTime;
private BigDecimal soc;
private BigDecimal current;
private BigDecimal voltage;
}
package com.sixkery.repository;
import com.sixkery.entity.es.CDR;
import com.sixkery.entity.es.EmployeeInfo;
import com.sixkery.entity.es.EsBlog;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
* @author sixkery
* @date 2019/11/24
*/
public interface CDRRepository extends ElasticsearchRepository<CDR, Long> {
Page<CDR> findByCdrId(String cdrId, Pageable pageable);
Page<CDR> findByCdrIdStartingWith(String cdrId, Pageable pageable);
Page<CDR> findByStartDateTimeBetween(Long from, Long to, Pageable pageable);
Page<CDR> findByStartDateTimeGreaterThanEqual(Long from, Pageable pageable);
Page<CDR> findByStartDateTimeLessThanEqual(Long to, Pageable pageable);
}