Browse Source

新建商品规格修改。套餐修改。增加商品图片

wr_2023_new_business
wurong 12 months ago
parent
commit
fb0ca0b2a6
  1. 298
      lib/business_system/goods/add_goods/add_goods_page.dart
  2. 837
      lib/business_system/goods/add_goods/data/product_sku.dart
  3. 70
      lib/business_system/goods/add_goods/data/product_sku_attr.dart
  4. 121
      lib/business_system/goods/add_goods/edit_specs_detail.dart
  5. 142
      lib/business_system/goods/add_goods/set_goods_specs.dart
  6. 48
      lib/business_system/goods/add_goods/set_goods_specs_value.dart
  7. 36
      lib/business_system/goods/add_goods/set_meal.dart
  8. 78
      lib/business_system/goods/on_sale/batch_shelf.dart
  9. 1
      lib/main.dart
  10. 2
      lib/retrofit/business_api.dart
  11. 15
      lib/retrofit/data/set_specs_list.dart
  12. 6
      lib/retrofit/data/set_specs_meal_list.dart
  13. 1
      lib/retrofit/data/set_specs_value_list.dart
  14. 198
      pubspec.lock
  15. 3
      pubspec.yaml

298
lib/business_system/goods/add_goods/add_goods_page.dart

@ -1,9 +1,16 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/business_system/goods/add_goods/data/product_sku_attr.dart';
import 'package:huixiang/retrofit/data/upload_result.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_pickers/image_pickers.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../../generated/l10n.dart';
import '../../../retrofit/business_api.dart';
import '../../../retrofit/data/base_data.dart';
@ -13,6 +20,7 @@ import '../../../utils/business_instance.dart';
import '../../../utils/flutter_utils.dart';
import '../../../utils/font_weight.dart';
import '../../../view_widget/settlement_tips_dialog.dart';
import 'data/product_sku.dart';
class AddGoodsPage extends StatefulWidget {
final Map<String, dynamic> arguments;
@ -52,8 +60,9 @@ class _AddGoodsPage extends State<AddGoodsPage> {
bool isAttrStyle = false;
bool isKeyBoardShow = false;
FocusNode _focusNode = FocusNode();
List<dynamic> mealDetails = [];
List<dynamic> goodsSpecsDetails = [];
List<Map<String, dynamic>> mealDetails = [];
List<ProductSkuAttr> skuAttrList = [];
List<Sku> skuList = [];
@override
void initState() {
@ -144,56 +153,73 @@ class _AddGoodsPage extends State<AddGoodsPage> {
tenant: BusinessInstance.instance.businessTenant,
storeId: widget.arguments["storeId"]);
}
BaseData baseData = await businessService.productSave({
if (productImgUrl == null || productImgUrl.isEmpty) {
SmartDialog.show(
widget: SettlementTips(
() {},
text: "必须传商品图片",
color: Color(0xFF30415B),
));
return;
}
var map = {
"storeId": widget.arguments["storeId"],
"attrStyle": isAttrStyle == true ? 0 : 1, //1- 0-
"categoryId": "1343391656220557312", //id
"attrStyle": isAttrStyle ? 1 : 0, //1- 0-
"categoryId": categoryId, //id
"oversold": isOversold == true ? 1 : 0, //1- 0-
"setMeal": isSetMeal == true ? 0 : 1, // 0 1
"groupId": "1693436138259218432", //id
"groupId": groupId, //id
"imgs": [
{
"imgPath":
"https://pos.upload.lotus-wallet.com/1195/2023/10/1ba87000-d940-49e5-a6ca-f15623d5f841.jpg"
"imgPath": productImgUrl
}
], //
"needLogistics": isLogistics == true ? 1 : 0, //1- 0-
"productName": "新建商品", //
"productName": goodsNameController.text.trim(), //
"productType": 0, //01app新增商品用不到0
"shortName": "商品简介", //
"skuAttrList": [
"shortName": profileController.text.trim(), //
"skuAttrList": isAttrStyle ? skuAttrList.map((e) => e.toJson()).toList() :
[
{
"attrCode": "", //,app新增商品用不到""
"attrName": "", //,app新增商品用不到""
"attrCode": "attr_code_0", //,app新增商品用不到""
"attrName": skuController.text.trim(), //,app新增商品用不到""
"needImg": 0, //,app新增商品用不到0
"attrValueList": [
{
"attrValue": "商品规格", //
"attrValueCode": "", //,app新增商品用不到""
"attrValue": skuController.text.trim(), //
"attrValueCode": "attr_code_0_value_0", //,app新增商品用不到""
}
] //
}
], //
"skuList": [
"skuList": isAttrStyle ?
skuList.map((e) => e.toJson()).toList() :
[
{
"applyPrice": "234",
//
"applyPrice": originalPriceController.text.trim(),
///
"skuAttrCodeDTOList": [
{"attrCode": "", "attrValueCode": ""}
{"attrCode": "attr_code_0", "attrValueCode": "attr_code_0_value_0"}
],
//sku对应的规格编码,app新增商品用不到
"skuPrice": "123",
//
"packagingFee": "789",
//
"skuStock": "666",
//
"weight": "222"
//
///sku对应的规格编码,app新增商品用不到
"skuPrice": priceController.text.trim(),
///
"packagingFee": packingChargeController.text.trim(),
///
"skuStock": stockController.text.trim(),
///
"weight": heftController.text.trim(),
///
"productSetMeals": mealDetails
///
}
], //sku列表
"status": isGround == true ? 1 : 0 //1- 0-
}).catchError((error) {
};
print("mapmapmap: $map");
BaseData baseData = await businessService.productSave(map).catchError((error) {
networkError = AppUtils.dioErrorTypeToString(error.type);
networkStatus = -1;
setState(() {});
@ -208,6 +234,7 @@ class _AddGoodsPage extends State<AddGoodsPage> {
));
networkStatus = 1;
setState(() {});
Navigator.of(context).pop();
} else {
SmartDialog.show(
widget: SettlementTips(
@ -284,8 +311,7 @@ class _AddGoodsPage extends State<AddGoodsPage> {
child: Column(
children: [
Padding(
padding:
EdgeInsets.only(top: 18.h, left: 16.w, right: 16.w),
padding: EdgeInsets.only(top: 18.h, left: 16.w, right: 16.w),
child: Row(
children: [
Padding(
@ -306,7 +332,7 @@ class _AddGoodsPage extends State<AddGoodsPage> {
});
},
child: Image.asset(
isAttrStyle == true
isAttrStyle
? "assets/image/reservation_switch.webp"
: "assets/image/reservation_unswitch.webp",
width: 44.w,
@ -329,11 +355,19 @@ class _AddGoodsPage extends State<AddGoodsPage> {
Navigator.of(context).pushNamed(
'/router/set_goods_specs',
arguments: {
"goodsSpecsDetails": goodsSpecsDetails
"skuAttrList": skuAttrList,
"skuList": skuList
}).then((value) {
if (value != null) {
goodsSpecsDetails.clear();
goodsSpecsDetails.addAll(value);
print("value:$value");
if (value != null && value is Map) {
if (value["skuAttrList"] is List) {
List<ProductSkuAttr> goodsSpecsDetail = value["skuAttrList"];
skuAttrList = goodsSpecsDetail;
}
if (value["skuList"] is List) {
List<Sku> specsValue = value["skuList"];
skuList = specsValue;
}
setState(() {});
}
});
@ -359,7 +393,7 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
)),
Text(
"请设置商品规格",
(skuList != null && skuList.isNotEmpty) ? "商品规格已设置" : "请设置商品规格",
style: TextStyle(
color: Color(0xFF7A797F),
fontSize: 14.sp,
@ -402,9 +436,9 @@ class _AddGoodsPage extends State<AddGoodsPage> {
arguments: {
"mealDetails": mealDetails
}).then((value) {
if (value != null) {
if (value != null && value is List) {
mealDetails.clear();
mealDetails.addAll(value);
mealDetails.addAll(value.map((e) => e as Map<String, dynamic>).toList());
setState(() {});
}
});
@ -429,9 +463,9 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
),
Text(
"套餐选择",
(mealDetails != null && mealDetails.isNotEmpty) ? "已设置套餐" : "套餐选择",
style: TextStyle(
color: Color(0xFF7A797F),
color: (mealDetails != null && mealDetails.isNotEmpty) ? Color(0xA9000000) : Color(0xFF7A797F),
fontSize: 14.sp,
fontWeight: FontWeight.bold,
),
@ -453,22 +487,27 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
),
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 16.h),
margin: EdgeInsets.only(
top: 111.h, bottom: 34.h, left: 16.w, right: 16.w),
decoration: BoxDecoration(
color: Color(0xFF30415B),
borderRadius: BorderRadius.circular(27),
),
alignment: Alignment.center,
child: Text(
S.of(context).baocun,
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: MyFontWeight.bold,
GestureDetector(
onTap: () {
addGoods();
},
child: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 16.h),
margin: EdgeInsets.only(
top: 111.h, bottom: 34.h, left: 16.w, right: 16.w),
decoration: BoxDecoration(
color: Color(0xFF30415B),
borderRadius: BorderRadius.circular(27),
),
alignment: Alignment.center,
child: Text(
S.of(context).baocun,
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: MyFontWeight.bold,
),
),
),
),
@ -521,25 +560,59 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
),
),
Container(
padding: EdgeInsets.all(15),
margin: EdgeInsets.only(right: 4.w),
decoration: BoxDecoration(
color: Color(0xFFF0F0F0),
borderRadius: BorderRadius.circular(4),
),
child: Icon(
Icons.add,
size: 24,
color: Color(0xFFD8D8D8),
InkWell(
onTap: () {
showImagePicker() {
showCupertinoModalPopup(
context: context,
builder: (contetx) {
return CupertinoActionSheet(
title: Text(S.of(context).genghuantouxiang),
actions: [
CupertinoActionSheetAction(
child: Text(S.of(context).paizhao),
onPressed: () {
openCamera();
Navigator.of(context).pop();
},
isDefaultAction: true,
isDestructiveAction: false,
),
CupertinoActionSheetAction(
child: Text(S.of(context).xiangce),
onPressed: () {
openStorage();
Navigator.of(context).pop();
},
isDefaultAction: true,
isDestructiveAction: false,
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(S.of(context).quxiao),
isDestructiveAction: true,
),
);
});
}
},
child: Container(
padding: EdgeInsets.all(15),
margin: EdgeInsets.only(right: 4.w),
decoration: BoxDecoration(
color: Color(0xFFF0F0F0),
borderRadius: BorderRadius.circular(4),
),
child: Icon(
Icons.add,
size: 24,
color: Color(0xFFD8D8D8),
),
),
),
Image.asset(
"assets/image/vip_code.webp",
fit: BoxFit.cover,
width: 54.h,
height: 54.h,
),
],
),
Container(
@ -931,7 +1004,7 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
textAlign: TextAlign.right,
style: TextStyle(
color: Color(0xFF7A797F),
color: Color(0xA9000000),
fontSize: 14.sp,
fontWeight: MyFontWeight.bold),
),
@ -1029,8 +1102,8 @@ class _AddGoodsPage extends State<AddGoodsPage> {
GestureDetector(
onTap: () {
setState(() {
categoryName =
goodsCategoryList[categoryIndex].categoryName;
categoryName = goodsCategoryList[categoryIndex].categoryName;
categoryId = goodsCategoryList[categoryIndex].id;
Navigator.of(context).pop();
});
},
@ -1186,9 +1259,8 @@ class _AddGoodsPage extends State<AddGoodsPage> {
GestureDetector(
onTap: () {
setState(() {
groupName =
productGroupList?.records[groupIndex]?.groupName ??
"";
groupName = productGroupList?.records[groupIndex]?.groupName ?? "";
groupId = productGroupList?.records[groupIndex]?.id ?? "";
Navigator.of(context).pop();
});
},
@ -1260,4 +1332,70 @@ class _AddGoodsPage extends State<AddGoodsPage> {
),
);
}
///
openCamera() async {
if (await Permission.camera.isGranted) {
Media medias = await ImagePickers.openCamera(
cameraMimeType: CameraMimeType.photo,
cropConfig: CropConfig(
enableCrop: true,
width: 200,
height: 200,
),
compressSize: 500,
);
if (medias == null) return;
filePath = medias.path;
fileUpload();
} else {
await Permission.camera.request();
openCamera();
}
}
String filePath;
String productImgUrl = "";
///
openStorage() async {
if (await Permission.storage.isGranted) {
List<Media> medias = await ImagePickers.pickerPaths(
galleryMode: GalleryMode.image,
selectCount: 1,
showGif: true,
showCamera: false,
compressSize: 500,
uiConfig: UIConfig(
uiThemeColor: Color(0xFFFFFFFF),
),
cropConfig: CropConfig(
enableCrop: true,
width: 200,
height: 200,
),
);
if (medias == null || medias.length == 0) return;
filePath = medias[0].path;
setState(() {});
fileUpload();
} else {
await Permission.storage.request();
openStorage();
}
}
///
fileUpload() async {
if (filePath != null && filePath != "" && await File(filePath).exists()) {
BaseData<UploadResult> baseData = await businessService
.upload(File(filePath), 123123123)
.catchError((onError) {});
if (baseData != null && baseData.isSuccess) {
UploadResult uploadResult = baseData.data;
productImgUrl = uploadResult.url;
}
}
}
}

837
lib/business_system/goods/add_goods/data/product_sku.dart

@ -0,0 +1,837 @@
class Sku {
Sku({
String applyPrice,
String autoRenewSkuStock,
String deliveries,
String id,
String isDelete,
List<dynamic> material,
String packagingFee,
String productId,
List<ProductSetMeals> productSetMeals,
String setMeal,
List<SetMealDtoList> setMealDTOList,
List<SkuAttrCodeDtoList> skuAttrCodeDTOList,
List<SkuAttrList> skuAttrList,
String skuCode,
String skuImg,
String skuNameStr,
String skuPrice,
String skuStock,
List<dynamic> skuTickets,
String sort,
String storeId,
List<dynamic> takeType,
String ticketDays,
TicketExpireTime ticketExpireTime,
String ticketStyle,
String ticketType,
String ticketWipedTimeTemplateId,
String version,
String vipPrice,
String volume,
String weight,}){
_applyPrice = applyPrice;
_autoRenewSkuStock = autoRenewSkuStock;
_deliveries = deliveries;
_id = id;
_isDelete = isDelete;
_material = material;
_packagingFee = packagingFee;
_productId = productId;
_productSetMeals = productSetMeals;
_setMeal = setMeal;
_setMealDTOList = setMealDTOList;
_skuAttrCodeDTOList = skuAttrCodeDTOList;
_skuAttrList = skuAttrList;
_skuCode = skuCode;
_skuImg = skuImg;
_skuNameStr = skuNameStr;
_skuPrice = skuPrice;
_skuStock = skuStock;
_skuTickets = skuTickets;
_sort = sort;
_storeId = storeId;
_takeType = takeType;
_ticketDays = ticketDays;
_ticketExpireTime = ticketExpireTime;
_ticketStyle = ticketStyle;
_ticketType = ticketType;
_ticketWipedTimeTemplateId = ticketWipedTimeTemplateId;
_version = version;
_vipPrice = vipPrice;
_volume = volume;
_weight = weight;
}
Sku.fromJson(dynamic json) {
_applyPrice = json['applyPrice'];
_autoRenewSkuStock = json['autoRenewSkuStock'];
_deliveries = json['deliveries'];
_id = json['id'];
_isDelete = json['isDelete'];
if (json['material'] != null) {
_material = [];
json['material'].forEach((v) {
_material.add(v);
});
}
_packagingFee = json['packagingFee'];
_productId = json['productId'];
if (json['productSetMeals'] != null) {
_productSetMeals = [];
json['productSetMeals'].forEach((v) {
_productSetMeals.add(ProductSetMeals.fromJson(v));
});
}
_setMeal = json['setMeal'];
if (json['setMealDTOList'] != null) {
_setMealDTOList = [];
json['setMealDTOList'].forEach((v) {
_setMealDTOList.add(SetMealDtoList.fromJson(v));
});
}
if (json['skuAttrCodeDTOList'] != null) {
_skuAttrCodeDTOList = [];
json['skuAttrCodeDTOList'].forEach((v) {
_skuAttrCodeDTOList.add(SkuAttrCodeDtoList.fromJson(v));
});
}
if (json['skuAttrList'] != null) {
_skuAttrList = [];
json['skuAttrList'].forEach((v) {
_skuAttrList.add(SkuAttrList.fromJson(v));
});
}
_skuCode = json['skuCode'];
_skuImg = json['skuImg'];
_skuNameStr = json['skuNameStr'];
_skuPrice = json['skuPrice'];
_skuStock = json['skuStock'];
if (json['skuTickets'] != null) {
_skuTickets = [];
json['skuTickets'].forEach((v) {
_skuTickets.add(v);
});
}
_sort = json['sort'];
_storeId = json['storeId'];
if (json['takeType'] != null) {
_takeType = [];
json['takeType'].forEach((v) {
_takeType.add(v);
});
}
_ticketDays = json['ticketDays'];
_ticketExpireTime = json['ticketExpireTime'] != null ? TicketExpireTime.fromJson(json['ticketExpireTime']) : null;
_ticketStyle = json['ticketStyle'];
_ticketType = json['ticketType'];
_ticketWipedTimeTemplateId = json['ticketWipedTimeTemplateId'];
_version = json['version'];
_vipPrice = json['vipPrice'];
_volume = json['volume'];
_weight = json['weight'];
}
String _applyPrice;
String _autoRenewSkuStock;
String _deliveries;
String _id;
String _isDelete;
List<dynamic> _material;
String _packagingFee;
String _productId;
List<ProductSetMeals> _productSetMeals;
String _setMeal;
List<SetMealDtoList> _setMealDTOList;
List<SkuAttrCodeDtoList> _skuAttrCodeDTOList;
List<SkuAttrList> _skuAttrList;
String _skuCode;
String _skuImg;
String _skuNameStr;
String _skuPrice;
String _skuStock;
List<dynamic> _skuTickets;
String _sort;
String _storeId;
List<dynamic> _takeType;
String _ticketDays;
TicketExpireTime _ticketExpireTime;
String _ticketStyle;
String _ticketType;
String _ticketWipedTimeTemplateId;
String _version;
String _vipPrice;
String _volume;
String _weight;
String get applyPrice => _applyPrice;
String get autoRenewSkuStock => _autoRenewSkuStock;
String get deliveries => _deliveries;
String get id => _id;
String get isDelete => _isDelete;
List<dynamic> get material => _material;
String get packagingFee => _packagingFee;
String get productId => _productId;
List<ProductSetMeals> get productSetMeals => _productSetMeals;
String get setMeal => _setMeal;
List<SetMealDtoList> get setMealDTOList => _setMealDTOList;
List<SkuAttrCodeDtoList> get skuAttrCodeDTOList => _skuAttrCodeDTOList;
List<SkuAttrList> get skuAttrList => _skuAttrList;
String get skuCode => _skuCode;
String get skuImg => _skuImg;
String get skuNameStr => _skuNameStr;
String get skuPrice => _skuPrice;
String get skuStock => _skuStock;
List<dynamic> get skuTickets => _skuTickets;
String get sort => _sort;
String get storeId => _storeId;
List<dynamic> get takeType => _takeType;
String get ticketDays => _ticketDays;
TicketExpireTime get ticketExpireTime => _ticketExpireTime;
String get ticketStyle => _ticketStyle;
String get ticketType => _ticketType;
String get ticketWipedTimeTemplateId => _ticketWipedTimeTemplateId;
String get version => _version;
String get vipPrice => _vipPrice;
String get volume => _volume;
String get weight => _weight;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['applyPrice'] = _applyPrice;
map['autoRenewSkuStock'] = _autoRenewSkuStock;
map['deliveries'] = _deliveries;
map['id'] = _id;
map['isDelete'] = _isDelete;
if (_material != null) {
map['material'] = _material.map((v) => v.toJson()).toList();
}
map['packagingFee'] = _packagingFee;
map['productId'] = _productId;
if (_productSetMeals != null) {
map['productSetMeals'] = _productSetMeals.map((v) => v.toJson()).toList();
}
map['setMeal'] = _setMeal;
if (_setMealDTOList != null) {
map['setMealDTOList'] = _setMealDTOList.map((v) => v.toJson()).toList();
}
if (_skuAttrCodeDTOList != null) {
map['skuAttrCodeDTOList'] = _skuAttrCodeDTOList.map((v) => v.toJson()).toList();
}
if (_skuAttrList != null) {
map['skuAttrList'] = _skuAttrList.map((v) => v.toJson()).toList();
}
map['skuCode'] = _skuCode;
map['skuImg'] = _skuImg;
map['skuNameStr'] = _skuNameStr;
map['skuPrice'] = _skuPrice;
map['skuStock'] = _skuStock;
if (_skuTickets != null) {
map['skuTickets'] = _skuTickets.map((v) => v.toJson()).toList();
}
map['sort'] = _sort;
map['storeId'] = _storeId;
if (_takeType != null) {
map['takeType'] = _takeType.map((v) => v.toJson()).toList();
}
map['ticketDays'] = _ticketDays;
if (_ticketExpireTime != null) {
map['ticketExpireTime'] = _ticketExpireTime.toJson();
}
map['ticketStyle'] = _ticketStyle;
map['ticketType'] = _ticketType;
map['ticketWipedTimeTemplateId'] = _ticketWipedTimeTemplateId;
map['version'] = _version;
map['vipPrice'] = _vipPrice;
map['volume'] = _volume;
map['weight'] = _weight;
return map;
}
}
class TicketExpireTime {
TicketExpireTime({
String hour,
String minute,
String nano,
String second,}){
_hour = hour;
_minute = minute;
_nano = nano;
_second = second;
}
TicketExpireTime.fromJson(dynamic json) {
_hour = json['hour'];
_minute = json['minute'];
_nano = json['nano'];
_second = json['second'];
}
String _hour;
String _minute;
String _nano;
String _second;
TicketExpireTime copyWith({ String hour,
String minute,
String nano,
String second,
}) => TicketExpireTime( hour: hour ?? _hour,
minute: minute ?? _minute,
nano: nano ?? _nano,
second: second ?? _second,
);
String get hour => _hour;
String get minute => _minute;
String get nano => _nano;
String get second => _second;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['hour'] = _hour;
map['minute'] = _minute;
map['nano'] = _nano;
map['second'] = _second;
return map;
}
}
class SkuAttrList {
SkuAttrList({
String attrId,
String attrValueId,
String id,
String isDelete,
String skuId,
String sortOrder,}){
_attrId = attrId;
_attrValueId = attrValueId;
_id = id;
_isDelete = isDelete;
_skuId = skuId;
_sortOrder = sortOrder;
}
SkuAttrList.fromJson(dynamic json) {
_attrId = json['attrId'];
_attrValueId = json['attrValueId'];
_id = json['id'];
_isDelete = json['isDelete'];
_skuId = json['skuId'];
_sortOrder = json['sortOrder'];
}
String _attrId;
String _attrValueId;
String _id;
String _isDelete;
String _skuId;
String _sortOrder;
SkuAttrList copyWith({ String attrId,
String attrValueId,
String id,
String isDelete,
String skuId,
String sortOrder,
}) => SkuAttrList( attrId: attrId ?? _attrId,
attrValueId: attrValueId ?? _attrValueId,
id: id ?? _id,
isDelete: isDelete ?? _isDelete,
skuId: skuId ?? _skuId,
sortOrder: sortOrder ?? _sortOrder,
);
String get attrId => _attrId;
String get attrValueId => _attrValueId;
String get id => _id;
String get isDelete => _isDelete;
String get skuId => _skuId;
String get sortOrder => _sortOrder;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrId'] = _attrId;
map['attrValueId'] = _attrValueId;
map['id'] = _id;
map['isDelete'] = _isDelete;
map['skuId'] = _skuId;
map['sortOrder'] = _sortOrder;
return map;
}
}
class SkuAttrCodeDtoList {
SkuAttrCodeDtoList({
String attrCode,
String attrValueCode,}){
_attrCode = attrCode;
_attrValueCode = attrValueCode;
}
SkuAttrCodeDtoList.fromJson(dynamic json) {
_attrCode = json['attrCode'];
_attrValueCode = json['attrValueCode'];
}
String _attrCode;
String _attrValueCode;
SkuAttrCodeDtoList copyWith({ String attrCode,
String attrValueCode,
}) => SkuAttrCodeDtoList( attrCode: attrCode ?? _attrCode,
attrValueCode: attrValueCode ?? _attrValueCode,
);
String get attrCode => _attrCode;
String get attrValueCode => _attrValueCode;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrCode'] = _attrCode;
map['attrValueCode'] = _attrValueCode;
return map;
}
}
class SetMealDtoList {
SetMealDtoList({
String buyNum,
String groupId,
String productId,
String productName,
String sellPrice,
String skuId,
String storeId,}){
_buyNum = buyNum;
_groupId = groupId;
_productId = productId;
_productName = productName;
_sellPrice = sellPrice;
_skuId = skuId;
_storeId = storeId;
}
SetMealDtoList.fromJson(dynamic json) {
_buyNum = json['buyNum'];
_groupId = json['groupId'];
_productId = json['productId'];
_productName = json['productName'];
_sellPrice = json['sellPrice'];
_skuId = json['skuId'];
_storeId = json['storeId'];
}
String _buyNum;
String _groupId;
String _productId;
String _productName;
String _sellPrice;
String _skuId;
String _storeId;
SetMealDtoList copyWith({ String buyNum,
String groupId,
String productId,
String productName,
String sellPrice,
String skuId,
String storeId,
}) => SetMealDtoList( buyNum: buyNum ?? _buyNum,
groupId: groupId ?? _groupId,
productId: productId ?? _productId,
productName: productName ?? _productName,
sellPrice: sellPrice ?? _sellPrice,
skuId: skuId ?? _skuId,
storeId: storeId ?? _storeId,
);
String get buyNum => _buyNum;
String get groupId => _groupId;
String get productId => _productId;
String get productName => _productName;
String get sellPrice => _sellPrice;
String get skuId => _skuId;
String get storeId => _storeId;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['buyNum'] = _buyNum;
map['groupId'] = _groupId;
map['productId'] = _productId;
map['productName'] = _productName;
map['sellPrice'] = _sellPrice;
map['skuId'] = _skuId;
map['storeId'] = _storeId;
return map;
}
}
class ProductSetMeals {
ProductSetMeals({
String groupName,
String optionalNumber,
List<ProductInfoList> productInfoList,
String totalNumber,}){
_groupName = groupName;
_optionalNumber = optionalNumber;
_productInfoList = productInfoList;
_totalNumber = totalNumber;
}
ProductSetMeals.fromJson(dynamic json) {
_groupName = json['groupName'];
_optionalNumber = json['optionalNumber'];
if (json['productInfoList'] != null) {
_productInfoList = [];
json['productInfoList'].forEach((v) {
_productInfoList.add(ProductInfoList.fromJson(v));
});
}
_totalNumber = json['totalNumber'];
}
String _groupName;
String _optionalNumber;
List<ProductInfoList> _productInfoList;
String _totalNumber;
ProductSetMeals copyWith({ String groupName,
String optionalNumber,
List<ProductInfoList> productInfoList,
String totalNumber,
}) => ProductSetMeals( groupName: groupName ?? _groupName,
optionalNumber: optionalNumber ?? _optionalNumber,
productInfoList: productInfoList ?? _productInfoList,
totalNumber: totalNumber ?? _totalNumber,
);
String get groupName => _groupName;
String get optionalNumber => _optionalNumber;
List<ProductInfoList> get productInfoList => _productInfoList;
String get totalNumber => _totalNumber;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['groupName'] = _groupName;
map['optionalNumber'] = _optionalNumber;
if (_productInfoList != null) {
map['productInfoList'] = _productInfoList.map((v) => v.toJson()).toList();
}
map['totalNumber'] = _totalNumber;
return map;
}
}
class ProductInfoList {
ProductInfoList({
bool allSku,
bool markProductNone,
String number,
List<ProductAttrInfoList> productAttrInfoList,
String productId,
String productImg,
String productName,
List<SkuInfoList> skuInfoList,
String storeId,}){
_allSku = allSku;
_markProductNone = markProductNone;
_number = number;
_productAttrInfoList = productAttrInfoList;
_productId = productId;
_productImg = productImg;
_productName = productName;
_skuInfoList = skuInfoList;
_storeId = storeId;
}
ProductInfoList.fromJson(dynamic json) {
_allSku = json['allSku'];
_markProductNone = json['markProductNone'];
_number = json['number'];
if (json['productAttrInfoList'] != null) {
_productAttrInfoList = [];
json['productAttrInfoList'].forEach((v) {
_productAttrInfoList.add(ProductAttrInfoList.fromJson(v));
});
}
_productId = json['productId'];
_productImg = json['productImg'];
_productName = json['productName'];
if (json['skuInfoList'] != null) {
_skuInfoList = [];
json['skuInfoList'].forEach((v) {
_skuInfoList.add(SkuInfoList.fromJson(v));
});
}
_storeId = json['storeId'];
}
bool _allSku;
bool _markProductNone;
String _number;
List<ProductAttrInfoList> _productAttrInfoList;
String _productId;
String _productImg;
String _productName;
List<SkuInfoList> _skuInfoList;
String _storeId;
ProductInfoList copyWith({ bool allSku,
bool markProductNone,
String number,
List<ProductAttrInfoList> productAttrInfoList,
String productId,
String productImg,
String productName,
List<SkuInfoList> skuInfoList,
String storeId,
}) => ProductInfoList( allSku: allSku ?? _allSku,
markProductNone: markProductNone ?? _markProductNone,
number: number ?? _number,
productAttrInfoList: productAttrInfoList ?? _productAttrInfoList,
productId: productId ?? _productId,
productImg: productImg ?? _productImg,
productName: productName ?? _productName,
skuInfoList: skuInfoList ?? _skuInfoList,
storeId: storeId ?? _storeId,
);
bool get allSku => _allSku;
bool get markProductNone => _markProductNone;
String get number => _number;
List<ProductAttrInfoList> get productAttrInfoList => _productAttrInfoList;
String get productId => _productId;
String get productImg => _productImg;
String get productName => _productName;
List<SkuInfoList> get skuInfoList => _skuInfoList;
String get storeId => _storeId;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['allSku'] = _allSku;
map['markProductNone'] = _markProductNone;
map['number'] = _number;
if (_productAttrInfoList != null) {
map['productAttrInfoList'] = _productAttrInfoList.map((v) => v.toJson()).toList();
}
map['productId'] = _productId;
map['productImg'] = _productImg;
map['productName'] = _productName;
if (_skuInfoList != null) {
map['skuInfoList'] = _skuInfoList.map((v) => v.toJson()).toList();
}
map['storeId'] = _storeId;
return map;
}
}
class SkuInfoList {
SkuInfoList({
String id,
List<ProductSkuAttrList> productSkuAttrList,
String skuName,}){
_id = id;
_productSkuAttrList = productSkuAttrList;
_skuName = skuName;
}
SkuInfoList.fromJson(dynamic json) {
_id = json['id'];
if (json['productSkuAttrList'] != null) {
_productSkuAttrList = [];
json['productSkuAttrList'].forEach((v) {
_productSkuAttrList.add(ProductSkuAttrList.fromJson(v));
});
}
_skuName = json['skuName'];
}
String _id;
List<ProductSkuAttrList> _productSkuAttrList;
String _skuName;
SkuInfoList copyWith({ String id,
List<ProductSkuAttrList> productSkuAttrList,
String skuName,
}) => SkuInfoList( id: id ?? _id,
productSkuAttrList: productSkuAttrList ?? _productSkuAttrList,
skuName: skuName ?? _skuName,
);
String get id => _id;
List<ProductSkuAttrList> get productSkuAttrList => _productSkuAttrList;
String get skuName => _skuName;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = _id;
if (_productSkuAttrList != null) {
map['productSkuAttrList'] = _productSkuAttrList.map((v) => v.toJson()).toList();
}
map['skuName'] = _skuName;
return map;
}
}
/// attrId : 0
/// attrValueId : 0
/// id : 0
/// isDelete : 0
/// skuId : 0
/// sortOrder : 0
class ProductSkuAttrList {
ProductSkuAttrList({
String attrId,
String attrValueId,
String id,
String isDelete,
String skuId,
String sortOrder,}){
_attrId = attrId;
_attrValueId = attrValueId;
_id = id;
_isDelete = isDelete;
_skuId = skuId;
_sortOrder = sortOrder;
}
ProductSkuAttrList.fromJson(dynamic json) {
_attrId = json['attrId'];
_attrValueId = json['attrValueId'];
_id = json['id'];
_isDelete = json['isDelete'];
_skuId = json['skuId'];
_sortOrder = json['sortOrder'];
}
String _attrId;
String _attrValueId;
String _id;
String _isDelete;
String _skuId;
String _sortOrder;
ProductSkuAttrList copyWith({ String attrId,
String attrValueId,
String id,
String isDelete,
String skuId,
String sortOrder,
}) => ProductSkuAttrList( attrId: attrId ?? _attrId,
attrValueId: attrValueId ?? _attrValueId,
id: id ?? _id,
isDelete: isDelete ?? _isDelete,
skuId: skuId ?? _skuId,
sortOrder: sortOrder ?? _sortOrder,
);
String get attrId => _attrId;
String get attrValueId => _attrValueId;
String get id => _id;
String get isDelete => _isDelete;
String get skuId => _skuId;
String get sortOrder => _sortOrder;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrId'] = _attrId;
map['attrValueId'] = _attrValueId;
map['id'] = _id;
map['isDelete'] = _isDelete;
map['skuId'] = _skuId;
map['sortOrder'] = _sortOrder;
return map;
}
}
/// attrId : 0
/// attrName : ""
/// attrValueList : [{"attrId":0,"attrName":"","attrValueList":[{}]}]
class ProductAttrInfoList {
ProductAttrInfoList({
String attrId,
String attrName,
List<AttrValueList> attrValueList,}){
_attrId = attrId;
_attrName = attrName;
_attrValueList = attrValueList;
}
ProductAttrInfoList.fromJson(dynamic json) {
_attrId = json['attrId'];
_attrName = json['attrName'];
if (json['attrValueList'] != null) {
_attrValueList = [];
json['attrValueList'].forEach((v) {
_attrValueList.add(AttrValueList.fromJson(v));
});
}
}
String _attrId;
String _attrName;
List<AttrValueList> _attrValueList;
ProductAttrInfoList copyWith({ String attrId,
String attrName,
List<AttrValueList> attrValueList,
}) => ProductAttrInfoList( attrId: attrId ?? _attrId,
attrName: attrName ?? _attrName,
attrValueList: attrValueList ?? _attrValueList,
);
String get attrId => _attrId;
String get attrName => _attrName;
List<AttrValueList> get attrValueList => _attrValueList;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrId'] = _attrId;
map['attrName'] = _attrName;
if (_attrValueList != null) {
map['attrValueList'] = _attrValueList.map((v) => v.toJson()).toList();
}
return map;
}
}
/// attrId : 0
/// attrName : ""
/// attrValueList : [{}]
class AttrValueList {
AttrValueList({
String attrId,
String attrName,
List<dynamic> attrValueList,}){
_attrId = attrId;
_attrName = attrName;
_attrValueList = attrValueList;
}
AttrValueList.fromJson(dynamic json) {
_attrId = json['attrId'];
_attrName = json['attrName'];
if (json['attrValueList'] != null) {
_attrValueList = [];
json['attrValueList'].forEach((v) {
_attrValueList.add(v);
});
}
}
String _attrId;
String _attrName;
List<dynamic> _attrValueList;
AttrValueList copyWith({ String attrId,
String attrName,
List<dynamic> attrValueList,
}) => AttrValueList( attrId: attrId ?? _attrId,
attrName: attrName ?? _attrName,
attrValueList: attrValueList ?? _attrValueList,
);
String get attrId => _attrId;
String get attrName => _attrName;
List<dynamic> get attrValueList => _attrValueList;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrId'] = _attrId;
map['attrName'] = _attrName;
if (_attrValueList != null) {
map['attrValueList'] = _attrValueList.map((v) => v.toJson()).toList();
}
return map;
}
}

70
lib/business_system/goods/add_goods/data/product_sku_attr.dart

@ -0,0 +1,70 @@
import 'package:flutter/cupertino.dart';
class ProductSkuAttr {
TextEditingController _specsNameController;
String attrCode;
String needImg;
TextEditingController get specsNameController => _specsNameController;
String get attrName => _attrName = specsNameController.text;
String _attrName;
List<ProductSkuAttrValue> attrValueList = [];
ProductSkuAttr(){
_specsNameController = TextEditingController();
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrCode'] = attrCode;
map['needImg'] = needImg ?? false;
map['attrName'] = attrName;
if (attrValueList != null && attrValueList.isNotEmpty) {
map['attrValueList'] = attrValueList.map((e) => e.toJson()).toList();
}
return map;
}
@override
String toString() {
return 'ProductSkuAttr{attrCode: $attrCode, attrName: $attrName, needimg: $needImg, attrValueList: $attrValueList}';
}
}
class ProductSkuAttrValue {
String attrValue;
String attrValueCode;
String attrValueImage;
TextEditingController _specsValueNameController;
TextEditingController get specsValueNameController => _specsValueNameController;
ProductSkuAttrValue(){
_specsValueNameController = TextEditingController();
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['attrValue'] = attrValue;
map['attrValueCode'] = attrValueCode;
map['attrValueImage'] = attrValueImage;
return map;
}
@override
String toString() {
return 'ProductSkuAttrValue{attrValue: $attrValue, attrValueCode: $attrValueCode, attrValueImage: $attrValueImage}';
}
}

121
lib/business_system/goods/add_goods/edit_specs_detail.dart

@ -7,6 +7,8 @@ import '../../../retrofit/business_api.dart';
import '../../../retrofit/data/edit_specs_detail_list.dart';
import '../../../utils/font_weight.dart';
import '../../../view_widget/settlement_tips_dialog.dart';
import 'data/product_sku.dart';
import 'data/product_sku_attr.dart';
class EditSpecsDetail extends StatefulWidget {
final Map<String, dynamic> arguments;
@ -21,6 +23,7 @@ class EditSpecsDetail extends StatefulWidget {
class _EditSpecsDetail extends State<EditSpecsDetail> {
List<EditSpecsDetailList> editSpecsDetailList = [];
Map<String, List<String>> codeMap = {};
bool isKeyBoardShow = false;
FocusNode _focusNode = FocusNode();
BusinessApiService businessService;
@ -42,18 +45,23 @@ class _EditSpecsDetail extends State<EditSpecsDetail> {
}
});
});
List<String> skus = widget?.arguments["skus"] ?? [];
List<Map<String, String>> specsDetails =
widget.arguments["specsDetails"] ?? [];
skus.forEach((element) {
List<ProductSkuAttr> skus = widget?.arguments["skus"] ?? [];
List<String> skiStr = mergeAttrCode(skus);
List<Sku> skuList = widget.arguments["skuList"] ?? [];
print("skuList: ${skuList.map((e) => e.toJson()).toList()}");
print("skiStr: $skiStr");
skiStr.forEach((element) {
var edit = EditSpecsDetailList(element);
for(var e1 in specsDetails){
if(e1["skuName"] == element){
edit.goodPriceController.text = e1["goodPrice"];
edit.originalPriceController.text = e1["originalPrice"];
edit.packagingFeeController.text = e1["packagingFee"];
edit.specsWeightController.text = e1["specsWeight"];
edit.skuStockController.text = e1["skuStock"];
for (var e1 in skuList) {
if (e1.skuNameStr == element) {
edit.goodPriceController.text = "${e1.skuPrice}";
edit.originalPriceController.text = "${e1.applyPrice}";
edit.packagingFeeController.text = "${e1.packagingFee}";
edit.specsWeightController.text = "${e1.weight}";
edit.skuStockController.text = "${e1.skuStock}";
break;
}
}
@ -61,6 +69,67 @@ class _EditSpecsDetail extends State<EditSpecsDetail> {
});
}
///sku计算
List<String> mergeArr(List<List<String>> arr) {
var result = arr.removeAt(0);
while (arr.isNotEmpty) {
var curArr = arr.removeAt(0);
var lastArr = result;
result = [];
for (var lastVal in lastArr) {
for (var curVal in curArr) {
result.add("$lastVal $curVal");
}
}
}
return result;
}
///sku计算
List<String> mergeAttrCode(List<ProductSkuAttr> arr) {
List<String> attrValue = [];
for (ProductSkuAttr skuAttr in arr) {
attrValue = mergeName(attrValue, skuAttr.attrValueList);
}
codeMap = mergeCodeMap(codeMap, attrValue, arr);
print("attrValue: $attrValue");
print("codeMap: $codeMap");
return attrValue;
}
Map<String, List<String>> mergeCodeMap(Map<String, List<String>> resultMap, List<String> attrValue, List<ProductSkuAttr> skuAttr) {
for (String attrName in attrValue) {
for (ProductSkuAttr skuAttrValue in skuAttr) {
for (ProductSkuAttrValue skuAttrValue in skuAttrValue.attrValueList) {
if (attrName.contains("${skuAttrValue.attrValue}")) {
if (resultMap.containsKey(attrName)) {
resultMap[attrName].add(skuAttrValue.attrValueCode);
} else {
resultMap[attrName] = [skuAttrValue.attrValueCode];
}
}
}
}
}
return resultMap;
}
List<String> mergeName(List<String> attrValues, List<ProductSkuAttrValue> values) {
if (attrValues.isEmpty) {
return values.map((e) => e.attrValue).toList();
}
List<String> resultValue = [];
for (String rValue in attrValues) {
for (ProductSkuAttrValue iValue in values) {
resultValue.add("$rValue ${iValue.attrValue}");
}
}
return resultValue;
}
///
@override
void dispose() {
@ -110,26 +179,32 @@ class _EditSpecsDetail extends State<EditSpecsDetail> {
onTap: () {
bool flag = false;
String editType = "";
List<Map<String, String>> specsDetail = [];
List<Sku> skuList = [];
editSpecsDetailList.forEach((element) {
if (element.goodPriceController.text.trim() == "") {
flag = true;
editType = "请输入商品售价";
return;
} else if (element.originalPriceController.text.trim() ==
"") {
} else if (element.originalPriceController.text.trim() == "") {
flag = true;
editType = "请输入商品原价";
return;
}
specsDetail.add({
"skuName": element.specsDetailName,
"goodPrice": element.goodPriceController.text,
"originalPrice": element.originalPriceController.text == "" ? "0" :element.originalPriceController.text,
"packagingFee": element.packagingFeeController.text == "" ? "0" :element.packagingFeeController.text,
"specsWeight": element.specsWeightController.text == "" ? "0" :element.specsWeightController.text,
"skuStock": element.skuStockController.text == "" ? "0" :element.skuStockController.text
});
var productSku = Sku(
skuNameStr: element.specsDetailName,
skuPrice: element.goodPriceController.text.toString(),
applyPrice: element.originalPriceController.text == "" ? "0" : element.originalPriceController.text,
packagingFee: element.packagingFeeController.text == "" ? "0" : element.packagingFeeController.text,
weight: element.specsWeightController.text == "" ? "0" : element.specsWeightController.text,
skuStock: element.skuStockController.text == "" ? "0" : element.skuStockController.text,
skuAttrCodeDTOList: codeMap[element.specsDetailName].map((e) {
return SkuAttrCodeDtoList(
attrCode: e.substring(0, e.lastIndexOf("_value")),
attrValueCode: e,
);
}).toList(),
);
skuList.add(productSku);
});
if (flag) {
SmartDialog.show(
@ -140,7 +215,7 @@ class _EditSpecsDetail extends State<EditSpecsDetail> {
color: Color(0xFF30415B),
));
} else {
Navigator.of(context).pop(specsDetail);
Navigator.of(context).pop(skuList);
}
},
child: Container(

142
lib/business_system/goods/add_goods/set_goods_specs.dart

@ -1,11 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/business_system/goods/add_goods/data/product_sku_attr.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../../retrofit/business_api.dart';
import '../../../retrofit/data/set_specs_list.dart';
import '../../../utils/font_weight.dart';
import '../../../view_widget/settlement_tips_dialog.dart';
import 'data/product_sku.dart';
class SetGoodsSpecs extends StatefulWidget {
final Map<String, dynamic> arguments;
@ -19,8 +21,8 @@ class SetGoodsSpecs extends StatefulWidget {
}
class _SetGoodsSpecs extends State<SetGoodsSpecs> {
List<SetSpecsList> specs = [];
List<Map<String, String>> specsDetails = [];
List<ProductSkuAttr> skuAttrList = [];
List<Sku> skuList = [];
bool isKeyBoardShow = false;
FocusNode _focusNode = FocusNode();
BusinessApiService businessService;
@ -42,13 +44,10 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
}
});
});
List<dynamic> goodsSpecsDetails = widget?.arguments["goodsSpecsDetails"] ??[];
goodsSpecsDetails.forEach((element) {
var tempValue = SetSpecsList();
tempValue.specsNameController.text = element["specsName"];
tempValue.specsValues = element["specsValue"];
specsDetails.addAll(element["valueDetail"]);
specs.add(tempValue);
skuAttrList = widget?.arguments["skuAttrList"] ?? [];
skuList = widget?.arguments["skuList"] ?? [];
skuAttrList.forEach((element) {
element.specsNameController.text = element.attrName;
});
}
@ -59,22 +58,6 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
super.dispose();
}
///sku计算
List<String> mergeArr(List<List<String>> arr) {
var result = arr.removeAt(0);
while (arr.isNotEmpty) {
var curArr = arr.removeAt(0);
var lastArr = result;
result = [];
for (var lastVal in lastArr) {
for (var curVal in curArr) {
result.add("$lastVal $curVal");
}
}
}
return result;
}
@override
Widget build(BuildContext context) {
return GestureDetector(
@ -102,7 +85,7 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
children: [
ListView.builder(
padding: EdgeInsets.zero,
itemCount: specs.length,
itemCount: skuAttrList.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
@ -119,7 +102,9 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
specs.add(SetSpecsList());
ProductSkuAttr product = ProductSkuAttr();
product.attrCode = "attr_code_${skuAttrList.length}";
skuAttrList.add(product);
});
},
child: Container(
@ -148,7 +133,7 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
),
),
),
if (specs.length > 0)
if (skuAttrList.length > 0)
Padding(
padding: EdgeInsets.all(16),
child: Text(
@ -159,7 +144,7 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
fontWeight: MyFontWeight.bold,
),
)),
if (specs.length > 0)
if (skuAttrList.length > 0)
Container(
color: Colors.white,
padding: EdgeInsets.only(
@ -185,21 +170,26 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
onTap: () {
bool flag = false;
String tipText = "";
specs.forEach((element) {
skuAttrList.forEach((element) {
if (element.specsNameController.text
.trim() ==
"") {
flag = true;
tipText = "规格名称未输入,请先输入规格名称";
return;
} else if (element
.specsValues.length ==
} else if (element.attrValueList.length ==
0) {
flag = true;
tipText = "未添加规格值,请先添加规格值";
return;
}
});
for (var value1 in skuAttrList) {
int index = skuAttrList.indexOf(value1);
value1.attrCode = "attr_code_$index";
}
if (flag) {
SmartDialog.show(
clickBgDismissTemp: false,
@ -209,19 +199,16 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
color: Color(0xFF30415B),
));
} else {
List<String> skus = mergeArr(specs
.map((e) => e.specsValues)
.toList());
Navigator.of(context).pushNamed(
'/router/edit_specs_detail',
arguments: {
"skus": skus,
"specsDetails": specsDetails
"skus": skuAttrList,
"skuList": skuList
}).then((value) {
if (value != null){
specsDetails.clear();
specsDetails.addAll(value);
setState((){});
if (value != null && value is List) {
skuList.clear();
skuList.addAll(value.map((e) => e as Sku).toList());
setState(() {});
}
});
}
@ -234,9 +221,17 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
padding:
EdgeInsets.only(right: 5.w),
child: Text(
"去设置",
(skuList != null &&
skuList.isNotEmpty)
? "已设置"
: "去设置",
style: TextStyle(
color: Color(0xD9000000),
color:
(skuList != null &&
skuList
.isNotEmpty)
? Color(0xA9000000)
: Color(0xD9000000),
fontSize: 14.sp,
fontWeight: MyFontWeight.bold,
),
@ -264,42 +259,40 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
onTap: () {
bool flag = false;
String tipText = "";
List<dynamic> goodsSpecsDetail = [];
specs.forEach((element) {
if (element.specsNameController.text
.trim() ==
"") {
List<ProductSkuAttr> skuAttrs = [];
skuAttrList.forEach((element) {
if (element.specsNameController.text.trim() == "") {
flag = true;
tipText = "规格名称未输入,请先输入规格名称";
return;
} else if (element
.specsValues.length ==
0) {
} else if (element.attrValueList.length == 0) {
flag = true;
tipText = "未添加规格值,请先添加规格值";
return;
}else if(specsDetails.length == 0){
} else if (skuList.length == 0) {
flag = true;
tipText = "请设置规格明细";
return;
}
goodsSpecsDetail.add({
"specsName": element.specsNameController.text,
"specsValue":element.specsValues,
"valueDetail":specsDetails
});
skuAttrs.add(element);
});
if (flag) {
SmartDialog.show(
clickBgDismissTemp: false,
widget: SettlementTips(
() {},
() {},
text: tipText,
color: Color(0xFF30415B),
));
} else {
print(goodsSpecsDetail);
Navigator.of(context).pop(goodsSpecsDetail);
print("skuAttrs:$skuAttrs");
skuList.forEach((element) {
print("skuList: ${element.toJson()}");
});
Navigator.of(context).pop({
"skuAttrList": skuAttrs,
"skuList": skuList,
});
}
},
child: Container(
@ -354,7 +347,7 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
),
Expanded(
child: TextField(
controller: specs[index].specsNameController,
controller: skuAttrList[index].specsNameController,
decoration: InputDecoration(
hintText: "请输入规格名称",
hintTextDirection: TextDirection.rtl,
@ -405,12 +398,23 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
'/router/set_goods_specs_value',
arguments: {
"storeId": "",
"specsValues": specs[index].specsValues
"attrCode": skuAttrList[index].attrCode,
"attrValues": skuAttrList[index].attrValueList
}).then((value) {
if (value != null)
if (value != null && value is Map && value["attrValues"] is List<String>) {
String code = value["attrCode"];
List<String> attrValues = value["attrValues"];
print("value: $value");
setState(() {
specs[index].specsValues = value;
skuAttrList[index].attrValueList = attrValues.map((e) {
int index = attrValues.indexOf(e);
var product = ProductSkuAttrValue();
product.attrValue = e;
product.attrValueCode = "${code}_value_$index";
return product;
}).toList();
});
}
});
},
child: Row(
@ -419,10 +423,10 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
children: [
Expanded(
child: Text(
specs[index].specsValues.length != 0
? specs[index]
.specsValues
.map((e) => e)
skuAttrList[index].attrValueList.length != 0
? skuAttrList[index]
.attrValueList
.map((e) => e.attrValue)
.toString()
.replaceAll("(", "")
.replaceAll(")", "")
@ -457,7 +461,7 @@ class _SetGoodsSpecs extends State<SetGoodsSpecs> {
GestureDetector(
onTap: () {
setState(() {
specs.removeAt(index);
skuAttrList.removeAt(index);
});
},
child: Padding(

48
lib/business_system/goods/add_goods/set_goods_specs_value.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/business_system/goods/add_goods/data/product_sku_attr.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../../retrofit/business_api.dart';
@ -8,6 +9,7 @@ import '../../../retrofit/data/set_specs_value_list.dart';
import '../../../utils/font_weight.dart';
import '../../../view_widget/settlement_tips_dialog.dart';
///
class SetGoodsSpecsValue extends StatefulWidget {
final Map<String, dynamic> arguments;
@ -20,7 +22,8 @@ class SetGoodsSpecsValue extends StatefulWidget {
}
class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
List<SetSpecsValueList> specsValue = [];
List<ProductSkuAttrValue> attrValues = [];
String attrCode;
bool isKeyBoardShow = false;
FocusNode _focusNode = FocusNode();
BusinessApiService businessService;
@ -42,11 +45,11 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
}
});
});
List<String> specsValues = widget.arguments["specsValues"] ?? [];
specsValues.forEach((element) {
var temp = SetSpecsValueList();
temp.specsValueNameController.text = element;
specsValue.add(temp);
attrValues = widget.arguments["attrValues"] ?? [];
attrCode = widget.arguments["attrCode"] ?? "";
print("arguments: ${widget.arguments}");
attrValues.forEach((element) {
element.specsValueNameController.text = element.attrValue;
});
}
@ -86,7 +89,7 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
color: Colors.white,
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: specsValue.length,
itemCount: attrValues.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
@ -103,7 +106,7 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
specsValue.add(SetSpecsValueList());
attrValues.add(ProductSkuAttrValue());
FocusScope.of(context).unfocus();
});
},
@ -144,26 +147,23 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
bool flag = false;
List<String> values = [];
specsValue.forEach((element) {
if (element.specsValueNameController.text == "") {
flag = true;
return;
}
values.add(element.specsValueNameController.text);
});
if (flag) {
if (attrValues.any((element) => element.specsValueNameController.text == "")) {
SmartDialog.show(
clickBgDismissTemp: false,
widget: SettlementTips(
() {},
() {},
text: "还有规格未输入值,请输入完整",
color: Color(0xFF30415B),
));
} else {
Navigator.of(context).pop(values);
return;
}
List<String> values = attrValues.map((element) {
return element.specsValueNameController.text;
}).toList();
Navigator.of(context).pop({
"attrCode": attrCode,
"attrValues": values,
});
},
child: Container(
color: Colors.white,
@ -206,7 +206,7 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
GestureDetector(
onTap: () {
setState(() {
specsValue.removeAt(index);
attrValues.removeAt(index);
});
},
child: Container(
@ -220,7 +220,7 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
),
Expanded(
child: TextField(
controller: specsValue[index].specsValueNameController,
controller: attrValues[index].specsValueNameController,
decoration: InputDecoration(
hintText: "请输入规格值名称",
hintStyle: TextStyle(
@ -239,7 +239,7 @@ class _SetGoodsSpecsValue extends State<SetGoodsSpecsValue> {
),
],
),
if (specsValue.length - 1 > index)
if (attrValues.length - 1 > index)
Container(
width: double.infinity,
height: 1.h,

36
lib/business_system/goods/add_goods/set_meal.dart

@ -47,10 +47,10 @@ class _SetMeal extends State<SetMeal> {
List<dynamic> mealDetails = widget?.arguments["mealDetails"] ??[];
mealDetails.forEach((element) {
var tempValue = SetSpecsMealList();
tempValue.groupsNameController.text = element["groupsName"];
tempValue.groupsTotal = element["groupsTotal"];
tempValue.optionalNum = element["optionalNum"];
tempValue.goodsMeal = element["goodsDetail"];
tempValue.groupsNameController.text = element["groupName"];
tempValue.groupsTotal = element["totalNumber"];
tempValue.optionalNum = element["optionalNumber"];
tempValue.goodsMeal = element["productInfoList"];
specsMeal.add(tempValue);
});
}
@ -103,10 +103,10 @@ class _SetMeal extends State<SetMeal> {
return;
}
mealDetail.add({
"groupsName":element.groupsNameController.text,
"groupsTotal":element.groupsTotal,
"optionalNum":element.optionalNum,
"goodsDetail":element.goodsMeal
"groupName": element.groupsNameController.text,
"totalNumber":element.groupsTotal,
"optionalNumber":element.optionalNum,
"productInfoList":element.goodsMeal
});
});
if (flag) {
@ -397,11 +397,17 @@ class _SetMeal extends State<SetMeal> {
Navigator.of(context).pushNamed('/router/batch_shelf',
arguments: {
"storeId": widget.arguments["storeId"],
"titleName": "选择商品"
"titleName": "选择商品",
"groupNum": specsMeal[index].groupsTotal
}).then((value) {
specsMeal[index].goodsMeal.clear();
specsMeal[index].goodsMeal.addAll(value);
setState(() {});
if (value != null && value is List) {
if (specsMeal[index].goodsMeal == null) {
specsMeal[index].goodsMeal = [];
}
specsMeal[index].goodsMeal.clear();
specsMeal[index].goodsMeal.addAll(value.map((e) => e as Map<String, dynamic>).toList());
setState(() {});
}
});
},
child: Container(
@ -563,7 +569,7 @@ class _SetMeal extends State<SetMeal> {
Widget addGoodsItem(specsIndex, index) {
return Container(
color: Colors.white,
margin: EdgeInsets.symmetric(vertical: 12.h),
margin: EdgeInsets.symmetric(vertical: 8),
padding: EdgeInsets.only(
left: 16.w,
top: 20.h,
@ -575,7 +581,7 @@ class _SetMeal extends State<SetMeal> {
children: [
Expanded(
child: Text(
specsMeal[specsIndex]?.goodsMeal[index]["goodsName"] ?? "",
specsMeal[specsIndex]?.goodsMeal[index]["productName"] ?? "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@ -599,7 +605,7 @@ class _SetMeal extends State<SetMeal> {
),
Expanded(
child: Text(
specsMeal[specsIndex]?.goodsMeal[index]["goodsNum"] ?? "",
specsMeal[specsIndex]?.goodsMeal[index]["number"] ?? "",
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFF000000),

78
lib/business_system/goods/on_sale/batch_shelf.dart

@ -1,3 +1,5 @@
import 'dart:ffi';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
@ -40,12 +42,14 @@ class _BatchShelf extends State<BatchShelf> {
BusinessApiService businessService;
ProductGroupList productGroupList;
List<AdminProductVoList> adminProductVoList = [];
List<AdminProductVoList> selectedProductVoList = [];
List<dynamic> productIds = [];
int _loadCount = 0;
int _pageIndex = 1;
int groupIndex = -1;
String networkError = "";
int networkStatus = 0;
int groupNum = 1;
String titleName;
@override
@ -53,6 +57,7 @@ class _BatchShelf extends State<BatchShelf> {
super.initState();
_onRefresh();
titleName = widget?.arguments["titleName"] ?? "";
groupNum = widget?.arguments["groupNum"] ?? 1;
}
@override
@ -134,6 +139,14 @@ class _BatchShelf extends State<BatchShelf> {
if (!mounted) return;
if (baseData != null && baseData.isSuccess) {
adminProductVoList.addAll(baseData?.data?.adminProductVOList ?? []);
//
if (selectedProductVoList.isNotEmpty) {
adminProductVoList.forEach((element) {
element.isSelect = selectedProductVoList.any((e) => e.id == element.id);
});
}
if ((baseData?.data?.adminProductVOList ?? []).isEmpty ||
adminProductVoList.length == baseData.data.total) {
_refreshController.loadNoData();
@ -201,7 +214,7 @@ class _BatchShelf extends State<BatchShelf> {
action: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
List<Map<String, String>> goodsMeal = [];
List<Map<String, dynamic>> goodsMeal = [];
if (titleName == "批量下架") {
if (productIds.length != 0) productIds.clear();
adminProductVoList.forEach((element) {
@ -215,24 +228,29 @@ class _BatchShelf extends State<BatchShelf> {
}
} else {
if (goodsMeal.length != 0) goodsMeal.clear();
adminProductVoList.forEach((element) {
if (element.isSelect)
goodsMeal.add({
"goodsName": element.productName,
"goodsNum": element.goodsNumber.toString()
});
});
Navigator.of(context).pop(goodsMeal);
if (groupNum != selectedProductVoList.length) {
SmartDialog.showToast("选择的商品与分组总数不一致", alignment: Alignment.center);
return;
}
goodsMeal = selectedProductVoList.map((e) => {
"productId": e.id,
"storeId": e.storeId,
"skuInfoList": e.productSkuVOList,
"productAttrInfoList": e.attrList,
"productName": e.productName,
"number": e.goodsNumber.toString()
}).toList();
if (goodsMeal.length == 0) {
SmartDialog.showToast("请选择要增加的商品", alignment: Alignment.center);
return;
}
Navigator.of(context).pop(goodsMeal);
}
},
child: Container(
alignment: Alignment.center,
child: Text(
S.of(context).queren,
"${S.of(context).queren}(${selectedProductVoList.length}/${groupNum})",
style: TextStyle(
color: Color(0xFF30415B),
fontSize: 14.sp,
@ -450,13 +468,13 @@ class _BatchShelf extends State<BatchShelf> {
);
}
Widget shelfGoodsItem(AdminProductVoList adminProductVoList) {
Widget shelfGoodsItem(AdminProductVoList adminProductVo) {
return Container(
margin: EdgeInsets.only(bottom: 21.h, left: 16.w),
child: Row(
children: [
MImage(
adminProductVoList?.productImg ?? "",
adminProductVo?.productImg ?? "",
width: 77.h,
height: 77.h,
fit: BoxFit.cover,
@ -472,7 +490,7 @@ class _BatchShelf extends State<BatchShelf> {
Padding(
padding: EdgeInsets.only(top: 2.h),
child: Text(
adminProductVoList?.productName ?? "",
adminProductVo?.productName ?? "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@ -484,7 +502,7 @@ class _BatchShelf extends State<BatchShelf> {
Row(
children: [
Text(
"库存${adminProductVoList?.stock ?? 0}",
"库存${adminProductVo?.stock ?? 0}",
style: TextStyle(
fontSize: 10.sp,
fontWeight: MyFontWeight.regular,
@ -496,7 +514,7 @@ class _BatchShelf extends State<BatchShelf> {
),
Expanded(
child: Text(
"销量${adminProductVoList?.sellCount ?? 0}",
"销量${adminProductVo?.sellCount ?? 0}",
style: TextStyle(
fontSize: 10.sp,
fontWeight: MyFontWeight.regular,
@ -504,11 +522,21 @@ class _BatchShelf extends State<BatchShelf> {
),
)),
Checkbox(
value: adminProductVoList.isSelect,
value: adminProductVo.isSelect,
onChanged: (a) {
if (!adminProductVo.isSelect) {
if (selectedProductVoList.length >= groupNum) {
SmartDialog.showToast("商品分组总数只有${groupNum}个,无法添加更多", alignment: Alignment.center);
return;
}
}
setState(() {
adminProductVoList.isSelect =
!adminProductVoList.isSelect;
adminProductVo.isSelect = !adminProductVo.isSelect;
if (adminProductVo.isSelect) {
selectedProductVoList.add(adminProductVo);
} else {
selectedProductVoList.remove(adminProductVo);
}
});
},
shape: RoundedRectangleBorder(
@ -537,7 +565,7 @@ class _BatchShelf extends State<BatchShelf> {
),
),
TextSpan(
text: adminProductVoList?.price ?? "",
text: adminProductVo?.price ?? "",
style: TextStyle(
fontSize: 18.sp,
fontWeight: MyFontWeight.medium,
@ -552,9 +580,9 @@ class _BatchShelf extends State<BatchShelf> {
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
if (adminProductVoList.goodsNumber <= 1) return;
adminProductVoList?.goodsNumber =
adminProductVoList.goodsNumber - 1;
if (adminProductVo.goodsNumber <= 1) return;
adminProductVo?.goodsNumber =
adminProductVo.goodsNumber - 1;
});
},
child: Container(
@ -566,7 +594,7 @@ class _BatchShelf extends State<BatchShelf> {
))),
if (titleName == "选择商品")
Text(
adminProductVoList?.goodsNumber?.toString() ?? "",
adminProductVo?.goodsNumber?.toString() ?? "",
style: TextStyle(
color: Color(0xD9000000),
fontSize: 20.sp,
@ -578,8 +606,8 @@ class _BatchShelf extends State<BatchShelf> {
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
adminProductVoList.goodsNumber =
adminProductVoList.goodsNumber + 1;
adminProductVo.goodsNumber =
adminProductVo.goodsNumber + 1;
});
},
child: Container(

1
lib/main.dart

@ -275,7 +275,6 @@ class MyApp extends StatelessWidget {
if(lastRoutePage?.settings?.name == "/router/personal_page"
&& lastRoutePage.navigator != null)
lastRoutePage.navigator.pop();
}
final Function pageContentBuilder = routers[name];
if (pageContentBuilder != null) {

2
lib/retrofit/business_api.dart

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio_log/interceptor/dio_log_interceptor.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -94,6 +95,7 @@ abstract class BusinessApiService {
responseType: ResponseType.json,
baseUrl: baseUrl,
);
dio.interceptors.add(DioLogInterceptor());
dio.interceptors.add(
InterceptorsWrapper(onRequest: (RequestOptions options) {
debugPrint("\n======================= 请求数据 =======================");

15
lib/retrofit/data/set_specs_list.dart

@ -1,17 +1,22 @@
import 'package:flutter/cupertino.dart';
import 'package:huixiang/business_system/goods/add_goods/data/product_sku_attr.dart';
@Deprecated("更换为:ProductSkuAttr")
class SetSpecsList {
TextEditingController _specsNameController;
List<String> _specsValues = [];
List<ProductSkuAttrValue> _specsValues = [];
String _specsCode = "";
TextEditingController get specsNameController => _specsNameController;
List<ProductSkuAttrValue> get specsValues => _specsValues;
String get specsCode => _specsCode;
List<String> get specsValues => _specsValues;
set specsValues(List<String> value) {
set specsValues(List<ProductSkuAttrValue> value) {
_specsValues = value;
}
set specsCode(String value) {
_specsCode = value;
}
SetSpecsList(){
_specsNameController = TextEditingController();

6
lib/retrofit/data/set_specs_meal_list.dart

@ -2,16 +2,16 @@ import 'package:flutter/cupertino.dart';
class SetSpecsMealList {
TextEditingController _groupsNameController;
List<Map<String, String>> _goodsMeal = [];
List<Map<String, dynamic>> _goodsMeal = [];
num _groupsTotal = 1;
num _optionalNum = 1;
TextEditingController get groupsNameController => _groupsNameController;
List<Map<String, String>> get goodsMeal => _goodsMeal;
List<Map<String, dynamic>> get goodsMeal => _goodsMeal;
set goodsMeal(List<Map<String, String>> value) {
set goodsMeal(List<Map<String, dynamic>> value) {
_goodsMeal = value;
}

1
lib/retrofit/data/set_specs_value_list.dart

@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
@Deprecated("更换为:ProductSkuAttrValue")
class SetSpecsValueList {
TextEditingController _specsValueNameController;

198
pubspec.lock

File diff suppressed because it is too large Load Diff

3
pubspec.yaml

@ -51,7 +51,8 @@ dependencies:
rxdart: ^0.26.0
retrofit: ^1.3.4+1
json_annotation: ^3.1.1
logger: ^1.0.0
logger: ^2.0.2+1
dio_log: ^1.3.5
pin_input_text_field: ^4.1.2
android_intent_plus: ^1.0.2

Loading…
Cancel
Save