ai_v/templates/ocr.html
24024 825f4fb4a9 feat(ocr): 新增验光单助手功能页面
- 在主应用路由中添加 /ocr 页面路由渲染 ocr.html
- 菜单中新增“验光单助手”入口,图标为 scan-eye,便于访问
- 在生成文本接口中支持聊天模型,处理 messages 内图片链接为 Base64
- 兼容 messages 为空场景,重构 payload 结构支持图片 Base64 传输
- 解析验光单请求不保存生成记录,避免污染历史数据
- 获取历史记录时过滤掉“解读验光单”的操作记录
- AI 接口配置新增 CHAT_API 地址,支持聊天模型调用

style(frontend): 优化首页图片展示与交互样式

- 缩小加载动画高度,调整提示文字为“AI 构思中...”
- 图片展示容器增加阴影和悬停放大效果,提升视觉体验
- 结果区域改为flex布局,支持滚动区域和固定底部操作栏
- 按钮圆角加大,阴影色调调整,增强交互反馈
- 引入 Tailwind typography 插件,提升排版一致性
- 静态资源由 CDN 改为本地引用避免外部依赖

docs(ui): 补充首页联系方式提示,优化用户导航

- 在用户个人信息区域新增客服 QQ 联系方式悬浮提示
- 调整首页初始占位状态布局,提升视觉层次感
- 细化按钮标签与图标增强可用性提示
2026-01-14 00:00:23 +08:00

