【微信小程序】数字化会议OA系统之投票模块(附源码)

🎉🎉欢迎来到我的CSDN主页!🎉🎉

🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚

🌟推荐给大家我的专栏《微信小程序开发实战》。🎯🎯

👉点击这里,就可以查看我的主页啦!👇👇

Java方文山的个人主页

🎁如果感觉还不错的话请给我点赞吧!🎁🎁

💖期待你的加入,一起学习,一起进步!💖💖

请添加图片描述

前言

开会是企业中必不可少的一种沟通方式,可以让团队成员之间交流思想,协调工作进度,解决问题等。但是,过于频繁和冗长的会议可能会浪费时间和资源,影响工作效率。

在公司中,如果每个小事情都要开会,那么很容易造成员工的厌烦和不满。这样的会议可能会让人感到无聊、浪费时间,甚至失去动力。因此,企业应该合理安排会议,选择适当的时间和场合,避免不必要的会议,并确保会议的目的明确、内容简洁、效率高效,因此鄙人开发了一个数字化会议OA系统。

这篇文章主讲投票模块的实现,其中包括发布投票信息,用户选择所属会议的投票标题内容进行投票、投票的数据报表等实现。

一、投票模块页面搭建

【微信小程序】自定义组件布局会议OA其他页面(附源码)icon-default.png?t=N7T8http://t.csdnimg.cn/lLeMU页面搭建与自定义组件的编写在这篇文章中提过,这里只做粗略的讲述。

1.顶部导航栏

我们可以根据自定义组件完成,首先在相应的json文件中引用自定义组件。

  "usingComponents": {"tabs": "/components/tabs/tabs"}

 随后在js文件中定义我们所需要展示的内容。

  tabs: ['发起投票', '投票进行中', '已结束投票', '全部投票']

 最后直接在wxml中应用即可。

<tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange"></tabs>

 效果展示:

 2.定义内容切换事件

我们这里与会议管理有些不同,我们会议管理是点击不同的菜单显示不同的数据,但是这个的内容可就不是数据了,而是各不相同的组件,所以针对这个事情我们要做一个内容切换事件。

首先在我们的wxml中定义好每个菜单需要展示的内容并写好hidden样式

  <view class="{{componentStatus[0] ? '' : 'hidden'}}">发起投票</view><view class="{{componentStatus[1] ? '' : 'hidden'}}">投票进行中</view><view class="{{componentStatus[2] ? '' : 'hidden'}}">已结束投票</view><view class="{{componentStatus[3] ? '' : 'hidden'}}">全部投票</view>
.hidden {display: none;
}

在js中定义好属性与事件

 componentStatus: [true,false, false, false]
  tabsItemChange(e) {let index = e.detail.index;//全部的组件赋值为falseconst lists = [false, false, false, false];//将所点击的组件赋值为truelists[index] = true;this.setData({componentStatus: lists // 更新 data 中的 componentStatus 属性值});}

 效果展示:

 温馨提示:

因为在写这篇博客之前,我就已经完成了功能,并且模块中的样式没有进行相应的标记,所以这里就放上我投票模块的所有样式,避免大家在进行编写的时候因为样式问题而导致效果出不来的情况。

wxss

/* pages/vote/list/list.wxss */
.hidden {display: none;
}.title-view {background-color: beige;font-weight: 700;padding-left: 7px;
}.info-title {padding: 5px 5px 10px 5px;border-top: 1px solid rgb(129, 129, 127);
}.info-text {height: 100px;padding: 5px 5px 10px 5px;border-top: 1px solid rgb(129, 129, 127);
}.image {padding-left: 55px;display: flex;align-items: center;
}.time {border-top: 1px solid rgb(129, 129, 127);padding: 5px 0px 5px 0px;display: flex;align-items: center;
}.image-container {padding-left: 60px;
}.info-sousuo {margin-left: 85px;padding-left: 20px;border-radius: 25px;border: 4px solid rgb(214, 214, 98);width: 250px;
}/* pages/meeting/list/list.wxss */
.section{color: #aaa;display: flex;justify-content: center;
}.list-info {margin-top: 10px;color: #aaa;
}.list-num {color: #e40909;font-weight: 700;
}.join {padding: 0px 0px 0px 10px;color: #aaa;
}.state {margin: 0px 6px 0px 6px;border: 1px solid #93b9ff;color: #93b9ff;
}.list-tag {padding: 3px 0px 10px 0px;display: flex;align-items: center;
}.list-title {display: flex;justify-content: space-between;color: #333;font-weight: 900;}
.yyy{display: flex;align-items: center;
}
.list-img{height: 300rpx;width: 90%;border-radius: 50rpx;margin: 5px 5px 5px 20px;
}
.centered {display: flex;  /* 设置为弹性容器 */justify-content: center;  /* 子元素水平方向居中对齐 */
}.video-img {width: 100px;height: 100px;
}.list {border-bottom: 1px solid #6b6e74;padding: 10px;
}.mobi-text {font-weight: 700;padding: 15px;
}.mobi-icon {border-left: 5px solid #e40909;
}.mobi-title {background-color: rgba(158, 158, 142, 0.678);margin: 10px 0px 10px 0px;
}.swiper-item {height: 300rpx;width: 100%;border-radius: 10rpx;
}.userinfo {display: flex;flex-direction: column;align-items: center;color: #aaa;
}.userinfo-avatar {overflow: hidden;width: 128rpx;height: 128rpx;margin: 20rpx;border-radius: 50%;
}.usermotto {margin-top: 200px;
}.filx{display: flex;align-items: center;
}
.container {padding: 20px;
}.modal-container {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background-color: #fff;width: 80%;max-height: 80%;overflow-y: auto;padding: 20px;
}.mask {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.5);
}button {display: block;margin-top: 10px;
}.content {margin-top: 10px;border: 1px solid #ccc;padding: 10px;
}
.right{display: flex;align-items: center;
}

二、发起投票

1.初始数据

首先最基本的就是要拿到数据,但是这个数据可不是乱拿的,我们先来看一下表数据。

我们要拿到state值为5的数据,只有该数据才是通过了审核并且还未结束的会议,所以能进行投票,明确了目标现在开始敲代码吧。

InfoMapper.xml

  <select id="votelist" resultMap="BaseResultMap"  >select<include refid="Base_Column_List" />from t_oa_meeting_infowhere state=5</select>

Controller代码

//创建投票的会议信息@RequestMapping("/vote")public Object votelist(Info info) {List<Info> infoList = infoMapper.votelist(info);Map<Object, Object> data = new HashMap<Object, Object>();data.put("infoList",infoList);return ResponseUtil.ok(data);}

 在config/api.js配置后端接口

// 以下是业务服务器API地址// 本机开发API地址var WxApiRoot = 'http://localhost:8080/wx/';// 测试环境部署api地址// var WxApiRoot = 'http://192.168.0.101:8070/demo/wx/';// 线上平台api地址//var WxApiRoot = 'https://www.oa-mini.com/demo/wx/';module.exports = {IndexUrl: WxApiRoot + 'home/index', //首页数据接口SwiperImgs: WxApiRoot+'swiperImgs', //轮播图MettingInfos: WxApiRoot+'meeting/list', //会议信息VoteInfos:WxApiRoot+'home/vote',//可发起投票会议信息OptionInfos:WxApiRoot+'home/add',//发布投票信息SelectOption:WxApiRoot+'home/selectOptions'//查看可进行投票信息};

 JS代码

引入后端接口配置文件 

const api = require("../../config/api.js")

 可发起投票会议信息的ajax

  loadvoteInfos() {util.request(api.VoteInfos).then(res => {// console.log(res.data.infoList)this.setData({lists: res.data.infoList})})}

 在onLoad函数中调用该方法

WXML代码

<!-- 我创建的投票 -->
<view class="{{componentStatus[0] ? '' : 'hidden'}}"><block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id"><view><image bindtap="showModal" data-id="{{item}}" class="list-img" mode="scaleToFill" src="{{item.seatpic !=null? item.seatpic : '/static/persons/6.png'}}"></image></view><view class="centered"><view class="list" data-id="{{item.id}}"><view class="yyy"><view class="list-title"><text>{{item.title}}</text></view><view class="join"><text class="list-num">{{tools.getNumber(item.canyuze,item.liexize,item.item.zhuchiren)}}</text>人报名</view></view><view class="list-info"><text>{{item.location}}</text>|<text>{{tools.formatDate(item.starttime)}}</text></view></view></view></block></view>

 注意:将代码放入所需要展示内容的view中。

效果展示

2.模态框实现发布 

这里我给大家捋一下我的思路,当我点击会议信息的时候就会弹出一个模态框,模态框的内容有显示该会议的标题、输入投票的标题、新增选项、删除选项、发布投票、取消发布等。我需要将我所点击的会议信息的标题传入模态框中,并且可以获取投票标题和选项内容的文本内容并进行保存,等我点击发布投票的时候就会将保存的内容传值给后端。

数据库展示

OptionMapper.xml

  <insert id="insertSelective" parameterType="com.zking.minoa.model.Option">INSERT INTO t_oa_meeting_option<trim prefix="(" suffix=")" suffixOverrides=","><if test="id != null">id,</if><if test="meetingId != null">meetingId,</if><if test="optionValue != null">optionValue,</if><if test="optionText != null">optionText,</if></trim><trim prefix="VALUES (" suffix=")" suffixOverrides=","><if test="id != null">#{id, jdbcType=INTEGER},</if><if test="meetingId != null">#{meetingId, jdbcType=INTEGER},</if><if test="optionValue != null">#{optionValue, jdbcType=VARCHAR},</if><if test="optionText != null">#{optionText, jdbcType=VARCHAR},</if></trim></insert>

Controller代码

//发布投票@RequestMapping("/add")public Object add(@RequestBody Map<String, Object> obj) {System.out.println(obj);//获取选项数组的长度来控制新增的次数int optionsLength = ((List)obj.get("options")).size();//循环添加投票数据for (int i = 0; i < optionsLength; i++) {//初始化optionOption option = new Option();List<String> options = (List<String>) obj.get("options");option.setmeetingId((Integer) obj.get("modalConId"));//会议idString firstOption = options.get(i);option.setoptionValue((String)obj.get("title"));//投票标题option.setoptionText(firstOption);//选项内容//调取添加的方法int insert = optionMapper.insertSelective(option);}return ResponseUtil.ok();}

这里需要注意是一个投票选项就是一条数据,所以我们要先拿到前端的选择数组的长度,从而进行遍历添加数据,同一批请求的投票标题与会议id肯定是一致的所以不用变动。

 在config/api.js配置后端接口

 OptionInfos:WxApiRoot+'home/add',//发布投票信息

JS代码

//投票标题的监听事件bindTitle: function (e) {this.setData({title: e.detail.value})},// 输入框输入事件,保存输入的内容到相应的选项bindInput(e) {console.log(e)const { index } = e.currentTarget.dataset; // 获取当前选项的索引const { value } = e.detail;const { options } = this.data;options[index] = value;this.setData({options: options});},// 添加选项addOption() {const { options, optionCount } = this.data;options.push('');this.setData({options: options,optionCount: optionCount + 1});},// 删除选项deleteOption() {const { options, optionCount } = this.data;options.pop();this.setData({options: options,optionCount: optionCount - 1});}, // 确认按钮点击事件confirm() {let modalConId = this.data.modalConId;//会议idlet title = this.data.title;//投票标题let options = this.data.options;//选项内容let data = {modalConId: modalConId,options: options,title: title};// console.log(data)util.request(api.OptionInfos, data, 'POST').then(res => {// console.log(res)this.setData({modalVisible: false,optionCount: 1});})},// 取消按钮点击事件cancel() {this.setData({modalVisible: false,optionCount: 1});}

 事件中提到的变量在data中定义即可,这里就不做展示了

WXML代码

  <!-- 模态框 --><view wx:if="{{modalVisible}}"><view class="mask"></view><view class="modal-container"><h1>{{modalContent}}</h1><view style="margin-top: 20px;" class="filx"><l-button type="default" bindtap="addOption" style="padding: 0px 10px 0px 0px;">添加选项</l-button><l-button type="warning" bindtap="deleteOption" wx:if="{{optionCount > 1}}">删除选项</l-button></view><span style="margin-right: 30px;">投票标题:</span><input type="text" placeholder="请输入投票标题" bindinput="bindTitle" style="width: 300px;border: 3px solid rgb(7, 7, 7);" /><view wx:for="{{options}}" wx:key="{{index}}"><span style="margin-right: 30px;">选项{{index+1}}:</span><input type="text" value="{{item}}" bindinput="bindInput" data-index="{{index}}" style="width: 300px;border: 3px solid rgb(7, 7, 7);" /></view><view class="filx" style="margin-top: 20px;"><l-button bindtap="confirm" type="success" style="padding: 0px 10px 0px 0px;">发布投票</l-button><l-button bindtap="cancel" type="error">取消</l-button></view></view></view>

 我这里还引用了小程序框架LinUI可以丰富我的页面,不懂的可以看官网哦!!

结合我们刚刚的页面数据再看看效果

三、用户投票

1.初始数据

OptionMapper.xml

 <select id="selecttoupiao" resultType="java.util.Map" parameterType="java.lang.String">SELECTid,optionValue,optionText,title,seatPicFROM (SELECTt_oa_meeting_option.id,t_oa_meeting_option.optionValue,t_oa_meeting_option.optionText,t_oa_meeting_info.title,t_oa_meeting_info.seatPic,ROW_NUMBER() OVER (PARTITION BY t_oa_meeting_option.optionValue ORDER BY t_oa_meeting_option.id) AS row_numFROMt_oa_meeting_optionJOIN t_oa_meeting_info ON t_oa_meeting_option.meetingId = t_oa_meeting_info.idWHEREt_oa_meeting_info.state = 5) subqueryWHERE row_num = 1<if test="title != null and title != ''">AND title LIKE CONCAT('%', #{title}, '%')</if></select>

Controller代码

  //带模糊查询的会议信息@RequestMapping("/selectOptions")public Object selectOptions(String title) {System.out.println(title);List<Map> selecttoupiao = optionMapper.selecttoupiao(title);Map<Object, Object> data = new HashMap<Object, Object>();data.put("selecttoupiao", selecttoupiao);return ResponseUtil.ok(data);}

 在config/api.js配置后端接口

   SelectOption:WxApiRoot+'home/selectOptions'//查看可进行投票信息

在投票页面我使用了LinUI的滑动菜单和卡片布局。

 利用好框架我们写起来就会简单许多只需要将数据进行绑定即可,但为了让用户有更好的体验,所以我加了一个搜索框,用户可进行模糊查询自己所需要投票的会议。

JS代码

   //加载投票会议信息的ajaxloadoptinos() {util.request(api.SelectOption).then(res => {// console.log(res.data.selecttoupiao)this.setData({Options: res.data.selecttoupiao})})},// 监听搜索事件onSearch: function(event) {var title = event.detail.value;let data = {title: title};util.request(api.SelectOption,data).then(res => {this.setData({Options: res.data.selecttoupiao})})}

 WXML代码

<view style="height: 20px;"></view><view class="view-suo"> <input class="info-sousuo" type="text" placeholder="请输入会议标题进行搜索" bindconfirm="onSearch"/></view><block wx:for-items="{{Options}}" wx:for-item="item" wx:key="item.id"><l-card type="cover" image="{{item.seatPic !=null? item.seatPic : '/static/persons/6.png'}}" title="{{item.title}}" style="margin-top: 10px;"><l-slide-view height="120" width="650" slide-width="340"><view slot="left" class="left"><view class='left-con' style="margin-top: 30px;"><text class='left-title'>投票标题:《{{item.optionValue}}》</text></view></view><view slot="right" class="right"><view style="background-color:#9eb0fb;width: 100px;height: 100px;color: white;" ><view style="margin: 20px 5px 5px 14px;">投票</view></view><view style="background-color: #728cf8;width: 100px;height: 100px;color: white;"><view style="margin: 20px 5px 5px 14px;">报表</view></view><view style="background-color: #e45c6c;width: 100px;height: 100px;color: white;"><view style="margin: 10px 5px 5px 14px;">结束会议</view></view></view></l-slide-view></l-card>
</block>

 效果展示

2.模态框显示选项

投票数据表的字段非常简单,只需要拿到所选投票的id与投票人员的id即可

首先我们需要一个模态框作为载体来加载投票标题的投票选项

OptionMapper.xml

  <!--根据投票标题查询选项  --><select id="voting" resultType="java.util.Map" parameterType="java.lang.String" >select *from t_oa_meeting_option where 1=1<if test="optionValue != null and optionValue != '' ">AND optionValue LIKE CONCAT('%', #{optionValue}, '%')</if></select>

 Controller代码

   //根据投票标题查询选项@RequestMapping("/voting")public Object voting(String optionValue) {List<Map> voting = optionMapper.voting(optionValue);Map<Object, Object> data = new HashMap<Object, Object>();data.put("voting", voting);return ResponseUtil.ok(data);}

 在config/api.js配置后端接口

  voting:WxApiRoot+'home/voting',//根据投票标题查询选项

JS代码

 //打开投票模态框并向后端拿值openModal: function (e) {let optionValue = e.currentTarget.dataset.value;// console.log('传递的值:', optionValue);let data = {optionValue: optionValue};util.request(api.voting, data).then(res => {this.setData({votes: res.data.voting,showModal: true})})},//关闭投票模态框closeModel(){this.setData({selectedOption:'',showModal: false})},
//保存用户所选择的选项radioChange: function (e) {const value = e.detail.value;this.setData({selectedOption: value});}

WXML代码

<!-- 模态框 -->
<view wx:if="{{showModal}}" class="modal"><view class="modal-content"><!-- 单选框 --><radio-group bindchange="radioChange"><label wx:for="{{votes}}" wx:key="{{index}}" class="radio-label"><radio value="{{item.id}}" checked>{{item.optionText}}</radio></label></radio-group><!-- 按钮 --><view><button bindtap="confirmVote">确定</button><button bindtap="closeModel">取消</button></view></view>
</view>

这里有个小地方需要注意我在投票的view上绑定了data-value="{{item.optionValue}}也就是投票标题,当打开模态框的时候,就会带着这个投票标题找到相应的选项出来。

效果演示

3.确认投票

 到这一步就可以说是非常简单了,我们只需要保存用户所选的是什么选项,并将值传到后端进行保存即可。

VoteMapper.xml

<insert id="insertSelective" parameterType="com.zking.minoa.model.Vote" >insert into t_oa_meeting_vote<trim prefix="(" suffix=")" suffixOverrides="," ><if test="id != null" >id,</if><if test="optionid != null" >optionId,</if><if test="personid != null" >personId,</if></trim><trim prefix="values (" suffix=")" suffixOverrides="," ><if test="id != null" >#{id,jdbcType=VARCHAR},</if><if test="optionid != null" >#{optionid,jdbcType=VARCHAR},</if><if test="personid != null" >#{personid,jdbcType=BIGINT},</if></trim></insert>

 Controller代码

   //投票@RequestMapping("/option")public Object add(int optionId) {System.out.println(optionId);Vote vote=new Vote();vote.setOptionid(optionId);vote.setPersonid(7);int i = voteMapper.insertSelective(vote);return ResponseUtil.ok();}

这里没有进行用户登录的操作所以人的id就先定死 。

 在config/api.js配置后端接口

   option:WxApiRoot+'home/option',//用户投票

JS代码

//用户投票confirmVote: function () {const optionId = this.data.selectedOption;let data = {optionId: optionId};util.request(api.option, data).then(res => {console.log(res)this.setData({showModal: false})})}

效果展示

四、整体效果演示

 请添加图片描述

到这里我的分享就结束了,欢迎到评论区探讨交流!!

💖如果觉得有用的话还请点个赞吧 💖

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

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

相关文章

FoneDog iOS Unlocker(ios解锁工具) 适用macos电脑

FoneDog iOS Unlocker是一款专业的iOS设备解锁工具&#xff0c;旨在帮助用户解决iOS设备上的解锁问题。该软件支持解锁各种锁定类型&#xff0c;如数字密码锁、手势密码锁、Touch ID和Face ID等&#xff0c;可以解除iPhone、iPad和iPod Touch等设备的锁定状态。FoneDog iOS Unl…

react-组件间的通讯

一、父传子 父组件在使用子组件时&#xff0c;提供要传递的数据子组件通过props接收数据 class Parent extends React.Component {render() {return (<div><div>我是父组件</div><Child name"张" age{16} /></div>)} }const Child …

NEWCC:新时代的区块链生态新币私募造势平台

在当今区块链领域&#xff0c;这项技术已经为金融资产注入了全新的生机&#xff0c;同时也为初创企业提供了新的商业模式和融资机会。通过代币的金融属性&#xff0c;企业和项目方得以实现资本的初期积累&#xff0c;同时在区块链空间以更低成本和更高效率进行交易和服务创新。…

【广州华锐互动】VR公司工厂消防逃生演练带来沉浸式的互动体验

在工业生产过程中&#xff0c;安全问题始终是我们不能忽视的重要环节。特别是火灾事故&#xff0c;不仅会造成重大的经济损失&#xff0c;更会威胁到员工的生命安全。传统的消防安全训练方法&#xff0c;如讲座、实地演练等&#xff0c;虽然具有一定的效果&#xff0c;但是无法…

ZooKeeper中节点的操作命令(查看、创建、删除节点)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

docker部署prometheus+grafana服务器监控(二) - 安装数据收集器 node-exporter

在目标服务器安装数据收集器 node-exporter 1. 安装数据收集器 node-exporter wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gztar xvf node_exporter-1.6.1.linux-amd64.tar.gzmv node_exporter-1.6.1…

短视频矩阵系统搭建/源头----源码

一、智能剪辑、矩阵分发、无人直播、爆款文案于一体独立应用开发 抖去推----主要针对本地生活的----移动端(小程序软件系统&#xff0c;目前是全国源头独立开发)&#xff0c;开发功能大拆解分享&#xff0c;功能大拆解&#xff1a; 7大模型剪辑法&#xff08;数学阶乘&#xff…

SQL Server Management Studio (SSMS)的安装教程

文章目录 SQL Server Management Studio (SSMS)的安装教程从Microsoft官网下载SQL Server Management Studio安装程序。选中安装程序右键并选择“以管理员的身份运行”选项选择安装目录&#xff0c;单击“安装”按钮开始安装过程安装成功界面安装完成后&#xff0c;您可以启动S…

银河麒麟v10x86或者arm离线安装服务

银河麒麟v10x86或者arm离线安装服务 最近有个项目&#xff0c;甲方的服务器用的全是国产化服务器银河麒麟&#xff0c;架构是x86的然后也无法连接外网&#xff0c;需要离线安装服务正常思路就是找到离线安装的包&#xff0c;然后拷贝到现场的服务器中进行安装所以问题就在于如…

机器学习——正则化

正则化 在机器学习学习中往往不知道需要不知道选取的特征个数&#xff0c;假如特征个数选取过少&#xff0c;容易造成欠拟合&#xff0c;特征个数选取过多&#xff0c;则容易造成过拟合。由此为了保证模型能够很好的拟合样本&#xff0c;同时为了不要出现过拟合现象&#xff0…

Macos视频增强修复工具:Topaz Video AI for mac

Topaz Video AI是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单&#xff0c;…

基于SSM的二手车交易系统

基于SSM的二手车交易系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 登录界面 管理员界面 摘要 基于SSM&#xff08;Spring、SpringMVC、MyBatis&a…

如何进行微服务测试?一文4个知识点带入门微服务测试!

关注留言点赞&#xff0c;带你了解最流行的软件开发知识与最新科技行业趋势。 本文将讨论微服务测试的重要性、挑战和最佳实践。 微服务架构是一种越来越流行的构建复杂分布式系统的方法。在此体系结构中&#xff0c;大型应用程序被分成较小的、独立的服务&#xff0c;这些服务…

大数据平台架构及规划

梳理了数据平台及未来规划&#xff0c;具体如下&#xff1a; 整体架构&#xff1a; 当前建设进展&#xff1a; 部署架构 部署架构2&#xff1a; Flink 实时计算平台架构 版本1&#xff1a; 版本2&#xff1a; 离线平台架构&#xff1a; 未来规划&#xff1a;

公有云容灾,中小企业最具性价比的选择

备份容灾的成本门槛 业务数据是企业的核心&#xff0c;为了防止意外灾难引发的数据损失、业务系统宕机等情况&#xff0c;企业可以选择部署备份容灾&#xff0c;以此保证系统和服务不会在意外发生时断线&#xff0c;以及数据的完整性。 在过去&#xff0c;只有大型企业会部署…

SourceTree 使用

如何拉取远程仓库&#xff1f;如何拉去远程分支&#xff1f;如何创建本地分支&#xff1f;如何删除本地分支&#xff1f;如何删除远端分支&#xff1f; 删除了远程分支&#xff0c;如果本地还有此分支&#xff0c;那么是可以通过推送本地分支来还原远端分支。如何合并本地分支&…

一个Entity Framework Core的性能优化案例

概要 本文提供一个EF Core的优化案例&#xff0c;主要介绍一些EF Core常用的优化方法&#xff0c;以及在优化过程中&#xff0c;出现性能反复的时候的解决方法&#xff0c;并澄清一些对优化概念的误解&#xff0c;例如AsNoTracking并不包治百病。 本文使用的是Dotnet 6.0和EF…

【网络协议】聊聊网络路由相关算法

如何配置路由 路由器是一台网络设备&#xff0c;多张网卡&#xff0c;当一个入口的网络包到达路由器时&#xff0c;会根据本地的信息库决定如何正确的转发流量&#xff0c;通常称为路由表 路由表主要包含如下 核心思想是根据目的 IP 地址来配置路由 目的网络&#xff1a;要去…

Babylonjs学习笔记(五)——创建PBR材质

书接上回&#xff0c;这里讨论PBR材质&#xff01;&#xff01;&#xff01; // 创建天空盒/* */const createSkyBox (scene:Scene):void>{const envTex CubeTexture.CreateFromPrefilteredData(./env/environment.env,scene)scene.environmentTexture envTex;scene.cre…

Games104现代游戏引擎笔记 网络游戏架构基础

挑战1:网络同步 挑战2:是网络的可靠性&#xff0c;包括应对网络的延迟&#xff0c;丢包和掉线 挑战3: 反作弊和安全系统&#xff0c;因为网络游戏的本质是经济系统 挑战4:多样性(不同设备&#xff0c;不同服务器)&#xff0c;在不停服的情况下热更新 挑战5:大量人数时对高并发…