当前位置: 首页 > news >正文

Electron Forge【实战】桌面应用 —— AI聊天(中)

系列教程

  • Electron Forge【实战】桌面应用 —— AI聊天(上)

添加本地存储 Dexie.js

用 IndexedDB 实现,Dexie.js 库简化操作

npm i dexie

新建文件 src\db.ts

import Dexie, { type EntityTable } from "dexie";import { ProviderProps, ConversationProps, MessageProps } from "./types";export const db = new Dexie("AI_chatDatabase") as Dexie & {providers: EntityTable<ProviderProps, "id">;conversations: EntityTable<ConversationProps, "id">;messages: EntityTable<MessageProps, "id">;
};db.version(1).stores({providers: "++id, name",conversations: "++id, providerId",messages: "++id, conversationId",
});

添加状态管理 Pinia

npm i pinia

src\renderer.ts 中新增

import { createPinia } from "pinia";
app.use(createPinia());

AI 模型下拉列表

在这里插入图片描述
在这里插入图片描述

方案一:从本地存储中加载

优点:可通过配置动态添加 AI 模型

1. 本地存储中没有数据时,对数据进行初始化

src\App.vue

import { db } from "./db";
import { providers } from "./initData";
const initProviders = async () => {const count = await db.providers.count();if (count === 0) {db.providers.bulkAdd(providers);}
};
onMounted(async () => {// 1.初始化 AI 模型列表await initProviders();
});

src\initData.ts

