- Fix disable account API parameter format (pass null instead of empty object) - Add feedback dialog after account disable (aligned with jcloud dashboard) - Implement star rating, reason selection, and feedback submission - Add submitFeedback API function - Add missing Chinese translations for account status messages - Add feedback dialog translations and validation logic
582 lines
17 KiB
TypeScript
582 lines
17 KiB
TypeScript
import axios from 'axios'
|
||
import { get_session_api_headers } from './auth'
|
||
|
||
// 创建或重新生成 API Secret
|
||
export const createApiSecret = async (): Promise<{ success: boolean; data?: { api_key: string; api_secret: string }; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.create_api_secret`,
|
||
{},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data
|
||
if (result?.message) {
|
||
return { success: true, data: result.message }
|
||
}
|
||
return { success: true, data: result }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '创建 API Secret 失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新个人资料
|
||
export interface UpdateProfileParams {
|
||
first_name?: string
|
||
last_name?: string
|
||
username?: string
|
||
mobile_no?: string
|
||
email?: string
|
||
}
|
||
|
||
export const updateProfile = async (params: UpdateProfileParams): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.update_profile`,
|
||
params,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '更新成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '更新个人资料失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取邮箱列表
|
||
export const getEmails = async (): Promise<{ success: boolean; data?: Array<{ type: string; value: string }>; message?: string }> => {
|
||
try {
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.account.get_emails`,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data
|
||
return { success: true, data: result?.message || result }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '获取邮箱列表失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新邮箱
|
||
export const updateEmails = async (data: Array<{ type: string; value: string }>): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.update_emails`,
|
||
{ data: JSON.stringify(data) },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '更新成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '更新邮箱失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取用户 SSH 密钥列表
|
||
export const getUserSSHKeys = async (): Promise<{ success: boolean; data?: Array<any>; message?: string }> => {
|
||
try {
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.account.get_user_ssh_keys`,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data
|
||
return { success: true, data: result?.message || result || [] }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '获取 SSH 密钥列表失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加 SSH 密钥
|
||
export const addSSHKey = async (sshPublicKey: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.client.insert`,
|
||
{
|
||
pg: {
|
||
pagetype: 'User SSH Key',
|
||
ssh_public_key: sshPublicKey,
|
||
user: '' // 后端会自动获取当前用户
|
||
}
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '添加成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '添加 SSH 密钥失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 设置 SSH 密钥为默认
|
||
export const markKeyAsDefault = async (keyName: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.mark_key_as_default`,
|
||
{ key_name: keyName },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '设置成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '设置默认密钥失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 删除 SSH 密钥
|
||
export const deleteSSHKey = async (keyName: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.client.delete`,
|
||
{
|
||
pagetype: 'User SSH Key',
|
||
name: keyName
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '删除成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '删除 SSH 密钥失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取功能标志
|
||
export const getFeatureFlags = async (): Promise<{ success: boolean; data?: Record<string, boolean>; message?: string }> => {
|
||
try {
|
||
// 这里需要根据实际 API 调整
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.account.get_feature_flags`,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data
|
||
return { success: true, data: result?.message || result }
|
||
} catch (error: any) {
|
||
// 如果 API 不存在,返回空对象
|
||
return { success: false, data: {}, message: '功能标志 API 不可用' }
|
||
}
|
||
}
|
||
|
||
// 更新功能标志
|
||
export const updateFeatureFlags = async (values: Record<string, boolean>): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.update_feature_flags`,
|
||
{ values },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '更新成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '更新功能标志失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取用户信息(包含 API Key)
|
||
// 使用 jcloud.api.account.get API 获取账户信息
|
||
export const getUserAccountInfo = async (): Promise<{ success: boolean; data?: any; team?: any; message?: string }> => {
|
||
try {
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.account.get`,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
|
||
if (result?.user) {
|
||
return { success: true, data: result.user, team: result.team }
|
||
}
|
||
|
||
return { success: false, message: 'API 返回的数据中未找到用户信息' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '获取用户信息失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 成为开发者(更新 Team 的 is_developer 字段)
|
||
// 使用 jcloud.api.client.set_value API,与 jcloud dashboard 保持一致
|
||
export const becomeDeveloper = async (teamName: string): Promise<{ success: boolean; data?: any; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.client.set_value`,
|
||
{
|
||
pagetype: 'Team',
|
||
name: teamName,
|
||
fieldname: { is_developer: 1 }
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
// set_value API 返回更新后的 Team 对象
|
||
const result = response.data?.message || response.data
|
||
return { success: true, data: result, message: '成为开发者成功' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '成为开发者失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 禁用账户
|
||
export const disableAccount = async (totpCode?: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.disable_account`,
|
||
{ totp_code: totpCode || null },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '账户已禁用' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '禁用账户失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 启用账户
|
||
export const enableAccount = async (): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.enable_account`,
|
||
{},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '账户已启用' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '启用账户失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新密码
|
||
export const updatePassword = async (params: {
|
||
old_password: string
|
||
new_password: string
|
||
confirm_password: string
|
||
logout_all_sessions?: number
|
||
}): Promise<{ success: boolean; message?: string; redirectUrl?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jingrow.core.pagetype.user.user.update_password`,
|
||
{
|
||
old_password: params.old_password,
|
||
new_password: params.new_password,
|
||
confirm_password: params.confirm_password,
|
||
logout_all_sessions: params.logout_all_sessions || 1
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
return {
|
||
success: true,
|
||
message: '密码更新成功',
|
||
redirectUrl: typeof result === 'string' ? result : undefined
|
||
}
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '更新密码失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 测试密码强度
|
||
export const testPasswordStrength = async (params: {
|
||
old_password: string
|
||
new_password: string
|
||
}): Promise<{ success: boolean; data?: { score: number; feedback: any }; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jingrow.core.pagetype.user.user.test_password_strength`,
|
||
{
|
||
old_password: params.old_password,
|
||
new_password: params.new_password
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
return { success: true, data: result }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '测试密码强度失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 验证合作伙伴代码
|
||
export const validatePartnerCode = async (code: string): Promise<{ success: boolean; isValid: boolean; partnerName?: string; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.partner.validate_partner_code`,
|
||
{ code },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
if (Array.isArray(result) && result.length >= 2) {
|
||
return {
|
||
success: true,
|
||
isValid: result[0] === true,
|
||
partnerName: result[1] || undefined
|
||
}
|
||
}
|
||
return { success: true, isValid: false }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
isValid: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '验证合作伙伴代码失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加合作伙伴代码
|
||
export const addPartnerCode = async (referralCode: string): Promise<{ success: boolean; message?: string; isAlreadySent?: boolean }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.partner.add_partner`,
|
||
{ referral_code: referralCode },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
if (result === 'Request already sent') {
|
||
return { success: true, message: '请求已发送', isAlreadySent: true }
|
||
}
|
||
return { success: true, message: '请求已发送' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '添加合作伙伴代码失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 移除合作伙伴
|
||
export const removePartner = async (): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.partner.remove_partner`,
|
||
{},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '合作伙伴已移除' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '移除合作伙伴失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取合作伙伴名称
|
||
export const getPartnerName = async (partnerEmail: string): Promise<{ success: boolean; data?: string; message?: string }> => {
|
||
try {
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.partner.get_partner_name`,
|
||
{
|
||
params: { partner_email: partnerEmail },
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
return { success: true, data: result }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '获取合作伙伴名称失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取 2FA QR 码 URL
|
||
export const get2FAQRCodeUrl = async (): Promise<{ success: boolean; data?: string; message?: string }> => {
|
||
try {
|
||
const response = await axios.get(
|
||
`/api/action/jcloud.api.account.get_2fa_qr_code_url`,
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
const result = response.data?.message || response.data
|
||
return { success: true, data: result }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '获取 2FA QR 码失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 启用 2FA
|
||
export const enable2FA = async (totpCode: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.enable_2fa`,
|
||
{ totp_code: totpCode },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '双因素认证已启用' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '启用双因素认证失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 禁用 2FA
|
||
export const disable2FA = async (totpCode: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.disable_2fa`,
|
||
{ totp_code: totpCode },
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '双因素认证已禁用' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '禁用双因素认证失败'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 提交反馈
|
||
export const submitFeedback = async (team: string, message: string, note: string, rating: number, route?: string): Promise<{ success: boolean; message?: string }> => {
|
||
try {
|
||
const response = await axios.post(
|
||
`/api/action/jcloud.api.account.feedback`,
|
||
{
|
||
team,
|
||
message,
|
||
note,
|
||
rating,
|
||
route: route || null
|
||
},
|
||
{
|
||
headers: get_session_api_headers(),
|
||
withCredentials: true
|
||
}
|
||
)
|
||
|
||
return { success: true, message: response.data?.message || '反馈已提交' }
|
||
} catch (error: any) {
|
||
return {
|
||
success: false,
|
||
message: error.response?.data?.detail || error.response?.data?.message || error.message || '提交反馈失败'
|
||
}
|
||
}
|
||
}
|