WordPress 显示链接功能

WordPress 自 3.5 版本以后,默认隐藏了“链接”的功能,如果我们需要添加友情连接,可以借助插件或者修改代码的方式进行操作。但是本人不喜欢安装太多插件,所以使用修改代码的方式显示“链接”功能,进而添加友情链接。

“链接”功能显示方式

将下列代码添加进当前主题的 functions.php 即可:

add_filter('pre_option_link_manager_enabled','__return_true');

将上述代码粘贴至 functions.php 后,点击“更新文件”即可在左侧选择栏中看到“链接”功能。

你还想知道……

如何替换 Gravatar 头像?点击查看解决方案

连接共享打印机提示 Operation could not be completed (error 0x00000709)

连接共享打印机时出现的问题

最近需要使用其他电脑连接的打印机打印内容。通过网络成功查找到对应的机器及相关打印机,但双击连接一直提示“Operation could not be completed (error0x00000709)
Double check the printer name and make sure that the printer is connected to the network.
”,通过不断搜索,最终在微软社区找到了解决办法。

image
如图提示 Operation could not be completed (error0x00000709)

当 Windows 11 尝试连接共享打印机时会出现错误消息 0x00000709,出现此错误是因为默认连接方法在 22H2 发生了更改。更改组策略编辑器中的设置可以解决该问题。

全新打印机策略是导致报错的罪魁祸首:RPC 连接设置。需要将其切换到命名管道,它才能再次工作。

解决办法

非 Windows 11 家庭版

请注意,在继续之前,您应该以管理员身份登录

在 Windows 搜索中键入“组策略”(Group Policy),然后按下 Enter 键。

导航到以下位置:
1. 管理模板 > 打印机
2. 双击打开右侧的配置“RPC 连接设置”。
3. 确保它是“已启用”。
4. 在下面的选项下,从下拉菜单中选择“通过命名管道进行 RPC” 。
5. 关闭该策略,然后打开“打印机浏览”。
6. 确保该选项已启用。

以上是翻译过的内容,原文如下:

This method helped most users to resolve the error. Note that you should be logged in as an administrator before proceeding.

  • Type Group Policy in Windows search and press Enter.
  • Navigate to the following location:
    Administrative Templates > Printers
  • Double-click to open Configure RPC connection settings on the right.
  • Make sure it is enabled.
  • Under Options below, pick RPC over named pipes from the drop-down menu.
  • Close down the policy and then open Printer Browsing.
  • Ensure the option is enabled.
image 1
Configure RPC connection settings

Windows 11 家庭版

对于 Windows 11 家庭版,请尝试注册表编辑(相当于组策略设置):

[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Printers\RPC]

RpcUseNamedPipeProtocol 有 2 个值可以配置:

0:RpcOverTcp(默认)
1:RpcOverNamedPipes
将 0 更改为 1

通过上述操作,我的电脑已经自动安装好打印机驱动并可以正常使用共享打印机了。

以上是我遇到的相关问题解决方案,可能与你所遇到的问题相似或不同,解决方案可能有用或者无法解决,无法解决建议尝试搜索其他相关解决办法。

引用

Windows 11 Error message 0x00000709 while connecting to shared printer

How to fix printing error 0x00000709 (Operation could not be completed) in Windows?

基于 winston 实现 Nest.js 应用日志服务

Nest.js logo
Nest.js Logo

实现 Nest.js 应用日志服务有很多选择,较为出名的有:Log4jswinstonPino

这次就以 winston 为例,记录一下如何实现 Nest.js 应用日志服务。本文参考了搜索引擎中许多教程与案例,如果觉得有任何问题可以留言与我交流。

引入 winston

相关依赖:winston、nest-winston、winston-daily-rotate-file

pnpm install winston nest-winston winston-daily-rotate-file

winston-daily-rotate-file 用于实现日志文件的定期归档。由于应用日志量一般都非常大,因此需要定期自动对日志文件进行轮换、归档与删除。

配置 winston

app.module.ts

import {
  // ...
  Module,
} from '@nestjs/common';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
import 'winston-daily-rotate-file';
// ...

