起点:一个技术人的展示橱窗

在我学习了小程序之后,作为技术人,我想把自己的知识使用小程序来实现,这一切始于一个朴素的想法:我需要一个地方,来系统性地展示和沉淀我的技术知识点。

于是,“豆子小豆子碎片”小程序第一个版本诞生了。它是一个纯粹的技术“展示橱窗”,记录着我的学习与思考。

然而,我很快发现,一个单向输出的“橱窗”,即使内容再好,也缺乏持续的活力与互动。用户来了又走,我作为唯一的创作者,也感到动力有限。我意识到,如果知识只是被陈列,而无法流动、无法创造连接、无法衡量价值,它的影响力终究是有限的。

进化:引入“豆子点数”,点燃价值引擎

我想到了激励,为了自己,也方便他人。为了让知识流动起来,我构思了系统的核心:“豆子点数”激励系统。这不再是一个静态的展示柜,而是一个动态的价值交换市场。

我的目标,是将每一次阅读、每一次创作、每一次互动,都转化为可积累、可量化的数字资产——“豆子”。而“豆子”的终极锚点,是能兑换为人民币,这是我最初的想法。那我的收益又从哪里来呢?广告收入,用户需要查看文章,需要消耗豆子点数,当点数不足时,需要观看激励广告。

这个链路就是,创作者上传文章->用户看广告获取豆子点数->平台通过广告获取收益->用户浏览文章消耗豆子点数,创作者获取豆子点数->创作者兑换豆子点数。

升华:从个人项目到创作者平台

真正的蜕变,在于我决定将这个系统平台化、开放化。我不再是唯一的创作者,而是平台的搭建者和规则制定者。

平台的三角模型:

  • 我(平台方):开发了小程序和后台API,文章上传客户端,负责维护系统、制定规则、对接广告,确保整个经济体稳定运行。

  • 创作者:任何技术爱好者都可以通过API或客户端,向平台上传自己的技术文章,成为内容供应者。

  • 读者:所有用户,来此免费消费这些技术内容。

它的核心运转机制:基于广告分成的价值循环。这是整个构想最精妙的部分,它形成了一个完美的闭环:

  • 创作激励:读者阅读文章时,需要观看一则广告。这则广告产生的收益,将被平台折算成 “豆子点数”​ ,奖励给该文章的上传者(创作者)。创作者贡献内容,平台通过广告将读者的注意力变现,并回馈给创作者。

  • 内容分层与溢价机制:创作者如果对自己的文章质量有足够信心,可以为其 “加锁”​ 。一旦文章被“加锁”,读者阅读时需要观看的广告(或广告价值)会更高,随之产生、并奖励给创作者的“豆子点数”也会更多。

  • 这形成了强大的自我筛选和品质激励:优质内容会主动标示自己,并寻求更高回报;读者为高质量内容付出稍多的注意力(看更长或更多的广告),也觉合理;平台则通过优质内容吸引更多流量,形成良性循环。

  • 互动增强回路:除了阅读广告产生的点数,“点赞”等互动行为也可以被设计为额外的奖励来源(例如,点赞能为创作者带来少量点数)。这鼓励创作者不仅追求流量,更追求内容带来的认同与共鸣,促进社区氛围。

完整的经济闭环:

  • 创作者​为获取“豆子”(可换钱),积极生产内容,优质内容会“加锁”以求更高收益。

  • 读者​为获取免费知识,付出注意力观看广告。

  • 广告商​的投放费用流入平台。

  • 平台​将广告收益的大部分,以“豆子点数”形式分配给创作者(特别是“加锁”的优质内容获得更高权重)。

  • 创作者​积累“豆子”,最终从平台兑换人民币,实现知识变现。

  • 小程序本身,则纯粹作为这个生态的“展示窗口”和“交互界面”,负责优雅、流畅地向终端用户呈现这一切。

愿景:一个由技术人共建、共享的良性生态

