otp/pages/form/form.js
“xHuPo” 2b8870a40e init
2025-06-09 13:35:15 +08:00

196 lines
No EOL
4.7 KiB
JavaScript

// pages/form/form.js
const {
addToken,
parseURL,
validateToken,
showToast
} = require('../../utils/util');
Page({
/**
* 页面的初始数据
*/
data: {
type: 'totp', // 默认选择TOTP
isSubmitting: false // 防止重复提交
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 准备初始数据
const initialData = {
type: options.type || 'totp',
formData: {
issuer: '',
remark: '',
secret: '',
algo: 'SHA1',
digits: '6',
period: '30',
counter: '0'
},
pageReady: true // 直接设置为ready状态
};
// 如果有扫描结果,预处理数据
if (options.scan) {
try {
const scanData = decodeURIComponent(options.scan);
const parsedToken = parseURL(scanData);
if (parsedToken) {
initialData.type = parsedToken.type;
initialData.formData = {
issuer: parsedToken.issuer || '',
remark: parsedToken.remark || '',
secret: parsedToken.secret || '',
algo: parsedToken.algo || 'SHA1',
digits: parsedToken.digits || '6',
period: parsedToken.period || '30',
counter: parsedToken.counter || '0'
};
// 立即显示成功提示
wx.showToast({
title: '二维码解析成功',
icon: 'success',
duration: 1500
});
}
} catch (error) {
console.error('解析扫描数据失败:', error);
wx.showToast({
title: '无效的二维码数据',
icon: 'none',
duration: 1500
});
}
}
// 一次性设置所有数据
this.setData(initialData);
},
/**
* 处理类型切换
*/
onTypeChange: function(e) {
this.setData({
type: e.detail.value
});
},
/**
* 验证并格式化表单数据
*/
validateAndFormatForm: function(values) {
try {
// 基本字段验证
if (!values.issuer || !values.issuer.trim()) {
throw new Error('请输入服务名称');
}
if (!values.remark || !values.remark.trim()) {
throw new Error('请输入账号备注');
}
if (!values.secret || !values.secret.trim()) {
throw new Error('请输入密钥');
}
// 格式化数据
const tokenData = {
type: values.type,
issuer: values.issuer.trim(),
remark: values.remark.trim(),
secret: values.secret.trim().toUpperCase(),
algo: values.algo,
digits: parseInt(values.digits, 10)
};
// 类型特定字段
if (values.type === 'totp') {
const period = parseInt(values.period, 10);
if (isNaN(period) || period < 15 || period > 300) {
throw new Error('更新周期必须在15-300秒之间');
}
tokenData.period = period;
} else {
const counter = parseInt(values.counter, 10);
if (isNaN(counter) || counter < 0) {
throw new Error('计数器初始值必须大于等于0');
}
tokenData.counter = counter;
}
// 使用工具函数验证完整的令牌数据
const errors = validateToken(tokenData);
if (errors) {
throw new Error(errors.join('\n'));
}
return tokenData;
} catch (error) {
showToast(error.message, 'none');
return null;
}
},
/**
* 提交数据
*/
keySubmit: async function (e) {
// 防止重复提交
if (this.data.isSubmitting) {
return;
}
this.setData({ isSubmitting: true });
try {
const values = e.detail.value;
const tokenData = this.validateAndFormatForm(values);
if (!tokenData) {
this.setData({ isSubmitting: false });
return;
}
// 添加令牌
await addToken(tokenData);
// 显示成功提示
wx.showToast({
title: '添加成功',
icon: 'success',
mask: true,
duration: 800
});
// 获取页面事件通道
const eventChannel = this.getOpenerEventChannel();
// 通知上一页面刷新数据
if (eventChannel && typeof eventChannel.emit === 'function') {
eventChannel.emit('tokenAdded');
}
// 立即跳转到首页
wx.switchTab({
url: '/pages/index/index'
});
} catch (error) {
console.error('添加令牌失败:', error);
wx.showToast({
title: error.message || '添加失败',
icon: 'none',
duration: 2000
});
} finally {
this.setData({ isSubmitting: false });
}
},
// 扫描功能已移至主页面
})