mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-13 06:02:49 +00:00
1
This commit is contained in:
parent
37c5b1c0fb
commit
4f366ef636
2982
build/cool/eps.d.ts
vendored
2982
build/cool/eps.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,8 @@ import { getRules } from "./utils";
|
|||||||
export default (): ModuleConfig => {
|
export default (): ModuleConfig => {
|
||||||
return {
|
return {
|
||||||
options: {
|
options: {
|
||||||
host: "https://service.cool-js.com"
|
host: "/dev"
|
||||||
|
// host: "https://service.cool-js.com"
|
||||||
},
|
},
|
||||||
toolbar: {
|
toolbar: {
|
||||||
order: 1,
|
order: 1,
|
||||||
|
|||||||
@ -1,109 +1,105 @@
|
|||||||
import { ElNotification } from "element-plus";
|
|
||||||
import { io, Socket } from "socket.io-client";
|
|
||||||
import { module, useCool } from "/@/cool";
|
|
||||||
import { request } from "../utils";
|
import { request } from "../utils";
|
||||||
import type { EpsColumn } from "../types";
|
import type { EpsColumn } from "../types";
|
||||||
|
import { module } from "/@/cool";
|
||||||
|
import { useBase } from "/$/base";
|
||||||
|
|
||||||
export function useAi() {
|
export function useAi() {
|
||||||
const { route, router } = useCool();
|
|
||||||
const { host } = module.config("helper");
|
const { host } = module.config("helper");
|
||||||
|
const { user } = useBase();
|
||||||
|
|
||||||
let socket: Socket | null;
|
// 调用流程
|
||||||
|
async function invokeFlow(
|
||||||
|
label: string,
|
||||||
|
params: any,
|
||||||
|
streamCb?: ({ isEnd, content }: { isEnd: boolean; content: string }) => void
|
||||||
|
): Promise<any> {
|
||||||
|
const stream = !!streamCb;
|
||||||
|
|
||||||
// 连接
|
let cacheText = "";
|
||||||
function connect(cb: { onMessage?(content: string): void; onComplete?(): void }) {
|
|
||||||
if (!socket) {
|
|
||||||
socket = io(`${host}/code`, {
|
|
||||||
transports: ["websocket"]
|
|
||||||
});
|
|
||||||
|
|
||||||
if (socket) {
|
return new Promise((resolve, reject) => {
|
||||||
// 连接
|
fetch(host + "/open/code/gen/data", {
|
||||||
socket.on("connect", () => {
|
method: "POST",
|
||||||
console.log("connect");
|
headers: {
|
||||||
|
Authorization: user.token,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
params,
|
||||||
|
label,
|
||||||
|
stream
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.body) {
|
||||||
|
if (stream) {
|
||||||
|
const reader = res.body.getReader();
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
const stream = new ReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
function push() {
|
||||||
|
reader.read().then(({ done, value }) => {
|
||||||
|
if (done) {
|
||||||
|
controller.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let content = "";
|
let text = decoder.decode(value, { stream: true });
|
||||||
let code = "";
|
|
||||||
let isEnd = false;
|
|
||||||
let timer: any;
|
|
||||||
|
|
||||||
// 消息
|
if (streamCb) {
|
||||||
socket?.on("data", (msg: { isEnd: boolean; content: string }) => {
|
if (cacheText) {
|
||||||
isEnd = msg.isEnd;
|
text = cacheText + text;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.isEnd) {
|
if (text.indexOf("data:") == 0) {
|
||||||
if (route.path != "/helper/ai-code") {
|
text = "\n\n" + text;
|
||||||
const notify = ElNotification({
|
}
|
||||||
title: "提示",
|
|
||||||
message: "Ai自动生成代码完成,点击查看",
|
try {
|
||||||
duration: 0,
|
const arr = text
|
||||||
onClick() {
|
.split(/\n\ndata:/g)
|
||||||
router.push("/helper/ai-code");
|
.filter(Boolean)
|
||||||
notify.close();
|
.map((e) => JSON.parse(e));
|
||||||
|
|
||||||
|
arr.forEach(streamCb);
|
||||||
|
|
||||||
|
cacheText = "";
|
||||||
|
} catch (err) {
|
||||||
|
cacheText = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.enqueue(text);
|
||||||
|
push();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
push();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(stream);
|
||||||
} else {
|
} else {
|
||||||
try {
|
return res.json();
|
||||||
// 首行去掉 \n
|
|
||||||
if (msg.content.includes("\n") && !content) {
|
|
||||||
msg.content = msg.content.replace(/\n/, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去掉描述
|
|
||||||
msg.content = msg.content
|
|
||||||
.replace(/```/g, "")
|
|
||||||
.replace(/typescript/g, "");
|
|
||||||
|
|
||||||
// 拼接内容
|
|
||||||
content += msg.content || "";
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (stream) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (!timer) {
|
if (res.code == 1000) {
|
||||||
// 逐字输出
|
resolve(res.data.result);
|
||||||
timer = setInterval(() => {
|
} else {
|
||||||
const v = content[code.length] || "";
|
reject(res);
|
||||||
|
}
|
||||||
if (!v && isEnd) {
|
})
|
||||||
content = "";
|
.catch(reject);
|
||||||
code = "";
|
});
|
||||||
isEnd = false;
|
|
||||||
|
|
||||||
// 清除事件
|
|
||||||
clearInterval(timer);
|
|
||||||
timer = null;
|
|
||||||
|
|
||||||
// 完成事件
|
|
||||||
cb.onComplete?.();
|
|
||||||
} else {
|
|
||||||
code += v;
|
|
||||||
|
|
||||||
// 消息事件
|
|
||||||
cb?.onMessage?.(code);
|
|
||||||
}
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 断开
|
|
||||||
socket.on("disconnect", (err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送
|
|
||||||
function send(data: { name: string; columns: string[]; module: string }) {
|
|
||||||
socket?.emit("instruct", data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 匹配组件类型
|
// 匹配组件类型
|
||||||
function matchType({ columns, name }: { columns: EpsColumn[]; name: string }) {
|
async function matchType({ columns, name }: { columns: EpsColumn[]; name: string }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const fields = columns.filter((e) => {
|
const fields = columns.filter((e) => {
|
||||||
return !["id", "crateTime", "updateTime"].includes(e.propertyName);
|
return !["id", "crateTime", "updateTime"].includes(e.propertyName);
|
||||||
@ -137,8 +133,7 @@ export function useAi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
connect,
|
matchType,
|
||||||
send,
|
invokeFlow
|
||||||
matchType
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/modules/helper/static/svg/code.svg
Normal file
1
src/modules/helper/static/svg/code.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1719377496622" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6926" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M213.333 128h85.334v85.333h-85.334v213.334A85.333 85.333 0 0 1 128 512a85.333 85.333 0 0 1 85.333 85.333v213.334h85.334V896h-85.334C167.68 884.48 128 857.6 128 810.667V640a85.333 85.333 0 0 0-85.333-85.333H0v-85.334h42.667A85.333 85.333 0 0 0 128 384V213.333A85.333 85.333 0 0 1 213.333 128m597.334 0A85.333 85.333 0 0 1 896 213.333V384a85.333 85.333 0 0 0 85.333 85.333H1024v85.334h-42.667A85.333 85.333 0 0 0 896 640v170.667A85.333 85.333 0 0 1 810.667 896h-85.334v-85.333h85.334V597.333A85.333 85.333 0 0 1 896 512a85.333 85.333 0 0 1-85.333-85.333V213.333h-85.334V128h85.334M512 640a42.667 42.667 0 0 1 42.667 42.667A42.667 42.667 0 0 1 512 725.333a42.667 42.667 0 0 1-42.667-42.666A42.667 42.667 0 0 1 512 640m-170.667 0A42.667 42.667 0 0 1 384 682.667a42.667 42.667 0 0 1-42.667 42.666 42.667 42.667 0 0 1-42.666-42.666A42.667 42.667 0 0 1 341.333 640m341.334 0a42.667 42.667 0 0 1 42.666 42.667 42.667 42.667 0 0 1-42.666 42.666A42.667 42.667 0 0 1 640 682.667 42.667 42.667 0 0 1 682.667 640z" p-id="6927"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -1 +0,0 @@
|
|||||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1718961548891" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2699" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M330.6 311.2c-16.7-16.7-43.7-16.7-60.3 0L67.6 513.8l202.9 199.3c8.3 8.1 19.1 12.2 29.9 12.2 11 0 22.1-4.2 30.4-12.8 16.5-16.8 16.3-43.8-0.5-60.4l-141.5-139 141.8-141.8c16.7-16.5 16.7-43.5 0-60.1zM757.5 311.4c-16.5-16.8-43.5-17.1-60.3-0.5-16.8 16.5-17 43.5-0.5 60.3l139.5 142-139.3 139.3c-16.7 16.7-16.7 43.7 0 60.3 8.3 8.3 19.2 12.5 30.2 12.5s21.8-4.2 30.2-12.5l199.1-199-198.9-202.4zM564.8 256.8c-23.1-4.5-45.6 10.4-50.2 33.5L429.3 717c-4.6 23.1 10.4 45.6 33.5 50.2 2.8 0.6 5.6 0.8 8.4 0.8 19.9 0 37.8-14 41.8-34.3L598.3 307c4.6-23.1-10.4-45.6-33.5-50.2z" p-id="2700"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 915 B |
@ -10,7 +10,7 @@ export async function request(options: any): Promise<any> {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios({
|
axios({
|
||||||
...options,
|
...options,
|
||||||
url: host + "/api" + options.url
|
url: host + options.url
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { code, data, message } = res.data;
|
const { code, data, message } = res.data;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user