parent
62df0e52a9
commit
d5b8424975
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 2,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.akuhome.new_recook",
|
||||
"variantName": "processDebugResources",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0",
|
||||
"outputFile": "app-debug.apk"
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,82 @@
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
|
||||
|
||||
part 'shopping_cart_list_model.g.dart';
|
||||
|
||||
|
||||
@JsonSerializable()
|
||||
class ShoppingCartBrandModel extends Object {
|
||||
int? id;
|
||||
|
||||
int? brandID;
|
||||
|
||||
String? brandLogo;
|
||||
|
||||
String? brandName;
|
||||
|
||||
List<ShoppingCartGoodsModel>? children;
|
||||
|
||||
bool? selected;
|
||||
bool? isShowMore;
|
||||
ShoppingCartBrandModel(this.id, this.brandID, this.brandLogo, this.brandName,
|
||||
this.children, this.selected) {
|
||||
this.selected = false;
|
||||
isShowMore = false;
|
||||
}
|
||||
|
||||
factory ShoppingCartBrandModel.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$ShoppingCartBrandModelFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ShoppingCartBrandModelToJson(this);
|
||||
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ShoppingCartGoodsModel extends Object {
|
||||
int? shoppingTrolleyId;
|
||||
int? goodsId;
|
||||
|
||||
String? goodsName;
|
||||
|
||||
String? mainPhotoUrl;
|
||||
|
||||
String? skuName;
|
||||
|
||||
int? skuId;
|
||||
|
||||
int? quantity;
|
||||
|
||||
num? price;
|
||||
|
||||
bool? selected;
|
||||
|
||||
int? publishStatus;
|
||||
|
||||
|
||||
ShoppingCartGoodsModel(
|
||||
this.shoppingTrolleyId,
|
||||
this.goodsId,
|
||||
this.goodsName,
|
||||
this.mainPhotoUrl,
|
||||
this.skuName,
|
||||
this.skuId,
|
||||
this.quantity,
|
||||
this.price,
|
||||
this.selected,
|
||||
this.publishStatus,
|
||||
|
||||
) {
|
||||
this.selected = false;
|
||||
}
|
||||
|
||||
factory ShoppingCartGoodsModel.fromJson(Map<String, dynamic> srcJson) =>
|
||||
_$ShoppingCartGoodsModelFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ShoppingCartGoodsModelToJson(this);
|
||||
|
||||
ShoppingCartGoodsModel.empty();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'shopping_cart_list_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
|
||||
|
||||
ShoppingCartBrandModel _$ShoppingCartBrandModelFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return ShoppingCartBrandModel(
|
||||
json['id'] as int?,
|
||||
json['brandID'] as int?,
|
||||
json['brandLogo'] as String?,
|
||||
json['brandName'] as String?,
|
||||
(json['children'] as List?)
|
||||
?.map((e) => ShoppingCartGoodsModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
json['selected'] as bool?);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ShoppingCartBrandModelToJson(
|
||||
ShoppingCartBrandModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'brandID': instance.brandID,
|
||||
'brandLogo': instance.brandLogo,
|
||||
'brandName': instance.brandName,
|
||||
'children': instance.children,
|
||||
'selected': instance.selected
|
||||
};
|
||||
|
||||
ShoppingCartGoodsModel _$ShoppingCartGoodsModelFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return ShoppingCartGoodsModel(
|
||||
json['shoppingTrolleyId'] as int?,
|
||||
json['goodsId'] as int?,
|
||||
json['goodsName'] as String?,
|
||||
json['mainPhotoUrl'] as String?,
|
||||
json['skuName'] as String?,
|
||||
json['skuId'] as int?,
|
||||
json['quantity'] as int?,
|
||||
(json['price'] as num?)?.toDouble(),
|
||||
json['selected'] as bool?,
|
||||
(json['publish_status'] as num?) as int?,
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$ShoppingCartGoodsModelToJson(
|
||||
ShoppingCartGoodsModel instance) =>
|
||||
<String, dynamic>{
|
||||
'shoppingTrolleyId': instance.shoppingTrolleyId,
|
||||
'goodsId': instance.goodsId,
|
||||
'goodsName': instance.goodsName,
|
||||
'mainPhotoUrl': instance.mainPhotoUrl,
|
||||
'skuName': instance.skuName,
|
||||
'skuId': instance.skuId,
|
||||
'quantity': instance.quantity,
|
||||
|
||||
'price': instance.price,
|
||||
|
||||
'selected': instance.selected,
|
||||
|
||||
'publish_status': instance.publishStatus,
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
import 'goods_model.dart';
|
||||
|
||||
class FootPrintModel{
|
||||
final String? title;
|
||||
final List<GoodsModel>? goodsList;
|
||||
|
||||
const FootPrintModel( {
|
||||
this.title,
|
||||
this.goodsList,
|
||||
});
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
class AddressModel{
|
||||
int? id;
|
||||
String? name;
|
||||
|
||||
String? mobile;
|
||||
|
||||
String? province;
|
||||
|
||||
String? city;
|
||||
|
||||
String? district;
|
||||
|
||||
String? address;
|
||||
|
||||
int? isDefault;
|
||||
|
||||
AddressModel({
|
||||
this.id,
|
||||
this.name,
|
||||
this.mobile,
|
||||
this.province,
|
||||
this.city,
|
||||
this.district,
|
||||
this.address,
|
||||
this.isDefault,
|
||||
});
|
||||
|
||||
factory AddressModel.empty() {
|
||||
return AddressModel(id: null,name: '',mobile: '',province: '',city: '',district: '',address: '',isDefault: 0);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// import 'package:json_annotation/json_annotation.dart';
|
||||
// part 'model.g.dart';
|
||||
//
|
||||
//
|
||||
// @JsonSerializable()
|
||||
// class Model {
|
||||
// final int id;
|
||||
// factory Model.fromJson(Map<String, dynamic> json) =>_$ModelFromJson(json);
|
||||
// Map<String,dynamic> toJson()=> _$ModelToJson(this);
|
||||
//
|
||||
// const Model({
|
||||
// required this.id,
|
||||
// });
|
||||
// }
|
@ -0,0 +1,120 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InvoiceBillListModel {
|
||||
int? id;
|
||||
int? userId;
|
||||
int? orderId;
|
||||
String? buyerName;
|
||||
String? taxNum;
|
||||
String? address;
|
||||
String? telephone;
|
||||
String? phone;
|
||||
String? email;
|
||||
String? account;
|
||||
String? message;
|
||||
num? totalAmount;
|
||||
int? invoiceStatus;
|
||||
String? fpqqlsh;
|
||||
String? ctime;
|
||||
String? failReasons;
|
||||
String? ctimeInvoice;
|
||||
String? invoiceUrl;
|
||||
|
||||
InvoiceBillListModel(
|
||||
{this.id,
|
||||
this.userId,
|
||||
this.orderId,
|
||||
this.buyerName,
|
||||
this.taxNum,
|
||||
this.address,
|
||||
this.telephone,
|
||||
this.phone,
|
||||
this.email,
|
||||
this.account,
|
||||
this.message,
|
||||
this.totalAmount,
|
||||
this.invoiceStatus,
|
||||
this.fpqqlsh,
|
||||
this.ctime,
|
||||
this.failReasons,
|
||||
this.ctimeInvoice,
|
||||
this.invoiceUrl});
|
||||
|
||||
InvoiceBillListModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
userId = json['user_id'];
|
||||
orderId = json['order_id'];
|
||||
buyerName = json['buyer_name'];
|
||||
taxNum = json['tax_num'];
|
||||
address = json['address'];
|
||||
telephone = json['telephone'];
|
||||
phone = json['phone'];
|
||||
email = json['email'];
|
||||
account = json['account'];
|
||||
message = json['message'];
|
||||
totalAmount = json['total_amount'];
|
||||
invoiceStatus = json['invoice_status'];
|
||||
fpqqlsh = json['fpqqlsh'];
|
||||
ctime = json['ctime'];
|
||||
failReasons = json['fail_reasons'];
|
||||
ctimeInvoice = json['ctime_invoice'];
|
||||
invoiceUrl = json['invoice_url'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['user_id'] = this.userId;
|
||||
data['order_id'] = this.orderId;
|
||||
data['buyer_name'] = this.buyerName;
|
||||
data['tax_num'] = this.taxNum;
|
||||
data['address'] = this.address;
|
||||
data['telephone'] = this.telephone;
|
||||
data['phone'] = this.phone;
|
||||
data['email'] = this.email;
|
||||
data['account'] = this.account;
|
||||
data['message'] = this.message;
|
||||
data['total_amount'] = this.totalAmount;
|
||||
data['invoice_status'] = this.invoiceStatus;
|
||||
data['fpqqlsh'] = this.fpqqlsh;
|
||||
data['ctime'] = this.ctime;
|
||||
data['fail_reasons'] = this.failReasons;
|
||||
data['ctime_invoice'] = this.ctimeInvoice;
|
||||
data['invoice_url'] = this.invoiceUrl;
|
||||
return data;
|
||||
}
|
||||
|
||||
String get statusString {
|
||||
switch (this.invoiceStatus) {
|
||||
case 1:
|
||||
return '开票中';
|
||||
case 2:
|
||||
return '开票异常';
|
||||
case 3:
|
||||
return '开票中';
|
||||
case 4:
|
||||
return '开票失败';
|
||||
case 5:
|
||||
return '开票成功';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
Color get statusColor {
|
||||
switch (this.invoiceStatus) {
|
||||
case 1:
|
||||
return Color(0xFF44D7B6);
|
||||
case 2:
|
||||
return Color(0xFFFF4D4F);
|
||||
case 3:
|
||||
return Color(0xFF44D7B6);
|
||||
case 4:
|
||||
return Color(0xFFFF4D4F);
|
||||
case 5:
|
||||
return Color(0xFF999999);
|
||||
default:
|
||||
return Colors.black;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
class InvoiceDetailModel {
|
||||
int? id;
|
||||
int? userId;
|
||||
int? orderId;
|
||||
String? buyerName;
|
||||
String? taxNum;
|
||||
String? address;
|
||||
String? telephone;
|
||||
String? phone;
|
||||
String? email;
|
||||
String? account;
|
||||
String? message;
|
||||
num? totalAmount;
|
||||
int? invoiceStatus;
|
||||
String? fpqqlsh;
|
||||
String? ctime;
|
||||
String? failReasons;
|
||||
String? ctimeInvoice;
|
||||
String? invoiceUrl;
|
||||
|
||||
InvoiceDetailModel(
|
||||
{this.id,
|
||||
this.userId,
|
||||
this.orderId,
|
||||
this.buyerName,
|
||||
this.taxNum,
|
||||
this.address,
|
||||
this.telephone,
|
||||
this.phone,
|
||||
this.email,
|
||||
this.account,
|
||||
this.message,
|
||||
this.totalAmount,
|
||||
this.invoiceStatus,
|
||||
this.fpqqlsh,
|
||||
this.ctime,
|
||||
this.failReasons,
|
||||
this.ctimeInvoice,
|
||||
this.invoiceUrl});
|
||||
|
||||
InvoiceDetailModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
userId = json['user_id'];
|
||||
orderId = json['order_id'];
|
||||
buyerName = json['buyer_name'];
|
||||
taxNum = json['tax_num'];
|
||||
address = json['address'];
|
||||
telephone = json['telephone'];
|
||||
phone = json['phone'];
|
||||
email = json['email'];
|
||||
account = json['account'];
|
||||
message = json['message'];
|
||||
totalAmount = json['total_amount'];
|
||||
invoiceStatus = json['invoice_status'];
|
||||
fpqqlsh = json['fpqqlsh'];
|
||||
ctime = json['ctime'];
|
||||
failReasons = json['fail_reasons'];
|
||||
ctimeInvoice = json['ctime_invoice'];
|
||||
invoiceUrl = json['invoice_url'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['user_id'] = this.userId;
|
||||
data['order_id'] = this.orderId;
|
||||
data['buyer_name'] = this.buyerName;
|
||||
data['tax_num'] = this.taxNum;
|
||||
data['address'] = this.address;
|
||||
data['telephone'] = this.telephone;
|
||||
data['phone'] = this.phone;
|
||||
data['email'] = this.email;
|
||||
data['account'] = this.account;
|
||||
data['message'] = this.message;
|
||||
data['total_amount'] = this.totalAmount;
|
||||
data['invoice_status'] = this.invoiceStatus;
|
||||
data['fpqqlsh'] = this.fpqqlsh;
|
||||
data['ctime'] = this.ctime;
|
||||
data['fail_reasons'] = this.failReasons;
|
||||
data['ctime_invoice'] = this.ctimeInvoice;
|
||||
data['invoice_url'] = this.invoiceUrl;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
class InvoiceGetBillModel {
|
||||
String? endTime;
|
||||
String? goodsName;
|
||||
num? goodsTotalAmount;
|
||||
int? orderId;
|
||||
|
||||
InvoiceGetBillModel(
|
||||
{this.endTime, this.goodsName, this.goodsTotalAmount, this.orderId});
|
||||
|
||||
InvoiceGetBillModel.fromJson(Map<String, dynamic> json) {
|
||||
endTime = json['end_time'];
|
||||
goodsName = json['goods_name'];
|
||||
goodsTotalAmount = json['goods_total_amount'];
|
||||
orderId = json['order_id'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['end_time'] = this.endTime;
|
||||
data['goods_name'] = this.goodsName;
|
||||
data['goods_total_amount'] = this.goodsTotalAmount;
|
||||
data['order_id'] = this.orderId;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
class InvoiceTitleListModel {
|
||||
int? id;
|
||||
int? uid;
|
||||
int? type;
|
||||
String? name;
|
||||
String? taxnum;
|
||||
String? address;
|
||||
String? phone;
|
||||
String? bank;
|
||||
int? defaultValue;
|
||||
|
||||
InvoiceTitleListModel({
|
||||
this.id,
|
||||
this.uid,
|
||||
this.type,
|
||||
this.name,
|
||||
this.taxnum,
|
||||
this.address,
|
||||
this.phone,
|
||||
this.bank,
|
||||
this.defaultValue,
|
||||
});
|
||||
|
||||
InvoiceTitleListModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
uid = json['uid'];
|
||||
type = json['type'];
|
||||
name = json['name'];
|
||||
taxnum = json['taxnum'];
|
||||
address = json['address'];
|
||||
phone = json['phone'];
|
||||
bank = json['bank'];
|
||||
defaultValue = json['default'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['uid'] = this.uid;
|
||||
data['type'] = this.type;
|
||||
data['name'] = this.name;
|
||||
data['taxnum'] = this.taxnum;
|
||||
data['address'] = this.address;
|
||||
data['phone'] = this.phone;
|
||||
data['bank'] = this.bank;
|
||||
data['default'] = this.defaultValue;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,282 @@
|
||||
import 'package:new_recook/constants/api.dart';
|
||||
import 'package:new_recook/gen/assets.gen.dart';
|
||||
|
||||
import '../../models/car/shopping_cart_list_model.dart';
|
||||
import '../../utils/headers.dart';
|
||||
|
||||
|
||||
typedef GoodsSelectedCallback = Function(ShoppingCartGoodsModel goods);
|
||||
class ShopCarItem extends StatefulWidget {
|
||||
final ShoppingCartBrandModel carModel;
|
||||
final GoodsSelectedCallback selectedListener;
|
||||
const ShopCarItem({Key? key, required this.carModel, required this.selectedListener,}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ShopCarItemState createState() => _ShopCarItemState();
|
||||
}
|
||||
|
||||
class _ShopCarItemState extends State<ShopCarItem> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 26.w),
|
||||
margin: EdgeInsets.symmetric(vertical: 10.w, horizontal: 20.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10))),
|
||||
child: Column(
|
||||
children: <Widget>[_brandName(), _buildGoodsList()],
|
||||
),
|
||||
);
|
||||
}
|
||||
_brandName() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(right: 20.w, left: 20.w, bottom: 10.w),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
widget.carModel.selected = ! widget.carModel.selected!;
|
||||
widget.carModel.children!.forEach((goods) {
|
||||
// 只有 不是 活动未开始 的商品才能选择
|
||||
// isEdit 编辑状态下都可以选择
|
||||
// if (!goods.isWaitPromotionStart() || widget.isEdit) {
|
||||
if (goods.publishStatus == 1) {
|
||||
goods.selected = widget.carModel.selected;
|
||||
widget.selectedListener(goods);
|
||||
} else {}
|
||||
|
||||
// }
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
height: 32.w,
|
||||
width: 32.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16.w),
|
||||
border: widget.carModel.selected!
|
||||
? null
|
||||
: Border.all(
|
||||
width: 2.w,
|
||||
color: Color(0xFFC9C9C9),
|
||||
),
|
||||
color:
|
||||
widget.carModel.selected! ? Color(0xFFDB2D2D) : Colors.transparent,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.check,
|
||||
color: Colors.white,
|
||||
size: 24.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
12.wb,
|
||||
Text(widget.carModel.brandName??'',style: TextStyle(fontSize: 34.sp,fontWeight: FontWeight.w500),)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildGoodsList() {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(
|
||||
left: 0, top: 0, right: 0, bottom: ScreenUtil().bottomBarHeight),
|
||||
itemBuilder: (_, index) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 8.w),
|
||||
child: _goodsWidget(widget.carModel.children![index], index),
|
||||
));
|
||||
},
|
||||
itemCount: widget.carModel.children!.length,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_goodsWidget(ShoppingCartGoodsModel goodsModel, int index) {
|
||||
return Container(
|
||||
height: 272.w,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, borderRadius: BorderRadius.circular(16.w)),
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: goodsModel.publishStatus == 1
|
||||
? () {
|
||||
goodsModel.selected = !goodsModel.selected!;
|
||||
bool checkAll = true;
|
||||
widget.carModel.children!.forEach((goodsItem) {
|
||||
if (!goodsItem.selected!) {
|
||||
checkAll = false;
|
||||
return;
|
||||
}
|
||||
});
|
||||
widget.carModel.selected = checkAll;
|
||||
widget.selectedListener(goodsModel);
|
||||
setState(() {});
|
||||
}
|
||||
: () {},
|
||||
child: Container(
|
||||
height: 32.w,
|
||||
width: 32.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16.w),
|
||||
border: goodsModel.publishStatus == 1&&goodsModel.selected!
|
||||
? null
|
||||
: Border.all(
|
||||
width: 2.w,
|
||||
color: Color(0xFFC9C9C9),
|
||||
),
|
||||
color:
|
||||
goodsModel.publishStatus == 1&&goodsModel.selected! ? Color(0xFFDB2D2D) : Colors.transparent,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.check,
|
||||
color: Colors.white,
|
||||
size: 24.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
_image(goodsModel),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
16.hb,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 16.w),
|
||||
child: SizedBox(
|
||||
child: Text(
|
||||
goodsModel.goodsName ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
24.wb,
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: '¥',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: goodsModel.price.toString(),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 48.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
16.wb,
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 104.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Color(0xFFAAAAAA), width: 2.w),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20.w))),
|
||||
child: Text(
|
||||
'找相似',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
)),
|
||||
Spacer(),
|
||||
],
|
||||
),
|
||||
20.hb,
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_image(ShoppingCartGoodsModel goodsModel) {
|
||||
bool sellout = false;
|
||||
if (goodsModel.publishStatus! == 1) {
|
||||
sellout = false;
|
||||
} else {
|
||||
sellout = true;
|
||||
}
|
||||
return Container(
|
||||
width: 250.w,
|
||||
height: 250.w,
|
||||
color: Colors.white,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16.w)),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: FadeInImage.assetNetwork(
|
||||
placeholder: Assets.images.placeholderNew1x1A.path,
|
||||
image: API.getImgUrl(goodsModel.mainPhotoUrl) ?? '',
|
||||
fit: BoxFit.cover,
|
||||
imageErrorBuilder: (context, error, stackTrace) {
|
||||
return Image.asset(
|
||||
Assets.images.placeholderNew1x1A.path,
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
},
|
||||
)),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: Offstage(
|
||||
offstage: !sellout,
|
||||
child: Opacity(
|
||||
opacity: 0.7,
|
||||
child: Container(
|
||||
color: Color(0x80000000),
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
Assets.images.selloutBg.path,
|
||||
width: 140.w,
|
||||
height: 140.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,244 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_pickers/pickers.dart';
|
||||
import 'package:new_recook/models/home/address_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/edit_tile.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
import '../../utils/text_utils.dart';
|
||||
|
||||
|
||||
class AddAddressPage extends StatefulWidget {
|
||||
final AddressModel? addressModel;
|
||||
|
||||
const AddAddressPage({Key? key, this.addressModel}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AddAddressPageState createState() => _AddAddressPageState();
|
||||
}
|
||||
|
||||
class _AddAddressPageState extends State<AddAddressPage> {
|
||||
AddressModel _address = AddressModel.empty();
|
||||
bool isDefault = false;
|
||||
late StateSetter _addressStateSetter;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if(widget.addressModel!=null){
|
||||
_address = widget.addressModel!;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '添加收货地址',
|
||||
body: _body()
|
||||
);
|
||||
}
|
||||
|
||||
_body(){
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
},
|
||||
child: Container(
|
||||
child: MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 10,
|
||||
),
|
||||
EditTile(
|
||||
constraints: BoxConstraints.tight(Size(double.infinity, 45)),
|
||||
title: "收货人",
|
||||
value: _address.name,
|
||||
hint: "请填写收货人姓名",
|
||||
textChanged: (value) {
|
||||
_address.name = value;
|
||||
},
|
||||
),
|
||||
Container(
|
||||
height: 3,
|
||||
),
|
||||
EditTile(
|
||||
constraints: BoxConstraints.tight(Size(double.infinity, 45)),
|
||||
title: "手机号码",
|
||||
value: _address.mobile,
|
||||
hint: "请填写收货人手机号码",
|
||||
maxLength: 11,
|
||||
textChanged: (value) {
|
||||
_address.mobile = value;
|
||||
},
|
||||
),
|
||||
Container(
|
||||
height: 3,
|
||||
),
|
||||
_addressView(),
|
||||
Container(
|
||||
height: 3,
|
||||
),
|
||||
EditTile(
|
||||
title: "详细地址",
|
||||
hint: "街道门牌号等",
|
||||
value: _address.address,
|
||||
maxLength: 100,
|
||||
maxLines: 3,
|
||||
direction: Axis.vertical,
|
||||
constraints: BoxConstraints(maxHeight: 100),
|
||||
textChanged: (value) {
|
||||
_address.address = value;
|
||||
},
|
||||
),
|
||||
30.hb,
|
||||
_defaultAddressTile(),
|
||||
100.hb,
|
||||
_saveButton(context)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
_addressView() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Pickers.showAddressPicker(context,
|
||||
initProvince: _address.province??'',
|
||||
initCity: _address.city??'',
|
||||
initTown: _address.district??'',
|
||||
onConfirm: (p,c,d){
|
||||
_address.province = p;
|
||||
_address.city = c;
|
||||
_address.district = d;
|
||||
_addressStateSetter(() {
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setSta) {
|
||||
_addressStateSetter = setSta;
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Colors.grey[200]!, width: 0.5))),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 160.w,
|
||||
child: Text(
|
||||
"所在地区",
|
||||
style:
|
||||
TextStyle(fontSize: 30.sp, fontWeight: FontWeight.w300),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
TextUtils.isEmpty(_address.province)
|
||||
? "选择地址"
|
||||
: "${_address.province}-${_address.city}${!TextUtils.isEmpty(_address.district) ? "-${_address.district}" : ""}",
|
||||
textAlign: TextAlign.end,
|
||||
style: TextStyle(fontSize: 28.sp, fontWeight: FontWeight.w300),
|
||||
)),
|
||||
Icon(
|
||||
Icons.navigate_next,
|
||||
size: 32.w,
|
||||
color: Colors.black,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Container _saveButton(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 50.w),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_saveAddress();
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.horizontal(
|
||||
left: Radius.circular(40.w), right: Radius.circular(40.w)),
|
||||
),
|
||||
height: 80.w,
|
||||
padding: EdgeInsets.symmetric(vertical: 8.w),
|
||||
child: Text(
|
||||
"保存并使用",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_saveAddress(){
|
||||
Get.back(result: true);
|
||||
}
|
||||
|
||||
_defaultAddressTile() {
|
||||
|
||||
|
||||
return Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
margin: EdgeInsets.all(20.w),
|
||||
padding:
|
||||
EdgeInsets.only(top: 24.w, bottom: 24.w, left: 24.w, right: 24.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(24.w)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
'设置为默认地址'.text.size(28.sp).color(Color(0xFF333333)).make(),
|
||||
5.hb,
|
||||
'提醒:每次下单会默认推荐使用该地址'
|
||||
.text
|
||||
.size(24.sp)
|
||||
.color(Color(0xFFBBBBBB))
|
||||
.make(),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
CupertinoSwitch(
|
||||
value: isDefault,
|
||||
onChanged: (value) {
|
||||
if (value) {
|
||||
isDefault = value;
|
||||
_address.isDefault = 1;
|
||||
print(1);
|
||||
} else {
|
||||
isDefault = value;
|
||||
_address.isDefault = 0;
|
||||
print(0);
|
||||
}
|
||||
setState(() {});
|
||||
})
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
import 'package:new_recook/utils/alert.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
import '../../utils/headers.dart';
|
||||
|
||||
class DeleteAccountPage extends StatefulWidget {
|
||||
const DeleteAccountPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_DeleteAccountPageState createState() => _DeleteAccountPageState();
|
||||
}
|
||||
|
||||
class _DeleteAccountPageState extends State<DeleteAccountPage> {
|
||||
final deleteInfo = [
|
||||
'您的账户无法登录与使用',
|
||||
'身份、账户信息、会员权益将被清空且无法恢复',
|
||||
'您已完成的交易将无法处理售后',
|
||||
'您将无法便捷地查询帐号历史交易记录',
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
bodyColor: Colors.white,
|
||||
title: '注销账号',
|
||||
body: _bodyWidget(),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
_bodyWidget() {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.all(16.w),
|
||||
children: [
|
||||
Text(
|
||||
'请注意,一旦注销账户:',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 40.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30.w),
|
||||
...deleteInfo.map((e) => _buildChildTile(e)),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
Get.back();
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40.w),
|
||||
color: Color(0xFFF0F0F0)),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 20.w,
|
||||
),
|
||||
child: Text('不注销了',
|
||||
style:
|
||||
TextStyle(color: Color(0xFF666666), fontSize: 32.sp)),
|
||||
),
|
||||
),
|
||||
)),
|
||||
20.wb,
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
Alert.show(
|
||||
context,
|
||||
NormalTextDialog(
|
||||
title: '注销提示',
|
||||
type: NormalTextDialogType.delete,
|
||||
content: '确定注销账号?',
|
||||
items: ["取消"],
|
||||
listener: (index) {
|
||||
Alert.dismiss(context);
|
||||
},
|
||||
deleteItem: "确定",
|
||||
deleteListener: () async {
|
||||
Alert.dismiss(context);
|
||||
|
||||
},
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40.w),
|
||||
color: Color(0xFFDB1E1E)),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 20.w,
|
||||
),
|
||||
child: Text('确认注销',
|
||||
style: TextStyle(color: Colors.white, fontSize: 32.sp)),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
50.hb,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_buildChildTile(String title) {
|
||||
return Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 16.w,
|
||||
height: 16.w,
|
||||
margin: EdgeInsets.only(right: 20.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFE2E2E2),
|
||||
borderRadius: BorderRadius.circular(8.w),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
margin: EdgeInsets.only(bottom: 40.w),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/constants/styles.dart';
|
||||
import 'package:new_recook/models/user/invoice_get_bill_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/button/recook_check_box.dart';
|
||||
import 'package:new_recook/widget/no_data_widget.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
import 'invoice_detail_page.dart';
|
||||
|
||||
class InvoiceWithGoodsPage extends StatefulWidget {
|
||||
InvoiceWithGoodsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceWithGoodsPageState createState() => _InvoiceWithGoodsPageState();
|
||||
}
|
||||
|
||||
class _InvoiceWithGoodsPageState extends State<InvoiceWithGoodsPage> {
|
||||
GSRefreshController _refreshController =
|
||||
GSRefreshController(initialRefresh: true);
|
||||
|
||||
List<InvoiceGetBillModel> _models = [
|
||||
InvoiceGetBillModel(endTime: '2022-10-10',goodsName: '伊犁牛奶',goodsTotalAmount: 10.2,orderId: 1),
|
||||
InvoiceGetBillModel(endTime: '2022-10-10',goodsName: '伊犁牛奶',goodsTotalAmount: 10.2,orderId: 2),
|
||||
InvoiceGetBillModel(endTime: '2022-10-10',goodsName: '伊犁牛奶',goodsTotalAmount: 10.2,orderId: 3)
|
||||
];
|
||||
List<int?> _selectedIds = [];
|
||||
double _price = 0.0;
|
||||
//int _page = 0;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_refreshController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '开具发票',
|
||||
bodyColor: Colors.white,
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 16.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'可开票订单',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Color(0xFFEEEEEE),
|
||||
height: 0.5,
|
||||
),
|
||||
Expanded(
|
||||
child: RefreshWidget(
|
||||
onRefresh: () async {
|
||||
// await _invoicePresenter.getInvoice().then((value) {
|
||||
// _page = 0;
|
||||
// if (mounted) {
|
||||
// setState(() {
|
||||
// _models = value;
|
||||
// });
|
||||
// _refreshController.refreshCompleted();
|
||||
// }
|
||||
// });
|
||||
_refreshController.refreshCompleted();
|
||||
},
|
||||
onLoadMore: () async {
|
||||
// _page++;
|
||||
// await _invoicePresenter.getInvoice(page: _page).then((value) {
|
||||
// _models.addAll(value);
|
||||
// if (mounted)
|
||||
// setState(() {
|
||||
// _refreshController.loadComplete();
|
||||
// });
|
||||
// });
|
||||
_refreshController.loadComplete();
|
||||
},
|
||||
controller: _refreshController,
|
||||
body: _models.isNotEmpty? ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return _buildCard(_models[index]);
|
||||
},
|
||||
itemCount: _models.length,
|
||||
):NoDataWidget(text: '您还没有可开发票的订单'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavi: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 4.w,
|
||||
spreadRadius: 2.w,
|
||||
color: Color(0xFF3C0A07).withOpacity(0.07),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: true,
|
||||
top: false,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 12.w,
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 15 * 2.sp,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: _selectedIds.length.toString(),
|
||||
style: TextStyle(color: AppColor.priceColor),
|
||||
),
|
||||
TextSpan(
|
||||
text: '笔订单,共',
|
||||
),
|
||||
TextSpan(
|
||||
text: _price.toStringAsFixed(2),
|
||||
style: TextStyle(color: AppColor.priceColor),
|
||||
),
|
||||
TextSpan(
|
||||
text: '元',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 0.5 * 2.w,
|
||||
color: Color(0xFFEEEEEE),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 20.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
CupertinoButton(
|
||||
minSize: 0,
|
||||
padding: EdgeInsets.zero,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10.w),
|
||||
child: RecookCheckBox(
|
||||
state: _selectedIds.length == _models.length),
|
||||
),
|
||||
16.wb,
|
||||
Text(
|
||||
'全选',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
if (_selectedIds.length == _models.length) {
|
||||
_selectedIds = [];
|
||||
_price = 0;
|
||||
} else {
|
||||
_selectedIds = [];
|
||||
_price = 0;
|
||||
_models.forEach((element) {
|
||||
_price += element.goodsTotalAmount!;
|
||||
_selectedIds.add(element.orderId);
|
||||
});
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
// AppRouter.push(context, RouteName.USER_INVOICE_DETAIL,
|
||||
// arguments: {'ids': _selectedIds, 'price': _price});
|
||||
|
||||
Get.to(()=>InvoiceDetailPage(price: _price, ids: _selectedIds,));
|
||||
},
|
||||
child: Text('开具发票',style: TextStyle(color: Colors.white),),
|
||||
style:ButtonStyle(backgroundColor: MaterialStateProperty.all(AppColor.redColor),)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildCard(InvoiceGetBillModel model) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (_selectedIds.contains(model.orderId)) {
|
||||
_selectedIds.remove(model.orderId);
|
||||
_price -= model.goodsTotalAmount!;
|
||||
} else {
|
||||
_selectedIds.add(model.orderId);
|
||||
_price += model.goodsTotalAmount!;
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 2.w,
|
||||
color: Color(0xFFEEEEEE),
|
||||
),
|
||||
),
|
||||
),
|
||||
height: 100 * 2.w,
|
||||
child: Row(
|
||||
children: [
|
||||
RecookCheckBox(state: _selectedIds.contains(model.orderId)),
|
||||
32.wb,
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
model.endTime!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
model.goodsName!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: [
|
||||
Text(
|
||||
model.goodsTotalAmount.toString(),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFDB2D2D),
|
||||
fontSize: 24 * 2.sp,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'元',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,352 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/models/user/invoice_title_list_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/utils/text_utils.dart';
|
||||
import 'package:new_recook/widget/button/recook_check_box.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
class InvoiceAddTitlePage extends StatefulWidget {
|
||||
final InvoiceTitleListModel? model;
|
||||
|
||||
InvoiceAddTitlePage({Key? key, this.model}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceAddTitlePageState createState() => _InvoiceAddTitlePageState();
|
||||
}
|
||||
|
||||
class _InvoiceAddTitlePageState extends State<InvoiceAddTitlePage> {
|
||||
bool _isCompany = true;
|
||||
bool defaultValue = false;
|
||||
|
||||
TextEditingController _cName = TextEditingController();
|
||||
TextEditingController _pName = TextEditingController();
|
||||
TextEditingController _taxNum = TextEditingController();
|
||||
TextEditingController _address = TextEditingController();
|
||||
TextEditingController _phone = TextEditingController();
|
||||
TextEditingController _bankNum = TextEditingController();
|
||||
TextEditingController _bankName = TextEditingController();
|
||||
|
||||
InvoiceTitleListModel? model;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.model != null) {
|
||||
model = widget.model;
|
||||
_isCompany = (model!.type == 1);
|
||||
_cName.text = _isCompany ? model!.name! : "";
|
||||
_pName.text = _isCompany ? "" : model!.name!;
|
||||
_taxNum.text = model!.taxnum!;
|
||||
_address.text = model!.address!;
|
||||
_phone.text = model!.phone!;
|
||||
_bankNum.text = model!.bank!;
|
||||
defaultValue = model!.defaultValue == 1;
|
||||
_bankName.text = '宁波银行';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '常用发票抬头',
|
||||
body: ListView(
|
||||
padding: EdgeInsets.symmetric(vertical: 16.w),
|
||||
children: [
|
||||
_titleWidget('抬头类型', Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isCompany = true;
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
RecookCheckBox(state: _isCompany),
|
||||
16.wb,
|
||||
Text(
|
||||
'企业单位',
|
||||
style: TextStyle(
|
||||
fontSize: 14 * 2.sp,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
48.wb,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isCompany = false;
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
RecookCheckBox(state: !_isCompany),
|
||||
16.wb,
|
||||
Text(
|
||||
'个人/非企业单位',
|
||||
style: TextStyle(
|
||||
fontSize: 14 * 2.sp,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
_isCompany ? _buildCompany() : _buildPersonal(),
|
||||
20.hb,
|
||||
Material(
|
||||
color: Colors.white,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 32.w),
|
||||
title: Text(
|
||||
'设备默认抬头',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
'每次开票会默认填写该抬头信息',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
),
|
||||
trailing: CupertinoSwitch(
|
||||
value: defaultValue,
|
||||
activeColor: Color(0xffd5101a),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
defaultValue = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavi: Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: true,
|
||||
top: false,
|
||||
child: GestureDetector(
|
||||
onTap: _parseCheck()
|
||||
? () {
|
||||
if (widget.model != null) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
: null,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40.w),
|
||||
color: Color(0xFFDB1E1E),
|
||||
),
|
||||
|
||||
child: Text('保存',style: TextStyle(fontSize: 32.sp,color: Colors.white),),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildCompany() {
|
||||
return Column(
|
||||
children: [
|
||||
_titleWidget(
|
||||
'发票抬头',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _cName,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
hintText: '填写需要开具发票的企业名称',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
_BuildDivider(),
|
||||
_titleWidget(
|
||||
'公司税号',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _taxNum,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
hintText: '请填写纳税人识别号',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
_BuildDivider(),
|
||||
_titleWidget(
|
||||
'企业地址',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _address,
|
||||
decoration: InputDecoration(
|
||||
hintText: '请填写公司注册地址',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
_BuildDivider(),
|
||||
_titleWidget(
|
||||
'企业电话',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _phone,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
hintText: '请填写公司注册电话',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
_titleWidget(
|
||||
'开户银行',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _bankName,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
hintText: '请填写银行名称',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
_BuildDivider(),
|
||||
_titleWidget(
|
||||
'银行账号',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _bankNum,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
hintText: '请填写银行帐号',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//前端验证
|
||||
bool _parseCheck() {
|
||||
return _isCompany
|
||||
? (TextUtils.isNotEmpty(_cName.text) &&
|
||||
TextUtils.isNotEmpty(_taxNum.text))
|
||||
: (TextUtils.isNotEmpty(_pName.text));
|
||||
}
|
||||
|
||||
_buildPersonal() {
|
||||
return _titleWidget(
|
||||
'发票抬头',
|
||||
TextField(
|
||||
style: TextStyle(color: Color(0xFF333333)),
|
||||
controller: _pName,
|
||||
onChanged: (text) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
hintText: '填写发票抬头',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_BuildDivider() {
|
||||
return Divider(
|
||||
height: 1.w,
|
||||
thickness: 1.w,
|
||||
color: Color(0xFFEEEEEE),
|
||||
);
|
||||
}
|
||||
|
||||
_titleWidget(
|
||||
String title,
|
||||
Widget mid, {
|
||||
Widget? suffix,
|
||||
}) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 16 * 2.sp,
|
||||
),
|
||||
),
|
||||
32.wb,
|
||||
Expanded(child: mid),
|
||||
suffix ?? SizedBox(),
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
import 'package:new_recook/models/user/invoice_detail_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
|
||||
class InvoiceDetailInformationPage extends StatefulWidget {
|
||||
final int? id;
|
||||
InvoiceDetailInformationPage({
|
||||
Key? key,
|
||||
this.id,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceDetailInformationPageState createState() =>
|
||||
_InvoiceDetailInformationPageState();
|
||||
}
|
||||
|
||||
class _InvoiceDetailInformationPageState
|
||||
extends State<InvoiceDetailInformationPage> {
|
||||
InvoiceDetailModel? model;
|
||||
|
||||
bool _showMore = false;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
model = InvoiceDetailModel(
|
||||
id: 1,
|
||||
userId: 1,
|
||||
orderId: 1,
|
||||
buyerName: '阿三',
|
||||
taxNum: '123',
|
||||
address: '宁波市',
|
||||
telephone: '1232335452',
|
||||
phone: '12312323',
|
||||
email: '123123@123.com',
|
||||
account: '2',
|
||||
message: '123123',
|
||||
totalAmount: 123,
|
||||
invoiceStatus:1,
|
||||
fpqqlsh:'123',
|
||||
ctime: '123123',
|
||||
failReasons: '123123',
|
||||
ctimeInvoice: '123123',
|
||||
invoiceUrl: '122'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
String statusString(int invoiceStatus) {
|
||||
switch (invoiceStatus) {
|
||||
case 1:
|
||||
return '开票中';
|
||||
case 2:
|
||||
return '开票异常';
|
||||
case 3:
|
||||
return '开票中';
|
||||
case 4:
|
||||
return '开票失败';
|
||||
case 5:
|
||||
return '开票成功';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '发票详情',
|
||||
body: model == null
|
||||
? Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: ListView(
|
||||
children: [
|
||||
16.hb,
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal:32.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'电子发票',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
),
|
||||
|
||||
Spacer(),
|
||||
Text(
|
||||
statusString(model!.invoiceStatus??1),
|
||||
style: TextStyle(
|
||||
color: model!.invoiceStatus == 5
|
||||
? Color(0xFFFF8F44)
|
||||
: Color(0xFF333333),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
_buildBox('发票抬头', model!.buyerName),
|
||||
_buildBox('公司税号', model!.taxNum),
|
||||
_buildBox('公司地址', model!.address, show: _showMore),
|
||||
_buildBox('公司电话', model!.telephone, show: _showMore),
|
||||
_buildBox('开户银行银行', model!.account, show: _showMore),
|
||||
_buildBox('开户银行账号', model!.account, show: _showMore),
|
||||
_buildBox('发票内容', '平台消费', show: _showMore),//发票内容暂时写死
|
||||
_buildBox('备注', model!.message, show: _showMore),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal: 32.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'发票金额',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
model!.totalAmount!.toStringAsFixed(2),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFFF4D4F),
|
||||
fontSize: 28.sp,
|
||||
height: 1.5
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'元',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildBox('开票时间', model!.ctime),
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(vertical: 24.w),
|
||||
child: Text(
|
||||
_showMore ? '收起' : '展开更多信息',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_showMore = !_showMore;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildBox(String title, String? subtitle, {bool show = true}) {
|
||||
if (!show) return SizedBox();
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal:32.w
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 32.sp
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
subtitle!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 28.sp
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
class InvoiceDetailMorePage extends StatefulWidget {
|
||||
final TextEditingController address;
|
||||
final TextEditingController telephone;
|
||||
final TextEditingController bankNum;
|
||||
final TextEditingController message;
|
||||
InvoiceDetailMorePage({
|
||||
Key? key,
|
||||
required this.address,
|
||||
required this.telephone,
|
||||
required this.bankNum,
|
||||
required this.message,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceDetailMorePageState createState() => _InvoiceDetailMorePageState();
|
||||
}
|
||||
|
||||
class _InvoiceDetailMorePageState extends State<InvoiceDetailMorePage> {
|
||||
int _addressMax = 0;
|
||||
int _messageMax = 0;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '',
|
||||
body: ListView(
|
||||
children: [
|
||||
16.hb,
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
24.hb,
|
||||
Row(
|
||||
children: [
|
||||
32.wb,
|
||||
Text(
|
||||
'公司地址',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize:32.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'$_addressMax/50',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
32.wb,
|
||||
],
|
||||
),
|
||||
TextField(
|
||||
controller: widget.address,
|
||||
onChanged: (text) {
|
||||
setState(() {
|
||||
_addressMax = text.length;
|
||||
});
|
||||
},
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
minLines: 3,
|
||||
maxLines: 3,
|
||||
maxLength: 50,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical:24.w,
|
||||
),
|
||||
hintText: '填写公司地址',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
Divider(color: Color(0xFF666666)),
|
||||
Row(
|
||||
children: [
|
||||
32.wb,
|
||||
Text(
|
||||
'公司电话',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
controller: widget.telephone,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal: 32.w
|
||||
),
|
||||
border: InputBorder.none,
|
||||
hintText: '填写公司电话',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
Row(
|
||||
children: [
|
||||
32.wb,
|
||||
Text(
|
||||
'开户行帐号',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
controller: widget.bankNum,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal:32.w
|
||||
),
|
||||
border: InputBorder.none,
|
||||
hintText: '填写开户行帐号',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
32.wb,
|
||||
Text(
|
||||
'银行账号 ',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
controller: widget.bankNum,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal:32.w
|
||||
),
|
||||
border: InputBorder.none,
|
||||
hintText: '填写开户行名称',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 32.w,
|
||||
height: 64.w
|
||||
),
|
||||
Text(
|
||||
'备注',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize:32.sp
|
||||
),
|
||||
),
|
||||
20.wb,
|
||||
Text(
|
||||
'该内容将会打印在发票上',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize:28.sp
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'$_messageMax/80',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp
|
||||
),
|
||||
),
|
||||
32.wb,
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: TextField(
|
||||
controller: widget.message,
|
||||
onChanged: (text) {
|
||||
setState(() {
|
||||
_messageMax = text.length;
|
||||
});
|
||||
},
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
minLines: 3,
|
||||
maxLines: 3,
|
||||
maxLength: 80,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal:32.w,
|
||||
vertical: 24.w
|
||||
),
|
||||
hintText: '按企业报销要求填写,如下单时间,下单原因',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize:28.sp
|
||||
),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,727 @@
|
||||
import 'package:new_recook/constants/styles.dart';
|
||||
import 'package:new_recook/pages/user/invoice/invoice_detail_more_page.dart';
|
||||
import 'package:new_recook/pages/user/invoice/pick_invoice_title_picker.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/utils/text_utils.dart';
|
||||
import 'package:new_recook/widget/button/recook_check_box.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
import 'invoice_upload_done_page.dart';
|
||||
|
||||
class InvoiceDetailPage extends StatefulWidget {
|
||||
final List<int?> ids;
|
||||
final double price;
|
||||
InvoiceDetailPage({
|
||||
Key? key, required this.ids, required this.price,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceDetailPageState createState() => _InvoiceDetailPageState();
|
||||
}
|
||||
|
||||
class _InvoiceDetailPageState extends State<InvoiceDetailPage> {
|
||||
bool _isCompany = true;
|
||||
|
||||
TextEditingController _cName = TextEditingController();
|
||||
TextEditingController _pName = TextEditingController();
|
||||
TextEditingController _taxNum = TextEditingController();
|
||||
TextEditingController _phone = TextEditingController();
|
||||
TextEditingController _email = TextEditingController();
|
||||
|
||||
TextEditingController _addr = TextEditingController();
|
||||
TextEditingController _telePhone = TextEditingController();
|
||||
TextEditingController _bankNum = TextEditingController();
|
||||
TextEditingController _message = TextEditingController();
|
||||
|
||||
GlobalKey<FormState> _formState = GlobalKey<FormState>();
|
||||
|
||||
controllerClear() {
|
||||
_cName.clear();
|
||||
_pName.clear();
|
||||
_taxNum.clear();
|
||||
_phone.clear();
|
||||
_email.clear();
|
||||
_addr.clear();
|
||||
_telePhone.clear();
|
||||
_bankNum.clear();
|
||||
_message.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formState,
|
||||
child: RecookScaffold(
|
||||
title: '开具发票',
|
||||
body: ListView(
|
||||
padding: EdgeInsets.only(
|
||||
top: 16.w,
|
||||
),
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(24.w),
|
||||
//margin: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
//borderRadius: BorderRadius.circular(16.w),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'订单编号',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
20.wb,
|
||||
Text(
|
||||
'232748502637',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold,height: 1.5),
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'开票金额',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
20.wb,
|
||||
Text(
|
||||
'¥438.00',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFFD5101A),height: 1.5
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'订单编号',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
20.wb,
|
||||
Text(
|
||||
'232748502637',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold,height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'开票金额',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
20.wb,
|
||||
Text(
|
||||
'¥438.00',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFFD5101A),height: 1.5
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
_titleWidget(
|
||||
'抬头类型',
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isCompany = true;
|
||||
controllerClear();
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
RecookCheckBox(state: _isCompany),
|
||||
SizedBox(width: 16.w),
|
||||
Text(
|
||||
'企业单位',
|
||||
style: TextStyle(
|
||||
fontSize: 14 * 2.sp,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 48.w),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isCompany = false;
|
||||
controllerClear();
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
RecookCheckBox(state: !_isCompany),
|
||||
SizedBox(width: 16.w),
|
||||
Text(
|
||||
'个人/非企业',
|
||||
style: TextStyle(
|
||||
fontSize: 14 * 2.sp,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildDivider(),
|
||||
_isCompany ? _buildInc() : _buildPerson(),
|
||||
16.hb,
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'总金额',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 16 * 2.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
widget.price.toString(),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFDB2D2D),
|
||||
fontSize: 28.sp,height: 1.5
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' 元',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 20.w,
|
||||
),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'接收方式',
|
||||
style: TextStyle(
|
||||
fontSize: 14 * 2.sp,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
),
|
||||
),
|
||||
_titleWidget(
|
||||
'手机号码',
|
||||
TextFormField(
|
||||
validator: (value) {
|
||||
if (TextUtils.isEmpty(value)) {
|
||||
return "请填写接收发票手机号码";
|
||||
} else
|
||||
return null;
|
||||
},
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _phone,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
hintText: '用于向您发送开票成功通知',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
_titleWidget(
|
||||
'电子邮箱',
|
||||
TextFormField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
validator: (value) {
|
||||
if (TextUtils.isEmpty(value)) {
|
||||
return "请填写接收发票电子邮箱";
|
||||
} else
|
||||
return null;
|
||||
},
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _email,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
hintText: '用于向您发送电子发票',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
bottomNavi: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 64.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: true,
|
||||
top: false,
|
||||
child: GestureDetector(
|
||||
onTap: _parseCheck()
|
||||
? () {
|
||||
if (_formState.currentState!.validate()) {
|
||||
showGeneralDialog(
|
||||
barrierDismissible: true,
|
||||
barrierLabel: '',
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: Duration(milliseconds: 300),
|
||||
context: context,
|
||||
pageBuilder:
|
||||
(context, animation, secondaryAnimation) {
|
||||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Material(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(
|
||||
20.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
height: 750.w,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 30.w),
|
||||
child: Text(
|
||||
'开具电子发票',
|
||||
style: TextStyle(
|
||||
fontSize: 18 * 2.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
Divider(
|
||||
height: 0.5,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal: 32.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'发票类型',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'电子发票',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 0.5,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal: 32.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'发票抬头',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
_isCompany
|
||||
? _cName.text
|
||||
: _pName.text,
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 0.5,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 24.w,
|
||||
horizontal: 32.w,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'开票金额',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
widget.price.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xffd5101a),height: 1.5),
|
||||
),
|
||||
Text(
|
||||
'元',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1.w,
|
||||
color: Color(0xFF666666),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
child: TextButton(
|
||||
onPressed: _parseCheck()
|
||||
? () async {
|
||||
Get.to(()=>InvoiceUploadDonePage());
|
||||
}
|
||||
: null,
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all(
|
||||
AppColor.redColor)),
|
||||
child: Text(
|
||||
'确认提交',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context)
|
||||
.viewPadding
|
||||
.bottom,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: 80.w,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFDB1E1E),
|
||||
borderRadius: BorderRadius.circular(36.w)
|
||||
),
|
||||
child: Text(
|
||||
'提交申请',
|
||||
style: TextStyle(
|
||||
fontSize: 16 * 2.sp,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool _parseCheck() {
|
||||
return _isCompany
|
||||
? (TextUtils.isNotEmpty(_cName.text) &&
|
||||
TextUtils.isNotEmpty(_taxNum.text))
|
||||
: (TextUtils.isNotEmpty(_pName.text));
|
||||
}
|
||||
|
||||
_buildInc() {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_titleWidget(
|
||||
'发票抬头',
|
||||
TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _cName,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
hintText: '填写需要开具发票的企业名称',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
suffix: GestureDetector(
|
||||
child: Icon(
|
||||
Icons.menu,
|
||||
color: Color(0xFF707070),
|
||||
),
|
||||
onTap: () {
|
||||
pickInvoiceTitle(context, (model) {
|
||||
if (model.type == 1) {
|
||||
_addr.text = model.address!;
|
||||
_cName.text = model.name!;
|
||||
_taxNum.text = model.taxnum!;
|
||||
_telePhone.text = model.phone!;
|
||||
_bankNum.text = model.bank!;
|
||||
} else {
|
||||
_pName.text = model.name!;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildDivider(),
|
||||
_titleWidget(
|
||||
'公司税号',
|
||||
TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _taxNum,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
hintText: '填写纳税人识别号',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildDivider(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => InvoiceDetailMorePage(
|
||||
address: _addr,
|
||||
bankNum: _bankNum,
|
||||
message: _message,
|
||||
telephone: _telePhone,
|
||||
));
|
||||
},
|
||||
child: _titleWidget(
|
||||
'更多内容',
|
||||
Text(
|
||||
'填写备注、地址等(非必填)',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
suffix: Icon(
|
||||
Icons.navigate_next,
|
||||
color: Color(0xFFCCCCCC),
|
||||
size: 40.sp,
|
||||
),
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_buildPerson() {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_titleWidget(
|
||||
'抬头名称',
|
||||
TextField(
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
onChanged: (_) => setState(() {}),
|
||||
controller: _pName,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
hintText: '填写发票抬头',
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 14 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
suffix: GestureDetector(
|
||||
child: Icon(
|
||||
Icons.menu,
|
||||
color: Color(0xFF707070),
|
||||
),
|
||||
onTap: () {
|
||||
pickInvoiceTitle(context, (model) {
|
||||
if (model.type == 1) {
|
||||
_addr.text = model.address!;
|
||||
_cName.text = model.name!;
|
||||
_taxNum.text = model.taxnum!;
|
||||
_telePhone.text = model.phone!;
|
||||
_bankNum.text = model.bank!;
|
||||
} else {
|
||||
_pName.text = model.name!;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_buildDivider() {
|
||||
return Container(
|
||||
child: Divider(
|
||||
height: 0.5 * 2.w,
|
||||
thickness: 1,
|
||||
color: Color(0xFFEEEEEE),
|
||||
),
|
||||
color: Colors.white,
|
||||
);
|
||||
}
|
||||
|
||||
_titleWidget(
|
||||
String title,
|
||||
Widget mid, {
|
||||
Widget? suffix,
|
||||
}) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 16 * 2.sp,
|
||||
),
|
||||
),
|
||||
32.wb,
|
||||
Expanded(child: mid),
|
||||
suffix ?? SizedBox(),
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,199 @@
|
||||
import 'package:new_recook/models/user/invoice_bill_list_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
import 'invoice_detail_information_page.dart';
|
||||
|
||||
class InvoiceHistoryPage extends StatefulWidget {
|
||||
InvoiceHistoryPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceHistoryPageState createState() => _InvoiceHistoryPageState();
|
||||
}
|
||||
|
||||
class _InvoiceHistoryPageState extends State<InvoiceHistoryPage> {
|
||||
List<InvoiceBillListModel> _models = [
|
||||
InvoiceBillListModel(
|
||||
id: 1,
|
||||
userId: 1,
|
||||
orderId: 1,
|
||||
buyerName: '阿三',
|
||||
taxNum: '123',
|
||||
address: '宁波市',
|
||||
telephone: '1232335452',
|
||||
phone: '12312323',
|
||||
email: '123123@123.com',
|
||||
account: '2',
|
||||
message: '123123',
|
||||
totalAmount: 123,
|
||||
invoiceStatus: 1,
|
||||
fpqqlsh: '123',
|
||||
ctime: '2022-10-10',
|
||||
failReasons: '123123',
|
||||
ctimeInvoice: '123123',
|
||||
invoiceUrl: '122')
|
||||
];
|
||||
GSRefreshController _gsRefreshController = GSRefreshController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
_gsRefreshController.requestRefresh();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '开票历史',
|
||||
body: RefreshWidget(
|
||||
onRefresh: () async {
|
||||
_gsRefreshController.refreshCompleted();
|
||||
},
|
||||
controller: _gsRefreshController,
|
||||
body: ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return invoiceHistoryCard(
|
||||
context,
|
||||
_models[index],
|
||||
);
|
||||
},
|
||||
itemCount: _models.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget invoiceHistoryCard(BuildContext context, InvoiceBillListModel model) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => InvoiceDetailInformationPage(
|
||||
id: model.orderId,
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.w),
|
||||
),
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 32.w,
|
||||
vertical: 16.w,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 28.w),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 20.w, right: 16.w),
|
||||
height: 24.w,
|
||||
width: 24.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFD8637),
|
||||
borderRadius: BorderRadius.circular(12.w),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
model.ctime!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.navigate_next,
|
||||
size: 40.w,
|
||||
color: Color(0xFFCCCCCC),
|
||||
),
|
||||
SizedBox(width: 20.w),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 30.w),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 60.w),
|
||||
Text(
|
||||
'平台消费',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 6.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFE2F3FF),
|
||||
borderRadius: BorderRadius.circular(6.w),
|
||||
border: Border.all(
|
||||
width: 2.w,
|
||||
color: Color(0xFF63BCFF),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10.w,
|
||||
vertical: 4.w,
|
||||
),
|
||||
child: Text(
|
||||
'电子发票',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF10B1F1),
|
||||
fontSize: 22.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Row(
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
children: [
|
||||
Text(
|
||||
model.totalAmount!.toStringAsFixed(2),
|
||||
style: TextStyle(
|
||||
fontSize: 48.w,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'元',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 32.w),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 40.w),
|
||||
Divider(
|
||||
height: 2.w,
|
||||
thickness: 2.w,
|
||||
color: Color(0xFFEEEEEE),
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.only(
|
||||
left: 20.w,
|
||||
bottom: 20.w,
|
||||
top: 16.w,
|
||||
),
|
||||
child: Text(
|
||||
model.statusString,
|
||||
style: TextStyle(
|
||||
color: model.statusColor,
|
||||
fontSize: 26.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:new_recook/models/user/invoice_title_list_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
import 'invoice_add_title_page.dart';
|
||||
|
||||
class InvoiceUsuallyUsedPage extends StatefulWidget {
|
||||
InvoiceUsuallyUsedPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoiceUsuallyUsedPageState createState() => _InvoiceUsuallyUsedPageState();
|
||||
}
|
||||
|
||||
class _InvoiceUsuallyUsedPageState extends State<InvoiceUsuallyUsedPage> {
|
||||
GSRefreshController _controller = GSRefreshController();
|
||||
List<InvoiceTitleListModel> _models = [
|
||||
InvoiceTitleListModel(
|
||||
id: 1,uid: 2,name: '问问',taxnum: '123123213',address: '阿斯顿收到了',phone: '12232345324',bank: '宁波银行',defaultValue: 1,type: 1
|
||||
),
|
||||
InvoiceTitleListModel(
|
||||
id: 1,uid: 2,name: '问问',taxnum: '123123213',address: '阿斯顿收到了',phone: '12232345324',bank: '宁波银行',defaultValue: 0,type: 1
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
if (mounted) _controller.requestRefresh();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '常用开票抬头',
|
||||
body: RefreshWidget(
|
||||
controller: _controller,
|
||||
onRefresh: () async {
|
||||
_controller.refreshCompleted();
|
||||
},
|
||||
body: ListView.separated(
|
||||
padding: EdgeInsets.only(
|
||||
top: 16.w,
|
||||
),
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 4.w);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return _buildCard(_models[index]);
|
||||
},
|
||||
itemCount: _models.length,
|
||||
),
|
||||
),
|
||||
bottomNavi: Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 64.w,
|
||||
vertical: 24.w,
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: true,
|
||||
top: false,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(()=>InvoiceAddTitlePage())?.then((value) {
|
||||
_controller.requestRefresh();
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40.w),
|
||||
color: Color(0xffd5101a),
|
||||
),
|
||||
child: Text('添加新的抬头',style: TextStyle(fontSize: 32.sp,color: Colors.white),),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildCard(InvoiceTitleListModel model) {
|
||||
return Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Get.to(()=>InvoiceAddTitlePage(model: model,))?.then((value) {
|
||||
_controller.requestRefresh();
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
constraints: BoxConstraints(minHeight: 124.w),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 30.w),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
model.name!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
model.defaultValue == 1
|
||||
? Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 3.w,
|
||||
vertical: 1.w,
|
||||
),
|
||||
child: Text(
|
||||
'默认抬头',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFD5101A),
|
||||
fontSize: 20.sp,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color: Color(0xFFD5101A),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.w),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
10.hb,
|
||||
Text(
|
||||
model.type==1?'企业抬头':'个人抬头',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.navigate_next,
|
||||
color: Color(0xFF666666),
|
||||
size: 40.w,
|
||||
),
|
||||
SizedBox(width: 24.w),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
import 'Invoice_with_goods_page.dart';
|
||||
import 'invoice_history_page.dart';
|
||||
import 'invoice_usually_used_page.dart';
|
||||
|
||||
class InvoicingPage extends StatefulWidget {
|
||||
const InvoicingPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoicingPageState createState() => _InvoicingPageState();
|
||||
}
|
||||
|
||||
class _InvoicingPageState extends State<InvoicingPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '发票助手',
|
||||
body: ListView(
|
||||
padding: EdgeInsets.only(
|
||||
top: 16.w,
|
||||
),
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
Get.to(()=>InvoiceWithGoodsPage());
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(24.w),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text('平台消费开票',style: TextStyle(fontSize: 28.sp,color: Color(0xFF333333),fontWeight: FontWeight.bold),),
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
size: 40.sp,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
Get.to(()=>InvoiceUsuallyUsedPage());
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(24.w),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text('常用开票抬头',style: TextStyle(fontSize: 28.sp,color: Color(0xFF333333),fontWeight: FontWeight.bold),),
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
size: 40.sp,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
Get.to(()=>InvoiceHistoryPage());
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(24.w),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
Text('开票历史',style: TextStyle(fontSize: 28.sp,color: Color(0xFF333333),fontWeight: FontWeight.bold),),
|
||||
Spacer(),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
size: 40.sp,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
|
||||
import 'package:new_recook/models/user/invoice_title_list_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
import 'invoice_add_title_page.dart';
|
||||
|
||||
pickInvoiceTitle(
|
||||
BuildContext context, Function(InvoiceTitleListModel model) onModel) {
|
||||
showGeneralDialog(
|
||||
context: context,
|
||||
pageBuilder: (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: InvoicePicker(
|
||||
onModel: onModel,
|
||||
),
|
||||
);
|
||||
},
|
||||
barrierDismissible: true,
|
||||
barrierLabel: '',
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: Duration(milliseconds: 300),
|
||||
);
|
||||
}
|
||||
|
||||
class InvoicePicker extends StatefulWidget {
|
||||
final Function(InvoiceTitleListModel model)? onModel;
|
||||
InvoicePicker({Key? key, this.onModel}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvoicePickerState createState() => _InvoicePickerState();
|
||||
}
|
||||
|
||||
class _InvoicePickerState extends State<InvoicePicker> {
|
||||
|
||||
List<InvoiceTitleListModel> _models = [
|
||||
InvoiceTitleListModel(
|
||||
id: 1,uid: 2,name: '问问',taxnum: '123123213',address: '阿斯顿收到了',phone: '12232345324',bank: '宁波银行',defaultValue: 1,type: 1
|
||||
),
|
||||
InvoiceTitleListModel(
|
||||
id: 1,uid: 2,name: '问问',taxnum: '123123213',address: '阿斯顿收到了',phone: '12232345324',bank: '宁波银行',defaultValue: 0,type: 1
|
||||
),
|
||||
InvoiceTitleListModel(
|
||||
id: 1,uid: 2,name: '问问',taxnum: '123123213',address: '阿斯顿收到了',phone: '12232345324',bank: '宁波银行',defaultValue: 0,type: 1
|
||||
),
|
||||
];
|
||||
GSRefreshController _controller = GSRefreshController();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
if (mounted) {
|
||||
_controller.requestRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(
|
||||
32.w
|
||||
),
|
||||
),
|
||||
),
|
||||
height: 750.w,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(32.w),
|
||||
child: Text(
|
||||
'常用发票抬头',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 16 * 2.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildDivider(),
|
||||
Expanded(
|
||||
child: RefreshWidget(
|
||||
controller: _controller,
|
||||
onRefresh: () async {
|
||||
_controller.refreshCompleted();
|
||||
},
|
||||
body: ListView.separated(
|
||||
separatorBuilder: (context, index) {
|
||||
return Divider(
|
||||
height: 1.w,
|
||||
color: Color(0xFF666666),
|
||||
);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return Material(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
widget.onModel!(_models[index]);
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 30.w,
|
||||
height:96.w,
|
||||
),
|
||||
Text(
|
||||
_models[index].name!,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
_models[index].defaultValue == 1
|
||||
? Text(
|
||||
'默认抬头',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFFA6400),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
SizedBox(
|
||||
width: 30.w,
|
||||
height:96.w,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: _models.length),
|
||||
)),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal:32.w,
|
||||
vertical:24.w,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
Get.off(InvoiceAddTitlePage());
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical:24.w,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.w),
|
||||
color: Color(0xffd5101a),
|
||||
),
|
||||
child: Text('添加常用发票抬头',style: TextStyle(color: Colors.white),),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).viewPadding.bottom,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildDivider() {
|
||||
return Divider(
|
||||
color: Color(0xFFEEEEEE),
|
||||
thickness: 0.5,
|
||||
height: 0.5,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,444 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:new_recook/constants/api.dart';
|
||||
import 'package:new_recook/gen/assets.gen.dart';
|
||||
import 'package:new_recook/pages/splash/webView.dart';
|
||||
import 'package:new_recook/utils/alert.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/utils/text_utils.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LoginPageState createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
bool isLogin = true;
|
||||
bool _chooseAgreement = false;
|
||||
TextEditingController? _phoneController = TextEditingController();
|
||||
TextEditingController? _smsCodeController = TextEditingController();
|
||||
FocusNode? _phoneNode = FocusNode();
|
||||
FocusNode? _smsCodeNode = FocusNode();
|
||||
bool _getCodeEnable = false;
|
||||
bool _cantSelected = false;
|
||||
bool _loginEnable = false;
|
||||
String _errorMsg = "";
|
||||
Timer? _timer;
|
||||
String _countDownStr = "获取验证码";
|
||||
int _countDownNum = 59;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_phoneController?.dispose();
|
||||
_smsCodeController?.dispose();
|
||||
_phoneNode?.dispose();
|
||||
_smsCodeNode?.dispose();
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
_timer = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
bodyColor: Colors.white,
|
||||
title: '',
|
||||
body: Column(
|
||||
children: [
|
||||
100.hb,
|
||||
Container(
|
||||
width: 140.w,
|
||||
height: 140.w,
|
||||
alignment: Alignment.center,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: 140.w
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
child: Image.asset(Assets.icons.appIcon.path,fit: BoxFit.cover,),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
60.hb,
|
||||
isLogin
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
_getPhoneString('15938758940'),
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF111111)),
|
||||
),
|
||||
32.wb,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
isLogin = false;
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(
|
||||
'更换',
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp, color: Color(0xFF666666)),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
_phoneText(),
|
||||
_smsCode(),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
_buildPhoneLogin(),
|
||||
30.hb,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
_chooseAgreement = !_chooseAgreement;
|
||||
setState(() {});
|
||||
},
|
||||
child: Row(
|
||||
//mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
padding: EdgeInsets.only(top: 6.w, right: 5.w),
|
||||
child: !_chooseAgreement
|
||||
? Icon(CupertinoIcons.circle,
|
||||
size: 18, color: Color(0xFFdddddd))
|
||||
: Icon(CupertinoIcons.checkmark_circle,
|
||||
size: 18, color: Colors.red)),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: "您已阅读并同意",
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666), fontSize: 12 * 2.sp),
|
||||
children: [
|
||||
new TextSpan(
|
||||
text: '《用户服务协议》',
|
||||
style: new TextStyle(
|
||||
color: Color(0xFFD5101A), fontSize: 12 * 2.sp),
|
||||
recognizer: _recognizer(context, 2)),
|
||||
TextSpan(
|
||||
text: "和",
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666), fontSize: 12 * 2.sp),
|
||||
),
|
||||
new TextSpan(
|
||||
text: '《用户隐私政策》',
|
||||
style: new TextStyle(
|
||||
color: Color(0xFFD5101A), fontSize: 12 * 2.sp),
|
||||
recognizer: _recognizer(context, 1)),
|
||||
])),
|
||||
],
|
||||
),
|
||||
),
|
||||
50.hb,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_beginCountDown() {
|
||||
setState(() {
|
||||
_getCodeEnable = false;
|
||||
_countDownStr = "重新获取($_countDownNum)";
|
||||
});
|
||||
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
|
||||
if (_timer == null || !mounted) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
if (_countDownNum == 0) {
|
||||
_countDownNum = 59;
|
||||
_countDownStr = "获取验证码";
|
||||
_getCodeEnable = true;
|
||||
_timer!.cancel();
|
||||
_timer = null;
|
||||
return;
|
||||
}
|
||||
_countDownStr = "重新获取(${_countDownNum--})";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Container _phoneText() {
|
||||
return Container(
|
||||
margin:
|
||||
EdgeInsets.only(top: 20.w, right: 40.w, left: 40.w),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey[500]!, width: 1.w),
|
||||
borderRadius: BorderRadius.all(Radius.circular(6.w))),
|
||||
child: TextField(
|
||||
controller: _phoneController,
|
||||
focusNode: _phoneNode,
|
||||
keyboardType: TextInputType.number,
|
||||
style: TextStyle(color: Colors.black, fontSize: 16 * 2.sp),
|
||||
inputFormatters: [
|
||||
LengthLimitingTextInputFormatter(11),
|
||||
],
|
||||
cursorColor: Colors.black,
|
||||
onChanged: (String phone) {
|
||||
setState(() {
|
||||
if (phone.length >= 11) {
|
||||
_getCodeEnable = true;
|
||||
_loginEnable = _verifyLoginEnable();
|
||||
} else {
|
||||
_errorMsg = "";
|
||||
_getCodeEnable = false;
|
||||
_loginEnable = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: 20.w,
|
||||
top: 26.w,
|
||||
bottom: _phoneNode!.hasFocus ? 0 : 28.w),
|
||||
border: InputBorder.none,
|
||||
hintText: "请输入手机号",
|
||||
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15 * 2.sp),
|
||||
suffixIcon: _clearButton(_phoneController, _phoneNode!)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
IconButton? _clearButton(TextEditingController? controller, FocusNode node) {
|
||||
return node.hasFocus
|
||||
? IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: Icon(
|
||||
CupertinoIcons.clear,
|
||||
size: 17 * 2.sp,
|
||||
color: Colors.grey[300],
|
||||
),
|
||||
onPressed: () {
|
||||
controller!.clear();
|
||||
})
|
||||
: null;
|
||||
}
|
||||
|
||||
/// 验证码
|
||||
Container _smsCode() {
|
||||
return Container(
|
||||
margin:
|
||||
EdgeInsets.only(top: 20.w, right:40.w, left: 40.w),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey[500]!, width: 0.5),
|
||||
borderRadius: BorderRadius.all(Radius.circular(3))),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
LengthLimitingTextInputFormatter(4),
|
||||
],
|
||||
onChanged: (text) {
|
||||
setState(() {
|
||||
_loginEnable = _verifyLoginEnable();
|
||||
});
|
||||
},
|
||||
controller: _smsCodeController,
|
||||
focusNode: _smsCodeNode,
|
||||
keyboardType: TextInputType.number,
|
||||
style: TextStyle(color: Colors.black, fontSize: 16 * 2.sp),
|
||||
cursorColor: Colors.black,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: 20.w,
|
||||
top: 26.w,
|
||||
bottom: _smsCodeNode!.hasFocus ? 0 : 28.w),
|
||||
border: InputBorder.none,
|
||||
hintText: "请输入验证码",
|
||||
hintStyle:
|
||||
TextStyle(color: Colors.grey[400], fontSize: 14 * 2.sp),
|
||||
suffixIcon: _clearButton(_smsCodeController, _smsCodeNode!)),
|
||||
),
|
||||
),
|
||||
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (_chooseAgreement) {
|
||||
if (!TextUtils.verifyPhone(_phoneController!.text)) {
|
||||
BotToast.showText(text: '手机号码格式不正确!');
|
||||
return;
|
||||
}
|
||||
if (_cantSelected) return;
|
||||
_cantSelected = true;
|
||||
Future.delayed(Duration(seconds: 2), () {
|
||||
_cantSelected = false;
|
||||
});
|
||||
_getSmsCode();
|
||||
} else {
|
||||
Alert.show(
|
||||
context,
|
||||
NormalContentDialog(
|
||||
type: NormalTextDialogType.remind,
|
||||
title: null,
|
||||
content: Text(
|
||||
'请您先阅读并同意《用户协议》和《隐私政策》',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
items: ["确认"],
|
||||
listener: (index) {
|
||||
Alert.dismiss(context);
|
||||
},
|
||||
));
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 240.w,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(left: BorderSide(color: Colors.grey[500]!)),
|
||||
),
|
||||
child: Text(_countDownStr,style: TextStyle(color: Color(0xFFAAAAAA),fontSize: 25.sp),),
|
||||
),
|
||||
)
|
||||
|
||||
// TButton.TextButton(
|
||||
// title: _countDownStr,
|
||||
// width: rSize(120),
|
||||
// textColor: Colors.grey[700],
|
||||
// enable: _getCodeEnable,
|
||||
// font: 15 * 2.sp,
|
||||
// unableTextColor: Colors.grey[400],
|
||||
// highlightTextColor: Colors.grey[400],
|
||||
// border: Border(left: BorderSide(color: Colors.grey[500]!)),
|
||||
// onTap: () {
|
||||
// if (_chooseAgreement) {
|
||||
// if (!TextUtils.verifyPhone(_phoneController!.text)) {
|
||||
// Toast.showError("手机号码格式不正确!");
|
||||
// return;
|
||||
// }
|
||||
// if (_cantSelected) return;
|
||||
// _cantSelected = true;
|
||||
// Future.delayed(Duration(seconds: 2), () {
|
||||
// _cantSelected = false;
|
||||
// });
|
||||
//
|
||||
// _getSmsCode();
|
||||
// } else {
|
||||
// Alert.show(
|
||||
// context,
|
||||
// NormalContentDialog(
|
||||
// type: NormalTextDialogType.remind,
|
||||
// title: null,
|
||||
// content: Text(
|
||||
// '请您先阅读并同意《用户协议》和《隐私政策》',
|
||||
// style: TextStyle(color: Colors.black),
|
||||
// ),
|
||||
// items: ["确认"],
|
||||
// listener: (index) {
|
||||
// Alert.dismiss(context);
|
||||
// },
|
||||
// ));
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
_getSmsCode() {
|
||||
_beginCountDown();
|
||||
BotToast.showText(text: '验证码发送成功,请注意查收');
|
||||
}
|
||||
|
||||
_verifyLoginEnable() {
|
||||
if (!TextUtils.verifyPhone(_phoneController!.text)) {
|
||||
setState(() {
|
||||
_errorMsg = "手机号格式不正确,请检查";
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return _smsCodeController!.text.length == 4;
|
||||
}
|
||||
|
||||
Container _buildPhoneLogin() {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 40.w),
|
||||
height:80.w,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Color(0xFFE05346),
|
||||
Color(0xFFDB1E1E),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(40.w))),
|
||||
child: MaterialButton(
|
||||
onPressed: () {
|
||||
if (_chooseAgreement) {
|
||||
|
||||
} else {
|
||||
Alert.show(
|
||||
context,
|
||||
NormalContentDialog(
|
||||
type: NormalTextDialogType.remind,
|
||||
title: null,
|
||||
content: Text(
|
||||
'请您先阅读并同意《用户协议》和《隐私政策》',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
items: ["确认"],
|
||||
listener: (index) {
|
||||
Alert.dismiss(context);
|
||||
},
|
||||
));
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"本机号码登录",
|
||||
style:TextStyle(fontSize: 32.sp, color: Colors.white),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
_getPhoneString(String phone) {
|
||||
String phoneString = '';
|
||||
if (phone.isNotEmpty) {
|
||||
phoneString = phone.substring(0, 3) + '****' + phone.substring(7, 11);
|
||||
} else {}
|
||||
return phoneString;
|
||||
}
|
||||
|
||||
_recognizer(context, int type) {
|
||||
final TapGestureRecognizer recognizer = new TapGestureRecognizer();
|
||||
recognizer.onTap = () {
|
||||
print("点击协议了");
|
||||
Get.to(() => WebViewPage(
|
||||
url: type == 1 ? API.webAPI.webPrivacy : API.webAPI.webAgreement,
|
||||
));
|
||||
};
|
||||
return recognizer;
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/constants/styles.dart';
|
||||
import 'package:new_recook/models/home/address_model.dart';
|
||||
import 'package:new_recook/widget/no_data_widget.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
import '../../utils/headers.dart';
|
||||
import 'add_address_page.dart';
|
||||
|
||||
class MyAddressPage extends StatefulWidget {
|
||||
const MyAddressPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyAddressPageState createState() => _MyAddressPageState();
|
||||
}
|
||||
|
||||
class _MyAddressPageState extends State<MyAddressPage> {
|
||||
List<AddressModel> _addressList = [
|
||||
AddressModel(
|
||||
name: '阿三',
|
||||
mobile: '1239238643',
|
||||
province: '浙江省',
|
||||
city: '宁波市',
|
||||
district: '海曙区',
|
||||
address: 'xx街道xx路xx楼xx室',
|
||||
isDefault: 1),
|
||||
AddressModel(
|
||||
name: '阿4',
|
||||
mobile: '12392386343',
|
||||
province: '浙江省',
|
||||
city: '宁波市',
|
||||
district: '海曙区',
|
||||
address: 'xx街道xx路xx楼xx室',
|
||||
isDefault: 0),
|
||||
];
|
||||
bool _onLoad = true;
|
||||
|
||||
GSRefreshController _refreshController =
|
||||
GSRefreshController(initialRefresh: true);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '我的地址',
|
||||
actions: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 30.w),
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(()=>AddAddressPage());
|
||||
},
|
||||
child: Text(
|
||||
'添加收货地址',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
body: _addressList.isNotEmpty
|
||||
? _listWidget()
|
||||
: NoDataWidget(
|
||||
text: '还未添加地址~快去添加吧',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_listWidget() {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 16.w),
|
||||
child: RefreshWidget(
|
||||
controller: _refreshController,
|
||||
color: AppColor.themeColor,
|
||||
onRefresh: () async {
|
||||
_onLoad = false;
|
||||
setState(() {});
|
||||
_refreshController.refreshCompleted();
|
||||
},
|
||||
onLoadMore: () async {
|
||||
_refreshController.loadComplete();
|
||||
},
|
||||
body: _onLoad ? SizedBox() : _buildList()),
|
||||
);
|
||||
}
|
||||
|
||||
_buildList() {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(
|
||||
left: 0, top: 0, right: 0, bottom: ScreenUtil().bottomBarHeight),
|
||||
itemBuilder: (_, index) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Padding(child: _addressWidget(_addressList[index], index),padding: EdgeInsets.only(bottom: 24.w),) );
|
||||
},
|
||||
itemCount: _addressList.length,
|
||||
);
|
||||
}
|
||||
|
||||
_addressWidget(AddressModel model, int index) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
child: Column(
|
||||
children: [
|
||||
24.hb,
|
||||
Row(
|
||||
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
Text(
|
||||
model.name ?? '',
|
||||
style: TextStyle(color: Color(0xFF333333), fontSize: 30.sp,fontWeight: FontWeight.w500),
|
||||
),
|
||||
24.wb,
|
||||
Text(
|
||||
model.mobile ?? '',
|
||||
style: TextStyle(color: Color(0xFF333333), fontSize: 30.sp,fontWeight: FontWeight.w500,height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
12.hb,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${(model.province ?? "") + (model.city ?? "") + (model.district ?? "")}',
|
||||
style: TextStyle(color: Color(0xFF333333), fontSize: 30.sp),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
24.hb,
|
||||
Divider(
|
||||
height: 1.w,
|
||||
thickness: 1.w,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
},
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.w),
|
||||
child: AnimatedContainer(
|
||||
height: 40.w,
|
||||
width: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: themeColor.withOpacity(model.isDefault == 1 ? 1 : 0),
|
||||
border: Border.all(
|
||||
color: (model.isDefault == 1
|
||||
? themeColor
|
||||
: Color(0xFF979797)),
|
||||
width: 3.w,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
),
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutCubic,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedOpacity(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOutCubic,
|
||||
opacity: model.isDefault == 1 ? 1 : 0,
|
||||
child: Icon(
|
||||
CupertinoIcons.checkmark,
|
||||
color: Colors.white,
|
||||
size: 28.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
12.wb,
|
||||
Text(
|
||||
model.isDefault == 1?'默认地址':'设为默认地址',
|
||||
style: TextStyle(
|
||||
color: model.isDefault == 1?Color(0xFFC92219):Color(0xFF333333),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'编辑',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 30.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'删除',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF333333),
|
||||
fontSize: 30.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,432 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/constants/api.dart';
|
||||
import 'package:new_recook/constants/styles.dart';
|
||||
import 'package:new_recook/gen/assets.gen.dart';
|
||||
import 'package:new_recook/models/goods/goods_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/button/check_radio.dart';
|
||||
import 'package:new_recook/widget/no_data_widget.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
class MyCollectionPage extends StatefulWidget {
|
||||
const MyCollectionPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyCollectionPageState createState() => _MyCollectionPageState();
|
||||
}
|
||||
|
||||
class _MyCollectionPageState extends State<MyCollectionPage> {
|
||||
bool _editStatus = false;
|
||||
bool _onLoad = true;
|
||||
|
||||
GSRefreshController _refreshController =
|
||||
GSRefreshController(initialRefresh: true);
|
||||
List<GoodsModel> _goodsList = [
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶李子园牛奶李子园牛奶李子园牛奶李子园牛奶',
|
||||
saleNum: 100,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '100.5',
|
||||
imgPath: '',
|
||||
inventory: 200),
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶12',
|
||||
saleNum: 2200,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '200.5',
|
||||
imgPath: '',
|
||||
inventory: 0),
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶22',
|
||||
saleNum: 9900,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '300.5',
|
||||
imgPath: '',
|
||||
inventory: 200),
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶33',
|
||||
saleNum: 100,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '100.5',
|
||||
imgPath: '',
|
||||
inventory: 200),
|
||||
];
|
||||
|
||||
List<GoodsModel> _chooseGoodsList = [];
|
||||
|
||||
List<int> _selectIndex = [];
|
||||
|
||||
bool get _allSelect =>
|
||||
_selectIndex.length == _goodsList.length && _selectIndex.length != 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '我的收藏',
|
||||
body: _goodsList.isNotEmpty
|
||||
? _listWidget()
|
||||
: NoDataWidget(
|
||||
text: '收藏夹是空的~快去逛逛吧',
|
||||
btn: GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 212.w,
|
||||
height: 64.w,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Color(0xFFE05346),
|
||||
Color(0xFFDB1E1E),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(32.w))),
|
||||
child: Text(
|
||||
'去购物',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 30.w),
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_editStatus = !_editStatus;
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(
|
||||
!_editStatus ? '编辑' : '完成',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
bottomNavi: _editStatus
|
||||
? Container(
|
||||
color: Colors.white,
|
||||
height: 130.w,
|
||||
child: Row(
|
||||
children: [
|
||||
24.wb,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (_allSelect) {
|
||||
_selectIndex.clear();
|
||||
_chooseGoodsList.clear();
|
||||
} else {
|
||||
_selectIndex.clear();
|
||||
_chooseGoodsList.clear();
|
||||
_chooseGoodsList.addAll(_goodsList);
|
||||
_selectIndex.addAll(List.generate(
|
||||
_goodsList.length, (index) => index));
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.all(20.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.w),
|
||||
child: AnimatedContainer(
|
||||
height: 40.w,
|
||||
width: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: themeColor
|
||||
.withOpacity(_allSelect ? 1 : 0),
|
||||
border: Border.all(
|
||||
color: (_allSelect
|
||||
? themeColor
|
||||
: Color(0xFF979797)),
|
||||
width: 3.w,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
),
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutCubic,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedOpacity(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOutCubic,
|
||||
opacity: _allSelect ? 1 : 0,
|
||||
child: Icon(
|
||||
CupertinoIcons.checkmark,
|
||||
color: Colors.white,
|
||||
size: 28.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
24.wb,
|
||||
Text(
|
||||
'全选',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 200.w,
|
||||
height: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Color(0xFFE05346),
|
||||
Color(0xFFDB1E1E),
|
||||
],
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(40.w))),
|
||||
child: Text(
|
||||
'删除',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
24.wb,
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox());
|
||||
}
|
||||
|
||||
_listWidget() {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 16.w),
|
||||
child: RefreshWidget(
|
||||
controller: _refreshController,
|
||||
color: AppColor.themeColor,
|
||||
onRefresh: () async {
|
||||
_onLoad = false;
|
||||
setState(() {});
|
||||
_refreshController.refreshCompleted();
|
||||
},
|
||||
onLoadMore: () async {
|
||||
_refreshController.loadComplete();
|
||||
},
|
||||
body: _onLoad ? SizedBox() : _buildList()),
|
||||
);
|
||||
}
|
||||
|
||||
_buildList() {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(
|
||||
left: 0, top: 0, right: 0, bottom: ScreenUtil().bottomBarHeight),
|
||||
itemBuilder: (_, index) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 8.w),
|
||||
child: _goodsWidget(_goodsList[index], index, _editStatus),
|
||||
));
|
||||
},
|
||||
itemCount: _goodsList.length,
|
||||
);
|
||||
}
|
||||
|
||||
_goodsWidget(GoodsModel goodsModel, int index, bool showRadio) {
|
||||
return Container(
|
||||
height: 272.w,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, borderRadius: BorderRadius.circular(16.w)),
|
||||
child: Row(
|
||||
children: [
|
||||
showRadio
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
if (_selectIndex.contains(index)) {
|
||||
_selectIndex.remove(index);
|
||||
_chooseGoodsList.remove(goodsModel);
|
||||
} else {
|
||||
_selectIndex.add(index);
|
||||
_chooseGoodsList.add(goodsModel);
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
height: double.infinity,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
height: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
child: CheckRadio(
|
||||
value: index,
|
||||
groupValue: _selectIndex,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
_image(goodsModel),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
16.hb,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 16.w),
|
||||
child: SizedBox(
|
||||
child: Text(
|
||||
goodsModel.goodsName ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
24.wb,
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: '¥',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: goodsModel.price,
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 48.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
16.wb,
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 104.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Color(0xFFAAAAAA), width: 2.w),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20.w))),
|
||||
child: Text(
|
||||
'找相似',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
)),
|
||||
Spacer(),
|
||||
Image.asset(
|
||||
Assets.icons.iconCar.path,
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
)
|
||||
],
|
||||
),
|
||||
20.hb,
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_image(GoodsModel goodsModel) {
|
||||
bool sellout = false;
|
||||
if (goodsModel.inventory! > 0) {
|
||||
sellout = false;
|
||||
} else {
|
||||
sellout = true;
|
||||
}
|
||||
return Container(
|
||||
width: 250.w,
|
||||
height: 250.w,
|
||||
color: Colors.white,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16.w)),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: FadeInImage.assetNetwork(
|
||||
placeholder: Assets.images.placeholderNew1x1A.path,
|
||||
image: API.getImgUrl(goodsModel.imgPath) ?? '',
|
||||
fit: BoxFit.cover,
|
||||
imageErrorBuilder: (context, error, stackTrace) {
|
||||
return Image.asset(
|
||||
Assets.images.placeholderNew1x1A.path,
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
},
|
||||
)),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: Offstage(
|
||||
offstage: !sellout,
|
||||
child: Opacity(
|
||||
opacity: 0.7,
|
||||
child: Container(
|
||||
color: Color(0x80000000),
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
Assets.images.selloutBg.path,
|
||||
width: 140.w,
|
||||
height: 140.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,491 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/constants/api.dart';
|
||||
import 'package:new_recook/constants/styles.dart';
|
||||
import 'package:new_recook/gen/assets.gen.dart';
|
||||
import 'package:new_recook/models/goods/footPrint_model.dart';
|
||||
import 'package:new_recook/models/goods/goods_model.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
import 'package:new_recook/widget/button/check_radio.dart';
|
||||
import 'package:new_recook/widget/no_data_widget.dart';
|
||||
import 'package:new_recook/widget/recook_scaffold.dart';
|
||||
import 'package:new_recook/widget/refresh_widget.dart';
|
||||
|
||||
class MyFootprintPage extends StatefulWidget {
|
||||
const MyFootprintPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyFootprintPageState createState() => _MyFootprintPageState();
|
||||
}
|
||||
|
||||
class _MyFootprintPageState extends State<MyFootprintPage> {
|
||||
bool _editStatus = false;
|
||||
bool _onLoad = true;
|
||||
String _title = '';
|
||||
GSRefreshController _refreshController =
|
||||
GSRefreshController(initialRefresh: true);
|
||||
List<FootPrintModel> _footPrintModelList = [
|
||||
FootPrintModel(title: '今天', goodsList: [
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶李子园牛奶李子园牛奶李子园牛奶李子园牛奶',
|
||||
saleNum: 100,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '100.5',
|
||||
imgPath: '',
|
||||
inventory: 200),
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶12',
|
||||
saleNum: 2200,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '200.5',
|
||||
imgPath: '',
|
||||
inventory: 0),
|
||||
]),
|
||||
FootPrintModel(title: '前天', goodsList: [
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶李子123',
|
||||
saleNum: 100,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '100.5',
|
||||
imgPath: '',
|
||||
inventory: 200),
|
||||
GoodsModel(
|
||||
goodsName: '李子园牛奶132',
|
||||
saleNum: 200,
|
||||
shopName: '蒙牛旗舰店',
|
||||
price: '200.5',
|
||||
imgPath: '',
|
||||
inventory: 0),
|
||||
])
|
||||
];
|
||||
|
||||
List<GoodsModel> _goodsList = [];
|
||||
List<GoodsModel> _chooseGoodsList = [];
|
||||
|
||||
List<int> _selectIndex = [];
|
||||
|
||||
bool get _allSelect =>
|
||||
_selectIndex.length == _goodsList.length && _selectIndex.length != 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RecookScaffold(
|
||||
title: '我的足迹',
|
||||
body: !_footPrintModelList.isNotEmpty
|
||||
? _listWidget()
|
||||
: NoDataWidget(
|
||||
text: '浏览足迹是空的~快去逛逛吧',
|
||||
btn: GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 212.w,
|
||||
height: 64.w,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Color(0xFFE05346),
|
||||
Color(0xFFDB1E1E),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(32.w))),
|
||||
child: Text(
|
||||
'去购物',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 30.w),
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_editStatus = !_editStatus;
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(
|
||||
!_editStatus ? '编辑' : '完成',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
bottomNavi: _editStatus
|
||||
? Container(
|
||||
color: Colors.white,
|
||||
height: 130.w,
|
||||
child: Row(
|
||||
children: [
|
||||
12.wb,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (_allSelect) {
|
||||
_selectIndex.clear();
|
||||
_chooseGoodsList.clear();
|
||||
} else {
|
||||
_selectIndex.clear();
|
||||
_chooseGoodsList.clear();
|
||||
_chooseGoodsList.addAll(_goodsList);
|
||||
_selectIndex.addAll(List.generate(
|
||||
_goodsList.length, (index) => index));
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.all(20.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 10.w),
|
||||
child: AnimatedContainer(
|
||||
height: 40.w,
|
||||
width: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: themeColor
|
||||
.withOpacity(_allSelect ? 1 : 0),
|
||||
border: Border.all(
|
||||
color: (_allSelect
|
||||
? themeColor
|
||||
: Color(0xFF979797)),
|
||||
width: 3.w,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
),
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutCubic,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedOpacity(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOutCubic,
|
||||
opacity: _allSelect ? 1 : 0,
|
||||
child: Icon(
|
||||
CupertinoIcons.checkmark,
|
||||
color: Colors.white,
|
||||
size: 28.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
24.wb,
|
||||
Text(
|
||||
'全选',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 200.w,
|
||||
height: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(
|
||||
color: Color(0xFFD5101A), width: 2.w),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(40.w))),
|
||||
child: Text(
|
||||
'收藏',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFD5101A),
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
24.wb,
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: 200.w,
|
||||
height: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Color(0xFFE05346),
|
||||
Color(0xFFDB1E1E),
|
||||
],
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(40.w))),
|
||||
child: Text(
|
||||
'删除',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28.sp,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
24.wb,
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox());
|
||||
}
|
||||
|
||||
_listWidget() {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 16.w),
|
||||
child: RefreshWidget(
|
||||
controller: _refreshController,
|
||||
color: AppColor.themeColor,
|
||||
onRefresh: () async {
|
||||
_onLoad = false;
|
||||
_goodsList = [];
|
||||
_footPrintModelList.forEach((element) {
|
||||
element.goodsList?.forEach((good) {
|
||||
GoodsModel goodsModel = GoodsModel(
|
||||
goodsName: good.goodsName,
|
||||
saleNum: good.saleNum,
|
||||
shopName: good.shopName,
|
||||
price: good.price,
|
||||
imgPath: good.imgPath,
|
||||
inventory: good.inventory,
|
||||
title: element.title);
|
||||
_goodsList.add(goodsModel);
|
||||
});
|
||||
});
|
||||
setState(() {});
|
||||
_refreshController.refreshCompleted();
|
||||
},
|
||||
onLoadMore: () async {
|
||||
_refreshController.loadComplete();
|
||||
},
|
||||
body: _onLoad ? SizedBox() : _buildList()),
|
||||
);
|
||||
}
|
||||
|
||||
_buildList() {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(
|
||||
left: 0, top: 0, right: 0, bottom: ScreenUtil().bottomBarHeight),
|
||||
itemBuilder: (_, index) {
|
||||
bool showTitle = false;
|
||||
if (_title != _goodsList[index].title) {
|
||||
_title = _goodsList[index].title ?? '';
|
||||
showTitle = true;
|
||||
}
|
||||
return ListView(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
showTitle
|
||||
? Text(
|
||||
_goodsList[index].title ?? '',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF111111),
|
||||
fontSize: 32.sp,
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
: SizedBox(),
|
||||
10.hb,
|
||||
_goodsWidget(_goodsList[index], index, _editStatus),
|
||||
8.hb,
|
||||
],
|
||||
);
|
||||
},
|
||||
itemCount: _goodsList.length,
|
||||
);
|
||||
}
|
||||
|
||||
_goodsWidget(GoodsModel goodsModel, int index, bool showRadio) {
|
||||
return Container(
|
||||
height: 272.w,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, borderRadius: BorderRadius.circular(16.w)),
|
||||
child: Row(
|
||||
children: [
|
||||
showRadio
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
if (_selectIndex.contains(index)) {
|
||||
_selectIndex.remove(index);
|
||||
_chooseGoodsList.remove(goodsModel);
|
||||
} else {
|
||||
_selectIndex.add(index);
|
||||
_chooseGoodsList.add(goodsModel);
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
height: double.infinity,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
height: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
child: CheckRadio(
|
||||
value: index,
|
||||
groupValue: _selectIndex,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
_image(goodsModel),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
16.hb,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 16.w),
|
||||
child: SizedBox(
|
||||
child: Text(
|
||||
goodsModel.goodsName ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
16.hb,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
24.wb,
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: '¥',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 32.sp,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: goodsModel.price,
|
||||
style: TextStyle(
|
||||
color: Color(0xFFC92219),
|
||||
fontSize: 48.sp,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
16.wb,
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 104.w,
|
||||
height: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Color(0xFFAAAAAA), width: 2.w),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20.w))),
|
||||
child: Text(
|
||||
'找相似',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF666666),
|
||||
fontSize: 24.sp,
|
||||
),
|
||||
)),
|
||||
Spacer(),
|
||||
Image.asset(
|
||||
Assets.icons.iconCar.path,
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
)
|
||||
],
|
||||
),
|
||||
20.hb,
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_image(GoodsModel goodsModel) {
|
||||
bool sellout = false;
|
||||
if (goodsModel.inventory! > 0) {
|
||||
sellout = false;
|
||||
} else {
|
||||
sellout = true;
|
||||
}
|
||||
return Container(
|
||||
width: 250.w,
|
||||
height: 250.w,
|
||||
color: Colors.white,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16.w)),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: FadeInImage.assetNetwork(
|
||||
placeholder: Assets.images.placeholderNew1x1A.path,
|
||||
image: API.getImgUrl(goodsModel.imgPath) ?? '',
|
||||
fit: BoxFit.cover,
|
||||
imageErrorBuilder: (context, error, stackTrace) {
|
||||
return Image.asset(
|
||||
Assets.images.placeholderNew1x1A.path,
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
},
|
||||
)),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: Offstage(
|
||||
offstage: !sellout,
|
||||
child: Opacity(
|
||||
opacity: 0.7,
|
||||
child: Container(
|
||||
color: Color(0x80000000),
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
Assets.images.selloutBg.path,
|
||||
width: 140.w,
|
||||
height: 140.w,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
|
||||
class CheckRadio<T> extends StatefulWidget {
|
||||
final T? value;
|
||||
final List<T>? groupValue;
|
||||
final Widget? indent;
|
||||
final Color? backColor;
|
||||
|
||||
CheckRadio(
|
||||
{Key? key, this.value, this.groupValue, this.indent, this.backColor})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_CheckRadioState createState() => _CheckRadioState();
|
||||
}
|
||||
|
||||
class _CheckRadioState extends State<CheckRadio> {
|
||||
bool get _selected {
|
||||
if (widget.groupValue!.contains(widget.value)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedContainer(
|
||||
height: 40.w,
|
||||
width: 40.w,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.backColor ?? themeColor.withOpacity(_selected ? 1 : 0),
|
||||
border: Border.all(
|
||||
color: widget.backColor != null
|
||||
? Color(0xFFBBBBBB)
|
||||
: (_selected ? themeColor : Color(0xFF979797)),
|
||||
width: 3.w,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
),
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutCubic,
|
||||
alignment: Alignment.center,
|
||||
child: AnimatedOpacity(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOutCubic,
|
||||
opacity: _selected ? 1 : 0,
|
||||
child: widget.indent ??
|
||||
Icon(
|
||||
CupertinoIcons.checkmark,
|
||||
color: Colors.white,
|
||||
size: 28.w,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
|
||||
class RecookCheckBox extends StatelessWidget {
|
||||
final bool state;
|
||||
const RecookCheckBox({Key? key, this.state = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 32.w,
|
||||
width: 32.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
16.w
|
||||
),
|
||||
border: state
|
||||
? null
|
||||
: Border.all(
|
||||
width:2.w,
|
||||
color: Color(0xFFC9C9C9),
|
||||
),
|
||||
color: state ? Color(0xFFDB2D2D) : Colors.transparent,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.check,
|
||||
color: Colors.white,
|
||||
size: 24.w,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
|
||||
import 'package:new_recook/utils/headers.dart';
|
||||
|
||||
import 'input_view.dart';
|
||||
|
||||
typedef StringCallback = Function(String text);
|
||||
|
||||
class EditTile extends StatefulWidget {
|
||||
final String? title;
|
||||
final String? value;
|
||||
final String? hint;
|
||||
final int maxLength;
|
||||
final int maxLines;
|
||||
final TextStyle titleStyle;
|
||||
final TextStyle textStyle;
|
||||
final TextStyle hintStyle;
|
||||
final StringCallback textChanged;
|
||||
final Axis direction;
|
||||
final BoxConstraints? constraints;
|
||||
|
||||
const EditTile({
|
||||
Key? key,
|
||||
this.title,
|
||||
required this.textChanged,
|
||||
this.value,
|
||||
this.hint,
|
||||
this.titleStyle = const TextStyle(
|
||||
color: Colors.black, fontWeight: FontWeight.w300, fontSize: 15),
|
||||
this.textStyle = const TextStyle(
|
||||
color: Colors.black, fontWeight: FontWeight.w500, fontSize: 14),
|
||||
this.hintStyle = const TextStyle(color: Color(0xFFBDBDBD), fontSize: 14),
|
||||
this.direction = Axis.horizontal,
|
||||
this.constraints,
|
||||
this.maxLength = 100,
|
||||
this.maxLines = 1,
|
||||
});
|
||||
|
||||
@override
|
||||
_EditTileState createState() => _EditTileState();
|
||||
}
|
||||
|
||||
class _EditTileState extends State<EditTile> {
|
||||
TextEditingController? _controller;
|
||||
FocusNode _focusNode = FocusNode();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = TextEditingController(text: widget.value);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(_focusNode);
|
||||
},
|
||||
child: Container(
|
||||
constraints: widget.constraints,
|
||||
padding: EdgeInsets.symmetric(vertical: 2, horizontal: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Colors.grey[200]!, width: 0.5))),
|
||||
child:
|
||||
widget.direction == Axis.horizontal ? _horizontal() : _vertical(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Row _horizontal() {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 160.w,
|
||||
child: Text(
|
||||
widget.title!,
|
||||
style: widget.titleStyle,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: InputView(
|
||||
focusNode: _focusNode,
|
||||
controller: _controller,
|
||||
maxLength: widget.maxLength,
|
||||
hintStyle: widget.hintStyle,
|
||||
textStyle: widget.textStyle,
|
||||
onValueChanged: (string) {
|
||||
widget.textChanged(string);
|
||||
},
|
||||
hint: widget.hint,
|
||||
)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_vertical() {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
height: 80.w,
|
||||
child: Text(
|
||||
widget.title!,
|
||||
style: widget.titleStyle,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: InputView(
|
||||
focusNode: _focusNode,
|
||||
padding: EdgeInsets.symmetric(horizontal: 3),
|
||||
maxLines: widget.maxLines,
|
||||
maxLength: widget.maxLength,
|
||||
controller: _controller,
|
||||
hintStyle: widget.hintStyle,
|
||||
textStyle: widget.textStyle,
|
||||
onValueChanged: (string) {
|
||||
widget.textChanged(string);
|
||||
},
|
||||
hint: widget.hint,
|
||||
)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue