diff --git a/demo/LINUX_DEPLOY_COMMANDS.sh b/demo/LINUX_DEPLOY_COMMANDS.sh deleted file mode 100644 index a8621b3..0000000 --- a/demo/LINUX_DEPLOY_COMMANDS.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# Linux服务器部署命令脚本 -# 使用方法: bash LINUX_DEPLOY_COMMANDS.sh - -set -e # 遇到错误立即退出 - -echo "============================================================" -echo "开始部署 Spring Boot + Vue 项目" -echo "============================================================" - -# 进入项目目录 -cd /home/ubuntu/spring-vue-app || cd ~/spring-vue-app || exit 1 - -echo "" -echo "步骤 1: 检查 Dockerfile" -echo "============================================================" -if [ -f "backend/Dockerfile" ]; then - echo "✅ 找到 backend/Dockerfile" - echo "检查使用的镜像:" - grep "FROM" backend/Dockerfile | head -2 -else - echo "❌ 未找到 backend/Dockerfile" - exit 1 -fi - -echo "" -echo "步骤 2: 构建 Docker 镜像" -echo "============================================================" -sudo docker-compose build --no-cache - -echo "" -echo "步骤 3: 启动服务" -echo "============================================================" -sudo docker-compose up -d - -echo "" -echo "步骤 4: 等待服务启动(30秒)" -echo "============================================================" -sleep 30 - -echo "" -echo "步骤 5: 检查服务状态" -echo "============================================================" -sudo docker-compose ps - -echo "" -echo "步骤 6: 健康检查" -echo "============================================================" -# 检查后端健康状态(不依赖Actuator,直接检查根路径) -if curl -f http://localhost:8080/ > /dev/null 2>&1; then - echo "✅ 后端服务健康检查通过" -else - echo "⚠️ 后端服务可能还在启动中,请稍后检查" - echo "查看日志: sudo docker-compose logs backend" -fi - -# 检查前端 -if curl -f http://localhost/ > /dev/null 2>&1; then - echo "✅ 前端服务健康检查通过" -else - echo "⚠️ 前端服务可能还在启动中,请稍后检查" - echo "查看日志: sudo docker-compose logs frontend" -fi - -echo "" -echo "============================================================" -echo "✅ 部署完成!" -echo "============================================================" -echo "" -echo "访问地址:" -echo " 前端: http://localhost" -echo " 后端: http://localhost:8080" -echo "" -echo "常用命令:" -echo " 查看日志: sudo docker-compose logs -f" -echo " 停止服务: sudo docker-compose down" -echo " 重启服务: sudo docker-compose restart" -echo "============================================================" - - diff --git a/demo/backend-dist.zip b/demo/backend-dist.zip deleted file mode 100644 index fb95cb4..0000000 Binary files a/demo/backend-dist.zip and /dev/null differ diff --git a/demo/application-prod.properties.example b/demo/config/examples/application-prod.properties.example similarity index 100% rename from demo/application-prod.properties.example rename to demo/config/examples/application-prod.properties.example diff --git a/demo/env.example b/demo/config/examples/env.example similarity index 100% rename from demo/env.example rename to demo/config/examples/env.example diff --git a/demo/frpc.ini.example b/demo/config/examples/frpc.ini.example similarity index 100% rename from demo/frpc.ini.example rename to demo/config/examples/frpc.ini.example diff --git a/demo/paypal-config.properties.example b/demo/config/examples/paypal-config.properties.example similarity index 100% rename from demo/paypal-config.properties.example rename to demo/config/examples/paypal-config.properties.example diff --git a/demo/tencent-config-template.properties b/demo/config/examples/tencent-config-template.properties similarity index 100% rename from demo/tencent-config-template.properties rename to demo/config/examples/tencent-config-template.properties diff --git a/demo/database_migration_20251119_add_duration.sql b/demo/database_migration_20251119_add_duration.sql deleted file mode 100644 index a7ce298..0000000 --- a/demo/database_migration_20251119_add_duration.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 为 storyboard_video_tasks 表添加 duration 字段 --- 执行时间:2025-11-19 - -ALTER TABLE storyboard_video_tasks -ADD COLUMN duration INT NOT NULL DEFAULT 10 COMMENT '视频时长(秒)' AFTER hd_mode; - --- 更新现有记录,设置默认值为10秒 -UPDATE storyboard_video_tasks SET duration = 10 WHERE duration IS NULL OR duration = 0; diff --git a/demo/database_migration_20251119_task_status_result_url.sql b/demo/database_migration_20251119_task_status_result_url.sql deleted file mode 100644 index 67d6f05..0000000 --- a/demo/database_migration_20251119_task_status_result_url.sql +++ /dev/null @@ -1,9 +0,0 @@ --- 修复 TaskStatus 表的 result_url 字段长度问题 --- 日期: 2025-11-19 --- 原因: Base64 编码的分镜图超过 MEDIUMTEXT 限制 - --- 修改 task_status 表的 result_url 字段为 LONGTEXT -ALTER TABLE task_status MODIFY COLUMN result_url LONGTEXT COMMENT '任务结果URL或Base64数据'; - --- 验证修改 -SHOW FULL COLUMNS FROM task_status WHERE Field = 'result_url'; diff --git a/demo/database_migration_user_error_log.sql b/demo/database_migration_user_error_log.sql deleted file mode 100644 index 2541ba6..0000000 --- a/demo/database_migration_user_error_log.sql +++ /dev/null @@ -1,55 +0,0 @@ --- ===================================================== --- 用户错误日志表 --- 用于记录和统计用户操作过程中产生的错误 --- ===================================================== - -CREATE TABLE IF NOT EXISTS user_error_log ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - username VARCHAR(100) COMMENT '用户名(可为空,未登录用户)', - error_type VARCHAR(50) NOT NULL COMMENT '错误类型枚举', - error_code VARCHAR(50) COMMENT '错误代码', - error_message TEXT COMMENT '错误消息', - error_source VARCHAR(100) NOT NULL COMMENT '错误来源(服务类名或接口路径)', - task_id VARCHAR(100) COMMENT '关联的任务ID', - task_type VARCHAR(50) COMMENT '任务类型', - request_path VARCHAR(500) COMMENT '请求路径', - request_method VARCHAR(10) COMMENT '请求方法 GET/POST等', - request_params TEXT COMMENT '请求参数(JSON格式)', - stack_trace TEXT COMMENT '堆栈跟踪', - ip_address VARCHAR(50) COMMENT 'IP地址', - user_agent VARCHAR(500) COMMENT '用户代理', - created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - - INDEX idx_username (username), - INDEX idx_error_type (error_type), - INDEX idx_created_at (created_at), - INDEX idx_error_source (error_source), - INDEX idx_task_id (task_id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户错误日志表'; - --- ===================================================== --- 错误类型说明: --- TASK_SUBMIT_ERROR - 任务提交失败 --- TASK_PROCESSING_ERROR - 任务处理失败 --- TASK_TIMEOUT - 任务超时 --- TASK_CANCELLED - 任务取消 --- API_CALL_ERROR - API调用失败 --- API_RESPONSE_ERROR - API响应异常 --- API_TIMEOUT - API超时 --- PAYMENT_ERROR - 支付失败 --- PAYMENT_CALLBACK_ERROR- 支付回调异常 --- REFUND_ERROR - 退款失败 --- AUTH_ERROR - 认证失败 --- TOKEN_EXPIRED - Token过期 --- PERMISSION_DENIED - 权限不足 --- DATA_VALIDATION_ERROR - 数据验证失败 --- DATA_NOT_FOUND - 数据未找到 --- DATA_CONFLICT - 数据冲突 --- FILE_UPLOAD_ERROR - 文件上传失败 --- FILE_DOWNLOAD_ERROR - 文件下载失败 --- FILE_PROCESS_ERROR - 文件处理失败 --- SYSTEM_ERROR - 系统错误 --- DATABASE_ERROR - 数据库错误 --- NETWORK_ERROR - 网络错误 --- UNKNOWN - 未知错误 --- ===================================================== diff --git a/demo/database_update_20231203.sql b/demo/database_update_20231203.sql deleted file mode 100644 index 5b4593f..0000000 --- a/demo/database_update_20231203.sql +++ /dev/null @@ -1,38 +0,0 @@ --- ============================================ --- 数据库结构更新脚本 (完整版) --- 日期: 2025-12-03 --- 说明: 将存储Base64图片的字段从TEXT升级为LONGTEXT --- ============================================ - --- 选择数据库 -USE aigc_platform; - --- ============================================ --- 1. storyboard_video_tasks 表 (分镜视频任务) --- ============================================ -ALTER TABLE storyboard_video_tasks MODIFY COLUMN image_url LONGTEXT; -ALTER TABLE storyboard_video_tasks MODIFY COLUMN result_url LONGTEXT; -ALTER TABLE storyboard_video_tasks MODIFY COLUMN storyboard_images LONGTEXT; -ALTER TABLE storyboard_video_tasks MODIFY COLUMN video_urls LONGTEXT; - --- ============================================ --- 2. user_works 表 (用户作品) --- ============================================ -ALTER TABLE user_works MODIFY COLUMN result_url LONGTEXT; -ALTER TABLE user_works MODIFY COLUMN thumbnail_url LONGTEXT; - --- ============================================ --- 3. image_to_video_tasks 表 (图生视频任务) --- ============================================ -ALTER TABLE image_to_video_tasks MODIFY COLUMN result_url LONGTEXT; - --- ============================================ --- 验证结果 --- ============================================ -SELECT '=== 验证修改结果 ===' AS info; -SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE -FROM information_schema.COLUMNS -WHERE TABLE_SCHEMA = 'aigc_platform' - AND COLUMN_NAME IN ('image_url', 'result_url', 'thumbnail_url', 'storyboard_images', 'video_urls') - AND TABLE_NAME IN ('storyboard_video_tasks', 'user_works', 'image_to_video_tasks') -ORDER BY TABLE_NAME, COLUMN_NAME; diff --git a/demo/DATABASE_SCHEMA_GUIDE.md b/demo/docs/DATABASE_SCHEMA_GUIDE.md similarity index 100% rename from demo/DATABASE_SCHEMA_GUIDE.md rename to demo/docs/DATABASE_SCHEMA_GUIDE.md diff --git a/demo/PAYMENT_EVENTS_FLOW.md b/demo/docs/PAYMENT_EVENTS_FLOW.md similarity index 100% rename from demo/PAYMENT_EVENTS_FLOW.md rename to demo/docs/PAYMENT_EVENTS_FLOW.md diff --git a/demo/src/数据库完整结构-宝塔导入.sql b/demo/docs/数据库完整结构-宝塔导入.sql similarity index 100% rename from demo/src/数据库完整结构-宝塔导入.sql rename to demo/docs/数据库完整结构-宝塔导入.sql diff --git a/demo/src/环境变量配置说明-宝塔部署.md b/demo/docs/环境变量配置说明-宝塔部署.md similarity index 100% rename from demo/src/环境变量配置说明-宝塔部署.md rename to demo/docs/环境变量配置说明-宝塔部署.md diff --git a/demo/frontend/public/images/backgrounds/logo-admin.svg b/demo/frontend/public/images/backgrounds/logo-admin.svg index 3a9177e..3f7c4c1 100644 --- a/demo/frontend/public/images/backgrounds/logo-admin.svg +++ b/demo/frontend/public/images/backgrounds/logo-admin.svg @@ -1,14 +1,14 @@ - - - + + + - + - + diff --git a/demo/frontend/public/images/backgrounds/logo.svg b/demo/frontend/public/images/backgrounds/logo.svg index ed6c8fb..1129558 100644 --- a/demo/frontend/public/images/backgrounds/logo.svg +++ b/demo/frontend/public/images/backgrounds/logo.svg @@ -1,15 +1,15 @@ - - - - + + + + - + - - + + diff --git a/demo/frontend/src/api/imageToVideo.js b/demo/frontend/src/api/imageToVideo.js index 0dbe1f2..8329304 100644 --- a/demo/frontend/src/api/imageToVideo.js +++ b/demo/frontend/src/api/imageToVideo.js @@ -57,6 +57,40 @@ export const imageToVideoApi = { }) }, + /** + * 通过图片URL创建图生视频任务(用于"做同款"功能) + * @param {Object} params - 任务参数 + * @param {string} params.imageUrl - 图片URL + * @param {string} params.prompt - 描述文字 + * @param {string} params.aspectRatio - 视频比例 + * @param {number} params.duration - 视频时长 + * @param {boolean} params.hdMode - 是否高清模式 + * @returns {Promise} API响应 + */ + createTaskByUrl(params) { + if (!params) { + throw new Error('参数不能为空') + } + if (!params.imageUrl) { + throw new Error('图片URL不能为空') + } + if (!params.prompt || params.prompt.trim() === '') { + throw new Error('描述文字不能为空') + } + + return request({ + url: '/image-to-video/create-by-url', + method: 'POST', + data: { + imageUrl: params.imageUrl, + prompt: params.prompt.trim(), + aspectRatio: params.aspectRatio || '16:9', + duration: params.duration || 5, + hdMode: params.hdMode || false + } + }) + }, + /** * 获取用户任务列表 * @param {number} page - 页码 diff --git a/demo/frontend/src/components/NavBar.vue b/demo/frontend/src/components/NavBar.vue index 628e468..466db14 100644 --- a/demo/frontend/src/components/NavBar.vue +++ b/demo/frontend/src/components/NavBar.vue @@ -4,7 +4,7 @@ diff --git a/demo/frontend/src/components/PaymentModal.vue b/demo/frontend/src/components/PaymentModal.vue index 83d7ad7..fe2010e 100644 --- a/demo/frontend/src/components/PaymentModal.vue +++ b/demo/frontend/src/components/PaymentModal.vue @@ -140,14 +140,39 @@ const qrCodeUrl = ref('') // 二维码URL const showQrCode = ref(false) // 是否显示二维码 let paymentPollingTimer = null let isPaymentStarted = false // 防止重复调用 +let lastPlanType = '' // 记录上一次的套餐类型 + +// 从orderId中提取套餐类型(如 SUB_standard_xxx -> standard) +const getPlanTypeFromOrderId = (orderId) => { + if (!orderId) return '' + const parts = orderId.split('_') + return parts.length >= 2 ? parts[1] : '' +} // 监听 modelValue 变化 watch(() => props.modelValue, (newVal) => { visible.value = newVal - // 当模态框打开时,自动开始支付流程(只调用一次) - if (newVal && !isPaymentStarted) { - isPaymentStarted = true - handlePay() + // 当模态框打开时,检查是否需要创建新订单 + if (newVal) { + const currentPlanType = getPlanTypeFromOrderId(props.orderId) + + // 如果套餐类型变化了,重置paymentId + if (currentPlanType !== lastPlanType) { + console.log('套餐变化,重置 paymentId,旧套餐:', lastPlanType, '新套餐:', currentPlanType) + currentPaymentId.value = null + lastPlanType = currentPlanType + } else { + console.log('同一套餐,复用 paymentId:', currentPaymentId.value) + } + + qrCodeUrl.value = '' + showQrCode.value = false + + // 只有选择支付宝时才自动生成二维码,PayPal需要用户点击按钮 + if (!isPaymentStarted && selectedMethod.value === 'alipay') { + isPaymentStarted = true + handlePay() + } } // 关闭时重置标志 if (!newVal) { @@ -158,7 +183,7 @@ watch(() => props.modelValue, (newVal) => { // 监听 visible 变化 watch(visible, (newVal) => { emit('update:modelValue', newVal) - // 如果模态框关闭,停止轮询并重置状态 + // 如果模态框关闭,停止轮询并重置二维码状态(但保留paymentId和lastPlanType用于同套餐复用) if (!newVal) { stopPaymentPolling() qrCodeUrl.value = '' @@ -167,13 +192,62 @@ watch(visible, (newVal) => { }) // 选择支付方式 -const selectMethod = (method) => { - // 如果切换了支付方式,需要重置 paymentId,因为支付方式不同需要创建新的支付记录 +const selectMethod = async (method) => { if (selectedMethod.value !== method) { - currentPaymentId.value = null - console.log('切换支付方式,重置 paymentId') + console.log('切换支付方式:', selectedMethod.value, '->', method, '复用 paymentId:', currentPaymentId.value) + selectedMethod.value = method + + // 重置二维码显示 + qrCodeUrl.value = '' + showQrCode.value = false + + // 如果已有支付记录,更新支付方式和描述(复用paymentId) + if (currentPaymentId.value) { + try { + const newDescription = `${props.title} - ${method === 'paypal' ? 'PayPal' : '支付宝'}支付` + const newMethod = method === 'paypal' ? 'PAYPAL' : 'ALIPAY' + + console.log('=== 开始更新支付方式 ===') + console.log('paymentId:', currentPaymentId.value) + console.log('newMethod:', newMethod) + console.log('newDescription:', newDescription) + + const response = await fetch(`/api/payments/${currentPaymentId.value}/method`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token')}` + }, + body: JSON.stringify({ + method: newMethod, + description: newDescription + }) + }) + + console.log('API响应状态:', response.status) + const responseData = await response.json() + console.log('API响应数据:', responseData) + + if (response.ok && responseData.success) { + console.log('✅ 支付方式更新成功,复用paymentId:', currentPaymentId.value) + // 如果切换到支付宝,生成新二维码 + if (method === 'alipay') { + await handleAlipayPayment() + } + } else { + console.error('❌ 支付方式更新失败:', responseData.message || response.statusText) + } + } catch (error) { + console.error('❌ 更新支付方式异常:', error) + } + } else { + // 没有支付记录,如果是支付宝则自动创建 + if (method === 'alipay') { + isPaymentStarted = true + await handlePay() + } + } } - selectedMethod.value = method } // 处理支付 @@ -183,10 +257,9 @@ const handlePay = async () => { // 如果还没有创建支付记录,先创建 if (!currentPaymentId.value) { - // 生成唯一的订单ID,加上时间戳避免重复 - const uniqueOrderId = `${props.orderId}_${Date.now()}` + // 直接使用传入的orderId,不再添加时间戳(Subscription.vue已经处理了) const paymentData = { - orderId: uniqueOrderId, + orderId: props.orderId, amount: props.amount.toString(), method: selectedMethod.value === 'paypal' ? 'PAYPAL' : 'ALIPAY', description: `${props.title} - ${selectedMethod.value === 'paypal' ? 'PayPal' : '支付宝'}支付` @@ -204,6 +277,27 @@ const handlePay = async () => { } else { throw new Error(createResponse.data?.message || '创建支付记录失败') } + } else { + // 已有支付记录,确保支付方式和描述与当前选择一致 + try { + const newDescription = `${props.title} - ${selectedMethod.value === 'paypal' ? 'PayPal' : '支付宝'}支付` + const newMethod = selectedMethod.value === 'paypal' ? 'PAYPAL' : 'ALIPAY' + + await fetch(`/api/payments/${currentPaymentId.value}/method`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token')}` + }, + body: JSON.stringify({ + method: newMethod, + description: newDescription + }) + }) + console.log('支付方式已同步:', newMethod) + } catch (e) { + console.warn('同步支付方式失败,继续支付:', e) + } } // 根据选择的支付方式处理 @@ -332,6 +426,9 @@ const startPaymentPolling = (paymentId) => { stopPaymentPolling() ElMessage.success('支付成功!') emit('pay-success', payment) + // 重置状态,下次购买生成新订单 + currentPaymentId.value = null + lastPlanType = '' // 延迟关闭模态框 setTimeout(() => { visible.value = false @@ -412,6 +509,9 @@ const manualCheckPayment = async () => { stopPaymentPolling() ElMessage.success('支付成功!') emit('pay-success', payment) + // 重置状态,下次购买生成新订单 + currentPaymentId.value = null + lastPlanType = '' setTimeout(() => { visible.value = false }, 1500) diff --git a/demo/frontend/src/locales/en.js b/demo/frontend/src/locales/en.js index d06980a..c5c309b 100644 --- a/demo/frontend/src/locales/en.js +++ b/demo/frontend/src/locales/en.js @@ -507,6 +507,7 @@ export default { permanent: 'Permanent', remainingPoints: 'Remaining Points', plans: 'Plans', + pointsPerYear: 'points/year', currentPackage: 'Current Plan', firstPurchaseDiscount: 'First Purchase Discount up to 15% off', bestValue: 'Best Value', @@ -518,6 +519,23 @@ export default { commercialUse: 'Commercial Use', noWatermark: 'No Watermark', earlyAccess: 'Early Access to New Features', + + // Points and items + points: 'points', + items: 'items', + pointsValidOneYear: 'Points valid for one year', + textToVideo30Points: 'Text to Video: 30 points/item', + imageToVideo30Points: 'Image to Video: 30 points/item', + storyboardImage30Points: 'Storyboard Image: 30 points/time', + storyboardVideo30Points: 'Storyboard Video: 30 points/item', + maxTextToVideo: 'Max Text to Video {count} items', + maxImageToVideo: 'Max Image to Video {count} items', + maxStoryboardImage: 'Max Storyboard Image {count} times', + maxStoryboardVideo: 'Max Storyboard Video {count} items', + textToVideoItems: 'Text to Video {count} items', + imageToVideoItems: 'or Image to Video {count} items', + storyboardImageTimes: 'or Storyboard Image {count} times', + storyboardVideoItems: 'or Storyboard Video {count} items', // Points history related pointsUsageHistory: 'Points Usage History', @@ -591,7 +609,11 @@ export default { onlineUsers: 'Online Users', systemUptime: 'System Uptime', todayVisitors: 'Today Visitors', - loading: 'Loading...' + loading: 'Loading...', + memberManagement: 'Member Management', + orderManagement: 'Order Management', + taskRecord: 'Task Records', + errorStats: 'Error Statistics' }, admin: { @@ -668,7 +690,12 @@ export default { batchDeleteSuccess: 'Batch delete successful', batchDeleteFailed: 'Batch delete failed', loadOrdersFailed: 'Failed to load orders', - apiDataFormatError: 'API data format error' + apiDataFormatError: 'API data format error', + productOrder: 'Product Order', + serviceOrder: 'Service Order', + subscriptionOrder: 'Subscription Order', + digitalProduct: 'Digital Product', + physicalProduct: 'Physical Product' }, tasks: { @@ -685,10 +712,27 @@ export default { processing: 'Processing', failed: 'Failed', cancelled: 'Cancelled', + pending: 'Pending', textToVideo: 'Text to Video', imageToVideo: 'Image to Video', storyboardVideo: 'Storyboard Video', - taskDetail: 'Task Detail' + taskDetail: 'Task Detail', + unknown: 'Unknown', + pointsUnit: ' points', + basicInfo: 'Basic Info', + timeInfo: 'Time Info', + progressInfo: 'Progress Info', + progress: 'Progress', + result: 'Result', + resultLink: 'Result Link', + viewResult: 'View Result', + errorInfo: 'Error Info', + close: 'Close', + updateTime: 'Update Time', + completeTime: 'Complete Time', + taskType: 'Task Type', + resourcesConsumed: 'Resources Consumed', + defaultPoints: '0 points' }, members: { @@ -706,22 +750,73 @@ export default { usernamePlaceholder: 'Enter username', levelPlaceholder: 'Select level', pointsPlaceholder: 'Enter points', - expiryPlaceholder: 'Select expiry date' + expiryPlaceholder: 'Select expiry date', + memberLevel: 'Membership Level', + freeMember: 'Free Member', + standardMember: 'Standard Member', + professionalMember: 'Professional Member', + userStatus: 'User Status', + activeUsers: 'Active Users', + bannedUsers: 'Banned Users', + allUsers: 'All Users', + role: 'Role', + status: 'Status', + setAdmin: 'Set as Admin', + revokeAdmin: 'Revoke Admin', + ban: 'Ban', + unban: 'Unban', + active: 'Active', + banned: 'Banned', + superAdmin: 'Super Admin', + admin: 'Admin', + normalUser: 'User', + userRole: 'User Role', + selectRole: 'Select role', + confirmRoleChange: 'Are you sure to {action} user {username}?', + confirmBanAction: 'Are you sure to {action} user {username}?', + confirmAction: 'Confirm {action}', + actionSuccess: '{action} successful', + actionFailed: '{action} failed' }, apiManagement: { title: 'API Management', apiKey: 'API Key', apiKeyPlaceholder: 'Enter API key', + apiBaseUrl: 'API Base URL', + apiBaseUrlPlaceholder: 'Enter API base URL, e.g. https://ai.comfly.chat', + apiBaseUrlHint: 'Currently using', tokenExpiration: 'Token Expiration', tokenPlaceholder: 'Enter hours (1-720)', hours: 'hours', days: 'days', rangeHint: 'Range: 1-720 hours (1 hour - 30 days)', + atLeastOneRequired: 'Please enter at least one configuration', saveSuccess: 'Saved successfully', saveFailed: 'Save failed' }, + errorStats: { + title: 'Error Statistics', + userAvatar: 'User Avatar', + totalErrors: 'Total Errors', + todayErrors: 'Today Errors', + weekErrors: 'Week Errors', + errorTypeDistribution: 'Error Type Distribution', + last7Days: 'Last 7 Days', + last30Days: 'Last 30 Days', + last90Days: 'Last 90 Days', + times: 'times', + noErrorData: 'No error data', + recentErrors: 'Recent Errors', + refresh: 'Refresh', + time: 'Time', + errorType: 'Error Type', + user: 'User', + taskId: 'Task ID', + errorMessage: 'Error Message' + }, + systemSettings: { title: 'System Settings', membership: 'Membership Pricing', @@ -801,8 +896,6 @@ export default { unknown: 'Unknown', aiModel: 'AI Model Settings', promptOptimization: 'Prompt Optimization Settings', - promptOptimizationApiUrl: 'API Endpoint', - promptOptimizationApiUrlTip: 'Enter the API endpoint for prompt optimization, e.g., https://api.openai.com', promptOptimizationModel: 'Model Name', promptOptimizationModelTip: 'Enter the model name for prompt optimization, e.g., gpt-4o, gemini-pro', storyboardSystemPrompt: 'Storyboard System Prompt', diff --git a/demo/frontend/src/locales/zh.js b/demo/frontend/src/locales/zh.js index b87206e..879bc75 100644 --- a/demo/frontend/src/locales/zh.js +++ b/demo/frontend/src/locales/zh.js @@ -506,6 +506,7 @@ export default { unlimited: '无限', limited: '有限', pointsPerMonth: '积分/年', + pointsPerYear: '积分/年', videoQuality: '视频质量', support: '客服支持', priorityQueue: '优先队列', @@ -532,6 +533,23 @@ export default { commercialUse: '支持商用', noWatermark: '下载去水印', earlyAccess: '新功能优先体验', + + // 积分和条数 + points: '积分', + items: '条', + pointsValidOneYear: '积分一年有效', + textToVideo30Points: '文生视频:30积分/条', + imageToVideo30Points: '图生视频:30积分/条', + storyboardImage30Points: '分镜图生成:30积分/次', + storyboardVideo30Points: '分镜视频生成:30积分/条', + maxTextToVideo: '最多文生视频 {count}条', + maxImageToVideo: '最多图生视频 {count}条', + maxStoryboardImage: '最多分镜图 {count}次', + maxStoryboardVideo: '最多分镜视频 {count}条', + textToVideoItems: '文生视频 {count}条', + imageToVideoItems: '或图生视频 {count}条', + storyboardImageTimes: '或分镜图 {count}次', + storyboardVideoItems: '或分镜视频 {count}条', // 积分历史相关 pointsUsageHistory: '积分使用情况', @@ -604,7 +622,11 @@ export default { systemSettings: '系统设置', onlineUsers: '当前在线用户', systemUptime: '系统运行时间', - todayVisitors: '今日访客' + todayVisitors: '今日访客', + memberManagement: '会员管理', + orderManagement: '订单管理', + taskRecord: '生成任务记录', + errorStats: '错误统计' }, admin: { @@ -669,7 +691,12 @@ export default { orderDetail: '订单详情', basicInfo: '基本信息', orderType: '订单类型', - paymentInfo: '支付信息' + paymentInfo: '支付信息', + productOrder: '商品订单', + serviceOrder: '服务订单', + subscriptionOrder: '订阅订单', + digitalProduct: '数字商品', + physicalProduct: '实体商品' }, tasks: { @@ -686,10 +713,27 @@ export default { processing: '处理中', failed: '失败', cancelled: '已取消', + pending: '待处理', textToVideo: '文生视频', imageToVideo: '图生视频', storyboardVideo: '分镜视频', - taskDetail: '任务详情' + taskDetail: '任务详情', + unknown: '未知', + pointsUnit: '积分', + basicInfo: '基本信息', + timeInfo: '时间信息', + progressInfo: '进度信息', + progress: '进度', + result: '结果', + resultLink: '结果链接', + viewResult: '查看结果', + errorInfo: '错误信息', + close: '关闭', + updateTime: '更新时间', + completeTime: '完成时间', + taskType: '任务类型', + resourcesConsumed: '消耗资源', + defaultPoints: '0积分' }, members: { @@ -707,22 +751,73 @@ export default { usernamePlaceholder: '请输入用户名', levelPlaceholder: '请选择会员等级', pointsPlaceholder: '请输入资源点', - expiryPlaceholder: '请选择到期时间' + expiryPlaceholder: '请选择到期时间', + memberLevel: '会员等级', + freeMember: '免费会员', + standardMember: '标准会员', + professionalMember: '专业会员', + userStatus: '用户状态', + activeUsers: '活跃用户', + bannedUsers: '封禁用户', + allUsers: '全部用户', + role: '角色', + status: '状态', + setAdmin: '设为管理员', + revokeAdmin: '取消管理员', + ban: '封禁', + unban: '解封', + active: '活跃', + banned: '封禁', + superAdmin: '超级管理员', + admin: '管理员', + normalUser: '普通用户', + userRole: '用户角色', + selectRole: '请选择用户角色', + confirmRoleChange: '确定要将用户 {username} {action}吗?', + confirmBanAction: '确定要{action}用户 {username} 吗?', + confirmAction: '确认{action}', + actionSuccess: '{action}成功', + actionFailed: '{action}失败' }, apiManagement: { title: 'API管理', apiKey: 'API密钥', apiKeyPlaceholder: '请输入API密钥', + apiBaseUrl: 'API基础URL', + apiBaseUrlPlaceholder: '请输入API基础URL,如 https://ai.comfly.chat', + apiBaseUrlHint: '当前使用', tokenExpiration: 'Token过期时间', tokenPlaceholder: '请输入小时数(1-720)', hours: '小时', days: '天', rangeHint: '范围:1-720小时(1小时-30天)', + atLeastOneRequired: '请至少输入一个配置项', saveSuccess: '保存成功', saveFailed: '保存失败' }, + errorStats: { + title: '错误类型统计', + userAvatar: '用户头像', + totalErrors: '总错误数', + todayErrors: '今日错误', + weekErrors: '本周错误', + errorTypeDistribution: '错误类型分布', + last7Days: '最近7天', + last30Days: '最近30天', + last90Days: '最近90天', + times: '次', + noErrorData: '暂无错误数据', + recentErrors: '最近错误', + refresh: '刷新', + time: '时间', + errorType: '错误类型', + user: '用户', + taskId: '任务ID', + errorMessage: '错误信息' + }, + systemSettings: { title: '系统设置', membership: '会员收费标准', @@ -779,8 +874,6 @@ export default { confirmCleanup: '确认清理', aiModel: 'AI模型设置', promptOptimization: '提示词优化设置', - promptOptimizationApiUrl: 'API端点', - promptOptimizationApiUrlTip: '输入用于优化提示词的API端点地址,如 https://api.openai.com', promptOptimizationModel: '模型名称', promptOptimizationModelTip: '输入用于优化提示词的模型名称,如 gpt-4o、gemini-pro 等', storyboardSystemPrompt: '分镜图系统引导词', diff --git a/demo/frontend/src/views/AdminDashboard.vue b/demo/frontend/src/views/AdminDashboard.vue index 72e2bcc..9d1e45d 100644 --- a/demo/frontend/src/views/AdminDashboard.vue +++ b/demo/frontend/src/views/AdminDashboard.vue @@ -49,11 +49,10 @@
- +
-