在上篇随笔《基于Admin.NET框架的前端的一些改进和代码生成处理(1)》中大致介绍了一些关于对Admin.NET框架的前端的改造工作,主要目的就是希望能够增加前端代码的简洁性和可读性,以及利用代码生成工具来快速生成相关的代码,从而减少开发过程中的繁琐问题。本篇随笔继续探讨一下,对其中一些模块功能进行一些修改调整,涉及前后端的一起修改调整。

Admin.NET框架的后端基于基于Furion/.NET 6实现,底层集成SqlSugar;前端则是采用Vue-Next-Admin的前端框架,整体是一套非常不错的框架。

1、增加批量添加字典项目

Admin.NET框架的字典管理项目界面如下所示。

它通过列出字典大类,然后在右边入口进行字典项目的管理,以前我倾向于使用左右视图分拆的方式,从而实现字典大类和字典项目的快捷管理。

如在随笔《在Vue&Element前端项目中,对于字典列表的显示处理》中介绍到的字典综合展示方式如下所示。

我们这里暂且不修改这个页面,继续查看其字典项目管理的界面如下所示。

其列表里面只有一个新增的操作,如果对于初始化字典,则是一份苦差事,反复的打开录入是比较费时间的。我们可以使用惯用的方式,来批量录入字典项目,来提高字典项目初始化处理的效率。

我们在原有界面上增加一个批量录入,和批量删除的操作,如下界面所示。

批量新增字典项目的界面,如下所示。

如果字典值和编码内容不一致,可以使用如下效果进行批量新增

批量添加字典项目的页面,我们是作为一个组件页面的方式添加,然后在页面中应用组件即可,如下代码所示。

对应的批量添加页面里面,提交的时候,调用对应的API接口就可以了,如下代码所示。

  1. // 保存数据处理
  2. async function submitData() {
  3. var formEl = editRef.value;
  4. if (!formEl) return;
  5.  
  6. await formEl.validate(async (valid) => {
  7. if (valid) {
  8. //验证成功,执行下面方法
  9. var result = await dictdata.BatchAdd(editForm); //编辑保存
  10.  
  11. if (result) {
  12. $u.message.success('批量添加字典成功!'); // 提示信息
  13. emit('submit'); // 提示刷新数据
  14. closeDialog(); // 重置窗口状态
  15. } else {
  16. $u.message.error('批量添加失败');
  17. }
  18. }
  19. });
  20. }

对应的业务API类里面,定义对应的接口函数。

  1. /**
  2. * 系统字典值表 管理Api
  3. */
  4. class SysDictDataApi extends BaseApi<SysDictData, AddDictDataInput, UpdateDictDataInput> {
  5. ............
  6.  
  7. /** 批量添加字典项目 */
  8. BatchAdd = async (data: object) => {
  9. const url = this.baseUrl + `/BatchAdd`;
  10. return await this.axiosInstance.post<UnifyResult<void>>(url, data)
  11. }
  12. }
  13. export default new SysDictDataApi('/api/sysDictData');

后端增加对应的处理接口,实现数据的批量添加即可。

至此,批量添加字典项目的操作,配合前端后端一起,就可以完成该操作了。

2、显示/隐藏开发测试菜单

在Vue-Next-Admin的前端框架演示项目里面,本身提供了很多Demo案例的页面展示,不过Admin.NET应该为了简化框架的效果,从而把这些演示的案例菜单移除了,不过视图文件依旧保存在项目里面,我们开发测试过程中,有时候需要参考这些页面效果,以便了解一些插件的功能和特点,因此可能偶尔需要使用了解下的。而在部署的时候,肯定是需要隐藏起来,不让客户使用这些Demo,否则增加烦恼。

为了更好的管控这些演示菜单连接的入口,我们在原有菜单的表里面增加一个Tag标签,用来标识相关的菜单功能,例如我们把测试页面的Tag标注为 dev, 而菜单表里面本身有是否隐藏和是否启用的设置,隐藏相对于菜单而已不显示(但包含路由),是否启用相对于路由而言(禁用也就无法访问菜单的路由了)。

我们通过这些设置信息,可以对特定的标签,启用或者禁用,从而实现我们对开发测试的菜单页面的显示和隐藏操作。

