PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)

embedded/2024/10/7 13:20:49/

作为“贴代码”力推的一个CRUD实践项目PasteTemplate,在对现有的3个项目进行实战后效果非常舒服!下面就针对PasteForm为啥我愿称为最佳CRUD做一些回答:
image

哪里可以下载这个PasteForm的项目案例

目前“贴代码”对外使用PasteForm的项目有"贴Builder(PasteSpider)"和案例项目(PasteTemplate),其中案例项目你可以在
https://gitee.com/pastecode/paste-template 获得

PasteForm的CRUD模式有什么特色?

搞这个的起初是因为我有一个项目要在小程序上行实现大量的表单,思考了下,一大堆相似的代码,不是可以使用那个组件的方式实现么,那就需要传入模型,换位思考下,那么我们经常使用的CRUD是否也可以这么搞?
于是就有了这个利用多数据模型Dto和反射的原理实现的PasteForm,主要优点如下

1.PasteForm输出的是一个思想,就是管理端的页面由后端控制,无论是安全性还是数据的表现

2.前端编写一次后,后续都不用编写,如果你使用的是我的案例项目,那么你前端都可以不用编写,包括后端要新增表,修改字段等,前端都不再需要修改代码

3.前端页面的超简洁性,无论你的后端是30个表还是100个表,对于前端来说都差不多大概4个页面搞定!当然了一些特殊的需求,还是需要编写下的!

4.无语言限制,上面说得输出的是一个思想,本文的案例使用的是.netcore+html的形式实现的,你也可以使用比如java+vue的模式

5.统一性,比如你30个表的图片上传,在表单中他们的样式都是一样的,因为他们其实使用的是同一个管理端页面

6.后端统筹所有,比如字段的显示顺序,字段是否显示,字段的默认值等等等,都由后端对应的Dto来限制和控制,比如同样的新增,由于当前登陆用户的角色不同,你可以限制某一个字段张三必填,而李四可以是选填!

image

看到管理端的代码,感觉像JSP的?

整个PasteForm的原理就是后端把数据模型的属性,字段等返回给前端,前端基于后端返回的数据再渲染到UI上,为了便于编写所以采用了template的模式,其实不是JSP,是长得像而已!

我的项目拥有120个数据表,那是不是要编写很多的后端文件?

PasteForm原则上只有3个页面pasteform/index.html,pasteform/view.html,pasteform/detail.html,只是有一些特殊情况下,会添加一些页面,这个要看你项目的实际需求,其实无论多少个表,PasteForm的页面都只是那么几个,比如说权限的页面为pasteform/index.html?path=roleInfo而用户的表为pasteform/index.html?path=userInfo,你会发觉其实他们是同一个页面,只是参数path不一样而已,这个path就是WebApi的Service!
其实你完全可以一个页面都不写,直接使用我提供的案例项目PasteTemplate中的pasteform的文件!
image

我看案例PasteTemplate项目是使用html,js,css编写的,可以使用vue编写管理端么?

上面提到的,PasteForm主要输出的是一个思想,也就是由后端的Dto控制前端的页面呈现和交互等,所以从WebApi中请求得到模板得属性字段等信息后,你可以使用其他语言实现管理端得页面得,不限原生,vue,angular等

pasteform/index.html是干嘛用?

作为对应数据表得数据展示用,一般为表格table呈现,对应模型为XXXListDto,也包括了搜索区域,搜索区域由对应得InputQueryXXX的数据模型决定,一般只有page,size,word三个字段!当然了这个页面也包含了新增数据,编辑,详情,删除等的操作交互!

pasteform/view.html是做什么用得?

新增数据,或者编辑数据的时候使用的都是这个页面,不过他们读取的数据模型不一样,比如权限这个表roleInfo,则有新增的时候为pasteform/view.html?path=roleInfo,对应的数据模型为roleInfoAddDto,而在编辑的时候为pasteform/view.html?path=roleInfo&id=3,对应的数据模型为roleInfoUpdateDto。页面的整体逻辑就是从WebApi中获得对应模型后,基于规则渲染到UI中,包括默认值,当前值等,提交的时候再从页面中的form读取到值提交给后端,所以说主要的控制还是在后端中!

pasteform/detail.html是做什么用得?

有些时候我们的数据没办法在pasteform/index.html页面中显示完成,比如文章列表,主要是一些字段过长的,这个时候我们希望有一个页面显示详细内容,所以detail就是干这个用的,对应的数据模型为XXXDto!

我不会.netcore可以用其他语言写pasteform么

