Compare commits
2 Commits
feba423b16
...
8d228527d0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d228527d0 | ||
|
|
e3a645d519 |
19
.kilocode/mcp.json
Normal file
19
.kilocode/mcp.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
.promptx/resource/role/dev-manager/dev-manager.role.md
Normal file
44
.promptx/resource/role/dev-manager/dev-manager.role.md
Normal 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>
|
||||||
@@ -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>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<knowledge>
|
||||||
|
## 技术规格清单
|
||||||
|
- **页面尺寸**: 单个页面尺寸为 375x812px,带有描边,模拟手机边框。
|
||||||
|
- **图标**: 引用在线矢量图标库内的图标 (任何图标都不要带有背景色块、底板、外框)。
|
||||||
|
- **图片**: 使用开源图片网站链接的形式引入 (例如: Unsplash, Pexels)。
|
||||||
|
- **样式**: 必须引入 Tailwind CSS CDN 来完成。
|
||||||
|
- **显示**:
|
||||||
|
- 不要显示状态栏以及时间、信号等信息。
|
||||||
|
- 不要显示非移动端元素,如滚动条。
|
||||||
|
- **文字**: 所有文字只可以使用黑色或白色。
|
||||||
|
</knowledge>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<role>
|
||||||
|
<personality>
|
||||||
|
# 角色:资深原型设计师 & 前端开发工程师
|
||||||
|
|
||||||
|
我是一位在设计与前端开发领域拥有丰富经验的专家,致力于在优雅的极简主义美学与强大的功能性之间找到完美的平衡点。
|
||||||
|
|
||||||
|
@!thought://design-thinking
|
||||||
|
</personality>
|
||||||
|
<principle>
|
||||||
|
@!execution://design-process
|
||||||
|
</principle>
|
||||||
|
<knowledge>
|
||||||
|
@!knowledge://design-specs
|
||||||
|
</knowledge>
|
||||||
|
</role>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<thought>
|
||||||
|
<exploration>
|
||||||
|
## 设计风格探索
|
||||||
|
- **美学核心**: 优雅的极简主义美学与功能的完美平衡。
|
||||||
|
- **色彩策略**: 清新柔和的渐变配色与品牌色系浑然一体,强调色根据APP类型灵活选择。
|
||||||
|
- **空间感**: 恰到好处的留白设计,营造轻盈通透的沉浸式体验。
|
||||||
|
- **信息架构**: 通过微妙的阴影过渡与模块化卡片布局,呈现清晰的信息层级,引导用户视线自然聚焦核心功能。
|
||||||
|
- **细节打磨**: 精心打磨的圆角、细腻的微交互、舒适的视觉比例,共同提升产品质感。
|
||||||
|
</exploration>
|
||||||
|
<reasoning>
|
||||||
|
## 设计理念推理
|
||||||
|
- 极简不是简单,而是为了突出核心功能,减少用户认知负荷。
|
||||||
|
- 色彩和渐变服务于品牌表达和用户情绪引导。
|
||||||
|
- 留白和布局是构建呼吸感和秩序感的关键。
|
||||||
|
- 细节决定体验,微交互能创造情感连接。
|
||||||
|
</reasoning>
|
||||||
|
<plan>
|
||||||
|
## 设计执行计划
|
||||||
|
1. **理解需求**: 深入理解产品经理的功能设计和信息架构。
|
||||||
|
2. **确立风格**: 根据产品类型(如旅游攻略)确定主色和强调色。
|
||||||
|
3. **布局优先**: 先进行模块化卡片布局和信息层级规划。
|
||||||
|
4. **视觉细化**: 填充色彩、图片、图标,并调整间距、圆角等细节。
|
||||||
|
5. **交互点缀**: 在关键操作上增加细腻的微交互效果。
|
||||||
|
</plan>
|
||||||
|
</thought>
|
||||||
45
.superdesign/README.md
Normal file
45
.superdesign/README.md
Normal 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设计师可进行最终的视觉细节敲定和切图交付。
|
||||||
|
- **开发对接**: 前端开发工程师可基于此原型作为参考,开始组件化开发。
|
||||||
351
.superdesign/b_end_prototype_v1.1.html
Normal file
351
.superdesign/b_end_prototype_v1.1.html
Normal 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>
|
||||||
43
.superdesign/b_end_theme_v1.1.css
Normal file
43
.superdesign/b_end_theme_v1.1.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
<div class="flex items-center">
|
||||||
<p class="font-bold text-lg text-gray-800">幸福社区回收站</p>
|
<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">
|
||||||
查看更多
|
查看更多
|
||||||
@@ -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);
|
||||||
|
|
||||||
/* 破坏性操作 - 柔和红色 */
|
/* 破坏性操作 - 柔和红色 */
|
||||||
303
.superdesign/design_iterations/b_side_prototype_1.html
Normal file
303
.superdesign/design_iterations/b_side_prototype_1.html
Normal 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>
|
||||||
358
.superdesign/design_iterations/c_side_prototype_1.html
Normal file
358
.superdesign/design_iterations/c_side_prototype_1.html
Normal 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>
|
||||||
45
.superdesign/design_iterations/green_neighbor_theme_b.css
Normal file
45
.superdesign/design_iterations/green_neighbor_theme_b.css
Normal 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);
|
||||||
|
}
|
||||||
44
.superdesign/design_iterations/green_neighbor_theme_c.css
Normal file
44
.superdesign/design_iterations/green_neighbor_theme_c.css
Normal 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);
|
||||||
|
}
|
||||||
96
.superdesign/prototype_optimization_plan.md
Normal file
96
.superdesign/prototype_optimization_plan.md
Normal 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`)的评估,并严格对标PRD(V2.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. **最终评审**: 对更新后的原型进行最终确认,确保所有优化点均已落实。
|
||||||
@@ -10,6 +10,15 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 0. 文档追踪
|
||||||
|
|
||||||
|
| **评审状态** | **评审人** | **评审日期** | **备注** |
|
||||||
|
| :--- | :--- | :--- | :--- |
|
||||||
|
| 初稿 | Sean | 2025-08-08 | - |
|
||||||
|
| 技术评审 | (待定) | (待定) | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 1. 项目概述
|
## 1. 项目概述
|
||||||
|
|
||||||
### 1.1 项目背景与核心矛盾
|
### 1.1 项目背景与核心矛盾
|
||||||
@@ -87,6 +96,9 @@ graph TD
|
|||||||
- **团队风险**:
|
- **团队风险**:
|
||||||
- **风险点**: 团队成员对 `NestJS` 或 `uni-app` 的熟练度可能不一。
|
- **风险点**: 团队成员对 `NestJS` 或 `uni-app` 的熟练度可能不一。
|
||||||
- **应对策略**: 在项目启动前安排1-2天的技术预研(Spike),统一代码规范和最佳实践。
|
- **应对策略**: 在项目启动前安排1-2天的技术预研(Spike),统一代码规范和最佳实践。
|
||||||
|
- **需求风险**:
|
||||||
|
- **风险点**: MVP开发期间出现重大需求变更,影响核心交付范围。
|
||||||
|
- **应对策略**: 建立需求变更控制流程。所有需求变更需经由产品、项目、研发三方共同评估影响后,再决定是否纳入当前版本。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -211,13 +223,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 +237,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 / 钉钉
|
||||||
|
|||||||
39
01_设计/后台功能模块.md
Normal file
39
01_设计/后台功能模块.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# 后台管理系统功能模块设计 V1.0
|
||||||
|
|
||||||
|
> **设计者**: dev-manager
|
||||||
|
> **依据文档**:
|
||||||
|
> - 《废品回收小程序产品需求文档 (PRD) V2.0》
|
||||||
|
> - 《废品回收小程序 - 初步设计文档 V1.0》
|
||||||
|
> - 《用户故事 - 绿邻回收项目》
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
本设计旨在为“绿邻回收”项目提供一个全面、可扩展的后台管理系统功能模块规划。后台的核心定位是**公司的“大脑”**,为运营、管理、财务和技术团队提供数据支持和业务管控工具。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 功能模块详细规划
|
||||||
|
|
||||||
|
| 一级菜单 | 二级菜单 (页面) | 功能模块 | 细节描述 | 对应PRD/用户故事 |
|
||||||
|
| :--- | :--- | :--- | :--- | :--- |
|
||||||
|
| **数据中心** | **运营驾驶舱** | 核心KPI展示 | - 今日交易总额、总单数、总重量<br>- 活跃用户数 (DAU/MAU)<br>- 新增用户数 | PRD 6.1.1 |
|
||||||
|
| | | 业务数据图表 | - 各品类回收趋势图 (近7/30天)<br>- 各小站回收量动态排名<br>- 用户活跃时段分布图 | PRD 6.1.1 |
|
||||||
|
| **运营管理** | **小站管理** | 小站列表 | - 显示小站ID、名称、地址、负责人、联系电话、状态(营业/休息中/已关闭)<br>- 支持按名称、地址、负责人搜索<br>- 支持按状态筛选 | PRD 6.1.3 |
|
||||||
|
| | | 小站详情/编辑 | - **基本信息**:查看和修改名称、地址、地理位置(地图选点)、负责人、营业时间<br>- **员工管理**:关联/解绑小站员工账号<br>- **服务状态**:手动切换小站营业/休息状态<br>- **交易数据**:查看该小站的历史交易流水 | PRD 6.1.3, 用户故事 5.2.3 |
|
||||||
|
| | | 入驻审核 | - 查看待审核的小站申请列表<br>- 点击审核,可查看提交资料,并执行“通过”或“驳回”操作 | PRD 6.1.3 |
|
||||||
|
| | **品类价格管理** | 回收品类列表 | - 显示品类ID、名称、单位(如kg)、状态(启用/停用)<br>- 支持新增、编辑、停用品类 | PRD 6.1.4, 用户故事 6.3.2 |
|
||||||
|
| | | 价格策略配置 | - 选择一个或多个小站,为指定品类设置回收单价<br>- 支持批量调价和设置价格生效时间<br>- 可查看历史价格调整记录 | PRD 6.1.4, 用户故事 5.2.2 |
|
||||||
|
| | | 物流损耗配置 | - 为不同品类设置全局或区域性的运输损耗比例(如:纸壳损耗2%) | PRD 6.1.4, 用户故事 6.3.3 |
|
||||||
|
| **交易管理** | **订单流水** | 交易列表 | - 列表展示所有交易记录:交易ID、用户昵称、回收小站、总金额、创建时间<br>- 支持按交易ID、用户、小站、时间范围进行复合查询 | PRD 6.1.5, 初步设计 2. MVP |
|
||||||
|
| | | 订单详情 | - 查看单笔交易的详细信息,包括所有回收物品的品类、重量、单价、金额 | PRD 6.1.5 |
|
||||||
|
| **用户管理** | **C端用户列表** | 用户信息查询 | - 列表展示所有C端用户信息:用户ID、微信昵称、头像、账户余额、注册时间<br>- 支持按用户ID、昵称查询 | PRD 6.1.2 |
|
||||||
|
| | | 用户详情 | - 查看用户的基本信息、账户余额、完整的交易记录列表 | PRD 6.1.2 |
|
||||||
|
| **物流管理** | **揽收任务** | 任务列表 | - 查看所有物流任务:任务ID、状态(待揽收/运输中/已入库)、司机、关联小站、创建时间<br>- 支持按状态、司机、小站筛选 | PRD 6.1.6, V1.1规划 |
|
||||||
|
| | | 任务详情 | - 查看任务包含的所有待交接的品类和重量信息,以及实际交接的记录 | PRD 6.1.6, V1.1规划 |
|
||||||
|
| | | 司机管理 | - 管理物流司机信息(姓名、联系方式、关联车辆) | PRD 6.1.6, V1.1规划 |
|
||||||
|
| **财务管理** | **结算管理** | 对账单 | - 生成与小站、物流司机的周期性结算账单<br>- 账单需清晰列出所有明细,并扣除平台服务费/损耗 | PRD 6.1.7, V1.2规划 |
|
||||||
|
| | | 提现审批 | - (若C端提现需人工审核)处理C端用户的提现申请 | PRD 3.1.3 (V1.1) |
|
||||||
|
| | | 账单导出 | - 支持将结算账单导出为Excel格式 | PRD 6.1.7 |
|
||||||
|
| **系统管理** | **角色与权限** | 角色管理 | - 创建、编辑后台角色(如:运营、财务、客服)<br>- 为角色分配不同的菜单和操作权限(增删改查) | PRD 6.1.8 |
|
||||||
|
| | | 账号管理 | - 创建后台操作员账号,并为其分配角色 | PRD 6.1.8 |
|
||||||
|
| | **系统监控** | 登录日志 | - 查看所有后台账号的登录历史记录,包括登录IP、时间、设备信息 | PRD 6.1.8 |
|
||||||
|
| | | 报警中心 | - 集中展示系统产生的各类业务异常报警(库存预警、交易异常、API错误)<br>- 支持查看报警详情、标记处理状态、记录处理过程 | PRD 6.1.9, 用户故事 6.3.4 |
|
||||||
@@ -91,7 +91,7 @@ graph TD
|
|||||||
#### 3.1.2 首页 (核心页面)
|
#### 3.1.2 首页 (核心页面)
|
||||||
- **界面元素**:
|
- **界面元素**:
|
||||||
1. **【我的卖品码】**: 页面最中心、最大的按钮,点击后全屏显示个人专属二维码,并调高屏幕亮度。
|
1. **【我的卖品码】**: 页面最中心、最大的按钮,点击后全屏显示个人专属二维码,并调高屏幕亮度。
|
||||||
2. **【附近小站】**: 列表或地图形式,展示附近合作小站的位置、营业时间、联系电话。
|
2. **【附近小站】**: 列表或地图形式,展示附近合作小站的位置、**实时营业状态(营业中/休息中)、距离我有多远**、联系电话。
|
||||||
3. **【今日回收价】**: 醒目位置展示主要品类(纸壳、塑料瓶等)的单价(元/斤)。
|
3. **【今日回收价】**: 醒目位置展示主要品类(纸壳、塑料瓶等)的单价(元/斤)。
|
||||||
|
|
||||||
#### 3.1.3 “我的”页面
|
#### 3.1.3 “我的”页面
|
||||||
@@ -121,8 +121,8 @@ graph TD
|
|||||||
- **界面元素**:
|
- **界面元素**:
|
||||||
1. **【开始回收】**: 核心操作按钮,点击进入扫码回收流程。
|
1. **【开始回收】**: 核心操作按钮,点击进入扫码回收流程。
|
||||||
2. **【今日汇总】**: 数据卡片,展示当日回收总单数、总重量、总金额。
|
2. **【今日汇总】**: 数据卡片,展示当日回收总单数、总重量、总金额。
|
||||||
3. **【库存盘点】**: 查看当前各类废品的库存重量。
|
3. **【库存盘点】**: 查看当前各类废品的库存重量。**当库存达到预警阈值时,系统应有明显提示。**
|
||||||
4. **【向上游交接】**: 生成出库单,打印或出示出库二维码,等待物流端揽收。
|
4. **【向上游交接】**: 生成出库单,**一键通知物流团队上门揽收**,并出示出库二维码。
|
||||||
|
|
||||||
#### 4.1.3 回收流程 (核心业务)
|
#### 4.1.3 回收流程 (核心业务)
|
||||||
1. **扫码识客**: 点击“开始回收”,启动扫码器,扫描C端用户的“卖品码”。成功后显示用户昵称。
|
1. **扫码识客**: 点击“开始回收”,启动扫码器,扫描C端用户的“卖品码”。成功后显示用户昵称。
|
||||||
@@ -158,23 +158,43 @@ graph TD
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. 统一管理后台 (Web端)
|
## 6. 大仓管理端 (Web/PC)
|
||||||
|
|
||||||
|
**核心定位:业务流转的仓储枢纽,数据准确性的最终保障。**
|
||||||
|
|
||||||
|
### 6.1 功能模块详述
|
||||||
|
|
||||||
|
#### 6.1.1 扫码确认入库
|
||||||
|
- **需求**: 司机运抵大仓后,仓管员扫描司机任务单(或出库单)上的二维码。
|
||||||
|
- **流程**: 系统自动带出司机、来源小站、货品品类及重量等信息。仓管员核对实物后确认,完成入库操作。库存数据自动更新。
|
||||||
|
|
||||||
|
#### 6.1.2 实时库存监控
|
||||||
|
- **需求**: 在PC端或数据大屏上,以可视化图表展示所有品类的实时库存量、库存周转天数、存放位置等。
|
||||||
|
- **目标**: 为仓储规划和销售决策提供数据支持。
|
||||||
|
|
||||||
|
#### 6.1.3 出库管理
|
||||||
|
- **需求**: 当与下游回收商(如打包站)达成交易后,可在系统中选择品类和重量,一键生成标准化的出库单。
|
||||||
|
- **凭证**: 出库单可打印,作为与下游结算和备货的依据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 统一管理后台 (Web端)
|
||||||
|
|
||||||
**核心定位:公司的“大脑”,驱动业务运转。**
|
**核心定位:公司的“大脑”,驱动业务运转。**
|
||||||
|
|
||||||
### 6.1 功能模块详述
|
### 6.1 功能模块详述
|
||||||
|
|
||||||
#### 6.1.1 Dashboard 数据看板
|
#### 6.1.1 Dashboard 数据看板
|
||||||
- **需求**: 实时展示核心KPI,如:今日交易额、总用户数、活跃小站数、各品类回收量趋势图等。
|
- **需求**: 实时展示核心KPI,如:今日交易额、活跃用户数、**各小站回收量排名**、各品类回收趋势图等,形成数据驾驶舱。
|
||||||
|
|
||||||
#### 6.1.2 用户管理
|
#### 6.1.2 用户管理
|
||||||
- **需求**: 查询C端用户信息、交易记录、账户状态。
|
- **需求**: 查询C端用户信息、交易记录、账户状态。
|
||||||
|
|
||||||
#### 6.1.3 小站管理
|
#### 6.1.3 小站管理
|
||||||
- **需求**: 小站的入驻审核、信息管理、地理位置分布图、服务状态(营业/休息)管理。
|
- **需求**: 小站的入驻审核、信息管理(**名称、地址、地理位置、负责人、营业时间**)、地理位置分布图、服务状态(营业/休息)管理。
|
||||||
|
|
||||||
#### 6.1.4 品类与价格管理
|
#### 6.1.4 品类与价格管理
|
||||||
- **需求**: 动态添加/修改回收品类,实时调整各品类在不同区域的回收单价。
|
- **需求**: 动态添加/修改/停用回收品类,实时调整各品类在不同区域或站点的回收单价。**支持设置不同品类的物流损耗参数。**
|
||||||
|
|
||||||
#### 6.1.5 订单与库存管理
|
#### 6.1.5 订单与库存管理
|
||||||
- **需求**: 查询全平台所有交易流水。实时监控各小站、各打包站的库存情况。
|
- **需求**: 查询全平台所有交易流水。实时监控各小站、各打包站的库存情况。
|
||||||
@@ -186,28 +206,39 @@ graph TD
|
|||||||
- **需求**: 管理与小站、物流司机的结算周期和账单,支持账单导出。
|
- **需求**: 管理与小站、物流司机的结算周期和账单,支持账单导出。
|
||||||
|
|
||||||
#### 6.1.8 系统管理
|
#### 6.1.8 系统管理
|
||||||
- **需求**: 后台操作员的角色与权限管理。
|
- **需求**: 后台操作员的角色与权限管理。**对异常登录行为进行告警**。
|
||||||
|
|
||||||
|
#### 6.1.9 报警中心
|
||||||
|
- **需求**: 集中查看和处理系统产生的各类业务异常报警(如库存异常、交易异常、物流延误),记录处理过程与结果,并支持上报给相关负责人。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. 非功能性需求
|
## 8. 非功能性需求
|
||||||
- **性能**: 扫码响应时间 < 1秒。页面加载时间 < 2秒。
|
- **性能**: 扫码响应时间 < 1秒。页面加载时间 < 2秒。系统核心接口可用性 > 99.9%。
|
||||||
- **易用性**: C端和B端界面必须严格遵循“适老化”设计,大字体、高对比度、操作简单。
|
- **易用性**: C端和B端界面必须严格遵循“适老化”设计,大字体、高对比度、操作简单。
|
||||||
- **安全性**: 交易、支付、个人信息等敏感数据必须加密传输和存储。
|
- **安全性**: 交易、支付、个人信息等敏感数据必须加密传输和存储。需有完善的权限管理体系,防止未授权访问。
|
||||||
- **可扩展性**: 架构设计应支持未来新品类、新城市、新业务模式(如积分商城、上门回收)的快速扩展。
|
- **可扩展性**: 架构设计应支持未来新品类、新城市、新业务模式(如积分商城、上门回收)的快速扩展。
|
||||||
|
- **可观测性 (Observability)**:
|
||||||
|
- **监控与告警**: 对服务器、数据库、核心接口等进行实时监控,并在出现异常(如CPU过高、响应超时)时,通过短信/邮件/企业微信发出告警。
|
||||||
|
- **日志管理**: 建立集中化的日志平台,支持按关键字、时间、服务模块快速检索日志,以便于高效排查问题。
|
||||||
|
- **可维护性**:
|
||||||
|
- **版本更新与回滚**: 发布流程应支持一键回滚到上一个稳定版本。
|
||||||
|
- **容量规划**: 定期输出系统资源使用趋势报告,为扩容提供决策依据。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. 版本迭代规划 (Roadmap)
|
## 9. 版本迭代规划 (Roadmap)
|
||||||
- **V1.0 (MVP)**:
|
- **V1.0 (MVP)**:
|
||||||
- 核心功能: C端 + B端核心回收流程、管理后台基础框架(品类价格、订单查看)。
|
- 核心功能: C端 + B端核心回收流程、管理后台基础框架(品类价格、订单查看)。
|
||||||
- 目标: 跑通商业模式闭环。
|
- 目标: 跑通“居民->小站”核心商业模式闭环。
|
||||||
- **V1.1**:
|
- **V1.1**:
|
||||||
- 新增功能: 物流端H5、后台物流管理、后台小站管理、C端提现功能。
|
- 新增功能: 物流端H5、后台物流管理、后台小站管理、C端提现功能。
|
||||||
- 目标: 引入物流角色,实现规范化清运。
|
- 目标: 引入物流角色,实现“小站->大仓”规范化清运。
|
||||||
- **V1.2**:
|
- **V1.2**:
|
||||||
- 新增功能: C端积分商城、后台财务结算模块、数据报表优化。
|
- 新增功能: 大仓管理模块、后台财务结算模块、数据报表优化。
|
||||||
- 目标: 探索增值服务,提升运营效率。
|
- 目标: 完善全链路管理,提升运营和财务效率。
|
||||||
|
- **V1.3**:
|
||||||
|
- 新增功能: C端积分商城、精细化运营工具(如用户分层、活动配置)。
|
||||||
|
- 目标: 探索增值服务,提升用户粘性。
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
**文档结束**
|
|
||||||
|
|||||||
386
UI.html
Normal file
386
UI.html
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
<!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-code-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-white p-4 rounded-lg shadow mb-4">
|
||||||
|
<h3 class="font-bold text-lg mb-2 flex items-center"><i class="ri-price-tag-3-line mr-2 text-green-500"></i>今日回收价</h3>
|
||||||
|
<div class="space-y-2 text-lg">
|
||||||
|
<div class="flex justify-between"><span>废纸壳</span><span class="font-bold text-green-600">0.85 元/斤</span></div>
|
||||||
|
<div class="flex justify-between"><span>塑料瓶</span><span class="font-bold text-green-600">0.10 元/个</span></div>
|
||||||
|
<div class="flex justify-between"><span>旧衣物</span><span class="font-bold text-green-600">0.50 元/斤</span></div>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<!-- B端 分组 -->
|
||||||
|
<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">B端 (小站端)</h1>
|
||||||
|
<div class="flex flex-wrap justify-center gap-5">
|
||||||
|
<!-- B端 - 工作台 -->
|
||||||
|
<div class="mobile-frame">
|
||||||
|
<div class="screen p-4">
|
||||||
|
<div class="flex justify-between items-center mb-6">
|
||||||
|
<div><h2 class="text-2xl font-bold">李老板</h2><p class="text-gray-500">社区便民超市站</p></div>
|
||||||
|
<i class="ri-logout-box-r-line text-2xl text-gray-500"></i>
|
||||||
|
</div>
|
||||||
|
<div class="text-center my-8">
|
||||||
|
<button class="bg-blue-600 text-white rounded-lg shadow-lg w-full py-6"><i class="ri-scan-2-line text-6xl"></i><span class="block text-2xl font-bold mt-2">开始回收</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white p-4 rounded-lg shadow mb-4">
|
||||||
|
<h3 class="font-bold text-lg mb-2 flex items-center"><i class="ri-price-tag-3-line mr-2 text-blue-600"></i>今日回收价</h3>
|
||||||
|
<div class="space-y-2 text-lg">
|
||||||
|
<div class="flex justify-between"><span>废纸壳</span><span class="font-bold text-green-600">0.85 元/斤</span></div>
|
||||||
|
<div class="flex justify-between"><span>塑料瓶</span><span class="font-bold text-green-600">0.10 元/个</span></div>
|
||||||
|
<div class="flex justify-between"><span>旧衣物</span><span class="font-bold text-green-600">0.50 元/斤</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white p-4 rounded-lg shadow 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 text-blue-600">¥245.50</p><p class="text-sm text-gray-500">总金额</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white p-4 rounded-lg shadow">
|
||||||
|
<div class="flex justify-between items-center mb-3"><h3 class="font-bold text-lg">库存盘点</h3><span class="text-red-500 font-semibold flex items-center"><i class="ri-error-warning-fill mr-1"></i>库存预警</span></div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex justify-between items-center"><span>废纸壳</span><div class="w-1/2 bg-gray-200 rounded-full h-2.5"><div class="bg-red-500 h-2.5 rounded-full" style="width: 90%"></div></div><span class="font-bold">90 kg</span></div>
|
||||||
|
<div class="flex justify-between items-center"><span>塑料瓶</span><div class="w-1/2 bg-gray-200 rounded-full h-2.5"><div class="bg-blue-600 h-2.5 rounded-full" style="width: 45%"></div></div><span class="font-bold">45 kg</span></div>
|
||||||
|
</div>
|
||||||
|
<button class="mt-4 w-full bg-blue-100 text-blue-700 font-bold py-3 rounded-lg"><i class="ri-truck-line mr-2"></i>一键通知物流交接</button>
|
||||||
|
</div>
|
||||||
|
<!-- B端图表 -->
|
||||||
|
<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-box-line mr-2 text-blue-600"></i>今日品类分布 (按重量)</h3>
|
||||||
|
<canvas id="bCategoryChart" 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-box-line mr-2 text-blue-600"></i>近7日回收量 (kg)</h3>
|
||||||
|
<canvas id="bHistoryChart" height="180"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom-nav">
|
||||||
|
<div class="nav-item active"><i class="ri-dashboard-fill text-2xl"></i><span>工作台</span></div>
|
||||||
|
<div class="nav-item"><i class="ri-bill-fill text-2xl"></i><span>账单</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- B端 - 回收流程 -->
|
||||||
|
<div class="mobile-frame">
|
||||||
|
<div class="screen p-4 flex flex-col">
|
||||||
|
<div class="flex items-center mb-4"><i class="ri-arrow-left-s-line text-2xl mr-2"></i><h1 class="font-bold text-xl flex-grow">回收流程</h1></div>
|
||||||
|
<div class="text-center bg-gray-100 p-4 rounded-lg mb-4"><p>已识别用户</p><p class="font-bold text-2xl">王大妈</p></div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="font-bold text-lg">1. 选择品类</label>
|
||||||
|
<div class="grid grid-cols-3 gap-3 mt-2">
|
||||||
|
<button class="bg-blue-600 text-white p-4 rounded-lg font-bold">纸壳</button>
|
||||||
|
<button class="bg-gray-200 p-4 rounded-lg font-bold">塑料瓶</button>
|
||||||
|
<button class="bg-gray-200 p-4 rounded-lg font-bold">旧衣物</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="font-bold text-lg">2. 输入重量 (斤)</label>
|
||||||
|
<input type="number" value="5.8" class="text-center text-4xl font-bold w-full mt-2 p-4 border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:outline-none">
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow"></div>
|
||||||
|
<div class="text-center p-4 bg-white border-t-2">
|
||||||
|
<p class="text-gray-600">合计金额</p><p class="text-4xl font-bold text-blue-600 mb-4">¥4.93</p>
|
||||||
|
<button class="w-full bg-blue-600 text-white font-bold py-4 rounded-lg text-xl flex items-center justify-center"><i class="ri-volume-up-fill mr-2 text-2xl"></i><span>确认并语音播报</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- B端 - 账单 -->
|
||||||
|
<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">
|
||||||
|
<div class="text-center mb-4"><p class="text-gray-500">2025年8月 总收入</p><p class="text-4xl font-bold text-blue-600">¥ 3,450.70</p></div>
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="bg-white p-3 rounded-lg shadow-sm flex justify-between items-center">
|
||||||
|
<div><p class="font-bold">8月15日 (今日)</p><p class="text-sm text-gray-500">共 32 笔</p></div>
|
||||||
|
<span class="text-xl font-bold">¥245.50</span>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white p-3 rounded-lg shadow-sm flex justify-between items-center">
|
||||||
|
<div><p class="font-bold">8月14日</p><p class="text-sm text-gray-500">共 45 笔</p></div>
|
||||||
|
<span class="text-xl font-bold">¥312.80</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- B端 - 物流交接单 -->
|
||||||
|
<div class="mobile-frame">
|
||||||
|
<div class="screen p-4 flex flex-col items-center">
|
||||||
|
<h1 class="font-bold text-2xl mt-4 mb-2">出库交接单</h1>
|
||||||
|
<p class="text-gray-500 mb-6">请向物流司机出示此码</p>
|
||||||
|
<div class="bg-white p-4 rounded-lg shadow-lg"><img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=STATION_001_OUT_20250815" alt="QR Code"></div>
|
||||||
|
<div class="w-full mt-6 p-4 bg-white rounded-lg shadow-sm">
|
||||||
|
<h3 class="font-bold text-lg mb-2">待交接物品</h3>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex justify-between"><span>废纸壳</span><span class="font-bold">90 kg</span></div>
|
||||||
|
<div class="flex justify-between"><span>塑料瓶</span><span class="font-bold">45 kg</span></div>
|
||||||
|
</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>
|
||||||
Reference in New Issue
Block a user