From 1071e600611a2325df98ff610f82602be691f9dd Mon Sep 17 00:00:00 2001 From: datang Date: Sun, 21 Aug 2022 23:42:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BD=91=E7=BB=9C=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .fvm/flutter_sdk | 1 - lib/constants/api.dart | 26 +++- lib/model/user_info_model.dart | 57 +++++--- lib/model/user_info_model.g.dart | 34 +++-- lib/ui/home/add_sms_page.dart | 106 +++++++++++++++ lib/ui/home/content_connect_page.dart | 158 +++++++++++++++++++++++ lib/ui/home/content_details_page.dart | 114 ---------------- lib/ui/home/content_page.dart | 117 ----------------- lib/ui/home/content_refuse_page.dart | 150 +++++++++++++++++++++ lib/ui/home/home_page.dart | 91 ++++++------- lib/ui/login/login_page.dart | 2 +- lib/ui/user/content_authority_page.dart | 78 +++++++++++ lib/ui/user/content_details_page.dart | 111 ++++++++++++++++ lib/ui/user/privacy_rights_page.dart | 2 +- lib/ui/user/user_page.dart | 113 +++++++++++----- lib/ui/widget/centertipsalterwidget.dart | 24 +++- pubspec.lock | 7 + pubspec.yaml | 2 + 18 files changed, 841 insertions(+), 352 deletions(-) delete mode 120000 .fvm/flutter_sdk create mode 100644 lib/ui/home/add_sms_page.dart create mode 100644 lib/ui/home/content_connect_page.dart delete mode 100644 lib/ui/home/content_details_page.dart create mode 100644 lib/ui/home/content_refuse_page.dart create mode 100644 lib/ui/user/content_authority_page.dart create mode 100644 lib/ui/user/content_details_page.dart diff --git a/.fvm/flutter_sdk b/.fvm/flutter_sdk deleted file mode 120000 index 7f90269..0000000 --- a/.fvm/flutter_sdk +++ /dev/null @@ -1 +0,0 @@ -/Users/datang/fvm/versions/2.8.0 \ No newline at end of file diff --git a/lib/constants/api.dart b/lib/constants/api.dart index ec7c29a..8437552 100644 --- a/lib/constants/api.dart +++ b/lib/constants/api.dart @@ -6,12 +6,20 @@ class API { ///HOST static String get host { if (DevEV.instance.dev) { + // return 'http://10.0.2.2:8088/'; return 'http://api.dxbs.vip'; } else { - return 'https://api.yunyunwenche.com'; + return 'http://api.dxbs.vip/'; } } + static String get imageHost { + if (DevEV.instance.dev) { + return 'http://10.0.2.2:8088'; + } else { + return 'http://api.dxbs.vip/'; + } + } static const int networkTimeOut = 10000; @@ -21,15 +29,31 @@ class API { static _Pay pay = _Pay(); } class _App { + ///用户登录 String get login => '/app/login'; + ///退出登录 String get logout => '/app/login/logout'; + ///发送验证码 String get captcha => '/app/captcha'; + ///用户信息 String get info => '/app/user/info'; + ///短信标签 + String get addTag => '/app/user/addTag'; + ///自定义短信 + String get content => '/app/user/content'; + ///删除自定义短信 + String get delete => '/app/user/content/delete'; + ///更新VIP状态(已合并至用户信息) + String get updateVip => '/app/user/updateVip'; } class _Pay { + ///微信支付 String get wxpay => '/app/pay/wxpay'; + ///支付宝支付 String get alipay => '/app/pay/alipay'; + ///微信支付回调 String get wxCallback => '/callback/wxpay/notify'; + ///支付宝支付回调 String get aliCallback => '/callback/alipay/notify'; } \ No newline at end of file diff --git a/lib/model/user_info_model.dart b/lib/model/user_info_model.dart index 99cbd71..07fdb89 100644 --- a/lib/model/user_info_model.dart +++ b/lib/model/user_info_model.dart @@ -1,5 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:equatable/equatable.dart'; +import 'package:project_telephony/ui/user/content_details_page.dart'; part 'user_info_model.g.dart'; @@ -8,8 +9,13 @@ class UserInfoModel extends Equatable { final int id; final String name; final String phone; + final int isVip; + final String tag; final int status; - final Vip vip; + final num start; + final num end; + final List? contentRef; + final List? contentCon; factory UserInfoModel.fromJson(Map json) => _$UserInfoModelFromJson(json); @@ -20,36 +26,47 @@ class UserInfoModel extends Equatable { id: 0, name: '', phone: '', + isVip: 0, + tag: '', status: 0, - vip: Vip(start: '', end: ''), + start: 0, + end: 0, + contentCon: [], + contentRef: [], ); + const UserInfoModel( + {required this.id, + required this.name, + required this.phone, + required this.isVip, + required this.tag, + required this.status, + required this.start, + required this.end, + required this.contentCon, + required this.contentRef, + }); @override - List get props => [id, name, phone, status, vip]; - - const UserInfoModel({ - required this.id, - required this.name, - required this.phone, - required this.status, - required this.vip, - }); + List get props => + [id, name, phone, isVip, tag, status, start, end, contentCon,contentRef]; } @JsonSerializable() -class Vip extends Equatable { - final String start; - final String end; +class Content extends Equatable { + final int id; + final String content; - const Vip({ - required this.start, - required this.end, + const Content({ + required this.id, + required this.content, }); - factory Vip.fromJson(Map json) => _$VipFromJson(json); + factory Content.fromJson(Map json) => + _$ContentFromJson(json); - Map toJson() => _$VipToJson(this); + Map toJson() => _$ContentToJson(this); @override - List get props => [start, end]; + List get props => [id, content]; } diff --git a/lib/model/user_info_model.g.dart b/lib/model/user_info_model.g.dart index a2431ec..6761b97 100644 --- a/lib/model/user_info_model.g.dart +++ b/lib/model/user_info_model.g.dart @@ -11,8 +11,17 @@ UserInfoModel _$UserInfoModelFromJson(Map json) => id: json['id'] as int, name: json['name'] as String, phone: json['phone'] as String, + isVip: json['is_vip'] as int, + tag: json['tag']as String, status: json['status'] as int, - vip: Vip.fromJson(json['vip'] as Map), + start: json['start']as num, + end: json['end']as num, + contentCon:(json['content_con'] as List?) + ?.map((e) => Content.fromJson(e as Map)) + .toList(), + contentRef:(json['content_ref'] as List?) + ?.map((e) => Content.fromJson(e as Map)) + .toList(), ); Map _$UserInfoModelToJson(UserInfoModel instance) => @@ -20,16 +29,21 @@ Map _$UserInfoModelToJson(UserInfoModel instance) => 'id': instance.id, 'name': instance.name, 'phone': instance.phone, + 'is_vip':instance.isVip, + 'tag':instance.tag, 'status': instance.status, - 'vip': instance.vip, + 'start':instance.start, + 'end':instance.end, + 'content_con':instance.contentCon, + 'content_ref':instance.contentRef, }; -Vip _$VipFromJson(Map json) => Vip( - start: json['start'] as String, - end: json['end'] as String, - ); +Content _$ContentFromJson(Map json) => Content( + id: json['id'] as int, + content: json['content'] as String, +); -Map _$VipToJson(Vip instance) => { - 'start': instance.start, - 'end': instance.end, - }; +Map _$ContentToJson(Content instance) => { + 'id': instance.id, + 'content': instance.content, +}; \ No newline at end of file diff --git a/lib/ui/home/add_sms_page.dart b/lib/ui/home/add_sms_page.dart new file mode 100644 index 0000000..672e1fe --- /dev/null +++ b/lib/ui/home/add_sms_page.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:provider/provider.dart'; + +import '../../base/base_style.dart'; +import '../../constants/api.dart'; +import '../../model/network/api_client.dart'; +import '../../model/network/base_model.dart'; +import '../../providers/user_provider.dart'; +import '../../utils/toast/cloud_toast.dart'; +import '../user/content_details_page.dart'; +import '../widget/plone_back_button.dart'; +import '../widget/plone_bottom.dart'; + +class AddSmsPage extends StatefulWidget { + final int status; + final TextCallback ploneBack; + const AddSmsPage({Key? key, required this.status, required this.ploneBack}) : super(key: key); + + @override + _AddSmsPageState createState() => _AddSmsPageState(); +} + +class _AddSmsPageState extends State { + late TextEditingController _controller; + final userProvider = Provider.of(Get.context!, listen: false); + + @override + void initState() { + super.initState(); + _controller = TextEditingController(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + elevation: 0, + title: Text( + '编辑短信标签', + style: TextStyle( + fontSize: BaseStyle.fontSize34, + color: BaseStyle.color333333, + fontWeight: FontWeight.bold), + ), + titleSpacing: 162.w, + leading: const CloudBackButton(isSpecial: true), + backgroundColor: kForeGroundColor), + backgroundColor: Colors.white, + body: Align( + alignment: Alignment.topCenter, + child: Container( + height: 800.w, + decoration: BoxDecoration( + color: const Color(0xFFF9F9F9), + borderRadius: BorderRadius.circular(16.w), + ), + padding: EdgeInsets.all(30.w), + margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 50.w), + child: TextField( + maxLines: 100, + keyboardType: TextInputType.text, + onEditingComplete: () { + setState(() {}); + // _refreshController.callRefresh(); + }, + style: TextStyle( + color: BaseStyle.color333333, + fontSize: BaseStyle.fontSize28, + ), + controller: _controller, + decoration: const InputDecoration( + fillColor: Colors.transparent, + contentPadding: EdgeInsets.zero, + filled: true, + isDense: true, + hintText: "请输入所需短信标签", + border: InputBorder.none, + ), + ), + ), + ), + bottomNavigationBar: PloneBottom( + border: _controller.text.isEmpty, + opacity: _controller.text.isNotEmpty ? 1 : 0.4, + onTap: () async { + BaseModel res = await apiClient.request(API.app.content, data: { + 'content': _controller.text, + 'status': widget.status, + }); + if (res.code == 0) { + setState(() {}); + widget.ploneBack(_controller.text); + userProvider.updateUserInfo(); + } else { + CloudToast.show(res.msg); + } + Get.back(); + }, + text: "保存", + ).paddingOnly(bottom: 30.w), + ); + } +} diff --git a/lib/ui/home/content_connect_page.dart b/lib/ui/home/content_connect_page.dart new file mode 100644 index 0000000..11d843b --- /dev/null +++ b/lib/ui/home/content_connect_page.dart @@ -0,0 +1,158 @@ +import 'package:bot_toast/bot_toast.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:project_telephony/base/base_style.dart'; +import 'package:project_telephony/ui/home/add_sms_page.dart'; +import 'package:project_telephony/ui/widget/centertipsalterwidget.dart'; +import 'package:project_telephony/ui/widget/plone_back_button.dart'; +import 'package:project_telephony/utils/headers.dart'; +import 'package:provider/provider.dart'; +import '../../providers/user_provider.dart'; + +class ContentConnectPage extends StatefulWidget { + const ContentConnectPage({Key? key}) : super(key: key); + + @override + _ContentConnectPageState createState() => _ContentConnectPageState(); +} + +class _ContentConnectPageState extends State { + int _select = 0; + List textList = [ + '欢迎您的来电,祝您生活愉快', + '祝您万事顺心', + '感谢您的来电,我们会尽快处理的', + "自定义短信内容" + ]; + List smsIdList =[]; + List textListSMS = []; + + final userProvider = Provider.of(Get.context!, listen: false); + final EasyRefreshController _easyRefreshController = EasyRefreshController(); + + + @override + void initState() { + super.initState(); + updateList(); + } + + @override + void dispose() { + _easyRefreshController.dispose(); + super.dispose(); + } + + updateList(){ + if (userProvider.isLogin) { + textListSMS.clear(); + smsIdList.clear(); + userProvider.userInfo.contentCon?.forEach((model) { + textListSMS.add(model.content); + smsIdList.add(model.id); + }); + textListSMS.add("自定义短信内容"); + } else { + textListSMS = textList; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + elevation: 0, + title: Text( + '选择短信内容', + style: Theme.of(context).textTheme.headline6, + ), + leading: const CloudBackButton(isSpecial: true), + backgroundColor: kForeGroundColor, + ), + backgroundColor: Colors.white, + body: Column(children: [ + Expanded( + child: _getList(), + ), + ]), + ); + } + + _getList() { + return EasyRefresh( + firstRefresh: true, + header: MaterialHeader(), + footer: MaterialFooter(), + controller: _easyRefreshController, + onRefresh: () async { + await userProvider.updateUserInfo(); + updateList(); + setState(() {}); + }, + child:ListView.builder( + itemBuilder: (context, index) { + return _getBox(textListSMS[index], index == _select, index); + }, + itemCount: textListSMS.length, + ), + ); + } + + _getBox(String content, bool pd, int index) { + return GestureDetector( + onTap: () async { + if (content != "自定义短信内容") { + _select = index; + } else { + if(userProvider.isLogin){ + if(textListSMS.length>5){ + BotToast.showText(text: '自定义数量已达上限,请先删除不需要的短信'); + }else{ + Get.to(AddSmsPage( + status: 1, ploneBack: (String textContent) { + _easyRefreshController.callRefresh(); + }, + )); + } + }else{ + BotToast.showText(text: '请先登录'); + } + } + setState(() {}); + }, + onLongPress: () { + if(content != "自定义短信内容"){ + if (textListSMS.length<2 ) { + BotToast.showText(text: '不能再删了'); + }else{ + showDialog( + context: context, + builder: (context) { + return Centertipsalterwidget( + desText: '你确定要删除这个短信模版吗,删除之后无法还原。', + title: '删除短信模板', id: smsIdList[index], + ); + }); + } + } + setState(() {}); + }, + child: Container( + // width: 686.w, + margin: EdgeInsets.only(top: 32.w, left: 64.w, right: 64.w), + padding: EdgeInsets.all(40.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: pd ? Colors.blue : const Color(0xFFF9F9F9), + ), + child: Text( + content, + style: TextStyle( + fontSize: BaseStyle.fontSize28, + color: pd ? const Color(0xFFF9F9F9) : BaseStyle.color333333, + fontWeight: FontWeight.bold), + ), + ), + ); + } +} diff --git a/lib/ui/home/content_details_page.dart b/lib/ui/home/content_details_page.dart deleted file mode 100644 index 1c8553b..0000000 --- a/lib/ui/home/content_details_page.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:project_telephony/utils/headers.dart'; - -import '../../base/base_style.dart'; -import '../widget/plone_back_button.dart'; -import '../widget/plone_bottom.dart'; - -typedef TextCallback = Function(String textContent); - -class ContentDetailsPage extends StatefulWidget { - final TextCallback ploneBack; - final String content; - const ContentDetailsPage( - {Key? key, required this.content, required this.ploneBack}) - : super(key: key); - - @override - _ContentDetailsPageState createState() => _ContentDetailsPageState(); -} - -String content = ""; - -class _ContentDetailsPageState extends State { - late TextEditingController _controller; - - @override - void initState() { - super.initState(); - _controller = TextEditingController(text: widget.content); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar( - elevation: 0, - title: Text( - '编辑短信内容', - style: TextStyle( - fontSize: BaseStyle.fontSize34, - color: BaseStyle.color333333, - fontWeight: FontWeight.bold), - ), - titleSpacing: 162.w, - leading: const CloudBackButton(isSpecial: true), - backgroundColor: kForeGroundColor), - backgroundColor: Colors.white, - body: _getBox(), - ); - } - - _getBox() { - return Column(children: [ - Container( - width: 622.w, - height: 960.w, - decoration: BoxDecoration( - color: const Color(0xFFF9F9F9), - borderRadius: BorderRadius.circular(16.w)), - margin: EdgeInsets.only(top: 32.w, bottom: 298.w), - child: Container( - // color: kForeGroundColor, - margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 50.w), - child: TextField( - maxLines: 100, - keyboardType: TextInputType.text, - onEditingComplete: () { - setState(() {}); - // _refreshController.callRefresh(); - }, - onChanged: (text) { - content = text; - // print(content); - setState(() {}); - }, - style: TextStyle( - color: BaseStyle.color333333, - fontSize: BaseStyle.fontSize28, - ), - controller: _controller, - decoration: InputDecoration( - contentPadding: EdgeInsets.zero, - filled: true, - isDense: true, - fillColor: Colors.white, - hintText: widget.content != "" ? "" : "请输入短信内容", - hintStyle: TextStyle( - color: widget.content != "" - ? const Color(0xFF333333) - : Colors.grey.shade500, - fontSize: 28.sp, - fontWeight: FontWeight.bold), - border: InputBorder.none, - ), - ), - ), - - // Text(widget.content,), - ), - PloneBottom( - border: !content.isNotEmpty, - opacity: content.isNotEmpty ? 1 : 0.4, - onTap: () { - setState(() {}); - widget.ploneBack(content); - Get.back(); - // print(content); - }, - text: "保存", - ) - ]); - } -} diff --git a/lib/ui/home/content_page.dart b/lib/ui/home/content_page.dart index 2ff0801..e69de29 100644 --- a/lib/ui/home/content_page.dart +++ b/lib/ui/home/content_page.dart @@ -1,117 +0,0 @@ - -import 'package:call_log/call_log.dart'; -import 'package:flutter/material.dart'; - - -import 'package:project_telephony/base/base_style.dart'; -import 'package:project_telephony/ui/home/content_details_page.dart'; -import 'package:project_telephony/ui/widget/centertipsalterwidget.dart'; - -import 'package:project_telephony/ui/widget/plone_back_button.dart'; -import 'package:project_telephony/utils/headers.dart'; - - -class ContentPage extends StatefulWidget { - final bool? isAnswer; //true接听false未接听 - const ContentPage({Key? key, required this.isAnswer}) : super(key: key); - - @override - _ContentPageState createState() => _ContentPageState(); -} - - - -class _ContentPageState extends State { - int _select = 0; - List textList = ['欢迎你的来电', '祝您生活愉快', '感谢您的来电我们会尽快处理的', '自定义短信内容']; - List textList1 = ['自定义短信内容']; - late String phoneNum; - late String callState; - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - elevation: 0, - title: Text( - '选择短信内容', - style: Theme.of(context).textTheme.headline6, - ), - leading: const CloudBackButton(isSpecial: true), - backgroundColor: kForeGroundColor, - ), - backgroundColor: Colors.white, - body: Column(children: [ - Expanded( - child: _getList(), - ), - ]), - ); - } - - _getList() { - return ListView.builder( - itemBuilder: (context, index) { - return _getBox(textList[index], index == _select, index); - }, - itemCount: textList.length, - ); - } - - _getBox(String content, bool pd, int index) { - return GestureDetector( - onTap: () async { - _select = index; - if (index == textList.length - 1) { - await Get.to(() => ContentDetailsPage( - content: "", - ploneBack: (String textContent) { - // print("这是数据" + textContent); - textList.setAll(index, {textContent}); - }, - )); - } else { - final Iterable result = await CallLog.query(); - phoneNum = result.first.number!; - } - setState(() {}); - // print("这是数据" + textList[_s lect]); - - // print(index); - }, - onLongPress: () { - if (index != textList.length - 1) { - showDialog( - context: context, - builder: (context) { - return const Centertipsalterwidget( - desText: '你确定要删除这个短信模版吗,删除之后无法还原。', - title: '删除短信模板', - ); - }); - } - setState(() {}); - }, - child: Container( - // width: 686.w, - height: 135.w, - margin: EdgeInsets.only(top: 32.w, left: 64.w, right: 64.w), - padding: EdgeInsets.only(left: 40.w, top: 50.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - color: pd - ? widget.isAnswer! - ? Colors.blue - : const Color(0xFF72E4C8) - : const Color(0xFFF9F9F9), - ), - child: Text( - content, - style: TextStyle( - fontSize: BaseStyle.fontSize28, - color: pd ? const Color(0xFFF9F9F9) : BaseStyle.color333333, - fontWeight: FontWeight.bold), - ), - ), - ); - } -} diff --git a/lib/ui/home/content_refuse_page.dart b/lib/ui/home/content_refuse_page.dart new file mode 100644 index 0000000..b09dae0 --- /dev/null +++ b/lib/ui/home/content_refuse_page.dart @@ -0,0 +1,150 @@ +import 'dart:async'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:project_telephony/base/base_style.dart'; +import 'package:project_telephony/ui/widget/centertipsalterwidget.dart'; +import 'package:project_telephony/ui/widget/plone_back_button.dart'; +import 'package:project_telephony/utils/headers.dart'; +import 'package:provider/provider.dart'; +import '../../providers/user_provider.dart'; +import 'add_sms_page.dart'; + +class ContentRefusePage extends StatefulWidget { + const ContentRefusePage({Key? key}) : super(key: key); + + @override + _ContentRefusePageState createState() => _ContentRefusePageState(); +} + +class _ContentRefusePageState extends State { + int _select = 0; + List textList = ['现在无法接听。有什么事吗?', '我马上会打给你。', '我稍后会打给你。', "自定义短信内容"]; + List textListSMS = []; + List smsIdList =[]; + + final userProvider = Provider.of(Get.context!, listen: false); + final EasyRefreshController _easyRefreshController = EasyRefreshController(); + + @override + void initState() { + super.initState(); + updateList(); + } + + @override + void dispose() { + _easyRefreshController.dispose(); + super.dispose(); + } + + Future updateList() async{ + if (userProvider.isLogin) { + textListSMS.clear(); + userProvider.userInfo.contentRef?.forEach((model) { + textListSMS.add(model.content); + smsIdList.add(model.id); + }); + textListSMS.add("自定义短信内容"); + } else { + textListSMS = textList; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + elevation: 0, + title: Text( + '选择短信内容', + style: Theme.of(context).textTheme.headline6, + ), + leading: const CloudBackButton(isSpecial: true), + backgroundColor: kForeGroundColor, + ), + backgroundColor: Colors.white, + body: Column(children: [ + Expanded( + child: _getList(), + ), + ]), + ); + } + + _getList() { + return EasyRefresh( + firstRefresh: true, + header: MaterialHeader(), + footer: MaterialFooter(), + controller: _easyRefreshController, + onRefresh: () async { + await updateList(); + }, + child:ListView.builder( + itemBuilder: (context, index) { + return _getBox(textListSMS[index], index == _select, index); + }, + itemCount: textListSMS.length, + ), + ); + } + + _getBox(String content, bool pd, int index) { + return GestureDetector( + onTap: () async { + if (content != "自定义短信内容") { + _select = index; + } else { + if(userProvider.isLogin){ + if(textListSMS.length>5){ + BotToast.showText(text: '自定义数量已达上限,请先删除不需要的短信'); + }else{ + Get.to(AddSmsPage( + status: 2, ploneBack: (String textContent) { }, + )); + } + }else{ + BotToast.showText(text: '请先登录'); + } + } + setState(() {}); + }, + onLongPress: () { + if(content != "自定义短信内容"){ + if (textListSMS.length<2 ) { + BotToast.showText(text: '不能再删了'); + }else{ + showDialog( + context: context, + builder: (context) { + return Centertipsalterwidget( + desText: '你确定要删除这个短信模版吗,删除之后无法还原。', + title: '删除短信模板', id: smsIdList[index], + ); + }); + } + } + setState(() { + _easyRefreshController.callRefresh(); + }); + }, + child: Container( + // width: 686.w, + margin: EdgeInsets.only(top: 32.w, left: 64.w, right: 64.w), + padding: EdgeInsets.all(40.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: pd ? const Color(0xFF72E4C8) : const Color(0xFFF9F9F9), + ), + child: Text( + content, + style: TextStyle( + fontSize: BaseStyle.fontSize28, + color: pd ? const Color(0xFFF9F9F9) : BaseStyle.color333333, + fontWeight: FontWeight.bold), + ), + ), + ); + } +} diff --git a/lib/ui/home/home_page.dart b/lib/ui/home/home_page.dart index a465df9..9cff0dc 100644 --- a/lib/ui/home/home_page.dart +++ b/lib/ui/home/home_page.dart @@ -1,11 +1,10 @@ import 'dart:async'; - import 'package:flutter/material.dart'; -import 'package:project_telephony/ui/home/content_page.dart'; +import 'package:project_telephony/ui/home/content_connect_page.dart'; +import 'package:project_telephony/ui/home/content_refuse_page.dart'; import 'package:project_telephony/utils/headers.dart'; - import 'call.dart'; class HomePage extends StatefulWidget { @@ -15,11 +14,9 @@ class HomePage extends StatefulWidget { _HomePageState createState() => _HomePageState(); } - class _HomePageState extends State { @override void initState() { - // TODO: implement initState super.initState(); // initializeService(); setState(() {}); @@ -32,15 +29,18 @@ class _HomePageState extends State { extendBodyBehindAppBar: true, extendBody: true, body: SafeArea( - child: Column( + child: Stack( + fit: StackFit.expand, children: [ - Container( - child: Image.asset( - Assets.images.homeBg.path, - height: 722.w, - width: 722.w, - )), - _getBody(), + Positioned( + top: 10.w, + child: Image.asset( + Assets.images.homeBg.path, + height: 722.w, + width: 722.w, + ), + ), + Positioned(bottom: 20.w, child: _getBody()), ], ), )); @@ -59,7 +59,7 @@ class _HomePageState extends State { color: const Color(0xFF333333), fontWeight: FontWeight.bold), ), - 32.hb, + 8.hb, Text( "希望能成为您的短信小助手", style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)), @@ -80,13 +80,9 @@ class _HomePageState extends State { onTap: () { print(title); if (title == "接听后") { - Get.to(() => const ContentPage( - isAnswer: true, - )); + Get.to(() => const ContentConnectPage()); } else { - Get.to(() => const ContentPage( - isAnswer: false, - )); + Get.to(() => const ContentRefusePage()); print("未接听"); } }, @@ -105,37 +101,32 @@ class _HomePageState extends State { ), ), Positioned( - child: Row( - children: [ - Container( - padding: EdgeInsets.only( - left: 48.w, - top: 35.w, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, - style: TextStyle( - fontSize: 36.sp, - color: const Color(0xFFFFFFFF), - fontWeight: FontWeight.bold)), - 24.hb, - Text( - text, - style: TextStyle( - fontSize: 27.sp, - color: const Color(0xFFFFFFFF).withOpacity(0.6)), - ), - ], + // top: 0, + // left: 0, + child: Container( + // height: 192.w, + // alignment: Alignment.centerLeft, + padding: EdgeInsets.only( + left: 48.w, + top: 38.w, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle( + fontSize: 36.sp, + color: const Color(0xFFFFFFFF), + fontWeight: FontWeight.bold)), + 16.hb, + Text( + text, + style: TextStyle( + fontSize: 27.sp, + color: const Color(0xFFFFFFFF).withOpacity(0.6)), ), - ), - // Padding( - // padding: EdgeInsets.only(top: 40.w), - // child: - - // ) - ], + ], + ), ), ), Positioned( diff --git a/lib/ui/login/login_page.dart b/lib/ui/login/login_page.dart index 1028d92..aad13c0 100644 --- a/lib/ui/login/login_page.dart +++ b/lib/ui/login/login_page.dart @@ -86,7 +86,7 @@ class _LoginPageState extends State { Padding( padding: EdgeInsets.only(left: 186.w, top: 88.w), child: Text( - "登录/注册", + "", style: TextStyle( fontSize: BaseStyle.fontSize34, color: BaseStyle.color333333, diff --git a/lib/ui/user/content_authority_page.dart b/lib/ui/user/content_authority_page.dart new file mode 100644 index 0000000..dfffd79 --- /dev/null +++ b/lib/ui/user/content_authority_page.dart @@ -0,0 +1,78 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import '../../base/base_style.dart'; +import '../widget/plone_back_button.dart'; + +class ContentAuthorityPage extends StatelessWidget { + const ContentAuthorityPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + elevation: 0, + title: Text( + '隐私权限', + style: TextStyle( + fontSize: BaseStyle.fontSize34, + color: BaseStyle.color333333, + fontWeight: FontWeight.bold), + ), + titleSpacing: 162.w, + leading: const CloudBackButton(isSpecial: true), + backgroundColor: kForeGroundColor), + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: EdgeInsets.all(16.sp), + child: RichText( + text: const TextSpan( + style: TextStyle( + fontSize: 16, //设置大小 + color: Colors.black, //设置颜色 + ), + children: [ + TextSpan( + text: '短信帮手隐私政策\n', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + )), + TextSpan( + text: ''' + +本应用尊重并保护所有使用服务用户的个人隐私权。本应用将以高度的勤勉、审慎义务对待这些信息。 除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。 +1. 适用范围 (a) 在您使用本应用网络服务,或访问本应用平台网页时,本应用自动接收并记录的您的浏览器和计算机上的信息, 包括但不限于您的IP地址、浏览器的类型、使用的语言、访问日期和时间、软硬件特征信息及您需求的网页记录等数据; 您了解并同意,以下信息不适用本隐私权政策: (a) 本应用收集到的您在本应用发布的有关信息数据,包括但不限于参与活动、成交信息及评价详情; (b) 违反法律规定或违反本应用规则行为及本应用已对您采取的措施。 +2. 信息使用 (a)本应用不会向任何无关第三方提供、出售、出租、分享或交易您的个人信息,除非事先得到您的许可, 或该第三方和本应用(含本应用关联公司)单独或共同为您提供服务,且在该服务结束后,其将被禁止访问包括其以前能够访问的所有这些资料。 (b) 本应用亦不允许任何第三方以任何手段收集、编辑、出售或者无偿传播您的个人信息。 任何本应用平台用户如从事上述活动,一经发现,本应用有权立即终止与该用户的服务协议。 +3. 信息披露 在如下情况下,本应用将依据您的个人意愿或法律的规定全部或部分的披露您的个人信息: (a) 经您事先同意,向第三方披露; (b)为提供您所要求的产品和服务,而必须和第三方分享您的个人信息; (c) 根据法律的有关规定,或者行政或司法机构的要求,向第三方或者行政、司法机构披露; (d) 如您出现违反中国有关法律、法规或者本应用服务协议或相关规则的情况,需要向第三方披露; (e) 如您是适格的知识产权投诉人并已提起投诉,应被投诉人要求,向被投诉人披露,以便双方处理可能的权利纠纷; (f) 在本应用平台上创建的某一交易中,如交易任何一方履行或部分履行了交易义务并提出信息披露请求的,本应用有权决定向该用户提供其交易对方的联络方式等必要信息,以促成交易的完成或纠纷的解决。 (g) 其它本应用根据法律、法规或者网站政策认为合适的披露。 +4. 信息存储和交换 本应用收集的有关您的信息和资料将保存在本应用及(或)其关联公司的服务器上,这些信息和资料可能传送至您所在国家、地区或本应用收集信息和资料所在地的境外并在境外被访问、存储和展示。 +5. Cookie的使用 (a) 在您未拒绝接受cookies的情况下,本应用会在您的计算机上设定或取用cookies ,以便您能登录或使用依赖于cookies的本应用平台服务或功能。 (b) 您有权选择接受或拒绝接受cookies。您可以通过修改浏览器设置的方式拒绝接受cookies。但如果您选择拒绝接受cookies,则您可能无法登录或使用依赖于cookies的本应用网络服务或功能。 (c) 通过本应用所设cookies所取得的有关信息,将适用本政策。 +6. 信息安全 (a) 本应用帐号均有安全保护功能,请妥善保管您的用户名及密码信息。本应用将通过对用户密码进行加密等安全措施确保您的信息不丢失,不被滥用和变造。尽管有前述安全措施, 但同时也请您注意在信息网络上不存在“完善的安全措施”。 (b) 在使用本应用网络服务进行网上交易时,您不可避免的要向交易对方或潜在的交易对 +7.本隐私政策的更改 (a)如果决定更改隐私政策,我们会在本政策中、本公司网站中以及我们认为适当的位置发布这些更改,以便您了解我们如何收集、使用您的个人信息,哪些人可以访问这些信息,以及在什么情况下我们会透露这些信息。 (b)本公司保留随时修改本政策的权利,因此请经常查看。如对本政策作出重大更改,本公司会通过网站通知的形式告知。 请您妥善保护自己的个人信息,仅在必要的情形下向他人提供。如您发现自己的个人信息泄密,尤其是本应用用户名及密码发生泄露,请您立即联络本应用客服,以便本应用采取相应措施。 + +此app旨在根据您定义的短信模版来自动回复未接/已接来电。这个app需要权限来发送短信它不会在服务器上存储您的短信/联系人,当您家删除此app时,所有数据都会被删除。 + +为了自动回复短信,请允许此app具有以下所需权限 +''', + ), + TextSpan(text: ''' +1.短信的发送 +自动回复短信到来电手机 +2.手机电话号码、状态信息 +用于获取手机卡信息,然后发送短信 +3.通话记录 +用于自动回复未接/已接来电信息\n + +''', style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan( + text: '短信帮手\n宁波沃尔斯软件有限公司', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/user/content_details_page.dart b/lib/ui/user/content_details_page.dart new file mode 100644 index 0000000..ab0f532 --- /dev/null +++ b/lib/ui/user/content_details_page.dart @@ -0,0 +1,111 @@ +import 'package:flutter/material.dart'; +import 'package:project_telephony/utils/headers.dart'; +import 'package:provider/provider.dart'; + +import '../../base/base_style.dart'; +import '../../constants/api.dart'; +import '../../model/network/api_client.dart'; +import '../../model/network/base_model.dart'; +import '../../providers/user_provider.dart'; +import '../../utils/toast/cloud_toast.dart'; +import '../widget/plone_back_button.dart'; +import '../widget/plone_bottom.dart'; + +typedef TextCallback = Function(String textContent); + +class ContentDetailsPage extends StatefulWidget { + final TextCallback ploneBack; + final String content; + const ContentDetailsPage( + {Key? key, required this.content, required this.ploneBack}) + : super(key: key); + + @override + _ContentDetailsPageState createState() => _ContentDetailsPageState(); +} + +class _ContentDetailsPageState extends State { + late TextEditingController _controller; + final userProvider = Provider.of(Get.context!, listen: false); + + + @override + void initState() { + super.initState(); + _controller = TextEditingController(text: widget.content); + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + elevation: 0, + title: Text( + '编辑短信标签', + style: TextStyle( + fontSize: BaseStyle.fontSize34, + color: BaseStyle.color333333, + fontWeight: FontWeight.bold), + ), + titleSpacing: 162.w, + leading: const CloudBackButton(isSpecial: true), + backgroundColor: kForeGroundColor), + backgroundColor: Colors.white, + body: Container( + height: 800.w, + decoration: BoxDecoration( + color: const Color(0xFFF9F9F9), + borderRadius: BorderRadius.circular(16.w), + ), + padding: EdgeInsets.all(30.w), + margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 50.w), + child: TextField( + maxLines: 100, + keyboardType: TextInputType.text, + onEditingComplete: () { + setState(() {}); + // _refreshController.callRefresh(); + }, + style: TextStyle( + color: BaseStyle.color333333, + fontSize: BaseStyle.fontSize28, + ), + controller: _controller, + decoration: InputDecoration( + contentPadding: EdgeInsets.zero, + filled: true, + isDense: true, + fillColor: Colors.transparent , + hintText: widget.content.isNotEmpty ? "" : "请输入所需短信标签", + hintStyle: TextStyle( + color: widget.content != "" + ? const Color(0xFF333333) + : Colors.grey.shade500, + fontSize: 28.sp, + fontWeight: FontWeight.bold), + border: InputBorder.none, + ), + ), + ), + bottomNavigationBar: PloneBottom( + border: _controller.text.isEmpty, + opacity: _controller.text.isNotEmpty ? 1 : 0.4, + onTap: () async { + BaseModel res = + await apiClient.request(API.app.addTag, data: {'tag': _controller.text}); + if (res.code == 0) { + setState(() {}); + widget.ploneBack(_controller.text); + userProvider.updateUserInfo(); + Get.back(); + } else { + CloudToast.show(res.msg); + } + }, + text: "保存", + ).paddingOnly(bottom: 30.w), + ); + } +} diff --git a/lib/ui/user/privacy_rights_page.dart b/lib/ui/user/privacy_rights_page.dart index ebc7d32..6d365b5 100644 --- a/lib/ui/user/privacy_rights_page.dart +++ b/lib/ui/user/privacy_rights_page.dart @@ -57,7 +57,7 @@ class _PrivacyRightsPageState extends State { leading: const CloudBackButton(isSpecial: true), backgroundColor: kForeGroundColor), backgroundColor: Colors.white, - body: widget.name == "隐私政策" ? null : _getRights(), + body: _getRights(), ); } // Color getPermissionColor() { diff --git a/lib/ui/user/user_page.dart b/lib/ui/user/user_page.dart index dfedac4..3686409 100644 --- a/lib/ui/user/user_page.dart +++ b/lib/ui/user/user_page.dart @@ -2,19 +2,24 @@ import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart'; import 'package:project_telephony/base/base_style.dart'; import 'package:project_telephony/ui/login/login_page.dart'; +import 'package:project_telephony/ui/tab_navigator.dart'; +import 'package:project_telephony/ui/user/content_authority_page.dart'; import 'package:project_telephony/ui/user/members_page.dart'; import 'package:project_telephony/ui/user/privacy_rights_page.dart'; import 'package:project_telephony/ui/widget/image_scaffold.dart'; import 'package:project_telephony/ui/widget/plone_bottom.dart'; import 'package:project_telephony/ui/widget/plone_image_picker.dart'; import 'package:project_telephony/utils/headers.dart'; - +import 'package:project_telephony/utils/permissionutils.dart'; import 'package:provider/provider.dart'; import 'package:telephony/telephony.dart'; +import 'package:velocity_x/velocity_x.dart'; import '../../constants/api.dart'; import '../../model/network/api_client.dart'; @@ -22,8 +27,8 @@ import '../../model/network/api_client.dart'; import '../../providers/user_provider.dart'; import '../../utils/toast/cloud_toast.dart'; import '../../utils/user_tool.dart'; +import 'content_details_page.dart'; -import '../home/content_details_page.dart'; import '../home/home_page.dart'; class UserPage extends StatefulWidget { @@ -36,9 +41,23 @@ class UserPage extends StatefulWidget { final Telephony telephony = Telephony.instance; class _UserPageState extends State { - // bool vle =PermissionStatus.denied.isGranted; + // bool vle = PermissionStatus.denied.isGranted; + //bool vle =PermissionStatus.denied.isGranted; final userProvider = Provider.of(Get.context!, listen: false); bool vle=false; + bool isVip=false; + + @override + void initState() { + super.initState(); + if(userProvider.isLogin){ + if(userProvider.userInfo.isVip==1){ + isVip=true; + }else{ + isVip=false; + } + } + } @override Widget build(BuildContext context) { @@ -55,21 +74,22 @@ class _UserPageState extends State { 72.hb, _getBanner(), 120.hb, - _getSwitch(Assets.icons.switch1.path, "功能开关", true), + _getSwitch(Assets.icons.switch1.path, "功能开关", true), _getSwitch(Assets.icons.privacy.path, "隐私政策", false), - _getSwitch(Assets.icons.permissions.path, "权限说明", false), - _getSwitch(Assets.icons.sms.path, "短信标签", false), + _getSwitch(Assets.icons.permissions.path, "权限说明", false), + _getSwitch(Assets.icons.sms.path, "短信标签", false), // const Spacer(), 182.hb, userProvider.isLogin ? PloneBottom( border: false, - onTap: () async{ + onTap: () async { var cancel = CloudToast.loading; - var base = await apiClient.request(API.app.logout, showMessage: true); + var base = await apiClient.request(API.app.logout, + showMessage: true); if (base.code == 0) { UserTool.userProvider.logout(); - Get.offAll(const HomePage()); + Get.offAll(const TabNavigator()); } cancel(); }, @@ -180,7 +200,7 @@ class _UserPageState extends State { begin: Alignment.centerLeft, end: Alignment.centerRight)), child: Text( - "立即开通", + isVip?"立即续费":"立即购买", style: TextStyle( color: const Color(0xFF001F3F), fontSize: BaseStyle.fontSize24), )), @@ -195,7 +215,7 @@ class _UserPageState extends State { _getVip(), 16.hb, Text( - "解锁全部功能", + isVip?"{$userProvider.userInfo.end}到期":"解锁全部功能", style: TextStyle(color: Colors.white, fontSize: BaseStyle.fontSize24), ) ], @@ -222,9 +242,9 @@ class _UserPageState extends State { color: const Color(0xFFFFEAB0), ), ), - const Text( - "未开通会员", - style: TextStyle( + Text( + isVip?"已成为会员":"未开通会员", + style: const TextStyle( color: Color( 0xFFFFEAB0, ), @@ -238,18 +258,31 @@ class _UserPageState extends State { _getSwitch(String url, String name, bool pd) { return GestureDetector( onTap: () async { - pd - ? "" - : name=="短信标签"?Get.to(()=> ContentDetailsPage( - content: "", - ploneBack: (String textContent) { - // print("这是数据" + textContent); - // textList.setAll(index, {textContent}); - }, - )): - Get.to(() => PrivacyRightsPage( - name: name, - )); + + if(!pd){ + switch(name){ + case "短信标签": + Get.to(() => ContentDetailsPage( + content: + userProvider.isLogin ? userProvider.userInfo.tag : "", + ploneBack: (String textContent) { + // print("这是数据" + textContent); + // textList.setAll(index, {textContent}); + }, + )); + break; + case"隐私政策": + Get.to(() => const ContentAuthorityPage()); + break; + case"权限说明": + Get.to(() => PrivacyRightsPage( + name: name, + )); + break; + default: + break; + } + } }, child: Container( padding: EdgeInsets.symmetric(horizontal: 32.w), @@ -271,15 +304,25 @@ class _UserPageState extends State { trailing: pd ? Switch( value: vle, - onChanged: (value) async{ - vle=value; - if(vle) { - // Telephony.backgroundInstance.sendSms(to: "13395740386", message: "啦啦啦啦啦"); - // Workmanager().registerOneOffTask("task-identifier", "simpleTask"); - } - setState((){}); - - }) + onChanged: (value) async { + await Permission.phone.request(); + // List permissions = [ + // Permission.sms, + // Permission.phone, + // ]; + // PermissionHelper.check(permissions, onSuccess: () { + // print('onSuccess'); + // }, onFailed: () { + // print('onFailed'); + // }, onOpenSetting: () { + // print('onOpenSetting'); + // openAppSettings(); + // }); + // setState(() { + // vle = value; + // }); + } + ) : const Icon(Icons.keyboard_arrow_right)), ), ); diff --git a/lib/ui/widget/centertipsalterwidget.dart b/lib/ui/widget/centertipsalterwidget.dart index 91bd98f..11513a5 100644 --- a/lib/ui/widget/centertipsalterwidget.dart +++ b/lib/ui/widget/centertipsalterwidget.dart @@ -1,12 +1,20 @@ import 'package:flutter/cupertino.dart'; import 'package:project_telephony/utils/headers.dart'; +import 'package:provider/provider.dart'; + +import '../../constants/api.dart'; +import '../../model/network/api_client.dart'; +import '../../model/network/base_model.dart'; +import '../../providers/user_provider.dart'; +import '../../utils/toast/cloud_toast.dart'; class Centertipsalterwidget extends StatefulWidget { final String title; final String desText; + final int id; const Centertipsalterwidget( - {Key? key, required this.desText, required this.title}) + {Key? key, required this.desText, required this.title, required this.id}) : super(key: key); @override @@ -14,6 +22,9 @@ class Centertipsalterwidget extends StatefulWidget { } class _CentertipsalterwidgetState extends State { + + final userProvider = Provider.of(Get.context!, listen: false); + @override Widget build(BuildContext context) { return CupertinoAlertDialog( @@ -39,7 +50,16 @@ class _CentertipsalterwidgetState extends State { ), CupertinoDialogAction( child: const Text('确定'), - onPressed: () { + onPressed: () async { + BaseModel res = await apiClient.request(API.app.delete, data: { + 'id': widget.id, + }); + if (res.code == 0) { + setState(() {}); + userProvider.updateUserInfo(); + } else { + CloudToast.show(res.msg); + } Navigator.pop(context); }, ) diff --git a/pubspec.lock b/pubspec.lock index b0ed806..f4e88fb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -356,6 +356,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + flutter_easyrefresh: + dependency: "direct main" + description: + name: flutter_easyrefresh + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" flutter_gen_core: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 43e8c0a..a7a88d0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -79,6 +79,8 @@ dependencies: get_phone_number: ^2.0.1 # 存取数据 shared_preferences: ^2.0.15 +#刷新组件 + flutter_easyrefresh: ^2.2.1 # # jdk