|
|
@@ -1,5 +1,6 @@
|
|
|
import 'package:auto_size_text/auto_size_text.dart';
|
|
|
import 'package:carousel_slider/carousel_slider.dart';
|
|
|
+import 'package:collection/collection.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
import 'package:get/get.dart';
|
|
|
@@ -11,9 +12,12 @@ import 'package:keyboard/module/store/store_user_reviews_bean.dart';
|
|
|
import 'package:keyboard/resource/string.gen.dart';
|
|
|
import 'package:keyboard/widget/platform_util.dart';
|
|
|
|
|
|
+import '../../data/bean/goods_info.dart';
|
|
|
import '../../data/consts/constants.dart';
|
|
|
import '../../resource/assets.gen.dart';
|
|
|
+import '../../resource/colors.gen.dart';
|
|
|
import '../../router/app_pages.dart';
|
|
|
+import '../../utils/count_down_timer.dart';
|
|
|
import '../../utils/date_util.dart';
|
|
|
import '../../widget/horizontal_dashed_line.dart';
|
|
|
import '../../utils/styles.dart';
|
|
|
@@ -244,17 +248,26 @@ class StorePage extends BasePage<StoreController> {
|
|
|
Obx(() {
|
|
|
return Column(
|
|
|
children:
|
|
|
- controller.filteredGoodsList.map((item) {
|
|
|
- return Obx(() {
|
|
|
- return GestureDetector(
|
|
|
- onTap: () => controller.onGoodsItemClick(item),
|
|
|
- child: _buildGoodsItem(
|
|
|
- item,
|
|
|
- controller.selectedGoodsInfoItem?.id == item.id,
|
|
|
- ),
|
|
|
- );
|
|
|
- });
|
|
|
- }).toList(),
|
|
|
+ controller.filteredGoodsList.mapIndexed((index, item) {
|
|
|
+ return Obx(() {
|
|
|
+ return GestureDetector(
|
|
|
+ onTap: () => controller.onGoodsItemClick(item),
|
|
|
+ child:
|
|
|
+ PlatformUtil.isIOS
|
|
|
+ ? _buildGoodsItemIos(
|
|
|
+ index,
|
|
|
+ item,
|
|
|
+ controller.selectedGoodsInfoItem?.id ==
|
|
|
+ item.id,
|
|
|
+ )
|
|
|
+ : _buildGoodsItem(
|
|
|
+ item,
|
|
|
+ controller.selectedGoodsInfoItem?.id ==
|
|
|
+ item.id,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }).toList(),
|
|
|
);
|
|
|
}),
|
|
|
// iOS平台的产品描述
|
|
|
@@ -319,7 +332,201 @@ class StorePage extends BasePage<StoreController> {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- Widget _buildGoodsItem(item, bool isSelected) {
|
|
|
+ /// 商品-iOS端
|
|
|
+ Widget _buildGoodsItemIos(int index, GoodsInfo item, bool isSelected) {
|
|
|
+ // 第一个商品,才有有倒计时
|
|
|
+ bool hasCountdown = index == 0;
|
|
|
+
|
|
|
+ Widget contentWidget = Stack(
|
|
|
+ children: [
|
|
|
+ Positioned(
|
|
|
+ left: 16.w,
|
|
|
+ top: 0,
|
|
|
+ right: 0,
|
|
|
+ bottom: 0,
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ // 价格
|
|
|
+ RichText(
|
|
|
+ text: TextSpan(
|
|
|
+ children: [
|
|
|
+ TextSpan(
|
|
|
+ text: '¥',
|
|
|
+ style: Styles.getTextStyleFF663300W700(14.sp),
|
|
|
+ ),
|
|
|
+ TextSpan(
|
|
|
+ text: item.priceDescNumber,
|
|
|
+ style: Styles.getTextStyleFF663300W700(18.sp),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(width: 18.w),
|
|
|
+ // 名称和描述
|
|
|
+ Column(
|
|
|
+ // 垂直居中
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ // 水平左对齐
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: [
|
|
|
+ // 名称
|
|
|
+ Text(
|
|
|
+ item.name,
|
|
|
+ style: Styles.getTextStyleFF663300W500(15.sp),
|
|
|
+ ),
|
|
|
+ // 描述
|
|
|
+ if (item.mostDesc?.isNotEmpty == true)
|
|
|
+ AutoSizeText(
|
|
|
+ item.mostDesc!,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Color(0x99673300),
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ letterSpacing: -0.60,
|
|
|
+ ),
|
|
|
+ maxLines: 1,
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
+ // 最小字体
|
|
|
+ minFontSize: 8,
|
|
|
+ // 缩小步长,越小越丝滑
|
|
|
+ stepGranularity: 0.5,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ // 勾选状态
|
|
|
+ Positioned(
|
|
|
+ top: 0,
|
|
|
+ right: 22.w,
|
|
|
+ bottom: 0,
|
|
|
+ child: Image(
|
|
|
+ image:
|
|
|
+ isSelected
|
|
|
+ ? Assets.images.iconStoreGoodsSelectedSymbolIos.provider()
|
|
|
+ : Assets.images.iconStoreGoodsNormalSymbolIos.provider(),
|
|
|
+ width: 20.w,
|
|
|
+ height: 20.w,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ // 倒计时
|
|
|
+ Positioned(
|
|
|
+ top: 0,
|
|
|
+ right: 8,
|
|
|
+ child: Visibility(
|
|
|
+ visible: hasCountdown,
|
|
|
+ child: Row(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ "倒计时",
|
|
|
+ style: TextStyle(
|
|
|
+ color: isSelected ? Color(0xFFFFECBB) : Color(0xFFFF9416),
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SizedBox(width: 4.w),
|
|
|
+ Container(
|
|
|
+ margin: EdgeInsets.only(top: 2.5.h),
|
|
|
+ child: Obx(() {
|
|
|
+ return Text(
|
|
|
+ CountdownTimer.format(controller.goodsCountdown.value),
|
|
|
+ style: TextStyle(
|
|
|
+ color: isSelected ? ColorName.white : Color(0xFFFF9416),
|
|
|
+ fontSize: 12.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 最终呈现的内容组件
|
|
|
+ Widget resultWidget;
|
|
|
+ if (hasCountdown) {
|
|
|
+ // 有倒计时的商品,不规则,使用图片背景
|
|
|
+ resultWidget = Container(
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ image: DecorationImage(
|
|
|
+ image:
|
|
|
+ isSelected
|
|
|
+ ? Assets.images.bgStoreGoodsItemWithCountdownSelectedIos
|
|
|
+ .provider()
|
|
|
+ : Assets.images.bgStoreGoodsItemWithCountdownNormalIos
|
|
|
+ .provider(),
|
|
|
+ fit: BoxFit.fill,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: contentWidget,
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ // 没有倒计时的商品
|
|
|
+ resultWidget = Container(
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ shape: BoxShape.rectangle,
|
|
|
+ borderRadius: BorderRadius.circular(8.r),
|
|
|
+ border: Border.all(
|
|
|
+ color: isSelected ? Color(0xFFFF9416) : Color(0xFFFEE86B),
|
|
|
+ width: 2.w,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: contentWidget,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 最后面背景透出来的颜色
|
|
|
+ Decoration bgDecoration;
|
|
|
+ if (isSelected) {
|
|
|
+ // 渐变背景
|
|
|
+ bgDecoration = ShapeDecoration(
|
|
|
+ gradient: LinearGradient(
|
|
|
+ begin: Alignment(-0.06, 0.50),
|
|
|
+ end: Alignment(1.14, 0.50),
|
|
|
+ colors: [const Color(0xFFFFF895), const Color(0xFFFFE941)],
|
|
|
+ ),
|
|
|
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ // 纯色背景
|
|
|
+ bgDecoration = BoxDecoration(
|
|
|
+ color: Color(0xFFFFFEEE),
|
|
|
+ borderRadius: BorderRadius.circular(6.r),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return Container(
|
|
|
+ margin: EdgeInsets.only(bottom: 8.h),
|
|
|
+ width: 296.w,
|
|
|
+ height: 70.h,
|
|
|
+ decoration: bgDecoration,
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ // 对勾图片
|
|
|
+ Positioned(
|
|
|
+ top: 0,
|
|
|
+ right: 0,
|
|
|
+ bottom: 0,
|
|
|
+ child: Assets.images.bgStoreSelectedArrow1Ios.image(
|
|
|
+ width: 85.w,
|
|
|
+ height: double.infinity,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ resultWidget,
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 商品-Android端
|
|
|
+ Widget _buildGoodsItem(GoodsInfo item, bool isSelected) {
|
|
|
return Container(
|
|
|
margin: EdgeInsets.only(bottom: 8.h),
|
|
|
width: 296.w,
|
|
|
@@ -949,7 +1156,7 @@ class StorePage extends BasePage<StoreController> {
|
|
|
);
|
|
|
}),
|
|
|
Transform.translate(
|
|
|
- offset: Offset(-10.w, 0),
|
|
|
+ offset: Offset(-2.w, 0),
|
|
|
child: Text.rich(
|
|
|
TextSpan(
|
|
|
children: [
|