js实现倒计时5秒提交及redis防止多人同时提交

该博客介绍了如何利用Redis缓存和Layui框架实现多人同时提交文档时的验证机制,确保文档提交的顺序和唯一性。当用户尝试提交时,后台进行Redis验证,如果键值不存在则添加并开始5秒倒计时,用户可以选择立即提交或等待自动提交。倒计时结束后,文档自动提交并删除Redis中的键值。整个过程中,利用JavaScript、Ajax和layui的弹出层展示倒计时和交互反馈。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

项目背景

 一、相关配置说明

二、使用步骤

1.开发思路

2.代码示例

效果展示


项目背景

        在多人同时提交文档时,js前往后台进行redis验证,验证通过前台显示一个倒计时5秒进行,点击确定立即提交,倒计时结束自动提交,避免用户中断了提交过程。

 相关技术:redis缓存,layui框架,javascript,ajax。


 一、相关配置说明

开发前配置: 

          前往官网下载Layui框架的配置文件,引入layui.css和layui.js两个文件。

          Layui官网自2021.10.13起迁移到GitHub,地址:https://github.com/sentsin/layui

<link rel="stylesheet" href="layui/css/layui.css">
<script src="layui/layui.js"></script>
  • js文件引入:
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>

 layui框架弹出层(公告层)示例和详细参数配置:

//示范一个公告层
layer.open({
	//0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
	type: 1,
	//不显示标题栏
	title: false,
	//title: ['是否确定提交','margin-left:10px'],
	closeBtn: false,
	//弹框[宽度,高度]
	area: ['300px', '150px'],
	//蒙版透明度
	shade: 0.8,
	id: 'LAY_layup', //设定一个id防止重复弹出,
	//btn: ['确认提交', '再想想'],
	btn: ['确认提交'],
	//弹框弹出动画
	anim: 1,
	//弹框关闭动画
	isOutAnim: 0,
	//btnAlign: 'l'	按钮左对齐
	//btnAlign: 'c'	按钮居中对齐;
	//btnAlign: 'r' 按钮右对齐。默认值,不用设置
	btnAlign: 'c',
	//是否允许最大化
	//maxmin:true,
	moveType: 1, //拖拽模式,0或者1
	content: "<div style='margin-top: 30px;line-height: 15px' id='test'></div>",
	//创建弹框完成时的回调:success:function(){}
	success: function () {
		//倒计时5秒
		layui.use('util', function () {
			const util = layui.util;
			//结束时间(当前时间戳+10秒)单位毫秒
			const endTime = (new Date().getTime()) + 5000,
			//当前时间,单位毫秒
			serverTime = new Date().getTime();
			//定义全局变量接收timer参数
			let timeouts;
			//每次调用倒计时时重置
			clearTimeout(timeouts);
			util.countdown(endTime, serverTime, function (date, serverTime, timer) {
				//在内部将timer参数动态赋给timeouts变量;
				timeouts = timer;
				//当倒计时结束时,提交文件
				if (date[3] === 0) {
					//关闭所有层
					layer.closeAll();
					clearInterval(timeouts);
					//提交
					submit_form(update_document_file_content);
				} else {
					const str = date[3] + '秒';
					layui.$('#test').html('<i class="layui-icon layui-icon-face-smile" style="font-size:20px;color: green"></i>&nbsp;已通过提交验证<br><br>距离自动提交还有:' + str);
				}
			});
		});
	},
	//点击确定按钮时的回调:yes:function(){}
	yes: function () {
		//关闭所有层
		layer.closeAll();
		//提交
		submit_form(update_document_file_content);
	},
});

 

二、使用步骤

1.开发思路

  • 用户点击提交时,前往后台进行redis验证,验证是否可以进行提交。查看redis指定键值是否存在,不存在加入键值,进行提交。存在时拒绝提交。(因为多人同时提交的需求不大,所以没有使用redis队列进行验证)
  1. 验证失败 :弹框显示“其他用户正在提交,请稍后”,阻止提交并防止页面刷新。   
  2. 验证成功 :弹框显示倒计时,点击确定立即提交,倒计时结束自动提交。
  • 验证成功后,调用Layui框架的弹出层,使用JS动态插入倒计时的秒数到弹出层。
  • 倒计时结束或点击提交,Ajax获取编辑器内容和用户数据提交到后台插入数据库以及生成本地文档。(编辑器内容过大需存入本地或服务器指定位置的文档中)
  • 提交完成后删除redis中指定键值并跳转回目录。

2.代码示例

<!--redis队列,防止多人同时提交-->
<script>
    //表单数据
	let folder_id="{$_GET['folder_id']}";
	let folder_name="{$_GET['folder_name']}";
	//编辑器内容
	let update_document_file_content = document.getElementById("update_document_file_content");
	function OnSave(){
        //因为编辑器自带"<p><br></p>"这段代码,所以判断语句如下
		if(editor.document.getBody().getHtml()==="<p><br></p>"){
			alert("内容不能为空!");
			return false;
		}else {
			//点击提交时,先使用ajax获取能否提交的返回值
			//注:$.get请求不带管理员id,在后台控制器中处理
			$.get("{url:/document_revision/handle_result}",function(status){
				if(status==='0'){
					alert("有人正在提交中,请稍后!");
					return false;
				}
				if(status==='2'){
					alert("系统检测到当前登录的管理员身份异常,请重新登录!");
					return false;
				}
				if(status==='1'){
					update_document_file_content=editor.document.getBody().getHtml();
					layer.open({
						//0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
						type: 1,
						//不显示标题栏
						title: false,
						//title: ['是否确定提交','margin-left:10px'],
						closeBtn: false,
						//弹框[宽度,高度]
						area: ['300px', '150px'],
						//蒙版透明度
						shade: 0.8,
						id: 'LAY_layup', //设定一个id防止重复弹出,
						//btn: ['确认提交', '再想想'],
						btn: ['确认提交'],
						//弹框弹出动画
						anim: 1,
						//弹框关闭动画
						isOutAnim: 0,
						//btnAlign: 'l'	按钮左对齐
						//btnAlign: 'c'	按钮居中对齐;
						//btnAlign: 'r' 按钮右对齐。默认值,不用设置
						btnAlign: 'c',
						//是否允许最大化
						//maxmin:true,
						moveType: 1, //拖拽模式,0或者1
						content: "<div style='margin-top: 30px;line-height: 15px' id='test'></div>",
						//创建弹框完成时的回调:success:function(){}
						success: function () {
							//倒计时5秒
							layui.use('util', function () {
								const util = layui.util;
								//结束时间(当前时间戳+10秒)单位毫秒
								const endTime = (new Date().getTime()) + 5000,
								//当前时间,单位毫秒
								serverTime = new Date().getTime();
								//定义全局变量接收timer参数
								let timeouts;
								//每次调用倒计时时重置
								clearTimeout(timeouts);
								util.countdown(endTime, serverTime, function (date, serverTime, timer) {
									//在内部将timer参数动态赋给timeouts变量;
									timeouts = timer;
									//当倒计时结束时,提交文件
									if (date[3] === 0) {
										//关闭所有层
										layer.closeAll();
										clearInterval(timeouts);
										//提交
										submit_form(update_document_file_content);
									} else {
										const str = date[3] + '秒';
										layui.$('#test').html('<i class="layui-icon layui-icon-face-smile" style="font-size:20px;color: green"></i>&nbsp;已通过提交验证<br><br>距离自动提交还有:' + str);
									}
								});
							});
						},
						//点击确定按钮时的回调:yes:function(){}
						yes: function () {
							//关闭所有层
							layer.closeAll();
							//提交
							submit_form(update_document_file_content);
						},
					});
				}
			})
		}
	}
	//ajax提交表单数据函数,因为有两处地方调同一个ajax方法所以拿出来单独写一个函数
	function submit_form(file_content){
		$.ajax({
			url:"{url:/document_revision/update_document_file_doing}",
			type:'post',
			data:{folder_id:folder_id,folder_name:folder_name,update_document_file_content:file_content},
			success:function(messages){
				console.log(messages);
				const link = "./index.php?controller=document_revision&action=update_document_file&folder_name=" + folder_name + "&folder_id=" + folder_id;
				if(messages==='0'){
					alert("文件提交成功,即将跳转回版本列表页面!");
					setInterval(function() {
						window.location.href=link;
					}, 1000);
				}
				if(messages==='1'){
					alert("文件修改失败,疑似有人插队,请稍后再试!")
					return false;
				}
			}
		});
	}
</script>


效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阑珊处的秋月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值