开发文档.md 20 KB

佳友厚苑 MVP 第一阶段开发文档


1. 项目目标与范围

1.1 项目目标

第一阶段目标是快速搭建“扫码溯源展示能力”,跑通最小业务闭环:

  • 用户扫码 → 打开溯源页面
  • 页面展示商品、农场、批次、检测报告、合格证
  • 支撑运营实际使用(打印标签 + 贴标 + 直播/发货使用)

1.2 本阶段解决的问题

  • 如何让用户“看到可信信息”
  • 如何快速上线溯源能力
  • 如何支撑运营落地流程

1.3 本阶段不做内容

  • 不做商城交易系统
  • 不做登录注册
  • 不接农小禹系统
  • 不做农事记录
  • 不接设备/摄像头数据
  • 不做复杂审核流
  • 不做统计分析

2. 业务流程

2.1 标准流程

  1. 运营创建批次
  2. 填写商品信息、农场信息、批次信息
  3. 收集农户提供的:
    • 合格证
    • 检测报告
  4. 在爱智农后台上传资料
  5. 生成批次二维码
  6. 生成标签打印文件
  7. 打印标签并贴标
  8. 用户扫码进入溯源页查看信息

2.2 关键约束

  • 批次创建时必须填写商品与农场信息
  • 批次未发布不可扫码
  • 所有展示内容均来源于批次

3. 角色与职责

3.1 运营人员

  • 创建批次
  • 收集合格证与检测报告
  • 上传资料
  • 生成二维码
  • 打印标签
  • 校验扫码效果

3.2 系统(爱智农)

  • 提供批次管理能力
  • 提供文件上传能力
  • 提供二维码生成能力
  • 提供标签打印能力

3.3 用户

  • 扫码查看溯源信息

4. 核心数据模型

4.1 核心对象:批次(Batch)

第一阶段所有数据围绕“批次”组织


4.2 批次结构

批次包含以下信息:

商品信息

  • 商品名称
  • 商品规格
  • 商品图片
  • 商品简介

农场信息

  • 农场名称
  • 农场所在地
  • 农场简介
  • 农场图片

批次信息

  • 批次号
  • 生产/采收日期
  • 包装日期
  • 状态(草稿/已发布/已下线)

文件信息

  • 检测报告
  • 合格证

4.3 设计原则

  • 批次创建时必须填写商品与农场信息
  • 批次为唯一展示数据源
  • 前端不单独维护数据

5. 前端页面说明(溯源页)

5.1 页面目标

让用户快速理解:

  • 买的是什么(商品基础信息清晰可见)
  • 来自哪里(农场来源明确)
  • 属于哪一批(批次信息明确)
  • 是否经过检测(检测报告可查看)
  • 是否具备合格证(合格证可查看)
  • 页面整体有一定品牌感与可信感

5.2 页面结构

1. 页面头部

  • 品牌名称:佳友厚苑
  • 页面标题:商品溯源信息
  • 商品/农场背景图
  • 品牌文案(如:可追溯 · 更安心)
  • 商品主视觉图优先,若无则使用农场图

2. 商品信息区

  • 商品名称
  • 商品图片
  • 商品规格
  • 商品简介

3. 农场信息区

  • 农场名称
  • 农场所在地
  • 农场图片
  • 农场简介

4. 批次信息区

  • 批次号
  • 生产/采收时间
  • 包装时间
  • 批次状态

5. 检测报告区

  • 检测状态(合格/待补充)
  • 检测日期(可选)
  • 报告编号(可选)
  • 报告文件预览(PDF/图片)
  • 查看原件按钮

6. 合格证区

  • 合格证状态
  • 开具日期
  • 合格证文件预览
  • 查看原件按钮
  • 合格证编号(可选)

7. 溯源说明区

  • 数据来源说明(前端固定文案)
  • 溯源说明文案(前端固定文案)

示例文案:

数据来源说明: 本页面信息由佳友厚苑溯源系统提供,相关检测报告及合格证由平台统一收集并上传,确保信息真实可查。

溯源说明文案: 本商品支持溯源查询,您可通过本页面查看该批次的商品来源、生产信息、检测报告及合格证等内容,让消费更安心。

