数据库动态视图和存储过程报表数据管理功能设计

需求:需要将ERP的报表数据挪到OA中,但是OA表单设计不支持存储过程动态传参,所以需要设计一个系统,可以手动配置,动态显示原本ERP的报表数据,ERP报表是存在数据库的视图和存储过程中

思路:因为ERP数据库只有一个,所以不需要考虑多数据源问题(当然这个也很好解决),动态sql拼接,存储过程原本想用临时表的方式解决结果集字段查询和分页问题,但是后来觉得太麻烦了,选择程序中解决,毕竟数据量最多的也就一两万条,使用list的截取实现分页

后端:spring
前端:element

效果截图:
管理界面:
在这里插入图片描述
新增界面:
在这里插入图片描述
修改界面:
视图没有必要参数,因为视图可以通过where查询,默认都是结果集筛选参数
在这里插入图片描述
展示页面效果(用于外挂在OA系统里):
(展示页面只有一个文件,动态展示数据,根据管理页面中注释字段区分)
在这里插入图片描述
所有筛选参数和展示字段也都是动态显示
在这里插入图片描述

针对不同字段的动态处理:
日期:
在这里插入图片描述
客户和供应商,采购员,员工,销售员都是对应数据的下拉带搜索:
在这里插入图片描述
在这里插入图片描述
后台配置筛选参数的时候,字段名叫日期会去调用日期选择,字段叫客户会调用所有客户信息选择,字段名叫供应商会去调用所有供应商信息,字段名带员的(人员,员工,采购员,销售员)会去调用员工信息选择(这些都是前端设置的,不想后端在加一个类型字段来区分了,直接用名字区分)

数据库表结构:
主表:
在这里插入图片描述
从表(用于筛选字段):
在这里插入图片描述
部分代码:
页面获取参数信息(根据展示页面url的参数):

@RequestMapping("/getcanshu")public R getcanshu(@RequestParam("name") String zhushi){QueryWrapper<XinxiShituzhuEntity> query = new QueryWrapper();query.eq("zhushi", zhushi);XinxiShituzhuEntity zhudata = xinxiShituzhuService.getOne(query);Integer zhuid = zhudata.getId();QueryWrapper<XinxiShitucongEntity> congquery = new QueryWrapper();congquery.eq("fatherid", zhuid);List<XinxiShitucongEntity> congdata = xinxiShitucongService.list(congquery);zhudata.setCanshu(congdata);return R.ok().put("data", zhudata);}

获取展示页面查询数据:

