2
0

feat: add cdr schedule task

This commit is contained in:
caiyuchao
2024-12-10 11:07:17 +08:00
parent 95d4b02aad
commit b1848e3ab3
17 changed files with 277 additions and 30 deletions

View File

@@ -49,8 +49,8 @@ CREATE TABLE `u_cdr` (
`client_id` bigint(20) NULL DEFAULT NULL COMMENT 'Client ID',
`device_id` bigint(20) NULL DEFAULT NULL COMMENT 'Device ID',
`ssid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'Wireless SSID name ',
`rx_rate` int(11) NULL DEFAULT NULL COMMENT 'tx rate ',
`tx_rate` int(11) NULL DEFAULT NULL COMMENT 'tx rate',
`rx_rate` bigint(20) NULL DEFAULT NULL COMMENT 'tx rate ',
`tx_rate` bigint(20) NULL DEFAULT NULL COMMENT 'tx rate',
`down_packet` bigint(20) NULL DEFAULT NULL COMMENT 'Number of downstream packets.\n',
`up_packet` bigint(20) NULL DEFAULT NULL COMMENT 'Number of upstream packets. ',
`traffic_down` bigint(20) NULL DEFAULT NULL COMMENT 'Downstream traffic (Byte)',

View File

@@ -94,6 +94,11 @@ public interface OmadaClientApi {
method = RequestMethod.GET)
ResponseEntity<OperationResponseClientGridVoClientInfo> getGridActiveClients(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.name", required = false) String sortsName,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.mac", required = false) String sortsMac,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.ip", required = false) String sortsIp,@ApiParam(value = "Filter query parameters, support field wireless: true/false.") @Valid @RequestParam(value = "filters.wireless", required = false) String filtersWireless,@ApiParam(value = "Filter query parameters, support field radioId: 0: 2G, 1: 5G1, 2: 5G2, 3: 6G") @Valid @RequestParam(value = "filters.radioId", required = false) String filtersRadioId,@ApiParam(value = "Filter query parameters, support field ap mac") @Valid @RequestParam(value = "filters.apMac", required = false) String filtersApMac,@ApiParam(value = "Filter query parameters, support field switch mac") @Valid @RequestParam(value = "filters.switchMac", required = false) String filtersSwitchMac,@ApiParam(value = "Filter query parameters, support field gateway mac") @Valid @RequestParam(value = "filters.gatewayMac", required = false) String filtersGatewayMac,@ApiParam(value = "Fuzzy query parameters, support field clientName,clientMac,ip,channel,ssid,apName,apMac,switchMac,switchName,gatewayMac,gatewayName.") @Valid @RequestParam(value = "searchKey", required = false) String searchKey);
@RequestMapping(value = "/openapi/v1/${omada.omadac-id}/sites/{siteId}/clients",
produces = "*/*",
method = RequestMethod.GET)
ResponseEntity<OperationResponseClientGridVoClientInfo> getGridActiveClients(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize);
/**
* POST /openapi/v1/{omadacId}/sites/{siteId}/clients/{clientMac}/reconnect : Reconnect the client

View File

@@ -48,4 +48,9 @@ public interface OmadaClientInsightApi {
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoClientHistoryInfo> getGridPastConnections(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.lastSeen", required = false) String sortsLastSeen,@ApiParam(value = "Filter query parameters, support field time range: start timestamp (ms).") @Valid @RequestParam(value = "filters.timeStart", required = false) String filtersTimeStart,@ApiParam(value = "Filter query parameters, support field time range: end timestamp (ms).") @Valid @RequestParam(value = "filters.timeEnd", required = false) String filtersTimeEnd,@ApiParam(value = "Filter query parameters, support field guest: true/false.") @Valid @RequestParam(value = "filters.guest", required = false) String filtersGuest,@ApiParam(value = "Fuzzy query parameters, support field name,mac,ssid.") @Valid @RequestParam(value = "searchKey", required = false) String searchKey);
@RequestMapping(value = "/openapi/v1/${omada.omadac-id}/sites/{siteId}/insight/past-connection",
produces = "*/*",
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoClientHistoryInfo> getGridPastConnections(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize,@ApiParam(value = "Fuzzy query parameters, support field name,mac,ssid.") @Valid @RequestParam(value = "searchKey", required = false) String searchKey);
}

View File

@@ -406,6 +406,11 @@ public interface OmadaDeviceApi {
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoDeviceInfo> getDeviceList(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.name", required = false) String sortsName,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.status", required = false) String sortsStatus,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.ip", required = false) String sortsIp,@ApiParam(value = "Fuzzy query parameters, support field name,mac,ip") @Valid @RequestParam(value = "searchKey", required = false) String searchKey,@ApiParam(value = "Filter query parameters, support field tag name") @Valid @RequestParam(value = "filters.tag", required = false) String filtersTag);
@RequestMapping(value = "/openapi/v1/${omada.omadac-id}/sites/{siteId}/devices",
produces = "*/*",
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoDeviceInfo> getDeviceList(@ApiParam(value = "Site ID",required=true) @PathVariable("siteId") String siteId,@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize);
/**
* GET /openapi/v1/{omadacId}/sites/{siteId}/devices/{deviceMac}/latest-firmware-info : Get the latest firmware info of the device

View File

@@ -275,6 +275,11 @@ public interface OmadaSiteApi {
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoSiteSummaryInfo> getSiteList(@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize,@ApiParam(value = "Sort parameter may be one of asc or desc. Optional parameter. If it is not carried, it means it is not sorted by this field. When there are more than one, the first one takes effect") @Valid @RequestParam(value = "sorts.name", required = false) String sortsName,@ApiParam(value = "Fuzzy query parameters, support field name") @Valid @RequestParam(value = "searchKey", required = false) String searchKey,@ApiParam(value = "Filter query parameters, support field tag ID") @Valid @RequestParam(value = "filters.tag", required = false) String filtersTag,@ApiParam(value = "Filter query parameters, support field site type. 0: basic site; 1: pro site.") @Valid @RequestParam(value = "filters.type", required = false) String filtersType);
@RequestMapping(value = "/openapi/v1/${omada.omadac-id}/sites",
produces = "*/*",
method = RequestMethod.GET)
ResponseEntity<OperationResponseGridVoSiteSummaryInfo> getSiteList(@NotNull @ApiParam(value = "Start page number. Start from 1.", required = true) @Valid @RequestParam(value = "page", required = true) Integer page,@NotNull @ApiParam(value = "Number of entries per page. It should be within the range of 11000.", required = true) @Valid @RequestParam(value = "pageSize", required = true) Integer pageSize);
/**
* GET /openapi/v1/{omadacId}/sites/tags : Get site tag list

View File

@@ -56,4 +56,10 @@ public interface RemoteUUserService
*/
@PutMapping("/user/recordlogin")
public R<Boolean> recordUserLogin(@RequestBody UUser user, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 添加话单信息通过OmadaApi
*/
@GetMapping("/user/uCdr/addCdrInfo")
public R<Boolean> addCdrInfoByOmadaApi();
}

View File

@@ -48,6 +48,11 @@ public class RemoteUUserFallbackFactory implements FallbackFactory<RemoteUUserSe
{
return R.fail("记录用户登录信息失败:" + throwable.getMessage());
}
@Override
public R<Boolean> addCdrInfoByOmadaApi() {
return R.fail("添加话单信息失败:" + throwable.getMessage());
}
};
}
}

View File

@@ -71,6 +71,11 @@
<artifactId>wfc-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>org.wfc</groupId>
<artifactId>wfc-api-user</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1,25 @@
package org.wfc.job.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.wfc.user.api.RemoteUUserService;
/**
* @description: 话单信息任务
* @author: cyc
* @since: 2024-12-10
*/
@Slf4j
@Component("cdrInfoTask")
public class CdrInfoTask {
@Autowired
private RemoteUUserService remoteUUserService;
public void addCdrInfo() {
log.info("开始执行话单信息任务");
remoteUUserService.addCdrInfoByOmadaApi();
log.info("话单信息任务执行成功");
}
}

View File

@@ -1,7 +1,11 @@
package org.wfc.user.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.wfc.common.core.domain.R;
import org.wfc.user.service.IUCdrService;
/**
* <p>
@@ -15,4 +19,16 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user/uCdr")
public class UCdrController {
@Autowired
private IUCdrService cdrService;
/**
* 添加话单信息通过OmadaApi
*/
@GetMapping("/addCdrInfo")
public R<Boolean> addCdrInfoByOmadaApi() {
cdrService.addCdrInfoByOmadaApi();
return R.ok(true);
}
}

View File

@@ -2,8 +2,9 @@ package org.wfc.user.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.wfc.common.mybatis.domain.BaseData;
/**
@@ -14,8 +15,9 @@ import org.wfc.common.mybatis.domain.BaseData;
* @author cyc
* @since 2024-12-09
*/
@Getter
@Setter
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@TableName("u_cdr")
@Schema(name = "UCdr", description = "用户平台_用户话单表")
public class UCdr extends BaseData {
@@ -35,10 +37,10 @@ public class UCdr extends BaseData {
private String ssid;
@Schema(description = "tx rate ")
private Integer rxRate;
private Long rxRate;
@Schema(description = "tx rate")
private Integer txRate;
private Long txRate;
@Schema(description = "Number of downstream packets. ")
private Long downPacket;

View File

@@ -1,12 +1,13 @@
package org.wfc.user.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import org.wfc.common.mybatis.domain.BaseData;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.wfc.common.mybatis.domain.BaseData;
import java.util.Date;
/**
* <p>
@@ -16,8 +17,9 @@ import lombok.Setter;
* @author cyc
* @since 2024-12-09
*/
@Getter
@Setter
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@TableName("u_cdr_detail")
@Schema(name = "UCdrDetail", description = "用户平台_话单明细表")
public class UCdrDetail extends BaseData {

View File

@@ -2,8 +2,9 @@ package org.wfc.user.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.wfc.common.mybatis.domain.BaseData;
/**
@@ -14,8 +15,9 @@ import org.wfc.common.mybatis.domain.BaseData;
* @author cyc
* @since 2024-12-09
*/
@Getter
@Setter
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@TableName("u_client")
@Schema(name = "UClient", description = "用户平台_用户设备表")
public class UClient extends BaseData {

View File

@@ -1,11 +1,11 @@
package org.wfc.user.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import org.wfc.common.mybatis.domain.BaseData;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.wfc.common.mybatis.domain.BaseData;
/**
* <p>
@@ -15,8 +15,9 @@ import lombok.Setter;
* @author cyc
* @since 2024-12-09
*/
@Getter
@Setter
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@TableName("u_device")
@Schema(name = "UDevice", description = "用户平台_AP设备表")
public class UDevice extends BaseData {

View File

@@ -13,4 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface IUCdrService extends IService<UCdr> {
void addCdrInfoByOmadaApi();
}

View File

@@ -1,10 +1,35 @@
package org.wfc.user.service.impl;
import org.wfc.user.domain.UCdr;
import org.wfc.user.mapper.UCdrMapper;
import org.wfc.user.service.IUCdrService;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.wfc.omada.api.client.OmadaClientApi;
import org.wfc.omada.api.client.OmadaClientInsightApi;
import org.wfc.omada.api.client.model.ClientHistoryInfo;
import org.wfc.omada.api.client.model.ClientInfo;
import org.wfc.omada.api.client.model.OperationResponseClientGridVoClientInfo;
import org.wfc.omada.api.client.model.OperationResponseGridVoClientHistoryInfo;
import org.wfc.omada.api.device.OmadaDeviceApi;
import org.wfc.omada.api.device.model.DeviceInfo;
import org.wfc.omada.api.device.model.OperationResponseGridVoDeviceInfo;
import org.wfc.omada.api.organization.OmadaSiteApi;
import org.wfc.omada.api.organization.model.OperationResponseGridVoSiteSummaryInfo;
import org.wfc.omada.api.organization.model.SiteSummaryInfo;
import org.wfc.user.domain.UCdr;
import org.wfc.user.domain.UCdrDetail;
import org.wfc.user.domain.UClient;
import org.wfc.user.domain.UDevice;
import org.wfc.user.mapper.UCdrMapper;
import org.wfc.user.service.IUCdrDetailService;
import org.wfc.user.service.IUCdrService;
import org.wfc.user.service.IUClientService;
import org.wfc.user.service.IUDeviceService;
import java.util.Date;
import java.util.List;
/**
* <p>
@@ -17,4 +42,139 @@ import org.springframework.stereotype.Service;
@Service
public class UCdrServiceImpl extends ServiceImpl<UCdrMapper, UCdr> implements IUCdrService {
@Autowired
private OmadaSiteApi omadaSiteApi;
@Autowired
private OmadaDeviceApi omadaDeviceApi;
@Autowired
private OmadaClientApi omadaClientApi;
@Autowired
private OmadaClientInsightApi omadaClientInsightApi;
@Autowired
private IUDeviceService deviceService;
@Autowired
private IUClientService clientService;
@Autowired
private IUCdrDetailService cdrDetailService;
@Override
public void addCdrInfoByOmadaApi() {
ResponseEntity<OperationResponseGridVoSiteSummaryInfo> siteResp = omadaSiteApi.getSiteList(1, 1000);
if (ObjectUtil.isNull(siteResp.getBody())) {
return;
}
List<SiteSummaryInfo> sites = siteResp.getBody().getResult().getData();
// 添加AP设备
addDevices(sites);
for (SiteSummaryInfo site : sites) {
ResponseEntity<OperationResponseClientGridVoClientInfo> clientResp = omadaClientApi.getGridActiveClients(site.getSiteId(), 1, 1000);
if (ObjectUtil.isNull(clientResp.getBody())) {
continue;
}
List<ClientInfo> clients = clientResp.getBody().getResult().getData();
for (ClientInfo client : clients) {
// 添加用户设备
Long clientId = addClient(client);
// 添加话单
Long cdrId = addCdr(client, clientId);
// 添加话单明细
addCdrDetail(site, client, cdrId);
}
}
}
private void addCdrDetail(SiteSummaryInfo site, ClientInfo client, Long cdrId) {
// 话单明细
ResponseEntity<OperationResponseGridVoClientHistoryInfo> pastConnResp = omadaClientInsightApi.getGridPastConnections(site.getSiteId(), 1, 1000, client.getMac());
if (ObjectUtil.isNull(pastConnResp.getBody())) {
return;
}
List<ClientHistoryInfo> pastConns = pastConnResp.getBody().getResult().getData();
for (ClientHistoryInfo pastConn : pastConns) {
UCdrDetail uCdrDetail = cdrDetailService.getOne(Wrappers.<UCdrDetail>lambdaQuery().eq(UCdrDetail::getCdrId, cdrId).eq(UCdrDetail::getStartTime, pastConn.getFirstSeen()), false);
if (ObjectUtil.isNotNull(uCdrDetail)) {
continue;
}
UCdrDetail uCdrDetail1 = UCdrDetail.builder().cdrId(cdrId).startTime(new Date(pastConn.getFirstSeen()))
.endTime(new Date(pastConn.getLastSeen()))
.trafficUp(pastConn.getUpload())
.trafficDown(pastConn.getDownload())
.duration(pastConn.getDuration())
.build();
cdrDetailService.save(uCdrDetail1);
}
}
private Long addCdr(ClientInfo client, Long clientId) {
// 话单
UCdr hasUCdr = this.getOne(Wrappers.<UCdr>lambdaQuery().eq(UCdr::getClientId, clientId), false);
Long cdrId;
if (ObjectUtil.isNull(hasUCdr)) {
UDevice hasDevice = deviceService.getOne(Wrappers.<UDevice>lambdaQuery().eq(UDevice::getDeviceMac, client.getApMac()), false);
UCdr uCdr = UCdr.builder().clientId(clientId)
.deviceId(hasDevice.getId())
.ssid(client.getSsid())
.rxRate(client.getRxRate())
.txRate(client.getTxRate())
.lastSeenTime(client.getLastSeen())
.upTime(client.getUptime())
.upPacket(client.getUpPacket())
.downPacket(client.getDownPacket())
.trafficDown(client.getTrafficDown())
.trafficUp(client.getTrafficUp())
.build();
this.save(uCdr);
cdrId = uCdr.getId();
} else {
cdrId = hasUCdr.getId();
}
return cdrId;
}
private Long addClient(ClientInfo client) {
// 用户设备
UClient hasClient = clientService.getOne(Wrappers.<UClient>lambdaQuery().eq(UClient::getClientMac, client.getMac()), false);
Long clientId;
if (ObjectUtil.isNull(hasClient)) {
UClient uClient = UClient.builder().clientMac(client.getMac())
.clientName(client.getName())
.clientDeviceType(client.getDeviceType())
.build();
clientService.save(uClient);
clientId = uClient.getId();
} else {
clientId = hasClient.getId();
}
return clientId;
}
private void addDevices(List<SiteSummaryInfo> sites) {
// ap设备
for (SiteSummaryInfo site : sites) {
ResponseEntity<OperationResponseGridVoDeviceInfo> deviceResp = omadaDeviceApi.getDeviceList(site.getSiteId(), 1, 1000);
if (ObjectUtil.isNull(deviceResp.getBody())) {
return;
}
List<DeviceInfo> devices = deviceResp.getBody().getResult().getData();
for (DeviceInfo device : devices) {
UDevice hasUDevice = deviceService.getOne(Wrappers.<UDevice>lambdaQuery().eq(UDevice::getDeviceMac, device.getMac()), false);
if (ObjectUtil.isNotNull(hasUDevice)) {
continue;
}
UDevice uDevice = UDevice.builder().deviceIp(device.getIp())
.deviceMac(device.getMac())
.deviceName(device.getName())
.deviceModel(device.getModel())
.build();
deviceService.save(uDevice);
}
}
}
}

View File

@@ -3,7 +3,7 @@ package org.wfc.user;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.wfc.user.service.IUClientService;
import org.wfc.user.service.IUCdrService;
/**
* @description: 设备单元测试
@@ -14,10 +14,11 @@ import org.wfc.user.service.IUClientService;
public class UClientTest {
@Autowired
private IUClientService clientService;
private IUCdrService cdrService;
@Test
public void test() {
cdrService.test();
}
}