充值画面——金额的选择和输入

本文详细介绍了如何设计并实现一个带有数字输入限制的充值界面,包括使用正则表达式限制输入、金额显示格式化及焦点控制等关键技术点。

先看一下做好的效果图
金额的选择和输入
这个充值画面看着还挺简单的,几个预定的充值金额,还有一个手动输入框,但涉及到了蛮多的知识点,还是花费了一点时间的,这里总结一下:

  1. 要求是只能输入数字,最多小数点后两位,下方的充值金额小计一栏始终显示两位小数,除非金额为0,才可以显示为0。
  2. GridView 的最后一项是EditText ,点击的时候不能在OnItemClickListener 中监听到,通过OnFocusChangeListener 进行了监听。
  3. 从输入框切换到具体金额时,清除输入框的焦点clearFocus(),以便下次点击输入框时能回调OnFocusChangeListener 中的方法。

  4. 从输入框切换到具体金额时,隐藏键盘,同时避免隐藏时影响画面布局。

  5. 从具体金额切换到输入框时,提取输入框中已经输入的金额到小计一栏。

  6. 控制输入框中的输入,利用正则表达式结合TextWatcher() 监听器,当输入不符合规定时,动态改变显示的数字(要避免进入死循环),再实时更新到小计一栏。

    最后的效果还是比较6的,需求已经都实现了,美中不足的是键盘还能调出不是数字的,虽然不能输入非数字的,暂时没找到这个的解决方案。
    看了一下支付宝的金额键盘是纯数字的,比较好。

