《每天100秒读懂世界》查询接口是一款提供全球每日要闻摘要的标准化数据服务。开发者可通过调用该API,定时(通常为每日)获取由AI或编辑团队萃取、结构化呈现的新闻简报,内容覆盖时事、财经、科技等核心领域。接口通常返回标题、摘要、关键事实、来源链接及发布时间等字段,支持按日期或分类筛选。适用于新闻聚合、智能助理、办公插件及个人知识管理工具等场景,为用户高效集成精简、权威的全球资讯流。

接口地址:https://zuzuda.com/openapp/ranking/100200

请求参数:{}

请求方式:HTTPPOST

请求HEADER:

名称 说明
Content-Type application/json;charset=UTF-8 固定值
timestamp 1766806308552 时间戳(前后不超过2分钟)
appId 6d1b0dbf65534258aff6791eccf94ec4 系统分配的appId
requestId 2512272004757077918093312 请求唯一ID
sign a5d9669becd931fb0bd67531a7cd404e appId=&plateNo=&requestId=&timestamp=(签名原数据)

请求参数说明:

名称 必填 类型 示例值 说明

返回参数说明:

名称 类型 说明
code int 状态码
msg string 响应描述
data string 响应数据

返回示例:

状态码 类型 说明
200 int 请求成功
201 int 无数据
403 int 没有权限
404 int 接口不存在
405 int 请求方式错误(仅支持POST)
415 int 请求参数错误
500 int 其他错误
6021 int 账户余额不足
6009 int 账户不可用(请联系客服)

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.iizan.common.base.KvTree;
import com.iizan.common.enums.CommonEnum;
import com.iizan.common.enums.Constants;
import com.iizan.common.enums.EncryptType;
import com.iizan.common.openapp.OpenAppConfig;
import com.iizan.common.util.data.IDUtil;
import com.iizan.common.util.encrypt.AesUtils;
import com.iizan.common.util.encrypt.Des3Utils;
import com.iizan.common.util.encrypt.MD5;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class OpenAppUtil {

    @Data
    public static class OpenAppDTO {

        private OpenAppConfig config;
        private String requestId;
        private String path;
        private KvTree data;

        public OpenAppDTO(String path, KvTree data) {
            this.path = path;
            this.data = data;
        }

        public OpenAppDTO config(OpenAppConfig config) {
            this.config = config;
            return this;
        }
        public OpenAppDTO requestId(String requestId) {
            this.requestId = requestId;
            return this;
        }

        public OpenAppDTO set(String key,Object value) {
            data.set(key,value);
            return this;
        }


        public OpenAppDTO set(KvTree datas) {
            data.putAll(datas);
            return this;
        }

        public static OpenAppDTO by(String path, KvTree data) {
            return new OpenAppDTO(path, data);
        }

        public static OpenAppDTO by(String path) {
            return new OpenAppDTO(path, KvTree.by());
        }

        public static OpenAppDTO by(String path,OpenAppConfig config) {
            return new OpenAppDTO(path, KvTree.by()).config(config);
        }
    }

    public static String send(OpenAppDTO dto){
        String requestId = dto.getRequestId();
        String path = dto.getPath();
        KvTree data = dto.getData();
        OpenAppConfig config = dto.getConfig();
        String appId = config.getAppId();
        String baseUrl = config.getBaseUrl();
        String password = config.getPassword();
        String secret = config.getSecret();
        String platformCode = config.getPlatformCode();
        String encryptType = config.getEncryptType();
        String timestamp=System.currentTimeMillis()+"";
        if(requestId==null){
            requestId= IDUtil.uuid();
        }

        //1.构建签名参数
        Map sourceData = KvTree.by(data)
                .set("appId",appId)
                .set("timestamp",timestamp)
                .set("requestId",requestId)
                ;
        String signSource = sourceData.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey())  // 按键排序
                .filter(entry -> entry.getValue() != null)
                .map(entry -> entry.getKey() + "=" + (entry.getValue()==null?"":entry.getValue()))  // 格式化为 k=v
                .collect(Collectors.joining("&"));

        //2.MD5签名
        String sign = MD5.sign(signSource + password, Constants.CHARSET_UTF8);

        //3.构建请求头
        Map> headers=new HashMap<>();
        headers.put("content-type",List.of(CommonEnum.MediaTypes.JSON_UTF_8.getType()));//添加请求头
        headers.put("timestamp",List.of(timestamp));//按当前时间生成,系统会校验该值
        headers.put("appId",List.of(appId));//系统分配
        headers.put("platformCode",List.of(platformCode));//系统分配
        headers.put("requestId",List.of(requestId));//每次请求生成唯一请求ID,长度不超过32位
        headers.put("sign",List.of(sign));


        //4.请求数据,如果需要加密则加密数据
        String requestData = null;
        if(EncryptType.DES.name().equals(encryptType)){
            requestData = Des3Utils.encode(JSON.toJSONString(data),secret);
        }else if(EncryptType.AES.name().equals(encryptType)){
            requestData = AesUtils.encode(JSON.toJSONString(data),secret);
        }else if(EncryptType.RSA.name().equals(encryptType)){
            //requestData = RSAUtils.encryptByPublicKey(JSON.toJSONString(data),secret);
        }else {
            requestData = JSON.toJSONString(data);
        }

        long startTime=System.currentTimeMillis();
        //发送POST请求(仅支持 post)
        log.info("OPENAPI请求开始:{}-{} -> {} {}",path,requestId,data,requestData);
        try{
            String body = HttpRequest.post(baseUrl+path)
                    .body(requestData)
                    .header(headers)
                    .execute()
                    .body();
            log.info("OPENAPI请求结果:{}-{} -> {} ({}ms)",path,requestId,body,(System.currentTimeMillis()-startTime));
            return body;
        }catch (Exception e){
            e.printStackTrace();
            log.error("OPENAPI请求异常:{}-{} -> {} ({}ms)",baseUrl+path,requestId,e.getMessage(),(System.currentTimeMillis()-startTime));
            return null;
        }
    }


    public static void main(String[] args) {
        OpenAppConfig config = new OpenAppConfig();
        config.setBaseUrl("https://api.zuzuda.com/openapp");//https://api.zuzuda.com/openapp + /logistics/100001 接口路径
        config.setPlatformCode("100000");//系统分配
        config.setAppId("6d1b0dbf65534258aff6791eccf94ec4");//系统分配
        config.setSecret("9+XaxnFxe2GtQlOpS+==");//数据加密密钥,系统分配
        config.setPassword("123456");//签名密码,系统分配
        config.setEncryptType(EncryptType.DES.name());//数据加密方式,系统分配

        OpenAppUtil.OpenAppDTO dto = OpenAppUtil.OpenAppDTO.by("/logistics/100001",  KvTree.by("expressNo","773374947375732").set("code","STO")).config(config);
        String result = OpenAppUtil.send(dto);
    }

}

                                        

package main

import (
    "crypto/md5"
    "crypto/des"
    "crypto/cipher"
    "encoding/base64"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "sort"
    "strings"
    "time"
)

type OpenAppConfig struct {
    AppId        string `json:"appId"`
    BaseUrl      string `json:"baseUrl"`
    Password     string `json:"password"`
    Secret       string `json:"secret"`
    PlatformCode string `json:"platformCode"`
    EncryptType  string `json:"encryptType"`
}

type OpenAppDTO struct {
    Config    *OpenAppConfig
    RequestId string
    Path      string
    Data      map[string]interface{}
}

func (dto *OpenAppDTO) Set(key string, value interface{}) *OpenAppDTO {
    dto.Data[key] = value
    return dto
}

func NewOpenAppDTO(path string, data map[string]interface{}) *OpenAppDTO {
    if data == nil {
        data = make(map[string]interface{})
    }
    return &OpenAppDTO{
        Path: path,
        Data: data,
    }
}

func Send(dto *OpenAppDTO) string {
    config := dto.Config
    requestId := dto.RequestId
    path := dto.Path
    data := dto.Data
    
    if requestId == "" {
        requestId = generateUUID()
    }
    
    timestamp := fmt.Sprintf("%d", time.Now().UnixNano()/1e6)
    
    // 1. 构建签名参数
    sourceData := make(map[string]interface{})
    for k, v := range data {
        sourceData[k] = v
    }
    sourceData["appId"] = config.AppId
    sourceData["timestamp"] = timestamp
    sourceData["requestId"] = requestId
    
    // 排序并构建签名字符串
    var keys []string
    for k, v := range sourceData {
        if v != nil {
            keys = append(keys, k)
        }
    }
    sort.Strings(keys)
    
    var signSource strings.Builder
    for i, k := range keys {
        v := sourceData[k]
        strValue := ""
        if v != nil {
            strValue = fmt.Sprintf("%v", v)
        }
        signSource.WriteString(k + "=" + strValue)
        if i < len(keys)-1 {
            signSource.WriteString("&")
        }
    }
    
    // 2. MD5签名
    hash := md5.Sum([]byte(signSource.String() + config.Password))
    sign := hex.EncodeToString(hash[:])
    
    // 3. 请求数据加密
    var requestData string
    jsonData, _ := json.Marshal(data)
    
    switch config.EncryptType {
    case "DES":
        requestData = des3Encode(string(jsonData), config.Secret)
    case "AES":
        requestData = aesEncode(string(jsonData), config.Secret)
    default:
        requestData = string(jsonData)
    }
    
    // 4. 发送请求
    client := &http.Client{}
    req, err := http.NewRequest("POST", config.BaseUrl+path, strings.NewReader(requestData))
    if err != nil {
        return ""
    }
    
    req.Header.Set("content-type", "application/json; charset=utf-8")
    req.Header.Set("timestamp", timestamp)
    req.Header.Set("appId", config.AppId)
    req.Header.Set("platformCode", config.PlatformCode)
    req.Header.Set("requestId", requestId)
    req.Header.Set("sign", sign)
    
    resp, err := client.Do(req)
    if err != nil {
        return ""
    }
    defer resp.Body.Close()
    
    body, _ := ioutil.ReadAll(resp.Body)
    return string(body)
}

