Xuan's blog - 项目实战
type: channel
link: https://blog.ybyq.wang/category/project-practice/
description: 完整项目的开发、部署全流程实战记录
items: 第二笔项目劳务费到手
items: 基于Spring Boot + Vue.js的GPT AI聊天应用：从开发到部署的完整实践
items: 智慧零工平台后端开发实战：SpringBoot + MyBatis-Flex 现代化架构
items: 智慧零工平台前端开发实战：从uni-app到跨平台应用
items: 从零开始搭建微信推送服务
items: 基于Node.js + Express + MySQL的健身会员管理系统后端
items: 基于uniapp+vant的健身会员管理系统h5前端

第二笔项目劳务费到手
type: item
date: 2025-10-01T18:23:00+08:00
description: 第一个项目在2025年4月，做了一个健身房会员管理系统，用的是uniapp+Express+Mysql，从开发到部署将近两周时间。甲方要求的是一个微信小程序，但由于一些原因做成了一个h5网页版的。不过最后还是拿到了1000元劳务费。第二个项目以前对于老师们这种询问都是不予理睬的，但这次我参与了。这个项目是一个AI+智慧教学系统： 用的是Vue+Django+Mysql前后端分离。由于课堂管理工具课堂派开始收费，老师要做出一个替代它的，然后在基础功能上加一个学生上课状态的实时识别和一个思政课程智能推荐。说来也挺巧的，第一批功能开发中的两个队友都是熟人，一个是学号同桌，一个是邻班的老乡。第一批功能开发中我负责的是成绩管理模块，有出勤、答题、作业、小测成绩四部分，这个模块是最麻烦的一个，但好在都是增删改查，把数据库表设计清楚就好弄多了。带我们做的是老师的一个研究生学生，这上面是一个大致的要求，实际上还有一些功能，比如签到功能。第二批功能开发在暑假，接了一个作业模块模块。劳务费按照贡献度来分发，总共6.5我占了2.8。在刚接手项目的时候我还以为最后能拿个200块，没想到拿到了1600，一个月生活费了。正好要换手机，那这笔钱加上女朋友资助一些，换一个oppo FindX8手机。左边是新的x8，右边是正在用的x6。

基于Spring Boot + Vue.js的GPT AI聊天应用：从开发到部署的完整实践
type: item
date: 2025-09-23T21:57:00+08:00
description: 前言一个人一个下午做成的，为了应对周四的作业答辩。🚀 项目概述本文将详细介绍一个基于Spring Boot后端和Vue.js前端的GPT AI聊天应用的完整开发流程。该项目集成了OpenAI、阿里云通义千问、DeepSeek、豆包、Kimi等多个主流AI平台，支持文本对话和图像生成功能，并实现了用户认证、会话管理、管理员面板、用户统计等完整的业务功能。体验地址：https://gpt.xuan.cyou/技术栈后端: Spring Boot 3.5.5, Java 17, SQLite, JPA/Hibernate前端: Vue.js 3, Vite, Pinia, JavaScript ES6+AI集成: OpenAI GPT-4, 阿里云通义千问, DeepSeek, 豆包, Kimi部署: 宝塔面板, Nginx, SSL证书📁 项目架构GPT-AI-Project/ ├── gpt-ai-java/ # Spring Boot 后端 │ ├── src/main/java/ │ │ ├── controller/ # REST API控制器 (用户, AI, 管理员等) │ │ ├── service/ # 业务逻辑层 (多AI平台服务, 用户统计等) │ │ ├── entity/ # 数据实体 (用户, 对话历史, 统计数据等) │ │ ├── config/ # 配置类 │ │ └── adopter/ # AI平台适配器 (OpenAI, Ali, DeepSeek, Kimi等) │ ├── src/main/resources/ │ │ └── application.yaml # 应用配置 │ └── pom.xml # Maven依赖配置 └── frontend/ # Vue.js 前端 ├── src/ │ ├── components/ # Vue组件 │ ├── views/ # 页面视图 (聊天, 图像, 管理面板, 用户后台等) │ ├── api/ # API调用封装 │ └── store/ # 状态管理 (Pinia) ├── public/ # 静态资源 └── package.json # NPM依赖配置🔧 核心功能实现1. 后端核心架构1.1 多AI平台集成项目支持OpenAI和阿里云通义千问两个AI平台，通过适配器模式实现：// AI控制器统一入口 @RestController @RequestMapping("/api/ai") public class AiController { @GetMapping("/chat/text/stream") public SseEmitter streamChat( @RequestParam String platform, @RequestParam String model, @RequestParam String message ) { // 根据平台选择对应的AI服务 (示例) if ("openai".equals(platform)) { return openAiController.sendTextStream(model, message); } else if ("ali".equals(platform)) { return aliAiController.sendTextStream(model, message); } // ... 此处添加对 deepseek, doubao, kimi 等平台的路由逻辑 return null; // or throw an exception } }1.2 流式响应实现使用Server-Sent Events (SSE) 实现实时流式对话：@PostMapping("/chat/text/stream") public SseEmitter sendTextStream(String model, String message) { SseEmitter emitter = new SseEmitter(0L); CompletableFuture.runAsync(() -> { try { // 流式读取AI响应并实时推送 openAIService.sendText(model, message, true, delta -> { emitter.send(SseEmitter.event().name("delta").data(delta)); }); emitter.send(SseEmitter.event().name("done").data("[DONE]")); emitter.complete(); } catch (Exception e…

智慧零工平台后端开发实战：SpringBoot + MyBatis-Flex 现代化架构
type: item
date: 2025-06-02T17:46:00+08:00
description: 本文将详细分享我使用Spring Boot 3.3.5 + MyBatis-Flex + SQLite构建零工平台后端系统的完整经验，包含架构设计、技术选型、核心功能实现和生产部署。项目背景随着零工经济的快速发展，我决定开发一个现代化的零工服务平台。后端系统需要支持工作发布、申请匹配、用户管理、支付结算等复杂业务场景，同时要保证高性能、高可用和易扩展。项目概览项目名称: 智慧零工平台后端系统技术栈: Spring Boot 3.3.5 + Java 21 + MyBatis-Flex + SQLite项目地址: GitHub - Gigplatform_backendAPI文档: 24个业务模块，100+接口部署方式: 宝塔面板 + PM2 + Nginx技术选型分析为什么选择Spring Boot 3？Java 21支持: 享受最新的语言特性和性能优化原生镜像: 支持GraalVM原生编译，启动更快响应式编程: 内置WebFlux支持可观测性: 增强的监控和链路追踪安全性: 升级的Spring SecurityMyBatis-Flex vs MyBatis-Plus经过对比，我选择了MyBatis-Flex：// MyBatis-Flex 优势示例 // 1. 类型安全的查询 List<Job> jobs = queryWrapper .select(JOB.ALL_COLUMNS) .from(JOB) .where(JOB.STATUS.eq("ACTIVE")) .and(JOB.SALARY.ge(5000)) .orderBy(JOB.CREATE_TIME.desc()) .limit(10) .list(); // 2. 智能字段映射 @Table("t_job") public class Job { @Id(keyType = KeyType.Auto) private Long id; @Column("job_title") private String title; // 自动处理驼峰命名 private String companyName; // -> company_name }SQLite的选择对于中小型项目，SQLite具有独特优势：零配置: 无需独立数据库服务器高性能: 本地文件访问，减少网络开销事务支持: 完整的ACID特性跨平台: 易于开发和部署成本低: 降低运维复杂度架构设计整体架构┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 前端应用 │ │ API网关 │ │ 负载均衡 │ │ (uni-app) │◄───│ (Nginx) │◄───│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────────────┐ │ Spring Boot │ │ (业务逻辑层) │ └─────────────────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 认证授权 │ │ 业务服务 │ │ 数据访问 │ │ (JWT) │ │ (Service) │ │ (MyBatis) │ └─────────────┘ └─────────────┘ └─────────────┘ │ ▼ ┌─────────────────┐ │ SQLite 数据库 │ └─────────────────┘项目模块结构com.example.backend/ ├── controller/ # 控制器层 │ ├── AuthController # 认证授权 │ ├── JobsController # 工作管理 │ ├── UsersController # 用户管理 │ └── ... # 其他业务控制器 ├── service/ # 业务逻辑层 │ ├── impl/ # 实现类 │ └── interfaces/ # 接口定义 ├── mapper/ # 数据访问层 ├── entity/ # 实体类 ├── config/ # 配置类 ├── common/ # 公共组件 │ ├── Result.java # 统一返回结果 │ ├── JwtUtil.java # JWT工具 │ └── JwtFilter.java # JWT过滤器 └── BackendApplication.java # 启动类核心功能实现1. JWT认证体系@Componen…

智慧零工平台前端开发实战：从uni-app到跨平台应用
type: item
date: 2025-06-02T17:42:00+08:00
description: 本文将详细介绍我如何使用uni-app框架开发一个支持微信小程序和H5的零工平台前端应用，包含技术选型、架构设计、核心功能实现及部署经验。前言在当今移动互联网时代，跨平台开发已成为提高开发效率的重要手段。本次我选择uni-app框架开发了一个智慧零工平台的前端应用，该平台致力于为零工与雇主搭建高效便捷的双向服务桥梁。项目概况项目名称: 智慧零工平台前端系统技术栈: Vue.js 2.6 + uni-app 3.0 + ColorUI支持平台: 微信小程序 + H5项目地址: GitHub - Gigplatform_front在线预览: https://lgpt.xuan.cyou/技术选型分析为什么选择uni-app？在众多跨平台解决方案中，我最终选择了uni-app，主要基于以下考虑：一套代码多端运行: 支持编译到微信小程序、H5、App等10+平台学习成本低: 基于Vue.js语法，前端开发者容易上手生态完善: 拥有丰富的组件库和插件市场性能优异: 接近原生应用的性能表现社区活跃: DCloud官方维护，社区支持良好核心技术栈{ "前端框架": "Vue.js 2.6.11", "跨平台框架": "uni-app 3.0", "UI组件库": "ColorUI 2.1.6", "样式预处理": "SCSS/SASS", "状态管理": "Vuex", "构建工具": "webpack", "开发工具": "HBuilderX" }项目架构设计整体架构项目采用模块化架构设计，清晰分离业务逻辑和技术实现：smart-gig-platform-front/ ├── api/ # API接口层 ├── components/ # 公共组件 ├── pages/ # 页面文件 ├── employerPackage/ # 雇主端分包 ├── static/ # 静态资源 ├── store/ # 状态管理 ├── colorui/ # UI组件库 └── utils/ # 工具函数分包策略为了优化小程序包体积，我采用了分包加载策略：{ "subPackages": [ { "root": "employerPackage", "name": "employer", "pages": [ "pages/center/index", "pages/postJob/index", "pages/resume/index" ] } ] }这样可以将雇主端功能独立打包，减少主包体积，提升首屏加载速度。核心功能实现1. 双重身份系统这是项目的一大特色功能，用户可以在零工和雇主身份间无缝切换： <view class="identity-switch"> <view class="switch-container"> <view class="switch-item" :class="{ active: currentRole === 'worker' }" @click="switchRole('worker')" > <image src="/static/img/worker-icon.png" /> <text>我是零工</text> </view> <view class="switch-item" :class="{ active: currentRole === 'employer' }" @click="switchRole('employer')" > <image src="/static/img/employer-icon.png" /> <text>我是雇主</text> </view> </view> </view> 2. 地理位置服务实现基于位置的工作推荐功能：// 获取用户位置 async getUserLocation() { try { const res = await uni.getLocation({ type: 'wgs84' }) this.userLocation = { latitude: res.latitude, longitude: res.longitude } // 获取附近工作 await this.getNearbyJobs() } catch (error) { console.error('获取位置失败:', error) uni.showToast({ title: '位置获取失败', icon: 'none' }) } }, // 计算距离 calculateDistance(lat1, lon1, lat2, lon2) { const R = 6371 // 地球半径(km) const dLat = (lat2 - lat1) * Math.PI / 180 const…

从零开始搭建微信推送服务
type: item
date: 2025-05-04T17:28:00+08:00
description: 一、准备阶段注册微信公众号登录微信公众平台选择「服务号」类型（需企业资质）或「订阅号」（个人可用但功能受限）完成资质认证（服务号需300元认证费）服务器准备# 推荐配置 CPU: 2核+ ｜ 内存: 2GB+ ｜ 带宽: 3Mbps+ 系统: Ubuntu 22.04 LTS 安装组件: Nginx + MySQL + Redis + Python3.10+购买云服务器（阿里云/腾讯云）配置域名并申请SSL证书（Let's Encrypt免费证书）备案域名（国内服务器必需）微信后台配置开发 → 基本配置 → 启用服务器配置生成AppID和AppSecret设置IP白名单（服务器公网IP）配置消息加密密钥（EncodingAESKey）二、核心开发阶段Token生成与绑定系统# Token生成逻辑（示例） import uuid from datetime import datetime, timedelta def generate_token(openid): token = str(uuid.uuid4()).replace('-','')[:16] expire_time = datetime.now() + timedelta(days=365) # 存储到数据库 sql = ''' INSERT INTO user_tokens (openid, token, expire_time) VALUES (%s, %s, %s) ''' cursor.execute(sql, (openid, token, expire_time)) return token用户关注处理# 微信消息处理框架（使用werobot库） import werobot robot = werobot.WeRoBot(token='YOUR_WECHAT_TOKEN') robot.config["APP_ID"] = "YOUR_APPID" robot.config["APP_SECRET"] = "YOUR_APPSECRET" @robot.subscribe def subscribe_handler(message): openid = message.source token = generate_token(openid) return f"Token已生成：{token}\n请妥善保存"消息推送接口开发# Flask消息处理接口 from flask import Flask, request import requests app = Flask(__name__) @app.route('/<token>.send', methods=['GET', 'POST']) def send_message(token): # 验证Token openid = redis.get(f"token:{token}") if not openid: return "Invalid Token", 403 # 获取消息内容 text = request.args.get('text') or request.form.get('text') desp = request.args.get('desp') or request.form.get('desp', '') # 调用微信API access_token = get_access_token() # 需实现AccessToken获取 url = f"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}" payload = { "touser": openid, "msgtype": "text", "text": {"content": f"{text}\n\n{desp}"} } response = requests.post(url, json=payload) return "Message Sent" if response.json().get('errcode') == 0 else "Error"三、服务部署Nginx配置server { listen 443 ssl; server_name wx.yourdomain.com; ssl_certificate /path/to/fullchain.pem; ssl_certificate_key /path/to/privkey.pem; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_…

基于Node.js + Express + MySQL的健身会员管理系统后端
type: item
date: 2025-04-17T13:40:00+08:00
description: 一个健身会员管理系统的后端开发实践项目背景得知需要做一个人员管理的后端，第一个想到使用springboot（毕竟上学期刚学完），在我看了一些文章后，我得知了一个云操作系统，然后就使用这个做了后端和数据库。项目简介这是一个基于 Node.js + Express + MySQL 开发的健身会员管理系统后端。主要功能包括会员管理、课程管理、管理员系统等。作为一个大三学生的练手项目，它涵盖了后端开发中的许多基础知识点，非常适合想要学习后端开发的同学参考。项目部署说明本项目使用 Sealos 进行部署，这是一个开源的云操作系统，提供了完整的云原生应用部署和管理能力。使用 Sealos 的好处是：简单易用：不需要自己搭建服务器不需要配置复杂的网络环境提供了完整的开发环境数据库部署：使用 Sealos 提供的 MySQL 服务数据库连接地址：****-db-mysql.ns-umwit6**.svc默认端口：3306后端部署：使用 Sealos 的容器服务自动配置网络和域名支持 HTTPS 访问开发体验：提供了完整的开发环境支持代码热更新可以方便地进行调试技术栈后端框架：Node.js + Express数据库：MySQL身份认证：JWT (JSON Web Token)跨域处理：CORS数据库连接：mysql2项目结构详解在开始之前，我们先来了解一下这个项目的基本结构。这种结构是 Express 框架的常见组织方式，也是很多项目的基础架构：backend/ ├── config/ # 配置文件目录 │ ├── database.js # 数据库配置 │ ├── init.sql # 数据库初始化脚本 │ └── init-db.js # 数据库初始化程序 ├── controllers/ # 控制器目录 │ └── admin.js # 管理员相关控制器 ├── models/ # 数据模型目录 │ └── admin.js # 管理员数据模型 ├── routes/ # 路由目录 │ └── admin.js # 管理员相关路由 ├── middlewares/ # 中间件目录 │ └── auth.js # 认证中间件 ├── utils/ # 工具函数目录 │ └── logger.js # 日志工具 ├── app.js # 应用入口文件 └── package.json # 项目依赖配置各目录功能说明config/：存放配置文件database.js：数据库连接配置init.sql：数据库表结构初始化脚本init-db.js：执行数据库初始化的程序controllers/：控制器目录处理具体的业务逻辑接收请求参数调用模型层处理数据返回响应结果models/：数据模型目录定义数据结构和关系封装数据库操作处理数据验证routes/：路由目录定义 API 接口路径将请求映射到对应的控制器处理请求参数验证middlewares/：中间件目录处理请求预处理实现认证授权处理错误utils/：工具函数目录封装通用功能提供辅助函数处理日志记录数据库连接详解1. 本项目数据库连接（Sealos 环境）本项目使用 Sealos 提供的 MySQL 服务，配置如下：// config/database.js const mysql = require('mysql2/promise'); const pool = mysql.createPool({ host: '****-db-mysql.ns-umwit6**.svc', // Sealos 提供的数据库地址 user: 'xxxx', // 数据库用户名 password: 'xxxx', // 数据库密码 database: 'fitness', // 数据库名 port: 3306, // MySQL 默认端口 charset: 'utf8mb4', // 字符集，支持中文 waitForConnections: true, connectionLimit: 10 });2. 传统数据库连接方式如果你没有使用 Sealos，而是使用传统的数据库部署方式，可以参考以下配置：2.1 本地开发环境// config/database.js const mysql = require('mysql2/promise'); const pool = mysql.createPool({ host: 'localhost', // 本地数据库地址 user: 'root', // 数据库用户名 password: '123456', // 数据库密码 database: 'fitness', // 数据库名 port: 3306, // MySQL 默认端口 charset: 'utf8mb4', …

