diff --git a/2023/06/15/article-archive/index.html b/2023/06/15/article-archive/index.html index 7841d1e7..563136d0 100644 --- a/2023/06/15/article-archive/index.html +++ b/2023/06/15/article-archive/index.html @@ -30,7 +30,7 @@ - + @@ -47,9 +47,9 @@ - - - + + + @@ -57,7 +57,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+ +
+
+ +
+
+ + + + + + + + + + + + +
+
+

最近一直在学习 React 高阶知识,因此对于主页的开发再一次停滞了,主要也是一段时间内没有找到什么灵感,今天空闲时间打开又添加了一些另外的功能,其中包括了折腾了好久的主页加载 Spring (不是那个 Spring 啦)弹簧效果和模糊效果。

+ + +

最后的效果在 Grtsinry43 的个人主页 (最近还会考虑继续更新,哭)

+

环境准备

这里我的网站是使用 Nuxt.js 开发的,使用了"nuxt": "^3.12.4",于是就可以使用 Vue.js 的所有语法和写法,当然也包括自定义指令啦!这就为我们的集成添加了可行性

+

前置知识

首先我们要知道 Vue 中的指令是类似v-xxx的形式,比如我们平时常用的 v-model v-for 等等都是其提供的指令,当然也为我们保留了自定义的能力。

+

问题引入

在标准 Vue/Vue+Vite 项目中,其往往位于 /directives 路径,在我们自定义之后在 main.js/main.ts 文件中引入即可

+
1
2
3
4
5
6
7
8
9
import { createApp } from 'vue';
import App from './App.vue';
import scrollSpring from '@/directives/scrollSpring';

const app = createApp(App);

app.directive('scroll-spring', scrollSpring);

app.mount('#app');
+ +

而在 Nuxt.js项目中,其主 app 对象创建与挂载,以及 SSR 实现等都是由框架统一管理,为了引入里定自定义指令,我们要借助 nuxt 强大的插件系统。

+

问题解决

我们可以参考对应的文档: Vue指令

+

其给出了这样一段示例

+
1
2
3
4
5
6
7
8
9
10
11
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// 你可以在这里提供SSR特定的props
return {}
}
})
})
+ +

由于我们无需单独处理 SSR 部分,直接引入插件注册指令即可,Nuxt 会自动扫描并加载 /plugins 路径的文件,无需手动添加。

+

实现这段动画的大致思路就是,首先所有元素默认 opacity 为 0,并且有向下的位移,当元素移动到视口内即添加标签设置为可见,并恢复位置,当然也可以配合 filter blur 等实现模糊渐显的效果,于是写好如下 css

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 初始状态,元素处于下方且不可见,并带有模糊效果 */
.scroll-item {
opacity: 0;
filter: blur(10px); /* 元素模糊 25px */
transform: translateY(20px); /* 元素初始位移 20px */
transition: transform 0.5s ease-out, opacity 0.5s ease-out, filter 0.5s ease-out; /* 为 filter 添加动画 */
}

/* 当元素进入视口时,透明度变为 1,模糊度变为 0,且上移回原位 */
.scroll-in {
opacity: 1;
filter: blur(0); /* 模糊效果消失 */
transform: translateY(0); /* 元素回到原始位置 */
transition: transform 0.5s ease-out, opacity 0.5s ease-out, filter 0.5s ease-out; /* 确保 filter 也有动画 */
}
+ +

有了思路之后就写好对应的指令 js
/plugins/scrollSpring.js

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 导出一个 Nuxt 插件
export default defineNuxtPlugin((nuxtApp) => {
// 定义一个自定义指令 'scroll-spring'
nuxtApp.vueApp.directive('scroll-spring', {
// 当元素被挂载到 DOM 中时调用的钩子
mounted(el) {
// 设置 Intersection Observer 的选项
const options = {
root: null, // 使用浏览器视口作为根元素
rootMargin: '0px', // 根元素的边距
threshold: 0.1 // 交叉的阈值,当 10% 的目标元素在视口内时触发回调
};

// 观察者回调函数
const callback = (entries) => {
entries.forEach(entry => {
// 如果目标元素与视口相交
if (entry.isIntersecting) {
// 添加动画类
el.classList.add('scroll-in');
} else {
// 移出视口时移除动画类
el.classList.remove('scroll-in');
}
});
};

// 创建一个 Intersection Observer 实例,并传入回调函数和选项
const observer = new IntersectionObserver(callback, options);
// 开始观察当前元素
observer.observe(el);
},
// 当元素从 DOM 中卸载时调用的钩子
unmounted(el) {
// 创建一个空的 Intersection Observer 实例
const observer = new IntersectionObserver(() => {});
// 停止观察当前元素
observer.unobserve(el);
}
});
});
+ +

这里我们利用 Intersection Observer ,当元素进入视口触发回调添加类名,移出视口则去掉类名

+

接下来我们只要在对应的元素引入就可以啦!
注意 scroll-itemv-scroll-spring 缺一不可,前者负责决定开始状态,后者是动画和结束效果

+

这里简单贴一个代码片段,也可以参考我主页对应的仓库~
/pages/index.vue

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="slogan font-jb-mono scroll-item" v-scroll-spring>
<p>Coding,</p>
<p>build a better world</p>
<p>together!</p>
</div>
<span class="slogan-cn scroll-item" v-if="locale === 'zh'" v-scroll-spring>{{ t('slogan.cn') }}</span>
<br/>
<div class="button-container scroll-item" v-scroll-spring>
<UButton to="https://github.com/grtsinry43" target="_blank"
icon="i-grommet-icons:github" style="vertical-align: -4px"
class="btn-item github-link bg-blue-400 text-black dark:bg-blue-800 dark:text-white">
{{ t('buttons.github') }}
</UButton>
<UButton :label="t('buttons.learningLog')" color="gray" class="btn-item scroll-item" v-scroll-spring>
<template #trailing>
<UIcon name="i-heroicons-arrow-right-20-solid" class="w-5 h-5 btn-more-icon"/>
</template>
</UButton>
<UButton color="gray" class="btn-item scroll-item" disabled v-scroll-spring>
{{ t('buttons.resume') }}
</UButton>
</div>
+ +

最后效果

https://blogoss.grtsinry43.com/uploads/24/10/dfd9b723931112b166843ff4b28d68fa.gif/improved

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ +

评论

+ +

在这里留下你的评论吧~

+ + +
+ +
+ + + + + + +
+ + + + + + + + + + +
+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + + + diff --git a/404.html b/404.html index 850417b1..83cd4394 100644 --- a/404.html +++ b/404.html @@ -30,7 +30,7 @@ - + @@ -46,13 +46,13 @@ - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ +
+
+ + +

Grtsinry43’s Blog

+ + +

一个认真学习前端的大二学生 总之岁月漫长,然而值得等待

+ +
+ +
+ + +
+ + +
+ +
+
+ +
+ + +
+ + + + + + + + + + +
+
+ + + + + + + + + + +

+ +

+ +
+ +

最近一直在学习 React 高阶知识,因此对于主页的开发再一次停滞了,主要也是一段时间内没有找到什么灵感,今天空闲时间打开又添加了一些另外的功能,其中包括了折腾了好久的主页加载 Spring (不是那个 Spring 啦)弹簧效果和模糊效果。

+ +
+ +
+
+ + + + + + + + + 技术学习 + + + + +
+ + + +
+ + +
+ +
+ + + +
+ + + + + + +
+ + + + + + + + + +
+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + + + diff --git a/archives/2024/index.html b/archives/2024/index.html index 8a6dcfd2..d198ef9c 100644 --- a/archives/2024/index.html +++ b/archives/2024/index.html @@ -30,7 +30,7 @@ - + @@ -46,11 +46,11 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ +
+
+ + +

Grtsinry43’s Blog

+ + +

一个认真学习前端的大二学生 总之岁月漫长,然而值得等待

+ +
+ +
+ + +
+ + +
+ +
+
+ + + + + + + + + + + +
+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + + + diff --git a/atom.xml b/atom.xml index 30e22481..90d3aab1 100644 --- a/atom.xml +++ b/atom.xml @@ -6,7 +6,7 @@ - 2024-09-18T15:46:06.398Z + 2024-11-29T03:25:20.877Z https://blog.grtsinry43.com/ @@ -16,12 +16,39 @@ Hexo + + 学习分享|利用Vue自定义指令(directives)实现全站动画效果 + + https://blog.grtsinry43.com/2024/10/12/vue3-spring-animation/ + 2024-10-12T13:19:25.259Z + 2024-11-29T03:25:20.877Z + + 最近一直在学习 React 高阶知识,因此对于主页的开发再一次停滞了,主要也是一段时间内没有找到什么灵感,今天空闲时间打开又添加了一些另外的功能,其中包括了折腾了好久的主页加载 Spring (不是那个 Spring 啦)弹簧效果和模糊效果。

最后的效果在 Grtsinry43 的个人主页 (最近还会考虑继续更新,哭)

环境准备

这里我的网站是使用 Nuxt.js 开发的,使用了"nuxt": "^3.12.4",于是就可以使用 Vue.js 的所有语法和写法,当然也包括自定义指令啦!这就为我们的集成添加了可行性

前置知识

首先我们要知道 Vue 中的指令是类似v-xxx的形式,比如我们平时常用的 v-model v-for 等等都是其提供的指令,当然也为我们保留了自定义的能力。

问题引入

在标准 Vue/Vue+Vite 项目中,其往往位于 /directives 路径,在我们自定义之后在 main.js/main.ts 文件中引入即可

1
2
3
4
5
6
7
8
9
import { createApp } from 'vue';
import App from './App.vue';
import scrollSpring from '@/directives/scrollSpring';

const app = createApp(App);

app.directive('scroll-spring', scrollSpring);

app.mount('#app');

而在 Nuxt.js项目中,其主 app 对象创建与挂载,以及 SSR 实现等都是由框架统一管理,为了引入里定自定义指令,我们要借助 nuxt 强大的插件系统。

问题解决

我们可以参考对应的文档: Vue指令

其给出了这样一段示例

1
2
3
4
5
6
7
8
9
10
11
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// 你可以在这里提供SSR特定的props
return {}
}
})
})

由于我们无需单独处理 SSR 部分,直接引入插件注册指令即可,Nuxt 会自动扫描并加载 /plugins 路径的文件,无需手动添加。

实现这段动画的大致思路就是,首先所有元素默认 opacity 为 0,并且有向下的位移,当元素移动到视口内即添加标签设置为可见,并恢复位置,当然也可以配合 filter blur 等实现模糊渐显的效果,于是写好如下 css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 初始状态,元素处于下方且不可见,并带有模糊效果 */
.scroll-item {
opacity: 0;
filter: blur(10px); /* 元素模糊 25px */
transform: translateY(20px); /* 元素初始位移 20px */
transition: transform 0.5s ease-out, opacity 0.5s ease-out, filter 0.5s ease-out; /* 为 filter 添加动画 */
}

/* 当元素进入视口时,透明度变为 1,模糊度变为 0,且上移回原位 */
.scroll-in {
opacity: 1;
filter: blur(0); /* 模糊效果消失 */
transform: translateY(0); /* 元素回到原始位置 */
transition: transform 0.5s ease-out, opacity 0.5s ease-out, filter 0.5s ease-out; /* 确保 filter 也有动画 */
}

有了思路之后就写好对应的指令 js
/plugins/scrollSpring.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 导出一个 Nuxt 插件
export default defineNuxtPlugin((nuxtApp) => {
// 定义一个自定义指令 'scroll-spring'
nuxtApp.vueApp.directive('scroll-spring', {
// 当元素被挂载到 DOM 中时调用的钩子
mounted(el) {
// 设置 Intersection Observer 的选项
const options = {
root: null, // 使用浏览器视口作为根元素
rootMargin: '0px', // 根元素的边距
threshold: 0.1 // 交叉的阈值,当 10% 的目标元素在视口内时触发回调
};

// 观察者回调函数
const callback = (entries) => {
entries.forEach(entry => {
// 如果目标元素与视口相交
if (entry.isIntersecting) {
// 添加动画类
el.classList.add('scroll-in');
} else {
// 移出视口时移除动画类
el.classList.remove('scroll-in');
}
});
};

// 创建一个 Intersection Observer 实例,并传入回调函数和选项
const observer = new IntersectionObserver(callback, options);
// 开始观察当前元素
observer.observe(el);
},
// 当元素从 DOM 中卸载时调用的钩子
unmounted(el) {
// 创建一个空的 Intersection Observer 实例
const observer = new IntersectionObserver(() => {});
// 停止观察当前元素
observer.unobserve(el);
}
});
});

这里我们利用 Intersection Observer ,当元素进入视口触发回调添加类名,移出视口则去掉类名

接下来我们只要在对应的元素引入就可以啦!
注意 scroll-itemv-scroll-spring 缺一不可,前者负责决定开始状态,后者是动画和结束效果

这里简单贴一个代码片段,也可以参考我主页对应的仓库~
/pages/index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="slogan font-jb-mono scroll-item" v-scroll-spring>
<p>Coding,</p>
<p>build a better world</p>
<p>together!</p>
</div>
<span class="slogan-cn scroll-item" v-if="locale === 'zh'" v-scroll-spring>{{ t('slogan.cn') }}</span>
<br/>
<div class="button-container scroll-item" v-scroll-spring>
<UButton to="https://github.com/grtsinry43" target="_blank"
icon="i-grommet-icons:github" style="vertical-align: -4px"
class="btn-item github-link bg-blue-400 text-black dark:bg-blue-800 dark:text-white">
{{ t('buttons.github') }}
</UButton>
<UButton :label="t('buttons.learningLog')" color="gray" class="btn-item scroll-item" v-scroll-spring>
<template #trailing>
<UIcon name="i-heroicons-arrow-right-20-solid" class="w-5 h-5 btn-more-icon"/>
</template>
</UButton>
<UButton color="gray" class="btn-item scroll-item" disabled v-scroll-spring>
{{ t('buttons.resume') }}
</UButton>
</div>

最后效果

https://blogoss.grtsinry43.com/uploads/24/10/dfd9b723931112b166843ff4b28d68fa.gif/improved

]]>
+ + + <p>最近一直在学习 React 高阶知识,因此对于主页的开发再一次停滞了,主要也是一段时间内没有找到什么灵感,今天空闲时间打开又添加了一些另外的功能,其中包括了折腾了好久的主页加载 Spring (不是那个 Spring 啦)弹簧效果和模糊效果。</p> + + + + + + + + + + + + + + +
+ 折腾记录|使用 Nuxt.js 重写个人主页,使用 SSR 优化 SEO ,实现一些期待已久的效果 https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ - 2024-09-18T10:09:49.000Z - 2024-09-18T15:46:06.398Z + 2024-09-18T18:09:49.000Z + 2024-11-29T03:26:20.565Z 在 22 年刚创建个人主页的时候,由于我的技术水平不够,只能用一些 wordpress typecho 这种直观的工具,后来因为换域名等等一系列的问题就被搁置了…再后来为了过备案,用图形化工具和 bootstrap 糊了一个,而如今熟练掌握 Vue 和 React 等框架之后,也到了完全重写的时候了,于是就有了这段记录。

