3.若依前后端分离版开发用户自定义配置表格功能
一、背景
在项目上线测试的时候,关于同一个界面的表格,不同的用户会出现不同的字段排列需求,有些用户希望把A字段排在最前面,有些用户则希望A字段不显示。针对这种情况,开发一个表格自定义配置的功能,每个用户根据自己的需求自己去设定表单字段的显示、隐藏、字段的宽度、左右固定等。
二、效果图
1.配置界面,可以拖动字段的顺序,是否显示、宽度、左右固定
三、实现方式
3.1 整体实现思路
将前端表格配置好的字段方式的Json存到数据库,用户打开界面的时候去数据库读取这个配置,前端用循环动态的渲染elemnet-table的表头即可。如果这个用户没有配置过,则读取默认的配置,默认配置写在前端一个JSON里面,每个vue界面的table设置一个table key用来标识table列表,数据库层面查找的时候根据用户code和tablekey来找到这个用户关于这个表格的配置。
最后’在前端进行动态渲染表头即可。整个功能的重点在于前端动态的拿到后端的json跟默认的存在前端的Json进行比较,然后生成最终的一个配置的json(注意:要以前端的默认Json为准,因为要考虑到字段的新增和删除的情况)
3.2 建立配置表 test_table_config
CREATE TABLE `test_table_config` (`Id` int NOT NULL AUTO_INCREMENT,`UserCode` varchar(100) COLLATE utf8mb4_bin NOT NULL COMMENT '用户编码',`TableKey` varchar(200) COLLATE utf8mb4_bin NOT NULL COMMENT '表名key',`TableConifgJsonStr` varchar(8000) COLLATE utf8mb4_bin NOT NULL COMMENT '配置的字段Json',`IsDelete` tinyint NOT NULL COMMENT '是否删除',`CreateTime` datetime DEFAULT NULL COMMENT '创建时间',`CreateUserId` int DEFAULT NULL COMMENT '创建人id',`UpdateTime` datetime DEFAULT NULL COMMENT '更新时间',`DeleteTime` datetime DEFAULT NULL COMMENT '删除时间',`UpdateUserId` int DEFAULT NULL COMMENT '更新用户',`DeleteUserId` int DEFAULT NULL COMMENT '删除人',PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='table配置表';
3.3 服务端test_table_config的crud
/*** 新增table配置*/// @PreAuthorize("@ss.hasPermi('system:tableconfig:add')")public AjaxResult add( TestTableAddInput testTableAddInput){TestTableConfig testTableConfig = new TestTableConfig();testTableConfig.setUserCode(this.getUsername());testTableConfig.setTableKey(testTableAddInput.getTableKey());testTableConfig.setTableConifgJsonStr(testTableAddInput.getTableConifgJsonStr());testTableConfig.setCreateUserId(this.getUserId());testTableConfig.setCreateBy(this.getUsername());testTableConfig.setCreateTime(new Date());testTableConfig.setIsDelete(0l);return toAjax(testTableConfigService.insertTestTableConfig(testTableConfig));}@Log(title = "编辑table配置", businessType = BusinessType.INSERT)@PostMapping@Anonymous@ApiOperation("编辑table配置")public AjaxResult addAndUpdate(@RequestBody TestTableAddInput testTableAddInput){TestTableConfig testTableConfig = new TestTableConfig();if(testTableAddInput.getTableConifgJsonStr() == null || testTableAddInput.getTableConifgJsonStr().length()==0){return error("没有传入配置Json");}// 先查询testTableConfig = testTableConfigService.selectTestTableConfigByUserAndTableKey(this.getUsername(),testTableAddInput.getTableKey());if(testTableConfig==null) // 更新{return add(testTableAddInput);}else{testTableConfig.setTableConifgJsonStr(testTableAddInput.getTableConifgJsonStr());// 修改return edit(testTableConfig);}}/*** 修改table配置*/// @PreAuthorize("@ss.hasPermi('system:tableconfig:edit')")public AjaxResult edit(TestTableConfig testTableConfig){testTableConfig.setUpdateUserId(this.getUserId());testTableConfig.setUserCode(this.getUsername());testTableConfig.setUpdateTime(new Date());testTableConfig.setIsDelete(0l);return toAjax(testTableConfigService.updateTestTableConfig(testTableConfig));}
3.4 前端配置组件界面
<template><div>
<div><vuedraggable v-model="paramClounm"><transition-group><div v-for="(item,index) in paramClounm" :key="item.key" style="margin:10px; text-align: left;"><el-row :gutter="24"><el-col :span="8"> <el-checkbox :label="item.label" v-model="item.visable"></el-checkbox></el-col><el-col :span="6"> <el-input-number v-model="item.width" placeholder="宽度"></el-input-number></el-col><el-col :span="4"> <el-checkbox v-model="item.isfix" label="固定"></el-checkbox></el-col><el-col :span="6"> <el-switch :span="8" v-model="item.fixlorr" active-text="固定右侧" inactive-text="固定左侧"></el-switch></el-col></el-row></div> </transition-group></vuedraggable></div><div><span slot="footer" class="dialog-footer"><el-button class="buttonLeft" type="primary" plain @click="recoverChecked">恢复默认</el-button><!-- <el-button @click="dialogVisible = false" class="buttonRight">取 消</el-button> --><el-button type="primary" @click="submit" class="buttonRight" >确 定</el-button></span></div></div></template>
<script>import vuedraggable from 'vuedraggable';import { getConfig, addAndUpdate } from "@/api/system/tableconfig";export default{name: 'configTest',components: {vuedraggable},data(){return{paramClounm:[], // 参数列dialogVisible:false,}},// 计算属性computed:{activeFields: function(){// alert(0);return this.fields.filter((item)=>{return item.visible;})}},// 加载完mounted(){// 加载列名 ; this.loadingTableClounm(Object.assign([],this.$parent.$parent.teacherTableClonms));},methods:{ getRowKey(v){return v.id},// 指令之前beforeHandleCommand(index,row,command) {//alert(0);return {'index':index,'row':row,'command':command}},// 移动操作handleCommand(command) {switch(command.command) {case "search":this.search(command.index);break;case "edit":this.edit(command.index);break;case "delete":this.rowOperation(command.row.indexLine,"delete",command.row);break;case "moveTop":this.rowOperation(command.row.indexLine,"moveTop",command.row);break;case "moveUp":this.rowOperation(command.row.indexLine,"moveUp",command.row);break;case "moveDown":this.rowOperation(command.row.indexLine,"moveDown",command.row);break;case "moveBottom":this.rowOperation(command.row.indexLine,"moveBottom",command.row);break;};},// 加载表格的列loadingTableClounm(teacherTableClonms){this.paramClounm= Object.assign([],teacherTableClonms) ;},// 保存配置submit(){// alert(JSON.stringify(this.paramClounm));var objList = this.paramClounm;// 移除不需要存入数据库的属性,然后将Json存到数据库for(var i=0;i<objList.length;i++){var obj=objList[i];obj.sortNum =i; // 排序编号delete obj.ifRender;delete obj.renderFun;}// alert(JSON.stringify(objList));var inputData={tableConifgJsonStr:JSON.stringify(objList),tableKey: this.$parent.$parent.tableKey};addAndUpdate(inputData).then(res=>{this.$modal.msgSuccess("操作成功");window.location.reload();});},// 恢复默认recoverChecked(){// this.checkedColumns=['编号','计划开始日期','计划完成日期','实际开始日期','实际完成日期'];// this.fieldList=columnOptions;this.paramClounm= [];// 为了解决子组件改变导致父组件也跟着改变的问题this.paramClounm = Object.assign([],this.$parent.$parent.teacherTableDefaultClonms) ; // alert(JSON.stringify(this.$parent.$parent.teacherTableDefaultClonms) );//window.location.reload();},edit(index,row){},},}</script>
3.5 前端Table界面对应table表头的配置Json
/********************************************** 功 能:teacher表列名* 创建人:cola* 创建时间:2023-08-11******************************************/
import Vue from 'vue'
const vm = new Vue()
export const
columnOptions=
[{key:"id",label:"Id",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"name",label:"姓名",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"teachercode",label:"教师工号",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"fex",label:"性别",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"age",label:"年龄",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"createtime",label:"创建时间",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''
},{key:"isdelete",label:"删除",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''},{key:"deletetime",label:"删除时间",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''
},
{key:"updatetime",label:"更新时间",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:true,renderFun:(scope)=>{let html="";html+="<span>";html+= vm.parseTime(scope.row.updatetime,'{y}-{m}-{d}');html+= "</span>"return html;}
},
{key:"updateuserid",label:"更新人",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''
},
{key:"deleteuserid",label:"删除人",visable : true,width: 200,isfix : false,fixlorr: 0,ifRender:false,renderFun:''
},];
3.6 前端Table界面读取配置进行动态展示
<template><div class="app-container"><el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"><el-form-item label="姓名" prop="name"><el-inputv-model="queryParams.name"placeholder="请输入姓名"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="教师工号" prop="teachercode"><el-inputv-model="queryParams.teachercode"placeholder="请输入教师工号"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="性别 0 女 1男" prop="fex"><el-inputv-model="queryParams.fex"placeholder="请输入性别 0 女 1男"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="年龄" prop="age"><el-inputv-model="queryParams.age"placeholder="请输入年龄"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="是否删除" prop="isdelete"><el-inputv-model="queryParams.isdelete"placeholder="请输入是否删除"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="创建时间" prop="createtime"><el-date-picker clearablev-model="queryParams.createtime"type="date"value-format="yyyy-MM-dd"placeholder="请选择创建时间"></el-date-picker></el-form-item><el-form-item label="更新时间" prop="updatetime"><el-inputv-model="queryParams.updatetime"placeholder="请输入更新时间"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="删除时间" prop="deletetime"><el-date-picker clearablev-model="queryParams.deletetime"type="date"value-format="yyyy-MM-dd"placeholder="请选择删除时间"></el-date-picker></el-form-item><el-form-item label="创建人id" prop="createuserid"><el-inputv-model="queryParams.createuserid"placeholder="请输入创建人id"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="修改人id" prop="updateuserid"><el-inputv-model="queryParams.updateuserid"placeholder="请输入修改人id"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="删除人id" prop="deleteuserid"><el-inputv-model="queryParams.deleteuserid"placeholder="请输入删除人id"clearable@keyup.enter.native="handleQuery"/></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button><el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button></el-form-item></el-form><el-row :gutter="10" class="mb8"><el-col :span="1.5"><el-buttontype="primary"plainicon="el-icon-plus"size="mini"@click="handleAdd">新增</el-button></el-col><el-col :span="1.5"><el-buttontype="success"plainicon="el-icon-edit"size="mini":disabled="single"@click="handleUpdate">修改</el-button></el-col><el-col :span="1.5"><el-buttontype="danger"plainicon="el-icon-delete"size="mini":disabled="multiple"@click="handleDelete">删除</el-button></el-col><el-col :span="1.5"><el-buttontype="warning"plainicon="el-icon-download"size="mini"@click="handleExport">导出</el-button></el-col><el-col :span="1.5"><el-buttontype="warning"plainicon="el-icon-download"size="mini"@click="openconifg">配置</el-button></el-col><right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar></el-row><!-- :data="teacherList" v-loading="loading" :fixed="item.fixlorr==0? 'left':'right'"--><el-table :data="teacherList" v-loading="loading" @selection-change="handleSelectionChange" style="width: 400"><!-- <el-table-column type="selection" width="55" align="center" :fixed="true" /> <template slot-name=''></template></el-table-column> --><el-table-column v-for="item in this.teacherTableClonms " :key="item.key" :label="item.label" :prop="item.key" :width="item.width" v-if="item.ifRender && item.visable" :fixed="item.isfix?item.fixlorr==0?left:right :false"><template slot-scope="scope" ><div v-html="item.renderFun? item.renderFun(scope) : ''"></div></template></el-table-column><el-table-column :label="item.label" align="center" :prop="item.key" :width="item.width" v-else-if="item.ifRender==false && item.visable" :fixed="item.isfix?item.fixlorr==0?'left':'right' :false" /><el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" ><template slot-scope="scope"><el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handleUpdate(scope.row)">修改</el-button><el-buttonsize="mini"type="text"icon="el-icon-delete"@click="handleDelete(scope.row)">删除</el-button></template></el-table-column><!-- <el-table-column label="id" align="center" prop="id" /><el-table-column label="姓名" align="center" prop="name" /><el-table-column label="教师工号" align="center" prop="teachercode" /><el-table-column label="性别 0 女 1男" align="center" prop="fex" /><el-table-column label="年龄" align="center" prop="age" /><el-table-column label="是否删除" align="center" prop="isdelete" /><el-table-column label="创建时间" align="center" prop="createtime" width="180"><template slot-scope="scope"><span>{{ parseTime(scope.row.createtime, '{y}-{m}-{d}') }}</span></template></el-table-column><el-table-column label="更新时间" align="center" prop="updatetime" /><el-table-column label="删除时间" align="center" prop="deletetime" width="180"><template slot-scope="scope"><span>{{ parseTime(scope.row.deletetime, '{y}-{m}-{d}') }}</span></template></el-table-column><el-table-column label="创建人id" align="center" prop="createuserid" /><el-table-column label="修改人id" align="center" prop="updateuserid" /><el-table-column label="删除人id" align="center" prop="deleteuserid" />--></el-table><paginationv-show="total>0":total="total":page.sync="queryParams.pageNum":limit.sync="queryParams.pageSize"@pagination="getList"/><!-- 添加或修改测试_教师对话框 --><el-dialog :title="title" :visible.sync="open" width="500px" append-to-body><el-form ref="form" :model="form" :rules="rules" label-width="80px"><el-form-item label="姓名" prop="name"><el-input v-model="form.name" placeholder="请输入姓名" /></el-form-item><el-form-item label="教师工号" prop="teachercode"><el-input v-model="form.teachercode" placeholder="请输入教师工号" /></el-form-item><el-form-item label="性别 0 女 1男" prop="fex"><el-input v-model="form.fex" placeholder="请输入性别 0 女 1男" /></el-form-item><el-form-item label="年龄" prop="age"><el-input v-model="form.age" placeholder="请输入年龄" /></el-form-item><el-form-item label="是否删除" prop="isdelete"><el-input v-model="form.isdelete" placeholder="请输入是否删除" /></el-form-item><el-form-item label="删除时间" prop="deletetime"><el-date-picker clearablev-model="form.deletetime"type="date"value-format="yyyy-MM-dd"placeholder="请选择删除时间"></el-date-picker></el-form-item><el-form-item label="创建人id" prop="createuserid"><el-input v-model="form.createuserid" placeholder="请输入创建人id" /></el-form-item><el-form-item label="修改人id" prop="updateuserid"><el-input v-model="form.updateuserid" placeholder="请输入修改人id" /></el-form-item><el-form-item label="删除人id" prop="deleteuserid"><el-input v-model="form.deleteuserid" placeholder="请输入删除人id" /></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</el-button></div></el-dialog><!-- 传入 参数--><el-dialog title="配置表格列" :visible.sync="cofigshow" width="900px" append-to-body><ConfigTableTest :tableclounms="this.teacherTableClonms"></ConfigTableTest></el-dialog> </div>
</template><script>
import { listTeacher, getTeacher, delTeacher, addTeacher, updateTeacher } from "@/api/system/teacher";
import { getTableConfigByUserCodeAndTabelKey } from "@/api/system/tableconfig";
import { columnOptions } from "../../../tableclounm/teacherclounm";import ConfigTableTest from "../tableconfig/configtabletest.vue";import TableCloumRender from "../tableconfig/tableclounmrender.vue";
export default {name: "Teacher",components: {ConfigTableTest,TableCloumRender
},data() {return {// 遮罩层loading: true,// 选中数组ids: [],// 非单个禁用single: true,// 非多个禁用multiple: true,// 显示搜索条件showSearch: true,// 总条数total: 0,// 测试_教师表格数据teacherList: [],// 弹出层标题title: "",// 是否显示弹出层open: false,// 配置显示层cofigshow: false,// 表格的Key,用来自定义配置的标识 to do 命名规范定义 功能模_块功能界面_Table ?tableKey:'TeacherIndexTable',// 查询参数queryParams: {pageNum: 1,pageSize: 10,name: null,teachercode: null,fex: null,age: null,isdelete: null,createtime: null,updatetime: null,deletetime: null,createuserid: null,updateuserid: null,deleteuserid: null},// 表单参数form: {},// 表单校验rules: {},teacherTableClonms : [], // 获取后端返回的当前用户个性化配置的列名teacherTableDefaultClonms:[] // 获取js里面配置的列名};},created() {this.getTableConfig(); // 获取用户列表配置// alert(JSON.stringify(this.teacherTableClonms) );this.getList();},methods: {/** 查询测试_教师列表 */getList() {this.loading = true;listTeacher(this.queryParams).then(response => {this.teacherList = response.rows;this.total = response.total;this.loading = false;});},// 获取当前用户这个列表对应的配置:// 逻辑:// 1.先查询配置。// 2.如果这个用户还没配置 则取JS里面的默认配置。// 3.如果这个用户已经配置了,则取数据库里面保存的配置,然后循环比对存在js里面的字段,// 生成最后对应的配置(因为数据库里面没有存渲染的代码,考虑到字段的长度限制 8000 风险点 1 如果大宽表,需要修改数据库字段类型)。getTableConfig(){// 默认的配置 Object.assign防止 this.teacherTableDefaultClonms的变动影响columnOptionsthis.teacherTableDefaultClonms = JSON.parse(JSON.stringify(columnOptions)) ; // alert(JSON.stringify(this.teacherTableDefaultClonms ));var param={tableKey:this.tableKey // 表格的key 每个表格唯一};// 默认的配置 Object.assign防止 jsConfigClounms的变动影响columnOptionslet jsConfigClounms = Object.assign([],columnOptions); let newClounms =[]; // 拼接成新的一个配置数组getTableConfigByUserCodeAndTabelKey(param).then(res=>{if(!!res){var data =JSON.parse(res.tableConifgJsonStr) ;// 以配置在JS里面的配置为循环的基础(需要考虑到增减字段)for(var i=0;i<jsConfigClounms.length;i++){var jsClounmItem = jsConfigClounms[i];var newItem = jsClounmItem; // 新的项以JS的配置为基础,能设置的配置项取数据库里面的// 查询对应的配置// rfor(var j=0;j<data.length;j++){var dataItem = data[j];if(newItem.key == dataItem.key){// 说明匹配上了if(dataItem.visable!=null){newItem.visable = dataItem.visable; // 是否显示}if(dataItem.width!=null){newItem.width = dataItem.width; // 宽度}if(dataItem.isfix!=null){newItem.isfix = dataItem.isfix; // 是否固定}if(dataItem.fixlorr!=null){newItem.fixlorr = dataItem.fixlorr; // 固定左边or右边}if(dataItem.sortNum!=null){newItem.sortNum = dataItem.sortNum ; //排序编号}break; // 匹配上了,跳出一层循环} else{// 没有匹配上,则说明是新加的字段,把这些新加的字段放在最后newItem.sortNum = 10000-i; // 把排序号增加到最大} } // for 1 endnewClounms.push(newItem);}// for2 end// 这个时候需要排序一下,恢复顺序newClounms = newClounms.sort(this.sortByNum);}else{// 说明数据库里面没有配置,则直接取JS里面的配置newClounms = jsConfigClounms;}this.teacherTableClonms = newClounms;// alert(JSON.stringify(this.teacherTableDefaultClonms ));});},// 根据排序编码号进行排序
sortByNum(a, b) {return a.sortNum - b.sortNum;
},// 取消按钮cancel() {this.open = false;this.reset();},// 表单重置reset() {this.form = {id: null,name: null,teachercode: null,fex: null,age: null,isdelete: null,createtime: null,updatetime: null,deletetime: null,createuserid: null,updateuserid: null,deleteuserid: null};this.resetForm("form");},/** 搜索按钮操作 */handleQuery() {this.queryParams.pageNum = 1;this.getList();},/** 重置按钮操作 */resetQuery() {this.resetForm("queryForm");this.handleQuery();},// 多选框选中数据handleSelectionChange(selection) {this.ids = selection.map(item => item.id)this.single = selection.length!==1this.multiple = !selection.length},/** 新增按钮操作 */handleAdd() {this.reset();this.open = true;this.title = "添加测试_教师";},/** 修改按钮操作 */handleUpdate(row) {this.reset();const id = row.id || this.idsgetTeacher(id).then(response => {this.form = response.data;this.open = true;this.title = "修改测试_教师";});},/** 提交按钮 */submitForm() {this.$refs["form"].validate(valid => {if (valid) {if (this.form.id != null) {updateTeacher(this.form).then(response => {this.$modal.msgSuccess("修改成功");this.open = false;this.getList();//});} else {addTeacher(this.form).then(response => {this.$modal.msgSuccess("新增成功");this.open = false;this.getList();});}}});},/** 删除按钮操作 */handleDelete(row) {const ids = row.id || this.ids;this.$modal.confirm('是否确认删除测试_教师编号为"' + ids + '"的数据项?').then(function() {return delTeacher(ids);}).then(() => {this.getList();this.$modal.msgSuccess("删除成功");}).catch(() => {});},/** 导出按钮操作 */handleExport() {this.download('system/teacher/export', {...this.queryParams}, `teacher_${new Date().getTime()}.xlsx`)},/**打开配置 */openconifg(){this.cofigshow = true;}}
};
</script>
3.7 功能完成
相关文章:

3.若依前后端分离版开发用户自定义配置表格功能
一、背景 在项目上线测试的时候,关于同一个界面的表格,不同的用户会出现不同的字段排列需求,有些用户希望把A字段排在最前面,有些用户则希望A字段不显示。针对这种情况,开发一个表格自定义配置的功能,每个…...

【操作系统】24王道考研笔记——第三章 内存管理
第三章 内存管理 一、内存管理概念 1.基本概念 2.覆盖与交换 覆盖技术: 交换技术: 总结: 3.连续分配管理方式 单一连续分配 固定分区分配 动态分区分配 动态分区分配算法: 总结: 4.基本分页存储管理 定义…...

Spring缓存深入解析:@Cacheable的使用详解
摘要:在本文中,我们将深入研究Spring框架中的Cacheable注解。我们会通过详细的Java示例,探讨如何使用这个功能强大的注解来提升应用程序性能。 一、什么是缓存? 在计算机科学中,缓存是一种存储技术,用于保…...

软件配置安装(破解)--- jdk下载配置
下载jdk 如果有oracle账号的话直接登录下载你想要的版本 不然可以尝试镜像站 HUAWEI镜像:https://repo.huaweicloud.com/java/jdk/ 安装 配置(细节) 这里的JAVA_HOME就是java的家,也就是解压(或安装)之后的java的目录ÿ…...

idea使用docker生成镜像(打包镜像,导入镜像,导出镜像)
1:先下载安装dockerdesktop,安装成功后 2: 在cmd执行docker -v,查看安装的docker版本 C:\Users\dell>docker -v Docker version 24.0.5, build ced09963:需要启动 dockerdesktop应用,才算启动docker&a…...

wazuh环境配置
目录 一、wazuh的安装 1.1官方仓库安装 1.2虚拟机OVA安装 1.2.1 然后执行下面命令 1.2.2 这里还要下载脚本和config.yml配置文件,用来生成证书编辑 1.2.3然后编辑config.yml文件,将下面的三个IP地址改为一样的 1.2.4运行./wazuh-certs-tool.sh以…...
【Linux】Linux下常用压缩解压缩指令及选项小结
0x00 前言 版本信息:Ubuntu 18.04.6 LTS 最后更新日期:2023.8.22 0x01 Linux下常用压缩解压缩指令小结 1.gzip指令 gzip file:压缩file文件为file.gz ,但是只能压缩文件不能压缩目录,且不保留源文件。若想打包目录…...

香蕉派社区推出带10G SFP+ 端口的Banana Pi BPI-R4 Wifi7开源路由器
香蕉派BPI-R4 根据著名Banana Pi品牌背后的公司Sinovoip提供的初步信息,他们即将推出的Banana Pi BPI-R4路由器板目前正在开发中。与之前的 Banana Pi R3 板相比,这在规格上将有显着提升。这就是我们目前所知道的。 您可以选择 R4 板的两种不同配置。具…...
A 题:震源属性识别模型构建与震级预测 :代码分析:
问题 1: 针对附件 1~8 中的地震波数据,找出一系列合适的指 标与判据,构建震源属性识别模型,进行天然地震事件(附件 1~7) 与非天然地震事件(附件 8)的准确区…...

源码分析CompletableFuture使用默认线程池ForkJoinPool的弊端
先说结论: 假如有20CompletableFuture任务并发执行时,都使用默认线程池ForkJoinPool,但cpu的核心数又小于3,那么就会新建20个线程(不使用默认线程池了),这20个线程相互竞争cpu资源和内存&#x…...

连接pgsql数据库 sslmode sslrootcert sslkey sslcert 参数的作用
sslmode 参数的作用 sslmode 参数用于指定数据库连接时使用的 SSL 加密模式。SSL(Secure Sockets Layer)是一种加密协议,用于保护数据在客户端和服务器之间的传输过程,以增加数据传输的安全性。sslmode 参数可以设置不同的值&…...
从零学算法3
3.给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”&…...

宠物小程序开发
在当今社会,宠物已成为许多人生活中不可或缺的一部分。宠物市场的持续增长为创业者提供了巨大的商机。然而,作为一个创业者,要在竞争激烈的宠物市场中脱颖而出并不容易。因此,开发一个专属于自己的宠物小程序成为了解决这一难题的…...

07-Vue基础之综合案例——小黑记事本
个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习目标: 坚持每一次的学习打卡 文章…...

vite4+vue3+electron23.3+ts桌面应用bs端开发 打包windows、linux、max三个系统的安装包
vite4vue3electron23.3ts桌面应用bs端开发 打包windows、linux、max三个系统的安装包 主要包依赖 "electron-store": "^8.1.0", //全局数据状态管理,可选择性安装"electron": "23.3.8","electron-builder": &q…...

限制 el-input 输入 emoji
1. 电脑如何输入 emoji 表情 ? 快捷键 win; 或 win. 2. 代码实现 <template><el-input v-model"input" placeholder"请输入内容" input"inputChange"></el-input> </template><script> export default {name: D…...
【AI】解决Number_Words的安装和使用
It appears that you encountered an error while trying to install the “Numbers_Words” package using the specific version 0.18.2 of the PEAR channel. The error message indicates that there was a problem unpacking the “Math_BigInteger-1.0.3” package, whi…...
开启MySQL的binlog日志
在/etc/my.cnf增加如下配置 #binlog相关 log-bin /testdata/mysql/log/bin/mysql-bin expire_logs_days 7 binlog-format ROW binlog_cache_size 4M max_binlog_cache_size 20G binlog_rows_query_log_events 1 binlog_row_image FULL sync_binlog 1 log_bin_trust_fun…...
【支付宝小程序】支付宝小程序自定义组件技术教程
🦖我是Sam9029,一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **🐱🐉🐱🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,…...
CSDN编程题-每日一练(2023-08-23)
CSDN编程题-每日一练(2023-08-23) 一、题目名称:圆小艺二、题目名称:连续子数组的最大和三、题目名称:投篮一、题目名称:圆小艺 时间限制:1000ms内存限制:256M 题目描述: 最近小艺酱渐渐变成了一个圆滑的形状-球!! 小艺酱开始变得喜欢上球! 小艺酱得到n个同心圆。 …...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...