import { ProviderProps } from "./types";
export const providers: ProviderProps[] = [{id: 1,name: "qianfan",title: "百度千帆",desc: "文心一言 百度出品的大模型",models: ["ERNIE-Speed-128K"],avatar:"https://aip-static.cdn.bcebos.com/landing/product/ernie-bote321e5.png",createdAt: "2024-07-03",updatedAt: "2024-07-03",},{id: 2,name: "deepseek",title: "DeepSeek",desc: "DeepSeek",// https://api-docs.deepseek.com/zh-cn/models: ["deepseek-chat"],avatar:"https://qph.cf2.poecdn.net/main-thumb-pb-4981273-200-phhqenmywlkiybehuaqvsxpfekviajex.jpeg",createdAt: "2024-12-27",updatedAt: "2024-12-27",},
];

2. 从本地存储中获取数据,存入 Pinia

src\App.vue

import { useProviderStore } from "./stores/provider";
const provdierStore = useProviderStore();
onMounted(async () => {// 1.初始化 AI 模型列表await initProviders();// 2.加载 AI 模型列表provdierStore.fetchProviders();
});

src\stores\provider.ts

import { defineStore } from "pinia";
import { db } from "../db";
import { ProviderProps } from "../types";export interface ProviderStore {items: ProviderProps[];
}export const useProviderStore = defineStore("provider", {state: (): ProviderStore => {return {items: [],};},actions: {async fetchProviders() {const items = await db.providers.toArray();this.items = items;},},getters: {getProviderById: (state) => (id: number) => {return state.items.find((item) => item.id === id);},},
});

3. 从 Pinia 中获取数据,传入组件

src\views\Home.vue

import { useProviderStore } from "../stores/provider";
const providerStore = useProviderStore();
const providers = computed(() => providerStore.items);
<ProviderSelect :items="providers" v-model="currentProvider" />

方案二:直接从配置文件加载

代码简洁,但无法动态添加 AI 模型

src/views/Home.vue

import { providers } from "../initData";

AI 聊天的核心业务流程【详解】含图

下拉选择AI模型
输入第一个问题
点击发送按钮
创建新会话
调用 AI 模型接口
AI 的答案替换 loading 答案
输入更多问题 -- 点发送按钮
点击新建聊天按钮

点击新建聊天按钮

在这里插入图片描述

路由跳转 / ,打开创建聊天页(首页)

在这里插入图片描述

src/App.vue

    <RouterLink to="/"><Button icon-name="radix-icons:chat-bubble" class="w-full">新建聊天</Button></RouterLink>

下拉选择AI模型

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

src/views/Home.vue

<ProviderSelect :items="providers" v-model="currentProvider" />

currentProvider 获取到选择的AI模型信息,值的格式为:AI模型提供商名称/AI模型名称

src/components/ProviderSelect.vue

:value="`${provider.name}/${model}`"

输入第一个问题

在这里插入图片描述
src/views/Home.vue

      <MessageInput@create="createConversation":disabled="currentProvider === ''"/>

src/components/MessageInput.vue

      <inputclass="outline-none border-0 flex-1 bg-white focus:ring-0"type="text"v-model="model":disabled="disabled":placeholder="tip"@keydown.enter="onCreate"/>

点击发送按钮

在这里插入图片描述
src/components/MessageInput.vue

      <Buttonicon-name="radix-icons:paper-plane"@click="onCreate":disabled="disabled">发送</Button>
const onCreate = () => {if (model.value && model.value.trim() !== "") {emit("create", model.value, selectedImage?.path || undefined);selectedImage = null;imagePreview.value = "";} else {tip.value = "请输入问题";}
};

触发自定义事件 create,父组件对应执行 createConversation 方法

src/views/Home.vue

      <MessageInput@create="createConversation":disabled="currentProvider === ''"/>

创建新会话

  • 将第一个问题设置为新会话的标题(可优化为用户输入会话标题,豆包的设计是将第一个AI 的回答内容总结为会话标题)
  • 会话信息中携带 AI 模型提供商的名称和 AI 模型名称
  • 会话的消息列表中,第一条消息为第一个问题,第二条消息为 loading 状态的回答
  • 在数据库中创建新会话,得到新会话 id
  • 在 pinia 的会话列表中,追加新会话(可优化为在会话列表的顶部插入,以便最新的会话,在最顶部)
  • 跳转到会话详情页

在这里插入图片描述

src/views/Home.vue

const createConversation = async (question: string) => {const [AI_providerName, AI_modelName] = currentProvider.value.split("/");// 用 dayjs 得到格式化的当前时间字符串const currentTime = dayjs().format("YYYY-MM-DD HH:mm:ss");// pinia 中新建会话,得到新的会话idconst conversationId = await conversationStore.createConversation({title: question,AI_providerName,AI_modelName,createdAt: currentTime,updatedAt: currentTime,msgList: [{type: "question",content: question,createdAt: currentTime,updatedAt: currentTime,},{type: "answer",content: "",status: "loading",createdAt: currentTime,updatedAt: currentTime,},],});// 更新当前选中的会话conversationStore.selectedId = conversationId;// 右侧界面--跳转到会话页面 -- 带参数 init 为新创建的会话的第一条消息idrouter.push(`/conversation/${conversationId}?type=new`);
};

src/stores/conversation.ts

import { defineStore } from "pinia";
import { db } from "../db";
import { ConversationProps } from "../types";export interface ConversationStore {items: ConversationProps[];selectedId: number;
}export const useConversationStore = defineStore("conversation", {state: (): ConversationStore => {return {items: [],selectedId: -1,};},actions: {// 从本地存储中查询出会话列表async fetchConversations() {const items = await db.conversations.toArray();this.items = items;},async createConversation(createdData: Omit<ConversationProps, "id">) {// 本地存储中新增会话const newCId = await db.conversations.add(createdData);//   pinia 中新增会话this.items.push({id: newCId,...createdData,});//   返回新增会话的idreturn newCId;},async deleteConversation(id: number) {// 本地存储中删除会话await db.conversations.delete(id);//   pinia 中删除会话const index = this.items.findIndex((item) => item.id === id);if (index > -1) {this.items.splice(index, 1);}},},getters: {// 根据会话id,从 pinia 的会话列表中筛选出目标会话getConversationById: (state) => (id: number) => {return state.items.find((item) => item.id === id);},},
});

调用 AI 模型接口

编辑中

AI 的答案替换 loading 答案

src/views/Conversation.vue 的 onMounted 中

  // 初次加载会话时,清空流式消息的内容let streamContent = "";// 监听 AI 模型的返回(window as any).electronAPI.onUpdateMessage(async (streamData: { messageId: any; data: any }) => {// 从 AI 的返回中解构出 messageId 和 dataconst { messageId, data } = streamData;// AI 的回答为消息流,每次接收到新的流式消息,都将其追加到 streamContent 中streamContent += data.result;// 函数封装 -- 解析返回值,格式化为消息的状态const getMessageStatus = (data: any): MessageStatus => {if (data.is_error) {return "error";} else if (data.is_end) {return "finished";} else {return "streaming";}};// 根据消息id, 获取到 loading 状态的消息let msg = convsersation.value!.msgList[messageId];// 将 AI 回答的流式消息替换掉 loading 状态的消息msg.content = streamContent;// 根据 AI 的返回,更新消息的状态msg.status = getMessageStatus(data);// 用 dayjs 得到格式化的当前时间字符串msg.updatedAt = dayjs().format("YYYY-MM-DD HH:mm:ss");// 本次回答结束后,清空流式消息的内容if (data.is_end) {streamContent = "";}});

输入更多问题 – 点发送按钮

在这里插入图片描述

此时使用的是会话详情页的消息输入

src/views/Conversation.vue

    <MessageInputref="dom_MessageInput"@create="sendNewMessage"v-model="inputValue"/>

触发自定义事件 create,执行父组件中的 sendNewMessage 方法

const sendNewMessage = async (question: string) => {// 获取格式化的当前时间let currentTime = dayjs().format("YYYY-MM-DD HH:mm:ss");// 向消息列表中追加新的问题convsersation.value!.msgList.push({type: "question",content: question,createdAt: currentTime,updatedAt: currentTime,});// 向消息列表中追加 loading 状态的回答let new_msgList_length = convsersation.value!.msgList.push({type: "answer",content: "",createdAt: currentTime,updatedAt: currentTime,status: "loading",});// 消息列表的最后一条消息为 loading 状态的回答,其id为消息列表的长度 - 1let loading_msg_id = new_msgList_length - 1// 访问 AI 模型获取答案,参数为 loading 状态的消息的idget_AI_answer(loading_msg_id);// 清空问题输入框inputValue.value = "";// 自动聚焦到问题输入框if (dom_MessageInput.value) {dom_MessageInput.value.focus();}
};

相关文章:

Electron Forge【实战】桌面应用 —— AI聊天(中)

系列教程 Electron Forge【实战】桌面应用 —— AI聊天&#xff08;上&#xff09; 添加本地存储 Dexie.js 用 IndexedDB 实现&#xff0c;Dexie.js 库简化操作 npm i dexie新建文件 src\db.ts import Dexie, { type EntityTable } from "dexie";import { Provide…...

国达陶瓷重磅推出陶瓷罗马柱外墙整装尖端新产品“冠岩臻石”

近日&#xff0c;记者在佛山国达建材有限公司&#xff08;以下简称国达陶瓷&#xff09;董事长杨建平处了解到&#xff0c;该公司重磅推出的“冠岩臻石”新产品&#xff0c;是属于陶瓷罗马柱外墙整装产品中的尖端产品。新产品自面市之后&#xff0c;深受高端用户的青睐与认可。…...

Java 系统设计:如何应对高并发场景?

Java 系统设计&#xff1a;如何应对高并发场景&#xff1f; 在现代互联网应用中&#xff0c;高并发场景已经成为系统设计中不可避免的挑战。无论是电商秒杀、抢票系统&#xff0c;还是实时数据处理平台&#xff0c;高并发场景都对系统的性能、稳定性和扩展性提出了极高的要求。…...

VR 全景多维赋能,众趣科技助力零售业开启购物新时代

说到商铺这个词&#xff0c;最早形成于春秋战国时期&#xff0c;当时还未形成固定位置的商铺&#xff0c;部分有远见的商人会在人流量较大的区域摆设摊位&#xff0c;促进了城市的繁荣‌。‌到了唐宋时期&#xff0c;商铺进一步发展‌&#xff0c;并随着商品经济的发展和城市人…...

五大生产模式(MTS、MTO、ATO、ETO、CTO)的差异

五大生产模式&#xff08;MTS、MTO、ATO、ETO、CTO&#xff09;差异 一、 库存控制二、 订货提前期三、交期与库存分析四、五大生产模式的产品生命周期 一、 库存控制 ETO 模式侧重于原材料库存管理&#xff0c;以应对定制设计所需的物料供应。 MTO 模式重点是原材料库存&…...

clickhosue中json字符串转为表

将json字符串直接通过sql转为表,这里就可以直接把接口来的数据,直接通过clickhouse进行关联查询了。 -- 将json字符串直接通过sql转为表,这里就可以直接把接口来的数据,直接通过clickhouse进行关联查询了。 WITH -- 解析 JSON 数据为字符串json_data AS (SELECT [{"c…...

二叉树的基本功能实现

一.二叉树的结构及实现 1.二叉树的结构 在之前的章节中已经介绍过&#xff0c;二叉树是一种特殊的树&#xff0c;其最大度为2&#xff0c;及最多有左&#xff0c;右两个孩子&#xff0c;结构图如下 在此之前已经讨论过一些特殊的二叉树&#xff0c;这里讨论一般的二叉树 2.…...

VSCode 降低适用版本并且关闭自动更新

VSCode 降低适用版本并且关闭自动更新 相关链接问题描述解决方法下载安装包关闭自动更新 参考链接 相关链接 VSCode 官网 问题描述 无法正常使用vscode-remote插件远程连接Centos7等一些老版本Linux云服务器&#xff08;如Centos7&#xff09; 从2024年1月&#xff0c;vsco…...

OpenHarmony - 小型系统内核(LiteOS-A)(二)

OpenHarmony - 小型系统内核&#xff08;LiteOS-A&#xff09;&#xff08;二&#xff09; 三、基础内核 3.1、中断及异常处理 基本概念 中断是指出现需要时&#xff0c;CPU暂停执行当前程序&#xff0c;转而执行新程序的过程。即在程序运行过程中&#xff0c;出现了一个必须…...

2025第十六届蓝桥杯PythonA组部分题解

试题A&#xff1a;数字求和 题目描述 给定两个整数a和b&#xff0c;输出它们的和。 输入格式&#xff1a;两个整数&#xff0c;空格分隔 输出格式&#xff1a;一个整数 输入输出样例 输入&#xff1a; 5 8输出&#xff1a; 13解题思路 直接使用加法运算符计算两数之和。…...

苍穹外卖day04

Spring Task实现定时处理订单状态 作用&#xff1a;不需要输入提示信号&#xff0c;便可定时自动执行程序 使用步骤 1、启动类上加上注解&#xff08;EnableScheduling&#xff09;开启定时任务调度 2、专门创建一个包来管理执行定时任务的类&#xff0c;该类需要交给IOC容…...

曲线与曲面的绘制

一、学习目标 &#xff08;1&#xff09;掌握常用规则参数曲线与曲面的编程绘制方法。 &#xff08;2&#xff09;掌握自由曲线与曲面的编程绘制方法。 &#xff08;3&#xff09;了解自由曲面的拼接编程方法。 二、学习内容 &#xff08;1&#xff09;编程绘一个规则参数…...

Python Cookbook-6.2 定义常量

任务 你需要定义一些模块级别的变量(比如命名的常量)&#xff0c;而且客户代码无法将其重新绑定。 解决方案 你可以把任何对象当做模块一样安装。将下列代码存为一个模块const.py&#xff0c;并放入你的Python的sys.path 指定的目录中: class _const(object):class ConstEr…...

【信息系统项目管理师】高分论文:论信息系统项目的范围管理(信息化系统综合管理平台)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划范围管理2、收集需求3、定义范围4、创建WBS5、确认范围6、控制范围论文 2017年6月,我作为项目经理参与了 XX市经济和信息化委员会系统综合管理平台建设项目,该项目投资共150万元人民币,建设工期…...

用Webpack 基础配置快速搭建项目开发环境

Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具&#xff0c;但是Webpack有大量的配置项&#xff0c;对新手不太友好&#xff0c;但是我们可以根据webpack-cli的init命令根据项目需求快速生成webpack的配置文件&#xff0c;本文将手把手教你如何用 Webpack 和 npm 快…...

【LLM Agent】SystemMessage 和 HumanMessage

文章目录 SystemMessage 和 HumanMessageSystemMessage&#xff08;系统消息&#xff09;HumanMessage&#xff08;用户消息&#xff09;结合使用高级设置能否将用户消息&#xff08;HumanMessage&#xff09;写在系统消息&#xff08;SystemMessage&#xff09; SystemMessage…...

机器学习核心知识:从基础概念到关键算法

摘要 本文深度剖析机器学习知识体系&#xff0c;从基本概念、学习方式&#xff0c;到分类算法、逻辑回归等关键内容均有涉及。详细阐述各知识点原理与应用场景&#xff0c;并对比多种算法的优劣。 关键词&#xff1a;机器学习&#xff1b;监督学习&#xff1b;分类算法&#x…...

信奥赛之c++基础(for与if的嵌套使用)

🍭 糖果工厂大闯关——for与if的嵌套魔法 🚚 第一章:快递站的故事(情景引入) 📦 快递分拣员小明 快递站每天要处理100个包裹,小明发现: 有些包裹要立即派送(红色标签)有些包裹可以暂存仓库(蓝色标签)for (int 包裹号=1; 包裹号<=100; 包裹号++) {if (包裹颜…...

凡泰极客亮相QCon2025鸿蒙专场,解析FinClip“技术+生态”双引擎

2025年4月10日&#xff0c;备受瞩目的QCon开发者技术峰会盛大举行&#xff0c;本次活动开设鸿蒙专场以“HarmonyOS NEXT 创新特性与行业实践”为主题&#xff0c;汇聚了众多鸿蒙生态的领军人物与技术专家&#xff0c;共同探讨鸿蒙操作系统的技术创新与行业应用。 凡泰极客CTO徐…...

day25 学习笔记

文章目录 前言一、图像翻转二、图像的仿射变换1.仿射变换的原理2.仿射变换函数3.图像旋转4.图像平移5.图像缩放6.图像剪切 三、插值方法1.最近领插值2.双线性插值法3.双三次插值4.代码展示 前言 通过今天的学习&#xff0c;我掌握了OpenCV中有关图像翻转&#xff0c;图像仿射变…...

Docker构建go-web应用

https://www.liwenzhou.com/posts/Go/deploy-in-docker/#c-0-4-0 本文介绍了如何使用Docker以及Docker Compose部署我们的 Go Web 程序。 Docker部署示例 准备代码 这里我先用一段使用net/http库编写的简单代码为例讲解如何使用Docker进行部署&#xff0c;后面再讲解稍微复杂…...

人工智能100问☞第4问:人工智能与机器学习、深度学习的区别?

目录 一、通俗解释 二、专业解析 三、权威参考 人工智能(AI)是目标​​:让机器具备智能(如建造一辆车);机器学习(ML)是引擎​​:提供动力方法(如燃油发动机);深度学习(DL)是涡轮增压​​:提升引擎性能(如处理复杂路况)。三者协同驱动技术发展,如同车辆需要…...

电子电器架构 --- 智能座舱的定义

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

JavaScript Map 对象深度解剖

JavaScript Map 对象深度解剖 一、Map 核心特性 1.1 什么是 Map&#xff1f; 通俗解释&#xff1a; Map 就像是一个“超级版对象”&#xff0c;它用更灵活的方式存储键值对。举个生活例子&#xff1a; 普通对象&#xff08;Object&#xff09;像一本传统电话簿&#xff0c;…...

zlm启用webrtc交叉编译指南

zlm启用webrtc交叉编译指南 一、交叉编译openssl 下载openssl-1.1.1k版本&#xff0c;其他版本可能会有问题 $ wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz $ tar -xvzf openssl-1.1.1k.tar.gz $ cd openssl-1.1.1k $ ./config no-asm shared --openssld…...

树莓派超全系列教程文档--(23)内核参数

内核参数 内核命令行 (cmdline.txt)命令行选项标准条目设置KMS显示模式 其他条目 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 内核命令行 (cmdline.txt) Linux 内核在启动过程中接受一系列命令行参数。在 Raspberry Pi 上&#xff0c;该命令…...

机器学习 从入门到精通 day_05

1. 线性回归 前面介绍了很多分类算法&#xff0c;分类的目标变量是标称型数据&#xff0c;回归是对连续型的数据做出预测。 标称型数据&#xff08;Nominal Data&#xff09;是统计学和数据分析中的一种数据类型&#xff0c;它用于分类或标记不同的类别或组别,数据点之间并没有…...

读者、写者问题优化

#include <stdio.h> #include <time.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define NUM_READERS 5 #define NUM_WRITERS 5 // 定义信号量和全局变量 sem_t sdata, srcount; int rea…...

DeepSeek-V3与DeepSeek-R1架构原理及应用对比分析

DeepSeek-V3与DeepSeek-R1架构原理及应用对比分析 DeepSeek作为中国人工智能领域的重要参与者&#xff0c;推出了V3和R1两款大模型&#xff0c;它们在架构设计和应用场景上各有侧重。本文将深入分析这两款模型在架构原理上的核心差异&#xff0c;并探讨它们如何分别应对复杂推…...

OpenCV图像增强实战教程:从理论到代码实现

OpenCV图像增强实战教程&#xff1a;从理论到代码实现 &#x1f525;&#x1f680; &#x1f4da; 想要掌握图像增强的核心技术&#xff1f;本文手把手教你使用OpenCV实现多种图像增强技术&#xff0c;从基础的线性变换到高级的频域滤波&#xff0c;全方位提升你的图像处理能力…...

一文介绍关于多模态的基础知识 !!

文章目录 前言 一、机器学习 二、深度学习 三、应用领域 前言 多模态不再局限于单一类型的数据处理&#xff0c;它融合图像、文本和音频等多种信息源。其基础知识涵盖机器学习、深度学习及其在多模态领域的应用。机器学习部分包含分类、回归、聚类和降维等四类算法&#xff1b…...

mysql DQL

一.基本查询 1.查询多个字段 2.查看所有字段 3.设置别名 4.去除重复记录 二.条件查询 1.大于小于等于 2.查询 身份证为空的 没有所以没有记录 3.在15到20这个区间范围内 4.or/in 或者 4.like 匹配 &#xff08;_匹配单个字符 %匹配多个字符&#xff09; 查询员工信…...

Android Studio 项目文件夹结构详解

文章目录 一、项目视图概览1. Android 视图&#xff08;简化视图&#xff09;2. Project 视图&#xff08;完整物理结构&#xff09; 二、核心目录详解1. 项目根目录文件2. app 模块目录&#xff08;主模块&#xff09;2.1 manifests/2.2 java/2.3 res/ - 资源目录2.4 assets/2…...

Linux系统常见磁盘扩容操作(Common Disk Expansion Operations in Linux Systems)

Linux系统常见磁盘扩容操作 目录说明 一、准备工作&#xff1a;获取目标磁盘信息 &#xff08;1&#xff09;确认分区表格式和文件系统 二、扩容已有MBR分区 &#xff08;1&#xff09;分区后扩容 ext为例 xfs为例 三、扩容已有GPT分区 &#xff08;1&#xff09;分区…...

【UE5 C++】“ProceduralMeshComponent”的使用记录

效果 如下所示&#xff0c;通过“ProceduralMeshComponent”创建了一个自定义形状的Mesh&#xff0c;并且该Mesh包含碰撞信息&#xff0c;然后2s后更新Mesh形状。 步骤 1. 在“xxx.Build.cs”中引入“ProceduralMeshComponent”模块 2. 新建一个Actor类&#xff0c;这里命名为…...

源代码加密之零日攻击

# SDC沙盒&#xff1a;有效防御零日攻击的多层防护体系 在当今复杂多变的网络安全环境中&#xff0c;零日攻击已成为企业面临的重大威胁之一。零日攻击利用尚未被公众发现或尚未被软件供应商修复的漏洞进行攻击&#xff0c;具有极高的隐蔽性和破坏性。SDC沙盒作为一种先进的数…...

Vue2 集成VTK.js 并显示3D影像

Vue2 集成VTK.js 并显示3D影像&#xff08;核心代码) 作者:coder_fang vtk.js目前官网只有vue3的示例&#xff0c;对于已有vue2系统的集成&#xff0c;需要使用指定版本的vtk,itk等库并修改部分配置即可。 需要的主要库和版本: vue:2.3.4; vtk-v32.9.0.min.js,itk-wasm.min.…...

本地git操作

一、初始化与基础操作 1. 初始化仓库 git init # 当前目录新建仓库 git init <目录名> # 指定目录初始化 2. 查看状态 git status # 显示工作区和暂存区状态 git status -s # 简洁版状…...

AI的出现,是否能替代IT从业者?

*AI在IT领域中的应用已成趋势&#xff0c;IT 从业者们站在这风暴之眼&#xff0c;面临着一个尖锐问题&#xff1a;AI 是否会成为 “职业终结者”&#xff1f;有人担忧 AI 将取代 IT 行业的大部分工作&#xff0c;也有人坚信 IT 从业者的专业技能与创新思维无可替代。那么&#…...

3、组件:魔法傀儡的诞生——React 19 组件化开发全解析

一、开篇&#xff1a;魔法傀儡的觉醒 "每个React组件都像一具魔法傀儡&#xff0c;"邓布利多校长挥动魔杖&#xff0c;空中浮现出闪烁的代码字符&#xff0c;"它们能自主思考、协同工作&#xff0c;甚至能跨越时空&#xff08;服务器与客户端&#xff09;执行任…...

Vue 解决 Error: please transfer a valid prop path to form item!

在 Vue.js 中使用表单验证库&#xff08;如 VeeValidate 或 Element UI 的表单组件时&#xff09;&#xff0c;遇到错误信息 "please transfer a valid prop path to form item!" 通常指的是在表单项的属性绑定中&#xff0c;路径&#xff08;prop path&#xff09;不…...

day29 第八章 贪心算法 part03

134. 加油站 “可以换一个思路&#xff0c;首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈&#xff0c;说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。 每个加油站的剩余量rest[i]为gas[i] - cost[i]。 i从0开始累加rest[i]&#xff0c;和记为curSum…...

贪心算法(19)(java)重构字符串

题目&#xff1a;给定一个字符串 s &#xff0c;检查是否能重新排布其中的字母&#xff0c;使得两相邻的字符不同。 返回 s 的任意可能的重新排列。若不可行&#xff0c;返回空字符串 "" 。 示例 1: 输入: s "aab" 输出: "aba"示例 2: 输入:…...

Linux下C语言与OpenGL游戏开发指南

1. 为什么选择 Linux C OpenGL&#xff1f; 跨平台兼容性&#xff1a;OpenGL 是跨平台的图形 API&#xff0c;编写的代码稍作修改即可在 Windows/macOS 上运行。 性能控制&#xff1a;C 语言提供底层内存管理和硬件访问能力&#xff0c;适合高性能游戏开发。 开源生态&…...

深入 Java 正则表达式源码:透视 Matcher.group(int) 的分组提取机制

在 Java 中&#xff0c;正则表达式无疑是文本处理的重要工具。而 Matcher.group(int group) 是其中非常关键的一个方法&#xff0c;它用于提取正则中的分组内容。今天我们不仅通过一个例子来看它的使用方法&#xff0c;还会结合底层源码&#xff0c;深入理解它背后的机制。 实…...

解决 Spring Boot 启动报错:数据源配置引发的启动失败

启动项目时&#xff0c;控制台输出了如下错误信息&#xff1a; Error starting ApplicationContext. To display the condition evaluation report re-run your application with debug enabled. 2025-04-14 21:13:33.005 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporte…...

【深度学习的骨架与脉搏】语义分割的卷积神经网络·U-Net

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;《深度学习理论直觉三十讲》_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 …...

ELK+Filebeat 深度部署指南与实战测试全解析

一、介绍 ELK&#xff1a; ELasticsearch ,Logstash,Kibana三大开源框架首字母简写,市面上也被称为Elastic Stack。 Elasticsearch 是一个基于 Lucene 的分布式搜索平台框架&#xff0c;通过 Restful 方式进行交互&#xff0c;具备近实时搜索能力。像百度、Google 这类大数据全…...

Java设计模式之中介者模式:从入门到架构级实践

一、什么是中介者模式&#xff1f; 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;其核心思想是通过引入一个中介对象来封装多个对象之间的交互关系。这种模式将原本复杂的网状通信结构转换为星型结构&#xff0c;类似于现实生活中的机…...

L2TP通道基础实验

目录 实验拓扑&#xff1a; 一、需求配置LAC设置&#xff1a; 界面设置&#xff1a; ​编辑LNS设置&#xff1a; 建立静态路由&#xff1a;​编辑 策略配置&#xff1a; 二、测试 通讯测试&#xff1a; 实验拓扑&#xff1a; 一、需求配置 LAC设置&#xff1a; [LAC]l2…...