master 4c2e99a0c8b4 cached
628 files
756.5 KB
258.9k tokens
264 symbols
1 requests
Download .txt
Showing preview only (943K chars total). Download the full file or copy to clipboard to get everything.
Repository: lowcode-scaffold/lowcode-materials
Branch: master
Commit: 4c2e99a0c8b4
Files: 628
Total size: 756.5 KB

Directory structure:
gitextract_0an204y0/

├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── README.md
├── buildMaterials.js
├── llm/
│   └── index.js
├── lowcode-context.d.ts
├── materials/
│   ├── blocks/
│   │   ├── antdv2 增删改查列表页/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── ModifyModal/
│   │   │       │   ├── index.vue.ejs
│   │   │       │   ├── model.ts.ejs
│   │   │       │   ├── presenter.ts.ejs
│   │   │       │   └── service.ts.ejs
│   │   │       ├── api.ts.ejs
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       ├── service.ts.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       └── temp.mock.type.ejs
│   │   ├── react-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.tsx.ejs
│   │   │       └── service.ts.ejs
│   │   ├── taro-request/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── config.ts.ejs
│   │   │       ├── index.ts.ejs
│   │   │       └── interceptors.ts.ejs
│   │   ├── vant 表单/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   └── index.js
│   │   │   └── src/
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.tsx.ejs
│   │   │       └── service.ts.ejs
│   │   ├── vue-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       └── service.ts.ejs
│   │   ├── vue2-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       └── service.ts.ejs
│   │   ├── 测试使用 jsx 作为模版引擎/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   ├── schema.ts
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── ModifyModal/
│   │   │       │   ├── index.vue.ejs
│   │   │       │   ├── model.ts.ejs
│   │   │       │   ├── presenter.tsx.ejs
│   │   │       │   └── service.ts.ejs
│   │   │       ├── api.ts.ejs
│   │   │       ├── api.ts.template.tsx
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.template.tsx
│   │   │       ├── presenter.tsx.ejs
│   │   │       ├── service.ts.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       └── temp.mock.type.ejs
│   │   ├── 测试脚本/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       └── README.md
│   │   ├── 现有模块中添加 antdv Descriptions 描述列表/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Form 垂直布局列表/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Form 表单/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       ├── temp.presenter.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Modal 弹框/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.presenter.ts.ejs
│   │   ├── 现有模块中添加 antdv Table 表格/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       ├── temp.presenter.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 通过 ast 给 antdv Descriptions 描述列表添加字段/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       └── README.md
│   │   └── 通过脚本启动一个 nest api 服务/
│   │       ├── config/
│   │       │   ├── model.json
│   │       │   ├── preview.json
│   │       │   ├── schema.json
│   │       │   └── viewPrompt.ejs
│   │       ├── script/
│   │       │   ├── index.js
│   │       │   └── src/
│   │       │       ├── app.controller.ts
│   │       │       ├── app.module.ts
│   │       │       ├── app.service.ts
│   │       │       ├── context.ts
│   │       │       └── main.ts
│   │       └── src/
│   │           └── README.md
│   └── snippets/
│       ├── OCR/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── OCR + ChatGPT 翻译/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── Pro Chat/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── Pro Chat + Tldraw/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── Pro Chat + TypeChat/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── amis/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request-api-外挂脚本/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── genCode/
│       │   │       │   └── genCodeByYapi.ts
│       │   │       ├── main.ts
│       │   │       └── utils/
│       │   │           ├── config.ts
│       │   │           ├── editor.ts
│       │   │           ├── ejs.ts
│       │   │           ├── file.ts
│       │   │           ├── json.ts
│       │   │           ├── material.ts
│       │   │           └── request.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── form-render/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── formily/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── share ChatGPT 测试/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── start nest api server/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── app.controller.ts
│       │   │       ├── app.module.ts
│       │   │       ├── app.service.ts
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── taro-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── umi-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 动态表单 demo/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── controller.ts
│       │   │       ├── main.ts
│       │   │       └── routes.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 当前目录翻译成英文/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 快速创建区块/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       ├── lowcode/
│       │       │   └── 代码片段/
│       │       │       ├── config/
│       │       │       │   ├── commandPrompt.ejs.ejs
│       │       │       │   ├── model.json
│       │       │       │   ├── preview.json
│       │       │       │   └── schema.json
│       │       │       ├── script/
│       │       │       │   ├── index.js.ejs
│       │       │       │   └── src/
│       │       │       │       ├── context.ts.ejs
│       │       │       │       └── main.ts.ejs
│       │       │       └── src/
│       │       │           └── template.ejs.ejs
│       │       ├── uTools askChatGPT/
│       │       │   └── script/
│       │       │       ├── index.ts.ejs
│       │       │       └── src/
│       │       │           └── main.ts.ejs
│       │       ├── uTools 动态表单/
│       │       │   ├── config/
│       │       │   │   ├── config.json
│       │       │   │   ├── model.json
│       │       │   │   ├── schema.json
│       │       │   │   └── schema.ts
│       │       │   ├── script/
│       │       │   │   ├── index.ts.ejs
│       │       │   │   └── src/
│       │       │   │       ├── controller.ts.ejs
│       │       │   │       └── main.ts.ejs
│       │       │   └── src/
│       │       │       ├── api.ts.keep.ejs
│       │       │       ├── index.vue.keep.ejs
│       │       │       ├── model.ts.keep.ejs
│       │       │       ├── presenter.ts.keep.ejs
│       │       │       ├── service.ts.keep.ejs
│       │       │       ├── temp.mock.script
│       │       │       └── temp.mock.type.keep.ejs
│       │       ├── uTools 自动化脚本/
│       │       │   └── script/
│       │       │       ├── index.ts.ejs
│       │       │       └── src/
│       │       │           └── main.ts.ejs
│       │       └── uniapp/
│       │           ├── vue3-mvp/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           ├── vue3-mvp emit/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           ├── vue3-mvp props/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           └── vue3-mvp props emit/
│       │               ├── index.scss.ejs
│       │               ├── index.vue.ejs
│       │               ├── model.ts
│       │               ├── presenter.ts
│       │               └── service.ts
│       ├── 打开webview/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── 根据 DevOps 需求标题创建 GIT commit - 截图/
│       │   ├── config/
│       │   │   └── preview.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/
│       │   ├── config/
│       │   │   ├── preview.json
│       │   │   └── schema.ts
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 根据JSON生成API请求方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成MOCK方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型-去除接口名称/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型-将中文字段翻译成英文/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成API请求方法/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成MOCK方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成markdown表格/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据YAPI接口定义生成高级Mock脚本/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 测试 JSONSchemaChat/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── validSchema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 测试脚本/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 生成 value-label 格式 JSON/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 翻译成驼峰格式/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 自动保存活动窗口/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 获取当前用户最近一次 Git Commit 信息/
│       │   ├── config/
│       │   │   └── preview.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 设置配置信息/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── controller.ts
│       │   │       ├── main.ts
│       │   │       └── routes.ts
│       │   └── src/
│       │       └── template.ejs
│       └── 通过 TS 类型做字段映射/
│           ├── config/
│           │   ├── model.json
│           │   ├── preview.json
│           │   └── schema.json
│           ├── script/
│           │   ├── index.js
│           │   └── src/
│           │       ├── context.ts
│           │       ├── controller.ts
│           │       ├── main.ts
│           │       └── routes.ts
│           └── src/
│               └── template.ejs
├── package.json
├── scripts/
│   └── ClipboardImage/
│       ├── linux.sh
│       ├── mac.applescript
│       └── pc.ps1
├── share/
│   ├── BaiduOCR/
│   │   ├── index.ts
│   │   └── request.ts
│   ├── JSONSchemaChat/
│   │   ├── index.ts
│   │   └── result.ts
│   ├── LLM/
│   │   ├── gemini.ts
│   │   ├── geminiProxy.ts
│   │   ├── index.ts
│   │   ├── openai.ts
│   │   └── openaiV2.ts
│   ├── TypeChatSlim/
│   │   ├── index.ts
│   │   ├── result.ts
│   │   └── utools.ts
│   ├── WebView/
│   │   ├── callback.ts
│   │   ├── controllers/
│   │   │   ├── alert.ts
│   │   │   ├── dynamicForm.ts
│   │   │   ├── llm.ts
│   │   │   ├── script.ts
│   │   │   └── task.ts
│   │   ├── index.ts
│   │   ├── routes/
│   │   │   └── index.ts
│   │   └── type.ts
│   ├── clearCache.ts
│   ├── uTools/
│   │   └── webviewBaseController.ts
│   └── utils/
│       ├── clipboardImage.ts
│       ├── config.ts
│       ├── dynamicForm.ts
│       ├── editor.ts
│       ├── ejs.ts
│       ├── emitter.ts
│       ├── file.ts
│       ├── json.ts
│       ├── lint.ts
│       ├── material.ts
│       ├── platformIndependent/
│       │   └── json.ts
│       ├── shareData.ts
│       ├── tsx.ts
│       └── uTools.ts
├── tsconfig.compiler.json
├── tsconfig.json
├── uTools/
│   ├── Ask ChatGPT/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON/
│   │   ├── config/
│   │   │   ├── schema.ts
│   │   │   └── template.ejs
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON - Form/
│   │   ├── config/
│   │   │   ├── schema.ts
│   │   │   └── template.ejs
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON - Prompt/
│   │   ├── config/
│   │   │   └── schema.ts
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Gemini/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Groq/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Kimi/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Perplexity/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Chat With Form Demo/
│   │   ├── config/
│   │   │   ├── config.json
│   │   │   ├── model.json
│   │   │   └── schema.json
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           ├── controller.ts
│   │           └── main.ts
│   ├── Git 获取当前用户最近一次 Commit 信息/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open ChatGPT/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open ChatGPT-获取命令行命令/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open Tldraw/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── TS 类型新增字段 - 根据 YAPI 文档字段格式/
│   │   ├── prompt.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── TS 类型新增字段 - 根据 YAPI 文档字段格式 - 截图/
│   │   ├── README.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── vscode 选中的文件夹/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 中文翻译英文/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 动态表单 demo/
│   │   ├── config/
│   │   │   ├── config.json
│   │   │   ├── model.json
│   │   │   ├── schema.json
│   │   │   └── schema.ts
│   │   ├── script/
│   │   │   ├── index.ts
│   │   │   └── src/
│   │   │       ├── controller.ts
│   │   │       └── main.ts
│   │   └── src/
│   │       ├── api.ts.ejs
│   │       ├── index.vue.ejs
│   │       ├── model.ts.ejs
│   │       ├── presenter.ts.ejs
│   │       ├── service.ts.ejs
│   │       ├── temp.mock.script
│   │       └── temp.mock.type.ejs
│   ├── 截屏并转base64/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT commit - 截图/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/
│   │   ├── config/
│   │   │   └── schema.ts
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据当前分支名称创建 GIT commit/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 翻译为驼峰格式-首字母大写/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 翻译为驼峰格式-首字母小写/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 英文翻译中文/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 英文:中文格式的描述转 TS 类型/
│   │   ├── README.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 获取命令行命令/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   └── 设置配置信息/
│       └── script/
│           ├── index.ts
│           └── src/
│               └── main.ts
├── uTools.js
└── uToolsUpload.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintignore
================================================
dist
gemini.js
geminiProxy.js

================================================
FILE: .eslintrc.js
================================================
module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'airbnb-base',
    'prettier',
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  parser: '@typescript-eslint/parser',
  plugins: ['prettier', '@typescript-eslint'],
  parserOptions: {
    ecmaVersion: 12,
  },
  rules: {
    'prettier/prettier': 'error',
    'func-names': 'off',
    'import/prefer-default-export': 'off',
    'no-plusplus': 'off',
    'no-unused-vars': 'off',
    '@typescript-eslint/no-var-requires': 'off',
    '@typescript-eslint/no-unused-vars': 'off',
    'max-classes-per-file': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'class-methods-use-this': 'off',
    '@typescript-eslint/ban-ts-comment': 'off',
    'import/no-unresolved': 'off',
    'no-useless-constructor': 'off',
    'no-empty-function': 'off',
    'import/extensions': 'off',
    'consistent-return': 'off',
    'no-use-before-define': 'off',
    'array-callback-return': 'off',
    'no-param-reassign': 'off',
    'no-new-func': 'off',
    'no-empty': 'off',
    'import/no-dynamic-require': 'off',
    'global-require': 'off',
    'import/no-extraneous-dependencies': 'off',
    'no-template-curly-in-string': 'off',
    'arrow-body-style': 'off',
    'prefer-promise-reject-errors': 'off',
  },
};


================================================
FILE: .gitattributes
================================================
*.ejs linguist-language=TypeScript

================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
.ts-node
.lowcoderc
dist

================================================
FILE: .npmrc
================================================
electron_mirror=https://npmmirror.com/mirrors/electron/

================================================
FILE: .prettierignore
================================================
.ejs
dist

================================================
FILE: .prettierrc.js
================================================
module.exports = {
  trailingComma: 'all',
  tabWidth: 2,
  semi: true,
  singleQuote: true,
  endOfLine: 'auto',
};


================================================
FILE: README.md
================================================
将项目 clone 到本地,安装依赖,执行 yarn build

## 使用 VSCODE