PasteForm输出的是一个思想,所以使用其他语言也是可以的,不过你得对着写一整套的就是了,比如你可以使用vue+java的模式搞一套!后端核心代码案例

        /// <summary>/// 读取AddDto的数据模型/// </summary>/// <returns></returns>[HttpGet][TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]public PasteBuilderHelper.VoloModelInfo ReadAddModel(){var _model = PasteBuilderHelper.ReadModelProperty<RoleInfoAddDto>(new RoleInfoAddDto());return _model;}/// <summary>/// 读取UpdateDto的数据模型/// </summary>/// <returns></returns>[HttpGet][TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]public async Task<PasteBuilderHelper.VoloModelInfo> ReadUpdateModel(int id){var _query = from a in _dbContext.RoleInfojoin b in _dbContext.RoleInfo on a.FatherId equals b.Id into cfrom rol in c.DefaultIfEmpty()select new RoleInfoUpdateDto{Id = a.Id,Desc = a.Desc,FatherId = a.FatherId,Icon = a.Icon,IsEnable = a.IsEnable,Model = a.Model,Name = a.Name,Path = a.Path,Role = a.Role,RoleType = a.RoleType,Sort = a.Sort,ExtendRole = rol != null ? new RoleShortModel{Id = rol.Id,Model = rol.Model,Name = rol.Name,Path = rol.Path,Role = rol.Role,RoleType = rol.RoleType} : null};var _info = await _query.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();if (_info == null || _info == default){throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");}var _dataModel = PasteBuilderHelper.ReadModelProperty<RoleInfoUpdateDto>(_info);return _dataModel;}/// <summary>/// 读取UpdateDto的数据模型/// </summary>/// <returns></returns>[HttpGet][TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]public async Task<PasteBuilderHelper.VoloModelInfo> ReadDetailModel(int id){var _query = from a in _dbContext.RoleInfojoin b in _dbContext.RoleInfo on a.FatherId equals b.Id into cfrom rol in c.DefaultIfEmpty()select new RoleInfoDto{Id = a.Id,Desc = a.Desc,FatherId = a.FatherId,Icon = a.Icon,IsEnable = a.IsEnable,Model = a.Model,Name = a.Name,Path = a.Path,Role = a.Role,RoleType = a.RoleType,SortStr = a.SortStr,FatherStr = a.FatherStr,Level = a.Level,RootId = a.RootId,Sort = a.Sort,ExtendRole = rol != null ? new RoleShortModel{Id = rol.Id,Model = rol.Model,Name = rol.Name,Path = rol.Path,Role = rol.Role,RoleType = rol.RoleType} : null};var _info = await _query.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();if (_info == null || _info == default){throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");}var _dataModel = PasteBuilderHelper.ReadModelProperty<RoleInfoDto>(_info);return _dataModel;}/// <summary>/// 读取ListDto的数据模型/// </summary>/// <returns></returns>[HttpGet][TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "root", "root" })]public PasteBuilderHelper.VoloModelInfo ReadListModel(){var _model = PasteBuilderHelper.ReadModelProperty<RoleInfoListDto>(new RoleInfoListDto());var _query_model = PasteBuilderHelper.ReadModelProperty(new InputQueryRoleInfo());if (_query_model != null){_model.QueryProperties = _query_model.Properties;}return _model;}

PasteForm使用到的各个模型是干嘛用的,Dto

我最早接触Dto的时候是ABPvNext,说到这个Dto不得不说ObjectMapper,比如说权限表RoleInfo,则对应的有RoleInfoAddDto,RoleInfoUpdateDto,RoleInfoDto和RoleInfoListDto,当前实际开发中你可能还会引申出更多的Dto,比如我常用的RoleMenuDto,RoleAuthDto等,PasteForm中主要用到前面的4个,一般还会附带一个InputQueryRoleInfo!比如说新增的时候,用户提交的数据模型是RoleInfoAddDto,提交给API后,API处数据校验合法后再使用AutoMapper把RoleInfoAddDto转化成RoleInfo,然后写入到数据库!
XXXAddDto:用于新增的时候的数据模型,对应的是pasteform/view.html页面使用
XXXUpdateDto:用于数据编辑修改的数据模型,对应的是pasteform/view.html页面使用
XXXDto:这里我一般用于显示详情的时候的数据模型,也就是pasteform/detail.html的页面使用
XXXListDto:这里一般使用于数据表格展示的时候的数据模型,也就是pasteform/index.html的页面使用
InputQueryXXX:这里一般用于表格上方的搜索项的数据模型,也就是pasteform/index.html的搜索区域使用

如何上传图片?

图片分新增编辑和展示,展示的话这里就是pasteform/index.html和pasteform/detail.html页面中了,其实在编辑的时候pasteform/view.html页面上也有展示,只要给对应字段添加属性[ColumnDataTypeAttribute(“image”,“1”,“image”,“60*60”)]即可

        /// <summary>/// 多图 回传的值是多个的,使用,隔开/// </summary>[ColumnDataType("image", "3", "img", "60*60")]public string Img2 { get; set; }/// <summary>/// 图片 回传的使用string[]的模式/// </summary>[ColumnDataType("image", "3", "img", "60*60")]public string[] Img3 { get; set; }

表格中如何让数据左靠

        ///<summary>///文本区域 模拟文本区域的输入///</summary>[ColumnDataType("class","fleft")]public string Desc { get; set; }

表格中如何自定义显示

        ///<summary>///单选 一般表示状态,内定的,有点像Enum,关于Enum后续会支持///</summary>[ColumnDataType("html", "<div>{{:=item.dateType}}-{{:=item.gradeId}}</div>")]public int DateType { get; set; }

