feat(可回溯): 可回溯

初始化
This commit is contained in:
BrandWang
2023-03-23 18:05:14 +08:00
commit f8286861cd
12 changed files with 538 additions and 0 deletions
@@ -0,0 +1,13 @@
package com.wabestway.recall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AfisRecallApplication {
public static void main(String[] args) {
SpringApplication.run(AfisRecallApplication.class, args);
}
}
@@ -0,0 +1,31 @@
package com.wabestway.recall.model;
import lombok.Data;
import org.bson.codecs.pojo.annotations.BsonIgnore;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Data
@Document(collection = "orders")
public class Order {
@Id
private String id;
private String appKey;
private String tenantId;
private String productCode;
private String productName;
@BsonIgnore
private List<String> events;
@Indexed(unique = true)
private String traceId;
@Indexed(unique = true)
private String orderId;
private String complete;
private String archived;
private String fileId;
private String fileUrl;
private long createAt;
}
@@ -0,0 +1,29 @@
package com.wabestway.recall.model;
import lombok.Data;
import org.bson.codecs.pojo.annotations.BsonIgnore;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Data
@Document(collection = "records")
public class Record {
@Id
private String id;
private List<String> events;
@Indexed(unique = false)
private String traceId;
@BsonIgnore
private String orderId;
private boolean last;
private String productCode;
private String productName;
private long createAt;
@BsonIgnore
private String appKey;
private String module;
private String content;
}
@@ -0,0 +1,173 @@
package com.wabestway.recall.model;
import lombok.Data;
import java.util.Map;
@Data
public class ResObj<T> {
private static final String SUCCESS = "success";
private static final String FAILURE = "failure";
private static final Integer SUCCESS_CODE = 200;
private static final Integer FAILURE_CODE = 400;
private Integer code;
private String message;
private String _trackId;
private T data;
private Map extr;
private long timestamp;
private Integer _status;
private ResObj(Integer code, T data) {
this.code = code;
this.data = data;
this.timestamp = System.currentTimeMillis();
}
private ResObj(Integer code, String message, T data) {
this.code = code;
this.data = data;
this.message = message;
this.timestamp = System.currentTimeMillis();
}
private ResObj(T data) {
this.data = data;
this.timestamp = System.currentTimeMillis();
}
private ResObj(Integer code) {
this.code = code;
this.timestamp = System.currentTimeMillis();
}
public boolean isOk() {
return SUCCESS_CODE.equals(this.code);
}
public T data() {
return (T) this.data;
}
public Object get(String key) {
if (this.data != null && key != null) {
return ((Map) this.data).get(key);
}
return null;
}
public ResObj() {
this.timestamp = System.currentTimeMillis();
}
public static ResObj ok() {
ResObj o = new ResObj(SUCCESS_CODE);
return o;
}
public static ResObj ok(Object data) {
ResObj o = new ResObj(SUCCESS_CODE, data);
return o;
}
public static ResObj fail(String msg) {
ResObj o = new ResObj(FAILURE_CODE, msg, null);
return o;
}
public static ResObj fail() {
ResObj o = new ResObj(FAILURE_CODE);
return o;
}
public static ResObj result(Integer code, Object data) {
ResObj o = new ResObj(code, data);
return o;
}
public static ResObj result(Integer code, String message, Object data) {
ResObj o = new ResObj(code, message, data);
return o;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public ResObj<T> setData(T data) {
this.data = data;
return this;
}
public Long getTimestamp() {
return timestamp;
}
public ResObj setTimestamp(Long timestamp) {
this.timestamp = timestamp;
return this;
}
public Map getExtr() {
return extr;
}
public Integer get_status() {
return _status;
}
public void set_status(Integer _status) {
this._status = _status;
}
public String get_trackId() {
return _trackId;
}
public void set_trackId(String _trackId) {
this._trackId = _trackId;
}
public ResObj trackId(String _trackId) {
this._trackId = _trackId;
return this;
}
@Override
public String toString() {
if (message == null) {
return "ResObj(" + code + ")";
}
return "ResObj(" + code + "){" + message + "}";
}
}
@@ -0,0 +1,11 @@
package com.wabestway.recall.repository;
import com.wabestway.recall.model.Order;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import reactor.core.publisher.Mono;
public interface OrderRepository extends ReactiveMongoRepository<Order, String> {
Mono<Order> findByOrderId(String orderId);
Mono<Order> findByTraceId(String traceId);
}
@@ -0,0 +1,11 @@
package com.wabestway.recall.repository;
import com.wabestway.recall.model.Record;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import reactor.core.publisher.Flux;
public interface RecordRepository extends ReactiveMongoRepository<Record, String> {
Flux<Record> findAllByTraceIdOrderByCreateAtAsc(String traceId);
}
@@ -0,0 +1,53 @@
package com.wabestway.recall.web;
import com.wabestway.recall.model.Order;
import com.wabestway.recall.model.Record;
import com.wabestway.recall.model.ResObj;
import com.wabestway.recall.repository.OrderRepository;
import com.wabestway.recall.repository.RecordRepository;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
private final RecordRepository recordRepository;
private final OrderRepository orderRepository;
public OrderController(RecordRepository recordRepository, OrderRepository orderRepository) {
this.recordRepository = recordRepository;
this.orderRepository = orderRepository;
}
@GetMapping
public Flux<Order> getAllOrders() {
return orderRepository.findAll();
}
@PostMapping("/list")
public Flux<Order> list(@RequestBody Order order) {
Example<Order> ep = Example.of(order);
Sort s = Sort.by("createAt");
return orderRepository.findAll(ep, s);
}
@PostMapping("/info/{orderId}")
public Mono<ResObj> findByOrderId(@PathVariable String orderId) {
Mono<Order> forder = orderRepository.findByOrderId(orderId);
return forder.flatMap(fo -> {
Flux<Record> rs = recordRepository.findAllByTraceIdOrderByCreateAtAsc(fo.getTraceId());
Mono<List<List<String>>> es = rs.map(rr -> rr.getEvents()).collectList();
Mono<List<String>> events = es.flatMapIterable(lists -> lists).flatMapIterable(list -> list).collectList();
return events.flatMap(e -> {
fo.setEvents(e);
return Mono.just(ResObj.ok(fo));
});
});
}
}
@@ -0,0 +1,93 @@
package com.wabestway.recall.web;
import com.wabestway.recall.model.Order;
import com.wabestway.recall.model.Record;
import com.wabestway.recall.model.ResObj;
import com.wabestway.recall.repository.OrderRepository;
import com.wabestway.recall.repository.RecordRepository;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.UUID;
@RestController
@RequestMapping("/track")
public class RecallController {
private final RecordRepository recordRepository;
private final OrderRepository orderRepository;
public RecallController(RecordRepository recordRepository, OrderRepository orderRepository) {
this.recordRepository = recordRepository;
this.orderRepository = orderRepository;
}
@GetMapping
public Flux<Record> getAllUsers() {
return recordRepository.findAll();
}
@PostMapping("/save")
public Mono<ResObj> save(@RequestBody Record record) {
if (record.getOrderId() != null && !record.getOrderId().isEmpty()) {
Mono<Order> order = orderRepository.findByOrderId(record.getOrderId());
order.hasElement().subscribe(exit -> {
if (!exit) {
if (record.getTraceId() != null && !record.getTraceId().isEmpty()) {
Mono<Order> tcOrder = orderRepository.findByTraceId(record.getTraceId());
tcOrder.filter(to -> to.getId() != null).flatMap(to -> {
to.setOrderId(record.getOrderId());
if (record.isLast()) {
to.setComplete("1");
}
return orderRepository.save(to);
}).subscribe();
} else {
record.setTraceId(UUID.randomUUID().toString().replace("-", ""));
Order forder = new Order();
forder.setOrderId(record.getOrderId());
forder.setTraceId(record.getTraceId());
forder.setProductCode(record.getProductCode());
forder.setProductName(record.getProductName());
forder.setCreateAt(System.currentTimeMillis());
forder.setAppKey(record.getAppKey());
forder.setArchived("0");
forder.setComplete("0");
if (record.isLast()) {
forder.setComplete("1");
}
orderRepository.save(forder).subscribe();
}
} else {
order.subscribe(to -> {
if (record.isLast()) {
to.setComplete("1");
orderRepository.save(to).subscribe();
}
});
}
});
} else {
if (record.getTraceId() == null || record.getTraceId().isEmpty()) {
record.setTraceId(UUID.randomUUID().toString().replace("-", ""));
Order order = new Order();
order.setTraceId(record.getTraceId());
order.setProductCode(record.getProductCode());
order.setProductName(record.getProductName());
order.setCreateAt(System.currentTimeMillis());
order.setAppKey(record.getAppKey());
order.setArchived("0");
order.setComplete("0");
if (record.isLast()) {
order.setComplete("1");
}
orderRepository.save(order).subscribe();
}
}
record.setCreateAt(System.currentTimeMillis());
return recordRepository.save(record).flatMap(ss -> {
return Mono.just(ResObj.ok(ss));
});
}
}