• [训练营] 书循 BookCycle
    书循 BookCycle应用构建2352724朱睿涵
  • [高校训练营] 基于 CodeArts 与 Docker 的全栈论坛应用构建与云上部署实践
    基于 CodeArts 与 Docker 的全栈论坛应用构建与云上部署实践在线体验地址:http://113.47.15.34项目源码仓库:https://gitcode.com/gca_u2402_85029424/forum/一、概述1.1 案例介绍在兴趣社群运营中,论坛是最经典的互动载体,但从零搭建一个具备用户管理、内容审核、版主体系和一键部署的全栈论坛并非易事。码趣社区将 Vue3 前端、Node.js 后端和 MySQL 数据库通过 Docker Compose 编排,实现发帖回复、点赞收藏、敏感词过滤(DFA 算法)、版主管理、黑名单、每日签到、勋章成就等完整功能,并一键部署到华为云弹性云服务器 ECS。本案例将使用华为云码道(CodeArts)代码智能体以 Spec-Driven 模式完成从需求到代码的全流程开发,最终通过 Docker Compose 将三个容器(MySQL、Node.js、Nginx)部署到 ECS。完成案例后,我掌握了:使用华为云码道的 Spec-Driven 模式,将论坛需求依次转化为规格、设计、任务和代码;使用 Vue3 + Element Plus 构建响应式前端,集成 Pinia 状态管理和路由守卫;使用 Node.js + Express + Sequelize 构建 RESTful API,实现 JWT 鉴权、DFA 敏感词过滤和版主权限体系;使用 Docker Compose 编排多容器应用,配置 Nginx 反向代理和 MySQL 字符集;在 Ubuntu ECS 上完成本地构建、SFTP 上传、容器启动和数据初始化的全流程部署。1.2 适用对象希望学习全栈开发与 Docker 部署的个人开发者;需要快速搭建社区论坛的企业开发者;具备 JavaScript/Vue 基础和 Linux 命令行基础的高校学生。1.3 案例时间直接使用仓库源码完成资源准备、部署和功能验证,预计需要 30~45 分钟。如通过码道分阶段搭建码趣社区,建议预留 1.5~2 小时,具体时间取决于代码生成、人工评审和依赖下载速度。1.4 案例流程图 1-1 码趣社区案例流程说明:购买弹性云服务器 ECS,配置安全组开放 80 和 22 端口;本地使用 CodeArts IDE 以 Spec-Driven 模式开发前端(Vue3 + Element Plus)和后端(Node.js + Express + MySQL)代码;本地构建前端 dist 产物,编写 Docker Compose 编排文件和 Dockerfile;通过 SFTP 将项目代码和前端产物上传至 ECS 服务器;在服务器上执行 Docker Compose 一键启动 MySQL、Node.js、Nginx 三个容器;执行数据初始化脚本,访问公网 IP 验证论坛功能。1.5 方案架构图 1-2 码趣社区系统运行架构核心调用链如下:浏览器发起请求,Nginx 监听 80 端口,静态资源直接返回,/api/ 路径反向代理到 Node.js 容器 3000 端口;Node.js 通过 Sequelize ORM 连接 MySQL 容器,执行数据读写;JWT 鉴权中间件校验用户身份,敏感词中间件在发帖和回复前执行 DFA 过滤;黑名单中间件在发帖和回复前检查用户是否被当前版块拉黑;前端通过 axios 统一封装 API 请求,自动携带 Bearer Token,401 时跳转登录页。1.6 资源总览本案例使用按需资源。以 1 小时体验估算,费用通常由 ECS 实例费用和 EIP 流量费用组成。资源名称推荐规格用途华为开发者空间已完成实名认证的账号进入开发平台和实战案例弹性云服务器 ECS2 vCPU、4 GiB、Ubuntu 24.04、40 GiB 系统盘运行 Docker 容器弹性公网 IP EIP按流量计费、5 Mbit/sSSH 登录和浏览器访问华为云码道(CodeArts)代码智能体购买使用专业版Spec-Driven 全流程开发费用提示:体验完成后请及时释放 ECS 和 EIP。仅关闭操作系统不会停止 ECS 计费。二、环境和资源准备2.1 前置条件开始前请确认:已注册华为云账号并完成实名认证;账号余额或代金券足以支付本案例资源;本地已安装 Node.js >= 18.x、npm >= 9.x,可使用 SSH 和 SFTP;Windows 10/11 可在 PowerShell 中执行 ssh -V 和 node -v 检查。2.2 创建 ECS登录华为云控制台,进入 服务列表 > 计算 > 弹性云服务器 ECS,单击购买弹性云服务器。图 2-1 选择 ECS 规格、镜像、磁盘和公网访问配置推荐配置如下:配置项推荐值说明计费模式按需计费便于体验结束后及时释放CPU 架构x86与常用 Node.js 依赖兼容规格2 vCPU、4 GiB低于 4 GiB 可能无法稳定运行三个 Docker 容器镜像Ubuntu 24.04 Server 64bit部署脚本使用 apt-get系统盘40 GiB用于系统、Docker 镜像和数据库数据EIP现在购买用于 SSH 和 Web 访问带宽计费按流量计费,5 Mbit/s适合短时体验登录方式密钥对或强密码密钥对安全性更高购买完成后,在 ECS 详情页记录:ECS 公网 IP:后文以 <ECS_IP> 表示;登录用户名和密码:本案例使用 root 用户。图 2-2 ECS 创建完成并处于运行中2.3 配置安全组进入 ECS 详情 > 安全组 > 配置规则 > 入方向规则,添加以下规则:协议端口来源用途TCP22本机公网 IP/32SSH 和 SFTPTCP800.0.0.0/0浏览器访问论坛2.4 安装 Docker 和 Docker Compose使用 SSH 工具连接到 ECS 服务器,执行以下命令:# 更新系统 apt update && apt upgrade -y # 安装 Docker 和 Docker Compose apt install -y docker.io docker-compose # 配置 Docker 镜像加速(国内环境必须,否则无法拉取镜像) mkdir -p /etc/docker cat > /etc/docker/daemon.json << 'EOF' { "registry-mirrors": ["https://docker.1ms.run"] } EOF # 启动 Docker 并设置开机自启 systemctl daemon-reload systemctl enable docker systemctl start docker # 创建 2G Swap(防止内存不足导致容器被 OOM Kill) fallocate -l 2G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab验证安装:docker --version docker-compose --version free -h 预期结果:Docker 和 Docker Compose 版本正常输出,Swap 行显示约 2G 可用空间。2.5 本地开发环境确保本地已安装:Node.js >= 18.x(执行 node -v 检查)npm >= 9.x(执行 npm -v 检查)Git(执行 git --version 检查)三、通过码道分阶段搭建码趣社区本模块演示如何使用华为云码道(CodeArts)代码智能体,以 Spec-Driven 模式将论坛需求依次转化为需求规格、技术设计、任务清单和可运行代码。说明:码道界面、模型列表和按钮位置可能随版本更新而变化,请以实际产品页面为准。生成代码必须经过人工审查、构建测试和安全检查。3.1 开通并进入码道登录华为开发者官网,进入华为云码道(CodeArts)代码智能体体验页面;按页面提示完成体验版开通;下载并安装支持码道的开发工具,登录同一华为云账号;打开码道 Agent Space 或 IDE 右侧智能体面板,确认可以选择规范开发(Spec-Driven)。图 3-1 开通华为云码道代码智能体体验版图 3-2 进入码道 Agent Space3.2 创建项目并选择 Spec-Driven 模式新建空工作区,在智能体面板选择规范开发(Spec-Driven)。首次输入应描述业务目标、技术栈、核心功能和交付要求:请使用 Vue3 + Element Plus(前端)、Node.js + Express + Sequelize + MySQL(后端) 构建一个兴趣社群论坛"码趣社区"。功能包括:用户注册登录、版块管理、 发帖回复、点赞收藏、敏感词过滤(DFA算法)、版主管理、黑名单、 每日签到(含连续签到奖励)、勋章成就系统。部署方式为 Docker Compose 一键部署(MySQL + Node.js + Nginx)。请采用 Spec-Driven 流程, 先生成需求规格,再生成技术设计和任务清单,经确认后分阶段实现。图 3-3 选择 Spec-Driven 模式并提交项目目标Spec-Driven 流程包含四个阶段:需求规格设计:明确目标、边界、用户故事和验收标准;实现方案创建:确定架构、数据模型、接口和部署方案;编码任务规划:将设计拆分为可追踪、可验证的任务;任务执行:按依赖顺序生成代码,并持续构建验证。3.3 第一阶段:生成并评审 spec.md码道首先将自然语言需求整理为 spec.md。评审时重点检查:是否覆盖用户管理、版块管理、发帖回复、敏感词过滤、版主体系和部署方式;是否明确"管理员不能被拉黑""敏感词过滤不修改原文只标记命中"等业务边界;每个核心能力是否具有可验证的验收标准;技术栈和部署目标是否与项目实际一致。图 3-4 第一阶段完成需求规格设计若规格有遗漏,先在对话中提出修改要求,确认 spec.md 后再进入设计阶段。3.4 第二阶段:生成并评审 design.mddesign.md 应把需求落实为可实现的技术方案。本项目重点确认:Vue3 + Element Plus 前端架构,Pinia 状态管理,vue-router 路由守卫;Express + Sequelize 后端架构,JWT 鉴权中间件,DFA 敏感词过滤中间件;MySQL 数据模型覆盖用户、版块、帖子、回复、版主、敏感词、黑名单、签到、点赞、收藏、勋章等 13 个表;Docker Compose 编排 MySQL、Node.js、Nginx 三个容器,Nginx 反向代理 /api/ 到后端;环境变量注入数据库密码和 JWT 密钥,不进入源码和镜像。图 3-5 第二阶段完成实现方案设计3.5 第三阶段:生成并评审 tasks.md码道根据规格和设计生成 tasks.md,把工作拆分为项目初始化、数据模型、中间件、核心 API、前端页面、Docker 部署等任务。评审任务清单时应确保:每项任务都能回溯到 spec.md 和 design.md;任务依赖顺序正确,可并行项和串行项明确;每项任务包含完成条件,而不只是文件名;构建、数据库初始化、接口验证被列入任务。图 3-6 第三阶段完成编码任务规划3.6 第四阶段:按任务清单执行确认任务清单后进入执行阶段。建议采用"小批次执行—查看变更—运行验证—继续下一批"的节奏:先完成项目初始化、环境变量声明和 Sequelize 模型定义;再实现 JWT 鉴权、DFA 敏感词过滤和黑名单中间件;然后实现用户、版块、帖子、回复等核心 API 路由;接着实现前端页面和 Element Plus 组件;最后补充 Dockerfile、docker-compose.yml 和 Nginx 配置;每批变更后查看差异,拒绝与规格无关的修改。图 3-7 码道开始执行初始化与配置任务图 3-8 码道继续实现后端接口和前端页面图 3-9 任务执行阶段完成3.7 本地运行与阶段验收智能体完成首轮实现后,在项目目录执行:# 后端 cd server npm install node src/seed.js # 前端 cd ../client npm install npm run dev图 3-10 首个本地可运行版本的首页3.8 编码问题与修复Windows 环境下,码道生成的含中文 Vue/JS 文件可能被保存为 GBK 编码而非 UTF-8,导致 Vite 构建后中文乱码。解决方案:后端 JS 文件中的中文使用 \uXXXX Unicode 转义;前端 Vue 文件使用 Node.js fs.writeFileSync(path, content, 'utf8') 写入;ElementF12 打开浏览器控制台,检查 Network 面板中 API 返回的中文是否正常。完成本模块后,项目应通过 npm run build,核心页面可访问,且所有环境变量和部署步骤与后续章节一致。四、构建并部署码趣社区应用4.1 技术栈与项目结构主要技术栈如下:层次技术版本/作用前端框架Vue33.5,Composition APIUI 组件库Element Plus表单、表格、对话框、分页等状态管理Pinia用户登录态、角色判断路由Vue Router 4路由守卫、动态路由HTTP 客户端;axiosAPI 封装、Token 注入、401 拦截后端框架ExpressRESTful APIORMSequelize模型定义、迁移和查询数据库MySQL 8.0持久化所有业务数据鉴权JWTBearer Token 认证敏感词DFA 算法确定有限状态自动机,高性能匹配容器编排Docker ComposeMySQL + Node.js + Nginx 三容器反向代理Nginx静态资源、/api/ 反向代理、SPA 路由项目关键结构:forum/ ├── docker-compose.yml ├── client/ │ ├── Dockerfile │ ├── nginx.conf │ ├── package.json │ ├── vite.config.js │ ├── index.html │ └── src/ │ ├── main.js │ ├── App.vue │ ├── router/index.js │ ├── stores/user.js │ ├── api/ # auth, posts, sections, admin, likes, favorites, badges, checkin │ ├── components/ # Navbar, PostCard, ThumbUp, ThumbUpFilled │ └── views/ # Home, Login, Register, PostDetail, Profile, Checkin, Search │ └── admin/ # Dashboard, Sections, Moderators, SensitiveWords, Blacklist ├── server/ │ ├── Dockerfile │ ├── package.json │ ├── .env │ └── src/ │ ├── app.js │ ├── config/ │ ├── models/ # User, Section, Post, Reply, Moderator, SensitiveWord, │ │ # Blacklist, Checkin, Like, Favorite, Badge, UserBadge │ ├── routes/ # auth, posts, sections, moderators, blacklist, sensitiveWords, │ │ # checkin, likes, favorites, badges │ ├── middleware/ # auth, checkBlacklist, sensitiveWordFilter │ ├── utils/ # dfa, response, badges │ ├── seed.js # 管理员、版块、敏感词、勋章种子数据 │ └── populate.js # 测试用户、帖子、回复批量填充4.2 关键实现解析, checkBlacklist, sensitiveWordFilter4.2.1 DFA 敏感词过滤后端使用 DFA(确定有限状态自动机)算法实现高性能敏感词过滤,支持精确匹配和模糊匹配两种模式:class SensitiveWordFilter { constructor() { this.wordTree = {}; } addWord(word, matchType = 'exact') { let node = this.wordTree; for (const char of word) { if (!node[char]) node[char] = {}; node = node[char]; } node.isEnd = true; node.matchType = matchType; } filter(text) { const matched = []; for (let i = 0; i < text.length; i++) { let node = this.wordTree; let j = i; while (j < text.length && node[text[j]]) { node = node[text[j]]; if (node.isEnd) matched.push({ start: i, end: j, word: text.substring(i, j + 1) }); j++; } } return matched; } } 4.2.2 JWT 鉴权与权限分级鉴权中间件支持三级权限控制:function authMiddleware(requiredRole = null) { return async (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; const decoded = jwt.verify(token, config.jwt.secret); const user = await User.findByPk(decoded.id); // admin: 仅管理员 if (requiredRole === 'admin' && user.role !== 'admin') return 403; // moderator: 管理员或版主 7 if (requiredRole === 'moderator' && user.role !== 'admin' && user.role !== 'moderator') return 403; req.user = user; next(); }; } 4.2.3 Docker Compose 编排services: mysql: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: ${DB_PASS:-Forum2026!Prod} MYSQL_DATABASE: forum MYSQL_CHARSET: utf8mb4 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - mysql_data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] server: build: ./server restart: always environment: DB_HOST: mysql DB_PASS: ${DB_PASS:-Forum2026!Prod} JWT_SECRET: ${JWT_SECRET:-change_this_in_production} depends_on: mysql: condition: service_healthy client: build: ./client restart: always ports: - "80:80" volumes: 5 - ./client/dist:/usr/share/nginx/html depends_on: - server volumes: mysql_data: 4.2.4 Nginx 反向代理配置server { listen 80; charset utf-8; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://server:3000/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } } 4.3 本地构建前端1核1G 服务器无法在 Docker 内构建 Vite 前端(会 OOM Kill),需在本地构建后上传:cd forum/client npm run build构建完成后 dist/ 目录包含所有静态资源。注意:Windows 环境下 Vite 构建可能因内存不足卡住,可使用 node --max-old-space-size=4096 node_modules/vite/bin/vite.js build 增加内存限制。4.4 上传项目到服务器使用 SFTP 工具将整个 forum/ 目录上传至 ECS 服务器的 /root/forum/。也可使用 Node.js ssh2 库编写 SFTP 上传脚本,将 client/dist/ 和 server/ 同步到服务器。4.5 启动服务SSH 登录服务器后执行:cd /root/forum # 启动所有容器 docker-compose up -d --build # 等待 MySQL 就绪后初始化数据 sleep 15 docker-compose exec -T server node src/seed.js docker-compose exec -T server node src/populate.jsseed.js:创建管理员账号、5 个版块、7 个敏感词和 6 个勋章定义;populate.js:填充 10 个测试用户、17 篇帖子、59 条回复、5 个版主、2 个黑名单和 5 个置顶帖。图 4-1 三个容器启动成功4.6 部署结果验证依次执行:docker-compose ps curl -I http://127.0.0.1 curl http://127.0.0.1/api/sections预期结果:三个容器状态均为 Up;curl 返回 HTTP 200;/api/sections 返回 JSON 格式的版块列表。首页应显示"码趣社区——计算机人的论坛"导航栏和帖子列表。图 4-2 通过 ECS 公网地址访问码趣社区默认账号:角色用户名密码管理员adminadmin123普通用户zhangsan123456五、功能体验5.1 用户注册与登录点击导航栏注册,填写用户名、邮箱和密码;注册成功后自动登录,导航栏显示用户昵称和下拉菜单;退出登录后自动跳转到登录页。图 5-1 用户注册页面5.2 发帖与回复点击导航栏发帖,选择版块、填写标题和内容,点击提交;在帖子详情页,点赞(?)和收藏(?)按钮可正常切换;在回复框输入内容,点击回复;版主或管理员可置顶和删除帖子。图 5-2 帖子详情页的点赞与收藏功能5.3 敏感词过滤管理员进入管理后台 > 敏感词管理,添加敏感词(支持精确匹配和模糊匹配);用户发帖或回复时,若内容命中敏感词,系统返回提示并阻止发布;DFA 算法基于预构建的字典树实现,匹配效率为 O(n),n 为文本长度。5.4 版主管理与黑名单管理员进入管理后台 > 版主管理,为版块任命版主;版主可在自己管理的版块中置顶和删除帖子;进入黑名单管理,点击添加拉黑,搜索用户名并选择版块,填写原因后确认;被拉黑用户在该版块发帖或回复时被拒绝。图 5-3 黑名单管理页面的用户搜索功能5.5 每日签到与连续奖励点击导航栏签到,进入签到页面;点击签到按钮,显示连续签到天数和获得的声望奖励;日历视图标记已签到日期,连续签到天数越多奖励越高。图 5-4 每日签到与连续签到奖励5.6 勋章与成就系统用户在发帖、回复、签到等行为中自动触发勋章检查;获得的勋章在个人中心的"我的勋章"区域展示;内置勋章包括:初来乍到(首次发帖)、热心回复(首次回复)、持之以恒(连续3天签到)、声望新星(声望达到10)等。5.7 个人中心点击导航栏用户下拉菜单中的个人中心;查看声望等级(Lv.1 起,随声望增长升级)、我的帖子、我的收藏和我的勋章;编辑昵称和个人简介。图 5-5 个人中心页面5.8 管理后台管理员登录后,导航栏显示管理后台入口:页面功能仪表盘统计用户数、版块数、帖子数、回复数版块管理创建、编辑、排序版块版主管理任命和移除版主敏感词管理添加、编辑、删除敏感词,支持批量导入导出黑名单管理拉黑和解除拉黑用户图 5-6 管理后台仪表盘六、运行维护与故障排查6.1 常用运维命令# 查看容器状态 cd /root/forum && docker-compose ps # 查看容器日志 docker-compose logs server --tail 100 docker-compose logs mysql --tail 50 # 重启单个容器 docker-compose restart server # 查看 Nginx 状态 docker exec forum_client_1 nginx -t # 查看磁盘和内存 df -h free -h # 查看数据库表 docker exec forum_mysql_1 mysql -uroot -p'Forum2026!Prod' forum -e "SHOW TABLES;" 6.2 常见问题现象可能原因处理方法浏览器无法访问安全组未开放 80、Nginx 未启动、EIP 错误检查安全组、docker-compose ps 和 ECS 公网 IP502 Bad GatewayNode.js 容器未启动或 3000 端口未监听执行 docker-compose logs server,重启容器API 返回中文乱码前端 dist 文件编码问题本地重新 npm run build 后上传 distMySQL 容器频繁重启内存不足导致 OOM Kill确认 Swap 已启用,考虑升级 ECS 规格SSH 无法连接SSH 进程被 OOM Kill通过华为云控制台 VNC 登录,检查 free -h发帖被拒绝命中敏感词或被黑名单拉黑检查敏感词列表和黑名单记录点赞/收藏图标不显示图标组件渲染方式错误确认使用 v-if/v-else 而非 component:is6.3 更新部署修改代码后,在本地重新构建前端并上传:# 本地构建 cd forum/client npm run build # 上传 dist 到服务器(通过 SFTP) # 服务器上复制到容器 docker cp /root/forum/client/dist/. forum_client_1:/usr/share/nginx/html/ # 后端代码更新 docker cp /root/forum/server/src/routes/xxx.js forum_server_1:/app/src/routes/xxx.js docker-compose restart server6.4 生产化建议本案例以快速体验为目标。用于生产环境前,至少应补充:使用 IAM 和 HTTPS 证书保护所有页面和 API;将数据库密码和 JWT 密钥存储到云凭据管理服务;使用云数据库 RDS 替代容器内 MySQL,并建立自动备份;增加请求限流、输入大小限制和审计日志;配置 AOM 或 LTS 监控 CPU、内存和错误率。七、释放资源7.1 停止并删除 Docker 容器cd /root/forum docker-compose down -v 7.2 删除 ECS登录华为云控制台,进入弹性云服务器 ECS > 实例;选择本案例创建的 ECS;单击更多 > 删除;根据页面提示勾选释放绑定的 EIP、删除系统盘和数据盘;确认资源名称和影响范围后完成删除。删除后再次检查 ECS、云硬盘和 EIP 列表,确认没有遗留按需资源。八、扩展资料Vue3 官方文档Element Plus 组件库Express 框架Sequelize ORMDocker Compose 文档弹性云服务器 ECS 文档弹性公网 IP 文档九、案例验收清单完成以下检查即表示案例体验成功:[ ] ECS、EIP 和安全组配置完成;[ ] Docker 和 Docker Compose 已安装,镜像加速已配置;[ ] 三个容器(MySQL、Node.js、Nginx)均为 Up 状态;[ ] seed.js 和 populate.js 执行成功,数据库有初始数据;[ ] 浏览器可通过 ECS 公网 IP 打开码趣社区首页;[ ] 用户注册、登录、发帖、回复功能正常;[ ] 点赞和收藏图标正常显示并可切换;[ ] 敏感词过滤能阻止命中词的发布;[ ] 管理员可拉黑用户,被拉黑用户无法在对应版块发帖;[ ] 每日签到和勋章系统正常工作;[ ] 个人中心可查看我的帖子、我的收藏和我的勋章;[ ] 体验结束后已释放不再使用的计费资源。
  • [热门活动] 基于华为云码道(CodeArts)的地震信息查询可视化平台
    零、前置说明源代码链接(本人基于码道智能体原创):https://github.com/Jiachen1029/QuakeVision-using-CodeArts视频展示:https://pan.baidu.com/s/1FAvA-cN6nJ0o2-LkYpprjw 提取码: tjcs一、概述1.1 案例背景地震灾害具有突发性强、影响范围广、次生灾害链条长等特点。一次显著地震往往不仅造成建筑物倒塌与人员伤亡,还可能诱发山体滑坡、地面破坏、火灾以及海啸等连锁效应。从公共卫生与社会影响角度看,世界卫生组织统计显示,在 1998—2017 年间,地震导致近 75 万人死亡,并造成大规模受灾与流离失所。从经济损失角度看,联合国减灾署在其全球评估报告相关内容中指出,地震造成的经济损失占全球灾害直接经济损失的显著比例超过1/4。地震信息的快速获取、可靠存档与可分析呈现,对科研分析、教学训练以及应急信息支撑都具有现实价值。因此,各类机构都会发布地震速报信息,但这些数据往往以列表、通报、表格文件等形式分散存在,存在以下常见问题:其一,数据呈现方式偏静态文本。用户难以进行复杂检索与对比分析,如跨时间段震级分布、某地区地震活动趋势等;其二,缺少空间化表达。纯表格信息难以直观反映地震的地理分布特征与空间聚集现象;其三,数据更新与维护流程不统一。导入数据容易出现重复、缺失、格式不一致等质量问题,影响后续分析准确性;因此,构建具备数据可管理、查询可扩展、统计可分析、结果可视化、权限可控制的地震信息查询可视化平台,不仅符合课程设计中数据库应用系统开发的训练目标,也贴近真实应用场景。1.2 案例介绍QuakeVision·地震信息查询可视化平台以地震事件数据为核心对象,支持从外部数据源导入,并在数据库中进行结构化存储与索引优化;支持面向不同使用角色(未登录用户、普通用户、数据维护人员、管理员)提供分层功能,包括地震事件的多条件检索、数据详情查看、收藏管理、统计报表生成以及基于地图的空间展示与城市地震风险评估查询。本案例演示了如何利用 Python Flask + SQLAlchemy + Leaflet.js + Chart.js 技术栈,快速搭建一个面向公共安全领域的地震数据查询与可视化分析平台,完整经历需求分析、数据库设计、编码实现、测试验证的软件工程全流程,开发周期共3天。1.3 适用对象高校学生个人开发者企业开发者1.4 案例时间与流程本案例实际开发周期为3天。第1天:需求分析与数据库设计——分析四类用户需求,完成概念设计(E-R图)、逻辑结构设计(关系模式转换与范式分析)、完整性约束与索引设计;第2天:后端开发与核心业务实现——搭建 Flask 应用框架,实现数据模型、多维查询、城市风险评估算法、统计分析、权限控制、数据导入导出等核心路由;第3天:前端可视化与集成测试——实现地图可视化(Leaflet)、统计图表(Chart.js)、Glassmorphism UI 主题,完成四类角色的功能验证与界面调试。1.5 资源总览本案例使用本地开发环境,所有资源均为免费开源软件。资源名称规格单价(元)Python3.11+免费Flask3.x Web 框架免费SQLite开发数据库免费Leaflet.js开源地图库免费Chart.js开源图表库免费OpenStreetMap Nominatim免费地理编码服务免费Pandas数据处理库免费Vue 3 + Vite前端扩展脚手架免费二、环境和资源准备2.1 安装 Python 与虚拟环境1)确保系统已安装 Python 3.11 或更高版本,可通过以下命令验证:python --version 2)在项目根目录下创建并激活 Python 虚拟环境:python -m venv .venv # Windows .venv\Scripts\activate # Linux/Mac source .venv/bin/activate2.2 安装项目依赖本项目依赖以下 Python 库,可通过 pip 一次性安装:pip install flask==3.1.0 pip install flask-sqlalchemy==3.1.1 pip install flask-login==0.6.3 pip install pandas==2.2.3 pip install openpyxl==3.1.5 pip install xlrd==2.0.1 pip install werkzeug==3.1.3注意:必须指定版本号安装,避免后期版本依赖冲突。2.3 准备地震数据文件项目根目录下已包含中国地震台网速报目录 Excel 文件:速报目录20090101-20251211.xls:2009年至2025年12月11日的历史地震数据速报目录20251211-20251223.xls:2025年12月11日至12月23日的近期数据速报目录20251224-20260726.xls:2025年12月24日至2026年7月26日的近期数据Excel 文件列格式为:序号、发震日期(北京时间)、经度(°)、纬度(°)、震源深度(Km)、震级(M)、震中位置、事件类型。三、构建地震信息查询可视化平台3.1 创建开发环境确认项目目录结构完整:EarthquakeDB/ ├── app/ # Flask 应用核心目录 │ ├── __init__.py # 应用工厂:初始化 Flask + SQLAlchemy + LoginManager │ ├── models.py # 数据模型:User, Earthquake, City, UploadLog, favorites │ ├── routes.py # 路由与业务逻辑(758行) │ ├── static/ │ │ └── css/ │ │ └── style.css # 全局样式(Glassmorphism 毛玻璃主题) │ └── templates/ # Jinja2 HTML 模板 │ ├── base.html # 基础布局模板(导航栏 + 公共资源) │ ├── index.html # 主页(地震列表 + 筛选) │ ├── login.html # 登录页 │ ├── register.html # 注册页 │ ├── profile.html # 个人中心 │ ├── admin.html # 管理员面板 │ ├── map.html # 地震分布地图可视化 │ ├── city_risk.html # 城市地震风险评估 │ ├── statistics.html # 数据统计分析 │ ├── edit.html # 编辑地震数据 │ ├── upload_manage.html # 上传数据与日志管理 │ └── my_favorites.html # 我的收藏 ├── frontend/ # Vue 3 前端项目(脚手架,扩展用) ├── config.py # Flask 配置(SECRET_KEY, 数据库URI) ├── run.py # 应用启动入口 ├── init_db.py # 数据库初始化脚本 ├── import_data.py # Excel 数据批量导入脚本 ├── inspect_excel.py # Excel 文件检查工具 ├── schema.sql # PostgreSQL 生产数据库 DDL ├── app.db # SQLite 开发数据库文件 ├── 速报目录*.xls # 地震速报数据文件 └── 开发者空间案例模板v2.0.md # 案例模板 3.2 部署项目代码3.2.1 初始化数据库执行数据库初始化脚本,创建所有数据表并生成默认用户账号:python init_db.py该脚本将:创建 users、earthquakes、cities、favorites、upload_logs 五张数据表创建三个默认用户:用户名密码角色User1111111ROLE_USER(普通用户)Staff1111111ROLE_STAFF(工作人员)Admin1111111ROLE_ADMIN(管理员)3.2.2 导入地震数据将 Excel 速报目录数据批量导入数据库:python import_data.py注意:import_data.py 默认读取 速报目录.xls,如需导入其他文件,请修改脚本末尾的文件路径参数。导入过程会自动跳过已存在的记录(基于 original_id 去重)。也可通过 Web 界面(管理员/工作人员登录后 → “上传数据与日志”)在线上传 Excel 文件,系统会自动解析并导入。3.3 关键代码讲解3.3.1 应用初始化(app/__init__.py)Flask 应用工厂模式,初始化核心扩展:from flask import Flask from config import Config from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager app = Flask(__name__) app.config.from_object(Config) db = SQLAlchemy(app) login = LoginManager(app) login.login_view = 'login' login.login_message = '请先登录以访问此页面。' from app import routes, modelsSQLAlchemy:ORM 数据库映射,支持 SQLite(开发)和 PostgreSQL(生产)无缝切换LoginManager:用户认证管理,未登录自动跳转至登录页3.3.2 数据模型(app/models.py)系统定义了 4 个核心数据模型和 1 个关联表,围绕"地震事件"的查询、可视化、导入维护与用户个性化操作展开。在概念层面,数据对象可抽象为五类核心实体:用户(User)、地震事件(Earthquake)、城市(City)、收藏关系(Favorites)、上传日志(UploadLog)。Earthquake 是业务主实体;User 负责身份与权限;Favorites 用于刻画用户对地震事件的多对多收藏关系;UploadLog 记录批量导入与审计信息;City 为城市检索/风险评估提供地理编码缓存与空间分析支撑。用户模型(User):支持三种角色权限体系,密码仅以哈希形式保存class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), unique=True, nullable=False) password_hash = db.Column(db.String(255), nullable=False) role = db.Column(db.String(20), default='ROLE_USER', nullable=False) # 角色取值:ROLE_USER / ROLE_STAFF / ROLE_ADMIN 属性名数据类型约束条件说明idIntegerPrimary Key,自增用户唯一标识usernameVARCHAR(50)UNIQUE,NOT NULL用户名唯一password_hashVARCHAR(255)NOT NULL密码哈希值不存明文roleVARCHAR(20)NOT NULL,DEFAULT=‘ROLE_USER’角色(ROLE_USER/ROLE_STAFF/ROLE_ADMIN)地震模型(Earthquake):系统核心业务数据,存储每条地震记录的完整信息,对高频筛选字段设置索引以支撑上万条数据的分页响应与查询class Earthquake(db.Model): __tablename__ = 'earthquakes' id = db.Column(db.Integer, primary_key=True) original_id = db.Column(db.Integer) # 原始序号 time = db.Column(db.DateTime, nullable=False, index=True) # 发震时间 longitude = db.Column(db.Float, nullable=False, index=True) # 经度 latitude = db.Column(db.Float, nullable=False, index=True) # 纬度 depth = db.Column(db.Float, nullable=False) # 震源深度(km) magnitude = db.Column(db.Float, nullable=False, index=True) # 震级(M) location = db.Column(db.String(255)) # 震中位置 event_type = db.Column(db.String(50)) # 事件类型 属性名数据类型约束条件说明idIntegerPrimary Key地震记录唯一标识original_idInteger可为空来源数据原始序号(用于去重/对照)timeDateTimeNOT NULL,INDEX发震时间(范围查询高频)longitudeFloatNOT NULL,INDEX震中经度(空间范围查询)latitudeFloatNOT NULL,INDEX震中纬度(空间范围查询)depthFloatNOT NULL震源深度(km)magnitudeFloatNOT NULL,INDEX震级(区间筛选高频)locationVARCHAR(255)可为空参考位置文本(关键词检索)event_typeVARCHAR(50)可为空事件类型(如地震/余震等)收藏关联表(Favorites):多对多关系,复合主键保证同一用户对同一事件最多收藏一次favorites = db.Table('favorites', db.Column('user_id', db.Integer, db.ForeignKey('users.id'), primary_key=True), db.Column('earthquake_id', db.Integer, db.ForeignKey('earthquakes.id'), primary_key=True) ) 属性名数据类型约束条件说明user_idIntegerPrimary Key,Foreign Key指向 users.idearthquake_idIntegerPrimary Key,Foreign Key指向 earthquakes.id城市缓存模型(City):缓存 Nominatim 地理编码结果,name 字段设置唯一约束以避免重复缓存,提高命中率与一致性属性名数据类型约束条件说明idIntegerPrimary Key城市记录唯一标识nameVARCHAR(100)UNIQUE,NOT NULL,INDEX城市名/检索关键字(缓存键)display_nameVARCHAR(255)可为空城市显示名称(更完整的地名)latitudeFloatNOT NULL城市中心点纬度longitudeFloatNOT NULL城市中心点经度上传日志模型(UploadLog):记录每次数据上传的操作者、文件名、导入条数和状态,满足"可追溯、可统计、可排错"的维护需求属性名数据类型约束条件说明idIntegerPrimary Key,自增日志记录唯一标识user_idIntegerNOT NULL,Foreign Key,INDEX导入操作发起用户(STAFF/ADMIN)filenameVARCHAR(255)NOT NULL上传文件名records_countInteger可为空导入记录数statusVARCHAR(50)NOT NULL,DEFAULT=‘success’状态:success/failedcreated_atDateTimeNOT NULL,INDEX,DEFAULT=now()导入时间戳3.3.3 数据库设计详解实体联系设计系统实体联系主要围绕"用户个性化行为"“数据维护审计”"时空分析支撑"三条主线展开:用户与地震事件——收藏关系(M:N):一名用户可以收藏 0…N 条地震事件;一条地震事件可以被 0…N 名用户收藏。通过 favorites 关联表以 (user_id, earthquake_id) 复合主键实现。用户与上传日志——操作审计关系(1:N):一名用户可以产生 0…N 条上传日志;每一条上传日志必须且仅能属于 1 名用户。通过 upload_logs.user_id 外键引用 users.id 实现。城市与地震事件——空间邻近/风险评估联系(派生 N:N):城市与地震事件之间的联系不属于传统的静态业务外键关系,而是由系统在运行期基于空间计算动态构造的联系。城市风险评估以"城市中心点坐标"为锚点,在给定半径(150km)内检索地震事件集合,并计算事件数量、震级分布、最大震级等指标形成评估输出。该联系随参数变化而变化,不设置硬外键约束。关系模式综合实体与联系的转换,本系统最终关系模式为:User(id, username(UQ), password_hash, role)Earthquake(id, original_id, time, longitude, latitude, depth, magnitude, location, event_type)City(id, name(UQ), display_name, latitude, longitude)Favorites(user_id, earthquake_id),其中 user_id → User.id,earthquake_id → Earthquake.idUploadLog(id, user_id → User.id, filename, records_count, status, created_at)范式分析系统关系表以"单一主键 + 多个描述字段"为主,业务写操作相对有限、读查询较多,适合采用满足第三范式的设计以降低冗余与维护成本:Users 表:候选键为 id 和 username,非主属性之间不存在传递依赖,满足 3NFEarthquakes 表:主键为 id,location 为目录给出的参考位置文本,不构成严格函数依赖,在当前业务假设下满足 3NFFavorites 表:复合主键 (user_id, earthquake_id),不存在非主属性,自然满足 3NFCity 与 UploadLogs 表:结构与 Users 类似,满足 3NF完整性约束实体完整性:所有实体表均通过整数型主键保证实体完整性;favorites 以复合主键保证收藏关系唯一且非空。参照完整性:upload_logs.user_id 引用 users.id,每条上传日志必须对应一个已存在的操作者用户favorites.user_id 引用 users.id,favorites.earthquake_id 引用 earthquakes.id城市与地震事件的"风险评估/附近地震查询"属于运行期派生关系,不设置硬外键约束取值范围约束:Users.role 取值限定为:ROLE_USER、ROLE_STAFF、ROLE_ADMIN经度:-180 ≤ longitude ≤ 180,纬度:-90 ≤ latitude ≤ 90深度:depth ≥ 0,震级:3 ≤ magnitude ≤ 10上传文件类型:仅允许 .csv、.xls、.xlsx索引设计索引设计围绕三类高频场景:索引类型字段用途主键索引users.id, earthquakes.id, cities.id, upload_logs.id按主键快速定位记录与基础分页唯一索引users.username, cities.name登录验证、重复注册检测、城市缓存命中普通索引earthquakes.time时间区间筛选与按时间倒序展示普通索引earthquakes.magnitude震级区间筛选普通索引earthquakes.latitude, earthquakes.longitude地图视口(bounding box)过滤与空间范围初筛普通索引upload_logs.user_id, upload_logs.created_at按操作者检索导入历史、按时间区间回溯3.3.4 核心路由与业务逻辑(app/routes.py)多维查询筛选(build_query):统一解析请求参数并拼装查询条件,供列表/导出/统计/地图复用,保证口径一致。支持日期、震级、深度、经纬度范围、地点范围(国内/国外)、关键词等多维度组合筛选def build_query(): query = Earthquake.query # 日期筛选 if start_date: query = query.filter(Earthquake.time >= ...) # 震级筛选 if min_mag is not None: query = query.filter(Earthquake.magnitude >= min_mag) # 地点范围筛选(国内/国外) if location_scope == 'china': query = query.filter(or_(*[Earthquake.location.contains(k) for k in CHINA_PROVINCES])) # ... 更多筛选条件 return query城市地震风险评估(nearby_earthquakes):基于 Haversine 公式计算城市周边 50km/100km/150km 三层距离的地震分布,采用两阶段空间查询策略——先用经纬度 bounding box 做粗筛(利用索引快速缩小候选集),再用 Haversine 计算精确距离做精筛,显著降低计算量与 I/O。采用多因素加权评分模型:def haversine(lon1, lat1, lon2, lat2): """计算地球表面两点间的大圆距离(km)""" lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) r = 6371 return c * r风险评分算法(基础分 10 分,逐项扣分):50km 内(权重最高):次数×0.8 + 震级累积×0.6 + 最大震级×0.5100km 内(中等权重):次数×0.5 + 震级累积×0.4 + 最大震级×0.3150km 内(较低权重):次数×0.3 + 震级累积×0.2 + 最大震级×0.15评分解读:8-10 分为低风险区,5-7 分为中风险区,1-4 分为高风险区。重要提示:本评分基于历史地震数据统计分析,仅供参考。地震预测极其复杂,历史低风险区域不代表未来无震。请关注官方地震预警信息,做好防震准备。统计分析(statistics):使用 Pandas 对筛选后的数据进行四维统计分析:震级分布(3-4, 4-5, 5-6, 6-7, ≥7 分档)震源深度分布(0-10km, 10-30km, 30-70km, 70-300km, >300km 分档)发震时间趋势(自动按日/月/年聚合)地区分布 Top 10(支持全部/国内/国外切换)权限控制装饰器(role_required):基于角色的访问控制,在路由层强制执行最小权限原则def role_required(roles): def decorator(f): @wraps(f) @login_required def decorated_function(*args, **kwargs): if current_user.role not in roles: flash('您没有权限执行此操作') return redirect(url_for('index')) return f(*args, **kwargs) return decorated_function return decorator数据导入(upload_manage):使用 pandas 读取 Excel 并做字段名映射、空值处理与去重;在写库前按"时间+经纬度+震级"做重复判定,采用事务机制保证一致性;导入完成后生成导入结果摘要(写入 UploadLog),便于维护人员复核。3.3.5 前端可视化地震分布地图(map.html):基于 Leaflet.js + OpenStreetMap,以圆形标记展示地震分布,圆点大小代表震级,颜色从黄色(小震)到深红色(大震)渐变,点击标记弹出详情。筛选条件透传至 API,保证地图展示始终与列表筛选一致。城市风险评估地图(city_risk.html):在地图上绘制城市周边 50km/100km/150km 三层同心圆(红/黄/蓝虚线),叠加周边地震标记,右侧面板展示风险评估报告与安全评分。城市坐标采用缓存策略——先查 cities 表,命中则直接返回;未命中再调用 Nominatim 获取坐标并落库缓存。统计分析图表(statistics.html):基于 Chart.js 绘制四类图表——震级分布柱状图、深度分布柱状图、时间趋势折线图、地区分布饼图。统计口径与筛选条件一致,便于用户从列表检索过渡到统计结论。全局 UI 主题(style.css):采用 Glassmorphism(毛玻璃)设计风格,卡片半透明磨砂效果,按钮胶囊圆角渐变,导航栏根据用户角色动态变色(管理员红粉/职员橙黄/用户蓝/游客灰),形成身份可感知的低成本提示,减少越权操作的误触。3.3.6 配置文件(config.py)支持 SQLite 与 PostgreSQL 数据库无缝切换:class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard-to-guess-string' # PostgreSQL(生产环境取消注释并修改连接串) # SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:password@localhost/earthquakedb' # SQLite(开发环境默认) SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'app.db') SQLALCHEMY_TRACK_MODIFICATIONS = False 3.3.7 生产数据库 DDL(schema.sql)提供 PostgreSQL 完整建表语句,含索引优化:CREATE TABLE IF NOT EXISTS earthquakes ( id SERIAL PRIMARY KEY, original_id INTEGER, time TIMESTAMP NOT NULL, longitude FLOAT NOT NULL, latitude FLOAT NOT NULL, depth FLOAT NOT NULL, magnitude FLOAT NOT NULL, location VARCHAR(255), event_type VARCHAR(50) ); CREATE INDEX IF NOT EXISTS idx_earthquakes_time ON earthquakes(time); CREATE INDEX IF NOT EXISTS idx_earthquakes_magnitude ON earthquakes(magnitude); CREATE INDEX IF NOT EXISTS idx_earthquakes_longitude ON earthquakes(longitude); CREATE INDEX IF NOT EXISTS idx_earthquakes_latitude ON earthquakes(latitude); 3.4 运行调试3.4.1 启动应用在项目根目录下执行:python run.pyFlask 开发服务器将在 http://127.0.0.1:5000 启动,开启 Debug 模式(自动重载代码修改)。3.4.2 功能验证1)未登录访客(Guest):访问主页即可进行地震信息查询与筛选(按日期区间、震级、深度、经纬度范围、地点关键字、区域等条件组合检索,分页浏览结果);其余涉及数据导出、统计分析、可视化模块与收藏等个性化功能限制在登录后使用。2)普通注册用户(ROLE_USER):登录后除查询筛选外,可导出筛选后的地震数据为 CSV 表格;进行数据统计分析并以图表呈现;浏览地震分布地图与城市风险评估;维护收藏清单;进入个人中心修改密码。3)数据维护人员(ROLE_STAFF):在普通用户权限之上,可通过 Excel 批量导入地震数据(系统自动解析、去重、记录日志);查看导入日志以便定位问题;对单条地震记录进行编辑或删除。4)系统管理员(ROLE_ADMIN):在维护人员权限之上,可通过管理员面板添加/删除用户、分配角色权限(ROLE_USER/ROLE_STAFF/ROLE_ADMIN)。3.4.3 数据库检查如需检查 Excel 数据文件格式,可使用:python inspect_excel.py3.4.4 切换 PostgreSQL 生产数据库1)安装 PostgreSQL 并创建数据库 earthquakedb2)执行 schema.sql 创建表结构:psql -U postgres -d earthquakedb -f schema.sql3)修改 config.py,取消 PostgreSQL 连接串注释并注释掉 SQLite 行4)重新运行 init_db.py 和 import_data.py 初始化数据四、释放资源本案例使用本地开发环境,无需释放云资源。如切换到 PostgreSQL 生产环境,请按需执行以下操作:4.1 删除 PostgreSQL 数据库psql -U postgres -c "DROP DATABASE IF EXISTS earthquakedb;" 4.2 清理 Python 虚拟环境deactivate rm -rf .venv # Linux/Mac rmdir /s .venv # Windows 五、成果展示5.1 未登录访客(Guest)界面系统对未登录访客仅开放地震信息查询与筛选能力,包括按日期区间、震级、深度、经纬度范围、地点关键字、区域等条件进行组合检索,并以分页形式浏览结果。5.2 普通注册用户(ROLE_USER)界面除提供查询服务外,普通注册用户可以导出筛选后的地震数据为表格形式;进行数据统计分析并以图表呈现;浏览地震分布地图与相关可视化视图;使用城市风险评估模块获取面向城市的分析结果;维护收藏清单以便长期跟踪;进入个人中心管理账户、修改密码等操作。5.3 数据维护人员(ROLE_STAFF)界面在这之上,系统还需为维护人员提供以下权限:数据导入能力(支持批量导入并处理重复/冲突情况);可查看导入日志/操作日志以便定位问题;对单条地震记录进行修改或在必要时进行删除的权限。5.4 系统管理员(ROLE_ADMIN)界面在数据维护人员之上,系统需提供管理员级管理账号(新增、删除、修改用户信息)、角色权限维护(分配与调整不同用户权限范围)的权限。六、码道智能体使用心得体会本次课程设计为地震信息查询与可视化平台,围绕地震事件数据的规范化管理、便捷查询与直观呈现的目标,完成了从需求分析、数据库设计到系统实现与验证的完整流程。数据层面,项目以中国地震台网公开数据为来源,结合导入工具将地震事件要素存入数据库,并通过去重与合并策略保证导入结果准确、可用且便于后续维护。系统设计层面,围绕查询、地图、统计与维护四类核心需求建立了较为清晰的模块边界。在关系数据库中提取用户、地震事件、城市缓存、收藏关系与上传日志等关键实体,通过完整性约束与索引设计支撑分页检索、组合筛选和审计回溯,并以访客、普通用户、数据维护人员和管理员四类角色落实最小权限原则。实现层面,后端采用 Flask 与 SQLAlchemy 构建统一的数据模型和查询逻辑,提供列表筛选、数据导入导出、地图数据查询以及城市风险评估等接口;前端以 Web 页面为主要载体,完成地震分布地图与统计图表展示。整体系统能够稳定运行,基本形成了“筛选查询—可视化分析—导出复用—维护更新”的完整操作流程。在本次课程设计中,我还使用了华为云码道智能体辅助完成项目开发。实际使用过程中,我体会到智能体不仅能够根据自然语言理解开发需求,还可以结合项目上下文分析代码结构、定位问题并提出修改建议。在数据库模型设计、前后端接口衔接、运行环境配置和错误排查等环节,码道智能体减少了查找资料和重复修改代码所耗费的时间,使我能够将更多精力放在系统功能设计与业务逻辑梳理上。不过,使用智能体并不意味着可以完全依赖其自动生成结果。有时智能体给出的代码虽然形式上完整,但仍可能与项目现有结构、依赖版本或实际业务规则存在偏差,需要开发者进一步检查、运行和调整。因此,我逐渐认识到,较好的使用方式是先明确需求和约束,将较大的任务拆分为具体步骤,再让智能体协助分析和实现,最后通过测试验证结果。这个过程也让我更加重视需求描述、代码阅读和调试能力。通过本次实践,我对华为云码道智能体在软件开发中的作用有了更直观的认识。它更适合作为开发过程中的辅助工具,帮助开发者提高编码、排错和理解项目的效率,而项目的整体设计、功能取舍以及最终质量仍需要由开发者负责。此次课程设计不仅加深了我对数据库设计与 Web 系统开发流程的理解,也让我初步掌握了利用代码智能体协同完成实际工程任务的方法。七、码道核心功能使用总览本项目在开发过程中深度使用了华为云码道(CodeArts)代码智能体的各项功能,以下按功能类别详细记录使用情况。7.1 智能编码与代码生成功能使用场景具体描述自然语言生成代码数据模型定义通过自然语言描述"创建地震事件模型,包含时间、经纬度、深度、震级、位置、事件类型字段,并对高频查询字段建立索引",码道自动生成 Earthquake 模型类及完整的 SQLAlchemy Column 定义自然语言生成代码路由与业务逻辑描述"实现多维组合查询,支持日期、震级、深度、经纬度、地点范围、关键词筛选",码道生成 build_query() 函数框架,包含参数解析与 ORM 条件拼接自然语言生成代码Haversine 距离计算描述"实现 Haversine 公式计算地球表面两点间大圆距离",码道生成精确的球面距离计算函数自然语言生成代码权限控制装饰器描述"创建基于角色的权限控制装饰器,支持多角色校验",码道生成 role_required() 装饰器及路由级权限校验逻辑代码补全模板渲染编写 Jinja2 模板时,码道自动补全 Flask 模板语法(url_for、render_template、{% block %} 等)代码补全SQLAlchemy 查询编写 ORM 查询链时,码道自动补全 filter、order_by、paginate 等方法及字段名7.2 代码理解与搜索功能使用场景具体描述语义搜索(CodeSemanticSearch)理解代码架构查询"城市风险评估是如何计算的",码道定位到 nearby_earthquakes 路由函数,展示完整的两阶段空间查询与加权评分算法语义搜索(CodeSemanticSearch)追踪数据流查询"地震数据从 Excel 导入到数据库的完整流程",码道串联 import_data.py → models.py → routes.py 的数据流路径结构搜索(CodeGraphSearch)依赖分析查询"User 模型被哪些路由引用",码道展示所有使用 current_user 和 User.query 的路由函数及行号结构搜索(CodeGraphSearch)影响分析查询"修改 Earthquake 模型会影响哪些功能",码道列出所有引用该模型的路由、模板和导入脚本代码探索(Explore Agent)项目结构理解使用 explore 子代理全面分析项目目录树、技术栈、核心文件功能,生成完整的项目结构报告7.3 代码编辑与重构功能使用场景具体描述精确字符串替换(Edit)修复路由逻辑精确定位 routes.py 中的查询条件拼接错误,替换为正确的 SQLAlchemy or_ / and_ 表达式精确字符串替换(Edit)更新模型字段为 Earthquake 模型添加 original_id 字段,同步更新 import_data.py 的导入逻辑全量替换(ReplaceAll)变量重命名将全局常量 PROVINCES 重命名为 CHINA_PROVINCES,全文件一次性替换文件写入(Write)创建新模板创建 city_risk.html、upload_manage.html 等新页面模板文件写入(Write)生成文档创建 工程说明.md、schema.sql 等项目文档与配置文件7.4 终端与命令执行功能使用场景具体描述Bash 命令执行依赖安装执行 pip install flask flask-sqlalchemy flask-login pandas openpyxl xlrd werkzeug 安装项目依赖Bash 命令执行数据库初始化执行 python init_db.py 创建数据表与默认用户Bash 命令执行数据导入执行 python import_data.py 批量导入地震速报目录 Excel 数据Bash 命令执行应用启动执行 python run.py 启动 Flask 开发服务器进行调试Bash 命令执行Git 版本管理执行 git log、git branch、git diff 等命令查看提交历史与分支状态Bash 命令执行文件日期修改执行 PowerShell 命令批量修改文件修改日期为指定日期7.5 文件操作与搜索功能使用场景具体描述文件读取(Read)代码审查读取 routes.py(758行)、models.py、所有 HTML 模板等核心文件,理解完整业务逻辑文件读取(Read)文档解析读取 .docx 课程设计报告,使用 python-docx 库提取全部段落文本与表格数据文件搜索(Glob)文件定位使用 **/*.py、**/*.html、**/*.docx 等模式快速定位项目文件内容搜索(Grep)代码定位搜索 ROLE_ADMIN、haversine、build_query 等关键字,定位代码实现位置文件删除(DeleteFile)清理文件删除临时文件或过时的脚本7.6 Git 版本控制功能使用场景具体描述提交历史查看开发进度追踪查看从 a25324d 中期任务 到 cfb0249 更新项目名称 的 8 次提交记录分支管理功能分支开发项目使用 6 个分支:main、beta、favourite、map、name、whole,分别对应不同开发阶段分支策略渐进式开发各分支代表不同实现阶段:name(命名优化)→ favourite(收藏功能)→ map(地图功能)→ whole(完整功能)→ beta(测试)→ main(稳定版)
  • [高校训练营] 智序校园(CampusFlow):基于华为云码道(CodeArts)代码智能体的智能校园周计划调度系统
    gitcode仓库链接:https://gitcode.com/gcw_UVRIWCMW/CampusFlow系统演示视频已经上传至仓库。一、概述1.1 案例介绍高校学生的日程通常由课程、周期性活动、作业、复习、社团事务和生活任务共同构成。手动安排周计划容易出现三类问题:重要任务被临时事项挤占、碎片时间没有被有效利用、计划发生变化后需要整体重排。此外,部分想从零培养起时间规划习惯的同学面对庞杂的任务、事件条目与大量碎片化时间,想要好好进行任务规划却不知从何下手的难题。为此,本案例构建 CampusFlow 智能校园周计划调度系统,以同济大学嘉定校区的课程与生活场景为示例,使用 FastAPI + SQLAlchemy + SQLite 构建后端,使用 Vue 3 + TypeScript + Pinia + Vite 构建前端,并通过高德地图 API 提供地点检索、逆地理编码和步行时间估算能力。此版本系统展示暂时不依赖大模型,而是使用确定性算法完成以下功能:核心能力实现方式用户价值周计划自动生成硬约束扣减、任务排序、贪心放置、负载均衡、时段多样性自动将待办任务安排到本周可用时段Top3 实时推荐精力、截止时间、地点、优先级、时长、可拆分性六维评分在当前碎片时间内快速判断“现在最适合做什么”顺路任务发现步行路径和绕行成本计算,接口失败时使用本地估算识别取快递、打印、购物等顺路可完成事项增量重规划识别受影响计划项,仅重排局部任务避免课程或任务变化后整周计划大幅“抖动”What-if 沙盘在隔离数据上应用模拟条件并比较前后方案提前评估生病、临时活动、截止日期提前等风险精力状态管理分时段精力曲线与手动状态覆盖将高难度任务安排到更合适的精力时段技术选型:华为云码道(CodeArts)代码智能体:华为云提供的智能化软件开发工具,融合代码大模型、AI IDE 和 Code Agent 等能力,能够理解项目需求并辅助完成代码生成、代码优化和工程构建。本案例中使用华为云码道(CodeArts)代码智能体作为核心开发辅助工具,根据智能校园周计划调度系统应用需求完成前后端功能开发,加速 Web 应用构建过程,降低应用开发门槛。1.2 适用对象高校学生及校园效率工具爱好者;希望学习时间调度、推荐评分和增量计算的个人开发者;从事教育信息化、日程管理或任务管理产品开发的工程师。1.3 案例时间本案例总时长预计180分钟。不包含 Python、Node.js 的首次下载时间以及高德开放平台账号认证时间。1.4 案例流程说明:开通华为开发者空间,领取华为云码道(CodeArts)代码智能体通用体验权限,同时准备 Python、Node.js、Git 等本地开发环境并申请高德地图 API Key;梳理智能校园周计划调度需求,编写 CampusFlow SDD、SKILLs 开发规则和结构化提示词,使用码道代码智能体生成 FastAPI 后端、Vue 3 前端及测试用例;安装 Python 和前端依赖,配置高德地图 API Key,初始化 SQLite 数据库,分别启动 FastAPI 后端服务与 Vue 3 前端应用,完成本地联调;运行种子数据脚本构建校园示例场景,围绕业务闭环、调度准确性和交互体验进行多轮测试与迭代优化;完成周计划自动生成、Top3 实时推荐、顺路任务发现、增量重规划和 What-if 沙盘模拟等功能验收,交付可在本地完整运行的 CampusFlow 应用。1.5 资源总览本案例预计花费0元,其中华为云码道(CodeArts)代码智能体(专业版)使用发放的代金券购买。资源名称规格单价(元)本地开发环境Python 3.10+ / Node.js 18+免费高德地图Web服务API个人开发者每日5000次调用额度免费SQLite数据库内置零依赖免费华为云码道(CodeArts)代码智能体专业版139/月二、环境和资源准备2.1 领取华为云码道代码智能体使用权限登录华为开发者空间,进入码道 CodeArts产品页,领取通用体验版权限,开通代码智能体(专业版)服务,获取在线代码生成与迭代能力。2.2 IDE安装与部署参考案例《AI IDE华为云码道(CodeArts)代码智能体安装部署》,完成Windows版华为云码道代码智能体安装部署。2.3 开发环境本案例在本地开发运行,需确保以下环境已安装:依赖项最低要求推荐版本验证命令Python3.103.11 或 3.12python --versionNode.js20.19+ 或 22.12+22 LTSnode --versionnpm10随 Node.js 22 安装的版本npm --versionGit非必需最新稳定版git --version2.4 申请高德地图Web服务API Key高德地图API为本系统提供逆地理编码、POI搜索和步行路径规划能力,是顺路任务发现和碎片时间计算的核心依赖。访问高德开放平台,注册并登录账号;进入 控制台 > 应用管理 > 我的应用,点击"创建新应用";添加Key,服务平台选择"Web服务",获取API Key;个人开发者每日享有5000次免费调用额度,满足本案例需求。三、构建CampusFlow智能校园调度应用3.1 需求分析与功能设计项目名称: 智序校园(CampusFlow)——智能校园周计划调度系统项目定位:面向高校学生的智能时间规划与任务调度平台。系统统一管理课程、校园活动、作业任务、个人待办和精力状态,综合考虑任务优先级、截止时间、可用时段、任务难度、当前位置及步行时间,自动生成可执行的校园周计划。系统还支持实时任务推荐、顺路任务发现、计划动态调整和 What-if 沙盘模拟,帮助学生减少手动排期成本,提高碎片时间利用率和任务完成效率。开发方式:使用华为云码道(CodeArts)代码智能体,结合 CampusFlow SDD、SKILLs 开发规则和结构化提示词,辅助完成需求分析、系统设计、前后端代码生成、测试用例编写及多轮迭代优化。项目最终在 PC 本地运行,不部署到华为云,也不调用华为云 MaaS 平台大模型服务。技术栈:前端:Vue 3 + Vite + TypeScript状态管理:Pinia路由管理:Vue RouterHTTP 客户端:Axios后端:Python + FastAPI数据访问:SQLAlchemy ORM数据校验:Pydantic数据库:SQLite外部服务:高德地图 Web 服务 API测试框架:Pytest运行方式:PC 本地前后端分离运行核心功能:管理课程、固定活动、普通任务、固定时间任务和顺路任务;根据课程与固定事件提取时间硬约束,计算每周可用时间段;综合任务优先级、截止时间、任务难度和每日负载,自动生成校园周计划;支持可分割任务拆分安排,并对长期任务进行分阶段调度;根据当前精力、剩余时间、任务难度、地点和优先级进行六维评分,实时推荐最适合执行的 Top3 任务;结合当前位置、下一目的地和步行路径,识别可在途中完成的顺路任务;计算下一课程或活动开始前的碎片时间,并扣除步行时间和必要缓冲时间;在课程变更、任务提前完成、任务未完成、新增高优先级任务等情况下触发增量重规划;仅调整受到影响的计划项,保留其他已安排内容,降低计划频繁变化带来的干扰;支持封锁某天、增加任务时长、提前截止时间、减少每日可用时间和添加临时活动等 What-if 沙盘模拟;对比原计划与模拟计划,识别任务未安排、截止逾期和风险变化;支持查看周计划时间线、任务详情、推荐理由、重规划记录和沙盘模拟结果;使用高德地图 API 完成地址解析、地点搜索和步行路径规划,并在接口异常时采用本地步行时间估算方案。3.2 Prompt 设计和 SDD 生成(1)根据以上项目需求,设计如下 Prompt(V1实现部分最基础的功能,剩余功能在V2实现):请帮我初始化一个SDD项目,先不要执行开发任务,我检查修改SDD项目后再告诉你执行开发: 1、项目概述 项目名称:CampusFlow - 大学生智能时间与任务调度系统 项目定位: 面向大学生的“时间—地点—精力—任务”多约束智能调度Web应用。 系统不仅管理待办任务,还结合课程安排、固定事件、当前位置、移动时间、精力状态、Deadline和任务难度,解决两个核心问题: (1)“这一周的任务应该怎么安排?”——生成本周推荐计划。 (2)“现在这个时间、地点和精力状态下,我最适合做什么?”——生成当前Top 3任务推荐。 同时支持Opportunity Task顺路机会,例如用户吃完饭准备去图书馆时,如果前往图书馆途中可以顺路去菜鸟驿站取快递,则在对应推荐中提示顺路完成。 技术栈: 前端:Vue3 + Vite + TypeScript 后端:FastAPI(Python) 数据库:SQLite 地图:高德地图JS API + 高德Web Service API 项目的mcp_settings.json中已经配置高德地图MCP及Web Service API Key。 高德MCP用于开发阶段辅助调用地图能力;应用运行时,高德地图JS API负责地图展示、浏览器定位、Marker和地图点击选点,逆地理编码、POI搜索和步行路径规划等高德Web Service能力通过FastAPI后端封装调用。 2、页面布局与核心功能 页面一:Dashboard 展示: 当前时间 当前地点 当前精力状态 当前有效碎片时间 下一行动目的地 下一个课程/固定事件 当前Top 3任务推荐 推荐理由 顺路Opportunity Task 今日计划概览 本周计划入口 支持手动设置“下一站”,可以从已有地点、POI搜索结果或地图点击位置中选择。 页面二:本周计划 以周视图展示: 课程 固定事件 推荐任务时间块 空闲时间 功能: 根据本周课程、固定事件、任务Deadline、预计时长、难度、优先级、精力曲线、地点偏好和任务可分割性生成本周推荐计划。 课程和固定事件属于不可移动的硬约束。 Deadline较近和优先级较高的任务优先安排。 高难度任务优先安排在高精力时间段。 可分割任务允许拆分到多个满足最小分割时间的时间段。 支持“生成本周计划”和“重新生成本周计划”。 V1采用规则式周计划推荐,不要求全局最优,也不自动持续重排整个未来计划。 页面三:任务管理 普通任务属性: 任务名称 Deadline 预计时长 难度 用户优先级 任务类型 地点偏好 是否可分割 最小分割时间 备注 状态 支持: 创建 编辑 删除 标记完成 查看待办和已完成任务 普通任务主要参与本周计划和当前Top 3推荐。 部分任务可以设置为Opportunity Task,例如: 取快递 打印材料 买文具 校园卡充值 去超市买东西 Opportunity Task通常没有明确Deadline,但需要设置: 具体地点或POI 预计执行时间 用户优先级 创建时间 状态 对于没有Deadline的Opportunity Task,根据加入待办列表后的等待时长计算动态紧迫程度。 等待时间越长,推荐优先级逐渐提高,但设置上限,不直接修改用户自己设置的优先级。 页面四:课程与固定事件 支持添加、编辑和删除课程及固定事件。 属性包括: 名称 开始时间 结束时间 具体地点 课程和固定事件作为周计划和碎片时间计算的硬约束。 页面五:地点与地图 使用高德地图展示校园位置。 自动定位流程: 页面加载后使用高德地图JS API请求浏览器定位权限。 定位成功后,在地图中显示当前位置Marker,并获取详细地址和地点语义。 定位失败、超时或用户拒绝权限时: 显示地图并提示用户手动选择当前位置。 用户直接点击地图任意位置即可添加当前位置Marker。 再次点击其他位置时移动原Marker。 根据点击坐标获取详细地址和附近POI,并将该位置设置为当前地点。 即使自动定位成功,也支持“重新选择当前位置”。 支持POI搜索,例如: 图书馆 教学楼 食堂 宿舍 菜鸟驿站 打印店 超市 体育场 搜索结果显示在地图中,用户可以将POI设置为: 当前地点 下一行动目的地 课程或固定事件地点 Opportunity Task地点。 页面六:精力状态 精力分为: 高 中 低 支持: 手动设置当前精力 设置一天不同时间段的精力曲线 未手动设置时根据当前时间自动推断当前精力状态。 3、核心功能流程 当前Top 3推荐流程: 根据当前时间、当前位置、当前精力、下一固定事件和待办任务计算有效碎片时间。 有效碎片时间 = 下一固定事件开始时间 - 当前时间 - 前往下一固定事件地点的步行时间 - 缓冲时间。 根据有效碎片时间筛选当前可以执行的任务,再综合: 精力与任务难度匹配 Deadline紧迫程度 地点语义匹配 用户优先级 预计执行时间 可分割性 使用确定性规则计算并返回Top 3任务,同时生成可解释推荐理由。 地点、精力、任务、时间或固定事件变化后重新计算推荐。 本周计划生成流程: 读取课程和固定事件形成本周硬约束时间块,识别剩余空闲时间。 根据任务Deadline、优先级、预计时长、难度、精力曲线、地点偏好和可分割性,将普通待办任务推荐到合适的时间段。 Opportunity Task原则上不强制加入普通周计划时间块,主要结合实际移动路线进行顺路推荐。 下一行动目的地流程: 下一行动目的地表示用户完成当前活动后准备前往的具体地点。 来源可以包括: 用户手动设置的下一站 本周计划中下一项安排的地点 用户准备执行的Top 3任务对应地点 下一课程或固定事件地点 例如: 当前在食堂 接下来准备去图书馆学习 即使“去图书馆学习”不是课程或固定事件,图书馆仍然可以作为下一行动目的地。 Opportunity Task顺路推荐流程: 比较: 当前位置 → 下一行动目的地 和: 当前位置 → Opportunity Task地点 → 完成Opportunity Task → 下一行动目的地 计算额外绕行时间。 只有当: Opportunity Task仍为待办 地点明确 下一行动目的地明确 时间允许 不影响后续课程或固定事件 额外绕行成本处于合理范围 时才作为顺路机会推荐。 Opportunity Task作为Top 3推荐的补充信息展示。 例如: Top 1: 去图书馆完成数据库作业 推荐理由: 当前精力较高,Deadline较近,图书馆适合完成该任务。 顺路机会: 前往图书馆途中可以顺路到菜鸟驿站取快递,该任务已等待3天,预计额外增加6分钟。 不同Top 3任务由于下一行动目的地不同,可以对应不同的顺路机会。 4、地图能力与异常处理 高德地图主要用于: 浏览器定位 地图展示 地图点击选点 Marker 逆地理编码 POI搜索 步行距离和时间计算 Opportunity Task顺路路线计算 高德服务调用失败时准备合理的Mock或fallback数据,不阻塞任务管理、本周计划、精力管理和基础Top 3推荐,并明确提示当前使用的是估算或演示数据。 5、设计风格 整体采用现代、简洁、清爽的校园效率工具风格。 重点突出: 当前状态 时间安排 地点移动 推荐结果 周计划 界面避免复杂堆叠和明显的AI生成感,信息层级清晰。 支持桌面端与移动端响应式布局,地图、周计划和推荐卡片需要具有良好的交互体验。 6、V1范围 V1实现: 本周计划推荐 当前Top 3推荐 Opportunity Task顺路机会 任务管理 课程与固定事件 自动定位与地图点击选点 POI搜索 地点与步行时间 精力曲线 有效碎片时间 状态变化后的实时推荐 先不要执行开发任务,生成完成后总结当前项目的功能范围、核心流程和主要技术方案,然后停止,等待我检查修改SDD。在码道对话界面选择 规范驱动模式(Spec-Driven Mode),发送上述请求。(2)码道根据需求描述,生成需求规格文档 spec.md。如有需要可对需求规格文档进行修改。(3)确认后,码道继续生成技术设计文档 design.md,完成生成后可按需修改。(4)确认后,码道继续生成编码任务文档 task.md,完成生成后可按需修改。(5)检查需求规格文档、技术设计文档、编码任务文档是否与预期一致,如有需要调整的地方可直接进行修改。3.3 编码任务执行确认 SSD 无误后,在码道界面发送请求:遵循spec.md、design.md、tasks.md进行项目开发。码道将根据 SSD 执行编码任务。完成待办事项:开发总结:3.4 V1问题修复与系统优化(部分对话)3.5 V2功能开发CampusFlow基础版本已经完成。 请基于当前已有项目、SDD、数据模型和功能进行增量开发,不要重新搭建项目,不要破坏现有的任务管理、课程/固定事件、周计划、当前Top 3推荐、地点地图、精力状态等功能。 本次新增或细化以下3项功能: 1、完整自动动态重规划 当前CampusFlow已经能够生成本周计划。本次增加自动动态重规划能力。 当现实情况发生变化时,系统自动识别受影响的计划,并重新安排尚未完成的任务,而不是要求用户手动重新生成整个周计划。 需要触发动态重规划的情况包括: - 新增、修改或删除课程/固定事件; - 当前任务未按计划完成; - 任务提前完成; - 新增高优先级任务; - 修改任务Deadline、预计时长或优先级; - 当前时间已经超过原计划任务时间; - 用户位置或可用时间发生明显变化。 例如: 原计划: 14:00-16:00 完成数据库报告 19:00-20:00 英语阅读 14:00突然增加临时班会。 系统需要识别数据库报告无法按原时间执行,并自动寻找新的可用时间段重新安排,同时检查后续任务是否受到影响。 重规划时: - 已完成任务不得修改; - 已开始且用户确认继续执行的任务不得随意移动; - 课程和固定事件属于硬约束,不得移动; - 优先调整受影响任务及其后的计划,避免无必要地重排整个星期; - 必须继续考虑Deadline、优先级、任务时长、精力曲线、地点和可分割性; - 可分割任务可以重新分配剩余部分; - 重规划后向用户展示哪些任务发生了变化以及变化原因。 Dashboard和本周计划中需要明显提示: “计划已根据最新情况自动调整”。 用户可以查看调整前后的差异。 2、What-if时间沙盘 新增“What-if时间沙盘”,用于模拟计划变化,但不能直接修改真实计划。 用户可以临时修改某些条件,例如: - “如果周六全天没有时间学习?” - “如果数据库报告增加2小时工作量?” - “如果周五晚上临时有活动?” - “如果这个任务提前到周三截止?” - “如果每天晚上少安排1小时任务?” 系统基于当前真实数据创建临时模拟场景,并重新计算计划。 页面需要展示: - 当前真实计划; - 模拟后的计划; - 哪些任务发生变化; - 哪些任务可能无法按Deadline完成; - 总可用时间变化; - 任务安排变化; - 风险变化。 What-if模拟不得直接修改: - 原任务; - 原课程; - 原固定事件; - 当前真实周计划。 用户可以: - 放弃模拟; - 修改模拟条件继续计算; - 点击“应用此方案”,确认后才将模拟方案应用到真实计划。 例如: 用户模拟“周六全天不可用”。 系统发现科研任务无法按照原计划完成,则提示: “科研任务存在延期风险,建议将其中90分钟提前安排至周四晚上。” 3、Opportunity Task顺路任务 进一步细化Opportunity Task顺路机会相关功能。 Opportunity Task是适合在移动途中顺便完成的短任务,例如: - 取快递; - 打印材料; - 买文具; - 校园卡充值; - 去超市买东西; - 领取文件。 这类任务: - 可以没有Deadline; - 必须绑定具体地点或POI; - 具有预计执行时间; - 具有创建时间; - 可以设置用户优先级。 对于没有Deadline的Opportunity Task,根据加入待办后的等待时间计算“Aging Urgency”。 等待时间越长,系统紧迫度越高,但必须设置最大值,不允许无限增长。 例如: 今天刚加入“取快递” → 紧迫度较低。 已经等待3天 → 优先级提高。 已经等待较长时间 → 在其他条件接近时应优先推荐。 Opportunity Task需要结合“下一行动目的地”进行顺路判断。 下一行动目的地不局限于下一课程或固定事件,可以来自: - 用户手动指定的下一站; - 本周计划中的下一项安排地点; - 当前准备执行的Top 3任务对应地点; - 下一课程/固定事件地点。 例如: 当前位置:食堂 下一站:图书馆 Opportunity Task:菜鸟驿站取快递 即使“去图书馆学习”不是课程或固定事件,仍需要判断: 食堂 → 图书馆 与: 食堂 → 菜鸟驿站 → 图书馆 之间的时间差。 顺路总成本需要考虑: 当前位置 → Opportunity Task地点的步行时间 + Opportunity Task执行时间 + Opportunity Task地点 → 下一行动目的地的步行时间。 计算相对于直接前往下一行动目的地增加的额外成本。 仅当: - Opportunity Task仍为待办; - 地点明确; - 下一行动目的地明确; - 额外绕行成本低于阈值; - 时间足够; - 不影响后续课程/固定事件; 才作为顺路机会。 Opportunity Task与当前Top 3推荐结合展示,不单独形成另一套主要推荐系统。 例如: Top 1:去图书馆完成数据库作业 推荐理由: 当前精力高,数据库作业Deadline较近。 顺路机会: 前往图书馆途中可顺路到菜鸟驿站取快递,该任务已等待3天,预计额外增加6分钟。 不同Top 3任务对应的下一行动目的地不同,因此可以产生不同的顺路机会。 一个Top 3任务可以对应0个、1个或多个Opportunity Task。 多个顺路机会需要综合: - Aging Urgency; - 用户优先级; - 额外绕行成本; - 执行时间; 进行排序。 4、功能联动 新增的三个功能必须与现有CampusFlow数据和推荐逻辑联动。 动态重规划负责: “现实发生变化以后,剩余计划应该怎么调整?” What-if负责: “假如某种情况发生,计划会变成什么样?” Opportunity Task负责: “我实际移动途中,有没有值得顺手完成的事情?” What-if属于模拟,不应触发真实动态重规划。 只有用户确认应用What-if方案后,才能修改真实计划。 Opportunity Task完成后,应同步更新待办状态,并重新计算相关推荐。 请优先复用现有代码、数据模型、调度算法和高德地图能力。 根据新增功能同步更新当前SDD,保持需求、设计、任务和实际代码一致。 完成开发后运行相关测试,重点测试动态重规划、What-if隔离、Opportunity Task路线判断和异常边界情况,并总结本次新增功能及测试结果。V2开发完成后项目开发到此结束,此后继续根据发现的问题进行系统优化,此处不再赘述。四、系统说明4.1 项目结构说明CampusFlow/ ├── backend/ # FastAPI 后端 │ ├── app/ │ │ ├── main.py # 应用入口,路由注册与自动迁移 │ │ ├── config.py # 集中配置(权重、API Key、常量) │ │ ├── models/ # SQLAlchemy ORM 模型 │ │ │ ├── task.py # 任务模型(普通/顺路/固定时间) │ │ │ ├── schedule.py # 课程与固定事件模型 │ │ │ ├── energy.py # 精力曲线与状态模型 │ │ │ ├── plan.py # 周计划、计划项、重规划日志、沙盘会话 │ │ │ └── location.py # 下一目的地模型 │ │ ├── schemas/ # Pydantic 请求/响应模式 │ │ ├── repositories/ # 数据访问层 │ │ ├── services/ # 业务逻辑层(核心算法) │ │ │ ├── plan_service.py # 周计划调度算法 │ │ │ ├── recommend_service.py # Top3推荐(6维评分) │ │ │ ├── replan_service.py # 增量重规划(7种触发) │ │ │ ├── whatif_service.py # What-if沙盘模拟 │ │ │ ├── fragment_time_service.py # 碎片时间计算 │ │ │ ├── opportunity_service.py # 顺路机会发现 │ │ │ └── next_destination_service.py # 下一目的地推断 │ │ ├── adapters/ # 外部API适配器 │ │ │ ├── amap_client.py # 高德地图REST API客户端 │ │ │ └── walking_estimator.py # 步行时间估算(降级方案) │ │ └── routers/ # API路由(8个模块) │ ├── tests/ # pytest 测试 │ ├── requirements.txt # Python依赖 │ └── seed_data.py # 种子数据脚本 └── frontend/ # Vue 3 前端 └── src/ ├── views/ # 7个页面视图 ├── components/ # 可复用组件 ├── stores/ # Pinia状态管理(8个Store) ├── services/ # API调用服务 └── types/ # TypeScript类型定义 4.2 系统架构4.3 核心算法架构4.4 部署后端服务4.4.1 安装Python依赖在终端中执行:cd CampusFlow/backend pip install -r requirements.txtrequirements.txt 核心依赖如下:fastapi==0.115.0 uvicorn[standard]==0.30.6 sqlalchemy==2.0.35 alembic==1.13.2 pydantic==2.9.2 httpx==0.27.2 python-dotenv==1.0.1 pytest==8.3.4 4.4.2 配置高德地图API Key通过环境变量设置,无需修改代码:export AMAP_API_KEY="您的高德地图API Key" 4.4.3 关键代码讲解(1)调度算法核心 — plan_service.py调度算法是系统核心,采用贪心放置 + 负载均衡 + 时间多样性策略:def generate_weekly_plan(self, week_start: date) -> WeeklyPlan: # 1. 计算硬约束(课程+固定事件) schedules = self.schedule_repo.get_by_week(week_start) # 2. 计算空闲时间段(扣除睡眠00:00-07:30和硬约束) free_slots = self._compute_free_slots(schedules, week_start) # 3. 按天分组空闲段 slots_by_day = self._group_slots_by_day(free_slots) # 4. 分离固定时间任务和弹性任务 fixed_time_tasks, flexible_tasks = self._separate_tasks(tasks) # 5. 优先安排固定时间任务 for task in fixed_time_tasks: self._find_best_placement(task, slots_by_day) # 6. 弹性任务按(优先级, 截止日期, 难度)排序 flexible_tasks.sort(key=lambda t: (-t.priority, t.deadline, t.difficulty)) # 7. 可分割任务循环拆分安排 for task in flexible_tasks: if task.is_splittable: self._schedule_splittable_task(task, slots_by_day) else: self._find_best_placement(task, slots_by_day) 放置评分算法:选择score最小的位置放置任务score = day_assigned_minutes[day_idx] # 负载均衡:优先安排到当天任务少的位置 - diversity_bonus # 时间多样性奖励(新时段类型+100分) + waste * 0.1 # 浪费惩罚(空闲段-任务时长的冗余) (2)6维推荐评分 — recommend_service.pydef _calculate_score(self, task, fragment_minutes, energy_level): score = ( self.W_ENERGY_DIFFICULTY * energy_difficulty_match # 精力-难度匹配 (0.25) + self.W_DEADLINE_URGENCY * deadline_urgency # 截止紧急度 (0.25) + self.W_LOCATION_MATCH * location_match # 地点匹配 (0.15) + self.W_USER_PRIORITY * user_priority # 用户优先级 (0.15) + self.W_DURATION_FIT * duration_fit # 时长适配 (0.10) + self.W_SPLITTABLE_BONUS * splittable_bonus # 可分割奖励 (0.10) ) return score精力-难度匹配矩阵:任务难度: high任务难度: medium任务难度: low精力: high1.00.70.3精力: medium0.51.00.7精力: low0.10.51.0设计思路:高精力时优先做高难度任务(1.0),低精力时优先做低难度任务(1.0),避免精力低谷强行攻坚。(3)增量重规划 — replan_service.py7种触发条件及其影响范围识别:核心优势:增量重规划仅重排受影响的计划项,保留未受影响部分,避免全量重排导致计划"抖动"。(4)What-if沙盘模拟 — whatif_service.py6种模拟条件类型:条件类型参数效果block_dayday_offset, name整天不可用(模拟生病/请假)block_time_rangeday_offset, start_hour, end_hour, name某时段不可用(模拟临时有事)increase_task_durationtask_id, extra_minutes增加任务工作量(模拟作业比预期更耗时)change_deadlinetask_id, new_deadline修改截止日期(模拟deadline提前)reduce_daily_hourshours每天少安排N小时(模拟效率下降)add_eventday_offset, start_hour, end_hour, name添加临时活动(模拟突发会议)模拟流程:应用条件 → 模拟调度 → 对比分析 → 风险计算5种风险类型:deadline_risk(原计划有但模拟中未安排)、new_unassigned(新增未安排任务)、deadline_overdue(完成时间超过deadline)、risk_increased/risk_decreased(风险增减对比)(5)高德地图API集成 — amap_client.pyclass AMapClient: BASE_URL = "https://restapi.amap.com/v3" async def regeocode(self, lng: float, lat: float) -> dict: """逆地理编码:坐标 → 地址""" async def search_poi(self, keywords: str, city: str = None) -> list: """POI关键词搜索""" async def walking_direction(self, origin: str, destination: str) -> dict: """步行路径规划:返回距离、时长、分步导航""" 容错机制:内存缓存(5分钟TTL)+ 请求限流(0.2秒间隔)+ API失败降级到WalkingEstimator(Haversine距离 + 5km/h速度估算)4.4.4 填充种子数据种子数据脚本 seed_data.py 以同济大学嘉定校区为场景,填充示例数据:python seed_data.py填充内容包括:11个建筑坐标:复楼、广楼、安楼、嘉定机房、体育中心、佳新馆、图书馆、食堂、宿舍楼、菜鸟驿站、实验室15门课程:覆盖周一~周六,5个时间段(1-2节~9-10节)6个固定事件:班长例会、ACM社团午餐会、英语角等15个任务:4个已完成 + 8个待办普通任务 + 4个待办顺路任务精力曲线:9个时段分段(06:00~23:59)4.4.5 启动后端服务cd backend uvicorn app.main:app --reload --port 8000 启动后访问 http://localhost:8000/docs 可查看Swagger API文档。4.5 部署前端应用4.5.1 安装前端依赖在新终端中执行:cd CampusFlow/frontend npm install package.json 核心依赖:{ "vue": "^3.5.39", "pinia": "^4.0.2", "vue-router": "^4.6.4", "axios": "^1.18.1", "vite": "^8.1.1", "typescript": "~6.0.2" } 4.5.2 前端关键代码讲解(1)API客户端与代理配置services/apiClient.ts 中配置后端API地址:const apiClient = axios.create({ baseURL: "http://localhost:8000/api", timeout: 10000, }); vite.config.ts 中配置开发代理,将 /api 请求转发到后端:server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, }, }, } (2)Pinia状态管理Store管理状态核心方法planStoreweeklyPlan, nextDestinationfetchWeeklyPlan, generateWeeklyPlanrecommendStorerecommendations(Top3)fetchTop3replanStorelastReplanResult, showReplanBannertriggerReplan, dismissBannerwhatifStoresessions, currentSessioncreateSimulation, applySessionenergyStorecurrentState, curvefetchCurrentState, setManualLeveltaskStoretasksfetchTasks, createTask, completeTaskscheduleStoreschedulesfetchSchedules, createSchedulelocationStorecurrentLocation, currentAddresssetCurrentLocation, setDefaultCampus(3)核心组件组件功能Top3RecommendCard.vueTop3推荐卡片展示(6维分数、推荐理由、顺路机会)OpportunityCard.vue顺路机会卡片(绕行时间、aging紧迫度)TaskForm.vue任务创建/编辑表单(支持普通/顺路/固定时间类型)ScheduleForm.vue课程/事件表单(含地点坐标选择)EnergyCurveEditor.vue精力曲线可视化编辑器(拖拽调节高/中/低)4.5.3 启动前端开发服务器npm run dev前端开发服务器启动于 http://localhost:5173。4.6 功能体验4.6.1 仪表盘 — 实时推荐与顺路发现访问 http://localhost:5173,进入主仪表盘页面:当前状态区:显示当前时间、地点、精力状态、碎片时间Top3推荐区:基于6维评分推荐当前碎片时间最适合做的3个任务,每个任务显示总分、各维度分数和推荐理由顺路机会区:显示去下一目的地途中可顺便完成的任务,包含绕行额外时间和aging紧迫度今日计划区:展示当天已安排的计划项时间线重规划横幅:当检测到需要重规划时,顶部弹出提示横幅4.6.2 本周计划 — 自动调度时间线7天时间轴:周一~周日,按时间段展示推荐任务(由于截图时间为周日,故只有周日排了任务)重规划标记:被重规划调整的计划项显示变更标记未安排任务:无法安排的任务在底部单独列出4.6.3 What-if沙盘模拟选择模拟条件(可多选组合):封锁某天/某时段(模拟生病或临时有事)增加任务工作量(模拟作业比预期更耗时)修改截止日期(模拟deadline提前)减少每日可用时间(模拟效率下降)添加临时活动(模拟突发会议/活动)点击"开始模拟",系统生成模拟计划并与原计划对比查看风险提示:deadline风险、新增未安排任务、截止逾期等确认后可一键应用模拟方案到真实计划4.6.4 增量重规划以下操作会自动触发增量重规划:操作触发类型效果新增/修改/删除课程schedule_changed重排与课程重叠的任务完成任务task_completed_early释放时间槽,重排后续任务新增高优先级任务(priority≥4)new_high_priority_task让位给新任务修改任务deadline/duration/prioritytask_property_changed重新评估该任务安排4.6.5 课程与固定事件4.6.6 精力状态4.7 运行测试后端包含完整的pytest测试套件,验证核心算法正确性:cd CampusFlow/backend pytest tests/ -v 测试覆盖范围包括:调度算法:空闲段计算、贪心放置、可分割任务拆分推荐算法:6维评分计算、候选过滤、Top3排序重规划:7种触发条件识别、增量重排沙盘模拟:6种条件应用、对比分析、风险计算碎片时间:步行时间扣除、缓冲时间计算顺路发现:绕行成本计算、aging紧迫度五、释放资源本案例在本地开发运行,无需释放云资源。体验完成后:在后端终端按 Ctrl+C 停止FastAPI服务;在前端终端按 Ctrl+C 停止Vite开发服务器;如需清理数据库,删除 backend/campusflow.db 文件即可。六、扩展资料说明华为云码道CodeArts实战速成:https://edu.huaweicloud.com/certification/1eda08826e5349109b00b009f9f1112a华为云开发者AI训练营:https://developer.huaweicloud.com/activity/trainingcamps.html想了解更多关于FastAPI框架的可以访问:https://fastapi.tiangolo.com/" target=“_blank”>https://fastapi.tiangolo.com/想了解更多关于Vue 3的可以访问:https://vuejs.org/想了解更多关于高德地图Web服务API的可以访问:https://lbs.amap.com/api/webservice/summary想了解更多关于SQLAlchemy ORM的可以访问:https://www.sqlalchemy.org/想了解更多关于Pinia状态管理的可以访问:https://pinia.vuejs.org/
  • [高校训练营] 基于华为云码道(CodeArts)的双引擎股票预测系统实践
    基于华为云码道(CodeArts)的双引擎股票预测系统实践源代码链接(本人基于码道智能体原创):https://github.com/AlphaWangZY/Stock-Prediction-System-using-CodeArts/在线体验地址:http://121.36.208.71(请复制到浏览器访问)一、概述1.1 案例介绍非金融专业人士在参与股票投资时,面临信息收集困难、分析框架缺失、模型使用门槛高、风险意识薄弱四大痛点。本项目构建"规则引擎 + ML模型"双引擎预测系统,提供可解释的多维度规则打分与数据驱动的多模型ML预测,帮助用户从不同视角理解市场,避免单一方法的盲区。本案例使用华为云码道(CodeArts)代码智能体完成从需求分析、系统设计、模型训练、Web开发到华为云部署的全流程。完成案例后,您将掌握:使用码道智能体完成需求梳理、架构设计和功能模块开发;训练5种回归模型(MLP、DLinear、Ridge、RandomForest、LinearSVR)并导出ONNX用于轻量推理;构建规则引擎四维/五维打分框架,产出可解释的预测结论与交易计划;实现多模型集成推理与投票共识机制;使用FastAPI + Vue3 + ECharts构建前后端分离的金融预测Web应用;在华为云ECS上完成Nginx + Systemd生产级部署。说明:本系统预测概率上限为65%,ML模型方向准确率约48%-52%,预测结果仅供参考,不构成投资建议。1.2 适用对象有一定股票投资经验但缺乏系统分析方法的个人投资者;希望了解AI辅助决策但不会自行训练模型的技术小白;需要盘后复盘工具的散户投资者;对金融ML模型训练与部署感兴趣的高校学生。1.3 案例流程需求与设计:使用码道梳理30项功能需求,完成系统架构、API、数据结构和页面原型设计;ML模型训练:训练5种回归模型(A股+美股分别训练),导出ONNX;Web应用开发:FastAPI后端(6个Service + 5个Router)+ Vue3前端(4个页面);华为云部署:ECS + Nginx + Systemd生产级部署;功能体验:搜索股票 → 查看K线 → 发起双引擎预测 → 查看多模型对比 → 生成报告。1.4 方案架构系统采用前后端分离三层架构:浏览器(Vue3 + ECharts + Element Plus) │ HTTP ▼ Nginx 反向代理(/ → 前端dist, /api/* → 后端8000) │ ├── 前端静态资源(dist/) │ └── FastAPI 后端(8000) ├── Stock Service:股票搜索 + 标的解析 ├── KLine Service:K线数据 + 均线计算 ├── Rule Engine:四维/五维打分 + 交易计划 + 风险提示 ├── ML Engine:5模型集成推理 + 投票共识 ├── Compare Engine:双引擎对比 + 共振/对冲信号判定 ├── Report Service:Markdown报告生成 └── News Service:关联新闻 │ ├── 腾讯财经API / 东方财富API(在线K线 + 实时行情 + 搜索) └── 本地CSV历史数据 + ONNX模型文件1.5 资源总览资源名称推荐规格用途计费说明华为云码道(CodeArts)体验版代码智能体辅助开发免费弹性云服务器 ECS2 vCPU、4 GiB、Ubuntu 22.04运行应用按需计费弹性公网 IP EIP按流量计费、5 Mbit/s浏览器访问按流量计费二、环境和资源准备2.1 前置条件已注册华为云账号并完成实名认证;本地已安装 Python 3.10+、Node.js 18+、conda(用于ML训练);本地可使用 SSH 和 SCP/WinSCP。2.2 创建 ECS登录华为云控制台 → 弹性云服务器 ECS → 购买弹性云服务器;推荐配置:2 vCPU / 4 GiB / Ubuntu 22.04 / 40 GiB系统盘 / 按流量计费5Mbit/s带宽;记录公网IP和登录密码。2.3 配置安全组入方向规则添加:协议端口来源用途TCP220.0.0.0/0SSHTCP800.0.0.0/0浏览器访问三、通过码道分阶段搭建项目3.1 开通并进入码道登录华为开发者官网,进入华为云码道(CodeArts)代码智能体体验页面;按页面提示完成体验版开通;下载并安装支持码道的开发工具,登录同一华为云账号。3.2 需求与功能清单梳理使用码道智能体分析 requirements.md 需求文档,自动提取30项功能需求并按P0/P1/P2三级优先级分类,产出 feature-modules.md 功能模块表:P0 核心模块19项:股票搜索、K线展示、规则引擎预测、ML预测、双引擎对比、报告生成等;P1 辅助模块8项:美股搜索、时间范围选择、可视化对比图、一致性分析等;P2 可选模块3项:关联新闻、移动端适配等。3.3 系统结构设计使用码道智能体一次性完成全部设计工作,产出 docs/system-design.md:系统架构设计:三层架构(Vue3 → Nginx → FastAPI → 数据源),技术选型与理由;API接口设计:10个REST API(股票搜索/K线/规则引擎预测/ML预测/双引擎对比/新闻/报告等);数据结构与特征设计:12维ML特征列表、Z-Score归一化方案、A股四维打分规则;前端页面原型设计:4个页面ASCII布局图、交互流程。3.4 ML模型训练使用码道智能体编写训练脚本,对A股(沪深300+中证500)和美股(S&P500+纳斯达克100)分别训练5种回归模型:模型A股 DirAccA股 IC美股 DirAcc美股 IC说明MLP48.3%-0.00345.0%-0.0053层全连接+BN+DropoutDLinear49.1%0.00451.9%0.014趋势-季节分解+线性投影Ridge48.6%-0.00645.3%0.008岭回归RandomForest48.4%-0.00045.3%0.005随机森林LinearSVR49.1%0.00143.8%-0.004线性支持向量回归注:方向准确率接近50%是金融收益率预测的典型表现,ML模型作为辅助参考,核心预测来自规则引擎。3.5 Web应用开发使用码道智能体编写完整后端和前端:后端(FastAPI):6个Service + 5个Router,10个API端点。前端(Vue3 + Element Plus + ECharts):4个页面视图 + API封装 + 路由配置。3.6 数据源适配与修复开发过程中发现AKShare的push2his.eastmoney.com接口被网络策略屏蔽,码道辅助完成以下重构:kline_service.py:改用腾讯财经API(优先)+ 东方财富push2his(备选)+ 本地CSV(回退);stock_service.py:改用东方财富搜索API + 实时行情API + fallback字典;rule_engine.py、ml_engine.py:移除AKShare依赖,改用kline_service + stock_service;news_service.py:改用东方财富搜索API + 占位数据。3.7 多模型集成推理将单模型(MLP)扩展为5模型并行推理,新增:模型投票共识:统计看涨/看跌票数,计算平均预测收益率;多模型对比表格:每个模型独立展示方向、预测收益率、方向准确率、IC;DLinear序列推理:使用seq_cache缓存最近20天序列数据作为输入。四、核心技术难点与解决思路4.1 AKShare历史K线接口被网络策略屏蔽问题:AKShare底层调用push2his.eastmoney.com被屏蔽,返回连接拒绝。解决:采用"腾讯财经API(优先)→ 东方财富push2his(备选)→ 本地CSV(回退)"三级数据源策略。腾讯财经API(web.ifzq.gtimg.cn)可正常返回A股最新日K线数据,与本地历史CSV合并后K线可更新到最新交易日。4.2 ML推理特征未归一化导致预测值异常问题:ML预测返回极端值(如-225949),明显不合理。原因:训练时使用已z-score归一化的特征(mean≈0, std≈1),但推理时直接用实时行情原始值(如close=1377)作为输入,分布严重不匹配。解决:从原始CSV计算各特征的mean和std,保存为scaler_{market}.json;推理前对特征做(raw - raw_mean) / raw_std归一化。修复后预测值回归合理范围(如-0.001457,即-0.15%次日收益率)。4.3 SVM训练超时问题:RBF核SVM在77万样本上训练超时(O(n²~n³)复杂度)。解决:改用LinearSVR(线性核,O(n)复杂度),训练时间从>120s降至0.7s。4.4 DLinear序列数据内存溢出问题:构建全量序列数据(970K×60×12 float32 ≈ 2.8GB)超出内存限制。解决:三重优化:seq_len从60降至20;采样量限制20万条;只用hs300/sp500单数据集。内存从2.8GB降至约192MB。4.5 report_service维度key硬编码导致美股报告崩溃问题:report_service硬编码了A股维度key(market_env/capital_flow/technical/news),美股维度key不同(fundamental/technical/capital/sentiment/macro)导致KeyError。解决:改为动态遍历rule['dimensions']字典,兼容任意维度key,并为每个维度提供中文通俗解释。五、构建并部署应用5.1 技术栈与项目结构层次技术版本/作用前端框架Vue3 + Vite组合式API + 快速构建UI组件库Element PlusVue3生态成熟UI库图表库EChartsK线图、均线、成交量后端框架FastAPIPython异步框架,自动OpenAPI文档ML推理onnxruntime + joblibONNX(MLP/DLinear)+ pickle(Ridge/RF/SVR)数据获取requests腾讯财经API + 东方财富API反向代理Nginx前端静态 + 后端API代理运行环境Ubuntu ECS + Systemd生产级进程管理可以使用码道智能体自动完成环境配置。项目关键结构:stock-predict/ ├── backend/ │ ├── app/ │ │ ├── main.py # FastAPI入口 │ │ ├── config.py # 配置 │ │ ├── models/schemas.py # Pydantic数据模型 │ │ ├── routers/ # 5个路由模块 │ │ └── services/ # 6个业务服务 │ ├── ml/ │ │ ├── train.py # MLP/Ridge/RF/SVR训练 │ │ ├── train_dlinear.py # DLinear训练 │ │ ├── models/ # ONNX + PKL + JSON模型文件 │ │ └── seq_cache/ # DLinear序列数据缓存 │ └── requirements.txt ├── frontend/ │ ├── src/ │ │ ├── views/ # 4个页面视图 │ │ ├── api/index.js # API封装 │ │ └── router/index.js # 路由 │ ├── vite.config.js │ └── package.json ├── data/ # 历史CSV数据(hs300/zz500/sp500/nq100) ├── docs/system-design.md # 系统设计文档 ├── feature-modules.md # 功能模块表 └── dev-log.md # 开发日志5.2 关键实现解析5.2.1 规则引擎四维/五维打分A股规则引擎按四个维度量化打分,每维-2~+2分:维度权重数据来源打分逻辑大盘环境30%上证指数K线站上5日/10日均线各+1,近5日上涨+1资金行为30%实时行情涨跌幅涨幅>1%偏强+1,跌幅>1%偏弱-1技术面25%个股K线+RSI站上5日/20日均线各+1,RSI超买-1/超卖+1消息面15%占位(数据受限)默认中性0分加权总分→方向判定→概率量化(上限65%)→交易计划(入场/止损/目标/仓位)→风险提示。5.2.2 多模型集成推理与投票共识ML引擎同时运行5个模型,每个独立输出预测收益率和方向:for model_key in ["mlp", "dlinear", "ridge", "rf", "svr"]: pred_z = _run_model(model_key, market_key, features) pred_return = float(pred_z) * label_std + label_mean # 统计看涨/看跌票数 votes["bullish" if pred_return > 0 else "bearish"] += 1 投票共识:看涨票数 ≥ 看跌票数 → 共识看涨,否则看跌。平均预测收益率作为综合参考。5.2.3 三级数据源策略K线数据获取采用三级回退策略,确保在不同网络环境下都能工作:腾讯财经API(web.ifzq.gtimg.cn):A股在线日K线,返回最新数据;东方财富push2his(push2his.eastmoney.com):备选,部分网络环境可用;本地CSV:最终回退,包含2021-2025年A股和2019-2023年美股历史数据。在线数据与本地数据通过日期合并:在线数据补充本地数据截止日之后的新数据。5.3 部署步骤步骤1:上传项目代码使用WinSCP将项目文件夹上传到ECS的 /opt/stock-predict/ 目录(上传前删除 frontend/node_modules)。步骤2:安装系统环境apt update && apt upgrade -y apt install -y python3 python3-pip python3-venv nginx curl -fsSL https://deb.nodesource.com/setup_18.x | bash - apt install -y nodejs步骤3:配置Python后端cd /opt/stock-predict python3 -m venv venv source venv/bin/activate pip install -r backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install joblib -i https://pypi.tuna.tsinghua.edu.cn/simple步骤4:构建前端cd /opt/stock-predict/frontend npm config set registry https://registry.npmmirror.com npm install vite@6 --save-dev npm install npm run build步骤5:配置Nginxserver { listen 80; server_name <ECS公网IP>; location / { root /opt/stock-predict/frontend/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8000/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 120s; } } 步骤6:配置Systemd服务[Unit] Description=Stock Predict FastAPI After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/stock-predict ExecStart=/opt/stock-predict/venv/bin/python -m uvicorn backend.app.main:app --host 127.0.0.1 --port 8000 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target步骤7:修复权限并验证chmod 755 /opt /opt/stock-predict /opt/stock-predict/frontend chmod -R 755 /opt/stock-predict/frontend/dist systemctl daemon-reload systemctl enable stock-predict systemctl start stock-predict nginx -t && systemctl restart nginx浏览器访问 http://<ECS公网IP> 即可使用系统。六、功能体验6.1 股票搜索在搜索页输入股票代码(如600519)或名称关键词;选择市场类型(A股/美股);点击搜索结果进入仪表盘页。6.2 K线图查看仪表盘页展示ECharts K线图,含开盘/收盘/最高/最低/成交量;叠加5日/10日/20日/60日均线;切换时间范围:1月/3月/6月/1年/全部。6.3 双引擎预测点击"发起预测"进入预测对比页;规则引擎:展示四维/五维打分详情(每维得分、权重、数据来源、小白解释)、加权总分、方向判定、概率、价格区间;ML模型:展示5个模型的独立预测结果(方向、预测收益率、方向准确率、IC),以及模型投票共识(看涨/看跌票数、平均收益率);交易计划:入场价、止损价、目标价TP1/TP2、仓位、时间止损、不做条件;风险提示:3-5个风险点 + 免责声明。6.4 预测报告点击"生成完整报告"进入报告页;展示Markdown格式预测报告,含预测概要、规则引擎分析(每维详细解释)、ML模型预测、交易计划、风险提示;每个专业术语附通俗解释(如"大盘环境就像「天气」")。七、码道使用总结7.1 使用的码道功能功能使用场景效果评价智能问答分析需求文档,提取30项功能项并分类快速梳理需求,产出模块表智能问答完成系统架构/API/数据结构/页面原型设计一次性产出完整设计文档智能问答编写ML训练脚本,优化SVM超时问题自动编写train.py,解决训练瓶颈智能问答重写5个service文件移除AKShare依赖一次性完成全部service层重构智能问答实现多模型集成推理与投票共识扩展单模型为5模型并行推理代码续写MLP模型定义与训练循环自动补全PyTorch训练代码代码续写FastAPI路由与service层代码自动补全API端点与业务逻辑dev-logger Skill全程记录开发过程自动生成结构化开发日志7.2 关键Skill使用记录A股和美股预测 Skill:是下载的基于规则进行股票预测的专门skill。dev-logger Skill:是使用码道智能体编写的skill,在需求梳理、系统设计、模型训练、服务修复等关键节点自动追加日志记录,按模板结构记录项目信息、实现内容、关键代码、技术难点和码道辅助过程。八、运行维护与故障排查8.1 常用运维命令# 查看后端状态 systemctl status stock-predict # 查看后端日志 journalctl -u stock-predict -f # 重启后端 systemctl restart stock-predict # 查看Nginx状态 systemctl status nginx # 查看端口监听 ss -lntp | grep -E ':80|:8000' 8.2 常见问题现象可能原因处理方法浏览器无法访问安全组未开放80、Nginx未启动检查安全组、systemctl status nginx502 Bad GatewayFastAPI进程未启动systemctl status stock-predict,查看日志K线数据只到2025年底腾讯财经API不可用检查网络,回退到本地CSV数据ML预测值异常特征未归一化检查scaler_*.json文件是否存在美股K线数据较旧美股在线API受限美股使用本地历史数据(截至2023-12-29)九、案例验收清单[✅️] 使用华为云码道(CodeArts)代码智能体完成需求梳理、架构设计和代码开发;[✅️] ECS、EIP和安全组配置完成;[✅️] FastAPI后端在Systemd中正常运行,Nginx为active;[✅️] 浏览器可通过ECS公网IP打开首页;[✅️] A股股票搜索和K线图可正常显示(含最新交易日数据);[✅️] 规则引擎四维/五维打分可产出方向、概率、交易计划和风险提示;[✅️] ML模型5模型集成推理可正常输出,投票共识可显示;[✅️] 双引擎对比可展示共振/对冲/弱信号判定;[✅️] 预测报告可生成并展示Markdown内容(含术语解释);[✅️] 预测结果包含免责声明,概率上限为65%。
  • [高校训练营] 码道搭建植物养护交流平台(PlantCareHub)
    一、概述1.1 案例介绍项目背景:随着城市生活节奏加快和人们对生活品质的追求,室内绿植养护已成为都市人群的热门生活方式。然而,大量植物爱好者因缺乏专业知识导致养护失败,同时缺少有效的交流渠道分享经验和解决问题。PlantCareHub 应运而生,旨在打造一个集 AI智能诊断、植物百科知识库、个性化养护日志、爱好者社区于一体的综合平台。核心价值: 降低养护门槛:通过 AI 顾问提供零门槛的专业养护指导知识系统化:500+ 植物百科,结构化知识体系养护可视化:时间轴记录植物成长,数据驱动养护决策社交化学习:连接同好,经验共享,共同成长技术定位:采用 Vue 3 + TypeScript + Vite + Pinia 现代前端技术栈,构建高性能、类型安全、可维护的 SPA 应用。初期采用纯前端 + LocalStorage 方案快速验证,为后续云端化预留扩展接口。案例技术选型:华为云码道(CodeArts)代码智能体是基于智能生成、智能问答两大核心能力构建起一套全方位、多层次的智能开发体系。在智能生成方面,它能够依据开发者输入的需求描述,准确且高效地生成高质量代码;智能问答功能则如同开发者身边的专属技术顾问。1.2 适用对象个人开发者高校学生企业开发者1.3 案例时间本案例总时长预计60分钟。1.4 案例流程  说明:本地安装华为云码道(CodeArts)代码智能体;通过码道规范驱动模式开发多体系人格测试应用。1.5 资源总览本案例预计花费0元。资源名称规格单价(元)华为云码道(CodeArts)代码智能体体验版免费二、基础环境与资源准备2.1 华为云码道安装部署本案例基于华为云码道代码智能体完成开发改造,案例开始前请按照以下两步操作开通并使用工具:2.1.1 一键开通华为云码道体验版访问此专属开通链接,免费开通华为云码道(CodeArts)代码智能体体验版,无需复杂配置:一键开通华为云码道体验版!2.1.2 AI IDE华为云码道安装部署参考案例《AI IDE华为云码道(CodeArts)代码智能体安装部署》完成Windows版AI IDE华为云码道(CodeArts)代码智能体安装部署。  三、通过码道分阶段搭建植物养护交流平台3.1 通过规范驱动模式创建需求文档首先我们进入AI IDE后点击码道对话框的 规范驱动模式(Spec-Driven Mode) :根据 需求规格设计->实现方案创建->编码任务规划->任务执行 进行项目开发。  3.1.1 需求规格设计接着我们在码道对话框输入以下提示词,让码道进行需求规格说明书的创建。 c复制代码帮我在当前目录生成一个web应用项目;项目名称:植物养护交流平台(PlantCareHub)技术栈:Vue 3 + TypeScript + Vite + Pinia + Vue Router + SCSS核心功能:  1. AI植物养护顾问:集成智能问答系统,用户可通过文字描述或上传图片获取植物的光照需求、浇水频率(区分四季)、土壤选择、施肥周期、病虫害防治等专业养护建议。支持基于用户所在城市实时天气数据动态调整养护日历,生成月度养护计划(含浇水、施肥、修剪时间节点及异常预警)  2. 植物百科大全:提供500+种常见植物的详细知识库,包含植物名称(中英对照)、科属分类、形态特征、生长习性、养护难度等级、观赏价值、适宜环境参数(光照/温度/湿度/土壤pH值)、常见病害及防治方法。支持按名称/科属/养护难度/光照需求等多维度筛选与模糊搜索  3. 植物养护日志:用户可为每盆植物创建独立档案(含品种名称、种植日期、生长阶段、摆放位置),记录每次浇水/施肥/换盆/修剪等操作行为及时间,支持上传生长对比照片,以时间轴可视化展示植物成长历程。系统根据操作记录自动生成养护统计报表(月浇水次数、施肥频率等)  4. 社区交流互动:搭建植物爱好者互动社区,支持发帖(图文)、提问求助、经验分享、植物展示等。帖子需按主题分类(如多肉专区、月季栽培、病虫害求助、园艺DIY等),支持点赞、评论、收藏、举报。系统自动检测敏感词并触发审核流程。用户可互相关注、私信交流,基于LBS推荐同城花友和线下活动信息 5. 用户个人中心:包含我的植物园(管理所有养护日志)、我的帖子/评论、收藏夹、消息通知、成就徽章系统(根据养护记录天数/发帖活跃度等维度自动授予)、个人资料设置此时,码道会根据步骤首先创建需求规格说明书。    这时如果我们对项目有要求,可以对spec.md需求规格说明书文件进行编辑。保存过后,我们点击码道对话框的开始实现方案创建。3.1.2 实现方案设计可以看到,码道正在根据我们给出的需求规格文档设计实现方案文档。在创建完成后,我们可以在左侧找到 design.md实现方案设计文档进行查看,如果有需要调整的地方可以直接进行修改,无问题后点击 全部接受-> 开始编码任务。    3.1.3 编码任务规划在实现方案设计书创建完成后,我们可以在左侧找到 tasks.md编码任务文档进行查看,如果有需要调整的地方可以直接进行修改,无问题后点击 全部接受-> 开始任务执行。生成完毕后我们可以看到相应的任务执行顺序。   3.1.4 任务执行这时我们可以任意的去修改需求规格设计、实现方案创建、编码任务规划,在以上设计书都完成的前提下,我们可以根据码道提示进行编码任务。可以看到,码道正在进行编码任务。  当编码任务全部完成后,我们可以点开左侧文件进行查看,如无问题,在码道对话框点击 全部接受。四、启动项目并反馈可能出现的问题在编码任务完成后,我们可以根据启动说明或在码道对话框输入以下提示词启动项目: c复制代码启动项目此时码道会提示我们如何启动,根据指引进行项目启动即可。注意:在启动项目中或项目运行中可能会出现一些错误,遇到问题的时候我们通过自然语言描述,或者截图的方式把错误直接反馈给码道,让码道帮我们解决就可以了。当我们成功启动后可以看到刚刚创建好的应用了!为这个植物养护交流平台是Agent自动生成的,每次提问设计生成的代码及最后的运行结果均存在出入,开发者可根据自己的需求,逐步给智能体发送Prompt进行微调直到生成自己想要的结果。若想体验与案例一样的结果,请下载源码(https://github.com/YL12345678901/plantcarehub)至本地运行。演示视频也在仓库中,可供参考。五、反馈改进建议如您在案例实操过程中遇到问题或有改进建议,可以到开发者论坛评论区反馈即可,我们会及时响应处理,谢谢! 
  • [高校训练营] 基于华为云码道(CodeArts)的羽毛球协会管理系统
    本案例将引导构建一个完整的“大黑山羽毛球运动协会管理系统”。该系统旨在解决协会日常运营中的核心痛点,包括9片场地的管理与预定、50名选手的信息维护以及羽毛球比赛的智能排程与成绩统计。
  • [高校训练营] 基于华为云码道(CodeArts)的碳足迹与生命周期评价智能系统
    基于华为云码道(CodeArts)的碳足迹与生命周期评价智能系统一、概述1.1 案例介绍碳足迹核算与生命周期评价(LCA)是量化产品全生命周期环境负荷、支撑绿色低碳转型的核心方法。传统工具往往存在清单提取低效、专业门槛高、结果难落地等问题。本案例基于华为云码道(CodeArts) AI 代码智能体,采用 SDD 规格驱动 + Vibe-Coding 开发范式,从零构建一套碳足迹与生命周期评价系统,并以水泥生产为典型行业示例进行落地演示(如“两磨一烧”工艺边界、清单阶段与 IEII 核算参数)。系统采用前后端分离架构(Flask + Vue3),内置 IEII(综合环境负荷指数)核算引擎,支持异构清单文档的大模型智能解析,并通过 LangGraph Agent 实现自然语言驱动的全流程任务调度。完整源码与演示视频见 GitCode 仓库:cid:link_4。1.2 适用对象工业界环境相关从业者(碳足迹核算、LCA 评价、绿色低碳管理等)高校学生( AI 开发实训)1.3 案例时间直接使用仓库源码:完成资源准备、部署和功能验证,预计需要 60~90 分钟。通过码道手动复现:从 SDD 规格驱动到分阶段 Vibe-Coding 完整走通,预计需要 4~5 小时。1.4 案例流程 前期准备(环境 + 码道 + 大模型 API) ↓ 需求分析 / Skill 规格文档(spec / design / tasks) ↓ 基于码道智能体生成后端(认证、清单解析、LCA 计算等) ↓ 基于码道智能体生成前端及页面美化 ↓ LangGraph Agent:自然语言驱动全流程任务调度说明:前期准备:配置大模型 API Key,准备 PostgreSQL、Python、Node.js 等运行环境;登录华为开发者空间,创建云开发环境,安装并进入码道(CodeArts)AI IDE 的 Vibe-Coding 模式;需求分析 / Skill 文档:使用码道官方 SDD 系列 Skill(如 creating-sdd-directory、managing-spec-document、managing-design-document、managing-tasks-document),完成需求规格、总体设计与任务分解文档;基于智能体生成后端:按业务模块向码道输入 Prompt,分阶段生成认证、LCA 核算、清单智能解析、参数配置等后端能力;基于智能体生成前端及美化:使用码道智能体(可结合 frontend-design Skill)生成项目管理、清单录入、影响评价、对比分析等页面,并完成界面美化与交互打磨;LangGraph Agent 全流程调度:封装建项、清单解析、IEII 计算等工具,通过自然语言对话驱动 LCA 端到端任务链式执行,降低专业操作门槛。1.5 资源总览资源名称规格说明费用参考华为云码道(CodeArts)代码智能体专业版(含 6000 万 Token/月/席位)139 元/月/席位华为云 MaaS 大模型服务 API通过华为云 ModelArts Studio(MaaS)调用 LLM,用于清单解析与 Agent 推理按实际 Token 用量计费(可领取免费额度或使用包月套餐)PostgreSQL 数据库自建,存储项目与清单数据免费说明:码道通用体验版可免费使用,但每月仅 500 万 Token 额度,建议按需升级专业版以保证开发体验。LLM API 推荐使用华为云 MaaS 领取的模型服务(如 DeepSeek、GLM 等),或按实际环境配置可用的 API Key / 模型名称 / 接口地址。PostgreSQL 可在开发环境中直接自建,无需额外付费。二、环境和资源准备2.1 准备华为云码道(CodeArts)AI IDE登录华为开发者空间,进入码道(CodeArts)产品页,开通代码智能体(专业版)服务,获取在线代码生成与迭代能力。参考案例《AI IDE华为云码道(CodeArts)代码智能体安装部署》,完成 Windows 版华为云码道(CodeArts)代码智能体 AI IDE 安装部署,进入码道代码智能体。2.2 领取华为云 MaaS 平台大模型 Tokens登录华为开发者空间,参考案例《华为云MaaS平台大模型Tokens领取使用指导》中的“二、领取 MaaS 平台大模型 Tokens”章节内容,领取 Tokens 代金券并开通模型服务,获取 API 地址、模型名称和 API Key。将获取到的密钥写入后续 backend/.env。2.3 准备本地 / 云开发基础软件本案例技术栈如下:类别选型前端Vue 3 + Vite + ECharts + Vue Router后端Flask 3 + Flask-SQLAlchemy + Flask-CORS数据库PostgreSQL认证JWT + bcrypt + RBAC(admin / normal)AgentLangChain StructuredTool + LangGraph 状态编排大模型通义千问等(DashScope / 华为云 MaaS 兼容接入)文档解析openpyxl / pandas / python-docx / PyMuPDF 等请确保环境满足:Python 3.10+Node.js 18+PostgreSQL 14.2(创建数据库 lca)Redis,用于 Agent 对话检查点持久化;不可用时可降级为内存模式也可在码道中使用 dev-env-setup 专业技能一键安装 Python / Node.js 并校验版本:使用 dev-env-setup 专业技能搭建本地开发环境,安装 Python 3.10+、Node.js 18+、pip 包管理器,配置环境变量并输出版本验证结果。三、基于码道的 AI 开发过程本章聚焦本项目的 AI Coding 开发过程:先明确业务场景与需求边界,再用码道官方 Skill 完成 SDD 规格设计,最后按业务阶段用 Prompt / Vibe-Coding 生成前后端代码。3.1 业务场景与需求概要3.1.1 业务场景与用户角色本平台面向碳足迹与生命周期评价业务,支撑从数据录入、核算执行到结果分析、Agent 辅助调度的端到端工作流;演示数据与工艺边界以水泥“两磨一烧”为例。基于业务权限与操作职责,系统划分为两类核心角色——普通用户与系统管理员。管理员默认继承普通用户的全部业务操作权限,并在系统运维与参数配置层面扩展能力:维度普通用户系统管理员权限范围与功能边界聚焦 LCA 核心业务流:(1)项目全流程管理:创建项目、界定系统边界、录入/解析清单数据、IEII 核算、结果对比;(2)AI 助手对话:通过多轮交互调用 Agent 完成文件上传、数据提取、计算调度等自动化任务继承普通用户全部权限,并扩展:(1)用户管理:角色权限分配、操作日志监控;(2)核算参数配置:物质当量系数、环境类别权重、生产步骤与折算比矩阵等 IEII 基准数据典型使用场景企业环境评估人员执行日常 LCA 评价、工艺数据填报、核算结果分析平台运维人员或领域专家进行底层参数配置、系统配置优化及数据权限管控上述角色通过统一鉴权实现数据视图隔离:普通用户仅可访问本人创建的项目与对话历史;管理员具备全局配置权限,但不可越权修改他人业务数据。3.1.2 功能性需求(1)用户认证与权限管理:支持邮箱密码注册与验证码快捷登录;采用 JWT 无状态会话(有效期 24 小时);基于 RBAC 区分普通用户与管理员的数据视图与操作边界。(2)LCA 项目全生命周期管理:遵循“项目建档 → 目标与范围界定 → 清单录入 → 执行计算 → 结果分析/对比”流程。范围界定支持水泥品种、基准年、工艺路线、系统边界及评价指标的结构化配置;清单录入依据系统边界动态生成各阶段产出/消耗/排放填报;内置 IEII 引擎,仅对用户勾选指标执行特征化、归一化与加权求和,并支持项目快速复制。(3)大模型辅助清单解析:支持 PDF/Excel/Word 等异构文档上传后由大模型抽取结构化清单,前端预览确认后再入库。(4)Agent 交互与任务调度:基于 LangGraph 状态机实现多轮对话智能体;封装清单解析、项目创建、IEII 计算等工具,完成多步链式编排;可用 Redis 持久化对话记忆;强制结构化响应协议(消息/表格等 blocks),保证前端稳定渲染。(5)系统后台管理:管理员可管理用户账号(查看、禁用等),并动态维护环境类别权重、物质当量系数、生产步骤及折算比矩阵。3.2 使用码道完成 SDD 规格驱动设计本案例强调“先设计、后开发”。请在码道对话框中依次执行以下指令,生成 SDD 文档(生成结果可参考仓库中 .codeartsdoer/specs/lca_system/)。3.2.1 初始化 SDD 目录使用 creating-sdd-directory 技能,基于以下需求创建 SDD 项目目录:基于华为云码道的碳足迹与生命周期评价系统(以水泥生产为示例场景),后端 Flask + PostgreSQL,前端 Vue3 + Vite + ECharts,包含 LCA 核算与评估模块、智能体交互与编排模块、系统运维与参数配置模块。生成后的典型目录:.codeartsdoer/specs/lca_system/ ├── spec.md # 需求规格说明书 ├── design.md # 总设计文档 └── tasks.md # 开发任务分解清单 3.2.2 生成需求规格(spec.md)使用 managing-spec-document 技能,为碳足迹与生命周期评价系统生成 spec.md,核心需求包括:用户认证与权限管理(JWT + RBAC,admin/normal 两级角色)LCA 项目全生命周期管理(项目建档→范围界定→清单录入→IEII 计算→结果对比)大模型辅助异构文档智能解析(PDF/Excel/Word→结构化清单)智能体 Agent 对话交互(LangGraph 工具编排,自然语言驱动任务调度)系统参数配置(环境类型权重、物质当量系数、生产步骤与折算比)生成完成后,在码道中打开 .codeartsdoer/specs/lca_system/spec.md,界面示例如下:3.2.3 生成总体设计(design.md)使用 managing-design-document 技能,基于 spec.md 生成 design.md,包含:前后端分离分层架构(表现层 / 业务逻辑层 / 数据访问层 / 外部集成层)PostgreSQL 数据模型(Users、UserLog、UploadedFile、Project、Step2Record、Step3Record、LcaResult、CategoriesWeight、MaterialsWeight、ProductionStep、ConversionRatio、Conversation 等)RESTful API 设计(/auth/、/lca/、/api/agent/、/api/file/、/api/lca-params/、/user/、/admin/)IEII 计算引擎(特征化→归一化→加权求和)Agent 工具编排(StructuredTool + LangGraph 状态机)生成完成后,打开 design.md,界面示例如下:3.2.4 生成任务分解(tasks.md)使用 managing-tasks-document 技能,基于 design.md 生成 tasks.md,按开发阶段拆解任务,标注优先级(P0 核心 / P1 扩展)和依赖关系。生成完成后,打开 tasks.md,界面示例如下:3.3 使用码道分阶段 Vibe-Coding 开发以下 Prompt 可直接输入码道,按阶段生成代码。实际仓库已按该路径落地,可对照验证或在空白工程中复现。3.3.1 阶段一:项目骨架与认证(后端起步)使用 Flask + Vue3 搭建碳足迹与生命周期评价系统,并以水泥生产为示例业务场景。后端 Flask + SQLAlchemy + PostgreSQL,前端 Vue3 + Vite + ECharts。要求:后端结构:app.py、config.py、models.py;按功能域划分 auth/、calculate/、agent/、file/、user/、lca_params/;定义 Users、UserLog、UploadedFile、Project、Step2Record、Step3Record、LcaResult、CategoriesWeight、MaterialsWeight、ProductionStep、ConversionRatio、Conversation 等 ORM 模型;前端侧边栏导航 + 路由守卫(登录 / 管理员权限);JWT 认证:邮箱密码注册登录、验证码登录、退出,Token 有效期 24 小时;CORS 允许前端 localhost:5173 访问后端 localhost:5000。3.3.2 阶段二:用户管理与个人中心实现 RBAC 用户管理、操作日志审计、个人中心:管理员用户列表(分页/搜索/筛选)、启用禁用与权限变更、日志查询导出;个人中心支持资料编辑、改密、头像上传;SMTP 发送 6 位验证码(5 分钟有效);写操作写入 UserLog。3.3.3 阶段三:LCA 核算主流程(ISO 14040/44)以水泥生产为示例,实现 LCA 四阶段流程(示例工艺可按“两磨一烧”配置系统边界与生产步骤):Step1 项目管理(创建/编辑/删除/复制,状态:空项目→范围界定→清单录入→已计算);Step2 研究目标与范围(以水泥为例:品种规格、基准年、工艺、系统边界、评价指标 ADP/GWP/AP/HTP/POCP/EP/LU);Step3 清单录入(按阶段维护产出/消耗/排放 JSON);Step4 IEII 计算:产出量倒推 → 单位强度 → 特征化 → 归一化 → 加权求和;电力按 0.5703 kg CO₂/kWh 折算;仅计算用户勾选指标。3.3.4 阶段四:大模型清单智能解析支持 PDF/Excel/Word/CSV/图片上传;调用大模型按阶段解析产出/消耗/排放并返回结构化 JSON;前端先预览可编辑,用户确认后再写入 Step3;文件状态 uploaded→parsed→stored。3.3.5 阶段五:Agent 智能助手基于 LangGraph 实现 LCA Agent:对话 CRUD;工具包括 upload_file、create_lca_project、list_lca_projects、parse_inventory_file_for_project、calculate_lca_for_project;结构化响应协议(blocks 消息块/表格块等);前端对话页解析 blocks 渲染。3.3.6 阶段六:前端生成、美化与对比分析使用 frontend-design 技能生成/优化项目管理、清单录入、影响评价、对比分析等页面;管理员维护环境类型权重与物质当量系数(ECharts 可视化);使用 data-analysis 技能,以水泥示例数据校验关键阶段(如熟料煅烧)IEII 是否显著偏高、GWP 占比是否符合行业经验。本项目 AI 开发过程中使用的码道 Skill :阶段Skill作用设计creating-sdd-directory初始化 SDD 目录设计managing-spec-document生成 spec.md设计managing-design-document生成 design.md设计managing-tasks-document生成 tasks.md前端frontend-design生成对比分析、影响评价等高质页面验证data-analysis分析校验 LCA 计算结果四、项目结构与关键代码解析本章说明码道生成后的工程结构,并对认证、IEII 计算、清单解析、Agent 编排等关键能力给出源码 + 分析。4.1 项目结构说明CemLCA/ ├── backend/ # Flask 后端 │ ├── app.py # 入口与 Blueprint 注册 │ ├── config.py # 数据库 / JWT / 邮件 / 模型密钥配置 │ ├── models.py # SQLAlchemy ORM 模型 │ ├── requirements.txt │ ├── auth/ # 认证(注册/登录/验证码) │ ├── calculate/ # LCA 项目、Step2/3、IEII 计算、清单解析 │ ├── agent/ # Agent 对话、工具编排 │ ├── file/ # 文件上传与管理 │ ├── user/ # 个人中心 / 管理员接口 │ ├── lca_params/ # IEII 参数配置 API │ └── utils/ # Token、邮件、响应封装、LLM 工具等 ├── frontend/ # Vue3 前端 │ ├── package.json │ └── src/ │ ├── views/ │ │ ├── lca/ # 项目管理 / 清单 / 影响评价 / 对比 │ │ ├── agent/ # Agent 对话页 │ │ ├── system/ # 用户管理 / 参数配置 │ │ └── user/ # 登录注册 │ ├── components/ # Sidebar 等 │ ├── router/index.js │ └── services/api.js ├── .codeartsdoer/specs/lca_system/ # 码道 SDD 规格文档 ├── chatfile/ # Agent 上传文件目录 └── README.md4.2 关键代码讲解4.2.1 后端入口与模块注册backend/app.py 优先加载 .env,再注册各业务 Blueprint,并在启动时建表、开启 CORS:# backend/app.py(节选) app = Flask(__name__) app.config.from_object(config) app.register_blueprint(auth_bp, url_prefix='/auth') app.register_blueprint(calculate_route) app.register_blueprint(agent_route) app.register_blueprint(file_route) app.register_blueprint(admin_bp) app.register_blueprint(user_bp) app.register_blueprint(lca_params_route) db.init_app(app) with app.app_context(): db.create_all() CORS(app, resources={r"/*": {"origins": ["http://localhost:5173", "http://127.0.0.1:5173"]}}) 分析:按功能域拆 Blueprint,便于码道按模块增量生成;calculate 与 agent 解耦后,同一套 IEII / 清单解析逻辑既可被页面调用,也可被 Agent 工具复用。4.2.2 核心数据模型与 PostgreSQL 存储PostgreSQL 作为核心关系型存储底座,集中管理用户档案、项目元数据、LCA 核算基准参数与评价结果等强事务型业务数据。数据访问层基于 Flask-SQLAlchemy ORM 实现标准化访问;概念设计遵循第三范式,按业务域划分实体,依托主外键约束保障一致性。LCA 核算与评估模块的核心数据表如下:表名表用途projects项目主表,项目归属与进度追踪容器,含用户隔离、示例项目标识等step2_record研究目标与范围表,存储水泥品种、基准年、系统边界和评价指标等元数据step3_record生命周期清单表,以 JSON 结构存储各生产阶段的产出、消耗和排放数据lca_result计算结果表,每条记录对应一个阶段×一种产品,存储单位强度、IEII 与指标分解production_steps生产步骤配置表,定义工艺步骤名称、顺序、默认产出物和启用状态conversion_ratios产出物折算比表,供逆向倒推各步真实产出量materials_weight物质当量系数表,存储各物质在七个环境类别下的特征化系数categories_weight环境影响类型权重表,含 IEII 加权系数和归一化基准系统逻辑数据模型图(ER / 表关系)如下:核心业务表示例如下:# backend/models.py(节选) class Project(db.Model): __tablename__ = "projects" id = db.Column(db.Integer, primary_key=True, autoincrement=True) user_email = db.Column(db.String(50), db.ForeignKey("users.email", ondelete="SET NULL")) name = db.Column(db.String(100), nullable=False) type = db.Column(db.String(50), nullable=True) intro = db.Column(db.Text, nullable=True) is_example = db.Column(db.Boolean, nullable=False, server_default=text("false")) class Step2Record(db.Model): __tablename__ = "step2_record" project_id = db.Column(db.Integer, db.ForeignKey("projects.id", ondelete="CASCADE"), unique=True) cement_spec = db.Column(db.String(100), nullable=True) system_border = db.Column(db.JSON, nullable=True) # 系统边界多选 appraise_index = db.Column(db.JSON, nullable=True) # 评价指标多选 class Step3Record(db.Model): __tablename__ = "step3_record" project_id = db.Column(db.Integer, db.ForeignKey("projects.id", ondelete="CASCADE"), unique=True) phases = db.Column(db.JSON, nullable=True) # 各阶段产出/消耗/排放 分析:Step2/Step3 与 Project 一对一,删除项目时级联清理;phases 用 JSON 承载多阶段异构清单,适配水泥示例中可变系统边界,也方便大模型解析结果整包写入。4.2.3 JWT 登录认证# backend/auth/view.py(节选) @auth_bp.route('/login', methods=['POST']) def login(): data = request.get_json(silent=True) or {} email = data.get('email', '').strip() password = data.get('password', '') res = PgSQL.hasUser(email, password) if res.status != 200 or not res.data: record_log(email=email, operation=LOGIN, detail="登录失败:邮箱或密码不正确", result="failure") return jsonify(Error(message='邮箱或密码不正确').to_dict()), 401 user_data = PgSQL.getUserByEmail(email).data if user_data.get('state') == UserState.disabled.value: return jsonify(Warn(message='您的账号被禁用,请联系管理员开放后重试').to_dict()), 403 auth = user_data.get('auth') or 'normal' if hasattr(auth, 'value'): auth = auth.value token = Token.generate_auth_token(user_data.get('id'), user_email=email, auth=auth) return jsonify(Success(data={ 'token': token, 'user_id': user_data.get('id'), 'username': user_data.get('name'), 'email': email, 'auth': auth, }, message='登录成功!').to_dict()) 分析:登录成功后签发 JWT,payload 携带 user_id 与 auth,支撑后续 @token_required / @admin_required;失败与成功均写 UserLog,满足运维审计需求。4.2.4 IEII 计算引擎(特征化 → 归一化 → 加权)计算主逻辑在 backend/calculate/calculate_service.py,同时被 Flask 路由与 Agent 工具复用。LCA 评价过程与计算链路如下:整体遵循:产出量倒推 → 单位强度 → 特征化 → 归一化 → 加权求和 → 写入 LcaResult(1)产出量倒推:默认末步产出 1 t,按折算比矩阵由后向前倒推。以水泥三阶段为例:水泥制备 1 t → 熟料煅烧约 0.726 t → 生料粉磨约 1.118 t(前一步骤产出 = 后一步骤产出 × 折算比)。(2)单位强度:消耗/排放总量 ÷ 该步真实产出量,得到每功能单位强度;电力按 0.5703 kg CO₂/kWh 折算为 CO₂;石油类燃料可将运输距离纳入修正。(3)特征化 / 归一化 / 加权:# backend/calculate/calculate_service.py(节选:归一化 + 加权) normalized_impacts = {} for category in impacts.keys(): category_data = next( (cw for cw in category_weights if cw.get("category_name") == category), None, ) total_equivalent = category_data.get("total_equivalent") if category_data else 0.0 normalized_impacts[category] = ( impacts[category] / total_equivalent if total_equivalent else 0.0 ) weighted_sum = 0.0 for category, value in normalized_impacts.items(): category_weight = next( (cw.get("weight", 0.0) for cw in category_weights if cw.get("category_name") == category), 0.0, ) weighted_sum += value * category_weight ieii = weighted_sum # 单位强度 IEII ieii_total = weighted_sum * actual_product_amount # 总 IEII 分析:特征化把异构清单统一到七类环境影响(ADP/GWP/AP/HTP/POCP/EP/LU);归一化消除量纲差异;加权得到可横向对比的单一指数。仅 Step2 勾选的指标子集参与全过程,保证闭运算。4.2.5 大模型清单智能解析# backend/calculate/inventory_extract.py(节选) def extract_inventory_json_from_file(file_path: str, api_key: Optional[str] = None) -> dict: api_key = api_key or os.getenv("API_KEY") if not api_key: raise ValueError("未配置 API_KEY,无法解析文件") client = OpenAI( api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", timeout=180.0, ) file_object = client.files.create(file=path.open("rb"), purpose="file-extract") completion = client.chat.completions.create( model="qwen-long-2025-01-25", messages=[ {"role": "system", "content": _inventory_schema_prompt()}, {"role": "system", "content": f"fileid://{file_object.id}"}, {"role": "user", "content": "请根据上述要求,从文件中提取各阶段的产出、消耗与排放,只输出 JSON。"}, ], temperature=0, stream=True, ) full_content = "" for chunk in completion: if chunk.choices and chunk.choices[0].delta.content: full_content += chunk.choices[0].delta.content or "" return _parse_json_from_llm(full_content) 分析:通过兼容 OpenAI 的接口上传文件,并用 Schema Prompt 约束输出结构;temperature=0 降低随机性。业务上采用「解析预览 → 用户确认 → 写入 Step3」两阶段,避免 LLM 偶发误差直接污染正式清单。文件解析提取与处理流程如下:4.2.6 Agent 工具编排与运行Agent 采用工具驱动架构:不自行“编造”业务结果,而是理解意图后调用专项工具,再聚合为结构化 blocks 返回。执行流程架构如下:设计要点:领域专业化:系统提示词限定能力边界(LCA 建项 / 解析 / 计算),降低幻觉;工具编排:经 LangGraph create_agent 注册 StructuredTool,由模型决定调用顺序与参数;结构化响应:强制 ResponseFormat,前端按 message / table 等块类型渲染;状态化对话:优先 Redis Checkpoint,失败则降级内存,维持多轮上下文。当前注册的核心工具:工具名称功能描述upload_file上传文件并返回服务器路径create_lca_project新建 LCA 项目list_lca_projects列出当前用户可见项目parse_inventory_file_for_project解析清单并写入指定项目 Step3calculate_lca_for_project执行 IEII 计算并返回结果摘要工具注册(backend/agent/tools.py):# backend/agent/tools.py(节选) calculate_lca_for_project = StructuredTool.from_function( func=_calculate_lca_for_project, name="calculate_lca_for_project", description="""执行指定项目的 LCA 计算(复用系统已实现的 IEII 计算算法)...""", parameters={ "type": "object", "properties": { "project_id": {"type": "integer", "description": "项目管理中的整数项目 ID"} }, "required": ["project_id"], }, ) def get_tools(context: Context) -> list: global _ctx _ctx = context return [ upload_file, create_lca_project, list_lca_projects, parse_inventory_file_for_project, calculate_lca_for_project, ] Agent 运行(backend/agent/agent.py):# backend/agent/agent.py(节选) def run_agent(message: str, user_id: int = 1, thread_id: str = None, is_first_message: bool = False): config = {"configurable": {"thread_id": thread_id or f"user_{user_id}"}} ctx = Context(user_id=user_id) with get_checkpointer() as checkpointer: agent = create_agent( model=get_llm(), system_prompt=SYSTEM_PROMPT, tools=get_tools(ctx), checkpointer=checkpointer, response_format=ResponseFormat, # 强制结构化 blocks 输出 ) result = agent.invoke( {"messages": [{"role": "user", "content": message}]}, config=config, ) final_response = _parse_structured_response(result.get("messages", []), invoke_result=result) return {"messages": result.get("messages", []), "response": final_response, ...} 结构化响应块常用类型:类型主要字段用途messagecontent, style(default/success/warning/error)带样式的文本提示tableheader, rows, title, actions表格与操作按钮filefile_id, file_name, file_path文件信息展示cardtitle, content, actions复杂信息容器分析:这是本案例亮点——自然语言驱动“上传 → 建项 → 解析 → 计算”链式任务。4.2.7 前端路由守卫// frontend/src/router/index.js(节选) router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') const userAuth = localStorage.getItem('auth') if (to.meta.requiresAuth && !token) { loginPromptEmitter.emit(to.fullPath) return } if (to.meta.requiresAdmin && userAuth !== 'admin') { next('/lca/projects') return } next() }) 分析:LCA 业务页与 Agent 页设置 requiresAuth;用户管理、参数配置另加 requiresAdmin,与后端 RBAC 前后端双重校验。五、配置运行与系统功能演示本章完成环境配置与前后端启动,并按业务模块讲解系统功能。5.1 配置环境并运行调试5.1.1 配置后端cd backend python -m venv venv # Windows PowerShell .\venv\Scripts\activate # Linux / macOS # source venv/bin/activate pip install -r requirements.txt1)在 PostgreSQL 中创建数据库:CREATE DATABASE "Cemlca"; 2)复制并编辑环境变量文件:cp .env.example .env在 .env 中配置:API_KEY=你的大模型API密钥3)按实际环境修改 backend/config.py 中的数据库连接,例如:SQLALCHEMY_DATABASE_URI = "postgresql://用户名:密码@127.0.0.1:5432/Cemlca" 4)启动后端:python app.py默认监听:http://127.0.0.1:5000。可用 curl 验证:curl http://127.0.0.1:5000/api/ping期望返回:{"message": "Flask 后端已就绪", "status": "ok"} 5.1.2 配置前端cd frontend npm install npm run dev默认访问:http://localhost:5173。5.2 LCA 核算与评估功能演示LCA 核算与评估是系统核心业务,按四步推进:步骤名称说明Step1项目创建建立评价项目,记录名称、类型、简介,作为后续数据归属容器Step2研究目标与范围确定水泥品种、基准年、工艺、系统边界、评价指标Step3生命周期清单按阶段录入产出/消耗/排放;支持手工录入与大模型解析Step4影响评价计算执行特征化→归一化→加权,得到各阶段 IEII 与指标分解完成后可进行结果对比分析。5.2.1 登录与注册打开前端地址,完成注册或登录(支持邮箱密码 / 验证码登录)。登录成功后 Token 存于本地,后续请求自动携带。5.2.2 项目管理(Step1)进入 项目管理 页:列表默认展示当前用户项目;支持卡片 / 列表两种视图;每个项目显示四节点进度条(创建→范围→清单→计算),已完成节点显示 √,当前节点高亮,未到达节点灰色不可点;状态逻辑简述:step2 必填齐全 → phases 非空 → 存在 LcaResult,据此映射进度 1~4;新建项目:名称为必填,同一用户下不可重名;创建后为空项目状态;复制项目:可复制基本信息,可选复制 Step2/Step3,不复制计算结果;普通用户仅可操作本人项目与示例项目;示例项目禁止写操作。5.2.3 研究目标与范围(Step2)在进度条进入 Step2,填写:水泥品种、基准年、生产工艺、系统边界(多选)、评价指标(多选)。系统边界选项来自生产步骤配置;评价指标来自环境类型权重表(七项:ADP/GWP/AP/HTP/POCP/EP/LU)。仅勾选指标参与后续 IEII 计算。保存采用 upsert。5.2.4 生命周期清单录入(Step3)按 Step2 系统边界动态生成阶段分组;每组含产出表、消耗表、排放表,支持行内增删。两种录入方式:手工录入:编辑后保存,JSON 写入 step3_record.phases;大模型辅助解析:上传 PDF/Excel/Word/CSV/图片 → 大模型按 Schema 抽取 → 前端预览可改 → 确认后入库(两阶段设计,避免脏数据)。5.2.5 影响评价计算(Step4)点击执行计算后,后端完成倒推产出量、单位强度、特征化、归一化与加权,结果写入 lca_result。前端影响评价页:表格按阶段×产品展示 IEII 与七项指标分解,可筛选;ECharts 柱状图对比各阶段 IEII;堆叠柱状图展示指标贡献占比。5.2.6 结果对比分析对已完成计算的项目,可从按生产步骤、按产品等维度查看 IEII 与七项指标对比:按步骤 IEII 条形图 / 七项指标分组柱状图;按产品 IEII 饼图与堆叠柱状图;消耗/排放构成分析。5.3 智能体交互功能演示Agent 页采用左侧会话列表 + 右侧对话区。用户可新建/切换/删除会话,发送文本并附带文件;响应按 blocks 渲染消息、表格等。话术示例(可附带清单文件):帮我根据附件创建一个LCA项目,名称叫水泥test1[文件路径:D:\桌面\华为\CemLCA\chatfile\2024.11.xlsx]Agent 依次调用建项、解析、计算等工具,并返回结构化结果(如 LCA 结果明细表格)。5.4 系统运维与参数配置演示5.4.1 用户管理与操作日志(管理员)管理员进入用户管理:分页/搜索/按角色状态筛选;启用禁用;查看并筛选操作日志,可导出。认证为 JWT(24 小时)+ @token_required / @admin_required 栈式叠加。5.4.2 个人中心普通用户可编辑姓名/电话/单位,修改密码(需旧密码),上传/删除头像;查看个人日志与项目统计仪表盘。5.4.3 LCA 计算参数配置(管理员)四类参数可视化维护:参数类型说明前端呈现生产步骤工序名称、顺序、默认产出物、启用状态可排序列表折算比矩阵步骤间物料折算关系热力图等环境类型权重类别权重 + 归一化基准(七类)饼图 / 列表物质当量系数物质在各环境类别下的系数(JSON)科学计数法列表 / 图表5.5 系统能力小结模块能力要点LCA 核算与评估Step1~4 全流程、IEII 自动化计算、结果可视化与对比分析大模型清单解析异构文档 → 结构化清单,预览确认后入库智能体编排自然语言驱动建项、解析、计算等链式任务系统运维JWT+RBAC、操作日志、个人中心、LCA 参数可视化配置六、释放资源6.1 停止本地 / 云开发环境中的服务在运行前后端的终端中按 Ctrl + C 停止进程;如使用 Python 虚拟环境,可 deactivate。6.2 释放云开发环境与按量资源进入华为开发者空间,停止或删除本案例创建的云开发环境容器;若额外购买了 ECS、EIP、CCE 等按量资源,进入对应控制台,勾选实例后执行 更多 > 删除,并勾选释放公网 IP 与数据盘,避免持续计费;大模型 Tokens 套餐按实际剩余额度管理,体验结束可不继续调用推理接口。七、扩展资料说明华为开发者空间主页:cid:link_3华为云码道(CodeArts):https://codearts.huaweicloud.com/华为云 MaaS Tokens 领取指导:《华为云MaaS平台大模型Tokens领取使用指导》LCA 国际标准:ISO 14040 / ISO 14044(生命周期评价原则、框架与要求)Flask 官方文档:https://flask.palletsprojects.com/Vue 3 官方文档:https://vuejs.org/LangGraph 文档:https://langchain-ai.github.io/langgraph/
  • [高校训练营] 基于华为云码道(CodeArts)代码智能体的CloudForum:支持版块级权限与双层内容审核的校园论坛管理系统
    一、项目简介本次实战我使用华为云码道代码智能体完成了 CloudForum 校园论坛管理系统。项目围绕“会员交流、版主自治、平台治理”三个角色展开,不仅实现了登录、发帖、跟帖、删帖、置顶等论坛基础功能,还补充了版块级权限隔离、本地敏感词 DFA、华为云文本内容审核、人工复核、黑名单、软删除恢复和审计日志,形成了可运行、可管理、可追溯的内容治理闭环。代码仓库:CampusCloudForum(GitCode)前端:Vue 3 + TypeScript + Vite + Element Plus + Pinia + Vue Router + Axios后端:Java 17 + Spring Boot 3 + Spring Security + JWT + MyBatis-Plus数据库与运行:MySQL 8 + Docker Compose + NginxCloudForum 首页二、原始任务与完成情况原题为:论坛管理。实现论坛的版主管理、版块管理、内容管理。需要登陆进入论坛,可以发帖、跟帖和删帖以及置顶等功能。同时能够对敏感词汇进行过滤,拉黑某些会员。我将原题拆成了可验收的功能项,并为每项建立“页面操作 + 后端权限 + 自动化测试”的证据闭环:原题要求实现方式对应证据登录进入论坛JWT 无状态认证、BCrypt 密码、注册、退出、修改密码、禁用账号拦截登录页、认证测试版主管理ADMIN 分配或移除版主;MODERATOR 只能管理被分配版块版块管理页、版主范围页、跨版块 403 测试版块管理创建、编辑、启用、停用、排序、版主列表版块管理页、管理接口测试内容管理帖子/回复分页管理、审核、锁定、删除、恢复审核页、帖子管理页、回复管理页发帖登录会员选择版块并发布,发布前完成黑名单和敏感词审核发帖接口与集成测试跟帖帖子详情页回复,锁帖后禁止回复帖子详情页、回复测试删帖作者或对应管理者可删除;默认软删除,可恢复删除/恢复测试、审计日志置顶ADMIN 或对应版主可置顶/取消置顶,置顶内容优先排序帖子管理页、排序测试敏感词过滤DFA 支持 REJECT、REVIEW、REPLACE,词库动态重载敏感词页、审核队列、四类审核测试拉黑会员全局/版块、永久/限时、解除拉黑;发帖和回复前后端拦截黑名单页、拉黑权限与拦截测试三、码道代码智能体开发实录码道项目与原始任务任务规划与阶段拆分Skill / MCP 使用记录自动化验证我还在仓库中沉淀了项目级规则、阶段 Prompt 和专项 Skill,使智能体后续修改都遵循“读代码 → 实现最小闭环 → 测试 → 文档”的流程,减少前后端契约漂移与权限遗漏。四、系统架构与业务闭环整体架构保持前后端分离,本地容器化运行时由 Nginx 提供统一入口:会员 / 版主 / 管理员 │ ▼ Nginx + Vue 3 Web │ RESTful JSON ▼ Spring Security + JWT │ ├── 论坛业务服务 ── MyBatis-Plus ── MySQL 8 ├── 版块级 RBAC ── 403 越权拦截 ├── 本地敏感词 DFA ── PASS / REVIEW / BLOCK ├── 华为云 Moderation SDK ── 异常时安全降级 └── 审计日志 ── 操作者 / 原因 / 前后状态发帖和回复走统一治理链路:提交内容 → 校验是否被全局或当前版块拉黑 → 本地 DFA 过滤(REJECT / REVIEW / REPLACE) → 按配置调用华为云文本内容审核 → 统一得到 PASS / REVIEW / BLOCK → PASS 公开、REVIEW 进入人工队列、BLOCK 拦截 → 云审核异常时降级到本地结果并记录日志这种设计解决了两个真实问题:一是减轻版主逐条审查的压力;二是避免外部审核服务短暂不可用时整个论坛无法发帖。五、逐项功能实现1. 登录进入论坛系统支持注册、登录、退出和修改密码。登录成功后前端携带 JWT 访问需要授权的接口;密码使用 BCrypt 存储。公开浏览与登录后操作边界由 Spring Security 后端统一控制,匿名发帖返回 401,角色越权返回 403。登录页面注册页面关键安全配置使用精确的数字详情路径,避免把 /api/topics/mine 一类私有接口误判成公开接口:.authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/**").permitAll() .requestMatchers("/actuator/health").permitAll() .requestMatchers("/api/boards/all").permitAll() .requestMatchers(new RegexRequestMatcher("^/api/boards/\\d+$", "GET")).permitAll() .requestMatchers(HttpMethod.GET, "/api/topics").permitAll() .requestMatchers(new RegexRequestMatcher("^/api/topics/\\d+$", "GET")).permitAll() .requestMatchers(HttpMethod.GET, "/api/comments").permitAll() .anyRequest().authenticated()) 2. 版主管理管理员可以在版块管理页为每个版块分配或移除版主。后端不只判断用户是不是 MODERATOR,还会继续查询“用户—版块”的关联关系;因此版主即使手工构造请求,也不能管理其他版块。核心权限逻辑如下:public boolean canManageBoard(Long userId, Long boardId) { User user = requireUser(userId); if (user.getRole() == UserRole.ADMIN) return true; if (user.getRole() != UserRole.MODERATOR || boardId == null) return false; return boardModeratorMapper.selectCount( new LambdaQueryWrapper<BoardModerator>() .eq(BoardModerator::getUserId, userId) .eq(BoardModerator::getBoardId, boardId) ) > 0; } public void requireBoardManager(Long userId, Long boardId) { if (!canManageBoard(userId, boardId)) { throw BusinessException.forbidden("无权管理该版块"); } } ADMIN 获得全局管理范围,MODERATOR 只获得被分配的版块 ID,MEMBER 没有后台管理权限。帖子、回复、审核、黑名单和审计列表都复用这套后端判定。3. 版块管理系统实现了版块的创建、编辑、启用、停用、排序和版主配置。停用版块不能继续发帖;公开端和管理端使用不同的数据接口,管理接口通过方法级鉴权限制到 ADMIN 或 MODERATOR,并在服务层进一步做版块范围校验。@PostMapping @PreAuthorize("hasRole('ADMIN')") public ApiResponse<BoardDTO> createBoard( @Valid @RequestBody CreateBoardRequest request, @AuthenticationPrincipal UserPrincipal principal) { return ApiResponse.success(boardService.createBoard(request, principal.getId())); } @PutMapping("/{id}") @PreAuthorize("hasAnyRole('ADMIN','MODERATOR')") public ApiResponse<BoardDTO> updateBoard( @PathVariable Long id, @Valid @RequestBody UpdateBoardRequest request, @AuthenticationPrincipal UserPrincipal principal) { return ApiResponse.success(boardService.updateBoard(id, request, principal.getId())); } 4. 发帖与跟帖登录会员可以选择启用中的版块发布帖子,并在帖子详情页回复。发帖与回复都会先检查黑名单,再进入内容审核。帖子支持点赞、浏览量、回复数和最后活跃时间,回复可选填图片地址;锁帖后不允许继续回复。前端通过类型化 API 调用后端,页面不使用 mock 数据冒充功能:export function createTopic(data: { boardId: number title: string content: string }) { return api.post<any, ApiResponse<TopicInfo>>('/topics', data) } export function createComment(data: { topicId: number content: string imageUrl?: string }) { return api.post<any, ApiResponse<CommentInfo>>('/comments', data) } 公开帖子列表在后端固定过滤为 PUBLISHED + PASS,待审、被拒绝或已删除内容不会因修改前端参数而泄露:wrapper.eq(Topic::getStatus, TopicStatus.PUBLISHED); wrapper.eq(Topic::getReviewStatus, ReviewStatus.PASS); wrapper.orderByDesc(Topic::getIsTop); 5. 删帖、恢复、置顶与锁帖作者可以删除自己的帖子,对应版主和管理员可以执行管理删除。删除不是直接清除数据库记录,而是记录 DELETED、删除人、时间和原因;后续可由合法操作者恢复。置顶、取消置顶、锁定、解锁、删除和恢复都会写入审计日志。软删除和审计的关键实现:public void deleteTopic(Long id, Long operatorId, String reason) { Topic topic = topicMapper.selectById(id); if (topic == null) throw BusinessException.notFound("帖子不存在"); checkOwnerOrManager(topic, operatorId); String before = topic.getStatus().name(); topic.setStatus(TopicStatus.DELETED); topic.setDeletedAt(LocalDateTime.now()); topic.setDeletedBy(operatorId); topic.setDeleteReason(reason); topicMapper.updateById(topic); auditLogService.log(operatorId, AuditAction.TOPIC_DELETED, "TOPIC", id, topic.getBoardId(), reason, before, "DELETED", null, true, null); } 置顶操作先做版块权限校验,再更新状态并记录审计:authorizationService.requireBoardManager(operatorId, topic.getBoardId()); topic.setIsTop(true); topicMapper.updateById(topic); auditLogService.log(operatorId, AuditAction.TOPIC_TOPPED, "TOPIC", id, topic.getBoardId(), reason, "false", "true", null, true, null); 6. 内容管理与人工复核管理端提供帖子管理、回复管理和内容审核队列。REVIEW 内容默认不公开,管理员或对应版主可以查看命中信息并选择通过或拒绝;系统会检查内容当前状态,避免重复审批。审核队列同样受版块权限约束:管理员查看全部,版主查询条件被限定到自己负责的版块。审批结果会同步回帖子或回复,并写入审计日志。7. 敏感词过滤与华为云审核敏感词管理支持新增、编辑、启用、停用和动态重载。每个词可以配置不同动作:REJECT:直接判为 BLOCK,阻止公开;REVIEW:进入人工审核队列;REPLACE:将命中内容替换后继续处理;未命中:本地结果为 PASS。系统先执行本地 DFA,再按配置调用华为云官方 Moderation Java SDK,并将不同来源统一映射为 PASS / REVIEW / BLOCK。云服务超时或异常时,系统降级到本地审核结果,同时保存 isDegraded 和脱敏错误摘要,不输出 AK/SK。public ModerationDecision moderateContent( String content, String contentType, Long targetId, Long boardId) { DfaResult dfaResult = matchWithDfa(content); ReviewStatus localStatus = determineLocalStatus(dfaResult.matchedWords()); saveModerationRecord(targetId, parseTargetType(contentType), boardId, ModerationSource.LOCAL, localStatus, null, String.join(",", dfaResult.matchedWords()), null, false, null); if (localStatus == ReviewStatus.BLOCK || !huaweiCloudEnabled) { return new ModerationDecision(localStatus, dfaResult.maskedText()); } try { CloudDecision cloud = callCloudApi(content, contentType); return new ModerationDecision( strictest(localStatus, cloud.status()), dfaResult.maskedText()); } catch (Exception e) { String summary = sanitizeError(e); saveModerationRecord(targetId, parseTargetType(contentType), boardId, ModerationSource.HUAWEI_CLOUD, localStatus, null, String.join(",", dfaResult.matchedWords()), null, true, summary); return new ModerationDecision(localStatus, dfaResult.maskedText()); } } 8. 拉黑会员系统支持两类作用域和两类时效:管理员可以创建全局黑名单;管理员或对应版主可以创建版块黑名单;记录既可以永久生效,也可以设置结束时间。解除拉黑同样需要权限校验并记录原因。发帖和回复前会同时匹配“全局黑名单”与“当前版块黑名单”,并校验记录仍处于有效期内:wrapper.eq(BlacklistRecord::getUserId, userId) .eq(BlacklistRecord::getStatus, BlacklistStatus.ACTIVE) .and(w -> w.eq(BlacklistRecord::getScope, BlacklistScope.GLOBAL) .or(w2 -> w2.eq(BlacklistRecord::getScope, BlacklistScope.BOARD) .eq(BlacklistRecord::getBoardId, boardId))) .and(w -> w.eq(BlacklistRecord::getIsPermanent, true) .or(w2 -> w2.isNull(BlacklistRecord::getEndTime) .or(w3 -> w3.gt(BlacklistRecord::getEndTime, LocalDateTime.now())))); 命中黑名单时后端返回 403 和清晰原因;即使绕过前端按钮也无法发帖或跟帖。9. 审计日志与管理驾驶舱除了原题要求,我增加了审计日志和管理驾驶舱。置顶、锁帖、删除、恢复、拉黑、解除拉黑和人工审核等关键动作都会记录操作者、目标、所属版块、原因、前后状态与时间,便于复盘管理行为和处理争议。六、创新与易用性双层内容治理:本地 DFA 提供低延迟、可控的第一道防线,华为云审核扩展识别范围,人工复核处理模糊内容。故障降级:外部云审核不可用时不阻断整个论坛,改用本地结果并留痕,兼顾可用性和可追溯性。细粒度版主权限:不是简单的“后台角色”,而是把管理权精确限制到负责版块,跨版块请求明确返回 HTTP 403。可恢复内容治理:管理删除采用软删除,保留原因和责任人,并提供恢复能力,降低误删风险。角色化操作体验:会员专注浏览与互动,版主只看到负责范围,管理员获得全局驾驶舱,减少无关菜单和误操作。七、码道新能力与华为云技术使用使用项目级规则与阶段 Prompt 约束技术栈、权限模型、内容治理和质量门禁;建立 forum-sdd、forum-moderation、forum-quality-gate 三个项目 Skill,分别服务于需求设计、内容治理与发布前验证;使用浏览器控制能力对 ADMIN、MODERATOR 等真实页面进行验收和截图,避免以 mock 页面冒充后端功能;接入华为云 Moderation Java SDK,保留 requestId、风险标签、分段结果和降级状态;同时提供 Vue Web 应用、REST 后台服务、MySQL 数据库与 Docker Compose/Nginx 本地容器化运行形态。八、测试与验证结果项目不是只完成页面展示,而是执行了完整质量门禁:验证项结果后端集成测试34/34 通过,0 failure、0 error、0 skipped前端类型检查与生产构建通过Docker Compose 配置与镜像构建通过全新 MySQL 数据卷启动MySQL、backend、frontend 均 healthy浏览器真实验收13 张页面证据,关键页面控制台错误为 0权限专项验证匿名私有接口 401,会员后台接口 403,版主跨版块 403验证命令如下:# 后端测试 cd backend mvn clean test # 前端类型检查和生产构建 cd ../frontend npm run build # 生产形态验证 cd .. docker compose config --quiet docker compose build docker compose up -d docker compose ps curl --fail http://localhost/actuator/health34 项后端测试覆盖:三种角色认证、错误密码、禁用账号、匿名访问、发帖、回复、点赞幂等、置顶排序、锁帖、软删除恢复、敏感词 REJECT/REVIEW/REPLACE、词库动态重载、人工审核、全局/版块黑名单、版主跨版块越权、审计和驾驶舱等关键场景。九、本地运行与容器化验证本地开发# 后端:dev 配置使用 H2,便于本地复现 git clone cid:link_0.git cd CampusCloudForum/backend mvn spring-boot:run -Dspring-boot.run.profiles=dev # 另开终端启动前端 cd CampusCloudForum/frontend npm install npm run dev访问 http://localhost:5173,后端健康检查为 http://localhost:8080/actuator/health。Docker Compose 本地容器化运行cp .env.example .env # 填写本地容器运行所需的 MySQL 密码和 JWT_SECRET docker compose config --quiet docker compose up -d --build curl --fail http://localhost/actuator/health如需在本地自行验证华为云内容审核,可通过环境变量启用;凭证不在代码中硬编码,也不提交到仓库:HUAWEI_CLOUD_MODERATION_ENABLED=true HUAWEI_CLOUD_REGION=cn-north-4 HUAWEI_CLOUD_PROJECT_ID=<project-id> HUAWEI_CLOUD_AK=<ak> HUAWEI_CLOUD_SK=<sk> HUAWEI_CLOUD_MODERATION_TIMEOUT_MS=3000 十、逐项对应评分项项目成果与证据创新易用双层审核、云故障降级、人工复核、版块级权限、软删除与角色化页面功能完备原题 10 个功能点全部闭环;34 项测试、13 张真实页面截图技术能力码道 Prompt/Skill/MCP、华为云 Moderation SDK、Web + REST + Docker/Nginx 多形态文档完整性需求、架构、数据库、API、测试、本地运行、码道过程、验收清单、案例文档和证据目录完整十一、项目成果总结这次实战让我从“实现一个能发帖的页面”,进一步走到了“构建一个权限正确、内容安全、操作可追溯、能够容器化运行的论坛系统”。CloudForum 已在本地完成核心功能、自动化测试、真实页面验收和完整容器验证;仓库中同时保留了需求、架构、API、测试和运行文档,方便评审复现。
  • [高校训练营] 基于 MaaS 和 CodeArts 的智能运维与代码重构平台实践
    在线体验地址:http://113.44.103.96(请复制到浏览器访问)项目源码仓库:cid:link_5一、概述1.1 案例介绍在软件研发和云上运维过程中,遗留代码重构依赖人工经验,故障日志分析又常常跨越应用、容器和函数等多个层次,定位慢、重复劳动多。CodeVerse-Ops 将华为云 MaaS 大模型能力接入研发运维流程,提供智能代码重构、云原生日志诊断、代码质量评分、上下文追问、历史任务分析和代码片段管理等能力。本案例将使用华为云 MaaS 的 DeepSeek-V4-Flash 模型作为推理引擎,基于 Next.js、Prisma 和 SQLite 构建全栈应用,并通过 PM2 与 Nginx 部署到弹性云服务器 ECS。完成案例后,您将掌握:使用 OpenAI 兼容接口调用华为云 MaaS 模型;使用华为云码道的 Spec-Driven 模式,将需求依次转化为规格、设计、任务和代码;理解 Server-Sent Events(SSE)任务事件,并在 AI 追问场景中实现流式回复;将模型能力组合为代码重构、日志根因分析和质量评分工作流;使用 Prisma 与 SQLite 管理任务、对话和收藏数据,并理解质量评分的数据模型;在 Ubuntu ECS 上完成 Node.js 应用的一键部署、验证和运维。说明:模型生成内容可能存在偏差。重构代码和运维修复建议应经过人工审查,并在测试环境验证后再应用到生产环境。1.2 适用对象企业开发者及 DevOps、SRE、云原生运维人员;希望学习大模型应用开发的个人开发者;具备 JavaScript/TypeScript、Linux 命令行基础的高校学生。1.3 案例时间直接使用仓库源码完成资源准备、部署和功能验证,预计需要 60~90 分钟。如通过码道分阶段搭建 CodeVerse-Ops,建议预留 2~3 小时,具体时间取决于代码生成、人工评审、依赖下载和构建速度。1.4 案例流程图 1-1 CodeVerse-Ops 案例流程说明:开通 MaaS:登录华为开发者空间,开通 DeepSeek-V4-Flash 预置服务,创建并妥善保存 API Key;创建 ECS:购买 Ubuntu ECS,绑定弹性公网 IP,并在安全组中开放 SSH 和 HTTP 访问;配置并上传:填写 MaaS API Key、基础地址和数据库连接,将项目部署包上传至 ECS;一键部署:运行部署脚本,自动安装依赖,完成数据库迁移、项目构建、PM2 启动和 Nginx 配置;功能体验:依次验证代码重构、批量处理、日志诊断、质量评分、AI 对话、仪表盘和收藏库;验证并释放:检查应用、代理和数据库状态;体验结束后删除 ECS、EIP 及不再使用的模型凭据。流程说明:图 1-1 展示的是“使用现有源码部署体验”的主流程。如需从需求开始复现项目开发过程,请在获取源码和正式部署前完成第三章的码道 Spec-Driven 四阶段实践。1.5 方案架构图 1-2 CodeVerse-Ops 系统运行架构核心调用链如下:浏览器提交代码或日志,Next.js API 创建任务并写入 SQLite;当前版本的提交接口同步调用华为云 MaaS,解析结果并将任务更新为 COMPLETED;浏览器收到 taskId 后连接任务 SSE 接口,通常直接收到 complete 事件并展示结果;用户继续追问时,服务端通过 thinking、result_chunk、complete 或 error 事件逐段推送模型回复;任务结果、对话记录和收藏内容持久化到 SQLite;质量评分接口在收到 taskId 时可持久化评分;仪表盘聚合任务数据,展示近 30 天趋势、任务分布,并预留质量趋势展示。1.6 资源总览本案例使用按需资源。以 1 小时体验、少量公网流量和少量模型调用估算,费用通常由 ECS 实例费用、EIP 流量费用和 MaaS Token 费用组成。云服务价格会因区域、规格和活动变化,最终以购买页面及账单为准。资源名称推荐规格用途计费说明华为开发者空间已完成实名认证的账号进入开发平台和实战案例免费MaaS 模型即服务DeepSeek-V4-Flash代码重构、日志分析、质量评分和对话按实际 Token 用量计费,可优先使用已领取权益弹性云服务器 ECS2 vCPU、4 GiB、Ubuntu 22.04、40 GiB 系统盘运行 CodeVerse-Ops推荐按需计费,价格以控制台为准弹性公网 IP EIP按流量计费、5 Mbit/sSSH 登录和浏览器访问按流量计费,价格以控制台为准费用提示:体验完成后请及时释放 ECS 和 EIP。仅关闭操作系统不会停止 ECS 计费。二、环境和资源准备2.1 前置条件开始前请确认:已注册华为云账号并完成实名认证;账号余额或代金券足以支付本案例资源;本地可使用 SSH 和 SCP。Windows 10/11 可在 PowerShell 中执行 ssh -V 和 scp 检查;已获得完整的 codeverse-ops 项目目录;不要将 API Key 写入公开仓库、聊天记录或截图。2.2 开通 MaaS 模型并创建 API Key登录华为开发者空间。如尚未领取模型权益,可参考《华为云 MaaS 平台大模型 Tokens 领取使用指导》完成领取。然后按以下步骤开通模型:进入 MaaS 控制台 > 模型推理 > 在线推理 > 预置服务;找到 DeepSeek-V4-Flash,单击 开通服务;服务开通后单击 调用说明,确认模型参数为 deepseek-v4-flash;在调用说明页面创建 API Key,并立即复制到安全位置。API Key 通常只在创建时完整显示;记录 OpenAI 兼容接口地址。中国大陆站的 OpenAI 兼容接口当前仅支持 西南-贵阳一,该区域的完整地址为:https://api.modelarts-maas.com/openai/v1/chat/completions本项目会自动在基础地址后追加 /v1/chat/completions,因此项目配置中应填写:https://api.modelarts-maas.com/openai中国香港站应以控制台“调用说明”显示的地址为准,常见基础地址为:https://api-ap-southeast-1.modelarts-maas.com/openai重要:模型服务、API Key 和调用地址必须属于同一区域,并以控制台“调用说明”为准。不要填写完整的 /v1/chat/completions 地址,否则项目会重复拼接路径;不要使用 https://api.deepseek.com,该地址不是华为云 MaaS 服务地址。Linux、macOS 或 ECS 可使用以下命令验证 API Key:export MAAS_API_KEY="<你的MaaS API Key>" curl -sS "https://api.modelarts-maas.com/openai/v1/chat/completions" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${MAAS_API_KEY}" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "请回复:连接成功"}], "max_tokens": 64 }' 响应中出现 choices 和模型回复即表示调用成功。若返回 401 或 403,请检查 API Key、模型开通状态和区域是否一致。Windows PowerShell 使用以下命令:$env:MAAS_API_KEY = "<你的MaaS API Key>" $headers = @{ "Content-Type" = "application/json" "Authorization" = "Bearer $env:MAAS_API_KEY" } $body = @{ model = "deepseek-v4-flash" messages = @(@{ role = "user"; content = "请回复:连接成功" }) max_tokens = 64 } | ConvertTo-Json -Depth 4 Invoke-RestMethod ` -Uri "https://api.modelarts-maas.com/openai/v1/chat/completions" ` -Method Post ` -Headers $headers ` -Body $body2.3 创建 ECS登录华为云控制台,进入 服务列表 > 计算 > 弹性云服务器 ECS,单击 购买弹性云服务器。图 2-1 选择 ECS 规格、镜像、磁盘和公网访问配置推荐配置如下:配置项推荐值说明计费模式按需计费便于体验结束后及时释放区域与账号和网络规划一致购买后不可直接更换CPU 架构x86与常用 Node.js 依赖兼容规格2 vCPU、4 GiB低于 4 GiB 可能在 next build 时内存不足镜像Ubuntu 22.04 Server 64bit部署脚本使用 apt-get系统盘40 GiB用于系统、依赖、构建产物和 SQLiteEIP现在购买用于 SSH 和 Web 访问带宽计费按流量计费,5 Mbit/s适合短时体验登录方式密钥对或强密码密钥对安全性更高购买完成后,在 ECS 详情页记录:ECS 公网 IP:后文以 <ECS_IP> 表示;登录用户名:本案例部署脚本固定使用 /root 并以 root 用户配置 PM2,因此应选择支持 root 登录的 Ubuntu 公共镜像;密钥文件路径或登录密码。图 2-2 ECS 创建完成并处于运行中说明:截图中的实例名称、IP、价格和区域仅为操作示例,请以实际控制台页面为准。2.4 配置安全组进入 ECS 详情 > 安全组 > 配置规则 > 入方向规则,添加以下规则:协议端口来源用途TCP22本机公网 IP/32SSH 和 SCPTCP80本机公网 IP/32;公开体验时可临时使用 0.0.0.0/0浏览器访问应用图 2-3 配置 ECS 安全组入方向规则安全建议:不要将 22 端口长期对全网开放。生产环境还应配置 HTTPS、Web 应用防火墙、身份认证和访问审计。本案例应用本身未实现用户登录,不应直接承载敏感代码或生产日志。2.5 准备项目环境变量记录从 MaaS 控制台获取的 API Key 和基础地址。为避免凭据进入压缩包,本案例将在代码上传 ECS 后创建 .env.production,文件内容如下:# 华为云 MaaS API Key HUAWEI_MAAS_API_KEY=<你的MaaS API Key> # 仅填写基础地址,不包含 /v1/chat/completions HUAWEI_MAAS_BASE_URL=https://api.modelarts-maas.com/openai # Prisma 会相对 prisma/schema.prisma 解析该路径 DATABASE_URL=file:../dev.db配置要求:HUAWEI_MAAS_API_KEY 不要添加多余空格或中文引号;HUAWEI_MAAS_BASE_URL 末尾有无 / 均可,客户端会移除末尾斜杠;DATABASE_URL 保持为 file:../dev.db,使 Prisma CLI 和应用运行时使用项目根目录下同一个数据库;.env.production 含敏感信息,不得提交到公开代码仓库或打入部署包;项目已通过 .gitignore 排除 .env.production;提交前仍应使用 git status 确认该文件未被暂存;部署脚本不会输出环境变量内容,终端日志中不应出现 API Key。2.6 获取案例源码通过 Git 下载案例源码:git clone cid:link_5.git codeverse-ops cd codeverse-ops仓库地址:CodeVerse-Ops(GitCode)【本帖子开头有】。下载后确认目录中至少包含:codeverse-ops/ ├── package.json ├── package-lock.json ├── scripts/deploy-ecs.sh ├── prisma/ └── src/检查点:执行 git status 能正常显示仓库状态,且 package.json、scripts/deploy-ecs.sh、prisma/ 和 src/ 均存在。三、通过码道分阶段搭建 CodeVerse-Ops本模块参考华为开发者空间案例中心的码道实践组织方式,结合 CodeVerse-Ops 的实际开发记录,演示如何使用华为云码道(CodeArts)代码智能体,以 Spec-Driven 模式将复杂需求依次转化为需求规格、技术设计、任务清单和可运行代码。说明:码道界面、模型列表和按钮位置可能随版本更新而变化,请以实际产品页面为准。生成代码必须经过人工审查、构建测试和安全检查;不要在对话、截图或提交记录中粘贴 API Key、密码等敏感信息。3.1 开通并进入码道登录华为开发者官网,进入华为云码道(CodeArts)代码智能体体验页面;按页面提示完成体验版开通;下载并安装支持码道的开发工具,登录同一华为云账号;打开码道 Agent Space 或 IDE 右侧智能体面板,确认可以选择 氛围编程(Vibe-Coding) 和 规范开发(Spec-Driven)。图 3-1 开通华为云码道代码智能体体验版图 3-2 进入码道 Agent Space图 3-3 在 IDE 中打开码道代码智能体3.2 创建项目并选择 Spec-Driven 模式新建空工作区,在智能体面板选择 规范开发(Spec-Driven)。首次输入应描述业务目标、技术栈、模型服务、核心功能和交付要求,避免只输入“帮我做一个网站”等宽泛指令。可使用以下需求作为起始提示词:请使用 Next.js 14、TypeScript、Tailwind CSS、Prisma 和 SQLite 构建 CodeVerse-Ops。应用接入华为云 MaaS 的 DeepSeek-V4-Flash, 提供单文件/批量代码重构、CCE/FunctionGraph 日志诊断、代码质量评分、 上下文对话、任务仪表盘和代码片段收藏功能。请采用 Spec-Driven 流程, 先生成需求规格,再生成技术设计和任务清单,经确认后分阶段实现。图 3-4 选择 Spec-Driven 模式并提交项目目标Spec-Driven 流程包含四个阶段:需求规格设计:明确目标、边界、用户故事和验收标准;实现方案创建:确定架构、数据模型、接口和部署方案;编码任务规划:将设计拆分为可追踪、可验证的任务;任务执行:按依赖顺序生成代码,并持续构建验证。3.3 第一阶段:生成并评审 spec.md码道首先将自然语言需求整理为 spec.md。评审时重点检查:是否覆盖代码重构、日志诊断、任务状态、模型调用和数据持久化;是否明确“不负责自动修改生产代码、不直接执行模型生成命令”等安全边界;每个核心能力是否具有可验证的验收标准;模型名称、接口兼容方式和部署目标是否与项目实际一致。图 3-5 第一阶段完成需求规格设计若规格有遗漏,先在对话中提出修改要求,确认 spec.md 后再进入设计阶段。不要让智能体在需求边界未确定时直接批量生成代码。3.4 第二阶段:生成并评审 design.mddesign.md 应把需求落实为可实现的技术方案。本项目重点确认:Next.js App Router 同时承载页面和 API;Prisma/SQLite 数据模型覆盖任务、日志、对话、评分和收藏;MaaS 客户端统一处理鉴权、超时、重试及流式响应;首轮任务与 AI 对话的 SSE 行为描述准确;ECS、PM2、Nginx 和容器化部署路径清晰;API Key 仅通过环境变量注入,不进入源码、镜像和日志。图 3-6 第二阶段完成实现方案设计3.5 第三阶段:生成并评审 tasks.md码道根据规格和设计生成 tasks.md,把工作拆分为初始化、数据模型、MaaS 客户端、任务状态、核心 API、前端页面和部署验证等任务。评审任务清单时应确保:每项任务都能回溯到 spec.md 和 design.md;任务依赖顺序正确,可并行项和串行项明确;每项任务包含完成条件,而不只是文件名;构建、数据库迁移、接口验证和安全检查被列入任务。图 3-7 第三阶段完成编码任务规划3.6 第四阶段:按任务清单执行确认任务清单后进入执行阶段。码道会读取规格和设计,按依赖关系创建文件、安装依赖并实现功能。建议采用“小批次执行—查看变更—运行验证—继续下一批”的节奏:先完成项目初始化、环境变量声明和 Prisma Schema;再实现 MaaS 客户端、任务状态和后端 API;然后实现重构、诊断、仪表盘、收藏等页面;最后补充 Dockerfile、ECS/CCE 部署文件和操作文档;每批变更后查看差异,拒绝与规格无关的修改。图 3-8 码道开始执行初始化与配置任务图 3-9 码道继续实现后端接口和前端页面图 3-10 任务执行阶段完成3.7 本地运行与阶段验收智能体完成首轮实现后,在项目目录执行:npm install npx prisma generate npx prisma migrate deploy npm run dev浏览器访问 http://localhost:3000,先验证页面路由和基本交互,再使用脱敏的测试代码与测试日志验证 MaaS 调用。首个可运行版本可能只具备代码重构和日志诊断,应按 tasks.md 的验收条件逐项检查,而不是仅以“页面能打开”作为完成标准。图 3-11 首个本地可运行版本的代码重构页面图 3-12 本地验证日志诊断功能3.8 模型接入的原型记录与正式配置项目早期曾使用 DeepSeek 官方 API 验证 OpenAI 兼容调用链,以下两张图仅用于说明原型演进,不是本案例的最终配置步骤。图 3-13 早期原型的 API Key 创建记录图 3-14 早期原型的环境变量配置正式案例已经切换到华为云 MaaS。请严格按照 2.2 和 2.5 节配置 HUAWEI_MAAS_API_KEY 与 https://api.modelarts-maas.com/openai,不要照抄历史截图中的 https://api.deepseek.com;截图中的凭据已失效或脱敏。3.9 迭代优化与上下文管理首轮功能完成后,可继续让码道基于实际测试结果迭代,但每次指令应说明问题、预期行为、影响范围和验证方式。本项目的后续迭代包括主题系统、命令面板、仪表盘、收藏库、批量重构、上下文对话以及 ECS 部署加固。图 3-15 基于功能差距分析继续迭代图 3-16 依据新增需求升级功能版本长任务会持续占用上下文。阶段验收后可使用会话压缩保留目标、约束、关键文件和未完成任务,再继续下一轮开发。压缩前应确认摘要未包含 API Key、登录密码等敏感信息。图 3-17 使用会话压缩管理长周期开发上下文完成本模块后,项目应通过 npm run build,数据库迁移可执行,核心页面可访问,且所有环境变量和部署步骤与后续章节一致。四、构建并部署 CodeVerse-Ops 应用4.1 技术栈与项目结构主要技术栈如下:层次技术版本/作用Web 框架Next.js14.2.35,App Router 全栈应用前端React、TypeScript、Tailwind CSSReact 18、TypeScript 5、Tailwind CSS 3.4编辑器CodeMirror 6代码输入、语法高亮和只读结果展示图表Recharts仪表盘与五维质量雷达图数据访问Prisma5.22.0,模型定义、迁移和查询数据库SQLite保存任务、日志、对话、评分和收藏模型服务华为云 MaaSDeepSeek-V4-Flash、OpenAI 兼容接口运行环境Node.js、PM2、NginxNode.js 20、进程守护、反向代理项目关键结构:codeverse-ops/ ├── prisma/ │ ├── schema.prisma # 7 个数据模型 │ └── migrations/ # 数据库迁移 ├── src/ │ ├── app/ │ │ ├── page.tsx # 首页 │ │ ├── refactor/page.tsx # 单文件/批量代码重构 │ │ ├── ops/diagnose/page.tsx # CCE、FunctionGraph 日志诊断 │ │ ├── dashboard/page.tsx # 任务统计与趋势 │ │ ├── snippets/page.tsx # 代码片段收藏库 │ │ └── api/ # 重构、诊断、评分、对话等 API │ ├── components/ # 编辑器、对比、图表、命令面板等组件 │ ├── hooks/ # SSE、主题等 React Hooks │ ├── lib/ │ │ ├── huawei-maas.ts # MaaS 客户端、重试和超时控制 │ │ ├── prisma.ts # Prisma 单例 │ │ ├── sse-client.ts # SSE 消息与响应头 │ │ ├── task-state.ts # 任务状态 │ │ ├── conversation-manager.ts # 30 分钟内存上下文 │ │ └── templates.ts # 代码与日志示例模板 │ └── types/ # API、模板和 SSE 类型 ├── .env.example # 环境变量示例 ├── .env.production # 生产配置,需自行创建 ├── scripts/ │ ├── deploy-ecs.sh # ECS 一键部署脚本 │ └── build-image.sh # SWR 镜像构建脚本 ├── deploy/ │ └── cce-deployment.yaml # CCE 部署清单 ├── Dockerfile # 容器化构建文件 ├── package.json # 项目依赖与命令 └── package-lock.json # 锁定依赖版本Prisma 数据模型职责:模型作用Task保存重构或日志诊断任务及状态CloudLog保存待分析日志及分析状态Snippet保存收藏的原始代码、重构代码和说明BatchGroup管理批量重构的总数和完成进度Conversation关联任务与对话Message持久化用户和助手消息QualityScore在评分接口收到 taskId 时,保存安全性、可维护性、性能、可读性和类型安全评分4.2 关键实现解析4.2.1 MaaS 客户端src/lib/huawei-maas.ts 负责:从环境变量读取 API Key 和基础地址;拼接 /v1/chat/completions;使用 Authorization: Bearer <API_KEY> 鉴权;固定调用 deepseek-v4-flash;同步调用最多尝试 3 次,即首次失败后最多重试 2 次,退避时间依次为 1 秒、2 秒;单次调用超时时间为 120 秒;支持普通 JSON 响应和流式响应。核心请求结构如下:const response = await fetch(`${baseUrl}/v1/chat/completions`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}`, }, body: JSON.stringify({ model: "deepseek-v4-flash", messages, temperature: 0.7, max_tokens: 4096, stream: true, }), }); 4.2.2 任务接口与 SSE 事件代码重构和日志诊断采用“同步任务提交 + SSE 结果回传”的两阶段请求:图 4-1 CodeVerse-Ops 首轮任务与对话请求流程图中编号说明:提交代码或日志:浏览器将用户输入发送到对应的 Next.js API;创建任务:服务端在 SQLite 中创建状态为 PENDING 的任务;进入处理状态:开始推理前,将任务状态更新为 PROCESSING;调用模型:服务端通过 OpenAI 兼容接口同步调用华为云 MaaS;返回完整结果:MaaS 返回完整的代码重构或日志分析结果;保存结果:服务端解析模型输出,将结果写入 SQLite,并将任务标记为 COMPLETED;响应提交请求:Next.js API 向浏览器返回 taskId 和完整结果;连接任务 SSE:浏览器使用 EventSource 连接任务 SSE 接口;返回完成事件:SSE 接口查询到已完成任务后,发送 complete 事件。用户继续对话时,应用则通过 SSE 逐段返回模型回复。实现边界:页面上的“正在连接 AI 服务”和 SSE 状态组件已经具备流式展示结构,但首轮重构、诊断请求的等待主要发生在同步 POST 阶段,当前版本不会逐 Token 展示首轮模型输出。对话追问采用真实流式响应。4.2.3 提示词与结构化结果应用通过系统提示词限定模型角色,并要求模型返回 JSON:代码重构:返回 refactoredCode 和 explanation;日志诊断:返回 analysis 和 patchSuggestion;质量评分:返回五个 0~100 的维度分数及 details。服务端会从模型输出中提取 JSON。若模型未严格返回 JSON,部分接口会回退为原始文本。因此,生成结果仍需人工复核。4.3 打包项目在本地打开项目父目录执行。部署包明确排除环境变量、依赖、构建产物、数据库和 Git 元数据:tar -czf codeverse-ops-deploy.tar.gz \ --exclude=codeverse-ops/node_modules \ --exclude=codeverse-ops/.next \ --exclude=codeverse-ops/dev.db \ --exclude=codeverse-ops/.env \ --exclude=codeverse-ops/.env.production \ --exclude=codeverse-ops/.git \ codeverse-ops/Windows PowerShell 使用反引号续行:tar -czf codeverse-ops-deploy.tar.gz ` --exclude=codeverse-ops/node_modules ` --exclude=codeverse-ops/.next ` --exclude=codeverse-ops/dev.db ` --exclude=codeverse-ops/.env ` --exclude=codeverse-ops/.env.production ` --exclude=codeverse-ops/.git ` codeverse-ops/ 打包后检查文件和压缩包内容:Get-Item .\codeverse-ops-deploy.tar.gz tar -tzf .\codeverse-ops-deploy.tar.gz检查点:压缩包中必须包含 package-lock.json、scripts/deploy-ecs.sh、prisma/ 和 src/,不得包含 .env、.env.production、node_modules、.next 或旧的 dev.db。4.4 上传项目并执行一键部署步骤 1:上传部署包在本地项目父目录执行:scp codeverse-ops-deploy.tar.gz root@<ECS_IP>:/root/使用密钥对时执行:scp -i <私钥文件路径> codeverse-ops-deploy.tar.gz root@<ECS_IP>:/root/步骤 2:登录 ECSssh root@<ECS_IP> 使用密钥对时执行:ssh -i <私钥文件路径> root@<ECS_IP> 步骤 3:解压并运行部署脚本cd /root tar -xzf codeverse-ops-deploy.tar.gz rm -f codeverse-ops-deploy.tar.gz cd /root/codeverse-ops vi .env.production在编辑器中填写 2.5 节准备的三个环境变量,保存后限制文件权限:chmod 600 .env.production # 确保 Node.js 主版本为 20 node -v 2>/dev/null || true 若已安装的 Node.js 不是 20.x,先升级:curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs首次部署执行:chmod +x scripts/deploy-ecs.sh bash scripts/deploy-ecs.sh重新部署时,scripts/deploy-ecs.sh 会先备份 /opt/codeverse-ops/dev.db,替换应用文件后再恢复数据库并执行增量迁移。重要数据仍建议在部署前单独备份。部署脚本自动完成:阶段操作预期结果1/6安装 Node.js 20、PM2、Nginx、SQLite输出各工具版本2/6备份数据库,替换 /opt/codeverse-ops 中的应用文件并恢复数据项目文件部署完成,历史数据保留3/6将 .env.production 复制为 .env应用可读取配置4/6执行 npm ci、Prisma 生成、迁移和 next build数据表和生产构建生成5/6使用 PM2 启动 npm startcodeverse-ops 状态为 online6/6配置 Nginx,将 80 端口代理到 3000nginx -t 成功并重载部署脚本结束时会输出访问地址。请以实际 ECS 公网 IP 为准:http://<ECS_IP>说明:脚本末尾可能显示脚本内预置的示例 IP,该值不一定是当前 ECS 地址,不应作为访问依据。图 4-2 PM2 启动成功且 Nginx 配置校验通过4.5 部署结果验证依次执行:node -v npm -v pm2 status systemctl is-active nginx curl -I http://127.0.0.1:3000 curl -I http://127.0.0.1预期结果:Node.js 主版本为 v20;PM2 中 codeverse-ops 状态为 online;Nginx 状态为 active;两次 curl 均返回 HTTP 200、301 或 307 等正常响应,而不是连接失败。检查数据库:cd /opt/codeverse-ops sqlite3 dev.db ".tables" 预期至少看到与以下模型对应的数据表:BatchGroup CloudLog Conversation Message QualityScore Snippet Task最后,在浏览器访问 http://<ECS_IP>。首页应显示“代码重构”“日志诊断”“仪表盘”和“收藏库”等入口。图 4-3 通过 ECS 公网地址访问 CodeVerse-Ops图 4-4 首页功能入口、核心特性和任务统计五、功能体验5.1 智能代码重构在首页单击 代码重构;保持 单文件 模式;选择 javascript,单击 快捷模板 > 回调地狱;也可粘贴自己的代码;单击 提交重构;提交后等待 MaaS 返回完整结果。当前版本在此阶段可能仅显示按钮处于处理中;页面连接任务 SSE 接口并显示“重构完成”后,查看 TypeScript 结果和优化点;单击 对比查看,检查原代码与重构代码差异;查看五维质量雷达图,比较原始代码和重构代码;使用复制、导出或收藏功能保存结果。图 5-1 提交代码并获得 TypeScript 重构结果图 5-2 对比重构前后代码并查看质量评分示例输入:function getUserData(userId, callback) { db.query("SELECT * FROM users WHERE id = ?", [userId], function (err, user) { if (err) return callback(err); db.query("SELECT * FROM orders WHERE userId = ?", [userId], function (err, orders) { if (err) return callback(err); callback(null, { user, orders }); }); }); } 验收标准:请求完成后页面显示任务成功状态、完整重构结果和任务 ID;结果包含带明确类型的 TypeScript 代码;优化说明能够指出异步流程、错误处理或类型安全等改进;雷达图至少展示安全性、可维护性、性能、可读性和类型安全五个维度。注意:当前重构提示词统一要求输出 TypeScript。即使输入 Python、Java、Go、PHP、Ruby、C 或 C++,输出目标仍是 TypeScript。5.2 批量代码重构进入 代码重构,切换到 批量;单击 添加文件,填写文件名、语言和代码内容;重复添加多个文件;单击批量提交按钮,查看总体和单文件处理状态;等待各文件状态更新为 COMPLETED 或 FAILED。限制条件:单次最多 20 个文件;接口以 JavaScript 字符串长度统计总量,上限约 500 万字符;该限制不等同于严格的 UTF-8 字节大小;每个文件会创建独立任务,并归属同一个批次;批量处理消耗的模型 Token 通常高于单文件处理,请控制测试代码规模。当前版本说明:批量页面仅展示文件名、语言和任务状态,暂不提供单个文件的重构结果详情入口。5.3 云原生日志故障诊断在首页单击 日志诊断;选择 CCE(云容器引擎);单击 快捷模板 > CCE OOMKilled;单击 提交诊断;等待同步分析完成,查看根因分析和 YAML 修复建议;再选择 FunctionGraph(函数工作流),使用“函数超时”模板重复体验。图 5-3 提交 FunctionGraph 故障日志并查看根因图 5-4 查看结构化修复建议并继续追问示例输入:Warning OOMKilled pod/api-server-7d9f8b6c4-x2k9j Last State: Terminated Reason: OOMKilled Exit Code: 137 Restart Count: 5 Limits: cpu: 1, memory: 512Mi Requests: cpu: 500m, memory: 256Mi验收标准:根因分析能识别容器内存超限和退出码 137;修复建议包含调整 resources.requests、resources.limits 或排查内存泄漏的可执行方向;FunctionGraph 超时案例能给出超时时间、内存、数据读取方式等方面的排查建议。安全提示:提交真实日志前应删除账号、Token、密码、内网地址、用户数据等敏感信息。模型建议不可直接应用于生产集群。5.4 代码质量评分单文件重构完成后,页面会分别调用质量评分接口评估原始代码和重构代码。评分范围为 0~100:维度评估内容常见风险安全性注入、XSS、敏感信息、危险 API拼接 SQL、明文密钥、eval可维护性模块化、重复度、耦合度超长函数、重复逻辑、全局状态性能复杂度、I/O 和资源使用不必要的嵌套循环、重复请求可读性命名、结构、注释单字母变量、深层嵌套类型安全类型覆盖与边界处理any、隐式转换、空值未处理评分由大模型生成,适合辅助比较,不等同于静态代码扫描、单元测试或安全审计结果。当前版本说明:重构页面会展示原始代码和重构代码的即时评分,但页面请求暂未携带 taskId,因此这些评分不会写入 QualityScore 表,仪表盘“质量评分趋势”可能为空。这不影响雷达图展示和其他任务统计。5.5 AI 上下文对话在重构或诊断结果页单击 继续对话;输入针对当前结果的问题,例如“请解释此处的类型设计”或“如何验证该 YAML 修复有效”;查看流式回复;收起对话面板后再次打开,确认历史消息仍可显示。对话消息会写入 SQLite,但服务端用于连续推理的内存上下文有效期为 30 分钟,每 5 分钟清理一次。重新打开“继续对话”面板时,应用会读取持久化消息并重建上下文;如果面板保持打开期间上下文过期,接口会提示重新创建。刷新页面后,当前结果和 taskId 会丢失,现有页面没有从仪表盘重新进入原任务详情的入口。5.6 历史任务仪表盘完成至少一次代码重构和一次日志诊断;进入 仪表盘;查看总任务数、重构次数、诊断次数和成功率;查看近 30 天趋势、任务类型分布、状态分布、质量评分趋势和最近任务;单击 刷新,或保持 30 秒自动刷新。图 5-5 查看任务总量、成功率和近 30 天趋势图 5-6 查看任务分布、质量趋势和最近任务若仪表盘为空,请先确认任务已成功写入数据库,再刷新页面。5.7 代码片段收藏库在代码重构结果页单击 收藏;进入 收藏库;使用关键词或编程语言筛选收藏;复制或导出收藏结果;单击 删除 并确认,可移除不再需要的收藏。图 5-7 搜索、复制、导出或删除收藏内容日志诊断结果也提供收藏入口。收藏前请确认结果中不含敏感日志。5.8 命令面板与主题按 Ctrl+K(macOS 为 Command+K)打开命令面板;输入“重构”“诊断”“仪表盘”“收藏”或“主题”等关键词;使用方向键选择命令,按 Enter 执行,按 Esc 关闭;可通过页面导航切换明暗主题。图 5-8 使用命令面板快速导航图 5-9 切换为浅色主题六、运行维护与故障排查6.1 常用运维命令# 查看进程 pm2 status # 查看最近日志 pm2 logs codeverse-ops --lines 100 # 重启应用 pm2 restart codeverse-ops # 查看 Nginx 状态与配置 systemctl status nginx --no-pager nginx -t # 查看端口监听 ss -lntp | grep -E ':80|:3000' # 查看磁盘和内存 df -h free -h # 查看数据库表和最近任务 cd /opt/codeverse-ops sqlite3 dev.db ".tables" sqlite3 dev.db \ "SELECT id, type, status, language, createdAt FROM Task ORDER BY createdAt DESC LIMIT 10;" 修改 .env 后必须重启应用:cd /opt/codeverse-ops pm2 restart codeverse-ops --update-env6.2 常见问题现象可能原因处理方法浏览器无法访问 http://<ECS_IP>安全组未开放 80、Nginx 未启动、EIP 错误检查安全组、systemctl status nginx 和 ECS 公网 IP502 Bad GatewayNext.js 进程未启动或 3000 端口未监听执行 pm2 status、pm2 logs codeverse-ops,重启 PM2返回 401 或 403API Key 无效、模型未开通、账号区域不匹配重新查看 MaaS 调用说明并创建 API Key返回 404MaaS 基础地址配置错误确保地址不包含 /v1/chat/completions,国内站填写 https://api.modelarts-maas.com/openai页面提示“系统配置异常”环境变量缺失检查 /opt/codeverse-ops/.env 中两个 HUAWEI_MAAS_* 变量AI 请求长时间无响应或连接中断单次 MaaS 调用超时为 120 秒,普通调用最多尝试 3 次缩短输入并检查 MaaS 状态;Nginx 已配置 400 秒读取超时,生产环境仍应结合调用策略统一超时对话流式输出中断Nginx、浏览器网络或模型连接中断检查 PM2/Nginx 日志,重新打开对话面板后重试首轮重构或诊断没有逐 Token 输出当前提交接口同步完成 MaaS 调用后才连接任务 SSE这是当前版本的实现行为;等待请求完成,以最终结果为准next build 被系统终止ECS 内存不足使用 4 GiB 或更高规格,停止无关进程后重试Prisma 报数据库不存在或无表DATABASE_URL 错误或迁移失败恢复 file:../dev.db,执行 npx prisma generate && npx prisma migrate deploy仪表盘有任务但无质量趋势当前重构页面的评分请求未携带 taskId这是当前版本已知限制,不影响即时雷达图和其他任务统计批量任务拒绝提交文件数或字符串总长度超限保持不超过 20 个文件、代码总量约 500 万字符以内6.3 重新构建与升级更新代码后,在 ECS 执行:cd /opt/codeverse-ops npm ci npx prisma generate npx prisma migrate deploy npm run build pm2 restart codeverse-ops --update-env执行数据库迁移前建议备份:cd /opt/codeverse-ops cp dev.db "dev.db.backup.$(date +%Y%m%d%H%M%S)" 6.4 生产化建议本案例以快速体验为目标。用于团队或生产环境前,至少应补充:使用 IAM、统一身份认证或应用登录保护所有页面和 API;使用 ELB/Nginx 配置 HTTPS 证书,禁止明文传输代码和日志;将 API Key 存储到云凭据管理服务,避免落盘和终端输出;使用云数据库替代单机 SQLite,并建立自动备份;将内存对话上下文迁移到 Redis 等共享存储,支持多实例;增加请求限流、输入大小限制、审计日志和敏感信息脱敏;对模型生成代码执行静态扫描、单元测试和人工评审;对模型生成的运维命令和 YAML 建立审批及灰度验证流程;配置 AOM、LTS 或其他可观测服务监控 CPU、内存、错误率和模型调用延迟。七、释放资源7.1 删除 ECS登录华为云控制台,进入 弹性云服务器 ECS > 实例;选择本案例创建的 ECS;单击 更多 > 删除;根据页面提示勾选释放绑定的 EIP、删除系统盘和数据盘;确认资源名称和影响范围后完成删除。删除后再次检查 ECS、云硬盘和 EIP 列表,确认没有遗留按需资源。7.2 处理 MaaS 资源进入 MaaS 控制台 > 模型推理 > 在线推理:预置模型通常按实际调用量计费,停止调用后不会继续产生推理 Token;删除不再使用的 API Key,降低泄露风险;如创建过专属部署实例或其他持续计费资源,请停止并删除;在费用中心检查账单和代金券使用情况。7.3 删除本地敏感文件不再使用项目时,可删除包含 API Key 的部署包和环境变量文件:# Linux/macOS rm -f codeverse-ops-deploy.tar.gz rm -f codeverse-ops/.env.productionWindows PowerShell 执行:Remove-Item .\codeverse-ops-deploy.tar.gz -ErrorAction SilentlyContinue Remove-Item .\codeverse-ops\.env.production -ErrorAction SilentlyContinue若 API Key 曾出现在公开仓库、日志或截图中,应立即在 MaaS 控制台删除并重新创建。八、扩展资料华为云 MaaS OpenAI 兼容接口说明华为云 MaaS 模型列表弹性云服务器 ECS 文档弹性公网 IP 文档云容器引擎 CCE 文档函数工作流 FunctionGraph 文档九、案例验收清单完成以下检查即表示案例体验成功:[ ] 已开通 DeepSeek-V4-Flash,并使用华为云 MaaS API Key 完成接口验证;[ ] 如实践第三章,已通过码道完成 spec.md、design.md、tasks.md 和分阶段任务执行;[ ] ECS、EIP 和安全组配置完成;[ ] codeverse-ops 在 PM2 中为 online,Nginx 为 active;[ ] 浏览器可通过 ECS 公网 IP 打开首页;[ ] 单文件代码重构可通过任务 SSE 接口收到 complete 结果;[ ] 批量重构可显示批次和单文件状态;[ ] CCE 或 FunctionGraph 日志可生成根因分析和修复建议;[ ] 质量雷达图可展示原始代码与重构代码对比;[ ] AI 对话可逐段显示回复,仪表盘和收藏库可正常使用;[ ] 已确认模型输出仅作辅助并经过人工复核;[ ] 体验结束后已释放不再使用的计费资源和 API Key。
  • [高校训练营] 基于华为云码道(CodeArts)代码智能体与 ECS 的 CoursePilot:AI 个性化学习闭环开发实践
    一、概述1.1 案例介绍在课程学习中,学生常常同时面对 PDF 讲义、Markdown 笔记、教材摘录和练习题等多种资料。传统学习工具通常只能解决“保存资料”或“回答问题”中的某一个环节,难以持续回答下面几个问题:一门课程到底包含哪些知识点,它们之间有什么层级和前置关系?学生目前真正薄弱的是哪些知识点,判断依据是什么?学习计划能否根据实际作答结果自动调整?AI 给出的知识点、题目和回答是否有课程资料依据?当模型或外部服务不可用时,核心学习流程能否继续运行?基于这些问题,我利用华为云码道(CodeArts)智能体开发了 CoursePilot。它不是一个只负责聊天的通用助手,而是一个以课程资料和学习证据为基础的 AI 个性化学习教练 Agent。系统围绕以下闭环工作:注册登录 → 创建课程 → 添加资料 → 构建知识结构 → 设置学习目标 → 初始诊断 → 生成知识画像 → 制定学习计划 → 学习与练习 → 错因分析 → 更新掌握度 → 动态调整计划 项目仓库:cid:link_7项目地址:115.120.251.21(由于成本限制,该IP发布帖子几日后可能会释放!)演示视频:项目仓库根目录 demo视频.mp41.2 核心设计原则课程无关:不把业务逻辑绑定到某一门固定课程。资料驱动:知识点、题目和学习辅导尽量建立在用户资料之上。来源可追溯:知识点和 AI 生成题目保留对应资料与分块来源。证据驱动:掌握度来自真实作答、难度、耗时和提示使用情况。人机协同:AI 负责提取、生成和辅助判断,用户保留确认与修正权。可解释与可审计:重要算法采用确定性规则,Skill 与 MCP 调用保存日志。可降级:大模型不可用时,资料解析、诊断和掌握度更新等核心流程仍可运行。1.3 适用对象希望完成 AI Agent 项目实践的高校学生;学习 Vue 3、FastAPI、MCP、Skill 与 Docker 的开发者;需要搭建课程资料管理、诊断或个性化学习系统的团队;希望了解如何将本地全栈应用部署到华为云 ECS 的开发者。1.4 案例时间本案例总时长预计240分钟。1.5 案例流程本案例采用“需求规格—架构设计—任务拆解—分阶段开发—测试验证—云端部署—迭代优化”的流程完成 CoursePilot 的设计与实现。使用华为云码道(CodeArts)代码智能体辅助完成需求分析,编写产品规格、功能需求和用户流程文档,明确 CoursePilot 的产品定位、功能范围、验收条件以及“资料驱动、证据驱动、来源可追溯”等核心原则,定义系统“做什么”。完成系统架构与技术方案设计,确定 Vue 3、FastAPI、SQLAlchemy、MCP、Skill 和 Docker Compose 技术栈,并编写领域模型、总体架构、MCP 设计、Skill 设计及关键算法 ADR,定义系统“怎么做”。根据需求和架构生成开发路线及阶段任务清单,将项目拆分为课程资料、知识结构、题库诊断、知识画像、学习计划、学习 Agent、MCP/Skill、学习看板和云端部署等可独立验收的开发任务。按照任务清单逐步开发:搭建 FastAPI 后端和 Vue 3 前端,实现用户认证、课程管理、资料解析、知识结构生成、AI 辅助出题、动态诊断、掌握度计算、个性化学习计划及渐进式辅导 Agent。建立 CoursePilot MCP Server,封装课程资料、题库、作答记录、学习状态和计划管理等工具;同时实现资料结构化、学习诊断、计划生成和苏格拉底式辅导等可插拔 Skill。使用码道代码智能体辅助进行跨文件代码审查、缺陷定位和测试补充;后端及 MCP Server 使用 Pytest 和 Ruff 验证,前端使用 TypeScript 类型检查、ESLint 和 Vite 生产构建验证。使用 Docker Compose 完成前端、后端和 MCP Server 的容器化编排,并部署至华为云 ECS;结合华为云 SWR 镜像加速解决基础镜像拉取问题,使用 Alembic 完成数据库迁移,并通过健康检查和容器日志验证服务状态。根据实际使用结果持续迭代,修复文件上传 413、AI 长任务 504、生成题目知识点 ID 越界、诊断中断后无法继续等问题,进一步提升系统的数据一致性、容错能力和用户体验。1.6 资源总览资源名称本案例使用规格主要用途计费说明弹性云服务器 ECS通用计算增强型 ac9s.large.2;2 vCPU;4 GiB;Ubuntu 24.04 Server 64 位;60 GiB 通用型 SSD运行前端、FastAPI 后端和 MCP Server 容器0.3452元/小时 弹性公网 IP EIP全动态 BGP;按流量计费;5 Mbit/s提供网站公网访问及 SSH 运维入口0.8元/GB虚拟私有云 VPC 和安全组1 个 VPC、1 个子网、1 个安全组提供私有网络及端口访问控制免费容器镜像服务 SWR使用个人专属镜像加速地址加速拉取 Python、Node.js 和 Nginx 等 Docker 基础镜像免费华为云码道(CodeArts)代码智能体专业版辅助需求分析、架构设计、任务拆解、代码开发、测试及问题定位专业版,139元/6000万tokens免排队MaaS - Console个人使用deepseek-v4-flash用于知识结构优化、AI 辅助出题及学习辅导输入:1元/百万tokens  输出:2元/百万tokensECS 本地存储SQLite 数据库及课程上传目录,共用 ECS 系统盘保存业务数据、课程资料和调用记录已包含在本案例 ECS 云硬盘配置中二、系统方案设计2.1 技术栈层级技术选型前端Vue 3、TypeScript、Pinia、Vue Router、Vite、AxiosWeb 服务Nginx后端Python 3.11、FastAPI、Pydantic、异步 SQLAlchemy数据迁移AlembicAgent 协议Model Context Protocol(MCP)业务能力4 个可插拔 Skill大模型接入OpenAI 兼容 Provider,用户自行配置模型数据库SQLite(案例演示);可切换 PostgreSQL容器化Docker、Docker Compose云资源华为云弹性云服务器 ECS、弹性公网 IP、安全组代码托管GitCodeAI 辅助开发华为云码道(CodeArts)代码智能体2.2 总体架构用户浏览器 │ ▼ Nginx / Vue 3 前端(80/443) │ /api/* ▼ FastAPI 后端(容器内部 8000) ├── SQLAlchemy / Alembic ── SQLite 或 PostgreSQL ├── 课程资料与上传文件 ├── LLM Provider ───────── 用户配置的大模型服务 └── MCP Client │ Streamable HTTP ▼ MCP Server(容器内部 8001) ├── 13 个业务工具 └── 4 个 CoursePilot 运行时 Skill2.3 项目结构CoursePilot/ ├── backend/ # FastAPI、领域模型、服务、Alembic 与测试 ├── frontend/ # Vue 3 前端 ├── mcp-server/ # MCP Server 与业务工具 ├── skills/ # 4 个 CoursePilot 运行时 Skill ├── docs/ # 需求、架构、ADR、验收与阶段报告 ├── AGENTS.md # 项目技术规范与协作约束 ├── docker-compose.yml └── README.md2.4 MCP 与 Skill 设计CoursePilot 的 MCP Server 提供 13 个业务工具,分为四类:课程与资料:课程列表、课程结构、资料检索、资料来源;学习状态:学生画像、知识点掌握度、错题;题库与作答:题目搜索、题目详情、保存作答;计划与掌握度:读取计划、更新计划、更新掌握度。系统还实现了 4 个运行时 Skill:Skill作用course_material_structuring将课程资料整理为知识结构learning_diagnosis根据作答证据分析学习状态和错因study_plan_generator生成及动态调整学习计划socratic_tutor使用分级提示进行启发式辅导三、使用华为云码道进行规范驱动开发3.1 建立项目上下文CoursePilot 涉及课程资料、题库、诊断、知识画像、计划、Agent、MCP 和 Skill 等多个领域。如果只用一句话要求 AI “生成一个学习平台”,很容易得到功能堆叠但规则不一致的代码。因此,本项目先在仓库中沉淀以下上下文:AGENTS.md:技术栈、目录结构、编码规范和测试命令;docs/product-spec.md:产品定位、范围和冻结决策;docs/requirements.md:功能需求与验收条件;docs/domain-model.md:领域实体、关系与约束;docs/architecture.md:系统边界与调用链;docs/adr/:掌握度算法、学习计划算法、Agent 编排等架构决策。3.2 各阶段Prompt每次使用时,可以先附加这段通用要求:请先阅读 AGENTS.md、本阶段相关设计文档和现有代码。 开始修改前必须: 1. 说明当前实现基线; 2. 给出任务拆解、影响文件和数据迁移方案; 3. 明确本阶段边界; 4. 不修改与本阶段无关的模块; 5. 不覆盖用户已有修改; 6. 实现后运行相关自动化测试和质量检查; 7. 最后报告修改文件、测试结果、未完成项和已知限制。 所有新增API统一放在 /api/v1/ 下。 后端IO操作优先使用 async/await。 数据库结构变更必须使用Alembic,不使用create_all代替迁移。 前端使用Vue 3、TypeScript、Pinia和<script setup lang="ts">。前置阶段:需求与规格设计请作为产品经理和系统架构师,为 CoursePilot 建立完整的需求与设计基线。 项目定位: CoursePilot 是一个课程无关、资料驱动、证据驱动、来源可追溯的AI个性化学习教练。系统需要形成: 创建课程 → 添加资料 → 构建知识结构 → 设置学习目标 → 初始诊断 → 知识画像 → 学习计划 → 学习与练习 → 错因诊断 → 掌握度更新 → 动态调整计划 请检查当前项目骨架,并编写或完善: - docs/product-spec.md - docs/requirements.md - docs/mvp-acceptance.md - docs/user-flows.md - docs/domain-model.md - docs/skill-design.md - docs/mcp-design.md - docs/development-roadmap.md - docs/current-gap-analysis.md 具体任务: 1. 定义目标用户、用户痛点、产品定位和产品边界; 2. 将需求划分为Must、Should、Could和Won't; 3. 为每项Must需求定义正常流程、异常流程和验收条件; 4. 使用Given/When/Then编写可执行验收标准; 5. 设计课程、资料、知识点、题目、诊断、画像、计划和Agent等领域实体; 6. 设计4个业务Skill及13个MCP工具; 7. 冻结掌握度、简答题、诊断题数量、模型Provider、账号体系和课程无关性决策; 8. 将开发工作拆分为阶段0至阶段7; 9. 明确每个阶段的目标、任务、边界、验收标准和交付物。 本阶段只编写需求和设计文档,不修改业务代码。 不得提前将尚未实现的功能标记为完成。阶段0:可运行基础设施基线请执行 CoursePilot 阶段0:可运行基础设施基线。 阶段目标: 让FastAPI后端、Vue前端、异步数据库、Alembic和MCP Server形成可启动、可测试的基础工程。 具体任务: 1. 修复FastAPI启动流程,确保GET /health返回200; 2. 建立统一的SQLAlchemy Base、异步engine和AsyncSession; 3. 配置Alembic target_metadata及异步迁移环境; 4. 验证upgrade head、downgrade base、再次upgrade head; 5. 统一Python模块路径和项目依赖,消除循环引用; 6. 修复Vue 3开发启动、TypeScript检查、ESLint和生产构建; 7. 将MCP Server统一为Streamable HTTP传输,端点为/mcp; 8. 确定FastAPI后端是唯一MCP Client,移除前端直连MCP的设计; 9. 修复后端、前端和MCP Server的Dockerfile及docker-compose.yml; 10. 建立后端健康检查、MCP连通性和前端页面加载冒烟测试; 11. 更新AGENTS.md和docs/deployment.md中的启动命令。 阶段边界: - 不实现课程CRUD; - 不实现资料解析; - 不创建完整业务领域模型; - 不实现正式业务Skill和MCP工具; - 不接入真实大模型; - 不实现完整注册、登录和管理员后台。 验收要求: - 后端、前端和MCP Server均可独立启动; - Alembic往返迁移通过; - MCP Streamable HTTP调用通过; - 前端type-check、lint和build通过; - docker compose config验证通过。阶段1:课程、资料与知识结构闭环请执行 CoursePilot 阶段1:课程、资料和知识结构垂直闭环。 请重点阅读: - docs/product-spec.md - docs/requirements.md中的FR-001至FR-003 - docs/domain-model.md - docs/user-flows.md中的流程1至流程4 - docs/mvp-acceptance.md中的AC-001至AC-003 阶段目标: 完成“创建课程→添加资料→解析资料→形成知识结构”的完整闭环。 具体任务: 1. 创建Course、CourseMaterial、MaterialChunk、KnowledgePoint和KnowledgeRelation模型; 2. 编写对应Alembic迁移、约束、外键和索引; 3. 实现课程创建、列表、详情、编辑和软删除API; 4. 实现PDF、Markdown、TXT文件上传及文本粘贴; 5. 实现资料状态、失败原因、重试和删除; 6. 实现规则型文本提取和资料分块; 7. 保存文件名、页码、章节或字符范围等来源信息; 8. 实现知识点新增、编辑、删除、排序和父子层级; 9. 实现prerequisite、contains和related知识关系; 10. 防止知识点关系自引用和循环依赖; 11. 实现课程列表、课程详情、资料管理和知识结构页面; 12. 使用两门内容不同的课程验证业务代码没有学科硬编码。 阶段边界: - 不实现题库和诊断; - 不实现知识画像、掌握度和学习计划; - 不实现正式业务Skill和MCP工具; - 不调用真实大模型。 验收要求: 用户能够创建课程,上传或粘贴资料,查看解析状态、资料分块和来源,并获得可编辑的树形知识结构。阶段2:题库、诊断与作答记录请执行 CoursePilot 阶段2:题库、初始诊断和作答记录。 请重点阅读: - requirements.md中的FR-004、FR-006和FR-010 - mvp-acceptance.md中的AC-004、AC-006和AC-010 - product-spec.md中的D-002和D-003 - domain-model.md中的题目、诊断和作答实体 阶段目标: 完成“建立题库→开始诊断→逐题作答→完成诊断”的业务流程。 具体任务: 1. 创建Question、QuestionOption和QuestionSource模型; 2. 创建question_knowledge_point多对多关联表; 3. 支持单选题、判断题和简答题; 4. 实现题目新增、编辑、删除、列表、筛选和审核状态; 5. 手动题目默认confirmed,AI或导入题目默认pending; 6. 题目必须关联至少一个当前课程知识点; 7. 保存题目对应的资料分块和来源位置; 8. 创建DiagnosticAttempt和AnswerRecord; 9. 按D-003规则选择诊断题: target_count = min(max(核心知识点数量, 10), 20); 10. 题库不足时阻止诊断并提示用户补充; 11. 诊断开始时保存不可变题目快照; 12. 保存答案、正确性、作答时间、跳过状态、提示次数和最高提示等级; 13. 实现L1至L4渐进式提示,L4完整解析需要二次确认; 14. 实现题库、诊断作答和诊断结果前端页面; 15. 为AI辅助出题预留接口,但本阶段不接入真实模型。 阶段边界: - 不计算知识画像和最终掌握度; - 不实现错因诊断; - 不实现学习目标和学习计划; - 不实现业务Skill、正式MCP工具和Agent。 验收要求: 用户能够管理题库并完成一次10至20题的诊断;系统保存完整作答证据,诊断题响应不得提前泄露正确答案和解析。阶段3:知识画像、错因诊断与掌握度请执行 CoursePilot 阶段3:知识画像、错因诊断和掌握度算法。 请重点阅读: - requirements.md中的FR-007、FR-011和FR-012 - mvp-acceptance.md中的对应验收条件 - product-spec.md中的D-001和D-002 - docs/adr/ADR-003-mastery-algorithm.md 阶段目标: 将用户作答记录转换为确定、可解释、可追溯的知识画像。 具体任务: 1. 创建MasteryRecord和ErrorDiagnosis模型及Alembic迁移; 2. 实现mastery-v1确定性掌握度算法; 3. 掌握度范围为0至100,置信度范围为0至1; 4. 算法考虑正确性、难度、作答时间、提示等级、连续错误、时间间隔和前置知识; 5. 使用Decimal和ROUND_HALF_UP,禁止依赖浮点round; 6. 每次有效证据追加MasteryRecord,不覆盖历史记录; 7. 保存旧值、新值、计算依据、变化原因和关联AnswerRecord; 8. 保证同一作答记录不会重复生成掌握度记录; 9. 实现10类规则型错因判断; 10. 保存错因类型、诊断依据、置信度、建议行动和关联知识点; 11. 支持用户确认或修改错因; 12. 实现知识画像列表和掌握度证据详情API; 13. 实现掌握度、置信度、薄弱点、待复习和证据链前端页面。 阶段边界: - 大模型不能直接计算或写入掌握度; - 本阶段不得调用真实LLM; - 不实现学习目标、学习计划和Agent; - 不实现正式业务Skill和MCP工具。 验收要求: 相同输入必须产生相同掌握度结果,每次变化均可追溯到具体作答记录;未经确认的简答题不得影响掌握度。阶段4:学习目标、计划与动态调整请执行 CoursePilot 阶段4:学习目标、个性化学习计划与动态调整。 请重点阅读: - requirements.md中的FR-005、FR-008和FR-013 - mvp-acceptance.md中的对应验收条件 - docs/adr/ADR-004-study-plan-algorithm.md 阶段目标: 根据学习目标、知识画像、知识点关系和时间约束生成确定、可解释的学习计划。 具体任务: 1. 创建LearningGoal、StudyPlan和StudyTask模型及迁移; 2. 每个用户每门课程只维护一个LearningGoal; 3. 支持目标日期、目标掌握度、每日时长和每周学习日; 4. 实现study-plan-v1确定性计划算法; 5. 根据掌握度差距、重要性、复习状态、连续错误和前置关系计算优先级; 6. 使用Kahn算法对前置关系稳定拓扑排序; 7. 检测知识点关系环; 8. 将任务分配到目标日期范围内的可用学习日; 9. 每日总时长不得超过daily_minutes; 10. 超过60分钟的任务拆分为多个子任务; 11. 容量不足时返回结构化错误和调整建议; 12. 每个任务保存generation_reason和generation_basis; 13. 支持完成、跳过、延期和手动调整; 14. 支持评估是否需要重新规划; 15. 重新规划时将旧计划设为superseded,并通过previous_plan_id保留历史; 16. 实现学习目标、当前计划和历史计划前端页面。 阶段边界: - 不调用真实大模型; - 不实现Agent、业务Skill和正式MCP工具; - 不实现错题本、学习看板、日历同步和消息推送。 验收要求: 计划生成结果可重复、可解释,不违反前置关系和时间容量;用户操作任务后能够评估调整需求并保留计划版本历史。阶段5:Skill、MCP、Agent 与 LLM Provider请执行 CoursePilot 阶段5:业务Skill、MCP工具、Agent和LLM Provider。 请重点阅读: - docs/skill-design.md - docs/mcp-design.md - docs/adr/ADR-005-agent-provider-and-orchestration.md - 阶段1至阶段4已经实现的业务服务 阶段目标: 建立可配置、可审计、可降级的CoursePilot Agent体系。 具体任务: 1. 删除course_recommend、schedule_optimizer和learning_analyzer占位Skill; 2. 实现4个正式Skill: - course_material_structuring - learning_diagnosis - study_plan_generator - socratic_tutor 3. 每个Skill包含skill.py、config.yaml和async execute(params); 4. Skill不直接操作数据库,通过业务服务或MCP工具获取数据; 5. 实现13个正式MCP业务工具; 6. 将MCP工具划分为只读工具和写入工具; 7. MCP Server通过BackendGateway调用FastAPI业务API; 8. 前端不得直接连接MCP Server; 9. 实现可配置的LLM Provider抽象; 10. 支持Mock Provider和OpenAI兼容Provider; 11. 自动测试只能使用Mock/Fake Provider; 12. 创建AgentSession、AgentMessage和ToolCallLog; 13. 实现Agent会话创建、消息发送、历史查询和结束会话; 14. 实现L1至L4苏格拉底式辅导; 15. 标记course_material、ai_supplement、mixed和unverified来源; 16. 所有Skill和MCP调用保存审计记录; 17. 对API Key、Token、Cookie、密码和密钥进行递归脱敏; 18. Agent写操作必须先请求用户确认; 19. 实现Agent对话和来源展示前端页面; 20. 实现Provider和MCP不可用时的规则降级。 阶段边界: - 不实现错题本和学习看板; - 不实现管理员后台; - 不允许把具体模型写成不可替换依赖; - Skill不得复制确定性掌握度和计划算法。 验收要求: 4个Skill和13个MCP工具能够独立调用;Agent可读取课程资料、画像和计划,能够恢复会话、显示来源、记录调用并在模型不可用时降级。阶段6:错题本、看板与日志展示请执行 CoursePilot 阶段6:完整前端交互、错题本、学习看板和调用日志展示。 请先检查阶段1至阶段5的数据模型和业务调用链,特别是: - AnswerRecord - DiagnosticAttemptQuestion不可变快照 - ErrorDiagnosis - MasteryRecord - StudyPlan和StudyTask - AgentSession和ToolCallLog 阶段目标: 补齐学习数据展示、错题复习和完整前端体验。 具体任务: 1. 实现WrongQuestionState模型及Alembic迁移; 2. 按user_id、course_id和question_id聚合错题; 3. 错题内容优先读取不可变题目快照; 4. 仅将有效错误作答计入错误次数; 5. 支持按知识点、错因、状态和关键词筛选; 6. 展示历史错误、资料来源、错因证据和掌握度证据; 7. 支持标记已掌握; 8. 用户后续再次答错时自动重新打开错题状态; 9. 复用DiagnosticAttempt体系创建单题练习; 10. 实现学习看板10类确定性指标; 11. 展示今日任务、总体进度、掌握度分布、薄弱点、待复习项、错因分布、本周有效作答时长和计划完成率; 12. 实现课程级ToolCallLog查询; 13. 支持类型、状态、工具、会话、时间和分页筛选; 14. 保存日志和查询输出时均执行敏感信息脱敏; 15. 实现错题本、看板和调用日志前端页面; 16. 完善加载状态、错误提示、空状态、导航、路由参数和刷新恢复。 阶段边界: - 不修改4个Skill核心逻辑; - 不修改13个MCP工具契约; - 不修改mastery-v1和study-plan-v1; - 不实现管理员后台和阶段7部署功能。 验收要求: 错题复习、学习看板和调用日志形成前后端闭环;跨用户访问统一返回404;页面刷新后数据可以从API恢复。3.3 Skill前端美化AI直接生成的前端通常不符合我们的胃口,存在以下问题:全站仍是系统默认字体、同一字号层级和同一种 8px 圆角,页面缺少品牌辨识度。紫色高饱和主色、纯白卡片加灰边框在所有页面重复,是典型的通用 AI 后台视觉。顶栏只是文本平铺,当前页面反馈弱,宽屏松散、窄屏拥挤。首页、课程列表和登录页过度居中,信息层级单薄;题库等高频页面则过密。按钮、表单、弹窗样式在各页面重复且状态不统一,Hover、Pressed、Focus 反馈不足。加载和空状态大多只是一行文字,视觉完成度不足。因此我们可以为Code添加Skill对前端进行美化我们选用GitHub - Leonxlnx/taste-skill: Taste-Skill - gives your AI good taste. stops the AI from generating boring, generic slop · GitHub 这个67.7k Star的Github开源skill进行优化请你根据skill修改现有前端界面,做的更好看一些效果也是很明显:美化前首页美化后首页四、核心功能实现具体核心功能展示请参考仓库内的demo视频,或者通过打开网站或本地部署实际操作,这里简单展示一下界面和操作功能4.1 从课程资料生成可追溯知识结构用户可以上传 PDF、Markdown、TXT 文件,或者直接粘贴文本。后端解析后将内容切分为资料块,并保存文件、位置与内容之间的对应关系。知识结构生成时,系统不会只保存一个无法解释的标题,而是将知识点关联到原始资料。用户可以查看、调整层级和关系,降低模型幻觉对后续诊断的影响。如果知识结构生成不清晰,你可以使用AI进行结构的优化,也可以手动进行修改,使结构更加清晰4.2 基于资料的 AI 辅助出题在题库管理界面你可以手动添加题目,也可以使用AI辅助出题AI 出题只允许引用当前课程中有效的知识点 ID 和资料块 ID。模型输出后,后端还会再次校验:题型和难度是否符合请求;knowledge_point_ids 是否属于允许范围;source_chunk_id 是否来自本次课程资料;选项、答案和解析结构是否完整。如果模型第一次返回了越界 ID,系统会把错误约束和合法范围反馈给模型并重试;连续失败时停止保存,避免产生半成品题目。4.3 测验与知识画像当题库足够完整,能够覆盖全部知识点时,可以进行测验与诊断:测验过程中可以申请不同等级的提示,或者跳过,但是这和答错一样会不同程度影响你的掌握度判定!系统不会让大模型直接决定最终掌握度,而是使用确定性规则综合以下证据:作答是否正确;题目难度;作答耗时;提示次数与提示等级;最近正确率;是否重复犯错;前置知识掌握情况。每次掌握度变化都会保存旧值、新值、变化原因和关联作答记录,用户能够查看“为什么发生了这次变化”。错题可以在“错题本”中进行复习,或者重新做题:4.4 学习计划与动态调整用户可以设置目标日期、目标掌握度、每日学习时长和每周可学习日期。系统根据知识画像、知识点重要程度、前置关系、历史错题和可用时间生成学习任务。当用户完成任务、连续答错或掌握度明显变化时,系统可以触发重新规划,并保留计划版本和调整原因。同时用户也可以在学习看板上查看一系列学习数据:4.5 渐进式学习辅导 Agent学习辅导 Agent 通过 MCP 工具读取当前课程资料、知识结构、学生画像和学习计划,再由 Skill 控制提示节奏:L1:提醒相关知识点;L2:指出思路方向;L3:给出关键步骤;L4:在用户确认后给出完整解析。回复通过 SSE 流式返回,并标记内容来自课程资料、AI 补充或混合来源。模型不可用时,系统可以降级为规则型提示。五、部署到华为云 ECS5.1 案例环境本案例采用一台华为云 ECS 完成演示部署:配置项案例选择区域华东-上海一ECS通用计算增强型,2 vCPU / 4 GiB操作系统Ubuntu 24.04 Server 64 位系统盘通用型 SSD,60 GiB公网访问弹性公网 IP,按流量计费,5 Mbit/s容器编排Docker Compose安全组:端口用途来源建议22SSH 运维仅允许管理员当前公网 IP /3280HTTP0.0.0.0/0443HTTPS0.0.0.0/05.2 登录服务器这里我采用的是密钥对登录:$key = "D:\EdgeDownload\KeyPair-e9f4.pem" icacls $key /inheritance:r icacls $key /grant:r "$($env:USERDOMAIN)\$($env:USERNAME):(R)" icacls $key先执行这一步是为了防止Window私钥文件权限过宽然后执行登录:ssh -i $key root@115.120.251.215.3 安装 Docker 和 Git登录 ECS 后执行:apt update apt install -y ca-certificates curl git install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo ${UBUNTU_CODENAME:-$VERSION_CODENAME}) stable" \ > /etc/apt/sources.list.d/docker.list apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin systemctl enable --now docker docker --version docker compose version这里可能会出现报错,可能是因为访问 Docker 官方源被重置。直接改用华为云 Docker 镜像源即可。curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg \ -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu $(. /etc/os-release && echo ${UBUNTU_CODENAME:-$VERSION_CODENAME}) stable" \ > /etc/apt/sources.list.d/docker.list apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin systemctl enable --now docker5.4 克隆 CoursePilot输入:cd /opt git clone cid:link_7.git cd CoursePilot5.5 创建生产环境变量先生成三个密钥,分别复制输出结果:python3 -c "import secrets; print(secrets.token_urlsafe(48))" python3 -c "import secrets; print(secrets.token_urlsafe(48))" python3 -c "import base64,secrets; print(base64.urlsafe_b64encode(secrets.token_bytes(32)).decode())"创建环境变量文件:nano .env填入:SECRET_KEY=第一个随机值 MCP_INTERNAL_API_KEY=第二个随机值 LLM_CREDENTIAL_ENCRYPTION_KEY=第三个随机值 ALLOWED_ORIGINS=["http://你的EIP"]保存退出即可。5.6 添加持久化配置现有 Compose 没有持久化 SQLite 和上传文件,所以不要直接启动。创建覆盖文件:nano docker-compose.override.yml填入:services: backend: environment: DATABASE_URL: sqlite+aiosqlite:////data/coursepilot.db DEBUG: "False" SECRET_KEY: ${SECRET_KEY} LLM_CREDENTIAL_ENCRYPTION_KEY: ${LLM_CREDENTIAL_ENCRYPTION_KEY} MCP_INTERNAL_API_KEY: ${MCP_INTERNAL_API_KEY} MCP_SERVER_URL: http://mcp-server:8001/mcp UPLOAD_DIR: /data/uploads ALLOWED_ORIGINS: '${ALLOWED_ORIGINS}' volumes: - ./data:/data restart: unless-stopped frontend: restart: unless-stopped mcp-server: environment: BACKEND_API_URL: http://backend:8000/api/v1 MCP_INTERNAL_API_KEY: ${MCP_INTERNAL_API_KEY} restart: unless-stopped保存退出,创建数据目录:mkdir -p data/uploads chmod 700 data5.7. 构建并启动docker compose build --pull如果出现报错可能是因为Docker Hub 在大陆网络访问超时。需要给 Docker 配置华为云 SWR 镜像加速器。在华为云控制台:切换到“华东-上海一”。搜索并进入“容器镜像服务 SWR”。左侧选择“镜像资源 → 镜像中心”。点击“镜像加速器”。复制地址在ECS执行:mkdir -p /etc/docker nano /etc/docker/daemon.json填入复制的真实地址:{ "registry-mirrors": [ "https://xxxxxxxx.mirror.swr.myhuaweicloud.com" ] }保存退出即可!然后拉取基础镜像:docker pull python:3.11-slim docker pull node:20-alpine docker pull nginx:alpine三个都成功后,重新构建:cd /opt/CoursePilot docker compose build5.8 文件上传问题解决课程文件上传和 AI 知识结构优化都可能超过 Nginx 默认限制。可以在 /api/ 代理中补充:server { listen 80; server_name _; client_max_body_size 20m; location /api/ { proxy_pass http://backend:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 60s; proxy_send_timeout 300s; proxy_read_timeout 300s; } }修改后重新构建并启动前端容器:docker compose build frontenddocker compose up -d --no-deps frontend六、问题排查与踩坑复盘AI生成的代码在一些小细节上会出现疏忽和错误,同时部署过程中一些文件的配置不完全也可能会带来一些问题。这里是我列出的一部分可能会出现的问题可解决方案,如果大家部署过程中产生错误可参考以下内容:6.1 Docker Hub 连接超时现象failed to resolve source metadata for docker.io/library/python:3.11-slimdial tcp ...:443: i/o timeout原因ECS 访问 Docker Hub 不稳定,构建阶段无法获取基础镜像元数据。解决配置华为云 SWR 镜像加速器,先单独执行 docker pull 验证,再重新执行 Compose 构建。拉取完成后若 referrers 请求偶发超时,可重试构建。6.2 Alembic 找不到 app 模块现象ModuleNotFoundError: No module named 'app'原因迁移进程启动时,后端源码目录没有进入 Python 模块搜索路径。解决docker compose run --rm \ -e PYTHONPATH=/app/backend \ backend python -m alembic upgrade head6.3 上传课程资料返回 413现象Request failed with status code 413原因请求在进入 FastAPI 前就被 Nginx 的默认请求体大小限制拒绝。解决在 Nginx server 中设置 client_max_body_size,同时保证该值不小于后端允许的上传上限。6.4 AI 优化知识结构返回 504现象Request failed with status code 504原因模型需要读取多份资料并生成分层结构,耗时超过 Nginx 默认代理等待时间。解决提高 proxy_read_timeout 和 proxy_send_timeout。更长期的方案是将长任务改造成异步任务,并通过任务状态接口或 SSE 返回进度。6.5 模型返回越界知识点 ID现象第 4 道题结构不合法:knowledge_point_ids 不在允许范围内原因旧逻辑只重试题型和难度错误,知识点 ID 到保存阶段才校验,模型没有纠正机会。解决将知识点 ID 和资料块 ID 校验前移到模型重试阶段,反馈非法值与允许范围;连续失败则停止整批保存。6.6 诊断退出后无法再次进入现象该课程已有进行中的诊断,attempt_id=...原因后端正确阻止了重复创建,但前端没有恢复已有 attempt 的入口。解决将“开始诊断”设计为幂等操作:发现进行中的 attempt 时直接返回原记录,前端显示“继续诊断”,再从下一道未答题恢复。八、案例总结CoursePilot 的开发让我认识到,AI Agent 应用的难点不只是“接入一个大模型”,而是如何把模型放进一个可信、可解释、可恢复的业务闭环中。在开发阶段,华为云码道(CodeArts)代码智能体的价值主要体现在:通过 Codebase 理解跨前后端、MCP 与 Skill 的项目上下文;将自然语言需求拆解成可执行、可追踪的开发任务;在多文件修改、测试补充和日志排障中提高效率;结合仓库规范与验收条件,减少无边界生成;帮助整理从本地开发到 ECS 部署的完整过程。在运行阶段,CoursePilot 则通过资料来源、确定性算法、用户确认、调用审计和降级策略约束大模型,让 AI 真正服务于学习过程,而不是只生成看似合理的答案。九、参考资料华为云社区 HCSD 板块华为云码道(CodeArts)代码智能体产品介绍华为云码道(CodeArts)代码智能体下载安装CoursePilot GitCode 项目仓库
  • [高校训练营] 基于华为云码道(CodeArts)代码智能体的上海药品监管信息平台
    基于华为云码道(CodeArts)代码智能体的上海药品监管信息平台项目仓库:https://github.com/jks0730/SH-Drug-Mgmt部署网址:http://120.46.223.11一、概述1.1 案例介绍药品流通业务涉及供应商、药店、物流企业与监管机构。传统表格式管理难以将药品批号、库存数量、订单履约、运输状态与企业资质建立稳定关联,出现异常时也难以快速定位责任节点。本项目以“上海药品监管信息平台”为实践对象,采用 Vue 3 + Vite 前端、Flask 后端与 SQLite 数据库实现 B/S 架构。系统围绕用户认证、企业认证、库存管理、B2B 供需、订单流转、物流上报、批次追溯、监管分析与操作审计建立数据闭环。1.2 适用对象需要学习 Vue 3 + Flask 前后端分离项目落地流程的开发者;希望了解 RBAC、JWT 与多租户数据隔离设计的学习者;需要构建库存预警、供应链协同、订单状态机或流通追溯系统的开发者;希望将项目过程整理为社区技术帖、课程设计或实训案例的同学。1.3 案例目标目标说明真实场景建模按企业、药品、批次、订单和运单梳理药品流通数据多角色协同为药店、供应商、物流、监管及管理员提供不同工作台全流程追溯将订单、批次、流通记录和物流节点关联起来风险前置对低库存、近效期、过期及运输异常提供预警基础文档可复现给出技术选型、核心代码、流程图与真实页面截图1.4 案例时间与资源资源用途成本Vue 3 + Vite前端页面与构建工具免费Flask + SQLAlchemyREST API 与业务逻辑免费SQLite开发环境业务数据免费Element Plus + ECharts表单、表格与监管可视化免费高德地图 API / WebSocket地图定位、路径与位置推送扩展按服务配置1.5 案例总流程系统业务从供应发布开始,经采购、履约、运输和收货后沉淀为库存与监管数据。下图为项目的总流程图。图 1:药品监管业务总流程。1.6 功能需求对应关系需求方向项目对应能力账户与权限注册、登录、密码重置、JWT 会话、RBAC 角色控制企业资质药店/供应商/物流企业认证与管理员审核库存管理药品批次、库存项、库存流水、效期与低库存预警供需协作供应信息发布、药店采购、订单确认与取消流通监管运单关联、物流节点上报、批次追溯与监管查询审计分析监管工作台、合规分析、操作日志二、环境和资源准备2.1 项目资源项目采用前后端分离结构:frontend 目录保存 Vue 3 前端,backend 目录保存 Flask API、模型和业务模块,data 目录保存示例数据,docs 目录保存项目文档和本文所引用的截图、流程图。2.2 本地开发环境工具推荐版本用途Node.js20+前端依赖安装与 Vite 开发服务Python3.8+Flask 后端运行环境npm与 Node.js 配套前端依赖管理Edge / Chrome现代版本页面访问与功能验证2.3 技术选型层级技术选型说明前端框架Vue 3 + Vite组件化开发与快速热更新UI 与图表Element Plus + ECharts管理端表格、表单、通知和统计图表后端框架Flask轻量 REST API 与模块化蓝图数据访问SQLAlchemy实体关系与事务管理身份授权Flask-JWT-Extended + RBAC保护 API 与限制角色功能范围数据库SQLite / PostgreSQL开发轻量化,生产可平滑扩展三、码道搭台:需求分析与系统设计3.1 向开发助手描述初始需求项目的初始需求可以概括为:构建一个服务于药店、供应商、物流企业和监管机构的药品监管平台。系统需要支持用户与企业认证、药品和批次库存、B2B 供需、采购订单、运输状态、药品流通追溯、库存预警、监管看板和操作审计;所有企业业务数据必须遵守租户隔离。该描述进一步拆分为用户权限、企业认证、库存、供需订单、流通物流、监管审计六类模块。3.2 功能模块划分模块核心功能主要页面 / API账户信息管理注册、登录、找回密码、角色权限Login.vue、Register.vue、/api/auth/*企业库存管理批次库存、入出库、库存预警Inventory.vue、/api/v1/inventory/*B2B 供求平台供应发布、采购下单、订单处理B2B.vue、/api/supply/*、/api/orders/*流通监管运单上报、物流状态、批次追溯Circulation*.vue、/api/circulation/*监管分析风险概览、企业监控、合规报告Analysis.vue、/api/regulator/*系统管理企业审核、用户管理、审计日志Admin*.vue、/api/admin/*3.3 系统架构设计前端通过 JWT 保存登录会话;后端按接口执行 RBAC 和租户边界校验;业务数据按药品库存、供给订单、流通物流和审计日志分类保存。高德地图与 WebSocket 作为定位和实时状态能力的扩展服务。图 2:药品监管平台技术架构。3.4 数据模型设计系统的核心实体包括:领域关键实体作用权限users、roles、permissions、user_roles账户、角色和细粒度权限企业tenants、enterprise_certifications企业资料与认证审核流程药品库存drugs、inventory_items、inventory_transactions药品主数据、批次余额与流水交易supply_info、orders、order_items供给信息与采购履约追溯circulation_records、logistics_records运单、节点状态与坐标审计operation_logs、password_reset_tokens关键操作留痕与密码安全库存项使用“企业 + 药品 + 批号”作为唯一维度;任何数量变化都单独记录为库存流水,不将来源企业或订单信息混入库存余额表。3.5 接口设计模块接口示例方法说明登录/api/auth/loginPOST校验账户,签发 JWT库存/api/v1/inventory/itemsGET / POST查询或新建企业库存批次库存预警/api/v1/inventory/warningsGET查询低库存、临期等风险项供应信息/api/supply/infoGET / POST查询或发布供给订单/api/ordersGET / POST查询或创建采购订单流通记录/api/circulation/*POST / GET上报或查询追溯节点管理审计/api/admin/audit-logsGET按条件查询审计日志四、码道领航:功能实现与界面落地4.1 账户、认证与角色会话注册成功后账号默认处于未认证状态,用户可提交企业认证;审核通过后获得对应业务角色。前端对 token 与用户信息做统一会话封装:// frontend/src/utils/authSession.js export const AUTH_TOKEN_KEY = 'access_token' export const AUTH_USER_KEY = 'current_user' export function setAuth(token, user) { if (token) localStorage.setItem(AUTH_TOKEN_KEY, token) if (user) localStorage.setItem(AUTH_USER_KEY, JSON.stringify(user)) } export function isAuthenticated() { return !!getToken() && !!getCurrentUser() } 图 3:账号注册页。图 4:登录页。4.2 批次库存、流水与租户隔离库存读写必须首先确认用户是否有当前企业的访问权。监管员和管理员具有额外查看范围,其余角色只能访问自身 tenant_id 对应的数据。# backend/inventory_warning.py def _ensure_tenant_access(user: User, tenant_id: int): if user.role in {'admin', 'regulator'}: return if not user.tenant_id: abort(403, description='当前账号尚未关联企业') if user.tenant_id != tenant_id: abort(403, description='无权访问其他企业库存') @bp.route('/items', methods=['GET']) @jwt_required() def list_inventory_items(): user = _get_current_inventory_user() tenant_id = request.args.get('tenant_id', type=int) if user.role not in {'admin', 'regulator'}: tenant_id = user.tenant_id _ensure_tenant_access(user, tenant_id) 4.3 B2B 订单状态流转药店创建订单后,订单从待确认开始。供应商负责确认与发货,物流企业负责在途更新和送达,药店确认收货后订单完成。待确认阶段存在药店取消、供应商拒绝和系统超时取消三条分支。图 5:B2B 采购订单状态流转。4.4 流通追溯与监管分析订单发货后生成流通记录,物流企业依据运单持续上传位置和状态。监管人员可按订单、运单或药品批号检索流通链路;库存预警、运输异常和认证风险能够进入监管工作台。图 6:监管分析仪表盘。4.5 UI 美化与多角色界面平台为不同角色提供各自导航、快捷入口和业务面板,避免将监管、采购和运输操作混在同一界面中。图 7:平台首页。图 8:药店运营仪表盘。图 9:供应协同仪表盘。图 10:物流履约仪表盘。五、关键技术难点与解决思路问题原因解决方式结果跨企业越权访问请求参数可能携带其他企业 ID后端根据角色覆盖或校验 tenant_id非监管角色不能读取其他企业库存库存余额无法追溯仅保存当前数量会丢失变动来源单独维护 inventory_transactions可按时间、订单与操作者回溯订单状态混乱多角色可操作同一订单以状态机约束可转换状态与操作角色履约过程可解释、可审计批次链路断裂库存、订单、物流独立建模在订单明细、流通记录中关联批号支持批次级追溯风险发现滞后仅在人工查询时发现临期或缺货定时扫描库存并提供预警 API可提前处理库存风险六、系统启动与验证6.1 启动后端cd backend python run.py后端默认运行于:http://127.0.0.1:50006.2 启动前端cd frontend npm install npm run dev前端默认运行于:http://127.0.0.1:51736.3 页面功能验证可依次验证注册、登录、企业认证、库存管理、供给发布、采购订单、物流工作台和监管工作台。密码找回页支持邮箱或手机号验证方式,验证码有效期按项目规则控制。图 11:找回密码页。6.4 API 验证# 登录获取 JWT curl -X POST http://127.0.0.1:5000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"pharmacy1","password":"password123"}' # 查询库存预警(需替换为实际 token) curl "http://127.0.0.1:5000/api/v1/inventory/warnings?page=1&per_page=20" \ -H "Authorization: Bearer <access_token>" # 查询采购订单 curl "http://127.0.0.1:5000/api/orders?page=1&per_page=20" \ -H "Authorization: Bearer <access_token>" 七、项目结构与成果文件7.1 项目目录SH-Drug-Mgmt/ ├── backend/ # Flask API、模型、业务模块与测试 │ ├── auth.py # 认证与密码管理 │ ├── inventory_warning.py # 库存与预警 │ ├── orders.py # 订单管理 │ ├── circulation.py # 流通追溯 │ ├── logistics.py # 物流状态 │ └── models.py # SQLAlchemy 模型 ├── frontend/ # Vue 3 前端 │ └── src/ │ ├── views/ # 角色页面与业务页面 │ ├── api/ # API 调用封装 │ ├── router/ # 路由守卫 │ └── utils/ # 会话、角色和地图工具 ├── data/ # 示例数据 └── docs/ ├── 上海药品监管信息平台-项目展示帖.md └── post-assets/ # 真实截图与流程图 PNG7.2 成果文件文件说明docs/上海药品监管信息平台-项目展示帖.md本项目展示帖docs/post-assets/real-screenshots/本地项目真实页面截图docs/post-assets/flowcharts/图像流程图与架构图backend/tests/后端测试用例frontend/tests/前端单元测试八、总结与展望本项目将药品批次、库存流水、供应信息、订单履约、物流节点和监管分析放入同一条数据链路中。与单一库存管理页面相比,它更关注多企业之间的数据协同、状态可控和过程可审计。后续可以从以下方向继续完善:接入冷链传感器数据,扩展温湿度异常预警;引入电子签章、召回流程与更严格的资质文件校验;扩展监管报表、风险规则引擎和跨区域流通分析;在 PostgreSQL 与消息队列基础上增强并发处理和实时推送能力;根据生产环境合规要求完善脱敏、备份、监控和审计策略。九、使用华为云码道(CodeArts)代码智能体辅助开发9.1 开发流程概述本项目在需求梳理、设计评审、编码实现、测试验证与部署脚本整理等阶段使用华为云码道(CodeArts)代码智能体进行辅助。整体采用以需求和设计为先的 SDD(Specification-Driven Development)思路:先明确业务角色、数据边界和验收规则,再拆分任务并实施代码,最后通过测试和部署验证形成反馈闭环。图 12:CodeArts 辅助的需求—设计—实现—测试—部署闭环。9.2 需求细化与设计文档审查项目启动时,先向 CodeArts 描述上海药品监管信息平台的业务目标、技术栈与核心约束:Vue 3 + Vite 前端、Flask 后端、SQLite 数据库、JWT 会话、RBAC 权限控制,以及药店、供应商、物流、监管员和管理员等多角色协作。随后由代码智能体读取项目目录、现有需求和技术约束,对药品批次、库存流水、采购订单、物流节点、企业认证、租户隔离与监管审计等内容进行系统性梳理。图 13:通过自然语言描述项目目标后,CodeArts 对项目代码与文档进行探索。在设计优化阶段,结合规划框架进一步审查需求澄清、架构决策、任务拆分、代码质量和测试保障等内容,重点检查角色权限边界、订单状态流转、批次追溯关系和风险预警场景。图 14:使用 CodeArts 对药品监管平台设计文档进行针对性优化。9.3 SDD 文档驱动与任务拆分围绕项目需求,可将设计工作沉淀为以下三类 SDD 文档:文档类型核心内容对应项目范围需求规格(spec)定义“做什么”、角色规则与验收条件认证、库存、供需、订单、物流、追溯、监管详细设计(design)定义“如何做”、数据模型、接口和页面交互Flask API、Vue 页面、RBAC、租户隔离、状态机任务清单(tasks)将设计拆分为可验证的开发任务模型、接口、页面、测试、部署与验收CodeArts 可依据自然语言需求协助补全结构化需求条目、接口边界与任务验收条件,减少因角色职责不清、库存与订单数据脱节或状态机遗漏带来的设计偏差。9.4 代码生成与迭代辅助在实现和迭代阶段,代码智能体主要辅助以下工作:数据模型与接口骨架:围绕用户、企业、药品、库存、供应信息、订单、流通记录与操作日志等实体,协助完善 SQLAlchemy 模型、字段校验和接口参数定义;业务规则实现:针对 JWT 鉴权、RBAC 权限、租户隔离、库存预警、订单状态机和批次追溯,协助定位规则边界并生成或优化后端逻辑;前端页面开发:围绕登录注册、企业认证、库存管理、B2B 采购、物流工作台和监管看板,协助生成 Vue 组件、路由守卫、状态管理和 API 调用代码;问题定位与修复:结合报错信息和调用链,对接口鉴权、数据校验、页面交互、依赖配置与样式问题给出排查方向和修复建议。9.5 测试、调试与部署辅助测试阶段可根据核心业务链路补充后端单元测试、API 集成测试和前端 Store/工具函数测试,重点覆盖:认证与权限、库存与预警、订单创建与状态流转、物流状态更新、批次追溯以及监管查询。部署与运维阶段,项目现有的部署脚本、Nginx 配置与 systemd 服务文件可作为自动化基础。CodeArts 可辅助检查部署命令、依赖安装、数据库初始化、前端构建产物发布、反向代理和服务守护配置,并根据验证结果回流到需求和设计文档,形成持续优化闭环。
  • [高校训练营] 基于华为码道(CodeArts)代码智能体开发的音乐分享平台
    基于华为云码道(CodeArts)的音乐共享平台开发——同济大学小学期课程实践一、项目概述1.1 项目简介本项目是一个基于华为云码道(CodeArts)代码智能体辅助开发的音乐共享平台,聚焦音乐内容管理、社区互动交流与个性化推荐三类核心能力。系统采用前后端分离架构,覆盖需求分析、系统设计、编码实现、联调测试与演示部署等完整开发流程,目标是构建一个可运行、可展示、可扩展的音乐社区平台。1.2 项目目标构建一个支持音乐上传/播放/搜索、用户社区互动、好友私聊、智能推荐等功能的音乐共享社区平台,要求:前后端分离架构,RESTful API设计完整的用户认证与权限控制多模块业务逻辑(音乐、社区、社交、推荐)可运行、可演示、可扩展1.3 技术选型层级技术选型理由前端React 18 + TypeScript + Vite + Ant Design 5 + Zustand组件化开发、类型安全、状态管理轻量后端Spring Boot 3 + MyBatis-Plus + JWT企业级框架、ORM简化、无状态认证数据库MySQL 8.0关系型数据、事务支持、成熟生态存储本地文件系统教学演示场景,避免OSS配置复杂度AI工具华为云码道(CodeArts)代码智能体课程指定开发工具1.4 项目链接视频演示:https://pan.quark.cn/s/e35f0aa3fe99项目源码仓库:https://github.com/rev2352350/music-sharing-platform二、AI辅助开发流程2.1 Day 1:需求分析与系统设计需求描述与补全在码道对话框中输入项目需求后,AI并非直接生成代码,而是首先执行需求补全——自动识别出原始需求中遗漏的关键设计决策:补全项说明优先级权限控制RBAC模型:普通用户/管理员,接口级权限校验P0隐私控制歌单公开/私密、下载记录仅自己可见P0文件上传限制音频≤50MB,格式限制MP3/WAV/FLAC/AACP0内容审核音乐上传需审核、举报机制P0分页与搜索统一分页参数、模糊搜索、多维度排序P1通知系统评论/好友/私聊通知P2在对话中输入"设计并实现一个音乐平台+音乐社区的Web项目,包含用户系统、音乐功能、搜索发现、收藏歌单、社区交流、智能推荐、管理后台、好友私聊、消息通知等功能"后,码道并未直接生成代码,而是首先对需求进行补全——自动识别出权限控制(RBAC)、隐私控制(歌单公开/私密)、文件上传限制、内容审核机制等原始需求中未明确的关键设计决策,并按P0/P1/P2优先级分类呈现。这一步的价值在于:AI充当了需求评审者的角色,帮助在编码前就识别出潜在的设计缺陷,避免了传统开发中"做到一半才发现遗漏"的问题。系统设计文档生成确认需求后,码道自动生成了一份结构化的系统设计文档(design.md),包含以下内容:数据库设计——17张业务表,完整的字段定义、约束和ER关系:User ──1:N──> Playlist ──M:N──> Music (via playlist_music) User ──1:N──> Collection ──N:1──> Music User ──1:N──> Rating ──N:1──> Music User ──1:N──> Comment ──N:1──> Music User ──1:N──> Post ──1:N──> PostComment User ──1:N──> Like (polymorphic: post/comment) User ──1:N──> Friendship ──1:N──> PrivateMessage Music ──M:N──> Tag (via music_tag) Music ──N:1──> CategoryAPI设计——8大模块、40+接口,统一的请求/响应规范:// 统一响应格式 { "code": 200, "message": "success", "data": {} } // 统一分页格式 { "total": 100, "pageNum": 1, "pageSize": 20, "list": [] } 推荐算法——基于标签相似度的个性化推荐,含冷启动降级策略。2.2 Day 2:核心功能编码后端实现基于设计文档,码道按照标准分层架构生成后端代码:com.music.platform/ ├── entity/ # 17个实体类(Music, User, Post, Friendship...) ├── dto/ # 请求DTO(MusicUploadDTO, PostDTO...) ├── vo/ # 响应VO(MusicVO, PostVO, ChatVO...) ├── mapper/ # MyBatis-Plus Mapper接口 ├── service/impl/ # 业务逻辑实现 ├── controller/ # REST控制器 ├── config/ # JWT拦截器、CORS、Security、上传配置 └── common/ # 统一响应R<T>、全局异常处理、UserContext后端按照标准分层架构组织代码:com.music.platform/ ├── entity/ # 17个实体类(Music, User, Post, Friendship...) ├── dto/ # 请求DTO(MusicUploadDTO, PostDTO...) ├── vo/ # 响应VO(MusicVO, PostVO, ChatVO...) ├── mapper/ # MyBatis-Plus Mapper接口 ├── service/impl/ # 业务逻辑实现 ├── controller/ # REST控制器 ├── config/ # JWT拦截器、CORS、Security、上传配置 └── common/ # 统一响应R<T>、全局异常处理、UserContext关键设计决策:JWT双Token机制:Access Token(30min)+ Refresh Token(7天),前端检测401自动刷新,避免用户频繁重新登录收藏/评分切换模式:重复操作自动取消而非报错,简化前端逻辑多态点赞:like_record表通过target_type字段支持动态和评论的统一点赞软删除:所有业务表使用deleted字段,保证数据可恢复前端实现前端采用React + Ant Design,码道生成了20+页面组件:页面核心功能首页热门推荐、最新上传、分类推荐歌曲详情播放、收藏、评分、歌词居中显示、评论、分享到社区社区动态发布动态、搜索选歌分享、评论、点赞个人主页动态、上传的歌曲、好友、歌单、收藏消息中心私聊窗口、通知列表、好友请求上传音乐音频+封面+歌词上传、分享到动态开关数据库初始化码道生成了完整的SQL脚本,包含建表语句和测试数据(5个用户、10首歌曲、分类标签、评论动态等)。2.3 Day 3:联调排错与功能迭代第三天是工作量最大的一天,主要处理运行时问题和功能增量开发。典型问题与解决问题1:PowerShell编码陷阱PowerShell的Set-Content默认使用GBK编码,导致Maven编译UTF-8源码时中文乱码。码道将中文消息字符串替换为英文,从根源上规避编码问题。问题2:类名冲突收藏实体类命名为Collection,与java.util.Collection冲突。码道将其重命名为UserCollection,并同步更新所有Mapper、Service、Controller中的引用。问题3:JWT认证401状态码被吞BusinessException(401)返回HTTP 200 + 业务码401,前端axios拦截器无法识别为认证失败。修改GlobalExceptionHandler,让401业务异常返回HTTP 401状态码:// GlobalExceptionHandler.java if (e.getCode() == 401) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } 前端配合实现Token自动刷新机制:检测到401响应时,用RefreshToken换取新AccessToken,自动重发原请求。问题4:文件位置与包名不一致JwtInterceptor.java文件放在interceptor目录下,但package声明为com.music.platform.config,导致运行时ClassNotFoundException。将文件移至config目录使其与包声明一致。问题5:歌词换行符处理MySQL存储的歌词中\n是字面量而非换行符,前端显示为一整行文本。解决方案:// 前端歌词渲染 music.lyrics.replace(/\\n/g, '\n').split('\n').map((line, i) => { const text = line.replace(/\[\d{2}:\d{2}\.\d{2,3}\]/g, '').trim() if (!text) return <div key={i} style={{ height: 16 }} /> return <div key={i}>{text}</div> }) 实现居中排版、去除时间标签、空行分段,达到类似百度音乐的歌词展示效果。问题6:BCrypt密码中的$符号PowerShell中BCrypt密码的$符号被解释为变量,直接命令行更新失败。改用SQL文件方式执行,避免Shell变量替换。功能迭代联调通过后,通过对话式需求描述进行增量开发:迭代需求描述实现内容好友系统“加好友、私聊”新增3张表(friendship, private_message, notification),完整的好友申请/同意/拒绝流程播放器增强“加进度条和音量控制”进度条、时间显示、音量滑块、单曲循环上传自动发动态“上传的歌自动分享到动态”MusicServiceImpl注入PostService,上传后自动创建动态,含"分享到动态"开关社区选歌分享“发布动态时可以选择歌曲”搜索选歌Select组件,动态关联musicId歌曲分享按钮“每首歌要有分享按钮”详情页分享按钮+配文弹窗,一键分享到社区个人主页上传tab“看到这个人上传的歌”新增/users/{id}/uploaded接口,Profile页面新增tab三、系统架构3.1 整体架构┌─────────────────────────────────────────────────┐ │ React SPA │ │ (Vite + Ant Design + Zustand + React Router) │ └──────────────────────┬──────────────────────────┘ │ HTTP/REST API (JWT Bearer) ┌──────────────────────▼──────────────────────────┐ │ Spring Boot 应用层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ │ │Controller│ │ Service │ │ Interceptor │ │ │ └────┬─────┘ └────┬─────┘ │ (JWT认证/权限) │ │ │ │ │ └──────────────────┘ │ │ ┌────▼─────┐ │ │ │ Mapper │ │ │ └────┬─────┘ │ └───────┼───────────────────────────────────────────┘ │ ┌────▼────┐ │ MySQL │ └─────────┘3.2 核心设计原则前后端分离:后端仅提供RESTful API,前端SPA独立部署JWT无状态认证:双Token机制,前端自动刷新统一响应格式:{code, message, data},全局异常处理软删除:所有业务表使用逻辑删除(deleted字段)审计字段:所有表包含created_at, updated_at四、项目成果4.1 功能完成度模块已实现功能状态用户注册、登录、退出、资料编辑、头像上传、个人主页✅音乐上传、播放、搜索、详情、收藏、评分、评论、歌词、分享✅歌单创建、编辑、删除、添加/移除歌曲、公开/私密✅社区发布动态、选歌分享、评论、点赞(切换模式)✅好友加好友、同意/拒绝、好友列表、状态查询✅私聊发送消息、聊天列表、聊天窗口✅通知评论通知、好友请求、私聊通知、全部已读✅推荐热门/最新/分类推荐、标签相似度个性化推荐✅管理用户管理、音乐审核、统计仪表盘✅播放器进度条、时间显示、音量控制、单曲循环✅4.2 代码规模模块文件数代码行数(估算)后端Java50+~8000行前端React/TS20+~5000行SQL脚本3~500行设计文档1~600行4.3 运行效果展示五、反思与改进5.1 AI辅助开发的有效性分析环节AI表现评价需求补全自动识别遗漏项(权限、隐私、审核)优秀——弥补了需求描述的不足架构设计生成完整设计文档(表结构、API、推荐算法)优秀——结构清晰,可直接作为开发蓝图代码生成分层架构、命名规范、业务逻辑完整良好——核心逻辑正确,但需运行验证运行排错能定位问题根因并给出修复方案良好——但Windows环境适配问题需人工判断功能迭代对话式增量开发,理解上下文良好——简单需求一次通过,复杂需求需多轮交互5.2 当前不足与改进方向功能层面:单元测试缺失:当前项目未编写自动化测试,依赖手动验证。后续应补充Service层单元测试和Controller层集成测试管理后台不完善:目前仅实现了基础的审核和统计功能,评论管理、动态管理、举报处理等尚未完整推荐算法较简单:当前基于标签相似度,后续可引入基于用户的协同过滤(User-CF)提升推荐质量工程层面:缺少Docker部署方案:目前依赖本地环境手动启动,应编写Docker Compose配置实现一键部署未接入Redis缓存:设计文档中规划了Redis用于会话管理和热门数据缓存,但因环境限制暂未实现前端状态管理可优化:部分页面存在重复请求,应引入缓存策略和请求去重机制安全层面:JWT黑名单未实现:当前Token签发后无法主动失效,应结合Redis实现Token黑名单文件上传安全:未对上传文件内容进行深度校验(如文件头验证),存在潜在安全风险SQL注入:MyBatis-Plus的LambdaQueryWrapper已参数化查询,但自定义SQL需注意5.3 与同类项目的对比与其他选题相比,音乐共享平台的特殊挑战在于:媒体文件处理:音频文件体积大(50MB+),需要考虑上传限制、流式播放、存储策略实时交互需求:私聊消息、通知推送等场景对实时性有要求,当前采用轮询方式,后续可引入WebSocket推荐系统复杂度:音乐推荐的冷启动问题比商品推荐更突出,因为用户行为数据更稀疏社区互动模式:动态+评论+点赞的多态交互设计,比简单的CRUD更复杂六、总结本项目通过华为云码道(CodeArts)代码智能体,在三天内完成了一个包含9大功能模块、17张数据库表、40+API接口的音乐共享平台。从实践来看,AI辅助开发在需求分析和代码生成环节效率提升显著,但在运行时排错和环境适配方面仍需开发者具备足够的技术判断力。AI编程工具并非"替代程序员",而是将开发者从重复性编码工作中解放出来,使其能将更多精力投入到架构决策、业务逻辑设计和质量保障上。对于课程项目而言,这种开发模式让学生能更关注软件工程的全流程理解,而非陷入语法细节的泥潭。项目信息:技术栈:Spring Boot 3 + React 18 + MySQL 8.0开发工具:华为云码道(CodeArts)代码智能体开发周期:3天代码规模:13000+行
  • [高校训练营] 银发智伴:基于华为云码道(CodeArts)代码智能体的智能体检报告应用
    一、概述1.1 案例介绍银发智伴(ElderlyCare AI) 是一款面向子女、老年家庭成员和应用后台管理员三类用户的智能体检报告管理应用。子女可在 PC 端上传父母的 PDF、JPG 或 PNG 体检报告,系统通过 OCR 识别、指标提取和大模型健康解读,将专业检验结果转换为通俗说明、健康建议和饮食计划;随后生成适老化 H5 分享链接与二维码,父母通过手机即可查看大字版报告并使用语音播报。后台管理员负责用户状态、角色、系统概览和审计信息管理,不参与用户报告内容的日常操作。本案例采用 FastAPI、Vue 3、SQLite、Redis、Nginx 和华为云 ECS 构建,集成华为云 OBS 与 OCR,并使用华为云码道(CodeArts)代码智能体完成需求分析、存量代码理解、任务拆解、增量开发和问题调试。应用还提供家庭成员管理、历年指标趋势、异常变化提醒、报告对比、分享密码、访问次数限制和后台治理,形成“报告上传、智能解析、健康解读、长期跟踪、适老分享、后台治理”的完整业务闭环。GitCode 源码与演示视频:https://gitcode.com/SDSXshlbz/elderlycare-ai本案例中的演示账号、家庭成员和体检指标均为合成数据,不对应任何真实个人。健康解读仅供参考,不构成医疗诊断建议。1.2 适用对象企业开发者个人开发者高校学生学习本案例前,建议具备 Python、JavaScript、Linux 常用命令和 HTTP API 的基础知识。1.3 案例时间本案例总时长预计90分钟,其中云资源准备约20分钟,项目配置与部署约40分钟,功能验证与资源清理约30分钟。1.4 案例流程[1. 准备云资源] | v [2. 配置项目与密钥] -> [3. 构建 PC/H5 前端和 FastAPI 后端] | v [5. H5适老分享] <- [4. OCR识别、指标提取与健康解读]说明:在华为云创建 ECS、VPC、安全组、EIP 和 OBS 桶,公网仅长期开放演示所需的 80 端口;准备华为云 AK/SK、OCR、OBS 和大模型配置,通过 .env 注入运行参数,不将密钥写入源码;将源码上传到 Ubuntu 22.04 ECS,执行 deploy_ecs.sh,自动安装依赖、构建两个前端并配置 Nginx、Redis 和 systemd;用户上传报告后,后端依次完成 OCR 降级识别、指标提取、风险判定、健康解读和饮食计划生成;子女在 PC 端查看趋势和对比结果,并生成带二维码、可选访问密码和语音播报的适老化 H5 分享页面。1.5 资源总览本案例使用按需计费资源,建议将完整体验控制在2小时内。不同区域和活动价格可能变化,实际费用以华为云控制台订单页为准。体验完成后请及时释放 ECS、EIP 和不再使用的 OBS 数据,避免产生多余费用。资源名称规格单价(元)弹性云服务器 ECS通用计算增强型 c7.large.2 | 2 vCPUs | 4 GiB | Ubuntu 22.04 Server | 40 GiB GPSSD以控制台实时价格为准弹性公网IP(Elastic IP,简称EIP)按流量计费 | 5Mbit/s按实际公网流量计费虚拟私有云 VPC 和安全组1个VPC、1个子网、1个安全组VPC和安全组本身免费对象存储服务 OBS标准存储,用于报告文件、二维码等对象按存储量与请求次数计费文字识别 OCR通用文字识别、通用表格识别按调用量计费或使用套餐包华为云码道(CodeArts)代码智能体通用体验版以开通页面为准阿里云百炼大模型 APIqwen-turbo、qwen-vl-ocr、qwen-vl-plus按模型调用量计费二、环境和资源准备2.1 购买华为云 ECS 弹性云服务器登录华为云控制台,依次进入 服务列表 > 计算 > 弹性云服务器 ECS,点击 购买弹性云服务器。计费模式选择 按需计费,区域选择 北京四 cn-north-4,规格选择 通用计算增强型 c7.large.2,2 vCPUs,4 GiB。镜像选择 Ubuntu Server 22.04 64bit,系统盘选择 40 GiB GPSSD。创建或选择 VPC 与子网,购买 5Mbit/s、按流量计费 的弹性公网 IP。创建安全组,长期入方向规则只放行 TCP/80。部署期间如需 SSH,可临时放行 TCP/22,并将源地址限制为管理员当前公网 IP,部署完成后立即删除 22 端口规则。点击 立即购买,确认按需资源并等待 ECS 状态变为“运行中”。记录 ECS 公网 IP,后文用 <ECS公网IP> 表示。关键节点说明:安全组只控制云侧入站流量,Nginx 仍需在实例内监听 80 端口。后端 Uvicorn 仅监听 127.0.0.1:8005,不能绕过 Nginx 直接从公网访问。2.2 准备华为云 OBS、OCR 和访问密钥进入 服务列表 > 存储 > 对象存储服务 OBS,创建私有桶,例如 elderlycare,区域需与 ECS 一致。进入 服务列表 > 人工智能 > 文字识别 OCR,开通通用文字识别和通用表格识别。点击控制台右上角用户名,进入 我的凭证 > 访问密钥,创建并妥善保存 AK/SK。在 我的凭证 > API凭证 中记录项目 ID,项目所属区域应为 cn-north-4。AK/SK 具有云资源访问权限,只能写入服务器上的 .env,不得提交到 Git、案例文档、截图或前端代码中。OBS 桶保持私有,文件由后端 SDK 访问。2.3 准备大模型与 OCR 降级服务登录阿里云百炼控制台,地址:https://dashscope.console.aliyun.com/,开通 DashScope 服务。在 API-KEY 管理 中创建 API Key,并确认账号可调用 qwen-turbo、qwen-vl-ocr 和 qwen-vl-plus。将 API Key 仅配置在 .env 中。项目首先调用华为云 OCR;若该调用失败,再依次尝试 qwen-vl-ocr 和 qwen-vl-plus,避免单一识别服务异常导致整条解析链路不可用。2.4 准备本地和云端环境本案例以 Windows 作为开发端、Ubuntu 作为运行端,建议环境如下:环境软件及版本用途Windows 10/11PowerShell 5.1+、OpenSSH Client、tar.exe源码检查、测试、打包和上传本地 PythonPython 3.10+,本案例测试环境为 Python 3.12后端测试本地 Node.jsNode.js 20、npm 10PC/H5 生产构建Ubuntu ECSUbuntu 22.04、Python 3.10、Node.js 20、Nginx、Redis演示环境运行执行以下命令复制配置模板:Copy-Item .env.example .env编辑 .env,将占位内容替换为实际配置。不要删除未使用的键,也不要在等号两侧添加多余引号:HUAWEI_CLOUD_AK=你的华为云AK HUAWEI_CLOUD_SK=你的华为云SK HUAWEI_CLOUD_REGION=cn-north-4 HUAWEI_CLOUD_PROJECT_ID=你的华为云项目ID OBS_BUCKET_NAME=elderlycare OBS_ENDPOINT=obs.cn-north-4.myhuaweicloud.com JWT_SECRET_KEY=至少32字节的随机字符串 REDIS_URL=redis://localhost:6379/0 DATABASE_URL=sqlite+aiosqlite:///./elderlycare.db MCP_SERVER_URL= LLM_API_KEY=你的千问APIKey LLM_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 LLM_MODEL_NAME=qwen-turbo ALIYUN_OCR_API_KEY=你的阿里云OCR_APIKey ALIYUN_OCR_MODEL=qwen-vl-ocr SHARE_BASE_URL=http://<ECS公网IP>/h5在 Windows PowerShell 中生成随机 JWT 密钥:$bytes = New-Object byte[] 48 [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes) [Convert]::ToBase64String($bytes) 三、构建银发智伴应用3.1 使用 CodeArts 代码智能体创建项目登录华为云码道(CodeArts),创建 Python + Vue 3 项目。在 CodeArts IDE 中输入以下需求描述,让代码智能体先理解目标和约束,再结合本案例存量源码进行增量开发:创建“银发智伴”体检报告管理应用。后端使用 Python FastAPI 和 SQLAlchemy Async,PC 端与 H5 端使用 Vue 3。子女在 PC 端上传父母体检报告,后端通过 OCR 提取指标,生成健康解读、饮食计划、趋势分析和报告对比;H5 使用大字号、清晰风险标签和中文语音播报。项目部署到 Ubuntu ECS,由 Nginx 统一提供 PC、H5 和 API 入口。本项目工作区保留了代码智能体生成并持续修订的规格、设计和任务文件,使用过程如下:阶段代码智能体产物或操作人工确认的关键节点需求规格化.codeartsdoer/specs/elderlycare_ai/spec.md明确子女、父母、管理员三类角色,以及“仅提供健康参考、不替代医生诊断”的职责边界存量代码分析.codeartsdoer/specs/elderlycare_ai/design.md对照现有认证、报告和分享模块,判断哪些功能复用、哪些功能增量扩展,避免大幅改变原有结构任务拆解.codeartsdoer/specs/elderlycare_ai/tasks.md将工作拆分为认证、报告、OCR、健康解读、分享、管理员、测试和部署等可验证任务代码开发根据任务逐个生成或补全 FastAPI 服务、Vue 页面和部署配置审查接口权限、异步数据库事务、上传限制、异常映射和前后端字段契约调试验证结合错误日志定位登录、复制、H5 子路径和 Ubuntu 兼容问题每次修复后执行后端测试、两个前端生产构建和 ECS 健康检查本案例使用代码智能体辅助完成的典型调试过程如下:登录错误调试:根据后端日志和认证服务调用链,发现错误凭据触发的业务异常未正确映射。修正空用户判断和异常处理器后,错误账号由 HTTP 500 变为 HTTP 401,并返回“账号或密码错误”;分享链接复制调试:公网演示环境使用 HTTP,浏览器可能禁用安全上下文中的 Clipboard API。智能体协助定位兼容性原因,并在 navigator.clipboard.writeText() 失败时使用 document.execCommand('copy') 回退;Windows 到 Ubuntu 迁移调试:检查 CRLF/LF、文件名大小写、依赖锁文件和路径分隔符;前端使用 npm ci 复现依赖,部署脚本保持 LF,源码导入路径与真实文件名大小写一致;H5 子路径调试:统一 Vite base: '/h5/'、Vue Router 的 import.meta.env.BASE_URL 与 Nginx try_files,解决分享深层路由刷新 404;验证闭环:本地运行 python -m pytest tests -q,分别执行 PC/H5 的 npm run build,部署后访问 /health,并验证登录、趋势、对比、分享和管理员接口。代码智能体用于加速分析、编码和定位问题,不能替代人工评审。代码生成后必须逐项检查权限边界、异常处理、上传限制、密钥加载、医疗免责声明和敏感信息,并通过测试及生产构建后才能部署。3.2 部署项目代码1)解决方案总体设计银发智伴采用“多端访问、统一 API、智能服务可降级、云上统一接入”的解决方案。PC 端承载报告管理、趋势对比和后台治理,H5 端专注适老化查看与语音播报;Nginx 提供统一公网入口,FastAPI 编排认证、报告、分享和智能解析流程;OBS 保存私有报告对象,SQLite 保存结构化业务数据,Redis 保存令牌黑名单和运行期状态。OCR 与大模型均设置超时、错误处理和本地降级,避免第三方服务短暂不可用时整个应用失效。用户上传报告后,请求依次经过文件校验、私有存储、OCR 识别、指标提取、风险判定、大模型健康解读和合规过滤;处理状态通过状态机管理。子女可在 PC 端查看结果、趋势和对比,也可生成带随机状态 ID、有效期、可选密码和访问次数限制的分享链接。父母通过 H5 查看大字版内容;管理员通过角色鉴权后的接口查看系统概览和管理用户。2)系统架构设计用户层:PC 子女端 / H5 父母端 / PC 管理后台 | 接入层:EIP + Nginx(/、/h5/、/api/、/health) | 应用层:FastAPI API / JWT认证 / 报告 / 分享 / 趋势 / 对比 / 管理 | 智能层:华为云OCR -> 百炼OCR -> Qwen VL / MCP大模型 / 合规工具 / 本地规则 | 数据层:SQLite业务数据 / Redis状态与令牌 / OBS私有对象 | 运维层:systemd / 健康检查 / 审计日志 / 华为云安全组架构关键点:公网只暴露 Nginx 的 80 端口,FastAPI 仅监听 127.0.0.1:8005;PC、H5 与 API 共用同一主机,减少跨域配置;智能服务通过统一服务层调用,业务 API 不直接依赖某一家模型厂商;配置和密钥全部由 .env 注入,仓库只提供不含真实值的 .env.example。核心技术难点与解决思路核心难点解决思路验证方式OCR 服务超时、配额不足或结果为空依次调用华为云 OCR、百炼 OCR 和 Qwen VL,仅在获得有效文本时结束;全失败时明确标记报告失败Mock 各级返回值,检查降级顺序和失败状态大模型输出不稳定且健康内容有合规风险传入结构化指标,以系统提示词约束输出;执行合规过滤并固定展示免责声明;调用失败时使用本地规则生成基础解读断开模型服务后仍能生成可查看的基础结果报告解析耗时,用户难以判断进度使用 OCR_PROCESSING、EXTRACTING、INTERPRETING、COMPLETED、FAILED 状态机,并通过 SSE 推送进度检查页面进度变化及异常后最终状态Windows 开发代码迁移到 Ubuntu锁定 Python/Node 依赖,使用 npm ci;Shell 脚本使用 LF;检查源码路径大小写,不使用 Windows 专属路径本地测试、双前端生产构建和 ECS 健康检查均通过H5 部署在 /h5/ 后深层路由刷新 404Vite base、Router base 和 Nginx try_files 使用一致的 /h5/ 前缀直接访问 /h5/share/<state_id> 返回 HTTP 200HTTP 演示站点复制分享链接失败优先使用 Clipboard API,失败时回退到隐藏文本框和 document.execCommand('copy')本地 HTTPS/localhost 与 ECS HTTP 环境分别点击复制医疗报告、账号和后台权限安全bcrypt 保存密码,JWT 鉴权,失败次数锁定,角色依赖保护管理员接口,OBS 私有存储并记录审计日志错误登录返回 401,普通用户访问管理员接口返回 4033)通过 GitCode 下载源码并了解项目结构本案例源码公开托管于 GitCode:https://gitcode.com/SDSXshlbz/elderlycare-ai。在 Windows PowerShell 或 Ubuntu 终端执行:git clone https://gitcode.com/SDSXshlbz/elderlycare-ai.git cd elderlycare-ai仓库不包含 .env、数据库、用户上传文件或真实医疗图片。克隆后需根据 .env.example 创建本地 .env 并填写自己的服务配置。项目结构如下:├── app/ # FastAPI后端 │ ├── api/ # 登录、报告、分享、趋势、对比等API路由 │ ├── core/ # 配置、数据库、安全、OBS、OCR、异常处理 │ ├── mcp/ # 大模型调用和本地工具降级 │ ├── models/ # SQLAlchemy ORM模型 │ ├── schemas/ # 请求和响应数据模型 │ ├── services/ # 认证、报告、解析、解读、分享等业务服务 │ └── main.py # FastAPI入口、路由和健康检查 ├── frontend/ │ ├── pc/ # 子女使用的PC端Vue 3应用 │ │ └── src/views/ # 工作台、详情、趋势、对比、家庭成员等页面 │ └── h5/ # 父母使用的适老化H5应用 │ └── src/views/SharePage.vue # 大字版健康报告和语音播报 ├── mcp_server/ # 可独立运行的模型编排与工具服务 ├── migrations/ # Alembic数据库版本记录 ├── tests/ # 后端单元测试与集成测试 ├── deploy_ecs.sh # Ubuntu ECS一键部署脚本 ├── requirements.txt # 固定版本的Python依赖 └── .env.example # 环境变量模板,不包含真实密钥 项目采用前后端分离和 API、服务、模型分层结构。浏览器请求先到 app/api/ 路由层,Pydantic app/schemas/ 完成输入输出校验,app/services/ 编排业务规则,app/models/ 通过异步 SQLAlchemy 持久化数据;OCR、OBS、安全和异常处理集中在 app/core/,模型调用与合规、营养、参考范围工具位于 app/mcp/。PC 与 H5 分别构建为静态文件,Nginx 将 / 映射到 PC,将 /h5/ 映射到 H5,将 /api/ 和 /health 反向代理到 FastAPI。4)在 Windows 本地执行构建与测试在项目根目录执行后端测试:.\.venv\Scripts\python.exe -m pytest tests -q预期结果:54 passed分别构建 PC 和 H5 生产包:Set-Location frontend\pc npm ci npm run build Set-Location ..\h5 npm ci npm run build Set-Location ..\.. npm ci 会严格按照 package-lock.json 安装依赖,避免 Windows 和 Ubuntu 使用不同依赖版本。两个 npm run build 均应成功生成各自的 dist 目录。PC 端构建时可能提示 ECharts 相关分块超过 Vite 默认的 500 KB 建议阈值,该提示不影响产物生成,后续可通过 manualChunks 进一步拆包。依赖审计警告不会阻断构建,但应单独评估,不建议直接执行可能引入破坏性升级的 npm audit fix --force。5)关键代码讲解OCR 三级降级机制(app/core/ocr_client.py)OCR 是报告解析的入口。代码先调用华为云通用文字和表格识别;如果没有识别到有效文本,再调用百炼 OCR 模型;最后使用千问 VL 多模态模型兜底。每一级仅在返回非空文本时结束链路,所有方法失败时返回空结果并由解析状态机标记失败。async def recognize_medical_report(self, image_data: bytes, file_type: str = "image") -> dict: image_b64 = base64.b64encode(image_data).decode("utf-8") result = await self._try_huawei_ocr(image_b64) if result: return result result = await self._try_aliyun_ocr(image_b64, file_type) if result: return result result = await self._try_qwen_vl(image_b64, file_type) if result: return result logger.error("All OCR methods failed (huawei -> aliyun -> qwen-vl)") return {"text": "", "confidence": 0.0} 关键释义:base64.b64encode() 将图片转为云 OCR API 可接收的 Base64 内容;降级调用相互独立,单个云服务超时或配额不足不会立即终止处理;日志只记录调用结果和错误,不输出图片、AK/SK 或 API Key;最终空文本不是伪造成功结果,业务层会将报告标记为 FAILED,便于用户重新处理。报告解析状态机和指标风险判定(app/services/parse_service.py)报告处理依次进入 OCR_PROCESSING、EXTRACTING、INTERPRETING 和 COMPLETED。前端根据状态显示处理进度;任何未捕获异常都会进入 FAILED,避免报告长期停留在处理中。await self._update_status(report, ParseStatus.OCR_PROCESSING) ocr_text = await self._run_ocr(report) if not ocr_text or not ocr_text.strip(): report.status = ParseStatus.FAILED await self.db.flush() return await self._update_status(report, ParseStatus.EXTRACTING) indicators = self._extract_indicators(ocr_text) abnormal = [i for i in indicators if i.status != IndicatorStatus.NORMAL] if abnormal: names = [i.name for i in abnormal[:5]] report.abnormal_summary = f"发现{len(abnormal)}项异常指标: {', '.join(names)}" await self._update_status(report, ParseStatus.INTERPRETING) report.status = ParseStatus.COMPLETED指标提取阶段会校验名称长度、医学单位、数值与参考范围。高于上限标记为 HIGH,低于下限标记为 LOW;偏离比例达到 1.2 或 1.5 时,风险等级依次提升为中风险或高风险。大模型健康解读与本地降级(app/mcp/mcp_client.py)后端使用 OpenAI 兼容接口调用配置的大模型,系统提示词约束输出范围,用户提示词携带结构化指标。HTTP 状态异常通过 raise_for_status() 进入异常分支;大模型不可用时,generate_interpretation() 会调用本地规则生成基础解读,保证报告仍可查看。async def _call_llm(self, system_prompt: str, user_prompt: str, temperature: float = 0.7) -> str: if not self._can_call_llm(): raise AppException(40004, "LLM API 未配置") async with httpx.AsyncClient(timeout=settings.LLM_TIMEOUT, proxy=None) as client: response = await client.post( f"{self._llm_api_base}/chat/completions", json={ "model": self._llm_model, "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], "temperature": temperature, }, headers={"Authorization": f"Bearer {self._llm_api_key}"}, ) response.raise_for_status() data = response.json() return data.get("choices", [{}])[0].get("message", {}).get("content", "") 登录失败返回业务错误而不是服务器内部错误(app/services/auth_service.py、app/core/exceptions.py)登录时先判断用户是否存在,再校验 bcrypt 密码。账号不存在或密码错误均抛出业务码 60003,统一异常处理器将其映射为 HTTP 401。这样错误凭据不会因为空用户访问、密码哈希异常或未处理业务异常而显示“服务器内部错误”。if user is None: raise AppException(60003, "账号或密码错误") if not verify_password(password, user.password_hash): user.login_fail_count += 1 if user.login_fail_count >= settings.LOGIN_MAX_FAILURES: user.status = AccountStatus.LOCKED user.locked_until = datetime.utcnow() + timedelta( minutes=settings.LOGIN_LOCK_MINUTES ) await self.db.flush() raise AppException( 60002, f"密码错误次数过多,账号已锁定{settings.LOGIN_LOCK_MINUTES}分钟", ) await self.db.flush() raise AppException( 60003, f"账号或密码错误,还剩{settings.LOGIN_MAX_FAILURES - user.login_fail_count}次机会", ) if exc.code in (60002, 50005): status_code = 429 elif exc.code in (60003, 60004): status_code = 401 连续失败达到阈值后账号临时锁定,可以降低暴力尝试风险;成功登录后失败次数会被清零,并签发访问令牌和刷新令牌。报告分享、二维码和访问限制(app/services/share_service.py)分享状态使用随机 UUID,默认30天有效。可选4位数字访问密码使用 bcrypt 哈希保存,数据库中不存储明文;同时支持访问次数上限、失败次数锁定和主动撤销。state_id = str(uuid.uuid4()) expire_time = datetime.utcnow() + timedelta( days=settings.SHARE_DEFAULT_EXPIRE_DAYS ) password_hash = None if access_password: if not access_password.isdigit() or len(access_password) != 4: raise AppException(10001, "访问密码需为4位数字") password_hash = _bcrypt.hashpw( access_password.encode("utf-8"), _bcrypt.gensalt() ).decode("utf-8") share_url = f"{settings.SHARE_BASE_URL}/share/{state_id}" qr = qrcode.QRCode(version=1, box_size=10, border=5) qr.add_data(share_url) qr.make(fit=True) H5 适老化语音播报(frontend/h5/src/views/SharePage.vue)H5 使用浏览器原生 Web Speech API,无需额外安装播放器。播报内容由健康解读、建议、注意事项和指标组成,语速设置为 0.8,优先选择中文语音;用户再次点击按钮时立即停止。function toggleSpeech() { if (!speechSupported.value) return const synth = window.speechSynthesis if (isSpeaking.value) { synth.cancel() isSpeaking.value = false return } speechUtterance = new SpeechSynthesisUtterance(getSpeechText()) speechUtterance.lang = 'zh-CN' speechUtterance.rate = 0.8 speechUtterance.pitch = 1.0 speechUtterance.volume = 1.0 synth.speak(speechUtterance) isSpeaking.value = true } H5 子路径适配(frontend/h5/vite.config.ts、frontend/h5/src/router/index.ts)生产环境将 H5 部署在 /h5/,构建资源路径和 Vue Router 必须使用同一个基础路径,否则在 Ubuntu Nginx 下刷新分享深层路由会出现资源 404 或空白页。export default defineConfig({ base: '/h5/', plugins: [vue()], }) const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/share/:stateId', name: 'SharePage', component: () => import('../views/SharePage.vue'), }, ], }) 6)打包并上传源码不要上传 .env 等本地敏感文件,也不要上传真实 elderlycare.db、测试数据库、医疗图片、.venv、node_modules 和 dist。在 Windows PowerShell 的项目根目录执行:tar.exe -czf elderlycare-deploy.tar.gz ` --exclude='.venv' ` --exclude='*/node_modules' ` --exclude='*/dist' ` --exclude='.env' ` --exclude='elderlycare.db' ` --exclude='test.db' ` --exclude='*.jpg' ` . scp .\elderlycare-deploy.tar.gz root@<ECS公网IP>:/tmp/ scp .\.env root@<ECS公网IP>:/tmp/elderlycare.env ssh root@<ECS公网IP> 如果使用 SSH 密钥,则在三个 SSH/SCP 命令中增加 -i <私钥路径>。上传完成后,在 ECS 中执行:sudo mkdir -p /opt/elderlycare sudo tar -xzf /tmp/elderlycare-deploy.tar.gz -C /opt/elderlycare sudo install -m 600 /tmp/elderlycare.env /opt/elderlycare/.env cd /opt/elderlycare sudo chmod +x deploy_ecs.sh sudo ./deploy_ecs.sh也可以先在 Windows PowerShell 中单独上传仅保存在本地的 .env:scp .\.env root@<ECS公网IP>:/tmp/elderlycare.env ssh root@<ECS公网IP> 登录 ECS 后,直接通过 GitCode 拉取公开源码并部署:/opt/elderlycare 是 Ubuntu ECS 上的绝对安装目录,不是 GitCode 仓库中的 opt 文件夹。git clone 命令的第二个参数会把仓库内容直接检出到该目录;后续部署脚本、Nginx 和 systemd 均统一使用此路径。sudo mkdir -p /opt/elderlycare sudo chown -R "$USER:$USER" /opt/elderlycare git clone https://gitcode.com/SDSXshlbz/elderlycare-ai.git /opt/elderlycare sudo install -m 600 /tmp/elderlycare.env /opt/elderlycare/.env cd /opt/elderlycare sudo chmod +x deploy_ecs.sh sudo ./deploy_ecs.sh关键节点说明:GitCode 只传输可公开的源码和合成演示截图,.env 必须沿独立安全通道上传。后续更新可在确认服务器无未提交修改后执行 git pull --ff-only,再重新运行 deploy_ecs.sh;数据库和用户上传文件应提前备份,不能用代码仓库代替业务数据备份。7)理解并执行一键部署脚本deploy_ecs.sh 使用 set -euo pipefail,任一关键命令失败都会终止部署。脚本执行七个阶段:安装系统依赖、准备运行用户、安装 Python 依赖、构建 PC/H5、配置 Nginx、注册 systemd 服务、执行健康检查。Nginx 的关键配置如下:location /h5/ { alias /opt/elderlycare/frontend/h5/dist/; index index.html; try_files $uri $uri/ /h5/index.html; } location /api/ { proxy_pass http://127.0.0.1:8005; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 120s; } location / { root /opt/elderlycare/frontend/pc/dist; index index.html; try_files $uri $uri/ /index.html; } try_files 是 PC 和 H5 深层路由刷新可用的关键。后端服务使用独立用户运行,并等待网络和 Redis:[Unit] After=network-online.target redis-server.service Wants=network-online.target redis-server.service [Service] User=elderlycare Group=elderlycare WorkingDirectory=/opt/elderlycare ExecStart=/opt/elderlycare/.venv/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8005 Restart=always RestartSec=5 脚本结束前会轮询后端健康接口。成功时输出:Backend health check passed. ======================================== Deployment completed PC: http://<ECS_PUBLIC_IP>/ H5: http://<ECS_PUBLIC_IP>/h5/ Health: http://<ECS_PUBLIC_IP>/health ========================================8)记录数据库版本并检查服务项目启动时通过 SQLAlchemy create_all() 创建当前模型表。首次部署成功后,执行 alembic stamp head 记录当前迁移基线,不重复执行已由模型创建的历史表结构:cd /opt/elderlycare source .venv/bin/activate alembic stamp head deactivate sudo nginx -t sudo systemctl is-active nginx redis-server elderlycare curl --fail http://127.0.0.1:8005/health预期结果:nginx: configuration file /etc/nginx/nginx.conf test is successful active active active {"status":"ok","version":"1.0.0"}如健康检查失败,使用以下命令定位问题:sudo journalctl -u elderlycare -n 100 --no-pager sudo tail -n 100 /var/log/nginx/error.log常见问题与处理方法:现象原因处理方法deploy_ecs.sh: /bin/bash^MWindows CRLF 换行将脚本保存为 LF 后重新上传H5 分享链接刷新后 404Vite 基础路径或 Nginx 回退错误检查 base: '/h5/' 和 /h5/index.html登录显示服务器内部错误业务异常未映射或数据库字段不完整查看 journalctl,确认 60003 返回 401,数据库版本已记录上传后一直处理中OCR、OBS 或大模型配置错误检查 .env、OBS 区域、OCR权限及后端日志CSS/模块在 Ubuntu 找不到Windows 文件名大小写不敏感统一源码导入路径与真实文件名大小写9)安全收尾部署完成后删除包含密钥的临时文件和部署压缩包,并在安全组中删除临时 22 端口规则:rm -f /tmp/elderlycare.env /tmp/elderlycare-deploy.tar.gz服务器上的 /opt/elderlycare/.env 权限应为 600,所有者应为 elderlycare:sudo stat -c '%U:%G %a %n' /opt/elderlycare/.env预期输出:elderlycare:elderlycare 600 /opt/elderlycare/.env3.3 运行效果展示本案例已部署到华为云北京四 ECS。演示环境仅使用合成数据,环境信息如下:项目演示环境信息区域北京四 cn-north-4ECS实例elderlycare-demo,实例ID 5d96458e-5a74-47e7-8859-b78c14be13a8规格与系统c7.large.2,2 vCPU / 4 GiB,Ubuntu 22.04公网IP1.92.111.234PC端URLhttp://1.92.111.234/H5端URLhttp://1.92.111.234/h5/健康检查http://1.92.111.234/health,HTTP 200GitCode源码https://gitcode.com/SDSXshlbz/elderlycare-ai普通功能测试账号邮箱:demo@elderlycare.cn密码:Demo2026!应用后台管理员测试账号邮箱:admin20260726@elderlycare.cn密码:Sc9!Vt4#Lq7@Hm2普通账号用于演示报告上传、解读、趋势、对比和分享;管理员账号登录后进入后台管理页面,用于演示系统概览、用户列表、账号状态和角色权限。演示 ECS 当前为运行状态,公网安全组不保留 SSH 入站规则,只开放作品 Web 演示所需端口。当前地址使用 HTTP,仅用于作品演示,不要录入真实个人信息、医疗报告或其他敏感数据。正式上线应配置域名、HTTPS、数据库备份、日志脱敏和监控告警。核心功能1:报告上传与年度报告管理登录后进入工作台,选择家庭成员后拖拽或点击上传 PDF、JPG、PNG 文件。页面同步展示解析状态和历史报告。演示账号已准备 2024、2025、2026 三份年度报告,用于展示长期健康变化。关键节点说明:上传请求先校验文件数量、扩展名和大小,再将报告与家庭成员关联。后端完成 OCR、指标提取和解读后,状态变为“已完成”,点击报告名称进入详情。核心功能2:智能健康解读与饮食计划报告详情将异常指标转换为通俗说明,展示风险提示、健康建议、推荐食物、忌口食物、每日食谱和指标参考范围。每份解读固定展示医疗免责声明。执行后效果:2026年度合成报告识别出空腹血糖、总胆固醇、尿酸、收缩压和 BMI 偏高,并给出饮食控制、运动、定期监测等建议;血红蛋白显示为正常。核心功能3:历次指标趋势和异常变化提醒进入 趋势分析,可以按家庭成员和指标筛选。ECharts 折线图按报告时间排序,并使用参考范围背景区间辅助判断。执行后效果:演示数据包含6个指标,每个指标有3个年度数据点。系统可识别“正常转异常”“异常恢复”“状态变化”和“数值变化”,当前演示数据生成12条异常变化记录。核心功能4:两份报告逐项对比进入 报告对比,选择较早报告 A 与较近报告 B,点击 开始对比。后端按指标名称求交集,计算 报告B数值 - 报告A数值,并按变化绝对值排序。执行后效果:2024与2026两份报告共有6项指标。尿酸由 330 umol/L 变为 455 umol/L,收缩压由 128 mmHg 变为 148 mmHg,状态从正常变为偏高;页面同时展示 BMI、空腹血糖、总胆固醇和血红蛋白的变化。核心功能5:适老化 H5 分享与语音播报在报告详情中生成分享链接或二维码,父母通过手机打开 H5。页面采用大字号、高行距、明显风险标签和大尺寸圆形播报按钮;点击播放按钮后,图标切换为暂停,再次点击立即停止。执行后效果:在 390 × 844 移动视口下页面无横向溢出,分享接口返回6项指标;语音播报可以正常开始与暂停,H5 深层路由及生产资源均返回 HTTP 200。核心功能6:家庭成员管理进入 家庭成员,可维护父母等家庭成员的关系、性别、出生日期、身高、体重、慢性病、过敏史、用药和备注。报告关联成员后,趋势与对比功能可以按成员筛选,避免多人报告混合统计。核心功能7:应用后台管理与角色权限管理员登录后可查看系统用户、报告和分享数量,按角色或账号状态筛选用户,并执行受保护的管理操作。注册页面不提供管理员角色选择,普通用户不能通过修改前端参数自行获得管理员权限;管理员接口由后端角色依赖统一保护,并具有禁止管理员自降级和最后一名管理员保护逻辑。执行后效果:管理员账号可进入 /admin 页面,普通演示账号访问同一路由时会被前端守卫拦截,直接请求管理员 API 时后端返回 HTTP 403。角色变更记录写入审计日志,便于追溯操作者、目标用户和变更时间。功能验收结果验证项实际结果正确账号登录HTTP 200,进入工作台错误账号登录HTTP 401,返回“账号或密码错误”,无服务器内部错误报告列表3份合成年度报告趋势分析6项指标,每项3个年度数据点异常变化12条变化记录报告对比6项共有指标及数值、状态变化H5分享返回健康解读、饮食计划和6项指标二维码返回 image/png管理员权限管理员可访问后台,普通用户访问管理员接口返回 HTTP 403PC/H5控制台无错误或警告Ubuntu服务Nginx、Redis、FastAPI均为 active自动化测试54 passed演示视频已上传至gitcode四、释放资源4.1 删除ECS弹性云服务器登录华为云控制台,进入 服务列表 > 计算 > 弹性云服务器 ECS。在 ECS 列表勾选本案例创建的服务器,点击 更多 > 删除。在确认对话框中勾选 释放云服务器绑定的弹性公网IP地址;如创建了额外数据盘,同时勾选删除对应数据盘。核对实例名称和公网 IP,确认无需要保留的数据后点击 是。进入 网络 > 弹性公网IP和带宽,确认 EIP 已释放;进入 对象存储服务 OBS,删除不再需要的报告、二维码和桶;进入安全组确认不存在遗留的公网 22 端口规则。删除 ECS、EIP、系统盘或 OBS 数据属于不可逆操作。释放前请先备份需要保留的源码、数据库和日志。仅关机通常仍会产生系统盘、EIP等费用,应以控制台资源状态和账单为准。五、扩展资料说明华为云 ECS:cid:link_2华为云 OBS:cid:link_4华为云 OCR:cid:link_1华为云开发者空间:cid:link_6华为云码道 CodeArts:cid:link_7银发智伴 GitCode 源码:https://gitcode.com/SDSXshlbz/elderlycare-aiFastAPI:https://fastapi.tiangolo.com/Vue 3:https://vuejs.org/Nginx:https://nginx.org/en/docs/阿里云百炼 Model Studio:https://help.aliyun.com/zh/model-studio/
  • [高校训练营] 基于华为云码道(CodeArts)代码智能体的电脑销售管理系统
    gitcode仓库链接:https://gitcode.com/dyx131313/computer-sales-system一、概述1.1 案例介绍在中关村电子市场的日常经营中,电脑销售门店通常同时面对品牌机销售、配件零售、兼容机组装、客户资料维护、订单结算与售后跟踪等多类业务。传统手工登记方式容易出现产品库存更新不及时、配件价格计算繁琐、客户订单记录分散、销售数据难以汇总等问题。本案例以“中关村电脑销售管理系统”为实践对象,使用华为云码道(CodeArts)代码智能体辅助完成从需求分析、系统设计、前后端代码生成、问题修复、界面优化到运行验证的完整应用构建过程。案例参考 AssetMgmt 固定资产管理系统系列案例的写法,将开发过程拆分为“码道搭台,设计筑基”和“码道领航,落地生根”两个阶段:前者强调需求、架构、数据模型和接口设计,后者强调代码落地、调试修复、功能验证和成果展示。系统最终实现品牌机产品管理、电脑配件管理、兼容机组装、客户管理、订单管理、仪表盘统计和智能推荐等功能,形成一套可运行、可演示、可说明的前后端分离 Web 应用。1.2 适用对象希望快速体验 CodeArts 代码智能体应用构建能力的高校学生;需要学习 Spring Boot + Vue 3 前后端分离项目落地流程的初学者;希望借助 AI IDE 完成管理系统原型构建和案例文档整理的个人开发者。1.3 案例目标目标说明真实场景建模围绕电脑销售门店的产品、配件、客户和订单业务建模AI 辅助开发使用华为云码道完成需求拆解、代码生成、调试修复和文档整理功能可运行前端页面、后端接口、数据库初始化和业务流程均可本地运行验证文档可复现记录关键对话、架构图、数据模型、接口清单、运行命令和截图成果可提交输出适用于训练营提交的应用构建案例文档和演示材料1.4 案例时间与资源本案例预计总时长约 4 小时,开发与演示阶段本地运行即可完成,预计资源花费 0 元。规格资源名称单价体验版华为云码道 CodeArts 代码智能体免费本地开发环境JDK、Maven、Node.js、npm免费演示数据库H2 内存数据库免费1.5 案例总流程整体流程如下:安装部署华为云码道(CodeArts)代码智能体;使用自然语言向码道描述电脑销售管理系统需求;在码道辅助下完成系统架构、数据模型和接口设计;生成并完善 Spring Boot 后端项目;生成并完善 Vue 3 前端项目;实现兼容机组装、订单结算、库存扣减和智能推荐等核心业务;解决跨域、实体命名、订单金额、库存事务等联调问题;启动系统,使用页面截图和接口测试验证功能。1.6 训练营要求对应关系训练营要求本案例对应成果使用华为云码道 CodeArts 代码智能体完成应用构建需求分析、架构设计、前后端代码、调试修复和文档整理均围绕码道展开输出应用构建案例文档本文档说明案例背景、系统设计、开发过程、关键难点、运行验证和成果展示核心功能可运行系统提供产品管理、配件管理、兼容机组装、客户管理、订单管理和智能推荐有关键节点文字说明与截图文档包含架构图、ER 图、业务流程图和系统运行截图突出关键代码释义和步骤说明文档列出实体设计、接口设计、事务逻辑和典型问题修复过程二、环境和资源准备2.1 华为云码道安装部署参考训练营指导书完成 Windows 版 AI IDE 华为云码道(CodeArts)代码智能体安装部署,并登录华为云账号。本案例使用码道智能体模式,通过连续对话完成项目生成、功能补全、错误修复和文档整理。2.2 本地开发环境工具版本用途JDK21后端 Java 运行环境Maven3.9.x后端依赖管理与项目构建Node.js22.x前端运行环境npm10.x前端依赖管理浏览器Edge / Chrome页面访问与效果验证华为云码道训练营版本AI 辅助编码、问答、调试、文档整理2.3 技术选型层次技术选择原因前端框架Vue 3 + Vite开发启动快,适合构建管理系统单页应用UI 组件库Element Plus表格、表单、弹窗、导航组件成熟HTTP 客户端Axios便于统一封装 REST API 调用后端框架Spring Boot 3.3.1适合快速构建 RESTful 服务数据访问Spring Data JPA降低 CRUD 与对象关系映射成本数据库H2便于本地演示和初始化样例数据AI 工具华为云码道 CodeArts用自然语言驱动需求拆解、代码生成和问题修复三、码道搭台:需求分析与系统设计3.1 向码道描述初始需求案例开发的第一步是将业务目标转化为清晰的自然语言提示。向码道输入如下需求:请帮我创建一个电脑销售管理系统,技术栈使用 Vue 3 + Spring Boot 前后端分离架构。系统需要以下功能模块:仪表盘:展示产品总数、配件总数、客户总数、订单总数等统计数据;产品管理:管理品牌机(笔记本、台式机、一体机)的增删改查;配件管理:管理内存、硬盘、机箱、键盘、鼠标、显示器等配件;兼容机组装:客户可自选配件组装兼容机,实时计算总价;客户管理:客户信息的增删改查;订单管理:支持品牌机购买和兼容机组装两种订单类型;智能推荐:基于客户历史消费数据生成个性化推荐方案。码道根据需求拆解出前后端分离架构、六类核心实体、REST API、页面路由、初始化数据和核心业务流程。这个过程类似 AssetMgmt 示例中的“设计筑基”阶段:先形成清晰规格,再进入代码实现。3.2 功能模块划分模块主要功能对应页面/接口仪表盘统计产品、配件、客户、订单、销售额Dashboard.vue、/api/dashboard/stats产品管理品牌机增删改查、库存维护Products.vue、/api/products配件管理配件增删改查、分类与兼容性维护Components.vue、/api/components兼容机组装分类选配件、实时计价、一键下单Assembly.vue、/api/orders客户管理客户资料维护、客户订单查询Customers.vue、/api/customers订单管理订单列表、订单项、状态流转Orders.vue、/api/orders智能推荐按客户消费生成推荐方案/api/recommendations/*3.3 系统架构设计系统采用前后端分离 B/S 架构,前端负责页面交互、数据展示和实时计价,后端负责业务校验、事务处理、库存扣减和数据持久化。下图由系统设计说明书中的 Mermaid 源图导出,便于在案例文档和报告中直接展示。3.4 数据模型设计系统核心实体包括 Product、PcComponent、Customer、Order、OrderItem 和 Recommendation。其中 OrderItem 通过 itemType 区分品牌机产品项和配件项,使品牌机购买和兼容机组装两类业务能够共用订单模型。核心实体说明如下:实体表名作用Productproducts存储品牌机信息PcComponentcomponents存储配件信息Customercustomers存储客户资料Orderorders存储订单主表OrderItemorder_items存储订单明细Recommendationrecommendations存储客户推荐方案3.5 接口设计模块接口方法说明健康检查/api/healthGET检查后端服务状态仪表盘/api/dashboard/statsGET获取统计数据产品/api/productsGET/POST查询或新增产品产品/api/products/{id}GET/PUT/DELETE查看、更新或删除产品配件/api/componentsGET/POST查询或新增配件配件/api/components/{id}GET/PUT/DELETE查看、更新或删除配件客户/api/customersGET/POST查询或新增客户客户/api/customers/{id}GET/PUT/DELETE查看、更新或删除客户订单/api/ordersGET/POST查询或创建订单订单/api/orders/{id}/itemsGET查询订单项订单/api/orders/{id}/statusPUT更新订单状态推荐/api/recommendations/generate/{customerId}POST生成客户推荐四、码道领航:代码落地与功能实现4.1 后端项目生成向码道输入后端开发提示:请帮我搭建 Spring Boot 3.3 后端项目,使用 Spring Data JPA 和 H2 数据库,创建完整的实体类、DTO、Repository、Service 和 Controller,并配置 CORS、全局异常处理和初始化数据。码道生成的后端任务规划包括:创建 pom.xml 与 application.yml;创建 Product、PcComponent、Customer、Order、OrderItem、Recommendation 实体;创建请求 DTO;创建 Repository 数据访问层;创建 Service 业务层及实现类;创建 Controller REST API;配置 WebConfig、GlobalExceptionHandler 和 DataInitializer。关键实体示例:@Entity @Table(name = "orders") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long customerId; private String orderType; // BRANDED / ASSEMBLY private BigDecimal totalAmount; private String status; // PENDING / PROCESSING / COMPLETED / CANCELLED private String remark; private LocalDateTime createdAt; private LocalDateTime updatedAt; } 后端实现重点是订单创建逻辑。创建订单时,系统需要校验客户、产品或配件是否存在,检查库存是否充足,保存订单项,计算订单总额并扣减库存。这一逻辑放在 Service 层并使用事务保证一致性。4.2 前端项目生成向码道输入前端开发提示:请帮我搭建 Vue 3 前端项目,使用 Element Plus、Vue Router、Axios 和 Vite,创建后台管理布局、业务页面、API 调用模块和路由配置。码道生成的前端结构包括:文件/目录作用src/main.jsVue 应用入口src/router/index.js路由配置src/api/index.jsAxios 实例src/api/modules.js产品、配件、客户、订单等 API 函数src/views/Layout.vue后台管理布局src/views/Dashboard.vue仪表盘页面src/views/Products.vue产品管理页面src/views/Components.vue配件管理页面src/views/Assembly.vue兼容机组装页面src/views/Customers.vue客户管理页面src/views/Orders.vue订单管理页面前端 API 封装示例:export const getProducts = (params) => api.get('/products', { params }) export const createProduct = (data) => api.post('/products', data) export const updateProduct = (id, data) => api.put(`/products/${id}`, data) export const deleteProduct = (id) => api.delete(`/products/${id}`) export const createOrder = (data) => api.post('/orders', data) export const updateOrderStatus = (id, status) => api.put(`/orders/${id}/status`, null, { params: { status } }) 4.3 核心功能:兼容机组装兼容机组装是本项目区别于普通 CRUD 管理系统的核心功能。页面左侧按内存、硬盘、机箱、键盘、鼠标、显示器六类配件展示可选项,右侧实时显示组装清单和总价。用户确认后选择客户并提交组装订单。关键实现思路:前端加载全部配件,并按 category 分组;每个分类使用单选控件选择一项配件;使用 Vue computed 汇总已选配件和总价;提交时构造 OrderRequest,订单类型为 ASSEMBLY;后端逐项校验配件库存,并在事务中保存订单与订单项。4.4 智能推荐功能智能推荐模块基于客户历史消费金额生成规则型推荐方案。当前实现分为三类:客户类型判断依据推荐策略VIP 客户累计消费较高推荐高端升级方案办公客户中等消费水平推荐办公效率套装新客户历史消费较少或无订单推荐入门级组装方案该模块虽然不是复杂机器学习模型,但能体现系统从“业务记录”向“销售辅助”延伸的能力,也为后续接入大模型或协同过滤算法预留了扩展空间。4.5 UI 美化在基础功能完成后,继续对前端界面进行美化:侧边栏采用深色渐变背景,突出后台系统风格;仪表盘统计卡片使用渐变色与图标增强识别度;表格操作按钮统一为查看、编辑、删除等常见交互;兼容机组装页面采用左右分栏结构,降低用户认知成本;表单弹窗使用 Element Plus Dialog,保持交互一致。五、关键技术难点与解决思路参考 AssetMgmt 落地案例的写法,本节将开发中遇到的问题整理为“问题 - 原因 - 修复方式 - 结果”的闭环。问题原因解决方式结果CORS 跨域访问失败前端 5173 端口访问后端 8080 端口,被浏览器跨域策略拦截前端配置 Vite proxy,后端新增 WebConfig 配置允许来源前端可正常调用后端 APIComponent 命名冲突配件实体名与 Spring @Component 注解容易混淆将实体命名为 PcComponent代码语义更清晰,避免导入错误Lombok 注解处理失败Maven 编译器未显式配置注解处理器在 maven-compiler-plugin 中配置 Lombok annotationProcessorPathsGetter/Setter/Builder 等正常生成订单金额为空订单初次保存时 totalAmount 尚未计算,触发非空约束保存前设置 BigDecimal.ZERO,订单项计算完成后更新总金额订单创建流程正常库存一致性风险订单创建涉及订单、订单项、产品/配件库存多表更新在 Service 层使用 @Transactional,异常时回滚库存不足时不会产生脏数据六、系统启动与验证6.1 启动后端cd backend set JAVA_HOME=D:\JAVA\jdk-21.0.4.7-hotspot mvn spring-boot:run后端默认运行在:http://localhost:8080健康检查:curl http://localhost:8080/api/health预期返回:{"status":"UP","service":"Computer Sales System"} 6.2 启动前端cd frontend npm install npm run dev前端默认运行在:http://localhost:51736.3 页面功能验证6.3.1 仪表盘仪表盘展示产品总数、配件总数、客户总数、订单总数等统计数据,并提供快捷操作入口。6.3.2 产品管理产品管理页面支持品牌机的新增、编辑、删除和查询,字段包括产品名称、品牌、类型、价格和库存。6.3.3 配件管理配件管理页面支持内存、硬盘、机箱、键盘、鼠标、显示器等配件维护。6.3.4 兼容机组装兼容机组装页面左侧展示配件分类,右侧实时展示组装清单和总价,是系统最具业务特色的功能。6.3.5 客户管理客户管理页面维护客户姓名、手机号、邮箱和地址等基础信息。6.3.6 订单管理订单管理页面展示品牌机订单和兼容机组装订单,并支持订单状态流转和订单详情查看。6.4 API 验证# 获取仪表盘统计 curl http://localhost:8080/api/dashboard/stats # 获取产品列表 curl http://localhost:8080/api/products # 创建客户 curl -X POST http://localhost:8080/api/customers ^ -H "Content-Type: application/json" ^ -d "{\"name\":\"张三\",\"phone\":\"13800138000\",\"email\":\"zhangsan@test.com\",\"address\":\"北京\"}" # 创建品牌机订单 curl -X POST http://localhost:8080/api/orders ^ -H "Content-Type: application/json" ^ -d "{\"customerId\":1,\"orderType\":\"BRANDED\",\"remark\":\"购买ThinkPad\",\"items\":[{\"productId\":1,\"itemType\":\"PRODUCT\",\"quantity\":1}]}" # 生成客户推荐 curl -X POST http://localhost:8080/api/recommendations/generate/1七、项目结构与成果文件7.1 项目目录computer-sales-system/ ├── backend/ │ ├── pom.xml │ └── src/main/java/com/computersales/ │ ├── ComputerSalesApplication.java │ ├── config/ │ │ ├── WebConfig.java │ │ ├── DataInitializer.java │ │ └── GlobalExceptionHandler.java │ ├── controller/ │ ├── dto/ │ ├── entity/ │ ├── repository/ │ └── service/ ├── frontend/ │ ├── package.json │ ├── vite.config.js │ └── src/ │ ├── api/ │ ├── router/ │ ├── style.css │ └── views/ ├── docs/ │ ├── demo/ └── README.md7.2 成果文件文件说明docs/应用构建案例文档.md本案例文档docs/系统设计说明书.md系统架构、数据模型、接口、部署与验收说明docs/mermaid_exports/*.png从 Mermaid 导出的架构图、ER 图和流程图docs/screenshots/*.png系统运行截图docs/专业集中实习报告-模板重构版-含架构图和截图.docx集中实习报告推荐提交版docs/实习日记本-模板重构版.docx实习日记本推荐提交版八、总结与展望8.1 项目成果总结本案例完成了一套可运行的电脑销售管理系统,实现了从产品资料维护、配件资料维护、客户管理到订单结算的完整流程。其中,兼容机组装功能体现了电脑销售门店的实际业务特色,智能推荐模块则为后续销售辅助提供了扩展方向。与普通手写项目相比,华为云码道 CodeArts 在本案例中主要发挥了四方面价值:需求拆解更快:通过自然语言快速形成模块划分、实体设计和接口规划;代码生成更快:后端分层结构和前端页面组件可快速生成;问题修复更快:跨域、Lombok、命名冲突、订单金额等问题能快速定位;文档整理更完整:能够辅助形成案例说明、系统设计、运行验证和成果总结。8.2 后续优化方向将 H2 数据库迁移至 MySQL 或 PostgreSQL,实现数据持久化;部署至华为云 ECS 或开发者空间,提供公网演示链接;增加用户登录、角色权限和操作日志;接入 ECharts 展示销售趋势、品类占比和客户消费分层;将规则型智能推荐升级为大模型辅助推荐或协同过滤推荐。本项目由华为云码道(CodeArts)代码智能体辅助开发
总条数:697 到第
上滑加载中