mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-12 13:42:50 +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 => {
|
||||
return {
|
||||
options: {
|
||||
host: "https://service.cool-js.com"
|
||||
host: "/dev"
|
||||
// host: "https://service.cool-js.com"
|
||||
},
|
||||
toolbar: {
|
||||
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 type { EpsColumn } from "../types";
|
||||
import { module } from "/@/cool";
|
||||
import { useBase } from "/$/base";
|
||||
|
||||
export function useAi() {
|
||||
const { route, router } = useCool();
|
||||
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;
|
||||
|
||||
// 连接
|
||||
function connect(cb: { onMessage?(content: string): void; onComplete?(): void }) {
|
||||
if (!socket) {
|
||||
socket = io(`${host}/code`, {
|
||||
transports: ["websocket"]
|
||||
});
|
||||
let cacheText = "";
|
||||
|
||||
if (socket) {
|
||||
// 连接
|
||||
socket.on("connect", () => {
|
||||
console.log("connect");
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(host + "/open/code/gen/data", {
|
||||
method: "POST",
|
||||
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 code = "";
|
||||
let isEnd = false;
|
||||
let timer: any;
|
||||
let text = decoder.decode(value, { stream: true });
|
||||
|
||||
// 消息
|
||||
socket?.on("data", (msg: { isEnd: boolean; content: string }) => {
|
||||
isEnd = msg.isEnd;
|
||||
if (streamCb) {
|
||||
if (cacheText) {
|
||||
text = cacheText + text;
|
||||
}
|
||||
|
||||
if (msg.isEnd) {
|
||||
if (route.path != "/helper/ai-code") {
|
||||
const notify = ElNotification({
|
||||
title: "提示",
|
||||
message: "Ai自动生成代码完成,点击查看",
|
||||
duration: 0,
|
||||
onClick() {
|
||||
router.push("/helper/ai-code");
|
||||
notify.close();
|
||||
if (text.indexOf("data:") == 0) {
|
||||
text = "\n\n" + text;
|
||||
}
|
||||
|
||||
try {
|
||||
const arr = text
|
||||
.split(/\n\ndata:/g)
|
||||
.filter(Boolean)
|
||||
.map((e) => JSON.parse(e));
|
||||
|
||||
arr.forEach(streamCb);
|
||||
|
||||
cacheText = "";
|
||||
} catch (err) {
|
||||
cacheText = text;
|
||||
}
|
||||
}
|
||||
|
||||
controller.enqueue(text);
|
||||
push();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
push();
|
||||
}
|
||||
});
|
||||
|
||||
return new Response(stream);
|
||||
} else {
|
||||
try {
|
||||
// 首行去掉 \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);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
if (stream) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!timer) {
|
||||
// 逐字输出
|
||||
timer = setInterval(() => {
|
||||
const v = content[code.length] || "";
|
||||
|
||||
if (!v && isEnd) {
|
||||
content = "";
|
||||
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);
|
||||
if (res.code == 1000) {
|
||||
resolve(res.data.result);
|
||||
} else {
|
||||
reject(res);
|
||||
}
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
// 匹配组件类型
|
||||
function matchType({ columns, name }: { columns: EpsColumn[]; name: string }) {
|
||||
async function matchType({ columns, name }: { columns: EpsColumn[]; name: string }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fields = columns.filter((e) => {
|
||||
return !["id", "crateTime", "updateTime"].includes(e.propertyName);
|
||||
@ -137,8 +133,7 @@ export function useAi() {
|
||||
}
|
||||
|
||||
return {
|
||||
connect,
|
||||
send,
|
||||
matchType
|
||||
matchType,
|
||||
invokeFlow
|
||||
};
|
||||
}
|
||||
|
||||
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) => {
|
||||
axios({
|
||||
...options,
|
||||
url: host + "/api" + options.url
|
||||
url: host + options.url
|
||||
})
|
||||
.then((res) => {
|
||||
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