2024-06-18 16:52:17 +08:00
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'package:async/async.dart';
|
2024-06-17 17:28:54 +08:00
|
|
|
import 'package:dio/dio.dart';
|
2024-06-20 10:06:05 +08:00
|
|
|
import 'package:flutter/cupertino.dart';
|
2024-06-14 17:22:52 +08:00
|
|
|
import 'package:flutter/material.dart';
|
2024-06-18 16:52:17 +08:00
|
|
|
import 'package:flutter/services.dart';
|
2024-06-17 17:28:54 +08:00
|
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import 'package:logistics_tools/utils/request.dart';
|
2024-06-18 16:52:17 +08:00
|
|
|
import 'package:uuid/uuid.dart';
|
2024-06-14 17:22:52 +08:00
|
|
|
|
|
|
|
class Logistics extends StatefulWidget {
|
|
|
|
const Logistics({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<Logistics> createState() => _LogisticsState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _LogisticsState extends State<Logistics> {
|
2024-06-17 17:28:54 +08:00
|
|
|
List<dynamic> goodsList = [];
|
2024-06-18 16:52:17 +08:00
|
|
|
String _orderPayWay = "";
|
2024-06-20 10:06:05 +08:00
|
|
|
|
|
|
|
// String _logistics = "";
|
2024-06-18 16:52:17 +08:00
|
|
|
List _packages = [];
|
2024-06-20 10:06:05 +08:00
|
|
|
bool _packageInit = false;
|
2024-06-18 16:52:17 +08:00
|
|
|
int _activePackage = 0;
|
|
|
|
final TextEditingController _goodsNameController =
|
|
|
|
TextEditingController(text: "");
|
|
|
|
final TextEditingController _goodsSpecController =
|
|
|
|
TextEditingController(text: "");
|
|
|
|
final TextEditingController _goodsNumController = TextEditingController();
|
|
|
|
final _memoizer = AsyncMemoizer();
|
2024-06-17 17:28:54 +08:00
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
// TODO: implement initState
|
|
|
|
super.initState();
|
2024-06-18 16:52:17 +08:00
|
|
|
setState(() {
|
|
|
|
_packages = [
|
|
|
|
{"id": const Uuid().v4(), "logisticsNumber": "", "goods": []}
|
|
|
|
];
|
|
|
|
});
|
2024-06-17 17:28:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<Response> fetchGoodsList(BuildContext context) async {
|
|
|
|
String? orderNumber =
|
|
|
|
GoRouterState.of(context).uri.queryParameters["orderNumber"];
|
|
|
|
String? orderPayWay =
|
|
|
|
GoRouterState.of(context).uri.queryParameters["orderPayWay"];
|
2024-06-20 10:06:05 +08:00
|
|
|
String? logistics =
|
|
|
|
GoRouterState.of(context).uri.queryParameters["logistics"];
|
2024-06-18 16:52:17 +08:00
|
|
|
_orderPayWay = orderPayWay!;
|
|
|
|
|
2024-06-17 17:28:54 +08:00
|
|
|
if (orderNumber?.isEmpty ?? true) {
|
|
|
|
context.pop();
|
|
|
|
}
|
2024-06-18 16:52:17 +08:00
|
|
|
Response response = await _memoizer.runOnce(() async {
|
|
|
|
return await dio.get(
|
|
|
|
"https://www.sanpinhuicai.com/wisdommining/api/order/goodsOfOrder",
|
|
|
|
queryParameters: {"orderNumber": orderNumber});
|
|
|
|
});
|
2024-06-17 17:28:54 +08:00
|
|
|
goodsList = response.data["value"];
|
2024-06-20 10:06:05 +08:00
|
|
|
|
|
|
|
if (logistics != null && logistics.isNotEmpty && !_packageInit) {
|
|
|
|
try {
|
|
|
|
List packages = jsonDecode(logistics);
|
|
|
|
|
|
|
|
_packages = packages;
|
|
|
|
|
|
|
|
if (_orderPayWay != "套餐商品") {
|
|
|
|
for (var p in _packages) {
|
|
|
|
p["goods"].forEach((g) {
|
|
|
|
var targetGoods = goodsList
|
|
|
|
.firstWhere((tg) => g["id"] == tg["id"], orElse: () => null);
|
|
|
|
if (targetGoods != null) {
|
|
|
|
targetGoods["goodsNum"] -= g["num"];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_packageInit = true;
|
|
|
|
} catch (e) {
|
|
|
|
e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-17 17:28:54 +08:00
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2024-06-14 17:22:52 +08:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
2024-06-18 16:52:17 +08:00
|
|
|
title: Text(
|
|
|
|
"填写物流信息 (${GoRouterState.of(context).uri.queryParameters["orderPayWay"]})"),
|
|
|
|
actions: [
|
|
|
|
ElevatedButton(
|
|
|
|
onPressed: () {
|
|
|
|
// 数据验证
|
|
|
|
if (_orderPayWay != "套餐商品") {
|
|
|
|
bool hasUnAddedGoods =
|
|
|
|
goodsList.every((el) => el["goodsNum"] > 0);
|
|
|
|
if (hasUnAddedGoods) {
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
|
|
|
content: Text("有未添加至包裹的商品"),
|
2024-06-20 10:06:05 +08:00
|
|
|
showCloseIcon: true,
|
2024-06-18 16:52:17 +08:00
|
|
|
backgroundColor: Colors.redAccent,
|
|
|
|
));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool result = _packages.every((package) {
|
|
|
|
return package["logisticsNumber"].toString().isNotEmpty &&
|
|
|
|
package["goods"].length > 0 &&
|
|
|
|
package["goods"].every((goods) {
|
|
|
|
return goods["name"].toString().isNotEmpty &&
|
|
|
|
goods["num"].toString().isNotEmpty &&
|
|
|
|
goods["spec"].toString().isNotEmpty;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (!result) {
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
|
|
|
backgroundColor: Colors.redAccent,
|
2024-06-20 10:06:05 +08:00
|
|
|
showCloseIcon: true,
|
2024-06-18 16:52:17 +08:00
|
|
|
content: Text("有未填写的数据")));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
String logisticsJson = jsonEncode(_packages);
|
|
|
|
context.pop(logisticsJson);
|
|
|
|
},
|
|
|
|
child: const Row(
|
|
|
|
children: [Text("保存"), Icon(Icons.save)],
|
|
|
|
)),
|
|
|
|
const SizedBox(
|
|
|
|
width: 4,
|
|
|
|
)
|
|
|
|
],
|
2024-06-14 17:22:52 +08:00
|
|
|
),
|
|
|
|
body: Container(
|
2024-06-17 17:28:54 +08:00
|
|
|
padding: const EdgeInsets.all(40),
|
|
|
|
width: double.infinity,
|
|
|
|
child: FutureBuilder(
|
|
|
|
future: fetchGoodsList(context),
|
2024-06-18 16:52:17 +08:00
|
|
|
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
|
2024-06-17 17:28:54 +08:00
|
|
|
if (snapshot.hasData) {
|
|
|
|
return Card(
|
|
|
|
color: Colors.white,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(20),
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
flex: 1,
|
2024-06-18 16:52:17 +08:00
|
|
|
child: _orderPayWay == "套餐商品"
|
|
|
|
? Column(
|
|
|
|
children: [
|
|
|
|
Card(
|
|
|
|
color: Colors.white70,
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
Image.network(
|
|
|
|
width: 80,
|
|
|
|
height: 80,
|
|
|
|
goodsList[0]["goodsPhoto"]),
|
|
|
|
const SizedBox(
|
|
|
|
width: 16,
|
|
|
|
),
|
|
|
|
Text(
|
|
|
|
"${goodsList[0]["goodsName"]}")
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 20,
|
|
|
|
),
|
|
|
|
TextField(
|
|
|
|
controller: _goodsNameController,
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
labelText: "商品名称",
|
|
|
|
border: OutlineInputBorder()),
|
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 20,
|
|
|
|
),
|
|
|
|
TextField(
|
|
|
|
controller: _goodsSpecController,
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
labelText: "商品规格",
|
|
|
|
border: OutlineInputBorder()),
|
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 20,
|
|
|
|
),
|
|
|
|
TextField(
|
|
|
|
controller: _goodsNumController,
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
inputFormatters: <TextInputFormatter>[
|
|
|
|
FilteringTextInputFormatter
|
|
|
|
.digitsOnly
|
|
|
|
],
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
labelText: "商品数量",
|
|
|
|
border: OutlineInputBorder()),
|
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 20,
|
|
|
|
),
|
|
|
|
ElevatedButton(
|
|
|
|
onPressed: () {
|
|
|
|
if (_goodsNumController
|
|
|
|
.text.isEmpty ||
|
|
|
|
_goodsNameController
|
|
|
|
.text.isEmpty ||
|
|
|
|
_goodsSpecController
|
|
|
|
.text.isEmpty) {
|
|
|
|
ScaffoldMessenger.of(context)
|
|
|
|
.showSnackBar(
|
|
|
|
const SnackBar(
|
2024-06-20 10:06:05 +08:00
|
|
|
content: Text("请填写完整商品信息"),
|
|
|
|
showCloseIcon: true,
|
|
|
|
));
|
2024-06-18 16:52:17 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
int goodsNum = int.parse(
|
|
|
|
_goodsNumController.text);
|
|
|
|
String goodsName =
|
|
|
|
_goodsNameController.text;
|
|
|
|
String goodsSpec =
|
|
|
|
_goodsSpecController.text;
|
|
|
|
var goods = {
|
|
|
|
"id": const Uuid().v4(),
|
|
|
|
"name": goodsName,
|
|
|
|
"num": goodsNum,
|
|
|
|
"specId": const Uuid().v4(),
|
|
|
|
"spec": goodsSpec
|
|
|
|
};
|
|
|
|
var packagesList = _packages;
|
|
|
|
|
|
|
|
packagesList[_activePackage]
|
|
|
|
["goods"]
|
|
|
|
.add(goods);
|
|
|
|
setState(() {
|
|
|
|
_packages = packagesList;
|
|
|
|
});
|
|
|
|
_goodsNumController.clear();
|
|
|
|
_goodsNameController.clear();
|
|
|
|
_goodsSpecController.clear();
|
|
|
|
},
|
|
|
|
child: const Text("添加到包裹"))
|
|
|
|
],
|
|
|
|
)
|
2024-06-20 10:06:05 +08:00
|
|
|
: goodsList
|
2024-06-18 16:52:17 +08:00
|
|
|
.where((el) => el["goodsNum"] > 0)
|
2024-06-20 10:06:05 +08:00
|
|
|
.isNotEmpty
|
|
|
|
? ListView.builder(
|
|
|
|
itemCount: goodsList
|
|
|
|
.where(
|
|
|
|
(el) => el["goodsNum"] > 0)
|
|
|
|
.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
final goods = goodsList
|
|
|
|
.where((el) =>
|
|
|
|
el["goodsNum"] > 0)
|
|
|
|
.toList()[index];
|
|
|
|
return ListTile(
|
|
|
|
trailing: IconButton(
|
|
|
|
icon: const Icon(Icons.add),
|
|
|
|
onPressed: () {
|
|
|
|
// 检查商品及规格是否已存在于目标包裹
|
|
|
|
int targetIndex = _packages[
|
|
|
|
_activePackage]
|
2024-06-18 16:52:17 +08:00
|
|
|
["goods"]
|
2024-06-20 10:06:05 +08:00
|
|
|
.indexWhere((el) =>
|
|
|
|
el["id"] ==
|
|
|
|
goods["id"] &&
|
|
|
|
goods["wisdGoodsSpec"]
|
|
|
|
["id"] ==
|
|
|
|
el["specId"]);
|
|
|
|
if (targetIndex != -1) {
|
|
|
|
setState(() {
|
|
|
|
_packages[_activePackage]
|
|
|
|
["goods"]
|
|
|
|
[targetIndex]
|
|
|
|
["num"] += 1;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
setState(() {
|
|
|
|
_packages[_activePackage]
|
|
|
|
["goods"]
|
|
|
|
.add({
|
|
|
|
"id": goods["id"],
|
|
|
|
"specId": goods[
|
|
|
|
"wisdGoodsSpec"]
|
2024-06-18 16:52:17 +08:00
|
|
|
["id"],
|
2024-06-20 10:06:05 +08:00
|
|
|
"name": goods[
|
|
|
|
"goodsName"],
|
|
|
|
"spec": goods?[
|
|
|
|
"wisdGoodsSpec"]
|
2024-06-18 16:52:17 +08:00
|
|
|
?[
|
|
|
|
"specName"] ??
|
|
|
|
"",
|
2024-06-20 10:06:05 +08:00
|
|
|
"num": 1
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
var curGoods =
|
|
|
|
goodsList.firstWhere(
|
|
|
|
(el) =>
|
|
|
|
el["id"] ==
|
|
|
|
goods["id"],
|
|
|
|
orElse: () => -1);
|
2024-06-18 16:52:17 +08:00
|
|
|
|
2024-06-20 10:06:05 +08:00
|
|
|
setState(() {
|
|
|
|
curGoods["goodsNum"] -= 1;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
leading: Image.network(
|
|
|
|
goods["goodsPhoto"],
|
|
|
|
width: 100,
|
|
|
|
height: 100,
|
|
|
|
),
|
|
|
|
title: Text(
|
|
|
|
"${goods["goodsName"]} - ${goods?["wisdGoodsSpec"]?["specName"] ?? ''}"),
|
|
|
|
subtitle: Text(
|
|
|
|
"数量 : ${goods?["goodsNum"]}"),
|
|
|
|
);
|
|
|
|
})
|
|
|
|
: const Center(
|
|
|
|
child: Icon(
|
|
|
|
CupertinoIcons.circle,
|
|
|
|
size: 36,
|
2024-06-18 16:52:17 +08:00
|
|
|
),
|
2024-06-20 10:06:05 +08:00
|
|
|
)),
|
2024-06-18 16:52:17 +08:00
|
|
|
const SizedBox(
|
|
|
|
width: 20,
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
flex: 1,
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: ListView.builder(
|
|
|
|
itemCount: _packages.length,
|
|
|
|
itemBuilder:
|
|
|
|
(BuildContext context, int index) {
|
|
|
|
return PackageCard(
|
2024-06-20 10:06:05 +08:00
|
|
|
logisticsNumber: _packages[index]
|
|
|
|
["logisticsNumber"],
|
|
|
|
onDeleteGoods: (goods) {
|
|
|
|
if (goods["num"] == 1) {
|
|
|
|
setState(() {
|
|
|
|
_packages[index]["goods"] =
|
|
|
|
_packages[index]["goods"]
|
|
|
|
.where((el) =>
|
|
|
|
el["id"] !=
|
|
|
|
goods["id"])
|
|
|
|
.toList();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
setState(() {
|
|
|
|
goods["num"] -= 1;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (_orderPayWay != "套餐商品") {
|
|
|
|
setState(() {
|
|
|
|
goodsList.firstWhere(
|
|
|
|
(e) =>
|
|
|
|
goods["id"] ==
|
|
|
|
e["id"],
|
|
|
|
orElse: () => null)?[
|
|
|
|
"goodsNum"] += 1;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2024-06-18 17:18:35 +08:00
|
|
|
onLogisticsChanged: (value) {
|
|
|
|
_packages[index]
|
|
|
|
["logisticsNumber"] = value;
|
|
|
|
},
|
2024-06-20 10:06:05 +08:00
|
|
|
orderPayWay: _orderPayWay,
|
2024-06-18 17:18:35 +08:00
|
|
|
onTap: () {
|
|
|
|
setState(() {
|
|
|
|
_activePackage = index;
|
|
|
|
});
|
|
|
|
},
|
2024-06-18 17:26:27 +08:00
|
|
|
onClose: () {
|
|
|
|
var curId =
|
|
|
|
_packages[index]["id"];
|
2024-06-20 10:06:05 +08:00
|
|
|
if (_orderPayWay != "套餐商品") {
|
|
|
|
_packages[index]["goods"]
|
|
|
|
.forEach((el) {
|
|
|
|
var targetGoods =
|
|
|
|
goodsList.firstWhere(
|
|
|
|
(goodsItem) =>
|
|
|
|
goodsItem["id"] ==
|
|
|
|
el["id"],
|
|
|
|
orElse: () => -1);
|
|
|
|
if (targetGoods != -1) {
|
|
|
|
setState(() {
|
|
|
|
targetGoods["goodsNum"] +=
|
|
|
|
el["num"];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2024-06-18 17:26:27 +08:00
|
|
|
setState(() {
|
|
|
|
_activePackage =
|
|
|
|
_activePackage >= index
|
|
|
|
? _activePackage - 1
|
|
|
|
: _activePackage;
|
|
|
|
_packages = _packages
|
|
|
|
.where((el) =>
|
|
|
|
el["id"] != curId)
|
|
|
|
.toList();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
totalPackagesCount:
|
|
|
|
_packages.length,
|
2024-06-18 17:18:35 +08:00
|
|
|
isActive: _activePackage == index,
|
|
|
|
package: _packages[index],
|
|
|
|
index: index);
|
2024-06-18 16:52:17 +08:00
|
|
|
},
|
|
|
|
)),
|
|
|
|
ElevatedButton(
|
|
|
|
onPressed: () {
|
|
|
|
setState(() {
|
|
|
|
_packages = [
|
|
|
|
..._packages,
|
|
|
|
{
|
|
|
|
"logisticsNumber": "",
|
|
|
|
"id": const Uuid().v4(),
|
|
|
|
"goods": []
|
|
|
|
}
|
|
|
|
];
|
2024-06-20 10:06:05 +08:00
|
|
|
_activePackage += 1;
|
2024-06-18 16:52:17 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
child: const Text("添加包裹"))
|
|
|
|
],
|
|
|
|
))
|
2024-06-17 17:28:54 +08:00
|
|
|
],
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
} else if (snapshot.hasError) {
|
|
|
|
return const Center(
|
2024-06-20 10:06:05 +08:00
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.error_outline,
|
|
|
|
color: Colors.red,
|
|
|
|
size: 60,
|
|
|
|
),
|
|
|
|
],
|
2024-06-14 17:22:52 +08:00
|
|
|
),
|
2024-06-17 17:28:54 +08:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return const Center(child: CircularProgressIndicator());
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)));
|
2024-06-14 17:22:52 +08:00
|
|
|
}
|
|
|
|
}
|
2024-06-18 16:52:17 +08:00
|
|
|
|
|
|
|
class PackageCard extends StatefulWidget {
|
|
|
|
const PackageCard({
|
|
|
|
super.key,
|
|
|
|
required this.onTap,
|
|
|
|
required this.isActive,
|
|
|
|
required this.package,
|
|
|
|
required this.index,
|
|
|
|
required this.onLogisticsChanged,
|
2024-06-18 17:26:27 +08:00
|
|
|
required this.totalPackagesCount,
|
|
|
|
required this.onClose,
|
2024-06-20 10:06:05 +08:00
|
|
|
required this.orderPayWay,
|
|
|
|
required this.onDeleteGoods,
|
|
|
|
required this.logisticsNumber,
|
2024-06-18 16:52:17 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
final bool isActive;
|
|
|
|
final Function() onTap;
|
2024-06-18 17:26:27 +08:00
|
|
|
final Function() onClose;
|
2024-06-20 10:06:05 +08:00
|
|
|
final Function(Map<String, dynamic> goods) onDeleteGoods;
|
2024-06-18 16:52:17 +08:00
|
|
|
final Map<String, dynamic> package;
|
|
|
|
final int index;
|
|
|
|
final Function(String) onLogisticsChanged;
|
2024-06-18 17:26:27 +08:00
|
|
|
final int totalPackagesCount;
|
2024-06-20 10:06:05 +08:00
|
|
|
final String orderPayWay;
|
|
|
|
final String logisticsNumber;
|
2024-06-18 16:52:17 +08:00
|
|
|
|
|
|
|
@override
|
|
|
|
State<PackageCard> createState() => _PackageCardState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _PackageCardState extends State<PackageCard> {
|
2024-06-20 10:06:05 +08:00
|
|
|
final TextEditingController _logisticsController = TextEditingController();
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
// TODO: implement initState
|
|
|
|
super.initState();
|
|
|
|
_logisticsController.text = widget.logisticsNumber;
|
|
|
|
}
|
|
|
|
|
2024-06-18 16:52:17 +08:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return GestureDetector(
|
|
|
|
onTap: widget.onTap,
|
|
|
|
child: Card(
|
|
|
|
elevation: widget.isActive ? 5 : null,
|
|
|
|
shape: widget.isActive
|
|
|
|
? RoundedRectangleBorder(
|
|
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
|
|
side: const BorderSide(
|
|
|
|
color: Colors.blue,
|
|
|
|
width: 1.0,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
: null,
|
|
|
|
child: Stack(
|
|
|
|
// clipBehavior: Clip.none,
|
|
|
|
children: [
|
|
|
|
const SizedBox(
|
|
|
|
height: 100,
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.fromLTRB(20, 30, 20, 20),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
children: [
|
|
|
|
TextField(
|
2024-06-20 10:06:05 +08:00
|
|
|
controller: _logisticsController,
|
2024-06-18 16:52:17 +08:00
|
|
|
onChanged: widget.onLogisticsChanged,
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
border: OutlineInputBorder(), labelText: "物流单号"),
|
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 20,
|
|
|
|
),
|
|
|
|
DataTable(columns: const [
|
|
|
|
DataColumn(label: Text("名称")),
|
|
|
|
DataColumn(label: Text("规格")),
|
2024-06-20 10:06:05 +08:00
|
|
|
DataColumn(label: Text("数量")),
|
|
|
|
DataColumn(label: Text("操作"))
|
2024-06-18 16:52:17 +08:00
|
|
|
], rows: [
|
2024-06-20 10:06:05 +08:00
|
|
|
for (var goodsItem
|
|
|
|
in widget.package["goods"].asMap().entries)
|
2024-06-18 16:52:17 +08:00
|
|
|
DataRow(cells: [
|
2024-06-20 10:06:05 +08:00
|
|
|
DataCell(Text("${goodsItem.value["name"]}")),
|
|
|
|
DataCell(Text("${goodsItem.value["spec"]}")),
|
|
|
|
DataCell(Text("${goodsItem.value["num"]}")),
|
|
|
|
DataCell(SizedBox(
|
|
|
|
width: 24,
|
|
|
|
height: 24,
|
|
|
|
child: IconButton(
|
|
|
|
icon: const Icon(CupertinoIcons.delete),
|
|
|
|
iconSize: 16,
|
|
|
|
padding: const EdgeInsets.all(4),
|
|
|
|
onPressed: () {
|
|
|
|
widget.onDeleteGoods(goodsItem.value);
|
|
|
|
}),
|
|
|
|
)),
|
2024-06-18 16:52:17 +08:00
|
|
|
])
|
|
|
|
]),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Positioned(
|
|
|
|
left: 20,
|
|
|
|
top: 2,
|
|
|
|
child: Text("包裹${widget.index + 1}"),
|
|
|
|
),
|
2024-06-18 17:26:27 +08:00
|
|
|
widget.totalPackagesCount > 1
|
|
|
|
? Positioned(
|
|
|
|
top: 2,
|
|
|
|
right: 2,
|
|
|
|
child: SizedBox(
|
|
|
|
width: 20,
|
|
|
|
height: 20,
|
|
|
|
child: IconButton(
|
|
|
|
color: Colors.redAccent,
|
|
|
|
iconSize: 20,
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
icon: const Icon(Icons.close),
|
|
|
|
onPressed: widget.onClose,
|
|
|
|
),
|
|
|
|
))
|
|
|
|
: const SizedBox(
|
|
|
|
width: 0,
|
|
|
|
)
|
2024-06-18 16:52:17 +08:00
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|