Skip to content

Commit a68ae29

Browse files
committed
Merge remote-tracking branch 'yudao-ui-admin-vue3/dev' into dev
# Conflicts: # src/views/ai/utils/constants.ts
2 parents 9e628ba + 6550983 commit a68ae29

File tree

30 files changed

+1812
-1236
lines changed

30 files changed

+1812
-1236
lines changed

src/api/ai/image/index.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,11 @@ export interface ImageVO {
1212
publicStatus: boolean // 公开状态
1313
picUrl: string // 任务地址
1414
errorMessage: string // 错误信息
15-
options: object // 配置 Map<string, string>
15+
options: any // 配置 Map<string, string>
1616
taskId: number // 任务编号
17-
buttons: ImageMjButtonsVO[] // mj 操作按钮
18-
createTime: string // 创建时间
19-
finishTime: string // 完成时间
20-
}
21-
22-
export interface ImagePageReqVO {
23-
pageNo: number // 分页编号
24-
pageSize: number // 分页大小
17+
buttons: ImageMidjourneyButtonsVO[] // mj 操作按钮
18+
createTime: Date // 创建时间
19+
finishTime: Date // 完成时间
2520
}
2621

2722
export interface ImageDrawReqVO {
@@ -43,22 +38,22 @@ export interface ImageMidjourneyImagineReqVO {
4338
version: string // 版本
4439
}
4540

46-
export interface ImageMjActionVO {
41+
export interface ImageMidjourneyActionVO {
4742
id: number // 图片编号
4843
customId: string // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
4944
}
5045

51-
export interface ImageMjButtonsVO {
46+
export interface ImageMidjourneyButtonsVO {
5247
customId: string // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
5348
emoji: string // 图标 emoji
5449
label: string // Make Variations 文本
5550
style: number // 样式: 2(Primary)、3(Green)
5651
}
5752

58-
// AI API 密钥 API
53+
// AI 图片 API
5954
export const ImageApi = {
6055
// 获取【我的】绘图分页
61-
getImagePageMy: async (params: ImagePageReqVO) => {
56+
getImagePageMy: async (params: PageParam) => {
6257
return await request.get({ url: `/ai/image/my-page`, params })
6358
},
6459
// 获取【我的】绘图记录
@@ -85,7 +80,7 @@ export const ImageApi = {
8580
return await request.post({ url: `/ai/image/midjourney/imagine`, data })
8681
},
8782
// 【Midjourney】Action 操作(二次生成图片)
88-
midjourneyAction: async (data: ImageMjActionVO) => {
83+
midjourneyAction: async (data: ImageMidjourneyActionVO) => {
8984
return await request.post({ url: `/ai/image/midjourney/action`, data })
9085
},
9186

src/assets/ai/clear.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/utils/download.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,25 @@ const download = {
3232
// 下载 Markdown 方法
3333
markdown: (data: Blob, fileName: string) => {
3434
download0(data, fileName, 'text/markdown')
35+
},
36+
// 下载图片(允许跨域)
37+
image: (url: string) => {
38+
const image = new Image()
39+
image.setAttribute('crossOrigin', 'anonymous')
40+
image.src = url
41+
image.onload = () => {
42+
const canvas = document.createElement('canvas')
43+
canvas.width = image.width
44+
canvas.height = image.height
45+
const ctx = canvas.getContext('2d') as CanvasDrawImage
46+
ctx.drawImage(image, 0, 0, image.width, image.height)
47+
const url = canvas.toDataURL('image/png')
48+
const a = document.createElement('a')
49+
a.href = url
50+
a.download = 'image.png'
51+
a.click()
52+
}
3553
}
3654
}
3755

3856
export default download
39-
40-
/** 图片下载(通过浏览器图片下载) */
41-
export const downloadImage = async (imageUrl) => {
42-
const image = new Image()
43-
image.setAttribute('crossOrigin', 'anonymous')
44-
image.src = imageUrl
45-
image.onload = () => {
46-
const canvas = document.createElement('canvas')
47-
canvas.width = image.width
48-
canvas.height = image.height
49-
const ctx = canvas.getContext('2d') as CanvasDrawImage
50-
ctx.drawImage(image, 0, 0, image.width, image.height)
51-
const url = canvas.toDataURL('image/png')
52-
const a = document.createElement('a')
53-
a.href = url
54-
a.download = 'image.png'
55-
a.click()
56-
}
57-
}

src/views/ai/chat/index/components/message/MessageList.vue

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div ref="messageContainer" class="h-100% overflow-y relative">
2+
<div ref="messageContainer" class="h-100% overflow-y-auto relative">
33
<div class="chat-list" v-for="(item, index) in list" :key="index">
44
<!-- 靠左 message:system、assistant 类型 -->
55
<div class="left-message message-item" v-if="item.type !== 'user'">
@@ -101,13 +101,12 @@ const emits = defineEmits(['onDeleteSuccess', 'onRefresh', 'onEdit']) // 定义
101101
102102
/** 滚动到底部 */
103103
const scrollToBottom = async (isIgnore?: boolean) => {
104-
// 注意要使用 nextTick 以免获取不到dom
105-
await nextTick(() => {
106-
if (isIgnore || !isScrolling.value) {
107-
messageContainer.value.scrollTop =
108-
messageContainer.value.scrollHeight - messageContainer.value.offsetHeight
109-
}
110-
})
104+
// 注意要使用 nextTick 以免获取不到 dom
105+
await nextTick()
106+
if (isIgnore || !isScrolling.value) {
107+
messageContainer.value.scrollTop =
108+
messageContainer.value.scrollHeight - messageContainer.value.offsetHeight
109+
}
111110
}
112111
113112
function handleScroll() {

src/views/ai/chat/index/components/role/RoleList.vue

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010
<el-icon><More /></el-icon>
1111
</el-button>
1212
</span>
13-
<!-- TODO @fan:下面两个 icon,可以使用类似 <Icon icon="ep:question-filled" /> 替代哈 -->
1413
<template #dropdown>
1514
<el-dropdown-menu>
1615
<el-dropdown-item :command="['edit', role]">
17-
<el-icon><EditPen /></el-icon>编辑
16+
<Icon icon="ep:edit" color="#787878" />编辑
1817
</el-dropdown-item>
1918
<el-dropdown-item :command="['delete', role]" style="color: red">
20-
<el-icon><Delete /></el-icon>
21-
<span>删除</span>
19+
<Icon icon="ep:delete" color="red" />删除
2220
</el-dropdown-item>
2321
</el-dropdown-menu>
2422
</template>
@@ -43,9 +41,9 @@
4341
</template>
4442

4543
<script setup lang="ts">
46-
import { ChatRoleVO } from '@/api/ai/model/chatRole'
47-
import { PropType, ref } from 'vue'
48-
import { Delete, EditPen, More } from '@element-plus/icons-vue'
44+
import {ChatRoleVO} from '@/api/ai/model/chatRole'
45+
import {PropType, ref} from 'vue'
46+
import {More} from '@element-plus/icons-vue'
4947
5048
const tabsRef = ref<any>() // tabs ref
5149

src/views/ai/chat/index/components/role/RoleRepository.vue

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
@click="handlerAddRole"
2424
class="ml-20px"
2525
>
26-
<!-- TODO @fan:下面两个 icon,可以使用类似 <Icon icon="ep:question-filled" /> 替代哈 -->
27-
<el-icon>
28-
<User />
29-
</el-icon>
26+
<Icon icon="ep:user" style="margin-right: 5px;" />
3027
添加角色
3128
</el-button>
3229
</div>
@@ -67,15 +64,15 @@
6764
</template>
6865

6966
<script setup lang="ts">
70-
import { ref } from 'vue'
67+
import {ref} from 'vue'
7168
import RoleHeader from './RoleHeader.vue'
7269
import RoleList from './RoleList.vue'
7370
import ChatRoleForm from '@/views/ai/model/chatRole/ChatRoleForm.vue'
7471
import RoleCategoryList from './RoleCategoryList.vue'
75-
import { ChatRoleApi, ChatRolePageReqVO, ChatRoleVO } from '@/api/ai/model/chatRole'
76-
import { ChatConversationApi, ChatConversationVO } from '@/api/ai/chat/conversation'
77-
import { Search, User } from '@element-plus/icons-vue'
78-
import { TabsPaneContext } from 'element-plus'
72+
import {ChatRoleApi, ChatRolePageReqVO, ChatRoleVO} from '@/api/ai/model/chatRole'
73+
import {ChatConversationApi, ChatConversationVO} from '@/api/ai/chat/conversation'
74+
import {Search} from '@element-plus/icons-vue'
75+
import {TabsPaneContext} from 'element-plus'
7976
8077
const router = useRouter() // 路由对象
8178
@@ -222,15 +219,14 @@ onMounted(async () => {
222219
// 获取 role 数据
223220
await getActiveTabsRole()
224221
})
225-
// TODO @fan:css 是不是可以融合到 scss 里面呀?
226222
</script>
227-
<style lang="css">
223+
<!-- 覆盖 element ui css -->
224+
<style lang="scss">
228225
.el-tabs__content {
229226
position: relative;
230227
height: 100%;
231228
overflow: hidden;
232229
}
233-
234230
.el-tabs__nav-scroll {
235231
margin: 10px 20px;
236232
}

src/views/ai/chat/index/index.vue

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
<Icon icon="ep:setting" class="ml-10px" />
2323
</el-button>
2424
<el-button size="small" class="btn" @click="handlerMessageClear">
25-
<img src="@/assets/ai/clear.svg" class="h-14px" />
25+
<Icon icon="heroicons-outline:archive-box-x-mark" color="#787878" />
26+
</el-button>
27+
<el-button size="small" class="btn">
28+
<Icon icon="ep:download" color="#787878" />
29+
</el-button>
30+
<el-button size="small" class="btn" @click="handleGoTopMessage" >
31+
<Icon icon="ep:top" color="#787878" />
2632
</el-button>
27-
<!-- TODO @fan:下面两个 icon,可以使用类似 <Icon icon="ep:question-filled" /> 替代哈 -->
28-
<el-button size="small" :icon="Download" class="btn" />
29-
<el-button size="small" :icon="Top" class="btn" @click="handleGoTopMessage" />
3033
</div>
3134
</el-header>
3235

@@ -180,11 +183,6 @@ const handleConversationClick = async (conversation: ChatConversationVO) => {
180183
// 更新选中的对话 id
181184
activeConversationId.value = conversation.id
182185
activeConversation.value = conversation
183-
// 处理进行中的对话
184-
// TODO @fan:这里,和上面的 “对话进行中,不允许切换” 是不是重叠了?
185-
if (conversationInProgress.value) {
186-
await stopStream()
187-
}
188186
// 刷新 message 列表
189187
await getMessageList()
190188
// 滚动底部
@@ -203,7 +201,11 @@ const handlerConversationDelete = async (delConversation: ChatConversationVO) =>
203201
}
204202
/** 清空选中的对话 */
205203
const handleConversationClear = async () => {
206-
// TODO @fan:需要加一个 对话进行中,不允许切换
204+
// 对话进行中,不允许切换
205+
if (conversationInProgress.value) {
206+
message.alert('对话中,不允许切换!')
207+
return false
208+
}
207209
activeConversationId.value = null
208210
activeConversation.value = null
209211
activeMessageList.value = []
@@ -363,7 +365,7 @@ const handlePromptInput = (event) => {
363365
isComposing.value = false
364366
}, 400)
365367
}
366-
// TODO @fan:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑
368+
// TODO @芋艿:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑
367369
const onCompositionstart = () => {
368370
isComposing.value = true
369371
}
@@ -394,7 +396,6 @@ const doSendMessage = async (content: string) => {
394396
} as ChatMessageVO)
395397
}
396398
397-
// TODO @fan:= = 不知道哪里被改动了。点击【发送】后,不会跳转到消息最底部了。。
398399
/** 真正执行【发送】消息操作 */
399400
const doSendMessageStream = async (userMessage: ChatMessageVO) => {
400401
// 创建 AbortController 实例,以便中止请求
@@ -421,9 +422,8 @@ const doSendMessageStream = async (userMessage: ChatMessageVO) => {
421422
createTime: new Date()
422423
} as ChatMessageVO)
423424
// 1.2 滚动到最下面
424-
nextTick(async () => {
425-
await scrollToBottom() // 底部
426-
})
425+
await nextTick()
426+
await scrollToBottom() // 底部
427427
// 1.3 开始滚动
428428
textRoll()
429429
@@ -573,7 +573,6 @@ onMounted(async () => {
573573

574574
<style lang="scss" scoped>
575575
.ai-layout {
576-
// TODO @范 这里height不能 100% 先这样临时处理 TODO @fan:这个目前要搞处理么?
577576
position: absolute;
578577
flex: 1;
579578
top: 0;

0 commit comments

Comments
 (0)