diff --git a/assets/edit_avatar.png b/assets/edit_avatar.png new file mode 100644 index 0000000..6dd92fb Binary files /dev/null and b/assets/edit_avatar.png differ diff --git a/lib/components/page_appbar.dart b/lib/components/page_appbar.dart index 0461e10..03d8655 100644 --- a/lib/components/page_appbar.dart +++ b/lib/components/page_appbar.dart @@ -21,9 +21,9 @@ class PageAppbar extends StatelessWidget implements PreferredSizeWidget { title: Text( title, style: TextStyle( - fontSize: ScreenUtil().setWidth(32), - fontWeight: FontWeight.bold, - color: color + fontSize: ScreenUtil().setWidth(27), + fontWeight: FontWeight.w500, + color: const Color.fromRGBO(51, 51, 51, 1) ), ), ); diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index ddb4784..4cbaf11 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -11,7 +11,7 @@ class AppConfig { case 'test': return const AppConfig._('https://test-api.example.com'); default: - return const AppConfig._('https://dev-api.example.com'); + return const AppConfig._('https://dating-agency-api-test.qniao.cn'); } } } diff --git a/lib/http/api.dart b/lib/http/api.dart index fb3c5af..b7b38fb 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -15,24 +15,22 @@ class Api { // 初始化基本选项 } - $getUserData() async { - // 假设发起了请求 - // var result = await Request().request( - // "xxx", - // method: DioMethod.get, - // params: data, - // isToken: true - // ); - return { - "code": 200, - "data": { - "id": 1, - "nickName": "xxx", - "phone": 123123123, - "token": "xawqweqeqwqwqwe" - }, - "msg": "请求成功" - }; + $getAuthCaptcha(data) async { + var result = await Request().request( + "/dating-agency-uec/authorize/get/auth-captcha", + method: DioMethod.post, + data: data + ); + return result; + } + + $login(data) async { + var result = await Request().request( + "/dating-agency-uec/authorize/by-captcha", + method: DioMethod.post, + data: data + ); + return result; } diff --git a/lib/pages/edit_info_page.dart b/lib/pages/edit_info_page.dart new file mode 100644 index 0000000..c1a3bc8 --- /dev/null +++ b/lib/pages/edit_info_page.dart @@ -0,0 +1,443 @@ +import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:dating_touchme_app/router/route_paths.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:go_router/go_router.dart'; + +class EditInfoPage extends StatefulWidget { + const EditInfoPage({super.key}); + + @override + State createState() => _EditInfoPageState(); +} + +class _EditInfoPageState extends State { + + int menuActive = 1; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PageAppbar(title: "编辑资料"), + body: SingleChildScrollView( + child: Column( + children: [ + Row( + children: [ + Expanded( + child: InkWell( + onTap: (){ + menuActive = 1; + setState(() { + + }); + }, + child: Container( + height: 98.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 1, + color: menuActive == 1 ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(242, 242, 242, 1)) + ) + ), + child: Center( + child: Text( + "预览", + style: TextStyle( + fontSize: 27.w, + color: menuActive == 1 ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(144, 144, 144, 1) + ), + ), + ), + ), + ), + ), + Expanded( + child: InkWell( + onTap: (){ + menuActive = 2; + setState(() { + + }); + }, + child: Container( + height: 98.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 1, + color: menuActive == 2 ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(242, 242, 242, 1)) + ) + ), + child: Center( + child: Text( + "预览", + style: TextStyle( + fontSize: 27.w, + color: menuActive == 2 ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(144, 144, 144, 1) + ), + ), + ), + ), + ), + ), + ], + ), + SizedBox(height: 52.w,), + Stack( + children: [ + SizedBox( + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(170.w)), + child: Image.asset( + "assets/user_avatar.png", + width: 170.w, + height: 170.w, + ), + ), + ), + Positioned( + right: 17.w, + bottom: 2.w, + child: Image.asset( + "assets/edit_avatar.png", + width: 34.w, + height: 34.w, + ), + ) + ], + ), + SizedBox(height: 41.w,), + Container( + width: 750.w, + padding: EdgeInsets.only( + left: 29.w, + right: 40.w + ), + child: Column( + children: [ + Row( + children: [ + Text( + "个人相册", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ), + SizedBox(height: 10.w,), + Container( + width: 681.w, + margin: EdgeInsets.only(bottom: 70.w), + child: Wrap( + spacing: 10.w, + runSpacing: 10.w, + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + child: Image.network( + "https://fastly.picsum.photos/id/1003/400/400.jpg?hmac=aA6suLuxF9UGDuOSzWauxOJBgBT0XeUFVqMIIjO4hJU", + width: 141.w, + height: 141.w, + ), + ), + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + child: Image.network( + "https://fastly.picsum.photos/id/342/400/400.jpg?hmac=u_p3Kwp2J2A0XENzZfDKmtTzLjqsxLF48EUgImcL6v8", + width: 141.w, + height: 141.w, + ), + ), + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + child: Image.network( + "https://fastly.picsum.photos/id/935/400/400.jpg?hmac=d-_aU-UWnAMEk7lMRmhv-yD1sBBeSmiQ9fbTmcQqDT4", + width: 141.w, + height: 141.w, + ), + ), + Container( + width: 141.w, + height: 141.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.w)), + border: Border.all(width: 1, color: const Color.fromRGBO(224, 224, 224, 1)) + ), + child: Center( + child: Icon( + Icons.add, + size: 30.w, + color: const Color.fromRGBO(144, 144, 144, 1), + ), + ), + ) + ], + ), + ), + Row( + children: [ + Text( + "基本信息", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ), + SizedBox(height: 5.w,), + SetItem(label: "昵称",), + Container( + margin: EdgeInsets.only(bottom: 6.w), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: const Color.fromRGBO(245, 245, 245, 1)) + ) + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: "性别", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(51, 51, 51, 1), + fontWeight: FontWeight.w500 + ) + ), + ] + ), + ), + Row( + children: [ + Text( + "男", + style: TextStyle( + fontSize: 26.w, + fontWeight: FontWeight.w500, + color: const Color.fromRGBO(51, 51, 51, 1) + ), + ), + SizedBox(width: 30.w,), + Image.asset( + "assets/male.png", + width: 26.w, + height: 26.w, + color: const Color.fromRGBO(218, 218, 218, 1) + ) + ], + ) + + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: "生日", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(51, 51, 51, 1), + fontWeight: FontWeight.w500 + ) + ), + TextSpan( + text: "*", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(224, 54, 54, 1), + fontWeight: FontWeight.w500 + ) + ), + ] + ), + ), + Row( + children: [ + Text( + "1989-06-30", + style: TextStyle( + fontSize: 26.w, + fontWeight: FontWeight.w500, + color: const Color.fromRGBO(51, 51, 51, 1) + ), + ), + SizedBox(width: 30.w,), + Icon( + Icons.keyboard_arrow_right, + size: 26.w, + color: const Color.fromRGBO(191, 191, 191, 1) + ) + ], + ) + ], + ), + ], + ), + ), + SetItem(label: "身高",), + SetItem(label: "所在地", showRequired: false,), + SetItem(label: "家乡",), + SetItem(label: "学历",), + SetItem(label: "职业",), + SetItem(label: "公司", showRequired: false,), + SetItem(label: "月收入",), + SetItem(label: "婚姻状况", showRequired: false,), + SetItem(label: "有无房产", showRequired: false,), + SizedBox(height: 16.w,), + InkWell( + onTap: (){ + context.pushNamed(RouteNames.signature); + }, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "交友心声", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ), + Icon( + Icons.keyboard_arrow_right, + size: 26.w, + color: const Color.fromRGBO(191, 191, 191, 1) + ) + ], + ), + Container( + margin: EdgeInsets.only(bottom: 6.w), + padding: EdgeInsets.only(bottom: 24.w), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: const Color.fromRGBO(245, 245, 245, 1)) + ) + ), + child: Text( + "拒绝内耗,向阳而生,用热爱抵御岁月漫长,用真诚对待每一次相遇拒绝内耗,向阳而生,用热爱抵御岁月漫长,用真诚对待每一次相遇", + style: TextStyle( + fontSize: 26.w, + fontWeight: FontWeight.w500, + color: const Color.fromRGBO(51, 51, 51, 1) + ), + ), + ), + ], + ), + ), + SetItem(label: "个性标签", showRequired: false,), + SizedBox(height: 16.w,), + Row( + children: [ + Text( + "交友范围", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(144, 144, 144, 1) + ), + ) + ], + ), + SizedBox(height: 5.w,), + SetItem(label: "所在地", showRequired: false,), + SetItem(label: "年龄", showRequired: false,), + SetItem(label: "身高", showRequired: false,), + SetItem(label: "最低学历", showRequired: false,), + SetItem(label: "最低月收入", showRequired: false,), + ], + ), + ) + ], + ), + ), + ); + } +} + +class SetItem extends StatefulWidget { + final String label; + final bool showRequired; + const SetItem({super.key, required this.label, this.showRequired = true}); + + @override + State createState() => _SetItemState(); +} + +class _SetItemState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.only(bottom: 6.w), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: const Color.fromRGBO(245, 245, 245, 1)) + ) + ), + child: InkWell( + child: SizedBox( + height: 83.w, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: widget.label, + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(51, 51, 51, 1), + fontWeight: FontWeight.w500 + ) + ), + if(widget.showRequired) TextSpan( + text: "*", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(224, 54, 54, 1), + fontWeight: FontWeight.w500 + ) + ), + ] + ), + ), + Row( + children: [ + Text( + "未选择", + style: TextStyle( + fontSize: 26.w, + color: const Color.fromRGBO(191, 191, 191, 1) + ), + ), + SizedBox(width: 30.w,), + Icon( + Icons.keyboard_arrow_right, + size: 26.w, + color: const Color.fromRGBO(191, 191, 191, 1) + ) + ], + ) + ], + ), + ), + ), + ); + } +} + diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 2456aba..0f147ca 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,5 +1,9 @@ +import 'dart:async'; + +import 'package:dating_touchme_app/http/api.dart'; import 'package:dating_touchme_app/model/phone_code.dart'; import 'package:dating_touchme_app/router/route_paths.dart'; +import 'package:dating_touchme_app/utils/storage.dart'; import 'package:dating_touchme_app/utils/utils.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -23,6 +27,7 @@ class _LoginPageState extends State { String selectPhoneCode = "86"; int s = 0; + Timer? timer; bool checked = false; @@ -33,6 +38,29 @@ class _LoginPageState extends State { }); } + sendMsg() async { + var res = await Api().$getAuthCaptcha({ + "purpose":1, + "verifiableAccount":phone, + "verifiableAccountType":1 + }); + if(res["message"] == "successful"){ + toast("发送成功", context); + setState(() { + s = 60; + timer = Timer.periodic(const Duration(seconds: 1), (timer) { + setState(() { + s--; + if(s == 0){ + timer.cancel(); + } + }); + }); + }); + } else { + toast(res["msg"], context); + } + } @override Widget build(BuildContext context) { @@ -169,6 +197,9 @@ class _LoginPageState extends State { ), onChanged: (value){ phone = value; + setState(() { + + }); }, )), InputItem(child: TextField( @@ -197,7 +228,7 @@ class _LoginPageState extends State { // toast("请输入正确的手机号", context); // return; // } - // sendMsg(); + sendMsg(); }, child: Text( s > 0 ? "${s}s后再获取" : "获取验证码", @@ -222,6 +253,9 @@ class _LoginPageState extends State { ), onChanged: (value){ code = value; + setState(() { + + }); }, )), SizedBox(height: 12.w,), @@ -287,7 +321,34 @@ class _LoginPageState extends State { ), SizedBox(height: 175.w,), InkWell( - onTap: (){ + onTap: () async { + context.goNamed(RouteNames.completeInfo); + return; + if(phone == ""){ + toast("请输入手机号", context); + return; + } + if(code == ""){ + toast("请输入6位数字验证码", context); + return; + } + if(!checked) { + toast("请阅读并同意用户协议", context); + return; + } + var res = await Api().$login({ + "account":phone, + "accountType":2, + "captcha":code + }); + if(res["code"] == 200){ + // toast("登录成功", context); + // await Storage().removeStorage("token"); + // await Storage().setStorage("token", res["data"]["token"]); + } else { + toast(res["msg"], context); + } + context.goNamed(RouteNames.completeInfo); }, child: Container( @@ -295,7 +356,15 @@ class _LoginPageState extends State { height: 105.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(105.w)), - color: const Color.fromRGBO(217, 217, 217, 1) + color: const Color.fromRGBO(217, 217, 217, 1), + gradient: phone != "" && code != "" ? LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + Color.fromRGBO(131, 89, 255, 1), // 起始颜色 + Color.fromRGBO(61, 138, 224, 1), // 结束颜色 + ], + ) : null, ), child: Center( child: Text( diff --git a/lib/pages/my_page.dart b/lib/pages/my_page.dart index 8ffae4a..2fa0866 100644 --- a/lib/pages/my_page.dart +++ b/lib/pages/my_page.dart @@ -1,5 +1,7 @@ +import 'package:dating_touchme_app/router/route_paths.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:go_router/go_router.dart'; class MyPage extends StatefulWidget { const MyPage({super.key}); @@ -102,23 +104,28 @@ class _MyPageState extends State { ) ], ), - Row( - children: [ - Image.asset( - "assets/edit.png", - width: 20.w, - height: 20.w, - ), - SizedBox(width: 8.w,), - Text( - "编辑资料", - style: TextStyle( - fontSize: 24.w, - color: const Color.fromRGBO(55, 57, 72, 1), - fontWeight: FontWeight.w500 + InkWell( + onTap: (){ + context.pushNamed(RouteNames.editInfo); + }, + child: Row( + children: [ + Image.asset( + "assets/edit.png", + width: 20.w, + height: 20.w, ), - ) - ], + SizedBox(width: 8.w,), + Text( + "编辑资料", + style: TextStyle( + fontSize: 24.w, + color: const Color.fromRGBO(55, 57, 72, 1), + fontWeight: FontWeight.w500 + ), + ) + ], + ), ) ], ), diff --git a/lib/pages/signature_page.dart b/lib/pages/signature_page.dart new file mode 100644 index 0000000..2ccf5f1 --- /dev/null +++ b/lib/pages/signature_page.dart @@ -0,0 +1,70 @@ +import 'package:dating_touchme_app/components/page_appbar.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class SignaturePage extends StatefulWidget { + const SignaturePage({super.key}); + + @override + State createState() => _SignaturePageState(); +} + +class _SignaturePageState extends State { + + + String message = '拒绝内耗,向阳而生,用热爱抵御岁月漫长,用真诚对待每一次相遇拒绝内耗,向阳而生,用热爱抵御岁月漫长,用真诚对待每一次相遇'; + final TextEditingController _messageController = TextEditingController(); + + @override + void initState() { + super.initState(); + + _messageController.value = TextEditingValue( + text: message, + selection: TextSelection.fromPosition(TextPosition(offset: message.length)), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PageAppbar(title: "交友心声",), + body: Container( + padding: EdgeInsets.all(35.w), + child: TextField( + controller: _messageController, + maxLength: 50, // 上限 + minLines: 5, // 多行 + maxLines: 5, // 自适应高度 + style: TextStyle( + fontSize: ScreenUtil().setWidth(26), + height: 1 + ), + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric( + vertical: 0, + horizontal: 0 + ), + hintText: "请输入邀请码", + + border: const OutlineInputBorder( + borderSide: BorderSide.none, // 这将移除边框 // 可选:设置圆角 + ), + // 如果你希望聚焦时和未聚焦时都没有边框,也可以设置 focusedBorder 和 enabledBorder + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.all(Radius.circular(8.0)), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.all(Radius.circular(8.0)), + ), + ), + onChanged: (value){ + message = value; + }, + ), + ), + ); + } +} diff --git a/lib/router/app_router.dart b/lib/router/app_router.dart index d8d05f1..1435a08 100644 --- a/lib/router/app_router.dart +++ b/lib/router/app_router.dart @@ -1,10 +1,12 @@ import 'package:dating_touchme_app/pages/complete_info.dart'; +import 'package:dating_touchme_app/pages/edit_info_page.dart'; import 'package:dating_touchme_app/pages/home_page.dart'; import 'package:dating_touchme_app/pages/live_room_page.dart'; import 'package:dating_touchme_app/pages/login_page.dart'; import 'package:dating_touchme_app/pages/message_page.dart'; import 'package:dating_touchme_app/pages/notify_page.dart'; import 'package:dating_touchme_app/pages/open_webview.dart'; +import 'package:dating_touchme_app/pages/signature_page.dart'; import 'package:dating_touchme_app/pages/test_page.dart'; import 'package:dating_touchme_app/pages/user_info_page.dart'; import 'package:dating_touchme_app/router/route_paths.dart'; @@ -82,6 +84,16 @@ class AppRouter { return MessagePage(id: id,); }, ), + GoRoute( + name: RouteNames.editInfo, + path: RoutePaths.editInfo, + builder: (context, state) => const EditInfoPage(), + ), + GoRoute( + name: RouteNames.signature, + path: RoutePaths.signature, + builder: (context, state) => const SignaturePage(), + ), GoRoute( name: RouteNames.test, path: RoutePaths.test, diff --git a/lib/router/route_paths.dart b/lib/router/route_paths.dart index dc6a53a..437f628 100644 --- a/lib/router/route_paths.dart +++ b/lib/router/route_paths.dart @@ -8,6 +8,8 @@ class RouteNames { static const liveRoom = 'liveRoom'; static const notify = 'notify'; static const message = 'message'; + static const editInfo = 'editInfo'; + static const signature = 'signature'; static const test = 'test'; } @@ -20,5 +22,7 @@ class RoutePaths { static const liveRoom = '/liveRoom'; static const notify = '/notify'; static const message = '/message'; + static const editInfo = '/editInfo'; + static const signature = '/signature'; static const test = '/test'; }