This commit is contained in:
“xHuPo” 2025-05-23 18:57:11 +08:00
parent a45ddf13d5
commit bcd986e3f7
46 changed files with 6166 additions and 454 deletions

View file

@ -0,0 +1,169 @@
// otp-add/index.js
import { createOTP } from '../../services/otp';
Page({
data: {
form: {
name: '',
issuer: '',
secret: '',
algorithm: 'SHA1',
digits: 6,
period: 30
},
algorithms: ['SHA1', 'SHA256', 'SHA512'],
digitOptions: [6, 8],
periodOptions: [30, 60],
submitting: false,
scanMode: false
},
// 处理输入变化
handleInputChange(e) {
const { field } = e.currentTarget.dataset;
const { value } = e.detail;
this.setData({
[`form.${field}`]: value
});
},
// 处理选择器变化
handlePickerChange(e) {
const { field } = e.currentTarget.dataset;
const { value } = e.detail;
const options = this.data[`${field}Options`] || this.data[field];
const selectedValue = options[value];
this.setData({
[`form.${field}`]: selectedValue
});
},
// 扫描二维码
handleScanQRCode() {
this.setData({ scanMode: true });
wx.scanCode({
scanType: ['qrCode'],
success: (res) => {
try {
// 解析otpauth://协议的URL
const url = res.result;
if (url.startsWith('otpauth://totp/')) {
const parsedUrl = new URL(url);
const path = parsedUrl.pathname.substring(1); // 移除开头的斜杠
// 解析路径中的issuer和name
let issuer = '';
let name = path;
if (path.includes(':')) {
const parts = path.split(':');
issuer = parts[0];
name = parts[1];
}
// 从查询参数中获取其他信息
const secret = parsedUrl.searchParams.get('secret') || '';
const algorithm = parsedUrl.searchParams.get('algorithm') || 'SHA1';
const digits = parseInt(parsedUrl.searchParams.get('digits') || '6');
const period = parseInt(parsedUrl.searchParams.get('period') || '30');
// 如果查询参数中有issuer优先使用
if (parsedUrl.searchParams.get('issuer')) {
issuer = parsedUrl.searchParams.get('issuer');
}
this.setData({
form: {
name,
issuer,
secret,
algorithm,
digits,
period
}
});
wx.showToast({
title: '二维码解析成功',
icon: 'success'
});
} else {
wx.showToast({
title: '不支持的二维码格式',
icon: 'none'
});
}
} catch (err) {
wx.showToast({
title: '二维码解析失败',
icon: 'none'
});
}
},
fail: () => {
wx.showToast({
title: '扫描取消',
icon: 'none'
});
},
complete: () => {
this.setData({ scanMode: false });
}
});
},
// 提交表单
handleSubmit() {
const { form } = this.data;
// 表单验证
if (!form.name) {
wx.showToast({
title: '请输入名称',
icon: 'none'
});
return;
}
if (!form.secret) {
wx.showToast({
title: '请输入密钥',
icon: 'none'
});
return;
}
this.setData({ submitting: true });
createOTP(form)
.then(() => {
wx.showToast({
title: '添加成功',
icon: 'success'
});
// 返回上一页
setTimeout(() => {
wx.navigateBack();
}, 1500);
})
.catch(err => {
wx.showToast({
title: err.message || '添加失败',
icon: 'none'
});
})
.finally(() => {
this.setData({ submitting: false });
});
},
// 取消
handleCancel() {
wx.navigateBack();
}
});