耀极客论坛

 找回密码
 立即注册
查看: 540|回复: 0

JavaScript实现语音排队叫号系统

[复制链接]

336

主题

318

帖子

22万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
220555
发表于 2022-5-8 01:51:24 | 显示全部楼层 |阅读模式
  语音排队叫号系统广泛用于银行,餐饮,医院等场景。本文主要介绍了通过JavaScript实现的语音排队叫号系统,有扫码排队,语音叫号等功能。需要的可以参考一下

介绍
  语音排队叫号系统广泛用于银行,餐饮,医院等场景。本系统采用Layui框架完成,前端体验不错,基于角色实现了权限管理,实现了数据库菜单无限级扩展和菜单链接动态控制,系统实现扫码排队,语音叫号等功能。
  开发语言:C# 
  数据库:sql server2017
  开发工具:vs2019
  技术:asp.net+layui

主要功能
  带验证码的登录界面,背景可替换。
  基于角色的权限管理。
  系统具有打印和导出数据表格的功能。
  支持筛选列和组合查询。
  系统实现换肤功能。 

效果展示












关键代码
  1. ‹%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TbLineUpList.aspx.cs" Inherits="PaiDuiSys.page.TbLineUpList" %>
  2. ‹!DOCTYPE html>
  3. ‹html xmlns="http://www.w3.org/1999/xhtml">
  4. ‹head runat="server">
  5. ‹meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  6.     ‹title>夜鹰排队叫号系统v1.0‹/title>
  7.     ‹meta charset="utf-8"/>
  8.     ‹meta name="renderer" content="webkit"/>
  9.     ‹meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  10.     ‹meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
  11.     ‹link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" rel="external nofollow"  media="all"/>
  12.     ‹link rel="stylesheet" href="../css/public.css" rel="external nofollow"  media="all"/>
  13. ‹/head>
  14. ‹body>
  15.     ‹div class="layuimini-container">
  16.     ‹div class="layuimini-main">
  17.         ‹fieldset class="table-search-fieldset">
  18.             ‹legend>搜索信息‹/legend>
  19.             ‹div>
  20.                 ‹form id="form1"  class="layui-form layui-form-pane" action="">
  21.                     ‹div class="layui-form-item">
  22.                         ‹div class="layui-inline">
  23.                             ‹label class="layui-form-label">业务类型:‹/label>
  24.                             ‹div class="layui-input-inline">
  25.                                 ‹select name="BuType" lay-verify="required">
  26.                                                 ‹option value="0" selected="selected">全部‹/option>
  27.                                                 ‹option value="1">个人业务‹/option>
  28.                                                 ‹option value="2">对公业务‹/option>                                               
  29.                                 ‹/select>               
  30.                             ‹/div>
  31.                         ‹/div>
  32.                         ‹div class="layui-inline">
  33.                             ‹label class="layui-form-label">关键字‹/label>
  34.                             ‹div class="layui-input-inline">
  35.                                 ‹input type="text" name="SearchKey" autocomplete="off" class="layui-input"/>
  36.                             ‹/div>
  37.                         ‹/div>
  38.                        
  39.                         
  40.                         ‹div class="layui-inline">
  41.                             ‹button type="submit" class="layui-btn layui-btn-primary"  lay-submit lay-filter="data-search-btn">‹i class="layui-icon">‹/i> 搜 索‹/button>
  42.                         ‹/div>
  43.                     ‹/div>
  44.                 ‹/form>
  45.             ‹/div>
  46.         ‹/fieldset>
  47.         ‹script type="text/html" id="toolbarDemo">
  48.             ‹div class="layui-btn-container">
  49.                 ‹button class="layui-btn layui-btn-sm layui-btn-normal data-add-btn" lay-event="add"> 添加 ‹/button>
  50.                 ‹button class="layui-btn layui-btn-sm layui-btn-normal data-add-btn" lay-event="edit"> 编辑 ‹/button>
  51.                 ‹button class="layui-btn layui-btn-sm layui-btn-normal data-add-btn" lay-event="delete"> 删除 ‹/button>
  52.                 ‹button class="layui-btn layui-btn-sm layui-btn-normal data-add-btn" lay-event="showdetail"> 查看 ‹/button>
  53.             ‹/div>
  54.         ‹/script>
  55.       
  56.         ‹table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter">‹/table>
  57.         
  58.   
  59.         ‹/div>
  60.         ‹script type="text/html" id="currentTableBar">
  61.             ‹a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="classnum">叫号‹/a>
  62.             ‹a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="classfinish">完成‹/a>
  63.             ‹a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="classovertime">过期‹/a>
  64.             ‹a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="showview">查看‹/a>
  65.             
  66.         ‹/script>
  67. ‹/div>
  68. ‹script src="../lib/layui-v2.6.3/layui.js" charset="utf-8">‹/script>
  69. ‹script>
  70.    
  71.     layui.use(['form', 'table'], function () {
  72.         var $ = layui.jquery;
  73.             form = layui.form;
  74.             table = layui.table;
  75.             layer = layui.layer;
  76.         table.render({
  77.             elem: '#currentTableId',
  78.             url: '../Ajax.ashx?rnum=2',
  79.             toolbar: '#toolbarDemo',
  80.             defaultToolbar: ['filter', 'exports', 'print', {
  81.                 title: '提示',
  82.                 layEvent: 'LAYTABLE_TIPS',
  83.                 icon: 'layui-icon-tips'
  84.             }],
  85.             cellMinWidth: 80,
  86.             cols: [[
  87.                 { type: "checkbox", width: 50 },
  88.                 { field: 'ID', width: 80, title: 'ID' },
  89.                 { field: 'CreateTime', width: 200, title: '创建时间' },
  90.                 { field: 'CustName', width: 100, title: '客户姓名'},
  91.                 { field: 'CustIDCard', width:200, title: '身份证' },
  92.                 { field: 'CustTel', width: 120, title: '客户电话' ,edit: 'text'},
  93.                 { field: 'LineNum', width: 60, title: '排号' },
  94.                 { field: 'WindowNumStr', width: 120, title: '当前窗口' },
  95.                 { field: 'BuType', title: '类型', width: 120,hide: true },
  96.                 { field: 'BuTypeStr', title: '类型', width: 120},               
  97.                 { field: 'BuStatusStr', width: 80, title: '状态'},               
  98.                 { field: 'Memo', title: '备注(点击单元格改备注)', event: 'setMemo' },
  99.                 { field: 'CallTime', title: '最后一次叫号时间',  hide: true },
  100.                 { field: 'FinishTime', title: '业务完成时间',  hide: true },
  101.                 { field: 'OptName', title: '业务办理人员',hide: true },
  102.                 { field: 'OptUserId', title: '业务办理人员ID', hide: true },
  103.                 { field: 'WindowNum', title: '窗口号', hide: true },
  104.                 { field: 'LineNum', title: '排队号', hide: true },
  105.                 {title: '操作', width:300, toolbar: '#currentTableBar', align: "center"}
  106.             ]],
  107.             limits: [10, 15, 20, 25, 50, 100],
  108.             limit: 10,
  109.             page: true,
  110.             skin: 'line',
  111.             done(res, curr, count) {
  112.                 let data = res.data;
  113.                 data.forEach((value, i) => {
  114.                   
  115.                     //console.log(value.BuStatus);
  116.                     //根据每一行的status字段,设置当前行的背景颜色
  117.                     if (value.BuStatus =="1") {
  118.                         $('.layui-table tr[data-index="' + i + '"]').css({ 'background-color': 'red','color':'#fff'});
  119.                     } else if (value.BuStatus =="2") {
  120.                         $('.layui-table tr[data-index="' + i + '"]').css({ 'background-color': '#3cb371', 'color': '#fff'});
  121.                     } else if (value.BuStatus == "3"){
  122.                         $('.layui-table tr[data-index="' + i + '"]').css({ 'background-color': '#ccc', 'color': '#fff'});
  123.                     }
  124.                 });
  125.             }        
  126.         });
  127.       
  128.         // 监听搜索操作
  129.         form.on('submit(data-search-btn)', function (data) {
  130.            
  131.             //执行搜索重载
  132.             table.reload('currentTableId', {
  133.                 page: {
  134.                     curr: 1
  135.                 }
  136.                 , where: {
  137.                     BuType: data.field.BuType,
  138.                     SearchKey: data.field.SearchKey
  139.                 }
  140.             }, 'data');
  141.             return false;
  142.         });
  143.         /**
  144.          * toolbar监听事件
  145.          */
  146.         table.on('toolbar(currentTableFilter)', function (obj) {
  147.             if (obj.event === 'add') {  // 监听添加操作
  148.                 var index = layer.open({
  149.                     title: '新增用户',
  150.                     type: 2,
  151.                     zIndex: layer.zIndex,
  152.                     id: 'LAY_layuiproadd',  //设定一个id,防止重复弹出
  153.                     shade: 0.1,
  154.                     maxmin: true,
  155.                     // shadeClose: true,
  156.                     area: ['60%', '520px'],
  157.                     content: '../page/table/TbLineUpAdd.aspx',
  158.                     success: function (layero, index) {
  159.                         layer.setTop(layero);
  160.                     }
  161.                 });
  162.                 $(window).on("resize", function () {
  163.                     layer.full(index);
  164.                 });
  165.             } else if (obj.event === 'delete') {  // 监听删除操作
  166.                 var checkStatus = table.checkStatus('currentTableId');
  167.                 var dataarray = checkStatus.data;
  168.                 var ids = "0";
  169.                 for (var i = 0; i ‹ dataarray.length; i++) {
  170.                     ids += "," + dataarray[i].ID;
  171.                 }
  172.                 ids += ",0";
  173.                 layer.confirm('确定删除该记录吗?一旦删除不能恢复!', { icon: 3, title: '提示' }, function (index) {
  174.                     $.ajax({
  175.                         url: '../Ajax.ashx', //要请求的url地址
  176.                         type: 'POST', //请求方法 GET or POST
  177.                         async: true, //是否使用异步请求的方式
  178.                         timeout: 5000, //请求超时的时间,以毫秒计
  179.                         data: {
  180.                             rnum: 10,
  181.                             ids: ids
  182.                         },
  183.                         dataType: 'json',
  184.                         success: function (data) {
  185.                             console.log(obj);
  186.                             layer.alert("删除成功");
  187.                             table.reload('currentTableId', {})
  188.                         }
  189.                     });
  190.                 });
  191.             } else if (obj.event === 'edit') {
  192.                 var checkStatus = table.checkStatus('currentTableId');
  193.                 var dataarray = checkStatus.data;
  194.                 console.log(dataarray);
  195.                 if (dataarray.length > 0) {
  196.                     layer.open({
  197.                         type: 2 //此处以iframe举例
  198.                         , title: '编辑用户'
  199.                         , area: ['60%', '520px']
  200.                         , shade: 0.1
  201.                         , maxmin: true
  202.                         , id: 'LAY_layuipro' //设定一个id,防止重复弹出
  203.                         , content: '../page/table/TbLineUpEdit.aspx'
  204.                         , zIndex: layer.zIndex
  205.                         , success: function (layero, index) {
  206.                             var item = dataarray[0];
  207.                             var body = layer.getChildFrame('body', index);
  208.                             console.log(o);
  209.                             body.find("[name='rid']").val(item.ID);
  210.                             body.find("[name='CustName']").val(item.CustName);
  211.                             body.find("input[name='CustIDCard']").val(item.CustIDCard);
  212.                             console.log(item.BuType);
  213.                             console.log(body.find("input[name='BuType'][value='2']"));
  214.                             if (item.BuType == "1") {
  215.                                 body.find("input[name='BuType'][value='1']").prop("checked", true);
  216.                             }
  217.                             else {
  218.                                 $(body).find("input[name='BuType'][value='2']").prop("checked", true);
  219.                             }
  220.                             body.find("[name='CustTel']").val(item.CustTel);
  221.                             body.find("[name='Memo']").val(item.Memo);
  222.                             layer.setTop(layero);
  223.                             //关键点:父窗口调用子页面的getformobj函数,返回子页面的form对象,然后重绘子页面的数据。
  224.                             var iframeWin = window[layero.find('iframe')[0]['name']];
  225.                             var o = iframeWin.getformobj();
  226.                             o.render();
  227.                         }
  228.                     });
  229.                 }
  230.                 else {
  231.                     layer.msg('请先勾选一条要编辑的数据');
  232.                 }
  233.             } else if (obj.event === 'showdetail') {
  234.                 var checkStatus = table.checkStatus('currentTableId');
  235.                 var dataarray = checkStatus.data;
  236.                 if (dataarray.length > 0) {
  237.                     layer.open({
  238.                         type: 2
  239.                         , title: '查看用户'
  240.                         , area: ['50%', '520px']
  241.                         , shade: 0.1
  242.                         , maxmin: true
  243.                         , id: 'layuiproview' //设定一个id,防止重复弹出
  244.                         , content: '../page/table/TbLineUpView.aspx'
  245.                         , zIndex: layer.zIndex
  246.                         , success: function (layero, index) {
  247.                             var item = dataarray[0];
  248.                             var body = layer.getChildFrame('body', index);
  249.                             console.log(item);
  250.                             body.find("[name='rid']").val(item.ID);
  251.                             body.find("[name='CustName']").val(item.CustName);
  252.                             body.find("input[name='CustIDCard']").val(item.CustIDCard);
  253.                             body.find("input[name='CreateTime']").val(item.CreateTime);
  254.                             body.find("input[name='CallTime']").val(item.CallTime);
  255.                             body.find("input[name='FinishTime']").val(item.FinishTime);
  256.                             body.find("input[name='OptName']").val(item.OptName);
  257.                             body.find("input[name='LineNum']").val(item.LineNum);
  258.                             body.find("input[name='WindowNum']").val(item.WindowNum);
  259.                            
  260.                             if (item.BuType == "1") {
  261.                                 body.find("input[name='BuType'][value='1']").prop("checked", true);
  262.                             }
  263.                             else {
  264.                                 $(body).find("input[name='BuType'][value='2']").prop("checked", true);
  265.                             }
  266.                             body.find("[name='CustTel']").val(item.CustTel);
  267.                             body.find("[name='Memo']").val(item.Memo);
  268.                             layer.setTop(layero);
  269.                             //关键点:父窗口调用子页面的getformobj函数,返回子页面的form对象,然后重绘子页面的数据。
  270.                             var iframeWin = window[layero.find('iframe')[0]['name']];
  271.                             var o = iframeWin.getformobj();
  272.                             o.render();
  273.                         }
  274.                     });
  275.                 }
  276.                 else {
  277.                     layer.msg('请先勾选一条要编辑的数据');
  278.                 }
  279.             }
  280.         });
  281.         //监听单元格编辑
  282.         table.on('edit(currentTableFilter)', function (obj) {
  283.             var v = obj.value; //得到修改后的值
  284.             var data = obj.data;//得到所在行所有键值
  285.             var CurrentField = obj.field; //修改的字段
  286.             $.ajax({
  287.                 url: '../Ajax.ashx', //要请求的url地址
  288.                 type: 'POST', //请求方法 GET or POST
  289.                 async: true, //是否使用异步请求的方式
  290.                 timeout: 5000, //请求超时的时间,以毫秒计
  291.                 data: {
  292.                     rnum: "11",
  293.                     id:data.ID,
  294.                     value:v,
  295.                     Field:CurrentField
  296.                 },
  297.                 dataType: 'json', //预期的服务器返回参数类型
  298.                 beforeSend: function () {
  299.                 },
  300.                 success: function (data) {
  301.                     layer.msg("修改成功");
  302.                 },
  303.                 error: function () {
  304.                 },
  305.                 complete: function () {
  306.                 }
  307.             });
  308.            
  309.         });
  310.         //监听表格复选框选择
  311.         table.on('checkbox(currentTableFilter)', function (obj) {
  312.             //console.log(obj)
  313.         });
  314.         function getWindowVoice()
  315.         {  // 获取浏览器中语音 (中文 + 本地服务)
  316.             return window.speechSynthesis.getVoices().find(item => item.localService && item.lang === 'zh-CN');
  317.         }
  318.         table.on('tool(currentTableFilter)', function (obj) {
  319.             var data = obj.data;
  320.             if (obj.event === 'classnum') {
  321.                 const synth = window.speechSynthesis
  322.                 const message = new SpeechSynthesisUtterance();
  323.                 function voice_playback(text) {
  324.                     message.text = text;
  325.                     message.lang = 'zh';
  326.                     message.volume = 1;     // 声音音量:1
  327.                     message.rate = 1;       // 语速:1
  328.                     message.pitch = 1;       // 音高:1
  329.                     message.voice = getWindowVoice();  // 使用本地服务合成语音(若是获取不到 请异步获取, 加一个setTimeout)
  330.                     //synth.cancel(message);
  331.                     window.speechSynthesis.cancel();
  332.                     synth.speak(message)
  333.                 }
  334.                 /*
  335.                  * text – 要合成的文字内容,字符串
  336.                  * lang – 使用的语言,字符串, 例如:“zh-cn”
  337.                  * voiceURI – 指定希望使用的声音和服务,字符串
  338.                  * volume – 声音的音量,区间范围是0到1,默认是1
  339.                  * rate – 语速,数值,默认值是1,范围是0.1到10,表示语速的倍数,例如2表示正常语速的两倍。
  340.                  * pitch – 表示说话的音高,数值,范围从0(最小)到2(最大)。默认值为1
  341.                  */
  342.                 var s = "请" + obj.data.LineNum + "号顾客" + obj.data.CustName + "到" + obj.data.WindowNumStr + "号窗口办理业务";
  343.               
  344.                 voice_playback(s);
  345.                 setstatus("4", obj.data.ID, obj.tr);
  346.                
  347.                 return false;
  348.             } else if (obj.event === 'classfinish') {
  349.                 setstatus("5", obj.data.ID, obj.tr);
  350.                 return false;
  351.             } else if (obj.event === 'classovertime') {
  352.                 setstatus("6", obj.data.ID, obj.tr);
  353.                 return false;
  354.             }
  355.             else if (obj.event === 'setMemo') {
  356.                 layer.prompt({
  357.                     formType: 2
  358.                     , title: '修改用户【' + data.CustName + '】的备注'
  359.                     , value: data.Memo
  360.                 }, function (value, index) {
  361.                     layer.close(index);
  362.                     $.ajax({
  363.                         url: '../Ajax.ashx', //要请求的url地址
  364.                         type: 'POST', //请求方法 GET or POST
  365.                         async: true, //是否使用异步请求的方式
  366.                         timeout: 5000, //请求超时的时间,以毫秒计
  367.                         data: {
  368.                             rnum:"7",
  369.                             id: obj.data.ID,
  370.                             memo: value
  371.                         },
  372.                         dataType: 'json', //预期的服务器返回参数类型
  373.                         beforeSend: function () {
  374.                         },
  375.                         success: function (data) {
  376.                             //console.log(data);
  377.                             //同步更新表格中缓存对应的值
  378.                             obj.update({
  379.                                 Memo: value
  380.                             });
  381.                         },
  382.                         error: function () {
  383.                         },
  384.                         complete: function () {
  385.                            
  386.                         }
  387.                     });
  388.                   
  389.                   
  390.                 });
  391.             }
  392.             else if (obj.event === 'showview') {
  393.                 layer.open({
  394.                     type: 2
  395.                     , title: '查看用户'
  396.                     , area: ['50%', '520px']
  397.                     , shade: 0.1
  398.                     , maxmin: true
  399.                     , id: 'layuiproview' //设定一个id,防止重复弹出
  400.                     , content: '../page/table/TbLineUpView.aspx'
  401.                     , zIndex: layer.zIndex
  402.                     , success: function (layero, index) {
  403.                         var item = obj.data;
  404.                         var body = layer.getChildFrame('body', index);
  405.                      
  406.                         body.find("[name='rid']").val(item.ID);
  407.                         body.find("[name='CustName']").val(item.CustName);
  408.                         body.find("input[name='CustIDCard']").val(item.CustIDCard);
  409.                         body.find("input[name='CreateTime']").val(item.CreateTime);
  410.                         body.find("input[name='CallTime']").val(item.CallTime);
  411.                         body.find("input[name='FinishTime']").val(item.FinishTime);
  412.                         body.find("input[name='OptName']").val(item.OptName);
  413.                         body.find("input[name='LineNum']").val(item.LineNum);
  414.                         body.find("input[name='WindowNum']").val(item.WindowNum);                        
  415.                         if (item.BuType == "1") {
  416.                             body.find("input[name='BuType'][value='1']").prop("checked", true);
  417.                         }
  418.                         else {
  419.                             $(body).find("input[name='BuType'][value='2']").prop("checked", true);
  420.                         }
  421.                         body.find("[name='CustTel']").val(item.CustTel);
  422.                         body.find("[name='Memo']").val(item.Memo);
  423.                         layer.setTop(layero);
  424.                         //关键点:父窗口调用子页面的getformobj函数,返回子页面的form对象,然后重绘子页面的数据。
  425.                         var iframeWin = window[layero.find('iframe')[0]['name']];
  426.                         var o = iframeWin.getformobj();
  427.                         o.render();
  428.                     }
  429.                 });
  430.             }
  431.         });
  432.         function setstatus(currentrnum,currentid,objtr) {
  433.             $.ajax({
  434.                 url: '../Ajax.ashx', //要请求的url地址
  435.                 type: 'POST', //请求方法 GET or POST
  436.                 async: true, //是否使用异步请求的方式
  437.                 timeout: 5000, //请求超时的时间,以毫秒计
  438.                 data: {
  439.                     rnum: currentrnum,
  440.                     id: currentid
  441.                 },
  442.                 dataType: 'json', //预期的服务器返回参数类型
  443.                 beforeSend: function () {
  444.                 },
  445.                 success: function (data) {
  446.                     //console.log(data);
  447.                     switch (currentrnum) {
  448.                         case "4": $(objtr).css({ "background-color": "red", "color": "#fff" });  $(objtr).find("td[data-field='BuStatusStr']").find("div").text("办理中"); break;
  449.                         case "5": $(objtr).css({ "background-color": "#3cb371", "color": "#fff" });$(objtr).find("td[data-field='BuStatusStr']").find("div").text("已完成"); break;
  450.                         case "6": $(objtr).css({ "background-color": "#ccc", "color": "#fff" }); $(objtr).find("td[data-field='BuStatusStr']").find("div").text("已过期"); break;
  451.                     }  
  452.                 },
  453.                 error: function () {
  454.                 },
  455.                 complete: function () {
  456.                 }
  457.             });
  458.         }
  459.     });
  460. ‹/script>
  461.    
  462. ‹/body>
  463. ‹/html>
复制代码
  以上就是JavaScript实现语音排队叫号系统的详细内容,更多关于JavaScript语音排队叫号系统的资料请关注脚本之家其它相关文章!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|耀极客论坛 ( 粤ICP备2022052845号-2 )|网站地图

GMT+8, 2022-12-10 02:39 , Processed in 0.064292 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表