找到
8
篇与
博客
相关的结果
-
为你的Typecho博客添加一个访问统计 前引 在之前的静态Hexo 中借助的是第三方的统计平台,现在转到动态博客下,有了自己的数据库就没有必要再使用第三方的统计;于是就有了typecho访问统计插件TeohVist github地址: {% link github,TeohVisit,https://github.com/mstzf/TeohVisit.git %} 插件实现的功能非常简单,就只是记录了访问数据,和在需要的界面提供数据 安装 将代码克隆到typecho插件目录,在管理后台找到 TeohVisit 之间开启使用即可 git clone https://github.com/mstzf/TeohVisit.git使用 具体使用需要修改主题源码,或者自定义独立界面模板 插件提供了两种读取数据的方法 getStat:返回所需要的单个值,具体值为:today,yesterday,month,total getAllStats:返回全部数据 示例: if (TeohVisit_Plugin::isPluginEnabled()) { $stats = TeohVisit_Plugin::getAllStats(); $data = [ 'today_unique_visitors' => $stats['today']['unique_visitors'], 'today_views' => $stats['today']['views'], 'yesterday_unique_visitors' => $stats['yesterday']['unique_visitors'], 'yesterday_views' => $stats['yesterday']['views'], 'month_total_views' => $stats['month']['total_views'], 'total_total_views' => $stats['total']['total_views'] ]; } -
TeoTag:在typecho中使用和butterfly一样的外挂标签 {% label 声明: red %} 绝大部分的样式都是hexo butterfly的原生样式,本人只是将功能在typecho中做了相应的移植。 {% link Butterfly,Butterfly,https://butterfly.js.org/ %} 我只是站在了巨人的肩膀上 为什么会有TeoTag 在此之前,博客使用了Hexo框架和Butterfly主题,文章内有很多样式都使用了Butterfly主题的写作语法;这两天将博客迁移到了typecho下,导致文章的很多非MarkDown格式内容都没法和原来一样正常显示,重新修改起来也比较麻烦,就想着把之前在Butterfly下的格式全部般过来,便有了TeoTag这个插件。 {% link TeoTag,github,https://github.com/mstzf/TeoTags %} 现有功能 Note Tabs label timeline link hideToggle 语法和渲染结果 和Butterfly一样的用法 Butterfly Note {% note simple %} 默认 提示块标签 {% endnote %} {% note default simple %} default 提示块标签 {% endnote %} {% note primary simple %} primary 提示块标签 {% endnote %} {% note success simple %} success 提示块标签 {% endnote %} {% note info simple %} info 提示块标签 {% endnote %} {% note warning simple %} warning 提示块标签 {% endnote %} {% note danger simple %} danger 提示块标签 {% endnote %} {% note simple %} 默认 提示块标签 {% endnote %} {% note default simple %} default 提示块标签 {% endnote %} {% note primary simple %} primary 提示块标签 {% endnote %} {% note success simple %} success 提示块标签 {% endnote %} {% note info simple %} info 提示块标签 {% endnote %} {% note warning simple %} warning 提示块标签 {% endnote %} {% note danger simple %} danger 提示块标签 {% endnote %} Tabs {% tabs test1 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %}{% tabs test1 %} This is Tab 1. This is Tab 2. This is Tab 3. {% endtabs %} {% tabs test2, 3 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %}{% tabs test2, 3 %} This is Tab 1. This is Tab 2. This is Tab 3. {% endtabs %} {% tabs test3, -1 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %}{% tabs test3, -1 %} This is Tab 1. This is Tab 2. This is Tab 3. {% endtabs %} {% tabs test4 %} <!-- tab 第一个Tab --> **tab名字为第一个Tab** <!-- endtab --> <!-- tab @fab fa-apple-pay --> **只有图标 没有Tab名字** <!-- endtab --> <!-- tab 炸弹@fas fa-bomb --> **名字+icon** <!-- endtab --> {% endtabs %}{% tabs test4 %} tab名字为第一个Tab 只有图标 没有Tab名字 名字+icon {% endtabs %} label 臣亮言:{% label 先帝 %}创业未半,而{% label 中道崩殂 blue %}。今天下三分,{% label 益州疲敝 pink %},此诚{% label 危急存亡之秋 red %}也!然侍衞之臣,不懈于内;{% label 忠志之士 purple %},忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气;不宜妄自菲薄,引喻失义,以塞忠谏之路也。 宫中、府中,俱为一体;陟罚臧否,不宜异同。若有{% label 作奸 orange %}、{% label 犯科 green %},及为忠善者,宜付有司,论其刑赏,以昭陛下平明之治;不宜偏私,使内外异法也。臣亮言:{% label 先帝 %}创业未半,而{% label 中道崩殂 blue %}。今天下三分,{% label 益州疲敝 pink %},此诚{% label 危急存亡之秋 red %}也!然侍衞之臣,不懈于内;{% label 忠志之士 purple %},忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气;不宜妄自菲薄,引喻失义,以塞忠谏之路也。 宫中、府中,俱为一体;陟罚臧否,不宜异同。若有{% label 作奸 orange %}、{% label 犯科 green %},及为忠善者,宜付有司,论其刑赏,以昭陛下平明之治;不宜偏私,使内外异法也。 timeline {% timeline 2022 %} <!-- timeline 01-02 --> 这是测试页面 <!-- endtimeline --> {% endtimeline %}{% timeline 2022 %} 这是测试页面 {% endtimeline %} {% timeline 2022,pink %} <!-- timeline 01-02 --> 这是测试页面 <!-- endtimeline --> {% endtimeline %}{% timeline 2022,pink %} 这是测试页面 {% endtimeline %} 颜色可取: blue pink red purple orange green link 这部分使用的是 (张洪Heo - 分享设计与科技生活 (zhheo.com)) 的样式 {% link 获取网站的Favicon图标并显示在你的网页上,owen0o0,https://github.com/owen0o0/getFavicon %}{% link 获取网站的Favicon图标并显示在你的网页上,owen0o0,https://github.com/owen0o0/getFavicon %} {% link TeohZY,TeohZY,https://blog.teohzy.com %}{% link TeohZY,TeohZY,https://blog.teohzy.com %} hideToggle {% hideToggle 标题 %} 内容1 内容2 内容3 {% endhideToggle %}{% hideToggle 标题 %} 内容1 内容2 内容3 {% endhideToggle %} -
树莓派+EC20模块实现连接蜂窝网和短信收发 软硬件 树莓派 ec20 wvdial gammu SIM卡 EC20模块 概述 EC20-CE是移远通信最近推出的LTE Cat 4无线通信模块,采用LTE 3GPP Release 11 技术,支持最大下行速率 150 Mbps和最大上行速率50 Mbps;同时在封装上兼容移远通信多网络制式LTE EC21系列、EC25系列和EG25-G 模块,实现了3G网络与4G网络之间的无缝切换。 EC20-CE采用镭雕工艺,镭雕工艺具有外观更漂亮、金属质感强、散热更好、信息不容易被抹除、更能适应自动化需求等优点。 EC20-CE内置多星座高精度定位GNSS(GPS/GLONASS/BDS/Galileo/QZSS)接收机;在简化产品设计的同时,还大大提升了定位速度及精度。 EC20-CE内置丰富的网络协议,集成多个工业标准接口,并支持多种驱动和软件功能(适用于Windows 7/8/8.1/10/11、Linux、Android等操作系统下的USB驱动等),极大地拓展了EC20-CE在M2M领域的应用范围,如CPE、路由器、数据卡、平板电脑、车载、智能安全以及工业级PDA等。 产品特性 更多详情可到官网查看 {%link LTE EC20-CE,QUECTEL,https://www.quectel.com.cn/product/lte-ec20-ce %} 产品手册 Quectel_Product_Brochure_CN_V7.8) 查看设备是否挂载成功 使用命令 sudo ls /dev |grep ttyUSB挂载成功会有如图输出 要是没有看到设备则检查设备是否稳定插入、更换USB口或者重启设备之后再重新使用命令查看 拨号上网 wvdial 安装 wvdial是一个方便使用的PPP拨号模块,它能调用调制调节器,并通过PPP上网,无需像手动拨号一样配置繁琐的文件 sudo apt update sudo apt install wvdial 配置 修改配置文件 sudo vim /etc/wvdial.conf 可以继续使用 [Dialer Defaults]也可以重新根据自己需要添加,我这里为了没有多余手机卡,也为了方便输入命令,就直接使用 电信/移动SIM卡使用以下配置 [Dialer Defaults] Init1 = ATZ Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 Modem Type = Analog Modem Modem = /dev/ttyUSB3 Baud = 115200 New PPPD = yes ISDN = 0 Phone = *99# Username = card Password = card联通卡使用以下配置 [Dialer Defaults] Init1 = ATZ Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 Init3 = at+cgdcont=1,"ip","uninet" Modem Type = Analog Modem Modem = /dev/ttyUSB3 Baud = 115200 New PPPD = yes ISDN = 0 Phone = *99# Password = card Username = card配置来源于 Quectel EC20 在 Linux 上的使用 在配置文件中大部分都不需要自己调整,只有Modem和Baud需要根据自己设备情况进行调整 Modem:根据情况选择合适的设备我的这个ttyUSB2和ttyUSB3都能正常使用 Baud:根据情况选择合适的波特率,对于ec20来说9600-115200都可以 启动wvdial sudo wvdial 查看网络设备 ifconfig 可以看到多了ppp0和wwan0两个设备 正常情况还无法访问网络,因为默认路由在其他网络设备中,需要重新配置路由 配置路由 查看路由 sudo route配置路由的方式有很多种,我这里的方法比较简单粗暴,需要具体配置的可自己查找方法 sudo route add default dev ppp0该命令会在路由表中添加一条新的默认路由 在每次重启后都会刷新路由,可以将命令加到/etc/rc.local中,每次开机都执行添加方法 sudo vim /etc/rc.local在exit 0前添加 su - root -c `route add default dev ppp0`通过systemctl来管理wvdial 开机自启wvdial的方法有很多种,并不一定要使用systemctl 最简单的就是和添加路由一样,在/etc/rc.local中添加启动命令 sudo vim /etc/rc.local # 添加 wvdial & 编写控制wvdial启动和检测wvdial运行脚本 新建sh脚本文件,可以放到你想存放的地方 我这里在root用户下/root/shell中 sudo mkdir /root/shell && cd shell # 名字可以任起 sudo vim onwvdial.shwvdial控制脚本内容 #!/bin/bash DEVICE_NAME="/dev/ttyUSB3" # 和wvdial配置设备一致 LOG_FILE="/var/log/wvdial_on.log" # 日志文件存储位置 PROCESS_NAME=(wvdial pppd) # 需检查占用软件 # 定义函数检查进程是否占用设备 check_device_usage() { local process_name=$1 local device=$2 local pids=$(pgrep -f "$process_name") if [ -z "$pids" ]; then return fi for pid in $pids; do echo "pid:$pid" local device_count=$(lsof -p "$pid" 2>/dev/null | grep -e "$device" | wc -l) if [ "$device_count" -gt 0 ]; then echo "占用设备:$device" kill $pid fi done return } function check_wvdial() { if pgrep -x "wvdial" >/dev/null; then return 0 # wvdial 进程在运行 else return 1 # wvdial 进程未运行 fi } for process in $PROCESS_NAME; do echo "进程名: $process" check_device_usage $process $DEVICE_NAME done wvdial >> "$LOG_FILE" 2>&1 & route add default dev ppp0 while true;do if ! check_wvdial;then echo "$(date +"%Y-%m-%d %H:%M:%S") - wvdial 进程未运行,正在重新启动..." >> "$LOG_FILE" wvdial >> "$LOG_FILE" 2>&1 & fi sleep 120 done该脚本包含功能: 停止wvdial启动前所需设备的占用 启动wvdial 添加ppp0默认路由 每120秒检测wvdial是否运行 记录启动、错误日志 设置可执行权限 sudo chmod u+x /root/shell/onwvdial.sh 编写systemctl控制文件 sudo vim /etc/systemd/system/wvdial_on.service配置文件内容如下: [Unit] Description=Safe Start Wvadil After=dev-ttyUSB3.device Requires=dev-ttyUSB3.device [Service] User=root Group=root ExecStart=/root/shell/onwvdial.sh # 路径根据自己配置修改 [Install] WantedBy=multi-user.target 启动服务 systemctl daemon-reload systemctl start wvdial_on.service systemctl enable wvdial_on.service设置自启动后就不需要在/etc/rc.local中添加修改路由和启动wvdial命令了 配置防火墙 如果在ec20模块连接4G网络后还需要使用wifi则需要配置防火墙,不需要则不用配置 sudo iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE sudo iptables -A FORWARD -i ppp0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i wlan0 -o ppp0 -j ACCEPT 将防火墙规则写入文件 sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"顺序执行命令即可 收发短信 安装软件gammu sudo apt install gammu gammu-smsd 配置gammu 使用命令 sudo gammu-config配置可参考我的 或者直接修改/root/.gammurc,效果是一样的 如果没有/root/.gammurc文件就使用命令 [gammu] port = /dev/ttyUSB2 model = connection = at19200 synchronizetime = yes logfile = logformat = nothing use_locking = no gammuloc =修改 /etc/gammu-smsdrc [gammu] # Please configure this! port = /dev/ttyUSB2 connection = at19200 # Debugging #logformat = textall # SMSD configuration, see gammu-smsdrc(5) [smsd] service = files logfile = syslog RunOnReceive = /root/msmtp/sh/send-smsd.sh # 发送邮件脚本 # Increase for debugging information debug = yes #debuglevel = 0 # Paths where messages are stored inboxpath = /var/spool/gammu/inbox/ outboxpath = /var/spool/gammu/outbox/ sentsmspath = /var/spool/gammu/sent/ errorsmspath = /var/spool/gammu/error/ 编辑收到短信后自动发送邮件脚本 树莓派配置邮件这里不再赘述,可以自行搜索,或者参考我之前的一篇博客 {% link 树莓派开机自动发送邮件,TeohZY,https://blog.teohzy.com/posts/smpxjfsyj/ %} 编辑脚本 vim /root/msmtp/sh/send-smsd.sh文件路径根据自己需要修改 #!/bin/bash for i in `seq $SMS_MESSAGES` ; do if [ $i -eq 1 ]; then phone="$SMS_1_NUMBER" fi tmp="$(eval echo '$'SMS_${i}_TEXT)" message="$text$tmp" done echo "$message" |mutt -s "树莓派短信转发" xxx@163.com 重启gammu systemctl restart gammu-smsd.service 短信测试 向目标号码发送短信后邮箱能收到短信 通过终端向其他号码发送短信 gammu-smsd-inject TEXT 目标号码 -text '短信内容' -unicode如果收到短信说明配置成功 短信发送失败踩坑 查看端口占用 sudo lsof /dev/ttyUSB2如果有其他进程和gammu-sms占用设备,可以使用kill命令结束非必须进程 设备波特率和wvdial重复 检查wvdial配置和gammu配置,如果wvdial已经使用了ttyUSB3和波特率115200则gammu配置中就不要再使用相同设备和波特率,可以使用ttyUSB2和波特率at19200 ModemManager占用设备 查看设备后发现有进程ModemMnana在使用设备,可以停用ModemManager 需要考虑实际使用情况来判断,在确认ModemManager确实不是必要软件后再进行操作 sudo systemctl disable ModemManager.service sudo systemctl stop ModemManager.service -
SSM开发环境搭建(小白自用) 前言 将SSM作为后端的的一个项目即将完工,在开发过程中踩了很多坑,与此同时也学习到了新知识,有了不小收获。在遇到麻烦和解决麻烦的路上,受到了很多分享教程博主的帮助。为了将帮助延续下去,我也将自己SSM环境配置的过程做了简单的纪录、分享。 系统软件版本 Windows 10 专业版 22H2 IntelliJ IDEA 2022.3.3 MySQL 8.0.32 Java 19.0.2 Spring 6.0.6 MyBatis 3.5.13 Tomcat 11.0.0 (软件系统版本不用完全一致,不同版本之间可能会出现一定程度的兼容性问题,可在有问题时在寻找对应版本的解决办法) 新建项目及项目配置 新建项目 使用IDEA新建一个空的默认Maven项目,并新建Java包完善SSM项目架构。 在新建controller包(表现层)、dao包(持久层)、service包(业务层) 在resources下新建db(存放数据库相关配置文件)、log(存放日志相关配置文件)、spring(存放与spring与其他整合相关配置文件) image-20230507141558542图片 修改Maven配置文件 使用默认Maven配置文件,在下载包时会比较慢,我们可以修改配置文件使用国内镜像来加速下载 IDEA内修改路径为File->Settings->Builde,Execution,Deployment->Maven 可以修改默认的文件,也可以重新使用一个自定义的配置文件,笔者这里使用了重新新建一个配置文件的方法。 image-20230507142114670图片 其中settings.xml文件中内容如下: <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- | This is the configuration file for Maven. It can be specified at two levels: | | 1. User Level. This settings.xml file provides configuration for a single user, | and is normally provided in ${user.home}/.m2/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -s /path/to/user/settings.xml | | 2. Global Level. This settings.xml file provides configuration for all Maven | users on a machine (assuming they're all using the same Maven | installation). It's normally provided in | ${maven.conf}/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -gs /path/to/global/settings.xml | | The sections in this sample file are intended to give you a running start at | getting the most out of your Maven installation. Where appropriate, the default | values (values used when the setting is not specified) are provided. | |--> <settings xmlns="http://maven.apache.org/SETTINGS/1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd"> <!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> --> <!-- interactiveMode | This will determine whether maven prompts you when it needs input. If set to false, | maven will use a sensible default value, perhaps based on some other setting, for | the parameter in question. | | Default: true <interactiveMode>true</interactiveMode> --> <!-- offline | Determines whether maven should attempt to connect to the network when executing a build. | This will have an effect on artifact downloads, artifact deployment, and others. | | Default: false <offline>false</offline> --> <!-- pluginGroups | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e. | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list. |--> <pluginGroups> <!-- pluginGroup | Specifies a further group identifier to use for plugin lookup. <pluginGroup>com.your.plugins</pluginGroup> --> </pluginGroups> <!-- proxies | This is a list of proxies which can be used on this machine to connect to the network. | Unless otherwise specified (by system property or command-line switch), the first proxy | specification in this list marked as active will be used. |--> <proxies> <!-- proxy | Specification for one proxy, to be used in connecting to the network. | <proxy> <id>optional</id> <active>true</active> <protocol>http</protocol> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> </proxy> --> </proxies> <!-- servers | This is a list of authentication profiles, keyed by the server-id used within the system. | Authentication profiles can be used whenever maven must make a connection to a remote server. |--> <servers> <!-- server | Specifies the authentication information to use when connecting to a particular server, identified by | a unique name within the system (referred to by the 'id' attribute below). | | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are | used together. | <server> <id>deploymentRepo</id> <username>repouser</username> <password>repopwd</password> </server> --> <!-- Another sample, using keys to authenticate. <server> <id>siteServer</id> <privateKey>/path/to/private/key</privateKey> <passphrase>optional; leave empty if not used.</passphrase> </server> --> </servers> <!-- mirrors | This is a list of mirrors to be used in downloading artifacts from remote repositories. | | It works like this: a POM may declare a repository to use in resolving certain artifacts. | However, this repository may have problems with heavy traffic at times, so people have mirrored | it to several places. | | That repository definition will have a unique id, so we can create a mirror reference for that | repository, to be used as an alternate download site. The mirror site will be the preferred | server for that repository. |--> <mirrors> <!-- mirror | Specifies a repository mirror site to use instead of a given repository. The repository that | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used | for inheritance and direct lookup purposes, and must be unique across the set of mirrors. | <mirror> <id>mirrorId</id> <mirrorOf>repositoryId</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://my.repository.com/repo/path</url> </mirror> --> <mirror> <id>aliment</id> <name>aliyah maven</name> <url>https://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>uk</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>https://uk.maven.org/maven2/</url> </mirror> <mirror> <id>CN</id> <name>OSChina Central</name> <url>https://maven.oschina.net/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>nexus</id> <name>internal nexus repository</name> <!-- <url>http://192.168.1.100:8081/nexus/content/groups/public/</url>--> <url>https://repo.maven.apache.org/maven2</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <!-- profiles | This is a list of profiles which can be activated in a variety of ways, and which can modify | the build process. Profiles provided in the settings.xml are intended to provide local machine- | specific paths and repository locations which allow the build to work in the local environment. | | For example, if you have an integration testing plugin - like cactus - that needs to know where | your Tomcat instance is installed, you can provide a variable here such that the variable is | dereferenced during the build process to configure the cactus plugin. | | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles | section of this document (settings.xml) - will be discussed later. Another way essentially | relies on the detection of a system property, either matching a particular value for the property, | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'. | Finally, the list of active profiles can be specified directly from the command line. | | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact | repositories, plugin repositories, and free-form properties to be used as configuration | variables for plugins in the POM. | |--> <profiles> <!-- profile | Specifies a set of introductions to the build process, to be activated using one or more of the | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/> | or the command line, profiles have to have an ID that is unique. | | An encouraged best practice for profile identification is to use a consistent naming convention | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc. | This will make it more intuitive to understand what the set of introduced profiles is attempting | to accomplish, particularly when you only have a list of profile id's for debug. | | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo. <profile> <id>jdk-1.4</id> <activation> <jdk>1.4</jdk> </activation> <repositories> <repository> <id>jdk14</id> <name>Repository for JDK 1.4 builds</name> <url>http://www.myhost.com/maven/jdk14</url> <layout>default</layout> <snapshotPolicy>always</snapshotPolicy> </repository> </repositories> </profile> --> <!-- | Here is another profile, activated by the system property 'target-env' with a value of 'dev', | which provides a specific path to the Tomcat instance. To use this, your plugin configuration | might hypothetically look like: | | ... | <plugin> | <groupId>org.myco.myplugins</groupId> | <artifactId>myplugin</artifactId> | | <configuration> | <tomcatLocation>${tomcatPath}</tomcatLocation> | </configuration> | </plugin> | ... | | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to | anything, you could just leave off the <value/> inside the activation-property. | <profile> <id>env-dev</id> <activation> <property> <name>target-env</name> <value>dev</value> </property> </activation> <properties> <tomcatPath>/path/to/tomcat/instance</tomcatPath> </properties> </profile> --> </profiles> <!-- activeProfiles | List of profiles that are active for all builds. | <activeProfiles> <activeProfile>alwaysActiveProfile</activeProfile> <activeProfile>anotherAlwaysActiveProfile</activeProfile> </activeProfiles> --> </settings> 只是修改了mirrors部分,使用了阿里云镜像加速国内下载速度。 设置项目所需包 修改pom.xml文件,以下内容为本人使用成功的配置文件内容,仅作参考 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mango</groupId> <artifactId>ssmTest</artifactId> <version>1.0-SNAPSHOT</version> <properties> <!-- 工程编译版本,一般与安装的JDK版本一致--> <maven.compiler.source>19</maven.compiler.source> <maven.compiler.target>19</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!--统一的版本管理--> <spring.version>6.0.6</spring.version> <slf4j.version>2.0.5</slf4j.version> <mysql.version>8.0.32</mysql.version> <mybatis.version>3.5.13</mybatis.version> </properties> <dependencies> <!-- spring --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--Junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>compile</scope> </dependency> <!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> <type>jar</type> <scope>compile</scope> </dependency> <!--Servlet - JSP --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- @Resource注解依赖包--> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- Spring整合ORM --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>6.0.6</version> </dependency> <!-- spring整合mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.1</version> </dependency> <!-- log --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j</artifactId> <version>2.20.0</version> <type>pom</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!--加入对json转换--> <!-- JSON: jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.jr</groupId> <artifactId>jackson-jr-all</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.25</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.16</version> </dependency> <!-- http请求--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> <version>3.0.4</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build> </project> 添加Web模块 File->Project Structure->Modules 如图操作 image-20230507143328815图片 添加后内容保持默认,确认后即可导入web模块 安装Tomcat 可以参考以下教程 {% link Wxy1122.,[IntelliJ IDEA中配置Tomcat(超详细)_idea配置tomcat_Wxy1122.的博客-CSDN博客,https://blog.csdn.net/Wxy971122/article/details/123508532 %} SSM配置文件 jdbc配置文件 在resources->db下新建jdbc.properties文件,其中内容参考如下 jdbc.driver = com.mysql.cj.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT jdbc.username = root jdbc.password = root由于使用的MySQL版本为8,所以驱动才使用为com.mysql.cj.jdbc.Driver,由于没有在MySQL中做过测试,不能确定在MySQL 5中也能正常使用 jdbc.url中的xxx用自己数据库名称替换 新建mybatis控制文件 在db下新建mybatis.xml文件 由于大部分和MyBatis相关配置文件都会和Spring的配置文件整合到一起,这里的Mybatis控制文件只起到辅助作用,参考代码如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 开启延迟加载 该项默认为false,即所有关联属性都会在初始化时加载 true表示延迟按需加载 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <!-- 开启二级缓存 --> <setting name="cacheEnabled" value="true"/> </settings> </configuration> Spring整合MyBatis 在resources->spring下新建applicationContext.xml文件,将Spring和MyBatis配置文件整合在一起,参考代码如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 开启注解扫描,要扫描的是service和dao层的注解,要忽略web层注解,因为web层让SpringMVC框架去管理 --> <context:component-scan base-package="com.mango"> <!-- 配置要忽略的注解 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 引入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:db/jdbc.properties" /> </bean> <!--Spring整合Mybatisl框架--> <!-- 配置C3P0的连接池对象 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 配置SessionFactory的Bean --> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 注入数据源 --> <property name="dataSource" ref="dataSource"/> <!-- 指定MyBatis配置文件的位置 --> <property name="configLocation" value="classpath:db/mybatis.xml"/> <!-- 给实体类起别名 --> <property name="typeAliasesPackage" value="com.mango.entity"/> </bean> <!-- 配置mapper接口的扫描器,将Mapper接口的实现类自动注入到IoC容器中 实现类Bean的名称默认为接口类名的首字母小写 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- basePackage属性指定自动扫描mapper接口所在的包 --> <property name="basePackage" value="com.mango.dao"/> </bean> <!--SqlMapConfig.xml和jdbcConfig.properties可以删除了--> <!--配置Spring框架声明式事务管理--> <!--配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> <tx:method name="*" isolation="DEFAULT"/> </tx:attributes> </tx:advice> <!-- 配置AOP增强 --> <aop:config> <!-- <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mango.service.impl.*.*(..))"/>--> <!-- 配置切入点表达式 --> <aop:pointcut expression="execution(* com.mango.service.impl.*.*(..))" id="pt1"/> <!-- 建立通知和切入点表达式的关系 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/> </aop:config> </beans> Springmvc配置文件 在resources->spring下新建springmvc.xml文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置@controller扫描包 --> <context:component-scan base-package="com.mango.controller" /> <!--使用Annotation自动注册Bean,扫描@Controller和@ControllerAdvice--> <context:component-scan base-package="com.mango" use-default-filters="false"> <!-- base-package 如果多个,用“,”分隔 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <!--控制器增强,使一个Controller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常--> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" /> </context:component-scan> <!-- 配置注解驱动,相当于同时使用最新处理器映射跟处理器适配器,对json数据响应提供支持 --> <mvc:annotation-driven /> <!-- 输出对象转JSON支持 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>text/plain;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </list> </property> </bean> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans> web模块控制文件 编辑web->WEB-INF->web.xml文件,内容如下 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- 配置前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定配置文件位置和名称 如果不设置,默认找/WEB-INF/<servlet-name>-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置 spring 提供的监听器,用于启动服务时加载容器 。 该监听器只能加载 WEB-INF 目录中名称为 applicationContext.xml 的配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 手动指定 spring 配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext.xml</param-value> </context-param> </web-app> 日志配置 在resources->log下新建log4j.properties log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n log4j.logger.java.sql.ResultSet=INFO log4j.logger.org.apache=INFO log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG 测试 在test->java下更具需求新建测试类 新建测试数据库test,其中有表student(id,name,age) 在之前新建的entity包中新建Student的实现类(getter、setter方法以省略) package com.mango.entity; public class Student { private int id; private String name; private String age; @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age='" + age + '\'' + '}'; } } 对Spring和MyBatis整合配置测试 在包dao中新建学生接口StudentDao.java package com.mango.dao; import com.mango.entity.Student; import java.util.List; public interface StudentDao { public List<Student> findAll(); }在同样位置新建同名mapper文件StudentDao.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--命名空间为StudentDao接口--> <mapper namespace="com.mango.dao.StudentDao"> <!-- id为接口中的方法名--> <select id="findAll">SELECT * FROM Student</select> </mapper>在service包中新建service接口和实现类 image-20230507154913975图片 学生业务层接口StudentService.java package com.mango.service; import com.mango.entity.Student; import org.springframework.stereotype.Service; import java.util.List; //千万不要忘记添加Service注解 @Service public interface StudentService { public List<Student> findAll(); }实现类StudentServiceImpl.java package com.mango.service.impl; import com.mango.dao.StudentDao; import com.mango.entity.Student; import com.mango.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class StudentServiceImpl implements StudentService { @Autowired private StudentDao studentDao; public List<Student> findAll(){ return studentDao.findAll(); } }在test中新建Spring和MyBatis整合测试代码SpringMyBatis.java import com.mango.entity.Student; import com.mango.service.StudentService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:spring/applicationContext.xml") public class SpringMyBatis { @Autowired private StudentService studentService; @Test public void test(){ List<Student> studentList=studentService.findAll(); for (Student student:studentList){ System.out.println(student.toString()); } } } image-20230507161529932图片 测试成功 Spring整合SpringMVC测试 在Controller包中新建StudentController.java package com.mango.controller; import com.mango.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; //千万不要忘记@Controller @Controller @RequestMapping public class StudentController { @Autowired private StudentService studentService; @RequestMapping(value = "/test" ,method = RequestMethod.GET) @ResponseBody public Object test(){ return studentService.findAll(); } } 将项目打包File->Project Structure->Artifacts image-20230507162236159图片 如果有出现部分包不完全可以下图操作 image-20230507162342826图片 修改Tomcat配置(已正确安装Tomcat的情况下) image-20230507162648849图片 image-20230507162740440图片 启动Tomcat后在浏览器中访问localhost:8080/test 不报错有返回值,说明Spring整合SpringMVC配置成功。 image-20230507163245993图片 -
ESP32通过SmartConfig扫码配网 前引 对于ESP配网方式和SmartConfig的介绍,在ESP-IDF编程指南中已经介绍得很详细了,这里就不在赘述。 {% link ESP配网API,ESPRESSIF,https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/provisioning/index.html %} 这里主要来介绍一下在Arduino中怎么使用SmartConfig来实现微信扫码配网,配网失败的一些解决办法,主要代码参考了CSDN上的一篇文章(不能确定是不是原作者,对贡献代码的人都表示感谢) {% link ESP8266/ESP32 SmartConfig一键配网+自动重连+微信扫码配网,lw1997的博客-CSDN博客_esp32蓝牙配网,https://blog.csdn.net/u014091490/article/details/105178037 %} 正文 我只是在代码的原基础上做了简单的添加,指定了SmartConfig的Type #include "WiFi.h" void SmartConfig() { WiFi.mode(WIFI_AP_STA); Serial.println("\r\nWait for Smartconfig..."); WiFi.beginSmartConfig(SC_TYPE_ESPTOUCH_AIRKISS); //我做了修改的部分添加了“SC_TYPE_ESPTOUCH_AIRKISS” while (1) { Serial.print("."); delay(500); // wait for a second if (WiFi.smartConfigDone()) { Serial.println("SmartConfig Success"); Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str()); Serial.printf("PSW:%s\r\n", WiFi.psk().c_str()); break; } } } bool AutoConfig() { WiFi.begin(); //如果觉得时间太长可改 for (int i = 0; i < 20; i++) { int wstatus = WiFi.status(); if (wstatus == WL_CONNECTED) { Serial.println("WIFI SmartConfig Success"); Serial.printf("SSID:%s", WiFi.SSID().c_str()); Serial.printf(", PSW:%s\r\n", WiFi.psk().c_str()); Serial.print("LocalIP:"); Serial.print(WiFi.localIP()); Serial.print(" ,GateIP:"); Serial.println(WiFi.gatewayIP()); return true; } else { Serial.print("WIFI AutoConfig Waiting......"); Serial.println(wstatus); delay(1000); } } Serial.println("WIFI AutoConfig Faild!" ); return false; } void setup() { Serial.begin(115200); delay(100); if (!AutoConfig()) { SmartConfig(); } } void loop() { // put your main code here, to run repeatedly: }在使用作者源代码的时候,微信扫码和ESPTouch APP都没有成功,然后看到说要指定连接的类型,就可以解决 image-20230205231815105图片 根据自己的需求选合适的类型就行。 关于连接工具 微信扫码 官方给的工具网址为:https://iot.espressif.cn/configWXDeviceWiFi.html 可以利用网址链接转二维码工具生成二维码,像我生成的二维码: QRcode_SP — 2图片 利用ESPTouch 可以到ESP官网下载软件,有Android和iOS版本 {% link 资源 | 乐鑫科技,ESPRESSIF,https://www.espressif.com.cn/zh-hans/products/software/esp-touch/resources %} 乐鑫信息科技微信公众号 image-20230205235550535图片 image-20230205235507900图片 -
利用GitHub Action自动集成部署Hexo博客到服务器 前引 Hexo生成的静态博客有着安全、快速等特点,但是同时也存在一些比较明显的痛点 由于没有后台,出现错误时移动端修改不方便 本地文件丢失,很难找回原本博客配置文件 没有Nodejs环境不能部署 而这些问题都能通过Github Action得到比较好的解决 Hexo本地博客创建 {% note info simple %} 已经有的可以跳过 {% endnote %} 第一次使用的话本地Hexo环境是肯定要有的,如果本地博客都没有的话后续步骤也没有意义了 网上已经有比较成熟的教程,此处不做具体描述, {% link 从0开始用Hexo框架搭建个人博客(无坑版),清菡,https://zhuanlan.zhihu.com/p/305812430 %} {% link Hexo+阿里云,手把手教你如何搭建属于自己的个人博客(超详细),到站了还不下车,https://zhuanlan.zhihu.com/p/126243913 %} GitHub仓库创建 在创建时最好选择私有,避免重要内容泄露 image-20220811233905181图片 新建工作流文件 在博客更目录下新建.github/workflows/deploy.yml文件,deploy.yml文件的文件名可以随意起,只要是yml文件就行 将配置内容复制到新建文件中 # 当有改动推送到master分支时,启动Action name: Hexo博客自动部署 on: push: branches: - master release: types: - published jobs: deploy: runs-on: ubuntu-latest steps: - name: 检查分支 uses: actions/checkout@v2 with: ref: master - name: 安装 Node uses: actions/setup-node@v1 with: node-version: "12.x" - name: 安装 Hexo run: | export TZ='Asia/Shanghai' npm install hexo-cli -g env: CI: true - name: 缓存 Hexo uses: actions/cache@v1 id: cache with: path: node_modules key: ${{runner.OS}}-${{hashFiles('**/package-lock.json')}} - name: 安装依赖 if: steps.cache.outputs.cache-hit != 'true' run: | npm install --save env: CI: true - name: 生成静态文件 run: | hexo clean hexo generate env: CI: true - name: 部署 uses: burnett01/rsync-deployments@@5.2.1 with: switches: -avzh path: public/ remote_path: /var/hexo/ remote_host: mstzf.cn remote_port: 22 remote_user: root remote_key: ${{ secrets.SERVER_KEY }} 文本中流程执行结果是将静态文件部署到个人服务器中去 其中,最后部署部分脚本通过 ssh 上的 rsync 将文件部署到远程文件夹中 switches:rsync 标志,例如:-avzr --delete path:要上传文件地址,当前hexo g之后静态文件在public/中 remote_path:博客在服务器中的路径 remote_host:主机地址 remote_port:ssh连接端口号 remote_user:要连接的用户 remote_key:服务器生成的密钥 服务器获取ssh连接密钥 登录服务器终端,输入命令ssh-keygen 出现的提示内容一路回车,最终会在~/.ssh生成公钥和私钥id_rsa.pub、id_rsa 将公钥id_rsa.pub复制到authorized_keys cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys复制一份私钥的内容 新建secrets 登录GitHub,选择要上传博客源文件的仓库->setting下 image-20220812001540652图片 name:SERVER_KEY Value:刚刚复制的私钥 name可以随意但要和流程文件中secrets调用的名字一致 image-20220812001911234图片 检查.gitignore文件 .DS_Store Thumbs.db db.json *.log node_modules/ public/ .deploy*/文件中内容表示上传要忽略的文件,如果文件不存在或者内容有缺少,要及时补充 否则会上传大量无用文件,在添加和提交时都会浪费大量时间 提交博客源代码到github 将博客根目录下和主题文件下存在的.git文件删除或者移动到其非博客文件夹下 将本地博客目录初始化文git仓库 git init #初始化 git remote add origin <github仓库ssh代码> git checkout -b master # 切换到master分支,本地git仓库搭建成功后将源代码提交到GitHub仓库 git add . git commit -m "first commit" git push origin masterGitHub Action会自动执行工作流程,如果一切顺利没有差错的话,博客会自动部署到我们的服务器上去 image-20220812003735619图片 -
Hexo搜索引擎优化(SEO) 前引 我们费尽心血写出来的各种博客,当然是希望分享给更多的人,让更多的人看到的,但是如果只是在自己的小圈子里面去分享的话,很难有好的浏览量,所以就需要我们去优化搜索,让浏览器收录我们的网址,这样在有人在浏览器搜索对应关键字的时候就有可能将我们的文章推荐给他。 道理虽然是这样,但我自己的浏览数据也一直少得可怜 -190f176b0e175c2a" style="zoom:25%;" /> 搜索平台收添加搜索平台 站长管理平台地址 必应站长管理平台 谷歌站长管理平台 百度站长管理平台 登录到搜索平台的站长管理页面,将自己的域名添加后,还需要进行验证,有三种方式,截图以必应的为例 文件验证 下载对应平台的验证文件后,将其保存到网站的根目录,hexo博客框架的话推荐保存到source/目录下,这样每次生成静态页面后都会在public文件下存在,当然也可以直接在public/下添加,但是在运行hexo clean之后被删除。 其他博客框架添加方法也大同小异,只要确定网站根目录然后添加即可。 最终达到的效果就是:能够通过https://你的域名/下载文件名直接访问到文件内容即可 HTML标签验证 将获取到的Meta粘贴在HTML文件的 <head> </head> 部分中 以下为必应下的Meta样式: <meta name="msvalidate.01" content="9565AFED5E9E8A24241BB5E6223CCB04" /> 我用的是hexo的butterfly主题,添加方法作者大大已经弄好,直接将获取到的值添加就行 Butterfly 安裝文檔(四) 主題配置-2 | Butterfly -
接入每天60S看世界API Timeline {% timeline 更新日志 %} 文章发布 将XMLHttpRequest替换为fetch,增加打字机效果 {% endtimeline %} 前言 目前在网上已经有很多博主出了对博客引入这个API的教程,内容也已经比较详细,但是很多通过直接获取整张图片的形式;这样做省去了很多不必要的麻烦,只是图片在加载的时候会比较缓慢,而且在静态博客框架下开启图片懒加载后有几率发生图片加载失败的情况。还有一些博主也使用了直接请求文字内容的教程,而这些很多都是针对基于PHP搭建的博客,不能用于静态博客。 XMLHttpRequest求情Http XMLHttpRequest是JavaScript中自带Http请求函数,可以快速调出浏览器调试界面发请求。在小规模的情况下可以有效减少其他依赖快速的接入接口。 方法描述open("method","URL",[asyncFlag],["userName"],["password"])建立对服务器的调用。method参数可以是GET、POST或PUT。url参数可以是相对URL或绝对URL。这个方法还包括3个可选的参数,是否异步,用户名,密码setRequestHeader("header", "value")把指定首部设置为所提供的值。在设置任何首部之前必须先调用open()。设置header并和请求一起发送 ('post'方法一定要 )send(content)向服务器发送请求在代码中主要值使用了XMLHttpRequest中的这几个方法,更多方法可以到 (XMLHttpRequest - Web API 接口参考 | MDN (mozilla.org) 中查看更多方法使用技巧 开始引入 注册ALAPI 账号获取Token 注册账号后到用户管理界面获取Token并保存,在后面的代码部分会使用到 代码部分 <div> <div style="display: flex;flex-direction: column;align-items: center;"> <h1 style="color: red;font-size: 2.5em;">每天60s看世界</h1> <img id="head-img" src="" alt=""> <p id="news" style="width:90%; color: blue;font-size: 1.4em;">新闻正在加载</p> </div> <script> (() => { const news = document.querySelector('#news') const headImg = document.querySelector('#head-img') var xhr = new XMLHttpRequest() fetch('https://v2.alapi.cn/api/zaobao', { method: "POST", // or 'PUT' headers: { "Content-Type": "application/json", }, body: JSON.stringify({ token: 'wNj349sLbMqqUaew', format: 'json', }), }).then(res => res.json()).then(ori => { var text = ori.data.news var str = '' for (let i = 0; i < text.length; i++) { str += text[i] + '<br>' } // news.innerHTML = str; headImg.src = ori.data.head_image let i = 0; let str_ = '' let timer = setInterval(() => { if (str_.length < str.length) { str_ += str[i++] news.innerHTML = '<p>' + str_ + '_</p>' //打印时加光标 } else { clearInterval(timer) news.innerHTML = '<p>' + str_ + '</p>' } }, 50) }) })() </script> </div>找到代码中xhr.send('token=粘贴刚刚获取到的Token&format=json');部分,将刚刚获取到的Token粘贴到中文标注部分。 引入到博客中 将html代码整个的粘贴到新建页面或者其他要添加的地方。 image-20220422205402441图片