feat(ZmswpmSubscribe): implement subscription management with create, update, delete, and list functionalities

This commit is contained in:
2025-10-23 22:36:37 +08:00
parent 35383cd3a3
commit f4b90cf953
10 changed files with 477 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
package cn.lihongjie.coal.zmswpmSubscribe.controller;
import cn.lihongjie.coal.annotation.OrgScope;
import cn.lihongjie.coal.annotation.SysLog;
import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.zmswpmSubscribe.dto.CreateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.UpdateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.ZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.service.ZmswpmSubscribeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/zmswpmSubscribe")
@SysLog(module = "煤炭商务网拍卖订阅")
@Slf4j
@OrgScope
public class ZmswpmSubscribeController {
@Autowired private ZmswpmSubscribeService service;
@PostMapping("/create")
public ZmswpmSubscribeDto create(@RequestBody CreateZmswpmSubscribeDto request) {
return this.service.create(request);
}
@PostMapping("/update")
public ZmswpmSubscribeDto update(@RequestBody UpdateZmswpmSubscribeDto request) {
return this.service.update(request);
}
@PostMapping("/delete")
public Object delete(@RequestBody IdRequest request) {
this.service.delete(request);
return true;
}
@PostMapping("/getById")
public ZmswpmSubscribeDto getById(@RequestBody IdRequest request) {
return this.service.getById(request.getId());
}
@PostMapping("/list")
public Page<ZmswpmSubscribeDto> list(@RequestBody CommonQuery request) {
return this.service.list(request);
}
}

View File

@@ -0,0 +1,22 @@
package cn.lihongjie.coal.zmswpmSubscribe.dto;
import cn.lihongjie.coal.base.dto.OrgCommonDto;
import jakarta.persistence.ManyToOne;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@EqualsAndHashCode(callSuper = true)
public class CreateZmswpmSubscribeDto extends OrgCommonDto {
@Comment("查询条件JSON")
private String queryJson;
@ManyToOne
private String botScene;
}

View File

@@ -0,0 +1,21 @@
package cn.lihongjie.coal.zmswpmSubscribe.dto;
import cn.lihongjie.coal.base.dto.OrgCommonDto;
import jakarta.persistence.ManyToOne;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@EqualsAndHashCode(callSuper = true)
public class UpdateZmswpmSubscribeDto extends OrgCommonDto {
@Comment("查询条件JSON")
private String queryJson;
@ManyToOne
private String botScene;
}

View File

@@ -0,0 +1,22 @@
package cn.lihongjie.coal.zmswpmSubscribe.dto;
import cn.lihongjie.coal.base.dto.OrgCommonDto;
import cn.lihongjie.coal.dingtalkBotScene.dto.DingtalkBotSceneDto;
import jakarta.persistence.ManyToOne;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@EqualsAndHashCode(callSuper = true)
public class ZmswpmSubscribeDto extends OrgCommonDto {
@Comment("查询条件JSON")
private String queryJson;
@ManyToOne
private DingtalkBotSceneDto botScene;
}

View File

@@ -0,0 +1,29 @@
package cn.lihongjie.coal.zmswpmSubscribe.entity;
import cn.lihongjie.coal.base.entity.OrgCommonEntity;
import cn.lihongjie.coal.dingtalkBotScene.entity.DingtalkBotSceneEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(
indexes =
@jakarta.persistence.Index(
name = "idx_zmswpmSubscribe_org_id",
columnList = "organization_id"))
public class ZmswpmSubscribeEntity extends OrgCommonEntity {
@Comment("查询条件JSON")
private String queryJson;
@ManyToOne private DingtalkBotSceneEntity botScene;
}

View File

