基于admin.net框架的前端的一些改进和代码生成处理(代码片段)

wuhuacong(伍华聪)的专栏 wuhuacong(伍华聪)的专栏     2023-03-29     601

关键词:

Admin.NET 是一套基于Furion/.NET 6实现的通用管理平台,模块插件式开发,框架包含了常规的权限管理、字典等管理模块,以及一些Vue3的Demo案例,框架前后端分离。后端基于基于Furion/.NET 6实现,底层集成SqlSugar;前端则是采用Vue-Next-Admin的前端框架,整体是一套非常不错的框架。本人比较喜欢研究一些技术框架,最近对该框架进行了一些研究分析,结合我自己开发框架的思路,对其前后端进行一定的修改调整,本篇随笔记录一些对该框架的相关修改内容。

Admin.NET 是一套基于Furion/.NET 6实现的通用管理平台,模块插件式开发,框架包含了常规的权限管理、字典等管理模块,以及一些Vue3的Demo案例,框架前后端分离。后端基于基于Furion/.NET 6实现,底层集成SqlSugar;前端则是采用Vue-Next-Admin的前端框架,整体是一套非常不错的框架。本人比较喜欢研究一些技术框架,最近对该框架进行了一些研究分析,结合我自己开发框架的思路,对其前后端进行一定的修改调整,本篇随笔记录一些对该框架的相关修改内容。

Admin.NET官网的的地址:https://gitee.com/zuohuaijun/Admin.NET,Vue-Next-Admin的官网地址:https://lyt-top.gitee.io/vue-next-admin-doc-preview/,有兴趣可以分别到官网上进行预览了解。

1、API及对象接口的处理

一般的前端,为了访问后端接口,以及转换对象,都需要构建后端接口的API代理类,以及相关的对象接口定义,Admin.NET的前端这部分内容放在 api-services 目录 下,包含了apis和models两个目录

 不过由于它们可能使用基于类似  generator-swagger-2-ts 插件的方式进行前端代码的生成,因此代码显得非常臃肿,一个简单的API需要来回的封装接口进行调用,以字典API为例,每个API的类代码都显得很臃肿,接近1000行代码,这个和我们实际的API调用不太匹配,我们一般只需要简单的调用就可以做到了,太多的代码不利于阅读和维护。

在我的随笔《基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理》中介绍过前端的API调用过程场景,如下所示。

前端一般根据框架后端的接口进行前端JS端的类的封装处理,引入了ES6类的概念实现业务基类接口的统一封装,简化代码。

一般我们在基类BaseApi中创建一些常用API的调用处理,那么常用的业务类继承BaseApi,就会具有相关的接口了,如下所示继承关系。

这样我们代码就会变得简洁很多,维护阅读都非常方便。

我们遵循Admin.NET的目录结构,如下所示放置Api接口和业务对象接口类。

 根据是否具有常规接口的后台接口定义,我们创建两个不同的基类BaseNormal 和 BaseApi ,这样我们便于实际的业务类Api的封装抽象。

如下是常规的基类,不具有任何基类接口,只是为了方便构造一些参数

/**
 * 此类作为普通API的基类,不继承常规的通用CRUD方法,如文件操作,服务器信息等类
 */
export class BaseNormal 
    /**
        * 服务器请求的起始路径, 类似 \'http://localhost:**
       */
    protected basePath = serveConfig.basePath;

    /**
     * Api路径。子类通过构造函数修改, 其中api转义为具体的路径,如\'/api/test\'
    */
    protected apiPath = \'/api/test\';

    /**
     * 请求完整路径(除了方法名),类似 `http://localhost:**\\/api/test`
    */
    protected baseUrl = this.basePath + this.apiPath;//

    /**
     * 定义一个axios变量,便于子类访问
    */
    protected axiosInstance = axiosInstance;

    /**
     * 构造函数,接受Api路径,如\'/api/test\'
    */
    constructor(apiPath: string) 
        // 构造函数
        this.apiPath = apiPath;
        this.baseUrl = this.basePath + this.apiPath;
    

下面是一个具有数据访问CRUD的操作接口,如下所示。

