Compare commits

...

9 Commits

Author SHA1 Message Date
史悦
817a7f6da6 优化统计计算器HTML结构和代码 2025-09-16 17:34:34 +08:00
史悦
c9e1bb951c 修复计算 2025-09-16 16:36:53 +08:00
史悦
0d7d5b0a43 根据提供的统计摘要,我看到有3个文件发生了变化:
- 新增了一个关于汇率预测的markdown文件(125行新增)
- 修改了一个工作计划汇报的HTML文件(大量修改)
- 新增了一个统计计算器的HTML文件(451行新增)

基于这些变化,生成的常规提交信息如下:

feat: 新增汇率预测文档和统计计算器功能

- 新增汇率预测相关的markdown文档
- 新增统计计算器HTML页面,提供数据分析功能
- 重构工作计划汇报页面,优化内容结构和布局
2025-09-16 15:51:00 +08:00
史悦
5c9a60ee27 我已经收到了你的文档,里面包含了一个 Git 提交信息生成器的系统指令。
从文档内容来看,这是一个专门用于分析 Git diff 输出并生成符合 Conventional Commits 规范的提交信息的工具。我注意到:

1. **当前状态**:你在 `master` 分支上,刚刚添加了一个名为 `...规划汇报.html` 的新文件(1059行新增内容)

2. **最近的提交历史**显示你在开发一个产品相关的项目,包括:
   - 产品生命周期指标曲线图
   - 精益画布和智能回收终端UI
   - 产品需求文档优化
   - 高保真UI原型设计

根据提供的 diff 统计信息,这次的变更是添加了一个新的 HTML 文件,看起来是产品规划汇报相关的内容。

按照 Conventional Commits 规范,我建议的提交信息是:

feat: 新增产品规划汇报HTML页面

如果你需要我根据更详细的 diff 内容来优化这个提交信息,或者有其他关于这个提交信息生成器的问题,请告诉我!
2025-09-15 18:03:31 +08:00
史悦
e31bf2855a feat: 新增产品生命周期指标曲线图SVG文件 2025-09-15 16:33:58 +08:00
史悦
83f1a51ae5 feat: 重构产品画布为精益画布并添加智能回收终端多角色UI界面 2025-09-15 16:19:57 +08:00
史悦
450f08d05c docs: 优化产品需求文档和功能模块文档结构
- 重构了产品需求文档的章节组织和内容结构
- 改进了智能功能模块的文档格式和可读性
- 优化了一键邻回收和用户故事文档的排版
- 新增了完整的规格文档模板和内容框架
- 统一了文档风格和格式规范,提升文档质量
2025-09-15 14:07:29 +08:00
史悦
8d228527d0 feat: 新增prototype-designer角色,并生成B端与C端高保真UI原型 2025-09-15 13:26:19 +08:00
史悦
e3a645d519 增加了设计,后台功能模块设计 2025-08-12 14:02:16 +08:00
30 changed files with 5132 additions and 406 deletions

19
.kilocode/mcp.json Normal file
View File

@@ -0,0 +1,19 @@
{
"mcpServers": {
"promptx": {
"command": "npx",
"args": [
"-y",
"-f",
"--registry",
"https://registry.npmjs.org",
"dpml-prompt@beta",
"mcp-server"
],
"alwaysAllow": [
"promptx_action",
"promptx_init"
]
}
}
}

View File

@@ -4,29 +4,73 @@
{ {
"from": "initial", "from": "initial",
"command": "action", "command": "action",
"timestamp": "2025-08-11T10:11:24.381Z", "timestamp": "2025-08-15T00:58:32.454Z",
"args": [ "args": [
"product-manager" "nuwa"
] ]
}, },
{ {
"from": "role_activated_with_memory", "from": "role_activated_with_memory",
"command": "init", "command": "init",
"timestamp": "2025-08-11T10:11:46.821Z", "timestamp": "2025-08-15T00:58:46.782Z",
"args": [ "args": [
{ {
"workingDirectory": "E:\\我的项目\\2023年12月21日" "workingDirectory": "e:\\我的项目\\2023年12月21日",
"ideType": "vscode"
} }
] ]
}, },
{ {
"from": "initialized", "from": "initialized",
"command": "action", "command": "action",
"timestamp": "2025-08-11T10:11:54.465Z", "timestamp": "2025-08-15T00:59:00.012Z",
"args": [
"nuwa"
]
},
{
"from": "role_activated_with_memory",
"command": "init",
"timestamp": "2025-08-15T01:01:30.679Z",
"args": [
{
"workingDirectory": "e:\\我的项目\\2023年12月21日",
"ideType": "vscode"
}
]
},
{
"from": "initialized",
"command": "action",
"timestamp": "2025-08-15T01:02:09.276Z",
"args": [
"prototype-designer"
]
},
{
"from": "role_activated_with_memory",
"command": "action",
"timestamp": "2025-08-15T01:04:54.139Z",
"args": [
"prototype-designer"
]
},
{
"from": "role_activated_with_memory",
"command": "action",
"timestamp": "2025-08-15T01:22:41.214Z",
"args": [ "args": [
"product-manager" "product-manager"
] ]
},
{
"from": "role_activated_with_memory",
"command": "action",
"timestamp": "2025-08-15T01:23:23.715Z",
"args": [
"prototype-designer"
]
} }
], ],
"lastUpdated": "2025-08-11T10:11:54.481Z" "lastUpdated": "2025-08-15T01:23:23.737Z"
} }

View File

@@ -4,9 +4,9 @@
"metadata": { "metadata": {
"version": "2.0.0", "version": "2.0.0",
"description": "project 级资源注册表", "description": "project 级资源注册表",
"createdAt": "2025-08-11T10:11:46.830Z", "createdAt": "2025-08-15T01:01:30.684Z",
"updatedAt": "2025-08-11T10:11:46.838Z", "updatedAt": "2025-08-15T01:01:30.691Z",
"resourceCount": 4 "resourceCount": 9
}, },
"resources": [ "resources": [
{ {
@@ -17,9 +17,9 @@
"description": "执行模式,定义具体的行为模式", "description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/product-manager/execution/workflow.execution.md", "reference": "@project://.promptx/resource/domain/product-manager/execution/workflow.execution.md",
"metadata": { "metadata": {
"createdAt": "2025-08-11T10:11:46.833Z", "createdAt": "2025-08-15T01:01:30.686Z",
"updatedAt": "2025-08-11T10:11:46.833Z", "updatedAt": "2025-08-15T01:01:30.686Z",
"scannedAt": "2025-08-11T10:11:46.833Z", "scannedAt": "2025-08-15T01:01:30.686Z",
"path": "domain/product-manager/execution/workflow.execution.md" "path": "domain/product-manager/execution/workflow.execution.md"
} }
}, },
@@ -31,9 +31,9 @@
"description": "专业角色,提供特定领域的专业能力", "description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/product-manager/product-manager.role.md", "reference": "@project://.promptx/resource/domain/product-manager/product-manager.role.md",
"metadata": { "metadata": {
"createdAt": "2025-08-11T10:11:46.834Z", "createdAt": "2025-08-15T01:01:30.686Z",
"updatedAt": "2025-08-11T10:11:46.834Z", "updatedAt": "2025-08-15T01:01:30.686Z",
"scannedAt": "2025-08-11T10:11:46.834Z", "scannedAt": "2025-08-15T01:01:30.686Z",
"path": "domain/product-manager/product-manager.role.md" "path": "domain/product-manager/product-manager.role.md"
} }
}, },
@@ -45,9 +45,9 @@
"description": "专业角色,提供特定领域的专业能力", "description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/project_manager/project_manager.role.md", "reference": "@project://.promptx/resource/domain/project_manager/project_manager.role.md",
"metadata": { "metadata": {
"createdAt": "2025-08-11T10:11:46.835Z", "createdAt": "2025-08-15T01:01:30.687Z",
"updatedAt": "2025-08-11T10:11:46.835Z", "updatedAt": "2025-08-15T01:01:30.687Z",
"scannedAt": "2025-08-11T10:11:46.835Z", "scannedAt": "2025-08-15T01:01:30.687Z",
"path": "domain/project_manager/project_manager.role.md" "path": "domain/project_manager/project_manager.role.md"
} }
}, },
@@ -59,21 +59,93 @@
"description": "专业角色,提供特定领域的专业能力", "description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/ui_ux_designer/ui_ux_designer.role.md", "reference": "@project://.promptx/resource/domain/ui_ux_designer/ui_ux_designer.role.md",
"metadata": { "metadata": {
"createdAt": "2025-08-11T10:11:46.836Z", "createdAt": "2025-08-15T01:01:30.687Z",
"updatedAt": "2025-08-11T10:11:46.836Z", "updatedAt": "2025-08-15T01:01:30.687Z",
"scannedAt": "2025-08-11T10:11:46.836Z", "scannedAt": "2025-08-15T01:01:30.687Z",
"path": "domain/ui_ux_designer/ui_ux_designer.role.md" "path": "domain/ui_ux_designer/ui_ux_designer.role.md"
} }
},
{
"id": "dev-manager",
"source": "project",
"protocol": "role",
"name": "Dev Manager 角色",
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/role/dev-manager/dev-manager.role.md",
"metadata": {
"createdAt": "2025-08-15T01:01:30.688Z",
"updatedAt": "2025-08-15T01:01:30.688Z",
"scannedAt": "2025-08-15T01:01:30.688Z",
"path": "role/dev-manager/dev-manager.role.md"
}
},
{
"id": "design-process",
"source": "project",
"protocol": "execution",
"name": "Design Process 执行模式",
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/role/prototype-designer/execution/design-process.execution.md",
"metadata": {
"createdAt": "2025-08-15T01:01:30.689Z",
"updatedAt": "2025-08-15T01:01:30.689Z",
"scannedAt": "2025-08-15T01:01:30.689Z",
"path": "role/prototype-designer/execution/design-process.execution.md"
}
},
{
"id": "design-specs",
"source": "project",
"protocol": "knowledge",
"name": "Design Specs 知识库",
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/role/prototype-designer/knowledge/design-specs.knowledge.md",
"metadata": {
"createdAt": "2025-08-15T01:01:30.690Z",
"updatedAt": "2025-08-15T01:01:30.690Z",
"scannedAt": "2025-08-15T01:01:30.690Z",
"path": "role/prototype-designer/knowledge/design-specs.knowledge.md"
}
},
{
"id": "prototype-designer",
"source": "project",
"protocol": "role",
"name": "Prototype Designer 角色",
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/role/prototype-designer/prototype-designer.role.md",
"metadata": {
"createdAt": "2025-08-15T01:01:30.690Z",
"updatedAt": "2025-08-15T01:01:30.690Z",
"scannedAt": "2025-08-15T01:01:30.690Z",
"path": "role/prototype-designer/prototype-designer.role.md"
}
},
{
"id": "design-thinking",
"source": "project",
"protocol": "thought",
"name": "Design Thinking 思维模式",
"description": "思维模式指导AI的思考方式",
"reference": "@project://.promptx/resource/role/prototype-designer/thought/design-thinking.thought.md",
"metadata": {
"createdAt": "2025-08-15T01:01:30.691Z",
"updatedAt": "2025-08-15T01:01:30.691Z",
"scannedAt": "2025-08-15T01:01:30.691Z",
"path": "role/prototype-designer/thought/design-thinking.thought.md"
}
} }
], ],
"stats": { "stats": {
"totalResources": 4, "totalResources": 9,
"byProtocol": { "byProtocol": {
"execution": 1, "execution": 2,
"role": 3 "role": 5,
"knowledge": 1,
"thought": 1
}, },
"bySource": { "bySource": {
"project": 4 "project": 9
} }
} }
} }

View File

@@ -0,0 +1,44 @@
<role>
<personality>
我是绿邻回收项目的研发经理,是技术战略的制定者和项目执行的保障者。我负责将产品蓝图转化为高质量、可扩展的技术现实。
我深度理解业务,以终为始,确保技术决策服务于核心商业目标。我关注团队成长,致力于打造一个高效、协作、有战斗力的研发团队。
<thought>
<exploration>
## 技术选型与架构探索
- **评估当前技术栈**Node.js + NestJS, uni-app, PostgreSQL。它们的优势和潜在风险是什么
- **预见未来挑战**:随着业务扩展(如物流、积分商城),当前架构需要预留哪些扩展点?
- **寻找效率杠杆**团队对NestJS和uni-app的熟练度如何如何通过技术预研和规范统一来提升效率
</exploration>
</thought>
</personality>
<principle>
<execution>
<constraint>
## 关键约束
- **MVP范围**: 严格遵守初步设计文档中定义的MVP范围任何变更需经产品、项目、研发三方评估。
- **技术栈**: 遵循选定的技术栈 (Node.js/NestJS, uni-app, PostgreSQL),任何调整需充分论证。
- **时间表**: 遵循4周2个Sprint完成MVP的总体排期。
</constraint>
<rule>
## 强制规则
- **每日站会**: 必须在每天上午10点组织15分钟站会同步进度、风险和阻塞点。
- **每周复盘**: 必须在每周五下午进行功能演示和复盘。
- **API文档先行**: 后端必须在Sprint 1结束时提供完整的API文档。
- **E2E测试**: MVP上线前必须通过核心流程的端到端测试。
</rule>
<guideline>
## 指导原则
- **风险驱动**: 主动识别技术、团队和需求风险,并制定应对策略。
- **质量内建**: 在开发流程中融入代码审查Code Review、单元测试保障交付质量。
</guideline>
</execution>
</principle>
<knowledge>
## 绿邻回收项目特定知识
- **核心矛盾**: 居民“便捷、透明处理废品”的需求与传统回收行业“效率低下、信息不透明”现状的矛盾。
- **MVP目标**: 跑通“居民到小站”的核心商业模式闭环。
- **核心用户**: 对价格敏感、希望操作简单的中老年用户(王大妈)。
</knowledge>
</role>

View File

@@ -0,0 +1,22 @@
<execution>
<constraint>
## 任务约束
- **输入**: 接收并等待用户提供明确的产品需求、功能设计和信息架构。
- **输出**: 根据用户的具体需求,结合{设计风格}和{技术规格}输出一套UI设计方案并生成一个`UI.html`文件。
- **页面要求**: 遵循用户的具体页面设计和布局要求。
</constraint>
<rule>
## 执行规则
1. **严格遵守技术规格**: 所有设计产出必须严格符合`design-specs.knowledge.md`中定义的技术规格。
2. **代码实现**: 最终产出物为包含所有页面的单个`UI.html`文件。
3. **内容填充**: 使用免费的无版权图片完成空白照片的填充。
4. **布局**: 页面布局需按照“一横排四个”的要求完成。
</rule>
<process>
## 工作流程
1. **需求沟通**: 主动与用户沟通,获取并确认产品需求、目标用户、核心功能和页面布局等信息。
2. **原型设计**: 根据确认的需求进行UI设计并编写HTML和Tailwind CSS代码。
3. **交付与反馈**: 将生成的`UI.html`文件交付给用户,并请求反馈。
4. **迭代修改**: 根据用户的反馈进行修改,直到用户满意为止。
</process>
</execution>

View File

@@ -0,0 +1,11 @@
<knowledge>
## 技术规格清单
- **页面尺寸**: 单个页面尺寸为 375x812px带有描边模拟手机边框。
- **图标**: 引用在线矢量图标库内的图标 (任何图标都不要带有背景色块、底板、外框)。
- **图片**: 使用开源图片网站链接的形式引入 (例如: Unsplash, Pexels)。
- **样式**: 必须引入 Tailwind CSS CDN 来完成。
- **显示**:
- 不要显示状态栏以及时间、信号等信息。
- 不要显示非移动端元素,如滚动条。
- **文字**: 所有文字只可以使用黑色或白色。
</knowledge>

View File

@@ -0,0 +1,15 @@
<role>
<personality>
# 角色:资深原型设计师 & 前端开发工程师
我是一位在设计与前端开发领域拥有丰富经验的专家,致力于在优雅的极简主义美学与强大的功能性之间找到完美的平衡点。
@!thought://design-thinking
</personality>
<principle>
@!execution://design-process
</principle>
<knowledge>
@!knowledge://design-specs
</knowledge>
</role>

View File

@@ -0,0 +1,25 @@
<thought>
<exploration>
## 设计风格探索
- **美学核心**: 优雅的极简主义美学与功能的完美平衡。
- **色彩策略**: 清新柔和的渐变配色与品牌色系浑然一体强调色根据APP类型灵活选择。
- **空间感**: 恰到好处的留白设计,营造轻盈通透的沉浸式体验。
- **信息架构**: 通过微妙的阴影过渡与模块化卡片布局,呈现清晰的信息层级,引导用户视线自然聚焦核心功能。
- **细节打磨**: 精心打磨的圆角、细腻的微交互、舒适的视觉比例,共同提升产品质感。
</exploration>
<reasoning>
## 设计理念推理
- 极简不是简单,而是为了突出核心功能,减少用户认知负荷。
- 色彩和渐变服务于品牌表达和用户情绪引导。
- 留白和布局是构建呼吸感和秩序感的关键。
- 细节决定体验,微交互能创造情感连接。
</reasoning>
<plan>
## 设计执行计划
1. **理解需求**: 深入理解产品经理的功能设计和信息架构。
2. **确立风格**: 根据产品类型(如旅游攻略)确定主色和强调色。
3. **布局优先**: 先进行模块化卡片布局和信息层级规划。
4. **视觉细化**: 填充色彩、图片、图标,并调整间距、圆角等细节。
5. **交互点缀**: 在关键操作上增加细腻的微交互效果。
</plan>
</thought>

45
.superdesign/README.md Normal file
View File

@@ -0,0 +1,45 @@
# 绿邻回收小程序 - 高保真原型 V1.1
此目录存放了“绿邻回收”项目当前最新的高保真HTML原型。
**版本**: `1.1`
**更新日期**: `2025-08-12`
**状态**: `已根据优化方案 V1.1 更新`
---
## 原型文件说明
### 1. C端 (居民端) 原型
- **文件**: [`c_end_prototype_v1.1.html`](c_end_prototype_v1.1.html)
- **主题**: [`c_end_theme_v1.1.css`](c_end_theme_v1.1.css)
- **查看方式**: 直接在浏览器中打开 `c_end_prototype_v1.1.html` 文件。
- **核心更新**:
- 优化了“我的卖品码”交互,改为点击全屏显示。
- 增加了小站“营业中”的实时状态显示。
- 丰富了交易记录和价格等静态数据,更具真实感。
- 修复了CSS路径问题。
### 2. B端 (小站端) 原型
- **文件**: [`b_end_prototype_v1.1.html`](b_end_prototype_v1.1.html)
- **主题**: [`b_end_theme_v1.1.css`](b_end_theme_v1.1.css)
- **查看方式**: 直接在浏览器中打开 `b_end_prototype_v1.1.html` 文件。
- **核心更新**:
- 强化了库存预警机制,对达到阈值的品类给予醒目的视觉提示。
- 增加了品类选择的交互逻辑,点击不同品类会高亮显示,并联动计算最终金额。
- 实现了模拟的语音播报功能(需要浏览器支持)。
### 3. 优化方案文档
- **文件**: [`prototype_optimization_plan.md`](prototype_optimization_plan.md)
- **内容**: 详细记录了本次原型优化的所有评估、分析和决策过程。
---
## 后续步骤
- **团队评审**: 相关干系人对本次更新后的原型进行评审。
- **UI交付**: 基于此原型UI/UX设计师可进行最终的视觉细节敲定和切图交付。
- **开发对接**: 前端开发工程师可基于此原型作为参考,开始组件化开发。

View File

@@ -0,0 +1,351 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>B端小站原型</title>
<!-- Tailwind CSS for utility classes -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<!-- Link to the B-side theme -->
<link rel="stylesheet" href="b_end_theme_v1.1.css">
<style>
/* General Body Styling from C-End for consistency */
body {
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
padding-top: 2rem;
padding-bottom: 2rem;
font-family: var(--font-sans) !important;
}
/* App container to simulate a phone screen */
.app-container {
width: 100%;
max-width: 420px;
height: 850px;
background-color: var(--background);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-2xl);
display: flex;
flex-direction: column;
overflow: hidden;
border: 8px solid #111;
position: relative;
}
.status-bar {
height: 30px;
background-color: #111;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1rem;
color: white;
font-size: 0.8rem;
flex-shrink: 0;
}
.status-bar .camera-notch {
width: 120px;
height: 20px;
background: #111;
border-radius: 0 0 10px 10px;
position: absolute;
top: 8px;
left: 50%;
transform: translateX(-50%);
}
.page {
flex-grow: 1;
overflow-y: auto;
background-color: var(--background);
animation: fadeIn 0.4s ease-out;
display: none; /* Hidden by default */
}
.page.active {
display: flex; /* Use flex for pages */
flex-direction: column;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* General purpose button style */
.btn-press {
transition: transform 0.1s ease;
}
.btn-press:active {
transform: scale(0.97);
}
</style>
</head>
<body>
<div class="app-container">
<div class="status-bar">
<span>10:00</span>
<div class="camera-notch"></div>
<div class="flex items-center space-x-1">
<i data-lucide="bar-chart-2" class="w-4 h-4"></i>
<i data-lucide="wifi" class="w-4 h-4"></i>
<span>100%</span>
</div>
</div>
<!-- Main Content Area -->
<main class="flex-grow overflow-hidden flex flex-col">
<!-- Screen: Workbench (Home) -->
<div id="screen-workbench" class="page active p-4 space-y-6">
<header class="flex justify-between items-center flex-shrink-0">
<div>
<h1 class="text-xl font-bold" style="color: var(--foreground);">工作台</h1>
<p class="text-sm" style="color: var(--muted-foreground);">老李的社区回收站</p>
</div>
<button class="btn-press p-2 rounded-md" style="background-color: var(--secondary);"><i data-lucide="more-horizontal" class="w-5 h-5"></i></button>
</header>
<div class="flex-grow flex flex-col justify-center space-y-8">
<button onclick="showScreen('screen-scan')" class="btn-press w-full py-8 rounded-lg shadow-lg" style="background-color: var(--primary); color: var(--primary-foreground);">
<div class="flex flex-col items-center justify-center">
<i data-lucide="scan-line" class="w-12 h-12 mb-2"></i>
<span class="text-2xl font-bold">开始回收</span>
</div>
</button>
<div class="p-4 rounded-lg" style="background-color: var(--card); border: 1px solid var(--border);">
<h2 class="text-lg font-semibold mb-3">今日汇总</h2>
<div class="grid grid-cols-3 gap-4 text-center">
<div>
<p id="summary-orders" class="text-3xl font-bold" style="color: var(--primary);">32</p>
<p class="text-sm" style="color: var(--muted-foreground);">总单数</p>
</div>
<div>
<p id="summary-weight" class="text-3xl font-bold" style="color: var(--primary);">150.5</p>
<p class="text-sm" style="color: var(--muted-foreground);">总重量 (kg)</p>
</div>
<div>
<p id="summary-amount" class="text-3xl font-bold" style="color: var(--primary);">¥210.00</p>
<p class="text-sm" style="color: var(--muted-foreground);">总金额</p>
</div>
</div>
</div>
</div>
<footer class="space-y-3 flex-shrink-0">
<button onclick="showScreen('screen-inventory')" class="btn-press w-full flex justify-between items-center p-4 rounded-lg" style="background-color: var(--secondary); color: var(--secondary-foreground);">
<div class="flex items-center">
<i data-lucide="boxes" class="w-6 h-6 mr-3"></i>
<span class="text-lg font-medium">库存盘点</span>
</div>
<div class="flex items-center">
<span class="text-sm font-semibold mr-2" style="color: var(--accent);">纸壳: 85%</span>
<i data-lucide="chevron-right" class="w-5 h-5"></i>
</div>
</button>
<button class="btn-press w-full flex justify-between items-center p-4 rounded-lg" style="background-color: var(--secondary); color: var(--secondary-foreground);">
<div class="flex items-center">
<i data-lucide="truck" class="w-6 h-6 mr-3"></i>
<span class="text-lg font-medium">向上游交接</span>
</div>
<i data-lucide="chevron-right" class="w-5 h-5"></i>
</button>
</footer>
</div>
<!-- Screen: Scan Customer Code -->
<div id="screen-scan" class="page p-4 bg-black text-white">
<header class="flex items-center flex-shrink-0">
<button onclick="showScreen('screen-workbench')" class="btn-press p-2 rounded-full"><i data-lucide="arrow-left" class="w-6 h-6"></i></button>
<h1 class="text-xl font-bold mx-auto">扫描识客</h1>
<div class="w-8"></div>
</header>
<div class="flex-grow flex flex-col items-center justify-center space-y-4">
<div class="w-64 h-64 border-4 border-dashed border-gray-400 rounded-lg flex items-center justify-center">
<i data-lucide="scan" class="w-24 h-24 text-gray-400"></i>
</div>
<p class="text-lg">请对准用户的卖品码</p>
<button onclick="showScreen('screen-details')" class="mt-8 px-6 py-2 bg-gray-700 rounded-md">模拟扫码成功</button>
</div>
</div>
<!-- Screen: Enter Details -->
<div id="screen-details" class="page p-4">
<header class="flex items-center mb-4 flex-shrink-0">
<button onclick="showScreen('screen-scan')" class="btn-press p-2 rounded-full"><i data-lucide="arrow-left" class="w-6 h-6"></i></button>
<h1 class="text-xl font-bold mx-auto">录入信息</h1>
<div class="w-8"></div>
</header>
<main class="flex-grow space-y-6 overflow-y-auto pr-2">
<div class="p-4 rounded-lg" style="background-color: var(--secondary);">
<span style="color: var(--muted-foreground);">顾客:</span>
<span class="text-lg font-bold">王大妈</span>
</div>
<div>
<h2 class="text-lg font-semibold mb-2">选择品类</h2>
<div class="grid grid-cols-3 gap-3">
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg border-2" style="border-color: var(--primary); color: var(--primary); background-color: var(--secondary);" data-price="1.2">纸壳</button>
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg" style="background-color: var(--card); border:1px solid var(--border);" data-price="2.0">塑料瓶</button>
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg" style="background-color: var(--card); border:1px solid var(--border);" data-price="1.1">报纸</button>
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg" style="background-color: var(--card); border:1px solid var(--border);" data-price="0.8">金属</button>
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg" style="background-color: var(--card); border:1px solid var(--border);" data-price="0.2">玻璃</button>
<button class="category-btn btn-press p-4 text-lg font-medium rounded-lg" style="background-color: var(--card); border:1px solid var(--border);" data-price="0.1">其他</button>
</div>
</div>
<div>
<h2 class="text-lg font-semibold mb-2">输入重量 (kg)</h2>
<input id="weight-input" type="number" value="12.5" class="w-full text-4xl font-bold p-4 text-center rounded-lg" style="background-color: var(--card); border: 1px solid var(--border); color: var(--foreground);" oninput="calculateAmount()">
</div>
<div class="text-center">
<h2 class="text-lg font-semibold mb-2">金额</h2>
<p id="amount-display" class="text-5xl font-bold" style="color: var(--primary);">¥15.00</p>
</div>
</main>
<footer class="mt-auto flex-shrink-0 pt-4">
<button onclick="confirmTransaction()" class="btn-press w-full py-5 text-xl font-bold rounded-lg shadow-lg" style="background-color: var(--primary); color: var(--primary-foreground);">
确认交易
</button>
</footer>
</div>
<!-- Screen: Inventory -->
<div id="screen-inventory" class="page p-4">
<header class="flex items-center mb-6 flex-shrink-0">
<button onclick="showScreen('screen-workbench')" class="btn-press p-2 rounded-full"><i data-lucide="arrow-left" class="w-6 h-6"></i></button>
<h1 class="text-xl font-bold mx-auto">库存盘点</h1>
<div class="w-8"></div>
</header>
<main class="space-y-5 overflow-y-auto">
<div class="p-4 rounded-lg" style="background-color: var(--card); border: 1px solid var(--border);">
<div class="flex justify-between items-center">
<h3 class="text-lg font-semibold">纸壳</h3>
<div class="flex items-center" style="color: var(--accent);">
<i data-lucide="alert-triangle" class="w-5 h-5 mr-1"></i>
<span class="font-semibold">库存警告</span>
</div>
</div>
<p class="font-mono text-sm mt-1"><span class="font-bold text-lg" style="color: var(--accent);">255.0</span> / 300 kg</p>
<div class="w-full h-4 rounded-full mt-2" style="background-color: var(--muted);">
<div class="h-4 rounded-full" style="width: 85%; background-color: var(--accent);"></div>
</div>
<p class="text-xs mt-2" style="color: var(--accent);">库存已达阈值,请及时联系上游清运。</p>
</div>
<div class="p-4 rounded-lg" style="background-color: var(--card); border: 1px solid var(--border);">
<div class="flex justify-between items-baseline mb-1">
<h3 class="text-lg font-semibold">塑料瓶</h3>
<p class="font-mono text-sm"><span class="font-bold text-lg" style="color: var(--primary);">80.2</span> / 200 kg</p>
</div>
<div class="w-full h-4 rounded-full" style="background-color: var(--muted);">
<div class="h-4 rounded-full" style="width: 40%; background-color: var(--primary);"></div>
</div>
</div>
<div class="p-4 rounded-lg" style="background-color: var(--card); border: 1px solid var(--border);">
<div class="flex justify-between items-baseline mb-1">
<h3 class="text-lg font-semibold">报纸</h3>
<p class="font-mono text-sm"><span class="font-bold text-lg" style="color: var(--primary);">35.5</span> / 100 kg</p>
</div>
<div class="w-full h-4 rounded-full" style="background-color: var(--muted);">
<div class="h-4 rounded-full" style="width: 35.5%; background-color: var(--primary);"></div>
</div>
</div>
</main>
</div>
</main>
</div>
<!-- Success Modal -->
<div id="success-modal" class="fixed inset-0 bg-black bg-opacity-50 flex-col items-center justify-center" style="display: none; z-index: 999;">
<div class="bg-white p-8 rounded-lg text-center shadow-xl transform scale-90 transition-transform duration-300">
<i data-lucide="check-circle" class="w-20 h-20 mx-auto" style="color: var(--primary);"></i>
<p id="success-message" class="text-2xl font-bold mt-4" style="color: var(--foreground);"></p>
<p class="text-lg" style="color: var(--muted-foreground);">交易成功</p>
</div>
</div>
<script>
lucide.createIcons();
function showScreen(screenId) {
document.querySelectorAll('.page').forEach(screen => {
screen.classList.remove('active');
});
document.getElementById(screenId).classList.add('active');
}
let currentPricePerKg = 1.2;
const categoryButtons = document.querySelectorAll('.category-btn');
categoryButtons.forEach(button => {
button.addEventListener('click', () => {
categoryButtons.forEach(btn => {
btn.style.borderColor = 'var(--border)';
btn.style.color = 'var(--foreground)';
btn.style.backgroundColor = 'var(--card)';
btn.classList.remove('border-2');
btn.classList.add('border');
});
button.style.borderColor = 'var(--primary)';
button.style.color = 'var(--primary)';
button.style.backgroundColor = 'var(--secondary)';
button.classList.add('border-2');
currentPricePerKg = parseFloat(button.dataset.price) || 0;
calculateAmount();
});
});
function calculateAmount() {
const weight = parseFloat(document.getElementById('weight-input').value) || 0;
const amount = (weight * currentPricePerKg).toFixed(2);
document.getElementById('amount-display').innerText = `¥${amount}`;
}
function confirmTransaction() {
const amountText = document.getElementById('amount-display').innerText;
const amountValue = parseFloat(amountText.replace('¥', ''));
const modal = document.getElementById('success-modal');
const message = document.getElementById('success-message');
message.innerText = amountText;
modal.style.display = 'flex';
setTimeout(() => {
modal.querySelector('div').style.transform = 'scale(1)';
}, 10);
const utterance = new SpeechSynthesisUtterance(`收款成功, ${amountValue}`);
utterance.lang = 'zh-CN';
speechSynthesis.speak(utterance);
setTimeout(() => {
modal.querySelector('div').style.transform = 'scale(0.9)';
setTimeout(() => {
modal.style.display = 'none';
showScreen('screen-workbench');
}, 300);
}, 2000);
}
showScreen('screen-workbench');
calculateAmount();
</script>
</body>
</html>

View File

@@ -0,0 +1,43 @@
:root {
--background: oklch(0.98 0.01 90);
--foreground: oklch(0.2 0.01 90);
--card: oklch(1.0000 0 0);
--card-foreground: oklch(0.2 0.01 90);
--popover: oklch(1.0000 0 0);
--popover-foreground: oklch(0.2 0.01 90);
--primary: oklch(0.65 0.18 150);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.9 0.03 150);
--secondary-foreground: oklch(0.2 0.01 90);
--muted: oklch(0.95 0 0);
--muted-foreground: oklch(0.5 0 0);
--accent: oklch(0.75 0.22 45); /* A more vibrant and friendly orange */
--accent-foreground: oklch(0.2 0.01 90);
--destructive: oklch(0.58 0.24 28);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.92 0.02 90);
--input: oklch(0.92 0.02 90);
--ring: oklch(0.65 0.18 150);
--chart-1: oklch(0.65 0.18 150);
--chart-2: oklch(0.75 0.18 55);
--chart-3: oklch(0.6 0.2 250);
--chart-4: oklch(0.7 0.15 110);
--chart-5: oklch(0.5 0.05 90);
--sidebar: oklch(0.98 0.01 90);
--sidebar-foreground: oklch(0.2 0.01 90);
--sidebar-primary: oklch(0.65 0.18 150);
--sidebar-primary-foreground: oklch(1 0 0);
--sidebar-accent: oklch(0.75 0.18 55);
--sidebar-accent-foreground: oklch(0.2 0.01 90);
--sidebar-border: oklch(0.92 0.02 90);
--sidebar-ring: oklch(0.65 0.18 150);
--font-sans: 'Inter', sans-serif;
--font-serif: 'Merriweather', serif;
--font-mono: 'JetBrains Mono', monospace;
--radius: 0.5rem;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--spacing: 0.25rem;
}

