当前位置: 首页 > news >正文

一二三应用开发平台自定义查询设计与实现系列2——查询方案功能实现

查询方案功能实现

上面实现了自定义查询功能框架,从用户角度出发,有些条件组合可以形成特定的查询方案,对应着业务查询场景。诸多查询条件的组合,不能每次都让用户来设置,而是应该保存下来,下次可以直接使用或者在其基础上按需调整,也就是将查询方案持久化。

实体配置

使用平台的低代码配置功能来实现查询方案的实体配置。

考虑到自定义查询属于通用性功能,因此放到了平台架构体系中位于底层的系统管理模块下。

实体配置如下:

实体模型配置如下:

查询方案内置于自定义查询功能内部的,因此无需配置相关视图。

使用平台功能生成库表和代码、拷贝代码、编译、配置权限项。

功能整合

首先上整体效果图,有个直观的了解,如下图:

在原有基础上,顶部增加了查询方案的下拉列表,用户可以通过下拉选择快速加载先前保存的查询方案,并可以通过修改按钮来修改名称、通过删除按钮来删除方案。

查询方案的主体,仍是由筛选器组件来承担,集成整合过程中增加了交互。

底部通过保存按钮来保存查询方案;通过另存为按钮来拷贝新增方案,点击查询按钮后,关闭对话框,将查询方案对应查询条件组合,传递给父窗口(自定义查询功能页面),发起查询操作。

查询方案下拉列表实现

在查询方案目录下,新增一个select.vue的页面,源码如下:

