Toggle navigation
Toggle navigation
This project
Loading...
Sign in
OnePoem
/
OnePoem-App
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Chad
2022-11-04 16:45:42 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
482422ca4b66d2097bde5cfa7e3b9e294614d2ce
482422ca
1 parent
ed4fc927
完善支付接口
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
132 additions
and
55 deletions
lib/apis/api_base.dart
lib/apis/api_order.dart
lib/base/base_state.dart
lib/membership/page/membership_page.dart
lib/net/intercept.dart
lib/payment/payment_sdk.dart
lib/apis/api_base.dart
View file @
482422c
import
'dart:convert'
;
import
'package:Parlando/apis/api_response.dart'
;
import
'package:Parlando/net/dio_utils.dart'
;
import
'package:common_utils/common_utils.dart'
;
import
'package:dio/dio.dart'
;
import
'package:flutter/material.dart'
;
class
BaseApi
{
Future
<
Response
<
ApiResponse
<
T
>
>>
post
<
T
>(
Future
<
Response
<
T
>>
post
<
T
>(
String
path
,
{
data
,
Map
<
String
,
dynamic
>?
queryParameters
,
...
...
@@ -13,7 +16,7 @@ class BaseApi {
ProgressCallback
?
onSendProgress
,
ProgressCallback
?
onReceiveProgress
,
})
{
return
_getDio
().
post
<
ApiResponse
<
T
>
>(
return
_getDio
().
post
<
T
>(
path
,
data:
data
,
queryParameters:
queryParameters
,
...
...
lib/apis/api_order.dart
View file @
482422c
import
'dart:convert'
;
import
'package:Parlando/apis/api_base.dart'
;
import
'package:Parlando/apis/api_response.dart'
;
import
'package:common_utils/common_utils.dart'
;
import
'package:dio/dio.dart'
;
import
'package:flutter/material.dart'
;
...
...
@@ -11,7 +15,13 @@ class OrderApi extends BaseApi {
return
_instance
;
}
Future
<
Response
>
createOrder
(
String
productId
)
{
return
post
(
"/order"
);
Future
<
dynamic
>
createOrder
(
String
productId
)
{
var
data
=
{
"goods_id"
:
productId
};
return
post
(
"order"
,
data:
data
).
then
((
value
)
{
if
(
TextUtil
.
isEmpty
(
value
.
data
))
{
return
{};
}
return
json
.
decode
(
value
.
data
);
});
}
}
...
...
lib/base/base_state.dart
View file @
482422c
...
...
@@ -15,10 +15,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
Widget
buildBody
(
BuildContext
context
);
void
onFirstBuildBody
(
BuildContext
context
){
}
void
onFirstBuildBody
(
BuildContext
context
)
{}
showLoading
({
String
text
=
'Loading...'
})
{
EasyLoading
.
show
(
status:
text
);
...
...
@@ -27,4 +24,8 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
hideLoading
()
{
EasyLoading
.
dismiss
();
}
toast
(
String
text
)
{
EasyLoading
.
showToast
(
text
);
}
}
...
...
lib/membership/page/membership_page.dart
View file @
482422c
...
...
@@ -30,8 +30,7 @@ class MembershipPage extends StatefulWidget {
}
class
MembershipPageState
extends
BaseState
<
MembershipPage
>
with
WidgetsBindingObserver
{
final
List
<
Widget
>
_productWidgets
=
<
Widget
>[];
final
List
<
ProductDetails
>
_products
=
<
ProductDetails
>[];
Function
?
connectionCallBack
;
...
...
@@ -40,11 +39,18 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
@override
void
initState
()
{
super
.
initState
();
PaymentSdk
.
instance
.
initState
();
PaymentSdk
.
instance
.
initState
(
onPaySuccess:
()
{
hideLoading
();
},
onCancel:
()
{
hideLoading
();
},
onFailed:
()
{
hideLoading
();
},
onPending:
()
{
toast
(
"订单Pending"
);
});
PaymentSdk
.
instance
.
queryProducts
().
then
((
value
)
{
for
(
var
element
in
value
)
{
_productWidgets
.
add
(
buildBuyItem
(
element
));
}
_products
.
clear
();
_products
.
addAll
(
value
);
setState
(()
{});
});
if
(
SpUtil
.
containsKey
(
Constant
.
userToken
)!)
{
...
...
@@ -76,8 +82,8 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
child:
Column
(
children:
[
initBackBar
(),
Spacer
(),
//
buildCompleteWidget(),
const
Spacer
(),
buildCompleteWidget
(),
],
),
),
...
...
@@ -112,20 +118,6 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
);
}
Widget
buildBuyItem
(
ProductDetails
element
)
{
var
style
=
const
TextStyle
(
color:
Colors
.
white
);
var
button
=
Text
(
"购买"
,
style:
style
).
paddingLeftRight
(
15
).
paddingTopBottom
(
8
).
click
(()
{
PaymentSdk
.
instance
.
buy
(
element
);
},
color:
Colors
.
blue
).
round
(
radius:
10
);
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
[
Text
(
element
.
price
,
style:
style
),
button
,
],
).
paddingLeftRight
(
10
).
paddingTopBottom
(
5
);
}
Widget
initOtherEntrance
()
{
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
...
...
@@ -165,7 +157,7 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
children:
[
Text
(
mb
?.
title
??
"一言会员"
,
style:
TextStyle
(
fontSize:
18
.
px
,
color:
Colors
.
white
)),
Gaps
.
vGap24
,
_productWidgets
.
isNotEmpty
?
Column
(
children:
_productWidgets
)
:
const
GFLoader
(),
mb
?.
goodsList
?.
isNotEmpty
==
true
?
buildProductWidget
(
mb
)
:
const
GFLoader
(),
Gaps
.
vGap24
,
Text
(
mb
?.
intro
??
"一言介绍"
,
style:
TextStyle
(
fontSize:
14
.
px
,
color:
Colors
.
white
)),
Gaps
.
vGap10
,
...
...
@@ -186,6 +178,55 @@ class MembershipPageState extends BaseState<MembershipPage> with WidgetsBindingO
);
}
buildProductWidget
(
MembershipData
?
mb
)
{
var
widgets
=
mb
?.
goodsList
?.
map
((
e
)
=>
buildProductItem
(
e
)).
toList
()
??
[];
return
Column
(
children:
widgets
);
}
Widget
buildProductItem
(
MembershipDataGoodsList
e
)
{
ProductDetails
?
element
;
for
(
var
value
in
_products
)
{
if
(
value
.
id
==
e
.
membershipId
||
mapId
(
value
.
id
,
e
.
id
))
{
element
=
value
;
break
;
}
}
return
buildBuyItem
(
element
,
e
);
}
Widget
buildBuyItem
(
ProductDetails
?
element
,
MembershipDataGoodsList
e
)
{
var
style
=
const
TextStyle
(
color:
Colors
.
white
);
var
button
=
Text
(
"购买"
,
style:
style
).
paddingLeftRight
(
15
).
paddingTopBottom
(
8
).
click
(()
{
showLoading
();
if
(
element
!=
null
)
{
PaymentSdk
.
instance
.
buy
(
element
,
e
);
}
},
color:
Colors
.
blue
).
round
(
radius:
10
);
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
[
Text
(
buildBuyPrice
(
element
,
e
),
style:
style
),
button
,
],
).
paddingLeftRight
(
10
).
paddingTopBottom
(
5
);
}
String
buildBuyPrice
(
ProductDetails
?
element
,
MembershipDataGoodsList
e
)
{
if
(
element
==
null
)
{
return
"
${e.price}
/
${e.name}
"
;
}
return
"
${element.price}
/
${e.name}
"
;
}
bool
mapId
(
String
?
id
,
int
?
membershipId
)
{
bool
year
=
id
==
'yearly_yiyan_vip'
&&
membershipId
==
4
;
bool
month
=
id
==
'monthly_yiyan_vip'
&&
membershipId
==
3
;
if
(
year
||
month
)
{
print
(
"
$id
----
$membershipId
"
);
}
return
year
||
month
;
}
@override
void
dispose
()
{
PaymentSdk
.
instance
.
dispose
();
...
...
lib/net/intercept.dart
View file @
482422c
...
...
@@ -122,7 +122,7 @@ class LoggingInterceptor extends Interceptor {
Log
.
e
(
'ResponseCode:
${response.statusCode}
'
);
}
// 输出结果
//
Log.json(response.data.toString());
Log
.
json
(
response
.
data
.
toString
());
Log
.
d
(
'----------End:
$duration
毫秒----------'
);
super
.
onResponse
(
response
,
handler
);
}
...
...
lib/payment/payment_sdk.dart
View file @
482422c
import
'dart:async'
;
import
'package:Parlando/apis/api_order.dart'
;
import
'package:flutter/material.dart'
;
import
'package:Parlando/membership/models/membership_entity.dart'
;
import
'package:common_utils/common_utils.dart'
;
import
'package:in_app_purchase/in_app_purchase.dart'
;
class
PaymentSdk
{
...
...
@@ -13,12 +14,25 @@ class PaymentSdk {
return
_instance
;
}
static
const
Set
<
String
>
_kIds
=
<
String
>{
'yearly_yiyan_vip'
,
'monthly_yiyan_vip'
,
'yearly-default'
};
static
const
Set
<
String
>
_kIds
=
<
String
>{
'yearly_yiyan_vip'
,
'monthly_yiyan_vip'
};
StreamSubscription
<
List
<
PurchaseDetails
>>?
_subscription
;
List
<
ProductDetails
>
products
=
[];
Function
?
onPaySuccess
;
Function
?
onPending
;
Function
?
onFailed
;
Function
?
onCancel
;
initState
()
{
initState
({
Function
?
onPaySuccess
,
Function
?
onPending
,
Function
?
onFailed
,
Function
?
onCancel
,
})
{
this
.
onPaySuccess
=
onPaySuccess
;
this
.
onPending
=
onPending
;
this
.
onFailed
=
onFailed
;
this
.
onCancel
=
onCancel
;
final
Stream
<
List
<
PurchaseDetails
>>
purchaseUpdated
=
InAppPurchase
.
instance
.
purchaseStream
;
_subscription
=
purchaseUpdated
.
listen
((
purchaseDetailsList
)
{
_listenToPurchaseUpdated
(
purchaseDetailsList
);
...
...
@@ -32,41 +46,35 @@ class PaymentSdk {
Future
<
List
<
ProductDetails
>>
queryProducts
()
async
{
final
bool
available
=
await
InAppPurchase
.
instance
.
isAvailable
();
if
(!
available
)
{
print
(
"####### isAvailable false"
);
return
[];
}
final
ProductDetailsResponse
response
=
await
InAppPurchase
.
instance
.
queryProductDetails
({
'yearly_yiyan_vip'
,
'monthly_yiyan_vip'
,
'yearly-default'
,
'test.yiyan.vip.1.month'
,
});
if
(
response
.
notFoundIDs
.
isNotEmpty
)
{
// Handle the error.
print
(
"####### notFoundIDs"
);
}
else
{
}
print
(
response
.
productDetails
.
length
);
final
ProductDetailsResponse
response
=
await
InAppPurchase
.
instance
.
queryProductDetails
(
_kIds
);
return
products
=
response
.
productDetails
;
}
buy
(
ProductDetails
details
)
{
// OrderApi.request.createOrder()
final
PurchaseParam
purchaseParam
=
PurchaseParam
(
productDetails:
details
);
buy
(
ProductDetails
details
,
MembershipDataGoodsList
e
)
{
OrderApi
.
request
.
createOrder
(
e
.
id
.
toString
()).
then
((
value
)
{
var
orderId
=
value
?[
'data'
]?[
'data'
]?[
'order_sn'
];
if
(
TextUtil
.
isEmpty
(
orderId
))
{
onFailed
?.
call
();
return
;
}
final
PurchaseParam
purchaseParam
=
PurchaseParam
(
productDetails:
details
,
applicationUserName:
orderId
);
if
(
_isConsumable
(
details
))
{
InAppPurchase
.
instance
.
buyConsumable
(
purchaseParam:
purchaseParam
);
}
else
{
InAppPurchase
.
instance
.
buyNonConsumable
(
purchaseParam:
purchaseParam
);
}
});
}
void
_listenToPurchaseUpdated
(
List
<
PurchaseDetails
>
purchaseDetailsList
)
async
{
for
(
var
purchaseDetails
in
purchaseDetailsList
)
{
if
(
purchaseDetails
.
status
==
PurchaseStatus
.
pending
)
{
// _showPendingUI
();
onPending
?.
call
();
}
else
{
if
(
purchaseDetails
.
status
==
PurchaseStatus
.
error
)
{
//
_handleError(purchaseDetails.error!);
_handleError
(
purchaseDetails
.
error
!);
}
else
if
(
purchaseDetails
.
status
==
PurchaseStatus
.
purchased
||
purchaseDetails
.
status
==
PurchaseStatus
.
restored
)
{
bool
valid
=
await
_verifyPurchase
(
purchaseDetails
);
if
(
valid
)
{
...
...
@@ -74,6 +82,8 @@ class PaymentSdk {
}
else
{
_handleInvalidPurchase
(
purchaseDetails
);
}
}
else
{
onCancel
?.
call
();
}
if
(
purchaseDetails
.
pendingCompletePurchase
)
{
await
InAppPurchase
.
instance
.
completePurchase
(
purchaseDetails
);
...
...
@@ -86,15 +96,27 @@ class PaymentSdk {
return
true
;
}
void
_deliverProduct
(
PurchaseDetails
purchaseDetails
)
{}
void
_deliverProduct
(
PurchaseDetails
purchaseDetails
)
{
onPaySuccess
?.
call
();
}
void
_handleInvalidPurchase
(
PurchaseDetails
purchaseDetails
)
{
onFailed
?.
call
();
}
void
_handleInvalidPurchase
(
PurchaseDetails
purchaseDetails
)
{}
void
_handleError
(
IAPError
iapError
)
{
onFailed
?.
call
();
}
bool
_isConsumable
(
ProductDetails
details
)
{
return
true
;
}
void
dispose
()
{
onPaySuccess
=
null
;
onPending
=
null
;
onFailed
=
null
;
onCancel
=
null
;
_subscription
?.
cancel
();
}
}
...
...
Please
register
or
login
to post a comment