Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
c72cfcea
提交
c72cfcea
authored
11月 13, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 营销内容创作图片增加AI图像生成
上级
fb5296da
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
43 行增加
和
18 行删除
+43
-18
ImageChat.vue
src/components/ImageChat.vue
+13
-4
useAI.js
src/composables/useAI.js
+1
-1
Upload.vue
src/modules/live/product/management/components/Upload.vue
+1
-1
api.ts
src/modules/live/test/api.ts
+1
-1
StepOne.vue
src/modules/material/all/components/StepOne.vue
+4
-8
ViewDialog.vue
src/modules/material/all/components/ViewDialog.vue
+9
-3
Update.vue
src/modules/material/all/views/Update.vue
+13
-0
dictionary.ts
src/utils/dictionary.ts
+1
-0
没有找到文件。
src/
modules/live/product/management/
components/ImageChat.vue
→
src/components/ImageChat.vue
浏览文件 @
c72cfcea
<
script
setup
>
import
{
ref
,
nextTick
}
from
'vue'
import
{
Promotion
,
Close
,
Download
,
ZoomIn
,
Check
}
from
'@element-plus/icons-vue'
import
{
Promotion
,
Close
Bold
,
Download
,
ZoomIn
,
Check
,
Picture
}
from
'@element-plus/icons-vue'
import
{
saveAs
}
from
'file-saver'
import
{
ElMessage
}
from
'element-plus'
import
{
useChatImage
}
from
'@/composables/useChatImage'
...
...
@@ -113,7 +113,7 @@ const handleSend = () => {
</
script
>
<
template
>
<el-dialog
title=
"AI
生成图片
"
:close-on-click-modal=
"false"
@
closed=
"$emit('update:modelValue', false)"
width=
"860px"
>
<el-dialog
title=
"AI
图像生成
"
:close-on-click-modal=
"false"
@
closed=
"$emit('update:modelValue', false)"
width=
"860px"
>
<div
class=
"chat-container"
>
<div
class=
"chat-messages"
ref=
"chatMessages"
>
<div
v-for=
"(message, index) in allMessages"
:key=
"index"
class=
"chat-message"
:class=
"message.role"
>
...
...
@@ -174,13 +174,22 @@ const handleSend = () => {
placeholder=
"输入您的想法或问题..."
@
keyup
.
enter=
"handleSend"
:disabled=
"isLoading"
></el-input>
<template
v-if=
"isLoading"
>
<el-tooltip
content=
"取消生成"
>
<el-button
circle
type=
"primary"
size=
"large"
:icon=
"CloseBold"
@
click=
"cancel"
></el-button>
</el-tooltip>
</
template
>
<
template
v-else
>
<el-button
circle
size=
"large"
:icon=
"Picture"
v-if=
"false"
></el-button>
<el-button
circle
type=
"primary"
size=
"large"
:icon=
"Promotion"
@
click=
"handleSend"
:disabled=
"isLoading || !inputMessage.trim()"
></el-button>
<el-button
type=
"primary"
size=
"large"
:icon=
"Close"
@
click=
"cancel"
v-if=
"isLoading"
></el-button>
:disabled=
"!inputMessage.trim()"
:loading=
"isLoading"
></el-button>
</
template
>
</div>
</div>
</el-dialog>
...
...
src/composables/useAI.js
浏览文件 @
c72cfcea
...
...
@@ -308,7 +308,7 @@ export function useAI(config) {
messages
.
value
.
push
({
type
:
'image'
,
role
:
'assistant'
,
image_url
:
`data:image/jpeg;base64,
${
res
.
url
}
`
,
image_url
:
res
.
url
,
content
:
data
.
content
,
})
}
else
{
...
...
src/modules/live/product/management/components/Upload.vue
浏览文件 @
c72cfcea
...
...
@@ -4,7 +4,7 @@ import { useFileDialog } from '@vueuse/core'
import
{
upload
}
from
'@/utils/upload'
import
dayjs
from
'dayjs'
const
ImageDesign
=
defineAsyncComponent
(()
=>
import
(
'./ImageDesign.vue'
))
const
ImageChat
=
defineAsyncComponent
(()
=>
import
(
'
.
/ImageChat.vue'
))
const
ImageChat
=
defineAsyncComponent
(()
=>
import
(
'
@/components
/ImageChat.vue'
))
const
props
=
defineProps
({
modelValue
:
{
type
:
[
Array
,
String
],
default
:
()
=>
[]
},
...
...
src/modules/live/test/api.ts
浏览文件 @
c72cfcea
...
...
@@ -74,5 +74,5 @@ export function updateImprovementPlan(data: { id: string; improvement_plan: stri
// AI 打分
export
function
aiScore
(
data
:
{
id
:
string
})
{
return
httpRequest
.
post
(
'/api/
dev
/v1/experiment/live-practice/score-live-practice-record'
,
data
)
return
httpRequest
.
post
(
'/api/
lab
/v1/experiment/live-practice/score-live-practice-record'
,
data
)
}
src/modules/material/all/components/StepOne.vue
浏览文件 @
c72cfcea
...
...
@@ -16,7 +16,7 @@ const formRef = ref()
const
rules
=
ref
({
type
:
[{
required
:
true
,
message
:
'请选择营销内容类型'
}],
name
:
[{
required
:
true
,
message
:
'请输入内容名称'
}],
teacher_id
:[{
required
:
true
,
message
:
'请选择老师标签'
}],
teacher_id
:
[{
required
:
true
,
message
:
'请选择老师标签'
}],
})
async
function
handleValidate
()
{
...
...
@@ -85,13 +85,9 @@ const { hasQuestion, teacherMaterialList } = useQuestion(questionType, form.valu
</el-form-item>
<el-form-item
label=
"创作方式"
prop=
"way"
>
<el-radio-group
v-model=
"form.way"
>
<el-radio
v-for=
"item in materialMethodList"
:key=
"item.value"
:value=
"item.value"
:disabled=
"wayDisabled(item, form.type)"
>
{{ item.label }}
</el-radio
>
<
template
v-for=
"item in materialMethodList"
:key=
"item.value"
>
<el-radio
:value=
"item.value"
v-show=
"!wayDisabled(item, form.type)"
>
{{
item
.
label
}}
</el-radio>
</
template
>
</el-radio-group>
</el-form-item>
</el-form>
...
...
src/modules/material/all/components/ViewDialog.vue
浏览文件 @
c72cfcea
...
...
@@ -7,7 +7,7 @@ import {
materialMethodList
,
materialUsageList
,
materialUsersList
,
materialPictureStyleList
materialPictureStyleList
,
}
from
'@/utils/dictionary'
import
AppUpload
from
'@/components/base/AppUpload.vue'
...
...
@@ -31,6 +31,7 @@ const typeName = computed(() => {
</el-form>
<el-divider></el-divider>
<el-form
label-suffix=
":"
label-width=
"120"
ref=
"formRef"
>
<template
v-if=
"data.way != 3"
>
<template
v-if=
"data.type == 2 && data.way == 1"
>
<!-- 图片AI -->
<el-form-item
label=
"图片风格"
prop=
"extend_info.picture_style"
>
...
...
@@ -53,7 +54,11 @@ const typeName = computed(() => {
<
template
v-else
>
<el-form-item
label=
"所属行业"
prop=
"industry_id"
>
<el-select
:model-value=
"data.industry_id"
>
<el-option
v-for=
"item in industryList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id + ''"
></el-option>
<el-option
v-for=
"item in industryList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id + ''"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"使用场景"
prop=
"scenario_type"
>
...
...
@@ -79,10 +84,11 @@ const typeName = computed(() => {
placeholder=
"请输入内容的核心内容或者关键点,多个请使用英文“,”号进行隔离。"
/>
</el-form-item>
</
template
>
</template>
<el-form-item
:label=
"`${typeName}资源`"
prop=
"content"
>
<
template
v-if=
"data.type == 1"
>
<!-- 文本 -->
<el-input
type=
"textarea"
rows=
"12"
:model-value=
"data.content"
></el-input>
<el-input
type=
"textarea"
:
rows=
"12"
:model-value=
"data.content"
></el-input>
</
template
>
<
template
v-if=
"['2', '6', '7', '8'].includes(data.type)"
>
<!-- 图片|二维码|小程序|卡券 -->
...
...
src/modules/material/all/views/Update.vue
浏览文件 @
c72cfcea
...
...
@@ -8,6 +8,7 @@ const props = defineProps<{ action: string }>()
const
StepOne
=
defineAsyncComponent
(()
=>
import
(
'../components/StepOne.vue'
))
const
StepTwo
=
defineAsyncComponent
(()
=>
import
(
'../components/StepTwo.vue'
))
const
StepThree
=
defineAsyncComponent
(()
=>
import
(
'../components/StepThree.vue'
))
const
ImageChat
=
defineAsyncComponent
(()
=>
import
(
'@/components/ImageChat.vue'
))
const
router
=
useRouter
()
const
route
=
useRoute
()
...
...
@@ -45,6 +46,10 @@ function handlePrev() {
// 下一步
function
handleNext
()
{
if
(
form
.
way
==
3
)
{
chatVisible
.
value
=
true
return
}
activeName
.
value
=
activeName
.
value
+
1
}
...
...
@@ -76,6 +81,13 @@ async function handleUpdate() {
ElMessage
.
success
(
'修改成功'
)
router
.
replace
(
'/material'
)
}
const
chatVisible
=
ref
(
false
)
async
function
handleChatSave
(
url
:
string
)
{
form
.
content
=
url
await
handleSubmit
()
chatVisible
.
value
=
false
}
</
script
>
<
template
>
...
...
@@ -97,6 +109,7 @@ async function handleUpdate() {
</el-tab-pane>
</el-tabs>
</AppCard>
<ImageChat
v-model=
"chatVisible"
@
update=
"handleChatSave"
v-if=
"chatVisible"
></ImageChat>
</
template
>
<
style
lang=
"scss"
>
...
...
src/utils/dictionary.ts
浏览文件 @
c72cfcea
...
...
@@ -116,6 +116,7 @@ export const materialMethodList = [
{
label
:
'离线上传 '
,
value
:
'2'
},
{
label
:
'在线AI'
,
value
:
'1'
},
// { label: '在线设计', value: '3' },
{
label
:
'AI图像生成'
,
value
:
'3'
},
]
// 使用场景
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论