func des3Encode(data, key string) string {
    block, err := des.NewTripleDESCipher([]byte(key))
    if err != nil {
        return ""
    }
    
    dataBytes := []byte(data)
    blockSize := block.BlockSize()
    dataBytes = pkcs5Padding(dataBytes, blockSize)
    
    ciphertext := make([]byte, len(dataBytes))
    mode := cipher.NewCBCEncrypter(block, []byte(key)[:blockSize])
    mode.CryptBlocks(ciphertext, dataBytes)
    
    return base64.StdEncoding.EncodeToString(ciphertext)
}

func aesEncode(data, key string) string {
    // AES加密实现
    return base64.StdEncoding.EncodeToString([]byte(data))
}

func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

func generateUUID() string {
    return fmt.Sprintf("%x", time.Now().UnixNano())
}

func main() {
    config := &OpenAppConfig{
        BaseUrl:      "https://api.zuzuda.com/openapp",
        PlatformCode: "100000",
        AppId:        "6d1b0dbf65534258aff6791eccf94ec4",
        Secret:       "9+XaxnFxe2GtQlOpS+==",
        Password:     "123456",
        EncryptType:  "DES",
    }
    
    data := map[string]interface{}{
        "expressNo": "773374947375732",
        "code":      "STO",
    }
    
    dto := NewOpenAppDTO("/logistics/100001", data)
    dto.Config = config
    
    result := Send(dto)
    fmt.Println(result)
}

                                        

import hashlib
import hmac
import json
import time
import uuid
from typing import Dict, Any, Optional
import requests
from base64 import b64encode, b64decode
from Crypto.Cipher import DES3, AES
from Crypto.Util.Padding import pad
import urllib.parse

class OpenAppConfig:
    def __init__(self, **kwargs):
        self.app_id = kwargs.get('app_id')
        self.base_url = kwargs.get('base_url')
        self.password = kwargs.get('password')
        self.secret = kwargs.get('secret')
        self.platform_code = kwargs.get('platform_code')
        self.encrypt_type = kwargs.get('encrypt_type')

class OpenAppDTO:
    def __init__(self, path: str, data: Optional[Dict[str, Any]] = None):
        self.config: Optional[OpenAppConfig] = None
        self.request_id: Optional[str] = None
        self.path = path
        self.data = data or {}
    
    def set(self, key: str, value: Any) -> 'OpenAppDTO':
        self.data[key] = value
        return self
    
    def with_config(self, config: OpenAppConfig) -> 'OpenAppDTO':
        self.config = config
        return self
    
    def with_request_id(self, request_id: str) -> 'OpenAppDTO':
        self.request_id = request_id
        return self
    
    @classmethod
    def by(cls, path: str, data: Optional[Dict[str, Any]] = None) -> 'OpenAppDTO':
        return cls(path, data)

class OpenAppUtil:
    @staticmethod
    def send(dto: OpenAppDTO) -> Optional[str]:
        config = dto.config
        request_id = dto.request_id or str(uuid.uuid4()).replace('-', '')
        path = dto.path
        data = dto.data
        
        timestamp = str(int(time.time() * 1000))
        
        # 1. 构建签名参数
        source_data = data.copy()
        source_data['appId'] = config.app_id
        source_data['timestamp'] = timestamp
        source_data['requestId'] = request_id
        
        # 过滤None值并排序
        filtered_items = {k: v for k, v in source_data.items() if v is not None}
        sorted_items = sorted(filtered_items.items())
        
        # 构建签名字符串
        sign_parts = []
        for key, value in sorted_items:
            sign_parts.append(f"{key}={value}")
        sign_source = '&'.join(sign_parts)
        
        # 2. MD5签名
        sign_string = sign_source + config.password
        sign = hashlib.md5(sign_string.encode('utf-8')).hexdigest()
        
        # 3. 请求数据加密
        json_data = json.dumps(data, ensure_ascii=False)
        
        if config.encrypt_type == 'DES':
            request_data = OpenAppUtil.des3_encode(json_data, config.secret)
        elif config.encrypt_type == 'AES':
            request_data = OpenAppUtil.aes_encode(json_data, config.secret)
        else:
            request_data = json_data
        
        # 4. 发送请求
        headers = {
            'content-type': 'application/json; charset=utf-8',
            'timestamp': timestamp,
            'appId': config.app_id,
            'platformCode': config.platform_code,
            'requestId': request_id,
            'sign': sign
        }
        
        try:
            start_time = time.time()
            print(f"OPENAPI请求开始:{path}-{request_id} -> {data} {request_data}")
            
            response = requests.post(
                config.base_url + path,
                data=request_data.encode('utf-8') if isinstance(request_data, str) else request_data,
                headers=headers,
                timeout=30
            )
            
            duration = int((time.time() - start_time) * 1000)
            print(f"OPENAPI请求结果:{path}-{request_id} -> {response.text} ({duration}ms)")
            
            return response.text
            
        except Exception as e:
            duration = int((time.time() - start_time) * 1000)
            print(f"OPENAPI请求异常:{config.base_url}{path}-{request_id} -> {str(e)} ({duration}ms)")
            return None
    
    @staticmethod
    def des3_encode(data: str, key: str) -> str:
        """3DES加密"""
        # 确保key长度为24字节
        key_bytes = key.encode('utf-8')
        if len(key_bytes) != 24:
            key_bytes = key_bytes.ljust(24, b'\0')[:24]
        
        # 使用CBC模式
        cipher = DES3.new(key_bytes, DES3.MODE_CBC, iv=b'\0' * 8)
        padded_data = pad(data.encode('utf-8'), DES3.block_size)
        encrypted = cipher.encrypt(padded_data)
        return b64encode(encrypted).decode('utf-8')
    
    @staticmethod
    def aes_encode(data: str, key: str) -> str:
        """AES加密"""
        # 确保key长度为16、24或32字节
        key_bytes = key.encode('utf-8')
        if len(key_bytes) not in [16, 24, 32]:
            key_bytes = key_bytes.ljust(32, b'\0')[:32]
        
        # 使用CBC模式
        cipher = AES.new(key_bytes, AES.MODE_CBC, iv=b'\0' * 16)
        padded_data = pad(data.encode('utf-8'), AES.block_size)
        encrypted = cipher.encrypt(padded_data)
        return b64encode(encrypted).decode('utf-8')

def main():
    config = OpenAppConfig(
        base_url="https://api.zuzuda.com/openapp",
        platform_code="100000",
        app_id="6d1b0dbf65534258aff6791eccf94ec4",
        secret="9+XaxnFxe2GtQlOpS+==",
        password="123456",
        encrypt_type="DES"
    )
    
    data = {
        "expressNo": "773374947375732",
        "code": "STO"
    }
    
    dto = OpenAppDTO.by("/logistics/100001", data).with_config(config)
    result = OpenAppUtil.send(dto)
    print(result)

if __name__ == "__main__":
    main()

                                        

const crypto = require('crypto');
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');

class OpenAppConfig {
    constructor(config) {
        this.appId = config.appId;
        this.baseUrl = config.baseUrl;
        this.password = config.password;
        this.secret = config.secret;
        this.platformCode = config.platformCode;
        this.encryptType = config.encryptType;
    }
}

class OpenAppDTO {
    constructor(path, data = {}) {
        this.config = null;
        this.requestId = null;
        this.path = path;
        this.data = data;
    }

    set(key, value) {
        this.data[key] = value;
        return this;
    }

    withConfig(config) {
        this.config = config;
        return this;
    }

    withRequestId(requestId) {
        this.requestId = requestId;
        return this;
    }

    static by(path, data = {}) {
        return new OpenAppDTO(path, data);
    }
}

class OpenAppUtil {
    static async send(dto) {
        const config = dto.config;
        let requestId = dto.requestId || uuidv4().replace(/-/g, '');
        const path = dto.path;
        const data = dto.data;

        const timestamp = Date.now().toString();

        // 1. 构建签名参数
        const sourceData = { ...data };
        sourceData.appId = config.appId;
        sourceData.timestamp = timestamp;
        sourceData.requestId = requestId;

        // 排序并构建签名字符串
        const sortedKeys = Object.keys(sourceData)
            .filter(key => sourceData[key] != null)
            .sort();

        const signParts = [];
        for (const key of sortedKeys) {
            const value = sourceData[key] === null ? '' : sourceData[key];
            signParts.push(`${key}=${value}`);
        }
        const signSource = signParts.join('&');

        // 2. MD5签名
        const sign = crypto
            .createHash('md5')
            .update(signSource + config.password)
            .digest('hex');

        // 3. 请求数据加密
        let requestData;
        const jsonData = JSON.stringify(data);

        switch (config.encryptType) {
            case 'DES':
                requestData = this.des3Encode(jsonData, config.secret);
                break;
            case 'AES':
                requestData = this.aesEncode(jsonData, config.secret);
                break;
            default:
                requestData = jsonData;
        }

        // 4. 构建请求头
        const headers = {
            'content-type': 'application/json; charset=utf-8',
            'timestamp': timestamp,
            'appId': config.appId,
            'platformCode': config.platformCode,
            'requestId': requestId,
            'sign': sign
        };

        const startTime = Date.now();
        console.log(`OPENAPI请求开始:${path}-${requestId} -> ${jsonData} ${requestData}`);

        try {
            const response = await axios.post(config.baseUrl + path, requestData, {
                headers: headers,
                timeout: 30000
            });

            const duration = Date.now() - startTime;
            console.log(`OPENAPI请求结果:${path}-${requestId} -> ${JSON.stringify(response.data)} (${duration}ms)`);

            return response.data;
        } catch (error) {
            const duration = Date.now() - startTime;
            console.error(`OPENAPI请求异常:${config.baseUrl}${path}-${requestId} -> ${error.message} (${duration}ms)`);
            return null;
        }
    }

