Przeglądaj źródła

fix: 定时同步应用、日志添加客户端IP

lwh 1 tydzień temu
rodzic
commit
63977d4cef

+ 1 - 61
docker-compose.yml

@@ -1,45 +1,4 @@
 services:
-  pig-mysql:
-    build:
-      context: ./db
-    environment:
-      MYSQL_ROOT_HOST: "%"
-      MYSQL_ROOT_PASSWORD: root
-    restart: always
-    container_name: pig-mysql
-    image: pig-mysql
-    ports:
-      - 33306:3306
-    networks:
-      - spring_cloud_default
-
-  pig-redis:
-    image: registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/redis
-    ports:
-      - 36379:6379
-    restart: always
-    container_name: pig-redis
-    hostname: pig-redis
-    networks:
-      - spring_cloud_default
-
-  pig-register:
-    build:
-      context: ./pig-register
-    restart: always
-    ports:
-      - 8848:8848
-      - 9848:9848
-      - 8080:8080
-    environment:
-      MYSQL_HOST: pig-mysql
-      REDIS_HOST: pig-redis
-    container_name: pig-register
-    hostname: pig-register
-    image: pig-register
-    networks:
-      - spring_cloud_default
-
   pig-gateway:
     build:
       context: ./pig-gateway
@@ -49,9 +8,6 @@ services:
     container_name: pig-gateway
     hostname: pig-gateway
     image: pig-gateway
-    environment:
-      REDIS_HOST: pig-redis
-      NACOS_HOST: pig-register
     networks:
       - spring_cloud_default
 
@@ -62,9 +18,6 @@ services:
     container_name: pig-auth
     hostname: pig-auth
     image: pig-auth
-    environment:
-      REDIS_HOST: pig-redis
-      NACOS_HOST: pig-register
     networks:
       - spring_cloud_default
 
@@ -75,10 +28,6 @@ services:
     container_name: pig-upms
     hostname: pig-upms
     image: pig-upms
-    environment:
-      MYSQL_HOST: pig-mysql
-      REDIS_HOST: pig-redis
-      NACOS_HOST: pig-register
     networks:
       - spring_cloud_default
 
@@ -91,8 +40,7 @@ services:
     container_name: pig-monitor
     hostname: pig-monitor
     image: pig-monitor
-    environment:
-      NACOS_HOST: pig-register
+
     networks:
       - spring_cloud_default
 
@@ -103,10 +51,6 @@ services:
     container_name: pig-codegen
     hostname: pig-codegen
     image: pig-codegen
-    environment:
-      MYSQL_HOST: pig-mysql
-      REDIS_HOST: pig-redis
-      NACOS_HOST: pig-register
     networks:
       - spring_cloud_default
 
@@ -116,10 +60,6 @@ services:
     restart: always
     image: pig-quartz
     container_name: pig-quartz
-    environment:
-      MYSQL_HOST: pig-mysql
-      REDIS_HOST: pig-redis
-      NACOS_HOST: pig-register
     networks:
       - spring_cloud_default
 

+ 3 - 0
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/dto/mongo/SaveDeviceInfoDTO.java

