65c672b4ad
- 新组件 DsSwitch(原型 atoms .switch 对照,L1 已登记:38×22 pill,on=primary) - 商品抽屉状态行:三态徽章后跟挂售 switch(在售⇄库存 即时生效,已售只读, readonly 禁用),桌面 drawer / 移动 sheet 同组件 - 列表状态列/卡片徽章三态化(在售绿/库存蓝/已售灰,icons BADGE_ICON 补两词); 状态筛选改「全部/在售/库存/已售」走服务端;预警缺货退出状态维度由数量染色承担 - KPI 第四卡「缺货预警」→「已售」(sold_count,点击筛选已售) - 原型同步:atoms/index 登记 switch 与 b-库存/b-已售、inventory 两屏三态数据、 抽屉状态行 switch;12 道 ds 闸 + L1 同源闸全过 - golden 重录 ×9(三态徽章 + 已售卡形态) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
121 lines
3.8 KiB
Dart
121 lines
3.8 KiB
Dart
import 'package:dio/dio.dart';
|
||
import '../core/api/api_client.dart';
|
||
import '../core/exceptions.dart';
|
||
import '../core/models/page_result.dart';
|
||
import '../models/inventory.dart';
|
||
|
||
class InventoryRepository {
|
||
final ApiClient _client;
|
||
|
||
const InventoryRepository(this._client);
|
||
|
||
Future<PageResult<Inventory>> listInventory({
|
||
int? warehouseId,
|
||
int? productId,
|
||
String? keyword,
|
||
String? code,
|
||
List<String>? series,
|
||
List<String>? spec,
|
||
String? status, // 三态筛选:stock/on_sale/sold(逗号可多值);空=后端默认(排除已售)
|
||
int page = 1,
|
||
int pageSize = 50,
|
||
}) async {
|
||
try {
|
||
final params = <String, dynamic>{
|
||
'page': page,
|
||
'page_size': pageSize,
|
||
if (warehouseId != null) 'warehouse_id': warehouseId,
|
||
if (productId != null) 'product_id': productId,
|
||
if (keyword != null && keyword.isNotEmpty) 'keyword': keyword,
|
||
if (code != null && code.isNotEmpty) 'code': code,
|
||
if (series != null && series.isNotEmpty) 'series': series.join(','),
|
||
if (spec != null && spec.isNotEmpty) 'spec': spec.join(','),
|
||
if (status != null && status.isNotEmpty) 'status': status,
|
||
};
|
||
final resp = await _client.get('/inventory', params: params);
|
||
return PageResult.fromJson(
|
||
resp.data as Map<String, dynamic>,
|
||
Inventory.fromJson,
|
||
);
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '获取库存失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
|
||
Future<InventorySummary> getSummary() async {
|
||
try {
|
||
final resp = await _client.get('/inventory/summary');
|
||
return InventorySummary.fromJson(resp.data as Map<String, dynamic>);
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '获取库存汇总失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
|
||
Future<Map<String, dynamic>> createCheck(Map<String, dynamic> data) async {
|
||
try {
|
||
final resp = await _client.post('/inventory/checks', data: data);
|
||
return resp.data as Map<String, dynamic>;
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '提交盘点失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 库存⇄在售 挂售切换(status 仅收 stock/on_sale;sold 由出库流程专属)
|
||
Future<void> updateStatus(int id, String status) async {
|
||
try {
|
||
await _client.put('/inventory/$id/status', data: {'status': status});
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '状态更新失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
|
||
Future<void> updateRemark(int id, String remark) async {
|
||
try {
|
||
await _client.put('/inventory/$id/remark', data: {'remark': remark});
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '更新备注失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
|
||
Future<PageResult<InventoryLog>> listLogs({
|
||
int? warehouseId,
|
||
int? productId,
|
||
int page = 1,
|
||
int pageSize = 50,
|
||
}) async {
|
||
try {
|
||
final params = <String, dynamic>{
|
||
'page': page,
|
||
'page_size': pageSize,
|
||
if (warehouseId != null) 'warehouse_id': warehouseId,
|
||
if (productId != null) 'product_id': productId,
|
||
};
|
||
final resp = await _client.get('/inventory/logs', params: params);
|
||
return PageResult.fromJson(
|
||
resp.data as Map<String, dynamic>,
|
||
InventoryLog.fromJson,
|
||
);
|
||
} on DioException catch (e) {
|
||
throw AppException(
|
||
e.response?.data?['error'] as String? ?? '获取流水失败',
|
||
statusCode: e.response?.statusCode,
|
||
);
|
||
}
|
||
}
|
||
}
|