AiText.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { useEditor } from "@/modules/editor";
  2. import { CloseOutlined } from "@ant-design/icons-vue";
  3. import { defineComponent, reactive } from "vue";
  4. import { Button, Input, message } from "ant-design-vue";
  5. import { css } from "@linaria/core";
  6. import { queenApi } from "queenjs";
  7. export default defineComponent({
  8. emits: ["visible"],
  9. setup(props, { emit }) {
  10. const { store, actions } = useEditor();
  11. const state = reactive({
  12. loading: false,
  13. inputValue: "",
  14. aiValue: "",
  15. boxFocus: false,
  16. generated: false,
  17. });
  18. const generateWord = () => {
  19. if (state.loading) {
  20. return;
  21. }
  22. state.loading = true;
  23. const reqData = {
  24. model: "gpt-3.5-turbo",
  25. messages: [
  26. {
  27. role: "user",
  28. content: state.inputValue,
  29. },
  30. ],
  31. };
  32. const xhr = new XMLHttpRequest();
  33. xhr.open(
  34. "post",
  35. "https://186b2d5554134321a0afd4b1be443273.apig.ap-southeast-1.huaweicloudapis.com/chatgpt"
  36. );
  37. xhr.setRequestHeader("content-type", "application/json");
  38. xhr.send(JSON.stringify(reqData));
  39. xhr.onload = function (e: any) {
  40. let result = e.target?.responseText;
  41. try {
  42. result = JSON.parse(result);
  43. const { choices } = result;
  44. const message = choices[0].message.content;
  45. state.aiValue = message;
  46. state.generated = true;
  47. } catch (e) {
  48. queenApi.messageError("生成失败!");
  49. console.log(e);
  50. } finally {
  51. state.loading = false;
  52. }
  53. };
  54. xhr.onerror = (e: any) => {
  55. queenApi.messageError("生成失败!");
  56. console.log(e);
  57. state.loading = false;
  58. };
  59. };
  60. const addText = async () => {
  61. const aitext = `<p style="line-height:1.5;"><span style="font-size:14px;">${state.aiValue}</span></p>`;
  62. await actions.clickCompToDesign("Text", (comp) => {
  63. actions.updateCompData(comp, "value", aitext);
  64. });
  65. };
  66. return () => (
  67. <div class={[AIStyle, "w-280px p-20px bg-component"]}>
  68. <div>
  69. <div class={"flex justify-between items-center "}>
  70. AI提示词
  71. <CloseOutlined
  72. onClick={() => {
  73. emit("visible", false);
  74. }}
  75. />
  76. </div>
  77. <div class={"mt-14px"}>
  78. <div class={["input_box pb-12px", state.boxFocus ? "focus" : ""]}>
  79. <Input.TextArea
  80. class={"ai_input scrollbar"}
  81. value={state.inputValue}
  82. maxlength={1000}
  83. onChange={(e) => {
  84. if (state.inputValue.length >= 1000) {
  85. return;
  86. }
  87. state.inputValue = e.target.value || "";
  88. }}
  89. onFocus={() => {
  90. state.boxFocus = true;
  91. }}
  92. onBlur={() => {
  93. state.boxFocus = false;
  94. }}
  95. autoSize={{ minRows: 3, maxRows: 6 }}
  96. placeholder={"请输入关键词,AI将自动帮您生成对应文案"}
  97. />
  98. <div class={"px-12px text-right f-12px text-white"}>
  99. {state.inputValue.length}/1000
  100. </div>
  101. </div>
  102. </div>
  103. </div>
  104. <div class={"mt-24px"}>
  105. <div>结果生成</div>
  106. <div class={"mt-14px result_text"}>
  107. <Input.TextArea
  108. class={"ai_input scrollbar"}
  109. autoSize={{ minRows: 6, maxRows: 6 }}
  110. readonly
  111. value={state.aiValue}
  112. />
  113. </div>
  114. </div>
  115. <div class={"mt-24px space-y-10px"}>
  116. {state.generated ? (
  117. <Button
  118. block
  119. class={"fade_input"}
  120. type="primary"
  121. onClick={generateWord}
  122. loading={state.loading}
  123. >
  124. 重新生成
  125. </Button>
  126. ) : (
  127. <Button
  128. block
  129. type="primary"
  130. onClick={generateWord}
  131. loading={state.loading}
  132. >
  133. 开始生成
  134. </Button>
  135. )}
  136. {state.generated && (
  137. <Button block type="primary" onClick={addText}>
  138. 添加至图层
  139. </Button>
  140. )}
  141. </div>
  142. </div>
  143. );
  144. },
  145. });
  146. const AIStyle = css`
  147. border-radius: 4px;
  148. box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2);
  149. background-color: rgba(38, 38, 38, 0.95);
  150. color: #fff;
  151. .input_box,
  152. .result_text {
  153. position: relative;
  154. background-color: rgba(255, 255, 255, 0.2);
  155. border-radius: 4px;
  156. .ai_input {
  157. color: #fff;
  158. font-size: 12px;
  159. border-color: transparent;
  160. &:hover,
  161. &:focus {
  162. border-color: transparent;
  163. box-shadow: none;
  164. }
  165. &::placeholder {
  166. color: #fff;
  167. }
  168. }
  169. }
  170. .input_box {
  171. border: 1px solid transparent;
  172. &.focus,
  173. &:hover {
  174. border-color: @inf-primary-color;
  175. }
  176. }
  177. .fade_input {
  178. color: @inf-primary-color;
  179. border-color: @inf-primary-fade-color;
  180. background-color: @inf-primary-fade-color;
  181. }
  182. `;