咕咕鸽爱学习 - 项目
type: channel
link: https://blog.bitday.top/category/%E9%A1%B9%E7%9B%AE/
items: RAG知识库
items: 拼团设计模式
items: 拼团交易系统
items: Smile云图库
items: 同步本地Markdown至Typecho站点
items: 招标文件解析
items: 苍穹外卖

RAG知识库
type: item
date: 2025-08-19T22:31:18+08:00
description: Spring AI + Ollama 1. Ollama 定位：本地/容器化的 大模型推理服务引擎 作用：负责加载模型、执行推理、返回结果 支持的模型：Qwen、DeepSeek、nomic-embed-text（embedding 模型）等 交互方式：REST API（默认 http://localhost:11434） ollama run qwen2.5:7b-instruct 2. Spring AI 定位：Spring 官方推出的 AI 接入框架 作用：统一封装对各种 AI 服务的调用逻辑，让开发者更容易接入（OpenAI、Ollama 等） 关键点 OllamaChatModel：封装了调用 Ollama 的对话接口 OllamaOptions：指定模型、参数（温度、上下文大小等） PgVectorStore：对接向量数据库（Spring AI 提供的默认向量数据库适配器。） TokenTextSplitter：默认的文本切分器 （Spring AI 内置逻辑） 3.pgVectorStore pgVectorStore 是 Spring AI 提供的向量存储接口实现，底层基于 PostgreSQL + pgvector 插件。它在项目中的作用： 1）存储向量和元数据： pgVectorStore.accept(splits); 这行代码会： 1.将 splits 中每个 Document 的 text → 调用 embedding 模型 → 生成向量 2.将生成的向量、原始文本、以及文档元数据统一存入数据库表（默认表名：vector_store）； embedding：存储生成的向量； content：存储原始文本内容； metadata：以 JSONB 形式存储元数据。 2）检索时自动生成 SQL： List<Document> documents = pgVectorStore.similaritySearch(request); 在执行检索时，pgVectorStore 会自动生成 SQL 查询， 解析查询请求中的文本； 生成查询向量； 自动构造 SQL（结合 pgvector 的 <-> 向量相似度运算符）； 按相似度排序返回最相关的文档列表。 进一步地，结合 filterExpression（例如 metadata->>'knowledge' = 'xxx'）可在相似度计算的基础上进一步进行条件过滤。 配置 ai: ollama: base-url: http://ollama:11434 #告诉 Spring AI 去 http://ollama:11434 调用模型接口。 embedding: options: num-batch: 512 #批处理参数 model: nomic-embed-text #指定使用的 embedding 模型 rag: embed: nomic-embed-text 注意，需要提前下载模型： ollama pull deepseek-r1:1.5b ollama pull qwen2.5:7b-instruct ollama pull nomic-embed-text ollama list Docker如何开启GPU加速大模型推理 巨坑！ 默认是CPU跑大模型，deepseek1.5b勉强能跑动，但速度很慢，一换qwen2.5:7b模型瞬间就跑不动了，这才发现一直在用CPU跑！！ 如何排查？ 1.查看ollama日志： load_backend: loaded CPU backend from /usr/lib/ollama/libggml-cpu-alderlake.so 2.本地cmd命令行输入，查看显存占用率。 nvidia-smi | 0 NVIDIA GeForce RTX 4060 ... WDDM | 00000000:01:00.0 On | N/A | | N/A 58C P0 24W / 110W | 2261MiB / 8188MiB | 6% Default | 设备状态： RTX 4060显卡驱动（576.02）和CUDA 12.9环境正常 当前GPU利用率仅6%（GPU-Util列） 显存占用2261MB/8188MB（约27.6%） 可见模型推理的时候压根没有用GPU！！！ 解决 参考博客：1-3 Windows Docker Desktop安装与设置docker实现容器GPU加速_windows docker gpu-CSDN博客 1）配置WSL2，打开 PowerShell（以管理员身份运行），执行以下命令： wsl --install -d Ubuntu # 安装 Linux 发行版 wsl --set-default-versi…