@Module({
  controllers: [],
  imports: [
    // ...
    WinstonModule.forRoot({
      transports: [
        new winston.transports.DailyRotateFile({
          dirname: `logs`, // 日志保存的目录
          filename: '%DATE%.log', // 日志名称,占位符 %DATE% 取值为 datePattern 值。
          datePattern: 'YYYY-MM-DD', // 日志轮换的频率,此处表示每天。
          zippedArchive: true, // 是否通过压缩的方式归档被轮换的日志文件。
          maxSize: '20m', // 设置日志文件的最大大小,m 表示 mb 。
          maxFiles: '14d', // 保留日志文件的最大天数,此处表示自动删除超过 14 天的日志文件。
          // 记录时添加时间戳信息
          format: winston.format.combine(
            winston.format.timestamp({
            	format: 'YYYY-MM-DD HH:mm:ss',
            }),
            winston.format.json(),
          ),
        }),
      ],
    }),
  ],
  // ...
})
export class AppModule { // ... }

在全局中间件、过滤器以及拦截器中记录日志

获取请求头信息的工具方法

getReqMainInfo.ts

import { Request } from 'express';

export const getReqMainInfo: (req: Request) => {
  [prop: string]: any;
} = req => {
  const { query, headers, url, method, body, connection } = req;

  // 获取 IP
  const xRealIp = headers['X-Real-IP'];
  const xForwardedFor = headers['X-Forwarded-For'];
  const { ip: cIp } = req;
  const { remoteAddress } = connection || {};
  const ip = xRealIp || xForwardedFor || cIp || remoteAddress;

  return {
    url,
    host: headers.host,
    ip,
    method,
    query,
    body,
  };
};

在全局中间件中记录日志

logger.middleware.ts

import { Inject, Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from '../../utils/getReqMainInfo';

@Injectable()
export default class LoggerMiddleware implements NestMiddleware {
  // 注入日志服务相关依赖
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  use(req: Request, res: Response, next: NextFunction) {
    // 获取请求信息
    const {
      query,
      headers: { host },
      url,
      method,
      body,
    } = req;

    // 记录日志
    this.logger.info('route', {
      req: getReqMainInfo(req),
    });

    next();
  }
}

在全局异常过滤器中记录日志

uinify-exception.filter.ts

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
  Inject,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from '../../utils/getReqMainInfo';

@Catch()
export default class UnifyExceptionFilter implements ExceptionFilter {
  // 注入日志服务相关依赖
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp(); // 获取当前执行上下文
    const res = ctx.getResponse<Response>(); // 获取响应对象
    const req = ctx.getRequest<Request>(); // 获取请求对象
    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const response = exception.getResponse();
    let msg =
      exception.message || (status >= 500 ? 'Service Error' : 'Client Error');
    if (Object.prototype.toString.call(response) === '[object Object]') {
      if (typeof response === 'string') {
        msg = response;
      }
    }
    const { query, headers, url, method, body } = req;

    // 记录日志(错误消息,错误码,请求信息等)
    this.logger.error(msg, {
      status,
      req: getReqMainInfo(req),
      // stack: exception.stack,
    });

    res.status(status >= 500 ? status : 200).json({ code: 1, msg });
  }
}

在响应拦截器中记录日志

unify-response.interceptor.ts

import {
  CallHandler,
  ExecutionContext,
  Inject,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Request } from 'express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { getReqMainInfo } from '../../utils/getReqMainInfo';

@Injectable()
export class UnifyResponseInterceptor implements NestInterceptor {
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const ctx = context.switchToHttp();
    const req = ctx.getRequest<Request>();

    return next.handle().pipe(
      map(data => {
        this.logger.info('response', {
          responseData: data,
          req: getReqMainInfo(req),
        });
        return {
          code: 0,
          data,
          msg: '成功',
        };
      }),
    );
  }
}

应用全局中间件、过滤器以及拦截器

app.module.ts

import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
import 'winston-daily-rotate-file';
import UnifyExceptionFilter from './common/uinify-exception.filter';
import logger from './common/logger.middleware';
// ...

@Module({
  // ...
  imports: [
    // ...
    WinstonModule.forRoot({
     // ...
    }),
  ],
  providers: [
    // ...
    // 应用全局过滤器
    {
      provide: APP_FILTER,
      useClass: UnifyExceptionFilter,
    },
    // 应用拦截器
    {
      provide: APP_INTERCEPTOR,
      useClass: UnifyResponseInterceptor,
    },
  ],
})
export class AppModule implements NestModule {
  // 应用全局中间件
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(logger).forRoutes({ path: '*', method: RequestMethod.ALL });
  }
}