<template><el-selectv-model="selectedValue":size="size"clearable:disabled="readonly"style="width: 200px; margin: 20 auto"@change="change"><el-optionv-for="item in dictionaryItemList":key="item.id":value="item.id":label="item.name"/></el-select></template><script>
export default {name: 'QueryPlanSelect',label: '查询方案下拉',props: {modelValue: {type: String,required: false,default: ''},code: {type: String,default: ''},readonly: {type: Boolean,required: false,default: false},size: {type: String,default: ''}},data() {return {dictionaryItemList: [],selectedValue: ''}},watch: {modelValue: {immediate: true,handler: 'setSelected'}},mounted() {this.loadData()},methods: {change(value) {let rowData = nullthis.dictionaryItemList.forEach((item) => {if (item.id === value) {rowData = itemreturn}})// 更新绑定值this.$emit('update:modelValue', value)// 注意,此处若命令为change,则可能会与底层实现冲突,导致执行两次this.$emit('my-change', value, rowData)},setSelected() {this.selectedValue = this.modelValue},loadData() {this.dictionaryItemList = []this.$api.system.queryPlan.list().then((res) => {this.dictionaryItemList = res.dataif (this.dictionaryItemList.length == 1) {this.selectedValue = this.dictionaryItemList[0].idthis.$emit('my-change', this.dictionaryItemList[0].id, this.dictionaryItemList[0])} else {this.selectedValue = ''this.$emit('my-change', '', null)}})}}
}
</script>

就是把查询方案实体的列表数据,转换为下拉列表的数据格式,并对传入值以及下拉选择变更后,将数据通过事件触发返回给父页面,也就是自定义查询页面。

查询方案下拉列表选中项变更

自定义查询页面会监听查询方案下拉列表的选择的变更,可能有两种情况,一是变更选择项,二是清空选择,对应的事件处理如下:

    // 查询方案变更queryPlanChanged(value, data) {// 保存为当前查询方案this.currentQueryPlan = dataif (data) {//加载条件this.$refs.everrightFilter.setData(JSON.parse(data.content))} else {this.$refs.everrightFilter.clearData()}}

注意当查询方案内容不为空时,调用筛选器的setData方法,来填充条件组合,便于用户查看或在其基础上调整。

查询方案改名

点击下拉列表右侧的“修改”按钮,弹出输入框,这里实际是用于改名,系统会弹出对话框,默认填充当前选中的查询方案名称,用户修改后点击确定按钮后保存,如下图:

功能实现使用了element plus的MessageBox的Prompt模式,代码如下:

    // 修改方案名称modify() {if (this.currentQueryPlan == null) {this.$message.warning('请先选择要改名的查询方案')return}//获取查询方案内容,并做非空判断const content = JSON.stringify(this.$refs.everrightFilter.getData(), null, '\t')if (this.checkContentIsNull(content)) {return}// 输入新的方案名称ElMessageBox.prompt('请输入新的方案名称', '修改查询方案', {confirmButtonText: '确定',cancelButtonText: '取消',inputValue: this.currentQueryPlan.name,inputPattern: /.+/,inputErrorMessage: '不能为空'}).then(({ value }) => {this.currentQueryPlan.name = valuethis.currentQueryPlan.content = contentthis.$api.system.queryPlan.modify(this.currentQueryPlan).then((res) => {//刷新查询方案列表this.refreshQuerPlanList()})})},

查询方案删除

点击下拉列表右侧的“删除”按钮,弹出确认框,确定后删除,如下:

源码实现如下:

 // 删除remove() {if (this.currentQueryPlan == null) {this.$message.warning('请先选择要删除的查询方案')return}this.$confirm('确定要删除该查询方案吗?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {this.$api.system.queryPlan.remove(this.currentQueryPlan.id).then((res) => {// 刷新查询方案列表this.refreshQuerPlanList()})})}

查询方案新增/修改

在查询方案下拉列表无选中项的情况下,通过筛选器配置查询条件组合后,点击保存按钮,弹出对话框,输入方案名称后,新增查询方案,如下:

在查询方案下拉列表有选中项的情况下,点击保存按钮,直接调用后端服务,保存数据,实际更新的是条件组合。

代码如下:

     // 保存查询方案save() {//获取查询方案内容,并做非空判断const content = JSON.stringify(this.$refs.everrightFilter.getData(), null, '\t')if (this.checkContentIsNull(content)) {return}if (this.currentQueryPlan) {// 如当前查询方案不会空,更新数据this.currentQueryPlan.content = contentthis.$api.system.queryPlan.modify(this.currentQueryPlan)} else {// 如当前查询方案为空,新增数据ElMessageBox.prompt('请输入方案名称', '新增查询方案', {confirmButtonText: '确定',cancelButtonText: '取消',inputPattern: /.+/,inputErrorMessage: '不能为空'}).then(({ value }) => {const data = {name: value,entityModelCode: this.entityModelCode,content: content}this.$api.system.queryPlan.add(data).then((res) => {//刷新查询方案列表this.refreshQuerPlanList()})})}}

查询方案另存为

用户往往需要基于某个现有的查询方案调整,另存为另一个查询方案,通过功能按钮实现。

这里没有根据当前是否有选中的查询方案来控制另存为按钮的可用,而是在逻辑上进行了处理,如当前查询方案为空,新增数据,否则参照当前数据新增(即另存),实现如下:

//另存为saveAs() {//获取查询方案内容,并做非空判断const content = JSON.stringify(this.$refs.everrightFilter.getData(), null, '\t')if (this.checkContentIsNull(content)) {return}if (this.currentQueryPlan == null) {// 如当前查询方案为空,新增数据ElMessageBox.prompt('请输入方案名称', '新增查询方案', {confirmButtonText: '确定',cancelButtonText: '取消',inputPattern: /.+/,inputErrorMessage: '不能为空'}).then(({ value }) => {const data = {name: value,entityModelCode: this.entityModelCode,content: content}this.$api.system.queryPlan.add(data).then((res) => {//刷新查询方案列表this.refreshQuerPlanList()})})} else {// 如当前查询方案不为空,参照当前数据新增ElMessageBox.prompt('请输入方案名称', '查询方案另存为', {confirmButtonText: '确定',cancelButtonText: '取消',inputPattern: /.+/,inputErrorMessage: '不能为空'}).then(({ value }) => {const data = {name: value,entityModelCode: this.entityModelCode,content: content}this.$api.system.queryPlan.add(data).then((res) => {//刷新查询方案列表this.refreshQuerPlanList()})})}}

辅助方法

有几个公共辅助方法,在这里也简单列一下:

保存数据前需要判断是否已添加了条件,即进行数据验证,如下:

     // 判断方案内容是否为空checkContentIsNull(content) {if (content == '{}') {this.$message.warning('请先添加至少一个查询条件')return true}return false}

在对方案新增、修改、删除时,需要刷新下拉列表,如下:

    // 刷新查询方案列表refreshQuerPlanList() {this.$refs.queryPlanSelect.loadData()}

后端处理

先前搭建框架的时候,仅实现了单组单条件,接下来,就来完善该部分逻辑以及其他细节。

单组多条件

配置查询方案条件如下:

后端逻辑完善如下:

        // 转换数据DataFilterRuleVO dataFilterRule = JSON.parseObject(customQueryString, DataFilterRuleVO.class);// 获取组集合List<DataFilterGroupVO> dataFilterGroupList = dataFilterRule.getFilters();// 遍历组集合for (DataFilterGroupVO dataFilterGroup : dataFilterGroupList) {// 获取条件集合List<DataFilterConditionVO> conditionList = dataFilterGroup.getConditions();// 组内条件逻辑关系String logicalOperator = dataFilterGroup.getLogicalOperator();if (CollectionUtils.isNotEmpty(conditionList)) {// 遍历条件集合for (DataFilterConditionVO condition : conditionList) {if (logicalOperator.equals(OR)) {queryWrapper = queryWrapper.or();}// 获取字段名,命名风格驼峰转换成下划线String fieldName = condition.getProperty();Object value = condition.getValue();// 获取操作String operator = condition.getOperator();QueryRuleEnum queryRule = EnumUtils.getEnum(QueryRuleEnum.class, operator, QueryRuleEnum.EQ);addEasyQuery(queryWrapper, fieldName, queryRule, value);}}}

运行,查看生成SQL,如下:

SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND (name = ? AND content LIKE ?)

将组内逻辑关系调整为或,如下:

运行,查看生成SQL,如下:

SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND (name = ? OR content LIKE ?)

多组多条件

配置查询方案条件如下:

后端逻辑增加组间逻辑关系处理,调整后如下:

           // 转换数据DataFilterRuleVO dataFilterRule = JSON.parseObject(customQueryString, DataFilterRuleVO.class);// 获取组集合List<DataFilterGroupVO> dataFilterGroupList = dataFilterRule.getFilters();// 组间条件逻辑关系String logicalOperatorGroup = dataFilterRule.getLogicalOperator();// 遍历组集合for (DataFilterGroupVO dataFilterGroup : dataFilterGroupList) {if (logicalOperatorGroup.equals(OR)) {queryWrapper = queryWrapper.or();}// 获取条件集合List<DataFilterConditionVO> conditionList = dataFilterGroup.getConditions();// 组内条件逻辑关系String logicalOperator = dataFilterGroup.getLogicalOperator();if (CollectionUtils.isNotEmpty(conditionList)) {// 遍历条件集合for (DataFilterConditionVO condition : conditionList) {if (logicalOperator.equals(OR)) {queryWrapper = queryWrapper.or();}// 获取字段名,命名风格驼峰转换成下划线String fieldName = condition.getProperty();Object value = condition.getValue();// 获取操作String operator = condition.getOperator();QueryRuleEnum queryRule = EnumUtils.getEnum(QueryRuleEnum.class, operator, QueryRuleEnum.EQ);addEasyQuery(queryWrapper, fieldName, queryRule, value);}}}

运行,查看生成SQL,如下:

==>  Preparing: SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND (name = ? AND content LIKE ? AND name LIKE ? AND name LIKE ?)
==> Parameters: 1(String), %2%(String), 3%(String), %4(String)

看上去,SQL从最终查询结果而言是正确的,但是没有分组,如果组内关系是or,推测应该会出问题,我们继续验证下。

将组间逻辑关系调整为或,如下:

运行,查看生成SQL,如下:

==>  Preparing: SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND (name = ? AND content LIKE ? OR name LIKE ? AND name LIKE ?)
==> Parameters: 1(String), %2%(String), 3%(String), %4(String)

可以看出来,果然出了问题,我们希望各条件组相对独立,用小括号包裹,然后再参与组间逻辑运算。

基于上述需求,对逻辑转换代码进行调整,如下:

private static <E, VO> void build(QueryWrapper<E> queryWrapper, Class<E> entityClass, String customQueryString, SortInfo sortInfo) {// 转换数据DataFilterRuleVO dataFilterRule = JSON.parseObject(customQueryString, DataFilterRuleVO.class);// 获取组集合List<DataFilterGroupVO> dataFilterGroupList = dataFilterRule.getFilters();// 组间条件逻辑关系String logicalOperatorGroup = dataFilterRule.getLogicalOperator();// 遍历组集合for (DataFilterGroupVO dataFilterGroup : dataFilterGroupList) {if (logicalOperatorGroup.equals(OR)) {queryWrapper.or(x ->generateQueryWrapper(x, dataFilterGroup));} else {queryWrapper.and(x ->generateQueryWrapper(x, dataFilterGroup));}}// 附加排序if (sortInfo != null && StringUtils.isNotBlank(sortInfo.getField())) {// 此处未使用注解,而是按照约定的规则,将驼峰命名转换为下划线,从而获取到数据库表字段名String orderField = CommonUtil.camelToUnderline(sortInfo.getField());if (sortInfo.getAscType()) {queryWrapper.orderByAsc(orderField);} else {queryWrapper.orderByDesc(orderField);}}}private static <E> QueryWrapper<E> generateQueryWrapper(QueryWrapper<E> queryWrapper, DataFilterGroupVO dataFilterGroup) {// 获取条件集合List<DataFilterConditionVO> conditionList = dataFilterGroup.getConditions();// 组内条件逻辑关系String logicalOperator = dataFilterGroup.getLogicalOperator();if (CollectionUtils.isNotEmpty(conditionList)) {// 遍历条件集合for (DataFilterConditionVO condition : conditionList) {if (logicalOperator.equals(OR)) {queryWrapper = queryWrapper.or();}// 获取字段名,命名风格驼峰转换成下划线String fieldName = condition.getProperty();Object value = condition.getValue();// 获取操作String operator = condition.getOperator();QueryRuleEnum queryRule = EnumUtils.getEnum(QueryRuleEnum.class, operator, QueryRuleEnum.EQ);addEasyQuery(queryWrapper, fieldName, queryRule, value);}}return queryWrapper;}

运行,查看生成SQL,如下:

==>  Preparing: SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND ((name = ? AND content LIKE ?) OR (name LIKE ? AND name LIKE ?))
==> Parameters: 1(String), %2%(String), 3%(String), %4(String)

可以看到,条件组外层使用了小括号包裹,组间的逻辑运算也是正确的。

日期类型的处理

前面提到过,在做筛选器组件前端功能验证时,发现日期类型的属性,生成查询规则与其他类型不同,如下:

value属性不是一个值,而是对应了一个对象,并且也不是日期字符串,而是时间戳,这种情况下,需要后端另行解析处理。

设置测试条件如下:

增加逻辑处理如下:

运行,查看生成SQL,如下:

==>  Preparing: SELECT COUNT(*) AS total FROM cfg_template WHERE delete_flag = 'NO' AND ((name = ? AND content LIKE ?) OR (name LIKE ? AND name LIKE ?))
==> Parameters: 1(String), %2%(String), 3%(String), %4(String)

开源平台资料

平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:[csdn专栏]
开源地址:[Gitee]
开源协议:MIT
如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~
请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!

相关文章:

一二三应用开发平台自定义查询设计与实现系列2——查询方案功能实现

查询方案功能实现 上面实现了自定义查询功能框架&#xff0c;从用户角度出发&#xff0c;有些条件组合可以形成特定的查询方案&#xff0c;对应着业务查询场景。诸多查询条件的组合&#xff0c;不能每次都让用户来设置&#xff0c;而是应该保存下来&#xff0c;下次可以直接使…...

Redis 集群 问题

前言 相关系列 《Redis & 目录》《Redis & 集群 & 源码》《Redis & 集群 & 总结》《Redis & 集群 & 问题》 什么是Redis集群&#xff1f;为什么要集群&#xff1f;Redis集群的优/缺点是什么&#xff1f; Redis集群是指将多台Redis实例进行协…...

PyQt入门指南二十九 QListView列表视图组件

在PyQt中&#xff0c;QListView 是一个用于显示项目列表的视图组件。它可以与 QStandardItemModel 或其他模型一起使用&#xff0c;以显示和编辑数据。以下是一个简单的入门指南&#xff0c;介绍如何使用 QListView 组件。 安装 PyQt 首先&#xff0c;确保你已经安装了 PyQt5…...

cisco网络安全技术第4章测试及考试

测试 以下 ACE 将放置在何处&#xff1f; permit icmp any any nd-na 试题 1选择一项&#xff1a; 在连接到另一个路由器并已启用 IPv6 的路由器接口上 使用下一代防火墙而不是状态防火墙的一个好处是什么&#xff1f; 试题 2选择一项&#xff1a; 主动而不是被动防护互…...

vue下载安装

目录 vue工具前置要求&#xff1a;安装node.js并配置好国内镜像源下载安装 vue 工具 系统&#xff1a;Windows 11 前置要求&#xff1a;安装node.js并配置好国内镜像源 参考&#xff1a;本人写的《node.js下载、安装、设置国内镜像源&#xff08;永久&#xff09;&#xff…...

C++ | Leetcode C++题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindromeSubseq(string s) {int n s.length();vector<vector<int>> dp(n, vector<int>(n));for (int i n - 1; i > 0; i--) {dp[i][i] 1;char c1 s[i];for (int j i 1; j…...

Python中的`update`方法详解及示例

Python中的update方法详解及示例 1. update方法简介2. update方法的应用场景3. 代码示例示例代码代码解释运行结果 4. 总结 在Python编程中&#xff0c;update方法是一个非常实用的工具&#xff0c;尤其是在处理集合&#xff08;Set&#xff09;数据类型时。本文将详细介绍upda…...

Docker本地安装Minio对象存储

Docker本地安装Minio对象存储 1. 什么是 MinIO&#xff1f; MinIO 是一个开源的对象存储服务器。这意味着它允许你在互联网上存储大量数据&#xff0c;比如文件、图片、视频等&#xff0c;而不需要依赖传统的文件系统。MinIO 的特点在于它非常灵活、易于使用&#xff0c;同时…...

vuex、vue-router实现原理

文章目录 Vuex 实现原理1. 状态管理2. 核心概念3. 数据流4. 实现细节 Vue Router 实现原理1. 路由管理2. 核心概念3. 数据流4. 实现细节 总结 Vuex 和 Vue Router 是 Vue.js 生态系统中非常重要的两个库&#xff0c;分别用于状态管理和路由管理。它们各自的实现原理如下&#x…...

我在命令行下剪辑视频

是的&#xff0c;你不需要格式工厂&#xff0c;你也不需要会声会影&#xff0c;更不需要爱剪辑这些莫名其妙的流氓软件&#xff0c;命令行下视频处理&#xff0c;包括剪辑&#xff0c;转码&#xff0c;提取&#xff0c;合成&#xff0c;缩放&#xff0c;字幕&#xff0c;特效等…...

Rust 力扣 - 643. 子数组最大平均数 I

文章目录 题目描述题解思路题解代码题解链接 题目描述 题解思路 我们遍历长度为k的窗口&#xff0c;我们只需要记录窗口内的最大和即可&#xff0c;遍历过程中刷新最大值 结果为窗口长度为k的最大和 除以 k 题解代码 impl Solution {pub fn find_max_average(nums: Vec<…...

流场主动流动控制

对于流场的主动控制而言&#xff0c;其难点主要集中在强化学习的环境搭建过程&#xff0c;如何建立数值仿真与强化学习的信息交互是研究过程中的拦路虎。经过几个星期的研究&#xff0c;已基本实现由pycharm程序数据端向star ccm端的数据传递。其主要过程包括如下过程&#xff…...

BOOST电感选型(参数详细计算)

上一篇文章我们介绍了BUCK电路中电感的计算与选型&#xff0c;与BUCK类似&#xff0c;这篇来介绍下BOOST BOOST电路原理简析 上图是一个异步BOOST电路拓扑图&#xff0c;我们先来简单回忆一下它是如何工作的&#xff1a; 1.Q闭合&#xff0c;Vin为Rload供电&#xff0c;Vin为L…...

EfficientNet-B6模型实现ISIC皮肤镜图像数据集分类

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于opencv答题卡识别判卷】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【G…...

Elasticsearch分词器基础安装

简介 Elasticsearch (ES) 是一个基于 Lucene 的搜索引擎&#xff0c;分词器是其核心组件之一&#xff0c;负责对文本数据进行分析和处理。 1. 文本分析 分词器将输入的文本拆分成一个个单独的词&#xff08;tokens&#xff09;&#xff0c;以便后续的索引和搜索。例如&#x…...

Django-邮件发送

邮件相关协议&#xff1a; SMTP&#xff08;负责发送&#xff09;&#xff1a; IMAP&#xff08;负责收邮件&#xff09;&#xff1a; POP3&#xff08;负责收邮件&#xff09;: 两者区别&#xff1a; Django发邮件&#xff1a; 邮箱相关配置&#xff1a; settings中&…...

SchooWeb2--基于课堂学习到的知识点2

SchoolWeb2 form表单input控件中各type中value值含义 默认值 text password hidden 提交给服务器的值 select option radio属性的name含义 name值相同表示是同一组单选框中的内容 script的位置 head标签 在head中使用script可以保证在页面加载时进行加载&#xff…...

Android.mk 写法

目录放在odm/bundled_uninstall_back-app/VantronMdm/VantronMdm.apk LOCAL_PATH : $(my-dir) include $(CLEAR_VARS) LOCAL_MODULE : VantronMdm LOCAL_MODULE_CLASS : APPS LOCAL_MODULE_PATH : $(TARGET_OUT_ODM)/bundled_uninstall_back-app LOCAL_SRC_FILES : $(LOCAL_M…...

精通Javascript 函数式array.forEach的8个案例

JavaScript是当今流行语言中对函数式编程支持最好的编程语言。我们继续构建函数式编程的基础&#xff0c;在前文中分解介绍了帮助我们组织思维的四种方法&#xff0c;分别为&#xff1a; array.reduce方法 帮你精通JS&#xff1a;神奇的array.reduce方法的10个案例 array.map方…...

忘记无线网络密码的几种解决办法

排名由简单到复杂 1网线直连&#xff1b; 2查看密码备份文件&#xff1b; 3问人要密码&#xff1b; 4已连接无线设备生成二维码扫描即可上网&#xff1b; 5路由器有wps功能&#xff0c;设备输入pin码可上网&#xff1b; 6已连接电脑右键wifi名&#xff0c;选择属性&#xff0c;…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...