<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ZY知识库</title><description>欢迎来到我的博客</description><link>https://blog.pljzy.top/</link><language>zh_CN</language><item><title>Astro/fuwai博客配置教程</title><link>https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</guid><description>新博客站点部署也有2周多时间了，新站的访问量不是很多，但是我发现有人是用我的fuwai_zyplj仓库去修改配置然后再部署自己的博客</description><pubDate>Mon, 11 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Astro/fuwai博客配置教程&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;新博客站点部署也有2周多时间了，新站的访问量不是很多，但是我发现有人是用我的&lt;a href=&quot;https://github.com/ZyPLJ/fuwai_zyplj&quot;&gt;fuwai_zyplj&lt;/a&gt;仓库去修改配置然后再部署自己的博客，因为我个人喜欢对博客乱改，所以我这边出一个教程，来讲讲如何部署和我一样的博客。&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;本篇文章重点讲解博客配置！！！&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;为了方便大家使用我的仓库，我特意将原本的仓库改为私有，新建了一个公共的仓库，包括不限于没有我的文章、其他第三方配置。&lt;/p&gt;
&lt;p&gt;我的博客只是在原作者&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;仓库的基础上增加了：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;音乐播放器&lt;/li&gt;
&lt;li&gt;文章置顶固定（原作者仓库PR中的）&lt;/li&gt;
&lt;li&gt;评论系统&lt;/li&gt;
&lt;li&gt;友链页面&lt;/li&gt;
&lt;li&gt;首图支持视频&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果对于上述功能不感兴趣的可以直接&lt;code&gt;clone&lt;/code&gt;原作者的仓库。&lt;/p&gt;
&lt;h2&gt;页面基础配置&lt;/h2&gt;
&lt;p&gt;大部分页面配置都在&lt;code&gt;src/config.ts&lt;/code&gt;文件中完成,大部分配置都有注释。重点讲解我添加的配置。&lt;/p&gt;
&lt;h3&gt;banner图换成视频&lt;/h3&gt;
&lt;p&gt;将&lt;code&gt;type&lt;/code&gt;设置为&lt;code&gt;video&lt;/code&gt;，然后将&lt;code&gt;src&lt;/code&gt;指向视频&lt;code&gt;MP4&lt;/code&gt;格式的视频文件，注意视频文件放在 &lt;code&gt;public/videos/&lt;/code&gt; 目录下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;banner: {
    enable: true,
    src: &quot;assets/images/banner.jpg&quot;, // Relative to the /src directory. Relative to the /public directory if it starts with &apos;/&apos;
    // 如果要使用MP4视频，可以这样配置：
    // src: &quot;/videos/banner-video.mp4&quot;, // 视频文件放在 public/videos/ 目录下
    // type: &quot;video&quot;, // 设置为视频类型
    position: &quot;center&quot;, // Equivalent to object-position, only supports &apos;top&apos;, &apos;center&apos;, &apos;bottom&apos;. &apos;center&apos; by default
    type: &quot;image&quot;, // Support &apos;image&apos; or &apos;video&apos; format
    credit: {
        enable: false, // Display the credit text of the banner image
        text: &quot;&quot;, // Credit text to be displayed
        url: &quot;&quot;, // (Optional) URL link to the original artwork or artist&apos;s page
    },
},
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Microsoft Clarity 分析&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Microsoft Clarity&lt;/code&gt;是微软提供的用于网站流量分析的工具，如果用不上改成false即可，如果想用就需要去官网注册个账号：https://clarity.microsoft.com/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clarity: {
    enable: false, // 是否启用 Microsoft Clarity 分析
    projectId: &quot;&quot;, // Clarity 项目 ID
},
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;音乐播放器&lt;/h3&gt;
&lt;p&gt;在&lt;code&gt;public/lib/MasterMusic.js&lt;/code&gt;中修改音乐数据源。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;musicPlayer: {
    enable: true, // 是否启用音乐播放器
},
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;评论系统&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;envId&lt;/code&gt;替换成你部署的评论系统的域名或者ip地址。&lt;/p&gt;
&lt;p&gt;本博客集成的&lt;a href=&quot;https://twikoo.js.org/quick-start.html&quot;&gt;快速上手 | Twikoo 文档&lt;/a&gt;评论系统，如果想部署这个评论系统，官网的部署文档还是很详细的，推荐有服务器的人使用&lt;code&gt;宝塔+Docker&lt;/code&gt;部署。&lt;/p&gt;
&lt;p&gt;如果不想用或者部署不好评论系统，修改&lt;code&gt;enable&lt;/code&gt;为&lt;code&gt;false&lt;/code&gt;就能关闭评论。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const commentConfig = {
	enable: true,
	provider: &quot;twikoo&quot;,
	twikoo: {
		envId: &quot;https://api.pljzy.top&quot;, // 移除末尾的斜杠
		region: &quot;&quot;,
		lang: &quot;zh-CN&quot;,
	},
};

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果发现评论系统没有出现，可能是&lt;code&gt;CDN&lt;/code&gt;文件引入的问题，可以在&lt;code&gt;src/components/Comment.astro&lt;/code&gt;组件中修改&lt;code&gt;CDN&lt;/code&gt;文件路径。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// https://twikoo.js.org/frontend.html CDN指南
const script = document.createElement(&apos;script&apos;);
script.src = &apos;https://registry.npmmirror.com/twikoo/1.6.44/files/dist/twikoo.min.js&apos; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;友链页面&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/content/spec/links.md&lt;/code&gt;友链页面其实就是&lt;code&gt;md&lt;/code&gt;文件，如果有新的友链，将参考的&lt;code&gt;div&lt;/code&gt;复制一份修改里面的内容就行了，对于没有评论系统的，也想使用友链，可以将自己仓库的&lt;code&gt;issues&lt;/code&gt;地址放出来，让其他博主在&lt;code&gt;github&lt;/code&gt;上体积&lt;code&gt;issues&lt;/code&gt;来达到友链提交的效果&lt;/p&gt;
&lt;p&gt;2025-08-25 优化后，在&lt;code&gt;src-&amp;gt;data-&amp;gt;frend-links.ts&lt;/code&gt;文件中添加友链数据即可。&lt;/p&gt;
&lt;h3&gt;文章置顶&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pinned&lt;/code&gt; 属性设置为true即为置顶显示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: ***文章标题
published: 2025-06-21 发布时间
description: 文章简介
image: ./5.png 文章首图,非必须可删除。
tags: [日常,测试] 文章标签 可多个 
category: 记录生活 文章分类
draft: false 
pinned: false 文章是否固定、置顶
---
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;多提一嘴&lt;/h2&gt;
&lt;p&gt;大部分博客的配置都是在&lt;code&gt;src/config.ts&lt;/code&gt;文件中完成，文章底部显示的内容在&lt;code&gt;src/components/Footer.astro&lt;/code&gt;组件中设置。&lt;/p&gt;
&lt;p&gt;部署博客的话可以参考：&lt;a href=&quot;https://blog.pljzy.top/posts/astro/%E5%9F%BA%E4%BA%8Eastro%E5%BC%80%E5%8F%91%E7%9A%84fuwari%E9%9D%99%E6%80%81%E5%8D%9A%E5%AE%A2%E6%A8%A1%E7%89%88%E9%85%8D%E7%BD%AEcicd%E6%B5%81%E7%A8%8B/&quot;&gt;基于Astro开发的Fuwari静态博客模版配置CICD流程 - ZY知识库&lt;/a&gt;--https://blog.pljzy.top/posts/astro/  这篇文章&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;上述就是博主所集成的工具开关，如果还有问题可以在文章下留言。&lt;/p&gt;
&lt;p&gt;推荐先去了解原作者的模版：&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;--https://github.com/saicaca/fuwari， 如果喜欢本博客集成功能可以参考代码添加进去。&lt;/p&gt;
</content:encoded></item><item><title>AESCO A83 Air 矮轴键盘开箱</title><link>https://blog.pljzy.top/posts/aesco-a83-air%E7%9F%AE%E8%BD%B4%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1/aesco-a83-air%E7%9F%AE%E8%BD%B4%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/aesco-a83-air%E7%9F%AE%E8%BD%B4%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1/aesco-a83-air%E7%9F%AE%E8%BD%B4%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1/</guid><description>AESCO A83 Air 矮轴键盘开箱前言目前在使用的主力键盘有2个，分别是：HELLO GANSS XS 75T 键盘开箱 - ZY知识库 (2024年1月购入)KZZI 珂芝K75 机械键盘（2023年6月购入）这2款机械键盘的轴体都不是矮轴，不过都是75配列，因为平常写代码感觉还是小配列的键盘舒服，数字键很少用上。</description><pubDate>Sun, 15 Mar 2026 15:54:57 GMT</pubDate><content:encoded>&lt;h1&gt;AESCO A83 Air 矮轴键盘开箱&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;目前在使用的主力键盘有2个，分别是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/&quot;&gt;HELLO GANSS XS 75T 键盘开箱 - ZY知识库&lt;/a&gt; (2024年1月购入)&lt;/li&gt;
&lt;li&gt;KZZI 珂芝K75 机械键盘（2023年6月购入）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这2款机械键盘的轴体都不是矮轴，不过都是75配列，因为平常写代码感觉还是小配列的键盘舒服，数字键很少用上。&lt;/p&gt;
&lt;p&gt;2025年一整年没有购入新键盘，到2026年换新电脑后也产生了换个新键盘的想法，当时机械键盘、磁轴键盘我都在看，不过我朋友给我推荐矮轴键盘，说：“打字特别爽”。&lt;/p&gt;
&lt;p&gt;我看了好几款矮轴键盘，感觉都不是我喜欢的外观风格，我买机械键盘就喜欢买有旋钮和按钮盒小屏幕的，喜欢花里胡哨的。
不过刚好26年3月新出了一款&lt;strong&gt;AESCO A83 Air矮轴键盘&lt;/strong&gt;,虽然外观没一个符合我要求的，不过物极必反，这种极致的简约也挺不错。&lt;/p&gt;
&lt;h2&gt;产品介绍&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;详情&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;产品型号&lt;/td&gt;
&lt;td&gt;aeesco A83 Air 多模矮轴机械键盘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;产品尺寸&lt;/td&gt;
&lt;td&gt;315×132×30mm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重量&lt;/td&gt;
&lt;td&gt;1032g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;连接模式&lt;/td&gt;
&lt;td&gt;蓝牙5.0、2.4GHz、有线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;电池容量&lt;/td&gt;
&lt;td&gt;3800mAh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;键帽材质&lt;/td&gt;
&lt;td&gt;PBT 双色注塑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;键盘结构&lt;/td&gt;
&lt;td&gt;Gasket 结构&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;热插拔&lt;/td&gt;
&lt;td&gt;支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;兼容系统&lt;/td&gt;
&lt;td&gt;Win、mac OS双系统&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;充电接口&lt;/td&gt;
&lt;td&gt;USB-C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;快捷功能&lt;/td&gt;
&lt;td&gt;12 种&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;背光系统&lt;/td&gt;
&lt;td&gt;预设9种背光模式 驱动可支持自定义背光模式&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;目前这个系列只出了一款配色和轴体，配色如图所示，轴体名叫薄荷轴，键程短。键盘采用Gasket结构，打字时声音也很好听。键帽是PBT材质，总共83键。三模连接，可手动切换&lt;code&gt;Win&lt;/code&gt;和&lt;code&gt;mac&lt;/code&gt;系统3800mAh可充锂电池，官方宣称630小时续航，实际多久就不知道了，我也没测试。可通过官方驱动进行按键编程，全键无冲。&lt;/p&gt;
&lt;h2&gt;开箱图片&lt;/h2&gt;
&lt;p&gt;包装还是无破损的，这点不错，发的是顺丰快递。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;打开包装，里面就是一张说明书，然后键盘本体，以及充电线和接收器，接收器是单独一个小包装，注意不要漏掉了。&lt;/p&gt;
&lt;h2&gt;键盘本体&lt;/h2&gt;
&lt;p&gt;外观还是很好看的，不过目前只有这款配色，要是能有更多选择的键帽配色就好了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;驱动界面&lt;/h2&gt;
&lt;p&gt;直接百度搜索键盘名称，打开官网下载驱动即可。&lt;/p&gt;
&lt;p&gt;值得注意的是右下角方向键判断的呼吸灯也是可以设置颜色的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这是我第一款买入的矮轴键盘，总的来说体验还是很好的，无论是手感还是敲击声音都挺满意。&lt;/p&gt;
</content:encoded></item><item><title>旧物新生，新包入手，还有一杯联动的甜</title><link>https://blog.pljzy.top/posts/%E6%97%A7%E7%89%A9%E6%96%B0%E7%94%9F%E6%96%B0%E5%8C%85%E5%85%A5%E6%89%8B%E8%BF%98%E6%9C%89%E4%B8%80%E6%9D%AF%E8%81%94%E5%8A%A8%E7%9A%84%E7%94%9C/%E6%97%A7%E7%89%A9%E6%96%B0%E7%94%9F%E6%96%B0%E5%8C%85%E5%85%A5%E6%89%8B%E8%BF%98%E6%9C%89%E4%B8%80%E6%9D%AF%E8%81%94%E5%8A%A8%E7%9A%84%E7%94%9C/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%97%A7%E7%89%A9%E6%96%B0%E7%94%9F%E6%96%B0%E5%8C%85%E5%85%A5%E6%89%8B%E8%BF%98%E6%9C%89%E4%B8%80%E6%9D%AF%E8%81%94%E5%8A%A8%E7%9A%84%E7%94%9C/%E6%97%A7%E7%89%A9%E6%96%B0%E7%94%9F%E6%96%B0%E5%8C%85%E5%85%A5%E6%89%8B%E8%BF%98%E6%9C%89%E4%B8%80%E6%9D%AF%E8%81%94%E5%8A%A8%E7%9A%84%E7%94%9C/</guid><description>旧物新生，新包入手，还有一杯联动的甜前言生活就像一盒惊喜盲盒，这周打开来，满满都是温暖的碎片。旧电脑完成使命开启新旅程，新电脑包带着诚意抵达，还有一杯古茗与《凡人修仙传》联名的拿铁，让味蕾也坠入了仙侠世界。</description><pubDate>Sun, 08 Mar 2026 21:49:35 GMT</pubDate><content:encoded>&lt;h1&gt;旧物新生，新包入手，还有一杯联动的甜&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;生活就像一盒惊喜盲盒，这周打开来，满满都是温暖的碎片。旧电脑完成使命开启新旅程，新电脑包带着诚意抵达，还有一杯古茗与《凡人修仙传》联名的拿铁，让味蕾也坠入了仙侠世界。&lt;/p&gt;
&lt;h2&gt;旧电脑的“毕业礼”：联想拯救者Y7000 2019的回收之旅&lt;/h2&gt;
&lt;p&gt;看着那台陪伴我度过无数日夜的&lt;strong&gt;联想拯救者Y7000 2019&lt;/strong&gt;，它曾陪我在游戏世界里冲锋陷阵，也在工作学习中默默支撑。这次决定让它“毕业”，选择了回收。从提交订单到质检完成，过程比想象中顺利。&lt;/p&gt;
&lt;p&gt;原本以为只能回收&lt;strong&gt;800-900&lt;/strong&gt;，回收的时候发现，用了5年多，电池健康还有**80%**以上，不得不佩服联想拯救者系列的质量了，用了这么久没出过问题（除了&lt;code&gt;windows&lt;/code&gt;系统问题）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;新电脑包的“见面礼”：ThinkBook双肩包的贴心抵达&lt;/h2&gt;
&lt;p&gt;上周买的&lt;strong&gt;Thinkbook&lt;/strong&gt;送的双肩包到了，感觉外观不是特别好看。&lt;/p&gt;
&lt;p&gt;日常通勤装电脑倒是够用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一杯拿铁的“仙侠梦”：古茗×《凡人修仙传》联名特调&lt;/h2&gt;
&lt;p&gt;网上冲浪，发现凡人修仙传和古茗出联动套餐了，作为刚看完凡人修仙传的新粉必须支持一波。&lt;/p&gt;
&lt;p&gt;果断点了一杯联名拿铁,看着桌上的《凡人修仙传》周边海报和手机壳上的韩立Q版形象，突然觉得生活里的小美好就是这样：一口饮品，一个爱好，就能把平凡的日子酿成诗。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;结尾&lt;/h2&gt;
&lt;p&gt;这周的碎片，拼凑出的是一种充实又温柔的生活质感。旧物妥善告别，新物带着期待到来，还有一份味觉与兴趣的碰撞。愿我们都能在琐碎日常里，收集这些小确幸，把日子过成自己喜欢的模样。&lt;/p&gt;
</content:encoded></item><item><title>Windows系统安装OpenClaw并使用Qwen千问接入飞书教程 🤖</title><link>https://blog.pljzy.top/posts/windows%E7%B3%BB%E7%BB%9Fopenclawdeepseek%E9%A3%9E%E4%B9%A6%E6%8E%A5%E5%85%A5%E6%95%99%E7%A8%8B/windows%E7%B3%BB%E7%BB%9Fopenclawdeepseek%E9%A3%9E%E4%B9%A6%E6%8E%A5%E5%85%A5%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/windows%E7%B3%BB%E7%BB%9Fopenclawdeepseek%E9%A3%9E%E4%B9%A6%E6%8E%A5%E5%85%A5%E6%95%99%E7%A8%8B/windows%E7%B3%BB%E7%BB%9Fopenclawdeepseek%E9%A3%9E%E4%B9%A6%E6%8E%A5%E5%85%A5%E6%95%99%E7%A8%8B/</guid><description>Windows系统安装OpenClaw并使用Qwen千问接入飞书教程 🤖免责声明 ⚠️本教程仅供学习和参考 purposes，作者不对使用本教程产生的任何后果承担责任。</description><pubDate>Wed, 04 Mar 2026 00:30:23 GMT</pubDate><content:encoded>&lt;h1&gt;Windows系统安装OpenClaw并使用Qwen千问接入飞书教程 🤖&lt;/h1&gt;
&lt;h1&gt;免责声明 ⚠️&lt;/h1&gt;
&lt;p&gt;本教程仅供学习和参考 &lt;code&gt;purposes&lt;/code&gt;，作者不对使用本教程产生的任何后果承担责任。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用风险：&lt;/strong&gt; &lt;strong&gt;读者应自行评估使用本教程的风险&lt;/strong&gt;，因遵循本教程操作而导致的任何直接或间接损失（包括但不限于数据丢失、系统故障、账号安全问题等），作者不承担任何责任。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;技术支持：&lt;/strong&gt; 本教程为个人经验分享，不提供正式技术支持。遇到问题请优先查阅官方文档或向相关软件官方寻求帮助。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;阅读本教程即表示您已阅读并同意上述声明。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这种直接操作电脑的AI使用有风险，大家注意规避风险！！！ 🚨&lt;/p&gt;
&lt;h2&gt;前言 📝&lt;/h2&gt;
&lt;p&gt;最近&lt;a href=&quot;https://openclaw.ai/&quot;&gt;OpenClaw（小龙虾）&lt;/a&gt;挺火的，这是个什么东西呢，说白了就是通过它可以调度各大AI，相当于一个AI代理程序。🦞&lt;/p&gt;
&lt;p&gt;往往之前我们常常是在&lt;code&gt;web&lt;/code&gt;、&lt;code&gt;Idea&lt;/code&gt;中使用&lt;code&gt;AI&lt;/code&gt;来完成一些对话、编程代码处理等。&lt;/p&gt;
&lt;p&gt;有了&lt;a href=&quot;https://openclaw.ai/&quot;&gt;OpenClaw&lt;/a&gt;的帮助，可以直接帮我们操作浏览器、填写&lt;code&gt;Excel&lt;/code&gt;表格，读取系统的文件。💪&lt;/p&gt;
&lt;p&gt;那么今天我也是看了些许教程，来试试安装这个工具。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./banner.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;环境准备 🔧&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安装&lt;a href=&quot;https://nodejs.org/zh-cn/download&quot;&gt;node.js&lt;/a&gt;,在官网安装最新版本的&lt;code&gt;node.js&lt;/code&gt; 📦&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装成功后，管理员身份打开&lt;strong&gt;PowerShell（终端管理员）&lt;/strong&gt;,输入&lt;pre&gt;&lt;code&gt;node -v
&lt;/code&gt;&lt;/pre&gt;
出现版本号则安装成功。✅&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装飞书插件 📱&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;pre&gt;&lt;code&gt;openclaw plugins install @m1heng-clawd/feishu
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;(谨慎操作，相当于AI直接操作你的电脑)&amp;lt;/font&amp;gt;&amp;lt;font color=&apos;red&apos;&amp;gt;(可选)&amp;lt;/font&amp;gt;安装后**PowerShell（终端管理员）**开启文件权限&lt;code&gt;openclaw config set tools.profile &quot;coding&quot;  # 启用文件操作（read/write/edit）+ 执行命令&lt;/code&gt; ⚡&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;（可选）创建飞书应用 🎯&lt;/h2&gt;
&lt;p&gt;如果不需要飞书机器人，只是体验&lt;a href=&quot;https://openclaw.ai/&quot;&gt;OpenClaw&lt;/a&gt;可跳过这个步骤。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&quot;https://open.feishu.cn/?lang=zh-CN&quot;&gt;飞书开放平台&lt;/a&gt;注册账号并登录。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;进入&lt;strong&gt;开发者后台创建企业自建应用&lt;/strong&gt; 🏗️&lt;/li&gt;
&lt;li&gt;添加机器人 🤖&lt;/li&gt;
&lt;li&gt;权限管理，配置应用权限&lt;a href=&quot;https://clawd.org.cn/channels/feishu.html#_4-%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E6%9D%83%E9%99%90&quot;&gt;飞书机器人 | OpenClaw 中文社区 - 开源免费 AI 助手 | WhatsApp/Telegram/微信自动化&lt;/a&gt; 🔑
&lt;ol&gt;
&lt;li&gt;赋值文档中的&lt;code&gt;json&lt;/code&gt;到飞书的权限管理界面，详见下发图片。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;飞书开放平台左上角，点击创建应用版本，首次发布免审，提交弹窗点击确认发布即可。 🚀&lt;/li&gt;
&lt;li&gt;飞书开放平台凭证与基础信息，这里的&lt;code&gt;App ID&lt;/code&gt;和&lt;code&gt;App Secret&lt;/code&gt;，后面&lt;code&gt;OpenClaw&lt;/code&gt;会用到 🔐&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面步骤图片参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;安装OpenClaw ⚙️&lt;/h2&gt;
&lt;p&gt;下面步骤为官方版安装步骤，中文版安装教程：https://clawd.org.cn/install/，步骤大差不差。&lt;/p&gt;
&lt;p&gt;在**PowerShell（终端管理员）**中输入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iwr -useb https://openclaw.ai/install.ps1 | iex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等待下载完成，如图就是下载成功。✨&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;安装向导 🧭&lt;/h2&gt;
&lt;p&gt;运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;openClaw onboard --install-daemon
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;进行启动配置，这里我翻译成中文了，自行查看。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;风险提示：Yes ⚠️&lt;/li&gt;
&lt;li&gt;安装引导模式：Manual（手动） 🖱️&lt;/li&gt;
&lt;li&gt;网关：Local（本地网关） 🌐&lt;/li&gt;
&lt;li&gt;工作区目录：默认 📂&lt;/li&gt;
&lt;li&gt;模型：Qwen（千问），此时会跳转千问登录页，注册或创建账号登录成功后返回控制台，目前是免费使用，不知道有没有限制。 🆓&lt;/li&gt;
&lt;li&gt;默认模型：keep current（保持当前） 💾&lt;/li&gt;
&lt;li&gt;默认运行端口：18789 🔌&lt;/li&gt;
&lt;li&gt;网关绑定：Loopback（127.0.0.1） 🔄&lt;/li&gt;
&lt;li&gt;网关认证：Token 🔑&lt;/li&gt;
&lt;li&gt;Tailscale：off 📴&lt;/li&gt;
&lt;li&gt;网关令牌：直接回车或自行输入，建议自行输入一个简单的 ✏️
&lt;ol&gt;
&lt;li&gt;后面如果打开web网页报错，可以尝试将修改的令牌填入如图位置后点击连接 🔗&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;./4-3.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;选择频道：跳过，后续会对接飞书。 ⏭️&lt;/li&gt;
&lt;li&gt;配置技能：No ❌&lt;/li&gt;
&lt;li&gt;启用钩子：选择跳过后按空格后再按回车 ⏎&lt;/li&gt;
&lt;li&gt;此时会新弹出一个控制台，不要关闭，然后通过打开http://127.0.0.1:18789/网址访问Web页面，如果网页无法对话，关闭&lt;strong&gt;PowerShell（终端管理员）&lt;strong&gt;输入&lt;code&gt;openclaw gateway restart&lt;/code&gt;重启&lt;code&gt;openclaw&lt;/code&gt;和参考&lt;/strong&gt;11&lt;/strong&gt;步网关令牌,看看是不是令牌问题。 🔍&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以下是部分选项截图参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;向导安装完成 🎉&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;（可选）对接飞书 📲&lt;/h2&gt;
&lt;p&gt;飞书应用和向导安装完成后，打开**PowerShell（终端管理员）**执行&lt;code&gt;openclaw config set tools.profile &quot;coding&quot;&lt;/code&gt;开启操作文件权限。 🔓&lt;/p&gt;
&lt;p&gt;让小龙虾帮我们安装飞书插件和配置飞书。 🦞&lt;/p&gt;
&lt;p&gt;也可以自行安装飞书插件&lt;code&gt;openclaw plugins install @m1heng-clawd/feishu&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;安装飞书插件和配置 🛠️&lt;/h3&gt;
&lt;p&gt;将我们上面飞书应用的&lt;code&gt;App ID&lt;/code&gt;和&lt;code&gt;App Secret&lt;/code&gt;，发给&lt;code&gt;OpenClaw&lt;/code&gt;让它帮我们配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出现图中如下控制台则表示正在与飞书建立连接，这时候就需要去飞书再配置下事件了。 🔄&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7-2.png&quot; alt=&quot;feishu7-2&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;飞书事件配置 📋&lt;/h3&gt;
&lt;p&gt;在事件与回调中点击订阅方式，配置订阅方式。注意只有出现上面截图的窗口这时候才能配置接收时间，否则会提示无法创建。 ⏰&lt;/p&gt;
&lt;p&gt;订阅方式选择长链接后，点击添加事件，添加一个接收信息的事件，然后发布版本即可。 📢&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E9%A3%9E%E4%B9%A68.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;飞书配队 🤝&lt;/h3&gt;
&lt;p&gt;事件配置并发布版本后，此时打开飞书，给机器人发一条消息，它会回复&lt;strong&gt;配对码&lt;/strong&gt;给你，直接把配对码丢给&lt;code&gt;OpenClaw&lt;/code&gt;就行了。 💬&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7-3.png&quot; alt=&quot;feishu7-3&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;飞书对接完成 ✅&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./feishu7-5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;总结 📌&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;注意开启文件读取操作权限后，谨慎使用&lt;/strong&gt;&lt;code&gt;OpenClaw&lt;/code&gt;。 ⚡&lt;/p&gt;
&lt;p&gt;本教程完整记录了在 &lt;code&gt;Windows&lt;/code&gt; 系统上部署 &lt;code&gt;OpenClaw&lt;/code&gt; 并接入飞书的整个过程：&lt;/p&gt;
&lt;h3&gt;核心步骤 📋&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;环境准备&lt;/strong&gt; - 安装 &lt;code&gt;Node.js&lt;/code&gt; 和 &lt;code&gt;OpenClaw&lt;/code&gt; 框架 🔧&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;飞书应用创建&lt;/strong&gt; - 在飞书开放平台创建企业自建应用，配置机器人权限 🎯&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenClaw 安装&lt;/strong&gt; - 通过官方脚本安装并完成向导配置 ⚙️&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;飞书对接&lt;/strong&gt; - 配置飞书插件、订阅事件、完成配对 📲&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;关键配置 ⚙️&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;网关端口&lt;/strong&gt;: 18789 🔌&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型&lt;/strong&gt;: Qwen（千问） 🤖&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;连接模式&lt;/strong&gt;: WebSocket 长连接 🔗&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;注意事项 ⚠️&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;注意开启文件读取操作权限后，谨慎使用&lt;/strong&gt;&lt;code&gt;OpenClaw&lt;/code&gt; 🔒&lt;/li&gt;
&lt;li&gt;遇到问题可访问 &lt;a href=&quot;https://docs.openclaw.ai&quot;&gt;OpenClaw 文档&lt;/a&gt; 或 &lt;a href=&quot;https://clawd.org.cn&quot;&gt;中文社区&lt;/a&gt; 📚&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;后续扩展 🚀&lt;/h3&gt;
&lt;p&gt;完成基础对接后，OpenClaw 还可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读写飞书文档 📄&lt;/li&gt;
&lt;li&gt;管理云空间文件 📁&lt;/li&gt;
&lt;li&gt;设置权限和协作 👥&lt;/li&gt;
&lt;li&gt;导航知识库 📚&lt;/li&gt;
&lt;li&gt;自动回复消息 💬&lt;/li&gt;
&lt;li&gt;扩展更多插件功能 🔌&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;教程最后更新：2026 年 3 月 4 日&lt;/em&gt; 📅&lt;/p&gt;
</content:encoded></item><item><title>联想Thinkbook14+ 2026 锐龙7 H255 开箱 📦✨</title><link>https://blog.pljzy.top/posts/%E8%81%94%E6%83%B3thinkbook14-2026-%E9%94%90%E9%BE%997-h255-%E5%BC%80%E7%AE%B1/%E8%81%94%E6%83%B3thinkbook14-2026-%E9%94%90%E9%BE%997-h255-%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%81%94%E6%83%B3thinkbook14-2026-%E9%94%90%E9%BE%997-h255-%E5%BC%80%E7%AE%B1/%E8%81%94%E6%83%B3thinkbook14-2026-%E9%94%90%E9%BE%997-h255-%E5%BC%80%E7%AE%B1/</guid><description>联想Thinkbook14+ 2026 锐龙7 H255 开箱 📦✨前言 💭目前办公我用的电脑还是19年买的联想拯救者 Y7000 i5 版本的，过去这么久，已经无法满足我的办公需求了 😫。所以我也是看了对比了很久的笔记本电脑，决定换一台新的笔记本 🆕。</description><pubDate>Sun, 01 Mar 2026 16:11:32 GMT</pubDate><content:encoded>&lt;h1&gt;联想Thinkbook14+ 2026 锐龙7 H255 开箱 📦✨&lt;/h1&gt;
&lt;h2&gt;前言 💭&lt;/h2&gt;
&lt;p&gt;目前办公我用的电脑还是19年买的联想拯救者 &lt;strong&gt;Y7000 i5&lt;/strong&gt; 版本的，过去这么久，已经无法满足我的办公需求了 😫。&lt;/p&gt;
&lt;p&gt;所以我也是看了对比了很久的笔记本电脑，决定换一台新的笔记本 🆕。&lt;/p&gt;
&lt;p&gt;一开始我其实想等 &lt;strong&gt;Thinkbook14+ 2026&lt;/strong&gt; 新酷睿版本出来的。不出意外，我刚下单买锐龙版本的，新酷睿版本就开始预约了 ⏰。&lt;/p&gt;
&lt;p&gt;不过看了一眼新酷睿的价格还是偏高的 💸，酷睿版本内存是非板载的，后续能自己升级，反正锐龙7也够用，开箱没质量问题我也就选择留下来了 ✅。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;配置介绍 ⚙️&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;处理器&lt;/strong&gt; 🧠：搭载 &lt;strong&gt;AMD Ryzen™ 7 H 255&lt;/strong&gt; 移动处理器，极客模式性能释放 &lt;strong&gt;87W&lt;/strong&gt; 🚀。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;显卡&lt;/strong&gt; 🎮：集成 &lt;strong&gt;AMD Radeon™ 780M&lt;/strong&gt; 核心显卡。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存&lt;/strong&gt; 💾：板载 &lt;strong&gt;32GB LPDDR5x 7500MT/s&lt;/strong&gt; 高频内存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;硬盘&lt;/strong&gt; 💿：配备 &lt;strong&gt;1TB M.2 2280 PCIe Gen 4 TLC&lt;/strong&gt; 固态硬盘，双硬盘位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;屏幕&lt;/strong&gt; 🖥️：&lt;strong&gt;14.5&lt;/strong&gt; 英寸 &lt;strong&gt;IPS LED&lt;/strong&gt; 显示屏，3K分辨率 (3072 × 1920)，支持 &lt;strong&gt;120Hz&lt;/strong&gt; 高刷新率，峰值亮度达到 &lt;strong&gt;500nits&lt;/strong&gt; ☀️。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尺寸重量&lt;/strong&gt; 🎒：整机厚度约 &lt;strong&gt;15.9mm&lt;/strong&gt;，重量约 &lt;strong&gt;1.5kg&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开箱 🔓&lt;/h2&gt;
&lt;h3&gt;验机流程（仅供参考）📝&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;检查外包装&lt;/strong&gt; 📦
&lt;ul&gt;
&lt;li&gt;封条是否完整 🔒。&lt;/li&gt;
&lt;li&gt;SN码核对 🔢。&lt;/li&gt;
&lt;li&gt;纸箱是否有明显的外观损伤，如挤压、水浸 💧。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;首次开机（跳过联网激活）&lt;/strong&gt; 💻
&lt;ul&gt;
&lt;li&gt;在联网界面输入 &lt;code&gt;Shift+F10&lt;/code&gt; 或者 &lt;code&gt;Shift+FN+F10&lt;/code&gt; 后，在弹出的命令窗口输入：&lt;code&gt;oobe\bypassnro&lt;/code&gt; 后回车 ↩️，等待电脑重启后，再次回到联网界面就可以选择（我没有Internet连接）跳过联网 🚫🌐。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;图吧工具箱&lt;/strong&gt; 🧰
&lt;ul&gt;
&lt;li&gt;可以先用u盘下载一个 &lt;a href=&quot;https://www.tbtool.cn/&quot;&gt;图吧工具箱官方网站 - DIY爱好者的必备工具合集&lt;/a&gt;（https://www.tbtool.cn/）， 然后测一测屏幕有没有坏点 👁️，烤鸡时，CPU性能释放有没有问题 🔥，硬盘有没有问题 💾。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;键盘与触控板测试&lt;/strong&gt; ⌨️，检查键盘和触控板是否有失灵的情况。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口测试&lt;/strong&gt; 🔌，检测电脑接口是否都能正常工作。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;做完这些检测后就可以进行激活联网了 🎉。&lt;/p&gt;
&lt;h3&gt;配置信息 📊&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;实机图片 📸&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;📝 总结&lt;/h2&gt;
&lt;p&gt;AI总结：这次从老旧的 Y7000 升级到 ThinkBook 14+ 2026 锐龙版，整体体验提升巨大！✨ 虽然错过了可升级内存的酷睿版，但 &lt;strong&gt;R7 H255 + 32GB 大内存&lt;/strong&gt; 的组合完全能满足未来几年的办公和轻度创作需求 💼。3K 120Hz 的高刷屏看起来非常舒服，1.5kg 的重量也让通勤变得轻松许多 🎒。只要验机流程走对，避开激活陷阱，这绝对是一台性价比极高的全能本，值得入手！💯👍&lt;/p&gt;
</content:encoded></item><item><title>我们订婚了 💍✨</title><link>https://blog.pljzy.top/posts/%E6%88%91%E4%BB%AC%E8%AE%A2%E5%A9%9A%E4%BA%86/%E6%88%91%E4%BB%AC%E8%AE%A2%E5%A9%9A%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%88%91%E4%BB%AC%E8%AE%A2%E5%A9%9A%E4%BA%86/%E6%88%91%E4%BB%AC%E8%AE%A2%E5%A9%9A%E4%BA%86/</guid><description>趁过年休息时间（2026年2月18日），我也是把人生大事定下来了。🎉❤️</description><pubDate>Wed, 25 Feb 2026 21:07:24 GMT</pubDate><content:encoded>&lt;h1&gt;我们订婚了 💍✨&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;趁过年休息时间（&lt;strong&gt;2026年2月18日&lt;/strong&gt;），我也是把人生大事定下来了。🎉❤️&lt;/p&gt;
&lt;p&gt;婚期目前还在看日子，不出意外的话今年肯定是要结婚了。🗓️😊&lt;/p&gt;
&lt;p&gt;有很多话想说，但是又不知如何表达，就这样了，放一张图片吧。📸🥰&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>我入职京东了</title><link>https://blog.pljzy.top/posts/%E6%88%91%E5%85%A5%E8%81%8C%E4%BA%AC%E4%B8%9C%E4%BA%86/%E6%88%91%E5%85%A5%E8%81%8C%E4%BA%AC%E4%B8%9C%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%88%91%E5%85%A5%E8%81%8C%E4%BA%AC%E4%B8%9C%E4%BA%86/%E6%88%91%E5%85%A5%E8%81%8C%E4%BA%AC%E4%B8%9C%E4%BA%86/</guid><description>我入职京东了前言 😅</description><pubDate>Tue, 10 Feb 2026 21:00:02 GMT</pubDate><content:encoded>&lt;h1&gt;我入职京东了&lt;/h1&gt;
&lt;h2&gt;前言 😅&lt;/h2&gt;
&lt;p&gt;好了，标题党了，实际上是入职京东众包外卖。🛵&lt;/p&gt;
&lt;p&gt;事情的起因是上班太累了，不想自己做饭，然后下班的时候就点了份外卖，然后坐地铁回家（大约1个小时路程），都快到家了发现还是没人接单😤，这种情况不是一次二次了，只要是晚上点京东外卖就会出现没人接单的情况。&lt;/p&gt;
&lt;p&gt;那么我也想看看为啥没人接单，就下载了&lt;strong&gt;京东秒送App&lt;/strong&gt;📱，然后注册账号、实名认证，正当我满心欢喜能接单的时候（已经在app上看到自己的单了🎉），需要进行学习📚，花了大约1分多钟，终于可以接单了，也是马上把自己的单抢了🚀。&lt;/p&gt;
&lt;p&gt;我点的是一份韩式炸鸡🍗，差不多9块钱，然后我这单配送费竟然高达6块💰，我自己也没电动车，出了地铁就扫了个共享电动车去拿外卖了。&lt;/p&gt;
&lt;p&gt;不得不说这些商家的地址太隐蔽了😵，我围着导航的地点转了几圈都没看到，最后是打商家电话才知道的📞，商家真实地址离导航差不多有50米偏差，而且门店在小道里面。&lt;/p&gt;
&lt;p&gt;我拿完单商家还问我怎么骑的共享电动车送外卖😲，我说：“点了半天没人就接单，我就自己下了个京东秒送自己接单了”，商家后面也说京东骑手不多，不过没卷的情况下京东外卖还是挺划算的。&lt;/p&gt;
&lt;p&gt;看似挣了&lt;code&gt;6.84&lt;/code&gt;💸，但扣除我的共享电动车&lt;code&gt;4.5&lt;/code&gt;和保险&lt;code&gt;3&lt;/code&gt;块，我还倒贴了。😭&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>转载：写一句项目描述，就能生成软著申请材料</title><link>https://blog.pljzy.top/posts/%E8%BD%AC%E8%BD%BD%E5%86%99%E4%B8%80%E5%8F%A5%E9%A1%B9%E7%9B%AE%E6%8F%8F%E8%BF%B0%E5%B0%B1%E8%83%BD%E7%94%9F%E6%88%90%E8%BD%AF%E8%91%97%E7%94%B3%E8%AF%B7%E6%9D%90%E6%96%99/%E8%BD%AC%E8%BD%BD%E5%86%99%E4%B8%80%E5%8F%A5%E9%A1%B9%E7%9B%AE%E6%8F%8F%E8%BF%B0%E5%B0%B1%E8%83%BD%E7%94%9F%E6%88%90%E8%BD%AF%E8%91%97%E7%94%B3%E8%AF%B7%E6%9D%90%E6%96%99/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%BD%AC%E8%BD%BD%E5%86%99%E4%B8%80%E5%8F%A5%E9%A1%B9%E7%9B%AE%E6%8F%8F%E8%BF%B0%E5%B0%B1%E8%83%BD%E7%94%9F%E6%88%90%E8%BD%AF%E8%91%97%E7%94%B3%E8%AF%B7%E6%9D%90%E6%96%99/%E8%BD%AC%E8%BD%BD%E5%86%99%E4%B8%80%E5%8F%A5%E9%A1%B9%E7%9B%AE%E6%8F%8F%E8%BF%B0%E5%B0%B1%E8%83%BD%E7%94%9F%E6%88%90%E8%BD%AF%E8%91%97%E7%94%B3%E8%AF%B7%E6%9D%90%E6%96%99/</guid><description>转载：写一句项目描述，就能生成软著申请材料一句话介绍你只要输入项目描述，就能快速得到可编辑、可导出的申请材料。</description><pubDate>Sat, 07 Feb 2026 13:34:42 GMT</pubDate><content:encoded>&lt;h1&gt;转载：写一句项目描述，就能生成软著申请材料&lt;/h1&gt;
&lt;h1&gt;一句话介绍&lt;/h1&gt;
&lt;p&gt;你只要输入项目描述，就能快速得到可编辑、可导出的申请材料。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;用户价值&lt;/h1&gt;
&lt;p&gt;上手快：一句话创建申请草稿，不懂流程也能开始。&lt;/p&gt;
&lt;p&gt;成本低：自己完成大部分材料准备，减少外包依赖。&lt;/p&gt;
&lt;p&gt;省时间：说明书和代码材料自动整理，支持直接导出。&lt;/p&gt;
&lt;p&gt;可追踪：申请进度、时间线、材料都在一个工作台里查看。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;用户最关心的功能&lt;/h1&gt;
&lt;h2&gt;1. 快速登录与账户安全&lt;/h2&gt;
&lt;p&gt;邮箱验证码登录、密码登录、Google 登录。&lt;/p&gt;
&lt;p&gt;忘记密码找回，支持新用户首次资料完善。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2. 软著申请一站式流程&lt;/h2&gt;
&lt;p&gt;新建申请：填写软件名称、版本、功能描述等核心信息。&lt;/p&gt;
&lt;p&gt;智能生成：自动生成申请摘要与基础材料。&lt;/p&gt;
&lt;p&gt;申请管理：列表查看、状态筛选、进度追踪。&lt;/p&gt;
&lt;p&gt;申请详情：支持在线编辑、提交与重新生成。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3. 材料导出能力（核心）&lt;/h2&gt;
&lt;p&gt;说明书工作台：Markdown 编辑、图表渲染、打印/PDF 导出。&lt;/p&gt;
&lt;p&gt;源代码工作台：代码自动排版、分页处理、打印/PDF 导出。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./8.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4. 实用 AI 工具箱（附加价值）&lt;/h2&gt;
&lt;p&gt;SVG Studio：在线编辑图形、AI 生成 SVG、导出图片。&lt;/p&gt;
&lt;p&gt;图片工坊：抠图、压缩、格式转换、切图。&lt;/p&gt;
&lt;p&gt;PDF 转图 / 图转 PDF：日常文档处理更高效。&lt;/p&gt;
&lt;p&gt;多模态生成：文生图、图生图、视频生成。&lt;/p&gt;
&lt;p&gt;合作协议生成：在线填写并导出。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./9.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./10.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./11.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;适合哪些用户&lt;/h1&gt;
&lt;p&gt;独立开发者：想快速完成软著材料准备并提交。&lt;/p&gt;
&lt;p&gt;自由职业者：希望低成本、自助完成申请文档制作。&lt;/p&gt;
&lt;p&gt;小型创业团队：需要稳定、可复用的申请流程模板。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s/_H5Vl7CSD5_T7VX7KZM1mA&quot;&gt;原文地址&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>微软的安全漏洞-Microsoft账户安全信息</title><link>https://blog.pljzy.top/posts/%E5%BE%AE%E8%BD%AF%E7%9A%84%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E-microsoft%E8%B4%A6%E6%88%B7%E5%AE%89%E5%85%A8%E4%BF%A1%E6%81%AF/%E5%BE%AE%E8%BD%AF%E7%9A%84%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E-microsoft%E8%B4%A6%E6%88%B7%E5%AE%89%E5%85%A8%E4%BF%A1%E6%81%AF/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%BE%AE%E8%BD%AF%E7%9A%84%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E-microsoft%E8%B4%A6%E6%88%B7%E5%AE%89%E5%85%A8%E4%BF%A1%E6%81%AF/%E5%BE%AE%E8%BD%AF%E7%9A%84%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E-microsoft%E8%B4%A6%E6%88%B7%E5%AE%89%E5%85%A8%E4%BF%A1%E6%81%AF/</guid><description>微软的安全漏洞-Microsoft账户安全信息前言新工作已经入职2个月了，第一个月很轻松，第二个月忙的飞起，也是没有时间管理博客写文章了。自从入职了新公司，博客园都没怎么打开过了，真的太忙了，我都感觉我工资要少了。😭说回正题，上班的时候莫名奇妙受到微软官方的邮件</description><pubDate>Wed, 28 Jan 2026 21:52:25 GMT</pubDate><content:encoded>&lt;h1&gt;微软的安全漏洞-Microsoft账户安全信息&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;新工作已经入职2个月了，第一个月很轻松，第二个月忙的飞起，也是没有时间管理博客写文章了。自从入职了新公司，博客园都没怎么打开过了，真的太忙了，我都感觉我工资要少了。😭
&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;说回正题，上班的时候莫名奇妙受到微软官方的邮件，还好我点进去看了一下，如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;总结一下就是任何人都可以修改你的Microsoft账户的安全信息，我也是百度了一下，发现2025年10月24日的时候有人向微软提交过这个问题，具体可以看这篇文章&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/zh-cn/answers/questions/5596086/microsoft-bug?page=1&quot;&gt;我的Microsoft账户安全信息已被替换，邮箱也被替换了,微软存在重大BUG - Microsoft Q&amp;amp;A&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;https://learn.microsoft.com/zh-cn/answers/questions/5596086/microsoft-bug?page=1)&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>24岁了！！！🎂</title><link>https://blog.pljzy.top/posts/24%E5%B2%81%E4%BA%86/24%E5%B2%81%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/24%E5%B2%81%E4%BA%86/24%E5%B2%81%E4%BA%86/</guid><description>24岁了！！！2026年了，前些日子太忙了，都没时间写文章，今天过24岁生日，水一篇。谢谢宝贝送的礼物🥰</description><pubDate>Wed, 07 Jan 2026 21:41:10 GMT</pubDate><content:encoded>&lt;h1&gt;24岁了！！！🎂&lt;/h1&gt;
&lt;p&gt;2026年了，前些日子太忙了，都没时间写文章，今天过24岁生日，水一篇。&lt;/p&gt;
&lt;p&gt;谢谢宝贝送的礼物🥰&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>迈从L7 Pro开箱 🖱️✨</title><link>https://blog.pljzy.top/posts/%E8%BF%88%E4%BB%8El7-pro%E5%BC%80%E7%AE%B1/%E8%BF%88%E4%BB%8El7-pro%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%BF%88%E4%BB%8El7-pro%E5%BC%80%E7%AE%B1/%E8%BF%88%E4%BB%8El7-pro%E5%BC%80%E7%AE%B1/</guid><description>迈从L7 Pro开箱 🖱️✨前言这段时间新工作入职没空写文章，难得空闲，也是借此机会写个开箱文章。⌛📝之前和我的女朋友提过一嘴，我说：“我的鼠标用了好久了，想换一个新鼠标”。</description><pubDate>Sun, 07 Dec 2025 16:26:18 GMT</pubDate><content:encoded>&lt;h1&gt;迈从L7 Pro开箱 🖱️✨&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;这段时间新工作入职没空写文章，难得空闲，也是借此机会写个开箱文章。⌛📝&lt;/p&gt;
&lt;p&gt;之前和我的女朋友提过一嘴，我说：“我的鼠标用了好久了，想换一个新鼠标”。原本打算她是等我过生日的时候送给我，但是周五下班回家，她拿出了一个鼠标包装，在的我惊讶和喜悦中，发现正是我想要换的小手鼠标。🎁💖&lt;/p&gt;
&lt;p&gt;选择小手鼠标的原因肯定是因为的我手小，再加上我之前的鼠标和 &lt;code&gt;L7&lt;/code&gt; 差不多大。&lt;/p&gt;
&lt;p&gt;下面开始进入正文。👇&lt;/p&gt;
&lt;h2&gt;老鼠标退休&lt;/h2&gt;
&lt;p&gt;从初中开始用，算下来差不多用了8、9年了，确切时间记不清了，不过用了这么久竟然没坏，质量还挺好。&lt;/p&gt;
&lt;p&gt;下面是包浆图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;参数介绍 📊&lt;/h2&gt;
&lt;p&gt;这里直接拿官方的图片出来了，我个人对鼠标的参数不是很了解，不过咱也不是电竞选手，平时用来打打游戏、办办公应该绰绰有余。🎮💼&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DPI&lt;/code&gt; 最高支持&lt;strong&gt;26000&lt;/strong&gt;，我尝试了一下，太快了，掌握不住，我之前的老鼠标也不知道 &lt;code&gt;DPI&lt;/code&gt; 用的是多少，用了那么久，也没找到驱动，反正用按钮能调节3个档位，慢、中快、快。⚡&lt;/p&gt;
&lt;p&gt;我目前 &lt;code&gt;L7&lt;/code&gt; 用的最舒服的 &lt;code&gt;DPI&lt;/code&gt; 是&lt;strong&gt;1600&lt;/strong&gt;，推演一下估计之前老鼠标的 &lt;code&gt;DPI&lt;/code&gt; 是&lt;strong&gt;1200&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;驱动展示 ⚙️&lt;/h2&gt;
&lt;p&gt;驱动页面整体还挺好看，可以设置 &lt;code&gt;DPI &lt;/code&gt;和开启电竞模式，以及设置鼠标轮询率，最高支持&lt;strong&gt;8000Hz&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;包装展示 📦&lt;/h2&gt;
&lt;p&gt;包装的标语：“年轻一代的选择”，还挺不错。👌&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;上手感觉 ✋&lt;/h2&gt;
&lt;p&gt;当时开箱拿起这个鼠标的时候就感觉到这个鼠标重量非常轻，比我之前的鼠标轻很多，官方写的重量是&lt;strong&gt;39g&lt;/strong&gt;。⚖️&lt;/p&gt;
&lt;p&gt;再就是我的选择果然没错，我习惯的握持姿势是抓握，我的小手握上去刚好合适，握着也不会感觉到累。😌&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;总结 ✨&lt;/h2&gt;
&lt;p&gt;总的来说，迈从 &lt;code&gt;L7 Pro&lt;/code&gt; 是一次非常满意的体验！从惊喜的礼物开箱🎁，到轻巧便携的设计✨，再到舒适的抓握手感🤲，每一个细节都让人感到愉悦。它不仅完美适配了我的小手🖐️，超高的DPI也满足了日常办公和偶尔游戏的需求🎯。感谢女朋友的心意，让这次升级充满了温馨与实用💝。如果你也在寻找一款适合小手的轻量级鼠标，&lt;code&gt;L7 Pro&lt;/code&gt;绝对值得考虑！👍&lt;/p&gt;
</content:encoded></item><item><title>搬家-做饭周记</title><link>https://blog.pljzy.top/posts/%E6%90%AC%E5%AE%B6-%E5%81%9A%E9%A5%AD%E5%91%A8%E8%AE%B0/%E6%90%AC%E5%AE%B6-%E5%81%9A%E9%A5%AD%E5%91%A8%E8%AE%B0/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%90%AC%E5%AE%B6-%E5%81%9A%E9%A5%AD%E5%91%A8%E8%AE%B0/%E6%90%AC%E5%AE%B6-%E5%81%9A%E9%A5%AD%E5%91%A8%E8%AE%B0/</guid><description>搬家-做饭周记前言祝贺自己跳槽成功 - ZY知识库 距离上篇跳槽文章已经过了2周了，我也是从旧公司离职了，这段时间还真忙，又是租房、然后搬家、交接项目一堆事。简单的记录下这次搬家把。</description><pubDate>Fri, 28 Nov 2025 21:18:47 GMT</pubDate><content:encoded>&lt;h1&gt;搬家-做饭周记&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/&quot;&gt;祝贺自己跳槽成功 - ZY知识库&lt;/a&gt; 距离上篇跳槽文章已经过了2周了，我也是从旧公司离职了，这段时间还真忙，又是租房、然后搬家、交接项目一堆事。&lt;/p&gt;
&lt;p&gt;简单的记录下这次搬家把。&lt;/p&gt;
&lt;h2&gt;旧家&lt;/h2&gt;
&lt;p&gt;这个地方我租了2年，除了厕所有点小有点潮湿外也没啥缺点了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;把我最重要的电脑打包好了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;新家&lt;/h2&gt;
&lt;p&gt;搞卫生、清东西累死了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;新家的阳台&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;厨艺展示&lt;/h2&gt;
&lt;p&gt;第二次抄辣椒炒肉，卖相可能不是太好，味道还是挺不错的。和第一次做鸡蛋面包。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>2019款联想拯救者Y7000清灰换硅脂</title><link>https://blog.pljzy.top/posts/%E8%81%94%E6%83%B3%E6%8B%AF%E6%95%91%E8%80%85y7000%E6%8D%A2%E7%A1%85%E8%84%82/2019%E6%AC%BE%E8%81%94%E6%83%B3%E6%8B%AF%E6%95%91%E8%80%85y7000%E6%B8%85%E7%81%B0%E6%8D%A2%E7%A1%85%E8%84%82/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%81%94%E6%83%B3%E6%8B%AF%E6%95%91%E8%80%85y7000%E6%8D%A2%E7%A1%85%E8%84%82/2019%E6%AC%BE%E8%81%94%E6%83%B3%E6%8B%AF%E6%95%91%E8%80%85y7000%E6%B8%85%E7%81%B0%E6%8D%A2%E7%A1%85%E8%84%82/</guid><description>给我的2019款联想拯救者Y7000清灰换硅脂前言由于24年新装了一台主机，我的联想拯救者也就一直放桌面吃灰了。</description><pubDate>Fri, 21 Nov 2025 10:48:21 GMT</pubDate><content:encoded>&lt;h1&gt;2019款联想拯救者Y7000清灰换硅脂&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;由于24年新装了一台&lt;strong&gt;主机&lt;/strong&gt;，我的&lt;strong&gt;联想拯救者&lt;/strong&gt;也就一直放桌面吃灰了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之前的3篇装机文章：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/&quot;&gt;&lt;strong&gt;小白装机-选配篇&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/&quot;&gt;小白装机-装机篇&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/4060/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-4060%E4%B8%8A%E6%9C%BA%E4%BD%93%E9%AA%8C%E6%84%9F%E5%8F%97%E5%88%86%E4%BA%AB/&quot;&gt;&lt;strong&gt;小白装机-上机体验篇&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后最近因为工作需要，不得已让它出山，这么久没用，灰尘多不讲，硅脂也从来没换过，那肯定会影响散热，影响散热就会影响性能，所以这次来给它做个全身&lt;strong&gt;spa&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;贴纸清洁&lt;/h2&gt;
&lt;p&gt;首先先把贴纸撕掉，这个贴纸贴了至少2年了，该退休了，之前也清理过一次，贴纸残留的胶水非常难清理，这次的贴纸也不例外。&lt;/p&gt;
&lt;p&gt;用了好多张酒精湿纸巾，加上棉签揉搓，大概清理了**90%&lt;strong&gt;的残留的胶水，其他&lt;/strong&gt;10%**不影响使用懒得弄了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开始拆机&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;tips: 养成好习惯，拆机前撸起袖子洗手并擦干。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;贴纸清理干净后，也是开始拆机。由于我很久之前就清理过灰尘（当时没换硅脂），所以拆起来比较轻松，第一次拆后盖，非常难拆，后盖卡得很紧，建议用拨片慢慢的别开，&lt;strong&gt;小心用力过猛&lt;/strong&gt;把后盖弄坏了。&lt;/p&gt;
&lt;p&gt;我这里素材拍少了，将就看一下吧。&lt;/p&gt;
&lt;p&gt;可以看到我的散热铜管和电池已经拆下来，这里是因为电池的那个接口太难拔了，拆下来好拔一点，&lt;strong&gt;不一定非得拆电池&lt;/strong&gt;，&lt;strong&gt;但是电池的主板接口一定要拔&lt;/strong&gt;，&lt;strong&gt;防止静电&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;由于之前清理过灰尘，风扇上的灰其实并不多，这次主要是为了换硅脂。&lt;/p&gt;
&lt;p&gt;清理风扇的灰尘最好用刷子刷，不要用水洗。&lt;/p&gt;
&lt;h2&gt;涂硅脂&lt;/h2&gt;
&lt;p&gt;我这里用的硅脂是利民的&lt;strong&gt;TF7&lt;/strong&gt;，还挺便宜的，某多上面&lt;strong&gt;9.9￥&lt;strong&gt;能买到&lt;/strong&gt;4g&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;涂新硅脂之前先把散热铜管和CPU上残留的旧硅脂清理干净。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;稍微涂得有一点不均匀，无伤大雅。&lt;/p&gt;
&lt;h2&gt;装机测试&lt;/h2&gt;
&lt;p&gt;来小烤一下看看温度是否稳定。由于拆机之前忘记烤了，所以只有换硅脂之后的温度，少了对比。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到烤鸡5分钟， &lt;code&gt;cpu&lt;/code&gt; 最大测试温度&lt;strong&gt;56°C&lt;/strong&gt;，还是挺稳的。&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;还能再用3年！！！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>祝贺自己跳槽成功</title><link>https://blog.pljzy.top/posts/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/%E7%A5%9D%E8%B4%BA%E8%87%AA%E5%B7%B1%E8%B7%B3%E6%A7%BD%E6%88%90%E5%8A%9F/</guid><description>祝贺自己跳槽成功故事的开头 📖本人：🎓 22届专科毕业-&gt;24届普通民本专升本毕业💻 计算机专业，专科方向 C#/.NET，本科方向 java负面 buff 叠满。😫</description><pubDate>Wed, 19 Nov 2025 15:49:19 GMT</pubDate><content:encoded>&lt;h1&gt;祝贺自己跳槽成功&lt;/h1&gt;
&lt;h2&gt;故事的开头 📖&lt;/h2&gt;
&lt;p&gt;本人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🎓 22届专科毕业-&amp;gt;24届普通民本专升本毕业&lt;/li&gt;
&lt;li&gt;💻 计算机专业，专科方向 &lt;code&gt;C#/.NET&lt;/code&gt;，本科方向 &lt;code&gt;java&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;负面 &lt;code&gt;buff&lt;/code&gt; 叠满。😫&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;22年专科毕业，由于专升本原因，没有找开发岗位实习。&lt;/p&gt;
&lt;p&gt;24年本科毕业，亲身体验就业市场的内卷，原本想在&lt;strong&gt;长沙&lt;/strong&gt;找一份实习工作，发现工资低得可怜（3000-3500），且没有任何福利可言，真的是把普本的实习生&lt;strong&gt;当日本人整&lt;/strong&gt;。💢&lt;/p&gt;
&lt;p&gt;只能海投了📮，经过几周的投递与面试，收到2个offer。一个上海 &lt;code&gt;.Net&lt;/code&gt;后端开发，工资&lt;strong&gt;4.8k&lt;/strong&gt;不包住，考虑到生活压力，放弃。&lt;/p&gt;
&lt;p&gt;另外一个苏州，也是&lt;code&gt;.Net&lt;/code&gt;后端开发，工资&lt;strong&gt;5k&lt;/strong&gt;，最后也是选择在苏州这家公司实习，生活压力相对比较小。&lt;/p&gt;
&lt;p&gt;这一干就是2年，我从&lt;strong&gt;23年10月&lt;/strong&gt;一直到现在，都在这家公司干，满打满算&lt;strong&gt;2年1个月&lt;/strong&gt;，期间只有转正时涨了一次薪，我转正后的薪资是税前6K。拿着这么低的工资干了1年多，&lt;strong&gt;今年7月&lt;/strong&gt;向公司提过涨薪，没有后文，所以我计划是年前离职，也就是&lt;strong&gt;26年1月份&lt;/strong&gt;离职，这是我原本的打算。💔&lt;/p&gt;
&lt;p&gt;这里应该就有人要问了，为什么不早点跳槽。主要原因有以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📜 学历不好，没有竞争力。&lt;/li&gt;
&lt;li&gt;🏢 24年又去面试过几家，收到过一个offer，但试用期6个月工资打8折，且我是在职，加上当时离职意愿不坚定（认为现在的公司会给我涨薪的），所以放弃了。&lt;/li&gt;
&lt;li&gt;👶 刚毕业经验不够，虽然我是&lt;strong&gt;23年10月&lt;/strong&gt;就参加了工作，但是我是24年才毕业，24年跳槽企业默认实习经验不算工作经验，导致开的工资也和现在公司差不了多少，所以我想着混个工作经验再跳。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总结一下：23年10月到至今，工资6k，期间有跳槽，但都没有成功，于是下定决心&lt;strong&gt;26年1月&lt;/strong&gt;离职。🔄&lt;/p&gt;
&lt;h2&gt;蓄力待发 💪&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;30年河东30年河西，莫欺少年穷。🔥&lt;/p&gt;
&lt;p&gt;大学期间遇良友，亦师亦友，今年11月他内推我面试一家互联网公司，也是做 &lt;code&gt;.Net&lt;/code&gt; 后端开发。&lt;/p&gt;
&lt;p&gt;经过我&lt;strong&gt;一周时间&lt;/strong&gt;的准备，背面试题，学新技术，我也是不负所托，通过了&lt;strong&gt;机试&lt;/strong&gt;和&lt;strong&gt;面试&lt;/strong&gt;。🎯&lt;/p&gt;
&lt;p&gt;奈何这家公司位于三线城市，开个工资达不到我的预期，同时该公司开始实行&lt;strong&gt;996&lt;/strong&gt;工作制，又把我劝退了。😮‍💨&lt;/p&gt;
&lt;p&gt;好在通过这次面试，让我清楚的认识到自己的实力，面试通过也是给了我很大的&lt;strong&gt;自信&lt;/strong&gt;，为后面的面试埋下了伏笔。🌟&lt;/p&gt;
&lt;h2&gt;绝地反击 🚀&lt;/h2&gt;
&lt;p&gt;虽然内推我的那家公司，薪资没谈拢，但是刚好&lt;strong&gt;boss直聘&lt;/strong&gt;有一家公司约我面试，我也是立马休了年假准备面试。&lt;/p&gt;
&lt;p&gt;机会来了挡都挡不住，因为我 &lt;code&gt;boss&lt;/code&gt; 很久没打开过了，我只是登录了一下 &lt;code&gt;boss&lt;/code&gt; 直聘的简历修改网站，可能 &lt;code&gt;boss&lt;/code&gt; 的算法把我归为活跃用户了，竟然有公司主动联系我。🤩&lt;/p&gt;
&lt;p&gt;第一轮面试：问了一些业务相关的问题，大约10分钟面试就结束了，当时觉得可能要凉了，便和女朋友出去吃饭了。吃饭途中收到&lt;strong&gt;HR二面&lt;/strong&gt;的邀请，也是约的当天下午，吃完饭马不停蹄的跑回家准备二面。🍚➡️🏠&lt;/p&gt;
&lt;p&gt;第二轮面试：问了一点编程基础，和项目相关的问题，面了大约20多分钟。&lt;/p&gt;
&lt;p&gt;这家公司和上面内推我的公司问的问题完全不一样，第一家公司问的技术问题比较多，技术要求比较高，然后第二家公司主要是业务和项目问题比较多，技术要求不高。&lt;/p&gt;
&lt;p&gt;可能因为第一家公司是互联网公司，第二家公司是制造业公司，虽然都是 &lt;code&gt;.Net&lt;/code&gt;后端开发，但是方向是完全不同的，比如互联网公司可能是做电商系统、 &lt;code&gt;OA&lt;/code&gt; 系统，而制造业公司大部分是 &lt;code&gt;MES&lt;/code&gt;、&lt;code&gt;WMS&lt;/code&gt; 等与生产有关的系统。🏭&lt;/p&gt;
&lt;p&gt;最后也是收到了HR面试通过的通知，谈好了待遇，并给我发了入职通知书，我也是第二天就像现在的公司提出了离职，等待项目交接的完成，就能入职新公司了。📨✅&lt;/p&gt;
&lt;p&gt;待遇比现在公司好很多，还是双休，薪资暂且保密~ 🤫&lt;/p&gt;
&lt;h2&gt;故事的结尾 🎬&lt;/h2&gt;
&lt;p&gt;历经2年，我也不在是之前啥也不懂的少年，经历了社会的毒打，体验到了生活的不易，好在有一堆知心朋友，还有个犟种女朋友陪着我。希望后面生活越来越好。🌈&lt;/p&gt;
&lt;p&gt;学历不是终点，我也迷茫过，想开点，抓住机会也能逆风翻盘。🎉&lt;/p&gt;
&lt;h2&gt;简历鉴赏&lt;/h2&gt;
&lt;p&gt;请尽情拷打我的简历吧，敏感信息已打码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>有趣的便签网站-使用Sdcb.WordCloud生成词云图</title><link>https://blog.pljzy.top/posts/%E4%BE%BF%E7%AD%BE%E7%BD%91%E7%AB%99-%E8%AF%8D%E4%BA%91%E5%9B%BE%E7%94%9F%E6%88%90/%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E7%BD%91%E7%AB%99-%E4%BD%BF%E7%94%A8sdcbwordcloud%E7%94%9F%E6%88%90%E8%AF%8D%E4%BA%91%E5%9B%BE/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E4%BE%BF%E7%AD%BE%E7%BD%91%E7%AB%99-%E8%AF%8D%E4%BA%91%E5%9B%BE%E7%94%9F%E6%88%90/%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E7%BD%91%E7%AB%99-%E4%BD%BF%E7%94%A8sdcbwordcloud%E7%94%9F%E6%88%90%E8%AF%8D%E4%BA%91%E5%9B%BE/</guid><description>有趣的便签网站-使用Sdcb.WordCloud生成词云图前言最近也是忙着面试、背题，终于闲下来，也是来更新下网站顺便写一篇文章~上周在网上看到一个静态的便签网站，我也是拿来用并发布了一篇文章，找到一个有趣的便签墙网站 - ZY知识库，后续也是制作了一个可以提交内容的便签网站，也发布了一篇文章，可以提交内容的便签墙来了 - ZY知识库。</description><pubDate>Fri, 14 Nov 2025 21:41:10 GMT</pubDate><content:encoded>&lt;h1&gt;有趣的便签网站-使用Sdcb.WordCloud生成词云图&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近也是忙着面试、背题，终于闲下来，也是来更新下网站顺便写一篇文章~&lt;/p&gt;
&lt;p&gt;上周在网上看到一个静态的便签网站，我也是拿来用并发布了一篇文章，&lt;a href=&quot;https://blog.pljzy.top/posts/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/&quot;&gt;找到一个有趣的便签墙网站 - ZY知识库&lt;/a&gt;，后续也是制作了一个可以提交内容的便签网站，也发布了一篇文章，&lt;a href=&quot;https://blog.pljzy.top/posts/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/&quot;&gt;可以提交内容的便签墙来了 - ZY知识库&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这两篇文章都比较火，特别是可以提交内容的便签网站，截止今日，已经有&lt;strong&gt;4000&lt;/strong&gt;千多条评论，去除重复的也有&lt;strong&gt;3000&lt;/strong&gt;多条，保守估计，网站搭建至今，访问人数和使用人数应该总和有&lt;strong&gt;100+&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;大部分人提交的内容都是表白、鼓励、吐槽之类的内容，也有一些人发布了恶意评论，当然已经被我删除掉了。&lt;/p&gt;
&lt;p&gt;需要注意的是，网站&lt;strong&gt;默认&lt;/strong&gt;只会展示最新的&lt;strong&gt;150&lt;/strong&gt;条信息，如果你发现你之前的信息找不到了，刷新网页好多次还是没看到，那么可能排序到最新的第&lt;strong&gt;150&lt;/strong&gt;条数据后面去了。&lt;/p&gt;
&lt;p&gt;下面是网站发布以来更新的内容&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2025/11/04 限制内容长度不能超过30字&lt;/li&gt;
&lt;li&gt;2025/11/05 限制 &lt;code&gt;xss&lt;/code&gt; 攻击&lt;/li&gt;
&lt;li&gt;2025/11/06 高估互联网的素质了，还是加上了关键词过滤&lt;/li&gt;
&lt;li&gt;2025/11/07 被恶意刷屏，无奈添加接口限流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么也是为了看看大家都发布的什么内容，也是心血来潮想着用词云图实现一下，通过数据清洗、筛选来看看出现频率最高的词语有哪些，并用 &lt;code&gt;词云图&lt;/code&gt; 的形式展示出来，话不多说开始操作。&lt;/p&gt;
&lt;p&gt;便签网站直达地址：https://pljzy.top/noteweb&lt;/p&gt;
&lt;h2&gt;前端设计&lt;/h2&gt;
&lt;p&gt;前端页面就很简单的设计了一个&lt;strong&gt;词云图&lt;/strong&gt;跳转按钮，通过点击这个按钮可以查看词云图。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;后端设计&lt;/h2&gt;
&lt;p&gt;后端采用的是.Net框架，那么生成词云图必然也是.Net框架下的包，我这里使用的是 &lt;code&gt;Sdcb.WordCloud&lt;/code&gt; 包。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet add package Sdcb.WordCloud
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个包&lt;strong&gt;Star&lt;/strong&gt;数比较少，可能因为词云图本身不是很知名吧，之前绘制词云图还是学校时期用 &lt;code&gt;python&lt;/code&gt; 绘制过。不得不说 &lt;code&gt;python&lt;/code&gt; 的包是又多又方便~&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sdcb/Sdcb.WordCloud&quot;&gt;sdcb/Sdcb.WordCloud: Generate WordCloud image from .NET/.NET Core&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;踩坑指南&lt;/h3&gt;
&lt;p&gt;我在本地 &lt;code&gt;windows&lt;/code&gt; 环境下生成词云图是没问题的，当我部署到 &lt;code&gt;Liunx&lt;/code&gt; 系统下时，会提示缺少依赖，后面发现需要手动导入 &lt;code&gt;SkiaSharp.NativeAssets.Linux.NoDependencies&lt;/code&gt; 包。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;关键代码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public async Task GenerateWordCloud()
{
    try
    {
        using var scope = _serviceProvider.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService&amp;lt;MyDbContext&amp;gt;();

        var allNotes = await db.Notes.Select(n =&amp;gt; n.Content).ToListAsync();
        var text = string.Join(&quot; &quot;, allNotes);

        // 处理文本并生成词频统计
        var words = ProcessText(text)
            .GroupBy(word =&amp;gt; word)
            .ToDictionary(g =&amp;gt; g.Key, g =&amp;gt; g.Count())
            .OrderByDescending(kv =&amp;gt; kv.Value) // 按词频降序排序
            .Take(150) // 取前150个高频词
            .ToDictionary(kv =&amp;gt; kv.Key, kv =&amp;gt; kv.Value)
            .Select(kv =&amp;gt; new WordScore(kv.Key, kv.Value));	// 转换为WordScore对象集合

        // 创建词云实例，设置画布大小为1000x1000
        WordCloud wc = WordCloud.Create(new WordCloudOptions(1000, 1000, words));
        byte[] pngBytes = wc.ToSKBitmap().Encode(SKEncodedImageFormat.Png, 100).AsSpan().ToArray();

        string filePath = &quot;wwwroot/wordcloud.png&quot;;

        // 将PNG图片保存到文件
        await File.WriteAllBytesAsync(filePath, pngBytes);

        _logger.LogInformation($&quot;词云图已更新: {DateTime.Now:yyyy-MM-dd HH:mm:ss}&quot;);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, &quot;生成词云图时发生错误&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里由于各方面因素影响，只获取了词频出现最多的前 &lt;code&gt;150&lt;/code&gt; 条数据。&lt;/p&gt;
&lt;h3&gt;定时任务&lt;/h3&gt;
&lt;p&gt;由于词云图生成比较慢，我试了一下150条数据，生成大概要 &lt;code&gt;20~30s&lt;/code&gt; ，如果做成接口的话响应很慢，用户体验也不好。&lt;/p&gt;
&lt;p&gt;那么我也是采用后台定时任务去执行，我使用的是 &lt;code&gt;Hangfire&lt;/code&gt; ，每隔&lt;strong&gt;4小时&lt;/strong&gt;重新绘制一次图像。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet add package Hangfire
dotnet add package Hangfire.MemoryStorage
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;关键代码&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddHangfire(config =&amp;gt;
    config.UseMemoryStorage());
builder.Services.AddHangfireServer();

// 每天0:00, 4:00, 8:00, 12:00, 16:00, 20:00执行
RecurringJob.AddOrUpdate&amp;lt;WordCloudService&amp;gt;(
    &quot;generate-wordcloud&quot;,
    service =&amp;gt; service.GenerateWordCloud(),
    &quot;0 0,4,8,12,16,20 * * *&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;多提一嘴&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;Hangfire&lt;/code&gt; 可以选择是否开启仪表板，仪表板截图如下，用来查看任务执行情况还是挺方便的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;词云图效果&lt;/h2&gt;
&lt;p&gt;好像大家都有喜欢的人呀，词云图每隔4小时更新一次，如果发现自己发的文字没有在里面可能是出现频率不高，不过不建议大家刷留言~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;结尾&lt;/h2&gt;
&lt;p&gt;如果对项目源代码感兴趣的可以访问 &lt;code&gt;Github&lt;/code&gt; 并点上 &lt;code&gt;Star&lt;/code&gt; ，&lt;a href=&quot;https://github.com/ZyPLJ/NoteWeb&quot;&gt;ZyPLJ/NoteWeb: 便签墙带后端版本，可以随心所欲(注意文明用语)的发送便签~&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这个项目也就到这里结束了，后续不会更新内容，网站会一直存在，除非服务器到期和其他不可避免因素导致网站关闭。&lt;/p&gt;
&lt;p&gt;总的来说，这是一个很有趣的项目，希望能一直存在下去~&lt;/p&gt;
&lt;p&gt;最后放上新的截图：&lt;/p&gt;
</content:encoded></item><item><title>可以提交内容的便签墙来了</title><link>https://blog.pljzy.top/posts/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BA%A4%E5%86%85%E5%AE%B9%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E6%9D%A5%E4%BA%86/</guid><description>可以提交内容的便签墙来了前言上一篇文章发布了一篇：有趣的便签墙发现有很多人都觉得挺有趣的，那么也是有人提问能不能输入，当时那篇文章的是一个静态网站，是没有后端的，所以是没办法输入并在便签墙显示。</description><pubDate>Tue, 04 Nov 2025 09:17:46 GMT</pubDate><content:encoded>&lt;h1&gt;可以提交内容的便签墙来了&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;上一篇文章发布了一篇：&lt;a href=&quot;https://blog.pljzy.top/posts/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/&quot;&gt;有趣的便签墙&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;发现有很多人都觉得挺有趣的，那么也是有人提问能不能输入，当时那篇文章的是一个静态网站，是没有后端的，所以是没办法输入并在便签墙显示。&lt;/p&gt;
&lt;p&gt;我也是挤了点时间出来，非常快速的搭建了一个后端服务，然后稍微前后端对接了一下，然后又稍微操作一下部署到服务器上，最终也是成功完成部署，话不多说展示地址：&lt;/p&gt;
&lt;p&gt;Github：https://github.com/ZyPLJ/NoteWeb&lt;/p&gt;
&lt;p&gt;快速访问：https://www.pljzy.top/noteweb&lt;/p&gt;
&lt;h2&gt;多提一嘴&lt;/h2&gt;
&lt;p&gt;突然发现我的老博客的留言板和这个便签墙功能挺类似的，哈哈。这里放一个地址，感兴趣的可以去看看，老博客已经不维护了~&lt;/p&gt;
&lt;p&gt;快速访问：https://pljzy.top/MsgBoard&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;技术栈&lt;/h2&gt;
&lt;h3&gt;前端&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTML5&lt;/li&gt;
&lt;li&gt;CSS3&lt;/li&gt;
&lt;li&gt;JavaScript (原生)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;后端&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ASP.NET Core 9.0&lt;/li&gt;
&lt;li&gt;Entity Framework Core&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;项目结构&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;NoteWeb/
├── Entity/
│   ├── Model/
│   │   └── Note.cs         # 便签数据模型
│   ├── MyDbContext.cs      # 数据库上下文
│   └── MyDbContextDesignFac.cs
├── wwwroot/                # 静态资源
│   ├── img/                # 图片资源
│   └── index.html          # 前端页面
├── Program.cs              # 应用入口和API定义
├── appsettings.json        # 应用配置
└── noteweb.db              # SQLite数据库文件
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;效果展示&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;p&gt;由于是赶鸭子上架，后端只是写了2个接口，一个查询一个新增，且没做&lt;strong&gt;关键词校验&lt;/strong&gt;、&lt;strong&gt;限流&lt;/strong&gt;，所以请大家&lt;strong&gt;文明发言&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;然后其他&lt;strong&gt;项目详情&lt;/strong&gt;请移步 &lt;a href=&quot;https://github.com/ZyPLJ/NoteWeb&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本项目尚未完结，有许多bug！！！&lt;/li&gt;
&lt;li&gt;文明发言~&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>我的发！网站CDN被刷了 😱</title><link>https://blog.pljzy.top/posts/%E6%88%91%E7%9A%84%E5%8F%91%E7%BD%91%E7%AB%99cdn%E8%A2%AB%E5%88%B7%E4%BA%86/%E6%88%91%E7%9A%84%E5%8F%91%E7%BD%91%E7%AB%99cdn%E8%A2%AB%E5%88%B7%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%88%91%E7%9A%84%E5%8F%91%E7%BD%91%E7%AB%99cdn%E8%A2%AB%E5%88%B7%E4%BA%86/%E6%88%91%E7%9A%84%E5%8F%91%E7%BD%91%E7%AB%99cdn%E8%A2%AB%E5%88%B7%E4%BA%86/</guid><description>我的发！网站CDN被刷了 😱前言当我正沉浸在周末休闲时光的时候，一封欠费短信📱打扰了正在享受休闲时光的我。当我打开手机，查看短信的时候，发现竟然是七牛云CDN欠费通知，当时第一反应是比较震惊的😳，因为我平时一个月CDN费用才2元不到，平时网站访问量不高，而且我只是部分静态文件放在七牛云上。</description><pubDate>Sun, 02 Nov 2025 21:59:38 GMT</pubDate><content:encoded>&lt;h1&gt;我的发！网站CDN被刷了 😱&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;./689fe8963fbba.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;当我正沉浸在周末休闲时光的时候，一封欠费短信📱打扰了正在享受休闲时光的我。&lt;/p&gt;
&lt;p&gt;当我打开手机，查看短信的时候，发现竟然是七牛云&lt;code&gt;CDN&lt;/code&gt;欠费通知，当时第一反应是比较震惊的😳，因为我平时一个月&lt;code&gt;CDN&lt;/code&gt;费用才2元不到，平时网站访问量不高，而且我只是部分静态文件放在&lt;code&gt;七牛云&lt;/code&gt;上。&lt;/p&gt;
&lt;p&gt;最主要的是我前几天才充值，莫名奇妙就欠费了，后面我通过查看网站访问量发现访问量并不是很多，这个时候我就已经确认是有人在刷我的&lt;code&gt;CDN&lt;/code&gt;了💔。&lt;/p&gt;
&lt;p&gt;然后我登录七牛云管理平台，发现&lt;strong&gt;10月31号&lt;/strong&gt;和&lt;strong&gt;11月1号&lt;/strong&gt;晚上&lt;strong&gt;21:00-23:00&lt;/strong&gt;短短3个小时刷了&lt;strong&gt;10G&lt;/strong&gt;流量，2天用了我&lt;code&gt;20G&lt;/code&gt;📈。&lt;/p&gt;
&lt;h2&gt;短信截图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;七牛云截图&lt;/h2&gt;
&lt;p&gt;可以看到平时正常来讲是几乎没有多少流量的，&lt;strong&gt;31号&lt;/strong&gt;和&lt;strong&gt;1号&lt;/strong&gt;突然就激增📊。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开始排查 🔍&lt;/h2&gt;
&lt;p&gt;通过查看七牛云的请求日志，发现是国内的&lt;code&gt;IP&lt;/code&gt;在刷，&lt;code&gt;IP&lt;/code&gt;具体的地址是&lt;strong&gt;湖北黄石市&lt;/strong&gt;，当然有可能攻击者只是用的这个地方的&lt;code&gt;IP&lt;/code&gt;进行攻击，不一定是这个地区的人。&lt;/p&gt;
&lt;p&gt;不过很少有用国内&lt;code&gt;IP&lt;/code&gt;进行攻击的，当然攻击者不只是这个&lt;code&gt;IP&lt;/code&gt;进行盗刷，有其他网段的&lt;code&gt;IP&lt;/code&gt;，不过都指向湖北黄石市📍。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开始处理 🛠️&lt;/h2&gt;
&lt;p&gt;其实我对&lt;code&gt;CDN&lt;/code&gt;配置并不上心，也不是很懂这方面的配置，我之前对&lt;code&gt;CDN&lt;/code&gt;只配置了&lt;code&gt;Referer&lt;/code&gt; 防盗链，因为我的&lt;code&gt;CDN&lt;/code&gt;主要是加速静态文件，然后我的对象存储服务是没有配置防盗链的，然后我这边也是加上了防盗链🔒。&lt;/p&gt;
&lt;p&gt;然后将攻击者&lt;code&gt;IP&lt;/code&gt;网段拉入了黑名单🚫，七牛云的&lt;code&gt;AI&lt;/code&gt;给我的建议是将&lt;strong&gt;对象存储&lt;/strong&gt;设置成私有访问，但是每次请求需要有&lt;code&gt;token&lt;/code&gt;才行，我懒得配置，目前就先这样解决吧。&lt;/p&gt;
&lt;h2&gt;结尾&lt;/h2&gt;
&lt;p&gt;因为我的网站只是个人博客，对于一个访问量不高的博客来说&lt;code&gt;10G&lt;/code&gt;流量已经算很多了，而且个人博客纯属是爱好，并不想投入太多的资金💸。&lt;/p&gt;
&lt;p&gt;后续还被盗刷的话我就准备停用&lt;code&gt;CDN&lt;/code&gt;了，一开始使用七牛云&lt;code&gt;CDN&lt;/code&gt;的原因是我的服务器带宽太低了，想减少点静态文件的加载速度⚡。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./689fe8963fbba.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>找到一个有趣的便签墙网站</title><link>https://blog.pljzy.top/posts/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84%E4%BE%BF%E7%AD%BE%E5%A2%99%E7%BD%91%E7%AB%99/</guid><description>找到一个有趣的便签墙网站前言在网上冲浪的时候发现了一个有趣的网站：https://pljzy.top/note.html</description><pubDate>Fri, 31 Oct 2025 16:38:49 GMT</pubDate><content:encoded>&lt;h1&gt;找到一个有趣的便签墙网站&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在网上冲浪的时候发现了一个有趣的网站：https://pljzy.top/note.html&lt;/p&gt;
&lt;p&gt;这个网站作者是：https://github.com/uninto/notes ，纯&lt;code&gt;html&lt;/code&gt;、&lt;code&gt;css&lt;/code&gt;、&lt;code&gt;js&lt;/code&gt;实现。&lt;/p&gt;
&lt;p&gt;:spoiler[嘿嘿，被我偷过来了。]&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>博客篇：文章列表添加评论数显示</title><link>https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%87%E7%AB%A0%E5%88%97%E8%A1%A8%E6%B7%BB%E5%8A%A0%E8%AF%84%E8%AE%BA%E6%95%B0%E6%98%BE%E7%A4%BA/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%87%E7%AB%A0%E5%88%97%E8%A1%A8%E6%B7%BB%E5%8A%A0%E8%AF%84%E8%AE%BA%E6%95%B0%E6%98%BE%E7%A4%BA/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%87%E7%AB%A0%E5%88%97%E8%A1%A8%E6%B7%BB%E5%8A%A0%E8%AF%84%E8%AE%BA%E6%95%B0%E6%98%BE%E7%A4%BA/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%87%E7%AB%A0%E5%88%97%E8%A1%A8%E6%B7%BB%E5%8A%A0%E8%AF%84%E8%AE%BA%E6%95%B0%E6%98%BE%E7%A4%BA/</guid><description>博客篇：文章列表添加评论数显示前言目前博客文章列表只会显示字数和阅读时间，不会显示评论数,不过博客接入了twikoo评论系统，我翻了翻官方文档，发现有提供获取评论数的API接口。如图：那么事情就变得简单起来了，只需要调用这个接口，然后把返回的数据渲染到对于的文章列表上即可。</description><pubDate>Tue, 28 Oct 2025 13:57:29 GMT</pubDate><content:encoded>&lt;h1&gt;博客篇：文章列表添加评论数显示&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;目前博客文章列表只会显示字数和阅读时间，不会显示评论数,不过博客接入了&lt;a href=&quot;https://twikoo.js.org/frontend.html&quot;&gt;twikoo&lt;/a&gt;评论系统，我翻了翻官方文档，发现有提供获取评论数的&lt;code&gt;API&lt;/code&gt;接口。如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;那么事情就变得简单起来了，只需要调用这个接口，然后把返回的数据渲染到对于的文章列表上即可。&lt;/p&gt;
&lt;h2&gt;说说缺点&lt;/h2&gt;
&lt;p&gt;不过依赖于外部插件，对于&lt;code&gt;Astro&lt;/code&gt;框架的静态博客不是很友好，会拖慢网站加载速度，虽然可以忽约不计，但是多少有点影响。&lt;/p&gt;
&lt;p&gt;目前博客集成第三方主要就是&lt;a href=&quot;https://twikoo.js.org/frontend.html&quot;&gt;twikoo&lt;/a&gt;、&lt;a href=&quot;https://blog.liushen.fun/posts/4dc716ec/&quot;&gt;友链朋友圈&lt;/a&gt;、&lt;a href=&quot;https://docs.lsky.pro/&quot;&gt;lsky图床&lt;/a&gt;，对于友链朋友圈和图床我都是单开一个页面，实际对博客的影响非常小，即使服务崩溃也不会影响网站正常运行。&lt;/p&gt;
&lt;p&gt;为了尽可能的达到对这些第三方集成完美控制，我都有在&lt;code&gt;config.ts&lt;/code&gt;做开关配置，可以配置是否开启这些功能或页面。&lt;/p&gt;
&lt;h2&gt;主要代码&lt;/h2&gt;
&lt;h3&gt;PostCard 页面&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src-&amp;gt;components-&amp;gt;PostCard.astro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在阅读时长旁边添加&lt;strong&gt;评论数&lt;/strong&gt;显示元素。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { commentConfig } from &quot;src/config&quot;;

&amp;lt;!-- word count, read time and comment count  --&amp;gt;
&amp;lt;div class=&quot;text-sm text-black/30 dark:text-white/30 flex gap-4 transition&quot;&amp;gt;
    &amp;lt;div&amp;gt;
        {remarkPluginFrontmatter.words} {&quot; &quot; + i18n(remarkPluginFrontmatter.words === 1 ? I18nKey.wordCount : I18nKey.wordsCount)}
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;|&amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
        {remarkPluginFrontmatter.minutes} {&quot; &quot; + i18n(remarkPluginFrontmatter.minutes === 1 ? I18nKey.minuteCount : I18nKey.minutesCount)}
    &amp;lt;/div&amp;gt;
    {commentConfig.enable &amp;amp;&amp;amp; (
        &amp;lt;&amp;gt;
            &amp;lt;div&amp;gt;|&amp;lt;/div&amp;gt;
            &amp;lt;span class=&quot;comment-count&quot; data-path={url}&amp;gt;
                &amp;lt;span&amp;gt;0&amp;lt;/span&amp;gt;
                &amp;lt;span&amp;gt;{i18n(I18nKey.commentsCount)}&amp;lt;/span&amp;gt;
            &amp;lt;/span&amp;gt;
        &amp;lt;/&amp;gt;
    )}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;twikoo-loader&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;public-&amp;gt;lib-&amp;gt;twikoo-loader.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;新建一份&lt;code&gt;twikoo-loader.js&lt;/code&gt;文件，请求&lt;code&gt;API&lt;/code&gt;和渲染操作都在这个文件中完成。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// public/lib/twikoo-loader.js

(function () {
	if (window.__twikooLoaderInitialized) return;
	window.__twikooLoaderInitialized = true;

	let twikooLoadTimer;

	// 加载评论数量
	const loadTwikooCommentCount = () =&amp;gt; {
		if (!window.twikoo) return;

		const commentEls = document.querySelectorAll(&quot;.comment-count[data-path]&quot;);
		if (commentEls.length === 0) return;

		const paths = Array.from(commentEls)
			.map((el) =&amp;gt; el.dataset.path)
			.map((path) =&amp;gt; path.split(&quot;/&quot;).map(encodeURIComponent).join(&quot;/&quot;));

		// 从全局配置获取Twikoo参数
		const twikooConfig = window.commentConfig?.twikoo || {};

		window.twikoo
			.getCommentsCount({
				envId: twikooConfig.envId || &quot;选填&quot;,
				region: twikooConfig.region || &quot;选填&quot;,
				urls: paths,
				includeReply: true,
			})
			.then((res) =&amp;gt; {
				res.forEach((item) =&amp;gt; {
					const el = document.querySelector(
						`.comment-count[data-path=&quot;${decodeURIComponent(item.url)}&quot;] span:nth-child(1)`,
					);
					if (el) el.textContent = `${item.count}`;
				});
			})
			.catch(console.error);
	};

	// 确保 Twikoo 加载
	const ensureTwikooLoaded = () =&amp;gt; {
		clearTimeout(twikooLoadTimer);
		twikooLoadTimer = setTimeout(() =&amp;gt; {
			if (window.twikooLoaded) {
				loadTwikooCommentCount();
			} else if (!window.twikooLoading) {
				window.twikooLoading = true;
				const script = document.createElement(&quot;script&quot;);
				script.src =
					&quot;https://registry.npmmirror.com/twikoo/1.6.44/files/dist/twikoo.min.js&quot;; // 国内默认CDN
				script.onload = () =&amp;gt; {
					window.twikooLoaded = true;
					loadTwikooCommentCount();
				};
				document.head.appendChild(script);
			}
		}, 200);
	};

	// 绑定事件（只绑定一次）
	const bindEvents = () =&amp;gt; {
		const safeReload = () =&amp;gt; ensureTwikooLoaded();
		document.addEventListener(&quot;astro:page-load&quot;, safeReload);
		document.addEventListener(&quot;swup:page:view&quot;, safeReload);
	};

	// 初始化
	ensureTwikooLoaded();
	bindEvents();
})();

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个&lt;code&gt;js&lt;/code&gt;文件主要完成的操作就是根据官方文档所描述的配置&lt;code&gt;getCommentsCount&lt;/code&gt;方法，发送请求，然后将返回的数据渲染到页面上。需要注意的是&lt;code&gt;script.src&lt;/code&gt;的值需要自己调整，我这里是使用的官方推荐的国内&lt;code&gt;cdn&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;通过-&lt;code&gt;cdn&lt;/code&gt;-引入：&lt;a href=&quot;https://twikoo.js.org/frontend.html#%E9%80%9A%E8%BF%87-cdn-%E5%BC%95%E5%85%A5&quot;&gt;前端部署 | Twikoo 文档&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Config&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src-&amp;gt;Config.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在配置文件中添加评论组件的相关配置，这个之前在集成&lt;a href=&quot;https://twikoo.js.org/frontend.html&quot;&gt;twikoo&lt;/a&gt;就添加过了&lt;a href=&quot;https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/&quot;&gt;astrofuwai配置教程&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要注意&lt;code&gt;envId&lt;/code&gt;的配置就行了，我是私有部署的，所以我这里填的是我部署的评论系统后端的&lt;code&gt;ip|域名&lt;/code&gt;地址。&lt;/p&gt;
&lt;p&gt;修改&lt;code&gt;enable&lt;/code&gt;为&lt;code&gt;false&lt;/code&gt;就能关闭评论，包括评论数展示。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const commentConfig = {
	enable: true,
	provider: &quot;twikoo&quot;,
	twikoo: {
		envId: &quot;https://api.pljzy.top&quot;, // 部署的项目地址
		region: &quot;&quot;,
		lang: &quot;zh-CN&quot;,
	},
};

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Layout 页面&lt;/h3&gt;
&lt;p&gt;最后在&lt;code&gt;Layout&lt;/code&gt;页面导入并使用&lt;code&gt;twikoo-loader.js&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { commentConfig } from &quot;src/config&quot;;


{commentConfig.enable &amp;amp;&amp;amp; (
  &amp;lt;&amp;gt;
    &amp;lt;script is:inline define:vars={{ commentConfig }}&amp;gt;
	  window.commentConfig = commentConfig;
      // 动态加载 Twikoo Loader（保证执行顺序）
      const script = document.createElement(&apos;script&apos;);
      script.src = &apos;/scripts/twikoo-loader.js&apos;;
      script.defer = true; // 延迟到 HTML 解析后执行
      document.head.appendChild(script);
    &amp;lt;/script&amp;gt;
  &amp;lt;/&amp;gt;
)}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;实现效果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;对于文章添加评论数显示，主要代码逻辑在&lt;code&gt;twikoo-loader.js&lt;/code&gt;中完成，然后只需在母版页中导入并使用即可。&lt;/p&gt;
&lt;p&gt;为了可以控制评论组件和评论数是否显示，可以直接修改&lt;code&gt;Config.ts&lt;/code&gt;中的&lt;code&gt;enable&lt;/code&gt;属性。&lt;/p&gt;
&lt;h2&gt;相关链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;评论系统：&lt;a href=&quot;https://twikoo.js.org/frontend.html&quot;&gt;twikoo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;本博客配置教程：&lt;a href=&quot;https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/&quot;&gt;astrofuwai配置教程&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>博客篇：TwiKoo实现评论图片点击放大 🖼️✨</title><link>https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87twikoo%E5%AE%9E%E7%8E%B0%E8%AF%84%E8%AE%BA%E5%9B%BE%E7%89%87%E7%82%B9%E5%87%BB%E6%94%BE%E5%A4%A7/%E5%8D%9A%E5%AE%A2%E7%AF%87twikoo%E5%AE%9E%E7%8E%B0%E8%AF%84%E8%AE%BA%E5%9B%BE%E7%89%87%E7%82%B9%E5%87%BB%E6%94%BE%E5%A4%A7/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87twikoo%E5%AE%9E%E7%8E%B0%E8%AF%84%E8%AE%BA%E5%9B%BE%E7%89%87%E7%82%B9%E5%87%BB%E6%94%BE%E5%A4%A7/%E5%8D%9A%E5%AE%A2%E7%AF%87twikoo%E5%AE%9E%E7%8E%B0%E8%AF%84%E8%AE%BA%E5%9B%BE%E7%89%87%E7%82%B9%E5%87%BB%E6%94%BE%E5%A4%A7/</guid><description>博客篇：TwiKoo实现评论图片点击放大 🖼️✨前言 💬之前博客写过一篇配置文章，里面有讲解如何集成TwiKoo评论系统。Astro/fuwai博客配置教程不过TwiKoo默认是不支持图片点击放大的，但是fuwari主题默认是支持图片点击放大的。那么这就非常好实现了💡，也不需要引入其他的插件了🙌。</description><pubDate>Thu, 23 Oct 2025 11:03:39 GMT</pubDate><content:encoded>&lt;h1&gt;博客篇：TwiKoo实现评论图片点击放大 🖼️✨&lt;/h1&gt;
&lt;h2&gt;前言 💬&lt;/h2&gt;
&lt;p&gt;之前博客写过一篇配置文章，里面有讲解如何集成&lt;code&gt;TwiKoo&lt;/code&gt;评论系统。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/&quot;&gt;Astro/fuwai博客配置教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;不过&lt;code&gt;TwiKoo&lt;/code&gt;默认是不支持图片点击放大的，但是&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;主题默认是支持图片点击放大的。&lt;/p&gt;
&lt;p&gt;那么这就非常好实现了💡，也不需要引入其他的插件了🙌。&lt;/p&gt;
&lt;h2&gt;开始实现 🛠️&lt;/h2&gt;
&lt;h3&gt;修改配置文件 ⚙️&lt;/h3&gt;
&lt;p&gt;通过阅读代码发现&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;主题是用的&lt;code&gt;PhotoSwipe&lt;/code&gt;插件实现的图片点击放大🔍。&lt;/p&gt;
&lt;p&gt;具体代码在&lt;code&gt;src/layouts/Layout.astro&lt;/code&gt;文件中配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createPhotoSwipe() {
	lightbox = new PhotoSwipeLightbox({
		gallery: &quot;.custom-md img, #post-cover img, .tk-content img&quot;,
		...
	)}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;首先需要在&lt;code&gt;gallery&lt;/code&gt;中添加&lt;code&gt;TwiKoo&lt;/code&gt;评论区域&lt;code&gt;img&lt;/code&gt;标签图片所在的父元素&lt;code&gt;ID&lt;/code&gt;或者&lt;code&gt;class&lt;/code&gt;属性。&lt;/p&gt;
&lt;p&gt;我这里就直接在原本基础上加上了：&lt;code&gt;.tk-content img&lt;/code&gt; 🧩。&lt;/p&gt;
&lt;p&gt;但是由于我们的评论组件是 &lt;strong&gt;动态加载&lt;/strong&gt; 的⚡，所以想让图片点击生效还需要添加一行代码，将&lt;code&gt;createPhotoSwipe&lt;/code&gt;方法绑定到&lt;code&gt;window&lt;/code&gt;对象上。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createPhotoSwipe() {
	lightbox = new PhotoSwipeLightbox({
		gallery: &quot;.custom-md img, #post-cover img, .tk-content img&quot;,
		...
	)}
}

(window as any).createPhotoSwipe = createPhotoSwipe;

...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改评论组件 💻&lt;/h3&gt;
&lt;p&gt;虽然实现了点击放大🖱️，但是鼠标移入图片的时候，鼠标应该变为放大镜🔎，所以还需要修改评论组件，添加样式。&lt;/p&gt;
&lt;p&gt;需要在&lt;code&gt;script&lt;/code&gt;代码里面动态添加上样式代码🎨：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 动态创建样式并添加到页面
const style = document.createElement(&apos;style&apos;);
style.textContent = `
                        .tk-content img {
                            cursor: zoom-in;
                            transition: opacity 0.2s ease;
                        }
                        .tk-content img:hover {
                            opacity: 0.9;
                        }
                     `;
document.head.appendChild(style);
console.log(&quot;动态样式已添加到页面&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在评论组件&lt;code&gt;init&lt;/code&gt;方法中的&lt;code&gt;onCommentLoaded&lt;/code&gt;事件中调用刚刚为&lt;code&gt;window&lt;/code&gt;对象绑定的方法⚙️。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;twikoo.init({
    envId: commentConfig.twikoo.envId,
    el: &apos;#tcomment&apos;,
    region: commentConfig.twikoo.region,
    path: location.pathname,
    lang: commentConfig.twikoo.lang,
    onCommentLoaded: function() {
        console.log(&apos;Twikoo comments loaded successfully&apos;);
        if (window.createPhotoSwipe){
            window.createPhotoSwipe();
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就完成了评论组件里面图片的点击放大功能 🎉。&lt;/p&gt;
&lt;h2&gt;效果展示 👀&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;总结 📝&lt;/h2&gt;
&lt;p&gt;对于&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;主题的博客，在集成&lt;a href=&quot;https://twikoo.js.org/frontend.html#%E9%80%9A%E8%BF%87-cdn-%E5%BC%95%E5%85%A5&quot;&gt;twikoo&lt;/a&gt;后，
想在评论区实现图片点击放大，只需要修改&lt;code&gt;Layout.astro&lt;/code&gt;文件和&lt;strong&gt;评论组件&lt;/strong&gt;就行了💪。&lt;/p&gt;
&lt;p&gt;当然这只是其中一种方式，还有很多方式可以实现评论区图片点击放大 🌈，有更多更好的实现方式可以在评论区留言~ 💬&lt;/p&gt;
&lt;h2&gt;参考链接 🔗&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本博客 &lt;code&gt;Github&lt;/code&gt; 地址：https://github.com/ZyPLJ/fuwai_zyplj&lt;/li&gt;
&lt;li&gt;原作者开源地址：https://github.com/saicaca/fuwari&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Astro/fuwai&lt;/code&gt; &lt;a href=&quot;https://blog.pljzy.top/posts/astrofuwai/astrofuwai%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/&quot;&gt;博客配置教程&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>原神短片-菜菜，带带！</title><link>https://blog.pljzy.top/posts/%E5%8E%9F%E7%A5%9E%E7%9F%AD%E7%89%87-%E8%8F%9C%E8%8F%9C%E5%B8%A6%E5%B8%A6/%E5%8E%9F%E7%A5%9E%E7%9F%AD%E7%89%87-%E8%8F%9C%E8%8F%9C%E5%B8%A6%E5%B8%A6/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8E%9F%E7%A5%9E%E7%9F%AD%E7%89%87-%E8%8F%9C%E8%8F%9C%E5%B8%A6%E5%B8%A6/%E5%8E%9F%E7%A5%9E%E7%9F%AD%E7%89%87-%E8%8F%9C%E8%8F%9C%E5%B8%A6%E5%B8%A6/</guid><description>原神短片-菜菜，带带！</description><pubDate>Wed, 22 Oct 2025 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;原神短片-菜菜，带带！&lt;/h1&gt;
&lt;p&gt;无意中又刷到2024年原神生日会的短片了，如今也是怀恋呀~&lt;/p&gt;
&lt;p&gt;当初带你的大佬还在吗？&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?aid=113134052383396&amp;amp;bvid=BV1wjtNe1ESW&amp;amp;cid=25853101928&amp;amp;page=1&quot; title=&quot;【原神生日会】菜菜，带带&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>博客篇：给博客添加上友链朋友圈页面</title><link>https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E4%B8%8A%E5%8F%8B%E9%93%BE%E6%9C%8B%E5%8F%8B%E5%9C%88%E9%A1%B5%E9%9D%A2/%E5%8D%9A%E5%AE%A2%E7%AF%87%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E4%B8%8A%E5%8F%8B%E9%93%BE%E6%9C%8B%E5%8F%8B%E5%9C%88%E9%A1%B5%E9%9D%A2/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E4%B8%8A%E5%8F%8B%E9%93%BE%E6%9C%8B%E5%8F%8B%E5%9C%88%E9%A1%B5%E9%9D%A2/%E5%8D%9A%E5%AE%A2%E7%AF%87%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E4%B8%8A%E5%8F%8B%E9%93%BE%E6%9C%8B%E5%8F%8B%E5%9C%88%E9%A1%B5%E9%9D%A2/</guid><description>博客篇：给博客添加上友链朋友圈页面前言最近工作不忙，也是对博客文章进行爆肝，已经连续几天发布新文章了。这次也是和mccsjs博主聊的甚欢，也是得知有友链朋友圈这个功能页面。</description><pubDate>Wed, 22 Oct 2025 11:01:44 GMT</pubDate><content:encoded>&lt;h1&gt;博客篇：给博客添加上友链朋友圈页面 🌐&lt;/h1&gt;
&lt;h2&gt;前言 ✍️&lt;/h2&gt;
&lt;p&gt;最近工作不忙，也是对博客文章进行爆肝 💪，已经连续几天发布新文章了。
这次也是和 &lt;a href=&quot;http://mccsjs.eu.org/&quot;&gt;&lt;strong&gt;mccsjs&lt;/strong&gt;&lt;/a&gt; 博主聊的甚欢 😄，也是得知有友链朋友圈这个功能页面。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;https://seln.cn/posts/7dc9a0a2/ ，当时看了一下这个页面，发现还挺有意思🤩，那我也是迫不及待地开始为自己的博客添加这个页面。&lt;/p&gt;
&lt;p&gt;我的友链朋友圈页面是基于 https://github.com/willow-god/Friend-Circle-Lite 开源项目实现。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开始部署 🚀&lt;/h2&gt;
&lt;h3&gt;拉取项目 📥&lt;/h3&gt;
&lt;p&gt;首先 &lt;code&gt;clone&lt;/code&gt; 项目，我这里是从 &lt;code&gt;Github&lt;/code&gt; 创建新的模版再 &lt;code&gt;clone&lt;/code&gt; 的，因为我部署时发现了小问题做了点修改。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/ZyPLJ/Friend-Circle-Lite.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后参考原作者文档进行下一步操作：
&lt;a href=&quot;https://blog.liushen.fun/posts/4dc716ec/#%E8%87%AA%E9%83%A8%E7%BD%B2&quot;&gt;https://blog.liushen.fun/posts/4dc716ec/#%E8%87%AA%E9%83%A8%E7%BD%B2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我是自部署的，部署在我的 &lt;code&gt;Debian 12 liunx&lt;/code&gt; 服务器上 🖥️&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;前置条件 ⚙️&lt;/h3&gt;
&lt;p&gt;需要有一份目前博客的友链 &lt;code&gt;friend.json&lt;/code&gt; 文件，且格式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;friends&quot;: [
    [
      &quot;清羽飞扬&quot;,
      &quot;https://blog.liushen.fun/&quot;,
      &quot;https://blog.liushen.fun/info/avatar.ico&quot;
    ],
    [
      &quot;ChrisKim&quot;,
      &quot;https://www.zouht.com/&quot;,
      &quot;https://p.liiiu.cn/i/2024/06/27/667d880789765.webp&quot;
    ],
    [
      &quot;Akilar&quot;,
      &quot;https://akilar.top/&quot;,
      &quot;https://p.liiiu.cn/i/2024/04/06/661170950f7a2.png&quot;
    ],
    ……
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;修改配置文件 🧩&lt;/h3&gt;
&lt;p&gt;修改项目根目录的 &lt;code&gt;config.yaml&lt;/code&gt; 文件，我这里主要是修改了爬虫相关配置。
主要是配置 &lt;code&gt;json_url&lt;/code&gt; 爬取地址，对应上面前置条件的 &lt;code&gt;friend.json&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 爬虫相关配置
# 解释：使用request实现友链文章爬取，并放置到根目录的all.json下
#   enable:             是否启用爬虫
#   json_url:           请填写对应格式json的地址，仅支持网络地址
#   article_count:      请填写每个博客需要获取的最大文章数量
#   marge_result:       是否合并多个json文件
spider_settings:
  enable: true
  json_url: &quot;https://www.pljzy.top/friend.json&quot;
  article_count: 5
  merge_result:
    enable: false
    merge_json_url: &quot;https://blog.pljzy.top&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;安装包 📦&lt;/h3&gt;
&lt;p&gt;前提条件：服务器有安装 &lt;code&gt;python3&lt;/code&gt; 🐍
接下来安装必要的包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install -r ./requirements.txt
pip install -r ./server/requirements-server.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果上述执行不成功，用下方的命令 👇&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install -r ./requirements.txt --break-system-packages
pip install -r ./server/requirements-server.txt --break-system-packages
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;部署 API 🔧&lt;/h3&gt;
&lt;p&gt;如果环境配置完毕，你可以进入目录路径 &lt;code&gt;cd Friend-Circle-Lite&lt;/code&gt; 后直接运行 &lt;code&gt;deploy.sh&lt;/code&gt; 脚本启动 &lt;code&gt;API&lt;/code&gt; 服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod +x ./deploy.sh
./deploy.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;选择操作那里，第一次执行的话输入 &lt;code&gt;1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;检测是否部署成功 ✅&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl 127.0.0.1:1223
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就可以访问项目自带的朋友圈页面啦 🎉&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;小插曲 🎭&lt;/h3&gt;
&lt;p&gt;在爬取的时候出现了乱码问题 😅，刚刚在拉取项目时说过我做了点修改，就是为了修复这个问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;问题不大，用 &lt;code&gt;AI&lt;/code&gt; 稍微修改下爬取部分的代码 🤖，下面是修改后爬取，没有乱码问题了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;定时任务 ⏰&lt;/h3&gt;
&lt;p&gt;然后就跟着原作者的教程，添加定时任务即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;集成到 Fuwari 🌸&lt;/h2&gt;
&lt;p&gt;上面友链朋友圈部署成功后，会有一个项目默认的页面，如果不想折腾的话，可以直接用上面部署的页面。&lt;/p&gt;
&lt;p&gt;服务器部署的话我是用 &lt;code&gt;Nginx&lt;/code&gt; 反向代理指向服务器 &lt;code&gt;ip:1223&lt;/code&gt;，然后防火墙添加出入站规则就能访问到了 🔒。&lt;/p&gt;
&lt;p&gt;有很多部署办法可以访问到网站，这个就看自己喜欢哪种办法了 😎。&lt;/p&gt;
&lt;p&gt;这是我自己部署的 👉 https://pljzy.top:1224/&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当然我是属于喜欢折腾的 🔧，我自己也在博客里面添加了个友链朋友圈页面。&lt;/p&gt;
&lt;p&gt;https://blog.pljzy.top/feed/&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;7.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果有喜欢的可以拉取我的仓库参考着做修改 👉
https://github.com/ZyPLJ/fuwai_zyplj&lt;/p&gt;
&lt;h2&gt;参考链接 🔗&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://mccsjs.eu.org/&quot;&gt;&lt;strong&gt;mccsjs&lt;/strong&gt;&lt;/a&gt; 博客&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/willow-god/Friend-Circle-Lite&quot;&gt;Friend-Circle-Lite&lt;/a&gt; 开源项目&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.liushen.fun/posts/4dc716ec/#%E8%87%AA%E9%83%A8%E7%BD%B2&quot;&gt;Friend-Circle-Lite&lt;/a&gt; 部署教程&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/fuwai_zyplj&quot;&gt;fuwai_zyplj&lt;/a&gt; 本博客仓库&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>拼多多百亿补贴苹果17 Pro开箱💰</title><link>https://blog.pljzy.top/posts/%E6%8B%BC%E5%A4%9A%E5%A4%9A%E7%99%BE%E4%BA%BF%E8%A1%A5%E8%B4%B4%E8%8B%B9%E6%9E%9C17-pro%E5%BC%80%E7%AE%B1/%E6%8B%BC%E5%A4%9A%E5%A4%9A%E7%99%BE%E4%BA%BF%E8%A1%A5%E8%B4%B4%E8%8B%B9%E6%9E%9C17-pro%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%8B%BC%E5%A4%9A%E5%A4%9A%E7%99%BE%E4%BA%BF%E8%A1%A5%E8%B4%B4%E8%8B%B9%E6%9E%9C17-pro%E5%BC%80%E7%AE%B1/%E6%8B%BC%E5%A4%9A%E5%A4%9A%E7%99%BE%E4%BA%BF%E8%A1%A5%E8%B4%B4%E8%8B%B9%E6%9E%9C17-pro%E5%BC%80%E7%AE%B1/</guid><description>拼多多百亿补贴苹果17 Pro开箱前言目前使用的手机是iPhone 13 128G 蓝色款，已经用了差不多3年半了，电池健康只有75%了，然后我非常喜欢更新系统，目前系统是iOS 26.0，这就导致了一个问题，那就是手机非常的卡，所以也是下定决心换手机了。</description><pubDate>Mon, 20 Oct 2025 23:00:46 GMT</pubDate><content:encoded>&lt;h1&gt;拼多多百亿补贴苹果17 Pro开箱&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;目前使用的手机是&lt;code&gt;iPhone 13&lt;/code&gt; &lt;code&gt;128G&lt;/code&gt; 蓝色款，已经用了差不多3年半了，电池健康只有75%了，然后我非常喜欢更新系统，目前系统是&lt;code&gt;iOS 26.0&lt;/code&gt;，这就导致了一个问题，那就是手机非常的卡，所以也是下定决心换手机了。&lt;/p&gt;
&lt;p&gt;一开始是想着用国补买个&lt;code&gt;17 256G&lt;/code&gt;基础版就行了，但是下半年这国补是真的领不到，所以只能去拼多多看看了。&lt;/p&gt;
&lt;h2&gt;退休&lt;/h2&gt;
&lt;p&gt;光荣退休&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;百亿补贴&lt;/h2&gt;
&lt;p&gt;在逛拼多多发现百亿补贴的&lt;code&gt;17&lt;/code&gt;基础版和&lt;code&gt;pro&lt;/code&gt;都挺便宜，&lt;code&gt;256G&lt;/code&gt;价格分别是&lt;code&gt;5099&lt;/code&gt;和&lt;code&gt;8099&lt;/code&gt;，比官网和京东都便宜很多，但是需要抢，不是很好抢！！！&lt;/p&gt;
&lt;p&gt;我一开始也是抱着试试的心态，第一波是抢&lt;code&gt;17&lt;/code&gt;基础版，不出意外没抢到，下一波是晚上&lt;code&gt;8:00&lt;/code&gt;,想着反正要换手机，要不试试&lt;code&gt;Pro&lt;/code&gt;，结果还真让我抢到了橙色的&lt;code&gt;17&lt;/code&gt;，然后8099拿下&lt;code&gt;iphone17 Pro 256G&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;预售&lt;/h2&gt;
&lt;p&gt;我不是直接抢的手机，而是抢的&lt;code&gt;600&lt;/code&gt;元的卷，卷的有效期是一个小时，我也是犹豫了很久，最终才下单。下完单才发现我这个是预售，上面写的&lt;strong&gt;9天内&lt;/strong&gt;发货， 不过卷也用了，也不能退，只能等了。&lt;/p&gt;
&lt;p&gt;这9天可等死我了，期间也催过客服，并没有什么用，然后刷小红书发现有可能会被砍单，不过我的过了&lt;code&gt;48小时&lt;/code&gt;也没有被砍，心也是放下来了。&lt;/p&gt;
&lt;p&gt;也刷到了超过规定的时间没发货的，我也不知真假，不过我的是卡在最后时间才发货，我是10月&lt;strong&gt;10号&lt;/strong&gt;买的，卡在最后一天&lt;strong&gt;19号&lt;/strong&gt;晚上才发货。&lt;/p&gt;
&lt;p&gt;然后我这个是&lt;strong&gt;杭州&lt;/strong&gt;发货的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开箱&lt;/h2&gt;
&lt;p&gt;顺丰快递还是给力，&lt;strong&gt;20号&lt;/strong&gt;早上就收到快递员电话了，但是当时在上班，只能让他晚上过来。&lt;/p&gt;
&lt;p&gt;下班后也是飞快地跑回家。&lt;/p&gt;
&lt;p&gt;首先我的开箱步骤是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先检查手机盒子是否有明显的破损和开箱痕迹，检查后发现除了盒子有点灰没什么问题。&lt;/li&gt;
&lt;li&gt;然后检查盒子上面的序列号，在苹果官网查询：&lt;a href=&quot;https://checkcoverage.apple.com/?locale=zh_CN&quot;&gt;查看保障状态 - AppleCare 与保修&lt;/a&gt;，查询后是未激活的状态。&lt;/li&gt;
&lt;li&gt;接下来就是开箱了，打开包装盒，拿出手机查看摄像头是否有灰、屏幕是否有划痕、边框是否有磕碰，检查下来也是没有问题。&lt;/li&gt;
&lt;li&gt;最后就是开机激活，在系统设置-关于本机里面查看序列号和&lt;code&gt;IMEI&lt;/code&gt;码和包装盒上的是否一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;期间需要配合快递小哥完成拍照，我这个顺丰小哥还挺友好没有催我。大约也是花了&lt;strong&gt;8分钟&lt;/strong&gt;左右完成从开箱到激活。&lt;/p&gt;
&lt;h3&gt;开箱图片&lt;/h3&gt;
&lt;p&gt;接下来是开箱图片，我是激活后才拍的，所以细节就不用在意了~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;爱思检测&lt;/h2&gt;
&lt;p&gt;完成开箱和检查后，还可以用爱思助手进一步查看手机的状态，我这里直接把图放出来。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;硬盘：&lt;code&gt;Samsung&lt;/code&gt;三星&lt;/li&gt;
&lt;li&gt;电池：深圳欣旺达&lt;/li&gt;
&lt;li&gt;前置：高伟电子&lt;/li&gt;
&lt;li&gt;后置：&lt;code&gt;LG&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;屏幕：&lt;code&gt;G9N&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不知道这算是中奖还是普通还是踩雷了，哈哈。后续看使用起来是否有问题吧~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>博客篇：给博客添加多级菜单功能</title><link>https://blog.pljzy.top/posts/%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%BA%A7%E8%8F%9C%E5%8D%95%E5%8A%9F%E8%83%BD/%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%BA%A7%E8%8F%9C%E5%8D%95%E5%8A%9F%E8%83%BD/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%BA%A7%E8%8F%9C%E5%8D%95%E5%8A%9F%E8%83%BD/%E7%BB%99%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%BA%A7%E8%8F%9C%E5%8D%95%E5%8A%9F%E8%83%BD/</guid><description>给博客添加多级菜单功能📝 前言目前我使用的这个博客模版是基于Astro的fuwari开源博客模版。🌟我也是经过了一系列魔改给博客添加了如下功能：🛠️🎵 音乐播放器</description><pubDate>Mon, 20 Oct 2025 15:44:08 GMT</pubDate><content:encoded>&lt;h1&gt;给博客添加多级菜单功能&lt;/h1&gt;
&lt;h2&gt;📝 前言&lt;/h2&gt;
&lt;p&gt;目前我使用的这个博客模版是基于&lt;code&gt;Astro&lt;/code&gt;的&lt;a href=&quot;https://github.com/saicaca/fuwari/&quot;&gt;fuwari&lt;/a&gt;开源博客模版。🌟&lt;/p&gt;
&lt;p&gt;我也是经过了一系列魔改给博客添加了如下功能：🛠️&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;🎵 音乐播放器&lt;/li&gt;
&lt;li&gt;📌 文章置顶固定（原作者仓库未合并的PR中找到的）&lt;/li&gt;
&lt;li&gt;💬 评论系统【基于twikoo】&lt;/li&gt;
&lt;li&gt;🔗 友链页面&lt;/li&gt;
&lt;li&gt;🎬 首图支持视频&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果对于这些功能感兴趣的可以参考下面的地址进行修改添加。🔧&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Github&lt;/code&gt;地址：https://github.com/ZyPLJ/fuwai_zyplj&lt;/p&gt;
&lt;p&gt;我的旧站也是基于开源项目进行魔改的，旧站的菜单非常之多，迁移到新增后舍弃了很多菜单。因为新博客默认是不支持多级菜单的，我在之前在原作者项目中提过&lt;a href=&quot;https://github.com/saicaca/fuwari/issues/596&quot;&gt;PR&lt;/a&gt;，不过这种小功能，作者肯定是没时间去弄的，而且可能不符合作者的设计理念。🤔&lt;/p&gt;
&lt;p&gt;那么只能自己动手做了，在提&lt;a href=&quot;https://github.com/saicaca/fuwari/issues/596&quot;&gt;PR&lt;/a&gt;之前我就自己尝试过，但是有点缺陷，后面也就没有提交代码，我的初版如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;由于有点缺陷我也就没继续做下去，后面也是有人在&lt;code&gt;PR&lt;/code&gt;中提到自己已经实现了，那我这次也是为后面的功能做准备，必须要把多级菜单搞定了。💪&lt;/p&gt;
&lt;h2&gt;🚀 开始操作&lt;/h2&gt;
&lt;p&gt;这次具体实现是参考 &lt;a href=&quot;https://github.com/matsuzaka-yuki/Mizuki&quot;&gt;Mizuki&lt;/a&gt;主题库实现的，参考下来，发现设计思路和我最初版是一致的，哈哈。😄&lt;/p&gt;
&lt;p&gt;不过我把菜单图标去掉了，如果有喜欢菜单图标的可以自己参考然后修改，不是很难。&lt;/p&gt;
&lt;h2&gt;⚙️ config.ts&lt;/h2&gt;
&lt;p&gt;一步一步来，先在&lt;code&gt;types-&amp;gt;config.ts&lt;/code&gt;中的&lt;code&gt;NavBarLink&lt;/code&gt;类型变量添加&lt;code&gt;children&lt;/code&gt;类型声明&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export type NavBarLink = {
	name: string;
	url: string;
	external?: boolean;
	children?: (NavBarLink | LinkPreset)[]; // 支持子菜单，可以是NavBarLink或LinkPreset
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🎨 main.css&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;styles-&amp;gt;main.css&lt;/code&gt;然后把css搞定，直接复制拿来用，注意放在&lt;code&gt;text-25&lt;/code&gt;类名后面&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.text-25 {
    @apply text-black/25 dark:text-white/25
}

/* 下拉菜单样式 */
.dropdown-container {
    @apply relative;
}

.dropdown-menu {
    @apply absolute top-full left-0 pt-2 opacity-0 invisible pointer-events-none transition-all duration-200 ease-out transform translate-y-[-8px] z-50;
}

.dropdown-container:hover .dropdown-menu,
.dropdown-container:focus-within .dropdown-menu {
    @apply opacity-100 visible pointer-events-auto translate-y-0;
}

.dropdown-container:hover .dropdown-arrow,
.dropdown-container:focus-within .dropdown-arrow {
    @apply rotate-180;
}

.dropdown-content {
    @apply bg-[var(--float-panel-bg)] rounded-[var(--radius-large)] shadow-xl dark:shadow-none border border-black/5 dark:border-white/10 py-2 min-w-[12rem];
}

.dropdown-item {
    @apply flex items-center justify-between px-4 py-2.5 text-black/75 dark:text-white/75 hover:text-[var(--primary)] hover:bg-[var(--btn-plain-bg-hover)] transition-colors duration-150 font-medium;
}

.dropdown-item:first-child {
    @apply rounded-t-[calc(var(--radius-large)-0.5rem)];
}

.dropdown-item:last-child {
    @apply rounded-b-[calc(var(--radius-large)-0.5rem)];
}

/* 移动端菜单样式 */
.mobile-submenu {
    @apply max-h-0 overflow-hidden transition-all duration-300 ease-in-out;
}

.mobile-dropdown[data-expanded=&quot;true&quot;] .mobile-submenu {
    @apply max-h-96;
}

.mobile-dropdown[data-expanded=&quot;true&quot;] .mobile-dropdown-arrow {
    @apply rotate-180;
}

/* 响应式隐藏 */
@media (max-width: 768px) {
    .dropdown-container {
        @apply hidden;
    }
}

/* 无障碍支持 */
.dropdown-container:focus-within .dropdown-menu {
    @apply opacity-100 visible pointer-events-auto translate-y-0;
}

.dropdown-item:focus {
    @apply outline-none;
}

.mobile-dropdown button:focus {
    @apply outline-none;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🧩 DropdownMenu.astro&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;components-&amp;gt;widget-&amp;gt;DropdownMenu.astro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接下来新建&lt;code&gt;DropdownMenu.astro&lt;/code&gt;组件把代码复制过来，代码比较多，就不细讲了，我也是用&lt;code&gt;AI&lt;/code&gt;优化了一下&lt;code&gt;js&lt;/code&gt;部分代码，为什么要优化，因为我在执行&lt;code&gt;pnpm check&lt;/code&gt;代码检查的时候报错了,大部分是&lt;code&gt;ts&lt;/code&gt;类型错误,如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { Icon } from &quot;astro-icon/components&quot;;
import { LinkPresets } from &quot;../../constants/link-presets&quot;;
import { LinkPreset, type NavBarLink } from &quot;../../types/config&quot;;
import { url } from &quot;../../utils/url-utils&quot;;

interface Props {
	link: NavBarLink;
	class?: string;
}

const { link, class: className } = Astro.props;

// 转换子菜单中的LinkPreset为NavBarLink
const processedLink = {
	...link,
	children: link.children?.map((child: NavBarLink | LinkPreset): NavBarLink =&amp;gt; {
		if (typeof child === &quot;number&quot;) {
			return LinkPresets[child];
		}
		return child;
	}),
};

const hasChildren = processedLink.children &amp;amp;&amp;amp; processedLink.children.length &amp;gt; 0;
---

&amp;lt;div class:list={[&quot;dropdown-container&quot;, className]} data-dropdown&amp;gt;
	{hasChildren ? (
		&amp;lt;button 
			class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95 dropdown-trigger&quot;
			aria-expanded=&quot;false&quot;
			aria-haspopup=&quot;true&quot;
			data-dropdown-trigger
		&amp;gt;
			&amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
				{processedLink.name}
				&amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-down-rounded&quot; class=&quot;text-[1.25rem] transition-transform duration-200 dropdown-arrow ml-1&quot; /&amp;gt;
			&amp;lt;/div&amp;gt;
		&amp;lt;/button&amp;gt;
		&amp;lt;div class=&quot;dropdown-menu&quot; data-dropdown-menu&amp;gt;
			&amp;lt;div class=&quot;dropdown-content&quot;&amp;gt;
				{processedLink.children?.map((child) =&amp;gt; (
					&amp;lt;a 
						href={child.external ? child.url : url(child.url)} 
						target={child.external ? &quot;_blank&quot; : null}
						class=&quot;dropdown-item&quot;
						aria-label={child.name}
					&amp;gt;
						&amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
							&amp;lt;span&amp;gt;{child.name}&amp;lt;/span&amp;gt;
						&amp;lt;/div&amp;gt;
						{child.external &amp;amp;&amp;amp; (
							&amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.75rem] text-black/25 dark:text-white/25&quot; /&amp;gt;
						)}
					&amp;lt;/a&amp;gt;
				))}
			&amp;lt;/div&amp;gt;
		&amp;lt;/div&amp;gt;
	) : (
		&amp;lt;a 
			aria-label={processedLink.name} 
			href={processedLink.external ? processedLink.url : url(processedLink.url)} 
			target={processedLink.external ? &quot;_blank&quot; : null}
			class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95&quot;
		&amp;gt;
			&amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
				{processedLink.name}
				{processedLink.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.875rem] transition -translate-y-[1px] ml-1 text-black/[0.2] dark:text-white/[0.2]&quot; /&amp;gt;}
			&amp;lt;/div&amp;gt;
		&amp;lt;/a&amp;gt;
	)}
&amp;lt;/div&amp;gt;

&amp;lt;style&amp;gt;
	.dropdown-container {
		@apply relative;
	}

	.dropdown-menu {
		@apply absolute top-full left-0 pt-2 opacity-0 invisible pointer-events-none transition-all duration-200 ease-out transform translate-y-[-8px] z-50;
	}

	.dropdown-container:hover .dropdown-menu,
	.dropdown-container:focus-within .dropdown-menu {
		@apply opacity-100 visible pointer-events-auto translate-y-0;
	}

	.dropdown-container:hover .dropdown-arrow,
	.dropdown-container:focus-within .dropdown-arrow {
		@apply rotate-180;
	}

	.dropdown-content {
		@apply bg-[var(--float-panel-bg)] rounded-[var(--radius-large)] shadow-xl dark:shadow-none border border-black/5 dark:border-white/10 py-2 min-w-[12rem];
	}

	.dropdown-item {
		@apply flex items-center justify-between px-4 py-2.5 text-black/75 dark:text-white/75 hover:text-[var(--primary)] hover:bg-[var(--btn-plain-bg-hover)] transition-colors duration-150 font-medium;
	}

	.dropdown-item:first-child {
		@apply rounded-t-[calc(var(--radius-large)-0.5rem)];
	}

	.dropdown-item:last-child {
		@apply rounded-b-[calc(var(--radius-large)-0.5rem)];
	}

	/* 移动端隐藏下拉菜单 */
	@media (max-width: 768px) {
		.dropdown-container {
			@apply hidden;
		}
	}
&amp;lt;/style&amp;gt;

&amp;lt;script&amp;gt;
    // 键盘导航支持
    document.addEventListener(&apos;DOMContentLoaded&apos;, () =&amp;gt; {
        const dropdowns = document.querySelectorAll(&apos;[data-dropdown]&apos;);

        // 点击外部关闭下拉菜单
        const handleDocumentClick = (e: Event) =&amp;gt; {
            dropdowns.forEach(dropdown =&amp;gt; {
                if (!dropdown.contains(e.target as Node)) {
                    const trigger = dropdown.querySelector(&apos;[data-dropdown-trigger]&apos;) as HTMLElement;
                    const menu = dropdown.querySelector(&apos;[data-dropdown-menu]&apos;) as HTMLElement;
                    if (trigger &amp;amp;&amp;amp; menu) {
                        closeDropdown(trigger, menu);
                    }
                }
            });
        };

        // 键盘事件处理函数
        const handleTriggerKeydown = (
            e: KeyboardEvent,
            trigger: HTMLElement,
            menu: HTMLElement,
            items: NodeListOf&amp;lt;HTMLElement&amp;gt;
        ) =&amp;gt; {
            switch (e.key) {
                case &apos;Enter&apos;:
                case &apos; &apos;:
                    e.preventDefault();
                    toggleDropdown(trigger, menu);
                    break;
                case &apos;ArrowDown&apos;:
                    e.preventDefault();
                    openDropdown(trigger, menu);
                    if (items.length &amp;gt; 0) {
                        items[0].focus();
                    }
                    break;
                case &apos;Escape&apos;:
                    closeDropdown(trigger, menu);
                    break;
            }
        };

        // 菜单项键盘导航处理
        const handleItemKeydown = (
            e: KeyboardEvent,
            index: number,
            items: NodeListOf&amp;lt;HTMLElement&amp;gt;,
            trigger: HTMLElement,
            menu: HTMLElement
        ) =&amp;gt; {
            switch (e.key) {
                case &apos;ArrowDown&apos;:
                    e.preventDefault();
                    const nextIndex = (index + 1) % items.length;
                    items[nextIndex].focus();
                    break;
                case &apos;ArrowUp&apos;:
                    e.preventDefault();
                    const prevIndex = (index - 1 + items.length) % items.length;
                    items[prevIndex].focus();
                    break;
                case &apos;Escape&apos;:
                    closeDropdown(trigger, menu);
                    trigger.focus();
                    break;
            }
        };

        // 初始化下拉菜单
        dropdowns.forEach(dropdown =&amp;gt; {
            const trigger = dropdown.querySelector(&apos;[data-dropdown-trigger]&apos;) as HTMLElement;
            const menu = dropdown.querySelector(&apos;[data-dropdown-menu]&apos;) as HTMLElement;
            const items = dropdown.querySelectorAll(&apos;.dropdown-item&apos;) as NodeListOf&amp;lt;HTMLElement&amp;gt;;

            if (!trigger || !menu) return;

            // 触发器键盘事件
            trigger.addEventListener(&apos;keydown&apos;, (e) =&amp;gt; {
                handleTriggerKeydown(e as KeyboardEvent, trigger, menu, items);
            });

            // 菜单项键盘事件
            items.forEach((item, index) =&amp;gt; {
                item.addEventListener(&apos;keydown&apos;, (e) =&amp;gt; {
                    handleItemKeydown(e as KeyboardEvent, index, items, trigger, menu);
                });
            });
        });

        document.addEventListener(&apos;click&apos;, handleDocumentClick);
    });

    // 下拉菜单状态管理
    const toggleDropdown = (trigger: HTMLElement, menu: HTMLElement) =&amp;gt; {
        const isOpen = trigger.getAttribute(&apos;aria-expanded&apos;) === &apos;true&apos;;
        isOpen ? closeDropdown(trigger, menu) : openDropdown(trigger, menu);
    };

    const openDropdown = (trigger: HTMLElement, menu: HTMLElement) =&amp;gt; {
        trigger.setAttribute(&apos;aria-expanded&apos;, &apos;true&apos;);
        updateMenuClasses(menu, false);
    };

    const closeDropdown = (trigger: HTMLElement, menu: HTMLElement) =&amp;gt; {
        trigger.setAttribute(&apos;aria-expanded&apos;, &apos;false&apos;);
        updateMenuClasses(menu, true);
    };

    // 菜单类名管理
    const updateMenuClasses = (menu: HTMLElement, isClosing: boolean) =&amp;gt; {
        const classesToAdd = isClosing
            ? [&apos;opacity-0&apos;, &apos;invisible&apos;, &apos;pointer-events-none&apos;, &apos;translate-y-[-8px]&apos;]
            : [&apos;opacity-100&apos;, &apos;visible&apos;, &apos;pointer-events-auto&apos;, &apos;translate-y-0&apos;];

        const classesToRemove = isClosing
            ? [&apos;opacity-100&apos;, &apos;visible&apos;, &apos;pointer-events-auto&apos;, &apos;translate-y-0&apos;]
            : [&apos;opacity-0&apos;, &apos;invisible&apos;, &apos;pointer-events-none&apos;, &apos;translate-y-[-8px]&apos;];

        menu.classList.remove(...classesToRemove);
        menu.classList.add(...classesToAdd);
    };
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;📱 NavMenuPanel.astro&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;components-&amp;gt;widget-&amp;gt;NavMenuPanel.astro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NavMenuPanel.astro&lt;/code&gt;是&lt;a href=&quot;https://github.com/saicaca/fuwari/&quot;&gt;fuwari&lt;/a&gt;主题原本的菜单组件，也是需要修改的，因为修改的地方还比较多，我就直接把全部代码贴出来。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { Icon } from &quot;astro-icon/components&quot;;
import { LinkPresets } from &quot;../../constants/link-presets&quot;;
import { LinkPreset, type NavBarLink } from &quot;../../types/config&quot;;
import { url } from &quot;../../utils/url-utils&quot;;

interface Props {
	links: NavBarLink[];
}

// 处理links中的LinkPreset转换
const processedLinks = Astro.props.links.map(
	(link: NavBarLink): NavBarLink =&amp;gt; ({
		...link,
		children: link.children?.map(
			(child: NavBarLink | LinkPreset): NavBarLink =&amp;gt; {
				if (typeof child === &quot;number&quot;) {
					return LinkPresets[child];
				}
				return child;
			},
		),
	}),
);
---
&amp;lt;div id=&quot;nav-menu-panel&quot; class:list={[&quot;float-panel float-panel-closed absolute transition-all fixed right-4 px-2 py-2 max-h-[80vh] overflow-y-auto&quot;]}&amp;gt;
    {processedLinks.map((link) =&amp;gt; (
            &amp;lt;div class=&quot;mobile-menu-item&quot;&amp;gt;
                {link.children &amp;amp;&amp;amp; link.children.length &amp;gt; 0 ? (
                    &amp;lt;!-- 有子菜单的项目 --&amp;gt;
                        &amp;lt;div class=&quot;mobile-dropdown&quot; data-mobile-dropdown&amp;gt;
                            &amp;lt;button
                                    class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8 w-full text-left
                            hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition&quot;
                                    data-mobile-dropdown-trigger
                                    aria-expanded=&quot;false&quot;
                            &amp;gt;
                                &amp;lt;div class=&quot;transition text-black/75 dark:text-white/75 font-bold group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                                    {link.name}
                                &amp;lt;/div&amp;gt;
                                &amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-down-rounded&quot;
                                      class=&quot;transition text-[1.25rem] text-[var(--primary)] mobile-dropdown-arrow duration-200&quot;
                                /&amp;gt;
                            &amp;lt;/button&amp;gt;
                            &amp;lt;div class=&quot;mobile-submenu&quot; data-mobile-submenu&amp;gt;
                                {link.children.map((child) =&amp;gt; {
                                    const childLink = child as NavBarLink;
                                    return (
                                            &amp;lt;a
                                                    href={childLink.external ? childLink.url : url(childLink.url)}
                                                    class=&quot;group flex justify-between items-center py-2 pl-6 pr-1 rounded-lg gap-8 hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition&quot;
                                                    target={childLink.external ? &quot;_blank&quot; : null}
                                            &amp;gt;
                                                &amp;lt;div class=&quot;transition text-black/60 dark:text-white/60 font-medium group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                                                    {childLink.name}
                                                &amp;lt;/div&amp;gt;
                                                {childLink.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;transition text-[0.75rem] text-black/25 dark:text-white/25 -translate-x-1&quot; /&amp;gt;}
                                            &amp;lt;/a&amp;gt;
                                    );
                                })}
                            &amp;lt;/div&amp;gt;
                        &amp;lt;/div&amp;gt;
                ) : (
                    &amp;lt;!-- 普通链接项目 --&amp;gt;
                        &amp;lt;a href={link.external ? link.url : url(link.url)} class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8
                    hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition
                &quot;
                           target={link.external ? &quot;_blank&quot; : null}
                        &amp;gt;
                            &amp;lt;div class=&quot;transition text-black/75 dark:text-white/75 font-bold group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                                {link.name}
                            &amp;lt;/div&amp;gt;
                            {!link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot;
                                                     class=&quot;transition text-[1.25rem] text-[var(--primary)]&quot;
                            /&amp;gt;}
                            {link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot;
                                                    class=&quot;transition text-[0.75rem] text-black/25 dark:text-white/25 -translate-x-1&quot;
                            /&amp;gt;}
                        &amp;lt;/a&amp;gt;
                )}
            &amp;lt;/div&amp;gt;
    ))}
&amp;lt;/div&amp;gt;

&amp;lt;style&amp;gt;
    .mobile-submenu {
        @apply max-h-0 overflow-hidden transition-all duration-300 ease-in-out;
    }

    .mobile-dropdown[data-expanded=&quot;true&quot;] .mobile-submenu {
        @apply max-h-96;
    }

    .mobile-dropdown[data-expanded=&quot;true&quot;] .mobile-dropdown-arrow {
        @apply rotate-180;
    }
&amp;lt;/style&amp;gt;

&amp;lt;script&amp;gt;
    document.addEventListener(&apos;DOMContentLoaded&apos;, function() {
        const mobileDropdowns = document.querySelectorAll(&apos;[data-mobile-dropdown]&apos;);

        mobileDropdowns.forEach(dropdown =&amp;gt; {
            const trigger = dropdown.querySelector(&apos;[data-mobile-dropdown-trigger]&apos;);
            const submenu = dropdown.querySelector(&apos;[data-mobile-submenu]&apos;);

            if (!trigger || !submenu) return;

            trigger.addEventListener(&apos;click&apos;, function(e) {
                e.preventDefault();
                const isExpanded = dropdown.getAttribute(&apos;data-expanded&apos;) === &apos;true&apos;;

                // 关闭其他打开的下拉菜单
                mobileDropdowns.forEach(otherDropdown =&amp;gt; {
                    if (otherDropdown !== dropdown) {
                        otherDropdown.setAttribute(&apos;data-expanded&apos;, &apos;false&apos;);
                        const otherTrigger = otherDropdown.querySelector(&apos;[data-mobile-dropdown-trigger]&apos;);
                        if (otherTrigger) {
                            otherTrigger.setAttribute(&apos;aria-expanded&apos;, &apos;false&apos;);
                        }
                    }
                });

                // 切换当前下拉菜单
                const newState = !isExpanded;
                dropdown.setAttribute(&apos;data-expanded&apos;, newState.toString());
                trigger.setAttribute(&apos;aria-expanded&apos;, newState.toString());
            });
        });
    });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🧭 Navbar.astro&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;components-&amp;gt;Navbar.astro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接下来修改&lt;code&gt;Navbar.astro&lt;/code&gt;组件差不多就快完工了，这个组件只修改了2处，首先导入我们上面创建的&lt;code&gt;DropdownMenu&lt;/code&gt;组件，然后把原本的代码替换一下就行了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import DropdownMenu from &quot;./widget/DropdownMenu.astro&quot;;


/*&amp;lt;div class=&quot;hidden md:flex&quot;&amp;gt;
    {links.map((l) =&amp;gt; {
        return &amp;lt;a aria-label={l.name} href={l.external ? l.url : url(l.url)} target={l.external ? &quot;_blank&quot; : null}
                  class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95&quot;
        &amp;gt;
            &amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
                {l.name}
                {l.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.875rem] transition -translate-y-[1px] ml-1 text-black/[0.2] dark:text-white/[0.2]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;}
            &amp;lt;/div&amp;gt;
        &amp;lt;/a&amp;gt;;
    })}
&amp;lt;/div&amp;gt;*/
&amp;lt;div class=&quot;hidden md:flex&quot;&amp;gt;
    {links.map((l) =&amp;gt; {
        return &amp;lt;DropdownMenu link={l} /&amp;gt;;
    })}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;⚙️ config.ts&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;src-&amp;gt;config.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;最后修改&lt;code&gt;config.ts&lt;/code&gt;配置文件就行了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const navBarConfig: NavBarConfig = {
	links: [
		LinkPreset.Home,
		LinkPreset.Archive,
		LinkPreset.About,
		{
			name: &quot;社交&quot;,
			url: &quot;/links/&quot;,
			children: [LinkPreset.Links],
		},
		{
			name: &quot;其他&quot;,
			url: &quot;/content/&quot;,
			children: [
				LinkPreset.Images, // 如果没有lsky.pro图床，则注释掉 https://docs.lsky.pro/archive/free/v2/
				{
					name: &quot;网站监控&quot;,
					url: &quot;https://stats.uptimerobot.com/f3bIMzwfwF&quot;,
					external: true,
				},
			],
		},
		{
			name: &quot;旧站&quot;,
			url: &quot;https://pljzy.top&quot;, // Internal links should not include the base path, as it is automatically added
			external: true, // Show an external link icon and will open in a new tab
		},
		{
			name: &quot;开往🚆&quot;,
			url: &quot;https://www.travellings.cn/go.html&quot;, // Internal links should not include the base path, as it is automatically added
			external: true, // Show an external link icon and will open in a new tab
		},
	],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🎉 实现效果&lt;/h2&gt;
&lt;p&gt;首先&lt;code&gt;pnpm check&lt;/code&gt;✅&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到是没有错误的了&lt;/p&gt;
&lt;p&gt;然后&lt;code&gt;pnpm dev&lt;/code&gt;运行项目&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;📋 总结&lt;/h2&gt;
&lt;p&gt;对于&lt;a href=&quot;https://github.com/saicaca/fuwari/&quot;&gt;fuwari&lt;/a&gt;博客模版添加多级菜单只需要修改6处地方。🔧&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;📝 types-&amp;gt;config.ts&lt;/li&gt;
&lt;li&gt;🎨 styles-&amp;gt;main.css&lt;/li&gt;
&lt;li&gt;🧩 components-&amp;gt;widget-&amp;gt;DropdownMenu.astro&lt;/li&gt;
&lt;li&gt;📱 components-&amp;gt;widget-&amp;gt;NavMenuPanel.astro&lt;/li&gt;
&lt;li&gt;🧭 components-&amp;gt;Navbar.astro&lt;/li&gt;
&lt;li&gt;⚙️ src-&amp;gt;config.ts&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于开源的博客，自己虽然可以任意魔改，但要保持初心~ ❤️&lt;/p&gt;
</content:encoded></item><item><title>用uptimerobot监控网站状态</title><link>https://blog.pljzy.top/posts/%E7%94%A8uptimerobot%E7%9B%91%E6%8E%A7%E7%BD%91%E7%AB%99%E7%8A%B6%E6%80%81/%E7%94%A8uptimerobot%E7%9B%91%E6%8E%A7%E7%BD%91%E7%AB%99%E7%8A%B6%E6%80%81/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%94%A8uptimerobot%E7%9B%91%E6%8E%A7%E7%BD%91%E7%AB%99%E7%8A%B6%E6%80%81/%E7%94%A8uptimerobot%E7%9B%91%E6%8E%A7%E7%BD%91%E7%AB%99%E7%8A%B6%E6%80%81/</guid><description>用uptimerobot监控网站状态前言在浏览博客的时候发现了一个免费好用的工具，它可以用来监控你的网站是否运行正常。官网地址：[免费状态页面 |正常运行时间机器人](https://uptimerobot.com/status-page/?ref=psp-footer)</description><pubDate>Thu, 16 Oct 2025 21:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;用uptimerobot监控网站状态&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在浏览博客的时候发现了一个免费好用的工具，它可以用来监控你的网站是否运行正常。&lt;/p&gt;
&lt;p&gt;官网地址：[&lt;a href=&quot;https://uptimerobot.com/status-page/?ref=psp-footer&quot;&gt;免费状态页面 |正常运行时间机器人&lt;/a&gt;](https://uptimerobot.com/status-page/?ref=psp-footer)&lt;/p&gt;
&lt;h2&gt;开始部署&lt;/h2&gt;
&lt;p&gt;首先这个工具是免费+付费的模式，目前来说给用来监控博客的状态免费的账号是够用的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;注册账号&lt;/h3&gt;
&lt;p&gt;打开官网网址，使用邮箱注册一个账号，并根据提示完成第一个监控网站的创建即可使用。&lt;/p&gt;
&lt;p&gt;登录后界面如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到我这里创建了3个网站监视器。&lt;/p&gt;
&lt;h2&gt;状态页面&lt;/h2&gt;
&lt;p&gt;在Status Pages状态页面可以查看监视器的服务状态，目前我是才创建一天，所以前面的状态都是灰色的，绿色的状态表示网站能正常访问。&lt;/p&gt;
&lt;p&gt;如果网站出现宕机，&lt;code&gt;uptimerobot&lt;/code&gt;会通过邮件告知你。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这是一个免费的网站健康检查的工具，当然除了网站，它还有&lt;code&gt;API&lt;/code&gt;接口、端口、&lt;code&gt;SSL&lt;/code&gt;监控等功能。&lt;/p&gt;
</content:encoded></item><item><title>我用AI做了个《日历记账系统》📅💰</title><link>https://blog.pljzy.top/posts/%E6%88%91%E7%94%A8ai%E5%81%9A%E4%BA%86%E4%B8%AA%E6%97%A5%E5%8E%86%E8%AE%B0%E8%B4%A6%E7%B3%BB%E7%BB%9F/%E6%88%91%E7%94%A8ai%E5%81%9A%E4%BA%86%E4%B8%AA%E6%97%A5%E5%8E%86%E8%AE%B0%E8%B4%A6%E7%B3%BB%E7%BB%9F/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%88%91%E7%94%A8ai%E5%81%9A%E4%BA%86%E4%B8%AA%E6%97%A5%E5%8E%86%E8%AE%B0%E8%B4%A6%E7%B3%BB%E7%BB%9F/%E6%88%91%E7%94%A8ai%E5%81%9A%E4%BA%86%E4%B8%AA%E6%97%A5%E5%8E%86%E8%AE%B0%E8%B4%A6%E7%B3%BB%E7%BB%9F/</guid><description>我用AI做了个《日历记账系统》📅💰前言 ✨说到记账🧾，之前我都是在手机上记账，用过很多记账软件，之前还写过一篇苹果手机快捷指令numbers自动记账教程，通过敲击背板，自动完成记账。</description><pubDate>Tue, 30 Sep 2025 08:50:00 GMT</pubDate><content:encoded>&lt;h1&gt;我用AI做了个《日历记账系统》📅💰&lt;/h1&gt;
&lt;h2&gt;前言 ✨&lt;/h2&gt;
&lt;p&gt;说到&lt;strong&gt;记账&lt;/strong&gt;🧾，之前我都是在手机上记账，用过很多记账软件，之前还写过一篇&lt;a href=&quot;https://blog.pljzy.top/posts/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4numbers%E8%87%AA%E5%8A%A8%E8%AE%B0%E8%B4%A6%E6%95%99%E7%A8%8B/&quot;&gt;苹果手机快捷指令numbers自动记账教程&lt;/a&gt;，通过敲击背板，自动完成记账。后面用过一段时间发现还是满足不了我的需求😕，所以用了一段时间也就没用了。&lt;/p&gt;
&lt;p&gt;后面，我也是用了新出的记账软件，这款软件也是能够通过敲击背板完成自动记账，同时还接入了&lt;code&gt;AI&lt;/code&gt;🤖用来帮助记账，整体使用下来还是很不错的，不过也是用了一段时间就放弃了。主要原因是我每次下单的时候还需要敲击背板，很多时候会忘记🧠，然后到家要手动补记录，有时候也会误触导致运行记账指令😫。&lt;/p&gt;
&lt;h2&gt;开始创作 🎨&lt;/h2&gt;
&lt;p&gt;有了以上经历，我也是在上班摸鱼🐟的时候有了一个灵感💡，我为什么不做个网页版的记账网站呢，不需要很复杂，能够满足我自己的需求就行，说干就干🚀，直接把提示词丢给&lt;code&gt;Deepseek&lt;/code&gt;，让他帮我完成编写。&lt;/p&gt;
&lt;p&gt;提示词：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你是一个html、js、css精通的网页开发工程师👨‍💻，现在有个需求给你，你需要完成一个使用html+js+css实现的按照日历记账的系统。主要功能如下：
1.记账功能，选中日历中的某个日期，可以为该日期添加消费记录。
2.查询功能，可以查询每个时间的消费记录，可以根据日期、消费类型查询。
3.统计功能，统计各个日期的消费记录，形成图表。
&lt;strong&gt;目前可以将消费记录存放在浏览器存储中。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;初版使用的是&lt;code&gt;localStorage&lt;/code&gt;存储，后面换成了&lt;code&gt;IndexedDB&lt;/code&gt;🗄️，后续有时间可能会把存储抽象出来，可以轻松切换不同的存储。&lt;/p&gt;
&lt;h3&gt;初版效果 👀&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;整体效果还是不错的👍，主要使用方式也就是通过&lt;strong&gt;选择日期&lt;/strong&gt;，然后添加&lt;strong&gt;消费记录&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;初版的系统只支持记账、查询和统计功能，功能较少，而且样式不够美观。接下来我也是继续让&lt;code&gt;Deepseek&lt;/code&gt;优化和添加功能🛠️&lt;/p&gt;
&lt;h3&gt;初版优化 ✨&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;现在添加一个消费记录导入和导出的功能&lt;/p&gt;
&lt;p&gt;其他功能不变的情况下，能否增加一个按时间汇总得到这段时间内所有消费汇总后的金额的功能呢。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到现在功能已经比较完全了✅，可以选择&lt;strong&gt;时间段&lt;/strong&gt;进行&lt;strong&gt;汇总计算&lt;/strong&gt;，并且支持导入、导出记录，样式上也进行了优化。&lt;/p&gt;
&lt;h3&gt;搭配Cursor优化 🔧&lt;/h3&gt;
&lt;p&gt;在使用&lt;code&gt;Deepseek&lt;/code&gt;进行一系列优化后，感觉到达了拼接，后面我有使用了&lt;code&gt;Cursor&lt;/code&gt;进行优化。&lt;/p&gt;
&lt;p&gt;部分对话截图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;目前最终版本 🎯&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我个人比较喜欢的功能就是这个&lt;strong&gt;时间汇总&lt;/strong&gt;功能⏰，可以根据支出、收入计算&lt;strong&gt;平均每日消费&lt;/strong&gt;和&lt;strong&gt;剩余可用天数&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;最终版本也是采用了毛玻璃+透明背景的效果🎨，目前还没有适配手机端显示，后续会继续进行优化。&lt;/p&gt;
&lt;h2&gt;介绍 📖&lt;/h2&gt;
&lt;p&gt;上面讲了这么多创作历程，下面来介绍下这个&lt;strong&gt;日历记账系统&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;日历记账系统是一个基于 &lt;code&gt;HTML + CSS + JavaScript&lt;/code&gt; 的本地记账网页应用🌐，内置现代化 &lt;code&gt;UI&lt;/code&gt;、日历视图、筛选与统计功能，数据默认存储在浏览器 &lt;code&gt;IndexedDB&lt;/code&gt;，支持一键导入/导出 &lt;code&gt;JSON&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;功能特性 🌟&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;📅 日历视图：按月展示每日收支概览，带当日总支出提示点与金额汇总&lt;/li&gt;
&lt;li&gt;➕ 一键添加记录：日期、金额、类型、收/支、描述&lt;/li&gt;
&lt;li&gt;🔍 右侧筛选：按日期与类型快速筛选记录（与日历点击联动）&lt;/li&gt;
&lt;li&gt;📊 数据统计：支持柱状图、折线图、饼图（使用 &lt;code&gt;Chart.js&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;⏱️ 时间汇总：任意日期范围的收入/支出/净收入、平均每日消费与“剩余可用天数”估算&lt;/li&gt;
&lt;li&gt;💾 数据持久化：&lt;code&gt;IndexedDB&lt;/code&gt; 本地存储；兼容历史 &lt;code&gt;localStorage&lt;/code&gt; 数据并提供迁移进度反馈&lt;/li&gt;
&lt;li&gt;📥📤 导入/导出：支持 &lt;code&gt;JSON&lt;/code&gt; 文件导入与一键导出&lt;/li&gt;
&lt;li&gt;🖥️ 纯前端：单个 &lt;code&gt;HTML&lt;/code&gt; 文件即可离线使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;在线预览与使用 🚀&lt;/h3&gt;
&lt;p&gt;直接用浏览器打开 &lt;code&gt;bookkeeping.html&lt;/code&gt; 即可使用（推荐 Chrome/Edge）🌐。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;点击日历的某一天，会自动：
&lt;ul&gt;
&lt;li&gt;🎯 高亮所选日期&lt;/li&gt;
&lt;li&gt;🔄 同步右侧“按日期筛选”输入框&lt;/li&gt;
&lt;li&gt;📋 列表即时筛选为该日期&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;填写“添加消费记录”区域并点击“添加记录”&lt;/li&gt;
&lt;li&gt;在“消费记录”页签中，可按日期和类型进行筛选；“清除筛选”恢复全部&lt;/li&gt;
&lt;li&gt;在“统计图表”页签中选择图表类型和统计周期，点击“生成图表”&lt;/li&gt;
&lt;li&gt;在“时间汇总”区域选择开始/结束日期并“生成汇总”&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;技术栈 ⚙️&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;🏗️ 原生 &lt;code&gt;HTML/CSS/JavaScript&lt;/code&gt;（无构建依赖）&lt;/li&gt;
&lt;li&gt;🗄️ &lt;code&gt;IndexedDB&lt;/code&gt;（数据持久化）&lt;/li&gt;
&lt;li&gt;📈 &lt;code&gt;Chart.js&lt;/code&gt;（统计图表）&lt;/li&gt;
&lt;li&gt;🎨 &lt;code&gt;Font Awesome&lt;/code&gt;（图标）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;项目结构 📁&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Desktop/
├─ bookkeeping.html   # 应用主文件（包含样式与脚本）
└─ README.md          # 本说明文件
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;数据导入与导出 💾&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;📤 导出：点击“导出数据”生成包含全部记录的 &lt;code&gt;JSON&lt;/code&gt; 文件&lt;/li&gt;
&lt;li&gt;📥 导入：点击“导入数据”选择符合字段的 &lt;code&gt;JSON&lt;/code&gt;，系统会校验并追加至现有数据&lt;/li&gt;
&lt;li&gt;🔄 首次使用含有历史 &lt;code&gt;localStorage&lt;/code&gt; 的旧版本数据时，会自动迁移至 &lt;code&gt;IndexedDB&lt;/code&gt;，并显示迁移进度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;数据记录的基本字段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;id&quot;: &quot;时间戳字符串&quot;,
  &quot;date&quot;: &quot;YYYY-MM-DD&quot;,
  &quot;amount&quot;: &quot;字符串化的小数，保留两位&quot;,
  &quot;type&quot;: &quot;food|shopping|transport|entertainment|utilities|other&quot;,
  &quot;category&quot;: &quot;expense|income&quot;,
  &quot;description&quot;: &quot;可选描述&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;开发与自定义 🛠️&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;💻 所有代码在 &lt;code&gt;bookkeeping.html&lt;/code&gt; 中，便于复制与二次开发&lt;/li&gt;
&lt;li&gt;🎨 &lt;code&gt;UI&lt;/code&gt; 主题色在 &lt;code&gt;:root&lt;/code&gt; CSS 变量中统一管理，可按需调整&lt;/li&gt;
&lt;li&gt;➕ 如需扩展消费类型或字段，可在“添加记录”选择与渲染逻辑中同步调整&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;隐私与数据 🔒&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;🛡️ 所有数据均保存在本地浏览器 &lt;code&gt;IndexedDB&lt;/code&gt; 中，不会上传到服务器&lt;/li&gt;
&lt;li&gt;⚠️ 更换浏览器/设备或清理站点数据会导致本地数据不可用，请定期导出备份&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;兼容性 💻&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;🌐 现代浏览器（Chrome、Edge、Firefox 最新版）。旧版浏览器可能缺少 &lt;code&gt;IndexedDB&lt;/code&gt; 或部分特性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结尾 🎉&lt;/h2&gt;
&lt;p&gt;最后欢迎大家使用这个系统👋，虽然这个系统是网页版，但是对于打工人👨‍💼来说我觉得网页版比手机版更好用，我平时记账都是上班摸鱼🐟或者提前到公司的时候就打开这个网站进行记账，很方便，这个也看个人习惯。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;项目地址&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🌐 在线体验：&lt;a href=&quot;https://www.pljzy.top/bookkeeping.html&quot;&gt;https://www.pljzy.top/bookkeeping.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;💻 GitHub仓库：&lt;a href=&quot;https://github.com/ZyPLJ/bookkeeping&quot;&gt;https://github.com/ZyPLJ/bookkeeping&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以放心使用，数据存本地🔒，你甚至可以把&lt;code&gt;html&lt;/code&gt;代码下载下来，在本地浏览器打开💾，或者直接克隆&lt;code&gt;GitHub&lt;/code&gt;仓库到本地使用。&lt;/p&gt;
&lt;p&gt;后续我也会对这个系统进行一系列优化，以完成我的记账需求。🔮&lt;/p&gt;
</content:encoded></item><item><title>原神5周年快乐</title><link>https://blog.pljzy.top/posts/%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4%E5%BF%AB%E4%B9%90/%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4%E5%BF%AB%E4%B9%90/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4%E5%BF%AB%E4%B9%90/%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4%E5%BF%AB%E4%B9%90/</guid><description>原神5周年快乐。</description><pubDate>Sun, 28 Sep 2025 22:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;原神5周年快乐&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;./1759069498714.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4-1.jpg&quot; alt=&quot;原神5周年-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4-2.jpg&quot; alt=&quot;原神5周年-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4-3.jpg&quot; alt=&quot;原神5周年-3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4-4.jpg&quot; alt=&quot;原神5周年-4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%8E%9F%E7%A5%9E5%E5%91%A8%E5%B9%B4-5.jpg&quot; alt=&quot;原神5周年-5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot;  src=&quot;//player.bilibili.com/player.html?isOutside=true&amp;amp;aid=115265547277452&amp;amp;bvid=BV1XmnhzVEby&amp;amp;cid=32631293344&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>记录一次客户系统服务器搬迁折腾</title><link>https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%AE%A2%E6%88%B7%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AC%E8%BF%81%E6%8A%98%E8%85%BE/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%AE%A2%E6%88%B7%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AC%E8%BF%81%E6%8A%98%E8%85%BE/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%AE%A2%E6%88%B7%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AC%E8%BF%81%E6%8A%98%E8%85%BE/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%AE%A2%E6%88%B7%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AC%E8%BF%81%E6%8A%98%E8%85%BE/</guid><description>有一家客户需要进行系统搬迁，将他们目前用的系统搬迁到另外一台服务器。由于原本维护这个项目的同事休假了，这件事也落在了我的头上😅</description><pubDate>Fri, 26 Sep 2025 15:50:00 GMT</pubDate><content:encoded>&lt;h1&gt;记录一次客户系统服务器搬迁折腾&lt;/h1&gt;
&lt;h2&gt;开篇&lt;/h2&gt;
&lt;p&gt;有一家客户需要进行系统搬迁，将他们目前用的系统搬迁到另外一台服务器。由于原本维护这个项目的同事休假了，这件事也落在了我的头上😅&lt;/p&gt;
&lt;p&gt;首先这家客户系统采用的版本和部署方式如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🖥️ 系统环境：Windows Server 2022 Datacenter&lt;/li&gt;
&lt;li&gt;🗃️ 数据库版本：SQL server 2022&lt;/li&gt;
&lt;li&gt;⚙️ 部署工具：IIS&lt;/li&gt;
&lt;li&gt;🔧 系统版本：.Net Framework 4.5.2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;客户那边已经安装好了数据库，我只需要安装&lt;code&gt;SQL Server Management Studio&lt;/code&gt;数据库管理工具和&lt;code&gt;IIS&lt;/code&gt;就行。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;font size=2&amp;gt;💡 tips：我是解决之后才写的这篇文章，部分截图可能来自于网络。&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;安装SSMS&lt;/h2&gt;
&lt;p&gt;📥 下载地址：https://learn.microsoft.com/zh-cn/ssms/release-notes-19&lt;/p&gt;
&lt;p&gt;这边我选择安装的是&lt;code&gt;19.3&lt;/code&gt;版本，安装的时候发生了一件小插曲，我是直接点击的下载&lt;code&gt;SSMS 19.3&lt;/code&gt;,安装完成后发现是英文的，然后我回到下载网页才发现下面可以选择安装的语言，我又下了遍简体中文的版本。🔄&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SSMS&lt;/code&gt;安装完成之后，将旧服务器备份的&lt;code&gt;SQl.BAK&lt;/code&gt;文件还原一下即可搞定数据库迁移。✅&lt;/p&gt;
&lt;h2&gt;安装IIS&lt;/h2&gt;
&lt;p&gt;📚 教程很多，我这里就不再讲了。具体安装办法可以查看。
https://blog.csdn.net/wangyuxiang946/article/details/139953914&lt;/p&gt;
&lt;p&gt;总结来说就是在&lt;strong&gt;服务器管理器的添加角色和功能中&lt;/strong&gt;安装。🔍&lt;/p&gt;
&lt;h2&gt;网站报错解决&lt;/h2&gt;
&lt;p&gt;数据库配置好了，我也是把网站部署到了&lt;code&gt;IIS&lt;/code&gt;，不出意外的话就要出意外了，打开网页出现&lt;code&gt;500&lt;/code&gt;错误，如图：🚨&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我也是马上百度了一下，直接在一篇文章中定位到了错误：“先确认安装&lt;code&gt;IIS&lt;/code&gt;的时候有没有装&lt;code&gt;Asp.Net&lt;/code&gt;，如果没安装的话，安装上即可。”，具体原因就是安装&lt;code&gt;IIS&lt;/code&gt;的时候没有勾选&lt;code&gt;ASP&lt;/code&gt;。🎯&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;结尾&lt;/h2&gt;
&lt;p&gt;应该会有人说公司系统怎么还在用&lt;code&gt;.Net Framework 4.5.2&lt;/code&gt;，没办法这不是我能决定的🙂‍↔️。反正我要跳槽了！&lt;/p&gt;
&lt;p&gt;又水了一篇，这日子越来越有盼头咯。💦✨&lt;/p&gt;
</content:encoded></item><item><title>2025年9月21日-盲盒日记</title><link>https://blog.pljzy.top/posts/2025%E5%B9%B49%E6%9C%8821%E6%97%A5-%E7%9B%B2%E7%9B%92%E6%97%A5%E8%AE%B0/2025%E5%B9%B49%E6%9C%8821%E6%97%A5-%E7%9B%B2%E7%9B%92%E6%97%A5%E8%AE%B0/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/2025%E5%B9%B49%E6%9C%8821%E6%97%A5-%E7%9B%B2%E7%9B%92%E6%97%A5%E8%AE%B0/2025%E5%B9%B49%E6%9C%8821%E6%97%A5-%E7%9B%B2%E7%9B%92%E6%97%A5%E8%AE%B0/</guid><description>买了芙莉莲和蜡笔小新的盲盒~</description><pubDate>Sun, 21 Sep 2025 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2025年9月21日-盲盒日记&lt;/h1&gt;
&lt;p&gt;买了芙莉莲和蜡笔小新的盲盒~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./ops-coffee-1758465221913.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>简单来讲讲C#锁</title><link>https://blog.pljzy.top/posts/%E7%AE%80%E5%8D%95%E8%AE%B2%E8%AE%B2%E9%94%81/%E7%AE%80%E5%8D%95%E8%AE%B2%E8%AE%B2%E9%94%81/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%AE%80%E5%8D%95%E8%AE%B2%E8%AE%B2%E9%94%81/%E7%AE%80%E5%8D%95%E8%AE%B2%E8%AE%B2%E9%94%81/</guid><description>🔑 简单来讲讲C#锁✨ 前言今天来说说C#中的锁，锁在日常开发中还是很常用的，但是用的不得当，或者骚操作比较多那么就会导致死锁，从而导致系统崩溃。后面我会出一系列文章，来讲讲C#里面的代码和技巧</description><pubDate>Sat, 20 Sep 2025 16:06:14 GMT</pubDate><content:encoded>&lt;h1&gt;🔑 简单来讲讲C#锁&lt;/h1&gt;
&lt;h2&gt;✨ 前言&lt;/h2&gt;
&lt;p&gt;今天来说说C#中的锁，锁在日常开发中还是很常用的，但是用的不得当，或者骚操作比较多那么就会导致死锁，从而导致系统崩溃。&lt;/p&gt;
&lt;p&gt;后面我会出一系列文章，来讲讲C#里面的代码和技巧，通过不断的学习积累，以达到我的跳槽目标。&lt;/p&gt;
&lt;p&gt;文章中有任何错误的地方都可以指出，博主也在不断的学习中~&lt;/p&gt;
&lt;h2&gt;📖 简述&lt;/h2&gt;
&lt;p&gt;下面问问&lt;code&gt;AI&lt;/code&gt;来简单了解下什么是锁，&lt;code&gt;AI&lt;/code&gt;分析还是挺详细的。&lt;/p&gt;
&lt;h3&gt;🧩 通俗理解&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在现实生活里，&lt;strong&gt;锁&lt;/strong&gt;就像一把门锁。&lt;/li&gt;
&lt;li&gt;如果一个人进了房间并把门反锁，别人就得在外面等他出来。&lt;/li&gt;
&lt;li&gt;等里面的人出来并开锁后，下一个人才能进去。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 编程里的“锁”也是一样的：
它保证&lt;strong&gt;同一时刻只有一个线程能进入临界区（共享资源的代码块）&lt;/strong&gt;，从而避免混乱。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;⚙️ 技术定义&lt;/h3&gt;
&lt;p&gt;在 &lt;strong&gt;并发编程&lt;/strong&gt; 中，**锁（Lock）**是一种同步机制，用来 &lt;strong&gt;控制多个线程对共享资源的并发访问&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有锁时：多个线程可能同时修改同一个变量、文件、数据库记录 → 造成 &lt;strong&gt;数据竞争 (Race Condition)&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;有了锁后：一个线程进入临界区时，其它线程必须等待 → 保证 &lt;strong&gt;数据一致性&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🔒 锁的关键特性&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;互斥性&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;一次只能有一个线程持有锁。&lt;/li&gt;
&lt;li&gt;其他线程必须等待。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可见性&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;线程释放锁前的修改，对之后获取锁的线程是可见的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可重入性（C# 的 lock 是可重入的）&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;同一线程可以多次进入同一把锁，而不会死锁自己。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;💡 举例&lt;/h2&gt;
&lt;p&gt;下面就举个例子讲讲什么情况下就需要用到锁。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int a = 0;

// 并行++ 
Parallel.For(0, 1000, _ =&amp;gt; { 
    a++;
});

// 会发现 a 的值小于 1000，因为并行操作导致了线程之间的竞争。
Console.WriteLine(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正常情况下，a的值应该是等于&lt;code&gt;1000&lt;/code&gt;的，但由于这里使用了&lt;code&gt;Parallel.For&lt;/code&gt;，会导致多个线程对同一个值进行&lt;code&gt;++&lt;/code&gt;操作，从而导致最终的结果没有1000次。&lt;/p&gt;
&lt;p&gt;那么如何避免这种情况呢，可以使用锁去避免。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 使用锁解决线程竞争问题
object obj = new object();

int b = 0;

Parallel.For(0, 1000, _ =&amp;gt; { 
    lock (obj) {
        b++;
    }
});

// 现在 b 的值一定是 1000，因为锁确保了同一时间只有一个线程可以执行 b++ 操作。
Console.WriteLine(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里使用了一个&lt;code&gt;object&lt;/code&gt;类型作为锁对象，这也是常见的锁对象，不一定非得使用object类型，其他引用类型也行。&lt;/p&gt;
&lt;h3&gt;🖼️ 运行结果&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;🚀 .net9 新的锁对象&lt;/h2&gt;
&lt;p&gt;上面已经通过简单的例子了解到了什么是锁，已经怎么使用锁，那么在&lt;code&gt;.net9&lt;/code&gt;中可以直接使用&lt;code&gt;lock&lt;/code&gt;对象作为锁。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ℹ️ 在使用&lt;code&gt;.net9&lt;/code&gt;创建项目时，如果使用&lt;code&gt;object&lt;/code&gt;类型的锁，&lt;code&gt;rider&lt;/code&gt;编辑器会提示使用&lt;code&gt;Lock&lt;/code&gt;类型作为锁。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;⏳ 老写法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public class Lock
{
    private readonly object _lock = new();
    public void Foo()
    {
        lock (_lock)
        {
            Thread.Sleep(3000);
            Console.WriteLine(&quot;In Foo&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;⚡ 新写法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public class Deadlock
{
    private readonly Lock _lock = new();
    public void Foo()
    {
        lock (_lock)
        {
            Thread.Sleep(3000);
            Console.WriteLine(&quot;In Foo&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;📊 比较&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;传统的 &lt;code&gt;object&lt;/code&gt; + &lt;code&gt;lock(obj)&lt;/code&gt;（Monitor-based）&lt;/th&gt;
&lt;th&gt;用 &lt;code&gt;System.Threading.Lock&lt;/code&gt; + &lt;code&gt;lock(newLock)&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;锁对象类型意图性&lt;/td&gt;
&lt;td&gt;任意引用类型，不专门为锁“设计”&lt;/td&gt;
&lt;td&gt;专门的锁类型，用意明确&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编译器识别/处理&lt;/td&gt;
&lt;td&gt;用 &lt;code&gt;Monitor.Enter/Exit&lt;/code&gt;； &lt;code&gt;lock(object)&lt;/code&gt; 被编译器转换为 Monitor 操作&lt;/td&gt;
&lt;td&gt;如果 &lt;code&gt;lock&lt;/code&gt; 的目标是 &lt;code&gt;Lock&lt;/code&gt; 类型，编译器 special-case 使用 &lt;code&gt;EnterScope()/Dispose()&lt;/code&gt; 的新方式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内部机制&lt;/td&gt;
&lt;td&gt;使用 &lt;code&gt;Monitor&lt;/code&gt;、SyncBlocks、Thin locks 等，涉及 object header，可能有额外开销&lt;/td&gt;
&lt;td&gt;新语义可以减少某些 Monitor 的开销，scope 块式释放锁，可能在某些场景性能更优&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;性能&lt;/td&gt;
&lt;td&gt;在高并发且锁竞争严重的场景下性能可能成为瓶颈&lt;/td&gt;
&lt;td&gt;在同样场景下可有更好的性能（但具体提升依赖于运行情况和 contention）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可读性／安全性&lt;/td&gt;
&lt;td&gt;用 &lt;code&gt;object&lt;/code&gt;，可能误用；不容易一眼看出这是锁对象&lt;/td&gt;
&lt;td&gt;用 &lt;code&gt;Lock&lt;/code&gt; 类型，代码语义直接告诉你“这是用来加锁的”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;📝 总结&lt;/h2&gt;
&lt;p&gt;锁是并发编程里的“双刃剑”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;用得好&lt;/strong&gt; 👉 能保证线程安全，避免数据错乱。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用不好&lt;/strong&gt; 👉 容易掉进性能陷阱，甚至导致死锁，拖垮整个系统。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 .NET 9 之前，我们习惯用 &lt;code&gt;object&lt;/code&gt; 作为锁对象，但语义模糊，容易被误用。&lt;/p&gt;
&lt;p&gt;而新的 &lt;code&gt;System.Threading.Lock&lt;/code&gt; 专门为锁而生，让代码更直观，也在某些场景下带来性能提升。&lt;/p&gt;
&lt;p&gt;所以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;写 demo、小项目&lt;/strong&gt; → 用 &lt;code&gt;lock(object)&lt;/code&gt; 依旧没问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写业务、追求可维护性和性能&lt;/strong&gt; → 建议上手 .NET 9 的 &lt;code&gt;Lock&lt;/code&gt;，让代码更优雅、更安全。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 学会合理使用锁，能让你的程序更加稳定，也能减少“背锅”的机会。&lt;/p&gt;
&lt;h2&gt;🔗 相关链接&lt;/h2&gt;
&lt;p&gt;【.NET 9新增的锁对象（Lock）是怎么一回事？】 https://www.bilibili.com/video/BV1rLp2zMEua/?share_source=copy_web&amp;amp;vd_source=fce337a51d11a67781404c67ec0b5084&lt;/p&gt;
</content:encoded></item><item><title>由感而写：为什么我现在很少写技术文章</title><link>https://blog.pljzy.top/posts/%E7%94%B1%E6%84%9F%E8%80%8C%E5%86%99%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%8E%B0%E5%9C%A8%E5%BE%88%E5%B0%91%E5%86%99%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0/%E7%94%B1%E6%84%9F%E8%80%8C%E5%86%99%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%8E%B0%E5%9C%A8%E5%BE%88%E5%B0%91%E5%86%99%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%94%B1%E6%84%9F%E8%80%8C%E5%86%99%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%8E%B0%E5%9C%A8%E5%BE%88%E5%B0%91%E5%86%99%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0/%E7%94%B1%E6%84%9F%E8%80%8C%E5%86%99%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%8E%B0%E5%9C%A8%E5%BE%88%E5%B0%91%E5%86%99%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0/</guid><description>今天脑子里面突然想到写这么一篇文章，也是由感而写。回到文章主题，为什么我现在的文章都很少写技术文章，如果有长期看我博客的，或者从旧博客就开始关注的人应该会发现，随着时间的推移，我写技术文章的次数越来越少，可以说是一个月都很难挤出一篇来。</description><pubDate>Tue, 16 Sep 2025 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;由感而写：为什么我现在很少写技术文章&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;今天脑子里面突然想到写这么一篇文章，也是由感而写。回到文章主题，为什么我现在的文章都很少写技术文章，如果有长期看我博客的，或者从旧博客就开始关注的人应该会发现，随着时间的推移，我写技术文章的次数越来越少，可以说是一个月都很难挤出一篇来。&lt;/p&gt;
&lt;p&gt;那么为什么会出现这个现象呢?&lt;/p&gt;
&lt;h2&gt;拖延&lt;/h2&gt;
&lt;p&gt;从步入社会开始上班之后，发现自己的拖延症越来越严重，每次上班或者周末休息的时候，脑子里面可以说是思绪万千，什么都想干，但什么又干不动，只有想法没有行动。&lt;/p&gt;
&lt;p&gt;上班的时候，脑子里面出现过很多项目，比如记账、书签、收藏夹，我都想去实现这些项目，但是当我建立完项目，开始编写代码，心血来潮的写了几行，后面又被搁置，之后就是没有提交过代码了。&lt;/p&gt;
&lt;h2&gt;焦虑&lt;/h2&gt;
&lt;p&gt;为什会出现这种情况，我个人觉得还是上班的时候，给自己的压力太大了，为了处理客户的问题，忙前忙后，甚至是下班的时候被客户骚扰，身心没有得到放松，精神高度紧绷，生怕错过消息。&lt;/p&gt;
&lt;p&gt;当一个人自己给自己施加压力，也可以说是焦虑之后，做什么事都没兴趣，没办法坚持做下去，因为脑子里面无时无刻不在胡思乱想，担忧。&lt;/p&gt;
&lt;h3&gt;时间&lt;/h3&gt;
&lt;p&gt;之前写技术文章的时候，还处于学生时代，我有花不完的时间去专研，去学习，我可以探索和学习各种新技术，这也是导致我一开始技术文章高产的原因。&lt;/p&gt;
&lt;p&gt;但是上班之后，总感觉时间不够，时间不知不觉就过去了，在学习的时候也会心不在焉，注意力无法集中，这种状态写出的技术文章，我不如用&lt;code&gt;AI&lt;/code&gt;直接生成，所以状态不佳也是技术文章产出少的原因之一。&lt;/p&gt;
&lt;h2&gt;没人看&lt;/h2&gt;
&lt;p&gt;我写的技术文章，大多数是我自己在学习过程中的一些心得，可能会和很多其他博主写的内容有高度重合，这导致大部分对我的文章不感兴趣，不过我写技术文章不光是为了给大家学习，更多的是给自己做记录。&lt;/p&gt;
&lt;p&gt;但是没人看的话，写文章的动力就减少了，这也导致我开始慢慢产出日常生活类文章，反而看得人更多。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;其实还有很多原因，但是明天还要上班，今天就写到这了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./202aa8c301e4288c6b7d82d87ba92c90.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>记录第N次服务器被植入挖坑病毒</title><link>https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E7%AC%ACn%E6%AC%A1%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E6%A4%8D%E5%85%A5%E6%8C%96%E5%9D%91%E7%97%85%E6%AF%92/%E8%AE%B0%E5%BD%95%E7%AC%ACn%E6%AC%A1%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E6%A4%8D%E5%85%A5%E6%8C%96%E5%9D%91%E7%97%85%E6%AF%92/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E7%AC%ACn%E6%AC%A1%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E6%A4%8D%E5%85%A5%E6%8C%96%E5%9D%91%E7%97%85%E6%AF%92/%E8%AE%B0%E5%BD%95%E7%AC%ACn%E6%AC%A1%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E6%A4%8D%E5%85%A5%E6%8C%96%E5%9D%91%E7%97%85%E6%AF%92/</guid><description>最近太忙了，无暇管理博客，也没怎么写文章，很多技术文章写一半都被我搁置了，主要还是感觉生活压力大，下班之后很难行动起来，只想躺着。为什么标题要说是第N次呢？</description><pubDate>Wed, 10 Sep 2025 21:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;记录第N次服务器被植入挖坑病毒&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;./1.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;📑前言&lt;/h2&gt;
&lt;p&gt;最近太忙了，无暇管理博客，也没怎么写文章，很多技术文章写一半都被我搁置了，主要还是感觉生活压力大，下班之后很难行动起来，只想躺着。&lt;/p&gt;
&lt;p&gt;为什么标题要说是第N次呢？&lt;/p&gt;
&lt;p&gt;其实在刚接触服务器的那段时间也被植入过挖坑程序，也算是踩坑多次。&lt;/p&gt;
&lt;p&gt;声明：本人是个服务器小白，就单纯会敲&lt;code&gt;cd&lt;/code&gt;命令和&lt;code&gt;docker&lt;/code&gt;命令部署点项目玩玩！&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;font size=&quot;2&quot;&amp;gt;tip：最近太忙有一部分原因是公司老板迷上了AI，天天就是AI分享，搞得公司员工身心疲惫,我在考虑要不要写一篇吐槽文章。&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;💥事发&lt;/h2&gt;
&lt;p&gt;上班摸鱼时间，突然发现博客访问不到了，天塌了，像这种情况，我以为是服务器被攻击了（因为之前被&lt;code&gt;DDOS&lt;/code&gt;攻击过）。然后打开阿里云控制面板发现不是， 看了一下阿里云的消息发现是又被植入挖坑程序了，天塌了，按道理这时候应该会提前接收到短信的，但是好巧不巧被苹果（IOS 26.0版本）手机识别为未知发件人短信了，导致我没有第一时间弹出信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;💫处理&lt;/h2&gt;
&lt;p&gt;由于之前也处理过这类事情，其实就是普通的挖坑程序，根据阿里云提供的信息，kill 进程、删除挖矿文件以及后门就能解决了。&lt;/p&gt;
&lt;p&gt;这里就不细讲操作了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;💯事后&lt;/h2&gt;
&lt;p&gt;经过这次事件之后，我把ssh登录从密码登录改为秘钥登录、&lt;code&gt;Redis&lt;/code&gt;从外网访问改为只能内网访问，也安装阿里云给出的建议做了一系列防护。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;🤡总结&lt;/h2&gt;
&lt;p&gt;虽然不知道挖坑程序是怎么植入的，不过大概是ssh暴力破解或者利用了&lt;code&gt;Redis&lt;/code&gt;，这就不得而知了，不过本身我的服务器也没有什么重要文件，博客的文章也是存放在本地再上传服务器的，所以我对于安全这块好像没怎么研究，只有当我的服务出现异常才会着急，希望大家不要像我学习，哈哈。&lt;/p&gt;
</content:encoded></item><item><title>我的图片转ico网站必应收录没有了</title><link>https://blog.pljzy.top/posts/%E6%88%91%E7%9A%84%E5%9B%BE%E7%89%87%E8%BD%ACico%E7%BD%91%E7%AB%99%E5%BF%85%E5%BA%94%E6%94%B6%E5%BD%95%E6%B2%A1%E6%9C%89%E4%BA%86/%E6%88%91%E7%9A%84%E5%9B%BE%E7%89%87%E8%BD%ACico%E7%BD%91%E7%AB%99%E5%BF%85%E5%BA%94%E6%94%B6%E5%BD%95%E6%B2%A1%E6%9C%89%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%88%91%E7%9A%84%E5%9B%BE%E7%89%87%E8%BD%ACico%E7%BD%91%E7%AB%99%E5%BF%85%E5%BA%94%E6%94%B6%E5%BD%95%E6%B2%A1%E6%9C%89%E4%BA%86/%E6%88%91%E7%9A%84%E5%9B%BE%E7%89%87%E8%BD%ACico%E7%BD%91%E7%AB%99%E5%BF%85%E5%BA%94%E6%94%B6%E5%BD%95%E6%B2%A1%E6%9C%89%E4%BA%86/</guid><description>我在7月初的部署了一个[图片转ico图标](https://ico.pljzy.top)的网站，必应大概是从7月6号开始收录，截止到8月27号还是能在必应搜索到我的网站的。</description><pubDate>Mon, 01 Sep 2025 12:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;我的图片转ico网站必应收录没有了&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;我在7月初的部署了一个&lt;a href=&quot;https://ico.pljzy.top&quot;&gt;图片转ico图标&lt;/a&gt;的网站，必应大概是从7月6号开始收录，截止到8月27号还是能在必应搜索到我的网站的。&lt;/p&gt;
&lt;p&gt;但在8月28号开始就搜不到了，然后我在&lt;a href=&quot;https://www.bing.com/webmasters/&quot;&gt;必应站长平台&lt;/a&gt;查看，发现索引是正常的，不知道是什么原因导致已经被收录过的网站却搜索不到了。&lt;/p&gt;
&lt;h2&gt;正文&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;结尾&lt;/h2&gt;
&lt;p&gt;目前已经向必应提交工单，看后续怎么回应吧。&lt;/p&gt;
</content:encoded></item><item><title>恭喜韩天尊结婴成功</title><link>https://blog.pljzy.top/posts/%E6%81%AD%E5%96%9C%E9%9F%A9%E5%A4%A9%E5%B0%8A%E7%BB%93%E5%A9%B4%E6%88%90%E5%8A%9F/%E6%81%AD%E5%96%9C%E9%9F%A9%E5%A4%A9%E5%B0%8A%E7%BB%93%E5%A9%B4%E6%88%90%E5%8A%9F/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%81%AD%E5%96%9C%E9%9F%A9%E5%A4%A9%E5%B0%8A%E7%BB%93%E5%A9%B4%E6%88%90%E5%8A%9F/%E6%81%AD%E5%96%9C%E9%9F%A9%E5%A4%A9%E5%B0%8A%E7%BB%93%E5%A9%B4%E6%88%90%E5%8A%9F/</guid><description>恭喜韩天尊结婴成功</description><pubDate>Sat, 16 Aug 2025 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;恭喜韩天尊结婴成功&lt;/h1&gt;
&lt;p&gt;【凡人修仙传：第156话 重返天南4】 https://www.bilibili.com/bangumi/play/ep1231564/?share_source=copy_web&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe frameborder=&quot;no&quot; border=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; width=330 height=86 src=&quot;//music.163.com/outchain/player?type=2&amp;amp;id=1465288702&amp;amp;auto=1&amp;amp;height=66&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>博客篇：新增图片页面</title><link>https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%B0%E5%A2%9E%E5%9B%BE%E7%89%87%E9%A1%B5%E9%9D%A2/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%B0%E5%A2%9E%E5%9B%BE%E7%89%87%E9%A1%B5%E9%9D%A2/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%B0%E5%A2%9E%E5%9B%BE%E7%89%87%E9%A1%B5%E9%9D%A2/%E5%8D%9A%E5%AE%A2%E7%AF%87%E6%96%B0%E5%A2%9E%E5%9B%BE%E7%89%87%E9%A1%B5%E9%9D%A2/</guid><description>博客篇：新增图片页面前言换博客之后，也是折腾了挺多功能，比如评论、友链页面、文章置顶等等。和我之前的旧博客比起来还是少了些功能。想着加一个图片页面出来，说干就干，用Cursor给博客添加了个图片页面，用于展示图片。</description><pubDate>Sat, 16 Aug 2025 15:57:26 GMT</pubDate><content:encoded>&lt;h1&gt;博客篇：新增图片页面&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;换博客之后，也是折腾了挺多功能，比如评论、友链页面、文章置顶等等。和我之前的旧博客比起来还是少了些功能。想着加一个图片页面出来，说干就干，用&lt;code&gt;Cursor&lt;/code&gt;给博客添加了个图片页面，用于展示图片。当然图片使用的是&lt;a href=&quot;https://docs.lsky.pro/&quot;&gt;兰空图床&lt;/a&gt;来存放的。&lt;/p&gt;
&lt;p&gt;不得不说&lt;code&gt;Cursor&lt;/code&gt;还是挺给力的，几乎10分钟不到就完成我想要的效果，不过还是有点小细节需要自己去改改。&lt;/p&gt;
&lt;p&gt;图片页面直达地址：https://blog.pljzy.top/images/&lt;/p&gt;
&lt;h2&gt;页面截图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以通过鼠标移入图片来查看原图。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;相关代码&lt;/h2&gt;
&lt;p&gt;博客新增的功能已同步更新到我的&lt;code&gt;Github&lt;/code&gt;仓库：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://github.com/ZyPLJ/fuwai_zyplj&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个仓库和我博客部署的仓库几乎是一模一样的，只是删除了一些配置而已。&lt;/p&gt;
&lt;p&gt;图片页面主要就是添加了一个图片&lt;code&gt;Svelte&lt;/code&gt;组件页面，然后在&lt;code&gt;config&lt;/code&gt;配置文件中添加了一些必要的配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;文章开头就说过，使用了&lt;a href=&quot;https://docs.lsky.pro/&quot;&gt;兰空图床&lt;/a&gt;,所以需要配置&lt;code&gt;Api&lt;/code&gt;地址和&lt;code&gt;token&lt;/code&gt;才能让图片页面正常显示。&lt;/p&gt;
&lt;p&gt;兰空图床怎么部署这里就不讲了，博主使用的是&lt;code&gt;Docker&lt;/code&gt;部署在自己的服务器上的。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;这个页面开发起来不难，几乎全部是&lt;code&gt;Cursor&lt;/code&gt;去完成的，主要也是对接兰空图床提供的接口就行了,唯一的不足就是，&lt;code&gt;token&lt;/code&gt;可能会泄露，所以要在图床上面设置好限制，不然遇到坏人就会把服务器搞崩,目前就这样了，后续看能不能再优化一下安全性。&lt;/p&gt;
&lt;p&gt;不过我的这些修改好像违背了静态博客的初衷，哈哈，不过&lt;code&gt;Astro&lt;/code&gt;框架用着挺爽的，可以在同一个项目里混合用 &lt;code&gt;React + Vue + Svelte&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果看到喜欢的图片，欢迎自取~&lt;/p&gt;
</content:encoded></item><item><title>🎵 Balazing Heart — 灼火之心</title><link>https://blog.pljzy.top/posts/balazingheart/balazing-heart-%E7%81%BC%E7%81%AB%E4%B9%8B%E5%BF%83%E9%9F%B3%E4%B9%90/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/balazingheart/balazing-heart-%E7%81%BC%E7%81%AB%E4%B9%8B%E5%BF%83%E9%9F%B3%E4%B9%90/</guid><description>一首充满热血与力量的战歌，点燃心中的火焰，带你驶向未知的旅途。</description><pubDate>Tue, 12 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;🎵 Balazing Heart — 灼火之心&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;2.jpg&quot; alt=&quot;Balazing Heart&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一首充满热血与力量的战歌，点燃心中的火焰，带你驶向未知的旅途。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;🎧 在线收听&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?isOutside=true&amp;amp;aid=113742394234505&amp;amp;bvid=BV1PH6GYUEZC&amp;amp;cid=27611762071&amp;amp;p=1&quot; title=&quot;Balazing Heart-灼火之心音乐&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;📜 歌词&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;点燃灼热的声浪&lt;br /&gt;
蒸发荒漠绿洲海洋&lt;br /&gt;
开往未知前方&lt;br /&gt;
旅途的起点&lt;br /&gt;
向着星辰日月&lt;br /&gt;
下一站到达&lt;br /&gt;
无论春秋冬夏&lt;br /&gt;
宿命分岔划出伤疤&lt;br /&gt;
挣扎的代价&lt;br /&gt;
&lt;strong&gt;Blazing Heart！再出发&lt;/strong&gt;&lt;br /&gt;
风来引航 光的方向&lt;br /&gt;
超越过往 将意志武装&lt;br /&gt;
把泪与伤燃作勋章&lt;br /&gt;
载无畏向赛场&lt;br /&gt;
唤醒沉睡中的力量&lt;br /&gt;
&lt;strong&gt;火 是热 是梦 是光&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Blazing Heart Blazing Heart!&lt;/strong&gt;&lt;br /&gt;
去绽放 勇气碾碎 末日交响&lt;br /&gt;
一路高唱 加速向太阳&lt;br /&gt;
故事刚刚开场&lt;br /&gt;
&lt;strong&gt;Blazing Heart! 请苏醒&lt;/strong&gt;&lt;br /&gt;
夜会铭记 英雄的名&lt;br /&gt;
撕开命运 烧炼出赤心&lt;br /&gt;
把苦与痛当作洗礼&lt;br /&gt;
载信仰去战场&lt;br /&gt;
友谊铸成胜利的枪&lt;br /&gt;
&lt;strong&gt;火 是热 是梦 是光&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;💬 推荐理由&lt;/h2&gt;
&lt;p&gt;这首歌旋律热血高昂，歌词充满奋斗与信念，非常适合在需要鼓励、打气的时候循环播放。无论是在游戏赛场还是现实生活中，都能点燃你的斗志。&lt;/p&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>说说我把运行3年的个人博客网站换了~</title><link>https://blog.pljzy.top/posts/personalblog/%E8%BF%90%E8%A1%8C3%E5%B9%B4%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E7%BD%91%E7%AB%99%E6%8D%A2%E6%A1%86%E6%9E%B6%E4%BA%86/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/personalblog/%E8%BF%90%E8%A1%8C3%E5%B9%B4%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E7%BD%91%E7%AB%99%E6%8D%A2%E6%A1%86%E6%9E%B6%E4%BA%86/</guid><description>说说我把运行3年的个人博客网站换了~前言这是一篇宣传我的新博客的文章，阅读原文跳转友链申请页面，欢迎互换友链~</description><pubDate>Fri, 08 Aug 2025 15:54:55 GMT</pubDate><content:encoded>&lt;h1&gt;说说我把运行3年的个人博客网站换了~&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;这是一篇宣传我的新博客的文章，阅读原文跳转友链申请页面，欢迎互换友链~&lt;/p&gt;
&lt;p&gt;之前的文章讲了我把现在的博客网站换成了基于&lt;code&gt;Astro&lt;/code&gt;开发的&lt;code&gt;Fuwari&lt;/code&gt;静态博客模版。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.pljzy.top/posts/astro/%E5%9F%BA%E4%BA%8Eastro%E5%BC%80%E5%8F%91%E7%9A%84fuwari%E9%9D%99%E6%80%81%E5%8D%9A%E5%AE%A2%E6%A8%A1%E7%89%88%E9%85%8D%E7%BD%AEcicd%E6%B5%81%E7%A8%8B/&quot;&gt;基于Astro开发的Fuwari静态博客模版配置CICD流程&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;旧站：&lt;a href=&quot;https://www.pljzy.top&quot;&gt;ZY知识库-pljzy.top&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;新站：&lt;a href=&quot;https://blog.pljzy.top&quot;&gt;ZY知识库-blog.pljzy.top&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;旧站依然使用顶级域名正常运行，目前还没有关闭旧站的想法，新站部署在&lt;code&gt;blog&lt;/code&gt;子域名下。&lt;/p&gt;
&lt;h2&gt;为什么要换？&lt;/h2&gt;
&lt;h3&gt;博客前世&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;旧站还是我在上大学的时候使用开源的&lt;a href=&quot;https://github.com/Deali-Axy/StarBlog&quot;&gt;StarBlog&lt;/a&gt;博客二次开发部署的。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Deali-Axy/StarBlog&quot;&gt;StarBlog&lt;/a&gt;博客是一个适合&lt;code&gt;.Net&lt;/code&gt;初学者的博客系统，里面有很多常用的技术栈，非常适合学习。&lt;/p&gt;
&lt;p&gt;我也是在这个博客中学到了很多知识，当时也是花了点时间基于这个博客修改了很多代码，不过当时我写的代码没有规范，现在维护起来很麻烦😅。&lt;/p&gt;
&lt;p&gt;但是旧站的功能还是挺完善的，经过我的锦上添“花”，也是完成了最终博客如今的摸样。&lt;/p&gt;
&lt;p&gt;这个博客文章发布是用配套的后台管理系统去管理的，这里就不细讲了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;换站原因&lt;/h3&gt;
&lt;p&gt;导致我换掉旧博客采用新博客的原因，主要是因为旧博客静态资源的问题，加载非常慢，访问过我旧站的人应该能够感受到，因为我在旧博客里面放了很多图片，加上大部分图片都没有用&lt;code&gt;cdn&lt;/code&gt;加速。如果没有遇到&lt;code&gt;DNS&lt;/code&gt;解析慢的问题话，估计也得花个10秒左右才能加载完整个首页。&lt;/p&gt;
&lt;p&gt;刚好我在使用&lt;a href=&quot;https://www.travellings.cn/&quot;&gt;开往&lt;/a&gt;随机跳转到了同样使用新博客模版的博客网站，第一眼我就喜欢上了这个主题。&lt;/p&gt;
&lt;p&gt;也是在第一时间去&lt;code&gt;Github&lt;/code&gt;下载了&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;模版，开始部署这个新博客网站。&lt;/p&gt;
&lt;p&gt;原作者开发时还并未完成评论系统的开发，所以我在新博客上加上了 &lt;a href=&quot;https://twikoo.js.org/frontend.html&quot;&gt;Twikoo&lt;/a&gt;评论系统，目前使用情况良好。&lt;/p&gt;
&lt;h3&gt;博客今生&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;对于音乐的执着，我将旧站的&lt;code&gt;APlayer&lt;/code&gt;音乐播放器也搬到了新博客，这也是一种传承吧😂&lt;/p&gt;
&lt;p&gt;对于新博客，因为这是个静态博客，没有后端加上首页图片不多，访问起来速度是很快的。&lt;/p&gt;
&lt;p&gt;同时我也对一些较大的静态文件使用了&lt;code&gt;CDN&lt;/code&gt;，在没有&lt;code&gt;DNS&lt;/code&gt;解析问题的情况下，&lt;code&gt;1S-2S&lt;/code&gt;就能完成页面加载。&lt;/p&gt;
&lt;p&gt;虽然新博客没有后台系统，但是发布文章也是很方便的，搭配上&lt;code&gt;GitHub Action&lt;/code&gt;可以实现&lt;code&gt;CICD&lt;/code&gt;流程。&lt;/p&gt;
&lt;p&gt;只需提交文章，然后&lt;code&gt;push&lt;/code&gt;到&lt;code&gt;Github&lt;/code&gt;上就可以自动完成文章发布。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;文章搬迁&lt;/h2&gt;
&lt;p&gt;对于文章搬迁也不算太麻烦，只需要将我之前的文章目录拷贝到新博客文章目录下，然后在&lt;code&gt;md&lt;/code&gt;格式的文章开头添加预览信息就行了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 基于Astro开发的Fuwari静态博客模版配置CICD流程
published: 2025-07-30
description: 同往常一样，上班摸鱼的时候，就喜欢逛逛随机逛逛别人的博客，然后有一个博客的主题让我有点心动。我自己也是部署了博客的，我目前的博客网站是：[ZY的博客](https://pljzy.top/)，已经安稳运行了800多天。
tags: [Docker, CICD, 博客]
category: 杂七杂八
draft: false
pinned: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我这里有个习惯，我的文章图片都是相对路径(图片和文章在同一目录下)，所以搬迁起来不用考虑图片位置的问题。如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![](1.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然用对于有的图床搬迁起来更容易。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;旧站依然在运行，不过我会把心思花在新站上了。&lt;/p&gt;
&lt;p&gt;如果想部署同款博客，欢迎在本文章下评论留言，我会解答你的问题。&lt;/p&gt;
&lt;h2&gt;相关链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;旧站：&lt;a href=&quot;https://www.pljzy.top&quot;&gt;ZY知识库-pljzy.top&lt;/a&gt;-https://www.pljzy.top&lt;/li&gt;
&lt;li&gt;新站：&lt;a href=&quot;https://blog.pljzy.top&quot;&gt;ZY知识库-blog.pljzy.top&lt;/a&gt;-https://blog.pljzy.top&lt;/li&gt;
&lt;li&gt;StarBlog开源博客：&lt;a href=&quot;https://github.com/Deali-Axy/StarBlog&quot;&gt;StarBlog&lt;/a&gt;-https://github.com/Deali-Axy/StarBlog&lt;/li&gt;
&lt;li&gt;Fuwari博客模板：&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;-https://github.com/saicaca/fuwari&lt;/li&gt;
&lt;li&gt;Astro框架：&lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;-https://astro.build/&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>记录一次未合并的PR分支合并到本地</title><link>https://blog.pljzy.top/posts/pr/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E6%9C%AA%E5%90%88%E5%B9%B6%E7%9A%84pr%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E5%88%B0%E6%9C%AC%E5%9C%B0/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/pr/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E6%9C%AA%E5%90%88%E5%B9%B6%E7%9A%84pr%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E5%88%B0%E6%9C%AC%E5%9C%B0/</guid><description>记录一次合并PR分支前言最近一直再折腾博客，我发现fuwari有很多实用的功能没有被作者合并，例如文章固定的功能，简而言之就是置顶。</description><pubDate>Mon, 04 Aug 2025 10:50:20 GMT</pubDate><content:encoded>&lt;h1&gt;记录一次未合并的PR分支合并到本地&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近一直再折腾博客，我发现&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;fuwari&lt;/a&gt;有很多实用的功能没有被作者合并，例如文章固定的功能，简而言之就是置顶。&lt;/p&gt;
&lt;p&gt;PR地址：&lt;a href=&quot;https://github.com/saicaca/fuwari/pull/433&quot;&gt;PR433&lt;/a&gt; https://github.com/saicaca/fuwari/pull/433&lt;/p&gt;
&lt;p&gt;通过vercel提供的预览地址：https://fuwari-yags-git-fork-kintamiao-main-zephyirdgmailcoms-projects.vercel.app/ 发现这个置顶还不错。&lt;/p&gt;
&lt;p&gt;想着给自己的博客也整上，那么下面就开始操作。&lt;/p&gt;
&lt;h2&gt;第一步：添加远程仓库&lt;/h2&gt;
&lt;p&gt;在开始拉取PR前，需要先添加原作者的仓库作为远程仓库。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote add upstream https://github.com/saicaca/fuwari.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加后可以验证一下是否添加成功。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第二步：拉取PR&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git fetch upstream pull/433/head:dev
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;433&lt;/code&gt; 是 PR 编号&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dev&lt;/code&gt; 是本地创建的分支名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第三步：合并&lt;/h2&gt;
&lt;p&gt;合并这里我在Rider中合并，图形化操作方便一点。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;无法合并&lt;/h2&gt;
&lt;p&gt;如果因为你的主分支和原作者的主分支不一样，那么可能无法直接合并，需要单独将置顶功能的提交单独拎出来合并。&lt;/p&gt;
&lt;p&gt;首先查看dev提交历史，找到置顶功能合并的id。&lt;/p&gt;
&lt;p&gt;然后应用提交，在Rider就能出现合并的操作提示了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; git log dev
 git cherry-pick d74c3c483f0a4105155d38e9d780be83b07d0a1c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下来进行手动合并就行了。&lt;/p&gt;
&lt;h2&gt;效果展示&lt;/h2&gt;
&lt;p&gt;可以看到第一篇文章有一个置顶图标了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>基于Astro开发的Fuwari静态博客模版配置CICD流程</title><link>https://blog.pljzy.top/posts/astro/%E5%9F%BA%E4%BA%8Eastro%E5%BC%80%E5%8F%91%E7%9A%84fuwari%E9%9D%99%E6%80%81%E5%8D%9A%E5%AE%A2%E6%A8%A1%E7%89%88%E9%85%8D%E7%BD%AEcicd%E6%B5%81%E7%A8%8B/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/astro/%E5%9F%BA%E4%BA%8Eastro%E5%BC%80%E5%8F%91%E7%9A%84fuwari%E9%9D%99%E6%80%81%E5%8D%9A%E5%AE%A2%E6%A8%A1%E7%89%88%E9%85%8D%E7%BD%AEcicd%E6%B5%81%E7%A8%8B/</guid><description>同往常一样，上班摸鱼的时候，就喜欢逛逛随机逛逛别人的博客，然后有一个博客的主题让我有点心动。我自己也是部署了博客的，我目前的博客网站是：[ZY的博客](https://pljzy.top/)，已经安稳运行了800多天。</description><pubDate>Wed, 30 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;基于Astro开发的Fuwari静态博客模版配置CICD流程&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;同往常一样，上班摸鱼的时候，就喜欢逛逛随机逛逛别人的博客，然后有一个博客的主题让我有点心动。&lt;/p&gt;
&lt;p&gt;我自己也是部署了博客的，我目前的博客网站是：&lt;a href=&quot;https://pljzy.top/&quot;&gt;ZY的博客&lt;/a&gt;，已经安稳运行了800多天。不过我的博客有个缺点就是加载很慢，主要原因呢是因为静态资源的关系，虽然有一小部分我使用了七牛云的&lt;code&gt;cdn&lt;/code&gt;服务，但还是无法解决访问慢的问题。加上本身的服务器带宽也不大，只有&lt;code&gt;3M&lt;/code&gt;的带宽。种种原因导致我的博客访问很慢，然后就遇到了今天要说的这个博客，这是一个静态博客，访问起来速度会快很多。&lt;/p&gt;
&lt;p&gt;这个博客是基于&lt;a href=&quot;https://docs.astro.build/zh-cn/concepts/why-astro/&quot;&gt;Astro&lt;/a&gt;开发的一个博客主题模版，GitHub上叫&lt;a href=&quot;https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&quot;&gt;fuwari&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;先来放一张博客的图片，我觉得这个主题还是很好看的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;在线访问&lt;/h2&gt;
&lt;p&gt;目前我的新博客也已经部署到服务器上了，地址为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.pljzy.top/&quot;&gt;ZY知识库&lt;/a&gt; https://blog.pljzy.top/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;欢迎大家访问我的新博客！&lt;/p&gt;
&lt;h2&gt;博客的不足&lt;/h2&gt;
&lt;p&gt;如果拿这个博客和我目前的博客对比，我认为的不足点有以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[x] 评论功能还未完成；（已集成）&lt;/li&gt;
&lt;li&gt;[ ] 没有友情链接功能；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&quot;&gt;fuwari&lt;/a&gt;的开发者不知道什么时候会更新评论功能，不过我在翻阅&lt;code&gt;Pull requests&lt;/code&gt;时，发现有一个关于评论的合并请求：https://github.com/saicaca/fuwari/pull/406。&lt;/p&gt;
&lt;p&gt;我也是花了时间去实验了一下，发现我还得重新注册个域名，总的来说还是比较麻烦的。后面发现他这种办法是针对于没有服务器的博主，我有自己的服务器完全可以找一个开源的评论系统集成到&lt;a href=&quot;https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&quot;&gt;fuwari&lt;/a&gt;中去就行了。&lt;/p&gt;
&lt;p&gt;后续我在博客集成了&lt;a href=&quot;https://twikoo.js.org/quick-start.html&quot;&gt;Twikoo&lt;/a&gt;评论系统，后面我再单独出一篇文章讲如何集成评论系统。&lt;/p&gt;
&lt;p&gt;总之我觉得&lt;a href=&quot;https://docs.astro.build/zh-cn/concepts/why-astro/&quot;&gt;Astro&lt;/a&gt;的自由度很高，支持很多语言如：&lt;code&gt;React&lt;/code&gt;、&lt;code&gt;Preact&lt;/code&gt;、&lt;code&gt;Svelte&lt;/code&gt;、&lt;code&gt;Vue&lt;/code&gt;、&lt;code&gt;Solid&lt;/code&gt;等，可扩展性很高，完全可以根据自己的想法去修改博客的内容。&lt;/p&gt;
&lt;h2&gt;如何部署&lt;/h2&gt;
&lt;p&gt;下面来讲一讲如何部署一个这个博客，&lt;a href=&quot;https://docs.astro.build/zh-cn/concepts/why-astro/&quot;&gt;Astro&lt;/a&gt;的文档很详细，这里就拿部署到&lt;code&gt;GitHub&lt;/code&gt;上来作为例子。&lt;/p&gt;
&lt;p&gt;部署文档：&lt;a href=&quot;https://docs.astro.build/zh-cn/guides/deploy/github/&quot;&gt;部署你的 Astro 站点至 GitHub Pages | Docs&lt;/a&gt; https://docs.astro.build/zh-cn/guides/deploy/github/&lt;/p&gt;
&lt;p&gt;部署文档里面说的很清楚，我这里就不再复述了，如果只是单纯的部署到&lt;code&gt;GitHub Pages&lt;/code&gt;上，跟着官方文档去做，一般不会出现问题。&lt;/p&gt;
&lt;h3&gt;使用自己的域名&lt;/h3&gt;
&lt;p&gt;总所周知，&lt;code&gt;Github Pages&lt;/code&gt;部署后会给你一个&lt;code&gt;Github.io&lt;/code&gt;域名，如果想使用自己的域名则需要做一点修改。&lt;/p&gt;
&lt;p&gt;首先修改代码中的&lt;code&gt;astro.config.mjs&lt;/code&gt;文件，将&lt;code&gt;site&lt;/code&gt;指向你的域名，&amp;lt;font color=&apos;red&apos;&amp;gt;要注意的是不要为 &lt;code&gt;base&lt;/code&gt; 设置值。&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { defineConfig } from &apos;astro/config&apos;

export default defineConfig({
  site: &apos;https://example.com&apos;,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;域名解析&lt;/h3&gt;
&lt;p&gt;代码改完之后，需要为你的域名添加域名解析，以阿里云域名为例。&lt;/p&gt;
&lt;p&gt;顶级域名：需要添加A类解析，将你的顶级域名指向&lt;code&gt;Github.io&lt;/code&gt;域名的&lt;code&gt;ip&lt;/code&gt;地址，获取ip地址，本地控制台ping一下&lt;code&gt;github.io&lt;/code&gt;域名即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果是二级域名，比如我的&lt;code&gt;blog.pljzy.top&lt;/code&gt;,那么则需要添加的是CNAME类型的解析，将&lt;code&gt;blog.pljzy.top&lt;/code&gt;域名直接解析到&lt;code&gt;Github.io&lt;/code&gt;上去就行了。&lt;/p&gt;
&lt;h3&gt;Github配置&lt;/h3&gt;
&lt;p&gt;如图所示：&lt;/p&gt;
&lt;p&gt;Source选择&lt;code&gt;GitHub Actions&lt;/code&gt;，&lt;code&gt;Custom domian&lt;/code&gt;填入自己的域名，然后强制&lt;code&gt;HTTPS&lt;/code&gt;打开。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;如何创建文章&lt;/h2&gt;
&lt;p&gt;部署完成后，如果上传文章呢，我之前的博客是在后台管理系统中上传文章，这个静态博客当然是不存在后台管理系统的，所以上传文章就需要手动去讲文章放到&lt;code&gt;posts&lt;/code&gt;目录下。&lt;/p&gt;
&lt;p&gt;注意分为带展示图的文章和不带展示图的文章。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;posts&lt;/code&gt;指代&lt;code&gt;Src&lt;/code&gt;-&amp;gt;&lt;code&gt;Content&lt;/code&gt;-&amp;gt;&lt;code&gt;posts&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;带展示图&lt;/h3&gt;
&lt;p&gt;在&lt;code&gt;posts&lt;/code&gt;目录下创建文章目录&lt;code&gt;guide&lt;/code&gt;，&lt;code&gt;cover.jpeg&lt;/code&gt;就是首图，&lt;code&gt;index.md&lt;/code&gt;就是文章。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;guide/
├── index.md
└── cover.jpeg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;不带展示图&lt;/h3&gt;
&lt;p&gt;不带展示图的文章就只需要在&lt;code&gt;posts&lt;/code&gt;下创建md文件即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;posts/
└── index.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;注意&lt;/h3&gt;
&lt;p&gt;需要注意的是，md文件需要再开头添加上标识，用于展示文章的标题、时间、首图、分类、标签等信息。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
lang: jp      # Set only if the post&apos;s language differs from the site&apos;s language in `config.ts`
---、
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;步入正题CICD&lt;/h2&gt;
&lt;h3&gt;CICD简述&lt;/h3&gt;
&lt;p&gt;CI/CD（持续集成/持续交付或持续部署）是一种自动化软件开发和交付流程。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持续集成（CI）：开发者提交代码后，自动触发构建和测试（单元测试、代码扫描等）。&lt;/li&gt;
&lt;li&gt;持续交付（CD）：生成可部署的产物（如Docker镜像），等待人工确认发布。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简言之，CI/CD通过自动化实现从代码提交到发布的快速、可靠流程。&lt;/p&gt;
&lt;h3&gt;deploy.yml&lt;/h3&gt;
&lt;p&gt;上面扯了很多，还没有开始讲&lt;code&gt;CICD&lt;/code&gt;。部署到&lt;code&gt;GitHub Pages&lt;/code&gt;时，Astro官方文档给了一个通用的&lt;code&gt;Github Action&lt;/code&gt;模版。&lt;/p&gt;
&lt;p&gt;使用这个模版就可以完成简单的&lt;code&gt;CICD&lt;/code&gt;流程，我们只需要在本地的&lt;code&gt;Src&lt;/code&gt;-&amp;gt;&lt;code&gt;Content&lt;/code&gt;-&amp;gt;&lt;code&gt;posts&lt;/code&gt;中创建文章，或者把文章目录移入该目录下，然后&lt;code&gt;commit&lt;/code&gt;提交，&lt;code&gt;push&lt;/code&gt;推送，&lt;code&gt;GitHub Action&lt;/code&gt;会自动帮我们完成打包+部署。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy to GitHub Pages

on:
  # 每次推送到 `main` 分支时触发这个“工作流程”
  # 如果你使用了别的分支名，请按需将 `main` 替换成你的分支名
  push:
    branches: [ main ]
  # 允许你在 GitHub 上的 Actions 标签中手动触发此“工作流程”
  workflow_dispatch:

# 允许 job 克隆 repo 并创建一个 page deployment
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout your repository using git
        uses: actions/checkout@v4
      - name: Install, build, and upload your site
        uses: withastro/action@v3
        # with:
          # path: . # 存储库中 Astro 项目的根位置。（可选）
          # node-version: 20 # 用于构建站点的特定 Node.js 版本，默认为 20。（可选）
          # package-manager: pnpm@latest # 应使用哪个 Node.js 包管理器来安装依赖项和构建站点。会根据存储库中的 lockfile 自动检测。（可选）

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用自己的服务器&lt;/h3&gt;
&lt;p&gt;考虑到&lt;code&gt;Github Pages&lt;/code&gt;的访问速度时好时坏，非常的不稳定,想部署到自己的服务器上。部署的方式有很多种，直接将打包后的文件丢入&lt;code&gt;Nginx&lt;/code&gt;中，或者使用&lt;code&gt;Docker&lt;/code&gt;构建容器去部署。&lt;/p&gt;
&lt;p&gt;这样做都行，但是我每次添加文章，都要重新去&lt;code&gt;build&lt;/code&gt;代码，然后上传到服务器，很麻烦。&lt;/p&gt;
&lt;p&gt;聪明的网友已经发现解决办法了，上面我们是不是讲过&lt;code&gt;GitHub Action&lt;/code&gt;流程可以完成简单的&lt;code&gt;CICD&lt;/code&gt;，即本地编写&lt;strong&gt;文章-push代码-GitHub自动构建打包部署&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;那我们只需要稍微修改一下&lt;code&gt;deploy.yml&lt;/code&gt;文件，然后在Github配置一下连接服务器的ssh私钥即可。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SERVER_IP：服务器外网ip地址&lt;/li&gt;
&lt;li&gt;SSH_USERNAME：登录用户名&lt;/li&gt;
&lt;li&gt;SSH_PRIVATE_KEY：ssh私钥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;打包后的文件直接丢进服务器的Nginx目录下&lt;/h4&gt;
&lt;p&gt;使用这份&lt;code&gt;deploy.yml&lt;/code&gt;文件就行了，根据自己的实际情况修改挂载目录和端口。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy with Volume Mount

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install and Build (Astro)
        uses: withastro/action@v3

      - name: Upload Files to Server
        uses: appleboy/scp-action@v0.1.6
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: &quot;dist/*&quot;
          target: &quot;/www/wwwroot/default/newblog&quot;  # 直接上传到挂载目录

      - name: Start/Restart Container
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            # 直接运行Nginx容器并挂载目录
            docker stop astro-app || true
            docker rm astro-app || true
            docker run -d \
              --name astro-app \
              -p 4321:80 \
              -v /www/wwwroot/default/newblog:/usr/share/nginx/html:ro \
              nginx:alpine
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用Docker部署到服务器&lt;/h4&gt;
&lt;p&gt;使用&lt;code&gt;Docker&lt;/code&gt;相对来说麻烦一点，使用这份&lt;code&gt;deploy.yml&lt;/code&gt;文件就行了，然后需要常见&lt;code&gt;DockerFile&lt;/code&gt;、&lt;code&gt;docker-compose.yml&lt;/code&gt;、&lt;code&gt;default.conf&lt;/code&gt;这3个文件，博主就是采用的这种方式。同样注意根据自己服务器的实际情况修改目录和端口。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;deploy.yml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Docker Compose Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install and Build (Astro)
        uses: withastro/action@v3
        
      - name: Debug file existence
        run: |
          ls -la
          ls -la dist/ || echo &quot;dist/ not found&quot;
          ls -la docker/ || echo &quot;docker/ not found&quot;
          test -f docker-compose.yml &amp;amp;&amp;amp; echo &quot;docker-compose.yml exists&quot; || echo &quot;docker-compose.yml missing&quot;

      - name: Upload Files to Server
        uses: appleboy/scp-action@v0.1.6
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: &quot;dist/*,docker/*,docker-compose.yml&quot;
          target: &quot;/www/wwwroot/default/newblog&quot;

      - name: Deploy with Docker Compose
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /www/wwwroot/default/newblog
            docker-compose down
            docker-compose up -d --build
            docker system prune -f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DockerFile&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM nginx:alpine

# 删除默认配置
RUN rm /etc/nginx/conf.d/default.conf

# 复制自定义配置
COPY ./nginx/default.conf /etc/nginx/conf.d/

# 复制构建好的静态文件（由CI/CD流程完成）
WORKDIR /usr/share/nginx/html

# 暴露端口
EXPOSE 4321
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.8&apos;
services:
  web:
    build: ./docker
    ports:
      - &quot;4321:4321&quot;
    volumes:
      - /www/wwwroot/default/newblog/dist:/usr/share/nginx/html:ro
    restart: unless-stopped
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;default.conf&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       4321;# 配置端口
    server_name  0.0.0.0; # 修改为docker服务宿主机的ip
 
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;无论采用上述那种方式，我们只需要在本地创建文章然后提交到git上就能自动上传到服务器完成构建并运行重新项目。&lt;/p&gt;
&lt;h2&gt;吐槽一下&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Github Action&lt;/code&gt;调试起来还是挺费劲的，博主整整调试了10几次才完成CICD，有各种原因会导致部署失败。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;效果演示&lt;/h2&gt;
&lt;p&gt;修改代码后直接提交git，就能完成构建部署。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;Github Action&lt;/code&gt;页面可以看到有3个流程，分别是代码检查、构建检查、以及最后的推送到服务器构建，代码检查和构建检查是&lt;a href=&quot;https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&quot;&gt;fuwari&lt;/a&gt;模版自带的无需修改。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;相关链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/zh-cn/guides/deploy/&quot;&gt;部署你的Astro站点&lt;/a&gt; https://docs.astro.build/zh-cn/guides/deploy/&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://twikoo.js.org/quick-start.html&quot;&gt;快速上手Twikoo &lt;/a&gt;  https://twikoo.js.org/quick-start.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&quot;&gt;fuwari博客主题模版&lt;/a&gt; https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/fuwai_zy&quot;&gt;ZyPLJ/fuwai_zy&lt;/a&gt; https://github.com/ZyPLJ/fuwai_zy&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>dotnet Minimal APIs实现动态注册端点</title><link>https://blog.pljzy.top/posts/dotnetminimalapis/dotnet-minimal-apis%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E6%B3%A8%E5%86%8C%E7%AB%AF%E7%82%B9/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/dotnetminimalapis/dotnet-minimal-apis%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E6%B3%A8%E5%86%8C%E7%AB%AF%E7%82%B9/</guid><description>dotnet Minimal APIs实现动态注册端点.</description><pubDate>Mon, 28 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;dotnet Minimal APIs实现动态注册端点&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;之前使用.Net的Minimal Apis框架开发了&lt;a href=&quot;https://github.com/ZyPLJ/SharpIcoWeb&quot;&gt;SharpIcoWeb&lt;/a&gt;图片转ico项目，也是初次使用这个最小Api框架，使用下来的感受就是小项目用起来非常舒服，很轻量。&lt;/p&gt;
&lt;p&gt;在之前的项目中，我都是手动去注册端点，比如我创建了一个端点类&lt;code&gt;IcoEndpoints&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class IcoEndpoints
{
    public static void MapIcoEndpoints(this WebApplication app)
    {
        var group = app.MapGroup(&quot;/api&quot;);
        group.MapGet(...)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我会在&lt;code&gt;Program.cs&lt;/code&gt;中注册这个端点类&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.MapIcoEndpoints();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么如果不想每个端点类都通过手动去注册，就可以使用动态注册的方法，动态注册的原理是通过反射和扩展方法来完成注册。&lt;/p&gt;
&lt;h2&gt;动态注册&lt;/h2&gt;
&lt;p&gt;本文就是使用基于接口的自动注册，还可以根据约定端点类命名、特性、标记去实现注册。&lt;/p&gt;
&lt;p&gt;文件层级结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SharpIcoWeb
├── Endpoints
│   ├── Internal
│   │   ├── EndpointExtensions.cs
│   │   ├── IEndpoint.cs
│   ├── IcoEndpoints.cs
│   ├── testEndpoints.cs
├── Program.cs
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;接口类&lt;/h3&gt;
&lt;p&gt;首先目录创建完成后，去创建&lt;code&gt;IEndpoint&lt;/code&gt;接口类，让每个端点类就去实现这个接口。&lt;/p&gt;
&lt;p&gt;注意：&lt;code&gt;static abstract&lt;/code&gt;接口成员需要&lt;code&gt;C# 11+ (.NET 7+)&lt;/code&gt; 支持&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IEndpoint
{ 
    static abstract void MapEndpoints(IEndpointRouteBuilder app);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;端点类&lt;/h3&gt;
&lt;p&gt;测试端点类&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class TestEndpoints : IEndpoint
{
    public static void MapEndpoints(IEndpointRouteBuilder app)
    {
        app.MapGet(&quot;/test&quot;, async (context) =&amp;gt;
        {
            await context.Response.WriteAsync(&quot;Hello, World!&quot;);
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;图片转Ico端点类&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class IcoEndpoints: IEndpoint
{
    public static void MapEndpoints(IEndpointRouteBuilder app)
    {
        var group = app.MapGroup(&quot;/api&quot;);

        // 上传图片文件并返回文件名
        group.MapPost(&quot;/uploadDownload&quot;, UploadDownload)
            .DisableAntiforgery();

        // 获取图片信息
        group.MapGet(&quot;/getImageInfo/{filename}&quot;, GetImageInfo);

        // 下载文件
        group.MapGet(&quot;/downloads/{fileName}&quot;, DowloadFile);

        // 上传图片文件并返回文件名和不同尺寸的ICO文件的ZIP文件
        group.MapPost(&quot;/uploadDownload/sizes&quot;, UploadDownloadSizes)
            .DisableAntiforgery();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;扩展方法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public static class EndpointExtensions
{
    public static void MapAllEndpoints(this IEndpointRouteBuilder app)
    {
        var endpointTypes = Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(t =&amp;gt; typeof(IEndpoint).IsAssignableFrom(t) &amp;amp;&amp;amp; !t.IsInterface &amp;amp;&amp;amp; !t.IsAbstract);

        foreach (var type in endpointTypes)
        {
            type.GetMethod(nameof(IEndpoint.MapEndpoints))?
            .Invoke(null, new object[] { app });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Program.cs&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;app.MapAllEndpoints();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成上述配置就可以实现自动注册端点类了。&lt;/p&gt;
&lt;h3&gt;测试访问&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@SharpIcoWeb_HostAddress = http://localhost:5235

### 上传文件并转换为ICO（带尺寸参数）
POST {{SharpIcoWeb_HostAddress}}/api/uploadDownload/sizes
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;1.png&quot;
Content-Type: image/png

&amp;lt; ./1.png
--WebAppBoundary
Content-Disposition: form-data; name=&quot;sizes&quot;

16,32,48,64,128

### 测试端点类访问
GET {{SharpIcoWeb_HostAddress}}/test

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到新建的test接口也是可以正常访问的。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;实现端点类的自动注册需要使用反射和扩展方法来完成。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;static abstract&lt;/code&gt;接口成员需要&lt;code&gt;C# 11+ (.NET 7+)&lt;/code&gt; 支持&lt;/p&gt;
&lt;p&gt;可以思考一下如何将服务和端点一起注册&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddScoped&amp;lt;IFileService, FileService&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>SharpIcoWeb开发记录篇</title><link>https://blog.pljzy.top/posts/sharpicoweb/sharpicoweb%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95%E7%AF%87/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/sharpicoweb/sharpicoweb%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95%E7%AF%87/</guid><description>SharpIcoWeb开发记录篇.</description><pubDate>Sun, 27 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;`&lt;/p&gt;
&lt;h1&gt;SharpIcoWeb开发记录篇&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;大佬用.NET 9.0开发了&lt;a href=&quot;https://github.com/star-plan/sharp-ico&quot;&gt;SharpIco&lt;/a&gt;轻量级图标生成工具，是一款控制台应用程序，支持AOT发布，非常方便。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✨ 功能特点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🖼️ 将PNG图像转换为多尺寸ICO图标&lt;/li&gt;
&lt;li&gt;🔍 支持生成包含自定义尺寸的ICO图标（最高支持1024×1024）&lt;/li&gt;
&lt;li&gt;🧐 检查ICO文件的内部结构和信息&lt;/li&gt;
&lt;li&gt;📏 准确识别并显示超大尺寸图标（如512×512、1024×1024）的实际尺寸&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;直达地址：&lt;a href=&quot;https://github.com/star-plan/sharp-ico&quot;&gt;https://github.com/star-plan/sharp-ico&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;现在互联网上应该有很多这类小工具或者网站，我也想部署把这个小工具部署成网站，当然不要和别人网站一模一样，所有后端我采用 &lt;code&gt;.NET Core Minimal API&lt;/code&gt;去开发。&lt;/p&gt;
&lt;p&gt;大佬开发的这款小工具可以直接在集成 &lt;code&gt;.NET Core&lt;/code&gt;中，所以我只需要写一个上传文件的接口就行了。用了 &lt;code&gt;.NET&lt;/code&gt;这么久，写接口一直用的是 &lt;code&gt;WebApi&lt;/code&gt;，这次尝试下 &lt;code&gt;Minimal Api&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;在线地址：&lt;a href=&quot;https://ico.pljzy.top&quot;&gt;https://ico.pljzy.top&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Minimal Api 简介&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;在使用 ASP.NET Core 生成快速 HTTP API 时，可以将最小 API 作为一种简化的方法。 可以使用最少的代码和配置生成完全正常运行的 REST 终结点。 跳过传统的基架，并通过流畅地声明 API 路由和操作来避免不必要的控制器。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;主要特点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;简洁的语法&lt;/strong&gt;：使用更少的代码定义 API 端点&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;减少样板代码&lt;/strong&gt;：不需要控制器类&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内置依赖注入&lt;/strong&gt;：简化服务配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路由和请求处理一体化&lt;/strong&gt;：直接在路由定义中处理请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;支持所有 ASP.NET Core 功能&lt;/strong&gt;：中间件、认证、授权等&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;架构概述&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;MiniAPI&lt;/code&gt;的核心架构包括以下几个关键组件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WebApplication：这是整个应用的入口点和宿主。它负责配置服务、中间件和路由。&lt;/li&gt;
&lt;li&gt;Endpoints：这些是API的终点，也就是处理特定HTTP请求的地方。&lt;/li&gt;
&lt;li&gt;Handlers：这些是实际处理请求并生成响应的函数。&lt;/li&gt;
&lt;li&gt;Middleware：这些组件在请求到达handler之前和之后处理请求。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;关键术语&lt;/h3&gt;
&lt;p&gt;在进行开发前，先了解下什么是 &lt;code&gt;Endpoints&lt;/code&gt;、&lt;code&gt;Handlers&lt;/code&gt;、&lt;code&gt;Middleware&lt;/code&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Endpoints（端点）：Endpoints是一个特定的URL路径，与一个HTTP方法相关联。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.MapGet(&quot;/hello&quot;, () =&amp;gt; &quot;Hello, World!&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Handlers（处理器）：Handlers是一个函数，它接收http请求并返回响应。在 &lt;code&gt;MiniAPIs&lt;/code&gt;中handler可以是一个简单的lambda表达式，也可以是一个单独定义的方法。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.MapGet(&quot;/users/{id}&quot;, (int id) =&amp;gt; $&quot;User ID: {id}&quot;);

&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Middleware（中间件）：与WebApi一样，MiniAPIs中也可以使用中间件，它们可以在请求到达handler之前执行操作，也可以在handler处理完请求后修改响应。例如，你可以使用中间件来处理身份验证、日志记录或异常处理。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;开发&lt;/h2&gt;
&lt;p&gt;了解完一些 &lt;code&gt;Minimal Api&lt;/code&gt;基础知识后，就可以开始开发了。首先创建 &lt;code&gt;MiniMal Api&lt;/code&gt;模版的 &lt;code&gt;.NET 9 Api&lt;/code&gt;程序。&lt;/p&gt;
&lt;p&gt;模版默认为创建一个示例接口，看到这个接口，看起来和 &lt;code&gt;WebApi&lt;/code&gt;写法差别不大，但是代码是直接写在 &lt;code&gt;Program.cs&lt;/code&gt;文件中,无需创建控制器。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;731d9fcb-67c3-438a-9142-2dbf19de76c6.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接下来开发一个上传文件的接口，然后调用大佬开发的工具就ok了。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;MiniAPI&lt;/code&gt;中也可以使用依赖注入，那么这里创建一个处理文件的服务，然后再注入这个服务在接口中使用。&lt;/p&gt;
&lt;h3&gt;项目结构&lt;/h3&gt;
&lt;p&gt;可以看到我的项目可以直接引用 &lt;code&gt;SharpIco&lt;/code&gt;工具，这里右键 &lt;code&gt;SharpIco&lt;/code&gt;编辑csproj文件将项目类型改为类库就可以直接调用了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;
        &amp;lt;!-- 改为生成库而不是控制台应用 --&amp;gt;
        &amp;lt;OutputType&amp;gt;Library&amp;lt;/OutputType&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;f442603a-fb8c-476d-a958-8d54ccbf88b1.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;IFileService接口&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public interface IFileService
{
    // 检查文件是否有效
    bool IsFileValid(IFormFile file);
    // 保存上传的文件
    Task&amp;lt;string&amp;gt; SaveUploadedFile(IFormFile file);
    // 创建临时目录
    string GetTempDirectory();
    // 读取文件到内存流
    Task&amp;lt;MemoryStream&amp;gt; ReadFileToMemoryAsync(string filePath);
    // 删除临时文件
    void DeleteFile(string tempFilePath);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;FileService类&lt;/h3&gt;
&lt;p&gt;这里使用了一个变量 &lt;code&gt;_tempFiles&lt;/code&gt;去记录上传的临时文件,然后实现IDisposable接口自动清理临时文件，确保上传的图片不会留存到硬盘里面。&lt;/p&gt;
&lt;p&gt;一开始我的设计思路就是在 &lt;code&gt;wooroot&lt;/code&gt;中去建立一个待转换和转换后的目录取处理图片，但转念一想，作为一款图片转ico的工具，还是不要留存图片好一点，所以才采用了临时目录这个办法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
public class FileService : IFileService, IDisposable
{
    private readonly List&amp;lt;string&amp;gt; _tempFiles = new();

    public string GetTempDirectory()
    {
        var tempDir = Path.Combine(Path.GetTempPath(), &quot;SharpIcoTemp&quot;);
        Directory.CreateDirectory(tempDir);
        return tempDir;
    }
  
    public bool IsFileValid(IFormFile file)
    {
        var allowedExtensions = new[] { &quot;.png&quot;, &quot;.jpg&quot;, &quot;.jpeg&quot; };
        var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
        return file.Length is &amp;gt; 0 and &amp;lt; 10 * 1024 * 1024 &amp;amp;&amp;amp; // 10MB
               allowedExtensions.Contains(extension);
    }

    // 保存上传的文件
    public async Task&amp;lt;string&amp;gt; SaveUploadedFile(IFormFile file)
    {
        var tempDir = GetTempDirectory();
        var tempFilePath = Path.Combine(tempDir, $&quot;{Guid.NewGuid()}{Path.GetExtension(file.FileName)}&quot;);
  
        await using var stream = new FileStream(tempFilePath, FileMode.Create);
        await file.CopyToAsync(stream);
  
        _tempFiles.Add(tempFilePath); // 记录待清理文件
        return tempFilePath;
    }
  
    // 安全读取文件到内存流
    public async Task&amp;lt;MemoryStream&amp;gt; ReadFileToMemoryAsync(string filePath)
    {
        var memoryStream = new MemoryStream();
        await using (var fileStream = File.OpenRead(filePath))
        {
            await fileStream.CopyToAsync(memoryStream);
        }
        memoryStream.Position = 0;
        return memoryStream;
    }

    public void DeleteFile(string tempFilePath)
    {
        if (File.Exists(tempFilePath))
            File.Delete(tempFilePath);
    }

    // 实现IDisposable接口自动清理
    public void Dispose()
    {
        foreach (var file in _tempFiles)
        {
            try
            {
                if (File.Exists(file))
                    File.Delete(file);
            }
            catch { /* 忽略删除异常 */ }
        }
        GC.SuppressFinalize(this);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Program类&lt;/h3&gt;
&lt;p&gt;服务写完后，接下来在配置类中注入服务并完成接口编写就大功告成了。&lt;/p&gt;
&lt;p&gt;注入服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddScoped&amp;lt;IFileService, FileService&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接口编写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.MapPost(&quot;/api/uploadDownload&quot;, async ([FromForm] IFormFile file,[FromForm] string? sizes,IFileService fileService, ILogger&amp;lt;Program&amp;gt; logger) =&amp;gt;
{
    try
    {
        // 验证输入
        if (!fileService.IsFileValid(file))
        {
            return Results.BadRequest(&quot;请上传有效文件,文件大小不能超过10MB&quot;);
        }

        // 保存临时文件
        var tempFilePath = await fileService.SaveUploadedFile(file);

        // 生成输出路径
        var outputPath = Path.Combine(fileService.GetTempDirectory(), $&quot;{Guid.NewGuid()}.ico&quot;);

        // 执行转换 处理大小参数
        var sizesArray = sizes?.Split(&apos;,&apos;).Select(int.Parse).ToArray();
        if (sizesArray is { Length: &amp;gt; 0 })
            IcoGenerator.GenerateIcon(tempFilePath, outputPath, sizesArray);
        else
            IcoGenerator.GenerateIcon(tempFilePath, outputPath);

        // 读取到内存
        var memoryStream = await fileService.ReadFileToMemoryAsync(outputPath);
  
        // 删除临时文件
        fileService.DeleteFile(outputPath);
  
        logger.LogInformation($&quot;{DateTime.UtcNow} 文件 {file.FileName} 转换成功&quot;);
  
        return Results.File(memoryStream, &quot;image/x-icon&quot;);
    }
    catch (Exception ex)
    {
        logger.LogError(ex, $&quot;{DateTime.UtcNow} 处理文件时发生错误&quot;);
        return Results.Problem(&quot;处理文件时发生错误&quot;);
    }
}).DisableAntiforgery();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;接口测试&lt;/h2&gt;
&lt;p&gt;这里直接使用模版自带的http文件进行测试，这个还是第一次使用，还折腾了挺久。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SharpIcoWeb.http&lt;/code&gt; 文件&lt;/p&gt;
&lt;p&gt;简单介绍下，第一个请求只上传了图片文件，未指定尺寸参数，后端接口会默认生成16,32,48,64,128,256,512,1024 尺寸的ico文件。&lt;/p&gt;
&lt;p&gt;第二个请求就是添加了尺寸参数的请求。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@SharpIcoWeb_HostAddress = http://localhost:5235

### 上传文件并转换为ICO（不带尺寸参数）
POST {{SharpIcoWeb_HostAddress}}/api/uploadDownload
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;1.png&quot;
Content-Type: image/png

&amp;lt; ./1.png
--WebAppBoundary--

### 上传文件并转换为ICO（带尺寸参数）
POST {{SharpIcoWeb_HostAddress}}/api/uploadDownload
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;1.png&quot;
Content-Type: image/png

&amp;lt; ./1.png
--WebAppBoundary
Content-Disposition: form-data; name=&quot;sizes&quot;

16,32,48,64,128
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;测试结果&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;837bb5ba-af7c-4a23-b364-55c1ac60737c.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;关键代码&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;IcoGenerator.GenerateIcon(tempFilePath, outputPath, sizesArray);&lt;/code&gt;这里是调用SharpIco工具提供的方法。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;app.MapPost().DisableAntiforgery()&lt;/code&gt;DisableAntiforgery作用是禁用 ASP.NET Core 的防伪造令牌验证。&lt;/p&gt;
&lt;h2&gt;相关链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SharpIco：https://github.com/star-plan/sharp-ico&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/SharpIcoWeb&quot;&gt;SharpIcoWeb&lt;/a&gt;：https://github.com/ZyPLJ/SharpIcoWeb&lt;/li&gt;
&lt;li&gt;最小API官方文档：&lt;a href=&quot;https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/minimal-apis/overview?view=aspnetcore-9.0&quot;&gt;https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/minimal-apis/overview?view=aspnetcore-9.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;最小API学习指南：&lt;a href=&quot;https://blog.csdn.net/xiaohucxy/article/details/140134927&quot;&gt;https://blog.csdn.net/xiaohucxy/article/details/140134&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>使用Cursor网页版优化SharpIcoWeb项目</title><link>https://blog.pljzy.top/posts/cursor/%E4%BD%BF%E7%94%A8cursor%E7%BD%91%E9%A1%B5%E7%89%88%E4%BC%98%E5%8C%96sharpicoweb%E9%A1%B9%E7%9B%AE/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/cursor/%E4%BD%BF%E7%94%A8cursor%E7%BD%91%E9%A1%B5%E7%89%88%E4%BC%98%E5%8C%96sharpicoweb%E9%A1%B9%E7%9B%AE/</guid><description>使用Cursor网页版优化SharpIcoWeb项目前言前些日子基于SharpIco开发了一个Web项目，更方便的进行图片转ico。之前在第三方网站使用 Glaude 3.7 Sonnet Think模型优化了一次前端页面，效果还挺不错。优化前：image.png优化后：image.png项目地址https://github.com/ZyPLJ/SharpIcoWebhttps</description><pubDate>Mon, 07 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;使用Cursor网页版优化SharpIcoWeb项目&lt;/h2&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;前些日子基于SharpIco开发了一个Web项目，更方便的进行图片转ico。&lt;/p&gt;
&lt;p&gt;之前在第三方网站使用 &lt;code&gt;Glaude 3.7 Sonnet Think&lt;/code&gt;模型优化了一次前端页面，效果还挺不错。&lt;/p&gt;
&lt;p&gt;优化前：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./fc32b1bac00c205b.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;优化后：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1e729ae5ad6d390f.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;项目地址&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;https://github.com/ZyPLJ/SharpIcoWeb&lt;/p&gt;
&lt;p&gt;https://github.com/star-plan/sharp-ico&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在线预览&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;https://ico.pljzy.top/&lt;/p&gt;
&lt;h2&gt;官网地址&lt;/h2&gt;
&lt;p&gt;https://cursor.com/agents&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./577ce74e7d1b7f83.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;开始使用&lt;/h2&gt;
&lt;p&gt;然后在网上冲浪的时候发现 &lt;code&gt;Cursor&lt;/code&gt;网页版可以直接访问，不需要挂梯子，我也是马上体验了一下， 我这里使用的是 &lt;code&gt;Claude 4 Sonnet MAX&lt;/code&gt; 模型。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./830650ee0bb7f0d8.png&quot; alt=&quot;image.png&quot; /&gt;image.png&lt;/p&gt;
&lt;p&gt;需要注意的是 &lt;code&gt;Cursor&lt;/code&gt;网页版需要绑定 &lt;code&gt;GitHub&lt;/code&gt;账号，绑定成功后，选择仓库和仓库分支就可以开始让ai帮你写代码了，我这里选择了SharpIcoWeb项目的 &lt;code&gt;master&lt;/code&gt;分支，让它帮我优化前端项目。&lt;/p&gt;
&lt;p&gt;提问后，他会在下方生成一个任务列表&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5571388e5863f999.png&quot; alt=&quot;image.png&quot; /&gt;image.png&lt;/p&gt;
&lt;p&gt;点击这个列表可以查看ai正在做什么操作，同时当任务结束后可以直接提 &lt;code&gt;PR&lt;/code&gt;合并到仓库分支中去，也可以选择不提交 &lt;code&gt;PR&lt;/code&gt;，他默认会在仓库建立一个分支。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./64ce2b1bc54f14e5.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;并且他还会生成一份总结报告&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./392e95aef43f8f9a.png&quot; alt=&quot;image.png&quot; /&gt;image.png&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;经过 &lt;code&gt;Curosr&lt;/code&gt;优化后，界面和功能都有很大的提升，而且它生成代码竟然没有报错，生成了2900行代码，经过测试可以直接运行，不过还是有小瑕疵需要自己手动调整。总体来说是一次非常不错的体验。&lt;/p&gt;
&lt;p&gt;bug：最后部署的时候发现，它给的分包策略有问题，会导致页面无法显示~&lt;/p&gt;
&lt;p&gt;下面是优化后的截图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./d98b17a53f272d47.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>基于SharpIco开发图片转ICO工具网站</title><link>https://blog.pljzy.top/posts/sharpico/%E5%9F%BA%E4%BA%8Esharpico%E5%BC%80%E5%8F%91%E5%9B%BE%E7%89%87%E8%BD%ACico%E5%B7%A5%E5%85%B7%E7%BD%91%E7%AB%99/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/sharpico/%E5%9F%BA%E4%BA%8Esharpico%E5%BC%80%E5%8F%91%E5%9B%BE%E7%89%87%E8%BD%ACico%E5%B7%A5%E5%85%B7%E7%BD%91%E7%AB%99/</guid><description>基于SharpIco开发图片转ICO工具网站SharpIcoWebLicense.NETStars📝项目介绍SharpIcoWeb是基于SharpIco开发的图片转ICO工具网站，支持上传png、jpg等图片转换为多尺寸的Ico图片文件。采用前后端分离技术。后端接口使用 .NET Minimal API开发，够轻量。📍项目地址https://github.com/ZyPLJ/</description><pubDate>Mon, 30 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;基于SharpIco开发图片转ICO工具网站&lt;/h1&gt;
&lt;h1&gt;SharpIcoWeb&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://camo.githubusercontent.com/bb4e5c0036a6a8cdbc59b38d44f09ad8f6dc722751dad34d3df5bf0ac61913c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565&quot;&gt;&lt;img src=&quot;https://camo.githubusercontent.com/bb4e5c0036a6a8cdbc59b38d44f09ad8f6dc722751dad34d3df5bf0ac61913c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565&quot; alt=&quot;License&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/7732c145abc7fb05a8373d4d161318970723f355ddd1d080a3fbef3c6941cd0f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2e4e45542d392e302d707572706c65&quot; alt=&quot;.NET&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/github/stars/ZyPLJ/SharpIcoWeb?color=gold&amp;amp;style=for-the-badge&quot; alt=&quot;Stars&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;📝项目介绍&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ZyPLJ/SharpIcoWeb&quot;&gt;SharpIcoWeb&lt;/a&gt;是基于&lt;a href=&quot;https://github.com/star-plan/sharp-ico&quot;&gt;SharpIco&lt;/a&gt;开发的图片转ICO工具网站，支持上传png、jpg等图片转换为多尺寸的Ico图片文件。采用前后端分离技术。&lt;/p&gt;
&lt;p&gt;后端接口使用 &lt;code&gt;.NET Minimal API&lt;/code&gt;开发，够轻量。&lt;/p&gt;
&lt;h2&gt;📍项目地址&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;https://github.com/ZyPLJ/SharpIcoWeb&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;🎯 应用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;网站Favicon 🌐&lt;/li&gt;
&lt;li&gt;软件图标 🖥️&lt;/li&gt;
&lt;li&gt;个性化文件夹标识 📂&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&quot;icon&quot; type=&quot;image/x-icon&quot; href=&quot;/logo.ico&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;✨核心技术&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;⚡&lt;/strong&gt; &lt;strong&gt;Vite+Vue+Element-Plus&lt;/strong&gt; &lt;strong&gt;极速的开发服务器和高效的生产构建&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;🗂️ → ❌&lt;/strong&gt; &lt;strong&gt;纯文件操作（无需SQLite/MySQL）&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🏗️.NET 9 MiniAPI 轻量级API开发，处理图像转换业务逻辑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;🖼️&lt;/strong&gt; &lt;strong&gt;后端使用的强大图像处理库，实现PNG/JPG转ICO&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🐳&lt;/strong&gt; &lt;strong&gt;可容器化（Docker 支持）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;📱 + 💻&lt;/strong&gt; &lt;strong&gt;响应式设计（适配移动端）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;✅后续更新&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] 不同尺寸ICO,可分别生成ICO文件。&lt;/li&gt;
&lt;li&gt;[ ] 前端显示ICO文件图标数量数据、大小、偏移等数据。&lt;/li&gt;
&lt;li&gt;[ ] 批量转换功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;🚀快速开始&lt;/h2&gt;
&lt;h3&gt;Docker部署&lt;/h3&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;注意注释部分配置可能需要根据实际情况修改&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;h4&gt;Docker CLI&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;docker-compose up --build -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;default.conf&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       5173; # 配置端口
    server_name  0.0.0.0; # 修改为docker服务宿主机的ip 
  
    # 设置允许的最大请求体大小（例如 100MB）
    client_max_body_size 100M;
 
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
  
    location /api {
        proxy_pass http://backend:5235;  # Docker 内部网络
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Docker Compose&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.8&apos;

services:
  frontend:
    build:
      context: ./sharp-ico-vue   # 指向前端目录
      dockerfile: Dockerfile
    ports:
      - &quot;5173:5173&quot;               # 前端映射到宿主机的5173端口
    depends_on:
      - backend

  backend:
    build:
      context: .    # 指向后端目录
      dockerfile: Dockerfile
    ports:
      - &quot;5235:5235&quot;            # 后端端口
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;手动部署&lt;/h3&gt;
&lt;h4&gt;clone&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;git clone https://github.com/ZyPLJ/SharpIcoWeb.git&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;后端运行&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cd SharpIcoWeb

dotnet build -c Release

dotnet run
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;前端运行&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cd ..

cd sharp-ico-vue

npm install

npm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;👀如何使用&lt;/h2&gt;
&lt;p&gt;前后端项目运行或部署后，打开运行后网址。&lt;/p&gt;
&lt;p&gt;选择需要生成的ICO图表尺寸，可多选&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;82586b88-2c72-47db-8c42-4b90d7b43235.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上传图片文件，点击转换。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;77b11313-ff66-4d3f-924d-f31c0c16b349.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;🛠 开发指南&lt;/h2&gt;
&lt;h3&gt;项目结构&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sharp-ico/
├── SharpIco/               # 图标转换类库  
│   ├── SharpIco.csproj
├── SharpIcoWeb/            # 后端Api项目
│   ├── SharpIcoWeb.csproj
├── sharp-ico-vue           # 前端项目
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;开发环境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;.Net 9&lt;/li&gt;
&lt;li&gt;Node.js 20.19+&lt;/li&gt;
&lt;li&gt;Vue3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;运行项目&lt;/h3&gt;
&lt;h4&gt;后端&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;dotnet build -c Release

dotnet run
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;前端&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;npm install

npm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;相关链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/star-plan/sharp-ico&quot;&gt;SharpIco&lt;/a&gt; 🌟 Star if useful!&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/SharpIcoWeb&quot;&gt;SharpIcoWeb&lt;/a&gt;  🌟 Star if useful!&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>程序猿等于装机猿吗？</title><link>https://blog.pljzy.top/posts/%E7%A8%8B%E5%BA%8F%E7%8C%BF%E7%AD%89%E4%BA%8E%E8%A3%85%E6%9C%BA%E7%8C%BF%E5%90%97/%E7%A8%8B%E5%BA%8F%E7%8C%BF%E7%AD%89%E4%BA%8E%E8%A3%85%E6%9C%BA%E7%8C%BF%E5%90%97/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E7%A8%8B%E5%BA%8F%E7%8C%BF%E7%AD%89%E4%BA%8E%E8%A3%85%E6%9C%BA%E7%8C%BF%E5%90%97/%E7%A8%8B%E5%BA%8F%E7%8C%BF%E7%AD%89%E4%BA%8E%E8%A3%85%E6%9C%BA%E7%8C%BF%E5%90%97/</guid><description>程序猿等于装机猿吗？🧑‍💻前言还记得当时刚入大学时，学的计算机专业，身边的长辈就会开玩笑地说：“计算机专业，那你肯定会修电脑”，每次听到这些话，我都会笑着回答：”会一点点“。</description><pubDate>Sat, 21 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;程序猿等于装机猿吗？&lt;/h1&gt;
&lt;h2&gt;🧑‍💻前言&lt;/h2&gt;
&lt;p&gt;还记得当时刚入大学时，学的计算机专业，身边的长辈就会开玩笑地说：“计算机专业，那你肯定会修电脑”，每次听到这些话，我都会笑着回答：”会一点点“。但我清楚的知道，除了简单的装系统、装硬件，并不会修电脑。至今还是有很多人对程序猿有误解，认为程序猿一定会修电脑或者装电脑，但其实不然，我身边计算机专业的室友或者朋友，很少有会装机的，更别说修电脑了。&lt;/p&gt;
&lt;h2&gt;🖊为什么我会写这么一篇文章呢？&lt;/h2&gt;
&lt;p&gt;因为莫名其妙中枪了，我在&lt;code&gt;2024年10月16日&lt;/code&gt;发布了一篇文章，主要描述自主装机如何选择配件的一篇文章。&lt;/p&gt;
&lt;p&gt;这篇文章还是有很多网络喷子，我总结了一下如下一点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为什么要用水冷，水冷漏液你不知道吗？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于风冷、水冷的选择，我也不想多说了，萝卜青菜各有所爱，解释再多也没用，就好比你活在这个&lt;code&gt;地球online&lt;/code&gt;，摆脱不了生老病死、天灾人祸，与其和别人争论，不如坚定自己的选择。&lt;/p&gt;
&lt;p&gt;当然对于喷子说我用水冷并不会让我写一篇文章去怼他。就在这周，出现了一位，我称之为bug的逆天存在。他的发言直击我脆弱的心灵，仿佛我整个人都被他看穿了，让我感到深深的后怕，世间竟有如此之人。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;话不多说看图：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图1：我一开始看到这个评论以为是简单的喷我，也不知道出于何种理由说出这种话，微星迫击炮超频&lt;code&gt;7500F&lt;/code&gt;有什么问题吗，很显然他不是因为这个喷我，然后我在屏蔽的留言里面又看到了他的留言（微信自动屏蔽了），如下：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;扎心了，短短的几句话还真让他说到点子上了。&lt;/p&gt;
&lt;p&gt;奴工码农这个标签好像真的很适合我，回想起曾经无数个下班的晚上，被客户艾特，打开电脑处理问题的日子，确实很像奴工，我无话可说。&lt;/p&gt;
&lt;p&gt;穷逼这个标签好像也很适合我，从24年毕业，实习+转正工作也快2年了，身上的存款不见涨、工资不见涨，都说程序猿工资高，但对于我这个一无背景二无学历三无实力的人来说，高薪好像遥不可及。&lt;/p&gt;
&lt;p&gt;这些标签我都不在意，但是他说&lt;code&gt;穷逼还装什么机&lt;/code&gt;，我不能忍受这句话，从一个国人的口中说出！&lt;/p&gt;
&lt;p&gt;一个人最终能达到什么资产，也许生来注定，也许能够逆天改命，任何人都不应该轻易的否定别人，何况素不相识。也许你很有钱，每天挥金如土，纸醉金迷，这是你的人生，没人干涉。同样有人食不果腹，解决上一顿饿下一顿，他也有他的人生，你无端端的指责他，有胳膊有腿，怎么会没钱？当然我这是打个比喻，这样的人生有什么意义？网络上的喷子活在世界上的意义是什么？&lt;/p&gt;
&lt;p&gt;人穷志不穷，我对未来抱有无限的希望，不像某些人躲在阴暗的角落，像病毒一样到处散播。&lt;/p&gt;
&lt;p&gt;我不知道这哥们受了什么刺激，我翻遍了我的留言区，并没有惹他，看样子是乱咬人。&lt;/p&gt;
&lt;p&gt;先富带后富，当我看到最近的蒙古格格、天价耳环事件，心里不禁在想，人与人生来便有差距，努力做自己就行，人生不过短短3万天，活好每一天。&lt;/p&gt;
&lt;p&gt;以上便是我的回复，与其说是回复，说是发泄更好，好在现在是法治社会，不像美利坚。。。。。。&lt;/p&gt;
&lt;h2&gt;🖥聊聊装机&lt;/h2&gt;
&lt;p&gt;自己组装一台电脑，也算是了却小时候的愿望，当时和朋友们打&lt;code&gt;lol&lt;/code&gt;（英雄联盟），家里的电脑配置什么的记不清了，只知道玩的时候会闪退（内存不足），当时英雄联盟对于挂机玩家有惩罚，挂机了要开下一把可能要等10、20分钟，无赖只能让朋友们先开一把，自己在哪里等着惩罚时间过去，回想起来还真是怀恋。&lt;/p&gt;
&lt;p&gt;所以当我大学毕业踏入社会，挣到人生的第一桶金就给自己装了一台机器，终于打英雄联盟不卡了，但是我自己却卡了😥&lt;/p&gt;
&lt;p&gt;第一次了解到一台电脑需要哪些配件，还是大学第一躺专业课的时候才知道，当时老师拿着一台主机，告诉我们一台电脑需要主板、CPU、电源、内存、硬盘、散热器才能运行。后面因为专业需要，我也是买了一台笔记本，那时我才知道玩游戏需要搭配独立显卡的笔记本才行，不然会很卡。&lt;/p&gt;
&lt;p&gt;到如今我也是能够自己从选择配件到组装配件最好装上系统点亮电脑的人了。&lt;/p&gt;
&lt;p&gt;回归到文章标题，程序员一定会装机吗？很显然不是，我如果不是为了完成自己儿时的心愿，我也不会自己去组装一台电脑。&lt;/p&gt;
&lt;p&gt;装机不难，装系统也不难，世间无难事只怕有心人。&lt;/p&gt;
&lt;p&gt;最后我自己组装的电脑配置和效果图还是放出来一下，很多人没有看过我之前的文章，配置不高，&lt;code&gt;4060+7500F&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;🔗其他链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&quot;&gt;ZY知识库 · ZY - 小白装机-选配篇&lt;/a&gt; https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/4030f7f731ddccd2.html&quot;&gt;ZY知识库 · ZY - 小白装机-装机篇&lt;/a&gt; https://pljzy.top/blog/post/4030f7f731ddccd2.html&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SqlServer 中行转列PIVOT函数用法</title><link>https://blog.pljzy.top/posts/pivot/sqlserver-%E4%B8%AD%E8%A1%8C%E8%BD%AC%E5%88%97pivot%E5%87%BD%E6%95%B0%E7%94%A8%E6%B3%95/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/pivot/sqlserver-%E4%B8%AD%E8%A1%8C%E8%BD%AC%E5%88%97pivot%E5%87%BD%E6%95%B0%E7%94%A8%E6%B3%95/</guid><description>SqlServer 中行转列PIVOT函数用法前言最近在面试的时候，碰到了手写sql的题目，这让我这个面向AI的程序员着实难看。只见我面露难色，绞尽脑汁的情况下，终于还是放弃了。这道题目不难，但是由于平时几乎没有遇到行转列的情况，导致在手写时忘记了PIVOT函数怎么使用😩。</description><pubDate>Thu, 20 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;SqlServer 中行转列PIVOT函数用法&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;最近在面试的时候，碰到了手写&lt;code&gt;sql&lt;/code&gt;的题目，这让我这个面向AI的程序员着实难看。只见我面露难色，绞尽脑汁的情况下，终于还是放弃了。&lt;/p&gt;
&lt;p&gt;这道题目不难，但是由于平时几乎没有遇到行转列的情况，导致在手写时忘记了&lt;code&gt;PIVOT&lt;/code&gt;函数怎么使用😩。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;font color=&apos;gray&apos; size=&apos;2&apos;&amp;gt;面试准备不充分给自己找借口，菜就多练，不会写就别写。&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;题目描述&lt;/h2&gt;
&lt;p&gt;下面请看题：&lt;/p&gt;
&lt;p&gt;假设有以下表 &lt;code&gt;EmpCanlendar&lt;/code&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;CalendarDate&lt;/th&gt;
&lt;th&gt;ClassName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;2005-05-01&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;2005-05-02&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;2005-05-03&lt;/td&gt;
&lt;td&gt;夜班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;李四&lt;/td&gt;
&lt;td&gt;2005-05-01&lt;/td&gt;
&lt;td&gt;夜班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;李四&lt;/td&gt;
&lt;td&gt;2005-05-02&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;输出结果：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;D20050501&lt;/th&gt;
&lt;th&gt;D20050502&lt;/th&gt;
&lt;th&gt;D20050503&lt;/th&gt;
&lt;th&gt;D20050504&lt;/th&gt;
&lt;th&gt;D20050505&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;张三&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;夜班&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;李四&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;日班&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;王五&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;夜班&lt;/td&gt;
&lt;td&gt;夜班&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;code&gt;PIVOT&lt;/code&gt;函数简单介绍&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;PIVOT&lt;/code&gt; 是 SQL Server 中的一种功能，用于将行数据转换为列数据（即行转列）。它通常用于将某一列的唯一值作为新列，并将对应的值填充到这些新列中。&lt;code&gt;PIVOT&lt;/code&gt; 是数据透视表的一种实现方式，非常适合用于统计和报表场景。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;PIVOT&lt;/code&gt; 的基本语法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    [非透视列],
    [透视值1], [透视值2], ..., [透视值N]
FROM 
    (
        -- 子查询：提供原始数据
        SELECT [非透视列], [透视列], [值列]
        FROM 表名
    ) AS 源表
PIVOT 
(
    聚合函数(值列) -- 例如 SUM、COUNT、MAX 等
    FOR 透视列 IN ([透视值1], [透视值2], ..., [透视值N])
) AS 透视表
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;参数&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;非透视列&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;不需要转换的列，这些列的值将作为结果表的行标识。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透视列&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;需要转换为新列的列。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;值列&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;需要填充到新列中的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;聚合函数&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;对值列进行聚合操作，例如 &lt;code&gt;SUM&lt;/code&gt;、&lt;code&gt;COUNT&lt;/code&gt;、&lt;code&gt;MAX&lt;/code&gt; 等。&lt;/li&gt;
&lt;li&gt;如果值列不需要聚合，可以使用 &lt;code&gt;MAX&lt;/code&gt; 或 &lt;code&gt;MIN&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透视值&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;透视列中的唯一值，这些值将成为新列的名称。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;解题&lt;/h2&gt;
&lt;h3&gt;测试数据准备&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE #EmpCanlendar(
	[Name] NVARCHAR(20) NULL,
	CalendarDate DATETIME NULL,
	ClassName NVARCHAR(10) NULL,
)
INSERT INTO #EmpCanlendar(Name,CalendarDate,ClassName)
VALUES
(&apos;张三&apos;,&apos;2005-05-01&apos;,&apos;日班&apos;),
(&apos;张三&apos;,&apos;2005-05-02&apos;,&apos;日班&apos;),
(&apos;张三&apos;,&apos;2005-05-03&apos;,&apos;日班&apos;),
(&apos;张三&apos;,&apos;2005-05-04&apos;,&apos;日班&apos;),
(&apos;张三&apos;,&apos;2005-05-05&apos;,&apos;夜班&apos;),
(&apos;李四&apos;,&apos;2005-05-01&apos;,&apos;日班&apos;),
(&apos;李四&apos;,&apos;2005-05-02&apos;,&apos;日班&apos;),
(&apos;李四&apos;,&apos;2005-05-03&apos;,&apos;日班&apos;),
(&apos;王五&apos;,&apos;2005-05-02&apos;,&apos;夜班&apos;),
(&apos;王五&apos;,&apos;2005-05-03&apos;,&apos;夜班&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;非动态&lt;code&gt;sql&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;适用于日期范围固定，或者日期列较少的情况&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
    Name,
    [2005-05-01] AS D20050501,
    [2005-05-02] AS D20050502,
    [2005-05-03] AS D20050503,
    [2005-05-04] AS D20050504,
    [2005-05-05] AS D20050505
FROM 
(
    SELECT 
        Name, 
        CalendarDate, 
        ClassName
    FROM 
        #EmpCanlendar
) AS SourceTable
PIVOT
(
    MAX(ClassName)
    FOR CalendarDate IN ([2005-05-01], [2005-05-02], [2005-05-03], [2005-05-04], [2005-05-05])
) AS PivotTable;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;动态&lt;code&gt;sql&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;适用于日期范围不固定，或者日期列较多的情况&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SQL Server 2017&lt;/strong&gt;及以上版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 声明变量存储动态 SQL
DECLARE @sql NVARCHAR(MAX) = &apos;&apos;
DECLARE @columns NVARCHAR(MAX) = &apos;&apos;

SELECT @columns = STRING_AGG(QUOTENAME(&apos;D&apos; + CONVERT(VARCHAR, DistinctDates.CalendarDate, 112)), &apos;,&apos;)
FROM (SELECT DISTINCT CalendarDate FROM #EmpCanlendar) AS DistinctDates

SET @sql = &apos;
	SELECT 
		Name , &apos; + @columns +&apos;
	FROM
	(
		SELECT 
			Name,
			&apos;&apos;D&apos;&apos; + CONVERT(VARCHAR,CalendarDate, 112) CalendarDate,
			ClassName
		FROM
			#EmpCanlendar
	) AS SourceTable
	PIVOT
	(
		MAX(ClassName)
		FOR CalendarDate IN (&apos;+ @columns +&apos;)
	) AS PivotTable;
&apos;
PRINT @sql
EXEC sp_executesql @sql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;SQL Server 2017&lt;/strong&gt;以下版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT @columns = STUFF(
    (
        SELECT DISTINCT &apos;,&apos; + QUOTENAME(&apos;D&apos;+ CONVERT(VARCHAR, CalendarDate, 112))
        FROM #EmpCanlendar
        FOR XML PATH(&apos;&apos;)
    ),1, 1, &apos;&apos;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;查询结果：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;扩展&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;STUFF&lt;/code&gt;函数简单介绍&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;STUFF&lt;/code&gt; 是 SQL Server 中的一个字符串函数，用于删除字符串的一部分并在指定位置插入新的子字符串。它的主要作用是修改字符串的内容，通常用于拼接或替换字符串中的某些部分。&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;STUFF&lt;/code&gt; 函数的语法：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;STUFF(原始字符串, 开始位置, 删除长度, 新子字符串)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;参数&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;原始字符串&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;需要修改的字符串。&lt;/li&gt;
&lt;li&gt;可以是字符型（&lt;code&gt;CHAR&lt;/code&gt;、&lt;code&gt;VARCHAR&lt;/code&gt;、&lt;code&gt;NVARCHAR&lt;/code&gt; 等）的列、变量或表达式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开始位置&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;指定从原始字符串的哪个位置开始删除和插入。&lt;/li&gt;
&lt;li&gt;位置从 1 开始计数。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;删除长度&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;指定要删除的字符数。&lt;/li&gt;
&lt;li&gt;如果为 0，则不删除任何字符，仅插入新子字符串。&lt;/li&gt;
&lt;li&gt;如果大于原始字符串的长度，则从开始位置删除到字符串末尾。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新子字符串&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;要插入的新字符串。&lt;/li&gt;
&lt;li&gt;如果为空字符串 &lt;code&gt;&apos;&apos;&lt;/code&gt;，则仅删除字符，不插入新内容。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;可用于&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;删除字符&lt;/strong&gt;：从指定位置开始删除一定长度的字符。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;插入字符&lt;/strong&gt;：在删除字符的位置插入新的子字符串。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;替换字符&lt;/strong&gt;：通过删除和插入操作，可以实现字符串的替换。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;STRING_AGG&lt;/code&gt;函数简单介绍：&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;STRING_AGG&lt;/code&gt; 是 SQL Server 2017 及更高版本中引入的一个聚合函数，用于将一组字符串值连接成一个单独的字符串，并使用指定的分隔符分隔每个值。它是 SQL Server 中处理字符串拼接的强大工具，特别适合将多行数据合并为一个字符串。&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;STRING_AGG&lt;/code&gt; 的基本语法&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;STRING_AGG(表达式, 分隔符)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;参数&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;表达式&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;需要拼接的字符串列或表达式。&lt;/li&gt;
&lt;li&gt;可以是 &lt;code&gt;VARCHAR&lt;/code&gt;、&lt;code&gt;NVARCHAR&lt;/code&gt;、&lt;code&gt;CHAR&lt;/code&gt; 等字符类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分隔符&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;用于分隔每个字符串值的字符或字符串。&lt;/li&gt;
&lt;li&gt;可以是任意字符串，例如 &lt;code&gt;,&lt;/code&gt;、&lt;code&gt;;&lt;/code&gt;、&lt;code&gt;-&lt;/code&gt; 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;code&gt;QUOTENAME&lt;/code&gt;函数简单介绍&lt;/h3&gt;
&lt;p&gt;在SQL Server中，&lt;code&gt;QUOTENAME()&lt;/code&gt;函数用于将一个标识符（如表名、列名等）包围在方括号中，以防止引起语法错误或与关键字冲突。&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;QUOTENAME&lt;/code&gt;函数的语法：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;QUOTENAME ( &apos;character_string&apos; [ , &apos;quote_character&apos; ] )
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;参数&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;&apos;character_string&apos;&lt;/code&gt;：是要包围的标识符，可以是表名、列名等&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&apos;quote_character&apos;&lt;/code&gt;：是可选参数，用于指定用于包围标识符的字符，默认为方括号（[ ]）。&lt;/p&gt;
&lt;h2&gt;参考链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;深入浅出：&lt;code&gt;SQL Server&lt;/code&gt; 中的 &lt;code&gt;PIVOT&lt;/code&gt; 与 &lt;code&gt;UNPIVOT&lt;/code&gt; 用法详解：https://blog.csdn.net/houbincarson/article/details/145483265&lt;/li&gt;
&lt;li&gt;&lt;code&gt;QUOTENAME (Transact-SQL)&lt;/code&gt; ：https://learn.microsoft.com/zh-cn/sql/t-sql/functions/quotename-transact-sql?view=sql-server-ver16&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SQL Server&lt;/code&gt;中&lt;code&gt;quotename(&lt;/code&gt;)函数怎么使用：https://www.cnblogs.com/luyj00436/p/18453443&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>关于我用Claude 3.7 Sonnet模型直接生成小程序</title><link>https://blog.pljzy.top/posts/claude-37-sonnet/%E5%85%B3%E4%BA%8E%E6%88%91%E7%94%A8claude-37-sonnet%E6%A8%A1%E5%9E%8B%E7%9B%B4%E6%8E%A5%E7%94%9F%E6%88%90%E5%B0%8F%E7%A8%8B%E5%BA%8F/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/claude-37-sonnet/%E5%85%B3%E4%BA%8E%E6%88%91%E7%94%A8claude-37-sonnet%E6%A8%A1%E5%9E%8B%E7%9B%B4%E6%8E%A5%E7%94%9F%E6%88%90%E5%B0%8F%E7%A8%8B%E5%BA%8F/</guid><description>关于我用Claude 3.7 Sonnet模型直接生成小程序前言最近AI一直是很火的话题，Deepseek也是一夜爆火，但是实际使用下来发现Deepseek好像和其他大模型一样，并没有什么厉害之处，而且官网经常服务器繁忙。</description><pubDate>Fri, 07 Mar 2025 21:28:06 GMT</pubDate><content:encoded>&lt;h1&gt;关于我用Claude 3.7 Sonnet模型直接生成小程序&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;最近AI一直是很火的话题，&lt;code&gt;Deepseek&lt;/code&gt;也是一夜爆火，但是实际使用下来发现&lt;code&gt;Deepseek&lt;/code&gt;好像和其他大模型一样，并没有什么厉害之处，而且官网经常服务器繁忙。&lt;/p&gt;
&lt;p&gt;当我使用&lt;code&gt;Claude 3.7 Sonnet&lt;/code&gt;之后才算是被惊讶到，在此之前我也是在微信公众号看到很多文章是&lt;code&gt;Claude 3.7&lt;/code&gt;很厉害，我本着不信的原则去使用了一下，发现代码能力肯定是强于&lt;code&gt;Deepseek&lt;/code&gt;的。为什么我这么肯定呢，请看下文介绍。&lt;/p&gt;
&lt;h1&gt;AI提示词&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;我想开发一个记账小程序，现在需要输出原型图（带颜色），请通过以下方式帮我完成小程序所有原型图片的设计。1、思考用户需要记账小程序实现哪些功能2、作为产品经理规划这些界面3、作为设计师思考这些原型界面的设计4、使用html在一个界面上生成所有的原型界面，可以使用FontAwesome等开源图标库，让原型显得更精美和接近真实我希望这些界面是需要能直接拿去进行开发的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;DeepSeek\Claude 3.5\Claude 3.7&lt;/code&gt;提示词相同，但是之前问的时候没有加上**（带颜色）**所以 &lt;code&gt;DeepSeek\Claude 3.5&lt;/code&gt;是原型图是没颜色的。&lt;/p&gt;
&lt;h1&gt;&lt;code&gt;DeepSeek&lt;/code&gt;生成记账程序原型图&lt;/h1&gt;
&lt;p&gt;这是用&lt;code&gt;DeekSeek&lt;/code&gt;生成出来的，可以说和我自己写的简直一模一样，当然我这里没有硬黑，不过当时还有一段小插曲，提示服务不可用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Claude 3.5&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Claude 3.5&lt;/code&gt;生成出来的算不上很惊艳，但是至少看得过去。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Claude 3.7&lt;/h1&gt;
&lt;h2&gt;第一版&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Claude 3.7&lt;/code&gt;生成的第一版明显比3.5好看很多，就算是去掉颜色也比3.5和&lt;code&gt;Deepseek&lt;/code&gt;强！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第二版&lt;/h2&gt;
&lt;p&gt;在第一版的基础上我加上了现代化风格，提示词如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上次让你生成的 ‘我想开发一个记账小程序，现在需要输出原型图（带颜色），请通过以下方式帮我完成小程序所有原型图片的设计。1、思考用户需要记账小程序实现哪些功能2、作为产品经理规划这些界面3、作为设计师思考这些原型界面的设计4、使用html在一个界面上生成所有的原型界面，可以使用FontAwesome等开源图标库，让原型显得更精美和接近真实我希望这些界面是需要能直接拿去进行开发的’的html原型图，在不改变功能的情况下修改页面风格，修改为现代风。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以说这个效果已经是非常惊讶了，并且生成出来的不是图片而是&lt;code&gt;html&lt;/code&gt;代码，但是我明明说的小程序，为什么会让他生成&lt;code&gt;html&lt;/code&gt;代码呢，因为生成&lt;code&gt;html&lt;/code&gt;可以直观的看到效果，但是肯定是不能直接在小程序中使用的，那么继续让&lt;code&gt;Claude 3.7&lt;/code&gt;优化。&lt;/p&gt;
&lt;p&gt;提示词：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上次叫你用html生成了原型界面，但是这是个记账小程序，对于微信小程序来说html并不行，所以我想使用uniapp来实现小程序开发，根据昨天的html界面，你能将他转换成uniapp+vue的页面吗？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最好在小程序运行的效果如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到和原型图几乎一样，不过眼尖的人可以看到头部的信息是重叠的，你可以继续选择问他让他优化一下，这是因为他自定义的头部和小程序头部冲突了，我因为略懂小程序知识也就没往下问，手动将小程序头部修改一下就可以了。&lt;/p&gt;
&lt;h2&gt;最终效果图&lt;/h2&gt;
&lt;p&gt;这里只放了部分截图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;结尾&lt;/h1&gt;
&lt;p&gt;不得不说现在&lt;code&gt;Ai&lt;/code&gt;是越来越厉害，虽然我只生成了小程序的静态页面，但我如果继续问下去，让&lt;code&gt;Ai&lt;/code&gt;生成后端我觉得也是可行的，有兴趣的朋友可以自己去试试。&lt;/p&gt;
&lt;p&gt;那么如何使用&lt;code&gt;Claude 3.7&lt;/code&gt;，使用3.7目前来说是需要消费的，但是可以通过邀请朋友注册享受体验资格，邀请得越多提问的次数越多，感兴趣的可以私信我~，顺便帮博主拉拉次数。&lt;/p&gt;
</content:encoded></item><item><title>解决uniapp使用Font Awesome图标无法显示问题</title><link>https://blog.pljzy.top/posts/uniapp/%E8%A7%A3%E5%86%B3uniapp%E4%BD%BF%E7%94%A8font-awesome%E5%9B%BE%E6%A0%87%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/uniapp/%E8%A7%A3%E5%86%B3uniapp%E4%BD%BF%E7%94%A8font-awesome%E5%9B%BE%E6%A0%87%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98/</guid><description>解决uniapp使用Font Awesome图标无法显示问题前言在平时的Vue项目中使用Font Awesome图标时很方便，只需要引入即可，但是在小程序里面使用却无法显示，并且提示[渲染层网络层错误]。</description><pubDate>Thu, 06 Mar 2025 21:15:49 GMT</pubDate><content:encoded>&lt;h1&gt;解决&lt;code&gt;uniapp&lt;/code&gt;使用&lt;code&gt;Font Awesome&lt;/code&gt;图标无法显示问题&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;在平时的&lt;code&gt;Vue&lt;/code&gt;项目中使用&lt;code&gt;Font Awesome&lt;/code&gt;图标时很方便，只需要引入即可，但是在小程序里面使用却无法显示，并且提示&amp;lt;font color=&apos;red&apos;&amp;gt;[渲染层网络层错误]&amp;lt;/font&amp;gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Font Awesome下载 &lt;a href=&quot;https://fontawesome.com/download&quot;&gt;Download Font Awesome Free or Pro | Font Awesome&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;原因&lt;/h1&gt;
&lt;p&gt;导致报错的原因：小程序无法解析字体文件&lt;/p&gt;
&lt;p&gt;在下载的&lt;code&gt;Font Awesome &lt;/code&gt; &lt;code&gt;css&lt;/code&gt;文件中使用字体是如下方式导入的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这种方式，小程序无法识别。&lt;/p&gt;
&lt;h1&gt;解决方案&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;fontawesome-free-6.7.2-web\webfonts&lt;/code&gt;文件夹下的字体文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我们只需要将字体文件转换为&lt;code&gt;base64&lt;/code&gt;文件即可&lt;/p&gt;
&lt;p&gt;打开这个网站：&lt;a href=&quot;https://transfonter.org/&quot;&gt;https://transfonter.org/ &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;注意事项：ttf字体文件勾选TTF，woff2字体文件勾选WOFF2&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;第四步点击后会生成一个压缩包，下载压缩包，将&lt;code&gt;stylesheet.css&lt;/code&gt;文件中的&lt;code&gt;src&lt;/code&gt; 中的&lt;code&gt;url&lt;/code&gt;替换&lt;code&gt;Font Awesome&lt;/code&gt;的all.css文件中对应的字体文件引入，具体看图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;替换后应是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有好几个字体文件都需要一一替换！！！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;建议：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;base64&lt;/code&gt;很长，推荐从&lt;code&gt;stylesheet.css&lt;/code&gt;文件复制的时候，只复制&lt;code&gt;url&lt;/code&gt;中单引号的内容去&lt;code&gt;all.css&lt;/code&gt;替换&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;url(&apos;base64.....&apos;) format(&quot;woff2&quot;)
url(&quot;../webfonts/fa-brands-400.woff2&quot;) format(&quot;woff2&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;结尾&lt;/h1&gt;
&lt;p&gt;记得在&lt;code&gt;App.vue&lt;/code&gt;中引入一下&lt;code&gt;css&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;style&amp;gt;
/* 导入字体图标 替换成你的自己路径 */  
@import &apos;/src/static/css/all.css&apos;;
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;font size=&apos;2&apos;&amp;gt;参考链接&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;lt;font size=&apos;2&apos;&amp;gt;https://blog.csdn.net/weixin_46858417/article/details/137469883&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Apple Watch Series 10-国补开箱</title><link>https://blog.pljzy.top/posts/applewatch/apple-watch-series-10%E5%9B%BD%E8%A1%A5%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/applewatch/apple-watch-series-10%E5%9B%BD%E8%A1%A5%E5%BC%80%E7%AE%B1/</guid><description>Apple Watch Series 10-国补开箱前言高中时候买的Apple Watch 1 一直用到现在 ，将近8年之久(大部分时间在吃灰)，原本我是对手表不是很在意的，因为前几年手机换回国产了，Watch 1也就没带了。</description><pubDate>Sun, 09 Feb 2025 22:45:42 GMT</pubDate><content:encoded>&lt;h1&gt;Apple Watch Series 10-国补开箱&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;高中时候买的Apple Watch 1 一直用到现在 ，将近8年之久(大部分时间在吃灰)，原本我是对手表不是很在意的，因为前几年手机换回国产了，Watch 1也就没带了。在近几年才换回苹果手机，老古董的Watch 1也用上了。不过性能和功能已经跟不上时代了，虽说可以测心跳，但是我想要的睡眠检测、压力检测等App是不受支持的。平时也就测测心率看看时间，而且电池只能勉强使用一天，大约8.00出门上班，下午6.00几乎就只有10%的电了。&lt;/p&gt;
&lt;p&gt;刚好最近国补很火，也是一直想换，然后我这边也是有手表国补，再加上京东的卷，我是&lt;code&gt;￥2209&lt;/code&gt;拿下。&lt;/p&gt;
&lt;p&gt;我买的型号是 Series 10 42 毫米 &lt;code&gt;GPS&lt;/code&gt;版本 玫瑰金色铝金属版本。&lt;/p&gt;
&lt;p&gt;我看很多人纠结42毫米还是46毫米，我因为本身手腕就细，然后的是Watch 1 才38毫米我都觉得够用了，所以我就毫不犹豫下单了42毫米，开箱试戴之后还是很满意的。这个根据自己的喜欢选择就行了。&lt;/p&gt;
&lt;p&gt;然后就是通关国补购买需要现场激活，我的苹果手机IOS是18版本，听说只有18版本能激活，然后激活大约花费了10分钟不到，快递员也是很有耐心。激活完成等快递员上传照片后就可以拿走了。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;font size=&apos;2&apos;&amp;gt;由于现场激活，这些开箱图片是补拍的&amp;lt;/font&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;手表介绍&lt;/h1&gt;
&lt;p&gt;这里直接放官网的图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其实买这款手表主要就是为了搭配App检测压力和睡眠情况。&lt;/p&gt;
&lt;h1&gt;退役手表&lt;/h1&gt;
&lt;p&gt;屏幕还是保护很完整的，哈哈。&lt;/p&gt;
&lt;p&gt;终于是退役了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;开箱图片&lt;/h1&gt;
&lt;p&gt;随手拍，非专业~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里显示心率测试43天前，是因为同步了我之前的旧手表~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Mintcaps·C64R2侧印键帽开箱</title><link>https://blog.pljzy.top/posts/mintcaps/mintcapsc64r2%E4%BE%A7%E5%8D%B0%E9%94%AE%E5%B8%BD%E5%BC%80%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/mintcaps/mintcapsc64r2%E4%BE%A7%E5%8D%B0%E9%94%AE%E5%B8%BD%E5%BC%80%E7%AE%B1/</guid><description>Mintcaps·C64R2侧印键帽开箱前言上一篇文章写了盲盒开箱，我自己也是给自己准备了礼物。身为一位专业的吗喽，一款好的键盘自然必不可少，但是键盘我暂时不想换新，那么在逛小红薯的时候看到了一款键帽，一眼就看上了，简直是梦中情帽。</description><pubDate>Fri, 20 Dec 2024 19:49:01 GMT</pubDate><content:encoded>&lt;h1&gt;Mintcaps·C64R2侧印键帽开箱&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;上一篇文章写了盲盒开箱，我自己也是给自己准备了礼物。&lt;/p&gt;
&lt;p&gt;身为一位专业的吗喽，一款好的键盘自然必不可少，但是键盘我暂时不想换新，那么在逛小红薯的时候看到了一款键帽，一眼就看上了，简直是梦中情帽。&lt;/p&gt;
&lt;p&gt;注意 ，这不是广告！！！&lt;/p&gt;
&lt;p&gt;我的键盘是：&lt;code&gt;HELLO GANSS XS 75T&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;产品参数&lt;/h1&gt;
&lt;p&gt;这款是&lt;code&gt;PBT&lt;/code&gt;热升华原厂高度键帽，这里就不细讲了。&lt;/p&gt;
&lt;h1&gt;产品样貌&lt;/h1&gt;
&lt;p&gt;这里放几张官方的图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.jpg&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;包装图&lt;/h1&gt;
&lt;p&gt;我买的盒装的，也就比散装贵几块钱。&lt;/p&gt;
&lt;p&gt;当时刚下班拍的比较着急，不是很好看，哈哈。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./4.jpg&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;实图&lt;/h1&gt;
&lt;p&gt;这是我自己拍的实物图，也是非常好看呀，特别是这次侧刻的图片。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./6.jpg&quot; alt=&quot;6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./7.jpg&quot; alt=&quot;7&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;结尾&lt;/h1&gt;
&lt;p&gt;整体来说，这款键帽还是非常舒服的。好看且手感也不错。&lt;/p&gt;
&lt;p&gt;这款键帽还有一款彩色的，不过我比较喜欢这个白色的。&lt;/p&gt;
&lt;p&gt;如果有喜欢的可以去小红书买，为了不打广告这里就不放地址了~&lt;/p&gt;
</content:encoded></item><item><title>记录星穹铁道叠叠乐第二弹拆箱</title><link>https://blog.pljzy.top/posts/%E6%98%9F%E7%A9%B9%E9%93%81%E9%81%93%E5%8F%A0%E5%8F%A0%E4%B9%90%E7%AC%AC%E4%BA%8C%E5%BC%B9%E6%8B%86%E7%AE%B1/%E8%AE%B0%E5%BD%95%E6%98%9F%E7%A9%B9%E9%93%81%E9%81%93%E5%8F%A0%E5%8F%A0%E4%B9%90%E7%AC%AC%E4%BA%8C%E5%BC%B9%E6%8B%86%E7%AE%B1/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%98%9F%E7%A9%B9%E9%93%81%E9%81%93%E5%8F%A0%E5%8F%A0%E4%B9%90%E7%AC%AC%E4%BA%8C%E5%BC%B9%E6%8B%86%E7%AE%B1/%E8%AE%B0%E5%BD%95%E6%98%9F%E7%A9%B9%E9%93%81%E9%81%93%E5%8F%A0%E5%8F%A0%E4%B9%90%E7%AC%AC%E4%BA%8C%E5%BC%B9%E6%8B%86%E7%AE%B1/</guid><description>记录星穹铁道叠叠乐第二弹拆箱前言从上次在线下店看到叠叠乐第一弹，就迷上了这么个小玩样，作为星穹铁道的一位普通玩家，对这东西甚是喜欢。</description><pubDate>Wed, 18 Dec 2024 21:06:48 GMT</pubDate><content:encoded>&lt;h1&gt;记录星穹铁道叠叠乐第二弹拆箱&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;从上次在线下店看到叠叠乐第一弹，就迷上了这么个小玩样，作为星穹铁道的一位普通玩家，对这东西甚是喜欢。那么为了迎接我的23岁，我的死党也是送了整整一盒叠叠乐，那么我就顺便记录一下这次拆箱。&lt;/p&gt;
&lt;p&gt;单买和整盒买感受完全不一样啊~&lt;/p&gt;
&lt;p&gt;话不多说，下面放图：&lt;/p&gt;
&lt;h1&gt;图片流警告&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;7&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;8&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;9&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;结尾&lt;/h1&gt;
&lt;p&gt;整体来是还是很不错的，唯二的不足就是钟表小子的鼻子竟然断掉了(未拆开就算断的)，还有银枝的闪光发饰掉了，不过用过502胶水连上就行了，问题不大。&lt;/p&gt;
&lt;p&gt;我最喜欢的还是三月七和萨姆，一个漂亮一个帅，银枝也好看~&lt;/p&gt;
&lt;p&gt;最好祝自己23岁生日快乐！！！&lt;/p&gt;
</content:encoded></item><item><title>小白装机-上机体验篇</title><link>https://blog.pljzy.top/posts/4060/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-4060%E4%B8%8A%E6%9C%BA%E4%BD%93%E9%AA%8C%E6%84%9F%E5%8F%97%E5%88%86%E4%BA%AB/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/4060/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-4060%E4%B8%8A%E6%9C%BA%E4%BD%93%E9%AA%8C%E6%84%9F%E5%8F%97%E5%88%86%E4%BA%AB/</guid><description>小白装机-上机体验篇前言前2篇文章：ZY知识库 · ZY - 小白装机-选配篇 https://pljzy.top/blog/post/60f2b0fa0e8491c9.htmlZY知识库 · ZY - 小白装机-装机篇</description><pubDate>Thu, 05 Dec 2024 23:46:00 GMT</pubDate><content:encoded>&lt;h1&gt;小白装机-上机体验篇&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;前2篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&quot;&gt;ZY知识库 · ZY - 小白装机-选配篇&lt;/a&gt; https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/4030f7f731ddccd2.html&quot;&gt;ZY知识库 · ZY - 小白装机-装机篇&lt;/a&gt; https://pljzy.top/blog/post/4030f7f731ddccd2.html&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分别讲了选配和装机，也是体验了2个月，这次分享一下我这套配置实际体验如何&lt;/p&gt;
&lt;p&gt;在这里声明一下，这是我个人的体验，并不是很专业。&lt;/p&gt;
&lt;h1&gt;我的配置&lt;/h1&gt;
&lt;p&gt;这里还是放一下我的配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;主板：微星 B650M GAMING PLUS WIFI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU：AMD R5 7500F 盒装&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;显卡：七彩虹4060 UItra W&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内存：金百达 银爵16*2 D5 6000 M-die C30&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;硬盘：致态 Ti Plus7100系列 1TB SSD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;散热：利民 240水冷&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;电源：长城G6 650W 金牌全模组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;其他配件：3把棱镜6PRO 一正二反&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;屏幕：KTC Q24T09 2k 180HZ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;机箱：玩嘉硕果海景公寓机箱&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;整机效果图&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;11.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;跑分&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不知道是不是因为CPU体质不好，只跑了&lt;code&gt;646205&lt;/code&gt;分，不过不影响，性能还是够够的。&lt;/p&gt;
&lt;h1&gt;吃鸡体验&lt;/h1&gt;
&lt;p&gt;首先是游玩吃鸡时候的体验，我的画质是&lt;code&gt;2k&lt;/code&gt;中高画质，这是在训练场的FPS：&lt;code&gt;161&lt;/code&gt;帧。&lt;/p&gt;
&lt;p&gt;下面是我的设置和帧数：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.2.jpg&quot; alt=&quot;4.2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.3.jpg&quot; alt=&quot;4.3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;黑神话悟空体验&lt;/h1&gt;
&lt;p&gt;目前我玩到第二章了，打boss稳定80-100帧数没任何问题，画质是游戏默认画质，也是2k分辨率高画质，未开光追。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;9-1.png&quot; alt=&quot;9-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;9-2.png&quot; alt=&quot;9-2&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;原神崩铁体验&lt;/h1&gt;
&lt;p&gt;原神和崩铁都是锁60帧，我也是默认画质游玩的，默认画质是2k高画质，我这套配置开2个窗口也是毫无压力~&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;消失的光芒2体验&lt;/h1&gt;
&lt;p&gt;可以看到帧数是&lt;code&gt;128&lt;/code&gt;帧，当时是在风车上拍的。然后游戏的画质也是&lt;code&gt;2k&lt;/code&gt; 其他画质均为默认未做修改，未开光追。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;逃离塔科夫体验&lt;/h1&gt;
&lt;p&gt;一样没截图，塔科夫的账号也被我出掉了，我的是限定俄黑边。&lt;/p&gt;
&lt;p&gt;整体游戏玩下来，我基本也就玩了几把，之前因为老电脑带不动买回来一直没玩，然后新电脑买回来也就玩了几把，玩的好像是海岸线地图，帧数稳定在&lt;code&gt;80&lt;/code&gt;帧左右吧。游戏画质我也没做调整，同样是&lt;code&gt;2k&lt;/code&gt;画质。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;暗区突围体验&lt;/h1&gt;
&lt;p&gt;2k中高画质下，未遇敌人帧数稳定在&lt;code&gt;150&lt;/code&gt;上下浮动。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;10-1.png&quot; alt=&quot;10-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;10-2.png&quot; alt=&quot;10-2&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;英雄联盟体验&lt;/h1&gt;
&lt;p&gt;众所周知英雄联盟不吃配置，确实不吃，进游戏&lt;code&gt;730&lt;/code&gt;帧，不过lol要这么高没用，锁240。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;永劫无间体验&lt;/h1&gt;
&lt;p&gt;画质和帧数如图，我本身是不玩这个游戏的，因为朋友玩，说想看看我这套配置的帧数，所以我就玩了一下。&lt;/p&gt;
&lt;p&gt;最高的时候跑过&lt;code&gt;190&lt;/code&gt;多帧，最低的时候&lt;code&gt;100&lt;/code&gt;多帧。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8.1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8.2.jpg&quot; alt=&quot;8.2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8.jpg&quot; alt=&quot;8&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;玩了这么多游戏，我总结一下就是这套配置基本可以畅玩3A和网游了。&lt;/p&gt;
&lt;p&gt;对于4060显卡我觉得还是很不错的，没有网上说的那么难堪，什么2k带不动呀等等，不过在现在网友人均4090的情况下还是看不上眼。&lt;/p&gt;
&lt;p&gt;那么对于想用2k玩游戏的，但是预算不够，用4060还是足够的（帧数敏感的直接上TI）。我上面的游戏都是2k中高画质下游玩的，基本感觉不到卡顿。可能由于我之前的显卡是&lt;code&gt;GTX 1650&lt;/code&gt;吧，我感觉换上4060是质的飞跃了哈哈。不过对于有&lt;strong&gt;光追需求&lt;/strong&gt;的玩家，4060就不是很合适了。&lt;/p&gt;
&lt;p&gt;那么对于CPU &lt;code&gt;7500F&lt;/code&gt;，我的评价也是很不错了。&lt;/p&gt;
</content:encoded></item><item><title>记录一次NPOI库导出Excel遇到的小问题解决方案</title><link>https://blog.pljzy.top/posts/npoiexcel/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1npoi%E5%BA%93%E5%AF%BC%E5%87%BAexcel%E9%81%87%E5%88%B0%E7%9A%84%E5%B0%8F%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/npoiexcel/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1npoi%E5%BA%93%E5%AF%BC%E5%87%BAexcel%E9%81%87%E5%88%B0%E7%9A%84%E5%B0%8F%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</guid><description>在工作中经常回去导入或者导出Excel，那么我在工作中用的是NPOI库，很方便。不过在用的时候难免会出现问题，在这里记录一下这次需求遇到的问题。</description><pubDate>Sat, 23 Nov 2024 14:54:41 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;在工作中经常会去导入或者导出Excel，那么我在工作中用的是NPOI库，很方便。不过在用的时候难免会出现问题，在这里记录一下这次需求遇到的问题。&lt;/p&gt;
&lt;p&gt;不过目前用的NPOI库的版本很老，不知道最新版本是否有其他实现方式，注意甄别。&lt;/p&gt;
&lt;h1&gt;问题一，自动换行&lt;/h1&gt;
&lt;p&gt;如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Snipaste_2024-11-23_14-42-39.png&quot; alt=&quot;Snipaste_2024-11-23_14-42-39&quot; /&gt;&lt;/p&gt;
&lt;p&gt;需要设置&lt;code&gt;WrapText = true&lt;/code&gt;才能让单元格中的内容自动换行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IFont fontfp = wb.CreateFont();
ICellStyle FontStyle = wb.CreateCellStyle();
FontStyle.WrapText = true; // 设置自动换行
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;问题二，函数问题&lt;/h1&gt;
&lt;p&gt;如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Snipaste_2024-11-23_14-55-21.png&quot; alt=&quot;Snipaste_2024-11-23_14-55-21&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果导出Excel是根据模版导出，模版中的函数可能会因为各种原因变成上图的样子，那么为了避免这种情况这里使用&lt;code&gt;SetCellFormula&lt;/code&gt;为单元格设置函数,这里以&lt;code&gt;SUM&lt;/code&gt;函数为例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IWorkbook workbook = new XSSFWorkbook();  
ISheet sheet = workbook.CreateSheet(&quot;Sheet1&quot;); 
sheet.GetRow(1).CreateCell(1).SetCellFormula(&quot;SUM(A1:A2)&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;问题三，插入行但图片位置不跟随&lt;/h1&gt;
&lt;p&gt;如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Snipaste_2024-11-23_14-56-55.png&quot; alt=&quot;Snipaste_2024-11-23_14-56-55&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果使用Office操作Excel插入行图片是会移动的，我插入一行，图片就会往下移动一行。但是如果使用代码操作，即使你插入行使用了&lt;code&gt;ShiftRows&lt;/code&gt;移动行，但是图片就是不动。&lt;/p&gt;
&lt;p&gt;那么，我的解决方案是图片不放到模版中，而是在进行模版导出的时候进行插入操作，当Excel数据插入后，再对图片进行插入，这样图片就可以在想要的位置中显示。&lt;/p&gt;
&lt;p&gt;这里用GPT写了个函数，可以参考一下。当完成插入行的操作后再调用这个函数就行了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;  
/// 将图片插入到Excel的指定sheet中  
/// &amp;lt;/summary&amp;gt;  
/// &amp;lt;param name=&quot;workbook&quot;&amp;gt;Excel工作簿&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;sheet&quot;&amp;gt;目标sheet&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;imagePath&quot;&amp;gt;图片路径&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;rowStart&quot;&amp;gt;起始行索引&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;rowEnd&quot;&amp;gt;结束行索引&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;colStart&quot;&amp;gt;起始列索引&amp;lt;/param&amp;gt;  
/// &amp;lt;param name=&quot;colEnd&quot;&amp;gt;结束列索引&amp;lt;/param&amp;gt;  
public void InsertImage(IWorkbook workbook, ISheet sheet, string imagePath, int rowStart, int rowEnd, int colStart, int colEnd, double scaleSize)
{
	// 读取图片文件  
	byte[] imageBytes = System.IO.File.ReadAllBytes(Server.MapPath(imagePath));

	// 添加图片到工作簿  
	int pictureIndex = workbook.AddPicture(imageBytes, PictureType.PNG);

	// 创建图形和锚定  
	IDrawing drawing = sheet.CreateDrawingPatriarch();
	IClientAnchor anchor = new XSSFClientAnchor (0, 0, 0, 0, co	lStart, rowStart, colEnd, rowEnd);

	// 创建并调整图片  
	IPicture picture = drawing.CreatePicture(anchor, pictureIndex);
	// 设置图片的新尺寸  
	picture.Resize(scaleSize);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;记录了&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;换行处理&lt;/li&gt;
&lt;li&gt;函数处理&lt;/li&gt;
&lt;li&gt;图片位置处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3个问题，虽然都不是很难的问题，但是这里还是分享一下~，如果有问题欢迎指出。&lt;/p&gt;
</content:encoded></item><item><title>记录一次原神抽卡双金</title><link>https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%8E%9F%E7%A5%9E%E6%8A%BD%E5%8D%A1%E5%8F%8C%E9%87%91/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%8E%9F%E7%A5%9E%E6%8A%BD%E5%8D%A1%E5%8F%8C%E9%87%91/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%8E%9F%E7%A5%9E%E6%8A%BD%E5%8D%A1%E5%8F%8C%E9%87%91/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1%E5%8E%9F%E7%A5%9E%E6%8A%BD%E5%8D%A1%E5%8F%8C%E9%87%91/</guid><description>记录一次原神抽卡双金，话不多说，放图：从原神开服就玩起，这啥第一次双金，记录一下，虽然第二个金的是常驻池，但也不错了。</description><pubDate>Wed, 20 Nov 2024 22:51:07 GMT</pubDate><content:encoded>&lt;h1&gt;记录一次原神抽卡双金&lt;/h1&gt;
&lt;p&gt;话不多说，放图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;从原神开服就玩起，这啥第一次双金，记录一下，虽然第二个金的是常驻池，但也不错了。&lt;/p&gt;
</content:encoded></item><item><title>leetcode算法题-有效的括号</title><link>https://blog.pljzy.top/posts/leetcode%E7%AE%97%E6%B3%95%E9%A2%98-%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7/%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/leetcode%E7%AE%97%E6%B3%95%E9%A2%98-%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7/%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7/</guid><description>有效的括号(简单)leetcode：https://leetcode.cn/problems/valid-parentheses/description/前言防止脑袋生锈，做一下leetcode的简单算法题，难得也做不来哈哈。</description><pubDate>Mon, 11 Nov 2024 22:39:09 GMT</pubDate><content:encoded>&lt;h1&gt;有效的括号(简单)&lt;/h1&gt;
&lt;p&gt;leetcode：https://leetcode.cn/problems/valid-parentheses/description/&lt;/p&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;防止脑袋生锈，做一下leetcode的简单算法题，难得也做不来哈哈。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;大佬绕道，小白可看。&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;题目描述&lt;/h1&gt;
&lt;p&gt;给定一个只包括 &lt;code&gt;&apos;(&apos;&lt;/code&gt;，&lt;code&gt;&apos;)&apos;&lt;/code&gt;，&lt;code&gt;&apos;{&apos;&lt;/code&gt;，&lt;code&gt;&apos;}&apos;&lt;/code&gt;，&lt;code&gt;&apos;[&apos;&lt;/code&gt;，&lt;code&gt;&apos;]&apos;&lt;/code&gt; 的字符串 &lt;code&gt;s&lt;/code&gt; ，判断字符串是否有效。&lt;/p&gt;
&lt;p&gt;有效字符串需满足：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;左括号必须用相同类型的右括号闭合。&lt;/li&gt;
&lt;li&gt;左括号必须以正确的顺序闭合。&lt;/li&gt;
&lt;li&gt;每个右括号都有一个对应的相同类型的左括号。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;示例 1：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**输入：**s = &quot;()&quot;&lt;/p&gt;
&lt;p&gt;**输出：**true&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;示例 2：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**输入：**s = &quot;()[]{}&quot;&lt;/p&gt;
&lt;p&gt;**输出：**true&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;示例 3：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**输入：**s = &quot;(]&quot;&lt;/p&gt;
&lt;p&gt;**输出：**false&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;示例 4：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**输入：**s = &quot;([])&quot;&lt;/p&gt;
&lt;p&gt;**输出：**true&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;提示：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= s.length &amp;lt;= 104&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; 仅由括号 &lt;code&gt;&apos;()[]{}&apos;&lt;/code&gt; 组成&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;题目解析&lt;/h1&gt;
&lt;p&gt;通过题目描述可以举例哪些是有效字符串，哪些是无效字符串，如：&lt;/p&gt;
&lt;p&gt;有效字符串&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&quot;()&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;({})&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;()[]&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;无效字符串&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&quot;(]&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;({)}&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;)&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不难发现即使字符串中有闭合但是顺序不对也是属于无效字符串。&lt;/p&gt;
&lt;h1&gt;解题思路&lt;/h1&gt;
&lt;p&gt;右括号不一定出现在左括号下一位&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&quot;([{}])&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;左右括号必须以正确的顺序闭合：&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;({})&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;&lt;code&gt;&quot;({)}&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;字符串中会存在有效的括号对也会有无效的括号对了，如：&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;({})({})&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;&lt;code&gt;&quot;({})({)}&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;尝试将有效的括号对一一消除掉&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;()({})&quot;&lt;/code&gt;&amp;lt;/font&amp;gt; =&amp;gt; &amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;({})&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;=&amp;gt;&amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;()&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;=&amp;gt;&amp;lt;font color=&apos;blue&apos;&amp;gt;&lt;code&gt;&quot;&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;&lt;code&gt;&quot;()({)}&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;=&amp;gt;&amp;lt;font color=&apos;red&apos;&amp;gt;&lt;code&gt;&quot;({)}&quot;&lt;/code&gt;&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;如果是有效的字符串最终会得到空字符串，反之则是无效字符串。&lt;/p&gt;
&lt;h2&gt;伪代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;遍历字符串:
	如果是左括号:
		等待遍历到与之对应的右括号
	如果是右括号:
		查看是否有与之对应的左括号
			如果有，则消除
			如果没有，当前字符串无效
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;动图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;1.gif&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;初步总结&lt;/h2&gt;
&lt;p&gt;通过前面的解题思路和动图可以发现，最后遍历到的左括号，最先匹配到有效的右括号。&lt;/p&gt;
&lt;p&gt;这可以看作为**“后进先出”**的栈。后加入的元素最先被处理。&lt;/p&gt;
&lt;h1&gt;后进先出的栈&lt;/h1&gt;
&lt;h2&gt;栈的定义&lt;/h2&gt;
&lt;p&gt;栈（Stack）是一种数据结构，遵循后进先出（LIFO, Last In First Out）的原则。也就是说，最后插入栈中的元素最先被取出。栈可以用来存储数据、管理函数调用、实现撤销操作等。&lt;/p&gt;
&lt;p&gt;栈的主要操作包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;压入（Push）&lt;/strong&gt;：将一个元素添加到栈顶。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;弹出（Pop）&lt;/strong&gt;：移除并返回栈顶的元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查看栈顶（Peek/Top）&lt;/strong&gt;：返回栈顶的元素但不移除它。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检查栈是否为空（IsEmpty）&lt;/strong&gt;：判断栈中是否还有元素。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;开始解题&lt;/h1&gt;
&lt;h2&gt;图片详解&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;遍历字符串:
	如果是左括号:
		入栈
	如果是右括号:
		查看栈顶元素
			如果是对应的左括号则出栈
			如果不是，当前字符串无效
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;代码实现&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public bool IsValid(string s) {
	Stack&amp;lt;char&amp;gt; stack = new Stack&amp;lt;char&amp;gt;();
	foreach (char c in s)
	{
		switch(c)
		{
            case &apos;{&apos;:
            case &apos;[&apos;:
            case &apos;(&apos;:
            	stack.Push(c);
            	break;
			case &apos;}&apos;:
				if(stack.Count == 0 || stack.Pop()!= &apos;{&apos;)
					return false;
				break;
			case &apos;]&apos;:
				if(stack.Count == 0 || stack.Pop()!= &apos;[&apos;)
				return false;
				break;
			case &apos;)&apos;:
				if(stack.Count == 0 || stack.Pop()!= &apos;(&apos;)
					return false;
				break;
		}
	}
	return stack.Count == 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;复杂度分析&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;空间复杂度：O(n)&lt;/li&gt;
&lt;li&gt;时间复杂度：O(n)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;结果展示&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;其他解法&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;public bool IsValid(string s) {
	int length = s.Length/ 2;
	for (int i = 0; i &amp;lt; length; i++) {
		s = s.Replace(&quot;()&quot;, &quot;&quot;).Replace(&quot;{}&quot;, &quot;&quot;).Replace(&quot;[]&quot;, &quot;&quot;);
	}
	return s.Length == 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;相关链接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;https://leetcode.cn/problems/valid-parentheses/description/&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>小白装机-装机篇</title><link>https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E8%A3%85%E6%9C%BA%E7%AF%87/</guid><description>小白装机-装机篇前言上一篇文章讲了我是如何选择装机配置的，这篇文章讲解一下如何进行装机，分享一下装机经验由于装机过程未拍摄视频或照片，这里就简单分享下经验，我会将我参考的装机视频链接放在文章最下面。安装步骤我这里以我的机箱和配件来讲解装机步骤。首先我是等配件全部到齐再进行装机。</description><pubDate>Fri, 18 Oct 2024 23:42:11 GMT</pubDate><content:encoded>&lt;h1&gt;小白装机-装机篇&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&quot;&gt;选配篇&lt;/a&gt; https://pljzy.top/blog/post/60f2b0fa0e8491c9.html&lt;/p&gt;
&lt;p&gt;上一篇文章讲了我是如何选择装机配置的，这篇文章讲解一下如何进行装机，分享一下装机经验&lt;/p&gt;
&lt;p&gt;由于装机过程未拍摄视频或照片，这里就简单分享下经验，我会将我参考的装机视频链接放在文章最下面。&lt;/p&gt;
&lt;h2&gt;安装步骤&lt;/h2&gt;
&lt;p&gt;我这里以我的机箱和配件来讲解装机步骤。&lt;/p&gt;
&lt;p&gt;首先我是等配件全部到齐再进行装机。&lt;/p&gt;
&lt;p&gt;第一步，安装CPU，把主板放在平面上，装的时候可以先洗个手去除一下手上的静电，以防击穿主板（也可以佩戴仿静电手套）。打开主板CPU盖板，检查主板CPU针脚有无弯曲，没问题后，CPU会有一个防呆三角形标识，将标识方向和主板标识方向一致，缓缓的放下CPU。放稳后，压下盖板，CPU保护盖会弹起。&lt;strong&gt;如果没有弹起，在你确定cpu安装是正确的情况下，用手把保护盖取下来就行。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第二步，安装内存条，我买了16G内存条2根，通常安装到主板的2,4通道，也就是第2和第4个插槽，插槽也有防呆口。将插槽一端的锁扣打开，内存条缺口和插槽缺口对齐放入，然后用手按住内存条两端用力往下压，锁扣会自动回弹回去。&lt;/p&gt;
&lt;p&gt;第三步，安装硬盘，以45度对准硬盘接口插进去然后往下压，硬盘那里会有一个螺丝或者卡扣用于固定硬盘。装好之后有马甲的把马甲贴上按钮螺丝拧上&lt;/p&gt;
&lt;p&gt;第四步，把电源线整理好放进机箱里面，然后把主板固定在机箱上面。&lt;/p&gt;
&lt;p&gt;第五步，安装水冷或者风冷，把其他风扇也安装上去&lt;/p&gt;
&lt;p&gt;第六步，插线，将Cpu供电、水冷、风扇等供电线插上，注意不要插错了，也不要暴力插&lt;/p&gt;
&lt;p&gt;第七步，安装显卡，此时电脑已经把所有配件都装上了&lt;/p&gt;
&lt;h2&gt;装机图片分享&lt;/h2&gt;
&lt;p&gt;理线杂乱无章请忽略哈哈。长图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20241013163957.jpg&quot; alt=&quot;微信图片_20241013163957&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20241018233632.jpg&quot; alt=&quot;微信图片_20241018233632&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410182336321.jpg&quot; alt=&quot;微信图片_202410182336321&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410182336322.jpg&quot; alt=&quot;微信图片_202410182336322&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20241018233633.jpg&quot; alt=&quot;微信图片_20241018233633&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20241013164049.jpg&quot; alt=&quot;微信图片_20241013164049&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410182336331.jpg&quot; alt=&quot;微信图片_202410182336331&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410182336332.jpg&quot; alt=&quot;微信图片_202410182336332&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410182336333.jpg&quot; alt=&quot;微信图片_202410182336333&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20241013135800.jpg&quot; alt=&quot;微信图片_20241013135800&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;超频&lt;/h1&gt;
&lt;h2&gt;cpu超频&lt;/h2&gt;
&lt;p&gt;我买的是AMD的CPU，并且主板供电可以跑满这颗cpu，默认频率是3.7，所以超频是必然的。不过不知道是体质问题还是电压没给够，第一次超频5.2直接开不了机，然后我重置了Blos之后重新超的5.1就能开机了。&lt;/p&gt;
&lt;h2&gt;内存条超频&lt;/h2&gt;
&lt;p&gt;这个比较简单，我直接在主板开启EXPO就行了，其他的参数我怕影响开机，因为第一次我是调过其他参数的，也可能是这个原因导致无法开机。&lt;/p&gt;
&lt;h2&gt;教程链接分享&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;水冷安装：https://www.bilibili.com/video/BV12T411p7oj/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;li&gt;机箱线：&lt;a href=&quot;https://www.bilibili.com/video/BV1PA4y1d7yf/?spm_id_from=333.880.my_history.page.click&quot;&gt;接机箱线，电脑开关线_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV1PA4y1d7yf/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;li&gt;全模组电源接线：&lt;a href=&quot;https://www.bilibili.com/video/BV1WQ4y1N7dy/?spm_id_from=333.880.my_history.page.click&quot;&gt;全模组电源接线安装教程，细节分析电源接线方法！_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV1WQ4y1N7dy/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;li&gt;微星主板供电线：&lt;a href=&quot;https://www.bilibili.com/video/BV13B4y1H7os/?spm_id_from=333.880.my_history.page.click&amp;amp;vd_source=f8b5615a803ba75e76e0cee5d4de22b6&quot;&gt;微星主板供电线安装教程_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV13B4y1H7os/?spm_id_from=333.880.my_history.page.click&amp;amp;vd_source=f8b5615a803ba75e76e0cee5d4de22b6&lt;/li&gt;
&lt;li&gt;装机教程：&lt;a href=&quot;https://www.bilibili.com/video/BV1BG4y137mG/?spm_id_from=333.880.my_history.page.click&quot;&gt;【装机教程】全网最好的装机教程，没有之一_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV1BG4y137mG/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;li&gt;装机教程：&lt;a href=&quot;https://www.bilibili.com/video/BV1pKxFeFEdf/?spm_id_from=333.880.my_history.page.click&quot;&gt;【毛子电脑】爱国者星灿岚超详细装机走线教学，AMD主机装机 学不会电脑送你_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV1pKxFeFEdf/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;li&gt;系统安装(win11步骤一样)：&lt;a href=&quot;https://www.bilibili.com/video/BV1DJ411D79y/?spm_id_from=333.880.my_history.page.click&quot;&gt;【装机教程】超详细WIN10系统安装教程，官方ISO直装与PE两种方法教程，UEFI+GUID分区与Legacy+MBR分区_哔哩哔哩_bilibili&lt;/a&gt; https://www.bilibili.com/video/BV1DJ411D79y/?spm_id_from=333.880.my_history.page.click&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>小白装机-选配篇</title><link>https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/%E5%B0%8F%E7%99%BD%E8%A3%85%E6%9C%BA-%E9%80%89%E9%85%8D%E7%AF%87/</guid><description>小白装机-选配篇前言出来工作挺久了，自己用的笔记本也是19年的产品，用起来有点卡。最主要的是带不动黑悟空了，那么也是有了想买台台式机的想法。在选配阶段也是在抖音、B站、小红书上看了很多视频，自己做了很多功课。废话不多说，我先放出我的配置。</description><pubDate>Tue, 15 Oct 2024 23:55:23 GMT</pubDate><content:encoded>&lt;h1&gt;小白装机-选配篇&lt;/h1&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;出来工作挺久了，自己用的笔记本也是19年的产品，用起来有点卡。最主要的是带不动黑悟空了，那么也是有了想买台台式机的想法。&lt;/p&gt;
&lt;p&gt;在选配阶段也是在抖音、B站、小红书上看了很多视频，自己做了很多功课。废话不多说，我先放出我的配置。&lt;/p&gt;
&lt;h2&gt;我的配置&lt;/h2&gt;
&lt;p&gt;主板：微星 B650M GAMING PLUS WIFI&lt;/p&gt;
&lt;p&gt;CPU：AMD R5 7500F 盒装&lt;/p&gt;
&lt;p&gt;显卡：七彩虹4060 UItra W&lt;/p&gt;
&lt;p&gt;内存：金百达 银爵16*2 D5 6000 M-die C30&lt;/p&gt;
&lt;p&gt;散热：利民 240水冷&lt;/p&gt;
&lt;p&gt;电源：长城G6 650W 金牌全模组&lt;/p&gt;
&lt;p&gt;其他配件：3把棱镜6PRO 一正二反&lt;/p&gt;
&lt;p&gt;屏幕：KTC Q24T09 2k 180HZ&lt;/p&gt;
&lt;p&gt;机箱：玩嘉硕果海景公寓机箱&lt;/p&gt;
&lt;p&gt;这里简单讲一下选择这套配置的原因，首先是主板，我觉得颜值还不错，然后有WIFI 6E非常重要，因为租房没网线，然后也能超频跑满这颗CPU，虽然网上说这款主板是水桶板，但以我这颗CPU来说完全不影响。&lt;/p&gt;
&lt;p&gt;CPU选择的是AMD平台的7500F，一开始是准备选择Intel的12600KF的，不出意外就出意外了，涨价涨到1300了，最后选择了这款7500F，网友们称为网游神U。我对生产力和游戏其实没有特别的要求，流畅就行，所以AMD和Intel我都能接受。&lt;/p&gt;
&lt;p&gt;显卡为了颜值选择了七彩虹的UItra，白色显卡，这里为什么不上4060Ti，主要是预算不够，4060可以畅玩3A了，够用，大不了调低一下游戏画质。&lt;/p&gt;
&lt;p&gt;内存也是选择了金百达的M代颗粒C30时序的，新出的M代价格也便宜，如果上A代28时序超预算了。&lt;/p&gt;
&lt;p&gt;散热和电源这可就随意选择了，选水冷是为了颜值！！！，电源也是选的长城电源有7年质保。&lt;/p&gt;
&lt;h2&gt;个人见解&lt;/h2&gt;
&lt;p&gt;这里详细讲解下我是如何选配的，首先得益于算法时代，当各大电商平台知道我想买台式机后，抖音、小红书、淘宝、拼多多、京东全在给我推电商主机。我也是在刷抖音的时候看到了胖哥装机，那段时间一下班就看胖哥的直播。他的直播类型就是粉丝连麦然后配主机。看了一段时间自然而然自己也懂了一点。当然我这套配置完完全全是刀把机，钱都花在了颜值上。&lt;/p&gt;
&lt;p&gt;在有一定的基础后，也了解了当下装机热门的CPU，无可非议在1000左右价位就非AMD R5 7500和Intel 12600KF为主了。虽然7500F核心数比12600KF小，但7500F三缓多且超频成本低。可以将主频超至5.3。&lt;/p&gt;
&lt;p&gt;那么简单讲一下这2颗U的区别&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;AMD 7500F&lt;/th&gt;
&lt;th&gt;Intel 12600KF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;核显&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;核心数量&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;线程&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;频率范围&lt;/td&gt;
&lt;td&gt;3.7~5.0 GHz&lt;/td&gt;
&lt;td&gt;3.6~4.9 GHz&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max内存频率&lt;/td&gt;
&lt;td&gt;D5 5200&lt;/td&gt;
&lt;td&gt;D4 3200 D5 4800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TDP功耗&lt;/td&gt;
&lt;td&gt;65W&lt;/td&gt;
&lt;td&gt;125W&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;二级缓存&lt;/td&gt;
&lt;td&gt;6MB&lt;/td&gt;
&lt;td&gt;9.5MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;三级缓存&lt;/td&gt;
&lt;td&gt;32MB&lt;/td&gt;
&lt;td&gt;20MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;7500F的优势就算功耗低三缓多，12600KF核心多。&lt;/p&gt;
&lt;p&gt;网上有很多这2颗U的对比和评测，我这里就不多讲了。&lt;/p&gt;
&lt;h2&gt;配件图片&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(1).png&quot; alt=&quot;WPS图片(1)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(2).png&quot; alt=&quot;WPS图片(2)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(3).png&quot; alt=&quot;WPS图片(3)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(4).png&quot; alt=&quot;WPS图片(4)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(5).png&quot; alt=&quot;WPS图片(5)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(6).png&quot; alt=&quot;WPS图片(6)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(7).png&quot; alt=&quot;WPS图片(7)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(8).png&quot; alt=&quot;WPS图片(8)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(9).png&quot; alt=&quot;WPS图片(9)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;WPS%E5%9B%BE%E7%89%87(10).png&quot; alt=&quot;WPS图片(10)&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;如果想自己租一台主机，可以先从抖音入局，先看看直播，然后小红书对比配置，再在B站看装机教程，这里推荐一款装机小程序，在微信小程序搜索装机助手。下一篇文章是博主的装机篇！！！&lt;/p&gt;
</content:encoded></item><item><title>弹幕树洞项目功能新增篇</title><link>https://blog.pljzy.top/posts/%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE-1/%E5%BC%B9%E5%B9%95%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE%E5%8A%9F%E8%83%BD%E6%96%B0%E5%A2%9E%E7%AF%87/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE-1/%E5%BC%B9%E5%B9%95%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE%E5%8A%9F%E8%83%BD%E6%96%B0%E5%A2%9E%E7%AF%87/</guid><description>项目地址项目后端地址：https://github.com/ZyPLJ/ZYTteeHole项目前端页面地址：ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue目前项目测试访问地址：http://tree.pljzy.top/ 注意是http,输成https就访问到博客里面去了。</description><pubDate>Thu, 26 Sep 2024 23:05:48 GMT</pubDate><content:encoded>&lt;h1&gt;项目地址&lt;/h1&gt;
&lt;p&gt;项目后端地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://github.com/ZyPLJ/ZYTteeHole&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目前端页面地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/TreeHoleVue&quot;&gt;ZyPLJ/TreeHoleVue (github.com)&lt;/a&gt; https://github.com/ZyPLJ/TreeHoleVue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前项目测试访问地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http://tree.pljzy.top/ 注意是http,输成https就访问到博客里面去了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;系列文章📖&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/ZYPLJ/p/18403223&quot;&gt;.NET Core搭配Vue开源弹幕效果，实现一个评论小项目。好玩！ - 妙妙屋（zy） - 博客园 (cnblogs.com)&lt;/a&gt; https://www.cnblogs.com/ZYPLJ/p/18403223&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pljzy.top/blog/post/2b33f54a84901364.html&quot;&gt;ZY知识库 · ZY - 弹幕树洞项目 (pljzy.top)&lt;/a&gt; https://www.pljzy.top/blog/post/2b33f54a84901364.html&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;接上一篇文章，无聊的时候做了个树洞项目，其实一开始打算做真正的树洞，但是奈何前端技术有限，只能去GitHub找找灵感💡，不巧看到了Vue弹幕项目，看了一下觉得挺不错就拿来用了。
那做这个项目的初衷是自己有个地方能倾述自己的想法，能够让自己随便吐槽。这个项目目前是没有记录评论的ip和用户信息的，全是匿名的，所以可以随便吐槽（当然需要保持素质）。
本篇文章主要讲一讲我是怎么实现实时消息和人数的。&lt;/p&gt;
&lt;h1&gt;实时消息、人数展示实现&lt;/h1&gt;
&lt;h2&gt;SignalR📖&lt;/h2&gt;
&lt;p&gt;既然是用.net写的项目，必然少不了 &lt;code&gt;SignalR&lt;/code&gt;技术，最开始考虑使用消息实时性有如下几种方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WebSocket&lt;/li&gt;
&lt;li&gt;SignalR&lt;/li&gt;
&lt;li&gt;轮询&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后综合考虑 &lt;code&gt;SignalR&lt;/code&gt;，主要是使用起来简单，并且我要实现的功能也不复杂。
那么就简单讲下&lt;code&gt;SignalR&lt;/code&gt;是什么：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SignalR是一个由微软开发的实时通信框架，它简化了在C#中实现实时双向通信的过程。SignalR特别适用于需要实时交互的应用，如聊天程序、在线游戏、协同工作工具等。
SignalR 支持以下用于处理实时通信的技术：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WebSockets&lt;/li&gt;
&lt;li&gt;Server-Sent Events&lt;/li&gt;
&lt;li&gt;长轮询
SignalR 自动选择服务器和客户端能力范围内的最佳传输方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;简单来讲可以使用&lt;code&gt;SignalR&lt;/code&gt;快速开发实时通讯项目。&lt;/p&gt;
&lt;h2&gt;代码实现&lt;/h2&gt;
&lt;h3&gt;后端代码&lt;/h3&gt;
&lt;p&gt;我使用的是.net 8创建的项目，好像自带&lt;code&gt;SignalR&lt;/code&gt;，如果没有则需要去Nuget去下载。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Microsoft.AspNetCore.SignalR.Client
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后端主要代码就是&lt;code&gt;Hub&lt;/code&gt;类的实现&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ChatHub:Hub  
{  
    private static int _connectionCount;  
    public async Task SendComment(string content)    
    {    
		ZyComments comment = new ZyComments  
        {  
            Content = content  
        };       
        //广播评论给所有连接的客户端    
		await Clients.All.SendAsync(&quot;ReceiveComment&quot;, comment);  
    }
    public override Task OnConnectedAsync()  
    {        
	    // 每次客户端连接时增加计数  
        Interlocked.Increment(ref _connectionCount);  
        return base.OnConnectedAsync();  
    } 
    public override Task OnDisconnectedAsync(Exception? exception)  
    {        
	    // 每次客户端断开连接时减少计数  
        Interlocked.Decrement(ref _connectionCount);  
        // 广播连接数量变化    
		_ = BroadcastConnectionCount();  
        return base.OnDisconnectedAsync(exception);  
    } 
    public int GetConnectionCount()  
    {       
		// 获取当前连接数量  
        return _connectionCount;  
    }    
    public async Task BroadcastConnectionCount()  
    {        
	    await Clients.All.SendAsync(&quot;ConnectionCountChanged&quot;, _connectionCount);  
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;简单描述就是用户评论的时候会调用&lt;code&gt;SendComment&lt;/code&gt;方法将消息广播给当前连接的用户。然后在连接的时候将统计在线用户的计数++，断开连接的时候减少，并广播给连接的用户。
配置&lt;code&gt;Program.cs&lt;/code&gt;文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddSignalR();

app.MapHub&amp;lt;ChatHub&amp;gt;(&quot;/ChatHub&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到此后端就编写完成了，是不是非常简单。&lt;/p&gt;
&lt;h3&gt;前端代码&lt;/h3&gt;
&lt;p&gt;安装客户端连接库：&lt;code&gt;npm install @microsoft/signalr&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import * as signalR from &apos;@microsoft/signalr&apos;;

const connectionCount = ref(0);// 连接数量
let connection: signalR.HubConnection | null = null;  

connection = new signalR.HubConnectionBuilder()  
    .withUrl(&apos;https://localhost:44323/ChatHub&apos;) //后端地址 
    .build();
    
//订阅评论消息事件
connection.on(&apos;ReceiveComment&apos;, (comment: any) =&amp;gt; {    
  comments.value.push(comment);  
  const _danmuMsg =  
      {        
	      ...
      }  
  danmaku.value.add(_danmuMsg)   
});

// 订阅连接数量变化事件  
connection.on(&apos;ConnectionCountChanged&apos;, (count) =&amp;gt; {  
  connectionCount.value = count;  
  console.log(`当前连接数量：${count}`);  
});

//连接成功后调用BroadcastConnectionCount方法广播一次
connection.start().then(()=&amp;gt;{  
  connection.invoke(&apos;BroadcastConnectionCount&apos;)  
      .catch(err =&amp;gt; console.error(err.toString()));  
}).catch(err =&amp;gt; console.error(err.toString()));

......
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上述展示部分代码，也很简单，当用户创建连接后调用一次计数方法广播一次，并订阅评论消息和连接数量变化事件，然后当收到广播时执行相应的逻辑。
代码所在区域：&lt;a href=&quot;https://github.com/ZyPLJ/TreeHoleVue/blob/master/src/Views/Home.vue&quot;&gt;TreeHoleVue/src/Views/Home.vue at master · ZyPLJ/TreeHoleVue (github.com)&lt;/a&gt; https://github.com/ZyPLJ/TreeHoleVue/blob/master/src/Views/Home.vue&lt;/p&gt;
&lt;h1&gt;效果展示💯&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;待完成的点🏷️&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[x] 评论限流&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 关键词过滤&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 将前端弹幕设置滚动频率、速度等写入配置文件或者数据库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ ] 完成后台管理模块的编写。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 前端页面美化&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 实时消息、人数展示&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 评论点赞排行榜&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ ] 高亮显示最新评论及最新评论时间&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;相关链接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;前端弹幕效果使用开源项目：&lt;a href=&quot;https://github.com/hellodigua/vue-danmaku&quot;&gt;https://github.com/hellodigua/vue-danmaku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-8.0&amp;amp;tabs=visual-studio&quot;&gt;ASP.NET Core SignalR 入门 | Microsoft Learn&lt;/a&gt; https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-8.0&amp;amp;tabs=visual-studio)&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>设计模式-实现简单工厂模式</title><link>https://blog.pljzy.top/posts/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E7%8E%B0%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E7%8E%B0%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</guid><description>前言上一篇文章写了如何使用RabbitMQ做个简单的发送邮件项目，然后评论也是比较多，也是准备去学习一下如何确保RabbitMQ的消息可靠性，但是由于时间原因，先来说说设计模式中的简单工厂模式吧！在了解简单工厂模式之前，我们要知道C#是一款面向对象的高级程序语言。</description><pubDate>Thu, 26 Sep 2024 23:05:48 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;上一篇文章写了如何使用RabbitMQ做个简单的发送邮件项目，然后评论也是比较多，也是准备去学习一下如何确保RabbitMQ的消息可靠性，但是由于时间原因，先来说说设计模式中的简单工厂模式吧！
在了解简单工厂模式之前，我们要知道C#是一款面向对象的高级程序语言。它有3大特性，封装、继承、多态。&lt;/p&gt;
&lt;h1&gt;简述&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;工厂模式（Factory Pattern）是一种常用的设计模式，属于创建型模式，它提供了一种创建对象的最佳方式。在工厂模式中，我们创建对象时不会对客户端暴露创建逻辑，并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式的核心是定义一个创建产品对象的工厂接口，将实际创建工作推迟到子类当中。这样客户端可以无需指定具体产品的类，只需通过工厂类即可得到所需的产品对象。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;工厂模式主要分为三种类型：简单工厂模式（Simple Factory Pattern）、工厂方法模式（Factory Method Pattern）和抽象工厂模式（Abstract Factory Pattern）。
本文主要讲解简单工厂模式（Simple Factory Pattern）。&lt;/p&gt;
&lt;h1&gt;案例带入&lt;/h1&gt;
&lt;p&gt;下面使用C#控制台程序去写一个简易的计算器，实现加减乘除。如果我没学过设计模式，我会这么写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)  
{  
    Console.WriteLine(&quot;请输入数字A：&quot;);  
    string A = Console.ReadLine();  
    Console.WriteLine(&quot;请选择运算符号：(+、-、*、/)：&quot;);  
    string op = Console.ReadLine();  
    Console.WriteLine(&quot;请输入数字B：&quot;);  
    string B = Console.ReadLine();  
    string result = &quot;&quot;;  
    switch (op)  
    {        
	    case &quot;+&quot;:  
            result = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(B));  
            break;  
        case &quot;-&quot;:  
            result = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(B));  
            break;  
        case &quot;*&quot;:  
            result = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(B));  
            break;  
        case &quot;/&quot;:  
            result = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(B));  
            break;  
        default:  
            Console.WriteLine(&quot;输入的运算符号有误！&quot;);  
            break;  
    }    
    Console.WriteLine(&quot;结果：&quot; + result);  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上述代码乍一看没问题，实则隐藏了很多陷阱，比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;变量命名不规范&lt;/li&gt;
&lt;li&gt;除数为0怎么办&lt;/li&gt;
&lt;li&gt;输入的不是数字怎么办&lt;/li&gt;
&lt;li&gt;......&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;优化&lt;/h2&gt;
&lt;p&gt;我们用面向对象的思想进行优化，主要体现在：可维护、可复用、可扩展、灵活性几个方面。通过封装、继承、多态来降低程序的耦合度。&lt;/p&gt;
&lt;h3&gt;封装&lt;/h3&gt;
&lt;p&gt;我们可以将运算逻辑封装成一个方法去实现，让主方法减轻负担。封装后：
&lt;code&gt;Operation&lt;/code&gt;类&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Operation
{
    public static double GetResult(double num1, double num2, string op)
    {
        double result = 0d;
        switch (op)
        {
            case &quot;+&quot;:
                result = num1 + num2;
                break;
            case &quot;-&quot;:
                result = num1 - num2;
                break;
            case &quot;*&quot;:
                result = num1 * num2;
                break;
            case &quot;/&quot;:
                result = num1 / num2;
                break;
        }
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Main&lt;/code&gt;方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)
{
	try
	{
		Console.WriteLine(&quot;请输入数字A：&quot;);
		string strNumA = Console.ReadLine();
		Console.WriteLine(&quot;请选择运算符号：(+、-、*、/)：&quot;);
		string op = Console.ReadLine();
		Console.WriteLine(&quot;请输入数字B：&quot;);
		string strNumB = Console.ReadLine();
		string result = &quot;&quot;;
		result = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumA), Convert.ToDouble(strNumB), op));
		Console.WriteLine(&quot;结果：&quot; + result);
	}
	catch (Exception e)
	{
		Console.WriteLine(&quot;发生异常：&quot; + e.Message);
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;松耦合&lt;/h3&gt;
&lt;p&gt;当我们完成封装后开始思考一个问题，如果后面有新的需求，需要增加一个开根运行，应该如何去修改？如果是我，我会在switch里面加一个分支，但是这样耦合度太高。我明明只需要去开根，但是却要让加减乘除参与进来，所以我们应该将加减乘除运算分离出来。
优化耦合度：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Operation
{
    private double _num1;
    private double _num2;
    public double Num1 { get =&amp;gt; _num1; set =&amp;gt; _num1 = value; }
    public double Num2 { get =&amp;gt; _num2; set =&amp;gt; _num2 = value; }
    public virtual double GetResult()
    {
        return 0;
    }
}

//加法类
public class AddOperation : Operation
{
    public override double GetResult()
    {
        return Num1 + Num2;
    }
}
//减法类
public class SubtractOperation : Operation
{
    public override double GetResult()
    {
        return Num1 - Num2;
    }
}
//乘法类
public class MultiplyOperation : Operation
{
    public override double GetResult()
    {
        return Num1 * Num2;
    }
}
//除法类
public class DivideOperation : Operation
{
    public override double GetResult()
    {
        if (Num2 == 0)
            throw new DivideByZeroException(&quot;除数不能为0&quot;);
        return Num1 / Num2;
    }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我创建了&lt;code&gt;Operation&lt;/code&gt;基类，并定义了2个成员变量&lt;code&gt;_num1&lt;/code&gt;和&lt;code&gt;_num2&lt;/code&gt;,同时定义了一个&lt;code&gt;GetResult&lt;/code&gt;虚方法。同时分别创建了加减乘除子类去重写&lt;code&gt;GetResult&lt;/code&gt;方法来降级耦合度。&lt;/p&gt;
&lt;h3&gt;回归正题(简单工厂模式)&lt;/h3&gt;
&lt;p&gt;我们需要通过简单工厂模式，来让程序知道该实例化谁。需要来创建一个工厂类：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class OperationFactory
{
    public static Operation CreateOperation(string operation)
    {
        switch (operation)
        {
            case &quot;+&quot;:
                return new AddOperation();
            case &quot;-&quot;:
                return new SubtractOperation();
            case &quot;*&quot;:
                return new MultiplyOperation();
            case &quot;/&quot;:
                return new DivideOperation();
            default:
                return null;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建了工厂类有什么好处呢，好处就是，只需要输入运算符号，工厂就能自己实例化出合适的对象，通过多态，返回父类的方法实现了计算器的计算结果。
&lt;code&gt;Main&lt;/code&gt;方法
通过简单工厂模式，让我们在计算加减乘除的时候只需要去增加对应的子类就行了，下面的代码进行加法运行时，通过传入+号让工厂去帮我们实例化子类。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)  
{  
    try  
    {  
        // 简单工厂模式  
        var oper = OperationFactory.CreateOperation(&quot;+&quot;);  
        oper.Num1 = 10;  
        oper.Num2 = 5;  
        Console.WriteLine(oper.GetResult());  
    }    
    catch (Exception e)  
    {        
    Console.WriteLine(&quot;发生异常：&quot; + e.Message);  
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;类图&lt;/h1&gt;
&lt;p&gt;讲完简单工厂模式后，简简单单复现一下类图：
&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;小小知识点&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;接口&lt;/strong&gt;：强调“做什么”，即接口定义了对象应该做什么，而不关心它是如何做的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;虚方法&lt;/strong&gt;：强调“如何做”，即基类提供了一种实现方式，但允许派生类根据需要进行修改。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;参考资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;熟读并反复背诵大话设计模式-程杰出版&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>弹幕树洞项目</title><link>https://blog.pljzy.top/posts/%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE/%E5%BC%B9%E5%B9%95%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE/%E5%BC%B9%E5%B9%95%E6%A0%91%E6%B4%9E%E9%A1%B9%E7%9B%AE/</guid><description>ZY树洞前言ZY树洞是一个基于.NET Core开发的简单的评论系统，主要用于大家分享自己心中的感悟、经验、心得、想法等。好了，不卖关子了，这个项目其实是上班无聊的时候写的，为什么要写这个项目呢？因为我单纯的想吐槽一下工作中的不满而已。</description><pubDate>Sun, 08 Sep 2024 18:22:43 GMT</pubDate><content:encoded>&lt;h1&gt;ZY树洞&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;ZY树洞是一个基于.NET Core开发的简单的评论系统，主要用于大家分享自己心中的感悟、经验、心得、想法等。&lt;br /&gt;
好了，不卖关子了，这个项目其实是上班无聊的时候写的，为什么要写这个项目呢？因为我单纯的想吐槽一下工作中的不满而已。&lt;/p&gt;
&lt;h1&gt;项目介绍&lt;/h1&gt;
&lt;p&gt;项目很简单，主要功能就是提供一个简单的评论系统，用户可以发布自己的评论，然后评论以弹幕的形式展示在页面上。&lt;br /&gt;
项目后端地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://github.com/ZyPLJ/ZYTteeHole&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目前端页面地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ZyPLJ/TreeHoleVue&quot;&gt;ZyPLJ/TreeHoleVue (github.com)&lt;/a&gt; https://github.com/ZyPLJ/TreeHoleVue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前项目测试访问地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http://tree.pljzy.top/ 注意是http,输成https就访问到博客里面去了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;项目特点&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;基于.NET Core开发，跨平台&lt;/li&gt;
&lt;li&gt;简单易用，界面简洁&lt;/li&gt;
&lt;li&gt;匿名评论，不用注册即可发表评论&lt;/li&gt;
&lt;li&gt;弹幕效果，评论以弹幕的形式展示在页面上&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;主要技术&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;ASP.NET Core Web API&lt;/li&gt;
&lt;li&gt;Entity Framework Core&lt;/li&gt;
&lt;li&gt;Sql Server数据库 | Sqlite3数据库&lt;/li&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;项目结构&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;ZYTreeHole 主项目&lt;/li&gt;
&lt;li&gt;ZYTreeHole.Tests 集成测试&lt;/li&gt;
&lt;li&gt;ZYTreeHole_Services 服务层&lt;/li&gt;
&lt;li&gt;ZYTreeHole_Models 模型层&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;项目截图&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;1dd68d7f25886dac.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;后端部署&lt;/h1&gt;
&lt;p&gt;创建数据库，默认用的是sqlite3数据库，如需更改要自行替换连接字符串。连接字符串分为2部分，&lt;code&gt;appsetting.json&lt;/code&gt;中的用于项目访问数据库，而&lt;code&gt;Models&lt;/code&gt;中的&lt;code&gt;MyDbContextDesignFac&lt;/code&gt;类用于CodeFirst模式生成数据库。
如果不更换数据库则不需要更改
直接使用终端，进入&lt;strong&gt;ZYTreeHole_Models&lt;/strong&gt;目录输入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet ef migrations add Init //生成迁移文件
dotnet ef database update //更新数据库
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用dotnet语句需安装&lt;code&gt;.NET SDK&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dotnet.microsoft.com/zh-cn/download&quot;&gt;下载 .NET(Linux、macOS 和 Windows) (microsoft.com)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完成数据库生成后，会在Models层生成一个app.db文件，将该文件剪切到ZYTreeHole 主项目里面去就行了。完成上述步骤即可开始部署，将项目打包成文件夹形式，这里就不多讲了。
我是采用的Docker部署，DockerFile文件项目已经包含进去了。
在打包后端路径中打开终端执行，默认部署为44323端口。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker build -t treehole . --下载镜像
docker run -d -p 44323:44323 -v /...替换成你的打包路径/treehole:/src --name treehole treehole --创建容器
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Docker镜像无法下载问题解决&lt;/h1&gt;
&lt;p&gt;相关链接：&lt;a href=&quot;https://mixuying.com/archives/1719753069678&quot;&gt;国内镜像源下架的解决办法-米续硬 (mixuying.com)&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;待完成的点&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[x] 评论限流&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 关键词过滤&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ ] 将前端弹幕设置滚动频率、速度等写入配置文件或者数据库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ ] 完成后台管理模块的编写。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[ ] 前端页面美化&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;欢迎各位提提意见~.~&lt;/p&gt;
&lt;h1&gt;参考链接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;前端弹幕效果使用开源项目：&lt;a href=&quot;https://github.com/hellodigua/vue-danmaku&quot;&gt;https://github.com/hellodigua/vue-danmaku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;接口限流：&lt;a href=&quot;https://www.cnblogs.com/ZYPLJ/p/17243389.html&quot;&gt;.NET Core WebApi接口ip限流实践 - 妙妙屋（zy） - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;评论关键词过滤：&lt;a href=&quot;https://www.cnblogs.com/deali/p/17910094.html#%E5%B0%8F%E7%AE%A1%E5%AE%B6%E5%AE%A1%E6%A0%B8&quot;&gt;基于.NetCore开发博客项目 StarBlog - (30) 实现评论系统 - 程序设计实验室 - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>使用RabbitMQ做个简单的发送邮件项目</title><link>https://blog.pljzy.top/posts/rabiitmqdemo/%E4%BD%BF%E7%94%A8rabbitmq%E5%81%9A%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E5%8F%91%E9%80%81%E9%82%AE%E4%BB%B6%E9%A1%B9%E7%9B%AE/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/rabiitmqdemo/%E4%BD%BF%E7%94%A8rabbitmq%E5%81%9A%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E5%8F%91%E9%80%81%E9%82%AE%E4%BB%B6%E9%A1%B9%E7%9B%AE/</guid><description>前言好久没有做项目了，这次做一个发送邮件的小项目。发邮件是一个比较耗时的操作，之前在我的个人博客里面回复评论和友链申请是会通过发送邮件来通知对方的，不过当时只是简单的进行了异步操作。那么这次来使用RabbitMQ去统一发送邮件，我是想法是通过调用邮件发送接口，将请求发送到队列。</description><pubDate>Mon, 01 Jul 2024 23:12:57 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;好久没有做项目了，这次做一个发送邮件的小项目。发邮件是一个比较耗时的操作，之前在我的个人博客里面回复评论和友链申请是会通过发送邮件来通知对方的，不过当时只是简单的进行了异步操作。
那么这次来使用RabbitMQ去统一发送邮件，我的想法是通过调用邮件发送接口，将请求发送到队列。然后在队列中接收并执行邮件发送操作。
本文采用简单的点对点模式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在点对点模式中，只会有一个消费者进行消费。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于常用的RabbitMQ队列模式不了解的可以查看往期文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/ZYPLJ/p/17572104.html&quot;&gt;.NET 中使用RabbitMQ初体验 - 妙妙屋（zy） - 博客园 (cnblogs.com)&lt;/a&gt; https://www.cnblogs.com/ZYPLJ/p/17572104.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/fa670520e3df2839.html&quot;&gt;ZY知识库 · ZY - 在.NET Core中使用RabbitMQ (pljzy.top)&lt;/a&gt; https://pljzy.top/blog/post/fa670520e3df2839.html&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;架构图&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;
简单描述下项目结构。项目主要分为生产者、RabbitMQ、消费者这3个对象。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;生产者（Publisher）&lt;/strong&gt;：负责将邮件发送请求发送到RabbitMQ的队列中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RabbitMQ服务器&lt;/strong&gt;：作为消息中间件，用于接收并存储生产者发送的消息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;消费者（Consumer）&lt;/strong&gt;：从RabbitMQ的队列中接收邮件发送请求，并执行实际的邮件发送操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;项目结构&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;RabbitMQEmailProject
&lt;ul&gt;
&lt;li&gt;EamilApiProject 生产者
&lt;ul&gt;
&lt;li&gt;Controllers 控制器&lt;/li&gt;
&lt;li&gt;Service 服务&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RabiitMQClient 消费者
&lt;ul&gt;
&lt;li&gt;Program 主程序&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Model 实体类&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;开始编码(一阶段)&lt;/h1&gt;
&lt;p&gt;首先我们先简单的将生产者和消费者代码完成，让生产者能够发送消息，消费者能够接受并处理消息。代码有点多，不过注释也多很容易看懂。
给生产者和消费者都安装上用于处理RabiitMQ连接的Nuget包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet add package RabbitMQ.Client
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;生产者&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;EamilApiProject&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;配置文件&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;appsetting.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;RabbitMQ&quot;: {  
  &quot;Hostname&quot;: &quot;localhost&quot;,  
  &quot;Port&quot;: &quot;5672&quot;,  
  &quot;Username&quot;: &quot;guest&quot;,  
  &quot;Password&quot;: &quot;guest&quot;  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;控制器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[ApiController]  
[Route(&quot;[controller]&quot;)]  
public class SendEmailController : ControllerBase  
{  
    private readonly EmailService _emailService;  
  
    public SendEmailController(EmailService emailService)  
    {       
	     _emailService = emailService;  
    }  
    [HttpPost(Name = &quot;SendEmail&quot;)]  
    public IActionResult Post([FromBody] EmailDto emailRequest)  
    {        
	    _emailService.SendEamil(emailRequest);  
        return Ok(&quot;邮件已发送&quot;);  
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;服务&lt;/h3&gt;
&lt;p&gt;RabbitMQ连接服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class RabbitMqConnectionFactory :IDisposable  
{  
    private readonly RabbitMqSettings _settings;  
    private IConnection _connection;  
  
    public RabbitMqConnectionFactory (IOptions&amp;lt;RabbitMqSettings&amp;gt; settings)  
    {       
	     _settings = settings.Value;  
    }  
    public IModel CreateChannel()  
    {        
    if (_connection == null || _connection.IsOpen == false)  
        {            
        var factory = new ConnectionFactory()  
            {  
                HostName = _settings.Hostname,  
                UserName = _settings.Username,  
                Password = _settings.Password  
            };  
            _connection = factory.CreateConnection();  
        }  
        return _connection.CreateModel();  
    }  
    public void Dispose()  
    {        
	    if (_connection != null)  
        {            
	        if (_connection.IsOpen)  
            {               
	             _connection.Close();  
            }            
            _connection.Dispose();  
        }    
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发送邮件服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class EmailService
{
    private readonly RabbitMqConnectionFactory _connectionFactory;

    public EmailService(RabbitMqConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }
    public void SendEamil(EmailDto emailDto)
    {
        using var channel = _connectionFactory.CreateChannel();
        var properties = channel.CreateBasicProperties();
        properties.Persistent = true;//消息持久化
        
        var message = JsonConvert.SerializeObject(emailDto);
        var body = Encoding.UTF8.GetBytes(message);

        channel.BasicPublish( string.Empty, &quot;email_queue&quot;, properties, body);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注册服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.Configure&amp;lt;RabbitMqSettings&amp;gt;(builder.Configuration.GetSection(&quot;RabbitMQ&quot;));
builder.Services.AddSingleton&amp;lt;RabbitMqConnectionFactory &amp;gt;();
builder.Services.AddTransient&amp;lt;EmailService&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;实体&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Model&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class EmailDto  
{  
    /// &amp;lt;summary&amp;gt;  
    /// 邮箱地址  
    /// &amp;lt;/summary&amp;gt;  
    public string Email { get; set; }  
    /// &amp;lt;summary&amp;gt;  
    /// 主题  
    /// &amp;lt;/summary&amp;gt;  
    public string Subject { get; set; }  
    /// &amp;lt;summary&amp;gt;  
    /// 内容  
    /// &amp;lt;/summary&amp;gt;  
    public string Body { get; set; }  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class RabbitMqSettings  
{  
    public string Hostname { get; set; }  
    public string Port { get; set; }  
    public string Username { get; set; }  
    public string Password { get; set; }  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;消费者&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;RabiitMQClient&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)  
{  
    var factory = new ConnectionFactory { HostName = &quot;localhost&quot;, Port = 5672, UserName = &quot;guest&quot;, Password = &quot;guest&quot; };  
    using var connection = factory.CreateConnection();  
    using var channel = connection.CreateModel();  
  
    channel.QueueDeclare(queue: &quot;email_queue&quot;,  
        durable: true,//是否持久化  
        exclusive: false,//是否排他  
        autoDelete: false,//是否自动删除  
        arguments: null);//参数  
  
    //这里可以设置prefetchCount的值，表示一次从队列中取多少条消息，默认是1，可以根据需要设置  
    //这里设置了prefetchCount为1，表示每次只取一条消息，然后处理完后再确认收到，这样可以保证消息的顺序性  
    //global是否全局  
    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);  
  
    Console.WriteLine(&quot; [*] 正在等待消息...&quot;);  
  
    //创建消费者  
    var consumer = new EventingBasicConsumer(channel);  
    //注册事件处理方法  
    consumer.Received += (model, ea) =&amp;gt;  
    {  
        byte[] body = ea.Body.ToArray();  
        var message = Encoding.UTF8.GetString(body);  
        var email = JsonConvert.DeserializeObject&amp;lt;EmailDto&amp;gt;(message);  
        Console.WriteLine(&quot; [x] 发送邮件 {0}&quot;, email.Email);  
        //处理完消息后，确认收到  
        //multiple是否批量确认  
        channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);  
    };    //开始消费  
    //queue队列名  
    //autoAck是否自动确认，false表示手动确认  
    //consumer消费者  
    channel.BasicConsume(queue: &quot;email_queue&quot;,  
        autoAck: false,  
        consumer: consumer);  
  
    Console.WriteLine(&quot; 按任意键退出&quot;);  
    Console.ReadLine();  
}	
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;一阶段测试效果&lt;/h1&gt;
&lt;p&gt;一阶段就是消费者和生产者能正常运行。
&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;
可以看到生产者发送邮件之后，消费者能够正常消费请求。那么开始二阶段，将邮件发送代码完成，并实现能够通过队列处理邮件发送。
对于邮件发送失败就简单的做下处理，相对较好的解决方案就是使用死信队列，将发送失败的消息放到死信队列处理，我这里就不用死信队列，对于死信队列感兴趣的可以查看往期文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/ZYPLJ/p/17591838.html&quot;&gt;.NET中使用RabbitMQ延时队列和死信队列 - 妙妙屋（zy） - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/8a8b75ca23896940.html#&quot;&gt;ZY知识库 · ZY - RabbitMQ延时队列和死信队列 (pljzy.top)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;开始编码(二阶段)&lt;/h1&gt;
&lt;p&gt;简单的创建一个用于发送邮件的类，这里使用&lt;code&gt;MailKit&lt;/code&gt;库发送邮件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class EmailService  
{  
	private readonly SmtpClient client;  

	public EmailService(SmtpClient client)  
	{  
		this.client = client;  
	}  

	public async Task SendEmailAsync(string from, string to, string subject, string body)  
	{
		try
		{
			await client.ConnectAsync(&quot;smtp.163.com&quot;, 465, SecureSocketOptions.SslOnConnect); 
			// 认证  
			await client.AuthenticateAsync(&quot;zy1767992919@163.com&quot;, &quot;&quot;);  

			// 创建一个邮件消息  
			var message = new MimeMessage(); 
			message.From.Add(new MailboxAddress(&quot;发件人名称&quot;, from));  
			message.To.Add(new MailboxAddress(&quot;收件人名称&quot;, to));  
			message.Subject = subject;  

			// 设置邮件正文  
			message.Body = new TextPart(&quot;html&quot;)  
			{  
				Text = body  
			};  

			// 发送邮件  
			var response =await client.SendAsync(message);  
			
			// 断开连接  
			await client.DisconnectAsync(true);  
		}
		catch (Exception ex)
		{
			// 断开连接  
			await client.DisconnectAsync(true);  
			throw new EmailServiceException(&quot;邮件发送失败&quot;, ex);  
		}
	}  
}  

public class EmailServiceFactory  
{  
	public EmailService CreateEmailService()  
	{  
		var client = new SmtpClient();  
		return new EmailService(client);  
	}  
}  
public class EmailServiceException : Exception  
{  
	public EmailServiceException(string message) : base(message)  
	{  
	}  

	public EmailServiceException(string message, Exception innerException) : base(message, innerException)  
	{  
	}  
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来我们在消费者中调用邮件发送方法即可，如果不使用死信队列，我们只需要在事件处理代码加上邮件发送逻辑就行了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;consumer.Received += async (model, ea) =&amp;gt;
{
	byte[] body = ea.Body.ToArray();
	var message = Encoding.UTF8.GetString(body);
	
	var email = JsonConvert.DeserializeObject&amp;lt;EmailDto&amp;gt;(message);
	
	// 创建一个EmailServiceFactory实例
	var emailServiceFactory = new EmailServiceFactory();  
	  
	// 使用EmailServiceFactory创建一个EmailService实例  
	var emailService = emailServiceFactory.CreateEmailService();  
	  
	// 调用EmailService的SendEmailAsync方法来发送电子邮件  
	string from = &quot;zy1767992919@163.com&quot;; // 发件人地址  
	string to = email.Email; // 收件人地址  
	string subject = email.Subject; // 邮件主题  
	string emailbody = email.Body; // 邮件正文  
	  
	try  
	{  
		await emailService.SendEmailAsync(from, to, subject, emailbody);  
		Console.WriteLine(&quot; [x] 发送邮件 {0}&quot;, email.Email);
	}  
	catch (Exception ex)  
	{  
		Console.WriteLine(&quot; [x] 发送邮件失败 &quot; + ex.Message);  
		//这里可以记录日志
		//可以使用BasicNack方法，重新回到队列，重新消费
	}  
	
	
	//处理完消息后，确认收到
	//multiple是否批量确认
	channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上面中可以将发送失败的邮件重新放队列，多试几次，这里就不做多余的介绍了。&lt;/p&gt;
&lt;h1&gt;完成效果展示&lt;/h1&gt;
&lt;h2&gt;一封正确的邮件&lt;/h2&gt;
&lt;p&gt;ok，现在展示邮件发送Demo的完整展示。
首先我们来写一个正确的邮箱地址进行发送：
&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;6.jpg&quot; alt=&quot;&quot; /&gt;
可以看到当我们发送请求之后，消费者正常消费了这条请求，同时邮件发送服务也正常执行。&lt;/p&gt;
&lt;h2&gt;多条发送邮件请求&lt;/h2&gt;
&lt;p&gt;那么接下来，我们通过Api测试工具，一次性发送多条邮件请求。其中包含正确的邮箱地址、错误的邮箱地址，看看消费者能不能正常消费呢~
这里简单的发送3条请求，2封正确的邮件地址，一封错误的，看看2封正常邮件地址的能不能正常发送出去。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里有个问题，如果我填的邮件格式是正确的但是这个邮件地址是不存在的，他是能正常发送过去的，然后会被邮箱服务器退回来，这里不知道该怎么判断是否发送成功。所以我这的错误地址是格式就不对的邮件地址，用来模拟因为网络原因或者其他原因导致的邮件发送不成功。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;7.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;8.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;9.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;10.jpg&quot; alt=&quot;&quot; /&gt;
可以看到3条请求都成功了，并且消费者接收到并正确消费了。2条正确邮件也收到了，1条错误的邮件也捕获到了。&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;本文通过使用&lt;code&gt;RabiitMQ&lt;/code&gt;点对点模式来完成一个发送邮件的小项目，通过队列去处理邮件发送。
通过&lt;code&gt;RabbitMQ.Client&lt;/code&gt;库去连接RabbitMQ服务器。
使用&lt;code&gt;MailKit&lt;/code&gt;库发送邮件。
通过使用RabbitMQ来避免邮件发送请求时间长的问题，同时能在消费者中重试、记录发送失败的邮件，来统一发送、统一处理。
不足点就是被退回的邮件不知道该如何处理。
可优化点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以使用&lt;code&gt;WorkQueues&lt;/code&gt;工作队列队列模式将消息分发给多个消费者，适用于消息量较大的情况。&lt;/li&gt;
&lt;li&gt;可以使用死信队列处理发送失败的邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;参考链接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rabbitmq.com/tutorials/tutorial-two-dotnet&quot;&gt;RabbitMQ tutorial - Work Queues | RabbitMQ&lt;/a&gt; https://www.rabbitmq.com/tutorials/tutorial-two-dotnet&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/ZYPLJ/p/17572104.html&quot;&gt;.NET 中使用RabbitMQ初体验 - 妙妙屋（zy） - 博客园 (cnblogs.com)&lt;/a&gt; https://www.cnblogs.com/ZYPLJ/p/17572104.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pljzy.top/blog/post/8a8b75ca23896940.html&quot;&gt;ZY知识库 · ZY - RabbitMQ延时队列和死信队列 (pljzy.top)&lt;/a&gt; https://pljzy.top/blog/post/8a8b75ca23896940.html&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>记录Visual Studio2022运行.NET Framework4.5项目报错</title><link>https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95visual-studio2022%E8%BF%90%E8%A1%8Cnet-framework45%E9%A1%B9%E7%9B%AE%E6%8A%A5%E9%94%99/%E8%AE%B0%E5%BD%95visual-studio2022%E8%BF%90%E8%A1%8Cnet-framework45%E9%A1%B9%E7%9B%AE%E6%8A%A5%E9%94%99/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95visual-studio2022%E8%BF%90%E8%A1%8Cnet-framework45%E9%A1%B9%E7%9B%AE%E6%8A%A5%E9%94%99/%E8%AE%B0%E5%BD%95visual-studio2022%E8%BF%90%E8%A1%8Cnet-framework45%E9%A1%B9%E7%9B%AE%E6%8A%A5%E9%94%99/</guid><description>问题解决公司项目都是.NET Framework的老项目，而我入职的时候电脑也是安装的Visual Studio2019，用了挺久。但是最近出的免费Ai补全的插件不支持，所以我下载了一个2022，不过问题就来了，我用Visual Studio2022去打开公司的老项目会报错</description><pubDate>Sat, 29 Jun 2024 23:35:01 GMT</pubDate><content:encoded>&lt;h1&gt;问题解决&lt;/h1&gt;
&lt;p&gt;公司项目都是&lt;code&gt;.NET Framework&lt;/code&gt;的老项目，而我入职的时候电脑也是安装的&lt;code&gt;Visual Studio2019&lt;/code&gt;，用了挺久。但是最近出的免费Ai补全的插件不支持，所以我下载了一个2022，不过问题就来了，我用&lt;code&gt;Visual Studio2022&lt;/code&gt;去打开公司的老项目会报错，如图：
&lt;img src=&quot;c1e7609ee2f1f0c8af750ba5504ef4b.png&quot; alt=&quot;&quot; /&gt;
当我看到这些报错的时候就很疑惑，删除bin、obj文件重新加载项目生成解决方案都试了没用。正当我百思不得其解的时候，看到了一篇文章提到了如图：
&lt;img src=&quot;ce59b2b76e90c511f921a70c362716e.png&quot; alt=&quot;&quot; /&gt;
我记得组长叫我部署iis的时候都会将支持32位哪里改为true，我就在想会不会就是这个问题。然后我打开了&lt;code&gt;Visual Studio 2022&lt;/code&gt;的web项目设置页面，发现了默认是勾选是64位版本运行项目，如图：
&lt;img src=&quot;2cca65fd66cfd5640447324ab1bede8.png&quot; alt=&quot;&quot; /&gt;
把这个==&amp;lt;span style=&quot;background:#fff88f&quot;&amp;gt;勾选去掉&amp;lt;/span&amp;gt;==之后就能运行项目了，当然前提是安装了这些：
&lt;img src=&quot;37481f99b23abde8499ab36fe395be4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;参考链接&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cnblogs.com/Chowhound/p/17158355.html&quot;&gt;未能加载文件或程序集“XXX.dll”或它的某个依赖项的解决方法 - 睡觉对我非常重要 - 博客园 (cnblogs.com)&lt;/a&gt;  https://www.cnblogs.com/Chowhound/p/17158355.html&lt;/p&gt;
</content:encoded></item><item><title>记录一次Windows下安装RabbitMQ</title><link>https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1windows%E4%B8%8B%E5%AE%89%E8%A3%85rabbitmq/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1windows%E4%B8%8B%E5%AE%89%E8%A3%85rabbitmq/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1windows%E4%B8%8B%E5%AE%89%E8%A3%85rabbitmq/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1windows%E4%B8%8B%E5%AE%89%E8%A3%85rabbitmq/</guid><description>前言周六在公司加班，干完活后越显无聊，想着下载RabbiitMQ做个小项目玩玩。然而这一下就下载了2个小时，真让人头痛。</description><pubDate>Sat, 29 Jun 2024 16:40:43 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;周六在公司加班，干完活后越显无聊，想着下载&lt;code&gt;RabbiitMQ&lt;/code&gt;做个小项目玩玩。然而这一下就下载了2个小时，真让人头痛。
简单的讲一下如何安装吧，网上教程和踩坑文章还是很多的，我讲我感觉有用的文章放在本文末尾。&lt;/p&gt;
&lt;h2&gt;安装地址&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;erlang &lt;a href=&quot;https://www.erlang.org/downloads&quot;&gt;下载 - Erlang/OTP&lt;/a&gt; https://www.erlang.org/downloads&lt;/li&gt;
&lt;li&gt;RabbitMQ &lt;a href=&quot;https://www.rabbitmq.com/docs/install-windows&quot;&gt;Installing on Windows | RabbitMQ&lt;/a&gt; https://www.rabbitmq.com/docs/install-windows&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;安装步骤&lt;/h2&gt;
&lt;p&gt;无脑Next就行&lt;/p&gt;
&lt;h2&gt;环境变量&lt;/h2&gt;
&lt;p&gt;先放图：
&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;
图1、图2变量值替换成你安装的位置。
图3需要编辑系统变量Path，然后添加下面2段代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%ERLANG_HOME%\bin
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;%RABBITQM_SERVER%\sbin
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;测试安装&lt;/h2&gt;
&lt;p&gt;问题就出现在这里，我一直以为我没安装成功，看图：
&lt;img src=&quot;4.png&quot; alt=&quot;&quot; /&gt;
打开控制台输入&lt;code&gt;erl&lt;/code&gt;,和上图一致则是==安装成功==，然后是mq，输入&lt;code&gt;rabbitmq-server start&lt;/code&gt;没有出现Error则启动成功。
然后我看了文章末尾的2篇链接，安装完后都是要输入&lt;code&gt;rabbitmqctl status&lt;/code&gt;来测试是否安装成功，然而我输了很多次都是如图错误
![[Snipaste_2024-06-29_15-07-34.png]]
然后我以为是&lt;code&gt;.erlang.cookie&lt;/code&gt;文件的问题，找了很久也只找到一个文件，网上的教程都说有2个文件，当我准备放弃的时候，我翻看了评论区，然后发现要先启动才行。
正确的流程是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;rabbitmq-server start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rabbitmqctl status&lt;/code&gt;
启动之后输入&lt;code&gt;rabbitmqctl status&lt;/code&gt;就行了 如图：
&lt;img src=&quot;5.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;安装可视化插件&lt;/h2&gt;
&lt;p&gt;在mq安装目录打开控制台输入如下指令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rabbitmq-plugins enable rabbitmq_management
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;成功启动&lt;/h2&gt;
&lt;p&gt;网址：http://127.0.0.1:15672/
账号：guest
密码：guest
&lt;img src=&quot;6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;参考链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;https://blog.csdn.net/qq_25919879/article/details/113055350&lt;/li&gt;
&lt;li&gt;https://blog.csdn.net/xch_yang/article/details/136758177&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>C#中进行单元测试</title><link>https://blog.pljzy.top/posts/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/</guid><description>单元测试前言时隔多个月，终于抽空学习了点新知识，那么这次来记录一下C#怎么进行单元测试，单元测试是做什么的。我相信大部分刚毕业的都很疑惑单元测试是干什么的？在小厂实习了6个月后，我发现每天除了写CRUD就是写CRUD，几乎用不到单元测试。写完一个功能直接上手去测，当然这只是我个人感受，仅供参考。然后当我还在抱怨测试好烦的时候，大佬跟我说为什么不用单元测试和集成测试，我这也是有苦说不出。</description><pubDate>Tue, 25 Jun 2024 23:42:55 GMT</pubDate><content:encoded>&lt;h1&gt;单元测试&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;时隔多个月，终于抽空学习了点新知识，那么这次来记录一下C#怎么进行单元测试，单元测试是做什么的。&lt;/p&gt;
&lt;p&gt;我相信大部分刚毕业的都很疑惑单元测试是干什么的？在小厂实习了6个月后，我发现每天除了写CRUD就是写CRUD，几乎用不到单元测试。写完一个功能直接上手去测，当然这只是我个人感受，仅供参考。&lt;/p&gt;
&lt;p&gt;然后当我还在抱怨测试好烦的时候，大佬跟我说为什么不用单元测试和集成测试，我这也是有苦说不出。要知道光学会理论知识，没有实践作为基础，都是扯淡，入职这么久还真没用过单元测试，吓得我赶紧去找资料学习。&lt;/p&gt;
&lt;p&gt;那么也是通过观看B站某位Up主的视频，然后有点想法写下这篇文章，虽然up主的主题是探究接口的作用和意义，但是视频中也讲解了怎么进行单元测试，所以对于接口理解不够的可以去本文底部观看视频学习。&lt;/p&gt;
&lt;p&gt;那么本篇文章就简单的讲解下C#中如何做单元测试，博主也是处于学习阶段，有不对的地方欢迎指出改正。&lt;/p&gt;
&lt;h1&gt;单元测试简述&lt;/h1&gt;
&lt;p&gt;单元测试（Unit Testing）是软件开发中的一种测试方法，用于验证代码中的最小可测试单元（通常是方法或函数）是否按照预期进行工作。这些单元通常是独立于其他代码部分进行测试的，以确保其正确性和可靠性。&lt;/p&gt;
&lt;p&gt;单元测试的主要作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;确保每个单元能正确执行&lt;strong&gt;预期&lt;/strong&gt;功能&lt;/li&gt;
&lt;li&gt;能够尽快找到&lt;strong&gt;Bug&lt;/strong&gt;的具体位置&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;开始测试&lt;/h1&gt;
&lt;p&gt;本文以当前时间去返回早上好、中午好、晚上好来讲解单元测试。&lt;/p&gt;
&lt;p&gt;通过传入不同的时间（边界值）来确保代码能够正确处理各种情况以及是否达到了预期的功能。&lt;/p&gt;
&lt;p&gt;预期结果为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;早上好...&lt;/li&gt;
&lt;li&gt;中午好...&lt;/li&gt;
&lt;li&gt;晚上好..&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;项目搭建&lt;/h2&gt;
&lt;h3&gt;主程序&lt;/h3&gt;
&lt;p&gt;首先需要创建一个控制台项目，起名为&lt;code&gt;UnitTesting&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;并安装&lt;code&gt;Microsoft.Extensions.DependencyInjection&lt;/code&gt;包，管理IOC容器。&lt;/p&gt;
&lt;p&gt;创建&lt;code&gt;ITimeProvider&lt;/code&gt;接口，并创建&lt;code&gt;SystemTimeProvider&lt;/code&gt;类去实现这个接口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface ITimeProvider
{
    int GetHour();
}
//返回当前时间
public class SystemTimeProvider: ITimeProvider
{
    public int GetHour()
    {
        return DateTime.Now.Hour;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建&lt;code&gt;GreetingService&lt;/code&gt;类&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class GreetingService
{
    private readonly ITimeProvider _timeProvider;

    public GreetingService(ITimeProvider timeProvider)
    {
        _timeProvider = timeProvider;
    }
    /// &amp;lt;summary&amp;gt;
    /// 通过当前时间来打返回问候语
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;name&quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    public string Greet(string name)
    {
        var hour = _timeProvider.GetHour();
        return hour switch
        {
            &amp;lt; 12 =&amp;gt; $&quot;Good Morning,{name}&quot;,
            &amp;lt; 18 =&amp;gt; $&quot;Good Afternoon,{name}&quot;,
            _ =&amp;gt; $&quot;Good Evening,{name}&quot;
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Program.cs&lt;/code&gt;使用IOC容器注入服务并调用Greet方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using Microsoft.Extensions.DependencyInjection;
using UnitTesting.Services;

var container = new ServiceCollection();
container.AddSingleton&amp;lt;ITimeProvider,SystemTimeProvider&amp;gt;();
container.AddTransient&amp;lt;GreetingService&amp;gt;();
var services = container.BuildServiceProvider();

var greetingService = services.GetRequiredService&amp;lt;GreetingService&amp;gt;();
var greeting = greetingService.Greet(&quot;吗喽&quot;);
Console.WriteLine(greeting);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;测试程序&lt;/h3&gt;
&lt;p&gt;用&lt;code&gt;xUnit&lt;/code&gt;模版创建单元测试，名为&lt;code&gt;UnitTesting.Test&lt;/code&gt;,并添加&lt;code&gt;UnitTesting&lt;/code&gt;项目引用，还需安装&lt;code&gt;Moq&lt;/code&gt;包：&lt;/p&gt;
&lt;p&gt;Moq包（全称Mocking Objects in C#，简称Moq）是一个流行的模拟框架，其主要作用在于模拟和验证对象的行为，以支持更加可靠和可重复的测试，简单来讲就是模拟创建对象。&lt;/p&gt;
&lt;p&gt;回到&lt;code&gt;GreetingService&lt;/code&gt;类，这里使用Rider提供的快捷方式创建测试类，当然也可以手动创建。如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;测试流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arrange&lt;/strong&gt;：准备阶段，创建&lt;code&gt;ITimeProvider&lt;/code&gt;的模拟对象&lt;code&gt;provider&lt;/code&gt;，并指定时间参数且调用&lt;code&gt;GetHour()&lt;/code&gt;方法，使用这个模拟对象创建&lt;code&gt;GreetingService&lt;/code&gt;实例。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Act&lt;/strong&gt;：执行阶段，调用&lt;code&gt;GreetingService&lt;/code&gt;的&lt;code&gt;Greet&lt;/code&gt;方法&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assert&lt;/strong&gt;：断言阶段，验证返回的消息是否与预期的结果相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;using JetBrains.Annotations;
using Moq;
using UnitTesting.Services;

namespace UnitTesting.Tes.Services;

[TestSubject(typeof(GreetingService))]
public class GreetingServiceTests
{
    [Fact]
    public void GreetReturnsMorningMessage()
    {
        // Arrange
        var provider = new Mock&amp;lt;ITimeProvider&amp;gt;();
        provider.Setup(x =&amp;gt; x.GetHour()).Returns(10);
        var service = new GreetingService(provider.Object);

        // Act
        var message = service.Greet(&quot;吗喽&quot;);

        // Assert
        Assert.Equal(&quot;Good Morning,吗喽&quot;, message);
    }
    [Fact]
    public void GreetReturnsAfternoonMessage()
    {
        // Arrange
        var provider = new Mock&amp;lt;ITimeProvider&amp;gt;();
        provider.Setup(x =&amp;gt; x.GetHour()).Returns(15);
        var service = new GreetingService(provider.Object);

        // Act
        var message = service.Greet(&quot;吗喽&quot;);

        // Assert
        Assert.Equal(&quot;Good Afternoon,吗喽&quot;, message);
    }
    [Fact]
    public void GreetReturnsEveningMessage()
    {
        // Arrange
        var provider = new Mock&amp;lt;ITimeProvider&amp;gt;();
        provider.Setup(x =&amp;gt; x.GetHour()).Returns(20);
        var service = new GreetingService(provider.Object);

        // Act
        var message = service.Greet(&quot;吗喽&quot;);

        // Assert
        Assert.Equal(&quot;Good Evening,吗喽&quot;, message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;效果截图&lt;/h1&gt;
&lt;p&gt;主程序没什么好讲的，通过当前时间返回问候语。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;测试程序通过3个测试方法测试了3种情况，早上好、中午好、晚上好，并全部测试通过。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;本文讲解了如何创建单元测试，并且通过单元测试来测试Greet方法，在传入不同的时间参数的情况下，判断是否满足3种情况。&lt;/p&gt;
&lt;p&gt;本文提到了IOC容器、依赖注入、Moq、xUnit等知识点。&lt;/p&gt;
&lt;h1&gt;参考链接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;【从单元测试出发探讨接口的作用及意义】 https://www.bilibili.com/video/BV1Ut421V7Sz/?share_source=copy_web&amp;amp;vd_source=fce337a51d11a67781404c67ec0b5084&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/deali/p/17559685.html&quot;&gt;Asp-Net-Core学习笔记：单元测试和集成测试 - 程序设计实验室 - 博客园 (cnblogs.com)&lt;/a&gt; https://www.cnblogs.com/deali/p/17559685.html&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>苹果手机快捷指令➕Numbers自动记账教程</title><link>https://blog.pljzy.top/posts/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4numbers%E8%87%AA%E5%8A%A8%E8%AE%B0%E8%B4%A6%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4/%E8%8B%B9%E6%9E%9C%E6%89%8B%E6%9C%BA%E5%BF%AB%E6%8D%B7%E6%8C%87%E4%BB%A4numbers%E8%87%AA%E5%8A%A8%E8%AE%B0%E8%B4%A6%E6%95%99%E7%A8%8B/</guid><description>苹果手机快捷指令➕Numbers自动记账教程前言,最近迷上了记录自己日常开销，之前一直用的是手动记账app，每次消费完之后需要自己后面空闲的时候补上记录，很不方便，有时候很容易忘记。</description><pubDate>Sun, 16 Jun 2024 20:56:52 GMT</pubDate><content:encoded>&lt;h1&gt;苹果手机快捷指令➕Numbers自动记账教程&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;​    最近迷上了记录自己日常开销，之前一直用的是手动记账app，每次消费完之后需要自己后面空闲的时候补上记录，很不方便，有时候很容易忘记。虽然有的App提供了自动记账功能但是要支付一定的金额开通会员之类的，不然就只能手动录，所以果断放弃这种记账方式。&lt;/p&gt;
&lt;p&gt;​    然后有一段时间使用的是&amp;lt;font color=&apos;blur&apos;&amp;gt;微信记账本&amp;lt;/font&amp;gt;,功能很多，也很方便，可以查看明细，只要是用微信支付的都能被记录下来，但是我觉得还是不够。如果想用支付宝支付是不会被记录下来的，那么闲来无事就研究了一下苹果的快捷指令来记账。下面开始详细讲解，大部分是图片教程，请耐心观看，如果有错误可以及时指出。&lt;/p&gt;
&lt;p&gt;​    对于记账不感兴趣的可以退出去啦。&lt;/p&gt;
&lt;h1&gt;快捷指令&lt;/h1&gt;
&lt;p&gt;我会按照1 2 3 4...标注步骤&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;p&gt;&amp;lt;font color=&apos;red&apos;&amp;gt;脚本搜索建议用开头或结尾的文字搜索，比如搜索步骤2，我会搜&lt;strong&gt;提取文本&lt;/strong&gt;，步骤3我会搜&lt;strong&gt;匹配&lt;/strong&gt;。&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;p&gt;注意如果否则语句，通过观察脚本前方空行查看是否在如果否则语句中。考虑到很多人是没有编程基础，在这里说一下截图中的&lt;strong&gt;如果和否则&lt;/strong&gt;是成对出现的，并且否则后面会接上&lt;strong&gt;结束条件&lt;/strong&gt;语句&lt;/p&gt;
&lt;h2&gt;1-8&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;1-8.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;8-15&lt;/h2&gt;
&lt;p&gt;注意如果否则语句层级关系。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8-15.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;15-19&lt;/h2&gt;
&lt;p&gt;列表对应你记账的类别，根据需求自行添加或删除。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;15-19.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;19-24&lt;/h2&gt;
&lt;p&gt;19对应上面的列表，将列表存放在类别变量中，这里就不细讲作用了。23也是列表，23用于记录是收入还是支出。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;19-24.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;24-27&lt;/h2&gt;
&lt;p&gt;这里要注意26步骤，“将”后面的变量要点击“+”加号一个一个添加上去。&lt;/p&gt;
&lt;p&gt;同时注意27，这条指令作用是回到主屏幕，如果不加这条指令，记账的时候会停留在Numbers页面。&lt;/p&gt;
&lt;p&gt;注意添加到“账单”中的“交易表单”这个是Numbers表格中的文件名，后面会讲。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;24-27.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Numbers表格&lt;/h1&gt;
&lt;p&gt;打开苹果手机自带的&lt;code&gt;Numbers&lt;/code&gt;App，如果没有的话去应用市场下载即可。&lt;/p&gt;
&lt;p&gt;跟着图片步骤做，如果表格玩的厉害的人，可以自定义图表啥的，我这里就用苹果自己的模版了。&lt;/p&gt;
&lt;h2&gt;1&lt;/h2&gt;
&lt;p&gt;创建表格，注意这里表格名称，对应快捷指令24-27中的26添加到“表格名称”，后面交易表单如果没有修改名称可以不用管。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2&lt;/h2&gt;
&lt;p&gt;这里选择个人预算模版&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3&lt;/h2&gt;
&lt;p&gt;创建模版后，创建新的表单。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4&lt;/h2&gt;
&lt;p&gt;点击刚刚创建的表单，点击交易。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;5&lt;/h2&gt;
&lt;p&gt;第4步点击交易后会进入交易表单，点击齿轮图标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;6&lt;/h2&gt;
&lt;p&gt;第5步点击齿轮图标后，点击类别后面的图标。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;7&lt;/h2&gt;
&lt;p&gt;将类别的格式改为自动。按照第6步的操作后，会弹出如图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;8&lt;/h2&gt;
&lt;p&gt;添加一个空白字段&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-8.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;9&lt;/h2&gt;
&lt;p&gt;新增的空白字段为收支类型，格式也是自动。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-9.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;10&lt;/h2&gt;
&lt;p&gt;选择交易，把里面模版自动创建的数据删除掉。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-10.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;11&lt;/h2&gt;
&lt;p&gt;交易表单同理，删除掉就留一个就行了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-11.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;12&lt;/h2&gt;
&lt;p&gt;预算也是数据删除掉，然后类别就是快捷指令15-19步中的19的列表，要一一对应。到这里表格算是完成一半了，但是当你测试录入账单的时候发现预算这个界面的图标都没反应呀，数据也没有，那么这个时候就要用到Excel的知识了，我们要用公式。我下面会讲解我自己使用的公司，你们可以根据自己的需求进行更改。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2-12.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;表格公式&lt;/h1&gt;
&lt;h2&gt;步骤讲解&lt;/h2&gt;
&lt;p&gt;主要用到&lt;code&gt;SUMIFS&lt;/code&gt;函数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SUMIFS(待求和的值，待检验的值，条件，...,条件N)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我这里以早饭类别举例，其他列表公式同理，只是条件改一下就行了，选中每列实际支出单元格，点击单元格，编辑公式。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图片制作有点粗糙，简单来讲一下。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第一个参数：移动到交易页面点击一下总额上面的字母，一定要字母，代表整列数据。&lt;/p&gt;
&lt;p&gt;第二个参数：同样回到交易页面点击交易列表单元格上面的字母。&lt;/p&gt;
&lt;p&gt;第三个参数：这个是预算页面对应的类别了，你当前设置的是那个列表就选择那一个。&lt;/p&gt;
&lt;p&gt;第四个参数：同理，注意后面需要手动输入字符串为&quot;支出&quot;，只统计支出的数据。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;公式一图流&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;3-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-5.jpg&quot; alt=&quot;3-5&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-6.jpg&quot; alt=&quot;3-6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3-7.jpg&quot; alt=&quot;3-7&quot; /&gt;&lt;/p&gt;
&lt;p&gt;觉得条件不够的可以自己加，其实这里就是设置了&lt;strong&gt;实际支出&lt;/strong&gt;列，根据当前&lt;strong&gt;类别&lt;/strong&gt;去统计&lt;strong&gt;支出&lt;/strong&gt;的金额。&lt;/p&gt;
&lt;h1&gt;系统设置&lt;/h1&gt;
&lt;h2&gt;系统设置一图流&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;5-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5-2.jpg&quot; alt=&quot;5-2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5-3.jpg&quot; alt=&quot;5-3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5-4.jpg&quot; alt=&quot;5-4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5-5.jpg&quot; alt=&quot;5-5&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;效果展示&lt;/h1&gt;
&lt;p&gt;在我们支付完成后，双击手机背面触发快捷指令，我这里以我的为例。因为我这个是单笔，他只识别到一笔金额，所以一开始就是选择类型的界面，如果你支付的页面有多个金额，它会弹出要你选择金额，才会进入到这步。那么我这里选择其他。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里会要你添加描述，默认是无，但是不能为空否则录入到表格中会有问题。如果你没有描述点击已完成即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里会弹出选择支出还是收入，其实这个收入这步用不上，我自己就没用，如果不想用这个可以把快捷指令和表格的支出删除掉。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;执行完后，会回到手机主界面。当我们去查看表格的时候可以看到交易表单已经把刚刚记录的一票记录进去了，然后交易表里面也有数据了。预算应该也会同步过去，如果没有同步过去那就是公式设置错误了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;4-5.jpg&quot; alt=&quot;4-5&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;本文图片居多，可能要花费写时间观看，制作不易，各位点个赞支持一下吧。如果看完整篇文章还是没有设置成功可以通过留言、评论的形式联系我。&lt;/p&gt;
&lt;h1&gt;参考连接&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;http://xhslink.com/Aja0vM&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>面试题-01</title><link>https://blog.pljzy.top/posts/%E9%9D%A2%E8%AF%95%E9%A2%98-01/%E9%9D%A2%E8%AF%95%E9%A2%98-01/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E9%9D%A2%E8%AF%95%E9%A2%98-01/%E9%9D%A2%E8%AF%95%E9%A2%98-01/</guid><description>.NET 常问面试题</description><pubDate>Sat, 18 May 2024 15:02:36 GMT</pubDate><content:encoded>&lt;h1&gt;1.eq的值？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;public static DateTime Now =&amp;gt; DateTime.Now;
var eq = Now == Now;
eq == false&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now 属性被定义为返回 DateTime.Now 的一个快捷方式，但这里重要的是你并不是直接调用 DateTime.Now 两次进行比较，而是先调用了 Now 属性一次并将其结果存储在隐式的中间变量中（由编译器生成），然后再次调用 Now 属性并比较这两个结果。
由于这两次对 Now 属性的调用是独立的，并且都发生在几乎相同的时间点，很有可能（但不保证）这两个 DateTime 值会是相同的。但是，从逻辑上讲，由于 Now 属性的每次调用都会返回当前的日期和时间，因此从严格意义上说，这两次调用返回的值应该是不同的（尽管在实际操作中，由于时钟分辨率的原因，它们可能会是相同的）。&lt;/p&gt;
&lt;h1&gt;2.numbers至少继承了什么接口？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;foreach(var i in numbers){
Console.Write(i);
}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至少实现了 &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;或者IEnumerable&lt;/p&gt;
&lt;h1&gt;3.在C#中,a.Equals(b)和a==b有什么区别？&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;默认行为&lt;/strong&gt;：对于引用类型，a.Equals(b) 默认比较引用相等性，而 a == b 也默认比较引用相等性（除非类重写了 == 操作符）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可重写性&lt;/strong&gt;：Equals 方法可以被重写以提供自定义的相等性逻辑，而 == 操作符也可以被重写（通过定义 operator ==），但通常不这么做，因为这会改变语言的基本语义。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用场景&lt;/strong&gt;：Equals 方法通常用于更复杂的相等性检查，尤其是在涉及继承、接口或自定义相等性逻辑的场景中。而 == 操作符则更常用于值类型的比较或简单的引用类型比较（在没有重写的情况下）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能&lt;/strong&gt;：在某些情况下，Equals 方法可能比 == 操作符更慢，因为它可能涉及更多的方法调用和逻辑判断。但是，在大多数情况下，这种性能差异是可以忽略不计的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;空引用&lt;/strong&gt;：如果 a 是 null，那么调用 a.Equals(b) 会抛出 NullReferenceException 异常。而 a == null 是安全的，并且会返回 true 或 false。因此，在比较之前检查 null 通常是一个好习惯。可以使用 ReferenceEquals 方法或 == 操作符来安全地检查两个引用是否都为 null 或是否指向同一对象。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;4.推断解释下面ling 所代表的含义&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;iDbcontext db - ...;
Guid[] clientids ; ....;
// 客户
var dbclient - db.client.AsQueryable();
//  客户联系人
var dbclientlinkman - db.Clientlinkman.AsQueryable();
var query : from c in dbclient
 where clientids.contains(c.id)
 join l in dbClientlinkman on c.id equals l.clie
 ntid into ls
 from l in ls.defaultifempty()
 where l !: null
 select new
 clientname c.clientname,
 linkmanname - l.linkman,
};
var list - query.ToArray(
var clientmap = list.ToDictionary(k =&amp;gt; k.clientname,  v =&amp;gt; v.Linkmanname);
return clientmap;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;查询来源&lt;/strong&gt;：从dbclient（即数据库中的客户表）开始查询。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;过滤条件&lt;/strong&gt;：只选择那些其Id在clientids数组中的客户。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;连接&lt;/strong&gt;：将dbclient中的每个客户与dbClientLinkman（即数据库中的客户联系人表）进行连接。连接条件是客户的Id与联系人的ClientId相匹配。into ls表示将匹配的联系人列表（可能是0个、1个或多个）放入ls中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;左连接&lt;/strong&gt;：使用ls.DefaultIfEmpty()进行左连接。这意味着，即使某个客户在dbClientLinkman中没有匹配的联系人，该客户也会被包含在结果中，但对应的联系人将为null。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再次过滤&lt;/strong&gt;（虽然在这里是不必要的）：由于我们已经使用了DefaultIfEmpty()，所以这一步的where l != null实际上是不必要的，因为DefaultIfEmpty()已经确保了l要么是有效的联系人对象，要么是null。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选择结果&lt;/strong&gt;：为每个匹配的客户-联系人组合创建一个新的匿名对象，该对象包含客户的ClientName和联系人的LinkmanName（如果有的话）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结果转换&lt;/strong&gt;：将查询结果转换为数组，并将该数组转换为一个字典，其中键是客户的ClientName，值是相应的联系人的LinkmanName（如果有的话）。如果一个客户有多个联系人，只有第一个联系人的名字会被添加到字典中（因为字典的键是唯一的）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;简短总结&lt;/strong&gt;：根据clientids数组查询满足条件的客户信息并关联查询出客户联系人表的数据，最后将结果转换为字典。&lt;/p&gt;
&lt;h1&gt;5.关系型数据库的几种事务隔离级别&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读未提交（Read Uncommitted）&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;这是最低的隔离级别。&lt;/li&gt;
&lt;li&gt;一个事务可以读取到其他事务还未提交的数据。&lt;/li&gt;
&lt;li&gt;这种隔离级别可能导致脏读（Dirty Read），即读取到未提交的数据。&lt;/li&gt;
&lt;li&gt;并发性能最高，但一致性最差。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;读已提交（Read Committed）&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;这是大多数数据库系统的默认隔离级别（但不是MySQL的默认隔离级别）。&lt;/li&gt;
&lt;li&gt;一个事务只能读取到其他事务已经提交的数据，避免了脏读问题。&lt;/li&gt;
&lt;li&gt;但仍可能出现不可重复读和幻读问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可重复读（Repeatable Read）&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;一个事务在执行期间读取到的数据始终保持一致，不受其他事务的影响。&lt;/li&gt;
&lt;li&gt;避免了不可重复读问题，但仍可能出现幻读问题。&lt;/li&gt;
&lt;li&gt;MySQL的InnoDB存储引擎默认使用此隔离级别。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;串行化（Serializable）&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;这是最高的隔离级别。&lt;/li&gt;
&lt;li&gt;所有事务必须按顺序依次执行，避免了所有并发问题，如脏读、不可重复读和幻读。&lt;/li&gt;
&lt;li&gt;但牺牲了系统的并发性能，因为事务之间需要等待前一个事务完成才能开始执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;：4种，分别是读未提交、读已提交、可重复读、串行化&lt;/p&gt;
&lt;h1&gt;6.数据库查询题&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Sql server数据库，写出符合要求的sql语句：查询员工表employee中名字name重复且名字长度为2的name字段&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;SELECT name, COUNT(*) AS count  
FROM employee  
WHERE LEN(name) = 2  
GROUP BY name  
HAVING COUNT(*) &amp;gt; 1;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>游戏人生-七龙珠Z卡卡罗特</title><link>https://blog.pljzy.top/posts/%E4%B8%83%E9%BE%99%E7%8F%A0%E5%8D%A1%E5%8D%A1%E7%BD%97%E7%89%B9/%E6%B8%B8%E6%88%8F%E4%BA%BA%E7%94%9F-%E4%B8%83%E9%BE%99%E7%8F%A0z%E5%8D%A1%E5%8D%A1%E7%BD%97%E7%89%B9/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/%E4%B8%83%E9%BE%99%E7%8F%A0%E5%8D%A1%E5%8D%A1%E7%BD%97%E7%89%B9/%E6%B8%B8%E6%88%8F%E4%BA%BA%E7%94%9F-%E4%B8%83%E9%BE%99%E7%8F%A0z%E5%8D%A1%E5%8D%A1%E7%BD%97%E7%89%B9/</guid><description>游戏人生-七龙珠Z卡卡罗特近况从入职到现在也工作了大约7个月了，我的博客已经很少更新技术文章了，主要原因有：工作太忙，压力比较大没有学习到新技术休息时间不够作为一名小厂程序员，每天的工作量还是很饱和的，然后同事也是比较内卷，5.30的下班时间硬是6.00才开始陆续走人。</description><pubDate>Mon, 13 May 2024 22:03:19 GMT</pubDate><content:encoded>&lt;h1&gt;游戏人生-七龙珠Z卡卡罗特&lt;/h1&gt;
&lt;h1&gt;近况&lt;/h1&gt;
&lt;p&gt;从入职到现在也工作了大约7个月了，我的博客已经很少更新技术文章了，主要原因有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;工作太忙，压力比较大&lt;/li&gt;
&lt;li&gt;没有学习到新技术&lt;/li&gt;
&lt;li&gt;休息时间不够&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作为一名小厂程序员，每天的工作量还是很饱和的，然后同事也是比较内卷，5.30的下班时间硬是6.00才开始陆续走人。间接性的导致我每天下班之后没有学习新技术的欲望，然后公司实行的是每月安排2周单休制，如果遇到调休，可能一个月遇不到双休了，比如这次五一虽然得到了5天休息，但是5月份照常安排2周单价加上一周补班，这个月是没有双休了。在这样的工作时长下也是导致我技术文章产出为0的原因之一。&lt;/p&gt;
&lt;p&gt;公司用到的技术也不是很新，总的来说是上班没学到新技术，下班不想学，目前是这个状态，等毕业之后也许会学习新技术，毕业答辩也是压力之一。&lt;/p&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;回到正题，那么为了缓解我的压力，我也是迷上了玩游戏，从我入手这款游戏，一共游玩了25个小时，按照每天2小时的游玩时长，我也是玩了大概12天。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20240513212437.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这款游戏在不打折的情况下是需要&lt;strong&gt;298RMB&lt;/strong&gt;去购买的，然后我是在打折的时候去买的，然后我也是够买了&lt;strong&gt;龙珠Z：卡卡罗-新力量觉醒集DLC&lt;/strong&gt;，也就是可以变身为超赛神。然后当时一共花了170拿下。&lt;/p&gt;
&lt;h1&gt;游戏介绍&lt;/h1&gt;
&lt;p&gt;游戏类型：动作角色扮演&lt;/p&gt;
&lt;p&gt;内容主题：格斗、开发世界、角色扮演&lt;/p&gt;
&lt;p&gt;游戏平台：PC&lt;/p&gt;
&lt;p&gt;发行日期：2020年1月17日（PC）&lt;/p&gt;
&lt;p&gt;游戏角色：孙悟空、贝吉塔、孙悟饭、比克、特兰克斯、悟天克斯、克林、天津饭、孙悟天......&lt;/p&gt;
&lt;p&gt;游戏背景：游戏剧情改编自《&lt;a href=&quot;https://baike.baidu.com/item/%E9%BE%99%E7%8F%A0Z/3105302?fromModule=lemma_inlink&quot;&gt;龙珠Z&lt;/a&gt;》，并采用线性剧情讲述了四个篇章：赛亚人篇、那美克星篇、人造人篇、魔人布欧篇，玩家将根据剧情走向扮演相应的主角进行游玩。&lt;/p&gt;
&lt;p&gt;总的来说就是会带你走一变龙珠Z的剧情，然后游戏里面是有很多支线任务的，除了主线剧情还可以体验到支线的剧情，游戏是开放世界，可以在大世界打击小怪进行升级、也可以采矿、钓鱼、收集材料制作料理，游戏内容还说很丰富的。&lt;/p&gt;
&lt;h1&gt;游戏体验&lt;/h1&gt;
&lt;p&gt;对于没有看过龙珠Z的人来说，这款游戏可以让你沉浸式体验龙珠Z的剧情。对于看过龙珠的人来说，你可以体验到变身超级赛亚人暴打弗利萨、魔人布欧。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240508200426_1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240508210945_1.jpg&quot; alt=&quot;20240508210945_1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240508211457_1.jpg&quot; alt=&quot;20240508211457_1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我这里就只放几张模糊的截图了，第一张图片是DLC里面的内容，可以看到悟空已经可以变身为超赛神了。&lt;/p&gt;
&lt;h1&gt;游玩推荐&lt;/h1&gt;
&lt;p&gt;格斗类游戏，我还是推荐用手柄去玩，当然这只是个人推荐。&lt;/p&gt;
&lt;p&gt;我这边正常来说走完本体所有剧情，偶然会碰到一次无法过关的情况，但是整体来讲还说可以轻松过关的，不需要特意的去提升等级。跟着剧情走基本能过。&lt;/p&gt;
&lt;p&gt;然后游戏很多部分我都没有完全体验，我比较喜欢快节奏，当我打完本体剧情才知道，角色可以升级技能，这也是导致我打boss一次不过的原因之一。&lt;/p&gt;
&lt;p&gt;如果你想入手这款游戏，我建议将&lt;strong&gt;超赛神的DLC&lt;/strong&gt;一同入手，它可以让你快速升级到300级满级，这是我目前发现升级最快的方法，就是用悟空挑战200级的维斯。用挑战得到的神水快速升级。&lt;/p&gt;
&lt;p&gt;Z球，后期升级技能主要材料，当等级达到255级+，可以通偷懒的方式快速获得Z球，这个就自行看攻略吧。&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;游戏内容丰富，建议搭配DLC游玩，不过建议等打折入手~&lt;/p&gt;
&lt;h1&gt;其他链接&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E9%BE%99%E7%8F%A0Z%EF%BC%9A%E5%8D%A1%E5%8D%A1%E7%BD%97%E7%89%B9/23758985?fr=ge_ala&quot;&gt;龙珠Z：卡卡罗特_百度百科 (baidu.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bilibili.com/video/BV1Hk4y1W7Bz/?p=69&amp;amp;share_source=copy_web&amp;amp;vd_source=fce337a51d11a67781404c67ec0b5084&quot;&gt;小宇《七龙珠：卡卡罗特》4090画质拉满︱全DLC流程通关&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>C# LINQ基础差集计算</title><link>https://blog.pljzy.top/posts/linq/linq%E5%9F%BA%E7%A1%80%E5%B7%AE%E5%80%BC%E8%AE%A1%E7%AE%97/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/linq/linq%E5%9F%BA%E7%A1%80%E5%B7%AE%E5%80%BC%E8%AE%A1%E7%AE%97/</guid><description>C# LINQ基础差集计算前言最近开发的时候遇到个需求，接口参数为表的主键集合，用接口传递过来的参数去数据库查询数据，然后返回数据库不存在的数据。举个例子集合 1,2,3,4,5数据库 1,2,3通过查询语句查询，能从数据库查询出1,2,3来，然后与参数对比发现4,5是不存在与数据库的，那么要返回出来。</description><pubDate>Wed, 08 May 2024 15:49:06 GMT</pubDate><content:encoded>&lt;h1&gt;C# LINQ基础差集计算&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;最近开发的时候遇到个需求，接口参数为表的主键集合，用接口传递过来的参数去数据库查询数据，然后返回数据库不存在的数据。&lt;/p&gt;
&lt;p&gt;举个例子&lt;/p&gt;
&lt;p&gt;集合 1,2,3,4,5&lt;/p&gt;
&lt;p&gt;数据库 1,2,3&lt;/p&gt;
&lt;p&gt;通过查询语句查询，能从数据库查询出1,2,3来，然后与参数对比发现4,5是不存在与数据库的，那么要返回出来。这时候就可以用到LINQ的&lt;code&gt;Except&lt;/code&gt;方法。&lt;/p&gt;
&lt;h1&gt;简介&lt;/h1&gt;
&lt;p&gt;在C#中，LINQ的&lt;code&gt;Except&lt;/code&gt;方法用于从第一个集合中移除存在于第二个集合中的所有元素，创建一个新的集合。&lt;/p&gt;
&lt;h1&gt;实践&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;static void Main(string[] args)
{
    List&amp;lt;int&amp;gt; list = [1, 2, 3, 4, 5];//模仿接口参数
    List&amp;lt;int&amp;gt; list2 = [1, 2, 3];//模仿数据库返回数据

    var result = list.Except(list2);
    foreach (var item in result)
    {
    	Console.WriteLine(item); 
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;1.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>HELLO GANSS XS 75T 键盘开箱</title><link>https://blog.pljzy.top/posts/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/</link><guid isPermaLink="true">https://blog.pljzy.top/posts/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/hello_ganss_xs_75t_%E9%94%AE%E7%9B%98%E5%BC%80%E7%AE%B1%E6%B5%8B%E8%AF%84/</guid><description>HELLO GANSS XS 75T 键盘开箱前言也是入职.NET开发有一段时间了，写代码一直用的是公司配的笔记本电脑，键盘很硬。虽然我本身有一款珂芝K75键盘，但是我在家的时候也会打打游戏干嘛的，带去上班不是很方便，所以也是选择了再买一款键盘。</description><pubDate>Tue, 09 Jan 2024 19:48:50 GMT</pubDate><content:encoded>&lt;h1&gt;HELLO GANSS XS 75T 键盘开箱&lt;/h1&gt;
&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;也是入职.NET开发有一段时间了，写代码一直用的是公司配的笔记本电脑，键盘很硬。虽然我本身有一款珂芝K75键盘，但是我在家的时候也会打打游戏干嘛的，带去上班不是很方便，所以也是选择了再买一款键盘。&lt;/p&gt;
&lt;p&gt;买这款键盘之前我也是看中了好几款，有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;狼途LT84&lt;/li&gt;
&lt;li&gt;达尔优EK75&lt;/li&gt;
&lt;li&gt;狼蛛F99&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这几款的价位也是在200-500之间，也是属于我的能力范围内。最终因为一块小屏幕我选择了XS 75T，这块小屏幕可以查看时间，虽然没什么用，但是我就是喜欢这种花里胡哨的东西，并且可以通过驱动上传动图。话不多说看图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5fd3179f625af54afab47e3ca83246b8.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240109193556.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240109193601.jpg&quot; alt=&quot;微信图片_20240109193601&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;配件&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240109194518.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;轴体参数&lt;/h1&gt;
&lt;p&gt;我选择的是月季粉轴，整个轴体按压很轻，适合码代码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240109193609.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;驱动预览&lt;/h1&gt;
&lt;p&gt;这里放出部分图片，作为一款300元价位的键盘，这款驱动的功能还是很不错的。可以自定义动图，灯光以及自定义宏。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Snipaste_2024-01-09_19-25-48.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Snipaste_2024-01-09_19-26-01.png&quot; alt=&quot;Snipaste_2024-01-09_19-26-01&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;正面图&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240109193547.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item></channel></rss>