关键词:Vue SSR,Nuxt.js

网页的开发一直在持续哇…本文章会持续跟进更新

最后链接:https://www.grtsinry43.com/

框架选择

首先,对于这种主页类的网站,单纯的 Vue React SPA(单页面应用)肯定是不行的,比如说这里我们使用 pure-admin 模板创建的一个后台系统(Vue3),对于搜索引擎来说不会等待页面完全加载和渲染,而抓到的这些内容无法分析网站的关键词和主题等,导致很难被搜索引擎排名考前,因此我们不得不从历史中汲取经验,从服务端生成静态网页,到了客户端渲染的单页面应用,又回到了服务端渲染

这样是很难做好 SEO 的

对于个人主页这种比较小的项目,我更喜欢使用 Vue 来完成开发,也就是其对应的 SSR 框架——Nuxt.js

快速上手

由于要使用 NuxtUI,我们便可以使用官方的创建工程的脚手架

1
npx nuxi@latest init -t ui [项目名称]

创建好项目之后,我们便可以像正常写 Vue 一样来进行开发啦

前置准备工作

在代码块以及项目名称中,我们选用一个等宽而且适用于代码的字体 JetBrains Mono,于是我们可以在 assets/fonts.css 中这样进行引入

1
2
3
4
5
6
7
8
9
10
11
@font-face {
font-family: 'JetBrains Mono';
src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
}

.font-jb-mono {
/* 设置fallback防止出现宋体 */
font-family: 'JetBrains Mono', 'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Console', 'Microsoft YaHei', 'WenQuanYi Micro Hei', monospace;
}

注意这里要设置好 fallback 字体,因为某些 Windows 系统(雾)默认会回落到宋体,导致中文字体不堪入目

以后当我们需要使用的时候只需要挂上这个类名就好

防止掉头发

经典防止掉头发几件套:assets/global.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

a {
text-decoration: none;
color: inherit;
}

ul {
list-style: none;
}

疑难解决方案与创新点

桌面与移动端导航栏适配

为了达到最完美的使用效果,我直接写了 NavBarNavBarMobile 两个组件,通过简单的媒体查询来进行切换

1
2
3
4
5
6
7
8
9
@media (max-width: 800px) {
.nav-bar-desktop {
display: none;
}

.nav-bar-mobile {
display: block;
}
}

对于移动段的 Navbar,我选择了可收起菜单来优化体验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const toggleMenu = () => {
isMenuOpen.value = !isMenuOpen.value
}

const toggleLocale = () => {
locale.value = locale.value === 'en' ? 'zh' : 'en';
};
</script>

<template>
<div
class="nav-container fixed w-full bg-opacity-80 bg-blue-50 text-blue-950 dark:bg-opacity-80 dark:bg-black dark:text-white">
<UContainer class="flex flex-row items-center justify-between nav-inner">
<div class="nav-logo">
<NuxtLink :to="localePath('/')" class="font-bold">{{ $t('homePageTitle') }}</NuxtLink>
</div>
<!-- Toggle Button for Mobile Menu -->
<UButton class="lg:hidden bg-opacity-0 dark:bg-opacity-0" @click="toggleMenu"
icon="i-heroicons:bars-3-bottom-right"
square
color="gray"
>
</UButton>
<!-- Theme Toggle Button -->
<div class="theme-option lg:block">
<UToggle
on-icon="i-heroicons-moon-20-solid"
off-icon="i-heroicons-sun-20-solid"
:model-value="colorMode.preference === 'dark'"
@change="toggleTheme"
/>
</div>
<!-- Icons Container -->
<div class="actions-container hidden lg:grid">
<Icon class="language-toggle-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-heroicons-language" @click="toggleLocale"/>
<Icon class="rss-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-heroicons-rss"/>
<a href="https://github.com/grtsinry43/home-web" target="_blank">
<Icon class="github-icon hover:text-blue-400 dark:hover:text-blue-600" name="i-grommet-icons:github"/>
</a>
</div>
</UContainer>

<!-- Mobile Navigation Menu -->
<div v-show="isMenuOpen"
class="nav-extend-container flex flex-col items-center bg-blue-50 bg-opacity-85 dark:bg-black dark:bg-opacity-80 backdrop-blur-lg">
这里就是菜单项目啦
</div>
</div>
</template>

深浅色模式的极不优雅解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import {onMounted} from "vue";
const colorMode = useColorMode();

const toggleTheme = () => {
if (colorMode.preference === 'system') {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark';
buttonState.value = colorMode.preference === 'dark';
} else {
colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark';
buttonState.value = colorMode.preference === 'dark';
}
};

const buttonState = ref(false);

onMounted(() => {
// 根据最开始的主题设置按钮的图标
buttonState.value = colorMode.value === 'dark';
})

这里深色模式的实现有点太不优雅了,我发现 NuxtUI 官网确实有一个跟随主题的开关,但是自己实现起来就是很奇怪,对于输出的 colorMode 有两个用的上的属性,一个是 preference 对应偏好主题(light dark system),一个是 value 对应当前主题(light dark),由于偏好能被保存下来,于是选择在切换按钮时改变 preference 的对应的值

当组件被挂载(onMounted),首先根据 value 设置初始的状态,当点击切换时,对于当前是否偏好系统要采取不同的方式来切换,不知道大佬们有没有什么好办法,或者过几天我再看看 Nuxt 源码

]]>
@@ -47,8 +74,8 @@ 学习分享|使用 Spring Boot + MyBatisPlus 提高效率,简化开发 https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ - 2024-08-10T16:05:33.000Z - 2024-08-11T04:22:45.760Z + 2024-08-11T00:05:33.000Z + 2024-11-29T03:26:20.565Z 最近一段时间,由于一些项目的需求,于是被迫用很快的速度学完了 Spring Framework,SpringMVC,Spring Boot。

然而实际上,我认为学习后端框架原理,前端的脚手架开发,搞一些基础建设是远远比每天写单调简单的业务逻辑要收获更多的,就是更多还是要有解决问题的能力和创新进步的想法吧,所以写业务逻辑当然是越省时间越好,机械操作和基础代码就越快搞定越好,这引出了我们为什么要使用 MyBatis-Plus

首先是它的官网快速上手部分:点我跳转

基础使用(利用提供的类进行增删改查)

首先在 maven 的依赖中添加 (最新版在 Maven Repository 查找)

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>

同步依赖后配置注解扫描 mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.grtsinry43.projectpackage;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.grtsinry43.projectpackage.mapper")
public class SimpleBackendApplication {

public static void main(String[] args) {
SpringApplication.run(SimpleBackendApplication.class, args);
}

}

下面我们先创建实体类(model)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.grtsinry43.projectpackage.model;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.sql.Timestamp;

/**
* @author grtsinry43
* @date 2024/8/11 11:08
* @description user 的实体类
*/
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Boolean gender;
private Integer age;
private String phone;
private String password;
private Timestamp createAt;
}

这里使用了 Lombok 的 @Data 注解来自动生成 GetterSetter 方法、toString 方法、hashCode 方法、equals 方法。

下面我们来写对应的 Mapper,在这里,MyBatis-Plus 提供了一个 BaseMapper,我们只需要继承这个接口就可以直接获得增删改查的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.grtsinry43.projectpackage.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.grtsinry43.projectpackage.model.User;

/**
* @author grtsinry43
* @date 2024/8/11 11:13
* @description 用户的 Mapper 接口
*/
public interface UserMapper extends BaseMapper<User> {
}

当然,如果需要一些自定义的 sql 语句,也可以自行配置,这里采用最简单的来举例

在 resources/mapper 新建 UserMapper.xml

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.grtsinry43.projectpackage.mapper.UserMapper">
<select id="selectUsersOlderThan" resultType="com.grtsinry43.projectpackage.model.User">
SELECT * FROM user WHERE age > #{age}
</select>
</mapper>
1
2
3
4
public interface UserMapper extends BaseMapper<User> {
@Select("select * from user where age > #{age}")
List<User> selectUsersOlderThan(Integer age);
}代码生成器

然后在 Service 中,传入 Mapper 和对应的数据模型,继承 ServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.grtsinry43.projectpackage.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.grtsinry43.projectpackage.mapper.UserMapper;
import com.grtsinry43.projectpackage.model.User;
import org.springframework.stereotype.Service;

@Service
public class UserService extends ServiceImpl<UserMapper, User> {
private final UserMapper userMapper;

public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
}

这样,我们的 Service 对象就有了 crud 方法,我们可以在 Controller 类中直接使用~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.grtsinry43.projectpackage.controller;

import com.grtsinry43.projectpackage.dto.ApiResponse;
import com.grtsinry43.projectpackage.model.User;
import com.grtsinry43.projectpackage.service.UserService;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.*;

/**
* @author grtsinry43
* @date 2024/8/11 11:30
* @description 少年负壮气,奋烈自有时!
*/
@RestController
@RequestMapping("/api/user")
public class UserController {
private final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/{id}")
public ApiResponse<User> getUserInfo(@PathVariable Integer id) {
User user = userService.getById(id);
return ApiResponse.success(user);
}

@PutMapping("/{id}")
public ApiResponse<User> updateUserInfo(@PathVariable Integer id, @RequestBody User user) {
user.setId(id);
userService.updateById(user);
return ApiResponse.success(user);
}

@DeleteMapping("/{id}")
public ApiResponse<Object> deleteUser(@PathVariable Integer id) {
userService.removeById(id);
return ApiResponse.success(null);
}
}

使用代码生成器(完全不用敲代码)

当然,手动敲代码真的是太繁琐了,我真的非常讨厌在简单业务逻辑尤其是基本的 crud 上浪费时间,MyBatis-Plus 也想到了这一点,人家的完整使用方法可不是上面的那复杂,借助代码生成器(Auto Generator)完全无脑搞起来吧!

注意!根据官方文档,新的代码生成器适用于 3.5.1 及以上版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.grtsinry43.mybatisplusquickstart.util;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* Code generator for MyBatis Plus.
* Author: grtsinry43
* Date: 2024/8/11
*/
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("url",
"username", "password")
// 全局配置
.globalConfig((scanner, builder) -> builder
.author(scanner.apply("请输入作者名称?"))
.outputDir("src/main/java") // Specify the output directory
)
// 包配置
.packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")))
// 策略配置
.strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.entityBuilder()
.enableLombok()
.addTableFills(
new Column("create_time", FieldFill.INSERT)
)
.build())
// 使用Freemarker引擎模板,默认的是Velocity引擎模板
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}

// 处理 all 情况
protected static List<String> getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
}

这样,就会按照结构生成好啦:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ tree .
.
└── mybatisplusquickstart
├── controller
│   └── UserController.java
├── entity
│   └── User.java
├── mapper
│   ├── UserMapper.java
│   └── xml
│   └── UserMapper.xml
├── MybatisplusQuickstartApplication.java
├── service
│   ├── impl
│   │   └── UserServiceImpl.java
│   └── IUserService.java
└── util
└── CodeGenerator.java

以上,就可以在不用敲代码的情况下实现基本的数据操作,大大提高效率,减少机械操作了

]]>
@@ -76,8 +103,8 @@ 六月初至七月中旬|前端学习简要总结,生活的小回顾 https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ - 2024-07-11T15:27:23.000Z - 2024-08-11T02:49:07.853Z + 2024-07-11T23:27:23.000Z + 2024-11-29T03:26:20.565Z 在这段时间里我通过完成多个项目,深入学习了前端和全栈开发的技术。主要使用了 Vue3、C++ Web 框架、jwt 鉴权、Docker、Nginx、FastAPI、微信网页开发、Vue2、Vant 组件库、TypeScript 和 React 等技术。

项目驱动对我来说是一种很好的学习方式哈哈哈,不仅让我掌握了新技术,也让我遇到并克服了许多挑战,比如阅读别人的代码、复杂的后端逻辑处理和微信开发的复杂性等。 通过项目驱动的学习方式,我快速提升了自己的技术能力,并对此感到非常满意和自豪。我也意识到自己还处于学习的初阶段,对未来的学习充满了规划和期待。

额..最近的事情

上次总结应该是 5 月 27 号,那大概两周的时间学习 Vue 剩下的内容,那个时候同时也在研究全栈开发,照葫芦画瓢弄明白了 Spring Boot(不过基础太差,这个假期还得再弄一弄),然后应该是六月初。

后来搞了一周的课设、期末的任务、一些慕课的考试什么的,六月下旬就进期末考试周了,全天都在 预习 啊不,复习。主要也是老师讲了一学期也未必能给我们讲明白,就是老师其实很厉害但是讲课方面可能就不会那么面面俱到,反正我就一学期的内容看英文教材一周弄完了,考试结束换完寝室是六月末。

然后痛苦的来了,就是我所在的校团委网络信息部有个学生组织的技术部门,这学期当部长的几个学长下学期都不打算继续干了,一般都选择保研了。像我这种会学习不会考试绩点很低的肯定以提升技术为主 然后下学期我就得当两个部门的部长,假期要搞的几个项目都到我身上了 😰,和我同级的同学们前端后端又没那么熟练,所以本质上整个两个项目全是我一个人写的 😭。ddl 是 10 号,所以我被迫留在长沙现在还没有离校,9 号弄完上线的,现在终于轻松了。

最近的学习总结

感觉最近的前端学习全是自主探索的,全是项目驱动的 😂。

先是课程设计

课设是 C++的,正好我之前研究过一个 C++的 Web 框架,就给弄成前后端了。当时就是把这个当成练手项目了,因为全栈项目没搞过几个,所以就直接用上了 Vite+Vue3,至于学的话就是自己看文档,自己研究,然后也没用 Vuex 用的 pinia,同样也是自己研究的 😂。为了把这个项目搞出来又学了 jwt 让前后端能鉴权。

最后成品太丑了….搞个 Element Plus 其实主要是为了应付嘛(doge),学习技术和练手才是真,绩点我又不在乎

后来又自己研究了 docker 环境,nginx 反代后端到 /api,总之就是让我学到相当相当多,算是一个对我挺有意义的项目了

image-20240711222156417

之后是接的学校的项目

额这个对我来说主要的难度一个是微信网页开发实在太恶心,要搞什么认证又登录,还有就是学长传承下来了代码,但是这个代码的质量 emm…就是说屎山代码应该不过分。因为项目后端用的 FastAPI,这样我又不得不去学习这个,两天之内看文档学完了,但是真正上手看学长代码我才知道问题严重性。

154709B18B51FEF491EC9F8469FC1364

第一个项目是一个什么社团注册,这个前端之前代码用 Vue2 写的,不过还好代码完全没有压力,这个 Vant 组件库我又跑去看文档了,不过后端代码有点太抽象了,又用刚学的知识改了半天后端。然后还有…还有团委老师经常让我加功能 😰 啊这个太痛苦了,因为学长代码用的数据结构有点过于离谱,好多都是曲线救国,真的极其痛苦。

FD42D5950E45510DF7AA62EB5EEA4C044A88CD8706AB2D582D9EDDD96243D836B28977AB2B6D607D38D53945572D36B4

第二个就是一个简单的签到打卡,这个是被微信恶心的网页开发卡了好久,就是有个 wx.config() 需要后端调用 api 缓存 token 和签名啥的一大堆弄的天天做梦都在改 Bug😰,连着 3 天才弄出来。其他的就简单了感觉就是体力活了哈哈哈,实际写业务逻辑挺快的,不过好多后端给的响应数据结构太奇怪了,连写这个还得连改后端。然后为了管理又搞了个后台系统:

image-20240711225210198

image-20240711225506531

这个就是用 pure-admin 二次开发的,因为之前用过 element-admin 那个感觉这个还挺简单的,然后因为这个系统用的 TypeScript,大体上和 js 差不多吧,不过还是被迫,不对是自愿哈哈哈哈,毕竟能学到好多东西,看了文档搞明白了。

研究学长的项目

image-20240711230010314

这个是一个学长写的项目,不是我写的,不过我太感兴趣了 😂,所以自己看文档一天之内过了一遍 React,然后给学长提了 pr,现在还挺好看的

简要总结

这段时间真的都是因为一堆项目学到了好多东西,还挺爽的哈哈,至少因为项目需要自学了 Vue3,啊对还有 node 学着写了中间层,还有学了 React 和学长一起弄项目搞项目去了。

接下来计划再学习 node 中间层和后端,然后继续慢慢向下学习。而且就是我一年之内从刚开始写简单的 Hello World,到熟悉静态网页,再到今天一个人搞全栈项目,真的有非常大的进步,也真的克服了好多好多困难才能做到。不过我也知道我这才是刚入门而已,前面要学的太多太多了

然后假期回家也是绝大部分时间写代码,继续加油叭!

]]>
@@ -104,8 +131,8 @@ 学习分享|Vue3项目中使用微信SDK开发微信网页 https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ - 2024-07-03T02:54:25.000Z - 2024-08-11T04:22:33.297Z + 2024-07-03T10:54:25.000Z + 2024-11-29T03:26:20.565Z 最近在开发一个微信 H5 的项目,采用的是 Vue3+FastAPI,正好学习下微信用户登录,api 配置和调用,以及前后端关于这部分的解决方案

对微信网页开发的探索起源于最近的一个项目,需要一方面调用微信登录获取用户信息和将 token 作为区分用户的方式,另一方面要调用微信网页的 API 实现定位的操作

于是我查询微信官方开发文档,还有一些相关资料,按照自己理解研究了相关的解决方案

比较蛋疼的是,由于微信开发调用 API 时都会校验当前域名,因此被迫开发时进行线上测试(!!),目前个人没有解决方案,如果有了解的大佬恳请在评论处告知,不胜感激!!

安装及引入

首先微信的 js-sdk 是可以通过 npm 获取的:weixin-js-sdk

在项目中直接通过以下命令安装:

1
npm install weixin-js-sdk

之后就可以在项目中直接引用

1
import wx from 'weixin-js-sdk';

image-20240703141306717

此时你可以发现已经能正常调用并且补全了(好耶)

项目背景

首先前端我使用的 Vite+Vue3,后端是 FastAPI,为了在页面打开时就载入相关配置,我们需要在 main.js 执行相关逻辑

首先规定相关的接口逻辑

url定义
/api/wxconfig/get?url =获取相关配置
/api/wxconfig/flush?url =强制刷新配置

前端配置

这部分比较简单,无脑写就行,当测试完成之后,可以添加逻辑,让 wx.error 时候调用强制刷新的 API,这个具体自己设计就好

新建 util/wx-api-config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import wx from 'weixin-js-sdk';
import {getWxConfig} from "@/api/wxConfig.js";

console.log("微信 JS-SDK 配置开始...")

// 微信 API 全局配置
getWxConfig(location.href.split('#')[0]).then(res => {
console.log(res)
const {appId, timestamp, nonceStr, signature} = res;
wx.config({
debug: process.env.NODE_ENV === 'development',
appId,
timestamp,
nonceStr,
signature,
jsApiList: []
});
});

wx.ready(function(){
// config 信息验证后会执行 ready 方法,所有接口调用都必须在 config 接口获得结果之后,
// config 是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
// 则须把相关接口放在 ready 函数中调用来确保正确执行。
// 对于用户触发时才调用的接口,则可以直接调用,不需要放在 ready 函数中。
console.log("微信 JS-SDK 配置成功!")
});

wx.error(function(err){
console.log("微信 JS-SDK 配置失败:", err);
});



以及 axios 的配置,注意我这里使用了响应拦截器进行了统一处理,返回时已经直接是 data 的内容

api/wxConfig.js

1
2
3
4
5
6
7
8
9
10
import ins from "@/api/request.js";

export function getWxConfig(url) {
return ins.get("/wxconfig/get",{
params: {
url
}
})
}

最后只需要在 main.js 中调用即可:

1
2
// 配置微信 API
import "@/util/wx-api-config.js";

后端配置

重头戏肯定在这里哇,首先呢,我们先了解一下 config 都有哪些部分:

让我们把目光再转向刚才的配置

1
2
3
4
5
6
7
8
wx.config({
debug: true,
appId,
timestamp,
nonceStr,
signature,
jsApiList: []
});

其中有:是否开发模式,公众号唯一 id,生成签名的时间戳,生成签名的随机字符串,签名,要调用的 api 列表

准备好你的信息~,就像这样:

1
2
3
4
wx_app_cfg = {
'appid': 'xxxxxxxxxxxxxxxxxx',
'secret': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
}

对于这些内容,我们继续了解微信这个签名逻辑

首先,要带上 appidappscrect 请求微信接口拿到 access_token,有效时长 7200

1
2
3
4
5
6
def get_access_token(appid: str, appsecret: str) -> str:
"""调用微信API获取access_token"""
url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={appsecret}"
response = requests.get(url)
data = response.json()
return data.get("access_token")

之后获取 jsapi_ticket

1
2
3
4
5
6
def get_jsapi_ticket(access_token: str) -> str:
"""调用微信API使用access_token获取jsapi_ticket"""
url = f"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi"
response = requests.get(url)
data = response.json()
return data.get("ticket")

有了这两个东西,就可以开始签名啦~

1
2
3
4
5
6
7
8
9
10
def generate_nonce_str(length: int = 16) -> str:
"""生成随机字符串,用于签名"""
characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return ''.join(random.choice(characters) for _ in range(length))


def generate_signature(ticket: str, noncestr: str, timestamp: int, url: str) -> str:
"""使用sha1生成签名"""
string1 = f"jsapi_ticket={ticket}&noncestr={noncestr}&timestamp={timestamp}&url={url}"
return hashlib.sha1(string1.encode('utf-8')).hexdigest()

这样我们就得到了签名,但是这还没有结束,根据微信文档的介绍:

access_token 是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用 access_token。开发者需要进行妥善保存。access_token 的存储至少要保留 512 个字符空间。access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效。

公众平台的 API 调用所需的 access_token 的使用及生成方式说明:

1、建议公众号开发者使用中控服务器统一获取和刷新 access_token,其他业务逻辑服务器所使用的 access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务;

2、目前 access_token 的有效期通过返回的 expires_in 来传达,目前是 7200 秒之内的值。中控服务器需要根据这个有效时间提前去刷新新 access_token。在刷新过程中,中控服务器可对外继续输出的老 access_token,此时公众平台后台会保证在 5 分钟内,新老 access_token 都可用,这保证了第三方业务的平滑过渡;

3、access_token 的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新 access_token 的接口,这样便于业务服务器在 API 调用获知 access_token 已超时的情况下,可以触发 access_token 的刷新流程。

因此我们需要提供缓存的能力,这里使用 mongoengine 处理相关逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def save_and_expire_handle(force=False):
"""
每次调用的时候,首先检查mongo中是否有缓存(mongoengine),如果有,检查是否过期,如果过期,重新获取并且存储,如果没有,直接获取
"""
current_time = int(time.time())
config = WXConfig.objects().first() # 因为只会有一条记录,所以直接获取第一条应该就可以了

if config and config.expires_at > current_time and not force:
# 如果配置存在且未过期,直接返回
return {
"access_token": config.access_token,
"jsapi_ticket": config.jsapi_ticket
}
else:
# 如果配置不存在或已过期,重新获取并存储
appid = wx_app_cfg['appid']
appsecret = wx_app_cfg['secret']
print("==重新调用微信API获取access_token和jsapi_ticket==")
access_token = get_access_token(appid, appsecret)
jsapi_ticket = get_jsapi_ticket(access_token)
expires_at = current_time + 7000 # 这里过期时间应该是 7200 秒,但是为了保险起见,提前 200 秒过期并重新获取

if config:
# 更新现有记录
config.update(access_token=access_token, jsapi_ticket=jsapi_ticket, expires_at=expires_at)
else:
# 创建新记录
WXConfig(access_token=access_token, jsapi_ticket=jsapi_ticket, expires_at=expires_at).save()

return {
"access_token": access_token,
"jsapi_ticket": jsapi_ticket
}

这样,我们就可以实现缓存 access_tokenjsapi_ticket,并且在每次都检查是否过期减少请求次数了。

诶?为什么要留一个 force 参数呢?

在实际开发中,如果存在多端测试,可能在未过期时候就会刷新 access_tokenjsapi_ticket,这样之前的存储就会过期,因此需要提供一个强制刷新的接口

按照前端需要的内容封装好函数,就有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def get_wx_config(appid: str, appsecret: str, url: str, force=False) -> Dict[str, str]:
"""获取微信JS-SDK配置"""
# 首先从数据库或者新获取 access_token 和 jsapi_ticket
# 这里就一个需要 force 即可,因为 access_token 和 jsapi_ticket 是一起获取的
access_token = save_and_expire_handle(force)['access_token']
jsapi_ticket = save_and_expire_handle()['jsapi_ticket']
# 生成签名所需的参数
noncestr = generate_nonce_str()
timestamp = int(time.time())
# 生成签名
signature = generate_signature(jsapi_ticket, noncestr, timestamp, url)

return {
"appId": appid,
"timestamp": timestamp,
"nonceStr": noncestr,
"signature": signature
}

最后注册路由接口,FastAPI,启动!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@wxconfig_route.get('/get')
async def return_wx_config(url: str):
"""
获取微信JS-SDK配置
"""
# 生成微信 JS-SDK 配置
wx_config = get_wx_config(wx_app_cfg['appid'], wx_app_cfg['secret'], url)

return trueReturn(wx_config)


@wxconfig_route.get('/flush')
async def flush_wx_config(url):
"""
这里保留了一个接口用于特殊情况,强制刷新微信JS-SDK配置
"""
# 生成微信 JS-SDK 配置
wx_config = get_wx_config(wx_app_cfg['appid'], wx_app_cfg['secret'], url, force=True)

return trueReturn(wx_config)

测试

按照之前我说的,测试过程比较蛋疼,必须是正式域名的线上环境,可以用微信开发者工具测试一下,测试时候可以将 debug 写死成 true 便于发现问题


这里留个坑(?!又来),之后详细讲一下测试过程

]]>
@@ -129,8 +156,8 @@ 学习分享|Kubernetes快速上手,快速了解及开始使用 https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ - 2024-06-27T11:09:46.000Z - 2024-06-27T14:08:15.096Z + 2024-06-27T19:09:46.000Z + 2024-11-29T03:26:20.565Z 最近感觉 K8s 挺火的,也许是时下比较热门的技术栈了,学习过程比较曲折复杂,分享一下自己的学习过程,从快速入门,到一些深入的使用

简要介绍

Kubernetes 简介

Kubernetes,通常简称为 “k8s”,是一个开源平台,用于自动化部署、扩展和管理容器化应用程序。它允许您在一个计算机集群中管理容器化应用程序,提供部署、维护和扩展的机制。

听说过一个说法,docker 的图标是载满集装箱的鲸鱼,而 k8s 的图标是一个带有舵轮的蓝色八边形,代表着它在容器编排领域的导航和控制作用,象征着 Kubernetes 能够帮助用户高效地管理和指导容器化应用程序的部署和运行,驾驶着驶向远方(中二 ing)。

docker 更多用于将应用程序及其依赖项打包到一个轻量级、可移植的容器中,解决的是配置环境和实现容器化,而 Kubernetes 提供了高可用性、负载均衡、自动扩展和滚动更新等功能,适用于生产环境,使管理大规模容器化应用程序变得更加高效和可靠。Kubernetes 适用于需要自动化管理、扩展和部署多个容器的复杂应用场景。

