From ad2c37be828ea3829492335da99667b8b5f42221 Mon Sep 17 00:00:00 2001 From: lyc Date: Tue, 15 Oct 2024 16:30:07 +0800 Subject: [PATCH 1/3] ai-ppt --- electron.vite.config.mjs | 5 + src/renderer/src/utils/aichat.js | 80 ++ src/renderer/src/utils/index.js | 33 + src/renderer/src/utils/ppt-request.js | 78 ++ .../src/views/prepare/container/ai-ppt.vue | 697 ++++++++++++++++++ .../views/prepare/container/ppt-dialog.vue | 33 + src/renderer/src/views/prepare/index.vue | 7 + 7 files changed, 933 insertions(+) create mode 100644 src/renderer/src/utils/aichat.js create mode 100644 src/renderer/src/utils/index.js create mode 100644 src/renderer/src/utils/ppt-request.js create mode 100644 src/renderer/src/views/prepare/container/ai-ppt.vue create mode 100644 src/renderer/src/views/prepare/container/ppt-dialog.vue diff --git a/electron.vite.config.mjs b/electron.vite.config.mjs index 01bf054..8e66b38 100644 --- a/electron.vite.config.mjs +++ b/electron.vite.config.mjs @@ -43,6 +43,11 @@ export default defineConfig({ changeOrigin: true, rewrite: (p) => p.replace(/^\/baidubce/, '') }, + '/parth': { + target: 'https://zwapi.xfyun.cn', // 第三方API的地址 + changeOrigin: true, // 改变请求的起源 + rewrite: (path) => path.replace(/^\/parth/, '') // 重写路径 + }, }, }, plugins: [vue(), WindiCSS()], diff --git a/src/renderer/src/utils/aichat.js b/src/renderer/src/utils/aichat.js new file mode 100644 index 0000000..85dcdc5 --- /dev/null +++ b/src/renderer/src/utils/aichat.js @@ -0,0 +1,80 @@ +import axios from "axios"; +import { getSignature } from "./index"; + +let appId = "01ec9aa3"; +let secret = "M2QxMDAxMjYyYTEzODMwMGRkZTQ4NmUy"; +let timestamp = Math.floor(Date.now() / 1000); +let signature = getSignature(appId, secret, timestamp); + +export function text2Text(data) { + return axios({ + url: "v1/chat/completions", + method: "post", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer yjCwlZCeUtBYvjHAQZdk:FtWNmJSWcZMCmTBQZfoH", + Accept: "*/*", + }, + data: { + model: "4.0Ultra", + messages: data, + stream: false, + }, + }); +} +export function uploadDoc(data) { + return axios({ + url: "openapi/v1/file/upload", + method: "post", + headers: { + "Content-Type": "multipart/form-data", + appId: appId, + timestamp: timestamp, + signature: signature, + }, + data: data, + }); +} +export function queryDocStatus(data) { + return axios({ + url: "openapi/v1/file/status", + method: "post", + headers: { + "Content-Type": "application/form-data", + appId: appId, + timestamp: timestamp, + signature: signature, + }, + data: data + }); +} +export function chatByDoc(fileId, data) { + const wsUrl = `wss://chatdoc.xfyun.cn/openapi/chat?fileId=${fileId}&appId=${appId}×tamp=${timestamp}&signature=${signature}`; + + const ws = new WebSocket(wsUrl); + + ws.onopen = () => { + const messageBody = { + fileIds: [fileId], + messages: data, + chatExtends: { + wikiPromptTpl: + "请将以下内容作为已知信息:\n\n请根据以上内容回答用户的问题。\n问题:\n回答:", + wikiFilterScore: 0.82, + temperature: 0.5, + sparkWhenWithoutEmbedding: false, + }, + }; + + ws.send(JSON.stringify(messageBody)); + }; + + ws.onmessage = (event) => { + const response = JSON.parse(event.data); + console.log("WebSocket 消息:", response); + }; + + ws.onerror = (error) => { + console.error("WebSocket 错误:", error); + }; +} \ No newline at end of file diff --git a/src/renderer/src/utils/index.js b/src/renderer/src/utils/index.js new file mode 100644 index 0000000..e7bf6a4 --- /dev/null +++ b/src/renderer/src/utils/index.js @@ -0,0 +1,33 @@ +import CryptoJS from 'crypto-js'; + +// 生成签名的主方法 +export function getSignature(appId, secret, ts) { + try { + const auth = md5(appId + ts); + return hmacSHA1Encrypt(auth, secret); + } catch (error) { + console.error('Error generating signature:', error); + return null; + } +} + +// MD5 加密 +function md5(cipherText) { + try { + return CryptoJS.MD5(cipherText).toString(); // 使用 CryptoJS 进行 MD5 加密 + } catch (error) { + console.error('Error in MD5 hashing:', error); + return null; + } +} + +// HMAC-SHA1 加密 +function hmacSHA1Encrypt(encryptText, encryptKey) { + try { + // 使用 CryptoJS 进行 HMAC-SHA1 加密,并转换为 Base64 格式 + return CryptoJS.HmacSHA1(encryptText, encryptKey).toString(CryptoJS.enc.Base64); + } catch (error) { + console.error('Error in HMAC-SHA1 encryption:', error); + return null; + } +} diff --git a/src/renderer/src/utils/ppt-request.js b/src/renderer/src/utils/ppt-request.js new file mode 100644 index 0000000..de0ab56 --- /dev/null +++ b/src/renderer/src/utils/ppt-request.js @@ -0,0 +1,78 @@ +import axios from "axios"; +import { getSignature } from "./index"; +import { ElMessage } from "element-plus"; + +let appId = "01ec9aa3"; +let secret = "M2QxMDAxMjYyYTEzODMwMGRkZTQ4NmUy"; +let timestamp = Math.floor(Date.now() / 1000); +let signature = getSignature(appId, secret, timestamp); + +const instance = axios.create({ + baseURL: "", + headers: { + "Content-Type": "application/json", + appId: appId, + timestamp: timestamp, + signature: signature, + }, +}); + +const createOutline = async (data) => { + console.log("createOutline data:", data); + try { + const response = await instance.post( + "/parth/api/aippt/createOutline", + data + ); + console.log("createOutline response:", response); + if (response.code == 81002) { + ElMessage.error("并发数量超过限制"); + } + return response.data; + } catch (error) { + console.error("请求失败:", error); + throw error; + } +}; +const getBackGround = async () => { + try { + const response = await instance.get("/parth/api/aippt/themeList"); + return response.data; + } catch (error) { + console.error("请求失败:", error); + throw error; + } +}; +const createPPT = async (data) => { + try { + const response = await instance.post("/parth/api/aippt/create", data); + console.log("createOutline response:", response); + + return response.data; + } catch (error) { + console.error("请求失败:", error); + throw error; + } +}; +const createByOutline = async (data) => { + try { + const response = await instance.post("/parth/api/aippt/createByOutline", data); + console.log("createByOutline response:", response); + + return response.data; + } catch (error) { + console.error("请求失败:", error); + throw error; + } +}; +const getProgress = async (id) => { + try { + const response = await instance.get(`/parth/api/aippt/progress?sid=${id}`); + return response.data; + } catch (error) { + console.error("请求失败:", error); + throw error; + } +}; + +export { instance, createOutline, getBackGround, createPPT, getProgress, createByOutline }; diff --git a/src/renderer/src/views/prepare/container/ai-ppt.vue b/src/renderer/src/views/prepare/container/ai-ppt.vue new file mode 100644 index 0000000..961c874 --- /dev/null +++ b/src/renderer/src/views/prepare/container/ai-ppt.vue @@ -0,0 +1,697 @@ + + + + + + diff --git a/src/renderer/src/views/prepare/container/ppt-dialog.vue b/src/renderer/src/views/prepare/container/ppt-dialog.vue new file mode 100644 index 0000000..ec40a5c --- /dev/null +++ b/src/renderer/src/views/prepare/container/ppt-dialog.vue @@ -0,0 +1,33 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/prepare/index.vue b/src/renderer/src/views/prepare/index.vue index 7b68cf6..c5f4dcc 100644 --- a/src/renderer/src/views/prepare/index.vue +++ b/src/renderer/src/views/prepare/index.vue @@ -13,6 +13,10 @@
传统课件
+
+
+
试验版
+
+