@RequestMapping("/getalldatas")public R getalldatas(@RequestBody XinxiShituzhuEntity xinxiShituzhu){// 视图if(xinxiShituzhu.getBtype()==1){// 拼接sqlString querySql = "SELECT * FROM "+xinxiShituzhu.getName() +" WHERE 1=1 ";String countsql = "SELECT COUNT(1) FROM "+xinxiShituzhu.getName() +" WHERE 1=1 ";List<XinxiShitucongEntity> congdatas = xinxiShituzhu.getCanshu();for(XinxiShitucongEntity data: congdatas){if(!Objects.equals(data.getZdzhi(), "")&& data.getZdzhi()!=null){querySql = querySql + " AND ["+data.getName()+"]= '"+data.getZdzhi()+"'";countsql = countsql + " AND ["+data.getName()+"]= '"+data.getZdzhi()+"'";}}// 添加分页querySql = querySql + " order by ["+ xinxiShituzhu.getPaixuzd() +"] offset "+(xinxiShituzhu.getPageNum()-1)*xinxiShituzhu.getPageSize()+" row fetch next "+xinxiShituzhu.getPageSize()+" row only;";List<Map<String, Object>> zhudatas = xinxiShituzhuService.getAllShituDatas(querySql);// 总数Integer zhucount = xinxiShituzhuService.getAllShituCount(countsql);// 获取所有表头,用于展示页表头信息List<Map<String, Object>> newdatas = new ArrayList<>();for(Map<String, Object> data : zhudatas){for(String key: data.keySet()){Map<String, Object> newmapdata = new LinkedHashMap<>();newmapdata.put("key", key);newdatas.add(newmapdata);}
//                Collections.reverse(newdatas);break;}return R.ok().put("count", zhucount).put("data", zhudatas).put("headdata", newdatas);}// 存储过程else{// 拼接sqlString querySql = "EXEC ["+xinxiShituzhu.getName()+"]";List<XinxiShitucongEntity> congdatas = xinxiShituzhu.getCanshu();List<String> canshus = new ArrayList<>();// 遍历所有参数for(XinxiShitucongEntity data: congdatas){// 视图必要参数添加if(Objects.equals(data.getZdtype(), "1")){if(!Objects.equals(data.getZdzhi(), "")&& data.getZdzhi()!=null){canshus.add(" @"+data.getName()+"= '"+data.getZdzhi()+"'");// querySql = querySql + " @"+data.getName()+"= '"+data.getZdzhi()+"'";}else{return R.error("必要参数不能为空");}}}if(canshus.size()>0){querySql = querySql + StringUtils.join(canshus, ",");}// 获取所有数据List<Map<String, Object>> zhudatas = xinxiShituzhuService.getAllShituDatas(querySql);List<Map<String, Object>> newdatas = new ArrayList<>();// 遍历结果集,用于结果集的字段筛选for(Map<String, Object> dataxx: zhudatas){// 用于标记筛选字段有效性List<Boolean> biaojis = new ArrayList<>();for(XinxiShitucongEntity data: congdatas){if(Objects.equals(data.getZdtype(), "2")){if(!Objects.equals(data.getZdzhi(), "")&& data.getZdzhi()!=null){if(ObjectUtil.isNotNull(dataxx.get(data.getName())) && dataxx.get(data.getName()).equals(data.getZdzhi())){// 如果被其中一个条件筛选出来就给整条数据标记truebiaojis.add(true);}else{// 如果被其中一个条件没有筛选出来就给整条数据标记falsebiaojis.add(false);}}else{// 筛选条件没有填的是都要筛选的biaojis.add(true);}}}// 只有没有false标记的数据才是被筛选出来的if(!biaojis.contains(false)){newdatas.add(dataxx);}}// 总数Integer zhucount = newdatas.size();int pagenum = (xinxiShituzhu.getPageNum()-1)*xinxiShituzhu.getPageSize();int pagesize = pagenum + xinxiShituzhu.getPageSize();// list截取List<Map<String, Object>> newzhudatas = CollectionUtil.sub(newdatas, pagenum, pagesize);List<Map<String, Object>> newheaddatas = new ArrayList<>();// 获取表头信息for(Map<String, Object> data : newzhudatas){for(String key: data.keySet()){Map<String, Object> newmapdata = new LinkedHashMap<>();newmapdata.put("key", key);newheaddatas.add(newmapdata);}break;}return R.ok().put("count", zhucount).put("data", newzhudatas).put("headdata", newheaddatas);}}

sql拼接xml(要用LinkedHashMap类型,不然字段顺序不固定,数据展示就很难看):

 <select id="getAllShituDatas" resultType="java.util.LinkedHashMap">${shitusql}</select><select id="getAllShituCount" resultType="java.lang.Integer">${shitusql}</select>

主Entity:
在这里插入图片描述
从Entity:
在这里插入图片描述

展示页面的vue代码:

<template><div class="sanfangcangkuliang-main"><el-form :model="form" :inline="true" ><el-form-item :label="item.zdname" v-for="item of canshulist" :key="item.name" ><el-input v-model="item.zdzhi" v-if="item.zdname!='供应商' && item.zdname!='客户' && item.zdname.indexOf('员')==-1 && item.zdname!='日期'" :placeholder="item.zdtype==1?'必填':'选填'"></el-input><!-- <el-input v-model="item.zdzhi" v-if="item.zdtype==2" placeholder="选填"></el-input> --><el-select v-model="item.zdzhi" filterable clearable :placeholder="item.zdtype==1?'必填':'选填'" v-if="item.zdname=='供应商'"><el-optionv-for="item in gongyingshanglist":key="item.gys":label="item.gys":value="item.gys"></el-option></el-select><el-select v-model="item.zdzhi" filterable clearable :placeholder="item.zdtype==1?'必填':'选填'" v-if="item.zdname=='客户'"><el-optionv-for="item in kehulist":key="item.kh":label="item.kh":value="item.kh"></el-option></el-select><el-select v-model="item.zdzhi" filterable clearable :placeholder="item.zdtype==1?'必填':'选填'" v-if="item.zdname.indexOf('员')!=-1"><el-optionv-for="item in renyuanlist":key="item.yg":label="item.yg":value="item.yg"></el-option></el-select><el-date-pickerv-model="item.zdzhi"type="date"value-format="yyyy-MM-dd":placeholder="item.zdtype==1?'必填':'选填'"v-if="item.zdname=='日期'"></el-date-picker></el-form-item><el-form-item><el-button type="primary" style="display:inline-block; width: 80px;height: 40px;" @click="getList(1)">搜索</el-button><el-button style="display:inline-block; width: 80px;height: 40px;" @click="chongzhi()">重置</el-button><!-- <el-button type="success" style="display:inline-block; width: 100px;height: 40px;" @click="gengxin()">批量更新</el-button> --></el-form-item></el-form><el-paginationstyle="margin:30px"@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="mapdatas.pageNum":page-sizes="[50, 100, 200, 500, 1000, 2000, 5000]":page-size="mapdatas.pageSize"layout="total, sizes, prev, pager, next, jumper":total=total></el-pagination><el-table style="width: 100%; margin-left:40px" :data="tableData"><template v-for="(item,index) in maphead"><el-table-column :prop="item.key" :label="item.key" :key="index"></el-table-column></template></el-table><el-paginationstyle="margin:30px"@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="mapdatas.pageNum":page-sizes="[50, 100, 200, 500, 1000, 2000, 5000]":page-size="mapdatas.pageSize"layout="total, sizes, prev, pager, next, jumper":total=total></el-pagination></div>
</template>
<script>export default {data () {return {renyuanlist:[],gongyingshanglist:[],kehulist:[],form:{},maphead:[],mapdatas:{pageNum:1,pageSize:100,},canshulist:[],pageSize:100,currentPage:1,total:0,tableData: [],xiangqingshow:false,xiangqingdatas:[],tableDatazong:[],ckmclist: [],ywymc:""}},mounted(){this.getTableCanshu();this.getRenyuanDatas();this.getGyingshangDatas();this.getKehuDatas();},methods: {handleSizeChange(val) {this.mapdatas.pageSize = valthis.getList(2);},handleCurrentChange(val) {this.mapdatas.pageNum = valthis.getList(2);},getList(type){if(type==1){this.mapdatas.pageNum = 1this.mapdatas.pageSize = 100;}this.mapdatas['canshu'] = this.canshulistthis.$axios({method:'post',url:"/renren-fast/xinxi/xinxishituzhu/getalldatas",data:JSON.stringify(this.mapdatas),headers:{"Content-Type": "application/json"}}).then((response) =>{          //这里使用了ES6的语法if(response.data.code==0 || response.data.code=='0'){this.tableData = response.data.data;this.total = response.data.count;this.maphead = response.data.headdata;}else{this.$message.error(response.data.msg);this.total = 0this.mapdatas.pageNum = 1this.mapdatas.pageSize = 100;}}).catch((error) =>{console.log(error)       //请求失败返回的数据})},chongzhi(){for(let data of this.canshulist){data.zdzhi=""}this.mapdatas.pageNum = 1this.mapdatas.pageSize = 100;this.tableData = []this.getList(1)},// 获取表的参数getTableCanshu(){this.$axios({url: '/xinxi/xinxishituzhu/getcanshu',method: 'GET',params: {name: this.$route.query.name}}).then((res) => {if(res.data.code==0 || res.data.code=='0'){this.mapdatas = {btype: res.data.data.btype,deleted: res.data.data.deleted,id: res.data.data.id,name: res.data.data.name,pageNum: res.data.data.pageNum || 1,pageSize: res.data.data.pageSize || 100,paixuzd: res.data.data.paixuzd,reationtime: res.data.data.reationtime,updatetime: res.data.data.updatetime,zhushi: res.data.data.zhushi}this.canshulist = res.data.data.canshuif(res.data.data.btype==1){this.getList(1);}}})},// 获取人员getRenyuanDatas(){this.$axios({url: '/xinxi/xinxishituzhu/getyuangongdatas',method: 'GET',// params: {//     name: this.$route.query.name// }}).then((res) => {if(res.data.code==0 || res.data.code=='0'){this.renyuanlist = res.data.data;}})},// 获取供应商getGyingshangDatas(){this.$axios({url: '/xinxi/xinxishituzhu/getgongyingshangdatas',method: 'GET',// params: {//     name: this.$route.query.name// }}).then((res) => {if(res.data.code==0 || res.data.code=='0'){this.gongyingshanglist = res.data.data;}})},// 获取客户getKehuDatas(){this.$axios({url: '/xinxi/xinxishituzhu/getkehudatas',method: 'GET',// params: {//     name: this.$route.query.name// }}).then((res) => {if(res.data.code==0 || res.data.code=='0'){this.kehulist = res.data.data;}})},}
}
</script>
<style scoped>
*{margin: 0;padding: 0;
}
</style>

因为ERP有几十个报表要迁移,之前领导都是上级领导想看报表但是他们不使用ERP只使用OA,就会我们做进OA报表,只有OA实现不了的我才自己写后台接口和前端页面,这次说要全部迁移,我看一下几十个报表,如果像原来那样一个个写后台接口和前端页面的话不知道要写到什么时候,于是花了两天写了这个功能出来,目前正常使用没问题(因为存储过程必须要填参数才可以出数据,所以存储过程的展示页面需要输入必填参数以后点查询出数据,视图则是可以直接出数据)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c#按照时间进行数据存储(不用数据库)

概要介绍 按照日期生成文件夹&#xff0c;按照时间生成文件名&#xff0c;存储字符串。 可以用于简单数据记录&#xff08;如果数据存储考虑格式文本&#xff0c;保存为csv格式&#xff09; 实现效果 调用方法 SaveText.saveStr("测试字符串"DateTime.Now.ToStrin…

高效排队,紧急响应:RabbitMQ Priority Queue全面指南【RabbitMQ 九】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 高效排队&#xff0c;紧急响应&#xff1a;RabbitMQ Priority Queue全面指南 引言前言第一&#xff1a;初识RabbitMQ Priority Queue插件插件的背景和目的&#xff1a;为什么需要消息优先级&#xff1…

我的NPI项目之Android 安全系列 -- Google Wallet and Secure Element(SE)

随着电子支付的兴起&#xff0c;越来越多的支付方式出现在我们的生活中。其中就有基于NFC的“碰一碰”的支付&#xff0c;支付宝的“扫一扫”支付&#xff0c;我们还知道有Google Pay(Wallet), Apple Pay(Wallet)。作为Android BSP的开发者&#xff0c;我比较关心的是Google Pa…

Processon的使用以及流程图的绘制

目录 一、ProcessOn 1.2 官方网站 门诊流程图 会议OA流程图 药库采购入库流程图 ​住院流程图 二、Axure自定义元件库 2.1 新建元件库 2.2 自定义元件 2.3 添加元件库 一、ProcessOn ProcessOn是一款在线的流程图、思维导图、组织结构图、网络拓扑图等多种图表类型…

2020年第九届数学建模国际赛小美赛A题自由泳解题全过程文档及程序

2020年第九届数学建模国际赛小美赛 A题 自由泳 原题再现&#xff1a; 在所有常见的游泳泳姿中&#xff0c;哪一种最快&#xff1f;哪个冲程推力最大&#xff1f;在自由泳项目中&#xff0c;游泳者可以选择他们的泳姿&#xff0c;他们通常选择前面的爬行。然而&#xff0c;游泳…

Java基础面试题小结

基础面试题 Java语言简介 Java是1995年由sun公司推出的一门高级语言&#xff0c;该语言具备如下特点: 简单易学&#xff0c;相较于C语言和C&#xff0c;没有指针的概念&#xff0c;所以操作和使用是会相对容易一些。平台无关性&#xff0c;即Java程序可以通过Java虚拟机在不…

MongoDB 与 Python 的交互

文章目录 第1关&#xff1a;MongoDB 与 Python 的交互 第1关&#xff1a;MongoDB 与 Python 的交互 编程要求 根据提示&#xff0c;在右侧编辑器 Begin-End 处补充代码&#xff0c;完成右侧程序。 测试说明 点击评测&#xff0c;平台会对你编写的代码进行测试。 import pymo…

tomcat优化

目录 一.tomcat的优化 二.nginxtomcat负载均衡、动静分离 三.nginx的反向代理类型 四.nginx的调度算法&#xff08;调度策略、负载均衡模式&#xff09; 五.nginx反向代理如何实现会话保持 一.tomcat的优化 tomcat的优化分为&#xff1a;系统优化&#xff0c;配置文件参数…

GoLong的学习之路,进阶,微服务之序列化协议,Protocol Buffers V3

这章是接上一章&#xff0c;使用RPC包&#xff0c;序列化中没有详细去讲&#xff0c;因为这一块需要看的和学习的地方很多。并且这一块是RPC中可以说是最重要的一块&#xff0c;也是性能的重要影响因子。今天这篇主要会讲其使用方式。 文章目录 Protocol Buffers V3 背景以及概…

RHEL7.5编译openssl1.1.1w源码包到rpm包

openssl1.1.1w下载地址 https://www.openssl.org/source/ 安装依赖包 yum -y install curl which make gcc perl perl-WWW-Curl rpm-build wget http://mirrors.aliyun.com/centos-vault/7.5.1804/os/x86_64/Packages/perl-WWW-Curl-4.15-13.el7.x86_64.rpm rpm -ivh pe…

JVM之堆学习

一、Java虚拟机内存结构图 二、堆的介绍 1. 前面学习的程序计数器&#xff0c;虚拟机栈和本地方法栈都是线程私有的&#xff0c;堆是线程共享的&#xff1b; 2. 通过 new 关键字&#xff0c;创建的对象都会使用堆内存&#xff0c;其特点是&#xff1a; 它是线程共享的&#x…

【每日一题】【面试经典150 | 动态规划】爬楼梯

Tag 【动态规划】【数组】 题目来源 70. 爬楼梯 题目解读 有过刷题「动态规划」刷题经验的读者都知道&#xff0c;爬楼梯问题是一种最典型也是最简单的动态规划问题了。 题目描述为&#xff1a;你每次可以爬 1 或者 2 个台阶&#xff0c;问爬上 n 阶有多少种方式。 解题思路…

智能优化算法应用:基于探路者算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于探路者算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于探路者算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.探路者算法4.实验参数设定5.算法结果6.参考文…

开源书籍—鸢尾花书:从加减乘除到机器学习系列 | 开源专题 No.50

Visualize-ML/Book1_Python-For-Beginners Stars: 2.4k License: NOASSERTION 《编程不难》是一本名为鸢尾花书的开源项目&#xff0c;它从基础的加减乘除开始&#xff0c;逐步引导读者进入机器学习领域。该项目提供了 PDF 草稿和 Jupyter 笔记&#xff0c;并经过至少两轮修改…

LED恒流调节器FP7125,应用LED街道照明、调光电源、汽车大灯、T5T8日光灯

目录 一、FP7125概述 二、FP7125功能 三、应用领域 近年来&#xff0c;随着人们环保意识的不断增强&#xff0c;LED照明产品逐渐成为照明行业的主流。而作为LED照明产品中的重要配件&#xff0c;LED恒流调节器FP7125的出现为LED照明带来了全新的发展机遇。 一、FP7125概述 FP…

OBS实时字幕(第三第四种方法)

我的视频地址 https://www.bilibili.com/video/BV1uN411V7uG基于wispper的obs实时字幕插件&#xff0c;中文支持不太好&#xff0c;需要加载模型 github.com/occ-ai/obs-localvocal推荐使用这个 下面参考B站 www.bilibili.com/video/BV11u411G7Vt Curses&#xff1a;为OBS、V…

【NSX-T】7. 搭建NSX-T环境 —— 部署和配置 Edge Cluster

目录 7. 部署和配置 Edge Cluster7.1 配置 Edge 节点&#xff08;1&#xff09;Name and Description&#xff08;2&#xff09;Credentials&#xff08;3&#xff09;Configure Deployment&#xff08;4&#xff09;Configure Node Settings&#xff08;5&#xff09;Configur…

压缩软件电脑版哪个好?

压缩软件是我们存储文件、清理电脑、向他人发送文件经常用到的工具&#xff0c;下面就从头到尾操作一遍各个软件压缩步骤&#xff0c;根据需求选择好啦。可以放心的是&#xff0c;这四款软件都经过了安全测试&#xff0c;能够保证文件的安全性&#xff0c;并且能够兼容多种操作…

qt-C++笔记之模拟实现一个linux终端窗口

qt-C笔记之模拟实现一个linux终端窗口 code review! 文章目录 qt-C笔记之模拟实现一个linux终端窗口一.运行二.main.cpp三.不足&#xff0c;待改进点 一.运行 二.main.cpp 代码 #include <QApplication> #include <QPlainTextEdit> #include <QLineEdit>…

微服务技术 RabbitMQ SpringAMQP P61-P76

B站学习视频https://www.bilibili.com/video/BV1LQ4y127n4?p61&vd_source8665d6da33d4e2277ca40f03210fe53a 文档资料: 链接&#xff1a;https://pan.baidu.com/s/1P_Ag1BYiPaF52EI19A0YRw?pwdd03r 提取码&#xff1a;d03r 一 初始MQ 1. 同步通讯 2. 异步通讯 3. MQ常…