这个修改处理,必须结合后端进行相关数据表结构调整,以及相关的代码属性调整,在数据库增加一个Tag属性字段,然后修改实体对象定义。

  1. /// <summary>
  2. /// 系统菜单表
  3. /// </summary>
  4. [SugarTable(null, "系统菜单表")]
  5. [SystemTable]
  6. public class SysMenu : EntityBase
  7. {
  8. ....................
  9.  
  10. /// <summary>
  11. /// 标签
  12. /// </summary>
  13. [SugarColumn(ColumnDescription = "标签", Length = 256)]
  14. [MaxLength(256)]
  15. public string? Tag { get; set; }
  16.  
  17. }

以及在相关的Dto对象上增加相关的属性。

  1. public class MenuInput
  2. {
  3. /// <summary>
  4. /// 标题
  5. /// </summary>
  6. public string Title { get; set; }
  7.  
  8. /// <summary>
  9. /// 标签
  10. /// </summary>
  11. public string? Tag { get; set; }
  12.  
  13. /// <summary>
  14. /// 菜单类型(1目录 2菜单 3按钮)
  15. /// </summary>
  16. public MenuTypeEnum? Type { get; set; }
  17. }

为了隐藏或者显示菜单,我们需要在后端增加一个接口函数,接口函数会通过代理注入的方式提供相关的控制器接口入口,从而给前端访问处理的。

  1. /// <summary>
  2. /// 隐藏/启用开发测试页面菜单(对标记tag为dev的,进行隐藏或者启用)
  3. /// </summary>
  4. /// <returns></returns>
  5. [DisplayName("隐藏/启用开发测试页面菜单")]
  6. public async Task HideOrShowDevMenu()
  7. {
  8. var tagFlag = "dev";
  9. var hideState = await _sysMenuRep.IsAnyAsync(u => u.Tag == tagFlag && u.IsHide);
  10. var newHide = !hideState;
  11. var newState = hideState ? StatusEnum.Enable : StatusEnum.Disable;
  12.  
  13. //更新特定字段(同时隐藏和禁用)
  14. await _sysMenuRep.UpdateAsync(
  15. u => new SysMenu { IsHide = newHide, Status = newState },
  16. u => u.Tag == tagFlag);
  17. }

我们通过判断当前记录的隐藏状态和启用状态,从而给他一个反转值,然后根据条件更新相关的记录即可。

前端开发的时候,我们除了也是相应增加对应的Tag属性,也需要配合后端,手工添加一个对应的方法调用,如下代码所示。

  1. import { BaseApi } from './base-api';
  2. import { SysMenu, UpdateMenuInput, AddMenuInput, MenuOutput } from '/@/api/models';
  3.  
  4. /** 菜单管理Api */
  5. class SysMenuApi extends BaseApi<SysMenu, AddMenuInput, UpdateMenuInput> {
  6. /**隐藏/启用开发测试页面菜单(对标记tag为dev的,进行隐藏或者启用) */
  7. HideOrShowDevMenu = async () => {
  8. const url = this.baseUrl + `/HideOrShowDevMenu`;
  9. return await this.axiosInstance.post<UnifyResult<void>>(url, null)
  10. }
  11. }
  12.  
  13. export default new SysMenuApi('/api/sysMenu');

这里只需要注意前端的调用api路径,以及返回结果即可。

根据Vue-Next-Admin的前端的测试菜单的页面信息,我们添加了相关的测试案例菜单,并给它们统一打上dev的标签,添加后的菜单列表界面如下所示。

然后在界面上增加一个操作入口,如下所示。

来操作测试案例菜单的启用或者禁用处理即可。

  1. const hideOrShowDevMenu = () => {
  2. var tips = '您确认要隐藏/启用开发测试页面?';
  3. //(对记录标记tag为dev的,进行隐藏或者启用)
  4. $u.message.confirm(tips).then(async () => {
  5. await menuApi.HideOrShowDevMenu();
  6. $u.message.success('操作成功,请刷新菜单页面,查看变化。');
  7. setTimeout(() => {
  8. window.location.reload();
  9. }, 1000);
  10. });
  11. }

其中 $u.message 是我们注入的一个全局对象的调用方式,具体操作方式,请参考随笔《在基于vue-next-admin的Vue3+TypeScript前端项目中,为了使用方便全局挂载对象接口》进行了解。

这样显示/禁用测试案例的菜单,就可以正常的随意处理了。

3、文件管理增加分组ID

Admin.NET框架的文件表结构如下所示。

我在以前使用文件的时候,倾向于添加一个附件组,这样在实际业务处理的时候,不用记录多个附件ID的记录,只需要引用一个附件组的ID即可,因此我也希望保留这个方式来绑定多个附件的展示处理。

因此在原有表的基础上增加一个GroupId的字段,如下所示。

调整前后端的代码,让它和其他字段一样能够生效。