表格中如何显示按钮

        /// <summary>/// 普通菜单/// </summary>[ColumnDataType("menu", "菜单一", "open_window('查阅用户带参','./index.html?path=userInfo&xxid={{:=item.id}}');", "Hui-iconfont-menu")]public string Menu2 { get; set; }

表格中如何显示条件按钮

有些时候我们需要基于当前行数据进行判断,是否显示某一个按钮,则有

        /// <summary>/// 普通条件菜单/// </summary>[ColumnDataType("ifmenu", "item.age==7", "<a href=\"javascript:;\" onclick=\"open_window(`111`,`./index.html?path=userInfo&goid={{:=item.id}}`)\">条件1</a>", "")]public string Menu3 { get; set; }

按钮太多,如何使用按钮盒子

        /// <summary>/// 菜单盒子菜单/// </summary>[ColumnDataType("menu", "菜单二", "open_window('查阅用户带参','./index.html?path=userInfo&xxid={{:=item.id}}');", "Hui-iconfont-menu", "box")]public string Menu5 { get; set; }/// <summary>/// 菜单盒子中的条件菜单/// </summary>[ColumnDataType("ifmenu", "item.age==8", "<a href=\"javascript:;\" onclick=\"open_window(`222`,`./index.html?path=userInfo&goid={{:=item.id}}`)\">条件2</a>", "box")]public string Menu4 { get; set; }

按照排序查下,某些字段支持升序降序

前端只是基于这个属性,在查下的时候会回传orderby字段给后端,后续需要基于回传的这个字段进行orderby查询

///<summary>///排序///</summary>[ColumnDataType("orderby", "Sort","Sort desc")]public int Sort { get; set; }

— 未完待续,下期继续 —


http://www.ppmy.cn/embedded/124103.html

相关文章

SSH(安全外壳协议)可以基于多种加密算法

SSH&#xff08;安全外壳协议&#xff09;可以基于多种加密算法&#xff0c;确保数据的机密性和完整性。以下是 SSH 中常见的加密类型&#xff1a; 1. 对称加密 对称加密算法用于加密会话中的数据&#xff0c;常见的算法包括&#xff1a; AES&#xff08;高级加密标准&#…

Spring Boot 3.x 集成 Feign

在Spring Boot 3.x中集成Feign&#xff0c;可以大大简化微服务之间的HTTP调用。以下是关于Spring Boot 3.x集成Feign的详细步骤和说明&#xff1a; 一、Feign简介 Feign是一个声明式的HTTP客户端&#xff0c;它使得编写Web服务客户端变得更加简单。使用Feign&#xff0c;可以通…

Python开发环境配置(mac M2)

1. 前言 作为一名程序员&#xff0c;工作中需要使用Python进行编程&#xff0c;甚至因为项目需要还得是不同版本的Python如何手动管理多个版本的Python&#xff0c;如何给Pycharm&#xff08;IDE&#xff09;配置对应的interpreter等&#xff0c;都成为一个 “不熟练工” 的难…

鼓组编写:SsdSample鼓映射 GM Map 自动保存 互换midi位置 风格模板 逻辑编辑器

SsdSample音源的键位映射 方便编写鼓的技巧 可以这样去设置键位关系的面板和钢琴卷帘窗的面板&#xff0c;方便去写鼓。 可以先按GM的midi标准去写鼓&#xff0c;然后比对下鼓的键位映射的关系&#xff0c;去调整鼓。 可以边看自己发b站等处的图文笔记&#xff0c;然后边用电…

ELK日志收集之ES的DSL查询语句

一、简介 在Elasticsearch中&#xff0c;我们可以使用Elasticsearch-DSL(Elasticsearch Domain Specific Language)来构建和执行复杂的搜索查询。官方Query DSL指导文档。 叶查询&#xff1a;在特定字段中寻找特定值,例如 match ,term 或 range。 复合查询&#xff1a;具有查询…

js采用覆盖键、覆盖鼠标滑动事件实现禁止网页通过 ctrl + +/- 和 ctrl + 滚轮 对页面进行缩放

一、兼容电脑端的禁止通过 ctrl /- 和 ctrl 滚轮 对页面进行缩放 const keyCodeMap {// 91: true, // command61: true,107: true, // 数字键盘 109: true, // 数字键盘 -173: true, // 火狐 - 号187: true, // 189: true, // -};二、覆盖ctrl||command ‘’/‘-’ // 覆…

汇编内存寻址

处理字符问题 汇编程序中,用单引号(‘’)的方式指明数据是以字符的形式给出,编译器将把字符转换为相对应的ASCLL码。 大写字母ASCLL值 20H 转换为小写字母 (或运算or) 0010 0000 小写字母ASCLL值 - 20H 转换为大写字母 (与运算and) 1101 1111 示例: 大小写转换 assume c…

2024计算机毕业设计最简单的完成流程

一、计算机专业毕业设计选题-选题推荐 1.基于深度学习的生活垃圾智能分类系统&#xff08;微信小程序YOLOv5训练数据集开题报告中期检查论文&#xff09; &#xff08;1&#xff09;程序界面 &#xff08;2&#xff09;论文大纲 &#xff08;3&#xff09;论文详情链接 基于…