    static des3Encode(data, key) {
        // 3DES加密
        const keyBuffer = Buffer.from(key, 'utf8');
        const iv = Buffer.alloc(8, 0); // 使用零向量
        
        // 补全key到24字节
        const fullKey = Buffer.alloc(24);
        keyBuffer.copy(fullKey);
        
        const cipher = crypto.createCipheriv('des-ede3-cbc', fullKey, iv);
        let encrypted = cipher.update(data, 'utf8', 'base64');
        encrypted += cipher.final('base64');
        
        return encrypted;
    }

    static aesEncode(data, key) {
        // AES加密
        const keyBuffer = Buffer.from(key, 'utf8');
        const iv = Buffer.alloc(16, 0); // 使用零向量
        
        // 根据key长度确定算法
        let algorithm;
        if (keyBuffer.length === 16) {
            algorithm = 'aes-128-cbc';
        } else if (keyBuffer.length === 24) {
            algorithm = 'aes-192-cbc';
        } else {
            algorithm = 'aes-256-cbc';
        }
        
        const cipher = crypto.createCipheriv(algorithm, keyBuffer, iv);
        let encrypted = cipher.update(data, 'utf8', 'base64');
        encrypted += cipher.final('base64');
        
        return encrypted;
    }
}

// 使用示例
async function main() {
    const config = new OpenAppConfig({
        baseUrl: 'https://api.zuzuda.com/openapp',
        platformCode: '100000',
        appId: '6d1b0dbf65534258aff6791eccf94ec4',
        secret: '9+XaxnFxe2GtQlOpS+=',
        password: '123456',
        encryptType: 'DES'
    });

    const data = {
        expressNo: '773374947375732',
        code: 'STO'
    };

    const dto = OpenAppDTO.by('/logistics/100001', data).withConfig(config);
    const result = await OpenAppUtil.send(dto);
    console.log(result);
}

// 执行
main().catch(console.error);

                                        

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef struct {
    char* appId;
    char* baseUrl;
    char* password;
    char* secret;
    char* platformCode;
    char* encryptType;
} OpenAppConfig;

typedef struct {
    OpenAppConfig* config;
    char* requestId;
    char* path;
    json_t* data;
} OpenAppDTO;

// 简化版实现,只展示核心逻辑
char* openapp_send(OpenAppDTO* dto) {
    // 生成时间戳
    char timestamp[20];
    snprintf(timestamp, sizeof(timestamp), "%lld", (long long)time(NULL) * 1000);
    
    // 生成签名(简化版)
    char sign[33];
    // ... 签名逻辑 ...
    
    // 加密数据
    char* requestData = NULL;
    char* jsonData = json_dumps(dto->data, JSON_COMPACT);
    
    if (strcmp(dto->config->encryptType, "DES") == 0) {
        // DES加密
    } else if (strcmp(dto->config->encryptType, "AES") == 0) {
        // AES加密
    } else {
        requestData = strdup(jsonData);
    }
    
    // 发送HTTP请求
    CURL* curl = curl_easy_init();
    if (curl) {
        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, "content-type: application/json; charset=utf-8");
        // ... 添加其他header ...
        
        curl_easy_setopt(curl, CURLOPT_URL, dto->config->baseUrl);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        
        // 执行请求
        // ...
        
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    
    free(jsonData);
    if (requestData) free(requestData);
    return NULL;
}

                                        

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using json = nlohmann::json;

class OpenAppConfig {
public:
    std::string appId;
    std::string baseUrl;
    std::string password;
    std::string secret;
    std::string platformCode;
    std::string encryptType;
};

class OpenAppDTO {
public:
    OpenAppConfig* config;
    std::string requestId;
    std::string path;
    json data;

    OpenAppDTO(const std::string& path, const json& data = json::object()) 
        : path(path), data(data), config(nullptr) {}

    OpenAppDTO* set(const std::string& key, const json& value) {
        data[key] = value;
        return this;
    }