与 docker-compose 的比较

  1. 集群管理和多节点支持
    Kubernetes:设计用于管理一个跨多个节点(机器)的容器集群。它可以自动分配和调度容器到集群中的不同节点上,确保高可用性和资源的最佳利用。
    Docker Compose:主要用于单个节点上的容器编排。虽然可以通过 Swarm 模式在多个节点上运行,但其功能和扩展性不如 Kubernetes 强大。

  2. 自动化和自我修复
    Kubernetes:提供了自动化的容器部署、扩展和自我修复能力。它可以自动重新启动失败的容器、替换被损坏的节点、自动扩展应用实例数量等。
    Docker Compose:缺乏自动化的修复和扩展机制。需要手动管理容器的状态和扩展。

  3. 服务发现和负载均衡
    Kubernetes:内置了强大的服务发现和负载均衡功能。服务可以通过 DNS 名称互相访问,Kubernetes 会自动在各个 Pod 之间进行负载均衡。
    Docker Compose:服务发现和负载均衡功能较为基础,需要依赖外部工具或手动配置。

  4. 持久化存储和卷管理
    Kubernetes:提供了丰富的持久化存储选项和卷管理功能,包括 PersistentVolume 和 PersistentVolumeClaim,支持多种存储后端(如 NFS、Ceph、AWS EBS 等)。
    Docker Compose:支持卷的基本功能,但管理持久化存储的功能较为简单,且不具备 Kubernetes 那样的存储抽象和集成能力。

  5. 安全性和访问控制
    Kubernetes:提供了强大的安全和访问控制机制,包括基于角色的访问控制(RBAC)、网络策略、Pod 安全策略等,可以细粒度地管理用户和应用的权限。
    Docker Compose:安全性和访问控制较为基础,需要依赖外部工具或额外的配置来实现类似的功能。

  6. 扩展性和生态系统
    Kubernetes:具有丰富的扩展性和庞大的生态系统,支持 Helm Charts(包管理)、Operator(运维自动化)、CRD(自定义资源)等,可以轻松集成各种第三方工具和插件。
    Docker Compose:相对简单,功能较为有限,扩展性不如 Kubernetes 强大。

  7. 社区和支持
    Kubernetes:由 CNCF(Cloud Native Computing Foundation)维护,拥有庞大的社区支持和活跃的开发生态。广泛应用于生产环境,得到了各大云服务商的全面支持。
    Docker Compose:主要由 Docker 社区维护,虽然也有不少用户,但在生产环境中的应用和支持程度不如 Kubernetes。

安装与快速上手

这里为了在本地演示方便,使用的是本地的 Archlinux

安装

首先安装必要的组件

1
sudo pacman -S kubeadm kubelet kubectl

这里要注意,进行下一步之前,由于 k8s 不支持 swap(为了保证容器运行),需要关闭 swap,以下命令适用于临时关闭,如果不再使用 swap,在 /etc/fstab 注释掉对应行即可

1
sudo swapoff -a

随后启动服务,当然也可以设置开机启动(enable)

1
sudo systemctl start kubelet

Kubernetes 需要一个容器运行时来实际运行容器。最常用的选择是 containerdCRI-O。这里我们选择使用 containerd

1
2
sudo pacman -S containerd
sudo systemctl start containerd

系统配置

Kubernetes 需要一些特定的内核模块和系统参数来正常工作。

  1. 加载必要的内核模块

    • overlaybr_netfilter 是两个内核模块,分别用于文件系统层和网络层。
    • 创建文件 /etc/modules-load.d/k8s.conf 系统启动时将会自动加载这些模块
    1
    2
    overlay
    br_netfilter
    • 然后手动加载这些模块:
    1
    2
    sudo modprobe overlay
    sudo modprobe br_netfilter
  2. 设置 sysctl 参数

    • Kubernetes 需要一些特定的网络配置

    • 创建文件 /etc/sysctl.d/k8s.conf

      前两个是使得桥接的流量(例如虚拟机或容器之间的流量)可以被 iptables 的规则所处理

      最后一个是启用 IPv4 在接口之间的转发

    1
    2
    3
    net.bridge.bridge-nf-call-iptables = 1
    net.bridge.bridge-nf-call-ip6tables = 1
    net.ipv4.ip_forward = 1
    • 然后应用这些参数:
    1
    sudo sysctl --system

集群配置

  1. 初始化控制平面:
    控制平面是 Kubernetes 集群的核心部分,负责管理所有集群活动。使用以下命令初始化控制平面:
1
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

--pod-network-cidr 参数指定 Pod 网络的 CIDR(Classless Inter-Domain Routing,无类别域间路由)。这里我们使用 10.244.0.0/16。

为什么选这个地址?

  1. 大多数人使用的习惯
  2. 选择 10.244.0.0/16 范围,旨在最小化与集群节点可能连接的其他网络的 IP 地址冲突的风险。10.0.0.0/8 的私有网络空间很大,允许灵活选择不太可能与组织现有网络配置重叠的子网。(比如我所在学校的校园网的内网网段就有冲突部分,10.244.xxx 更不容易冲突)

这个命令完成需要一些时间哦

该命令完成后会输出一个 kubeadm join 命令,用于将工作节点加入集群。

image-20240627203321509

  1. 为用户配置 kubectl:

    按照上一步的提示创建 .kube 目录并复制配置文件:

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. 安装 Pod 网络插件

    Pod 网络插件使得 Pod 之间可以通信。我们选择使用 Flannel 作为网络插件。

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  1. 将工作节点加入集群
    在每个工作节点上运行在 kubeadm init 步骤中输出的 kubeadm join 命令。

    1
    sudo kubeadm join <control-plane-host>: <control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256: <hash>

image-20240627214438919

一些常用命令

  1. 查看所有节点的状态:

    1
    kubectl get nodes
  2. 查看所有命名空间中的 Pod 状态:

    1
    kubectl get pods --all-namespaces
  3. 查看特定 Pod 的日志:

    1
    kubectl logs <pod-name>

实际演练

让我们搞一个简单的示例项目来实际应用一下叭~

这个例子包含一个前端( Nginx 提供静态文件)和一个后端( Flask 提供 API),帮助我们了解如何在 Kubernetes 上部署和管理多组件应用程序。


挖坑,再研究研究之后更新(悲)

]]>
@@ -154,8 +181,8 @@ 问题解决|使用Less变量和媒体查询实现深浅色模式适配 https://blog.grtsinry43.com/2024/06/09/less-media-variable/ - 2024-06-09T13:36:30.000Z - 2024-08-10T16:07:05.446Z + 2024-06-09T21:36:30.000Z + 2024-11-29T03:26:20.565Z 使用Less变量简化css写法,并不影响css变量和媒体查询在深浅模式切换时的效果

分析问题

首先要清楚问题的来源是什么,使用媒体查询api可以根据深浅色为css变量赋予不同的值,而Less(或是scss)不是原生被浏览器所支持,运行时需要先转为为原生css,这一步也就是编译,有点类似ts和js的关系。这里采用的是vite创建的Vue3项目
而Less/Scss在编译的过程中,进行的是完全的字段替换,这也就意味着在运行之前css已经被固定,无法在运行的过程中动态修改,当然也不支持媒体查询的所有属性,但一些还是支持的哈,比如设备类型,最大宽度什么的,这里深浅色默认是不支持的。

问题出现

这里首先我是想办法完全使用Less的,也就是媒体查询+正常定义变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@primary: #1890ff; // 全局主色
@bg: #ffffff; // 全局背景
@font: #333333; // 全局字体颜色
@warning: #faad14; // 警告
@success: #52c41a; // 成功
@error: #f5222d; // 错误
@info: #1890ff; // 信息
@disabled: #bfbfbf; // 失效
@link: #1890ff; // 链接
@hover: #001764; // hover

@media (prefers-color-scheme: dark) {
:root {
@primary: #718dff; // 全局主色
    @bg: #1d1e21; // 全局背景
    @font: #ffffff; // 全局字体颜色
    @warning: #faad14; // 警告
    @success: #a8ff7d; // 成功
    @error: #f5222d; // 错误
    @info: #80c1ff; // 信息
    @disabled: #4e4e4e; // 失效
    @link: #a0b5ff; // 链接
    @hover: #d5e8ff; // hover
}
}

但是实际测试中发现所编译出的css根本没有@media的字样,所以又是inline编译了,导致完全写死,不可能在运行中改变

问题解决

因为测试Less写法一直有问题,而原生css是可以完美解决的,为了既保留Less的简便的变量写法,又解决变量无法修改的问题,因此利用字段替换编译的特性,我们可以将Less变量赋值为css变量,这样当编译之后所生成的css,依然是变量形式储存内容,具体代码可以参考:

colors.less

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
:root {
--primary: #1890ff; // 全局主色
--bg: #ffffff; // 全局背景
--font: #333333; // 全局字体颜色
--warning: #faad14; // 警告
--success: #52c41a; // 成功
--error: #f5222d; // 错误
--info: #1890ff; // 信息
--disabled: #bfbfbf; // 失效
--link: #1890ff; // 链接
--hover: #001764; // hover
}

@primary: var(--primary);
@bg: var(--bg);
@font: var(--font);
@warning: var(--warning);
@success: var(--success);
@error: var(--error);
@info: var(--info);
@disabled: var(--disabled);
@link: var(--link);
@hover: var(--hover);

@media (prefers-color-scheme: dark) {
:root {
--primary: #718dff; // 全局主色
--bg: #1d1e21; // 全局背景
--font: #ffffff; // 全局字体颜色
--warning: #faad14; // 警告
--success: #a8ff7d; // 成功
--error: #f5222d; // 错误
--info: #80c1ff; // 信息
--disabled: #4e4e4e; // 失效
--link: #a0b5ff; // 链接
--hover: #d5e8ff; // hover
}
}

global.less

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@import "@/styles/colors";

*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

a {
color: @link;
text-decoration: none;
}

a:hover {
text-decoration: underline;
color: @hover;
}

ul {
list-style: none;
}


body {
min-height: 100vh;
color: @font;
background: @bg;
transition: color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family: Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

#app {
margin: 0 auto;
font-weight: normal;
}

随后正常在main.js引入global.less即可:

1
import '@/styles/global.less'

问题延伸

问题到这里解决了吗?当然,但是还有个需求场景,某些网站会提供用户手动切换深色浅色模式的功能,而css变量可在运行中动态修改的优势就显现了出来

这里就需要js在运行中更改变量啦,具体的实现逻辑如下:

这里采用触发事件的方式进行,在Vue3中,你可以使用mitt进行事件的监听,

1
npm install mitt

可以直接注册在全局app上,也可以单独延续Vue2的习惯创建Vue实例挂载到上面:

这里的举例是创建Vue实例挂载到上面,新建一个eventBus.js

1
2
3
4
5
6
7
8
9
10
import { createApp } from 'vue';
import mitt from 'mitt';

const emitter = mitt();

const bus = createApp({});

bus.config.globalProperties.$bus = emitter;

export default bus;

这样就可以全局触发和监听事件

接下来创建一个工具函数,在挂载时候添加监听,新建util/useColorScheme.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { onMounted, onUnmounted } from 'vue';
import bus from "@/eventBus.js";
/**
* 当触发themeChange事件,切换页面的颜色主题,在onMounted,onUnmounted生命周期钩子函数中设置
* 修改原理是css变量
*/
export function useColorScheme() {
const themeChange = (theme) => {
console.log('themeChange', theme)
if (theme) {
// 深色模式
document.documentElement.style.setProperty('--primary', '#718dff');
document.documentElement.style.setProperty('--bg', '#1d1e21');
document.documentElement.style.setProperty('--font', '#ffffff');
document.documentElement.style.setProperty('--warning', '#faad14');
document.documentElement.style.setProperty('--success', '#a8ff7d');
document.documentElement.style.setProperty('--error', '#f5222d');
document.documentElement.style.setProperty('--info', '#80c1ff');
document.documentElement.style.setProperty('--disabled', '#4e4e4e');
document.documentElement.style.setProperty('--link', '#a0b5ff');
document.documentElement.style.setProperty('--hover', '#d5e8ff');
} else {
// 浅色模式
document.documentElement.style.setProperty('--primary', '#1890ff');
document.documentElement.style.setProperty('--bg', '#ffffff');
document.documentElement.style.setProperty('--font', '#333333');
document.documentElement.style.setProperty('--warning', '#faad14');
document.documentElement.style.setProperty('--success', '#52c41a');
document.documentElement.style.setProperty('--error', '#f5222d');
document.documentElement.style.setProperty('--info', '#1890ff');
document.documentElement.style.setProperty('--disabled', '#bfbfbf');
document.documentElement.style.setProperty('--link', '#1890ff');
document.documentElement.style.setProperty('--hover', '#001764');
}
};

onMounted(() => {
bus.config.globalProperties.$bus.on('themeChange', themeChange);
});

onUnmounted(() => {
bus.config.globalProperties.$bus.off('themeChange', themeChange);
});
}

这个就是在当触发themeChange事件,切换页面的颜色主题,在onMounted,onUnmounted生命周期钩子函数中设置,工具都准备好啦,就可以在任意地方使用啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import {ref, watchEffect} from 'vue';
import {useColorScheme} from "@/util/useColorScheme.js";
import bus from "@/eventBus.js";

// 定义深浅模式的变量
const isDark = ref(false);

// 切换深浅模式
const handleThemeButton = () => {
isDark.value = !isDark.value;
};

watchEffect(() => {
//当深浅模式变量改变时,发出自定义事件
bus.config.globalProperties.$bus.emit('themeChange', isDark.value);
});

useColorScheme();

总结一下

其实有点复杂不太优雅,不过在大的Vue项目中,一定会用到pinia,mitt等工具来进行状态管理,全局事件总线监听的,折腾一下利于积累经验()

回到最开始的问题,原生css变量可用于动态修改,给了实时切换的可能,而less/scss的便捷写法又能大大简化开发,好啦,就到这里呀

效果演示

]]>
@@ -179,8 +206,8 @@ 学习分享|原生三件套的网页效果 https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ - 2024-06-09T13:29:07.000Z - 2024-08-11T04:22:27.744Z + 2024-06-09T21:29:07.000Z + 2024-11-29T03:26:20.565Z 这是学习前端基础,用原生三件套尤其是js实现效果一些学习过程的记录,首先是静态的小米商城,之后实现了一些效果,比如表格、轮播图、瀑布流等,都是为了提升自己原生js的dom操作能力

话题开始之前是一些没有用的内容:

首先是因为之前那个副硬盘位的西数盘经常掉盘(损失惨重),问了一下居然是兼容性问题(?这个好久没遇到或者听说过了),赶在硬盘涨价的时机含泪购入三星硬盘,因为测试原因单硬盘使用了一段时间,被迫用Windows一段时间还是感觉挺好用的嘛(docker/nginx/mysql等除外,用了wsl2),再加上我搞了个二手4k屏,N卡+Linux开源驱动太卡,闭源驱动没法雷电口输出,裂开,所以至今只能被迫Windows,后面给大家分享一点好用的工具。

更新:win太难用了,又回去了()

然后还有从假期开始之前我就开始搞算法,所以假期很多时间也用来学和写算法题了,留给我写JS的时间并不多,不过还好我写算法用的Java(能和JS有几分相像?),总体也学到挺多。

至于我为什么要学前端三件套呢,这个是因为我现在没有全栈开发能力,Java的swing写点什么简直是天方夜谭,极其痛苦,所以这个假期还有这学期大部分时间我都会用来学习前端开发,当然是广义上的前端,先从网页开始,也接触并且计划了以后学习Qt,electron,Android(Jetpack Compose),Flutter

一、从基础开始

