import 'dart:convert'; import 'dart:io'; import 'package:bbyyy/beans/commodity_category_bean_entity.dart'; import 'package:bbyyy/beans/goods_bean_entity.dart'; import 'package:bbyyy/beans/my_shop_bean_entity.dart'; import 'package:bbyyy/beans/upload_image_bean_entity.dart'; import 'package:bbyyy/https/MyDio.dart'; import 'package:bbyyy/https/my_request.dart'; import 'package:bbyyy/https/url.dart'; import 'package:bbyyy/my_tools/const.dart'; import 'package:bbyyy/my_tools/dims.dart'; import 'package:bbyyy/my_tools/easy_loading/easy_loading.dart'; import 'package:bbyyy/my_tools/event_bus.dart'; import 'package:bbyyy/my_tools/my_colors.dart'; import 'package:bbyyy/my_tools/my_cookie.dart'; import 'package:bbyyy/my_tools/my_datas.dart'; import 'package:bbyyy/my_tools/my_tools.dart'; import 'package:bbyyy/my_tools/my_views.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; class ReleaseGoodsPage extends StatefulWidget { GoodsBeanDataData data; String shopName; ReleaseGoodsPage(this.data,this.shopName); @override _ReleaseGoodsPageState createState() => _ReleaseGoodsPageState(); } class _ReleaseGoodsPageState extends State { List> sortItems = []; List> sortItems1 = []; String typeValue = ''; String typeValue1 = ''; File _frontCover; TextEditingController _title = TextEditingController(); TextEditingController _costOfProduction = TextEditingController(); TextEditingController _markedPrice = TextEditingController(); TextEditingController _num = TextEditingController(); TextEditingController _description = TextEditingController(); List shops = []; bool onSale = true; List commodityCategoryBeanData = []; var detailsPictures = []; @override initState() { // TODO: implement initState super.initState(); detailsPictures.add(null); queryGang(); initCC(); if (widget.data != null) { print(widget.data.pictures); _title.text = widget.data.title; _costOfProduction.text = widget.data.originalPrice.toString(); onSale = widget.data.onSale; _markedPrice.text = widget.data.price.toString(); _num.text = widget.data.stock.toString(); _description.text = widget.data.description; picturesPath = widget.data.pictures; picturesPath.split(',').forEach((element) { if (detailsPictures.length < 6) { detailsPictures.insert(detailsPictures.length - 1, element); } else if (detailsPictures.length == 6) { detailsPictures[5] = element; } }); } } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { MyTools().hideKeyboard(context); }, child: Scaffold( body: Column( children: [ MyViews() .myAppBar(widget.data == null ? '发布商品' : '修改商品', context, []), Expanded( child: SingleChildScrollView( child: Column( children: [ Container( color: Colors.white, child: Column( children: [ Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '商品名称', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: TextField( textAlign: TextAlign.end, controller: _title, cursorColor: MyColors.cFF4233, cursorWidth: 1.0, onTap: () {}, decoration: InputDecoration( border: InputBorder.none, disabledBorder: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, isDense: true, hintText: '请输入', hintStyle: TextStyle( color: MyColors.c999999, fontSize: 14), contentPadding: const EdgeInsets.fromLTRB( 14, 4.5, 8, 4.5), ), maxLines: 1, style: TextStyle( color: MyColors.c333333, fontSize: 14, height: 1.3, letterSpacing: 0.2), keyboardType: TextInputType.text, onChanged: (t) {}, ), ), ) ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '封面图片', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: GestureDetector( onTap: () async { _frontCover = await selectImage(); setState(() {}); }, behavior: HitTestBehavior.translucent, child: Container( alignment: Alignment.centerRight, child: _frontCover == null ? (widget.data == null ? SvgPicture.asset( 'images/svg/更换头像.svg', height: 40, width: 40, ) : MyViews().netImg( imgURL(widget.data.coverPath), 40, 40)) : ClipRRect( child: Image.file( _frontCover, height: 40, width: 40, ), borderRadius: BorderRadius.circular(4), ), ), ), ) ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 4, bottom: 4), child: Row( children: [ Text( '商品类型', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: DropdownButtonHideUnderline( child: DropdownButton( items: sortItems, onChanged: (value) { setState(() { typeValue = value; }); }, value: typeValue, ), ), ), ) ], ), ), Visibility( visible: widget.data == null, child: Column( children: [ Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 4, bottom: 4), child: Row( children: [ Text( '所属货帮', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: DropdownButtonHideUnderline( child: DropdownButton( items: sortItems1, onChanged: (value) { setState(() { typeValue1 = value; }); }, value: typeValue1, ), ), ), ) ], ), ), ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '原价', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: TextField( textAlign: TextAlign.end, controller: _costOfProduction, cursorColor: MyColors.cFF4233, cursorWidth: 1.0, onTap: () {}, decoration: InputDecoration( border: InputBorder.none, disabledBorder: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, isDense: true, hintText: '请输入', hintStyle: TextStyle( color: MyColors.c999999, fontSize: 14), contentPadding: const EdgeInsets.fromLTRB( 14, 4.5, 8, 4.5), ), maxLines: 1, style: TextStyle( color: MyColors.c333333, fontSize: 14, height: 1.3, letterSpacing: 0.2), keyboardType: TextInputType.number, onChanged: (t) {}, ), ), ) ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '标价', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: TextField( textAlign: TextAlign.end, controller: _markedPrice, cursorColor: MyColors.cFF4233, cursorWidth: 1.0, onTap: () {}, decoration: InputDecoration( border: InputBorder.none, disabledBorder: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, isDense: true, hintText: '请输入', hintStyle: TextStyle( color: MyColors.c999999, fontSize: 14), contentPadding: const EdgeInsets.fromLTRB( 14, 4.5, 8, 4.5), ), maxLines: 1, style: TextStyle( color: MyColors.c333333, fontSize: 14, height: 1.3, letterSpacing: 0.2), keyboardType: TextInputType.number, onChanged: (t) {}, ), ), ) ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '数量', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: TextField( textAlign: TextAlign.end, controller: _num, cursorColor: MyColors.cFF4233, cursorWidth: 1.0, onTap: () {}, decoration: InputDecoration( border: InputBorder.none, disabledBorder: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, isDense: true, hintText: '请输入', hintStyle: TextStyle( color: MyColors.c999999, fontSize: 14), contentPadding: const EdgeInsets.fromLTRB( 14, 4.5, 8, 4.5), ), maxLines: 1, style: TextStyle( color: MyColors.c333333, fontSize: 14, height: 1.3, letterSpacing: 0.2), keyboardType: TextInputType.number, onChanged: (t) {}, ), ), ) ], ), ), Container( height: 0.5, color: MyColors.cE7E7E7, margin: EdgeInsets.only(left: 16, right: 14), ), Padding( padding: EdgeInsets.only( left: 16, right: 13, top: 15, bottom: 15), child: Row( children: [ Text( '是否上架', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), Expanded( child: Container( alignment: Alignment.centerRight, child: CupertinoSwitch( value: onSale, activeColor: MyColors.cFF4233, onChanged: (v) { setState(() { onSale = v; }); }, ), ), ) ], ), ), ], ), margin: EdgeInsets.only(top: 10), ), Container( margin: EdgeInsets.only(top: 10), color: Colors.white, child: Column( children: [ Container( width: double.infinity, margin: EdgeInsets.only(left: 16, top: 17), child: Text( '商品描述', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), ), Container( margin: EdgeInsets.only(left: 15, right: 15, top: 17), constraints: BoxConstraints(minHeight: 86), decoration: BoxDecoration( border: Border.all(color: MyColors.cE7E7E7, width: 1), borderRadius: BorderRadius.all( Radius.circular(4), ), ), child: TextField( controller: _description, cursorColor: MyColors.cFF4233, maxLines: null, cursorWidth: 1.0, onTap: () {}, decoration: InputDecoration( border: InputBorder.none, disabledBorder: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, isDense: true, hintText: '请输入', hintStyle: TextStyle( color: MyColors.c999999, fontSize: 14), contentPadding: const EdgeInsets.fromLTRB(14, 4.5, 8, 4.5), ), style: TextStyle( color: MyColors.c333333, fontSize: 14, height: 1.3, letterSpacing: 0.2), keyboardType: TextInputType.text, onChanged: (t) {}, ), ), Container( width: double.infinity, margin: EdgeInsets.only(left: 16, top: 17), child: Text( '商品图片', style: TextStyle( color: MyColors.c333333, fontSize: 15), ), ), Container( height: detailsPictures.length > 3 ? 279 : 137, margin: EdgeInsets.only(bottom: 15, top: 15), child: GridView.builder( padding: EdgeInsets.symmetric(horizontal: 15), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, childAspectRatio: 102 / 137, mainAxisSpacing: 5, crossAxisSpacing: (MediaQuery.of(context).size.width - 336) / 2), itemBuilder: (BuildContext context, int index) { return GestureDetector( child: picItem(detailsPictures[index]), onTap: () { selectPic(detailsPictures[index]); }, behavior: HitTestBehavior.translucent, ); }, itemCount: detailsPictures.length, physics: NeverScrollableScrollPhysics(), ), ), ], ), ), GestureDetector( onTap: () { if (widget.data == null) { checkData(); } else { modifyCargo(); } }, behavior: HitTestBehavior.translucent, child: Container( width: double.infinity, height: 50, color: Colors.white, child: Text( widget.data == null ? '发布' : '保存', style: TextStyle(color: MyColors.cFF4233, fontSize: 16), ), alignment: Alignment.center, margin: EdgeInsets.only(top: 10, bottom: 20), ), ) ], ), ), ) ], ), backgroundColor: MyColors.cF7F7F7, ), ); } queryGang() { MyDio().query({ "key": "shop_user", "filters": { "or": true, "conditions": [ "role!=$shopUserOwner", "user_uid==${MyCookie().getUID()}", "review_state==1" ], "filters": [ { "conditions": [ "role==$shopUserOwner", "user_uid==${MyCookie().getUID()}" ] } ] }, "dims": shopUserDims, "paging": [1, 2000] }, (response, hasError) { if (!hasError) { MyShopBeanEntity entity = MyShopBeanEntity().fromJson(json.decode(response.data.toString())); shops = entity.data.data; shops.forEach((element) { //自己的公开店铺 if (!element.privateShop && element.ownerUid == MyCookie().getUID() && element.shopState == shopStateNormal) { element.canSend = true; } //自己在某个允许顾客间交易的私有店铺中 if (element.innerTrade) { element.canSend = true; } }); shops.removeWhere((element) => !element.canSend); if (shops.length == 0) { showDialog( context: context, builder: (BuildContext context) { return Center( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(8))), child: Column( children: [ Expanded( child: Center( child: Padding( padding: const EdgeInsets.only(left: 15, right: 15), child: Text( '对不起你没有可以发布商品的货帮', style: TextStyle( color: MyColors.c333333, fontSize: 16, fontWeight: FontWeight.normal, decoration: TextDecoration.none), ), ), ), ), Container( height: 0.5, color: MyColors.cE7E7E7, ), Row( children: [ Expanded( child: GestureDetector( onTap: () async { Navigator.pop(context); Navigator.pop(context); }, behavior: HitTestBehavior.translucent, child: Container( alignment: Alignment.center, height: 55, child: Text( '确定', style: TextStyle( color: MyColors.cFF4233, fontSize: 16, fontWeight: FontWeight.normal, decoration: TextDecoration.none), ), ), )), ], ) ], ), height: 126, margin: EdgeInsets.only(left: 48, right: 48), ), ); }, ); } if (shops != null) { for (int i = 0; i < shops.length; i++) { if (i == 0) { typeValue1 = shops[i].shopName; } sortItems1.add(DropdownMenuItem( child: Text( '${shops[i].shopName}', style: TextStyle(color: MyColors.c666666, fontSize: 14), ), value: '${shops[i].shopName}', )); } if(widget.shopName!=''){ typeValue1 = widget.shopName; } } setState(() {}); } }, (error) {}); } void checkData() { if (shops.isEmpty) { showToast('货帮获取失败,请稍后再试'); return; } if (_title.text.isEmpty) { showToast('请填写商品名称'); return; } if (_frontCover == null) { showToast('请选择商品封面'); return; } bool hasP = false; detailsPictures.forEach((element) { if (element != null) { hasP = true; } }); if (!hasP) { showToast('请设置商品详情图片'); return; } if (_costOfProduction.text.isEmpty) { showToast('请填写原价'); return; } if (_markedPrice.text.isEmpty) { showToast('请填写标价'); return; } if (_num.text.isEmpty) { showToast('请填写数量'); return; } uploadCover(); } void productsOnTheShelves() { if (widget.data != null) { MyDio().update({ 'key': 'commodity', 'values': { 'id': widget.data.id, 'category': typeValue, 'title': _title.text.toString(), 'cover_path': coverPath, 'description': _description.text.toString(), 'original_price': double.parse(_costOfProduction.text.toString()), 'price': double.parse(_markedPrice.text.toString()), 'on_sale': onSale, 'stock': int.parse(_num.text.toString()), 'pictures': picturesPath, } }, (response, hasError) { if (!hasError) { showToast('保存成功'); Navigator.pop(context); EventBus().emit('uploadGoods'); } }, (error) {}); } else { int sIndex = shops.indexWhere((element) => element.shopName == typeValue1); MyDio().save({ 'key': 'commodity', 'object': { 'category': typeValue, 'shop_uid': shops[sIndex].shopUid, 'shop_name': shops[sIndex].shopName, 'shop_pic': shops[sIndex].shopPic, 'user_uid': MyCookie().getUID(), 'user_name': MyCookie().loginInformation.data.extra.name, 'user_pic': MyCookie().loginInformation.data.extra.picture, 'title': _title.text.toString(), 'cover_path': coverPath, 'description': _description.text.toString(), 'original_price': double.parse(_costOfProduction.text.toString()), 'price': double.parse(_markedPrice.text.toString()), 'on_sale': onSale, 'stock': int.parse(_num.text.toString()), 'pictures': picturesPath, } }, (response, hasError) { if (!hasError) { showToast('上传成功'); Navigator.pop(context); EventBus().emit('uploadGoods'); } }, (error) {}); } } String coverPath = ''; String picturesPath = ''; void uploadCover() { if (_frontCover == null) { if (widget.data != null) { coverPath = widget.data.coverPath; upPic(); } else { showToast('请选择商品封面'); return; } } else { EasyLoading.instance ..contentPadding = EdgeInsets.symmetric(horizontal: 20, vertical: 12) ..alignment = Alignment.center ..loadingStyle = EasyLoadingStyle.light ..contentMargin = EdgeInsets.all(20); EasyLoading.show(); print('uploadCover'); upload(_frontCover, (r, hE) { if (!hE) { UploadImageBeanEntity data = UploadImageBeanEntity().fromJson(json.decode(r.data.toString())); coverPath = data.data[0].path; upPic(); } else { EasyLoading.dismiss(); } }, (e) { EasyLoading.dismiss(); }); } } Future initCC() async { commodityCategoryBeanData = await MyData().getCommodityCategoryBeanData(context); if (commodityCategoryBeanData.length > 0) { typeValue = commodityCategoryBeanData[0].name; } commodityCategoryBeanData.forEach((element) { sortItems.add(DropdownMenuItem( child: Text( '${element.name}', style: TextStyle(color: MyColors.c666666, fontSize: 14), ), value: '${element.name}', )); }); setState(() {}); } void modifyCargo() { bool havePic = false; detailsPictures.forEach((element) { if (element != null) { havePic = true; } }); if (!havePic) { showToast('请设置商品详情图片'); return; } uploadCover(); } upPic() { List fs = []; List oP = []; for (int i = 0; i < detailsPictures.length; i++) { if (detailsPictures[i] is File) { fs.add(detailsPictures[i]); } if (detailsPictures[i] is String) { oP.add(i); } } if (fs.length == 0) { detailsPictures.forEach((element) { if (element is String) { if (picturesPath == '') { picturesPath = element; } else { picturesPath = picturesPath + ',' + element; } } }); productsOnTheShelves(); } else { uploadFiles(fs, (re, hE) { if (!hE) { UploadImageBeanEntity data = UploadImageBeanEntity().fromJson(json.decode(re.data.toString())); for (int i = 0; i < data.data.length; i++) { oP.forEach((element) { if (i == element) { if (picturesPath == '') { picturesPath = detailsPictures[i]; } else { picturesPath = picturesPath + ',' + detailsPictures[i]; } } }); if (picturesPath == '') { picturesPath = data.data[i].path; } else { picturesPath = picturesPath + ',' + data.data[i].path; } } oP.forEach((element) { if (element >= picturesPath.split(',').length) { if (picturesPath == '') { picturesPath = detailsPictures[element]; } else { picturesPath = picturesPath + ',' + detailsPictures[element]; } } }); productsOnTheShelves(); } else { EasyLoading.dismiss(); } }, (e) { EasyLoading.dismiss(); }); } } Widget picItem(data) { if (data is String) { return Container( width: 102, child: Column( children: [ ClipRRect( child: MyViews().netImg(imgURL(data), 102, 102), borderRadius: BorderRadius.circular(4), ), GestureDetector( child: Container( height: 30, width: 30, margin: EdgeInsets.only(top: 5), child: Icon( Icons.cancel, color: MyColors.cFF4233, ), ), onTap: () { detailsPictures.remove(data); if (detailsPictures.length == 5 && !detailsPictures.contains(null)) { detailsPictures.add(null); } setState(() {}); }) ], ), ); } else if (data is File) { return Container( width: 102, child: Column( children: [ ClipRRect( child: Image.file( data, height: 102, width: 102, fit: BoxFit.cover, ), borderRadius: BorderRadius.circular(4), ), GestureDetector( child: Container( height: 30, width: 30, margin: EdgeInsets.only(top: 5), child: Icon( Icons.cancel, color: MyColors.cFF4233, ), ), onTap: () { detailsPictures.remove(data); if (detailsPictures.length == 5 && !detailsPictures.contains(null)) { detailsPictures.add(null); } setState(() {}); }) ], ), ); } else { return Column( children: [ Container( height: 102, width: 102, decoration: BoxDecoration( color: MyColors.cF0F0F0, borderRadius: BorderRadius.all(Radius.circular(4))), child: Icon( Icons.add, color: MyColors.cB6B6B6, size: 44, ), ), Container( height: 35, ) ], ); } } Future selectPic(data) async { File f = await selectImage(isCover: false); if (f == null) { return; } if (data == null) { if (detailsPictures.length == 6) { detailsPictures[ detailsPictures.indexWhere((element) => element == data)] = f; } else { detailsPictures.insert(detailsPictures.length - 1, f); } } else { detailsPictures[ detailsPictures.indexWhere((element) => element == data)] = f; } setState(() {}); } }