这个构想的终极目标,不再是展示我个人的技术,而是搭建一个基于价值认同的、可持续的开发者内容生态。对创作者而言,这是一个轻量级、可直接获得正反馈和物质激励的技术博客平台。对读者而言,这是一个能免费(以注意力为代价)接触到众多同行一线思考和经验的宝库。对整个社区而言,“豆子点数”如同血液,驱动着优质内容的生产、筛选与流通。

这看起来非常美好,仿佛是一个微小的公众号生态缩影。然而,当我真正试运行之后,才发现这个循环其实非常脆弱,很容易就会崩塌。

原因主要有这么几点:

第一,小程序的广告收益实在太低,我根本无法维持当初设想的“1000豆子兑换1元人民币”的固定汇率。

第二,小程序广告的收益算法并不透明,我很难设计出公平又可持续的豆子折算比例。

第三,用户对文章内容并不那么感兴趣,阅读量和互动始终起不来。

第四,创作者那边也缺乏持续上传文章的动力,早期激励难以覆盖他们的创作投入。

第五,从长远来看,小程序平台本身也在政策上存在不确定性,后续版本很可能会限制甚至禁止用户自定义内容的上传。

为了把这个想法落地,我在技术实现上是下了功夫的。我专门开发了一个内容上传平台,它拥有清晰的公开API和创作者使用的客户端界面。当创作者提交文章后,会进入审核流程。为了给创作者即时的反馈,我还额外集成了MQTT消息服务——一旦文章审核通过(或退回),系统就会通过MQTT通道向创作者客户端推送实时通知,让整个流程更顺畅、更透明。

就这样,尽管有这些技术上的准备和实现,这个想法在运行一段时间后,还是慢慢沉寂了。

虽然它没有成功,但却给我留下了一笔很大的财富——我意识到,我过去所做的,从技术实现上看是完整的,但从模式上看,更多是一种对现有逻辑的复制,而非真正的创新。

但这依然是一次宝贵的尝试。它让我完整地走完了一个“想法-开发-运营-验证”的闭环,其中的技术架构与产品反思,是单纯复制项目所无法获得的。

最后介绍一下识别码。文章上传和维护,我们是通过命令行工具来完成的。没有集成到小程序中,一是因为个人小程序不容易过审,二是在小程序中编制 Markdown 文档非常麻烦,因为没有提供 API 选择 MARKDOWN 文档,因此上传 Markdown 文档也不能实现。我自己实现了命令行工具可以管理文章。也提供开放接口 API 供用户自己实现工具上传。为了保护开放接口,我们需要用户认证。在小程序中实现了获取用户识别码的功能。可以获取到用户识别码,调用开放接口。

用户识别码

我们的小程序只实现了文章的浏览和搜索。为了将整个应用完善,我们还需要文章上传,文章删除等功能。上一节,我们已经讲了一种解决方案。就是使用开放接口 API。

开放接口因为是面向互联网的,所以任何人都能访问,为了保护我们的开放接口不让任意调用,我们需要添加认证。我们通过小程序的微信生态进行认证。只有用户能使用小程序,并能获取用户的 OPENID,我们才给用户提供识别码。

用户识别码相当于用户的账号和密码,我们基于用户的 OPENID 生成识别码。识别码是项目中是唯一的,可识别的。识别码密钥是随机字符串。通过识别码和识别码密钥,我们可以用来识别用户,所以,请妥善保管你的识别码和识别码密钥。防止他人滥用。你还可以重置识别码密钥,让以前的识别码密钥失效。类似于用户账户中的修改密码。

根据小程序的特性,我们还集成了广告,结合广告,用户识别码更加的重要。我们使用豆子点数机制,来实现广告和用户识别码的结合。当用户观看广告时,获取豆子点数,当用户调用开放接口时,消耗豆子点数。用户的公开加锁文章被其他用户浏览时,可以获得豆子点数,并且提供文章的浏览量,提高文章的排序。

增加一个 Tab 项,叫我的页面。我的页面只有两个功能,观看广告获取豆子点数,获取我的识别码。现在看看如何实现我的识别码。

