mirror of
https://gitee.com/hhyykk/ipms-sjy-ui.git
synced 2025-07-23 23:35:06 +08:00
【代码优化】分支合并
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
<h3 class="m-0 px-7 shrink-0 flex items-center justify-between">
|
||||
<span>思维导图预览</span>
|
||||
<!-- 展示在右上角 -->
|
||||
<el-button type="primary" v-show="isEnd" @click="downloadImage" size="small">
|
||||
<el-button v-show="isEnd" size="small" type="primary" @click="downloadImage">
|
||||
<template #icon>
|
||||
<Icon icon="ph:copy-bold" />
|
||||
</template>
|
||||
@ -20,14 +20,14 @@
|
||||
</div>
|
||||
|
||||
<div ref="mindMapRef" class="wh-full">
|
||||
<svg ref="svgRef" class="w-full" :style="{ height: `${contentAreaHeight}px` }" />
|
||||
<svg ref="svgRef" :style="{ height: `${contentAreaHeight}px` }" class="w-full" />
|
||||
<div ref="toolBarRef" class="absolute bottom-[10px] right-5"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { Markmap } from 'markmap-view'
|
||||
import { Transformer } from 'markmap-lib'
|
||||
import { Toolbar } from 'markmap-toolbar'
|
||||
@ -43,7 +43,7 @@ const props = defineProps<{
|
||||
isGenerating: boolean // 是否正在生成
|
||||
isStart: boolean // 开始状态,开始时需要清除 html
|
||||
}>()
|
||||
const contentRef = ref<HTMLDivElement>() // 右侧出来header以下的区域
|
||||
const contentRef = ref<HTMLDivElement>() // 右侧出来 header 以下的区域
|
||||
const mdContainerRef = ref<HTMLDivElement>() // markdown 的容器,用来滚动到底下的
|
||||
const mindMapRef = ref<HTMLDivElement>() // 思维导图的容器
|
||||
const svgRef = ref<SVGElement>() // 思维导图的渲染 svg
|
||||
@ -106,8 +106,7 @@ const processContent = (text: string) => {
|
||||
return arr.join('\n')
|
||||
}
|
||||
|
||||
/** 下载图片 */
|
||||
// download SVG to png file
|
||||
/** 下载图片:download SVG to png file */
|
||||
const downloadImage = () => {
|
||||
const svgElement = mindMapRef.value
|
||||
// 将 SVG 渲染到图片对象
|
||||
@ -138,6 +137,7 @@ defineExpose({
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.my-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -150,13 +150,16 @@ defineExpose({
|
||||
@extend .hide-scroll-bar;
|
||||
}
|
||||
}
|
||||
|
||||
// markmap的tool样式覆盖
|
||||
:deep(.markmap) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.mm-toolbar-brand) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:deep(.mm-toolbar) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -3,9 +3,9 @@
|
||||
<!--表单区域-->
|
||||
<Left
|
||||
ref="leftRef"
|
||||
:is-generating="isGenerating"
|
||||
@submit="submit"
|
||||
@direct-generate="directGenerate"
|
||||
:is-generating="isGenerating"
|
||||
/>
|
||||
<!--右边生成思维导图区域-->
|
||||
<Right
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import Left from './components/Left.vue'
|
||||
import Right from './components/Right.vue'
|
||||
import { AiMindMapApi, AiMindMapGenerateReqVO } from '@/api/ai/mindmap'
|
||||
@ -40,7 +40,7 @@ const rightRef = ref<InstanceType<typeof Right>>() // 右边组件
|
||||
|
||||
/** 使用已有内容直接生成 **/
|
||||
const directGenerate = (existPrompt: string) => {
|
||||
isEnd.value = false // 先设置为false再设置为true,让子组建的watch能够监听到
|
||||
isEnd.value = false // 先设置为 false 再设置为 true,让子组建的 watch 能够监听到
|
||||
generatedContent.value = existPrompt
|
||||
isEnd.value = true
|
||||
}
|
||||
|
195
src/views/ai/mindmap/manager/index.vue
Normal file
195
src/views/ai/mindmap/manager/index.vue
Normal file
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
:model="queryParams"
|
||||
class="-mb-15px"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="用户编号" prop="userId">
|
||||
<el-select
|
||||
v-model="queryParams.userId"
|
||||
class="!w-240px"
|
||||
clearable
|
||||
placeholder="请输入用户编号"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userList"
|
||||
:key="item.id"
|
||||
:label="item.nickname"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="提示词" prop="prompt">
|
||||
<el-input
|
||||
v-model="queryParams.prompt"
|
||||
class="!w-240px"
|
||||
clearable
|
||||
placeholder="请输入提示词"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery">
|
||||
<Icon class="mr-5px" icon="ep:search" />
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button @click="resetQuery">
|
||||
<Icon class="mr-5px" icon="ep:refresh" />
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||
<el-table-column align="center" fixed="left" label="编号" prop="id" width="180" />
|
||||
<el-table-column align="center" label="用户" prop="userId" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ userList.find((item) => item.id === scope.row.userId)?.nickname }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="提示词" prop="prompt" width="180" />
|
||||
<el-table-column align="center" label="思维导图" min-width="300" prop="generatedContent" />
|
||||
<el-table-column align="center" label="模型" prop="model" width="180" />
|
||||
<el-table-column
|
||||
:formatter="dateFormatter"
|
||||
align="center"
|
||||
label="创建时间"
|
||||
prop="createTime"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column align="center" label="错误信息" prop="errorMessage" />
|
||||
<el-table-column align="center" fixed="right" label="操作" width="120">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openPreview(scope.row)"> 预览</el-button>
|
||||
<el-button
|
||||
v-hasPermi="['ai:mind-map:delete']"
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
v-model:limit="queryParams.pageSize"
|
||||
v-model:page="queryParams.pageNo"
|
||||
:total="total"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 思维导图的预览 -->
|
||||
<el-drawer v-model="previewVisible" :with-header="false" size="800px">
|
||||
<Right
|
||||
v-if="previewVisible2"
|
||||
:generatedContent="previewContent"
|
||||
:isEnd="true"
|
||||
:isGenerating="false"
|
||||
:isStart="false"
|
||||
/>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { AiMindMapApi, MindMapVO } from '@/api/ai/mindmap'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import Right from '@/views/ai/mindmap/index/components/Right.vue'
|
||||
|
||||
/** AI 思维导图 列表 */
|
||||
defineOptions({ name: 'AiMindMapManager' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<MindMapVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
userId: undefined,
|
||||
prompt: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AiMindMapApi.getMindMapPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AiMindMapApi.deleteMindMap(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 预览操作按钮 */
|
||||
const previewVisible = ref(false) // drawer 的显示隐藏
|
||||
const previewVisible2 = ref(false) // right 的显示隐藏
|
||||
const previewContent = ref('')
|
||||
const openPreview = async (row: MindMapVO) => {
|
||||
previewVisible2.value = false
|
||||
previewVisible.value = true
|
||||
// 在 drawer 渲染完后,再渲染 right 预览,不然会报错,需要保证 width 宽度先出来
|
||||
await nextTick()
|
||||
previewVisible2.value = true
|
||||
previewContent.value = row.generatedContent
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(async () => {
|
||||
getList()
|
||||
// 获得用户列表
|
||||
userList.value = await UserApi.getSimpleUserList()
|
||||
})
|
||||
</script>
|
@ -2,8 +2,8 @@
|
||||
<!-- 定义 tab 组件:撰写/回复等 -->
|
||||
<DefineTab v-slot="{ active, text, itemClick }">
|
||||
<span
|
||||
class="inline-block w-1/2 rounded-full cursor-pointer text-center leading-[30px] relative z-1 text-[5C6370] hover:text-black"
|
||||
:class="active ? 'text-black shadow-md' : 'hover:bg-[#DDDFE3]'"
|
||||
class="inline-block w-1/2 rounded-full cursor-pointer text-center leading-[30px] relative z-1 text-[5C6370] hover:text-black"
|
||||
@click="itemClick"
|
||||
>
|
||||
{{ text }}
|
||||
@ -14,9 +14,9 @@
|
||||
<h3 class="mt-5 mb-3 flex items-center justify-between text-[14px]">
|
||||
<span>{{ label }}</span>
|
||||
<span
|
||||
@click="hintClick"
|
||||
v-if="hint"
|
||||
class="flex items-center text-[12px] text-[#846af7] cursor-pointer select-none"
|
||||
@click="hintClick"
|
||||
>
|
||||
<Icon icon="ep:question-filled" />
|
||||
{{ hint }}
|
||||
@ -29,17 +29,17 @@
|
||||
<div class="w-full pt-2 bg-[#f5f7f9] flex justify-center">
|
||||
<div class="w-[303px] rounded-full bg-[#DDDFE3] p-1 z-10">
|
||||
<div
|
||||
class="flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
|
||||
:class="
|
||||
selectedTab === AiWriteTypeEnum.REPLY && 'after:transform after:translate-x-[100%]'
|
||||
"
|
||||
class="flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
|
||||
>
|
||||
<ReuseTab
|
||||
v-for="tab in tabs"
|
||||
:key="tab.value"
|
||||
:text="tab.text"
|
||||
:active="tab.value === selectedTab"
|
||||
:itemClick="() => switchTab(tab.value)"
|
||||
:text="tab.text"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -49,36 +49,36 @@
|
||||
>
|
||||
<div>
|
||||
<template v-if="selectedTab === 1">
|
||||
<ReuseLabel label="写作内容" hint="示例" :hint-click="() => example('write')" />
|
||||
<ReuseLabel :hint-click="() => example('write')" hint="示例" label="写作内容" />
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
:maxlength="500"
|
||||
v-model="formData.prompt"
|
||||
:maxlength="500"
|
||||
:rows="5"
|
||||
placeholder="请输入写作内容"
|
||||
showWordLimit
|
||||
type="textarea"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<ReuseLabel label="原文" hint="示例" :hint-click="() => example('reply')" />
|
||||
<ReuseLabel :hint-click="() => example('reply')" hint="示例" label="原文" />
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
:maxlength="500"
|
||||
v-model="formData.originalContent"
|
||||
:maxlength="500"
|
||||
:rows="5"
|
||||
placeholder="请输入原文"
|
||||
showWordLimit
|
||||
type="textarea"
|
||||
/>
|
||||
|
||||
<ReuseLabel label="回复内容" />
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
:maxlength="500"
|
||||
v-model="formData.prompt"
|
||||
:maxlength="500"
|
||||
:rows="5"
|
||||
placeholder="请输入回复内容"
|
||||
showWordLimit
|
||||
type="textarea"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@ -93,18 +93,18 @@
|
||||
|
||||
<div class="flex items-center justify-center mt-3">
|
||||
<el-button :disabled="isWriting" @click="reset">重置</el-button>
|
||||
<el-button :loading="isWriting" @click="submit" color="#846af7">生成</el-button>
|
||||
<el-button :loading="isWriting" color="#846af7" @click="submit">生成</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { createReusableTemplate } from '@vueuse/core'
|
||||
import { ref } from 'vue'
|
||||
import Tag from './Tag.vue'
|
||||
import { WriteVO } from 'src/api/ai/write'
|
||||
import { WriteVO } from '@/api/ai/write'
|
||||
import { omit } from 'lodash-es'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { AiWriteTypeEnum, WriteExample } from '@/views/ai/utils/constants'
|
||||
|
Reference in New Issue
Block a user