@@ -24,6 +24,9 @@ public class SaveDeviceInfoDTO implements Serializable {
 	@NotBlank(message = "客户端ID不能为空")
 	private String clientID;
 
+	@Schema(description = "客户端IP")
+	private String clientIp;
+
 	@Schema(description = "设备信息")
 	private String deviceInfo;
 

+ 1 - 1
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/dto/mongo/SaveTcpMessageDTO.java

@@ -28,7 +28,7 @@ public class SaveTcpMessageDTO implements Serializable {
 	private String msgData;
 
 	@Schema(description = "上报IP", example = "127.0.0.1")
-	private String clientIP;
+	private String clientIp;
 
 	@Schema(description = "上报域名报域名", example = "www.baidu.com")
 	private String clientDomain;;

+ 3 - 2
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/entity/mongo/Device.java

@@ -5,8 +5,6 @@ import lombok.Data;
 import org.springframework.data.annotation.Id;
 import org.springframework.data.mongodb.core.mapping.Document;
 
-import java.time.LocalDateTime;
-import java.util.Date;
 
 /**
  * @author: lwh
@@ -21,6 +19,9 @@ public class Device {
 	@Schema(description = "设备ID")
 	private String id; // MongoDB自动生成的ObjectId
 
+	@Schema(description = "客户端IP")
+	private String clientIp;
+
 	@Schema(description = "客户端ID")
 	private String clientID; // 客户端唯一标识
 

+ 1 - 1
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/entity/mongo/Message.java

@@ -4,7 +4,6 @@ import lombok.Data;
 import org.springframework.data.annotation.Id;
 import org.springframework.data.mongodb.core.mapping.Document;
 
-import java.time.LocalDateTime;
 
 /**
  * @author: lwh
@@ -17,6 +16,7 @@ public class Message {
 	@Id
 	private String id; // MongoDB自动生成的ObjectId
 
+	private String clientIp;
 	private String clientID; // 客户端唯一标识
 	private String msgData; // 消息内容字符串
 	private String reportTime; // 上报时间

+ 21 - 0
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/feign/RemoteMarketingService.java

@@ -0,0 +1,21 @@
+package com.pig4cloud.pig.marketing.api.feign;
+
+
+import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
+import com.pig4cloud.pig.common.core.util.R;
+import com.pig4cloud.pig.common.feign.annotation.NoToken;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+/**
+ * @author: lwh
+ * @date: 2025-09-07
+ * @description: 远程营销模块服务接口
+ */
+@FeignClient(contextId = "remoteMarketingService", value = ServiceNameConstants.MARKETING_SERVICE)
+public interface RemoteMarketingService {
+
+	@NoToken
+	@PostMapping("/app/synced")
+	R syncedAppList();
+}

+ 3 - 0
pig-marketing/pig-marketing-api/src/main/java/com/pig4cloud/pig/marketing/api/vo/mongo/PageDeviceInfoVO.java

@@ -22,6 +22,9 @@ public class PageDeviceInfoVO implements Serializable {
 	@Schema(description = "设备ID")
 	private String id;
 
+	@Schema(description = "客户端IP")
+	private String clientIp;
+
 	@Schema(description = "客户端ID")
 	private String clientID;
 

+ 2 - 0
pig-marketing/pig-marketing-biz/src/main/java/com/pig4cloud/pig/marketing/controller/MarketingAppsController.java

@@ -4,6 +4,7 @@ package com.pig4cloud.pig.marketing.controller;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.pig4cloud.pig.common.core.exception.BusinessException;
 import com.pig4cloud.pig.common.core.util.R;
+import com.pig4cloud.pig.common.security.annotation.Inner;
 import com.pig4cloud.pig.marketing.api.dto.app.*;
 import com.pig4cloud.pig.marketing.api.vo.app.MarketingAppsVO;
 import com.pig4cloud.pig.marketing.api.vo.app.PageMarketingAppsVO;
@@ -120,6 +121,7 @@ public class MarketingAppsController {
 		return res?R.ok():R.failed();
 	}
 
+	@Inner
 	@PostMapping("/synced")
 	@Operation(summary = "同步应用列表")
 	public R syncedAppList() {

+ 67 - 51
pig-marketing/pig-marketing-biz/src/main/java/com/pig4cloud/pig/marketing/service/impl/MarketingAppsServiceImpl.java

@@ -18,10 +18,11 @@ import com.pig4cloud.pig.marketing.api.entity.*;
 import com.pig4cloud.pig.marketing.api.vo.app.*;
 import com.pig4cloud.pig.marketing.mapper.*;
 import com.pig4cloud.pig.marketing.service.MarketingAppsService;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.*;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -41,17 +42,17 @@ import static com.pig4cloud.pig.marketing.api.MarketingConfigConstants.TRIGGER_R
  */
 @Slf4j
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class MarketingAppsServiceImpl implements MarketingAppsService {
 
 
 	// 从配置文件读取URL
-//	@Value("${marketing.app.url}")
-	private static final String getAppListUrl = "http://192.168.3.17:2888/ipa/getApps";
+	@Value("${marketing.app.url}")
+	private String getAppListUrl;
 
 	// 从配置文件读取accessKey
-//	@Value("${marketing.app.access-key}")
-	private static final String accessKey = "4ea5ba93-d222-45dc-862a-1c7fc7789d11";
+	@Value("${marketing.app.access-key}")
+	private String accessKey;
 
 	private final MarketingAppsMapper appsMapper;
 
@@ -281,10 +282,13 @@ public class MarketingAppsServiceImpl implements MarketingAppsService {
 		int deleteCount = 0;
 
 		// 1. 获取lafa服务应用的appId集合
-		Set<String> lafaAppIds = appList.stream()
-				.map(MarketingApps::getAppId)
-				.collect(Collectors.toSet());
-
+		// 1. 获取lafa服务应用的appId集合 - 添加空值检查
+		Set<String> lafaAppIds = new HashSet<>();
+		if (appList != null && !appList.isEmpty()) {
+			lafaAppIds = appList.stream()
+					.map(MarketingApps::getAppId)
+					.collect(Collectors.toSet());
+		}
 		// 2. 查询本地数据库中所有未删除的应用
 		List<MarketingApps> localApps = appsMapper.selectList(new QueryWrapper<>());
 
@@ -293,52 +297,63 @@ public class MarketingAppsServiceImpl implements MarketingAppsService {
 				.collect(Collectors.toMap(MarketingApps::getAppId, app -> app));
 
 		// 4. 获取全局配置
-		AtomicReference<Integer> triggerRule = new AtomicReference<>();
-		AtomicReference<String> triggerNum = new AtomicReference<>("");
+		AtomicReference<Integer> triggerRule = new AtomicReference<>(1);
+		AtomicReference<String> triggerNum = new AtomicReference<>("1");
 		R<ArrayList<SysPublicParamDTO>> ParamDTO = remoteParamService.getParamList(Arrays.asList(TRIGGER_RULE, TRIGGER_NUM));
 
-		ParamDTO.getData().forEach(param -> {
-			if (TRIGGER_RULE.equals(param.getPublicKey())) {
-				triggerRule.set(Integer.valueOf(param.getPublicValue()));
-			} else if (TRIGGER_NUM.equals(param.getPublicKey())) {
-				triggerNum.set(param.getPublicValue());
-			}
-		});
+		// 添加空值检查,防止空指针异常
+		if (ParamDTO != null && ParamDTO.getData() != null) {
+			ParamDTO.getData().forEach(param -> {
+				if (TRIGGER_RULE.equals(param.getPublicKey())) {
+					triggerRule.set(Integer.valueOf(param.getPublicValue()));
+				} else if (TRIGGER_NUM.equals(param.getPublicKey())) {
+					triggerNum.set(param.getPublicValue());
+				}
+			});
+		}
+		if (appList != null) {
+			// 5. 处理新增和更新
+			for (MarketingApps app : appList) {
+				MarketingApps localApp = localAppMap.get(app.getAppId());
 
-		// 5. 处理新增和更新
-		for (MarketingApps app : appList) {
-			MarketingApps localApp = localAppMap.get(app.getAppId());
-
-			if (localApp == null) {
-				// 4.1 本地不存在,新增
-				app.setStatus( true);
-				app.setDomainLimit(false);
-				app.setLaunch( true);
-				app.setTriggerRule(triggerRule.get());
-				app.setTriggerNum(triggerNum.get());
-				appsMapper.insert(app);
-				addCount++;
-			} else {
-				// 4.2 本地存在,判断是否需要更新
-				// 复制ID(本地自增ID)和创建时间(保留原始创建时间)
-				app.setId(localApp.getId());
-
-				// 对比是否有变化
-				if (!isSameApp(app, localApp)) {
-					appsMapper.updateById(app);
-					updateCount++;
+				if (localApp == null) {
+
+					MarketingApps existingApp = appsMapper.selectOne(
+							new QueryWrapper<MarketingApps>().eq("app_id", app.getAppId())
+					);
+
+					if (existingApp == null) {
+						// 4.1 本地不存在,新增
+						app.setStatus(true);
+						app.setDomainLimit(false);
+						app.setLaunch(true);
+						app.setTriggerRule(triggerRule.get());
+						app.setTriggerNum(triggerNum.get());
+						appsMapper.insert(app);
+						addCount++;
+					}
+				} else {
+					// 4.2 本地存在,判断是否需要更新
+					// 复制ID(本地自增ID)和创建时间(保留原始创建时间)
+					app.setId(localApp.getId());
+
+					// 对比是否有变化
+					if (!isSameApp(app, localApp)) {
+						appsMapper.updateById(app);
+						updateCount++;
+					}
 				}
 			}
-		}
 
-		// 5. 处理删除:本地存在但A服务不存在的应用,标记为删除
-		for (MarketingApps localApp : localApps) {
-			if (!lafaAppIds.contains(localApp.getAppId())) {
-				appsMapper.deleteById(localApp);
-				// 删除应用关联的IP、域名
-				appsIpMapper.delete(Wrappers.<MarketingAppsIp>lambdaQuery().eq(MarketingAppsIp::getAppId, localApp.getId()));
-				appsDomainMapper.delete(Wrappers.<MarketingAppsDomain>lambdaQuery().eq(MarketingAppsDomain::getAppId, localApp.getId()));
-				deleteCount++;
+			// 6. 处理删除:本地存在但A服务不存在的应用,标记为删除
+			for (MarketingApps localApp : localApps) {
+				if (!lafaAppIds.contains(localApp.getAppId())) {
+					appsMapper.deleteById(localApp);
+					// 删除应用关联的IP、域名
+					appsIpMapper.delete(Wrappers.<MarketingAppsIp>lambdaQuery().eq(MarketingAppsIp::getAppId, localApp.getId()));
+					appsDomainMapper.delete(Wrappers.<MarketingAppsDomain>lambdaQuery().eq(MarketingAppsDomain::getAppId, localApp.getId()));
+					deleteCount++;
+				}
 			}
 		}
 
@@ -515,7 +530,8 @@ public class MarketingAppsServiceImpl implements MarketingAppsService {
 				Objects.equals(newApp.getAppImg(), oldApp.getAppImg()) &&
 				Objects.equals(newApp.getAppUrl(), oldApp.getAppUrl()) &&
 				Objects.equals(newApp.getBackupUrl(), oldApp.getBackupUrl()) &&
-				Objects.equals(newApp.getDomainType(), oldApp.getDomainType());
+				Objects.equals(newApp.getDomainType(), oldApp.getDomainType()) &&
+				Objects.equals(newApp.getBundle(), oldApp.getBundle());
 	}
 
 	/**

+ 13 - 2
pig-marketing/pig-marketing-biz/src/main/java/com/pig4cloud/pig/marketing/service/impl/TcpDataServiceImpl.java

@@ -70,6 +70,10 @@ import java.util.stream.Collectors;
 	 */
 	@Override
 	public String saveOrUpdateDevice(SaveDeviceInfoDTO reqDto) {
+		if (reqDto.getClientIp() != null) {
+			reqDto.setClientIp(reqDto.getClientIp().split(":")[0]);
+		}
+
 		// 根据客户端ID查询设备信息
 		Query query = new Query(Criteria.where("clientID").is(reqDto.getClientID()));
 		Device existingDevice = mongoTemplate.findOne(query, Device.class);
@@ -77,6 +81,7 @@ import java.util.stream.Collectors;
 		if (existingDevice == null) {
 			// 无数据时直接新增
 			Device device = new Device();
+			device.setClientIp(reqDto.getClientIp());
 			device.setClientID(reqDto.getClientID());
 			device.setDeviceInfo(reqDto.getDeviceInfo());
 			device.setHeadInfo(reqDto.getHeadInfo());
@@ -98,6 +103,7 @@ import java.util.stream.Collectors;
 				if (!StringUtils.isBlank(reqDto.getHeadInfo())) {
 					update.set("headInfo", reqDto.getHeadInfo());
 				}
+				update.set("clientIp", reqDto.getClientIp());
 				// 设置更新时间为当前时间的字符串格式
 				update.set("updateTime", LocalDateTime.now().format(DATE_TIME_FORMATTER));
 
@@ -205,8 +211,13 @@ import java.util.stream.Collectors;
 	 */
 	@Override
 	public String saveMessage(SaveTcpMessageDTO reqDto) {
+		if (reqDto.getClientIp() != null) {
+			reqDto.setClientIp(reqDto.getClientIp().split(":")[0]);
+		}
+
 		Message message = new Message();
 		message.setClientID(reqDto.getClientID());
+		message.setClientIp(reqDto.getClientIp());
 		message.setMsgData(reqDto.getMsgData());
 		message.setReportTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
 		Message save = messageRepository.save(message);
@@ -215,7 +226,7 @@ import java.util.stream.Collectors;
 		String hand = "";
 		if (save.getId() != null) {
 			saveRecordDTO.setPushContent(reqDto.getMsgData());
-			saveRecordDTO.setPushIP(reqDto.getClientIP());
+			saveRecordDTO.setPushIP(reqDto.getClientIp());
 			saveRecordDTO.setPushDomain(reqDto.getClientDomain());
 			saveRecordDTO.setClientId(reqDto.getClientID());
 
@@ -223,7 +234,7 @@ import java.util.stream.Collectors;
 			hand = mktMgmtHandPushService.handPush(saveRecordDTO);
 		}
 
-		log.info("保存推送记录:{}", s);
+		log.info("保存推送记录:{}---{}", s,hand);
 		return save.getId();
 	}
 

+ 1 - 8
pig-marketing/pig-marketing-biz/src/main/resources/application.yml

@@ -20,11 +20,4 @@ spring:
   config:
     import:
       - nacos:application.yml
-      - nacos:${spring.application.name}.yml
-
-marketing:
-  app:
-    url: http://192.168.3.17:2888/ipa/getApps
-    access-key: 4ea5ba93-d222-45dc-862a-1c7fc7789d11
-
-
+      - nacos:${spring.application.name}.yml

+ 4 - 0
pig-visual/pig-quartz/pom.xml

@@ -74,6 +74,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-undertow</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.pig4cloud</groupId>
+            <artifactId>pig-marketing-api</artifactId>
+        </dependency>
     </dependencies>
 
     <profiles>

+ 31 - 0
pig-visual/pig-quartz/src/main/java/com/pig4cloud/pig/daemon/quartz/task/MktModeTask.java

@@ -0,0 +1,31 @@
+package com.pig4cloud.pig.daemon.quartz.task;
+
+
+import com.pig4cloud.pig.common.core.util.R;
+import com.pig4cloud.pig.daemon.quartz.constants.PigQuartzEnum;
+import com.pig4cloud.pig.marketing.api.feign.RemoteMarketingService;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @author: lwh
+ * @date: 2025-09-07
+ * @description: 营销模块定时任务
+ */
+@Slf4j
+@Component("marketing")
+public class MktModeTask {
+
+	@Autowired
+	private RemoteMarketingService marketingAppsService;
+
+	// 同步应用列表
+	@SneakyThrows
+	public String asyncAppList() {
+		R r = marketingAppsService.syncedAppList();
+		return PigQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
+	}
+}