huanglizhi пре 11 месеци
родитељ
комит
72c7be025c

+ 143 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/AmazonInventorySynchronizer.java

@@ -0,0 +1,143 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.FeedsApi;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.model.feeds.*;
+import com.amazon.spapi.SellingPartnerAPIAA.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AmazonInventorySynchronizer {
+
+    private final FeedsApi feedsApi;
+    private final String sellerId;
+    private final List<String> marketplaceIds;
+
+    public AmazonInventorySynchronizer(String sellerId, List<String> marketplaceIds) {
+        this.sellerId = sellerId;
+        this.marketplaceIds = marketplaceIds;
+        this.feedsApi = initializeFeedsApi();
+    }
+
+    private FeedsApi initializeFeedsApi() {
+        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                .clientId("YOUR_LWA_CLIENT_ID")
+                .clientSecret("YOUR_LWA_CLIENT_SECRET")
+                .refreshToken("YOUR_REFRESH_TOKEN")
+                .endpoint("https://api.amazon.com/auth/o2/token")
+                .build();
+
+        AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                .secretKey("YOUR_AWS_SECRET_KEY")
+                .region("YOUR_AWS_REGION")
+                .build();
+
+        AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
+                .roleArn("YOUR_ROLE_ARN")
+                .roleSessionName("session-name")
+                .build();
+
+        return new FeedsApi.Builder()
+                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
+                .endpoint("https://sellingpartnerapi-na.amazon.com")
+                .build();
+    }
+
+    public void syncInventory(Map<String, Integer> localInventory) {
+        try {
+            // 创建 XML 格式的库存更新 feed
+            String feedContent = createInventoryFeedContent(localInventory);
+
+            // 创建 feed 文档
+            CreateFeedDocumentSpecification feedDocSpec = new CreateFeedDocumentSpecification()
+                    .contentType("text/xml; charset=UTF-8");
+            CreateFeedDocumentResponse feedDocResponse = feedsApi.createFeedDocument(feedDocSpec);
+
+            // 上传 feed 内容
+            uploadFeedDocument(feedDocResponse.getUrl(), feedContent);
+
+            // 创建 feed
+            CreateFeedSpecification feedSpec = new CreateFeedSpecification()
+                    .feedType("POST_INVENTORY_AVAILABILITY_DATA")
+                    .marketplaceIds(marketplaceIds)
+                    .inputFeedDocumentId(feedDocResponse.getFeedDocumentId());
+
+            CreateFeedResponse feedResponse = feedsApi.createFeed(feedSpec);
+
+            System.out.println("Inventory feed submitted. Feed ID: " + feedResponse.getFeedId());
+
+        } catch (ApiException | IOException e) {
+            System.err.println("Error synchronizing inventory: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    private void uploadFeedDocument(String url, String content) throws IOException {
+        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+        connection.setDoOutput(true);
+        connection.setRequestMethod("PUT");
+        connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
+
+        try (OutputStream os = connection.getOutputStream()) {
+            byte[] input = content.getBytes(StandardCharsets.UTF_8);
+            os.write(input, 0, input.length);
+        }
+
+        int responseCode = connection.getResponseCode();
+        if (responseCode != HttpURLConnection.HTTP_OK) {
+            throw new IOException("HTTP error code: " + responseCode);
+        }
+    }
+
+    private String createInventoryFeedContent(Map<String, Integer> localInventory) {
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        xmlBuilder.append("<AmazonEnvelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"amzn-envelope.xsd\">\n");
+        xmlBuilder.append("  <Header>\n");
+        xmlBuilder.append("    <DocumentVersion>1.01</DocumentVersion>\n");
+        xmlBuilder.append("    <MerchantIdentifier>").append(sellerId).append("</MerchantIdentifier>\n");
+        xmlBuilder.append("  </Header>\n");
+        xmlBuilder.append("  <MessageType>Inventory</MessageType>\n");
+
+        int messageId = 1;
+        for (Map.Entry<String, Integer> entry : localInventory.entrySet()) {
+            xmlBuilder.append("  <Message>\n");
+            xmlBuilder.append("    <MessageID>").append(messageId++).append("</MessageID>\n");
+            xmlBuilder.append("    <OperationType>Update</OperationType>\n");
+            xmlBuilder.append("    <Inventory>\n");
+            xmlBuilder.append("      <SKU>").append(entry.getKey()).append("</SKU>\n");
+            xmlBuilder.append("      <Quantity>").append(entry.getValue()).append("</Quantity>\n");
+            xmlBuilder.append("    </Inventory>\n");
+            xmlBuilder.append("  </Message>\n");
+        }
+
+        xmlBuilder.append("</AmazonEnvelope>");
+        return xmlBuilder.toString();
+    }
+
+    // 示例使用方法
+    public static void main(String[] args) {
+        String sellerId = "YOUR_SELLER_ID";
+        List<String> marketplaceIds = Arrays.asList("YOUR_MARKETPLACE_ID");
+        AmazonInventorySynchronizer synchronizer = new AmazonInventorySynchronizer(sellerId, marketplaceIds);
+
+        Map<String, Integer> localInventory = new HashMap<>();
+        localInventory.put("SKU001", 100);
+        localInventory.put("SKU002", 50);
+        localInventory.put("SKU003", 75);
+
+        synchronizer.syncInventory(localInventory);
+    }
+}

+ 105 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/AmazonOrderFetcher.java

@@ -0,0 +1,105 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.OrdersV0Api;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.model.orders.*;
+import com.amazon.spapi.SellingPartnerAPIAA.*;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.util.Arrays;
+import java.util.List;
+
+public class AmazonOrderFetcher {
+
+    private final OrdersV0Api ordersApi;
+    private final List<String> marketplaceIds;
+
+    public AmazonOrderFetcher(List<String> marketplaceIds) {
+        this.marketplaceIds = marketplaceIds;
+        this.ordersApi = initializeOrdersApi();
+    }
+
+    private OrdersV0Api initializeOrdersApi() {
+        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                .clientId("YOUR_LWA_CLIENT_ID")
+                .clientSecret("YOUR_LWA_CLIENT_SECRET")
+                .refreshToken("YOUR_REFRESH_TOKEN")
+                .endpoint("https://api.amazon.com/auth/o2/token")
+                .build();
+
+        AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                .secretKey("YOUR_AWS_SECRET_KEY")
+                .region("YOUR_AWS_REGION")
+                .build();
+
+        AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
+                .roleArn("YOUR_ROLE_ARN")
+                .roleSessionName("session-name")
+                .build();
+
+        return new OrdersV0Api.Builder()
+                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
+                .endpoint("https://sellingpartnerapi-na.amazon.com")
+                .build();
+    }
+
+    public void fetchOrders(String createdAfter, String createdBefore) {
+        try {
+            GetOrdersResponse ordersResponse = ordersApi.getOrders(
+                    marketplaceIds,
+                    createdAfter,
+                    createdBefore,
+                    null, // LastUpdatedAfter
+                    null, // LastUpdatedBefore
+                    Arrays.asList("UNSHIPPED", "PARTIALLY_SHIPPED", "SHIPPED"), // OrderStatuses
+                    null, // FulfillmentChannels
+                    null, // PaymentMethods
+                    null, // BuyerEmail
+                    null, // SellerOrderId
+                    null, // MaxResultsPerPage
+                    null, // EasyShipShipmentStatuses
+                    null, // NextToken
+                    null, // AmazonOrderIds
+                    null,  // ActualFulfillmentSupplySourceId
+                    null,
+                    null
+            );
+
+            List<Order> orders = ordersResponse.getPayload().getOrders();
+            for (Order order : orders) {
+                System.out.println("Order ID: " + order.getAmazonOrderId());
+                System.out.println("Order Status: " + order.getOrderStatus());
+                System.out.println("Purchase Date: " + order.getPurchaseDate());
+
+                // 获取订单项目
+                GetOrderItemsResponse itemsResponse = ordersApi.getOrderItems(order.getAmazonOrderId(),null);
+                List<OrderItem> orderItems = itemsResponse.getPayload().getOrderItems();
+
+                System.out.println("Number of items: " + orderItems.size());
+                for (OrderItem item : orderItems) {
+                    System.out.println("  - SKU: " + item.getSellerSKU());
+                    System.out.println("    Title: " + item.getTitle());
+                    System.out.println("    Quantity: " + item.getQuantityOrdered());
+                    System.out.println("    Price: " + item.getItemPrice().getAmount() + " " + item.getItemPrice().getCurrencyCode());
+                    //把已经售卖的商品数量在我们自己的商品库存里面减去
+                }
+                System.out.println("--------------------");
+            }
+
+        } catch (ApiException e) {
+            System.err.println("Exception when calling OrdersV0Api: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        List<String> marketplaceIds = Arrays.asList("YOUR_MARKETPLACE_ID");
+        AmazonOrderFetcher fetcher = new AmazonOrderFetcher(marketplaceIds);
+        // 获取过去7天的订单
+        fetcher.fetchOrders(LocalDateTime.now().toString(), LocalDateTime.now().minusDays(7).toString());
+    }
+}

+ 82 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/AmazonProductPusher.java

@@ -0,0 +1,82 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.ListingsApi;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.SellingPartnerAPIAA.LWAAuthorizationCredentials;
+import com.amazon.spapi.SellingPartnerAPIAA.AWSAuthenticationCredentials;
+import com.amazon.spapi.SellingPartnerAPIAA.AWSAuthenticationCredentialsProvider;
+import com.amazon.spapi.model.catalogitems.Item;
+import com.amazon.spapi.model.catalogitems.ItemProductTypes;
+import com.amazon.spapi.model.listingsitems.ListingsItemPatchRequest;
+import com.amazon.spapi.model.listingsitems.PatchOperation;
+
+import java.util.*;
+
+public class AmazonProductPusher {
+
+    public static void pushProduct() {
+        try {
+            // 设置 LWA 凭证
+            LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                    .clientId("YOUR_LWA_CLIENT_ID")
+                    .clientSecret("YOUR_LWA_CLIENT_SECRET")
+                    .refreshToken("YOUR_REFRESH_TOKEN")
+                    .endpoint("https://api.amazon.com/auth/o2/token")
+                    .build();
+
+            // 设置 AWS 凭证
+            AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                    .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                    .secretKey("YOUR_AWS_SECRET_KEY")
+                    .region("YOUR_AWS_REGION")
+                    .build();
+
+            AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
+                    .roleArn("YOUR_ROLE_ARN")
+                    .roleSessionName("session-name")
+                    .build();
+
+            // 初始化 ListingsApi
+            ListingsApi listingsApi = new ListingsApi.Builder()
+                    .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                    .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                    .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
+                    .endpoint("https://sellingpartnerapi-na.amazon.com")  // 根据你的区域选择正确的端点
+                    .build();
+
+            // 创建产品信息
+            Map<String, Object> attributes = new HashMap<>();
+            attributes.put("title", "Your Product Title");
+            attributes.put("brand", "Your Brand");
+            attributes.put("product_type", "PRODUCT_TYPE");
+            // 添加其他必要的属性...
+
+            List<PatchOperation> patchOperations = new ArrayList<>();
+            patchOperations.add(new PatchOperation()
+                    .op(PatchOperation.OpEnum.REPLACE)
+                    .path("/attributes")
+                    .value(new ArrayList<>()));
+
+            ListingsItemPatchRequest patchRequest = new ListingsItemPatchRequest()
+                    .productType("PRODUCT_TYPE")
+                    .patches(patchOperations);
+
+            // 推送产品
+            listingsApi.patchListingsItem("YOUR_SELLER_ID",
+                    "YOUR_SKU",
+                    Arrays.asList("YOUR_MARKETPLACE_ID"),
+                    patchRequest,
+                    "PATCH_LISTINGS_ITEM");
+
+            System.out.println("Product pushed successfully!");
+
+        } catch (ApiException e) {
+            System.err.println("Exception when calling ListingsApi#patchListingsItem");
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        pushProduct();
+    }
+}

+ 98 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/AmazonProductUpdater.java

@@ -0,0 +1,98 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.ListingsApi;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.SellingPartnerAPIAA.LWAAuthorizationCredentials;
+import com.amazon.spapi.SellingPartnerAPIAA.AWSAuthenticationCredentials;
+import com.amazon.spapi.SellingPartnerAPIAA.AWSAuthenticationCredentialsProvider;
+import com.amazon.spapi.model.listingsitems.ListingsItemPatchRequest;
+import com.amazon.spapi.model.listingsitems.PatchOperation;
+
+import java.util.*;
+
+public class AmazonProductUpdater {
+
+    private final ListingsApi listingsApi;
+    private final String sellerId;
+    private final List<String> marketplaceIds;
+
+    public AmazonProductUpdater(String sellerId, List<String> marketplaceIds) {
+        this.sellerId = sellerId;
+        this.marketplaceIds = marketplaceIds;
+        this.listingsApi = initializeListingsApi();
+    }
+
+    private ListingsApi initializeListingsApi() {
+        // 设置 LWA 凭证
+        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                .clientId("YOUR_LWA_CLIENT_ID")
+                .clientSecret("YOUR_LWA_CLIENT_SECRET")
+                .refreshToken("YOUR_REFRESH_TOKEN")
+                .endpoint("https://api.amazon.com/auth/o2/token")
+                .build();
+
+        // 设置 AWS 凭证
+        AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                .secretKey("YOUR_AWS_SECRET_KEY")
+                .region("YOUR_AWS_REGION")
+                .build();
+
+        AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
+                .roleArn("YOUR_ROLE_ARN")
+                .roleSessionName("session-name")
+                .build();
+
+        // 初始化并返回 ListingsApi
+        return new ListingsApi.Builder()
+                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
+                .endpoint("https://sellingpartnerapi-na.amazon.com")  // 根据您的区域选择正确的端点
+                .build();
+    }
+
+    public void updateProduct(String sku, Map<String, Object> updatedAttributes) {
+        try {
+            List<PatchOperation> patchOperations = new ArrayList<>();
+
+            // 为每个更新的属性创建一个 PatchOperation
+            for (Map.Entry<String, Object> entry : updatedAttributes.entrySet()) {
+                patchOperations.add(new PatchOperation()
+                        .op(PatchOperation.OpEnum.REPLACE)
+                        .path("attributes/" + entry.getKey())
+                        .value(new ArrayList<>()));
+            }
+
+            ListingsItemPatchRequest patchRequest = new ListingsItemPatchRequest()
+                    .productType("PRODUCT_TYPE")  // 根据实际产品类型设置
+                    .patches(patchOperations);
+
+            // 调用 API 更新商品
+            listingsApi.patchListingsItem(sellerId, sku, marketplaceIds, patchRequest, "PATCH_LISTINGS_ITEM");
+
+            System.out.println("Product " + sku + " updated successfully on Amazon!");
+        } catch (ApiException e) {
+            System.err.println("Error updating product " + sku + " on Amazon: " + e.getMessage());
+            System.err.println("Response body: " + e.getResponseBody());
+            e.printStackTrace();
+        }
+    }
+
+    // 示例使用方法
+    public static void main(String[] args) {
+        String sellerId = "YOUR_SELLER_ID";
+        List<String> marketplaceIds = Arrays.asList("YOUR_MARKETPLACE_ID");
+        AmazonProductUpdater updater = new AmazonProductUpdater(sellerId, marketplaceIds);
+
+        // 假设这是从您的后台系统获取的更新信息
+        String skuToUpdate = "YOUR_PRODUCT_SKU";
+        Map<String, Object> updatedAttributes = new HashMap<>();
+        updatedAttributes.put("title", "Updated Product Title");
+        updatedAttributes.put("brand", "Updated Brand");
+        updatedAttributes.put("bullet_point", Arrays.asList("New feature 1", "New feature 2"));
+        updatedAttributes.put("list_price", 29.99);
+
+        updater.updateProduct(skuToUpdate, updatedAttributes);
+    }
+}

+ 148 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/AmazonStoreManager.java

@@ -0,0 +1,148 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.SellersApi;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.model.sellers.*;
+import com.amazon.spapi.SellingPartnerAPIAA.*;
+
+import java.sql.*;
+import java.util.Arrays;
+import java.util.List;
+
+public class AmazonStoreManager {
+
+    private final SellersApi sellersApi;
+    private final List<String> marketplaceIds;
+    private final Connection dbConnection;
+
+    public AmazonStoreManager(List<String> marketplaceIds, String dbUrl, String dbUser, String dbPassword) throws SQLException {
+        this.marketplaceIds = marketplaceIds;
+        this.sellersApi = initializeSellersApi();
+        this.dbConnection = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
+    }
+
+    private SellersApi initializeSellersApi() {
+        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                .clientId("YOUR_LWA_CLIENT_ID")
+                .clientSecret("YOUR_LWA_CLIENT_SECRET")
+                .refreshToken("YOUR_REFRESH_TOKEN")
+                .endpoint("https://api.amazon.com/auth/o2/token")
+                .build();
+
+        AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                .secretKey("YOUR_AWS_SECRET_KEY")
+                .region("YOUR_AWS_REGION")
+                .build();
+
+        AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider.builder()
+                .roleArn("YOUR_ROLE_ARN")
+                .roleSessionName("session-name")
+                .build();
+
+        return new SellersApi.Builder()
+                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
+                .endpoint("https://sellingpartnerapi-na.amazon.com")
+                .build();
+    }
+
+    public void fetchAndSaveStoreInfo() {
+        try {
+            GetMarketplaceParticipationsResponse response = sellersApi.getMarketplaceParticipations();
+            List<MarketplaceParticipation> participations = response.getPayload();
+
+            for (MarketplaceParticipation participation : participations) {
+                Marketplace marketplace = participation.getMarketplace();
+                Participation participationData = participation.getParticipation();
+
+                // 保存到数据库
+                String sql = "INSERT INTO amazon_stores (marketplace_id, name, country_code, default_currency_code, default_language_code, domain_name, is_participating) " +
+                        "VALUES (?, ?, ?, ?, ?, ?, ?) " +
+                        "ON DUPLICATE KEY UPDATE name = ?, country_code = ?, default_currency_code = ?, default_language_code = ?, domain_name = ?, is_participating = ?";
+
+                try (PreparedStatement pstmt = dbConnection.prepareStatement(sql)) {
+                    pstmt.setString(1, marketplace.getId());
+                    pstmt.setString(2, marketplace.getName());
+                    pstmt.setString(3, marketplace.getCountryCode());
+                    pstmt.setString(4, marketplace.getDefaultCurrencyCode());
+                    pstmt.setString(5, marketplace.getDefaultLanguageCode());
+                    pstmt.setString(6, marketplace.getDomainName());
+                    pstmt.setBoolean(7, participationData.isIsParticipating());
+
+                    // 更新部分
+                    pstmt.setString(8, marketplace.getName());
+                    pstmt.setString(9, marketplace.getCountryCode());
+                    pstmt.setString(10, marketplace.getDefaultCurrencyCode());
+                    pstmt.setString(11, marketplace.getDefaultLanguageCode());
+                    pstmt.setString(12, marketplace.getDomainName());
+                    pstmt.setBoolean(13, participationData.isIsParticipating());
+
+                    pstmt.executeUpdate();
+                }
+            }
+        } catch (ApiException | SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void updateLocalStoreInfo(String marketplaceId, boolean isParticipating) {
+        String sql = "UPDATE amazon_stores SET is_participating = ? WHERE marketplace_id = ?";
+        try (PreparedStatement pstmt = dbConnection.prepareStatement(sql)) {
+            pstmt.setBoolean(1, isParticipating);
+            pstmt.setString(2, marketplaceId);
+            pstmt.executeUpdate();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void syncStoreInfoToAmazon() {
+        String sql = "SELECT marketplace_id, is_participating FROM amazon_stores";
+        try (Statement stmt = dbConnection.createStatement();
+             ResultSet rs = stmt.executeQuery(sql)) {
+            while (rs.next()) {
+                String marketplaceId = rs.getString("marketplace_id");
+                boolean isParticipating = rs.getBoolean("is_participating");
+
+                // 这里应该调用亚马逊的API来更新店铺信息
+                // 注意:亚马逊可能不允许直接修改某些店铺信息,这里仅作为示例
+                System.out.println("Syncing store info for marketplace " + marketplaceId + ": isParticipating = " + isParticipating);
+                // 实际的API调用应该放在这里
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void close() {
+        try {
+            if (dbConnection != null && !dbConnection.isClosed()) {
+                dbConnection.close();
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        List<String> marketplaceIds = Arrays.asList("YOUR_MARKETPLACE_ID");
+        try {
+            AmazonStoreManager manager = new AmazonStoreManager(marketplaceIds, "jdbc:mysql://localhost:3306/your_database", "your_username", "your_password");
+
+            // 从亚马逊拉取店铺信息并保存到本地
+            manager.fetchAndSaveStoreInfo();
+
+            // 在本地更新店铺信息
+            manager.updateLocalStoreInfo("YOUR_MARKETPLACE_ID", false);
+
+            // 将本地更改同步回亚马逊
+            manager.syncStoreInfoToAmazon();
+
+            manager.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 175 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/OrderFulfillmentManager.java

@@ -0,0 +1,175 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.amazon.spapi.api.FeedsApi;
+import com.amazon.spapi.api.OrdersV0Api;
+import com.amazon.spapi.client.ApiException;
+import com.amazon.spapi.model.feeds.CreateFeedDocumentResponse;
+import com.amazon.spapi.model.feeds.CreateFeedDocumentSpecification;
+import com.amazon.spapi.model.feeds.CreateFeedResponse;
+import com.amazon.spapi.model.feeds.CreateFeedSpecification;
+import com.amazon.spapi.model.orders.*;
+import com.amazon.spapi.SellingPartnerAPIAA.*;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.time.OffsetDateTime;
+
+public class OrderFulfillmentManager {
+    private OrdersV0Api ordersApi;
+    private FeedsApi feedsApi;
+
+    public OrderFulfillmentManager() {
+        // 初始化 OrdersV0Api
+        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
+                .clientId("YOUR_CLIENT_ID")
+                .clientSecret("YOUR_CLIENT_SECRET")
+                .refreshToken("YOUR_REFRESH_TOKEN")
+                .endpoint("https://api.amazon.com/auth/o2/token")
+                .build();
+
+        AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
+                .accessKeyId("YOUR_AWS_ACCESS_KEY")
+                .secretKey("YOUR_AWS_SECRET_KEY")
+                .region("YOUR_AWS_REGION")
+                .build();
+
+        this.ordersApi = new OrdersV0Api.Builder()
+                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
+                .awsAuthenticationCredentials(awsAuthenticationCredentials)
+                .endpoint("https://sellingpartnerapi-na.amazon.com")
+                .build();
+    }
+
+    public List<Order> getPendingOrders(String marketplaceId) throws ApiException {
+        GetOrdersResponse response = ordersApi.getOrders(
+                Arrays.asList(marketplaceId),
+                OffsetDateTime.now().minusDays(7).toString(), // 获取最近7天的订单
+                null, null, null,
+                Arrays.asList("Unshipped"), // 只获取未发货的订单
+                null, null,null,null, null, null, null, null, null, null, null
+        );
+        return response.getPayload().getOrders();
+    }
+
+
+    public void fulfillOrders(List<Order> orders, List<String> trackingNumbers, List<String> carrierCodes) throws ApiException, IOException {
+        if (orders.size() != trackingNumbers.size() || orders.size() != carrierCodes.size()) {
+            throw new IllegalArgumentException("订单数量与跟踪号和承运商代码数量不匹配");
+        }
+
+        String xmlContent = createFulfillmentXml(orders, trackingNumbers, carrierCodes);
+
+        // 创建 feed 文档
+        CreateFeedDocumentSpecification feedDocSpec = new CreateFeedDocumentSpecification()
+                .contentType("text/xml; charset=UTF-8");
+        CreateFeedDocumentResponse feedDocResponse = feedsApi.createFeedDocument(feedDocSpec);
+
+        // 上传 feed 内容
+        uploadFeedDocument(feedDocResponse.getUrl(), xmlContent);
+
+        // 提交 feed
+        CreateFeedSpecification feedSpec = new CreateFeedSpecification()
+                .feedType("POST_ORDER_FULFILLMENT_DATA")
+                .marketplaceIds(Arrays.asList("YOUR_MARKETPLACE_ID"))
+                .inputFeedDocumentId(feedDocResponse.getFeedDocumentId());
+
+        CreateFeedResponse feedResponse = feedsApi.createFeed(feedSpec);
+
+        System.out.println("Feed submitted with id: " + feedResponse.getFeedId());
+    }
+
+    private String createFulfillmentXml(List<Order> orders, List<String> trackingNumbers, List<String> carrierCodes) {
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        xmlBuilder.append("<AmazonEnvelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"amzn-envelope.xsd\">\n");
+        xmlBuilder.append("  <Header>\n");
+        xmlBuilder.append("    <DocumentVersion>1.01</DocumentVersion>\n");
+        xmlBuilder.append("    <MerchantIdentifier>YOUR_MERCHANT_ID</MerchantIdentifier>\n");
+        xmlBuilder.append("  </Header>\n");
+        xmlBuilder.append("  <MessageType>OrderFulfillment</MessageType>\n");
+
+        for (int i = 0; i < orders.size(); i++) {
+            Order order = orders.get(i);
+            String trackingNumber = trackingNumbers.get(i);
+            String carrierCode = carrierCodes.get(i);
+
+            xmlBuilder.append("  <Message>\n");
+            xmlBuilder.append("    <MessageID>").append(i + 1).append("</MessageID>\n");
+            xmlBuilder.append("    <OrderFulfillment>\n");
+            xmlBuilder.append("      <AmazonOrderID>").append(order.getAmazonOrderId()).append("</AmazonOrderID>\n");
+            xmlBuilder.append("      <FulfillmentDate>").append(OffsetDateTime.now()).append("</FulfillmentDate>\n");
+            xmlBuilder.append("      <FulfillmentData>\n");
+            xmlBuilder.append("        <CarrierCode>").append(carrierCode).append("</CarrierCode>\n");
+            xmlBuilder.append("        <ShippingMethod>Standard</ShippingMethod>\n");
+            xmlBuilder.append("        <ShipperTrackingNumber>").append(trackingNumber).append("</ShipperTrackingNumber>\n");
+            xmlBuilder.append("      </FulfillmentData>\n");
+            xmlBuilder.append("    </OrderFulfillment>\n");
+            xmlBuilder.append("  </Message>\n");
+        }
+
+        xmlBuilder.append("</AmazonEnvelope>");
+        return xmlBuilder.toString();
+    }
+
+    private void uploadFeedDocument(String presignedUrl, String content) throws IOException {
+        URL url = new URL(presignedUrl);
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setDoOutput(true);
+        connection.setRequestMethod("PUT");
+        connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
+
+        try (OutputStream os = connection.getOutputStream()) {
+            byte[] input = content.getBytes(StandardCharsets.UTF_8);
+            os.write(input, 0, input.length);
+        }
+
+        int responseCode = connection.getResponseCode();
+        if (responseCode != HttpURLConnection.HTTP_OK) {
+            throw new IOException("HTTP error code: " + responseCode);
+        }
+    }
+
+    public void processPendingOrders(String marketplaceId) {
+        try {
+            List<Order> pendingOrders = getPendingOrders(marketplaceId);
+            List<String> trackingNumbers = new ArrayList<>();
+            List<String> carrierCodes = new ArrayList<>();
+
+            for (Order order : pendingOrders) {
+                // 这里应该是从您的系统中获取实际的物流信息
+                trackingNumbers.add(generateTrackingNumber());
+                carrierCodes.add("UPS"); // 或其他承运商代码
+
+                // 在这里更新您本地系统中的订单状态
+                updateLocalOrderStatus(order.getAmazonOrderId(), "SHIPPED");
+            }
+
+            fulfillOrders(pendingOrders, trackingNumbers, carrierCodes);
+            System.out.println(pendingOrders.size() + " orders have been fulfilled.");
+        } catch (ApiException | IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private String generateTrackingNumber() {
+        // 生成或获取实际的跟踪号
+        return "TRACK-" + System.currentTimeMillis();
+    }
+
+    private void updateLocalOrderStatus(String orderId, String status) {
+        // 更新本地数据库中的订单状态
+        // 这里应该是您的本地数据库操作
+        System.out.println("Updating local order status: " + orderId + " to " + status);
+    }
+
+    public static void main(String[] args) {
+        OrderFulfillmentManager manager = new OrderFulfillmentManager();
+        manager.processPendingOrders("YOUR_MARKETPLACE_ID");
+    }
+}

+ 79 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/OwnProduct.java

@@ -0,0 +1,79 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.hys.app.framework.database.annotation.Column;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@TableName(value = "erp_company")
+@Data
+public class OwnProduct {
+
+    public static final Long ROOT_ID = 0L;
+
+    private Long id; // 产品唯一标识符
+
+    private String sku; // 库存单位,唯一标识产品的编码
+
+    private String name; // 产品名称
+
+    private String description; // 产品描述
+
+    private List<String> bulletPoints; // 产品要点列表,用于突出产品特性
+
+    private BigDecimal price; // 产品价格
+
+    private BigDecimal salePrice; // 促销价格
+
+    private Integer lowStockThreshold; // 低库存警戒线
+
+    private String brand; // 品牌
+
+    private String manufacturer; // 制造商
+
+    private String category; // 产品类别
+
+    private String picUrl; // 产品图片URL列表
+
+    private BigDecimal weight; // 重量
+
+    private String weightUnit; // 重量单位
+
+    private BigDecimal length; // 长度
+    private BigDecimal width;  // 宽度
+    private BigDecimal height; // 高度
+
+    private String dimensionUnit; // 尺寸单位
+
+    private String color; // 颜色
+    private String size;  // 尺寸
+
+    private List<String> keywords; // 搜索关键词列表
+
+    private String upc; // 通用产品代码
+    private String ean; // 欧洲商品编号
+    private String isbn; // 国际标准书号
+
+    private Integer quantityPerPackage; // 每包数量
+
+    private Integer packageQuantity; // 包装数量
+
+    private String countryOfOrigin; // 原产国
+
+    private String warranty; // 保修信息
+
+    private String fulfillmentType; // 履行类型,如亚马逊的FBA、FBM
+
+    private Map<String, String> platformSpecificIds; // 平台特定ID,如{"AMAZON": "ASIN12345", "EBAY": "EB67890"}
+
+    private Map<String, String> customAttributes; // 自定义属性,用于存储额外的平台特定信息
+
+    private LocalDateTime createdAt; // 创建时间
+
+    private LocalDateTime updatedAt; // 最后更新时间
+
+}

+ 51 - 0
module-erp/src/main/java/com/hys/app/service/otherService/amazon/OwnStore.java

@@ -0,0 +1,51 @@
+package com.hys.app.service.otherService.amazon;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.OffsetDateTime;
+
+
+@TableName(value = "erp_store")
+@Data
+public class OwnStore {
+    public static final Long ROOT_ID = 0L;
+
+    private Long id; // 产品唯一标识符
+
+    // 亚马逊市场的唯一标识符
+    private String marketplaceId;
+
+    // 亚马逊市场的唯一标识符
+    private String name;
+
+    // 亚马逊市场的唯一标识符
+    private String code;
+
+    // 亚马逊市场的唯一标识符
+    private String url;
+
+    // 亚马逊市场的唯一标识符
+    private String username;
+
+    // 亚马逊市场的唯一标识符
+    private String password;
+
+    // 国家代码
+    private String countryCode;
+
+    // 默认货币代码
+    private String defaultCurrencyCode;
+
+    // 默认语言代码
+    private String defaultLanguageCode;
+
+    // 域名
+    private String domainName;
+
+    // 是否参与销售
+    private boolean isParticipating;
+
+    // 最后更新时间
+    private OffsetDateTime lastUpdated;
+}