安装 [lowcode](https://marketplace.visualstudio.com/items?itemName=wjkang.lowcode) 插件

设置同步目录为 clone 项目的目录

![](https://github.com/user-attachments/assets/979aefca-445b-4805-98e8-5224f9a06067)

![](https://github.com/user-attachments/assets/01f4684d-3cc5-496d-adce-91a345c8a4c8)

vscode 执行如下命令

![](https://github.com/user-attachments/assets/3563be5f-322d-429a-b3d7-44be3d380fbe)

出现如下选项,配置成功

![](https://github.com/user-attachments/assets/266b876a-bae9-409a-bbb9-f01dbd8c0637)

快速创建区块

![](https://github.com/user-attachments/assets/cacc892a-0834-4899-a766-f6e090abe302)



以同步目录设置的代码模版和区块在所有项目里都可见,代码逻辑可以自由修改,不过分依赖 lowcode 插件内部,比如上面快速创建区块的代码: https://github.com/lowcode-scaffold/lowcode-materials/blob/master/materials/snippets/%E5%BF%AB%E9%80%9F%E5%88%9B%E5%BB%BA%E5%8C%BA%E5%9D%97/script/src/main.ts

### 支持其它 LLM

只要实现了 `llm/index.js` 中的 `createChatCompletion` 的方法,lowcode 插件内部的 ChatGPT 请求将会转为使用这个方法。不存在这个文件或者没有  `createChatCompletion` 方法会继续使用内部 ChatGPT 请求。https://github.com/lowcode-scaffold/lowcode-materials/blob/master/llm/index.js

如果使用的 LLM 兼容 openai 的数据格式,直接通过可视化界面进行配置

![image](https://github.com/user-attachments/assets/c115b70c-68f8-4479-96f4-495d4d0a1275)

![image](https://github.com/user-attachments/assets/cfa2b61b-e462-40a5-aadd-710adec15b8a)

![image](https://github.com/user-attachments/assets/5eb13ef1-150b-450c-9b53-018cbbdf59a1)


## 使用 uTools

### uTools 自动化脚本

安装依赖后执行 yarn build,uTools 中安装自动化脚本插件,新建脚本,把 dist/utools 目录下的各个 index.js 内容复制过去就行。

![image](https://github.com/user-attachments/assets/ee3cd944-850b-478b-b1e7-03fa8a79d3a2)

![image](https://github.com/user-attachments/assets/3b307be1-70ab-4524-9a2d-9b19419965a4)


部分脚本需要配合插件使用,插件下载:[lowcode-1.0.0.upxs](https://github.com/lowcode-scaffold/lowcode-materials/releases)


一个生成特定代码的例子:

![](https://github.com/user-attachments/assets/ebd19d40-1f92-49d3-ab13-aa7272ff04f9)

![](https://github.com/user-attachments/assets/b0a4e635-08cf-4e09-8469-6d73c76c17d3)



================================================
FILE: buildMaterials.js
================================================
const path = require('path');
const fs = require('fs-extra');
/**
 * @description
 * @param {string} dirPath
 * @return {string[]}
 */
function getAllFiles(dirPath) {
  const files = fs.readdirSync(dirPath);

  let result = [];

  // eslint-disable-next-line no-restricted-syntax
  for (const file of files) {
    const filePath = `${dirPath}/${file}`;
    // eslint-disable-next-line no-await-in-loop
    const stats = fs.statSync(filePath);

    if (stats.isDirectory()) {
      result = result.concat(getAllFiles(filePath));
    } else {
      result.push(filePath);
    }
  }

  return result;
}

const devContent = `
require('ts-node').register({
  transpileOnly: true,
  typeCheck: false,
  emit: false,
  compilerHost: false, // 和 emit 一起设置为 true,会在 .ts-node 文件夹输出编译后的代码
  cwd: __dirname, // 要输出编译后代码必须配置,否则会报错 EROFS: read-only file system, mkdir '/.ts-node'。不输出也要配置不然会出现各种奇奇怪怪的报错
});
// 清除缓存,保证每次修改代码后实时生效,否则要重新打开 vscode
const { clearCache } = require('../../../../share/clearCache.ts');

clearCache(__dirname); // 调试的时候才打开,不然会很慢
const main = require('./src/main.ts');
const { context } = require('./src/context.ts');

`;

const mode = process.argv[2] || 'prod';

fs.removeSync(path.join(__dirname, 'dist'));

getAllFiles(path.join(__dirname, 'materials'))
  .filter((s) => s.includes('script/index.js') && !s.includes('.ejs'))
  .forEach((file) => {
    const materialName = file
      .replace(/\\/g, '/')
      .replace(`${__dirname.replace(/\\/g, '/')}/materials/`, '')
      .replace('/script/index.js', '');
    const prodContent = `
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/${materialName}/script/src/main');
const {
  context,
} = require('../../../../dist/materials/${materialName}/script/src/context');

`;
    const content = fs.readFileSync(file).toString();
    const exportContent = `module.exports${content.split('module.exports')[1]}`;
    if (mode === 'prod') {
      fs.writeFileSync(file, prodContent.trimStart() + exportContent);
    } else {
      fs.writeFileSync(file, devContent.trimStart() + exportContent);
    }
  });


================================================
FILE: llm/index.js
================================================
const vscode = require('vscode');
const gemini = require('../dist/share/LLM/gemini');
const geminiProxy = require('../dist/share/LLM/geminiProxy');
const openai = require('../dist/share/LLM/openai');
const share = require('../dist/share/utils/shareData');

const GeminiKey = 'lowcode.GeminiKey';
const OpenaiKey = 'lowcode.OpenaiKey';

module.exports = {
  /**
   * @description 替换 lowcode 插件内部的 ChatGPT 请求,修改后需要重启对应项目 vscode
   * @param {({
   *   messages: { role: 'system' | 'user' | 'assistant'; content: string }[];
   *   handleChunk?: (data: { text?: string; }) => void;
   *   lowcodeContext: { env: { extensionContext:  any }};
   * })} options
   * @returns {Promise<string>}
   */
  createChatCompletion: async (options) => {
    const context = options.lowcodeContext.env.extensionContext;
    // await context.secrets.delete(GeminiKey); // 需要更新 API KEY 的时候打开
    // let apiKey = await context.secrets.get(GeminiKey);
    // if (!apiKey) {
    //   vscode.window.showWarningMessage(
    //     'Enter your API KEY to save it securely.',
    //   );
    //   apiKey = await setApiKey(context, GeminiKey);
    //   if (!apiKey) {
    //     if (options.handleChunk) {
    //       options.handleChunk({ text: 'Please enter your api key' });
    //     }
    //     return 'Please enter your api key';
    //   }
    // }
    // const res = await gemini.createChatCompletion({
    //   messages: options.messages,
    //   model: 'gemini-pro',
    //   apiKey,
    //   handleChunk(data) {
    //     if (options.handleChunk) {
    //       options.handleChunk(data);
    //     }
    //   },
    //   proxyUrl: 'http://127.0.0.1:7890',
    // });
    // return res;
    // const res = await geminiProxy.createChatCompletion({
    //   messages: options.messages,
    //   model: 'gemini-pro',
    //   maxTokens: '4096',
    //   handleChunk(data) {
    //     if (options.handleChunk) {
    //       options.handleChunk(data);
    //     }
    //   },
    // });
    // return res;

    // await context.secrets.delete(OpenaiKey); // 需要更新 API KEY 的时候打开
    // let apiKey = await context.secrets.get(OpenaiKey);
    // if (!apiKey) {
    //   vscode.window.showWarningMessage(
    //     'Enter your API KEY to save it securely.',
    //   );
    //   apiKey = await setApiKey(context, OpenaiKey);
    //   if (!apiKey) {
    //     if (options.handleChunk) {
    //       options.handleChunk({ text: 'Please enter your api key' });
    //     }
    //     return 'Please enter your api key';
    //   }
    // }
    const config = share.oneAPIConfig() || {};
    const res = await openai.createChatCompletion({
      messages: options.messages,
      hostname: config.hostname,
      model: config.model,
      apiKey: config.apiKey,
      notHttps: config.notHttps,
      apiPath: config.apiPath,
      port: config.port,
      handleChunk(data) {
        if (options.handleChunk) {
          options.handleChunk(data);
        }
      },
    });
    return res;
  },
};


================================================
FILE: lowcode-context.d.ts
================================================
import type vscode from 'vscode';

interface Context {
  /**
   * @description 模版数据
   * @type {object}
   */
  model: object;
  /**
   * @description vscode 对象,能调用 vscode 提供的 api
   * @type {typeof vscode}
   */
  vscode: typeof vscode;
  /**
   * @description 调用脚本的工作目录,不一定是脚本所在的项目目录
   * @type {string}
   */
  workspaceRootPath: string;
  /**
   * @description 区块生成目录
   * @type {string}
   */
  createBlockPath?: string;
  /**
   * @description OutputChannel
   * @type {vscode.OutputChannel}
   */
  outputChannel: vscode.OutputChannel;
  /**
   * @description log
   * @type {vscode.OutputChannel}
   */
  log: vscode.OutputChannel;
  /**
   * @description 调用 ChatGPT
   */
  createChatCompletion: (options: {
    messages: {
      role: 'system' | 'user' | 'assistant';
      content: string;
    }[];
    handleChunk?: ((data: { text?: string }) => void) | undefined;
    showWebview?: boolean;
  }) => Promise<string>;
  /**
   * @description 当前选择的物料路径(加上物料名称)
   * @type {string}
   */
  materialPath: string;
  /**
   * @description 一些环境变量
   */
  env: {
    /**
     * @description 等于 workspaceRootPath
     * @type {string}
     */
    rootPath: string;
    /**
     * @description 临时工作目录
     * @type {string}
     */
    tempWorkPath: string;
    /**
     * @description 物料路径
     * @type {string}
     */
    materialsPath: string;
    /**
     * @description 区块路径
     * @type {string}
     */
    blockMaterialsPath: string;
    /**
     * @description 代码片段路径
     * @type {string}
     */
    snippetMaterialsPath: string;
    /**
     * @description 私有物料路径
     * @type {string}
     */
    privateMaterialsPath: string;
    /**
     * @description ExtensionContext
     * @type {vscode.ExtensionContext}
     */
    extensionContext: vscode.ExtensionContext;
  };
  /**
   * @description lwocode 插件内部使用的一些库,暴露出来避免重复安装
   */
  libs: {
    /**
     * @description axios
     * @type {*}
     */
    axios: any;
    /**
     * @description copy-paste
     * @type {*}
     */
    copyPaste: any;
    /**
     * @description directory-tree
     * @type {*}
     */
    dirTree: any;
    /**
     * @description ejs
     * @type {*}
     */
    ejs: any;
    /**
     * @description fs-extra
     * @type {*}
     */
    fsExtra: any;
    /**
     * @description execa
     * @type {*}
     */
    execa: any;
    /**
     * @description glob
     * @type {*}
     */
    glob: any;
    /**
     * @description prettier
     * @type {*}
     */
    prettier: any;
    /**
     * @description strip-comments
     * @type {*}
     */
    stripComments: any;
    /**
     * @description strip-json-comments
     * @type {*}
     */
    stripJsonComments: any;
    /**
     * @description generate-schema
     * @type {*}
     */
    generateSchema: any;
    /**
     * @description json-schema-to-typescript
     * @type {*}
     */
    jsonSchemaToTypescript: any;
    /**
     * @description typescript-json-schema
     * @type {*}
     */
    typescriptJsonSchema: any;
    /**
     * @description axios
     * @type {*}
     */
    tar: any;
  };

  /**
   * 剪贴板的图片,执行脚本弹框里点击确定按钮的时候获取的,不通过 webview 获取不到
   */
  clipboardImage?: string;
  /**
   * 打开 webview 获取剪贴板里的图片,base64 格式
   */
  getClipboardImage: () => Promise<string | undefined>;
  /**
   * @description 最后一次激活的 TextEditor
   */
  activeTextEditor?: vscode.TextEditor;
}
export interface CompileContext extends Context {
  /**
   * @description 代码片段编译后的代码
   * @type {string}
   */
  code: string;
  /**
   * @description 执行右键菜单时选中的文件夹
   * @type {string}
   */
  explorerSelectedPath: string;
  /** 脚本方法名,runScript 方法才有 */
  method: string;
  /** 脚本方法名,runScript 方法才有 */
  script: string;
  /** 脚本方法参数,runScript 方法才有 */
  params: string;
}

export interface ViewCallContext extends Context {
  /**
   * @description 传入的方法参数
   * @type {string}
   */
  params: string;
}


================================================
FILE: materials/blocks/antdv2 增删改查列表页/config/model.json
================================================
{
  "filters": [],
  "columns": [],
  "pagination": {
    "show": true,
    "page": "page",
    "size": "size",
    "total": "result.total"
  },
  "includeModifyModal": false,
  "fetchName": "fetchTableList",
  "result": "[\"result\"][\"records\"]",
  "serviceName": "getTableList"
}

================================================
FILE: materials/blocks/antdv2 增删改查列表页/config/preview.json
================================================
{
	"title": "",
	"description": "",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [],
	"schema": "amis",
	"scripts": [
		{
			"method": "OCR",
			"remark": "OCR 识别剪贴版截图"
		},
		{
			"method": "initFiltersFromImage",
			"remark": "使用截图初始化查询条件"
		},
		{
			"method": "initFiltersFromText",
			"remark": "使用文本初始化查询条件"
		},
		{
			"method": "initColumnsFromText",
			"remark": "使用文本初始化表格"
		},
		{
			"method": "initColumnsFromImage",
			"remark": "使用截图初始化表格"
		},
		{
			"method": "askChatGPT",
			"remark": "使用 ChatGPT 翻译模版数据里的指定中文字段"
		}
	]
}

================================================
FILE: materials/blocks/antdv2 增删改查列表页/config/schema.json
================================================
{
	"formSchema": {
		"schema": {
			"type": "page",
			"body": [
				{
					"type": "form",
					"title": "",
					"body": [
						{
							"type": "combo",
							"label": "查询条件",
							"name": "filters",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "icon",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:47ecb9e15ff1"
							},
							"items": [
								{
									"type": "input-text",
									"name": "key",
									"placeholder": "字段名",
									"id": "u:25b0c7b5e5a0",
									"label": "字段名(key)"
								},
								{
									"type": "input-text",
									"label": "label",
									"name": "label",
									"id": "u:6496cac4f4b8",
									"description": ""
								},
								{
									"type": "select",
									"name": "component",
									"placeholder": "选项",
									"options": [
										{
											"label": "input",
											"value": "input"
										},
										{
											"label": "select",
											"value": "select"
										},
										{
											"label": "range-picker",
											"value": "range-picker"
										}
									],
									"id": "u:995915eabcca",
									"multiple": false,
									"label": "组件",
									"value": ""
								},
								{
									"type": "switch",
									"label": "后端接口查询",
									"option": "",
									"name": "remoteFetch",
									"falseValue": false,
									"trueValue": true,
									"id": "u:3a46d16f89c9",
									"value": false,
									"visibleOn": "${filters[index].component==='select'}"
								},
								{
									"type": "input-text",
									"label": "placeholder",
									"name": "placeholder",
									"id": "u:d7f1a8a39449",
									"description": "",
									"visibleOn": "${filters[index].component==='select'||filters[index].component==='input'}"
								}
							],
							"id": "u:186f183e9320",
							"strictMode": false,
							"syncFields": [],
							"tabsMode": true,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"tabsLabelTpl": "表单项${index+1}",
							"multiLine": true,
							"noBorder": false
						},
						{
							"type": "combo",
							"label": "表格",
							"name": "columns",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "button",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:1e8070edc3d3"
							},
							"items": [
								{
									"type": "input-text",
									"name": "title",
									"id": "u:152dd82b82f9",
									"label": "title"
								},
								{
									"type": "input-text",
									"label": "dataIndex",
									"name": "dataIndex",
									"id": "u:ecc7298e0550",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "key",
									"name": "key",
									"id": "u:fbaa95c3f15d",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "width",
									"name": "width",
									"id": "u:b143127e097b",
									"description": ""
								},
								{
									"type": "switch",
									"label": "自定义插槽",
									"option": "",
									"name": "slot",
									"falseValue": false,
									"trueValue": true,
									"id": "u:ee1ce1faee0b",
									"value": false
								}
							],
							"id": "u:9b9fb0cf38f9",
							"strictMode": true,
							"syncFields": [],
							"tabsMode": true,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"deleteBtn": {
								"label": "删除",
								"level": "default"
							},
							"tabsLabelTpl": "列${index+1}"
						},
						{
							"type": "fieldset",
							"title": "分页参数",
							"collapsable": true,
							"body": [
								{
									"type": "switch",
									"label": "是否分页",
									"option": "",
									"name": "pagination.show",
									"falseValue": false,
									"trueValue": true,
									"id": "u:6c70041d5143",
									"value": true,
									"className": ""
								},
								{
									"type": "input-text",
									"label": "查询接口页数参数字段名",
									"name": "pagination.page",
									"id": "u:cbbf6853cf64",
									"value": "page"
								},
								{
									"type": "input-text",
									"label": "查询接口每页数据行数参数字段名",
									"name": "pagination.size",
									"id": "u:a8fae66fa927",
									"value": "size"
								},
								{
									"type": "input-text",
									"label": "接口返回总数据量字段 PATH",
									"name": "pagination.total",
									"id": "u:e1cd979c7ee8",
									"value": "result.total",
									"themeCss": {
										"inputControlClassName": {
											"padding-and-margin:default": {
												"marginBottom": "",
												"marginTop": "",
												"marginRight": "",
												"marginLeft": ""
											}
										}
									}
								}
							],
							"id": "u:0f1bd8fc2f2b",
							"collapsed": true,
							"headingClassName": "",
							"bodyClassName": "p"
						},
						{
							"type": "fieldset",
							"title": "请求方法",
							"collapsable": true,
							"body": [
								{
									"type": "input-text",
									"label": "请求名称",
									"name": "fetchName",
									"id": "u:a3e712484fae",
									"value": "fetchTableList",
									"description": "追加了YAPI数据则不使用此参数",
									"themeCss": {
										"labelClassName": {
											"padding-and-margin:default": {
												"marginTop": "",
												"marginRight": "",
												"marginBottom": "",
												"marginLeft": ""
											}
										}
									},
									"labelClassName": "labelClassName-a3e712484fae"
								},
								{
									"type": "input-text",
									"label": "接口数据字段 PATH",
									"name": "result",
									"id": "u:8c082acf7db2",
									"value": "[\"result\"][\"records\"]",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "service方法名",
									"name": "serviceName",
									"id": "u:cfbbdd07366b",
									"value": "getTableList",
									"description": ""
								}
							],
							"id": "u:382f8cdf59a6",
							"collapsed": true,
							"className": "",
							"headingClassName": "",
							"bodyClassName": "p-r p-l p-b"
						},
						{
							"type": "fieldset",
							"title": "新增/编辑弹框",
							"collapsable": true,
							"body": [
								{
									"type": "switch",
									"label": "是否包含弹框",
									"option": "",
									"name": "includeModifyModal",
									"falseValue": false,
									"trueValue": true,
									"id": "u:03957070af9e",
									"value": false
								},
								{
									"type": "combo",
									"label": "表单项",
									"name": "modifyModal.formItems",
									"multiple": true,
									"addable": true,
									"removable": true,
									"removableMode": "icon",
									"strictMode": false,
									"addBtn": {
										"label": "新增",
										"icon": "fa fa-plus",
										"level": "primary",
										"size": "sm",
										"id": "u:86cc27b6a663"
									},
									"items": [
										{
											"type": "input-text",
											"name": "key",
											"id": "u:62cc1cf36c73",
											"label": "字段名(key)"
										},
										{
											"type": "select",
											"name": "type",
											"options": [
												{
													"label": "string",
													"value": "string"
												},
												{
													"label": "number",
													"value": "number"
												},
												{
													"label": "boolean",
													"value": "boolean"
												},
												{
													"label": "Dayjs",
													"value": "Dayjs"
												},
												{
													"label": "string[]",
													"value": "string[]"
												},
												{
													"label": "number[]",
													"value": "number[]"
												},
												{
													"label": "boolean[]",
													"value": "boolean[]"
												},
												{
													"label": "[Dayjs,Dayjs]",
													"value": "[Dayjs,Dayjs]"
												}
											],
											"id": "u:b165c75e5e1a",
											"multiple": false,
											"label": "字段类型",
											"value": ""
										},
										{
											"type": "switch",
											"label": "字段可选",
											"option": "",
											"name": "optional",
											"falseValue": false,
											"trueValue": true,
											"id": "u:68fc4c85fb03",
											"value": false,
											"description": "字段名字后加?"
										},
										{
											"type": "select",
											"name": "defaultValue",
											"options": [
												{
													"label": "\"\"",
													"value": "\"\""
												},
												{
													"label": "false",
													"value": "false"
												},
												{
													"label": "true",
													"value": "true"
												},
												{
													"label": "0",
													"value": "0"
												},
												{
													"label": "undefined",
													"value": "undefined"
												},
												{
													"label": "[]",
													"value": "[]"
												}
											],
											"id": "u:379ea92fb3c6",
											"multiple": false,
											"label": "默认值",
											"value": ""
										},
										{
											"type": "select",
											"name": "component",
											"options": [
												{
													"label": "input",
													"value": "input"
												},
												{
													"label": "input-password",
													"value": "input-password"
												},
												{
													"label": "input-number",
													"value": "input-number"
												},
												{
													"label": "textarea",
													"value": "textarea"
												},
												{
													"label": "select",
													"value": "select"
												},
												{
													"label": "radio-group",
													"value": "radio-group"
												},
												{
													"label": "checkbox-group",
													"value": "checkbox-group"
												},
												{
													"label": "switch",
													"value": "switch"
												},
												{
													"label": "date-picker",
													"value": "date-picker"
												},
												{
													"label": "time-ticker",
													"value": "time-picker"
												},
												{
													"label": "range-picker",
													"value": "range-picker"
												},
												{
													"label": "transfer",
													"value": "transfer"
												}
											],
											"id": "u:7932ea3b05da",
											"multiple": false,
											"label": "组件",
											"value": ""
										},
										{
											"type": "input-text",
											"name": "label",
											"id": "u:5bb237f20098",
											"label": "label"
										},
										{
											"type": "input-text",
											"name": "placeholder",
											"id": "u:580898257491",
											"label": "placeholder"
										},
										{
											"type": "switch",
											"label": "required",
											"option": "",
											"name": "required",
											"falseValue": false,
											"trueValue": true,
											"id": "u:559dbdbb01da",
											"value": false,
											"description": "验证规则加required"
										},
										{
											"type": "input-text",
											"name": "message",
											"id": "u:55013279d659",
											"label": "校验失败 message",
											"value": "不能为空"
										},
										{
											"type": "switch",
											"label": "更多组件配置",
											"option": "",
											"name": "showMore",
											"falseValue": false,
											"trueValue": true,
											"id": "u:67e0cb5b7496",
											"value": false,
											"description": ""
										},
										{
											"type": "switch",
											"label": "labelInValue",
											"option": "",
											"name": "labelInValue",
											"falseValue": false,
											"trueValue": true,
											"id": "u:7fd6f1b233d9",
											"value": false,
											"description": "是否把每个选项的 label 包装到 value 中",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "select",
											"name": "mode",
											"options": [
												{
													"label": "multiple",
													"value": "multiple"
												},
												{
													"label": "tags",
													"value": "tags"
												}
											],
											"multiple": false,
											"label": "mode",
											"value": "",
											"description": "设置 Select 的模式为多选或标签",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "input-text",
											"name": "optionFilterProp",
											"label": "optionFilterProp",
											"description": "搜索时过滤对应的 option 属性",
											"value": "label",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "switch",
											"label": "showSearch",
											"option": "",
											"name": "showSearch",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "使单选模式可搜索",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "switch",
											"label": "hideArrow",
											"option": "",
											"name": "hideArrow",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否隐藏下拉小箭头",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "input-text",
											"name": "maxlength",
											"label": "maxlength",
											"description": "最大长度",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'input' && modifyModal.formItems[index].component !== 'input-password' && modifyModal.formItems[index].component !== 'textarea')}"
										},
										{
											"type": "switch",
											"label": "showCount",
											"option": "",
											"name": "showCount",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否展示字数",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'input' && modifyModal.formItems[index].component !== 'input-password' && modifyModal.formItems[index].component !== 'textarea')}"
										},
										{
											"type": "input-text",
											"name": "max",
											"label": "max",
											"description": "最大值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "min",
											"label": "min",
											"description": "最小值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "step",
											"label": "step",
											"description": "每次改变步数,可以为小数",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "checkedChildren",
											"label": "checkedChildren",
											"description": "选中时的内容",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "unCheckedChildren",
											"label": "unCheckedChildren",
											"description": "非选中时的内容",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "checkedValue",
											"label": "checkedValue",
											"description": "选中时的值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "unCheckedValue",
											"label": "unCheckedValue",
											"description": "非选中时的值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "select",
											"name": "picker",
											"options": [
												{
													"label": "date",
													"value": "date"
												},
												{
													"label": "week",
													"value": "week"
												},
												{
													"label": "month",
													"value": "month"
												},
												{
													"label": "quarter",
													"value": "quarter"
												},
												{
													"label": "year",
													"value": "year"
												}
											],
											"multiple": false,
											"label": "picker",
											"description": "设置选择器类型",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker')}"
										},
										{
											"type": "switch",
											"label": "showTime",
											"name": "showTime",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "增加时间选择功能",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										},
										{
											"type": "switch",
											"label": "showNow",
											"name": "showNow",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "当设定了 showTime 的时候,面板是否显示“此刻”按钮",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										},
										{
											"type": "switch",
											"label": "showToday",
											"name": "showToday",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否展示“今天”按钮",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										}
									],
									"syncFields": [],
									"tabsMode": true,
									"draggable": true,
									"draggableTip": "可拖动排序",
									"tabsStyle": "line",
									"tabsLabelTpl": "表单项${index+1}",
									"multiLine": true,
									"noBorder": false,
									"hiddenOn": "${!includeModifyModal}"
								}
							],
							"bodyClassName": "p",
							"collapsed": true
						}
					],
					"submitText": ""
				}
			],
			"pullRefresh": {
				"disabled": true
			},
			"regions": [
				"body"
			],
			"style": {
				"boxShadow": " 0px 0px 0px 0px transparent"
			},
			"asideResizor": false
		}
	},
	"conditionFiles": {
		"includeModifyModal": {
			"value": false,
			"exclude": [
				"/ModifyModal/index.vue.ejs",
				"/ModifyModal/model.ts.ejs",
				"/ModifyModal/presenter.tsx.ejs",
				"/ModifyModal/presenter.ts.ejs",
				"/ModifyModal/service.ts.ejs"
			]
		}
	},
	"excludeCompile": [
		"temp.mock.script.ejs"
	]
}

================================================
FILE: materials/blocks/antdv2 增删改查列表页/config/schema.ts
================================================
export type PageConfig = {
  filters: {
    component: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    key: string;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    label: string;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    placeholder: string;
  }[];
  columns: {
    slot: boolean;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    title: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    dataIndex: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    key: string;
  }[];
  pagination: {
    show: boolean;
    page: string;
    size: string;
    total: string;
  };
  includeModifyModal: boolean;
  fetchName: string;
  result: string;
  serviceName: string;
};


================================================
FILE: materials/blocks/antdv2 增删改查列表页/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/antdv2 增删改查列表页/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/antdv2 增删改查列表页/script/src/context');

module.exports = {
  beforeCompile: (lowcodeContext) => {},
  afterCompile: (lowcodeContext) => {
    lowcodeContext.outputChannel.appendLine(__dirname);
    lowcodeContext.outputChannel.appendLine(__filename);
    lowcodeContext.outputChannel.appendLine(process.cwd());
    lowcodeContext.outputChannel.appendLine(
      JSON.stringify(lowcodeContext.model),
    );
    if (!lowcodeContext.model.includeModifyModal) {
      // lowcodeContext.libs.fsExtra.removeSync(
      //   path.join(
      //     path.join(lowcodeContext.env.tempWorkPath, 'src', 'ModifyModal'),
      //   ),
      // );
    }
  },
  complete: (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    try {
      main.handleComplete();
    } catch (ex) {}
  },
  initFiltersFromImage: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleInitFiltersFromImage();
    return res;
  },
  initFiltersFromText: (lowcodeContext) => {
    let filters = lowcodeContext.params
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n');
    filters = filters.map((item) => {
      const s = item.replace(/:|:/g, ':').split(':');
      return {
        component: (s[1] || '').indexOf('选择') > -1 ? 'select' : 'input',
        key: s[0].trim(),
        label: s[0].trim(),
        placeholder: s[1] || '',
      };
    });
    return {
      updateModelImmediately: false,
      onlyUpdateParams: false,
      params: '',
      model: { ...lowcodeContext.model, filters },
    };
  },
  initColumnsFromImage: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleInitColumnsFromImage();
    return res;
  },
  initColumnsFromText: (lowcodeContext) => {
    let columns = lowcodeContext.params
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n');
    columns = columns.map((s) => ({
      slot: false,
      title: s,
      dataIndex: s,
      key: s,
    }));
    return {
      updateModelImmediately: false,
      onlyUpdateParams: false,
      params: '',
      model: { ...lowcodeContext.model, columns },
    };
  },
  askChatGPT: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleAskChatGPT();
    return res;
  },
  OCR: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleOCR();
    return res;
  },
};


================================================
FILE: materials/blocks/antdv2 增删改查列表页/script/src/context.ts
================================================
import { INestApplication } from '@nestjs/common';
import { CompileContext } from 'lowcode-context';
import { StatusBarItem } from 'vscode';

export const context: {
  lowcodeContext?: CompileContext;
  nestApp?: INestApplication<any>;
  statusBarItem?: StatusBarItem;
} = {
  lowcodeContext: undefined,
  nestApp: undefined,
  statusBarItem: undefined,
};


================================================
FILE: materials/blocks/antdv2 增删改查列表页/script/src/main.ts
================================================
import * as path from 'path';
import { window, workspace } from 'vscode';
import * as fs from 'fs-extra';
import * as execa from 'execa';
import * as ejs from 'ejs';
import axios from 'axios';
import { translate } from '@share/TypeChatSlim/index';
import { generalBasic } from '@share/BaiduOCR/index';
import { typescriptToMock } from '@share/utils/json';
import { context } from './context';
import { PageConfig } from '../../config/schema';

export async function handleOCR() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return {
      updateModelImmediately: false,
      onlyUpdateParams: true,
      params: '',
      model: lowcodeContext?.model,
    };
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  return {
    updateModelImmediately: false,
    onlyUpdateParams: true,
    params: ocrRes.words_result.map((s) => s.words).join('\r\n'),
    model: lowcodeContext?.model,
  };
}

export async function handleInitFiltersFromImage() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return lowcodeContext?.model;
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  const filters = ocrRes.words_result.map((s) => s.words);
  const formatedFilters = filters.map((item) => {
    const s = item.replace(/:|:/g, ':').split(':');
    return {
      component: (s[1] || '').indexOf('选择') > -1 ? 'select' : 'input',
      key: s[0].replace(/:|:/g, '').trim(),
      label: s[0].replace(/:|:/g, '').trim(),
      placeholder: s[1],
    };
  });
  return {
    updateModelImmediately: false,
    onlyUpdateParams: false,
    params: '',
    model: { ...lowcodeContext.model, filters: formatedFilters },
  };
}

export async function handleInitColumnsFromImage() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return lowcodeContext?.model;
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  const columns = ocrRes.words_result.map((s) => ({
    slot: false,
    title: s.words,
    dataIndex: s.words,
    key: s.words,
  }));
  return {
    updateModelImmediately: false,
    onlyUpdateParams: false,
    params: '',
    model: { ...lowcodeContext.model, columns },
  };
}

export async function handleAskChatGPT() {
  const { lowcodeContext } = context;
  const schema = fs.readFileSync(
    path.join(lowcodeContext!.materialPath, 'config/schema.ts'),
    'utf8',
  );
  const typeName = 'PageConfig';
  const res = await translate<PageConfig>({
    schema,
    typeName,
    request: JSON.stringify(lowcodeContext!.model as PageConfig),
    completePrompt:
      `你是一个根据以下 TypeScript 类型定义将用户请求转换为 "${typeName}" 类型的 JSON 对象的服务,并且按照字段的注释进行处理:\n` +
      `\`\`\`\n${schema}\`\`\`\n` +
      `以下是用户请求:\n` +
      `"""\n${JSON.stringify(lowcodeContext!.model as PageConfig)}\n"""\n` +
      `The following is the user request translated into a JSON object with 2 spaces of indentation and no properties with the value undefined:\n`,
    createChatCompletion: lowcodeContext!.createChatCompletion,
    showWebview: true,
    extendValidate: (jsonObject) => ({ success: true, data: jsonObject }),
  });
  lowcodeContext!.outputChannel.appendLine(JSON.stringify(res, null, 2));
  if (res.success) {
    return {
      updateModelImmediately: false,
      onlyUpdateParams: false,
      params: '',
      model: { ...res.data },
    };
  }
  return lowcodeContext!.model;
}

export async function handleComplete() {
  const { lowcodeContext } = context;
  const createBlockPath = context.lowcodeContext?.createBlockPath;
  if (createBlockPath) {
    // #region 更新 mock 服务
    const mockType = fs
      .readFileSync(path.join(createBlockPath, 'temp.mock.type').toString())
      .toString();
    fs.removeSync(path.join(createBlockPath, 'temp.mock.type'));
    const { mockCode, mockData } = typescriptToMock(mockType);
    const mockTemplate = fs
      .readFileSync(
        path.join(createBlockPath, 'temp.mock.script.ejs').toString(),
      )
      .toString();
    fs.removeSync(path.join(createBlockPath, 'temp.mock.script.ejs'));
    // @ts-ignore
    if (!lowcodeContext?.model.includeModifyModal) {
      fs.removeSync(path.join(path.join(createBlockPath, 'ModifyModal')));
    }
    const mockScript = ejs.render(mockTemplate, {
      ...lowcodeContext!.model,
      mockCode,
      mockData,
      createBlockPath: createBlockPath.replace(':', ''),
    });
    const mockProjectPathRes = await axios
      .get('http://localhost:3000/mockProjectPath', { timeout: 1000 })
      .catch(() => {
        // window.showInformationMessage(
        //   '获取 mock 项目路径失败,跳过更新 mock 服务',
        // );
      });
    if (mockProjectPathRes?.data.result) {
      const projectName = workspace.rootPath
        ?.replace(/\\/g, '/')
        .split('/')
        .pop();
      const mockRouteFile = path.join(
        mockProjectPathRes.data.result,
        `${projectName}.js`,
      );
      let mockFileContent = `
			import KoaRouter from 'koa-router';
			import proxy from '../middleware/Proxy';
			import { delay } from '../lib/util';

			const Mock = require('mockjs');

			const { Random } = Mock;

			const router = new KoaRouter();
			router{{mockScript}}
			module.exports = router;
			`;

      if (fs.existsSync(mockRouteFile)) {
        mockFileContent = fs.readFileSync(mockRouteFile).toString().toString();
        const index = mockFileContent.lastIndexOf(')') + 1;
        mockFileContent = `${mockFileContent.substring(
          0,
          index,
        )}{{mockScript}}\n${mockFileContent.substring(index)}`;
      }
      mockFileContent = mockFileContent.replace(/{{mockScript}}/g, mockScript);
      fs.writeFileSync(mockRouteFile, mockFileContent);
      try {
        execa.sync('node', [
          path.join(
            mockProjectPathRes.data.result
              .replace(/\\/g, '/')
              .replace('/src/routes', ''),
            '/node_modules/eslint/bin/eslint.js',
          ),
          mockRouteFile,
          '--resolve-plugins-relative-to',
          mockProjectPathRes.data.result
            .replace(/\\/g, '/')
            .replace('/src/routes', ''),
          '--fix',
        ]);
      } catch (err) {
        console.log(err);
      }
      // #endregion
    }
  }
}


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/ModifyModal/index.vue.ejs
================================================
<template>
  <a-modal
    :visible="props.visible"
    :title="props.title"
    :width="700"
    @ok="presenter.handleSubmit"
    @cancel="presenter.handleCancel"
    :ok-button-props="{ loading: model.loading.value }"
    :mask-closable="false"
  >
    <a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 12 }">
			<% modifyModal.formItems.map(item => { _%>
				<% if(item.component === "input") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input 
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allow-clear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						>
						</a-input>
					</a-form-item>
				<% } _%>
				<% if(item.component === "input-password") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input-password
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allowClear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						></a-input-password>
					</a-form-item>
				<% } _%>
				<% if(item.component === "input-number") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input-number
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allowClear
							<% if(item.max) { _%>
							:max="<%= item.max %>"
							<% } _%>
							<% if(item.min) { _%>
							:min="<%= item.min %>"
							<% } _%>
							<% if(item.step) { _%>
							:step="<%= item.step %>"
							<% } _%>
						></a-input-number>
					</a-form-item>
				<% } _%>
				<% if(item.component === "textarea") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-textarea
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allow-clear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						>
						</a-textarea>
					</a-form-item>
				<% } _%>
				<% if(item.component === "select") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-select
							placeholder="<%= item.placeholder %>"
							allow-clear
							:options="model.options.<%= item.key %>"
							v-model:value="model.formData.<%= item.key %>"
							<% if(item.labelInValue) { _%>
							labelInValue
							<% } _%>
							<% if(item.mode) { _%>
							mode="<%= item.mode %>"
							<% } _%>
							optionFilterProp="<%= item.optionFilterProp || 'label' %>"
							<% if(item.showSearch) { _%>
							showSearch
							<% } _%>
							<% if(item.hideArrow) { _%>
							:showArrow="false"
							<% } _%>
						></a-select>
					</a-form-item>
				<% } _%>
				<% if(item.component === "radio-group") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-radio-group v-model:value="model.formData.<%= item.key %>">
							<a-radio
								v-for="item in model.options.<%= item.key %>"
								:value="item.value"
								:key="item.value"
								>{{ item.label }}
							</a-radio>
						</a-radio-group>
					</a-form-item>
				<% } _%>
				<% if(item.component === "checkbox-group") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-checkbox-group
							v-model:value="model.formData.<%= item.key %>"
							style="width: 100%; margin-top: 6px"
						>
							<a-row>
							<a-col
								:span="8"
								v-for="item in model.options.<%= item.key %>"
								:key="item.value"
							>
								<a-checkbox :value="item.value">{{ item.label }} </a-checkbox>
							</a-col>
							</a-row>
						</a-checkbox-group>
					</a-form-item>
				<% } _%>
				<% if(item.component === "switch") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-switch
							v-model:checked="model.formData.<%= item.key %>"
							<% if(item.checkedChildren) { _%>
							checkedChildren="<%= item.checkedChildren %>"
							<% } _%>
							<% if(item.unCheckedChildren) { _%>
							unCheckedChildren="<%= item.unCheckedChildren %>"
							<% } _%>
							<% if(item.checkedValue) { _%>
								checkedValue="<%= item.checkedValue || 'true' %>"
							<% } _%>
							<% if(item.unCheckedValue) { _%>
								unCheckedValue="<%= item.unCheckedValue || 'false' %>"
							<% } _%>
						></a-switch>
					</a-form-item>
				<% } _%>
				<% if(item.component === "date-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-date-picker
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allow-clear
							picker="<%= item.picker || 'date' %>"
							:showTime="<%= item.showTime || false %>"
							:showNow="<%= item.showNow || false %>"
							:showToday="<%= item.showToday || false %>"
						/>
					</a-form-item>
				<% } _%>
				<% if(item.component === "range-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-range-picker
							v-model:value="model.formData.<%= item.key %>"
							:placeholder="[<%- item.placeholder || '\'\'' %>,<%- item.placeholder || '\'\'' %>]"
							allow-clear
							picker="<%= item.picker || 'date' %>"
							:showTime="<%= item.showTime || false %>"
							:showNow="<%= item.showNow || false %>"
							:showToday="<%= item.showToday || false %>"
						/>
					</a-form-item>
				<% } _%>
				<% if(item.component === "time-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-time-picker
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allow-clear
						/>
					</a-form-item>
				<% } _%>
			<% }) _%>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
import { usePresenter } from "./presenter";

interface IProps {
  title: string
  visible: boolean
  action: 'add' | 'edit' | 'view'
  id?: number
}

interface IEmit {
  (event: 'cancel'): void
  (event: 'ok'): void
}

const props = defineProps<IProps>()

const emit = defineEmits<IEmit>()

const presenter = usePresenter(props, emit);
const { model } = presenter;
</script>


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/ModifyModal/model.ts.ejs
================================================
import { reactive, ref } from "vue";
<% if(modifyModal.formItems.some(s => (s.type || "").indexOf("Dayjs") > -1)) { _%>
import type { Dayjs } from "dayjs";
<% } _%>

export interface IFormData {
	id?:number;
	<% modifyModal.formItems.map(item => { _%>
		<%= item.key %><% if(item.optional){ _%>?<% } _%>: <%= item.type %>;
	<% }) _%>
}

const defaultFormData: IFormData = {
	<% modifyModal.formItems.map(item => { _%>
		<%= item.key %>: <%- item.defaultValue || '\"\"' %>,
	<% }) _%>
};
<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ %>
interface IOptionItem {
  label: string;
  value: string;
}

interface IOptions {
  <% modifyModal.formItems.filter(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group").map(item => { _%>
		<%= item.key %>: IOptionItem[];
	<% }) _%>
}

const defaultOptions: IOptions = {
  <% modifyModal.formItems.filter(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group").map(item => { _%>
		<%= item.key %>: [],
	<% }) _%>
};
<% } %>

export const useModel = () => {
  const formData = reactive<IFormData>({ ...defaultFormData });
	<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ _%>
  const options = reactive<IOptions>({ ...defaultOptions });
	<% } _%>
  const loading = ref(false);

  return { 
		formData, 
		<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ _%>
		options,
		<% } _%>
		loading 
	};
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/ModifyModal/presenter.ts.ejs
================================================
import Service from "./service";
import { useModel } from "./model";
import { Form, message } from "ant-design-vue";
import { watch, reactive } from "vue";
import { Rule } from 'ant-design-vue/es/form/interface'

interface IProps {
  title: string
  visible: boolean
  action: 'add' | 'edit' | 'view'
  id?: number
}

interface IEmit {
  (event: 'cancel'): void
  (event: 'ok'): void
}

const { useForm } = Form;

export const usePresenter = (props: IProps, emit: IEmit) => {
  const model = useModel();
  const service = new Service(model);

  const rules: Record<string, Rule[]> = reactive({
		<% modifyModal.formItems.map(item => { _%>
			<%= item.key %>: [{ required: <%= item.required || false %>, message: "<%= item.message %>" }],
		<% }) _%>
  });

  const { resetFields, validate, validateInfos } = useForm(
    model.formData,
    rules,
  );

  watch(
    () => props.visible,
    () => {
      if (props.visible && props.id) {
        service.getDetail(props.id as number);
      }
    },
  );

  const handleSubmit = () => {
    validate().then(() => {
      if (props.action === "add") {
        service.create().then(() => {
          message.success("新建成功");
          resetFields();
          emit("ok");
        });
      } else {
        service.edit().then(() => {
          message.success("提交成功");
          resetFields();
          emit("ok");
        });
      }
    });
  };

  const handleCancel = () => {
    resetFields();
    emit("cancel");
  };

  return {
    model,
    service,
    handleSubmit,
    handleCancel,
    validateInfos,
  };
};


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/ModifyModal/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  async getDetail(id: number) {
    // const res = await fetchDetail({ id });
    // this.model.formData.id = id;
	<% modifyModal.formItems.map(item => { _%>
		// this.model.formData.<%= item.key %> = res.result<%= item.key %>;
	<% }) _%>
  }

  async create() {
    // this.model.loading.value = true;
    // await create({
	<% modifyModal.formItems.map(item => { _%>
		// <%= item.key %>: this.model.formData.<%= item.key %>,
	<% }) _%>
    // }).finally(() => {
    //   this.model.loading.value = false;
    // });
  }

  async edit() {
    // this.model.loading.value = true;
    // await edit(
    //   { id: this.model.formData.id! },
    //   {
	<% modifyModal.formItems.map(item => { _%>
		// <%= item.key %>: this.model.formData.<%= item.key %>,
	<% }) _%>
    //   },
    // ).finally(() => {
    //   this.model.loading.value = false;
    // });
  }
}


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/api.ts.ejs
================================================
import request from "@/utils/request";
<% if (locals.api) { %>
// #region <%= api.title %>
<%= type %>

<% if (api.req_query.length > 0 || api.req_params.length > 0 || api.query_path.params.length > 0) { _%>
export interface I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params {
	<% api.req_query.filter(query => query.name !== pagination.page && query.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% api.req_params.filter(s => s.name !== pagination.page && s.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% api.query_path.params.filter(s => s.name !== pagination.page && s.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% if (pagination.show) { _%>
		<%= pagination.page %>: number;
		<%= pagination.size %>: number;
	<% } _%>
}
<% } %> 
<% if (requestBodyType && api.req_body_other.indexOf('{}') < 0) { %>
    <%= requestBodyType %> 
<% } %> 

/**
* <%= api.title %> 
* /project/<%= api.project_id %>/interface/api/<%= api._id %> 
* @author <%= api.username %>  
* 
<% if (api.req_query.length > 0 || api.req_params.length > 0 || api.query_path.params.length > 0) { -%>* @param {I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params} params<%- "\n" %><% } _%>
<% if (requestBodyType && api.req_body_other.indexOf('{}')<0) { -%>* @param {I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Data} data<%- "\n" %><% } _%>
* @returns
*/
export function <%= funcName %> (
<% if (api.req_query.length>0 || api.req_params.length > 0 || api.query_path.params.length > 0) { %>
params: I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params,
<% } _%>
<% if (requestBodyType) { %> 
data: I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Data
<% } %> 
) {
return request<<%= typeName %>["result"]>({
	  url: `http://127.0.0.1:3000<%= api.query_path.path.replace(/\{/g,"${params.") %>`, 
		method: '<%= api.method %>',
		<% if(api.req_query.length>0 || api.req_params.length > 0) { %>params,<% } _%>
        <% if (requestBodyType && api.req_body_other.indexOf('{}')<0) {%>data,<% } %> 
	})
}
// #endregion
<% } else { %>
// #region
export interface I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result {
  code: number;
	msg: string;
	<% if (!pagination.show) { _%>
	result: {
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: string;
		<% }) _%>
		}[];
	<% } else { _%>
		result: {
			records: {
				<% columns.map((item, index) => { _%>
					<%= item.key || `column${index+1}` %>: string;
				<% }) _%>
			}[];
			total: number;
		}
	<% } _%>
}

export interface I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Params {
	<% filters.map(item => { _%>
		<% if(item.component !== "range-picker") { _%>
			 <%= item.key %>?: string;
		<% } else { _%>
			<%= item.key %>Start?: string;
			<%= item.key %>End?: string;
		<% } _%>
	<% }) _%>
	<% if (pagination.show) { _%>
		<%= pagination.page %>: number;
		<%= pagination.size %>: number;
	<% } _%>
}

export function <%= fetchName %>(
params: I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Params
) {
return request<I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result["result"]>({
	url: `http://127.0.0.1:3000/<%= createBlockPath %>/<%= fetchName %>`, 
	method: 'GET',
	params,
});
}
// #endregion
<% } %>

================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/index.vue.ejs
================================================
<template>
  <a-row class="filterForm" :gutter="30">
    <% filters.map(item => { _%> 
		  <a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8" :xxl="6">
				<% if(item.component === "select") { %>
				<a-form-item label="<%= item.label %>">
					<a-select
						v-model:value="model.filterForm.<%= item.key %>"
						:options="model.options.<%= item.key %>"
						placeholder="<%= item.placeholder %>"
						show-search
						allow-clear
						<% if(item.remoteFetch) { _%>
						:filter-option="false"
						<% } _%>
						option-filter-prop="label"
						@change="presenter.handleSearch"
						<% if(item.remoteFetch) { _%>
						@search="presenter.handleSearch<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>"
						<% } _%>
					></a-select>
				</a-form-item>
				<% } _%> 
				<% if(item.component === "input") { _%>
				<a-form-item label="<%= item.label %>">
					<a-input
						v-model:value="model.filterForm.<%= item.key %>"
						placeholder="<%= item.placeholder %>"
						allow-clear
						@press-enter="presenter.handleSearch"
					></a-input>
				</a-form-item>
				<% } _%> 
				<% if(item.component === "range-picker") { _%>
				<a-form-item label="<%= item.label %>">
					<a-range-picker
						v-model:value="model.filterForm.<%= item.key %>"
						:placeholder="['开始时间', '结束时间']"
						format="YYYY-MM-DD"
						valueFormat="YYYY-MM-DD"
						@change="presenter.handleSearch"
					/>
				</a-form-item>
				<% } _%> 
			</a-col>
		<% }) _%>
		<a-col style="text-align: right; flex: 1">
			<a-space>
				<a-button @click="presenter.handleClear">重置</a-button>
        <a-button @click="presenter.handleSearch" type="primary">查询</a-button>
        <a-button @click="presenter.handleCreate" type="primary">
          <template #icon><PlusOutlined /></template>
          新增
        </a-button>
			</a-space>
		</a-col>
  </a-row>
  <a-table
    :loading="model.loading.list"
    :columns="columns"
    :data-source="model.tableList.value"
    :pagination="false"
  >
	<% columns.filter(item => item.slot).map((item, index) => { _%>
		<template #<%= item.key %>="{ record }">
			{{ record.<%= item.key %> }}
		</template>
		<% }) _%>
		<template #operation="{ record }">
			<a-space :size="0">
				<% if(includeModifyModal) { _%>
				<a-button
					type="link"
					size="small"
					@click="
						() => {
							presenter.handleView(record);
						}
					"
				>
					查看
				</a-button>
				<% } _%>
				<a-button
					type="link"
					size="small"
					@click="
						() => {
							presenter.handleEdit(record);
						}
					"
				>
					编辑
				</a-button>
				<a-button
					type="link"
					danger
					size="small"
					@click="
						() => {
							presenter.handleDel(record);
						}
					"
				>
					删除
				</a-button>
			</a-space>
		</template>
  </a-table>
  <% if(pagination.show) { _%>
  <a-pagination
    style="margin-top: 10px"
    @change="presenter.handlePageChange"
		@showSizeChange="presenter.handlePageChange"
    v-model:current="model.pagination.page"
    :total="model.pagination.total"
    show-size-changer
    show-quick-jumper
	:show-total="(total: number) => `共 ${total} 条`"
  ></a-pagination>
  <% } _%> <% if(includeModifyModal) { _%>
  <ModifyModal
    :id="model.modalInfo.id"
    :title="model.modalInfo.title"
    :visible="model.modalInfo.visible"
    :action="model.modalInfo.action"
    @ok="presenter.handleModalOk"
    @cancel="presenter.handleModalCancel"
  ></ModifyModal>
  <% } _%>
</template>
<script lang="ts" setup>
  import { PlusOutlined } from "@ant-design/icons-vue";
  <% if(includeModifyModal) { _%>
  import ModifyModal from "./ModifyModal/index.vue";
  <% } _%>
  import { usePresenter } from "./presenter";

  const presenter = usePresenter();
  const { model } = presenter;

  const columns = [
    <% columns.map((item, index) => { _%>
  		{
        title: "<%= item.title || `column${index+1}` %>",
  			dataIndex: "<%= item.dataIndex || `column${index+1}` %>",
  			key: "<%= item.key || `column${index+1}` %>",
  			<% if(item.width) {%>width: "<%= item.width %>",<% } _%>
				<% if(item.slot) {%>slots: { customRender: "<%= item.key %>"},<% } _%>
  		},
  	<% }) _%>
  	{
      title: "操作",
      key: "operation",
  		width: 100,
			slots:{customRender: "operation"}
    }
  ];
</script>


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/model.ts.ejs
================================================
import { reactive, ref } from "vue";
<% if(locals.api){ %>
import { I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Result } from "./api";
<% } else { %>
import { I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result } from "./api";
<% } %>
<% if(!locals.api){ %>
interface ITableListItem {
	<% columns.map((item, index) => { _%>
		/** <%= item.title %> */
		<%= item.key || `column${index+1}` %>: string;
	<% }) _%>
	/**
   * 接口返回的数据,新增字段不需要改 ITableListItem 直接从这里取
   */
	apiResult: I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result<%- result %>[0]
}
<% } %>
interface IFormData {
	<% filters.map(item => { _%>
		/** <%= item.label %> */
		<% if(item.component === "range-picker") { _%>
			<%= item.key %>?: [string,string];
		<% } _%>
		<% if(item.component !== "range-picker") { _%>
			<%= item.key %>?: string;
		<% } _%>
	<% }) _%>
}
<% if(filters.some(s => s.component === "select" )){ %>
interface IOptionItem {
  label: string;
  value: string;
}

interface IOptions {
  <% filters.filter(s => s.component === "select").map(item => { _%>
	<%= item.key %>: IOptionItem[],
  <% }) _%>
}

const defaultOptions: IOptions = {
	<% filters.filter(s => s.component === "select").map(item => { _%>
		<%= item.key %>: [],
	<% }) _%>
};
<% } %>
export const defaultFormData: IFormData = {
	<% filters.map(item => { _%>
		<%= item.key %>: undefined,
	<% }) _%>
};

export const useModel = () => {
  const filterForm = reactive<IFormData>({ ...defaultFormData });
	<% if(filters.some(s => s.component === "select" )){ %>
  		const options = reactive<IOptions>({ ...defaultOptions });
	<% } %>
	<% if(locals.api){ _%>
		const tableList = ref<(I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Result<%- result %>[0] & { _?: unknown })[]>(
			[],
		);
	<% } else { _%>
		const tableList = ref<(ITableListItem & { _?: unknown })[]>(
			[],
		);
	<% } _%>
	<% if(pagination.show) { %>
		const pagination = reactive<{
			page: number;
			pageSize: number;
			total: number;
		}>({
			page: 1,
			pageSize: 10,
			total: 0,
		});
	<% } %>
  const loading = reactive<{ list: boolean }>({
    list: false,
  });
  <% if(includeModifyModal) { %>
	const modalInfo = reactive<{
		visible: boolean;
		title: string;
		id?: number;
		action: "add" | "edit" | "view";
	}>({
		visible: false,
		title: "",
		action: "add",
	});
  <% } %>
  return {
    filterForm,
		<% if(filters.some(s => s.component === "select" )){ _%>
    options,
		<% } _%>
    tableList,
		<% if(pagination.show) { _%>
		pagination,
		<% } _%>
			loading,
		<% if(includeModifyModal) { _%>
		modalInfo,
		<% } _%>
  };
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/presenter.ts.ejs
================================================
import Service from "./service";
import { defaultFormData, useModel } from "./model";
import { createVNode, onMounted } from "vue";
import { message, Modal } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
<% if(filters.some(item => item.component === "select" && item.remoteFetch)) { _%>
import { useDebounceFn } from "@vueuse/core";
<% } _%>

export const usePresenter = () => {
  const model = useModel();
  const service = new Service(model);

  onMounted(() => {
    service.<%= serviceName %>();
  });

  const handleClear = () => {
		Object.assign(model.filterForm, defaultFormData)
		<% if(pagination.show) { _%>
			model.pagination.page = 1;
		<% } _%>
    service.<%= serviceName %>();
  };

  const handleSearch = () => {
		<% if(pagination.show) { _%>
			model.pagination.page = 1;
		<% } _%>
    service.<%= serviceName %>();
  };

  <% if(pagination.show) { _%>
  const handlePageChange = (page: number, pageSize: number) => {
    if (pageSize !== model.pagination.pageSize) {
      model.pagination.pageSize = pageSize;
      model.pagination.page = 1;
    } else {
      model.pagination.page = page;
    }
    service.<%= serviceName %>();
  };
  <% } _%>

	<% filters.filter(item => item.component === "select" && item.remoteFetch).map(item => { _%> 
	const handleSearch<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %> = useDebounceFn((value: string) => {
		if (!value) {
			return;
		}
		service.search<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>(value);
	}, 400);
	
	<% }) _%>

  const handleDel = (record: typeof model.tableList.value[0]) => {
    Modal.confirm({
      title: "此操作将删除该选项,是否继续?",
      icon: createVNode(ExclamationCircleOutlined),
			okText: "确定",
      cancelText: "取消",
      onOk() {
        message.success("删除成功");
      },
    });
  };

  const handleCreate = () => {
	<% if(includeModifyModal) { _%>
    model.modalInfo.visible = true;
    model.modalInfo.title = "新建";
    model.modalInfo.action = "add";
    model.modalInfo.id = undefined;
	<% } _%>
  };

  const handleEdit = (record: typeof model.tableList.value[0]) => {
	<% if(includeModifyModal) { _%>
    model.modalInfo.visible = true;
    model.modalInfo.title = "编辑";
    model.modalInfo.action = "edit";
    model.modalInfo.id = record.id;
	<% } _%>
  };

  <% if(includeModifyModal) { _%>
  const handleView = (record: typeof model.tableList.value[0]) => {
    model.modalInfo.visible = true;
    model.modalInfo.title = "查看";
    model.modalInfo.action = "view";
    model.modalInfo.id = record.id;
  };

  const handleModalOk = () => {
    model.modalInfo.visible = false;
    service.<%= serviceName %>();
  };

  const handleModalCancel = () => {
    model.modalInfo.visible = false;
  };
  <% } _%>

  return {
    model,
    service,
    handleClear,
    handleSearch,
	<% if(pagination.show) { _%>
	handlePageChange,
  <% } _%>
	<% filters.filter(item => item.component === "select" && item.remoteFetch).map(item => { _%> 
		handleSearch<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>,
	<% }) _%>
	handleDel,
	handleCreate,
    handleEdit,
	<% if(includeModifyModal) { _%>
	handleView,
	handleModalOk,
	handleModalCancel
	<% } _%>
  };
};


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/service.ts.ejs
================================================
import { <%= locals.api ? funcName : fetchName %> } from "./api";
import { Model } from "./model"; 

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  async <%= serviceName %>() {
    this.model.loading.list = true;
		<% filters.map(item => { _%>
			<% if(item.component === "range-picker") { _%>
				let <%= item.key %>Start: string | undefined = undefined;
				let <%= item.key %>End: string | undefined = undefined;
				if (
				this.model.filterForm.<%= item.key %> &&
				this.model.filterForm.<%= item.key %>[0]
				) {
					<%= item.key %>Start = `${this.model.filterForm.<%= item.key %>[0]} 00:00:00`;
				}
				if (
				this.model.filterForm.<%= item.key %> &&
				this.model.filterForm.<%= item.key %>[1]
				) {
					<%= item.key %>End = `${this.model.filterForm.<%= item.key %>[1]} 23:59:59`;
				}
			<% } _%>
		<% }) _%>
    const res = await <%= locals.api ? funcName : fetchName %>({
			<% filters.map(item => { _%>
				<% if(item.component !== "range-picker") { _%>
					<%= item.key %>: this.model.filterForm.<%= item.key %>,
				<% } else { _%>
					<%= item.key %>Start: <%= item.key %>Start,
					<%= item.key %>End: <%= item.key %>End,
				<% } _%>
			<% }) _%>
			<% if(pagination.show) { _%>
				<%= pagination.page %>: this.model.pagination.page,
				<%= pagination.size %>: this.model.pagination.pageSize,
			<% } _%>
		}).finally(() => {
			this.model.loading.list = false;
		});
    this.model.tableList.value = res<%- result %>.map((s) => {
      return {
		...s,
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: s.<%= item.key || `column${index+1}` %>,
		<% }) _%>
		apiResult: s
      };
    });
	<% if(pagination.show) { _%>
	this.model.pagination.total = res.<%- pagination.total %>;
	<% } _%>
  }

	<% filters.filter(item => item.component === "select" && item.remoteFetch).map(item => { _%> 
		async search<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>(value: string) {
			const res = await Promise.resolve([{ label: "1", value: "1" }]);
			this.model.options.<%= item.key %> = res;
		}
		
	<% }) _%>
}


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/temp.mock.script.ejs
================================================
.get(`<%= createBlockPath %>/<%= fetchName %>`, async (ctx, next) => { <%- mockCode %> ctx.body = <%- mockData %>
})


================================================
FILE: materials/blocks/antdv2 增删改查列表页/src/temp.mock.type.ejs
================================================
{
  code: number;
	msg: string;
	<% if (!pagination.show) { _%>
	result: {
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: string;
		<% }) _%>
	}[];
	<% } else { _%>
		result: {
			records: {
				<% columns.map((item, index) => { _%>
					<%= item.key || `column${index+1}` %>: string;
				<% }) _%>
			}[];
			total: number;
		}
	<% } _%>
}

================================================
FILE: materials/blocks/react-mvp 模块/config/model.json
================================================
{}

================================================
FILE: materials/blocks/react-mvp 模块/config/preview.json
================================================
{
	"title": "react-mvp 模块",
	"description": "react-mvp 模块",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [
		"react",
		"mvp"
	]
}

================================================
FILE: materials/blocks/react-mvp 模块/config/schema.json
================================================
{}

================================================
FILE: materials/blocks/react-mvp 模块/src/index.tsx.ejs
================================================
import React from "react";
import usePresenter from "./presenter";

export default () => {
  const presenter = usePresenter();
  const { model } = presenter;
  return <div>react mvp</div>;
};


================================================
FILE: materials/blocks/react-mvp 模块/src/model.ts.ejs
================================================
export const useModel = () => {};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/react-mvp 模块/src/presenter.tsx.ejs
================================================
import { useModel } from "./model";
import Service from "./service";

const usePresenter = () => {
  const model = useModel();
  const service = new Service(model);

  return {
    model,
    service,
  };
};

export default usePresenter;


================================================
FILE: materials/blocks/react-mvp 模块/src/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }
}


================================================
FILE: materials/blocks/taro-request/config/model.json
================================================
{}

================================================
FILE: materials/blocks/taro-request/config/preview.json
================================================
{
	"title": "taro-request",
	"description": "taro-request通用封装",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [
		"taro",
		"request"
	]
}

================================================
FILE: materials/blocks/taro-request/config/schema.json
================================================
{}

================================================
FILE: materials/blocks/taro-request/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/taro-request/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/taro-request/script/src/context');

module.exports = {
  beforeCompile: (context) => {},
  afterCompile: (constext) => {},
};


================================================
FILE: materials/blocks/taro-request/script/src/context.ts
================================================
import { INestApplication } from '@nestjs/common';
import { CompileContext } from 'lowcode-context';
import { StatusBarItem } from 'vscode';

export const context: {
  lowcodeContext?: CompileContext;
  nestApp?: INestApplication<any>;
  statusBarItem?: StatusBarItem;
} = {
  lowcodeContext: undefined,
  nestApp: undefined,
  statusBarItem: undefined,
};


================================================
FILE: materials/blocks/taro-request/script/src/main.ts
================================================
export const main = 1;


================================================
FILE: materials/blocks/taro-request/src/config.ts.ejs
================================================
// 请求连接前缀
export const baseUrl =
  process.env.NODE_ENV === "production"
    ? "https://xxx.com"
    : "http://localhost:8360";

// 输出日志信息
export const noConsole = false;


================================================
FILE: materials/blocks/taro-request/src/index.ts.ejs
================================================
import * as Taro from "@tarojs/taro";
import * as queryString from "query-string";
import { baseUrl } from "./config";
import interceptors from "./interceptors";

interceptors.forEach((interceptorItem) => Taro.addInterceptor(interceptorItem));

interface OptionsType {
  method: "GET" | "POST" | "PUT" | "DELETE";
  params?: Object;
  data?: Object;
  noLoading?: boolean;
}
export const request = <T = any>(
  url: string,
  options: OptionsType = {
    method: "GET",
    params: {},
    data: {},
    noLoading: false,
  }
) => {
  if (!options.noLoading) {
    Taro.showLoading({
      title: "加载中",
    });
  }
  for (const key in options.data) {
    if (
      options.data.hasOwnProperty(key) &&
      (options.data[key] === undefined || options.data[key] == null)
    ) {
      delete options.data[key];
    }
  }
  const urlWithParms =
    url.indexOf("?") > -1
      ? `${url}&${queryString.stringify(options.params)}`
      : `${url}?${queryString.stringify(options.params)}`;
  return Taro.request<T>({
    url:
      urlWithParms.indexOf("http") === -1
        ? `${baseUrl}${urlWithParms}`
        : urlWithParms,
    data: {
      ...options.data,
    },
    header: {
      // "X-Token": Taro.getStorageSync("token"),
      "Content-Type": "application/json",
    },
    method: options.method.toUpperCase() as any,
  })
    .then((res) => {
      return res.data;
    })
    .finally(() => {
      setTimeout(() => {
        Taro.hideLoading();
      }, 100);
    });
};


================================================
FILE: materials/blocks/taro-request/src/interceptors.ts.ejs
================================================
import * as Taro from "@tarojs/taro";

const HTTP_STATUS = {
  SUCCESS: 200,
  CREATED: 201,
  ACCEPTED: 202,
  CLIENT_ERROR: 400,
  AUTHENTICATE: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
  BAD_GATEWAY: 502,
  SERVICE_UNAVAILABLE: 503,
  GATEWAY_TIMEOUT: 504,
};

const rspInterceptor: Taro.interceptor = (chain) => {
  const { requestParams } = chain;

  return chain.proceed(requestParams).then((res) => {
    if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
      return Promise.reject("服务端出现了问题");
    }
    if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
      return Promise.reject("没有权限访问");
    }
    if (res.statusCode === HTTP_STATUS.AUTHENTICATE) {
      return Promise.reject("需要鉴权");
    }
    if (res.statusCode === HTTP_STATUS.SUCCESS) {
      return res;
    }
  });
};

const interceptors = [rspInterceptor];

export default interceptors;


================================================
FILE: materials/blocks/vant 表单/config/model.json
================================================
{
	"formItems": []
}

================================================
FILE: materials/blocks/vant 表单/config/preview.json
================================================
{
	"title": "",
	"description": "",
	"img": [
		"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg"
	],
	"category": [],
	"schema": "amis",
	"scripts": [
		{
			"method": "askChatGPT",
			"remark": "使用 ChatGPT 翻译模版数据里的指定中文字段"
		}
	]
}

================================================
FILE: materials/blocks/vant 表单/config/schema.json
================================================
{
	"formSchema": {
		"schema": {
			"type": "page",
			"body": [
				{
					"type": "form",
					"title": "",
					"body": [
						{
							"type": "switch",
							"label": "defineProps",
							"option": "",
							"name": "defineProps",
							"falseValue": false,
							"trueValue": true,
							"id": "u:9e7d1ee83373",
							"value": false
						},
						{
							"type": "switch",
							"label": "defineEmits",
							"option": "",
							"name": "defineEmits",
							"falseValue": false,
							"trueValue": true,
							"id": "u:4ef4be234efc",
							"value": false
						},
						{
							"type": "combo",
							"label": "表单项",
							"name": "formItems",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "button",
							"tabsLabelTpl": "表单项${index+1}",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:47ecb9e15ff1"
							},
							"items": [
								{
									"type": "input-text",
									"name": "key",
									"placeholder": "字段名",
									"id": "u:25b0c7b5e5a0",
									"label": "字段名(key)"
								},
								{
									"type": "select",
									"name": "type",
									"placeholder": "选项",
									"options": [
										{
											"label": "string",
											"value": "string"
										},
										{
											"label": "number",
											"value": "number"
										},
										{
											"label": "boolean",
											"value": "boolean"
										},
										{
											"label": "string[]",
											"value": "string[]"
										},
										{
											"label": "number[]",
											"value": "number[]"
										},
										{
											"label": "boolean[]",
											"value": "boolean[]"
										}
									],
									"id": "u:5bb823bc0afb",
									"multiple": false,
									"label": "字段类型",
									"value": ""
								},
								{
									"type": "switch",
									"label": "字段可选(字段名字后加?)",
									"option": "",
									"name": "optional",
									"falseValue": false,
									"trueValue": true,
									"id": "u:f22b76a31198",
									"value": false,
									"description": ""
								},
								{
									"type": "select",
									"label": "默认值",
									"name": "defaultValue",
									"options": [
										{
											"label": "\"\"",
											"value": "\"\""
										},
										{
											"label": "false",
											"value": "false"
										},
										{
											"label": "true",
											"value": "true"
										},
										{
											"label": "0",
											"value": "0"
										},
										{
											"label": "undefined",
											"value": "undefined"
										},
										{
											"label": "[]",
											"value": "[]"
										}
									],
									"id": "u:d721f505457e",
									"multiple": false,
									"value": "",
									"creatable": true
								},
								{
									"type": "flex",
									"items": [
										{
											"type": "container",
											"body": [
												{
													"type": "select",
													"name": "component",
													"placeholder": "选项",
													"options": [
														{
															"label": "input(van-field)",
															"value": "input"
														},
														{
															"label": "van-cell(常规表单组件布局无法满足时使用)",
															"value": "van-cell"
														},
														{
															"label": "van-switch",
															"value": "van-switch"
														},
														{
															"label": "van-checkbox",
															"value": "van-checkbox"
														},
														{
															"label": "van-checkbox-group",
															"value": "van-checkbox-group"
														},
														{
															"label": "van-radio-group",
															"value": "van-radio-group"
														},
														{
															"label": "van-stepper",
															"value": "van-stepper"
														},
														{
															"label": "van-uploader",
															"value": "van-uploader"
														},
														{
															"label": "van-picker",
															"value": "van-picker"
														},
														{
															"label": "van-datetime-picker",
															"value": "van-datetime-picker"
														}
													],
													"id": "u:995915eabcca",
													"multiple": false,
													"label": "组件",
													"value": ""
												}
											],
											"size": "xs",
											"style": {
												"position": "static",
												"display": "block",
												"flex": "1 1 auto",
												"flexGrow": 1,
												"flexBasis": "auto",
												"paddingLeft": "0px"
											},
											"wrapperBody": false,
											"isFixedHeight": false,
											"isFixedWidth": false,
											"id": "u:63cbd01838cb"
										},
										{
											"type": "container",
											"body": [
												{
													"type": "button",
													"label": "预览图",
													"id": "u:421835b9eb42",
													"actionType": "dialog",
													"dialog": {
														"type": "dialog",
														"title": "",
														"body": [
															{
																"type": "carousel",
																"auto": false,
																"thumbMode": "contain",
																"animation": "fade",
																"options": [
																	{
																		"image": "https://black-pearl.oss-cn-shenzhen.aliyuncs.com/2023/08/14/df767ebd-1a56-40ee-bb47-f7acbda5a85f.png",
																		"href": "https://black-pearl.oss-cn-shenzhen.aliyuncs.com/2023/08/14/df767ebd-1a56-40ee-bb47-f7acbda5a85f.png"
																	},
																	{
																		"image": "https://black-pearl.oss-cn-shenzhen.aliyuncs.com/2023/08/14/deb8c82a-7b03-415d-bfd0-372f8a5d9e31.png",
																		"href": "https://black-pearl.oss-cn-shenzhen.aliyuncs.com/2023/08/14/deb8c82a-7b03-415d-bfd0-372f8a5d9e31.png"
																	}
																],
																"height": "300",
																"id": "u:679ce934b491",
																"interval": 5000,
																"duration": 500,
																"multiple": false,
																"alwaysShowArrow": false,
																"controls": "arrows",
																"controlsTheme": "dark"
															}
														],
														"actions": [],
														"id": "u:92a20653a80f"
													},
													"hiddenOn": "${formItems[index].component==='666'}"
												}
											],
											"size": "xs",
											"style": {
												"position": "static",
												"display": "block",
												"flex": "0 0 auto"
											},
											"wrapperBody": false,
											"isFixedHeight": false,
											"isFixedWidth": false,
											"id": "u:e1a77fc17ac2"
										}
									],
									"style": {
										"position": "relative",
										"inset": "auto",
										"flexWrap": "nowrap",
										"alignItems": "flex-end",
										"marginBottom": "1.5rem",
										"paddingLeft": "0px",
										"paddingRight": "0px"
									},
									"id": "u:e109a539ee8f",
									"isFixedHeight": false,
									"isFixedWidth": false
								},
								{
									"type": "input-text",
									"label": "label",
									"name": "label",
									"id": "u:6496cac4f4b8",
									"placeholder": "",
									"description": "输入框左侧文本"
								},
								{
									"type": "input-text",
									"label": "placeholder",
									"name": "placeholder",
									"id": "u:d7f1a8a39449",
									"placeholder": "",
									"description": "输入框占位提示文字"
								},
								{
									"type": "switch",
									"label": "required",
									"option": "",
									"name": "required",
									"falseValue": false,
									"trueValue": true,
									"id": "u:032dae2bdd71",
									"value": false,
									"description": "是否显示表单必填星号"
								},
								{
									"type": "switch",
									"label": "Props (更多组件配置)",
									"option": "",
									"name": "showMore",
									"falseValue": false,
									"trueValue": true,
									"id": "u:bb465f530390",
									"value": false,
									"description": "以下组件 props 不修改默认值,对应 props 不会显式出现"
								},
								{
									"type": "input-text",
									"label": "name",
									"name": "name",
									"id": "u:8f64b1631d4b",
									"description": "名称,作为提交表单时的标识符",
									"hiddenOn": "${!showMore}",
									"clearValueOnHidden": false,
									"static": false
								},
								{
									"type": "select",
									"label": "type",
									"name": "prop-type",
									"options": [
										{
											"label": "text",
											"value": "text"
										}
									],
									"id": "u:2c327c726ef1",
									"multiple": false,
									"description": "输入框类型, 支持原生 input 标签的所有 type 属性,额外支持了 digit 类型,默认 text",
									"value": "",
									"creatable": true,
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "select",
									"label": "size",
									"name": "size",
									"options": [
										{
											"label": "large",
											"value": "large"
										}
									],
									"id": "u:8226dd30543a",
									"multiple": false,
									"description": "大小,可选值为 large",
									"value": "",
									"creatable": false,
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "input-text",
									"label": "maxlength",
									"name": "maxlength",
									"id": "u:07d46929d8bd",
									"description": "输入的最大字符数",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "border",
									"option": "",
									"name": "border",
									"falseValue": false,
									"trueValue": true,
									"id": "u:c8ffc4fb3136",
									"value": true,
									"description": "是否显示内边框",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "disabled",
									"option": "",
									"name": "disabled",
									"falseValue": false,
									"trueValue": true,
									"id": "u:8e7682ebbdf7",
									"value": false,
									"description": "是否禁用输入框",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "readonly",
									"option": "",
									"name": "readonly",
									"falseValue": false,
									"trueValue": true,
									"id": "u:51f1dc68ba31",
									"value": false,
									"description": "是否为只读状态,只读状态下无法输入内容",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "colon",
									"option": "",
									"name": "colon",
									"falseValue": false,
									"trueValue": true,
									"id": "u:d9d4478d4916",
									"value": false,
									"description": "是否在 label 后面添加冒号",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "center",
									"option": "",
									"name": "center",
									"falseValue": false,
									"trueValue": true,
									"id": "u:15bf10ee0f38",
									"value": false,
									"description": "是否使内容垂直居中",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "clearable",
									"option": "",
									"name": "clearable",
									"falseValue": false,
									"trueValue": true,
									"id": "u:6c6cb9913893",
									"value": false,
									"description": "是否启用清除图标,点击清除图标后会清空输入框",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "clickable",
									"option": "",
									"name": "clickable",
									"falseValue": false,
									"trueValue": true,
									"id": "u:a477d44b7d8b",
									"value": false,
									"description": "是否开启点击反馈",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "is-link",
									"option": "",
									"name": "is-link",
									"falseValue": false,
									"trueValue": true,
									"id": "u:7dec0bd94494",
									"value": false,
									"description": "是否展示右侧箭头并开启点击反馈",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "autofocus",
									"option": "",
									"name": "autofocus",
									"falseValue": false,
									"trueValue": true,
									"id": "u:e4ed85c736e6",
									"value": false,
									"description": "是否自动聚焦,iOS 系统不支持该属性",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "switch",
									"label": "show-word-limit",
									"option": "",
									"name": "show-word-limit",
									"falseValue": false,
									"trueValue": true,
									"id": "u:09de98d0b14f",
									"value": false,
									"description": "是否显示字数统计,需要设置 maxlength 属性",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "select",
									"label": "arrow-direction",
									"name": "arrow-direction",
									"options": [
										{
											"label": "left",
											"value": "left"
										},
										{
											"label": "right",
											"value": "right"
										},
										{
											"label": "up",
											"value": "up"
										},
										{
											"label": "down",
											"value": "down"
										}
									],
									"id": "u:861c9d5d39f9",
									"value": "",
									"creatable": true,
									"description": "箭头方向,可选值为 left up down,默认 right",
									"hiddenOn": "${!showMore}"
								},
								{
									"type": "select",
									"label": "label-align",
									"name": "label-align",
									"options": [
										{
											"label": "left",
											"value": "left"
										},
										{
											"label": "center",
											"value": "center"
										},
										{
											"label": "right",
											"value": "right"
										}
									],
									"id": "u:29bb77848154",
									"value": "",
									"creatable": true,
									"description": "左侧文本对齐方式,可选值为 center right,默认 left",
									"hiddenOn": "${!showMore}",
									"multiple": false
								},
								{
									"type": "select",
									"label": "input-align",
									"name": "input-align",
									"options": [
										{
											"label": "left",
											"value": "left"
										},
										{
											"label": "center",
											"value": "center"
										},
										{
											"label": "right",
											"value": "right"
										}
									],
									"id": "u:5a64d2c0eb4d",
									"value": "",
									"creatable": true,
									"description": "输入框对齐方式,可选值为 center right",
									"hiddenOn": "${!showMore}",
									"multiple": false
								},
								{
									"type": "switch",
									"label": "Slots",
									"option": "",
									"name": "slots",
									"falseValue": false,
									"trueValue": true,
									"id": "u:678ac90795de",
									"value": false,
									"hidden": false
								},
								{
									"type": "switch",
									"label": "label slot",
									"option": "",
									"name": "label-slot",
									"falseValue": false,
									"trueValue": true,
									"id": "u:549ef5521c55",
									"value": false,
									"description": "自定义输入框左侧文本",
									"hiddenOn": "${!slots}"
								},
								{
									"type": "switch",
									"label": "left-icon slot",
									"option": "",
									"name": "left-icon",
									"falseValue": false,
									"trueValue": true,
									"id": "u:02a1b49564b8",
									"value": false,
									"description": "自定义输入框头部图标",
									"hiddenOn": "${!slots}"
								},
								{
									"type": "switch",
									"label": "right-icon slot",
									"option": "",
									"name": "right-icon",
									"falseValue": false,
									"trueValue": true,
									"id": "u:5ce280c3acfe",
									"value": false,
									"description": "自定义输入框尾部图标",
									"hiddenOn": "${!slots}"
								},
								{
									"type": "switch",
									"label": "button slot",
									"option": "",
									"name": "button",
									"falseValue": false,
									"trueValue": true,
									"id": "u:90291d1eca81",
									"value": false,
									"description": "自定义输入框尾部按钮",
									"hiddenOn": "${!slots}"
								},
								{
									"type": "switch",
									"label": "extra slot",
									"option": "",
									"name": "extra",
									"falseValue": false,
									"trueValue": true,
									"id": "u:db41c5de7416",
									"value": false,
									"description": "自定义输入框最右侧的额外内容",
									"hiddenOn": "${!slots}"
								}
							],
							"id": "u:186f183e9320",
							"strictMode": false,
							"syncFields": [],
							"tabsMode": true,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"deleteBtn": {
								"label": "删除",
								"level": "default"
							}
						}
					],
					"id": "u:67967afb0e69",
					"submitText": ""
				}
			],
			"id": "u:d87dbf6bf8df",
			"pullRefresh": {
				"disabled": true
			},
			"regions": [
				"body"
			],
			"style": {
				"boxShadow": " 0px 0px 0px 0px transparent"
			},
			"asideResizor": false
		},
		"conditionFiles": {
			"name": {
				"value": "123",
				"exclude": [
					"当表单name的值为123,删除这个数组里的文件.ejs"
				]
			}
		},
		"excludeCompile": [
			"不需要编译的文件,不会被删除.ejs"
		]
	}
}

