chen.yinxiang
Committed by Jiaqi Xia

农信小程序订阅消息记录数据库

...@@ -11,6 +11,7 @@ import brave.propagation.TraceContext; ...@@ -11,6 +11,7 @@ import brave.propagation.TraceContext;
11 import brave.sampler.Sampler; 11 import brave.sampler.Sampler;
12 import com.tianting.infoloop.service.grpc.MealOrderGrpcService; 12 import com.tianting.infoloop.service.grpc.MealOrderGrpcService;
13 import com.tianting.infoloop.service.grpc.OrderGrpcService; 13 import com.tianting.infoloop.service.grpc.OrderGrpcService;
14 +import com.tianting.infoloop.service.grpc.OrderSubscriptionMessageGrpcService;
14 import io.grpc.Server; 15 import io.grpc.Server;
15 import io.grpc.ServerInterceptor; 16 import io.grpc.ServerInterceptor;
16 import io.grpc.ServerInterceptors; 17 import io.grpc.ServerInterceptors;
...@@ -66,11 +67,13 @@ public class AppConfig implements ApplicationContextAware { ...@@ -66,11 +67,13 @@ public class AppConfig implements ApplicationContextAware {
66 public Server serviceServer(@Value(SERVICE_PORT) final int port, 67 public Server serviceServer(@Value(SERVICE_PORT) final int port,
67 final ServerInterceptor serverInterceptor, 68 final ServerInterceptor serverInterceptor,
68 final OrderGrpcService orderGrpcService, 69 final OrderGrpcService orderGrpcService,
69 - final MealOrderGrpcService mealOrderGrpcService) { 70 + final MealOrderGrpcService mealOrderGrpcService,
71 + final OrderSubscriptionMessageGrpcService orderSubscriptionMessageGrpcService) {
70 return NettyServerBuilder 72 return NettyServerBuilder
71 .forPort(port) 73 .forPort(port)
72 .addService(ServerInterceptors.intercept(orderGrpcService, serverInterceptor)) 74 .addService(ServerInterceptors.intercept(orderGrpcService, serverInterceptor))
73 .addService(ServerInterceptors.intercept(mealOrderGrpcService, serverInterceptor)) 75 .addService(ServerInterceptors.intercept(mealOrderGrpcService, serverInterceptor))
76 + .addService(ServerInterceptors.intercept(orderSubscriptionMessageGrpcService, serverInterceptor))
74 .build(); 77 .build();
75 } 78 }
76 } 79 }
......
1 +package com.tianting.infoloop.mapper;
2 +
3 +import com.tianting.infoloop.inject.MyBaseMapper;
4 +import com.tianting.infoloop.model.db.OrderSubscriptionMessageDb;
5 +import org.apache.ibatis.annotations.Delete;
6 +import org.apache.ibatis.annotations.Param;
7 +
8 +import java.util.List;
9 +
10 +public interface OrderSubscriptionMessageMapper extends MyBaseMapper<OrderSubscriptionMessageDb> {
11 +
12 + /**
13 + * 批量物理删除(绕过逻辑删除)
14 + */
15 + @Delete("<script>" +
16 + "DELETE FROM order_subscription_message " +
17 + "WHERE enterpriseId = #{enterpriseId} " +
18 + "AND id IN " +
19 + "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
20 + "#{id}" +
21 + "</foreach>" +
22 + "</script>")
23 + int physicalDeleteByIds(@Param("ids") List<Long> ids, @Param("enterpriseId") int enterpriseId);
24 +}
25 +
1 +package com.tianting.infoloop.model.db;
2 +
3 +import com.baomidou.mybatisplus.annotation.FieldFill;
4 +import com.baomidou.mybatisplus.annotation.IdType;
5 +import com.baomidou.mybatisplus.annotation.TableField;
6 +import com.baomidou.mybatisplus.annotation.TableId;
7 +import com.baomidou.mybatisplus.annotation.TableLogic;
8 +import com.baomidou.mybatisplus.annotation.TableName;
9 +import com.baomidou.mybatisplus.extension.activerecord.Model;
10 +import lombok.Data;
11 +import lombok.EqualsAndHashCode;
12 +import lombok.experimental.Accessors;
13 +
14 +import java.time.LocalDateTime;
15 +
16 +/**
17 + * order subscription message DB
18 + * @TableName order_subscription_message
19 + */
20 +@Data
21 +@Accessors(chain = true)
22 +@EqualsAndHashCode(callSuper = true)
23 +@TableName(value = "order_subscription_message")
24 +public class OrderSubscriptionMessageDb extends Model<OrderSubscriptionMessageDb> {
25 + /**
26 + * 主键ID
27 + */
28 + @TableId(type = IdType.AUTO)
29 + private Long id;
30 + /**
31 + * 企业ID
32 + */
33 + private Integer enterpriseId;
34 + /**
35 + * 订餐用户ID(dinerId)
36 + */
37 + private Integer dinerId;
38 + /**
39 + * 微信用户OpenID
40 + */
41 + private String openId;
42 + /**
43 + * 订阅消息模板ID
44 + */
45 + private String templateId;
46 + /**
47 + * 跳转路径(小程序 path)
48 + */
49 + private String jumpPath;
50 + /**
51 + * 关联的订餐周期开始时间(精确到秒)
52 + */
53 + private LocalDateTime orderPeriodStartDate;
54 + /**
55 + * 关联的订餐周期结束时间(精确到秒)
56 + */
57 + private LocalDateTime orderPeriodEndDate;
58 + /**
59 + * 授权时间(创建时间)
60 + */
61 + @TableField(fill = FieldFill.INSERT)
62 + private LocalDateTime createdAt;
63 + /**
64 + * 更新时间
65 + */
66 + @TableField(fill = FieldFill.INSERT_UPDATE)
67 + private LocalDateTime updatedAt;
68 + /**
69 + * 授权状态,0-待使用(已授权但未发送),1-已使用(已发送,逻辑删除)
70 + */
71 + @TableLogic
72 + private Boolean isDeleted;
73 +}
74 +
1 +package com.tianting.infoloop.service;
2 +
3 +import com.baomidou.mybatisplus.extension.service.IService;
4 +import com.infoloop.tianting.ordersubscriptionmessageservice.CreateOrderSubscriptionMessageRpcRequest;
5 +import com.infoloop.tianting.ordersubscriptionmessageservice.GetUserOrderSubscriptionMessageHistoryRpcRequest;
6 +import com.tianting.infoloop.model.db.OrderSubscriptionMessageDb;
7 +
8 +import java.util.List;
9 +
10 +public interface OrderSubscriptionMessageDbService extends IService<OrderSubscriptionMessageDb> {
11 +
12 + OrderSubscriptionMessageDb createOrderSubscriptionMessage(CreateOrderSubscriptionMessageRpcRequest request);
13 +
14 + List<OrderSubscriptionMessageDb> getUserOrderSubscriptionMessageHistory(GetUserOrderSubscriptionMessageHistoryRpcRequest request);
15 +
16 + /**
17 + * 批量逻辑删除授权记录(表示已使用)
18 + * @param ids 要删除的记录ID列表
19 + * @param enterpriseId 企业ID
20 + * @return 受影响的行数
21 + */
22 + int batchDeleteByIds(java.util.List<Long> ids, int enterpriseId);
23 +
24 + /**
25 + * 批量物理删除授权记录
26 + * @param ids 要删除的记录ID列表
27 + * @param enterpriseId 企业ID
28 + * @return 受影响的行数
29 + */
30 + int batchPhysicalDeleteByIds(java.util.List<Long> ids, int enterpriseId);
31 +}
32 +
1 +package com.tianting.infoloop.service.grpc;
2 +
3 +import com.baomidou.dynamic.datasource.annotation.DS;
4 +import com.infoloop.tianting.ordersubscriptionmessageservice.BatchDeleteOrderSubscriptionMessagesByIdsRpcRequest;
5 +import com.infoloop.tianting.ordersubscriptionmessageservice.BatchDeleteOrderSubscriptionMessagesByIdsRpcResponse;
6 +import com.infoloop.tianting.ordersubscriptionmessageservice.BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcRequest;
7 +import com.infoloop.tianting.ordersubscriptionmessageservice.BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcResponse;
8 +import com.infoloop.tianting.ordersubscriptionmessageservice.CreateOrderSubscriptionMessageRpcRequest;
9 +import com.infoloop.tianting.ordersubscriptionmessageservice.CreateOrderSubscriptionMessageRpcResponse;
10 +import com.infoloop.tianting.ordersubscriptionmessageservice.GetUserOrderSubscriptionMessageHistoryRpcRequest;
11 +import com.infoloop.tianting.ordersubscriptionmessageservice.GetUserOrderSubscriptionMessageHistoryRpcResponse;
12 +import com.infoloop.tianting.ordersubscriptionmessageservice.OrderSubscriptionMessageRpcResponse;
13 +import com.infoloop.tianting.ordersubscriptionmessageservice.OrderSubscriptionMessageServiceRpcGrpc;
14 +import com.tianting.infoloop.model.db.OrderSubscriptionMessageDb;
15 +import com.tianting.infoloop.service.OrderSubscriptionMessageDbService;
16 +import io.grpc.Status;
17 +import io.grpc.stub.StreamObserver;
18 +import lombok.RequiredArgsConstructor;
19 +import lombok.extern.slf4j.Slf4j;
20 +import org.springframework.beans.factory.annotation.Autowired;
21 +import org.springframework.stereotype.Service;
22 +
23 +import java.time.ZoneId;
24 +import java.util.stream.Collectors;
25 +
26 +import static com.tianting.infoloop.constants.ConfigConstants.DATA_SOURCE_MASTER;
27 +
28 +@Slf4j
29 +@Service
30 +@RequiredArgsConstructor(onConstructor_ = @Autowired)
31 +public class OrderSubscriptionMessageGrpcService extends OrderSubscriptionMessageServiceRpcGrpc.OrderSubscriptionMessageServiceRpcImplBase {
32 + private final OrderSubscriptionMessageDbService orderSubscriptionMessageDbService;
33 +
34 + @Override
35 + @DS(DATA_SOURCE_MASTER)
36 + public void createOrderSubscriptionMessage(final CreateOrderSubscriptionMessageRpcRequest request,
37 + final StreamObserver<CreateOrderSubscriptionMessageRpcResponse> responseObserver) {
38 + final var builder = CreateOrderSubscriptionMessageRpcResponse.newBuilder();
39 + try {
40 + final var data = orderSubscriptionMessageDbService.createOrderSubscriptionMessage(request);
41 + builder.setId(data.getId());
42 + } catch (final Exception e) {
43 + log.error("createOrderSubscriptionMessage error;", e);
44 + responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
45 + return;
46 + }
47 + responseObserver.onNext(builder.build());
48 + responseObserver.onCompleted();
49 + }
50 +
51 + @Override
52 + @DS(DATA_SOURCE_MASTER)
53 + public void getUserOrderSubscriptionMessageHistory(final GetUserOrderSubscriptionMessageHistoryRpcRequest request,
54 + final StreamObserver<GetUserOrderSubscriptionMessageHistoryRpcResponse> responseObserver) {
55 + final var builder = GetUserOrderSubscriptionMessageHistoryRpcResponse.newBuilder();
56 + try {
57 + final var list = orderSubscriptionMessageDbService.getUserOrderSubscriptionMessageHistory(request);
58 + builder.addAllResponse(list.stream()
59 + .map(this::convertToRpcResponse)
60 + .collect(Collectors.toList()));
61 + } catch (final Exception e) {
62 + log.error("getUserOrderSubscriptionMessageHistory error;", e);
63 + responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
64 + return;
65 + }
66 + responseObserver.onNext(builder.build());
67 + responseObserver.onCompleted();
68 + }
69 +
70 + private OrderSubscriptionMessageRpcResponse convertToRpcResponse(OrderSubscriptionMessageDb db) {
71 + OrderSubscriptionMessageRpcResponse.Builder builder = OrderSubscriptionMessageRpcResponse.newBuilder();
72 + builder.setId(db.getId());
73 +
74 + if (db.getJumpPath() != null) {
75 + builder.setJumpPath(db.getJumpPath());
76 + }
77 +
78 + // 转换LocalDateTime为时间戳(毫秒),与项目中其他时间字段保持一致
79 + if (db.getOrderPeriodStartDate() != null) {
80 + long timestamp = db.getOrderPeriodStartDate().atZone(ZoneId.systemDefault())
81 + .toInstant()
82 + .toEpochMilli();
83 + builder.setOrderPeriodStartDate(timestamp);
84 + }
85 +
86 + if (db.getOrderPeriodEndDate() != null) {
87 + long timestamp = db.getOrderPeriodEndDate().atZone(ZoneId.systemDefault())
88 + .toInstant()
89 + .toEpochMilli();
90 + builder.setOrderPeriodEndDate(timestamp);
91 + }
92 +
93 + // 转换LocalDateTime为时间戳(毫秒)
94 + if (db.getCreatedAt() != null) {
95 + long timestamp = db.getCreatedAt().atZone(ZoneId.systemDefault())
96 + .toInstant()
97 + .toEpochMilli();
98 + builder.setCreatedAt(timestamp);
99 + }
100 +
101 + builder.setIsDeleted(db.getIsDeleted() != null && db.getIsDeleted());
102 + return builder.build();
103 + }
104 +
105 + @Override
106 + @DS(DATA_SOURCE_MASTER)
107 + public void batchDeleteOrderSubscriptionMessagesByIds(final BatchDeleteOrderSubscriptionMessagesByIdsRpcRequest request,
108 + final StreamObserver<BatchDeleteOrderSubscriptionMessagesByIdsRpcResponse> responseObserver) {
109 + final var builder = BatchDeleteOrderSubscriptionMessagesByIdsRpcResponse.newBuilder();
110 + try {
111 + final int affectedRows = orderSubscriptionMessageDbService.batchDeleteByIds(
112 + request.getIdsList(),
113 + request.getEnterpriseId());
114 + builder.setAffectedRows(affectedRows);
115 + } catch (final Exception e) {
116 + log.error("batchDeleteOrderSubscriptionMessagesByIds error;", e);
117 + responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
118 + return;
119 + }
120 + responseObserver.onNext(builder.build());
121 + responseObserver.onCompleted();
122 + }
123 +
124 + @Override
125 + @DS(DATA_SOURCE_MASTER)
126 + public void batchPhysicalDeleteOrderSubscriptionMessagesByIds(
127 + final BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcRequest request,
128 + final StreamObserver<BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcResponse> responseObserver) {
129 + final var builder = BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcResponse.newBuilder();
130 + try {
131 + final int affectedRows = orderSubscriptionMessageDbService.batchPhysicalDeleteByIds(
132 + request.getIdsList(),
133 + request.getEnterpriseId());
134 + builder.setAffectedRows(affectedRows);
135 + } catch (final Exception e) {
136 + log.error("batchPhysicalDeleteOrderSubscriptionMessagesByIds error;", e);
137 + responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());
138 + return;
139 + }
140 + responseObserver.onNext(builder.build());
141 + responseObserver.onCompleted();
142 + }
143 +}
144 +
1 +package com.tianting.infoloop.service.impl;
2 +
3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
5 +import com.infoloop.tianting.ordersubscriptionmessageservice.CreateOrderSubscriptionMessageRpcRequest;
6 +import com.infoloop.tianting.ordersubscriptionmessageservice.GetUserOrderSubscriptionMessageHistoryRpcRequest;
7 +import com.tianting.infoloop.mapper.OrderSubscriptionMessageMapper;
8 +import com.tianting.infoloop.model.db.OrderSubscriptionMessageDb;
9 +import com.tianting.infoloop.service.OrderSubscriptionMessageDbService;
10 +import com.tianting.infoloop.utils.exception.ErrorCodeConstants;
11 +import com.tianting.infoloop.utils.exception.ServiceExceptionUtil;
12 +import lombok.RequiredArgsConstructor;
13 +import lombok.extern.slf4j.Slf4j;
14 +import org.springframework.beans.factory.annotation.Autowired;
15 +import org.springframework.stereotype.Service;
16 +
17 +import java.time.Instant;
18 +import java.time.LocalDateTime;
19 +import java.time.ZoneId;
20 +import java.util.List;
21 +
22 +@Slf4j
23 +@Service
24 +@RequiredArgsConstructor(onConstructor_ = @Autowired)
25 +public class OrderSubscriptionMessageDbServiceImpl extends ServiceImpl<OrderSubscriptionMessageMapper, OrderSubscriptionMessageDb> implements OrderSubscriptionMessageDbService {
26 +
27 + @Override
28 + public OrderSubscriptionMessageDb createOrderSubscriptionMessage(CreateOrderSubscriptionMessageRpcRequest request) {
29 + OrderSubscriptionMessageDb orderSubscriptionMessageDb = new OrderSubscriptionMessageDb();
30 + orderSubscriptionMessageDb.setEnterpriseId(request.getEnterpriseId());
31 + if (request.getDinerId() != 0) {
32 + orderSubscriptionMessageDb.setDinerId(request.getDinerId());
33 + }
34 + orderSubscriptionMessageDb.setOpenId(request.getOpenId());
35 + orderSubscriptionMessageDb.setTemplateId(request.getTemplateId());
36 + if (!request.getJumpPath().isEmpty()) {
37 + orderSubscriptionMessageDb.setJumpPath(request.getJumpPath());
38 + }
39 +
40 + // 转换时间戳为LocalDateTime(精确到秒),与项目中其他时间字段保持一致
41 + LocalDateTime orderPeriodStartDate = Instant.ofEpochMilli(request.getOrderPeriodStartDate())
42 + .atZone(ZoneId.systemDefault())
43 + .toLocalDateTime();
44 + orderSubscriptionMessageDb.setOrderPeriodStartDate(orderPeriodStartDate);
45 +
46 + if (request.getOrderPeriodEndDate() > 0) {
47 + LocalDateTime orderPeriodEndDate = Instant.ofEpochMilli(request.getOrderPeriodEndDate())
48 + .atZone(ZoneId.systemDefault())
49 + .toLocalDateTime();
50 + orderSubscriptionMessageDb.setOrderPeriodEndDate(orderPeriodEndDate);
51 + }
52 +
53 + boolean res = this.save(orderSubscriptionMessageDb);
54 + if (!res) {
55 + log.error("创建订阅消息授权记录失败, request: {}", request);
56 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_GEN_FAIL);
57 + }
58 + return orderSubscriptionMessageDb;
59 + }
60 +
61 + @Override
62 + public List<OrderSubscriptionMessageDb> getUserOrderSubscriptionMessageHistory(GetUserOrderSubscriptionMessageHistoryRpcRequest request) {
63 + LambdaQueryWrapper<OrderSubscriptionMessageDb> queryWrapper = new LambdaQueryWrapper<>();
64 + queryWrapper.eq(OrderSubscriptionMessageDb::getEnterpriseId, request.getEnterpriseId());
65 + queryWrapper.eq(OrderSubscriptionMessageDb::getOpenId, request.getOpenId());
66 +
67 + // 如果传入了 orderPeriodStartDate,查询大于等于该值的记录
68 + if (request.getOrderPeriodStartDate() > 0) {
69 + LocalDateTime orderPeriodStartDate = Instant.ofEpochMilli(request.getOrderPeriodStartDate())
70 + .atZone(ZoneId.systemDefault())
71 + .toLocalDateTime();
72 + queryWrapper.ge(OrderSubscriptionMessageDb::getOrderPeriodStartDate, orderPeriodStartDate);
73 + }
74 +
75 + queryWrapper.orderByDesc(OrderSubscriptionMessageDb::getCreatedAt);
76 + return this.list(queryWrapper);
77 + }
78 +
79 + @Override
80 + public int batchDeleteByIds(java.util.List<Long> ids, int enterpriseId) {
81 + if (ids == null || ids.isEmpty()) {
82 + return 0;
83 + }
84 + LambdaQueryWrapper<OrderSubscriptionMessageDb> queryWrapper = new LambdaQueryWrapper<>();
85 + queryWrapper.eq(OrderSubscriptionMessageDb::getEnterpriseId, enterpriseId);
86 + queryWrapper.in(OrderSubscriptionMessageDb::getId, ids);
87 + // 逻辑删除(使用 MyBatis-Plus 的 @TableLogic)
88 + return this.remove(queryWrapper) ? ids.size() : 0;
89 + }
90 +
91 + @Override
92 + public int batchPhysicalDeleteByIds(java.util.List<Long> ids, int enterpriseId) {
93 + if (ids == null || ids.isEmpty()) {
94 + return 0;
95 + }
96 + // 物理删除(使用 Mapper 中的 SQL,绕过逻辑删除)
97 + return this.baseMapper.physicalDeleteByIds(ids, enterpriseId);
98 + }
99 +}
100 +
1 +syntax = "proto3";
2 +
3 +option java_multiple_files = true;
4 +option java_package = "com.infoloop.tianting.ordersubscriptionmessageservice";
5 +option java_outer_classname = "OrderSubscriptionMessageServiceProto";
6 +option objc_class_prefix = "OP";
7 +
8 +package com.infoloop.tianting.ordersubscriptionmessageservice;
9 +
10 +service OrderSubscriptionMessageServiceRpc {
11 + // 创建订阅消息授权
12 + rpc CreateOrderSubscriptionMessage (CreateOrderSubscriptionMessageRpcRequest) returns (CreateOrderSubscriptionMessageRpcResponse) {}
13 +
14 + // 查询用户授权历史
15 + rpc GetUserOrderSubscriptionMessageHistory (GetUserOrderSubscriptionMessageHistoryRpcRequest) returns (GetUserOrderSubscriptionMessageHistoryRpcResponse) {}
16 +
17 + // 批量逻辑删除授权记录(表示已使用)
18 + rpc BatchDeleteOrderSubscriptionMessagesByIds (BatchDeleteOrderSubscriptionMessagesByIdsRpcRequest) returns (BatchDeleteOrderSubscriptionMessagesByIdsRpcResponse) {}
19 +
20 + // 批量物理删除授权记录
21 + rpc BatchPhysicalDeleteOrderSubscriptionMessagesByIds (BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcRequest) returns (BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcResponse) {}
22 +}
23 +
24 +// 创建订阅消息授权请求
25 +message CreateOrderSubscriptionMessageRpcRequest {
26 + int32 enterpriseId = 1;
27 + int32 dinerId = 2;
28 + string openId = 3;
29 + string templateId = 4;
30 + int64 orderPeriodStartDate = 5; // Unix 时间戳(毫秒),精确到秒
31 + string jumpPath = 6; // 跳转路径(小程序 path),可选
32 + int64 orderPeriodEndDate = 7; // Unix 时间戳(毫秒),精确到秒,可选
33 +}
34 +
35 +// 创建订阅消息授权响应
36 +message CreateOrderSubscriptionMessageRpcResponse {
37 + int64 id = 1;
38 +}
39 +
40 +// 查询用户授权历史请求
41 +message GetUserOrderSubscriptionMessageHistoryRpcRequest {
42 + int32 enterpriseId = 1;
43 + string openId = 2;
44 + int64 orderPeriodStartDate = 3; // Unix 时间戳(毫秒),精确到秒,可选,如果传入则查询大于等于该值的记录
45 +}
46 +
47 +// 订阅消息授权记录
48 +message OrderSubscriptionMessageRpcResponse {
49 + int64 id = 1;
50 + int64 orderPeriodStartDate = 2; // Unix 时间戳(毫秒),精确到秒
51 + int64 createdAt = 3; // Unix 时间戳(毫秒)
52 + bool isDeleted = 4;
53 + string jumpPath = 5; // 跳转路径(小程序 path),可选
54 + int64 orderPeriodEndDate = 6; // Unix 时间戳(毫秒),精确到秒,可选
55 +}
56 +
57 +// 查询用户授权历史响应
58 +message GetUserOrderSubscriptionMessageHistoryRpcResponse {
59 + repeated OrderSubscriptionMessageRpcResponse response = 1;
60 +}
61 +
62 +// 批量逻辑删除授权记录请求
63 +message BatchDeleteOrderSubscriptionMessagesByIdsRpcRequest {
64 + int32 enterpriseId = 1;
65 + repeated int64 ids = 2; // 要删除的记录ID列表
66 +}
67 +
68 +// 批量逻辑删除授权记录响应
69 +message BatchDeleteOrderSubscriptionMessagesByIdsRpcResponse {
70 + int32 affectedRows = 1; // 受影响的行数
71 +}
72 +
73 +// 批量物理删除授权记录请求
74 +message BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcRequest {
75 + int32 enterpriseId = 1;
76 + repeated int64 ids = 2; // 要删除的记录ID列表
77 +}
78 +
79 +// 批量物理删除授权记录响应
80 +message BatchPhysicalDeleteOrderSubscriptionMessagesByIdsRpcResponse {
81 + int32 affectedRows = 1; // 受影响的行数
82 +}
83 +