完成以上配置后,项目目录下就会包含访问及错误信息的日志文件。日志文件将每天自动归档压缩,超过 14 天的日志也将被自动删除。

引用

基于 Winston 实现 NestJS 应用日志服务
NestJS: Setting up file logging daily rotation with winston

Windows 相关知识操作及部分快捷键

之前机缘巧合,搜索了一下 Windows 相关知识,发现有一些知识和快捷键确实不了解,也从没注意到过,在此记录一下作为整理,如果你有其他关于 Windows 的相关知识和快捷键可以与我一同分享。

Windows 相关知识

1. 命令行访问带空格的目录时,必需要加引号,不然访问不到:

e.g. C:\>cd "Program Files\Java"

另最新版的 Windows 系统已经帮你处理了这块,按下 Tab 联想自动会加的,有时候就是用代码执行 bat 的时候需要注意这里。

2. Windows 中一些特殊单词不能作为文件名,例如 auxcom1com2prnconnul,如果你发现有软件用用户文件名作为配置文件夹名称,你可以把自己用户名改成上面那些单词,软件可能就会崩溃。

3. Windows 路径长度最多为 260 个字符。

4. Windows 创建一个没后缀名的文件需要在文件名称后面紧跟一个点,比如 .ignore. 系统会自动识别成 .ignore

5. 文件删除不掉提示被占用,可以通过资源监视器CPU关联句柄里搜索文件,然后结束进程。

6. 使用 PROGRA~1 代替 Program Files 。cmd 访问文件最快的办法是把文件用鼠标拖入 cmd 中。

7. Windows 软件闪退想找错误日志?运行里打开 eventvwr.exe

8. Windows 文件历史记录可以备份文件十分好用,Windows 自带的搜索可以设置搜索文件的内容(包括 TXT、Word、Excel 等文件内容)。

9. 按住 ctrl + shift + alt 再打开任务管理器,任务管理器会进入精简模式,便于在系统资源不足时使用任务管理器。任务管理器卡死崩溃,按 ctrl + shift + esc 可以让崩溃的任务管理器在 10 秒内重新启动。

10. 在开始菜单点关机重启时,按住 shift 键可以修改系统启动模式或进入高级恢复选项。

11. Windows 可以设置在重要操作时要求输入密码:组策略编辑器,Windows 组件,凭据用户界面—要求输入凭据的受信任路径,点击启用。系统 UAC 需要开最高。这样安装软件,修改系统重要设置都需要验证密码。

12. 电脑配置不高,你使用软件比较卡顿时,可以在任务管理器修改进程优先级。正常改为:高于正常。

13. 资源管理器中按住 Shift 键,再按鼠标右键会弹出带有“在此处打开 CMD/PowerShell 窗口”的菜单。

14. 选中文件上按住 Shift 点鼠标右键,菜单里会多出一项复制为路径。

15. Windows 下按住 alt 键双击文件夹会打开该文件夹的属性窗口。

16. 按住 Ctrl+Shift,再单击打开可执行程序,就会通过管理员模式打开。

17. 修改 hosts 文件时,可以按 Win + R 打开“运行”窗口,在输入框中输入 drivers 直接打开 C:\Windows\System32\drivers 目录,之后再自行打开 .\etc\hosts,比一层层目录点进去要省不少事。

18. Windows 系统盘下的 User 目录可以迁移到其他盘符中,具体操作可以看我之前发过的文章《改变 Windows 用户文件夹默认路径 C:/Users》。

Windows 快捷键

win + q (query) 搜索
win + w (write) 手写笔
win + e (explorer) 资源管理器
win + r (run) 运行
win + a (alert) 通知中心
win + s (search) 也是搜索
win + d (disappear) 老板键
win + f (feedback) 系统反馈
win + x 等同于右键点击开始菜单
win + c (cortana) 微软小娜
win + v 剪切板
win + h 语言输入
win + m (minimal) 最小化窗口
win + . emoji
win + ; emoji
win + i 设置
win + p (project) 投影
win + + 放大镜
win + d (desktop) 显示桌面
win + l (lock) 锁屏
win + t (taskbar) 任务栏上固定的应用
win + tab 虚拟桌面切换
win + ctrl + 左右键 切换虚拟桌面
win + shift + s 截图
ctrl + shift + Esc 任务管理器
ctrl + shift + Enter 以管理员权限启动
ctrl + l 激活地址栏,在地址栏中键入 PowerShell 即可自动打开已当前目录路径的 PowerShell
ctrl + w 关闭窗口

