feat(client): 新增入库单/出库单打印,增强商品标签打印布局
- 商品标签改为 4×2 英寸横向,二维码右置,左侧展示系列/规格/批次/生产日期 - 新增 printStockInOrder:A4 入库单,含单号/供应商/仓库/明细表/签字栏 - 新增 printStockOutOrder:A4 出库通知单(温馨提示),含客户/明细表/签字栏 - 入库单/出库单编辑页加载完成后显示「打印」按钮 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -533,6 +533,7 @@ class _QRCodeDialogState extends ConsumerState<_QRCodeDialog> {
|
||||
name: p.name,
|
||||
code: p.code,
|
||||
spec: p.spec,
|
||||
series: p.series,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
import '../../core/auth/auth_state.dart';
|
||||
import '../../core/utils/print_util.dart';
|
||||
import '../../models/stock_in.dart';
|
||||
import '../../providers/partner_provider.dart';
|
||||
import '../../providers/product_option_provider.dart';
|
||||
import '../../providers/product_provider.dart';
|
||||
@@ -29,6 +31,7 @@ class _StockInFormScreenState extends ConsumerState<StockInFormScreen> {
|
||||
bool _submitting = false;
|
||||
bool _loadingEdit = false;
|
||||
Map<int, double> _inventoryMap = {};
|
||||
StockInOrder? _loadedOrder;
|
||||
|
||||
final List<_ItemRow> _items = [];
|
||||
|
||||
@@ -53,6 +56,7 @@ class _StockInFormScreenState extends ConsumerState<StockInFormScreen> {
|
||||
final specOpts = await ref.read(productSpecListProvider.future);
|
||||
|
||||
setState(() {
|
||||
_loadedOrder = order;
|
||||
_warehouseId = order.warehouseId;
|
||||
_partnerId = order.partnerId;
|
||||
if (order.orderDate != null) {
|
||||
@@ -124,6 +128,11 @@ class _StockInFormScreenState extends ConsumerState<StockInFormScreen> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _printOrder() async {
|
||||
if (_loadedOrder == null) return;
|
||||
await printStockInOrder(_loadedOrder!);
|
||||
}
|
||||
|
||||
Future<void> _submit(bool asDraft) async {
|
||||
if (!asDraft && !_formKey.currentState!.validate()) return;
|
||||
if (_warehouseId == null) {
|
||||
@@ -248,6 +257,14 @@ class _StockInFormScreenState extends ConsumerState<StockInFormScreen> {
|
||||
Text(_isEdit ? '修改入库单' : '新建入库单',
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
||||
const Spacer(),
|
||||
if (_isEdit && _loadedOrder != null) ...[
|
||||
OutlinedButton.icon(
|
||||
onPressed: _printOrder,
|
||||
icon: const Icon(Icons.print_outlined, size: 16),
|
||||
label: const Text('打印'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
OutlinedButton(
|
||||
onPressed: _submitting ? null : () => _submit(true),
|
||||
child: const Text('保存草稿'),
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
import '../../core/auth/auth_state.dart';
|
||||
import '../../core/utils/print_util.dart';
|
||||
import '../../models/stock_out.dart';
|
||||
import '../../providers/inventory_provider.dart';
|
||||
import '../../providers/partner_provider.dart';
|
||||
import '../../providers/product_option_provider.dart';
|
||||
@@ -29,6 +31,7 @@ class _StockOutFormScreenState extends ConsumerState<StockOutFormScreen> {
|
||||
bool _submitting = false;
|
||||
bool _loadingEdit = false;
|
||||
Map<int, double> _inventoryMap = {};
|
||||
StockOutOrder? _loadedOrder;
|
||||
|
||||
final List<_ItemRow> _items = [];
|
||||
|
||||
@@ -53,6 +56,7 @@ class _StockOutFormScreenState extends ConsumerState<StockOutFormScreen> {
|
||||
final specOpts = await ref.read(productSpecListProvider.future);
|
||||
|
||||
setState(() {
|
||||
_loadedOrder = order;
|
||||
_warehouseId = order.warehouseId;
|
||||
_partnerId = order.partnerId;
|
||||
if (order.orderDate != null) {
|
||||
@@ -125,6 +129,11 @@ class _StockOutFormScreenState extends ConsumerState<StockOutFormScreen> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _printOrder() async {
|
||||
if (_loadedOrder == null) return;
|
||||
await printStockOutOrder(_loadedOrder!);
|
||||
}
|
||||
|
||||
Future<void> _submit(bool asDraft) async {
|
||||
if (!asDraft && !_formKey.currentState!.validate()) return;
|
||||
if (_warehouseId == null) {
|
||||
@@ -248,6 +257,14 @@ class _StockOutFormScreenState extends ConsumerState<StockOutFormScreen> {
|
||||
Text(_isEdit ? '修改出库单' : '新建出库单',
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
||||
const Spacer(),
|
||||
if (_isEdit && _loadedOrder != null) ...[
|
||||
OutlinedButton.icon(
|
||||
onPressed: _printOrder,
|
||||
icon: const Icon(Icons.print_outlined, size: 16),
|
||||
label: const Text('打印'),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
OutlinedButton(
|
||||
onPressed: _submitting ? null : () => _submit(true),
|
||||
child: const Text('保存草稿'),
|
||||
|
||||
Reference in New Issue
Block a user