重连机制优化

main
Comair 1 year ago
parent 2827a79f6c
commit 5bfef6b2cd
  1. 35
      shkj-admin/src/main/resources/application-test.yml
  2. 11
      shkj-wms/src/main/java/com/shkj/wms/controller/busin/TaskController.java
  3. 4
      shkj-wms/src/main/java/com/shkj/wms/controller/business/BaseBarcodesController.java
  4. 88
      shkj-wms/src/main/java/com/shkj/wms/plc/PlcEventTask.java
  5. 67
      shkj-wms/src/main/java/com/shkj/wms/plc/PlcInit.java
  6. 2
      shkj-wms/src/main/java/com/shkj/wms/scheduled/ScheduledTasks.java
  7. 2
      shkj-wms/src/main/java/com/shkj/wms/service/IBusinDataTaskService.java
  8. 6
      shkj-wms/src/main/java/com/shkj/wms/service/impl/BusinDataTaskServiceImpl.java
  9. 2
      shkj-wms/src/main/java/com/shkj/wms/service/impl/BusinPickupServiceImpl.java
  10. 5
      shkj-wms/src/main/java/com/shkj/wms/utils/PdfConvertHtmlUtil.java
  11. 2
      shkj-wms/src/main/resources/mapper/wms/BaseBarcodesOutMapper.xml
  12. 2
      shkj-wms/src/main/resources/mapper/wms/BaseLocationMapper.xml

@ -2,7 +2,7 @@
shkj:
# 文件路径 示例( Windows配置D:/shkj/uploadPath,Linux配置 /home/shkj/uploadPath)
profile: /www/shkj_v2/static
urlPre: http://120.77.94.227:8031
urlPre: http://120.77.94.227:8041
# 数据源配置
spring:
@ -12,10 +12,10 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://127.0.0.1:3306/testpo1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://127.0.0.1:3306/po1_wms_wcs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://127.0.0.1:3306/po1testsh?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
# password: CTlTwKgIrRVTsEHqxxx
# 从库数据源
slave:
# 从数据源开关/默认关闭
@ -71,7 +71,8 @@ spring:
# 数据库索引
database: 1
# 密码
password: rvGUoUFAIg4nESp9
password:
# password: 123456
# 连接超时时间
timeout: 10s
lettuce:
@ -87,10 +88,19 @@ spring:
third:
# agv接口
agvCreateTaskUrl: http://169.254.61.3:8081/rest/common/createTask
agvStatesUrl: http://169.254.61.3:8081/rest/robots/states
agvCancelTaskUrl: http://169.254.61.3:8081/rest/common/cancelTask
queryAckByTaskUrl: http://169.254.61.3:8081/rest/common/queryAckByTaskId
agvCreateTaskUrl: http://192.168.2.200:20003/rest/common/createTask
agvStatesUrl: http://192.168.2.200:20003/rest/robots/states
agvCancelTaskUrl: http://192.168.2.200:20003/rest/common/cancelTas
queryAckByTaskUrl: http://169.254.61.3:8095/rest/common/queryAck
deleteShelfUrl: http://169.254.61.3:8095/rest/common/deleteShelf
updateTaskUrl: http://169.254.61.3:8095/rest/common/updateTask
# agvCreateTaskUrl: http://169.254.61.4:8095/rest/common/createTask
# agvStatesUrl: http://169.254.61.4:8095/rest/robots/states
# agvCancelTaskUrl: http://169.254.61.4:8095/rest/common/cancelTask
# queryAckByTaskUrl: http://169.254.61.4:8095/rest/common/queryAck
# deleteShelfUrl: http://169.254.61.4:8095/rest/common/deleteShelf
# ess接口
essTaskDistributionUrl: http://210.21.218.14:60354/task/create
essTaskCancelUrl: http://210.21.218.14:60354/task/cancel
@ -103,3 +113,12 @@ third:
# erp接口
erpU8PuStoreInUrl: http://192.168.1.99:13001/api/U8PuStoreIn/Add
erpU8MaterialOutUrl: http://192.168.1.99:13001/api/U8MaterialOut/Add
#QAD 反馈给QAD正常保险杠
QADSuccessUrl: http://10.110.36.247:9889/equality.mes.stereoscopicLibrary/v1.0/pqslibpushcodeinfo/receiveCodes
plc:
firstBarcode: DB320.84
secondBarcode: DB320.106
thirdBarcode: DB320.128
containerCode: DB320.62

@ -9,7 +9,6 @@ import com.shkj.wms.plc.PlcEventTask;
import com.shkj.wms.plc.PlcEventTmpTask;
import com.shkj.wms.scheduled.ScheduledTasks;
import com.shkj.wms.service.IBusinEnptyContainerService;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -39,7 +38,7 @@ public class TaskController extends BaseController {
@Log(title = "手动调度任务流程",businessType = BusinessType.UPDATE)
@PostMapping("/exeTask")
@RepeatSubmit
public Result<Bool> exeTask(){
public Result<Boolean> exeTask(){
scheduledTasks.task();
return Result.ok();
}
@ -50,7 +49,7 @@ public class TaskController extends BaseController {
@Log(title = "执行PLC相关任务",businessType = BusinessType.UPDATE)
@PostMapping("/exePlcTmpTask")
@RepeatSubmit
public Result<Bool> exePlcTmpTask(){
public Result<Boolean> exePlcTmpTask(){
plcEventTmpTask.init();
return Result.ok();
}
@ -61,7 +60,7 @@ public class TaskController extends BaseController {
@Log(title = "执行PLC相关任务",businessType = BusinessType.UPDATE)
@PostMapping("/exePlcTask")
@RepeatSubmit
public Result<Bool> exePlcTask(){
public Result<Boolean> exePlcTask(){
plcEventTask.init();
return Result.ok();
}
@ -72,7 +71,7 @@ public class TaskController extends BaseController {
@Log(title = "空治具出库流程",businessType = BusinessType.UPDATE)
@PostMapping("/exeEmptyContainerFromWare")
@RepeatSubmit
public Result<Bool> exeEmptyContainerFromWare(){
public Result<Boolean> exeEmptyContainerFromWare(){
iBusinEnptyContainerService.emptyContainerFromWare();
return Result.ok();
}
@ -83,7 +82,7 @@ public class TaskController extends BaseController {
@Log(title = "空治具出库流程",businessType = BusinessType.UPDATE)
@PostMapping("/intask")
@RepeatSubmit
public Result<Bool> intask(Long taskId,Long containerId){
public Result<Boolean> intask(Long taskId,Long containerId){
scheduledTasks.inTask(taskId,containerId);
return Result.ok();
}

@ -13,12 +13,8 @@ import com.shkj.wms.service.IBaseBarcodesOutService;
import com.shkj.wms.service.IBaseGoodsDataService;
import com.shkj.wms.vo.BaseBarcodesOutTaskVo;
import com.shkj.wms.vo.BaseBarcodesOutVo;
import com.shkj.wms.vo.BaseContainerVo;
import com.shkj.wms.vo.BaseInOutQtyVo;
import com.sun.org.apache.xpath.internal.operations.Bool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;

@ -144,62 +144,76 @@ public class PlcEventTask {
return;
}
for (WcsPlcConnectVo conn : plcList) {
if(conn.getPlcIp().contains(".41")){
PlcOperate plcOperate_41 = plcInit.getPlcOperate_41();
if (plcOperate_41 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcInit.getPlcOperate_41(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_41();
}
if(conn.getPlcIp().contains(".50")){
plcTask(plcInit.getPlcOperate_50(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_50();
PlcOperate plcOperate_50 = plcInit.getPlcOperate_50();
if (plcOperate_50 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_50, conn, conn.getPointTables());
}
if(conn.getPlcIp().contains(".60")){
plcTask(plcInit.getPlcOperate_60(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_60();
doDevStatus(plcInit.getPlcOperate_60(),"1#");
PlcOperate plcOperate_60 = plcInit.getPlcOperate_60();
if (plcOperate_60 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_60, conn, conn.getPointTables());
doDevStatus(plcOperate_60,"1#");
}
if(conn.getPlcIp().contains(".70")){
plcTask(plcInit.getPlcOperate_70(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_70();
doDevStatus(plcInit.getPlcOperate_70(),"2#");
PlcOperate plcOperate_70 = plcInit.getPlcOperate_70();
if (plcOperate_70 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_70, conn, conn.getPointTables());
doDevStatus(plcOperate_70,"2#");
}
if(conn.getPlcIp().contains(".80")){
plcTask(plcInit.getPlcOperate_80(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_80();
doDevStatus(plcInit.getPlcOperate_80(),"3#");
PlcOperate plcOperate_80 = plcInit.getPlcOperate_80();
if (plcOperate_80 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_80, conn, conn.getPointTables());
doDevStatus(plcOperate_80,"3#");
}
if(conn.getPlcIp().contains(".90")){
plcTask(plcInit.getPlcOperate_90(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_90();
doDevStatus(plcInit.getPlcOperate_90(),"4#");
PlcOperate plcOperate_90 = plcInit.getPlcOperate_90();
if (plcOperate_90 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_90, conn, conn.getPointTables());
doDevStatus(plcOperate_90,"4#");
}
if(conn.getPlcIp().contains(".100")){
plcTask(plcInit.getPlcOperate_100(), conn, conn.getPointTables());
PlcOperate plc = plcInit.getPlcOperate_100();
doDevStatus(plcInit.getPlcOperate_100(),"5#");
PlcOperate plcOperate_100 = plcInit.getPlcOperate_100();
if (plcOperate_100 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_100, conn, conn.getPointTables());
doDevStatus(plcOperate_100,"5#");
}
if(conn.getPlcIp().contains(".110")){
plcTask(plcInit.getPlcOperate_110(), conn, conn.getPointTables());
// PlcOperate plc = plcInit.getPlcOperate_110();
doDevStatus(plcInit.getPlcOperate_110(),"6#");
PlcOperate plcOperate_110 = plcInit.getPlcOperate_110();
if (plcOperate_110 ==null){
plcInit.connect(conn.getPlcIp());
}
plcTask(plcOperate_110, conn, conn.getPointTables());
doDevStatus(plcOperate_110,"6#");
}
// PlcOperate finalPlc = plc;
// executorService.scheduleWithFixedDelay(
// () -> plcTask(finalPlc, conn, conn.getPointTables()), 1, 1, TimeUnit.SECONDS
// );
//本地测试用
/* if(conn.getPlcIp().contains("127.0.0.1")){
plcTask(plcInit.getPlcOperate_1(), conn, conn.getPointTables());
doDevStatus(plcInit.getPlcOperate_1(),"4#");
}*/
}
}
@ -227,7 +241,7 @@ public class PlcEventTask {
Boolean heartType = plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allHbMap));
if(!heartType){
log.info("心跳写入失败,重连服务器");
plcInit.connect();
plcInit.connect(null);
}
}
@ -248,7 +262,9 @@ public class PlcEventTask {
//根据连接的plcId获取属性
PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, pointTables);
//读取数据失败时,进行重连
if (ObjectUtils.isEmpty(pointMap)){
plcInit.connect(conn.getPlcIp());
return;
}
@ -470,7 +486,7 @@ public class PlcEventTask {
BusinDataTask businDataTaskServiceById = iBusinDataTaskService.getById(taskId);
tunnel = businDataTaskServiceById.getTunnel();
String taskType = businDataTaskServiceById.getTaskType();
if (!taskType.equals("4") && !taskType.equals("5") && !taskType.equals("15") && !taskType.equals("16")) {
if (!taskType.equals("4") && !taskType.equals("5") && !taskType.equals("15") && !taskType.equals("16")&& !taskType.equals("21")) {
Result<Boolean> booleanResult = iPutInOutStorageService.productDeposit(taskId);
//处理成功 返回状态,写入状态位为0
if (booleanResult.getCode() == HttpStatus.SUCCESS) {
@ -513,9 +529,9 @@ public class PlcEventTask {
} else if (TaskTypeEnum.normal_out.getValue().equals(taskType)
|| TaskTypeEnum.urgent_out.getValue().equals(taskType)
||TaskTypeEnum.abnormal_delivery.getValue().equals(taskType)
|| TaskTypeEnum.punching_delivery.getValue().equals(taskType)
|| "21".equals(taskType)
|| TaskTypeEnum.replenish_out.getValue().equals(taskType)){
//处理 4正常出库 5紧急出库 17异常出库 18冲孔出库 10补货出库 库存
//处理 4正常出库 5紧急出库 17异常出库 21冲孔出库 10补货出库 库存
log.info("扣减库存的任务类型:"+taskType);
Boolean delStock = iBusinPickupService.subtractStockDetailByLocation(businDataTaskServiceById);
log.info("扣减库存的结果:"+delStock);
@ -822,7 +838,7 @@ public class PlcEventTask {
businDataTask.setPlcId(30L);
}
if (TaskTypeEnum.punching_delivery.getValue().equals(businDataTask.getTaskType())
if ("21".equals(businDataTask.getTaskType())
|| TaskTypeEnum.replenish_out.getValue().equals(businDataTask.getTaskType())){
bo.setTaskType(24);
businDataTask.setPlcId(30L);

@ -42,18 +42,23 @@ public class PlcInit {
RedisTemplate redisTemplate;
private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
// @PostConstruct
@PostConstruct
public void init(){
log.info("初始化连接对象");
executorService.scheduleWithFixedDelay(
() -> reconnect(), 20, 20, TimeUnit.SECONDS
);
connect();
connect(null);
}
public void connect(){
public void connect(String plcIp){
WcsPlcConnect wcsPlcConnect = new WcsPlcConnect();
wcsPlcConnect.setIsActive("1");
if (plcIp !=null){
wcsPlcConnect.setPlcIp(plcIp);
}
//查询需要连接的PLC,初始化连接对象
List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(new WcsPlcConnect().setIsActive("1"));
List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(wcsPlcConnect);
if (plcList.size() == 0) {
return;
}
@ -62,82 +67,116 @@ public class PlcInit {
PlcHelper plc = new PlcHelper(conn.getPlcType(), conn.getPlcIp(), conn.getPlcFactory(), conn.getPort());
if (conn.getPlcIp().contains(".41")){
plcOperate_41 = plc.getAutomation();
if(plcOperate_41 !=null){
OperateResult connect = plcOperate_41.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 41初始化成功");
}else {
log.info(conn.getPlcIp()+" 41初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 41连接失败");
}
}
if (conn.getPlcIp().contains(".50")){
plcOperate_50 = plc.getAutomation();
if(plcOperate_50 !=null){
OperateResult connect = plcOperate_50.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 50初始化成功");
}else {
log.info(conn.getPlcIp()+" 50初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 50连接失败");
}
}
if (conn.getPlcIp().contains(".60")){
plcOperate_60 = plc.getAutomation();
if(plcOperate_60 !=null){
OperateResult connect = plcOperate_60.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 60初始化成功");
}else {
log.info(conn.getPlcIp()+" 60初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 60连接失败");
}
}
if (conn.getPlcIp().contains(".70")){
plcOperate_70 = plc.getAutomation();
if (plcOperate_70 != null){
OperateResult connect = plcOperate_70.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 70初始化成功");
}else {
log.info(conn.getPlcIp()+" 70初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 70连接失败");
}
}
if (conn.getPlcIp().contains(".80")){
plcOperate_80 = plc.getAutomation();
if (plcOperate_80 != null){
OperateResult connect = plcOperate_80.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 80初始化成功");
}else {
log.info(conn.getPlcIp()+" 80初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 80连接失败");
}
}
if (conn.getPlcIp().contains(".90")){
plcOperate_90 = plc.getAutomation();
if(plcOperate_90 !=null){
OperateResult connect = plcOperate_90.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 90初始化成功");
}else {
log.info(conn.getPlcIp()+" 90初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 90连接失败");
}
}
if (conn.getPlcIp().contains(".100")){
plcOperate_100 = plc.getAutomation();
if (plcOperate_100 != null){
OperateResult connect = plcOperate_100.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 100初始化成功");
}else {
log.info(conn.getPlcIp()+" 100初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 100连接失败");
}
}
if (conn.getPlcIp().contains(".110")){
plcOperate_110 = plc.getAutomation();
if (plcOperate_110 != null){
OperateResult connect = plcOperate_110.connect();
if (connect.IsSuccess){
log.info(conn.getPlcIp()+" 110初始化成功");
}else {
log.info(conn.getPlcIp()+" 110初始化失败");
}
}else {
log.info(conn.getPlcIp()+" 110连接失败");
}
}
@ -153,30 +192,32 @@ public class PlcInit {
}*/
}
}
private void reconnect(){
if (!plcOperate_41.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_50.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_60.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_70.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_80.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_90.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_100.isConnectd()){
connect();
connect(null);
}
if (!plcOperate_110.isConnectd()){
connect();
connect(null);
}
}

@ -175,7 +175,7 @@ public class ScheduledTasks {
}
// @PostConstruct
@Scheduled(cron = "0/3 * * * * ? ")
// @Scheduled(cron = "0/3 * * * * ? ")
@Transactional(rollbackFor = Exception.class)
public void task() {
log.info("开始获取需要执行的任务");

@ -155,7 +155,7 @@ public interface IBusinDataTaskService extends IService<BusinDataTask> {
/**
* 可视化大屏统计出入任务数量
* @param bo
* @param
* @return
*/
List<DataScreeTaskqtyVo> getCurDateTaskQty();

@ -217,7 +217,8 @@ public class BusinDataTaskServiceImpl extends ServiceImpl<BusinDataTaskMapper, B
boolean numberAdd = false;
boolean proportionStatus = true;
if (ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(RedisConstant.out_plan_type)) && redisTemplate.opsForValue().get(RedisConstant.out_plan_type).toString().contains("比例")) {
if (ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(RedisConstant.out_plan_type))
&& redisTemplate.opsForValue().get(RedisConstant.out_plan_type).toString().contains("比例")) {
numberAdd = true;
//查询获取每个货区的比例
BaseStorageQueryListBo baseStorageQueryListBo = new BaseStorageQueryListBo();
@ -282,8 +283,7 @@ public class BusinDataTaskServiceImpl extends ServiceImpl<BusinDataTaskMapper, B
List<String> dbTableColumnNames = pointDeviceout.stream().map(BasePointDeviceVo::getPointNo).collect(Collectors.toList());
String urgencyBefore = null;
String urgencyAfter = null;
for (String str : dbTableColumnNames
) {
for (String str : dbTableColumnNames) {
// TODO 中科 测试 需要还原
if (str.equals(ParameterConstants.ParameterSystem.assemble_point_after)) {
urgencyAfter = str;

@ -179,7 +179,7 @@ public class BusinPickupServiceImpl extends ServiceImpl<BusinPickupMapper, Busin
);
}
//剩余产品创建任务进入待补货区
//查询待补货区货位
// 查询待补货区货位
Long abnormalArea =Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.replenish_area));
List<BaseLocationVo> baseLocationVos = baseLocationMapper.getLocationByAreaId(abnormalArea);
if(baseLocationVos.size()<=0){

@ -4,7 +4,6 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
@ -149,7 +148,7 @@ public class PdfConvertHtmlUtil {
public static String bufferedImageToBase64(BufferedImage bufferedImage) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String png_base64 = "";
try {
/* try {
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);// 写入流中
byte[] bytes = byteArrayOutputStream.toByteArray();// 转换成字节
BASE64Encoder encoder = new BASE64Encoder();
@ -159,7 +158,7 @@ public class PdfConvertHtmlUtil {
.replaceAll("\r", "");
} catch (IOException e) {
e.printStackTrace();
}
}*/
return png_base64;
}

@ -187,7 +187,7 @@
LEFT JOIN base_branch bb ON bdr.branch_id = bb.id
LEFT JOIN busin_data_task bdt ON bdr.task_code = bdt.id
LEFT JOIN base_container bc ON bdr.container_id = bc.id
where bdr.is_state != 1
where bdr.is_state != 1 and date_format(bdr.create_time,'%Y-%m-%d') >=CURDATE()
order by bdr.id desc,bp.point_name desc
</select>
</mapper>

@ -94,7 +94,7 @@
and ba.id = #{areaId}
</if>
<if test="extend1 != null">
and ba.extend1 = #{extend1}
and bl.isuse = #{extend1}
</if>
<if test="storageClassify != null and storageClassify != ''">
and bl.storage_classify = #{storageClassify}

Loading…
Cancel
Save