AiPPT接口文件PHP版本全,智能生成PPT文件并下载

开放平台:https://open.aippt.cn/docs/zh/guide/introduce.html

php 复制代码
<?php
const AIPPT_API = '';
const AIPPT_SECRET = '';
const AIPPT_UID = '';


/**
 * AK/SK 签名认证工具类
 * 用于生成签名并调用 AIPPT 的 Token/Code 接口
 */
class AIPPTClient
{
    // API 基础配置
    private $apiUid;      // AK
    private $apiKey;      // AK
    private $secretKey;   // SK
    private $baseUrl;     // API 基础地址

    /**
     * 构造函数初始化配置
     * @param string $apiKey API Key (AK)
     * @param string $secretKey Secret Key (SK)
     * @param string $baseUrl API 基础地址
     */
    public function __construct($apiUid, $apiKey, $secretKey, $baseUrl = 'https://co.aippt.cn')
    {
        $this->apiUid = $apiUid;
        $this->apiKey = $apiKey;
        $this->secretKey = $secretKey;
        $this->baseUrl = rtrim($baseUrl, '/');
    }

    /**
     * 格式化API路径 (确保以/开头和结尾)
     * @param string $uri 原始路径
     * @return string 格式化后的路径
     */
    private function formatApiUri($uri)
    {
        $uri = '/' . ltrim($uri, '/');
        if (substr($uri, -1) !== '/') {
            $uri .= '/';
        }
        return $uri;
    }

    /**
     * 生成 HMAC-SHA1 + Base64 签名
     * @param string $httpMethod HTTP请求方法 (GET/POST)
     * @param string $apiUri API路径 (需以/开头和结尾)
     * @param int $timestamp 时间戳(秒)
     * @return string 最终签名值
     */
    private function generateSignature($httpMethod, $apiUri, $timestamp)
    {
        $apiUri = $this->formatApiUri($apiUri);

        // 1. 构造待签字符串 (HTTP方法@API路径@时间戳)
        $stringToSign = $httpMethod . '@' . $apiUri . '@' . $timestamp;

        // 2. HMAC-SHA1 加密 + Base64 编码
        $hash = hash_hmac('sha1', $stringToSign, $this->secretKey, true);
        $signature = base64_encode($hash);

        return $signature;
    }

