PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)
作为“贴代码”力推的一个CRUD实践项目PasteTemplate,在对现有的3个项目进行实战后效果非常舒服!下面就针对PasteForm为啥我愿称为最佳CRUD做一些回答:
哪里可以下载这个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来限制和控制,比如同样的新增,由于当前登陆用户的角色不同,你可以限制某一个字段张三必填,而李四可以是选填!
看到管理端的代码,感觉像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的文件!
我看案例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; }
— 未完待续,下期继续 —
相关文章:

PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)
作为“贴代码”力推的一个CRUD实践项目PasteTemplate,在对现有的3个项目进行实战后效果非常舒服!下面就针对PasteForm为啥我愿称为最佳CRUD做一些回答: 哪里可以下载这个PasteForm的项目案例 目前“贴代码”对外使用PasteForm的项目有"贴Builder(PasteSpide…...
【无标题】logistic映射
当Logistic映射中的控制参数 μ \mu μ 为负数时,系统的行为与正数 μ \mu μ 的情况截然不同。Logistic映射的一般形式是: x ( t 1 ) μ x ( t ) ( 1 − x ( t ) ) x(t1) \mu x(t) (1 - x(t)) x(t1)μx(t)(1−x(t))其中 x ( t ) x(t) x(t) 表示时…...

基于Node.js+Express+MySQL+VUE科研成果网站发布查看科研信息科研成果论文下载免费安装部署
目录 1.技术选型 2.功能设计 3.系统架构 4.开发流程 5.开发背景 6.开发目标 7.技术可行性 8.功能可行性 8.1功能图 8.2 界面设计 8.3 部分代码 构建一个基于Spring Boot、Java Web、J2EE、MySQL数据库以及Vue前后端分离的科研成果网站,可…...
提升C++代码质量的一些建议
文章目录 1. 命名清晰2. 简洁性3. 一致性4. 注释5. 避免复杂性6. 重构7. 测试8. 错误处理9. 文档10. 代码复用11. 性能优化12. 安全性- 代码规范推荐 C开发中,写出优雅且可维护的代码不仅能提升代码质量,还能提高团队协作效率和项目长期的可扩展性。以下…...

起重机防摇摆技术如何达标-武汉正向科技
武汉正向科技防摇摆控制器 主要技术参数 1、防摇摆精度: 0.4 2、行车到达目标位置偏差位置偏差: 25mm 3、通讯方式:PROFINET / PROFIBUS / RS232 / RS422 / RS485; 4、消除载荷的摇摆达 96% 以上; 5、技术先进…...

[大语言模型-论文精读] MoRAG - 基于多部分融合的检索增强型人体动作生成
MoRAG--Multi-Fusion Retrieval Augmented Generation for Human Motion KS Shashank, S Maheshwari, RK Sarvadevabhatla - arXiv preprint arXiv:2409.12140, 2024 MoRAG - 基于多部分融合的检索增强型人体动作生成 1. 目录 MoRAG--Multi-Fusion Retrieval Augmented Generat…...

解决端口被占用
当你被你的编译器提醒, 当前端口被占用, 但明明你的服务什么的都没有启用,这时有三种解决办法: 1 。 重启 。 重启解决80%的问题 2 。 修改你的端口号 。 3 。 去windows命令行中查看,端口占用情况 第一步 …...

【递归】7. leetcode 404 左叶子之和
1 题目描述 题目链接:左叶子之和 2 解答思路 递归分为三步,接下来就按照这三步来思考问题 第一步:挖掘出相同的子问题 (关系到具体函数头的设计) 第二步:只关心具体子问题做了什么 (关系…...

react+antdMobie实现消息通知页面样式
一、实现效果 二、代码 import React, { useEffect, useState } from react; import style from ./style/index.less; import { CapsuleTabs, Ellipsis, Empty, SearchBar, Tag } from antd-mobile; //消息通知页面 export default function Notification(props) {const [opti…...

Git 撤销一个已经push到远端仓库的commit
在 Git 中,撤销一个已经推送到远程仓库的改动有几种不同的方法,具体取决于你是否想要完全删除改动,还是只是恢复文件的某个状态。以下是常见的几种方法: git revert 撤销特定的commit git revert 是最安全的方法,因为…...

lambda表达式底层实现
一、lambda 代码 & 反编译 原始Java代码 假设我们有以下简单的Java程序,它使用Lambda表达式来遍历并打印一个字符串列表: import java.util.Arrays; import java.util.List;public class LambdaExample {public static void main(String[] args) {…...

鸿蒙NEXT开发-组件事件监听和状态管理(基于最新api12稳定版)
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...

《More Effective C++》的学习
引用与指针 没有所谓的null reference reference一定需要代表某个对象,所以C要求reference必须有初值。 QString &s; 使用reference可能比使用pointer更高效。 因为reference一定是有效的,而指针可能为空(需要多加一个判断࿰…...

Leetcode面试经典150题-322.零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...

python17_len()函数
len()函数 A B "" C "hello world" D 18 E 18def len_test(s):try:# 尝试计算字符串的长度length len(s)return lengthexcept TypeError:# 如果不是字符串,则返回 None 或者提示错误return Noneif __name__ "__main__":# 单…...

车视界系统小程序的设计
管理员账户功能包括:系统首页,个人中心,汽车品牌管理,汽车颜色管理,用户管理,汽车信息管理,汽车订单管理系统管理 微信端账号功能包括:系统首页,汽车信息,我…...
SQLCMD命令行工具导入数据并生成对应的日志文件
SQLCMD是一个命令行工具,专门用于在Microsoft SQL Server数据库上运行SQL脚本和管理任务。它提供了一种交互式和自动化的方式来执行SQL命令和脚本,并允许用户与SQL Server数据库进行高效的交互。以下是关于SQLCMD的详细介绍: 主要功能 执行SQL脚本: SQLCMD可以执行包含SQL…...

tauri中加载本地文件图片或者下载网络文件图片后存储到本地,然后通过前端页面展示
有一个需求是需要将本地上传的文件或者网络下载的文件存储到本地,并展示在前端页面上的。其实如果只是加载本地文件,然后展示还是挺简单的,可以看我的文章:tauri程序加载本地图片或者文件在前端页面展示-CSDN博客 要想实现上述需…...

QSqlDatabase在多线程中的使用
Qt中多线程使用数据库_qt数据库管理类支持多数据库,多线程-CSDN博客 1. 代码: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError>…...

【无人机设计与控制】Multi-UAV|多无人机多场景路径规划算法MATLAB
摘要 本研究探讨了多无人机路径规划问题,提出了三种不同算法的对比分析,包括粒子群优化(PSO)、灰狼优化(GWO)和鲸鱼优化算法(WOA)。利用MATLAB实现了多场景仿真实验,验证…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...