@@ -0,0 +1,191 @@
package cn.lihongjie.coal.zmswpmSubscribe.listener;
import cn.hutool.core.bean.BeanUtil;
import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.dingtalkBot.entity.DingtalkBotEntity;
import cn.lihongjie.coal.dingtalkBot.service.DingtalkBotService;
import cn.lihongjie.coal.rabbitmq.RabbitMQConfiguration;
import cn.lihongjie.coal.zmswpm.dto.ZmswpmDto;
import cn.lihongjie.coal.zmswpm.service.ZmswpmService;
import cn.lihongjie.coal.zmswpmSubscribe.entity.ZmswpmSubscribeEntity;
import cn.lihongjie.coal.zmswpmSubscribe.repository.ZmswpmSubscribeRepository;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Component
@Slf4j
public class ZmswpmDataListener {
@Autowired ObjectMapper objectMapper;
@Autowired ZmswpmSubscribeRepository zmswpmSubscribeRepository;
@Autowired ZmswpmService zmswpmService;
@Autowired private DingtalkBotService dingtalkBotService;
@SneakyThrows
@RabbitListener(
bindings = {
@QueueBinding(
value =
@org.springframework.amqp.rabbit.annotation.Queue(
value = "zmswpm.data",
durable = "true"),
exchange =
@Exchange(
value = RabbitMQConfiguration.SYS_EXCHANGE,
declare = Exchange.FALSE),
key = "zmswpm.*")
})
@Transactional()
public void handleZmswpmMessage(Message message) {
String body = new String(message.getBody());
var rk = message.getMessageProperties().getReceivedRoutingKey();
try {
switch (rk) {
case "zmswpm.newdata":
handleNewData(body);
break;
case "zmswpm.updatedata":
handleUpdateData(body);
break;
default:
log.error("unknown routing key: {}", rk);
}
} catch (Exception e) {
log.error("handle zmswpm message error", e);
throw e;
}
}
@SneakyThrows
private void handleUpdateData(String body) {
JsonNode jsonNode = objectMapper.readTree(body);
String bidId = jsonNode.get("old").get("bidId").asText();
// 获取状态值可能为null
JsonNode oldStatusNode = jsonNode.get("old").get("outbidstate");
JsonNode newStatusNode = jsonNode.get("new").get("outbidstate");
String oldStatus = oldStatusNode != null ? oldStatusNode.asText() : null;
String newStatus = newStatusNode != null ? newStatusNode.asText() : null;
// 状态发生变化时才通知
if (!StringUtils.equals(oldStatus, newStatus)) {
notifyUpdateData(bidId, jsonNode.get("new"));
}
}
private void notifyUpdateData(String bidId, JsonNode aNew) {
notifySubscribers(bidId, aNew);
}
@SneakyThrows
private void handleNewData(String body) {
JsonNode jsonNode = objectMapper.readTree(body);
String bidId = jsonNode.get("bidId").asText();
notifyNewData(bidId, jsonNode);
}
private void notifyNewData(String bidId, JsonNode jsonNode) {
notifySubscribers(bidId, jsonNode);
}
public void notifySubscribers(String bidId, JsonNode jsonNode) {
List<ZmswpmSubscribeEntity> list =
zmswpmSubscribeRepository.findAll().stream()
.filter(x -> ObjectUtils.notEqual(x.getStatus(), 0))
.toList();
if (list.isEmpty()) {
log.info("no subscribers");
return;
}
list.forEach(
e -> {
try {
sendIfMatch(e, bidId, jsonNode);
} catch (Exception exception) {
log.error("notify subscriber error {} {}", e.getName(), bidId, exception);
}
});
}
@SneakyThrows
private void sendIfMatch(ZmswpmSubscribeEntity e, String bidId, JsonNode jsonNode) {
String queryJson = e.getQueryJson();
CommonQuery commonQuery = new CommonQuery();
commonQuery.setItems(
new ArrayList<>(
objectMapper.readValue(
queryJson, new TypeReference<List<CommonQuery.QueryItem>>() {})));
commonQuery
.getItems()
.add(
new CommonQuery.QueryItem(
false, "bidId", "eq", bidId, "default", null, null, "string",
false));
Page<ZmswpmDto> list = zmswpmService.list(commonQuery);
if (list.isEmpty()) {
log.info("no match for subscriber {} {}", e.getName(), bidId);
return;
}
if (e.getBotScene() != null) {
List<DingtalkBotEntity> bots = e.getBotScene().getDingtalkBots();
for (DingtalkBotEntity bot : bots) {
try {
dingtalkBotService.doSend(
bot,
e.getBotScene().getDingtalkBotTemplate(),
BeanUtil.beanToMap(list.getContent().get(0)));
} catch (Exception exception) {
log.error("send to dingtalk bot error", exception);
}
}
}
}
}

View File

@@ -0,0 +1,23 @@
package cn.lihongjie.coal.zmswpmSubscribe.mapper;
import cn.lihongjie.coal.base.mapper.BaseMapper;
import cn.lihongjie.coal.base.mapper.CommonEntityMapper;
import cn.lihongjie.coal.base.mapper.CommonMapper;
import cn.lihongjie.coal.zmswpmSubscribe.dto.CreateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.UpdateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.ZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.entity.ZmswpmSubscribeEntity;
import org.mapstruct.Mapper;
import org.mapstruct.control.DeepClone;
@Mapper(
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
uses = {CommonMapper.class, CommonEntityMapper.class},
mappingControl = DeepClone.class)
public interface ZmswpmSubscribeMapper
extends BaseMapper<
ZmswpmSubscribeEntity,
ZmswpmSubscribeDto,
CreateZmswpmSubscribeDto,
UpdateZmswpmSubscribeDto> {}

View File

@@ -0,0 +1,15 @@
package cn.lihongjie.coal.zmswpmSubscribe.repository;
import cn.lihongjie.coal.base.dao.BaseRepository;
import cn.lihongjie.coal.zmswpmSubscribe.entity.ZmswpmSubscribeEntity;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ZmswpmSubscribeRepository extends BaseRepository<ZmswpmSubscribeEntity> {
@Query("select false")
boolean isLinked(List<String> ids);
}

View File

@@ -0,0 +1,81 @@
package cn.lihongjie.coal.zmswpmSubscribe.service;
import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.dbFunctions.DbFunctionService;
import cn.lihongjie.coal.exception.BizException;
import cn.lihongjie.coal.zmswpmSubscribe.dto.CreateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.UpdateZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.dto.ZmswpmSubscribeDto;
import cn.lihongjie.coal.zmswpmSubscribe.entity.ZmswpmSubscribeEntity;
import cn.lihongjie.coal.zmswpmSubscribe.mapper.ZmswpmSubscribeMapper;
import cn.lihongjie.coal.zmswpmSubscribe.repository.ZmswpmSubscribeRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Slf4j
@Transactional
public class ZmswpmSubscribeService
extends BaseService<ZmswpmSubscribeEntity, ZmswpmSubscribeRepository> {
@Autowired private ZmswpmSubscribeRepository repository;
@Autowired private ZmswpmSubscribeMapper mapper;
@Autowired private ConversionService conversionService;
@Autowired private DbFunctionService dbFunctionService;
public ZmswpmSubscribeDto create(CreateZmswpmSubscribeDto request) {
ZmswpmSubscribeEntity entity = mapper.toEntity(request);
this.repository.save(entity);
return getById(entity.getId());
}
public ZmswpmSubscribeDto update(UpdateZmswpmSubscribeDto request) {
ZmswpmSubscribeEntity entity = this.repository.get(request.getId());
this.mapper.updateEntity(entity, request);
this.repository.save(entity);
return getById(entity.getId());
}
public void delete(IdRequest request) {
boolean linked = this.repository.isLinked(request.getIds());
if (linked) {
throw new BizException("数据已被关联,无法删除");
}
this.repository.deleteAllById(request.getIds());
}
public ZmswpmSubscribeDto getById(String id) {
ZmswpmSubscribeEntity entity = repository.get(id);
return mapper.toDto(entity);
}
public Page<ZmswpmSubscribeDto> list(CommonQuery query) {
Page<ZmswpmSubscribeEntity> page =
repository.findAll(
query.specification(conversionService),
PageRequest.of(
query.getPageNo(),
query.getPageSize(),
Sort.by(query.getOrders())));
return page.map(this.mapper::toDto);
}
}

View File

@@ -0,0 +1,19 @@
package scripts.dict
import cn.lihongjie.coal.base.dto.CommonQuery
import cn.lihongjie.coal.zmswpmSubscribe.controller.ZmswpmSubscribeController
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.context.ApplicationContext
ApplicationContext ioc = ioc
def controller = ioc.getBean(ZmswpmSubscribeController.class)
def objectMapper = ioc.getBean(ObjectMapper.class) as ObjectMapper
return controller.list(params!=null ? objectMapper.convertValue(params, CommonQuery.class ) : new CommonQuery())