    /**
     * 发送通用HTTP请求
     * @param string $apiPath API接口路径
     * @param string $method HTTP方法 (GET/POST)
     * @param array $params 请求参数(GET为query,POST为form-data)
     * @param array $files 上传的文件列表(键为参数名,值为文件路径)
     * @return array 接口响应数据
     * @throws Exception 请求失败时抛出异常
     */
    private function sendRequest($apiPath, $method = 'GET', $params = [], $files = [])
    {
        // 1. 基础参数初始化
        $httpMethod = strtoupper($method);
        $apiUri = $this->formatApiUri($apiPath);
        $timestamp = time();

        // 2. 构建请求URL
        $url = $this->baseUrl . $apiUri;
        if ($httpMethod === 'GET' && !empty($params)) {
            $url .= '?' . http_build_query($params);
        }

        // 3. 初始化cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随301/302重定向
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 测试环境临时关闭,生产建议开启
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        // 4. 设置请求头(任务创建需要x-token,鉴权接口需要x-signature)
        $headers = [
            'x-api-key: ' . $this->apiKey,
            'x-channel: ', // 渠道标识,无则传空
        ];

        // 任务创建接口用x-token,鉴权接口用x-timestamp+x-signature
        if (strpos($apiPath, '/api/grant/') === 0) {
            // 鉴权接口(获取token/code)
            $signature = $this->generateSignature($httpMethod, $apiUri, $timestamp);
            $headers[] = 'x-timestamp: ' . $timestamp;
            $headers[] = 'x-signature: ' . $signature;
        } else {
            // 业务接口(任务创建)
            if (empty($this->access_token())) {
                throw new Exception("调用业务接口前必须设置有效的x-token");
            }
            $headers[] = 'x-token: ' . $this->access_token();
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        // 5. 处理POST请求(含文件上传)
        if ($httpMethod === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);

            // 构建POST数据(兼容普通参数+文件)
            $postData = [];
            // 普通参数
            foreach ($params as $key => $value) {
                $postData[$key] = $value;
            }
            // 文件参数
            foreach ($files as $fieldName => $filePath) {
                if (!file_exists($filePath)) {
                    throw new Exception("文件不存在:{$filePath}");
                }
                // CURLFile 兼容PHP 5.5+,处理文件上传
                $postData[$fieldName] = new CURLFile(realpath($filePath), mime_content_type($filePath), basename($filePath));
            }
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }

        // 6. 执行请求并处理响应
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if (curl_errno($ch)) {
            $error = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL请求失败: " . $error);
        }
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception("HTTP请求失败,状态码: {$httpCode},响应内容: {$response}");
        }

        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("响应JSON解析失败: " . json_last_error_msg());
        }

        if (isset($result['code']) && $result['code'] !== 0) {
            throw new Exception("接口返回异常: {$result['msg']} (code: {$result['code']})");
        }

        return $result;
    }

    /**
     * 获取认证Token
     * @param string $channel 渠道标识 (无则传空字符串)
     * @return array Token响应数据 (包含token、time_expire等)
     * @throws Exception 请求失败时抛出异常
     */
    private function getToken($channel = '')
    {
        $queryParams = [
            'uid' => $this->apiUid,
            'channel' => $channel
        ];
        return $this->sendRequest('/api/grant/token', 'GET', $queryParams);
    }

    /**
     * 本地获取访问凭证
     */
    public function access_token()
    {
        $accessTokenMp = '';
        $file = "access_token_aippt.txt";
        $savePath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "temp" . DIRECTORY_SEPARATOR;
        if (!file_exists($savePath)) {
            mkdir($savePath, 0777, true);
        }
        $filePath = $savePath . $file;
        if (file_exists($filePath)) {
            $fp = fopen($filePath, "r");
            $fpStr = fread($fp, filesize($filePath));
            fclose($fp);
            if ($fpStr) {
                $arr = explode("_||_", $fpStr);
                $accessTime = $arr[1];
                if ($accessTime && $accessTime > time()) {
                    $accessTokenMp = $arr[0];
                }
            }
        }
        if (!$accessTokenMp) {
            $tokenData = $this->getToken();
            $accessTokenMp = $tokenData["data"]['token'];
            $accessTokenValidity = $tokenData["data"]['time_expire'];
            $_str = $accessTokenMp . "_||_" . (time() + $accessTokenValidity - 60);
            file_put_contents($filePath, $_str);
        }
        return $accessTokenMp;
    }

    /**
     * 创建PPT生成任务
     * @param array $params 任务参数(根据type传对应字段)
     * @param array $files 上传文件列表(键为参数名,值为文件路径)
     * @return array 任务创建响应数据(含任务ID)
     * @throws Exception
     */
    public function createTask($params, $files = [])
    {
        // 必传参数校验
        if (!isset($params['type'])) {
            throw new Exception("type参数为必传项");
        }
        $type = $params['type'];

        // 根据type校验核心参数(简化版,可根据实际需求扩展)
        $checkRules = [
            1 => ['required' => ['title']], // 智能生成
            7 => ['required' => ['title', 'content']], // Markdown粘贴
            8 => ['required' => ['id']], // 预置词
            11 => ['required' => ['title', 'content']], // 自由输入
            16 => ['required' => ['link']], // 导入URL
            3 => ['required' => [], 'files' => ['file']], // 上传Word
            4 => ['required' => [], 'files' => ['file']], // 上传XMind
            17 => ['required' => ['title'], 'files' => ['files']], // 上传参考文档
        ];

        if (isset($checkRules[$type])) {
            // 校验普通必传参数
            foreach ($checkRules[$type]['required'] as $field) {
                if (!isset($params[$field]) || $params[$field] === '') {
                    throw new Exception("type={$type}时,{$field}为必传项");
                }
            }
            // 校验文件参数
            if (isset($checkRules[$type]['files'])) {
                foreach ($checkRules[$type]['files'] as $fileField) {
                    if (!isset($files[$fileField])) {
                        throw new Exception("type={$type}时,{$fileField}文件为必传项");
                    }
                }
            }
        }

        // 调用任务创建接口
        return $this->sendRequest('/api/ai/chat/v2/task', 'POST', $params, $files);
    }

    /**
     * 模板套装列表筛选项
     * @return array 创建响应数据
     * @throws Exception
     */
    public function templateSuitList()
    {
        // 调用任务创建接口
        return $this->sendRequest('/api/template_component/suit/select');
    }


    /**
     * 模板套装列表
     * @param array $params 任务参数(根据type传对应字段)
     * @return array 创建响应数据
     * @throws Exception
     */

    public function templateList($params)
    {
        // 调用任务创建接口
        return $this->sendRequest('/api/template_component/suit/search', 'GET', $params);
    }

    /**
     * 作品生成
     * @param array $params 任务参数(根据type传对应字段)
     * @return array 创建响应数据
     * @throws Exception
     */
    public function createWork($params)
    {
        return $this->sendRequest('/api/design/v2/save', 'POST', $params);
    }

    /**
     * 作品导出
     * @param array $params 任务参数(根据type传对应字段)
     * @return array 创建响应数据
     * @throws Exception
     */
    public function exportWork($params)
    {
        return $this->sendRequest('/api/download/export/file', 'POST', $params);
    }

    /**
     * 作品导出结果
     * @param array $params 任务参数(根据type传对应字段)
     * @return array 创建响应数据
     * @throws Exception
     */
    public function exportExport($params)
    {
        return $this->sendRequest('/api/download/export/file/result', 'POST', $params);
    }

}