说明:

  • 第一阶段溯源说明区内容建议由前端写死为固定文案,不依赖后台配置
  • 若检测报告或合格证缺失,通过对应模块内“待补充”提示即可,不单独设置“数据完整性说明”区域

8. 底部引导

  • 联系客服
  • 引导回购买渠道(直播/小店)

5.3 页面状态设计

正常状态

  • 展示全部信息

空数据状态

  • 显示:
    • “检测报告待补充”
    • “合格证待补充”
    • “农场信息待补充”

异常状态

  • 批次不存在 → 提示“无效二维码”
  • 批次未发布 → 提示“暂未开放查询”
  • 批次已下线 → 提示“该批次已下线”

5.4 第一阶段溯源页展示建议(推荐采用卡片式布局)

推荐展示顺序

  1. 页面头部(品牌 + 标题 + 主视觉)
  2. 商品信息区
  3. 农场信息区
  4. 批次信息区
  5. 检测报告区
  6. 合格证区
  7. 溯源说明区
  8. 底部引导区

推荐展示原则

  • 先展示用户最关心的信息:商品、农场、批次
  • 再展示证明可信的信息:检测报告、合格证
  • 再展示平台与品牌说明,增强页面完整度
  • 第一阶段即使数据不全,也建议将展示结构预留完整,未填字段以空状态或待补充提示处理
  • 第一阶段展示字段以“实用、易维护、可快速上线”为原则,暂不引入冗余修饰型字段
  • 第一阶段仅保留必要展示字段,避免增加运营录入负担与前后端复杂度

6. 爱智农后台功能说明

6.1 批次管理

功能

  • 创建批次
  • 编辑批次
  • 查看批次
  • 上传检测报告(操作按钮)
  • 上传合格证(操作按钮)
  • 生成二维码
  • 打印标签
  • 发布/下线

关键规则

  • 创建时必须填写商品与农场信息
  • 草稿状态不可生成二维码

6.2 检测报告管理

  • 通过批次管理操作按钮上传
  • 支持 PDF 或多张图片上传
  • 支持查看/预览与覆盖上传

6.3 合格证管理

  • 通过批次管理操作按钮上传
  • 支持 PDF 或多张图片上传
  • 支持查看/预览与覆盖上传

6.4 二维码生成

  • 为批次生成唯一溯源链接
  • 生成二维码图片
  • 支持下载

6.5 标签打印管理

功能

  • 选择批次
  • 生成标签PDF
  • 下载打印文件

标签内容

  • 二维码(核心,保证清晰可扫码)
  • 商品名称(用户可快速识别商品)
  • 批次号(用于溯源对应)
  • 简要提示文案(如:扫码查看溯源信息)
  • 品牌名称(佳友厚苑,可选)
  • 打印日期(可选)

标签展示设计建议

  • 不建议仅打印二维码,必须搭配文字说明,否则用户无法理解用途
  • 推荐结构:二维码在中间或左侧,文字信息在下方或右侧
  • 建议至少包含一句引导语:如“扫码查看商品溯源信息”
  • 商品名称建议简化显示,避免过长导致排版拥挤
  • 批次号可使用较小字体展示
  • 整体布局保持简洁,确保二维码识别优先

6.6 发布管理

批次状态:

  • 草稿:不可扫码
  • 已发布:可扫码
  • 已下线:不可扫码

7. 字段定义(简要)

批次

  • batchNo
  • productName
  • productSpec
  • productImage
  • productDesc
  • farmName
  • farmRegion
  • farmImage
  • farmIntro
  • produceDate
  • packageDate
  • status

检测报告

  • reportStatus(上传状态:uploaded/pending)
  • reportFiles(文件列表,支持PDF或多图)
  • reportDate(必填)
  • reportNo(必填)

合格证

  • certStatus(上传状态:uploaded/pending)
  • certFiles(文件列表,支持PDF或多图)
  • certIssueDate(必填)
  • certNo(必填)

8. 二维码与标签打印方案