引用

Windows 下有哪些程序员平时不太了解,却很重要的知识?

改变 Windows 用户文件夹默认路径 C:/Users

Windows 默认的总用户文件夹总是会在系统盘下,如果你的系统盘为 C 盘,则为: C:\Users ,许多默认文件夹也都会放在这里:

  • 文档、桌面、下载、图片、视频等文件夹都默认在这里,这些文件夹倒是可以改变位置
  • AppData 文件夹默认在用户根目录下,存储了大部分软件的数据、配置,无法被改变位置
  • .config / .ssh / .config / scoop 等配置目录也在用户根目录下,无法改变位置
  • 许多软件的默认数据位置

系统盘符:\Users\用户名\AppData 里面一般有三个文件夹,分别是 Local / LocalLow / Roaming ,简单地来说,都是用来存放软件的配置文件和临时文件的,里面有很多以软件名称或软件公司命名的文件夹,还有用户帐户的配置文件。随着系统使用时间的增加和安装软件的增多, AppData 占用的空间会越来越大。

上面这些目录会导致系统盘占用很大,即使其中有部分可以手动指派其它路径,但是每次指定都很麻烦,重装系统时候备份也不方便(用户目录里有许多细碎的小文件,备份非常慢),还不如将用户目录迁出系统盘,所有软件都用默认路径,多省事。

另外,修改了用户路径后,当安装软件只为用户安装时,默认的安装路径也会到你的用户目录所在盘,大大节省了系统盘空间。

安装 Windows 的时候修改默认用户路径(推荐)

正常安装 Windows

当 Windows 连接到网络的时候有时 Sysprep 会失败,所以建议全程关闭网络连接安装系统。安装系统的方法不多做介绍。安装系统重启后停留在选择地区的配置界面。

进入 Audit Mode(审计模式)

在系统配置选择地区的界面,按下 Ctrl + Shift + F3 ,这时 Windows 会重启,进入 Audit Mode ,然后显示一个 System Preparation Tool(系统准备工具) ,点击取消,将它关闭。

新建 relocate.xml

现在你可以将电脑连接到网络了。