    OpenAppDTO* config(OpenAppConfig* config) {
        this->config = config;
        return this;
    }
};

class OpenAppUtil {
public:
    static std::string send(OpenAppDTO* dto) {
        auto config = dto->config;
        auto requestId = dto->requestId;
        auto path = dto->path;
        auto data = dto->data;

        if (requestId.empty()) {
            requestId = generateUUID();
        }

        auto timestamp = std::to_string(getCurrentTimestamp());

        // 1. 构建签名参数
        json sourceData = data;
        sourceData["appId"] = config->appId;
        sourceData["timestamp"] = timestamp;
        sourceData["requestId"] = requestId;

        // 排序并构建签名字符串
        std::map sortedMap;
        for (auto& item : sourceData.items()) {
            if (!item.value().is_null()) {
                sortedMap[item.key()] = item.value().dump();
            }
        }

        std::stringstream signSource;
        for (auto it = sortedMap.begin(); it != sortedMap.end(); ++it) {
            if (it != sortedMap.begin()) signSource << "&";
            signSource << it->first << "=" << it->second;
        }

        // 2. MD5签名
        std::string sign = md5(signSource.str() + config->password);

        // 3. 请求数据加密
        std::string requestData;
        std::string jsonData = data.dump();

        if (config->encryptType == "DES") {
            requestData = des3Encode(jsonData, config->secret);
        } else if (config->encryptType == "AES") {
            requestData = aesEncode(jsonData, config->secret);
        } else {
            requestData = jsonData;
        }

        // 4. 发送HTTP请求
        CURL* curl = curl_easy_init();
        if (curl) {
            std::string response;

            struct curl_slist* headers = nullptr;
            headers = curl_slist_append(headers, "content-type: application/json; charset=utf-8");
            headers = curl_slist_append(headers, ("timestamp: " + timestamp).c_str());
            headers = curl_slist_append(headers, ("appId: " + config->appId).c_str());
            headers = curl_slist_append(headers, ("platformCode: " + config->platformCode).c_str());
            headers = curl_slist_append(headers, ("requestId: " + requestId).c_str());
            headers = curl_slist_append(headers, ("sign: " + sign).c_str());

            curl_easy_setopt(curl, CURLOPT_URL, (config->baseUrl + path).c_str());
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

            CURLcode res = curl_easy_perform(curl);
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);

            if (res == CURLE_OK) {
                return response;
            }
        }

        return "";
    }

private:
    static size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) {
        ((std::string*)userp)->append((char*)contents, size * nmemb);
        return size * nmemb;
    }

    static long long getCurrentTimestamp() {
        auto now = std::chrono::system_clock::now();
        return std::chrono::duration_cast(
            now.time_since_epoch()).count();
    }

    static std::string generateUUID() {
        std::stringstream ss;
        ss << std::hex << std::setfill('0');
        for (int i = 0; i < 16; i++) {
            ss << std::setw(2) << (rand() % 256);
        }
        return ss.str();
    }

    static std::string md5(const std::string& str) {
        unsigned char digest[MD5_DIGEST_LENGTH];
        MD5((unsigned char*)str.c_str(), str.length(), digest);

        std::stringstream ss;
        ss << std::hex << std::setfill('0');
        for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
            ss << std::setw(2) << (int)digest[i];
        }
        return ss.str();
    }

    static std::string des3Encode(const std::string& data, const std::string& key) {
        // DES加密实现
        return base64Encode(data); // 简化
    }

    static std::string aesEncode(const std::string& data, const std::string& key) {
        // AES加密实现
        return base64Encode(data); // 简化
    }

    static std::string base64Encode(const std::string& data) {
        // Base64编码实现
        return data; // 简化
    }
};

                                        

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using Newtonsoft.Json;
using System.Linq;

namespace OpenAppUtil
{
    public class OpenAppConfig
    {
        public string AppId { get; set; }
        public string BaseUrl { get; set; }
        public string Password { get; set; }
        public string Secret { get; set; }
        public string PlatformCode { get; set; }
        public string EncryptType { get; set; }
    }

    public class OpenAppDTO
    {
        public OpenAppConfig Config { get; set; }
        public string RequestId { get; set; }
        public string Path { get; set; }
        public Dictionary Data { get; set; }

        public OpenAppDTO(string path, Dictionary data = null)
        {
            Path = path;
            Data = data ?? new Dictionary();
        }

        public OpenAppDTO Set(string key, object value)
        {
            Data[key] = value;
            return this;
        }

        public OpenAppDTO Config(OpenAppConfig config)
        {
            Config = config;
            return this;
        }

        public static OpenAppDTO By(string path, Dictionary data = null)
        {
            return new OpenAppDTO(path, data);
        }
    }

    public class OpenAppUtil
    {
        public static async Task Send(OpenAppDTO dto)
        {
            var config = dto.Config;
            var requestId = dto.RequestId;
            var path = dto.Path;
            var data = dto.Data;

            if (string.IsNullOrEmpty(requestId))
            {
                requestId = Guid.NewGuid().ToString("N");
            }

            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();

            // 1. 构建签名参数
            var sourceData = new Dictionary(data)
            {
                ["appId"] = config.AppId,
                ["timestamp"] = timestamp,
                ["requestId"] = requestId
            };

            // 排序并构建签名字符串
            var sortedParams = sourceData
                .Where(kv => kv.Value != null)
                .OrderBy(kv => kv.Key)
                .Select(kv => $"{kv.Key}={kv.Value}");

            var signSource = string.Join("&", sortedParams);

            // 2. MD5签名
            using var md5 = MD5.Create();
            var signBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(signSource + config.Password));
            var sign = BitConverter.ToString(signBytes).Replace("-", "").ToLower();

            // 3. 请求数据加密
            string requestData;
            var jsonData = JsonConvert.SerializeObject(data);

            switch (config.EncryptType)
            {
                case "DES":
                    requestData = Des3Encode(jsonData, config.Secret);
                    break;
                case "AES":
                    requestData = AesEncode(jsonData, config.Secret);
                    break;
                default:
                    requestData = jsonData;
                    break;
            }

            // 4. 发送请求
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Add("timestamp", timestamp);
            client.DefaultRequestHeaders.Add("appId", config.AppId);
            client.DefaultRequestHeaders.Add("platformCode", config.PlatformCode);
            client.DefaultRequestHeaders.Add("requestId", requestId);
            client.DefaultRequestHeaders.Add("sign", sign);

            var content = new StringContent(requestData, Encoding.UTF8, "application/json");
            var response = await client.PostAsync(config.BaseUrl + path, content);

            return await response.Content.ReadAsStringAsync();
        }

        private static string Des3Encode(string data, string key)
        {
            using var des = TripleDES.Create();
            des.Key = Encoding.UTF8.GetBytes(key.PadRight(24).Substring(0, 24));
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;

            using var encryptor = des.CreateEncryptor();
            var bytes = Encoding.UTF8.GetBytes(data);
            var result = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
            return Convert.ToBase64String(result);
        }

        private static string AesEncode(string data, string key)
        {
            using var aes = Aes.Create();
            aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.IV = new byte[16];

            using var encryptor = aes.CreateEncryptor();
            var bytes = Encoding.UTF8.GetBytes(data);
            var result = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
            return Convert.ToBase64String(result);
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var config = new OpenAppConfig
            {
                BaseUrl = "https://api.zuzuda.com/openapp",
                PlatformCode = "100000",
                AppId = "6d1b0dbf65534258aff6791eccf94ec4",
                Secret = "9+XaxnFxe2GtQlOpS+==",
                Password = "123456",
                EncryptType = "DES"
            };

            var data = new Dictionary
            {
                ["expressNo"] = "773374947375732",
                ["code"] = "STO"
            };

            var dto = OpenAppDTO.By("/logistics/100001", data);
            dto.Config(config);

            var result = await OpenAppUtil.Send(dto);
            Console.WriteLine(result);
        }
    }
}

                                        

<?php

