Merge remote-tracking branch 'origin/test' into test

This commit is contained in:
walker-sheng 2021-01-15 11:04:42 +08:00
commit d65a01fcd9
28 changed files with 1542 additions and 33 deletions

View File

@ -98,6 +98,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.1</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,24 @@
package club.joylink.rtss.controller.pay;
import club.joylink.rtss.services.pay.wechat.WechatPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/api/wechatPay")
public class WechatPayController {
@Autowired
private WechatPayService wechatPayService;
@PostMapping("/receive")
public void receive(@RequestBody String data) {
log.info(String.format("微信回调信息:%s", data));
wechatPayService.receive(data);
}
}

View File

@ -53,7 +53,10 @@ public enum BusinessExceptionAssertEnum implements BusinessExceptionAssert {
WECHAT_CODE_EXPIRED(40029, "wechat code expired"),
INVALID_CLIENT(40031, "invalid client"),
INCORRECT_VERIFICATION_CODE(40051, "incorrect verification code"),
THIRD_SERVICE_CALL_EXCEPTION(40071, "the third service call exception")
THIRD_SERVICE_CALL_EXCEPTION(40071, "the third service call exception"),
//支付异常
PAY_ERROR(50000, "pay error")
;
int code;

View File

@ -295,8 +295,7 @@ public class DraftMapService implements IDraftMapService {
section.setDestinationCode(null);
section.setDestinationCodePoint(null);
}
if (Objects.equals(section.getType(), BusinessConsts.Section.SectionType.Type01) ||
Objects.equals(section.getType(), BusinessConsts.Section.SectionType.Type04) ||
if (Objects.equals(section.getType(), BusinessConsts.Section.SectionType.Type04) ||
Objects.equals(section.getType(), BusinessConsts.Section.SectionType.Type05)) {
section.setParentCode(null);
}

View File

@ -0,0 +1,39 @@
package club.joylink.rtss.services.pay.bean;
import club.joylink.rtss.vo.client.order.OrderDetailVO;
import lombok.Getter;
import lombok.Setter;
import java.time.OffsetDateTime;
import java.util.List;
@Getter
@Setter
public class OrderPay {
/**
* 订单编号*
*/
private String orderNo;
/**
* 订单描述*
*/
private String description;
/**
* 订单总价*
*/
private Integer totalFee;
/**
* 交易结束时间
*/
private OffsetDateTime timeExpire;
/**
* 订单中包含的商品详情
*/
private List<OrderDetailVO> orderDetail;
}

View File

@ -0,0 +1,129 @@
package club.joylink.rtss.services.pay.wechat;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.IOrderService;
import club.joylink.rtss.services.pay.bean.OrderPay;
import club.joylink.rtss.services.pay.wechat.bean.WxUnifiedOrder;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.order.OrderDetailVO;
import club.joylink.rtss.websocket.StompMessageService;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.time.OffsetDateTime;
import java.util.List;
import static club.joylink.rtss.services.pay.wechat.constant.WechatConstants.*;
@Service
@Slf4j
public class WechatPayService {
@Autowired
private IOrderService iorderService;
@Autowired
private StompMessageService stompMessageService;
private CloseableHttpClient httpClient;
/**
* 统一下单
* @param orderPay
* @return 支付二维码url
* @throws IOException
*/
public String unifiedOrder(OrderPay orderPay) throws IOException {
CloseableHttpResponse response = null;
try {
if (httpClient == null)
buildHttpClient();
//构建并发送请求
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
httpPost.setHeader("Accept", "application/json");
WxUnifiedOrder wxUnifiedOrder = new WxUnifiedOrder(orderPay, "http://2i38984j47.qicp.vip/api/wechatPay/receive");
String json = JsonUtils.writeValueAsString(wxUnifiedOrder);
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
entity.setContentType("application/json");
httpPost.setEntity(entity);
response = httpClient.execute(httpPost);
//处理请求结果
int statusCode = response.getStatusLine().getStatusCode();
String result = EntityUtils.toString(response.getEntity());
if (statusCode == 200) { //处理成功
log.info("微信支付下单成功,return body = " + result);
return result;
} else if (statusCode == 204) { //处理成功无返回Body
System.out.println("微信支付下单成功");
return result;
} else {
log.error("failed,resp code = " + statusCode+ ",return body = " + result);
throw BusinessExceptionAssertEnum.PAY_ERROR.exception();
}
} catch (Exception e) {
throw BusinessExceptionAssertEnum.PAY_ERROR.exception("微信Native支付异常", e);
} finally {
if (httpClient != null)
httpClient.close();
if (response != null)
response.close();
}
}
private void buildHttpClient() {
try {
PrivateKey privateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(MCH_PRIVATE_KEY.getBytes("utf-8")));
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(MCH_ID, new PrivateKeySigner(MCH_SERIAL_NO, privateKey)), APIV3_KEY.getBytes("utf-8"));
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(MCH_ID, MCH_SERIAL_NO, privateKey)
.withValidator(new WechatPay2Validator(verifier))
.build();
} catch (Exception e) {
throw BusinessExceptionAssertEnum.PAY_ERROR.exception("微信支付httpClient构建异常", e);
}
}
public static void main(String[] args) throws Exception {
OrderPay pay = new OrderPay();
pay.setOrderNo("2018081400001");
pay.setDescription("标准1号线ATS现地工作站实操");
pay.setTotalFee(1);
pay.setTimeExpire(OffsetDateTime.now().plusMinutes(10));
OrderDetailVO orderDetailVO = new OrderDetailVO();
orderDetailVO.setGoodsId(1L);
orderDetailVO.setGoodsName("测试");
orderDetailVO.setGoodsAmount(1);
orderDetailVO.setPrice(1L);
pay.setOrderDetail(List.of(orderDetailVO));
WechatPayService wps = new WechatPayService();
String result = wps.unifiedOrder(pay);
System.out.println(result);
}
/**
* 支付结果处理
*/
public String receive(String data) {
String result = "支付结果:" + data;
log.info(result);
return result;
}
}

