-
一、概述1.1 案例介绍考研备考管家是一款面向考研学子的 AI 智能学习管理网站,覆盖数学一、英语一、政治、408计算机基础四门统考科目,提供知识图谱追踪、刷题记录、艾宾浩斯错题复习、智能排期、AI 管家对话、专注计时等一站式备考功能。前端采用 Vue3 + Element Plus 手绘手账风格,后端采用 Flask + SQLite + DeepSeek 大模型,全栈可一键构建运行。项目地址:https://github.com/LeoMay23/ExamPreparationDEMO展示:https://www.bilibili.com/video/BV1MpKh6nEJr/?spm_id_from=333.1387.upload.video_card.click&vd_source=69e3b625d4662860466dccf85672cf571.2 适用对象高校学生个人开发者1.3 案例时间本案例总时长预计100分钟。1.4 案例流程说明:环境准备:安装 Node.js、Python,配置 DeepSeek 大模型 API Key;后端构建:安装 Python 依赖,初始化 SQLite 数据库与知识点种子数据,启动 Flask 服务;前端构建:安装 npm 依赖,配置 Vite 代理,构建并启动 Vue3 开发服务器;功能体验:注册登录 → 考研档案 → 仪表盘 → 科目中心 → 刷题记录 → 错题本 → 智能计划 → AI 管家 → 专注学习 → 复盘中心。1.5 资源总览本案例预计花费10元。所有依赖均为开源免费软件,大模型 API 可使用 DeepSeek 免费额度。资源名称规格单价(元)Node.jsv22.x免费Python3.10+免费DeepSeek APIdeepseek-v4-pro10元华为云码道(CodeArts)代码智能体专业版代金券兑换二、环境和资源准备2.1 安装 Node.js 与 Python确保本地已安装:Node.js v18+(推荐 v22.x),下载地址:cid:link_1Python 3.10+,下载地址:cid:link_0验证安装:node --version python --version 2.2 配置 DeepSeek 大模型 API Key注册 DeepSeek 开放平台账号在「API Keys」页面创建新的 API Key,复制保存。在项目 backend/ 目录下创建 .env 文件,填入以下内容:DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_AUTH_TOKEN=sk-xxxxxxxxxxxxxxxxxxxxxxxx DEEPSEEK_MODEL=deepseek-v4-pro2.3 获取项目代码将项目代码下载到本地工作目录:git clone <项目仓库地址> ExamPreparation cd ExamPreparation三、构建考研备考管家应用3.1 项目结构说明ExamPreparation/ ├── backend/ # Flask 后端 │ ├── app.py # 应用入口,注册蓝图 │ ├── config.py # 配置(DB路径、DeepSeek API) │ ├── database.py # 数据库表定义 + 种子数据 + 迁移 │ ├── requirements.txt # Python 依赖 │ ├── .env # 环境变量(API Key 等) │ ├── agent/ # AI Agent 模块 │ │ ├── llm_client.py # DeepSeek LLM 客户端 │ │ ├── orchestrator.py # Agent 编排器 │ │ ├── prompts.py # Prompt 模板 │ │ ├── tool_registry.py # 工具注册 │ │ └── tool_executor.py # 工具执行器 │ ├── planner/ # 排期引擎 │ │ ├── scheduler.py # 6维权重4阶段排期算法 │ │ └── time_slot.py # 空闲时段计算 │ ├── routes/ # API 路由(11个蓝图) │ │ ├── auth.py # 用户注册/登录/档案 │ │ ├── subjects.py # 科目中心(14个端点) │ │ ├── mistakes.py # 错题本 │ │ ├── plans.py # 智能计划 │ │ ├── chat.py # AI 管家对话 │ │ ├── sessions.py # 专注学习 Session │ │ └── ... │ └── services/ # 业务逻辑层 │ ├── subject_service.py # 科目中心(知识树/刷题/词汇/背诵/算法) │ ├── mistake_service.py # 错题本(艾宾浩斯复习) │ ├── planner_service.py # 计划服务(生成/延后/提前/锁定) │ ├── ai_butler_service.py# AI管家(今日概览/提醒/专注建议) │ ├── user_service.py # 用户系统 │ └── ... ├── web/ # Vue3 前端 │ ├── package.json # npm 依赖 │ ├── vite.config.js # Vite 配置(代理 /api → localhost:5000) │ └── src/ │ ├── main.js # 应用入口 │ ├── assets/main.css # 全局手绘风格 CSS │ ├── router/index.js # 路由(15个页面 + 守卫) │ ├── stores/ # Pinia 状态管理 │ │ ├── user.js # 用户状态(登录/档案/倒计时) │ │ ├── subject.js # 科目状态(知识树/统计/刷题) │ │ └── mistake.js # 错题状态 │ ├── utils/api.js # Axios 封装(拦截器注入 user_id/token) │ ├── components/ │ │ └── layout/MainLayout.vue # 侧边栏 + 主内容区 │ └── views/ # 15个页面 │ ├── Login.vue # 登录注册 │ ├── Onboarding.vue # 考研档案 │ ├── Dashboard.vue # 仪表盘(倒计时+4科卡片+今日计划+错题) │ ├── Subjects.vue # 科目中心入口 │ ├── math/MathIndex.vue # 数学一 │ ├── english/EnglishIndex.vue # 英语一 │ ├── politics/PoliticsIndex.vue # 政治 │ ├── cs408/Cs408Index.vue # 408 │ ├── Plan.vue # 智能计划 │ ├── Chat.vue # AI 管家 │ ├── Focus.vue # 专注学习 │ ├── Mistakes.vue # 错题本 │ ├── Review.vue # 复盘中心 │ ├── Tasks.vue # 计划管理 │ └── Settings.vue # 设置 └── HLD-KaoyanPrep-Website-20260710.md # HLD 设计文档 3.2 后端:安装依赖并启动服务步骤1:进入后端目录,安装 Python 依赖:cd backend pip install -r requirements.txtrequirements.txt 内容如下:Flask==3.0.3 flask-cors==4.0.1 requests==2.32.3 python-dotenv步骤2:启动 Flask 服务:python app.py启动成功后,服务运行在 http://localhost:5000。首次启动时会自动:创建 SQLite 数据库 aiplanpal.db建立全部 25 张表插入知识点种子数据(数学64个、政治32个、408共55个节点)关键代码讲解:数据库初始化与种子数据backend/database.py 中的 init_db() 函数负责数据库的创建与迁移:def init_db(): with closing(sqlite3.connect(DB_PATH)) as conn: conn.row_factory = sqlite3.Row conn.execute("PRAGMA foreign_keys = ON") create_tables(conn) # 创建全部25张表 migrate_existing_tables(conn) # 迁移旧表结构 + 种子数据 conn.commit() 考研专用表包括:表名用途math_knowledge_nodes数学知识点(高数/线代/概率论,64个节点)math_practice_records数学刷题记录english_vocabulary_progress英语词汇复习进度(艾宾浩斯间隔)english_reading_records英语阅读训练记录english_writing_records英语写作记录politics_knowledge_nodes政治知识点(马原/毛中特/史纲/思修,32个节点)politics_choice_records政治选择题记录politics_memorization_progress政治背诵进度cs408_knowledge_nodes408知识点(数据结构/计组/OS/网络,55个节点)cs408_practice_records408刷题记录cs408_algorithm_records408算法训练记录mistake_records错题本(艾宾浩斯复习)种子数据示例——数学知识点在 _seed_knowledge_nodes() 中批量插入:math_nodes = [ ("higher_math", "函数与极限", "函数的概念", 2, "core", "unstarted", 3.0), ("higher_math", "函数与极限", "极限的概念与性质", 3, "core", "unstarted", 4.0), ("higher_math", "一元微分学", "微分中值定理", 5, "core", "unstarted", 6.0), # ... 共64个节点 ] conn.executemany( "INSERT INTO math_knowledge_nodes (subject, chapter, section, difficulty, importance, mastery, estimated_hours) VALUES (?, ?, ?, ?, ?, ?, ?)", math_nodes, ) 关键代码讲解:DeepSeek LLM 客户端backend/agent/llm_client.py 封装了与大模型的交互,支持普通对话和 JSON 结构化输出:def chat_completion(messages, max_tokens=900, temperature=0.2, response_format=None, timeout_seconds=45): if not DEEPSEEK_AUTH_TOKEN: raise LLMUnavailableError("DEEPSEEK_AUTH_TOKEN is not configured") payload = { "model": DEEPSEEK_MODEL, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, } if response_format: payload["response_format"] = response_format response = requests.post( f"{DEEPSEEK_BASE_URL.rstrip('/')}/chat/completions", headers={ "Authorization": f"Bearer {DEEPSEEK_AUTH_TOKEN}", "Content-Type": "application/json", }, json=payload, timeout=timeout_seconds, ) response.raise_for_status() # ... 解析返回 降级策略:当 DEEPSEEK_AUTH_TOKEN 未配置时,所有 AI 功能会自动降级为本地规则引擎,不会报错阻断服务。关键代码讲解:智能排期引擎backend/services/planner_service.py 中的 generate_plans() 实现了6维权重4阶段的动态排期:def generate_plans(user_id=DEFAULT_USER_ID): tasks = fetch_tasks(user_id) if not tasks: # 无任务时自动创建8个默认考研任务 default_tasks = [ ("高数极限与连续刷题", "math", 90, "4", 3), ("英语阅读理解训练", "english", 60, "3", 2), ("政治马原选择题", "politics", 45, "3", 2), ("408数据结构算法练习", "cs408", 60, "4", 3), # ... 共8个 ] for title, task_type, est_min, priority, difficulty in default_tasks: db.execute("INSERT INTO tasks (...) VALUES (...)") # 删除未锁定的旧计划,保留用户锁定的计划 db.execute("DELETE FROM study_plans WHERE user_id = ? AND locked = 0 AND status IN (...)") # 调用排期算法生成新计划 generated = schedule_tasks(tasks, courses, existing_plans=locked_plans, days=7) 排期策略:schedule_tasks() 综合考虑任务优先级、难度、截止时间、课表冲突、用户偏好时段和当前备考阶段(基础/强化/冲刺/模考)6个维度,自动生成7天学习计划。3.3 前端:安装依赖并启动开发服务器步骤1:进入前端目录,安装 npm 依赖:cd web npm install 步骤2:启动 Vite 开发服务器:npm run dev启动成功后,浏览器访问 http://localhost:3000。关键代码讲解:全局手绘风格 CSSweb/src/assets/main.css 定义了整套手绘手账风格的设计令牌::root { --ink: #171717; /* 墨黑:边框、文字 */ --paper: #f7eed7; /* 网格纸背景 */ --cream: #fff7e8; /* 奶油白卡片 */ --yellow: #f8d46b; /* 黄色强调 */ --blue: #86b7d9; /* 蓝色强调 */ --red: #e1452d; /* 红色强调 */ --green: #4c9b54; /* 绿色强调 */ --border-thick: 4px solid var(--ink); /* 粗黑边 */ --shadow: 6px 6px 0 var(--ink); /* 偏移投影 */ --radius: 16px; /* 大圆角 */ --radius-pill: 999px; /* 药丸圆角 */ --color-math: #4A90D9; /* 数学蓝 */ --color-english: #7B68EE; /* 英语紫 */ --color-politics: #e1452d; /* 政治红 */ --color-cs408: #4c9b54; /* 408绿 */ } 网格纸背景通过 CSS 渐变实现:body { background: linear-gradient(90deg, rgba(23,23,23,0.03) 1px, transparent 1px), linear-gradient(0deg, rgba(23,23,23,0.025) 1px, transparent 1px), var(--paper); background-size: 24px 24px; } 关键代码讲解:AI 管家对话与确认卡片web/src/views/Chat.vue 实现了 AI 管家对话界面,支持确认卡片(confirm_card)交互:<div v-if="msg.confirmCard" class="confirm-card"> <div class="confirm-title">{{ msg.confirmCard.title }}</div> <div class="confirm-summary">{{ msg.confirmCard.summary }}</div> <ul v-if="msg.confirmCard.details?.length" class="confirm-details"> <li v-for="(d, di) in msg.confirmCard.details" :key="di">{{ d }}</li> </ul> <div class="confirm-actions"> <el-button v-for="(action, ai) in msg.confirmCard.actions" :key="ai" :type="ai === 0 ? 'primary' : 'default'" size="small" @click="handleConfirm(msg.confirmCard, action, i)" :disabled="msg.confirmed"> {{ action }} </el-button> </div> </div> 交互流程:用户发送消息 → 后端 Agent 分析意图 → 如果需要执行操作(如生成计划),返回 confirm_card → 用户点击确认 → 前端发送 confirmed_tool → 后端执行操作并返回结果。3.4 构建生产版本前端构建生产版本:cd web npm run build构建成功后,静态文件输出到 web/dist/ 目录,可直接部署到任何静态服务器。后端无需额外构建步骤,直接运行 python app.py 即可。3.5 运行效果展示登录注册页面用户首次访问时进入登录页面,支持注册和登录。页面采用居中布局,手绘风格卡片和药丸按钮。考研档案登录后进入考研档案页面,设置目标院校、专业、考研日期(日期选择器)、当前阶段、每日可用时间等。仪表盘仪表盘是用户首页,核心展示:考研倒计时:大号数字显示距考研天数,右侧显示当前阶段和考试日期四科进度卡片:数学/英语/政治/408 各一张卡片,显示掌握进度和正确率,点击进入对应科目今日计划:展示当天学习块列表,支持一键生成待复习错题:展示最近5条待复习错题AI 管家:显示今日概览和建议科目中心科目中心入口展示四门科目的卡片,每张卡片带有科目色带、图标和简介,hover 时有手绘风格的旋转偏移动画。数学一页面数学一页面包含三个 Tab:知识图谱:按高数/线代/概率论分组展示知识点,每个知识点可设置掌握度(未开始/学习中/已练习/已掌握)刷题记录:表单录入题源、题号、知识点、结果、耗时、错误类型统计:展示总刷题数、正确率、知识点掌握分布(进度条)、最近20条刷题记录(药丸标签)英语一页面英语一页面包含四个 Tab:词汇管理:展示今日待复习词汇,支持艾宾浩斯间隔复习阅读训练:录入年份、篇号、正确数、耗时写作工坊:录入作文类型、题目、内容统计:展示阅读篇数、写作篇数、最近阅读记录、最近写作记录政治页面政治页面包含三个 Tab:知识框架:按马原/毛中特/史纲/思修/时政分组,标注核心考点和考试频率选择题训练:录入题源、题号、单选/多选、结果、错误类型背诵管理:今日待背诵内容,支持艾宾浩斯间隔复习统计:展示选择题总数、正确率、最近选择题记录408计算机基础页面408页面包含四个 Tab:知识图谱:按数据结构/计组/OS/网络分组,标注算法类知识点刷题记录:录入子科目、题源、题号、题型、结果、耗时算法训练:录入算法名、语言、代码、时间/空间复杂度统计:展示刷题总数、正确率、算法题数、最近刷题记录、最近算法记录错题本错题本页面功能完整:筛选栏:按科目和掌握状态筛选统计药丸:总错题、已掌握、未掌握、今日待复习错题卡片列表:左侧色带标识科目,展示题目内容、题源、错误类型、复习次数操作按钮:复习(艾宾浩斯)、已掌握详情弹窗:展示题目内容、我的答案、正确答案、解析添加错题弹窗:手动录入完整错题信息自动创建:在数学/政治/408刷题时,答错的题目会自动创建错题记录。智能计划智能计划页面展示7天学习计划,支持:一键生成计划(6维权重4阶段排期算法)开始/完成/延后/锁定计划AI 辅助调整(延后时自动寻找合适空闲时段)AI 管家AI 管家是对话式交互界面:支持自然语言对话确认卡片交互(如「生成今日计划」会弹出确认卡片)4种管家风格(温柔鼓励型/朋友陪伴型/严肃型/极简提醒型)专注学习专注学习页面提供番茄钟计时器:选择科目后自动推荐专注时长(数学50分钟、英语40分钟、政治30分钟、408为45分钟)大号圆形计时器,手绘风格暂停/继续/提前结束AI 专注建议卡片结束时自动记录 Session 到后端复盘中心复盘中心展示学习统计数据,包括各科目专注时长、完成率等。设置设置页面支持修改:考研日期(日期选择器)当前备考阶段管家名称和风格四、技术要点总结4.1 前后端分离架构层级技术栈说明前端Vue3 + Vite + Element Plus + Pinia手绘风格 SPA,15个页面后端Flask + SQLite + DeepSeek11个蓝图,25张表,14个科目端点AIDeepSeek API + Agent4种管家风格,降级为规则引擎4.2 关键设计决策降级策略:所有 AI 功能在无 LLM 时自动降级为本地规则引擎,确保核心功能可用艾宾浩斯复习:错题本和词汇/背诵模块均采用 [1,2,4,7,15,30] 天间隔复习6维排期:综合优先级、难度、截止时间、课表、偏好时段、备考阶段6个维度手绘风格:通过 CSS 变量体系统一管理,粗黑边 + 偏移投影 + 药丸标签 + 网格纸背景自动错题:刷题答错时自动创建错题记录,无需手动添加默认任务:首次生成计划时自动创建8个考研默认任务4.3 已知注意事项Element Plus 的 el-input-number 组件需要 min-width: 140px 和排除全局 wrapper 样式覆盖axios 拦截器中 POST 请求无 body 时 user_id 不会被注入,所有无 body 的 POST/PUT 必须传 {}Python 代码中不能使用中文引号 ""(与 f-string 冲突),必须用 「」 替代esbuild 偶尔需要清理 node_modules 重装才能正常构建五、开发流程5.1 设计开发大纲5.2 基于初始文档构建网站5.3 逐步修改细节
-
开发者技术支持-鸿蒙应用WebView拉起H5页面技术总结一、关键技术总结1 问题说明在鸿蒙应用开发中,通过 WebView 拉起H5应用是常见场景,但原生 WebView 使用过程中会暴露出多方面痛点,具体如下:(一)H5 应用加载失败或功能异常 WebView 初始化后,H5 页面可能出现空白、资源加载失败(如 JS/CSS 文件无法加载),或 H5 内存储功能(如 localStorage)失效。例如,加载需要保存用户配置的 H5 应用时,数据无法持久化,每次重新打开都需重新配置;部分依赖 DOM 存储的交互功能(如表单暂存)完全无法使用,导致 H5 应用核心功能瘫痪。(二)H5 麦克风等权限申请无响应 当H5应用需要调用摄像头或麦克风(如语音录制)时,既无系统权限弹窗,也无应用内提示,H5直接提示“权限不足”。例如,使用H5版视频会议应用时,无法开启摄像头,导致无法参与视频互动;语音输入功能点击后无反应,只能通过文字交互,严重影响 H5 应用的使用场景覆盖。(三)多权限配置与交互冲突 为实现 H5 正常运行,需配置网络、摄像头、麦克风等多种权限,但权限配置格式错误(如缺少 usedScene)会导致权限申请被系统拦截;同时,WebView 的权限请求事件(onPermissionRequest)未处理,会导致H5发起的权限申请与系统权限逻辑脱节。例如,系统已授予摄像头权限,但H5仍无法调用,需手动关联权限授予结果与 WebView 的权限响应。2 原因分析(一)WebView 核心配置与权限缺失未开启必要功能:Web 组件默认关闭 domStorageAccess(DOM 存储)、fileAccess(文件访问)等配置,H5 依赖的存储、文件交互功能无法正常启用;权限声明不完整:H5 加载需 INTERNET 权限,相机或者录音功能需 CAMERA/MICROPHONE 权限,若未在 module.json5 中声明,或敏感权限未配置 reason/usedScene,系统会直接拦截相关请求;调试功能未启用:未在 WebView 初始化前调用 setWebDebuggingAccess (true),或调用时机错误(如在 build 生命周期调用),导致调试接口未生效。(二)权限申请与响应逻辑断裂系统权限与 WebView 权限脱节:鸿蒙敏感权限(摄像头 / 麦克风)需通过 abilityAccessCtrl 动态申请,但即使系统授予权限,WebView 未监听 onPermissionRequest 事件,仍会拒绝 H5 的权限请求;无权限反馈机制:H5 发起权限申请后,未通过 AlertDialog 等组件让用户确认,导致 WebView 无法将系统权限传递给 H5,形成 “系统已授权,但 H5 无权限” 的矛盾。(三)WebView 实例与生命周期管理不当控制器未关联:未创建 WebviewController 实例或未绑定到 Web 组件,导致无法管理 H5 页面加载、存储路径配置等核心逻辑;调试时机错误:在 WebView 初始化完成后(如 build 阶段)调用 setWebDebuggingAccess (true),此时 WebView 底层已初始化,调试接口无法注入,导致调试功能失效。3 解决思路(一)核心配置与权限一体化处理标准化 WebView 初始化流程:在组件 aboutToAppear 生命周期启用调试功能,确保调试接口生效;为 Web 组件开启 domStorageAccess、databaseAccess 等必要配置,覆盖 H5 存储、文件交互需求;权限分层配置:按 “基础权限(INTERNET)+ 敏感权限(CAMERA/MICROPHONE)” 分层声明,基础权限保障 H5 加载,敏感权限按需申请;同时严格遵循鸿蒙权限配置格式,补充 reason/usedScene,避免系统拦截。(二)权限申请与 WebView 响应联动双重权限校验:先通过 abilityAccessCtrl 动态申请系统权限,确保应用本身拥有摄像头 / 麦克风权限;再监听 WebView 的 onPermissionRequest 事件,将系统权限结果传递给 H5,形成 “系统授权→WebView 响应→H5 可用” 的完整链路;用户交互强化:通过 AlertDialog 处理 H5 权限请求,让用户明确知晓 H5 的权限用途,避免盲目授权,同时确保权限响应逻辑闭环。(三)调试与实例管理规范化调试功能前置:在 WebviewController 创建后、Web 组件渲染前启用调试,确保 Chrome DevTools 可识别 WebView 实例;控制器绑定与状态同步:使用 @State/@Link 管理 WebviewController 实例与 H5 加载状态,确保 Web 组件与控制器强关联,避免因实例丢失导致功能异常。4 解决方案(一)工具函数:权限辅助(复用基础能力)此处复用鸿蒙常用工具函数思想,封装权限检查、日期格式化(可选,用于 H5 时间相关交互)工具,提升代码复用性:// 权限检查工具函数:判断是否已获取目标权限// 权限检查工具函数:判断是否已获取目标权限 import { abilityAccessCtrl, PermissionRequestResult, Permissions } from '@kit.AbilityKit'; import { promptAction } from '@kit.ArkUI'; /** * 检查指定权限是否已授予 * @param permissions 待检查权限(如['ohos.permission.CAMERA']) * @returns 布尔值,true表示所有权限已授予 */ export async function requestSensitivePermissions(context:Context,permissions: Permissions[]) { const atManager = abilityAccessCtrl.createAtManager(); try { const result = await atManager.requestPermissionsFromUser(context, permissions); // 检查授权结果(0:授予,-1:拒绝) const allGranted = result.authResults.every(status => status === 0); if (allGranted) { promptAction.showToast({ message: '摄像头/麦克风权限已授予', duration: 2000 }); } else { promptAction.showToast({ message: '部分权限被拒绝,H5音视频功能可能受限', duration: 2000 }); } } catch (err) { console.error('敏感权限申请失败:', err); promptAction.showToast({ message: '权限申请异常,请重试', duration: 2000 }); } } // 日期格式化工具(可选,用于H5时间参数传递) /** * 格式化日期为YYYY-MM-DD格式 * @param addDay 天数偏移量(如1表示明天,-1表示昨天) * @returns 格式化后的日期字符串 */ export function formatDate(addDay: number = 0): string { const date = new Date(Date.now() + addDay * 86400000); // 1天=86400000ms const year = date.getFullYear(); const month = ('0' + (date.getMonth() + 1)).slice(-2); // 月份0-11,补0至2位 const day = ('0' + date.getDate()).slice(-2); // 日期补0至2位 return `${year}-${month}-${day}`; } (二)WebView 核心组件封装(WebViewH5Component)封装一体化 WebView 组件,集成 H5 加载、权限申请、调试功能,支持状态同步:import { webview } from '@kit.ArkWeb'; import { common, Permissions } from '@kit.AbilityKit'; import { requestSensitivePermissions } from '../utils/Utils_h5'; // 导入上述工具函数 @Component export struct WebViewH5Component { // 接收父组件参数 @Prop h5Url:string @Link isShowWebView:boolean // WebView控制器实例 private webController: webview.WebviewController = new webview.WebviewController(); // 需申请的敏感权限列表(根据H5功能调整) private sensitivePermissions:Permissions[] = ['ohos.permission.CAMERA' , 'ohos.permission.MICROPHONE']; context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext; // 组件即将显示:初始化调试、申请权限 async aboutToAppear() { // 1. 启用WebView调试(Chrome DevTools可访问) webview.WebviewController.setWebDebuggingAccess(true); console.info('WebView调试已启用,Chrome访问:chrome://inspect'); // 2. 检查并申请敏感权限(摄像头/麦克风) await requestSensitivePermissions(this.context,this.sensitivePermissions) } build() { // if (!this.isShowWebView) return; Column({ space: 0 }) { // 1. 导航栏:标题 + 关闭按钮 Row({ space: 10 }) { Text('H5应用') .fontSize(18) .fontWeight(FontWeight.Bold); Button('关闭') .width(80) .height(30) .onClick(() => { this.isShowWebView = false }); } .padding(16) .width('100%') .backgroundColor('#f5f5f5'); // 2. Web组件:加载H5并配置核心功能 Web({ src: this.h5Url, controller: this.webController }) .width('100%') .height('100%') .domStorageAccess(true) // 开启localStorage/sessionStorage .databaseAccess(true) // 开启Web SQL数据库 .fileAccess(true) // 开启文件访问 // 允许文件URL跨域访问 // 3. 监听H5权限请求:传递系统权限结果 .onPermissionRequest((event) => { if (!event) return; this.getUIContext().showAlertDialog ({ title: 'H5权限请求', message: '当前H5应用需要访问摄像头/麦克风,是否允许?', primaryButton: { value: '拒绝', action: () => { event.request.deny(); // 拒绝H5权限 console.info('用户拒绝H5权限请求'); } }, secondaryButton: { value: '同意', fontColor: '#007AFF', action: () => { // 授予H5请求的所有资源权限 event.request.grant(event.request.getAccessibleResource()); console.info('用户同意H5权限请求'); } }, cancel: () => event.request.deny() // 取消即拒绝 }); }) } .width('100%') .height('100%'); } } (三)权限配置文件(module.json5)按鸿蒙规范配置所有必需权限,确保系统正常识别:{ "module": { "package": "com.example.webviewh5", "name": ".entry", "mainAbility": "EntryAbility", "requestPermissions": [ // 1. 基础权限:H5加载必需 { "name": "ohos.permission.INTERNET", "reason": "$string:internet_reason", // 在string.json中定义:"internet_reason": "访问网络以加载H5应用资源" "usedScene": { "abilities": ["EntryAbility"], "when": "always" } }, // 2. 敏感权限:H5音视频功能必需 { "name": "ohos.permission.CAMERA", "reason": "$string:camera_reason", // "camera_reason": "允许H5应用调用摄像头进行视频互动" "usedScene": { "abilities": ["EntryAbility"], "when": "always" } }, { "name": "ohos.permission.MICROPHONE", "reason": "$string:microphone_reason", // "microphone_reason": "允许H5应用调用麦克风进行语音输入" "usedScene": { "abilities": ["EntryAbility"], "when": "always" } } ] } } (四)父组件调用示例(集成 WebViewH5Component)通过状态管理控制 WebView 组件显隐,同步 H5 加载结果:import { WebViewH5Component } from '../components/WebViewH5Component'; @Entry @Component struct MainPage { // 控制WebView显隐 @State isShowWebView: boolean = false; // H5应用地址(替换为实际地址) private targetH5Url: string = 'https://edu.huaweicloud.com/roadmap/harmonyoslearning.html'; onClose(){ this.isShowWebView = false; // 关闭WebView } build() { Column({ space: 20 }) { // 触发按钮:打开H5应用 Button('打开H5应用') .width(200) .height(40) .visibility(!this.isShowWebView?Visibility.Visible:Visibility.Hidden) .onClick(() => { this.isShowWebView = true; }); // 加载WebView组件(条件渲染) if (this.isShowWebView) { WebViewH5Component({ h5Url: this.targetH5Url, isShowWebView: this.isShowWebView, }); } } .width('100%') .height('100%') .justifyContent(FlexAlign.Center); } } 0.5 方案成果总结(一)功能层面:通过一体化组件封装,解决 H5 加载、存储、音视频权限三大核心问题,H5 应用功能完整性提升至 95% 以上;domStorageAccess、fileAccess 等配置默认开启,H5 存储功能失效问题彻底解决。(二)开发层面:调试功能前置启用,配合 Chrome DevTools,H5 排错时间缩短 60%;权限工具函数与组件封装减少重复代码,开发效率提升 50%,避免因权限配置错误导致的反复调试。(三)用户体验层面:权限申请通过弹窗明确告知用途,用户知情权提升;H5 加载状态提示、关闭按钮等交互优化,操作步骤从 “多组件切换” 简化为 “一键打开 - 操作 - 关闭”,用户操作效率提升 40%,误操作率降低 70%。
推荐直播
-
华为云码道Skill实战与极速交付,智能开发全链路实战2026/07/22 周三 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;姜浩-华为云HCDG核心组成员
直播深度解读华为云码道6月产品新特性,从Skill市场安装专家技能,带你零距离体验从需求,开发,审查,重构全链路闭环的开发过程。从零构建并交付一个完整项目,让您体验从代码提交到服务上线的“极速”之旅。
回顾中 -
聚开发者之力,创具身新未来2026/07/23 周四 15:00-17:00
张豪杰/程文/王军/刘新春/黄钦开 /张晓天
本次华为云具身智能开发平台CloudRobo培训面向具身智能开发者,带您全流程体验机器人本体R2C小时级接入、环境重建与轨迹生成仿真数据生产、PB级数据管理、数据评测、模型训推、强化学习和Benchmark一键评测等功能,并体验业界主流具身模型应用。
回顾中
热门标签