同上你看看我这个类还有什么没有删 或者还有什么没有加的import uiBase from "./uiBase.js"; import { Container, Graphics, Text, Assets, Sprite, Texture } from "pixi.js"; import gameData from "../Frame/gameDataMgr.js"; import networkMgr from "../Frame/networkMgr.js"; import { UIManager } from "../Frame/uiManager.js"; import { BlackMaskBg } from "../Frame/CommonUI/blackMaskBg"; import { LocalSprite } from "../Frame/CommonUI/LocalSprite"; import { UIBankData } from "../UIView/uiBankData.js"; class uiShop extends uiBase { mainContainer; // 主界面容器 blockBg; // 背景遮罩 shopBg3Container; // 弹窗容器 shopBgButton; // 按钮 buttonText; // 按钮文字 closeButton; // 叉叉按钮 introduceText; // 介绍背景 isInist = false; isPivotInitialized = false; CONTAINER_WIDTH = 650; CONTAINER_HEIGHT = 400; shopGoodsList = []; _rpLabel = gameData.currencySign; // 使用动态货币符号 // 记录当前选中的索引金额值 selectedIndex = -1; // 当前选中的金额框索引 selectedAmountValue = 0; // 当前选中的金额数值 selectedStarCount = 0; // 当前赠送的星数 id = 0; // 当前选中的id inputDisplayText; // 显示选中金额的文本 rechargeYes; // 可点击亮色图 rechargeNo; // 不可点击灰色图 depositHistory; // 历史记录按钮 depositHistoryText; // 历史记录文本 // =====银行选择弹窗容器 ===== bankPopupContainer; // 充值支付银行弹窗容器 bankList = []; // 银行列表数据 bankSprites = []; // 银行图标精灵数组 bankShineSprites = []; // 银行图标发光边框数组 selectedBankIndex = -1; // 当前选中的银行索引 selectedBankData = null; // 当前选中的银行数据 bankConfirmYes; // 银行确认按钮亮色 bankConfirmNo; // 银行确认按钮灰色 // =====支付成功展示 ===== paymentSuccessContainer; // 支付成功展示容器 paymentAmountText; // 支付金额文本 paymentConfirmButton; // 支付成功确认按钮 scrollContainer; //创建滚动容器 // =====历史记录弹窗容器 ===== historyListContainer; recordList = []; historyTextObjects = []; // 用于存储每条记录的所有文本对象(因为要每条记录都参与本地化) bank=null; async init() { super.init(); // 创建主界面容器 this.mainContainer = new Container(); this.mainContainer.position.set(330, 210); this.container.addChild(this.mainContainer); // 预加载资源 await Assets.load([ "assets/UIShop/+.png", "assets/UIShop/复制.png", "assets/UIShop/商店底1_1.png", "assets/UIShop/商店底2.png", "assets/UIShop/商店底3.png", "assets/UIShop/赠送底.png", "assets/UIShop/赠送金额底.png", "assets/UIShop/UI1_02.png", "assets/UIShop/UI1_03.png", "assets/UIShop/UI1_05.png", "assets/UIShop/UI1_07.png", "assets/UIShop/UI1_09_2.png", "assets/UIShop/UI1_09.png", "assets/UIShop/UI1_11.png", "assets/UIShop/UI1_14.png", "assets/UIShop/UI1_17.png", "assets/UIShop/UI1_22.png", "assets/UIShop/商店底4.png", "assets/UIShop/UI8_6.png", "assets/UIShop/WithdrawalBankIcon_DANA.png", "assets/UIShop/WithdrawalBankIcon_OVO.png", "assets/UIShop/WithdrawalBankIcon_QRIS.png", "assets/UIShop/WithdrawalBankIcon_BNI.png", "assets/UIShop/WithdrawalBankIcon_BRI.png", "assets/UIShop/WithdrawalBankIcon_ALLIANCE.png", "assets/UIShop/WithdrawalBankIcon_BCA.png", "assets/UIShop/WithdrawalBankIcon_BIMB.png", "assets/UIShop/商店底5.png", "assets/UIShop/复制.png", "assets/UIShop/商店底1_12.png", ]); // 获取商店数据 await this.SendShopData(); // === 主界面内容 === // 创建主界面后面黑幕 const app = this.app; this.overallWidth = app.screen.width; this.overallHeight = app.screen.height; const opacity = 0.6; //黑幕 const blackMask = new Graphics(); blackMask.beginFill(0x000000, opacity); blackMask.drawRect(-this.overallWidth * 0.51, -this.overallHeight * 0.53, this.overallWidth*1.13, this.overallHeight); blackMask.endFill(); this.mainContainer.addChild(blackMask); //黑幕 //let blackMask = new BlackMaskBg({ parent: this.mainContainer }); const shopBg2 = new Sprite(Texture.from("assets/UIShop/商店底1_12.png")); shopBg2.width = this.overallWidth; shopBg2.height = this.overallHeight; const offsetX = -this.overallWidth * 0.5; // 向左偏移整体宽度的 50% const offsetY = -this.overallHeight * 0.53; // 向上偏移高度的 20% shopBg2.position.set(offsetX, offsetY); this.closeButton = new Sprite(Texture.from("assets/UIShop/UI1_03.png")); //主界面叉叉按钮 this.closeButton.width = 40; this.closeButton.height = 40; this.closeButton.anchor.set(1, 0); this.closeButton.position.set(this.overallWidth/2-10, -this.overallHeight/2); this.closeButton.eventMode = "static"; this.closeButton.cursor = "pointer"; this.closeButton.on("pointerdown", () => this.hide()); const textX = shopBg2.position.x + shopBg2.width * 0.5; const textY = shopBg2.position.y+10; // 主界面装饰文本 this.depositText = Object.assign( new Text("存款deposit", { fontFamily: "Arial", fontSize: 35, fill: 0xffff84, align: "center", stroke: "#FFA500", strokeThickness: 2, fontWeight: "bold", }), { anchor: { x: 0.5, y: 0 }, position: { x: textX, y: textY } }, ); this.topUpAmountText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 14, fill: 0xcf9f6c, align: "center", fontWeight: "bold", }), { anchor: { x: 0.5, y: 0 },position: { x: this.overallWidth * -0.15, y:this.overallHeight* -0.3 } }, ); this.inputAmountText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 14.5, fill: 0xd37744, align: "center", }), { anchor: { x: 0.5, y: 0 }, position: { x: this.overallWidth * -0.12, y:this.overallHeight* -0.23 } }, ); const inputBox = new Sprite(Texture.from("assets/UIShop/UI1_02.png")); // 输入框图 inputBox.width *= this.app.rat; inputBox.height *= this.app.rat; inputBox.anchor.set(0.5, 0.5); inputBox.position.set( this.overallWidth * -0.10+5, this.overallHeight* -0.21, ); // 显示选中金额的文本 this.inputDisplayText = new Text("", { fontSize: 18, fill: 0xb18b5b, fontFamily: "Arial", fontWeight: "bold", }); this.inputDisplayText.anchor.set(0.5); this.inputDisplayText.position.set( this.overallWidth * -0.15, this.overallHeight* -0.21, ); this.inputDisplayText.visible = false; // 初始不显示 const clearInput = new Sprite(Texture.from("assets/UIShop/UI1_17.png")); // 输入框里的叉叉 clearInput.width *= this.app.rat+0.2; clearInput.height *= this.app.rat+0.1; clearInput.anchor.set(0.5, 0.5); clearInput.position.set( this.overallWidth * 0.07, this.overallHeight* -0.21, ); clearInput.eventMode = "static"; clearInput.cursor = "pointer"; // 绑定叉叉点击事件:清除输入框中的金额 clearInput.on("pointerdown", () => { if (this.inputDisplayText.visible) { this.clearSelection(); // 清除状态 } }); const addPicture = new Sprite(Texture.from("assets/UIShop/+.png")); // 加号图 addPicture.width *= this.app.rat; addPicture.height *= this.app.rat; addPicture.anchor.set(0.5, 0.5); addPicture.position.set( this.overallWidth * 0.15, this.overallHeight* -0.21, ); const givePicture = new Sprite( Texture.from("assets/UIShop/赠送金额底.png"), ); // 赠送金额底 givePicture.width *= this.app.rat; givePicture.height *= this.app.rat; givePicture.anchor.set(0.5, 0.5); givePicture.position.set( this.overallWidth * 0.29, this.overallHeight* -0.21, ); const givePicture2 = new Sprite(Texture.from("assets/UIShop/赠送底.png")); // 赠送底 givePicture2.width *= this.app.rat; givePicture2.height *= this.app.rat; givePicture2.anchor.set(0.5, 0.5); givePicture2.position.set( this.overallWidth * 0.29, this.overallHeight* -0.21, ); this.freeAmountText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 11, fill: 0xcf9f6c, align: "center", fontWeight: "bold", }), { anchor: { x: 0.5, y: 0.5 }, position: { x: this.overallWidth * 0.29, y:this.overallHeight* -0.26 } }, ); this.rpText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 25, fill: 0xffffff, align: "center", fontWeight: "bold", }), { anchor: { x: 0.5, y: 0.5 }, position: { x: this.overallWidth * 0.28, y:this.overallHeight* -0.18 } }, ); this.selectAmountText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 15, fill: 0xcf9f6c, align: "center", fontWeight: "bold", }), { anchor: { x: 0.5, y: 0.5 }, position: { x: this.overallWidth * -0.1, y:this.overallHeight* -0.12 } }, ); //添加到舞台 画面上 this.mainContainer.addChild( shopBg2, // shopBg1, this.closeButton, inputBox, clearInput, addPicture, givePicture, givePicture2, ); this.mainContainer.addChild( this.depositText, this.topUpAmountText, this.inputAmountText, this.freeAmountText, this.rpText, this.selectAmountText, this.inputDisplayText, ); console.log("看一下有没有赋值进去~~~", this.shopGoodsList); // 创建金额框图8个、小红角星8张、发光边框8个 this.amountSprites = []; // 存储所有金额图的数组 this.starSprites = []; // 存储所有五角星的数组 this.shineSprites = []; // 存储所有发光边框的数组 this.selectedIndex = -1; // 当前选中的索引,-1表示没有选中 // === 创建滚动容器 === this.scrollContainer = new Container(); this.scrollContainer.x = 0; this.scrollContainer.y = 0; this.mainContainer.addChild(this.scrollContainer); // === 设置滚动参数 === const visibleRows = 2; // 显示2排 const colsPerRow = 4; // 每排3个 const totalRows = Math.ceil(this.shopGoodsList.length / colsPerRow); // 总排数 const scrollableHeight = (totalRows - visibleRows) * 60; // 可滚动的高度 // === 设置遮罩,限制显示区域 === const mask = new Graphics(); mask.beginFill(0x000000, opacity); mask.drawRect(-this.overallWidth * 0.51, -this.overallHeight * 0.53, this.overallWidth*1.13, this.overallHeight); mask.endFill(); this.scrollContainer.mask = mask; this.mainContainer.addChild(mask); // 调整金额框的间距参数 const startX = this.overallWidth * -0.2; // 起始X坐标 const startY = this.overallHeight* 0.01; // 起始Y坐标 const spacingX = 100; // X轴间距(左右间隔) const spacingY = 60; // Y轴间距(上下间隔) for (let i = 0; i < this.shopGoodsList.length; i++) { // 1. 创建发光边框图 const shine = new Sprite(Texture.from("assets/UIShop/UI1_11.png")); shine.width *= this.app.rat; shine.height *= this.app.rat; shine.anchor.set(0.5, 0.5); shine.visible = false; // 初始隐藏,只有选中时才显示 // 2. 创建金额框图 const amount = new Sprite(Texture.from("assets/UIShop/UI1_22.png")); amount.width *= this.app.rat; amount.height *= this.app.rat; amount.anchor.set(0.5, 0.5); amount.interactive = true; // 启用点击交互 amount.buttonMode = true; // 鼠标移到上面变成手型 // 3. 创建小红角星图 const star = new Sprite(Texture.from("assets/UIShop/UI1_14.png")); star.width *= this.app.rat; star.height *= this.app.rat; star.anchor.set(0.5, 0.5); // 4. 创建文本显示 - 金额 const amountText = new Text("", { fontSize: 15, fill: 0xff7e36, // 橘色 fontFamily: "Arial", }); amountText.anchor.set(0.5, 0.5); amountText.interactive = true; // 启用点击交互 amountText.buttonMode = true; // 鼠标移到上面变成手型 amountText.cursor = "pointer"; // 设置鼠标指针为手型 // 5. 创建文本显示 - 星星 const starText = new Text("", { fontSize: 11, fill: 0xffffff, // 白色 fontWeight: "normal", fontFamily: "Arial, sans-serif", }); starText.anchor.set(0.5, 0.5); starText.interactive = true; // 启用点击交互 starText.buttonMode = true; // 鼠标移到上面变成手型 starText.cursor = "pointer"; // 设置鼠标指针为手型 // 计算位置(每排3个,多排) const row = Math.floor(i / colsPerRow); const col = i % colsPerRow; const xPos = startX + col * spacingX; const yPos = startY + row * spacingY; // 设置所有元素的位置 shine.position.set(xPos, yPos); // 发光边框在底层 amount.position.set(xPos, yPos); // 金额框在中间 star.position.set(xPos + 18, yPos - 22); // 五角星在金额框右上方 amountText.position.set(xPos, yPos + 2); // 金额文本在金额框中心偏下 starText.position.set(xPos + 18, yPos - 25); // 星星数量文本在五角星中心 // shopGoodsList获取数据 let item, extraItem, count, starCount, id; if (this.shopGoodsList && this.shopGoodsList[i]) { item = this.shopGoodsList[i].items[0]; extraItem = this.shopGoodsList[i].extraItems[0]; count = item ? item.count : 0; starCount = extraItem ? extraItem.count : 0; id = this.shopGoodsList[i].id; } else { count = 0; starCount = 0; id = 0; } // 设置金额文本 const label = this._rpLabel; amountText.text = count > 0 ? `${label} ${count}` : "0"; // 只有当starCount大于0时才显示星星图片文本 if (starCount > 0) { starText.text = `+${starCount}`; star.visible = true; starText.visible = true; star.interactive = true; star.buttonMode = true; } else { starText.text = ""; star.visible = false; starText.visible = false; star.interactive = false; star.buttonMode = false; } // 创建点击处理函数 const handleItemClick = () => { if (this.bankPopupContainer && this.bankPopupContainer.visible) { // 如果支付弹窗已显示 return; } // 先隐藏所有发光边框 for (let j = 0; j < this.shineSprites.length; j++) { this.shineSprites[j].visible = false; } // 显示当前点击的发光边框 this.shineSprites[i].visible = true; this.selectedIndex = i; this.selectedAmountValue = count; this.selectedStarCount = starCount; this.id = id; this.inputDisplayText.text = `${label} ${count}`; //// 输入框显示为"货币" this.inputDisplayText.visible = true; this.inputAmountText.visible = false; // 隐藏提示文字 // rpText 显示为纯数字 this.rpText.text = `${this._rpLabel} ${this.formatNumberWithUnit(starCount)}`; console.log( "选中了第", i + 1, "个金额图,金额:", count, "赠送星:", starCount, "id:", id, ); // 选中后切换为亮色可点击按钮 if (this.rechargeYes && this.rechargeNo) { this.rechargeYes.visible = true; this.rechargeNo.visible = false; this.rechargeYes.eventMode = "static"; this.rechargeYes.cursor = "pointer"; } }; // 给金额图添加点击事件 amount.on("pointerdown", handleItemClick); // 给金额文本添加点击事件 amountText.on("pointerdown", handleItemClick); // 当starCount大于0时,才给星星图片文本添加点击事件 if (starCount > 0) { star.on("pointerdown", handleItemClick); starText.on("pointerdown", handleItemClick); } // 将创建的元素存储到数组 this.amountSprites.push(amount); this.starSprites.push(star); this.shineSprites.push(shine); // 按层级顺序添加到滚动容器(从下到上) this.scrollContainer.addChild(amount); // 最底层:金额图 this.scrollContainer.addChild(shine); // 中间层:发光边框 // 只有当starCount大于0时,才添加星星图片文本到容器 if (starCount > 0) { this.scrollContainer.addChild(star); // 最上层:五角星 this.scrollContainer.addChild(starText); // 星星数量文本 } this.scrollContainer.addChild(amountText); // 金额文本 } // === 添加滚动功能 === if (scrollableHeight > 0) { // 只有需要滚动时才添加滚动功能 let isDragging = false; let lastY = 0; let currentScrollY = 0; // 鼠标/触摸按下事件 this.scrollContainer.interactive = true; this.scrollContainer.on("mousedown", (event) => { isDragging = true; lastY = event.data.global.y; }); this.scrollContainer.on("touchstart", (event) => { isDragging = true; lastY = event.data.global.y; }); // 鼠标/触摸移动事件 this.scrollContainer.on("mousemove", (event) => { if (isDragging) { const deltaY = event.data.global.y - lastY; lastY = event.data.global.y; // 更新滚动位置,限制在可滚动范围内 currentScrollY += deltaY; currentScrollY = Math.max( -scrollableHeight, Math.min(0, currentScrollY), ); this.scrollContainer.y = currentScrollY; } }); this.scrollContainer.on("touchmove", (event) => { if (isDragging) { const deltaY = event.data.global.y - lastY; lastY = event.data.global.y; // 更新滚动位置,限制在可滚动范围内 currentScrollY += deltaY; currentScrollY = Math.max( -scrollableHeight, Math.min(0, currentScrollY), ); this.scrollContainer.y = currentScrollY; } }); // 鼠标/触摸释放事件 this.scrollContainer.on("mouseup", () => { isDragging = false; }); this.scrollContainer.on("touchend", () => { isDragging = false; }); this.scrollContainer.on("mouseupoutside", () => { isDragging = false; }); this.scrollContainer.on("touchendoutside", () => { isDragging = false; }); // 鼠标滚轮事件 this.scrollContainer.on("wheel", (event) => { const scrollAmount = event.deltaY > 0 ? 30 : -30; // 滚轮滚动量 // 更新滚动位置,限制在可滚动范围内 currentScrollY += scrollAmount; currentScrollY = Math.max( -scrollableHeight, Math.min(0, currentScrollY), ); this.scrollContainer.y = currentScrollY; }); } // === 充值按钮:亮色(可点)与灰色(不可点)切换 === const rechargeYes = new Sprite(Texture.from("assets/UIShop/UI1_09.png")); // 可点击亮色图 rechargeYes.width *= this.app.rat; rechargeYes.height *= this.app.rat; rechargeYes.anchor.set(0.5, 0.5); rechargeYes.position.set(-20, 140); rechargeYes.visible = false; // 初始隐藏 rechargeYes.eventMode = "static"; // 启用交互 rechargeYes.cursor = "pointer"; const rechargeNo = new Sprite(Texture.from("assets/UIShop/UI1_09_2.png")); // 不可点击灰色图 rechargeNo.width *= this.app.rat; rechargeNo.height *= this.app.rat; rechargeNo.anchor.set(0.5, 0.5); rechargeNo.position.set(-20, 140); rechargeNo.visible = true; // 初始显示 rechargeNo.eventMode = "none"; rechargeNo.cursor = "default"; // 创建按钮文字 - 保持你的本地化逻辑 this.depositText2 = Object.assign( new Text("嘟嘟嘟", { fontFamily: "Arial", fontSize: 25, fill: 0xffffff, align: "center", stroke: "#FFA500", }), { anchor: { x: 0.5, y: 0.5 } } ); // 灰色按钮的文字 const depositTextNo = Object.assign( new Text("嘟嘟嘟", { fontFamily: "Arial", fontSize: 25, fill: 0xcccccc, // 灰色文字 align: "center", }), { anchor: { x: 0.5, y: 0.5 } } ); this.depositText2.position.set(0, -5); // 相对于亮色按钮的位置 depositTextNo.position.set(0, -5); // 相对于灰色按钮的位置 rechargeYes.addChild(this.depositText2); rechargeNo.addChild(depositTextNo); // 添加到主容器 this.mainContainer.addChild(rechargeYes, rechargeNo); this.rechargeYes = rechargeYes; this.rechargeNo = rechargeNo; // 保存灰色按钮文字引用 this.depositTextNo = depositTextNo; // 绑定点击事件 rechargeYes.on("pointerdown", async () => { // 先检查是否选择金额 if (this.selectedIndex === -1) return; // 设置回调:当用户在银行弹窗点击【确认】时执行的操作 UIBankData.onPaymentRequest = async (selectedBank) => { // 执行支付请求 await this.sendPaymentRequest(selectedBank); // 关闭银行弹窗 UIBankData.hide(); }; // 显示银行弹窗(传入当前商品 ID) await UIBankData.showForGoods(this.id); }); // =======支付成功展示容器开始========= this.paymentSuccessContainer = new Container(); this.paymentSuccessContainer.visible = false; // 初始隐藏 this.paymentSuccessContainer.zIndex = 200; // 最高层级 this.paymentSuccessContainer.eventMode = "static"; // 启用交互 // 创建全屏透明背景 const successOverlay = new Graphics(); successOverlay.beginFill(0x000000, 0.01); // 透明 successOverlay.drawRect(-375, -667, 750, 1334); successOverlay.endFill(); this.paymentSuccessContainer.addChild(successOverlay); // 创建支付金额文本 this.paymentAmountText = new Text("", { fontFamily: "Arial", fontSize: 60, fill: 0xffff00, // 黄色 align: "center", fontWeight: "bold", stroke: "#000000", strokeThickness: 4, }); this.paymentAmountText.anchor.set(0.5); this.paymentAmountText.position.set(0, 0); this.paymentSuccessContainer.addChild(this.paymentAmountText); // 创建确认按钮 this.createPaymentConfirmButton(); // 点击任意位置隐藏支付成功展示 this.paymentSuccessContainer.on("pointerdown", (event) => { // 检查点击的是否是确认按钮,如果不是则隐藏 if ( !event.target || !event.target.parent || event.target.parent !== this.paymentConfirmButton ) { this.hidePaymentSuccess(); } }); // 将支付成功容器添加到根容器 this.container.addChild(this.paymentSuccessContainer); // =======支付成功展示容器结束========= this.depositHistory = new Sprite(Texture.from("assets/UIShop/UI1_05.png")); //历史记录图按钮 this.depositHistory.width *= this.app.rat; this.depositHistory.height *= this.app.rat; this.depositHistory.anchor.set(0.5, 0.5); this.depositHistory.position.set(this.overallWidth/2-110, this.overallHeight/2-50); this.depositHistory.interactive = true; this.depositHistory.buttonMode = true; this.mainContainer.addChild(this.depositHistory); const threeStripes = new Sprite(Texture.from("assets/UIShop/UI1_07.png")); //三条杠图(历史) threeStripes.width *= this.app.rat; threeStripes.height *= this.app.rat; threeStripes.anchor.set(0.5, 0.5); threeStripes.position.set(this.overallWidth/2-160, this.overallHeight/2-50); threeStripes.interactive = true; // 添加交互 threeStripes.buttonMode = true; // 添加按钮模式 this.depositHistoryText = Object.assign( //提示历史文字(主界面点击的历史) new Text("haha", { fontFamily: "Arial", fontSize: 12, fill: 0xd87910, align: "center", }), { anchor: { x: 0.5, y: 0.5 }, position: { x: this.overallWidth/2-105, y: this.overallHeight/2-50 } }, ); this.depositHistoryText.interactive = true; // 添加交互 this.depositHistoryText.buttonMode = true; // 添加按钮模式 this.mainContainer.addChild(threeStripes, this.depositHistoryText); // 创建统一的点击处理函数 const handleHistoryClick = async () => { // 如果支付弹窗已显示,忽略点击 if (this.bankPopupContainer && this.bankPopupContainer.visible) { return; } console.log("depositHistory 被点击了"); await this.SendHistoryData(); }; // 为所有三个元素添加点击事件 this.depositHistory.on("pointerdown", handleHistoryClick); threeStripes.on("pointerdown", handleHistoryClick); this.depositHistoryText.on("pointerdown", handleHistoryClick); // === 历史记录弹窗开始=== this.historyListContainer = new Container(); this.historyListContainer.visible = false; // 默认隐藏 this.historyListContainer.zIndex = 100;//内容透明度 this.historyListContainer.position.set( this.overallWidth * -0.35, // 距离左侧 this.overallHeight * -0.3 // 距离顶部 ); // 背景图 const recordBg = new Sprite(Texture.from("assets/UIShop/商店底5.png")); recordBg.anchor.set(0.5, 0.5); recordBg.width = this.overallWidth * 1.2; recordBg.height = this.overallHeight * 1; recordBg.position.set( this.overallWidth * 0.35, this.overallHeight* 0.3, ); this.historyText = Object.assign( new Text("haha", { fontFamily: "Arial", fontSize: 20, fill: 0xfff1a5, align: "center", }), { anchor: { x: 0.5, y: 0.5 }, position: { x: this.overallWidth* 0.35, y: this.overallHeight* -0.14} }, ); this.historyListContainer.addChild(recordBg, this.historyText); // 关闭按钮 const closeHistory = new Sprite(Texture.from("assets/UIShop/UI1_03.png")); closeHistory.width *= this.app.rat; closeHistory.height *= this.app.rat; closeHistory.position.set( this.overallWidth * 0.7, this.overallHeight* -0.1, ); closeHistory.eventMode = "static"; closeHistory.cursor = "pointer"; closeHistory.on("pointerdown", () => { this.historyListContainer.visible = false; if (this.blockBg) this.blockBg.visible = false; this.enableMainContainerInteractivity(true); // 恢复主界面操作 if (this.selectedAmountValue > 0) { this.inputAmountText.visible = false; // 隐藏提示文字 } }); this.historyListContainer.addChild(closeHistory); this.container.addChild(this.historyListContainer); // === 历史记录弹窗结束 === // === 弹窗与阴影遮罩 === //黑幕 let blockBg = new BlackMaskBg({ parent: this.container }); this.blockBg=blockBg; const shopBg3 = new Sprite(Texture.from("assets/UIShop/商店底3.png")); shopBg3.width = 500; shopBg3.height = 300; shopBg3.position.set(0, 0); this.shopBg3Container = new Container(); this.shopBg3Container.position.set(-240, -140); this.shopBg3Container.addChild(shopBg3); this.container.addChild(this.shopBg3Container); this.introduceText = new Text("介绍背景", { fontFamily: "Arial", fontSize: 13, fill: 0xffffff, align: "center", stroke: " #000000", strokeThickness: 0, lineHeight: 25, }); this.introduceText.anchor.set(0.5); this.introduceText.position.set( shopBg3.width / 2 + 60, shopBg3.height / 2 - 5, ); this.shopBg3Container.addChild(this.introduceText); this.shopBgButton = new Sprite(Texture.from("assets/UIShop/UI1_09.png")); this.shopBgButton.width = 210; this.shopBgButton.height = 60; this.shopBgButton.position.set(-80, 100); this.shopBgButton.eventMode = "static"; this.shopBgButton.cursor = "pointer"; this.buttonText = new Text("哈咯", { fontSize: 28, fill: 0xffffff, align: "center", stroke: "#000000", strokeThickness: 2, }); this.buttonText.anchor.set(0.5); this.buttonText.position.set( this.shopBgButton.width / 2, this.shopBgButton.height / 2, ); this.shopBgButton.addChild(this.buttonText); this.shopBgButton.on("pointerdown", () => { // 点击按钮后隐藏弹窗 if (this.shopBg3Container) this.shopBg3Container.visible = false; if (this.shopBgButton) this.shopBgButton.visible = false; if (blockBg) blockBg.visible = false; if (this.closeButton) { this.closeButton.eventMode = "static"; this.closeButton.cursor = "pointer"; } this.enableMainContainerInteractivity(true); }); this.container.addChild(this.shopBgButton); // 只设置一次 pivot:围绕内容中心缩放 if (!this.isPivotInitialized) { this.mainContainer.pivot.set( this.CONTAINER_WIDTH / 2, this.CONTAINER_HEIGHT / 2, ); this.isPivotInitialized = true; } // 初始化状态 this.resetState(); this.localize(); this.isInist = true; } // 创建支付成功确认按钮 createPaymentConfirmButton() { // 创建确认按钮 this.paymentConfirmButton = new Sprite( Texture.from("assets/UIShop/UI1_09.png"), ); this.paymentConfirmButton.width = 200; this.paymentConfirmButton.height = 80; this.paymentConfirmButton.anchor.set(0.5, 0.5); this.paymentConfirmButton.position.set(5, 150); this.paymentConfirmButton.eventMode = "static"; this.paymentConfirmButton.cursor = "pointer"; // 创建按钮文字 this.confirmText = new Text("这是Confirm", { fontFamily: "Arial", fontSize: 30, fill: 0xffffff, align: "center", stroke: "#FFA500", }); this.confirmText.anchor.set(0.5, 0.5); this.confirmText.position.set(0, 0); this.paymentConfirmButton.addChild(this.confirmText); // 绑定点击事件 this.paymentConfirmButton.on("pointerdown", () => { this.hidePaymentSuccess(); }); // 添加到支付成功容器 this.paymentSuccessContainer.addChild(this.paymentConfirmButton); } // 显示支付成功动画 showPaymentSuccess(amount) { UIBankData.hide(); // 恢复主界面交互 this.enableMainContainerInteractivity(true); // 设置支付金额文本 显示数字 this.paymentAmountText.text = amount.toString(); // 显示支付成功容器 this.paymentSuccessContainer.visible = true; // 动画效果:透明到不透明,再放大 this.paymentAmountText.alpha = 0; this.paymentAmountText.scale.set(0.5); // 动画序列 const animate = () => { // 渐显 if (this.paymentAmountText.alpha < 1) { this.paymentAmountText.alpha += 0.05; requestAnimationFrame(animate); return; } // 放大 if (this.paymentAmountText.scale.x < 1.2) { this.paymentAmountText.scale.x += 0.02; this.paymentAmountText.scale.y += 0.02; requestAnimationFrame(animate); return; } // 缩小回正常 if (this.paymentAmountText.scale.x > 1) { this.paymentAmountText.scale.x -= 0.01; this.paymentAmountText.scale.y -= 0.01; requestAnimationFrame(animate); } }; // 开始动画 animate(); } // 隐藏支付成功展示 hidePaymentSuccess() { this.paymentSuccessContainer.visible = false; } // 启用或禁用主界面的交互性 enableMainContainerInteractivity(enable) { // 设置主容器内所有可交互元素的交互性 this.closeButton.eventMode = enable ? "static" : "none"; this.closeButton.cursor = enable ? "pointer" : "default"; // 设置金额框的交互性 for (const amount of this.amountSprites) { amount.eventMode = enable ? "static" : "none"; amount.cursor = enable ? "pointer" : "default"; } // 设置充值按钮的交互性 if (this.rechargeYes) { this.rechargeYes.eventMode = enable && this.selectedIndex !== -1 ? "static" : "none"; this.rechargeYes.cursor = enable && this.selectedIndex !== -1 ? "pointer" : "default"; } // 设置历史记录按钮的交互性 if (this.depositHistory) { this.depositHistory.eventMode = enable ? "static" : "none"; this.depositHistory.cursor = enable ? "pointer" : "default"; } // 设置清除输入按钮的交互性 const clearInput = this.mainContainer.children.find( (child) => child.texture && child.texture.textureCacheIds && child.texture.textureCacheIds.includes("assets/UIShop/UI1_17.png"), ); if (clearInput) { clearInput.eventMode = enable ? "static" : "none"; clearInput.cursor = enable ? "pointer" : "default"; } } // 清除选中状态 clearSelection() { this.inputDisplayText.visible = false; this.inputAmountText.visible = true; // 恢复提示文字 this.selectedIndex = -1; this.selectedAmountValue = 0; this.selectedStarCount = 0; this.rpText.text = `${this._rpLabel} 0`; // 恢复 rpText 为默认状态 for (const shine of this.shineSprites) { // 隐藏所有发光边框 shine.visible = false; } // 清除选择时切回灰色按钮 if (this.rechargeYes && this.rechargeNo) { this.rechargeYes.visible = false; this.rechargeNo.visible = true; this.rechargeYes.eventMode = "none"; this.rechargeYes.cursor = "default"; } } async show() { console.log(this.constructor.name + " 1"); if (!this.isInist) { await this.init(); } else { this.resetState(); } console.log(this.constructor.name + " 2"); this.container.visible = true; UIManager.hideLoading(); // 开启动画 //this.animateOpen(); } // 动画从中间向两边展开 animateOpen() { this.mainContainer.scale.set(0, 1); const duration = 500; const startTime = performance.now(); const tick = (currentTime) => { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); const easeProgress = 1 - Math.pow(1 - progress, 2); // 缓动效果 this.mainContainer.scale.x = easeProgress; if (progress < 1) { requestAnimationFrame(tick); } }; requestAnimationFrame(tick); } resetState() { if (this.shopBg3Container) this.shopBg3Container.visible = true; if (this.shopBgButton) this.shopBgButton.visible = true; if (this.blockBg) this.blockBg.visible = true; if (this.mainContainer) { this.mainContainer.alpha = 1; this.mainContainer.scale.set(1); } if (this.closeButton) { this.closeButton.eventMode = "none"; this.closeButton.cursor = "default"; } // 重置选择状态 this.clearSelection(); this.enableMainContainerInteractivity(false); } hide() { this.container.visible = false; } //本地化 async localize() { this.uiname = "uiShop"; await super.localize(); // 使用 setLocalWords 方法统一设置本地化文本 super.setLocalWords(this.buttonText, "Confirmation"); super.setLocalWords(this.introduceText, "introduce"); super.setLocalWords(this.depositText, "deposit"); super.setLocalWords(this.depositText2, "deposit"); super.setLocalWords(this.depositTextNo, "deposit"); super.setLocalWords(this.topUpAmountText, "topUpAmount"); super.setLocalWords(this.inputAmountText, "inputAmount"); super.setLocalWords(this.freeAmountText, "freeAmount"); super.setLocalWords(this.selectAmountText, "selectAmount"); super.setLocalWords(this.depositHistoryText, "depositHistory"); super.setLocalWords(this.confirmText, "confirm"); super.setLocalWords(this.historyText, "depositHistory"); // 使用动态货币符号 this._rpLabel = gameData.currencySign; this.rpText.text = `${this._rpLabel} 0`; this.inputAmountText.visible = true; // 历史记录本地化 if (this.historyTextObjects && this.historyTextObjects.length > 0) { this.historyTextObjects.forEach((recordTexts) => { if (recordTexts.amountLabel && recordTexts.amountLabel.localKey) { super.setLocalWords(recordTexts.amountLabel, recordTexts.amountLabel.localKey); } if (recordTexts.orderLabel && recordTexts.orderLabel.localKey) { super.setLocalWords(recordTexts.orderLabel, recordTexts.orderLabel.localKey); } if (recordTexts.timeLabel && recordTexts.timeLabel.localKey) { super.setLocalWords(recordTexts.timeLabel, recordTexts.timeLabel.localKey); } if (recordTexts.statusLabel && recordTexts.statusLabel.localKey) { super.setLocalWords(recordTexts.statusLabel, recordTexts.statusLabel.localKey); } if (recordTexts.statusFinished && recordTexts.statusFinished.localKey) { super.setLocalWords(recordTexts.statusFinished, recordTexts.statusFinished.localKey); } if (recordTexts.statusProcessing && recordTexts.statusProcessing.localKey) { super.setLocalWords(recordTexts.statusProcessing, recordTexts.statusProcessing.localKey); } if (recordTexts.statusWaiting && recordTexts.statusWaiting.localKey) { super.setLocalWords(recordTexts.statusWaiting, recordTexts.statusWaiting.localKey); } }); } // 无数据提示 if (this.noDataText) { super.setLocalWords(this.noDataText, "oDataText"); } } formatNumberWithUnit(value) { if (value == null || isNaN(value)) return "0"; let formatted; if (value >= 1_000_000_000_000) { formatted = (value / 1_000_000_000_000).toFixed(2).replace(/\.00$/, ""); return `${formatted}T`; } else if (value >= 1_000_000_000) { formatted = (value / 1_000_000_000).toFixed(2).replace(/\.00$/, ""); return `${formatted}B`; } else if (value >= 1_000_000) { formatted = (value / 1_000_000).toFixed(2).replace(/\.00$/, ""); return `${formatted}M`; } else if (value >= 1_000) { formatted = (value / 1_000).toFixed(2).replace(/\.00$/, ""); return `${formatted}K`; } else { return String(value); } } // 接口请求:获取商店商品列表 async SendShopData() { const requestData = { token: gameData.gameToken, playerIndex: gameData.playerDto.playerIndex, }; console.log("发送请求参数:", requestData); const response = await networkMgr.postMessage("getShopGoods", requestData); if (!response) { throw new Error("接口返回空数据"); } this.shopGoodsList = response.shopGoodsList || response["shopGoodsList"] || []; console.log("获取商店数据:", this.shopGoodsList); if (this.isInist) { this.localize(); } } // 获取银行数据 async preloadBankData() { if (this.shopGoodsList.length > 0) { try { const requestData = { token: gameData.gameToken, playerIndex: gameData.playerDto.playerIndex, goodsId: this.shopGoodsList[0].id, }; await networkMgr.postMessage("getPaymentBank", requestData); console.log("预加载银行数据完成"); } catch (e) { console.warn("预加载银行数据失败", e); } } } // 发送支付请求 async SendPaymentRequest() { if (!this.selectedBankData || !this.id) { console.error("未选择银行或商品"); return; } try { const requestData = { token: gameData.gameToken, playerIndex: gameData.playerDto.playerIndex, goodsId: this.id, bankId: this.selectedBankData.bankId, bankCode: this.selectedBankData.bankCode, }; console.log("发送支付请求参数:", requestData); const response = await networkMgr.postMessage("payment", requestData); if (!response) { throw new Error("支付接口返回空数据"); } console.log("支付接口返回:", response); if (response.result === 0) { console.log("支付成功,金额:", response.amount); // 显示支付成功动画 this.showPaymentSuccess(response.amount); } else { // 支付失败 console.error("支付失败:", response.msg); } } catch (error) { console.error("支付请求失败:", error); } } // 历史记录接口 async SendHistoryData(isInit = false) { try { const requestData = { token: gameData.gameToken, playerIndex: gameData.playerDto.playerIndex, }; console.log("发送历史请求参数:", requestData); const response = await networkMgr.postMessage( "getPaymentRecord", requestData, ); if (!response) { throw new Error("接口返回空数据"); } this.recordList = response.recordList || response["recordList"] || []; // 渲染历史记录列表 this.renderHistoryList(); // 如果不是初始化调用,显示弹窗 if (!isInit) { this.historyListContainer.visible = true; this.blockBg.visible = true; for (const shine of this.bankShineSprites) { shine.visible = false; } this.enableMainContainerInteractivity(false); } this.localize(); } catch (error) { console.error("获取历史记录失败:", error); this.recordList = []; // 渲染列表 this.renderHistoryList(); if (!isInit) { this.historyListContainer.visible = true; this.blockBg.visible = true; this.enableMainContainerInteractivity(false); } } } // 历史记录列表 renderHistoryList() { // 清空之前的记录文本对象 if (this.scrollContent) { this.scrollContent.removeChildren(); } this.historyTextObjects = []; // 配置 const listWidth = this.overallWidth * 0.7; const listHeight = this.overallHeight * 0.7; const itemHeight = this.overallHeight * 0.28; //每条记录的内容多高 const contentStartX = this.overallWidth *-0.01; const contentStartY = 0; // 重新创建滚动内容容器 this.scrollContent = new Container(); this.scrollContent.position.set(contentStartX, contentStartY); this.historyListContainer.addChild(this.scrollContent); // 如果没有数据,显示提示文字 if (!this.recordList || this.recordList.length === 0) { this.noDataText = new Text("暂无充值记录", { fontSize: 18, fill: 0x999999, }); this.noDataText.anchor.set(0.5); this.noDataText.position.set(listWidth / 2, 100); this.scrollContent.addChild(this.noDataText); return; } // 有数据时遍历生成每一条记录 this.recordList.forEach((record, index) => { const y = index * itemHeight; // 为每条记录创建一个对象来存储所有文本元素 const recordTexts = {}; // 圆角背景框 const bg = new Graphics(); bg.lineStyle(2, 0x7d503a, 0.6); // 边框颜色 bg.beginFill(0x7d503a, 0.3); // 背景色 bg.drawRoundedRect( 10, // x y + 5, // y listWidth - 15, // 宽:左右各留边距 itemHeight - 10, // 高:上下留空 18, // 圆角半径 ); bg.endFill(); this.scrollContent.addChild(bg); // 时间格式化 const date = new Date(record.createDate); const formattedTime = date.toLocaleString("en-US", { month: "numeric", day: "numeric", year: "numeric", hour: "numeric", minute: "2-digit", second: "2-digit", hour12: true, }); // 充值金额标签 recordTexts.amountLabel = new Text("Top up amount", { fontSize: 13, fill: 0xb88e7e, }); recordTexts.amountLabel.position.set(20, y + 12); recordTexts.amountLabel.localKey = "amountText"; // 添加本地化标识 // 充值金额值 recordTexts.amountValue = new Text(`${record.amount.toLocaleString()}`, { //recordTexts.amountValue = new Text(`${this._rpLabel} ${record.amount.toLocaleString()}`, { fontSize: 13, fill: 0xe1ae68, }); recordTexts.amountValue.position.set(180, y + 12); // 订单标签 recordTexts.orderLabel = new Text("Recharge Order", { fontSize: 13, fill: 0xb88e7e, }); recordTexts.orderLabel.position.set(20, y + 32); recordTexts.orderLabel.localKey = "rechargeOrderText"; // 订单号 recordTexts.orderId = new Text(record.id, { fontSize: 13, fill: 0xb77760, }); recordTexts.orderId.position.set(180, y + 32); // 时间标签 recordTexts.timeLabel = new Text("Top up time", { fontSize: 13, fill: 0xb88e7e, }); recordTexts.timeLabel.position.set(20, y + 52); recordTexts.timeLabel.localKey = "rechargeTimeText"; // 时间值 recordTexts.timeValue = new Text(formattedTime, { fontSize: 13, fill: 0xb77760, }); recordTexts.timeValue.position.set(180, y + 52); // 状态标签 recordTexts.statusLabel = new Text("Order status", { fontSize: 13, fill: 0xb88e7e, }); recordTexts.statusLabel.position.set(20, y + 72); recordTexts.statusLabel.localKey = "statusText"; // 状态文本 recordTexts.statusFinished = new Text("已成功", { fontSize: 12, fill: 0x00ff00, }); recordTexts.statusFinished.position.set(180, y + 72); recordTexts.statusFinished.visible = record.status === "1"; recordTexts.statusFinished.localKey = "status_1"; recordTexts.statusProcessing = new Text("在等待处理", { fontSize: 12, fill: 0xffff00, }); recordTexts.statusProcessing.position.set(180, y + 72); recordTexts.statusProcessing.visible = record.status === "0"; recordTexts.statusProcessing.localKey = "status_0"; recordTexts.statusWaiting = new Text("失败", { fontSize: 12, fill: 0xaa0000, }); recordTexts.statusWaiting.position.set(180, y + 72); recordTexts.statusWaiting.visible = !( record.status === "1" || record.status === "0" ); recordTexts.statusWaiting.localKey = "status_2"; // 添加到滚动容器 this.scrollContent.addChild( recordTexts.amountLabel, recordTexts.amountValue, recordTexts.orderLabel, recordTexts.orderId, recordTexts.timeLabel, recordTexts.timeValue, recordTexts.statusLabel, recordTexts.statusFinished, recordTexts.statusProcessing, recordTexts.statusWaiting, ); // 存储到数组 this.historyTextObjects.push(recordTexts); // 复制图标(点击复制订单号) const copyIcon = new Sprite(Texture.from("assets/UIShop/复制.png")); copyIcon.width = 55 * this.app.rat; copyIcon.height = 55 * this.app.rat; copyIcon.anchor.set(0.5); copyIcon.position.set(listWidth - 40, y + itemHeight / 2); // 靠右居中 copyIcon.eventMode = "static"; copyIcon.cursor = "pointer"; copyIcon.on("pointerdown", (e) => { e.stopPropagation(); navigator.clipboard .writeText(record.id) .then(() => { console.log(`已复制订单号: ${record.id}`); copyIcon.tint = 0x00ff00; setTimeout(() => { copyIcon.tint = 0xffffff; }, 300); }) .catch((err) => { alert("复制失败,请手动选择文本复制"); console.warn("Clipboard error:", err); }); }); this.scrollContent.addChild(copyIcon); }); // 限制可见范围 const clipMask = new Graphics(); clipMask.beginFill(0x000000, 0.01); clipMask.drawRect(0, 0, listWidth, listHeight); clipMask.endFill(); clipMask.position.set(0, 0); this.historyListContainer.addChild(clipMask); this.scrollContent.mask = clipMask; // 添加拖拽滚动功能 this.setupHistoryScroll(); } // 设置历史记录滚动功能 setupHistoryScroll() { const listHeight = 250; // 显示区域高度 const itemHeight = 95; // 每条记录的高度 let isDragging = false; let dragStartY = 0; let scrollStartY = 0; this.app.view.removeEventListener( "pointermove", this.handleHistoryPointerMove, ); this.app.view.removeEventListener("pointerup", this.handleHistoryPointerUp); this.app.view.removeEventListener( "pointerupoutside", this.handleHistoryPointerUp, ); this.handleHistoryPointerMove = (e) => { if (!isDragging) return; const dy = e.clientY - dragStartY; let newY = scrollStartY + dy; const maxScrollUp = 0; const totalItemsHeight = this.recordList.length * itemHeight; const maxScrollDown = listHeight - totalItemsHeight; if (newY > maxScrollUp) newY = maxScrollUp; else if (newY < maxScrollDown) newY = maxScrollDown; this.scrollContent.y = newY; }; this.handleHistoryPointerUp = () => { isDragging = false; this.scrollContent.cursor = "grab"; }; // 设置滚动容器的交互 this.scrollContent.eventMode = "static"; this.scrollContent.cursor = "grab"; this.scrollContent.on("pointerdown", (event) => { isDragging = true; dragStartY = event.global.y; scrollStartY = this.scrollContent.y; this.scrollContent.cursor = "grabbing"; event.stopPropagation(); }); // 绑定全局事件 this.app.view.addEventListener( "pointermove", this.handleHistoryPointerMove, ); this.app.view.addEventListener("pointerup", this.handleHistoryPointerUp); this.app.view.addEventListener( "pointerupoutside", this.handleHistoryPointerUp, ); } // 提供给外部 async sendPaymentRequest(bankData) { if (!bankData || !this.id) { console.error("缺少必要参数:bankData 或 goodsId"); return; } try { const requestData = { token: gameData.gameToken, playerIndex: gameData.playerDto.playerIndex, goodsId: this.id, bankId: bankData.bankId, bankCode: bankData.bankCode, }; const response = await networkMgr.postMessage("payment", requestData); if (response && response.result === 0) { console.log("支付成功,金额:", response.amount); this.showPaymentSuccess(response.amount); } else { console.error("支付失败:", response?.msg || "未知错误"); } } catch (error) { console.error("支付请求异常:", error); } } } export const UIShop = new uiShop();
最新发布
12-10
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值