例如后端进行分页查询的时候,我们增加对分组ID的判别,如下代码所示。

  1. /// <summary>
  2. /// 获取文件分页列表
  3. /// </summary>
  4. /// <param name="input"></param>
  5. /// <returns></returns>
  6. [DisplayName("获取文件分页列表")]
  7. public async Task<SqlSugarPagedList<SysFile>> GetPage([FromQuery] PageFileInput input)
  8. {
  9. return await _sysFileRep.AsQueryable()
  10. .WhereIF(!string.IsNullOrWhiteSpace(input.FileName), u => u.FileName.Contains(input.FileName.Trim()))
  11. //增加分组ID查询
  12. .WhereIF(!string.IsNullOrWhiteSpace(input.GroupId), u => u.GroupId.Equals(input.GroupId.Trim(), StringComparison.OrdinalIgnoreCase))
  13. .WhereIF(!string.IsNullOrWhiteSpace(input.StartTime.ToString()) && !string.IsNullOrWhiteSpace(input.EndTime.ToString()),
  14. u => u.CreateTime >= input.StartTime && u.CreateTime <= input.EndTime)
  15. .OrderBy(u => u.CreateTime, OrderByType.Desc)
  16. .ToPagedListAsync(input.Page, input.PageSize);
  17. }

另外我们增加一个根据分组ID进行查询列表的操作,便于我们在前端根据分组获得对应的文件列表。

  1. /// <summary>
  2. /// 获取指定附件组GUID的附件列表
  3. /// </summary>
  4. /// <param name="groupId">附件组GUID</param>
  5. /// <returns></returns>
  6. [DisplayName("获取指定附件组GUID的附件列表")]
  7. public async Task<List<SysFile>> GetFilesByGroupId(string groupId)
  8. {
  9. var list = new List<SysFile>();
  10. if(!string.IsNullOrWhiteSpace(groupId))
  11. {
  12. list = await _sysFileRep.GetListAsync(u => u.GroupId == groupId);
  13. }
  14. return list;
  15. }

其他地方进行适当的调整,以便能够使得分组ID真正的好用,便利即可。

在前端代码里面,我们增加对应分组ID查询文件的接口,如下代码所示。

  1. import { BaseNormal } from './base-api';
  2. import { FileInput, FileOutput, SysFile } from '/@/api/models';
  3. /**
  4. * 系统文件 管理Api
  5. */
  6. class SysFileApi extends BaseNormal {
  7. .............

  8. /**获取指定附件组ID的附件列表 */
  9. GetFilesByGroupId = async (groupId: string) => {
  10. const url = this.baseUrl + `/FilesByGroupId/${groupId}`;
  11. return await this.axiosInstance.get<UnifyResult<Array<SysFile>>>(url, { params: null })
  12. }
  13. }
  14. export default new SysFileApi('/api/sysFile');

在查看附件或者上传附件的时候,我们指定对应的groupId就可以了,由于为了方便展示附件列表,我们通过自定义组件的方式,绑定它的分组ID进行处理。

  1. <div>
  2. <my-upload v-model="attachGroupId" :data="{ groupId: attachGroupId, path: '' }" :is-avatar-upload="false"
  3. :show-file-list="true" :is-show-tip="true" />
  4. </div>
  5. <div>
  6. <my-attachment v-model="attachGroupId"></my-attachment>
  7. </div>