================================================
FILE: materials/blocks/vant 表单/config/viewPrompt.ejs
================================================
<%- model %> 
将这段 json 中,中文 key 翻译为英文,使用驼峰语法,
返回翻译后的markdown语法的代码块

================================================
FILE: materials/blocks/vant 表单/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/vant 表单/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/vant 表单/script/src/context');

module.exports = {
  beforeCompile: (context) => {},
  afterCompile: (context) => {
    context.outputChannel.appendLine(__dirname);
    context.outputChannel.appendLine(__filename);
    context.outputChannel.appendLine(process.cwd());
    context.outputChannel.appendLine(JSON.stringify(context.model));
  },
  askChatGPT: async (context) => {
    const statusBarItem = context.vscode.window.createStatusBarItem(
      context.vscode.StatusBarAlignment.Left,
    );
    statusBarItem.text = '$(sync~spin) Ask ChatGPT...';
    statusBarItem.show();
    const res = await context.createChatCompletion({
      messages: [
        {
          role: 'system',
          content: `你是一个严谨的代码机器人,严格按照输入的要求处理问题`,
        },
        {
          role: 'user',
          content: `${JSON.stringify(
            context.model,
          )} 将这段 json formItems 字段中的 key 字段的值翻译为英文,使用驼峰语法,label、placeholder
					保留中文。
					返回翻译后的JSON,不要带其他无关的内容,并且返回的结果使用 JSON.parse 不会报错`,
        },
      ],
      handleChunk: (data) => {
        // context.outputChannel.append(data.text || '')
      },
    });
    statusBarItem.hide();
    statusBarItem.dispose();
    context.outputChannel.appendLine(res);
    return { ...context.model, ...JSON.parse(res) };
  },
};


================================================
FILE: materials/blocks/vant 表单/src/index.vue.ejs
================================================
<template>
  <van-cell-group inset>
		<% formItems.map(item => { _%>
			<% if(item.component === "input"){ _%>
				<van-field
					v-model="model.formData.<%= item.key %>"
					<% if(item.label){ _%>
					label="<%= item.label %>"
					<% } _%>
					<% if(item.name){ _%>
					name="<%= item.name %>"
					<% } _%>
					<% if(item["prop-type"]){ _%>
					type="<%= item["prop-type"] %>"
					<% } _%>
					<% if(item.size){ _%>
					size="<%= item.size %>"
					<% } _%>
					<% if(item.maxlength){ _%>
					maxlength="<%= item.maxlength %>"
					<% } _%>
					<% if(item.placeholder){ _%>
					placeholder="<%= item.placeholder %>"
					<% } _%>
					<% if(item.border === false){ _%>
					:border="false"
					<% } _%>
					<% if(item.disabled){ _%>
					disabled
					<% } _%>
					<% if(item.readonly){ _%>
					readonly
					<% } _%>
					<% if(item.colon){ _%>
					colon
					<% } _%>
					<% if(item.required){ _%>
					required
					<% } _%>
					<% if(item.center){ _%>
					center
					<% } _%>
					<% if(item.clearable){ _%>
					clearable
					<% } _%>
					<% if(item.clickable){ _%>
					clickable
					<% } _%>
					<% if(item["is-link"]){ _%>
					is-link
					<% } _%>
					<% if(item.autofocus){ _%>
					autofocus
					<% } _%>
					<% if(item["show-word-limit"]){ _%>
					show-word-limit
					<% } _%>
					<% if(item["arrow-direction"]){ _%>
					arrow-direction="<%= item["arrow-direction"] %>"
					<% } _%>
					<% if(item["label-align"]){ _%>
					label-align="<%= item["label-align"] %>"
					<% } _%>
					<% if(item["input-align"]){ _%>
					input-align="<%= item["input-align"] %>"
					<% } _%>
				>
					<% if(item["label-slot"]){ _%>
						<template #label>
							label-slot
						</template>
					<% } _%>
					<% if(item["left-icon"]){ _%>
						<template #left-icon>
							left-icon
						</template>
					<% } _%>
					<% if(item["right-icon"]){ _%>
						<template #right-icon>
							right-icon
						</template>
					<% } _%>
					<% if(item["button"]){ _%>
						<template #button>
							button
						</template>
					<% } _%>
					<% if(item["extra"]){ _%>
						<template #extra>
							extra
						</template>
					<% } _%>
				</van-field>
			<% } else if(item.component === "van-cell") { _%>
				<van-cell>
					<template #title>
						<label class="van-field__label van-field__label--required"><%= item.label %></label>
					</template>
					<template #label>
						<div>
							自定义组件
						</div>
					</template>
				</van-cell>
			<% } else { _%>
				<van-field
					<% if(item.component === "van-picker" || item.component === "van-datetime-picker"){ _%>
					v-model="model.formData.<%= item.key %>"
					@click="presenter.handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerOpen"
					is-link
      		readonly
					<% } _%>
					<% if(item.label){ _%>
					label="<%= item.label %>"
					<% } _%>
					<% if(item.name){ _%>
					name="<%= item.name %>"
					<% } _%>
					<% if(item["prop-type"]){ _%>
					type="<%= item["prop-type"] %>"
					<% } _%>
					<% if(item.size){ _%>
					size="<%= item.size %>"
					<% } _%>
					<% if(item.maxlength){ _%>
					maxlength="<%= item.maxlength %>"
					<% } _%>
					<% if(item.placeholder){ _%>
					placeholder="<%= item.placeholder %>"
					<% } _%>
					<% if(item.border === false){ _%>
					:border="false"
					<% } _%>
					<% if(item.disabled){ _%>
					disabled
					<% } _%>
					<% if(item.readonly){ _%>
					readonly
					<% } _%>
					<% if(item.colon){ _%>
					colon
					<% } _%>
					<% if(item.requiredIcon){ _%>
					required
					<% } _%>
					<% if(item.center){ _%>
					center
					<% } _%>
					<% if(item.clearable){ _%>
					clearable
					<% } _%>
					<% if(item.clickable){ _%>
					clickable
					<% } _%>
					<% if(item["is-link"]){ _%>
					is-link
					<% } _%>
					<% if(item.autofocus){ _%>
					autofocus
					<% } _%>
					<% if(item["show-word-limit"]){ _%>
					show-word-limit
					<% } _%>
					<% if(item["arrow-direction"]){ _%>
					arrow-direction="<%= item["arrow-direction"] %>"
					<% } _%>
					<% if(item["label-align"]){ _%>
					label-align="<%= item["label-align"] %>"
					<% } _%>
					<% if(item["input-align"]){ _%>
					input-align="<%= item["input-align"] %>"
					<% } _%>
				>
				<% if(item.component === "van-switch"){ _%>
					<template #input>
						<van-switch
							v-model="model.formData.<%= item.key %>"
							loading
							disabled
							size="20"
							active-color="#1989fa"
							inactive-color="white"
							active-value="true"
							inactive-value="false"
						/>
					</template>
				<% } _%>
				<% if(item.component === "van-checkbox"){ _%>
					<template #input>
						<van-checkbox v-model="model.formData.<%= item.key %>" shape="square" />
					</template>
				<% } _%>
				<% if(item.component === "van-checkbox-group"){ _%>
					<template #input>
						<van-checkbox-group v-model="model.formData.<%= item.key %>" direction="horizontal">
							<van-checkbox
								v-for="item in model.options.<%= item.key %>"
								:key="item.value"
								:name="item.value"
								shape="square"
							>
								{{ item.label }}
							</van-checkbox>
						</van-checkbox-group>
					</template>
				<% } _%>
				<% if(item.component === "van-radio-group"){ _%>
					<template #input>
						<van-radio-group v-model="model.formData.<%= item.key %>" direction="horizontal">
							<van-radio v-for="item in model.options.<%= item.key %>" :key="item.value" :name="item.value">
								{{ item.label }}
							</van-radio>
						</van-radio-group>
					</template>
				<% } _%>
				<% if(item.component === "van-stepper"){ _%>
					<template #input>
						<van-stepper v-model="model.formData.<%= item.key %>" />
					</template>
				<% } _%>
				<% if(item.component === "van-uploader"){ _%>
					<template #input>
						<van-uploader />
					</template>
				<% } _%>
				<% if(item.component === "van-picker"){ _%>
				<% } _%>
				<% if(item.component === "van-datetime-picker"){ _%>
				<% } _%>
				<% if(item["label-slot"]){ _%>
					<template #label>
						label-slot
					</template>
				<% } _%>
				<% if(item["left-icon"]){ _%>
					<template #left-icon>
						left-icon
					</template>
				<% } _%>
				<% if(item["right-icon"]){ _%>
					<template #right-icon>
						right-icon
					</template>
				<% } _%>
				<% if(item["button"]){ _%>
					<template #button>
						button
					</template>
				<% } _%>
				<% if(item["extra"]){ _%>
					<template #extra>
						extra
					</template>
				<% } _%>
				</van-field>
			<% } _%>
		<% }) _%>
		<% formItems.filter(s => s.component === "van-picker" || s.component === "van-datetime-picker").map(item => { _%>
			<% if(item.component === "van-picker"){ _%>	
				<van-popup v-model:show="model.picker.<%= item.key %>.visible" position="bottom">
					<van-picker
						:columns="model.picker.<%= item.key %>.columns"
						@confirm="presenter.handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerConfirm"
						@cancel="presenter.handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerCancel"
					/>
				</van-popup>
			<% } _%>
			<% if(item.component === "van-datetime-picker"){ _%>	
				<van-popup v-model:show="model.picker.<%= item.key %>.visible" position="bottom">
					<van-datetime-picker
						type="time"
						@confirm="presenter.handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerConfirm"
						@cancel="presenter.handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerCancel"
					/>
				</van-popup>
			<% } _%>
		<% }) _%>
  </van-cell-group>
</template>
<script lang="ts" setup>
<% if(defineProps || defineEmits){ _%>
import {<% if(defineProps){ %>defineProps,<% } %> <% if(defineEmits){ %>defineEmits<% } %> } from 'vue'
<% } _%>
import { usePresenter } from './presenter'
<% if(defineProps){ %>
interface IProps {
  visible: boolean
}
<% } _%>
<% if(defineEmits){ %>
interface IEmit {
  (event: 'update', id: number): void
}
<% } %>
<% if(defineProps){ %>
const props = defineProps<IProps>()
<% } _%>
<% if(defineEmits){ %>
const emit = defineEmits<IEmit>()
<% } _%>

const presenter = usePresenter(<% if(defineProps){ %>props,<% } _%> <% if(defineEmits){ %>emit<% } %>)
const { model } = presenter
</script>


================================================
FILE: materials/blocks/vant 表单/src/model.ts.ejs
================================================
import { reactive } from 'vue'

export interface IFormData {
	<% formItems.map(item => { _%>
		<%= item.key %><% if(item.optional){ _%>?<% } _%>: <%= item.type %>;
	<% }) _%>
}

const defaultFormData: IFormData = {
	<% formItems.map(item => { _%>
		<%= item.key %>: <%- item.defaultValue || '\'\'' %>,
	<% }) _%>
};

<% if(formItems.some(s => s.component === "van-picker" || s.component === "van-datetime-picker")){ %>
interface IPicker {
	<% formItems.filter(s => s.component === "van-picker" || s.component === "van-datetime-picker").map(item => { _%>
		<% if(item.component === "van-picker"){ %>	
			<%= item.key %>: { visible: boolean; columns: string[] }
		<% } _%>
		<% if(item.component === "van-datetime-picker"){ %>	
			<%= item.key %>: { visible: boolean }
		<% } _%>
	<% }) _%>
}
<% } %>


<% if(formItems.some(s => s.component === "van-checkbox-group" || s.component === "van-radio-group")){ %>
interface IOptionItem {
  label: string;
  value: string;
}

interface IOptions {
  <% formItems.filter(s => s.component === "van-checkbox-group" || s.component === "van-radio-group").map(item => { _%>
		<%= item.key %>: IOptionItem[];
	<% }) _%>
}

const defaultOptions: IOptions = {
  <% formItems.filter(s => s.component === "van-checkbox-group" || s.component === "van-radio-group").map(item => { _%>
		<%= item.key %>: [],
	<% }) _%>
};
<% } %>

export const useModel = () => {
  const formData = reactive<IFormData>({ ...defaultFormData });
	<% if(formItems.some(s => s.component === "van-checkbox-group" || s.component === "van-radio-group")){ _%>
  const options = reactive<IOptions>({ ...defaultOptions });
	<% } _%>
	<% if(formItems.some(s => s.component === "van-picker" || s.component === "van-datetime-picker")){ %>
		const picker = reactive<IPicker>({
			<% formItems.filter(s => s.component === "van-picker" || s.component === "van-datetime-picker").map(item => { _%>
				<% if(item.component === "van-picker"){ %>	
					<%= item.key %>: {
						visible: false,
						columns: []
					},
				<% } _%>
				<% if(item.component === "van-datetime-picker"){ %>	
					<%= item.key %>: {
						visible: false
					}
				<% } _%>
			<% }) _%>
		})
	<% } %>

  return { 
		formData, 
		<% if(formItems.some(s => s.component === "van-checkbox-group" || s.component === "van-radio-group")){ _%>
		options,
		<% } _%>
		<% if(formItems.some(s => s.component === "van-picker" || s.component === "van-datetime-picker")){ _%>
		picker
		<% } %>
	};
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/vant 表单/src/presenter.tsx.ejs
================================================
import Service from './service'
import { useModel } from './model'
<% if(defineProps){ %>
interface IProps {
  visible: boolean
}
<% } %>
<% if(defineEmits){ %>
interface IEmit {
  (event: 'update', id: number): void
}
<% } %>
export const usePresenter = (<% if(defineProps){ %>props: IProps,<% } %> <% if(defineEmits){ %>emit: IEmit<% } %>) => {
  const model = useModel()
  const service = new Service(model)

	<% formItems.filter(s => s.component === "van-picker" || s.component === "van-datetime-picker").map(item => { _%>
		const handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerOpen = () => {
			model.picker.<%= item.key %>.visible = true
		}
	
		const handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerCancel = () => {
			model.picker.<%= item.key %>.visible = false
		}
	
		const handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerConfirm = (value: string) => {
			model.picker.<%= item.key %>.visible = false
			model.formData.<%= item.key %> = value
		}
	<% }) _%>

  const handleSubmit = () => {}

  const handleCancel = () => {}

  return {
    model,
    service,
    handleSubmit,
    handleCancel,
		<% formItems.filter(s => s.component === "van-picker" || s.component === "van-datetime-picker").map(item => { _%>
			handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerOpen,
			handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerCancel,
			handle<%= item.key.slice(0, 1).toUpperCase() + item.key.slice(1) %>PickerConfirm,
		<% }) _%>
  }
}


================================================
FILE: materials/blocks/vant 表单/src/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  async submit() {
    const data = {
			<% formItems.map(item => { _%>
				<%= item.key %>: this.model.formData.<%= item.key %>,
			<% }) _%>
    };
    await Promise.resolve(data);
  }
}


================================================
FILE: materials/blocks/vue-mvp 模块/config/model.json
================================================
{}

================================================
FILE: materials/blocks/vue-mvp 模块/config/preview.json
================================================
{
	"title": "vue-mvp 模块",
	"description": "vue-mvp 模块",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [
		"vue",
		"vue3",
		"mvp"
	]
}

================================================
FILE: materials/blocks/vue-mvp 模块/config/schema.json
================================================
{}

================================================
FILE: materials/blocks/vue-mvp 模块/src/index.tsx.ejs
================================================
import { defineComponent } from "vue";
import { usePresenter } from "./presenter";

const Page = defineComponent({
  setup() {
    const presenter = usePresenter();
    const { model } = presenter;

    return { model, presenter };
  },
  render() {
    return <div>vue mvp</div>;
  },
});
export default Page;


================================================
FILE: materials/blocks/vue-mvp 模块/src/model.ts.ejs
================================================
import { reactive } from "vue";

export const useModel = () => {
  return {};
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/vue-mvp 模块/src/presenter.ts.ejs
================================================
import Service from "./service";
import { useModel } from "./model";

export const usePresenter = () => {
  const model = useModel();
  const service = new Service(model);

  return {
    model,
    service,
  };
};


================================================
FILE: materials/blocks/vue-mvp 模块/src/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }
}


================================================
FILE: materials/blocks/vue2-mvp 模块/config/model.json
================================================
{}

================================================
FILE: materials/blocks/vue2-mvp 模块/config/preview.json
================================================
{
	"title": "vue2-mvp 模块",
	"description": "vue2-mvp 模块",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [
		"vue",
		"vue2",
		"mvp"
	]
}

================================================
FILE: materials/blocks/vue2-mvp 模块/config/schema.json
================================================
{}

================================================
FILE: materials/blocks/vue2-mvp 模块/src/index.tsx.ejs
================================================
import { defineComponent } from "@vue/composition-api";
import { usePresenter } from "./presenter";

const Index = defineComponent({
  setup() {
    const presenter = usePresenter();
    const { model } = presenter;

    return { model, presenter };
  },
  render() {
    return <div>vue2 mvp</div>;
  }
});
export default Index;


================================================
FILE: materials/blocks/vue2-mvp 模块/src/model.ts.ejs
================================================
import { reactive } from "@vue/composition-api";

export const useModel = () => {
  return {};
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/vue2-mvp 模块/src/presenter.ts.ejs
================================================
import Service from "./service";
import { useModel } from "./model";

export const usePresenter = () => {
  const model = useModel();
  const service = new Service(model);

  return {
    model
  };
};


================================================
FILE: materials/blocks/vue2-mvp 模块/src/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }
}


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/model.json
================================================
{
  "filters": [],
  "columns": [],
  "pagination": {
    "show": true,
    "page": "page",
    "size": "size",
    "total": "result.total"
  },
  "includeModifyModal": false,
  "fetchName": "fetchTableList",
  "result": "[\"result\"][\"records\"]",
  "serviceName": "getTableList"
}

================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/preview.json
================================================
{
	"title": "",
	"description": "",
	"img": "https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg",
	"category": [],
	"schema": "amis",
	"scripts": [
		{
			"method": "initFiltersFromImage",
			"remark": "使用截图初始化查询条件"
		},
		{
			"method": "initFiltersFromText",
			"remark": "使用文本初始化查询条件"
		},
		{
			"method": "initColumnsFromText",
			"remark": "使用文本初始化表格"
		},
		{
			"method": "initColumnsFromImage",
			"remark": "使用截图初始化表格"
		},
		{
			"method": "askChatGPT",
			"remark": "使用 ChatGPT 翻译模版数据里的指定中文字段"
		}
	]
}

================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/schema.json
================================================
{
	"formSchema": {
		"schema": {
			"type": "page",
			"body": [
				{
					"type": "form",
					"title": "",
					"body": [
						{
							"type": "combo",
							"label": "查询条件",
							"name": "filters",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "icon",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:47ecb9e15ff1"
							},
							"items": [
								{
									"type": "input-text",
									"name": "key",
									"placeholder": "字段名",
									"id": "u:25b0c7b5e5a0",
									"label": "字段名(key)"
								},
								{
									"type": "input-text",
									"label": "label",
									"name": "label",
									"id": "u:6496cac4f4b8",
									"description": ""
								},
								{
									"type": "select",
									"name": "component",
									"placeholder": "选项",
									"options": [
										{
											"label": "input",
											"value": "input"
										},
										{
											"label": "select",
											"value": "select"
										}
									],
									"id": "u:995915eabcca",
									"multiple": false,
									"label": "组件",
									"value": ""
								},
								{
									"type": "input-text",
									"label": "placeholder",
									"name": "placeholder",
									"id": "u:d7f1a8a39449",
									"description": ""
								}
							],
							"id": "u:186f183e9320",
							"strictMode": false,
							"syncFields": [],
							"tabsMode": true,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"tabsLabelTpl": "表单项${index+1}",
							"multiLine": true,
							"noBorder": false
						},
						{
							"type": "combo",
							"label": "表格",
							"name": "columns",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "button",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:1e8070edc3d3"
							},
							"items": [
								{
									"type": "input-text",
									"name": "title",
									"id": "u:152dd82b82f9",
									"label": "title"
								},
								{
									"type": "input-text",
									"label": "dataIndex",
									"name": "dataIndex",
									"id": "u:ecc7298e0550",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "key",
									"name": "key",
									"id": "u:fbaa95c3f15d",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "width",
									"name": "width",
									"id": "u:b143127e097b",
									"description": ""
								},
								{
									"type": "switch",
									"label": "自定义插槽",
									"option": "",
									"name": "slot",
									"falseValue": false,
									"trueValue": true,
									"id": "u:ee1ce1faee0b",
									"value": false
								}
							],
							"id": "u:9b9fb0cf38f9",
							"strictMode": true,
							"syncFields": [],
							"tabsMode": true,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"deleteBtn": {
								"label": "删除",
								"level": "default"
							},
							"tabsLabelTpl": "列${index+1}"
						},
						{
							"type": "fieldset",
							"title": "分页参数",
							"collapsable": true,
							"body": [
								{
									"type": "switch",
									"label": "是否分页",
									"option": "",
									"name": "pagination.show",
									"falseValue": false,
									"trueValue": true,
									"id": "u:6c70041d5143",
									"value": true,
									"className": ""
								},
								{
									"type": "input-text",
									"label": "查询接口页数参数字段名",
									"name": "pagination.page",
									"id": "u:cbbf6853cf64",
									"value": "page"
								},
								{
									"type": "input-text",
									"label": "查询接口每页数据行数参数字段名",
									"name": "pagination.size",
									"id": "u:a8fae66fa927",
									"value": "size"
								},
								{
									"type": "input-text",
									"label": "接口返回总数据量字段 PATH",
									"name": "pagination.total",
									"id": "u:e1cd979c7ee8",
									"value": "result.total",
									"themeCss": {
										"inputControlClassName": {
											"padding-and-margin:default": {
												"marginBottom": "",
												"marginTop": "",
												"marginRight": "",
												"marginLeft": ""
											}
										}
									}
								}
							],
							"id": "u:0f1bd8fc2f2b",
							"collapsed": true,
							"headingClassName": "",
							"bodyClassName": "p"
						},
						{
							"type": "fieldset",
							"title": "请求方法",
							"collapsable": true,
							"body": [
								{
									"type": "input-text",
									"label": "请求名称",
									"name": "fetchName",
									"id": "u:a3e712484fae",
									"value": "fetchTableList",
									"description": "追加了YAPI数据则不使用此参数",
									"themeCss": {
										"labelClassName": {
											"padding-and-margin:default": {
												"marginTop": "",
												"marginRight": "",
												"marginBottom": "",
												"marginLeft": ""
											}
										}
									},
									"labelClassName": "labelClassName-a3e712484fae"
								},
								{
									"type": "input-text",
									"label": "接口数据字段 PATH",
									"name": "result",
									"id": "u:8c082acf7db2",
									"value": "[\"result\"][\"records\"]",
									"description": ""
								},
								{
									"type": "input-text",
									"label": "service方法名",
									"name": "serviceName",
									"id": "u:cfbbdd07366b",
									"value": "getTableList",
									"description": ""
								}
							],
							"id": "u:382f8cdf59a6",
							"collapsed": true,
							"className": "",
							"headingClassName": "",
							"bodyClassName": "p-r p-l p-b"
						},
						{
							"type": "fieldset",
							"title": "新增/编辑弹框",
							"collapsable": true,
							"body": [
								{
									"type": "switch",
									"label": "是否包含弹框",
									"option": "",
									"name": "includeModifyModal",
									"falseValue": false,
									"trueValue": true,
									"id": "u:03957070af9e",
									"value": false
								},
								{
									"type": "combo",
									"label": "表单项",
									"name": "modifyModal.formItems",
									"multiple": true,
									"addable": true,
									"removable": true,
									"removableMode": "icon",
									"strictMode": false,
									"addBtn": {
										"label": "新增",
										"icon": "fa fa-plus",
										"level": "primary",
										"size": "sm",
										"id": "u:86cc27b6a663"
									},
									"items": [
										{
											"type": "input-text",
											"name": "key",
											"id": "u:62cc1cf36c73",
											"label": "字段名(key)"
										},
										{
											"type": "select",
											"name": "type",
											"options": [
												{
													"label": "string",
													"value": "string"
												},
												{
													"label": "number",
													"value": "number"
												},
												{
													"label": "boolean",
													"value": "boolean"
												},
												{
													"label": "Dayjs",
													"value": "Dayjs"
												},
												{
													"label": "string[]",
													"value": "string[]"
												},
												{
													"label": "number[]",
													"value": "number[]"
												},
												{
													"label": "boolean[]",
													"value": "boolean[]"
												},
												{
													"label": "[Dayjs,Dayjs]",
													"value": "[Dayjs,Dayjs]"
												}
											],
											"id": "u:b165c75e5e1a",
											"multiple": false,
											"label": "字段类型",
											"value": ""
										},
										{
											"type": "switch",
											"label": "字段可选",
											"option": "",
											"name": "optional",
											"falseValue": false,
											"trueValue": true,
											"id": "u:68fc4c85fb03",
											"value": false,
											"description": "字段名字后加?"
										},
										{
											"type": "select",
											"name": "defaultValue",
											"options": [
												{
													"label": "\"\"",
													"value": "\"\""
												},
												{
													"label": "false",
													"value": "false"
												},
												{
													"label": "true",
													"value": "true"
												},
												{
													"label": "0",
													"value": "0"
												},
												{
													"label": "undefined",
													"value": "undefined"
												},
												{
													"label": "[]",
													"value": "[]"
												}
											],
											"id": "u:379ea92fb3c6",
											"multiple": false,
											"label": "默认值",
											"value": ""
										},
										{
											"type": "select",
											"name": "component",
											"options": [
												{
													"label": "input",
													"value": "input"
												},
												{
													"label": "input-password",
													"value": "input-password"
												},
												{
													"label": "input-number",
													"value": "input-number"
												},
												{
													"label": "textarea",
													"value": "textarea"
												},
												{
													"label": "select",
													"value": "select"
												},
												{
													"label": "radio-group",
													"value": "radio-group"
												},
												{
													"label": "checkbox-group",
													"value": "checkbox-group"
												},
												{
													"label": "switch",
													"value": "switch"
												},
												{
													"label": "date-picker",
													"value": "date-picker"
												},
												{
													"label": "time-ticker",
													"value": "time-picker"
												},
												{
													"label": "range-picker",
													"value": "range-picker"
												},
												{
													"label": "transfer",
													"value": "transfer"
												}
											],
											"id": "u:7932ea3b05da",
											"multiple": false,
											"label": "组件",
											"value": ""
										},
										{
											"type": "input-text",
											"name": "label",
											"id": "u:5bb237f20098",
											"label": "label"
										},
										{
											"type": "input-text",
											"name": "placeholder",
											"id": "u:580898257491",
											"label": "placeholder"
										},
										{
											"type": "switch",
											"label": "required",
											"option": "",
											"name": "required",
											"falseValue": false,
											"trueValue": true,
											"id": "u:559dbdbb01da",
											"value": false,
											"description": "验证规则加required"
										},
										{
											"type": "input-text",
											"name": "message",
											"id": "u:55013279d659",
											"label": "校验失败 message",
											"value": "不能为空"
										},
										{
											"type": "switch",
											"label": "更多组件配置",
											"option": "",
											"name": "showMore",
											"falseValue": false,
											"trueValue": true,
											"id": "u:67e0cb5b7496",
											"value": false,
											"description": ""
										},
										{
											"type": "switch",
											"label": "labelInValue",
											"option": "",
											"name": "labelInValue",
											"falseValue": false,
											"trueValue": true,
											"id": "u:7fd6f1b233d9",
											"value": false,
											"description": "是否把每个选项的 label 包装到 value 中",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "select",
											"name": "mode",
											"options": [
												{
													"label": "multiple",
													"value": "multiple"
												},
												{
													"label": "tags",
													"value": "tags"
												}
											],
											"multiple": false,
											"label": "mode",
											"value": "",
											"description": "设置 Select 的模式为多选或标签",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "input-text",
											"name": "optionFilterProp",
											"label": "optionFilterProp",
											"description": "搜索时过滤对应的 option 属性",
											"value": "label",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "switch",
											"label": "showSearch",
											"option": "",
											"name": "showSearch",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "使单选模式可搜索",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "switch",
											"label": "hideArrow",
											"option": "",
											"name": "hideArrow",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否隐藏下拉小箭头",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'select'}"
										},
										{
											"type": "input-text",
											"name": "maxlength",
											"label": "maxlength",
											"description": "最大长度",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'input' && modifyModal.formItems[index].component !== 'input-password' && modifyModal.formItems[index].component !== 'textarea')}"
										},
										{
											"type": "switch",
											"label": "showCount",
											"option": "",
											"name": "showCount",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否展示字数",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'input' && modifyModal.formItems[index].component !== 'input-password' && modifyModal.formItems[index].component !== 'textarea')}"
										},
										{
											"type": "input-text",
											"name": "max",
											"label": "max",
											"description": "最大值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "min",
											"label": "min",
											"description": "最小值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "step",
											"label": "step",
											"description": "每次改变步数,可以为小数",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'input-number'}"
										},
										{
											"type": "input-text",
											"name": "checkedChildren",
											"label": "checkedChildren",
											"description": "选中时的内容",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "unCheckedChildren",
											"label": "unCheckedChildren",
											"description": "非选中时的内容",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "checkedValue",
											"label": "checkedValue",
											"description": "选中时的值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "input-text",
											"name": "unCheckedValue",
											"label": "unCheckedValue",
											"description": "非选中时的值",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || modifyModal.formItems[index].component !== 'switch'}"
										},
										{
											"type": "select",
											"name": "picker",
											"options": [
												{
													"label": "date",
													"value": "date"
												},
												{
													"label": "week",
													"value": "week"
												},
												{
													"label": "month",
													"value": "month"
												},
												{
													"label": "quarter",
													"value": "quarter"
												},
												{
													"label": "year",
													"value": "year"
												}
											],
											"multiple": false,
											"label": "picker",
											"description": "设置选择器类型",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker')}"
										},
										{
											"type": "switch",
											"label": "showTime",
											"name": "showTime",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "增加时间选择功能",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										},
										{
											"type": "switch",
											"label": "showNow",
											"name": "showNow",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "当设定了 showTime 的时候,面板是否显示“此刻”按钮",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										},
										{
											"type": "switch",
											"label": "showToday",
											"name": "showToday",
											"falseValue": false,
											"trueValue": true,
											"value": false,
											"description": "是否展示“今天”按钮",
											"hiddenOn": "${!modifyModal.formItems[index].showMore || (modifyModal.formItems[index].component !== 'date-picker' && modifyModal.formItems[index].component !== 'range-picker' || modifyModal.formItems[index].picker !== 'date')}"
										}
									],
									"syncFields": [],
									"tabsMode": true,
									"draggable": true,
									"draggableTip": "可拖动排序",
									"tabsStyle": "line",
									"tabsLabelTpl": "表单项${index+1}",
									"multiLine": true,
									"noBorder": false,
									"hiddenOn": "${!includeModifyModal}"
								}
							],
							"bodyClassName": "p",
							"collapsed": true
						}
					],
					"submitText": ""
				}
			],
			"pullRefresh": {
				"disabled": true
			},
			"regions": [
				"body"
			],
			"style": {
				"boxShadow": " 0px 0px 0px 0px transparent"
			},
			"asideResizor": false
		}
	},
	"conditionFiles": {
		"includeModifyModal": {
			"value": false,
			"exclude": [
				"/ModifyModal/index.vue.ejs",
				"/ModifyModal/model.ts.ejs",
				"/ModifyModal/presenter.tsx.ejs",
				"/ModifyModal/presenter.ts.ejs",
				"/ModifyModal/service.ts.ejs"
			]
		}
	},
	"excludeCompile": [
		"temp.mock.script.ejs"
	]
}

================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/schema.ts
================================================
export type PageConfig = {
  filters: {
    component: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    key: string;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    label: string;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    placeholder: string;
  }[];
  columns: {
    slot: boolean;
    /**
     * @description 保持原始内容,不要翻译
     * @type {string}
     */
    title: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    dataIndex: string;
    /**
     * @description 翻译成英文,驼峰格式
     * @type {string}
     */
    key: string;
  }[];
  pagination: {
    show: boolean;
    page: string;
    size: string;
    total: string;
  };
  includeModifyModal: boolean;
  fetchName: string;
  result: string;
  serviceName: string;
};


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/viewPrompt.ejs
================================================
<%- model %> 将这段 json 中,filters 字段中的 key
字段的值翻译为英文,使用驼峰语法,label、placeholder 字段的值保留中文。columns 字段中的
key、dataIndex 字段的值翻译为英文,使用驼峰语法,title 字段的值保留中文。 返回翻译后的 markdown
语法的代码块


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/测试使用 jsx 作为模版引擎/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/测试使用 jsx 作为模版引擎/script/src/context');

module.exports = {
  beforeCompile: (lowcodeContext) => {},
  afterCompile: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    try {
      await main.handleAfterCompile();
    } catch (ex) {
      console.log(ex);
    }
  },
  complete: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    try {
      await main.handleComplete();
    } catch (ex) {
      console.log(ex);
    }
  },
  initFiltersFromImage: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleInitFiltersFromImage();
    return res;
  },
  initFiltersFromText: (lowcodeContext) => {
    let filters = lowcodeContext.params
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n');
    filters = filters.map((item) => {
      const s = item.replace(/:|:/g, ':').split(':');
      return {
        component: (s[1] || '').indexOf('选择') > -1 ? 'select' : 'input',
        key: s[0].trim(),
        label: s[0].trim(),
        placeholder: s[1] || '',
      };
    });
    lowcodeContext.outputChannel.appendLine(JSON.stringify(filters));
    return { ...lowcodeContext.model, filters };
  },
  initColumnsFromImage: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleInitColumnsFromImage();
    return res;
  },
  initColumnsFromText: (lowcodeContext) => {
    let columns = lowcodeContext.params
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n');
    columns = columns.map((s) => ({
      slot: false,
      title: s,
      dataIndex: s,
      key: s,
    }));
    lowcodeContext.outputChannel.appendLine(JSON.stringify(columns));
    return { ...lowcodeContext.model, columns };
  },
  askChatGPT: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleAskChatGPT();
    return res;
  },
};


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/script/src/context.ts
================================================
import { INestApplication } from '@nestjs/common';
import { CompileContext } from 'lowcode-context';
import { StatusBarItem } from 'vscode';

export const context: {
  lowcodeContext?: CompileContext;
  nestApp?: INestApplication<any>;
  statusBarItem?: StatusBarItem;
} = {
  lowcodeContext: undefined,
  nestApp: undefined,
  statusBarItem: undefined,
};


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/script/src/main.ts
================================================
import * as path from 'path';
import { window, env, workspace } from 'vscode';
import * as fs from 'fs-extra';
import * as execa from 'execa';
import * as ejs from 'ejs';
import axios from 'axios';
import { lint } from '@share/utils/lint';
import { renderTemplates } from '@share/utils/tsx';
import { translate } from '@share/TypeChatSlim/index';
import { generalBasic } from '@share/BaiduOCR/index';
import { typescriptToMock } from '@share/utils/json';
import { context } from './context';
import { PageConfig } from '../../config/schema';

export async function handleInitFiltersFromImage() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return lowcodeContext?.model;
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  env.clipboard.writeText(ocrRes.words_result.map((s) => s.words).join('\r\n'));
  window.showInformationMessage('内容已经复制到剪贴板');
  const filters = ocrRes.words_result
    .map((s) => s.words)
    .reduce((result, value, index, array) => {
      if (index % 2 === 0) {
        result.push(array.slice(index, index + 2));
      }
      return result;
    }, [] as string[][]);
  const formatedFilters = filters.map((s) => ({
    component: s[1].indexOf('选择') > -1 ? 'select' : 'input',
    key: s[0].replace(/:|:/g, '').trim(),
    label: s[0].replace(/:|:/g, '').trim(),
    placeholder: s[1],
  }));
  return { ...lowcodeContext.model, filters: formatedFilters };
}

export async function handleInitColumnsFromImage() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return lowcodeContext?.model;
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  env.clipboard.writeText(ocrRes.words_result.map((s) => s.words).join('\r\n'));
  window.showInformationMessage('内容已经复制到剪贴板');
  const columns = ocrRes.words_result.map((s) => ({
    slot: false,
    title: s.words,
    dataIndex: s.words,
    key: s.words,
  }));
  return { ...lowcodeContext.model, columns };
}

export async function handleAskChatGPT() {
  const { lowcodeContext } = context;
  const schema = fs.readFileSync(
    path.join(lowcodeContext!.materialPath, 'config/schema.ts'),
    'utf8',
  );
  const typeName = 'PageConfig';
  const res = await translate<PageConfig>({
    schema,
    typeName,
    request: JSON.stringify(lowcodeContext!.model as PageConfig),
    completePrompt:
      `你是一个根据以下 TypeScript 类型定义将用户请求转换为 "${typeName}" 类型的 JSON 对象的服务,并且按照字段的注释进行处理:\n` +
      `\`\`\`\n${schema}\`\`\`\n` +
      `以下是用户请求:\n` +
      `"""\n${JSON.stringify(lowcodeContext!.model as PageConfig)}\n"""\n` +
      `The following is the user request translated into a JSON object with 2 spaces of indentation and no properties with the value undefined:\n`,
    createChatCompletion: lowcodeContext!.createChatCompletion,
    showWebview: true,
    extendValidate: (jsonObject) => ({ success: true, data: jsonObject }),
  });
  lowcodeContext!.outputChannel.appendLine(JSON.stringify(res, null, 2));
  if (res.success) {
    return { ...res.data };
  }
  return lowcodeContext!.model;
}

export async function handleAfterCompile() {
  const { lowcodeContext } = context;
  const tempWorkPath = path.join(
    lowcodeContext?.env.privateMaterialsPath || '',
    '.lowcode',
  );
  await renderTemplates(
    {
      ...lowcodeContext?.model,
      title: '12121',
    },
    path.join(tempWorkPath, 'src'),
  );
}

export async function handleComplete() {
  const { lowcodeContext } = context;
  const createBlockPath = context.lowcodeContext?.createBlockPath;
  if (createBlockPath) {
    // #region lint
    lint({
      createBlockPath,
      rootPath: lowcodeContext!.env.rootPath,
    });
    // #endregion

    // #region 更新 mock 服务
    const mockType = fs
      .readFileSync(path.join(createBlockPath, 'temp.mock.type').toString())
      .toString();
    fs.removeSync(path.join(createBlockPath, 'temp.mock.type'));
    const { mockCode, mockData } = typescriptToMock(mockType);
    const mockTemplate = fs
      .readFileSync(
        path.join(createBlockPath, 'temp.mock.script.ejs').toString(),
      )
      .toString();
    fs.removeSync(path.join(createBlockPath, 'temp.mock.script.ejs'));
    // @ts-ignore
    if (!lowcodeContext?.model.includeModifyModal) {
      fs.removeSync(path.join(path.join(createBlockPath, 'ModifyModal')));
    }
    const mockScript = ejs.render(mockTemplate, {
      ...lowcodeContext!.model,
      mockCode,
      mockData,
      createBlockPath: createBlockPath.replace(':', ''),
    });
    const mockProjectPathRes = await axios
      .get('http://localhost:3000/mockProjectPath', { timeout: 1000 })
      .catch(() => {
        // window.showInformationMessage(
        //   '获取 mock 项目路径失败,跳过更新 mock 服务',
        // );
      });
    if (mockProjectPathRes?.data.result) {
      const projectName = workspace.rootPath
        ?.replace(/\\/g, '/')
        .split('/')
        .pop();
      const mockRouteFile = path.join(
        mockProjectPathRes.data.result,
        `${projectName}.js`,
      );
      let mockFileContent = `
			import KoaRouter from 'koa-router';
			import proxy from '../middleware/Proxy';
			import { delay } from '../lib/util';

			const Mock = require('mockjs');

			const { Random } = Mock;

			const router = new KoaRouter();
			router{{mockScript}}
			module.exports = router;
			`;

      if (fs.existsSync(mockRouteFile)) {
        mockFileContent = fs.readFileSync(mockRouteFile).toString().toString();
        const index = mockFileContent.lastIndexOf(')') + 1;
        mockFileContent = `${mockFileContent.substring(
          0,
          index,
        )}{{mockScript}}\n${mockFileContent.substring(index)}`;
      }
      mockFileContent = mockFileContent.replace(/{{mockScript}}/g, mockScript);
      fs.writeFileSync(mockRouteFile, mockFileContent);
      try {
        execa.sync('node', [
          path.join(
            mockProjectPathRes.data.result
              .replace(/\\/g, '/')
              .replace('/src/routes', ''),
            '/node_modules/eslint/bin/eslint.js',
          ),
          mockRouteFile,
          '--resolve-plugins-relative-to',
          mockProjectPathRes.data.result
            .replace(/\\/g, '/')
            .replace('/src/routes', ''),
          '--fix',
        ]);
      } catch (err) {
        console.log(err);
      }
      // #endregion
    }
  }
}


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/index.vue.ejs
================================================
<template>
  <a-modal
    :visible="props.visible"
    :title="props.title"
    :width="700"
    @ok="presenter.handleSubmit"
    @cancel="presenter.handleCancel"
    :ok-button-props="{ loading: model.loading.value }"
    :mask-closable="false"
  >
    <a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 12 }">
			<% modifyModal.formItems.map(item => { _%>
				<% if(item.component === "input") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input 
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allow-clear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						>
						</a-input>
					</a-form-item>
				<% } _%>
				<% if(item.component === "input-password") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input-password
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allowClear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						></a-input-password>
					</a-form-item>
				<% } _%>
				<% if(item.component === "input-number") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-input-number
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allowClear
							<% if(item.max) { _%>
							:max="<%= item.max %>"
							<% } _%>
							<% if(item.min) { _%>
							:min="<%= item.min %>"
							<% } _%>
							<% if(item.step) { _%>
							:step="<%= item.step %>"
							<% } _%>
						></a-input-number>
					</a-form-item>
				<% } _%>
				<% if(item.component === "textarea") { _%>
					<a-form-item
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-textarea
							v-model:value="model.formData.<%= item.key %>" 
							placeholder="<%= item.placeholder %>"
							allow-clear
							<% if(item.maxlength) { _%>
							:maxlength="<%= item.maxlength %>"
							<% } _%>
							<% if(item.showCount) { _%>
							showCount
							<% } _%>
						>
						</a-textarea>
					</a-form-item>
				<% } _%>
				<% if(item.component === "select") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-select
							placeholder="<%= item.placeholder %>"
							allow-clear
							:options="model.options.<%= item.key %>"
							v-model:value="model.formData.<%= item.key %>"
							<% if(item.labelInValue) { _%>
							labelInValue
							<% } _%>
							<% if(item.mode) { _%>
							mode="<%= item.mode %>"
							<% } _%>
							optionFilterProp="<%= item.optionFilterProp || 'label' %>"
							<% if(item.showSearch) { _%>
							showSearch
							<% } _%>
							<% if(item.hideArrow) { _%>
							:showArrow="false"
							<% } _%>
						></a-select>
					</a-form-item>
				<% } _%>
				<% if(item.component === "radio-group") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-radio-group v-model:value="model.formData.<%= item.key %>">
							<a-radio
								v-for="item in model.options.<%= item.key %>"
								:value="item.value"
								:key="item.value"
								>{{ item.label }}
							</a-radio>
						</a-radio-group>
					</a-form-item>
				<% } _%>
				<% if(item.component === "checkbox-group") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%>
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-checkbox-group
							v-model:value="model.formData.<%= item.key %>"
							style="width: 100%; margin-top: 6px"
						>
							<a-row>
							<a-col
								:span="8"
								v-for="item in model.options.<%= item.key %>"
								:key="item.value"
							>
								<a-checkbox :value="item.value">{{ item.label }} </a-checkbox>
							</a-col>
							</a-row>
						</a-checkbox-group>
					</a-form-item>
				<% } _%>
				<% if(item.component === "switch") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-switch
							v-model:checked="model.formData.<%= item.key %>"
							<% if(item.checkedChildren) { _%>
							checkedChildren="<%= item.checkedChildren %>"
							<% } _%>
							<% if(item.unCheckedChildren) { _%>
							unCheckedChildren="<%= item.unCheckedChildren %>"
							<% } _%>
							<% if(item.checkedValue) { _%>
								checkedValue="<%= item.checkedValue || 'true' %>"
							<% } _%>
							<% if(item.unCheckedValue) { _%>
								unCheckedValue="<%= item.unCheckedValue || 'false' %>"
							<% } _%>
						></a-switch>
					</a-form-item>
				<% } _%>
				<% if(item.component === "date-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-date-picker
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allow-clear
							picker="<%= item.picker || 'date' %>"
							:showTime="<%= item.showTime || false %>"
							:showNow="<%= item.showNow || false %>"
							:showToday="<%= item.showToday || false %>"
						/>
					</a-form-item>
				<% } _%>
				<% if(item.component === "range-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-range-picker
							v-model:value="model.formData.<%= item.key %>"
							:placeholder="[<%- item.placeholder || '\'\'' %>,<%- item.placeholder || '\'\'' %>]"
							allow-clear
							picker="<%= item.picker || 'date' %>"
							:showTime="<%= item.showTime || false %>"
							:showNow="<%= item.showNow || false %>"
							:showToday="<%= item.showToday || false %>"
						/>
					</a-form-item>
				<% } _%>
				<% if(item.component === "time-picker") { _%>
					<a-form-item 
						<% if(item.label) { _%>
						label="<%= item.label %>"
						<% } _%> 
						v-bind="presenter.validateInfos.<%= item.key %>"
					>
						<a-time-picker
							v-model:value="model.formData.<%= item.key %>"
							placeholder="<%= item.placeholder %>"
							allow-clear
						/>
					</a-form-item>
				<% } _%>
			<% }) _%>
    </a-form>
  </a-modal>
</template>
<script lang="ts" setup>
import { usePresenter } from "./presenter";

interface IProps {
  title: string
  visible: boolean
  action: 'add' | 'edit' | 'view'
  id?: number
}

interface IEmit {
  (event: 'cancel'): void
  (event: 'ok'): void
}

const props = defineProps<IProps>()

const emit = defineEmits<IEmit>()

const presenter = usePresenter(props, emit);
const { model } = presenter;
</script>


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/model.ts.ejs
================================================
import { reactive, ref } from "vue";
<% if(modifyModal.formItems.some(s => (s.type || "").indexOf("Dayjs") > -1)) { _%>
import type { Dayjs } from "dayjs";
<% } _%>

export interface IFormData {
	id?:number;
	<% modifyModal.formItems.map(item => { _%>
		<%= item.key %><% if(item.optional){ _%>?<% } _%>: <%= item.type %>;
	<% }) _%>
}

const defaultFormData: IFormData = {
	<% modifyModal.formItems.map(item => { _%>
		<%= item.key %>: <%- item.defaultValue || '\"\"' %>,
	<% }) _%>
};
<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ %>
interface IOptionItem {
  label: string;
  value: string;
}

interface IOptions {
  <% modifyModal.formItems.filter(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group").map(item => { _%>
		<%= item.key %>: IOptionItem[];
	<% }) _%>
}

const defaultOptions: IOptions = {
  <% modifyModal.formItems.filter(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group").map(item => { _%>
		<%= item.key %>: [],
	<% }) _%>
};
<% } %>

export const useModel = () => {
  const formData = reactive<IFormData>({ ...defaultFormData });
	<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ _%>
  const options = reactive<IOptions>({ ...defaultOptions });
	<% } _%>
  const loading = ref(false);

  return { 
		formData, 
		<% if(modifyModal.formItems.some(s => s.component === "select" || s.component === "radio-group" || s.component === "checkbox-group")){ _%>
		options,
		<% } _%>
		loading 
	};
};

export type Model = ReturnType<typeof useModel>;


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/presenter.tsx.ejs
================================================
import Service from "./service";
import { useModel } from "./model";
import { Form, message } from "ant-design-vue";
import { watch, reactive } from "vue";
import { Rule } from 'ant-design-vue/es/form/interface'

interface IProps {
  title: string
  visible: boolean
  action: 'add' | 'edit' | 'view'
  id?: number
}

interface IEmit {
  (event: 'cancel'): void
  (event: 'ok'): void
}

const { useForm } = Form;

export const usePresenter = (props: IProps, emit: IEmit) => {
  const model = useModel();
  const service = new Service(model);

  const rules: Record<string, Rule[]> = reactive({
		<% modifyModal.formItems.map(item => { _%>
			<%= item.key %>: [{ required: <%= item.required || false %>, message: "<%= item.message %>" }],
		<% }) _%>
  });

  const { resetFields, validate, validateInfos } = useForm(
    model.formData,
    rules,
  );

  watch(
    () => props.visible,
    () => {
      if (props.visible && props.id) {
        service.getDetail(props.id as number);
      }
    },
  );

  const handleSubmit = () => {
    validate().then(() => {
      if (props.action === "add") {
        service.create().then(() => {
          message.success("新建成功");
          resetFields();
          emit("ok");
        });
      } else {
        service.edit().then(() => {
          message.success("提交成功");
          resetFields();
          emit("ok");
        });
      }
    });
  };

  const handleCancel = () => {
    resetFields();
    emit("cancel");
  };

  return {
    model,
    service,
    handleSubmit,
    handleCancel,
    validateInfos,
  };
};


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/service.ts.ejs
================================================
import { Model } from "./model";

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  async getDetail(id: number) {
    // const res = await fetchDetail({ id });
    // this.model.formData.id = id;
	<% modifyModal.formItems.map(item => { _%>
		// this.model.formData.<%= item.key %> = res.result<%= item.key %>;
	<% }) _%>
  }

  async create() {
    // this.model.loading.value = true;
    // await create({
	<% modifyModal.formItems.map(item => { _%>
		// <%= item.key %>: this.model.formData.<%= item.key %>,
	<% }) _%>
    // }).finally(() => {
    //   this.model.loading.value = false;
    // });
  }

  async edit() {
    // this.model.loading.value = true;
    // await edit(
    //   { id: this.model.formData.id! },
    //   {
	<% modifyModal.formItems.map(item => { _%>
		// <%= item.key %>: this.model.formData.<%= item.key %>,
	<% }) _%>
    //   },
    // ).finally(() => {
    //   this.model.loading.value = false;
    // });
  }
}


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/api.ts.ejs
================================================
import request from "@/utils/request";
<% if (locals.api) { %>
// #region <%= api.title %>
<%= type %>

<% if (api.req_query.length > 0 || api.req_params.length > 0 || api.query_path.params.length > 0) { _%>
export interface I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params {
	<% api.req_query.filter(query => query.name !== pagination.page && query.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% api.req_params.filter(s => s.name !== pagination.page && s.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% api.query_path.params.filter(s => s.name !== pagination.page && s.name !== pagination.size).map(query => { _%>
		<%= query.name %>?: string;
	<% }) _%>
	<% if (pagination.show) { _%>
		<%= pagination.page %>: number;
		<%= pagination.size %>: number;
	<% } _%>
}
<% } %> 
<% if (requestBodyType && api.req_body_other.indexOf('{}') < 0) { %>
    <%= requestBodyType %> 
<% } %> 

/**
* <%= api.title %> 
* /project/<%= api.project_id %>/interface/api/<%= api._id %> 
* @author <%= api.username %>  
* 
<% if (api.req_query.length > 0 || api.req_params.length > 0 || api.query_path.params.length > 0) { -%>* @param {I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params} params<%- "\n" %><% } _%>
<% if (requestBodyType && api.req_body_other.indexOf('{}')<0) { -%>* @param {I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Data} data<%- "\n" %><% } _%>
* @returns
*/
export function <%= funcName %> (
<% if (api.req_query.length>0 || api.req_params.length > 0 || api.query_path.params.length > 0) { %>
params: I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Params,
<% } _%> 
<% if (requestBodyType) { %> 
data: I<%= funcName.slice(0, 1).toUpperCase() + funcName.slice(1) %>Data
<% } %> 
) {
return request<<%= typeName %>["result"]>({
	  url: `http://127.0.0.1:3000<%= api.query_path.path.replace(/\{/g,"${params.") %>`, 
		method: '<%= api.method %>',
		<% if(api.req_query.length>0 || api.req_params.length > 0) { %>params,<% } _%>
        <% if (requestBodyType && api.req_body_other.indexOf('{}')<0) {%>data,<% } %> 
	})
}
// #endregion
<% } else { %>
// #region
export interface I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result {
  code: number;
	msg: string;
	<% if (!pagination.show) { _%>
	result: {
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: string;
		<% }) _%>
		}[];
	<% } else { _%>
		result: {
			records: {
				<% columns.map((item, index) => { _%>
					<%= item.key || `column${index+1}` %>: string;
				<% }) _%>
			}[];
			total: number;
		}
	<% } _%>
}

export interface I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Params {
	<% filters.map(item => { _%>
		<%= item.key %>?: string;
	<% }) _%>
	<% if (pagination.show) { _%>
		<%= pagination.page %>: number;
		<%= pagination.size %>: number;
	<% } _%>
}

export function <%= fetchName %>(
params: I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Params
) {
return request<I<%= fetchName.slice(0, 1).toUpperCase() + fetchName.slice(1) %>Result["result"]>({
	url: `http://127.0.0.1:3000/<%= createBlockPath %>/<%= fetchName %>`, 
	method: 'GET',
	params,
});
}
// #endregion
<% } %>

================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/api.ts.template.tsx
================================================
import React from 'react';

interface IProps {
  api?: {
    title: string;
    req_query: { name: string }[];
    req_params: { name: string }[];
    query_path: { params: { name: string }[] };
    req_body_other: string;
  };
  requestBodyType: string;
  type: string;
  funcName: string;
  fetchName: string;
  title: string;
  columns: { title: string; key: string }[];
  filters: { key: string; label: string; component: string }[];
  result: string;
  pagination: { show: boolean; page: string; size: string };
}

const Content: React.FC<IProps> = (props) => (
  <>
    {`import request from "@/utils/request";`}
    {props.api && (
      <>
        // #region {props.api.title}
        {props.type}
        {(props.api.req_query.length > 0 ||
          props.api.req_params.length > 0 ||
          props.api.query_path.params.length > 0) && (
          <>
            {`export interface I${props.funcName
              .slice(0, 1)
              .toUpperCase()}${props.funcName.slice(1)}Params {`}
            <>
              {props.api.req_query
                .filter(
                  (query) =>
                    query.name !== props.pagination.page &&
                    query.name !== props.pagination.size,
                )
                .map((query) => (
                  <>{query.name}?: string;</>
                ))}
              {props.api.req_params
                .filter(
                  (query) =>
                    query.name !== props.pagination.page &&
                    query.name !== props.pagination.size,
                )
                .map((query) => (
                  <>{query.name}?: string;</>
                ))}
              {props.api.query_path.params
                .filter(
                  (query) =>
                    query.name !== props.pagination.page &&
                    query.name !== props.pagination.size,
                )
                .map((query) => (
                  <>{query.name}?: string;</>
                ))}
              {props.pagination.show && (
                <>
                  {props.pagination.page}: number;
                  {props.pagination.size}: number;
                </>
              )}
            </>
            {`}`}
          </>
        )}
        {props.requestBodyType &&
          props.api.req_body_other.indexOf('{}') < 0 && (
            <>{props.requestBodyType}</>
          )}
        // #endregion
      </>
    )}
  </>
);