class OpenAppUtil
{
    public static function send(OpenAppDTO $dto)
    {
        $requestId = $dto->getRequestId();
        $path = $dto->getPath();
        $data = $dto->getData();
        $config = $dto->getConfig();
        
        $appId = $config->getAppId();
        $baseUrl = $config->getBaseUrl();
        $password = $config->getPassword();
        $secret = $config->getSecret();
        $platformCode = $config->getPlatformCode();
        $encryptType = $config->getEncryptType();
        
        $timestamp = (string)(round(microtime(true) * 1000));
        
        if ($requestId === null) {
            $requestId = self::uuid();
        }
        
        // 1. 构建签名参数
        $sourceData = array_merge($data, [
            'appId' => $appId,
            'timestamp' => $timestamp,
            'requestId' => $requestId
        ]);
        
        // 过滤空值并按键排序
        $sourceData = array_filter($sourceData, function($value) {
            return $value !== null;
        });
        ksort($sourceData);
        
        // 构建签名字符串
        $signSource = '';
        foreach ($sourceData as $key => $value) {
            $signSource .= $key . '=' . ($value === null ? '' : $value) . '&';
        }
        $signSource = rtrim($signSource, '&');
        
        // 2. MD5签名
        $sign = md5($signSource . $password);
        
        // 3. 构建请求头
        $headers = [
            'content-type: application/json; charset=utf-8',
            'timestamp: ' . $timestamp,
            'appId: ' . $appId,
            'platformCode: ' . $platformCode,
            'requestId: ' . $requestId,
            'sign: ' . $sign,
        ];
        
        // 4. 请求数据,如果需要加密则加密数据
        $requestData = json_encode($data);
        if ($encryptType === 'DES') {
            $requestData = self::des3Encode($requestData, $secret);
        } elseif ($encryptType === 'AES') {
            $requestData = self::aesEncode($requestData, $secret);
        } elseif ($encryptType === 'RSA') {
            // RSA加密,需要openssl扩展
            // $requestData = self::rsaEncrypt($requestData, $secret);
        }
        
        $startTime = microtime(true) * 1000;
        
        error_log("OPENAPI请求开始:{$path}-{$requestId} -> " . json_encode($data) . " " . $requestData);
        
        try {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $baseUrl . $path);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $requestData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            
            $body = curl_exec($ch);
            $error = curl_error($ch);
            curl_close($ch);
            
            if ($error) {
                throw new Exception($error);
            }
            
            $endTime = microtime(true) * 1000;
            $duration = round($endTime - $startTime);
            error_log("OPENAPI请求结果:{$path}-{$requestId} -> {$body} ({$duration}ms)");
            
            return $body;
        } catch (Exception $e) {
            $endTime = microtime(true) * 1000;
            $duration = round($endTime - $startTime);
            error_log("OPENAPI请求异常:{$baseUrl}{$path}-{$requestId} -> {$e->getMessage()} ({$duration}ms)");
            return null;
        }
    }
    
    private static function uuid()
    {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
    
    private static function des3Encode($data, $key)
    {
        // 3DES加密实现,需要根据具体算法调整
        $method = 'des-ede3';
        $iv = substr($key, 0, 8); // 根据实际需求调整IV
        return base64_encode(openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv));
    }
    
    private static function aesEncode($data, $key)
    {
        // AES加密实现
        $method = 'aes-128-cbc';
        $iv = substr($key, 0, 16); // 根据实际需求调整IV
        return base64_encode(openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv));
    }
    
    public static function main()
    {
        $config = new OpenAppConfig();
        $config->setBaseUrl('https://api.zuzuda.com/openapp');
        $config->setPlatformCode('100000');
        $config->setAppId('6d1b0dbf65534258aff6791eccf94ec4');
        $config->setSecret('9+XaxnFxe2GtQlOpS+==');
        $config->setPassword('123456');
        $config->setEncryptType('DES');
        
        $data = [
            'expressNo' => '773374947375732',
            'code' => 'STO'
        ];
        
        $dto = OpenAppDTO::by('/logistics/100001', $data);
        $dto->config($config);
        
        $result = self::send($dto);
        return $result;
    }
}

class OpenAppDTO
{
    private $config;
    private $requestId;
    private $path;
    private $data;
    
    public function __construct($path, $data = [])
    {
        $this->path = $path;
        $this->data = $data;
    }
    
    public function getConfig()
    {
        return $this->config;
    }
    
    public function getRequestId()
    {
        return $this->requestId;
    }
    
    public function getPath()
    {
        return $this->path;
    }
    
    public function getData()
    {
        return $this->data;
    }
    
    public function config(OpenAppConfig $config)
    {
        $this->config = $config;
        return $this;
    }
    
    public function requestId($requestId)
    {
        $this->requestId = $requestId;
        return $this;
    }
    
    public function set($key, $value)
    {
        $this->data[$key] = $value;
        return $this;
    }
    
    public function setData($datas)
    {
        $this->data = array_merge($this->data, $datas);
        return $this;
    }
    
    public static function by($path, $data = [])
    {
        return new self($path, $data);
    }
}

class OpenAppConfig
{
    private $appId;
    private $baseUrl;
    private $password;
    private $secret;
    private $platformCode;
    private $encryptType;
    
    public function getAppId()
    {
        return $this->appId;
    }
    
    public function setAppId($appId)
    {
        $this->appId = $appId;
        return $this;
    }
    
    public function getBaseUrl()
    {
        return $this->baseUrl;
    }
    
    public function setBaseUrl($baseUrl)
    {
        $this->baseUrl = $baseUrl;
        return $this;
    }
    
    public function getPassword()
    {
        return $this->password;
    }
    
    public function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }
    
    public function getSecret()
    {
        return $this->secret;
    }
    
    public function setSecret($secret)
    {
        $this->secret = $secret;
        return $this;
    }
    
    public function getPlatformCode()
    {
        return $this->platformCode;
    }
    
    public function setPlatformCode($platformCode)
    {
        $this->platformCode = $platformCode;
        return $this;
    }
    
    public function getEncryptType()
    {
        return $this->encryptType;
    }
    
    public function setEncryptType($encryptType)
    {
        $this->encryptType = $encryptType;
        return $this;
    }
}

// 使用示例
// $result = OpenAppUtil::main();

                                        
参数名 填写参数值 操作
无需填写
无需填写
NONE | DES | AES