Ver código fonte

!1391 前端框架集成FastCurd
Merge pull request !1391 from 倔强嘴角留下一抹殇/next

zuohuaijun 1 ano atrás
pai
commit
a4db31f45e

+ 1 - 0
Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs

@@ -193,6 +193,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             new SysMenu{ Id=1310000000621, Pid=1310000000601, Title="代码生成", Path="/develop/codeGen", Name="sysCodeGen", Component="/system/codeGen/index", Icon="ele-Crop", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
             new SysMenu{ Id=1310000000631, Pid=1310000000601, Title="表单设计", Path="/develop/formDes", Name="sysFormDes", Component="/system/formDes/index", Icon="ele-Edit", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
             new SysMenu{ Id=1310000000641, Pid=1310000000601, Title="系统接口", Path="/develop/api", Name="sysApi", Component="layout/routerView/iframe", IsIframe=true, OutLink="http://localhost:5005", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000651, Pid=1310000000601, Title="Curd仔专用", Path="/develop/crud", Name="sysCrud", Component="/system/crud/index",  Icon="ele-Edit", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=121},
 
             new SysMenu{ Id=1310000000701, Pid=0, Title="帮助文档", Path="/doc", Name="doc", Component="Layout", Icon="ele-Notebook", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=14000 },
             new SysMenu{ Id=1310000000711, Pid=1310000000701, Title="框架教程", Path="/doc/admin", Name="sysAdmin", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="http://101.43.53.74:5050/", Icon="ele-Sunny", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },

+ 5 - 0
Web/package.json

@@ -15,6 +15,11 @@
 	},
 	"dependencies": {
 		"@element-plus/icons-vue": "^2.3.1",
+		"@fast-crud/fast-crud": "^1.21.2",
+		"@fast-crud/fast-extends": "^1.21.2",
+		"@fast-crud/ui-element": "^1.21.2",
+		"@fast-crud/ui-interface": "^1.21.2",
+		"@iconify/vue": "^4.1.2",
 		"@logicflow/core": "^1.2.28",
 		"@logicflow/extension": "^1.2.28",
 		"@microsoft/signalr": "^8.0.7",

+ 82 - 1
Web/src/main.ts

@@ -24,5 +24,86 @@ const app = createApp(App);
 
 directive(app);
 other.elSvg(app);
-
+//#region  FastCrud配置
+import { FastCrud } from "@fast-crud/fast-crud";
+import "@fast-crud/fast-crud/dist/style.css";
+import ui from "@fast-crud/ui-element";
+import { FsExtendsUploader, FsExtendsEditor } from "@fast-crud/fast-extends";
+import "@fast-crud/fast-extends/dist/style.css";
+import { getToken } from '/@/utils/axios-utils';
+app.use(ui);
+app.use(FastCrud, {
+    i18n,
+    commonOptions() {
+        return {
+            request: {
+                transformQuery: ({ page, form, sort }) => {
+                    const order = sort == null ? {} : { orderProp: sort.prop, orderAsc: sort.asc }
+                    return { page: page.currentPage, pageSize: page.pageSize, ...form, ...order };
+                },
+                // page请求结果转换
+                transformRes: ({ res }) => {
+                    const records = res.data.result.items;
+                    const total = res.data.result.total;
+                    const currentPage = res.data.result.page;
+                    const pageSize = res.data.result.pageSize;
+                    return {
+                        currentPage: currentPage, pageSize: pageSize, total: total, records
+                    }
+                },
+                form: {
+                    display: 'flex', // 表单布局
+                    labelWidth: '120px' // 表单label宽度
+                }
+            },
+        };
+    },
+});
+const baseURL = import.meta.env.VITE_API_URL;
+import request from '/@/utils/request';
+//文件上传
+app.use(FsExtendsUploader, {
+    defaultType: 'form',
+    form: {
+        action: baseURL + '/api/sysFile/uploadFile',
+        name: 'file',
+        withCredentials: false,
+        uploadRequest: async props => {
+            const { action, file, onProgress } = props;
+            const data = new FormData();
+            data.append('file', file);
+            const token = getToken();
+            const Authorization = token ? `Bearer ${token}` : null;
+            const result = await request({
+                url: action,
+                method: 'post',
+                data,
+                headers: {
+                    'Content-Type': 'multipart/form-data',
+                    "Authorization": Authorization
+                },
+                timeout: 60000,
+                onUploadProgress(progress) {
+                    onProgress({ percent: Math.round((progress.loaded / progress.total!) * 100) });
+                }
+            });
+            if (result) {
+                return result.data
+            } else {
+                throw new Error(result.message);
+            }
+        },
+        async successHandle(ret: any) {
+            return {
+                url: baseURL + "/" + ret.result.filePath + "/" + ret.result.id + ret.result.suffix,
+                key: ret.result.fileName
+            };
+        }
+    }
+});
+//富文本编辑器
+app.use(FsExtendsEditor, {
+    wangEditor: {}
+});
+//#endregion
 app.use(pinia).use(router).use(ElementPlus).use(i18n).use(VueGridLayout).use(VForm3).use(VueSignaturePad).use(vue3TreeOrg).mount('#app');

+ 181 - 0
Web/src/views/system/crud/crud.tsx

@@ -0,0 +1,181 @@
+
+import { dict, compute } from '@fast-crud/fast-crud';
+import { shallowRef, ref } from 'vue';
+import { getAPI } from '/@/utils/axios-utils';
+import { SysNoticeApi } from '/@/api-services/api';
+import { ElMessage } from 'element-plus';
+export default function ({ expose }) {
+    const pageRequest = async (query) => {
+        const params = {
+            page: query.currentPage,
+            pageSize: query.pageSize,
+            field: query.field,
+            order: query.order,
+            descStr: 'desc'
+        } as PageFileInput;
+        const result = await getAPI(SysNoticeApi).apiSysNoticePagePost(params);
+        return result;
+    };
+    const editRequest = async ({ form, row }: EditReq) => {
+        if (form.id == null) {
+            form.id = row.id;
+        }
+        return await getAPI(SysNoticeApi)
+            .apiSysNoticeUpdatePost(form)
+            .then((rsp: any) => {
+                if (rsp.data.code == 200) {
+                    ElMessage.success('修改成功!');
+                } else {
+                    ElMessage.error('修改失败:' + rsp.data.message);
+                }
+            });
+    };
+    const delRequest = async ({ row }: DelReq) => {
+        return await getAPI(SysNoticeApi)
+            .apiSysNoticeDeletePost(row);
+    };
+    const addRequest = async ({ form }: AddReq) => {
+        return await getAPI(SysNoticeApi)
+            .apiSysNoticeAddPost(form);
+    };
+    const selectedIds = ref([]);
+    const onSelectionChange = (changed) => {
+        selectedIds.value = changed;
+    };
+    return {
+        selectedIds,
+        crudOptions: {
+            container: {
+                is: 'fs-layout-card'
+            },
+            form: {
+                wrapper: {
+                    // is: 'el-drawer',
+                    // width: '80%',
+                    draggable: false,
+                    closeOnEsc: false,
+                    maskClosable: false,
+                }
+            },
+            search: {
+                show: true,
+            },
+            actionbar: {
+            },
+            toolbar: {
+                show: true,
+                buttons: {
+                    search: { show: true },
+                    refresh: { show: true },
+                    compact: { show: true },
+                    export: { show: true },
+                    columns: { show: true },
+                },
+            },
+            table: {
+                scrollX: 725,
+                bordered: false,
+                rowKey: (row) => row.id,
+                checkedRowKeys: selectedIds,
+                'onUpdate:checkedRowKeys': onSelectionChange,
+            },
+            pagination: {
+                show: true
+            },
+            request: {
+                pageRequest,
+                addRequest,
+                editRequest,
+            },
+            rowHandle: {
+                fixed: "right",
+                align: "center",
+                width: 200,
+                buttons: {
+                    view: { show: true },
+                    edit: { show: true }
+                }
+            },
+            columns: {
+                _checked: {
+                    title: '选择',
+                    form: { show: false },
+                    column: {
+                        type: 'selection',
+                        align: 'center',
+                        width: '55px',
+                        columnSetDisabled: true,
+                        disabled(row) {
+                            return row.account === 'gvanet';
+                        },
+                    },
+                },
+                type: {
+                    title: '类型',
+                    type: 'dict-select',
+                    search: { show: true, col: { span: 6 } },
+                    column: {
+                        align: "center",
+                        width: '120px',
+                    },
+                    dict: dict({
+                        value: 'id',
+                        label: 'text',
+                        data: [
+                            { id: '1', text: '通知' },
+                            { id: '2', text: '公告' }
+                        ],
+                    }),
+                    form: {
+                        col: { span: 24 },
+                        rule: [
+                            { required: true, message: '请输入类型' }
+                        ],
+                    }
+                },
+                title: {
+                    title: '标题',
+                    type: 'text',
+                    search: { show: true, col: { span: 6 } },
+                    column: {
+                        align: "center",
+                        width: 'auto',
+                    },
+                    form: {
+                        col: { span: 24 },
+                        rule: [
+                            { required: true, message: '请输入标题' }
+                        ],
+                    }
+                },
+                content: {
+                    title: '内容',
+                    type: 'editor-wang5',
+                    search: { show: false, col: { span: 6 } },
+                    column: {
+                        show: false,
+                    },
+                    form: {
+                        col: { span: 24 },
+                        rule: [
+                            { required: true, message: '请输入内容' }
+                        ],
+                        component: {
+                            disabled: compute(({ form }) => {
+                                return form.disabled;
+                            }),
+                            id: '1', // 当同一个页面有多个editor时,需要配置不同的id
+                            config: {},
+                            uploader: {
+                                type: 'form',
+                                buildUrl(res) {
+                                    return res.url;
+                                },
+                            },
+                        },
+                    }
+                }
+            },
+        },
+    };
+}

+ 64 - 0
Web/src/views/system/crud/index.vue

@@ -0,0 +1,64 @@
+<template>
+    <div class="h-full">
+        <fs-crud ref="crudRef" v-bind="crudBinding">
+            <template #pagination-left>
+                <fs-button icon="ion:trash-outline" @click="handleBatchDelete" />
+            </template>
+            <template #cell_url="scope">
+                <n-tooltip trigger="hover">
+                    <template #trigger>
+                        <n-button>预览 </n-button>
+                    </template>
+                    <n-image width="120px" height="120px" :src="baseURL + '/' + scope.row.url"></n-image>
+                </n-tooltip>
+            </template>
+        </fs-crud>
+    </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, onMounted, ref, nextTick } from 'vue';
+import { useFs, useExpose, useCrud } from '@fast-crud/fast-crud';
+import createCrudOptions from './crud';
+import { getAPI } from '/@/utils/axios-utils';
+import { SysNoticeApi } from '/@/api-services/api';
+import { ElMessage, ElMessageBox } from 'element-plus';
+const baseURL = import.meta.env.VITE_API_URL;
+export default defineComponent({
+    name: 'ComponentCrud',
+    setup() {
+        const crudRef = ref();
+        const crudBinding = ref();
+        const { expose } = useExpose({ crudRef, crudBinding });
+        const { crudOptions, selectedIds } = createCrudOptions({ expose });
+        const { resetCrudOptions } = useCrud({ expose, crudOptions });
+        onMounted(() => {
+            expose.doRefresh();
+        });
+        const handleBatchDelete = async () => {
+            if (selectedIds.value?.length > 0) {
+                // ElMessageBox.confirm(`确定要批量删除这${selectedIds.value.length}条记录吗`, '确认', {
+                //     confirmButtonText: '确定',
+                //     cancelButtonText: '取消',
+                //     type: 'info',
+                // }).then(async () => {
+                //        await delBatchSysFile(selectedIds.value);
+                //       message.success('删除成功');
+                //       selectedIds.value = [];
+                //       await expose.doRefresh();
+                //         ElMessage.success('删除成功');
+                //     })
+                //     .catch(() => { });
+            } else {
+                // ElMessage.success('请勾选要删除的记录');
+            }
+        };
+        return {
+            crudBinding,
+            crudRef,
+            handleBatchDelete,
+            baseURL
+        };
+    }
+});
+</script>