首先当然是从样式入手,这方面我能拿得出手的也就是描摹了一个小米商城主页,纯静态界面,然后这里面主要就是为了回顾马上就要忘记的语法,然后还有养成开发的习惯:比如以组件为单位进行开发,css分文件,规定统一的样式方便应用,几种选择器的使用,复合组件的写法,利用伪元素来实现分隔符等等

大概就是一个这样的效果(还有实际的网页文件演示)

二、照葫芦画瓢

首先因为我学习能力有限,进度比较缓慢,还没有学习到框架,之前只是用过接触过但没有系统学习,所以这里的内容都是用原生JS实现的,更多想要去熟悉这门语言,我觉得可能这样对于以后学习框架能更容易一些

1.文字滚动效果

这里是学习到了,第一是为了防止代码污染而使用了立即执行函数,第二是用js实现动画本质上就是连续缓慢变化的画面

2.展开菜单效果

这里主要还是动画的实现

3.动态排序表格

1
2
3
4
5
6
7
8
9
10
var onCheckOneListsClick =(e)=> {
if (e.target.tagName !== 'INPUT') {
return;
}
var checkNumber = 0;
for (let i = 0; i < checkOneLists.length; i++) {
checkOneLists[i].checked && checkNumber++;
}
checkAll.checked = checkNumber === checkOneLists.length;
}

这个是添加事件,指定触发对象,还有一个字符的比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var handleThsClickFn = function (th, index) {
if (index === 0) return;
th.addEventListener('click', function () {
var arr = Array.prototype.slice.call(rows).sort(function (a, b) {
if (index === 2 || index === 4){
return a.getElementsByTagName('td')[index].innerHTML.localeCompare(b.getElementsByTagName('td')[index].innerHTML,'zh');
}
return a.getElementsByTagName('td')[index].innerHTML - b.getElementsByTagName('td')[index].innerHTML;
})
for (let i = 0; i < arr.length; i++) {
tbody.appendChild(arr[i]);
}
});
}

4.三级联动效果

这个就是常规js动态生成元素

5.积分抽奖效果

更多是学习一种思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var runGame = function () {
var random = Math.floor(Math.random() * 6000 + 3000)
timer = setInterval(function () {
random -= 200
if (random < 200) {
clearInterval(timer)
timer = null
openDialog()
return
}
currentIndex = ++index % prizeList.length
prizeList.forEach(function (node) {
node.classList.remove('active')
})
prizeList[currentIndex].classList.add('active')
}, 50)
}

6.轮播图

这个就是实现无缝轮播,关键就是几行代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function next() {
var newIndex = curIndex + 1;
var onend;
if (newIndex === doms.carouselList.children.length - 1) {
onend = function () {
console.log(1)
doms.carouselList.style.marginLeft = '0px';
curIndex = 0;
}
}
moveTo(newIndex, onend);
}

function prev() {
console.log(curIndex);
var newIndex = curIndex - 1;
if (newIndex < 0) {
var maxIndex = doms.carouselList.children.length - 1;
doms.carouselList.style.marginLeft = -maxIndex * containerWidth + 'px';
newIndex = maxIndex - 1;
}
moveTo(newIndex);
}

7.图片瀑布流

这个比较好玩,看源码讲

8.五子棋游戏

这个比较好玩,看源码讲

]]>
@@ -204,8 +231,8 @@ 学习分享|跨域解决、安卓开发探索、油猴脚本探索 https://blog.grtsinry43.com/2024/06/09/learn-share-1/ - 2024-06-09T13:22:48.000Z - 2024-08-11T02:49:07.282Z + 2024-06-09T21:22:48.000Z + 2024-11-29T03:26:20.565Z 最近学习的一些内容,包括跨域问题及其解决方案,安卓开发的简单探索,OpenAI的api做了个小插件

额,把原来用Hexo托管在Github上的博客重新搞了一下,本来我是想坚持每天写博客的,但一直苦于没有时间(其实就是懒),腾出时间把服务器和备案给搞了(又找借口),本来想用Vue和Spring自己写的,但还没学完( )

一、跨域问题及其解决方案

1.概念

跨域问题是指在浏览器的同源策略下,不同域名、端口或协议之间的网页请求受到限制,导致某些跨域请求被浏览器阻止。同源策略是一种安全机制,防止恶意网站获取到用户的敏感信息。

源:协议+域名+端口

  1. 不同域名:比如从 domain1.com 发起请求到 domain2.com
  2. 不同端口:比如从 domain.com:3000 发起请求到 domain.com:4000
  3. 不同协议:比如从 http://domain.com 发起请求到 https://domain.com

2.解决方案

  1. CORS(跨域资源共享):服务器端设置响应头,允许特定来源的请求。通过设置 Access-Control-Allow-Origin 头部来指定允许访问的域名,但是建议不要设置 Access-Control-Allow-Origin: *,在某些情况下只设置通配符会被理解为暂未配置。

比如使用nodejs处理一个简单的请求

1
2
3
4
5
6
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.header('Access-Control-Allow-Origin', '127.0.0.1');
res.status(200).sendFile('XXX.html');
});

此时你能够在浏览器开发人员工具——网络选项卡看到这个响应头的一部分

这里注意,是只有在响应头中看到这段语句浏览器才能正常请求,找不到语句(没有默认是拒绝)或者没有请求所在的域名均不会成功

  1. JSONP(JSON with Padding):通过 <script> 标签的方式实现跨域请求。JSONP利用了 <script> 标签可以跨域加载的特性,不过只支持GET请求,并且存在安全性问题。

是早期的工程师们的非常天才的想法!这东西的原理是请求URL会返回类似callbackFunction(data)的字段,也就是一段js代码,这样可以使浏览器执行,从而实现预期效果

1
2
3
4
<script src="https://otherdomain.com/data?callback=myFunction"></script>
function myFunction(data) {
console.log(data);
}
  1. 代理服务器:在同源策略下,通过在同一个域名下创建API代理,让客户端请求自己的服务器,再由服务器转发请求到目标地址。这样可以绕过浏览器的限制。
1
2
3
4
5
6
7
// 在服务器端发起请求
const resp = await axios.get('https://pvp.qq.com/web2 herolist.json');
// 将获取的数据返回给客户端
app.get('/', (req, res) => {
res.header('Access-Control-Allow-Origin', '127.0.0.1');
res.send(resp.data);
});

二、安卓开发的浅探索

这个其实是一个迫不得已的学习内容,起因是班级同学拽上我去参加一个嵌入式比赛,作品当然是大一专属的小车(蚌埠住了),他们希望亮点是软件,所以我就现学的安卓开发,本来还学了Kotlin一瘸一拐地写了点内容,但后来搞一些复杂的内容用一个不熟悉的语言还是太痛苦,所以还是回到了Java

 GitHub

grtsinry43/stm32-project-smartcontrol

项目包括以下几个类:

  • MainActivity.java:应用的主界面,实现手动控制,扫码反序列化,关于页面等功能
  • BluetoothActivity.java:实现蓝牙的连接和通信
  • ControlActivity.java:实现小车的控制指令的发送和接收
  • QRCodeActivity.java:实现二维码的扫描和解析
  • AboutActivity.java:显示应用的相关信息

所有都是现学的,我就大概说一下我学到了什么吧:

安卓开发是标准舒服的行为样式相分离,开发的单位是Java/Kotlin的类,每个界面是Activity,每个图形元素有对应的xml样式布局文件。大体上开发时候先用Adobe XD或者sigma(国内也可以即时设计啥的)设计好界面,然后为每个元素写xml文件,Activity里面通过id找到元素,可以添加、修改元素,可以监听元素动作(比如Button),但是通知线程服务啥的必须得学明白,别像我啥都不会,写的时候很痛苦

三、OpenAI的api简单使用

就是用js调用一个api,把回应显示出来,没什么复杂的,现在以我的技术只能做出这样(捂脸),前端有太多需要学的了……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// ==UserScript==
// @name GPT Answer
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Get GPT answer for selected text
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==

(function() {
'use strict';

// 创建悬浮提示框
var tooltip = document.createElement('div');
tooltip.style.position = 'fixed';
tooltip.style.zIndex = '9999';
tooltip.style.display = 'none';
tooltip.innerHTML = '<button id="gpt-answer">GPT回答</button>';

// 创建GPT回答显示区域
var answerArea = document.createElement('div');
answerArea.style.position = 'fixed';
answerArea.style.zIndex = '9999';
answerArea.style.display = 'none';
answerArea.style.outline = '1px solid';

document.body.appendChild(tooltip);
document.body.appendChild(answerArea);

// 监听文本选择事件
document.addEventListener('mouseup', function(e) {
var selectedText = window.getSelection().toString().trim();
if (selectedText) {
var selectedElement = window.getSelection().anchorNode.parentNode;
var rect = selectedElement.getBoundingClientRect();
tooltip.style.left = (rect.right + 10) + 'px';
tooltip.style.top = rect.top + 'px';
tooltip.style.display = 'block';
} else {
tooltip.style.display = 'none';
}
});

// 监听GPT回答按钮点击事件
document.getElementById('gpt-answer').addEventListener('click', function() {
var selectedText = window.getSelection().toString().trim();
if (selectedText) {
// 调用OpenAI API
fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY'
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{"role": "system", "content": "你是一个耐心回答问题的助手,请解答这个问题,谢谢!"},
{"role": "user", "content": selectedText}
]
})
}).then(response => response.json())
.then(data => {
// 在固定位置显示GPT的回答
var gptResponse = data['choices'][0]['message']['content'];
answerArea.textContent = gptResponse;
var selectedElement = window.getSelection().anchorNode.parentNode;
var rect = selectedElement.getBoundingClientRect();
answerArea.style.left = (rect.right + 10) + 'px';
answerArea.style.top = (rect.bottom + 10) + 'px';
answerArea.style.display = 'block';
});
}
});

// 监听页面点击事件,隐藏GPT回答显示区域
document.addEventListener('click', function(e) {
if (e.target !== answerArea && e.target !== tooltip && e.target !== document.getElementById('gpt-answer')) {
answerArea.style.display = 'none';
}
});
})();
]]>
@@ -229,8 +256,8 @@ 高考之后回来啦 https://blog.grtsinry43.com/2023/06/16/helloback/ - 2023-06-16T15:21:49.000Z - 2024-08-10T16:07:02.410Z + 2023-06-16T23:21:49.000Z + 2024-11-29T03:26:20.565Z 终于终于,忙碌而又充实的高三生活结束了,当然,这也意味着人生的一个新阶段开始啦
作为计算机技术的爱好者但也是小白,这次是一个新的起点,

希望自己能抓住这段时间,不断进步和成长。生命不息,学习不止!

未来这里会更新我的学习笔记和收获,希望自己不断进步,踏实进取!也希望自己和同行的朋友相互督促拒绝摆烂!

总之岁月漫长,然而值得等待!苦尽甘来的那一天,山河星月都做贺礼!

]]>
@@ -247,8 +274,8 @@ 高中时期一些文章的整理合集 https://blog.grtsinry43.com/2023/06/15/article-archive/ - 2023-06-15T06:21:19.000Z - 2024-08-10T16:07:03.650Z + 2023-06-15T14:21:19.000Z + 2024-11-29T03:26:20.565Z 这里归档了一些我高中时候写的作文,既是黑历史,也是一段之前的记忆吧

大多数都是格式文章,千篇一律的套路啦


Hi~居然让你发现了,这是我高考前自己写的和积累的一些文章。

如果你正在准备高考,那么这些主题很明确语言很吸人眼球的文章会对你有很大帮助;

如果你只是看完技术文章之后发现了这里,不妨期待一下以后我会更新的读书笔记。

无论年龄大小,学历高低,我们一直在学习,我们一直在路上


最是经历能致远 踔厉成长重担肩

2022-05-20 20:01:03

适用于:经历,成长,责任

  踏遍脚下的荆棘丛生,是为了赶上日出的秀丽璀璨。

  见证十七载春秋,我们骄傲于东方巨龙之腾跃,欣喜于人生漫路之新篇,当下时代,必定有我们踔厉成长、重任担肩。

  经历繁华,见证大国的泱泱崛起。“北京欢迎你,为你开天辟地……”,第一次让五环矗立在中国,第一次让世界认识中国。援引一曲宫商角徵羽,回首见东方雄起之中华。我们有幸看到这样的中国,更有幸证明这样的发展。高铁里程世界第一、潜艇技术世界第一、发展速度再创新篇……一座座高楼拔地而起,一艘艘火箭冲向蓝天,一个个乡村脱贫摘帽。这砥砺奋进的五年,正谱写新篇。对于我们,文化上有中华文明的繁荣;物质上,有衣食无忧的生活;科技上,见证了移动支付的畅快便捷。无数次为生在中国而骄傲,无数次因身为中华民族而心生自豪。
  经历人生,书写成长的熠熠华章。“相信自己,相信学校,缔造传奇,续写荣光!”2020年着实是不平凡的一年,当全民抗疫、共克时艰遇上拼搏百日、圆梦中考,也造就了我们不平凡的经历。八周网课,隔着屏幕却隔不断知识与爱;居家隔离,隔不住亲情、友情、师生情;带上口罩,阻隔不了对知识的渴望与追求。经历了考验,我们才更有对生活的勇气;磨砺过后,才更有意志不懈奋斗。带上这份经历,才让我们“目标明确,积极向上;勤学苦练,斗志昂扬;讲究方法,保质保量;顽强拼搏,不弃不放;严守纪律,自信自强;争分夺秒,适度紧张;自我调整,身心健康;全力以赴,创造辉煌”!
  经历坎坷,扛起时代的殷殷重任。“当下的国际形势与一战前并无两样”。我们不是生在一个和平的年代,而是生在一个和平的国家。当下各国为利益而追逐,为利益不惜一切,破坏环境,封锁猜忌。
  近日,“杂交水稻之父”袁隆平院士与世长辞,他的“杂交水稻覆盖全球梦”正传到我们手上。经历了十六载春秋的我们,重任在肩,责无旁贷。
  经历了崛起,方知背后艰辛;经历了辉煌,方知留下汗水;经历了历史方知重担已然在肩。我们早已成长为时代的接班人,站在两个一百年的历史交汇点上,前方必定有风雨载途。但也正有一路风霜,才有一份收获。百年大党,不畏艰难;吾辈青年,奋勇自强。磨砺中学会自强,重启我们的风光霁月,成为当之无愧的中国脊梁!


百年奋斗,踔厉奋发,不负韶华

2022-05-22 20:50:26

适用于:青年,奋斗

余秋雨曾说:

