import router from '@ohos.router';
import promptAction from '@ohos.promptAction';
import data_preferences from '@ohos.data.preferences';
@Entry
@Component
struct NumberBaseConverterPage {
@State inputNumber: string = '10'; // 提供默认值
@State inputBase: number = 10;
@State binaryResult: string = '等待计算...';
@State octalResult: string = '等待计算...';
@State decimalResult: string = '等待计算...';
@State hexResult: string = '等待计算...';
@State base64Result: string = '等待计算...';
@State customBase: number = 16;
@State customResult: string = '等待计算...';
@State historyList: string[] = [];
@State showHistory: boolean = false;
// 可选的进制列表
private baseOptions: string[] = ['2', '8', '10', '16'];
private customBaseOptions: string[] = ['2','3','4','5','6','7','8','9','10',
'11','12','13','14','15','16','32','36'];
aboutToAppear() {
this.loadHistory();
// 页面加载时自动计算默认值的转换结果
setTimeout(() => {
this.convertNumber();
}, 100);
}
convertNumber() {
console.log('开始转换: ' + this.inputNumber + ' (base: ' + this.inputBase + ')');
if (!this.inputNumber) {
promptAction.showToast({ message: '请输入要转换的数字' });
console.log('未输入数字');
return;
}
try {
// 先尝试直接转换,再进行严格验证
let decimalValue: number = parseInt(this.inputNumber, this.inputBase);
if (isNaN(decimalValue)) {
// 如果直接转换失败,进行严格验证找出问题
if (!this.isValidNumber(this.inputNumber, this.inputBase)) {
throw new Error('输入的数字与所选进制不兼容');
}
throw new Error('无效的数字或进制');
}
console.log('十进制值: ' + decimalValue);
// 计算各种进制结果
// 使用setTimeout确保在主线程上更新状态
setTimeout(() => {
this.binaryResult = decimalValue.toString(2);
this.octalResult = decimalValue.toString(8);
this.decimalResult = decimalValue.toString(10);
this.hexResult = decimalValue.toString(16).toUpperCase();
this.base64Result = this.convertToBase64(this.inputNumber);
this.customResult = decimalValue.toString(this.customBase);
console.log('转换结果: binary=' + this.binaryResult + ', octal=' + this.octalResult + ', decimal=' + this.decimalResult + ', hex=' + this.hexResult + ', base64=' + this.base64Result + ', custom=' + this.customResult);
promptAction.showToast({ message: '转换完成' });
}, 0);
this.saveToHistory(this.inputNumber, this.inputBase);
} catch (error) {
console.error('转换错误:', error);
promptAction.showToast({ message: error.message || '转换错误' });
// 出错时设置为错误信息,而不是保持原样
setTimeout(() => {
this.binaryResult = '转换失败';
this.octalResult = '转换失败';
this.decimalResult = '转换失败';
this.hexResult = '转换失败';
this.base64Result = '转换失败';
this.customResult = '转换失败';
}, 0);
}
}
// 改进的Base64转换方法
private convertToBase64(str: string): string {
try {
// 尝试使用简化的方式处理数字到Base64的转换
if (/^\d+$/.test(str)) {
const num = parseInt(str);
if (!isNaN(num)) {
const base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let result = '';
let i = 0;
let bytes = new ArrayBuffer(4);
let view = new DataView(bytes);
view.setUint32(0, num);
while (i < 4) {
const char1 = view.getUint8(i++);
const char2 = i < 4 ? view.getUint8(i++) : 0;
const char3 = i < 4 ? view.getUint8(i++) : 0;
const enc1 = char1 >> 2;
const enc2 = ((char1 & 3) << 4) | (char2 >> 4);
const enc3 = ((char2 & 15) << 2) | (char3 >> 6);
const enc4 = char3 & 63;
result += base64chars.charAt(enc1) + base64chars.charAt(enc2);
result += i > 3 ? '==' : i > 2 ? '=' : base64chars.charAt(enc3);
result += i > 2 ? '' : base64chars.charAt(enc4);
}
return result;
}
}
// 使用原始的Base64实现
const base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let result = '';
let i = 0;
let pad = 0;
let char1: number, char2: number, char3: number;
let enc1: number, enc2: number, enc3: number, enc4: number;
while (i < str.length) {
char1 = str.charCodeAt(i++) || 0;
char2 = i < str.length ? str.charCodeAt(i++) : 0;
char3 = i < str.length ? str.charCodeAt(i++) : 0;
pad = [0, 2, 1][str.length - i + 1] || 0;
enc1 = char1 >> 2;
enc2 = ((char1 & 3) << 4) | (char2 >> 4);
enc3 = ((char2 & 15) << 2) | (char3 >> 6);
enc4 = char3 & 63;
result += base64chars.charAt(enc1) + base64chars.charAt(enc2);
result += pad >= 2 ? '=' : base64chars.charAt(enc3);
result += pad >= 1 ? '=' : base64chars.charAt(enc4);
}
return result;
} catch (error) {
console.error('Base64转换错误:', error);
return '转换失败';
}
}
async loadHistory() {
try {
let preferences = await data_preferences.getPreferences(getContext(this), 'NumberBaseHistory');
let history = await preferences.get('history', '[]');
this.historyList = JSON.parse(history.toString());
} catch (error) {
console.error('Failed to load history');
}
}
async saveToHistory(number: string, base: number) {
const record = `${number} (${base}进制)`;
if (!number || this.historyList.includes(record)) {
return;
}
try {
this.historyList.unshift(record);
if (this.historyList.length > 10) {
this.historyList = this.historyList.slice(0, 10);
}
let preferences = await data_preferences.getPreferences(getContext(this), 'NumberBaseHistory');
await preferences.put('history', JSON.stringify(this.historyList));
await preferences.flush();
} catch (error) {
console.error('Failed to save history');
}
}
// 验证输入数字是否与选择的进制兼容
private isValidNumber(number: string, base: number): boolean {
// 处理特殊情况:空字符串
if (!number) return false;
// 定义每个进制的有效字符
let validChars: string;
switch (base) {
case 2:
validChars = '01';
break;
case 8:
validChars = '01234567';
break;
case 10:
validChars = '0123456789';
break;
case 16:
validChars = '0123456789ABCDEFabcdef';
break;
default:
// 对于其他进制,生成有效的字符集
validChars = '';
for (let i = 0; i < base; i++) {
if (i < 10) {
validChars += i.toString();
} else {
validChars += String.fromCharCode(55 + i); // 'A'-'Z'
validChars += String.fromCharCode(87 + i); // 'a'-'z'
}
}
}
// 检查每个字符是否有效
for (let char of number) {
if (!validChars.includes(char)) {
console.log('无效字符: ' + char + ' 在进制: ' + base);
return false;
}
}
return true;
}
// 简单的Base64实现(原方法,保留作为参考)
private simpleBase64(str: string): string {
const base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
let result = '';
let i = 0;
let char1: number, char2: number, char3: number;
let enc1: number, enc2: number, enc3: number, enc4: number;
while (i < str.length) {
char1 = str.charCodeAt(i++);
char2 = str.charCodeAt(i++);
char3 = str.charCodeAt(i++);
enc1 = char1 >> 2;
enc2 = ((char1 & 3) << 4) | (char2 >> 4);
enc3 = ((char2 & 15) << 2) | (char3 >> 6);
enc4 = char3 & 63;
if (isNaN(char2)) {
enc3 = enc4 = 64;
} else if (isNaN(char3)) {
enc4 = 64;
}
result += base64chars.charAt(enc1) + base64chars.charAt(enc2) +
base64chars.charAt(enc3) + base64chars.charAt(enc4);
}
return result || '不支持该转换';
}
build() {
Scroll() {
Column() {
// 导航栏
Row() {
Text('数字进制转换')
.fontSize(20)
.fontWeight(FontWeight.Bold)
Blank()
Button('返回')
.fontSize(16)
.fontColor(Color.White)
.backgroundColor('#0D6EFD')
.borderRadius(8)
.height(36)
.onClick(() => {
router.back();
})
}
.width('100%')
.padding(10)
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
// 输入区域
Column() {
Text('输入数字:')
.fontSize(16)
.alignSelf(ItemAlign.Start)
.margin({ top: 20, bottom: 10 })
Row() {
TextInput({ text: this.inputNumber })
.width('60%')
.height(50)
.backgroundColor('#ff154364')
.fontColor(Color.White)
.borderRadius(8)
.fontSize(16)
.padding(10)
.onChange((value: string) => {
this.inputNumber = value;
})
// 使用TextPicker替代Picker
TextPicker({ range: this.baseOptions })
.width('30%')
.height(50)
.margin({ left: 10 })
.onChange((value: string | string[], index: number | number[]) => {
const selectedValue = typeof value === 'string' ? value : value[0];
this.inputBase = parseInt(selectedValue);
})
}
.width('100%')
Row() {
Button(this.showHistory ? '隐藏历史' : '显示历史')
.width('100%')
.height(40)
.margin({ top: 10 })
.onClick(() => {
this.showHistory = !this.showHistory;
})
}
.width('100%')
}
.width('90%')
.padding(10)
// 历史记录
if (this.showHistory) {
Column() {
Text('历史记录')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.alignSelf(ItemAlign.Start)
.margin({ top: 10, bottom: 5 })
List() {
ForEach(this.historyList, (item: string) => {
ListItem() {
Row() {
Text(item)
.fontSize(14)
.width('70%')
Button('使用')
.width('25%')
.height(30)
.fontSize(14)
.onClick(() => {
const match = item.match(/(.*) \((\d+)进制\)/);
if (match) {
this.inputNumber = match[1];
this.inputBase = parseInt(match[2]);
}
this.showHistory = false;
})
}
.width('100%')
.padding(5)
}
})
}
.width('100%')
.height(150)
.backgroundColor('#ff154364')
.borderRadius(8)
.padding(5)
.scrollBar(BarState.Auto)
}
.width('90%')
}
// 结果区域
Column() {
Text('转换结果')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.alignSelf(ItemAlign.Start)
.margin({ top: 20, bottom: 10 })
this.buildResultItem('二进制:', this.binaryResult)
this.buildResultItem('八进制:', this.octalResult)
this.buildResultItem('十进制:', this.decimalResult)
this.buildResultItem('十六进制:', this.hexResult)
this.buildResultItem('Base64:', this.base64Result)
Row() {
// 使用TextPicker替代Picker
TextPicker({ range: this.customBaseOptions })
.width('40%')
.height(50)
.onChange((value: string | string[], index: number | number[]) => {
const selectedValue = typeof value === 'string' ? value : value[0];
this.customBase = parseInt(selectedValue);
if (this.inputNumber) {
this.convertNumber();
}
})
Text(this.customResult || '等待计算...')
.width('60%')
.fontSize(16)
.margin({ left: 10 })
}
.width('100%')
.padding(10)
.margin({ top: 5, bottom: 5 })
.borderRadius(8)
.backgroundColor('#ff154364')
Button('开始转换')
.width('100%')
.height(50)
.margin({ top: 20 })
.onClick(() => {
this.convertNumber();
})
}
.width('90%')
.padding(10)
.margin({ top: 10 })
.backgroundColor('#ff154364')
.borderRadius(10)
}
.width('100%')
.height('100%')
.backgroundColor('#0D6EFD20')
}
.width('100%')
.height('100%')
}
@Builder
buildResultItem(label: string, value: string) {
Row() {
Text(label)
.width('40%')
.fontSize(16)
.fontWeight(FontWeight.Bold)
Text(value || '等待计算...')
.width('60%')
.fontSize(16)
.fontColor(Color.White)
}
.width('100%')
.padding(10)
.margin({ top: 5, bottom: 5 })
.borderRadius(8)
.backgroundColor('#ff154364')
}
}为什么此功能实现转换,但转换结果却不显示更新