1.增加okhttpclient交于spring

2.bug修改
3.增加hik3d判断是否空
4.增加康耐视
5.dict交于redis
master
LAPTOP-S9HJSOEB\昊天 10 months ago
parent b1b4d0018b
commit 9496586193

@ -30,11 +30,14 @@
<!-- https://mvnrepository.com/artifact/com.sun.jna/jna -->
<dependency>
<groupId>com.sun.jna</groupId>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/libs/jna.jar</systemPath>
<version>5.13.0</version> <!-- 使用最新稳定版本 -->
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>

@ -27,8 +27,8 @@ import java.util.Objects;
public class MyInitializer {
private final OkHttpClient client = new OkHttpClient();
@Resource
private OkHttpClient client ;
@Resource
@ -43,6 +43,8 @@ public class MyInitializer {
myInitializer.checkAndAddRtspProxies();
}
@Scheduled(fixedRate = 30000) // 每分钟执行一次
public void checkAndAddRtspProxies() {

@ -1,144 +0,0 @@
package cn.iocoder.yudao.module.camera.controller.admin.cameraio;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.camera.controller.admin.cameraio.vo.CameraIoPageReqVO;
import cn.iocoder.yudao.module.camera.controller.admin.cameraio.vo.CameraIoRespVO;
import cn.iocoder.yudao.module.camera.controller.admin.cameraio.vo.CameraIoSaveReqVO;
import cn.iocoder.yudao.module.camera.dal.dataobject.camera.CameraDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.cameraio.CameraIoDO;
import cn.iocoder.yudao.module.camera.lib.camera.CameraModFactory;
import cn.iocoder.yudao.module.camera.service.camera.CameraService;
import cn.iocoder.yudao.module.camera.service.cameraio.CameraIoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 相机预置点位")
@RestController
@RequestMapping("/admin-api/camera/camera-io")
@Validated
public class CameraIoController {
@Resource
private CameraIoService cameraIoService;
@Resource
private CameraModFactory cameraModFactory;
@Resource
private CameraService cameraService;
@PostMapping("/create")
@Operation(summary = "创建相机预置点位")
@PreAuthorize("@ss.hasPermission('camera:camera-io:create')")
public CommonResult<Integer> createCameraIo(@Valid @RequestBody CameraIoSaveReqVO createReqVO) {
List<CameraIoDO> list = cameraIoService.list(new QueryWrapper<CameraIoDO>()
.eq("camera_id", createReqVO.getCameraId()));
Integer ptzId = list.stream().map(CameraIoDO::getPtzId).max(Integer::compareTo).orElse(0)+1;
createReqVO.setPtzId(ptzId);
int i= cameraIoService.createCameraIo(createReqVO);
CameraDO cameraIoDO = cameraService.getById(createReqVO.getCameraId());
cameraModFactory.get(cameraIoDO.getType()).ptz(createReqVO.getPtzId(),createReqVO.getName(),createReqVO.getCameraId());
return success(i);
}
@PostMapping("/callPtz")
@Operation(summary = "调用预置点位")
@PreAuthorize("@ss.hasPermission('camera:camera-io:callPtz')")
public CommonResult<Integer> callPtz(@Valid @RequestBody CameraIoSaveReqVO createReqVO) {
CameraDO cameraIoDO = cameraService.getById(createReqVO.getCameraId());
cameraModFactory.get(cameraIoDO.getType()).toPtz(createReqVO.getPtzId(),createReqVO.getCameraId());
return success(cameraIoService.createCameraIo(createReqVO));
}
/**
* 穿ptzId
* @param createReqVO
* @return
*/
@PostMapping("/overwritePtz")
@Operation(summary = "创建或覆盖相机预置点位")
@PreAuthorize("@ss.hasPermission('camera:camera-io:overwritePtz')")
public CommonResult<Integer> overwritePtz(@Valid @RequestBody CameraIoSaveReqVO createReqVO) {
CameraDO cameraIoDO = cameraService.getById(createReqVO.getCameraId());
cameraModFactory.get(cameraIoDO.getType()).ptz(createReqVO.getPtzId(),createReqVO.getName(),createReqVO.getCameraId());
return success(cameraIoService.createCameraIo(createReqVO));
}
@GetMapping("/list")
@Operation(summary = "获得相机预置点位分页")
@PreAuthorize("@ss.hasPermission('camera:camera-io:query')")
public CommonResult<List<CameraIoRespVO>> list(@Valid CameraIoPageReqVO pageReqVO) {
List<CameraIoDO> pageResult = cameraIoService.list(new QueryWrapper<CameraIoDO>().eq("camera_id", pageReqVO.getCameraId()).orderByAsc("id"));
return success(BeanUtils.toBean(pageResult, CameraIoRespVO.class));
}
@DeleteMapping("/delete")
@Operation(summary = "删除相机预置点位")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('camera:camera-io:delete')")
public CommonResult<Boolean> deleteCameraIo(@RequestParam("id") Integer id) {
cameraIoService.deleteCameraIo(id);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "更新相机预置点位")
@PreAuthorize("@ss.hasPermission('camera:camera-io:update')")
public CommonResult<Boolean> updateCameraIo(@Valid @RequestBody CameraIoSaveReqVO updateReqVO) {
cameraIoService.updateCameraIo(updateReqVO);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得相机预置点位")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('camera:camera-io:query')")
public CommonResult<CameraIoRespVO> getCameraIo(@RequestParam("id") Integer id) {
CameraIoDO cameraIo = cameraIoService.getCameraIo(id);
return success(BeanUtils.toBean(cameraIo, CameraIoRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得相机预置点位分页")
@PreAuthorize("@ss.hasPermission('camera:camera-io:query')")
public CommonResult<PageResult<CameraIoRespVO>> getCameraIoPage(@Valid CameraIoPageReqVO pageReqVO) {
PageResult<CameraIoDO> pageResult = cameraIoService.getCameraIoPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, CameraIoRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出相机预置点位 Excel")
@PreAuthorize("@ss.hasPermission('camera:camera-io:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportCameraIoExcel(@Valid CameraIoPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<CameraIoDO> list = cameraIoService.getCameraIoPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "相机预置点位.xls", "数据", CameraIoRespVO.class,
BeanUtils.toBean(list, CameraIoRespVO.class));
}
}

@ -24,6 +24,8 @@ public class CameraModFactory {
return hikControlModuleImpl; // 获取 HikControlModuleImpl 单例实例
} else if (type == 0) {
return dhControlModuleImpl; // 获取 DhControlModuleImpl 单例实例
}else if (type == 2) {
return dhControlModuleImpl; // 获取 DhControlModuleImpl 单例实例
}
// 默认返回 HikControlModuleImpl
return hikControlModuleImpl;

@ -7,9 +7,9 @@ public class CameraChannel {
public static String generateHikvisionRTSPUrl(String ip, int port, String channel, String username, String password) {
return String.format("rtsp://%s:%s@%s:%d/Streaming/channels/%s", username, password, ip, port, channel);
}
//默认主码流
public static String generateDahuaRTSPUrl(String ip, int port, String channel, String username, String password) {
return String.format("rtsp://%s:%s@%s:%d/cam/realmonitor?channel=%s", username, password, ip, port, channel);
return String.format("rtsp://%s:%s@%s:%d/cam/realmonitor?channel=%s&subtype=0", username, password, ip, port, channel);
}
public static String getRtspUrl(String ip, int port, String channel, String username, String password, int type) {
String rtspUrl = "";

@ -1,18 +0,0 @@
package cn.iocoder.yudao.module.camera.service.camera;
import cn.iocoder.yudao.module.camera.framework.netty.NettyClient;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
/**
* {@link CameraServiceImpl}
*
* @author
*/
@Import(NettyClient.class)
public class CameraServiceImplTest{
@Test
public void testCreateCamera_success() {
}
}

@ -35,11 +35,14 @@
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.jna/jna -->
<dependency>
<groupId>com.sun.jna</groupId>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/libs/jna.jar</systemPath>
<version>5.13.0</version> <!-- 使用最新稳定版本 -->
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.camera.config;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class OkHttpClientConfig {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(10, 3, TimeUnit.MINUTES))
// 可添加拦截器如日志、Token 添加等
// .addInterceptor(chain -> {
// Request request = chain.request().newBuilder()
// .addHeader("Authorization", "Bearer your_token")
// .build();
// return chain.proceed(request);
// })
.build();
}
}

@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.camera.controller.admin.Hik3D;
import cn.iocoder.yudao.module.camera.dal.entity.HikPythonEntity;
import cn.iocoder.yudao.module.camera.service.Hik3D.HikFlaskApiService;
import cn.iocoder.yudao.module.camera.service.checklog.CheckLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@Tag(name = "管理后台 - hik3D识别")
@RestController
@RequestMapping("/logistics/Hik3DController")
@Validated
public class Hik3DController {
@Resource
HikFlaskApiService hikFlaskApiService;
@Resource
private CheckLogService checkLogService;
@PostMapping("/updateConfig")
@Operation(summary = "updateConfig")
@ResponseBody
@PermitAll
public HikPythonEntity updateConfig(){
String baseUrl = "http://127.0.0.1:5000";
try {
return hikFlaskApiService.updateConfig(baseUrl);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@PostMapping("/addTemplate")
@Operation(summary = "updateConfig")
@ResponseBody
@PermitAll
public HikPythonEntity addTemplate(@RequestBody HikPythonEntity hikPythonEntity){
String baseUrl = "http://127.0.0.1:5000";
try {
return hikFlaskApiService.addTemplate(hikPythonEntity.getType(), hikPythonEntity,baseUrl);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@PostMapping("/picComputeAll")
@Operation(summary = "picComputeAll")
@ResponseBody
@PermitAll
public HikPythonEntity picComputeAll(@RequestBody HikPythonEntity hikPythonEntity){
String baseUrl = "http://127.0.0.1:5000";
try {
return hikFlaskApiService.picComputeAll(hikPythonEntity.getType(),baseUrl);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

@ -69,7 +69,7 @@ public class CameraIoController {
CameraDO cameraIoDO = cameraService.getById(createReqVO.getCameraId());
cameraModFactory.get(cameraIoDO.getType()).toPtz(createReqVO.getPtzId(),createReqVO.getCameraId());
return success(cameraIoService.createCameraIo(createReqVO));
return success(cameraIoDO.getPtzId());
}
/**

@ -19,6 +19,9 @@ public class SensorGunPageReqVO extends PageParam {
@Schema(description = "ip")
private String ip;
@Schema(description = "type")
private Integer type;
@Schema(description = "端口")
private Integer port;

@ -19,6 +19,9 @@ public class SensorGunSaveReqVO {
@Schema(description = "ip")
private String ip;
@Schema(description = "type")
private Integer type;
@Schema(description = "端口")
private Integer port;

@ -1,8 +1,11 @@
package cn.iocoder.yudao.module.camera.dal.dataobject.sensorgun;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import org.glassfish.jaxb.core.v2.TODO;
/**
* DO
@ -17,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SensorGunDO extends BaseDO {
public class SensorGunDO extends BaseDO {
/**
* id
@ -28,6 +31,11 @@ public class SensorGunDO extends BaseDO {
* id
*/
private Integer streetId;
/**
* type
*/
private Integer type;
/**
*
*

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.camera.dal.entity;
import lombok.Data;
import java.util.List;
@Data
public class HikPythonEntity {
private String type;
private String sn;
private Integer direction;
private String width;
private String length;
private Integer height;
private Integer min_area;
private Boolean lack;
// 是否有缺
private Integer tolerance;
private String status;
private List<String> colors;
}

@ -0,0 +1,171 @@
package cn.iocoder.yudao.module.camera.service.Hik3D;
import cn.iocoder.yudao.module.camera.dal.dataobject.resources.URLResourcesDo;
import cn.iocoder.yudao.module.camera.dal.dataobject.stock.StockDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.street.StreetDO;
import cn.iocoder.yudao.module.camera.dal.entity.HikPythonEntity;
import cn.iocoder.yudao.module.camera.dal.entity.ScanData;
import cn.iocoder.yudao.module.camera.framework.netty.ksec.KsecDataInfo;
import cn.iocoder.yudao.module.camera.service.resources.URLResourcesService;
import cn.iocoder.yudao.module.camera.service.scan.ScanService;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import com.google.gson.Gson;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Objects;
@Slf4j
@Service("HikFlaskApiService")
public class HikFlaskApiService implements ScanService {
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
@Resource
private OkHttpClient client;
private final Gson gson = new Gson();
@Resource
private DictDataService dictDataService;
// ================== /config/update ==================
/**
* /config/update
*/
public HikPythonEntity updateConfig(String baseUrl) throws IOException {
Request request = new Request.Builder()
.url(baseUrl + "/config/update")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = Objects.requireNonNull(response.body()).string();
return gson.fromJson(responseBody, HikPythonEntity.class);
}
}
// ================== /api/addTemplate ==================
/**
* /api/addTemplate
*
* @param templateType type
* @param data JSON Map
*/
public HikPythonEntity addTemplate(String templateType, HikPythonEntity data,String baseUrl) throws IOException {
if (templateType == null || templateType.isEmpty()) {
throw new IllegalArgumentException("Missing 'type' field");
}
String json = gson.toJson(data);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(baseUrl + "/api/addTemplate")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = Objects.requireNonNull(response.body()).string();
return gson.fromJson(responseBody, HikPythonEntity.class);
}
}
// ================== /api/picComputeAll ==================
/**
* /api/picComputeAll
*/
public HikPythonEntity picComputeAll(String type,String baseUrl) throws IOException {
HikPythonEntity requestData = new HikPythonEntity();
requestData.setType(type);
String json = gson.toJson(requestData);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(baseUrl + "/api/picComputeAll")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = Objects.requireNonNull(response.body()).string();
return gson.fromJson(responseBody, HikPythonEntity.class);
}
}
// ================== /api/picCompute ==================
/**
* /api/picCompute
*/
public HikPythonEntity picCompute(String sn, String type,String baseUrl) throws IOException {
HikPythonEntity requestData =new HikPythonEntity();
requestData.setSn(sn);
requestData.setType(type);
String json = gson.toJson(requestData);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(baseUrl + "/api/picCompute")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String responseBody = Objects.requireNonNull(response.body()).string();
return gson.fromJson(responseBody, HikPythonEntity.class);
}
}
@Resource
URLResourcesService urlResourcesService;
// 识别结果是正常或缺件
@Override
public ScanData scan(StreetDO streetDO, KsecDataInfo dataInfo, StockDO stockDO) {
ScanData scanData = new ScanData();
String urlPath ="http://"+streetDO.getPlcIp() + ":" + dictDataService.parseDictData("Hik3DApi", "port").getValue();
String picPath ="http://"+streetDO.getPlcIp() + ":" + dictDataService.parseDictData("Hik3DApi", "picPath").getValue();
try {
scanData.setCode("缺件");
HikPythonEntity hikPythonEntity = picComputeAll(dataInfo.getCategory(),urlPath);
if (hikPythonEntity != null){
if (hikPythonEntity.getLack()!= null && hikPythonEntity.getLack()) {
}else {
scanData.setCode("正常");
}
if (hikPythonEntity.getColors() != null && hikPythonEntity.getColors().size() > 0) {
for (String color:hikPythonEntity.getColors()){
if (color.startsWith(".")) {
color = color.substring(1);
}
color = picPath + color ;
urlResourcesService.save(URLResourcesDo.builder().url(color).uuid( stockDO.getCheckPic()).type("1").little("缺件拍照").build());
}
}
}
return scanData;
} catch (IOException e) {
throw new RuntimeException(e);
}
// return null;
}
// ================== 测试方法 ==================
}

@ -13,7 +13,6 @@ import jakarta.validation.Valid;
* @author
*/
public interface OrderService {
void check(OrderDO orderDO);
/**
*

@ -2,22 +2,19 @@ package cn.iocoder.yudao.module.camera.service.order;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.camera.controller.admin.checklog.vo.CheckLogSaveReqVO;
import cn.iocoder.yudao.module.camera.controller.admin.order.vo.OrderPageReqVO;
import cn.iocoder.yudao.module.camera.controller.admin.order.vo.OrderSaveReqVO;
import cn.iocoder.yudao.module.camera.controller.admin.stock.vo.StockSaveReqVO;
import cn.iocoder.yudao.module.camera.dal.dataobject.checklog.CheckLogDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.sensorgun.SensorGunDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.stock.StockDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.street.StreetDO;
import cn.iocoder.yudao.module.camera.dal.entity.echarts.*;
import cn.iocoder.yudao.module.camera.dal.entity.echarts.Axis;
import cn.iocoder.yudao.module.camera.dal.entity.echarts.EChartsOption;
import cn.iocoder.yudao.module.camera.dal.entity.echarts.Legend;
import cn.iocoder.yudao.module.camera.dal.entity.echarts.Series;
import cn.iocoder.yudao.module.camera.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.camera.dal.mysql.sensorgun.SensorGunMapper;
import cn.iocoder.yudao.module.camera.service.checklog.CheckLogService;
import cn.iocoder.yudao.module.camera.service.stock.StockService;
import cn.iocoder.yudao.module.camera.service.street.StreetService;
import cn.iocoder.yudao.module.camera.service.threeInOneCode.ScanningGun;
import cn.iocoder.yudao.module.camera.service.threeInOneCode.SpecificationsAndOCR;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import de.danielbechler.util.Strings;
@ -64,58 +61,6 @@ public class OrderServiceImpl implements OrderService {
StockService stockService;
@Override
public void check(OrderDO orderDO) {
StreetDO streetDo = streetService.getStreetByPlcId(orderDO.getSrmNumber());
if(streetDo==null){
return;
}
CheckLogSaveReqVO checkLogSaveReqVO = new CheckLogSaveReqVO();
List<SensorGunDO> sensorGunDOS = sensorGunMapper.selectListByStreetId(streetDo.getId());
//扫码枪校验
String sensorGunCode = "";
for (SensorGunDO sensorGunDO : sensorGunDOS){
sensorGunCode = ScanningGun.readOCR(sensorGunDO.getIp(), sensorGunDO.getPort(),"start",3);
}
//灵闪校验
Map<String,String> readOCR = SpecificationsAndOCR.readOCR(streetDo.getPlcIp(), streetDo.getPlcPort());
String code = readOCR.get("ORC");
StockDO stockDoc =stockService.getOne(new QueryWrapper<StockDO>()
.eq("street_id",streetDo.getId())
.eq("side",orderDO.getFromSide())
.eq("direction",orderDO.getFromDirection())
.eq("`column`",orderDO.getFromColumn())
.eq("`row`",orderDO.getFromRow())
.eq("separation",orderDO.getFromSeparation())
);
if(stockDoc==null){
stockDoc.setCode(sensorGunCode);
stockDoc.setStorageCode(code);
stockService.updateById(stockDoc);
}else {
//图片保存和记录
StockSaveReqVO stockSaveReqVO = new StockSaveReqVO();
stockSaveReqVO.setOrderNum(orderDO.getTaskId());
stockSaveReqVO.setCode(sensorGunCode);
stockSaveReqVO.setStreetId(streetDo.getId());
stockSaveReqVO.setSide(orderDO.getFromSide());
stockSaveReqVO.setDirection(orderDO.getFromDirection());
stockSaveReqVO.setColumn(orderDO.getFromColumn());
stockSaveReqVO.setRow(orderDO.getFromRow());
stockSaveReqVO.setStorageCode(code);
stockService.createStock(stockSaveReqVO);
}
CheckLogDO checkLogDoc = new CheckLogDO();
checkLogService.save(checkLogDoc);
}
@Override
public Long createOrder(OrderSaveReqVO createReqVO) {
// 插入

@ -26,6 +26,7 @@ import cn.iocoder.yudao.module.camera.service.checklog.CheckLogService;
import cn.iocoder.yudao.module.camera.service.resources.URLResourcesService;
import cn.iocoder.yudao.module.camera.service.scan.ScanServiceFactory;
import cn.iocoder.yudao.module.camera.service.stock.StockService;
import cn.iocoder.yudao.module.camera.service.streamingMedia.ZLMediaKitService;
import cn.iocoder.yudao.module.camera.service.street.StreetService;
import cn.iocoder.yudao.module.camera.service.threeInOneCode.ScanningGun;
import cn.iocoder.yudao.module.camera.util.PathUtil;
@ -502,7 +503,8 @@ public class PLCServiceImpl implements PLCService {
//OrderRealtime.startOrder(street.getId(), plcCmdInfo.getOrderNum());
}
}
@Resource
ZLMediaKitService zLMediaKitService;
public void orderStop(KsecDataInfo ksecDataInfo) {
Map<String, DictDataDO> dictDataList = dictDataService.getDictDataList("camera_conf");
LocalDateTime endTime = LocalDateTime.now();
@ -535,7 +537,8 @@ public class PLCServiceImpl implements PLCService {
if (street.getCamera1Id() != null) {
String pathSrc = PathUtil.createFileName(ksecDataInfo, street, "B2-1", ".mp4");
String path = cameraVideo(street.getCamera1Id(), pathSrc, order.getCreateTime(), endDownLoadTime, dictDataList);
String path = zLMediaKitService.startRecord("live", street.getCamera1Id().toString());
// String path = cameraVideo(street.getCamera1Id(), pathSrc, order.getCreateTime(), endDownLoadTime, dictDataList);
update.setVideoPath1(path);
}
if (street.getCamera2Id() != null) {

@ -5,7 +5,9 @@ import cn.iocoder.yudao.module.camera.dal.dataobject.stock.StockDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.street.StreetDO;
import cn.iocoder.yudao.module.camera.dal.entity.ScanData;
import cn.iocoder.yudao.module.camera.framework.netty.ksec.KsecDataInfo;
import cn.iocoder.yudao.module.camera.service.sensorgun.CognexSocket;
import cn.iocoder.yudao.module.camera.service.sensorgun.SensorGunService;
import cn.iocoder.yudao.module.camera.service.sensorgun.SickSocket;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -87,7 +89,13 @@ public class ScanGunScanServiceImpl implements ScanService{
if (sensorGun == null) {
log.error("no sensor gun config in database ,street id:{},direction:{}", streetDO.getId(), dataInfo.getFromDirection());
} else {
trayCode = readOCR(sensorGun.getIp(), sensorGun.getPort());
// sick扫码
if (sensorGun.getType() == 1){
trayCode = SickSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
}else {
// 康耐视扫码
trayCode = CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
}
}
scanData.setCode(trayCode);
return scanData;

@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.camera.dal.dataobject.stock.StockDO;
import cn.iocoder.yudao.module.camera.dal.dataobject.street.StreetDO;
import cn.iocoder.yudao.module.camera.dal.entity.ScanData;
import cn.iocoder.yudao.module.camera.framework.netty.ksec.KsecDataInfo;
import cn.iocoder.yudao.module.camera.service.Hik3D.HikFlaskApiService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -21,8 +22,13 @@ public class ScanServiceFactory {
private YoloServiceImpl yoloService;
@Resource
private OpencvServiceImpl opencvService;
@Resource
private HikFlaskApiService hikFlaskApiService;
// 返回的ScanData的code会将作为扫描结果如果和wms的一致则记录为成功
// 图片保存将在scan方法中实现
public ScanData scan(String type, StreetDO streetDO, KsecDataInfo dataInfo, StockDO stockDO) {
@ -47,6 +53,9 @@ public class ScanServiceFactory {
case "5":
return opencvService.scan(streetDO, dataInfo, stockDO);
// hik3d识别扫码
case "6":
return hikFlaskApiService.scan(streetDO, dataInfo, stockDO);
// 默认情况处理
default:
return null;

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.camera.service.sensorgun;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
@Slf4j
public class CognexSocket {
private static final Logger tcpLogger = LoggerFactory.getLogger("sick");
public static String readOCR(String ip,int port){
Socket socket = new Socket();
String code = "NOREAD";
OutputStream os = null;
InputStream is = null;
try {
socket.connect(new InetSocketAddress(ip,port),3000);
os = socket.getOutputStream();
is = socket.getInputStream();
int i = 0;
while ("NOREAD".equals(code) && i <= 4){
writeCmd(os);
code = read(is);
tcpLogger.info("count:{},ip:{},code:{}",i,ip,code);
if(code!= null){
code = code.replace("\\n","");
}
i++;
}
} catch (IOException e) {
tcpLogger.error("sick time out,ip:{},info:{}",ip,e);
log.error("sick time out,ip:{},info:{}",ip,e);
}finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
}
private static void writeCmd(OutputStream os) throws IOException {
String startCmd = "+";
byte[]bytes = startCmd.getBytes(StandardCharsets.UTF_8);
os.write(bytes);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
startCmd = "-";
bytes = startCmd.getBytes(StandardCharsets.UTF_8);
os.write(bytes);
}
private static String read(InputStream inStream) throws IOException {
BufferedReader bd = new BufferedReader(new InputStreamReader(inStream));
return bd.readLine();
}
}

@ -52,4 +52,5 @@ public interface SensorGunService extends IService<SensorGunDO> {
*/
PageResult<SensorGunDO> getSensorGunPage(SensorGunPageReqVO pageReqVO);
String scan(Integer id);
}

@ -68,4 +68,20 @@ public class SensorGunServiceImpl extends ServiceImpl<SensorGunMapper, SensorGun
return sensorGunMapper.selectPage(pageReqVO,null);
}
@Override
public String scan(Integer id) {
SensorGunDO sensorGun = sensorGunMapper.selectById(id);
if (sensorGun == null) {
throw exception(SENSOR_GUN_NOT_EXISTS);
}
// sick扫描
if (sensorGun.getType()==1) {
return SickSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
}else if (sensorGun.getType()==2) {
return CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
}
return "NoRead";
}
}

@ -0,0 +1,83 @@
package cn.iocoder.yudao.module.camera.service.sensorgun;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
/**
* sick
*/
@Slf4j
public class SickSocket {
private static final Logger tcpLogger = LoggerFactory.getLogger("sick");
public static void main(String[] args) {
String code = readOCR("192.168.8.236", 2002);
System.out.println(code);
}
public static String readOCR(String ip,int port){
Socket socket = new Socket();
String code = "NoRead";
OutputStream os = null;
InputStream is = null;
try {
socket.connect(new InetSocketAddress(ip,port),3000);
socket.setSoTimeout(3000);
os = socket.getOutputStream();
is = socket.getInputStream();
int i = 0;
while ("NoRead".equals(code) && i <= 4){
writeCmd(os);
code = read(is);
tcpLogger.info("count:{},ip:{},code:{}",i,ip,code);
if(code!= null){
code = code.replace("\\n","");
}
i++;
}
} catch (IOException e) {
tcpLogger.error("sick time out,ip:{},info:{}",ip,e);
log.error("sick time out,ip:{},info:{}",ip,e);
}finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
}
private static void writeCmd(OutputStream os) throws IOException {
String startCmd = "start";
byte[]bytes = startCmd.getBytes(StandardCharsets.UTF_8);
os.write(bytes);
}
private static String read(InputStream inStream) throws IOException {
BufferedReader bd = new BufferedReader(new InputStreamReader(inStream));
return bd.readLine();
}
}

@ -0,0 +1,13 @@
package cn.iocoder.yudao.module.camera.service.streamingMedia;
import cn.iocoder.yudao.module.camera.dal.dataobject.camera.CameraDO;
import java.util.List;
public interface ZLMediaKitService {
String startRecord(String app, String stream);
void stopRecord(String app, String stream);
void addRtspProxy(CameraDO camera, String zlmApiUrl, String zlmApiSecret);
void zlmConf( List<CameraDO> list);
void deleteRecordDirectory(String app, String stream, String period);
}

@ -0,0 +1,218 @@
package cn.iocoder.yudao.module.camera.service.streamingMedia;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.camera.dal.dataobject.camera.CameraDO;
import cn.iocoder.yudao.module.camera.dal.zlm.RtspSessionResponse;
import cn.iocoder.yudao.module.camera.service.channel.CameraChannel;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Validated
@Slf4j
public class ZLMediaKitServiceImpl implements ZLMediaKitService{
@Resource
private OkHttpClient client ;
@Resource
private DictDataService dictDataService;
@Override
public String startRecord(String app, String cameraId) {
String zlmApiSecret = dictDataService.parseDictData("ZLMediaKit_conf", "secret").getValue();
Map<String, Object> addParams = new HashMap<>();
addParams.put("secret", zlmApiSecret);
addParams.put("type", "1");//0为hls1为mp4
addParams.put("vhost", "__defaultVhost__");
addParams.put("app", "live");
addParams.put("stream","camera"+ cameraId);
// addParams.put("url", CameraChannel.getRtspUrl(camera.getIp(), camera.getRtspPort(), camera.getChannel(), camera.getUser(), camera.getPassword(),camera.getType()));
sendHttp(addParams, "startRecord");
log.info("startRecord camera:"+cameraId);
String path = checkHiddenFilesInDirectory(app,cameraId);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
stopRecord(app,cameraId);
};
// 延迟5分钟后执行停止任务不会将录像文件录5分钟
long delay =5;
scheduler.schedule(task, delay, TimeUnit.MINUTES);
return path;
}
// 新增方法:检查指定文件夹下是否有以.为开头的文件
public String checkHiddenFilesInDirectory(String app, String cameraId) {
String mp4SavePath = dictDataService.parseDictData("ZLMediaKit_conf", "mp4SavePath").getValue();
// 获取当前日期
LocalDate currentDate = LocalDate.now();
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 格式化日期
String formattedDate = currentDate.format(formatter);
String directoryPath = mp4SavePath+"record/"+app+"/camera"+cameraId+"/"+formattedDate;
Path directory = Paths.get(directoryPath);
List<String> hiddenFiles = new ArrayList<>();
try (Stream<Path> paths = Files.walk(directory, 1)) {
hiddenFiles= paths
.filter(Files::isRegularFile)
.map(Path::getFileName)
.map(Path::toString)
.filter(name -> name.startsWith("."))
.collect(Collectors.toList());
return hiddenFiles.isEmpty() ? "" : "record/"+app+"/camera"+cameraId+"/"+formattedDate+"/"+removeLeadingDot(hiddenFiles.get(0));
} catch (IOException e) {
e.printStackTrace();
hiddenFiles= List.of(); // 返回空列表
}
return "";
}
public static String removeLeadingDot(String input) {
if (input == null || input.isEmpty()) {
return input;
}
if (input.startsWith(".")) {
return input.substring(1);
}
return input;
}
@Override
public void stopRecord(String app, String stream) {
String zlmApiSecret = dictDataService.parseDictData("ZLMediaKit_conf", "secret").getValue();
Map<String, Object> addParams = new HashMap<>();
addParams.put("secret", zlmApiSecret);
addParams.put("type", "1");//0为hls1为mp4
addParams.put("vhost", "__defaultVhost__");
addParams.put("app", "live");
addParams.put("stream","camera"+ stream);
// addParams.put("url", CameraChannel.getRtspUrl(camera.getIp(), camera.getRtspPort(), camera.getChannel(), camera.getUser(), camera.getPassword(),camera.getType()));
sendHttp(addParams, "stopRecord");
}
@Override
public void zlmConf( List<CameraDO> list) {
String zlmApiUrl = dictDataService.parseDictData("ZLMediaKit_conf", "Apiurl").getValue();
String zlmApiSecret = dictDataService.parseDictData("ZLMediaKit_conf", "secret").getValue();
try {
// 查询当前的RTSP拉流代理
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("secret", zlmApiSecret);
String queryUrl = buildUrl(zlmApiUrl +"getMediaList",null , queryParams);
String response = get(queryUrl);
RtspSessionResponse rtspSessionResponse = JsonUtils.parseObject(response, RtspSessionResponse.class);
// 检查并添加缺失的RTSP代理
for (CameraDO entry : list) {
boolean isRtspProxyExists = false;
if (rtspSessionResponse != null && rtspSessionResponse.getData()!=null && rtspSessionResponse.getData().size()>0) {
for (RtspSessionResponse.RtspSession rtspSession : rtspSessionResponse.getData()){
if (rtspSession.getApp().equals("live")&&rtspSession.getStream().equals("camera"+entry.getId())){
isRtspProxyExists = true;
break;
}
}
}
//不存在则重新注入
if (!isRtspProxyExists){
try {
addRtspProxy(entry, zlmApiUrl, zlmApiSecret);
}catch (Exception e){
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void addRtspProxy(CameraDO camera, String zlmApiUrl, String zlmApiSecret) {
Map<String, Object> addParams = new HashMap<>();
addParams.put("secret", zlmApiSecret);
addParams.put("vhost", "__defaultVhost__");
addParams.put("app", "live");
addParams.put("stream","camera"+ camera.getId());
addParams.put("url", CameraChannel.getRtspUrl(camera.getIp(), camera.getRtspPort(), camera.getChannel(), camera.getUser(), camera.getPassword(),camera.getType()));
String addUrl = buildUrl(zlmApiUrl+"addStreamProxy",null , addParams);
String response = null;
try {
response = get(addUrl);
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("Add RTSP Proxy Response: " + response);
}
@Override
public void deleteRecordDirectory(String app, String stream, String period) {
}
public void sendHttp(Map<String, Object> queryParams ,String url){
String zlmApiUrl = dictDataService.parseDictData("ZLMediaKit_conf", "Apiurl").getValue();
try {
// 查询当前的RTSP拉流代理
String queryUrl = buildUrl(zlmApiUrl +url,null , queryParams);
String response = get(queryUrl);
RtspSessionResponse rtspSessionResponse = JsonUtils.parseObject(response, RtspSessionResponse.class);
} catch (Exception e) {
e.printStackTrace();
}
}
private String buildUrl(String baseUrl, String action, Map<String, Object> params) {
HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
for (Map.Entry<String, Object> entry : params.entrySet()) {
urlBuilder.addQueryParameter(entry.getKey(), entry.getValue().toString());
}
return urlBuilder.build().toString();
}
private String get(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
}

@ -1,747 +0,0 @@
package cn.iocoder.yudao.module.camera.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
*
* @author springredisredisTemplate hash h Set s List l
*/
@Component
@Slf4j
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/**
*
*
* @param key
*
* @param time
* ()
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* key
*
* @param key
* null
* @return () 0
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* key
*
* @param key
*
* @return true false
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
*
*
* @param key
*
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
*
*
* @param key
*
* @return
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
*
*
* @param key
*
* @param value
*
* @return true false
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
*
*
* @param key
*
* @param value
*
* @param time
* () time0 time0
* @return true false
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* https://blog.csdn.net/y_y_y_k_k_k_k/article/details/79218254 高并发生成订单号,秒杀类的业务逻辑等。。
*
* @param key
*
* (0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
*
*
* @param key
*
* (0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
*
* @param key
* null
* @param item
* null
* @return
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* hashKey
*
* @param key
*
* @return
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key
*
* @param map
*
* @return true false
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* HashSet
*
* @param key
*
* @param map
*
* @param time
* ()
* @return true false
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* hash,
*
* @param key
*
* @param item
*
* @param value
*
* @return true false
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* hash,
*
* @param key
*
* @param item
*
* @param value
*
* @param time
* () :hash,
* @return true false
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* hash
*
* @param key
* null
* @param item
* 使 null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* hash
*
* @param key
* null
* @param item
* null
* @return true false
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash ,
*
* @param key
*
* @param item
*
* @param by
* (0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash
*
* @param key
*
* @param item
*
* @param by
* (0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* keySet
*
* @param key
*
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
log.error(key, e);
return null;
}
}
/**
* valueset,
*
* @param key
*
* @param value
*
* @return true false
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* set
*
* @param key
*
* @param values
*
* @return
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* set
*
* @param key
*
* @param time
* ()
* @param values
*
* @return
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* set
*
* @param key
*
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* value
*
* @param key
*
* @param values
*
* @return
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
// ============================zset=============================
/**
* keySet
*
* @param key
*
* @return
*/
public Set<Object> zSGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
log.error(key, e);
return null;
}
}
/**
* valueset,
*
* @param key
*
* @param value
*
* @return true false
*/
public boolean zSHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
log.error(key, e);
return false;
}
}
public Boolean zSSet(String key, Object value, double score) {
try {
return redisTemplate.opsForZSet().add(key, value, 2);
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* set
*
* @param key
*
* @param time
* ()
* @param values
*
* @return
*/
public long zSSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* set
*
* @param key
*
* @return
*/
public long zSGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* value
*
* @param key
*
* @param values
*
* @return
*/
public long zSetRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
// ===============================list=================================
/**
* list
*
* @ end-start+1
*
* @param key
*
* @param start
* 0
* @param end
* -1
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
log.error(key, e);
return null;
}
}
/**
* list
*
* @param key
*
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
/**
* list
*
* @param key
*
* @param index
* index>=0 0 1 index<0-1-2
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
log.error(key, e);
return null;
}
}
/**
* list
*
* @param key
*
* @param value
*
* ()
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* list
*
* @param key
*
* @param value
*
* @param time
* ()
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* list
*
* @param key
*
* @param value
*
* ()
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* list
*
* @param key
*
* @param value
*
* @param time
* ()
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* list
*
* @param key
*
* @param index
*
* @param value
*
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* Nvalue
*
* @param key
*
* @param count
*
* @param value
*
* @return
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
log.error(key, e);
return 0;
}
}
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.controller.app.sse;
import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.module.system.controller.app.sse.vo.SseVo;
import cn.iocoder.yudao.module.system.service.sse.SseClient;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
@ -42,6 +43,16 @@ public class SseController {
}
return "ok";
}
@CrossOrigin
@GetMapping("/sendMsgAll")
@ResponseBody
@PermitAll
public String sseChatAll() {
SseVo sseVo = new SseVo();
sseVo.setMessage("hello world");
sseClient.sendMessage(sseVo);
return "ok";
}
/**
*

@ -10,17 +10,16 @@ import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSave
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
import cn.iocoder.yudao.module.system.util.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -34,6 +33,8 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
@Service
@Slf4j
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO> implements DictDataService {
@Resource
private RedisUtil redisUtil;
/**
* dictType > sort
@ -48,8 +49,19 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
@Resource
private DictDataMapper dictDataMapper;
@PostConstruct
void init(){
// log.info("init DictDataServiceImpl");
List<DictDataDO> list = dictDataMapper.selectList();
Map<String,List<DictDataDO>> map = list.stream().collect(Collectors.groupingBy(DictDataDO::getDictType));
map.forEach((k,v)->{
redisUtil.hsetList("dict:"+k, v.stream().collect(Collectors.toMap(DictDataDO::getLabel,DictDataDO::getValue)));
});
}
@Override
public List<DictDataDO> getDictDataList(Integer status, String dictType) {
List<DictDataDO> list = dictDataMapper.selectListByStatusAndDictType(status, dictType);
list.sort(COMPARATOR_TYPE_AND_SORT);
return list;
@ -66,6 +78,18 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
}
@Override
public Map<String,DictDataDO> getDictDataList( String dictType) {
// redis
if(redisUtil.hasKey("dict:"+dictType)){
Map<String,DictDataDO> map = new HashMap<>();
Map<String,String> redisMap = redisUtil.hmget("dict:"+dictType);
map = redisMap.entrySet().stream().map(entry -> {
DictDataDO dictDataDO = new DictDataDO();
dictDataDO.setLabel(entry.getKey());
dictDataDO.setValue(entry.getValue());
return dictDataDO;
}).collect(Collectors.toMap(DictDataDO::getLabel, v->v));
return map;
}
List<DictDataDO> list = dictDataMapper.selectList( new QueryWrapper<DictDataDO>().eq("dict_type", dictType));
Map<String,DictDataDO> map = list.stream().collect(
Collectors.toMap(DictDataDO::getLabel, v->v));
@ -84,6 +108,7 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
@Override
public Long createDictData(DictDataSaveReqVO createReqVO) {
// 校验字典类型有效
validateDictTypeExists(createReqVO.getDictType());
// 校验字典数据的值的唯一性
@ -92,6 +117,9 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
// 插入字典类型
DictDataDO dictData = BeanUtils.toBean(createReqVO, DictDataDO.class);
dictDataMapper.insert(dictData);
// redis创建
redisUtil.hset("dict:"+createReqVO.getDictType(), createReqVO.getLabel(), createReqVO.getValue());
return dictData.getId();
}
@ -107,6 +135,8 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
// 更新字典类型
DictDataDO updateObj = BeanUtils.toBean(updateReqVO, DictDataDO.class);
dictDataMapper.updateById(updateObj);
// redis
redisUtil.hset("dict:"+updateReqVO.getDictType(), updateReqVO.getLabel(), updateReqVO.getValue());
}
@Override
@ -116,6 +146,11 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
// 删除字典数据
dictDataMapper.deleteById(id);
DictDataDO updateReqVO = dictDataMapper.selectById(id);
// redis
redisUtil.hdel("dict:"+updateReqVO.getDictType(), updateReqVO.getLabel());
}
@Override
@ -181,11 +216,21 @@ public class DictDataServiceImpl extends ServiceImpl<DictDataMapper,DictDataDO>
@Override
public DictDataDO getDictData(String dictType, String value) {
return dictDataMapper.selectByDictTypeAndValue(dictType, value);
}
@Override
public DictDataDO parseDictData(String dictType, String label) {
// redis
if(redisUtil.hasKey("dict:"+dictType)) {
String value = redisUtil.hgetString("dict:" + dictType,label);
DictDataDO dictDataDO = new DictDataDO();
dictDataDO.setLabel(label);
dictDataDO.setValue(value);
return dictDataDO;
}
return dictDataMapper.selectByDictTypeAndLabel(dictType, label);
}

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.camera.util;
package cn.iocoder.yudao.module.system.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -6,10 +6,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@ -43,6 +40,24 @@ public class RedisUtil {
return false;
}
}
/**
*
*
* @param key
* =
* ()
* @return
*/
public Set<String> keys(String key) {
try {
Set<String> list = redisTemplate.keys(key);
return list ;
} catch (Exception e) {
log.error(key, e);
return new HashSet<String>();
}
}
/**
* key
@ -189,6 +204,10 @@ public class RedisUtil {
return redisTemplate.opsForHash().get(key, item);
}
public String hgetString(String key, String item) {
return (String) redisTemplate.opsForHash().get(key, item);
}
/**
* hashKey
*
@ -196,8 +215,13 @@ public class RedisUtil {
*
* @return
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
public Map<String, String> hmget(String key) {
Map<Object, Object> map = redisTemplate.opsForHash().entries(key);
Map<String, String> mapString = new HashMap<>();
map.forEach((k, v) -> {
mapString.put(k.toString(), v.toString());
});
return mapString;
}
/**
@ -264,6 +288,18 @@ public class RedisUtil {
}
}
public boolean hsetList(String key, Map<String,String> itemMap) {
try {
for(String item:itemMap.keySet()) {
redisTemplate.opsForHash().put(key, item, itemMap.get(item));
}
return true;
} catch (Exception e) {
log.error(key, e);
return false;
}
}
/**
* hash,
*

@ -1,352 +0,0 @@
package cn.iocoder.yudao.module.system.service.dict;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import java.util.List;
import java.util.function.Consumer;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@Import(DictDataServiceImpl.class)
public class DictDataServiceImplTest extends BaseDbUnitTest {
@Resource
private DictDataServiceImpl dictDataService;
@Resource
private DictDataMapper dictDataMapper;
@MockBean
private DictTypeService dictTypeService;
@Test
public void testGetDictDataList() {
// mock 数据
DictDataDO dictDataDO01 = randomDictDataDO().setDictType("yunai").setSort(2)
.setStatus(CommonStatusEnum.ENABLE.getStatus());
dictDataMapper.insert(dictDataDO01);
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setSort(1)
.setStatus(CommonStatusEnum.ENABLE.getStatus());
dictDataMapper.insert(dictDataDO02);
DictDataDO dictDataDO03 = randomDictDataDO().setDictType("yunai").setSort(3)
.setStatus(CommonStatusEnum.DISABLE.getStatus());
dictDataMapper.insert(dictDataDO03);
DictDataDO dictDataDO04 = randomDictDataDO().setDictType("yunai2").setSort(3)
.setStatus(CommonStatusEnum.DISABLE.getStatus());
dictDataMapper.insert(dictDataDO04);
// 准备参数
Integer status = CommonStatusEnum.ENABLE.getStatus();
String dictType = "yunai";
// 调用
List<DictDataDO> dictDataDOList = dictDataService.getDictDataList(status, dictType);
// 断言
assertEquals(2, dictDataDOList.size());
assertPojoEquals(dictDataDO02, dictDataDOList.get(0));
assertPojoEquals(dictDataDO01, dictDataDOList.get(1));
}
@Test
public void testGetDictDataPage() {
// mock 数据
DictDataDO dbDictData = randomPojo(DictDataDO.class, o -> { // 等会查询到
o.setLabel("芋艿");
o.setDictType("yunai");
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
dictDataMapper.insert(dbDictData);
// 测试 label 不匹配
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
// 测试 dictType 不匹配
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
// 测试 status 不匹配
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 准备参数
DictDataPageReqVO reqVO = new DictDataPageReqVO();
reqVO.setLabel("芋");
reqVO.setDictType("yunai");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
// 调用
PageResult<DictDataDO> pageResult = dictDataService.getDictDataPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbDictData, pageResult.getList().get(0));
}
@Test
public void testGetDictData() {
// mock 数据
DictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);
// 准备参数
Long id = dbDictData.getId();
// 调用
DictDataDO dictData = dictDataService.getDictData(id);
// 断言
assertPojoEquals(dbDictData, dictData);
}
@Test
public void testCreateDictData_success() {
// 准备参数
DictDataSaveReqVO reqVO = randomPojo(DictDataSaveReqVO.class,
o -> o.setStatus(randomCommonStatus()))
.setId(null); // 防止 id 被赋值
// mock 方法
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
// 调用
Long dictDataId = dictDataService.createDictData(reqVO);
// 断言
assertNotNull(dictDataId);
// 校验记录的属性是否正确
DictDataDO dictData = dictDataMapper.selectById(dictDataId);
assertPojoEquals(reqVO, dictData, "id");
}
@Test
public void testUpdateDictData_success() {
// mock 数据
DictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
// 准备参数
DictDataSaveReqVO reqVO = randomPojo(DictDataSaveReqVO.class, o -> {
o.setId(dbDictData.getId()); // 设置更新的 ID
o.setStatus(randomCommonStatus());
});
// mock 方法,字典类型
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
// 调用
dictDataService.updateDictData(reqVO);
// 校验是否更新正确
DictDataDO dictData = dictDataMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, dictData);
}
@Test
public void testDeleteDictData_success() {
// mock 数据
DictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDictData.getId();
// 调用
dictDataService.deleteDictData(id);
// 校验数据不存在了
assertNull(dictDataMapper.selectById(id));
}
@Test
public void testValidateDictDataExists_success() {
// mock 数据
DictDataDO dbDictData = randomDictDataDO();
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
// 调用成功
dictDataService.validateDictDataExists(dbDictData.getId());
}
@Test
public void testValidateDictDataExists_notExists() {
assertServiceException(() -> dictDataService.validateDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS);
}
@Test
public void testValidateDictTypeExists_success() {
// mock 方法,数据类型被禁用
String type = randomString();
when(dictTypeService.getDictType(eq(type))).thenReturn(randomDictTypeDO(type));
// 调用, 成功
dictDataService.validateDictTypeExists(type);
}
@Test
public void testValidateDictTypeExists_notExists() {
assertServiceException(() -> dictDataService.validateDictTypeExists(randomString()), DICT_TYPE_NOT_EXISTS);
}
@Test
public void testValidateDictTypeExists_notEnable() {
// mock 方法,数据类型被禁用
String dictType = randomString();
when(dictTypeService.getDictType(eq(dictType))).thenReturn(
randomPojo(DictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 调用, 并断言异常
assertServiceException(() -> dictDataService.validateDictTypeExists(dictType), DICT_TYPE_NOT_ENABLE);
}
@Test
public void testValidateDictDataValueUnique_success() {
// 调用,成功
dictDataService.validateDictDataValueUnique(randomLongId(), randomString(), randomString());
}
@Test
public void testValidateDictDataValueUnique_valueDuplicateForCreate() {
// 准备参数
String dictType = randomString();
String value = randomString();
// mock 数据
dictDataMapper.insert(randomDictDataDO(o -> {
o.setDictType(dictType);
o.setValue(value);
}));
// 调用,校验异常
assertServiceException(() -> dictDataService.validateDictDataValueUnique(null, dictType, value),
DICT_DATA_VALUE_DUPLICATE);
}
@Test
public void testValidateDictDataValueUnique_valueDuplicateForUpdate() {
// 准备参数
Long id = randomLongId();
String dictType = randomString();
String value = randomString();
// mock 数据
dictDataMapper.insert(randomDictDataDO(o -> {
o.setDictType(dictType);
o.setValue(value);
}));
// 调用,校验异常
assertServiceException(() -> dictDataService.validateDictDataValueUnique(id, dictType, value),
DICT_DATA_VALUE_DUPLICATE);
}
@Test
public void testGetDictDataCountByDictType() {
// mock 数据
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai")));
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("tudou")));
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai")));
// 准备参数
String dictType = "yunai";
// 调用
long count = dictDataService.getDictDataCountByDictType(dictType);
// 校验
assertEquals(2L, count);
}
@Test
public void testValidateDictDataList_success() {
// mock 数据
DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
dictDataMapper.insert(dictDataDO);
// 准备参数
String dictType = dictDataDO.getDictType();
List<String> values = singletonList(dictDataDO.getValue());
// 调用,无需断言
dictDataService.validateDictDataList(dictType, values);
}
@Test
public void testValidateDictDataList_notFound() {
// 准备参数
String dictType = randomString();
List<String> values = singletonList(randomString());
// 调用, 并断言异常
assertServiceException(() -> dictDataService.validateDictDataList(dictType, values), DICT_DATA_NOT_EXISTS);
}
@Test
public void testValidateDictDataList_notEnable() {
// mock 数据
DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.DISABLE.getStatus());
dictDataMapper.insert(dictDataDO);
// 准备参数
String dictType = dictDataDO.getDictType();
List<String> values = singletonList(dictDataDO.getValue());
// 调用, 并断言异常
assertServiceException(() -> dictDataService.validateDictDataList(dictType, values),
DICT_DATA_NOT_ENABLE, dictDataDO.getLabel());
}
@Test
public void testGetDictData_dictType() {
// mock 数据
DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setValue("1");
dictDataMapper.insert(dictDataDO);
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setValue("2");
dictDataMapper.insert(dictDataDO02);
// 准备参数
String dictType = "yunai";
String value = "1";
// 调用
DictDataDO dbDictData = dictDataService.getDictData(dictType, value);
// 断言
assertEquals(dictDataDO, dbDictData);
}
@Test
public void testParseDictData() {
// mock 数据
DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setLabel("1");
dictDataMapper.insert(dictDataDO);
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setLabel("2");
dictDataMapper.insert(dictDataDO02);
// 准备参数
String dictType = "yunai";
String label = "1";
// 调用
DictDataDO dbDictData = dictDataService.parseDictData(dictType, label);
// 断言
assertEquals(dictDataDO, dbDictData);
}
// ========== 随机对象 ==========
@SafeVarargs
private static DictDataDO randomDictDataDO(Consumer<DictDataDO>... consumers) {
Consumer<DictDataDO> consumer = (o) -> {
o.setStatus(randomCommonStatus()); // 保证 status 的范围
};
return randomPojo(DictDataDO.class, ArrayUtils.append(consumer, consumers));
}
/**
*
*
* @param type
* @return DictTypeDO
*/
private static DictTypeDO randomDictTypeDO(String type) {
return randomPojo(DictTypeDO.class, o -> {
o.setType(type);
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 是开启
});
}
}

@ -55,7 +55,7 @@ spring:
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
data:
redis:
host: 400-infra.server.iocoder.cn # 地址
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 1 # 数据库索引
# password: 123456 # 密码,建议生产环境开启

Loading…
Cancel
Save