商瑞9.7客户端代码提交
This commit is contained in:
parent
46a5af7d47
commit
2d6404624e
126
client/pom.xml
Normal file
126
client/pom.xml
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.small</groupId>
|
||||
<artifactId>client</artifactId>
|
||||
<version>v1</version>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.0.RELEASE</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<hutool.version>5.8.20</hutool.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<!--jdbc数据库-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>9.4.1.jre8</version> <!-- -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<!-- 指定仓库为阿里云与阿帕奇 -->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>ali-maven</id>
|
||||
<url>https://maven.aliyun.com/repository/central</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repo.maven.apache.org</id>
|
||||
<url>https://repo.maven.apache.org/maven2</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 生成可执行JAR -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- 指定JDK版本 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source> <!-- Spring Boot 3.x需要JDK17+ -->
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
21
client/readme.txt
Normal file
21
client/readme.txt
Normal file
@ -0,0 +1,21 @@
|
||||
本系统主要安装在客户端
|
||||
主要有以下几个功能
|
||||
|
||||
第一阶段
|
||||
1、通过http获取远程数据小发服务配置,基础数据包括主要包括数据库地址ip,数据库名称,数据库密码,以及同步定时时间
|
||||
|
||||
2.采集本地数据库,通过多线程调用同步接口,同步商品,种类,会员
|
||||
|
||||
第二阶段
|
||||
由于系统的数据同步存在性能瓶颈,需要使用文件传输的方式同步数据,
|
||||
文件采用分页形式同步数据,每一页使用一个文件,服务器解析文件采用多线程解析方式解析
|
||||
|
||||
|
||||
|
||||
打包功能更,需要写一个shell脚本自动打包放到服务器供给下载和java的jkd安装包,这些下载放到后端的网页端,暴露下载地址
|
||||
|
||||
todo
|
||||
1、通过http获取dataInfo没有写
|
||||
2、文件传输没有写
|
||||
3.商品同步没有写
|
||||
4.商品分类同步没有写
|
||||
48
client/src/main/java/com/small/client/Cache/CommonCache.java
Normal file
48
client/src/main/java/com/small/client/Cache/CommonCache.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.small.client.Cache;
|
||||
|
||||
import cn.hutool.cache.Cache;
|
||||
import cn.hutool.cache.impl.FIFOCache;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import com.small.client.dto.BrandModel;
|
||||
import com.small.client.dto.SpecPriceDto;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用于本地缓存
|
||||
*/
|
||||
@Component
|
||||
public class CommonCache {
|
||||
public final static String CACHE_CATEGROY = "CACHE_CATEGROY";//分类缓存
|
||||
|
||||
private Cache<String, String> cache =new FIFOCache<>(20000);
|
||||
|
||||
private Cache<String, List<SpecPriceDto>> spriceCache =new FIFOCache<>(20);
|
||||
|
||||
private Cache<String, List<BrandModel>> brandCahce =new FIFOCache<>(20);
|
||||
|
||||
public void put(String key, String value) {
|
||||
cache.put(key, value, DateUnit.MINUTE.getMillis()*20);
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
return cache.get(key);
|
||||
}
|
||||
|
||||
public void putSpecPrice(String key, List<SpecPriceDto> value) {
|
||||
spriceCache.put(key, value, DateUnit.MINUTE.getMillis()*20);
|
||||
}
|
||||
|
||||
public List<SpecPriceDto> getSpecPrice(String key) {
|
||||
return spriceCache.get(key);
|
||||
}
|
||||
|
||||
public List<BrandModel> getBrandCahce(String key) {
|
||||
return brandCahce.get(key);
|
||||
}
|
||||
|
||||
public void setBrandCahce(String key, List<BrandModel> value) {
|
||||
brandCahce.put(key, value, DateUnit.MINUTE.getMillis()*20);
|
||||
}
|
||||
}
|
||||
27
client/src/main/java/com/small/client/ClientApplication.java
Normal file
27
client/src/main/java/com/small/client/ClientApplication.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.small.client;
|
||||
|
||||
import com.small.client.Utils.JarPathUtil;
|
||||
import com.small.client.service.SxDataService;
|
||||
import com.small.client.service.WebClientService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
@SpringBootApplication
|
||||
@Slf4j
|
||||
public class ClientApplication{
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ClientApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.small.client.Schedule;
|
||||
|
||||
import com.small.client.dto.CommentModel;
|
||||
import com.small.client.dto.DataBaseInfo;
|
||||
import com.small.client.service.SxDataService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.support.CronTrigger;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DynamicTaskScheduler {
|
||||
private final TaskScheduler taskScheduler;
|
||||
private final SxDataService sxDataService;
|
||||
private final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean isRuning =false;
|
||||
|
||||
@Autowired
|
||||
public DynamicTaskScheduler(TaskScheduler taskScheduler, SxDataService sxDataService) {
|
||||
this.taskScheduler = taskScheduler;
|
||||
this.sxDataService = sxDataService;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initTasks() {
|
||||
refreshTasks();
|
||||
// 每5分钟检查一次数据库更新
|
||||
taskScheduler.scheduleAtFixedRate(this::refreshTasks, Duration.ofHours(1));
|
||||
}
|
||||
|
||||
public void refreshTasks() {
|
||||
if(!isRuning){
|
||||
sxDataService.checkForUpdates();//检查app更新
|
||||
}
|
||||
CommentModel commentModel =sxDataService.getCommentModel();
|
||||
DataBaseInfo enabledTask = sxDataService.getDataBaseInfo(commentModel);
|
||||
|
||||
List<DataBaseInfo> enabledTasks=new ArrayList<>();
|
||||
enabledTasks.add(enabledTask);
|
||||
// 移除已禁用或删除的任务
|
||||
scheduledTasks.keySet().removeIf(taskKey ->
|
||||
enabledTasks.stream().noneMatch(task -> task.getDataBaseName().equals(taskKey)));
|
||||
|
||||
// 新增或更新任务
|
||||
enabledTasks.forEach(task -> {
|
||||
if (!scheduledTasks.containsKey(task.getDataBaseName()) ||
|
||||
isCronModified(task)) {
|
||||
cancelExistingTask(task.getDataBaseName());
|
||||
scheduleTask(task,commentModel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void scheduleTask(DataBaseInfo task, CommentModel commentModel) {
|
||||
ScheduledFuture<?> future = taskScheduler.schedule(
|
||||
() -> executeTask(task.getDataBaseName(),commentModel),
|
||||
new CronTrigger(task.getCronExpression())
|
||||
);
|
||||
scheduledTasks.put(task.getDataBaseName(), future);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务逻辑执行
|
||||
* @param taskKey
|
||||
*/
|
||||
private void executeTask(String taskKey, CommentModel commentModel) {
|
||||
isRuning=true;
|
||||
log.info("execute task key:{}, commentModel:{}", taskKey, commentModel);
|
||||
if(commentModel==null){
|
||||
commentModel =sxDataService.getCommentModel();
|
||||
}
|
||||
if(StringUtils.isEmpty(commentModel.getSyncTime())){
|
||||
commentModel =sxDataService.getCommentModel();
|
||||
}
|
||||
DataBaseInfo dataBaseInfo=sxDataService.getDataBaseInfo(commentModel);
|
||||
sxDataService.SyncBranchList(dataBaseInfo,commentModel);
|
||||
sxDataService.SyncCategory(dataBaseInfo,commentModel);
|
||||
sxDataService.SyncGoods(dataBaseInfo,commentModel);//todo 暂时同步全部的商品如果后期修改,需要增加服务器的字段test
|
||||
sxDataService.SyncVipList(dataBaseInfo,commentModel);
|
||||
isRuning=false;
|
||||
}
|
||||
|
||||
private void cancelExistingTask(String taskKey) {
|
||||
Optional.ofNullable(scheduledTasks.remove(taskKey))
|
||||
.ifPresent(future -> future.cancel(false));
|
||||
}
|
||||
|
||||
private boolean isCronModified(DataBaseInfo newTask) {
|
||||
DataBaseInfo dataBaseInfo= sxDataService.getDataBaseInfo(sxDataService.getCommentModel());
|
||||
return scheduledTasks.containsKey(newTask.getDataBaseName()) &&
|
||||
!dataBaseInfo.getCronExpression().equals(newTask.getCronExpression());
|
||||
}
|
||||
}
|
||||
98
client/src/main/java/com/small/client/Utils/CommonUtil.java
Normal file
98
client/src/main/java/com/small/client/Utils/CommonUtil.java
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.small.client.Utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
|
||||
public class CommonUtil {
|
||||
|
||||
private final static String apiUrl = "http://4ei8850868ux.vicp.fun";
|
||||
|
||||
public static JSONObject sendPostRequestToSiXun(String urlPath, JSONObject params) {
|
||||
String resp = HttpUtil.post(apiUrl + urlPath, params.toString());
|
||||
if (StrUtil.isBlank(resp)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject respObj = JSONUtil.parseObj(resp);
|
||||
|
||||
return respObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据总条数和分页大小,求页数
|
||||
*
|
||||
* @param total
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
public static Integer getPagesCount(Integer total, Integer pageSize) {
|
||||
if (total == null || pageSize == null || pageSize <= 0 || total <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pagesCount = 0;
|
||||
pagesCount = total / pageSize;
|
||||
|
||||
if (total % pageSize > 0) {
|
||||
// 有余数
|
||||
pagesCount++;
|
||||
} else {
|
||||
if (pagesCount == 0) {
|
||||
pagesCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return pagesCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口是否成功执行返回
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
public static Boolean isSuccess(JSONObject jsonObject) {
|
||||
if (jsonObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return jsonObject.get("code") != null && jsonObject.getStr("code").equals("0");
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口是否成功执行返回
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
public static Boolean hasSuccessData(JSONObject jsonObject) {
|
||||
if (jsonObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return jsonObject.get("code") != null && jsonObject.getStr("code").equals("0") && jsonObject.get("data") != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过json节点表达式,获取节点json字符串,注:驼峰命名改成下划线命名
|
||||
*
|
||||
* @param jsonObject
|
||||
* @param expression json 节点表达式比如: data.list, msg, code
|
||||
* @return
|
||||
*/
|
||||
public static String toUnderlineJson(JSONObject jsonObject, String expression) {
|
||||
return StrUtil.toUnderlineCase(jsonObject.getByPath(expression, String.class));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
110
client/src/main/java/com/small/client/Utils/CryptoUtils.java
Normal file
110
client/src/main/java/com/small/client/Utils/CryptoUtils.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.small.client.Utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CryptoUtils {
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
|
||||
private static final String SECRET_KEY = "9f823ea6ab22785caf040e4cc3930619"; // 必须16/24/32字符
|
||||
|
||||
private static final String HASH_ALGORITHM_KEY = "appKey=a&sign=b&storeId=c";
|
||||
|
||||
/**
|
||||
* 打包并加密字段
|
||||
*/
|
||||
public static String packAndEncrypt(String appKey, String sign, String storeId) throws Exception {
|
||||
String combined = String.format("appKey=%s&sign=%s&storeId=%s", appKey, sign, storeId);
|
||||
return encrypt(combined);
|
||||
}
|
||||
|
||||
/**
|
||||
* 32位字符串生成
|
||||
* @param input
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static String generate32CharMD5(String input) throws NoSuchAlgorithmException {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] hashBytes = md.digest(input.getBytes());
|
||||
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte b : hashBytes) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
|
||||
return hexString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密并解包字段
|
||||
*/
|
||||
public static Map<String, String> decryptAndUnpack(String encryptedData) throws Exception {
|
||||
String decrypted = decrypt(encryptedData);
|
||||
Map<String, String> result = new HashMap<>();
|
||||
String[] pairs = decrypted.split("&");
|
||||
for (String pair : pairs) {
|
||||
String[] keyValue = pair.split("=");
|
||||
if (keyValue.length == 2) {
|
||||
result.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
* @param value
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String encrypt(String value) throws Exception {
|
||||
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] encryptedBytes = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param encryptedValue
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String decrypt(String encryptedValue) throws Exception {
|
||||
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(encryptedValue);
|
||||
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
// 示例用法
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String appKey = "d68397c4fb671bc024e24e1964b067cc35388818";
|
||||
String sign = "d68397c4fb671bc024e24e1964b067cc35388818";
|
||||
String storeId = "1";
|
||||
|
||||
// 打包加密
|
||||
String encrypted = packAndEncrypt(appKey, sign, storeId);
|
||||
System.out.println("加密结果: " + encrypted);
|
||||
|
||||
// 解密解包
|
||||
Map<String, String> result = decryptAndUnpack(encrypted);
|
||||
System.out.println("解密结果: " + result);
|
||||
}
|
||||
}
|
||||
176
client/src/main/java/com/small/client/Utils/FileUtils.java
Normal file
176
client/src/main/java/com/small/client/Utils/FileUtils.java
Normal file
@ -0,0 +1,176 @@
|
||||
package com.small.client.Utils;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
public class FileUtils {
|
||||
|
||||
public static final String pathSeparator = System.getProperty("file.separator");
|
||||
public static final String FOLDER = System.getProperty("user.home") + pathSeparator+"uploaded"+pathSeparator;
|
||||
public static final String GOODS = pathSeparator+"goods"+pathSeparator;//商品
|
||||
public static final String CATEGORY= pathSeparator+ "category"+pathSeparator;//分类
|
||||
public static final String BRAND = pathSeparator+"brand/"+pathSeparator;//品牌
|
||||
public static final String MEMBER= pathSeparator+"member"+pathSeparator;//会员
|
||||
|
||||
public static final String CLIENTSTALLPATH = System.getProperty("user.home") + pathSeparator+"cientStorePath"+pathSeparator;
|
||||
|
||||
public static final String REFLESHDATE="refleshdate.txt";
|
||||
public static final String PRIMARYKEY="primaryKey.txt";
|
||||
|
||||
public static final String GOODS_TYPE = "goods";//商品
|
||||
public static final String CATEGORY_TYPE= "category";//分类
|
||||
public static final String BRAND_TYPE = "brand";//品牌
|
||||
public static final String MEMBER_TYPE= "member";//会员
|
||||
|
||||
public static final String okEnd = "ok";//后缀
|
||||
public static final String txtEnd = "txt";//后缀
|
||||
|
||||
public static String fileFormat = "%s_%s.%s";//good_1
|
||||
|
||||
public static String getSyncTypeFlag(String syncType){
|
||||
Calendar calendar=Calendar.getInstance();
|
||||
int year=calendar.get(Calendar.YEAR);
|
||||
int month=calendar.get(Calendar.MONTH)+1;
|
||||
int date=calendar.get(Calendar.DAY_OF_MONTH);
|
||||
String result =FOLDER;
|
||||
switch (syncType){
|
||||
case "1":
|
||||
result=GOODS;
|
||||
break;
|
||||
case "2":
|
||||
result=CATEGORY;
|
||||
break;
|
||||
case "3":
|
||||
result=BRAND;
|
||||
break;
|
||||
case "4":
|
||||
result=MEMBER;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result+year+pathSeparator+month+pathSeparator+date+pathSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
* @param syncType
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
public File createFile(String syncType,Integer page){
|
||||
String path= getSyncTypeFlag(syncType+pathSeparator+page+pathSeparator);
|
||||
File file=new File(path);
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public File createFile(String path){
|
||||
File file=new File(path);
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件写入
|
||||
* @param filePath
|
||||
*/
|
||||
public void writeFile(String filePath,String fileName,String content){
|
||||
try {
|
||||
FileWriter writer = new FileWriter(filePath+pathSeparator+fileName);
|
||||
writer.write(content);
|
||||
writer.close();
|
||||
log.info("文件写入成功!");
|
||||
} catch (IOException e) {
|
||||
log.info("文件写入失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取文件名称
|
||||
* @param syncType
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
public String getFileName(String syncType ,Integer page,String endFix){
|
||||
String result="";
|
||||
switch (syncType){
|
||||
case "1":
|
||||
result=GOODS_TYPE;
|
||||
break;
|
||||
case "2":
|
||||
result=CATEGORY_TYPE;
|
||||
break;
|
||||
case "3":
|
||||
result=BRAND_TYPE;
|
||||
break;
|
||||
case "4":
|
||||
result=MEMBER_TYPE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return String.format(fileFormat, result,page,endFix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
* @param folderPath
|
||||
* @param filePath
|
||||
*/
|
||||
public static void createFolderAndFileUsingFile(String folderPath, String filePath) {
|
||||
File folder = new File(folderPath);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdir();
|
||||
}
|
||||
|
||||
File file = new File(filePath);
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public static void copyFile(String srcFile, String destFile) {
|
||||
String path= JarPathUtil.getRuntimePath();
|
||||
Path sourceFile = Paths.get(srcFile);
|
||||
Path targetDir =Paths.get(destFile);
|
||||
try {
|
||||
Files.copy(sourceFile, targetDir.resolve(sourceFile.getFileName()),
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
FileUtils fileUtils= new FileUtils();
|
||||
File file=fileUtils.createFile("1",1);
|
||||
System.out.printf("--"+file.getAbsoluteFile());
|
||||
fileUtils.writeFile(file.getAbsolutePath(),fileUtils.getFileName("1",2,txtEnd),"456");
|
||||
}
|
||||
|
||||
}
|
||||
107
client/src/main/java/com/small/client/Utils/HttpUtils.java
Normal file
107
client/src/main/java/com/small/client/Utils/HttpUtils.java
Normal file
@ -0,0 +1,107 @@
|
||||
package com.small.client.Utils;
|
||||
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.small.client.dto.StoreDbConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class HttpUtils {
|
||||
|
||||
public static final String SUCCESSCODE="0";//上传文件
|
||||
|
||||
public static final String URL_UPLOUP="/shop/sync/third/uploudSxData";//上传文件
|
||||
|
||||
|
||||
public static final String URL_SYNC_CATEGORY="/shop/sync/third/goods/category";//商品分类数据同步
|
||||
|
||||
public static final String URL_SYNC_BRAND="/shop/sync/third/goods/brand";//商品品牌数据同步
|
||||
|
||||
public static final String URL_SYNC_GOODS="/shop/sync/third/goods";//商品数据同步
|
||||
|
||||
public static final String URL_SYNC_MEMBER="/shop/sync/third/member";
|
||||
|
||||
public static final String URL_SYNC_GOODS_READ="/shop/sync/third/readSxData";//商品数据同步
|
||||
|
||||
public static final String URL_SYNC_GET_APPSIGN="/shop/sync/third/getAppSign";//获取密文
|
||||
|
||||
public static final String URL_SYNC_GET_DOWNCLIENTJAR="/shop/sync/app/downClientJar";//文件下载
|
||||
|
||||
public static final String URL_SYNC_GET_STOREdBCONFIG="/shop/sync/third/getStoreDbConfig";//文件下载
|
||||
|
||||
public static String postData(RestTemplate restTemplate, String url,Object modelObject){
|
||||
// 创建表单参数
|
||||
// MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
// map.add("key1", "value1");
|
||||
// map.add("key2", "value2");
|
||||
|
||||
// 设置Content-Type为application/x-www-form-urlencoded
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
log.info(modelObject.toString());
|
||||
HttpEntity<Object> request = new HttpEntity<>(modelObject, headers);
|
||||
|
||||
// 发送POST请求
|
||||
JSONObject jsonObject = restTemplate.postForObject(url, request, JSONObject.class);
|
||||
assert jsonObject != null;
|
||||
log.info(jsonObject.toString());
|
||||
return jsonObject.getStr("error_code");
|
||||
}
|
||||
|
||||
public static String postData(RestTemplate restTemplate, String url,Object modelObject,String contentName){
|
||||
// 创建表单参数
|
||||
// MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
// map.add("key1", "value1");
|
||||
// map.add("key2", "value2");
|
||||
|
||||
// 设置Content-Type为application/x-www-form-urlencoded
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
log.info(modelObject.toString());
|
||||
HttpEntity<Object> request = new HttpEntity<>(modelObject, headers);
|
||||
|
||||
// 发送POST请求
|
||||
JSONObject jsonObject = restTemplate.postForObject(url, request, JSONObject.class);
|
||||
assert jsonObject != null;
|
||||
log.info(jsonObject.toString());
|
||||
if("OK".equals(jsonObject.get("resultCode"))){
|
||||
return jsonObject.getStr(contentName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static StoreDbConfig postDataGetConfig(RestTemplate restTemplate, String url, Object modelObject){
|
||||
// 创建表单参数
|
||||
// MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
// map.add("key1", "value1");
|
||||
// map.add("key2", "value2");
|
||||
|
||||
// 设置Content-Type为application/x-www-form-urlencoded
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
log.info(modelObject.toString());
|
||||
HttpEntity<Object> request = new HttpEntity<>(modelObject, headers);
|
||||
|
||||
// 发送POST请求
|
||||
JSONObject jsonObject = restTemplate.postForObject(url, request, JSONObject.class);
|
||||
assert jsonObject != null;
|
||||
log.info(jsonObject.toString());
|
||||
if(0==jsonObject.getInt("error_code")){
|
||||
JSONObject object= jsonObject.getJSONObject("result");
|
||||
if(null!=object){
|
||||
return JSONUtil.toBean(object,StoreDbConfig.class);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
70
client/src/main/java/com/small/client/Utils/JarPathUtil.java
Normal file
70
client/src/main/java/com/small/client/Utils/JarPathUtil.java
Normal file
@ -0,0 +1,70 @@
|
||||
package com.small.client.Utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Slf4j
|
||||
public class JarPathUtil {
|
||||
/**
|
||||
* 更健壮的获取JAR路径方法
|
||||
*/
|
||||
public static String getJarPath() {
|
||||
try {
|
||||
// 获取当前类的URI
|
||||
String jarPath = JarPathUtil.class
|
||||
.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI()
|
||||
.getPath();
|
||||
|
||||
// 处理Windows路径问题
|
||||
if (jarPath.startsWith("/") && System.getProperty("os.name").contains("Windows")) {
|
||||
jarPath = jarPath.substring(1);
|
||||
}
|
||||
|
||||
return new File(jarPath).getAbsolutePath();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("无法解析JAR文件URI", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用NIO获取JAR所在目录
|
||||
*/
|
||||
public static String getJarParentPath() {
|
||||
try {
|
||||
Path path = Paths.get(JarPathUtil.class.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI());
|
||||
return path.getParent().toString();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException("无法解析JAR文件URI", e);
|
||||
}
|
||||
}
|
||||
public static String getRuntimePath() {
|
||||
URL location = JarPathUtil.class.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation();
|
||||
String path = location.getPath();
|
||||
|
||||
// 判断是否在IDE中运行(class文件)
|
||||
if (path.endsWith(".jar")) {
|
||||
// JAR运行模式
|
||||
return new File(path).getParent();
|
||||
} else {
|
||||
// IDE运行模式,返回项目目录
|
||||
return new File("").getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
log.info(getRuntimePath());
|
||||
}
|
||||
}
|
||||
30
client/src/main/java/com/small/client/comment/DicEnum.java
Normal file
30
client/src/main/java/com/small/client/comment/DicEnum.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.small.client.comment;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public enum DicEnum {
|
||||
//1-品牌,2-分类,3-商品,4-会员
|
||||
SYNCTYPE_1("1","品牌","syncType","同步类型"),
|
||||
SYNCTYPE_2("2","分类","syncType","同步类型"),
|
||||
SYNCTYPE_3("3","商品","syncType","同步类型"),
|
||||
SYNCTYPE_4("4","会员","syncType","同步类型"),
|
||||
;
|
||||
|
||||
@Getter
|
||||
private String code;
|
||||
@Getter
|
||||
private String name;
|
||||
@Getter
|
||||
private String dicType;
|
||||
@Getter
|
||||
private String description;
|
||||
|
||||
DicEnum(String code, String name, String dicType, String description) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.dicType = dicType;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.small.client.comment;
|
||||
|
||||
public class UrlComment {
|
||||
|
||||
public static String url="";//获取shop的数据库基本信息 todo
|
||||
|
||||
public static String UrlSynShop="";//商品同步接口
|
||||
public static String UrlSynCategory="";//商品种类同步接口
|
||||
|
||||
public static String UrlSynProduct="";
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.small.client.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class ClientConfig {
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
||||
18
client/src/main/java/com/small/client/config/TaskConfig.java
Normal file
18
client/src/main/java/com/small/client/config/TaskConfig.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.small.client.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class TaskConfig {
|
||||
@Bean
|
||||
public TaskScheduler taskScheduler() {
|
||||
return new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10)); // 使用默认线程池
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.small.client.controller;
|
||||
|
||||
import com.small.client.Utils.HttpUtils;
|
||||
import com.small.client.dto.DataBaseInfo;
|
||||
import com.small.client.dto.SyncGoodsSearchModel;
|
||||
import com.small.client.service.SxDataService;
|
||||
import com.small.client.service.WebClientService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/client")
|
||||
@Slf4j
|
||||
public class WebController {
|
||||
@Autowired
|
||||
private WebClientService webClientService;
|
||||
@Autowired
|
||||
private SxDataService sxDataService;
|
||||
|
||||
@RequestMapping("/upload")
|
||||
public void upload(){
|
||||
System.out.println("upload");
|
||||
//webClientService.uploudSxData();
|
||||
}
|
||||
|
||||
@RequestMapping("/synBrand")
|
||||
public void synBrand(){
|
||||
log.info("synBrand");
|
||||
sxDataService.getAppSign();
|
||||
|
||||
sxDataService.SyncBranchList(new DataBaseInfo(),sxDataService.getCommentModel());
|
||||
}
|
||||
|
||||
@RequestMapping("/syncCategory")
|
||||
public void syncCategory(){
|
||||
log.info("syncCategory");
|
||||
sxDataService.getAppSign();
|
||||
sxDataService.SyncCategory(new DataBaseInfo(),sxDataService.getCommentModel());
|
||||
}
|
||||
|
||||
@RequestMapping("/syncGoods")
|
||||
public void syncGoods(){
|
||||
log.info("syncGoods");
|
||||
sxDataService.getAppSign();
|
||||
sxDataService.SyncGoods(new DataBaseInfo(),sxDataService.getCommentModel());
|
||||
}
|
||||
|
||||
@RequestMapping("/synvip")
|
||||
public void synvip(){
|
||||
log.info("synvip");
|
||||
sxDataService.getAppSign();
|
||||
sxDataService.SyncVipList(new DataBaseInfo(),sxDataService.getCommentModel());
|
||||
}
|
||||
|
||||
@RequestMapping("/getAppSign")
|
||||
public void getAppSign(){
|
||||
log.info("getAppSign");
|
||||
sxDataService.getAppSign();
|
||||
}
|
||||
|
||||
@RequestMapping("/downLoadClient")
|
||||
public void downLoadClient(){
|
||||
log.info("downLoadClient");
|
||||
sxDataService.downLoadClient();
|
||||
}
|
||||
|
||||
@RequestMapping("/udpateAndStart")
|
||||
public void updateAndStart(){
|
||||
sxDataService.checkForUpdates();
|
||||
}
|
||||
|
||||
@RequestMapping("/getDataBaseInfo")
|
||||
public void getDataBaseInfo(){
|
||||
sxDataService.getDataBaseInfo(sxDataService.getCommentModel());
|
||||
}
|
||||
|
||||
}
|
||||
246
client/src/main/java/com/small/client/dao/BaseDao.java
Normal file
246
client/src/main/java/com/small/client/dao/BaseDao.java
Normal file
@ -0,0 +1,246 @@
|
||||
package com.small.client.dao;
|
||||
|
||||
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
|
||||
import com.microsoft.sqlserver.jdbc.SQLServerException;
|
||||
|
||||
import com.small.client.dto.ResultDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@Slf4j
|
||||
public class BaseDao {
|
||||
|
||||
private final static String DEFAULT_IP="127.0.0.1";
|
||||
private final static String DEFAULT_DATABASE="hbposev9";
|
||||
private final static String DEFAULT_USERNAME="sa";
|
||||
private final static String DEFAULT_PWD="123456";
|
||||
private final static int PortNumber=1433;
|
||||
private final static int LoginTimeout=10;
|
||||
/**
|
||||
*
|
||||
* 动态获取数据库连接
|
||||
* @param ip 数据库ip+
|
||||
* @param username 用户名
|
||||
* @param password 密码 todo 需要加密
|
||||
* @param dataBaseName 数据库名称
|
||||
* @return
|
||||
*/
|
||||
public Connection getConnection(String ip, String username, String password,Integer port, String dataBaseName){
|
||||
Connection conn=null;
|
||||
SQLServerDataSource sqlServerDataSource=new SQLServerDataSource();
|
||||
sqlServerDataSource.setDatabaseName(dataBaseName==null?DEFAULT_DATABASE:dataBaseName);
|
||||
sqlServerDataSource.setServerName(ip==null?DEFAULT_IP:ip);
|
||||
sqlServerDataSource.setPortNumber(port==null?PortNumber:port);
|
||||
sqlServerDataSource.setLoginTimeout(LoginTimeout);
|
||||
sqlServerDataSource.setPassword(password==null?DEFAULT_PWD:password);
|
||||
sqlServerDataSource.setUser(username==null?DEFAULT_USERNAME:username);
|
||||
try {
|
||||
conn=sqlServerDataSource.getConnection();
|
||||
} catch (SQLServerException e) {
|
||||
log.info("数据库连接异常方法{}异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.getConnection",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭数据库连接
|
||||
* @param conn
|
||||
*/
|
||||
public void Close(Connection conn){
|
||||
if(conn!=null){
|
||||
try {
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回游标和连接 减少服务器的占用内存
|
||||
* @param ip
|
||||
* @param username
|
||||
* @param password
|
||||
* @param dataBaseName
|
||||
* @return ResultDto
|
||||
*/
|
||||
public ResultDto baseFindList(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String where){
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
String sql="select * from %s %s";
|
||||
sql=String.format(sql, table,where);
|
||||
ResultDto resultDto=new ResultDto();
|
||||
ResultSet rs=null;
|
||||
log.info(sql);
|
||||
try {
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.baseFindList",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
resultDto.setResultSet(rs);
|
||||
resultDto.setConnection(connection);
|
||||
return resultDto;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 带分页数据
|
||||
* @param ip
|
||||
* @param username
|
||||
* @param password
|
||||
* @param dataBaseName
|
||||
* @param table
|
||||
* @return
|
||||
*/
|
||||
public ResultDto baseFindListPage(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String orderColumn, int pageNo, int pageSize,String where){
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
int start=(pageNo-1)*pageSize+1;
|
||||
int end=pageNo*pageSize;
|
||||
String sql=" select * from( " +
|
||||
" select ROW_NUMBER() OVER(ORDER BY %s) as rowId,* from %s %s" +
|
||||
" ) as r where rowId between %s and %s";
|
||||
sql=String.format(sql, orderColumn,table,where,start,end);
|
||||
log.info(sql);
|
||||
ResultDto resultDto=new ResultDto();
|
||||
ResultSet rs=null;
|
||||
try {
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.baseFindListPage",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
resultDto.setResultSet(rs);
|
||||
resultDto.setConnection(connection);
|
||||
return resultDto;
|
||||
}
|
||||
|
||||
public Integer getBaseTotal(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String where){
|
||||
int total=0;
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
try {
|
||||
String sql="select count(*) from %s %s";
|
||||
sql=String.format(sql, table,where);
|
||||
log.info(sql);
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
ResultSet rs=ps.executeQuery();
|
||||
while (rs.next()){
|
||||
total=rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.getBaseTotal",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
public Integer getBaseJoinTotal(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String joinTable,String onLeft,String onRight,String orderColumn,String rightSelect,String where){
|
||||
int total=0;
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
try {
|
||||
String sql=" select COUNT(*) from( " +
|
||||
" select ROW_NUMBER() OVER(ORDER BY b.%s) as rowId,b.*,%s from %s b left join %s t on b.%s=t.%s %s" +
|
||||
" ) r";
|
||||
sql=String.format(sql, orderColumn,rightSelect,table,joinTable,onLeft,onRight,where);
|
||||
log.info(sql);
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
ResultSet rs=ps.executeQuery();
|
||||
while (rs.next()){
|
||||
total=rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.getBaseTotal",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 带分页数据关联分页查询
|
||||
* @param ip
|
||||
* @param username
|
||||
* @param password
|
||||
* @param dataBaseName
|
||||
* @param table
|
||||
* @return
|
||||
*/
|
||||
public ResultDto baseFindListJoinPage(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String joinTable,String onLeft,String onRight,String orderColumn,String rightSelect, int pageNo, int pageSize,String where){
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
int start=(pageNo-1)*pageSize+1;
|
||||
int end=pageNo*pageSize;
|
||||
String sql=" select * from( " +
|
||||
" select ROW_NUMBER() OVER(ORDER BY b.%s) as rowId,b.*,%s from %s b left join %s t on b.%s=t.%s %s" +
|
||||
" ) as r where rowId between %s and %s";
|
||||
sql=String.format(sql, orderColumn,rightSelect,table,joinTable,onLeft,onRight,where,start,end);
|
||||
log.info(sql);
|
||||
ResultDto resultDto=new ResultDto();
|
||||
ResultSet rs=null;
|
||||
try {
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.baseFindListJoinPage",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
resultDto.setResultSet(rs);
|
||||
resultDto.setConnection(connection);
|
||||
return resultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ip
|
||||
* @param username
|
||||
* @param password
|
||||
* @param dataBaseName
|
||||
* @param table
|
||||
* @param joinTable
|
||||
* @param onLeft
|
||||
* @param onRight
|
||||
* @param rightSelect
|
||||
* @param where
|
||||
* @return
|
||||
*/
|
||||
public ResultDto baseFindListJoin(String ip, String username, String password,Integer portNumber, String dataBaseName, String table,String joinTable,String onLeft,String onRight,String rightSelect, String where){
|
||||
Connection connection=getConnection(ip,username,password,portNumber,dataBaseName);
|
||||
String sql= "select b.*,%s from %s b left join %s t on b.%s=t.%s %s " ;
|
||||
sql=String.format(sql,rightSelect,table,joinTable,onLeft,onRight,where);
|
||||
log.info(sql);
|
||||
ResultDto resultDto=new ResultDto();
|
||||
ResultSet rs=null;
|
||||
try {
|
||||
PreparedStatement ps= connection.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
} catch (SQLException e) {
|
||||
log.info("数据库查询异常方法{},异常信息{}","com.suisung.mall.shop.sixun.dao.BaseDao.baseFindListJoin",e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
resultDto.setResultSet(rs);
|
||||
resultDto.setConnection(connection);
|
||||
return resultDto;
|
||||
}
|
||||
|
||||
}
|
||||
448
client/src/main/java/com/small/client/dao/SxDataDao.java
Normal file
448
client/src/main/java/com/small/client/dao/SxDataDao.java
Normal file
@ -0,0 +1,448 @@
|
||||
package com.small.client.dao;
|
||||
|
||||
|
||||
import com.small.client.dto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.charset.Charset;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考虑到每个思迅软件都是自己的数据,所以采用动态获取的方式获取数据
|
||||
* 数据库为MS SQL
|
||||
* todo 如果考虑到数据量需要分页多线程
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SxDataDao extends BaseDao{
|
||||
|
||||
private final static String T_BD_ITEM_CLS="t_bd_item_cls";//商品分类
|
||||
private final static String T_BD_ITEM_INFO="t_bd_item_info";//商品表
|
||||
private final static String T_RM_VIP_INFO="t_rm_vip_info";//会员表
|
||||
|
||||
private final static String ITEM_CLSNO="item_clsno";//商品分类排序字段
|
||||
private final static String ITEM_NO="item_no";//商品排序字段
|
||||
private final static String CARD_ID="card_id";//会员表排序字段
|
||||
|
||||
|
||||
private final static String T_BD_BASE_CODE="t_bd_base_code";//品牌表
|
||||
private final static String T_BD_BASECODE_TYPE="t_bd_basecode_type";//品牌表
|
||||
private final static String TYPE_NO="type_no";//品牌排序字段
|
||||
|
||||
private final static String T_IM_BRANCH_STOCK="t_im_branch_stock";//库存表
|
||||
|
||||
private final static String T_RM_SPEC_PRICE="t_rm_spec_price";//活动表
|
||||
|
||||
public final static Integer PAGESIZE=500;
|
||||
|
||||
public final static String DEFALTWHERE="where 1=1";
|
||||
|
||||
public final static String DEFAULT_IMG="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Homepage-Model-Y-2-Promo-Hero-Tablet-CN.png";
|
||||
|
||||
|
||||
/**
|
||||
* 查找商品分类数据
|
||||
* @param dataBaseInfo
|
||||
*/
|
||||
public List<SxSyncCategory> findTBdItemClsList(DataBaseInfo dataBaseInfo){
|
||||
ResultDto resultDto=baseFindList(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_BD_ITEM_CLS,DEFALTWHERE);
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SxSyncCategory> sxSyncCategories=new ArrayList<>();
|
||||
SxSyncCategory sxSyncCategory=null;
|
||||
try {
|
||||
while (rs.next()) {
|
||||
sxSyncCategory=new SxSyncCategory();
|
||||
sxSyncCategory.setItem_clsname(rs.getString("item_clsname").trim());//分类名称
|
||||
if(null!=rs.getString("cls_parent")){
|
||||
sxSyncCategory.setCls_parent(rs.getString("cls_parent").trim());//父级编码
|
||||
}
|
||||
sxSyncCategory.setItem_clsno(rs.getString("item_clsno").trim());//分类编码
|
||||
// System.out.printf(rs.getString("item_clsno"));//分类编码
|
||||
// System.out.printf(rs.getString("item_clsname")+"\t");//分类名称
|
||||
// System.out.print(rs.getString("cls_parent")+"\t");//父级编码
|
||||
// System.out.print(rs.getString("item_flag")+"\t" + "\n");//显示标识
|
||||
sxSyncCategories.add(sxSyncCategory);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return sxSyncCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查找商品分类数据
|
||||
* @param dataBaseInfo
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
*/
|
||||
public List<SxSyncCategory> findTBdItemClsListPage(DataBaseInfo dataBaseInfo, int pageNo, int pageSize){
|
||||
ResultDto resultDto=baseFindListPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_BD_ITEM_CLS,ITEM_CLSNO,pageNo,pageSize,DEFALTWHERE);
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SxSyncCategory> sxSyncCategories=new ArrayList<>();
|
||||
SxSyncCategory sxSyncCategory=null;
|
||||
try {
|
||||
while (rs.next()) {
|
||||
sxSyncCategory=new SxSyncCategory();
|
||||
sxSyncCategory.setItem_clsname(rs.getString("item_clsname"));//分类名称
|
||||
sxSyncCategory.setCls_parent(rs.getString("cls_parent"));//父级编码
|
||||
sxSyncCategory.setItem_clsno(rs.getString("item_clsno"));//分类编码
|
||||
// System.out.printf(rs.getString("item_clsno"));//分类编码
|
||||
// log.info(rs.getString("item_clsname")+"\t");//分类名称
|
||||
//log.info(rs.getString("cls_parent")+"\t");//父级编码
|
||||
//log.info(rs.getString("item_flag")+"\t" + "\n");//显示标识
|
||||
sxSyncCategories.add(sxSyncCategory);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return sxSyncCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类TBdItemCls表的数量
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public Integer getTBdItemClsTotal(DataBaseInfo dataBaseInfo){
|
||||
return getBaseTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_BD_ITEM_CLS,DEFALTWHERE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品表t_bd_item_info表的数量
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public int getTBditemInfoTotal(DataBaseInfo dataBaseInfo){
|
||||
// String where =DEFALTWHERE;
|
||||
// if(syncGoodsSearchModel!=null){
|
||||
// if(dataBaseInfo.getWhere()!=null){
|
||||
// where+= dataBaseInfo.getWhere();
|
||||
// }
|
||||
// }
|
||||
return getBaseTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_BD_ITEM_INFO,dataBaseInfo.getWhere());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品表t_bd_item_info表的数量
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public int getTBditemInfoJoninTotal(DataBaseInfo dataBaseInfo){
|
||||
return getBaseJoinTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName()
|
||||
, T_BD_ITEM_INFO
|
||||
,T_IM_BRANCH_STOCK
|
||||
,"item_no"
|
||||
,"item_no"
|
||||
,ITEM_CLSNO
|
||||
,"t.stock_qty,t.oper_date"
|
||||
,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员表t_rm_vip_info表的数量
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public int getTrmVipInfoTotal(DataBaseInfo dataBaseInfo){
|
||||
return getBaseTotal(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_RM_VIP_INFO,dataBaseInfo.getWhere());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查找商品数据
|
||||
* 表T_BD_ITEM_INFO
|
||||
* @param dataBaseInfo
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
*/
|
||||
public List<SxSyncGoods> findBditemInfoListPage(DataBaseInfo dataBaseInfo,int pageNo,int pageSize){
|
||||
ResultDto resultDto=baseFindListJoinPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName()
|
||||
, T_BD_ITEM_INFO
|
||||
,T_IM_BRANCH_STOCK
|
||||
,"item_no"
|
||||
,"item_no"
|
||||
,ITEM_CLSNO
|
||||
,"t.stock_qty,t.oper_date"
|
||||
,pageNo,pageSize,dataBaseInfo.getWhere()==null?DEFALTWHERE:dataBaseInfo.getWhere());
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SxSyncGoods> sxSyncGoodses=new ArrayList<>();
|
||||
SxSyncGoods sxSyncGoods=null;
|
||||
try {
|
||||
while (rs.next()) {
|
||||
sxSyncGoods=new SxSyncGoods();
|
||||
BigDecimal price=new BigDecimal(rs.getString("price"));
|
||||
BigDecimal salePrice=new BigDecimal(rs.getString("sale_price"));
|
||||
if(salePrice.compareTo(new BigDecimal("0"))>0){
|
||||
try{
|
||||
BigDecimal gross= salePrice.subtract(price).divide(salePrice,4, RoundingMode.HALF_UP);
|
||||
sxSyncGoods.setGross_margin(gross);//毛利率
|
||||
}catch (RuntimeException e){
|
||||
log.info("运行错误:{}",e.getMessage());
|
||||
log.info(String.valueOf(rs.getString("sale_price")));
|
||||
}
|
||||
|
||||
}else {
|
||||
sxSyncGoods.setGross_margin(new BigDecimal("0"));//毛利率
|
||||
}
|
||||
sxSyncGoods.setItem_no(rs.getString("item_no"));//货号
|
||||
sxSyncGoods.setItem_subname(rs.getString("item_subname"));//商品名称
|
||||
sxSyncGoods.setItem_subno(rs.getString("item_subno"));//商品条码
|
||||
|
||||
sxSyncGoods.setBig_cls_name("9999");//商品大类 todo 如何关联
|
||||
sxSyncGoods.setSmall_cls_name(rs.getString("item_clsno").trim());//商品小类 todo 如何关联
|
||||
|
||||
sxSyncGoods.setItem_size(rs.getString("item_size"));//规格
|
||||
sxSyncGoods.setUnit_no(rs.getString("unit_no"));//单位 todo
|
||||
sxSyncGoods.setStock(rs.getBigDecimal("stock_qty"));//库存数量 todo item_stock?
|
||||
|
||||
sxSyncGoods.setPrice(rs.getBigDecimal("price"));//进货价
|
||||
sxSyncGoods.setSale_price(rs.getBigDecimal("sale_price"));//零售价
|
||||
|
||||
sxSyncGoods.setVip_price(rs.getBigDecimal("vip_price"));//会员价
|
||||
sxSyncGoods.setVip_acc_flag(rs.getBigDecimal("vip_acc_flag"));//允许积分
|
||||
sxSyncGoods.setVip_acc_num(rs.getBigDecimal("vip_acc_num"));//积分值
|
||||
sxSyncGoods.setSale_flag(rs.getInt("main_Sale_flag"));//商品状态 todo 是main_Sale_flag?
|
||||
sxSyncGoods.setItem_rem(rs.getString("item_rem"));//助记码
|
||||
sxSyncGoods.setBuild_date(rs.getString("build_date"));//生产日期 todo
|
||||
sxSyncGoods.setValid_days(getStopDate(rs));//保质期 todo stop_date-build_date?
|
||||
|
||||
sxSyncGoods.setItem_brand_name(rs.getString("item_brandname"));
|
||||
sxSyncGoods.setItemBrand(rs.getString("item_brand"));
|
||||
sxSyncGoods.setItem_clsno(rs.getString("item_clsno").trim());
|
||||
sxSyncGoods.setItem_size(rs.getString("item_size"));
|
||||
|
||||
sxSyncGoodses.add(sxSyncGoods);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return sxSyncGoodses;
|
||||
}
|
||||
|
||||
private static String getStopDate(ResultSet rs) throws SQLException {
|
||||
return rs.getString("stop_date");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查找会员数据
|
||||
* RM_VIP_INFO
|
||||
* @param dataBaseInfo
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
*/
|
||||
public List<SxSyncVip> findRmVipInfoListPage(DataBaseInfo dataBaseInfo, int pageNo, int pageSize){
|
||||
ResultDto resultDto=baseFindListPage(dataBaseInfo.getIp(),dataBaseInfo.getUserName(),dataBaseInfo.getPassword(),dataBaseInfo.getDbPort(),dataBaseInfo.getDataBaseName(),T_RM_VIP_INFO,CARD_ID,pageNo,pageSize,dataBaseInfo.getWhere());
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SxSyncVip> sxSyncVips=new ArrayList<>();
|
||||
SxSyncVip sxSyncVip=null;
|
||||
try {
|
||||
while (rs.next()) {
|
||||
sxSyncVip = new SxSyncVip();
|
||||
int cardStatus=rs.getInt("card_status");
|
||||
if(cardStatus!=1){
|
||||
sxSyncVip.setVip_name(rs.getString("vip_name"));//会员名称
|
||||
sxSyncVip.setVip_sex(rs.getString("vip_sex"));//会员名称
|
||||
sxSyncVip.setMobile(rs.getString("mobile"));//会员名称
|
||||
sxSyncVip.setBirthday(rs.getString("birthday"));//会员生日
|
||||
sxSyncVip.setCard_type(rs.getString("card_type")==null?"v1":rs.getString("card_type"));//会员生日
|
||||
sxSyncVip.setCard_no(rs.getString("card_no"));//会员卡号
|
||||
sxSyncVip.setCard_no(rs.getString("now_acc_num"));//会员积分
|
||||
sxSyncVip.setCard_no(rs.getString("residual_amt"));//储值余额
|
||||
sxSyncVip.setCard_no(rs.getString("vip_start_date"));//建档日期
|
||||
|
||||
log.info(rs.getString("vip_name"));//会员名称
|
||||
log.info(rs.getString("mobile"));//会员手机号
|
||||
log.info(rs.getString("vip_sex"));//会员性别
|
||||
log.info(rs.getString("birthday"));//会员生日
|
||||
log.info(rs.getString("card_no"));//会员卡号
|
||||
log.info(rs.getString("card_type"));//会员等级
|
||||
log.info("{}",rs.getBigDecimal("residual_amt"));//储值余额
|
||||
log.info("{}",rs.getBigDecimal("now_acc_num"));//会员积分
|
||||
log.info(rs.getString("vip_start_date"));//建档日期
|
||||
log.info("{}",rs.getInt("card_status"));//会员状态
|
||||
}
|
||||
|
||||
sxSyncVips.add(sxSyncVip);
|
||||
}
|
||||
}catch (SQLException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return sxSyncVips;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取品牌数据
|
||||
* @param dataBaseInfo
|
||||
*/
|
||||
public List<BrandModel> getBdBrandList(DataBaseInfo dataBaseInfo) {
|
||||
String where="where t.type_name='品牌'";
|
||||
ResultDto resultDto=baseFindListJoin(dataBaseInfo.getIp()
|
||||
,dataBaseInfo.getUserName()
|
||||
,dataBaseInfo.getPassword()
|
||||
,dataBaseInfo.getDbPort()
|
||||
,dataBaseInfo.getDataBaseName()
|
||||
,T_BD_BASE_CODE
|
||||
,"t_bd_basecode_type"
|
||||
,"type_no"
|
||||
,"type_no"
|
||||
,"t.type_name"
|
||||
,where);
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<BrandModel> brandModels=new ArrayList<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
BrandModel brandModel=new BrandModel();
|
||||
brandModel.setBrand_name(rs.getString("code_name"));
|
||||
brandModel.setBrand_desc(rs.getString("code_name"));
|
||||
brandModel.setCodeId(rs.getString("code_id"));
|
||||
brandModel.setBrand_image("");
|
||||
brandModel.setCategory("0");
|
||||
brandModel.setBrand_recommend("0");//是否推荐
|
||||
brandModels.add(brandModel);
|
||||
// log.info(rs.getString("type_no")+"--"+rs.getString("code_name"));//分类编码-分类名称
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return brandModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存数据
|
||||
* @return
|
||||
*/
|
||||
public List<ImBranchStock> getImBranchStockList(DataBaseInfo dataBaseInfo,String where){
|
||||
ResultDto resultDto=baseFindList(dataBaseInfo.getIp()
|
||||
,dataBaseInfo.getUserName()
|
||||
,dataBaseInfo.getPassword()
|
||||
,dataBaseInfo.getDbPort()
|
||||
,dataBaseInfo.getDataBaseName()
|
||||
,T_IM_BRANCH_STOCK
|
||||
,where);
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<ImBranchStock> branchStocks=new ArrayList<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
ImBranchStock brandModel=new ImBranchStock();
|
||||
brandModel.setBranchNo(rs.getString("branch_no"));
|
||||
brandModel.setStockQty(rs.getBigDecimal("stock_qty"));
|
||||
brandModel.setItemNo(rs.getString("item_no"));
|
||||
brandModel.setPerDate(rs.getString("oper_date"));
|
||||
branchStocks.add(brandModel);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return branchStocks;
|
||||
}
|
||||
|
||||
/**
|
||||
*获取促销活动价格 时段特价单
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public List<SpecPriceDto> getSpecPriceList(DataBaseInfo dataBaseInfo){
|
||||
ResultDto resultDto=baseFindList(dataBaseInfo.getIp()
|
||||
,dataBaseInfo.getUserName()
|
||||
,dataBaseInfo.getPassword()
|
||||
,dataBaseInfo.getDbPort()
|
||||
,dataBaseInfo.getDataBaseName()
|
||||
,"T_RM_SPEC_PRICE"
|
||||
,"where special_type ='0'");
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SpecPriceDto> specPriceDtos=new ArrayList<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
SpecPriceDto specPriceDto=new SpecPriceDto();
|
||||
specPriceDto.setItemNo(rs.getString("item_no"));//
|
||||
specPriceDto.setOldPrice(rs.getBigDecimal("old_price"));//原价
|
||||
specPriceDto.setSpecPrice(rs.getBigDecimal("spe_price"));//特价
|
||||
specPriceDto.setSpecPrice(rs.getBigDecimal("sale_qty"));//限购
|
||||
specPriceDto.setDiscountType("0");
|
||||
specPriceDtos.add(specPriceDto);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return specPriceDtos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 折扣商品
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public List<SpecPriceDto> getDiscountPriceList(DataBaseInfo dataBaseInfo){
|
||||
ResultDto resultDto=baseFindList(dataBaseInfo.getIp()
|
||||
,dataBaseInfo.getUserName()
|
||||
,dataBaseInfo.getPassword()
|
||||
,dataBaseInfo.getDbPort()
|
||||
,dataBaseInfo.getDataBaseName()
|
||||
,T_RM_SPEC_PRICE
|
||||
,"where special_type in('6','G')");
|
||||
ResultSet rs= resultDto.getResultSet();
|
||||
List<SpecPriceDto> specPriceDtos=new ArrayList<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
SpecPriceDto specPriceDto=new SpecPriceDto();
|
||||
specPriceDto.setItemNo(rs.getString("item_no"));//
|
||||
specPriceDto.setDiscount(rs.getBigDecimal("discount"));//原价
|
||||
specPriceDto.setDiscountType("1");
|
||||
specPriceDtos.add(specPriceDto);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
resultDto.getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return specPriceDtos;
|
||||
}
|
||||
|
||||
}
|
||||
27
client/src/main/java/com/small/client/dto/BrandModel.java
Normal file
27
client/src/main/java/com/small/client/dto/BrandModel.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class BrandModel implements Serializable {
|
||||
@ApiModelProperty("品牌名称")
|
||||
private String brand_name;
|
||||
|
||||
@ApiModelProperty("品牌编号")
|
||||
private String codeId;
|
||||
|
||||
@ApiModelProperty("品牌描述")
|
||||
private String brand_desc;
|
||||
|
||||
@ApiModelProperty("品牌分类")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty("图片")
|
||||
private String brand_image;
|
||||
|
||||
@ApiModelProperty("是否推荐")
|
||||
private String brand_recommend;
|
||||
}
|
||||
17
client/src/main/java/com/small/client/dto/CommentModel.java
Normal file
17
client/src/main/java/com/small/client/dto/CommentModel.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CommentModel {
|
||||
@ApiModelProperty("店铺的key")
|
||||
private String appKey;
|
||||
@ApiModelProperty("店铺的密钥")
|
||||
private String sign;
|
||||
@ApiModelProperty("店铺的id")
|
||||
private String storeId;
|
||||
|
||||
@ApiModelProperty(value = "同步时间-用于增量同步,大于这个时间证明是增量")
|
||||
private String syncTime;//同步时间
|
||||
}
|
||||
33
client/src/main/java/com/small/client/dto/DataBaseInfo.java
Normal file
33
client/src/main/java/com/small/client/dto/DataBaseInfo.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DataBaseInfo {
|
||||
@ApiModelProperty("数据库IP")
|
||||
private String ip;
|
||||
@ApiModelProperty("用户名")
|
||||
private String userName;
|
||||
@ApiModelProperty("密码")
|
||||
private String password;
|
||||
@ApiModelProperty("数据库名称")
|
||||
private String dataBaseName;
|
||||
@ApiModelProperty("条件")
|
||||
private String where;
|
||||
@ApiModelProperty(value = "数据库端口")
|
||||
private Integer dbPort;
|
||||
@ApiModelProperty(value = "定时同步的cron表达式")
|
||||
private String cronExpression;
|
||||
@ApiModelProperty(value = "同步模式(1:定时同步,2:间隔同步)")
|
||||
private String syncMode;
|
||||
|
||||
@ApiModelProperty(value = "商品分类")
|
||||
private String categoryName;
|
||||
|
||||
@ApiModelProperty(value = "01全量,02增量")
|
||||
private String syncType;
|
||||
|
||||
@ApiModelProperty(value = "操作时间")
|
||||
private String operDate;
|
||||
}
|
||||
18
client/src/main/java/com/small/client/dto/ImBranchStock.java
Normal file
18
client/src/main/java/com/small/client/dto/ImBranchStock.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class ImBranchStock {
|
||||
@ApiModelProperty("商品编号")
|
||||
private String itemNo;
|
||||
@ApiModelProperty("商标编号")
|
||||
private String branchNo;
|
||||
@ApiModelProperty("库存")
|
||||
private BigDecimal stockQty;
|
||||
@ApiModelProperty("操作时间")
|
||||
private String perDate;
|
||||
}
|
||||
17
client/src/main/java/com/small/client/dto/ProductImage.java
Normal file
17
client/src/main/java/com/small/client/dto/ProductImage.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ProductImage {
|
||||
@ApiModelProperty("图片路径")
|
||||
private String image_url;
|
||||
@ApiModelProperty("推荐值")
|
||||
private String seq;
|
||||
@ApiModelProperty("介绍")
|
||||
private String desc;
|
||||
@ApiModelProperty("是否默认")
|
||||
private String is_default;
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PromotionDetail {
|
||||
|
||||
@ApiModelProperty("活动id")
|
||||
private String activity_id;
|
||||
@ApiModelProperty("活动名称")
|
||||
private String activity_name;
|
||||
@ApiModelProperty("价格")
|
||||
private String price;
|
||||
@ApiModelProperty("介绍")
|
||||
private String intro;
|
||||
}
|
||||
15
client/src/main/java/com/small/client/dto/ResultDto.java
Normal file
15
client/src/main/java/com/small/client/dto/ResultDto.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
@Data
|
||||
public class ResultDto {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
private ResultSet resultSet;
|
||||
|
||||
}
|
||||
19
client/src/main/java/com/small/client/dto/SpecPriceDto.java
Normal file
19
client/src/main/java/com/small/client/dto/SpecPriceDto.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class SpecPriceDto {
|
||||
|
||||
private String itemNo;
|
||||
private BigDecimal oldPrice;//原价
|
||||
private BigDecimal specPrice;//折后价
|
||||
|
||||
private BigDecimal discount;//折扣('6','G')
|
||||
|
||||
private Integer saleQty;//限购
|
||||
|
||||
private String discountType;//折扣类型 0-特价,1打折
|
||||
}
|
||||
64
client/src/main/java/com/small/client/dto/StoreDbConfig.java
Normal file
64
client/src/main/java/com/small/client/dto/StoreDbConfig.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class StoreDbConfig implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "店铺ID")
|
||||
private String storeId;
|
||||
|
||||
@ApiModelProperty(value = "数据库类型(mysql/oracle/sqlserver等)")
|
||||
private String dbType = "sqlserver";
|
||||
|
||||
@ApiModelProperty(value = "数据库名称")
|
||||
private String dbName;
|
||||
|
||||
@ApiModelProperty(value = "数据库IP地址")
|
||||
private String dbIp;
|
||||
|
||||
@ApiModelProperty(value = "数据库端口")
|
||||
private Integer dbPort;
|
||||
|
||||
@ApiModelProperty(value = "数据库用户名")
|
||||
private String dbUsername;
|
||||
|
||||
@ApiModelProperty(value = "数据库密码(建议加密存储)")
|
||||
private String dbPassword;
|
||||
|
||||
@ApiModelProperty(value = "是否有外网访问(0:无,1:有)")
|
||||
private String hasInternet;
|
||||
|
||||
@ApiModelProperty(value = "同步模式(1:定时同步,2:间隔同步)")
|
||||
private String syncMode;
|
||||
|
||||
@ApiModelProperty(value = "是否启用(0:否,1:是)")
|
||||
private String hasStart;
|
||||
|
||||
@ApiModelProperty(value = "定时同步的cron表达式")
|
||||
private String cronExpression;
|
||||
|
||||
@ApiModelProperty(value = "商品分类")
|
||||
private String categoryName;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
@ApiModelProperty(value = "备注信息")
|
||||
private String remark;
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 模型对应
|
||||
*/
|
||||
@Data
|
||||
public class SxCategoryModel {
|
||||
//模型对应ShopBaseProductCategory start
|
||||
private String parent_name;//暂时不用
|
||||
@ApiModelProperty(value = "商品分类名称")
|
||||
private String category_name;
|
||||
@ApiModelProperty(value = "分类图片")
|
||||
private String category_image;
|
||||
@ApiModelProperty(value = "是否允许虚拟商品(ENUM):1-是; 0-否")
|
||||
private Integer category_virtual_enable;
|
||||
@ApiModelProperty(value = "分佣比例-百分比")
|
||||
private BigDecimal category_commission_rate;
|
||||
// private String type_name;//todo 看代码没有用,使用的是product_type
|
||||
//模型对应ShopBaseProductCategory end
|
||||
@ApiModelProperty(value = "产品类型")
|
||||
private String product_type;
|
||||
@ApiModelProperty(value = "第一级父类")
|
||||
private String first_category_name;
|
||||
@ApiModelProperty(value = "第二级父类")
|
||||
private String second_category_name;
|
||||
|
||||
}
|
||||
103
client/src/main/java/com/small/client/dto/SxGoosModel.java
Normal file
103
client/src/main/java/com/small/client/dto/SxGoosModel.java
Normal file
@ -0,0 +1,103 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 思迅同步商品数据入口数据
|
||||
*/
|
||||
@Data
|
||||
public class SxGoosModel {
|
||||
|
||||
@ApiModelProperty("商品名称")
|
||||
private String product_name;
|
||||
|
||||
@ApiModelProperty("商品货号")
|
||||
private String product_number;
|
||||
|
||||
@ApiModelProperty("商品条形码")
|
||||
private String product_barcode;
|
||||
|
||||
@ApiModelProperty("一级分类")
|
||||
private String first_category_name;
|
||||
|
||||
@ApiModelProperty("二级分类")
|
||||
private String second_category_name;
|
||||
|
||||
@ApiModelProperty("三级分类")
|
||||
private String three_category_name;
|
||||
|
||||
@ApiModelProperty("产品类型")
|
||||
private String product_type;
|
||||
|
||||
@ApiModelProperty("商品种类")
|
||||
private String product_kind;
|
||||
|
||||
@ApiModelProperty("成本价")
|
||||
private BigDecimal cost_price;
|
||||
|
||||
@ApiModelProperty("零售价")
|
||||
private BigDecimal price;
|
||||
|
||||
@ApiModelProperty("原价")
|
||||
private BigDecimal original_price;
|
||||
|
||||
@ApiModelProperty("商品价格")
|
||||
private BigDecimal retail_price;
|
||||
|
||||
@ApiModelProperty("会员价")
|
||||
private BigDecimal member_price;
|
||||
|
||||
@ApiModelProperty("库存")
|
||||
private BigDecimal stock;
|
||||
|
||||
@ApiModelProperty("毛利率")
|
||||
private BigDecimal gross_margin;
|
||||
|
||||
@ApiModelProperty("规格单位")
|
||||
private String unit;
|
||||
|
||||
@ApiModelProperty("可用积分")
|
||||
private BigDecimal can_piont;
|
||||
|
||||
@ApiModelProperty("总积分")
|
||||
private BigDecimal points;
|
||||
|
||||
@ApiModelProperty("助记码")
|
||||
private String mnemonic;
|
||||
|
||||
|
||||
@ApiModelProperty("最大购买商品量")
|
||||
private Integer buy_limit;
|
||||
|
||||
@ApiModelProperty("品牌名称")
|
||||
private String brand_name;
|
||||
|
||||
@ApiModelProperty("标签")
|
||||
private String tags;
|
||||
|
||||
@ApiModelProperty("辅助属性")
|
||||
private List<String> product_assist;
|
||||
|
||||
@ApiModelProperty("规格(JSON)-规格、规格值、goods_id 规格不需要全选就可以添加对应数据[")
|
||||
private List<String> product_spec;
|
||||
|
||||
@ApiModelProperty("商品卖点特征")
|
||||
private String product_value;
|
||||
|
||||
@ApiModelProperty("商品视频")
|
||||
private String product_video;
|
||||
|
||||
@ApiModelProperty("产品描述")
|
||||
private String product_desc;
|
||||
|
||||
@ApiModelProperty("商品图片库")
|
||||
private List<ProductImage> product_images;
|
||||
|
||||
|
||||
@ApiModelProperty("商品详情")
|
||||
private List<PromotionDetail> promotion_detail;
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 思迅同步的商品分类表
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@ApiModel(value = "商品分类表", description = "商品分类表")
|
||||
public class SxSyncCategory implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "自增ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "店铺Id")
|
||||
private String store_id;
|
||||
|
||||
@ApiModelProperty(value = "分类编码")
|
||||
private String item_clsno;
|
||||
|
||||
@ApiModelProperty(value = "分类名称")
|
||||
private String item_clsname;
|
||||
|
||||
@ApiModelProperty(value = "父类编号")
|
||||
private String cls_parent;
|
||||
|
||||
@ApiModelProperty(value = "分类排序")
|
||||
private Integer item_order;
|
||||
|
||||
@ApiModelProperty(value = "是否显示:1-前台显示 0-前台不显示")
|
||||
private Integer display_flag;
|
||||
|
||||
@ApiModelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "同步时间戳")
|
||||
private Long sync_time;
|
||||
|
||||
@ApiModelProperty(value = "新增时间")
|
||||
private Date created_at;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updated_at;
|
||||
|
||||
@ApiModelProperty(value = "子节点")
|
||||
List<SxSyncCategory> children;
|
||||
}
|
||||
118
client/src/main/java/com/small/client/dto/SxSyncGoods.java
Normal file
118
client/src/main/java/com/small/client/dto/SxSyncGoods.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 思迅同步的商品表
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@ApiModel(value = "商品信息表", description = "商品信息表")
|
||||
public class SxSyncGoods implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "自增ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "店铺Id")
|
||||
private String store_id;
|
||||
|
||||
@ApiModelProperty(value = "商品编号")
|
||||
private String item_no;
|
||||
|
||||
@ApiModelProperty(value = "商品名称")
|
||||
private String item_subname;
|
||||
|
||||
@ApiModelProperty(value = "商品条码")
|
||||
private String item_subno;
|
||||
|
||||
@ApiModelProperty(value = "小分类编号")
|
||||
private String item_clsno;
|
||||
|
||||
@ApiModelProperty(value = "大分类名称")
|
||||
private String big_cls_name;
|
||||
|
||||
@ApiModelProperty(value = "小分类名称")
|
||||
private String small_cls_name;
|
||||
|
||||
@ApiModelProperty(value = "规格")
|
||||
private String item_size;
|
||||
|
||||
@ApiModelProperty(value = "单位")
|
||||
private String unit_no;
|
||||
|
||||
@ApiModelProperty(value = "库存")
|
||||
private BigDecimal stock;
|
||||
|
||||
@ApiModelProperty(value = "毛利率")
|
||||
private BigDecimal gross_margin;
|
||||
|
||||
@ApiModelProperty(value = "进货价")
|
||||
private BigDecimal price;
|
||||
|
||||
@ApiModelProperty(value = "零售价")
|
||||
private BigDecimal sale_price;
|
||||
|
||||
@ApiModelProperty(value = "会员价")
|
||||
private BigDecimal vip_price;
|
||||
|
||||
@ApiModelProperty(value = "允许积分")
|
||||
private BigDecimal vip_acc_flag;
|
||||
|
||||
@ApiModelProperty(value = "积分值")
|
||||
private BigDecimal vip_acc_num;
|
||||
|
||||
@ApiModelProperty(value = "商品状态")
|
||||
private Integer sale_flag;
|
||||
|
||||
@ApiModelProperty(value = "品牌名称")
|
||||
private String item_brand_name;
|
||||
|
||||
@ApiModelProperty(value = "商品助记号")
|
||||
private String item_rem;
|
||||
|
||||
@ApiModelProperty(value = "生产日期")
|
||||
private String build_date;
|
||||
|
||||
@ApiModelProperty(value = "质保期")
|
||||
private String valid_days;
|
||||
|
||||
@ApiModelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "同步时间戳")
|
||||
private Long sync_time;
|
||||
|
||||
@ApiModelProperty(value = "同步备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "新增时间")
|
||||
private Date created_at;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updated_at;
|
||||
|
||||
@ApiModelProperty(value = "品牌")
|
||||
private String itemBrand;
|
||||
|
||||
}
|
||||
|
||||
80
client/src/main/java/com/small/client/dto/SxSyncVip.java
Normal file
80
client/src/main/java/com/small/client/dto/SxSyncVip.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 思迅同步的商品表
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@ApiModel(value = "会员表", description = "会员表")
|
||||
public class SxSyncVip implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "自增ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "店铺Id")
|
||||
private String store_id;
|
||||
|
||||
@ApiModelProperty(value = "会员名称")
|
||||
private String vip_name;
|
||||
|
||||
@ApiModelProperty(value = "手机号")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "会员性别")
|
||||
private String vip_sex;
|
||||
|
||||
@ApiModelProperty(value = "会员生日")
|
||||
private String birthday;
|
||||
|
||||
@ApiModelProperty(value = "会员卡号(唯一键)")
|
||||
private String card_no;
|
||||
|
||||
@ApiModelProperty(value = "会员等级")
|
||||
private String card_type;
|
||||
|
||||
@ApiModelProperty(value = "储值余额")
|
||||
private BigDecimal residual_amt;
|
||||
|
||||
@ApiModelProperty(value = "会员积分")
|
||||
private BigDecimal now_acc_num;
|
||||
|
||||
@ApiModelProperty(value = "加入时间")
|
||||
private String vip_date;
|
||||
|
||||
@ApiModelProperty(value = "会员状态")
|
||||
private Integer card_status;
|
||||
|
||||
@ApiModelProperty(value = "同步时间")
|
||||
private Long sync_time;
|
||||
|
||||
@ApiModelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "新增时间")
|
||||
private Date created_at;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Date updated_at;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SyncGoodsSearchModel implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "分类名称")
|
||||
private String categoryName;//分类名称
|
||||
|
||||
@ApiModelProperty(value = "同步分类编号")
|
||||
private String itemClsno;
|
||||
|
||||
@ApiModelProperty(value = "操作时间")
|
||||
private String operDate;
|
||||
|
||||
@ApiModelProperty(value = "01全量,02增量")
|
||||
private String syncType;
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.small.client.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@ApiModel(description = "第三方会员同步请求参数")
|
||||
public class SyncThirdMemberReq{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("会员手机号")
|
||||
private String user_mobile;
|
||||
@ApiModelProperty("会员昵称")
|
||||
private String user_nickname;
|
||||
@ApiModelProperty("会员真实姓名")
|
||||
private String user_realname;
|
||||
@ApiModelProperty("会员性别:1-男;2-女;")
|
||||
private Integer user_gender;
|
||||
@ApiModelProperty("会员生日 yyyy-MM-dd")
|
||||
private String user_birthday;
|
||||
@ApiModelProperty("会员等级:v1...v9")
|
||||
private String user_level;
|
||||
@ApiModelProperty("会员卡号")
|
||||
private String user_level_card;
|
||||
@ApiModelProperty("会员积分值")
|
||||
private BigDecimal user_points;
|
||||
@ApiModelProperty("会员余额")
|
||||
private BigDecimal user_money;
|
||||
@ApiModelProperty("加入时间")
|
||||
private Date join_time;
|
||||
@ApiModelProperty("秒级别时间戳")
|
||||
private Long time_stamp;
|
||||
@ApiModelProperty("随机字符串")
|
||||
private String nonce_str;
|
||||
}
|
||||
15
client/src/main/java/com/small/client/dto/UploadModel.java
Normal file
15
client/src/main/java/com/small/client/dto/UploadModel.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.small.client.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UploadModel extends CommentModel{
|
||||
@ApiModelProperty("页数作为路径")
|
||||
private String page;
|
||||
@ApiModelProperty("同步类型1商品,2分类,3品牌,4会员")
|
||||
private String syncType;
|
||||
|
||||
}
|
||||
72
client/src/main/java/com/small/client/enums/DicEnum.java
Normal file
72
client/src/main/java/com/small/client/enums/DicEnum.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.small.client.enums;
|
||||
|
||||
|
||||
|
||||
public enum DicEnum {
|
||||
|
||||
SYNCTYPE_01("01","全量","syncType","同步类型","全量同步"),
|
||||
SYNCTYPE_02("02","增量","syncType","同步类型","增量同步"),
|
||||
|
||||
MUAL_1("1","商品","mual","商品","全量同步"),
|
||||
MUAL_2("2","分类","mual","分类","分类"),
|
||||
MUAL_3("3","品牌","mual","品牌","品牌"),
|
||||
MUAL_4("4","会员","mual","会员","会员"),
|
||||
;
|
||||
private String code;
|
||||
|
||||
private String value;
|
||||
|
||||
private String dicType;
|
||||
|
||||
private String dicName;
|
||||
|
||||
private String desc;
|
||||
|
||||
DicEnum(String code, String value, String dicType, String dicName, String desc) {
|
||||
this.code = code;
|
||||
this.value = value;
|
||||
this.dicType = dicType;
|
||||
this.dicName = dicName;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getDicType() {
|
||||
return dicType;
|
||||
}
|
||||
|
||||
public void setDicType(String dicType) {
|
||||
this.dicType = dicType;
|
||||
}
|
||||
|
||||
public String getDicName() {
|
||||
return dicName;
|
||||
}
|
||||
|
||||
public void setDicName(String dicName) {
|
||||
this.dicName = dicName;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,180 @@
|
||||
package com.small.client.service.SxDataAbst;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.small.client.Cache.CommonCache;
|
||||
import com.small.client.dao.SxDataDao;
|
||||
import com.small.client.dto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public abstract class SxDataAbstService {
|
||||
@Autowired
|
||||
private CommonCache commonCache;
|
||||
|
||||
/**
|
||||
* List<SxSyncVip> 转换为 List<SyncThirdMemberReq>
|
||||
* @param sxSyncVipList
|
||||
* @return
|
||||
*/
|
||||
public List<SyncThirdMemberReq> ConverList(List<SxSyncVip> sxSyncVipList){
|
||||
List<SyncThirdMemberReq> syncThirdMemberReqList=new ArrayList<>();
|
||||
if(CollUtil.isNotEmpty(sxSyncVipList)){
|
||||
SyncThirdMemberReq syncThirdMemberReq=null;
|
||||
for (SxSyncVip sxSyncVip : sxSyncVipList) {
|
||||
syncThirdMemberReq = new SyncThirdMemberReq();
|
||||
syncThirdMemberReq.setUser_nickname(sxSyncVip.getVip_name());
|
||||
syncThirdMemberReq.setUser_realname(sxSyncVip.getVip_name());
|
||||
if ("男".equals(sxSyncVip.getVip_name())) {//todo 需要确认数据是不是这样判断
|
||||
syncThirdMemberReq.setUser_gender(1);
|
||||
}
|
||||
if ("男".equals(sxSyncVip.getVip_name())) {
|
||||
syncThirdMemberReq.setUser_gender(2);
|
||||
}
|
||||
syncThirdMemberReq.setUser_mobile(sxSyncVip.getMobile());
|
||||
syncThirdMemberReq.setUser_birthday(sxSyncVip.getBirthday());
|
||||
syncThirdMemberReq.setUser_level(sxSyncVip.getCard_type());//todo 涉及会员等级字典转换
|
||||
syncThirdMemberReq.setUser_level_card(sxSyncVip.getCard_no());
|
||||
syncThirdMemberReq.setUser_points(sxSyncVip.getNow_acc_num());
|
||||
syncThirdMemberReq.setUser_money(sxSyncVip.getResidual_amt());
|
||||
if(sxSyncVip.getVip_date()!=null){
|
||||
try {
|
||||
syncThirdMemberReq.setJoin_time(DateUtils.parseDate(sxSyncVip.getVip_date()));
|
||||
} catch (ParseException e) {
|
||||
log.info("时间转换异常{0}",e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
syncThirdMemberReqList.add(syncThirdMemberReq);
|
||||
}
|
||||
}
|
||||
return syncThirdMemberReqList;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sxSyncCategories
|
||||
* @param allSxSyncCategories 所有分类
|
||||
* @return
|
||||
*/
|
||||
public List<SxCategoryModel> ConVToSxCategoryModel(List<SxSyncCategory> sxSyncCategories,List<SxSyncCategory> allSxSyncCategories) {
|
||||
if(CollectionUtil.isEmpty(sxSyncCategories)){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Iterator<SxSyncCategory> iterator= sxSyncCategories.iterator();
|
||||
List<SxCategoryModel> sxCategoryModels=new ArrayList<>();
|
||||
SxCategoryModel sxCategoryModel=null;
|
||||
while (iterator.hasNext()){
|
||||
SxSyncCategory sxSyncCategory= iterator.next();
|
||||
sxCategoryModel=new SxCategoryModel();
|
||||
sxCategoryModel.setCategory_image(SxDataDao.DEFAULT_IMG);
|
||||
sxCategoryModel.setCategory_name(sxSyncCategory.getItem_clsname());
|
||||
//寻找父级
|
||||
if(null!=sxSyncCategory.getCls_parent()){
|
||||
SxSyncCategory firstNode=getParentNode(allSxSyncCategories,sxSyncCategory.getCls_parent());
|
||||
sxCategoryModel.setParent_name(firstNode.getItem_clsname());//todo 暂时无用
|
||||
//如何存在上级的上级,则上级为第二层,上上及为第一层
|
||||
if(null!=firstNode.getCls_parent()) {//还存在上级
|
||||
SxSyncCategory secondNode=getParentNode(allSxSyncCategories,sxSyncCategory.getCls_parent());
|
||||
sxCategoryModel.setFirst_category_name(secondNode.getItem_clsname());
|
||||
sxCategoryModel.setSecond_category_name(firstNode.getItem_clsname());
|
||||
}else {
|
||||
sxCategoryModel.setFirst_category_name(firstNode.getItem_clsname());
|
||||
}
|
||||
}
|
||||
sxCategoryModels.add(sxCategoryModel);
|
||||
}
|
||||
return sxCategoryModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过流查找父节点
|
||||
* @param sxSyncCategories
|
||||
* @param parentId
|
||||
*/
|
||||
private SxSyncCategory getParentNode(List<SxSyncCategory> sxSyncCategories,String parentId){
|
||||
List<SxSyncCategory> list= sxSyncCategories.stream().filter(cc->
|
||||
cc.getItem_clsno().trim().equals(parentId.trim()))
|
||||
.collect(Collectors.toList());
|
||||
return CollectionUtil.isNotEmpty(list)?list.get(0):new SxSyncCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将List<sxSyncGoods>转换为List<SxGoosModel>
|
||||
* @param sxSyncGoods
|
||||
* @return
|
||||
*/
|
||||
public List<SxGoosModel> CvtToGoosModel(List<SxSyncGoods> sxSyncGoods,List<SpecPriceDto> specPriceDtoList){
|
||||
if(CollectionUtil.isEmpty(sxSyncGoods)){
|
||||
return null;
|
||||
}
|
||||
List<SxGoosModel> sxGoosModelList=new ArrayList<>();
|
||||
SxGoosModel sxGoosModel=null;
|
||||
for (SxSyncGoods sxSyncGood:sxSyncGoods){
|
||||
sxGoosModel=new SxGoosModel();
|
||||
sxGoosModel.setProduct_name(sxSyncGood.getItem_subname());
|
||||
sxGoosModel.setProduct_number(sxSyncGood.getItem_no().trim());// todo
|
||||
sxGoosModel.setProduct_barcode(sxSyncGood.getItem_subno());// todo
|
||||
|
||||
sxGoosModel.setFirst_category_name(commonCache.get(sxSyncGood.getSmall_cls_name()));// todo
|
||||
sxGoosModel.setSecond_category_name("");// todo
|
||||
|
||||
sxGoosModel.setThree_category_name("");// todo
|
||||
sxGoosModel.setProduct_type("");// todo
|
||||
sxGoosModel.setProduct_kind("");// todo
|
||||
sxGoosModel.setCost_price(sxSyncGood.getPrice());//成本价 todo
|
||||
sxGoosModel.setOriginal_price(sxSyncGood.getSale_price());//原价 todo
|
||||
sxGoosModel.setPrice(sxSyncGood.getSale_price());//
|
||||
sxGoosModel.setMember_price(sxSyncGood.getVip_price());//会员价
|
||||
sxGoosModel.setStock(sxSyncGood.getStock());//库存 todo
|
||||
sxGoosModel.setGross_margin(sxSyncGood.getGross_margin()); //毛利率 todo
|
||||
sxGoosModel.setUnit(sxSyncGood.getUnit_no());//单位
|
||||
sxGoosModel.setCan_piont(new BigDecimal(0));//可用积分 todo
|
||||
sxGoosModel.setPoints(sxSyncGood.getVip_acc_num());//总积分 todo
|
||||
sxGoosModel.setMnemonic(sxSyncGood.getItem_rem());//助记码 todo
|
||||
sxGoosModel.setRetail_price(sxSyncGood.getSale_price());
|
||||
// sxGoosModel.setBuy_limit(10);//最大购买商品量 todo
|
||||
sxGoosModel.setBrand_name(commonCache.get(sxSyncGood.getItemBrand()));//品牌 todo
|
||||
sxGoosModel.setTags("");//标签 todo
|
||||
|
||||
sxGoosModel.setProduct_assist(Arrays.asList(sxSyncGood.getItem_subname()));//帮助 todo
|
||||
|
||||
sxGoosModel.setProduct_spec(Collections.singletonList(sxSyncGood.getItem_size()==null?"":sxSyncGood.getItem_size()));//规格
|
||||
|
||||
sxGoosModel.setProduct_value("");//商品卖点特征 todo
|
||||
|
||||
sxGoosModel.setProduct_video("");//商品视频 todo
|
||||
|
||||
sxGoosModel.setProduct_desc("");//商品描述 todo
|
||||
|
||||
sxGoosModel.setProduct_images(new ArrayList<>());//介绍图片 todo
|
||||
|
||||
sxGoosModel.setPromotion_detail(new ArrayList<>());//活动列表 todo
|
||||
|
||||
SxGoosModel finalSxGoosModel = sxGoosModel;
|
||||
specPriceDtoList.forEach(m->{
|
||||
if(sxSyncGood.getItem_no().equals(m.getItemNo())){
|
||||
String type=m.getDiscountType();
|
||||
if(type.equals("1")){
|
||||
finalSxGoosModel.setPrice(m.getSpecPrice());
|
||||
finalSxGoosModel.setBuy_limit(m.getSaleQty());//最大购买商品量 todo
|
||||
}
|
||||
if(type.equals("2")){
|
||||
finalSxGoosModel.setPrice(finalSxGoosModel.getPrice().multiply(m.getDiscount()));
|
||||
}
|
||||
}
|
||||
});
|
||||
sxGoosModelList.add(sxGoosModel);
|
||||
}
|
||||
return sxGoosModelList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.small.client.service;
|
||||
|
||||
|
||||
import com.small.client.dto.*;
|
||||
|
||||
|
||||
public interface SxDataService {
|
||||
|
||||
/**
|
||||
* 同步商品分类数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
void SyncCategory(DataBaseInfo dataBaseInfo, CommentModel commentModel);
|
||||
|
||||
/**
|
||||
* 同步商品数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
void SyncGoods(DataBaseInfo dataBaseInfo, CommentModel commentModel);
|
||||
|
||||
/**
|
||||
* 品牌同步
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
void SyncBranchList(DataBaseInfo dataBaseInfo, CommentModel commentModel);
|
||||
|
||||
/**
|
||||
* 同步会员数据
|
||||
* @param dataBaseInfo
|
||||
*/
|
||||
void SyncVipList(DataBaseInfo dataBaseInfo, CommentModel commentModel);
|
||||
|
||||
|
||||
CommentModel getCommentModel();
|
||||
|
||||
void getAppSign();
|
||||
|
||||
String downLoadClient();
|
||||
|
||||
void checkForUpdates();
|
||||
|
||||
/**
|
||||
* 获取服务器配置
|
||||
* @param commentModel
|
||||
* @return
|
||||
*/
|
||||
DataBaseInfo getDataBaseInfo(CommentModel commentModel);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.small.client.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.small.client.Utils.FileUtils;
|
||||
import com.small.client.Utils.HttpUtils;
|
||||
import com.small.client.dto.CommentModel;
|
||||
import com.small.client.dto.UploadModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import netscape.javascript.JSObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WebClientService {
|
||||
@Value("${remoteIp}")
|
||||
private String remoteIp;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public WebClientService(RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
public String get(String url) {
|
||||
return restTemplate.getForObject(url, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*/
|
||||
public String uploudSxData(String filePath, CommentModel commentModel,String page,String syncType){
|
||||
UploadModel uploadModel=new UploadModel();
|
||||
uploadModel.setAppKey(commentModel.getAppKey());
|
||||
uploadModel.setSign(commentModel.getSign());
|
||||
uploadModel.setPage(page);
|
||||
uploadModel.setSyncType(syncType);
|
||||
//"C:\\Users\\Administrator\\uploaded\\2025\\3\\25\\goods_1.txt"
|
||||
return this.uploadFile(filePath, remoteIp+HttpUtils.URL_UPLOUP,uploadModel);
|
||||
}
|
||||
|
||||
|
||||
public String uploadFile(String filePath, String url, UploadModel uploadModel) {
|
||||
// 创建MultiValueMap来封装文件数据和请求参数(如果有的话)
|
||||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
FileSystemResource file = new FileSystemResource(filePath); // 文件路径
|
||||
body.add("file", file); // "file"是与服务器期望的表单字段名称相对应的键,例如在Spring Controller中用@RequestParam("file") String file接收文件数据
|
||||
body.add("appKey",uploadModel.getAppKey());
|
||||
body.add("sign",uploadModel.getSign());
|
||||
body.add("page",uploadModel.getPage());//页数
|
||||
body.add("syncType",uploadModel.getSyncType());//商品类型
|
||||
// 设置请求头,指定为multipart/form-data类型,并设置boundary(可选)
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
|
||||
// 创建HttpEntity对象,它将用于POST请求体中包含文件数据和请求头信息
|
||||
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
||||
|
||||
// 执行POST请求进行文件上传
|
||||
JSONObject jsonObject= restTemplate.exchange(url, HttpMethod.POST, requestEntity, JSONObject.class).getBody();
|
||||
log.info(jsonObject.toString());
|
||||
log.info(jsonObject.getStr("error_msg"));
|
||||
log.info(jsonObject.getStr("error_code"));
|
||||
return jsonObject.getStr("error_code");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// String responseStr= new WebClientService(new RestTemplate()).get("http://localhost:8088/mobile/account/login/testcase");
|
||||
|
||||
// String responseStr= new WebClientService(new RestTemplate()).get("http://localhost:8088/mobile/account/login/testcase");
|
||||
// System.out.printf(responseStr);
|
||||
// new WebClientService(new RestTemplate()).uploudSxData();
|
||||
log.info("测试");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,645 @@
|
||||
package com.small.client.service.imp;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.small.client.Cache.CommonCache;
|
||||
import com.small.client.Utils.*;
|
||||
import com.small.client.dao.SxDataDao;
|
||||
import com.small.client.dto.*;
|
||||
import com.small.client.enums.DicEnum;
|
||||
import com.small.client.service.SxDataAbst.SxDataAbstService;
|
||||
import com.small.client.service.SxDataService;
|
||||
|
||||
import com.small.client.service.WebClientService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.small.client.Utils.FileUtils.copyFile;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SxDataServiceImp extends SxDataAbstService implements SxDataService {
|
||||
@Autowired
|
||||
private SxDataDao sxDataDao;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Value("${remoteIp}")
|
||||
private String remoteIp;
|
||||
|
||||
@Autowired
|
||||
private CommonCache commonCache;
|
||||
|
||||
@Autowired
|
||||
private WebClientService webClientService;
|
||||
|
||||
|
||||
/**
|
||||
* 同步商品分类数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
@Override
|
||||
public void SyncCategory(DataBaseInfo dataBaseInfo, CommentModel commentModel) {
|
||||
dataBaseInfo= getDataBaseInfo(commentModel);
|
||||
// 记录总数
|
||||
Integer total = sxDataDao.getTBdItemClsTotal(dataBaseInfo);
|
||||
if(total==0){
|
||||
log.info("暂无商品分类同步");
|
||||
return;
|
||||
}
|
||||
// 总页数
|
||||
int pages = CommonUtil.getPagesCount(total, SxDataDao.PAGESIZE);
|
||||
List<SxSyncCategory> allSxSyncCategories= sxDataDao.findTBdItemClsList(dataBaseInfo);
|
||||
int syncCount =0;
|
||||
for (int i = 1; i <=pages; i++) {
|
||||
List<SxSyncCategory> sxSyncCategories= sxDataDao.findTBdItemClsListPage(dataBaseInfo,i,SxDataDao.PAGESIZE);
|
||||
List<SxCategoryModel> sxCategoryModelList= ConVToSxCategoryModel(sxSyncCategories,allSxSyncCategories);
|
||||
JSONArray jsonArray =null;
|
||||
String jsonString="";
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
jsonString = objectMapper.writeValueAsString(sxCategoryModelList);
|
||||
jsonArray = JSONUtil.parseArray(jsonString);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_CATEGORY
|
||||
+"?appKey="+commentModel.getAppKey()
|
||||
+"&sign="+commentModel.getSign(),jsonArray);//todo 后期改为文件传输
|
||||
if (!HttpUtils.SUCCESSCODE.equals(code)) {
|
||||
continue;
|
||||
}
|
||||
syncCount+=sxCategoryModelList.size();
|
||||
}
|
||||
log.info("商品分类总共有{}条数据,同步完成{}条",total,syncCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步商品数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
@Override
|
||||
public void SyncGoods(DataBaseInfo dataBaseInfo, CommentModel commentModel) {
|
||||
//dataBaseInfo= getDataBaseInfo(commentModel);
|
||||
String syncType ="01";
|
||||
if(StringUtils.isNotEmpty(commentModel.getSyncTime())){//如果有同步时间,则为增量
|
||||
syncType="02";
|
||||
dataBaseInfo.setSyncType("02");
|
||||
}
|
||||
if(StringUtils.isEmpty(syncType)){
|
||||
syncType="01";
|
||||
dataBaseInfo.setSyncType("01");
|
||||
}
|
||||
switch (syncType) {
|
||||
case "01"://全量
|
||||
syncAllGoods(dataBaseInfo, commentModel);
|
||||
break;
|
||||
case "02"://增量 todo test
|
||||
syncIncrementAddGoods(dataBaseInfo, commentModel);
|
||||
syncIncrementModifyGoods(dataBaseInfo, commentModel);
|
||||
syncIncrementStock(dataBaseInfo, commentModel);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步品牌数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
@Override
|
||||
public void SyncBranchList(DataBaseInfo dataBaseInfo, CommentModel commentModel) {
|
||||
dataBaseInfo= getDataBaseInfo(commentModel);
|
||||
List<BrandModel> brandModels= sxDataDao.getBdBrandList(dataBaseInfo);
|
||||
if(brandModels!=null&&brandModels.size()>0){
|
||||
String jsonString ="";
|
||||
JSONArray jsonArray =new JSONArray();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
jsonString = objectMapper.writeValueAsString(brandModels);
|
||||
jsonArray = JSONUtil.parseArray(jsonString);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_BRAND
|
||||
+"?appKey="+commentModel.getAppKey()
|
||||
+"&sign="+commentModel.getSign(),jsonArray);//todo 后期改为文件传输
|
||||
if(code!=null){
|
||||
log.info("品牌总共有{}条数据,同步完成{}条",brandModels.size(),brandModels.size());
|
||||
}
|
||||
}else {
|
||||
log.info("品牌数据为空");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
@Override
|
||||
public void SyncVipList(DataBaseInfo dataBaseInfo, CommentModel commentModel) {
|
||||
dataBaseInfo= getDataBaseInfo(commentModel);
|
||||
String where="where 1=1 ";
|
||||
if(StringUtils.isNotEmpty(commentModel.getSyncTime())){
|
||||
where+="and oper_date > '"+commentModel.getSyncTime()+"'";
|
||||
}
|
||||
dataBaseInfo.setWhere(where);
|
||||
// 记录总数
|
||||
Integer total = sxDataDao.getTrmVipInfoTotal(dataBaseInfo);
|
||||
if(total==0){
|
||||
log.info("暂无会员数据同步");
|
||||
return;
|
||||
}
|
||||
// 总页数
|
||||
int pages = CommonUtil.getPagesCount(total, SxDataDao.PAGESIZE);
|
||||
List<SyncThirdMemberReq> memberList=new ArrayList<>();
|
||||
int syncCount =0;
|
||||
for (int i = 1; i <=pages; i++) {
|
||||
memberList.clear();
|
||||
List<SxSyncVip> sxSyncVipList= sxDataDao.findRmVipInfoListPage(dataBaseInfo,i,SxDataDao.PAGESIZE);
|
||||
//处理数据转换SxSyncVip>SyncThirdMemberReq
|
||||
memberList=ConverList(sxSyncVipList);
|
||||
String jsonString ="";
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
jsonString = objectMapper.writeValueAsString(memberList);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_MEMBER
|
||||
+"?appKey="+commentModel.getAppKey()
|
||||
+"&sign="+commentModel.getSign(),memberList);//todo 后期改为文件传输
|
||||
if (!HttpUtils.SUCCESSCODE.equals(code)) {
|
||||
continue;
|
||||
}
|
||||
syncCount+=memberList.size();
|
||||
}
|
||||
log.info("vip会员总共有{}条数据,同步完成{}条",total,syncCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并缓存父节点的根节点,用户查找数据
|
||||
* @param dataBaseInfo
|
||||
* @param parentName
|
||||
*/
|
||||
public String getAndCacheTree(DataBaseInfo dataBaseInfo,String parentName){
|
||||
List<SxSyncCategory> sxSyncCategories=new SxDataDao().findTBdItemClsList(dataBaseInfo);
|
||||
String parentId= sxSyncCategories.stream().filter(m->m.getItem_clsname().equals(parentName)).
|
||||
map(SxSyncCategory::getItem_clsno).collect(Collectors.joining());
|
||||
getBdBrandCacheList(dataBaseInfo);
|
||||
String childrens=commonCache.get(CommonCache.CACHE_CATEGROY+parentId);
|
||||
if(childrens==null){
|
||||
log.info(JSONUtil.toJsonStr(buildTree(sxSyncCategories,parentId)));
|
||||
}
|
||||
return parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树节点
|
||||
* @param sxSyncCategories
|
||||
* @return
|
||||
*/
|
||||
public List<SxSyncCategory> buildTree(List<SxSyncCategory> sxSyncCategories,String parentId){
|
||||
List<SxSyncCategory> treeNodes=new ArrayList<>();
|
||||
List<SxSyncCategory> rootSxSyncCategory=getRootNode(sxSyncCategories);
|
||||
for (SxSyncCategory node : rootSxSyncCategory) {
|
||||
node=buildChildTree(node,sxSyncCategories,parentId);
|
||||
treeNodes.add(node);
|
||||
}
|
||||
return treeNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的根节点
|
||||
* @param sxSyncCategories
|
||||
* @return
|
||||
*/
|
||||
public List<SxSyncCategory> getRootNode(List<SxSyncCategory> sxSyncCategories){
|
||||
List<SxSyncCategory> rootNodeList=new ArrayList<>();
|
||||
for (SxSyncCategory node : sxSyncCategories) {
|
||||
if (null==node.getCls_parent()) {
|
||||
rootNodeList.add(node);
|
||||
}
|
||||
}
|
||||
return rootNodeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建子节点
|
||||
* @param root
|
||||
* @param sxSyncCategories
|
||||
* @return
|
||||
*/
|
||||
public SxSyncCategory buildChildTree(SxSyncCategory root,List<SxSyncCategory> sxSyncCategories,String findByParentId) {
|
||||
List<SxSyncCategory> children = new ArrayList<>();
|
||||
for (SxSyncCategory node : sxSyncCategories) {
|
||||
commonCache.put(node.getItem_clsno(),node.getItem_clsname());//把数据加入缓存
|
||||
if (root.getItem_clsno().equals(node.getCls_parent())) {
|
||||
children.add(buildChildTree(node,sxSyncCategories,findByParentId));
|
||||
}
|
||||
}
|
||||
if(root.getItem_clsno().equals(findByParentId)){
|
||||
commonCache.put(CommonCache.CACHE_CATEGROY+findByParentId,children.stream().map(SxSyncCategory::getItem_clsno).collect(Collectors.joining(",")));
|
||||
}
|
||||
root.setChildren(children);
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
*同步所有商品
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
private void syncAllGoods(DataBaseInfo dataBaseInfo, CommentModel commentModel){
|
||||
String where="where 1=1";
|
||||
Integer total =0;
|
||||
if(DicEnum.SYNCTYPE_02.getCode().equals(dataBaseInfo.getSyncType())){
|
||||
if (StringUtils.isNotEmpty(dataBaseInfo.getCategoryName())) {
|
||||
String parentId=getAndCacheTree(dataBaseInfo,dataBaseInfo.getCategoryName());
|
||||
String childrens= commonCache.get(CommonCache.CACHE_CATEGROY+parentId);
|
||||
//syncGoodsSearchModel.setItemClsno(childrens);
|
||||
where += " and b.item_clsno in ('" + childrens + "')";
|
||||
}
|
||||
if(StringUtils.isNotEmpty(commentModel.getSyncTime())){
|
||||
where+=" and b.modify_date>'"+commentModel.getSyncTime()+"' ";
|
||||
where+=" or b.build_date>'"+commentModel.getSyncTime()+"' ";
|
||||
}
|
||||
if(StringUtils.isNotEmpty(dataBaseInfo.getOperDate())){
|
||||
where+=" and t.oper_date>'"+dataBaseInfo.getOperDate()+"' ";
|
||||
}
|
||||
dataBaseInfo.setWhere(where);
|
||||
// 记录总数
|
||||
total = sxDataDao.getTBditemInfoJoninTotal(dataBaseInfo);
|
||||
}else {
|
||||
dataBaseInfo.setWhere(where);
|
||||
total = sxDataDao.getTBditemInfoTotal(dataBaseInfo);
|
||||
}
|
||||
if(total==0){
|
||||
log.info("暂无商品同步");
|
||||
return;
|
||||
}
|
||||
|
||||
// 总页数
|
||||
int pages = CommonUtil.getPagesCount(total, SxDataDao.PAGESIZE);
|
||||
int syncCount =0;
|
||||
|
||||
List<SpecPriceDto> discountList= getDiscountFromCache(dataBaseInfo);
|
||||
List<SpecPriceDto> specPriceDtoList= getSpecPriceFromCache(dataBaseInfo);
|
||||
specPriceDtoList.addAll(discountList);
|
||||
|
||||
List<String> folders=new ArrayList<>();
|
||||
for (int i = 1; i <=pages; i++) {
|
||||
List<SxSyncGoods> sxSyncGoods= sxDataDao.findBditemInfoListPage(dataBaseInfo,i,SxDataDao.PAGESIZE);
|
||||
List<SxGoosModel> sxGoosModelList= CvtToGoosModel(sxSyncGoods,specPriceDtoList);
|
||||
String jsonString="";
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
jsonString = objectMapper.writeValueAsString(sxGoosModelList);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String code= writeToFileAndUploud(i,jsonString,commentModel,DicEnum.MUAL_1.getCode());
|
||||
if (!HttpUtils.SUCCESSCODE.equals(code)) {
|
||||
continue;
|
||||
}
|
||||
folders.add(String.valueOf(i));
|
||||
syncCount+=sxSyncGoods.size();
|
||||
}
|
||||
// folders.add(String.valueOf(2));
|
||||
//folders.add(String.valueOf(4));
|
||||
//folders.add(String.valueOf(5));
|
||||
log.info("商品分类总共有{}条数据,同步完成{}条",total,syncCount);
|
||||
String code= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_GOODS_READ
|
||||
+"?appKey="+commentModel.getAppKey()
|
||||
+"&sign="+commentModel.getSign()
|
||||
+"&syncType="+DicEnum.MUAL_1.getCode(),
|
||||
JSONUtil.parseArray(folders));
|
||||
if (HttpUtils.SUCCESSCODE.equals(code)) {
|
||||
log.info("思迅商品同步完成,通知服务器处理数据相应成功");
|
||||
//记录同步时间
|
||||
createDateFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传到服务器
|
||||
* @param page
|
||||
* @param content
|
||||
* @param commentModel
|
||||
* @return
|
||||
*/
|
||||
private String writeToFileAndUploud(Integer page,String content,CommentModel commentModel,String syncType){
|
||||
FileUtils fileUtils= new FileUtils();
|
||||
File file=fileUtils.createFile(syncType,page);
|
||||
String fileName=fileUtils.getFileName(syncType,page,FileUtils.txtEnd);
|
||||
String filePath=file.getAbsolutePath();
|
||||
fileUtils.writeFile(filePath,fileName,content);
|
||||
return webClientService.uploudSxData(filePath+FileUtils.pathSeparator+fileName,commentModel,page.toString(),syncType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录同步时间
|
||||
*/
|
||||
private void createDateFile(){
|
||||
String path=JarPathUtil.getRuntimePath();
|
||||
FileUtils fileUtils= new FileUtils();
|
||||
File file=fileUtils.createFile(path);
|
||||
String filePath=file.getAbsolutePath();
|
||||
String date= DateUtil.format(new Date(),"yyyy-MM-dd");
|
||||
fileUtils.writeFile(filePath,FileUtils.REFLESHDATE,date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增量新增数据,新增商品数据
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
private void syncIncrementAddGoods(DataBaseInfo dataBaseInfo, CommentModel commentModel){
|
||||
syncAllGoods(dataBaseInfo,commentModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增量同步 商品内容变化
|
||||
* @param dataBaseInfo
|
||||
* @param commentModel
|
||||
*/
|
||||
private void syncIncrementModifyGoods(DataBaseInfo dataBaseInfo, CommentModel commentModel){
|
||||
syncAllGoods(dataBaseInfo,commentModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增量同步 库存变化
|
||||
*/
|
||||
private void syncIncrementStock(DataBaseInfo dataBaseInfo, CommentModel commentModel){
|
||||
dataBaseInfo.setOperDate(commentModel.getSyncTime());
|
||||
commentModel.setSyncTime("");
|
||||
syncAllGoods(dataBaseInfo,commentModel);
|
||||
}
|
||||
|
||||
/**
|
||||
*获取特价商品
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public List<SpecPriceDto> getDiscountFromCache(DataBaseInfo dataBaseInfo){
|
||||
List<SpecPriceDto> specPriceDtos= commonCache.getSpecPrice("specDiscountCache");
|
||||
if (null!=specPriceDtos){
|
||||
return specPriceDtos;
|
||||
}else {
|
||||
specPriceDtos= sxDataDao.getSpecPriceList(dataBaseInfo);
|
||||
commonCache.putSpecPrice("specDiscountCache",specPriceDtos);
|
||||
}
|
||||
return specPriceDtos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*获取促销产品数据
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public List<SpecPriceDto> getSpecPriceFromCache(DataBaseInfo dataBaseInfo){
|
||||
List<SpecPriceDto> specPriceDtos= commonCache.getSpecPrice("specPriceCache");
|
||||
if(null!=specPriceDtos){
|
||||
return specPriceDtos;
|
||||
}else {
|
||||
specPriceDtos= sxDataDao.getDiscountPriceList(dataBaseInfo);
|
||||
commonCache.putSpecPrice("specDiscountCache",specPriceDtos);
|
||||
}
|
||||
return specPriceDtos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取品牌数据并加入到缓存
|
||||
* @param dataBaseInfo
|
||||
* @return
|
||||
*/
|
||||
public void getBdBrandCacheList(DataBaseInfo dataBaseInfo){
|
||||
List<BrandModel> specPriceDtos= commonCache.getBrandCahce("brandCache");
|
||||
if(null==specPriceDtos){
|
||||
specPriceDtos= sxDataDao.getBdBrandList(dataBaseInfo);
|
||||
if(CollectionUtil.isNotEmpty(specPriceDtos)){
|
||||
for (BrandModel brandModel : specPriceDtos) {
|
||||
commonCache.put(brandModel.getCodeId(),brandModel.getBrand_name());
|
||||
}
|
||||
commonCache.setBrandCahce("brandCache",specPriceDtos);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommentModel getCommentModel() {
|
||||
String path=JarPathUtil.getRuntimePath();
|
||||
log.info(JarPathUtil.getRuntimePath());
|
||||
File folder = new File(path);
|
||||
//读取文件
|
||||
try {
|
||||
String encryptedData = getPrimaryKey();
|
||||
Map<String, String> result= CryptoUtils.decryptAndUnpack(encryptedData);
|
||||
CommentModel commentModel=new CommentModel();
|
||||
commentModel.setSign(result.get("sign"));
|
||||
commentModel.setAppKey(result.get("appKey"));
|
||||
commentModel.setStoreId(result.get("storeId"));
|
||||
//获取上次同步的最大时间
|
||||
File[] lastDateJsonFile = folder.listFiles((dir, name) -> name.endsWith(FileUtils.REFLESHDATE));
|
||||
if(lastDateJsonFile!=null&&lastDateJsonFile.length>0){
|
||||
String lastDate = new String(Files.readAllBytes(lastDateJsonFile[0].toPath()), StandardCharsets.UTF_8).trim();
|
||||
commentModel.setSyncTime(lastDate);
|
||||
}
|
||||
return commentModel;
|
||||
} catch (RuntimeException | IOException e) {
|
||||
throw new RuntimeException("密钥获取失败");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAppSign() {
|
||||
String encryptedData= getPrimaryKey();
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.putOnce("primaryKey",encryptedData);
|
||||
String primaryKey= HttpUtils.postData(restTemplate,remoteIp+HttpUtils.URL_SYNC_GET_APPSIGN
|
||||
+"?primaryKey="+encryptedData, jsonObject,"primaryKey");
|
||||
if(null!=primaryKey){
|
||||
String path=JarPathUtil.getRuntimePath();
|
||||
FileUtils fileUtils= new FileUtils();
|
||||
File file=fileUtils.createFile(path);
|
||||
String filePath=file.getAbsolutePath();
|
||||
fileUtils.writeFile(filePath,FileUtils.PRIMARYKEY,primaryKey);
|
||||
}else {
|
||||
log.info("获取服务器密钥失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文本密钥
|
||||
* @return
|
||||
*/
|
||||
private String getPrimaryKey(){
|
||||
String path=JarPathUtil.getRuntimePath();
|
||||
log.info("RuntimePath:{}",JarPathUtil.getRuntimePath());
|
||||
File folder = new File(path);
|
||||
File[] jsonFiles = folder.listFiles((dir, name) -> name.endsWith(FileUtils.PRIMARYKEY));
|
||||
if(null!=jsonFiles&&jsonFiles.length>0){
|
||||
try {
|
||||
return new String(Files.readAllBytes(jsonFiles[0].toPath()), StandardCharsets.UTF_8);
|
||||
}catch (RuntimeException | IOException e){
|
||||
throw new RuntimeException("读取[fileName]文件错误");
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String downLoadClient() {
|
||||
String downloadDirectory=FileUtils.CLIENTSTALLPATH;
|
||||
String originalFileName = "";
|
||||
try {
|
||||
File file= new File(downloadDirectory);
|
||||
if(!file.exists()){
|
||||
file.mkdirs(); // 确保目录存在
|
||||
}
|
||||
log.info("文件下载目录: {}", downloadDirectory);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
|
||||
String encryptedData = getPrimaryKey();
|
||||
|
||||
ResponseEntity<Resource> response = restTemplate.exchange(
|
||||
remoteIp+HttpUtils.URL_SYNC_GET_DOWNCLIENTJAR+"?primaryKey="+encryptedData,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
Resource.class);
|
||||
if(response.getStatusCode().is2xxSuccessful() && null!= response.getHeaders().getFirst("error")){
|
||||
String error=response.getHeaders().getFirst("error");
|
||||
switch (Objects.requireNonNull(error)){
|
||||
case "noVersion":
|
||||
log.info("没有版本更新");
|
||||
break;
|
||||
case "noFile":
|
||||
log.info("系统错误:文件不存在");
|
||||
break;
|
||||
case "500":;
|
||||
log.info("系统错误:系统内部错误");
|
||||
break;
|
||||
case "noValid":
|
||||
log.info("密钥校验失败:密钥过期");
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
|
||||
// 从Content-Disposition头获取文件名
|
||||
String contentDisposition = response.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
|
||||
if (contentDisposition != null && contentDisposition.contains("filename=")) {
|
||||
originalFileName = contentDisposition
|
||||
.split("filename=")[1]
|
||||
.replace("\"", ""); // 去除引号
|
||||
}
|
||||
// 如果无法从header获取,使用默认名
|
||||
if (originalFileName == null || originalFileName.isEmpty()) {
|
||||
originalFileName = "new_client" + System.currentTimeMillis()+".jar";
|
||||
}
|
||||
File outputFile = new File(downloadDirectory + originalFileName);
|
||||
try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
|
||||
StreamUtils.copy(response.getBody().getInputStream(), outputStream);
|
||||
log.info("文件下载成功: {}" , outputFile.getAbsolutePath());
|
||||
}catch (Exception e){
|
||||
log.error("下载失败,下载流异常:{}",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.error("文件下载失败: {}", response.getStatusCode());
|
||||
return null;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("文件下载失败:{}",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return downloadDirectory+originalFileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkForUpdates() {
|
||||
log.info("curentPath:{}",JarPathUtil.getRuntimePath());
|
||||
File classDirFile = new File(JarPathUtil.getRuntimePath());
|
||||
File parentDir = classDirFile.getParentFile();
|
||||
String filePath= this.downLoadClient();
|
||||
if (filePath != null) {
|
||||
copyFile(filePath,parentDir.getAbsolutePath()+"/lib");
|
||||
applyUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyUpdate() {
|
||||
try {
|
||||
File classDirFile = new File(JarPathUtil.getRuntimePath());
|
||||
File parentDir = classDirFile.getParentFile();
|
||||
// 执行脚本并退出当前应用
|
||||
log.info(parentDir.getAbsolutePath()+"/bin/run.bat");
|
||||
Runtime.getRuntime().exec(parentDir.getAbsolutePath()+"/bin/run.bat");
|
||||
log.info(parentDir.getAbsolutePath()+"/bin/run.bat");
|
||||
System.exit(0);
|
||||
} catch (IOException e) {
|
||||
log.error("异常{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataBaseInfo getDataBaseInfo(CommentModel commentModel) {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.putOnce("appKey",commentModel.getAppKey());
|
||||
jsonObject.putOnce("sign",commentModel.getSign());
|
||||
StoreDbConfig storeDbConfig= HttpUtils.postDataGetConfig(restTemplate,remoteIp+HttpUtils.URL_SYNC_GET_STOREdBCONFIG
|
||||
+"?appKey="+commentModel.getAppKey()
|
||||
+"&sign="+commentModel.getSign(), jsonObject);
|
||||
DataBaseInfo dataBaseInfo=new DataBaseInfo();
|
||||
if(null!=storeDbConfig){
|
||||
dataBaseInfo.setIp(storeDbConfig.getDbIp());
|
||||
dataBaseInfo.setPassword(storeDbConfig.getDbPassword());
|
||||
dataBaseInfo.setDataBaseName(storeDbConfig.getDbName());
|
||||
dataBaseInfo.setDbPort(storeDbConfig.getDbPort());
|
||||
dataBaseInfo.setSyncMode(storeDbConfig.getSyncMode());
|
||||
dataBaseInfo.setCronExpression(storeDbConfig.getCronExpression());
|
||||
dataBaseInfo.setCategoryName(storeDbConfig.getCategoryName());
|
||||
return dataBaseInfo;
|
||||
}
|
||||
return new DataBaseInfo();
|
||||
}
|
||||
|
||||
}
|
||||
15
client/src/main/resources/application.yml
Normal file
15
client/src/main/resources/application.yml
Normal file
@ -0,0 +1,15 @@
|
||||
server:
|
||||
port: 9099
|
||||
servlet:
|
||||
encoding:
|
||||
charset: UTF-8
|
||||
enabled: true
|
||||
force: true
|
||||
|
||||
#配置远程模板信息
|
||||
#服务器地址
|
||||
logging:
|
||||
charset:
|
||||
console: UTF-8
|
||||
|
||||
remoteIp: https://mall.gpxscs.cn
|
||||
19
client/src/main/resources/logback.xml
Normal file
19
client/src/main/resources/logback.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration>
|
||||
<configuration>
|
||||
<!--引用默认日志配置-->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<!--使用默认的控制台日志输出实现-->
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
|
||||
|
||||
<!--接口访问记录日志输出到LogStash-->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<charset>UTF-8</charset>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
Loading…
Reference in New Issue
Block a user