mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-24 08:03:53 +08:00
@@ -154,7 +154,7 @@ export default {
|
||||
}).send()
|
||||
},
|
||||
// 获取公共配置
|
||||
getPubConfig(callback) {
|
||||
getPubConfig(callback, failCallback) {
|
||||
RequestService.sendRequest()
|
||||
.url(`${getServiceUrl()}/user/pub-config`)
|
||||
.method('GET')
|
||||
@@ -162,10 +162,16 @@ export default {
|
||||
RequestService.clearRequestTime();
|
||||
callback(res);
|
||||
})
|
||||
.fail((err) => {
|
||||
RequestService.clearRequestTime();
|
||||
if (failCallback) {
|
||||
failCallback(err);
|
||||
}
|
||||
})
|
||||
.networkFail((err) => {
|
||||
console.error('获取公共配置失败:', err);
|
||||
RequestService.reAjaxFun(() => {
|
||||
this.getPubConfig(callback);
|
||||
this.getPubConfig(callback, failCallback);
|
||||
});
|
||||
}).send();
|
||||
},
|
||||
@@ -177,7 +183,8 @@ export default {
|
||||
.data({
|
||||
phone: passwordData.phone,
|
||||
code: passwordData.code,
|
||||
password: passwordData.password
|
||||
password: passwordData.password,
|
||||
captchaId: passwordData.captchaId
|
||||
})
|
||||
.success((res) => {
|
||||
RequestService.clearRequestTime();
|
||||
@@ -192,5 +199,6 @@ export default {
|
||||
this.retrievePassword(passwordData, callback, failCallback);
|
||||
});
|
||||
}).send()
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export default {
|
||||
'login.requiredCaptcha': 'Captcha cannot be empty',
|
||||
'login.requiredMobile': 'Please enter a valid mobile phone number',
|
||||
'login.loginSuccess': 'Login successful!',
|
||||
|
||||
|
||||
// HeaderBar组件文本
|
||||
'header.smartManagement': 'Agents',
|
||||
'header.modelConfig': 'Models',
|
||||
@@ -38,7 +38,7 @@ export default {
|
||||
'mcpToolCall.copyResult': 'Copy Result',
|
||||
'mcpToolCall.noResultYet': 'No result yet',
|
||||
'mcpToolCall.loadingToolList': 'Loading tool list...',
|
||||
|
||||
|
||||
// Tool names
|
||||
'mcpToolCall.toolName.getDeviceStatus': 'View Device Status',
|
||||
'mcpToolCall.toolName.setVolume': 'Set Volume',
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
'mcpToolCall.toolName.snapshot': 'Screen Snapshot',
|
||||
'mcpToolCall.toolName.previewImage': 'Preview Image',
|
||||
'mcpToolCall.toolName.setDownloadUrl': 'Set Download URL',
|
||||
|
||||
|
||||
// Tool categories
|
||||
'mcpToolCall.category.audio': 'Audio',
|
||||
'mcpToolCall.category.display': 'Display',
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
'mcpToolCall.category.system': 'System',
|
||||
'mcpToolCall.category.assets': 'Assets',
|
||||
'mcpToolCall.category.deviceInfo': 'Device Info',
|
||||
|
||||
|
||||
// Table categories and properties
|
||||
'mcpToolCall.table.audioSpeaker': 'Audio Speaker',
|
||||
'mcpToolCall.table.screen': 'Screen',
|
||||
@@ -80,7 +80,7 @@ export default {
|
||||
'mcpToolCall.table.component': 'Component',
|
||||
'mcpToolCall.table.property': 'Property',
|
||||
'mcpToolCall.table.value': 'Value',
|
||||
|
||||
|
||||
'mcpToolCall.prop.volume': 'Volume',
|
||||
'mcpToolCall.prop.brightness': 'Brightness',
|
||||
'mcpToolCall.prop.theme': 'Theme',
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
'mcpToolCall.prop.url': 'URL',
|
||||
'mcpToolCall.prop.quality': 'Quality',
|
||||
'mcpToolCall.prop.question': 'Question',
|
||||
|
||||
|
||||
// Tool help texts
|
||||
'mcpToolCall.help.getDeviceStatus': 'View the current running status of the device, including volume, screen, battery and other information.',
|
||||
'mcpToolCall.help.setVolume': 'Adjust the volume of the device, please enter a value between 0-100.',
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
'mcpToolCall.help.snapshot': 'Take a screenshot of the current screen and upload it to the specified URL.',
|
||||
'mcpToolCall.help.previewImage': 'Preview images from the specified URL on the device screen.',
|
||||
'mcpToolCall.help.setDownloadUrl': 'Set the download address for device resource files.',
|
||||
|
||||
|
||||
// Other text
|
||||
'mcpToolCall.text.strong': 'Strong',
|
||||
'mcpToolCall.text.medium': 'Medium',
|
||||
@@ -231,7 +231,7 @@ export default {
|
||||
|
||||
// AddModelDialog component related
|
||||
'addModelDialog.requiredSupplier': 'Please select a supplier',
|
||||
|
||||
|
||||
// Register page related
|
||||
'register.title': 'Create Account',
|
||||
'register.welcome': 'Welcome to XiaoZhi AI',
|
||||
@@ -384,10 +384,12 @@ export default {
|
||||
'register.registerSuccess': 'Registration successful!',
|
||||
'register.registerFailed': 'Registration failed',
|
||||
'register.passwordsNotMatch': 'The two passwords do not match',
|
||||
'register.secondsLater': 'seconds later',
|
||||
|
||||
// Retrieve password page text
|
||||
'retrievePassword.title': 'Reset Password',
|
||||
'retrievePassword.welcome': 'PASSWORD RETRIEVE',
|
||||
'retrievePassword.subtitle': 'Retrieve Password',
|
||||
'retrievePassword.mobile': 'Mobile',
|
||||
'retrievePassword.mobilePlaceholder': 'Please enter mobile number',
|
||||
'retrievePassword.captcha': 'Verification Code',
|
||||
@@ -399,6 +401,7 @@ export default {
|
||||
'retrievePassword.confirmNewPassword': 'Confirm New Password',
|
||||
'retrievePassword.confirmNewPasswordPlaceholder': 'Please confirm new password',
|
||||
'retrievePassword.getMobileCaptcha': 'Get Verification Code',
|
||||
'retrievePassword.resetButton': 'Reset Password',
|
||||
'retrievePassword.updateButton': 'Update Now',
|
||||
'retrievePassword.goToLogin': 'Back to Login',
|
||||
'retrievePassword.inputCorrectMobile': 'Please enter correct mobile number',
|
||||
@@ -411,6 +414,7 @@ export default {
|
||||
'retrievePassword.newPasswordRequired': 'New password cannot be empty',
|
||||
'retrievePassword.confirmNewPasswordRequired': 'Confirm new password cannot be empty',
|
||||
'retrievePassword.passwordUpdateSuccess': 'Password updated successfully',
|
||||
'retrievePassword.agreeTo': 'Reset means agree',
|
||||
|
||||
// Change password page text
|
||||
'changePassword.title': 'Change Password',
|
||||
@@ -631,7 +635,7 @@ export default {
|
||||
'providerManagement.selectToDelete': 'Please select providers to delete first',
|
||||
'providerManagement.confirmDelete': 'Are you sure to delete the selected {count} providers?',
|
||||
'providerManagement.viewFields': 'View Fields',
|
||||
|
||||
|
||||
// Common Text
|
||||
'common.all': 'All',
|
||||
'common.search': 'Search',
|
||||
@@ -661,7 +665,7 @@ export default {
|
||||
'common.confirm': 'Confirm',
|
||||
'common.cancel': 'Cancel',
|
||||
'common.sensitive': 'Sensitive',
|
||||
|
||||
|
||||
// Language switch
|
||||
'language.zhCN': '中文简体',
|
||||
'language.zhTW': '中文繁體',
|
||||
@@ -1029,7 +1033,7 @@ export default {
|
||||
'agentTemplateManagement.batchDeleteFailed': 'Template batch deletion failed',
|
||||
'agentTemplateManagement.deleteBackendError': 'Deletion failed, please check if the backend service is normal',
|
||||
'agentTemplateManagement.deleteCancelled': 'Deletion cancelled',
|
||||
|
||||
|
||||
// templateQuickConfig
|
||||
'templateQuickConfig.title': 'Module Quick Configuration',
|
||||
'templateQuickConfig.agentSettings.agentName': 'Nickname',
|
||||
@@ -1047,5 +1051,12 @@ export default {
|
||||
'templateQuickConfig.templateNotFound': 'Template not found',
|
||||
'warning': 'Warning',
|
||||
'info': 'Info',
|
||||
'common.networkError': 'Network request failed'
|
||||
'common.networkError': 'Network request failed',
|
||||
'sm2.publicKeyNotConfigured': 'SM2 public key not configured, please contact administrator',
|
||||
'sm2.encryptionFailed': 'Password encryption failed',
|
||||
'sm2.keyGenerationFailed': 'Key pair generation failed',
|
||||
'sm2.invalidPublicKey': 'Invalid public key format',
|
||||
'sm2.encryptionError': 'Error occurred during encryption',
|
||||
'sm2.publicKeyRetry': 'Retrying to get public key...',
|
||||
'sm2.publicKeyRetryFailed': 'Public key retrieval retry failed'
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export default {
|
||||
'login.requiredCaptcha': '验证码不能为空',
|
||||
'login.requiredMobile': '请输入正确的手机号码',
|
||||
'login.loginSuccess': '登录成功!',
|
||||
|
||||
|
||||
// HeaderBar组件文本
|
||||
'header.smartManagement': '智能体管理',
|
||||
'header.modelConfig': '模型配置',
|
||||
@@ -38,7 +38,7 @@ export default {
|
||||
'mcpToolCall.copyResult': '复制结果',
|
||||
'mcpToolCall.noResultYet': '暂无执行结果',
|
||||
'mcpToolCall.loadingToolList': '正在获取工具列表...',
|
||||
|
||||
|
||||
// 工具名称
|
||||
'mcpToolCall.toolName.getDeviceStatus': '查看设备状态',
|
||||
'mcpToolCall.toolName.setVolume': '设置音量',
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
'mcpToolCall.toolName.snapshot': '屏幕截图',
|
||||
'mcpToolCall.toolName.previewImage': '预览图片',
|
||||
'mcpToolCall.toolName.setDownloadUrl': '设置下载地址',
|
||||
|
||||
|
||||
// 工具分类
|
||||
'mcpToolCall.category.audio': '音频',
|
||||
'mcpToolCall.category.display': '显示',
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
'mcpToolCall.category.system': '系统',
|
||||
'mcpToolCall.category.assets': '资源',
|
||||
'mcpToolCall.category.deviceInfo': '设备信息',
|
||||
|
||||
|
||||
// 表格分类和属性
|
||||
'mcpToolCall.table.audioSpeaker': '音频扬声器',
|
||||
'mcpToolCall.table.screen': '屏幕',
|
||||
@@ -80,7 +80,7 @@ export default {
|
||||
'mcpToolCall.table.component': '组件',
|
||||
'mcpToolCall.table.property': '属性',
|
||||
'mcpToolCall.table.value': '值',
|
||||
|
||||
|
||||
'mcpToolCall.prop.volume': '音量',
|
||||
'mcpToolCall.prop.brightness': '亮度',
|
||||
'mcpToolCall.prop.theme': '主题',
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
'mcpToolCall.prop.url': 'URL',
|
||||
'mcpToolCall.prop.quality': '质量',
|
||||
'mcpToolCall.prop.question': '问题',
|
||||
|
||||
|
||||
// 工具帮助文本
|
||||
'mcpToolCall.help.getDeviceStatus': '查看设备的当前运行状态,包括音量、屏幕、电池等信息。',
|
||||
'mcpToolCall.help.setVolume': '调整设备的音量大小,请输入0-100之间的数值。',
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
'mcpToolCall.help.snapshot': '对当前屏幕进行截图并上传到指定URL。',
|
||||
'mcpToolCall.help.previewImage': '在设备屏幕上预览指定URL的图片。',
|
||||
'mcpToolCall.help.setDownloadUrl': '设置设备资源文件的下载地址。',
|
||||
|
||||
|
||||
// 其他文本
|
||||
'mcpToolCall.text.strong': '强',
|
||||
'mcpToolCall.text.medium': '中',
|
||||
@@ -231,7 +231,7 @@ export default {
|
||||
|
||||
// AddModelDialog组件相关
|
||||
'addModelDialog.requiredSupplier': '请选择供应器',
|
||||
|
||||
|
||||
// 注册页面相关
|
||||
'register.title': '创建账号',
|
||||
'register.welcome': '欢迎使用小智AI',
|
||||
@@ -259,7 +259,7 @@ export default {
|
||||
'register.requiredPassword': '密码不能为空',
|
||||
'register.requiredCaptcha': '验证码不能为空',
|
||||
'register.requiredMobileCaptcha': '请输入短信验证码',
|
||||
|
||||
|
||||
'manualAddDeviceDialog.deviceType': '设备型号',
|
||||
'manualAddDeviceDialog.deviceTypePlaceholder': '请选择设备型号',
|
||||
'manualAddDeviceDialog.firmwareVersion': '固件版本',
|
||||
@@ -384,10 +384,12 @@ export default {
|
||||
'register.registerSuccess': '注册成功!',
|
||||
'register.registerFailed': '注册失败',
|
||||
'register.passwordsNotMatch': '两次输入的密码不一致',
|
||||
'register.secondsLater': '秒后',
|
||||
|
||||
// 忘记密码页面文本
|
||||
'retrievePassword.title': '重置密码',
|
||||
'retrievePassword.welcome': '密码找回',
|
||||
'retrievePassword.subtitle': '找回密码',
|
||||
'retrievePassword.mobile': '手机号',
|
||||
'retrievePassword.mobilePlaceholder': '请输入手机号码',
|
||||
'retrievePassword.captcha': '验证码',
|
||||
@@ -399,6 +401,7 @@ export default {
|
||||
'retrievePassword.confirmNewPassword': '确认新密码',
|
||||
'retrievePassword.confirmNewPasswordPlaceholder': '请确认新密码',
|
||||
'retrievePassword.getMobileCaptcha': '获取验证码',
|
||||
'retrievePassword.resetButton': '重置密码',
|
||||
'retrievePassword.updateButton': '立即修改',
|
||||
'retrievePassword.goToLogin': '返回登录',
|
||||
'retrievePassword.inputCorrectMobile': '请输入正确的手机号码',
|
||||
@@ -411,6 +414,7 @@ export default {
|
||||
'retrievePassword.newPasswordRequired': '新密码不能为空',
|
||||
'retrievePassword.confirmNewPasswordRequired': '确认新密码不能为空',
|
||||
'retrievePassword.passwordUpdateSuccess': '密码修改成功',
|
||||
'retrievePassword.agreeTo': '重置即同意',
|
||||
|
||||
// 修改密码页面文本
|
||||
'changePassword.title': '修改密码',
|
||||
@@ -631,7 +635,7 @@ export default {
|
||||
'providerManagement.selectToDelete': '请先选择需要删除的供应器',
|
||||
'providerManagement.confirmDelete': '确定要删除选中的{count}个供应器吗?',
|
||||
'providerManagement.viewFields': '查看字段',
|
||||
|
||||
|
||||
// 公共文本
|
||||
'common.all': '全部',
|
||||
'common.search': '搜索',
|
||||
@@ -1029,7 +1033,7 @@ export default {
|
||||
'agentTemplateManagement.deleteFailed': '模板删除失败',
|
||||
'agentTemplateManagement.batchDeleteFailed': '模板批量删除失败',
|
||||
'agentTemplateManagement.deleteBackendError': '删除失败,请检查后端服务是否正常',
|
||||
|
||||
|
||||
// 模板快速配置页面文本
|
||||
'templateQuickConfig.title': '模块快速配置',
|
||||
'templateQuickConfig.agentSettings.agentName': '助手昵称',
|
||||
@@ -1047,5 +1051,13 @@ export default {
|
||||
'templateQuickConfig.resetSuccess': '重置成功',
|
||||
'warning': '警告',
|
||||
'info': '提示',
|
||||
'common.networkError': '网络请求失败'
|
||||
'common.networkError': '网络请求失败',
|
||||
// SM2加密相关错误消息
|
||||
'sm2.publicKeyNotConfigured': 'SM2公钥未配置,请联系管理员',
|
||||
'sm2.encryptionFailed': '密码加密失败',
|
||||
'sm2.keyGenerationFailed': '密钥对生成失败',
|
||||
'sm2.invalidPublicKey': '无效的公钥格式',
|
||||
'sm2.encryptionError': '加密过程中发生错误',
|
||||
'sm2.publicKeyRetry': '正在重试获取公钥...',
|
||||
'sm2.publicKeyRetryFailed': '公钥获取重试失败'
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export default {
|
||||
'login.requiredCaptcha': '驗證碼不能為空',
|
||||
'login.requiredMobile': '請輸入正確的手機號碼',
|
||||
'login.loginSuccess': '登錄成功!',
|
||||
|
||||
|
||||
// HeaderBar组件文本
|
||||
'header.smartManagement': '智能體管理',
|
||||
'header.modelConfig': '模型配置',
|
||||
@@ -38,7 +38,7 @@ export default {
|
||||
'mcpToolCall.copyResult': '複製結果',
|
||||
'mcpToolCall.noResultYet': '暫無執行結果',
|
||||
'mcpToolCall.loadingToolList': '正在獲取工具列表...',
|
||||
|
||||
|
||||
// 工具名稱
|
||||
'mcpToolCall.toolName.getDeviceStatus': '查看設備狀態',
|
||||
'mcpToolCall.toolName.setVolume': '設置音量',
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
'mcpToolCall.toolName.snapshot': '螢幕截圖',
|
||||
'mcpToolCall.toolName.previewImage': '預覽圖片',
|
||||
'mcpToolCall.toolName.setDownloadUrl': '設置下載地址',
|
||||
|
||||
|
||||
// 工具分類
|
||||
'mcpToolCall.category.audio': '音頻',
|
||||
'mcpToolCall.category.display': '顯示',
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
'mcpToolCall.category.system': '系統',
|
||||
'mcpToolCall.category.assets': '資源',
|
||||
'mcpToolCall.category.deviceInfo': '設備資訊',
|
||||
|
||||
|
||||
// 表格分類和屬性
|
||||
'mcpToolCall.table.audioSpeaker': '音頻揚聲器',
|
||||
'mcpToolCall.table.screen': '螢幕',
|
||||
@@ -80,7 +80,7 @@ export default {
|
||||
'mcpToolCall.table.component': '組件',
|
||||
'mcpToolCall.table.property': '屬性',
|
||||
'mcpToolCall.table.value': '值',
|
||||
|
||||
|
||||
'mcpToolCall.prop.volume': '音量',
|
||||
'mcpToolCall.prop.brightness': '亮度',
|
||||
'mcpToolCall.prop.theme': '主題',
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
'mcpToolCall.prop.url': 'URL',
|
||||
'mcpToolCall.prop.quality': '品質',
|
||||
'mcpToolCall.prop.question': '問題',
|
||||
|
||||
|
||||
// 工具幫助文本
|
||||
'mcpToolCall.help.getDeviceStatus': '查看設備的當前運行狀態,包括音量、螢幕、電池等資訊。',
|
||||
'mcpToolCall.help.setVolume': '調整設備的音量大小,請輸入0-100之間的數值。',
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
'mcpToolCall.help.snapshot': '對當前螢幕進行截圖並上傳到指定URL。',
|
||||
'mcpToolCall.help.previewImage': '在設備螢幕上預覽指定URL的圖片。',
|
||||
'mcpToolCall.help.setDownloadUrl': '設置設備資源文件的下載地址。',
|
||||
|
||||
|
||||
// 其他文本
|
||||
'mcpToolCall.text.strong': '強',
|
||||
'mcpToolCall.text.medium': '中',
|
||||
@@ -231,7 +231,7 @@ export default {
|
||||
|
||||
// AddModelDialog組件相關
|
||||
'addModelDialog.requiredSupplier': '請選擇供應器',
|
||||
|
||||
|
||||
// 註冊頁面相關
|
||||
'register.title': '建立帳號',
|
||||
'register.welcome': '歡迎使用小智慧AI',
|
||||
@@ -253,13 +253,14 @@ export default {
|
||||
'register.captchaSendSuccess': '驗證碼發送成功',
|
||||
'register.captchaSendFailed': '驗證碼發送失敗',
|
||||
'register.passwordsNotMatch': '兩次輸入的密碼不一致',
|
||||
'register.secondsLater': '秒後',
|
||||
'register.registerSuccess': '註冊成功!',
|
||||
'register.registerFailed': '註冊失敗',
|
||||
'register.requiredUsername': '用戶名不能為空',
|
||||
'register.requiredPassword': '密碼不能為空',
|
||||
'register.requiredCaptcha': '驗證碼不能為空',
|
||||
'register.requiredMobileCaptcha': '請輸入簡訊驗證碼',
|
||||
|
||||
|
||||
'manualAddDeviceDialog.deviceType': '設備型號',
|
||||
'manualAddDeviceDialog.deviceTypePlaceholder': '請選擇設備型號',
|
||||
'manualAddDeviceDialog.firmwareVersion': '固件版本',
|
||||
@@ -388,6 +389,7 @@ export default {
|
||||
// 忘记密码页面文本
|
||||
'retrievePassword.title': '重置密碼',
|
||||
'retrievePassword.welcome': '密碼找回',
|
||||
'retrievePassword.subtitle': '找回密碼',
|
||||
'retrievePassword.mobile': '手機號',
|
||||
'retrievePassword.mobilePlaceholder': '請輸入手機號碼',
|
||||
'retrievePassword.captcha': '驗證碼',
|
||||
@@ -399,6 +401,7 @@ export default {
|
||||
'retrievePassword.confirmNewPassword': '確認新密碼',
|
||||
'retrievePassword.confirmNewPasswordPlaceholder': '請確認新密碼',
|
||||
'retrievePassword.getMobileCaptcha': '獲取驗證碼',
|
||||
'retrievePassword.resetButton': '重置密碼',
|
||||
'retrievePassword.updateButton': '立即修改',
|
||||
'retrievePassword.goToLogin': '返回登錄',
|
||||
'retrievePassword.inputCorrectMobile': '請輸入正確的手機號碼',
|
||||
@@ -411,6 +414,7 @@ export default {
|
||||
'retrievePassword.newPasswordRequired': '新密碼不能為空',
|
||||
'retrievePassword.confirmNewPasswordRequired': '確認新密碼不能為空',
|
||||
'retrievePassword.passwordUpdateSuccess': '密碼修改成功',
|
||||
'retrievePassword.agreeTo': '重置即同意',
|
||||
|
||||
// 修改密码页面文本
|
||||
'changePassword.title': '修改密碼',
|
||||
@@ -548,41 +552,41 @@ export default {
|
||||
'voiceprint.delete': '刪除聲紋',
|
||||
|
||||
// 字典管理頁面文本
|
||||
'dictManagement.pageTitle': '字典管理',
|
||||
'dictManagement.searchPlaceholder': '請輸入字典值標籤查詢',
|
||||
'dictManagement.search': '搜索',
|
||||
'dictManagement.dictTypeName': '字典類型名稱',
|
||||
'dictManagement.operation': '操作',
|
||||
'dictManagement.edit': '編輯',
|
||||
'dictManagement.dictLabel': '字典標籤',
|
||||
'dictManagement.dictValue': '字典值',
|
||||
'dictManagement.sort': '排序',
|
||||
'dictManagement.delete': '刪除',
|
||||
'dictManagement.selectAll': '全選',
|
||||
'dictManagement.deselectAll': '取消全選',
|
||||
'dictManagement.addDictType': '新增字典類型',
|
||||
'dictManagement.batchDeleteDictType': '批量刪除字典類型',
|
||||
'dictManagement.addDictData': '新增字典數據',
|
||||
'dictManagement.batchDeleteDictData': '批量刪除字典數據',
|
||||
'dictManagement.itemsPerPage': '{items}條/頁',
|
||||
'dictManagement.firstPage': '首頁',
|
||||
'dictManagement.prevPage': '上一頁',
|
||||
'dictManagement.nextPage': '下一頁',
|
||||
'dictManagement.totalRecords': '共{total}條記錄',
|
||||
'dictManagement.editDictType': '編輯字典類型',
|
||||
'dictManagement.editDictData': '編輯字典數據',
|
||||
'dictManagement.saveSuccess': '保存成功',
|
||||
'dictManagement.deleteSuccess': '刪除成功',
|
||||
'dictManagement.selectDictTypeToDelete': '請選擇要刪除的字典類型',
|
||||
'dictManagement.confirmDeleteDictType': '確定要刪除選中的字典類型嗎?',
|
||||
'dictManagement.confirm': '確定',
|
||||
'dictManagement.cancel': '取消',
|
||||
'dictManagement.selectDictTypeFirst': '請先選擇字典類型',
|
||||
'dictManagement.confirmDeleteDictData': '確定要刪除該字典數據嗎?',
|
||||
'dictManagement.selectDictDataToDelete': '請選擇要刪除的字典數據',
|
||||
'dictManagement.confirmBatchDeleteDictData': '確定要刪除選中的{count}個字典數據嗎?',
|
||||
'dictManagement.pageTitle': '字典管理',
|
||||
'dictManagement.searchPlaceholder': '請輸入字典值標籤查詢',
|
||||
'dictManagement.search': '搜索',
|
||||
'dictManagement.dictTypeName': '字典類型名稱',
|
||||
'dictManagement.operation': '操作',
|
||||
'dictManagement.edit': '編輯',
|
||||
'dictManagement.dictLabel': '字典標籤',
|
||||
'dictManagement.dictValue': '字典值',
|
||||
'dictManagement.sort': '排序',
|
||||
'dictManagement.delete': '刪除',
|
||||
'dictManagement.selectAll': '全選',
|
||||
'dictManagement.deselectAll': '取消全選',
|
||||
'dictManagement.addDictType': '新增字典類型',
|
||||
'dictManagement.batchDeleteDictType': '批量刪除字典類型',
|
||||
'dictManagement.addDictData': '新增字典數據',
|
||||
'dictManagement.batchDeleteDictData': '批量刪除字典數據',
|
||||
'dictManagement.itemsPerPage': '{items}條/頁',
|
||||
'dictManagement.firstPage': '首頁',
|
||||
'dictManagement.prevPage': '上一頁',
|
||||
'dictManagement.nextPage': '下一頁',
|
||||
'dictManagement.totalRecords': '共{total}條記錄',
|
||||
'dictManagement.editDictType': '編輯字典類型',
|
||||
'dictManagement.editDictData': '編輯字典數據',
|
||||
'dictManagement.saveSuccess': '保存成功',
|
||||
'dictManagement.deleteSuccess': '刪除成功',
|
||||
'dictManagement.selectDictTypeToDelete': '請選擇要刪除的字典類型',
|
||||
'dictManagement.confirmDeleteDictType': '確定要刪除選中的字典類型嗎?',
|
||||
'dictManagement.confirm': '確定',
|
||||
'dictManagement.cancel': '取消',
|
||||
'dictManagement.selectDictTypeFirst': '請先選擇字典類型',
|
||||
'dictManagement.confirmDeleteDictData': '確定要刪除該字典數據嗎?',
|
||||
'dictManagement.selectDictDataToDelete': '請選擇要刪除的字典數據',
|
||||
'dictManagement.confirmBatchDeleteDictData': '確定要刪除選中的{count}個字典數據嗎?',
|
||||
'dictManagement.getDictDataFailed': '獲取字典數據失敗',
|
||||
|
||||
|
||||
// 用户信息
|
||||
'user.info': '用戶信息',
|
||||
'user.username': '用戶名',
|
||||
@@ -1005,31 +1009,31 @@ export default {
|
||||
'providerDialog.batchDeleteFieldsSuccess': '成功刪除{count}個字段',
|
||||
|
||||
// 預設角色管理頁面文本
|
||||
'agentTemplateManagement.title': '預設角色管理',
|
||||
'agentTemplateManagement.templateName': '模板名稱',
|
||||
'agentTemplateManagement.action': '操作',
|
||||
'templateQuickConfig.saveSuccess': '配置保存成功',
|
||||
'templateQuickConfig.saveFailed': '配置保存失敗',
|
||||
'agentTemplateManagement.createTemplate': '建立模板',
|
||||
'agentTemplateManagement.editTemplate': '編輯模板',
|
||||
'agentTemplateManagement.deleteTemplate': '刪除模板',
|
||||
'agentTemplateManagement.deleteSuccess': '模板刪除成功',
|
||||
'agentTemplateManagement.batchDelete': '批次刪除',
|
||||
'agentTemplateManagement.batchDeleteSuccess': '批次刪除成功',
|
||||
'agentTemplateManagement.selectTemplate': '請選擇模板',
|
||||
'agentTemplateManagement.select': '選擇',
|
||||
'agentTemplateManagement.searchPlaceholder': '請輸入模板名稱搜尋',
|
||||
'agentTemplateManagement.search': '搜尋',
|
||||
'agentTemplateManagement.serialNumber': '序號',
|
||||
'agentTemplateManagement.selectAll': '全選',
|
||||
'agentTemplateManagement.deselectAll': '取消全選',
|
||||
'agentTemplateManagement.loading': '拼命加載中',
|
||||
'agentTemplateManagement.confirmSingleDelete': '確定要刪除這個模板嗎?',
|
||||
'agentTemplateManagement.confirmBatchDelete': '確定要刪除選中的 {count} 個模板嗎?',
|
||||
'agentTemplateManagement.deleteFailed': '模板刪除失敗',
|
||||
'agentTemplateManagement.batchDeleteFailed': '模板批次刪除失敗',
|
||||
'agentTemplateManagement.title': '預設角色管理',
|
||||
'agentTemplateManagement.templateName': '模板名稱',
|
||||
'agentTemplateManagement.action': '操作',
|
||||
'templateQuickConfig.saveSuccess': '配置保存成功',
|
||||
'templateQuickConfig.saveFailed': '配置保存失敗',
|
||||
'agentTemplateManagement.createTemplate': '建立模板',
|
||||
'agentTemplateManagement.editTemplate': '編輯模板',
|
||||
'agentTemplateManagement.deleteTemplate': '刪除模板',
|
||||
'agentTemplateManagement.deleteSuccess': '模板刪除成功',
|
||||
'agentTemplateManagement.batchDelete': '批次刪除',
|
||||
'agentTemplateManagement.batchDeleteSuccess': '批次刪除成功',
|
||||
'agentTemplateManagement.selectTemplate': '請選擇模板',
|
||||
'agentTemplateManagement.select': '選擇',
|
||||
'agentTemplateManagement.searchPlaceholder': '請輸入模板名稱搜尋',
|
||||
'agentTemplateManagement.search': '搜尋',
|
||||
'agentTemplateManagement.serialNumber': '序號',
|
||||
'agentTemplateManagement.selectAll': '全選',
|
||||
'agentTemplateManagement.deselectAll': '取消全選',
|
||||
'agentTemplateManagement.loading': '拼命加載中',
|
||||
'agentTemplateManagement.confirmSingleDelete': '確定要刪除這個模板嗎?',
|
||||
'agentTemplateManagement.confirmBatchDelete': '確定要刪除選中的 {count} 個模板嗎?',
|
||||
'agentTemplateManagement.deleteFailed': '模板刪除失敗',
|
||||
'agentTemplateManagement.batchDeleteFailed': '模板批次刪除失敗',
|
||||
'agentTemplateManagement.deleteBackendError': '刪除失敗,請檢查後端服務是否正常',
|
||||
|
||||
|
||||
// 模板快速配置
|
||||
'templateQuickConfig.title': '模組快速設定',
|
||||
'templateQuickConfig.agentSettings.agentName': '助手暱稱',
|
||||
@@ -1047,5 +1051,14 @@ export default {
|
||||
'templateQuickConfig.newTemplate': '新模板',
|
||||
'warning': '警告',
|
||||
'info': '提示',
|
||||
'common.networkError': '網路請求失敗'
|
||||
'common.networkError': '網路請求失敗',
|
||||
|
||||
// SM2加密相關錯誤消息
|
||||
'sm2.publicKeyNotConfigured': 'SM2公鑰未配置,請聯繫管理員',
|
||||
'sm2.encryptionFailed': '密碼加密失敗',
|
||||
'sm2.keyGenerationFailed': '金鑰對生成失敗',
|
||||
'sm2.invalidPublicKey': '無效的公鑰格式',
|
||||
'sm2.encryptionError': '加密過程中發生錯誤',
|
||||
'sm2.publicKeyRetry': '正在重試獲取公鑰...',
|
||||
'sm2.publicKeyRetryFailed': '公鑰獲取重試失敗'
|
||||
}
|
||||
@@ -15,7 +15,8 @@ export default new Vuex.Store({
|
||||
version: '',
|
||||
beianIcpNum: 'null',
|
||||
beianGaNum: 'null',
|
||||
allowUserRegister: false
|
||||
allowUserRegister: false,
|
||||
sm2PublicKey: ''
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
||||
@@ -200,3 +200,59 @@ export function validateMobile(mobile, areaCode) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成SM2密钥对(十六进制格式)
|
||||
* @returns {Object} 包含公钥和私钥的对象
|
||||
*/
|
||||
export function generateSm2KeyPairHex() {
|
||||
// 使用sm-crypto库生成SM2密钥对
|
||||
const sm2 = require('sm-crypto').sm2;
|
||||
const keypair = sm2.generateKeyPairHex();
|
||||
|
||||
return {
|
||||
publicKey: keypair.publicKey,
|
||||
privateKey: keypair.privateKey,
|
||||
clientPublicKey: keypair.publicKey, // 客户端公钥
|
||||
clientPrivateKey: keypair.privateKey // 客户端私钥
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* SM2公钥加密
|
||||
* @param {string} publicKey 公钥(十六进制格式)
|
||||
* @param {string} plainText 明文
|
||||
* @returns {string} 加密后的密文(十六进制格式)
|
||||
*/
|
||||
export function sm2Encrypt(publicKey, plainText) {
|
||||
if (!publicKey) {
|
||||
throw new Error('公钥不能为null或undefined');
|
||||
}
|
||||
|
||||
if (!plainText) {
|
||||
throw new Error('明文不能为空');
|
||||
}
|
||||
|
||||
const sm2 = require('sm-crypto').sm2;
|
||||
// SM2加密,添加04前缀表示未压缩公钥
|
||||
const encrypted = sm2.doEncrypt(plainText, publicKey, 1);
|
||||
// 转换为十六进制格式(与后端保持一致,添加04前缀)
|
||||
const result = "04" + encrypted;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* SM2私钥解密
|
||||
* @param {string} privateKey 私钥(十六进制格式)
|
||||
* @param {string} cipherText 密文(十六进制格式)
|
||||
* @returns {string} 解密后的明文
|
||||
*/
|
||||
export function sm2Decrypt(privateKey, cipherText) {
|
||||
const sm2 = require('sm-crypto').sm2;
|
||||
// 移除04前缀(与后端保持一致)
|
||||
const dataWithoutPrefix = cipherText.startsWith("04") ? cipherText.substring(2) : cipherText;
|
||||
// SM2解密
|
||||
return sm2.doDecrypt(dataWithoutPrefix, privateKey, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
import Api from "@/apis/api";
|
||||
import VersionFooter from "@/components/VersionFooter.vue";
|
||||
import i18n, { changeLanguage } from "@/i18n";
|
||||
import { getUUID, goToPage, showDanger, showSuccess, validateMobile } from "@/utils";
|
||||
import { getUUID, goToPage, showDanger, showSuccess, sm2Encrypt, validateMobile } from "@/utils";
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
@@ -161,6 +161,7 @@ export default {
|
||||
allowUserRegister: (state) => state.pubConfig.allowUserRegister,
|
||||
enableMobileRegister: (state) => state.pubConfig.enableMobileRegister,
|
||||
mobileAreaList: (state) => state.pubConfig.mobileAreaList,
|
||||
sm2PublicKey: (state) => state.pubConfig.sm2PublicKey,
|
||||
}),
|
||||
// 获取当前语言
|
||||
currentLanguage() {
|
||||
@@ -284,10 +285,31 @@ export default {
|
||||
if (!this.validateInput(this.form.captcha, 'login.requiredCaptcha')) {
|
||||
return;
|
||||
}
|
||||
// 加密密码
|
||||
let encryptedPassword;
|
||||
try {
|
||||
// 拼接验证码和密码
|
||||
const captchaAndPassword = this.form.captcha + this.form.password;
|
||||
encryptedPassword = sm2Encrypt(this.sm2PublicKey, captchaAndPassword);
|
||||
} catch (error) {
|
||||
console.error("密码加密失败:", error);
|
||||
showDanger(this.$t('sm2.encryptionFailed'));
|
||||
return;
|
||||
}
|
||||
|
||||
const plainUsername = this.form.username;
|
||||
|
||||
this.form.captchaId = this.captchaUuid;
|
||||
|
||||
// 加密
|
||||
const loginData = {
|
||||
username: plainUsername,
|
||||
password: encryptedPassword,
|
||||
captchaId: this.form.captchaId
|
||||
};
|
||||
|
||||
Api.user.login(
|
||||
this.form,
|
||||
loginData,
|
||||
({ data }) => {
|
||||
showSuccess(this.$t('login.loginSuccess'));
|
||||
this.$store.commit("setToken", JSON.stringify(data.data));
|
||||
@@ -296,7 +318,7 @@ export default {
|
||||
(err) => {
|
||||
// 直接使用后端返回的国际化消息
|
||||
let errorMessage = err.data.msg || "登录失败";
|
||||
|
||||
|
||||
showDanger(errorMessage);
|
||||
if (
|
||||
err.data != null &&
|
||||
@@ -319,7 +341,7 @@ export default {
|
||||
},
|
||||
goToForgetPassword() {
|
||||
goToPage("/retrieve-password");
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -329,8 +351,7 @@ export default {
|
||||
.login-type-container {
|
||||
margin: 10px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.title-language-dropdown {
|
||||
|
||||
@@ -45,9 +45,10 @@
|
||||
<div style="display: flex; align-items: center; margin-top: 20px; width: 100%; gap: 10px;">
|
||||
<div class="input-box" style="width: calc(100% - 130px); margin-top: 0;">
|
||||
<img loading="lazy" alt="" class="input-icon" src="@/assets/login/shield.png" />
|
||||
<el-input v-model="form.captcha" :placeholder="$t('register.captchaPlaceholder')" style="flex: 1;" />
|
||||
<el-input v-model="form.captcha" :placeholder="$t('register.captchaPlaceholder')"
|
||||
style="flex: 1;" />
|
||||
</div>
|
||||
<img loading="lazy" v-if="captchaUrl" :src="captchaUrl" alt="验证码"
|
||||
<img loading="lazy" v-if="captchaUrl" :src="captchaUrl" alt="验证码"
|
||||
style="width: 150px; height: 40px; cursor: pointer;" @click="fetchCaptcha" />
|
||||
</div>
|
||||
|
||||
@@ -56,7 +57,8 @@
|
||||
<div style="display: flex; align-items: center; margin-top: 20px; width: 100%; gap: 10px;">
|
||||
<div class="input-box" style="width: calc(100% - 130px); margin-top: 0;">
|
||||
<img loading="lazy" alt="" class="input-icon" src="@/assets/login/phone.png" />
|
||||
<el-input v-model="form.mobileCaptcha" :placeholder="$t('register.mobileCaptchaPlaceholder')" style="flex: 1;" maxlength="6" />
|
||||
<el-input v-model="form.mobileCaptcha" :placeholder="$t('register.mobileCaptchaPlaceholder')"
|
||||
style="flex: 1;" maxlength="6" />
|
||||
</div>
|
||||
<el-button type="primary" class="send-captcha-btn" :disabled="!canSendMobileCaptcha"
|
||||
@click="sendMobileCaptcha">
|
||||
@@ -70,13 +72,15 @@
|
||||
<!-- 密码输入框 -->
|
||||
<div class="input-box">
|
||||
<img loading="lazy" alt="" class="input-icon" src="@/assets/login/password.png" />
|
||||
<el-input v-model="form.password" :placeholder="$t('register.passwordPlaceholder')" type="password" show-password />
|
||||
<el-input v-model="form.password" :placeholder="$t('register.passwordPlaceholder')" type="password"
|
||||
show-password />
|
||||
</div>
|
||||
|
||||
<!-- 新增确认密码 -->
|
||||
<div class="input-box">
|
||||
<img loading="lazy" alt="" class="input-icon" src="@/assets/login/password.png" />
|
||||
<el-input v-model="form.confirmPassword" :placeholder="$t('register.confirmPasswordPlaceholder')" type="password" show-password />
|
||||
<el-input v-model="form.confirmPassword" :placeholder="$t('register.confirmPasswordPlaceholder')"
|
||||
type="password" show-password />
|
||||
</div>
|
||||
|
||||
<!-- 验证码部分保持相同 -->
|
||||
@@ -121,11 +125,10 @@
|
||||
<script>
|
||||
import Api from '@/apis/api';
|
||||
import VersionFooter from '@/components/VersionFooter.vue';
|
||||
import { getUUID, goToPage, showDanger, showSuccess, validateMobile } from '@/utils';
|
||||
import { getUUID, goToPage, showDanger, showSuccess, sm2Encrypt, validateMobile } from '@/utils';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
// 导入语言切换功能
|
||||
import { changeLanguage } from '@/i18n';
|
||||
|
||||
export default {
|
||||
name: 'register',
|
||||
@@ -136,7 +139,8 @@ export default {
|
||||
...mapState({
|
||||
allowUserRegister: state => state.pubConfig.allowUserRegister,
|
||||
enableMobileRegister: state => state.pubConfig.enableMobileRegister,
|
||||
mobileAreaList: state => state.pubConfig.mobileAreaList
|
||||
mobileAreaList: state => state.pubConfig.mobileAreaList,
|
||||
sm2PublicKey: state => state.pubConfig.sm2PublicKey,
|
||||
}),
|
||||
canSendMobileCaptcha() {
|
||||
return this.countdown === 0 && validateMobile(this.form.mobile, this.form.areaCode);
|
||||
@@ -156,7 +160,7 @@ export default {
|
||||
},
|
||||
captchaUrl: '',
|
||||
countdown: 0,
|
||||
timer: null
|
||||
timer: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -240,7 +244,7 @@ export default {
|
||||
},
|
||||
|
||||
// 注册逻辑
|
||||
register() {
|
||||
async register() {
|
||||
if (this.enableMobileRegister) {
|
||||
// 手机号注册验证
|
||||
if (!validateMobile(this.form.mobile, this.form.areaCode)) {
|
||||
@@ -270,12 +274,34 @@ export default {
|
||||
if (!this.validateInput(this.form.captcha, this.$t('register.requiredCaptcha'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.enableMobileRegister) {
|
||||
this.form.username = this.form.areaCode + this.form.mobile
|
||||
// 加密
|
||||
let encryptedPassword;
|
||||
try {
|
||||
// 拼接验证码和密码
|
||||
const captchaAndPassword = this.form.captcha + this.form.password;
|
||||
encryptedPassword = sm2Encrypt(this.sm2PublicKey, captchaAndPassword);
|
||||
} catch (error) {
|
||||
console.error("密码加密失败:", error);
|
||||
showDanger(this.$t('sm2.encryptionFailed'));
|
||||
return;
|
||||
}
|
||||
|
||||
Api.user.register(this.form, ({ data }) => {
|
||||
let plainUsername;
|
||||
if (this.enableMobileRegister) {
|
||||
plainUsername = this.form.areaCode + this.form.mobile;
|
||||
} else {
|
||||
plainUsername = this.form.username;
|
||||
}
|
||||
|
||||
// 准备注册数据
|
||||
const registerData = {
|
||||
username: plainUsername,
|
||||
password: encryptedPassword,
|
||||
captchaId: this.form.captchaId,
|
||||
mobileCaptcha: this.form.mobileCaptcha
|
||||
};
|
||||
|
||||
Api.user.register(registerData, ({ data }) => {
|
||||
showSuccess(this.$t('register.registerSuccess'))
|
||||
goToPage('/login')
|
||||
}, (err) => {
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<el-button type="primary" class="send-captcha-btn" :disabled="!canSendMobileCaptcha"
|
||||
@click="sendMobileCaptcha">
|
||||
<span>
|
||||
{{ countdown > 0 ? `${countdown}秒后重试` : $t('retrievePassword.sendCaptcha') }}
|
||||
{{ countdown > 0 ? `${countdown}${$t('register.secondsLater')}` : $t('retrievePassword.getMobileCaptcha') }}
|
||||
</span>
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -67,7 +67,7 @@
|
||||
<!-- 确认新密码 -->
|
||||
<div class="input-box">
|
||||
<img loading="lazy" alt="" class="input-icon" src="@/assets/login/password.png" />
|
||||
<el-input v-model="form.confirmPassword" :placeholder="$t('retrievePassword.confirmPasswordPlaceholder')" type="password" show-password />
|
||||
<el-input v-model="form.confirmPassword" :placeholder="$t('retrievePassword.confirmNewPasswordPlaceholder')" type="password" show-password />
|
||||
</div>
|
||||
|
||||
<!-- 修改底部链接 -->
|
||||
@@ -101,7 +101,7 @@
|
||||
<script>
|
||||
import Api from '@/apis/api';
|
||||
import VersionFooter from '@/components/VersionFooter.vue';
|
||||
import { getUUID, goToPage, showDanger, showSuccess, validateMobile } from '@/utils';
|
||||
import { getUUID, goToPage, showDanger, showSuccess, validateMobile, sm2Encrypt } from '@/utils';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
// 导入语言切换功能
|
||||
@@ -115,7 +115,8 @@ export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
allowUserRegister: state => state.pubConfig.allowUserRegister,
|
||||
mobileAreaList: state => state.pubConfig.mobileAreaList
|
||||
mobileAreaList: state => state.pubConfig.mobileAreaList,
|
||||
sm2PublicKey: state => state.pubConfig.sm2PublicKey
|
||||
}),
|
||||
canSendMobileCaptcha() {
|
||||
return this.countdown === 0 && validateMobile(this.form.mobile, this.form.areaCode);
|
||||
@@ -151,7 +152,7 @@ export default {
|
||||
|
||||
} else {
|
||||
console.error('验证码加载异常:', error);
|
||||
showDanger('验证码加载失败,点击刷新');
|
||||
showDanger(this.$t('register.captchaLoadFailed'));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -168,12 +169,12 @@ export default {
|
||||
// 发送手机验证码
|
||||
sendMobileCaptcha() {
|
||||
if (!validateMobile(this.form.mobile, this.form.areaCode)) {
|
||||
showDanger('请输入正确的手机号码');
|
||||
showDanger(this.$t('retrievePassword.inputCorrectMobile'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证图形验证码
|
||||
if (!this.validateInput(this.form.captcha, '请输入图形验证码')) {
|
||||
if (!this.validateInput(this.form.captcha, this.$t('retrievePassword.captchaRequired'))) {
|
||||
this.fetchCaptcha();
|
||||
return;
|
||||
}
|
||||
@@ -201,9 +202,9 @@ export default {
|
||||
captcha: this.form.captcha,
|
||||
captchaId: this.form.captchaId
|
||||
}, (res) => {
|
||||
showSuccess('验证码发送成功');
|
||||
showSuccess(this.$t('retrievePassword.captchaSendSuccess'));
|
||||
}, (err) => {
|
||||
showDanger(err.data.msg || '验证码发送失败');
|
||||
showDanger(err.data.msg || this.$t('register.captchaSendFailed'));
|
||||
this.countdown = 0;
|
||||
this.fetchCaptcha();
|
||||
});
|
||||
@@ -213,32 +214,45 @@ export default {
|
||||
retrievePassword() {
|
||||
// 验证逻辑
|
||||
if (!validateMobile(this.form.mobile, this.form.areaCode)) {
|
||||
showDanger('请输入正确的手机号码');
|
||||
showDanger(this.$t('retrievePassword.inputCorrectMobile'));
|
||||
return;
|
||||
}
|
||||
if (!this.form.captcha) {
|
||||
showDanger('请输入图形验证码');
|
||||
showDanger(this.$t('retrievePassword.captchaRequired'));
|
||||
return;
|
||||
}
|
||||
if (!this.form.mobileCaptcha) {
|
||||
showDanger('请输入短信验证码');
|
||||
showDanger(this.$t('retrievePassword.mobileCaptchaRequired'));
|
||||
return;
|
||||
}
|
||||
if (this.form.newPassword !== this.form.confirmPassword) {
|
||||
showDanger('两次输入的密码不一致');
|
||||
showDanger(this.$t('retrievePassword.passwordsNotMatch'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 加密密码
|
||||
let encryptedPassword;
|
||||
try {
|
||||
// 拼接图形验证码和新密码进行加密
|
||||
const captchaAndPassword = this.form.captcha + this.form.newPassword;
|
||||
encryptedPassword = sm2Encrypt(this.sm2PublicKey, captchaAndPassword);
|
||||
} catch (error) {
|
||||
console.error("密码加密失败:", error);
|
||||
showDanger(this.$t('sm2.encryptionFailed'));
|
||||
return;
|
||||
}
|
||||
|
||||
Api.user.retrievePassword({
|
||||
phone: this.form.areaCode + this.form.mobile,
|
||||
password: this.form.newPassword,
|
||||
code: this.form.mobileCaptcha
|
||||
password: encryptedPassword,
|
||||
code: this.form.mobileCaptcha,
|
||||
captchaId: this.form.captchaId
|
||||
}, (res) => {
|
||||
showSuccess('密码重置成功');
|
||||
showSuccess(this.$t('retrievePassword.passwordUpdateSuccess'));
|
||||
goToPage('/login');
|
||||
}, (err) => {
|
||||
showDanger(err.data.msg || '重置失败');
|
||||
if (err.data != null && err.data.msg != null && err.data.msg.indexOf('图形验证码') > -1) {
|
||||
showDanger(err.data.msg || this.$t('message.error'));
|
||||
if (err.data != null && err.data.msg != null && (err.data.msg.indexOf('图形验证码') > -1 || err.data.msg.indexOf('Captcha') > -1)) {
|
||||
this.fetchCaptcha()
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user