例如附件列表,我们在请求数据的时候,如下代码所示。

  1. getData() {
  2. // console.log(this.modelValue);
  3. if (!isEmpty(this.modelValue)) {
  4. fileApi.GetFilesByGroupId(this.modelValue).then(data => {
  5. this.attachFiles = data.data.result!;
  6.  
  7. // 生成并添加预览图片列表
  8. this.imageList = [];
  9. this.attachFiles.map(item => {
  10. if (item.url && this.isImage(item)) {
  11. this.imageList.push(item.url!);
  12. }
  13. });
  14. });
  15. }

附件列表的界面效果如下所示,可以通过绑定GroupId的方式,展示多个附件列表了。

如果需要上传,那么使用封装的上传附件的控件展示,并绑定对应的GroupId就可以展示多个文件列表了

基于Admin.NET框架的前端的一些改进和代码生成处理(2)的更多相关文章

  1. 在基于ABP框架的前端项目Vue&Element项目中采用电子签名的处理

    在前面随笔介绍了<在基于ABP框架的前端项目Vue&Element项目中采用电子签章处理文件和打印处理>的处理,有的时候,我们在流程中或者一些文件签署的时候,需要签上自己的大名,一 ...

  2. Uwl.Admin开源框架(一)

    1.前言 作为一个忠实的软粉,一直期待微软出跨平台,一直在等待.Net Core,因为刚毕业对于.Net的很多东西不是很熟知,就开始了.Net Core的摸索,一路上坎坎坷坷,对于新技术一直很期待,就 ...

  3. 基于AngularJS的个推前端云组件探秘

    基于AngularJS的个推前端云组件探秘 AngularJS是google设计和开发的一套前端开发框架,帮助开发人员简化前端开发的负担.AngularJS将帮助标准化的开发web应用结构并且提供了针 ...

  4. 基于AngularJS的企业软件前端架构[转载]

    这篇是我参加QCon北京2014的演讲内容: 提纲: 企业应用在软件行业中占有很大的比重,而这类软件多数现在也都采用B/S的模式开发,在这个日新月异的时代,它们的前端开发技术找到了什么改进点呢? B/ ...

  5. 基于Java Netty框架构建高性能的部标808协议的GPS服务器

    使用Java语言开发一个高质量和高性能的jt808 协议的GPS通信服务器,并不是一件简单容易的事情,开发出来一段程序和能够承受数十万台车载接入是两码事,除去开发部标808协议的固有复杂性和几个月长周 ...

  6. 基于Typecho CMS框架开发大中型应用

    基于Typecho CMS框架开发大中型应用 大中型应用暂且定义为:大于等于3个数据表的应用!汗吧! Typecho原本是一款博客系统,其框架体系有别于市面上一般意义MVC框架,主体代码以自创的Wid ...

  7. 基于layui的框架模版,采用模块化设计,接口分离,组件化思想

    代码地址如下:http://www.demodashi.com/demo/13362.html 1. 准备工作 编辑器vscode,需要安装liveServer插件在前端开启静态服务器 或者使用hbu ...

  8. 基于React的PC网站前端架构分析

    代码地址如下:http://www.demodashi.com/demo/12252.html 本文适合对象 有过一定开发经验的初级前端工程师: 有过完整项目的开发经验,不论大小: 对node有所了解 ...

  9. 微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示

    1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发.微信公众平台定制开发,都不知道这些能给 ...

  10. 基于asp.net(C#)MVC+前端bootstrap+ztree+lodash+jquery技术-Angel工作室通用权限管理

    一.Angel工作室简单通用权限系统简介 AngelRM(Asp.net MVC Web api)是基于asp.net(C#)MVC+前端bootstrap+ztree+lodash+jquery技术 ...

随机推荐

  1. MATLAB 多行注释

    自用的两种方法 1: %{ 若干语句 } % 2.快捷键CTRL+R,取消注释CTRL+T

  2. JS笔记(三):函数与对象

    镇楼图 Pixiv:torino 四.Function类型 Rest语法 一些函数如Math.max可以支持任意数量的参数,JS中对于这样的参数可以简单使用...来实现,使用剩余参数,它支持收集剩余的 ...

  3. Idea项目构建时解决方法

    java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: GC overhead limit exceeded 整 ...

  4. 下载并安装Swagger-ui和Swagger-edit

    1. github上下载好Swagger-ui和Swagger-edit文件 https://github.com/swagger-api/swagger-ui https://github.com/ ...

  5. MAC完整的地址

    作者:匿名用户 链接:https://www.zhihu.com/question/22883229/answer/71280098 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

  6. (瞎学系列)RISC-V & ARM & x86

    reduced instruction set computing (RISC) -> ARM & RISC-V complex instruction set computing (C ...

  7. C++ 几款IDE和编程平台的选择分析

    最近闲来无事,就研究了一下几个编程平台和IDE.首先,我必须强调一下,这些方案研究并不一定适用于商业公司内部编程平台选择,而是给个人学习或者闲暇之余把玩用的.主要从以下几个指标考量:使用体验.跨平台. ...

  8. 前端复习之HTML5

      HTML5 Day01:   *概念:     *HTML5之后,声明不在出现版本信息     *HTML5永远不可能离开JavaScript.     *HTML5在移动端支持好于PC端   * ...

  9. python&C++区别

    1.类的定义  struct ListNode {  *     int val;  *     ListNode *next;  *     ListNode(int x) : val(x), ne ...

  10. Ubuntu NVIDIA显卡驱动+CUDA安装(多版本共存)

    NVIDIA显卡驱动 1.禁止集成的nouveau驱动 solution 1 (recommand) # 直接移除这个驱动(备份出来) mv /lib/modules/3.0.0-12-generic ...