v1.8.2,最新版已经是 v2.14.1。毕竟要做数据迁移,不如顺便把 harbor 版本也升级到最新版本。如果是 v1.8.2 升级到 v1.9.0 还好说,直接用官方的 prepare 工具升级就完了,但是我这跨越的版本太大了,我的迁移思路是通过 harbor 自带的 复制管理 功功能来同步仓库的所用 docker 镜像,连打包 harbor 数据都省了。
这一步可以不用做,因为我是直接把挂载在群晖上的硬盘挂载到了绿联上,需要找一台 centos 重启启动 v1.8.2 版本的 harbor。
1 | tar cvf data.tar /data |
1 | wget -c https://github.com/goharbor/harbor/releases/download/v2.14.1/harbor-online-installer-v2.14.1.tgz |
系统管理、仓库管理、新建目标
注意这里的访问ID和访问密码就是旧版 harbor 的登录账号及密码,配置上之后可以通过私有镜像。
系统管理、复制管理、新建规则
选中要执行的规则后,点击复制按钮,等待任务执行完成即可。
左 Alt + Fn + Tab
过去,要从一个URL中获取查询参数(如 id),我们通常需要使用正则表达式或一连串的 split 方法,代码冗长且容易出错。
1 | // 以前的方式 |
现在,URLSearchParams 对象让这一切变得无比简单:
1 | //现代的方式 |
内置的 URLSearchParams 不仅代码更短,而且在处理URL编码、多个同名参数等边缘情况时更加健壮可靠。
深拷贝是面试和工作中的常见痛点,最广为人知但有缺陷的方法是 JSON.parse(JSON.stringify(obj)),它无法处理 Date 对象、undefined、等特殊类型。
1 | const original = { |
现在,我们有了原生的、强大的深拷贝工具 structuredClone:
1 | // 现代的方式 |
structuredClone 是官方推荐的深拷贝方式,支持绝大多数数据类型(除函数、DOM节点等),彻底解决了 JSON 方法的弊端。
1 | const products = [ |
ES2023 引入了 Object.groupBy(),让分组操作变得语义化且极其简单。
1 | // 现代的方式 |
Object.groupBy() 将一个意图直接翻译成了一行代码,可读性远超复杂的 reduce 实现。
想象一个场景:用户在搜索框中快速输入,每次输入都触发一次请求。我们只关心最后一次请求的结果。使用
AbortController,实现起来易如反掌。
1 | let controller; |
1 | async function fetchWithTimeout(resource, options ={}, timeout = 8000){ |
JavaScript 是一门强大且灵活的语言,拥有丰富的特性和语法糖。分享下 16 个最常用的 JavaScript 的简写技巧,掌握它们可以让我们编写出更简洁、更优雅的代码,并显著提升开发效率(增加摸鱼时间)。
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
1 | // 传统写法 |
chrome://flags/#unsafely-treat-insecure-origin-as-secure

启用后需要重启 Chrome 浏览器,重启后就能成功调起麦克风。
查看当前设置的麦克风设备:
1 | navigator.mediaDevices.getUserMedia({ audio: true }) |
1 | // 首先请求用户权限(这是必要的,否则设备标签可能被隐藏) |
设计页面介绍:
json 数据格式保存至 localStorage 中。json 数据导出至 Excel 文件中。项目采用 localStorage 来进行页面间的消息存储。
抽奖页通过 setIntval 定时器监听 localStorage 中操作项值的变化,来进行页面中元素展现。
抽奖操控页实现奖品的抽取及操作项状态的变更。
页面设计的尺寸在大屏上展示的效果不理想:可以试试 ctrl - 、ctrl + 缩放下页面。
大屏也只是个屏幕而已,电脑连接上后,选择扩展屏幕,将抽奖页拖动到大屏屏幕,然后全屏展示即可:
Windows:
F11全屏。MacOS:
Command+Ctrl+FChrome窗口最大化(隐藏菜单栏及Docker栏),Command+Shift+FChrome全屏(隐藏Chrome 的 tab 标签栏及地址栏)。
注意原数据格式问题:因甲方提供的是 Excel 文件,其中的人员名单保存到 json 中时要特别注意人名中有可能存在 \n,\t 等特殊字符,这些特殊字符需提前处理掉,不然在中奖名单中就会像这样展示:王\t五。
注意中奖人员姓名拼接问题:甲方提供的人员名单中 姓 与 名 是拆开的。在对其进行合并时要注意中文姓名中间不能加空格,英文姓名则需要加空格。
1 | function isAllChinese(str) { |
注意抽奖端操控便利性问题:鼠标点击不如键位便捷准确,在进行奖品选项选择时可通过监听键盘:数字1、数字2、数字3 来对应奖品:一等奖、二等奖、三等奖。绑定 Enter 键代替鼠标点击 开始抽奖、停止抽奖、返回 按钮。
- 你不知道场控方提供的电脑是否带外接鼠标,场地是否有足够的空间来操作鼠标。警惕:触摸板。
- 第二个为什么要用键盘来代替鼠标的理由:你看看中控台就知道了,全是实体键位操控。
注意采集卡传输分辨率。
如果采集卡传输分辨率是1920*1080,而屏显分辨率是 2048*768。则页面设计的时候最好做两版。因为你不知道场控方是否可以调整采集卡分辨率,调整后是否有背景图失真情况。
在彩排时发现图片及文字在最终屏幕上有变形,经与场控方沟通后才得知采集卡分辨率是1920*1080,而我们是按照屏显 2048*768做的。在配合场控方调整外屏分辨率时,虽然文字及图片显示正常了,但是图片失真很严重。在调回原始分辨率后图片也失真,无法还原到初始状态了。更换到另一个采集卡
因程序是放在场控方提供的电脑上运行,应甲方数据保密要求需处理好善后工作。
清除 localStroage 中的全部数据。
删除抽奖程序:shift + delete 键删除。
这里有个小插曲哈,第一次删除的时候没按
shift键,文件进到回收站了,而回收站又打不开:
Win + R打开cmd命令行。
1 rd /s /q C:$Recycle.Bin
本篇将介绍如何使用免密证书的方式登录 MacOS 系统。
1 | ssh-keygen -t rsa -b 4096 -c "codezm@163.com" |
将公钥证书安装到
192.168.36.47MacOS 机器。
1 | ssh-copy-id -i ~/.ssh/id_rsa.pub codezm@192.168.36.47 |
1 | # 若私钥文件名是 id_rsa,那么 -i ~/.ssh/id_rsa 参数可省略。 |
1 | vim /etc/ssh/sshd_config |
向文件尾部追加以下内容:
1 | # 禁用密码认证 |
重启 sshd 服务,使配置生效。
1 | sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist |
1 | $ log show --predicate 'process == "sshd"' --info --last 10 |
问题原因是由软链引起的。
初衷是想将 .ssh 目录放到 dotfile 中由 Git 统一管理维护,但万万没想到竟然造成 sshd 无法实现免密证书登录。
1 | ln -s /Users/codezm/.config/dotfile/.ssh ~/.ssh |
| 功能 | 快捷键 |
|---|---|
| 截全屏图 | Command+Shift+3 |
| 自定义截图 | Command+Shift+4 |
| 截屏或录屏 | Command+Shift+5 |
| 立即锁定屏幕 | Control + Command + Q |
| 退出登录你的 macOS 用户账户。系统将提示你进行确认。 要在不确认的情况下立即退出登录,请按下 Option-Shift-Command-Q。 | Command + Shift + Q |
| 将最前方的窗口最小化至程序坞。 | Command-M |
| 访达 | |
| 创建一个新文件夹 | Shift-Command-N |
| 推出所选磁盘或宗卷。 | Command-E |
| 打开“桌面”文件夹 | Shift-Command-D |
| 打开“最近使用”窗口,其中会显示你最近查看或更改过的所有文件。 | Shift-Command-F |
| 打开“前往文件夹”窗口。 | Shift-Command-G |
| 打开当前 macOS 用户账户的个人文件夹。 | Shift-Command-H |
| 打开“网络”窗口 | Shift-Command-K |
| 打开“下载”文件夹 | Option-Command-L |
| 前往上一个文件夹。 | Command-左中括号 ([) |
| 前往下一个文件夹。 | Command-右中括号 (]) |
| 打开包含当前文件夹的文件夹。 | Command-上箭头 |
| 在一个新窗口中打开包含当前文件夹的文件夹。 | Command-Control-上箭头 |
| 打开所选项目。 | Command-下箭头 |
graph LR A[快捷键]---AA[fa:fa-apple MacOS操作系统 fa:fa-link] AA-.-AAB[fa:fa-link Typora] AA-.-AAC[fa:fa-link NeoVim] A[快捷键]---AB[fa:fa-windows Windows操作系统 fa:fa-link] A[快捷键]---AC[VSCode fa:fa-link] A[快捷键]---AD[IDEA fa:fa-link] A[快捷键]---AE[Chrome fa:fa-link] A[快捷键]---AF[HHKB键盘图 fa:fa-link] AB-.-ABB[fa:fa-link Typora] AB-.-ABC[fa:fa-link NeoVim] ABC---ABCA[fa:fa-link Vim] click AA "/posts/MacOS/kjj.html" click AB "/posts/Windows/kjj.html" click AC "/posts/VSCode/kjj.html" click AD "/posts/IDEA/kjj.html" click AE "/posts/Chrome/kjj.html" click AF "/images/hhkb.jpg" click AAB "https://support.typora.io/Shortcut-Keys/" click ABCA "https://www.runoob.com/w3cnote/all-vim-cheatsheat.html"
https://zhuanlan.zhihu.com/p/355997933
https://csnotes.gitlab.io/csnotes/tools/markdown/mermaid.html
]]>若依自带了管理后台及服务端,但项目通常还有客户端业务。那客户端如何实现鉴权?最简单的方式是在原有的 sys_user 上增加业务逻辑,但随着项目越做越大耦合度也会成倍增加。那解耦就势在必行。
本篇将介绍如何让客户端拥有一套独立表来实现用户鉴权。完整代码参见。
一个项目有可能有多个业务用户鉴权需求,所有的鉴权都放在这个模块中进行管理。
接下来我们将以创建 news 业务出发,目录文件结构如下:
1 | codezm-auths |
auths/src/main/java/com/codezm/auths/news/config/NewsSecurityConfig.java
1 | package com.codezm.auths.news.config; |
auths/src/main/java/com/codezm/auths/news/config/properties/PermitAllUrlProperties.java
1 | package com.codezm.auths.news.config.properties; |
auths/src/main/java/com/codezm/auths/news/constant/CacheConstants.java
1 | package com.codezm.auths.news.constant; |
auths/src/main/java/com/codezm/auths/news/domain/NewsLoginBody.java
1 | package com.codezm.auths.news.domain; |
auths/src/main/java/com/codezm/auths/news/domain/NewsLoginUser.java
1 | package com.codezm.auths.news.domain; |
auths/src/main/java/com/codezm/auths/news/domain/NewsUser.java
1 | package com.codezm.auths.news.domain; |
auths/src/main/java/com/codezm/auths/news/manager/factory/AsyncFactory.java
1 | package com.codezm.auths.news.manager.factory; |
auths/src/main/java/com/codezm/auths/news/manager/AsyncManager.java
1 | package com.codezm.auths.news.manager; |
auths/src/main/java/com/codezm/auths/news/mapper/LoginUserMapper.java
1 | package com.codezm.auths.news.mapper; |
auths/src/main/java/com/codezm/auths/news/security/context/AuthenticationContextHolder.java
1 | package com.codezm.auths.news.security.context; |
auths/src/main/java/com/codezm/auths/news/security/context/PermissionContextHolder.java
1 | package com.codezm.auths.news.security.context; |
auths/src/main/java/com/codezm/auths/news/security/filter/JwtAuthenticationTokenFilter.java
1 | package com.codezm.auths.news.security.filter; |
auths/src/main/java/com/codezm/auths/news/security/handle/AuthenticationEntryPointImpl.java
1 | package com.codezm.auths.news.security.handle; |
auths/src/main/java/com/codezm/auths/news/security/handle/LogoutSuccessHandlerImpl.java
1 | package com.codezm.auths.news.security.handle; |
auths/src/main/java/com/codezm/auths/news/security/UserPwdAuthenticationProvider.java
1 | package com.codezm.auths.news.security; |
auths/src/main/java/com/codezm/auths/news/security/UserPwdAuthenticationToken.java
1 | package com.codezm.auths.news.security; |
auths/src/main/java/com/codezm/auths/news/service/impl/LoginUserServiceImpl.java
1 | package com.codezm.auths.news.service.impl; |
auths/src/main/java/com/codezm/auths/news/service/ILoginUserService.java
1 | package com.codezm.auths.news.service.impl; |
auths/src/main/java/com/codezm/auths/news/service/LoginService.java
1 | package com.codezm.auths.news.service; |
auths/src/main/java/com/codezm/auths/news/service/TokenService.java
1 | package com.codezm.auths.news.service; |
auths/src/main/java/com/codezm/auths/news/service/UserPwdServiceImpl.java
1 | package com.codezm.auths.news.service; |
auths/src/main/java/com/codezm/auths/news/untils/SecurityUtils.java
1 | package com.codezm.auths.news.untils; |
/auths/src/main/resources/mapper/news/LoginUserMapper.xml
1 |
|
1 | <dependencyManagement> |
ruoyi-framework/pom.xml
1 | <dependencyManagement> |
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityBaseConfig.java
1 | package com.ruoyi.framework.config; |
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
1 | import org.springframework.beans.factory.annotation.Autowired; |
ruoyi-admin/src/main/resources/application.yml
1 | +# token配置 |
1 | package com.codezm.news.controller; |
1 | CREATE TABLE `news_user` ( |
https://github.com/codezm/whistle
1 | FROM node:lts-alpine3.18 |
任何 Git 的 push 动作将触发脚本的执行。本脚本将构建 linux/amd64 平台的 docker 镜像,交叉编译多平台可参见:https://github.com/codezm/whistle/blob/master/.github/workflows/docker.yml
1 | name: Docker Image CI |
ghcr.io 是GitHub Container Registry 的域名。
GitHub Container Registry 是GitHub 提供的容器镜像注册表服务,允许开发者在GitHub 上存储、管理和分享Docker 镜像。
Disable JavaScript 来启用或禁用。需要还原时再输入:Enable JavaScript。| 快捷键 | 功能 |
|---|---|
| ⇪⌘B | 显示/隐藏书签栏 |
| ⌘, | 打开设置页 |
| ⌥⌘L | 下载内容 |
| ⌘Y | 历史记录 |
| ⇪B | 打开书签检索框 |
| ⌃⇥ | 切换至下一个标签页 |
| ⌃⇪⇥ | 切换至上一个标签页 |
默认当前系统版本:
https://www.google.cn/intl/zh-CN/chrome/
Windows 64:
https://www.google.cn/intl/zh-CN/chrome/?standalone=1&platform=win64
Windows 32:
https://www.google.cn/intl/zh-CN/chrome/?standalone=1&platform=win
Mac:
https://www.google.cn/intl/zh-CN/chrome/?standalone=1&platform=mac
Linux:
https://www.google.cn/intl/zh-CN/chrome/?standalone=1&platform=linux
历史版本:
https://www.slimjet.com/chrome/google-chrome-old-version.php
url 的参数说明:
standalone=1:下载最新的完整离线安装包
platform=win64:适用于Windows操作系统,64代表64位
platform=win:如果不写64,就是下载的32位安装包
installdataindex=defaultbrowser: 设置 Chrome 为默认浏览器,
installdataindex=empty:不设置 Chrome 为默认浏览器
extra=stablechannel:指定下载的版本为稳定版,还有其他版本(betachannel、devchannel、canarychannel)分别是测试版、开发版、金丝雀版
Percona XtraBackup(简称PXB)是 Percona 公司开发的一个用于 MySQL 数据库物理热备的备份工具,支持 MySQL(Oracle)、Percona Server 和 MariaDB。
apt and yum package repositories :https://repo.percona.com/percona/yum/release/centos/7/RPMS/x86_64/1 | -- mysql 使用 --secure-file-priv 参数启用,需查看允许导出的目录。 |
导出 school_last1 数据库中所有表的结构
1 | $ mysqldump -uroot -proot -d school_last1 > school_last1-table-structure.sql |
删除表外键(在后期删除表空间时有影响)
1 | # 查看表外键 |
修改数据库名
1 | $ sed -i -e "s/school_last1/school/g" discard.sql |
1 | # on 10.10.16.10 |
xtrabackup 工具参数:
–backup 将备份保存到 target-dir
—target-dir 指定备份目录路径
–datadir 数据库物理路径
–use-memory 导出时可使用的内存限制,默认:100MB
–databases 指定要备份数据库名
mysqldump 导出的sql文件近 6GB,xtrabackup 备份用时不到 6 分钟。
1 | # on 10.10.16.10 |
1 | # on 10.10.51.81 |
1 | # on 10.10.51.81 |
1 | # on 10.10.51.81 |
1 | # on 10.10.51.81 |
1 | # on 10.10.51.81 |
1 | # on 10.10.51.81 |
通过上述方式备份及还原数据库时,支持热备及热还原。中途并未暂停及重启过位于 10.10.16.10 及 10.10.51.81 上的数据库。
| 快捷键 | 功能 |
|---|---|
| win | 打开开始屏幕 |
| win+r | 打开运行窗口 |
| win+d | 快速回桌面 |
| win+i | 设置 |
| win+e | 资源管理器,类似我的电脑 |
| win+l | 快速锁屏 |
| win+s | 快速小娜搜索,比浏览器查百度好多了 |
| win+p | 映射 |
| win+tab | 多工作区域切换 |
| win+pause | 电脑信息 |
| win+x | 快捷菜单 |
| win+prtsc | 全屏截图 截图在资源管理器图片 |
| win+shift+s | win10最骚截图功能 |
| ctrl+p | 快速打印,甚至网页内容都可以打印 |
| ctrl+alt+delete | 任务管理器,系统软中断 |
| shift+delete | 彻底删除 |
| alt+tab | 任务切换 |
| f1 | windows应用程序帮助页面 |
| f2 | 快速重命名 |
| f3 | 资源管理器内快速搜索文件 |
| f4 | 资源管理器中显示地址列表 |
| 以下功能全部基于win+r | |
| cmd | 命令提示符 |
| winver | windows版本信息 |
| calc | 计算器 |
| dxdiag | dx检测工具 |
| mspaint | 画图 |
| msconfig | 修改启动引导 |
| regedit | 注册表编辑器 |
| gpedit.msc | 策略组编辑器 |
1 | pnpm install --save xlsx |
1 | <template> |
| 功能 说明 | MacOS快捷键 | Windows快捷键 |
|---|---|---|
| 核心导航(必会!) | ||
| 快速打开文件 按下后输入文件名,快速跳转到任何文件,神器中的神器! | Cmd + P | |
| 命令面板 VSCode 的“魔法咒语”,所有功能都可以在这里搜索并执行。 | Shift+Cmd+P | Ctrl+Shift+P |
| 聚焦到资源管理器 如果侧边栏已打开,快速将焦点切换到文件资源管理器。 | Cmd + Shift + E | |
| 在打开的文件之间切换 像浏览器标签一样切换最近使用的文件。 | Ctrl + Tab | |
| 快速导航到符号(类、方法、变量等) | Shift+Cmd+O | Ctrl + Shift + O |
| 显示/隐藏侧边栏 最大化编辑区域。 | Cmd + B | |
| 显示/隐藏面板 切换下方面板(问题输出、调试控制台、终端等)的显示。 | Cmd + J | |
| 编辑技巧(大幅提升编码速度) | ||
| 多选相同词 选中一个单词后,按一次选中下一个相同的词,可以同时编辑多处。 | Cmd + D | Ctrl + D |
| 多光标编辑 在任意位置按住 Option并点击鼠标,可以添加多个光标,同时输入。 | Option + 点击 | |
| 向上/向下移动行 快速移动当前行或选中的多行代码。 | Option + ↑/↓ | |
| 向上/向下复制行 快速复制当前行或选中的多行代码。 | Option + Shift + ↑/↓ | |
| 删除行 无需选中,直接删除光标所在行。 | Cmd + Shift + K | |
| 添加/移除行注释 注释或取消注释当前行或选中的多行。 | Cmd + / | |
| 格式化文档 使用 Prettier 等格式化工具自动整理代码格式。 | Option + Shift + F | |
| 下方插入行 无论光标在行中任何位置,直接跳到行尾并换行。 | Cmd + Enter | |
| 切换自动换行 当代码行很长时,开启/关闭自动换行。 | Option + Z | |
| 鼠标拖动竖向列选(当前光标处开始) | Option + Shift + 鼠标向上或向下拖动 | |
| 搜索与替换(快速定位) | ||
| 在文件中查找 当前文件内搜索。 | Cmd + F | |
| 在文件中替换 当前文件内替换。 | Option + Cmd + F | |
| 查找下一个/上一个 在查找模式下快速跳转。 | Cmd + G/ Shift + Cmd + G | |
| 在全局中查找 在整个项目文件夹中搜索,功能非常强大。 | Shift + Cmd + F | Ctrl + Shift + F |
| 在全局中替换 在整个项目文件夹中搜索并替换。 | Shift + Cmd + H | Ctrl + Shift + H |
| 跳转到指定行号 | Ctrl + G | Ctrl + G |
| 代码操作(理解与重构) | ||
| 跳转到定义 跳转到变量、函数或类的定义处。 | F12 | |
| 查看定义 在不跳转的情况下,以小浮窗形式预览定义。 | Option + F12 | |
| 重命名符号 重命名变量、函数等,所有引用处会同步修改。 | F2 | |
| 后退 跳转到定义后,可以快速跳回原来的位置。 | Ctrl + - | |
| 查看引用 显示所有引用该符号的地方。 | Shift + F12 | |
| 快速修复 当光标在有问题的代码上时,触发快速修复(如自动导入)。 | Cmd + . | Ctrl + . |
| 启动或继续调试 | F5 | |
| 停止调试 | Shift + F5 | |
| 重构 显示可用的重构选项(如提取函数、变量等)。 | Shift + Option + F12 | |
| 窗口与标签页管理 | ||
| 拆分编辑器 向右拆分当前编辑器,实现分栏编辑。 | Cmd + | | |
| 聚焦到第1/2/3个编辑组 在拆分后的多个编辑组之间快速切换焦点。 | Cmd + 1/2/3 | |
| 关闭当前标签页 关闭当前活动的编辑器。 | Cmd + W | |
| 关闭所有标签页 先按 Cmd + K,松开后再按 W。 | Cmd + Kthen W | |
| 在编辑器和终端间切换焦点 让光标在编辑器和集成终端之间快速切换。 | Ctrl +`(Tab上方的键) |
| 功能 | MacOS快捷键 | Windows快捷键 |
|---|---|---|
| 创建或消除书签 | Cmd+Option+K | Ctrl+alt+K |
| 跳转到前一个书签 | Cmd+Option+J | Ctrl+alt+J |
| 跳转到后一个书签 | Cmd+Option+L | Ctrl+alt+L |
jsconfig.json 的工作区中有一个定义项目上下文的文件时,JavaScript 体验会得到改善。1 | { |
目录中存在此类文件表明该目录是 JavaScript 项目的根目录。文件本身可以选择列出属于项目的文件、要从项目中排除的文件以及编译器选项。
当使用 Visual Studio Code 编辑器打开存在 jsconfig.json 文件的项目时,可以获得更好的上下文体验。

#### 3.3 复制
]]>
]]>