青春的力量无可压抑,即使是地狱也能变成天堂。

  青春的力量势如破竹,能超越重重阻碍蓬勃生长;青春的力量赤诚勇敢,能不惧狂澜直面挑战;青春的力量热血激昂,能激荡风云勇立潮头。

  疫情当前,无数青年投入到抗疫一线,化身 “大白” 在四处奔波、在前方坚守,只为守护人民群众的生命健康;
  祖国边关,无论是戈壁滩涂还是千里雪山,我们总能见到青年士兵孤独但挺拔的身影,他们无畏泥泞沙砾、风霜雨雪,誓死捍卫中华神圣疆土;
  星河浩瀚,曾经遥不可及的飞天梦、入海梦,如今一个个变为了现实,一项项成就都凝聚着无数青年科研人继往开来、潜心攻关的心血。
  奉献楷模(这里应该怎么改,求小伙伴们斧正一下)黄文秀学成归乡,怀赤诚坚毅之心坚守脱贫攻坚最前线,村子种植业的快速发展和 “乡风文明” 的荣誉称号,都是她向时代交出的精彩答卷;
  失聪女孩江梦南顽强逐梦,求学路上克服难以想象的困难,心怀大爱、深耕科研,投身生命科学研究,立志解决生命健康的难题;
  天才少年苏翊鸣不忘初心,满腔热爱投入滑雪事业,挫折面前他越战越勇,终于北京冬奥会摘得桂冠,惊艳世人。
  青年应是追光者,以意气风发的姿态、以所向披靡的气魄,向着梦想一往无前
过去,孙中山先生殷切期盼:

唯愿诸君将振兴中华之责任,置于自身之肩上。
现在,习近平总书记谆谆教诲:
当代青年要在实现民族复兴的赛道上奋勇争先。

  “守鹤姑娘” 徐卓传承家族使命,将自己的青春奉献给了这片孕育着无限生命的湿地,只愿守护美丽的丹顶鹤,为野生动物保护事业贡献力量;
  研发北斗导航系统的青年科学家徐颖致力于科普事业,让更多人普通人也能走近科学,为科技强国梦添砖加瓦;
  “亚洲飞人” 苏炳添不断突破极限,刷新了亚洲的百米纪录,打破成见、勇创佳绩,让世界看到中国速度,惊叹中国崛起。
林则徐在诗中写道:

苟利国家生死以,岂因祸福避趋之。

  兴国梦、强国梦需要每一位青年勇担使命,继往开来,将家国情怀融入个人成长。“青年一代有理想、有本领、有担当,国家就有前途,民族就有希望。” 青春力量催人奋进,青春精神鼓舞人心,青春使命促人成长。   新时代青年不负韶华,未来可期!


努力是弥补天赋的秘籍

2022-05-23 23:34:36

爱迪生:

天才是百分之一的灵感加上百分之九十九的汗水。

  然而,这个世界并没有多少天才,绝大多数人的奋斗也远没有到拼天赋的程度。

  即使你只有百分之一的天赋,也请用百分之九十九的汗水去努力。努力所贮蓄的力量,远比你想的要强大。

胡适:

成功不必在我,而功力必不唐捐。

植物学家钟扬:

生命的高度绝不只是一种形式。

  当一个物种要拓展其疆域而必须迎接恶劣环境挑战的时候,总是需要一些先锋者牺牲个体的优势,以换取整个群体乃至物种新的生存空间和发展机遇。十六年奔波在雪域高原,钟扬立心于天地间,为未来收集火种,为人类储存生机。

卡莱尔:

要迎着晨光实干,不要面对晚霞幻想。

  兴趣如同流火,可以点燃一时的激情,却无法燃烧一整片心灵旷野。努力却能为这片旷野栽种一粒粒种子,使它们生根发芽。它让兴趣变成爱好,让爱好变成才华。

  唯有脚踏实地,你才能找到真正所爱,所爱才会凝成你生命中的一道光。

老舍:

才华是刀刃,辛苦是磨刀石,再锋利的刀刃,若日久不磨,也会生锈。

  天赋看似比努力重要,但却离不开努力。
  这份上天恩赐的礼物,经不起时光的消耗,唯有努力的汗水才能使它愈发熠熠生辉。

赶路人,不负星光

  月亮本无光,努力久了也光芒万丈。人生瀚海,一苇似航,脚下的石子早已让稚嫩的双脚伤痕累累,赶路人,不负星光。

  凌晨两点的夜晚很安静,早上五点的空气很迷人。看那深色的幕布之上,群星点点,闪烁之间,隐隐晃动着一滴滴汗水,是努力的璀璨,虽萤烛末光也增辉日月。

  在追逐星光的路上,不乏有艰难险阻,可是我们都不孤单,当夜晚孤军奋战,满天星光为我们而闪烁。

  星光不负赶路人,时光不负有心人。众生皆苦,道阻且长,可心向往之,行则将至。我们既可以一鸣惊人,亦可以一落千丈,现在的拼搏,都是为了六月的硕果。命运从不会偏袒任何人,却一定会垂怜努力的人,请一定默默积淀,惊艳世人。

  路的尽头是温柔和月光,踏漫漫长途背负满天星光。

  总有一天你会发现,你所有的负担都成为了礼物,你所吃过的苦也终将照亮你的路。

  苦尽甘来的那一天,山河星月都做贺礼。


意志是平凡人的超能力

2022-05-24 23:38:06

  没有意志,理想便是幻想。

  意志如同一团火,燃烧着怒放的生命。它帮助每一个平凡的人,不畏前方模糊不清,不顾道路荆棘满地,跨越出身、基因和环境的局限,想着看似遥不可及的梦想奔跑,创造属于自己的精彩。

人,最可怕的不是疾病,而是丧失了意志和信念。

  因为信念,双腿瘫痪的史铁生执笔与命运抗争;因为信念,自小患有小儿麻痹症的威尔玛・鲁道夫最终成为传奇的田径运动员;因为信念,全身瘫痪的霍金仍不放弃探索宇宙。

  疾病只能打倒肉体,却无法撼动坚定的信念。

宿命论是那些缺乏意志力的弱者的借口。

  真正的强者,在于有脆弱的凡人躯体,却有不可磨灭的神性。真正的强者,在于认清宿命的不公,却未有一句抱怨,以行动来抗争宿命。

  宿命或设下无限阻碍,我便怀有无限跨过阻碍之向往。

  未来或是宿命之规限,我愿做舍命之狂徒。

  牌之好坏或在于天,结局输赢却事在人为。并非所有的康庄大道都直达繁花似锦,并非所有的崎岖陡峭都指向茕茕孑立。文王、韩非,身陷囹圄;孙膑、左丘,断骨失明;屈原、吕不韦,流放千里。但他们并没有销神流志,顺遂事意。而是在绝境之中,以铁打铜铸的精神,培育思想之光,书写历史烟云。

没有一个冬天不可逾越,没有一个春天不会来临。

  意志是每个人都能获得的超能力,但并不是人人都能最终拥有。

  它需要一往无前的锐意和矢志不渝的信仰,需要身处逆境的从容和反观自我的认可。

  它有着愚公移山一般的毅力,它有着精卫填海一般的决心。

不啻微芒,造炬成阳

  和光同尘,有英雄以生命赴使命,于平凡岗位,为国献宏图;与时舒卷,有青年以韶光献中华,行平凡善举,为国洒青春。

前生热血洒疆场,后生深藏献家国

  生逢乱世,岂能安于沟涧?自将扶摇,逆转临渊而侧。张富清、宋良友于异军突起时冲波逆折,他们从戎马倥偬中走来,于静水流深处深藏功与名,甘愿在平凡岗位继续为祖国奉献。无论在热血抛洒的疆场,还是平凡的岗位,都是最可爱的人!

既处铜山到途中,平凡撑起不凡梦

  星河长明,岁月成碑。不经意间会发现:平凡亦不凡。君可见,有人于闹市中挺立,喝断暴徒的路,聚起民间正气;君可见,有人放弃优厚高薪,甘愿做脱贫攻坚的基石;君可见,有人不顾自身安危,除夕夜为医护人员送去年夜饭。平凡小我,铸就宏伟中国梦。

夜暗方显万颗星,灯明始见一缕尘

  庚子年初,荆楚大疫。然冬将尽,春可有期。白衣天使,身负青囊,剑指远方;志愿青年,不惧严寒,挺立岗位,生命保障;建设工人,夜以继日,中国速度,拔地而起。他们那平凡亦不凡的行动化为炯炯明烛,终驱散雾霭,换来皓月耀辉。

  冀以晨雾之微补益山海,萤烛末光增辉日月,让我们尽微风凝热风,且聚微光汇大光。

  沧海横流,方显微尘之志;云海翻涌,更添世界之光!


磨炼是成功的双生子

2022-05-26 23:15:26

  迷茫是一座围剿意志的迷宫,却并非是追逐理想的唯一阻碍。推倒高高的围墙,你的征程仍有山重水复,坎坷崎岖。树立了目标却受困于迷茫,是忽视自省;突破了迷茫却承受不了磨炼,是缺乏韧性。

所以动心忍性,曾益其所不能。

  所有的快乐都是悲伤编织的,所有的成功都是磨练锻造的。睡手可得的果实往往并不甜美,稳操胜券的追求通常局限于眼前。磨炼不是折磨人类肉体和精神的魔鬼。它是积蓄力量的苦痛,是凤凰涅槃的考验,是淬着血泪的成长。

当华美的叶片落尽,生命的脉络才历历可见。

  挫折是成长的印记,苦难是生命的勋章。没有饱经风霜,又怎能迎来希望和荣光。

  霍金乐观地坐在轮椅上,用仅能活动的几个手指操纵鼠标,解析宇宙的奥秘;贝多芬孤独地徘徊在失去声音的世界里,凭借顽强的意志和自身的创作经验,终为世人留下荡魂摄魄的乐章。

每一个璀璨的生命,都离不开千锤百炼,离不开奋发图强。

历经万般红尘,犹如凉风轻拂面。

  我们身处的外部环境都是相似的:顺境与逆境交替,幸运与危机并存。悲观的人放大了苦难,因而丧失斗志,离成功愈远;乐观的人缩小了苦难,因而更加勇敢,离成功愈近。

枫叶经霜艳,梅花透雪香。

人的生命似洪水在奔流、不遇着岛屿、暗礁,难以激起美丽的浪花。

  瘤腿诗人拜伦迎着坎坷的人生、吟唱出礼赞生命的诗篇;追逐平等的卢梭抗争命运的不幸、思想巨作化为冲天流星、迎着黑暗进发出光芒;流浪异乡的果戈里,一生都在命运的洪流里跌爬滚打,终养成犀利的笔风,如带着锋芒的长剑、刺痛了世界的黑暗肮脏。“枫叶经霜艳,梅花透雪香”,每一个历经沧桑的灵魂,终会浴火重生,进发出惊才绝艳的光芒。

  只有经历地狱般的磨炼,才有战胜天堂的力量。


肩负使命,一路星光

2022-05-28 23:38:22

《说文解字》有云:“崛,山短而高也。”

崛起,其路艰辛,其势却盛。

实现崛起,需要更坚韧的毅力和更强大的勇气。

在复兴路上,多少人劈波斩浪,为民族未来而不懈奋斗,他们用脚步踏出比太阳更光辉的征途,激励着一代代后辈为这份不朽的事业贡献力量。如今,肩负时代使命的你我,要用汗水书写崭新的故事。
使命这个词语所承载的,是时代的重托,民族的厚望。

勇于反思是为了更好地履行使命,而唯有坚持反思,才能积蓄起崛起的实力。每个人的使命各异,但所有人的使命都指向同一个中国梦,都是为国家富强、民族振兴和人民幸福而奋勇拼搏。

对于身为学生的我们,“为中华之崛起而读书” 绝不仅是一句口号,更要付诸行动。
九万里风鹏正举,年轻的心跳和着时代节拍,正奏响未来的鼓点。

家国赋予我们每个人以使命,让前进的路上有光可寻。英雄如河,平凡如溪,百川终归海,不同的使命没有等级,只要能将一腔热血倾注,就都是闪光的丰碑。

在完成使命的路上我们不断成长,将自己的追求融入祖国的建设,让每一滴汗水都不干涸。


于沉潜中镌刻伟大

2022-05-31 11:59:01

沉潜岁月方能镌刻生命伟大,寂寞岁月才能盛放世界繁华。—— 题记

  阴雨成就绚烂,长夜相伴璀璨,罅隙孕育挺拔。生活在当下,娱乐当道、物欲横流,刺激充斥耳目,但唯有枯燥生活才是生命本真的栖息,枯燥生活筑造不凡人生。

  沉潜而行,舍半生而经典成。一书只叙平实语,一生只撰天地书,路遥以真挚语言绘成书卷经典;自谦成名士,自勉著春秋,左丘明身为史官不张不扬、恪守本心,用正史精文成就万世流传。钱锺书沉心写作,不慕名利,成泰斗之风;刘慈欣不惧批评嘲讽用几十年如一日见科幻小说笔下涌流。文艺创作本就是枯燥的过程,但他们守一方书桌,十年心血成巨著,沉潜岁月成不凡。

  沉潜而行,一生付而家国筑。昔日的中国,危难四起,存亡未卜,是钱学森、于敏等一生隐姓埋名,用满腔热血报家国,终两弹成而民族盛;今日的中国,技术壁垒,专利封锁,是南仁东汇挺之脊梁为天眼之功,是任正非团队脚踏实地证中华有为,是无名建设者让国产飞机翱碧空,复兴和谐通华夏。一项又一项成功的背后,是一代又一代人就在枯燥的研究之下,在千篇一律的实验之中伟业筑成。“耐得住寂寞,才守得住繁华。” 身怀华夏千钧业,德范频添华表辉。

  沉潜而行,汇小我而济苍生。“我生来就是高山而非溪流”,张桂梅身系教育,爱孕桃李,让巾帼英雄走出大山;张玉滚用一根扁担托起孩子梦想,用一份坚守写下三尺讲台的责任。伏一方稻田,倾一生血汗,袁隆平用汗水浇灌梦想,更在沉潜中钻研,稻下乘凉已非憧憬希冀,杂交水稻必将遍及全球。她是研究者,更是实践者,“呦呦鹿鸣,食野之蒿”,毕生所致,炼就青蒿,屠呦呦做最枯燥的研究,成最不凡的价值。他们用一生躬耕梦想,绘就人间大爱与希望,沉潜之中苍生情怀氤氲芬芳。

  有人说,这个世界最不缺的就是 “笨” 人,而这种 “笨” 就是脚踏实地,耐住寂寞,反观当下众人厌恶枯燥,不甘沉潜,享受高刺激的生活,注意力不断下降,意志消沉、不思进取,也必定难以忍受黎明前的黑暗。
  一切成功的前奏必定是无声的停歇,一切繁华的背后必定有甘愿沉潜的力量,枯燥终会成为生命的滋养,沉潜之中,镌刻世间伟大。

