worsoft-frontend-codegen-local-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/MVP_DESIGN.md ADDED
@@ -0,0 +1,78 @@
1
+ # MVP Design
2
+
3
+ ## Goal
4
+
5
+ Build a parallel MCP plugin that generates frontend files from:
6
+ - local Markdown design docs
7
+ - local template assets
8
+ - style-based template selection
9
+
10
+ without depending on the Worsoft backend generation API.
11
+
12
+ ## First Supported Flow
13
+
14
+ 1. Read `designFile` or fall back to `plugins/sql/SQL 设计说明.md`
15
+ 2. Parse one table definition by `tableName`
16
+ 3. Load style metadata from `assets/style-catalog.json`
17
+ 4. Resolve the shared template selection for the requested `style`
18
+ 5. Build a normalized metadata model
19
+ 6. For `master_child_jump`, infer the child relation from the design doc when possible
20
+ 7. Map parsed fields into simple frontend field types
21
+ 8. Render plugin-local runtime templates when the style is implemented
22
+ 9. Return a render manifest
23
+ 10. Optionally write files
24
+
25
+ ## Declared Styles
26
+
27
+ - `single_table_jump`
28
+ - `single_table_dialog`
29
+ - `master_child_jump`
30
+
31
+ ## Runtime-Implemented Styles
32
+
33
+ - `single_table_jump`
34
+ - `single_table_dialog`
35
+ - `master_child_jump`
36
+
37
+ ## Metadata Model
38
+
39
+ ```json
40
+ {
41
+ "tableName": "iwm_sys_trade",
42
+ "className": "IwmSysTrade",
43
+ "functionName": "iwmSysTrade",
44
+ "moduleName": "admin/test",
45
+ "pk": { "fieldName": "id", "attrName": "id" },
46
+ "fields": [
47
+ {
48
+ "fieldName": "trade_name",
49
+ "attrName": "tradeName",
50
+ "sqlType": "VARCHAR",
51
+ "comment": "Trade Name",
52
+ "formType": "text",
53
+ "isAudit": false
54
+ }
55
+ ]
56
+ }
57
+ ```
58
+
59
+ ## Master-Child Contract
60
+
61
+ When `style=master_child_jump`, local mode now prefers the Markdown design file contract:
62
+ - parse child relations from the "主从表关联说明" section
63
+ - auto-resolve `mainField` and `childField`
64
+ - require `childTableName` only when one main table has multiple child relations
65
+
66
+ ## Risks
67
+
68
+ - Existing shared templates use Velocity syntax and need a larger rendering engine.
69
+ - Markdown design docs may drift from the real schema if they are not maintained.
70
+ - Query/list/form metadata inference is heuristic in local mode.
71
+ - Multi-child relations still need explicit disambiguation.
72
+
73
+ ## Next Steps
74
+
75
+ 1. Add query/grid heuristics
76
+ 2. Add dict config sidecar file support
77
+ 3. Decide whether to migrate shared templates into a neutral local template format
78
+ 4. Consider cross-checking Markdown definitions against SQL or DB metadata
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # Worsoft Frontend Codegen Local MCP
2
+
3
+ This plugin is a parallel local-template MVP for frontend code generation.
4
+ It does not call `/admin/generator/mcp/execute`.
5
+
6
+ ## MVP Scope
7
+
8
+ - local Markdown design file input
9
+ - style-based template selection
10
+ - local template rendering
11
+ - single-table runtime generation
12
+ - master-child runtime generation with relation inference from the design file
13
+ - render plan preview
14
+ - optional write-to-disk
15
+
16
+ ## Current Inputs
17
+
18
+ - `designFile` : optional, defaults to `../sql/SQL 设计说明.md`
19
+ - `tableName`
20
+ - `style`
21
+ - `frontendPath`
22
+ - `moduleName`
23
+ - `writeToDisk`
24
+ - `childTableName` when `style=master_child_jump` : optional, only needed when one main table has multiple child-table relations in the design file
25
+
26
+ ## Recommended MCP Arguments
27
+
28
+ Use `designFile` as the source argument.
29
+
30
+ ```json
31
+ {
32
+ "tableName": "iwm_sys_trade",
33
+ "style": "master_child_jump",
34
+ "designFile": "plugins/sql/SQL 设计说明.md",
35
+ "frontendPath": "E:/own-worker-platform/trunk/worsoft-ui",
36
+ "moduleName": "admin/test",
37
+ "writeToDisk": false
38
+ }
39
+ ```
40
+
41
+ ## Smoke Test Template
42
+
43
+ Use `smoke_test_mcp.js` for quick local MCP verification.
44
+
45
+ PowerShell is the recommended option on Windows because it does not depend on Node spawning a child Node process.
46
+
47
+ ```bash
48
+ node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario single
49
+ node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario master
50
+ node plugins/worsoft-codegen-local/smoke_test_mcp.js --scenario child
51
+ ```
52
+
53
+ ```powershell
54
+ powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario single
55
+ powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario master
56
+ powershell -ExecutionPolicy Bypass -File plugins/worsoft-codegen-local/smoke_test_mcp.ps1 -Scenario child
57
+ ```
58
+
59
+ Optional overrides:
60
+
61
+ - `--design-file`
62
+ - `--table-name`
63
+ - `--style`
64
+ - `--child-table-name`
65
+ - `--frontend-path`
66
+ - `--write-to-disk`
67
+
68
+ For `master_child_jump`, the execution result will return the detected relation. If the relation is ambiguous or not the one you want, the MCP error/result includes a `correctionEntry` with `childTableName`, `example`, and `retryArguments`, so the caller can resubmit directly.
69
+
70
+ When one main table has multiple child relations in the design file, add `childTableName` to disambiguate:
71
+
72
+ ```json
73
+ {
74
+ "tableName": "iwm_sys_trade_level",
75
+ "style": "master_child_jump",
76
+ "designFile": "plugins/sql/SQL 设计说明.md",
77
+ "childTableName": "iwm_sys_trade_level_standard",
78
+ "frontendPath": "E:/own-worker-platform/trunk/worsoft-ui",
79
+ "writeToDisk": false
80
+ }
81
+ ```
82
+
83
+ ## Current Outputs
84
+
85
+ - `src/views/<module>/<function>/index.vue`
86
+ - `src/views/<module>/<function>/form.vue`
87
+ - `src/views/<module>/<function>/options.ts`
88
+ - `src/api/<module>/<function>.ts`
89
+ - `menu/<function>_menu.sql`
90
+
91
+ ## Style Catalog
92
+
93
+ - Human guide: `STYLE_TEMPLATE_GUIDE.md`
94
+ - Machine source: `assets/style-catalog.json`
95
+
96
+ Declared styles:
97
+ - `single_table_jump`
98
+ - `single_table_dialog`
99
+ - `master_child_jump`
100
+
101
+ Runtime generation support:
102
+ - `single_table_jump`: supported
103
+ - `single_table_dialog`: supported
104
+ - `master_child_jump`: supported
105
+
106
+ ## Non-goals for v0.1
107
+
108
+ - backend API forwarding
109
+ - generic Velocity rendering
110
+ - dict lookup from backend
111
+ - full compatibility with the old generator contract
112
+
113
+ ## Notes
114
+
115
+ - Shared Worsoft template references live under `../template`.
116
+ - Plugin-local runtime assets live under `assets/templates`.
117
+ - The preferred source is `plugins/sql/SQL 设计说明.md`.
118
+ - Markdown mode parses both the field-definition tables and the "主从表关联说明" section.
119
+ - When a main table has multiple child relations, provide `childTableName` to disambiguate.
120
+ - Menu SQL is currently emitted to `frontendPath/menu/` because local mode does not accept `backendPath` yet.
121
+ - The renderer uses a simple placeholder engine instead of the old backend template engine.
@@ -0,0 +1,71 @@
1
+ {
2
+ "single_table_jump": {
3
+ "id": "single_table_jump",
4
+ "label": "单表跳转模板",
5
+ "description": "单表跳转页面,使用单表 form 和跳转列表模板。",
6
+ "templateFiles": {
7
+ "api": "api.md",
8
+ "options": "options.md",
9
+ "form": "单主表单跳转方式.md",
10
+ "list": "主子表单跳转列表.md",
11
+ "menuSql": "权限菜单V2025001.md"
12
+ },
13
+ "runtime": {
14
+ "supported": true,
15
+ "templateDir": "assets/templates/single_table_jump",
16
+ "files": {
17
+ "api": "api.tpl",
18
+ "options": "options.tpl",
19
+ "form": "form.tpl",
20
+ "list": "index.tpl",
21
+ "menuSql": "menu.sql.tpl"
22
+ }
23
+ }
24
+ },
25
+ "single_table_dialog": {
26
+ "id": "single_table_dialog",
27
+ "label": "单表弹窗模板",
28
+ "description": "单表弹窗页面,使用弹窗 form 和通用表格模板。",
29
+ "templateFiles": {
30
+ "api": "api.md",
31
+ "options": "options.md",
32
+ "form": "表单V2025001.md",
33
+ "list": "表格V2025001.md",
34
+ "menuSql": "权限菜单V2025001.md"
35
+ },
36
+ "runtime": {
37
+ "supported": true,
38
+ "templateDir": "assets/templates/single_table_dialog",
39
+ "files": {
40
+ "api": "api.tpl",
41
+ "options": "options.tpl",
42
+ "form": "form.tpl",
43
+ "list": "index.tpl",
44
+ "menuSql": "menu.sql.tpl"
45
+ }
46
+ }
47
+ },
48
+ "master_child_jump": {
49
+ "id": "master_child_jump",
50
+ "label": "主子表前端跳转类型",
51
+ "description": "主子表跳转页面,使用主子表 form 和主子表列表模板。",
52
+ "templateFiles": {
53
+ "api": "api.md",
54
+ "options": "options.md",
55
+ "form": "主子表单跳转方式.md",
56
+ "list": "主子表单跳转列表.md",
57
+ "menuSql": "权限菜单V2025001.md"
58
+ },
59
+ "runtime": {
60
+ "supported": true,
61
+ "templateDir": "assets/templates/master_child_jump",
62
+ "files": {
63
+ "api": "api.tpl",
64
+ "options": "options.tpl",
65
+ "form": "form.tpl",
66
+ "list": "index.tpl",
67
+ "menuSql": "menu.sql.tpl"
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,49 @@
1
+ import request from '/@/utils/request';
2
+
3
+ export function fetchList(query?: object) {
4
+ return request({
5
+ url: '/{{API_PATH}}/page',
6
+ method: 'get',
7
+ params: query,
8
+ });
9
+ }
10
+
11
+ export function addObj(obj?: object) {
12
+ return request({
13
+ url: '/{{API_PATH}}',
14
+ method: 'post',
15
+ data: obj,
16
+ });
17
+ }
18
+
19
+ export function getObj(obj?: object) {
20
+ return request({
21
+ url: '/{{API_PATH}}/details',
22
+ method: 'get',
23
+ params: obj,
24
+ });
25
+ }
26
+
27
+ export function delObjs(ids?: object) {
28
+ return request({
29
+ url: '/{{API_PATH}}',
30
+ method: 'delete',
31
+ data: ids,
32
+ });
33
+ }
34
+
35
+ export function putObj(obj?: object) {
36
+ return request({
37
+ url: '/{{API_PATH}}',
38
+ method: 'put',
39
+ data: obj,
40
+ });
41
+ }
42
+
43
+ export function delChildObj(ids?: object) {
44
+ return request({
45
+ url: '/{{API_PATH}}/child',
46
+ method: 'delete',
47
+ data: ids,
48
+ });
49
+ }
@@ -0,0 +1,130 @@
1
+ <template>
2
+ <div class="layout-padding-auto layout-padding-view">
3
+ <el-card shadow="never">
4
+ <template #header>
5
+ <span>{{ form.{{PK_ATTR}} ? (detail ? 'Detail' : 'Edit') : 'Add' }}</span>
6
+ </template>
7
+ <el-form ref="dataFormRef" :model="form" :rules="dataRules" :disabled="detail" v-loading="loading">
8
+ <el-row :gutter="24">
9
+ {{FORM_FIELDS}}
10
+ </el-row>
11
+ <el-row :gutter="24">
12
+ <sc-form-table v-model="form.{{CHILD_LIST_NAME}}" :addTemplate="childTemp" @delete="deleteChild" placeholder="No data">
13
+ {{CHILD_TABLE_COLUMNS}}
14
+ </sc-form-table>
15
+ </el-row>
16
+ </el-form>
17
+ <div class="dialog-footer" style="text-align: right; margin-top: 18px;">
18
+ <el-button @click="handleBack">Cancel</el-button>
19
+ <el-button type="primary" @click="onSubmit" :disabled="loading">Confirm</el-button>
20
+ </div>
21
+ </el-card>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup lang="ts" name="{{CLASS_NAME}}Form">
26
+ import mittBus from '/@/utils/mitt';
27
+ import { useMessage } from '/@/hooks/message';
28
+ import { getObj, addObj, putObj, delChildObj } from '/@/api/{{API_MODULE_PATH}}';
29
+ {{DICT_IMPORT_BLOCK}}
30
+
31
+ const scFormTable = defineAsyncComponent(() => import('/@/components/FormTable/index.vue'));
32
+ const route = useRoute();
33
+ const router = useRouter();
34
+
35
+ const dataFormRef = ref();
36
+ const loading = ref(false);
37
+ const detail = ref(false);
38
+
39
+ const form = reactive({
40
+ {{FORM_DEFAULTS}}
41
+ {{CHILD_LIST_NAME}}: [],
42
+ });
43
+
44
+ const childTemp = reactive({
45
+ {{CHILD_TEMP_DEFAULTS}}
46
+ });
47
+
48
+ const dataRules = ref({
49
+ {{FORM_RULES}}
50
+ });
51
+
52
+ const get{{CLASS_NAME}}Data = async (id: string) => {
53
+ try {
54
+ loading.value = true;
55
+ const { data } = await getObj({ {{PK_ATTR}}: id });
56
+ Object.assign(form, data[0] || {});
57
+ } catch (error) {
58
+ useMessage().error('Failed to fetch data');
59
+ } finally {
60
+ loading.value = false;
61
+ }
62
+ };
63
+
64
+ const resetFormState = () => {
65
+ Object.assign(form, {
66
+ {{FORM_DEFAULTS}}
67
+ {{CHILD_LIST_NAME}}: [],
68
+ });
69
+ nextTick(() => {
70
+ dataFormRef.value?.resetFields();
71
+ form.{{CHILD_LIST_NAME}} = [];
72
+ });
73
+ };
74
+
75
+ const initPage = async () => {
76
+ const id = route.query.id as string;
77
+ const isDetail = route.query.detail === 'true' || route.query.detail === '1';
78
+
79
+ detail.value = isDetail;
80
+ resetFormState();
81
+
82
+ if (id) {
83
+ form.{{PK_ATTR}} = id;
84
+ await get{{CLASS_NAME}}Data(id);
85
+ }
86
+ };
87
+
88
+ const closeCurrentPage = () => {
89
+ mittBus.emit('onCurrentContextmenuClick', { contextMenuClickId: 1, ...route });
90
+ };
91
+
92
+ const handleBack = () => {
93
+ router.back();
94
+ };
95
+
96
+ const onSubmit = async () => {
97
+ loading.value = true;
98
+
99
+ const valid = await dataFormRef.value.validate().catch(() => {});
100
+ if (!valid) {
101
+ loading.value = false;
102
+ return false;
103
+ }
104
+
105
+ try {
106
+ form.{{PK_ATTR}} ? await putObj(form) : await addObj(form);
107
+ useMessage().success(form.{{PK_ATTR}} ? 'Updated successfully' : 'Created successfully');
108
+ closeCurrentPage();
109
+ } catch (err: any) {
110
+ useMessage().error(err.msg || 'Submit failed');
111
+ } finally {
112
+ loading.value = false;
113
+ }
114
+ };
115
+
116
+ const deleteChild = async (obj: { {{CHILD_PK_ATTR}}: string }) => {
117
+ if (obj.{{CHILD_PK_ATTR}}) {
118
+ try {
119
+ await delChildObj([obj.{{CHILD_PK_ATTR}}]);
120
+ useMessage().success('Deleted successfully');
121
+ } catch (err: any) {
122
+ useMessage().error(err.msg || 'Delete failed');
123
+ }
124
+ }
125
+ };
126
+
127
+ onMounted(() => {
128
+ initPage();
129
+ });
130
+ </script>
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div class="layout-padding">
3
+ <div class="layout-padding-auto layout-padding-view">
4
+ <el-row>
5
+ <div class="mb8" style="width: 100%">
6
+ <el-button icon="folder-add" type="primary" class="ml10" v-auth="'{{PERMISSION_PREFIX}}_add'" @click="handleCreate">新增</el-button>
7
+ <el-button plain icon="upload-filled" type="primary" class="ml10" v-auth="'{{PERMISSION_PREFIX}}_add'" @click="excelUploadRef.show()">导入</el-button>
8
+ <el-button plain :disabled="multiple" icon="Delete" type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete(selectObjs)">删除</el-button>
9
+ <right-toolbar v-model:showSearch="showSearch" :export="'{{PERMISSION_PREFIX}}_export'" @exportExcel="exportExcel" @queryTable="getDataList" class="ml10 mr20" style="float: right;" />
10
+ </div>
11
+ </el-row>
12
+
13
+ <el-table
14
+ :data="state.dataList"
15
+ v-loading="state.loading"
16
+ border
17
+ :cell-style="tableStyle.cellStyle"
18
+ :header-cell-style="tableStyle.headerCellStyle"
19
+ @selection-change="selectionChangeHandle"
20
+ @sort-change="sortChangeHandle"
21
+ >
22
+ <el-table-column type="selection" width="40" align="center" />
23
+ <el-table-column type="index" label="#" width="40" />
24
+ {{TABLE_COLUMNS}}
25
+ <el-table-column label="操作" width="220">
26
+ <template #default="scope">
27
+ <el-button text type="primary" icon="view" v-auth="'{{PERMISSION_PREFIX}}_view'" @click="handleDetail(scope.row.{{PK_ATTR}})">查看</el-button>
28
+ <el-button icon="edit-pen" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_edit'" @click="handleEdit(scope.row.{{PK_ATTR}})">编辑</el-button>
29
+ <el-button icon="delete" text type="primary" v-auth="'{{PERMISSION_PREFIX}}_del'" @click="handleDelete([scope.row.{{PK_ATTR}}])">删除</el-button>
30
+ </template>
31
+ </el-table-column>
32
+ </el-table>
33
+
34
+ <pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
35
+ </div>
36
+
37
+ <upload-excel ref="excelUploadRef" title="导入" url="/{{API_PATH}}/import" temp-url="/admin/sys-file/local/file/{{FUNCTION_NAME}}.xlsx" @refreshDataList="getDataList" />
38
+ </div>
39
+ </template>
40
+
41
+ <script setup lang="ts" name="system{{CLASS_NAME}}">
42
+ import { BasicTableProps, useTable } from '/@/hooks/table';
43
+ import { fetchList, delObjs } from '/@/api/{{API_MODULE_PATH}}';
44
+ import { useMessage, useMessageBox } from '/@/hooks/message';
45
+ {{DICT_IMPORT_BLOCK}}
46
+ const router = useRouter();
47
+
48
+ const excelUploadRef = ref();
49
+ const queryRef = ref();
50
+ const showSearch = ref(true);
51
+ const selectObjs = ref([]) as any;
52
+ const multiple = ref(true);
53
+
54
+ const state: BasicTableProps = reactive<BasicTableProps>({
55
+ queryForm: {},
56
+ pageList: fetchList,
57
+ });
58
+
59
+ const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state);
60
+
61
+ const getFormPath = () => '/{{VIEW_MODULE_PATH}}/form';
62
+
63
+ const handleCreate = () => {
64
+ router.push({ path: getFormPath(), query: { tagsViewName: '新增' } });
65
+ };
66
+
67
+ const handleDetail = (id: string) => {
68
+ router.push({ path: getFormPath(), query: { id, detail: '1', tagsViewName: '查看' } });
69
+ };
70
+
71
+ const handleEdit = (id: string) => {
72
+ router.push({ path: getFormPath(), query: { id, tagsViewName: '编辑' } });
73
+ };
74
+
75
+ const exportExcel = () => {
76
+ downBlobFile('/{{API_PATH}}/export', { ...state.queryForm, ids: selectObjs.value }, '{{FUNCTION_NAME}}.xlsx');
77
+ };
78
+
79
+ const selectionChangeHandle = (objs: { {{PK_ATTR}}: string }[]) => {
80
+ selectObjs.value = objs.map((item) => item.{{PK_ATTR}});
81
+ multiple.value = !objs.length;
82
+ };
83
+
84
+ const handleDelete = async (ids: string[]) => {
85
+ try {
86
+ await useMessageBox().confirm('此操作将永久删除');
87
+ } catch {
88
+ return;
89
+ }
90
+
91
+ try {
92
+ await delObjs(ids);
93
+ getDataList();
94
+ useMessage().success('删除成功');
95
+ } catch (err: any) {
96
+ useMessage().error(err.msg || '删除失败');
97
+ }
98
+ };
99
+ </script>
@@ -0,0 +1,21 @@
1
+ -- Do not execute directly. Review parent menu id and tenant settings before import.
2
+ -- Suggested default parent_id: -1
3
+ -- Generated by worsoft-codegen-local on {{GENERATED_AT}}
4
+
5
+ insert into sys_menu (menu_id, parent_id, path, permission, menu_type, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
6
+ values ({{MENU_BASE_ID}}, '-1', '/{{MENU_ROUTE_PATH}}/index', '', '0', 'icon-bangzhushouji', '0', null, '8', null, '{{TABLE_COMMENT}}管理', 1);
7
+
8
+ insert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
9
+ values ({{MENU_BASE_ID_PLUS_1}}, {{MENU_BASE_ID}}, '{{PERMISSION_PREFIX}}_view', '1', null, '1', '0', null, '0', null, '{{TABLE_COMMENT}}查看', 1);
10
+
11
+ insert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
12
+ values ({{MENU_BASE_ID_PLUS_2}}, {{MENU_BASE_ID}}, '{{PERMISSION_PREFIX}}_add', '1', null, '1', '0', null, '1', null, '{{TABLE_COMMENT}}新增', 1);
13
+
14
+ insert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
15
+ values ({{MENU_BASE_ID_PLUS_3}}, {{MENU_BASE_ID}}, '{{PERMISSION_PREFIX}}_edit', '1', null, '1', '0', null, '2', null, '{{TABLE_COMMENT}}修改', 1);
16
+
17
+ insert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
18
+ values ({{MENU_BASE_ID_PLUS_4}}, {{MENU_BASE_ID}}, '{{PERMISSION_PREFIX}}_del', '1', null, '1', '0', null, '3', null, '{{TABLE_COMMENT}}删除', 1);
19
+
20
+ insert into sys_menu (menu_id, parent_id, permission, menu_type, path, icon, del_flag, create_time, sort_order, update_time, name, tenant_id)
21
+ values ({{MENU_BASE_ID_PLUS_5}}, {{MENU_BASE_ID}}, '{{PERMISSION_PREFIX}}_export', '1', null, '1', '0', null, '4', null, '导入导出', 1);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Local codegen metadata for {{TABLE_NAME}}
3
+ */
4
+ export const dataMasterEntity = {
5
+ {{OPTIONS_FIELDS}}
6
+ };
7
+
8
+ export const filterTypes = {
9
+ {{FILTER_TYPES}}
10
+ };
@@ -0,0 +1,41 @@
1
+ import request from '/@/utils/request';
2
+
3
+ export function fetchList(query?: object) {
4
+ return request({
5
+ url: '/{{API_PATH}}/page',
6
+ method: 'get',
7
+ params: query,
8
+ });
9
+ }
10
+
11
+ export function addObj(obj?: object) {
12
+ return request({
13
+ url: '/{{API_PATH}}',
14
+ method: 'post',
15
+ data: obj,
16
+ });
17
+ }
18
+
19
+ export function getObj(obj?: object) {
20
+ return request({
21
+ url: '/{{API_PATH}}/details',
22
+ method: 'get',
23
+ params: obj,
24
+ });
25
+ }
26
+
27
+ export function delObjs(ids?: object) {
28
+ return request({
29
+ url: '/{{API_PATH}}',
30
+ method: 'delete',
31
+ data: ids,
32
+ });
33
+ }
34
+
35
+ export function putObj(obj?: object) {
36
+ return request({
37
+ url: '/{{API_PATH}}',
38
+ method: 'put',
39
+ data: obj,
40
+ });
41
+ }