174 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}验光单助手 - AI 视界{% endblock %}
{% block content %}
<!-- 中间AI 功能设定区 -->
<aside class="w-80 lg:w-[340px] flex-shrink-0 glass-sidebar flex flex-col z-30 border-r border-slate-200/60 shadow-xl bg-white/50 backdrop-blur-xl">
<div class="p-6 pb-2">
<h2 class="text-xl font-black text-slate-900 tracking-tight">验光单助手</h2>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-widest mt-1">智能数据提取配置</p>
<!-- 免责声明提示 - 增强版 -->
<div class="mt-6 p-4 bg-indigo-50/50 border border-indigo-100/50 rounded-2xl relative overflow-hidden group">
<div class="absolute top-0 right-0 -mt-2 -mr-2 w-16 h-16 bg-indigo-500/5 rounded-full blur-2xl group-hover:bg-indigo-500/10 transition-colors"></div>
<div class="flex items-center gap-2.5 mb-2">
<div class="w-6 h-6 bg-white rounded-lg flex items-center justify-center shadow-sm border border-indigo-50">
<i data-lucide="shield-check" class="w-3.5 h-3.5 text-indigo-500"></i>
</div>
<span class="text-xs font-black text-indigo-900 uppercase tracking-wider">使用必读</span>
</div>
<div class="space-y-2">
<p class="text-[11px] text-slate-600 leading-relaxed font-medium">
本助手支持单次上传多张单据(如:电脑验光+综合验光),但请确保单据均属于<span class="text-indigo-600 font-bold underline">同一个人</span>
</p>
<div class="p-2 bg-white/60 rounded-xl border border-indigo-100/20 backdrop-blur-sm">
<p class="text-[11px] text-indigo-600 leading-relaxed font-bold flex items-start gap-1.5">
<i data-lucide="alert-triangle" class="w-3 h-3 mt-0.5 flex-shrink-0"></i>
<span>因手写单据模糊或光影识别误差,<span class="underline decoration-indigo-300 underline-offset-2">请务必以人工核对后的数据为准</span></span>
</p>
</div>
<p class="text-[10px] text-slate-400 font-bold italic">
* 平台仅提供 AI 技术支持参考,不承担医疗诊断建议。
</p>
</div>
</div>
</div>
<div class="flex-1 overflow-y-auto px-6 py-4 space-y-6 custom-scrollbar">
<section class="space-y-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="w-6 h-6 rounded-full bg-indigo-600 text-[10px] text-white flex items-center justify-center font-bold">01</span>
<h3 class="text-sm font-bold text-slate-800">状态信息</h3>
</div>
<!-- 积分显示 -->
<div id="pointsBadge" class="hidden px-2 py-0.5 bg-amber-50 text-amber-600 border border-amber-100 rounded-lg text-[10px] font-black uppercase">
可用积分: <span id="pointsDisplay">0</span>
</div>
</div>
<div id="premiumToggle" class="flex items-center justify-between bg-amber-50/50 border border-amber-100/50 p-3 rounded-2xl animate-in fade-in duration-500">
<div class="flex items-center gap-2">
<div class="w-7 h-7 bg-amber-100 text-amber-600 rounded-lg flex items-center justify-center">
<i data-lucide="sparkles" class="w-4 h-4"></i>
</div>
<div>
<div class="text-[10px] font-black text-amber-700 uppercase tracking-tight">高级解析模式</div>
<div class="text-[8px] text-amber-500 font-bold">积分消耗 X2</div>
</div>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="isPremium" class="sr-only peer">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-amber-500"></div>
</label>
</div>
</section>
<section class="space-y-4 pb-2">
<div class="flex items-center gap-3">
<span class="w-6 h-6 rounded-full bg-indigo-600 text-[10px] text-white flex items-center justify-center font-bold">02</span>
<h3 class="text-sm font-bold text-slate-800">验光单照片</h3>
</div>
<div id="dropZone" class="relative group">
<div class="border-2 border-dashed border-slate-100 rounded-3xl p-6 text-center bg-white/30 hover:border-indigo-200 transition-all cursor-pointer">
<i data-lucide="image-plus" class="w-6 h-6 mx-auto mb-2 text-slate-300"></i>
<p class="text-[10px] text-slate-400 font-bold">点击、拖拽或粘贴照片最多3张</p>
<p class="text-[8px] text-indigo-400 font-black mt-1 uppercase tracking-tighter">* 仅支持同一人的多张单据合拍或分传</p>
</div>
<input id="fileInput" type="file" multiple class="absolute inset-0 opacity-0 cursor-pointer">
</div>
<div id="imagePreview" class="flex flex-wrap gap-3 py-1"></div>
</section>
</div>
<div class="p-6 bg-white/95 border-t border-slate-100">
<button id="submitBtn" class="w-full btn-primary py-4 rounded-2xl shadow-lg hover:scale-[1.02] active:scale-[0.98] gap-2 flex items-center justify-center">
<i data-lucide="wand-2" class="w-5 h-5"></i>
<span class="text-base font-bold tracking-widest">开始解读验光单</span>
</button>
<p id="costPreview" class="text-center text-[10px] text-amber-600 font-bold mt-2 hidden"></p>
<p id="loginHint" class="text-center text-[10px] text-slate-400 mt-2 hidden">
<i data-lucide="lock" class="w-2.5 h-2.5 inline"></i> 请先登录以使用生成功能
</p>
</div>
</aside>
<!-- 右侧:主展示 -->
<main class="flex-1 relative flex flex-col bg-slate-50 overflow-hidden">
<div class="h-24 flex items-center justify-between px-12 relative z-10">
<div class="flex items-center gap-3">
<div class="w-2.5 h-2.5 bg-indigo-500 rounded-full animate-ping"></div>
<span class="text-[10px] font-black text-slate-500 uppercase tracking-widest text-xs">引擎就绪</span>
</div>
<div class="flex items-center gap-6">
<div id="userProfile" class="hidden flex items-center gap-3 bg-white/80 backdrop-blur-md px-4 py-2 rounded-2xl border border-white shadow-sm hover:bg-white transition-all">
<div class="w-8 h-8 bg-indigo-100 rounded-xl flex items-center justify-center text-indigo-600">
<i data-lucide="user" class="w-4 h-4"></i>
</div>
<div class="flex flex-col">
<span id="userPhoneDisplay" class="text-xs font-bold text-slate-600">--</span>
<span class="text-[9px] font-black text-amber-600 uppercase">余额: <span id="headerPoints">0</span> 积分</span>
</div>
</div>
<a id="loginEntryBtn" href="/login" class="bg-indigo-600 text-white px-6 py-2.5 rounded-2xl text-xs font-bold shadow-lg shadow-indigo-200 hover:bg-indigo-700 transition-all">
立即登录
</a>
</div>
</div>
<div class="flex-1 flex items-center justify-center p-8 relative overflow-hidden">
<div id="statusInfo" class="absolute top-8 left-1/2 -translate-x-1/2 hidden z-20">
<div class="bg-white/90 backdrop-blur-xl border border-indigo-100 px-6 py-3 rounded-2xl shadow-xl flex items-center gap-3">
<div class="w-2 h-2 bg-indigo-500 rounded-full animate-bounce"></div>
<span class="text-xs font-black text-slate-600 uppercase tracking-widest">AI 正在处理您的请求...</span>
</div>
</div>
<div id="resultCanvas" class="w-full h-full flex flex-col items-center justify-center">
<!-- 初始占位状态 -->
<div id="placeholder" class="text-center max-w-lg">
<div class="w-48 h-48 bg-white rounded-[4.5rem] shadow-2xl flex items-center justify-center rotate-6 mx-auto mb-12 border border-slate-100">
<i data-lucide="scan-eye" class="w-20 h-20 text-indigo-500"></i>
</div>
<h2 class="text-4xl font-black text-slate-900 mb-8">精准解析 · 专业建议</h2>
<p class="text-slate-500 text-lg font-medium">上传验光单照片,获取 AI 深度解读</p>
</div>
<!-- 结果展示状态:使用 flex 布局确保按钮区域固定在底部 -->
<div id="finalWrapper" class="hidden w-full h-full flex flex-col items-center">
<!-- 滚动的内容区域 -->
<div class="flex-1 w-full overflow-y-auto custom-scrollbar px-4 py-6 flex flex-col items-center">
<div id="textResult" class="w-full max-w-4xl p-10 bg-white rounded-[2.5rem] shadow-2xl border border-slate-100 prose prose-indigo max-w-none mb-6"></div>
</div>
<!-- 固定的操作栏区域 -->
<div id="resultActions" class="w-full flex-shrink-0 bg-slate-50/80 backdrop-blur-sm border-t border-slate-200/60 py-6 flex flex-col items-center gap-3 z-10">
<div class="flex items-center gap-4">
<button id="copyJsonBtn" class="bg-slate-900 text-white px-10 py-3.5 rounded-2xl text-xs font-bold shadow-xl hover:bg-slate-800 transition-all flex items-center gap-2.5 active:scale-[0.98]">
<i data-lucide="copy" class="w-4 h-4"></i>
复制解析数据
</button>
<button onclick="location.reload()" class="bg-white border border-slate-200 text-slate-600 px-10 py-3.5 rounded-2xl text-xs font-bold hover:bg-slate-50 transition-all flex items-center gap-2.5 active:scale-[0.98]">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
重新解析
</button>
</div>
<p class="text-[10px] text-slate-400 font-medium">
* AI 识别结果仅供参考,请务必以人工核对后的数据为准
</p>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block scripts %}
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="{{ url_for('static', filename='js/config.js') }}"></script>
<script src="{{ url_for('static', filename='js/prompts.js') }}"></script>
<script src="{{ url_for('static', filename='js/ocr.js') }}"></script>
{% endblock %}