2025-02-19 18:52:05 +08:00
|
|
|
|
import 'dart:convert';
|
2025-02-24 15:52:03 +08:00
|
|
|
|
import 'dart:ffi';
|
2025-02-19 18:52:05 +08:00
|
|
|
|
|
|
|
|
|
|
import 'package:bruno/bruno.dart';
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
2025-02-23 16:19:27 +08:00
|
|
|
|
import 'package:uuid/uuid.dart';
|
2025-02-19 18:52:05 +08:00
|
|
|
|
import 'package:wms_app/api_client/stock_in.dart';
|
|
|
|
|
|
import 'package:wms_app/component/card/stock_in_card_xugong.dart';
|
|
|
|
|
|
import 'package:wms_app/model/bo/stock_in_data_xugong.dart';
|
|
|
|
|
|
import '../../common/colorCom.dart';
|
|
|
|
|
|
import '../../utils/dialogUtils.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class StockInNormal extends StatefulWidget {
|
|
|
|
|
|
const StockInNormal({super.key});
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
State<StockInNormal> createState() => _StockInNormalState();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 通用普通码盘界面
|
|
|
|
|
|
class _StockInNormalState extends State<StockInNormal> {
|
2025-02-23 16:19:27 +08:00
|
|
|
|
Uuid uuidGen = Uuid();
|
2025-02-19 18:52:05 +08:00
|
|
|
|
|
|
|
|
|
|
final _vehicleTextController = TextEditingController(); // 载具号输入框
|
|
|
|
|
|
final _goodsCodeController = TextEditingController(); // 条码输入框
|
2025-02-23 16:19:27 +08:00
|
|
|
|
final _goodsNumController = BrnStepsController();
|
2025-02-24 15:52:03 +08:00
|
|
|
|
final _listIdController = TextEditingController();
|
2025-02-23 16:19:27 +08:00
|
|
|
|
final _orderTypeController = TextEditingController();
|
2025-02-24 15:52:03 +08:00
|
|
|
|
final _customerNameController = TextEditingController();
|
2025-02-23 16:19:27 +08:00
|
|
|
|
final _goodsDescController = TextEditingController();
|
2025-02-24 15:52:03 +08:00
|
|
|
|
final _goodsUnitController = TextEditingController();
|
2025-02-23 16:19:27 +08:00
|
|
|
|
final _weightController = TextEditingController();
|
|
|
|
|
|
final _sizeController = TextEditingController();
|
|
|
|
|
|
final _spare1Controller = TextEditingController();
|
|
|
|
|
|
final _spare2Controller = TextEditingController();
|
|
|
|
|
|
|
2025-02-19 18:52:05 +08:00
|
|
|
|
int goodsNum = 1; // 物料数量
|
|
|
|
|
|
|
|
|
|
|
|
List<StockInDataXuGong> stockInDataXuGong = [];
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
|
return Scaffold(
|
|
|
|
|
|
appBar: AppBar(
|
|
|
|
|
|
iconTheme: const IconThemeData(color: Colors.white),
|
2025-02-24 15:52:03 +08:00
|
|
|
|
leading: IconButton(
|
|
|
|
|
|
onPressed: () {
|
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
|
},
|
|
|
|
|
|
icon: const Icon(Icons.arrow_back)),
|
2025-02-19 18:52:05 +08:00
|
|
|
|
centerTitle: true,
|
|
|
|
|
|
backgroundColor: ColorCommon.colorScheme,
|
|
|
|
|
|
title: const Text(
|
|
|
|
|
|
"其他物料入库",
|
|
|
|
|
|
style: TextStyle(color: Colors.white),
|
|
|
|
|
|
),
|
|
|
|
|
|
actions: [
|
2025-02-24 15:52:03 +08:00
|
|
|
|
TextButton(
|
|
|
|
|
|
onPressed: () {},
|
2025-02-23 16:19:27 +08:00
|
|
|
|
style: const ButtonStyle(
|
|
|
|
|
|
foregroundColor: WidgetStatePropertyAll(Colors.white)),
|
2025-02-24 15:52:03 +08:00
|
|
|
|
child: const Text("清空"),
|
|
|
|
|
|
)
|
2025-02-19 18:52:05 +08:00
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
body: Center(
|
2025-02-23 16:19:27 +08:00
|
|
|
|
child: Padding(
|
|
|
|
|
|
padding: const EdgeInsets.only(top: 5, left: 10, right: 10),
|
2025-02-19 18:52:05 +08:00
|
|
|
|
child: ListView(
|
2025-02-23 16:19:27 +08:00
|
|
|
|
children: [
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _goodsCodeController,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "物料号:",
|
|
|
|
|
|
hint: "请输入或扫描物料号",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnStepInputFormItem(
|
|
|
|
|
|
title: "物料数量:",
|
|
|
|
|
|
minLimit: 1,
|
|
|
|
|
|
value: goodsNum,
|
|
|
|
|
|
maxLimit: 9999,
|
|
|
|
|
|
isRequire: true,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
canManualInput: true,
|
|
|
|
|
|
onChanged: (newValue, _) {
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
goodsNum = newValue;
|
|
|
|
|
|
});
|
|
|
|
|
|
}),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
BrnTextInputFormItem(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
controller: _listIdController,
|
|
|
|
|
|
title: "单据号:",
|
|
|
|
|
|
hint: "请输入或扫描单据号",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _orderTypeController,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "单据类型:",
|
|
|
|
|
|
hint: "请输入或扫描单据类型",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
controller: _customerNameController,
|
|
|
|
|
|
title: "客户名称:",
|
|
|
|
|
|
hint: "请输入或扫描客户名称",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _goodsDescController,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "物料描述:",
|
|
|
|
|
|
hint: "请输入或扫描物料描述",
|
|
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _goodsUnitController,
|
|
|
|
|
|
title: "物料单位:",
|
|
|
|
|
|
hint: "请输入物料单位",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _weightController,
|
|
|
|
|
|
title: "重量:",
|
|
|
|
|
|
hint: "仅支持数字(保留小数点四位)",
|
|
|
|
|
|
isRequire: true,
|
|
|
|
|
|
unit: "KG",
|
2025-02-19 18:52:05 +08:00
|
|
|
|
),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _sizeController,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "尺寸:",
|
|
|
|
|
|
hint: "请输入或扫描尺寸",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
2025-02-19 18:52:05 +08:00
|
|
|
|
),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _spare1Controller,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "备用1:",
|
|
|
|
|
|
hint: "请输入",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
BrnTextInputFormItem(
|
|
|
|
|
|
controller: _spare2Controller,
|
2025-02-24 15:52:03 +08:00
|
|
|
|
title: "备用2:",
|
|
|
|
|
|
hint: "请输入",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
|
|
|
|
|
ElevatedButton(
|
|
|
|
|
|
onPressed: resolveCode,
|
|
|
|
|
|
style: ButtonStyle(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
backgroundColor:
|
2025-02-25 16:50:15 +08:00
|
|
|
|
WidgetStateProperty.all(ColorCommon.colorScheme),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
),
|
2025-02-24 15:52:03 +08:00
|
|
|
|
child: const Text("添加物料",
|
|
|
|
|
|
style: TextStyle(color: Colors.white))),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
BrnTextInputFormItem(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
controller: _vehicleTextController,
|
|
|
|
|
|
title: "容器号:",
|
|
|
|
|
|
hint: "",
|
2025-02-23 16:19:27 +08:00
|
|
|
|
isRequire: true,
|
|
|
|
|
|
),
|
2025-02-24 15:52:03 +08:00
|
|
|
|
Padding(
|
|
|
|
|
|
padding: const EdgeInsets.only(top: 0),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
child: ElevatedButton(
|
|
|
|
|
|
onPressed: wheelComplete,
|
|
|
|
|
|
style: ButtonStyle(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
backgroundColor:
|
2025-02-25 16:50:15 +08:00
|
|
|
|
WidgetStateProperty.all(ColorCommon.colorScheme),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
),
|
2025-02-24 15:52:03 +08:00
|
|
|
|
child: const Text("码盘完成",
|
|
|
|
|
|
style: TextStyle(color: Colors.white)))),
|
|
|
|
|
|
const Padding(
|
|
|
|
|
|
padding: EdgeInsets.only(top: 10, bottom: 10),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
child: Text("添加在载具的物料:"),
|
|
|
|
|
|
),
|
|
|
|
|
|
StockInCardXuGong(stockInDataXuGong: stockInDataXuGong)
|
|
|
|
|
|
],
|
2025-02-19 18:52:05 +08:00
|
|
|
|
)),
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 解析条码
|
|
|
|
|
|
void resolveCode() {
|
|
|
|
|
|
setState(() {
|
2025-02-23 16:19:27 +08:00
|
|
|
|
stockInDataXuGong.add(StockInDataXuGong(
|
2025-02-24 15:52:03 +08:00
|
|
|
|
customerName: _customerNameController.text,
|
|
|
|
|
|
weight: double.parse(_weightController.text),
|
|
|
|
|
|
size: int.parse(_sizeController.text),
|
|
|
|
|
|
unit: _goodsUnitController.text,
|
|
|
|
|
|
listId: _listIdController.text,
|
|
|
|
|
|
orderType: int.parse(_orderTypeController.text),
|
2025-02-23 16:19:27 +08:00
|
|
|
|
goodsNum: goodsNum,
|
|
|
|
|
|
goodsId: _goodsCodeController.text,
|
|
|
|
|
|
goodsDesc: _goodsDescController.text,
|
|
|
|
|
|
spare1: _spare1Controller.text,
|
|
|
|
|
|
spare2: _spare2Controller.text));
|
2025-02-19 18:52:05 +08:00
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void wheelComplete() {
|
2025-02-23 16:19:27 +08:00
|
|
|
|
if (stockInDataXuGong.isEmpty) {
|
2025-02-25 16:50:15 +08:00
|
|
|
|
DialogUtils.showWarningMessage(
|
|
|
|
|
|
context, "警告", "您的码盘数据为空", btnLabel: "确定");
|
2025-02-19 18:52:05 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-02-25 16:00:50 +08:00
|
|
|
|
|
2025-02-24 15:52:03 +08:00
|
|
|
|
String vehicleNo = _vehicleTextController.text;
|
2025-02-19 18:52:05 +08:00
|
|
|
|
int dataCount = stockInDataXuGong.length;
|
2025-02-25 16:00:50 +08:00
|
|
|
|
|
2025-02-23 16:19:27 +08:00
|
|
|
|
DialogUtils.showConfirmMessage(
|
2025-02-25 16:00:50 +08:00
|
|
|
|
context,
|
|
|
|
|
|
"码盘完成",
|
|
|
|
|
|
"载具:$vehicleNo 码盘 $dataCount 条数据,是否继续?",
|
|
|
|
|
|
confirmBtn: "继续",
|
|
|
|
|
|
confirm: () {
|
|
|
|
|
|
int taskType = 1; // 1 表示进库,2 表示进站台
|
|
|
|
|
|
BrnLoadingDialog.show(context, content: "正在请求入库");
|
2025-02-25 16:50:15 +08:00
|
|
|
|
_stockInComplete(vehicleNo).then((isTaskSuccess) {
|
|
|
|
|
|
_dismissLoading();
|
|
|
|
|
|
if (isTaskSuccess) {
|
|
|
|
|
|
_showSuccessDialog("入库成功");
|
|
|
|
|
|
_clearData();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
_showWarningDialog("创建任务失败");
|
2025-02-25 16:00:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).catchError((err) {
|
|
|
|
|
|
_dismissLoading();
|
|
|
|
|
|
_handleError(err);
|
2025-02-19 18:52:05 +08:00
|
|
|
|
});
|
2025-02-25 16:50:15 +08:00
|
|
|
|
});
|
2025-02-25 16:00:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 完成入库请求
|
|
|
|
|
|
Future<bool> _stockInComplete(String vehicleNo) async {
|
|
|
|
|
|
try {
|
2025-02-25 16:50:15 +08:00
|
|
|
|
var response = await StockInApi.stockInComplete(
|
|
|
|
|
|
stockInDataXuGong, vehicleNo);
|
2025-02-25 16:00:50 +08:00
|
|
|
|
if (response["code"] != 200) {
|
|
|
|
|
|
_showWarningDialog("服务器请求失败");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
_handleError(err);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示错误提示
|
|
|
|
|
|
void _handleError(dynamic err) {
|
|
|
|
|
|
var thisContext = context;
|
|
|
|
|
|
if (thisContext.mounted) {
|
|
|
|
|
|
DialogUtils.showErrorMessage(
|
|
|
|
|
|
thisContext,
|
|
|
|
|
|
"请求发生错误",
|
|
|
|
|
|
"请求服务器发生错误:${err.toString()}",
|
|
|
|
|
|
btnLabel: "我知道了"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示成功提示
|
|
|
|
|
|
void _showSuccessDialog(String message) {
|
|
|
|
|
|
var thisContext = context;
|
|
|
|
|
|
if (thisContext.mounted) {
|
|
|
|
|
|
DialogUtils.showSuccessMessage(
|
|
|
|
|
|
thisContext,
|
|
|
|
|
|
message,
|
|
|
|
|
|
"",
|
|
|
|
|
|
btnLabel: "我知道了"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示警告提示
|
|
|
|
|
|
void _showWarningDialog(String message) {
|
|
|
|
|
|
var thisContext = context;
|
|
|
|
|
|
if (thisContext.mounted) {
|
|
|
|
|
|
DialogUtils.showWarningMessage(
|
|
|
|
|
|
thisContext,
|
|
|
|
|
|
"警告",
|
|
|
|
|
|
message,
|
|
|
|
|
|
btnLabel: "我知道了"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清除数据
|
|
|
|
|
|
void _clearData() {
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
_vehicleTextController.clear();
|
|
|
|
|
|
stockInDataXuGong = [];
|
2025-02-19 18:52:05 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-25 16:00:50 +08:00
|
|
|
|
// 隐藏加载对话框
|
|
|
|
|
|
void _dismissLoading() {
|
|
|
|
|
|
var thisContext = context;
|
|
|
|
|
|
if (thisContext.mounted) {
|
|
|
|
|
|
BrnLoadingDialog.dismiss(thisContext);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-25 16:50:15 +08:00
|
|
|
|
}
|