This commit is contained in:
神仙 2024-06-30 20:57:12 +08:00
parent a5bd14020f
commit 76a2ac05be
13 changed files with 5417 additions and 5110 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.DS_Store .DS_Store
node_modules/ node_modules/
/dist/ /dist/
/build/
dist-ssr/ dist-ssr/
# Log files # Log files

878
build/cool/eps.d.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
"lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix" "lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix"
}, },
"dependencies": { "dependencies": {
"@cool-vue/crud": "^7.1.23", "@cool-vue/crud": "^7.1.24",
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^10.4.0", "@vueuse/core": "^10.4.0",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-vue/crud", "name": "@cool-vue/crud",
"version": "7.1.23", "version": "7.1.24",
"private": false, "private": false,
"main": "./dist/index.umd.min.js", "main": "./dist/index.umd.min.js",
"typings": "types/index.d.ts", "typings": "types/index.d.ts",

File diff suppressed because it is too large Load Diff

View File

@ -23,26 +23,35 @@ function useParent(name: string, r: Ref) {
} }
// 多事件 // 多事件
function useEvent(names: string[], { r, options, clear }: any) { function useEvent(
const d: any = {}; names: string[],
{ r, options, clear, isChild }: { r: any; options: any; clear?: string; isChild?: boolean }
) {
if (!r.__ev) r.__ev = {}; if (!r.__ev) r.__ev = {};
const d: { [key: string]: (args: any[]) => void } = {};
const ev = r.__ev as { [key: string]: { fn: any; isChild?: boolean }[] };
names.forEach((k) => { names.forEach((k) => {
if (!r.__ev[k]) r.__ev[k] = []; if (!ev[k]) ev[k] = [];
if (options[k]) { if (options[k]) {
r.__ev[k].push(options[k]); ev[k].push({
fn: options[k],
isChild
});
} }
d[k] = (...args: any[]) => { d[k] = (...args: any[]) => {
r.__ev[k].filter(Boolean).forEach((e: any) => { ev[k].forEach((e) => {
e(...args); if (e.fn) {
e.fn(...args);
}
}); });
if (clear == k) { if (clear == k) {
for (const i in r.__ev) { for (const i in ev) {
r.__ev[i].splice(1, 999); ev[i] = ev[i].filter((e) => !e.isChild);
} }
} }
}; };
@ -80,6 +89,7 @@ export function useCrud(options?: ClCrud.Options, cb?: (app: ClCrud.Ref) => void
export function useUpsert<T = any>(options?: ClUpsert.Options<T>) { export function useUpsert<T = any>(options?: ClUpsert.Options<T>) {
const Upsert = ref<ClUpsert.Ref>(); const Upsert = ref<ClUpsert.Ref>();
useParent("cl-upsert", Upsert); useParent("cl-upsert", Upsert);
const isChild = !!Upsert.value;
if (options) { if (options) {
provide("useUpsert__options", options); provide("useUpsert__options", options);
@ -93,7 +103,8 @@ export function useUpsert<T = any>(options?: ClUpsert.Options<T>) {
const event = useEvent(["onOpen", "onOpened", "onClosed"], { const event = useEvent(["onOpen", "onOpened", "onClosed"], {
r: val, r: val,
options, options,
clear: "onClosed" clear: "onClosed",
isChild
}); });
Object.assign(val.config, event); Object.assign(val.config, event);

View File

@ -9,7 +9,7 @@ export function setFocus(prop?: string): ClForm.Plugin {
const { refs, setRefs } = useRefs(); const { refs, setRefs } = useRefs();
return ({ exposed, onOpen }) => { return ({ exposed, onOpen }) => {
const name = prop || exposed.config.items?.[0]?.prop; const name = prop || exposed.config?.items?.[0]?.prop;
let _ref: any; let _ref: any;
if (name) { if (name) {
@ -29,7 +29,7 @@ export function setFocus(prop?: string): ClForm.Plugin {
}); });
} }
deep(exposed.config.items); deep(exposed.config?.items || []);
onOpen(() => { onOpen(() => {
if (_ref) { if (_ref) {

View File

@ -262,7 +262,7 @@ const Upsert = useUpsert({
label: "上级节点", label: "上级节点",
hook: { hook: {
submit(value) { submit(value) {
return value === "" ? null : value; return value || null;
} }
}, },
component: { component: {

View File

@ -27,6 +27,7 @@ function toCode() {
position: relative; position: relative;
border-radius: 4px; border-radius: 4px;
padding: 5px 10px; padding: 5px 10px;
white-space: nowrap;
letter-spacing: 1px; letter-spacing: 1px;
span { span {

View File

@ -26,7 +26,7 @@ import type { EpsData } from "../../types";
const { service, mitt } = useCool(); const { service, mitt } = useCool();
const menu = useMenu(); const menu = useMenu();
const Form = useForm(); const Form = useForm();
const { matchType } = useAi(); const ai = useAi();
// //
const list: any[] = []; const list: any[] = [];
@ -193,7 +193,7 @@ function open() {
// ai // ai
if (data.isAi) { if (data.isAi) {
await matchType({ columns, name: data.name }); await ai.matchType({ columns, name: data.name });
} }
menu.create({ menu.create({

View File

@ -289,19 +289,24 @@ export function useCode() {
}); });
} }
console.log(table.columns);
// 筛选 // 筛选
const clFilter = fieldEq.map((field) => { const clFilter = fieldEq
const item = table.columns.find((e) => e.propertyName == field); .map((field) => {
const item = table.columns.find((e) => e.prop == field);
return item return item
? `<!-- 筛选${item.label} -->\n<cl-filter label="${item.label}"><cl-select options="${item.dict}" prop="${field}" /></cl-filter>` ? `<!-- 筛选${item.label} -->\n<cl-filter label="${
item.label
}">\n<cl-select options="${item.dict || []}" prop="${field}" />\n</cl-filter>`
: ""; : "";
}); })
.join("\n");
// 关键字搜索 // 关键字搜索
const clSearchKeyPlaceholder = keyWordLikeFields const clSearchKeyPlaceholder = keyWordLikeFields
.map((field) => { .map((field) => {
return table.columns.find((e) => e.propertyName == field)?.label; return table.columns.find((e) => e.prop == field)?.label;
}) })
.filter((e) => !!e) .filter((e) => !!e)
.join("、"); .join("、");

View File

@ -292,7 +292,7 @@ import * as monaco from "monaco-editor";
import { sleep, storage } from "/@/cool/utils"; import { sleep, storage } from "/@/cool/utils";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { nextTick } from "vue"; import { nextTick } from "vue";
import type { CodeItem } from "../types"; import type { CodeItem, EpsColumn } from "../types";
import { useClipboard } from "@vueuse/core"; import { useClipboard } from "@vueuse/core";
const { service, refs, setRefs, router } = useCool(); const { service, refs, setRefs, router } = useCool();
@ -323,7 +323,7 @@ const form = reactive({
// //
const step = reactive({ const step = reactive({
loading: false, loading: false,
value: "start", value: "coding",
list: ["start", "enter", "form", "coding"], list: ["start", "enter", "form", "coding"],
async next() { async next() {
@ -381,10 +381,42 @@ const code = reactive({
active: "node-entity", active: "node-entity",
// //
list: (storage.get("ai-code.list") || []) as CodeItem[], list: [] as CodeItem[],
// //
data: (storage.get("ai-code.data") || {}) as any, data: {
router: "",
prefix: "",
columns: [] as EpsColumn[],
fieldEq: [],
keyWordLikeFields: [],
api: [
{
path: "/add",
summary: "新增"
},
{
path: "/info",
summary: "单个信息"
},
{
path: "/update",
summary: "修改"
},
{
path: "/delete",
summary: "删除"
},
{
path: "/page",
summary: "分页查询"
},
{
path: "/list",
summary: "列表查询"
}
]
},
// //
logs: [] as any[], logs: [] as any[],
@ -462,11 +494,16 @@ const code = reactive({
// entity // entity
const entityData = await ai.invokeFlow("comm-parse-entity", { const entityData = await ai.invokeFlow("comm-parse-entity", {
entity entity,
module: form.module
}); });
code.tips(`Entity 解析成功,${JSON.stringify(entityData)}`); code.tips(`Entity 解析成功,${JSON.stringify(entityData)}`);
code.data.router = entityData.path.replace("/admin", "");
code.data.prefix = entityData.path;
code.data.columns = entityData.columns || [];
code.tips("Service 代码生成中"); code.tips("Service 代码生成中");
// service // service
@ -487,14 +524,24 @@ const code = reactive({
code.tips("Controller 代码生成中"); code.tips("Controller 代码生成中");
// controller // controller
await code.setContent("Controller 控制器", "node-controller", { const controller = await code.setContent("Controller 控制器", "node-controller", {
...serviceData, ...serviceData,
...entityData, ...entityData,
service, service,
entity entity
}); });
code.tips("Controller 生成成功"); code.tips("Controller 生成成功,开始解析");
// controller
const controllerData = await ai.invokeFlow("comm-parse-controller", {
controller
});
code.tips(`Controller 解析成功,${JSON.stringify(controllerData)}`);
code.data.fieldEq = controllerData.fieldEq;
code.data.keyWordLikeFields = controllerData.keyWordLikeFields;
await code.createVue(); await code.createVue();
@ -519,65 +566,26 @@ const code = reactive({
item.content = ""; item.content = "";
code.data = { assign(code.data, form);
router: "",
prefix: "",
path: "",
fileName: "",
className: "",
columns: [],
api: [
{
path: "/add",
summary: "新增"
},
{
path: "/info",
summary: "单个信息"
},
{
path: "/update",
summary: "修改"
},
{
path: "/delete",
summary: "删除"
},
{
path: "/page",
summary: "分页查询"
},
{
path: "/list",
summary: "列表查询"
}
],
...form,
name: form.entity
};
code.tips("Vue 代码生成中"); code.tips("Vue 代码生成中");
// // ai
await service.base.sys.menu await ai
.parse({ .invokeFlow("comm-parse-column", {
module: form.module,
entity: code.getContent("node-entity") entity: code.getContent("node-entity")
}) })
.then((res) => { .then((res) => {
res.router = res.path.replace("/admin", ""); (code.data.columns as EpsColumn[]).forEach((e) => {
res.prefix = res.path; e.component = res[e.propertyName];
});
assign(code.data, res);
}); });
code.tips("AI 分析字段中");
// ai
await ai.matchType({ columns: code.data.columns, name: form.entity });
// //
item.content = menu.createVue(code.data); item.content = menu.createVue({
...code.data,
module: form.module
});
await sleep(300); await sleep(300);
@ -664,15 +672,15 @@ const code = reactive({
if (flow == code.active) { if (flow == code.active) {
refs.editor?.revealLine(99999); refs.editor?.revealLine(99999);
} }
}, 10); }, 5);
}); });
}, },
// //
copy() { copy() {
copy(code.getContent(code.active)!); copy(code.getContent(code.active)!);
code.save();
ElMessage.success("复制成功"); ElMessage.success("复制成功");
code.save();
}, },
// //
@ -686,6 +694,7 @@ const code = reactive({
save() { save() {
storage.set("ai-code.list", code.list); storage.set("ai-code.list", code.list);
storage.set("ai-code.data", code.data); storage.set("ai-code.data", code.data);
storage.set("ai-code.form", form);
} }
}); });
@ -908,6 +917,12 @@ function toBack() {
onMounted(() => { onMounted(() => {
desc.init(); desc.init();
if (step.value == "coding") {
code.list = storage.get("ai-code.list") || [];
code.data = storage.get("ai-code.data") || [];
assign(form, storage.get("ai-code.form") || {});
}
}); });
</script> </script>

View File

@ -1,11 +1,11 @@
import type { Merge, ModuleConfig } from "/@/cool"; import type { Merge, ModuleConfig } from "/@/cool";
// npm // npm
import Crud, { locale, setFocus } from "@cool-vue/crud"; // import Crud, { locale, setFocus } from "@cool-vue/crud";
import "@cool-vue/crud/dist/index.css"; import "@cool-vue/crud/dist/index.css";
// 调试、自定义crud // 调试、自定义crud
// import Crud, { locale, setFocus } from "/~/crud/src"; import Crud, { locale, setFocus } from "/~/crud/src";
// import "/~/crud/src/static/index.scss"; // import "/~/crud/src/static/index.scss";
export default (): Merge<ModuleConfig, CrudOptions> => { export default (): Merge<ModuleConfig, CrudOptions> => {