拼团设计模式
type: item
date: 2025-08-11T21:40:45+08:00
description: 设计模式 单例模式 懒汉 注意，单例模式的构造函数是私有的！ public class LazySingleton { private static volatile LazySingleton INSTANCE; private LazySingleton() {} public static LazySingleton getInstance() { if (INSTANCE == null) { // 第一次检查 synchronized (LazySingleton.class) { if (INSTANCE == null) { // 第二次检查 INSTANCE = new LazySingleton(); } } } return INSTANCE; } } 第一次检查：防止重复实例化、以及进行synchronized同步块（防止每次加锁的开销）。 第二次检查：防止有多个线程同时通过第一次检查，然后依次进入同步块后，创建N个实例。 volatile：防止指令重排序。 instance = new LazySingleton(); 正确顺序是： memory = allocate(); // 分配内存 ctorInstance(memory); // 调用构造函数，初始化对象 INSTANCE = memory; // 将对象引用赋值给 INSTANCE 由于 JVM 和 CPU 都可能对指令进行优化重排，步骤 ② 和 ③ 的顺序可能被交换！ memory = allocate(); // 分配内存 INSTANCE = memory; // 把引用赋给 INSTANCE（但未初始化完） ctorInstance(memory); // 调用构造函数 线程 A刚执行完赋值（3），但没调用构造函数；此时线程B来了，发现 INSTANCE != null，直接返回这个未初始化完成的对象！！！ 饿汉 public class EagerSingleton { // 类加载时就初始化实例 private static final EagerSingleton INSTANCE = new EagerSingleton(); // 私有构造函数 private EagerSingleton() {} // 全局访问点 public static EagerSingleton getInstance() { return INSTANCE; } } 工厂模式 简单工厂 // 产品接口 interface Product { void use(); } // 具体产品A class ConcreteProductA implements Product { @Override public void use() { System.out.println("使用产品A"); } } // 具体产品B class ConcreteProductB implements Product { @Override public void use() { System.out.println("使用产品B"); } } class SimpleFactory { // 根据参数创建不同的产品 public static Product createProduct(String type) { switch (type) { case "A": return new ConcreteProductA(); case "B": return new ConcreteProductB(); default: throw new IllegalArgumentException("未知产品类型"); } } } public class Client { public static void main(String[] args) { // 通过工厂创建产品 Product productA = SimpleFactory.createProduct("A"); productA.use(); // 输出: 使用产品A Product productB = SimpleFactory.createProduct("B"); productB.use(); // 输出: 使用产品B } } 缺点：添加新产品需要修改工厂类（违反开闭原则） 抽象工厂 抽象工厂模式是一种创建型设计模式，它提供一个接口用于创建相关或依赖对象的家族，而不需要明确指定具体类。 // 抽象产品接口 interface Button { void render(); } interface Checkbox { void render(); } // 具体产品实现 - Window…

拼团交易系统
type: item
date: 2025-06-20T00:10:00+08:00
description: 拼团交易系统 部署 本地环境：Maven3.8.4 SpringBoot: 2.7.12 jdk:1.8 目录结构： 本地启动-1 docker-compose: version: '3.8' services: # 1. 前端 group-buy-market-front: image: nginx:alpine container_name: group-buy-market-front restart: unless-stopped ports: - '18091:80' volumes: - ./nginx/html:/usr/share/nginx/html - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro privileged: true networks: - group-buy-network # 4. Java 后端 group-buying-sys: build: context: ../../.. # 从 docs/tag/v2.0 回到项目根 dockerfile: group-buying-sys-app/Dockerfile image: smile/group-buying-sys:latest container_name: group-buying-sys restart: unless-stopped depends_on: mysql: condition: service_healthy redis: condition: service_healthy ports: - '8091:8091' environment: - TZ=Asia/Shanghai - SPRING_PROFILES_ACTIVE=prod volumes: - ./log:/data/log logging: driver: json-file options: max-size: '10m' max-file: '3' networks: - group-buy-network mysql: image: mysql:8.0 container_name: group-buy-mysql hostname: mysql command: --default-authentication-plugin=mysql_native_password restart: unless-stopped environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 ports: - "13306:3306" volumes: - ./mysql/my.cnf:/etc/mysql/conf.d/mysql.cnf:ro - ./mysql/sql:/docker-entrypoint-initdb.d healthcheck: test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ] interval: 5s timeout: 10s retries: 10 start_period: 15s networks: - group-buy-network # Redis redis: image: redis:6.2 restart: unless-stopped container_name: group-buy-redis hostname: redis privileged: true ports: - 16379:6379 volumes: - ./redis/redis.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf networks: - group-buy-network healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 10s timeout: 5s retries: 3 # rabbitmq # 账密 admin/admin # rabbitmq-plugins enable rabbitmq_management rabbitmq: image: rabbitmq:3.8-management container_name: group-buy-rabbitmq hostname: rabbitmq restart: unless-stopped ports: - "5672:5672" - "15672:15672" environment…

Smile云图库
type: item
date: 2025-06-07T00:10:00+08:00
description: Smile云图库 整体架构 注意：使用腾讯云OSS存储，12月7号资源包过期！！！ 数据库表 picture 表 — 图片表 字段名 类型 说明 id bigint 主键 ID url varchar(512) 图片 URL name varchar(128) 图片名称 introduction varchar(512) 简介 category varchar(64) 分类 tags varchar(512) 标签（JSON 数组） pic_size bigint 图片体积（字节） pic_width int 图片宽度 pic_height int 图片高度 pic_scale double 宽高比例 pic_format varchar(32) 图片格式 user_id bigint 创建用户 ID create_time datetime 创建时间 edit_time datetime 编辑时间 update_time datetime 更新时间（自动更新） is_delete tinyint 是否删除（0 否 1 是） review_status int 审核状态：0 待审核 / 1 通过 / 2 拒绝 review_message varchar(512) 审核信息 reviewer_id bigint 审核人 ID review_time datetime 审核时间 thumbnail_url varchar(512) 缩略图 URL original_url varchar(512) 原图 URL space_id bigint 空间 ID（null 为公共空间） pic_color varchar(16) 图片主色调 space 表 — 空间表 字段名 类型 说明 id bigint 主键 ID space_name varchar(128) 空间名称 space_level int 空间级别：0 普通版 / 1 专业版 / 2 旗舰版 max_size bigint 空间最大可存储总大小 max_count bigint 空间最大图片数量 total_size bigint 当前空间图片总大小 total_count bigint 当前空间图片数量 user_id bigint 创建用户 ID create_time datetime 创建时间 edit_time datetime 编辑时间 update_time datetime 更新时间（自动更新） is_delete tinyint 是否删除 space_type int 空间类型：0 私有 / 1 团队 space_user 表 — 空间与用户关联表 字段名 类型 说明 id bigint 主键 ID space_id bigint 空间 ID user_id bigint 用户 ID space_role varchar(128) 空间角色：viewer / editor / admin create_time datetime 创建时间 update_time datetime 更新时间（自动更新） user 表 — 用户表 字段名 类型 说明 id bigint 主键 ID user_account varchar(256) 用户账号 user_password varchar(512) 用户密码 user_name varchar(256) 用户昵称 user_avatar varchar(1024) 用户头像 user_profile varchar(512) 用户简介 user_role varchar(256) 用户角色（user / admin） user_email varchar(256) 用户邮箱 birthday date 出生日期 user_phone varchar(50) 用户手机号 edit_time datetime 编辑时间 create_time datetime 创建时间 update_time datetime 更新时间（自动更新） is_delete tinyint 是否删除 压测 正式环境：2核4GB运存 首页查询接口： 单测延迟70ms，耗时占比：若干图片json拿缓存+JSON 反序列化+序列化返回给前端+HTTP 传输 14 KB 数据+浏览器 解析 JSON 1秒内1000次请求压测： 为什么压测下这么慢？排查过本地缓存都是命中的。可能是： Caffeine 命中后 → 依旧要 mapper.readValue 做 JSON parse； JSON 体量 ~14 KB，CPU 在高并发下被打爆； Tomcat 线程池也被压满，导致排队。 待完善功能 缓存相关 1. 手动刷新缓存 在某些情况下，数据更…

同步本地Markdown至Typecho站点
type: item
date: 2025-03-22T13:09:00+08:00
description: 同步本地Markdown至Typecho站点 本项目基于https://github.com/Sundae97/typecho-markdown-file-publisher 实现效果： 将markdown发布到typecho 发布前将markdown中的公式块和代码块进行格式化，确保能适配md解析器。 发布前将markdown的图片资源上传到自己搭建的图床Easyimage中（自行替换成阿里云OSS等）, 并替换markdown中的图片链接。 将md所在的文件夹名称作为post的category(mysql发布可以插入category, xmlrpc接口暂时不支持category操作)。 以title和category作为文章的唯一标识，如果数据库中已有该数据，将会更新现有文章，否则新增文章。 环境：Typecho1.2.1 php8.1.0 项目目录 typecho_markdown_upload/main.py是上传md文件到站点的核心脚本 transfer_md/transfer.py是对md文件进行预处理的脚本。 核心思路 一、预先准备 图床服务器 本人自己在服务器上搭建了私人图床——easyimage，该服务能够实现图片上传并返回公网 URL，这对于在博客中正常显示 Markdown 文件中的图片至关重要。 当然，也可以选择使用公共图床服务，如阿里云 OSS，但这里不做详细介绍。 需手动修改transfer_md/upload_img.py，配置url、token等信息。 参考博客：【好玩儿的Docker项目】10分钟搭建一个简单图床——Easyimage-我不是咕咕鸽 github地址：icret/EasyImages2.0: 简单图床 - 一款功能强大无数据库的图床 2.0版 picgo安装： 使用 Typora + PicGo + Easyimage 组合，可以实现将本地图片直接粘贴到 Markdown 文件中，并自动上传至图床。 下载地址：Releases · Molunerfinn/PicGo 操作步骤如下： 打开 PicGo，点击右下角的小窗口。 进入插件设置，搜索并安装 web-uploader 1.1.1 插件（注意：旧版本可能无法搜索到，建议直接安装最新版本）。 配置插件：在设置中填写 API 地址，该地址可在 Easyimage 的“设置-API设置”中获取。 配置完成后，即可实现图片自动上传，提升 Markdown 编辑体验。 Typora 设置 为了确保在博客中图片能正常显示，编辑 Markdown 文档时必须将图片上传至图床，而不是保存在本地。请按以下步骤进行配置： 在 Typora 中，打开 文件 → 偏好设置 → 图像 选项。 在 “插入图片时” 选项中，选择 上传图片。 在 “上传服务设定” 中选择 PicGo，并指定 PicGo 的安装路径。 文件结构统一： md_files ├── category1 │ ├── file1.md │ └── file2.md ├── category2 │ ├── file3.md │ └── file4.md └── output ├── assets_type ├── pics └── updated_files 注意：category对应上传到typecho中的文章所属的分类。 如果你现有的图片分散在系统中，可以使用 transfer_md/transfer.py 脚本来统一处理。该脚本需要传入三个参数： input_path： 指定包含 Markdown 文件的根目录（例如上例中的 md_files）。 output_path： 输出文件夹（例如上例中的 output）。 type_value： 1：扫描 input_path 下所有 Markdown 文件，将其中引用的本地图片复制到 output_path 中，同时更新 Markdown 文件中的图片 URL 为 output_path 内的路径； 2：为每个 Markdown 文件建立单独的文件夹（以文件名命名），图片存放在文件夹下的 assets 子目录中，整体存入assets_type文件夹中，； 3：扫描 Markdown 文件中的本地图片，将其上传到图床（获取公网 URL），并将 Markdown 文件中对应的图片 URL 替换为公网地址。 4：预处理Markdown 文件，将公式块和代码块格式化，以便于Markdown解析器解析（本地typora编辑器对于md格式比较宽容，但博客中使用的md解析器插件不一定能正确渲染！） 二、使用Git进行版本控制 假设你在服务器上已经搭建了 Gitea (Github、Gitee都行)并创建了一个名为 md_files 的仓库，那么你可…

招标文件解析
type: item
date: 2025-03-21T16:12:00+08:00
description: 产品官网：智标领航 - 招投标AI解决方案 产品后台：xxx 项目地址：xxx git clone地址：xxx 选择develop分支，develop-xx 后面的xx越近越新。 正式环境：xxx 测试环境：xxx 大解析：指从招标文件解析入口进去，upload.py 小解析：从投标文件生成入口进去，little_zbparse 和get_deviation，两个接口后端一起调 项目启动与维护： .env存放一些密钥（大模型、textin等），它是gitignore忽略了，因此在服务器上git pull项目的时候，这个文件不会更新（因为密钥比较重要），需要手动维护服务器相应位置的.env。 如何更新服务器上的版本： 步骤 进入项目文件夹 **注意：**需要确认.env是否存在在服务器，默认是隐藏的 输入cat .env 如果不存在，在项目文件夹下sudo vim .env 将密钥粘贴进去！！！ git pull sudo docker-compose up --build -d 更新并重启 ​ 或者 sudo docker-compose build 先构建镜像 ​ sudo docker-compose up -d 等空间时再重启 sudo docker-compose logs flask_app --since 1h 查看最近1h的日志（如果重启后报错也能查看，推荐重启后都运行一下这个） requirements.txt一般无需变动，除非代码中使用了新的库，也要手动在该文件中添加包名及对应的版本 docker基础知识 docker-compose: 本项目为单服务项目，只有flask_app(服务名) build context（context: .）： 这是在构建镜像时提供给 Docker 的文件集，指明哪些文件可以被 Dockerfile 中的 COPY 或 ADD 指令使用。它是构建过程中的“资源包”。 对于多服务，build下就要针对不同的服务，指定所需的“资源包”和对应的Dockerfile dockerfile: COPY . .（在 Dockerfile 中）： 这条指令会将构建上下文中的所有内容复制到镜像中的当前工作目录（这里是 /flask_project）。 docker exec -it zbparse-flask_app-1 sh 这个命令会直接进入到flask_project目录内部ls之后可以看到： Dockerfile README.md docker-compose.yml flask_app md_files requirements.txt 如果这个基础上再cd /会切换到这个容器的根目录，可以看到flask_project文件夹以及其他基础系统环境。如： bin boot dev etc flask_project home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var 数据卷挂载： volumes: -/home/Z/zbparse_output_dev:/flask_project/flask_app/static/output # 额外的数据卷挂载 本地路径：容器内路径 都从根目录找起。 完整的容器名 <项目名>-<服务名>-<序号> 项目名：默认是当前目录的名称（这里是 zbparse），或者你在启动 Docker Compose 时通过 -p 参数指定的项目名称。 服务名：在 docker-compose.yml 文件中定义的服务名称（这里是 flask_app）。 序号：如果同一个服务启动了多个容器，会有数字序号来区分（这里是 1）。 docker-compose exec flask_app sh docker exec -it zbparse-flask_app-1 sh 这两个是等价的，因为docker-compose 会自动找到对应的完整容器名并执行命令。 删除所有悬空镜像（无容器引用的 <none> 镜像） docker image prune 如何本地启动本项目： Pycharm启动 requirements.txt里的环境要配好 conda create -n zbparse python=3.8 conda activate zbparse pip install -r requirements.txt .env环境配好 （一般不需要在电脑环境变量中额外配置了，但是要在Pycharm中安装插件，使得项目在启动时能将env中的环境变量自动配置到系统环境变量中！！！） 点击下拉框，Edit configurations ​ 设置run_serve.py为启动脚本 ​ 注意这里的wo…

苍穹外卖
type: item
date: 2025-03-21T16:12:00+08:00
description: 苍穹外卖 项目简介 整体介绍 本项目（苍穹外卖）是专门为餐饮企业（餐厅、饭店）定制的一款软件产品，包括 系统管理后台 和 小程序端应用 两部分。其中系统管理后台主要提供给餐饮企业内部员工使用，可以对餐厅的分类、菜品、套餐、订单、员工等进行管理维护，对餐厅的各类数据进行统计，同时也可进行来单语音播报功能。小程序端主要提供给消费者使用，可以在线浏览菜品、添加购物车、下单、支付、催单等。 1). 管理端功能 员工登录/退出 , 员工信息管理 , 分类管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 订单管理 ，数据统计，来单提醒。 2). 用户端功能 微信登录 , 收件人地址管理 , 用户历史订单查询 , 菜品规格查询 , 购物车功能 , 下单 , 支付、分类及菜品浏览。 技术选型 1). 用户层 本项目中在构建系统管理后台的前端页面，我们会用到H5、Vue.js、ElementUI、apache echarts(展示图表)等技术。而在构建移动端应用时，我们会使用到微信小程序。 2). 网关层 Nginx是一个服务器，主要用来作为Http服务器，部署静态资源，访问性能高。在Nginx中还有两个比较重要的作用： 反向代理和负载均衡， 在进行项目部署时，要实现Tomcat的负载均衡，就可以通过Nginx来实现。 3). 应用层 SpringBoot： 快速构建Spring项目, 采用 "约定优于配置" 的思想, 简化Spring项目的配置开发。 SpringMVC：SpringMVC是spring框架的一个模块，springmvc和spring无需通过中间整合层进行整合，可以无缝集成。 Spring Task: 由Spring提供的定时任务框架。 httpclient: 主要实现了对http请求的发送。 Spring Cache: 由Spring提供的数据缓存框架 JWT: 用于对应用程序上的用户进行身份验证的标记。 阿里云OSS: 对象存储服务，在项目中主要存储文件，如图片等。 Swagger： 可以自动的帮助开发人员生成接口文档，并对接口进行测试。 POI: 封装了对Excel表格的常用操作。 WebSocket: 一种通信网络协议，使客户端和服务器之间的数据交换更加简单，用于项目的来单、催单功能实现。 4). 数据层 MySQL： 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。 Redis： 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存。 Mybatis： 本项目持久层将会使用Mybatis开发。 pagehelper: 分页插件。 spring data redis: 简化java代码操作Redis的API。 5). 工具 git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。 maven: 项目构建工具。 junit：单元测试工具，开发人员功能实现完毕后，需要通过junit对功能进行单元测试。 postman: 接口测工具，模拟用户发起的各类HTTP请求，获取对应的响应结果。 准备工作 //待完善，最后写一套本地java开发、nginx部署前端；服务器docker部署的方案！！！ 前端环境搭建 Windows下 1.构建和打包前端项目 npm install #安装依赖 npm run build #打包，但我TypeScript 检查报错 npm run pure-build #不检查类型打包 2.将构建文件复制到指定目录 Nginx 默认的静态文件根目录通常是 /usr/share/nginx/html,你可以选择将打包好的静态文件拷贝到该目录 或者使用自定义目录/var/www/my-frontend,并修改 Nginx 配置文件来指向这个目录。 3.配置 Nginx 打开 Nginx 的配置文件，通常位于 /etc/nginx/nginx.conf 以下是一个使用自定义目录 /var/www/my-frontend 作为站点根目录的示例配置： server { listen 80; server_name your-domain.com; # 如果没有域名可以使用 _ 或 localhost root /var/www/my-frontend; index index.html; location / { try_files $uri $uri/ /index.html; } } 4.启动或重启 Nginx 启动：双击nginx.exe 重启：nginx -s reload 5.查看是否正在运行 tasklist /FI "IMAGENAME eq nginx.exe" 6.访问前端项目 在浏览器中输入你配置的域名或服务器 IP 地址 终止运…