| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055 |
- import { promptAction, router, window } from '@kit.ArkUI';
- import TitleBar from '../view/TitleBar';
- import { webview } from '@kit.ArkWeb';
- import { CommonConstants } from '../common/constants/CommonConstants';
- import { AES,
- AppUtil,
- Base64Util,
- CryptoHelper, DateUtil, FileUtil, LogUtil, PreferencesUtil,
- RandomUtil,
- StrUtil,
- ToastUtil } from '@pura/harmony-utils';
- import { BusinessError } from '@kit.BasicServicesKit';
- import { Pay } from '@cashier_alipay/cashiersdk';
- import { OrderInfoUtil } from '../alipay/OrderInfoUtil';
- import { Utility } from '../common/util/Utility';
- import fileIo, { ReadTextOptions } from '@ohos.file.fs';
- import { fileUri, picker } from '@kit.CoreFileKit';
- import { VipData } from '../viewmodel/VipData';
- import { LocalMusic } from '../view/LocalMusic';
- import { DialogHelper } from '@pura/harmony-dialog';
- import { common } from '@kit.AbilityKit';
- import * as wxOpenSdk from '@tencent/wechat_open_sdk';
- import { OnWXResp, WXApi, WXEventHandler } from '../common/util/WXApiWrap';
- import { ErrCode } from '@tencent/wechat_open_sdk';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- import { http } from '@kit.NetworkKit';
- import { bundleManager } from '@kit.AbilityKit';
- import { cryptoFramework } from '@kit.CryptoArchitectureKit';
- import { JSON } from '@kit.ArkTS';
- const context = getContext(this) as common.UIAbilityContext;
- @Preview
- @Component
- @Entry
- export struct VipPage{
- @State bundleName:string =''
- @State titleBarModel: TitleBar.Model = new TitleBar.Model()
- .setTitleTextStyle(FontStyle.Normal)
- .setTitleBarStyle(TitleBar.BarStyle.TRANSPARENT)
- .setLeftIcon($r('app.media.left_back_white'))
- .setTitleName('赞助中心')
- .setTitleFontColor(Color.White)
- .setTitleBarBackground($r('app.color.title_bar_bg'))
- .setLeftTitleBackground($r('app.color.title_bar_bg'))
- .setTitleBarBottomLineColor($r('app.color.title_bar_bg'))
- .setOnLeftClickListener(() => {
- router.back()
- })
- @State isShowDutySheetView: boolean = false;
- @State isAgree: boolean = false;
- static readonly IS_AGREE: string = 'isAgree';
- static readonly FOEVEER_DATE: string = 'forever';
- @State params: object = router.getParams()
- @State payPrice:number = 38.8 //9是一个 19是一年 19是永久赞助
- static readonly TYPE_MONTH: number = 9.8;
- static readonly TYPE_YEAR: number = 19
- static readonly TYPE_FOREVER: number = 38.8
- static readonly VIP_FILEPATH: string = '.vv'
- @State appName:string = ''
- @State expireDate:string = ''
- @State filePath:string = ''
- @State payType:number = 0
- private wxApi = WXApi
- private wxEventHandler = WXEventHandler
- @State resultText: string = ''
- static readonly WX_NOTIFY_URL: string = 'https://webhook.ss5.xyz/wechat_notify.php'
- // 组件生命周期
- async aboutToAppear() {
- this.isAgree = PreferencesUtil.getBooleanSync(VipPage.IS_AGREE,false)
- Utility.getAppName(getContext(this)).then((appName:string)=>{
- this.appName = appName
- })
- const documentViewPicker = new picker.DocumentViewPicker()
- let documentSaveResult = await documentViewPicker.save({ pickerMode: picker.DocumentPickerMode.DOWNLOAD })
- let download_path = new fileUri.FileUri(documentSaveResult[0]).path + '/'
- this.filePath = download_path + LocalMusic.STR_LOCK_VIDEO+ '/' + VipPage.VIP_FILEPATH
- this.expireDate = this.readDataFromFile(this.filePath)
- this.bundleName = await AppUtil.getBundleName()
- this.doCheckHao()
- this.wxEventHandler.registerOnWXRespCallback(this.onWXResp)
- }
- private onWXResp: OnWXResp = (resp) => {
- if (resp.errCode === ErrCode.ERR_OK) {
- ToastUtil.showToast('支付成功!')
- let expireDate = this.getExpireDate(this.payPrice)
- this.saveDataToFile(expireDate,this.filePath,false )
- }else {
- ToastUtil.showToast('支付失败!')
- }
- // this.resultText = JSON.stringify(resp ?? {}, null, 2)
- }
- // 组件消失生命周期
- aboutToDisappear() {
- console.info(' aboutToDisappear');
- this.wxEventHandler.unregisterOnWXRespCallback(this.onWXResp)
- }
- build() {
- Column() {
- TitleBar({ model: $titleBarModel })
- Scroll() {
- Column() {
- Column() {
- Column() {
- Image($r('app.media.icon'))
- .visibility(Visibility.Visible)
- .borderRadius('100%')
- .clip(true)
- .width(38)
- .height(38)
- Row(){
- Text('欢迎尊敬的用户 ')
- .margin({top:15,bottom:8})
- .fontSize(15)
- .maxLines(1)
- .fontColor(Color.Gray)
- .fontWeight(480)
- Text(this.expireDate===VipPage.FOEVEER_DATE ?'永久赞助':this.expireDate)
- .margin({top:15,bottom:8})
- .fontSize(15)
- .maxLines(1)
- .fontColor(Color.Gray)
- .fontWeight(480)
- }
- }
- .justifyContent(FlexAlign.Center)
- .width('100%')
- .height(72)
- .borderRadius(30)
- }
- .height(72)
- .margin({
- left: 15,
- right: 15,
- top: 15,
- bottom: 0
- })
- Column() {
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Image($r('app.media.vip'))
- .width(18)
- .height(18)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 22 })
- Text(`赞助特权\n1、跳过片头片尾\n2、纯净无广告\n3、更多功能开发中`)
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- Blank()
- }
- .width('100%')
- .height(98)
- .onClick(() => {
- this.isShowDutySheetView = !this.isShowDutySheetView;
- })
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Image($r('app.media.icon_person2'))
- .width(16)
- .height(16)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 22 })
- Text(`客服邮箱:${CommonConstants.CONTACT_MAIL}`)
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .maxLines(2)
- .fontColor(Color.Gray)
- .fontWeight(480)
- Blank()
- }
- .width('100%')
- .height(45)
- .onClick(()=>{
- ToastUtil.showToast('复制邮件地址成功!')
- Utility.copyText(CommonConstants.CONTACT_MAIL)
- })
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Image($r('app.media.selected'))
- .width(16)
- .height(16)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 22 })
- Text('选择赞助时间')
- .margin({ left: 10, right: 20 })
- .fontSize(12)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Blank()
- }
- .width('100%')
- .height(38)
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Text()
- .width(10)
- .height(10)
- .borderRadius('100%')
- .clip(true)
- .backgroundColor($r('app.color.title_bar_bg'))
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
- Text('一个月赞助:'+VipPage.TYPE_MONTH+'元')
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Blank()
- Checkbox()
- .select(this.payPrice===VipPage.TYPE_MONTH?true:false)
- .selectedColor($r('app.color.title_bar_bg'))
- .shape(CheckBoxShape.CIRCLE)
- .onChange((checked: boolean)=>{
- if(checked){
- this.payPrice = VipPage.TYPE_MONTH
- }
- })
- .margin({ left: 20, top: 8, bottom: 8,right:20 })
- .width(22)
- .height(22)
- }
- .onClick(() => {
- this.payPrice = VipPage.TYPE_MONTH
- })
- .width('100%')
- .height(50)
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Text()
- .width(10)
- .height(10)
- .borderRadius('100%')
- .clip(true)
- .backgroundColor($r('app.color.title_bar_bg'))
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
- Text('永久赞助:'+VipPage.TYPE_FOREVER+'元 ')
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Text('(原价¥49.8)')
- .fontSize(14)
- .fontColor(Color.Gray)
- .decoration({ type: TextDecorationType.LineThrough })
- Blank()
- Checkbox()
- .select(this.payPrice===VipPage.TYPE_FOREVER?true:false)
- .selectedColor($r('app.color.title_bar_bg'))
- .onChange((checked: boolean)=>{
- if(checked){
- this.payPrice = VipPage.TYPE_FOREVER
- }
- })
- .shape(CheckBoxShape.CIRCLE)
- .margin({ left: 20, top: 8, bottom: 8,right:20 })
- .width(22)
- .height(22)
- }
- .width('100%')
- .height(50)
- .onClick(() => {
- this.payPrice = VipPage.TYPE_FOREVER
- })
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Image($r('app.media.selected'))
- .width(16)
- .height(16)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 22 })
- Text('选择支付方式')
- .margin({ left: 10, right: 20 })
- .fontSize(12)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Blank()
- }
- .width('100%')
- .height(38)
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Image($r('app.media.wx_logo'))
- .width(22)
- .height(22)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
- Text('微信支付')
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- Blank()
- Checkbox()
- .select(this.payType===0?true:false)
- .selectedColor($r('app.color.title_bar_bg'))
- .onChange((checked: boolean)=>{
- if(checked){
- this.payType =0
- }else{
- this.payType =1
- }
- })
- .shape(CheckBoxShape.CIRCLE)
- .margin({ left: 20, top: 8, bottom: 8,right:20 })
- .width(22)
- .height(22)
- }
- .onClick(() => {
- this.payType =0
- })
- .width('100%')
- .height(50)
- // .visibility(Visibility.None)
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- // .visibility(Visibility.None)
- Row() {
- Image($r('app.media.alipay'))
- .width(22)
- .height(22)
- .alignSelf(ItemAlign.Center)
- .margin({ left: 25 })
- Text('支付宝')
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Blank()
- Checkbox()
- .select(this.payType===1?true:false)
- .selectedColor($r('app.color.title_bar_bg'))
- .onChange((checked: boolean)=>{
- if(checked){
- this.payType =1
- }else{
- this.payType =0
- }
- })
- .shape(CheckBoxShape.CIRCLE)
- .margin({ left: 20, top: 8, bottom: 8,right:20 })
- .width(22)
- .height(22)
- }
- .onClick(() => {
- this.payType =1
- })
- .width('100%')
- .height(50)
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- Row() {
- Checkbox()
- .select(this.isAgree)
- .selectedColor($r('app.color.title_bar_bg'))
- .shape(CheckBoxShape.CIRCLE)
- .onChange((checked: boolean)=>{
- this.isAgree = checked
- })
- .margin({ left: 20, top: 8, bottom: 8 })
- .width(22)
- .height(22)
- Text('请同意用户协议')
- .margin({ left: 10, right: 20 })
- .fontSize(15)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .id('text_update')
- Blank()
- Image($r('app.media.arrow_right'))
- .width(22)
- .height(22)
- .margin({ left: 20, right: 20 })
- .align(Alignment.Center)
- }
- .width('100%')
- .height(45)
- .bindSheet($$this.isShowDutySheetView, this.DutySheet(), {
- height:'85%',
- dragBar: true,
- showClose: true,
- backgroundColor:Color.White,
- title: { title: $r('app.string.persion_duty') }
- })
- .onClick(() => {
- this.isShowDutySheetView = !this.isShowDutySheetView;
- })
- Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
- }
- .margin({top:20,bottom:15})
- Row(){
- Button('开始赞助')
- .fontColor(Color.White)
- .layoutWeight(1)
- .height(50)
- .backgroundColor($r('app.color.title_bar_bg'))
- .stateEffect(true)
- .margin({left:10,right:25})
- .onClick(()=>{
- this.doPay()
- })
- }
- .margin({top:15,bottom:66})
- .width('60%')
- }
- .layoutWeight(1)
- }
- .scrollBar(BarState.Auto)
- .height('100%')
- .alignSelf(ItemAlign.Start)
- .width('100%')
- }
- }
- doPay(){
- if(this.isAgree){
- if(this.payType ===0){
- this.doWxPay()
- }else{
- this.goToAliPay()
- }
- }else{
- this.isShowDutySheetView = true
- }
- }
- doWxPay = () => {
- isHasWX().then((result:boolean) =>{
- if(!result){
- ToastUtil.showToast("没有安装微信")
- return
- }
- //需要德本的服务端支持,德本的接口返回prepayId
- createWeChatOrder(CommonConstants.WX_PAY_APPID, CommonConstants.WX_PAY_MCHID,
- this.appName, this.payPrice*100,CommonConstants.OUT_TRADE_NO_PRE)
- .then((prepayId: string) => {
- this.wechatPay(prepayId)
- // console.log('onecold Prepay ID:', prepayId);
- })
- .catch((error: Error) => {
- console.error('onecold Error:', error);
- });
- // createWeChatOrderInfo(CommonConstants.WX_PAY_APPID, CommonConstants.WX_PAY_MCHID,
- // this.appName, this.payPrice*100,getOutTradeNo())
- // .then((prepayId: string) => {
- // this.wechatPay(prepayId)
- // })
- // .catch((error: Error) => {
- // console.error('onecold Error:', error);
- // });
- })
- }
- //微信支付
- async wechatPay(prepayId: string) {
- console.log('onecold Prepay ID:', prepayId);
- let nonceStr = RandomUtil.getRandomStr(16,'abcdefghijklmnopqrstuvwxyz')
- const timestamp: number = Math.floor(Date.now() / 1000);
- const signString = constructSignatureString(CommonConstants.WX_PAY_APPID,timestamp+'',nonceStr,prepayId)
- // const signString = `${CommonConstants.WX_PAY_APPID}\n${timestamp}\n${nonceStr}\n${prepayId}\n`;
- console.log("onecold rsasignRSA ", 'signString: ' + signString);
- let signStr = await rsaSign2048(signString);
- let signStrBase64 = Base64Util.encodeToStrSync(signStr)
- console.log("onecold rsasignRSA ", 'signStr: ' + signStr);
- console.log("onecold rsasignRSA ", 'signStrBase64: ' + signStrBase64);
- let req = new wxOpenSdk.PayReq
- req.partnerId = CommonConstants.WX_PAY_MCHID //剑虾的商户号mchid对应的值。
- req.appId =CommonConstants.WX_PAY_APPID //微信开放平台审核通过的移动应用AppID 。
- req.packageValue = 'Sign=WXPay' //填写固定值Sign=WXPay
- req.prepayId = prepayId //调用微信支付下单接口返回的支付交易会话ID,该值有效期为2小时。
- req.nonceStr = nonceStr //随机字符串,不长于32位。推荐随机数生成算法。
- req.timeStamp = timestamp+'' //时间戳,标准北京时间
- req.sign = signStrBase64
- req.extData = 'extData'
- let finished = await this.wxApi.sendReq(getContext(this) as common.UIAbilityContext, req)
- hilog.info(0x0000,'onecold','send request finished: ', finished)
- }
- goToAliPay(){
- /*
- * 支付宝支付:这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
- * 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
- * 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
- *
- * orderInfo 的获取必须来自服务端;
- */
- OrderInfoUtil.getOrderInfo(this.payPrice,this.appName).then((orderInfo) => {
- new Pay().pay(orderInfo, true).then(async (result) => {
- let message =
- `resultStatus: ${result.get('resultStatus')} memo: ${result.get('memo')} result: ${result.get('result')}`;
- // console.log(message);
- if(result.get('resultStatus') === '9000'){//9000支付成功,6001取消支付
- ToastUtil.showToast('支付成功!')
- let expireDate = this.getExpireDate(this.payPrice)
- this.saveDataToFile(expireDate,this.filePath,false )
- }else{
- ToastUtil.showToast('取消支付!')
- }
- }).catch((error: BusinessError) => {
- console.log(error.message);
- ToastUtil.showToast('支付失败!'+error.message)
- });
- });
- }
- getExpireDate(payPrice:number){
- const now = new Date();
- if(payPrice == VipPage.TYPE_MONTH){
- // 返回一个月后的时间
- now.setMonth(now.getMonth() + 1);
- }else if(payPrice === VipPage.TYPE_YEAR){
- // 返回一年后的时间
- now.setFullYear(now.getFullYear() + 1);
- }else if(payPrice === VipPage.TYPE_FOREVER){
- return VipPage.FOEVEER_DATE
- }
- return DateUtil.getFormatDateStr(now,'yyyy-MM-dd HH:mm');
- }
- readDataFromFile(filePath:string){
- if(!FileUtil.accessSync(filePath)){
- return ''
- }
- let readTextOptions: ReadTextOptions = {
- offset: 0,
- length: 0,
- encoding: 'utf-8'
- };
- let stat = fileIo.statSync(filePath);
- readTextOptions.length = stat.size;
- let str = fileIo.readTextSync(filePath, readTextOptions);
- const parsedData:VipData = JSON.parse(str) as VipData;
- // LogUtil.info('onecold parsedData.expireDate = ' + parsedData.expireDate)
- let result = Base64Util.decodeSync( parsedData.expireDate)
- // LogUtil.info('onecold 解密的result = ' +StrUtil.unit8ArrayToStr(result))
- return StrUtil.unit8ArrayToStr(result);
- }
- async saveDataToFile(expireDate:string, filePath:string,isHao:boolean) {
- let newExpireDate = expireDate
- if(expireDate!==VipPage.FOEVEER_DATE){
- if(FileUtil.accessSync(filePath)&&!isHao){
- let readDate = this.readDataFromFile(filePath)
- let currentDate = new Date();
- if(readDate === VipPage.FOEVEER_DATE){
- newExpireDate = VipPage.FOEVEER_DATE
- }else{
- //如果里面有值,直接把日期相加
- if(DateUtil.getFormatDate(readDate) > currentDate){
- let iDate = DateUtil.compareDays(currentDate,readDate)
- // LogUtil.info('onecold iDate = ' + iDate)
- let itemDate = DateUtil.getFormatDate(expireDate);
- newExpireDate =DateUtil.getFormatDateStr(Utility.addDays(itemDate,iDate),'yyyy-MM-dd HH:mm')
- // LogUtil.info('onecold newExpireDate = ' + newExpireDate)
- }
- }
- }
- }else{
- newExpireDate = VipPage.FOEVEER_DATE
- }
- this.expireDate = newExpireDate
- Utility.setNoble(this.expireDate)
- //将newExpireDate进行加密
- newExpireDate = Base64Util.encodeToStrSync(StrUtil.strToUint8Array(newExpireDate))
- // LogUtil.info('onecold 加密后的newExpireDate = ' + newExpireDate)
- let newItem = new VipData(newExpireDate,'',true)
- try {
- let jsonData = JSON.stringify(newItem);
- const file = await fileIo.open(filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE);
- // 清空文件内容
- await fileIo.truncate(file.fd, 0);
- await fileIo.write(file.fd, jsonData);
- await fileIo.close(file);
- console.log('Data saved successfully.');
- } catch (error) {
- console.error('Failed to save data:', error);
- }
- }
- @Builder
- DutySheet() {
- Column(){
- this.DutyView()
- }
- .width('100%')
- .height('100%')
- }
- private webController: WebviewController = new webview.WebviewController();
- ports: webview.WebMessagePort[] = [];
- @State webUrl: string = CommonConstants.NEW_DUTY
- @State
- progressValue: number = 0
- @Builder
- DutyView(){
- Progress({ value: 0, total: 100, type: ProgressType.Linear })
- .backgroundColor(0xFFFFFF)
- .color(0x414AFF)
- .value(this.progressValue)
- .width('%100')
- .height(2)
- // .visibility(this.progressIsVisible)
- .visibility(this.progressValue!=100 ? Visibility.Visible : Visibility.None)
- Column(){
- Web({
- src: this.webUrl,
- controller: this.webController
- })
- .width("100%")
- .height("100%")
- .layoutWeight(1)
- .domStorageAccess(true)
- .onProgressChange((event)=>{
- if (event) {
- console.log('newProgress:' + event.newProgress);
- this.progressValue = event.newProgress
- }
- })
- Row(){
- Button('不同意')
- .fontColor(Color.White)
- .backgroundColor($r('app.color.title_bar_bg'))
- .height(50)
- .layoutWeight(1)
- .stateEffect(true)
- .margin({left:25,right:10})
- .onClick(()=>{
- this.isAgree = false
- PreferencesUtil.putSync(VipPage.IS_AGREE,this.isAgree)
- this.isShowDutySheetView = false
- })
- Button('同意')
- .fontColor(Color.White)
- .layoutWeight(1)
- .height(50)
- .backgroundColor($r('app.color.title_bar_bg'))
- .stateEffect(true)
- .margin({left:10,right:25})
- .onClick(()=>{
- this.isAgree = true
- PreferencesUtil.putSync(VipPage.IS_AGREE,this.isAgree)
- this.isShowDutySheetView = false
- })
- }
- .margin({top:20,bottom:30})
- }
- }
- doCheckHao(){
- if(Utility.isHaoOpenTime()){
- let isHao:boolean = PreferencesUtil.getBooleanSync('is_vhaoping');
- if(!isHao){
- this.showHaopingDialog()
- return
- }
- }
- }
- showHaopingDialog(){
- setTimeout(()=>{
- DialogHelper.showCustomContentDialog({
- dialogId:'haoping',
- title: "好评福利",
- autoCancel: false, //点击遮障层时,不关闭弹窗
- backCancel: true, //点击返回键,不关闭弹窗
- contentBuilder: () => {
- this.customHaoPingBuilder("好消息!好评可以返一个月无广告特权!\n\n如果您觉得好用可以给个好评吗?谢谢!\n\n给个好评吧,非常感谢您的支持!")
- },
- buttons: [],
- })
- },3000)
- }
- //好评的自定义内容
- @Builder
- customHaoPingBuilder(content: string) {
- Column() {
- Text(content)
- .fontColor(Color.Gray)
- .fontSize(16)
- .alignSelf(ItemAlign.Start)
- .margin({bottom:15})
- .fontSize(16)
- Row(){
- Button('取消')
- .fontColor(Color.White)
- .backgroundColor($r('app.color.title_bar_bg'))
- //.linearGradient( { direction: GradientDirection.Right, colors:[['#ff37a0fc',0.0],['#67e667',0.5],['#f5856e',1.0]]})
- .height(50)
- .layoutWeight(1)
- .stateEffect(true)
- .margin({right:6})
- .onClick(()=>{
- DialogHelper.closeDialog('haoping'); //关闭弹框
- })
- Button('好评')
- .fontColor(Color.White)
- //.linearGradient( { direction: GradientDirection.Right, colors:[['#ff37a0fc',0.0],['#67e667',0.5],['#f5856e',1.0]]})
- .layoutWeight(1)
- .height(50)
- .backgroundColor($r('app.color.title_bar_bg'))
- .stateEffect(true)
- .margin({left:6})
- .onClick(()=>{
- DialogHelper.closeDialog('haoping'); //关闭弹框
- Utility.gotoMarket(context,this.bundleName)
- PreferencesUtil.putSync("is_vhaoping", true);
- setTimeout(()=>{
- let expireDate = this.getExpireDate(VipPage.TYPE_MONTH)
- this.saveDataToFile(expireDate,this.filePath,true )
- },360000)
- })
- }
- }
- .width("100%")
- .padding(10)
- }
- }
- // 定义响应数据的类型
- interface WeChatOrderResponse {
- prepay_id: string;
- }
- interface Amount {
- total: number;
- currency: string;
- }
- //调用服务端接口,用户在商户APP端选择微信支付后,商户需调用该接口在微信支付下单,生成用于调起支付的预支付交易会话标识(prepay_id)。
- async function createWeChatOrder(
- app_id: string,
- mch_id: string,
- description: string,
- amount: number,
- out_trade_no_pre: string,
- ): Promise<string> {
- let requestUrl = CommonConstants.WX_PAY_API
- + '?app_id=' + encodeURIComponent(app_id.trim())
- + '&mch_id=' + encodeURIComponent(mch_id.trim())
- + '&description=' + encodeURIComponent(description.trim())
- + '&amount=' + encodeURIComponent(amount)
- + '&out_trade_no_pre=' + encodeURIComponent(out_trade_no_pre)
- LogUtil.debug("onecold 微信支付 requestUrl=" + requestUrl)
- const httpRequest: http.HttpRequest = http.createHttp();
- const options: http.HttpRequestOptions = {
- method: http.RequestMethod.GET,
- readTimeout: 6000,
- connectTimeout: 6000,
- };
- try {
- const response: http.HttpResponse = await httpRequest.request(requestUrl, options);
- if (response.responseCode === 200) {
- let responseData: WeChatOrderResponse;
- LogUtil.debug("onecold 微信支付 response.result=" + response.result)
- if (typeof response.result === 'string') {
- responseData = JSON.parse(response.result) as WeChatOrderResponse;
- } else if (response.result instanceof Object) {
- responseData = response.result as WeChatOrderResponse;
- } else {
- throw new Error('onecold Unexpected response format');
- }
- const prepayId: string = responseData.prepay_id;
- console.log('onecold WeChat Order Created, prepay_id:', prepayId);
- return prepayId;
- } else {
- console.error('Failed to create WeChat order:', response.responseCode, response.result);
- throw new Error(`HTTP Error: ${response.responseCode}`);
- }
- } catch (error) {
- console.error('Error creating WeChat order:', error);
- return '';
- }
- }
- async function isHasWX(): Promise<boolean>{
- try {
- let link = 'weixin://';
- let data = bundleManager.canOpenLink(link);
- if (data) {
- return true
- }else {
- promptAction.showToast({message:'微信未安装'})
- return false
- }
- } catch (err) {
- let message = (err as BusinessError).message;
- console.error('canOpenLink failed: %{public}s', message);
- return false
- }
- }
- // 微信支付构造签名串
- function constructSignatureString(appId: string, timestamp: string, nonceStr: string, prepayId: string): string {
- return `${appId}\n${timestamp}\n${nonceStr}\n${prepayId}\n`;
- }
- // 微信支付RSA2048|PKCS1|SHA256 APP调起支付签名
- async function rsaSign2048(message:string): Promise<Uint8Array> {
- try {
- let keyGen = cryptoFramework.createAsyKeyGenerator("RSA2048")
- let key = keyGen.convertPemKeySync(null, CommonConstants.WX_PAY_RSA_PRIVATE_KEY)
- let sign = cryptoFramework.createSign('RSA2048|PKCS1|SHA256');
- let msgBlob: cryptoFramework.DataBlob = {data: StrUtil.strToUint8Array(message)}
- sign.initSync(key.priKey)
- let signature = await sign.sign(msgBlob)
- return signature.data
- } catch (error) {
- console.error(error, `onecold error code: ${error.code}`)
- return new Uint8Array()
- }
- }
- // 定义接口请求参数类型
- interface WeChatOrderRequest {
- appid: string;
- mchid: string;
- description: string;
- out_trade_no: string;
- notify_url: string;
- amount: Amount;
- }
- function generateSignatureInfo(timestamp: string,nonceStr: string,body:string): string {
- const httpMethod = 'POST';
- const url = '/v3/pay/transactions/jsapi';
- // const timestamp = Math.floor(Date.now() / 1000).toString();
- // const body = '{"appid":"wxd678efh567hg6787","mchid":"1900007291","description":"Image形象店-深圳腾大-QQ公仔","out_trade_no":"1217752501201407033233368018","notify_url":"https://www.weixin.qq.com/wxpay/pay.php","amount":{"total":100,"currency":"CNY"},"payer":{"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"}}';
- console.log("onecold rsasignRSA ", 'body: ' + body);
- const signatureString = `${httpMethod}\n${url}\n${timestamp}\n${nonceStr}\n${body}\n`;
- return signatureString
- }
- function getOutTradeNo(): string {
- const timestamp = Date.now().toString(); // 获取当前时间戳
- const randomPart = Math.floor(Math.random() * 1e16).toString().padStart(16, '0'); // 生成16位随机数
- const orderNumber = (timestamp + randomPart).slice(0, 32); // 确保长度为32位
- return orderNumber;
- }
- // 构造Authorization头
- function constructAuthorizationHeader(mchid: string,nonceStr:string,signature: string,
- timestamp:string,serialNo:string): string {
- return `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonceStr}",signature="${signature}",timestamp="${timestamp}",serial_no="${serialNo}"`;
- }
- async function createWeChatOrderInfo(appid: string, mchid: string, description: string,amount: number,
- outTradeNo: string): Promise<string> {
- const url: string = 'https://api.mch.weixin.qq.com/v3/pay/transactions/app';
- let nonceStr = RandomUtil.getRandomStr(16,'abcdefghijklmnopqrstuvwxyz')
- const timestamp: number = Math.floor(Date.now() / 1000);
- // 构建请求体
- const body: WeChatOrderRequest = { appid: appid, mchid: mchid, description: description, out_trade_no: outTradeNo, notify_url: VipPage.WX_NOTIFY_URL, amount: { total: amount, currency: 'CNY'} };
- let generateSign:string= generateSignatureInfo(timestamp+'',nonceStr, JSON.stringify(body))
- console.log("onecold rsasignRSA ", 'generateSign: ' + generateSign);
- let signStr = await rsaSign2048(generateSign);
- let signStrBase64 = Base64Util.encodeToStrSync(signStr)
- let authorizationHeader = constructAuthorizationHeader(mchid,nonceStr,signStrBase64,timestamp+'',CommonConstants.WX_PAY_SERIALNO)
- console.log("onecold rsasignRSA ", 'signStr: ' + signStr);
- console.log("onecold rsasignRSA ", 'signStrBase64: ' + signStrBase64);
- console.log("onecold rsasignRSA ", 'authorizationHeader: ' + authorizationHeader);
- // 构建请求头
- const headers: Record<string, string> = {
- 'Authorization': authorizationHeader, // 替换为你的授权信息
- 'Accept': 'application/json',
- 'Content-Type': 'application/json',
- };
- const httpRequest: http.HttpRequest = http.createHttp();
- const options: http.HttpRequestOptions = {
- method: http.RequestMethod.POST,
- header: headers,
- extraData: JSON.stringify(body),
- readTimeout: 6000,
- connectTimeout: 6000,
- };
- try {
- const response: http.HttpResponse = await httpRequest.request(url, options);
- LogUtil.debug("onecold 微信支付 response.result=" + response.result)
- if (response.responseCode === 200) {
- // LogUtil.debug("onecold 微信支付 response.result=" + response.result)
- let responseData: WeChatOrderResponse;
- if (typeof response.result === 'string') {
- responseData = JSON.parse(response.result) as WeChatOrderResponse;
- } else if (response.result instanceof Object) {
- responseData = response.result as WeChatOrderResponse;
- } else {
- throw new Error('Unexpected response format');
- }
- const prepayId: string = responseData.prepay_id;
- console.log('WeChat Order Created, prepay_id:', prepayId);
- return prepayId;
- } else {
- console.error('Failed to create WeChat order:', response.responseCode, response.result);
- throw new Error(`HTTP Error: ${response.responseCode}`);
- }
- } catch (error) {
- console.error('Error creating WeChat order:', error);
- return '';
- }
- }
|