8.1 二维码内容

  • 二维码本质为一个带 batchId 的溯源访问链接
  • 推荐格式:/trace/{batchId}(可扩展 source、campaign 参数)
  • 若区分入口来源,可扩展参数:
    • source:来源渠道(如 packaging / douyin / wechat / service)
    • campaign:活动标识(可选)

第一阶段二维码承载的信息原则

  • 二维码本身只承载访问入口,不直接写入完整业务数据
  • 实际展示内容通过 batchId 在后台查询获取
  • 所有前端展示内容均通过批次数据统一返回

二维码关联的前端展示内容

扫码后进入溯源页,页面展示内容包括:

  • 商品信息
  • 农场信息
  • 批次信息
  • 检测报告
  • 合格证
  • 溯源说明

二维码生成规则

  • 每个批次生成唯一二维码
  • 未发布批次不可生成正式可用二维码
  • 批次下线后,扫码应提示“该批次已下线”或“暂不可查询”

8.2 打印方案

  • 打印机:热敏标签打印机
  • 标签尺寸:40×30mm(推荐)
  • 文件格式:PDF
  • 打印方式:人工触发
  • 标签打印内容建议与溯源页保持一致性(至少包含商品名与批次号)
  • 标签需包含用户可读信息(如商品名称 + 溯源提示语),避免仅二维码导致用户无法理解用途
  • 二维码尺寸需保证可扫码识别
  • 生成的PDF需固定尺寸,避免打印缩放导致二维码失效
  • 首期采用“后台生成PDF + 人工触发打印”的轻方案

9. 接口清单(第一阶段)

本章节仅作为接口总览,详细接口定义及返回结构详见第 14 章。

前端核心接口:

  • 获取溯源详情接口(/api/trace/{batchId})

后台接口分类:

  • 批次管理
  • 检测报告管理
  • 合格证管理
  • 二维码生成
  • 标签打印

10. 验收标准

  • 能创建批次
  • 能上传检测报告
  • 能上传合格证
  • 能生成二维码
  • 扫码可打开溯源页
  • 页面显示真实数据
  • 页面展示结构完整(商品 / 农场 / 批次 / 检测报告 / 合格证)
  • 报告与合格证支持预览或查看原件
  • 页面空状态与异常状态展示正常
  • 标签可打印
  • 打印二维码可扫码

11. 开发排期建议

第1-2天

  • 确认字段
  • 确认页面结构
  • 确认打印方案

第3-5天

  • 前端溯源页开发
  • 批次后台开发
  • 文件上传功能

第6-7天

  • 二维码生成
  • 标签打印功能
  • 联调

第8-10天

  • 测试
  • 修复问题
  • 优化细节

12. 总体原则

  • 批次为核心数据模型
  • 前端只展示,不维护数据
  • 优先保证“能用”
  • 不追求复杂功能
  • 先跑通,再优化

13. 数据库设计(第一阶段)

13.1 批次表(batch)

字段:

  • id(主键)
  • batch_no(批次号,唯一)
  • product_name(商品名称)
  • product_spec(商品规格)
  • product_image(商品图片URL)
  • product_desc(商品简介,可选)
  • farm_name(农场名称)
  • farm_region(农场所在地)
  • farm_image(农场图片URL)
  • farm_intro(农场简介,可选)
  • produce_date(生产/采收日期)
  • package_date(包装日期)
  • status(状态:draft/published/offline)
  • created_at
  • updated_at

约束:

  • batch_no 唯一
  • status 仅允许:draft/published/offline

13.2 检测报告表(report)

字段:

  • id(主键)
  • batch_id(关联批次)
  • report_status(状态:uploaded/pending)
  • report_files(JSON数组,文件URL列表)
  • report_no(报告编号,必填)
  • report_date(检测日期,必填)
  • created_at

约束:

  • batch_id 唯一(第一阶段每批次仅一条报告)

13.3 合格证表(certificate)

字段:

  • id(主键)
  • batch_id(关联批次)
  • cert_status(状态:uploaded/pending)
  • cert_files(JSON数组,文件URL列表)
  • cert_no(合格证编号,必填)
  • cert_issue_date(开具日期,必填)
  • created_at

约束:

  • batch_id 唯一(第一阶段每批次仅一张合格证)