export default Content;


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/index.vue.ejs
================================================
<template>
  <a-row :gutter="30">
    <% filters.map(item => { _%> 
		  <a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8" :xxl="6">
				<% if(item.component === "select") { %>
				<a-form-item label="<%= item.label %>">
					<a-select
						v-model:value="model.filterForm.<%= item.key %>"
						:options="model.options.<%= item.key %>"
						placeholder="<%= item.placeholder %>"
						allow-clear
					></a-select>
				</a-form-item>
				<% } _%> 
				<% if(item.component === "input") { _%>
				<a-form-item label="<%= item.label %>">
					<a-input
						v-model:value="model.filterForm.<%= item.key %>"
						placeholder="<%= item.placeholder %>"
						allow-clear
					></a-input>
				</a-form-item>
				<% } _%> 
				<% if(item.component === "range-picker") { _%>
				<a-form-item label="<%= item.label %>">
					<a-range-picker
						v-model:value="model.filterForm.<%= item.key %>"
						valueFormat="YYYY-MM-DD"
						:allowClear="false"
					/>
				</a-form-item>
				<% } _%> 
			</a-col>
		<% }) _%>
		<a-col style="text-align: right; flex: 1">
			<a-space>
				<a-button @click="presenter.handleClear">重置</a-button>
        <a-button @click="presenter.handleSearch" type="primary">查询</a-button>
        <a-button @click="presenter.handleCreate" type="primary">
          <template #icon><PlusOutlined /></template>
          新增
        </a-button>
			</a-space>
		</a-col>
  </a-row>
  <a-table
    :loading="model.loading.list"
    :columns="columns"
    :data-source="model.tableList.value"
    :pagination="false"
  >
	<% columns.filter(item => item.slot).map((item, index) => { _%>
		<template #<%= item.key %>="{ record }">
			{{ record.<%= item.key %> }}
		</template>
		<% }) _%>
		<template #operation="{ record }">
			<a-space :size="0">
				<% if(includeModifyModal) { _%>
				<a-button
					type="link"
					size="small"
					@click="
						() => {
							presenter.handleView(record);
						}
					"
				>
					查看
				</a-button>
				<% } _%>
				<a-button
					type="link"
					size="small"
					@click="
						() => {
							presenter.handleEdit(record);
						}
					"
				>
					编辑
				</a-button>
				<a-button
					type="link"
					danger
					size="small"
					@click="
						() => {
							presenter.handleDel(record);
						}
					"
				>
					删除
				</a-button>
			</a-space>
		</template>
  </a-table>
  <% if(pagination.show) { _%>
  <a-pagination
    style="margin-top: 10px"
    @change="presenter.handlePageChange"
		@showSizeChange="presenter.handlePageChange"
    v-model:current="model.pagination.page"
    :total="model.pagination.total"
    show-size-changer
    show-quick-jumper
  ></a-pagination>
  <% } _%> <% if(includeModifyModal) { _%>
  <ModifyModal
    :id="model.modalInfo.id"
    :title="model.modalInfo.title"
    :visible="model.modalInfo.visible"
    :action="model.modalInfo.action"
    @ok="presenter.handleModalOk"
    @cancel="presenter.handleModalCancel"
  ></ModifyModal>
  <% } _%>
</template>
<script lang="ts" setup>
  import { PlusOutlined } from "@ant-design/icons-vue";
  <% if(includeModifyModal) { _%>
  import ModifyModal from "./ModifyModal/index.vue";
  <% } _%>
  import { usePresenter } from "./presenter";

  const presenter = usePresenter();
  const { model } = presenter;

  const columns = [
    <% columns.map((item, index) => { _%>
  		{
        title: "<%= item.title || `column${index+1}` %>",
  			dataIndex: "<%= item.dataIndex || `column${index+1}` %>",
  			key: "<%= item.key || `column${index+1}` %>",
  			<% if(item.width) {%>width: "<%= item.width %>",<% } _%>
				<% if(item.slot) {%>slots: { customRender: "<%= item.key %>"},<% } _%>
  		},
  	<% }) _%>
  	{
      title: "操作",
      key: "operation",
  		width: 100,
			slots:{customRender: "operation"}
    }
  ];
</script>


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/model.ts.template.tsx
================================================
import React from 'react';

interface IProps {
  api?: object;
  funcName: string;
  fetchName: string;
  title: string;
  columns: { title: string; key: string }[];
  filters: { key: string; label: string; component: string }[];
  result: string;
  pagination: { show: boolean };
}

const Content: React.FC<IProps> = (props) => (
  <>
    {`import { reactive, ref } from "vue";`}
    {props.api &&
      `import { I${
        props.funcName.slice(0, 1).toUpperCase() + props.funcName.slice(1)
      }Result } from "./api";`}
    {!props.api &&
      `import { I${
        props.fetchName.slice(0, 1).toUpperCase() + props.fetchName.slice(1)
      }Result } from "./api";`}
    {!props.api && (
      <>
        {`interface ITableListItem {`}
        <>
          {props.columns.map((item, index) => (
            <>
              {`/** 
							* ${item.title}
							*/
						`}
              {item.key || `column${index + 1}`}: string;
            </>
          ))}
          <>
            <>
              {`
						/**
						 * 接口返回的数据,新增字段不需要改 ITableListItem 直接从这里取
						 */
						`}
              {`apiResult: I${props.fetchName
                .slice(0, 1)
                .toUpperCase()}${props.fetchName.slice(1)}Result${
                props.result
              }[0]`}
            </>
          </>
        </>
        {`}`}
      </>
    )}
    {`interface IFormData {`}
    <>
      {props.filters.map((item) => (
        <>
          {`/**
					* ${item.label}
					*/
				`}
          {item.component === 'range-picker' && `${item.key}?: string[];`}
          {item.component !== 'range-picker' && `${item.key}?: string;`}
        </>
      ))}
    </>
    {`}`}
    {props.filters.some((s) => s.component === 'select') && (
      <>
        {`interface IOptionItem {
						label: string;
						value: string;
					}`}
        {`interface IOptions {`}
        <>
          {props.filters
            .filter((s) => s.component === 'select')
            .map((item) => (
              <>{`${item.key}: IOptionItem[],`}</>
            ))}
        </>
        {`}`}
        {`const defaultOptions: IOptions = {`}
        <>
          {props.filters
            .filter((s) => s.component === 'select')
            .map((item) => (
              <>{`${item.key}: [],`}</>
            ))}
        </>
        {`};`}
      </>
    )}
    {`;export const defaultFormData: IFormData = {`}
    <>
      {props.filters.map((item) => (
        <>{`${item.key}: undefined,`}</>
      ))}
    </>
    {`}`}
    {`;export const useModel = () => {`}
    <>
      <>
        {`const filterForm = reactive<IFormData>({ ...defaultFormData });`}
        {props.filters.some((s) => s.component === 'select') && (
          <>{`const options = reactive<IOptions>({ ...defaultOptions });`}</>
        )}
        {props.api && (
          <>
            {`
							const tableList = ref<(I${props.funcName
                .slice(0, 1)
                .toUpperCase()}${props.funcName.slice(1)}Result${
                props.result
              }[0] & { _?: unknown })[]>(
								[],
							);
						`}
          </>
        )}
        {!props.api && (
          <>
            {`
							const tableList = ref<(ITableListItem & { _?: unknown })[]>(
								[],
							);
						`}
          </>
        )}
        {props.pagination.show && (
          <>
            {`
							const pagination = reactive<{
								page: number;
								pageSize: number;
								total: number;
							}>({
								page: 1,
								pageSize: 10,
								total: 0,
							});
						`}
          </>
        )}
        {`
					const loading = reactive<{ list: boolean }>({
						list: false,
					});
				`}
        {`return {`}
        <>
          filterForm,
          {props.filters.some((s) => s.component === 'select') && `options,`}
          tableList,
          {props.pagination.show && `pagination,`}
          loading,
        </>
        {`}`}
      </>
    </>
    {`};`}
    {`export type Model = ReturnType <typeof useModel>;`}
  </>
);

export default Content;


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/presenter.tsx.ejs
================================================
import Service from "./service";
import { defaultFormData, useModel } from "./model";
import { createVNode, onMounted } from "vue";
import { message, Modal } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";

export const usePresenter = () => {
  const model = useModel();
  const service = new Service(model);

  onMounted(() => {
    service.<%= serviceName %>();
  });

  const handleClear = () => {
		Object.assign(model.filterForm, defaultFormData)
		<% if(pagination.show) { _%>
			model.pagination.page = 1;
		<% } _%>
    service.<%= serviceName %>();
  };

  const handleSearch = () => {
		<% if(pagination.show) { _%>
			model.pagination.page = 1;
		<% } _%>
    service.<%= serviceName %>();
  };

  <% if(pagination.show) { _%>
  const handlePageChange = (page: number, pageSize: number) => {
    if (pageSize !== model.pagination.pageSize) {
      model.pagination.pageSize = pageSize;
      model.pagination.page = 1;
    } else {
      model.pagination.page = page;
    }
    service.<%= serviceName %>();
  };
  <% } _%>

  const handleDel = (record: typeof model.tableList.value[0]) => {
    Modal.confirm({
      title: "此操作将删除该选项,是否继续?",
      icon: createVNode(ExclamationCircleOutlined),
			okText: "确定",
      cancelText: "取消",
      onOk() {
        message.success("删除成功");
      },
    });
  };

  const handleCreate = () => {
	<% if(includeModifyModal) { _%>
    model.modalInfo.visible = true;
    model.modalInfo.title = "新建";
    model.modalInfo.action = "add";
    model.modalInfo.id = undefined;
	<% } _%>
  };

  const handleEdit = (record: typeof model.tableList.value[0]) => {
	<% if(includeModifyModal) { _%>
    model.modalInfo.visible = true;
    model.modalInfo.title = "编辑";
    model.modalInfo.action = "edit";
    model.modalInfo.id = record.id;
	<% } _%>
  };

  <% if(includeModifyModal) { _%>
  const handleView = (record: typeof model.tableList.value[0]) => {
    model.modalInfo.visible = true;
    model.modalInfo.title = "查看";
    model.modalInfo.action = "view";
    model.modalInfo.id = record.id;
  };

  const handleModalOk = () => {
    model.modalInfo.visible = false;
    service.<%= serviceName %>();
  };

  const handleModalCancel = () => {
    model.modalInfo.visible = false;
  };
  <% } _%>

  return {
    model,
    service,
    handleClear,
    handleSearch,
	<% if(pagination.show) { _%>
	handlePageChange,
    <% } _%>
	handleDel,
	handleCreate,
    handleEdit,
	<% if(includeModifyModal) { _%>
	handleView,
	handleModalOk,
	handleModalCancel
	<% } _%>
  };
};


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/service.ts.ejs
================================================
import { <%= locals.api ? funcName : fetchName %> } from "./api";
import { Model } from "./model"; 

export default class Service {
  private model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  async <%= serviceName %>() {
    this.model.loading.list = true;
    const res = await <%= locals.api ? funcName : fetchName %>({
			<% filters.map(item => { _%>
				<%= item.key %>: this.model.filterForm.<%= item.key %>,
			<% }) _%>
			<% if(pagination.show) { _%>
				<%= pagination.page %>: this.model.pagination.page,
				<%= pagination.size %>: this.model.pagination.pageSize,
			<% } _%>
		}).finally(() => {
			this.model.loading.list = false;
		});
    this.model.tableList.value = res<%- result %>.map((s) => {
      return {
		...s,
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: s.<%= item.key || `column${index+1}` %>,
		<% }) _%>
		apiResult: s
      };
    });
	<% if(pagination.show) { _%>
	this.model.pagination.total = res.<%- pagination.total %>;
	<% } _%>
  }
}


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/temp.mock.script.ejs
================================================
.get(`<%= createBlockPath %>/<%= fetchName %>`, async (ctx, next) => { <%- mockCode %> ctx.body = <%- mockData %>
})


================================================
FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/temp.mock.type.ejs
================================================
{
  code: number;
	msg: string;
	<% if (!pagination.show) { _%>
	result: {
		<% columns.map((item, index) => { _%>
			<%= item.key || `column${index+1}` %>: string;
		<% }) _%>
	}[];
	<% } else { _%>
		result: {
			records: {
				<% columns.map((item, index) => { _%>
					<%= item.key || `column${index+1}` %>: string;
				<% }) _%>
			}[];
			total: number;
		}
	<% } _%>
}

================================================
FILE: materials/blocks/测试脚本/config/model.json
================================================
{
  "name": "lowcode"
}

================================================
FILE: materials/blocks/测试脚本/config/preview.json
================================================
{
	"title": "测试脚本",
	"description": "测试脚本",
	"img": [
		"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg"
	],
	"category": [],
	"schema": "amis",
	"scripts": [
		{
			"method": "intFromOcrText",
			"remark": "使用 ocr 结果初始化表单"
		},
		{
			"method": "askChatGPT",
			"remark": "askChatGPT"
		}
	]
}

================================================
FILE: materials/blocks/测试脚本/config/schema.json
================================================
{
  "formSchema": {
    "schema": {
      "type": "page",
      "body": [
        {
          "type": "form",
          "title": "",
          "body": [
            {
              "type": "input-text",
              "name": "name",
              "label": "测试表单",
              "id": "u:4886baa626cf",
              "value": ""
            }
          ],
          "id": "u:67967afb0e69",
          "submitText": ""
        }
      ],
      "id": "u:d87dbf6bf8df",
      "asideResizor": false,
      "style": {
        "boxShadow": " 0px 0px 0px 0px transparent"
      },
      "pullRefresh": {
        "disabled": true
      },
      "regions": [
        "body"
      ]
    },
    "conditionFiles": {
      "name": {
        "value": "123",
        "exclude": [
          "当表单name的值为123,删除这个数组里的文件.ejs"
        ]
      }
    },
    "excludeCompile": [
      "不需要编译的文件,不会被删除.ejs"
    ]
  }
}

================================================
FILE: materials/blocks/测试脚本/config/viewPrompt.ejs
================================================
<%- model %> 
将这段 json 中,中文 key 翻译为英文,使用驼峰语法,
返回翻译后的markdown语法的代码块

================================================
FILE: materials/blocks/测试脚本/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/测试脚本/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/测试脚本/script/src/context');

module.exports = {
  beforeCompile: (context) => {
    const compileHandler =
      new main.CompileHandler3c5a281f3af548fda73cb864dd8f452b(context);
    compileHandler.log('compile start');
  },
  afterCompile: (context) => {
    const compileHandler =
      new main.CompileHandler3c5a281f3af548fda73cb864dd8f452b(context);
    compileHandler.log('compile end');
  },
  complete: (context) => {
    const compileHandler =
      new main.CompileHandler3c5a281f3af548fda73cb864dd8f452b(context);
    compileHandler.log('compile complete');
  },
  intFromOcrText: (context) => {
    const viewCallHandler =
      new main.ViewCallHandler3c5a281f3af548fda73cb864dd8f452b(context);
    viewCallHandler.log('call method intFromOcrText');
    viewCallHandler.showInformationMessage('lowcode');
    return viewCallHandler.intFromOcrText();
  },
  askChatGPT: (context) => {
    const viewCallHandler =
      new main.ViewCallHandler3c5a281f3af548fda73cb864dd8f452b(context);
    viewCallHandler.log('call method askChatGPT');
    return viewCallHandler.askChatGPT();
  },
};


================================================
FILE: materials/blocks/测试脚本/script/src/context.ts
================================================
import { INestApplication } from '@nestjs/common';
import { CompileContext } from 'lowcode-context';
import { StatusBarItem } from 'vscode';

export const context: {
  lowcodeContext?: CompileContext;
  nestApp?: INestApplication<any>;
  statusBarItem?: StatusBarItem;
} = {
  lowcodeContext: undefined,
  nestApp: undefined,
  statusBarItem: undefined,
};


================================================
FILE: materials/blocks/测试脚本/script/src/main.ts
================================================
import { CompileContext, ViewCallContext } from 'lowcode-context';

export class CompileHandler3c5a281f3af548fda73cb864dd8f452b {
  private context!: CompileContext;

  constructor(context: CompileContext) {
    this.context = context;
  }

  log(value: string) {
    this.context.outputChannel.appendLine(value);
  }
}

export class ViewCallHandler3c5a281f3af548fda73cb864dd8f452b {
  private context!: ViewCallContext;

  constructor(context: ViewCallContext) {
    this.context = context;
  }

  log(value: string) {
    this.context.outputChannel.appendLine(value);
  }

  showInformationMessage(msg: string) {
    this.context.vscode.window.showInformationMessage(msg);
  }

  intFromOcrText() {
    return Promise.resolve({ ...this.context.model, name: '测试一下' });
  }

  async askChatGPT() {
    const res = await this.context.createChatCompletion({
      messages: [{ role: 'user', content: this.context.params }],
      handleChunk: (data) => {
        this.context.outputChannel.append(data.text || '');
      },
    });
    return { ...this.context.model, name: res };
  }
}


================================================
FILE: materials/blocks/测试脚本/src/README.md
================================================
在当前文件夹下放区块模板,并将此文件删除

================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/model.json
================================================
{
	"items": [],
	"bordered": false,
	"extra": false,
	"layout": "horizontal",
	"variableName": "",
	"title": "",
	"column": ""
}

================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/preview.json
================================================
{
	"title": "",
	"description": "",
	"img": [
		"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg"
	],
	"category": [],
	"schema": "amis",
	"scripts": [
		{
			"method": "OCR",
			"remark": "OCR 识别剪贴版截图"
		},
		{
			"method": "initFromOcrText",
			"remark": "初始化列表,参数中粘贴 ocr 识别出的结果,每一行表示一项,也可以手动输入"
		},
		{
			"method": "askChatGPT",
			"remark": "使用 ChatGPT 翻译模版数据里的 items.key 字段"
		},
		{
			"method": "intFromClipboardImage",
			"remark": "读取剪贴板截图并翻译,初始化列表"
		}
	]
}

================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/schema.json
================================================
{
	"formSchema": {
		"schema": {
			"type": "page",
			"body": [
				{
					"type": "form",
					"title": "",
					"body": [
						{
							"type": "input-text",
							"id": "u:11b127c5df46",
							"label": "变量名",
							"name": "variableName",
							"description": ""
						},
						{
							"type": "input-text",
							"id": "u:1fdc2ed6321c",
							"label": "title",
							"name": "title",
							"description": "标题"
						},
						{
							"type": "switch",
							"id": "u:9cc79716dde1",
							"label": "bordered",
							"option": "",
							"name": "bordered",
							"falseValue": false,
							"trueValue": true,
							"value": false,
							"description": "是否展示边框"
						},
						{
							"type": "input-text",
							"id": "u:43fbc9d670c3",
							"label": "column",
							"name": "column",
							"description": "一行的 DescriptionItems 数量,可以写成像素值或支持响应式的对象写法 { xs: 8, sm: 16, md: 24},默认3"
						},
						{
							"type": "switch",
							"id": "u:b8b2cb8217d1",
							"label": "extra",
							"option": "",
							"name": "extra",
							"falseValue": false,
							"trueValue": true,
							"value": false,
							"description": "描述列表的操作区域,显示在右上方"
						},
						{
							"type": "select",
							"id": "u:a8859cde1998",
							"label": "layout",
							"name": "layout",
							"options": [
								{
									"label": "horizontal",
									"value": "horizontal"
								},
								{
									"label": "vertical",
									"value": "vertical"
								}
							],
							"multiple": false,
							"description": "描述布局",
							"value": "horizontal"
						},
						{
							"type": "combo",
							"label": "描述列表",
							"name": "items",
							"multiple": true,
							"addable": true,
							"removable": true,
							"removableMode": "icon",
							"addBtn": {
								"label": "新增",
								"icon": "fa fa-plus",
								"level": "primary",
								"size": "sm",
								"id": "u:47ecb9e15ff1"
							},
							"items": [
								{
									"type": "input-text",
									"name": "key",
									"placeholder": "字段名",
									"id": "u:25b0c7b5e5a0",
									"label": "字段名(key)"
								},
								{
									"type": "input-text",
									"label": "label",
									"name": "label",
									"id": "u:6496cac4f4b8",
									"description": "内容的描述"
								},
								{
									"type": "input-number",
									"label": "span",
									"name": "span",
									"keyboard": true,
									"id": "u:9ee4d10df24a",
									"step": 1,
									"min": 1,
									"description": "包含列的数量"
								}
							],
							"id": "u:186f183e9320",
							"strictMode": false,
							"syncFields": [],
							"tabsMode": false,
							"draggable": true,
							"draggableTip": "可拖动排序",
							"tabsStyle": "line",
							"tabsLabelTpl": "表单项${index+1}",
							"multiLine": true,
							"value": [
								{}
							]
						}
					],
					"submitText": "",
					"id": "u:67967afb0e69"
				}
			],
			"pullRefresh": {
				"disabled": true
			},
			"regions": [
				"body"
			],
			"style": {
				"boxShadow": " 0px 0px 0px 0px transparent"
			},
			"asideResizor": false,
			"id": "u:d87dbf6bf8df"
		},
		"conditionFiles": {
			"name": {
				"value": "123",
				"exclude": [
					"当表单name的值为123,删除这个数组里的文件.ejs"
				]
			}
		},
		"excludeCompile": [
			"temp.mock.script.ejs"
		]
	}
}

================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/schema.ts
================================================
export type IItems = {
  /**
   * @description 保持原始内容,不需要处理,不要翻译
   * @type {string}
   */
  label: string;
  /**
   * @description 翻译成英文,驼峰格式
   * @type {string}
   */
  key: string;
  span?: number;
}[];


================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/index.js
================================================
const path = require('path');
const moduleAlias = require('module-alias');

function splitStringByLastKeyword(inputString, keyword) {
  const lastIndex = inputString.lastIndexOf(keyword);

  if (lastIndex === -1) {
    return [inputString, ''];
  }

  const part1 = inputString.slice(0, lastIndex);
  const part2 = inputString.slice(lastIndex + keyword.length);

  return [part1, part2];
}

moduleAlias.addAlias(
  '@share',
  path.join(splitStringByLastKeyword(__dirname, 'materials')[0], 'dist/share'),
);
const main = require('../../../../dist/materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/main');
const {
  context,
} = require('../../../../dist/materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/context');

module.exports = {
  beforeCompile: (lowcodeContext) => {},
  afterCompile: (lowcodeContext) => {},
  complete: (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    main.handleComplete();
  },
  initFromOcrText: (lowcodeContext) => {
    let items = lowcodeContext.params
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n');
    items = items.map((s) => ({
      key: s.split(/:|:/g)[0],
      label: s.split(/:|:/g)[0],
    }));
    return { ...lowcodeContext.model, items };
  },
  askChatGPT: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleAskChatGPT();
    return res;
  },
  intFromClipboardImage: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleIntFromClipboardImage();
    return res;
  },

  OCR: async (lowcodeContext) => {
    context.lowcodeContext = lowcodeContext;
    const res = await main.handleOCR();
    return res;
  },
};


================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/context.ts
================================================
import { INestApplication } from '@nestjs/common';
import { CompileContext } from 'lowcode-context';
import { StatusBarItem } from 'vscode';

export const context: {
  lowcodeContext?: CompileContext;
  nestApp?: INestApplication<any>;
  statusBarItem?: StatusBarItem;
} = {
  lowcodeContext: undefined,
  nestApp: undefined,
  statusBarItem: undefined,
};


================================================
FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/main.ts
================================================
import * as path from 'path';
import * as fs from 'fs-extra';
import * as execa from 'execa';
import * as ejs from 'ejs';
import axios from 'axios';
import { workspace, window } from 'vscode';
import { translate } from '@share/TypeChatSlim/index';
import { generalBasic } from '@share/BaiduOCR/index';
import { typescriptToMock } from '@share/utils/json';
import { context } from './context';
import { IItems } from '../../config/schema';

