代码页标识符 Code Page Identifiers

转载于:http://msdn.microsoft.com/zh-cn/library/dd317756.aspx

 

The following table defines the available code page identifiers.

Note    ANSI code pages can be different on different computers, or can be changed for a single computer, leading to data corruption. For the most consistent results, applications should use Unicode, such as UTF-8 or UTF-16, instead of a specific code page.

 

Identifier.NET NameAdditional information
037IBM037IBM EBCDIC US-Canada
437IBM437OEM United States
500IBM500IBM EBCDIC International
708ASMO-708Arabic (ASMO 708)
709 Arabic (ASMO-449+, BCON V4)
710 Arabic - Transparent Arabic
720DOS-720Arabic (Transparent ASMO); Arabic (DOS)
737ibm737OEM Greek (formerly 437G); Greek (DOS)
775ibm775OEM Baltic; Baltic (DOS)
850ibm850OEM Multilingual Latin 1; Western European (DOS)
852ibm852OEM Latin 2; Central European (DOS)
855IBM855OEM Cyrillic (primarily Russian)
857ibm857OEM Turkish; Turkish (DOS)
858IBM00858OEM Multilingual Latin 1 + Euro symbol
860IBM860OEM Portuguese; Portuguese (DOS)
861ibm861OEM Icelandic; Icelandic (DOS)
862DOS-862OEM Hebrew; Hebrew (DOS)
863IBM863OEM French Canadian; French Canadian (DOS)
864IBM864OEM Arabic; Arabic (864)
865IBM865OEM Nordic; Nordic (DOS)
866cp866OEM Russian; Cyrillic (DOS)
869ibm869OEM Modern Greek; Greek, Modern (DOS)
870IBM870IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2
874windows-874ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows)
875cp875IBM EBCDIC Greek Modern
932shift_jisANSI/OEM Japanese; Japanese (Shift-JIS)
936gb2312ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)
949ks_c_5601-1987ANSI/OEM Korean (Unified Hangul Code)
950big5ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)
1026IBM1026IBM EBCDIC Turkish (Latin 5)
1047IBM01047IBM EBCDIC Latin 1/Open System
1140IBM01140IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)
1141IBM01141IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro)
1142IBM01142IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro)
1143IBM01143IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro)
1144IBM01144IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro)
1145IBM01145IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro)
1146IBM01146IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro)
1147IBM01147IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro)
1148IBM01148IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro)
1149IBM01149IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro)
1200utf-16Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications
1201unicodeFFFEUnicode UTF-16, big endian byte order; available only to managed applications
1250windows-1250ANSI Central European; Central European (Windows)
1251windows-1251ANSI Cyrillic; Cyrillic (Windows)
1252windows-1252ANSI Latin 1; Western European (Windows)
1253windows-1253ANSI Greek; Greek (Windows)
1254windows-1254ANSI Turkish; Turkish (Windows)
1255windows-1255ANSI Hebrew; Hebrew (Windows)
1256windows-1256ANSI Arabic; Arabic (Windows)
1257windows-1257ANSI Baltic; Baltic (Windows)
1258windows-1258ANSI/OEM Vietnamese; Vietnamese (Windows)
1361JohabKorean (Johab)
10000macintoshMAC Roman; Western European (Mac)
10001x-mac-japaneseJapanese (Mac)
10002x-mac-chinesetradMAC Traditional Chinese (Big5); Chinese Traditional (Mac)
10003x-mac-koreanKorean (Mac)
10004x-mac-arabicArabic (Mac)
10005x-mac-hebrewHebrew (Mac)
10006x-mac-greekGreek (Mac)
10007x-mac-cyrillicCyrillic (Mac)
10008x-mac-chinesesimpMAC Simplified Chinese (GB 2312); Chinese Simplified (Mac)
10010x-mac-romanianRomanian (Mac)
10017x-mac-ukrainianUkrainian (Mac)
10021x-mac-thaiThai (Mac)
10029x-mac-ceMAC Latin 2; Central European (Mac)
10079x-mac-icelandicIcelandic (Mac)
10081x-mac-turkishTurkish (Mac)
10082x-mac-croatianCroatian (Mac)
12000utf-32Unicode UTF-32, little endian byte order; available only to managed applications
12001utf-32BEUnicode UTF-32, big endian byte order; available only to managed applications
20000x-Chinese_CNSCNS Taiwan; Chinese Traditional (CNS)
20001x-cp20001TCA Taiwan
20002x_Chinese-EtenEten Taiwan; Chinese Traditional (Eten)
20003x-cp20003IBM5550 Taiwan
20004x-cp20004TeleText Taiwan
20005x-cp20005Wang Taiwan
20105x-IA5IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5)
20106x-IA5-GermanIA5 German (7-bit)
20107x-IA5-SwedishIA5 Swedish (7-bit)
20108x-IA5-NorwegianIA5 Norwegian (7-bit)
20127us-asciiUS-ASCII (7-bit)
20261x-cp20261T.61
20269x-cp20269ISO 6937 Non-Spacing Accent
20273IBM273IBM EBCDIC Germany
20277IBM277IBM EBCDIC Denmark-Norway
20278IBM278IBM EBCDIC Finland-Sweden
20280IBM280IBM EBCDIC Italy
20284IBM284IBM EBCDIC Latin America-Spain
20285IBM285IBM EBCDIC United Kingdom
20290IBM290IBM EBCDIC Japanese Katakana Extended
20297IBM297IBM EBCDIC France
20420IBM420IBM EBCDIC Arabic
20423IBM423IBM EBCDIC Greek
20424IBM424IBM EBCDIC Hebrew
20833x-EBCDIC-KoreanExtendedIBM EBCDIC Korean Extended
20838IBM-ThaiIBM EBCDIC Thai
20866koi8-rRussian (KOI8-R); Cyrillic (KOI8-R)
20871IBM871IBM EBCDIC Icelandic
20880IBM880IBM EBCDIC Cyrillic Russian
20905IBM905IBM EBCDIC Turkish
20924IBM00924IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)
20932EUC-JPJapanese (JIS 0208-1990 and 0121-1990)
20936x-cp20936Simplified Chinese (GB2312); Chinese Simplified (GB2312-80)
20949x-cp20949Korean Wansung
21025cp1025IBM EBCDIC Cyrillic Serbian-Bulgarian
21027 (deprecated)
21866koi8-uUkrainian (KOI8-U); Cyrillic (KOI8-U)
28591iso-8859-1ISO 8859-1 Latin 1; Western European (ISO)
28592iso-8859-2ISO 8859-2 Central European; Central European (ISO)
28593iso-8859-3ISO 8859-3 Latin 3
28594iso-8859-4ISO 8859-4 Baltic
28595iso-8859-5ISO 8859-5 Cyrillic
28596iso-8859-6ISO 8859-6 Arabic
28597iso-8859-7ISO 8859-7 Greek
28598iso-8859-8ISO 8859-8 Hebrew; Hebrew (ISO-Visual)
28599iso-8859-9ISO 8859-9 Turkish
28603iso-8859-13ISO 8859-13 Estonian
28605iso-8859-15ISO 8859-15 Latin 9
29001x-EuropaEuropa 3
38598iso-8859-8-iISO 8859-8 Hebrew; Hebrew (ISO-Logical)
50220iso-2022-jpISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
50221csISO2022JPISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana)
50222iso-2022-jpISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI)
50225iso-2022-krISO 2022 Korean
50227x-cp50227ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)
50229 ISO 2022 Traditional Chinese
50930 EBCDIC Japanese (Katakana) Extended
50931 EBCDIC US-Canada and Japanese
50933 EBCDIC Korean Extended and Korean
50935 EBCDIC Simplified Chinese Extended and Simplified Chinese
50936 EBCDIC Simplified Chinese
50937 EBCDIC US-Canada and Traditional Chinese
50939 EBCDIC Japanese (Latin) Extended and Japanese
51932euc-jpEUC Japanese
51936EUC-CNEUC Simplified Chinese; Chinese Simplified (EUC)
51949euc-krEUC Korean
51950 EUC Traditional Chinese
52936hz-gb-2312HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ)
54936GB18030Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030)
57002x-iscii-deISCII Devanagari
57003x-iscii-beISCII Bengali
57004x-iscii-taISCII Tamil
57005x-iscii-teISCII Telugu
57006x-iscii-asISCII Assamese
57007x-iscii-orISCII Oriya
57008x-iscii-kaISCII Kannada
57009x-iscii-maISCII Malayalam
57010x-iscii-guISCII Gujarati
57011x-iscii-paISCII Punjabi
65000utf-7Unicode (UTF-7)
65001utf-8Unicode (UTF-8)
C:\own\app\python_code\.venv\Scripts\python.exe C:\own\app\python_code\work\IBL_click_all\full_automation.py 🚀 启动 Android 自动化测试框架... ℹ️ 应用已安装 📱 正在启动应用... 🔍 检测用户协议... 📄 用户协议页面已加载 👇 正在滚动协议内容... ✅ 第 7 次滑动后发现可点击的【I agree】按钮 ✅ 已点击【I agree】 💥 运行异常: AttributeError: 'AndroidAppExplorer' object has no attribute 'handle_printer_selection' 🧹 正在重置应用状态... ✅ 应用已卸载,状态重置完成 🔚 自动化流程全部完成 Process finished with exit code 0 from appium import webdriver from appium.options.android import UiAutomator2Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException, NoSuchElementException, ElementNotInteractableException import time import os # ==================== 配置参数 ==================== APK_PATH = r"C:\own\download\iPL5.3.10_signed.apk" APP_PACKAGE = "com.brother.ptouch.iprintandlabel" APP_ACTIVITY = ".module.home.home.HomeActivity" MAX_RESTORE_ATTEMPTS = 2 MAX_BACK_OFFICE_COUNT = 3 MAX_RUNTIME = 600 # 最大运行时间:10分钟 # ==================== 创建 WebDriver ==================== def create_driver(): options = UiAutomator2Options() options.set_capability("platformName", "Android") options.set_capability("deviceName", "emulator-5554") # 修改为你的设备名(adb devices 查看) options.set_capability("automationName", "UiAutomator2") options.set_capability("noReset", False) # 每次都清空状态 options.set_capability("fullReset", False) # 不使用完全重置 options.set_capability("autoGrantPermissions", True) options.set_capability("newCommandTimeout", 600) options.set_capability("appPackage", APP_PACKAGE) options.set_capability("appActivity", APP_ACTIVITY) return webdriver.Remote('http://localhost:4723', options=options) # ==================== 安装 APK(如果未安装)==================== def install_app_if_needed(driver, apk_path): if not driver.is_app_installed(APP_PACKAGE): print(f"📦 正在安装应用: {apk_path}") if not os.path.exists(apk_path): raise FileNotFoundError(f"APK 文件不存在: {apk_path}") driver.install_app(apk_path) print("✅ 安装完成") else: print("ℹ️ 应用已安装") # ==================== 卸载应用(用于重置状态)==================== def reset_app_state(driver): print("🧹 正在重置应用状态...") if driver.is_app_installed(APP_PACKAGE): try: driver.remove_app(APP_PACKAGE) print("✅ 应用已卸载,状态重置完成") except Exception as e: print(f"⚠️ 卸载失败: {e}") else: print("ℹ️ 应用未安装,无需卸载") # ==================== 主探索类 ==================== class AndroidAppExplorer: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) self.clicked_identifiers = set() self.recovery_history = [] self.restore_attempt_count = 0 self.start_time = time.time() def wait_for_page_load(self, timeout=10): """等待页面基本结构加载""" try: WebDriverWait(self.driver, timeout).until( EC.presence_of_element_located(( 'xpath', '//*[contains(@resource-id, "layout") or @class="android.widget.LinearLayout"]' )) ) time.sleep(1) except: pass def get_element_identifier(self, element): """生成唯一可读标识符""" parts = [] res_id = element.get_attribute("resourceId") text = element.get_attribute("text") content_desc = element.get_attribute("contentDescription") clazz = element.get_attribute("className") if res_id: parts.append(f"resId={res_id.split('/')[-1]}") if text and len(text) < 20: parts.append(f"text='{text}'") if content_desc: parts.append(f"desc='{content_desc}'") if clazz: simple_class = clazz.split('.')[-1] if simple_class not in ['View', 'ViewGroup']: parts.append(f"class={simple_class}") return " | ".join(parts) if parts else "unknown" def find_clickable_elements(self): """查找所有可点击且可见的元素""" xpath = '//*[(@clickable="true" or @focusable="true") and @displayed="true" and @enabled="true"]' try: elements = self.driver.find_elements('xpath', xpath) return [e for e in elements if e.is_displayed()] except: return [] def click_element_safely(self, element): """安全点击元素,防止重复点击""" identifier = self.get_element_identifier(element) if identifier in self.clicked_identifiers: return False try: # 滚动到可见 self.driver.execute_script("arguments[0].scrollIntoView(true);", element) time.sleep(0.5) element.click() print(f"🟢 点击成功: {identifier}") self.clicked_identifiers.add(identifier) time.sleep(1.5) return True except Exception as e: print(f"🔴 点击失败: {identifier}, 错误: {str(e)}") return False def is_popup_visible(self): """判断是否弹出浮层菜单(如 Spinner 下拉)""" try: # 常见浮层控件 popup_classes = [ 'android.widget.PopupWindow', 'android.widget.ListPopupWindow' ] for cls in popup_classes: if self.driver.find_elements('class name', cls): return True # CheckedTextView 出现在屏幕中间区域 items = self.driver.find_elements('class name', 'android.widget.CheckedTextView') for item in items: if item.is_displayed(): bounds = item.get_attribute("bounds") try: y1 = int(bounds.split(',')[1].split(']')[0]) if 200 < y1 < 1000: # 屏幕中上部 return True except: pass return False except: return False def handle_floating_popup(self): """处理浮层选择项(如 High / Low)""" if not self.is_popup_visible(): return False print("🎈 检测到浮层,尝试选择...") common_options = ["High", "Normal", "Low", "On", "Off", "Auto", "Cut Every Label"] for opt in common_options: try: elem = self.driver.find_element(By.XPATH, f'//android.widget.CheckedTextView[@text="{opt}"]') if elem.is_displayed(): elem.click() print(f"🪄 选择了浮层选项: {opt}") time.sleep(1.5) return True except: continue # 尝试点击第一个 try: first_item = self.driver.find_element( By.XPATH, '//android.widget.CheckedTextView[@displayed="true"][1]' ) first_item.click() print("🪄 选择了默认浮层项") time.sleep(1.5) return True except: print("❌ 无法选择浮层项,使用 back 关闭") try: self.driver.back() time.sleep(1) except: pass return False def handle_alert_popup(self): """处理系统或应用弹窗(如权限请求)""" alert_xpaths = [ '//android.widget.Button[contains(@text, "OK")]', '//android.widget.Button[contains(@text, "允许")]', '//android.widget.Button[contains(@text, "Allow")]', '//android.widget.Button[@text="YES"]' ] for xpath in alert_xpaths: try: btn = self.driver.find_element('xpath', xpath) if btn.is_displayed(): btn.click() print("✅ 自动处理了弹窗") time.sleep(1) return True except: continue return False def ensure_in_target_app(self): """确保当前在目标 App,支持短暂跳转(如浏览器)""" current_pkg = self.driver.current_package current_act = self.driver.current_activity if current_pkg == APP_PACKAGE: self.wait_for_page_load(1) return True allowed_packages = ["nexuslauncher", "chrome", "android", "packageinstaller"] if any(pkg in current_pkg.lower() for pkg in allowed_packages): print(f"⏸️ 暂时处于外部页面: {current_pkg}/{current_act}") # 记录恢复历史,防循环 key = (current_pkg, current_act) if self.recovery_history[-10:].count(key) >= 3: print("🛑 恢复循环检测,终止") return False self.recovery_history.append(key) try: self.driver.back() time.sleep(2) if self.driver.current_package == APP_PACKAGE: print("✅ 通过 back 返回目标 App") return True except: pass try: self.driver.activate_app(APP_PACKAGE) time.sleep(3) return self.driver.current_package == APP_PACKAGE except: return False return False def accept_user_agreement(self): """处理首次启动的用户协议(自动滚动 + 点击 I agree)""" print("🔍 检测用户协议...") try: # 等待协议标题出现 WebDriverWait(self.driver, 15).until( EC.presence_of_element_located(( 'xpath', '//*[contains(@text, "License Agreement") or contains(@text, "User")]' )) ) print("📄 用户协议页面已加载") # 定义查找“Agree”或“I agree”按钮的函数 def find_agree_button(): candidates = [ '//android.widget.Button[@text="Agree"]', '//android.widget.Button[@text="I agree"]', '//android.widget.Button[contains(@resource-id, "yes")]', ] for xpath in candidates: try: btn = self.driver.find_element(By.XPATH, xpath) if btn.is_displayed() and btn.is_enabled(): return btn except: continue return None # 先尝试直接点击(可能已经激活) agree_btn = find_agree_button() if agree_btn: print("✅ 发现【I agree】按钮,直接点击") agree_btn.click() time.sleep(3) return True # 否则开始滑动并轮询 print("👇 正在滚动协议内容...") for i in range(10): # 最多滑动10次 size = self.driver.get_window_size() x = size['width'] // 2 y_start = int(size['height'] * 0.8) y_end = int(size['height'] * 0.3) self.driver.swipe(x, y_start, x, y_end, 600) time.sleep(0.8) # 查找并尝试点击 agree_btn = find_agree_button() if agree_btn: print(f"✅ 第 {i + 1} 次滑动后发现可点击的【I agree】按钮") try: agree_btn.click() print("✅ 已点击【I agree】") time.sleep(3) return True except Exception as e: print(f"❌ 尝试点击失败: {e}") # 如果还找不到,用 uiautomator 强制点 try: self.driver.find_element( 'android uiautomator', 'new UiSelector().textContains("agree").clickable(true)' ).click() print("🪄 使用 uiautomator 强制点击【I agree】") time.sleep(3) return True except: print("❌ 无法找到或点击【I agree】按钮") return False except TimeoutException: print("🟢 未检测到用户协议,跳过") return True except Exception as e: print(f"⚠️ 协议处理异常: {type(e).__name__}: {e}") return False def explore_page(self): """主探索逻辑""" print("\n🔄 开始探索当前页面...") last_handled_popup = False explored_states = set() consecutive_back_count = 0 while True: if time.time() - self.start_time > MAX_RUNTIME: print("⏰ 探索超时,自动结束。") break if not self.ensure_in_target_app(): print("❌ 无法恢复至目标应用") break self.handle_alert_popup() if self.is_popup_visible() and not last_handled_popup: self.handle_floating_popup() last_handled_popup = True time.sleep(1) continue else: last_handled_popup = False elements = self.find_clickable_elements() if not elements: print("📭 当前页面无可点击元素") try: self.driver.back() print("🔙 返回上一页") time.sleep(2) consecutive_back_count += 1 if consecutive_back_count > MAX_BACK_OFFICE_COUNT: print("🏁 所有路径已探索完毕") break continue except: break # 页面指纹(activity + 前几个元素 ID/text) current_act = self.driver.current_activity element_fingerprint = "|".join(sorted([self.get_element_identifier(e) for e in elements[:5]])) page_key = f"{current_act}|{element_fingerprint[:60]}" if page_key in explored_states: print(f"🟡 已探索过此页面: {current_act}") try: self.driver.back() time.sleep(2) consecutive_back_count += 1 if consecutive_back_count > MAX_BACK_OFFICE_COUNT: print("🔚 探索完成") break continue except: break else: explored_states.add(page_key) consecutive_back_count = 0 clicked = False for elem in elements: if self.click_element_safely(elem): clicked = True break if not clicked: print("✅ 当前页无新元素可操作") try: self.driver.back() time.sleep(2) except: break def handle_printer_selection(self): """处理打印机选择页面:选择第一个可用设备 + 点击 Done""" print("🖨️ 检测是否需要选择打印机...") # 判断是否在打印机选择界面(根据常见特征) try: # 等待列表或标题出现 WebDriverWait(self.driver, 10).until( EC.presence_of_element_located(( 'xpath', '//android.widget.TextView[@text="Select Printer"] | ' '//android.widget.TextView[contains(@text, "Available Printers")]' )) ) print("✅ 进入打印机选择页面") # 尝试选择第一个非空的设备项 device_items = self.driver.find_elements( 'xpath', '//android.widget.CheckedTextView[@text and not(@text="")] | ' '//android.widget.TextView[@resource-id and @text and string-length(@text) > 2]' ) if device_items: first_device = device_items[0] try: first_device.click() print(f"✅ 选择了打印机: {first_device.get_attribute('text')}") except: print("🟡 无法点击设备项,可能已默认选中") else: print("ℹ️ 未发现可用打印机列表") # 查找并点击 Done 按钮(通常在右下角) done_buttons = [ '//android.widget.Button[@text="Done"]', '//android.widget.Button[@text="OK"]', '//android.widget.Button[contains(@resource-id, "ok_button")]', '//android.widget.Button[contains(@resource-id, "done")]' ] for xpath in done_buttons: try: done_btn = self.driver.find_element(By.XPATH, xpath) if done_btn.is_displayed() and done_btn.is_enabled(): done_btn.click() print("✅ 已点击【Done】进入主界面") time.sleep(3) return True except: continue # 如果没找到 Done,尝试返回键(兜底) print("⚠️ 未找到【Done】按钮,尝试返回") self.driver.back() time.sleep(2) return True except TimeoutException: print("🟢 无需选择打印机") return True except Exception as e: print(f"⚠️ 处理打印机选择失败: {e}") return True # 失败也不阻塞后续探索 # ==================== 主程序入口 ==================== if __name__ == "__main__": driver = None try: print("🚀 启动 Android 自动化测试框架...") # Step 1: 创建驱动 driver = create_driver() # Step 2: 安装 APK install_app_if_needed(driver, APK_PATH) # Step 3: 启动应用 print("📱 正在启动应用...") driver.activate_app(APP_PACKAGE) time.sleep(5) # Step 4: 创建探索器并处理初始化流程 explorer = AndroidAppExplorer(driver) # 依次处理初始化步骤 if not explorer.accept_user_agreement(): print("❌ 用户协议处理失败,终止运行") else: # 新增:处理打印机选择 explorer.handle_printer_selection() # Step 5: 开始探索 explorer.explore_page() except KeyboardInterrupt: print("\n👋 用户中断执行") except Exception as e: print(f"💥 运行异常: {type(e).__name__}: {e}") finally: # Step 6: 重置状态(卸载应用) if driver: reset_app_state(driver) driver.quit() print("🔚 自动化流程全部完成")
最新发布
10-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值