|
@@ -1,28 +1,179 @@
|
|
|
import { useEditor } from "@/modules/editor";
|
|
|
-import { defineComponent } from "vue";
|
|
|
-import { Button, Input } from "ant-design-vue";
|
|
|
+import { CloseOutlined } from "@ant-design/icons-vue";
|
|
|
+import { defineComponent, reactive } from "vue";
|
|
|
+import { Button, Input, message } from "ant-design-vue";
|
|
|
+import { css } from "@linaria/core";
|
|
|
+import { queenApi } from "queenjs";
|
|
|
export default defineComponent({
|
|
|
- setup() {
|
|
|
- const { store } = useEditor();
|
|
|
+ emits: ["visible"],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const { store, actions } = useEditor();
|
|
|
+ const state = reactive({
|
|
|
+ loading: false,
|
|
|
+ inputValue: "",
|
|
|
+ aiValue: "",
|
|
|
+ boxFocus: false,
|
|
|
+ generated: false,
|
|
|
+ });
|
|
|
+ const generateWord = () => {
|
|
|
+ if (state.loading) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ state.loading = true;
|
|
|
+ const reqData = {
|
|
|
+ model: "gpt-3.5-turbo",
|
|
|
+ messages: [
|
|
|
+ {
|
|
|
+ role: "user",
|
|
|
+ content: state.inputValue,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ const xhr = new XMLHttpRequest();
|
|
|
+ xhr.open(
|
|
|
+ "post",
|
|
|
+ "http://186b2d5554134321a0afd4b1be443273.apig.ap-southeast-1.huaweicloudapis.com/chatgpt"
|
|
|
+ );
|
|
|
+ xhr.setRequestHeader("content-type", "application/json");
|
|
|
+ xhr.send(JSON.stringify(reqData));
|
|
|
+ xhr.onload = function (e: any) {
|
|
|
+ let result = e.target?.responseText;
|
|
|
+
|
|
|
+ try {
|
|
|
+ result = JSON.parse(result);
|
|
|
+ const { choices } = result;
|
|
|
+ const message = choices[0].message.content;
|
|
|
+ state.aiValue = message;
|
|
|
+ state.generated = true;
|
|
|
+ } catch (e) {
|
|
|
+ queenApi.messageError("生成失败!");
|
|
|
+ console.log(e);
|
|
|
+ } finally {
|
|
|
+ state.loading = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ xhr.onerror = (e: any) => {
|
|
|
+ queenApi.messageError("生成失败!");
|
|
|
+ console.log(e);
|
|
|
+ state.loading = false;
|
|
|
+ };
|
|
|
+ };
|
|
|
+ const addText = async () => {
|
|
|
+ const aitext = `<p style="line-height:1.5;"><span style="font-size:14px;">${state.aiValue}</span></p>`;
|
|
|
+ await actions.clickCompToDesign("Text", (comp) => {
|
|
|
+ actions.updateCompData(comp, "value", aitext);
|
|
|
+ });
|
|
|
+ };
|
|
|
|
|
|
return () => (
|
|
|
- <div class="w-280px p-20px bg-component border-r-4px">
|
|
|
+ <div class={[AIStyle, "w-280px p-20px bg-component"]}>
|
|
|
<div>
|
|
|
- <div>AI提示词</div>
|
|
|
- <div>
|
|
|
- <Input.TextArea showCount={true} />
|
|
|
+ <div class={"flex justify-between items-center "}>
|
|
|
+ AI提示词
|
|
|
+ <CloseOutlined
|
|
|
+ onClick={() => {
|
|
|
+ emit("visible", false);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class={"mt-14px"}>
|
|
|
+ <div class={["input_box pb-12px", state.boxFocus ? "focus" : ""]}>
|
|
|
+ <Input.TextArea
|
|
|
+ class={"ai_input scrollbar"}
|
|
|
+ value={state.inputValue}
|
|
|
+ maxlength={1000}
|
|
|
+ onChange={(e) => {
|
|
|
+ if (state.inputValue.length >= 1000) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ state.inputValue = e.target.value || "";
|
|
|
+ }}
|
|
|
+ onFocus={() => {
|
|
|
+ state.boxFocus = true;
|
|
|
+ }}
|
|
|
+ onBlur={() => {
|
|
|
+ state.boxFocus = false;
|
|
|
+ }}
|
|
|
+ autoSize={{ minRows: 3, maxRows: 6 }}
|
|
|
+ placeholder={"请输入关键词,AI将自动帮您生成对应文案"}
|
|
|
+ />
|
|
|
+ <div class={"px-12px text-right f-12px text-gray"}>
|
|
|
+ {state.inputValue.length}/1000
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div>
|
|
|
+ <div class={"mt-24px"}>
|
|
|
<div>结果生成</div>
|
|
|
- <div>
|
|
|
- <Input.TextArea />
|
|
|
+ <div class={"mt-14px result_text"}>
|
|
|
+ <Input.TextArea
|
|
|
+ class={"ai_input scrollbar"}
|
|
|
+ autoSize={{ minRows: 6, maxRows: 6 }}
|
|
|
+ readonly
|
|
|
+ value={state.aiValue}
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div>
|
|
|
- <Button type="primary">开始生成</Button>
|
|
|
+ <div class={"mt-24px space-y-10px"}>
|
|
|
+ {state.generated ? (
|
|
|
+ <Button
|
|
|
+ block
|
|
|
+ class={"fade_input"}
|
|
|
+ type="primary"
|
|
|
+ onClick={generateWord}
|
|
|
+ loading={state.loading}
|
|
|
+ >
|
|
|
+ 重新生成
|
|
|
+ </Button>
|
|
|
+ ) : (
|
|
|
+ <Button
|
|
|
+ block
|
|
|
+ type="primary"
|
|
|
+ onClick={generateWord}
|
|
|
+ loading={state.loading}
|
|
|
+ >
|
|
|
+ 开始生成
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
+ {state.generated && (
|
|
|
+ <Button block type="primary" onClick={addText}>
|
|
|
+ 添加至图层
|
|
|
+ </Button>
|
|
|
+ )}
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|
|
|
},
|
|
|
});
|
|
|
+const AIStyle = css`
|
|
|
+ border-radius: 4px;
|
|
|
+ box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2);
|
|
|
+ .input_box,
|
|
|
+ .result_text {
|
|
|
+ position: relative;
|
|
|
+ background-color: #303030;
|
|
|
+ border-radius: 4px;
|
|
|
+
|
|
|
+ .ai_input {
|
|
|
+ font-size: 12px;
|
|
|
+ border-color: transparent;
|
|
|
+ &:hover,
|
|
|
+ &:focus {
|
|
|
+ border-color: transparent;
|
|
|
+ box-shadow: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .input_box {
|
|
|
+ border: 1px solid transparent;
|
|
|
+ &.focus,
|
|
|
+ &:hover {
|
|
|
+ border-color: @inf-primary-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .fade_input {
|
|
|
+ color: @inf-primary-color;
|
|
|
+ border-color: @inf-primary-fade-color;
|
|
|
+ background-color: @inf-primary-fade-color;
|
|
|
+ }
|
|
|
+`;
|