/**
 * 服务器请求基础类
*/
export class BaseApi<EntityType = any, AddType = any, UpdateType = any> extends BaseNormal 
    /**
     * 分页获取列表
    */
    page = async (data: object | null) => 
        const url = this.baseUrl + `/page`;
        return await this.axiosInstance.get<UnifyResult<SqlSugarPagedList<EntityType>>>(url,  params: data )
    

    /**
     * 获取列表
    */
    list = async (data: object | null) => 
        const url = this.baseUrl + `/list`;
        return await this.axiosInstance.get<UnifyResult<Array<EntityType>>>(url,  params: data )
    

    /**
     * 新增记录
    */
    add = async (data: AddType) => 
        const url = this.baseUrl + `/add`;
        return await this.axiosInstance.post<UnifyResult<void>>(url, data)
    
    /**
     * 更新记录
    */
    update = async (data: UpdateType) => 
        const url = this.baseUrl + `/update`;
        return await this.axiosInstance.post<UnifyResult<void>>(url, data)
    
    /**
     * 删除记录
    */
    delete = async (data: object) => 
        const url = this.baseUrl + `/delete`;
        return await this.axiosInstance.post<UnifyResult<void>>(url, data)
    

    /** 批量删除 */
    batchDelete = async (data: object) => 
        const url = this.baseUrl + `/BatchDelete`;
        return await this.axiosInstance.post<UnifyResult<void>>(url, data)
    

根据接口返回的内容,其中UnifyResult 对象接口是统一接口返回的处理对象,我们在types目录中定义即可,而SqlSugarPagedList则是Admin.NET分页返回的结果集合,这些基础类接口也是定义types目录中即可。

 

 而对于对应后端业务类对象接口的定义,我们倾向于把它按业务区分,一个业务类对应的放在一个独立的文件中定义即可,如下所示。

 一般包含一个标准的对象接口,增加对象、修改对象、查询对象等接口对象。

其中由于常规的业务对象接口,往往都具备一些基础的属性,因此我们把这些基础属性放到基类里面定义,然后在实际的业务对象接口中继承基类对象就可以了。

 

 业务API代理类的定义,这是根据这些模型的信息进行简单的声明即可,如下对于菜单,如果不考虑除了增删改查的其他额外的接口,那么只需要简单的继承BaseApi即可。

import  BaseApi  from \'./base-api\';
import  SysMenu, UpdateMenuInput, AddMenuInput, MenuOutput  from \'/@/api/models\';

/**
 * 菜单管理Api
 */
class SysMenuApi extends BaseApi<SysMenu, AddMenuInput, UpdateMenuInput> 

   ............./*其他接口定义*/



