设计与实现框架
用户登录后上传照片,输入提示词(描述贺卡风格、祝福语、场景等),系统结合照片与提示词通过 AI 生成贺卡图片,用户可预览、保存或分享。
微信登录 → 上传照片 → 输入提示词 → AI 生成贺卡 → 预览/保存/分享
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 微信小程序端 │ ──→ │ 后端服务 API │ ──→ │ AI 图片生成 │
│ (WXML/WXSS/JS) │ │ (Node/Java/Go) │ │ (NanoBanana等) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ ↓ │
│ ┌──────────────┐ │
└──────────────→│ 对象存储 OSS │←────────────────┘
│ (照片/贺卡) │
└──────────────┘
│
┌──────────────┐
│ 数据库 MySQL │
│ (用户/作品) │
└──────────────┘
| 层级 | 技术 | 说明 |
|---|---|---|
| 前端 | 微信原生 / Taro / uni-app | 原生性能最佳,Taro 可跨端 |
| 后端 | Node.js (Express/Nest) | 与微信生态契合,开发快 |
| 数据库 | MySQL + Redis | 业务数据 + 缓存/会话 |
| 存储 | 腾讯云 COS / 阿里云 OSS | 照片与生成贺卡存储 |
| AI 生成 | NanoBanana / 文生图 API | 照片+提示词图生图 |
| 鉴权 | code2session + JWT | 登录态管理 |
wx.login() 取 code → 后端换 openid + session_key → 生成 JWT → 本地存储维持登录态,首次登录建档。
wx.chooseMedia() 选/拍照 → 前端压缩(1~2MB) → 上传 OSS → 校验格式/大小/imgSecCheck 内容安全。
文本框 + 预设模板(生日/节日/婚礼) + 风格标签(水彩/国潮/卡通) → msgSecCheck 检测。
组装 prompt(用户输入+风格+构图) → 调图生图 API → 返回 task_id 异步轮询进度 → 回传贺卡 URL。
预览结果支持重新生成 → saveImageToPhotosAlbum 存相册 → 转发分享 / 生成含小程序码海报。
-- 用户表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(64),
avatar VARCHAR(255),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 贺卡作品表
CREATE TABLE cards (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
origin_img VARCHAR(255), -- 原始照片
prompt TEXT, -- 用户提示词
style VARCHAR(32), -- 风格
result_img VARCHAR(255), -- 生成贺卡
status TINYINT DEFAULT 0, -- 0生成中 1成功 2失败
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user (user_id)
);
| 接口 | 方法 | 说明 |
|---|---|---|
/api/login | POST | 微信登录,返回 token |
/api/upload | POST | 上传照片,返回 OSS URL |
/api/card/generate | POST | 提交生成任务,返回 task_id |
/api/card/status/:taskId | GET | 查询生成进度/结果 |
/api/card/list | GET | 获取用户作品列表 |
POST /api/card/generate
{
"origin_img": "https://oss.../photo.jpg",
"prompt": "生日快乐,温馨水彩风格",
"style": "watercolor"
}
→ { "task_id": "xxx", "status": "pending" }
wx.login({
success: (res) => {
wx.request({
url: 'https://api.xxx.com/api/login',
method: 'POST',
data: { code: res.code },
success: (r) => wx.setStorageSync('token', r.data.token)
})
}
})
wx.chooseMedia({
count: 1, mediaType: ['image'], sizeType: ['compressed'],
success: (res) => {
wx.uploadFile({
url: 'https://api.xxx.com/api/upload',
filePath: res.tempFiles[0].tempFilePath,
name: 'file',
header: { Authorization: wx.getStorageSync('token') },
success: (r) => { this.setData({ originImg: JSON.parse(r.data).url }) }
})
}
})
const axios = require('axios')
app.post('/api/login', async (req, res) => {
const { code } = req.body
const { data } = await axios.get('https://api.weixin.qq.com/sns/jscode2session', {
params: { appid: APPID, secret: SECRET, js_code: code, grant_type: 'authorization_code' }
})
// data.openid 入库 → 生成 JWT
const token = jwt.sign({ openid: data.openid }, JWT_SECRET, { expiresIn: '7d' })
res.json({ token })
})
app.post('/api/card/generate', auth, async (req, res) => {
const { origin_img, prompt, style } = req.body
const finalPrompt = buildPrompt(prompt, style) // 组合风格模板
const task = await aiClient.editImage({ image_urls: [origin_img], prompt: finalPrompt })
await db.cards.insert({ user_id: req.user.id, origin_img, prompt, style, status: 0 })
res.json({ task_id: task.id, status: 'pending' })
})
imgSecCheck、文本 msgSecCheck,过滤违规内容| 阶段 | 内容 | 周期 |
|---|---|---|
| 一 | 项目搭建、登录、上传 | 1 周 |
| 二 | AI 生成对接、轮询、预览 | 1-2 周 |
| 三 | 作品列表、保存分享、海报 | 1 周 |
| 四 | 内容安全、限流、测试上线 | 1 周 |