Jolie 4 months ago
parent
commit
750d213181
30 changed files with 2600 additions and 1631 deletions
  1. BIN
      assets/images/vip_buy_tag.png
  2. BIN
      assets/images/vip_chat.png
  3. BIN
      assets/images/vip_gift.png
  4. BIN
      assets/images/vip_message.png
  5. BIN
      assets/images/vip_special.png
  6. BIN
      assets/images/vip_visitor.png
  7. BIN
      assets/images/vip_voice.png
  8. 151
      lib/controller/discover/visitor_controller.dart
  9. 25
      lib/controller/mine/auth_controller.dart
  10. 37
      lib/controller/mine/edit_info_controller.dart
  11. 17
      lib/controller/mine/mine_controller.dart
  12. 25
      lib/controller/mine/rose_controller.dart
  13. 71
      lib/generated/assets.dart
  14. 75
      lib/model/discover/visitor_model.dart
  15. 21
      lib/model/mine/submit_order_data.dart
  16. 3
      lib/network/api_urls.dart
  17. 6
      lib/network/user_api.dart
  18. 39
      lib/network/user_api.g.dart
  19. 258
      lib/pages/discover/visitor_list_page.dart
  20. 993
      lib/pages/home/user_information_page.dart
  21. 14
      lib/pages/mine/auth_center_page.dart
  22. 1164
      lib/pages/mine/edit_info_page.dart
  23. 299
      lib/pages/mine/mine_page.dart
  24. 81
      lib/pages/mine/pay_fail_page.dart
  25. 8
      lib/pages/mine/real_name_page.dart
  26. 75
      lib/pages/mine/renew_manage_page.dart
  27. 5
      lib/pages/mine/rose_page.dart
  28. 54
      lib/pages/mine/vip_manage_page.dart
  29. 390
      lib/pages/mine/vip_page.dart
  30. 420
      pubspec.lock

BIN
assets/images/vip_buy_tag.png

Before After
Width: 240  |  Height: 72  |  Size: 1.1 KiB

BIN
assets/images/vip_chat.png

Before After
Width: 136  |  Height: 90  |  Size: 4.8 KiB

BIN
assets/images/vip_gift.png

Before After
Width: 115  |  Height: 110  |  Size: 4.0 KiB

BIN
assets/images/vip_message.png

Before After
Width: 123  |  Height: 110  |  Size: 4.1 KiB

BIN
assets/images/vip_special.png

Before After
Width: 140  |  Height: 102  |  Size: 4.3 KiB

BIN
assets/images/vip_visitor.png

Before After
Width: 120  |  Height: 120  |  Size: 4.5 KiB

BIN
assets/images/vip_voice.png

Before After
Width: 120  |  Height: 120  |  Size: 5.0 KiB

151
lib/controller/discover/visitor_controller.dart

@ -0,0 +1,151 @@
// controllers/visitor_controller.dart
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../model/discover/visitor_model.dart';
class VisitorController extends GetxController {
// 访
var visitors = <VisitorModel>[].obs;
// Refresh controllers
final RefreshController refreshController = RefreshController();
final RefreshController loadMoreController = RefreshController();
//
var currentPage = 1.obs;
final int pageSize = 15;
var hasMore = true.obs;
var isLoading = false.obs;
@override
void onInit() {
super.onInit();
_loadInitialData();
}
//
void _loadInitialData() async {
isLoading.value = true;
await Future.delayed(Duration(milliseconds: 800)); //
final initialVisitors = _generateMockData(1, pageSize);
visitors.assignAll(initialVisitors);
isLoading.value = false;
hasMore.value = initialVisitors.length == pageSize;
}
//
void onRefresh() async {
currentPage.value = 1;
hasMore.value = true;
await Future.delayed(Duration(milliseconds: 1000)); //
final newVisitors = _generateMockData(1, pageSize);
visitors.assignAll(newVisitors);
refreshController.refreshCompleted();
hasMore.value = newVisitors.length == pageSize;
if (newVisitors.isEmpty) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
}
//
void onLoadMore() async {
if (!hasMore.value) {
loadMoreController.loadNoData();
return;
}
currentPage.value++;
await Future.delayed(Duration(milliseconds: 800)); //
final newVisitors = _generateMockData(currentPage.value, pageSize);
if (newVisitors.isEmpty) {
hasMore.value = false;
loadMoreController.loadNoData();
} else {
visitors.addAll(newVisitors);
loadMoreController.loadComplete();
hasMore.value = false;
}
}
// 访
void deleteVisitor(String visitorId) {
// visitors.removeWhere((visitor) => visitor.id == visitorId);
Get.snackbar('成功', '已删除访客记录');
}
// 访
void clearAllVisitors() {
visitors.clear();
Get.snackbar('成功', '已清空所有访客记录');
}
// 访
int get todayVisitorsCount {
return visitors.length;
}
// 线访
int get onlineVisitorsCount {
return visitors.length;
}
//
List<VisitorModel> _generateMockData(int page, int size) {
if (page > 3) return []; // 3
final names = [
'张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十',
'小明', '小红', '小刚', '小花', '大山', '小云', '星辰', '大海'
];
final avatars = [
'https://randomuser.me/api/portraits/men/1.jpg',
'https://randomuser.me/api/portraits/women/1.jpg',
'https://randomuser.me/api/portraits/men/2.jpg',
'https://randomuser.me/api/portraits/women/2.jpg',
'https://randomuser.me/api/portraits/men/3.jpg',
'https://randomuser.me/api/portraits/women/3.jpg',
'https://randomuser.me/api/portraits/men/4.jpg',
'https://randomuser.me/api/portraits/women/4.jpg',
];
final pages = [
'首页', '产品页', '关于我们', '博客', '联系方式', '服务页', '价格页', '案例页'
];
final startIndex = (page - 1) * size;
final endIndex = startIndex + size;
return List.generate(size, (index) {
final globalIndex = startIndex + index;
final isOnline = globalIndex % 3 == 0; // 3线
return VisitorModel(
miId: 'visitor_${globalIndex + 1}',
nickName: names[globalIndex % names.length],
profilePhoto: avatars[globalIndex % avatars.length],
visitTime: '2025-11-14 10:42:42',
onlineStatus: 2,
describeInfo: '阿萨德垃圾袋杰克伦敦撒娇克拉斯的健康拉屎的 金坷垃四大皆空拉屎的距离考试啊'
);
});
}
@override
void onClose() {
refreshController.dispose();
loadMoreController.dispose();
super.onClose();
}
}

25
lib/controller/mine/auth_controller.dart

@ -6,7 +6,8 @@ import '../global.dart';
class AuthController extends GetxController {
final isLoading = false.obs;
final List<AuthCard> dataList = [];
// var List<AuthCard> dataList = [];
var dataList = <AuthCard>[].obs;
//
final isLoggingIn = false.obs;
final name = ''.obs;
@ -19,31 +20,28 @@ class AuthController extends GetxController {
super.onInit();
// UserApi
_userApi = Get.find<UserApi>();
_loadInitialData();
loadInitialData();
}
//
Future<void> _loadInitialData() async {
Future<void> loadInitialData() async {
try {
isLoading.value = true;
late bool realAuth = false;
late bool realAuth = false, checkPhoto = false;
if (GlobalData().userData != null) {
final information = GlobalData().userData!;
if(information.identityCard != null){
realAuth = true;
}
if(information.profilePhoto != null){
checkPhoto = true;
}
}
dataList.assignAll([
AuthCard( title: '手机绑定', desc: '防止账号丢失', index: 1, authed: true),
AuthCard( title: '真实头像', desc: '提高交友成功率', index: 2, authed: false),
AuthCard( title: '真实头像', desc: '提高交友成功率', index: 2, authed: checkPhoto),
AuthCard( title: '实名认证', desc: '提高交友成功率', index: 3, authed: realAuth),
]);
//
// final response = await _userApi.login({});
//
// if (response.data.isSuccess) {
//
// }
} catch (e) {
SmartDialog.showToast('网络请求失败,请检查网络连接');
} finally {
@ -78,8 +76,9 @@ class AuthController extends GetxController {
}
void changeAuth(int index){
AuthCard card = dataList.firstWhere((item) => item.index == index);
card.authed = true;
final updatedMessages = List<AuthCard>.from(dataList);
updatedMessages[index].authed = true;
dataList.assignAll(updatedMessages);
}
Future<void> startAuthing() async {

37
lib/controller/mine/edit_info_controller.dart

@ -0,0 +1,37 @@
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/mine/user_data.dart';
import 'package:dating_touchme_app/pages/mine/auth_center_page.dart';
import 'package:dating_touchme_app/pages/mine/my_wallet_page.dart';
import 'package:dating_touchme_app/pages/mine/rose_page.dart';
import 'package:get/get.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
class EditInfoController extends GetxController {
final menuActive = 1.obs;
List<String> imgList = [
"https://fastly.picsum.photos/id/64/800/800.jpg?hmac=NBZ4_-vqzD6p25oCeaW0H5vH-ql9zzei-SqJNeUo1QU",
"https://fastly.picsum.photos/id/985/800/800.jpg?hmac=DfRt99HFbMJ96DlN-poOhruWYRsexESE94ilLC3g1rU",
"https://fastly.picsum.photos/id/703/800/800.jpg?hmac=-bRTkPxnsiQ5kCo2tfXj6tFrXMD7YnVx7bQ0STno3Tg"
];
final nowSelect = 0.obs;
List<String> tagList = [
"北京", "160cm", "想要甜甜的恋爱", "本科", "朋友圈摄影师", "英雄联盟", "流放之路",
"CF", "DNA", "堡垒之夜", "SCP"
];
final userData = GlobalData().userData.obs;
@override
void onInit() {
super.onInit();
}
}

17
lib/controller/mine/mine_controller.dart

@ -1,4 +1,6 @@
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/mine/user_data.dart';
import 'package:dating_touchme_app/pages/mine/auth_center_page.dart';
import 'package:dating_touchme_app/pages/mine/my_wallet_page.dart';
import 'package:dating_touchme_app/pages/mine/rose_page.dart';
@ -9,10 +11,10 @@ class MineController extends GetxController {
List<Map> infoList = [
{"label": "我的关注", "num": 88},
{"label": "关注我的", "num": 18988},
{"label": "好友", "num": 8},
{"label": "访客", "num": 357},
{"label": "我的关注", "num": 88, "type": 1},
{"label": "关注我的", "num": 18988, "type": 2},
{"label": "好友", "num": 8, "type": 3},
{"label": "访客", "num": 357, "type": 4},
].obs;
List<Map> blockList = [
@ -28,5 +30,12 @@ class MineController extends GetxController {
{"icon": Assets.imagesMail, "title": "意见反馈"},
].obs;
final userData = GlobalData().userData.obs;
@override
void onInit() {
super.onInit();
}
}

25
lib/controller/mine/rose_controller.dart

@ -67,4 +67,29 @@ class RoseController extends GetxController {
}
}
submitOrder() async {
try {
print(roseList[activePay.value].productDesc);
final response = await _userApi.submitOrder({
"productSpecId": roseList[activePay.value].productSpecId
});
if (response.data.isSuccess && response.data.data != null) {
final data = response.data.data;
SmartDialog.showToast('下单成功');
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch (e) {
print('玫瑰列表获取失败: $e');
SmartDialog.showToast('下单失败');
rethrow;
}
}
}

71
lib/generated/assets.dart

@ -2,6 +2,70 @@
class Assets {
Assets._();
static const String emojiEmoji01 = 'assets/images/emoji/emoji_01.png';
static const String emojiEmoji02 = 'assets/images/emoji/emoji_02.png';
static const String emojiEmoji03 = 'assets/images/emoji/emoji_03.png';
static const String emojiEmoji04 = 'assets/images/emoji/emoji_04.png';
static const String emojiEmoji05 = 'assets/images/emoji/emoji_05.png';
static const String emojiEmoji06 = 'assets/images/emoji/emoji_06.png';
static const String emojiEmoji07 = 'assets/images/emoji/emoji_07.png';
static const String emojiEmoji08 = 'assets/images/emoji/emoji_08.png';
static const String emojiEmoji09 = 'assets/images/emoji/emoji_09.png';
static const String emojiEmoji10 = 'assets/images/emoji/emoji_10.png';
static const String emojiEmoji11 = 'assets/images/emoji/emoji_11.png';
static const String emojiEmoji12 = 'assets/images/emoji/emoji_12.png';
static const String emojiEmoji13 = 'assets/images/emoji/emoji_13.png';
static const String emojiEmoji14 = 'assets/images/emoji/emoji_14.png';
static const String emojiEmoji15 = 'assets/images/emoji/emoji_15.png';
static const String emojiEmoji16 = 'assets/images/emoji/emoji_16.png';
static const String emojiEmoji17 = 'assets/images/emoji/emoji_17.png';
static const String emojiEmoji18 = 'assets/images/emoji/emoji_18.png';
static const String emojiEmoji19 = 'assets/images/emoji/emoji_19.png';
static const String emojiEmoji20 = 'assets/images/emoji/emoji_20.png';
static const String emojiEmoji21 = 'assets/images/emoji/emoji_21.png';
static const String emojiEmoji22 = 'assets/images/emoji/emoji_22.png';
static const String emojiEmoji23 = 'assets/images/emoji/emoji_23.png';
static const String emojiEmoji24 = 'assets/images/emoji/emoji_24.png';
static const String emojiEmoji25 = 'assets/images/emoji/emoji_25.png';
static const String emojiEmoji26 = 'assets/images/emoji/emoji_26.png';
static const String emojiEmoji27 = 'assets/images/emoji/emoji_27.png';
static const String emojiEmoji28 = 'assets/images/emoji/emoji_28.png';
static const String emojiEmoji29 = 'assets/images/emoji/emoji_29.png';
static const String emojiEmoji30 = 'assets/images/emoji/emoji_30.png';
static const String emojiEmoji31 = 'assets/images/emoji/emoji_31.png';
static const String emojiEmoji32 = 'assets/images/emoji/emoji_32.png';
static const String emojiEmoji33 = 'assets/images/emoji/emoji_33.png';
static const String emojiEmoji34 = 'assets/images/emoji/emoji_34.png';
static const String emojiEmoji35 = 'assets/images/emoji/emoji_35.png';
static const String emojiEmoji36 = 'assets/images/emoji/emoji_36.png';
static const String emojiEmoji37 = 'assets/images/emoji/emoji_37.png';
static const String emojiEmoji38 = 'assets/images/emoji/emoji_38.png';
static const String emojiEmoji39 = 'assets/images/emoji/emoji_39.png';
static const String emojiEmoji40 = 'assets/images/emoji/emoji_40.png';
static const String emojiEmoji41 = 'assets/images/emoji/emoji_41.png';
static const String emojiEmoji42 = 'assets/images/emoji/emoji_42.png';
static const String emojiEmoji43 = 'assets/images/emoji/emoji_43.png';
static const String emojiEmoji44 = 'assets/images/emoji/emoji_44.png';
static const String emojiEmoji45 = 'assets/images/emoji/emoji_45.png';
static const String emojiEmoji46 = 'assets/images/emoji/emoji_46.png';
static const String emojiEmoji47 = 'assets/images/emoji/emoji_47.png';
static const String emojiEmoji48 = 'assets/images/emoji/emoji_48.png';
static const String emojiEmoji49 = 'assets/images/emoji/emoji_49.png';
static const String emojiEmoji50 = 'assets/images/emoji/emoji_50.png';
static const String emojiEmoji51 = 'assets/images/emoji/emoji_51.png';
static const String emojiEmoji52 = 'assets/images/emoji/emoji_52.png';
static const String emojiEmoji53 = 'assets/images/emoji/emoji_53.png';
static const String emojiEmoji54 = 'assets/images/emoji/emoji_54.png';
static const String emojiEmoji55 = 'assets/images/emoji/emoji_55.png';
static const String emojiEmoji56 = 'assets/images/emoji/emoji_56.png';
static const String emojiEmoji57 = 'assets/images/emoji/emoji_57.png';
static const String emojiEmoji58 = 'assets/images/emoji/emoji_58.png';
static const String emojiEmoji59 = 'assets/images/emoji/emoji_59.png';
static const String emojiEmoji60 = 'assets/images/emoji/emoji_60.png';
static const String emojiEmoji61 = 'assets/images/emoji/emoji_61.png';
static const String emojiEmoji62 = 'assets/images/emoji/emoji_62.png';
static const String emojiEmoji63 = 'assets/images/emoji/emoji_63.png';
static const String emojiEmoji64 = 'assets/images/emoji/emoji_64.png';
static const String imagesAd = 'assets/images/ad.png';
static const String imagesAdd = 'assets/images/add.png';
static const String imagesAliPay = 'assets/images/ali_pay.png';
@ -83,8 +147,15 @@ class Assets {
static const String imagesVip = 'assets/images/vip.png';
static const String imagesVipBanner = 'assets/images/vip_banner.png';
static const String imagesVipBg = 'assets/images/vip_bg.png';
static const String imagesVipBuyTag = 'assets/images/vip_buy_tag.png';
static const String imagesVipChat = 'assets/images/vip_chat.png';
static const String imagesVipFont = 'assets/images/vip_font.png';
static const String imagesVipGift = 'assets/images/vip_gift.png';
static const String imagesVipImg = 'assets/images/vip_img.png';
static const String imagesVipMessage = 'assets/images/vip_message.png';
static const String imagesVipSpecial = 'assets/images/vip_special.png';
static const String imagesVipVisitor = 'assets/images/vip_visitor.png';
static const String imagesVipVoice = 'assets/images/vip_voice.png';
static const String imagesVoice = 'assets/images/voice.png';
static const String imagesVoiceIcon = 'assets/images/voice_icon.png';
static const String imagesWallet = 'assets/images/wallet.png';

75
lib/model/discover/visitor_model.dart

@ -0,0 +1,75 @@
class VisitorModel {
final String? miId;
final String? profilePhoto;
final String? nickName;
final int? height;
final String? visitTime;
final String? education;
final int? age;
final int? minimumIncome;
final int? maximumIncome;
final String? income;
final String? describeInfo;
final int? vip;
final int? miSessionType;
final int? genderCode;
final int? onlineStatus;
VisitorModel({
this.miId,
this.profilePhoto,
this.nickName,
this.height,
this.visitTime,
this.education,
this.age,
this.minimumIncome,
this.maximumIncome,
this.income,
this.describeInfo,
this.vip,
this.miSessionType,
this.genderCode,
this.onlineStatus,
});
factory VisitorModel.fromJson(Map<String, dynamic> json) {
return VisitorModel(
miId: json['miId'] as String?,
profilePhoto: json['profilePhoto'] as String?,
nickName: json['nickName'] as String?,
height: json['height'] as int?,
visitTime: json['visitTime'] as String?,
education: json['education'] as String?,
age: json['age'] as int?,
minimumIncome: json['minimumIncome'] as int?,
maximumIncome: json['maximumIncome'] as int?,
income: json['income'] as String?,
describeInfo: json['describeInfo'] as String?,
vip: json['vip'] as int?,
miSessionType: json['miSessionType'] as int?,
genderCode: json['genderCode'] as int?,
onlineStatus: json['onlineStatus'] as int?,
);
}
Map<String, dynamic> toJson() {
return {
'miId': miId,
'profilePhoto': profilePhoto,
'nickName': nickName,
'height': height,
'visitTime': visitTime,
'education': education,
'age': age,
'minimumIncome': minimumIncome,
'maximumIncome': maximumIncome,
'income': income,
'describeInfo': describeInfo,
'vip': vip,
'miSessionType': miSessionType,
'genderCode': genderCode,
'onlineStatus': onlineStatus,
};
}
}

21
lib/model/mine/submit_order_data.dart

@ -0,0 +1,21 @@
class SubmitOrderData {
String? orderId;
String? paymentOrderId;
bool? freeSettlement;
SubmitOrderData({this.orderId, this.paymentOrderId, this.freeSettlement});
SubmitOrderData.fromJson(Map<String, dynamic> json) {
orderId = json['orderId'];
paymentOrderId = json['paymentOrderId'];
freeSettlement = json['freeSettlement'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['orderId'] = this.orderId;
data['paymentOrderId'] = this.paymentOrderId;
data['freeSettlement'] = this.freeSettlement;
return data;
}
}

3
lib/network/api_urls.dart

@ -15,7 +15,8 @@ class ApiUrls {
static const String listVirtualCurrencyProduct = 'dating-agency-mall/user/list/virtual-currency-product';
static const String getVirtualAccount = 'dating-agency-mall/user/get/virtual-account';
static const String pageVirtualAccountRecord = 'dating-agency-mall/user/page/virtual-account-record';
static const String getCertificationList = '/dating-agency-service/user/get/certification/item/all/list';
static const String getCertificationList = 'dating-agency-service/user/get/certification/item/all/list';
static const String submitOrder = 'dating-agency-mall/user/submit/order';
//
static const String getMarriageList = 'dating-agency-service/user/page/dongwo/marriage-information';

6
lib/network/user_api.dart

@ -11,6 +11,7 @@ import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import '../model/mine/authentication_data.dart';
import '../model/mine/submit_order_data.dart';
part 'user_api.g.dart';
@ -73,4 +74,9 @@ abstract class UserApi {
@Query('pageSize') required int pageSize,
@Query('tradeType') int? tradeType,
});
@POST(ApiUrls.submitOrder)
Future<HttpResponse<BaseResponse<SubmitOrderData>>> submitOrder(
@Body() Map<String, dynamic> data,
);
}

39
lib/network/user_api.g.dart

@ -232,7 +232,7 @@ class _UserApi implements UserApi {
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'/dating-agency-service/user/get/certification/item/all/list',
'dating-agency-service/user/get/certification/item/all/list',
queryParameters: queryParameters,
data: _data,
)
@ -441,6 +441,43 @@ class _UserApi implements UserApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<SubmitOrderData>>> submitOrder(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options =
_setStreamType<HttpResponse<BaseResponse<SubmitOrderData>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-mall/user/submit/order',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl),
),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<SubmitOrderData> _value;
try {
_value = BaseResponse<SubmitOrderData>.fromJson(
_result.data!,
(json) => SubmitOrderData.fromJson(json as Map<String, dynamic>),
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

258
lib/pages/discover/visitor_list_page.dart

@ -0,0 +1,258 @@
// pages/visitor_list_page.dart
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../controller/discover/visitor_controller.dart';
import '../../model/discover/visitor_model.dart';
class VisitorListPage extends StatelessWidget {
final VisitorController visitorController = Get.put(VisitorController());
VisitorListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffF5F5F5),
appBar: AppBar(
title: Obx(() => Text(
'最近访客 (${visitorController.todayVisitorsCount})',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
)),
centerTitle: true,
backgroundColor: Colors.white,
actions: [
//
PopupMenuButton<String>(
onSelected: (value) {
if (value == 'clear') {
_showClearDialog();
} else if (value == 'sort') {
_showSortDialog();
}
},
itemBuilder: (BuildContext context) => [
PopupMenuItem(value: 'sort', child: Text('排序方式')),
PopupMenuItem(value: 'clear', child: Text('清空记录')),
],
),
],
),
body: Obx(() {
if (visitorController.isLoading.value && visitorController.visitors.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('加载访客数据中...'),
],
),
);
}
if (visitorController.visitors.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.people_outline, size: 80, color: Colors.grey[300]),
SizedBox(height: 16),
Text(
'暂无访客记录',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
SizedBox(height: 8),
Text(
'下拉刷新获取数据',
style: TextStyle(color: Colors.grey),
),
],
),
);
}
return SmartRefresher(
controller: visitorController.refreshController,
enablePullDown: true,
enablePullUp: visitorController.hasMore.value,
onRefresh: visitorController.onRefresh,
onLoading: visitorController.onLoadMore,
header: ClassicHeader(
idleText: '下拉刷新',
releaseText: '松开刷新',
refreshingText: '刷新中...',
completeText: '刷新完成',
failedText: '刷新失败',
height: 60,
),
footer: CustomFooter(
builder: (BuildContext context, LoadStatus? mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = Text("上拉加载更多");
} else if (mode == LoadStatus.loading) {
body = CircularProgressIndicator();
} else if (mode == LoadStatus.failed) {
body = Text("加载失败,点击重试");
} else if (mode == LoadStatus.canLoading) {
body = Text("松开加载更多");
} else {
body = Text("没有更多数据了");
}
return SizedBox(
height: 36,
child: Center(child: body),
);
},
),
child: ListView.builder(
padding: const EdgeInsets.only(top: 8, right: 10, left: 10),
itemCount: visitorController.visitors.length,
itemBuilder: (context, index) {
final visitor = visitorController.visitors[index];
return VisitorListItem(visitor: visitor);
},
),
);
}),
);
}
void _showClearDialog() {
Get.dialog(
AlertDialog(
title: Text('确认清空'),
content: Text('确定要清空所有访客记录吗?此操作不可恢复。'),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text('取消'),
),
TextButton(
onPressed: () {
visitorController.clearAllVisitors();
Get.back();
},
child: Text('确定', style: TextStyle(color: Colors.red)),
),
],
),
);
}
void _showSortDialog() {
Get.dialog(
AlertDialog(
title: Text('排序方式'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text('按访问时间'),
onTap: () {
//
Get.back();
},
),
ListTile(
title: Text('按访问时长'),
onTap: () {
//
Get.back();
},
),
ListTile(
title: Text('按访问次数'),
onTap: () {
//
Get.back();
},
),
],
),
),
);
}
}
class VisitorListItem extends StatelessWidget {
final VisitorModel visitor;
const VisitorListItem({Key? key, required this.visitor}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.all(12),
margin: EdgeInsets.only(bottom: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.blue[100],
image: DecorationImage(
image: NetworkImage(visitor.profilePhoto!),
fit: BoxFit.cover,
),
),
),
SizedBox(width: 12),
Expanded(
child: Column(
children: [
Row(
children: [
Text(
visitor.nickName!,
style: TextStyle(
fontSize: 14,
),
),
Spacer(),
Text(
visitor.visitTime!,
style: TextStyle(
color: Colors.grey[500],
fontSize: 13,
),
),
],
),
SizedBox(height: 4),
SizedBox(
// height: 20, // 20
child: Text(
visitor.describeInfo!,
style: TextStyle(
fontSize: 13,
color: Color.fromRGBO(51, 51, 51, 0.6),
),
overflow: TextOverflow.ellipsis, // ...
maxLines: 1, //
),
),
],
)
)
],
),
).onTap((){
// _showVisitorDetail(visitor);
});
}
}

993
lib/pages/home/user_information_page.dart
File diff suppressed because it is too large
View File

14
lib/pages/mine/auth_center_page.dart

@ -17,14 +17,8 @@ class AuthCenterPage extends StatelessWidget {
return Scaffold(
backgroundColor: Color(0xffF5F5F5),
appBar: AppBar(
title: Text('认证中心', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
title: Text('认证中心', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, size: 24, color: Colors.grey,),
onPressed: () {
Get.back();
},
),
),
body: Obx(() {
if (controller.isLoading.value) {
@ -115,12 +109,12 @@ class AuthCenterPage extends StatelessWidget {
).onTap(() async{
if(!item.authed){
if(item.index == 2){
Get.to(() => EditInfoPage());
// Get.to(widget.path);
await Get.to(() => EditInfoPage());
controller.loadInitialData();
} else if(item.index == 3){
final result = await Get.to(() => RealNamePage());
if(result > 0){
controller.changeAuth(result);
controller.loadInitialData();
}
}
}

1164
lib/pages/mine/edit_info_page.dart
File diff suppressed because it is too large
View File

299
lib/pages/mine/mine_page.dart

@ -1,5 +1,6 @@
import 'package:dating_touchme_app/controller/mine/mine_controller.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/pages/discover/visitor_list_page.dart';
import 'package:dating_touchme_app/pages/mine/edit_info_page.dart';
import 'package:dating_touchme_app/pages/mine/vip_page.dart';
import 'package:flutter/material.dart';
@ -20,166 +21,186 @@ class MinePage extends StatefulWidget {
class _MinePageState extends State<MinePage> with AutomaticKeepAliveClientMixin{
final MineController ctrl = Get.put(MineController());
@override
void initState() {
super.initState();
// HomeController
if (!Get.isRegistered<MineController>()) {
Get.put(MineController());
}
}
@override
Widget build(BuildContext context) {
super.build(context);
return Container(
padding: EdgeInsets.symmetric(horizontal: 9.w),
constraints: BoxConstraints(minHeight: ScreenUtil().setHeight(800)),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(248, 242, 255, 1.0), // rgba(248, 242, 255, 1)
Color.fromRGBO(247, 247, 247, 1.0), // rgba(247, 247, 247, 1)
],
stops: [0.0, 1.0],
),
),
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).padding.top + 54.w,
),
Container(
width: 356.w,
padding: EdgeInsets.only(
left: 6.w,
right: 5.w
return GetBuilder<MineController>(
builder: (controller) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 9.w),
constraints: BoxConstraints(minHeight: ScreenUtil().setHeight(800)),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(248, 242, 255, 1.0), // rgba(248, 242, 255, 1)
Color.fromRGBO(247, 247, 247, 1.0), // rgba(247, 247, 247, 1)
],
stops: [0.0, 1.0],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
),
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).padding.top + 54.w,
),
Container(
width: 356.w,
padding: EdgeInsets.only(
left: 6.w,
right: 5.w
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
Assets.imagesUserAvatar,
width: 60.w,
height: 60.w,
),
SizedBox(width: 14.w,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
Row(
children: [
Row(
(controller.userData.value?.profilePhoto?.isNotEmpty ?? false) ? Image.network(
"${controller.userData.value?.profilePhoto ?? ""}",
width: 60.w,
height: 60.w,
) : Image.asset(
Assets.imagesUserAvatar,
width: 60.w,
height: 60.w,
),
SizedBox(width: 14.w,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
"${controller.userData.value?.nickName ?? ""}",
style: TextStyle(
fontSize: 18.w,
color: const Color.fromRGBO(51, 51, 51, 1),
fontWeight: FontWeight.w700
),
),
SizedBox(width: 8.w,),
Image.asset(
Assets.imagesVip,
width: 44.w,
height: 16.w,
)
],
),
SizedBox(height: 11.w,),
Text(
"用户昵称",
"ID:${controller.userData.value?.id ?? ""}",
style: TextStyle(
fontSize: 18.w,
fontSize: 12.w,
color: const Color.fromRGBO(51, 51, 51, 1),
fontWeight: FontWeight.w700
fontWeight: FontWeight.w500
),
),
SizedBox(width: 8.w,),
Image.asset(
Assets.imagesVip,
width: 44.w,
height: 16.w,
)
],
),
SizedBox(height: 11.w,),
Text(
"ID:4654654565",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(51, 51, 51, 1),
fontWeight: FontWeight.w500
),
)
],
),
InkWell(
onTap: (){
Get.to(() => EditInfoPage());
},
child: Row(
children: [
Image.asset(
Assets.imagesEdit,
width: 10.w,
height: 10.w,
),
SizedBox(width: 4.w,),
Text(
"编辑资料",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(55, 57, 72, 1),
fontWeight: FontWeight.w500
),
)
],
),
)
],
),
InkWell(
onTap: (){
Get.to(() => EditInfoPage());
},
child: Row(
children: [
Image.asset(
Assets.imagesEdit,
width: 10.w,
height: 10.w,
),
SizedBox(width: 4.w,),
Text(
"编辑资料",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(55, 57, 72, 1),
fontWeight: FontWeight.w500
),
)
],
),
SizedBox(height: 16.w,),
Container(
height: 57.w,
padding: EdgeInsets.only(
top: 11.w,
right: 37.w,
bottom: 8.w,
left: 27.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
...controller.infoList.map((e){
return InfoItem(item: e);
}),
],
),
),
SizedBox(height: 12.w,),
Stack(
children: [
Image.asset(
Assets.imagesVipBanner,
width: 356.w,
height: 64.w,
),
)
],
),
),
SizedBox(height: 16.w,),
Container(
height: 57.w,
padding: EdgeInsets.only(
top: 11.w,
right: 37.w,
bottom: 8.w,
left: 27.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
...ctrl.infoList.map((e){
return InfoItem(item: e);
}),
],
),
),
SizedBox(height: 12.w,),
Stack(
children: [
Image.asset(
Assets.imagesVipBanner,
width: 356.w,
height: 64.w,
Positioned(
top: 18.w,
right: 15.w,
child: InkWell(
child: SizedBox(
width: 73.w,
height: 28.w,
).onTap((){
Get.to(() => VipPage());
}),
),
)
],
),
Positioned(
top: 18.w,
right: 15.w,
child: InkWell(
child: SizedBox(
width: 73.w,
height: 28.w,
).onTap((){
Get.to(() => VipPage());
SizedBox(height: 12.w,),
Wrap(
spacing: 8.w,
runSpacing: 8.w,
children: [
...controller.blockList.map((e){
return BlockItem(item: e, showWaring: e["title"] == "认证中心", path: e["path"],);
}),
),
)
],
),
SizedBox(height: 12.w,),
Wrap(
spacing: 8.w,
runSpacing: 8.w,
children: [
...ctrl.blockList.map((e){
return BlockItem(item: e, showWaring: e["title"] == "认证中心", path: e["path"],);
],
),
SizedBox(height: 12.w,),
...controller.settingList.map((e){
return SettingItem(item: e);
}),
],
),
SizedBox(height: 12.w,),
...ctrl.settingList.map((e){
return SettingItem(item: e);
}),
],
),
);
},
);
}
@ -224,7 +245,11 @@ class _InfoItemState extends State<InfoItem> {
),
)
],
);
).onTap((){
if(widget.item['type'] == 4){
Get.to(()=> VisitorListPage());
}
});
}
}

81
lib/pages/mine/pay_fail_page.dart

@ -0,0 +1,81 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class PayFailPage extends StatefulWidget {
const PayFailPage({super.key});
@override
State<PayFailPage> createState() => _PayFailPageState();
}
class _PayFailPageState extends State<PayFailPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "支付结果"),
body: SingleChildScrollView(
child: Container(
width: 375.w,
padding: EdgeInsets.symmetric(
vertical: 60.w
),
child: Column(
children: [
Container(
width: 70.w,
height: 70.w,
margin: EdgeInsets.only(bottom: 16.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(70.w)),
color: const Color.fromRGBO(248, 85, 66, 1)
),
child: Center(
child: Icon(
Icons.close,
size: 50.w,
color: Colors.white,
),
),
),
Text(
"交易失败",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
SizedBox(height: 292.w,),
Container(
width: 150.w,
height: 30.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30.w)),
color: const Color.fromRGBO(245, 245, 245, 1)
),
child: Center(
child: Text(
"联系客服",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
),
),
SizedBox(height: 18.w,),
Text(
"返回",
style: TextStyle(
fontSize: 13.w,
color: const Color.fromRGBO(144, 144, 144, 1),
fontWeight: FontWeight.w500
),
)
],
),
),
),
);
}
}

8
lib/pages/mine/real_name_page.dart

@ -15,14 +15,8 @@ class RealNamePage extends StatelessWidget {
return Scaffold(
backgroundColor: Color(0xffFFFFFF),
appBar: AppBar(
title: Text('实名认证', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
title: Text('实名认证', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, size: 24, color: Colors.grey,),
onPressed: () {
Get.back();
},
),
),
body: Column(
children: [

75
lib/pages/mine/renew_manage_page.dart

@ -0,0 +1,75 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class RenewManagePage extends StatefulWidget {
const RenewManagePage({super.key});
@override
State<RenewManagePage> createState() => _RenewManagePageState();
}
class _RenewManagePageState extends State<RenewManagePage> {
bool blockUser = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "自动续费管理"),
body: SingleChildScrollView(
child: Column(
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 14.w
),
margin: EdgeInsets.only(
bottom: 12.w
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"自动续费管理",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
TDSwitch(
isOn: blockUser,
trackOnColor: const Color.fromRGBO(117, 98, 249, 1),
onChanged: (bool e){
print(e);
blockUser = e;
setState(() {
});
return e;
},
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 14.w
),
child: Text(
"关闭“会员自动续费”即可解除连续包月协议,次月将不再扣除会员服务费,也可以前往支付宝和微信进行解约。",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(144, 144, 144, 1)
),
),
)
],
),
),
);
}
}

5
lib/pages/mine/rose_page.dart

@ -1,5 +1,6 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/controller/mine/rose_controller.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/mine/rose_data.dart';
import 'package:dating_touchme_app/pages/mine/rose_history_page.dart';
@ -220,7 +221,9 @@ class RosePage extends StatelessWidget {
),
),
),
)
).onTap((){
controller.submitOrder();
})
],
),
),

54
lib/pages/mine/vip_manage_page.dart

@ -0,0 +1,54 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/pages/mine/renew_manage_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
class VipManagePage extends StatefulWidget {
const VipManagePage({super.key});
@override
State<VipManagePage> createState() => _VipManagePageState();
}
class _VipManagePageState extends State<VipManagePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "会员特权管理"),
body: SingleChildScrollView(
child: Column(
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 14.w
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"自动续费管理",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
Icon(
Icons.keyboard_arrow_right,
size: 20.w,
color: const Color.fromRGBO(191, 191, 191, 1),
)
],
),
).onTap((){
Get.to(() => RenewManagePage());
})
],
),
),
);
}
}

390
lib/pages/mine/vip_page.dart

@ -1,7 +1,11 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/pages/mine/pay_fail_page.dart';
import 'package:dating_touchme_app/pages/mine/vip_manage_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class VipPage extends StatefulWidget {
const VipPage({super.key});
@ -15,6 +19,19 @@ class _VipPageState extends State<VipPage> {
bool checked = false;
int vipActive = 0;
List<Map> vipPrivilege = [
{"img": Assets.imagesVipSpecial, "label": "特殊标识"},
{"img": Assets.imagesVipVisitor, "label": "最近访客"},
{"img": Assets.imagesVipGift, "label": "专属礼物"},
{"img": Assets.imagesVipVoice, "label": "语音弹幕"},
];
int payActive = 0;
@override
Widget build(BuildContext context) {
return Stack(
@ -46,7 +63,7 @@ class _VipPageState extends State<VipPage> {
),
child: InkWell(
onTap: (){
print("12121");
Get.to(() => VipManagePage());
},
child: Image.asset(
Assets.imagesSettingIcon,
@ -60,7 +77,7 @@ class _VipPageState extends State<VipPage> {
children: [
Container(
padding: EdgeInsets.only(
top: 20.w,
top: 5.w,
left: 15.w
),
child:
@ -131,7 +148,7 @@ class _VipPageState extends State<VipPage> {
),
),
Positioned(
top: 270.w,
top: 260.w,
left: 0,
child: Material(
child: Container(
@ -152,9 +169,24 @@ class _VipPageState extends State<VipPage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
VipItem(),
VipItem(),
VipItem(),
VipItem(active: vipActive, index: 0,).onTap((){
vipActive = 0;
setState(() {
});
}),
VipItem(active: vipActive, index: 1,).onTap((){
vipActive = 1;
setState(() {
});
}),
VipItem(active: vipActive, index: 2,).onTap((){
vipActive = 2;
setState(() {
});
}),
],
),
SizedBox(height: 12.w,),
@ -201,11 +233,184 @@ class _VipPageState extends State<VipPage> {
padding: EdgeInsets.symmetric(
horizontal: 18.w
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
...vipPrivilege.map((e){
return VipPrivilege(img: e["img"], label: e["label"]);
})
],
),
),
SizedBox(height: 15.w,),
Container(
height: 60.w,
padding: EdgeInsets.symmetric(
vertical: 19.w,
horizontal: 18.w
),
margin: EdgeInsets.only(
bottom: 10.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
color: const Color.fromRGBO(117, 98, 249, .1)
),
child: Row(
children: [
Image.asset(
Assets.imagesVipChat,
width: 34.w,
),
SizedBox(width: 16.w,),
Text(
"【聊天券】立即得70张,后续每天领7张,共280张",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w500
),
)
],
),
),
Container(
height: 60.w,
padding: EdgeInsets.symmetric(
vertical: 19.w,
horizontal: 18.w
),
margin: EdgeInsets.only(
bottom: 10.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
color: const Color.fromRGBO(117, 98, 249, .1)
),
child: Row(
children: [
Image.asset(
Assets.imagesVipMessage,
width: 34.w,
),
SizedBox(width: 16.w,),
Text(
"【消息回执】消息已读!看到了~",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w500
),
)
],
),
),
Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 86.w,
height: 30.w,
padding: EdgeInsets.symmetric(
horizontal: 9.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30.w)),
border: Border.all(
width: 1,
color: Color.fromRGBO(117, 98, 249, payActive == 0 ? 1 : 0)),
color: payActive == 0 ?
const Color.fromRGBO(117, 98, 249, .07) :
const Color.fromRGBO(247, 247, 247, 1)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
Assets.imagesWechatPay,
width: 17.w,
),
Text(
"微信支付",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w500
),
)
],
),
).onTap((){
payActive = 0;
setState(() {
});
}),
Container(
width: 80.w,
height: 30.w,
padding: EdgeInsets.symmetric(
horizontal: 12.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30.w)),
border: Border.all(
width: 1,
color: Color.fromRGBO(117, 98, 249, payActive == 1 ? 1 : 0)),
color: payActive == 1 ?
const Color.fromRGBO(117, 98, 249, .07) :
const Color.fromRGBO(247, 247, 247, 1)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
Assets.imagesAliPay,
width: 17.w,
),
Text(
"支付宝",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w500
),
)
],
),
).onTap((){
payActive = 1;
setState(() {
});
}),
Container(
width: 161.w,
height: 45.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(45.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg:
end: Alignment.centerRight,
colors: [
Color.fromRGBO(131, 89, 255, 1), //
Color.fromRGBO(77, 127, 231, 1), //
Color.fromRGBO(61, 138, 224, 1), //
],
stops: [0.0, 0.7753, 1.0], // 0%77.53%100%
),
),
child: Center(
child: Text(
"立即开通",
style: TextStyle(
fontSize: 18.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
),
).onTap((){
Get.to(() => PayFailPage());
})
],
)
],
),
@ -218,7 +423,9 @@ class _VipPageState extends State<VipPage> {
}
class VipItem extends StatefulWidget {
const VipItem({super.key});
final int index;
final int active;
const VipItem({super.key, required this.index, required this.active});
@override
State<VipItem> createState() => _VipItemState();
@ -227,66 +434,112 @@ class VipItem extends StatefulWidget {
class _VipItemState extends State<VipItem> {
@override
Widget build(BuildContext context) {
return
Container(
width: 111.w,
height: 117.w,
padding: EdgeInsets.only(
top: 16.w,
bottom: 21.w
),
decoration: BoxDecoration(
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 113.w,
height: 119.w,
padding: EdgeInsets.only(
top: 16.w,
bottom: 21.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18.w)),
border: Border.all(width: 1, color: Color.fromRGBO(222, 222, 222, 1))
),
child: Column(
children: [
Text(
"3个月",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w700
),
border: widget.active == widget.index ?
Border.all(
width: 2,
color: const Color.fromRGBO(117, 98, 249, 1)) : Border.all(
width: 1,
color: Color.fromRGBO(222, 222, 222, 1)
),
SizedBox(height: 2.w,),
Text(
"¥29.3/月",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(144, 144, 144, 1)
gradient: widget.active == widget.index ? LinearGradient(
begin: Alignment.centerLeft, // 90deg
end: Alignment.centerRight,
colors: [
Color.fromRGBO(232, 199, 255, 0.2), // 20%
Color.fromRGBO(194, 195, 255, 0.2), // 20%
],
stops: [0.0, 1.0], // [0.0, 1.0]
) : null,
),
child: Column(
children: [
Text(
"3个月",
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w700
),
),
),
SizedBox(height: 23.w,),
RichText(
text: TextSpan(
SizedBox(height: 2.w,),
Text(
"¥29.3/月",
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1),
fontWeight: FontWeight.w700
fontSize: 11.w,
color: const Color.fromRGBO(144, 144, 144, 1)
),
children: [
TextSpan(
text: "",
style: TextStyle(
fontSize: 12.w
)
),
TextSpan(
text: "88",
style: TextStyle(
fontSize: 18.w
)
),
]
),
)
],
SizedBox(height: 23.w,),
RichText(
text: TextSpan(
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1),
fontWeight: FontWeight.w700
),
children: [
TextSpan(
text: "",
style: TextStyle(
fontSize: 12.w
)
),
TextSpan(
text: "88",
style: TextStyle(
fontSize: 18.w
)
),
]
),
)
],
),
),
);
Positioned(
left: 0,
top: -5.w,
child: Stack(
children: [
Image.asset(
Assets.imagesVipBuyTag,
width: 60.w,
height: 18.w,
),
Positioned.fill(
child: Center(
child: Text(
"推荐",
style: TextStyle(
fontSize: 11.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
),
)
],
),
)
],
);
}
}
class VipPrivilege extends StatefulWidget {
const VipPrivilege({super.key});
final String img;
final String label;
const VipPrivilege({super.key, required this.img, required this.label});
@override
State<VipPrivilege> createState() => _VipPrivilegeState();
@ -297,8 +550,27 @@ class _VipPrivilegeState extends State<VipPrivilege> {
Widget build(BuildContext context) {
return Column(
children: [
Image.asset(
Assets.imagesWallet
Container(
width: 54.w,
height: 54.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18.w)),
color: const Color.fromRGBO(245, 245, 245, 1)
),
child: Center(
child: Image.asset(
widget.img,
width: 30.w,
),
),
),
SizedBox(height: 3.w,),
Text(
widget.label,
style: TextStyle(
fontSize: 11.w,
fontWeight: FontWeight.w500
),
)
],
);

420
pubspec.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save