// ====================== 使用示例 ======================
try {

    // 2. 初始化客户端
    $client = new AIPPTClient(AIPPT_UID, AIPPT_API, AIPPT_SECRET);
    // 获取token-----------------------------------------------
    echo '<pre>';
//    $tokenResult = $client->access_token();


    // 4. 示例1:创建任务-----------------------------------------------
    $content = '# **性格测试2问卷调研结论总结**

## 📋 一、核心发现

本次调研共收集8份有效样本,通过对16个维度的统计分析,可以得出以下核心结论:

**样本群体呈现"务实感性型"人格倾向**:在生活态度上表现出强烈的现实主义倾向,但在情感决策中却依赖直觉与感觉,形成"行为务实、情感随缘"的鲜明特征。

## 🎯 二、四大核心特质总结

### 1. **务实导向的生活观**
- **高度一致性**:超过60%的受访者认同"关注实际生活"、"情侣聊实际话题"
- **表现**:偏好实际行为评价(75%)、不喜深挖抽象意义(75%)
- **内涵**:群体普遍重视可触摸、可验证的现实生活,避免过度哲思与空想

### 2. **随性但有秩序的生活方式**
- **矛盾统一**:周末高度无计划(87.5%)却重视环境秩序(75%)
- **表现**:享受即兴安排但需要物品归位的生活框架
- **内涵**:追求"框架内的自由"------在整洁有序的基础上享受随性

### 3. **直觉驱动的决策模式**
- **情感直觉强**:62.5%相信"第一眼正缘",同样比例会"凭感觉选择"
- **对比**:虽然在生活中务实,但在关键情感决策中依赖直觉而非逻辑
- **内涵**:形成了"日常理性、情感感性"的二元决策系统

### 4. **中庸的社交倾向**
- **无明显偏好**:在外向/内向、社交主动度等维度上分布均衡
- **表现**:既不完全回避社交,也不过度热衷
- **内涵**:社交能量随情境调节,无固定模式

## 🔄 三、内在张力与平衡

本群体呈现出三组有趣的**心理平衡点**:

1. **务实与感性的平衡**:生活中务实高效,情感上相信缘分
2. **随性与秩序的平衡**:时间安排随意,空间管理严格
3. **探索与安稳的平衡**:愿意尝试新路线,但总体生活态度务实

## 🧩 四、群体画像标签

基于以上分析,可为样本群体贴上以下标签:

- **标签1**:现实主义者(非浪漫空想型)
- **标签2**:直觉决策者(情感跟随感觉)
- **标签3**:有序随性派(整洁框架+自由安排)
- **标签4**:社交情境者(无固定社交模式)

## 💡 五、应用启示

### 针对产品/服务设计:
- 提供**结构化但选择自由**的方案(符合"有序随性"需求)
- 内容强调**实用价值+情感共鸣**(兼顾务实与感性)
- 避免过度抽象或完全无序的体验设计

### 针对人际匹配:
- 适合与**同样务实但有一定生活情趣**的伴侣相处
- 需要理解其"秩序需求"与"随性安排"的共存
- 情感建立可依赖"第一眼感觉",关系维护需"实际行动"

### 针对个人发展:
- 可加强**情感决策的理性补充**,避免完全依赖直觉
- 利用"秩序偏好"建立高效生活系统
- 在务实基础上适度增加生活"诗意时刻"

## 📌 六、调研价值与局限

### 价值:
- 揭示了"务实"与"感性"并非对立,可在同一人格中共存
- 发现了"秩序需求"与"时间随性"的有趣组合
- 为理解当代年轻群体性格复杂性提供了样本参考

### 局限:
- 样本量较小(n=8),结论需谨慎推广
- 样本来源集中(同一IP),可能存在群体同质化
- 问卷为自评数据,可能存在社会赞许性偏差

---

## 结语

本次性格测试描绘出一个**理性与感性交织、秩序与随性共存**的群体形象。他们在生活中脚踏实地,在情感上相信缘分;他们享受无计划的周末,却需要整洁有序的家居环境。这种看似矛盾的特质组合,恰恰反映了现代人复杂而多维的性格结构,提示我们在理解人格时,应避免简单二分,更多关注不同维度间的动态平衡与情境适配。

如需进一步分析或调整测试维度,可根据此结论进行问卷优化与深度研究。';

    $taskParams = [
        'type' => 7, // Markdown粘贴
        'title' => '性格测试报告', // 必传
        'content' => $content, // 必传
        'sub_type' => 1, // 保持原文(默认)
        'model' => 'deepSeek-v3' // 智谱模型
//        'senior_options' => json_encode([ // 高级配置
//            'page' => 3,
//            'group' => 6,
//            'scene' => 18,
//            'tone' => 40,
//            'language' => 47
//        ])
    ];
    $taskResult = $client->createTask($taskParams);
    echo "任务创建成功:<br>";
    print_r($taskResult);

    // 获取PPT模版筛选类型----------------------------------------------
//    $rsarrsai = $client->templateSuitList();
//    print_r($rsarrsai);

    // 获取PPT模版17618-----------------------------------------------
//    $params = array(
//        'colour_id' => 9,
//        'style_id' => 1,
//        'page_size' => 500
//    );
//    $rsarr = $client->templateList($params);
//   print_r($rsarr);
//    foreach ($rsarr["data"]["list"] as $item) {
//        echo "模版ID:" . $item["id"] . "<br>";
//        echo "模版封面<br>";
//        echo "<img src='" . $item["cover_img"] . "' width='200'><br>";
//        echo "<br>";
//    }

    // 作品生成-----------------------------------------------
    $taskParams1 = [
        'name' => '性格测试报告',
        'task_id' => $taskResult["data"]["id"],
        'template_id' => 17618
    ];
    $taskResult1 = $client->createWork($taskParams1);
    echo "作品生成成功:<br>";
    print_r($taskResult1);

    // 作品导出-----------------------------------------------
    $taskParams2 = [
        'id' => $taskResult1["data"]["id"],
        'format' => 'pdf',
        'edit' => 'true',
        'files_to_zip' => 'false'
    ];
    $taskResult2 = $client->exportWork($taskParams2);
    echo "作品导出成功,使用作品导出结果[导出文件]:<br>";
    print_r($taskResult2);

    // 作品导出结果-----------------------------------------------
//    $taskParams = [
//        'task_key' => $taskResult2["data"]
//    ];
//    $taskResult3 = $client->exportExport($taskParams);
//    echo "作品导出结果成功:<br>";
//    print_r($taskResult3);

} catch (Exception $e) {
    echo "请求失败: " . $e->getMessage() . "\n";
}
相关推荐
哪 吒1 小时前
GPT-5.4上线,编程能力超过Claude Opus 4.6
gpt·ai·chatgpt·openai·claude·gemini
ノBye~1 小时前
Spring的IOC详解
java·开发语言
willhuo1 小时前
全能文档解析服务doc-mcp-server
python·ai
147API1 小时前
Claude 模型选型:Opus/Sonnet/Haiku + 成本/限速预算(Kotlin)
android·开发语言·kotlin·147api
a187927218312 小时前
【教程】打通本地 IDE AI 与云端 AI 的记忆壁垒:基于 COS 的跨 AI 终端记忆共享与通信系统
人工智能·ai·ai编程·claude·mem·agents·vibe coding
电商API_180079052472 小时前
企业级应用:京东商品详情 API 的高可用架构与多级缓存设计
开发语言·人工智能·python·数据分析·网络爬虫·php
MoonBit月兔2 小时前
MoonBit 0.8.3版本更新
开发语言·人工智能·算法·ai编程·moonbit
小此方2 小时前
Re:从零开始的 C++ 进阶篇(二)C++继承到底做了什么?从对象模型到底层内存布局彻底讲透
c语言·开发语言·c++
哪 吒2 小时前
国内如何使用Gemini 3.1 Pro?
gpt·ai·chatgpt·gemini