View File

@ -0,0 +1,355 @@
package club.joylink.rtss.services.pay.wechat.bean;
public class WxPayResult {
/**
* 返回状态码
*/
private String returnCode;
/**
* 返回信息
*/
private String returnMsg;
/**
* 公众账号ID*
*/
private String appId;
/**
* 商户号*
*/
private String mchId;
/**
* 设备号
*/
private String deviceInfo;
/**
* 随机字符串*
*/
private String nonceStr;
/**
* 签名*
*/
private String sign;
/**
* 签名类型
*/
private String signType;
/**
* 业务结果
*/
private String resultCode;
/**
* 错误代码
*/
private String errCode;
/**
* 错误代码描述
*/
private String errCodeDes;
/**
* 用户标识
*/
private String openId;
/**
* 是否关注公众账号
*/
private String isSubscribe;
/**
* 交易类型*
*/
private String tradeType;
/**
* 付款银行
*/
private String bankType;
/**
* 订单金额
*/
private Integer totalFee;
/**
* 应结订单金额
*/
private Integer settlementTotalFee;
/**
* 货币种类
*/
private String feeType;
/**
* 现金支付金额
*/
private Integer cashFee;
/**
* 现金支付货币类型
*/
private String cashFeeType;
/**
* 总代金券金额
*/
private Integer couponFee;
/**
* 代金券使用数量
*/
private Integer couponCount;
/**
* 微信支付订单号
*/
private String transactionId;
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 商家数据包
*/
private String attach;
/**
* 支付完成时间
*/
private String timeEnd;
public String getReturnCode() {
return returnCode;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public String getReturnMsg() {
return returnMsg;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getNonceStr() {
return nonceStr;
}
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public String getErrCodeDes() {
return errCodeDes;
}
public void setErrCodeDes(String errCodeDes) {
this.errCodeDes = errCodeDes;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getIsSubscribe() {
return isSubscribe;
}
public void setIsSubscribe(String isSubscribe) {
this.isSubscribe = isSubscribe;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
public String getBankType() {
return bankType;
}
public void setBankType(String bankType) {
this.bankType = bankType;
}
public Integer getTotalFee() {
return totalFee;
}
public void setTotalFee(Integer totalFee) {
this.totalFee = totalFee;
}
public Integer getSettlementTotalFee() {
return settlementTotalFee;
}
public void setSettlementTotalFee(Integer settlementTotalFee) {
this.settlementTotalFee = settlementTotalFee;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public Integer getCashFee() {
return cashFee;
}
public void setCashFee(Integer cashFee) {
this.cashFee = cashFee;
}
public String getCashFeeType() {
return cashFeeType;
}
public void setCashFeeType(String cashFeeType) {
this.cashFeeType = cashFeeType;
}
public Integer getCouponFee() {
return couponFee;
}
public void setCouponFee(Integer couponFee) {
this.couponFee = couponFee;
}
public Integer getCouponCount() {
return couponCount;
}
public void setCouponCount(Integer couponCount) {
this.couponCount = couponCount;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getTimeEnd() {
return timeEnd;
}
public void setTimeEnd(String timeEnd) {
this.timeEnd = timeEnd;
}
@Override
public String toString() {
return "WxPayResult [returnCode=" + returnCode + ", returnMsg=" + returnMsg + ", appId=" + appId + ", mchId="
+ mchId + ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr + ", sign=" + sign + ", signType="
+ signType + ", resultCode=" + resultCode + ", errCode=" + errCode + ", errCodeDes=" + errCodeDes
+ ", openId=" + openId + ", isSubscribe=" + isSubscribe + ", tradeType=" + tradeType + ", bankType="
+ bankType + ", totalFee=" + totalFee + ", settlementTotalFee=" + settlementTotalFee + ", feeType="
+ feeType + ", cashFee=" + cashFee + ", cashFeeType=" + cashFeeType + ", couponFee=" + couponFee
+ ", couponCount=" + couponCount + ", transactionId=" + transactionId + ", outTradeNo=" + outTradeNo
+ ", attach=" + attach + ", timeEnd=" + timeEnd + "]";
}
}

View File

@ -0,0 +1,36 @@
package club.joylink.rtss.services.pay.wechat.bean;
public class WxPayResultReply {
/**
* 返回状态码
*/
private String returnCode;
/**
* 返回信息
*/
private String returnMsg;
public String getReturnCode() {
return returnCode;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public String getReturnMsg() {
return returnMsg;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}
@Override
public String toString() {
return "WxPayResultReply [returnCode=" + returnCode + ", returnMsg=" + returnMsg + "]";
}
}

View File

@ -0,0 +1,221 @@
package club.joylink.rtss.services.pay.wechat.bean;
import club.joylink.rtss.services.pay.bean.OrderPay;
import club.joylink.rtss.services.pay.wechat.constant.WechatConstants;
import club.joylink.rtss.vo.client.order.OrderDetailVO;
import lombok.Getter;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@Getter
public class WxUnifiedOrder {
/**
* 公众账号ID*
*/
private String appid;
/**
* 商户号*
*/
private String mchid;
/**
* 商品描述
*/
private String description;
/**
* 商户订单号
*/
private String out_trade_no;
/**
* 交易结束时间
*/
private String time_expire;
/**
* 附加数据
*/
private String attach;
/**
* 通知地址
*/
private String notify_url;
/**
* 订单优惠标记
*/
private String goods_tag;
/**
* 订单金额信息
*/
private WxPayOrderAmountInfo amount;
/**
* 优惠功能没懂为啥这个参数要叫优惠功能
*/
private WxPayOrderDetail detail;
/**
* 场景信息支付场景描述
*/
private WxPaySceneInfo scene_info;
public WxUnifiedOrder(OrderPay orderPay, String notify_url) {
this.appid = WechatConstants.APP_ID;
this.mchid = WechatConstants.MCH_ID;
this.description = orderPay.getDescription();
this.out_trade_no = orderPay.getOrderNo();
if (orderPay.getTimeExpire() != null) {
this.time_expire = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(orderPay.getTimeExpire().withNano(0));
}
// this.attach =
this.notify_url = notify_url;
// this.goods_tag =
this.amount = new WxPayOrderAmountInfo(orderPay.getTotalFee());
// this.detail = new WxPayOrderDetail(out_trade_no, orderPay.getOrderDetail());
// this.scene_info = new WxPaySceneInfo();
}
/**
* 订单金额信息
*/
@Getter
class WxPayOrderAmountInfo {
/**
* 订单总金额单位/
*/
private int total;
/**
* 货币类型
*/
private String currency = "CNY";
public WxPayOrderAmountInfo(int total) {
this.total = total;
}
}
@Getter
class WxPayOrderDetail {
/**
* 订单原价
* 该字段主要用于防止同一张小票分多次支付以享受多次优惠的情况正常支付订单不必上传此参数
*/
private int cost_price;
/**
* 商家小票ID
*/
private String invoice_id;
/**
* 单品列表
*/
private List<GoodsDetail> goods_detail;
public WxPayOrderDetail(String invoice_id, List<OrderDetailVO> orderDetailVOS) {
this.invoice_id = invoice_id;
this.goods_detail = orderDetailVOS.stream().map(GoodsDetail::new).collect(Collectors.toList());
}
@Getter
class GoodsDetail {
/**
* 商户侧商品编码
* 由半角的大小写字母数字中划线下划线中的一种或几种组成
*/
private String merchant_goods_id;
/**
* 微信侧商品编码
* 微信支付定义的统一商品编号没有可不传
*/
private String wechatpay_goods_id;
/**
* 商品名称
*/
private String goods_name;
/**
* 商品数量
*/
private int quantity;
/**
* 商品单价单位为分
*/
private int unit_price;
public GoodsDetail(OrderDetailVO orderDetail) {
this.merchant_goods_id = orderDetail.getGoodsId().toString();
this.goods_name = orderDetail.getGoodsName();
this.quantity = orderDetail.getGoodsAmount();
this.unit_price = orderDetail.getPrice().intValue();
}
}
}
/**
* 场景信息
*/
@Getter
class WxPaySceneInfo {
/**
* 用户终端ip调用微信支付API的机器IP支持IPv4和IPv6两种格式的IP地址
*/
private String payer_client_ip;
/**
* 商户端设备号商户端设备号门店号或收银设备ID
*/
private String device_id;
/**
* 商户门店信息
*/
private StoreInfo store_info;
public WxPaySceneInfo() {
this.payer_client_ip = WechatConstants.SPBILL_CREATE_IP;
this.device_id = "1";
this.store_info = new StoreInfo();
}
@Getter
class StoreInfo {
/**
* 门店编号商户侧门店编号
*/
private String id;
/**
* 门店名称商户侧门店名称
*/
private String name;
/**
* 地区编码地区编码详细请见省市区编号对照表
*/
private String area_code;
/**
* 详细地址详细的商户门店地址
*/
private String address;
public StoreInfo() {
}
}
}
}

View File

@ -0,0 +1,183 @@
package club.joylink.rtss.services.pay.wechat.bean;
public class WxUnifiedOrderResult {
/**
* 返回状态码*
*/
private String returnCode;
/**
* 返回信息*
*/
private String returnMsg;
/**
* 公众账号ID*
*/
private String appId;
/**
* 商户号*
*/
private String mchId;
/**
* 设备号
*/
private String deviceInfo;
/**
* 随机字符串*
*/
private String nonceStr;
/**
* 签名*
*/
private String sign;
/**
* 业务结果*
*/
private String resultCode;
/**
* 错误代码
*/
private String errCode;
/**
* 错误代码描述
*/
private String errCodeDes;
/**
* 交易类型*
*/
private String tradeType;
/**
* 预支付交易会话标识*
*/
private String prepayId;
/**
* 二维码链接
*/
private String codeUrl;
public String getReturnCode() {
return returnCode;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public String getReturnMsg() {
return returnMsg;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getNonceStr() {
return nonceStr;
}
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public String getErrCodeDes() {
return errCodeDes;
}
public void setErrCodeDes(String errCodeDes) {
this.errCodeDes = errCodeDes;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
public String getPrepayId() {
return prepayId;
}
public void setPrepayId(String prepayId) {
this.prepayId = prepayId;
}
public String getCodeUrl() {
return codeUrl;
}
public void setCodeUrl(String codeUrl) {
this.codeUrl = codeUrl;
}
@Override
public String toString() {
return "WxUnifiedOrderResult [returnCode=" + returnCode + ", returnMsg=" + returnMsg + ", appId=" + appId
+ ", mchId=" + mchId + ", deviceInfo=" + deviceInfo + ", nonceStr=" + nonceStr + ", sign=" + sign
+ ", resultCode=" + resultCode + ", errCode=" + errCode + ", errCodeDes=" + errCodeDes + ", tradeType="
+ tradeType + ", prepayId=" + prepayId + ", codeUrl=" + codeUrl + "]";
}
}

View File

@ -0,0 +1,73 @@
package club.joylink.rtss.services.pay.wechat.constant;
public interface WechatConstants {
public static interface PayUrl {
/** 统一下单接口地址 */
String UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
}
String DATE_FORMAT_STR = "yyyyMMddHHmmss";
/** 公众账号ID */
String APP_ID = "wx41cb66db5faf330f";
/** 商户号 */
String MCH_ID = "1511854231";
/** 机器IP */
String SPBILL_CREATE_IP = "58.87.66.250";
/** 商户平台设置的密钥key应该已经没用了 */
String MCH_KEY = "a6502d608c64fb2f7e6dbcf854cda32a";
/** 商户证书序列号 */
String MCH_SERIAL_NO = "40980EBE9204E4D8956215FE72A1C89A8480FA27";
/** APIv3密钥用于解密接口返回的数据平台证书公钥 */
String APIV3_KEY = "c0666cec1cb15d915f802ce5a3df5c2d";
/** 商户证书私钥 */
String MCH_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
"MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDAzmBwXZX7p+bl\n" +
"IiSl/5CukfAxOmYTVgCbLQ1SBJMd9c52VsPgWED4o/llkvwWXY9EUTDX09qOBroF\n" +
"+iCQBu9iWvStfN2VTmy7ECC3ROv1HzAK2U/aWOsCxv/svpqUoWImqAVaUtOd+kQK\n" +
"RtMVvz/kE+BUZO1RFA3YS7dmYPtAuZQOhLXTvg7uS5k/PaSg39Bx+ZNcymUQtHHs\n" +
"6nH0RmneY2LBtmLZHw3aeb2VCydEPY9tON/vhBbLXe/+Lq3C8Lx8R2IdURCcR2Wl\n" +
"92UlLwR5nBK/kKcgOPA7DjBf4zPGBHgFovytW5gKRY+UscrPgSEHxa9fmRy/SLQS\n" +
"k7AjGZC5AgMBAAECggEBALGIFiLA+Y5sbt3DD43OAbHMbSdXB5B8WziHRkGkNraa\n" +
"lI5AnEHh4YlQqx7NNdN+OKIGRHwm9ZJbPUStqPgVeqzM5YktdXa6bMHeOtGl48Kk\n" +
"Af+rU6zQvSykghjC9OEwrIi9o5gktfg77hSsXEck/7aKWsA64o4KcikcpvXdDNzt\n" +
"qrLumHzJ32WLN6q5JClc4zPfpc3CuRUH3SJevDC7b0E+BFth8c1cX1QDbSl1v8kA\n" +
"anolAIcHqhFvJHzpY+WjHqGVdN4RbPXl+xsOoo3mXsTHybSWgHd2ZJGAAqtQlaSV\n" +
"Y9dRLSU4MQBITNGe5j+rngyRowDkrYqbtAfFqtYQhwUCgYEA5iDlSqu69pr50xf4\n" +
"oQmyOk7ep9U8JOTH+C+OOtbVzpS51oLnq95wJ8cu/QV8qhOUVSZ6KKhD37o7XWhZ\n" +
"vGjBGrlv/C0anAsZ4S10GmL/gbqpCckSe4ITz4VI03oy/fdRK+VtulgMFvjKEr9F\n" +
"cYOkct4IkKAclAECYLhX7VUEKrMCgYEA1ntX1kA4objy7+bgfmxmFkAk50otHJwR\n" +
"huCEOMe9MlgAAc9NYk+GEF1tQPzTQVdVL6jovtrZ+L5HP1SXJGQWY6N06XJThN9+\n" +
"oks027gQWBoXnTQJ8/wXPQpXq3EIgCThzKNkTLq4fsnGIUgRUH2/W+IjlNEThw26\n" +
"KqmuBiXjfOMCgYEAxe6lSIRMWq8RES8c+eWNFfmgKFqPUGw2UpEUlCcT3oqtDIOr\n" +
"H3hCnvQCxj1h7CbK/jIJ/846EsPrK3wFMrgm3wV//DYPHQevSq39nnRnrv0NRw1a\n" +
"iEBpKaRJ7xq7oRSHDGpY5l20iE2UAGvjHq9LUkEGvN35tpLnqKjld4wX+WECgYEA\n" +
"urCwGzDZWoOXCpTHMaP/FD0PIjehnraGVwWUcawClhCdKPYdoIYh5pq734ZyB/0R\n" +
"jCOVO5NZibduYsSprqZkCqSbvhuicRTssC2QO/QyXc2QYmiKhVIXlC0tdHA1+vyf\n" +
"grVyN4uLzeipygxl7c8Wws7LM9ztB3A+bKY3cOiH5AsCgYEA4XOMKmJeucNOrXTY\n" +
"3NdHCb8Yx5JgCYqgdq5uIY7MQ8f3+OlXNwdhh/ftjk8DejWzyY7jpqgj2W3qZFu+\n" +
"BxGJZfCDzAqUS9OufMY8tOO/PaIABzSkU4gliBAuxovj9sU6oSSa7aYD+34QW2UU\n" +
"L83fUdwBuNbwX6vZM45hIASP6C8=\n" +
"-----END PRIVATE KEY-----";
/**
* 支付类型
* @author sheng
*/
public static interface TradeType {
/** 扫码支付 */
String NATIVE = "NATIVE";
/** 公众号支付 */
String JSAPI = "JSAPI";
/** APP支付 */
String APP = "APP";
}
}

View File

@ -0,0 +1,25 @@
package club.joylink.rtss.services.pay.wechat.controller;
import club.joylink.rtss.services.pay.wechat.WechatPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
@RestController
@RequestMapping("/api/wechatpay")
@Slf4j
public class PayResultController {
@Autowired
private WechatPayService wechatPayService;
@RequestMapping(path="/receive", method= {RequestMethod.POST})
public String receive(@RequestBody String data) {
log.info("支付结果通知:" + data);
return this.wechatPayService.receive(data);
}
}

View File

@ -0,0 +1,39 @@
package club.joylink.rtss.services.pay.wechat.util;
import club.joylink.rtss.util.EncryptUtil;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
public class SignUtil {
public static String sign(Map<String, String> map, String mchKey) {
Set<String> keysSet = map.keySet();
Object[] keys = keysSet.toArray();
// 排序
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true;
for (Object key : keys) {
Object value = map.get(key);
if(null != value) {
if (first) {
first = false;
} else {
temp.append("&");
}
temp.append(key).append("=");
String valueString = "";
if (null != value) {
valueString = value.toString();
}
temp.append(valueString);
}
}
String tempStr = temp.toString()+"&key="+mchKey;
System.out.println(tempStr);
return EncryptUtil.md5(tempStr).toUpperCase();
}
}

View File

@ -0,0 +1,56 @@
package club.joylink.rtss.simulation.cbtc.ATP.ground;
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.Responder;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
/** TODO
* 应答器信号
*/
@Slf4j
@Component
public class ResponderService {
@Autowired
private CiApiService ciApiService;
/**循环逻辑,列车到达触发电磁信号,交换数据*/
public void exchangeData2Train(Simulation simulation){
Map<Section,List<Responder>> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap();
if(CollectionUtils.isEmpty(sectionRespondersMap)){
return;
}
log.info("列车触发应答器交换数据");
List<VirtualRealityTrain> trainList = simulation.getRepository().getOnlineTrainList();
trainList.forEach(train -> {
//电磁触发以列车头位置(车载应答器)模拟
SectionPosition headPosition = train.getHeadPosition();
Section section = headPosition.getSection();
var responders = sectionRespondersMap.get(section);
if(CollectionUtils.isEmpty(responders)) return;
// if(responders.f)
});
}
/**接受LEU移动授权*/
public void receiveMA(){
log.info("应答器接收移动授权信息");
}
}

View File

@ -32,12 +32,18 @@ public class TempSpeedLimitService {
public void setSectionLimitSpeed(Simulation simulation, Section section, int limitSpeed) {
if (section.isSwitchTrack()) {
this.setSwitchLimitSpeed(simulation, section.getRelSwitch(), limitSpeed);
} else if (section.isCross()) {
section.setSpeedUpLimit(limitSpeed);
} else if (!CollectionUtils.isEmpty(section.getLogicList())) {
for (Section logic : section.getLogicList()) {
logic.setSpeedUpLimit(limitSpeed);
}
} else {
if(section.isSectionOfCross()){
section.getParent().setSpeedUpLimit(limitSpeed);
}else{
section.setSpeedUpLimit(limitSpeed);
}
}
}
}

View File

@ -101,6 +101,8 @@ public class Operation {
Section_Confirm_Axis_Valid(),
/**区段详情*/
Section_Details(),
/**强解*/
Section_Force_Unlock(),
//--------------------------- 信号机 ---------------------------
/** 封锁 */

View File

@ -112,4 +112,11 @@ public class SectionOperateHandler {
this.atsSectionService.confirmAxleValid(simulation, section);
}
/**强解*/
@OperateHandlerMapping(type = Operation.Type.Section_Force_Unlock)
public void forceUnlock(Simulation simulation, String sectionCode) {
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
this.atsSectionService.forceUnlock(simulation, section);
}
}

View File

@ -50,4 +50,12 @@ public class AtsSectionService {
}
section.confirmValid();
}
public void forceUnlock(Simulation simulation, Section section) {
if (Objects.nonNull(section.getParent())) {
section = section.getParent();
}
log.debug("仿真[{}] : 区段/岔心[{}]强解",simulation.getGroup(),String.format("%s(%s)", section.getName(), section.getCode()));
section.forceUnlocking();
}
}

View File

@ -35,7 +35,7 @@ public class SectionService {
}
if(!section.isBlockade()) {
section.setBlockade(true);
if (!CollectionUtils.isEmpty(section.getLogicList())) {
if (!section.isCross() && !CollectionUtils.isEmpty(section.getLogicList())) {
section.getLogicList().forEach(logic -> logic.setBlockade(true));
}
}
@ -48,7 +48,7 @@ public class SectionService {
public void unblock(Section section) {
if(section.isBlockade()) {
section.setBlockade(false);
if (!CollectionUtils.isEmpty(section.getLogicList())) {
if (!section.isCross() && !CollectionUtils.isEmpty(section.getLogicList())) {
section.getLogicList().forEach(logic -> logic.setBlockade(false));
}
}

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption;
@ -51,6 +52,7 @@ public class MapDeviceBuilder {
section.setRoadType(sectionVO.getRoadType());
section.setPhysical(isPhysicalSection(sectionVO.getType()));
section.setAxleCounter(isAxleCounterSection(sectionVO.getType()));
section.setCross(isCross(sectionVO.getType()));
// 计轴区段和道岔区段校验实际长度
if (isPhysicalSection(sectionVO.getType()) &&
(Objects.isNull(sectionVO.getLengthFact()) ||
@ -61,7 +63,7 @@ public class MapDeviceBuilder {
} else if (isPhysicalSection(sectionVO.getType())) {
section.setLen(sectionVO.getLengthFact());
}
if (Objects.equals(sectionVO.getType(), "02")) { // 逻辑区段
if (Objects.equals(sectionVO.getType(), BusinessConsts.Section.SectionType.Type02)) { // 逻辑区段
Float startOffset = sectionVO.getLogicSectionStartOffset();
Float endOffset = sectionVO.getLogicSectionEndOffset();
section.setLen(sectionVO.getLengthFact());
@ -197,8 +199,8 @@ public class MapDeviceBuilder {
// 区段关系
sectionList.forEach(sectionVO -> {
Section section = (Section) elementMap.get(sectionVO.getCode());
if (Objects.equals("02", sectionVO.getType()) ||
Objects.equals("03", sectionVO.getType())) { // 逻辑区段/道岔区段
if (Objects.equals(BusinessConsts.Section.SectionType.Type02, sectionVO.getType()) ||
Objects.equals(BusinessConsts.Section.SectionType.Type03, sectionVO.getType())) { // 逻辑区段/道岔区段
Section parent = (Section) elementMap.get(sectionVO.getParentCode());
if (Objects.isNull(parent)) {
errMsgList.add(String.format("逻辑区段/道岔区段[%s(%s)]没用关联(道岔)计轴区段或关联的(道岔)计轴区段不存在",
@ -228,6 +230,39 @@ public class MapDeviceBuilder {
}
}
}
if(Objects.equals(BusinessConsts.Section.SectionType.Type01, sectionVO.getType())){
Section parent = (Section) elementMap.get(sectionVO.getParentCode());//所属岔心
if (Objects.nonNull(parent)) {
if(!parent.isCross()){
errMsgList.add(String.format("物理区段[%s(%s)]关联父区段[%s(%s)]不是岔心",
section.getName(), section.getCode(),parent.getName(),parent.getCode()));
}else{
parent.addLogicSection(section);
section.setParent(parent);
}
}
}
if (section.isCross()) {
List<String> relateSectionList = sectionVO.getRelateSectionList();
if (CollectionUtils.isEmpty(relateSectionList)) {
errMsgList.add(String.format("岔心[%s(%s)]没有关联物理区段",
section.getName(), section.getCode()));
} else if (relateSectionList.size() != 2) {
errMsgList.add(String.format("岔心[%s(%s)]必须关联2个物理区段",
section.getName(), section.getCode()));
} else {
relateSectionList.forEach(s -> {
Section physicalSectionOfCross = (Section) elementMap.get(s);
if (Objects.isNull(physicalSectionOfCross)) {
errMsgList.add(String.format("岔心[%s(%s)]关联的物理区段[(%s)]不存在",
section.getName(), section.getCode(), s));
} else if (!physicalSectionOfCross.isAxleCounterSection()) {
errMsgList.add(String.format("岔心[%s(%s)]关联的区段[%s(%s)]不是一般计轴物理区段",
section.getName(), section.getCode(), physicalSectionOfCross.getName(), s));
}
});
}
}
});
// 计轴区段下的逻辑区段排序
List<Section> physicalSectionList = elementMap.values().stream()
@ -348,6 +383,28 @@ public class MapDeviceBuilder {
errMsgList.add(String.format("道岔区段[%s(%s)]有问题",
section.getName(), section.getCode()));
}
if (section.isAxleCounterSection()) {
Section leftSection = section.getLeftSection();
if (Objects.nonNull(leftSection)) {
if (!leftSection.isSwitchTrack()) {
errMsgList.add(String.format("岔心关联的计轴区段[%s(%s)]的左向区段[%s(%s)]不是道岔区段",
section.getName(), section.getCode(), section.getLeftSection().getName(), section.getLeftSection().getCode()));
} else if (!leftSection.getRelSwitch().isC(leftSection)) {
errMsgList.add(String.format("岔心关联的计轴区段[%s(%s)]的左向区段[%s(%s)]不是道岔的C位区段",
section.getName(), section.getCode(), section.getLeftSection().getName(), section.getLeftSection().getCode()));
}
}
Section rightSection = section.getRightSection();
if (Objects.nonNull(rightSection)) {
if (!rightSection.isSwitchTrack()) {
errMsgList.add(String.format("岔心关联的计轴区段[%s(%s)]的右向区段[%s(%s)]不是道岔区段",
section.getName(), section.getCode(), section.getRightSection().getName(), section.getRightSection().getCode()));
} else if (!rightSection.getRelSwitch().isC(rightSection)) {
errMsgList.add(String.format("岔心关联的计轴区段[%s(%s)]的右向区段[%s(%s)]不是道岔的C位区段",
section.getName(), section.getCode(), section.getRightSection().getName(), section.getRightSection().getCode()));
}
}
}
});
// 站台
List<MapStationStandNewVO> standList = graphData.getStationStandList();
@ -867,6 +924,53 @@ public class MapDeviceBuilder {
}
// 接触网
buildCatenary(graphData, elementMap, errMsgList, mapDataBuildResult.getCatenaryMap());
//应答器
buildResponderDataRef(graphData, elementMap, errMsgList);
}
/**应答器数据验证及关系构建*/
private static void buildResponderDataRef(MapGraphDataNewVO graphData, Map<String, MapElement> elementMap, List<String> errMsgList) {
List<MapResponderVO> responderList = graphData.getResponderList();
responderList.forEach(responderVO -> {
Responder responder = new Responder(responderVO.getCode(), responderVO.getName());
if (Objects.nonNull(elementMap.get(responder.getCode()))) {
errMsgList.add(String.format("编码为[%s]的应答器不唯一", responderVO.getCode()));
}
elementMap.put(responder.getCode(), responder);
if (Objects.isNull(responderVO.getType())) {
errMsgList.add(String.format("应答器[%s(%s)]类型未设置", responderVO.getName(), responderVO.getCode()));
} else {
responder.setType(responderVO.getType());
}
Station deviceStation = (Station) elementMap.get(responderVO.getStationCode());
if (Objects.isNull(deviceStation)) {
errMsgList.add(String.format("应答器[%s(%s)]未设置所属设备集中站或所属设备集中站[(%s)]不存在", responderVO.getName(), responderVO.getCode(), responderVO.getStationCode()));
} else if (!deviceStation.isCentralized()) {
errMsgList.add(String.format("应答器[%s(%s)]所属车站[(%s)]不是设备集中站", responderVO.getName(), responderVO.getCode(), responderVO.getStationCode()));
} else {
responder.setDeviceStation(deviceStation);
}
// 关联一般计轴区段及偏移量
Section section = (Section) elementMap.get(responderVO.getSectionCode());
if (Objects.isNull(section)) {
errMsgList.add(String.format("应答器[%s(%s)]未关联区段或关联区段[(%s)]不存在", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
} else if (!section.isPhysical()) {
errMsgList.add(String.format("应答器[%s(%s)]关联区段[(%s)]不是物理区段", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
} else {
responder.setPhysicalSection(section);
}
if (Objects.isNull(responderVO.getOffset()) ||
(Objects.nonNull(section) && Objects.nonNull(section.getLen()) &&
(responderVO.getOffset() < 0 || responderVO.getOffset() > section.getLen()))) {
errMsgList.add(String.format("应答器[%s(%s)]的区段偏移量未设置或数据异常[%s]",
responderVO.getName(), responderVO.getCode(), responderVO.getOffset()));
} else {
responder.setSectionOffset(responderVO.getOffset());
}
});
}
/**
@ -1048,10 +1152,14 @@ public class MapDeviceBuilder {
}
private static boolean isPhysicalSection(String type) {
return Objects.equals(type, "01") || Objects.equals(type, "03");
return Objects.equals(type, BusinessConsts.Section.SectionType.Type01) || Objects.equals(type, BusinessConsts.Section.SectionType.Type03);
}
private static boolean isAxleCounterSection(String type) {
return Objects.equals(type, "01") || Objects.equals(type, "04");
return Objects.equals(type, BusinessConsts.Section.SectionType.Type01) || Objects.equals(type, BusinessConsts.Section.SectionType.Type04);
}
private static boolean isCross(String type) {
return Objects.equals(type, BusinessConsts.Section.SectionType.Type05);
}
}

View File

@ -25,6 +25,7 @@ import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -181,6 +182,9 @@ public class SimulationDataRepository {
*/
private final Map<String, Set<Catenary>> catenaryMap = new ConcurrentHashMap<>();
private Map<Section,List<Responder>> sectionRespondersMap = new HashMap<>();
public Set<Catenary> findCatenaries(String sectionCode) {
return this.catenaryMap.get(sectionCode);
}
@ -319,6 +323,22 @@ public class SimulationDataRepository {
return getListByType(MapElement.DeviceType.STATION, Station.class);
}
public List<Responder> getResponderList() {
return getListByType(MapElement.DeviceType.RESPONDER, Responder.class);
}
public boolean hasResponder() {
return !CollectionUtils.isEmpty(getListByType(MapElement.DeviceType.RESPONDER, Responder.class));
}
public Map<Section,List<Responder>> getSectionRespondersMap() {
if(hasResponder() && CollectionUtils.isEmpty(sectionRespondersMap)){
sectionRespondersMap = getListByType(MapElement.DeviceType.RESPONDER, Responder.class).stream().collect(Collectors.groupingBy(Responder::getPhysicalSection));
return sectionRespondersMap;
}
return sectionRespondersMap;
}
public Station findStationByName(String stationName) {
List<Station> stationList = this.getStationList();
List<Station> matchList = new ArrayList<>(1);

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.map;
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
import lombok.Getter;
import lombok.Setter;
@ -12,25 +13,54 @@ public class Responder extends MapNamedElement {
public Responder(String code, String name) {
super(code, name, DeviceType.RESPONDER);
}
// ------------------固有属性/关联关系---------------------
/**应答器类型*/
private Responder.ResponderType type;
/**
* 所属设备集中站
*/
/** 所属设备集中站*/
private Station deviceStation;
/** 物理区段*/
private Section physicalSection;
/** 在区段上的偏移量*/
private float sectionOffset;
// ------------------状态属性---------------------
/**坡度*/
/**弯度*/
/**限速*/
/**移动授权位置*/
private MovementAuthority ma;
/**其它警示信息:升降弓/进出隧道/鸣笛/...*/
// ------------------操作---------------------
/***LEU状态数据同步给应答器*/
/**推送数据给列车*/
@Override
public void reset() {
}
public boolean isFB(){
return ResponderType.FB == type;
}
public boolean isVB(){
return ResponderType.VB == type;
}
public boolean isIB(){
return ResponderType.IB == type;
}
public enum ResponderType {
/** 固定应答器*/

View File

@ -408,8 +408,6 @@ public class Route extends MapNamedElement {
}
public synchronized void startSetting(LocalDateTime systemTime) {
if (getCode().equals("Route533"))
System.out.println();
this.setSetting(true);
this.settingStartTime = systemTime;
this.requisition = false;

View File

@ -58,6 +58,9 @@ public class Section extends MayOutOfOrderDevice {
*/
private boolean physical;
/**是否岔心*/
private boolean cross;
/**
* 是否计轴区段区段两端有计轴器道岔计轴区段和一般计轴区段
*/
@ -446,7 +449,23 @@ public class Section extends MayOutOfOrderDevice {
!CollectionUtils.isEmpty(this.logicList) &&
this.logicList.get(0).isSwitchTrack();
}
/**
* 一般计轴区段
*
* @return
*/
public boolean isAxleCounterSection() {
return this.physical && this.axleCounter;
}
/**
* 一般计轴区段
*
* @return
*/
public boolean isSectionOfCross() {
return this.physical && this.axleCounter && Objects.nonNull(parent) && parent.isCross();
}
/**
* 是否通信车占用
*
@ -543,6 +562,15 @@ public class Section extends MayOutOfOrderDevice {
}
}
public void forceUnlocking() {
this.routeLock = false;
this.overlapLock = false;
this.lockRight = false;
if (!isCross() && !CollectionUtils.isEmpty(this.logicList)) {
this.logicList.forEach(logic -> logic.forceUnlocking());
}
}
/**
* 进路延续保护(连同逻辑区段)
*/

View File

@ -0,0 +1,119 @@
package club.joylink.rtss.simulation.cbtc.data.support;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public final class FixedQueue<E> implements Queue<E> {
private final int limit;
private final Queue<E> queue = new LinkedList<>();
public FixedQueue(int limit){
this.limit = limit;
}
@Override
public boolean offer(E e){
if(queue.size() >= limit){
//如果超出长度,入队时,先出队
queue.poll();
}
return queue.offer(e);
}
@Override
public E poll() {
return queue.poll();
}
public Queue<E> getQueue(){
return queue;
}
public int getLimit(){
return limit;
}
@Override
public boolean add(E e) {
return queue.add(e);
}
@Override
public E element() {
return queue.element();
}
@Override
public E peek() {
return queue.peek();
}
@Override
public boolean isEmpty() {
return queue.size() == 0 ? true : false;
}
@Override
public int size() {
return queue.size();
}
@Override
public E remove() {
return queue.remove();
}
@Override
public boolean addAll(Collection<? extends E> c) {
return queue.addAll(c);
}
@Override
public void clear() {
queue.clear();
}
@Override
public boolean contains(Object o) {
return queue.contains(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return queue.containsAll(c);
}
@Override
public Iterator<E> iterator() {
return queue.iterator();
}
@Override
public boolean remove(Object o) {
return queue.remove(o);
}
@Override
public boolean removeAll(Collection<?> c) {
return queue.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return queue.retainAll(c);
}
@Override
public Object[] toArray() {
return queue.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return queue.toArray(a);
}
}

View File

@ -2,11 +2,9 @@ package club.joylink.rtss.simulation.cbtc.data.vr;
import club.joylink.rtss.simulation.cbtc.constant.*;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.FixedQueue;
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
@ -16,6 +14,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
import java.util.Queue;
/**
* 虚拟真实列车
@ -358,6 +357,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
*/
private VirtualRealityTrain linkTrain;
/**最近经过的两个应答器*/
private Queue<Responder> lastTwoPassedResponders = new FixedQueue<>(2);
public void setAtpOn(boolean on) {
this.atpOn = on;
if (!on) { //如果是关闭ATP取消信号EB

View File

@ -159,29 +159,21 @@ public class MapSectionNewVO {
@ApiModelProperty(value = "区段路线类型")
private Section.SectionRoadType roadType;
// /**
// * 逻辑区段列表
// */
// @JsonIgnore
// @ApiModelProperty(value = "逻辑区段列表")
// List<MapSectionNewVO> logicList;
/**
* 道岔计轴区段关联道岔区段列表
*/
@ApiModelProperty(value = "道岔计轴区段关联道岔区段列表")
List<String> relevanceSectionList;
/**
* 岔心关联道岔区段列表
* 岔心关联计轴区段列表
*/
@ApiModelProperty(value = "岔心关联道岔区段列表")
@ApiModelProperty(value = "岔心关联计轴区段列表")
List<String> relateSectionList;
/**
* 是否站台轨
*/
@ApiModelProperty(value = "是否站台轨")
// @JsonProperty("isStandTrack")
private boolean standTrack;
/**

View File

@ -31,7 +31,7 @@ public class OrderDetailVO {
private Integer monthAmount;
private Float price;
private Long price;
public OrderDetailVO(SaleOrderDetail detail) {
id = detail.getId();
@ -41,7 +41,7 @@ public class OrderDetailVO {
startTime = detail.getStartTime();
goodsAmount = detail.getGoodsAmount();
monthAmount = detail.getMonthAmount();
price = (float) detail.getPrice() / 100;
price = detail.getPrice();
}
}