export async function handleOCR() {
  const { lowcodeContext } = context;
  if (!lowcodeContext?.clipboardImage) {
    window.showInformationMessage('剪贴板里没有截图');
    return {
      updateModelImmediately: false,
      onlyUpdateParams: true,
      params: '',
      model: lowcodeContext?.model,
    };
  }
  const ocrRes = await generalBasic({ image: lowcodeContext!.clipboardImage! });
  return {
    updateModelImmediately: false,
    onlyUpdateP
Download .txt
gitextract_0an204y0/

├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── README.md
├── buildMaterials.js
├── llm/
│   └── index.js
├── lowcode-context.d.ts
├── materials/
│   ├── blocks/
│   │   ├── antdv2 增删改查列表页/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── ModifyModal/
│   │   │       │   ├── index.vue.ejs
│   │   │       │   ├── model.ts.ejs
│   │   │       │   ├── presenter.ts.ejs
│   │   │       │   └── service.ts.ejs
│   │   │       ├── api.ts.ejs
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       ├── service.ts.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       └── temp.mock.type.ejs
│   │   ├── react-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.tsx.ejs
│   │   │       └── service.ts.ejs
│   │   ├── taro-request/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── config.ts.ejs
│   │   │       ├── index.ts.ejs
│   │   │       └── interceptors.ts.ejs
│   │   ├── vant 表单/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   └── index.js
│   │   │   └── src/
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.tsx.ejs
│   │   │       └── service.ts.ejs
│   │   ├── vue-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       └── service.ts.ejs
│   │   ├── vue2-mvp 模块/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   └── src/
│   │   │       ├── index.tsx.ejs
│   │   │       ├── model.ts.ejs
│   │   │       ├── presenter.ts.ejs
│   │   │       └── service.ts.ejs
│   │   ├── 测试使用 jsx 作为模版引擎/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   ├── schema.ts
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── ModifyModal/
│   │   │       │   ├── index.vue.ejs
│   │   │       │   ├── model.ts.ejs
│   │   │       │   ├── presenter.tsx.ejs
│   │   │       │   └── service.ts.ejs
│   │   │       ├── api.ts.ejs
│   │   │       ├── api.ts.template.tsx
│   │   │       ├── index.vue.ejs
│   │   │       ├── model.ts.template.tsx
│   │   │       ├── presenter.tsx.ejs
│   │   │       ├── service.ts.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       └── temp.mock.type.ejs
│   │   ├── 测试脚本/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       └── README.md
│   │   ├── 现有模块中添加 antdv Descriptions 描述列表/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Form 垂直布局列表/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Form 表单/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       ├── temp.presenter.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 现有模块中添加 antdv Modal 弹框/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   └── schema.json
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       └── temp.presenter.ts.ejs
│   │   ├── 现有模块中添加 antdv Table 表格/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── schema.ts
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       ├── temp.api.ts.ejs
│   │   │       ├── temp.index.vue.ejs
│   │   │       ├── temp.mock.script.ejs
│   │   │       ├── temp.mock.type.ejs
│   │   │       ├── temp.model.ts.ejs
│   │   │       ├── temp.presenter.ts.ejs
│   │   │       └── temp.service.ts.ejs
│   │   ├── 通过 ast 给 antdv Descriptions 描述列表添加字段/
│   │   │   ├── config/
│   │   │   │   ├── model.json
│   │   │   │   ├── preview.json
│   │   │   │   ├── schema.json
│   │   │   │   └── viewPrompt.ejs
│   │   │   ├── script/
│   │   │   │   ├── index.js
│   │   │   │   └── src/
│   │   │   │       ├── context.ts
│   │   │   │       └── main.ts
│   │   │   └── src/
│   │   │       └── README.md
│   │   └── 通过脚本启动一个 nest api 服务/
│   │       ├── config/
│   │       │   ├── model.json
│   │       │   ├── preview.json
│   │       │   ├── schema.json
│   │       │   └── viewPrompt.ejs
│   │       ├── script/
│   │       │   ├── index.js
│   │       │   └── src/
│   │       │       ├── app.controller.ts
│   │       │       ├── app.module.ts
│   │       │       ├── app.service.ts
│   │       │       ├── context.ts
│   │       │       └── main.ts
│   │       └── src/
│   │           └── README.md
│   └── snippets/
│       ├── OCR/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── OCR + ChatGPT 翻译/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── Pro Chat/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── Pro Chat + Tldraw/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── Pro Chat + TypeChat/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── amis/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── axios-request-api-外挂脚本/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── genCode/
│       │   │       │   └── genCodeByYapi.ts
│       │   │       ├── main.ts
│       │   │       └── utils/
│       │   │           ├── config.ts
│       │   │           ├── editor.ts
│       │   │           ├── ejs.ts
│       │   │           ├── file.ts
│       │   │           ├── json.ts
│       │   │           ├── material.ts
│       │   │           └── request.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── form-render/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── formily/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── share ChatGPT 测试/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── start nest api server/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── app.controller.ts
│       │   │       ├── app.module.ts
│       │   │       ├── app.service.ts
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── taro-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── umi-request-api/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 动态表单 demo/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── controller.ts
│       │   │       ├── main.ts
│       │   │       └── routes.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 当前目录翻译成英文/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 快速创建区块/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       ├── lowcode/
│       │       │   └── 代码片段/
│       │       │       ├── config/
│       │       │       │   ├── commandPrompt.ejs.ejs
│       │       │       │   ├── model.json
│       │       │       │   ├── preview.json
│       │       │       │   └── schema.json
│       │       │       ├── script/
│       │       │       │   ├── index.js.ejs
│       │       │       │   └── src/
│       │       │       │       ├── context.ts.ejs
│       │       │       │       └── main.ts.ejs
│       │       │       └── src/
│       │       │           └── template.ejs.ejs
│       │       ├── uTools askChatGPT/
│       │       │   └── script/
│       │       │       ├── index.ts.ejs
│       │       │       └── src/
│       │       │           └── main.ts.ejs
│       │       ├── uTools 动态表单/
│       │       │   ├── config/
│       │       │   │   ├── config.json
│       │       │   │   ├── model.json
│       │       │   │   ├── schema.json
│       │       │   │   └── schema.ts
│       │       │   ├── script/
│       │       │   │   ├── index.ts.ejs
│       │       │   │   └── src/
│       │       │   │       ├── controller.ts.ejs
│       │       │   │       └── main.ts.ejs
│       │       │   └── src/
│       │       │       ├── api.ts.keep.ejs
│       │       │       ├── index.vue.keep.ejs
│       │       │       ├── model.ts.keep.ejs
│       │       │       ├── presenter.ts.keep.ejs
│       │       │       ├── service.ts.keep.ejs
│       │       │       ├── temp.mock.script
│       │       │       └── temp.mock.type.keep.ejs
│       │       ├── uTools 自动化脚本/
│       │       │   └── script/
│       │       │       ├── index.ts.ejs
│       │       │       └── src/
│       │       │           └── main.ts.ejs
│       │       └── uniapp/
│       │           ├── vue3-mvp/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           ├── vue3-mvp emit/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           ├── vue3-mvp props/
│       │           │   ├── index.scss.ejs
│       │           │   ├── index.vue.ejs
│       │           │   ├── model.ts
│       │           │   ├── presenter.ts
│       │           │   └── service.ts
│       │           └── vue3-mvp props emit/
│       │               ├── index.scss.ejs
│       │               ├── index.vue.ejs
│       │               ├── model.ts
│       │               ├── presenter.ts
│       │               └── service.ts
│       ├── 打开webview/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           ├── controller.ts
│       │           ├── main.ts
│       │           └── routes.ts
│       ├── 根据 DevOps 需求标题创建 GIT commit - 截图/
│       │   ├── config/
│       │   │   └── preview.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/
│       │   ├── config/
│       │   │   ├── preview.json
│       │   │   └── schema.ts
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 根据JSON生成API请求方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成MOCK方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型-去除接口名称/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据JSON生成TS类型-将中文字段翻译成英文/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── viewPrompt.ejs
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成API请求方法/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成MOCK方法/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据TS类型生成markdown表格/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 根据YAPI接口定义生成高级Mock脚本/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── src/
│       │       └── template.ejs
│       ├── 测试 JSONSchemaChat/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── validSchema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 测试脚本/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 生成 value-label 格式 JSON/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   ├── schema.json
│       │   │   └── schema.ts
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 翻译成驼峰格式/
│       │   ├── config/
│       │   │   ├── commandPrompt.ejs
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       └── main.ts
│       │   └── src/
│       │       └── template.ejs
│       ├── 自动保存活动窗口/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 获取当前用户最近一次 Git Commit 信息/
│       │   ├── config/
│       │   │   └── preview.json
│       │   └── script/
│       │       ├── index.js
│       │       └── src/
│       │           ├── context.ts
│       │           └── main.ts
│       ├── 设置配置信息/
│       │   ├── config/
│       │   │   ├── model.json
│       │   │   ├── preview.json
│       │   │   └── schema.json
│       │   ├── script/
│       │   │   ├── index.js
│       │   │   └── src/
│       │   │       ├── context.ts
│       │   │       ├── controller.ts
│       │   │       ├── main.ts
│       │   │       └── routes.ts
│       │   └── src/
│       │       └── template.ejs
│       └── 通过 TS 类型做字段映射/
│           ├── config/
│           │   ├── model.json
│           │   ├── preview.json
│           │   └── schema.json
│           ├── script/
│           │   ├── index.js
│           │   └── src/
│           │       ├── context.ts
│           │       ├── controller.ts
│           │       ├── main.ts
│           │       └── routes.ts
│           └── src/
│               └── template.ejs
├── package.json
├── scripts/
│   └── ClipboardImage/
│       ├── linux.sh
│       ├── mac.applescript
│       └── pc.ps1
├── share/
│   ├── BaiduOCR/
│   │   ├── index.ts
│   │   └── request.ts
│   ├── JSONSchemaChat/
│   │   ├── index.ts
│   │   └── result.ts
│   ├── LLM/
│   │   ├── gemini.ts
│   │   ├── geminiProxy.ts
│   │   ├── index.ts
│   │   ├── openai.ts
│   │   └── openaiV2.ts
│   ├── TypeChatSlim/
│   │   ├── index.ts
│   │   ├── result.ts
│   │   └── utools.ts
│   ├── WebView/
│   │   ├── callback.ts
│   │   ├── controllers/
│   │   │   ├── alert.ts
│   │   │   ├── dynamicForm.ts
│   │   │   ├── llm.ts
│   │   │   ├── script.ts
│   │   │   └── task.ts
│   │   ├── index.ts
│   │   ├── routes/
│   │   │   └── index.ts
│   │   └── type.ts
│   ├── clearCache.ts
│   ├── uTools/
│   │   └── webviewBaseController.ts
│   └── utils/
│       ├── clipboardImage.ts
│       ├── config.ts
│       ├── dynamicForm.ts
│       ├── editor.ts
│       ├── ejs.ts
│       ├── emitter.ts
│       ├── file.ts
│       ├── json.ts
│       ├── lint.ts
│       ├── material.ts
│       ├── platformIndependent/
│       │   └── json.ts
│       ├── shareData.ts
│       ├── tsx.ts
│       └── uTools.ts
├── tsconfig.compiler.json
├── tsconfig.json
├── uTools/
│   ├── Ask ChatGPT/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON/
│   │   ├── config/
│   │   │   ├── schema.ts
│   │   │   └── template.ejs
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON - Form/
│   │   ├── config/
│   │   │   ├── schema.ts
│   │   │   └── template.ejs
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask ChatGPT-生成 value-label 格式 JSON - Prompt/
│   │   ├── config/
│   │   │   └── schema.ts
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Gemini/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Groq/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Kimi/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Ask Perplexity/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Chat With Form Demo/
│   │   ├── config/
│   │   │   ├── config.json
│   │   │   ├── model.json
│   │   │   └── schema.json
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           ├── controller.ts
│   │           └── main.ts
│   ├── Git 获取当前用户最近一次 Commit 信息/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open ChatGPT/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open ChatGPT-获取命令行命令/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── Open Tldraw/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── TS 类型新增字段 - 根据 YAPI 文档字段格式/
│   │   ├── prompt.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── TS 类型新增字段 - 根据 YAPI 文档字段格式 - 截图/
│   │   ├── README.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── vscode 选中的文件夹/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 中文翻译英文/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 动态表单 demo/
│   │   ├── config/
│   │   │   ├── config.json
│   │   │   ├── model.json
│   │   │   ├── schema.json
│   │   │   └── schema.ts
│   │   ├── script/
│   │   │   ├── index.ts
│   │   │   └── src/
│   │   │       ├── controller.ts
│   │   │       └── main.ts
│   │   └── src/
│   │       ├── api.ts.ejs
│   │       ├── index.vue.ejs
│   │       ├── model.ts.ejs
│   │       ├── presenter.ts.ejs
│   │       ├── service.ts.ejs
│   │       ├── temp.mock.script
│   │       └── temp.mock.type.ejs
│   ├── 截屏并转base64/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT commit - 截图/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/
│   │   ├── config/
│   │   │   └── schema.ts
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 根据当前分支名称创建 GIT commit/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 翻译为驼峰格式-首字母大写/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 翻译为驼峰格式-首字母小写/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 英文翻译中文/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 英文:中文格式的描述转 TS 类型/
│   │   ├── README.md
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   ├── 获取命令行命令/
│   │   └── script/
│   │       ├── index.ts
│   │       └── src/
│   │           └── main.ts
│   └── 设置配置信息/
│       └── script/
│           ├── index.ts
│           └── src/
│               └── main.ts
├── uTools.js
└── uToolsUpload.js
Download .txt
SYMBOL INDEX (264 symbols across 153 files)

FILE: buildMaterials.js
  function getAllFiles (line 8) | function getAllFiles(dirPath) {

FILE: llm/index.js
  method handleChunk (line 83) | handleChunk(data) {

FILE: lowcode-context.d.ts
  type Context (line 3) | interface Context {
  type CompileContext (line 179) | interface CompileContext extends Context {
  type ViewCallContext (line 198) | interface ViewCallContext extends Context {

FILE: materials/blocks/antdv2 增删改查列表页/config/schema.ts
  type PageConfig (line 1) | type PageConfig = {

FILE: materials/blocks/antdv2 增删改查列表页/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/antdv2 增删改查列表页/script/src/main.ts
  function handleOCR (line 13) | async function handleOCR() {
  function handleInitFiltersFromImage (line 33) | async function handleInitFiltersFromImage() {
  function handleInitColumnsFromImage (line 58) | async function handleInitColumnsFromImage() {
  function handleAskChatGPT (line 79) | async function handleAskChatGPT() {
  function handleComplete (line 112) | async function handleComplete() {

FILE: materials/blocks/taro-request/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/vant 表单/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/测试使用 jsx 作为模版引擎/config/schema.ts
  type PageConfig (line 1) | type PageConfig = {

FILE: materials/blocks/测试使用 jsx 作为模版引擎/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/测试使用 jsx 作为模版引擎/script/src/main.ts
  function handleInitFiltersFromImage (line 15) | async function handleInitFiltersFromImage() {
  function handleInitColumnsFromImage (line 41) | async function handleInitColumnsFromImage() {
  function handleAskChatGPT (line 59) | async function handleAskChatGPT() {
  function handleAfterCompile (line 87) | async function handleAfterCompile() {
  function handleComplete (line 102) | async function handleComplete() {

FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/api.ts.template.tsx
  type IProps (line 3) | interface IProps {

FILE: materials/blocks/测试使用 jsx 作为模版引擎/src/model.ts.template.tsx
  type IProps (line 3) | interface IProps {

FILE: materials/blocks/测试脚本/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/测试脚本/script/src/main.ts
  class CompileHandler3c5a281f3af548fda73cb864dd8f452b (line 3) | class CompileHandler3c5a281f3af548fda73cb864dd8f452b {
    method constructor (line 6) | constructor(context: CompileContext) {
    method log (line 10) | log(value: string) {
  class ViewCallHandler3c5a281f3af548fda73cb864dd8f452b (line 15) | class ViewCallHandler3c5a281f3af548fda73cb864dd8f452b {
    method constructor (line 18) | constructor(context: ViewCallContext) {
    method log (line 22) | log(value: string) {
    method showInformationMessage (line 26) | showInformationMessage(msg: string) {
    method intFromOcrText (line 30) | intFromOcrText() {
    method askChatGPT (line 34) | async askChatGPT() {

FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/schema.ts
  type IItems (line 1) | type IItems = {

FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/main.ts
  function handleOCR (line 13) | async function handleOCR() {
  function handleAskChatGPT (line 33) | async function handleAskChatGPT() {
  function handleIntFromClipboardImage (line 63) | async function handleIntFromClipboardImage() {
  function handleComplete (line 113) | async function handleComplete() {

FILE: materials/blocks/现有模块中添加 antdv Form 垂直布局列表/config/schema.ts
  type IItems (line 1) | type IItems = {

FILE: materials/blocks/现有模块中添加 antdv Form 垂直布局列表/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/现有模块中添加 antdv Form 垂直布局列表/script/src/main.ts
  function handleOCR (line 13) | async function handleOCR() {
  function handleRunScript (line 84) | async function handleRunScript() {
  function handleComplete (line 90) | async function handleComplete() {

FILE: materials/blocks/现有模块中添加 antdv Form 表单/config/schema.ts
  type IFormItems (line 1) | type IFormItems = {

FILE: materials/blocks/现有模块中添加 antdv Form 表单/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/现有模块中添加 antdv Form 表单/script/src/main.ts
  function handleOCR (line 9) | async function handleOCR() {
  function handleRunScript (line 80) | async function handleRunScript() {
  function handleComplete (line 86) | async function handleComplete() {

FILE: materials/blocks/现有模块中添加 antdv Modal 弹框/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/现有模块中添加 antdv Modal 弹框/script/src/main.ts
  function handleComplete (line 7) | async function handleComplete() {

FILE: materials/blocks/现有模块中添加 antdv Table 表格/config/schema.ts
  type IColumns (line 1) | type IColumns = {

FILE: materials/blocks/现有模块中添加 antdv Table 表格/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/现有模块中添加 antdv Table 表格/script/src/main.ts
  function handleOCR (line 13) | async function handleOCR() {
  function handleAskChatGPT (line 33) | async function handleAskChatGPT() {
  function handleIntColumnsFromClipboardImage (line 65) | async function handleIntColumnsFromClipboardImage() {
  function handleInsertPlaceholder (line 104) | async function handleInsertPlaceholder() {
  function handleComplete (line 128) | async function handleComplete() {

FILE: materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/script/src/main.ts
  class CompileHandlerb9e78736b4ba410186eabffd9a749388 (line 9) | class CompileHandlerb9e78736b4ba410186eabffd9a749388 {
    method constructor (line 12) | constructor(context: CompileContext) {
    method log (line 16) | log(value: string) {
    method updateModel (line 20) | updateModel() {
  class ViewCallHandlerb9e78736b4ba410186eabffd9a749388 (line 74) | class ViewCallHandlerb9e78736b4ba410186eabffd9a749388 {
    method constructor (line 77) | constructor(context: ViewCallContext) {
    method log (line 81) | log(value: string) {
    method intFromOcrText (line 85) | intFromOcrText() {

FILE: materials/blocks/通过脚本启动一个 nest api 服务/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.controller.ts
  class AppController (line 5) | class AppController {
    method constructor (line 6) | constructor(private readonly appService: AppService) {}
    method getHello (line 9) | getHello(): string {

FILE: materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.module.ts
  class AppModule (line 16) | class AppModule {}

FILE: materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.service.ts
  class AppService (line 5) | class AppService {
    method getHello (line 6) | getHello(): string {

FILE: materials/blocks/通过脚本启动一个 nest api 服务/script/src/main.ts
  function bootstrap (line 5) | async function bootstrap() {

FILE: materials/snippets/OCR + ChatGPT 翻译/config/schema.ts
  type IColumns (line 1) | type IColumns = {

FILE: materials/snippets/OCR + ChatGPT 翻译/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/OCR + ChatGPT 翻译/script/src/main.ts
  function bootstrap (line 9) | async function bootstrap() {

FILE: materials/snippets/OCR/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/OCR/script/src/main.ts
  function bootstrap (line 5) | async function bootstrap() {

FILE: materials/snippets/Pro Chat + Tldraw/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/Pro Chat + Tldraw/script/src/controller.ts
  constant API_KEY (line 8) | const API_KEY = 'lowcode.GeminiKey';
  type Message (line 22) | type Message = (
  function setApiKey (line 114) | async function setApiKey(context) {

FILE: materials/snippets/Pro Chat + Tldraw/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: materials/snippets/Pro Chat + TypeChat/config/schema.ts
  type IOption (line 1) | type IOption = { value: string; label: string }[];

FILE: materials/snippets/Pro Chat + TypeChat/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/Pro Chat + TypeChat/script/src/main.ts
  function bootstrap (line 10) | async function bootstrap() {

FILE: materials/snippets/Pro Chat/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/Pro Chat/script/src/controller.ts
  constant API_KEY (line 8) | const API_KEY = 'lowcode.GeminiKey';
  type Message (line 10) | type Message = (
  function setApiKey (line 103) | async function setApiKey(context) {

FILE: materials/snippets/Pro Chat/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: materials/snippets/amis/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/axios-request-api-外挂脚本/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/axios-request-api-外挂脚本/script/src/genCode/genCodeByYapi.ts
  function fixSchema (line 166) | function fixSchema(obj: object, fieldNames: string[]) {

FILE: materials/snippets/axios-request-api-外挂脚本/script/src/main.ts
  function bootstrap (line 3) | async function bootstrap() {

FILE: materials/snippets/axios-request-api-外挂脚本/script/src/utils/config.ts
  type Config (line 12) | type Config = {

FILE: materials/snippets/axios-request-api-外挂脚本/script/src/utils/ejs.ts
  type YapiInfo (line 3) | type YapiInfo = {
  type Model (line 19) | type Model = {

FILE: materials/snippets/axios-request-api-外挂脚本/script/src/utils/request.ts
  type IApiDetailInfo (line 11) | interface IApiDetailInfo {

FILE: materials/snippets/axios-request-api/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/axios-request/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/form-render/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/formily/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/share ChatGPT 测试/config/schema.ts
  type IColumns (line 1) | type IColumns = {

FILE: materials/snippets/share ChatGPT 测试/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/share ChatGPT 测试/script/src/main.ts
  function bootstrap (line 44) | async function bootstrap() {

FILE: materials/snippets/start nest api server/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/start nest api server/script/src/app.controller.ts
  class AppController (line 5) | class AppController {
    method constructor (line 6) | constructor(private readonly appService: AppService) {}
    method getMaterialPath (line 9) | getMaterialPath() {

FILE: materials/snippets/start nest api server/script/src/app.module.ts
  class AppModule (line 16) | class AppModule {}

FILE: materials/snippets/start nest api server/script/src/app.service.ts
  class AppService (line 5) | class AppService {
    method getMaterialPath (line 6) | getMaterialPath() {

FILE: materials/snippets/start nest api server/script/src/main.ts
  function bootstrap (line 5) | async function bootstrap() {

FILE: materials/snippets/taro-request-api/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/umi-request-api/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/动态表单 demo/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/动态表单 demo/script/src/controller.ts
  type RunDynamicFormScript (line 5) | type RunDynamicFormScript = (

FILE: materials/snippets/动态表单 demo/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: materials/snippets/当前目录翻译成英文/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/当前目录翻译成英文/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: materials/snippets/快速创建区块/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/快速创建区块/script/src/main.ts
  function bootstrap (line 7) | async function bootstrap() {

FILE: materials/snippets/快速创建区块/src/uTools 动态表单/config/schema.ts
  type PageConfig (line 1) | type PageConfig = {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp emit/model.ts
  type Model (line 3) | type Model = ReturnType<typeof useModel>;

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp emit/presenter.ts
  type IEmit (line 4) | interface IEmit {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp emit/service.ts
  class Service (line 3) | class Service {
    method constructor (line 6) | constructor(model: Model) {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props emit/model.ts
  type Model (line 3) | type Model = ReturnType<typeof useModel>;

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props emit/presenter.ts
  type IProps (line 4) | interface IProps {
  type IEmit (line 8) | interface IEmit {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props emit/service.ts
  class Service (line 3) | class Service {
    method constructor (line 6) | constructor(model: Model) {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props/model.ts
  type Model (line 3) | type Model = ReturnType<typeof useModel>;

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props/presenter.ts
  type IProps (line 4) | interface IProps {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp props/service.ts
  class Service (line 3) | class Service {
    method constructor (line 6) | constructor(model: Model) {

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp/model.ts
  type Model (line 3) | type Model = ReturnType<typeof useModel>;

FILE: materials/snippets/快速创建区块/src/uniapp/vue3-mvp/service.ts
  class Service (line 3) | class Service {
    method constructor (line 6) | constructor(model: Model) {

FILE: materials/snippets/打开webview/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/打开webview/script/src/controller.ts
  constant API_KEY (line 8) | const API_KEY = 'lowcode.GeminiKey';
  type Message (line 22) | type Message = (
  function setApiKey (line 114) | async function setApiKey(context) {

FILE: materials/snippets/打开webview/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {
  function testScript (line 24) | async function testScript() {

FILE: materials/snippets/根据 DevOps 需求标题创建 GIT commit - 截图/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/根据 DevOps 需求标题创建 GIT commit - 截图/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: materials/snippets/根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/config/schema.ts
  type TaskInfo (line 1) | type TaskInfo = {

FILE: materials/snippets/根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/script/src/main.ts
  function bootstrap (line 9) | async function bootstrap() {

FILE: materials/snippets/根据JSON生成TS类型-将中文字段翻译成英文/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/根据JSON生成TS类型-将中文字段翻译成英文/script/src/main.ts
  function bootstrap (line 4) | async function bootstrap() {

FILE: materials/snippets/根据TS类型生成markdown表格/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/测试 JSONSchemaChat/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/测试 JSONSchemaChat/script/src/main.ts
  function bootstrap (line 7) | async function bootstrap() {

FILE: materials/snippets/测试脚本/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/测试脚本/script/src/main.ts
  function bootstrap (line 3) | async function bootstrap() {
  function onActivate (line 9) | function onActivate() {

FILE: materials/snippets/生成 value-label 格式 JSON/config/schema.ts
  type IOption (line 1) | type IOption = { value: string; label: string }[];

FILE: materials/snippets/生成 value-label 格式 JSON/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/生成 value-label 格式 JSON/script/src/main.ts
  function bootstrap (line 10) | async function bootstrap() {

FILE: materials/snippets/翻译成驼峰格式/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/翻译成驼峰格式/script/src/main.ts
  function bootstrap (line 4) | async function bootstrap() {

FILE: materials/snippets/自动保存活动窗口/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/自动保存活动窗口/script/src/main.ts
  function onActivate (line 5) | function onActivate() {

FILE: materials/snippets/获取当前用户最近一次 Git Commit 信息/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/获取当前用户最近一次 Git Commit 信息/script/src/main.ts
  function bootstrap (line 6) | function bootstrap() {

FILE: materials/snippets/设置配置信息/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/设置配置信息/script/src/controller.ts
  type RunDynamicFormScript (line 7) | type RunDynamicFormScript = (

FILE: materials/snippets/设置配置信息/script/src/main.ts
  function bootstrap (line 5) | async function bootstrap() {

FILE: materials/snippets/通过 TS 类型做字段映射/script/index.js
  function splitStringByLastKeyword (line 4) | function splitStringByLastKeyword(inputString, keyword) {

FILE: materials/snippets/通过 TS 类型做字段映射/script/src/controller.ts
  type RunDynamicFormScript (line 5) | type RunDynamicFormScript = (

FILE: materials/snippets/通过 TS 类型做字段映射/script/src/main.ts
  function bootstrap (line 6) | async function bootstrap() {

FILE: share/BaiduOCR/index.ts
  type IGeneralBasicResult (line 4) | interface IGeneralBasicResult {
  type IGeneralBasicData (line 12) | interface IGeneralBasicData {
  function generalBasic (line 22) | function generalBasic(data: IGeneralBasicData) {
  type IGeneralResult (line 32) | interface IGeneralResult {
  type IGeneralData (line 46) | interface IGeneralData {
  function general (line 57) | function general(data: IGeneralData) {
  type IAccurateBasicResult (line 68) | interface IAccurateBasicResult {
  type IAccurateBasicData (line 76) | interface IAccurateBasicData {
  function accurateBasic (line 84) | function accurateBasic(data: IAccurateBasicData) {
  type IAccurateResult (line 94) | interface IAccurateResult {
  type IAccurateData (line 108) | interface IAccurateData {
  function accurate (line 115) | function accurate(data: IAccurateData) {
  type IDocAnalysisOfficeResult (line 125) | interface IDocAnalysisOfficeResult {
  type IDocAnalysisOfficeData (line 142) | interface IDocAnalysisOfficeData {
  function docAnalysisOffice (line 149) | function docAnalysisOffice(data: IDocAnalysisOfficeData) {

FILE: share/BaiduOCR/request.ts
  type Request (line 41) | type Request = <T = unknown>(config: AxiosRequestConfig) => Promise<T>;

FILE: share/JSONSchemaChat/index.ts
  function translate (line 5) | async function translate<T extends object>(option: {
  function createRepairPrompt (line 73) | function createRepairPrompt(validationError: string) {
  function validate (line 81) | function validate<T extends object>(jsonText: string, schema: string) {
  function stripNulls (line 101) | function stripNulls(obj: any) {

FILE: share/JSONSchemaChat/result.ts
  type Success (line 1) | type Success<T> = { success: true; data: T };
  type Error (line 3) | type Error = { success: false; message: string };
  type Result (line 5) | type Result<T> = Success<T> | Error;
  function success (line 7) | function success<T>(data: T): Success<T> {
  function error (line 11) | function error(message: string): Error {
  function getData (line 15) | function getData<T>(result: Result<T>) {

FILE: share/LLM/gemini.ts
  type Message (line 5) | type Message = (

FILE: share/LLM/index.ts
  constant API_KEY (line 10) | const API_KEY = 'lowcode.GeminiKey';
  type Message (line 12) | type Message = (
  method handleChunk (line 57) | handleChunk(data) {
  method handleChunk (line 79) | handleChunk(data) {
  method handleChunk (line 91) | handleChunk(data) {

FILE: share/LLM/openai.ts
  type ChatGPTConfig (line 9) | type ChatGPTConfig = {

FILE: share/TypeChatSlim/index.ts
  function translate (line 15) | async function translate<T extends object>(option: {
  function createRepairPrompt (line 94) | function createRepairPrompt(validationError: string) {
  function validate (line 102) | function validate<T extends object>(
  function createProgramFromModuleText (line 154) | function createProgramFromModuleText(option: {
  function createFileMapEntry (line 191) | function createFileMapEntry(
  function stripNulls (line 201) | function stripNulls(obj: any) {

FILE: share/TypeChatSlim/result.ts
  type Success (line 1) | type Success<T> = { success: true; data: T };
  type Error (line 3) | type Error = { success: false; message: string };
  type Result (line 5) | type Result<T> = Success<T> | Error;
  function success (line 7) | function success<T>(data: T): Success<T> {
  function error (line 11) | function error(message: string): Error {
  function getData (line 15) | function getData<T>(result: Result<T>) {

FILE: share/TypeChatSlim/utools.ts
  function translate (line 14) | async function translate<T extends object>(option: {
  function createRepairPrompt (line 94) | function createRepairPrompt(validationError: string) {
  function validate (line 102) | function validate<T extends object>(
  function createProgramFromModuleText (line 154) | function createProgramFromModuleText(option: {
  function createFileMapEntry (line 191) | function createFileMapEntry(
  function stripNulls (line 201) | function stripNulls(obj: any) {

FILE: share/WebView/callback.ts
  function invokeCallback (line 3) | function invokeCallback<T = any>(
  function invokeLLMChunkCallback (line 16) | function invokeLLMChunkCallback<T = any>(
  function invokeErrorCallback (line 30) | function invokeErrorCallback(

FILE: share/WebView/controllers/llm.ts
  type LLMMessage (line 7) | type LLMMessage = (
  method handleChunk (line 35) | handleChunk(data) {

FILE: share/WebView/index.ts
  type WebViewKeys (line 8) | type WebViewKeys = 'main' | string;

FILE: share/WebView/type.ts
  type IMessage (line 1) | interface IMessage<T = any> {

FILE: share/clearCache.ts
  function getAllFiles (line 19) | function getAllFiles(dirPath: string) {

FILE: share/uTools/webviewBaseController.ts
  type MethodHandle (line 8) | type MethodHandle = (data: {
  type GetDynamicForm (line 31) | type GetDynamicForm = (data: { scriptFile: string }) => Promise<{
  type LLMMessage (line 46) | type LLMMessage = (
  type AskChatGPTForDynamicFormPageWebviewData (line 67) | type AskChatGPTForDynamicFormPageWebviewData = {
  type AskChatGPTForDynamicFormPage (line 74) | type AskChatGPTForDynamicFormPage = (
  type AskChatGPTData (line 141) | type AskChatGPTData = {
  type AskChatGPT (line 149) | type AskChatGPT = (

FILE: share/utils/config.ts
  type Config (line 6) | type Config = {

FILE: share/utils/ejs.ts
  type YapiInfo (line 6) | type YapiInfo = {
  type Model (line 22) | type Model = {
  function renderEjsTemplates (line 43) | async function renderEjsTemplates(
  function renderFile (line 84) | async function renderFile(

FILE: share/utils/emitter.ts
  type Events (line 3) | type Events = {

FILE: share/utils/lint.ts
  function lint (line 5) | async function lint(option: {

FILE: share/utils/platformIndependent/json.ts
  type Config (line 7) | type Config = {

FILE: share/utils/shareData.ts
  type ShareData (line 7) | type ShareData = {

FILE: share/utils/tsx.ts
  function renderTemplates (line 8) | async function renderTemplates(props: object, templateDir: string) {
  function renderFile (line 42) | async function renderFile(templateFilepath: string, props: object) {

FILE: share/utils/uTools.ts
  type LLMMessage (line 12) | type LLMMessage = (
  method handleChunk (line 50) | handleChunk(chunck) {

FILE: uTools.js
  function getAllFiles (line 9) | function getAllFiles(dirPath) {

FILE: uTools/Ask ChatGPT-生成 value-label 格式 JSON - Form/config/schema.ts
  type IOption (line 1) | type IOption = { value: string; label: string }[];

FILE: uTools/Ask ChatGPT-生成 value-label 格式 JSON - Form/script/src/main.ts
  type LLMMessage (line 34) | type LLMMessage = (

FILE: uTools/Ask ChatGPT-生成 value-label 格式 JSON - Prompt/config/schema.ts
  type IOption (line 1) | type IOption = { value: string; label: string }[];

FILE: uTools/Ask ChatGPT-生成 value-label 格式 JSON/config/schema.ts
  type IOption (line 1) | type IOption = { value: string; label: string }[];

FILE: uTools/Open ChatGPT-获取命令行命令/script/src/main.ts
  type LLMMessage (line 25) | type LLMMessage = (

FILE: uTools/动态表单 demo/config/schema.ts
  type PageConfig (line 1) | type PageConfig = {

FILE: uTools/根据 DevOps 需求标题创建 GIT 分支名 - 截图 - TypeCheck/config/schema.ts
  type TaskInfo (line 1) | type TaskInfo = {

FILE: uToolsUpload.js
  constant OSS (line 2) | const OSS = require('ali-oss');
Condensed preview — 628 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (956K chars).
[
  {
    "path": ".eslintignore",
    "chars": 29,
    "preview": "dist\ngemini.js\ngeminiProxy.js"
  },
  {
    "path": ".eslintrc.js",
    "chars": 1334,
    "preview": "module.exports = {\n  root: true,\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  extends: [\n    'airbnb-base',\n    "
  },
  {
    "path": ".gitattributes",
    "chars": 34,
    "preview": "*.ejs linguist-language=TypeScript"
  },
  {
    "path": ".gitignore",
    "chars": 48,
    "preview": ".DS_Store\nnode_modules/\n.ts-node\n.lowcoderc\ndist"
  },
  {
    "path": ".npmrc",
    "chars": 55,
    "preview": "electron_mirror=https://npmmirror.com/mirrors/electron/"
  },
  {
    "path": ".prettierignore",
    "chars": 9,
    "preview": ".ejs\ndist"
  },
  {
    "path": ".prettierrc.js",
    "chars": 117,
    "preview": "module.exports = {\n  trailingComma: 'all',\n  tabWidth: 2,\n  semi: true,\n  singleQuote: true,\n  endOfLine: 'auto',\n};\n"
  },
  {
    "path": "README.md",
    "chars": 1993,
    "preview": "将项目 clone 到本地,安装依赖,执行 yarn build\n\n## 使用 VSCODE\n\n安装 [lowcode](https://marketplace.visualstudio.com/items?itemName=wjkang."
  },
  {
    "path": "buildMaterials.js",
    "chars": 2569,
    "preview": "const path = require('path');\nconst fs = require('fs-extra');\n/**\n * @description\n * @param {string} dirPath\n * @return "
  },
  {
    "path": "llm/index.js",
    "chars": 2983,
    "preview": "const vscode = require('vscode');\nconst gemini = require('../dist/share/LLM/gemini');\nconst geminiProxy = require('../di"
  },
  {
    "path": "lowcode-context.d.ts",
    "chars": 3849,
    "preview": "import type vscode from 'vscode';\n\ninterface Context {\n  /**\n   * @description 模版数据\n   * @type {object}\n   */\n  model: o"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/config/model.json",
    "chars": 283,
    "preview": "{\n  \"filters\": [],\n  \"columns\": [],\n  \"pagination\": {\n    \"show\": true,\n    \"page\": \"page\",\n    \"size\": \"size\",\n    \"tot"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/config/preview.json",
    "chars": 595,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/config/schema.json",
    "chars": 20212,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"title\": \"\",\n\t\t\t\t\t\"body"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/config/schema.ts",
    "chars": 837,
    "preview": "export type PageConfig = {\n  filters: {\n    component: string;\n    /**\n     * @description 翻译成英文,驼峰格式\n     * @type {stri"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/script/index.js",
    "chars": 3148,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/script/src/main.ts",
    "chars": 6476,
    "preview": "import * as path from 'path';\nimport { window, workspace } from 'vscode';\nimport * as fs from 'fs-extra';\nimport * as ex"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/ModifyModal/index.vue.ejs",
    "chars": 7468,
    "preview": "<template>\n  <a-modal\n    :visible=\"props.visible\"\n    :title=\"props.title\"\n    :width=\"700\"\n    @ok=\"presenter.handleSu"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/ModifyModal/model.ts.ejs",
    "chars": 1734,
    "preview": "import { reactive, ref } from \"vue\";\n<% if(modifyModal.formItems.some(s => (s.type || \"\").indexOf(\"Dayjs\") > -1)) { _%>\n"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/ModifyModal/presenter.ts.ejs",
    "chars": 1575,
    "preview": "import Service from \"./service\";\nimport { useModel } from \"./model\";\nimport { Form, message } from \"ant-design-vue\";\nimp"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/ModifyModal/service.ts.ejs",
    "chars": 1013,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/api.ts.ejs",
    "chars": 3439,
    "preview": "import request from \"@/utils/request\";\n<% if (locals.api) { %>\n// #region <%= api.title %>\n<%= type %>\n\n<% if (api.req_q"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/index.vue.ejs",
    "chars": 4284,
    "preview": "<template>\n  <a-row class=\"filterForm\" :gutter=\"30\">\n    <% filters.map(item => { _%> \n\t\t  <a-col :xs=\"24\" :sm=\"24\" :md="
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/model.ts.ejs",
    "chars": 2691,
    "preview": "import { reactive, ref } from \"vue\";\n<% if(locals.api){ %>\nimport { I<%= funcName.slice(0, 1).toUpperCase() + funcName.s"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/presenter.ts.ejs",
    "chars": 3240,
    "preview": "import Service from \"./service\";\nimport { defaultFormData, useModel } from \"./model\";\nimport { createVNode, onMounted } "
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/service.ts.ejs",
    "chars": 2153,
    "preview": "import { <%= locals.api ? funcName : fetchName %> } from \"./api\";\nimport { Model } from \"./model\"; \n\nexport default clas"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/temp.mock.script.ejs",
    "chars": 117,
    "preview": ".get(`<%= createBlockPath %>/<%= fetchName %>`, async (ctx, next) => { <%- mockCode %> ctx.body = <%- mockData %>\n})\n"
  },
  {
    "path": "materials/blocks/antdv2 增删改查列表页/src/temp.mock.type.ejs",
    "chars": 375,
    "preview": "{\n  code: number;\n\tmsg: string;\n\t<% if (!pagination.show) { _%>\n\tresult: {\n\t\t<% columns.map((item, index) => { _%>\n\t\t\t<%"
  },
  {
    "path": "materials/blocks/react-mvp 模块/config/model.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/react-mvp 模块/config/preview.json",
    "chars": 185,
    "preview": "{\n\t\"title\": \"react-mvp 模块\",\n\t\"description\": \"react-mvp 模块\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/2020"
  },
  {
    "path": "materials/blocks/react-mvp 模块/config/schema.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/react-mvp 模块/src/index.tsx.ejs",
    "chars": 192,
    "preview": "import React from \"react\";\nimport usePresenter from \"./presenter\";\n\nexport default () => {\n  const presenter = usePresen"
  },
  {
    "path": "materials/blocks/react-mvp 模块/src/model.ts.ejs",
    "chars": 84,
    "preview": "export const useModel = () => {};\n\nexport type Model = ReturnType<typeof useModel>;\n"
  },
  {
    "path": "materials/blocks/react-mvp 模块/src/presenter.tsx.ejs",
    "chars": 239,
    "preview": "import { useModel } from \"./model\";\nimport Service from \"./service\";\n\nconst usePresenter = () => {\n  const model = useMo"
  },
  {
    "path": "materials/blocks/react-mvp 模块/src/service.ts.ejs",
    "chars": 150,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/taro-request/config/model.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/taro-request/config/preview.json",
    "chars": 192,
    "preview": "{\n\t\"title\": \"taro-request\",\n\t\"description\": \"taro-request通用封装\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/"
  },
  {
    "path": "materials/blocks/taro-request/config/schema.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/taro-request/script/index.js",
    "chars": 788,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/taro-request/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/taro-request/script/src/main.ts",
    "chars": 23,
    "preview": "export const main = 1;\n"
  },
  {
    "path": "materials/blocks/taro-request/src/config.ts.ejs",
    "chars": 171,
    "preview": "// 请求连接前缀\nexport const baseUrl =\n  process.env.NODE_ENV === \"production\"\n    ? \"https://xxx.com\"\n    : \"http://localhost"
  },
  {
    "path": "materials/blocks/taro-request/src/index.ts.ejs",
    "chars": 1488,
    "preview": "import * as Taro from \"@tarojs/taro\";\nimport * as queryString from \"query-string\";\nimport { baseUrl } from \"./config\";\ni"
  },
  {
    "path": "materials/blocks/taro-request/src/interceptors.ts.ejs",
    "chars": 878,
    "preview": "import * as Taro from \"@tarojs/taro\";\n\nconst HTTP_STATUS = {\n  SUCCESS: 200,\n  CREATED: 201,\n  ACCEPTED: 202,\n  CLIENT_E"
  },
  {
    "path": "materials/blocks/vant 表单/config/model.json",
    "chars": 20,
    "preview": "{\n\t\"formItems\": []\n}"
  },
  {
    "path": "materials/blocks/vant 表单/config/preview.json",
    "chars": 260,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/vant 表单/config/schema.json",
    "chars": 17302,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"title\": \"\",\n\t\t\t\t\t\"body"
  },
  {
    "path": "materials/blocks/vant 表单/config/viewPrompt.ejs",
    "chars": 68,
    "preview": "<%- model %> \r\n将这段 json 中,中文 key 翻译为英文,使用驼峰语法,\r\n返回翻译后的markdown语法的代码块"
  },
  {
    "path": "materials/blocks/vant 表单/script/index.js",
    "chars": 1929,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/vant 表单/src/index.vue.ejs",
    "chars": 8283,
    "preview": "<template>\n  <van-cell-group inset>\n\t\t<% formItems.map(item => { _%>\n\t\t\t<% if(item.component === \"input\"){ _%>\n\t\t\t\t<van-"
  },
  {
    "path": "materials/blocks/vant 表单/src/model.ts.ejs",
    "chars": 2510,
    "preview": "import { reactive } from 'vue'\n\nexport interface IFormData {\n\t<% formItems.map(item => { _%>\n\t\t<%= item.key %><% if(item"
  },
  {
    "path": "materials/blocks/vant 表单/src/presenter.tsx.ejs",
    "chars": 1568,
    "preview": "import Service from './service'\nimport { useModel } from './model'\n<% if(defineProps){ %>\ninterface IProps {\n  visible: "
  },
  {
    "path": "materials/blocks/vant 表单/src/service.ts.ejs",
    "chars": 338,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/vue-mvp 模块/config/model.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/vue-mvp 模块/config/preview.json",
    "chars": 189,
    "preview": "{\n\t\"title\": \"vue-mvp 模块\",\n\t\"description\": \"vue-mvp 模块\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/2020/11/"
  },
  {
    "path": "materials/blocks/vue-mvp 模块/config/schema.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/vue-mvp 模块/src/index.tsx.ejs",
    "chars": 311,
    "preview": "import { defineComponent } from \"vue\";\nimport { usePresenter } from \"./presenter\";\n\nconst Page = defineComponent({\n  set"
  },
  {
    "path": "materials/blocks/vue-mvp 模块/src/model.ts.ejs",
    "chars": 131,
    "preview": "import { reactive } from \"vue\";\n\nexport const useModel = () => {\n  return {};\n};\n\nexport type Model = ReturnType<typeof "
  },
  {
    "path": "materials/blocks/vue-mvp 模块/src/presenter.ts.ejs",
    "chars": 216,
    "preview": "import Service from \"./service\";\nimport { useModel } from \"./model\";\n\nexport const usePresenter = () => {\n  const model "
  },
  {
    "path": "materials/blocks/vue-mvp 模块/src/service.ts.ejs",
    "chars": 150,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/config/model.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/config/preview.json",
    "chars": 191,
    "preview": "{\n\t\"title\": \"vue2-mvp 模块\",\n\t\"description\": \"vue2-mvp 模块\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/2020/1"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/config/schema.json",
    "chars": 2,
    "preview": "{}"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/src/index.tsx.ejs",
    "chars": 330,
    "preview": "import { defineComponent } from \"@vue/composition-api\";\nimport { usePresenter } from \"./presenter\";\n\nconst Index = defin"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/src/model.ts.ejs",
    "chars": 148,
    "preview": "import { reactive } from \"@vue/composition-api\";\n\nexport const useModel = () => {\n  return {};\n};\n\nexport type Model = R"
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/src/presenter.ts.ejs",
    "chars": 202,
    "preview": "import Service from \"./service\";\nimport { useModel } from \"./model\";\n\nexport const usePresenter = () => {\n  const model "
  },
  {
    "path": "materials/blocks/vue2-mvp 模块/src/service.ts.ejs",
    "chars": 150,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/config/model.json",
    "chars": 283,
    "preview": "{\n  \"filters\": [],\n  \"columns\": [],\n  \"pagination\": {\n    \"show\": true,\n    \"page\": \"page\",\n    \"size\": \"size\",\n    \"tot"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/config/preview.json",
    "chars": 539,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": \"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875.jpg"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/config/schema.json",
    "chars": 19706,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"title\": \"\",\n\t\t\t\t\t\"body"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/config/schema.ts",
    "chars": 837,
    "preview": "export type PageConfig = {\n  filters: {\n    component: string;\n    /**\n     * @description 翻译成英文,驼峰格式\n     * @type {stri"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/config/viewPrompt.ejs",
    "chars": 172,
    "preview": "<%- model %> 将这段 json 中,filters 字段中的 key\r\n字段的值翻译为英文,使用驼峰语法,label、placeholder 字段的值保留中文。columns 字段中的\r\nkey、dataIndex 字段的值翻译"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/script/index.js",
    "chars": 2618,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/script/src/main.ts",
    "chars": 6508,
    "preview": "import * as path from 'path';\nimport { window, env, workspace } from 'vscode';\nimport * as fs from 'fs-extra';\nimport * "
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/index.vue.ejs",
    "chars": 7468,
    "preview": "<template>\n  <a-modal\n    :visible=\"props.visible\"\n    :title=\"props.title\"\n    :width=\"700\"\n    @ok=\"presenter.handleSu"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/model.ts.ejs",
    "chars": 1734,
    "preview": "import { reactive, ref } from \"vue\";\n<% if(modifyModal.formItems.some(s => (s.type || \"\").indexOf(\"Dayjs\") > -1)) { _%>\n"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/presenter.tsx.ejs",
    "chars": 1575,
    "preview": "import Service from \"./service\";\nimport { useModel } from \"./model\";\nimport { Form, message } from \"ant-design-vue\";\nimp"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/ModifyModal/service.ts.ejs",
    "chars": 1013,
    "preview": "import { Model } from \"./model\";\n\nexport default class Service {\n  private model: Model;\n\n  constructor(model: Model) {\n"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/api.ts.ejs",
    "chars": 3294,
    "preview": "import request from \"@/utils/request\";\n<% if (locals.api) { %>\n// #region <%= api.title %>\n<%= type %>\n\n<% if (api.req_q"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/api.ts.template.tsx",
    "chars": 2482,
    "preview": "import React from 'react';\n\ninterface IProps {\n  api?: {\n    title: string;\n    req_query: { name: string }[];\n    req_p"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/index.vue.ejs",
    "chars": 3774,
    "preview": "<template>\n  <a-row :gutter=\"30\">\n    <% filters.map(item => { _%> \n\t\t  <a-col :xs=\"24\" :sm=\"24\" :md=\"12\" :lg=\"12\" :xl=\""
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/model.ts.template.tsx",
    "chars": 4051,
    "preview": "import React from 'react';\n\ninterface IProps {\n  api?: object;\n  funcName: string;\n  fetchName: string;\n  title: string;"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/presenter.tsx.ejs",
    "chars": 2567,
    "preview": "import Service from \"./service\";\nimport { defaultFormData, useModel } from \"./model\";\nimport { createVNode, onMounted } "
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/service.ts.ejs",
    "chars": 1035,
    "preview": "import { <%= locals.api ? funcName : fetchName %> } from \"./api\";\nimport { Model } from \"./model\"; \n\nexport default clas"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/temp.mock.script.ejs",
    "chars": 117,
    "preview": ".get(`<%= createBlockPath %>/<%= fetchName %>`, async (ctx, next) => { <%- mockCode %> ctx.body = <%- mockData %>\n})\n"
  },
  {
    "path": "materials/blocks/测试使用 jsx 作为模版引擎/src/temp.mock.type.ejs",
    "chars": 375,
    "preview": "{\n  code: number;\n\tmsg: string;\n\t<% if (!pagination.show) { _%>\n\tresult: {\n\t\t<% columns.map((item, index) => { _%>\n\t\t\t<%"
  },
  {
    "path": "materials/blocks/测试脚本/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  },
  {
    "path": "materials/blocks/测试脚本/config/preview.json",
    "chars": 323,
    "preview": "{\n\t\"title\": \"测试脚本\",\n\t\"description\": \"测试脚本\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/16045"
  },
  {
    "path": "materials/blocks/测试脚本/config/schema.json",
    "chars": 891,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/blocks/测试脚本/config/viewPrompt.ejs",
    "chars": 68,
    "preview": "<%- model %> \r\n将这段 json 中,中文 key 翻译为英文,使用驼峰语法,\r\n返回翻译后的markdown语法的代码块"
  },
  {
    "path": "materials/blocks/测试脚本/script/index.js",
    "chars": 1751,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/测试脚本/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/测试脚本/script/src/main.ts",
    "chars": 1085,
    "preview": "import { CompileContext, ViewCallContext } from 'lowcode-context';\n\nexport class CompileHandler3c5a281f3af548fda73cb864d"
  },
  {
    "path": "materials/blocks/测试脚本/src/README.md",
    "chars": 20,
    "preview": "在当前文件夹下放区块模板,并将此文件删除"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/model.json",
    "chars": 128,
    "preview": "{\n\t\"items\": [],\n\t\"bordered\": false,\n\t\"extra\": false,\n\t\"layout\": \"horizontal\",\n\t\"variableName\": \"\",\n\t\"title\": \"\",\n\t\"colum"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/preview.json",
    "chars": 497,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/schema.json",
    "chars": 3295,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"title\": \"\",\n\t\t\t\t\t\"body"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/config/schema.ts",
    "chars": 206,
    "preview": "export type IItems = {\n  /**\n   * @description 保持原始内容,不需要处理,不要翻译\n   * @type {string}\n   */\n  label: string;\n  /**\n   * @"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/index.js",
    "chars": 1738,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/script/src/main.ts",
    "chars": 13063,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport * as execa from 'execa';\nimport * as ejs from 'ejs'"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.api.ts.ejs",
    "chars": 832,
    "preview": "// #region\nexport interface IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result {\n  code: "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.index.vue.ejs",
    "chars": 572,
    "preview": "<!-- lowcode-vue-template -->\n<a-descriptions \n\ttitle=\"<%= title %>\" \n\t:bordered=\"<%= bordered %>\"\n\t<% if(column){ _%>\n\t"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.mock.script",
    "chars": 175,
    "preview": ".get(`<%= createBlockPath %>/fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>`, async (ctx, ne"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.mock.type.ejs",
    "chars": 146,
    "preview": "{\n  code: number;\n\tmsg: string;\n\tresult: {\n\t\t<% items.map((item, index) => { _%>\n\t\t\t<%= item.key || `item${index+1}` %>:"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.model.ts.ejs",
    "chars": 794,
    "preview": "// lowcode-model-import-api\nimport { IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result }"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Descriptions 描述列表/src/temp.service.ts.ejs",
    "chars": 545,
    "preview": "// lowcode-service-import-api\nimport {fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>} from '"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/config/model.json",
    "chars": 37,
    "preview": "{\n\t\"items\": [],\n\t\"variableName\": \"\"\n}"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/config/preview.json",
    "chars": 418,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/config/schema.json",
    "chars": 1759,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"id\": \"u:67967afb0e69\","
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/config/schema.ts",
    "chars": 189,
    "preview": "export type IItems = {\n  /**\n   * @description 保持原始内容,不需要处理,不要翻译\n   * @type {string}\n   */\n  label: string;\n  /**\n   * @"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/script/index.js",
    "chars": 1547,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/script/src/main.ts",
    "chars": 10681,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport * as execa from 'execa';\nimport * as ejs from 'ejs'"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.api.ts.ejs",
    "chars": 832,
    "preview": "// #region\nexport interface IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result {\n  code: "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.index.vue.ejs",
    "chars": 294,
    "preview": "<!-- lowcode-vue-template -->\n<a-form :label-col=\"{ span: 4 }\" :wrapper-col=\"{ span: 12 }\">\n\t<% items.map((item, index) "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.mock.script",
    "chars": 175,
    "preview": ".get(`<%= createBlockPath %>/fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>`, async (ctx, ne"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.mock.type.ejs",
    "chars": 146,
    "preview": "{\n  code: number;\n\tmsg: string;\n\tresult: {\n\t\t<% items.map((item, index) => { _%>\n\t\t\t<%= item.key || `item${index+1}` %>:"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.model.ts.ejs",
    "chars": 794,
    "preview": "// lowcode-model-import-api\nimport { IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result }"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 垂直布局列表/src/temp.service.ts.ejs",
    "chars": 545,
    "preview": "// lowcode-service-import-api\nimport {fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>} from '"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/config/model.json",
    "chars": 41,
    "preview": "{\n\t\"variableName\": \"\",\n\t\"formItems\": []\n}"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/config/preview.json",
    "chars": 429,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/config/schema.json",
    "chars": 8397,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"object\",\n\t\t\t\"column\": 1,\n\t\t\t\"labelWidth\": 120,\n\t\t\t\"displayType\": \"column\",\n"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/config/schema.ts",
    "chars": 284,
    "preview": "export type IFormItems = {\n  /**\n   * @description 保持原始内容,不需要处理,不要翻译\n   * @type {string}\n   */\n  label: string;\n  /**\n  "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/script/index.js",
    "chars": 1599,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/script/src/main.ts",
    "chars": 9194,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport { window } from 'vscode';\nimport { generalBasic } f"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/src/temp.index.vue.ejs",
    "chars": 7920,
    "preview": "<!-- lowcode-vue-template -->\n<a-form :label-col=\"{ span: 4 }\" :wrapper-col=\"{ span: 12 }\">\n\t<% formItems.map(item => { "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/src/temp.model.ts.ejs",
    "chars": 2529,
    "preview": "// lowcode-model-type\nexport interface I<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>FormData {\n"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/src/temp.presenter.ts.ejs",
    "chars": 726,
    "preview": "// lowcode-presenter-variable\nconst <%= variableName %>Rules: Record<string, Rule[]> = reactive({\n\t<% formItems.map(item"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Form 表单/src/temp.service.ts.ejs",
    "chars": 285,
    "preview": "// lowcode-service-method\nasync submit<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>() {\n\tconst d"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/config/model.json",
    "chars": 37,
    "preview": "{\n\t\"variableName\": \"\",\n\t\"title\": \"\"\n}"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/config/preview.json",
    "chars": 182,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/config/schema.json",
    "chars": 523,
    "preview": "{\n\t\"type\": \"page\",\n\t\"body\": [\n\t\t{\n\t\t\t\"type\": \"form\",\n\t\t\t\"title\": \"\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"input-text\",\n\t\t\t\t\t"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/script/index.js",
    "chars": 932,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/script/src/context.ts",
    "chars": 359,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { ViewCallContext } from 'lowcode-context';\nimport { StatusBar"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/script/src/main.ts",
    "chars": 5372,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport * as execa from 'execa';\nimport { workspace } from "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/src/temp.index.vue.ejs",
    "chars": 413,
    "preview": "<!-- lowcode-vue-template -->\n<a-modal\n\ttitle=\"<%= title %>\"\n\t:visible=\"model.<%= variableName %>Modal.visible\"\n\t:confir"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/src/temp.model.ts.ejs",
    "chars": 207,
    "preview": "// lowcode-model-variable\nconst <%= variableName %>Modal = reactive<{ visible: boolean; loading: boolean }>({\n\tvisible: "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Modal 弹框/src/temp.presenter.ts.ejs",
    "chars": 652,
    "preview": "// lowcode-presenter-handle\nconst handleToggle<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Modal"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/config/model.json",
    "chars": 178,
    "preview": "{\n\t\"pagination\": {\n\t\t\"show\": true,\n\t\t\"page\": \"page\",\n\t\t\"size\": \"size\",\n\t\t\"total\": \"result.total\"\n\t},\n\t\"result\": \"[\\\"resu"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/config/preview.json",
    "chars": 510,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/config/schema.json",
    "chars": 15373,
    "preview": "{\n\t\"formSchema\": {\n\t\t\"schema\": {\n\t\t\t\"type\": \"page\",\n\t\t\t\"body\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"form\",\n\t\t\t\t\t\"title\": \"\",\n\t\t\t\t\t\"body"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/config/schema.ts",
    "chars": 290,
    "preview": "export type IColumns = {\n  /**\n   * @description 保持原始内容,不需要处理,不要翻译\n   * @type {string}\n   */\n  title: string;\n  /**\n   *"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/script/index.js",
    "chars": 1983,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/script/src/context.ts",
    "chars": 359,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { ViewCallContext } from 'lowcode-context';\nimport { StatusBar"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/script/src/main.ts",
    "chars": 16001,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport * as execa from 'execa';\nimport * as ejs from 'ejs'"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.api.ts.ejs",
    "chars": 1196,
    "preview": "// #region\nexport interface IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result {\n  code: "
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.index.vue.ejs",
    "chars": 1504,
    "preview": "<!-- lowcode-vue-template -->\n<a-table\n\t:columns=\"<%= variableName %>TableColumns\"\n\t:data-source=\"model.<%= variableName"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.mock.script.ejs",
    "chars": 175,
    "preview": ".get(`<%= createBlockPath %>/fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>`, async (ctx, ne"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.mock.type.ejs",
    "chars": 375,
    "preview": "{\n  code: number;\n\tmsg: string;\n\t<% if (!pagination.show) { _%>\n\tresult: {\n\t\t<% columns.map((item, index) => { _%>\n\t\t\t<%"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.model.ts.ejs",
    "chars": 1059,
    "preview": "// lowcode-model-import-api\nimport { IFetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>Result }"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.presenter.ts.ejs",
    "chars": 742,
    "preview": "  // lowcode-presenter-handlePageChange\n\t<% if(pagination.show) { _%>\n  const handle<%= variableName.slice(0, 1).toUpper"
  },
  {
    "path": "materials/blocks/现有模块中添加 antdv Table 表格/src/temp.service.ts.ejs",
    "chars": 700,
    "preview": "// lowcode-service-import-api\nimport {fetch<%= variableName.slice(0, 1).toUpperCase() + variableName.slice(1) %>} from '"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/config/preview.json",
    "chars": 294,
    "preview": "{\n\t\"title\": \"通过 ast 给 antdv Descriptions 描述列表添加字段\",\n\t\"description\": \"现有模块必须是遵循整洁架构的目录结构,否则无法使用\",\n\t\"img\": [\n\t\t\"https://gi"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/config/schema.json",
    "chars": 891,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/config/viewPrompt.ejs",
    "chars": 68,
    "preview": "<%- model %> \r\n将这段 json 中,中文 key 翻译为英文,使用驼峰语法,\r\n返回翻译后的markdown语法的代码块"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/script/index.js",
    "chars": 1681,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/script/src/main.ts",
    "chars": 2358,
    "preview": "import path from 'path';\nimport * as typescriptParse from 'recast/parsers/typescript';\nimport * as recast from 'recast';"
  },
  {
    "path": "materials/blocks/通过 ast 给 antdv Descriptions 描述列表添加字段/src/README.md",
    "chars": 20,
    "preview": "在当前文件夹下放区块模板,并将此文件删除"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/config/model.json",
    "chars": 36,
    "preview": "{\n  \"name\": \"通过脚本启动一个 nest api 服务\"\n}"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/config/preview.json",
    "chars": 317,
    "preview": "{\n  \"title\": \"通过脚本启动一个 nest api 服务\",\n  \"description\": \"通过脚本启动一个 nest api 服务\",\n  \"img\": [\n    \"https://gitee.com/img-host"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/config/schema.json",
    "chars": 891,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/config/viewPrompt.ejs",
    "chars": 68,
    "preview": "<%- model %> \r\n将这段 json 中,中文 key 翻译为英文,使用驼峰语法,\r\n返回翻译后的markdown语法的代码块"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/index.js",
    "chars": 985,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.controller.ts",
    "chars": 274,
    "preview": "import { Controller, Get } from '@nestjs/common';\nimport { AppService } from './app.service';\n\n@Controller()\nexport clas"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.module.ts",
    "chars": 407,
    "preview": "import { Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { AppController } from '."
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/src/app.service.ts",
    "chars": 219,
    "preview": "import { Injectable } from '@nestjs/common';\nimport { context } from './context';\n\n@Injectable()\nexport class AppService"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/src/context.ts",
    "chars": 359,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { ViewCallContext } from 'lowcode-context';\nimport { StatusBar"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/script/src/main.ts",
    "chars": 1979,
    "preview": "import { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { context } from './context"
  },
  {
    "path": "materials/blocks/通过脚本启动一个 nest api 服务/src/README.md",
    "chars": 20,
    "preview": "在当前文件夹下放区块模板,并将此文件删除"
  },
  {
    "path": "materials/snippets/OCR/config/commandPrompt.ejs",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "materials/snippets/OCR/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  },
  {
    "path": "materials/snippets/OCR/config/preview.json",
    "chars": 306,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/snippets/OCR/config/schema.json",
    "chars": 682,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/snippets/OCR/script/index.js",
    "chars": 905,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/snippets/OCR/script/src/context.ts",
    "chars": 359,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { ViewCallContext } from 'lowcode-context';\nimport { StatusBar"
  },
  {
    "path": "materials/snippets/OCR/script/src/main.ts",
    "chars": 966,
    "preview": "import { window, Range, env } from 'vscode';\nimport { generalBasic } from '@share/BaiduOCR/index';\nimport { context } fr"
  },
  {
    "path": "materials/snippets/OCR/src/template.ejs",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/config/preview.json",
    "chars": 306,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/config/schema.json",
    "chars": 682,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/config/schema.ts",
    "chars": 384,
    "preview": "export type IColumns = {\n  /**\n   * @description 保持原始内容,不需要处理,不要翻译\n   * @type {string}\n   */\n  title: string;\n  /**\n   *"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/script/index.js",
    "chars": 931,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/script/src/main.ts",
    "chars": 2090,
    "preview": "import * as path from 'path';\nimport * as fs from 'fs-extra';\nimport { window, Range } from 'vscode';\nimport { generalBa"
  },
  {
    "path": "materials/snippets/OCR + ChatGPT 翻译/src/template.ejs",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "materials/snippets/Pro Chat/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  },
  {
    "path": "materials/snippets/Pro Chat/config/preview.json",
    "chars": 306,
    "preview": "{\n\t\"title\": \"\",\n\t\"description\": \"\",\n\t\"img\": [\n\t\t\"https://gitee.com/img-host/img-host/raw/master/2020/11/05/1604587962875"
  },
  {
    "path": "materials/snippets/Pro Chat/config/schema.json",
    "chars": 682,
    "preview": "{\n  \"formSchema\": {\n    \"schema\": {\n      \"type\": \"page\",\n      \"body\": [\n        {\n          \"type\": \"form\",\n          "
  },
  {
    "path": "materials/snippets/Pro Chat/script/index.js",
    "chars": 915,
    "preview": "const path = require('path');\nconst moduleAlias = require('module-alias');\n\nfunction splitStringByLastKeyword(inputStrin"
  },
  {
    "path": "materials/snippets/Pro Chat/script/src/context.ts",
    "chars": 357,
    "preview": "import { INestApplication } from '@nestjs/common';\nimport { CompileContext } from 'lowcode-context';\nimport { StatusBarI"
  },
  {
    "path": "materials/snippets/Pro Chat/script/src/controller.ts",
    "chars": 2947,
    "preview": "import * as vscode from 'vscode';\nimport { CompileContext } from 'lowcode-context';\nimport { createChatCompletion } from"
  },
  {
    "path": "materials/snippets/Pro Chat/script/src/main.ts",
    "chars": 2021,
    "preview": "import { window } from 'vscode';\nimport { showWebView } from '@share/WebView';\nimport { routes } from './routes';\nimport"
  },
  {
    "path": "materials/snippets/Pro Chat/script/src/routes.ts",
    "chars": 165,
    "preview": "import * as controller from './controller';\n\nexport const routes: Record<string, any> = {\n  askGemini: controller.askGem"
  },
  {
    "path": "materials/snippets/Pro Chat + Tldraw/config/model.json",
    "chars": 23,
    "preview": "{\n  \"name\": \"lowcode\"\n}"
  }
]

// ... and 428 more files (download for full content)

About this extraction

This page contains the full source code of the lowcode-scaffold/lowcode-materials GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 628 files (756.5 KB), approximately 258.9k tokens, and a symbol index with 264 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!