Commit 28c2f4b6 authored by jaden's avatar jaden

feat: auto cdn

parent c55c1f98
type dbml = string type dbml = string;
export const GET_QUERY = (sql:dbml) =>`作为一个数据库模型业务分析专家,您需要根据当前数据库模型(DBML格式)生成对应的 MySQL 数据库可执行的 SQL 文本,并列出执行该 SQL 所需的变量及其解释,最后为此条查询命名。当前数据库模型为: export const GET_QUERY = (
sql: dbml
) => `作为一个数据库模型业务分析专家,您需要根据当前数据库模型(DBML格式)生成对应的 MySQL 数据库可执行的 SQL 文本,并列出执行该 SQL 所需的变量及其解释,最后为此条查询命名。当前数据库模型为:
\`\`\`dbml \`\`\`dbml
${sql} ${sql}
...@@ -15,8 +17,8 @@ ${sql} ...@@ -15,8 +17,8 @@ ${sql}
执行所需变量: 执行所需变量:
判断解决当前问题的查询执行时是否需要变量。若条件成立,请使用: 判断解决当前问题的查询执行时是否需要变量。若条件成立,请使用:
<var>执行 SQL 所需变量名称</var> <var>&=& 执行 SQL 所需变量名称 &=&</var>
<varDescription>变量解释</varDescription> <varDescription>&=& 变量解释 &=&</varDescription>
若不需要变量,则无需提供任何信息。 若不需要变量,则无需提供任何信息。
...@@ -41,13 +43,17 @@ INSERT INTO users (email, name) VALUES ($email$, $name$); ...@@ -41,13 +43,17 @@ INSERT INTO users (email, name) VALUES ($email$, $name$);
查询命名和描述: 查询命名和描述:
<queryName> 查用户和插入用户 </queryName> <queryName> 查用户和插入用户 </queryName>
<queryDescription> 先根据用户id查出用户,然后插入一个用户。 </queryDescription> <queryDescription> 先根据用户id查出用户,然后插入一个用户。 </queryDescription>
` `;
export const GET_SCHEMA_INFO = (sql:dbml) =>`作为一个数据模型业务分析专家,您需要根据当前数据模型(DBML格式)进行精确的分析,根据模型的提供的信息,分析该模型并输出简要描述。当前数据库模型为: export const GET_SCHEMA_INFO = (
sql: dbml
) => `作为一个数据模型业务分析专家,您需要根据当前数据模型(DBML格式)进行精确的分析,根据模型的提供的信息,分析该模型并输出简要描述。当前数据库模型为:
<dbml> <dbml>
${sql} ${sql}
</dbml> </dbml>
` `;
export const ADD_TABLE = (sql:dbml)=>`作为一位资深的业务分析的专家,你需要结合当前数据库模型(DBML格式)并精确地分析我需要在当前数据库模型新增加的业务需求,向当前数据库模型添加(DBML格式)新表或者修改表字段之间的关联关系。当前数据库模型为: export const ADD_TABLE = (
sql: dbml
) => `作为一位资深的业务分析的专家,你需要结合当前数据库模型(DBML格式)并精确地分析我需要在当前数据库模型新增加的业务需求,向当前数据库模型添加(DBML格式)新表或者修改表字段之间的关联关系。当前数据库模型为:
<dbml> <dbml>
${sql} ${sql}
</dbml> </dbml>
...@@ -87,9 +93,10 @@ Table users as U { ...@@ -87,9 +93,10 @@ Table users as U {
已经为你生成:<tableName>users</tableName> 已经为你生成:<tableName>users</tableName>
<field>product_tags.id</field>:<description>主键</description> <field>product_tags.id</field>:<description>主键</description>
<field>full_name</field>:<description>姓名</description>` <field>full_name</field>:<description>姓名</description>`;
export const ADD_SCHEMA=()=>`你作为一个擅长业务分析的数据库模型建表专家,您需要分析我的业务需求并且输出 DBML格式 的数据库模型,添加一个或多个表和新增的表字段之间的关联关系。 export const ADD_SCHEMA =
() => `你作为一个擅长业务分析的数据库模型建表专家,您需要分析我的业务需求并且输出 DBML格式 的数据库模型,添加一个或多个表和新增的表字段之间的关联关系。
请您使用以下模版格式输出结果 (输出格式:XML,注意:XMl标签需要保留) 请您使用以下模版格式输出结果 (输出格式:XML,注意:XMl标签需要保留)
=======模版开始======= =======模版开始=======
...@@ -127,4 +134,4 @@ Table users as U { ...@@ -127,4 +134,4 @@ Table users as U {
}</dbml> }</dbml>
已经为你生成:<tableName>merchants</tableName> <tableName>users</tableName> 已经为你生成:<tableName>merchants</tableName> <tableName>users</tableName>
` `;
\ No newline at end of file
import { Alert, Button, Card, Collapse, Input, Select, Spin } from '@arco-design/web-react'; import {
Alert,
Button,
Card,
Collapse,
Input,
Select,
Spin,
Tooltip,
} from '@arco-design/web-react';
import { import {
IconCode, IconCode,
IconEye, IconEye,
...@@ -31,7 +40,7 @@ import AI from '@/components/AITool'; ...@@ -31,7 +40,7 @@ import AI from '@/components/AITool';
import useSWRMutation from 'swr/mutation'; import useSWRMutation from 'swr/mutation';
import getView from '@/client/api/getView'; import getView from '@/client/api/getView';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { get, isEqual } from 'lodash'; import { get, isEqual, map, set } from 'lodash';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Editor, { Monaco, useMonaco, OnMount } from '@monaco-editor/react'; import Editor, { Monaco, useMonaco, OnMount } from '@monaco-editor/react';
import { XML } from '@/utils/getXMLContent'; import { XML } from '@/utils/getXMLContent';
...@@ -40,10 +49,15 @@ import dynamic from 'next/dynamic'; ...@@ -40,10 +49,15 @@ import dynamic from 'next/dynamic';
const ReactJson = dynamic(() => import('react-json-view'), { ssr: false }); const ReactJson = dynamic(() => import('react-json-view'), { ssr: false });
import { Parser } from 'acorn'; import { Parser } from 'acorn';
import ConnectDb, { Query } from '@/client/api/connectDb'; import ConnectDb, { Query } from '@/client/api/connectDb';
import 'systemjs';
import dayjs from 'dayjs';
import { simple } from 'acorn-walk';
import jsx from 'acorn-jsx';
const CollapseItem = Collapse.Item; const CollapseItem = Collapse.Item;
type MonacoEditor = Parameters<OnMount>[0]; type MonacoEditor = Parameters<OnMount>[0];
declare const System: any;
function Error() { function Error() {
const { error } = useLiveContext(); const { error } = useLiveContext();
...@@ -55,18 +69,80 @@ const init = `/** ...@@ -55,18 +69,80 @@ const init = `/**
* @description 处理数据的函数 * @description 处理数据的函数
* @param record<string,any> data * @param record<string,any> data
*/ */
`;
async function getUMDPath(packageName: string) {
const response = await fetch(`https://data.jsdelivr.com/v1/packages/npm/${packageName}`);
const packageJson = await response.json();
const packageLatest = get(packageJson, 'versions[0]');
const version = get(packageLatest, 'version');
const entryFile = await (await fetch(get(packageLatest, 'links.entrypoints'))).json();
// 一些包可能会在 "browser" 字段指定UMD模块的路径
return map(get(entryFile, 'entrypoints', []), (item: any, type: string) => {
return {
type: type,
url: `https://cdn.jsdelivr.net/npm/${packageName}@${version}${get(item, 'file')}`,
};
});
}
function loadUMDModule(packageName: string) {
return new Promise((resolve, reject) => {
try {
// const script = document.createElement('script');
// script.type = 'module';
// const initFnName: any = [packageName + 'Init'];
// window[initFnName] = mod => {
// resolve(mod);
// delete window[initFnName];
// };
// const errHandler = e => {
// resolve(loadUMDModuleBySystem(packageName));
// window.removeEventListener('error', errHandler);
// console.log('error: esm load err', e);
// };
function handler(data){ // window.addEventListener('error', errHandler);
return data
// script.textContent = `
// import * as module from "https://esm.run/${packageName}";
// console.log(module,"module")
// window["${initFnName}"] && window["${initFnName}"](module)
// `;
// document.head.append(script);
resolve(loadUMDModuleBySystem(packageName));
} catch (e) {
console.log(e);
}
});
} }
`; async function loadUMDModuleBySystem(packageName: string) {
try {
window.define = undefined;
window.React = React;
window.ReactDOM = ReactDOM;
window.dayjs = dayjs;
const umdPath = await getUMDPath(packageName);
let mod;
for (const item of umdPath) {
const res = await System.import(item.url);
if (item.type === 'js') {
mod = res;
}
}
return mod;
} catch (error) {
console.error(error);
}
}
function ReactView() { function ReactView({ props }: { props: Record<string, any> }) {
const { code } = useLiveContext(); const { code } = useLiveContext();
return ( return (
<div> <div>
<div className="flex justify-end"> <div className="flex justify-end my-[5px]">
<Button <Button
className="mr-[60px] shadow" className="mr-[60px] shadow"
type="primary" type="primary"
...@@ -78,6 +154,7 @@ function ReactView() { ...@@ -78,6 +154,7 @@ function ReactView() {
{ {
code: code, code: code,
type: 'code', type: 'code',
props,
}, },
'*' '*'
); );
...@@ -107,17 +184,71 @@ export function ChatView({ ...@@ -107,17 +184,71 @@ export function ChatView({
const reqRef = useRef(nanoid()); const reqRef = useRef(nanoid());
const [showTable, setShowTable] = useState(false); const [showTable, setShowTable] = useState(false);
const [props, setProps] = useState(propsRaw); const [props, setProps] = useState(propsRaw);
const [dependenciesMap, setDepend] = useState({
react: React,
lodash: get(window, '_'),
'react-dom': ReactDOM,
'styled-components': styledComponents,
'echarts-for-react': ReactECharts,
dayjs,
echarts: {
default: echarts,
echarts: echarts,
...echarts,
},
});
useEffect(() => { useEffect(() => {
setProps(propsRaw); setProps(propsRaw);
}, [propsRaw]); }, [propsRaw]);
const { trigger, data, isMutating } = useSWRMutation(reqRef.current, (_, { arg: { need } }) => { const { trigger, data, isMutating } = useSWRMutation(
reqRef.current,
(_, { arg: { need } }) => {
return getView.getViewComponent({ return getView.getViewComponent({
props, props,
need, need,
}); });
},
{
async onSuccess(data) {
// loadUMDModule('echarts').then(mod => {
// console.log(mod, 'mod');
// });
const example = get(data, 'data.code');
const ast = Parser.extend(jsx()).parse(example, {
sourceType: 'module',
ecmaVersion: 6,
});
const dependencies: string[] = [];
try {
simple(ast, {
ImportDeclaration(node: any) {
node.source?.value && dependencies.push(node.source.value);
},
});
} catch (e) {}
const deps: any = {};
for (const depend of dependencies) {
if (!get(dependenciesMap, depend)) {
await loadUMDModule(depend).then(mod => {
console.log(mod);
if (mod) {
deps[depend] = mod;
}
}); });
}
}
setDepend({
...dependenciesMap,
...deps,
});
},
}
);
console.log(dependenciesMap);
const SendButton = useCallback( const SendButton = useCallback(
({ inputRef }: { inputRef: any }) => { ({ inputRef }: { inputRef: any }) => {
...@@ -144,7 +275,7 @@ export function ChatView({ ...@@ -144,7 +275,7 @@ export function ChatView({
const Live = useMemo(() => { const Live = useMemo(() => {
let node; let node;
try { try {
node = !showCode ? <LiveEditor /> : <ReactView />; node = !showCode ? <LiveEditor /> : <ReactView props={props} />;
} catch (err) { } catch (err) {
node = <LiveEditor />; node = <LiveEditor />;
} }
...@@ -154,24 +285,14 @@ export function ChatView({ ...@@ -154,24 +285,14 @@ export function ChatView({
code={example} code={example}
scope={{ scope={{
data: props, data: props,
import: { import: dependenciesMap,
react: React,
'react-dom': ReactDOM,
'styled-components': styledComponents,
'echarts-for-react': ReactECharts,
echarts: {
default: echarts,
echarts: echarts,
...echarts,
},
},
}} }}
> >
{node} {node}
<Error /> <Error />
</LiveProvider> </LiveProvider>
); );
}, [example, props, showCode]); }, [example, props, showCode, dependenciesMap]);
const [editor, setEditor] = useState<MonacoEditor>(); const [editor, setEditor] = useState<MonacoEditor>();
const monaco = useMonaco(); const monaco = useMonaco();
...@@ -220,7 +341,6 @@ export function ChatView({ ...@@ -220,7 +341,6 @@ export function ChatView({
const insertText = xml.get('FunctionCode'); const insertText = xml.get('FunctionCode');
const nextLineNumber = lineNumber + 1; const nextLineNumber = lineNumber + 1;
console.log(insertText);
const op1 = { const op1 = {
range: new monaco.Range( range: new monaco.Range(
lineNumber, lineNumber,
...@@ -301,10 +421,19 @@ export function ChatView({ ...@@ -301,10 +421,19 @@ export function ChatView({
retainInputValue: true, retainInputValue: true,
}} }}
onClick={() => { onClick={() => {
let comments: { [line: string]: string } = {};
const root: any = Parser.parse( const root: any = Parser.parse(
editor?.getValue() || functions, editor?.getValue() || functions,
{ {
ecmaVersion: 6, locations: true,
ranges: true,
sourceType: 'module',
ecmaVersion: 2020,
onComment: (...arg) => {
if (arg[1]) {
comments[arg[3] + 1] = arg[1];
}
},
} }
); );
...@@ -312,10 +441,12 @@ export function ChatView({ ...@@ -312,10 +441,12 @@ export function ChatView({
root, root,
'body' 'body'
); );
setFunctionOption( setFunctionOption(
body.filter( body.filter(v => {
v => v.type === 'FunctionDeclaration' set(v, 'comment', comments[v.start]);
) return v.type === 'FunctionDeclaration';
})
); );
}} }}
onChange={setFunctionName} onChange={setFunctionName}
...@@ -324,7 +455,16 @@ export function ChatView({ ...@@ -324,7 +455,16 @@ export function ChatView({
const name = get(item, 'id.name', ''); const name = get(item, 'id.name', '');
return ( return (
<Select.Option key={name} value={name}> <Select.Option key={name} value={name}>
{name} <Tooltip content={get(item, 'comment')}>
<span className="text-[12px] leading-[24px] text-[var(--pc)] mr-[5px]">
{get(
item,
'comment',
'暂无函数描述'
)}
</span>
</Tooltip>
<div>{name}</div>
</Select.Option> </Select.Option>
); );
})} })}
......
...@@ -10,10 +10,13 @@ import Link from 'next/link'; ...@@ -10,10 +10,13 @@ import Link from 'next/link';
import { useTranslation, Trans } from 'react-i18next'; import { useTranslation, Trans } from 'react-i18next';
import { useEffect } from 'react'; import { useEffect } from 'react';
import Script from 'next/script'; import Script from 'next/script';
declare const fireworks: any;
function Home() { function Home() {
const { t } = useTranslation(); const { t } = useTranslation();
useEffect(() => { useEffect(() => {
if (window?.fireworks) { if (get(window, 'fireworks')) {
document.querySelector('#fireworks')?.remove(); document.querySelector('#fireworks')?.remove();
fireworks(); fireworks();
} }
...@@ -36,7 +39,7 @@ function Home() { ...@@ -36,7 +39,7 @@ function Home() {
<Script <Script
src="https://cdn.jsdelivr.net/npm/tsparticles-fireworks@2.10.1/tsparticles.fireworks.bundle.min.js" src="https://cdn.jsdelivr.net/npm/tsparticles-fireworks@2.10.1/tsparticles.fireworks.bundle.min.js"
onLoad={() => { onLoad={() => {
if (window?.fireworks) { if (get(window, 'fireworks')) {
document.querySelector('#fireworks')?.remove(); document.querySelector('#fireworks')?.remove();
fireworks(); fireworks();
} }
......
...@@ -38,12 +38,21 @@ dependencies: ...@@ -38,12 +38,21 @@ dependencies:
acorn: acorn:
specifier: ^8.10.0 specifier: ^8.10.0
version: 8.10.0 version: 8.10.0
acorn-jsx:
specifier: ^5.3.2
version: 5.3.2(acorn@8.10.0)
acorn-walk:
specifier: ^8.2.0
version: 8.2.0
autoprefixer: autoprefixer:
specifier: ^10.4.13 specifier: ^10.4.13
version: 10.4.13(postcss@8.4.14) version: 10.4.13(postcss@8.4.14)
classnames: classnames:
specifier: ^2.3.1 specifier: ^2.3.1
version: 2.3.2 version: 2.3.2
dayjs:
specifier: ^1.11.9
version: 1.11.9
dexie: dexie:
specifier: ^3.2.2 specifier: ^3.2.2
version: 3.2.3 version: 3.2.3
...@@ -140,6 +149,9 @@ dependencies: ...@@ -140,6 +149,9 @@ dependencies:
swr: swr:
specifier: ^2.0.3 specifier: ^2.0.3
version: 2.0.3(react@18.2.0) version: 2.0.3(react@18.2.0)
systemjs:
specifier: ^6.14.1
version: 6.14.1
tailwindcss: tailwindcss:
specifier: ^3.2.7 specifier: ^3.2.7
version: 3.2.7(postcss@8.4.14) version: 3.2.7(postcss@8.4.14)
...@@ -191,7 +203,7 @@ packages: ...@@ -191,7 +203,7 @@ packages:
b-tween: 0.3.3 b-tween: 0.3.3
b-validate: 1.4.4 b-validate: 1.4.4
compute-scroll-into-view: 1.0.20 compute-scroll-into-view: 1.0.20
dayjs: 1.11.7 dayjs: 1.11.9
lodash: 4.17.21 lodash: 4.17.21
number-precision: 1.6.0 number-precision: 1.6.0
react: 18.2.0 react: 18.2.0
...@@ -2530,6 +2542,11 @@ packages: ...@@ -2530,6 +2542,11 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: false dev: false
/acorn-walk@8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
dev: false
/acorn@7.4.1: /acorn@7.4.1:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
...@@ -3037,8 +3054,8 @@ packages: ...@@ -3037,8 +3054,8 @@ packages:
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
dev: false dev: false
/dayjs@1.11.7: /dayjs@1.11.9:
resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==}
dev: false dev: false
/debug@3.2.7: /debug@3.2.7:
...@@ -5847,6 +5864,10 @@ packages: ...@@ -5847,6 +5864,10 @@ packages:
tslib: 2.5.0 tslib: 2.5.0
dev: false dev: false
/systemjs@6.14.1:
resolution: {integrity: sha512-8ftwWd+XnQtZ/aGbatrN4QFNGrKJzmbtixW+ODpci7pyoTajg4sonPP8aFLESAcuVxaC1FyDESt+SpfFCH9rZQ==}
dev: false
/tailwindcss@3.2.7(postcss@8.4.14): /tailwindcss@3.2.7(postcss@8.4.14):
resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==}
engines: {node: '>=12.13.0'} engines: {node: '>=12.13.0'}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment