From 3eb017718835c129039caf72b3311460acb92fb3 Mon Sep 17 00:00:00 2001 From: GeekMaster Date: Wed, 17 Sep 2025 16:04:04 +0800 Subject: [PATCH] add prompt edit function --- CHANGELOG.md | 1 + api/core/types/geekai.go | 12 +- api/core/types/jimeng.go | 8 +- api/core/types/moderation.go | 32 +- api/core/types/oss.go | 46 +- api/core/types/payment.go | 42 +- api/core/types/sms.go | 22 +- api/core/types/smtp.go | 12 +- api/handler/chat_handler.go | 6 +- api/handler/jimeng_handler.go | 4 + web/src/assets/css/jimeng.scss | 4 + web/src/assets/css/video.scss | 13 +- web/src/components/ChatPrompt.vue | 315 +++++--------- web/src/components/ChatPromptLine.vue | 265 ++++++++++++ web/src/components/ChatReply.vue | 393 ++--------------- web/src/components/ChatReplyLine.vue | 450 ++++++++++++++++++++ web/src/components/ChatSetting.vue | 20 +- web/src/store/jimeng.js | 7 + web/src/store/sharedata.js | 5 - web/src/views/ChatExport.vue | 8 +- web/src/views/ChatPlus.vue | 112 ++--- web/src/views/Jimeng.vue | 2 +- web/src/views/admin/jimeng/JimengConfig.vue | 4 +- web/src/views/mobile/JimengCreate.vue | 2 +- 24 files changed, 1018 insertions(+), 767 deletions(-) create mode 100644 web/src/components/ChatPromptLine.vue create mode 100644 web/src/components/ChatReplyLine.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index f2ee79f4..bf1fd05b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Bug 修复:微信登录配置更新后,没有同步更新到系统配置 - 功能优化: 给 AI 对话 API 加上线程锁,确保同一个用户同时只有一个对话请求 - 功能新增:支持即梦 AI 4.0 图片编辑,即梦 AI 数字人,动作迁移功能。🔥🔥🔥 +- 功能新增:新增 AI 对话编辑功能,并优化了重新生成逻辑 ## v4.2.6 diff --git a/api/core/types/geekai.go b/api/core/types/geekai.go index 1e525fe6..39ca2a48 100644 --- a/api/core/types/geekai.go +++ b/api/core/types/geekai.go @@ -20,14 +20,14 @@ func init() { // CaptchaConfig 行为验证码配置 type CaptchaConfig struct { - ApiKey string `json:"api_key"` - Type string `json:"type"` // 验证码类型, 可选值: "dot" 或 "slide" - Enabled bool `json:"enabled"` + ApiKey string `json:"api_key,omitempty"` + Type string `json:"type,omitempty"` // 验证码类型, 可选值: "dot" 或 "slide" + Enabled bool `json:"enabled,omitempty"` } // WxLoginConfig 微信登录配置 type WxLoginConfig struct { - ApiKey string `json:"api_key"` - NotifyURL string `json:"notify_url"` // 登录成功回调 URL - Enabled bool `json:"enabled"` // 是否启用微信登录 + ApiKey string `json:"api_key,omitempty"` + NotifyURL string `json:"notify_url,omitempty"` // 登录成功回调 URL + Enabled bool `json:"enabled,omitempty"` // 是否启用微信登录 } diff --git a/api/core/types/jimeng.go b/api/core/types/jimeng.go index 21ce3d54..f38b8019 100644 --- a/api/core/types/jimeng.go +++ b/api/core/types/jimeng.go @@ -3,12 +3,12 @@ package types // JimengConfig 即梦AI配置 type JimengConfig struct { // 即梦AI的AccessKey和SecretKey - AccessKey string `json:"access_key"` - SecretKey string `json:"secret_key"` + AccessKey string `json:"access_key,omitempty"` + SecretKey string `json:"secret_key,omitempty"` // 火山引擎大模型专用的验证方式 - ApiKey string `json:"api_key"` + ApiKey string `json:"api_key,omitempty"` // 算力配置 - Powers map[string]int `json:"powers"` + Powers map[string]int `json:"powers,omitempty"` } // JMTaskStatus 任务状态 diff --git a/api/core/types/moderation.go b/api/core/types/moderation.go index a5310439..504d0195 100644 --- a/api/core/types/moderation.go +++ b/api/core/types/moderation.go @@ -9,13 +9,13 @@ package types // 文本审查 type ModerationConfig struct { - Enable bool `json:"enable"` // 是否启用文本审查 - Active string `json:"active"` - EnableGuide bool `json:"enable_guide"` // 是否启用模型引导提示词 - GuidePrompt string `json:"guide_prompt"` // 模型引导提示词 - Gitee ModerationGiteeConfig `json:"gitee"` - Baidu ModerationBaiduConfig `json:"baidu"` - Tencent ModerationTencentConfig `json:"tencent"` + Enable bool `json:"enable,omitempty"` // 是否启用文本审查 + Active string `json:"active,omitempty"` + EnableGuide bool `json:"enable_guide,omitempty"` // 是否启用模型引导提示词 + GuidePrompt string `json:"guide_prompt,omitempty"` // 模型引导提示词 + Gitee ModerationGiteeConfig `json:"gitee,omitempty"` + Baidu ModerationBaiduConfig `json:"baidu,omitempty"` + Tencent ModerationTencentConfig `json:"tencent,omitempty"` } const ( @@ -26,26 +26,26 @@ const ( // GiteeAI 文本审查配置 type ModerationGiteeConfig struct { - ApiKey string `json:"api_key"` - Model string `json:"model"` // 文本审核模型 + ApiKey string `json:"api_key,omitempty"` + Model string `json:"model,omitempty"` // 文本审核模型 } // 百度文本审查配置 type ModerationBaiduConfig struct { - AccessKey string `json:"access_key"` - SecretKey string `json:"secret_key"` + AccessKey string `json:"access_key,omitempty"` + SecretKey string `json:"secret_key,omitempty"` } // 腾讯云文本审查配置 type ModerationTencentConfig struct { - AccessKey string `json:"access_key"` - SecretKey string `json:"secret_key"` + AccessKey string `json:"access_key,omitempty"` + SecretKey string `json:"secret_key,omitempty"` } type ModerationResult struct { - Flagged bool `json:"flagged"` - Categories map[string]bool `json:"categories"` - CategoryScores map[string]float64 `json:"category_scores"` + Flagged bool `json:"flagged,omitempty"` + Categories map[string]bool `json:"categories,omitempty"` + CategoryScores map[string]float64 `json:"category_scores,omitempty"` } var ModerationCategories = map[string]string{ diff --git a/api/core/types/oss.go b/api/core/types/oss.go index e22f9ef9..5e65e9ed 100644 --- a/api/core/types/oss.go +++ b/api/core/types/oss.go @@ -8,39 +8,39 @@ package types // * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ type OSSConfig struct { - Active string `json:"active"` - Local LocalStorageConfig `json:"local"` - Minio MiniOssConfig `json:"minio"` - QiNiu QiNiuOssConfig `json:"qiniu"` - AliYun AliYunOssConfig `json:"aliyun"` + Active string `json:"active,omitempty"` + Local LocalStorageConfig `json:"local,omitempty"` + Minio MiniOssConfig `json:"minio,omitempty"` + QiNiu QiNiuOssConfig `json:"qiniu,omitempty"` + AliYun AliYunOssConfig `json:"aliyun,omitempty"` } type MiniOssConfig struct { - Endpoint string `json:"endpoint"` - AccessKey string `json:"access_key"` - AccessSecret string `json:"access_secret"` - Bucket string `json:"bucket"` - UseSSL bool `json:"use_ssl"` - Domain string `json:"domain"` + Endpoint string `json:"endpoint,omitempty"` + AccessKey string `json:"access_key,omitempty"` + AccessSecret string `json:"access_secret,omitempty"` + Bucket string `json:"bucket,omitempty"` + UseSSL bool `json:"use_ssl,omitempty"` + Domain string `json:"domain,omitempty"` } type QiNiuOssConfig struct { - Zone string `json:"zone"` - AccessKey string `json:"access_key"` - AccessSecret string `json:"access_secret"` - Bucket string `json:"bucket"` - Domain string `json:"domain"` + Zone string `json:"zone,omitempty"` + AccessKey string `json:"access_key,omitempty"` + AccessSecret string `json:"access_secret,omitempty"` + Bucket string `json:"bucket,omitempty"` + Domain string `json:"domain,omitempty"` } type AliYunOssConfig struct { - Endpoint string `json:"endpoint"` - AccessKey string `json:"access_key"` - AccessSecret string `json:"access_secret"` - Bucket string `json:"bucket"` - Domain string `json:"domain"` + Endpoint string `json:"endpoint,omitempty"` + AccessKey string `json:"access_key,omitempty"` + AccessSecret string `json:"access_secret,omitempty"` + Bucket string `json:"bucket,omitempty"` + Domain string `json:"domain,omitempty"` } type LocalStorageConfig struct { - BasePath string `json:"base_path"` - BaseURL string `json:"base_url"` + BasePath string `json:"base_path,omitempty"` + BaseURL string `json:"base_url,omitempty"` } diff --git a/api/core/types/payment.go b/api/core/types/payment.go index 83011356..d96fff6c 100644 --- a/api/core/types/payment.go +++ b/api/core/types/payment.go @@ -1,19 +1,19 @@ package types type PaymentConfig struct { - Alipay AlipayConfig `json:"alipay"` // 支付宝支付渠道配置 - Epay EpayConfig `json:"epay"` // 易支付配置 - WxPay WxPayConfig `json:"wxpay"` // 微信支付渠道配置 + Alipay AlipayConfig `json:"alipay,omitempty"` // 支付宝支付渠道配置 + Epay EpayConfig `json:"epay,omitempty"` // 易支付配置 + WxPay WxPayConfig `json:"wxpay,omitempty"` // 微信支付渠道配置 } // AlipayConfig 支付宝支付配置 type AlipayConfig struct { - Enabled bool `json:"enabled"` // 是否启用该支付通道 - SandBox bool `json:"sandbox"` // 是否沙盒环境 - AppId string `json:"app_id"` // 应用 ID - PrivateKey string `json:"private_key"` // 应用私钥 - AlipayPublicKey string `json:"alipay_public_key"` // 支付宝公钥 - Domain string `json:"domain"` // 支付回调域名 + Enabled bool `json:"enabled,omitempty"` // 是否启用该支付通道 + SandBox bool `json:"sandbox,omitempty"` // 是否沙盒环境 + AppId string `json:"app_id,omitempty"` // 应用 ID + PrivateKey string `json:"private_key,omitempty"` // 应用私钥 + AlipayPublicKey string `json:"alipay_public_key,omitempty"` // 支付宝公钥 + Domain string `json:"domain,omitempty"` // 支付回调域名 } func (c *AlipayConfig) Equal(other *AlipayConfig) bool { @@ -25,13 +25,13 @@ func (c *AlipayConfig) Equal(other *AlipayConfig) bool { // WxPayConfig 微信支付配置 type WxPayConfig struct { - Enabled bool `json:"enabled"` // 是否启用该支付通道 - AppId string `json:"app_id"` // 公众号的APPID,如:wxd678efh567hg6787 - MchId string `json:"mch_id"` // 直连商户的商户号,由微信支付生成并下发 - SerialNo string `json:"serial_no"` // 商户证书的证书序列号 - PrivateKey string `json:"private_key"` // 商户证书私钥 - ApiV3Key string `json:"api_v3_key"` // API V3 秘钥 - Domain string `json:"domain"` // 支付回调域名 + Enabled bool `json:"enabled,omitempty"` // 是否启用该支付通道 + AppId string `json:"app_id,omitempty"` // 公众号的APPID,如:wxd678efh567hg6787 + MchId string `json:"mch_id,omitempty"` // 直连商户的商户号,由微信支付生成并下发 + SerialNo string `json:"serial_no,omitempty"` // 商户证书的证书序列号 + PrivateKey string `json:"private_key,omitempty"` // 商户证书私钥 + ApiV3Key string `json:"api_v3_key,omitempty"` // API V3 秘钥 + Domain string `json:"domain,omitempty"` // 支付回调域名 } func (c *WxPayConfig) Equal(other *WxPayConfig) bool { @@ -45,11 +45,11 @@ func (c *WxPayConfig) Equal(other *WxPayConfig) bool { // EpayConfig 易支付配置 type EpayConfig struct { - Enabled bool `json:"enabled"` // 是否启用该支付通道 - AppId string `json:"app_id"` // 商户 ID - PrivateKey string `json:"private_key"` // 私钥 - ApiURL string `json:"api_url"` // z支付 API 网关 - Domain string `json:"domain"` // 支付回调域名 + Enabled bool `json:"enabled,omitempty"` // 是否启用该支付通道 + AppId string `json:"app_id,omitempty"` // 商户 ID + PrivateKey string `json:"private_key,omitempty"` // 私钥 + ApiURL string `json:"api_url,omitempty"` // z支付 API 网关 + Domain string `json:"domain,omitempty"` // 支付回调域名 } func (c *EpayConfig) Equal(other *EpayConfig) bool { diff --git a/api/core/types/sms.go b/api/core/types/sms.go index 7c95ab41..608fe9e6 100644 --- a/api/core/types/sms.go +++ b/api/core/types/sms.go @@ -8,23 +8,23 @@ package types // * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ type SMSConfig struct { - Active string `json:"active"` - Ali SmsConfigAli `json:"aliyun"` - Bao SmsConfigBao `json:"bao"` + Active string `json:"active,omitempty"` + Ali SmsConfigAli `json:"aliyun,omitempty"` + Bao SmsConfigBao `json:"bao,omitempty"` } // SmsConfigAli 阿里云短信平台配置 type SmsConfigAli struct { - AccessKey string `json:"access_key"` - AccessSecret string `json:"access_secret"` - Sign string `json:"sign"` // 短信签名 - CodeTempId string `json:"code_temp_id"` // 验证码短信模板 ID + AccessKey string `json:"access_key,omitempty"` + AccessSecret string `json:"access_secret,omitempty"` + Sign string `json:"sign,omitempty"` // 短信签名 + CodeTempId string `json:"code_temp_id,omitempty"` // 验证码短信模板 ID } // SmsConfigBao 短信宝平台配置 type SmsConfigBao struct { - Username string `json:"username"` //短信宝平台注册的用户名 - Password string `json:"password"` //短信宝平台注册的密码 - Sign string `json:"sign"` // 短信签名 - CodeTemplate string `json:"code_template"` // 验证码短信模板 匹配 + Username string `json:"username,omitempty"` //短信宝平台注册的用户名 + Password string `json:"password,omitempty"` //短信宝平台注册的密码 + Sign string `json:"sign,omitempty"` // 短信签名 + CodeTemplate string `json:"code_template,omitempty"` // 验证码短信模板 匹配 } diff --git a/api/core/types/smtp.go b/api/core/types/smtp.go index 5625622c..2a454cff 100644 --- a/api/core/types/smtp.go +++ b/api/core/types/smtp.go @@ -8,12 +8,12 @@ package types // * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ type SmtpConfig struct { - UseTls bool `json:"use_tls"` // 是否使用 TLS 发送 - Host string `json:"host"` // 邮件服务器地址 - Port int `json:"port"` // 邮件服务器端口 - AppName string `json:"app_name"` // 应用名称 - From string `json:"from"` // 发件人邮箱地址 - Password string `json:"password"` // 发件人邮箱密码 + UseTls bool `json:"use_tls,omitempty"` // 是否使用 TLS 发送 + Host string `json:"host,omitempty"` // 邮件服务器地址 + Port int `json:"port,omitempty"` // 邮件服务器端口 + AppName string `json:"app_name,omitempty"` // 应用名称 + From string `json:"from,omitempty"` // 发件人邮箱地址 + Password string `json:"password,omitempty"` // 发件人邮箱密码 } func (s *SmtpConfig) Equal(other *SmtpConfig) bool { diff --git a/api/handler/chat_handler.go b/api/handler/chat_handler.go index 207ce608..d52c5d09 100644 --- a/api/handler/chat_handler.go +++ b/api/handler/chat_handler.go @@ -272,9 +272,9 @@ func (h *ChatHandler) sendMessage(ctx context.Context, input ChatInput, c *gin.C if h.App.SysConfig.Base.ContextDeep > 0 { var historyMessages []model.ChatMessage dbSession := h.DB.Session(&gorm.Session{}).Where("chat_id", input.ChatId) - if input.LastMsgId > 0 { // 重新生成逻辑 + if input.LastMsgId > 0 { // 重新生成和编辑逻辑 var lastMessage model.ChatMessage - err = dbSession.Where("id <= ?", input.LastMsgId).Where("type", types.PromptMsg).First(&lastMessage).Error + err = dbSession.Where("id < ?", input.LastMsgId).Where("type", types.ReplyMsg).Order("id DESC").First(&lastMessage).Error if err != nil { input.LastMsgId = 0 } else { @@ -282,7 +282,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, input ChatInput, c *gin.C } dbSession = dbSession.Where("id < ?", input.LastMsgId) // 删除对应的聊天记录 - h.DB.Debug().Where("chat_id", input.ChatId).Where("id >= ?", input.LastMsgId).Delete(&model.ChatMessage{}) + h.DB.Debug().Where("chat_id", input.ChatId).Where("id > ?", input.LastMsgId).Delete(&model.ChatMessage{}) } err = dbSession.Limit(h.App.SysConfig.Base.ContextDeep).Order("id DESC").Find(&historyMessages).Error if err == nil { diff --git a/api/handler/jimeng_handler.go b/api/handler/jimeng_handler.go index 06aea75c..de6b0778 100644 --- a/api/handler/jimeng_handler.go +++ b/api/handler/jimeng_handler.go @@ -179,6 +179,10 @@ func (h *JimengHandler) Jobs(c *gin.Context) { query = query.Where("type = ?", types.JMTaskTypeImage) case "video": query = query.Where("type = ?", types.JMTaskTypeVideo) + case "virtual_human": + query = query.Where("type = ?", types.JMTaskTypeVirtualHuman) + case "action_transfer": + query = query.Where("type = ?", types.JMTaskTypeActionTransfer) } if len(req.Ids) > 0 { diff --git a/web/src/assets/css/jimeng.scss b/web/src/assets/css/jimeng.scss index 32b86273..8dec06ca 100644 --- a/web/src/assets/css/jimeng.scss +++ b/web/src/assets/css/jimeng.scss @@ -343,6 +343,10 @@ margin: 12px 0 16px; background-color: var(--el-fill-color-blank); + .el-collapse { + --el-collapse-border-color: none; + } + .guide-title { display: flex; align-items: center; diff --git a/web/src/assets/css/video.scss b/web/src/assets/css/video.scss index 2e89b1d4..e44bef0b 100644 --- a/web/src/assets/css/video.scss +++ b/web/src/assets/css/video.scss @@ -14,7 +14,7 @@ } :deep(.el-textarea__inner) { - background: transparent; + // background: transparent; color: var(--text-theme-color); } @@ -104,7 +104,8 @@ color: var(--text-theme-color); } - .el-input, .el-slider { + .el-input, + .el-slider { width: 100%; } @@ -422,7 +423,8 @@ flex-flow: column; padding: 0 20px; - .prompt, .failed { + .prompt, + .failed { padding: 0; font-size: 16px; max-height: 80px; @@ -547,7 +549,8 @@ .left .container { width: 120px; - .video, .el-image { + .video, + .el-image { width: 120px; } } @@ -562,4 +565,4 @@ } } } -} \ No newline at end of file +} diff --git a/web/src/components/ChatPrompt.vue b/web/src/components/ChatPrompt.vue index 4b403646..267360c5 100644 --- a/web/src/components/ChatPrompt.vue +++ b/web/src/components/ChatPrompt.vue @@ -1,5 +1,5 @@