14. 接口设计(第一阶段)

14.1 前端溯源接口(核心)

GET /api/trace/{batchId}

返回示例: { "batch": {

"batchNo": "B20250101",
"productName": "有机鸡蛋",
"productSpec": "30枚",
"productImage": "https://example.com/product.jpg",
"productDesc": "新鲜鸡蛋,适合家庭日常食用。",
"farmName": "阳光农场",
"farmRegion": "陕西西安",
"farmImage": "https://example.com/farm.jpg",
"farmIntro": "阳光农场位于西安周边,采用规范化种养管理。",
"produceDate": "2025-01-01",
"packageDate": "2025-01-02",
"status": "published"

}, "report": {

"reportStatus": "uploaded",
"reportFiles": ["https://example.com/report1.jpg"],
"reportDate": "2025-01-02",
"reportNo": "R20250102001"

}, "certificate": {

"certStatus": "uploaded",
"certFiles": ["https://example.com/cert1.jpg"],
"certIssueDate": "2025-01-02",
"certNo": "C20250102001"

} }

说明:

  • 前端所有展示数据统一通过该接口返回
  • productDesc、farmIntro 为可选字段
  • reportStatus、certStatus 表示“文件上传状态”,不是检测结果
  • 前端需将 uploaded/pending 映射为“已上传/待补充”进行展示

14.2 后台接口

批次:

  • POST /api/batch(创建)
  • GET /api/batch/list(列表)
  • GET /api/batch/{id}(详情)
  • PUT /api/batch/{id}(编辑)
  • POST /api/batch/{id}/publish(发布)
  • POST /api/batch/{id}/offline(下线)

检测报告:

  • POST /api/report/upload
  • GET /api/report/{batchId}

合格证:

  • POST /api/certificate/upload
  • GET /api/certificate/{batchId}

二维码:

  • GET /api/qrcode/{batchId}

打印:

  • GET /api/print/{batchId}

15. 业务规则说明

15.1 批次规则

  • 批次必须绑定商品与农场信息
  • 批次创建后默认状态为 draft
  • draft 状态不可生成二维码
  • 只有 published 状态可扫码访问
  • offline 状态扫码提示不可用

15.2 文件规则

  • 每个批次多检测报告(支持多文件)
  • 每个批次多个合格证(支持多文件)
  • 支持 PDF 或多张图片上传
  • 报告编号、检测日期为必填
  • 合格证编号、开具日期为必填
  • 支持覆盖上传(新文件覆盖旧文件)

15.3 二维码规则

  • 每个批次生成唯一二维码
  • 二维码内容为带 batchId 的溯源访问链接
  • 可扩展 source / campaign 参数用于渠道区分

15.4 打印规则

  • 标签必须包含二维码 + 商品名称 + 批次号
  • 打印文件为固定尺寸 PDF
  • 不允许缩放打印

15.5 页面展示规则

  • 页面数据统一来源于批次接口
  • 数据缺失需展示“待补充”
  • 商品简介、农场简介为可选字段
  • 报告/合格证状态由后端返回,前端根据状态展示
  • reportStatus、certStatus 仅表示文件是否上传,不表示检测是否合格


16. HTTP 请求工具模块

16.1 模块概述

项目已集成企业级 HTTP 请求工具模块,提供统一的网络请求能力,支持 Web 和 uni-app 多端运行。

核心特性

  • 基于 axios 封装,支持 uni-app 适配
  • 统一的请求/响应拦截器
  • 自动 Token 管理
  • 统一错误处理
  • 文件上传/下载支持
  • 请求重试机制
  • 防重复请求
  • 多环境配置

16.2 目录结构

utils/
├── request.js          # 核心请求模块(基于 axios)
├── uniRequest.js       # uni-app 原生请求适配器(备选)
├── upload.js           # 文件上传模块
├── download.js         # 文件下载模块
├── retry.js            # 请求重试模块
├── storage.js          # 本地存储模块
├── ui.js               # UI 交互模块
├── platform.js         # 平台检测模块
├── env.js              # 环境配置模块
├── index.js            # 统一导出
├── README.md           # 使用文档
└── ARCHITECTURE.md     # 架构设计文档

api/
├── user.js             # 用户相关 API
├── order.js            # 订单相关 API
├── product.js          # 产品相关 API
└── index.js            # API 统一导出

16.3 快速使用

基础请求

import { getUserInfo, getOrderList } from '@/api'

export default {
  async onLoad() {
    // 获取用户信息
    const userInfo = await getUserInfo()
    
    // 获取订单列表
    const orders = await getOrderList({ page: 1, size: 10 })
  }
}

文件上传

import { chooseAndUploadImage } from '@/utils/upload'

const handleUpload = async () => {
  const result = await chooseAndUploadImage({
    count: 1,
    onProgress: (progress) => {
      console.log('上传进度:', progress + '%')
    }
  })
  console.log('上传成功', result)
}

文件下载

import { downloadFile } from '@/utils/download'

const handleDownload = async () => {
  await downloadFile('/file/download', '文件名.pdf')
}

16.4 配置说明

环境配置

修改 utils/env.js 配置不同环境的 API 地址:

const envConfig = {
  development: {
    baseURL: 'http://localhost:3000/api',
    timeout: 10000
  },
  production: {
    baseURL: 'https://api.example.com/api',
    timeout: 20000
  }
}

Token 配置

Token 会自动注入到请求头,格式为:

config.headers['Authorization'] = `Bearer ${token}`

如需修改格式,编辑 utils/request.js 中的请求拦截器。

白名单配置

不需要 Token 的接口添加到白名单:

const WHITE_LIST = [
  '/auth/login',
  '/auth/register',
  '/auth/captcha'
]

16.5 API 层设计

按业务模块组织

// api/user.js
export const login = (data) => post('/auth/login', data)
export const getUserInfo = () => get('/user/info')

// api/order.js
export const getOrderList = (params) => get('/order/list', params)
export const createOrder = (data) => post('/order/create', data)

统一导出

// api/index.js
export * from './user'
export * from './order'
export * from './product'

16.6 错误处理

全局错误处理

已在 utils/request.js 中实现:

  • HTTP 状态码错误(401、403、500 等)
  • 业务错误码处理
  • Token 过期自动跳转登录
  • 网络错误处理

局部错误处理

try {
  const data = await getUserInfo()
} catch (error) {
  console.error('获取用户信息失败', error)
}

隐藏错误提示

const data = await getUserInfo({}, {
  hideError: true  // 不显示错误提示
})

16.7 高级功能

请求重试

import { createRetryRequest } from '@/utils/retry'

const getDataWithRetry = createRetryRequest(
  () => get('/api/data'),
  3 // 最大重试 3 次
)

并发请求

const [userInfo, orders, products] = await Promise.all([
  getUserInfo(),
  getOrderList({ page: 1 }),
  getProductList({ page: 1 })
])

请求取消

import axios from 'axios'

const source = axios.CancelToken.source()

get('/api/data', {}, {
  cancelToken: source.token
})

// 取消请求
source.cancel('请求被用户取消')

16.8 配置项说明

所有请求方法都支持以下配置:

{
  showLoading: true,           // 是否显示 loading
  loadingText: '加载中...',    // loading 文字
  hideError: false,            // 是否隐藏错误提示
  preventDuplicate: false,     // 是否防止重复请求
  noCache: false,              // 是否添加时间戳防缓存
  timeout: 10000,              // 超时时间
  headers: {}                  // 自定义请求头
}

16.9 详细文档

更多详细信息请参考:

  • utils/README.md - 完整使用文档
  • utils/ARCHITECTURE.md - 架构设计文档
  • utils/examples/INSTALL.md - 安装配置指南
  • utils/examples/ - 示例代码

16.10 注意事项

  1. 首次使用前需配置 utils/env.js 中的 baseURL
  2. 根据后端返回格式调整 utils/request.js 中的业务状态码
  3. 根据后端 Token 格式调整请求拦截器中的 Token 注入方式
  4. 小程序环境需在管理后台配置服务器域名白名单
  5. 所有 API 接口建议统一在 api/ 目录下管理,不要在组件中直接调用 request