<view class="page">
  <view class="weui-form">
    <view class="weui-form__bd">
      <view class="weui-form__text-area">
        <h2 class="weui-form__title">我的识别码</h2>
        <view class="weui-form__desc">识别码用于开放接口认证使用。请妥善保管识别码和密钥,不要将密钥告诉他人。</view>
      </view>
      <view class="weui-form__control-area">
        <view class="weui-cells__group weui-cells__group_form">
          <view class="weui-cells">
            <view class="weui-cell">
            <text>我的识别码:{{icode}}</text>
            </view>
            <view class="weui-cell">
            <text>我的密钥:{{isecret}}</text>
            </view>
          </view>
        </view>
      </view>
    </view>
    <view class="weui-form__ft">
      <view class="weui-form__opr-area">
        <view class="weui-btn weui-btn_primary" aria-role="button" bind:tap="getMyAppIcode">获取识别码</view>
        <view class="weui-btn weui-btn_warn" aria-role="button" bind:tap="resetAppIcode">重置识别码密钥</view>
        <view class="weui-btn weui-btn_default" aria-role="button" bind:tap="doCopy">复制到剪切板</view>
      </view>
    </view>
  </view>
</view>

获取识别码和重置识别码的整体思路和逻辑与前面的文章类似,没有新的技术点。这里添加了剪切板功能,方便用户复制识别码。

为了激励用户,我们把加锁的文章权重提高,当用户浏览加锁文章时,浏览量是普通文章的两倍。这样在排序时,会排到前面。

集成广告

当小程序的用户量达到一定数量时,就可以开通流量主。集成小程序广告,就可以获得收益。

为了增加一点收益,用于承担一些我的服务器费用支出。根据我的小程序特点,我集成了 3 类类型的广告。如果你喜欢我的文章,欢迎你浏览小程序观看广告。

  1. 封面广告,这个没有技术含量,在小程序后台开通即可。

  2. Banner 广告,这个也没有技术含量,在界面中设置时注意和界面的其它元素不冲突,排版协调即可。

  3. 激励视频广告,这个有一点技术含量。官方文档中说在 onLoad 方法中加载广告的初始化。我发现这样设置的话,界面会不流畅。特别是多次返回再进入,页面迟滞现象严重。

为了优化,我也想了很多办法。最后的解决方法如下:

  loadAd() {
    const that = this;
    vAd = wx.createRewardedVideoAd({
      adUnitId: 'adunit-2ce6db3cb1e45a86',
    })
    vAd.onLoad(() => {
      hasLoadAd = true
    }),
      vAd.onError((err) => {
        console.error('激励视频广告加载失败,', err)
      }),
      vAd.onClose((res) => {
        if (res && res.isEnded) {
          that.doAdProfit();
        } else {
          wx.showToast({
            title: '没有获得点数哟!',
          })
        }
      })
  },

  playAd() {
    const that = this;
    wx.showLoading({
      title: '加载广告中',
    })
    if (!hasLoadAd) {
      that.loadAd();
    }
    // 用户触发广告后,显示激励视频广告
    if (vAd) {
      vAd.show().then(() => [
        wx.hideLoading()
      ]).catch(() => {
        // 失败重试
        vAd.load()
          .then(() => {
            wx.hideLoading()
            vAd.show()
          })
          .catch(err => {
            wx.hideLoading()
            wx.showToast({
              title: '请重试一次',
            })
            console.error('激励视频 广告显示失败', err)
          })
      })
    } else {
      wx.hideLoading()
      wx.showToast({
        title: '请稍后重试',
      })
    }
  },

进入页面后,不加载广告,只有当用户主动点击广告按钮时,才加载广告。在加载广告的时候,给用户显示 Loading,增加用户的体验。如果已经加载了广告,就直接播放。如果加载广告失败,再重新拉取一次。还报错,就只能显示给用户错误了。

通过上面的方法改进后,发现多次进入页面不会卡顿,发生页面迟滞现象。

小程序开发部分基本就完成了,后续有新的功能或者优化再开新的文章。