1. 移除所有mock支付逻辑,订单强制走微信支付
2. 卡状态流转改为单向:UNUSED->RESERVED->USED(终态不可复用)
3. 解绑接口改为仅清除device_id,卡状态保持USED
4. 新增设备端取消订单接口 POST /api/jst/daycard/cancel/{orderNo}
5. 修复微信回调验签header大小写问题
6. 临时注释分账标记(商户号未开通分账权限)
7. 删除多余的App UI辅助接口(ApiJstUiController)
8. 清理application.yml中无用UI配置
441 lines
19 KiB
Java
441 lines
19 KiB
Java
package io.as.modules.openapi.controller;
|
||
|
||
import io.as.common.annotation.AuditAction;
|
||
import io.as.common.exception.ASException;
|
||
import io.as.modules.daycard.constants.DayCardConstants;
|
||
import io.as.modules.daycard.entity.DayCardActivationCodeEntity;
|
||
import io.as.modules.daycard.entity.DayCardOrderEntity;
|
||
import io.as.modules.daycard.entity.DayCardPoolEntity;
|
||
import io.as.modules.daycard.entity.DayCardPriceConfigEntity;
|
||
import io.as.modules.daycard.service.DayCardActivationCodeService;
|
||
import io.as.modules.daycard.service.DayCardOrderService;
|
||
import io.as.modules.device.entity.DeviceEntity;
|
||
import io.as.modules.device.service.DeviceService;
|
||
import io.as.modules.openapi.filter.ApiDeviceSignFilter;
|
||
import io.as.modules.openapi.form.DeviceInitRequest;
|
||
import io.as.modules.openapi.sign.ApiDeviceSignService;
|
||
import io.as.modules.openapi.sign.DeviceSignResult;
|
||
import io.as.modules.sys.entity.SysOrgEntity;
|
||
import io.as.modules.sys.service.SysOrgService;
|
||
import io.swagger.annotations.Api;
|
||
import io.swagger.annotations.ApiImplicitParam;
|
||
import io.swagger.annotations.ApiImplicitParams;
|
||
import io.swagger.annotations.ApiOperation;
|
||
import io.swagger.annotations.ApiParam;
|
||
import org.apache.commons.lang.StringUtils;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import javax.servlet.http.HttpServletRequest;
|
||
import java.util.Date;
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 橘视听 API 设备接口(对齐生产环境 as-partner-backend 的 ApiJstController)
|
||
* <p>完整流程:</p>
|
||
* <ol>
|
||
* <li><b>init</b>:设备初始化(注册/更新),返回 sign</li>
|
||
* <li><b>checkBenefits</b>:查询天卡权益,返回 thirdCardNo 与 status(ACTIVE/UNBOUND)</li>
|
||
* <li>无权益 → <b>daycard/create</b> 创建天卡订单 → 支付 → 轮询 checkBenefits 拿 thirdCardNo</li>
|
||
* </ol>
|
||
* <p><b>鉴权</b>:除 POST /api/jst/init 外,均须在请求头携带 sign。缺少或无效 sign 由过滤器直接返回 HTTP 401。</p>
|
||
*/
|
||
@Api(tags = "橘视听-API-设备接口",
|
||
description = "除 POST /api/jst/init 外均需请求头 sign;缺/无效 sign→401。业务结果以 JSON 的 code 为准。")
|
||
@RestController
|
||
@RequestMapping("/api/jst")
|
||
public class ApiJstController {
|
||
|
||
private static final Logger logger = LoggerFactory.getLogger(ApiJstController.class);
|
||
|
||
@Autowired
|
||
private ApiDeviceSignService apiDeviceSignService;
|
||
|
||
@Autowired
|
||
private DeviceService deviceService;
|
||
|
||
@Autowired
|
||
private SysOrgService sysOrgService;
|
||
|
||
@Autowired
|
||
private DayCardOrderService dayCardOrderService;
|
||
|
||
@Autowired
|
||
private DayCardActivationCodeService dayCardActivationCodeService;
|
||
|
||
/**
|
||
* 设备初始化:校验设备是否在系统,不在则添加、在则更新,返回 sign
|
||
*/
|
||
@ApiOperation(value = "设备初始化",
|
||
notes = "本接口无需 sign。body 必传 activationCode(管理后台按门店生成的激活码);设备可传 mac、wifiMac、deviceSn、deviceUid 等。成功返回 data.device、sign。")
|
||
@AuditAction(value = "DEVICE_INIT", description = "设备初始化")
|
||
@PostMapping("/init")
|
||
public Map<String, Object> init(
|
||
@ApiParam(value = "设备初始化请求体", required = true)
|
||
@RequestBody DeviceInitRequest request) {
|
||
try {
|
||
return doInit(request);
|
||
} catch (ASException e) {
|
||
return rrExceptionResponse(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 设备权益状态:查询天卡权益,返回 thirdCardNo + status
|
||
* <p>status: ACTIVE(橘视厅激活成功且未过期,返回 thirdCardNo)/ ACTIVATING(激活中)/ ACTIVATION_FAILED(激活失败)/ UNBOUND(无天卡)</p>
|
||
*/
|
||
@ApiOperation(value = "设备权益状态",
|
||
notes = "请求头必传 sign。查询设备天卡权益,返回 data.status(ACTIVE/ACTIVATING/ACTIVATION_FAILED/UNBOUND)。仅 ACTIVE 时返回 data.thirdCardNo(播放凭证)和 data.expireAt。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名(用于标识设备)", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/checkBenefits")
|
||
public Map<String, Object> checkBenefits(HttpServletRequest request) {
|
||
Long deviceId = deviceIdFrom(request);
|
||
DayCardPoolEntity pool = dayCardOrderService.getDeviceBenefits(deviceId);
|
||
Map<String, Object> data = new HashMap<>();
|
||
if (pool == null) {
|
||
data.put("status", "UNBOUND");
|
||
} else if (DayCardConstants.ACTIVATE_STATUS_SUCCESS.equals(pool.getActivateStatus())) {
|
||
data.put("status", "ACTIVE");
|
||
data.put("thirdCardNo", pool.getThirdCardNo());
|
||
data.put("cardNo", pool.getCardCode());
|
||
data.put("expireAt", pool.getExpireAt());
|
||
} else if (DayCardConstants.ACTIVATE_STATUS_FAILED.equals(pool.getActivateStatus())) {
|
||
data.put("status", "ACTIVATION_FAILED");
|
||
data.put("activateError", pool.getActivateError());
|
||
} else {
|
||
// PENDING 或 null,激活中
|
||
data.put("status", "ACTIVATING");
|
||
}
|
||
return buildSuccessResponse(data);
|
||
}
|
||
|
||
/**
|
||
* 设备天卡价格:供前端二维码展示
|
||
* <p>按 3 层维度匹配当前设备生效价:门店配置价 > 渠道配置价 > 平台默认价</p>
|
||
*/
|
||
@ApiOperation(value = "设备天卡价格",
|
||
notes = "请求头必传 sign。返回 data.price(元)、data.priceFen(分)、data.name。未配置定价时 data.status=UNCONFIGURED。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/price")
|
||
public Map<String, Object> price(HttpServletRequest request) {
|
||
Long deviceId = deviceIdFrom(request);
|
||
DayCardPriceConfigEntity config = dayCardOrderService.getDevicePrice(deviceId);
|
||
Map<String, Object> data = new HashMap<>();
|
||
if (config == null) {
|
||
data.put("status", "UNCONFIGURED");
|
||
} else {
|
||
data.put("status", "OK");
|
||
data.put("price", config.getPrice());
|
||
data.put("priceFen", config.getPrice().multiply(new java.math.BigDecimal("100")).intValue());
|
||
data.put("name", config.getName());
|
||
}
|
||
return buildSuccessResponse(data);
|
||
}
|
||
|
||
/**
|
||
* 创建天卡订单(无权益时调用)
|
||
*/
|
||
@ApiOperation(value = "创建天卡订单",
|
||
notes = "请求头必传 sign。从 sign 解析 deviceId,无需传设备标识。返回 data.orderNo、data.status、data.amount(分)、data.codeUrl、data.expireAt。")
|
||
@AuditAction(value = "DAYCARD_ORDER_CREATE", description = "创建天卡订单(设备端)")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/daycard/create")
|
||
public Map<String, Object> createDayCard(HttpServletRequest request) {
|
||
try {
|
||
Long deviceId = deviceIdFrom(request);
|
||
DayCardOrderEntity order = dayCardOrderService.createOrder(deviceId);
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("orderNo", order.getOrderNo());
|
||
data.put("status", order.getStatus());
|
||
data.put("amount", order.getAmount().multiply(new java.math.BigDecimal("100")).intValue());
|
||
data.put("cardNo", order.getCardNo());
|
||
data.put("codeUrl", order.getCodeUrl());
|
||
data.put("expireAt", order.getExpireTime());
|
||
data.put("deviceId", order.getDeviceId());
|
||
return buildSuccessResponse(data);
|
||
} catch (ASException e) {
|
||
return rrExceptionResponse(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 查询支付状态
|
||
*/
|
||
@ApiOperation(value = "查询支付状态",
|
||
notes = "请求头必传 sign。路径参数为订单号,返回 data.status(CREATED/PAYING/PAID/CANCELLED)、data.codeUrl 等。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@GetMapping("/daycard/status/{orderNo}")
|
||
public Map<String, Object> daycardStatus(@PathVariable("orderNo") String orderNo) {
|
||
DayCardOrderEntity order = dayCardOrderService.getByOrderNo(orderNo);
|
||
if (order == null) {
|
||
Map<String, Object> err = new HashMap<>();
|
||
err.put("code", 404);
|
||
err.put("msg", "订单不存在");
|
||
err.put("data", new HashMap<>());
|
||
return err;
|
||
}
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("orderNo", order.getOrderNo());
|
||
data.put("status", order.getStatus());
|
||
data.put("paidAt", order.getPayTime());
|
||
data.put("codeUrl", order.getCodeUrl());
|
||
data.put("amount", order.getAmount() != null ? order.getAmount().multiply(new java.math.BigDecimal("100")).intValue() : 0);
|
||
data.put("payChannel", order.getPayChannel());
|
||
return buildSuccessResponse(data);
|
||
}
|
||
|
||
/**
|
||
* 取消天卡订单(用户放弃支付时调用)
|
||
*/
|
||
@ApiOperation(value = "取消天卡订单",
|
||
notes = "请求头必传 sign。用户取消支付时调用,取消订单并释放卡,允许设备重新下单。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/daycard/cancel/{orderNo}")
|
||
public Map<String, Object> cancelDayCard(@PathVariable("orderNo") String orderNo, HttpServletRequest request) {
|
||
try {
|
||
Long deviceId = deviceIdFrom(request);
|
||
dayCardOrderService.cancelOrder(orderNo, deviceId);
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("orderNo", orderNo);
|
||
data.put("status", "CANCELLED");
|
||
return buildSuccessResponse(data);
|
||
} catch (ASException e) {
|
||
return rrExceptionResponse(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 设备心跳:更新设备心跳时间,续期 sign
|
||
*/
|
||
@ApiOperation(value = "设备心跳",
|
||
notes = "请求头必传 sign。更新设备 last_heartbeat 并续期 sign 缓存 TTL。建议按业务间隔调用以防 sign 过期。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/heartBeat")
|
||
public Map<String, Object> heartBeat(HttpServletRequest request) {
|
||
Long deviceId = deviceIdFrom(request);
|
||
DeviceEntity device = deviceService.getById(deviceId);
|
||
if (device != null) {
|
||
device.setLastHeartbeat(new Date());
|
||
deviceService.updateDevice(device);
|
||
}
|
||
apiDeviceSignService.refreshExpire(deviceId);
|
||
return buildSuccessResponse(new HashMap<>());
|
||
}
|
||
|
||
/**
|
||
* 刷新 sign:换新 sign,旧 sign 立即失效
|
||
*/
|
||
@ApiOperation(value = "刷新 sign",
|
||
notes = "请求头必传当前有效 sign。成功后在 data 中返回新 sign;旧 sign 立即失效,客户端必须替换本地存储。")
|
||
@ApiImplicitParams({
|
||
@ApiImplicitParam(name = "sign", value = "设备签名(旧的即将过期 sign)", required = true, paramType = "header", dataType = "string")
|
||
})
|
||
@PostMapping("/refreshSign")
|
||
public Map<String, Object> refreshSign(HttpServletRequest request) {
|
||
Long deviceId = deviceIdFrom(request);
|
||
String orgCode = channelOrgCodeFrom(request);
|
||
String newSign = apiDeviceSignService.generate(deviceId, System.currentTimeMillis(), orgCode);
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("sign", newSign);
|
||
return buildSuccessResponse(data);
|
||
}
|
||
|
||
// ==================== 内部方法 ====================
|
||
|
||
private Map<String, Object> doInit(DeviceInitRequest request) {
|
||
if (request == null) {
|
||
throw new ASException("请求体不能为空", 400);
|
||
}
|
||
String activationCode = trim(request.getActivationCode());
|
||
if (StringUtils.isBlank(activationCode)) {
|
||
// 代销模式:免activationCode,按设备标识查找已注册设备(由partner消耗天卡接口创建)
|
||
return doInitWithoutActivationCode(request);
|
||
}
|
||
|
||
// 通过激活码解析门店与渠道
|
||
DayCardActivationCodeEntity codeEntity = dayCardActivationCodeService.getByCode(activationCode);
|
||
if (codeEntity == null) {
|
||
throw new ASException("激活码无效或已禁用", 400);
|
||
}
|
||
Long storeOrgId = codeEntity.getStoreOrgId();
|
||
Long channelOrgId = codeEntity.getChannelOrgId();
|
||
if (storeOrgId == null) {
|
||
throw new ASException("激活码未绑定门店", 400);
|
||
}
|
||
|
||
// 校验门店存在
|
||
SysOrgEntity storeOrg = sysOrgService.getById(storeOrgId);
|
||
if (storeOrg == null) {
|
||
throw new ASException("门店不存在", 400);
|
||
}
|
||
|
||
// 校验设备数上限
|
||
if (codeEntity.getMaxDeviceCount() != null && codeEntity.getMaxDeviceCount() > 0) {
|
||
int activated = codeEntity.getActivatedCount() != null ? codeEntity.getActivatedCount() : 0;
|
||
if (activated >= codeEntity.getMaxDeviceCount()) {
|
||
throw new ASException("该激活码已达设备上限(" + codeEntity.getMaxDeviceCount() + "台)", 400);
|
||
}
|
||
}
|
||
|
||
String androidId = trim(request.getAndroidId());
|
||
String mac = trim(request.getMac());
|
||
String wifiMac = trim(request.getWifiMac());
|
||
String deviceSn = trim(request.getDeviceSn());
|
||
String deviceUid = trim(request.getDeviceUid());
|
||
|
||
// 查找或创建设备(按优先级降权匹配:androidId > mac > deviceSn > wifiMac > deviceUid)
|
||
DeviceEntity device = findOrCreateDevice(androidId, mac, wifiMac, deviceSn, deviceUid);
|
||
boolean isNewDevice = device.getId() == null;
|
||
Date now = new Date();
|
||
device.setStoreOrgId(storeOrgId);
|
||
// 仅用非空标识更新,避免覆盖已有标识(按文档"更新缺失的标识字段")
|
||
if (StringUtils.isNotBlank(androidId)) device.setAndroidId(androidId);
|
||
if (StringUtils.isNotBlank(mac)) device.setMac(mac);
|
||
if (StringUtils.isNotBlank(wifiMac)) device.setWifiMac(wifiMac);
|
||
if (StringUtils.isNotBlank(deviceSn)) device.setDeviceSn(deviceSn);
|
||
if (StringUtils.isNotBlank(deviceUid)) device.setDeviceUid(deviceUid);
|
||
if (StringUtils.isNotBlank(request.getManufacturer())) device.setManufacturer(trim(request.getManufacturer()));
|
||
if (StringUtils.isNotBlank(request.getModel())) device.setModel(trim(request.getModel()));
|
||
if (StringUtils.isNotBlank(request.getBrand())) device.setBrand(trim(request.getBrand()));
|
||
if (StringUtils.isNotBlank(request.getVerCode())) device.setVerCode(trim(request.getVerCode()));
|
||
if (StringUtils.isNotBlank(request.getVerName())) device.setVerName(trim(request.getVerName()));
|
||
if (StringUtils.isNotBlank(request.getAndroidVersion())) device.setAndroidVersion(trim(request.getAndroidVersion()));
|
||
if (StringUtils.isNotBlank(request.getDeviceModel())) device.setDeviceModel(trim(request.getDeviceModel()));
|
||
if (StringUtils.isNotBlank(request.getDeviceName())) device.setDeviceName(trim(request.getDeviceName()));
|
||
device.setLastHeartbeat(now);
|
||
if (isNewDevice) {
|
||
device.setCreatedAt(now);
|
||
device.setDeleteFlag("UNDEL");
|
||
device.setStatus("ACTIVE");
|
||
deviceService.saveDevice(device);
|
||
// 新设备激活计数 +1
|
||
dayCardActivationCodeService.incrementActivatedCount(codeEntity.getId());
|
||
} else {
|
||
device.setUpdatedAt(now);
|
||
deviceService.updateDevice(device);
|
||
}
|
||
|
||
// 生成 sign(orgCode 用渠道组织ID的字符串形式,sign 校验时不依赖此值)
|
||
String orgCode = channelOrgId != null ? String.valueOf(channelOrgId) : "";
|
||
String sign = apiDeviceSignService.generate(device.getId(), System.currentTimeMillis(), orgCode);
|
||
|
||
Map<String, Object> data = new HashMap<>();
|
||
Map<String, Object> deviceInfo = new HashMap<>();
|
||
deviceInfo.put("deviceId", device.getId());
|
||
deviceInfo.put("roomNo", device.getRoomNo());
|
||
data.put("device", deviceInfo);
|
||
data.put("sign", sign);
|
||
return buildSuccessResponse(data);
|
||
}
|
||
|
||
/**
|
||
* 代销模式免activationCode初始化:按设备标识查找已注册设备,返回sign
|
||
* <p>设备由 /openapi/partner/card/consume 接口创建,APK用同一设备标识调本方法拿sign</p>
|
||
*/
|
||
private Map<String, Object> doInitWithoutActivationCode(DeviceInitRequest request) {
|
||
String mac = trim(request.getMac());
|
||
String wifiMac = trim(request.getWifiMac());
|
||
String deviceSn = trim(request.getDeviceSn());
|
||
String deviceUid = trim(request.getDeviceUid());
|
||
if (StringUtils.isBlank(mac) && StringUtils.isBlank(wifiMac)
|
||
&& StringUtils.isBlank(deviceSn) && StringUtils.isBlank(deviceUid)) {
|
||
throw new ASException("代销模式免激活码,需至少传一个设备标识(mac/wifiMac/deviceSn/deviceUid)", 400);
|
||
}
|
||
// 按优先级查找已有设备:mac > wifiMac > deviceSn > deviceUid(与生产环境一致)
|
||
DeviceEntity device = findByIdentifier(mac, DeviceEntity::getMac);
|
||
if (device == null) device = findByIdentifier(wifiMac, DeviceEntity::getWifiMac);
|
||
if (device == null) device = findByIdentifier(deviceSn, DeviceEntity::getDeviceSn);
|
||
if (device == null) device = findByIdentifier(deviceUid, DeviceEntity::getDeviceUid);
|
||
if (device == null) {
|
||
throw new ASException("设备未注册,请先通过合作伙伴天卡消耗接口激活设备", 400);
|
||
}
|
||
// 更新心跳
|
||
device.setLastHeartbeat(new Date());
|
||
deviceService.updateDevice(device);
|
||
// 生成sign(orgCode留空,代销模式不依赖渠道组织)
|
||
String sign = apiDeviceSignService.generate(device.getId(), System.currentTimeMillis(), "");
|
||
Map<String, Object> data = new HashMap<>();
|
||
Map<String, Object> deviceInfo = new HashMap<>();
|
||
deviceInfo.put("deviceId", device.getId());
|
||
deviceInfo.put("roomNo", device.getRoomNo());
|
||
data.put("device", deviceInfo);
|
||
Map<String, Object> result = buildSuccessResponse(data);
|
||
result.put("sign", sign);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 查找或创建设备:按 mac 优先查找,无则新建
|
||
* <p>注:此处为简化实现,完整的多策略识别算法在 DeviceResolveService 中</p>
|
||
*/
|
||
private DeviceEntity findOrCreateDevice(String androidId, String mac, String wifiMac, String deviceSn, String deviceUid) {
|
||
if (StringUtils.isBlank(androidId) && StringUtils.isBlank(mac)
|
||
&& StringUtils.isBlank(wifiMac) && StringUtils.isBlank(deviceSn)
|
||
&& StringUtils.isBlank(deviceUid)) {
|
||
throw new ASException("androidId、mac、wifiMac、deviceSn、deviceUid 至少传一个", 400);
|
||
}
|
||
// 按优先级降权匹配:androidId > mac > deviceSn > wifiMac > deviceUid
|
||
DeviceEntity existing = findByIdentifier(androidId, DeviceEntity::getAndroidId);
|
||
if (existing == null) existing = findByIdentifier(mac, DeviceEntity::getMac);
|
||
if (existing == null) existing = findByIdentifier(deviceSn, DeviceEntity::getDeviceSn);
|
||
if (existing == null) existing = findByIdentifier(wifiMac, DeviceEntity::getWifiMac);
|
||
if (existing == null) existing = findByIdentifier(deviceUid, DeviceEntity::getDeviceUid);
|
||
return existing != null ? existing : new DeviceEntity();
|
||
}
|
||
|
||
private DeviceEntity findByIdentifier(String value, com.baomidou.mybatisplus.core.toolkit.support.SFunction<DeviceEntity, ?> column) {
|
||
if (StringUtils.isBlank(value)) {
|
||
return null;
|
||
}
|
||
return deviceService.lambdaQuery()
|
||
.eq(column, value)
|
||
.eq(DeviceEntity::getDeleteFlag, "UNDEL")
|
||
.last("LIMIT 1").one();
|
||
}
|
||
|
||
private static Long deviceIdFrom(HttpServletRequest request) {
|
||
return (Long) request.getAttribute(ApiDeviceSignFilter.REQUEST_ATTR_DEVICE_ID);
|
||
}
|
||
|
||
private static String channelOrgCodeFrom(HttpServletRequest request) {
|
||
DeviceSignResult signResult =
|
||
(DeviceSignResult) request.getAttribute(ApiDeviceSignFilter.REQUEST_ATTR_DEVICE_SIGN_RESULT);
|
||
return signResult != null ? signResult.getOrgCode() : null;
|
||
}
|
||
|
||
private static String trim(String s) {
|
||
return s == null ? null : s.trim();
|
||
}
|
||
|
||
private static Map<String, Object> buildSuccessResponse(Map<String, Object> data) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
result.put("code", 0);
|
||
result.put("msg", "success");
|
||
result.put("data", data != null ? data : new HashMap<>());
|
||
return result;
|
||
}
|
||
|
||
private static Map<String, Object> rrExceptionResponse(ASException e) {
|
||
Map<String, Object> err = new HashMap<>();
|
||
err.put("code", e.getCode());
|
||
err.put("msg", e.getMessage());
|
||
err.put("data", new HashMap<>());
|
||
return err;
|
||
}
|
||
}
|