接下来我们要使用 System Preparation Tool (Sysprep) 工具来设置用户路径。这个工具会执行一个 xml 文件中的配置(也就是 relocate.xml)。我们现在只需要一个非常简单的 xml配置文件,只需包含以下内容:

  • Windows 的版本(32 或 64 位)
  • 用户文件夹的新路径(例如 D:/Users

新建 relocate.xml ,并使用记事本打开拷贝以下代码:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
	<settings pass="oobeSystem">
		<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
			<FolderLocations>
				<ProfilesDirectory>D:\Users</ProfilesDirectory>
			</FolderLocations>
		</component>
	</settings>
</unattend>
警告,在操作之前,请先读一下这个:
1. Windows 以字母来标识盘符,但是当安装了 Windows 重启之后,本来你想把用户目录安装到 d 盘,但这个盘符可能会发生改变,比如变成了 e 盘,这个时候就会失败,所以一定要确定好盘符。
2. xml 文件保存到磁盘根目录(不能是 C 盘),例如我把它保存到了 D:\relocate.xml
3. 部分计算机在 Audit Mode 下因为缺少驱动,键盘无法使用,可以借助其他计算机编写,并拷贝,也可以完全用鼠标操作完成,看个人能力。

运行 Sysprep

以管理员身份运行 cmd,首先确保已停止 WMP Network Sharing Service 服务:

net stop wmpnetworksvc

然后运行以下命令:

%windir%\system32\sysprep\sysprep.exe /oobe /reboot /unattend:d:\relocate.xml

上述命令告诉系统从 Windows\System32\Sysprep 运行 Sysprep,执行 D:/relocate.xml 中的指令,为 OOBE (the firlst boot of newly installed Windows) 重启准备系统,最后重启。

完成

完成上述操作后,自动重启进入系统,检查 User 目录已经移动到了 D 盘。

在已经安装好的 Windows 系统上迁移用户目录

警告:操作之前,一定要先创建一个系统映像,做好备份。
对一个 OEM 预先安装的 Windows 使用 Sysprep 是非常危险的。电脑厂商可能有他们自己的 unattended answer file,这样可能就会忽略掉你的 unattended file。在这个过程中可能会出各种错误,所以不建议操作。
如果中途出错了,你的备份文件可以帮助你恢复。
这个操作非常有可能导致你的电脑恢复出厂设置。
警告****1703 或者更高版本,请不要禁用已存在的用户!!!
在 Win10 1703 或更高版本上,千万不要禁用现有用户,因为禁用现有用户可能会让你无法登录 Windows,进而需要重装。

新建 relocate.xml

按照上面说过的步骤新建一个 relocate.xml 文件。

运行 Sysprep

按照上面说过的步骤运行 Sysprep

OOBE

虽然你已经安装了 Windows,但是在 Sysprep 运行之后 OOBE 仍然会运行,这意味着你的电脑会经历初始化程序。

这里有两点需要注意:

  • Windows 要求你输入产品密钥,但是不需要去输入,单击跳过就可以了;
  • 之前的账户还会存在,但是 OOBE 会要求新建一个用户,如果新建的这个用户和已存在的用户名字相同,那就会发生错误。只需要新建一个随意的账户,之后,再把它删掉就可以了;

引用

Windows 如何删除右键菜单中的 “Git Gui Here”和“Git Bash Here”

今天重新安装了 Git 后,发现右击鼠标右侧多出了两个选项“Git Gui Here”和“Git Bash Here”。虽然这样证明我的 Git 已经成功安装了,但还是影响使用感受,遂上网寻找了一下相关的解决方案。

手动修改注册表

  1. Win + R 调出“运行”窗口,在搜索框中输入“regedit”打开注册表编辑器;
  2. 在打开的注册表中通过以下路径进行查找: Computer\HKEY_CLASSES_ROOT\Directory\Background\shell 。在下方就可以看到 git_guigit_shell 这两项内容,将其删除即可。
  3. 关闭注册表之后,在桌面上右击鼠标就能看到 “Git Gui Here”和“Git Bash Here”选项就已经被删除了。

直接使用管理员 CMD(命令提示符)执行删除

如果上述方法比较繁琐,可以尝试使用具有管理员权限的 CMD(命令提示符) 执行以下两条语句:

reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\git_gui" /f
reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\git_shell" /f

Debian 软件仓库镜像

一般情况下,将 /etc/apt/sources.list 文件中 Debian 默认的源地址 http://deb.debian.org/ 替换为镜像地址即可。

Debian Buster 以上版本默认支持 HTTPS 源。如果遇到无法拉取 HTTPS 源的情况,请先使用 HTTP 源并安装:

sudo apt install apt-transport-https ca-certificates

Debian Bookworm 12 软件仓库镜像源

清华大学开源软件镜像站

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware

# deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware

deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
# deb-src https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware

阿里云镜像站

deb https://mirrors.aliyun.com/debian/ bookworm main non-free non-free-firmware contrib 
deb-src https://mirrors.aliyun.com/debian/ bookworm main non-free non-free-firmware contrib
deb https://mirrors.aliyun.com/debian-security/ bookworm-security main
deb-src https://mirrors.aliyun.com/debian-security/ bookworm-security main
deb https://mirrors.aliyun.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb-src https://mirrors.aliyun.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb https://mirrors.aliyun.com/debian/ bookworm-backports main non-free non-free-firmware contrib
deb-src https://mirrors.aliyun.com/debian/ bookworm-backports main non-free non-free-firmware contrib

腾讯云镜像站

deb https://mirrors.tencent.com/debian/ bookworm main non-free non-free-firmware contrib
deb-src https://mirrors.tencent.com/debian/ bookworm main non-free non-free-firmware contrib
deb https://mirrors.tencent.com/debian-security/ bookworm-security main
deb-src https://mirrors.tencent.com/debian-security/ bookworm-security main
deb https://mirrors.tencent.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb-src https://mirrors.tencent.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb https://mirrors.tencent.com/debian/ bookworm-backports main non-free non-free-firmware contrib
deb-src https://mirrors.tencent.com/debian/ bookworm-backports main non-free non-free-firmware contrib

网易镜像站

deb https://mirrors.163.com/debian/ bookworm main non-free non-free-firmware contrib
deb-src https://mirrors.163.com/debian/ bookworm main non-free non-free-firmware contrib
deb https://mirrors.163.com/debian-security/ bookworm-security main
deb-src https://mirrors.163.com/debian-security/ bookworm-security main
deb https://mirrors.163.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb-src https://mirrors.163.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb https://mirrors.163.com/debian/ bookworm-backports main non-free non-free-firmware contrib
deb-src https://mirrors.163.com/debian/ bookworm-backports main non-free non-free-firmware contrib

华为云镜像站

deb https://mirrors.huaweicloud.com/debian/ bookworm main non-free non-free-firmware contrib
deb-src https://mirrors.huaweicloud.com/debian/ bookworm main non-free non-free-firmware contrib
deb https://mirrors.huaweicloud.com/debian-security/ bookworm-security main
deb-src https://mirrors.huaweicloud.com/debian-security/ bookworm-security main
deb https://mirrors.huaweicloud.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb-src https://mirrors.huaweicloud.com/debian/ bookworm-updates main non-free non-free-firmware contrib
deb https://mirrors.huaweicloud.com/debian/ bookworm-backports main non-free non-free-firmware contrib
deb-src https://mirrors.huaweicloud.com/debian/ bookworm-backports main non-free non-free-firmware contrib

Debian Bullseye 11 软件仓库镜像源

网易镜像站

#http://mirrors.163.com/debian/为软件源也可以为其他的 bullseye为版本代号 main non-free contrib区别如下
deb https://mirrors.163.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.163.com/debian/ bullseye main non-free contrib
deb https://mirrors.163.com/debian-security/ bullseye-security main
deb-src https://mirrors.163.com/debian-security/ bullseye-security main
deb https://mirrors.163.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.163.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.163.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.163.com/debian/ bullseye-backports main non-free contrib

腾讯云镜像站

deb https://mirrors.tencent.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.tencent.com/debian/ bullseye main non-free contrib
deb https://mirrors.tencent.com/debian-security/ bullseye-security main
deb-src https://mirrors.tencent.com/debian-security/ bullseye-security main
deb https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib

阿里云镜像站

deb https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib

华为云镜像站

deb https://mirrors.huaweicloud.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.huaweicloud.com/debian/ bullseye main non-free contrib
deb https://mirrors.huaweicloud.com/debian-security/ bullseye-security main
deb-src https://mirrors.huaweicloud.com/debian-security/ bullseye-security main
deb https://mirrors.huaweicloud.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.huaweicloud.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.huaweicloud.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.huaweicloud.com/debian/ bullseye-backports main non-free contrib

清华大学开源软件镜像站

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free

# deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free

deb https://security.debian.org/debian-security bullseye-security main contrib non-free
# deb-src https://security.debian.org/debian-security bullseye-security main contrib non-free

引用

Debian 软件仓库镜像使用帮助 —— 清华大学开源软件镜像站

Docker 相关容器配置

更新时间:2023年7月11日
– 新增 qbittorrent

自从服务器重置以后,重新安装了 Docker,下面记录一下正在使用的容器和相关配置内容。

创建容器间网络

docker network create -d bridge individual

Nginx

docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
-v $PWD/nginx/html:/usr/share/nginx/html \
-v $PWD/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/nginx/log:/var/log/nginx \
-v $PWD/nginx/cert:/etc/nginx/cert \
-v $PWD/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf \
--restart=always \
nginx

MySQL

docker run -d \
--name mysql \
-p 3306:3306 \
-v $PWD/mysql/log:/var/log/mysql \
-v $PWD/mysql/data:/var/lib/mysql \
-v $PWD/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always \
--network individual mysql --lower_case_table_names=1

MySQL 密码修改

ALTER USER 'root'@'%' IDENTIFIED WITH [mysql_native_password, caching_sha2_password] BY '123456';

MySQL 配置

进入 $PWD/mysql/conf/conf.d/ 创建 mysqld.cnf 文件,粘贴以下内容:

[mysqld]
performance_schema_max_table_instances=400
table_definition_cache=400 #缓存
performance_schema=off #用于监控MySQL server在一个较低级别的运行过程中的资源消耗、资源东西
table_open_cache=64 #打开表的缓存
innodb_buffer_pool_chunk_size=64M #InnoDB缓冲池大小调整操作的块大小
innodb_buffer_pool_size=64M #InnoDB 存储引擎的表数据和索引数据的最大内存缓冲区大小

phpMyAdmin

docker run -d \
--name phpmyadmin \
--network individual \
-e PMA_HOST="mysql" \
-p 80:80 \
--restart=always \
phpmyadmin

Redis

创建目录:
mkdir -p $PWD/redis/conf
创建文件:
touch $PWD/redis/conf/redis.conf

docker run -d \
--name redis \
-p 6379:6379 \
--network individual \
-v $PWD/redis/data:/data \
-v $PWD/redis/conf:/etc/redis \
--restart=always \
redis \
redis-server /etc/redis/redis.conf \
--appendonly yes

Warchtowe

docker run -d \
--name watchtower \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock  \
containrrr/watchtower \
--cleanup \
-i 3600

WordPress

docker run -d \
--name wordpress \
--network individual \
--restart=always \
-v $PWD/wordpress:/var/www/html \
-p 8080:80 \
wordpress

Vaultwarden

docker run -d \
--name vaultwarden \
--restart=always \
-v $PWD/vaultwarden:/data \
-p 80:80 \
vaultwarden/server:latest

QianDao

docker run -d \
--name qiandao \
--restart=always \
-p 80:80 \
-v $(pwd)/qiandao/config:/usr/src/app/config \
a76yyyy/qiandao

QingLong

docker run -dit \
--name qinglong \
--restart=always \
-p 5775:5700 \
-v $PWD/ql:/ql/data \
whyour/qinglong:latest

qbittorrent

docker run -d \
  --name=qbittorrent \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -e WEBUI_PORT=8090 \
  -p 9821:6881 \
  -p 9821:6881/udp \
  -p 8090:8090 \
  -v /data/qbittorrent/config:/config \
  -v /data/qbittorrent/downloads:/downloads \
  --restart=always \
  lscr.io/linuxserver/qbittorrent:latest

从 npm 迁移到 pnpm

目前自己写的项目都是使用的是 npm,但是昨天偶然看到了介绍,想把自己的项目从 npm 替换为 pnpm,遂上网搜索了一下迁移教程。

介于 npm 与 pnpm 的区别,可以浏览我先前发布的文章:《npm、yarn、pnpm 各自区别》。

如何将 npm 迁移到 pnpm

需要执行以下步骤:

1. 卸载 npm

首先,将 npm 包从当前项目中卸载

rm -rf node_modules

2. 安装 pnpm

安装 pnpm ,以便可以在项目中使用它

npm install -g pnpm

3. 创建配置文件

在项目目录下创建 .npmrc 的文件

# pnpm 配置
shamefully-hoist=true
auto-install-peers=true
strict-peer-dependencies=false

4. 转换相关文件

package-lock.jsonyarn.lock 转成 pnpm-lock.yaml 文件,保证依赖版本不变

pnpm import

5. 安装依赖包

通过 pnpm 安装依赖包

pnpm install

最后,迁移完成!

在项目正常运行之后,可以删除原本的 package-lock.jsonyarn.lock 文件,保持项目的整洁。

微信小程序 rich-text 超过 2 行显示省略号

rich-text(富文本),如果想实现文本超过两行变成省略号,常规的 div 可以实现,但因为是在微信小程序中,同时使用的是 rich-text 返回的是富文本,所以不能简单的使用以下代码实现:

word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;

因为富文本使用的 rich-text 回显的,想着直接对这个标签写上这个 CSS,发现也无法达到想要的效果。Android 真机可以正常显示,在模拟器上也能正常变成省略号,但 iOS 真机不兼容。

解决办法

在回显的 rich-text 中包裹一层 div,在这个包裹层中写上样式,就可达到超过两行隐藏的效果。

<rich-text style="word-wrap: break-word;word-break: break-all;" nodes="<div style='text-overflow:ellipsis; -webkit-box-orient:vertical;-webkit-line-clamp:2; overflow: hidden; display: -webkit-box;'>{{assetInfo.description}}</div>"></rich-text>

如上演示加粗部分就是需要手工增加的内容,手工在数据外加一层 div 包裹在外即可解决问题。