Merge branch 'pre' of http://139.159.177.244:3000/hurui/hai-server into pre
commit
7b11f5d1ef
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,191 @@ |
|||||||
|
package com.hai.model; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class SelfOilStationModel { |
||||||
|
/** |
||||||
|
* 订单流水号 |
||||||
|
*/ |
||||||
|
private String orderNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 油站名称 |
||||||
|
*/ |
||||||
|
private String oilStationName; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】加油员名称 |
||||||
|
*/ |
||||||
|
private String gasStaffName; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】油品类型 1:汽油:2:柴油;3:天然气 |
||||||
|
*/ |
||||||
|
private Integer gasOilType; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】油号 |
||||||
|
*/ |
||||||
|
private String gasOilNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】油抢号 |
||||||
|
*/ |
||||||
|
private String gasGunNo; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】国标价 |
||||||
|
*/ |
||||||
|
private BigDecimal gasPriceOfficial; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】油枪价 |
||||||
|
*/ |
||||||
|
private BigDecimal gasPriceGun; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】加油升数 |
||||||
|
*/ |
||||||
|
private BigDecimal gasOilLiters; |
||||||
|
|
||||||
|
/** |
||||||
|
* 【加油站】加油金额 |
||||||
|
*/ |
||||||
|
private BigDecimal gasPrice; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 用户电话 |
||||||
|
*/ |
||||||
|
private String userPhone; |
||||||
|
|
||||||
|
/** |
||||||
|
* 支付时间 |
||||||
|
*/ |
||||||
|
private Date payTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 生成时间 |
||||||
|
*/ |
||||||
|
private Date createTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 订单状态:1 待支付 2 已支付 3.已完成 4. 已退款 5.已取消 6.退款中 7.拒绝退款 |
||||||
|
*/ |
||||||
|
private Integer orderStatus; |
||||||
|
|
||||||
|
|
||||||
|
public String getOrderNo() { |
||||||
|
return orderNo; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOrderNo(String orderNo) { |
||||||
|
this.orderNo = orderNo; |
||||||
|
} |
||||||
|
|
||||||
|
public String getOilStationName() { |
||||||
|
return oilStationName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOilStationName(String oilStationName) { |
||||||
|
this.oilStationName = oilStationName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getGasStaffName() { |
||||||
|
return gasStaffName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasStaffName(String gasStaffName) { |
||||||
|
this.gasStaffName = gasStaffName; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getGasOilType() { |
||||||
|
return gasOilType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasOilType(Integer gasOilType) { |
||||||
|
this.gasOilType = gasOilType; |
||||||
|
} |
||||||
|
|
||||||
|
public String getGasOilNo() { |
||||||
|
return gasOilNo; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasOilNo(String gasOilNo) { |
||||||
|
this.gasOilNo = gasOilNo; |
||||||
|
} |
||||||
|
|
||||||
|
public String getGasGunNo() { |
||||||
|
return gasGunNo; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasGunNo(String gasGunNo) { |
||||||
|
this.gasGunNo = gasGunNo; |
||||||
|
} |
||||||
|
|
||||||
|
public BigDecimal getGasPriceOfficial() { |
||||||
|
return gasPriceOfficial; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasPriceOfficial(BigDecimal gasPriceOfficial) { |
||||||
|
this.gasPriceOfficial = gasPriceOfficial; |
||||||
|
} |
||||||
|
|
||||||
|
public BigDecimal getGasPriceGun() { |
||||||
|
return gasPriceGun; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasPriceGun(BigDecimal gasPriceGun) { |
||||||
|
this.gasPriceGun = gasPriceGun; |
||||||
|
} |
||||||
|
|
||||||
|
public BigDecimal getGasOilLiters() { |
||||||
|
return gasOilLiters; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasOilLiters(BigDecimal gasOilLiters) { |
||||||
|
this.gasOilLiters = gasOilLiters; |
||||||
|
} |
||||||
|
|
||||||
|
public BigDecimal getGasPrice() { |
||||||
|
return gasPrice; |
||||||
|
} |
||||||
|
|
||||||
|
public void setGasPrice(BigDecimal gasPrice) { |
||||||
|
this.gasPrice = gasPrice; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserPhone() { |
||||||
|
return userPhone; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserPhone(String userPhone) { |
||||||
|
this.userPhone = userPhone; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getPayTime() { |
||||||
|
return payTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPayTime(Date payTime) { |
||||||
|
this.payTime = payTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getCreateTime() { |
||||||
|
return createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) { |
||||||
|
this.createTime = createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getOrderStatus() { |
||||||
|
return orderStatus; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOrderStatus(Integer orderStatus) { |
||||||
|
this.orderStatus = orderStatus; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.v1.config; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* @serviceName ToolConfig.java |
||||||
|
* @author Sum1Dream |
||||||
|
* @version 1.0.0 |
||||||
|
* @Description // 对外接口 方法类
|
||||||
|
* @createTime 10:03 2022/7/26 |
||||||
|
**/ |
||||||
|
public class ToolConfig { |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author Sum1Dream |
||||||
|
* @name timetableCheck.java |
||||||
|
* @Description // 时间戳校验
|
||||||
|
* @Date 10:08 2022/7/26 |
||||||
|
* @Param [java.lang.Long, java.lang.Long] |
||||||
|
* @return java.lang.Boolean |
||||||
|
*/ |
||||||
|
public static Boolean timetableCheck(Long minNum , Long timetable) { |
||||||
|
|
||||||
|
long nd = 1000 * 24 * 60 * 60; |
||||||
|
long nh = 1000 * 60 * 60; |
||||||
|
long nm = 1000 * 60; |
||||||
|
|
||||||
|
// 获得两个时间的毫秒时间差异
|
||||||
|
long diff = new Date().getTime() - timetable; |
||||||
|
|
||||||
|
// 计算差多少分钟
|
||||||
|
long min = diff % nd % nh / nm; |
||||||
|
|
||||||
|
return min <= minNum; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,175 @@ |
|||||||
|
package com.v1.controller; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hai.common.exception.ErrorCode; |
||||||
|
import com.hai.common.exception.ErrorHelp; |
||||||
|
import com.hai.common.exception.SysCode; |
||||||
|
import com.hai.common.utils.ResponseMsgUtil; |
||||||
|
import com.hai.entity.ApiMerchants; |
||||||
|
import com.hai.model.ResponseData; |
||||||
|
import com.hai.service.*; |
||||||
|
import com.v1.config.ToolConfig; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
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.ResponseBody; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @serviceName rechargeProductController.java |
||||||
|
* @author Sum1Dream |
||||||
|
* @version 1.0.0 |
||||||
|
* @Description // 充值产品接口
|
||||||
|
* @createTime 17:14 2022/6/9 |
||||||
|
**/ |
||||||
|
@Controller |
||||||
|
@RequestMapping(value = "/order") |
||||||
|
@Api(value = "订单") |
||||||
|
public class HighOrderController { |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(HighOrderController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private ApiMerchantsService apiMerchantsService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private SecConfigService secConfigService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private OutRechargeOrderService outRechargeOrderService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private HighOrderService highOrderService; |
||||||
|
|
||||||
|
@RequestMapping(value = "/getCallOrderList", method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "获取话费订单列表") |
||||||
|
public ResponseData getCallOrderList(@RequestBody JSONObject object , HttpServletRequest request ) { |
||||||
|
try { |
||||||
|
|
||||||
|
String ip = ""; |
||||||
|
// 有的user可能使用代理,为处理用户使用代理的情况,使用x-forwarded-for
|
||||||
|
if (request.getHeader("x-forwarded-for") == null) { |
||||||
|
ip = request.getRemoteAddr(); |
||||||
|
} else { |
||||||
|
ip = request.getHeader("x-forwarded-for"); |
||||||
|
} |
||||||
|
|
||||||
|
if (!secConfigService.isConfig("IP_WHITE" , ip)) { |
||||||
|
log.error("getRechargeProduct error!", "非法ip地址,请联系管理人员!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.IP_ERROR, "非法ip地址,请联系管理人员!"); |
||||||
|
} |
||||||
|
|
||||||
|
if (StringUtils.isBlank(object.getString("apiKey")) || |
||||||
|
StringUtils.isBlank(object.getString("merchId")) || |
||||||
|
StringUtils.isBlank(object.getString("timetable")) || |
||||||
|
StringUtils.isBlank(object.getString("sign")) |
||||||
|
) { |
||||||
|
log.error("getRechargeProduct error!", "请求参数校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR); |
||||||
|
} |
||||||
|
|
||||||
|
ApiMerchants apiMerchants = apiMerchantsService.findByMchId(object.getString("merchId")); |
||||||
|
|
||||||
|
if (apiMerchants == null) { |
||||||
|
log.error("getRechargeProduct error!", "商户号错误!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.ACCOUNT_NOT_EXIST); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String , Object> map = new HashMap<>(); |
||||||
|
map.put("apiKey" , object.getString("apiKey")); |
||||||
|
map.put("timetable" , object.getString("timetable")); |
||||||
|
map.put("merchId" , object.getString("merchId")); |
||||||
|
|
||||||
|
if (!secConfigService.isSignVerify(map , object.getString("sign"))) { |
||||||
|
log.error("getRechargeProduct error!", "签名校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
if (!ToolConfig.timetableCheck(15L , object.getLong("timetable"))) { |
||||||
|
log.error("getRechargeProduct error!", "请求时间超过15分钟!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String, Object> postMap = new HashMap<>(); |
||||||
|
postMap.put("merchId" , object.getString("merchId")); |
||||||
|
|
||||||
|
return ResponseMsgUtil.success(outRechargeOrderService.getListRechargeOrder(postMap)); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("HighOpenApiController --> getRechargeProduct() error!", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value = "/getOrderList", method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "获取订单列表") |
||||||
|
public ResponseData getOrderList(@RequestBody JSONObject object , HttpServletRequest request ) { |
||||||
|
try { |
||||||
|
|
||||||
|
String ip = ""; |
||||||
|
// 有的user可能使用代理,为处理用户使用代理的情况,使用x-forwarded-for
|
||||||
|
if (request.getHeader("x-forwarded-for") == null) { |
||||||
|
ip = request.getRemoteAddr(); |
||||||
|
} else { |
||||||
|
ip = request.getHeader("x-forwarded-for"); |
||||||
|
} |
||||||
|
|
||||||
|
if (!secConfigService.isConfig("IP_WHITE" , ip)) { |
||||||
|
log.error("getRechargeProduct error!", "非法ip地址,请联系管理人员!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.IP_ERROR, "非法ip地址,请联系管理人员!"); |
||||||
|
} |
||||||
|
|
||||||
|
if (StringUtils.isBlank(object.getString("apiKey")) || |
||||||
|
StringUtils.isBlank(object.getString("merchId")) || |
||||||
|
StringUtils.isBlank(object.getString("timetable")) || |
||||||
|
StringUtils.isBlank(object.getString("sign")) |
||||||
|
) { |
||||||
|
log.error("getRechargeProduct error!", "请求参数校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR); |
||||||
|
} |
||||||
|
|
||||||
|
ApiMerchants apiMerchants = apiMerchantsService.findByMchId(object.getString("merchId")); |
||||||
|
|
||||||
|
if (apiMerchants == null) { |
||||||
|
log.error("getRechargeProduct error!", "商户号错误!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.ACCOUNT_NOT_EXIST); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String , Object> map = new HashMap<>(); |
||||||
|
map.put("apiKey" , object.getString("apiKey")); |
||||||
|
map.put("timetable" , object.getString("timetable")); |
||||||
|
map.put("merchId" , object.getString("merchId")); |
||||||
|
|
||||||
|
if (!secConfigService.isSignVerify(map , object.getString("sign"))) { |
||||||
|
log.error("getRechargeProduct error!", "签名校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
if (!ToolConfig.timetableCheck(15L , object.getLong("timetable"))) { |
||||||
|
log.error("getRechargeProduct error!", "请求时间超过15分钟!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String, Object> postMap = new HashMap<>(); |
||||||
|
postMap.put("merchId" , object.getString("merchId")); |
||||||
|
|
||||||
|
return ResponseMsgUtil.success(highOrderService.getOrderList(postMap)); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("HighOpenApiController --> getRechargeProduct() error!", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
package com.v1.controller; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hai.common.exception.ErrorCode; |
||||||
|
import com.hai.common.exception.ErrorHelp; |
||||||
|
import com.hai.common.exception.SysCode; |
||||||
|
import com.hai.common.utils.ResponseMsgUtil; |
||||||
|
import com.hai.entity.ApiMerchants; |
||||||
|
import com.hai.entity.HighOrder; |
||||||
|
import com.hai.entity.SecConfig; |
||||||
|
import com.hai.model.ResponseData; |
||||||
|
import com.hai.model.SelfOilStationModel; |
||||||
|
import com.hai.service.*; |
||||||
|
import com.v1.config.ToolConfig; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
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.ResponseBody; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(value = "/selfOilStation") |
||||||
|
@Api(value = "自建站接口") |
||||||
|
public class SelfOilStationController { |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(SelfOilStationController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private ApiMerchantsService apiMerchantsService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private SecConfigService secConfigService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private HighOrderService highOrderService; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping(value = "/getSelfOilStationOrderList", method = RequestMethod.POST) |
||||||
|
@ResponseBody |
||||||
|
@ApiOperation(value = "获取自建站订单") |
||||||
|
public ResponseData getSelfOilStationOrderList(@RequestBody JSONObject object , HttpServletRequest request ) { |
||||||
|
try { |
||||||
|
|
||||||
|
String ip = ""; |
||||||
|
// 有的user可能使用代理,为处理用户使用代理的情况,使用x-forwarded-for
|
||||||
|
if (request.getHeader("x-forwarded-for") == null) { |
||||||
|
ip = request.getRemoteAddr(); |
||||||
|
} else { |
||||||
|
ip = request.getHeader("x-forwarded-for"); |
||||||
|
} |
||||||
|
|
||||||
|
if (!secConfigService.isConfig("IP_WHITE" , ip)) { |
||||||
|
log.error("getRechargeProduct error!", "非法ip地址,请联系管理人员!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.IP_ERROR, "非法ip地址,请联系管理人员!"); |
||||||
|
} |
||||||
|
|
||||||
|
if (StringUtils.isBlank(object.getString("apiKey")) || |
||||||
|
StringUtils.isBlank(object.getString("timetable")) || |
||||||
|
StringUtils.isBlank(object.getString("merchId")) || |
||||||
|
StringUtils.isBlank(object.getString("sign")) |
||||||
|
) { |
||||||
|
log.error("getRechargeProduct error!", "请求参数校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR); |
||||||
|
} |
||||||
|
|
||||||
|
ApiMerchants apiMerchants = apiMerchantsService.findByMchId(object.getString("merchId")); |
||||||
|
|
||||||
|
if (apiMerchants == null) { |
||||||
|
log.error("getRechargeProduct error!", "错误商户,请联系管理人员!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.ACCOUNT_NOT_EXIST); |
||||||
|
} |
||||||
|
|
||||||
|
Map<String , Object> map = new HashMap<>(); |
||||||
|
map.put("timetable" , object.getString("timetable")); |
||||||
|
map.put("apiKey" , object.getString("apiKey")); |
||||||
|
map.put("merchId" , object.getString("merchId")); |
||||||
|
|
||||||
|
if (!secConfigService.isSignVerify(map , object.getString("sign"))) { |
||||||
|
log.error("getRechargeProduct error!", "签名校验失败!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
if (!secConfigService.isConfig("SELF_OIL_STATION_CONFIG" , object.getString("merchId"))) { |
||||||
|
log.error("getAllCities error!", "当前帐户无权限!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.MERCHANT_NOT_AUTHORIZED, "当前帐户无权限!"); |
||||||
|
} |
||||||
|
|
||||||
|
if (!ToolConfig.timetableCheck(15L , object.getLong("timetable"))) { |
||||||
|
log.error("getRechargeProduct error!", "请求时间超过15分钟!"); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.SIGN_VERIFY); |
||||||
|
} |
||||||
|
|
||||||
|
SecConfig config = secConfigService.findByCodeType(object.getString("merchId")); |
||||||
|
|
||||||
|
return ResponseMsgUtil.success(highOrderService.getSelfOilStationOrderList(config.getCodeValue())); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("HighOpenApiController --> getRechargeProduct() error!", e); |
||||||
|
return ResponseMsgUtil.exception(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue