feat(client): 出入库单详情抽屉明细增加生产日期+批次号列(两端,抽屉加宽 660,原型同步)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-14 09:54:10 +08:00
parent 3721fe6006
commit 44c985e6b5
11 changed files with 201 additions and 80 deletions
+3 -2
View File
@@ -60,8 +60,9 @@ class StockInItem {
costPrice: (json['cost_price'] as num?)?.toDouble() ?? 0,
costAmount: (json['cost_amount'] as num?)?.toDouble() ?? 0,
returnedQuantity: (json['returned_quantity'] as num?)?.toDouble() ?? 0,
batchNo: json['batch_no'] as String?,
productionDate: json['production_date'] as String?,
// 批次号/生产日期:优先明细行快照,回退 product 关联(对齐 stock_out.dart 写法)
batchNo: lineOrProduct('batch_no', 'batch_no'),
productionDate: lineOrProduct('production_date', 'production_date'),
productName: lineOrProduct('product_name', 'name'),
productCode: lineOrProduct('product_code', 'code'),
productSeries: lineOrProduct('series', 'series'),
@@ -414,7 +414,8 @@ class _StockInListScreenState extends ConsumerState<StockInListScreen> {
// 下拉刷新 = 桌面「刷新」
onRefresh: () async {
ref.read(stockInListProvider.notifier).reload();
await Future<void>.delayed(const Duration(milliseconds: 600));
await Future<void>.delayed(
const Duration(milliseconds: 600));
},
mobileCards:
orders.map((o) => _orderCard(context, o)).toList(),
@@ -995,6 +996,10 @@ class _StockInListScreenState extends ConsumerState<StockInListScreen> {
price: it.costPrice == 0 ? '待定价' : _num.format(it.costPrice),
amount: it.costAmount == 0 ? '待定价' : _num.format(it.costAmount),
pending: it.costPrice == 0,
productionDate: it.productionDate != null
? it.productionDate!.substring(0, 10)
: null,
batchNo: it.batchNo,
))
.toList(),
totalText: o.costTotal != null ? _money.format(o.costTotal) : '',
@@ -1076,6 +1076,10 @@ class _StockOutListScreenState extends ConsumerState<StockOutListScreen> {
cost: admin ? _num.format(it.costPrice) : null,
profit: admin ? (pending ? '待定价' : _num.format(profit)) : null,
pending: pending,
productionDate: it.productionDate != null
? it.productionDate!.substring(0, 10)
: null,
batchNo: it.batchNo,
);
}).toList(),
totalText: o.saleTotal != null ? _money.format(o.saleTotal) : '',
+71 -9
View File
@@ -41,7 +41,7 @@ Future<T?> showOrderDetailDrawer<T>(
barrierColor: _kDrawerMask,
transitionDuration: const Duration(milliseconds: 250),
pageBuilder: (ctx, _, __) {
final w = math.min(600.0, MediaQuery.of(ctx).size.width * 0.94);
final w = math.min(660.0, MediaQuery.of(ctx).size.width * 0.94);
return Align(
alignment: Alignment.centerRight,
child: Material(
@@ -63,7 +63,8 @@ Future<T?> showOrderDetailDrawer<T>(
);
}
/// 抽屉明细行(对齐原型 .lines .lr,5 列:商品·编码 / 系列·规格 / 数量 / 单价 / 金额)。
/// 抽屉明细行(对齐原型 .lines .lr,入库 6 列 / 出库管理员 8 列:
/// 商品·编码 / 系列·规格 / 生产日期·批次号 / 数量 / 单价(/成本价/售价/总售价) / 利润)。
class OrderLine {
final String name;
final String code;
@@ -77,6 +78,9 @@ class OrderLine {
final String? cost;
final String? profit;
final bool pending; // 单价<=0:单价/金额显示待定价样式
// 生产日期 / 批次号(2026-07-14,出入库单详情明细新增双行列)
final String? productionDate;
final String? batchNo;
const OrderLine({
required this.name,
required this.code,
@@ -88,6 +92,8 @@ class OrderLine {
this.cost,
this.profit,
this.pending = false,
this.productionDate,
this.batchNo,
});
}
@@ -327,8 +333,11 @@ class OrderDetailDrawer extends StatelessWidget {
);
}
/// 窄屏明细行(原型:左 商品名 + 系列·×数量 小字,右 金额 mono / 待定价徽章)。
/// 窄屏明细行(原型:左 商品名 + 系列·×数量 小字,中 生产日期/批次号双行列
/// (两值都空则不渲染,避免空占位),右 金额 mono / 待定价徽章)。
Widget _mLineRow(dynamic t, OrderLine l, bool last) {
final hasDateBatch = (l.productionDate?.isNotEmpty ?? false) ||
(l.batchNo?.isNotEmpty ?? false);
return Container(
padding: const EdgeInsets.symmetric(vertical: 11),
decoration: last
@@ -351,6 +360,30 @@ class OrderDetailDrawer extends StatelessWidget {
],
),
),
if (hasDateBatch) ...[
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
Text(
(l.productionDate?.isNotEmpty ?? false)
? l.productionDate!
: '',
style: TextStyle(
fontSize: AppDims.fsSm,
fontFamily: AppFonts.mono,
fontFamilyFallback: AppFonts.monoFallback,
color: t.text)),
Text((l.batchNo?.isNotEmpty ?? false) ? l.batchNo! : '',
style: TextStyle(
fontSize: AppDims.fsXs,
fontFamily: AppFonts.mono,
fontFamilyFallback: AppFonts.monoFallback,
color: t.faint)),
],
),
],
const SizedBox(width: 10),
l.pending
? const DsTextIconBadge('待定价')
@@ -450,6 +483,7 @@ class _LinesTable extends StatelessWidget {
c1: Text('商品 · 编码',
style: _hStyle(t), overflow: TextOverflow.ellipsis),
c2: Text('系列 / 规格', style: _hStyle(t)),
cDate: Text('生产日期 / 批次号', style: _hStyle(t)),
c3: Text('数量', textAlign: TextAlign.right, style: _hStyle(t)),
c4: _withProfit
? Text('成本价', textAlign: TextAlign.right, style: _hStyle(t))
@@ -506,6 +540,30 @@ class _LinesTable extends StatelessWidget {
TextStyle(fontSize: AppDims.fsXs, color: t.muted)),
],
),
cDate: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
(lines[i].productionDate?.isNotEmpty ?? false)
? lines[i].productionDate!
: '',
style: TextStyle(
fontSize: AppDims.fsSm,
fontFamily: AppFonts.mono,
fontFamilyFallback: AppFonts.monoFallback,
color: t.text)),
Text(
(lines[i].batchNo?.isNotEmpty ?? false)
? lines[i].batchNo!
: '',
style: TextStyle(
fontSize: AppDims.fsXs,
fontFamily: AppFonts.mono,
fontFamilyFallback: AppFonts.monoFallback,
color: t.faint)),
],
),
c3: Text(lines[i].qty,
textAlign: TextAlign.right,
style: const TextStyle(
@@ -557,11 +615,12 @@ class _LinesTable extends StatelessWidget {
color: accent ? t.text : t.text));
}
// 5 列布局(对齐原型 grid 1fr 124 40 64 78);c6/c7 非空时为出库 7 列形态
// 数量/成本价/售价/总售价/利润,数值列等宽收窄)。
// 6 列布局(入库,对齐原型 grid 1fr 110 72 40 64 78);c6/c7 非空时为出库
// 8 列形态(商品/系列规格/生产日期批次号/数量/成本价/售价/总售价/利润,数值列等宽收窄)。
Widget _lineRow(BuildContext context,
{required Widget c1,
required Widget c2,
required Widget cDate,
required Widget c3,
required Widget c4,
required Widget c5,
@@ -573,15 +632,18 @@ class _LinesTable extends StatelessWidget {
children: [
Expanded(child: c1),
const SizedBox(width: 8),
// 5 列(入库)时中间列加宽左移:商品列不再吃掉全部余宽,
// 6 列(入库)时中间列加宽左移:商品列不再吃掉全部余宽,
// 「进价(单瓶)」表头一行放得下(2026-07-03 用户反馈)。
SizedBox(width: wide ? 100 : 124, child: c2),
// 2026-07-14:新增「生产日期/批次号」列,入库侧挤压 124→110、88→78 腾位。
SizedBox(width: wide ? 100 : 110, child: c2),
const SizedBox(width: 8),
SizedBox(width: 72, child: cDate),
const SizedBox(width: 8),
SizedBox(width: wide ? 32 : 40, child: c3),
const SizedBox(width: 8),
SizedBox(width: wide ? 62 : 88, child: c4),
SizedBox(width: wide ? 62 : 78, child: c4),
const SizedBox(width: 8),
SizedBox(width: wide ? 62 : 88, child: c5),
SizedBox(width: wide ? 62 : 78, child: c5),
if (c6 != null) ...[
const SizedBox(width: 8),
SizedBox(width: 62, child: c6),
@@ -6,6 +6,9 @@ import 'package:jiu_client/widgets/order_detail_drawer.dart';
/// 2026-07 定价重设计:出库详情按角色两种形态——
/// 管理员(行带 cost/profit)= 成本价/售价/利润 三数值列 + 合计利润;
/// operator(不带)= 售价/小计两列,无成本无利润。
///
/// 2026-07-14:明细新增「生产日期 / 批次号」双行列(入库 5→6 列 / 出库管理员
/// 7→8 列),两种形态下都固定渲染,与成本/利润的角色可见性无关。
void main() {
Widget host(OrderDetailDrawer drawer) => MaterialApp(
theme: buildTheme('a'),
@@ -22,6 +25,8 @@ void main() {
amount: '¥800.00',
cost: '¥355.00',
profit: '¥90.00',
productionDate: '2021-01-27',
batchNo: '20260506',
);
const line4 = OrderLine(
@@ -32,9 +37,11 @@ void main() {
qty: '2',
price: '¥400.00',
amount: '¥800.00',
productionDate: '2021-01-27',
batchNo: '20260506',
);
testWidgets('管理员形态:成本价/售价/利润列 + 合计利润', (tester) async {
testWidgets('管理员形态:成本价/售价/利润列 + 生产日期/批次号列 + 合计利润', (tester) async {
await tester.pumpWidget(host(OrderDetailDrawer(
title: 'CK001',
infoRows: const [],
@@ -54,9 +61,12 @@ void main() {
expect(find.text('¥355.00'), findsOneWidget);
expect(find.text('¥90.00'), findsNWidgets(2)); // 行利润 + 合计利润
expect(find.text('合计利润 '), findsOneWidget);
expect(find.text('生产日期 / 批次号'), findsOneWidget);
expect(find.text('2021-01-27'), findsOneWidget);
expect(find.text('20260506'), findsOneWidget);
});
testWidgets('operator 形态:售价/小计,无成本无利润', (tester) async {
testWidgets('operator 形态:售价/小计 + 生产日期/批次号列,无成本无利润', (tester) async {
await tester.pumpWidget(host(OrderDetailDrawer(
title: 'CK001',
infoRows: const [],
@@ -73,5 +83,32 @@ void main() {
expect(find.text('利润'), findsNothing);
expect(find.text('合计利润 '), findsNothing);
expect(find.text('¥800.00'), findsNWidgets(2)); // 行小计 + 合计金额
expect(find.text('生产日期 / 批次号'), findsOneWidget);
expect(find.text('2021-01-27'), findsOneWidget);
expect(find.text('20260506'), findsOneWidget);
});
testWidgets('生产日期/批次号两值都空时,桌面列仍渲染但单元格显示 —', (tester) async {
const lineEmpty = OrderLine(
name: '汾酒青花20年',
code: 'ZXZ027232',
series: '普通/53度',
spec: '500ml*6/件',
qty: '2',
price: '¥400.00',
amount: '¥800.00',
);
await tester.pumpWidget(host(OrderDetailDrawer(
title: 'RK001',
infoRows: const [],
linesLabel: '入库明细',
lines: const [lineEmpty],
totalText: '¥800.00',
priceLabel: '进价(单瓶)',
amountLabel: '总价',
actionGroups: const [],
)));
expect(find.text('生产日期 / 批次号'), findsOneWidget);
expect(find.text(''), findsNWidgets(2)); // 生产日期 + 批次号均兜底
});
}
+4 -1
View File
@@ -217,7 +217,7 @@ td.num{font-family:var(--font-mono);}
/* ---- 抽屉 ---- */
.drawer{position:fixed; top:0; right:0; height:100vh; width:480px; max-width:94vw; background:var(--surface); border-left:1px solid var(--border); box-shadow:-16px 0 50px var(--shadow); transform:translateX(100%); transition:transform .25s; z-index:var(--z-drawer); display:flex; flex-direction:column;}
.drawer.show{transform:translateX(0);}
.drawer.wide{width:600px;}
.drawer.wide{width:660px;}
/* 抽屉遮罩:点击空白处关闭抽屉(z-index 在抽屉之下) */
.drawer-mask{position:fixed; inset:0; background:var(--scrim); opacity:0; pointer-events:none; transition:opacity .25s; z-index:var(--z-drawer-scrim);}
.drawer-mask.show{opacity:1; pointer-events:auto;}
@@ -256,6 +256,9 @@ td.num{font-family:var(--font-mono);}
.lcell .lcode{display:block; font-family:var(--font-mono); color:var(--muted); font-size:var(--fs-xs); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lspec{display:block; color:var(--muted); font-size:var(--fs-xs); margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lser{display:block; color:var(--text); font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
/* 明细行新增列:生产日期 / 批次号(2026-07-14,出入库单详情) */
.lcell .lpdate{display:block; font-family:var(--font-mono); color:var(--text); font-size:var(--fs-sm); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lbatch{display:block; font-family:var(--font-mono); color:var(--faint); font-size:var(--fs-xs); margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
/* 抽屉底部操作分组:审核类 / 打印类 */
.dactions{margin-top:18px; display:flex; flex-direction:column; gap:14px;}
.dact-group{display:flex; flex-direction:column; gap:8px;}
+3 -3
View File
@@ -427,9 +427,9 @@
<div class="notice info"><svg viewBox="0 0 24 24"><use href="#i-info"/></svg><div>检测到未提交的入库单草稿(06-21 11:20),是否恢复?</div><div class="nb"><span class="lk">恢复</span><span class="lk" style="color:var(--muted)">放弃</span></div></div>
<div class="notice danger" style="margin-bottom:0"><svg viewBox="0 0 24 24"><use href="#i-alert"/></svg><div>单据被驳回:单价高于近期采购价,请核实后重报。</div></div>
</div></div>
<div class="pcard"><div class="pcard-h"><h3>单据明细行(商品 / 系列规格分列)</h3><span class="tk">.lines .lr · .lcell .ln/.lcode/.lser/.lspec</span></div><div class="pcard-b" style="display:block">
<div class="lines" style="max-width:480px"><div class="lh" style="grid-template-columns:1fr 124px 40px 64px 78px"><span>商品 · 编码</span><span>系列 / 规格</span><span style="text-align:right">数量</span><span style="text-align:right">单价</span><span style="text-align:right">金额</span></div>
<div class="lr" style="grid-template-columns:1fr 124px 40px 64px 78px;align-items:start"><span class="lcell"><span class="ln">泸州老窖 特曲</span><span class="lcode">LZLJ-TQ-52-500</span></span><span class="lcell"><span class="lser">特曲</span><span class="lspec">52° 500ml×6</span></span><span style="text-align:right;font-family:var(--font-mono)">48</span><span style="text-align:right;font-family:var(--font-mono)">¥320</span><span class="amt">¥15,360</span></div>
<div class="pcard"><div class="pcard-h"><h3>单据明细行(商品 / 系列规格 / 生产日期批次号分列)</h3><span class="tk">.lines .lr · .lcell .ln/.lcode/.lser/.lspec/.lpdate/.lbatch</span></div><div class="pcard-b" style="display:block">
<div class="lines" style="max-width:560px"><div class="lh" style="grid-template-columns:1fr 110px 72px 40px 64px 78px"><span>商品 · 编码</span><span>系列 / 规格</span><span>生产日期 / 批次号</span><span style="text-align:right">数量</span><span style="text-align:right">单价</span><span style="text-align:right">金额</span></div>
<div class="lr" style="grid-template-columns:1fr 110px 72px 40px 64px 78px;align-items:start"><span class="lcell"><span class="ln">泸州老窖 特曲</span><span class="lcode">LZLJ-TQ-52-500</span></span><span class="lcell"><span class="lser">特曲</span><span class="lspec">52° 500ml×6</span></span><span class="lcell"><span class="lpdate">2022-02-14</span><span class="lbatch">20260415</span></span><span style="text-align:right;font-family:var(--font-mono)">48</span><span style="text-align:right;font-family:var(--font-mono)">¥320</span><span class="amt">¥15,360</span></div>
</div>
</div></div>
<div class="pcard"><div class="pcard-h"><h3>抽屉操作分组</h3><span class="tk">.dactions · .dact-group/.dact-label/.dact-row(审核类 / 打印类)</span></div><div class="pcard-b" style="display:block">
+12 -8
View File
@@ -43,13 +43,13 @@
<script src="datewheel.js"></script>
<script>
const ORDERS=[
{no:'RK-20260620-009',party:'鼎晟调货',wh:'主仓',items:2,amount:'¥5,360',status:'已审核',ret:'部分退单',date:'2026-06-20',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、五粮液 普五 52°',pending:1,lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:1,a:'待定价',pend:true},{n:'五粮液 普五 52°',s:'500ml×6',q:1,a:'¥2,680'}]},
{no:'RK-20260620-006',party:'鼎晟供应链',wh:'名酒仓',items:3,amount:'¥12,800',status:'待审核',date:'2026-06-20',by:'王经理',auditor:'',goods:'茅台 王子酒、习酒 窖藏 1988',lines:[{n:'茅台 王子酒',s:'500ml×6',q:4,a:'¥4,800'},{n:'习酒 窖藏 1988',s:'500ml×6',q:2,a:'¥4,000'},{n:'茅台 迎宾酒',s:'500ml×6',q:4,a:'¥4,000'}]},
{no:'RK-20260620-005',party:'贵州茅台经销',wh:'主仓',items:2,amount:'¥80,400',status:'已审核',date:'2026-06-20',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、茅台 1935',lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:20,a:'¥53,600'},{n:'茅台 1935',s:'500ml×6',q:10,a:'¥26,800'}]},
{no:'RK-20260619-004',party:'五粮液华东仓',wh:'一号仓',items:2,amount:'¥33,600',status:'已审核',ret:'已退单',date:'2026-06-19',by:'李采购',auditor:'张主管',goods:'五粮液 普五 52°、五粮液 1618',lines:[{n:'五粮液 普五 52°',s:'500ml×6',q:8,a:'¥16,800'},{n:'五粮液 1618',s:'500ml×6',q:8,a:'¥16,800'}]},
{no:'RK-20260619-003',party:'剑南春直营',wh:'主仓',items:1,amount:'¥4,380',status:'已拒绝',date:'2026-06-19',by:'李采购',auditor:'张主管',goods:'剑南春 水晶剑',lines:[{n:'剑南春 水晶剑',s:'500ml×6',q:10,a:'¥4,380'}]},
{no:'RK-20260618-002',party:'泸州老窖仓',wh:'名酒仓',items:2,amount:'¥16,000',status:'已审核',date:'2026-06-18',by:'王经理',auditor:'王经理',goods:'泸州老窖 特曲、国窖 1573',lines:[{n:'泸州老窖 特曲',s:'500ml×6',q:25,a:'¥8,000'},{n:'国窖 1573',s:'500ml×6',q:8,a:'¥8,000'}]},
{no:'RK-20260618-001',party:'洋河股份',wh:'主仓',items:2,amount:'¥14,800',status:'草稿',date:'2026-06-18',by:'王经理',auditor:'',goods:'洋河 梦之蓝 M6、洋河 海之蓝',lines:[{n:'洋河 梦之蓝 M6',s:'500ml×6',q:12,a:'¥7,440'},{n:'洋河 海之蓝',s:'500ml×6',q:16,a:'¥7,360'}]},
{no:'RK-20260620-009',party:'鼎晟调货',wh:'主仓',items:2,amount:'¥5,360',status:'已审核',ret:'部分退单',date:'2026-06-20',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、五粮液 普五 52°',pending:1,lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:1,a:'待定价',pend:true,pd:'2021-09-12',b:'20260518'},{n:'五粮液 普五 52°',s:'500ml×6',q:1,a:'¥2,680',pd:'2021-11-06',b:'20260408'}]},
{no:'RK-20260620-006',party:'鼎晟供应链',wh:'名酒仓',items:3,amount:'¥12,800',status:'待审核',date:'2026-06-20',by:'王经理',auditor:'',goods:'茅台 王子酒、习酒 窖藏 1988',lines:[{n:'茅台 王子酒',s:'500ml×6',q:4,a:'¥4,800',pd:'2022-01-18',b:'20260512'},{n:'习酒 窖藏 1988',s:'500ml×6',q:2,a:'¥4,000',pd:'2019-11-03',b:'20260210'},{n:'茅台 迎宾酒',s:'500ml×6',q:4,a:'¥4,000',pd:'2021-03-14',b:'20260425'}]},
{no:'RK-20260620-005',party:'贵州茅台经销',wh:'主仓',items:2,amount:'¥80,400',status:'已审核',date:'2026-06-20',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、茅台 1935',lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:20,a:'¥53,600',pd:'2021-09-12',b:'20260518'},{n:'茅台 1935',s:'500ml×6',q:10,a:'¥26,800',pd:'2020-05-03',b:'20260420'}]},
{no:'RK-20260619-004',party:'五粮液华东仓',wh:'一号仓',items:2,amount:'¥33,600',status:'已审核',ret:'已退单',date:'2026-06-19',by:'李采购',auditor:'张主管',goods:'五粮液 普五 52°、五粮液 1618',lines:[{n:'五粮液 普五 52°',s:'500ml×6',q:8,a:'¥16,800',pd:'2021-11-06',b:'20260408'},{n:'五粮液 1618',s:'500ml×6',q:8,a:'¥16,800',pd:'2022-03-22',b:'20260316'}]},
{no:'RK-20260619-003',party:'剑南春直营',wh:'主仓',items:1,amount:'¥4,380',status:'已拒绝',date:'2026-06-19',by:'李采购',auditor:'张主管',goods:'剑南春 水晶剑',lines:[{n:'剑南春 水晶剑',s:'500ml×6',q:10,a:'¥4,380',pd:'2022-07-15',b:'20260502'}]},
{no:'RK-20260618-002',party:'泸州老窖仓',wh:'名酒仓',items:2,amount:'¥16,000',status:'已审核',date:'2026-06-18',by:'王经理',auditor:'王经理',goods:'泸州老窖 特曲、国窖 1573',lines:[{n:'泸州老窖 特曲',s:'500ml×6',q:25,a:'¥8,000',pd:'2022-02-14',b:'20260415'},{n:'国窖 1573',s:'500ml×6',q:8,a:'¥8,000',pd:'2021-04-09',b:'20260410'}]},
{no:'RK-20260618-001',party:'洋河股份',wh:'主仓',items:2,amount:'¥14,800',status:'草稿',date:'2026-06-18',by:'王经理',auditor:'',goods:'洋河 梦之蓝 M6、洋河 海之蓝',lines:[{n:'洋河 梦之蓝 M6',s:'500ml×6',q:12,a:'¥7,440',pd:'2020-12-01',b:'20260322'},{n:'洋河 海之蓝',s:'500ml×6',q:16,a:'¥7,360',pd:'2022-06-11',b:'20260305'}]},
];
/* 状态词与桌面/后端对齐:主状态 4 词 + 退单态 2 词(return_state: partial/full */
const ST=['全部','草稿','待审核','已审核','已拒绝','部分退单','已退单'];
@@ -146,7 +146,11 @@ function openOrder(no){ const o=ORDERS.find(x=>x.no===no);
const pendRow=o.pending?`<div class="drow"><span>成本</span><b>${biB('待定价')}</b></div>`:'';
const confirmBtn=(o.pending&&o.status==='已审核')?`<div class="btn primary" style="flex:1;justify-content:center" onclick="openConfirm('${o.no}')"><svg viewBox="0 0 24 24"><use href="#i-edit"/></svg>确认进价</div>`:'';
const lns=o.lines||[];
const lineRows=lns.map((l,i)=>`<div class="drow"${i===lns.length-1?' style="border-bottom:none"':''}><span style="color:var(--text);line-height:1.45">${l.n}<br><span style="color:var(--faint);font-size:var(--fs-xs)">${l.s} · ×${l.q}</span></span><b style="font-family:var(--font-mono)">${l.pend?biB('待定价'):l.a}</b></div>`).join('');
// 金额区左侧插入「生产日期 / 批次号」双行列(与桌面同构,两值都空则不渲染该列)
const lineRows=lns.map((l,i)=>{
const pdb=(l.pd||l.b)?`<span class="lcell" style="text-align:right"><span class="lpdate">${l.pd||'—'}</span><span class="lbatch">${l.b||'—'}</span></span>`:'';
return `<div class="drow" style="align-items:flex-start;gap:10px${i===lns.length-1?';border-bottom:none':''}"><span style="flex:1;min-width:0;color:var(--text);line-height:1.45">${l.n}<br><span style="color:var(--faint);font-size:var(--fs-xs)">${l.s} · ×${l.q}</span></span>${pdb}<b style="font-family:var(--font-mono)">${l.pend?biB('待定价'):l.a}</b></div>`;
}).join('');
openSheet(o.no, `<div class="drow"><span>单据日期</span><b>${o.date}</b></div><div class="drow"><span>供应商</span><b>${o.party}</b></div><div class="drow"><span>仓库</span><b>${o.wh}</b></div><div class="drow"><span>商品数</span><b>${o.items}</b></div><div class="drow"><span>入库员</span><b>${o.by}</b></div><div class="drow"><span>审核员</span><b>${o.auditor||'—'}</b></div>${pendRow}<div class="drow" style="border-bottom:none"><span>状态</span><b>${biB(o.status)}${o.ret?' '+biB(o.ret):''}</b></div>
<div class="pe-card" style="margin-top:14px"><div class="pe-h"><span class="pe-ic"><svg viewBox="0 0 24 24"><use href="#i-ic33"/></svg></span>入库明细 · ${lns.length} 项</div><div class="pe-b" style="padding-top:2px;padding-bottom:2px">${lineRows}</div></div>
<div class="drow" style="border-bottom:none"><span>合计金额</span><b style="font-family:var(--font-mono)">${o.amount}</b></div>
+11 -7
View File
@@ -43,12 +43,12 @@
<script src="datewheel.js"></script>
<script>
const ORDERS=[
{no:'CK-20260620-008',party:'城东烟酒行',wh:'主仓',items:2,amount:'¥18,600',profit:'¥3,400',status:'待审核',date:'2026-06-20',by:'王经理',auditor:'',goods:'茅台 飞天 53°、五粮液 普五 52°',lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:4,a:'¥12,600'},{n:'五粮液 普五 52°',s:'500ml×6',q:3,a:'¥6,000'}]},
{no:'CK-20260620-007',party:'宴汇大酒店',wh:'名酒仓',items:2,amount:'¥6,400',profit:'¥980',status:'已审核',ret:'部分退单',date:'2026-06-20',by:'李销售',auditor:'张主管',goods:'剑南春 水晶剑、洋河 海之蓝',lines:[{n:'剑南春 水晶剑',s:'500ml×6',q:4,a:'¥3,200'},{n:'洋河 海之蓝',s:'500ml×6',q:8,a:'¥3,200'}]},
{no:'CK-20260619-006',party:'金樽会所',wh:'主仓',items:2,amount:'¥41,000',profit:'¥6,150',status:'已审核',date:'2026-06-19',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、国窖 1573',pending:1,lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:10,a:'¥28,000'},{n:'国窖 1573',s:'500ml×6',q:13,a:'待定价',pend:true}]},
{no:'CK-20260619-005',party:'喜宴婚庆',wh:'一号仓',items:2,amount:'¥9,900',profit:'¥1,480',status:'已拒绝',date:'2026-06-19',by:'李销售',auditor:'张主管',goods:'泸州老窖 特曲、汾酒 青花 20',lines:[{n:'泸州老窖 特曲',s:'500ml×6',q:10,a:'¥5,000'},{n:'汾酒 青花 20',s:'500ml×6',q:7,a:'¥4,900'}]},
{no:'CK-20260618-004',party:'城东烟酒行',wh:'主仓',items:2,amount:'¥12,500',profit:'¥1,870',status:'已审核',ret:'已退单',date:'2026-06-18',by:'王经理',auditor:'王经理',goods:'西凤酒 旗舰版、郎酒 红花郎 15',lines:[{n:'西凤酒 旗舰版',s:'500ml×6',q:13,a:'¥6,500'},{n:'郎酒 红花郎 15',s:'500ml×6',q:10,a:'¥6,000'}]},
{no:'CK-20260618-003',party:'金樽会所',wh:'名酒仓',items:1,amount:'¥8,400',profit:'¥1,260',status:'草稿',date:'2026-06-18',by:'李销售',auditor:'',goods:'汾酒 青花 20',lines:[{n:'汾酒 青花 20',s:'500ml×6',q:12,a:'¥8,400'}]},
{no:'CK-20260620-008',party:'城东烟酒行',wh:'主仓',items:2,amount:'¥18,600',profit:'¥3,400',status:'待审核',date:'2026-06-20',by:'王经理',auditor:'',goods:'茅台 飞天 53°、五粮液 普五 52°',lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:4,a:'¥12,600',pd:'2021-09-12',b:'20260518'},{n:'五粮液 普五 52°',s:'500ml×6',q:3,a:'¥6,000',pd:'2021-11-06',b:'20260408'}]},
{no:'CK-20260620-007',party:'宴汇大酒店',wh:'名酒仓',items:2,amount:'¥6,400',profit:'¥980',status:'已审核',ret:'部分退单',date:'2026-06-20',by:'李销售',auditor:'张主管',goods:'剑南春 水晶剑、洋河 海之蓝',lines:[{n:'剑南春 水晶剑',s:'500ml×6',q:4,a:'¥3,200',pd:'2022-07-15',b:'20260502'},{n:'洋河 海之蓝',s:'500ml×6',q:8,a:'¥3,200',pd:'2022-06-11',b:'20260305'}]},
{no:'CK-20260619-006',party:'金樽会所',wh:'主仓',items:2,amount:'¥41,000',profit:'¥6,150',status:'已审核',date:'2026-06-19',by:'王经理',auditor:'张主管',goods:'茅台 飞天 53°、国窖 1573',pending:1,lines:[{n:'茅台 飞天 53°',s:'500ml×6',q:10,a:'¥28,000',pd:'2021-09-12',b:'20260518'},{n:'国窖 1573',s:'500ml×6',q:13,a:'待定价',pend:true,pd:'2021-04-09',b:'20260410'}]},
{no:'CK-20260619-005',party:'喜宴婚庆',wh:'一号仓',items:2,amount:'¥9,900',profit:'¥1,480',status:'已拒绝',date:'2026-06-19',by:'李销售',auditor:'张主管',goods:'泸州老窖 特曲、汾酒 青花 20',lines:[{n:'泸州老窖 特曲',s:'500ml×6',q:10,a:'¥5,000',pd:'2022-02-14',b:'20260415'},{n:'汾酒 青花 20',s:'500ml×6',q:7,a:'¥4,900',pd:'2021-01-27',b:'20260506'}]},
{no:'CK-20260618-004',party:'城东烟酒行',wh:'主仓',items:2,amount:'¥12,500',profit:'¥1,870',status:'已审核',ret:'已退单',date:'2026-06-18',by:'王经理',auditor:'王经理',goods:'西凤酒 旗舰版、郎酒 红花郎 15',lines:[{n:'西凤酒 旗舰版',s:'500ml×6',q:13,a:'¥6,500',pd:'2021-12-05',b:'20260325'},{n:'郎酒 红花郎 15',s:'500ml×6',q:10,a:'¥6,000',pd:'2018-09-16',b:'20260118'}]},
{no:'CK-20260618-003',party:'金樽会所',wh:'名酒仓',items:1,amount:'¥8,400',profit:'¥1,260',status:'草稿',date:'2026-06-18',by:'李销售',auditor:'',goods:'汾酒 青花 20',lines:[{n:'汾酒 青花 20',s:'500ml×6',q:12,a:'¥8,400',pd:'2021-01-27',b:'20260506'}]},
];
/* 状态词与桌面/后端对齐:主状态 4 词 + 退单态 2 词(return_state: partial/full */
const ST=['全部','草稿','待审核','已审核','已拒绝','部分退单','已退单'];
@@ -145,7 +145,11 @@ function openOrder(no){ const o=ORDERS.find(x=>x.no===no);
const pendRow=o.pending?`<div class="drow"><span>售价</span><b>${biB('待定价')}</b></div>`:'';
const confirmBtn=(o.pending&&o.status==='已审核')?`<div class="btn primary" style="flex:1;justify-content:center" onclick="openConfirm('${o.no}')"><svg viewBox="0 0 24 24"><use href="#i-edit"/></svg>确认售价</div>`:'';
const lns=o.lines||[];
const lineRows=lns.map((l,i)=>`<div class="drow"${i===lns.length-1?' style="border-bottom:none"':''}><span style="color:var(--text);line-height:1.45">${l.n}<br><span style="color:var(--faint);font-size:var(--fs-xs)">${l.s} · ×${l.q}</span></span><b style="font-family:var(--font-mono)">${l.pend?biB('待定价'):l.a}</b></div>`).join('');
// 金额区左侧插入「生产日期 / 批次号」双行列(与桌面同构,两值都空则不渲染该列)
const lineRows=lns.map((l,i)=>{
const pdb=(l.pd||l.b)?`<span class="lcell" style="text-align:right"><span class="lpdate">${l.pd||'—'}</span><span class="lbatch">${l.b||'—'}</span></span>`:'';
return `<div class="drow" style="align-items:flex-start;gap:10px${i===lns.length-1?';border-bottom:none':''}"><span style="flex:1;min-width:0;color:var(--text);line-height:1.45">${l.n}<br><span style="color:var(--faint);font-size:var(--fs-xs)">${l.s} · ×${l.q}</span></span>${pdb}<b style="font-family:var(--font-mono)">${l.pend?biB('待定价'):l.a}</b></div>`;
}).join('');
openSheet(o.no, `<div class="drow"><span>单据日期</span><b>${o.date}</b></div><div class="drow"><span>客户</span><b>${o.party}</b></div><div class="drow"><span>仓库</span><b>${o.wh}</b></div><div class="drow"><span>商品数</span><b>${o.items}</b></div><div class="drow"><span>出库员</span><b>${o.by}</b></div><div class="drow"><span>审核员</span><b>${o.auditor||'—'}</b></div>${pendRow}<div class="drow" style="border-bottom:none"><span>状态</span><b>${biB(o.status)}${o.ret?' '+biB(o.ret):''}</b></div>
<div class="pe-card" style="margin-top:14px"><div class="pe-h"><span class="pe-ic"><svg viewBox="0 0 24 24"><use href="#i-ic33"/></svg></span>出库明细 · ${lns.length} 项</div><div class="pe-b" style="padding-top:2px;padding-bottom:2px">${lineRows}</div></div>
<div class="drow"><span>合计金额</span><b style="font-family:var(--font-mono)">${o.amount}</b></div>
+24 -23
View File
@@ -233,27 +233,27 @@ function applyDatePreset(v){ state.datePreset=v; if(v==='all'){state.dateFrom=''
const PINFO={
'茅台 飞天 53°':{code:'MT-FT-53-500',series:'飞天',spec:'53° 500ml×6',cat:'酱香型',batch:'20260518'},
'茅台 1935':{code:'MT-1935-53-500',series:'1935',spec:'53° 500ml×6',cat:'酱香型',batch:'20260420'},
'茅台 王子酒':{code:'MT-WZ-53-500',series:'王子',spec:'53° 500ml×6',cat:'酱香型',batch:'20260512'},
'五粮液 普五 52°':{code:'WLY-P8-52-500',series:'第八代',spec:'52° 500ml×6',cat:'浓香型',batch:'20260408'},
'五粮液 1618':{code:'WLY-1618-52-500',series:'1618',spec:'52° 500ml×6',cat:'浓香型',batch:'20260316'},
'剑南春 水晶剑':{code:'JNC-SJ-52-500',series:'水晶剑',spec:'52° 500ml×6',cat:'浓香型',batch:'20260502'},
'剑南春 珍藏级':{code:'JNC-ZC-52-500',series:'珍藏',spec:'52° 500ml×6',cat:'浓香型',batch:'20260228'},
'国窖 1573':{code:'GJ-1573-52-500',series:'经典装',spec:'52° 500ml×6',cat:'浓香型',batch:'20260410'},
'洋河 梦之蓝 M6':{code:'YH-M6-45-500',series:'梦之蓝',spec:'45° 500ml×6',cat:'浓香型',batch:'20260322'},
'洋河 海之蓝':{code:'YH-HZL-42-480',series:'海之蓝',spec:'42° 480ml×6',cat:'浓香型',batch:'20260305'},
'洋河 天之蓝':{code:'YH-TZL-42-480',series:'天之蓝',spec:'42° 480ml×6',cat:'浓香型',batch:'20260318'},
'泸州老窖 特曲':{code:'LZLJ-TQ-52-500',series:'特曲',spec:'52° 500ml×6',cat:'浓香型',batch:'20260415'},
'泸州老窖 头曲':{code:'LZLJ-TOUQ-52-500',series:'头曲',spec:'52° 500ml×6',cat:'浓香型',batch:'20260401'},
'习酒 窖藏 1988':{code:'XJ-JC-53-500',series:'窖藏',spec:'53° 500ml×6',cat:'酱香型',batch:'20260210'},
'汾酒 青花 20':{code:'FJ-QH20-53-500',series:'青花',spec:'53° 500ml×6',cat:'清香型',batch:'20260506'},
'汾酒 老白汾':{code:'FJ-LBF-53-475',series:'老白汾',spec:'53° 475ml×6',cat:'清香型',batch:'20260429'},
'郎酒 红花郎 15':{code:'LJ-HHL15-53-500',series:'红花郎',spec:'53° 500ml×6',cat:'酱香型',batch:'20260118'},
'古井贡 年份原浆':{code:'GJG-NF-50-500',series:'年份原浆',spec:'50° 500ml×6',cat:'浓香型',batch:'20260512'},
'古井贡 古5':{code:'GJG-G5-50-500',series:'古5',spec:'50° 500ml×6',cat:'浓香型',batch:'20260508'},
'西凤酒 旗舰版':{code:'XF-QJ-52-500',series:'旗舰',spec:'52° 500ml×6',cat:'凤香型',batch:'20260325'},
'水井坊 井台':{code:'SJF-JT-52-500',series:'井台',spec:'52° 500ml×6',cat:'浓香型',batch:'20260430'},
'茅台 飞天 53°':{code:'MT-FT-53-500',series:'飞天',spec:'53° 500ml×6',cat:'酱香型',pdate:'2021-09-12',batch:'20260518'},
'茅台 1935':{code:'MT-1935-53-500',series:'1935',spec:'53° 500ml×6',cat:'酱香型',pdate:'2020-05-03',batch:'20260420'},
'茅台 王子酒':{code:'MT-WZ-53-500',series:'王子',spec:'53° 500ml×6',cat:'酱香型',pdate:'2022-01-18',batch:'20260512'},
'五粮液 普五 52°':{code:'WLY-P8-52-500',series:'第八代',spec:'52° 500ml×6',cat:'浓香型',pdate:'2021-11-06',batch:'20260408'},
'五粮液 1618':{code:'WLY-1618-52-500',series:'1618',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-03-22',batch:'20260316'},
'剑南春 水晶剑':{code:'JNC-SJ-52-500',series:'水晶剑',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-07-15',batch:'20260502'},
'剑南春 珍藏级':{code:'JNC-ZC-52-500',series:'珍藏',spec:'52° 500ml×6',cat:'浓香型',pdate:'2019-10-30',batch:'20260228'},
'国窖 1573':{code:'GJ-1573-52-500',series:'经典装',spec:'52° 500ml×6',cat:'浓香型',pdate:'2021-04-09',batch:'20260410'},
'洋河 梦之蓝 M6':{code:'YH-M6-45-500',series:'梦之蓝',spec:'45° 500ml×6',cat:'浓香型',pdate:'2020-12-01',batch:'20260322'},
'洋河 海之蓝':{code:'YH-HZL-42-480',series:'海之蓝',spec:'42° 480ml×6',cat:'浓香型',pdate:'2022-06-11',batch:'20260305'},
'洋河 天之蓝':{code:'YH-TZL-42-480',series:'天之蓝',spec:'42° 480ml×6',cat:'浓香型',pdate:'2021-08-25',batch:'20260318'},
'泸州老窖 特曲':{code:'LZLJ-TQ-52-500',series:'特曲',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-02-14',batch:'20260415'},
'泸州老窖 头曲':{code:'LZLJ-TOUQ-52-500',series:'头曲',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-05-19',batch:'20260401'},
'习酒 窖藏 1988':{code:'XJ-JC-53-500',series:'窖藏',spec:'53° 500ml×6',cat:'酱香型',pdate:'2019-11-03',batch:'20260210'},
'汾酒 青花 20':{code:'FJ-QH20-53-500',series:'青花',spec:'53° 500ml×6',cat:'清香型',pdate:'2021-01-27',batch:'20260506'},
'汾酒 老白汾':{code:'FJ-LBF-53-475',series:'老白汾',spec:'53° 475ml×6',cat:'清香型',pdate:'2022-04-08',batch:'20260429'},
'郎酒 红花郎 15':{code:'LJ-HHL15-53-500',series:'红花郎',spec:'53° 500ml×6',cat:'酱香型',pdate:'2018-09-16',batch:'20260118'},
'古井贡 年份原浆':{code:'GJG-NF-50-500',series:'年份原浆',spec:'50° 500ml×6',cat:'浓香型',pdate:'2021-06-30',batch:'20260512'},
'古井贡 古5':{code:'GJG-G5-50-500',series:'古5',spec:'50° 500ml×6',cat:'浓香型',pdate:'2022-08-02',batch:'20260508'},
'西凤酒 旗舰版':{code:'XF-QJ-52-500',series:'旗舰',spec:'52° 500ml×6',cat:'凤香型',pdate:'2021-12-05',batch:'20260325'},
'水井坊 井台':{code:'SJF-JT-52-500',series:'井台',spec:'52° 500ml×6',cat:'浓香型',pdate:'2020-07-22',batch:'20260430'},
};
// ---- 详细搜索模态框 ----
@@ -308,8 +308,9 @@ function auditBtns(o,idx){
return '';
}
function openDetail(idx){ const o=ORDERS[idx]; document.getElementById('dTitle').textContent=o.no;
let lh=`<div class="lines"><div class="lh" style="grid-template-columns:1fr 124px 40px 64px 78px"><span>商品 · 编码</span><span>系列 / 规格</span><span style="text-align:right">数量</span><span style="text-align:right">进价(单瓶)</span><span style="text-align:right">总价</span></div>`;
o.lines.forEach(l=>{ const pi=PINFO[l.name]||{}; const pend=(l.price||0)<=0; const priceC=pend?'<span class="pending-price">待定价</span>':numf(l.price); const amtC=pend?'<span class="pending-price">待定价</span>':numf(l.qty*l.price); lh+=`<div class="lr" style="grid-template-columns:1fr 124px 40px 64px 78px;align-items:start"><span class="lcell"><span class="ln">${l.name}</span><span class="lcode">${pi.code||'—'}</span></span><span class="lcell"><span class="lser">${pi.series||'—'}</span><span class="lspec">${pi.spec||''}</span></span><span style="text-align:right;font-family:var(--font-mono)">${l.qty}</span><span style="text-align:right;font-family:var(--font-mono)">${priceC}</span><span class="amt">${amtC}</span></div>`; }); lh+='</div>';
const GRID='1fr 110px 72px 40px 64px 78px';
let lh=`<div class="lines"><div class="lh" style="grid-template-columns:${GRID}"><span>商品 · 编码</span><span>系列 / 规格</span><span>生产日期 / 批次号</span><span style="text-align:right">数量</span><span style="text-align:right">进价(单瓶)</span><span style="text-align:right">总价</span></div>`;
o.lines.forEach(l=>{ const pi=PINFO[l.name]||{}; const pend=(l.price||0)<=0; const priceC=pend?'<span class="pending-price">待定价</span>':numf(l.price); const amtC=pend?'<span class="pending-price">待定价</span>':numf(l.qty*l.price); lh+=`<div class="lr" style="grid-template-columns:${GRID};align-items:start"><span class="lcell"><span class="ln">${l.name}</span><span class="lcode">${pi.code||'—'}</span></span><span class="lcell"><span class="lser">${pi.series||'—'}</span><span class="lspec">${pi.spec||''}</span></span><span class="lcell"><span class="lpdate">${pi.pdate||'—'}</span><span class="lbatch">${pi.batch||'—'}</span></span><span style="text-align:right;font-family:var(--font-mono)">${l.qty}</span><span style="text-align:right;font-family:var(--font-mono)">${priceC}</span><span class="amt">${amtC}</span></div>`; }); lh+='</div>';
const pendCount=o.lines.filter(l=>(l.price||0)<=0).length;
const auditor=o.auditor?o.auditor:'<span style="color:var(--faint)"></span>';
document.getElementById('drawerBody').innerHTML=`<div class="drow"><span>单据日期</span><b>${o.date}</b></div><div class="drow"><span>${PARTY_LABEL}</span><b>${o.party}</b></div><div class="drow"><span>仓库</span><b>${o.wh}</b></div><div class="drow"><span>商品数</span><b>${o.count}</b></div><div class="drow"><span>入库员</span><b>${o.op}</b></div><div class="drow"><span>审核员</span><b>${auditor}</b></div><div class="drow"><span>状态</span><b>${stBadge(o.status)}${o.ret?' '+stBadge(o.ret):''}</b></div><label style="display:block;font-size:var(--fs-sm);color:var(--muted);margin:16px 0 8px;">入库明细</label>${lh}<div class="ltotal">合计金额 <b>${money(o.amount)}</b></div>`+
+24 -24
View File
@@ -227,27 +227,27 @@ function applyDatePreset(v){ state.datePreset=v; if(v==='all'){state.dateFrom=''
const PINFO={
'茅台 飞天 53°':{code:'MT-FT-53-500',series:'飞天',spec:'53° 500ml×6',cat:'酱香型',batch:'20260518'},
'茅台 1935':{code:'MT-1935-53-500',series:'1935',spec:'53° 500ml×6',cat:'酱香型',batch:'20260420'},
'茅台 王子酒':{code:'MT-WZ-53-500',series:'王子',spec:'53° 500ml×6',cat:'酱香型',batch:'20260512'},
'五粮液 普五 52°':{code:'WLY-P8-52-500',series:'第八代',spec:'52° 500ml×6',cat:'浓香型',batch:'20260408'},
'五粮液 1618':{code:'WLY-1618-52-500',series:'1618',spec:'52° 500ml×6',cat:'浓香型',batch:'20260316'},
'剑南春 水晶剑':{code:'JNC-SJ-52-500',series:'水晶剑',spec:'52° 500ml×6',cat:'浓香型',batch:'20260502'},
'剑南春 珍藏级':{code:'JNC-ZC-52-500',series:'珍藏',spec:'52° 500ml×6',cat:'浓香型',batch:'20260228'},
'国窖 1573':{code:'GJ-1573-52-500',series:'经典装',spec:'52° 500ml×6',cat:'浓香型',batch:'20260410'},
'洋河 梦之蓝 M6':{code:'YH-M6-45-500',series:'梦之蓝',spec:'45° 500ml×6',cat:'浓香型',batch:'20260322'},
'洋河 海之蓝':{code:'YH-HZL-42-480',series:'海之蓝',spec:'42° 480ml×6',cat:'浓香型',batch:'20260305'},
'洋河 天之蓝':{code:'YH-TZL-42-480',series:'天之蓝',spec:'42° 480ml×6',cat:'浓香型',batch:'20260318'},
'泸州老窖 特曲':{code:'LZLJ-TQ-52-500',series:'特曲',spec:'52° 500ml×6',cat:'浓香型',batch:'20260415'},
'泸州老窖 头曲':{code:'LZLJ-TOUQ-52-500',series:'头曲',spec:'52° 500ml×6',cat:'浓香型',batch:'20260401'},
'习酒 窖藏 1988':{code:'XJ-JC-53-500',series:'窖藏',spec:'53° 500ml×6',cat:'酱香型',batch:'20260210'},
'汾酒 青花 20':{code:'FJ-QH20-53-500',series:'青花',spec:'53° 500ml×6',cat:'清香型',batch:'20260506'},
'汾酒 老白汾':{code:'FJ-LBF-53-475',series:'老白汾',spec:'53° 475ml×6',cat:'清香型',batch:'20260429'},
'郎酒 红花郎 15':{code:'LJ-HHL15-53-500',series:'红花郎',spec:'53° 500ml×6',cat:'酱香型',batch:'20260118'},
'古井贡 年份原浆':{code:'GJG-NF-50-500',series:'年份原浆',spec:'50° 500ml×6',cat:'浓香型',batch:'20260512'},
'古井贡 古5':{code:'GJG-G5-50-500',series:'古5',spec:'50° 500ml×6',cat:'浓香型',batch:'20260508'},
'西凤酒 旗舰版':{code:'XF-QJ-52-500',series:'旗舰',spec:'52° 500ml×6',cat:'凤香型',batch:'20260325'},
'水井坊 井台':{code:'SJF-JT-52-500',series:'井台',spec:'52° 500ml×6',cat:'浓香型',batch:'20260430'},
'茅台 飞天 53°':{code:'MT-FT-53-500',series:'飞天',spec:'53° 500ml×6',cat:'酱香型',pdate:'2021-09-12',batch:'20260518'},
'茅台 1935':{code:'MT-1935-53-500',series:'1935',spec:'53° 500ml×6',cat:'酱香型',pdate:'2020-05-03',batch:'20260420'},
'茅台 王子酒':{code:'MT-WZ-53-500',series:'王子',spec:'53° 500ml×6',cat:'酱香型',pdate:'2022-01-18',batch:'20260512'},
'五粮液 普五 52°':{code:'WLY-P8-52-500',series:'第八代',spec:'52° 500ml×6',cat:'浓香型',pdate:'2021-11-06',batch:'20260408'},
'五粮液 1618':{code:'WLY-1618-52-500',series:'1618',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-03-22',batch:'20260316'},
'剑南春 水晶剑':{code:'JNC-SJ-52-500',series:'水晶剑',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-07-15',batch:'20260502'},
'剑南春 珍藏级':{code:'JNC-ZC-52-500',series:'珍藏',spec:'52° 500ml×6',cat:'浓香型',pdate:'2019-10-30',batch:'20260228'},
'国窖 1573':{code:'GJ-1573-52-500',series:'经典装',spec:'52° 500ml×6',cat:'浓香型',pdate:'2021-04-09',batch:'20260410'},
'洋河 梦之蓝 M6':{code:'YH-M6-45-500',series:'梦之蓝',spec:'45° 500ml×6',cat:'浓香型',pdate:'2020-12-01',batch:'20260322'},
'洋河 海之蓝':{code:'YH-HZL-42-480',series:'海之蓝',spec:'42° 480ml×6',cat:'浓香型',pdate:'2022-06-11',batch:'20260305'},
'洋河 天之蓝':{code:'YH-TZL-42-480',series:'天之蓝',spec:'42° 480ml×6',cat:'浓香型',pdate:'2021-08-25',batch:'20260318'},
'泸州老窖 特曲':{code:'LZLJ-TQ-52-500',series:'特曲',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-02-14',batch:'20260415'},
'泸州老窖 头曲':{code:'LZLJ-TOUQ-52-500',series:'头曲',spec:'52° 500ml×6',cat:'浓香型',pdate:'2022-05-19',batch:'20260401'},
'习酒 窖藏 1988':{code:'XJ-JC-53-500',series:'窖藏',spec:'53° 500ml×6',cat:'酱香型',pdate:'2019-11-03',batch:'20260210'},
'汾酒 青花 20':{code:'FJ-QH20-53-500',series:'青花',spec:'53° 500ml×6',cat:'清香型',pdate:'2021-01-27',batch:'20260506'},
'汾酒 老白汾':{code:'FJ-LBF-53-475',series:'老白汾',spec:'53° 475ml×6',cat:'清香型',pdate:'2022-04-08',batch:'20260429'},
'郎酒 红花郎 15':{code:'LJ-HHL15-53-500',series:'红花郎',spec:'53° 500ml×6',cat:'酱香型',pdate:'2018-09-16',batch:'20260118'},
'古井贡 年份原浆':{code:'GJG-NF-50-500',series:'年份原浆',spec:'50° 500ml×6',cat:'浓香型',pdate:'2021-06-30',batch:'20260512'},
'古井贡 古5':{code:'GJG-G5-50-500',series:'古5',spec:'50° 500ml×6',cat:'浓香型',pdate:'2022-08-02',batch:'20260508'},
'西凤酒 旗舰版':{code:'XF-QJ-52-500',series:'旗舰',spec:'52° 500ml×6',cat:'凤香型',pdate:'2021-12-05',batch:'20260325'},
'水井坊 井台':{code:'SJF-JT-52-500',series:'井台',spec:'52° 500ml×6',cat:'浓香型',pdate:'2020-07-22',batch:'20260430'},
};
// ---- 详细搜索模态框 ----
@@ -303,9 +303,9 @@ function auditBtns(o,idx){
return '';
}
function openDetail(idx){ const o=ORDERS[idx]; document.getElementById('dTitle').textContent=o.no;
const GRID='1fr 96px 32px 56px 56px 62px 60px';
let lh=`<div class="lines"><div class="lh" style="grid-template-columns:${GRID}"><span>商品 · 编码</span><span>系列 / 规格</span><span style="text-align:right">数量</span><span style="text-align:right">成本价</span><span style="text-align:right">售价</span><span style="text-align:right">总售价</span><span style="text-align:right">利润</span></div>`;
o.lines.forEach(l=>{ const pi=PINFO[l.name]||{}; const cost=l.cost!=null?l.cost:Math.round((l.price||0)*0.85); const pend=(l.price||0)<=0; const saleC=pend?'<span class="pending-price">待定价</span>':numf(l.price); const profit=(l.price-cost)*l.qty; const profitC=pend?'<span class="pending-price">待定价</span>':`<span style="color:${profit<0?'var(--danger)':'var(--success)'}">${numf(profit)}</span>`; lh+=`<div class="lr" style="grid-template-columns:${GRID};align-items:start"><span class="lcell"><span class="ln">${l.name}</span><span class="lcode">${pi.code||'—'}</span></span><span class="lcell"><span class="lser">${pi.series||'—'}</span><span class="lspec">${pi.spec||''}</span></span><span style="text-align:right;font-family:var(--font-mono)">${l.qty}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${numf(cost)}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${saleC}</span><span class="amt" style="font-size:var(--fs-sm)">${pend?'<span class="pending-price">待定价</span>':numf(l.qty*l.price)}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${profitC}</span></div>`; }); lh+='</div>';
const GRID='1fr 96px 72px 32px 56px 56px 62px 60px';
let lh=`<div class="lines"><div class="lh" style="grid-template-columns:${GRID}"><span>商品 · 编码</span><span>系列 / 规格</span><span>生产日期 / 批次号</span><span style="text-align:right">数量</span><span style="text-align:right">成本价</span><span style="text-align:right">售价</span><span style="text-align:right">总售价</span><span style="text-align:right">利润</span></div>`;
o.lines.forEach(l=>{ const pi=PINFO[l.name]||{}; const cost=l.cost!=null?l.cost:Math.round((l.price||0)*0.85); const pend=(l.price||0)<=0; const saleC=pend?'<span class="pending-price">待定价</span>':numf(l.price); const profit=(l.price-cost)*l.qty; const profitC=pend?'<span class="pending-price">待定价</span>':`<span style="color:${profit<0?'var(--danger)':'var(--success)'}">${numf(profit)}</span>`; lh+=`<div class="lr" style="grid-template-columns:${GRID};align-items:start"><span class="lcell"><span class="ln">${l.name}</span><span class="lcode">${pi.code||'—'}</span></span><span class="lcell"><span class="lser">${pi.series||'—'}</span><span class="lspec">${pi.spec||''}</span></span><span class="lcell"><span class="lpdate">${pi.pdate||'—'}</span><span class="lbatch">${pi.batch||'—'}</span></span><span style="text-align:right;font-family:var(--font-mono)">${l.qty}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${numf(cost)}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${saleC}</span><span class="amt" style="font-size:var(--fs-sm)">${pend?'<span class="pending-price">待定价</span>':numf(l.qty*l.price)}</span><span style="text-align:right;font-family:var(--font-mono);font-size:var(--fs-sm)">${profitC}</span></div>`; }); lh+='</div>';
const pendCount=o.lines.filter(l=>(l.price||0)<=0).length;
const auditor=o.auditor?o.auditor:'<span style="color:var(--faint)"></span>';
document.getElementById('drawerBody').innerHTML=`<div class="drow"><span>单据日期</span><b>${o.date}</b></div><div class="drow"><span>${PARTY_LABEL}</span><b>${o.party}</b></div><div class="drow"><span>仓库</span><b>${o.wh}</b></div><div class="drow"><span>商品数</span><b>${o.count}</b></div><div class="drow"><span>出库员</span><b>${o.op}</b></div><div class="drow"><span>审核员</span><b>${auditor}</b></div><div class="drow"><span>状态</span><b>${stBadge(o.status)}${o.ret?' '+stBadge(o.ret):''}</b></div><label style="display:block;font-size:var(--fs-sm);color:var(--muted);margin:16px 0 8px;">出库明细</label>${lh}<div class="ltotal">合计金额 <b>${money(o.amount)}</b></div><div class="ltotal" style="padding-top:4px">合计利润 <b style="color:var(--success)">${money(o.lines.reduce((s,l)=>{const c=l.cost!=null?l.cost:Math.round((l.price||0)*0.85);return s+((l.price||0)>0?((l.price-c)*l.qty):0);},0))}</b></div>`+