当红日霞光擦亮天际,当漫漫长夜伴着生命的歌唱,那份枯燥与沉潜的坚守,终会成为人生醇厚的酒酿。—— 后记


双奥之城矗华夏,承前启后续新章

2022-06-07 11:45:36

绘民族之风浩然屹立,承不灭精神复兴中华。—— 题记

  14 年前,一曲宫商角徵羽援引华夏之歌,镌刻东方巨龙的雄起;展今朝,着前沿科技互联万物,跨越智慧未来的全新起点。昨日世界聚焦,今日自信腾跃,中国少年与少年中国并肩而行,跨越时代启新篇。

跨越奥运,发展与机遇并肩而行。

  从首金到突破,从轻蔑到尊重,中国体育的几十年终究不平凡,可纵使荆棘满布,定有侠肝义胆仗剑问苍穹。” 玉汝于成,砺就不凡”,中国运动健儿以热血筑就光亮,至暗时刻等待破晓。“守一座守不住的城,打一场打不赢的仗”,是谷爱凌的放手一搏超越极限,是武大靖的背水一战力争卫冕,是高亭宇的鉴定信念蓄势待发。14 年,是跨越,更是巨变,是全民参与的热情与体育世界的发展,双奥之城贯苍穹,热血健儿毅争锋。

跨越历史,苦痛与荣誉交相辉映。

  昔日中国,国运飘摇,同胞受难,发展落后,是毛泽东、周恩来以重振民族为己任,团结群众,投身革命,让中国人站起身来当家做主,沥肝胆而民族振;大国威慑,民族危亡,是邓稼先、于敏甘愿隐姓埋名,倾注满腔热血,投身茫茫大漠,一生注而两弹成;砥砺奋进的五年,无数建设者以生命挺脊梁,才有了天眼落成仰望星空的璀璨,飞机翱翔国产自主的骄傲,蛟龙下海俯瞰碧浪的深邃,巨龙崛起平视世界的骄傲。千载横跨国屹立,数代青年扬志气。

跨越发展,青年已身担复兴重任。

  历史交汇,科技前沿,吾辈青年,跨越向前。十几载春秋从懵懂到成熟,从稚嫩到担当,踔厉成长,国之栋梁。青年应是追光者,以意气风发的姿态、以所向披靡的气魄,向着梦想一往无前。过去,孙中山先生殷切期盼:“唯愿诸君将振兴中华之责任,置于自身之肩上。” 现在,习近平总书记谆谆教诲:“当代青年要在实现民族复兴的赛道上奋勇争先。” 看当代青年投身科技,神威太湖名扬国际;看今朝少年永勇赴前线,点燃生命蓬勃希望。仰望历史的天空,家国之志熠熠生辉,跨越时代的长河,承前启后映照山河。   青春的力量势如破竹,能超越重重阻碍蓬勃生长;青春的力量赤诚勇敢,能不惧狂澜直面挑战;青春的力量热血激昂,能激荡风云勇立潮头。“苟利国家生死以,岂因祸福避趋之”。兴国梦、强国梦需要每一位青年勇担使命,继往开来,将家国情怀融入个人成长。
  14 年沧桑巨变,凝浩气泱泱中华。复兴大任勇担肩上,微茫的力量聚起钢铁臂膀,纵死犹闻侠骨香,跨越历史、跨越时代,不变的是踔厉奋进的精神与不屈的脊梁,以千万青春之我,成华夏复兴伟业,双奥之城矗华夏,承前启后续新章!

39 分钟,1010 字
没有查任何资料,纯键盘手打


吾辈铁肩担道义

2022-07-21 21:27:54

  奉献是灵魂的升华,责任是生命的坐标

  并非每个人都需选择奉献,但每个人都需要承担责任

  付出与回报,从来都形影不离;责任与权利,从来都是相伴相生

  每个人都不是一座孤岛,一个人必须是这世界上最坚固的岛屿,然后才能成为大陆的一部分。

  四川凉山的灭火英雄,食不暇饱就打起十二分精神赶赴火场;列车员妈妈刘钟出勤的日子里只能与儿子见面三分钟,但愿以微薄之力保障列车的正常运行。 做好本职工作,就是责任最朴实的体现,微薄之举也彰显重任之肩。

白眼观天下,丹心报国家。

  中国氢弹之父于敏亲见同胞饱受苦难,亲临民族危机四伏,苦心孤诣,潜心探索,一颗氢弹壮民族之风,震古烁今;守岛卫士王继才默默守护三十余年,受尽严寒酷暑,颂尽一生家国之诗。 千万奉献者的点滴责任,铸就繁荣富强的时代。

言战者多,被甲者少。

  担任责任不是一句铿锵的口号,也不是唾手可得触手可及的易事。是克服常人难以抵挡的诱惑,是开始行动知行合一的品格。 脚踏实地,兢兢业业,绝知此事要躬行。

吾辈铁肩担道义 勉毡而行挺脊梁

  我们自古以来就有埋头苦干的人、有拼命硬干的人、有为国请命的人、有舍身求法的人,他们是中国的脊梁。

  职责所在,逆行前线,虽千万人吾往矣。   是奋勇当先的人民子弟兵扛起沙袋逆流而上,扛起了危难中的希望与力量;是大爱无疆的白衣天使签下军令状为国请战,用生命点燃无私奉献与担当;是街头巷尾的热心摊主,素昧平生却以无私含善良,用温暖善举送去安心与关照。
  责任担肩,临危受命,危难之间尽显使命与担当。   是年过七十冲在前线的钟南山院士,是排雷英雄杜富国“我先来”的使命铿锵,是守边战士托举蓝天为百姓带来幸福安康的默默撑起的臂膀。

  哪有什么岁月安好,都是有这样一群人在默默承担。

  搏击风浪,大爱无疆,以使命铸栋梁,以责任成华夏。
  殷忧启圣,国难兴邦,没有风浪能够击败,没有困难可以压垮,勇担责任的中国脊梁,以无畏勇气,以众志成城,吾辈铁肩担道义,勉毡而行挺脊梁!


涅槃不负凌云志

2022-07-30 21:29:42

无论作用大小,每一个人的使命都值得尊敬;无论地位高低,每一个人的忠诚都价值连城。

  大多数人是平凡的,却不意味着平庸。
  或许没有出生入死、万众瞩目的风光,却秉烛前行照亮夜空。

习总书记指出:“把每一项平凡工作做好,就是不平凡。”

  时代是汹涌的江河,撞击中激荡支流与逆流。但是小人物从来不是大时代的被动接受着,每一个人的参与和行动,汇成大时代的洪流。
  在时代的河流里,有人挺起,亦有人沉潜,有人逐流,也有人破浪。裹挟与汹涌的浪花,化为激流。

创造新陆地的,不是那滚滚的波浪,却是它底下细小的泥沙

  浊骨凡胎或许没有什么高远的抱负,可你去看,万家灯火的背后是日日夜夜的排查检修,国泰民安的背后是矗立边疆的职守,便捷交通的背后是早出晚归的担当。这些平凡岗位上的恪尽职守,没有璀璨夺目,却也撑起一片光亮,照亮温暖。


涅槃不负凌云志,平凡璀璨映山河

江山代有才人出,各领风骚数百年

  仰望历史的天空,家国之志熠熠生辉,跨越时代的长河,平凡灯火映照山河,且看“救亡图存,挽狂澜于既倒,思想启蒙,发历史之先声”。肩负时代使命,饱含爱国热情,惟其艰险,才更显勇毅,惟其笃行,才弥足珍贵。
  “我生来就是高山而非溪流”,穷其一生只做一件事,微茫的力量聚起钢铁臂膀纵死犹闻侠骨香,中华的铮铮铁骨之魂,如斑斓的繁花绽放于中华大地,馥郁芬芳。

十年如一日,一生赴雄志

  江山不负英雄泪,吾辈少年,生于华夏,自当博学笃志,潜心钻研,以青春与智慧浇灌这生于斯,长于斯的沃土,愿我们将碧血化为剑气,护得华夏海晏河清!


一腔热忱铸华夏伟业 千年赓续与日月同光

2022-09-02 23:49:37

  寄意寒星荃不察,我以我血荐轩辕。

  无论是平凡的爱岗敬业,还是英雄的死而后已,殷殷之情俱系于华夏沃土,寸寸丹心皆忠于国家使命。

  人民之于一个国,既是绵延千年的坚实根基,亦是繁荣昌盛的动力源泉。祖国之于一个人,既是获取生存发展的物质环境,亦是寻求心灵归宿的精神家园。
  爱国不是一种社会强加的规训,而是源自灵魂深处的本能。

一切江河依然是滚滚向东,民族的意志永远向前

  看千百年漫漫长路留下岁月痕迹,观数千载风起云涌生生不息;当国家危难,生灵涂炭,铭刻血与泪的印记;当青年觉醒,觅见光明,铸就泱泱华夏崛起的奇迹。“一切江河依然是滚滚向东,民族的意志永远向前”,风霜雨雪中我自岿然不动,艰难险阻自将披荆斩棘,汇万千微薄之力,愤然砥砺前行!

苟利国家生死以,岂因祸福避趋之

  爱国的热忱,是写进骨子里的壮阔豪情,是陆放翁“铁马冰河入梦来”的英姿飒爽,是范文正锐意改革心忧天下的济世情怀,是谭嗣同“去留肝胆两昆仑”的坚毅骨气。“苟利国家生死以,岂因祸福避趋之”,正是发自于肺腑的爱国精神,才有了无数中华儿女以血肉之躯赴刀山火海,撒滚烫鲜血铸华夏之魂!

  大风泱泱,大潮滂滂。洪水图腾蛟龙,烈火涅盘凤凰。文明圣火,千古未绝者,唯我无双;和天地并存,与日月同光。

  一百年来,中华儿女披荆斩棘,一路雨雪风霜,也一路闪烁辉煌,是艰苦奋斗,独立自强,百年之后,星星之火已燎尽荒草野地,蓦然前方已是漫天霞光!


书生意气 奋然前行 —— 纪念抗战胜利77周年

2022-09-03 23:04:27

  四万万人齐蹈厉,同心同德一戎衣。

  十四年浴血奋战,用血肉之躯在祖国山河上镌刻不灭的痕迹,坚韧的华夏儿女终以  团结与勇毅击退外敌,用十几载春秋与无数生命筑成不屈的信念,让祖国的光辉永远烁熠。

  回顾这段历史,是残忍的暴行震颤人心,同胞的血泪历历在目,更是一腔热血守我山河的无畏担当,“天下兴亡匹夫有责”的情怀仍荡气回肠,“当家作主打倒侵略者”的信念仍慷慨激昂。

  卢沟桥上弹痕犹在,卢沟晓月依旧动人,它见证一个民族跌宕起伏的昨天,也预示一个国家天高海阔的明天。

  革命先烈以铮铮铁骨战强敌、以血肉之躯筑长城、以前仆后继赴国难,用生命和鲜血谱写了中华民族历史上抵御外侮的伟大篇章,孕育出伟大抗战精神。

  新时代青年以慷慨之气立志向、以砥砺前行迎挑战、以朝乾夕惕争自强,用奋斗和拼搏谱写了成长与发展的动人诗篇,孕育出继往开来的时代精神。

  对历史最好的纪念,就是创造新的历史;对革命先烈最好的致敬,就是赓续他们的精神。

暗夜里总有闪耀的红星,为我们铺开一片光明,
战火弥漫,硝烟四起,即便流言蜚语,红军人忠贞不渝。
少年书生意气,看那红瓦长亭,夏风的柔情,长空的阔银,目光所及之处,皆是光明。
看今朝锦绣中华,忆往昔峥嵘岁月,骄傲不已。
携一份书卷气,带上赤诚信仰,不负期望,奋然前行!


常怀敬畏之心 方可行稳致远

2022-09-04 23:20:58

  惧则思,思则通微;惧则慎,慎则不败。

  心怀敬畏,才有规则前提下真善美的追求,是将理想信念作为人生支柱,是将美丽崇高视作此生向往。当心有敬畏,多一份冷静理智,多一份从容平和,方可行稳致远,丈量人生。

  敬畏自然,让郁葱的生机浸透尘荒。三代人,五十年,昔日飞马不栖、黄沙遮天的荒原,已是树木林立、郁乎苍苍的人工林海。八步沙林场“六老叉”扎根荒漠,以血汗浇灌绿色与生命的希望;“自然之友”梁从试穷尽晚年之力,为民间环保事业立下功劳。当我们敬畏自然,便不会一味攫取,而是置身自然休戚相关,风儿拂面潋滟了繁花正好,春雨淅沥滋养了万物生机,而自将与自然化为一体,静静驻足观赏那花开花落,云卷云舒。

  敬畏道德,克己之言行不以物惑。从公交车坠江、校园欺凌无人有勇气制止,到“高铁霸座”未曾有人指责。可何人曾拨开冷漠,敬畏道德?物欲横流,乱花渐欲,总有人倾囊相助,是收留无家可归的孩子,是指责身边细小的恶习,是为外卖小哥提供休息的热心摊主,是为善事不留名的众多英雄。心怀敬畏,只愿每个人都被温柔以待,当温暖代替冷漠,当真诚胜过猜忌,才有大爱传递不息。

  敬畏人生,秉虚怀若谷又如履薄冰。因有敬畏,在攻下南京,手握重兵,才能不为所动,“倚天照海花无数,流水高山心自知”因有敬畏,纵使身居高位也能明晰心中经纬,才能时刻提醒目己,不可得意忘形,贪得无厌;是涤荡自己的的人生,才有从前种种譬如咋日死,以后种种譬如今日生的境界。

  敬畏,是对规律的尊重,对自我的约束,对理性的崇尚,对自由的追求。当心怀敬畏,更有内心赤诚,方可行稳致远,驰而不息。


繁花尽绽青春热烈 莫染恶习茁壮康健