View File

@@ -12,7 +12,7 @@
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script> <script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<!-- Link to our generated theme --> <!-- Link to our generated theme -->
<link rel="stylesheet" href="design_iterations/recycle_theme_1.css"> <link rel="stylesheet" href="recycle_theme_1.css">
<style> <style>
/* General Body Styling */ /* General Body Styling */
@@ -232,23 +232,29 @@
<!-- Home Page --> <!-- Home Page -->
<div id="home-page" class="page"> <div id="home-page" class="page">
<div id="qr-code-button" class="card main-action-card"> <div id="qr-code-button" class="card main-action-card">
<h3 class="mb-2">我的卖品码</h3> <i data-lucide="qr-code" class="w-20 h-20 mx-auto mb-3"></i>
<div class="mx-auto bg-white p-2 rounded-md w-32 h-32 mb-2 flex items-center justify-center"> <h3 class="mb-2">点此出示卖品码</h3>
<img src="https://api.qrserver.com/v1/create-qr-code/?size=120x120&data=userID-12345" alt="QR Code"> <p class="text-sm opacity-90">让站长扫一扫,轻松卖废品</p>
</div>
<p class="text-sm opacity-90">点击展示二维码</p>
</div> </div>
<h2><i data-lucide="map-pin"></i>附近小站</h2> <h2><i data-lucide="map-pin"></i>附近小站</h2>
<div class="card"> <div class="card">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>
<p class="font-bold text-lg text-gray-800">幸福社区回收站</p> <div class="flex items-center">
<p class="font-bold text-lg text-gray-800">幸福社区回收站</p>
<span class="ml-3 inline-flex items-center rounded-full bg-green-100 px-3 py-1 text-sm font-medium text-green-700">
<svg class="mr-1.5 h-2 w-2 text-green-500" fill="currentColor" viewBox="0 0 8 8">
<circle cx="4" cy="4" r="3" />
</svg>
营业中
</span>
</div>
<p class="text-sm text-gray-500">营业时间: 08:00 - 20:00</p> <p class="text-sm text-gray-500">营业时间: 08:00 - 20:00</p>
</div> </div>
<div class="text-right"> <div class="text-right">
<p class="font-bold text-green-600">500米</p> <p class="font-bold text-green-600">500米</p>
<a href="#" class="text-sm text-blue-500">去这里 ></a> <a href="#" class="text-sm text-blue-500">地图导航 ></a>
</div> </div>
</div> </div>
</div> </div>
@@ -258,22 +264,22 @@
<div class="price-grid"> <div class="price-grid">
<div class="price-item"> <div class="price-item">
<p class="font-bold">纸壳</p> <p class="font-bold">纸壳</p>
<p class="price">1.2</p> <p class="price">1.25</p>
<p class="unit">元/斤</p> <p class="unit">元/斤</p>
</div> </div>
<div class="price-item"> <div class="price-item">
<p class="font-bold">塑料瓶</p> <p class="font-bold">塑料瓶</p>
<p class="price">2.0</p> <p class="price">0.08</p>
<p class="unit">元/</p> <p class="unit">元/</p>
</div> </div>
<div class="price-item"> <div class="price-item">
<p class="font-bold">铁皮</p> <p class="font-bold">旧报纸</p>
<p class="price">0.8</p> <p class="price">1.10</p>
<p class="unit">元/斤</p> <p class="unit">元/斤</p>
</div> </div>
<div class="price-item"> <div class="price-item">
<p class="font-bold">旧衣服</p> <p class="font-bold">旧衣服</p>
<p class="price">0.5</p> <p class="price">0.50</p>
<p class="unit">元/斤</p> <p class="unit">元/斤</p>
</div> </div>
</div> </div>
@@ -294,17 +300,24 @@
<div class="card divide-y divide-gray-200 p-0"> <div class="card divide-y divide-gray-200 p-0">
<div class="p-4 flex justify-between items-center"> <div class="p-4 flex justify-between items-center">
<div> <div>
<p class="font-bold text-gray-800">卖纸壳</p> <p class="font-bold text-gray-800">卖纸壳 (5.2斤)</p>
<p class="text-sm text-gray-500">12月21日 14:30</p> <p class="text-sm text-gray-500">今天 14:30</p>
</div> </div>
<p class="font-bold text-green-600 text-xl">+ ¥6.00</p> <p class="font-bold text-green-600 text-xl">+ ¥6.50</p>
</div> </div>
<div class="p-4 flex justify-between items-center"> <div class="p-4 flex justify-between items-center">
<div> <div>
<p class="font-bold text-gray-800">卖塑料瓶</p> <p class="font-bold text-gray-800">卖塑料瓶 (15个)</p>
<p class="text-sm text-gray-500">12月20日 10:15</p> <p class="text-sm text-gray-500">昨天 10:15</p>
</div> </div>
<p class="font-bold text-green-600 text-xl">+ ¥6.00</p> <p class="font-bold text-green-600 text-xl">+ ¥1.20</p>
</div>
<div class="p-4 flex justify-between items-center">
<div>
<p class="font-bold text-gray-800">卖旧报纸 (3.0斤)</p>
<p class="text-sm text-gray-500">2025-08-10</p>
</div>
<p class="font-bold text-green-600 text-xl">+ ¥3.30</p>
</div> </div>
<div class="p-4 text-center text-blue-500 cursor-pointer hover:bg-gray-50"> <div class="p-4 text-center text-blue-500 cursor-pointer hover:bg-gray-50">
查看更多 查看更多

View File

@@ -16,7 +16,7 @@
--muted-foreground: oklch(0.5000 0 0); --muted-foreground: oklch(0.5000 0 0);
/* 强调色 - 温暖橙色 */ /* 强调色 - 温暖橙色 */
--accent: oklch(0.7200 0.1500 50.0000); --accent: oklch(0.75 0.22 45); /* A more vibrant and friendly orange */
--accent-foreground: oklch(1.0000 0 0); --accent-foreground: oklch(1.0000 0 0);
/* 破坏性操作 - 柔和红色 */ /* 破坏性操作 - 柔和红色 */

View File

@@ -0,0 +1,303 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绿邻回收 - B端高保真原型</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Theme & Fonts -->
<link rel="stylesheet" href="green_neighbor_theme_b.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&family=Poppins:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<!-- Icons -->
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--bg-color: var(--background, oklch(0.99 0.01 240));
--fg-color: var(--foreground, oklch(0.1 0.02 250));
--card-color: var(--card, oklch(1 0 0));
--primary-color: var(--primary, oklch(0.6 0.18 250));
--primary-fg-color: var(--primary-foreground, oklch(0.99 0.01 250));
--destructive-color: var(--destructive, oklch(0.7 0.2 25));
--success-color: var(--success, oklch(0.65 0.15 150));
--radius-val: var(--radius, 0.5rem);
--font-sans-val: var(--font-sans, 'Poppins', 'Noto Sans SC', sans-serif);
--shadow-md-val: var(--shadow-md, 0 4px 6px -1px oklch(0.1 0.02 250 / 0.1), 0 2px 4px -2px oklch(0.1 0.02 250 / 0.1));
}
body {
background-color: #e9ebee; /* A neutral desktop background */
font-family: var(--font-sans-val) !important;
color: var(--fg-color) !important;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
padding: 2rem;
}
.mobile-container {
position: relative;
width: 375px;
height: 812px;
}
.mobile-frame {
width: 100%;
height: 100%;
border: 8px solid black;
border-radius: 40px;
background-color: var(--bg-color);
overflow: hidden;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
transition: transform 0.35s ease-out, opacity 0.35s ease-out;
z-index: 1;
}
.mobile-frame.hidden-right {
transform: translateX(100%);
opacity: 0;
pointer-events: none;
z-index: 0;
}
.mobile-frame.hidden-left {
transform: translateX(-50%);
opacity: 0;
pointer-events: none;
z-index: 0;
}
.screen {
width: 100%;
flex-grow: 1;
overflow-y: auto;
background-color: var(--bg-color);
}
.screen::-webkit-scrollbar { display: none; }
.bottom-nav {
width: 100%;
height: 70px;
background-color: var(--card-color);
border-top: 1px solid var(--border, #eee);
display: flex;
justify-content: space-around;
align-items: center;
flex-shrink: 0;
box-shadow: 0 -4px 10px rgba(0,0,0,0.05);
}
.card {
background-color: var(--card-color);
border-radius: var(--radius-val);
box-shadow: var(--shadow-md-val);
padding: 1.25rem;
}
/* Animations */
@keyframes shake {
10%, 90% { transform: translate3d(-1px, 0, 0); }
20%, 80% { transform: translate3d(2px, 0, 0); }
30%, 50%, 70% { transform: translate3d(-3px, 0, 0); }
40%, 60% { transform: translate3d(3px, 0, 0); }
}
.animate-shake {
animation: shake 0.7s cubic-bezier(.36,.07,.19,.97) both;
animation-iteration-count: 2;
}
</style>
</head>
<body>
<div class="mobile-container">
<!-- Frame 1: Main Screens (Workbench & Bills) -->
<div id="frame-main" class="mobile-frame">
<div id="screen-workbench" class="screen p-5">
<header class="mb-6">
<div class="flex justify-between items-center">
<div>
<h1 class="text-2xl font-bold">李老板</h1>
<p class="text-gray-500">社区便民超市站</p>
</div>
<i data-lucide="log-out" class="text-gray-400"></i>
</div>
</header>
<main>
<section class="text-center my-8">
<button id="start-recycling-btn" class="w-full py-8 rounded-xl text-white shadow-lg flex flex-col items-center justify-center transition-transform active:scale-95" style="background-color: var(--primary-color);">
<i data-lucide="scan-line" class="w-16 h-16"></i>
<span class="block text-2xl font-bold mt-4">开始回收</span>
</button>
</section>
<section class="card mb-4">
<h3 class="font-bold text-lg mb-3">今日汇总</h3>
<div class="grid grid-cols-3 text-center">
<div><p class="text-2xl font-bold">32</p><p class="text-sm text-gray-500">总单数</p></div>
<div><p class="text-2xl font-bold">158.7</p><p class="text-sm text-gray-500">总重量(kg)</p></div>
<div><p class="text-2xl font-bold" style="color: var(--success-color);">¥245.50</p><p class="text-sm text-gray-500">总金额</p></div>
</div>
</section>
<section class="card">
<div class="flex justify-between items-center mb-3">
<h3 class="font-bold text-lg">库存盘点</h3>
<span class="text-sm font-semibold flex items-center px-2 py-1 rounded animate-shake" style="background-color: oklch(var(--destructive) / 0.1); color: var(--destructive-color);">
<i data-lucide="alert-triangle" class="w-4 h-4 mr-1"></i>库存预警
</span>
</div>
<div class="space-y-3">
<div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center">
<span class="font-medium">废纸壳</span>
<div class="w-full bg-gray-200 rounded-full h-2.5"><div style="width: 90%; background-color: var(--destructive-color);" class="h-2.5 rounded-full"></div></div>
<span class="font-bold text-sm">90%</span>
</div>
<div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center">
<span class="font-medium">塑料瓶</span>
<div class="w-full bg-gray-200 rounded-full h-2.5"><div style="width: 45%; background-color: var(--primary-color);" class="h-2.5 rounded-full"></div></div>
<span class="font-bold text-sm">45%</span>
</div>
</div>
<button class="mt-5 w-full font-bold py-3 rounded-lg flex items-center justify-center" style="background-color: var(--secondary, #eee); color: var(--secondary-foreground, #333);"><i data-lucide="truck" class="w-5 h-5 mr-2"></i>一键通知物流交接</button>
</section>
<div class="card mt-4">
<h3 class="font-bold text-lg mb-2"><i data-lucide="bar-chart-3" class="w-5 h-5 mr-2 inline-block" style="color: var(--primary-color);"></i>近7日回收量 (kg)</h3>
<canvas id="bHistoryChart" height="180"></canvas>
</div>
</main>
</div>
<div class="bottom-nav">
<div class="flex flex-col items-center" style="color: var(--primary-color);"><i data-lucide="layout-dashboard"></i><span class="text-xs mt-1 font-bold">工作台</span></div>
<div class="flex flex-col items-center text-gray-400"><i data-lucide="book-marked"></i><span class="text-xs mt-1">账单</span></div>
</div>
</div>
<!-- Frame 2: Recycling Flow -->
<div id="frame-flow" class="mobile-frame hidden-right">
<div class="screen flex flex-col">
<header class="p-4 border-b flex items-center flex-shrink-0">
<button id="back-to-main-btn"><i data-lucide="arrow-left" class="w-6 h-6"></i></button>
<h1 class="font-bold text-xl flex-grow text-center mr-6">回收流程</h1>
</header>
<div class="p-5 flex-grow">
<div class="text-center bg-gray-100 p-3 rounded-lg mb-5">
<p class="text-sm text-gray-600">已识别用户</p>
<p class="font-bold text-2xl text-gray-800">王大妈</p>
</div>
<div class="mb-5">
<label class="font-bold text-lg">1. 选择品类</label>
<div class="grid grid-cols-3 gap-3 mt-2">
<button class="flow-category-btn active bg-blue-600 text-white p-4 rounded-lg font-bold text-lg">纸壳</button>
<button class="flow-category-btn bg-gray-200 text-gray-800 p-4 rounded-lg font-bold text-lg">塑料瓶</button>
<button class="flow-category-btn bg-gray-200 text-gray-800 p-4 rounded-lg font-bold text-lg">旧衣物</button>
</div>
</div>
<div>
<label class="font-bold text-lg">2. 输入重量 (斤)</label>
<input type="number" value="5.8" class="text-center text-6xl font-extrabold w-full mt-2 p-4 border-2 border-gray-200 rounded-lg focus:border-blue-500 focus:outline-none bg-gray-50">
</div>
</div>
<footer class="p-4 bg-white border-t-2 flex-shrink-0">
<div class="text-center">
<p class="text-gray-600">合计金额</p>
<p class="text-5xl font-bold mb-4" style="color: var(--primary-color);">¥4.93</p>
</div>
<button class="w-full text-white font-bold py-4 rounded-lg text-xl flex items-center justify-center active:scale-[0.98] transition-transform" style="background-color: var(--primary-color);">
<i data-lucide="volume-2" class="w-6 h-6 mr-2"></i>
<span>确认并语音播报</span>
</button>
</footer>
</div>
</div>
</div>
<script>
lucide.createIcons();
// Screen/Frame Navigation Logic
const frameMain = document.getElementById('frame-main');
const frameFlow = document.getElementById('frame-flow');
const startRecyclingBtn = document.getElementById('start-recycling-btn');
const backToMainBtn = document.getElementById('back-to-main-btn');
startRecyclingBtn.addEventListener('click', () => {
frameMain.classList.add('hidden-left');
frameFlow.classList.remove('hidden-right');
});
backToMainBtn.addEventListener('click', () => {
frameFlow.classList.add('hidden-right');
frameMain.classList.remove('hidden-left');
});
// Recycling Flow Category Buttons
const categoryBtns = document.querySelectorAll('.flow-category-btn');
categoryBtns.forEach(btn => {
btn.addEventListener('click', () => {
categoryBtns.forEach(b => {
b.classList.remove('active', 'bg-blue-600', 'text-white');
b.classList.add('bg-gray-200', 'text-gray-800');
});
btn.classList.add('active', 'bg-blue-600', 'text-white');
btn.classList.remove('bg-gray-200', 'text-gray-800');
});
});
// Chart.js for B-side
setTimeout(() => {
const bHistoryCtx = document.getElementById('bHistoryChart')?.getContext('2d');
if (bHistoryCtx) {
new Chart(bHistoryCtx, {
type: 'line',
data: {
labels: ['8/09', '8/10', '8/11', '8/12', '8/13', '8/14', '8/15'],
datasets: [{
label: '回收总量 (kg)',
data: [120, 150, 135, 180, 165, 210, 158.7],
fill: true,
backgroundColor: oklch(0.6 0.18 250 / 0.1),
borderColor: 'var(--chart-1)',
tension: 0.3,
pointBackgroundColor: 'var(--chart-1)',
pointRadius: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true,
plugins: { legend: { display: false } },
scales: {
y: { beginAtZero: false, grid: { drawBorder: false } },
x: { grid: { display: false } }
}
}
});
}
}, 100);
</script>
</body>
</html>

View File

@@ -0,0 +1,358 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绿邻回收 - C端高保真原型</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Theme & Fonts -->
<link rel="stylesheet" href="green_neighbor_theme_c.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- Icons -->
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
/* Mapped from theme file for easy access in this style block */
--bg-color: var(--background, oklch(0.99 0.01 240));
--fg-color: var(--foreground, oklch(0.15 0.01 240));
--card-color: var(--card, oklch(1 0 0));
--primary-color: var(--primary, oklch(0.65 0.15 150));
--primary-fg-color: var(--primary-foreground, oklch(0.98 0.01 150));
--secondary-color: var(--secondary, oklch(0.9 0.18 85));
--muted-fg-color: var(--muted-foreground, oklch(0.55 0.01 240));
--radius-val: var(--radius, 0.75rem);
--font-sans-val: var(--font-sans, 'Poppins', 'Noto Sans SC', sans-serif);
--shadow-md-val: var(--shadow-md, 0 4px 6px -1px oklch(0.15 0.01 240 / 0.1), 0 2px 4px -2px oklch(0.15 0.01 240 / 0.1));
}
body {
background-color: #e9ebee; /* A neutral desktop background */
font-family: var(--font-sans-val) !important;
color: var(--fg-color) !important;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
padding: 2rem;
}
.mobile-frame {
width: 375px;
height: 812px;
border: 8px solid black;
border-radius: 40px;
background-color: var(--bg-color);
overflow: hidden;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
position: relative;
display: flex;
flex-direction: column;
}
.screen {
width: 100%;
flex-grow: 1;
overflow-y: auto;
display: none; /* Hidden by default */
}
.screen.active {
display: block; /* Show active screen */
}
.screen::-webkit-scrollbar { display: none; }
.bottom-nav {
width: 100%;
height: 70px; /* Increased height for better touch area */
background-color: var(--card-color);
border-top: 1px solid var(--border, #eee);
display: flex;
justify-content: space-around;
align-items: center;
flex-shrink: 0;
box-shadow: 0 -4px 10px rgba(0,0,0,0.05);
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
font-weight: 500;
color: var(--muted-fg-color);
cursor: pointer;
transition: color 0.2s ease-in-out, transform 0.2s ease-in-out;
}
.nav-item:hover {
color: var(--primary-color);
transform: translateY(-2px);
}
.nav-item.active {
color: var(--primary-color);
}
.card {
background-color: var(--card-color);
border-radius: var(--radius-val);
box-shadow: var(--shadow-md-val);
padding: 1.25rem;
margin-bottom: 1rem;
}
/* Animations */
@keyframes slide-up-in {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-slide-up-in {
animation: slide-up-in 0.5s ease-out forwards;
}
.stagger-1 { animation-delay: 100ms; }
.stagger-2 { animation-delay: 200ms; }
.stagger-3 { animation-delay: 300ms; }
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: var(--shadow-lg-val);
}
50% {
transform: scale(1.02);
box-shadow: var(--shadow-xl-val);
}
}
.animate-pulse-gentle {
animation: pulse 2.5s infinite ease-in-out;
}
</style>
</head>
<body>
<div class="mobile-frame">
<!-- Screen: Home -->
<div id="screen-home" class="screen active p-5">
<header class="flex items-center mb-6 animate-slide-up-in">
<img src="https://images.unsplash.com/photo-1529665253569-6d01c0eaf7b6?q=80&w=40&auto=format&fit=crop" class="w-10 h-10 rounded-full object-cover mr-3" alt="avatar">
<div>
<p class="font-medium text-lg leading-tight">欢迎, 王大妈!</p>
<p class="text-sm text-gray-500">今天也是环保的一天</p>
</div>
</header>
<main>
<section class="text-center my-8 animate-slide-up-in stagger-1">
<button class="w-full py-8 rounded-2xl text-white shadow-lg flex flex-col items-center justify-center animate-pulse-gentle" style="background-color: var(--primary-color);">
<i data-lucide="qr-code" class="w-16 h-16"></i>
<span class="block text-2xl font-bold mt-4">我的卖品码</span>
</button>
<p class="text-center text-sm text-gray-500 mt-3">向小站站长出示此码,即可开始回收</p>
</section>
<section class="card animate-slide-up-in stagger-2">
<h3 class="font-bold text-lg mb-3 flex items-center">
<i data-lucide="tag" class="w-5 h-5 mr-2" style="color: var(--primary-color);"></i>
今日回收价
</h3>
<div class="space-y-3 text-lg">
<div class="flex justify-between items-baseline">
<span class="font-medium">废纸壳</span>
<span class="font-bold" style="color: var(--primary-color);">0.85 <span class="text-sm font-normal">元/斤</span></span>
</div>
<div class="flex justify-between items-baseline">
<span class="font-medium">塑料瓶</span>
<span class="font-bold" style="color: var(--primary-color);">0.10 <span class="text-sm font-normal">元/个</span></span>
</div>
<div class="flex justify-between items-baseline">
<span class="font-medium">旧衣物</span>
<span class="font-bold" style="color: var(--primary-color);">0.50 <span class="text-sm font-normal">元/斤</span></span>
</div>
</div>
</section>
<section class="card animate-slide-up-in stagger-3">
<h3 class="font-bold text-lg mb-4 flex items-center">
<i data-lucide="store" class="w-5 h-5 mr-2" style="color: var(--primary-color);"></i>
附近小站
</h3>
<div class="space-y-4">
<div class="flex items-center">
<div class="flex-grow">
<p class="font-bold">社区便民超市</p>
<p class="text-sm text-gray-500">距离您 200米</p>
</div>
<span class="text-sm font-semibold px-3 py-1 rounded-full" style="background-color: var(--secondary-color); color: var(--secondary-foreground);">营业中</span>
</div>
<div class="flex items-center">
<div class="flex-grow">
<p class="font-bold">好邻居快递驿站</p>
<p class="text-sm text-gray-500">距离您 500米</p>
</div>
<span class="text-sm font-semibold text-gray-500 bg-gray-200 px-3 py-1 rounded-full">休息中</span>
</div>
</div>
</section>
</main>
</div>
<!-- Screen: My -->
<div id="screen-my" class="screen p-5">
<header class="text-center pt-4 mb-6">
<img src="https://images.unsplash.com/photo-1529665253569-6d01c0eaf7b6?q=80&w=80&auto=format&fit=crop" class="w-20 h-20 rounded-full object-cover mx-auto mb-3 border-4 border-white shadow-lg" alt="avatar">
<h2 class="text-2xl font-bold">王大妈</h2>
<p class="text-gray-500 text-sm">环保积分: 1,280</p>
</header>
<main>
<section class="text-white p-6 rounded-2xl shadow-lg text-center mb-6" style="background: linear-gradient(45deg, var(--primary-color), oklch(0.7 0.15 140));">
<p class="text-lg opacity-90">我的余额 (元)</p>
<p class="text-5xl font-bold my-2">128.50</p>
<button class="mt-2 bg-white/20 hover:bg-white/30 text-white font-bold py-2 px-6 rounded-full text-sm">去提现</button>
</section>
<section class="space-y-3 text-lg">
<div class="flex justify-between items-center p-4 card">
<div class="flex items-center"><i data-lucide="receipt" class="w-6 h-6 mr-4" style="color: var(--primary-color);"></i><span>交易记录</span></div>
<i data-lucide="chevron-right" class="text-gray-400"></i>
</div>
<div class="flex justify-between items-center p-4 card">
<div class="flex items-center"><i data-lucide="message-square" class="w-6 h-6 mr-4" style="color: var(--primary-color);"></i><span>联系客服</span></div>
<i data-lucide="chevron-right" class="text-gray-400"></i>
</div>
</section>
<div class="card mt-6">
<h3 class="font-bold text-lg mb-2 flex items-center"><i data-lucide="pie-chart" class="w-5 h-5 mr-2" style="color: var(--primary-color);"></i>我的回收分布</h3>
<canvas id="cUserChart" height="180"></canvas>
</div>
<div class="card mt-2">
<h3 class="font-bold text-lg mb-2 flex items-center"><i data-lucide="bar-chart-3" class="w-5 h-5 mr-2" style="color: var(--primary-color);"></i>历史收入</h3>
<canvas id="cHistoryChart" height="180"></canvas>
</div>
</main>
</div>
<!-- Bottom Navigation -->
<div class="bottom-nav">
<div class="nav-item active" data-screen="home">
<i data-lucide="home"></i>
<span class="mt-1">首页</span>
</div>
<div class="nav-item" data-screen="my">
<i data-lucide="user-round"></i>
<span class="mt-1">我的</span>
</div>
</div>
</div>
<script>
// Initialize Lucide Icons
lucide.createIcons();
// Screen Navigation
const navItems = document.querySelectorAll('.nav-item');
const screens = document.querySelectorAll('.screen');
navItems.forEach(item => {
item.addEventListener('click', () => {
// Update nav active state
navItems.forEach(i => i.classList.remove('active'));
item.classList.add('active');
// Show the correct screen
const screenId = `screen-${item.dataset.screen}`;
screens.forEach(s => {
s.classList.remove('active');
if (s.id === screenId) {
s.classList.add('active');
// Reset scroll to top when switching
s.scrollTop = 0;
}
});
});
});
// Chart.js Initialization
// We wrap it in a timeout to ensure the canvas is visible when the chart is initialized, preventing rendering issues.
setTimeout(() => {
const chartFont = { family: "'Poppins', 'Noto Sans SC', sans-serif" };
// C端 - 我的回收分布
const cUserCtx = document.getElementById('cUserChart')?.getContext('2d');
if(cUserCtx) {
new Chart(cUserCtx, {
type: 'pie',
data: {
labels: ['废纸壳', '旧衣物', '塑料瓶'],
datasets: [{
label: '回收分布',
data: [60, 25, 15],
backgroundColor: ['var(--chart-1)', 'var(--chart-2)', 'var(--chart-3)'],
borderColor: 'var(--card-color)',
borderWidth: 2,
hoverOffset: 8
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom',
labels: { font: chartFont }
}
}
}
});
}
// C端 - 历史收入
const cHistoryCtx = document.getElementById('cHistoryChart')?.getContext('2d');
if(cHistoryCtx) {
new Chart(cHistoryCtx, {
type: 'bar',
data: {
labels: ['8/09', '8/10', '8/11', '8/12', '8/13', '8/14', '8/15'],
datasets: [{
label: '收入 (元)',
data: [5.2, 0, 12.5, 8.0, 0, 12.5, 4.93],
backgroundColor: 'var(--chart-1)',
borderRadius: 6,
}]
},
options: {
responsive: true,
plugins: {
legend: { display: false }
},
scales: {
y: { beginAtZero: true, grid: { drawBorder: false } },
x: { grid: { display: false } }
}
}
});
}
}, 100);
</script>
</body>
</html>

View File

@@ -0,0 +1,45 @@
:root {
--background: oklch(0.99 0.01 240);
--foreground: oklch(0.1 0.02 250);
--card: oklch(1 0 0);
--card-foreground: oklch(0.1 0.02 250);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.1 0.02 250);
--primary: oklch(0.6 0.18 250);
--primary-foreground: oklch(0.99 0.01 250);
--secondary: oklch(0.95 0.02 250);
--secondary-foreground: oklch(0.2 0.1 250);
--muted: oklch(0.96 0.01 240);
--muted-foreground: oklch(0.55 0.02 250);
--accent: oklch(0.97 0.03 250);
--accent-foreground: oklch(0.25 0.1 250);
--destructive: oklch(0.7 0.2 25);
--destructive-foreground: oklch(0.98 0.01 25);
--border: oklch(0.92 0.01 240);
--input: oklch(0.92 0.01 240);
--ring: oklch(0.6 0.18 250);
--success: oklch(0.65 0.15 150);
--chart-1: oklch(0.6 0.18 250);
--chart-2: oklch(0.7 0.2 25);
--chart-3: oklch(0.8 0.18 85);
--chart-4: oklch(0.5 0.1 290);
--chart-5: oklch(0.55 0.1 200);
--sidebar: oklch(0.99 0.01 240);
--sidebar-foreground: oklch(0.1 0.02 250);
--sidebar-primary: oklch(0.6 0.18 250);
--sidebar-primary-foreground: oklch(0.99 0.01 250);
--sidebar-accent: oklch(0.97 0.03 250);
--sidebar-accent-foreground: oklch(0.25 0.1 250);
--sidebar-border: oklch(0.92 0.01 240);
--sidebar-ring: oklch(0.6 0.18 250);
--font-sans: 'Poppins', 'Noto Sans SC', sans-serif;
--font-serif: 'Merriweather', 'Noto Serif SC', serif;
--font-mono: 'Geist Mono', monospace;
--radius: 0.5rem;
--shadow-sm: 0 1px 2px 0 oklch(0.1 0.02 250 / 0.05);
--shadow: 0 1px 3px 0 oklch(0.1 0.02 250 / 0.1), 0 1px 2px -1px oklch(0.1 0.02 250 / 0.1);
--shadow-md: 0 4px 6px -1px oklch(0.1 0.02 250 / 0.1), 0 2px 4px -2px oklch(0.1 0.02 250 / 0.1);
--shadow-lg: 0 10px 15px -3px oklch(0.1 0.02 250 / 0.1), 0 4px 6px -4px oklch(0.1 0.02 250 / 0.1);
--shadow-xl: 0 20px 25px -5px oklch(0.1 0.02 250 / 0.1), 0 8px 10px -6px oklch(0.1 0.02 250 / 0.1);
--shadow-2xl: 0 25px 50px -12px oklch(0.1 0.02 250 / 0.25);
}

View File

@@ -0,0 +1,44 @@
:root {
--background: oklch(0.99 0.01 240);
--foreground: oklch(0.15 0.01 240);
--card: oklch(1 0 0);
--card-foreground: oklch(0.15 0.01 240);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.15 0.01 240);
--primary: oklch(0.65 0.15 150);
--primary-foreground: oklch(0.98 0.01 150);
--secondary: oklch(0.9 0.18 85);
--secondary-foreground: oklch(0.3 0.1 85);
--muted: oklch(0.96 0.01 240);
--muted-foreground: oklch(0.55 0.01 240);
--accent: oklch(0.98 0.02 150);
--accent-foreground: oklch(0.3 0.1 150);
--destructive: oklch(0.7 0.2 20);
--destructive-foreground: oklch(0.98 0.01 20);
--border: oklch(0.92 0.01 240);
--input: oklch(0.92 0.01 240);
--ring: oklch(0.65 0.15 150);
--chart-1: oklch(0.65 0.15 150);
--chart-2: oklch(0.8 0.18 85);
--chart-3: oklch(0.7 0.2 280);
--chart-4: oklch(0.75 0.2 50);
--chart-5: oklch(0.6 0.2 200);
--sidebar: oklch(0.99 0.01 240);
--sidebar-foreground: oklch(0.15 0.01 240);
--sidebar-primary: oklch(0.65 0.15 150);
--sidebar-primary-foreground: oklch(0.98 0.01 150);
--sidebar-accent: oklch(0.98 0.02 150);
--sidebar-accent-foreground: oklch(0.3 0.1 150);
--sidebar-border: oklch(0.92 0.01 240);
--sidebar-ring: oklch(0.65 0.15 150);
--font-sans: 'Poppins', 'Noto Sans SC', sans-serif;
--font-serif: 'Merriweather', 'Noto Serif SC', serif;
--font-mono: 'Geist Mono', monospace;
--radius: 0.75rem;
--shadow-sm: 0 1px 2px 0 oklch(0.15 0.01 240 / 0.05);
--shadow: 0 1px 3px 0 oklch(0.15 0.01 240 / 0.1), 0 1px 2px -1px oklch(0.15 0.01 240 / 0.1);
--shadow-md: 0 4px 6px -1px oklch(0.15 0.01 240 / 0.1), 0 2px 4px -2px oklch(0.15 0.01 240 / 0.1);
--shadow-lg: 0 10px 15px -3px oklch(0.15 0.01 240 / 0.1), 0 4px 6px -4px oklch(0.15 0.01 240 / 0.1);
--shadow-xl: 0 20px 25px -5px oklch(0.15 0.01 240 / 0.1), 0 8px 10px -6px oklch(0.15 0.01 240 / 0.1);
--shadow-2xl: 0 25px 50px -12px oklch(0.15 0.01 240 / 0.25);
}

View File

@@ -0,0 +1,96 @@
# 绿邻回收小程序 - 原型优化方案 V1.1
> **文档状态**: 草稿
> **版本**: 1.1
> **日期**: 2025-08-12
> **制定人**: Roo (AI产品经理)
---
## 1. 概述
本方案基于对 `V1.0` 原型(`recycle_c_end_1.html` & `station_prototype_1.html`的评估并严格对标PRDV2.0和初步设计文档V1.0中的核心要求旨在提升原型质量使其更精准地反映产品设计为下一步的UI精修和开发提供清晰指引。
**核心优化原则**:
- **紧扣PRD**: 确保原型与需求文档100%对齐。
- **强化“适老化”**: 在现有基础上,进一步突出易用性和直观性。
- **提升真实感**: 引入动态数据和状态变化,使原型更具说服力。
---
## 2. C端居民端原型优化 (`recycle_c_end_1.html`)
### 2.1. 【P0-最高优先级】“我的卖品码”交互流程调整
- **当前问题**: 首页直接展示小二维码,点击后放大,不符合“极致简化”原则。
- **优化目标**: 遵循PRD将首页核心区域设计为单一、超大、醒目的功能入口降低用户决策成本。
- **设计建议**:
1. 移除首页卡片中的静态二维码图片。
2. 将整个卡片区域(`.main-action-card`)作为一个巨大的点击按钮。
3. 文案调整为更直接的行动指引,如将 `<h3>` 内容改为“点此出示卖品码”。
4. 点击后,全屏模态框(`.qr-modal`)弹出,展示大二维码,效果不变。
### 2.2. 【P1-高优先级】增加小站“营业状态”
- **当前问题**: “附近小站”卡片仅显示营业时间,未展示实时状态。
- **优化目标**: 让用户能一眼判断小站是否可以立即前往,避免白跑一趟。
- **设计建议**:
1. 在“幸福社区回收站”名称旁,增加一个状态标签。
2. **状态一(营业中)**: 绿色小圆点 + “营业中”文字,字体为绿色。
3. **状态二(休息中)**: 灰色小圆点 + “休息中”文字,字体为灰色。
4. (可选)在原型中增加一个切换按钮,用于演示两种状态的变化。
### 2.3. 【P2-中优先级】数据动态化与真实感提升
- **当前问题**: 所有价格、余额均为写死。
- **优化目标**: 模拟真实场景,让数据看起来是“活”的。
- **设计建议**:
1. **今日回收价**: 将价格设置为更真实、有小数点的数字,例如“纸壳: 1.25 元/斤”,“塑料瓶: 0.08 元/个”。
2. **交易记录**:
- 增加更多交易条目。
- 丰富交易类型,如“卖塑料瓶”、“卖旧报纸”。
- 使每笔交易的金额和时间都不同,增强真实性。
### 2.4. 【技术修正】修复CSS路径
- **当前问题**: HTML文件中引用的CSS路径为 `design_iterations/recycle_theme_1.css`,在当前文件结构下无法正确加载。
- **修复方案**: 将 `<link>` 标签中的 `href` 修改为 `"recycle_theme_1.css"`
---
## 3. B端小站端原型优化 (`station_prototype_1.html`)
### 3.1. 【P1-高优先级】强化库存预警机制
- **当前问题**: 库存进度条警告不明显,仅靠颜色区分。
- **优化目标**: 当库存超过阈值如80%)时,给予站长强烈的视觉提示,驱动其发起交接。
- **设计建议**:
1. 在“纸壳”库存项当前为85%)的进度条旁边,增加一个醒目的**黄色感叹号图标** (`<i data-lucide="alert-triangle"></i>`)。
2. 将“纸壳: 85%”的文字颜色改为强调色(`--accent-color`),使其更加突出。
3. 在进度条下方增加一行小字提示:“库存已达阈值,请及时联系上游清运”。
### 3.2. 【P1-高优先级】细化回收品类选择
- **当前问题**: 品类选择按钮是静态的。
- **优化目标**: 模拟真实选择品类的交互过程。
- **设计建议**:
1. 在JavaScript中增加逻辑当点击不同的品类按钮时高亮当前选中的按钮如改变边框和背景色并取消其他按钮的高亮。
2. 将不同品类的单价预设在代码中选择品类后下方的“金额”能根据对应单价和重量自动重新计算。例如纸壳1.2元/kg塑料瓶2.0元/kg。
### 3.3. 【P2-中优先级】交易成功语音播报优化
- **当前问题**: 语音播报功能已实现,但可以更完善。
- **优化目标**: 确保在所有设备和浏览器上都能获得最佳体验。
- **设计建议**:
1. 在调用 `speechSynthesis.speak()` 前,增加对 `speechSynthesis` API可用性的检查。
2. 允许用户在界面上(例如,在设置或一个不显眼的角落)控制语音播报的开关。
3. 语音内容可以更丰富例如“支付宝到账5.8元”改为“绿邻回收收款成功5.8元”,强化品牌认知。
---
## 4. 下一步计划
1. **内部评审**: 与项目核心成员特别是UI/UX设计师一同评审此优化方案。
2. **任务分配**: 根据评审结果将具体的优化点分配给UI/UX设计师进行视觉细化。
3. **原型更新**: 基于UI/UX的设计稿更新HTML/CSS原型文件。
4. **最终评审**: 对更新后的原型进行最终确认,确保所有优化点均已落实。

View File

@@ -0,0 +1,337 @@
<svg width="1200" height="1400" viewBox="0 0 1200 1400" xmlns="http://www.w3.org/2000/svg">
<!-- 背景 -->
<rect fill="#f8f9fa" width="100%" height="100%"/>
<!-- 主标题 -->
<text x="600" y="30" text-anchor="middle" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="24" font-weight="bold" fill="#28a745">绿邻回收智能终端系统 - 产品生命周期关键指标曲线图</text>
<!-- 短期规划标题 -->
<text x="600" y="70" text-anchor="middle" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="bold" fill="#1976d2">短期规划 (3年)</text>
<!-- 短期图表区域背景 -->
<rect x="80" y="90" width="1040" height="350" fill="white" stroke="#e1e4e8" stroke-width="1"/>
<!-- 短期图表水平网格线 -->
<g stroke="#e8e8e8" stroke-width="0.5">
<line x1="80" y1="130" x2="1120" y2="130"/>
<line x1="80" y1="170" x2="1120" y2="170"/>
<line x1="80" y1="210" x2="1120" y2="210"/>
<line x1="80" y1="250" x2="1120" y2="250"/>
<line x1="80" y1="290" x2="1120" y2="290"/>
<line x1="80" y1="330" x2="1120" y2="330"/>
<line x1="80" y1="370" x2="1120" y2="370"/>
<line x1="80" y1="410" x2="1120" y2="410"/>
</g>
<!-- 短期图表垂直网格线 -->
<g stroke="#e8e8e8" stroke-width="0.5">
<line x1="200" y1="90" x2="200" y2="440"/>
<line x1="350" y1="90" x2="350" y2="440"/>
<line x1="500" y1="90" x2="500" y2="440"/>
<line x1="650" y1="90" x2="650" y2="440"/>
<line x1="800" y1="90" x2="800" y2="440"/>
<line x1="950" y1="90" x2="950" y2="440"/>
</g>
<!-- 短期X轴标签 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="12" fill="#666" text-anchor="middle">
<text x="140" y="460">Q1</text>
<text x="200" y="460">Q2</text>
<text x="275" y="460">Q3</text>
<text x="350" y="460">Q4</text>
<text x="425" y="460">第2年</text>
<text x="575" y="460">第2年末</text>
<text x="725" y="460">第3年</text>
<text x="875" y="460">第3年末</text>
</g>
<!-- 短期阶段描述 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="10" fill="#888" text-anchor="middle">
<text x="140" y="475">启动</text>
<text x="200" y="475">验证</text>
<text x="275" y="475">增长</text>
<text x="350" y="475">扩张</text>
<text x="425" y="475">规模化</text>
<text x="575" y="475">成熟</text>
<text x="725" y="475">稳定</text>
<text x="875" y="475">优化</text>
</g>
<!-- 短期Y轴标签 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="11" fill="#666" text-anchor="end">
<text x="75" y="95">100%</text>
<text x="75" y="170">75%</text>
<text x="75" y="250">50%</text>
<text x="75" y="330">25%</text>
<text x="75" y="410">0%</text>
</g>
<!-- 短期用户增长曲线 -->
<path d="M 140,400 Q 170,380 200,350 Q 240,300 275,250 Q 315,200 350,170 Q 390,150 425,140 Q 500,130 575,125 Q 650,120 725,118 Q 800,115 875,113"
stroke="#4caf50" stroke-width="3" fill="none"/>
<!-- 短期收入增长曲线 -->
<path d="M 140,420 Q 170,400 200,370 Q 240,320 275,270 Q 315,220 350,180 Q 390,150 425,135 Q 500,125 575,120 Q 650,115 725,112 Q 800,110 875,108"
stroke="#2196f3" stroke-width="3" fill="none"/>
<!-- 短期终端部署曲线 -->
<path d="M 140,410 Q 170,390 200,360 Q 240,310 275,260 Q 315,210 350,175 Q 390,145 425,138 Q 500,128 575,123 Q 650,118 725,115 Q 800,112 875,110"
stroke="#ff9800" stroke-width="3" fill="none"/>
<!-- 短期关键节点标记 -->
<g fill="white" stroke-width="2">
<circle cx="140" cy="400" r="4" stroke="#4caf50"/>
<circle cx="200" cy="350" r="4" stroke="#4caf50"/>
<circle cx="275" cy="250" r="4" stroke="#4caf50"/>
<circle cx="350" cy="170" r="4" stroke="#4caf50"/>
<circle cx="575" cy="125" r="4" stroke="#4caf50"/>
<circle cx="875" cy="113" r="4" stroke="#4caf50"/>
</g>
<!-- 短期关键数据标注 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="9" fill="#666">
<text x="140" y="385" text-anchor="middle" font-weight="bold">5个终端</text>
<text x="200" y="335" text-anchor="middle" font-weight="bold">20个终端</text>
<text x="275" y="235" text-anchor="middle" font-weight="bold">100个终端</text>
<text x="350" y="155" text-anchor="middle" font-weight="bold">500个终端</text>
<text x="575" y="110" text-anchor="middle" font-weight="bold">2000个终端</text>
<text x="875" y="98" text-anchor="middle" font-weight="bold">5000个终端</text>
</g>
<!-- 短期图例 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="11">
<rect x="950" y="100" width="150" height="80" fill="white" stroke="#e1e4e8" stroke-width="1" rx="3"/>
<text x="1025" y="118" text-anchor="middle" font-weight="bold" fill="#333">短期指标</text>
<line x1="960" y1="130" x2="980" y2="130" stroke="#4caf50" stroke-width="2"/>
<text x="985" y="135" fill="#4caf50">用户增长</text>
<line x1="960" y1="145" x2="980" y2="145" stroke="#2196f3" stroke-width="2"/>
<text x="985" y="150" fill="#2196f3">收入增长</text>
<line x1="960" y1="160" x2="980" y2="160" stroke="#ff9800" stroke-width="2"/>
<text x="985" y="165" fill="#ff9800">终端部署</text>
</g>
<!-- 长期规划标题 -->
<text x="600" y="520" text-anchor="middle" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="bold" fill="#1976d2">长期规划 (6年)</text>
<!-- 定义图表区域 -->
<defs>
<linearGradient id="userGrowth" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4caf50;stop-opacity:0.3"/>
<stop offset="100%" style="stop-color:#4caf50;stop-opacity:0.8"/>
</linearGradient>
<linearGradient id="revenueGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#2196f3;stop-opacity:0.3"/>
<stop offset="100%" style="stop-color:#2196f3;stop-opacity:0.8"/>
</linearGradient>
<linearGradient id="terminalGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#ff9800;stop-opacity:0.3"/>
<stop offset="100%" style="stop-color:#ff9800;stop-opacity:0.8"/>
</linearGradient>
</defs>
<!-- 长期图表背景和网格 -->
<rect x="80" y="540" width="1040" height="600" fill="white" stroke="#e1e4e8" stroke-width="1"/>
<!-- 长期水平网格线 -->
<g stroke="#e8e8e8" stroke-width="0.5">
<line x1="80" y1="600" x2="1120" y2="600"/>
<line x1="80" y1="660" x2="1120" y2="660"/>
<line x1="80" y1="720" x2="1120" y2="720"/>
<line x1="80" y1="780" x2="1120" y2="780"/>
<line x1="80" y1="840" x2="1120" y2="840"/>
<line x1="80" y1="900" x2="1120" y2="900"/>
<line x1="80" y1="960" x2="1120" y2="960"/>
<line x1="80" y1="1020" x2="1120" y2="1020"/>
<line x1="80" y1="1080" x2="1120" y2="1080"/>
</g>
<!-- 长期垂直网格线 -->
<g stroke="#e8e8e8" stroke-width="0.5">
<line x1="150" y1="540" x2="150" y2="1140"/>
<line x1="280" y1="540" x2="280" y2="1140"/>
<line x1="410" y1="540" x2="410" y2="1140"/>
<line x1="540" y1="540" x2="540" y2="1140"/>
<line x1="670" y1="540" x2="670" y2="1140"/>
<line x1="800" y1="540" x2="800" y2="1140"/>
<line x1="930" y1="540" x2="930" y2="1140"/>
<line x1="1060" y1="540" x2="1060" y2="1140"/>
</g>
<!-- 长期X轴标签 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="12" fill="#666" text-anchor="middle">
<text x="150" y="1160">启动期</text>
<text x="280" y="1160">成长期</text>
<text x="410" y="1160">快速发展期</text>
<text x="540" y="1160">扩张期</text>
<text x="670" y="1160">成熟期</text>
<text x="800" y="1160">稳定期</text>
<text x="930" y="1160">优化期</text>
<text x="1060" y="1160">转型期</text>
</g>
<!-- 长期阶段描述 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="10" fill="#888" text-anchor="middle">
<text x="150" y="1175">0-6月</text>
<text x="280" y="1175">6-12月</text>
<text x="410" y="1175">1-2年</text>
<text x="540" y="1175">2-3年</text>
<text x="670" y="1175">3-4年</text>
<text x="800" y="1175">4-5年</text>
<text x="930" y="1175">5-6年</text>
<text x="1060" y="1175">6年+</text>
</g>
<!-- 长期Y轴标签 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="11" fill="#666" text-anchor="end">
<text x="75" y="545"></text>
<text x="75" y="660">75%</text>
<text x="75" y="780">50%</text>
<text x="75" y="900">25%</text>
<text x="75" y="1020">0%</text>
<text x="75" y="1140"></text>
</g>
<!-- 长期用户增长曲线 (绿色) -->
<path d="M 150,1080 Q 200,1040 280,960 Q 350,840 410,780 Q 480,700 540,660 Q 600,620 670,600 Q 730,580 800,570 Q 860,565 930,568 Q 990,572 1060,575"
stroke="#4caf50" stroke-width="3" fill="none" marker-end="url(#arrowGreen)"/>
<!-- 长期收入增长曲线 (蓝色) -->
<path d="M 150,1110 Q 200,1090 280,1040 Q 350,940 410,840 Q 480,740 540,680 Q 600,630 670,600 Q 730,575 800,565 Q 860,560 930,562 Q 990,565 1060,568"
stroke="#2196f3" stroke-width="3" fill="none" marker-end="url(#arrowBlue)"/>
<!-- 长期终端部署数量曲线 (橙色) -->
<path d="M 150,1100 Q 200,1070 280,1000 Q 350,880 410,800 Q 480,720 540,670 Q 600,630 670,605 Q 730,585 800,575 Q 860,570 930,572 Q 990,575 1060,578"
stroke="#ff9800" stroke-width="3" fill="none" marker-end="url(#arrowOrange)"/>
<!-- 长期运营成本曲线 (红色,先升后降) -->
<path d="M 150,960 Q 200,910 280,840 Q 350,780 410,760 Q 480,750 540,760 Q 600,780 670,810 Q 730,840 800,880 Q 860,910 930,940 Q 990,960 1060,980"
stroke="#f44336" stroke-width="3" fill="none" marker-end="url(#arrowRed)"/>
<!-- 长期市场占有率曲线 (紫色) -->
<path d="M 150,1120 Q 200,1100 280,1060 Q 350,980 410,900 Q 480,820 540,760 Q 600,710 670,680 Q 730,660 800,650 Q 860,645 930,648 Q 990,652 1060,655"
stroke="#9c27b0" stroke-width="3" fill="none" marker-end="url(#arrowPurple)"/>
<!-- 箭头标记定义 -->
<defs>
<marker id="arrowGreen" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4caf50"/>
</marker>
<marker id="arrowBlue" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#2196f3"/>
</marker>
<marker id="arrowOrange" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#ff9800"/>
</marker>
<marker id="arrowRed" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#f44336"/>
</marker>
<marker id="arrowPurple" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#9c27b0"/>
</marker>
</defs>
<!-- 长期关键节点标记 -->
<g fill="white" stroke-width="2">
<!-- 启动期关键节点 -->
<circle cx="150" cy="1080" r="6" stroke="#4caf50"/>
<circle cx="150" cy="1110" r="6" stroke="#2196f3"/>
<circle cx="150" cy="1100" r="6" stroke="#ff9800"/>
<!-- 成长期关键节点 -->
<circle cx="280" cy="960" r="6" stroke="#4caf50"/>
<circle cx="280" cy="1040" r="6" stroke="#2196f3"/>
<circle cx="280" cy="1000" r="6" stroke="#ff9800"/>
<!-- 快速发展期关键节点 -->
<circle cx="410" cy="780" r="6" stroke="#4caf50"/>
<circle cx="410" cy="840" r="6" stroke="#2196f3"/>
<circle cx="410" cy="800" r="6" stroke="#ff9800"/>
<!-- 扩张期关键节点 -->
<circle cx="540" cy="660" r="6" stroke="#4caf50"/>
<circle cx="540" cy="680" r="6" stroke="#2196f3"/>
<circle cx="540" cy="670" r="6" stroke="#ff9800"/>
<!-- 成熟期关键节点 -->
<circle cx="670" cy="600" r="6" stroke="#4caf50"/>
<circle cx="670" cy="600" r="6" stroke="#2196f3"/>
<circle cx="670" cy="605" r="6" stroke="#ff9800"/>
</g>
<!-- 长期图例 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="12">
<!-- 图例背景 -->
<rect x="850" y="550" width="260" height="140" fill="white" stroke="#e1e4e8" stroke-width="1" rx="5"/>
<!-- 图例标题 -->
<text x="980" y="570" text-anchor="middle" font-weight="bold" fill="#333">长期关键指标</text>
<!-- 图例项目 -->
<g>
<line x1="860" y1="585" x2="885" y2="585" stroke="#4caf50" stroke-width="3"/>
<text x="895" y="590" fill="#4caf50">用户增长率</text>
<line x1="860" y1="605" x2="885" y2="605" stroke="#2196f3" stroke-width="3"/>
<text x="895" y="610" fill="#2196f3">收入增长率</text>
<line x1="860" y1="625" x2="885" y2="625" stroke="#ff9800" stroke-width="3"/>
<text x="895" y="630" fill="#ff9800">终端部署数量</text>
<line x1="860" y1="645" x2="885" y2="645" stroke="#f44336" stroke-width="3"/>
<text x="895" y="650" fill="#f44336">运营成本</text>
<line x1="860" y1="665" x2="885" y2="665" stroke="#9c27b0" stroke-width="3"/>
<text x="895" y="670" fill="#9c27b0">市场占有率</text>
</g>
</g>
<!-- 长期关键节点数据标注 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="10" fill="#666">
<!-- 启动期 -->
<text x="150" y="1040" text-anchor="middle" font-weight="bold">启动期目标</text>
<text x="150" y="1053" text-anchor="middle">• 10个终端部署</text>
<text x="150" y="1066" text-anchor="middle">• 500+用户注册</text>
<!-- 成长期 -->
<text x="280" y="920" text-anchor="middle" font-weight="bold">成长期目标</text>
<text x="280" y="933" text-anchor="middle">• 100个终端</text>
<text x="280" y="946" text-anchor="middle">• 5000+用户</text>
<!-- 快速发展期 -->
<text x="410" y="740" text-anchor="middle" font-weight="bold">发展期目标</text>
<text x="410" y="753" text-anchor="middle">• 500个终端</text>
<text x="410" y="766" text-anchor="middle">• 3万+用户</text>
<!-- 扩张期 -->
<text x="540" y="620" text-anchor="middle" font-weight="bold">扩张期目标</text>
<text x="540" y="633" text-anchor="middle">• 2000个终端</text>
<text x="540" y="646" text-anchor="middle">• 15万+用户</text>
<!-- 成熟期 -->
<text x="670" y="560" text-anchor="middle" font-weight="bold">成熟期目标</text>
<text x="670" y="573" text-anchor="middle">• 5000个终端</text>
<text x="670" y="586" text-anchor="middle">• 50万+用户</text>
</g>
<!-- 长期关键里程碑标注 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="11" fill="#f57c00" font-weight="bold">
<text x="280" y="1205">首次盈利</text>
<text x="410" y="1205">规模化复制</text>
<text x="540" y="1205">市场领先</text>
<text x="670" y="1205">生态完善</text>
<text x="800" y="1205">平台化</text>
</g>
<!-- 分隔线和说明 -->
<line x1="80" y1="500" x2="1120" y2="500" stroke="#ddd" stroke-width="2"/>
<!-- 底部说明 -->
<g font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="11" fill="#888">
<text x="80" y="1250">说明上方显示3年短期规划的快速发展轨迹下方展示6年长期规划的完整生命周期包含用户增长、收入增长、终端部署、运营成本和市场占有率五个核心指标的变化趋势。</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,112 +1,184 @@
<svg width="1200" height="800" viewBox="0 0 1200 800" xmlns="http://www.w3.org/2000/svg"> <svg width="900" height="550" viewBox="0 0 900 550" xmlns="http://www.w3.org/2000/svg" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif">
<defs>
<style>
.box { fill: white; stroke: #333; stroke-width: 2; }
.main-title { font-size: 20px; font-weight: bold; text-anchor: middle; }
.number { font-size: 32px; font-weight: bold; fill: #444; text-anchor: end; }
.title { font-size: 14px; font-weight: bold; text-anchor: middle; }
.desc { font-size: 10px; fill: #666; text-anchor: middle; }
.content { font-size: 9px; fill: #333; text-anchor: start; }
.content-bold { font-size: 9px; fill: #333; font-weight: bold; text-anchor: start; }
</style>
</defs>
<!-- 背景 --> <!-- 背景 -->
<rect fill="#f8f9fa" width="100%" height="100%"/> <rect fill="#f8f9fa" width="100%" height="100%"/>
<!-- 主标题 --> <!-- 主标题 -->
<text x="600" y="45" text-anchor="middle" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="28" font-weight="bold" fill="#28a745">产品画布 - 绿邻回收 (Green Neighbor Recycling)</text> <text x="450" y="35" class="main-title" fill="#28a745">产品精益画布 - 绿邻回收智能终端系统</text>
<!-- Column 1 --> <!-- Canvas Grid starting at y=60, centered in 900px width -->
<g id="col1"> <g transform="translate(75, 60)">
<!-- 目标用户 (Customer Segments) --> <!-- ROW 1 & 2 -->
<rect x="25" y="80" width="370" height="350" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/> <!-- Box 1: 问题 (rowspan=2) -->
<rect x="25" y="80" width="370" height="40" fill="#e6f7eb"/> <g transform="translate(0, 0)">
<text x="35" y="105" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">1. 目标用户 (Customer Segments)</text> <rect width="150" height="300" class="box"/>
<text x="35" y="140" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">C端用户 (居民):</text> <rect x="0" y="0" width="150" height="30" fill="#ffebee"/>
<text x="35" y="165" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 社区中老年人 (对价格敏感, 在意便利性)</text> <g transform="translate(75, 20)">
<text x="35" y="185" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 注重环保的年轻家庭 (追求品质生活)</text> <text class="title" fill="#c62828">问题</text>
<text x="35" y="205" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 图方便的上班族 (时间宝贵)</text> </g>
<text x="35" y="240" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">B端伙伴 (小站):</text> <text x="10" y="50" class="content-bold">居民痛点:</text>
<text x="35" y="265" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 社区小超市、便利店</text> <text x="10" y="62" class="content">• 卖废品麻烦,需囤积等人</text>
<text x="35" y="285" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 快递驿站、干洗店</text> <text x="10" y="74" class="content">• 老人操作困难,现有方案不友好</text>
<text x="35" y="305" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">(诉求: 增加额外收入, 吸引更多客流)</text> <text x="10" y="86" class="content">• 价格不透明,缺乏信任</text>
<text x="10" y="108" class="content-bold">商家痛点:</text>
<text x="10" y="120" class="content">• 人工成本高,需专人管理</text>
<text x="10" y="132" class="content">• 技术门槛高,缺乏智能方案</text>
<text x="10" y="154" class="content-bold">现有替代方案局限:</text>
<text x="10" y="166" class="content">• 流动回收车时间不固定</text>
<text x="10" y="178" class="content">• 人工回收点成本高</text>
<text x="130" y="280" class="number">1</text>
</g>
<!-- 核心问题 (Problem) --> <!-- Box 4: 解决方案 -->
<rect x="25" y="440" width="370" height="330" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/> <g transform="translate(150, 0)">
<rect x="25" y="440" width="370" height="40" fill="#e6f7eb"/> <rect width="150" height="150" class="box"/>
<text x="35" y="465" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">2. 核心问题 (Problem)</text> <rect x="0" y="0" width="150" height="30" fill="#e3f2fd"/>
<text x="35" y="500" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">对居民:</text> <g transform="translate(75, 20)">
<text x="35" y="525" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 卖废品麻烦: 需囤积、等待、走远路。</text> <text class="title" fill="#1976d2">解决方案</text>
<text x="35" y="545" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 价格不透明: 流动商贩随意定价。</text> </g>
<text x="35" y="565" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 渠道不稳定: 回收车时有时无。</text> <text x="10" y="50" class="content-bold">智能终端系统:</text>
<text x="35" y="600" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">对小站伙伴:</text> <text x="10" y="62" class="content">• 平板显示二维码供扫描</text>
<text x="35" y="625" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 线下门店客流变现难。</text> <text x="10" y="74" class="content">• 蓝牙电子秤自动称重</text>
<text x="35" y="645" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 缺乏稳定、低成本的增收方式。</text> <text x="10" y="86" class="content">• 大字体显示金额重量</text>
<text x="35" y="680" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">现有替代方案:</text> <text x="10" y="108" class="content-bold">多角色管理:</text>
<text x="35" y="705" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 流动回收车 (不方便, 不稳定)</text> <text x="10" y="120" class="content">• 普通用户/管理员/清运员</text>
<text x="35" y="725" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 大型回收站 (距离远)</text> <text x="10" y="132" class="content">• 统一平台,智能分权</text>
<text x="35" y="745" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 直接丢弃 (不环保, 浪费)</text> <text x="130" y="130" class="number">4</text>
</g> </g>
<!-- Column 2 -->
<g id="col2">
<!-- 独特价值主张 (Unique Value Proposition) -->
<rect x="415" y="80" width="370" height="200" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/>
<rect x="415" y="80" width="370" height="40" fill="#e6f7eb"/>
<text x="425" y="105" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">3. 独特价值主张 (UVP)</text>
<text x="425" y="150" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="bold" fill="#f57c00">下楼就卖废品,</text>
<text x="425" y="180" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="bold" fill="#f57c00">方便、透明、还能换东西!</text>
<text x="425" y="220" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 对用户: 极致便利, 公平价格</text>
<text x="425" y="240" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 对伙伴: 零成本增收, 锁定客流</text>
<!-- 解决方案 (Solution) -->
<rect x="415" y="290" width="370" height="220" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/>
<rect x="415" y="290" width="370" height="40" fill="#e6f7eb"/>
<text x="425" y="315" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">4. 解决方案 (Solution)</text>
<text x="425" y="345" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">微信小程序 (核心载体):</text>
<text x="425" y="370" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 用户端: LBS找站、个人账户、价格公示。</text>
<text x="425" y="390" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444"> (适老化设计: 大字体/图标/语音播报)</text>
<text x="425" y="415" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 小站端: 扫码识客、称重计价、数据汇总。</text>
<text x="425" y="445" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">线下运营体系:</text>
<text x="425" y="470" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 小站 → 小仓 → 大仓 → 打包站 的SOP流程。</text>
<!-- 渠道 (Channels) -->
<rect x="415" y="520" width="370" height="250" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/>
<rect x="415" y="520" width="370" height="40" fill="#e6f7eb"/>
<text x="425" y="545" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">5. 渠道 (Channels)</text>
<text x="425" y="575" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 线下: 社区地推、合作点(小站)引流、</text>
<text x="425" y="595" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444"> 与物业/居委会合作。</text>
<text x="425" y="620" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 线上: 微信群、本地生活公众号。</text>
<text x="425" y="645" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 传播: 用户口碑、小礼品激励分享。</text>
</g>
<!-- Column 3 -->
<g id="col3">
<!-- 收入来源 (Revenue Streams) -->
<rect x="805" y="80" width="370" height="200" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/>
<rect x="805" y="80" width="370" height="40" fill="#e6f7eb"/>
<text x="815" y="105" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">6. 收入来源 (Revenue Streams)</text>
<text x="815" y="140" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">• 核心收入: 废品差价</text>
<text x="815" y="160" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">(打包站售价 - 居民收购价)</text>
<text x="815" y="190" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#333" font-weight="bold">• 增值收入:</text>
<text x="815" y="210" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">- 小站商品导流佣金</text>
<text x="815" y="230" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">- 小程序内广告 (如环保品牌)</text>
<text x="815" y="250" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">- To B/G 数据服务</text>
<!-- 成本结构 (Cost Structure) -->
<rect x="805" y="290" width="370" height="220" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/>
<rect x="805" y="290" width="370" height="40" fill="#e6f7eb"/>
<text x="815" y="315" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">7. 成本结构 (Cost Structure)</text>
<text x="815" y="345" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 技术研发成本 (小程序开发、服务器)</text>
<text x="815" y="370" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 线下运营成本 (仓储、物流、车辆)</text>
<text x="815" y="395" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 人力成本 (管理团队、司机、分拣员)</text>
<text x="815" y="420" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 市场营销成本 (地推、物料、活动)</text>
<text x="815" y="445" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 小站补贴/分成 (给合作方的激励)</text>
<!-- 关键指标 (Key Metrics) --> <!-- Box 3: 独特卖点 (rowspan=2) -->
<rect x="805" y="520" width="370" height="150" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/> <g transform="translate(300, 0)">
<rect x="805" y="520" width="370" height="40" fill="#e6f7eb"/> <rect width="150" height="300" class="box"/>
<text x="815" y="545" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">8. 关键指标 (Key Metrics)</text> <rect x="0" y="0" width="150" height="30" fill="#fff3e0"/>
<text x="815" y="575" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 用户增长: 注册用户数、日/月活用户(DAU/MAU)</text> <g transform="translate(75, 20)">
<text x="815" y="600" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 业务量: 日均回收单量、回收品类重量</text> <text class="title" fill="#f57c00">独特卖点</text>
<text x="815" y="625" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 网络扩张: 成功签约并运营的小站数量</text> </g>
<text x="815" y="650" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 用户粘性: 用户复用率、单用户月均交易次数</text> <g transform="translate(75, 60)">
<text class="desc" style="font-size: 14px; font-weight: bold;" fill="#f57c00">
<tspan x="0" dy="0">微信扫一扫,</tspan>
<tspan x="0" dy="20">老少皆宜智能回收</tspan>
</text>
</g>
<text x="10" y="120" class="content-bold">对用户价值:</text>
<text x="10" y="132" class="content">• 扫码即用,操作超简单</text>
<text x="10" y="144" class="content">• 价格透明,立即到账</text>
<text x="10" y="166" class="content-bold">对商家价值:</text>
<text x="10" y="178" class="content">• 零人工成本,智能管理</text>
<text x="10" y="190" class="content">• 稳定增收,吸引客流</text>
<text x="130" y="280" class="number">3</text>
</g>
<!-- 竞争壁垒 (Unfair Advantage) --> <!-- Box 9: 门槛优势 -->
<rect x="805" y="680" width="370" height="90" fill="#ffffff" stroke="#e1e4e8" stroke-width="1"/> <g transform="translate(450, 0)">
<rect x="805" y="680" width="370" height="40" fill="#e6f7eb"/> <rect width="150" height="150" class="box"/>
<text x="815" y="705" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="18" font-weight="600" fill="#0d442a">9. 竞争壁垒 (Unfair Advantage)</text> <rect x="0" y="0" width="150" height="30" fill="#fce4ec"/>
<text x="815" y="735" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 强大的线下运营和地推能力 (最核心)</text> <g transform="translate(75, 20)">
<text x="815" y="755" font-family="'PingFang SC', 'Microsoft YaHei', sans-serif" font-size="14" fill="#444">• 率先抢占的社区点位网络效应</text> <text class="title" fill="#ad1457">门槛优势</text>
</g>
<text x="10" y="50" class="content-bold">产品壁垒:</text>
<text x="10" y="62" class="content">• 老人友好设计(市场空白)</text>
<text x="10" y="74" class="content">• 低成本智能化方案</text>
<text x="10" y="96" class="content-bold">运营壁垒:</text>
<text x="10" y="108" class="content">• 点位网络效应</text>
<text x="10" y="120" class="content">• 先发优势抢占资源</text>
<text x="130" y="130" class="number">9</text>
</g>
<!-- Box 2: 客户群体分类 (rowspan=2) -->
<g transform="translate(600, 0)">
<rect width="150" height="300" class="box"/>
<rect x="0" y="0" width="150" height="30" fill="#e8f5e8"/>
<g transform="translate(75, 20)">
<text class="title" fill="#2e7d32">客户群体分类</text>
</g>
<text x="10" y="50" class="content-bold">核心用户 (C端):</text>
<text x="10" y="62" class="content">• 社区中老年人 (扫码即用)</text>
<text x="10" y="74" class="content">• 环保意识强的年轻家庭</text>
<text x="10" y="86" class="content">• 图方便的上班族</text>
<text x="10" y="108" class="content-bold">合作伙伴 (B端):</text>
<text x="10" y="120" class="content">• 社区超市、便利店</text>
<text x="10" y="132" class="content">• 快递驿站、物业服务点</text>
<text x="10" y="154" class="content-bold">需求特征:</text>
<text x="10" y="166" class="content">• 操作简单、零成本增收</text>
<text x="10" y="178" class="content">• 智能化管理、吸引客流</text>
<text x="130" y="280" class="number">2</text>
</g>
<!-- ROW 2 (remaining cells) -->
<!-- Box 8: 关键指标 -->
<g transform="translate(150, 150)">
<rect width="150" height="150" class="box"/>
<rect x="0" y="0" width="150" height="30" fill="#e0f2f1"/>
<g transform="translate(75, 20)">
<text class="title" fill="#00695c">关键指标</text>
</g>
<text x="10" y="50" class="content-bold">运营指标:</text>
<text x="10" y="62" class="content">• 单终端日均交易量</text>
<text x="10" y="74" class="content">• 终端网络覆盖社区数</text>
<text x="10" y="96" class="content-bold">用户指标:</text>
<text x="10" y="108" class="content">• 操作成功率、用户满意度</text>
<text x="10" y="120" class="content">• 用户复购率、推荐率</text>
<text x="130" y="130" class="number">8</text>
</g>
<!-- Box 5: 渠道 -->
<g transform="translate(450, 150)">
<rect width="150" height="150" class="box"/>
<rect x="0" y="0" width="150" height="30" fill="#f3e5f5"/>
<g transform="translate(75, 20)">
<text class="title" fill="#7b1fa2">渠道</text>
</g>
<text x="10" y="50" class="content-bold">线下布点:</text>
<text x="10" y="62" class="content">• 社区超市、快递站合作</text>
<text x="10" y="74" class="content">• 与物业/居委会合作</text>
<text x="10" y="96" class="content-bold">用户触达:</text>
<text x="10" y="108" class="content">• 微信生态扫一扫直达</text>
<text x="10" y="120" class="content">• 业主群推广分享</text>
<text x="130" y="130" class="number">5</text>
</g>
<!-- ROW 3 -->
<!-- Box 7: 成本分析 (colspan=3) -->
<g transform="translate(0, 300)">
<rect width="375" height="150" class="box"/>
<rect x="0" y="0" width="375" height="30" fill="#fff8e1"/>
<g transform="translate(187.5, 20)">
<text class="title" fill="#f57f17">成本分析</text>
</g>
<text x="10" y="50" class="content-bold">单点成本:</text>
<text x="10" y="62" class="content">• 硬件成本: 1000元/终端 • 部署成本: 2000元/点</text>
<text x="10" y="84" class="content-bold">运营成本:</text>
<text x="10" y="96" class="content">• 技术维护、云服务 • 清运物流、客服支持</text>
<text x="10" y="118" class="content-bold">分成成本:</text>
<text x="10" y="130" class="content">• 与场地方交易额分账</text>
<text x="355" y="130" class="number">7</text>
</g>
<!-- Box 6: 收入分析 (colspan=3) -->
<g transform="translate(375, 300)">
<rect width="375" height="150" class="box"/>
<rect x="0" y="0" width="375" height="30" fill="#e8f5e8"/>
<g transform="translate(187.5, 20)">
<text class="title" fill="#2e7d32">收入分析</text>
</g>
<text x="10" y="50" class="content-bold">主要收入流:</text>
<text x="10" y="62" class="content">• 废品回收差价 (终端回收价 vs 批发销售价的差额) - 核心收入</text>
<text x="10" y="74" class="content">• 与合作场地按交易量分成 - 激励合作</text>
<text x="10" y="96" class="content-bold">增值收入流:</text>
<text x="10" y="108" class="content">• 规模化后的数据服务收入 • 绿色积分商城佣金</text>
<text x="10" y="130" class="content">• 单点投入3000元预期4-10个月回本</text>
<text x="355" y="130" class="number">6</text>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -10,6 +10,15 @@
--- ---
## 0. 文档追踪
| **评审状态** | **评审人** | **评审日期** | **备注** |
| :--- | :--- | :--- | :--- |
| 初稿 | Sean | 2025-08-08 | - |
| 技术评审 | (待定) | (待定) | - |
---
## 1. 项目概述 ## 1. 项目概述
### 1.1 项目背景与核心矛盾 ### 1.1 项目背景与核心矛盾
@@ -49,44 +58,69 @@
```mermaid ```mermaid
graph TD graph TD
subgraph 用户端 (User Layer) subgraph 用户端 (User Layer)
C_MP[C端居民小程序<br>(uni-app / Vue.js)] C_MP[C端用户小程序<br>(uni-app / Vue.js)]
B_MP[B端小站小程序<br>(uni-app / Vue.js)]
Admin[管理后台Web<br>(Vue 3 + Element Plus)] Admin[管理后台Web<br>(Vue 3 + Element Plus)]
Maintenance[运维端APP<br>(Flutter / React Native)]
end
subgraph 智能终端层 (Terminal Layer)
Terminal1[智能终端设备#1<br>(嵌入式Linux + Qt)]
Terminal2[智能终端设备#2<br>(嵌入式Linux + Qt)]
TerminalN[智能终端设备#N<br>(嵌入式Linux + Qt)]
end end
subgraph 网关层 (API Gateway) subgraph 网关层 (API Gateway)
Gateway[API Gateway<br>(Nginx)] Gateway[API Gateway<br>(Nginx + Load Balancer)]
end end
subgraph 后端服务 (Backend Service) subgraph 后端服务 (Backend Service)
Backend[后端应用服务器<br>(Node.js + NestJS)] Backend[后端应用服务器<br>(Node.js + NestJS)]
AIService[AI识别服务<br>(Python + TensorFlow)]
DeviceManager[设备管理服务<br>(MQTT Broker)]
end end
subgraph 数据层 (Data Layer) subgraph 数据层 (Data Layer)
DB[(PostgreSQL<br>核心业务数据)] DB[(PostgreSQL<br>核心业务数据)]
Cache[(Redis<br>缓存/会话)] Cache[(Redis<br>缓存/会话)]
TimeSeries[(InfluxDB<br>设备时序数据)]
end end
C_MP --> Gateway C_MP --> Gateway
B_MP --> Gateway
Admin --> Gateway Admin --> Gateway
Maintenance --> Gateway
Terminal1 --> DeviceManager
Terminal2 --> DeviceManager
TerminalN --> DeviceManager
Gateway --> Backend Gateway --> Backend
Backend --> AIService
Backend --> DeviceManager
Backend --> DB Backend --> DB
Backend --> Cache Backend --> Cache
DeviceManager --> TimeSeries
AIService --> Cache
``` ```
### 3.2 技术选型理由 ### 3.2 技术选型理由
- **前端 (uni-app + Vue)**: 一次开发多端发布极大提升MVP开发效率统一技术栈。 - **前端 (uni-app + Vue)**: 一次开发多端发布极大提升MVP开发效率C端小程序和运维端APP统一技术栈。
- **后端 (Node.js + NestJS)**: 全栈语言统一TypeScript架构清晰适合企业级应用保证代码质量和可维护性 - **智能终端 (嵌入式Linux + Qt)**: 稳定可靠的嵌入式系统Qt提供良好的触屏界面开发体验支持多媒体和网络通信
- **数据库 (PostgreSQL + Redis)**: PostgreSQL功能强大满足地理位置查询等复杂需求Redis作为缓存保证系统响应速度 - **后端 (Node.js + NestJS)**: 全栈语言统一TypeScript微服务架构清晰适合处理高并发的设备连接
- **AI服务 (Python + TensorFlow)**: 成熟的机器学习框架,支持物品识别模型的训练和推理。
- **设备通信 (MQTT)**: 轻量级物联网协议,适合终端设备与云端的实时通信。
- **数据库 (PostgreSQL + Redis + InfluxDB)**: PostgreSQL处理业务数据Redis提供缓存和会话InfluxDB专门存储设备时序数据。
### 3.3 风险评估与应对策略 ### 3.3 风险评估与应对策略
- **技术风险**: - **硬件风险**:
- **风险点**: `uni-app` 在部分低端安卓机型上可能存在性能瓶颈 - **风险点**: 智能终端设备的硬件稳定性和恶劣环境适应性
- **应对策略**: 在开发中期,选取核心页面(如扫码、列表)进行专项性能测试,预留优化时间 - **应对策略**: 选择工业级硬件组件,进行充分的环境测试(高温、低温、湿度、振动)
- **团队风险**: - **AI识别风险**:
- **风险点**: 团队成员对 `NestJS``uni-app` 的熟练度可能不一 - **风险点**: 物品识别准确率可能达不到预期,影响用户体验
- **应对策略**: 在项目启动前安排1-2天的技术预研Spike统一代码规范和最佳实践 - **应对策略**: 建立持续学习机制,收集错误样本不断优化模型;设置人工审核机制作为兜底
- **网络风险**:
- **风险点**: 终端设备网络不稳定导致数据传输中断。
- **应对策略**: 实现本地数据缓存机制,支持断网重连和数据补传。
- **成本风险**:
- **风险点**: 单台设备成本超出3000元预算影响盈利模式。
- **应对策略**: 严格控制硬件BOM成本探索批量采购降本优化设计减少不必要功能。
--- ---
@@ -99,6 +133,7 @@ graph TD
CREATE TABLE users ( CREATE TABLE users (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
wx_openid VARCHAR(255) UNIQUE NOT NULL, wx_openid VARCHAR(255) UNIQUE NOT NULL,
phone_number VARCHAR(20) UNIQUE,
nickname VARCHAR(255), nickname VARCHAR(255),
avatar_url TEXT, avatar_url TEXT,
balance DECIMAL(10, 2) NOT NULL DEFAULT 0.00, balance DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
@@ -106,26 +141,33 @@ CREATE TABLE users (
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
-- 2. B端回收小站 -- 2. 智能终端设备
CREATE TABLE stations ( CREATE TABLE terminals (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
device_code VARCHAR(100) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
address TEXT NOT NULL, address TEXT NOT NULL,
location GEOGRAPHY(POINT, 4326), location GEOGRAPHY(POINT, 4326),
manager_name VARCHAR(100), venue_type VARCHAR(50) NOT NULL, -- supermarket, express_station, etc.
phone_number VARCHAR(20), venue_contact_name VARCHAR(100),
status VARCHAR(20) NOT NULL DEFAULT 'active', venue_contact_phone VARCHAR(20),
status VARCHAR(20) NOT NULL DEFAULT 'online', -- online, offline, maintenance, error
hardware_version VARCHAR(50),
software_version VARCHAR(50),
deployment_cost DECIMAL(10, 2) DEFAULT 3000.00,
deployment_date DATE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
-- 3. 小站员工 -- 3. 终端配置
CREATE TABLE staff ( CREATE TABLE terminal_configs (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
station_id INT NOT NULL REFERENCES stations(id), terminal_id INT NOT NULL REFERENCES terminals(id),
phone_number VARCHAR(20) UNIQUE NOT NULL, bag_count INT NOT NULL DEFAULT 3,
password_hash VARCHAR(255) NOT NULL, max_weight_per_bag DECIMAL(10, 2) DEFAULT 50.00,
role VARCHAR(50) NOT NULL DEFAULT 'staff', ai_confidence_threshold DECIMAL(3, 2) DEFAULT 0.85,
network_config JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
@@ -134,7 +176,9 @@ CREATE TABLE staff (
CREATE TABLE categories ( CREATE TABLE categories (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL, name VARCHAR(100) UNIQUE NOT NULL,
code VARCHAR(20) UNIQUE NOT NULL, -- bottle, paper, textile
unit VARCHAR(20) NOT NULL DEFAULT 'kg', unit VARCHAR(20) NOT NULL DEFAULT 'kg',
ai_model_labels TEXT[], -- AI识别标签数组
is_active BOOLEAN NOT NULL DEFAULT TRUE, is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
@@ -143,20 +187,22 @@ CREATE TABLE categories (
CREATE TABLE prices ( CREATE TABLE prices (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
category_id INT NOT NULL REFERENCES categories(id), category_id INT NOT NULL REFERENCES categories(id),
station_id INT NOT NULL REFERENCES stations(id), terminal_id INT NOT NULL REFERENCES terminals(id),
price DECIMAL(10, 2) NOT NULL, price DECIMAL(10, 2) NOT NULL,
effective_date TIMESTAMPTZ NOT NULL DEFAULT NOW(), effective_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(category_id, station_id) UNIQUE(category_id, terminal_id)
); );
-- 6. 交易记录总表 -- 6. 交易记录总表
CREATE TABLE transactions ( CREATE TABLE transactions (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id), user_id INT NOT NULL REFERENCES users(id),
station_id INT NOT NULL REFERENCES stations(id), terminal_id INT NOT NULL REFERENCES terminals(id),
staff_id INT NOT NULL REFERENCES staff(id),
total_amount DECIMAL(10, 2) NOT NULL, total_amount DECIMAL(10, 2) NOT NULL,
payment_method VARCHAR(20) DEFAULT 'balance', -- balance, wechat_pay
ai_confidence_score DECIMAL(3, 2),
transaction_images TEXT[], -- 交易过程图片
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
@@ -165,9 +211,44 @@ CREATE TABLE transaction_items (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
transaction_id INT NOT NULL REFERENCES transactions(id) ON DELETE CASCADE, transaction_id INT NOT NULL REFERENCES transactions(id) ON DELETE CASCADE,
category_id INT NOT NULL REFERENCES categories(id), category_id INT NOT NULL REFERENCES categories(id),
bag_number INT NOT NULL, -- 投入的袋子编号
weight DECIMAL(10, 2) NOT NULL, weight DECIMAL(10, 2) NOT NULL,
price_per_unit DECIMAL(10, 2) NOT NULL, price_per_unit DECIMAL(10, 2) NOT NULL,
amount DECIMAL(10, 2) NOT NULL, amount DECIMAL(10, 2) NOT NULL,
ai_identified_category VARCHAR(100), -- AI识别的品类
ai_confidence DECIMAL(3, 2), -- AI置信度
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 8. 终端状态监控表
CREATE TABLE terminal_status (
id SERIAL PRIMARY KEY,
terminal_id INT NOT NULL REFERENCES terminals(id),
cpu_usage DECIMAL(5, 2),
memory_usage DECIMAL(5, 2),
disk_usage DECIMAL(5, 2),
network_status VARCHAR(20),
temperature DECIMAL(5, 2),
bag_weights JSONB, -- 各袋子当前重量 {"bag1": 25.5, "bag2": 30.2}
error_codes VARCHAR(255)[],
last_heartbeat TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 9. 设备维护记录表
CREATE TABLE maintenance_records (
id SERIAL PRIMARY KEY,
terminal_id INT NOT NULL REFERENCES terminals(id),
maintenance_type VARCHAR(50) NOT NULL, -- routine, repair, emergency
operator_name VARCHAR(100),
operator_phone VARCHAR(20),
description TEXT,
before_images TEXT[],
after_images TEXT[],
cost DECIMAL(10, 2),
status VARCHAR(20) DEFAULT 'completed', -- pending, in_progress, completed
scheduled_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
``` ```
@@ -177,28 +258,43 @@ CREATE TABLE transaction_items (
## 5. 核心API接口设计 ## 5. 核心API接口设计
### 5.1 管理后台API (`/api/admin`) ### 5.1 管理后台API (`/api/admin`)
- **终端管理**: `GET, POST, PUT /terminals/:id`
- **品类管理**: `GET, POST, PUT /categories/:id` - **品类管理**: `GET, POST, PUT /categories/:id`
- **小站管理**: `GET, POST, PUT /stations/:id`
- **价格管理**: `GET, POST /prices` - **价格管理**: `GET, POST /prices`
- **员工管理**: `GET, POST /staff` - **维护管理**: `GET, POST /maintenance`
- **数据监控**: `GET /monitoring/dashboard`
### 5.2 C端小程序API (`/api/c`) ### 5.2 C端小程序API (`/api/c`)
- **认证**: `POST /auth/login` (微信Code换JWT) - **认证**: `POST /auth/login` (微信Code换JWT)
- **用户信息**: `GET /profile` - **用户信息**: `GET /profile`
- **核心功能**: - **核心功能**:
- `GET /features/prices` (今日回收价) - `GET /features/prices` (今日回收价)
- `GET /features/nearby-stations` (附近小站) - `GET /features/nearby-terminals` (附近终端)
- `GET /features/transactions` (交易记录) - `GET /features/transactions` (交易记录)
- `GET /features/qrcode` (生成登录二维码)
### 5.3 B端小程序API (`/api/b`) ### 5.3 智能终端设备API (`/api/terminal`)
- **认证**: `POST /auth/login` (手机号密码登录) - **设备认证**: `POST /auth/device` (设备注册登录)
- **回收流程**: - **用户识别**: `POST /user/identify` (二维码/手机号识别)
- `GET /recycle/user-info` (扫码识客) - **交易流程**:
- `POST /recycle/transactions` (创建交易) - `POST /transaction/start` (开始交易)
- **数据查询**: - `POST /transaction/weigh` (称重数据上传)
- `GET /data/summary` (今日汇总) - `POST /transaction/ai-verify` (AI识别验证)
- `GET /data/inventory` (库存盘点) - `POST /transaction/complete` (完成交易)
- `GET /data/categories` (可用回收品类) - **设备状态**:
- `POST /status/heartbeat` (设备心跳)
- `POST /status/error` (错误报告)
- `GET /config` (获取设备配置)
### 5.4 运维端API (`/api/maintenance`)
- **认证**: `POST /auth/login` (运维人员登录)
- **任务管理**:
- `GET /tasks` (获取维护任务)
- `POST /tasks/:id/start` (开始任务)
- `POST /tasks/:id/complete` (完成任务)
- **设备检测**:
- `POST /device/:id/diagnose` (设备诊断)
- `POST /device/:id/repair` (维修记录)
--- ---
@@ -211,13 +307,13 @@ CREATE TABLE transaction_items (
- **目标**: 完成后端核心API开发与前端基础架构。 - **目标**: 完成后端核心API开发与前端基础架构。
- **后端**: 完成所有后台、C端、B端的API开发与单元测试。 - **后端**: 完成所有后台、C端、B端的API开发与单元测试。
- **前端**: 完成项目脚手架搭建各端登录、核心页面UI布局。 - **前端**: 完成项目脚手架搭建各端登录、核心页面UI布局。
- **产出**: 后端API可供调用前端页面静态可见 - **产出**: **所有后端API通过单元测试并提供Swagger文档**前端完成核心页面UI框架搭建
- **Sprint 2 (第三、四周)**: - **Sprint 2 (第三、四周)**:
- **目标**: 完成前后端对接、联调测试与上线准备。 - **目标**: 完成前后端对接、联调测试与上线准备。
- **前端**: 完成所有业务逻辑开发与后端API全面对接。 - **前端**: 完成所有业务逻辑开发与后端API全面对接。
- **测试**: 执行端到端的核心流程测试用例进行多轮Bug修复。 - **测试**: 执行端到端的核心流程测试用例进行多轮Bug修复。
- **产出**: 功能完备、通过测试的MVP版本可随时部署。 - **产出**: 功能完备、**通过核心流程E2E测试**的MVP版本可随时部署。
### 6.2 资源分配 (建议) ### 6.2 资源分配 (建议)
- **后端开发**: 1-2人 - **后端开发**: 1-2人
@@ -225,9 +321,19 @@ CREATE TABLE transaction_items (
- **测试(QA)**: 1人 (在Sprint 2后半段集中投入) - **测试(QA)**: 1人 (在Sprint 2后半段集中投入)
- **产品/项目**: 1人 (负责需求澄清、进度跟踪) - **产品/项目**: 1人 (负责需求澄清、进度跟踪)
### 6.3 沟通与协作 ### 6.3 关键里程碑 (Milestones)
| **里程碑** | **预计完成日期** | **负责人** | **交付物** |
| :--- | :--- | :--- | :--- |
| M1: 项目启动与技术预研 | W1周三 | Alex | 项目计划、技术选型确认 |
| M2: 后端API开发完成 | W2周五 | 后端Leader | 可供调用的API文档 |
| M3: 前后端联调完成 | W4周三 | 前/后端Leader | 完成核心功能对接 |
| M4: MVP版本测试完成 | W4周五 | QA Leader | 测试报告 |
| M5: MVP正式上线 | W5周一 | Alex | 上线公告 |
### 6.4 沟通与协作
- **每日站会**: 每天上午10点15分钟同步进度、风险和阻塞点。 - **每日站会**: 每天上午10点15分钟同步进度、风险和阻塞点。
- **每周复盘**: 每周五下午,复盘本周进展,规划下周计划。 - **每周复盘与演示**: 每周五下午,复盘本周进展,并**进行功能演示**规划下周计划。
- **协作工具**: - **协作工具**:
- **任务管理**: Jira (或类似工具) - **任务管理**: Jira (或类似工具)
- **即时沟通**: Slack / 钉钉 - **即时沟通**: Slack / 钉钉

View File

@@ -0,0 +1,43 @@
# 后台管理系统功能模块设计 V1.0
> **设计者**: dev-manager
> **依据文档**:
> - 《废品回收小程序产品需求文档 (PRD) V2.0》
> - 《废品回收小程序 - 初步设计文档 V1.0》
> - 《用户故事 - 绿邻回收项目》
## 概述
本设计旨在为“绿邻回收”项目提供一个全面、可扩展的后台管理系统功能模块规划。后台的核心定位是**公司的“大脑”**,为运营、管理、财务和技术团队提供数据支持和业务管控工具。
---
## 功能模块详细规划
| 一级菜单 | 二级菜单 (页面) | 功能模块 | 细节描述 | 对应PRD/用户故事 |
| :--- | :--- | :--- | :--- | :--- |
| **数据中心** | **运营驾驶舱** | 核心KPI展示 | - 今日交易总额、总单数、总重量<br>- 活跃用户数 (DAU/MAU)<br>- 在线设备数/故障设备数<br>- 设备利用率和平均交易频次 | PRD 7.1.1 |
| | | 实时监控大屏 | - 地图展示所有终端位置和状态<br>- 各终端实时交易数据<br>- 设备健康状态色彩编码<br>- 异常设备实时告警 | PRD 7.1.1, 用户故事 4.2.1 |
| **设备管理** | **终端设备列表** | 设备信息管理 | - 显示设备编号、名称、地址、场地方信息、运行状态<br>- 支持按设备编号、地址、状态搜索<br>- 设备部署成本和投资回收期显示 | PRD 7.1.2 |
| | | 设备详情/编辑 | - **基本信息**:设备编号、位置、场地方联系方式<br>- **硬件配置**袋子数量、最大承重、AI识别阈值<br>- **运行状态**:在线/离线/故障/维护中<br>- **交易数据**:该设备的历史交易流水和收益分析 | PRD 7.1.2 |
| | | 设备部署管理 | - 新设备入网配置和参数设置<br>- 设备软件版本管理和远程更新<br>- 设备网络配置和连接状态监控 | PRD 7.1.2 |
| | **设备监控** | 实时状态监控 | - 各设备CPU、内存、存储使用率<br>- 网络连接状态和数据传输质量<br>- 各袋子实时重量和容量预警<br>- 设备温度和环境监控 | PRD 7.1.2, 用户故事 4.2.1 |
| | | 故障预警系统 | - AI预测设备故障风险<br>- 自动生成维护提醒<br>- 故障类型统计和趋势分析 | PRD 7.1.9, 用户故事 4.2.2 |
| **运营管理** | **品类价格管理** | 回收品类列表 | - 显示品类ID、名称、代码、单位、AI识别标签<br>- 支持新增、编辑、停用品类<br>- AI识别模型标签配置 | PRD 7.1.4 |
| | | 价格策略配置 | - 选择一个或多个终端,为指定品类设置回收单价<br>- 支持批量调价和设置价格生效时间<br>- 可查看历史价格调整记录和市场价格对比 | PRD 7.1.4 |
| | | AI识别配置 | - 设置不同品类的AI识别置信度阈值<br>- 上传训练样本和错误样本管理<br>- 模型识别准确率统计和优化建议 | PRD 7.1.4 |
| **交易管理** | **订单流水** | 交易列表 | - 列表展示所有交易记录交易ID、用户昵称、终端设备、总金额、AI置信度、创建时间<br>- 支持按交易ID、用户、设备、时间范围进行复合查询 | PRD 7.1.5 |
| | | 订单详情 | - 查看单笔交易的详细信息,包括所有回收物品的品类、重量、单价、金额<br>- 显示AI识别结果和置信度<br>- 交易过程图片查看 | PRD 7.1.5 |
| | | 异常交易处理 | - 低置信度交易人工审核<br>- 用户投诉处理和退款管理<br>- 异常交易模式分析 | PRD 7.1.5 |
| **用户管理** | **C端用户列表** | 用户信息查询 | - 列表展示所有C端用户信息用户ID、微信昵称、手机号、账户余额、注册时间<br>- 用户行为分析:常用设备、交易频次、偏好品类 | PRD 7.1.3 |
| | | 用户详情 | - 查看用户的基本信息、账户余额、完整的交易记录列表<br>- 用户设备使用热力图和行为轨迹 | PRD 7.1.3 |
| **运维管理** | **维护任务** | 任务列表 | - 查看所有运维任务任务ID、类型巡检/维修/清运)、设备、运维人员、状态<br>- 支持按任务类型、状态、设备筛选 | PRD 7.1.6 |
| | | 任务详情 | - 查看任务的详细信息、维修记录、更换备件<br>- 维修前后照片对比<br>- 维修成本和时长统计 | PRD 7.1.6 |
| | | 运维人员管理 | - 管理运维工程师信息(姓名、联系方式、技能等级、负责区域) | PRD 7.1.6 |
| | **库存清运** | 清运计划 | - 基于设备容量自动生成清运计划<br>- 最优路线规划和运输成本计算<br>- 清运记录和重量核对 | PRD 7.1.5 |
| **财务管理** | **结算管理** | 对账单 | - 生成与场地方、运维团队的周期性结算账单<br>- 设备投资成本分摊和回收期计算<br>- 账单需清晰列出所有明细和分润比例 | PRD 7.1.7 |
| | | 成本分析 | - 单台设备成本构成分析<br>- 运营成本趋势和优化建议<br>- ROI计算和盈利预测 | PRD 7.1.7 |
| | | 提现审批 | - (若C端提现需人工审核)处理C端用户的提现申请 | PRD 4.1.4 |
| **系统管理** | **角色与权限** | 角色管理 | - 创建、编辑后台角色(如:运营、技术、财务、客服)<br>- 为角色分配不同的菜单和操作权限(增删改查) | PRD 7.1.8 |
| | | 账号管理 | - 创建后台操作员账号,并为其分配角色<br>- 设备访问权限管理 | PRD 7.1.8 |
| | **智能监控** | 系统日志 | - 查看所有后台账号的登录历史记录、设备操作日志<br>- 异常操作行为分析和告警 | PRD 7.1.8 |
| | | 智能报警中心 | - 集中展示设备故障、容量预警、交易异常、网络中断等告警<br>- AI辅助故障诊断和处理建议<br>- 告警处理流程跟踪和效果评估 | PRD 7.1.9 |

View File

@@ -5,9 +5,9 @@
## 1. 执行摘要 (Executive Summary) ## 1. 执行摘要 (Executive Summary)
**绿邻回收**是一个旨在革新城市社区废品回收模式的环保科技项目。我们通过构建一个以微信小程序为载体,连接居民、社区小站和回收产业链的超便捷回收网络,解决当前城市废品回收中存在的最后一公里难题。 **绿邻回收**是一个旨在革新城市社区废品回收模式的环保科技项目。我们通过在各大超市、快递门口部署智能回收终端,结合微信小程序后台管理系统,打造一个全自动化、高效透明的废品回收网络,解决当前城市废品回收中存在的"最后一公里"难题。
我们的核心业务是,用户(特别是中老年人)可以方便地将家中的可回收废品(初期聚焦于塑料瓶、纸壳、旧衣物)送到楼下的合作小站(如超市、快递驿站),通过一个极其简单的“适老化”小程序进行称重、计价,并立即获得现金或兑换商品。小站的废品将由我们的物流体系每日归集到城市中心仓,再统一销售给大型打包站,从而形成一个高效、透明、共赢的商业闭环 我们的核心产品是智能回收终端设备配备1-3个回收袋用于分类收集饮料瓶、废纸、织物等可回收物品通过AI摄像头自动识别监控回收物品平板电脑显示重量和操作界面整个系统由坚固的铝合金骨架组合而成。用户只需将废品投入对应的回收袋系统自动称重计价通过简单的身份识别即可完成交易实现真正的无人值守智能回收
本项目致力于通过技术手段和创新的运营模式,提升回收效率,改善用户体验,为环保事业贡献力量,并创造可观的经济价值。 本项目致力于通过技术手段和创新的运营模式,提升回收效率,改善用户体验,为环保事业贡献力量,并创造可观的经济价值。
@@ -55,57 +55,59 @@
## 4. 产品与服务 (Product and Service) ## 4. 产品与服务 (Product and Service)
### 4.1 核心载体:微信小程序 ### 4.1 核心产品:智能回收终端
分为两个端:用户端和小站端 我们的核心产品是部署在各大超市、快递门口的智能回收终端设备
- **用户端**: - **硬件组成**:
- **核心功能**: 查看附近小站、回收价格公示、个人账户(交易记录、余额)。 - **分类回收袋**: 1-3个可配置回收袋用于分类收集饮料瓶、废纸、织物等不同品类
- **“适老化”设计**: 超大字体、语音播报、极简流程、无需复杂注册。 - **AI视觉监控**: 高清摄像头实时监控回收物品,确保分类正确性和防止异物投入
- **智能称重**: 精准称重传感器,实时显示重量和计算价格
- **交互平板**: 用户友好的触摸屏界面,支持身份识别、重量显示、交易确认
- **结构骨架**: 坚固的铝合金框架,确保设备稳定性和防护性能
- **小站端**: - **软件系统**:
- **核心功能**: 扫码识别用户、称重品类录入、自动计价、结算(现金/兑换)、当日汇总。 - **用户端微信小程序**: 查看附近终端、回收价格公示、个人账户管理
- **设计理念**: 操作直观,功能聚焦,稳定可靠。 - **终端操作系统**: 支持多种身份识别方式,自动称重计价,实时数据上传
- **后台管理系统**: 远程监控终端状态、数据统计分析、故障预警
### 4.2 业务流程 ### 4.2 业务流程
这是一个完整闭环系统,从居民到最终的打包站。 这是一个基于智能终端的完整闭环系统,从居民到最终的打包站。
``` mermaid ``` mermaid
graph TD graph TD
subgraph 用户端 subgraph 用户端
A[居民在家整理废品] --> B{下楼前往小站}; A[居民在家整理废品] --> B[前往超市/快递门口终端];
end end
subgraph 小站 subgraph 智能终端
B --> C[站长使用小程序称重]; B --> C[用户身份识别登录];
C --> D[系统自动计算价格]; C --> D[选择回收品类投入对应袋子];
D --> E{选择结算方式}; D --> E[AI摄像头监控验证物品];
E --> F[获得现金/兑换商品]; E --> F[系统自动称重计价];
E --> G[积分存入账户]; F --> G[用户确认交易];
F --> H[完成回收]; G --> H[积分/现金到账];
G --> H; H --> I[废品自动存储在终端];
C --> I[废品暂存小站];
end end
subgraph 物流与仓储 subgraph 物流与仓储
I --> J(每日由专人从小站收集); I --> J[终端满载自动预警];
J --> K[转运至邻近小仓]; J --> K[物流团队定期清运];
K --> L(专车每日从小仓归集); K --> L[运输至城市大仓];
L --> M[送达城市大仓]; L --> M[分类、压缩、存储];
M --> N[分类、压缩、存储];
end end
subgraph 供应链末端 subgraph 供应链末端
N --> O(定期从大仓转运); M --> N[定期从大仓转运];
O --> P[销售给大型打包站]; N --> O[销售给大型打包站];
end end
P --> |资金回流| Q((分润体系)); O --> |资金回流| P((分润体系));
subgraph 收益分配 subgraph 收益分配
Q --> |利润| CEO/公司; P --> |利润| 公司运营;
Q --> |服务费| B端小站; P --> |场地费| 超市/快递站;
Q --> |回收金| A; P --> |回收金| A;
Q --> |工资/运费| 物流与仓储; P --> |运维成本| 设备维护;
end end
``` ```
@@ -143,11 +145,12 @@ graph TD
## 7. 财务规划 (Financial Plan) ## 7. 财务规划 (Financial Plan)
### 7.1 成本结构 (Cost Structure) ### 7.1 成本结构 (Cost Structure)
- **技术开发成本**: 小程序开发、服务器、数据库等。 - **设备成本**: 每个终端设备约2500元包含摄像头、平板、称重传感器、铝合金骨架、组装调试
- **人力成本**: 核心团队、线下运营及物流人员的工资。 - **部署成本**: 每个站点部署费用约300元包含运输、安装、调试、培训
- **营销成本**: 地推活动、物料制作费用。 - **运维成本**: 每个站点月运维成本约200元包含设备维护、软件更新、故障处理
- **运营成本**: 仓储租金、运输车辆油耗及维护 - **技术开发成本**: 软件系统开发、云服务器、数据库等
- **给用户的回收金**: 支付给用户的废品费用。 - **给用户的回收金**: 支付给用户的废品费用。
- **总投入**: 每个站点总投入成本约3000元实现一期自循环目标。
### 7.2 收入来源 (Revenue Streams) ### 7.2 收入来源 (Revenue Streams)
- **核心收入**: 将从大仓集中处理后的可回收物,以更高的价格批量出售给大型打包站或处理厂,赚取其中的差价。 - **核心收入**: 将从大仓集中处理后的可回收物,以更高的价格批量出售给大型打包站或处理厂,赚取其中的差价。
@@ -165,21 +168,25 @@ graph TD
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant User as 用户 participant User as 用户
participant Station as 小站端小程序 participant Terminal as 智能终端
participant Camera as AI摄像头
participant Server as 后端服务器 participant Server as 后端服务器
User->>User: 在家整理好废品 User->>User: 在家整理好废品
User->>Station: 带着废品到楼下小站 User->>Terminal: 前往超市/快递门口的智能终端
Station->>User: 站长:欢迎,请出示您的手机号/会员码 Terminal->>User: 显示欢迎界面,请选择登录方式
User->>Station: (提供手机号后4位) User->>Terminal: 手机号/扫码/刷卡登录
Station->>Server: 查询用户信息 (手机号:xxxx) Terminal->>Server: 验证用户身份
Server-->>Station: 返回用户信息 Server-->>Terminal: 返回用户信息
Station->>Station: 站长选择品类(纸壳),放置上称 Terminal->>User: 显示用户昵称,请选择回收品类
Station->>Server: 上传数据(用户ID, 品类:纸壳, 重量:2.5kg) User->>Terminal: 选择"废纸"并投入对应袋子
Server-->>Station: 返回计算价格(3.75元) Camera->>Terminal: AI识别确认是废纸类物品
Station->>User: 站长一共3块7毛5您要现金还是换东西 Terminal->>Terminal: 自动称重 (2.5kg)
User->>Station: 就要现金吧 Terminal->>Server: 上传数据(用户ID, 品类:废纸, 重量:2.5kg)
Station->>Server: 确认交易(用户ID, 金额:3.75, 方式:现金) Server-->>Terminal: 返回计算价格(3.75元)
Server-->>Station: 交易成功 Terminal->>User: 显示"废纸2.5kg价值3.75元,确认交易吗?"
Station->>User: (支付现金)好了,欢迎下次再来! User->>Terminal: 点击确认
Terminal->>Server: 确认交易(用户ID, 金额:3.75)
Server-->>Terminal: 交易成功
Terminal->>User: 语音播报"交易成功获得3.75元"并显示交易完成界面
``` ```

View File

@@ -0,0 +1,125 @@
### **第一部分:关键数据假设与市场调研**
为了让财务模型尽可能贴近现实,我们首先需要基于公开数据和行业惯例,对几个核心运营指标进行合理假设。
#### **假设1回收品类与价格**
四线城市废品回收价格相对稳定,但利润空间较一线城市薄。我们选取最常见、居民产生量最大的**废纸板**和**塑料瓶**作为核心分析对象。
* **废纸板 (黄板纸)**
* **回收价 (给用户)**:¥ 0.8元/公斤 (¥ 0.4元/斤)
* **出售价 (给打包站)**:¥ 1.2元/公斤 (¥ 0.6元/斤)
* **毛利**:¥ 0.4元/公斤
* **塑料瓶 (PET)**
* **回收价 (给用户)**:¥ 1.4元/公斤 (¥ 0.7元/斤)
* **出售价 (给打包站)**:¥ 2.0元/公斤 (¥ 1.0元/斤)
* **毛利**:¥ 0.6元/公斤
> **分析**:价差是核心盈利来源。这个价差需要覆盖场地、物流、设备折旧、运营等所有成本。
#### **假设2单站点日均回收量**
这是决定收入的关键变量,也是最难预测的。一个部署在超市或快递驿站门口的回收点,其回收量受社区大小、居民习惯、竞争等多种因素影响。参考行业数据,我们做一个**保守的**估算。
* **覆盖户数**:假设站点能有效覆盖周边 300-500 户常住居民。
* **日均有效投递户数**:假设每天有 5% 的家庭前来投递,即 15-25 户。
* **平均每户投递量**:假设每户平均投递 1.5 公斤的可回收物。
* **日均总回收量**22.5公斤 - 37.5公斤。为方便计算,我们取一个中间值 **30公斤/天**
* **品类构成**:根据生活经验,废纸板通常占大头。我们假设 **废纸板:塑料瓶 = 2:1**
* 废纸板20公斤/天
* 塑料瓶10公斤/天
#### **假设3运营成本参数**
* **场地合作费 (给超市/驿站)**:在四线城市,直接给付高额租金不现实。采用**利润分成**或**低额固定费用**是主流。我们按 **“营业额的10%”** 作为场地合作费,这样能更好地激励合作伙伴。
* **物流清运成本**假设一个物流人员兼职或专职配备一辆三轮车每天可负责清运10-15个站点。单个站点的清运成本被摊薄。
* 人员薪资(四线城市):¥ 3000/月
* 车辆折旧及电费:¥ 300/月
* 总物流成本:¥ 3300/月
* **分摊到单站的月物流成本** (按15个站计算):¥ 3300 / 15 = **¥ 220/月**
* **设备维护与网络费**您的计划书中提到200元/月这在初期可能偏高。我们采用一个更贴近实际的估算硬件年度维护成本5%+ 物联网卡及服务器费用。
* (¥ 1500 * 5%) / 12个月 + ¥ 20/月 ≈ **¥ 27/月**
* **其他运营成本**:包括小程序维护、客服、可能的坏账损失等,计提 **¥ 50/月**。
---
### **第二部分:单站点财务模型分析 (月度)**
基于以上假设,我们来构建一个单站点的月度财务模型。
#### **A. 月度收入估算**
* **月总回收量**:
* 废纸板: 20公斤/天 * 30天 = 600公斤
* 塑料瓶: 10公斤/天 * 30天 = 300公斤
* **月度毛利 (收入)**:
* 废纸板毛利: 600公斤 * ¥ 0.4/公斤 = ¥ 240
* 塑料瓶毛利: 300公斤 * ¥ 0.6/公斤 = ¥ 180
* **合计月度毛利**: ¥ 240 + ¥ 180 = **¥ 420**
#### **B. 月度成本估算**
1. **给用户的回收金 (变动成本)**
* 废纸板: 600公斤 * ¥ 0.8 = ¥ 480
* 塑料瓶: 300公斤 * ¥ 1.4 = ¥ 420
* **合计回收金**: ¥ 900
2. **月度运营成本 (固定成本)**
* **场地合作费**: (¥ 480 + ¥ 420) * 10% = **¥ 90**
* **物流清运成本**: **¥ 220**
* **设备维护网络费**: **¥ 27**
* **其他运营成本**: **¥ 50**
* **合计月度运营成本**: ¥ 90 + ¥ 220 + ¥ 27 + ¥ 50 = **¥ 387**
#### **C. 月度利润计算**
* **单站月度净利润** = 月度毛利 - 月度运营成本
* **单站月度净利润** = ¥ 420 - ¥ 387 = **¥ 33**
---
### **第三部分:投资回报分析**
#### **1. 初始投资成本 (CAPEX)**
* 设备投入: ¥ 1500
* 部署成本: ¥ 300 (如您计划书所述)
* **单站总投资**: **¥ 1800**
#### **2. 投资回收期 (Payback Period)**
* **计算公式**: 总投资 / 月度净利润
* **回收期**: ¥ 1800 / ¥ 33/月 ≈ **54.5个月**
#### **3. 年化投资回报率 (Annual ROI)**
* **计算公式**: (年净利润 / 总投资) * 100%
* **年净利润**: ¥ 33/月 * 12个月 = ¥ 396
* **年化ROI**: (¥ 396 / ¥ 1800) * 100% = **22%**
---
### **第四部分:结论与专业建议**
#### **分析结论**
1. **盈利能力非常脆弱**在当前保守的回收量假设下单个站点的月净利润仅为33元。这意味着模型对任何变量的波动都极其敏感。例如如果日均回收量下降到25公斤项目就会开始亏损。
2. **投资回收期过长**54.5个月约4年半的回收期对于一个硬件设备可能只有3-5年寿命的轻资产项目来说风险非常高。在收回成本之前设备可能就需要更新换代了。
3. **规模效应是关键**:单个站点无法盈利,但项目的核心在于通过规模化运营来摊薄成本、提升效率。特别是**物流成本**,只有当一个清运人员能覆盖足够多的站点时,单站成本才能降下来。
#### **专业建议与破局之道**
您的商业模式很有潜力,但必须优化财务模型才能走通。以下是几条关键建议:
1. **提升单点回收量是第一要务**
* **精准选址**:必须选择社区活跃度高、老年人多、且周边缺少竞争的“黄金点位”。前期需要投入大量精力进行地推和市场调研。
* **强效地推和用户教育**您的营销策略非常正确。“回收换鸡蛋”等活动虽然会短期增加成本但如果能将日均回收量从30公斤提升到50公斤整个模型就会发生质变月净利将超过200元回收期缩短至1年以内
2. **优化成本结构**
* **降低物流成本**能否与驿站或超市老板达成更深度的合作由他们进行“暂存”和“集包”当废品达到一定量级如500公斤您再派车统一清运这将极大降低物流频次和成本。
* **探索“众包物流”**:利用社区内的闲散劳动力(如三轮车主、退休人员),以订单制或兼职形式进行清运,进一步降低固定的人力成本。
3. **开拓多元化收入来源**
* **押注高价值品类**:除了纸板和塑料,能否增加对**旧衣物、金属(易拉罐)**等高毛利品类的回收?特别是旧衣物,其回收和处理链条利润空间更大。
* **广告收入前置**在设备屏幕和微信小程序上为社区周边的商家如小餐馆、理发店、菜市场摊主提供极其廉价如50-100元/月)的广告位。这笔收入虽然不多,但在项目初期可能是“救命钱”,可以直接覆盖掉一部分运营成本。
* **政府补贴**:积极与当地街道、环保部门沟通。垃圾分类和资源回收是政府的重点工作,很有可能申请到环保项目试点补贴或一次性的设备购置补贴,这将极大改善您的初始投资压力。

View File

@@ -30,19 +30,20 @@
### 1.3 项目目标 ### 1.3 项目目标
- **V1.0 (MVP) 目标**: - **V1.0 (MVP) 目标**:
- 验证核心商业模式:居民到小站的回收流程 - 验证智能终端的核心商业模式:无人值守自动回收
- 在1-2个试点社区,实现每周100+笔交易。 - 部署10-15台终端设备,实现每周200+笔交易。
- C端用户次月留存率达到30%B端小站无主动流失 - 单台设备日均交易量达到15笔用户重复使用率达到40%。
- 实现每台设备3000元投入成本的自循环盈利模式。
### 1.4 核心用户画像 ### 1.4 核心用户画像
- **C端 - 居民**: - **C端 - 居民用户**:
- **王大妈**: 65岁退休在家对价格敏感会用微信但对复杂操作有困难。希望卖废品能像去超市买菜一样简单。 - **王大妈**: 65岁退休在家对价格敏感希望24小时随时能卖废品操作要像ATM一样简单直观
- **B端 - 小站站长**: - **小张**: 30岁上班族希望下班路过超市时能快速处理家里的快递纸箱不用排队等人工服务。
- **李老板**: 45岁社区超市店主。希望回收操作不影响主业记账清晰能快速和上游完成交接结算。 - **B端 - 场地方**:
- **物流端 - 司机**: - **超市老板**: 希望终端设备不占用过多空间,不影响正常营业,还能获得稳定的场地租金收入。
- **张师傅**: 35岁回收车队司机。希望能有清晰的揽收路线交接时不用手写单据扫个码就能搞定 - **快递站点**: 希望设备能吸引更多客流,带动快递业务,增加额外收入来源
- **后台 - 运营经理**: - **运营端 - 设备管理员**:
- **小陈**: 28岁公司运营。希望实时看到各小站的回收数据,能灵活调整回收品类和价格 - **小陈**: 28岁负责终端设备的远程监控、故障处理、定期清运等运维工作
--- ---
@@ -50,164 +51,231 @@
```mermaid ```mermaid
graph TD graph TD
subgraph C端用户 subgraph 用户
A[1.居民携带废品到小站] --> B{2.出示个人收款码}; A[1.居民携带废品到终端] --> B[2.终端屏幕身份识别];
end end
subgraph B端用户 subgraph 智能终端
B --> C[3.站长扫码识别用户]; B --> C[3.选择回收品类];
C --> D[4.选择品类, 输入重量]; C --> D[4.投入对应回收袋];
D --> E[5.确认金额, 完成交易]; D --> E[5.AI摄像头识别验证];
E --> F((资金计入用户余额)); E --> F[6.自动称重计价];
E --> G[6.定期向上游发起交接]; F --> G[7.用户确认交易];
G --> H((资金计入用户余额));
G --> I[8.废品存储在终端];
end end
subgraph 物流端 subgraph 后台监控
G --> H[7.司机接单, 前往小站]; I --> J[9.终端容量监控];
H --> I[8.扫小站出库码, 核对品类重量]; J --> K{是否达到清运阈值?};
I --> J[9.确认揽收, 运输至打包站]; K -->|是| L[10.自动派发清运任务];
K -->|否| M[继续接收废品];
end
subgraph 物流清运
L --> N[11.物流团队接收任务];
N --> O[12.前往终端清运];
O --> P[13.运输至处理中心];
end end
subgraph 管理后台 subgraph 管理后台
K[品类/价格管理] --> D; Q[终端设备管理] --> C;
F --> L[订单流水监控]; R[品类/价格管理] --> F;
G --> M[库存数据监控]; H --> S[交易流水监控];
I --> N[物流状态跟踪]; I --> T[库存状态监控];
J --> O[财务结算管理]; L --> U[物流任务管理];
P --> V[财务结算管理];
end end
``` ```
--- ---
## 3. C端居民端小程序 ## 3. 智能终端系统
**核心定位:让卖废品像收钱一样简单。** **核心定位:24小时无人值守的智能回收站。**
### 3.1 功能模块详述 ### 3.1 硬件组成详述
#### 3.1.1 登录/注册 #### 3.1.1 回收袋模块
- **需求**: 微信一键授权登录,自动创建账户,无需额外注册步骤。 - **配置**: 1-3个可配置回收袋根据场地大小和回收品类需求调整
- **分类**: 饮料瓶袋、废纸袋、织物袋,每个袋子有独立的称重传感器
- **容量**: 每个袋子设计容量约50-80升支持自动容量检测
#### 3.1.2 首页 (核心页面) #### 3.1.2 AI视觉监控
- **界面元素**: - **摄像头**: 高清摄像头,支持物品识别和分类验证
1. **【我的卖品码】**: 页面最中心、最大的按钮,点击后全屏显示个人专属二维码,并调高屏幕亮度。 - **功能**: 实时监控投入物品,防止异物污染,记录投入过程
2. **【附近小站】**: 列表或地图形式,展示附近合作小站的位置、营业时间、联系电话。 - **AI算法**: 基于深度学习的物品分类识别,准确率>95%
3. **【今日回收价】**: 醒目位置展示主要品类(纸壳、塑料瓶等)的单价(元/斤)。
#### 3.1.3 “我的”页面 #### 3.1.3 交互平板系统
- **界面元素**: - **规格**: 10-12寸触摸屏支持多点触控
1. **【我的余额】**: 突出显示当前账户余额。 - **功能**: 用户身份识别、操作引导、重量显示、交易确认
2. **【提现】(V1.1)**: 将余额提现至微信零钱。需进行实名认证。 - **登录方式**: 支持手机号、二维码扫描、NFC卡片等多种方式
3. **【交易记录】**: 列表形式,展示每一笔交易的时间、地点、品类、重量、金额。
4. **【联系客服】**: 提供客服电话或在线咨询入口。
#### 3.1.4 消息通知 #### 3.1.4 结构骨架
- **需求**: - **材料**: 铝合金框架,具备防水、防盗、耐候性能
- 交易成功后,收到模板消息推送,告知本次收入金额。 - **设计**: 模块化设计,便于运输安装和维护
- 提现成功后,收到模板消息推送。 - **安全**: 配备防撬锁、振动报警等安全措施
### 3.2 软件系统详述
#### 3.2.1 终端操作系统
- **界面**: 适老化设计,大字体、高对比度、语音引导
- **流程**: 登录→选择品类→投入物品→AI验证→称重计价→确认交易
- **离线**: 支持网络断开时的离线操作和数据缓存
#### 3.2.2 数据采集与上传
- **实时数据**: 称重数据、交易记录、设备状态、故障信息
- **定时上传**: 每10分钟向后台上传一次数据
- **异常报警**: 设备故障、满载、异常操作自动报警
--- ---
## 4. B端(小站端)小程序 ## 4. C端(用户端)小程序
**核心定位:高效的移动回收工作站。** **核心定位:便捷的个人回收助手。**
### 4.1 功能模块详述 ### 4.1 功能模块详述
#### 4.1.1 登录 #### 4.1.1 登录/注册
- **需求**: 由管理员在后台创建账号,站长通过“手机号+验证码”登录 - **需求**: 微信一键授权登录,自动创建账户,无需额外注册步骤
- **支持**: 同时支持手机号快速注册,便于在终端设备上使用。
#### 4.1.2 工作台 (首页) #### 4.1.2 首页 (核心页面)
- **界面元素**: - **界面元素**:
1. **开始回收】**: 核心操作按钮,点击进入扫码回收流程 1. **附近终端】**: 地图或列表形式,展示附近智能终端的位置、设备状态(正常/故障/满载)、距离
2. **【今日汇总】**: 数据卡片,展示当日回收总单数、总重量、总金额 2. **【今日回收价】**: 醒目位置展示主要品类(饮料瓶、废纸、织物)的实时单价
3. **库存盘点】**: 查看当前各类废品的库存重量 3. **快速回收】**: 一键跳转到最近的可用终端,并生成二维码用于终端登录
4. **向上游交接】**: 生成出库单,打印或出示出库二维码,等待物流端揽收 4. **我的余额】**: 显示当前账户余额和今日收入
#### 4.1.3 回收流程 (核心业务) #### 4.1.3 终端交互功能
1. **扫码识客**: 点击“开始回收”启动扫码器扫描C端用户的“卖品码”。成功后显示用户昵称 - **二维码登录**: 生成个人专属二维码,用于在终端设备上快速登录
2. **录入信息**: - **交易确认**: 接收终端发送的交易确认通知,可在手机上再次确认。
- **品类选择**: 大按钮形式选择“纸壳”、“塑料瓶”等 - **实时反馈**: 显示正在进行的交易状态,包括称重、计价过程
- **重量输入**: 手动输入称重后的重量。
- 系统自动计算金额并显示。
3. **确认交易**: 与用户核对无误后,点击“确认”。系统二次弹窗确认。
4. **语音播报**: 交易成功后,必须有清晰的语音播报,如“**收款成功5.8元**”,方便老年用户确认。
#### 4.1.4 账单与库存 #### 4.1.4 "我的"页面
- **账单**: 查看每日、每周的交易流水和收入汇总。 - **界面元素**:
- **库存**: 实时查看各品类库存,达到阈值时有提醒 1. **【我的余额】**: 突出显示当前账户余额和累计收入
2. **【提现】**: 将余额提现至微信零钱,支持实名认证。
3. **【交易记录】**: 列表形式,展示每一笔交易的时间、终端位置、品类、重量、金额。
4. **【设备反馈】**: 用户可对使用过的终端设备进行评价和故障反馈。
#### 4.1.5 消息通知
- **需求**:
- 交易成功后,收到模板消息推送,告知本次收入金额。
- 提现成功后,收到模板消息推送。
- 设备故障或维护通知推送。
--- ---
## 5. 物流端 (打包站/司机端) ## 5. 运维端 (设备维护)
**核心定位:精准、高效的废品“快递员”。** (初期可为H5页面或集成在B端小程序中) **核心定位:智能终端的"医生",确保设备正常运行。**
### 5.1 功能模块详述 ### 5.1 功能模块详述
#### 5.1.1 揽收任务 #### 5.1.1 设备巡检任务
- **需求**: 查看系统(或后台运营)派发的揽收任务列表,包含小站地址、预计揽收重量、联系方式 - **需求**: 查看系统自动生成的巡检任务列表,包含终端位置、巡检类型(定期保养/故障维修/清运)、预计时间
- **功能**: 支持路线规划。 - **功能**: 支持路线规划,优化巡检效率
#### 5.1.2 扫码交接 #### 5.1.2 设备状态检测
- **需求**: 到达小站后,扫描小站端生成的“出库码” - **需求**: 到达终端后通过手机APP连接设备进行状态检测
- **流程**: 扫码后,页面显示待交接的品类和重量。司机确认实际收到的重量,可进行修改。双方确认后,完成交接 - **流程**: 检测各硬件模块(摄像头、称重、屏幕、网络)状态,记录检测结果
- **报告**: 自动生成巡检报告,上传设备照片和维修记录。
#### 5.1.3 状态更新 #### 5.1.3 清运管理
- **需求**: 可手动更新任务状态,如“运输中”、“已入库” - **需求**: 根据终端容量预警,及时清运回收物品
- **流程**: 扫描终端二维码,查看各品类存储量,记录清运重量,更新库存状态。
#### 5.1.4 故障处理
- **需求**: 接收设备故障报警,快速响应维修。
- **功能**: 常见故障诊断指导,备件管理,维修记录。
--- ---
## 6. 统一管理后台 (Web) ## 6. 数据中心 (Web/PC)
**核心定位:公司的“大脑”,驱动业务运转。** **核心定位:智能终端网络的"大脑",提供数据驱动的决策支持。**
### 6.1 功能模块详述 ### 6.1 功能模块详述
#### 6.1.1 Dashboard 数据看板 #### 6.1.1 实时监控大屏
- **需求**: 实时展示核心KPI今日交易额、总用户数、活跃小站数、各品类回收量趋势图等 - **需求**: 在PC端或数据大屏上实时显示所有终端的运行状态、交易数据、库存情况
- **可视化**: 地图展示终端分布,状态色彩编码(绿色正常/黄色预警/红色故障)。
- **告警**: 设备故障、满载、异常操作实时告警。
#### 6.1.2 用户管理 #### 6.1.2 数据分析中心
- **需求**: 查询C端用户信息、交易记录、账户状态 - **需求**: 提供深度数据分析,包括用户行为分析、设备效率分析、收益分析等
- **报表**: 自动生成日报、周报、月报,支持数据导出。
- **预测**: 基于历史数据预测设备维护需求、清运时间等。
#### 6.1.3 小站管理 #### 6.1.3 库存汇总管理
- **需求**: 小站的入驻审核、信息管理、地理位置分布图、服务状态(营业/休息)管理 - **需求**: 汇总所有终端的库存数据,为集中清运和销售提供决策支持
- **功能**: 库存预警、最优清运路线规划、销售时机建议。
#### 6.1.4 品类与价格管理
- **需求**: 动态添加/修改回收品类,实时调整各品类在不同区域的回收单价。
#### 6.1.5 订单与库存管理
- **需求**: 查询全平台所有交易流水。实时监控各小站、各打包站的库存情况。
#### 6.1.6 物流管理
- **需求**: 查看物流司机信息,手动派发或调整揽收任务,跟踪任务状态。
#### 6.1.7 财务管理
- **需求**: 管理与小站、物流司机的结算周期和账单,支持账单导出。
#### 6.1.8 系统管理
- **需求**: 后台操作员的角色与权限管理。
--- ---
## 7. 非功能性需求 ## 7. 统一管理后台 (Web端)
- **性能**: 扫码响应时间 < 1秒页面加载时间 < 2秒
**核心定位:智能终端网络的"指挥中心",驱动业务运转。**
### 7.1 功能模块详述
#### 7.1.1 Dashboard 数据看板
- **需求**: 实时展示核心KPI今日交易额、活跃用户数、**各终端设备回收量排名**、各品类回收趋势图、设备在线率等。
#### 7.1.2 终端设备管理
- **需求**: 设备的入网配置、信息管理(**设备编号、地理位置、场地方信息、运行状态**)、地理位置分布图、设备状态监控。
- **功能**: 远程设备重启、参数配置、软件更新推送。
#### 7.1.3 用户管理
- **需求**: 查询C端用户信息、交易记录、账户状态、使用习惯分析。
#### 7.1.4 品类与价格管理
- **需求**: 动态添加/修改/停用回收品类,实时调整各品类在不同区域或终端的回收单价。**支持设置不同品类的AI识别阈值参数。**
#### 7.1.5 交易与库存管理
- **需求**: 查询全平台所有交易流水。实时监控各终端设备的库存情况,自动生成清运计划。
#### 7.1.6 运维管理
- **需求**: 查看运维人员信息,手动派发或调整巡检任务,跟踪设备维护状态。
#### 7.1.7 财务管理
- **需求**: 管理与场地方、运维团队的结算周期和账单,支持成本分析和收益计算。
#### 7.1.8 系统管理
- **需求**: 后台操作员的角色与权限管理。**对异常登录行为和设备异常操作进行告警**。
#### 7.1.9 智能报警中心
- **需求**: 集中查看和处理系统产生的各类异常报警设备故障、容量预警、交易异常、网络中断AI辅助诊断问题原因。
---
## 8. 非功能性需求
- **性能**: 扫码响应时间 < 1秒页面加载时间 < 2秒系统核心接口可用性 > 99.9%。
- **易用性**: C端和B端界面必须严格遵循“适老化”设计大字体、高对比度、操作简单。 - **易用性**: C端和B端界面必须严格遵循“适老化”设计大字体、高对比度、操作简单。
- **安全性**: 交易支付个人信息等敏感数据必须加密传输和存储 - **安全性**: 交易、支付、个人信息等敏感数据必须加密传输和存储。需有完善的权限管理体系,防止未授权访问。
- **可扩展性**: 架构设计应支持未来新品类、新城市、新业务模式(如积分商城、上门回收)的快速扩展。 - **可扩展性**: 架构设计应支持未来新品类、新城市、新业务模式(如积分商城、上门回收)的快速扩展。
- **可观测性 (Observability)**:
- **监控与告警**: 对服务器、数据库、核心接口等进行实时监控并在出现异常如CPU过高、响应超时通过短信/邮件/企业微信发出告警。
- **日志管理**: 建立集中化的日志平台,支持按关键字、时间、服务模块快速检索日志,以便于高效排查问题。
- **可维护性**:
- **版本更新与回滚**: 发布流程应支持一键回滚到上一个稳定版本。
- **容量规划**: 定期输出系统资源使用趋势报告,为扩容提供决策依据。
--- ---
## 8. 版本迭代规划 (Roadmap) ## 9. 版本迭代规划 (Roadmap)
- **V1.0 (MVP)**: - **V1.0 (MVP)**:
- 核心功能: C端 + B端核心回收流程管理后台基础框架品类价格订单查看)。 - 核心功能: 智能终端硬件系统、C端小程序、基础管理后台设备监控、品类价格、订单查看)。
- 目标: 跑通商业模式闭环 - 目标: 跑通"用户->智能终端"无人值守回收模式验证3000元/台设备的自循环盈利。
- **V1.1**: - **V1.1**:
- 新增功能: 物流端H5后台物流管理后台小站管理C端提现功能 - 新增功能: 运维端APP、设备远程诊断、AI识别算法优化、C端提现功能
- 目标: 引入物流角色实现规范化清运 - 目标: 完善设备运维体系,提升设备稳定性和识别准确率。
- **V1.2**: - **V1.2**:
- 新增功能: C端积分商城后台财务结算模块数据报表优化 - 新增功能: 数据分析中心、智能清运调度、财务自动结算、设备健康管理。
- 目标: 探索增值服务提升运营效率 - 目标: 实现数据驱动运营,提升运营效率和设备利用率。
- **V1.3**:
- 新增功能: 积分商城、社区互动、碳积分系统、多品类扩展(电子垃圾等)。
- 目标: 构建环保生态圈,探索更多盈利模式。
---
**文档结束**

View File

@@ -15,25 +15,25 @@
### 1.2. 用户故事 ### 1.2. 用户故事
#### **故事1查看回收价格** #### **故事1查看回收价格和终端位置**
- **作为** 王大妈, - **作为** 王大妈,
- **我想要** 在出门前就能通过小程序看到今天纸壳子、塑料瓶卖多少钱一斤 - **我想要** 在出门前就能通过小程序看到今天各种废品的回收价格,以及最近的智能终端在哪里、是否正常运行
- **以便于** 我决定今天是否值得跑一趟,并且心里有底,不怕被坑 - **以便于** 我决定今天是否值得跑一趟,并且选择最方便的终端设备
#### **故事2找到最近的回收** #### **故事224小时随时回收**
- **作为** 刚搬来小区的年轻人小张, - **作为** 上班族小张,
- **我想要** 在小程序上用地图直接看到最近的回收站在哪,离我有多远,现在是否在营业 - **我想要** 下班后或周末任何时间都能使用智能终端处理家里的快递纸箱,不受营业时间限制
- **以便于** 我能快速方便地处理掉家里堆积的快递纸箱 - **以便于** 我能根据自己的时间安排处理废品,不用专门请假或赶时间
#### **故事3极速卖品** #### **故事3全自动回收体验**
- **作为** 王大妈, - **作为** 王大妈,
- **我想要** 到小站后让站长扫一下我的手机二维码他称重、确认后钱就能马上到我的小程序账户里并且能听到“收款成功5块8”这样的语音提醒 - **我想要** 在智能终端上用手机号登录后,按照屏幕提示选择废纸类型,把纸箱投入对应袋子,系统自动称重计价并语音播报"收款成功5块8毛"
- **以便于** 整个过程像在超市用付款码一样简单,不用我输密码、点确认,甚至不用掏手机看,听声音就知道交易成功了,非常安心 - **以便于** 整个过程像使用ATM一样简单不需要等人服务也不用担心被骗秤或算错账
#### **故事4查看我的收入** #### **故事4实时了解收益**
- **作为** 王大妈, - **作为** 王大妈,
- **我想要** 在“我的”页面清楚地看到我的账户里还有多少钱,并且能翻看每一笔卖废品的记录, - **我想要** 在手机小程序里实时看到交易完成的通知,查看我的账户余额变化和每笔交易的详细记录,
- **以便于** 我知道这个月靠卖废品攒了多少零花钱,感觉很有成就感 - **以便于** 我知道这个月通过智能终端攒了多少零花钱,对这种新方式更有信心
--- ---
@@ -71,59 +71,64 @@
--- ---
## 角色三:下站运输员 (物流司机) ## 角色三:设备运维人员
### 3.1. 核心诉求:路线清晰,任务明确,交接高效,权责分明 ### 3.1. 核心诉求:设备状态清晰,故障快速定位,维护高效便捷
#### **用户画像:张师傅** #### **用户画像:张师傅**
- **身份**: 35岁回收车队司机 - **身份**: 35岁智能终端设备运维工程师
- **习惯**: 每天需要跑多个点,时间观念强,不希望在交接流程上浪费时间 - **习惯**: 熟悉各种电子设备,有一定的技术基础,注重工作效率
- **痛点**: 路线规划不合理导致绕路,手写单据字迹潦草易出错,跟小站站长核对重量时偶尔会发生争执 - **痛点**: 设备分布较广需要跑多个点,故障诊断耗时,备件管理混乱,用户投诉处理压力大
### 3.2. 用户故事 ### 3.2. 用户故事
#### **故事1查看揽收任务** #### **故事1智能巡检任务**
- **作为** 运输员张师傅, - **作为** 运维工程师张师傅,
- **我想要** 在我的手机端H5或小程序看到今天所有需要去揽收的任务列表,并能一键开启导航, - **我想要** 在运维APP上看到系统根据设备状态自动生成的巡检任务包括设备位置、故障类型、优先级,并能一键导航,
- **以便于** 我可以合理规划路线,节省运输时间 - **以便于** 我可以高效规划巡检路线,优先处理紧急故障,提升设备可用率
#### **故事2无纸化扫码交接** #### **故事2远程诊断与现场维修**
- **作为** 运输员张师傅, - **作为** 运维工程师张师傅,
- **我想要** 到达小站后,直接扫描站长出示的出库二维码,手机上就能显示出待交接的品类和重量 - **我想要** 通过手机APP连接到智能终端远程查看设备各模块状态并获得故障诊断建议和维修指导
- **以便于** 我可以快速核对,确认无误后双方点击确认即可完成交接,无需手写单据,高效且有据可查 - **以便于** 我能快速定位问题,携带正确的备件前往现场,提高一次修复成功率
#### **故事3更新任务状态** #### **故事3设备清运与库存管理**
- **作为** 运输员张师傅, - **作为** 运维工程师张师傅,
- **我想要** 在完成揽收、运输、入库等关键节点时,能在手机上方便地更新任务状态 - **我想要** 当终端设备发出满载预警时能在APP上查看各袋子的准确重量并记录清运数据
- **以便于** 公司后台能实时了解我的工作进展,也方便了后续的流程协同 - **以便于** 我能合理安排清运车辆,确保数据准确性,避免与后台系统数据不一致
#### **故事4维修记录与绩效跟踪**
- **作为** 运维工程师张师傅,
- **我想要** 每次维修后能在APP上记录维修过程、更换的备件、维修时间并拍照存档
- **以便于** 建立完整的设备维护档案,也让我的工作成果得到准确记录和考核。
--- ---
## 角色四:大仓库管理员 ## 角色四:数据中心管理员
### 4.1. 核心诉求:入库清晰,库存准确,出库便捷 ### 4.1. 核心诉求:数据准确,监控全面,决策支持
#### **用户画像:赵主管** #### **用户画像:赵主管**
- **身份**: 50岁城市大仓的仓库主管。 - **身份**: 50岁智能终端网络数据中心主管。
- **习惯**: 工作严谨,对数据准确性要求高 - **习惯**: 工作严谨,善于数据分析,关注系统整体运行状况
- **痛点**: 司机运回来的货物品类和重量与预期不符,库存盘点耗时耗力,与下游打包站的销售记录对账困难 - **痛点**: 设备数量多分布广难以全面监控,数据异常发现不及时,缺乏有效的预测分析工具
### 4.2. 用户故事 ### 4.2. 用户故事
#### **故事1扫码确认入库** #### **故事1实时监控大屏**
- **作为** 仓库主管赵主管, - **作为** 数据中心主管赵主管,
- **我想要** 在司机把废品运到大仓时,我能扫描他任务单上的二维码,系统就自动记录某某司机在什么时间、从哪些小站运来了多少斤什么废品 - **我想要** 在数据中心的大屏上实时看到所有智能终端的运行状态、交易数据、库存情况,并用不同颜色标识设备健康状态
- **以便于** 我可以快速完成入库登记,保证数据的准确性,并自动更新仓库库存 - **以便于** 我能一目了然地掌握整个终端网络的运行情况,及时发现异常设备
#### **故事2实时库存监控** #### **故事2智能预警与分析**
- **作为** 仓库主管赵主管, - **作为** 数据中心主管赵主管,
- **我想要** 在后台系统的大屏或电脑上,实时看到仓库里所有品类的库存量、存放位置和存放天数 - **我想要** 系统能基于历史数据自动预测设备维护需求、最佳清运时间,并在设备即将出现故障前提前预警
- **以便于** 我可以合理规划仓储空间,并在某种废品库存达到一定数量时,及时安排出库销售 - **以便于** 我能提前安排运维资源,实现预防性维护,降低设备故障率
#### **故事3生成出库单** #### **故事3数据报表与决策支持**
- **作为** 仓库主管赵主管, - **作为** 数据中心主管赵主管,
- **我想要** 当联系好下游的打包站后,能在系统里选择品类和重量,一键生成标准化的出库单 - **我想要** 系统能自动生成各类运营报表,包括设备利用率、用户活跃度、收益分析等,并支持自定义查询和数据导出
- **以便于** 我可以指导工人备货,并作为与打包站结算的凭证,让整个出库流程规范化 - **以便于** 我能为公司管理层提供准确的数据支持,协助制定运营策略和扩张计划
--- ---

View File

@@ -0,0 +1,326 @@
# 智能回收终端设备技术规格文档 V1.0
> **文档状态**: 初稿
> **版本**: 1.0
> **修订日期**: 2024-09-15
> **作者**: 产品技术团队
---
## 1. 产品概述
### 1.1 产品定位
智能回收终端是一款部署在超市、快递门口的便携式废品回收设备通过AI视觉识别、自动称重、智能分类等技术在营业时间内提供智能化回收服务。设备可根据营业时间灵活收纳。
### 1.2 设计原则
- **成本控制**: 设备硬件成本控制在1000元以内
- **便携设计**: 支持营业时间外的收纳存放
- **用户友好**: 操作简单直观,适合中老年用户使用
- **简化部署**: 利用现有电源,无需复杂安装
---
## 2. 硬件规格
### 2.1 主要组成部件
#### 2.1.1 交互平板
- **平板电脑**: 10.1英寸Android/Windows平板2GB RAM + 32GB存储
- **触控**: 电容触摸屏,支持多点触控
- **连接**: WiFi + 4G LTE网络
- **可收纳**: 支持营业结束后收进室内保管
- **成本预算**: ≤350元
#### 2.1.2 AI摄像头
- **摄像头**: USB接口200万像素摄像头
- **视野**: 覆盖回收袋投入口区域
- **连接**: USB连接至平板即插即用
- **防护**: 基础防尘设计
- **成本预算**: ≤150元
#### 2.1.3 称重系统
- **称重模块**: 便携式电子秤模块×3
- **量程**: 单袋最大承重50kg精度±50g
- **连接**: 蓝牙/USB连接至平板
- **便携**: 支持快速拆装和收纳
- **成本预算**: ≤300元
#### 2.1.4 分类回收袋
- **回收袋**: 3个标准回收袋容积40L/袋
- **材料**: 牛津布或帆布材质,可清洗
- **标识**: 丝印分类标识无需LED灯
- **便携**: 可折叠收纳
- **成本预算**: ≤100元
#### 2.1.5 支撑骨架
- **材料**: 铝合金便携式支架
- **设计**: 可折叠设计,便于收纳运输
- **稳定**: 确保使用时的结构稳定性
- **重量**: 整套骨架≤15kg
- **成本预算**: ≤100元
### 2.2 整机规格
| 项目 | 规格参数 |
|------|----------|
| 展开尺寸 | 1000mm(H) × 600mm(W) × 400mm(D) |
| 收纳尺寸 | 200mm(H) × 600mm(W) × 400mm(D) |
| 整机重量 | ≤20kg |
| 工作温度 | 0°C ~ +40°C (室内使用) |
| 存储温度 | -10°C ~ +50°C |
| 工作湿度 | 20%~80% RH (无凝露) |
| 防护等级 | IP20 (基础防尘) |
| 供电要求 | 使用现有220V市电 |
| 功耗 | 工作≤30W |
| 通信方式 | Wi-Fi + 4G LTE + 蓝牙 |
| 认证标准 | 3C认证 |
---
## 3. 软件架构
### 3.1 平板应用软件
- **平台**: Android 8.0+ 或 Windows 10
- **开发**: 原生应用或H5网页应用
- **界面**: 简洁易用的触控界面
- **更新**: 应用商店更新或远程更新
### 3.2 外设连接
- **摄像头**: USB即插即用标准UVC驱动
- **称重模块**: 蓝牙或USB连接标准HID协议
- **网络**: Wi-Fi优先4G备用
- **数据同步**: 实时上传至云端服务器
### 3.3 AI识别引擎
- **框架**: 云端AI识别 + 本地缓存
- **识别方式**: 拍照上传至云端识别
- **识别品类**: 塑料瓶、废纸、织物等
- **准确率**: ≥90% (依赖云端算法)
- **响应时间**: ≤5秒 (含网络传输)
### 3.4 应用功能
- **用户登录**: 手机号验证码登录,小程序扫码登录
- **品类选择**: 大按钮选择回收品类
- **称重计价**: 自动读取称重数据并计价
- **交易确认**: 语音播报和屏幕确认
### 3.5 云端对接
- **协议**: HTTPS + MQTT over SSL
- **数据同步**: 实时上传交易数据
- **远程控制**: 支持远程参数配置
- **监控**: 实时状态监控和告警
---
## 4. 用户界面设计
### 4.1 界面设计原则
- **适老化设计**: 大字体、高对比度、简化操作
- **多语言支持**: 中文、英文界面切换
- **语音提示**: 全程语音引导和反馈
- **视觉反馈**: 丰富的动画和状态提示
### 4.2 主要界面流程
```mermaid
graph TD
A[待机界面<br>显示回收价格] --> B[用户登录<br>手机号/扫码]
B --> C[选择品类<br>塑料瓶/废纸/织物]
C --> D[投入物品<br>AI识别验证]
D --> E[自动称重<br>计算价格]
E --> F[确认交易<br>语音播报]
F --> G[交易完成<br>返回待机]
D --> H{识别失败}
H --> I[重新投入<br>或人工客服]
```
### 4.3 界面元素规范
- **主要文字**: 36px 思源黑体
- **按钮**: 最小80×60px圆角8px
- **颜色**: 主色调绿色#2E8B57,警告色红色#DC143C
- **图标**: 简洁线条风格,支持夜间模式
---
## 5. 网络与通信
### 5.1 通信架构
- **主通道**: 4G LTE网络连接云端服务器
- **备份通道**: Wi-Fi网络作为备用连接
- **本地通信**: 蓝牙5.0支持维护人员本地连接
### 5.2 数据传输
- **实时数据**: 交易数据实时上传
- **状态监控**: 每分钟上报设备状态
- **大文件**: 图片和日志文件压缩后传输
- **离线缓存**: 支持7天离线数据缓存
### 5.3 网络安全
- **加密**: TLS 1.3端到端加密
- **认证**: 设备证书双向认证
- **防护**: DDoS攻击防护
- **审计**: 完整的通信日志记录
---
## 6. 运行环境要求
### 6.1 部署环境
- **场地**: 超市内部或有顶棚的门口区域
- **电源**: 就近使用超市现有220V电源插座
- **网络**: Wi-Fi环境优先+ 4G信号覆盖
- **地面**: 平整地面即可,无需特殊承重要求
### 6.2 使用空间
- **展开时**: 营业时间内在指定区域展开使用
- **收纳时**: 营业结束后可收纳至室内存放
- **操作空间**: 前方预留1m用户操作区域
- **存放空间**: 室内预留0.5m²存放空间
### 6.3 部署要求
- **安装**: 无需复杂安装,即插即用
- **固定**: 临时固定方式,防止意外移动
- **收纳**: 支持快速拆装和室内存放
- **安全**: 平板等贵重设备可收进室内
---
## 7. 性能指标
### 7.1 关键性能指标
| 指标类别 | 具体指标 | 目标值 | 备注 |
|----------|----------|--------|------|
| **可用性** | 设备在线率 | ≥99% | 月度统计 |
| **可靠性** | 故障率(MTBF) | ≥2000小时 | 平均故障间隔 |
| **准确性** | 称重精度 | ±10g | 单次称重 |
| **识别率** | AI识别准确率 | ≥95% | 标准光线条件 |
| **响应性** | 交易完成时间 | ≤60秒 | 从投入到完成 |
| **容量** | 日处理能力 | 50-100笔 | 根据使用频率 |
| **效率** | 单笔交易时间 | ≤60秒 | 平均处理时间 |
### 7.2 用户体验指标
- **操作简易度**: 3步完成交易
- **等待时间**: AI识别≤3秒称重≤2秒
- **语音反馈**: 清晰度≥85分贝
- **界面响应**: 触控响应≤200ms
---
## 8. 成本分析
### 8.1 硬件成本构成
| 组件 | 成本(元) | 占比 |
|------|----------|------|
| 交互平板 | 350 | 35.0% |
| 称重系统 | 300 | 30.0% |
| AI摄像头 | 150 | 15.0% |
| 分类回收袋 | 100 | 10.0% |
| 支撑骨架 | 100 | 10.0% |
| **硬件总计** | **1000** | **100%** |
### 8.2 总投资成本构成
- **硬件设备**: 1000元/台
- **部署安装**: 300元/台 (运输、安装、调试)
- **培训推广**: 200元/台 (场地方培训、用户推广)
- **运营启动**: 500元/台 (前3个月运营成本)
- **备品备件**: 1000元/台 (维修备件、损耗补充)
- **总投资**: 3000元/台
### 8.3 运营成本预估
- **网络费用**: 30元/月 (4G套餐)
- **设备维护**: 80元/月 (人工+备件)
- **电费**: 实际很少 (使用超市电源)
- **场地费**: 50元/月 (给超市的场地费)
- **月运营成本**: 160元/台
- **年运营成本**: 1920元/台
### 8.4 投资回收分析
- **总投入**: 3000元/台
- **预期日收入**: 15-30元/台 (基于交易分成)
- **月收入**: 450-900元/台
- **扣除运营成本**: 290-740元/台 (净收入)
- **投资回收期**: 4-10个月
---
## 9. 质量保证
### 9.1 测试标准
- **功能测试**: 100%功能覆盖测试
- **性能测试**: 7×24小时连续运行测试
- **环境测试**: 高低温、湿度、震动测试
- **EMC测试**: 电磁兼容性测试
- **安全测试**: 电气安全和机械安全测试
### 9.2 质量认证
- **国标认证**: GB 4943.1-2011信息技术设备安全
- **环保认证**: RoHS 2.0有害物质限制指令
- **通信认证**: 工信部无线电发射设备型号核准
- **安全认证**: CCC强制性产品认证
### 9.3 售后服务
- **质保期**: 整机保修24个月
- **维修响应**: 市区4小时郊区24小时
- **备件保证**: 常用备件5年供应保证
- **技术支持**: 7×24小时远程技术支持
---
## 10. 技术发展路线
### 10.1 V1.0版本 (MVP)
- 基础功能实现: 识别、称重、交易
- 支持3大类物品回收
- 基本的远程监控能力
### 10.2 V1.1版本 (优化版)
- AI识别算法优化准确率提升至98%
- 增加更多回收品类支持
- 优化用户界面和交互流程
- 增强故障自诊断能力
### 10.3 V1.2版本 (智能版)
- 集成更强大的边缘计算能力
- 支持用户行为分析和个性化服务
- 增加积分兑换和游戏化元素
- 实现预测性维护
### 10.4 未来发展
- 支持更多品类(电子垃圾、有害垃圾)
- 集成区块链技术实现碳积分
- AI算法持续优化和自学习
- 与智慧城市系统深度集成
---
## 11. 附录
### 11.1 相关标准
- GB/T 191-2008《包装储运图示标志》
- GB 4943.1-2011《信息技术设备 安全 第1部分》
- GB/T 2423《电工电子产品环境试验》
- YD/T 1538-2014《移动通信手持机充电器及接口技术要求》
### 11.2 供应商推荐
- **主控芯片**: 瑞芯微RK3399、全志H6
- **触控屏**: 京东方、天马微电子
- **称重传感器**: 梅特勒-托利多、赛多利斯
- **摄像头**: 海康威视、大华股份
- **结构件**: 富士康、比亚迪精密制造
### 11.3 部署检查清单
- [ ] 现场勘查和空间规划
- [ ] 确认电源插座位置
- [ ] WiFi网络配置和4G信号测试
- [ ] 设备组装和摆放
- [ ] 平板应用安装和配置
- [ ] 称重设备校准
- [ ] 场地方培训和说明
- [ ] 试运行和用户体验测试
- [ ] 运营数据对接确认
---
**文档版权**: 绿邻回收项目组所有,未经授权不得转载或使用。

691
UI.html Normal file
View File

@@ -0,0 +1,691 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绿邻回收 - 全端原型</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body {
background-color: #f0f2f5;
}
.mobile-frame {
width: 375px;
height: 812px;
border: 8px solid black;
border-radius: 40px;
background-color: #f7f8fa;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
position: relative;
display: flex;
flex-direction: column;
}
.screen {
width: 100%;
flex-grow: 1;
overflow-y: auto;
}
.screen::-webkit-scrollbar {
display: none;
}
.bottom-nav {
width: 100%;
height: 60px;
background-color: white;
border-top: 1px solid #e5e7eb;
display: flex;
justify-content: space-around;
align-items: center;
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
color: #6b7280;
}
.nav-item.active {
color: #28a745;
}
</style>
</head>
<body>
<div class="w-full flex flex-col items-center p-5">
<!-- C端 分组 -->
<div class="w-full max-w-screen-2xl mb-12">
<h1 class="text-3xl font-bold text-center mb-6 text-gray-700">C端 (居民端)</h1>
<div class="flex flex-wrap justify-center gap-5">
<!-- C端 - 首页 -->
<div class="mobile-frame">
<div class="screen p-4">
<div class="text-center my-8">
<button class="bg-green-500 text-white rounded-lg shadow-lg w-full py-6">
<i class="ri-qr-scan-line text-6xl"></i>
<span class="block text-2xl font-bold mt-2">扫一扫 开始回收</span>
</button>
<p class="text-center text-sm text-gray-500 mt-2">使用微信扫一扫,扫描终端屏幕上的二维码即可回收</p>
</div>
<!-- 突出显示今日回收价格 -->
<div class="bg-gradient-to-r from-green-400 to-green-600 text-white p-6 rounded-2xl shadow-2xl mb-4">
<h3 class="font-bold text-2xl mb-4 text-center flex items-center justify-center">
<i class="ri-price-tag-3-line mr-3 text-3xl"></i>今日回收价格
</h3>
<div class="grid grid-cols-3 gap-4 text-center">
<div class="bg-white/20 backdrop-blur rounded-xl p-4">
<div class="text-xl font-bold mb-1">废纸壳</div>
<div class="text-3xl font-black">0.85</div>
<div class="text-lg opacity-90">元/斤</div>
</div>
<div class="bg-white/20 backdrop-blur rounded-xl p-4">
<div class="text-xl font-bold mb-1">塑料瓶</div>
<div class="text-3xl font-black">0.10</div>
<div class="text-lg opacity-90">元/个</div>
</div>
<div class="bg-white/20 backdrop-blur rounded-xl p-4">
<div class="text-xl font-bold mb-1">旧衣物</div>
<div class="text-3xl font-black">0.50</div>
<div class="text-lg opacity-90">元/斤</div>
</div>
</div>
<div class="text-center mt-4 text-lg opacity-90">
<i class="ri-time-line mr-2"></i>实时更新 · 当天有效
</div>
</div>
<div class="bg-white p-4 rounded-lg shadow">
<h3 class="font-bold text-lg mb-2 flex items-center"><i class="ri-store-2-line mr-2 text-green-500"></i>附近小站</h3>
<div class="space-y-3">
<div class="flex items-center">
<div class="flex-grow">
<p class="font-bold">社区便民超市</p>
<p class="text-sm text-gray-500">距离您 200米</p>
</div>
<span class="text-sm font-semibold text-green-600 bg-green-100 px-2 py-1 rounded-full">营业中</span>
</div>
<div class="flex items-center">
<div class="flex-grow">
<p class="font-bold">好邻居快递驿站</p>
<p class="text-sm text-gray-500">距离您 500米</p>
</div>
<span class="text-sm font-semibold text-gray-500 bg-gray-200 px-2 py-1 rounded-full">休息中</span>
</div>
</div>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item active"><i class="ri-home-4-fill text-2xl"></i><span>首页</span></div>
<div class="nav-item"><i class="ri-user-fill text-2xl"></i><span>我的</span></div>
</div>
</div>
<!-- C端 - 我的页面 -->
<div class="mobile-frame">
<div class="screen p-4">
<div class="flex items-center mb-6">
<img src="https://images.unsplash.com/photo-1529665253569-6d01c0eaf7b6?q=80&w=200&auto=format&fit=crop" class="w-16 h-16 rounded-full object-cover mr-4" alt="avatar">
<div>
<h2 class="text-2xl font-bold">王大妈</h2>
<p class="text-gray-500">欢迎使用绿邻回收</p>
</div>
</div>
<div class="bg-green-500 text-white p-6 rounded-lg shadow-lg text-center mb-6">
<p class="text-lg">我的余额 (元)</p>
<p class="text-5xl font-bold my-2">128.50</p>
<!-- V1.1功能MVP版本中移除 -->
</div>
<div class="space-y-3 text-lg">
<div class="flex justify-between items-center p-4 bg-white rounded-lg shadow-sm">
<div class="flex items-center"><i class="ri-bill-line mr-3 text-green-500"></i><span>交易记录</span></div>
<i class="ri-arrow-right-s-line"></i>
</div>
<div class="flex justify-between items-center p-4 bg-white rounded-lg shadow-sm">
<div class="flex items-center"><i class="ri-customer-service-2-line mr-3 text-green-500"></i><span>联系客服</span></div>
<i class="ri-arrow-right-s-line"></i>
</div>
</div>
<!-- C端图表 -->
<div class="bg-white p-4 rounded-lg shadow mt-4">
<h3 class="font-bold text-lg mb-2 flex items-center"><i class="ri-pie-chart-2-line mr-2 text-green-500"></i>我的回收分布</h3>
<canvas id="cUserChart" height="180"></canvas>
</div>
<div class="bg-white p-4 rounded-lg shadow mt-4">
<h3 class="font-bold text-lg mb-2 flex items-center"><i class="ri-bar-chart-line mr-2 text-green-500"></i>历史收入</h3>
<canvas id="cHistoryChart" height="180"></canvas>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item"><i class="ri-home-4-line text-2xl"></i><span>首页</span></div>
<div class="nav-item active"><i class="ri-user-fill text-2xl"></i><span>我的</span></div>
</div>
</div>
<!-- C端 - 交易记录 -->
<div class="mobile-frame">
<div class="screen">
<div class="p-4 bg-white border-b sticky top-0">
<div class="flex items-center"><i class="ri-arrow-left-s-line text-2xl mr-2"></i><h1 class="font-bold text-xl flex-grow text-center">交易记录</h1></div>
</div>
<!-- 列表有数据时 -->
<div class="p-4 space-y-3">
<div class="bg-white p-3 rounded-lg shadow-sm">
<div class="flex justify-between items-center mb-2"><span class="font-bold">社区便民超市</span><span class="text-xl font-bold text-green-600">+4.93</span></div>
<p class="text-sm text-gray-500">2025-08-15 10:30:45</p>
<div class="text-sm text-gray-600 mt-2 pt-2 border-t"><p>废纸壳: 5.8斤 x 0.85元/斤</p></div>
</div>
<div class="bg-white p-3 rounded-lg shadow-sm">
<div class="flex justify-between items-center mb-2"><span class="font-bold">好邻居快递驿站</span><span class="text-xl font-bold text-green-600">+12.50</span></div>
<p class="text-sm text-gray-500">2025-08-14 16:21:10</p>
<div class="text-sm text-gray-600 mt-2 pt-2 border-t"><p>旧衣物: 25.0斤 x 0.50元/斤</p></div>
</div>
</div>
<!-- 空状态 -->
<div class="p-4 text-center mt-16">
<i class="ri-file-text-line text-6xl text-gray-300"></i>
<p class="mt-4 text-gray-500">您还没有交易记录哦</p>
<p class="text-sm text-gray-400">快去楼下小站卖一次吧!</p>
</div>
</div>
</div>
</div>
</div>
<!-- 智能终端平板 分组 -->
<div class="w-full max-w-screen-2xl mb-12 border-t pt-8 mt-8">
<h1 class="text-3xl font-bold text-center mb-6 text-gray-700">智能回收终端界面</h1>
<div class="flex flex-wrap justify-center gap-5">
<!-- 平板框架样式 -->
<style>
.tablet-frame {
width: 768px;
height: 1024px;
border: 12px solid #2c3e50;
border-radius: 25px;
background-color: #000;
overflow: hidden;
box-shadow: 0 15px 40px rgba(0,0,0,0.2);
position: relative;
display: flex;
flex-direction: column;
}
.tablet-screen {
width: 100%;
flex-grow: 1;
overflow-y: auto;
background-color: #f8f9fa;
}
</style>
<!-- 智能终端 - 待机界面(显示二维码供扫描) -->
<div class="tablet-frame">
<div class="tablet-screen p-8 flex flex-col">
<!-- 顶部状态栏 -->
<div class="flex justify-between items-center mb-6 p-4 bg-white rounded-lg shadow-sm">
<div class="flex items-center">
<div class="w-4 h-4 bg-green-500 rounded-full mr-3"></div>
<span class="text-lg font-semibold">社区便民超市 - 绿邻回收终端</span>
</div>
<div class="text-right">
<div class="text-2xl font-bold">15:30</div>
<div class="text-sm text-gray-500">2025年8月15日</div>
<button class="ml-4 bg-blue-100 text-blue-600 px-4 py-2 rounded-lg text-sm">
<i class="ri-settings-line mr-1"></i>管理
</button>
</div>
</div>
<!-- 主二维码区域 -->
<div class="flex-grow flex items-center justify-center">
<div class="text-center">
<div class="bg-white rounded-3xl p-12 shadow-2xl mb-8">
<div class="mb-8">
<h2 class="text-4xl font-bold text-gray-800 mb-4">微信扫一扫开始回收</h2>
<p class="text-xl text-gray-600">操作简单,老少皆宜</p>
</div>
<!-- 大尺寸二维码 -->
<div class="bg-gray-100 rounded-2xl p-8">
<img src="https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=https://weixin.qq.com/recycling/start?terminal=SHOP001"
alt="回收二维码" class="mx-auto">
</div>
<div class="mt-6 flex justify-center gap-6 text-gray-500">
<div class="flex items-center">
<i class="ri-smartphone-line text-2xl mr-2"></i>
<span>支持微信</span>
</div>
<div class="flex items-center">
<i class="ri-qr-scan-2-line text-2xl mr-2"></i>
<span>扫码即用</span>
</div>
<div class="flex items-center">
<i class="ri-coin-line text-2xl mr-2"></i>
<span>立即到账</span>
</div>
</div>
</div>
</div>
</div>
<!-- 底部价格展示 -->
<div class="bg-white rounded-2xl p-6 shadow-lg">
<div class="grid grid-cols-3 gap-6 text-center">
<div class="p-4 bg-green-50 rounded-xl">
<div class="text-lg font-semibold mb-1">废纸壳</div>
<div class="text-2xl font-bold text-green-600">0.85元/斤</div>
</div>
<div class="p-4 bg-blue-50 rounded-xl">
<div class="text-lg font-semibold mb-1">塑料瓶</div>
<div class="text-2xl font-bold text-blue-600">0.10元/个</div>
</div>
<div class="p-4 bg-purple-50 rounded-xl">
<div class="text-lg font-semibold mb-1">旧衣物</div>
<div class="text-2xl font-bold text-purple-600">0.50元/斤</div>
</div>
</div>
</div>
</div>
</div>
<!-- 智能终端 - 普通用户回收流程界面 -->
<div class="tablet-frame">
<div class="tablet-screen p-8">
<!-- 用户信息栏 -->
<div class="bg-white rounded-2xl p-6 shadow-lg mb-8">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="https://images.unsplash.com/photo-1529665253569-6d01c0eaf7b6?q=80&w=80&auto=format&fit=crop"
class="w-16 h-16 rounded-full object-cover mr-4" alt="用户头像">
<div>
<h3 class="text-2xl font-bold">王大妈</h3>
<p class="text-gray-500">欢迎使用绿邻回收</p>
</div>
</div>
<button class="bg-red-100 text-red-600 px-6 py-3 rounded-lg font-semibold">
<i class="ri-close-line mr-2"></i>取消回收
</button>
</div>
</div>
<!-- 品类选择 -->
<div class="bg-white rounded-2xl p-8 shadow-lg mb-8">
<h3 class="text-3xl font-bold mb-8">请选择回收品类</h3>
<div class="grid grid-cols-3 gap-8">
<button class="p-8 bg-green-500 text-white rounded-2xl shadow-lg transform scale-105">
<i class="ri-file-paper-2-line text-6xl mb-4"></i>
<div class="text-2xl font-bold mb-2">废纸壳</div>
<div class="text-lg opacity-90">0.85元/斤</div>
</button>
<button class="p-8 bg-gray-100 text-gray-700 rounded-2xl hover:bg-gray-200 transition-colors">
<i class="ri-drop-line text-6xl mb-4"></i>
<div class="text-2xl font-bold mb-2">塑料瓶</div>
<div class="text-lg">0.10元/个</div>
</button>
<button class="p-8 bg-gray-100 text-gray-700 rounded-2xl hover:bg-gray-200 transition-colors">
<i class="ri-shirt-line text-6xl mb-4"></i>
<div class="text-2xl font-bold mb-2">旧衣物</div>
<div class="text-lg">0.50元/斤</div>
</button>
</div>
</div>
<!-- 称重和确认区域 -->
<div class="grid grid-cols-2 gap-8">
<!-- 称重区域 -->
<div class="bg-white rounded-2xl p-8 shadow-lg">
<h3 class="text-2xl font-bold mb-6">请放入回收袋中</h3>
<div class="text-center">
<div class="bg-gray-50 rounded-xl p-8 mb-6">
<i class="ri-scales-3-line text-5xl text-gray-400 mb-4"></i>
<div class="text-5xl font-bold text-green-600 mb-2">5.8</div>
<div class="text-xl text-gray-500"></div>
</div>
<div class="text-gray-600 text-lg">
<p>自动称重中...</p>
<p class="text-sm mt-2">请稍候片刻</p>
</div>
</div>
</div>
<!-- 确认信息 -->
<div class="bg-gradient-to-br from-green-500 to-green-600 text-white rounded-2xl p-8 shadow-lg">
<h3 class="text-2xl font-bold mb-6">回收信息确认</h3>
<div class="space-y-4 mb-8">
<div class="flex justify-between items-center text-lg">
<span>回收品类:</span>
<span class="font-bold">废纸壳</span>
</div>
<div class="flex justify-between items-center text-lg">
<span>重量:</span>
<span class="font-bold">5.8 斤</span>
</div>
<div class="flex justify-between items-center text-lg">
<span>单价:</span>
<span class="font-bold">0.85 元/斤</span>
</div>
<div class="border-t border-white/30 pt-4">
<div class="flex justify-between items-center">
<span class="text-xl">合计金额:</span>
<span class="text-4xl font-bold">¥ 4.93</span>
</div>
</div>
</div>
<button class="w-full bg-white text-green-600 py-6 rounded-xl font-bold text-2xl shadow-lg hover:shadow-xl transition-shadow">
<i class="ri-check-line mr-3"></i>确认回收
</button>
</div>
</div>
</div>
</div>
<!-- 智能终端 - 登录界面 -->
<div class="tablet-frame">
<div class="tablet-screen p-8 flex items-center justify-center">
<div class="bg-white rounded-3xl p-12 shadow-2xl max-w-md w-full">
<div class="text-center mb-8">
<i class="ri-shield-user-line text-6xl text-blue-600 mb-4"></i>
<h2 class="text-3xl font-bold text-gray-800 mb-2">终端管理登录</h2>
<p class="text-gray-600">请选择您的身份</p>
</div>
<div class="space-y-4">
<button class="w-full bg-blue-600 text-white p-6 rounded-2xl font-bold text-xl hover:bg-blue-700 transition-colors">
<i class="ri-user-settings-line text-3xl mb-2"></i>
<div>小站管理员</div>
<div class="text-sm opacity-90">李老板</div>
</button>
<button class="w-full bg-green-600 text-white p-6 rounded-2xl font-bold text-xl hover:bg-green-700 transition-colors">
<i class="ri-truck-line text-3xl mb-2"></i>
<div>清运人员</div>
<div class="text-sm opacity-90">物流收取</div>
</button>
<button class="w-full bg-gray-200 text-gray-700 p-4 rounded-2xl font-semibold hover:bg-gray-300 transition-colors">
<i class="ri-arrow-left-line mr-2"></i>返回用户界面
</button>
</div>
</div>
</div>
</div>
<!-- 智能终端 - 管理员工作台 -->
<div class="tablet-frame">
<div class="tablet-screen p-8">
<!-- 管理员顶部栏 -->
<div class="flex justify-between items-center mb-8 p-4 bg-blue-600 text-white rounded-lg shadow-sm">
<div class="flex items-center">
<i class="ri-user-settings-line text-2xl mr-3"></i>
<div>
<span class="text-lg font-semibold">管理员:李老板</span>
<div class="text-sm opacity-90">社区便民超市</div>
</div>
</div>
<div class="flex gap-4">
<div class="text-right">
<div class="text-xl font-bold">15:30</div>
<div class="text-sm opacity-90">8月15日</div>
</div>
<button class="bg-white text-blue-600 px-4 py-2 rounded-lg text-sm font-semibold">
<i class="ri-logout-box-line mr-1"></i>退出
</button>
</div>
</div>
<!-- 今日数据汇总 -->
<div class="grid grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-2xl p-6 shadow-lg text-center">
<i class="ri-shopping-bag-3-line text-4xl text-blue-600 mb-3"></i>
<div class="text-3xl font-bold text-blue-600">32</div>
<div class="text-gray-500">今日订单</div>
</div>
<div class="bg-white rounded-2xl p-6 shadow-lg text-center">
<i class="ri-scales-3-line text-4xl text-green-600 mb-3"></i>
<div class="text-3xl font-bold text-green-600">158.7</div>
<div class="text-gray-500">总重量(kg)</div>
</div>
<div class="bg-white rounded-2xl p-6 shadow-lg text-center">
<i class="ri-money-dollar-circle-line text-4xl text-yellow-600 mb-3"></i>
<div class="text-3xl font-bold text-yellow-600">¥245</div>
<div class="text-gray-500">今日收入</div>
</div>
</div>
<!-- 功能操作区 -->
<div class="grid grid-cols-2 gap-6 mb-8">
<button class="bg-white rounded-2xl p-8 shadow-lg hover:shadow-xl transition-shadow">
<i class="ri-price-tag-3-line text-4xl text-green-600 mb-4"></i>
<div class="text-xl font-bold mb-2">修改回收价格</div>
<div class="text-gray-500">调整各品类回收价格</div>
</button>
<button class="bg-white rounded-2xl p-8 shadow-lg hover:shadow-xl transition-shadow">
<i class="ri-file-list-3-line text-4xl text-blue-600 mb-4"></i>
<div class="text-xl font-bold mb-2">交易记录</div>
<div class="text-gray-500">查看所有回收记录</div>
</button>
<button class="bg-white rounded-2xl p-8 shadow-lg hover:shadow-xl transition-shadow">
<i class="ri-stack-line text-4xl text-purple-600 mb-4"></i>
<div class="text-xl font-bold mb-2">库存管理</div>
<div class="text-gray-500">查看和管理库存</div>
</button>
<button class="bg-white rounded-2xl p-8 shadow-lg hover:shadow-xl transition-shadow">
<i class="ri-truck-line text-4xl text-orange-600 mb-4"></i>
<div class="text-xl font-bold mb-2">通知清运</div>
<div class="text-gray-500">申请物流收取</div>
</button>
</div>
<!-- 返回用户界面 -->
<button class="w-full bg-gray-200 text-gray-700 p-4 rounded-2xl font-bold text-xl">
<i class="ri-arrow-left-line mr-2"></i>返回用户界面
</button>
</div>
</div>
<!-- 智能终端 - 清运人员界面 -->
<div class="tablet-frame">
<div class="tablet-screen p-8">
<!-- 清运人员顶部栏 -->
<div class="flex justify-between items-center mb-8 p-4 bg-green-600 text-white rounded-lg shadow-sm">
<div class="flex items-center">
<i class="ri-truck-line text-2xl mr-3"></i>
<div>
<span class="text-lg font-semibold">清运人员:张师傅</span>
<div class="text-sm opacity-90">绿邻物流</div>
</div>
</div>
<div class="flex gap-4">
<div class="text-right">
<div class="text-xl font-bold">15:30</div>
<div class="text-sm opacity-90">8月15日</div>
</div>
<button class="bg-white text-green-600 px-4 py-2 rounded-lg text-sm font-semibold">
<i class="ri-logout-box-line mr-1"></i>退出
</button>
</div>
</div>
<!-- 待收取库存 -->
<div class="bg-white rounded-2xl p-8 shadow-lg mb-8">
<h3 class="text-2xl font-bold mb-6 flex items-center">
<i class="ri-stack-line mr-3 text-green-600"></i>待收取物品
</h3>
<div class="grid grid-cols-3 gap-6">
<div class="bg-green-50 rounded-xl p-6 text-center">
<i class="ri-file-paper-2-line text-3xl text-green-600 mb-3"></i>
<div class="text-lg font-semibold mb-2">废纸壳</div>
<div class="text-3xl font-bold text-green-600">90</div>
<div class="text-sm text-gray-500">公斤</div>
</div>
<div class="bg-blue-50 rounded-xl p-6 text-center">
<i class="ri-drop-line text-3xl text-blue-600 mb-3"></i>
<div class="text-lg font-semibold mb-2">塑料瓶</div>
<div class="text-3xl font-bold text-blue-600">45</div>
<div class="text-sm text-gray-500">公斤</div>
</div>
<div class="bg-purple-50 rounded-xl p-6 text-center">
<i class="ri-shirt-line text-3xl text-purple-600 mb-3"></i>
<div class="text-lg font-semibold mb-2">旧衣物</div>
<div class="text-3xl font-bold text-purple-600">25</div>
<div class="text-sm text-gray-500">公斤</div>
</div>
</div>
</div>
<!-- 收取确认 -->
<div class="bg-white rounded-2xl p-8 shadow-lg mb-8">
<h3 class="text-2xl font-bold mb-6">收取确认</h3>
<div class="space-y-4">
<div class="flex justify-between items-center p-4 bg-gray-50 rounded-lg">
<span class="text-lg">总重量</span>
<span class="text-2xl font-bold">160 公斤</span>
</div>
<div class="flex justify-between items-center p-4 bg-gray-50 rounded-lg">
<span class="text-lg">预估价值</span>
<span class="text-2xl font-bold text-green-600">¥ 89.50</span>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="grid grid-cols-2 gap-6 mb-8">
<button class="bg-green-600 text-white p-6 rounded-2xl font-bold text-xl hover:bg-green-700 transition-colors">
<i class="ri-checkbox-circle-line text-3xl mb-2"></i>
<div>确认收取</div>
</button>
<button class="bg-gray-200 text-gray-700 p-6 rounded-2xl font-bold text-xl hover:bg-gray-300 transition-colors">
<i class="ri-close-circle-line text-3xl mb-2"></i>
<div>暂不收取</div>
</button>
</div>
<!-- 返回用户界面 -->
<button class="w-full bg-gray-200 text-gray-700 p-4 rounded-2xl font-bold text-xl">
<i class="ri-arrow-left-line mr-2"></i>返回用户界面
</button>
</div>
</div>
<!-- 智能终端 - 回收完成界面 -->
<div class="tablet-frame">
<div class="tablet-screen p-8 flex flex-col justify-center items-center text-center">
<div class="bg-white rounded-3xl p-16 shadow-2xl max-w-2xl">
<div class="w-24 h-24 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-8">
<i class="ri-check-line text-5xl text-white"></i>
</div>
<h2 class="text-4xl font-bold text-gray-800 mb-4">回收成功!</h2>
<p class="text-xl text-gray-600 mb-8">感谢您为环保事业做出的贡献</p>
<div class="bg-gray-50 rounded-2xl p-8 mb-8">
<div class="text-lg text-gray-600 mb-2">本次回收金额</div>
<div class="text-5xl font-bold text-green-600 mb-4">¥ 4.93</div>
<div class="text-gray-500">废纸壳 5.8斤 × 0.85元/斤</div>
</div>
<div class="text-gray-500 mb-8">
<p class="text-lg">回收金额已通过微信支付到账</p>
<p class="text-sm mt-2">如有疑问请联系客服400-123-4567</p>
</div>
<div class="text-6xl font-bold text-green-500 mb-4">5</div>
<div class="text-lg text-gray-500">秒后自动返回首页</div>
</div>
</div>
</div>
</div>
</div>
<!-- 物流端 (V1.1功能MVP版本中移除) -->
</div>
<script>
// C端图表
const cUserCtx = document.getElementById('cUserChart').getContext('2d');
new Chart(cUserCtx, {
type: 'pie',
data: {
labels: ['废纸壳', '旧衣物', '塑料瓶'],
datasets: [{
label: '回收分布',
data: [60, 25, 15],
backgroundColor: ['#28a745', '#20c997', '#6f42c1'],
hoverOffset: 4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
}
}
}
});
const cHistoryCtx = document.getElementById('cHistoryChart').getContext('2d');
new Chart(cHistoryCtx, {
type: 'bar',
data: {
labels: ['8/09', '8/10', '8/11', '8/12', '8/13', '8/14', '8/15'],
datasets: [{
label: '收入 (元)',
data: [5.2, 0, 12.5, 8.0, 0, 12.5, 4.93],
backgroundColor: '#28a745',
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
// B端图表
const bCategoryCtx = document.getElementById('bCategoryChart').getContext('2d');
new Chart(bCategoryCtx, {
type: 'doughnut',
data: {
labels: ['废纸壳', '塑料瓶', '旧衣物', '其他'],
datasets: [{
label: '品类分布',
data: [90, 45, 20.5, 3.2],
backgroundColor: ['#0d6efd', '#dc3545', '#ffc107', '#6c757d'],
hoverOffset: 4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
}
}
}
});
const bHistoryCtx = document.getElementById('bHistoryChart').getContext('2d');
new Chart(bHistoryCtx, {
type: 'line',
data: {
labels: ['8/09', '8/10', '8/11', '8/12', '8/13', '8/14', '8/15'],
datasets: [{
label: '回收总量 (kg)',
data: [120, 150, 135, 180, 165, 210, 158.7],
fill: false,
borderColor: '#0d6efd',
tension: 0.1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
</body>
</html>

1027
商业规划汇报.html Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,369 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>回报率预测计算器</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#2563eb',
secondary: '#38bdf8'
}
}
}
}
</script>
</head>
<body class="bg-gray-50 font-sans text-gray-800">
<div class="min-h-screen px-4 py-6 md:px-8 md:py-8">
<div class="max-w-6xl mx-auto bg-white/95 shadow-xl rounded-2xl p-6 md:p-8">
<header class="mb-8">
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 mb-2">回报率预测计算器</h1>
<p class="text-gray-600 text-sm md:text-base">根据《回报率预测》文档的假设提供默认值,可随场景调整实时查看财务指标。</p>
</header>
<!-- Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">月度净利润</h2>
<div id="monthlyNetProfit" class="text-2xl md:text-3xl font-bold mb-2">¥ 33.00</div>
<p class="text-xs text-blue-100">= 月毛利 - 固定运营成本</p>
</div>
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">投资回收期</h2>
<div id="paybackPeriod" class="text-2xl md:text-3xl font-bold mb-2">54.5 个月</div>
<p class="text-xs text-blue-100">= 总投资 / 月净利润</p>
</div>
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">年化 ROI</h2>
<div id="annualROI" class="text-2xl md:text-3xl font-bold mb-2">22.0%</div>
<p class="text-xs text-blue-100">= (年净利润 / 总投资) × 100%</p>
</div>
</div>
<!-- Input Sections -->
<section class="mb-8">
<h3 class="text-lg md:text-xl font-semibold text-gray-900 mb-4">核心量化假设</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">日均废纸板回收量 (公斤)</span>
<input id="dailyCardboard" type="number" min="0" step="0.1" value="20"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">日均塑料瓶回收量 (公斤)</span>
<input id="dailyPet" type="number" min="0" step="0.1" value="10"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">月计费天数 (天)</span>
<input id="daysPerMonth" type="number" min="1" step="1" value="30"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">运营站点数量 (个)</span>
<input id="siteCount" type="number" min="1" step="1" value="5"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">废纸板回收价 ¥/公斤 (给用户)</span>
<input id="buyPriceCardboard" type="number" min="0" step="0.01" value="0.8"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">废纸板出售价 ¥/公斤 (给打包站)</span>
<input id="sellPriceCardboard" type="number" min="0" step="0.01" value="1.2"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">塑料瓶回收价 ¥/公斤 (给用户)</span>
<input id="buyPricePet" type="number" min="0" step="0.01" value="1.4"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">塑料瓶出售价 ¥/公斤 (给打包站)</span>
<input id="sellPricePet" type="number" min="0" step="0.01" value="2.0"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
</div>
</section>
<section class="mb-8">
<h3 class="text-lg md:text-xl font-semibold text-gray-900 mb-4">运营及投入假设</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">场地合作分成 (占销售总收入 %)</span>
<input id="siteFeePercent" type="number" min="0" step="0.1" value="10"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">月物流清运成本 (¥)</span>
<input id="logisticsCost" type="number" min="0" step="1" value="220"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">设备维护与网络费 (¥/月)</span>
<input id="maintenanceCost" type="number" min="0" step="1" value="27"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">其他运营成本 (¥/月)</span>
<input id="otherCost" type="number" min="0" step="1" value="50"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">单站设备投入 (¥)</span>
<input id="equipmentCost" type="number" min="0" step="10" value="1500"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">部署及安装成本 (¥)</span>
<input id="deploymentCost" type="number" min="0" step="10" value="300"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
</div>
</section>
<!-- Results Section -->
<section class="space-y-6">
<h3 class="text-lg md:text-xl font-semibold text-gray-900">产出指标</h3>
<!-- 产出指标表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">指标</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">废纸板</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">塑料瓶</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">合计</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月度回收量 (公斤)</td>
<td id="monthlyCardboardKg" class="px-4 py-3 text-sm text-right text-gray-600">600.0</td>
<td id="monthlyPetKg" class="px-4 py-3 text-sm text-right text-gray-600">300.0</td>
<td id="monthlyTotalKg" class="px-4 py-3 text-sm text-right font-medium text-gray-900">900.0</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">给用户回收金 (¥)</td>
<td id="payoutCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 480.00</td>
<td id="payoutPet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 420.00</td>
<td id="payoutTotal" class="px-4 py-3 text-sm text-right font-medium text-gray-900">¥ 900.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">销售收入 (¥)</td>
<td id="saleCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 720.00</td>
<td id="salePet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 600.00</td>
<td id="saleTotal" class="px-4 py-3 text-sm text-right font-medium text-gray-900">¥ 1,320.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">毛利 (¥)</td>
<td id="grossCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 240.00</td>
<td id="grossPet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 180.00</td>
<td id="grossTotal" class="px-4 py-3 text-sm text-right font-medium text-primary">¥ 420.00</td>
</tr>
</tbody>
</table>
</div>
<!-- 成本拆解表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">成本拆解</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">金额 (¥)</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">场地合作费</td>
<td id="siteFee" class="px-4 py-3 text-sm text-right text-gray-600">¥ 90.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月物流清运成本</td>
<td id="logisticsCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 220.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">设备维护与网络费</td>
<td id="maintenanceCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 27.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">其他运营成本</td>
<td id="otherCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 50.00</td>
</tr>
<tr class="bg-gray-50">
<td class="px-4 py-3 text-sm font-semibold text-gray-900">固定成本合计</td>
<td id="fixedCostTotal" class="px-4 py-3 text-sm text-right font-semibold text-gray-900">¥ 387.00</td>
</tr>
</tbody>
</table>
</div>
<!-- 投资与回报表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">投资与回报</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">金额 / 指标</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">总投资 (Capex)</td>
<td id="totalInvestment" class="px-4 py-3 text-sm text-right text-gray-600">¥ 1,800.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月度净利润</td>
<td id="netProfitCell" class="px-4 py-3 text-sm text-right font-medium text-primary">¥ 33.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">投资回收期</td>
<td id="paybackCell" class="px-4 py-3 text-sm text-right text-gray-600">54.5 个月</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">年化投资回报率</td>
<td id="annualRoiCell" class="px-4 py-3 text-sm text-right font-medium text-green-600">22.0%</td>
</tr>
</tbody>
</table>
</div>
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<p class="text-sm text-yellow-800">
<span class="font-semibold">提示:</span>
若月度净利润≤0则投资回收期视为"尚无法回收",请通过提升日均回收量或优化成本结构来改进模型。
</p>
</div>
</section>
</div>
</div>
<script>
// 工具函数安全读取输入值若为空则返回0
function getValue(id) {
const value = parseFloat(document.getElementById(id).value);
return Number.isFinite(value) ? value : 0;
}
// 工具函数:格式化为货币展示
function formatCurrency(value) {
return `¥ ${value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}
// 工具函数:格式化数值,保留一位小数
function formatNumber(value) {
return value.toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 });
}
// 核心计算逻辑
function recalc() {
const dailyCardboard = getValue("dailyCardboard");
const dailyPet = getValue("dailyPet");
const days = getValue("daysPerMonth");
const siteCount = Math.max(getValue("siteCount"), 0);
const buyCardboard = getValue("buyPriceCardboard");
const sellCardboard = getValue("sellPriceCardboard");
const buyPet = getValue("buyPricePet");
const sellPet = getValue("sellPricePet");
const siteFeePercent = getValue("siteFeePercent") / 100;
const logisticsCost = getValue("logisticsCost");
const maintenanceCost = getValue("maintenanceCost");
const otherCost = getValue("otherCost");
const equipmentCost = getValue("equipmentCost");
const deploymentCost = getValue("deploymentCost");
const monthlyCardboardKg = dailyCardboard * days * siteCount;
const monthlyPetKg = dailyPet * days * siteCount;
const monthlyTotalKg = monthlyCardboardKg + monthlyPetKg;
const payoutCardboard = monthlyCardboardKg * buyCardboard;
const payoutPet = monthlyPetKg * buyPet;
const payoutTotal = payoutCardboard + payoutPet;
const saleCardboard = monthlyCardboardKg * sellCardboard;
const salePet = monthlyPetKg * sellPet;
const saleTotal = saleCardboard + salePet;
const grossCardboard = saleCardboard - payoutCardboard;
const grossPet = salePet - payoutPet;
const grossTotal = grossCardboard + grossPet;
const logisticsCostTotal = logisticsCost * siteCount;
const maintenanceCostTotal = maintenanceCost * siteCount;
const otherCostTotal = otherCost * siteCount;
const siteFee = saleTotal * siteFeePercent;
const fixedCostTotal = siteFee + logisticsCostTotal + maintenanceCostTotal + otherCostTotal;
const monthlyNetProfit = grossTotal - fixedCostTotal;
const totalInvestmentPerSite = equipmentCost + deploymentCost;
const totalInvestment = totalInvestmentPerSite * siteCount;
const annualNetProfit = monthlyNetProfit * 12;
const paybackMonths = monthlyNetProfit > 0 ? totalInvestment / monthlyNetProfit : Infinity;
const annualROI = monthlyNetProfit > 0 ? (annualNetProfit / totalInvestment) * 100 : 0;
// 更新表格及摘要展示
document.getElementById("monthlyCardboardKg").textContent = formatNumber(monthlyCardboardKg);
document.getElementById("monthlyPetKg").textContent = formatNumber(monthlyPetKg);
document.getElementById("monthlyTotalKg").textContent = formatNumber(monthlyTotalKg);
document.getElementById("payoutCardboard").textContent = formatCurrency(payoutCardboard);
document.getElementById("payoutPet").textContent = formatCurrency(payoutPet);
document.getElementById("payoutTotal").textContent = formatCurrency(payoutTotal);
document.getElementById("saleCardboard").textContent = formatCurrency(saleCardboard);
document.getElementById("salePet").textContent = formatCurrency(salePet);
document.getElementById("saleTotal").textContent = formatCurrency(saleTotal);
document.getElementById("grossCardboard").textContent = formatCurrency(grossCardboard);
document.getElementById("grossPet").textContent = formatCurrency(grossPet);
document.getElementById("grossTotal").textContent = formatCurrency(grossTotal);
document.getElementById("siteFee").textContent = formatCurrency(siteFee);
document.getElementById("logisticsCostCell").textContent = formatCurrency(logisticsCostTotal);
document.getElementById("maintenanceCostCell").textContent = formatCurrency(maintenanceCostTotal);
document.getElementById("otherCostCell").textContent = formatCurrency(otherCostTotal);
document.getElementById("fixedCostTotal").textContent = formatCurrency(fixedCostTotal);
document.getElementById("totalInvestment").textContent = formatCurrency(totalInvestment);
const netProfitLabel = formatCurrency(monthlyNetProfit);
document.getElementById("monthlyNetProfit").textContent = netProfitLabel;
document.getElementById("netProfitCell").textContent = netProfitLabel;
if (monthlyNetProfit > 0) {
const paybackText = `${paybackMonths.toFixed(1)} 个月`;
const annualRoiText = `${annualROI.toFixed(1)}%`;
document.getElementById("paybackPeriod").textContent = paybackText;
document.getElementById("annualROI").textContent = annualRoiText;
document.getElementById("paybackCell").textContent = paybackText;
document.getElementById("annualRoiCell").textContent = annualRoiText;
} else {
const warningText = "尚无法回收";
document.getElementById("paybackPeriod").textContent = warningText;
document.getElementById("paybackCell").textContent = warningText;
document.getElementById("annualROI").textContent = "0.0%";
document.getElementById("annualRoiCell").textContent = "0.0%";
}
}
// 监听所有输入框,实时刷新
document.querySelectorAll("input[type='number']").forEach((input) => {
input.addEventListener("input", recalc);
});
// 初始化计算一次,确保默认值正确呈现
recalc();
</script>
</body>
</html>