feat(client): 扫码出库(扫码枪扫二维码,明细自动 +1)
出库单新建页桌面端加「扫码枪扫码」框:扫商品二维码 URL → 取其中 的 ?code= → 本地整仓索引精确命中 → 明细自动新增/累加数量(每扫 +1)。本地未命中(大仓库存超前端加载上限 1000)时走服务端按编码 精确查兜底,复用现有库存搜索接口,无需新后端接口。 - 前端 stock_out_form_screen:扫码框 + _onScan + _codeIndex + parseScanCode + 服务端兜底 + 300ms 防抖 + 提示音;桌面专属, 窄屏隐藏。 - 后端 product.go:二维码 URL 路径 /app/product/ → /product/ 统一到 SSR 公开页路由。 - 原型 stock-in.js/html:出库明细头同步加扫码框(design-first)。 - 测试 parse_scan_code_test(8 例)+ 出库表单桌面 golden 重生成。 - 设计/实现计划文档 docs/design/scan-stock-out-*。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 130 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 128 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 130 KiB |
@@ -0,0 +1,49 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:jiu_client/screens/stock_out/stock_out_form_screen.dart';
|
||||
|
||||
/// 扫码出库:从扫码枪内容里取商品编码。
|
||||
/// 扫码枪扫二维码得到 URL(形如 …/product/{public_id}?code={code})或纯编码。
|
||||
void main() {
|
||||
group('parseScanCode', () {
|
||||
test('新路径 /product/xxx?code=', () {
|
||||
expect(
|
||||
parseScanCode('https://jiu.51yanmei.com/product/abc-123?code=P1001'),
|
||||
'P1001',
|
||||
);
|
||||
});
|
||||
|
||||
test('旧路径 /app/product/xxx?code=(兼容)', () {
|
||||
expect(
|
||||
parseScanCode('https://jiu.51yanmei.com/app/product/abc?code=P1002'),
|
||||
'P1002',
|
||||
);
|
||||
});
|
||||
|
||||
test('纯编码直接扫(无 URL)', () {
|
||||
expect(parseScanCode('P1003'), 'P1003');
|
||||
});
|
||||
|
||||
test('前后空白被去除', () {
|
||||
expect(parseScanCode(' P1004 '), 'P1004');
|
||||
});
|
||||
|
||||
test('code 带 URL 编码字符被解码', () {
|
||||
expect(parseScanCode('https://x/product/y?code=P%2D9'), 'P-9');
|
||||
});
|
||||
|
||||
test('多参数里的 code 也能取到', () {
|
||||
expect(parseScanCode('https://x/product/y?foo=1&code=P1005&bar=2'), 'P1005');
|
||||
});
|
||||
|
||||
test('空串返回空', () {
|
||||
expect(parseScanCode(''), '');
|
||||
expect(parseScanCode(' '), '');
|
||||
});
|
||||
|
||||
test('无 code 参数的 URL:整串兜底当编码', () {
|
||||
// 无 ?code= 时不误判,返回原串(由上层按编码匹配,匹配不到再报未找到)
|
||||
const raw = 'https://x/product/only-public-id';
|
||||
expect(parseScanCode(raw), raw);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user