简介:这是一套面向Web开发者与前端工程师的H5塔罗占卜系统源码,适用于快速搭建独立占卜类小程序或营销型H5站点,解决个性化运势服务落地难、UI定制成本高的问题。资源共2000个文件,以1264个JavaScript逻辑文件为核心支撑交互与牌阵算法,辅以144个HTML页面结构、113个CSS样式(含bootstrap.min.css、fastadmin.min.css等多套主题样式)、79个PHP后端接口及148个JSON配置数据,完整覆盖前后端功能链路;压缩包大小为576.08MB。已有283人学习下载,说明其在轻量级心理服务类项目中具备实操验证基础。用户可直接部署运行,获得紫色主题UI、圣三角牌阵解析模块、爱情/财富/事业三维度运势输出、响应式移动端适配能力,以及包含多层级目录结构的工程化代码组织方式,便于二次开发与功能扩展。
1. 这不是玄学工具,而是一套可部署、可调试、可二次开发的 H5 塔罗占卜交互系统
你打开一个紫色 UI 的 H5 页面,选中“圣三角牌阵”,点击三张虚拟塔罗牌——页面立刻生成一段结构化文本:“过去:权杖二逆位,暗示你曾因犹豫错失关键机会;现在:女祭司正位,代表直觉正在苏醒;未来:战车正位,预示三个月内将通过主动掌控扭转局面。”这不是静态文案轮播,而是后端根据牌面组合、位置权重、正逆位规则实时计算出的解读逻辑。这套源码不依赖第三方 API,所有牌义映射、阵型规则、运势标签均固化在代码中;它也不是单页 HTML 堆砌,而是由bootstrap.min.css+fastadmin.min.css+_all-skins.css构成的完整前端样式栈,配合backend.min.css和frontend.min.css实现前后端职责分离。它面向的是需要快速上线轻量级心理服务类 H5 的开发者:比如心理咨询机构想嵌入公众号菜单,独立运营者想用域名承载占卜流量,或前端工程师想拆解一个真实场景下的响应式交互架构。它不承诺命运预测,但能稳定输出符合塔罗学理基础的结构化反馈——这才是技术人该关心的“占卜系统”本质。
2. 紫色 UI 的实现逻辑与 H5 响应式适配原理
2.1 主题色体系如何通过 CSS 变量与皮肤文件协同控制
该系统采用 FastAdmin 框架衍生的皮肤机制,核心控制逻辑藏在_all-skins.css中。它并非简单覆盖bootstrap.css的.btn-primary,而是通过 CSS 自定义属性(CSS Custom Properties)建立主题变量层:
:root { --primary-color: #8A2BE2; /* 紫罗兰主色 */ --secondary-color: #9370DB; /* 中紫 */ --accent-color: #E6E6FA; /* 浅紫背景 */ --text-on-primary: #FFFFFF; } .skin-purple .main-header .navbar { background-color: var(--primary-color); } .skin-purple .sidebar-menu > li.active > a { border-left-color: var(--secondary-color); }fastadmin.min.css负责基础组件样式(如卡片、弹窗、分页),而_all-skins.css仅注入皮肤类名(.skin-purple)对应的变量重写和选择器覆盖。这种解耦设计让更换主题只需修改:root变量值并切换 body 类名,无需重写全部组件样式。实际部署时,可通过 JS 动态注入:
document.documentElement.style.setProperty('--primary-color', '#6A0DAD'); document.body.className = 'skin-purple sidebar-mini';提示:
bootstrap.min.css与bootstrap.css同时存在并非冗余。前者用于生产环境压缩版,后者保留源码注释供调试——当你发现某处圆角异常或阴影失效时,应优先检查bootstrap.css中.card,.btn等类的border-radius和box-shadow声明是否被_all-skins.css中更具体的选择器覆盖。
2.2 H5 移动端适配的关键参数与 viewport 配置陷阱
系统宣称“独立站 H5”,意味着它必须脱离微信 WebView 特定环境,在 Safari、Chrome Mobile、三星浏览器等主流移动内核中保持一致渲染。其index.html头部包含标准 viewport 声明:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">但仅此不够。真正决定 H5 在不同设备上缩放行为的是bootstrap.css中的媒体查询断点与rem基准设定。该源码未使用lib-flexible或postcss-pxtorem,而是采用传统media query + px方案,断点定义如下:
| 断点名称 | 最大宽度 | 典型设备 | 关键样式影响 |
|---|---|---|---|
| xs | 575px | iPhone SE | .col-12全宽,隐藏侧边栏导航 |
| sm | 767px | iPad Mini | .card-body内边距减半,按钮文字缩小为14px |
| md | 991px | 折叠屏展开态 | 恢复双栏布局,圣三角牌阵横向排列 |
| lg | 1199px | 平板横屏 | 显示完整运势雷达图,启用hover效果 |
验证方法:在 Chrome DevTools 中切换设备模拟器,观察.container-fluid宽度是否随视口严格变化;若出现横向滚动条,需检查body { margin: 0; padding: 0; }是否被第三方 CSS 覆盖。
2.3 圣三角牌阵的 DOM 结构与触摸交互优化
圣三角牌阵(Past-Present-Future)的 UI 实现并非三个静态图片,而是基于bootstrap.css的栅格系统构建的可交互卡片容器:
<div class="row card-deck mb-4"> <div class="col-12 col-sm-4 position-relative"> <div class="card h-100 shadow-sm border-0"> <div class="card-body text-center p-3"> <h5 class="card-title text-muted">过去</h5> <div class="tarot-card-wrapper mt-2"> <img src="images/cards/02.jpg" alt="权杖二" class="tarot-card img-fluid rounded"> </div> </div> </div> </div> <!-- present & future 同理 --> </div>关键优化点在于:
position-relative+tarot-card-wrapper为后续添加翻转动画预留定位上下文;img-fluid确保图片在col-*栅格内自适应缩放;rounded类提供统一圆角,避免 iOS Safari 渲染锯齿。
触摸交互增强通过fastadmin.min.css中的.btn-tap类实现:
.btn-tap { -webkit-tap-highlight-color: rgba(138, 43, 226, 0.2); /* 紫色高亮 */ -webkit-touch-callout: none; }注意:若在真机测试中发现点击无反馈,需确认
<meta name="format-detection" content="telephone=no">是否存在——缺失此声明会导致 iOS 将数字误识别为电话号码并禁用点击事件。
3. 占卜逻辑的后端实现与牌义数据库设计
3.1 牌义数据结构:JSON Schema 与正逆位状态机
系统后端(推测为 PHP,因fastadmin默认栈)将 78 张塔罗牌抽象为结构化 JSON,存储于/data/cards.json:
{ "cards": [ { "id": 1, "name": "愚者", "number": 0, "suit": "major", "position": "upright", "meaning": { "past": "新起点的勇气", "present": "信任直觉的时刻", "future": "旅程即将开启" } }, { "id": 1, "name": "愚者", "number": 0, "suit": "major", "position": "reversed", "meaning": { "past": "鲁莽导致的失误", "present": "缺乏方向感", "future": "需重新评估目标" } } ] }关键设计点:
- 同一
id对应正逆位两条记录,避免运行时条件判断分支; meaning对象按牌阵位置(past/present/future)预置文本,省去 NLP 解析开销;suit字段区分大阿卡纳(major)与小阿卡纳(minor),圣三角牌阵强制抽取 3 张大阿卡纳,后端校验逻辑为:
// cards.php function validateTriad($selectedCards) { foreach ($selectedCards as $card) { if ($card['suit'] !== 'major') { throw new Exception('圣三角牌阵仅支持大阿卡纳牌'); } } return true; }3.2 牌阵算法:位置权重与组合解读规则引擎
圣三角牌阵非简单拼接三段文本,而是引入位置权重系数与组合触发规则。后端 PHP 类TriadInterpreter核心逻辑如下:
class TriadInterpreter { private $weights = ['past' => 0.3, 'present' => 0.4, 'future' => 0.3]; public function interpret($cards) { $result = []; // 步骤1:单牌基础解读 foreach ($cards as $pos => $card) { $result[$pos] = $this->getBaseMeaning($card); } // 步骤2:组合规则匹配(示例:过去+现在同为权杖系 → 强化行动力) $suitCombination = $this->checkSuitCombination($cards); if ($suitCombination) { $result['insight'] = $suitCombination['text']; } // 步骤3:正逆位冲突检测(如过去逆位+现在正位 → 转折信号) $polaritySignal = $this->detectPolarityShift($cards); if ($polaritySignal) { $result['warning'] = $polaritySignal; } return $result; } }checkSuitCombination()方法遍历预设规则表(存于/config/suit-rules.php):
return [ ['suits' => ['wands', 'wands'], 'positions' => ['past','present'], 'text' => '行动力持续积累,当前是执行关键期'], ['suits' => ['cups', 'swords'], 'positions' => ['present','future'], 'text' => '情感与理性需平衡,未来决策将受情绪影响'] ];提示:若需扩展牌阵(如凯尔特十字),只需新增规则数组并修改
interpret()中的调用链,无需重构核心引擎——这是该源码可维护性的关键。
3.3 运势标签系统:从占卜结果到用户画像的映射
最终输出的“爱情+财富+事业”三维度运势,并非随机生成,而是基于牌义关键词匹配标签库。/data/tags.json定义如下:
{ "love": ["恋人", "皇后", "星星", "权杖四"], "wealth": ["金币国王", "星币八", "命运之轮", "力量"], "career": ["隐士", "战车", "审判", "宝剑国王"] }后端执行匹配:
function extractTags($cards) { $tags = ['love' => 0, 'wealth' => 0, 'career' => 0]; foreach ($cards as $card) { foreach (['love','wealth','career'] as $domain) { if (in_array($card['name'], $tagConfig[$domain])) { $tags[$domain]++; } } } // 归一化为 0-100 分数 return array_map(fn($v) => min(100, round($v * 33.3)), $tags); }分数直接驱动前端雷达图渲染,frontend.min.css中.radar-chart类已预设 SVG 路径动画。
4. 部署调试与常见兼容性问题排查
4.1 本地开发环境搭建:Nginx 配置要点与 MIME 类型修正
该源码为纯静态前端+PHP 后端混合架构,推荐使用 Nginx(非 Apache)部署,因其对 H5 资源缓存控制更精准。关键配置段:
server { listen 80; server_name tarot.local; root /var/www/tarot; index index.html index.php; # H5 资源强制缓存,但 HTML 不缓存 location / { try_files $uri $uri/ /index.html; add_header Cache-Control "public, max-age=31536000"; } # PHP 处理 location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 修复 iOS Safari 对 .json 文件的 MIME 识别错误 add_header Content-Type "application/json; charset=utf-8"; } # 静态资源压缩 location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } }注意:若访问
/data/cards.json返回text/plain导致 JS 解析失败,必须在location ~ \.php$块中显式设置Content-Type,因为 FastCGI 默认不继承 MIME 类型。
4.2 微信内嵌 H5 的授权与调试绕过方案
当系统需嵌入微信公众号菜单时,常遇wx.config签名失败。该源码未内置微信 JS-SDK,故需手动集成。安全做法是在后端生成签名:
// api/wechat-signature.php $appid = 'wx1234567890'; $appsecret = 'your_app_secret'; $jsapi_ticket = getJsApiTicket($appid, $appsecret); // 调用微信接口获取 $noncestr = bin2hex(random_bytes(16)); $timestamp = time(); $url = $_GET['url']; // 前端传入当前页面 URL $string1 = "jsapi_ticket={$jsapi_ticket}&noncestr={$noncestr}×tamp={$timestamp}&url={$url}"; $signature = sha1($string1); echo json_encode([ 'appId' => $appid, 'timestamp' => $timestamp, 'nonceStr' => $noncestr, 'signature' => $signature ]);前端调用:
fetch('/api/wechat-signature.php?url=' + encodeURIComponent(location.href)) .then(r => r.json()) .then(config => { wx.config({ debug: false, appId: config.appId, timestamp: config.timestamp, nonceStr: config.nonceStr, signature: config.signature, jsApiList: ['onMenuShareTimeline'] }); });4.3 真机调试必备:Chrome Remote Debugging over USB
iOS 设备无法直接查看 console,必须通过 macOS + Safari 开发者工具;Android 则依赖 Chrome Remote Debugging。关键步骤:
- Android 手机开启开发者模式(连续点击版本号 7 次);
- 启用 USB 调试,连接电脑;
- Chrome 地址栏输入
chrome://inspect,勾选Discover USB devices; - 在
Configure中添加localhost:8080(若 Nginx 运行在 8080 端口); - 手机 Chrome 访问
http://192.168.x.x:8080,页面将出现在Remote Target列表。
此时可实时查看:
Network标签中/api/interpret.php请求参数与响应;Console中Uncaught TypeError: Cannot read property 'meaning' of undefined类错误;Elements中.tarot-card的transform: rotateY(180deg)动画是否触发。
5. 二次开发实战:为圣三角牌阵增加“时间锚点”功能
5.1 需求分析:为什么用户需要指定“占卜时间”?
原始系统默认以当前时间为解读基准,但塔罗实践中常需回溯特定日期(如“去年今日的感情状态”)或预设未来节点(如“2025 年春节前的职场变动”)。这要求后端能接收时间戳并调整牌义权重——例如“过去”位置若指定为 2023-06-01,则优先匹配该时间段内高频出现的牌义变体。
5.2 前端改造:时间选择器与请求参数注入
在index.html圣三角启动按钮下方追加时间选择控件:
<div class="form-group mt-3"> <label class="form-check-label"> <input class="form-check-input" type="checkbox" id="enable-time-anchor"> 指定占卜时间锚点 </label> <div class="row mt-2" id="time-anchor-group" style="display:none;"> <div class="col-6"> <input type="date" class="form-control" id="anchor-date" value="2024-01-01"> </div> <div class="col-6"> <select class="form-control" id="anchor-period"> <option value="past">回溯过去</option> <option value="future">预判未来</option> </select> </div> </div> </div>JS 绑定事件:
$('#enable-time-anchor').change(function() { $('#time-anchor-group').toggle(this.checked); }); $('#start-triad').click(function() { const payload = { cards: selectedCards, anchor: $('#enable-time-anchor').is(':checked') ? { date: $('#anchor-date').val(), period: $('#anchor-period').val() } : null }; $.post('/api/interpret.php', payload, function(res) { renderResult(res); }); });5.3 后端增强:时间感知型解读器
修改TriadInterpreter,新增applyTimeAnchor()方法:
public function applyTimeAnchor($cards, $anchor) { if (!$anchor) return $cards; $baseYear = (int)substr($anchor['date'], 0, 4); $yearOffset = $anchor['period'] === 'past' ? date('Y') - $baseYear : $baseYear - date('Y'); // 加载时间敏感牌义库(/data/time-variants.json) $timeVariants = json_decode(file_get_contents(__DIR__.'/../data/time-variants.json'), true); foreach ($cards as &$card) { $key = $card['id'] . '_' . $card['position'] . '_' . $yearOffset; if (isset($timeVariants[$key])) { $card['meaning'] = array_merge($card['meaning'], $timeVariants[$key]); } } return $cards; }time-variants.json示例:
{ "1_upright_1": { "past": "一年前的冲动已沉淀为经验", "present": "当下需警惕重复旧模式" }, "13_reversed_2": { "future": "两年后将经历不可逆的转变,建议提前规划" } }提示:此功能上线后,需在
frontend.min.css中为.time-anchor-badge添加紫色徽章样式,并在renderResult()中插入<span class="badge bg-purple">时间锚点生效</span>,确保用户感知功能已激活。
本文还有配套的精品资源,点击获取