以前经常浏览一个叫句子迷网站,不知何故下线了,我决定做一个类似句子迷一样的产品,专门收集一些名人名言,网络金句等。后来结合自己学习的AI知识,加入了一些文案生成的功能,在“我的”页面可以尝试使用。下面我就从头开始讲一下这款产品的制作过程。
前提条件
相比于其他产品,例如博客、wiki等不需要修改代码,这款产品有一定的开发量,并且这款产品的功能涉及到句子的增删改查和存储,需要前后端联动,因此你至少需要懂一种前端开发语言(如vuejs),一种后端开发语言(如nodejs)以及一种数据库(如mysql)。
技术栈及选型
原生 vs 跨平台: 原生需要为每种平台都开发一个应用(如android和ios以及各种小程序),而跨平台多端共用一套代码,对于独立开发者和中小微企业,选择跨平台是明智之举。
国外跨平台 vs 国产跨平台:国外主要用RN 和 Flutter,这两个框架Flutter最近几年渐入佳境,有很多重量级的APP都是使用RN开发的,例如美团等等。但是国外平台有个硬伤,就是不支持国内生态,尤其是微信生态。因此选国产跨平台也是没得选。
国内跨平台框架: 简单对比便能分出高下,为了全端小程序都能上线,可选项就只有Taro vs uniapp,这是网上搜到的一个对比图,大家可以简单看一下。
框架 | 技术栈 | 案例 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | H5 | App |
---|---|---|---|---|---|---|---|---|
Taro | React | 丰富 | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ |
娜娜奇 | React | 少 | ⭕ | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ❌ |
wepy | Vue | 丰富 | ⭕ | ❌ | ❌ | ❌ | ❌ | ❌ |
mpvue | Vue | 丰富 | ⭕ | ❌ | ❌ | ❌ | ⭕️ | ❌ |
uni-app | Vue | 丰富 | ⭕ | ⭕️ | ⭕️ | ⭕ | ⭕️ | ⭕ |
megalo | Vue | 少 | ⭕ | ⭕️ | ⭕️ | ❌ | ❌ | ❌ |
OKAM | Vue | 少 | ⭕ | ⭕ | ⭕ | ⭕ | ❌ | ❌ |
Mpx | Vue | 少 | ⭕ | ❌ | ❌ | ❌ | ❌ | ❌ |
至于Taro和uniapp怎么选,我觉得因人而异,我希望能够快速的出原型,因此我选择了周边更丰富的uniapp,例如UI框架,甚至用户登录认证模块,uniapp都有现成的模块和插件来支持,所以用uniapp开发会很快。当然我也注意到网上有一些关于uniad的评价,我表示我会自己评估,如果确实有问题,再换到Taro也不难,我在功能设计上已经将几乎所有核心功能做到了服务端,客户端真的就只是个界面展示。
Taro vs uniapp
Taro | uniapp | |
开发语言 | RN | Vue |
开发工具 | VSCODE 插件 | HBuilder |
性能 | 极致 | 优秀 |
社区生态 | Github star 3k 轮子少 | Github star 1k 轮子多 |
架构设
计
前端使用uniapp, 用到的开发语言主要是vuejs, 后端采用unicloud, 用到的开发语言是nodejs, 我们只需要下载一个HBuilderX就可以进行uniapp和unicloud开发.
数据库设计
id是自增的,topic和category只用了一个字段,用于分类(例如是鸡汤还是国学),content就是短句内容,author_id就是作者的id,image_url是句子卡片的图片位置,uploader是图片上传者的id,enabled用来紧急下线不合规的句子,keywords用来辅助搜索,其他的count用来统计句子的受欢迎程度。
API设计:使用业界流行的swagger/openApi定义接口及接口文档
接口设计遵循RESTFul原则,针对一种资源Quote,HTTP POST是create,HTTP PUT是修改资源,保证幂等性,HTTP GET有几种,route上包含id的,是查找特定id的资源,搜索也用的HTTP GET,注意unicloud后台数据库是经过改造的mongodb,很容易实现简单的搜索功能。
功能实现
核心功能有几个:句子推荐, 海报生成以及文案生成.
句子推荐: 标签匹配。即给用户按照静态规则打上标签,然后和句子本身的标签做匹配,匹配度高的加以推荐。大概实现思路就是将所有静态规则录入数据库中,然后用规则引擎对每条规则针对每个用户进行求值。例如有一条规则:QuoteDate.Hour == 6 || QuoteDate.Hour == 7 则加一个标签 "日出",当用户请求过来时,只要将QuoteDate设置成当前时间,然后求一下这个规则的值就可以了。
海报生成: 这个功能可以简化为这么一个问题: 给定一句话,一个图片和一种字体, 如何计算字体的大小使得这句话刚好绘制在图片上. 我将这个问题抛给了chatgpt, 让他给我用nodejs实现, 这是他给出的答案, 基本上我改个两三处就可以用了:
const Jimp = require(jimp');
// 输入
const imageFile = 'image.jpg'; // 输入图像文件
const fontFile = 'font.ttf'; // 字体文件
const text = '你要绘制的文本';
// 创建一个 Promise 以载入图像和字体
async function loadImages() {
const image = await Jimp.read(imageFile);
const font = await Jimp.loadFont(fontFile);
return { image, font };
}
// 主函数
async function main() {
try {
const { image, font } = await loadImages();
const imageWidth = image.getWidth();
const imageHeight = image.getHeight();
let fontSize = 30; // 初始字体大小
let textWidth, textHeight;
do {
fontSize--;
// 计算文本尺寸
textWidth = Jimp.measureText(font, text);
textHeight = Jimp.measureTextHeight({ text, font }, imageWidth);
} while (textWidth > imageWidth || textHeight > imageHeight);
// 计算文本的位置,居中绘制
const x = (imageWidth - textWidth) / 2;
const y = (imageHeight - textHeight) / 2;
// 绘制文本到图像
image.print(font, x, y, text, textWidth);
// 保存包含文本的图像
image.write('output_image.jpg', () => {
console.log('文本已绘制到图像并保存为 output_image.jpg');
});
} catch (err) {
console.error('出现错误:', err);
}
}
main();
文案生成目前还在探索阶段, 效果还不是很好, 下次再讲.
部署及运维
unicloud我用的是19块钱包月的套餐, 用户量小的时候, 这个基本够用了。APP端的上架较为复杂,截至到发稿,我也没能成功上架APP。首先上架国内android市场,必须申请软著,而这个软著是真贵(两三个月的得上千),这一块等我上架成功了再补上。IOS上架也不顺利, 给我回复Guideline 4.3 - Design, 我就怕是Uniapp开发的都被4.3, 有谁懂的可以私信我. 最终上架成功了支付宝小程序和微信小程序(搜索渣渣句)。
盈利模式探讨
目前是放广告, 使用uniad, 不过等文案生成的功能稳定后, 我可能会弃用广告, 直接转收费.
关注我的微信公众号,获取更多全栈开发资料和教程和相关源代码。