Commit 073b354e by HlQ

[add]

1.指标批量绑定 mall,过滤已绑定的mall
2.添加指标记录查询
3.添加 mall 备注增删改查
[chg] 查询指定指标的 mall 逻辑优化
1 parent 1161af17
...@@ -8,7 +8,9 @@ import org.dromara.hutool.core.data.id.IdUtil; ...@@ -8,7 +8,9 @@ import org.dromara.hutool.core.data.id.IdUtil;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.dto.monitor.EventDTO; import vion.dto.monitor.EventDTO;
import vion.model.monitor.Event; import vion.model.monitor.Event;
import vion.model.monitor.EventRecord;
import vion.model.monitor.RAgentEvent; import vion.model.monitor.RAgentEvent;
import vion.service.monitor.IEventRecordService;
import vion.service.monitor.IEventService; import vion.service.monitor.IEventService;
import vion.service.monitor.IRAgentEventService; import vion.service.monitor.IRAgentEventService;
import vion.vo.monitor.EventVO; import vion.vo.monitor.EventVO;
...@@ -25,6 +27,7 @@ public class EventController { ...@@ -25,6 +27,7 @@ public class EventController {
private final IEventService eventService; private final IEventService eventService;
private final IRAgentEventService agentEventService; private final IRAgentEventService agentEventService;
private final IEventRecordService eventRecordService;
@GetMapping @GetMapping
@SaCheckPermission(value = "event:list", orRole = "admin") @SaCheckPermission(value = "event:list", orRole = "admin")
...@@ -84,4 +87,12 @@ public class EventController { ...@@ -84,4 +87,12 @@ public class EventController {
public String bindBatch(@PathVariable String agentUid, @RequestBody RAgentEvent dto) { public String bindBatch(@PathVariable String agentUid, @RequestBody RAgentEvent dto) {
return agentEventService.bindBatch(agentUid, dto); return agentEventService.bindBatch(agentUid, dto);
} }
@GetMapping("/rec")
@SaCheckPermission(value = "event:rec:list", orRole = "admin")
public Page<EventRecord> listRec(EventRecord dto) {
return eventRecordService.lambdaQuery(dto)
.orderByDesc(EventRecord::getCreateTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize()));
}
} }
...@@ -6,7 +6,9 @@ import lombok.RequiredArgsConstructor; ...@@ -6,7 +6,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.dto.monitor.MallDTO; import vion.dto.monitor.MallDTO;
import vion.model.monitor.MAccount; import vion.model.monitor.MAccount;
import vion.model.monitor.RMallRemark;
import vion.service.monitor.IMallService; import vion.service.monitor.IMallService;
import vion.service.monitor.IRMallRemarkService;
import vion.vo.monitor.MallVO; import vion.vo.monitor.MallVO;
import java.util.List; import java.util.List;
...@@ -20,6 +22,7 @@ import java.util.List; ...@@ -20,6 +22,7 @@ import java.util.List;
public class MallController { public class MallController {
private final IMallService mallService; private final IMallService mallService;
private final IRMallRemarkService mallRemarkService;
@GetMapping("/account") @GetMapping("/account")
@SaCheckPermission(value = "mall:account:list", orRole = "admin") @SaCheckPermission(value = "mall:account:list", orRole = "admin")
...@@ -29,7 +32,6 @@ public class MallController { ...@@ -29,7 +32,6 @@ public class MallController {
@GetMapping("/attention/account") @GetMapping("/attention/account")
@SaCheckPermission(value = "mall:attention:account:list", orRole = "admin") @SaCheckPermission(value = "mall:attention:account:list", orRole = "admin")
// todo 权限为加
public Page<MAccount> listAttentionAccount(MAccount dto) { public Page<MAccount> listAttentionAccount(MAccount dto) {
return mallService.listAttentionAccount(dto); return mallService.listAttentionAccount(dto);
} }
...@@ -75,4 +77,40 @@ public class MallController { ...@@ -75,4 +77,40 @@ public class MallController {
public String cancelAttention(@PathVariable Long id) { public String cancelAttention(@PathVariable Long id) {
return mallService.cancelAttention(id); return mallService.cancelAttention(id);
} }
// region 备注
@GetMapping("/remark")
@SaCheckPermission(value = "mall:remark:list", orRole = "admin")
public Page<RMallRemark> listRemark(RMallRemark dto) {
return mallRemarkService.lambdaQuery(dto)
.orderByDesc(RMallRemark::getCreateTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize()));
}
@GetMapping("/remark/{id}")
@SaCheckPermission(value = "mall:remark:get", orRole = "admin")
public RMallRemark getRemark(@PathVariable Long id) {
return mallRemarkService.getById(id);
}
@PostMapping("/remark")
@SaCheckPermission(value = "mall:remark:save", orRole = "admin")
public String remark(@RequestBody RMallRemark dto) {
return mallRemarkService.save(dto) ? "添加成功" : "添加失败";
}
@PostMapping("/remark/{id}")
@SaCheckPermission(value = "mall:remark:edit", orRole = "admin")
public String editRemark(@PathVariable Long id, @RequestBody RMallRemark dto) {
dto.setId(id);
return mallRemarkService.updateById(dto) ? "修改成功" : "修改失败";
}
@DeleteMapping("/remark/{id}")
@SaCheckPermission(value = "mall:remark:remove", orRole = "admin")
public String removeRemark(@PathVariable Long id) {
return mallRemarkService.removeById(id) ? "删除成功" : "删除失败";
}
// endregion
} }
...@@ -33,7 +33,7 @@ public class MqttClientMessageListener { ...@@ -33,7 +33,7 @@ public class MqttClientMessageListener {
private final IEventRecordService recordService; private final IEventRecordService recordService;
private final IRAgentEventService agentEventService; private final IRAgentEventService agentEventService;
@MqttClientSubscribe("${mqtt.client.server-topic:/MS/receive}") @MqttClientSubscribe(value = "${mqtt.client.server-topic:/MS/receive}", qos = MqttQoS.QOS2)
public void onMessage(String topic, byte[] payload) { public void onMessage(String topic, byte[] payload) {
log.info("topic:[{}] 收到消息", topic); log.info("topic:[{}] 收到消息", topic);
......
package vion.mapper.monitor;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import vion.model.monitor.RMallRemark;
/**
* @author vion
* @date 2024/11/20
*/
public interface RMallRemarkMapper extends BaseMapper<RMallRemark> {
}
\ No newline at end of file \ No newline at end of file
...@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*; ...@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import vion.config.mp.JsonbTypeHandler; import vion.config.mp.JsonbTypeHandler;
import vion.dto.BaseDTO;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -13,7 +14,7 @@ import java.time.LocalDateTime; ...@@ -13,7 +14,7 @@ import java.time.LocalDateTime;
@Getter @Getter
@Setter @Setter
@TableName(value = "m_event_record", autoResultMap = true) @TableName(value = "m_event_record", autoResultMap = true)
public class EventRecord { public class EventRecord extends BaseDTO {
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
private Long id; private Long id;
......
package vion.model.monitor;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import vion.dto.BaseDTO;
import java.time.LocalDate;
import java.util.Date;
/**
* mall注释关联表
*/
@Getter
@Setter
@TableName(value = "mr_mall_remark")
public class RMallRemark extends BaseDTO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField(value = "mall_uid")
private String mallUid;
/**
* 备注日期
*/
@TableField(value = "remark_date")
private LocalDate remarkDate;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "creator")
private String creator;
@TableField(value = "updater")
private String updater;
@TableField(value = "create_time")
private Date createTime;
@TableField(value = "update_time")
private Date updateTime;
}
\ No newline at end of file \ No newline at end of file
...@@ -82,35 +82,80 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem ...@@ -82,35 +82,80 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem
@Override @Override
public Page<MallVO> listAttention(MallDTO dto) { public Page<MallVO> listAttention(MallDTO dto) {
Assert.notNull(dto.getAgentType(), "agentType 不能为空"); Assert.notNull(dto.getAgentType(), "agentType 不能为空");
var wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Mall.class)) if (CollUtil.isEmpty(dto.getEventUidList())) {
.selectAll(Mall.class) var wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Mall.class))
.selectAs(MAccount::getName, MallVO::getAccountName) .selectAll(Mall.class)
.selectAs(Agent::getHostname, MallVO::getHostname) .selectAs(MAccount::getName, MallVO::getAccountName)
.leftJoin(MAccount.class, MAccount::getUid, Mall::getAccountUid) .selectAs(Agent::getHostname, MallVO::getHostname)
.leftJoin(Agent.class, Agent::getUid, Mall::getAgentUid) .leftJoin(MAccount.class, MAccount::getUid, Mall::getAccountUid)
.eq(Mall::getAttention, 1) .leftJoin(Agent.class, Agent::getUid, Mall::getAgentUid)
.orderByDesc(Mall::getUid, Mall::getUpdateTime); .eq(Mall::getAttention, 1)
var mallVOPage = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), MallVO.class, wrapper); .orderByDesc(Mall::getUid, Mall::getUpdateTime);
Opt.ofEmptyAble(mallVOPage.getRecords()) var mallVOPage = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), MallVO.class, wrapper);
.ifPresent(r -> { Opt.ofEmptyAble(mallVOPage.getRecords())
var mallUidList = r.stream().map(MallVO::getUid).toList(); .ifPresent(r -> {
// fixme {@link EventServiceImpl #51} var mallUidList = r.stream().map(MallVO::getUid).toList();
var eventRecWrapper = Wrappers.<EventRecord>query() // fixme {@link EventServiceImpl #51}
.select("DISTINCT on (mall_uid,event_type) *") var eventRecWrapper = Wrappers.<EventRecord>query()
.in("mall_uid", mallUidList) .select("DISTINCT on (mall_uid,event_type) *")
.orderByDesc("mall_uid", "event_type", "create_time"); .in("mall_uid", mallUidList)
var eventRecordList = eventRecordService.list(eventRecWrapper); .in(CollUtil.isNotEmpty(dto.getEventUidList()), "event_uid", dto.getEventUidList())
var mallUid2RecMap = eventRecordList.stream().collect(Collectors.groupingBy(EventRecord::getMallUid)); .orderByDesc("mall_uid", "event_type", "create_time");
var eventRecordList = eventRecordService.list(eventRecWrapper);
var agentEventList = agentEventService.lambdaQuery().in(RAgentEvent::getMallUid, mallUidList).list(); var mallUid2RecMap = eventRecordList.stream().collect(Collectors.groupingBy(EventRecord::getMallUid));
var mallUid2AgentEventMap = agentEventList.stream().collect(Collectors.groupingBy(RAgentEvent::getMallUid));
var agentEventList = agentEventService.lambdaQuery().in(RAgentEvent::getMallUid, mallUidList).list();
r.forEach(tmp -> { var mallUid2AgentEventMap = agentEventList.stream().collect(Collectors.groupingBy(RAgentEvent::getMallUid));
tmp.setEventRecordList(mallUid2RecMap.getOrDefault(tmp.getUid(), List.of()));
tmp.setAgentEventList(mallUid2AgentEventMap.getOrDefault(tmp.getUid(), List.of())); r.forEach(tmp -> {
tmp.setEventRecordList(mallUid2RecMap.getOrDefault(tmp.getUid(), List.of()));
tmp.setAgentEventList(mallUid2AgentEventMap.getOrDefault(tmp.getUid(), List.of()));
});
}); });
}); return mallVOPage;
return mallVOPage; } else {
var agentEventWrapper = new MPJLambdaWrapper<RAgentEvent>()
.selectAll(RAgentEvent.class)
.leftJoin(Agent.class, Agent::getUid, RAgentEvent::getAgentUid)
.in(RAgentEvent::getEventUid, dto.getEventUidList())
.eq(Agent::getType, dto.getAgentType())
.orderByDesc(RAgentEvent::getCreateTime);
var agentEventList = agentEventService.selectJoinList(RAgentEvent.class, agentEventWrapper);
if (CollUtil.isEmpty(agentEventList)) {
return new Page<>();
}
var mallUidList = agentEventList.stream().map(RAgentEvent::getMallUid).distinct().toList();
var wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Mall.class))
.selectAll(Mall.class)
.selectAs(MAccount::getName, MallVO::getAccountName)
.selectAs(Agent::getHostname, MallVO::getHostname)
.leftJoin(MAccount.class, MAccount::getUid, Mall::getAccountUid)
.leftJoin(Agent.class, Agent::getUid, Mall::getAgentUid)
.eq(Mall::getAttention, 1)
.in(Mall::getUid, mallUidList)
.orderByDesc(Mall::getUid, Mall::getUpdateTime);
var mallVOPage = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), MallVO.class, wrapper);
Opt.ofEmptyAble(mallVOPage.getRecords())
.ifPresent(r -> {
var tmpMallUidList = r.stream().map(MallVO::getUid).toList();
// fixme {@link EventServiceImpl #51}
var eventRecWrapper = Wrappers.<EventRecord>query()
.select("DISTINCT on (mall_uid,event_type) *")
.in("mall_uid", tmpMallUidList)
.orderByDesc("mall_uid", "event_type", "create_time");
var eventRecordList = eventRecordService.list(eventRecWrapper);
var mallUid2RecMap = eventRecordList.stream().collect(Collectors.groupingBy(EventRecord::getMallUid));
var tmpAgentEventList = agentEventService.lambdaQuery().in(RAgentEvent::getMallUid, mallUidList).list();
var mallUid2AgentEventMap = tmpAgentEventList.stream().collect(Collectors.groupingBy(RAgentEvent::getMallUid));
r.forEach(tmp -> {
tmp.setEventRecordList(mallUid2RecMap.getOrDefault(tmp.getUid(), List.of()));
tmp.setAgentEventList(mallUid2AgentEventMap.getOrDefault(tmp.getUid(), List.of()));
});
});
return mallVOPage;
}
} }
@Override @Override
...@@ -121,7 +166,7 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem ...@@ -121,7 +166,7 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem
.in(CollUtil.isNotEmpty(dto.getEventUidList()), "event_uid", dto.getEventUidList()) .in(CollUtil.isNotEmpty(dto.getEventUidList()), "event_uid", dto.getEventUidList())
.orderByDesc("mall_uid", "event_type", "create_time"); .orderByDesc("mall_uid", "event_type", "create_time");
var eventRecordList = eventRecordService.list(eventRecWrapper); var eventRecordList = eventRecordService.list(eventRecWrapper);
var mallUidList = eventRecordList.stream().filter(r -> r.getStatus() != 1).map(EventRecord::getMallUid).toList(); var mallUidList = eventRecordList.stream().filter(r -> r.getStatus() == 0).map(EventRecord::getMallUid).toList();
if (CollUtil.isEmpty(mallUidList)) { if (CollUtil.isEmpty(mallUidList)) {
return new Page<>(); return new Page<>();
} }
...@@ -139,9 +184,17 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem ...@@ -139,9 +184,17 @@ public class MallServiceImpl extends MPJBaseServiceImpl<MallMapper, Mall> implem
var mallVOPage = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), MallVO.class, wrapper); var mallVOPage = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), MallVO.class, wrapper);
Opt.ofEmptyAble(mallVOPage.getRecords()) Opt.ofEmptyAble(mallVOPage.getRecords())
.ifPresent(r -> { .ifPresent(r -> {
var mallUid2SelfMap = eventRecordList.stream().collect(Collectors.groupingBy(EventRecord::getMallUid)); var tmpMallUidList = r.stream().map(MallVO::getUid).toList();
var tmpWrapper = Wrappers.<EventRecord>query()
.select("DISTINCT on (mall_uid,event_type) *")
.in("mall_uid", tmpMallUidList)
.orderByDesc("mall_uid", "event_type", "create_time");
var tmpEventRecordList = eventRecordService.list(tmpWrapper);
var tmpMallUid2RecMap = tmpEventRecordList.stream().collect(Collectors.groupingBy(EventRecord::getMallUid));
r.forEach(tmp -> { r.forEach(tmp -> {
tmp.setEventRecordList(mallUid2SelfMap.getOrDefault(tmp.getUid(), List.of()));
tmp.setEventRecordList(tmpMallUid2RecMap.getOrDefault(tmp.getUid(), List.of()));
tmp.setAgentEventList(mallUid2AgentEventMap.getOrDefault(tmp.getUid(), List.of())); tmp.setAgentEventList(mallUid2AgentEventMap.getOrDefault(tmp.getUid(), List.of()));
}); });
}); });
......
...@@ -8,6 +8,7 @@ import net.dreamlu.iot.mqtt.codec.MqttQoS; ...@@ -8,6 +8,7 @@ import net.dreamlu.iot.mqtt.codec.MqttQoS;
import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate; import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import vion.mapper.monitor.MallMapper; import vion.mapper.monitor.MallMapper;
...@@ -96,7 +97,15 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper ...@@ -96,7 +97,15 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper
var mallList = mallMapper.selectList(Wrappers.<Mall>lambdaQuery().eq(Mall::getAccountUid, accountUid)); var mallList = mallMapper.selectList(Wrappers.<Mall>lambdaQuery().eq(Mall::getAccountUid, accountUid));
mallList.forEach(m -> m.setAttention((short) 1)); mallList.forEach(m -> m.setAttention((short) 1));
mallMapper.updateById(mallList); mallMapper.updateById(mallList);
var existMall2EventList = this.lambdaQuery()
.eq(RAgentEvent::getAccountUid, accountUid)
.eq(RAgentEvent::getEventUid, dto.getEventUid())
.list().stream().map(RAgentEvent::getMallUid).toList();
var agentEventList = mallList.stream().map(m -> { var agentEventList = mallList.stream().map(m -> {
if (existMall2EventList.contains(m.getUid())) {
return null;
}
var rAgentEvent = new RAgentEvent(); var rAgentEvent = new RAgentEvent();
rAgentEvent.setAgentUid(agentUid); rAgentEvent.setAgentUid(agentUid);
rAgentEvent.setAccountUid(accountUid); rAgentEvent.setAccountUid(accountUid);
...@@ -107,7 +116,7 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper ...@@ -107,7 +116,7 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper
rAgentEvent.setThreshold(dto.getThreshold()); rAgentEvent.setThreshold(dto.getThreshold());
rAgentEvent.setControlSwitch((short) 1); rAgentEvent.setControlSwitch((short) 1);
return rAgentEvent; return rAgentEvent;
}).toList(); }).filter(ObjUtil::isNotNull).toList();
this.saveBatch(agentEventList); this.saveBatch(agentEventList);
agentEventList.forEach(agentEvent -> client.publish(topic, JsonUtil.toJsonByte(agentEvent), MqttQoS.QOS2)); agentEventList.forEach(agentEvent -> client.publish(topic, JsonUtil.toJsonByte(agentEvent), MqttQoS.QOS2));
} }
...@@ -116,7 +125,15 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper ...@@ -116,7 +125,15 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper
var mallList = mallMapper.selectList(Wrappers.<Mall>lambdaQuery().in(Mall::getUid, mallUidList)); var mallList = mallMapper.selectList(Wrappers.<Mall>lambdaQuery().in(Mall::getUid, mallUidList));
mallList.forEach(m -> m.setAttention((short) 1)); mallList.forEach(m -> m.setAttention((short) 1));
mallMapper.updateById(mallList); mallMapper.updateById(mallList);
var existMall2EventList = this.lambdaQuery()
.in(RAgentEvent::getMallUid, mallUidList)
.eq(RAgentEvent::getEventUid, dto.getEventUid())
.list().stream().map(RAgentEvent::getMallUid).toList();
var agentEventList = mallList.stream().map(m -> { var agentEventList = mallList.stream().map(m -> {
if (existMall2EventList.contains(m.getUid())) {
return null;
}
var rAgentEvent = new RAgentEvent(); var rAgentEvent = new RAgentEvent();
rAgentEvent.setAgentUid(agentUid); rAgentEvent.setAgentUid(agentUid);
rAgentEvent.setAccountUid(m.getAccountUid()); rAgentEvent.setAccountUid(m.getAccountUid());
...@@ -127,7 +144,7 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper ...@@ -127,7 +144,7 @@ public class RAgentEventServiceImpl extends MPJBaseServiceImpl<RAgentEventMapper
rAgentEvent.setThreshold(dto.getThreshold()); rAgentEvent.setThreshold(dto.getThreshold());
rAgentEvent.setControlSwitch((short) 1); rAgentEvent.setControlSwitch((short) 1);
return rAgentEvent; return rAgentEvent;
}).toList(); }).filter(ObjUtil::isNotNull).toList();
this.saveBatch(agentEventList); this.saveBatch(agentEventList);
agentEventList.forEach(agentEvent -> client.publish(topic, JsonUtil.toJsonByte(agentEvent), MqttQoS.QOS2)); agentEventList.forEach(agentEvent -> client.publish(topic, JsonUtil.toJsonByte(agentEvent), MqttQoS.QOS2));
} }
......
package vion.service.impl.monitor;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import vion.mapper.monitor.RMallRemarkMapper;
import vion.model.monitor.RMallRemark;
import vion.service.monitor.IRMallRemarkService;
/**
* @author vion
* @date 2024/11/20
*/
@Service
public class RMallRemarkServiceImpl extends ServiceImpl<RMallRemarkMapper, RMallRemark> implements IRMallRemarkService {
}
package vion.service.monitor;
import com.baomidou.mybatisplus.extension.service.IService;
import vion.model.monitor.RMallRemark;
/**
* @author vion
* @date 2024/11/20
*/
public interface IRMallRemarkService extends IService<RMallRemark> {
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!