655 lines
25 KiB
Dart
655 lines
25 KiB
Dart
|
import 'dart:convert';
|
||
|
import 'dart:io';
|
||
|
|
||
|
import 'package:decimal/decimal.dart';
|
||
|
import 'package:dio/dio.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
import 'package:get/get.dart';
|
||
|
import 'package:math_expressions/math_expressions.dart';
|
||
|
import 'package:open_filex/open_filex.dart';
|
||
|
import 'package:path_provider/path_provider.dart';
|
||
|
import 'package:sk_base_mobile/apis/api.dart';
|
||
|
import 'package:sk_base_mobile/app_theme.dart';
|
||
|
import 'package:sk_base_mobile/config.dart';
|
||
|
import 'package:sk_base_mobile/constants/constants.dart';
|
||
|
import 'package:sk_base_mobile/models/base_search_more_controller.dart';
|
||
|
import 'package:sk_base_mobile/models/sale_quotaion_component.model.dart';
|
||
|
import 'package:sk_base_mobile/models/sale_quotaion_group.model.dart';
|
||
|
import 'package:sk_base_mobile/models/sale_quotation.model.dart';
|
||
|
import 'package:sk_base_mobile/models/sale_quotation_template.model.dart';
|
||
|
import 'package:sk_base_mobile/models/workbench.model.dart';
|
||
|
import 'package:sk_base_mobile/router/router.util.dart';
|
||
|
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
|
||
|
import 'package:sk_base_mobile/services/dio.service.dart';
|
||
|
import 'package:sk_base_mobile/services/storage.service.dart';
|
||
|
import 'package:sk_base_mobile/util/common.util.dart';
|
||
|
import 'package:sk_base_mobile/util/loading_util.dart';
|
||
|
import 'package:sk_base_mobile/util/logger_util.dart';
|
||
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||
|
import 'package:sk_base_mobile/widgets/core/sk_flat_button.dart';
|
||
|
import 'package:sk_base_mobile/widgets/core/sk_ink.dart';
|
||
|
import 'package:sk_base_mobile/widgets/form_item/sk_multi_search_more.dart';
|
||
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||
|
import 'package:pinyin/pinyin.dart';
|
||
|
import 'package:sk_base_mobile/widgets/form_item/sk_text_input.dart';
|
||
|
import 'package:sk_base_mobile/widgets/loading_indicator.dart';
|
||
|
|
||
|
class SaleQuotationController extends GetxController {
|
||
|
static SaleQuotationController get to => Get.find();
|
||
|
final RxList editingcell = RxList([null, null, null]);
|
||
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||
|
RxList<SaleQuotationModel> groups = RxList<SaleQuotationModel>([]);
|
||
|
RxDouble totalCost = RxDouble(0.0);
|
||
|
RxDouble totalPrice = RxDouble(0.0);
|
||
|
RxBool isFormulaEditing = false.obs;
|
||
|
RxString formula = '成本 * 1.3 / 0.864'.obs;
|
||
|
RxList<SaleQuotationTemplateModel> templates = RxList([]);
|
||
|
final List<WorkBenchModel> menus = [];
|
||
|
RxString templateName = '默认'.obs;
|
||
|
RxnInt templateId = RxnInt(null);
|
||
|
final downloadProgress = RxDouble(0.0);
|
||
|
final RxBool loading = false.obs;
|
||
|
@override
|
||
|
void onReady() {
|
||
|
init();
|
||
|
super.onReady();
|
||
|
}
|
||
|
|
||
|
Future export() async {
|
||
|
try {
|
||
|
if (templateId.value == null) {
|
||
|
SnackBarUtil().warning('请点击选中模板,若无模板请先创建');
|
||
|
return;
|
||
|
}
|
||
|
final dir = await getDownloadsDirectory();
|
||
|
if (dir != null) {
|
||
|
String storagePath = dir.path;
|
||
|
File file = File('$storagePath/$templateName.xls');
|
||
|
if (!file.existsSync()) {
|
||
|
file.createSync();
|
||
|
}
|
||
|
CancelToken token = CancelToken();
|
||
|
ModalUtil.alert(
|
||
|
barrierDismissible: false,
|
||
|
contentPadding: EdgeInsets.zero,
|
||
|
showActions: false,
|
||
|
content:
|
||
|
// 进度条
|
||
|
Obx(() => Column(
|
||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||
|
mainAxisSize: MainAxisSize.min,
|
||
|
children: [
|
||
|
Stack(
|
||
|
children: [
|
||
|
SizedBox(
|
||
|
height: ScreenAdaper.height(60),
|
||
|
child: LinearProgressIndicator(
|
||
|
value: downloadProgress.value,
|
||
|
),
|
||
|
),
|
||
|
Positioned(
|
||
|
left: 0,
|
||
|
right: 0,
|
||
|
child: Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||
|
children: [
|
||
|
Text(
|
||
|
'${downloadProgress.value * 100}%',
|
||
|
textAlign: TextAlign.center,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(30)),
|
||
|
),
|
||
|
const LoadingIndicator(
|
||
|
color: AppTheme.nearlyBlack)
|
||
|
],
|
||
|
)),
|
||
|
],
|
||
|
),
|
||
|
SkFlatButton(
|
||
|
onPressed: () {
|
||
|
token.cancel('已取消下载');
|
||
|
Get.back();
|
||
|
},
|
||
|
textColor: AppTheme.nearlyBlack,
|
||
|
color: AppTheme.nearlyWhite,
|
||
|
buttonText: '取消',
|
||
|
)
|
||
|
],
|
||
|
)));
|
||
|
try {
|
||
|
await DioService.dio.download(
|
||
|
'${Urls.saleQuotation}/export/${templateId.value}', file.path,
|
||
|
cancelToken: token,
|
||
|
onReceiveProgress: onReceiveProgress,
|
||
|
options: Options(
|
||
|
responseType: ResponseType.bytes,
|
||
|
followRedirects: false,
|
||
|
));
|
||
|
Get.back();
|
||
|
await OpenFilex.open(file.path);
|
||
|
} catch (e) {
|
||
|
Get.back();
|
||
|
SnackBarUtil().error((e as dynamic).error ?? '暂时无法下载,请稍后重试或联系管理员');
|
||
|
LoggerUtil().error(e);
|
||
|
}
|
||
|
}
|
||
|
} catch (e) {
|
||
|
SnackBarUtil().error('暂时无法下载,请稍后重试或联系管理员');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 展示下载进度
|
||
|
void onReceiveProgress(num received, num total) {
|
||
|
LoggerUtil().info(received);
|
||
|
if (total != -1) {
|
||
|
downloadProgress.value =
|
||
|
Decimal.parse((received / total).toStringAsFixed(2))
|
||
|
.toDouble()
|
||
|
.toPrecision(2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> init() async {
|
||
|
menus.addAll([
|
||
|
WorkBenchModel(title: '导出明细', icon: 'export.svg', onTap: export),
|
||
|
// WorkBenchModel(title: '模板', icon: 'sale_quotation_template.svg'),
|
||
|
WorkBenchModel(
|
||
|
title: '使用教程',
|
||
|
icon: 'usage_guide.svg',
|
||
|
onTap: () {
|
||
|
RouterUtil.toNamed(RouteConfig.saleQuotationGuide);
|
||
|
}),
|
||
|
WorkBenchModel(title: '配件管理', icon: 'product.svg'),
|
||
|
WorkBenchModel(title: '分组管理', icon: 'sale_quotation_group.svg'),
|
||
|
// WorkBenchModel(title: '计算公式', icon: 'sale_quotation_formula.svg'),
|
||
|
]);
|
||
|
String? salesQuotation = StorageService.to.getString('salesQuotation');
|
||
|
if (salesQuotation != null) {
|
||
|
SaleQuotationTemplateModel editTemplate =
|
||
|
SaleQuotationTemplateModel.fromJson(jsonDecode(salesQuotation));
|
||
|
parseTemplateModel(editTemplate);
|
||
|
}
|
||
|
await getTemplates();
|
||
|
}
|
||
|
|
||
|
void parseTemplateModel(SaleQuotationTemplateModel editTemplate) {
|
||
|
groups.assignAll(editTemplate.template.data);
|
||
|
templateName.value = editTemplate.name ?? '';
|
||
|
formula.value = editTemplate.template.formula;
|
||
|
totalPrice.value = editTemplate.template.totalPrice?.toDouble() ?? 0.0;
|
||
|
totalCost.value = editTemplate.template.totalCost?.toDouble() ?? 0.0;
|
||
|
templateId.value = editTemplate.id;
|
||
|
}
|
||
|
|
||
|
/// 切换报价模板
|
||
|
void changeTemplate(SaleQuotationTemplateModel templateModel) {
|
||
|
parseTemplateModel(templateModel);
|
||
|
saveToLocal();
|
||
|
}
|
||
|
|
||
|
/// 获取报价模板
|
||
|
Future<void> getTemplates() async {
|
||
|
final res = await Api.getSaleQuotationTemplate();
|
||
|
List<SaleQuotationTemplateModel> newList = res.data!.items
|
||
|
.map((e) => SaleQuotationTemplateModel.fromJson(e))
|
||
|
.toList();
|
||
|
templates.assignAll(newList);
|
||
|
}
|
||
|
|
||
|
/// 实时计算总数
|
||
|
void calculateTotal({String? newFormula}) {
|
||
|
//计算groups中所有items中的amout总和
|
||
|
totalCost.value = groups.fold<double>(0, (previousValue, element) {
|
||
|
return previousValue +
|
||
|
element.items.fold<double>(0, (previousValue, element) {
|
||
|
return previousValue + element.amount;
|
||
|
});
|
||
|
});
|
||
|
Parser p = Parser();
|
||
|
Expression exp = p.parse(newFormula ?? formula.value);
|
||
|
Variable x = Variable('成本');
|
||
|
ContextModel cm = ContextModel()..bindVariable(x, Number(totalCost.value));
|
||
|
double eval = exp.evaluate(EvaluationType.REAL, cm);
|
||
|
totalPrice.value = eval.toPrecision(2);
|
||
|
}
|
||
|
|
||
|
/// 实时计算数量,单价,总价之间的关系
|
||
|
SaleQuotationItemModel calculateRow(
|
||
|
SaleQuotationItemModel data, String changedField) {
|
||
|
Decimal quantity = Decimal.fromInt(0);
|
||
|
Decimal unitPrice = Decimal.fromInt(0);
|
||
|
Decimal amount = Decimal.fromInt(0);
|
||
|
if (data.quantity != 0) {
|
||
|
quantity = Decimal.parse('${data.quantity}');
|
||
|
}
|
||
|
if (data.unitPrice != 0) {
|
||
|
unitPrice = Decimal.parse('${data.unitPrice}');
|
||
|
}
|
||
|
if (data.amount != 0) {
|
||
|
amount = Decimal.parse('${data.amount}');
|
||
|
}
|
||
|
// 入库一般是先输入单价和数量,然后计算单价
|
||
|
if (changedField != 'amount') {
|
||
|
Decimal result = unitPrice * quantity;
|
||
|
data.amount = result != Decimal.zero ? result.toDouble() : 0;
|
||
|
}
|
||
|
|
||
|
if (changedField == 'amount' && quantity != Decimal.zero) {
|
||
|
Decimal result =
|
||
|
(amount / quantity).toDecimal(scaleOnInfinitePrecision: 10);
|
||
|
data.unitPrice = result != Decimal.zero ? result.toDouble() : 0.0;
|
||
|
} else if (changedField != 'amount') {
|
||
|
Decimal result = (unitPrice * quantity);
|
||
|
data.amount = result != Decimal.zero ? result.toDouble() : 0;
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/// 处理行数据变化
|
||
|
void afterRowChanges(int groupIndex, int rowIndex,
|
||
|
SaleQuotationItemModel data, String changedField) {
|
||
|
data = calculateRow(data, changedField);
|
||
|
groups[groupIndex].items[rowIndex] = data;
|
||
|
calculateTotal();
|
||
|
stopEditing();
|
||
|
}
|
||
|
|
||
|
/// 停止编辑
|
||
|
void stopEditing() {
|
||
|
editingcell.assignAll([null, null, null]);
|
||
|
saveToLocal();
|
||
|
}
|
||
|
|
||
|
/// 保存到本地持久化
|
||
|
Future<void> saveToLocal() async {
|
||
|
Map<String, dynamic> data = {
|
||
|
'name': templateName.value,
|
||
|
'template': {
|
||
|
'data': groups.map((e) => e.toJson()).toList(),
|
||
|
'totalCost': totalCost.value,
|
||
|
'totalPrice': totalPrice.value,
|
||
|
'formula': formula.value,
|
||
|
}
|
||
|
};
|
||
|
if (templateId.value != null) {
|
||
|
data['id'] = templateId.value;
|
||
|
}
|
||
|
await StorageService.to.setString('salesQuotation', jsonEncode(data));
|
||
|
}
|
||
|
|
||
|
/// 检查当前模板是否合法
|
||
|
bool checkIsValid() {
|
||
|
if (groups.isEmpty) {
|
||
|
SnackBarUtil().warning('至少要创建一个组');
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// 保存到数据库
|
||
|
Future<bool> saveToDatabase({isSaveAs = false}) async {
|
||
|
if (groups.isEmpty) {
|
||
|
SnackBarUtil().warning('至少要创建一个组');
|
||
|
return false;
|
||
|
}
|
||
|
try {
|
||
|
await LoadingUtil.to.show();
|
||
|
if (templateId.value == null || isSaveAs) {
|
||
|
await Api.createSaleQuotationTemplate({
|
||
|
'name': templateName.value,
|
||
|
'template': {
|
||
|
'data': groups.toJson(),
|
||
|
'totalCost': totalCost.value,
|
||
|
'totalPrice': totalPrice.value,
|
||
|
'formula': formula.value
|
||
|
}
|
||
|
});
|
||
|
await SnackBarUtil().success('已生成新的模板');
|
||
|
await getTemplates();
|
||
|
changeTemplate(templates.first);
|
||
|
} else {
|
||
|
await Api.updateSaleQuotationTemplate(templateId.value!, {
|
||
|
'name': templateName.value,
|
||
|
'template': {
|
||
|
'data': groups.toJson(),
|
||
|
'totalCost': totalCost.value,
|
||
|
'totalPrice': totalPrice.value,
|
||
|
'formula': formula.value
|
||
|
}
|
||
|
});
|
||
|
await SnackBarUtil().success('已保存');
|
||
|
await getTemplates();
|
||
|
}
|
||
|
} finally {
|
||
|
await LoadingUtil.to.dismiss();
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// 删除模板
|
||
|
Future<void> deleteTemplate(int deleteId) async {
|
||
|
await Api.deleteSaleQuotationTemplate(deleteId);
|
||
|
SnackBarUtil().success('已删除');
|
||
|
}
|
||
|
|
||
|
/// 添加分组
|
||
|
void addGroup() async {
|
||
|
final controller = Get.put(GroupSearchMoreController());
|
||
|
// 选择组件 选择分组
|
||
|
ModalUtil.showGeneralDialog(
|
||
|
content: SkMutilSearchMore<SaleQuotationModel>(
|
||
|
controller: controller,
|
||
|
title: '请选择分组',
|
||
|
enablePullUp: false,
|
||
|
enablePullDown: true,
|
||
|
onOk: (List<int> indexes) {
|
||
|
groups.addAll(controller.list.where((element) {
|
||
|
return indexes.contains(controller.list.indexOf(element));
|
||
|
}));
|
||
|
saveToLocal();
|
||
|
},
|
||
|
leadingBuilder: (index) {
|
||
|
return Container(
|
||
|
padding: EdgeInsets.symmetric(
|
||
|
horizontal: ScreenAdaper.width(5),
|
||
|
vertical: ScreenAdaper.height(10)),
|
||
|
child: Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
controller.list[index].name,
|
||
|
style: TextStyle(fontSize: ScreenAdaper.height(30)),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
},
|
||
|
),
|
||
|
width: Get.width - ScreenAdaper.width(50))
|
||
|
.then((value) => Get.delete<GroupSearchController>());
|
||
|
calculateTotal();
|
||
|
}
|
||
|
|
||
|
/// 移除分组
|
||
|
void removeGroup(int index) {
|
||
|
groups.removeAt(index);
|
||
|
calculateTotal();
|
||
|
saveToLocal();
|
||
|
}
|
||
|
|
||
|
void addItems(int groupIndex) async {
|
||
|
final controller = Get.put(ItemSearchMoreController());
|
||
|
// 选择配件
|
||
|
ModalUtil.showGeneralDialog(
|
||
|
content: SkMutilSearchMore<SaleQuotationItemModel>(
|
||
|
controller: controller,
|
||
|
enablePullUp: false,
|
||
|
title: '请选择配件产品',
|
||
|
enablePullDown: true,
|
||
|
isDialog: true,
|
||
|
onOk: (List<int> indexes) {
|
||
|
groups[groupIndex]
|
||
|
.items
|
||
|
.addAll(controller.list.where((element) {
|
||
|
return indexes.contains(controller.list.indexOf(element));
|
||
|
}).map((e) {
|
||
|
e.quantity = 1;
|
||
|
|
||
|
Decimal amount = Decimal.parse(e.unitPrice.toString()) *
|
||
|
Decimal.fromInt(e.quantity);
|
||
|
e.amount = amount.toDouble();
|
||
|
return e;
|
||
|
}));
|
||
|
calculateTotal();
|
||
|
saveToLocal();
|
||
|
},
|
||
|
leadingBuilder: (index) {
|
||
|
return Container(
|
||
|
padding: EdgeInsets.symmetric(
|
||
|
horizontal: ScreenAdaper.width(5),
|
||
|
),
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
controller.list[index].name,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(30),
|
||
|
fontWeight: FontWeight.w600),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
if (controller.list[index].unit != null)
|
||
|
Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
'单位:${controller.list[index].unit ?? ''}',
|
||
|
textAlign: TextAlign.start,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(23)),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
if (controller.list[index].componentSpecification !=
|
||
|
null)
|
||
|
Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
'规格、型号及说明:${controller.list[index].componentSpecification ?? ''}',
|
||
|
textAlign: TextAlign.start,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(23)),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
'单价:¥${controller.list[index].unitPrice}',
|
||
|
textAlign: TextAlign.start,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(23)),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
if (controller.list[index].remark != null)
|
||
|
Row(
|
||
|
children: [
|
||
|
Text(
|
||
|
'备注:${controller.list[index].remark ?? ''}',
|
||
|
textAlign: TextAlign.start,
|
||
|
style: TextStyle(
|
||
|
fontSize: ScreenAdaper.height(23)),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
]));
|
||
|
},
|
||
|
),
|
||
|
width: Get.width - ScreenAdaper.width(50))
|
||
|
.then((value) => Get.delete<ItemSearchMoreController>());
|
||
|
calculateTotal();
|
||
|
}
|
||
|
|
||
|
void removeItem(int groupIndex, int rowIndex) {
|
||
|
groups[groupIndex].items.removeAt(rowIndex);
|
||
|
calculateTotal();
|
||
|
}
|
||
|
|
||
|
void clearWorkbench() {
|
||
|
groups.value = [];
|
||
|
totalCost.value = 0.0;
|
||
|
totalPrice.value = 0.0;
|
||
|
formula.value = '成本 * 1.3 / 0.864';
|
||
|
templateName.value = '默认';
|
||
|
templateId.value = null;
|
||
|
saveToLocal();
|
||
|
}
|
||
|
|
||
|
void openTemplateNameEditPopup(
|
||
|
{String? title = '',
|
||
|
bool isSaveAs = false,
|
||
|
Function(String)? onConfirm,
|
||
|
Function? onCancel}) {
|
||
|
if (!checkIsValid()) {
|
||
|
return;
|
||
|
}
|
||
|
final textController = TextEditingController(text: title);
|
||
|
Get.dialog(AlertDialog(
|
||
|
shape: RoundedRectangleBorder(
|
||
|
borderRadius: BorderRadius.circular(ScreenAdaper.sp(20)),
|
||
|
),
|
||
|
contentPadding: EdgeInsets.only(
|
||
|
top: ScreenAdaper.height(10),
|
||
|
right: ScreenAdaper.height(20),
|
||
|
left: ScreenAdaper.height(20)),
|
||
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||
|
Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||
|
children: [
|
||
|
SkInk(
|
||
|
onTap: () {
|
||
|
RouterUtil.back();
|
||
|
},
|
||
|
child: const Icon(Icons.close))
|
||
|
],
|
||
|
),
|
||
|
SkTextInput(
|
||
|
height: ScreenAdaper.height(100),
|
||
|
textController: textController,
|
||
|
customLabel: true,
|
||
|
labelText: '模板名称',
|
||
|
),
|
||
|
Row(
|
||
|
children: [
|
||
|
Expanded(
|
||
|
child: TextButton(
|
||
|
onPressed: () {
|
||
|
RouterUtil.back();
|
||
|
},
|
||
|
child: const Text(
|
||
|
'取消',
|
||
|
style: TextStyle(color: AppTheme.nearlyBlack),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
Expanded(
|
||
|
child: TextButton(
|
||
|
onPressed: () async {
|
||
|
if (textController.text.isEmpty) {
|
||
|
SnackBarUtil().error('模板名不能为空');
|
||
|
return;
|
||
|
}
|
||
|
await RouterUtil.back();
|
||
|
onConfirm?.call(textController.text);
|
||
|
// templateName.value = textController.text;
|
||
|
// await RouterUtil.back();
|
||
|
// await saveToLocal();
|
||
|
// await saveToDatabase(isSaveAs: isSaveAs);
|
||
|
// await getTemplates();
|
||
|
},
|
||
|
child: const Text('确定'),
|
||
|
))
|
||
|
],
|
||
|
)
|
||
|
]),
|
||
|
));
|
||
|
}
|
||
|
// /// 检查是否已经保存
|
||
|
// void checkIsSaved() {
|
||
|
// if (templateId.value == null) {
|
||
|
// return false;
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
class GroupSearchMoreController
|
||
|
extends BaseSearchMoreController<SaleQuotationModel> {
|
||
|
@override
|
||
|
Future<List<SaleQuotationModel>> getData({bool isRefresh = false}) async {
|
||
|
await Future.delayed(const Duration(seconds: 1));
|
||
|
final res = await Api.getSaleQuotationGroups();
|
||
|
List<SaleQuotationGroupModel> groups = res.data!.items
|
||
|
.map((e) => SaleQuotationGroupModel.fromJson(e))
|
||
|
.toList();
|
||
|
|
||
|
List<SaleQuotationModel> newList = groups
|
||
|
.map((e) => SaleQuotationModel(name: e.name!, items: RxList([])))
|
||
|
.toList();
|
||
|
// List<SaleQuotationModel> newList = [
|
||
|
// SaleQuotationModel(name: '中间过渡架电控部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '端头架电控部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '主阀部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '自动反冲洗过滤器部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '位移测量部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '压力检测部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '煤机定位部分', items: RxList([])),
|
||
|
// SaleQuotationModel(name: '姿态检测部分', items: RxList([])),
|
||
|
// ];
|
||
|
list.assignAll(newList
|
||
|
.where((element) => PinyinHelper.getPinyin(element.name, separator: '')
|
||
|
.contains(searchKey.value))
|
||
|
.toList());
|
||
|
return newList;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ItemSearchMoreController
|
||
|
extends BaseSearchMoreController<SaleQuotationItemModel> {
|
||
|
@override
|
||
|
Future<List<SaleQuotationItemModel>> getData({bool isRefresh = false}) async {
|
||
|
try {
|
||
|
final res = await Api.getSaleQuotationComponents();
|
||
|
List<SaleQuotationComponentModel> componets = res.data!.items
|
||
|
.map((e) => SaleQuotationComponentModel.fromJson(e))
|
||
|
.toList();
|
||
|
List<SaleQuotationItemModel> newList = componets
|
||
|
.map((e) => SaleQuotationItemModel(
|
||
|
name: e.name!,
|
||
|
unitPrice: e.unitPrice ?? 0.0,
|
||
|
unit: e.unit?.label ?? '',
|
||
|
componentSpecification: e.componentSpecification,
|
||
|
remark: e.remark))
|
||
|
.toList();
|
||
|
// List<SaleQuotationItemModel> newList = [
|
||
|
// SaleQuotationItemModel(
|
||
|
// name: '矿用本安型支架控制器', unit: '台', componentSpecification: 'ZDYZ-Z', unitPrice: 4700),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', unitPrice: 1200),
|
||
|
// SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', unitPrice: 5700),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型隔离耦合器', unitPrice: 1200),
|
||
|
// SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', unitPrice: 600),
|
||
|
// SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器', unitPrice: 400),
|
||
|
// SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器', unitPrice: 500),
|
||
|
// SaleQuotationItemModel(
|
||
|
// name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器', unitPrice: 2000),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型支架控制器', unitPrice: 4700),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', unitPrice: 1200),
|
||
|
// SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', unitPrice: 5700),
|
||
|
// SaleQuotationItemModel(
|
||
|
// name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组', unitPrice: 13200),
|
||
|
// SaleQuotationItemModel(
|
||
|
// name: '电液换向阀(20功能20接口)', remark: '端头架主阀组', unitPrice: 26500),
|
||
|
// SaleQuotationItemModel(
|
||
|
// name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm', unitPrice: 2000),
|
||
|
// SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型位移传感器'),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型红外发射器'),
|
||
|
// SaleQuotationItemModel(name: '矿用本安型LED信号灯'),
|
||
|
// SaleQuotationItemModel(name: '倾角传感器'),
|
||
|
// SaleQuotationItemModel(name: '各类安装附件'),
|
||
|
// ];
|
||
|
list.assignAll(newList
|
||
|
.where((element) =>
|
||
|
PinyinHelper.getPinyin(element.name, separator: '')
|
||
|
.contains(searchKey.value))
|
||
|
.toList());
|
||
|
return newList;
|
||
|
} catch (e) {
|
||
|
return [];
|
||
|
}
|
||
|
}
|
||
|
}
|