0%

stuff-manage

物品管理

背景

需求

ui操作

功能项竞品SNW
物品与收纳箱的关联关系$\color{green}{\checkmark}$
地点$\color{green}{\checkmark}$
物品项记录物品数$\color{green}{\checkmark}$
图片$\color{green}{\checkmark}$
订单号$\color{red}{\times}$
下单平台$\color{red}{\times}$
价格$\color{green}{\checkmark}$
物品尺寸$\color{red}{\times}$
备注$\color{green}{\checkmark}$
支持折叠子物品折叠展示
与打印机联动$\color{green}{\checkmark}$
只能和特定的联动,
那个打印机不是我需要的
与chatgpt联动$\color{red}{\times}$
支持位切面标记
支持docker部署$\color{red}{\times}$
数据私有化云存储$\color{red}{\times}$

模块

  • P0 生成二维码/一维码
  • P0 扫描两件物品绑定关系
  • P0 页面查询
  • P0 通过 nfc/二维码 自动上报物品位置
  • 通过语音查询物品在哪
  • 通过喇叭告知物品在哪
  • 通过扫描二维码消耗物品
  • 通过扫描二维码增加物品
  • 扫描二维码展示东西
  • 短信通知
  • 微信公众号通知
  • 喇叭通知

设计方案

物品的生命周期

  • 创建,购买、计划购买
  • 使用,创建完成即流转到使用态
  • 销毁

物品的流动状态

静态物体

动态物体

  • 暂态,所处的位置不是
  • 漂浮态,既不是暂态也不是固定态
  • 固定态,

唯一标识生成

需要考虑足够条形码的印刷,所以物品id是需要支持变长的。

条形码使用code128标准,支持的设备多,是比较通用的。买的扫描枪、标签打印机都支持

技术选型

架构

Client(手机读取nfc标签)-Browser-Server

主要的交互是web。

服务器性能预估

  • QPS < 10
  • 延迟:
  • 服务器:1c2g

cache

local memory

持久化存储

mysql

对象存储

使用minio做对象存储服务

python

orm

使用sqlalchemy做orm框架。

go

做着玩?

表结构

经度纬度的精度,6位是0.1米,所以15位足够了参考文献

代码详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| a_number_item | CREATE TABLE `a_number_item` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`item_id` int NOT NULL COMMENT '用来生成编码',
`item_code` varchar(128) NOT NULL COMMENT '编码',
`name` varchar(100) NOT NULL COMMENT '物品的名称',
`location` varchar(100) DEFAULT NULL COMMENT '物品放置的位置',
`longitude` varchar(15) DEFAULT NULL COMMENT '经度',
`latitude` varchar(15) DEFAULT NULL COMMENT '纬度',
`init_num` int NOT NULL COMMENT '物品数量的初始数量',
`init_price` float DEFAULT NULL COMMENT '物品的初始总价',
`num` int DEFAULT NULL COMMENT '物品数量的现存数量',
`unit_price` float DEFAULT NULL COMMENT '物品的单价',
`picture` varchar(1024) DEFAULT NULL COMMENT 'oss的url',
`order_id` varchar(512) DEFAULT NULL COMMENT '订单编号',
`order_platform` varchar(512) DEFAULT NULL COMMENT '下单平台',
`tracking_number` varchar(512) DEFAULT NULL COMMENT '快递单号',
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_order_platform` (`order_platform`),
KEY `idx_item_code` (`item_code`),
KEY `idx_item_id` (`item_id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3 |
  • 指定utf8mb4
  • 为什么索引是key
  • 要有一个标签能够支持记录今天有没有换水
  • 物品表要有一个状态的字段,已上报

条形码

导航app跳转

<a href="androidamap://navi?sourceApplication=appname&amp;poiname=fangheng&amp;lat=36.547901&amp;lon=104.258354&amp;dev=1&amp;style=2">导航</a>

网页跳转高德地图app,参考文献

TODO

  • 增加参数校验

bug

去掉文字font size=0会报错

代码详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Traceback (most recent call last):
File "D:\Anaconda3\lib\site-packages\flask\app.py", line 867, in full_dispatch_request
rv = self.dispatch_request()
File "D:\Anaconda3\lib\site-packages\flask\app.py", line 852, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "F:\stuff-manage\api.py", line 80, in generate_barcode
return response.build_success_response({'barcode': encoder.generate_bar_code(barcode_value)})
File "F:\stuff-manage\service.py", line 104, in generate_bar_code
barcode_image.write(barcode_io, options=options)
File "D:\Anaconda3\lib\site-packages\barcode\base.py", line 80, in write
output = self.render(options, text)
File "D:\Anaconda3\lib\site-packages\barcode\codex.py", line 255, in render
return super().render(options, text)
File "D:\Anaconda3\lib\site-packages\barcode\base.py", line 100, in render
return self.writer.render(code)
File "D:\Anaconda3\lib\site-packages\barcode\writer.py", line 269, in render
self._callbacks["paint_text"](xpos, ypos)
File "D:\Anaconda3\lib\site-packages\barcode\writer.py", line 440, in _paint_text
font = ImageFont.truetype(self.font_path, font_size)
File "D:\Anaconda3\lib\site-packages\PIL\ImageFont.py", line 791, in truetype
return freetype(font)
File "D:\Anaconda3\lib\site-packages\PIL\ImageFont.py", line 788, in freetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File "D:\Anaconda3\lib\site-packages\PIL\ImageFont.py", line 226, in __init__
self.font = core.getfont(
OSError: invalid ppem value