feat: ai code
This commit is contained in:
@@ -83,7 +83,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'console/workflow/create',
|
path: String.raw`workflow/create/:id(\d+)/:type(update|create)`,
|
||||||
component: () => import('#/views/ai/workflow/form/index.vue'),
|
component: () => import('#/views/ai/workflow/form/index.vue'),
|
||||||
name: 'AiWorkflowCreate',
|
name: 'AiWorkflowCreate',
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@@ -202,7 +202,8 @@ async function updateConversationTitle(
|
|||||||
if (
|
if (
|
||||||
filterConversationList.length > 0 &&
|
filterConversationList.length > 0 &&
|
||||||
filterConversationList[0] && // tip:避免切换对话
|
filterConversationList[0] && // tip:避免切换对话
|
||||||
activeConversationId.value === filterConversationList[0].id
|
activeConversationId.value ===
|
||||||
|
(filterConversationList[0].id as number)
|
||||||
) {
|
) {
|
||||||
emits('onConversationClick', filterConversationList[0]);
|
emits('onConversationClick', filterConversationList[0]);
|
||||||
}
|
}
|
||||||
@@ -306,7 +307,7 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<Layout.Sider
|
<Layout.Sider
|
||||||
width="280px"
|
width="280px"
|
||||||
class="conversation-container relative flex h-full flex-col justify-between overflow-hidden p-4"
|
class="relative flex h-full flex-col justify-between overflow-hidden p-4"
|
||||||
>
|
>
|
||||||
<Drawer />
|
<Drawer />
|
||||||
<!-- 左顶部:对话 -->
|
<!-- 左顶部:对话 -->
|
||||||
@@ -329,7 +330,7 @@ onMounted(async () => {
|
|||||||
</Input>
|
</Input>
|
||||||
|
|
||||||
<!-- 左中间:对话列表 -->
|
<!-- 左中间:对话列表 -->
|
||||||
<div class="conversation-list mt-2 flex-1 overflow-auto">
|
<div class="mt-2 flex-1 overflow-auto">
|
||||||
<!-- 情况一:加载中 -->
|
<!-- 情况一:加载中 -->
|
||||||
<Empty v-if="loading" description="." v-loading="loading" />
|
<Empty v-if="loading" description="." v-loading="loading" />
|
||||||
|
|
||||||
@@ -337,11 +338,10 @@ onMounted(async () => {
|
|||||||
<div
|
<div
|
||||||
v-for="conversationKey in Object.keys(conversationMap)"
|
v-for="conversationKey in Object.keys(conversationMap)"
|
||||||
:key="conversationKey"
|
:key="conversationKey"
|
||||||
class=""
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="conversationMap[conversationKey].length > 0"
|
v-if="conversationMap[conversationKey].length > 0"
|
||||||
class="conversation-item classify-title pt-2"
|
class="classify-title pt-2"
|
||||||
>
|
>
|
||||||
<b class="mx-1">
|
<b class="mx-1">
|
||||||
{{ conversationKey }}
|
{{ conversationKey }}
|
||||||
@@ -354,24 +354,24 @@ onMounted(async () => {
|
|||||||
@click="handleConversationClick(conversation.id)"
|
@click="handleConversationClick(conversation.id)"
|
||||||
@mouseover="hoverConversationId = conversation.id"
|
@mouseover="hoverConversationId = conversation.id"
|
||||||
@mouseout="hoverConversationId = null"
|
@mouseout="hoverConversationId = null"
|
||||||
class="conversation-item mt-1"
|
class="mt-1"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="conversation flex cursor-pointer flex-row items-center justify-between rounded-lg px-2 leading-10"
|
class="flex cursor-pointer flex-row items-center justify-between rounded-lg px-2 leading-10"
|
||||||
:class="[
|
:class="[
|
||||||
conversation.id === activeConversationId
|
conversation.id === activeConversationId
|
||||||
? 'bg-primary-200'
|
? 'bg-success-600'
|
||||||
: '',
|
: '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<div class="title-wrapper flex items-center">
|
<div class="flex items-center">
|
||||||
<Avatar
|
<Avatar
|
||||||
v-if="conversation.roleAvatar"
|
v-if="conversation.roleAvatar"
|
||||||
:src="conversation.roleAvatar"
|
:src="conversation.roleAvatar"
|
||||||
/>
|
/>
|
||||||
<SvgGptIcon v-else class="size-8" />
|
<SvgGptIcon v-else class="size-8" />
|
||||||
<span
|
<span
|
||||||
class="max-w-36 overflow-hidden text-ellipsis whitespace-nowrap p-2 text-sm font-normal text-gray-600"
|
class="max-w-32 overflow-hidden text-ellipsis whitespace-nowrap p-2 text-sm font-normal"
|
||||||
>
|
>
|
||||||
{{ conversation.title }}
|
{{ conversation.title }}
|
||||||
</span>
|
</span>
|
||||||
@@ -379,7 +379,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-show="hoverConversationId === conversation.id"
|
v-show="hoverConversationId === conversation.id"
|
||||||
class="button-wrapper relative right-0.5 flex items-center text-gray-400"
|
class="relative right-0.5 flex items-center text-gray-400"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
class="mr-0 px-1"
|
class="mr-0 px-1"
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ async function textRoll() {
|
|||||||
// 设置状态
|
// 设置状态
|
||||||
textRoleRunning.value = true;
|
textRoleRunning.value = true;
|
||||||
receiveMessageDisplayedText.value = '';
|
receiveMessageDisplayedText.value = '';
|
||||||
const task = async () => {
|
async function task() {
|
||||||
// 调整速度
|
// 调整速度
|
||||||
const diff =
|
const diff =
|
||||||
(receiveMessageFullText.value.length -
|
(receiveMessageFullText.value.length -
|
||||||
@@ -472,7 +472,7 @@ async function textRoll() {
|
|||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
let timer = setTimeout(task, textSpeed.value);
|
let timer = setTimeout(task, textSpeed.value);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
@@ -503,7 +503,7 @@ onMounted(async () => {
|
|||||||
<!-- 左侧:对话列表 -->
|
<!-- 左侧:对话列表 -->
|
||||||
<ConversationList
|
<ConversationList
|
||||||
class="!bg-card"
|
class="!bg-card"
|
||||||
:active-id="activeConversationId as any"
|
:active-id="activeConversationId"
|
||||||
ref="conversationListRef"
|
ref="conversationListRef"
|
||||||
@on-conversation-create="handleConversationCreateSuccess"
|
@on-conversation-create="handleConversationCreateSuccess"
|
||||||
@on-conversation-click="handleConversationClick"
|
@on-conversation-click="handleConversationClick"
|
||||||
@@ -578,7 +578,7 @@ onMounted(async () => {
|
|||||||
class="border-border my-5 mb-5 mt-2 flex flex-col rounded-xl border px-2 py-2.5"
|
class="border-border my-5 mb-5 mt-2 flex flex-col rounded-xl border px-2 py-2.5"
|
||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
class="box-border h-24 resize-none overflow-auto border-none px-0 py-1 focus:outline-none"
|
class="box-border h-24 resize-none overflow-auto rounded-md px-0 py-1 focus:outline-none"
|
||||||
v-model="prompt"
|
v-model="prompt"
|
||||||
@keydown="handleSendByKeydown"
|
@keydown="handleSendByKeydown"
|
||||||
@input="handlePromptInput"
|
@input="handlePromptInput"
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ onMounted(async () => {
|
|||||||
<TableAction :actions="[]" />
|
<TableAction :actions="[]" />
|
||||||
</template>
|
</template>
|
||||||
<template #userId="{ row }">
|
<template #userId="{ row }">
|
||||||
<span>{{
|
<span>
|
||||||
userList.find((item) => item.id === row.userId)?.nickname
|
{{ userList.find((item) => item.id === row.userId)?.nickname }}
|
||||||
}}</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<Image class="rounded-lg" :src="detail?.picUrl" />
|
<Image class="rounded-lg" :src="detail?.picUrl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -52,7 +52,7 @@ watch(
|
|||||||
<!-- 时间 -->
|
<!-- 时间 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">时间</div>
|
<div class="text-lg font-bold">时间</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<div>
|
<div>
|
||||||
提交时间:{{ formatDate(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}
|
提交时间:{{ formatDate(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -65,7 +65,7 @@ watch(
|
|||||||
<!-- 模型 -->
|
<!-- 模型 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">模型</div>
|
<div class="text-lg font-bold">模型</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.model }}({{ detail.height }}x{{ detail.width }})
|
{{ detail.model }}({{ detail.height }}x{{ detail.width }})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,7 +73,7 @@ watch(
|
|||||||
<!-- 提示词 -->
|
<!-- 提示词 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">提示词</div>
|
<div class="text-lg font-bold">提示词</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.prompt }}
|
{{ detail.prompt }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +81,7 @@ watch(
|
|||||||
<!-- 图片地址 -->
|
<!-- 图片地址 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">图片地址</div>
|
<div class="text-lg font-bold">图片地址</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.picUrl }}
|
{{ detail.picUrl }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +95,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">采样方法</div>
|
<div class="text-lg font-bold">采样方法</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionSamplers.find(
|
StableDiffusionSamplers.find(
|
||||||
(item) => item.key === detail?.options?.sampler,
|
(item) => item.key === detail?.options?.sampler,
|
||||||
@@ -112,7 +112,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">CLIP</div>
|
<div class="text-lg font-bold">CLIP</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionClipGuidancePresets.find(
|
StableDiffusionClipGuidancePresets.find(
|
||||||
(item) => item.key === detail?.options?.clipGuidancePreset,
|
(item) => item.key === detail?.options?.clipGuidancePreset,
|
||||||
@@ -129,7 +129,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">风格</div>
|
<div class="text-lg font-bold">风格</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionStylePresets.find(
|
StableDiffusionStylePresets.find(
|
||||||
(item) => item.key === detail?.options?.stylePreset,
|
(item) => item.key === detail?.options?.stylePreset,
|
||||||
@@ -146,7 +146,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">迭代步数</div>
|
<div class="text-lg font-bold">迭代步数</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.steps }}</div>
|
<div class="mt-2">{{ detail?.options?.steps }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -157,7 +157,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">引导系数</div>
|
<div class="text-lg font-bold">引导系数</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.scale }}</div>
|
<div class="mt-2">{{ detail?.options?.scale }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -168,7 +168,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">随机因子</div>
|
<div class="text-lg font-bold">随机因子</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.seed }}</div>
|
<div class="mt-2">{{ detail?.options?.seed }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dall3 专属 -->
|
<!-- Dall3 专属 -->
|
||||||
@@ -177,7 +177,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">风格选择</div>
|
<div class="text-lg font-bold">风格选择</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
Dall3StyleList.find((item) => item.key === detail?.options?.style)?.name
|
Dall3StyleList.find((item) => item.key === detail?.options?.style)?.name
|
||||||
}}
|
}}
|
||||||
@@ -192,7 +192,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">模型版本</div>
|
<div class="text-lg font-bold">模型版本</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.version }}</div>
|
<div class="mt-2">{{ detail?.options?.version }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -203,7 +203,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">参考图</div>
|
<div class="text-lg font-bold">参考图</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<Image :src="detail.options.referImageUrl" />
|
<Image :src="detail.options.referImageUrl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ const platformOptions = [
|
|||||||
const models = ref<AiModelModelApi.Model[]>([]); // 模型列表
|
const models = ref<AiModelModelApi.Model[]>([]); // 模型列表
|
||||||
|
|
||||||
/** 绘画 start */
|
/** 绘画 start */
|
||||||
const handleDrawStart = async () => {};
|
async function handleDrawStart() {}
|
||||||
|
|
||||||
/** 绘画 complete */
|
/** 绘画 complete */
|
||||||
const handleDrawComplete = async () => {
|
async function handleDrawComplete() {
|
||||||
await imageListRef.value.getImageList();
|
await imageListRef.value.getImageList();
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 重新生成:将画图详情填充到对应平台 */
|
/** 重新生成:将画图详情填充到对应平台 */
|
||||||
const handleRegeneration = async (image: AiImageApi.Image) => {
|
async function handleRegeneration(image: AiImageApi.Image) {
|
||||||
// 切换平台
|
// 切换平台
|
||||||
selectPlatform.value = image.platform;
|
selectPlatform.value = image.platform;
|
||||||
// 根据不同平台填充 image
|
// 根据不同平台填充 image
|
||||||
@@ -79,7 +79,7 @@ const handleRegeneration = async (image: AiImageApi.Image) => {
|
|||||||
// No default
|
// No default
|
||||||
}
|
}
|
||||||
// TODO @fan:貌似 other 重新设置不行?
|
// TODO @fan:貌似 other 重新设置不行?
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 组件挂载的时候 */
|
/** 组件挂载的时候 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -69,15 +77,20 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
field: 'picUrl',
|
||||||
title: '图片',
|
title: '图片',
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
slots: { default: 'picUrl' },
|
cellRender: {
|
||||||
|
name: 'CellImage',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
minWidth: 180,
|
field: 'userId',
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
minWidth: 180,
|
||||||
|
formatter: ({ cellValue }) =>
|
||||||
|
userList.find((user) => user.id === cellValue)?.nickname || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'platform',
|
field: 'platform',
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiImageApi } from '#/api/ai/image';
|
import type { AiImageApi } from '#/api/ai/image';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
||||||
import { AiImageStatusEnum } from '@vben/constants';
|
import { AiImageStatusEnum } from '@vben/constants';
|
||||||
|
|
||||||
import { Image, message, Switch } from 'ant-design-vue';
|
import { message, Switch } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteImage, getImagePage, updateImage } from '#/api/ai/image';
|
import { deleteImage, getImagePage, updateImage } from '#/api/ai/image';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -40,7 +35,7 @@ async function handleDelete(row: AiImageApi.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
const handleUpdatePublicStatusChange = async (row: AiImageApi.Image) => {
|
async function handleUpdatePublicStatusChange(row: AiImageApi.Image) {
|
||||||
try {
|
try {
|
||||||
// 修改状态的二次确认
|
// 修改状态的二次确认
|
||||||
const text = row.publicStatus ? '公开' : '私有';
|
const text = row.publicStatus ? '公开' : '私有';
|
||||||
@@ -54,7 +49,7 @@ const handleUpdatePublicStatusChange = async (row: AiImageApi.Image) => {
|
|||||||
} catch {
|
} catch {
|
||||||
row.publicStatus = !row.publicStatus;
|
row.publicStatus = !row.publicStatus;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiImageApi.Image>,
|
} as VxeTableGridOptions<AiImageApi.Image>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -95,20 +86,6 @@ onMounted(async () => {
|
|||||||
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
|
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
|
||||||
</template>
|
</template>
|
||||||
<Grid table-title="绘画管理列表">
|
<Grid table-title="绘画管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #picUrl="{ row }">
|
|
||||||
<Image :src="row.picUrl" class="h-20 w-20" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
userList.find((item: SystemUserApi.User) => item.id === row.userId)
|
|
||||||
?.nickname
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #publicStatus="{ row }">
|
<template #publicStatus="{ row }">
|
||||||
<Switch
|
<Switch
|
||||||
v-model:checked="row.publicStatus"
|
v-model:checked="row.publicStatus"
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ async function getList() {
|
|||||||
}
|
}
|
||||||
const debounceGetList = useDebounceFn(getList, 80);
|
const debounceGetList = useDebounceFn(getList, 80);
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
const handleQuery = () => {
|
function handleQuery() {
|
||||||
queryParams.pageNo = 1;
|
queryParams.pageNo = 1;
|
||||||
getList();
|
getList();
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -65,16 +65,16 @@ async function handleDelete(row: AiKnowledgeDocumentApi.KnowledgeDocument) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 跳转到知识库分段页面 */
|
/** 跳转到知识库分段页面 */
|
||||||
const handleSegment = (id: number) => {
|
function handleSegment(id: number) {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'AiKnowledgeSegment',
|
name: 'AiKnowledgeSegment',
|
||||||
query: { documentId: id },
|
query: { documentId: id },
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
const handleStatusChange = async (
|
async function handleStatusChange(
|
||||||
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
||||||
) => {
|
) {
|
||||||
try {
|
try {
|
||||||
// 修改状态的二次确认
|
// 修改状态的二次确认
|
||||||
const text = row.status ? '启用' : '禁用';
|
const text = row.status ? '启用' : '禁用';
|
||||||
@@ -91,7 +91,7 @@ const handleStatusChange = async (
|
|||||||
? CommonStatusEnum.DISABLE
|
? CommonStatusEnum.DISABLE
|
||||||
: CommonStatusEnum.ENABLE;
|
: CommonStatusEnum.ENABLE;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiKnowledgeKnowledgeApi } from '#/api/ai/knowledge/knowledge';
|
|
||||||
import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment';
|
import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment';
|
||||||
|
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
@@ -41,12 +40,12 @@ function handleCreate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 编辑 */
|
/** 编辑 */
|
||||||
function handleEdit(row: AiKnowledgeKnowledgeApi.Knowledge) {
|
function handleEdit(row: AiKnowledgeSegmentApi.KnowledgeSegment) {
|
||||||
formModalApi.setData(row).open();
|
formModalApi.setData(row).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除 */
|
/** 删除 */
|
||||||
async function handleDelete(row: AiKnowledgeKnowledgeApi.Knowledge) {
|
async function handleDelete(row: AiKnowledgeSegmentApi.KnowledgeSegment) {
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
content: $t('ui.actionMessage.deleting', [row.id]),
|
content: $t('ui.actionMessage.deleting', [row.id]),
|
||||||
duration: 0,
|
duration: 0,
|
||||||
@@ -88,7 +87,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
refresh: true,
|
refresh: true,
|
||||||
search: true,
|
search: true,
|
||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiKnowledgeKnowledgeApi.Knowledge>,
|
} as VxeTableGridOptions<AiKnowledgeSegmentApi.KnowledgeSegment>,
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ defineExpose({
|
|||||||
<h3 class="text-primary h-7 w-full text-center text-xl leading-7">
|
<h3 class="text-primary h-7 w-full text-center text-xl leading-7">
|
||||||
思维导图创作中心
|
思维导图创作中心
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex-grow overflow-y-auto">
|
<div class="mt-4 flex-grow overflow-y-auto">
|
||||||
<div>
|
<div>
|
||||||
<b>您的需求?</b>
|
<b>您的需求?</b>
|
||||||
<Textarea
|
<Textarea
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ watch(props, ({ generatedContent, isGenerating, isEnd, isStart }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 更新思维导图的展示 */
|
/** 更新思维导图的展示 */
|
||||||
const update = () => {
|
function update() {
|
||||||
try {
|
try {
|
||||||
const { root } = transformer.transform(
|
const { root } = transformer.transform(
|
||||||
processContent(props.generatedContent),
|
processContent(props.generatedContent),
|
||||||
@@ -83,7 +83,7 @@ const update = () => {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
/** 处理内容 */
|
/** 处理内容 */
|
||||||
function processContent(text: string) {
|
function processContent(text: string) {
|
||||||
const arr: string[] = [];
|
const arr: string[] = [];
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -44,9 +52,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
minWidth: 180,
|
field: 'userId',
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
minWidth: 180,
|
||||||
|
formatter: ({ cellValue }) =>
|
||||||
|
userList.find((user) => user.id === cellValue)?.nickname || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'prompt',
|
field: 'prompt',
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiMindmapApi } from '#/api/ai/mindmap';
|
import type { AiMindmapApi } from '#/api/ai/mindmap';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { nextTick, onMounted, ref } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
|
|
||||||
import { DocAlert, Page, useVbenDrawer } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenDrawer } from '@vben/common-ui';
|
||||||
|
|
||||||
@@ -11,14 +10,11 @@ import { message } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteMindMap, getMindMapPage } from '#/api/ai/mindmap';
|
import { deleteMindMap, getMindMapPage } from '#/api/ai/mindmap';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import Right from '../index/modules/Right.vue';
|
import Right from '../index/modules/Right.vue';
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
const previewVisible = ref(false); // drawer 的显示隐藏
|
|
||||||
const previewContent = ref('');
|
const previewContent = ref('');
|
||||||
const [Drawer, drawerApi] = useVbenDrawer({
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
header: false,
|
header: false,
|
||||||
@@ -75,16 +71,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
} as VxeTableGridOptions<AiMindmapApi.MindMap>,
|
} as VxeTableGridOptions<AiMindmapApi.MindMap>,
|
||||||
});
|
});
|
||||||
async function openPreview(row: AiMindmapApi.MindMap) {
|
async function openPreview(row: AiMindmapApi.MindMap) {
|
||||||
previewVisible.value = false;
|
previewContent.value = row.generatedContent;
|
||||||
drawerApi.open();
|
drawerApi.open();
|
||||||
await nextTick();
|
await nextTick();
|
||||||
previewVisible.value = true;
|
|
||||||
previewContent.value = row.generatedContent;
|
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -94,7 +84,6 @@ onMounted(async () => {
|
|||||||
</template>
|
</template>
|
||||||
<Drawer class="w-3/5">
|
<Drawer class="w-3/5">
|
||||||
<Right
|
<Right
|
||||||
v-if="previewVisible"
|
|
||||||
:generated-content="previewContent"
|
:generated-content="previewContent"
|
||||||
:is-end="true"
|
:is-end="true"
|
||||||
:is-generating="false"
|
:is-generating="false"
|
||||||
@@ -102,17 +91,6 @@ onMounted(async () => {
|
|||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<Grid table-title="思维导图管理列表">
|
<Grid table-title="思维导图管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
userList.find((item: SystemUserApi.User) => item.id === row.userId)
|
|
||||||
?.nickname
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -209,8 +209,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '角色头像',
|
title: '角色头像',
|
||||||
slots: { default: 'avatar' },
|
field: 'avatar',
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellImage',
|
||||||
|
props: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '角色类别',
|
title: '角色类别',
|
||||||
@@ -229,13 +236,23 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '知识库',
|
title: '知识库',
|
||||||
slots: { default: 'knowledgeIds' },
|
field: 'knowledgeIds',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return !cellValue || cellValue.length === 0
|
||||||
|
? '-'
|
||||||
|
: `引用${cellValue.length}个`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '工具',
|
title: '工具',
|
||||||
slots: { default: 'toolIds' },
|
field: 'toolIds',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return !cellValue || cellValue.length === 0
|
||||||
|
? '-'
|
||||||
|
: `引用${cellValue.length}个`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'publicStatus',
|
field: 'publicStatus',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { AiModelChatRoleApi } from '#/api/ai/model/chatRole';
|
|||||||
|
|
||||||
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Image, message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteChatRole, getChatRolePage } from '#/api/ai/model/chatRole';
|
import { deleteChatRole, getChatRolePage } from '#/api/ai/model/chatRole';
|
||||||
@@ -100,17 +100,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #knowledgeIds="{ row }">
|
|
||||||
<span v-if="!row.knowledgeIds || row.knowledgeIds.length === 0">-</span>
|
|
||||||
<span v-else>引用 {{ row.knowledgeIds.length }} 个</span>
|
|
||||||
</template>
|
|
||||||
<template #toolIds="{ row }">
|
|
||||||
<span v-if="!row.toolIds || row.toolIds.length === 0">-</span>
|
|
||||||
<span v-else>引用 {{ row.toolIds.length }} 个</span>
|
|
||||||
</template>
|
|
||||||
<template #avatar="{ row }">
|
|
||||||
<Image :src="row.avatar" class="h-8 w-8" />
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { AiModelApiKeyApi } from '#/api/ai/model/apiKey';
|
||||||
|
|
||||||
import { AiModelTypeEnum, CommonStatusEnum, DICT_TYPE } from '@vben/constants';
|
import { AiModelTypeEnum, CommonStatusEnum, DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import { z } from '#/adapter/form';
|
import { z } from '#/adapter/form';
|
||||||
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
||||||
|
|
||||||
|
let apiKeyList: AiModelApiKeyApi.ApiKey[] = [];
|
||||||
|
async function getApiKeyList() {
|
||||||
|
apiKeyList = await getApiKeySimpleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getApiKeyList();
|
||||||
|
|
||||||
/** 新增/修改的表单 */
|
/** 新增/修改的表单 */
|
||||||
export function useFormSchema(): VbenFormSchema[] {
|
export function useFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -199,7 +208,12 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API 秘钥',
|
title: 'API 秘钥',
|
||||||
slots: { default: 'keyId' },
|
field: 'keyId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return (
|
||||||
|
apiKeyList.find((apiKey) => apiKey.id === cellValue)?.name || '-'
|
||||||
|
);
|
||||||
|
},
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiModelApiKeyApi } from '#/api/ai/model/apiKey';
|
|
||||||
import type { AiModelModelApi } from '#/api/ai/model/model';
|
import type { AiModelModelApi } from '#/api/ai/model/model';
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
|
||||||
import { deleteModel, getModelPage } from '#/api/ai/model/model';
|
import { deleteModel, getModelPage } from '#/api/ai/model/model';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
|
|
||||||
const apiKeyList = ref([] as AiModelApiKeyApi.ApiKey[]);
|
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
connectedComponent: Form,
|
connectedComponent: Form,
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiModelModelApi.Model>,
|
} as VxeTableGridOptions<AiModelModelApi.Model>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
apiKeyList.value = await getApiKeySimpleList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -109,15 +100,6 @@ onMounted(async () => {
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #keyId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
apiKeyList.find(
|
|
||||||
(item: AiModelApiKeyApi.ApiKey) => item.id === row.keyId,
|
|
||||||
)?.name
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -82,7 +90,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
{
|
{
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
field: 'userId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return userList.find((user) => user.id === cellValue)?.nickname || '-';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status',
|
field: 'status',
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiMusicApi } from '#/api/ai/music';
|
import type { AiMusicApi } from '#/api/ai/music';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
||||||
import { AiMusicStatusEnum } from '@vben/constants';
|
import { AiMusicStatusEnum } from '@vben/constants';
|
||||||
@@ -12,12 +9,10 @@ import { Button, message, Switch } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteMusic, getMusicPage, updateMusic } from '#/api/ai/music';
|
import { deleteMusic, getMusicPage, updateMusic } from '#/api/ai/music';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiMusicApi.Music>,
|
} as VxeTableGridOptions<AiMusicApi.Music>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -99,11 +90,6 @@ onMounted(async () => {
|
|||||||
<TableAction :actions="[]" />
|
<TableAction :actions="[]" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{ userList.find((item) => item.id === row.userId)?.nickname }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #content="{ row }">
|
<template #content="{ row }">
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
|
|||||||
@@ -190,8 +190,8 @@ function handleBack() {
|
|||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
workflowId.value = route.query.id as string;
|
workflowId.value = route.params.id as string;
|
||||||
actionType.value = route.query.type as string;
|
actionType.value = route.params.type as string;
|
||||||
await initData();
|
await initData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ defineExpose({ validate });
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset
|
<fieldset
|
||||||
class="m-0 mt-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-4"
|
class="bg-card m-0 mt-10 rounded-lg border border-gray-200 px-3 py-4"
|
||||||
>
|
>
|
||||||
<legend class="ml-2 px-2.5 text-base font-semibold text-gray-600">
|
<legend class="ml-2 px-2.5 text-base font-semibold text-gray-600">
|
||||||
<h3>运行结果</h3>
|
<h3>运行结果</h3>
|
||||||
|
|||||||
@@ -28,10 +28,7 @@ function handleCreate() {
|
|||||||
function handleEdit(row: any) {
|
function handleEdit(row: any) {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'AiWorkflowCreate',
|
name: 'AiWorkflowCreate',
|
||||||
query: {
|
params: { id: row.id, type: 'update' },
|
||||||
id: row.id,
|
|
||||||
type: 'update',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -62,7 +70,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
{
|
{
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
field: 'userId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return userList.find((user) => user.id === cellValue)?.nickname || '-';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'type',
|
field: 'type',
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiWriteApi } from '#/api/ai/write';
|
import type { AiWriteApi } from '#/api/ai/write';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { DocAlert, Page } from '@vben/common-ui';
|
import { DocAlert, Page } from '@vben/common-ui';
|
||||||
|
|
||||||
@@ -11,12 +8,10 @@ import { message } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteWrite, getWritePage } from '#/api/ai/write';
|
import { deleteWrite, getWritePage } from '#/api/ai/write';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -66,10 +61,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiWriteApi.AiWritePageReq>,
|
} as VxeTableGridOptions<AiWriteApi.AiWritePageReq>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -78,14 +69,6 @@ onMounted(async () => {
|
|||||||
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
|
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
|
||||||
</template>
|
</template>
|
||||||
<Grid table-title="写作管理列表">
|
<Grid table-title="写作管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>{{
|
|
||||||
userList.find((item) => item.id === row.userId)?.nickname
|
|
||||||
}}</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
Reference in New Issue
Block a user