WebUI问题总结

修改WebUI代码时遇到的一些问题以及解决办法

1. thttpd服务器环境的搭建

可参考《thttpd安装与启动流程》这一篇文章

其中遇到的问题有

  1. thttpd版本问题:版本过旧会导致安装失败,尽量安装新版本
  2. thttpd的启动命令失败的话要加上sudo
  3. 修改文件权限:去掉文件的可执行权限,加上可写入权限,均参考《Ubuntu的基本使用》这篇文章,可以解决在Ubuntu中使用VScode修改代码时保存就显示权限不足需要输入root密码的问题
2. WebUI页面修改
  1. 代码修改了,但浏览器没有反应:要同步修改en.json文件,开发新的页面时,引用的文件也要加进来,涉及到文字要把赋值的值写到json里面
  2. 隐藏页面或者页面内容可以不用注释,直接在div标签中加上style="display: none;" 即可
3. T99W444编译与烧录

可参考《Docker 9x07编译环境》这一篇文章

  1. 169服务器线上编译更方便,因为服务器有搭好的环境
  2. 初次使用服务器,要修改bash命令行颜色,以便区分,可参考《修改服务器里bash命令行颜色》文章中~/.bashrc的配置
  3. 创建一个文件夹KAGA,cloneT99W444远程仓库
  4. 每次编译之前都要拉取最新的代码,git pull --rebase
  5. 需要开通docker权限,进入docker环境mydocker.sh heshuang
  6. 进到代码目录,你的代码放在哪个目录就进哪个目录cd kaga/T99W444/
  7. 编译./build.sh all,有时候需要清理一下./build.sh clean all
  8. 单独编译WebUI的部分用:./build.sh fx
  9. 编译完成之后会生成一个FKSB-100D.0.3.0-20230314-172904.zip文件,拷贝压缩包文件
  10. 服务器与本地文件上传与下载可以使用scp命令:scp mydocker.sh heshuang@10.187.47.169:~/KAGA/build_tools/
  11. 代码解压后,下载烧录软件,根据《KAGA Mifi2 QFIL 烧录固件》SOP在SVN上下载烧录的软件,然后按照步骤烧录,烧录成功后按照《调试webui》cmd输入指令开启板子,浏览器输入板子ip进行连接
  12. WebUI最新代码合并之后弹警示框Socket TimeOut,原因是对接了新的接口,没有编译最新的代码,需要拉取最新的代码进行编译,编译要记得进入docker环境。
  13. 页面一直弹出警示框:Device went to a bad state..please re-login!!,原因是由于我们不断的push新的代码进去,所以有很多错误日志,磁盘满了,解决方案:adb shell进入设备,rm -rf data/www/serror.log,清除错误日志,adb reboot重启设备即可
  14. 手机连接MiFi,访问IP,查看网页效果,连接不上的解决办法:修改mac地址,adb shell进入板子,ifconfig查看HWaddr后的mac地址,使用命令fx-set-wifi-mac后面跟00A1C6EBCC88类似于这样的修改过的mac地址,最后reboot重启动,再连接即可。
  15. push代码进板子时提示:C:\Users\25589>adb push E:\kaga\WebUI\web20230526_1\www /WEBSERVER adb: error: failed to copy 'E:\kaga\WebUI\web20230526_1\www\mManagementadb.html' to '/WEBSERVER/www/mManagementadb.html': remote Read-only file system解决办法:adb shell rw
4. Git上传提交代码到服务器
  1. git pull --rebase拉取最新的代码
  2. git diff对比修改过的文件与新代码的区别,然后将新代码下载下来与自己的代码进行合并
  3. 上传替换原本的仓库里的/KAGA/T99W444/apps_proc/foxconn/fx-www下的www代码
  4. git add .添加文件到git
  5. git diff --cached检查具体的提交内容
  6. git commit提交代码,打开编辑器,详细书写commit message,前面要加一个WebUI
  7. 默认编辑器为nano(退出ctrl+X),使用起来很不方便,可以试用命令git config --global core.editor vim 修改Git默认编辑器为vim
  8. git commit之后要git pull --rebase一下再push,避免产生大量merge commit出现,影响后面的debug
  9. git push推送到远程仓库,第一次push提示让我配置用户,配置即可(git config --global user.email等等)
5. WebUI导航
  1. 将原本的侧边栏导航改成顶部导航栏
  2. 修改理念:尽量少修改原本代码布局,本来尝试将原本的树状导航修改为胶囊下拉导航,但是需要修改大量的源代码,而且问题太多,后改为直接修改flex布局,改变轴的方向,删除侧边栏。
  3. 点击下拉导航会撑开导航栏:固定导航栏的高度之后,点击下拉导航中心会改变位置,所以同时要固定导航的位置fixed-top,给下拉列表加浅灰色背景和圆框以及阴影修饰并且以便与页面做区分。
  4. TestSettings菜单下的两个导航点击不能变色:这两个导航有两个data-title,点击test下的按钮改变的实际上是已经被隐藏的别的地方的样式,解决方案是直接注释掉被隐藏的Network Configuration和APN Profile Settings。
  5. 语言选择和登录按钮不能点击:改变这一个部分的层级,加style=“z-index: 1040”,大过覆盖它的层级就可以了。
  6. 点击下拉导航的子级后,导航自动隐藏:没有实现
  7. 三级菜单打开后再次点击还是回到打开的三级菜单,有记忆功能:没有实现
  8. 关于移动端响应式布局,由于原本的代码结构为sidebar,并且我没有修改代码结构,所以很难通过bootstrap框架实现响应式,只能通过原生js来做,判断是否为手机端,手机端从文字变为图标。
  9. 下拉菜单图标被挤走:固定导航菜单以及下拉菜单的宽度,用js动态调整文字和图标样式时导航菜单的宽度。在html生命周期里做一个判断web端与手机端,默认样式为web端,所以只需要判断是否为手机端并且改变样式就可以。
  10. 将判断是否为移动端的函数在onLoad里面调用,写了一个resize函数调整PC端页面在宽度小于768的情况下也显示图标,提升用户体验感。
  11. 点击下拉导航之外的页面,导航自动关闭:将menuCoseAll()关闭所有导航函数加入到页面点击事件中,就可以实现点击页面关闭下拉导航,但是由于下拉导航撑开的除却导航的右半部分页面无法实现点击关闭,所以在导航的最后一个li后面加上一个div,然后flex=1让它占导航栏剩下的全部空间,即点击页面任意部分均可以实现下拉导航关闭。
  12. 语言切换导致的导航宽度不适配的问题:在调整页面宽度的函数ResizeFunction()里添加一个判断条件,通过判断是日文还是英文,动态调整导航宽度。在判断是否为手机端的函数MobileFunction()里也添加语言的判断条件,为了保证每次刷新都是合适的宽度,在切换语言的函数LanguageChanged(e)里添加手机端与PC端的判断条件,里面套语言的判断条件,为了保证点击语言切换的时候自动刷新也能有合适的宽度。
  13. 优化每次PC端刷新时会闪过图标,手机端刷新会闪过文字的问题,只要把默认的文字和图标都设置成display:none;先隐藏起来,然后在判断的时候block显示出来就行了。
  14. 找王博要了24X24的图片,改成新图片之后,图片和文字还是会同时显示,明明设置的是默认display:none;隐藏,判断条件之后再block,但是还是有冲突。于是我设置了MobileFunction()函数PC端调用ResizeFunction()函数,语言判断函数LanguageChanged(e)中直接调用MobileFunction()函数。有一点点小问题:PC端日语状态下刷新会闪过英文。
6. debug
  1. debug Connection History and Bluetooth Management手机端适配:将任何 .table 元素包裹在 .table-responsive 元素内,即可创建响应式表格,其会在小屏幕设备上(小于768px)水平滚动。当屏幕大于 768px 宽度时,水平滚动条消失。

  2. debug:debug DHCP Server and Navigation width.

    1. DHCP Server: debug DHCP Server Reserved IP Address List only display two and a half lines.页面高度是通过计算标签元素高度来获取的,显示不全是因为获取数据需要时间渲染到页面上,但是计算高度的时候来不及把这个高度加上就计算完成了,所以要加一个延时等渲染完下面的button再计算页面高度。
    2. Navigation width: debug Navigation text display wrapping.把导航的高度取消固定,改为自动高度。这样即使换设备也不会出现换行超出高度的情况。
  3. WebUI:给settings/Wi-Fi settings/Basic页面添加SSID限制条件,限制特殊字符以及去掉中文字符的限制,给出拦截提示框,并验证是否拦截成功

    // 限制特殊字符
    if (isValidSSIDStr(AP_SSID_A.value) == false) {parent.alertModal("AlertBox", false, "", GetMessage("mWiFi_Config", "InvalidSSIDMsg1", lang_message) + ssid_no_allow_letter + GetMessage("mWiFi_Config", "InvalidSSIDMsg2", lang_message));return false;
    }var ssid_no_allow_letter = "`!@#$%^&*()[]{}?/|,<>\\'\"\t:;";function isValidSSIDStr(s) {var i;for (i = 0; i < s.length; i++) {var c = s.charAt(i);if (ssid_no_allow_letter.indexOf(c) >= 0){return false;}}return true;
    }// 去掉中文和日文的限制
    function isValidStr (s) {var i;for (i = 0; i < s.length; i++) {var c = s.charAt(i);var ch = s.charCodeAt(i);if (digits.indexOf(c) < 0 &&lowercaseLetters.indexOf(c) < 0 &&uppercaseLetters.indexOf(c) < 0 &&special_symbol.indexOf(c) < 0 &&filed_no_allow_letter.indexOf(c) < 0 &&device_no_allow_letter.indexOf(c) < 0 && chkCN(c) == false &&chkJPN(c) == false && !isASCIICodeLong(ch)) {return false;}}return true;
    }
    
  4. WebUI:给settings/Wi-Fi settings/Basic页面添加password限制条件,限制特殊字符以及中文日文字符,给出拦截提示框,并验证是否拦截成功

    // 限制特殊字符
    if (isValidPWStr(key) == false) {parent.alertModal("AlertBox", false, "", GetMessage("mWiFi_Config", "InvalidPWMsg1", lang_message) + pw_no_allow_letter + GetMessage("mWiFi_Config", "InvalidPWMsg2", lang_message));return false;
    }var pw_no_allow_letter = "`!@#$%^&*()[]{}?/|,<>\\'\"\t:;";function isValidPWStr(s) {var i;for (i = 0; i < s.length; i++) {var c = s.charAt(i);if (pw_no_allow_letter.indexOf(c) >= 0){return false;}}return true;
    }
    
  5. “Wi-Fi Mode”下拉选项框修改为只读文本框:将select选择标签改为input文本框标签,删除option,将value值改为默认只读的IPv4,添加readonly,并修改readonly默认灰色背景颜色为白色。

    <!-- <select name="AP_FreqBand_A_ID" id="AP_FreqBand_A_ID" style="width: 100%;" class="form-control contentinputstyle"><option value="0">2.4G</option>
    </select> -->
    <input type="text" name="AP_FreqBand_A_ID" id="AP_FreqBand_A_ID" style="width: 100%; background-color: white;" class="form-control contentinputstyle" readonly value="2.4G">
    
  6. 删除Reset Default页面的ResetSettingMsgA、ResetSettingMsgB、ResetSettingMsgC字符串,添加ResetSettingMsg字符串,将因为有双引号而分成三句话的一段提示文字改为一句话,并修复英日文转换的问题。document.getElementById("mRestoreDefaultResetSetting").innerHTML = message.mRestoreDefault.ResetSettingMsg;

  7. 给mWiFi_Config_Adv页面加apply的翻译转换代码:document.getElementById("mWiFi_Config_AdvApplyBtn") .value = message.mAlert.Apply:

  8. 更新MAC Address Filtering页面MAC Address Filter、VPN Pass-through页面PPTP VPN Pass-through Setting和L2TP VPN Pass-through Setting、Basic页面SSID Stealth的Enabled和Disabled,Advanced页面Wi-Fi Channel的Automatic日文转换翻译

  9. 给WiFi password添加一个不能使用空格、中文和日文的限制条件,并给出提示:Password is invalid.Not support space, Chinese and Japanese.

    if (/[\u4e00-\u9fa5 ]/.test(key)) {parent.alertModal("AlertBox", false, "", GetMessage("mWiFi_Config", "PWInvalidChar3", lang_message));return false;
    }
    if (/[\u0800-\u4e00 ]/.test(key)) {parent.alertModal("AlertBox", false, "", GetMessage("mWiFi_Config", "PWInvalidChar3", lang_message));return false;
    }
    
  10. 给Client List页面加载添加延时,解决Client列表显示不全的问题

    setTimeout(() => {parent.iframeLoaded(document.getElementById("bigContent").clientHeight + 50);
    }, 600);
    
  11. 给SSID添加首尾均不能添加空格的限制,修改限制条件提示为:SSID must not start and end with the space.

    if (AP_SSID_A.value.slice(len_a-1) == " " || AP_SSID_A.value.slice(0, 1) == " ") {parent.alertModal("AlertBox", false, "", GetMessage("mWiFi_Config", "SSIDAErr4", lang_message));return false;
    }
    
  12. DHCP页面优化:对比当前数据与原始表单数据,如果有改变则true,可以进行下一步,如果没有改变则做出拦截返回false,并给出提示框。

    // js中如何从一个函数获取数据到另一个函数进行使用:将需要传递的数据定义为全局变量,在一个函数中赋值,另一个函数中调用
    // 定义全局变量
    var lanipall = "";
    var lansubmaskall = "";
    var Dhcp_Enable = "";
    var sinpall = "";
    var einpall = "";
    var leasetime = "";
    // RefreshWLANSettings()函数中给全局变量赋值
    lanipall = obj.lan_gw_addrs;
    lansubmaskall = obj.lan_sub;
    Dhcp_Enable = obj.lan_dhcp;
    sinpall = obj.lan_dhcp_start;
    einpall = obj.lan_dhcp_end;
    leasetime = obj.lan_dhcp_lease / 3600;
    // 创建一个isFormChanged()函数
    function isFormChanged() {// 获取页面中各个配置项的值// var obj = jQuery.parseJSON(msgs);var lanip = document.getElementById("lanipall").value;var subnetMask = document.getElementById("lansubmaskall").value;var dhcpEnabled = document.getElementById("Dhcp_Enable").value;var dhcpStartIP = document.getElementById("sinpall").value;var dhcpEndIP = document.getElementById("einpall").value;var leaseTime = document.getElementById("leasetime").value;// 检查这些值是否与之前保存的值相同if (lanip == lanipall && subnetMask == lansubmaskall && dhcpEnabled == Dhcp_Enable && dhcpStartIP == sinpall&& dhcpEndIP == einpall && leaseTime == leasetime) {return false;}return true;
    }
    // apply()函数中调用
    if (isFormChanged() == false) {parent.alertModal("AlertBox", false, "", GetMessage("mLan_Config", "ApplyNoChangeMsg", lang_message));return false;
    }
    
  13. DHCP页面优化:若提交的内容没有变化则拦截提交并给出提示。问题是,如果修改提交后,不手动刷新,再次不修改直接点击提交,不会被拦截,会直接继续提交。有两种方案:UpdateWLANSettings()的延迟处调用RefreshWLANSettings()接口,或者设置自动刷新当前页面。刷新当前页面:window.location.reload();都没办法解决这个问题

  14. DHCP页面优化:解决昨天说的需要手动刷新的问题,在调用UpdateWLANSettings()请求之前将当前的值赋值给全局变量。解决问题

    function apply() {if (isFormChanged() == false) {parent.alertModal("AlertBox", false, "", GetMessage("mLan_Config", "ApplyNoChangeMsg", lang_message));return false;}if (valiateIPRange() == false)return false;var AskDeleteMsg = GetMessage("mLan_Config", "PopupChangeDhcp", lang_message);parent.confirmDialog(true, GetMessage("mLan_Config", "PopupChange", lang_message), AskDeleteMsg, GetMessage("mAlert", "OK", lang_message), GetMessage("mAlert", "Cancel", lang_message),function () {//yes functionparent.loadingModal();// 在这里把当前的值赋值给全局变量lanipall = document.getElementById("lanipall").value;lansubmaskall = document.getElementById("lansubmaskall").value;Dhcp_Enable = document.getElementById("Dhcp_Enable").value;sinpall = document.getElementById("sinpall").value;einpall = document.getElementById("einpall").value;leasetime = document.getElementById("leasetime").value;UpdateWLANSettings();return true;},function () {//cancel function});
    }
    

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

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

相关文章

【C++重点】deque

C queue 容器介绍 queue 是 C 标准库中的一个容器适配器&#xff0c;它实现了先进先出&#xff08;FIFO&#xff09;数据结构。即&#xff0c;元素按照插入的顺序排队&#xff0c;首先插入的元素最先出队。queue 适用于需要排队处理任务的场景&#xff0c;比如消息队列、任务调…

透过 /proc 看见内核:Linux 虚拟文件系统与 systemd 初始化初探

当我们在终端中输入 ps、top、cat /proc/cpuinfo 等命令时&#xff0c;是否思考过这些信息来自哪里&#xff1f;为什么无需启动任何守护进程&#xff0c;就能实时读取系统负载、内存占用&#xff0c;甚至内核版本&#xff1f;这一切的答案&#xff0c;都藏在 Linux 系统中的一个…

操作系统(中断 异常 陷阱) ─── linux第28课

目录 1.硬件中断 2. 时钟中断 3. OS本质 4. 软件中断 缺页中断&#xff1f;内存碎片处理&#xff1f;除零野指针错误&#xff1f; 操作系统本质总结 操作系统是对软件硬件资源管理的软件 1.硬件中断 中断向量表(IDT)就是操作系统的⼀部分&#xff0c;启动就加载到内存中了…

文件分片上传

1前端 <inputtype"file"accept".mp4"ref"videoInput"change"handleVideoChange"style"display: none;">2生成hash // 根据整个文件的文件名和大小组合的字符串生成hash值&#xff0c;大概率确定文件的唯一性fhash(f…

机器学习的一百个概念(5)数据增强

前言 本文隶属于专栏《机器学习的一百个概念》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…

基于微信小程序的智慧乡村旅游服务平台【附源码】

基于微信小程序的智慧乡村旅游服务平台&#xff08;源码L文说明文档&#xff09; 目录 4系统设计 4.1系统功能设计 4.2系统结构 4.3.数据库设计 4.3.1数据库实体 4.3.2数据库设计表 5系统详细实现 5.1 管理员模块的实现 5.1.1旅游景点管理…

数据驱动的智能BMS革新:机器学习赋能电池健康预测与安全协同优化

传统电池管理系统&#xff08;BMS&#xff09;依赖等效电路模型和固定参数算法&#xff0c;面临电化学机理复杂、老化行为非线性、多工况适应性差等瓶颈。例如&#xff0c;健康状态&#xff08;SOH&#xff09;和荷电状态&#xff08;SOC&#xff09;估算易受温度、循环次数及电…

使用JSON.stringify报错:Uncaught TypeError: cyclic object value

具体错误 Uncaught TypeError: cyclic object valueonMouseOver Amap.vue:125renderMarker Amap.vue:84emit maps:1emit maps:1ci maps:1ui maps:1fireEvent maps:1jL maps:1Xt maps:1T maps:1<anonymous> amap.vue:49promise callback*nextTick runtime-core.esm-bundl…

Spring Boot 工程创建详解

2025/4/2 向全栈工程师迈进&#xff01; 一、SpingBoot工程文件的创建 点击Project Structure 然后按着如下点击 最后选择Spring Boot &#xff0c;同时记得选择是Maven和jar&#xff0c;而不是war。因为Boot工程内置了Tomcat&#xff0c;所以不需要war。 紧接着选择Spring We…

Java 8 的流(Stream API)简介

Java 8 引入的 Stream API 是一个强大的工具&#xff0c;用于处理集合&#xff08;如 List、Set&#xff09;中的元素。它支持各种操作&#xff0c;包括过滤、排序、映射等&#xff0c;并且能够以声明式的方式表达复杂的查询操作。流操作可以是中间操作&#xff08;返回流以便进…

4. Flink SQL访问HiveCatalog

一. 实验环境 Flink版本: 1.19.1 Hive版本: 2.1.3 Hadoop版本: 3.2.4二. 操作步骤 1.上传所需的jar包到Flink lib目录下 [roothadoop3 ~]# mv flink-sql-connector-hive-3.1.3_2.12-1.19.1.jar /www/flink-1.19.1/lib [roothadoop3 ~]# mv hadoop-mapreduce-client-core-3.2…

虚拟试衣间-云尚衣橱小程序-衣橱管理实现

衣橱管理实现 目标 (Goal): 用户 (User): 能通过 UniApp 小程序上传衣服图片。 后端 (Backend): 接收图片,存到云存储,并将图片信息(URL、用户ID等)存入数据库。 用户 (User): 能在小程序里看到自己上传的所有衣服图片列表。 技术栈细化 (Refined Tech Stack for this Pha…

HAL库 通过USB Boot进行APP程序升级

硬件&#xff1a;stm32f407VET6芯片&#xff1b; 软件&#xff1a;STM32CubeMx、Keil5 上位机&#xff1a;Dfuse DemoV3.06 这里给出通过在Bootlaoder中使用USB方式来更新APP程序的方法&#xff0c;首先我们编写一个自己的bootloader&#xff0c;关于bootloader的大致原理可以…

数据库权限获取

1. into outfile&#xff08;手写&#xff09; 1.1. 利用条件 • web 目录具有写入权限&#xff0c;能够使用单引号 • 知道网站绝对路径&#xff08;根目录&#xff0c;或则是根目录往下的目录都行&#xff09; • secure_file_priv 没有具体值&#xff08;在 mysql/my.ini…

关于ESP系列MCU的UART download原理

GPIO0&#xff0c;即BOOT&#xff0c;工作模式选择&#xff1a; 悬空/拉高&#xff1a;正常MCU启动工作状态 下拉接地&#xff1a;UARTDownload下载模式 如何进入UARTDownload下载模式&#xff1f; 先按下boot按键不放&#xff0c;再按下rst按键 / en按键&#xff0c;随后释放…

无需安装Office进行 Word、Excel操作的微软开发库

微软的确有一些无需安装完整 Office 就能进行 Word、Excel 操作的开发库&#xff0c;以下为你介绍&#xff1a; 1. Microsoft Graph API 简介&#xff1a;Microsoft Graph API 是一个强大的 RESTful API&#xff0c;能让开发者通过调用接口访问 Office 365 服务里的各种资源&…

【一起来学kubernetes】34、ReplicaSet使用详解

Kubernetes ReplicaSet 使用详解 ReplicaSet 是 Kubernetes 中用于确保指定数量的 Pod 副本持续运行的核心控制器。它通过动态调整 Pod 副本数&#xff0c;保障应用的高可用性和弹性。以下是其核心功能、配置方法及最佳实践&#xff1a; 一、ReplicaSet 核心作用 维持 Pod 副本…

【力扣hot100题】(034)LRU缓存

做完这题已经没有任何力气写链表题了。 思路很简单&#xff0c;就是调试特别的痛苦。 老是频频报错&#xff0c;唉。 class LRUCache { public:struct ListNode{int key,val;ListNode* next; ListNode* prev;ListNode() : key(0), val(0), next(nullptr), prev(nullptr) {}L…

基于随机森林算法的信用风险评估项目

引言 这是一个基于随机森林算法的德国信用风险评估项目&#xff0c;主要目的是构建一个机器学习模型来评估德国客户的信用风险&#xff0c;判断客户是否为高风险客户。 # -*- coding: utf-8 -*- """ 德国信用风险评估随机森林模型 """ # 基础…

亚马逊云科技携手 DeepSeek:开启企业级生成式 AI 新征程

文章目录 一、DeepSeek-R1模型的技术突破&#xff08;一&#xff09;卓越的性能表现&#xff08;二&#xff09;独特的训练方法&#xff08;三&#xff09;丰富的模型生态 二、亚马逊云科技平台上的部署与优化&#xff08;一&#xff09;灵活的部署方式&#xff08;二&#xff…