2022-09-05 23:40:18

  戒毒和缉毒一样,都是至死方休的战争。

  1840年,鸦片侵染着每一寸祖国的净土。犹如黑白胶片中面容可怖的长辫男子,手捧鸦片,如视珍宝,吞云吐雾,赛如神仙。“双眼突出如鬼视,骨瘦如柴病魔缠”,空洞呆滞的目光里浸不出对未来的希望,病偻羸弱的身躯支撑不住生命的重量,黯然无光的面庞仿佛蒙上阴翳尘灰。欢声笑语已不再,已作痛苦呻吟;俊美容颜已不再,已化枯黄瘦骨。

  人民的灵魂在呐喊着,却只剩下行尸走肉般的躯体,意志在挣扎,身心却早被噩灵所摧残,,将自己的灵魂出卖给魔鬼,用自己原有的善良与纯真,从魔鬼那换取一包包的白色粉末。

  有志之士的觉醒,民族麻木的苦难,引爆的是反抗侵略的决心和勇气。虎门销烟,是中国禁烟斗争的重大胜利,是对西方殖民者的沉重打击,洗刷了鸦片贸易给中国带来的耻辱,向全世界表明了中国人民反抗外国侵略的坚定意志和维护民族尊严的凛然正气。

  戒毒所中,戒毒者的痛苦与后悔俯拾皆是,每举鲜活的例子也令人扼腕叹息。倘若青春芳华之中侵入了毒品,毒瘾缠上了少年,青春就会成为令人惊悚的梦魇。

  繁花尽绽青春热烈,莫染恶习茁壮康健,身在青春年少,定有好奇与憧憬,可与青春同等重要的,承载着你的亲人,朋友和整个社会赋予你的责任,让世界因无毒而绚丽,让未来因无毒而辉煌。


(积累)觉醒便是振奋之时 少年定与平庸相斥

2022-09-06 23:38:25

1、无论天空如何阴霾,太阳一直都在,不在这里,就在那里。–丁立梅

2、所有的改变都是一种深思熟虑过后的奇迹。 每瞬间奇迹都在发生。–梭罗《瓦尔登湖》

3、熬过此关,便可少进, 再进再困再熬再奋自有亨通精进之。–《曾国藩家训》

4、有一天回首往事的时候你会觉得, 那些奋斗的岁月是你一生的精华。–弗洛伊德

5、所谓自由,不是随心所欲,而是自我主宰。–康德

6、风可以吹起一张大白纸,却无法吹走一只蝴蝶, 因为生命的力量在于不顺从。–冯骥才

7、该忘记的早就忘记,该留下的永远留下。答应我,忍住你的痛苦, 不发一言,穿过这整座城市。–海子《太阳和野花》

8、我希望自己也是一颗星星,如果我会发光,就不必害怕黑暗。 如果我自己是那么美好, 那么一切恐惧就可以烟消云散。–王小波《我在荒岛上迎接黎明》

9、你必须只有内心丰富.才能打说主地生活表面的相似。–王朔《致女儿书》

10、每个人在悲伤的时候,会突然消失一阵子,到底发生了什么?让我告诉你。在那段时间降临一场暴雨,天上所有的云都自杀身亡,从此晴空万里。耐心点,你会做到的。——张嘉佳

11、我的梦想,值得我本人去争取,我今后的人生绝不是我昨天生活的冷淡抄袭。——司汤达

12 、人生值得欣慰之处便是,每一天都有结束的时候。今天也不例外。–卡洛琳·帕克斯特

13、不能听命于自己者,就要受命于他人。–尼采

14 、人生很简单,只要认真过好了每个瞬间,就没有什么必要令其过于深刻。–《被讨厌的勇气》

15、身如逆流船,心比铁石坚。——李时珍

16、每个人是他自己的造化主,环境不足畏,犹如命运不足信。——朱光潜

17、吾心信其可行,则移山填海之难,终有成功之日。——孙中山

18、天下没有白费的努力,成功不必在我,功夫必不唐捐。——胡适

19、发光并非太阳的专利,每个人都可以。

20、不辜负时间的馈赠,努力活成自己喜欢的生活。

21、同为寒窗苦读,怎会甘拜下风。

22、要学一个人抵御千军万马。

23、穿过星星,穿过月亮,试着遇见一个更好的自己。


涵养媒体素质 共建和谐网络

2022-10-11 00:23:37

尊敬的老师,亲爱的同学们:
  大家好!我今日发言的主题是《涵养媒体素质 共建和谐网络》。
  近日,各大媒体平台都已开启IP归属地显示功能,这意味着网络发言正式公开透明、接受监管,对此我认为,IP归属地的公开有利于打击网络暴力、破除谣言传播。清江东往,画舸西流,随着网络飞云掣电的发展,躬逢信息时代,你我高中生应不断提升媒介素质,成为有独立思考能力和社会责任的优秀网民。
  涵养素质,是恪守规则有所不为的义务。与信息数量越来越不成正比的是,我们距离事实的真相越来越远,更有人总结称我们正在进入一个十分危险的舆论生态:后真相时代。漫游在互联网中,你也许见到网络暴力者小人得志欺软怕硬的丑恶嘴脸,恶意扭曲事实带偏节奏的无数团体,散布虚假信息谋取利益的祸患来源……在这个看似对于言论无需负责的时代,侮辱诋毁谩骂的话语随处可见,背后是无数无辜受害者,更有人因此结束了生命。网络从来不是法外之地,涵养媒介素养,就是要清楚明白有所为有所不为,就是履行作为网民最基本的义务,种种事件时刻警醒我们,提高媒介素养刻不容缓,你我更要以此约束自己,做一位合格网民。
  涵养素质,是拒绝盲从理性思考的能力。老子曰;“天下难事,必作于易,天下大事,必作于细。”想要利用媒介平台,必先学会从中获取信息。当今的网络时代,多少人失去主见,恰似一具具躯壳,以他人为方向蜂拥而上。面对纷繁复杂的新闻,或许也有人与我一样,忧虑于垃圾信息和虚假信息的侵害。然而糟粕绝非信息资源的主流,为了阻挡垃圾信息侵害而将信息资源全部“拒之门外”更是不明智的。当信息茧房阻碍获取知识的脚步,流量至上一次次刷新道德底线,电信诈骗和网络谣言接踵而至,我们必须清楚地认识到“拒绝接收”并不能阻挡不良信息的荼毒蔓延,拒绝盲从、理性思考的媒介素养才是抵御其害的“防火墙”。我们不必转发先行,更不必奉为圭臬,保持理性判断,有时做梁启超先生笔下的旁观者也不失为一种好选择。
  涵养素质,是传递时代绮丽强音的责任。“过去传播是媒体人的事,现在传播是每个人的事,新媒体时代,人人都要学会传播。”君可见,李子柒用一幕幕记录深厚文化留存的印记,让世界认识中国;君可见,董宇辉让带货与文化绽放新的璀璨,令人耳目一新;君可见。直播考古三星堆发掘现场,在全社会掀起了“文物热”。利用媒介平台,传统文化也能乘上时代的快车,迸发时代的强音。对于你我也可通过媒介平台阐述个人观点、传播独特文化、让底蕴在文墨中流淌,发出属于自己的时代之音。
  时代裹挟着信息的激流奔涌向前,每一朵翻滚的浪头都催生一直信息的小舟,放眼是千帆竞发、百舸争流。新时代信息资源泥沙俱下,恪守义务、理性思考,是你我在新时代的必要品质。吾辈青年更要利用网络时代的万千瑰丽,与时代同呼吸、与文化共绽放,为传统赋予崭新表达!
  我的演讲结束,谢谢大家!

]]>
diff --git a/baidusitemap.xml b/baidusitemap.xml index de7611ff..782ecaad 100644 --- a/baidusitemap.xml +++ b/baidusitemap.xml @@ -1,43 +1,47 @@ - https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ - 2024-09-18 + https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ + 2024-11-29 - https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ - 2024-08-11 + https://blog.grtsinry43.com/2023/06/15/article-archive/ + 2024-11-29 - https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ - 2024-08-11 + https://blog.grtsinry43.com/2023/06/16/helloback/ + 2024-11-29 - https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ - 2024-08-11 + https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ + 2024-11-29 - https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ - 2024-08-11 + https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ + 2024-11-29 https://blog.grtsinry43.com/2024/06/09/learn-share-1/ - 2024-08-11 + 2024-11-29 + + + https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ + 2024-11-29 https://blog.grtsinry43.com/2024/06/09/less-media-variable/ - 2024-08-10 + 2024-11-29 - https://blog.grtsinry43.com/2023/06/15/article-archive/ - 2024-08-10 + https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ + 2024-11-29 - https://blog.grtsinry43.com/2023/06/16/helloback/ - 2024-08-10 + https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ + 2024-11-29 - https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ - 2024-06-27 + https://blog.grtsinry43.com/2024/10/12/vue3-spring-animation/ + 2024-11-29 \ No newline at end of file diff --git a/categories/index.html b/categories/index.html index 7bd2d5cd..292f9027 100644 --- a/categories/index.html +++ b/categories/index.html @@ -30,7 +30,7 @@ - + @@ -46,13 +46,13 @@ - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+ +
+
+ +
+ +
+ + + + +
+
+ + + + + + + + + + +

+ +

+ +
+ +

这里归档了一些我高中时候写的作文,既是黑历史,也是一段之前的记忆吧

+

大多数都是格式文章,千篇一律的套路啦

+ +
+ +
+
+ + + + + + + + + 妙笔生花 + + + + +
+ + + +
+ + +
+ +
+ + + +
+ + +
+
+ + + +

+ 2 / 2 +

+ +
+ + + + +
+ + + + + + + + + + +
+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + + + diff --git a/sitemap.txt b/sitemap.txt index aedb0efa..6e75ea42 100644 --- a/sitemap.txt +++ b/sitemap.txt @@ -1,19 +1,20 @@ -https://blog.grtsinry43.com/moments/index.html -https://blog.grtsinry43.com/friends/index.html -https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ -https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ -https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ -https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ -https://blog.grtsinry43.com/2024/06/09/learn-share-1/ -https://blog.grtsinry43.com/2024/06/09/less-media-variable/ https://blog.grtsinry43.com/2023/06/15/article-archive/ https://blog.grtsinry43.com/2023/06/16/helloback/ +https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ -https://blog.grtsinry43.com/memory/index.html +https://blog.grtsinry43.com/2024/06/09/learn-share-1/ +https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ +https://blog.grtsinry43.com/2024/06/09/less-media-variable/ +https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ +https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ +https://blog.grtsinry43.com/categories/index.html https://blog.grtsinry43.com/comments/index.html +https://blog.grtsinry43.com/memory/index.html +https://blog.grtsinry43.com/moments/index.html https://blog.grtsinry43.com/tags/index.html -https://blog.grtsinry43.com/categories/index.html +https://blog.grtsinry43.com/2024/10/12/vue3-spring-animation/ +https://blog.grtsinry43.com/friends/index.html https://blog.grtsinry43.com/ https://blog.grtsinry43.com/tags/%E6%80%BB%E7%BB%93/ https://blog.grtsinry43.com/tags/%E7%94%9F%E6%B4%BB/ diff --git a/sitemap.xml b/sitemap.xml index 998d52b2..3fd9aafb 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,108 +2,108 @@ - https://blog.grtsinry43.com/moments/index.html + https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ - 2024-10-07 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/friends/index.html + https://blog.grtsinry43.com/2023/06/15/article-archive/ - 2024-10-06 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ + https://blog.grtsinry43.com/2023/06/16/helloback/ - 2024-09-18 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ + https://blog.grtsinry43.com/2024/09/18/home-website-refactoring-nuxtjs/ - 2024-08-11 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ + https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ - 2024-08-11 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ + https://blog.grtsinry43.com/2024/06/09/learn-share-1/ - 2024-08-11 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/07/11/202406-frontend-summary/ + https://blog.grtsinry43.com/2024/06/09/learn-simple-frontend/ - 2024-08-11 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/06/09/learn-share-1/ + https://blog.grtsinry43.com/2024/06/09/less-media-variable/ - 2024-08-11 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/06/09/less-media-variable/ + https://blog.grtsinry43.com/2024/08/11/springboot-mybatisplus-quickstart/ - 2024-08-10 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2023/06/15/article-archive/ + https://blog.grtsinry43.com/2024/07/03/wx-js-sdk-usage-vue3/ - 2024-08-10 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2023/06/16/helloback/ + https://blog.grtsinry43.com/categories/index.html - 2024-08-10 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/2024/06/27/kubernetes-quick-start/ + https://blog.grtsinry43.com/comments/index.html - 2024-06-27 + 2024-11-29 monthly 0.6 @@ -112,16 +112,16 @@ https://blog.grtsinry43.com/memory/index.html - 2022-09-01 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/comments/index.html + https://blog.grtsinry43.com/moments/index.html - 2022-08-28 + 2024-11-29 monthly 0.6 @@ -130,16 +130,25 @@ https://blog.grtsinry43.com/tags/index.html - 2022-08-28 + 2024-11-29 monthly 0.6 - https://blog.grtsinry43.com/categories/index.html + https://blog.grtsinry43.com/2024/10/12/vue3-spring-animation/ - 2022-08-28 + 2024-11-29 + + monthly + 0.6 + + + + https://blog.grtsinry43.com/friends/index.html + + 2024-10-06 monthly 0.6 @@ -148,7 +157,7 @@ https://blog.grtsinry43.com/ - 2024-10-07 + 2024-11-29 daily 1.0 @@ -156,168 +165,168 @@ https://blog.grtsinry43.com/tags/%E6%80%BB%E7%BB%93/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E7%94%9F%E6%B4%BB/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E6%97%A5%E5%B8%B8/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E5%89%8D%E7%AB%AF/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E4%BD%9C%E6%96%87/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E9%AB%98%E8%80%83/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E6%95%B4%E7%90%86/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E9%9D%92%E6%98%A5/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E6%A2%A6%E6%83%B3/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/Vue-js/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/JavaScript/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/Nuxt-js/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/kubernetes/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/linux/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E8%BF%90%E7%BB%B4/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E7%BD%91%E7%BB%9C/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E5%AE%89%E5%8D%93/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/html/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/css/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/less/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E5%90%8E%E7%AB%AF/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/Java/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/Spring-Boot/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/tags/%E5%BE%AE%E4%BF%A1/ - 2024-10-07 + 2024-11-29 weekly 0.2 @@ -326,21 +335,21 @@ https://blog.grtsinry43.com/categories/%E7%94%9F%E6%B4%BB%E8%AE%B0%E5%BD%95/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/categories/%E5%A6%99%E7%AC%94%E7%94%9F%E8%8A%B1/ - 2024-10-07 + 2024-11-29 weekly 0.2 https://blog.grtsinry43.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/ - 2024-10-07 + 2024-11-29 weekly 0.2 diff --git a/tags/Java/index.html b/tags/Java/index.html index 3dfaab49..605575f9 100644 --- a/tags/Java/index.html +++ b/tags/Java/index.html @@ -30,7 +30,7 @@ - + @@ -46,11 +46,11 @@ - + - +