<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>BH4FWA</title>
  
  <subtitle>BH4FWA‘s yet another Blog</subtitle>
  <link href="https://blog.bh4fwa.com/atom.xml" rel="self"/>
  
  <link href="https://blog.bh4fwa.com/"/>
  <updated>2024-08-30T14:04:33.358Z</updated>
  <id>https://blog.bh4fwa.com/</id>
  
  <author>
    <name>Jonas Qiao</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>ONLINE DATA LOST</title>
    <link href="https://blog.bh4fwa.com/2024/08/14/16-14-46/"/>
    <id>https://blog.bh4fwa.com/2024/08/14/16-14-46/</id>
    <published>2024-08-14T16:14:46.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<p>如果你的线上MySQL数据库是由你搭建并维护的，数据库中有比较重要的核心数据，而你突然发现你迷迷糊糊误操作了，执行了 <code>rm -rf /data/</code> 导致线上MySQL的文件夹目录数据全部丢失， 你会怎么办呢？</p><p>If Your Online MySQL Database is Built and Maintained by You, and It Contains Important Core Data, You Have Misunderstood and Executed <code>rm -rf /data/</code> to Delete the Entire Directory of Your Online MySQL Files, What Will You Do?</p><span id="more"></span><p>这是我在前一段时间，真实经历的一件事，但是所幸，事件的操作者当时以为没有备份，当时真的是太绝望了。在第二天也许是死心了之后又或是总是要面对的，竟然意外的和云服务商找回了对应服务器的前大概2-3天的备份，所幸数据丢失不算很多，一两天的数据还算可以接受。</p><p>这事情也过去了大概有半个月，这半个月一直在处理一些其他的事，今天索性就来写个记录。</p><h1 id="前情提要"><a href="#前情提要" class="headerlink" title="前情提要"></a>前情提要</h1><p>前情提要：作者和我是朋友，也是程序员。他在某一家国企上班。和大家理想中的国企工作不一样，他们那里就只有2个后端开发，Java的代码功能开发也不是很简单，所以是两个后端撑起一个部门，而他们的部门领导对他也并不太好，经常要他打黑工，所以说他的日常就可预期的被一些外人看来莫名其妙的工作所占满，自己的工作总是要拖到很久以后才能干。</p><h1 id="事情表象"><a href="#事情表象" class="headerlink" title="事情表象"></a>事情表象</h1><p>事情大概是这样子的，7月底的某一天下午4点半，他在微信上问我，数据库被误删除了，要怎么恢复，于是我就比较好奇，顺带抛出了一些问题，数据是否重要，是什么数据库被删除了，从朋友口中我得知，他的数据是线上的MySQL，并且是自己搭建的。刚开始我还比较纳闷，难道国企数据安全这么不规范的吗，在外面随便一个私企都不敢把线上的数据放到MySQL中去，而他们直接把线上的数据放到自己搭建的单节点的MySQL的docker容器中去。属实是buff叠满了。于是我让朋友发我了docker的 inspect信息，看到了服务器磁盘映射挂载的信息，进到了宿主机上的对应目录中去看了一下，果然是空了的。<br>于是我就真的很奇怪了，如果是之前就有数据的，肯定不可能是空的，那么我就让他给我了他的服务器 <code>history</code> 命令的截图，我还在看的时候，发现了端倪。 </p><h1 id="表象原因"><a href="#表象原因" class="headerlink" title="表象原因"></a>表象原因</h1><p>图片在这里：<img src="/images/data_operation.png" alt="data_operation.png"><br>注意看在 上方前几行，有一行 <code>rm -rf fi /data/</code> 这个应该就是误操作的记录。所以这个实际上就是因为我朋友误操作执行了  <code>rm -rf /data/</code> 才导致数据文件目录被删除掉了，他还告诉我，执行完了，他立马发现不太对劲，然后疯狂按Ctrl + C，但是终结完了以后再进目录，发现mysql的文件目录都已经被删除掉了。</p><h1 id="是否备份"><a href="#是否备份" class="headerlink" title="是否备份"></a>是否备份</h1><p>数据丢的原因很容易找到，那自然要尝试怎么找回来，但实话说，之前也没遇到过这种情况，于是我们便又开始了找数据的历程。找数据的历程自然起始是要问清楚有无备份，如果有备份的话数据恢复自然就是早晚的事。在遍历了可能的源数据文件 如是否有每日SQL Dump，以及各种备份恢复机制，也就是通过SQL可执行文件&#x2F;mysql的binlog之类的备份恢复机制&#x2F;服务器快照策略（这个前面有讲，当时确实认为没有快照）之后，一脸懵逼，全部都没有！！！当时我甚至都认为（不是以为，是真的是感觉要死了）棺材都躺一半了。</p><h1 id="恢复尝试"><a href="#恢复尝试" class="headerlink" title="恢复尝试"></a>恢复尝试</h1><p>后来问了运维比较好的一位朋友，这种是否能恢复，要取决于磁盘类型和挂载方式，于是又让我朋友通过 cfdisk  和 lsblk 查看文件磁盘的类型，<br>发现是 LVM逻辑磁盘卷，这个多是虚拟化磁盘类型，也就是把磁盘虚拟化或是融合到一起去，组成一个Pool，再去对上层提供存储和挂载，PVE就是这种磁盘格式。而且在这个过程中，也了解到一些正常的磁盘恢复的手段和方法。最简单的磁盘恢复方式，是实体机安装服务器操作系统 + 机械磁盘。Linux系统是基于inode来实现的文件存储机制，inode包含了每个目录的元数据信息，如果文件被删除时，立马使用inode恢复工具，找到被删除的inode号，也许还可以恢复数据，因为inode是这么一个机制，当你删除，也就是执行 <code>rm -rf /*</code> 时，文件并非是即时立马被删除掉的，很大批量的文件在磁盘上，也并非可以直接全部删除掉，会先在文件系统中标记删除，然后系统在空闲时刻再去回收掉对应的inode，了解到就算是机械盘，<br>也有个几分钟的时间来让你做对应的操作，如果你恰好反应过来了，又恰好懂得磁盘恢复，又恰好是实体机安装的话，那么可能是可以恢复回来的。否则，变一步，都比登天还难。<br>如果你的磁盘是SSD的话，SSD是一颗主控去管理N多个堆叠的NAND 芯片，同时SSD的NAND结构是纯粹的电逻辑门控制的，并非是HDD那种磁头读写数据，通过电力改变磁头磁性，来读取出磁盘区块中的比特位是0或1的数据信息的结构，有些SSD磁盘为了加速读写吞吐性能，甚至会在底层增加trim的属性，trim也很好理解，就是当你在删除数据之后，如果有 trim属性的话，那么你的数据区块可能在几秒钟之内就会自动被删除掉。这下子我算是明白了数据中心为什么会宁愿用到HDD也不用很高读取速度的SSD的原因了。因为环境是不一样的，而且存储原理都不一样，HDD更为传统，数据误删除后，还可以通过断电停机等方式，来保存数据，更有甚者，专业数据中心还会使用磁带机来进行数据的冷备。</p><h1 id="文件恢复的小知识"><a href="#文件恢复的小知识" class="headerlink" title="文件恢复的小知识"></a>文件恢复的小知识</h1><p>现代操作系统的文件格式，磁盘上会有很多超级备份快，类似游戏里的一个一个check point，存储这一区块中的文件元数据信息，如果丢失数据之后，可以尝试从超级备份快找一下。<br>还有的话，是inode，如果inode没有丢失，且时间足够短的情况下，也是可以恢复回来的。</p><h1 id="数据库使用教训"><a href="#数据库使用教训" class="headerlink" title="数据库使用教训"></a>数据库使用教训</h1><p>事实证明，数据安全是永无止境的话题。一定要在设计程序之初或是使用某个存储中间件时，就要考虑到数据是怎么恢复和备份的。不要等到真的出了事，再去发现，那样子就晚了。哪怕是使用最错币的方式勤备份，也比不管要强很多倍。<br>1.使用mysql 的话 要尽量开 binlog备份，同时 binlog的备份目录，建议是不要放在 数据目录中，一定要分开存储。<br>2.如果自己可以连得上数据库的话，哪怕最垃圾的方式，也就是自己手动每天导出备份一下。<br>3.如果是有类似宝塔（虽然说安全性差了点，但是好在备份数据是绝对的方便，没有之一）之类的工具的话，那么可以配置一些备份策略，滚动备份，这样子每次至少能保证有n多个历史景象或是全量数据，不至于两眼一抹黑。<br>4.如果是使用云厂商的数据存储产品，那么肯定1000%是有快照或是备份的，或全量或定期增量，备份策略也要开起来，要考虑到数据的绝对安全性。<br>5.如果认为我说的1-4 不对，那么请放弃查看本文，我可能就是个菜鸟。</p><h1 id="后续"><a href="#后续" class="headerlink" title="后续"></a>后续</h1><p>第二天，我朋友可能是联系了云厂商的客服，给了出事的磁盘号，然后云厂商客服帮忙找到了快照,快照是出事之前大约2-3天，损失的数据还算是可以接受，相比于损失全量数据的话，这个代价就算还好。经过这一次事情，我朋友应该知道了备份的重要性吧（或许吧，不过要吐槽的是，朋友的公司的部门，他们那天有同事也在，还说之前从来没有出过这种事，所以其他的也是没有备份的。我就一整个大无语了，这个数据难道还要出过事才能知道的吗，按照这个操作逻辑，但凡出一点事，客户分分钟是要骂娘的事情，你就想嘛，如果你是你公司的产品的客户，直接把你的真实使用的数据丢在一个黑盒子里，也没有备份恢复的机制，你觉得用的放心吗？</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;如果你的线上MySQL数据库是由你搭建并维护的，数据库中有比较重要的核心数据，而你突然发现你迷迷糊糊误操作了，执行了 &lt;code&gt;rm -rf /data/&lt;/code&gt; 导致线上MySQL的文件夹目录数据全部丢失， 你会怎么办呢？&lt;/p&gt;
&lt;p&gt;If Your Online MySQL Database is Built and Maintained by You, and It Contains Important Core Data, You Have Misunderstood and Executed &lt;code&gt;rm -rf /data/&lt;/code&gt; to Delete the Entire Directory of Your Online MySQL Files, What Will You Do?&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>10000 Page Views - 成就达成1w次观看</title>
    <link href="https://blog.bh4fwa.com/2024/07/17/03-46-54/"/>
    <id>https://blog.bh4fwa.com/2024/07/17/03-46-54/</id>
    <published>2024-07-17T03:46:54.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>创建这个blog已经超过了3个月，与此同时，也算达成了一些微微小的成就，超过了10000次 Page View。<br>下面是成就邮件。<br>This blog has been running over 3 months, and I have achieved 10000 Page Views.</p><span id="more"></span><p><img src="/images/10000_cloud_flare_mail.png" alt="10000_cloud_flare_mail.png"></p><p>不知道这个1w次 Page View算是页面或是所有的请求都算上，还是只有html页面的才算，不管哪种方式，对我来说也算是一个小小的正反馈，人世间最大的乐趣在于有人愿意和你交流，而有人看到我写的文章，也算是交流的一种。如果有些评论之类的那就更好了：）</p><p>但是我也发现了我的访客的国家构成，以Cloudflare的过去30天的数据来看，我的访客 只有一小部分是中国的，而其他相当一部分来自世界各地。这也直接解答了我很早之前的疑惑，那就是看某些人的blog的时候，会发现，他们会在blog里会更新一些英文的文章，我当时还纳闷，怎么国内的blog更新一些英文的内容，这么奇怪，原来受众是不一样的，中文内容只是给部分国内的访问者看。</p><p>所以为了照顾我那批小的国外浏览者，我决定是时候开启国际化进程了。但是找寻hexo 和 next博客主题的国际化方案，并没有什么比较不错的方式，所以我决定开启自己的国际化探索。</p><p>也就是，在同一篇文章同时放上中英文，借此也锻炼一下我的英文写作水平。</p><p>10000 page view在当今社会 已经是一个很小的微不足道的成就，但对我来说意义非凡，我将会一直不断地更新下去。</p><h1 id="English-Version"><a href="#English-Version" class="headerlink" title="English Version"></a>English Version</h1><p>This blog has been running over 3 months, and I have achieved 10000 Page Views.</p><p>I don’t know this 10000 page views is either all requests or just html pages requests. whatever, that’s a small positive feedback for me.</p><p>According to the data of Cloudflare’s past 30 days, my visitors are only a small part of China,<br>and the rest of them are from all over the world. So that directly answers my earlier doubt. That is, Why a Chinese blog update some English articles, so strange, I was confused. For the blog creators, Chinese content is just for a small part of the domestic visitors.   </p><p>So to accommodate my small foreign visitors, I decided to start the internationalization process. But I found that there was no good way to internationalize hexo and next blog themes. So I decided to start my own internationalization exploration.</p><p>Which means, I will put Chinese and English in the same article, by the way it can improve my English writing skills.</p><p>10000 page view in the current society is already a small micro-achievement, but it is extremely significant for me, I will continue to update it constantly.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;创建这个blog已经超过了3个月，与此同时，也算达成了一些微微小的成就，超过了10000次 Page View。&lt;br&gt;下面是成就邮件。&lt;br&gt;This blog has been running over 3 months, and I have achieved 10000 Page Views.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>《轻型民用无人驾驶航空器安全操控》--多旋翼部分</title>
    <link href="https://blog.bh4fwa.com/2024/05/17/15-45-26/"/>
    <id>https://blog.bh4fwa.com/2024/05/17/15-45-26/</id>
    <published>2024-05-17T15:45:26.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<p>《轻型民用无人驾驶航空器安全操控》–多旋翼部分</p><span id="more"></span><p><span class="s3_pv"></span></p><h1 id="航空器知识"><a href="#航空器知识" class="headerlink" title="航空器知识"></a>航空器知识</h1><h2 id="多旋翼民用无人驾驶航空器螺旋桨作用"><a href="#多旋翼民用无人驾驶航空器螺旋桨作用" class="headerlink" title="多旋翼民用无人驾驶航空器螺旋桨作用"></a>多旋翼民用无人驾驶航空器螺旋桨作用</h2><p>螺旋桨为多旋翼民用无人驾驶航空器提供升力，多旋翼民用无人驾驶航空器通过飞控系统控制电机调节螺旋桨转速，来实现飞行。</p><h2 id="多旋翼民用无人驾驶航空器天线的作用"><a href="#多旋翼民用无人驾驶航空器天线的作用" class="headerlink" title="多旋翼民用无人驾驶航空器天线的作用"></a>多旋翼民用无人驾驶航空器天线的作用</h2><p>多旋翼民用无人驾驶航空器的图像传输以及遥控控制信号，主要是通过无线信道进行的，靠民用无人驾驶航空器与遥控器的天仙传输。所以，一定要避免在高压线，通讯基站，或发射塔等区域飞行，以免无线通信信号受到干扰。</p><h2 id="多旋翼民用无人驾驶航空器中的图传是什么？"><a href="#多旋翼民用无人驾驶航空器中的图传是什么？" class="headerlink" title="多旋翼民用无人驾驶航空器中的图传是什么？"></a>多旋翼民用无人驾驶航空器中的图传是什么？</h2><p>图传是图像传输技术和装置，是指将图像信息通过无线电波或有线电览峰方式传输到远程设备上，实现图像的监控，传输和存储。图传的原理是将摄像头采集到的图像数据进行编码压缩，然后通过无线电波或有线电缆传输到接收端。在接收端，解码器将接收到的数据解码还原成原始图像，再通过显示器或其他设备进行显示或存储。</p><h2 id="在操作多旋翼民用无人驾驶航空器时，如何保证图传传输距离足够远？"><a href="#在操作多旋翼民用无人驾驶航空器时，如何保证图传传输距离足够远？" class="headerlink" title="在操作多旋翼民用无人驾驶航空器时，如何保证图传传输距离足够远？"></a>在操作多旋翼民用无人驾驶航空器时，如何保证图传传输距离足够远？</h2><p>多旋翼民用无人驾驶航空器通过无线电图传模块进行无线通信，无线电磁波采用直线传输，类似光线传输效果。所以，障碍物的阻挡对无线图传进行无线传输有着巨大的影响。如果发射和接收相对的方向有很多障碍物，无线传输的信号就几乎没有穿透的可能，就算能穿透，信号也非常弱，因此，在障碍物较少的远郊野外，开阔农田环境下，多旋翼民用无人驾驶航空器的图传距离较远。</p><h2 id="多旋翼民用无人驾驶航空器遥控器摇杆的作用"><a href="#多旋翼民用无人驾驶航空器遥控器摇杆的作用" class="headerlink" title="多旋翼民用无人驾驶航空器遥控器摇杆的作用"></a>多旋翼民用无人驾驶航空器遥控器摇杆的作用</h2><p>遥控器摇杆主要用于实时控制民用无人驾驶航空器的高度，方向和速度等飞行状态。</p><h2 id="常见的多旋翼民用无人驾驶航空器机头指示灯，状态指示灯的作用"><a href="#常见的多旋翼民用无人驾驶航空器机头指示灯，状态指示灯的作用" class="headerlink" title="常见的多旋翼民用无人驾驶航空器机头指示灯，状态指示灯的作用"></a>常见的多旋翼民用无人驾驶航空器机头指示灯，状态指示灯的作用</h2><p>航空器机头LED指示灯用于指示机头方向，状态指示灯用于指示当前飞控系统的状态。</p><h2 id="多旋翼民用无人驾驶航空器视觉系统的作用"><a href="#多旋翼民用无人驾驶航空器视觉系统的作用" class="headerlink" title="多旋翼民用无人驾驶航空器视觉系统的作用"></a>多旋翼民用无人驾驶航空器视觉系统的作用</h2><p>当广州啊等环境条件满足视觉系统需求时，可利用视觉系统定位实现暂停，视觉系统还可通过图像测距来感知障碍物实现避障。</p><h2 id="多旋翼民用无人驾驶航空器云台相机的作用"><a href="#多旋翼民用无人驾驶航空器云台相机的作用" class="headerlink" title="多旋翼民用无人驾驶航空器云台相机的作用"></a>多旋翼民用无人驾驶航空器云台相机的作用</h2><p>云台相机是多旋翼民用无人驾驶航空器的常见负载，其作用是让民用无人驾驶航空器在高速飞行的状态下，也能获取稳定的影像。</p><h2 id="在常见的多旋翼民用无人驾驶航空器中返航按钮的作用"><a href="#在常见的多旋翼民用无人驾驶航空器中返航按钮的作用" class="headerlink" title="在常见的多旋翼民用无人驾驶航空器中返航按钮的作用"></a>在常见的多旋翼民用无人驾驶航空器中返航按钮的作用</h2><p>常见的多旋翼民用无人驾驶航空器都配置有返航按键，其作用是启动或取消返航，启动后民用无人驾驶航空器将返航至最新记录的返航点。</p><h2 id="多旋翼民用无人驾驶航空器遥控器云台俯仰控制波轮的作用"><a href="#多旋翼民用无人驾驶航空器遥控器云台俯仰控制波轮的作用" class="headerlink" title="多旋翼民用无人驾驶航空器遥控器云台俯仰控制波轮的作用"></a>多旋翼民用无人驾驶航空器遥控器云台俯仰控制波轮的作用</h2><p>通过拨动多旋翼民用无人驾驶航空器遥控器云台俯仰控制波轮，可以调节云台俯仰角度。</p><h2 id="多旋翼民用无人驾驶航空器遥控器录像按键，拍照按键的作用"><a href="#多旋翼民用无人驾驶航空器遥控器录像按键，拍照按键的作用" class="headerlink" title="多旋翼民用无人驾驶航空器遥控器录像按键，拍照按键的作用"></a>多旋翼民用无人驾驶航空器遥控器录像按键，拍照按键的作用</h2><p>遥控器录像按键可以控制相机开始或停止录像，拍照按键可以控制相机拍摄照片。</p><h1 id="安全使用知识"><a href="#安全使用知识" class="headerlink" title="安全使用知识"></a>安全使用知识</h1><h1 id="操控知识"><a href="#操控知识" class="headerlink" title="操控知识"></a>操控知识</h1>]]></content>
    
    
    <summary type="html">&lt;p&gt;《轻型民用无人驾驶航空器安全操控》–多旋翼部分&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>《轻型民用无人驾驶航空器安全操控》--法规部分</title>
    <link href="https://blog.bh4fwa.com/2024/05/17/14-13-44/"/>
    <id>https://blog.bh4fwa.com/2024/05/17/14-13-44/</id>
    <published>2024-05-17T14:13:44.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<p>《轻型民用无人驾驶航空器安全操控》–法规部分</p><span id="more"></span><h1 id="民用无人驾驶航空器的分类"><a href="#民用无人驾驶航空器的分类" class="headerlink" title="民用无人驾驶航空器的分类"></a>民用无人驾驶航空器的分类</h1><h2 id="如何定义微型，轻型无人驾驶航空器？"><a href="#如何定义微型，轻型无人驾驶航空器？" class="headerlink" title="如何定义微型，轻型无人驾驶航空器？"></a>如何定义微型，轻型无人驾驶航空器？</h2><h4 id="微型无人驾驶航空器，是指空机重量小于0-25kg，最大飞行真高不超过50m，最大平飞速度不超过40km-h，无线电发射设备无核为功率段距离技术要求，全程可以随时人工介入操控的无人驾驶航空器。"><a href="#微型无人驾驶航空器，是指空机重量小于0-25kg，最大飞行真高不超过50m，最大平飞速度不超过40km-h，无线电发射设备无核为功率段距离技术要求，全程可以随时人工介入操控的无人驾驶航空器。" class="headerlink" title="微型无人驾驶航空器，是指空机重量小于0.25kg，最大飞行真高不超过50m，最大平飞速度不超过40km&#x2F;h，无线电发射设备无核为功率段距离技术要求，全程可以随时人工介入操控的无人驾驶航空器。"></a>微型无人驾驶航空器，是指空机重量小于0.25kg，最大飞行真高不超过50m，最大平飞速度不超过40km&#x2F;h，无线电发射设备无核为功率段距离技术要求，全程可以随时人工介入操控的无人驾驶航空器。</h4><h4 id="轻型无人驾驶航空器，是指空机重量不超过4kg且最大起飞质量不超过7kg，最大平飞速度不超过100km-h，具备符合空余管理要求的空余爆锤能力和可靠被监视能力，全程可以随时人工介入操控的无人驾驶航空器，但不包括微型无人驾驶航空器。"><a href="#轻型无人驾驶航空器，是指空机重量不超过4kg且最大起飞质量不超过7kg，最大平飞速度不超过100km-h，具备符合空余管理要求的空余爆锤能力和可靠被监视能力，全程可以随时人工介入操控的无人驾驶航空器，但不包括微型无人驾驶航空器。" class="headerlink" title="轻型无人驾驶航空器，是指空机重量不超过4kg且最大起飞质量不超过7kg，最大平飞速度不超过100km&#x2F;h，具备符合空余管理要求的空余爆锤能力和可靠被监视能力，全程可以随时人工介入操控的无人驾驶航空器，但不包括微型无人驾驶航空器。"></a>轻型无人驾驶航空器，是指空机重量不超过4kg且最大起飞质量不超过7kg，最大平飞速度不超过100km&#x2F;h，具备符合空余管理要求的空余爆锤能力和可靠被监视能力，全程可以随时人工介入操控的无人驾驶航空器，但不包括微型无人驾驶航空器。</h4><h3 id="什么是空机重量，最大起飞重量？"><a href="#什么是空机重量，最大起飞重量？" class="headerlink" title="什么是空机重量，最大起飞重量？"></a>什么是空机重量，最大起飞重量？</h3><h4 id="控制重量是指无人驾驶航空器机体，电池人聊容器等固态装置重量总和，不含填充燃料和任务载荷的重量。"><a href="#控制重量是指无人驾驶航空器机体，电池人聊容器等固态装置重量总和，不含填充燃料和任务载荷的重量。" class="headerlink" title="控制重量是指无人驾驶航空器机体，电池人聊容器等固态装置重量总和，不含填充燃料和任务载荷的重量。"></a>控制重量是指无人驾驶航空器机体，电池人聊容器等固态装置重量总和，不含填充燃料和任务载荷的重量。</h4><h4 id="最大起飞重量是指根据设计或者运行限制，无人驾驶航空器正常起飞所容许的最大重量。"><a href="#最大起飞重量是指根据设计或者运行限制，无人驾驶航空器正常起飞所容许的最大重量。" class="headerlink" title="最大起飞重量是指根据设计或者运行限制，无人驾驶航空器正常起飞所容许的最大重量。"></a>最大起飞重量是指根据设计或者运行限制，无人驾驶航空器正常起飞所容许的最大重量。</h4><h2 id="操控员管理"><a href="#操控员管理" class="headerlink" title="操控员管理"></a>操控员管理</h2><h3 id="操控民用无人驾驶航空器飞行的人员是否需要去的相关执照？"><a href="#操控民用无人驾驶航空器飞行的人员是否需要去的相关执照？" class="headerlink" title="操控民用无人驾驶航空器飞行的人员是否需要去的相关执照？"></a>操控民用无人驾驶航空器飞行的人员是否需要去的相关执照？</h3><h4 id="操控微型，轻型民用无人驾驶航空器飞行的人员，无需去的操控园执照，但应当熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度。"><a href="#操控微型，轻型民用无人驾驶航空器飞行的人员，无需去的操控园执照，但应当熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度。" class="headerlink" title="操控微型，轻型民用无人驾驶航空器飞行的人员，无需去的操控园执照，但应当熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度。"></a>操控微型，轻型民用无人驾驶航空器飞行的人员，无需去的操控园执照，但应当熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度。</h4><h4 id="操控小型，中型，大型民用无人驾驶航空器飞行的人员吗，应当取得局方规定的相关有效操控园执照，并且在行使响应权利时随身携带该执照。"><a href="#操控小型，中型，大型民用无人驾驶航空器飞行的人员吗，应当取得局方规定的相关有效操控园执照，并且在行使响应权利时随身携带该执照。" class="headerlink" title="操控小型，中型，大型民用无人驾驶航空器飞行的人员吗，应当取得局方规定的相关有效操控园执照，并且在行使响应权利时随身携带该执照。"></a>操控小型，中型，大型民用无人驾驶航空器飞行的人员吗，应当取得局方规定的相关有效操控园执照，并且在行使响应权利时随身携带该执照。</h4><h4 id="从事常规农用无人驾驶航空器作业飞行活动的人员无需取得操控园执照，但应当有农用无人驾驶航空器系统生产者按照民航局，农业农村部规定的内容进行培训和考核，合格后取得操作证书。"><a href="#从事常规农用无人驾驶航空器作业飞行活动的人员无需取得操控园执照，但应当有农用无人驾驶航空器系统生产者按照民航局，农业农村部规定的内容进行培训和考核，合格后取得操作证书。" class="headerlink" title="从事常规农用无人驾驶航空器作业飞行活动的人员无需取得操控园执照，但应当有农用无人驾驶航空器系统生产者按照民航局，农业农村部规定的内容进行培训和考核，合格后取得操作证书。"></a>从事常规农用无人驾驶航空器作业飞行活动的人员无需取得操控园执照，但应当有农用无人驾驶航空器系统生产者按照民航局，农业农村部规定的内容进行培训和考核，合格后取得操作证书。</h4><h3 id="无民事行为能力人是否可以操控民用无人驾驶航空器？"><a href="#无民事行为能力人是否可以操控民用无人驾驶航空器？" class="headerlink" title="无民事行为能力人是否可以操控民用无人驾驶航空器？"></a>无民事行为能力人是否可以操控民用无人驾驶航空器？</h3><h4 id="无民事行为能力人只能操控微型民用无人驾驶航空器飞行，限制民事行为能力人只能操控微型，轻型民用无人驾驶航空器飞行。无民事行为能力人操控微型民用无人驾驶航空器飞行或者限制民事行为能力人操控轻型民用无人驾驶航空器飞行，应当由熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度的完全民事行为能力人现场指导。"><a href="#无民事行为能力人只能操控微型民用无人驾驶航空器飞行，限制民事行为能力人只能操控微型，轻型民用无人驾驶航空器飞行。无民事行为能力人操控微型民用无人驾驶航空器飞行或者限制民事行为能力人操控轻型民用无人驾驶航空器飞行，应当由熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度的完全民事行为能力人现场指导。" class="headerlink" title="无民事行为能力人只能操控微型民用无人驾驶航空器飞行，限制民事行为能力人只能操控微型，轻型民用无人驾驶航空器飞行。无民事行为能力人操控微型民用无人驾驶航空器飞行或者限制民事行为能力人操控轻型民用无人驾驶航空器飞行，应当由熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度的完全民事行为能力人现场指导。"></a>无民事行为能力人只能操控微型民用无人驾驶航空器飞行，限制民事行为能力人只能操控微型，轻型民用无人驾驶航空器飞行。无民事行为能力人操控微型民用无人驾驶航空器飞行或者限制民事行为能力人操控轻型民用无人驾驶航空器飞行，应当由熟练掌握有关畸形操作方法，了解风险警示信息和有关管理制度的完全民事行为能力人现场指导。</h4><h3 id="什么情况下，无人驾驶航空器操控园需要购买责任保险？"><a href="#什么情况下，无人驾驶航空器操控园需要购买责任保险？" class="headerlink" title="什么情况下，无人驾驶航空器操控园需要购买责任保险？"></a>什么情况下，无人驾驶航空器操控园需要购买责任保险？</h3><h4 id="使用民用无人驾驶航空器从事经营性飞行活动，以及使用小型，中型，大型民用无人驾驶航空器从事非经营性飞行活动，应当依法投保责任保险。"><a href="#使用民用无人驾驶航空器从事经营性飞行活动，以及使用小型，中型，大型民用无人驾驶航空器从事非经营性飞行活动，应当依法投保责任保险。" class="headerlink" title="使用民用无人驾驶航空器从事经营性飞行活动，以及使用小型，中型，大型民用无人驾驶航空器从事非经营性飞行活动，应当依法投保责任保险。"></a>使用民用无人驾驶航空器从事经营性飞行活动，以及使用小型，中型，大型民用无人驾驶航空器从事非经营性飞行活动，应当依法投保责任保险。</h4><h3 id="登记管理具体有哪些要求？"><a href="#登记管理具体有哪些要求？" class="headerlink" title="登记管理具体有哪些要求？"></a>登记管理具体有哪些要求？</h3><h4 id="1-民用无人驾驶航空器登记管理包括实名登记和国籍登记，"><a href="#1-民用无人驾驶航空器登记管理包括实名登记和国籍登记，" class="headerlink" title="1.民用无人驾驶航空器登记管理包括实名登记和国籍登记，"></a>1.民用无人驾驶航空器登记管理包括实名登记和国籍登记，</h4><h4 id="2-在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当按照规定进行实名登记，"><a href="#2-在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当按照规定进行实名登记，" class="headerlink" title="2.在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当按照规定进行实名登记，"></a>2.在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当按照规定进行实名登记，</h4><h4 id="3-从事境外飞行的民用无人驾驶航空器，应当完成国籍登记，具有国籍表示和登记标志，"><a href="#3-从事境外飞行的民用无人驾驶航空器，应当完成国籍登记，具有国籍表示和登记标志，" class="headerlink" title="3.从事境外飞行的民用无人驾驶航空器，应当完成国籍登记，具有国籍表示和登记标志，"></a>3.从事境外飞行的民用无人驾驶航空器，应当完成国籍登记，具有国籍表示和登记标志，</h4><h4 id="4-民用无人驾驶航空器不得具有双重国籍，未注销外国国籍的民用无人驾驶航空器不得在中华人民共和国申请国籍登记，未注销中华人民共和国国籍的民用无人驾驶航空器，不得在外国办理国籍登记。"><a href="#4-民用无人驾驶航空器不得具有双重国籍，未注销外国国籍的民用无人驾驶航空器不得在中华人民共和国申请国籍登记，未注销中华人民共和国国籍的民用无人驾驶航空器，不得在外国办理国籍登记。" class="headerlink" title="4.民用无人驾驶航空器不得具有双重国籍，未注销外国国籍的民用无人驾驶航空器不得在中华人民共和国申请国籍登记，未注销中华人民共和国国籍的民用无人驾驶航空器，不得在外国办理国籍登记。"></a>4.民用无人驾驶航空器不得具有双重国籍，未注销外国国籍的民用无人驾驶航空器不得在中华人民共和国申请国籍登记，未注销中华人民共和国国籍的民用无人驾驶航空器，不得在外国办理国籍登记。</h4><h3 id="操控民用无人驾驶航空器，是否需要实名登记？"><a href="#操控民用无人驾驶航空器，是否需要实名登记？" class="headerlink" title="操控民用无人驾驶航空器，是否需要实名登记？"></a>操控民用无人驾驶航空器，是否需要实名登记？</h3><h4 id="在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当依照规定进行实名登记。"><a href="#在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当依照规定进行实名登记。" class="headerlink" title="在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当依照规定进行实名登记。"></a>在中华人民共和国境内从事飞行以及有关活动的民用无人驾驶航空器，应当依照规定进行实名登记。</h4><h3 id="实名登记需要提供哪些信息？"><a href="#实名登记需要提供哪些信息？" class="headerlink" title="实名登记需要提供哪些信息？"></a>实名登记需要提供哪些信息？</h3><h4 id="民用无人驾驶航空器实名登记信息应当包括以下内容：1-所有人合法身份的信息，2-所有人的联系信息，3-民用无人驾驶航空器的信息，4-民用无人驾驶航空器的使用用途。"><a href="#民用无人驾驶航空器实名登记信息应当包括以下内容：1-所有人合法身份的信息，2-所有人的联系信息，3-民用无人驾驶航空器的信息，4-民用无人驾驶航空器的使用用途。" class="headerlink" title="民用无人驾驶航空器实名登记信息应当包括以下内容：1.所有人合法身份的信息，2.所有人的联系信息，3.民用无人驾驶航空器的信息，4.民用无人驾驶航空器的使用用途。"></a>民用无人驾驶航空器实名登记信息应当包括以下内容：1.所有人合法身份的信息，2.所有人的联系信息，3.民用无人驾驶航空器的信息，4.民用无人驾驶航空器的使用用途。</h4><h3 id="哪些情况下，应当申请注销登记？"><a href="#哪些情况下，应当申请注销登记？" class="headerlink" title="哪些情况下，应当申请注销登记？"></a>哪些情况下，应当申请注销登记？</h3><h4 id="取得实名登记的民用无人驾驶航空器，遇有下列情形之一，应当申请注销登记：1-民用无人驾驶航空器所有权或者占有权发生变更，2-民用无人驾驶航空器推出使用，报废或失事，3-民用无人驾驶航空器所有权依法转移至境外并已办理出口适航证的。"><a href="#取得实名登记的民用无人驾驶航空器，遇有下列情形之一，应当申请注销登记：1-民用无人驾驶航空器所有权或者占有权发生变更，2-民用无人驾驶航空器推出使用，报废或失事，3-民用无人驾驶航空器所有权依法转移至境外并已办理出口适航证的。" class="headerlink" title="取得实名登记的民用无人驾驶航空器，遇有下列情形之一，应当申请注销登记：1.民用无人驾驶航空器所有权或者占有权发生变更，2.民用无人驾驶航空器推出使用，报废或失事，3.民用无人驾驶航空器所有权依法转移至境外并已办理出口适航证的。"></a>取得实名登记的民用无人驾驶航空器，遇有下列情形之一，应当申请注销登记：1.民用无人驾驶航空器所有权或者占有权发生变更，2.民用无人驾驶航空器推出使用，报废或失事，3.民用无人驾驶航空器所有权依法转移至境外并已办理出口适航证的。</h4><h3 id="管制空域和适飞空域"><a href="#管制空域和适飞空域" class="headerlink" title="管制空域和适飞空域"></a>管制空域和适飞空域</h3><h4 id="民用无人驾驶航空器空域氛围民用无人驾驶航空器管制空域和微型小型，轻型民用无人驾驶航空器适飞空域。"><a href="#民用无人驾驶航空器空域氛围民用无人驾驶航空器管制空域和微型小型，轻型民用无人驾驶航空器适飞空域。" class="headerlink" title="民用无人驾驶航空器空域氛围民用无人驾驶航空器管制空域和微型小型，轻型民用无人驾驶航空器适飞空域。"></a>民用无人驾驶航空器空域氛围民用无人驾驶航空器管制空域和微型小型，轻型民用无人驾驶航空器适飞空域。</h4><h3 id="什么是管制空域？"><a href="#什么是管制空域？" class="headerlink" title="什么是管制空域？"></a>什么是管制空域？</h3><h4 id="真高120m以上空域，空中禁区，空中限制区以及周边空域，军用航空抄底空中飞行空域，以及下列区域上方的空域应当划设为管制空域：1-机场以及周边一定范围内的区域，2-国界线，实际控制线，边境线向我方一侧一定范围内的区域，3-军事禁区，军事管理区，监管场所等涉密单位以及周边一定范围的区域，4-重要军工设施保护区域，核设施控制区域，易燃易爆等危险品的生产和仓储区域，以及可燃重要物资的大型仓储区域，5-发电厂，变电站，加油（气）站，供水厂，公共交通枢纽，航电枢纽，重大水利设施，港口，高速公路，铁路电气化线路等公共设施以及周边一定范围内的区域和饮用水水源保护区，6-射电天文台，微型测控（导航）站，航空无线电导航台，雷达站等需要电磁环境特殊保护的设施以及周边一定范围的区域，7-重要革命纪念地，重要不可以动文物以及周边一定范围的区域，8-国家空中交通管理领导机构规定的其他区域。"><a href="#真高120m以上空域，空中禁区，空中限制区以及周边空域，军用航空抄底空中飞行空域，以及下列区域上方的空域应当划设为管制空域：1-机场以及周边一定范围内的区域，2-国界线，实际控制线，边境线向我方一侧一定范围内的区域，3-军事禁区，军事管理区，监管场所等涉密单位以及周边一定范围的区域，4-重要军工设施保护区域，核设施控制区域，易燃易爆等危险品的生产和仓储区域，以及可燃重要物资的大型仓储区域，5-发电厂，变电站，加油（气）站，供水厂，公共交通枢纽，航电枢纽，重大水利设施，港口，高速公路，铁路电气化线路等公共设施以及周边一定范围内的区域和饮用水水源保护区，6-射电天文台，微型测控（导航）站，航空无线电导航台，雷达站等需要电磁环境特殊保护的设施以及周边一定范围的区域，7-重要革命纪念地，重要不可以动文物以及周边一定范围的区域，8-国家空中交通管理领导机构规定的其他区域。" class="headerlink" title="真高120m以上空域，空中禁区，空中限制区以及周边空域，军用航空抄底空中飞行空域，以及下列区域上方的空域应当划设为管制空域：1.机场以及周边一定范围内的区域，2.国界线，实际控制线，边境线向我方一侧一定范围内的区域，3.军事禁区，军事管理区，监管场所等涉密单位以及周边一定范围的区域，4.重要军工设施保护区域，核设施控制区域，易燃易爆等危险品的生产和仓储区域，以及可燃重要物资的大型仓储区域，5.发电厂，变电站，加油（气）站，供水厂，公共交通枢纽，航电枢纽，重大水利设施，港口，高速公路，铁路电气化线路等公共设施以及周边一定范围内的区域和饮用水水源保护区，6.射电天文台，微型测控（导航）站，航空无线电导航台，雷达站等需要电磁环境特殊保护的设施以及周边一定范围的区域，7.重要革命纪念地，重要不可以动文物以及周边一定范围的区域，8.国家空中交通管理领导机构规定的其他区域。"></a>真高120m以上空域，空中禁区，空中限制区以及周边空域，军用航空抄底空中飞行空域，以及下列区域上方的空域应当划设为管制空域：1.机场以及周边一定范围内的区域，2.国界线，实际控制线，边境线向我方一侧一定范围内的区域，3.军事禁区，军事管理区，监管场所等涉密单位以及周边一定范围的区域，4.重要军工设施保护区域，核设施控制区域，易燃易爆等危险品的生产和仓储区域，以及可燃重要物资的大型仓储区域，5.发电厂，变电站，加油（气）站，供水厂，公共交通枢纽，航电枢纽，重大水利设施，港口，高速公路，铁路电气化线路等公共设施以及周边一定范围内的区域和饮用水水源保护区，6.射电天文台，微型测控（导航）站，航空无线电导航台，雷达站等需要电磁环境特殊保护的设施以及周边一定范围的区域，7.重要革命纪念地，重要不可以动文物以及周边一定范围的区域，8.国家空中交通管理领导机构规定的其他区域。</h4><h3 id="什么是管制空域？-1"><a href="#什么是管制空域？-1" class="headerlink" title="什么是管制空域？"></a>什么是管制空域？</h3><h4 id="管制空域的具体范围由各级空中交通管理机构按照国家空中交通管理领导机构的规定确定，由设区的市级以上人民政府公布，民用航空管理部门和承担相应责任的单位发布航行情报。"><a href="#管制空域的具体范围由各级空中交通管理机构按照国家空中交通管理领导机构的规定确定，由设区的市级以上人民政府公布，民用航空管理部门和承担相应责任的单位发布航行情报。" class="headerlink" title="管制空域的具体范围由各级空中交通管理机构按照国家空中交通管理领导机构的规定确定，由设区的市级以上人民政府公布，民用航空管理部门和承担相应责任的单位发布航行情报。"></a>管制空域的具体范围由各级空中交通管理机构按照国家空中交通管理领导机构的规定确定，由设区的市级以上人民政府公布，民用航空管理部门和承担相应责任的单位发布航行情报。</h4><h3 id="什么是适飞空域？"><a href="#什么是适飞空域？" class="headerlink" title="什么是适飞空域？"></a>什么是适飞空域？</h3><h4 id="管制空域范围以外的空域为微型，轻型，小型无人驾驶航空器的适飞空域。在适飞空域内飞行不需要向空中交通管理机构申请，但需留意当地管理部门的临时性管控，如大型活动，人员密集的景点发布的管理公告等，建议提前向当地了解。"><a href="#管制空域范围以外的空域为微型，轻型，小型无人驾驶航空器的适飞空域。在适飞空域内飞行不需要向空中交通管理机构申请，但需留意当地管理部门的临时性管控，如大型活动，人员密集的景点发布的管理公告等，建议提前向当地了解。" class="headerlink" title="管制空域范围以外的空域为微型，轻型，小型无人驾驶航空器的适飞空域。在适飞空域内飞行不需要向空中交通管理机构申请，但需留意当地管理部门的临时性管控，如大型活动，人员密集的景点发布的管理公告等，建议提前向当地了解。"></a>管制空域范围以外的空域为微型，轻型，小型无人驾驶航空器的适飞空域。在适飞空域内飞行不需要向空中交通管理机构申请，但需留意当地管理部门的临时性管控，如大型活动，人员密集的景点发布的管理公告等，建议提前向当地了解。</h4><h3 id="什么是真高？"><a href="#什么是真高？" class="headerlink" title="什么是真高？"></a>什么是真高？</h3><h4 id="飞行真高：是指民用无人驾驶航空器的飞行高度与其地面投影的实时距离。【此处有图】"><a href="#飞行真高：是指民用无人驾驶航空器的飞行高度与其地面投影的实时距离。【此处有图】" class="headerlink" title="飞行真高：是指民用无人驾驶航空器的飞行高度与其地面投影的实时距离。【此处有图】"></a>飞行真高：是指民用无人驾驶航空器的飞行高度与其地面投影的实时距离。【此处有图】</h4><h3 id="若在管制空域飞行，如何进行飞行活动申请？"><a href="#若在管制空域飞行，如何进行飞行活动申请？" class="headerlink" title="若在管制空域飞行，如何进行飞行活动申请？"></a>若在管制空域飞行，如何进行飞行活动申请？</h3><h4 id="组织无人驾驶航空器飞行活动的单位或者个人应当在拟飞行前12点向空中交通管理机构（UOM平台）提出飞行活动申请，空中交通管理机构应当在飞行前1日21点作出批准或不予批准。未经空中交通管理机构批准，不得在管制空域内实施无人驾驶航空器飞行作业。"><a href="#组织无人驾驶航空器飞行活动的单位或者个人应当在拟飞行前12点向空中交通管理机构（UOM平台）提出飞行活动申请，空中交通管理机构应当在飞行前1日21点作出批准或不予批准。未经空中交通管理机构批准，不得在管制空域内实施无人驾驶航空器飞行作业。" class="headerlink" title="组织无人驾驶航空器飞行活动的单位或者个人应当在拟飞行前12点向空中交通管理机构（UOM平台）提出飞行活动申请，空中交通管理机构应当在飞行前1日21点作出批准或不予批准。未经空中交通管理机构批准，不得在管制空域内实施无人驾驶航空器飞行作业。"></a>组织无人驾驶航空器飞行活动的单位或者个人应当在拟飞行前12点向空中交通管理机构（UOM平台）提出飞行活动申请，空中交通管理机构应当在飞行前1日21点作出批准或不予批准。未经空中交通管理机构批准，不得在管制空域内实施无人驾驶航空器飞行作业。</h4><h4 id="按照国家空中交通管理机构的规定在固定空域内实施常态飞行活动的，可以提出长期飞行活动申请，经批准后实施，并应当在拟飞行前1日12点之前将飞行计划报空中交通管理机构备案。"><a href="#按照国家空中交通管理机构的规定在固定空域内实施常态飞行活动的，可以提出长期飞行活动申请，经批准后实施，并应当在拟飞行前1日12点之前将飞行计划报空中交通管理机构备案。" class="headerlink" title="按照国家空中交通管理机构的规定在固定空域内实施常态飞行活动的，可以提出长期飞行活动申请，经批准后实施，并应当在拟飞行前1日12点之前将飞行计划报空中交通管理机构备案。"></a>按照国家空中交通管理机构的规定在固定空域内实施常态飞行活动的，可以提出长期飞行活动申请，经批准后实施，并应当在拟飞行前1日12点之前将飞行计划报空中交通管理机构备案。</h4><h4 id="微型轻型小型无人驾驶航空器在适飞空域内的飞行活动，无需向空中交通管理机构提出飞行活动申请。"><a href="#微型轻型小型无人驾驶航空器在适飞空域内的飞行活动，无需向空中交通管理机构提出飞行活动申请。" class="headerlink" title="微型轻型小型无人驾驶航空器在适飞空域内的飞行活动，无需向空中交通管理机构提出飞行活动申请。"></a>微型轻型小型无人驾驶航空器在适飞空域内的飞行活动，无需向空中交通管理机构提出飞行活动申请。</h4><h3 id="隔离飞行和融合飞行"><a href="#隔离飞行和融合飞行" class="headerlink" title="隔离飞行和融合飞行"></a>隔离飞行和融合飞行</h3><h4 id="隔离飞行，是指无人驾驶航空器与有人驾驶航空器不同时在同一空域内的飞行。"><a href="#隔离飞行，是指无人驾驶航空器与有人驾驶航空器不同时在同一空域内的飞行。" class="headerlink" title="隔离飞行，是指无人驾驶航空器与有人驾驶航空器不同时在同一空域内的飞行。"></a>隔离飞行，是指无人驾驶航空器与有人驾驶航空器不同时在同一空域内的飞行。</h4><h4 id="融合飞行，是指无人驾驶航空器与有人驾驶航空器同时在同一空域内的飞行。"><a href="#融合飞行，是指无人驾驶航空器与有人驾驶航空器同时在同一空域内的飞行。" class="headerlink" title="融合飞行，是指无人驾驶航空器与有人驾驶航空器同时在同一空域内的飞行。"></a>融合飞行，是指无人驾驶航空器与有人驾驶航空器同时在同一空域内的飞行。</h4><h3 id="那些情况下，无人驾驶航空器可以与有人驾驶航空器融合飞行？"><a href="#那些情况下，无人驾驶航空器可以与有人驾驶航空器融合飞行？" class="headerlink" title="那些情况下，无人驾驶航空器可以与有人驾驶航空器融合飞行？"></a>那些情况下，无人驾驶航空器可以与有人驾驶航空器融合飞行？</h3><h4 id="无人驾驶航空器通常应当与有人驾驶航空器隔离飞行。"><a href="#无人驾驶航空器通常应当与有人驾驶航空器隔离飞行。" class="headerlink" title="无人驾驶航空器通常应当与有人驾驶航空器隔离飞行。"></a>无人驾驶航空器通常应当与有人驾驶航空器隔离飞行。</h4><h4 id="属于下列情形之一的，经空中交通管机构批准，可以进行融合飞行："><a href="#属于下列情形之一的，经空中交通管机构批准，可以进行融合飞行：" class="headerlink" title="属于下列情形之一的，经空中交通管机构批准，可以进行融合飞行："></a>属于下列情形之一的，经空中交通管机构批准，可以进行融合飞行：</h4><h4 id="1-根据任务或者飞行课目需要，警察，海关，应急管理部门辖有的无人驾驶航空器与本部门，本单位使用的有人驾驶航空器在同一空域或者同一机场区域的飞行，2-取得适航许可的大型无人驾驶航空器的飞行，3-取得适航许可的中型无人驾驶航空器不超过真高300m的飞行，4-小型无人驾驶航空器不超过真高300m的飞行，5-轻型无人驾驶航空器在适飞空域上方不超过真高300m的飞行。"><a href="#1-根据任务或者飞行课目需要，警察，海关，应急管理部门辖有的无人驾驶航空器与本部门，本单位使用的有人驾驶航空器在同一空域或者同一机场区域的飞行，2-取得适航许可的大型无人驾驶航空器的飞行，3-取得适航许可的中型无人驾驶航空器不超过真高300m的飞行，4-小型无人驾驶航空器不超过真高300m的飞行，5-轻型无人驾驶航空器在适飞空域上方不超过真高300m的飞行。" class="headerlink" title="1.根据任务或者飞行课目需要，警察，海关，应急管理部门辖有的无人驾驶航空器与本部门，本单位使用的有人驾驶航空器在同一空域或者同一机场区域的飞行，2.取得适航许可的大型无人驾驶航空器的飞行，3.取得适航许可的中型无人驾驶航空器不超过真高300m的飞行，4.小型无人驾驶航空器不超过真高300m的飞行，5.轻型无人驾驶航空器在适飞空域上方不超过真高300m的飞行。"></a>1.根据任务或者飞行课目需要，警察，海关，应急管理部门辖有的无人驾驶航空器与本部门，本单位使用的有人驾驶航空器在同一空域或者同一机场区域的飞行，2.取得适航许可的大型无人驾驶航空器的飞行，3.取得适航许可的中型无人驾驶航空器不超过真高300m的飞行，4.小型无人驾驶航空器不超过真高300m的飞行，5.轻型无人驾驶航空器在适飞空域上方不超过真高300m的飞行。</h4><h1 id="空域和飞行活动管理"><a href="#空域和飞行活动管理" class="headerlink" title="空域和飞行活动管理"></a>空域和飞行活动管理</h1><h3 id="微型，轻型无人驾驶航空器在适飞空域内进行融合飞行，是否需要经过空中交通管理机构批准？"><a href="#微型，轻型无人驾驶航空器在适飞空域内进行融合飞行，是否需要经过空中交通管理机构批准？" class="headerlink" title="微型，轻型无人驾驶航空器在适飞空域内进行融合飞行，是否需要经过空中交通管理机构批准？"></a>微型，轻型无人驾驶航空器在适飞空域内进行融合飞行，是否需要经过空中交通管理机构批准？</h3><h4 id="不需要"><a href="#不需要" class="headerlink" title="不需要"></a>不需要</h4><h3 id="什么是电子围栏？"><a href="#什么是电子围栏？" class="headerlink" title="什么是电子围栏？"></a>什么是电子围栏？</h3><h4 id="电子围栏，是指为防止民用无人驾驶航空器飞入或者飞出特定区域，在相应电子地理范围中画出其区域边界，并配合飞行控制系统，保障区域安全的软硬件系统。"><a href="#电子围栏，是指为防止民用无人驾驶航空器飞入或者飞出特定区域，在相应电子地理范围中画出其区域边界，并配合飞行控制系统，保障区域安全的软硬件系统。" class="headerlink" title="电子围栏，是指为防止民用无人驾驶航空器飞入或者飞出特定区域，在相应电子地理范围中画出其区域边界，并配合飞行控制系统，保障区域安全的软硬件系统。"></a>电子围栏，是指为防止民用无人驾驶航空器飞入或者飞出特定区域，在相应电子地理范围中画出其区域边界，并配合飞行控制系统，保障区域安全的软硬件系统。</h4><h3 id="那些民用无人驾驶航空器应当安装并使用无人驾驶航空器电子围栏？"><a href="#那些民用无人驾驶航空器应当安装并使用无人驾驶航空器电子围栏？" class="headerlink" title="那些民用无人驾驶航空器应当安装并使用无人驾驶航空器电子围栏？"></a>那些民用无人驾驶航空器应当安装并使用无人驾驶航空器电子围栏？</h3><h4 id="1-小型，中型和大型民用无人驾驶航空器，2-在重点地区和机场净空区以下运行的轻型无人驾驶航空器。"><a href="#1-小型，中型和大型民用无人驾驶航空器，2-在重点地区和机场净空区以下运行的轻型无人驾驶航空器。" class="headerlink" title="1.小型，中型和大型民用无人驾驶航空器，2.在重点地区和机场净空区以下运行的轻型无人驾驶航空器。"></a>1.小型，中型和大型民用无人驾驶航空器，2.在重点地区和机场净空区以下运行的轻型无人驾驶航空器。</h4><h3 id="什么是空域保持能力？"><a href="#什么是空域保持能力？" class="headerlink" title="什么是空域保持能力？"></a>什么是空域保持能力？</h3><h4 id="空域保持能力，是指通过电子围栏登记书措施控制无人驾驶航空器的高度与水平范围的能力。"><a href="#空域保持能力，是指通过电子围栏登记书措施控制无人驾驶航空器的高度与水平范围的能力。" class="headerlink" title="空域保持能力，是指通过电子围栏登记书措施控制无人驾驶航空器的高度与水平范围的能力。"></a>空域保持能力，是指通过电子围栏登记书措施控制无人驾驶航空器的高度与水平范围的能力。</h4><h3 id="操控无人驾驶航空器实施飞行活动，应该遵守那些行为规范？"><a href="#操控无人驾驶航空器实施飞行活动，应该遵守那些行为规范？" class="headerlink" title="操控无人驾驶航空器实施飞行活动，应该遵守那些行为规范？"></a>操控无人驾驶航空器实施飞行活动，应该遵守那些行为规范？</h3><h4 id="1-依法取得有关许可证书，证件，并在实施飞行活动时随身携带备查，"><a href="#1-依法取得有关许可证书，证件，并在实施飞行活动时随身携带备查，" class="headerlink" title="1.依法取得有关许可证书，证件，并在实施飞行活动时随身携带备查，"></a>1.依法取得有关许可证书，证件，并在实施飞行活动时随身携带备查，</h4><h4 id="2-实施飞行活动前做好安全飞行准备，检查无人驾驶航空器状态，并及时更新电子围栏等信息；"><a href="#2-实施飞行活动前做好安全飞行准备，检查无人驾驶航空器状态，并及时更新电子围栏等信息；" class="headerlink" title="2.实施飞行活动前做好安全飞行准备，检查无人驾驶航空器状态，并及时更新电子围栏等信息；"></a>2.实施飞行活动前做好安全飞行准备，检查无人驾驶航空器状态，并及时更新电子围栏等信息；</h4><h4 id="3-实时掌握无人驾驶航空器飞行动态，实施需经批准的飞行活动应当与空中交通管理机构保持通信联络畅通，服从空中交通管理，飞行结束后及时报告；"><a href="#3-实时掌握无人驾驶航空器飞行动态，实施需经批准的飞行活动应当与空中交通管理机构保持通信联络畅通，服从空中交通管理，飞行结束后及时报告；" class="headerlink" title="3.实时掌握无人驾驶航空器飞行动态，实施需经批准的飞行活动应当与空中交通管理机构保持通信联络畅通，服从空中交通管理，飞行结束后及时报告；"></a>3.实时掌握无人驾驶航空器飞行动态，实施需经批准的飞行活动应当与空中交通管理机构保持通信联络畅通，服从空中交通管理，飞行结束后及时报告；</h4><h4 id="4-按照国家空中交通管理领导机构的规定保持必要的安全间隔；"><a href="#4-按照国家空中交通管理领导机构的规定保持必要的安全间隔；" class="headerlink" title="4.按照国家空中交通管理领导机构的规定保持必要的安全间隔；"></a>4.按照国家空中交通管理领导机构的规定保持必要的安全间隔；</h4><h4 id="5-操控微型无人驾驶航空器的，应当保持视距内飞行；"><a href="#5-操控微型无人驾驶航空器的，应当保持视距内飞行；" class="headerlink" title="5.操控微型无人驾驶航空器的，应当保持视距内飞行；"></a>5.操控微型无人驾驶航空器的，应当保持视距内飞行；</h4><h4 id="6-操控小型无人驾驶航空器在适飞空域内飞行的，应当遵守国家空中交通管理领导机构关于限速，通信，导航等方面的规定；"><a href="#6-操控小型无人驾驶航空器在适飞空域内飞行的，应当遵守国家空中交通管理领导机构关于限速，通信，导航等方面的规定；" class="headerlink" title="6.操控小型无人驾驶航空器在适飞空域内飞行的，应当遵守国家空中交通管理领导机构关于限速，通信，导航等方面的规定；"></a>6.操控小型无人驾驶航空器在适飞空域内飞行的，应当遵守国家空中交通管理领导机构关于限速，通信，导航等方面的规定；</h4><h4 id="7-在夜间或者低能见度气象条件下飞行的，应当开启灯光系统并确保其处于良好工作状态；"><a href="#7-在夜间或者低能见度气象条件下飞行的，应当开启灯光系统并确保其处于良好工作状态；" class="headerlink" title="7.在夜间或者低能见度气象条件下飞行的，应当开启灯光系统并确保其处于良好工作状态；"></a>7.在夜间或者低能见度气象条件下飞行的，应当开启灯光系统并确保其处于良好工作状态；</h4><h4 id="8-实施超视距飞行的，应当掌握飞行空域内其他航空器的飞行动态，采取避免相撞的措施；"><a href="#8-实施超视距飞行的，应当掌握飞行空域内其他航空器的飞行动态，采取避免相撞的措施；" class="headerlink" title="8.实施超视距飞行的，应当掌握飞行空域内其他航空器的飞行动态，采取避免相撞的措施；"></a>8.实施超视距飞行的，应当掌握飞行空域内其他航空器的飞行动态，采取避免相撞的措施；</h4><h4 id="9-受到酒精类饮料，麻醉剂或者其他药物影响时，不得操控无人驾驶航空器；"><a href="#9-受到酒精类饮料，麻醉剂或者其他药物影响时，不得操控无人驾驶航空器；" class="headerlink" title="9.受到酒精类饮料，麻醉剂或者其他药物影响时，不得操控无人驾驶航空器；"></a>9.受到酒精类饮料，麻醉剂或者其他药物影响时，不得操控无人驾驶航空器；</h4><h4 id="10-国家空中交通管理领导机构规定的其他飞行活动行为规范。"><a href="#10-国家空中交通管理领导机构规定的其他飞行活动行为规范。" class="headerlink" title="10.国家空中交通管理领导机构规定的其他飞行活动行为规范。"></a>10.国家空中交通管理领导机构规定的其他飞行活动行为规范。</h4><h1 id="运行管理"><a href="#运行管理" class="headerlink" title="运行管理"></a>运行管理</h1><h3 id="对于无人驾驶航空器操控园，关于酒精和药物的限制是如何定义的？"><a href="#对于无人驾驶航空器操控园，关于酒精和药物的限制是如何定义的？" class="headerlink" title="对于无人驾驶航空器操控园，关于酒精和药物的限制是如何定义的？"></a>对于无人驾驶航空器操控园，关于酒精和药物的限制是如何定义的？</h3><h4 id="1-操控员在饮用任何含酒精饮料之后的8小时之内或者处在酒精作用之下，血液中酒精含量等于或者大于0-04-，或者收到任何药物影响损及工作能力时，不得淡人民用无人驾驶航空器操控员。"><a href="#1-操控员在饮用任何含酒精饮料之后的8小时之内或者处在酒精作用之下，血液中酒精含量等于或者大于0-04-，或者收到任何药物影响损及工作能力时，不得淡人民用无人驾驶航空器操控员。" class="headerlink" title="1.操控员在饮用任何含酒精饮料之后的8小时之内或者处在酒精作用之下，血液中酒精含量等于或者大于0.04%，或者收到任何药物影响损及工作能力时，不得淡人民用无人驾驶航空器操控员。"></a>1.操控员在饮用任何含酒精饮料之后的8小时之内或者处在酒精作用之下，血液中酒精含量等于或者大于0.04%，或者收到任何药物影响损及工作能力时，不得淡人民用无人驾驶航空器操控员。</h4><h4 id="2-操控员应当按照局方的要求接受酒精或者药物检验或者提供检验结果。"><a href="#2-操控员应当按照局方的要求接受酒精或者药物检验或者提供检验结果。" class="headerlink" title="2.操控员应当按照局方的要求接受酒精或者药物检验或者提供检验结果。"></a>2.操控员应当按照局方的要求接受酒精或者药物检验或者提供检验结果。</h4><h3 id="操控无人驾驶航空器实施飞行活动，应当遵守那些避让规则？"><a href="#操控无人驾驶航空器实施飞行活动，应当遵守那些避让规则？" class="headerlink" title="操控无人驾驶航空器实施飞行活动，应当遵守那些避让规则？"></a>操控无人驾驶航空器实施飞行活动，应当遵守那些避让规则？</h3><h4 id="1-避让有人驾驶航空器，无动力装置的航空器以及地面，水上交通工具；"><a href="#1-避让有人驾驶航空器，无动力装置的航空器以及地面，水上交通工具；" class="headerlink" title="1.避让有人驾驶航空器，无动力装置的航空器以及地面，水上交通工具；"></a>1.避让有人驾驶航空器，无动力装置的航空器以及地面，水上交通工具；</h4><h4 id="2-单架飞行避让集群飞行；"><a href="#2-单架飞行避让集群飞行；" class="headerlink" title="2.单架飞行避让集群飞行；"></a>2.单架飞行避让集群飞行；</h4><h4 id="3-微型无人驾驶航空器避让其他无人驾驶航空器；"><a href="#3-微型无人驾驶航空器避让其他无人驾驶航空器；" class="headerlink" title="3.微型无人驾驶航空器避让其他无人驾驶航空器；"></a>3.微型无人驾驶航空器避让其他无人驾驶航空器；</h4><h4 id="4-民用无人驾驶航空器之间，以及民用无人驾驶航空器与有人驾驶航空器之间应当按照局方要求保持飞行间隔，并遵守相应的避让规则。"><a href="#4-民用无人驾驶航空器之间，以及民用无人驾驶航空器与有人驾驶航空器之间应当按照局方要求保持飞行间隔，并遵守相应的避让规则。" class="headerlink" title="4.民用无人驾驶航空器之间，以及民用无人驾驶航空器与有人驾驶航空器之间应当按照局方要求保持飞行间隔，并遵守相应的避让规则。"></a>4.民用无人驾驶航空器之间，以及民用无人驾驶航空器与有人驾驶航空器之间应当按照局方要求保持飞行间隔，并遵守相应的避让规则。</h4><h1 id="法律责任"><a href="#法律责任" class="headerlink" title="法律责任"></a>法律责任</h1><h3 id="无人驾驶航空器操控园的哪些行为可能会受到处罚？"><a href="#无人驾驶航空器操控园的哪些行为可能会受到处罚？" class="headerlink" title="无人驾驶航空器操控园的哪些行为可能会受到处罚？"></a>无人驾驶航空器操控园的哪些行为可能会受到处罚？</h3><h4 id="1-对已经取得适航许可的民用无人驾驶航空器系统进行重大设计更改，未重新申请取得适航许可并将其用于飞行活动的，由民用航空管理机构责令改正，处无人驾驶航空器系统货值金额1倍以上5倍以下的罚款；"><a href="#1-对已经取得适航许可的民用无人驾驶航空器系统进行重大设计更改，未重新申请取得适航许可并将其用于飞行活动的，由民用航空管理机构责令改正，处无人驾驶航空器系统货值金额1倍以上5倍以下的罚款；" class="headerlink" title="1.对已经取得适航许可的民用无人驾驶航空器系统进行重大设计更改，未重新申请取得适航许可并将其用于飞行活动的，由民用航空管理机构责令改正，处无人驾驶航空器系统货值金额1倍以上5倍以下的罚款；"></a>1.对已经取得适航许可的民用无人驾驶航空器系统进行重大设计更改，未重新申请取得适航许可并将其用于飞行活动的，由民用航空管理机构责令改正，处无人驾驶航空器系统货值金额1倍以上5倍以下的罚款；</h4><h4 id="2-改变微型，小型，轻型民用无人驾驶航空器系统的空域保持能力，可靠被监视能力，速度或者高度与等出场性能以及参数，未及时在无人驾驶航空器一体化总和监督服务平台更新性能，参数信息的，由民用航空管理部门责令改正；拒不改正的，处2000元以上2万元以下罚款；"><a href="#2-改变微型，小型，轻型民用无人驾驶航空器系统的空域保持能力，可靠被监视能力，速度或者高度与等出场性能以及参数，未及时在无人驾驶航空器一体化总和监督服务平台更新性能，参数信息的，由民用航空管理部门责令改正；拒不改正的，处2000元以上2万元以下罚款；" class="headerlink" title="2.改变微型，小型，轻型民用无人驾驶航空器系统的空域保持能力，可靠被监视能力，速度或者高度与等出场性能以及参数，未及时在无人驾驶航空器一体化总和监督服务平台更新性能，参数信息的，由民用航空管理部门责令改正；拒不改正的，处2000元以上2万元以下罚款；"></a>2.改变微型，小型，轻型民用无人驾驶航空器系统的空域保持能力，可靠被监视能力，速度或者高度与等出场性能以及参数，未及时在无人驾驶航空器一体化总和监督服务平台更新性能，参数信息的，由民用航空管理部门责令改正；拒不改正的，处2000元以上2万元以下罚款；</h4><h4 id="3-民用无人驾驶航空器未经实名登记实施飞行活动的，由公安机关责令改正，可以处200元以下的罚款；情节严重的，处2000元以上2万元以下的罚款；"><a href="#3-民用无人驾驶航空器未经实名登记实施飞行活动的，由公安机关责令改正，可以处200元以下的罚款；情节严重的，处2000元以上2万元以下的罚款；" class="headerlink" title="3.民用无人驾驶航空器未经实名登记实施飞行活动的，由公安机关责令改正，可以处200元以下的罚款；情节严重的，处2000元以上2万元以下的罚款；"></a>3.民用无人驾驶航空器未经实名登记实施飞行活动的，由公安机关责令改正，可以处200元以下的罚款；情节严重的，处2000元以上2万元以下的罚款；</h4><h4 id="4-涉及境外飞行的民用无人驾驶航空器未依法进行国籍登记的，由民用航空管理部门责令改正，处1万元以上10万元以下的罚款；"><a href="#4-涉及境外飞行的民用无人驾驶航空器未依法进行国籍登记的，由民用航空管理部门责令改正，处1万元以上10万元以下的罚款；" class="headerlink" title="4.涉及境外飞行的民用无人驾驶航空器未依法进行国籍登记的，由民用航空管理部门责令改正，处1万元以上10万元以下的罚款；"></a>4.涉及境外飞行的民用无人驾驶航空器未依法进行国籍登记的，由民用航空管理部门责令改正，处1万元以上10万元以下的罚款；</h4><h4 id="5-民用无人驾驶航空器未依法投保责任保险的，由民用航空管理部门责令改正，处2000元以上2万元以下罚款，情节严重的，责令从事飞行活动的单位停业整顿直至吊销其运营合格证。"><a href="#5-民用无人驾驶航空器未依法投保责任保险的，由民用航空管理部门责令改正，处2000元以上2万元以下罚款，情节严重的，责令从事飞行活动的单位停业整顿直至吊销其运营合格证。" class="headerlink" title="5.民用无人驾驶航空器未依法投保责任保险的，由民用航空管理部门责令改正，处2000元以上2万元以下罚款，情节严重的，责令从事飞行活动的单位停业整顿直至吊销其运营合格证。"></a>5.民用无人驾驶航空器未依法投保责任保险的，由民用航空管理部门责令改正，处2000元以上2万元以下罚款，情节严重的，责令从事飞行活动的单位停业整顿直至吊销其运营合格证。</h4><h4 id="6-未取得运营合格证或者违反运营合格证的要求实施飞行活动的，由民用航空管理部门责令改正，处5万元以上50万元以下的罚款，情节严重的，责令停业整顿直至吊销其运营合格证；"><a href="#6-未取得运营合格证或者违反运营合格证的要求实施飞行活动的，由民用航空管理部门责令改正，处5万元以上50万元以下的罚款，情节严重的，责令停业整顿直至吊销其运营合格证；" class="headerlink" title="6.未取得运营合格证或者违反运营合格证的要求实施飞行活动的，由民用航空管理部门责令改正，处5万元以上50万元以下的罚款，情节严重的，责令停业整顿直至吊销其运营合格证；"></a>6.未取得运营合格证或者违反运营合格证的要求实施飞行活动的，由民用航空管理部门责令改正，处5万元以上50万元以下的罚款，情节严重的，责令停业整顿直至吊销其运营合格证；</h4><h4 id="7-无民事行为能力人，限制民事行为能力人违反本条例规定操控民用无人驾驶航空器飞行的，由公安机关对其监护人处500元以上5000元以下的罚款，情节严重的，没收实施违法飞行的无人驾驶航空器；"><a href="#7-无民事行为能力人，限制民事行为能力人违反本条例规定操控民用无人驾驶航空器飞行的，由公安机关对其监护人处500元以上5000元以下的罚款，情节严重的，没收实施违法飞行的无人驾驶航空器；" class="headerlink" title="7.无民事行为能力人，限制民事行为能力人违反本条例规定操控民用无人驾驶航空器飞行的，由公安机关对其监护人处500元以上5000元以下的罚款，情节严重的，没收实施违法飞行的无人驾驶航空器；"></a>7.无民事行为能力人，限制民事行为能力人违反本条例规定操控民用无人驾驶航空器飞行的，由公安机关对其监护人处500元以上5000元以下的罚款，情节严重的，没收实施违法飞行的无人驾驶航空器；</h4><h4 id="8-未取得操控员执照操控民用无人驾驶航空器飞行的，由民用航空管理部门处5000元以上5万元以下的罚款，情节严重的，处1万元以上10万元以下的罚款；"><a href="#8-未取得操控员执照操控民用无人驾驶航空器飞行的，由民用航空管理部门处5000元以上5万元以下的罚款，情节严重的，处1万元以上10万元以下的罚款；" class="headerlink" title="8.未取得操控员执照操控民用无人驾驶航空器飞行的，由民用航空管理部门处5000元以上5万元以下的罚款，情节严重的，处1万元以上10万元以下的罚款；"></a>8.未取得操控员执照操控民用无人驾驶航空器飞行的，由民用航空管理部门处5000元以上5万元以下的罚款，情节严重的，处1万元以上10万元以下的罚款；</h4><h4 id="9-超出操控员执照在明范围操控民用无人驾驶航空器飞行的，由民用航空管理部门处2000元以上2万元以下的罚款，并处暂扣操控园执照6个月-12个月，情节严重的，吊销其操控员执照，2年内不受理其操控员执照申请；"><a href="#9-超出操控员执照在明范围操控民用无人驾驶航空器飞行的，由民用航空管理部门处2000元以上2万元以下的罚款，并处暂扣操控园执照6个月-12个月，情节严重的，吊销其操控员执照，2年内不受理其操控员执照申请；" class="headerlink" title="9.超出操控员执照在明范围操控民用无人驾驶航空器飞行的，由民用航空管理部门处2000元以上2万元以下的罚款，并处暂扣操控园执照6个月-12个月，情节严重的，吊销其操控员执照，2年内不受理其操控员执照申请；"></a>9.超出操控员执照在明范围操控民用无人驾驶航空器飞行的，由民用航空管理部门处2000元以上2万元以下的罚款，并处暂扣操控园执照6个月-12个月，情节严重的，吊销其操控员执照，2年内不受理其操控员执照申请；</h4><h4 id="10-外国无人驾驶航空器或者由外国人员操控的无人驾驶航空器在我国境内实施测绘飞行活动的，由县级以上人民政府测绘地理信息主管部门责令停止违法行动，没收违法所得，测绘成果和实施违规飞行的无人驾驶航空器，并处10万元以上50万元以下的罚款，没情节严重的，并处50万元以上100万元以下的罚款，由公安机关，国家安全管理机关按照指责分工决定嫌弃出境或者驱逐出境。"><a href="#10-外国无人驾驶航空器或者由外国人员操控的无人驾驶航空器在我国境内实施测绘飞行活动的，由县级以上人民政府测绘地理信息主管部门责令停止违法行动，没收违法所得，测绘成果和实施违规飞行的无人驾驶航空器，并处10万元以上50万元以下的罚款，没情节严重的，并处50万元以上100万元以下的罚款，由公安机关，国家安全管理机关按照指责分工决定嫌弃出境或者驱逐出境。" class="headerlink" title="10.外国无人驾驶航空器或者由外国人员操控的无人驾驶航空器在我国境内实施测绘飞行活动的，由县级以上人民政府测绘地理信息主管部门责令停止违法行动，没收违法所得，测绘成果和实施违规飞行的无人驾驶航空器，并处10万元以上50万元以下的罚款，没情节严重的，并处50万元以上100万元以下的罚款，由公安机关，国家安全管理机关按照指责分工决定嫌弃出境或者驱逐出境。"></a>10.外国无人驾驶航空器或者由外国人员操控的无人驾驶航空器在我国境内实施测绘飞行活动的，由县级以上人民政府测绘地理信息主管部门责令停止违法行动，没收违法所得，测绘成果和实施违规飞行的无人驾驶航空器，并处10万元以上50万元以下的罚款，没情节严重的，并处50万元以上100万元以下的罚款，由公安机关，国家安全管理机关按照指责分工决定嫌弃出境或者驱逐出境。</h4><h4 id="11-非法拥有，使用无人驾驶航空器反制设备的，由无线电管理机构，公安机关按照指责分工予以没收，可以处5万元以下的罚款，情节严重的，处5万元以上20万元以下的罚款；"><a href="#11-非法拥有，使用无人驾驶航空器反制设备的，由无线电管理机构，公安机关按照指责分工予以没收，可以处5万元以下的罚款，情节严重的，处5万元以上20万元以下的罚款；" class="headerlink" title="11.非法拥有，使用无人驾驶航空器反制设备的，由无线电管理机构，公安机关按照指责分工予以没收，可以处5万元以下的罚款，情节严重的，处5万元以上20万元以下的罚款；"></a>11.非法拥有，使用无人驾驶航空器反制设备的，由无线电管理机构，公安机关按照指责分工予以没收，可以处5万元以下的罚款，情节严重的，处5万元以上20万元以下的罚款；</h4><h4 id="12-未经批准操控微型，轻型，小型民用无人驾驶航空器在管制空域内飞行，或者操控模型航空器在空中交通管理机构划定的空域外飞行，由公安机关责令停止飞行，可以处500元以下的罚款，情节严重的，没收实施违规飞行的无人驾驶航空器，并处1000元以上1万元以下的罚款。"><a href="#12-未经批准操控微型，轻型，小型民用无人驾驶航空器在管制空域内飞行，或者操控模型航空器在空中交通管理机构划定的空域外飞行，由公安机关责令停止飞行，可以处500元以下的罚款，情节严重的，没收实施违规飞行的无人驾驶航空器，并处1000元以上1万元以下的罚款。" class="headerlink" title="12.未经批准操控微型，轻型，小型民用无人驾驶航空器在管制空域内飞行，或者操控模型航空器在空中交通管理机构划定的空域外飞行，由公安机关责令停止飞行，可以处500元以下的罚款，情节严重的，没收实施违规飞行的无人驾驶航空器，并处1000元以上1万元以下的罚款。"></a>12.未经批准操控微型，轻型，小型民用无人驾驶航空器在管制空域内飞行，或者操控模型航空器在空中交通管理机构划定的空域外飞行，由公安机关责令停止飞行，可以处500元以下的罚款，情节严重的，没收实施违规飞行的无人驾驶航空器，并处1000元以上1万元以下的罚款。</h4><h1 id="详细法律责任内容请查看《无人驾驶航空器飞行管理暂行条例》法律责任章节。"><a href="#详细法律责任内容请查看《无人驾驶航空器飞行管理暂行条例》法律责任章节。" class="headerlink" title="详细法律责任内容请查看《无人驾驶航空器飞行管理暂行条例》法律责任章节。"></a>详细法律责任内容请查看《无人驾驶航空器飞行管理暂行条例》法律责任章节。</h1>]]></content>
    
    
    <summary type="html">&lt;p&gt;《轻型民用无人驾驶航空器安全操控》–法规部分&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>callsign aprs password generate</title>
    <link href="https://blog.bh4fwa.com/2024/05/06/10-32-22/"/>
    <id>https://blog.bh4fwa.com/2024/05/06/10-32-22/</id>
    <published>2024-05-06T10:32:22.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>由呼号生成APRS系统密码的程序</p><span id="more"></span><p>原来的开源项目在这里，是PHP的，<a href="http://apps.magicbug.co.uk/passcode/index.php">http://apps.magicbug.co.uk/passcode/index.php</a></p><p>翻了一下代码，php的生成密码的核心代码是这样子的：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">aprspass</span> (<span class="params"><span class="variable">$callsign</span></span>) </span>&#123;</span><br><span class="line"><span class="variable">$stophere</span> = <span class="title function_ invoke__">strpos</span>(<span class="variable">$callsign</span>, <span class="string">&#x27;-&#x27;</span>);</span><br><span class="line"><span class="keyword">if</span> (<span class="variable">$stophere</span>) <span class="variable">$callsign</span> = <span class="title function_ invoke__">substr</span>(<span class="variable">$callsign</span>, <span class="number">0</span>, <span class="variable">$stophere</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable">$realcall</span> = <span class="title function_ invoke__">strtoupper</span>(<span class="title function_ invoke__">substr</span>(<span class="variable">$callsign</span>, <span class="number">0</span>, <span class="number">10</span>));</span><br><span class="line"><span class="comment">// initialize hash</span></span><br><span class="line"><span class="variable">$hash</span> = <span class="number">0x73e2</span>;</span><br><span class="line"><span class="variable">$i</span> = <span class="number">0</span>;</span><br><span class="line"><span class="variable">$len</span> = <span class="title function_ invoke__">strlen</span>(<span class="variable">$realcall</span>);</span><br><span class="line"><span class="comment">// hash callsign two bytes at a time</span></span><br><span class="line"><span class="keyword">while</span> (<span class="variable">$i</span> &lt; <span class="variable">$len</span>) &#123;</span><br><span class="line"><span class="variable">$hash</span> ^= <span class="title function_ invoke__">ord</span>(<span class="title function_ invoke__">substr</span>(<span class="variable">$realcall</span>, <span class="variable">$i</span>, <span class="number">1</span>))&lt;&lt;<span class="number">8</span>;</span><br><span class="line"><span class="variable">$hash</span> ^= <span class="title function_ invoke__">ord</span>(<span class="title function_ invoke__">substr</span>(<span class="variable">$realcall</span>, <span class="variable">$i</span> + <span class="number">1</span>, <span class="number">1</span>));</span><br><span class="line"><span class="keyword">print</span>(<span class="string">&#x27;hash:&#x27;</span>. <span class="variable">$i</span> . <span class="string">&#x27; &#x27;</span> . <span class="variable">$hash</span>);</span><br><span class="line"><span class="variable">$i</span> += <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// mask off the high bit so number is always positive</span></span><br><span class="line"><span class="keyword">return</span> <span class="variable">$hash</span> &amp; <span class="number">0x7fff</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">print</span>(<span class="title function_ invoke__">aprspass</span>(<span class="string">&#x27;BH4FWA-1&#x27;</span>));</span><br></pre></td></tr></table></figure><p>大概的原理是，将原本的 输入的呼号内容，将 - 去掉，取前面一部分，然后再将其遍历，偶数位的 拿到 ascii码，左移8，奇数位的不变，并且与一个base bash不断异或，<br>最终返回 pass-code。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;由呼号生成APRS系统密码的程序&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Go语言访问IPFS分布式文件客户端的API-未完待续</title>
    <link href="https://blog.bh4fwa.com/2024/05/06/10-27-36/"/>
    <id>https://blog.bh4fwa.com/2024/05/06/10-27-36/</id>
    <published>2024-05-06T10:27:36.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>作为备份，存储一下，</p><span id="more"></span><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">&quot;context&quot;</span></span><br><span class="line"><span class="string">&quot;fmt&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/ipfs/boxo/files&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/ipfs/boxo/path&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/ipfs/kubo/client/rpc&quot;</span></span><br><span class="line">ma <span class="string">&quot;github.com/multiformats/go-multiaddr&quot;</span></span><br><span class="line"><span class="string">&quot;net/http&quot;</span></span><br><span class="line"><span class="string">&quot;os&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line"><span class="comment">// &quot;Connect&quot; to local node</span></span><br><span class="line">address, err := ma.NewMultiaddr(<span class="string">&quot;/ip4/192.168.123.6/tcp/4001&quot;</span>)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">node, err := rpc.NewApiWithClient(address, &amp;http.Client&#123;&#125;)</span><br><span class="line"><span class="comment">//node, err := rpc.NewLocalApi()</span></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Pin a given file by its CID</span></span><br><span class="line">ctx := context.Background()</span><br><span class="line">cid := <span class="string">&quot;/ipfs/QmepEzGBkDQ7a8xCTVYZvuZL2C7FUxaaC75FSY8pGb1v7b&quot;</span></span><br><span class="line">p, err := path.NewPath(cid)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//p := path.New(cid)</span></span><br><span class="line">data, err := node.Object().Get(ctx, p)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line">fmt.Println(<span class="type">string</span>(data.RawData()))</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">getFile</span><span class="params">()</span></span> &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">putFile</span><span class="params">()</span></span> &#123;</span><br><span class="line"><span class="comment">// &quot;Connect&quot; to local node</span></span><br><span class="line">node, err := rpc.NewLocalApi()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Pin a given file by its CID</span></span><br><span class="line">ctx := context.Background()</span><br><span class="line"></span><br><span class="line">f, _ := os.Open(<span class="string">&quot;/Users/qxdo/Projects/make_order/test.html&quot;</span>)</span><br><span class="line">fmt.Println(node.Unixfs().Add(ctx, files.NewReaderFile(f)))</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">&quot;context&quot;</span></span><br><span class="line"><span class="string">&quot;fmt&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/ipfs/boxo/path&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/ipfs/kubo/client/rpc&quot;</span></span><br><span class="line"><span class="comment">//path &quot;github.com/ipfs/boxo/coreiface/path&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line"><span class="comment">// &quot;Connect&quot; to local node</span></span><br><span class="line">node, err := rpc.NewLocalApi()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Pin a given file by its CID</span></span><br><span class="line">ctx := context.Background()</span><br><span class="line">cid := <span class="string">&quot;/ipfs/QmcmaL2fiXR6BLJiVixtCsX46xydTTjYdQr3DB2D7ecBQT&quot;</span></span><br><span class="line">p, err := path.NewPath(cid)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//p := path.New(cid)</span></span><br><span class="line">data, err := node.Object().Get(ctx, p)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line">fmt.Println(<span class="type">string</span>(data.RawData()))</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>一个简易HTML 网页文件管理的前端</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;zh-CN&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>文件列表页<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">        <span class="selector-tag">body</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">font-family</span>: Arial, sans-serif;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.container</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">width</span>: <span class="number">80%</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin</span>: <span class="number">20px</span> auto;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">list-style-type</span>: none;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list-item</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border-bottom</span>: <span class="number">1px</span> solid <span class="number">#ddd</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list-item</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#f5f5f5</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button-group</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin-bottom</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">10px</span> <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin-right</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#5cb85c</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">color</span>: white;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border</span>: none;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border-radius</span>: <span class="number">4px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#4cae4c</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">        <span class="selector-tag">body</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">font-family</span>: Arial, sans-serif;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.container</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">width</span>: <span class="number">80%</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin</span>: <span class="number">20px</span> auto;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">list-style-type</span>: none;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list-item</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border-bottom</span>: <span class="number">1px</span> solid <span class="number">#ddd</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.file-list-item</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#f5f5f5</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button-group</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin-bottom</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">text-align</span>: right;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">10px</span> <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">margin-left</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#5cb85c</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">color</span>: white;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border</span>: none;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border-radius</span>: <span class="number">4px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.button</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#4cae4c</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/* 添加文件上传样式 */</span></span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.upload-area</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">display</span>: none;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">position</span>: fixed;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">top</span>: <span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">left</span>: <span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">transform</span>: <span class="built_in">translate</span>(-<span class="number">50%</span>, -<span class="number">50%</span>);</span></span><br><span class="line"><span class="language-css">            <span class="attribute">background-color</span>: <span class="number">#fff</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#ddd</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">padding</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">border-radius</span>: <span class="number">4px</span>;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">z-index</span>: <span class="number">1000</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.close-btn</span> &#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">float</span>: right;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">    </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;container&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;button-group&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;button&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;toggleUploadArea()&quot;</span>&gt;</span>上传文件<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;button&quot;</span>&gt;</span>新建文件夹<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">ul</span> <span class="attr">class</span>=<span class="string">&quot;file-list&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!-- 文件列表项 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 文件上传区域 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;upload-area&quot;</span> <span class="attr">id</span>=<span class="string">&quot;uploadArea&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;close-btn&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;toggleUploadArea()&quot;</span>&gt;</span><span class="symbol">&amp;times;</span><span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span>&gt;</span>选择文件上传<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">form</span> <span class="attr">id</span>=<span class="string">&quot;uploadForm&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;file&quot;</span> <span class="attr">id</span>=<span class="string">&quot;fileInput&quot;</span> <span class="attr">multiple</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">&quot;submit&quot;</span> <span class="attr">class</span>=<span class="string">&quot;button&quot;</span>&gt;</span>开始上传<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 切换上传区域的显示和隐藏</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">function</span> <span class="title function_">toggleUploadArea</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> uploadArea = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;uploadArea&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">        uploadArea.<span class="property">style</span>.<span class="property">display</span> = uploadArea.<span class="property">style</span>.<span class="property">display</span> === <span class="string">&#x27;none&#x27;</span> ? <span class="string">&#x27;block&#x27;</span> : <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 处理文件上传</span></span></span><br><span class="line"><span class="language-javascript">    <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;uploadForm&#x27;</span>).<span class="title function_">addEventListener</span>(<span class="string">&#x27;submit&#x27;</span>, <span class="keyword">function</span>(<span class="params">event</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        event.<span class="title function_">preventDefault</span>();</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> files = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;fileInput&#x27;</span>).<span class="property">files</span>;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 这里可以添加处理文件上传的代码，例如通过XMLHttpRequest发送文件到服务器</span></span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">alert</span>(<span class="string">&#x27;文件选择成功，可以开始上传了。&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 关闭上传区域</span></span></span><br><span class="line"><span class="language-javascript">        <span class="title function_">toggleUploadArea</span>();</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 关闭上传区域</span></span></span><br><span class="line"><span class="language-javascript">    <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;uploadArea&#x27;</span>).<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span>(<span class="params">event</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">if</span> (event.<span class="property">target</span> === event.<span class="property">currentTarget</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="title function_">toggleUploadArea</span>();</span></span><br><span class="line"><span class="language-javascript">        &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;作为备份，存储一下，&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>一个简单的Go语言实现的表达式引擎-未完待续</title>
    <link href="https://blog.bh4fwa.com/2024/05/06/10-26-08/"/>
    <id>https://blog.bh4fwa.com/2024/05/06/10-26-08/</id>
    <published>2024-05-06T10:26:08.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<span id="more"></span><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">package</span> templatesService</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">&quot;errors&quot;</span></span><br><span class="line"><span class="string">&quot;fmt&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/Knetic/govaluate&quot;</span></span><br><span class="line"><span class="string">&quot;regexp&quot;</span></span><br><span class="line"><span class="string">&quot;strings&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> globalFunctions = <span class="keyword">map</span>[<span class="type">string</span>]govaluate.ExpressionFunction&#123;</span><br><span class="line"><span class="string">&quot;arrays_overlap_count&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(arguments ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="comment">// a b</span></span><br><span class="line">fmt.Println(<span class="string">&quot;arrays_overlap_count args:&quot;</span>, arguments)</span><br><span class="line">containsType := arguments[<span class="number">0</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">var</span> count <span class="type">float64</span></span><br><span class="line"><span class="keyword">switch</span> containsType &#123;</span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;float64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">float64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">float64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="type">float64</span>(<span class="number">0</span>), <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="string">&quot;arrays_bit_in&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(arguments ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line">fmt.Println(<span class="string">&quot;arrays_bit_in args:&quot;</span>, arguments)</span><br><span class="line">containsType := arguments[<span class="number">0</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">switch</span> containsType &#123;</span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int</span>)</span><br><span class="line">index := <span class="type">int</span>(arguments[<span class="number">2</span>].(<span class="type">float64</span>))</span><br><span class="line">target := arguments[<span class="number">3</span>].([]<span class="type">int</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &amp;&amp; <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) &gt; index &#123;</span><br><span class="line"><span class="keyword">for</span> _, d := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> data[index] == d &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="string">&quot;arrays_equals&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(arguments ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="comment">// a b</span></span><br><span class="line">fmt.Println(<span class="string">&quot;arrays_equals args:&quot;</span>, arguments)</span><br><span class="line">containsType := arguments[<span class="number">0</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">switch</span> containsType &#123;</span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &amp;&amp; <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="built_in">len</span>(target) &#123;</span><br><span class="line"><span class="keyword">for</span> i, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">if</span> target[i] == each &#123;</span><br><span class="line"><span class="keyword">continue</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &amp;&amp; <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="built_in">len</span>(target) &#123;</span><br><span class="line"><span class="keyword">for</span> i, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">if</span> target[i] == each &#123;</span><br><span class="line"><span class="keyword">continue</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;float64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">float64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">float64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &amp;&amp; <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="built_in">len</span>(target) &#123;</span><br><span class="line"><span class="keyword">for</span> i, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">if</span> target[i] == each &#123;</span><br><span class="line"><span class="keyword">continue</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="string">&quot;arrays_overlap&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(arguments ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="comment">// a b</span></span><br><span class="line">fmt.Println(<span class="string">&quot;arrays_overlap args:&quot;</span>, arguments)</span><br><span class="line">containsType := arguments[<span class="number">0</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">var</span> count <span class="type">int</span></span><br><span class="line"><span class="keyword">switch</span> containsType &#123;</span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count &gt; <span class="number">0</span>, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;int64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">int64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">int64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count &gt; <span class="number">0</span>, <span class="literal">nil</span></span><br><span class="line"><span class="keyword">case</span> <span class="string">&quot;float64&quot;</span>:</span><br><span class="line">data := arguments[<span class="number">1</span>].([]<span class="type">float64</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].([]<span class="type">float64</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(target) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _, each := <span class="keyword">range</span> data &#123;</span><br><span class="line"><span class="keyword">for</span> _, each1 := <span class="keyword">range</span> target &#123;</span><br><span class="line"><span class="keyword">if</span> each == each1 &#123;</span><br><span class="line">count++</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> count &gt; <span class="number">0</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="string">&quot;str_contains&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(arguments ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line">fmt.Println(<span class="string">&quot;str_contains args:&quot;</span>, arguments)</span><br><span class="line">containsType := arguments[<span class="number">0</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">if</span> containsType == <span class="string">&quot;string&quot;</span> &#123;</span><br><span class="line">data := arguments[<span class="number">1</span>].(<span class="type">string</span>)</span><br><span class="line">target := arguments[<span class="number">2</span>].(<span class="type">string</span>)</span><br><span class="line"><span class="keyword">return</span> strings.Contains(data, target), <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="string">&quot;str_len&quot;</span>: <span class="function"><span class="keyword">func</span><span class="params">(args ...<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="keyword">interface</span>&#123;&#125;, <span class="type">error</span>) &#123;</span><br><span class="line">length := <span class="built_in">len</span>(args[<span class="number">0</span>].(<span class="type">string</span>))</span><br><span class="line"><span class="keyword">return</span> (<span class="type">float64</span>)(length), <span class="literal">nil</span></span><br><span class="line">&#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> ExpressionStr = <span class="string">&quot;exp&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">expressionParse</span><span class="params">(str <span class="type">string</span>, dataMap <span class="keyword">map</span>[<span class="type">string</span>]<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="type">bool</span>, <span class="type">int</span>, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(str) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="number">0</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">re := regexp.MustCompile(ExpressionStr + <span class="string">`\&#123;(.*?)\&#125;`</span>)</span><br><span class="line">matches := re.FindAllStringSubmatch(str, <span class="number">-1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> _, match := <span class="keyword">range</span> matches &#123;</span><br><span class="line">fmt.Println(<span class="string">&quot;matchSimpleExp:&quot;</span>, match)</span><br><span class="line">parameter := match[<span class="number">1</span>]</span><br><span class="line"><span class="keyword">var</span> result <span class="type">bool</span></span><br><span class="line">fmt.Println(<span class="string">&quot;params:&quot;</span>, parameter)</span><br><span class="line">ok, err := matchFuncExp(parameter, dataMap, globalFunctions)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">fmt.Println(err)</span><br><span class="line">result = <span class="literal">true</span></span><br><span class="line">&#125;</span><br><span class="line">result = ok</span><br><span class="line"></span><br><span class="line">str = strings.ReplaceAll(str, fmt.Sprintf(ExpressionStr+<span class="string">&quot;&#123;%s&#125;&quot;</span>, parameter), fmt.Sprintf(<span class="string">&quot;%t&quot;</span>, result))</span><br><span class="line">fmt.Println(<span class="string">&quot;express:&quot;</span>, str)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">matchCount := strings.Count(str, <span class="string">&quot;true&quot;</span>)</span><br><span class="line">str = strings.ReplaceAll(str, <span class="string">&quot;and&quot;</span>, <span class="string">&quot;&amp;&amp;&quot;</span>)</span><br><span class="line">str = strings.ReplaceAll(str, <span class="string">&quot;or&quot;</span>, <span class="string">&quot;||&quot;</span>)</span><br><span class="line">totalRes, err := matchSimpleExp(str, dataMap)</span><br><span class="line">fmt.Println(<span class="string">&quot;totalResult:&quot;</span>, totalRes, err)</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> totalRes, matchCount, err</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">matchSimpleExp</span><span class="params">(exp <span class="type">string</span>, data <span class="keyword">map</span>[<span class="type">string</span>]<span class="keyword">interface</span>&#123;&#125;)</span></span> (<span class="type">bool</span>, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(exp) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">expression, err := govaluate.NewEvaluableExpression(exp)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">result, err := expression.Evaluate(data)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line">&#125;</span><br><span class="line">resultBool, ok := result.(<span class="type">bool</span>)</span><br><span class="line"><span class="keyword">if</span> ok &#123;</span><br><span class="line">fmt.Println(<span class="string">&quot;matchSimpleExp expression :&quot;</span>, exp, data, resultBool)</span><br><span class="line"><span class="keyword">return</span> resultBool, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, errors.New(<span class="string">&quot;go Expression matchSimpleExp error&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">matchFuncExp</span><span class="params">(expStr <span class="type">string</span>, data <span class="keyword">map</span>[<span class="type">string</span>]<span class="keyword">interface</span>&#123;&#125;, funcs <span class="keyword">map</span>[<span class="type">string</span>]govaluate.ExpressionFunction)</span></span> (<span class="type">bool</span>, <span class="type">error</span>) &#123;</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(expStr) == <span class="number">0</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line">fmt.Println(<span class="string">&quot;expStr:&quot;</span>, expStr)</span><br><span class="line">expression, _ := govaluate.NewEvaluableExpressionWithFunctions(expStr, funcs)</span><br><span class="line">result, err := expression.Evaluate(data)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line">&#125;</span><br><span class="line">resultBool, ok := result.(<span class="type">bool</span>)</span><br><span class="line"><span class="keyword">if</span> ok &#123;</span><br><span class="line">fmt.Println(<span class="string">&quot;matchSimpleExp expression:&quot;</span>, expStr, data, resultBool)</span><br><span class="line"><span class="keyword">return</span> resultBool, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, errors.New(<span class="string">&quot;go matchFuncExp matchSimpleExp error&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;span id=&quot;more&quot;&gt;&lt;/span&gt;


&lt;figure class=&quot;highlight go&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>IoT-Switch</title>
    <link href="https://blog.bh4fwa.com/2024/05/06/09-14-10/"/>
    <id>https://blog.bh4fwa.com/2024/05/06/09-14-10/</id>
    <published>2024-05-06T09:14:10.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>再放一下之前做的智能开关的设备，使用ESP-8266，连接舵机，主要功能是管理常见的86插座，使用热熔胶将舵机粘到86开关盒边上，使得该舵机的方向拨杆可以完成关灯操作，即可。主要是为了冬天懒得下床再关灯而设计的，然而后来我买了米家的智能灯泡，可以直接米家APP接入，就不需要了。<br>有智能升级，之前应该是接入了 blinker的，可以实现blinker app的控制，然后依稀记得 之前还实现了升级功能，不知道是真的假的，备份一下。</p><span id="more"></span><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BLINKER_WIFI</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BLINKER_MIOT_OUTLET</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;Blinker.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;ESP8266WiFi.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;Servo.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;ESP8266HTTPClient.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;ESP8266httpUpdate.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;ESP8266WebServer.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief </span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 需求描述：使用网线供电，需要使用USB分离器和分线器来配合使用，</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 1.先执行8266的WIFI入网功能，</span></span><br><span class="line"><span class="comment"> * 2.在执行webCLient的初始化功能将auth字符设置值，</span></span><br><span class="line"><span class="comment"> * 3.如何保证auth字段不被重置？那要不就新建模式写文件，写到auth字段，</span></span><br><span class="line"><span class="comment"> * 4.将auth字段设置给程序，然后继续往下走接口鉴权，</span></span><br><span class="line"><span class="comment"> * 5.再然后就自动鉴权，接口设备联网自行运转，</span></span><br><span class="line"><span class="comment"> * 6.设备Mac地址需要抓出来，配置WIFI使用，</span></span><br><span class="line"><span class="comment"> * 7.但是还需要获取一个mac地址，和IP地址，</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">char</span> auth[] = <span class="string">&quot;blinker-auth-key&quot;</span>;</span><br><span class="line"><span class="type">char</span> ssid[] = <span class="string">&quot;PDCN&quot;</span>;</span><br><span class="line"><span class="type">char</span> passwd[] = <span class="string">&quot;wifi-password&quot;</span>;</span><br><span class="line"></span><br><span class="line">ESP8266HTTPUpdate httpUpdate;</span><br><span class="line">ESP8266WebServer <span class="title function_">webServer</span><span class="params">(<span class="number">80</span>)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">bool</span> updateState = <span class="literal">false</span>;</span><br><span class="line"><span class="type">bool</span> oState = <span class="literal">false</span>;</span><br><span class="line">Servo servo;</span><br><span class="line"><span class="type">int</span> pos = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">BlinkerButton btn1 = BlinkerButton(<span class="string">&quot;btn1&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">doAction</span><span class="params">(<span class="type">const</span> String &amp; state)</span> &#123;</span><br><span class="line"></span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;doAction : &quot;</span>, state);</span><br><span class="line">    <span class="keyword">if</span>(state == BLINKER_CMD_ON) &#123;</span><br><span class="line">        <span class="comment">//暂时先空着，先不留开开关的</span></span><br><span class="line">        BLINKER_LOG(<span class="string">&quot;开关 开了&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span>(state == BLINKER_CMD_OFF) &#123;</span><br><span class="line">        BLINKER_LOG(<span class="string">&quot;开关 关了&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (pos = <span class="number">90</span>; pos &gt;= <span class="number">0</span>; pos --) &#123; <span class="comment">// 从180°到0°</span></span><br><span class="line">            servo.write(pos);              <span class="comment">// 舵机角度写入</span></span><br><span class="line">            delay(<span class="number">15</span>);                       <span class="comment">// 等待转动到指定角度</span></span><br><span class="line">        &#125;</span><br><span class="line">        delay(<span class="number">200</span>);</span><br><span class="line">        <span class="keyword">for</span> (pos = <span class="number">0</span>; pos &lt;= <span class="number">90</span>; pos ++) &#123; <span class="comment">// 0°到180°</span></span><br><span class="line">            <span class="comment">// in steps of 1 degree</span></span><br><span class="line">            servo.write(pos);              <span class="comment">// 舵机角度写入</span></span><br><span class="line">            delay(<span class="number">15</span>);                       <span class="comment">// 等待转动到指定角度</span></span><br><span class="line">        &#125;</span><br><span class="line">        delay(<span class="number">200</span>);<span class="comment">//延时0.2s</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="type">void</span> <span class="title function_">miotPowerState</span><span class="params">(<span class="type">const</span> String &amp; state)</span></span><br><span class="line">&#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;need set power state: &quot;</span>, state);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (state == BLINKER_CMD_ON) &#123;</span><br><span class="line">        digitalWrite(LED_BUILTIN, LOW);</span><br><span class="line">        doAction(state);</span><br><span class="line">        BlinkerMIOT.powerState(<span class="string">&quot;on&quot;</span>);</span><br><span class="line">        BlinkerMIOT.print();</span><br><span class="line"></span><br><span class="line">        oState = <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (state == BLINKER_CMD_OFF) &#123;</span><br><span class="line">        digitalWrite(LED_BUILTIN, HIGH);</span><br><span class="line">        doAction(state);</span><br><span class="line">        BlinkerMIOT.powerState(<span class="string">&quot;off&quot;</span>);</span><br><span class="line">        BlinkerMIOT.print();</span><br><span class="line">        oState = <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">miotQuery</span><span class="params">(<span class="type">int32_t</span> queryCode)</span></span><br><span class="line">&#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;MIOT Query codes: &quot;</span>, queryCode);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (queryCode)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">case</span> BLINKER_CMD_QUERY_ALL_NUMBER :</span><br><span class="line">            BLINKER_LOG(<span class="string">&quot;MIOT Query All&quot;</span>);</span><br><span class="line">            BlinkerMIOT.powerState(oState ? <span class="string">&quot;on&quot;</span> : <span class="string">&quot;off&quot;</span>);</span><br><span class="line">            BlinkerMIOT.print();</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> BLINKER_CMD_QUERY_POWERSTATE_NUMBER :</span><br><span class="line">            BLINKER_LOG(<span class="string">&quot;MIOT Query Power State&quot;</span>);</span><br><span class="line">            BlinkerMIOT.powerState(oState ? <span class="string">&quot;on&quot;</span> : <span class="string">&quot;off&quot;</span>);</span><br><span class="line">            BlinkerMIOT.print();</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span> :</span><br><span class="line">            BlinkerMIOT.powerState(oState ? <span class="string">&quot;on&quot;</span> : <span class="string">&quot;off&quot;</span>);</span><br><span class="line">            BlinkerMIOT.print();</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">dataRead</span><span class="params">(<span class="type">const</span> String &amp; data)</span></span><br><span class="line">&#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;Blinker readString: &quot;</span>, data);</span><br><span class="line"></span><br><span class="line">    Blinker.vibrate();</span><br><span class="line">    </span><br><span class="line">    <span class="type">uint32_t</span> BlinkerTime = millis();</span><br><span class="line">    </span><br><span class="line">    Blinker.print(<span class="string">&quot;millis&quot;</span>, BlinkerTime);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">update_started</span><span class="params">()</span> &#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;8266 update start&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">update_finished</span><span class="params">()</span> &#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;8266 update finished&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="type">void</span> <span class="title function_">update_process</span><span class="params">(<span class="type">int</span> cur, <span class="type">int</span> total)</span> &#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;update process at &quot;</span>, cur, <span class="string">&quot; of &quot;</span>, total, <span class="string">&quot; bytes&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">update_error</span><span class="params">(<span class="type">int</span> err)</span> &#123;</span><br><span class="line">    BLINKER_LOG(<span class="string">&quot;update error code &quot;</span>, err);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">update</span><span class="params">(String url)</span> &#123;</span><br><span class="line"></span><br><span class="line">    WiFi.mode(WIFI_STA);</span><br><span class="line">    WiFi.begin(ssid, passwd);</span><br><span class="line">    <span class="keyword">while</span>(WiFi.status() != WL_CONNECTED) &#123;</span><br><span class="line">        delay(<span class="number">500</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    WiFiClient client;</span><br><span class="line">    httpUpdate.onStart(update_started);</span><br><span class="line">    httpUpdate.onEnd(update_finished);</span><br><span class="line">    httpUpdate.onError(update_error);</span><br><span class="line">    httpUpdate.onProgress(update_process);</span><br><span class="line"></span><br><span class="line">    t_httpUpdate_return ret = httpUpdate.update(client, url);</span><br><span class="line">    <span class="keyword">switch</span>(ret) &#123;</span><br><span class="line">        <span class="keyword">case</span> HTTP_UPDATE_FAILED: </span><br><span class="line">            BLINKER_LOG(<span class="string">&quot;update failed  &quot;</span>, httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> HTTP_UPDATE_NO_UPDATES:</span><br><span class="line">            BLINKER_LOG(<span class="string">&quot;update result no updates&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> HTTP_UPDATE_OK:</span><br><span class="line">            BLINKER_LOG(<span class="string">&quot;update ok&quot;</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">handleUpdate</span><span class="params">()</span> &#123;</span><br><span class="line">    webServer.send(<span class="number">200</span>, <span class="string">&quot;text/plain&quot;</span>, <span class="string">&quot;ok&quot;</span>);</span><br><span class="line">    String url = webServer.arg(<span class="string">&quot;url&quot;</span>);</span><br><span class="line">    Serial.print(<span class="string">&quot;url: &quot;</span> + url);</span><br><span class="line">    update(url);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">handleRoot</span><span class="params">()</span> &#123;</span><br><span class="line">    webServer.send(<span class="number">200</span>, <span class="string">&quot;text/html;charset=utf-8&quot;</span>, <span class="string">&quot;&lt;form action=&#x27;/update&#x27;&gt;&lt;input name=&#x27;url&#x27; type=&#x27;input&#x27;&gt;&lt;/input&gt; &lt;input type=&#x27;submit&#x27;&gt; submit&lt;/input&gt;&lt;/form&gt;&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">setup</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    Serial.begin(<span class="number">115200</span>);</span><br><span class="line">    BLINKER_DEBUG.stream(Serial);</span><br><span class="line"></span><br><span class="line">    pinMode(LED_BUILTIN, OUTPUT);</span><br><span class="line">    digitalWrite(LED_BUILTIN, HIGH);</span><br><span class="line"></span><br><span class="line">    servo.attach(D0);</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    Blinker.begin(auth, ssid, passwd);</span><br><span class="line">    Blinker.attachData(dataRead);</span><br><span class="line"></span><br><span class="line">    BlinkerMIOT.attachPowerState(miotPowerState);</span><br><span class="line">    BlinkerMIOT.attachQuery(miotQuery);</span><br><span class="line">    doAction(<span class="string">&quot;off&quot;</span>);</span><br><span class="line">    webServer.begin();</span><br><span class="line">    webServer.on(<span class="string">&quot;/&quot;</span>, handleRoot);</span><br><span class="line">    webServer.on(<span class="string">&quot;/update&quot;</span>, handleUpdate);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">loop</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    Blinker.run();</span><br><span class="line">    webServer.handleClient();</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;再放一下之前做的智能开关的设备，使用ESP-8266，连接舵机，主要功能是管理常见的86插座，使用热熔胶将舵机粘到86开关盒边上，使得该舵机的方向拨杆可以完成关灯操作，即可。主要是为了冬天懒得下床再关灯而设计的，然而后来我买了米家的智能灯泡，可以直接米家APP接入，就不需要了。&lt;br&gt;有智能升级，之前应该是接入了 blinker的，可以实现blinker app的控制，然后依稀记得 之前还实现了升级功能，不知道是真的假的，备份一下。&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>ESP32-APRS</title>
    <link href="https://blog.bh4fwa.com/2024/05/05/12-45-52/"/>
    <id>https://blog.bh4fwa.com/2024/05/05/12-45-52/</id>
    <published>2024-05-05T12:45:52.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<h1 id="ESP32-APRS"><a href="#ESP32-APRS" class="headerlink" title="ESP32-APRS"></a>ESP32-APRS</h1><h3 id="This-is-APRS-Device-use-ESP32-it’s-designed-as-a-device-that-you-can-every-day-carry-with-week-charge-so-other-people-can-know-my-environment-changed-and-my-location-changed-and-know-my-history-track"><a href="#This-is-APRS-Device-use-ESP32-it’s-designed-as-a-device-that-you-can-every-day-carry-with-week-charge-so-other-people-can-know-my-environment-changed-and-my-location-changed-and-know-my-history-track" class="headerlink" title="This is APRS Device use ESP32, it’s designed as a device that you can every day carry with week-charge, so other people can know my environment changed, and my location changed, and know my history track."></a>This is APRS Device use ESP32, it’s designed as a device that you can every day carry with week-charge, so other people can know my environment changed, and my location changed, and know my history track.</h3><h4 id="这是使用ESP32开发的APRS设备-它被设计为是一个可以日常携带的设备-至少每一周或一个月充一次电-这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。"><a href="#这是使用ESP32开发的APRS设备-它被设计为是一个可以日常携带的设备-至少每一周或一个月充一次电-这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。" class="headerlink" title="这是使用ESP32开发的APRS设备,它被设计为是一个可以日常携带的设备,至少每一周或一个月充一次电,这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。"></a>这是使用ESP32开发的APRS设备,它被设计为是一个可以日常携带的设备,至少每一周或一个月充一次电,这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。</h4><span id="more"></span><h3 id="It’s-planed-Support-environment-sensors-GPS-location-Real-time-Network-and-enough-battery-support-Under-here-is-the-todo-list"><a href="#It’s-planed-Support-environment-sensors-GPS-location-Real-time-Network-and-enough-battery-support-Under-here-is-the-todo-list" class="headerlink" title="It’s planed Support environment sensors, GPS location, Real-time Network, and enough battery support. Under here is the todo list."></a>It’s planed Support environment sensors, GPS location, Real-time Network, and enough battery support. Under here is the todo list.</h3><h4 id="它被设计为支持环境传感器，GPS定位，实时网络，足够的电池支持，下面是待办事项。"><a href="#它被设计为支持环境传感器，GPS定位，实时网络，足够的电池支持，下面是待办事项。" class="headerlink" title="它被设计为支持环境传感器，GPS定位，实时网络，足够的电池支持，下面是待办事项。"></a>它被设计为支持环境传感器，GPS定位，实时网络，足够的电池支持，下面是待办事项。</h4><h3 id="Plan-Support-List"><a href="#Plan-Support-List" class="headerlink" title="Plan Support List"></a>Plan Support List</h3><h4 id="Real-time-Network"><a href="#Real-time-Network" class="headerlink" title="Real-time Network"></a>Real-time Network</h4><ul><li><input disabled="" type="checkbox"> 4G网络模块: 4G network module</li></ul><h4 id="Environment-Sensors"><a href="#Environment-Sensors" class="headerlink" title="Environment Sensors"></a>Environment Sensors</h4><ul><li><input disabled="" type="checkbox"> 温湿度传感器: Temperature and Humidity Sensor</li><li><input disabled="" type="checkbox"> 风向角度传感器: Wind Direction Sensor</li><li><input disabled="" type="checkbox"> 风速传感器: Anemometer (Wind Speed Sensor)</li><li><input disabled="" type="checkbox"> 雨量传感器: Rain Gauge Sensor</li><li><input disabled="" type="checkbox"> 气压传感器: Barometric Pressure Sensor</li></ul><h4 id="GPS-Location-System"><a href="#GPS-Location-System" class="headerlink" title="GPS Location System"></a>GPS Location System</h4><ul><li><input disabled="" type="checkbox"> GPS定位模块: GPS module</li></ul><h4 id="Battery-Support-System"><a href="#Battery-Support-System" class="headerlink" title="Battery Support System"></a>Battery Support System</h4><ul><li><input disabled="" type="checkbox"> 电量供应系统: battery support system</li></ul><h4 id="Plastic-Housing"><a href="#Plastic-Housing" class="headerlink" title="Plastic Housing"></a>Plastic Housing</h4><ul><li><input disabled="" type="checkbox"> 塑料外壳: Plastic Housing</li></ul><h4 id="WeChat-Alarm-System"><a href="#WeChat-Alarm-System" class="headerlink" title="WeChat Alarm System"></a>WeChat Alarm System</h4><ul><li><input disabled="" type="checkbox"> 微信报警系统: WeChat Alarm System</li><li>这里是该项目的地址，欢迎Star: <a href="https://github.com/qxdo/esp32-aprs">https://github.com/qxdo/esp32-aprs</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;ESP32-APRS&quot;&gt;&lt;a href=&quot;#ESP32-APRS&quot; class=&quot;headerlink&quot; title=&quot;ESP32-APRS&quot;&gt;&lt;/a&gt;ESP32-APRS&lt;/h1&gt;&lt;h3 id=&quot;This-is-APRS-Device-use-ESP32-it’s-designed-as-a-device-that-you-can-every-day-carry-with-week-charge-so-other-people-can-know-my-environment-changed-and-my-location-changed-and-know-my-history-track&quot;&gt;&lt;a href=&quot;#This-is-APRS-Device-use-ESP32-it’s-designed-as-a-device-that-you-can-every-day-carry-with-week-charge-so-other-people-can-know-my-environment-changed-and-my-location-changed-and-know-my-history-track&quot; class=&quot;headerlink&quot; title=&quot;This is APRS Device use ESP32, it’s designed as a device that you can every day carry with week-charge, so other people can know my environment changed, and my location changed, and know my history track.&quot;&gt;&lt;/a&gt;This is APRS Device use ESP32, it’s designed as a device that you can every day carry with week-charge, so other people can know my environment changed, and my location changed, and know my history track.&lt;/h3&gt;&lt;h4 id=&quot;这是使用ESP32开发的APRS设备-它被设计为是一个可以日常携带的设备-至少每一周或一个月充一次电-这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。&quot;&gt;&lt;a href=&quot;#这是使用ESP32开发的APRS设备-它被设计为是一个可以日常携带的设备-至少每一周或一个月充一次电-这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。&quot; class=&quot;headerlink&quot; title=&quot;这是使用ESP32开发的APRS设备,它被设计为是一个可以日常携带的设备,至少每一周或一个月充一次电,这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。&quot;&gt;&lt;/a&gt;这是使用ESP32开发的APRS设备,它被设计为是一个可以日常携带的设备,至少每一周或一个月充一次电,这样用来记录我的环境变换，以及我的位置变换，以此来记录我的成长经历和历史轨迹。&lt;/h4&gt;</summary>
    
    
    
    <category term="ham" scheme="https://blog.bh4fwa.com/categories/ham/"/>
    
    <category term="业余无线电" scheme="https://blog.bh4fwa.com/categories/ham/%E4%B8%9A%E4%BD%99%E6%97%A0%E7%BA%BF%E7%94%B5/"/>
    
    <category term="APRS" scheme="https://blog.bh4fwa.com/categories/ham/%E4%B8%9A%E4%BD%99%E6%97%A0%E7%BA%BF%E7%94%B5/APRS/"/>
    
    <category term="嵌入式" scheme="https://blog.bh4fwa.com/categories/ham/%E4%B8%9A%E4%BD%99%E6%97%A0%E7%BA%BF%E7%94%B5/APRS/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
    
    
    <category term="嵌入式" scheme="https://blog.bh4fwa.com/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
    
    <category term="ESP32" scheme="https://blog.bh4fwa.com/tags/ESP32/"/>
    
    <category term="APRS" scheme="https://blog.bh4fwa.com/tags/APRS/"/>
    
  </entry>
  
  <entry>
    <title>51开发板代码备份</title>
    <link href="https://blog.bh4fwa.com/2024/05/04/13-38-10/"/>
    <id>https://blog.bh4fwa.com/2024/05/04/13-38-10/</id>
    <published>2024-05-04T13:38:10.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>放一下早年学51开发板的代码，大概其实现的功能是驱动一个4*4的按键，实现一个矩阵键盘密码箱的功能。 不太记得了，有大佬可以看看。<br>这段代码是使用PlatformIO IDE开发的，有兴趣的可以去尝试一下，不过需要注意，这个代码中的引脚 好像都是 _ 来表示的，而 Keil里是 ^ 代表引脚标记。</p><span id="more"></span><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//// header/intrins.h</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">ifndef</span> _INTRINS_H_</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _INTRINS_H_</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* warning: __push __pop 使用堆栈临时保存 sfr 数据，必需成对使用!  </span></span><br><span class="line"><span class="comment">     __push(x);</span></span><br><span class="line"><span class="comment">         ...  // 保护代码块</span></span><br><span class="line"><span class="comment">         __pop(x)；  //缺少无该语句编译不会出错，但运行错误!</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">        <span class="meta">#<span class="keyword">define</span> __push(x)      __asm push _##x  __endasm  <span class="comment">/* void _push_ (unsigned char _sfr); */</span></span></span><br><span class="line">        <span class="meta">#<span class="keyword">define</span> __pop(x)       __asm pop  _##x  __endasm  <span class="comment">/* void _pop_  (unsigned char _sfr); */</span></span></span><br><span class="line"></span><br><span class="line">        <span class="meta">#<span class="keyword">define</span> _push_        __push　       <span class="comment">/*兼容 keil c51*/</span></span></span><br><span class="line">        <span class="meta">#<span class="keyword">define</span> _pop_        __pop　        <span class="comment">/*兼容 keil c51*/</span></span></span><br><span class="line">        </span><br><span class="line"><span class="comment">/*   安全使用保护宏： </span></span><br><span class="line"><span class="comment">     pushSfr(x);</span></span><br><span class="line"><span class="comment">         ...                 // 受保护代码块</span></span><br><span class="line"><span class="comment">         popSfr(x)；         // 缺少无该语句编译出错，确保生成正确代码。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">    <span class="meta">#<span class="keyword">define</span> pushSfr(x)  do&#123;\</span></span><br><span class="line"><span class="meta">                                  __push(x)</span></span><br><span class="line"></span><br><span class="line">        <span class="meta">#<span class="keyword">define</span>  popSfr(x)     __pop(x);\</span></span><br><span class="line"><span class="meta">                              &#125;while(0)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span> <span class="comment">//_INTRINS_H_</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//// header/my.h</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">ifndef</span> _MY_H_</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _MY_H_</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;8052.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BEEP P2_5</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> DEGITAL_LED P0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> DEGITAL_LED_SELECT P2</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY1 P3_1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY2 P3_0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY3 P3_2</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY4 P3_3</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">unsigned</span> <span class="type">char</span> u8;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">unsigned</span> <span class="type">int</span> u16;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 数码管默认字符显示 0 - F</span></span><br><span class="line">u8 smg_code[<span class="number">16</span>] = &#123;<span class="number">0x3F</span>,<span class="number">0x06</span>, <span class="number">0x5B</span>, <span class="number">0x4F</span>, <span class="number">0x66</span>, <span class="number">0x6D</span>, <span class="number">0x7D</span>, <span class="number">0x07</span>, <span class="number">0x7F</span>, <span class="number">0x6F</span>, <span class="number">0x77</span>, <span class="number">0x7C</span>, <span class="number">0x39</span>, <span class="number">0x5E</span>, <span class="number">0x79</span>, <span class="number">0x71</span>&#125;;</span><br><span class="line"><span class="comment">// 0 - F</span></span><br><span class="line"><span class="comment">// 单独的0-8位</span></span><br><span class="line">u8 smg_pos[<span class="number">8</span>] = &#123;<span class="number">0x1C</span>,<span class="number">0x18</span>,<span class="number">0x14</span>,<span class="number">0x10</span>,<span class="number">0x0C</span>,<span class="number">0x08</span>,<span class="number">0x04</span>,<span class="number">0x00</span>&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">u8 smg_show_code[<span class="number">2</span>][<span class="number">8</span>] = &#123;</span><br><span class="line">    &#123;<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>&#125;,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">delay_10us</span><span class="params">(u16 us)</span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(us--);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">show_digital_led</span><span class="params">(u8 pos, u8 degital, u8 ledCode)</span>&#123;</span><br><span class="line">    u8 realPos = <span class="number">0</span>;</span><br><span class="line">    realPos = pos % <span class="number">8</span>;</span><br><span class="line">    DEGITAL_LED_SELECT = smg_pos[realPos];</span><br><span class="line">    <span class="keyword">if</span>(degital &gt;= <span class="number">0</span> &amp;&amp; degital &lt;= <span class="number">15</span>) &#123;</span><br><span class="line">        DEGITAL_LED = smg_code[degital];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        DEGITAL_LED = ledCode;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">display_digital_led</span><span class="params">()</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">8</span>; i++)&#123;</span><br><span class="line">        show_digital_led(i, smg_show_code[<span class="number">0</span>][i], smg_show_code[<span class="number">1</span>][i]);</span><br><span class="line">        delay_10us(<span class="number">100</span>);</span><br><span class="line">        show_digital_led(i, <span class="number">16</span>, <span class="number">0x00</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 蜂鸣器模块,high 代表低电平占空比时间，low代表高电平占空比时间</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">beep</span><span class="params">(u8 voiceHigh, u8 voiceLow, u16 time)</span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(time--)&#123;</span><br><span class="line">        delay_10us(voiceHigh);</span><br><span class="line">        BEEP = <span class="number">1</span>;</span><br><span class="line">        delay_10us(voiceLow);</span><br><span class="line">        BEEP = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&quot;header/my.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY1_VALUE 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY2_VALUE 2</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY3_VALUE 3</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> KEY4_VALUE 4</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> NO_KEY_VALUE 5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 0 mean low power level 0是低电平</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">硬件设备2:键盘矩阵，LED，数码管，</span></span><br><span class="line"><span class="comment">硬件设备3:键盘矩阵，LED，LCD1602</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">按钮密码锁-初级版本</span></span><br><span class="line"><span class="comment">硬件设备1:独立键盘，LED，数码管，蜂鸣器</span></span><br><span class="line"><span class="comment">4位数码管密码，连续按5s，数码管中间横杠闪烁，重设密码，四个键盘代表1234 设置四位按键，同时按下12 代表重设密码，同时按下34 按钮 代表设置成功</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 独立键盘 P3.1-1  P3.0 -2 P3.2-3  P3.3-4</span></span><br><span class="line"><span class="comment">// LED P2.0 - P2.7 D1 - D8</span></span><br><span class="line"><span class="comment">// 数码管 74HC245控制 P0</span></span><br><span class="line"><span class="comment">// 蜂鸣器 P2.5 通过ULN2003控制 相反的驱动装置 给低电平 终端输出高电平</span></span><br><span class="line"></span><br><span class="line">u8 <span class="title function_">keyScan</span><span class="params">()</span>&#123;</span><br><span class="line">    delay_10us(<span class="number">1000</span>);</span><br><span class="line">    <span class="keyword">if</span>(KEY1 == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> KEY1_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(KEY2 == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> KEY2_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(KEY3 == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> KEY3_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(KEY4 == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> KEY4_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> NO_KEY_VALUE;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">initDegitalLED</span><span class="params">(u8 key)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(key &gt;=<span class="number">0</span> &amp;&amp; key &lt;= <span class="number">3</span>)&#123;</span><br><span class="line">        smg_show_code[<span class="number">0</span>][key] = <span class="number">16</span>;</span><br><span class="line">        smg_show_code[<span class="number">1</span>][key] = <span class="number">0x40</span>;</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        smg_show_code[<span class="number">0</span>][<span class="number">0</span>] = <span class="number">16</span>;</span><br><span class="line">        smg_show_code[<span class="number">1</span>][<span class="number">0</span>] = <span class="number">0x40</span>;</span><br><span class="line">        smg_show_code[<span class="number">0</span>][<span class="number">1</span>] = <span class="number">16</span>;</span><br><span class="line">        smg_show_code[<span class="number">1</span>][<span class="number">1</span>] = <span class="number">0x40</span>;</span><br><span class="line"></span><br><span class="line">        smg_show_code[<span class="number">0</span>][<span class="number">2</span>] = <span class="number">16</span>;</span><br><span class="line">        smg_show_code[<span class="number">1</span>][<span class="number">2</span>] = <span class="number">0x40</span>;</span><br><span class="line"></span><br><span class="line">        smg_show_code[<span class="number">0</span>][<span class="number">3</span>] = <span class="number">16</span>;</span><br><span class="line">        smg_show_code[<span class="number">1</span>][<span class="number">3</span>] = <span class="number">0x40</span>;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">    u8 key = <span class="number">0</span>;</span><br><span class="line">    u8 cur = <span class="number">0</span>;</span><br><span class="line">    initDegitalLED(<span class="number">5</span>);</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="comment">// 改成修改二维数组里的值 在显示即可</span></span><br><span class="line">        <span class="comment">// 第一步 闪烁两个LED</span></span><br><span class="line">        <span class="keyword">if</span>(smg_show_code[<span class="number">0</span>][<span class="number">0</span>] == <span class="number">1</span> &amp;&amp; smg_show_code[<span class="number">0</span>][<span class="number">1</span>] == <span class="number">2</span> &amp;&amp; smg_show_code[<span class="number">0</span>][<span class="number">2</span>] == <span class="number">3</span> &amp;&amp; smg_show_code[<span class="number">0</span>][<span class="number">3</span>] == <span class="number">4</span>)&#123;</span><br><span class="line">            beep(<span class="number">100</span>, <span class="number">10</span>, <span class="number">1000</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            key = keyScan();</span><br><span class="line">            <span class="keyword">if</span>(key != NO_KEY_VALUE) &#123;</span><br><span class="line">                smg_show_code[<span class="number">0</span>][key <span class="number">-1</span>] = key;</span><br><span class="line">                smg_show_code[<span class="number">1</span>][key <span class="number">-1</span>] = <span class="number">0x00</span>;</span><br><span class="line">                <span class="comment">// 0 1</span></span><br><span class="line">                <span class="comment">// 1 2</span></span><br><span class="line">                <span class="comment">// 2 3</span></span><br><span class="line">                <span class="comment">// 3 4</span></span><br><span class="line">                <span class="keyword">if</span>(cur != (key <span class="number">-1</span>))&#123;</span><br><span class="line">                    smg_show_code[<span class="number">0</span>][key<span class="number">-1</span>] = <span class="number">16</span>;</span><br><span class="line">                    smg_show_code[<span class="number">1</span>][key<span class="number">-1</span>] = <span class="number">0x40</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                cur++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(cur &gt; <span class="number">4</span>)&#123;</span><br><span class="line">                cur = <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            display_digital_led();</span><br><span class="line">        &#125;        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;放一下早年学51开发板的代码，大概其实现的功能是驱动一个4*4的按键，实现一个矩阵键盘密码箱的功能。 不太记得了，有大佬可以看看。&lt;br&gt;这段代码是使用PlatformIO IDE开发的，有兴趣的可以去尝试一下，不过需要注意，这个代码中的引脚 好像都是 _ 来表示的，而 Keil里是 ^ 代表引脚标记。&lt;/p&gt;</summary>
    
    
    
    <category term="51开发板" scheme="https://blog.bh4fwa.com/categories/51%E5%BC%80%E5%8F%91%E6%9D%BF/"/>
    
    <category term="嵌入式" scheme="https://blog.bh4fwa.com/categories/51%E5%BC%80%E5%8F%91%E6%9D%BF/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
    
    
    <category term="51开发板" scheme="https://blog.bh4fwa.com/tags/51%E5%BC%80%E5%8F%91%E6%9D%BF/"/>
    
    <category term="嵌入式" scheme="https://blog.bh4fwa.com/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/"/>
    
  </entry>
  
  <entry>
    <title>详细阅读FRP-1-未完待续</title>
    <link href="https://blog.bh4fwa.com/2024/04/25/08-25-23/"/>
    <id>https://blog.bh4fwa.com/2024/04/25/08-25-23/</id>
    <published>2024-04-25T08:25:23.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>写Go好几年，基本没有看过开源项目代码，只是搬砖，说来惭愧，偶然和一个朋友开启Side Project，基于开源项目 <a target="_blank" href="https://github.com/fatedier/frp">FRP </a>用来做一个内网穿透功能的工具，此项目在Github获得10.7K star，属于是超级硬核Project了。阅读一下大佬的源码，梳理一下思路，顺便写一下文章记录。</p><span id="more"></span><h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>由于官方好像并没有文档，所以知乎上找了几篇文章，基于参考文档的思路，往下继续梳理。</p><h3 id="基础认知"><a href="#基础认知" class="headerlink" title="基础认知"></a>基础认知</h3><p>frp属于C&#x2F;S架构，实现的功能是将内网某个端口提供的服务通过公网服务器的辅助，穿透绑定到公网IP的某个开放端口，提供给他人使用。Server端要求是放在公网服务器，Client端放在内网环境，能联网，但没有公网IP。所以基础逻辑是，两者在登录完成后 建立长连接，而由于Client的网络环境，导致Server侧是无法向Client直接发送消息的，除非是建连之后，通过长连接发送消息。</p><h3 id="详细介绍"><a href="#详细介绍" class="headerlink" title="详细介绍"></a>详细介绍</h3><p>有了基础的认知以后，我们来看一下代码。 Client端和Server端 都是使用这个库来封装的，<code>github.com/spf13/cobra</code> 这个库是一个Go做命令行工具比较常用的库。</p><h4 id="C端"><a href="#C端" class="headerlink" title="C端"></a>C端</h4><h5 id="多个代理配置"><a href="#多个代理配置" class="headerlink" title="多个代理配置"></a>多个代理配置</h5><p>抛去cobra框架的代码不看，主要的业务逻辑，是来自 这里： <code>cmd/frpc/sub/root.go:runClient</code> 这个方法接收一个配置，去启动每一个单独的代理配置，传入cfgDir的情况下<br>使用<code>runMultipleClients</code>并发去起多个goroutinue，并在协程内部调用 <code>runClient</code> 启动每个配置内的代理，本质上还是调用的一个方法。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">runMultipleClients</span><span class="params">(cfgDir <span class="type">string</span>)</span></span> <span class="type">error</span> &#123;</span><br><span class="line">    <span class="keyword">var</span> wg sync.WaitGroup</span><br><span class="line">    err := filepath.WalkDir(cfgDir, <span class="function"><span class="keyword">func</span><span class="params">(path <span class="type">string</span>, d fs.DirEntry, err <span class="type">error</span>)</span></span> <span class="type">error</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> err != <span class="literal">nil</span> || d.IsDir() &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">        &#125;</span><br><span class="line">        wg.Add(<span class="number">1</span>)</span><br><span class="line">        time.Sleep(time.Millisecond)</span><br><span class="line">        <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">            <span class="keyword">defer</span> wg.Done()</span><br><span class="line">            err := runClient(path)</span><br><span class="line">            <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">                fmt.Printf(<span class="string">&quot;frpc service error for config file [%s]\n&quot;</span>, path)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;()</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;)</span><br><span class="line">    wg.Wait()</span><br><span class="line">    <span class="keyword">return</span> err</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果是多个client，那么程序会阻塞在这里，等待进程退出的信号，优雅关闭协程，回到cobra的命令行提示符，或是退出程序。</p><h5 id="启动单个代理"><a href="#启动单个代理" class="headerlink" title="启动单个代理"></a>启动单个代理</h5><p>从配置文件加载到配置，并且在内部调用了 每个config struct的 Complete方法 设定初始值。每一个 client的配置分为 common_cfg，proxyCfgs， visitorCfgs 三种，每一种都会有不同的用途。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">runClient</span><span class="params">(cfgFilePath <span class="type">string</span>)</span></span> <span class="type">error</span> &#123;</span><br><span class="line">cfg, proxyCfgs, visitorCfgs, isLegacyFormat, err := config.LoadClientConfig(cfgFilePath, strictConfigMode)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> err</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"><span class="keyword">return</span> err</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> startService(cfg, proxyCfgs, visitorCfgs, cfgFilePath)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>cfg是 client的连接信息，代表这个客户端和服务端的连接配置，一般放在 client配置里，比如  <code>serverAddr, serverPort, TLS, transport</code> 等这些信息，他是长连接的配置，比如说 Server端的地址和端口，传输配置等等。</p><p>而 proxyCfgs 则是 每一个代理通道配置，你比如一个TCP服务端口80，另外一个TCP服务端口81，再有一个HTTPS服务端口443，一个SSH服务端口22，等等，每个proxyCfg指向的Client地址端口背后一定要有个对应的服务，这样子才能对外映射，如果这个端口没有监听对应协议的服务，并不会报错，只是你这个通道就没有用。</p><p><del>这里的内容还没有确认，官方也没有文档描述他，所以我暂时只能靠我自己的理解去描述。</del><br>visitorCfgs 暂时我还没了解到，就暂时不管，下面放一个我按照他配置文件理解来的含义。<br>visitorCfgs 的作用按照配置文件来看的话，意思是比如你映射了一个http的网站或服务，这个网站是要求对外提供服务的，那使用你这个服务的人 都叫做visitor，那么每个 visitor 可以配置一个角色 以及用户名密码做鉴权。 不过这个不重要，等真的了解到哪个地步，再说。</p><p><code>startService</code> 传入了 配置，并且把配置路径也给传递给service对象，方便后面使用。</p><p>startService方法，判断协议 是 kcp 或是 quic时，注册优雅关闭协程的 channel，订阅 SIGINT&#x2F;SIGTERM 这两个信号，出现信号 将 当前 ctx 取消，此时当前请求的父子请求 均会被取消，当前程序即可退出。</p><p>startService 方法中 注册的 webServer 并不是我们期望的主服务器，后续调用 Run方法时，才是启动主服务器。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(svr *Service)</span></span> loopLoginUntilSuccess(maxInterval time.Duration, firstLoginExit <span class="type">bool</span>) &#123;</span><br><span class="line">xl := xlog.FromContextSafe(svr.ctx)</span><br><span class="line"></span><br><span class="line">loginFunc := <span class="function"><span class="keyword">func</span><span class="params">()</span></span> (<span class="type">bool</span>, <span class="type">error</span>) &#123;</span><br><span class="line">xl.Infof(<span class="string">&quot;try to connect to server...&quot;</span>)</span><br><span class="line">conn, connector, err := svr.login()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">xl.Warnf(<span class="string">&quot;connect to server error: %v&quot;</span>, err)</span><br><span class="line"><span class="keyword">if</span> firstLoginExit &#123;</span><br><span class="line">svr.cancel(cancelErr&#123;Err: err&#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">svr.cfgMu.RLock()</span><br><span class="line">proxyCfgs := svr.proxyCfgs</span><br><span class="line">visitorCfgs := svr.visitorCfgs</span><br><span class="line">svr.cfgMu.RUnlock()</span><br><span class="line">connEncrypted := <span class="literal">true</span></span><br><span class="line"><span class="keyword">if</span> svr.clientSpec != <span class="literal">nil</span> &amp;&amp; svr.clientSpec.Type == <span class="string">&quot;ssh-tunnel&quot;</span> &#123;</span><br><span class="line">connEncrypted = <span class="literal">false</span></span><br><span class="line">&#125;</span><br><span class="line">sessionCtx := &amp;SessionContext&#123;</span><br><span class="line">Common:        svr.common,</span><br><span class="line">RunID:         svr.runID,</span><br><span class="line">Conn:          conn,</span><br><span class="line">ConnEncrypted: connEncrypted,</span><br><span class="line">AuthSetter:    svr.authSetter,</span><br><span class="line">Connector:     connector,</span><br><span class="line">&#125;</span><br><span class="line">ctl, err := NewControl(svr.ctx, sessionCtx)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">conn.Close()</span><br><span class="line">xl.Errorf(<span class="string">&quot;NewControl error: %v&quot;</span>, err)</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>, err</span><br><span class="line">&#125;</span><br><span class="line">ctl.SetInWorkConnCallback(svr.handleWorkConnCb)</span><br><span class="line"></span><br><span class="line">ctl.Run(proxyCfgs, visitorCfgs)</span><br><span class="line"><span class="comment">// close and replace previous control</span></span><br><span class="line">svr.ctlMu.Lock()</span><br><span class="line"><span class="keyword">if</span> svr.ctl != <span class="literal">nil</span> &#123;</span><br><span class="line">svr.ctl.Close()</span><br><span class="line">&#125;</span><br><span class="line">svr.ctl = ctl</span><br><span class="line">svr.ctlMu.Unlock()</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// try to reconnect to server until success</span></span><br><span class="line">wait.BackoffUntil(loginFunc, wait.NewFastBackoffManager(</span><br><span class="line">wait.FastBackoffOptions&#123;</span><br><span class="line">Duration:    time.Second,</span><br><span class="line">Factor:      <span class="number">2</span>,</span><br><span class="line">Jitter:      <span class="number">0.1</span>,</span><br><span class="line">MaxDuration: maxInterval,</span><br><span class="line">&#125;), <span class="literal">true</span>, svr.ctx.Done())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Run方法中，比较重要的是 <code>loopLoginUntilSuccess</code> 这个方法，会执行登录操作，并从 Server拿到 runID，进行token校验等操作。这个是个TCP协议的接口。</p><p>他是我们Client和 Server建立连接的第一个请求，如果失败则无法建立通信，只有成功才可以建立，作者也知道这个方法很重要，使用了 Backoff 来 循环调用login，直到成功。<br>当登录成功后，会创建一个 Control 对象，并且执行Run方法，Run方法会启动本地Client端口监听，代表连接正式建立，然后执行 handleWorkConnCb 方法，这个方法会启动一个协程，用来监听本地端口，然后通过conn发送给Server，等待Server返回一个workConn，然后通过workConn和本地端口进行通信。</p><hr><p>未完待续…</p><h1 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h1><p><a href="https://jiajunhuang.com/articles/2019_06_11-frpc_source_code_part1.md.html">https://jiajunhuang.com/articles/2019_06_11-frpc_source_code_part1.md.html</a></p><p><a href="https://jiajunhuang.com/articles/2019_06_19-frp_source_code_part2.md.html">https://jiajunhuang.com/articles/2019_06_19-frp_source_code_part2.md.html</a></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;写Go好几年，基本没有看过开源项目代码，只是搬砖，说来惭愧，偶然和一个朋友开启Side Project，基于开源项目 &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/fatedier/frp&quot;&gt;FRP &lt;/a&gt;用来做一个内网穿透功能的工具，此项目在Github获得10.7K star，属于是超级硬核Project了。阅读一下大佬的源码，梳理一下思路，顺便写一下文章记录。&lt;/p&gt;</summary>
    
    
    
    <category term="FRP" scheme="https://blog.bh4fwa.com/categories/FRP/"/>
    
    <category term="源码阅读" scheme="https://blog.bh4fwa.com/categories/FRP/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/"/>
    
    <category term="Go" scheme="https://blog.bh4fwa.com/categories/FRP/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/Go/"/>
    
    <category term="开源" scheme="https://blog.bh4fwa.com/categories/FRP/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/Go/%E5%BC%80%E6%BA%90/"/>
    
    
    <category term="FRP" scheme="https://blog.bh4fwa.com/tags/FRP/"/>
    
    <category term="Go" scheme="https://blog.bh4fwa.com/tags/Go/"/>
    
    <category term="源码阅读" scheme="https://blog.bh4fwa.com/tags/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/"/>
    
    <category term="开源" scheme="https://blog.bh4fwa.com/tags/%E5%BC%80%E6%BA%90/"/>
    
  </entry>
  
  <entry>
    <title>新的Blog，第一篇，Blog搭建的经历</title>
    <link href="https://blog.bh4fwa.com/2024/04/23/16-00-00/"/>
    <id>https://blog.bh4fwa.com/2024/04/23/16-00-00/</id>
    <published>2024-04-23T16:00:00.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<h3 id="起初"><a href="#起初" class="headerlink" title="起初"></a>起初</h3><p>记得接触Hexo + Next 还是在大学的时候，当时用腾讯云的学生优惠，买了10元&#x2F;月的服务器，还备案了一下，搞blog。后来因为服务器需要一个月一个月的续期，而导致blog的数据差点全部废掉（虽然后面还是废掉了）。</p><span id="more"></span><h3 id="过程"><a href="#过程" class="headerlink" title="过程"></a>过程</h3><p>刚开始兴致勃勃，看了Jekyll，Hexo之类的静态服务，发现Hexo+ Next 也就是我现在这个方式，比较符合我的风格，比较简约，黑白的配色，功能也不错，可以有评论，还可以使用Markdown用来写作。于是便搭建起来了v1版本。后来不出意外的，烂尾了。因为当时是参考别人的教程搭建的，所以当时对hexo这东西也不了解，当时的方式是，在 <code>config.yaml</code> 中配置好github仓库地址，分支，使用Hexo 默认的 <code>hexo deploy</code> 命令 可以推送到<code>gh-pages</code> 分支，当时也是这么搞的。<br>但是这样子就会遇到一个问题，就是你的 markdown源文件，只能跟随 那个本地的 github项目 copy过来copy过去，而github上面推送的是markdown编译过后的html文件，所以如果想要更新博客，就需要固定到一台电脑上面，相当于放弃了WordPress，Typecho之类博客的便利性。当时也有另外的教程，教你怎么把 markdown文件推送到 Github的同名仓库中，大概意思是先 pull下来 github的仓库，除了<code>gh-pages</code> 分支以外，切出来一个<code>master</code>分支，把master分支伤的所有内容删除掉，用markdown的文件目录覆盖，再推送到<code>master</code>分支，这样子就会导致一个问题是，配置中的 类似 private key&#x2F;token 也会丢掉，所以这个操作也不太方便，甚至有些被滥用的危险存在。</p><h3 id="中转"><a href="#中转" class="headerlink" title="中转"></a>中转</h3><p>后来痛定思痛，尤其是工作以后，虽然每个月也不缺这几十块钱，也不能导致我突然暴富，但是越来越发现买服务器需要及时续费这个途径对我来说走不通，因为我记性不太好，经常性会忘记（太懒），所以大学时的我大概也是这么想的，在接触到 Github之后，了解到了 Github Pages服务，于是便开始了搭建踩坑的路。后来这博客 也断断续续 但是大多都废了。还是需要坚持做下去。</p><h3 id="转机"><a href="#转机" class="headerlink" title="转机"></a>转机</h3><p>也不能算是转机，过了好多年，博客也重建了好几次，但每次都感觉达不到预想中的样子。就在一个月之前，我搭建了这个blog，这次是使用WordPress搭建的，找了一个比较不错的主题，于是就又又建起来了。还写了两三篇文章，也有几篇在草稿里酝酿。<br><img src="/images/new_blog.png" alt="new_blog"><br>直到昨天，受到一个大佬的启发，又想搭建起来 Hexo + Next的 blog，访问了 hexo的主页。<code>https://hexo.io/zh-cn/docs/</code> 突然发现，<strong>在Github Pages的部署方式里，清晰的写着，可以直接将 hexo的 blog文件夹，直接全部提交到 github的仓库里，而无需去管生成的静态文件！！！</strong> 也可能是后面更新了，我没follow，也可能是早就出了这功能，只不过是当时我没看过，也不太了解。<br><img src="/images/hexo_github_deploy_page.png" alt="hexo_github_deploy_page"></p><h3 id="反思"><a href="#反思" class="headerlink" title="反思"></a>反思</h3><p>之前很多次情况也是，因为没有看过官网，又或是懒得看官网，导致踩坑无数。早年上大学时，使用百度用来搜索一些技术问题，练就了屎里刨金的一些辨别本领，当时自我感觉良好，但是谁知道为以后甚至是现在 留下了很多深坑。</p><p>所以说，以后做事，又或者是翻技术文档，还是要尽量去看权威的文档，如果一个事情权威的文档都没有或是没有覆盖到的情况下，再去带着批判的心态去看别人转载或是写的文档，作交叉验证。<br>还有就是，最近养成了强迫不用百度的习惯，百度搜索出来的内容，真的是越来越多狗屎了。现在再去狗屎里刨金，可能刨个好久结果自己被狗屎淹没了。尤其是类似 ChatGPT之类的AI大模型出来之后，百度也出了自己的文心一言，还是不如ChatGPT的。倒是有个KiMi.AI 比 百度文心一言 给出的答案靠谱一些，所以最近有在用。</p>]]></content>
    
    
    <summary type="html">&lt;h3 id=&quot;起初&quot;&gt;&lt;a href=&quot;#起初&quot; class=&quot;headerlink&quot; title=&quot;起初&quot;&gt;&lt;/a&gt;起初&lt;/h3&gt;&lt;p&gt;记得接触Hexo + Next 还是在大学的时候，当时用腾讯云的学生优惠，买了10元&amp;#x2F;月的服务器，还备案了一下，搞blog。后来因为服务器需要一个月一个月的续期，而导致blog的数据差点全部废掉（虽然后面还是废掉了）。&lt;/p&gt;</summary>
    
    
    
    <category term="Blog" scheme="https://blog.bh4fwa.com/categories/Blog/"/>
    
    <category term="博客" scheme="https://blog.bh4fwa.com/categories/Blog/%E5%8D%9A%E5%AE%A2/"/>
    
    
    <category term="Hello World" scheme="https://blog.bh4fwa.com/tags/Hello-World/"/>
    
    <category term="New Page" scheme="https://blog.bh4fwa.com/tags/New-Page/"/>
    
    <category term="Demo" scheme="https://blog.bh4fwa.com/tags/Demo/"/>
    
  </entry>
  
  <entry>
    <title>对火车的阴影</title>
    <link href="https://blog.bh4fwa.com/2024/04/11/16-00-00/"/>
    <id>https://blog.bh4fwa.com/2024/04/11/16-00-00/</id>
    <published>2024-04-11T16:00:00.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<p>我身体自小就不太好，小时候好像因为身体没少让家里花钱。</p><p>但是这个事情，发生在我工作以后的一段时间。正是因为这件事，让我从此对回家 或是坐长途火车有了一定的恐惧心理。</p><span id="more"></span><p>我记得那是2020年十一放假回家，从上海到洛阳，再从洛阳到我们的县级市，再坐车从县级市到镇上，再从镇上让亲人接到位于我们村南边的家里。一套流程下来，少说得24小时，也就是 我从中午12点从上海的火车站出发，到第二天12点都不一定能到家。同理，回来的时间，怕是也要远超24小时。回来的时间，一般是根据车票的时间来的，都会留足余量，在上海可能留个1小时提前到火车站就可以，但是因为我家是在村里，还要到镇上去坐车，然后再从镇上到县级市，再到洛阳市，每个流程都起码要等个10分钟到半小时不等，所以一般这个时间，会提前很久。</p><p>回家是正常的，倒是回来挺麻烦。当时我记得，还是不知道从哪个app上抢到一张 “接程票”，也就是要到一个地方转车，刚好上海离杭州比较近嘛，所以当时就选了从洛阳到杭州，然后再从杭州坐高铁到上海，这种方式。偏偏那趟车 是 凌晨大概 3-4点到杭州的，而上海的车 又是 6-7点开的，所以就留了一段在杭州的时间。</p><p>我记得那天是早上大概八九点，我姐把我送到了镇上，买了两桶泡面，其他的好像也买了点，但是对当时来说，可能是不太够的。当时不懂得人间疾苦，不太舍得给自己花钱，也没钱(虽然现在也没钱)，于是就少买了点东西，想着再怎么地也能到上海了，就没多买点东西。再然后就是从镇上到县级市，再到洛阳火车站，到洛阳车站的时候 已经是当天下午了。于是就去候车室去等着。当时还迷迷糊糊在洛阳车站睡了一觉。</p><p>上了火车，一夜硬座。从大概下午一直坐到晚上夜里12点。半夜就吃完了所有东西，当时想着也没什么事，硬撑着，只能饿着了。撑着到了杭州火车站，到了火车站就想着，反正也离上海不远了，不如到了再吃早饭吧，于是就进站在候车厅等着，发现还早，于是在候车厅椅子那里躺着睡觉。接近凌晨的杭州动车候车厅，没有人。由于候车厅椅子 并不能身体伸直，他也没有一个类似床板那种平整的东西，只能靠着背包睡，还是一条腿耷拉着睡，记不太清了，不过体验不太好。大概到凌晨五点多，有动车发车了，才有人进来等车。等上了开往上海的动车，已经早上大概六七点了。当时已经是属于强撑着了，当时也没想着在杭州买点东西吃，上车以后，我就趴在动车小桌板上睡觉。突然，一阵类似腿麻了的感觉，传来，我顿感不妙。</p><p>于是我便想喝点热水 又或者是上个厕所，走动一下，缓解一下。谁知道这个感觉越来越强烈，我当时起身的时候，便已经眼神有点恍惚，感觉有点天旋地转了。走到过道里，发现走不动道了，眼前开始发黑，而感官上，也逐渐感觉有点坐卧不安，虽然当时没有坐，但是有这种感觉，脑袋也不听使唤的开始时而后仰时而低沉，正在这个时候，眼前越来越黑，然后我就不太记得是什么情况了。只能想的起来，动车列车员把我抬起来，掐人中。慢慢睁开眼，意识也逐渐恢复了，他们喂我喝了瓶冰糖雪梨还是什么的，然后问了我要去哪里，留了我的手机号，说如果有什么事，会联系我。刚好下一站就是上海，所以就让我回到座位等一会，大概一小会就到站了。到站以后，在地铁站的自动贩卖机里买了瓶冰糖雪梨，喝了大半，立马就去挂了号，去看一下医生。当时看医生，我意识还是清醒的，于是走进医院准备挂普通门诊，谁知道问了导诊才知道，我要挂急诊。。。抽了血，检查了脑电波，同时也测了血糖，但是因为我后来喝了冰糖雪梨嘛，血糖当时好像有6.5，反正已经离开危险区域了。然后自然是一通乱查，也查不出来什么东西来。最后医生甚至给开了速效救心丸给我，速效救心丸到现在一粒也没吃过。</p><p>思考。后来我想了一下，不能这么样子了，于是偶尔几次不太敢回家，遇到回家的时候 就在上海不想回，刚好也恰逢疫情，有了借口不回去，过年在出租屋里天天煮火锅做饭吃，过年的时候甚至会胖一些，大概是过年吃的碳水多，蛋白质肉质也多吧。但是后来，我又想着，不能永远也不回家吧，所以每次回家之前，都点一大堆水果+饼干+零食，提都提不动那种，每次下车了还有好多，为的就是不再重蹈覆辙，几十块买一大堆东西吃总比饿出来病，危及生命又要几百块看个病，来的划算。于是便对火车这种出行方式，阴影少了几分。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;我身体自小就不太好，小时候好像因为身体没少让家里花钱。&lt;/p&gt;
&lt;p&gt;但是这个事情，发生在我工作以后的一段时间。正是因为这件事，让我从此对回家 或是坐长途火车有了一定的恐惧心理。&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>一个帝王之家没落，却又激起狼性，奋起直追直至反杀的故事（其一）</title>
    <link href="https://blog.bh4fwa.com/2024/03/31/16-00-00/"/>
    <id>https://blog.bh4fwa.com/2024/03/31/16-00-00/</id>
    <published>2024-03-31T16:00:00.000Z</published>
    <updated>2024-08-30T14:04:33.358Z</updated>
    
    <content type="html"><![CDATA[<h3 id="起始"><a href="#起始" class="headerlink" title="起始"></a>起始</h3><p>故事起于一个龙脉的诞生。自从怀上小A之时，命途多遄的皇后，开始了一场押上自己性命与决定整个王朝的走向的豪赌—–因为，自从她被皇上宠幸之后，这种场景已不是第一次发生了，如果说第一次发现自己怀孕，她还对自己的未来产生过美好的幻想，但此时，她不得不早早为自己的以后进行周密的布局。</p><span id="more"></span><p>在这诺大皇宫内有三千佳丽，无人不想被皇上翻牌子，为皇上顺利诞下龙子，但是奈何其余妃子都是选召来的，皇上甚至有些连看都不看一眼，而唯一有能力与自己抗争同时又能得皇上宠幸翻牌子的，莫过于秦妃，刘妃，李妃，以及除了自己以外最重要的 萍妃，其他妃子都是皇上微服私访，从民间宣召而来，而萍妃的来头，可是不小，萍妃与皇上本是青梅竹马，皇上认识萍妃时，还穿开裆裤呢，而且 萍妃的父亲，曾是戍边大将军，这些年为皇上征战沙场，攻城略地，可以说皇上能有今天的江山，大半都是此人负责打下，可谓功不可没，而萍大将军年轻时，曾有一次性命攸关的出征时，曾为小皇子与自己女儿在皇上面前请下婚约，若自己可以平安归来，便将幼年的萍儿与小皇上订下婚约，而年迈的皇上为了稳住萍大将军，在朝廷议事时，便许诺了下来，萍大将军得到老皇上的亲口许诺，且当庭见证下，便也奋勇直追，虽有大伤，但也是完好的将城池拿下来，并把此地命名为羊平关，这名字也是有讲究，平通萍，谐音梗，小皇子乳名叫做羊儿，以此来纪念老皇上与自己关于女儿与皇子的口头婚约。但奈何老皇上此时已经体弱多病，在一次伏案阅奏折时，不幸突发心脏病，突发晕厥，青睐太医来看，太医只说是一种怪病，自己也没有能力看出问题的关键，只能说问题的关键，是在找出关键的问题，一通乱说，也说不到根上，于是未能多久，老皇上便驾崩了，此时年幼的皇上还不知道自己将面临着什么，年幼的皇上便被霸王硬上弓，强行拉着坐上了龙椅，转眼间 皇上已经到了中年，也不乏微服私访，拐卖宣召进宫，其中的皇后便是皇上一次下江南时，在烟雨的苏州划船时，遇到的，于是皇上便合理的宣召进宫。后宫三千，当然不缺萍妃与皇后一个，但是在这三千嫔妃中，萍妃与皇后的姿色绝对是排得上前几的，他们两个当时还都是妃子时，是平起平坐，也无备份区分，于是皇上也并非暴遣世间天物，偶有安排翻到萍妃与未来的皇后的牌子，但萍妃就是干打雷不下雨，并未有一点声势，而此时，未来的皇后日渐隆起的肚子，便是自己皇后的喜兆，便召集宫中所有太医，三天两头往未来皇后这里跑，而孩子便也顺利生下，是个带把的，于是未来的皇后便稳稳的坐到了皇后这把交椅上，从妃子登基成为了皇后，稳稳地坐到了皇后椅子上，任凭任何人也无法撼动自己的地位。</p><h3 id="山雨欲来风满楼"><a href="#山雨欲来风满楼" class="headerlink" title="山雨欲来风满楼"></a>山雨欲来风满楼</h3><p>按说，这龙子诞下，自己也顺利登基成为皇后，不说是双喜，但也是一等一的大好事，但此时的皇后却无心顾及这些，因为她发现，自己好不容易怀胎十月生下的一任龙子，随着日渐长大，智力也逐渐显现出来问题，学习能力也有问题，别人孩子一年就差不多会走路了，但一任龙子到了一年，却站也站不起来，请来多方的太医看出来，发现是患了小儿肌无力+智力低下，需要多加看护，多加训练 后续也未能脱离人，需要细心看护直至成年，或许这过程中就突然好了，毕竟谁也无法保证 这病就一直无法根治，也无法保证这病不会根治。自此，这一任皇子不正常的消息便传来了，满朝大臣都在议论，甚至后宫情报中心便也开始了长舌妇的嚼舌根，以讹传讹，传到最后，便说 皇后是克夫，要把皇后赶出皇宫之类云云，但皇上并未听进去那些谣言，倒也确实是真的介意一任皇子的情况，刻意保持着与一任皇子以及皇后的间距，疏远了皇后，于是乎皇后这把交椅便也摇摇欲坠，不得安宁。</p><h3 id="后路-一不做二不休"><a href="#后路-一不做二不休" class="headerlink" title="后路 一不做二不休"></a>后路 一不做二不休</h3><p>眼看一任皇子差点要被舆论干翻，年轻的皇后也并未有经验，同时皇上也并未有翻自己牌子的迹象，于是便日日去城隍庙求土地公公保佑，也或许是因为皇后的诚实，又或是皇后的诚心，感动了天地，愚笨的皇后得到了一个城隍庙中一老尼姑的指引，那老尼姑出家之前，被负心汉所抛弃，于是来到城隍庙削发为尼，在城隍庙从姿色翩翩至人到老年，皱纹爬上满脸。同时也因城隍庙中为神邸，老尼姑在城隍庙听过太多人的故事，而土地也未能全部显灵，故而养得一颗心狠手辣，阴险恶毒之性格，但对外人一般不显露，外人看起来，满脸皱纹，和蔼可亲，对人也很有礼貌。只是皇后多次过来，而老尼姑也实在是看不下去了，便告诉皇后，只要你回去以后按我说的去做，我保准你未来高枕无忧，同时还可成为皇太后，掌管天下，垂帘听政，一人之下 万人之上。同时一任皇子还可以安心顺利的长大，按照你现在这个形势，一任皇子在宫中怕是要落为别人的笑柄，贻笑大方，以后大家只要提起你来，便会想起一任皇子是个傻子，而你还在一直养着那个傻子。这在寻常人家 是在正常不过，但这里是皇宫之中，覆墙之下，又岂无白骨，岂有完人。于是皇后回去便按照城隍庙的老师傅嘱咐的去做。</p><h3 id="明修栈道，暗渡陈仓，狸猫换太子，接一任皇子出宫"><a href="#明修栈道，暗渡陈仓，狸猫换太子，接一任皇子出宫" class="headerlink" title="明修栈道，暗渡陈仓，狸猫换太子，接一任皇子出宫"></a>明修栈道，暗渡陈仓，狸猫换太子，接一任皇子出宫</h3><p>老尼姑先是教皇后，在适当的时候，伪造一任皇子的自杀，老尼姑借着城隍庙出去采购的机会，顺势帮皇后在皇宫外 找了个与一任皇子一抹年纪，也有些相仿的孩子，告诉孩子的父母，孩子是送进来享福的，所以孩子的父母也很安心将孩子送进来，送进来之后，皇后和一任皇子说，与这农人孩子玩角色扮演的游戏，费力将两个孩子衣服互换，再将一任皇子以农人孩子的身份，送出了皇宫，之后留在皇宫中的假的一任皇子，皇后便命人将其伪造成意外死亡，结束了农人孩子的性命。不得不说，农人孩子的性命，就如同你我一般随风飘摇，如同一只雏鸡，和一只大手一般轻而易举的被捏死。</p>]]></content>
    
    
    <summary type="html">&lt;h3 id=&quot;起始&quot;&gt;&lt;a href=&quot;#起始&quot; class=&quot;headerlink&quot; title=&quot;起始&quot;&gt;&lt;/a&gt;起始&lt;/h3&gt;&lt;p&gt;故事起于一个龙脉的诞生。自从怀上小A之时，命途多遄的皇后，开始了一场押上自己性命与决定整个王朝的走向的豪赌—–因为，自从她被皇上宠幸之后，这种场景已不是第一次发生了，如果说第一次发现自己怀孕，她还对自己的未来产生过美好的幻想，但此时，她不得不早早为自己的以后进行周密的布局。&lt;/p&gt;</summary>
    
    
    
    <category term="故事会" scheme="https://blog.bh4fwa.com/categories/%E6%95%85%E4%BA%8B%E4%BC%9A/"/>
    
    <category term="短篇故事" scheme="https://blog.bh4fwa.com/categories/%E6%95%85%E4%BA%8B%E4%BC%9A/%E7%9F%AD%E7%AF%87%E6%95%85%E4%BA%8B/"/>
    
    <category term="自创" scheme="https://blog.bh4fwa.com/categories/%E6%95%85%E4%BA%8B%E4%BC%9A/%E7%9F%AD%E7%AF%87%E6%95%85%E4%BA%8B/%E8%87%AA%E5%88%9B/"/>
    
    
    <category term="WordPress迁移文章" scheme="https://blog.bh4fwa.com/tags/WordPress%E8%BF%81%E7%A7%BB%E6%96%87%E7%AB%A0/"/>
    
    <category term="故事会" scheme="https://blog.bh4fwa.com/tags/%E6%95%85%E4%BA%8B%E4%BC%9A/"/>
    
    <category term="故事会短篇" scheme="https://blog.bh4fwa.com/tags/%E6%95%85%E4%BA%8B%E4%BC%9A%E7%9F%AD%E7%AF%87/"/>
    
  </entry>
  
  <entry>
    <title>我从认识一个朋友到他消失的故事--细思极恐</title>
    <link href="https://blog.bh4fwa.com/2024/03/29/16-00-00/"/>
    <id>https://blog.bh4fwa.com/2024/03/29/16-00-00/</id>
    <published>2024-03-29T16:00:00.000Z</published>
    <updated>2024-08-30T14:04:33.354Z</updated>
    
    <content type="html"><![CDATA[<p>观前声明：本文写的都是按照自己的理解随便写的，就当看个乐子。</p><p>故事大概要从10年前开始讲，大概是12还是13年吧。我家里买了第一台电脑开始讲起，因为种种机缘巧合，在QQ群里认识了一群比较聊的来的人，其中就包含了这个故事的男主，既然是男主就叫他老A吧。</p><span id="more"></span><p>老A的属性大概是贵州的一个山村的留守儿童或是年少辍学，我认识他的时候初中有可能还没毕业。老B，是当时我们那个群的群主，是个河北人，热爱技术 对人比较好，重要的是，他当时做了个和现在服务器IDC 类似的业务，而且是免费给人用，所以才有了这个群。</p><p>当时国内互联网可能还处在发展期，淘宝当时的名气，不能说是人尽皆知，也能说的算家喻户晓了。当时QQ这种app还没有要求强制实名认证，而且还有QQ钱包这种支付功能，所以各种诈骗贩卖源码盗号以及QQ群里各种被骗层出不穷，以及贩卖各种信息的人大多是在QQ群交易和活跃，当时网上信息流通还比较自由，也比较野蛮，后来因为反诈，互联网账户要求实名制，这种事情才有了一定程度伤的收敛，当时如果你稍微懂一点技术，做个网站，没准也许就能做成 “大买卖”，丝毫不差现在直播这种热度。</p><p>但是奈何当时家里才买了电脑，电脑在我们看来都是新鲜玩意，还没摆弄明白呢，那里有心思想着赚钱。当时人们另外一个比较流行的搭建网站的用途，是做个人blog，在当时的互联网上有一个自己的内容发布网站，我就是当时 开始玩上技术这些东西的。</p><p>总结一下，当时大多是用来做“大买卖” 又或是搭建 blog，那么当时所需要的资源呢？当时服务器和域名，已经有比较大的IDC去卖，类似像阿里云腾讯云那样子的，但是当时大家大多是没成年的小孩子或是不想买阿里云腾讯云，所以就有些脑子活络的人，买一台性能还不错的VPS，大约是2核4G，撑死这么高配置，2核4G当时在年幼的我心里都是很大一笔开销，算是服务器的高配置了（但是后来我开始工作的时候第一家公司，起步 2-4 甚至 4-8，就很伤人，哈哈哈哈）。搭建免费空间的方式，吸引大家来免费玩一段时间，继而再扩展收费业务的方式来赚点小钱，老B就是一个典型的这种脑子比较活络的人，所以才有了这个群。这个群人到最后 发展的很多，最少也有个几百个人吧，后来人越来越多，老B发现他管不过来了，于是他就招募几个志愿者，在群里帮大家 解答一些问题，顺带手帮忙处理问题，也给了群管理。我当时还是在高中，应该没到高三，因为当时能搭建的起自己的网站嘛，所以我就联系了群主，顺势成为了群管理。老A也是类似的情节，他本身比较闲可能是，于是大家一起成为了管理，后来群主还拉了个我们几个的群，一来二去，每次过年都会玩一下，开个视频聊个天，发个小红包之类的，也算是几个老朋友了。</p><p>事情的转折大概出现在2019-2021年左右。当时老A 和我们也会偶尔聊天，我当时已经从大学毕业了，进入了社会开始工作了。老A偶尔会有转场，大概意思就是从A地点回老家服务器带不走在群里抛售，于是我便比较关注老A，因为我是学软件工程的嘛，对服务器这种比较感兴趣，所以偶尔有低价服务器抛售 我自然是想要收的，能花点小钱玩到服务器，比较好玩，也算是给社畜生活增加一些乐趣吧。然后老A开始时不时和我们讲他的故事，他的故事也是个很离谱的故事。</p><p>因为他的老爸老妈离异了，所以他被迫就要选择跟哪一边，对十几岁的他来说，也是个不小的打击。虽然没有体会到父母离异，但是想想也不会很好过。他就选择了跟着他妈妈，早下学了，在贵州一个城镇上，当时还学一些 类似 网页制作，后端代码之类的，偶尔也会搞一些酷炫的（但是没什么用）程序给我们玩，也会和我们讲他新买的服务器，还拍了照给我们看，可惜聊天记录没留下来。后来有一天，他给我们讲 有个大单上门了，对方老板 邀请了他去缅甸又或是云南，坐直升机去玩，因为大家都知道这些东西是啥嘛，所以就一直劝他不要去，他回来之后 发给我们的就是一些 类似 “菠菜网站” 后台之类的截图。菠菜网站，说要做的技术的话，其实技术要求也不是很高，但是主要是来钱快，风险也高，被抓的话 就是刑事犯罪，于是他偶尔就在那里做，大家都没管他，都想着他是一个成年人了，也应该有自己的判断了。</p><p>然后事情开始急转直下，他有段时间就一直在抛售服务器，像是已经知道什么事一样，我当时还差一点收到他的一个服务器，后来他开始慢慢发言少了，于是我们大家开始着急，因为大家都偶尔会聊天嘛，就他一直不在，所以就会找他，但是无论是从已经公开的信息来看，又或者是从 某些机构的公开信息来看，都没有蛛丝马迹，能查得到的，只有他在2021年5月12日，报了公司的年报，自此以后 再无音信。</p><p>到如今，3年快过去了，我们也去政府机关的公开信息查了很多信息，一直都没有，老B找了A当时的女朋友，也没有回信。</p><p>以下是几个合理且很自然的猜测。</p><p>1.老A被JC抓了，但是因为某些原因，没有在公开信息渠道发布，真要是被抓了，倒还不是最严重，最恐怖的，我们只能期望他被JC抓了。</p><p>2.老A 因为某些原因，躲起来了，总之因为某些原因无法和我们取得联系，这个倒是对他来说 最好的情况。</p><p>3.老A因为某些原因，类似被车撞了又或者是被人伤害，精神不正常或者是无法正常，这个也并不是最恐怖的。</p><p>4.老A被抓去了缅甸，又或者是老A被缅甸的高薪工作吸引过去了，这个就很恐怖了，人还是不是全的，是不是处在正常状态，甚至于 骨灰还在不在 我们就都不知道了，也有可能被埋进了 芭蕉地，做肥料了，又或者是零件被回收利用了罢。</p><p>5.以上。这篇文章是我对上高中那时候的早期互联网的一小片记忆，如果写的有误，请麻烦 评论一下，我会修改一下，谢谢。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;观前声明：本文写的都是按照自己的理解随便写的，就当看个乐子。&lt;/p&gt;
&lt;p&gt;故事大概要从10年前开始讲，大概是12还是13年吧。我家里买了第一台电脑开始讲起，因为种种机缘巧合，在QQ群里认识了一群比较聊的来的人，其中就包含了这个故事的男主，既然是男主就叫他老A吧。&lt;/p&gt;</summary>
    
    
    
    <category term="回忆录" scheme="https://blog.bh4fwa.com/categories/%E5%9B%9E%E5%BF%86%E5%BD%95/"/>
    
    
    <category term="回忆录" scheme="https://blog.bh4fwa.com/tags/%E5%9B%9E%E5%BF%86%E5%BD%95/"/>
    
    <category term="早期记忆" scheme="https://blog.bh4fwa.com/tags/%E6%97%A9%E6%9C%9F%E8%AE%B0%E5%BF%86/"/>
    
    <category term="WordPress迁移文章" scheme="https://blog.bh4fwa.com/tags/WordPress%E8%BF%81%E7%A7%BB%E6%96%87%E7%AB%A0/"/>
    
  </entry>
  
</feed>
