简介:一款以星座运势查询与周公解梦为主要功能的微信小程序源码包,面向小程序开发者、内容运营者和流量主变现新手,适用于快速搭建带有星座生肖内容矩阵的小程序场景。包内集成星座查询、星座运势、十二生肖查询、生肖运势、星座配对、生肖配对、配对排行榜、星盘查询、周公解梦等模块,功能覆盖较全面,并预留流量主广告插入入口,便于后续通过广告收益变现。压缩包共295个文件,大小仅1.41MB,文件类型以gif动态图、png静态图和js、json、wxss、wxml源码为主:gif/png素材主要用于界面装饰与功能预览,js负责业务逻辑,json管理页面配置,wxss定义样式,wxml构建页面结构,导入微信开发者工具即可运行调试。已有475人浏览学习,整体代码风格简单、目录清晰,非常容易上手,适合作为小程序实战练习、毕业设计参考,或在此基础上扩展成自己的运势类应用;对于想了解流量主接入与内容型小程序搭建方式的读者,也具有直接参考价值。
1. 流量主小程序选题:星座与周公解梦的流量逻辑
做流量主小程序,最怕的是没有自然增长。星座运势和周公解梦这两类内容,常年排在微信小程序搜索词前列,用户带着明确预期来查“今天运势”“梦见蛇”,搜索直达场景非常强。这套源码把两个高频需求塞进一个小程序里,并且预留了 Banner、插屏、激励视频广告位,属于典型的轻量级流量变现产物。
源码本身由原生微信小程序写成,页面不复杂,数据都是本地 JSON,新手也能在开发者工具里直接跑通。适合两类人:一是想练手小程序发布流程的开发者,二是想批量做流量主测试广告填充率的个人站长。我拿到手先做的不是看功能,而是确认广告组件挂载位置、目录结构是否完整。这类源码最怕的是功能看着全,实际跑起来缺分包、缺图片资源,所以先做静态检查比直接预览更重要。
2. 功能模块与页面结构:从星座查询到周公解梦的实现拆解
2.1 四个底部导航与页面文件组织
这套源码的页面结构很常规,app.json里注册的页面决定入口顺序。解压后可以先看pages目录下有哪些页面文件,再对应底部导航配置。一个典型的布局是:
{ "pages": [ "pages/index/index", "pages/constellation/constellation", "pages/dream/dream", "pages/pair/pair", "pages/mine/mine" ], "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/constellation/constellation", "text": "星座" }, { "pagePath": "pages/dream/dream", "text": "解梦" }, { "pagePath": "pages/pair/pair", "text": "配对" } ] } }这里把constellation和dream放到 tabBar,意味着它们是用户最高频点击的入口。pair和index分别承担配对玩法和信息聚合。需要注意pages数组的第一个元素是启动页,源码里默认是首页,首页上通常堆了所有功能的入口图标,同时挂一个 Banner 广告。
参数说明:pagePath必须与pages里注册的路径完全一致,否则真机预览时 tabBar 会空白。text控制在 2~4 个中文最稳妥,超过 4 个字容易被截断。我一般会把热门功能放中间 tab,因为用户拇指更容易点中,广告曝光率也会高一点。下表是我对这套源码页面与广告位推荐的对照,方便你在改代码时直接参考。
| 页面 | 核心功能 | 建议广告位 | 触发时机 |
|---|---|---|---|
| 首页 | 功能导航 | Banner | 页面底部常驻 |
| 星座页 | 星座列表与详情 | 插屏 | 点击列表项返回时 |
| 解梦页 | 关键词搜索 | 激励视频 | 点击“查看完整解梦” |
| 配对页 | 星座配对评分 | 激励视频 | 配对结果二次解锁 |
2.2 星座运势与生肖数据的本地 JSON 结构
运势类数据不宜每次启动都从服务器拉,否则审核和体验都会打折。源码里大概率有一个data目录,里面放着类似constellation.json、zodiac.json这样的静态数据文件。常见的结构是按日期索引或按星座名称索引。
// data/constellation.json 片段 { "aries": { "name": "白羊座", "date": "3.21-4.19", "today": { "star": 4, "luckyNumber": "7", "luckyColor": "红色", "content": "今天行动力在线,适合推进之前搁置的计划。" } } }调用时直接用require('../../data/constellation.json')拿到全部数据,再根据用户选择的星座 key 取值。这样做的好处是加载速度快,零网络依赖,流量主小程序尤其需要保证页面秒开,否则用户划走就损失一次广告曝光。
这里有一个常见坑:所有星座共用一个对象数组,但没有给每条数据加id。如果你要在配对页里互相引用两个星座的运势,建议在data里增加"id": "aries"字段,用filter或find查找。直接遍历全量数据在数据量小的时候没问题,但解梦词库大了之后就要换索引方式,这个我在第 4 节讲。
2.3 周公解梦的本地模糊检索实现
解梦模块最大的工作量在词库。源码里通常有一份dream.json,格式是“关键词 + 解释”。用户输入“梦见蛇”,程序要做的是先做分词或直接子串匹配。
function searchDream(keyword, dreamLib) { if (!keyword) return []; const kw = keyword.trim(); return dreamLib.filter(item => item.keywords.some(k => kw.indexOf(k) > -1) ); }调用时把用户输入和每个词条里的keywords数组做indexOf匹配,命中就返回整条解释。keywords是数组,意味着一个词条可以对应多个说法,比如“蛇”可以有“梦见蛇”“蛇咬”“毒蛇”等变体。
参数说明:indexOf是子串匹配,不是严格相等,所以用户输入“梦见大蛇”也能命中“蛇”。但注意kw.indexOf(k)是反过来的,意思是“输入文本里是否包含词条关键词”。如果你写成了k.indexOf(kw),就会变成在“蛇”里找“梦见大蛇”,永远匹配不上。新手最容易把这两个方向写反。
注意:
indexOf匹配在词库条目超过 5000 后性能会明显下降,需要改用倒排索引或 Map 结构。后面维护词库时我会给出具体替换方法。
另外,源码如果用了<input>实时监听,建议加 300ms 防抖,不然每次按键都会filter一次几千条的数组,在低端安卓机上会有明显卡顿。
2.4 星盘与配对排行榜的简易算法
星盘和配对看似复杂,但源码为了控制成本,多半是简化方案。星座配对本质是两张预置的评分表,按配对组合索引查表。比如男孩星座是白羊、女孩星座是狮子,就直接查pairScore["aries"]["leo"]。
const pairTable = { "aries": { "leo": 95, "libra": 78, "capricorn": 60 }, "taurus": { "virgo": 92, "scorpio": 82 } }; function getPairScore(male, female) { const score = pairTable[male] && pairTable[male][female]; return score || Math.floor(Math.random() * 40 + 60); }这段逻辑里有一个值得注意的点:pairTable[male]只存了部分组合,如果用户选的组合没预置,源码可能返回一个随机分。这个随机兜底能保证用户永远能拿到结果,但从产品角度看会让“排行榜”失真。如果你打算长期运营,最好把完整 12×12 的配对表补全,宁可部分组合评分平庸,也不要让用户两次刷新看到不同分数。
星盘模块在源码里通常是一个 canvas 画圆形星盘,或者直接输出文字描述。Canvas 绘制时注意设置canvas-id与样式宽高,建议采用wx.createSelectorQuery().select('#starCanvas')获取节点再初始化,避免在页面未渲染完成时画布空白。
3. 流量主接入与初始化:Banner、插屏与激励视频的参数配置
3.1 开通流量主与广告位 ID 的获取
这套源码卖点是“流量主模式”,不是那种需要二次开通的阉割版。你只要有一个注册满一定条件的小程序账号,在微信公众平台左侧菜单找到“流量主”,点击“广告位管理”,创建对应广告位后拿到adunit-id。代码里所有广告位 ID 都是占位符,替换成自己的 ID 才能有真实填充。
常见广告类型有三类,用途差异很大。我做了一个对照表,方便在写代码前先想清楚每个页面放什么:
| 广告类型 | 最长样式 | 适合位置 | 单价特点 | 滥用风险 |
|---|---|---|---|---|
| Banner | 横条 | 首页底部、文章底部 | 按曝光计费,单价低 | 遮挡内容会违规 |
| 插屏 | 全屏 | 页面切换、点击返回时 | 按展示计费,单价中等 | 频繁弹出会被封广告 |
| 激励视频 | 15~30秒 | 解梦结果页、配对详情解锁 | 按完播计费,单价高 | 诱导点击会被拒审 |
我在实际项目里一般首页放 Banner,列表页转跳时放插屏,结果页或解锁按钮放激励视频。注意插屏不要同时在onLoad和onShow里触发,会出现“连续弹两次”的投诉。
3.2 在原生小程序中注入广告组件
原生小程序接入 Banner 最简单,直接在 WXML 里写<ad>组件即可。
<!-- pages/index/index.wxml --> <view class="ad-container"> <ad unit-id="adunit-xxxxxxxxxxxxxxxx" ad-type="banner"></ad> </view>unit-id替换成你在后台新建的 Banner 广告位 ID。ad-type可以省略,默认就是 banner。需要注意广告组件外层必须用view包住,并给这个view一个固定宽度和背景色,否则广告加载前后页面布局会发生抖动。
代码逻辑说明:微信小程序渲染引擎会在页面可见后自动拉取广告,你不需要写请求逻辑。但ad组件有binderror事件,当广告拉取失败时触发。失败原因通常是 ID 填错、类目不与内容不符、或广告缓存未同步。建议监听事件并尝试在失败时隐藏广告容器,避免出现空白占位大块。
注意:插屏和激励视频都是原生组件,覆盖在
web-view上会失效,如果你同时使用了web-view,广告会被原生层遮挡。这套源码里没有web-view,但如果你后期加装,要先把web-view的层级问题处理掉。
3.3 激励视频与插屏的代码接入方式
插屏和激励视频不能像 Banner 一样静态声明,必须通过wx.createInterstitialAd和wx.createRewardedVideoAd创建实例。激励视频比较适合用在“查看完整解梦结果”或“解锁星座配对详细分析”这类场景。
let videoAd = null; function initRewardedAd(adUnitId) { if (!wx.createRewardedVideoAd) return; videoAd = wx.createRewardedVideoAd({ adUnitId }); videoAd.onError(err => { console.error('激励视频广告加载失败', err); }); videoAd.onClose(res => { if (res && res.isEnded) { // 用户完整看完,发放奖励 unlockDreamResult(); } else { wx.showToast({ title: '完整观看后才可解锁', icon: 'none' }); } }); } function showRewardedAd() { if (videoAd) { videoAd.show().catch(() => videoAd.load().then(() => videoAd.show())); } }这里的关键点是onClose里的res.isEnded。isEnded为 true 表示用户看完了完整视频,此时才应该发放奖励。很多新人在onClose里直接发奖励,导致用户看两秒就关掉也能解锁。另外show()可能失败(比如广告头部缓存不足),所以要用.catch执行load()后再show()。
插屏广告的接入逻辑相似,但有一点值得提醒:插屏广告实例在微信基础库 2.6.0 之后是单例的,重复调用wx.createInterstitialAd可能报错。稳妥做法是在App.onLaunch里创建一次,然后按页面生命周期控制展示频率,不要每次onShow都调show(),否则会被流量主平台判定为“高频打扰”。
3.4 广告加载失败时的降级策略
流量主小程序最忌讳广告空白影响体验。广告填充率在低活跃时段可能不到 80%,所以前端必须有降级策略。我在源码基础上加了几个判断:
- Banner 广告在
binderror触发后把整个ad-container设置display: none,避免灰色占位。 - 插屏广告在
promise的catch里不做任何提示,静默失败即可,因为插屏本来就是打扰型广告。 - 激励视频加载失败时,改成弹窗提示“当前网络不给力,请稍后再试”,同时保留一个关闭按钮,不要强制用户继续。
这个策略的核心思路是:广告是营收手段,但页面正常转化才是基础。尤其是解梦结果页,用户如果因为等广告卡顿而关闭页面,那这一次访问的流量价值就归零了。
4. 源码改造实战:换素材、改加载页与数据维护
4.1 替换 gif 素材与启动加载页
源码压缩包里带了 11.gif、18.gif、19.gif 这些数字命名的动图,一般是启动页或加载动画的占位素材。你可以把它们全部替换成自己的品牌动图,注意保持同名,或者在app.json里把启动背景和图路径改掉。
{ "window": { "navigationBarTitleText": "星座解梦助手", "navigationBarBackgroundColor": "#1b1b3a", "navigationBarTextStyle": "white", "backgroundTextStyle": "dark" } }这些配置项控制的是小程序顶部导航栏样式,不是启动图。真正的启动图在微信公众平台后台的“设置 - 基本设置 - 小程序启动页”处修改,前端改不了。如果源码里还有一个splash页面,那它的作用是模拟启动页展示,比如在pages/index/index.js的onLoad里延时跳转。
修改加载页的一个常见做法是:在启动页的onLoad里设置一个 1.5 秒倒计时,时间到后wx.redirectTo到首页。但注意redirectTo会关闭当前页面,不能返回到启动页,适合启动页不需要再出现的情况。如果希望首页返回时还能见启动页,用wx.navigateTo代替。我这里加一张素材替换建议表,方便你在处理压缩包里的 gif 文件时有个尺寸边界。
| 素材类型 | 推荐格式 | 最大大小 | 尺寸建议 |
|---|---|---|---|
| 启动动画 | gif | 300KB | 750×1334 |
| 星座图标 | png | 50KB | 144×144 |
| 页面背景 | jpg/png | 100KB | 按屏幕宽度 |
| Tab 图标 | png | 40KB | 81×81 |
如果你拿到的是 uniapp 工程,加载页的配置在pages.json的style里,原理和原生app.json一致,但navigationBarBackgroundColor要写成navigationBarBackgroundColor还是navigationBarBackgroundColor,注意 uniapp 里也有同名属性,直接替换不要混写。
4.2 换新更准确的数据:运势 JSON 结构与修改示例
星座运势内容如果长期不更新,用户会流失。源码里运势是按“当天”写的静态文本,实际你可以做一个每日更新的脚本。常见做法是写一段 Node.js 脚本,把十二星座今日运势生成 JSON,提交前替换本地数据。
// update_daily.js 局部逻辑 const fs = require('fs'); const source = require('./data/constellation.json'); Object.keys(source).forEach(key => { source[key].today = { star: randomInt(3, 5), luckyNumber: String(randomInt(1, 30)), luckyColor: colors[randomInt(0, colors.length - 1)], content: fortunes[randomInt(0, fortunes.length - 1)] }; }); fs.writeFileSync('./data/constellation.json', JSON.stringify(source, null, 2));这段代码把每个星座的today字段随机替换成新的运势。randomInt需要在外面自己实现,colors和fortunes是预置的文案数组。重点在于不能直接覆盖原文件,要保留备份,因为 JSON 结构一旦出错,整个小程序首页都会白屏。
更好的做法是把运势数据拆成constellation.json(静态星座属性)和daily.json(每日运势增量)两个文件,页面同时读取后合并。这样每日只需替换daily.json,基础星座资料不受影响,审核时也可以把daily.json排除在“代码变更”之外。
4.3 解梦词库扩展与搜索优化
周公解梦词库是这类小程序的核心资产。源码自带的词条通常只有几百条,覆盖不了长尾搜索词。我在维护时会对用户搜索日志做统计,把搜索次数多但没结果的词收集起来,批量补进dream.json。
// 新词条样式 { "id": "snake_01", "keywords": ["蛇", "大蛇", "蛇咬", "毒蛇", "蟒蛇"], "title": "梦见蛇", "meaning": "梦见蛇通常象征潜意识中的恐惧或欲望。" }扩充词库时最重要的规范是:keywords数组放在前面并通过索引查找。如果你用indexOf匹配,每增加一个词条,搜索时的遍历次数就线性增加。当词库到 5000 条以上时,单次搜索在部分低端机上会超过 200ms。优化方法是在onLoad时把dream.json转成倒排索引,把每个关键词映射到词条 ID,搜索时用 Map 直接命中。
这里还要注意避免“同义词重复”:比如已经有了“蛇咬”,又加了“被蛇咬”,这两条会同时命中,页面展示两条相近的解释。我一般会在新增前做一次keywords数组的并集校验,用Set把重复关键词过滤掉。这样既保证搜索结果唯一,也减少数据冗余。
4.4 自定义分享文案与场景值参数
流量主小程序非常依赖用户分享。源码里的分享逻辑通常只是默认分享当前页面,没有自定义文案。建议在Page.onShareAppMessage里加上标题和路径参数,让打开分享卡的人直接看到结果页。
onShareAppMessage: function () { return { title: '我测出今日星座运势四颗星,快看看你的', path: '/pages/index/index?from=share' }; }path里的from=share是自定义参数,用于在首页onLoad里通过options.from判断用户来源。如果来源是 share,可以做一次引导弹窗,提示用户“点击底部广告位支持开发者”。这个动作在微信流量主规则里属于合理运营,但注意不要做“强制看广告才能分享”,容易被判定违规。
5. 上线前自检与提审避坑:类目选择、隐私协议与内容过滤
5.1 类目审核:为什么“星座解梦”容易被打回
微信小程序对“星座运势”“周公解梦”这类内容管控很严格,因为可能涉及迷信类。两个稳妥的类目选择是“工具-信息查询”和“教育-在线教育”,不要直接选择“生活服务-占卜”。实际提审时,机器审核会扫描页面上是否有“算命”“风水”“改运”等敏感词。源码里的文案如果包含这类词,要在提审前批量替换。
我有一次被拒的原因不是广告违规,而是首页源码里有一句“解析您的前世今生”。这种文案在审核语境下属于“宣扬迷信”,删掉文案并提交申诉后一次通过。建议全局搜索“命”“运”“前世”“风水”等字眼,用中性词替换,比如把“命理”改成“个性分析”。
5.2 用户隐私协议与广告合规
如果你的小程序激发了wx.getUserInfo、wx.getLocation这类接口,微信要求必须有隐私协议弹窗。这套源码里如果只在设置页用到头像昵称,多半用wx.getUserProfile,同样算隐私接口。你需要在小程序后台配置用户隐私保护指引,并保证代码里没有直接调用未声明接口。
广告合规方面需要注意三点:Banner 不能紧贴关闭按钮;插屏广告不要在用户点击按钮后立即弹出,建议延时 800ms 到 1s;激励视频按钮上要写“看视频解锁”而不是“点击领奖”,避免用户误解为现金奖励。这些细节影响广告通过率,也影响流量主结算,运营时建议每两周看一次后台违规通知,及时调整广告位密度。
5.3 真机预览与性能验证
在开发者工具里运行流畅不等于真机流畅。特别检查两处:一是解梦页的输入框,要用cursor-spacing属性调整键盘弹出后光标与输入框的距离;二是首页如果加载了多个 gif,要检查内存占用。我用 3 年前的老手机实测过,90% 以上的卡顿都来自同时渲染的 gif 过多。
经验做法是把首页大图全显区域控制在 200KB 以内,超过 100KB 的 gif 改成懒加载,等页面 onReady 后再设置src。流量主小程序并不需要炫酷动画,页面越快,广告曝光价值越高。上线后用“体验评分”功能看 5 秒内加载率,低于 70% 就需要继续压图片,同时检查有没有把上一轮的搜索日志堆到启动逻辑里,启动路径越短越好。
本文还有配套的精品资源,点击获取