基于uniapp+vant的健身会员管理系统h5前端
type: item
date: 2025-04-17T01:52:00+08:00
description: 基于uni-app的健身会员管理系统前端技术分析项目背景本来是打算做一个会员管理的wx小程序，由于我开始前未弄清楚wx小程序原生语言和uniapp都分别支持什么组件，只知道uniapp可以开发小程序，直接就使用了vue3+vant4组件。做到最后要打包为微信小程序时傻了眼，成堆报错，查了查错误后才知道几乎都是vant4组件的错，根本用不了。查了查才知道vant weapp是专门用于小程序和app的组件，所以我就全部替换了，发现还是不行：页内跳转方法不对，底部导航栏导航方法也不对。。。于是索性不改了，还好备份过，h5就h5吧。业主后来想通过微信小程序来给他的会员发送到期请续费的通知（服务号通知）。但是经过我对这块狠狠地补习后，我发现目前的系统并不能做到这点，需要让会员们通过微信授权登录进来（但是感觉纯H5网站实现微信授权登录挺麻烦的），这样的话可以获取到他们的微信用户信息，就能通过服务号发送给每位授权登录的会员。我突然想到可不可以使用微信原生框架开发一个只做登录，登录的请求和返回都对应做好的这个h5网站，这样的话既能用微信官方登录接口，登录后的画面是这个h5网站，两全其美。但是哪有我想的这莫简单，微信虽然有一个<webview>可以做外部网站的显示容器，但是需要设置授权，所以行不通。后面我会单独发一篇文章，关于微信小程序开发方式以及我碰到的全部麻烦。最后我找到了一个公众号，专门转发这种通知，但有限制。所以最后到期通知只能发给业主自己，且没有会员登录的功能。后面会发一篇后端和数据库的实现以及如何部署。项目概述这是一个基于uni-app开发的健身会员管理系统，主要用于管理会员信息、课程进度以及发送到期提醒等功能。项目采用了Vue 3 + Vite的技术栈，整体架构清晰，代码组织规范。技术栈前端框架：Vue 3构建工具：ViteUI组件库：Vant weappHTTP请求：Axios跨端框架：uni-appAPI设计与实现1. 请求配置与拦截器项目使用了axios进行HTTP请求，并配置了完整的请求拦截和响应拦截机制。让我们来看看具体的实现：// 后端API配置 const backendAPI = { baseUrl: "/api", } // 创建axios实例 const instance = axios.create({ baseURL: backendAPI.baseUrl, timeout: 30000, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, withCredentials: true })这段代码创建了一个axios实例，设置了基本的请求配置：baseURL: 设置API的基础路径timeout: 设置请求超时时间为30秒headers: 设置请求头，指定内容类型为JSONwithCredentials: 允许跨域请求携带cookieAPI路径配置详解在代码中出现的 /api 是一个API的基础路径（base URL），它表示：代理路径：在开发环境中，这个 /api 通常会被配置为代理路径比如当你在本地开发时，请求 /api/member/list 实际上会被代理到 http://localhost:3000/member/list 这样的实际后端地址实际作用：它作为所有API请求的前缀比如 getMemberList 方法实际请求的完整URL是 /api/member/list这样可以统一管理所有API的路径配置方式：在 vite.config.js 中通常会配置代理，类似这样：server: { proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } } }实际部署时：在生产环境中，这个 /api 可能会指向实际的服务器地址比如 https://api.yourdomain.com这样设计的好处是：开发时可以使用代理避免跨域问题部署时只需要修改代理配置，不需要改代码统一管理所有API请求的路径前缀2. 请求拦截器instance.interceptors.request.use( config => { const token = uni.getStorageSync('token') if (token) { config.headers['Authorization'] = `Bearer ${token.trim()}` } return config }, error => { return Promise.reject(error) } )请求拦截器的主要作用是：在每次请求前自动添加token到请求头…