export default new SysMenuApi(\'/api/sysMenu\');

对于没有标准CRUD接口的非常规API接口,我们可以让它继承NormalApi即可。

import  BaseNormal from \'./base-api\';
import  ConstOutput  from \'/@/api/models\';

/**
 * 系统常量服务 管理Api
 */
class SysConstApi extends BaseNormal   

     /**
     * 获取所有常量列表
    */
     list = async () => 
        const url = this.baseUrl + `/list`;
        return await this.axiosInstance.get<UnifyResult<Array<ConstOutput>>>(url,  params: null )
    


export default new SysConstApi(\'/api/sysConst\');

有了这些内容我们就可以在实际业务视图中进行API接口的调用了。

对于原先的Admin.NET的业务接口调用,他们需要先引入一个工厂类,然后构造处理才能调用接口,如下定义:

import  getAPI  from \'/@/utils/axios-utils\';
import  SysMenuApi  from \'/@/api-services/api\';

原先的Admin.NET视图组件中的实际的调用代码如下所示。

// 查询操作
const handleQuery = async () => 
    state.loading = true;
    var res = await getAPI(SysMenuApi).apiSysMenuListGet(state.queryParams.title, state.queryParams.type);
    state.menuData = res.data.result ?? [];
    state.loading = false;
;

由于他们是采用Swagger的接口生成,因此默认接口名称都带有api的前缀,Get或者Post的后缀,感觉不是那么易读。

而对于我们重构过的处理逻辑,定义代码如下所示。

import  SysMenu  from \'/@/api/models\';
import menuApi from \'/@/api/apis/sys-menu-api\'

实际视图或者组件中的调用代码如下所示。

// 查询操作
const handleQuery = async () => 
    state.loading = true;
    var res = await menuApi.list(state.queryParams);
    state.menuData = res.data.result ?? [];
    state.loading = false;
;

实际调用代码简单只是一点点,但是Api的定义代码,从上千行调用代码则锐减到仅仅几行代码就可以了,减少了大量重复的累赘接口定义,以及很多模型接口重复定义操作(例如对于分页返回的对象,他们每次都生成一遍重读的类型,而这里则是使用泛型基于SqlSugarPagedList的方式进行简化)。

 

2、基于代码生成工具的生成

有些人说他们虽然代码多了一点,贵在能够根据接口自动生成前端代码呀,确实能自动生成代码是非常不错的一件事情,可以极大提高效率。

那么我们也根据接口的通用性,来构建代码生成的相关规则即可。由于这些接口的生成,大多数情况下,都是以数据库表和字段的规则进行生成的,因此我把它整合在代码生成工具的功能上生成即可。

 

 

最后我们把生成的Api部分代码放在目录中

 视图代码放在views目录里面对应的目录即可,如下是测试生成的页面,包括有index.vue 页面,以及edit.vue,以及import.vue的页面。

其中index是主页面查询及列表展示内容,edit.vue是新增和编辑界面内容,而import.vue这是导入界面内容。

目录文件如下图所示。

自动生成的index.vue页面代码,根据预定义的模板进行生成,经过多次的校准,已经比较完美的根据数据库表字段及备注信息,生成视图代码了。

生成的页面,进行一定的微调即可用于实际的生产业务中了。 

该测试页面添加完成后,在后端创建一个菜单指向它即可,编译运行界面效果如下所示。

我改变了一下常规的界面功能,增加了导入、导出、批量删除的操作入口。

 

 默认进行折叠,展开则列出所有条件,如下界面所示。

 

导入界面是改进了ele-Import插件,得到界面效果如下所示。

 导出则是利用xlsx的插件进行导出Excel文件。 

 如果需要了解代码生成,可以下载Database2Sharp代码生成工具 进行了解。

 

框架比较

第一代框架(以下称A)与第二代框架(以下称B)迁移难易分析框架实现的需求:A框架与B框架实现融合,实现权限管理(权限、用户、角色、菜单和部门列表)、系统管理(实体账户、分账户、用户策略、策略配对、合约做市... 查看详情

框架比较

第一代框架(以下称A)与第二代框架(以下称B)迁移难易分析框架实现的需求:A框架与B框架实现融合,实现权限管理(权限、用户、角色、菜单和部门列表)、系统管理(实体账户、分账户、用户策略、策略配对、合约做市... 查看详情

分析一套源代码的代码规范和风格并讨论如何改进优化代码

...范和风格并讨论如何改进优化代码笔者工程实践课题是:基于语音识别的智能聊天机器人设计。本题目需要先研究机器学习的基本方法,用TeansorFlow机器学习库,通过Python构建一个基于LSTM循环神经网络的语音识别器。故此,笔者... 查看详情

前端框架和库的区别

...相当于dom操作+请求art-template库 相当于 模板引擎框架= 全方位功能齐全即 简易的dom体验+发请求+模板引擎+路由功能+数据管理以KFC为例:库就是一个个小套餐,框架就是全家桶 两者代码上的不同一般使用库的代... 查看详情

基于xlua和mvvm的unity框架(代码片段)

...开源的一个框架—XUUI,于是下载下来学习了一下。XUUI基于xlua,又借鉴了mvvm的设计概念。xlua是目前很火的unity热更方案,不仅支持纯lua脚本热更,也可以做C#代码的bughotfix,而mvvm框架呢,在前端开发中应用很广,我周围同事... 查看详情

基于改进east算法的文本检测(代码片段)

这段时间阅读研究了EAST算法以及在EAST算法上的改进并完成了复现运用到其他场景中去。当今社会已进入图像大数据时代,图像数量庞大种类繁多,包含大量的有用知识。从图像中高效、精准、全面地提取文本和地理信息... 查看详情

分析一套源代码的代码规范和风格并讨论如何改进优化代码

...是《物联网网关智能分析引擎》,我所做的是前端开发。基于此,我对Vue.js目录结构进行分析。Vue.js是当下很火的一个JavaScriptMVVM库,它是以数据驱动和组件化的思想构建的。1.Vue.js目录结构结构图如下所示:build:项目构建(webpa... 查看详情

有哪些优秀的前端js框架

...有简洁、直观的前端开发特点。2.EasyUI框架,EasyUI是一种基于jQuery、Angular.、Vue和React的用户界面插件集合。通过使用easyui不需要写很多代码,只需要通过编写一些简单HTML标记,就可以定义用户界面。二.前端框架1.Node.js框架。No... 查看详情

前端啥样的代码开发工具好用?

...参考。框架类:Bootstrap全世界最流行的响应式前端框架。基于HTML、CSS、JAVASCRIPT的,它在jQuery的基础上进行了更为个性化和人性化的完善,形成一套自己独有的网站风格。并兼容大部分jQuery插件。简洁灵活,使得Web开发更加快捷... 查看详情

前端之bootstrap(代码片段)

...Twitter公司的MarkOtto和JacobThornton一起开发的,Bootstra框架是基于HTML、CSS、JavaScript开发的,它因简洁、直观、功能强大被开发者广发使用。  Bootstrap前端框架使得Web开发更加快捷,提供了优雅的HTML、CSS和JavaScript规范 查看详情

基于深度学习的图异常检测如何改进

您好,基于深度学习的图异常检测是一种有效的方法,但是仍然存在一些问题需要改进。以下是几种可能的改进方法:1.数据增强:在训练模型之前,可以使用数据增强技术来扩充训练数据集。这可以帮助模型更好地学习数据的... 查看详情

(一)基于vue-element-admin前端与后端框架搭建

参考技术A通过src/settings.js进行全局配置:get-page-title.js在src/permission.js中被引用修改package.json执行命令启动中间件是一个函数,请求和响应周期中被顺序调用写一个中间函数调用中间件注意事项:应用如何响应请求的一种规则响... 查看详情

前端里的库和框架

库和框架是什么呢?虽然有时候在一些语境中他们是可以互相替代的,但是我们还是要了解下他们的真正含义。 库:它是一系列对象,方法的代码,我们通过引入库,来实现代码的重用,代码的精简。框架:它是一个系统中... 查看详情

前端之bootstrap框架(代码片段)

一Bootstrap简介在搭建前端页面时我们可以借用一些好的模板,为了让这些模板更好的让开发者使用,我们借助Bootstrap来实现一些常用的模板例如在看到上面这么好的模板,同学们是不是就想立刻收藏了呢?二css全局样式布局容器... 查看详情

前端框架的未来:usesignal()(代码片段)

...异使Signal更具优势。Vue、Preact、Solid和Qwik等流行JavaScript框架都支持Signal。Signal并不是最近才出现的,在此之前,它已经存在于Knockout等框架中。不过,在最近几年通过巧妙的编译器技巧和与JSX的深度集成极大地改进了... 查看详情

基于angularjs的个推前端云组件探秘

AngularJS是google设计和开发的一套前端开发框架,帮助开发人员简化前端开发的负担。AngularJS将帮助标准化的开发web应用结构并且提供了针对客户端应用的未来开发使用的模板,AngularJS非常全面且简单易学习,AngularJS快速的成为了... 查看详情

freemarker

...roller(模型-视图-控制器)一、整体理解freemarker也是一种基于模板和数据的展示。用官方的话来说:FreeMarker是一款模板引擎:即一种基于模板和要改变的数据, 查看详情

优化求解基于惯性权值非线性递减的改进粒子群算法(impso)matlab源码(代码片段)

 一、粒子群算法粒子群算法是在1995年由Eberhart博士和Kennedy博士一起提出的,它源于对鸟群捕食行为的研究。它的基本核心是利用群体中的个体对信息的共享从而使整个群体的运动在问题求解空间中产生从无序到有序的演化... 查看详情