From b5820d9be2f707865d0fde785c33726d182a9e65 Mon Sep 17 00:00:00 2001 From: AIGC Developer Date: Wed, 5 Nov 2025 18:18:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8banana=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E7=94=9F=E6=88=90=E5=88=86=E9=95=9C=E5=9B=BE=E7=89=87?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE=E5=BA=93=E5=88=97?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改RealAIService.submitTextToImageTask使用nano-banana/nano-banana-hd模型 - 支持根据hdMode参数选择模型(标准/高清) - 修复数据库列类型:将result_url等字段改为TEXT类型以支持Base64图片 - 添加数据库修复SQL脚本(fix_database_columns.sql, update_database_schema.sql) - 改进StoryboardVideoService的错误处理和空值检查 - 添加GlobalExceptionHandler全局异常处理 - 优化图片URL提取逻辑,支持url和b64_json两种格式 - 改进响应格式验证,确保data字段不为空 --- demo/ALIPAY_SETUP_GUIDE.md | 3 + demo/CODE_REVIEW_REPORT.md | 3 + demo/EMAIL_VERIFICATION_LOGIN_GUIDE.md | 3 + demo/FRP_QUICK_START.md | 89 +++ demo/IJPAY_USAGE_GUIDE.md | 3 + demo/IMAGE_TO_VIDEO_API_README.md | 3 + demo/POINTS_FREEZE_SYSTEM_README.md | 3 + demo/PasswordChecker.java | 3 + demo/TENCENT_SES_STARTUP_CHECKLIST.md | 3 + demo/TEXT_TO_VIDEO_API_README.md | 3 + demo/USER_WORKS_SYSTEM_README.md | 3 + demo/fix_database_columns.sql | 40 ++ demo/frontend/README.md | 3 + demo/frontend/package.json | 3 +- demo/frontend/src/App-backup.vue | 3 + demo/frontend/src/App.vue | 61 ++ demo/frontend/src/api/payments.js | 5 + demo/frontend/src/api/request.js | 58 +- demo/frontend/src/api/userWorks.js | 3 + demo/frontend/src/components/Footer.vue | 3 + demo/frontend/src/components/PaymentModal.vue | 556 +++++++++++++++--- demo/frontend/src/router/index.js | 16 +- demo/frontend/src/views/Login.vue | 47 +- demo/frontend/src/views/MyWorks.vue | 84 ++- demo/frontend/src/views/Profile.vue | 120 +++- demo/frontend/src/views/Subscription.vue | 232 ++++++-- demo/frontend/src/views/TextToVideoCreate.vue | 10 + demo/frpc.ini.example | 29 + .../demo/controller/AuthApiController.java | 91 ++- .../controller/GlobalExceptionHandler.java | 37 ++ .../demo/controller/PaymentApiController.java | 114 ++++ .../demo/controller/PaymentController.java | 9 +- .../com/example/demo/dto/MailMessage.java | 3 + .../example/demo/model/ImageToVideoTask.java | 2 +- .../demo/model/PointsFreezeRecord.java | 3 + .../demo/model/StoryboardVideoTask.java | 4 +- .../com/example/demo/model/TaskQueue.java | 3 + .../com/example/demo/model/TaskStatus.java | 3 + .../example/demo/model/TextToVideoTask.java | 12 +- .../java/com/example/demo/model/User.java | 21 +- .../java/com/example/demo/model/UserWork.java | 14 +- .../demo/repository/PaymentRepository.java | 18 +- .../demo/repository/TaskStatusRepository.java | 3 + .../security/PlainTextPasswordEncoder.java | 3 + .../example/demo/service/PaymentService.java | 36 +- .../example/demo/service/RealAIService.java | 293 +++++---- .../demo/service/StoryboardVideoService.java | 145 +++-- .../demo/service/TaskQueueService.java | 237 +++++++- .../com/example/demo/service/UserService.java | 5 + .../main/resources/application-dev.properties | 4 +- .../migration/V3__Create_Task_Queue_Table.sql | 3 + .../V4__Add_Points_Freeze_System.sql | 3 + .../V6__Create_Task_Status_Table.sql | 3 + .../resources/templates/orders/admin.html | 3 + .../resources/templates/orders/detail.html | 3 + .../main/resources/templates/orders/form.html | 3 + demo/start-frpc.bat | 36 ++ demo/start-image-to-video-test.bat | 3 + demo/test-api-connection.java | 3 + demo/test_api.py | 3 + demo/test_jwt.py | 3 + demo/test_payment.py | 3 + demo/update_database_schema.sql | 27 + 63 files changed, 2207 insertions(+), 341 deletions(-) create mode 100644 demo/FRP_QUICK_START.md create mode 100644 demo/fix_database_columns.sql create mode 100644 demo/frpc.ini.example create mode 100644 demo/src/main/java/com/example/demo/controller/GlobalExceptionHandler.java create mode 100644 demo/start-frpc.bat create mode 100644 demo/update_database_schema.sql diff --git a/demo/ALIPAY_SETUP_GUIDE.md b/demo/ALIPAY_SETUP_GUIDE.md index 0cf1689..c4d2ced 100644 --- a/demo/ALIPAY_SETUP_GUIDE.md +++ b/demo/ALIPAY_SETUP_GUIDE.md @@ -213,3 +213,6 @@ ngrok http 8080 + + + diff --git a/demo/CODE_REVIEW_REPORT.md b/demo/CODE_REVIEW_REPORT.md index 84b31ee..6697737 100644 --- a/demo/CODE_REVIEW_REPORT.md +++ b/demo/CODE_REVIEW_REPORT.md @@ -108,3 +108,6 @@ - 类型转换警告 + + + diff --git a/demo/EMAIL_VERIFICATION_LOGIN_GUIDE.md b/demo/EMAIL_VERIFICATION_LOGIN_GUIDE.md index c356bcc..baa79ba 100644 --- a/demo/EMAIL_VERIFICATION_LOGIN_GUIDE.md +++ b/demo/EMAIL_VERIFICATION_LOGIN_GUIDE.md @@ -274,3 +274,6 @@ if (result.success) { + + + diff --git a/demo/FRP_QUICK_START.md b/demo/FRP_QUICK_START.md new file mode 100644 index 0000000..60def89 --- /dev/null +++ b/demo/FRP_QUICK_START.md @@ -0,0 +1,89 @@ +# FRP 快速开始指南 + +## 最简单的配置方法(使用 OpenFrp) + +### 1. 注册并创建隧道 + +1. 访问:https://www.openfrp.net/ +2. 注册账号并登录 +3. 点击"创建隧道" +4. 配置: + - 节点:选择国内节点 + - 类型:HTTP + - 本地端口:8080 + - 域名:使用系统分配的或自定义 +5. 创建成功后,记录: + - 访问地址(如:`https://xxx.openfrp.net`) + - 服务器地址 + - Token + +### 2. 下载 FRP 客户端 + +1. 访问:https://github.com/fatedier/frp/releases +2. 下载最新版本的 Windows 版本(如:`frp_0.52.3_windows_amd64.zip`) +3. 解压到 `demo` 目录 + +### 3. 配置 FRP 客户端 + +1. 在 `demo` 目录下创建 `frpc.ini` 文件 +2. 复制 `frpc.ini.example` 的内容 +3. 修改配置: + ```ini + [common] + server_addr = 从OpenFrp控制台获取 + server_port = 7000 + token = 从OpenFrp控制台获取 + + [payment] + type = http + local_ip = 127.0.0.1 + local_port = 8080 + custom_domains = 你的域名.openfrp.net + ``` + +### 4. 启动 FRP + +双击运行 `start-frpc.bat`,或手动运行: + +```powershell +cd demo +.\frpc.exe -c frpc.ini +``` + +### 5. 更新配置文件 + +更新以下文件中的回调URL: + +**`demo/src/main/resources/application-dev.properties`:** +```properties +alipay.notify-url=https://你的域名.openfrp.net/api/payments/alipay/notify +alipay.return-url=https://你的域名.openfrp.net/api/payments/alipay/return +``` + +**`demo/src/main/resources/payment.properties`:** +```properties +alipay.domain=https://你的域名.openfrp.net +alipay.notify-url=https://你的域名.openfrp.net/api/payments/alipay/notify +alipay.return-url=https://你的域名.openfrp.net/api/payments/alipay/return +``` + +### 6. 重启服务器 + +重启 Spring Boot 应用,新的回调地址就会生效。 + +### 7. 测试 + +1. 访问 `https://你的域名.openfrp.net` - 应该能看到应用 +2. 测试回调接口: + ```powershell + Invoke-WebRequest -Uri "https://你的域名.openfrp.net/api/payments/alipay/notify" -Method HEAD + ``` + 应该返回 200,而不是 302 + +## 注意事项 + +- FRP 客户端需要一直运行,关闭后内网穿透会断开 +- 免费服务可能有流量限制,建议用于开发测试 +- 生产环境建议使用固定域名和服务器 + + diff --git a/demo/IJPAY_USAGE_GUIDE.md b/demo/IJPAY_USAGE_GUIDE.md index d134911..5500ddd 100644 --- a/demo/IJPAY_USAGE_GUIDE.md +++ b/demo/IJPAY_USAGE_GUIDE.md @@ -227,3 +227,6 @@ A: IJPay 是对原生 SDK 的封装,提供了更简洁的 API。底层实现 - 支付宝开放平台:https://open.alipay.com + + + diff --git a/demo/IMAGE_TO_VIDEO_API_README.md b/demo/IMAGE_TO_VIDEO_API_README.md index e434f9f..5578f1e 100644 --- a/demo/IMAGE_TO_VIDEO_API_README.md +++ b/demo/IMAGE_TO_VIDEO_API_README.md @@ -294,3 +294,6 @@ grep "img2vid_abc123def456" logs/application.log + + + diff --git a/demo/POINTS_FREEZE_SYSTEM_README.md b/demo/POINTS_FREEZE_SYSTEM_README.md index 170a426..9ba4a3e 100644 --- a/demo/POINTS_FREEZE_SYSTEM_README.md +++ b/demo/POINTS_FREEZE_SYSTEM_README.md @@ -295,3 +295,6 @@ public TaskQueue addTextToVideoTask(String username, String taskId) { + + + diff --git a/demo/PasswordChecker.java b/demo/PasswordChecker.java index 2005028..9904ead 100644 --- a/demo/PasswordChecker.java +++ b/demo/PasswordChecker.java @@ -36,6 +36,9 @@ public class PasswordChecker { + + + diff --git a/demo/TENCENT_SES_STARTUP_CHECKLIST.md b/demo/TENCENT_SES_STARTUP_CHECKLIST.md index 564db90..94318d3 100644 --- a/demo/TENCENT_SES_STARTUP_CHECKLIST.md +++ b/demo/TENCENT_SES_STARTUP_CHECKLIST.md @@ -286,3 +286,6 @@ ResourceNotFound.TemplateNotFound + + + diff --git a/demo/TEXT_TO_VIDEO_API_README.md b/demo/TEXT_TO_VIDEO_API_README.md index a239715..3df0e90 100644 --- a/demo/TEXT_TO_VIDEO_API_README.md +++ b/demo/TEXT_TO_VIDEO_API_README.md @@ -304,3 +304,6 @@ const startPolling = (taskId) => { + + + diff --git a/demo/USER_WORKS_SYSTEM_README.md b/demo/USER_WORKS_SYSTEM_README.md index c884bd3..84bb02a 100644 --- a/demo/USER_WORKS_SYSTEM_README.md +++ b/demo/USER_WORKS_SYSTEM_README.md @@ -174,3 +174,6 @@ const updateWork = async (workId, updateData) => { + + + diff --git a/demo/fix_database_columns.sql b/demo/fix_database_columns.sql new file mode 100644 index 0000000..5cc908f --- /dev/null +++ b/demo/fix_database_columns.sql @@ -0,0 +1,40 @@ +-- 修复数据库列类型:将 VARCHAR 改为 TEXT 以支持 Base64 图片数据 +-- 执行前请先备份数据库! + +USE aigc_platform; + +-- 检查当前列类型(可选,用于查看当前状态) +-- DESCRIBE storyboard_video_tasks; + +-- 更新 storyboard_video_tasks 表 +ALTER TABLE storyboard_video_tasks +MODIFY COLUMN result_url TEXT COMMENT '分镜图结果URL(Base64编码)', +MODIFY COLUMN image_url TEXT COMMENT '参考图片URL', +MODIFY COLUMN prompt TEXT COMMENT '文本描述'; + +-- 更新 text_to_video_tasks 表 +ALTER TABLE text_to_video_tasks +MODIFY COLUMN result_url TEXT COMMENT '视频结果URL'; + +-- 更新 image_to_video_tasks 表 +ALTER TABLE image_to_video_tasks +MODIFY COLUMN result_url TEXT COMMENT '视频结果URL'; + +-- 更新 user_works 表 +ALTER TABLE user_works +MODIFY COLUMN result_url TEXT COMMENT '作品结果URL', +MODIFY COLUMN thumbnail_url TEXT COMMENT '缩略图URL', +MODIFY COLUMN description TEXT COMMENT '作品描述', +MODIFY COLUMN prompt TEXT COMMENT '生成提示词'; + +-- 更新 users 表 +ALTER TABLE users +MODIFY COLUMN avatar TEXT COMMENT '用户头像URL'; + +-- 验证更新结果(可选) +-- DESCRIBE storyboard_video_tasks; +-- DESCRIBE text_to_video_tasks; +-- DESCRIBE image_to_video_tasks; +-- DESCRIBE user_works; +-- DESCRIBE users; + diff --git a/demo/frontend/README.md b/demo/frontend/README.md index cbef172..a65255e 100644 --- a/demo/frontend/README.md +++ b/demo/frontend/README.md @@ -436,6 +436,9 @@ MIT License + + + diff --git a/demo/frontend/package.json b/demo/frontend/package.json index 30a90d0..b5fd11f 100644 --- a/demo/frontend/package.json +++ b/demo/frontend/package.json @@ -15,7 +15,8 @@ "pinia": "^2.1.6", "axios": "^1.5.0", "element-plus": "^2.3.8", - "@element-plus/icons-vue": "^2.1.0" + "@element-plus/icons-vue": "^2.1.0", + "qrcode": "^1.5.3" }, "devDependencies": { "@vitejs/plugin-vue": "^4.3.4", diff --git a/demo/frontend/src/App-backup.vue b/demo/frontend/src/App-backup.vue index 2d9a1ba..f429eb5 100644 --- a/demo/frontend/src/App-backup.vue +++ b/demo/frontend/src/App-backup.vue @@ -33,6 +33,9 @@ console.log('App.vue 加载成功') + + + diff --git a/demo/frontend/src/App.vue b/demo/frontend/src/App.vue index 9a1da28..f0e3090 100644 --- a/demo/frontend/src/App.vue +++ b/demo/frontend/src/App.vue @@ -594,6 +594,67 @@ main.with-navbar { font-family: inherit; } +/* 移除 el-dialog 的所有可能的白色边框 */ +.payment-modal-dialog, +.payment-modal-dialog.el-dialog, +.payment-modal-dialog.el-dialog--center, +.payment-modal-dialog.el-dialog--center.payment-modal, +.el-overlay-dialog .payment-modal-dialog, +.el-overlay-dialog .payment-modal-dialog.el-dialog, +.el-overlay-dialog .payment-modal-dialog.el-dialog--center, +.el-overlay-dialog .payment-modal-dialog.el-dialog--center.payment-modal, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog--center, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog--center.payment-modal { + background: #000000 !important; + background-color: #000000 !important; + border: none !important; + border-width: 0 !important; + border-style: none !important; + border-color: transparent !important; + outline: none !important; + outline-width: 0 !important; + outline-style: none !important; + outline-color: transparent !important; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6) !important; +} + +.payment-modal-dialog .el-dialog__body, +.payment-modal-dialog .el-dialog__header { + background: #000000 !important; + background-color: #000000 !important; + border: none !important; + border-width: 0 !important; + border-left: none !important; + border-right: none !important; + border-top: none !important; + border-bottom: none !important; + outline: none !important; +} + +/* 全局覆盖所有可能的对话框背景 */ +.el-overlay.payment-modal-overlay.el-modal-dialog .el-dialog, +.el-overlay.payment-modal-overlay.el-modal-dialog .el-dialog.el-dialog--center, +.el-overlay.payment-modal-overlay.el-modal-dialog .el-dialog.el-dialog--center.payment-modal, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog--center, +.el-overlay.payment-modal-overlay.el-modal-dialog .payment-modal-dialog.el-dialog--center.payment-modal, +.el-overlay-dialog .el-dialog.el-dialog--center.payment-modal, +.el-overlay-dialog .payment-modal-dialog.el-dialog--center.payment-modal, +.el-dialog.el-dialog--center.payment-modal, +.payment-modal-dialog.el-dialog.el-dialog--center.payment-modal, +/* 使用属性选择器覆盖所有包含 payment-modal 的对话框 */ +[class*="payment-modal"][class*="el-dialog"], +[class*="payment-modal"][class*="el-dialog--center"], +.el-dialog[class*="payment-modal"], +.payment-modal-dialog[class*="el-dialog"] { + background: #000000 !important; + background-color: #000000 !important; + background-image: none !important; +} + /* 滚动条样式 */ ::-webkit-scrollbar { width: 8px; diff --git a/demo/frontend/src/api/payments.js b/demo/frontend/src/api/payments.js index cac60a0..49644cb 100644 --- a/demo/frontend/src/api/payments.js +++ b/demo/frontend/src/api/payments.js @@ -52,3 +52,8 @@ export const handleAlipayCallback = (params) => { export const getPaymentStats = () => { return api.get('/payments/stats') } + +// 获取用户订阅信息 +export const getUserSubscriptionInfo = () => { + return api.get('/payments/subscription/info') +} diff --git a/demo/frontend/src/api/request.js b/demo/frontend/src/api/request.js index f897890..cc67d94 100644 --- a/demo/frontend/src/api/request.js +++ b/demo/frontend/src/api/request.js @@ -9,8 +9,13 @@ const api = axios.create({ baseURL: getApiBaseURL(), timeout: 900000, // 增加到15分钟,适应视频生成时间 withCredentials: true, + maxRedirects: 0, // 不自动跟随重定向,手动处理302 headers: { 'Content-Type': 'application/json' + }, + validateStatus: function (status) { + // 允许所有状态码,包括302,让拦截器处理 + return status >= 200 && status < 600 } }) @@ -19,8 +24,11 @@ api.interceptors.request.use( (config) => { // 使用JWT认证,添加Authorization头 const token = sessionStorage.getItem('token') - if (token) { + if (token && token !== 'null' && token.trim() !== '') { config.headers.Authorization = `Bearer ${token}` + console.log('请求拦截器:添加Authorization头,token长度:', token.length) + } else { + console.warn('请求拦截器:未找到有效的token') } return config }, @@ -33,6 +41,33 @@ api.interceptors.request.use( // 响应拦截器 api.interceptors.response.use( (response) => { + // 检查是否是HTML响应(可能是302重定向的结果) + if (response.data && typeof response.data === 'string' && response.data.trim().startsWith(' { + + + diff --git a/demo/frontend/src/components/Footer.vue b/demo/frontend/src/components/Footer.vue index 0f53109..11b6a1f 100644 --- a/demo/frontend/src/components/Footer.vue +++ b/demo/frontend/src/components/Footer.vue @@ -95,6 +95,9 @@ + + + diff --git a/demo/frontend/src/components/PaymentModal.vue b/demo/frontend/src/components/PaymentModal.vue index 3cbc736..f9c2569 100644 --- a/demo/frontend/src/components/PaymentModal.vue +++ b/demo/frontend/src/components/PaymentModal.vue @@ -8,9 +8,9 @@ :close-on-click-modal="false" :close-on-press-escape="true" @close="handleClose" - center :show-close="true" custom-class="payment-modal-dialog" + :modal-class="'payment-modal-overlay'" >
@@ -36,8 +36,8 @@
- -
+ +
@@ -52,6 +52,26 @@

请使用支付宝扫描上方二维码完成支付

支付完成后页面将自动更新

+ +
+ +
@@ -63,10 +83,10 @@