Commit 6c2fc5cb authored by nick zheng's avatar nick zheng

chore: 数字人对话配置及我的对话

parent 621bdca9
......@@ -21,6 +21,7 @@
"@unocss/reset": "^0.61.9",
"@vueuse/core": "^10.11.1",
"axios": "^1.7.7",
"clipboardy": "^4.0.0",
"dayjs": "^1.11.13",
"nanoid": "^5.0.7",
"pinia": "^2.2.2",
......
......@@ -23,6 +23,9 @@ importers:
axios:
specifier: ^1.7.7
version: 1.7.7
clipboardy:
specifier: ^4.0.0
version: 4.0.0
dayjs:
specifier: ^1.11.13
version: 1.11.13
......@@ -1292,6 +1295,10 @@ packages:
resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
engines: {node: '>=18'}
clipboardy@4.0.0:
resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==}
engines: {node: '>=18'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
......@@ -1855,6 +1862,11 @@ packages:
engines: {node: '>=8'}
hasBin: true
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
......@@ -1875,6 +1887,11 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
hasBin: true
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
......@@ -1903,6 +1920,14 @@ packages:
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
engines: {node: '>=8'}
is-wsl@3.1.0:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
engines: {node: '>=16'}
is64bit@2.0.0:
resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==}
engines: {node: '>=18'}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
......@@ -2640,6 +2665,10 @@ packages:
resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
engines: {node: ^14.18.0 || >=16.0.0}
system-architecture@0.1.0:
resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==}
engines: {node: '>=18'}
table@6.8.2:
resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==}
engines: {node: '>=10.0.0'}
......@@ -4199,6 +4228,12 @@ snapshots:
slice-ansi: 5.0.0
string-width: 7.2.0
clipboardy@4.0.0:
dependencies:
execa: 8.0.1
is-wsl: 3.1.0
is64bit: 2.0.0
cliui@8.0.1:
dependencies:
string-width: 4.2.3
......@@ -4775,6 +4810,8 @@ snapshots:
is-docker@2.2.1: {}
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
......@@ -4789,6 +4826,10 @@ snapshots:
dependencies:
is-extglob: 2.1.1
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
is-number@7.0.0: {}
is-obj@2.0.0: {}
......@@ -4807,6 +4848,14 @@ snapshots:
dependencies:
is-docker: 2.2.1
is-wsl@3.1.0:
dependencies:
is-inside-container: 1.0.0
is64bit@2.0.0:
dependencies:
system-architecture: 0.1.0
isexe@2.0.0: {}
jiti@1.21.6: {}
......@@ -5476,6 +5525,8 @@ snapshots:
'@pkgr/core': 0.1.1
tslib: 2.7.0
system-architecture@0.1.0: {}
table@6.8.2:
dependencies:
ajv: 8.17.1
......
......@@ -21,8 +21,8 @@ export function fetchMultiDelectDigitalHumanDialogueConfig<T>(payload: string[])
}
// 通过对话数字人列表
export function fetchGetDigitalHumanDialogueList<T>(query: string) {
return request.post<T>(`/bizDigitalHumanDialogueConfigRest/getList.json?query=${query || null}`)
export function fetchGetDigitalHumanDialogueList<T>(query: string, payload: object) {
return request.post<T>(`/bizDigitalHumanDialogueConfigRest/getList.json?query=${query}`, payload)
}
// 更改对话数字人开关配置
......@@ -30,6 +30,11 @@ export function fetchUpdateDigitalHumanDialogueOpen<T>(configId: string, isOpen:
return request.post<T>(`/bizDigitalHumanDialogueConfigRest/openConfig.json?configId=${configId}&isOpen=${isOpen}`)
}
// 发布对话数字人
export function fetchPublishDigitalHumanDialogue<T>(configId: string) {
return request.post<T>(`/bizDigitalHumanDialogueConfigRest/publish.json?configId=${configId}`)
}
// 获取角色模型列表
export function fetchDigitalHumanDialogueSystemList<T>(payload: object) {
return request.post<T>('/bizDigitalHumanDialogueSystemModelRest/getList.json', payload)
......@@ -40,7 +45,25 @@ export function fetchGetInfoByFigureId<T>(figureId: string) {
return request.post<T>(`/bizDigitalHumanImageRest/getInfoByFigureId.json?figureId=${figureId}`)
}
// 用户上传背景图
export function handleUploadBackgroundImageFile<T>(imageName: string, formData: FormData) {
return request.post<T>(`/baiduDigitalHumanFileRest/uploadBackgroundImageFile.json?imageName=${imageName}`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 12000,
})
}
// 根据背景图id删除背景图
export function handleDeleteBackgroundImageById<T>(id: number) {
return request.post<T>(`/bizDigitalHumanMemberImageRest/deletedById.json?id=${id}`)
}
// 获取当前用户背景图
export function fetchGetBackgroundImageList<T>() {
return request.post<T>('/aiDigitalHumanImageRest/getBackgroundImageList.json')
}
// 模糊搜索查询背景图
export function fetchSearchBackgroundImageList<T>(imageName: string) {
return request.post<T>(`/aiDigitalHumanImageRest/searchBackgroundImageList.json?imageName=${imageName}`)
}
......@@ -11,7 +11,7 @@ function defaultDigitalHumanDialogue(): DigitalHumanDialogueConfig {
publishStatus: 'N',
},
humanInfo: {
figureId: 'A2A_V2-3to2_leqing',
figureId: '',
speed: 5,
intonation: 5,
timebreId: '5132',
......
import clipboard from 'clipboardy'
export function copyToClip(text: string) {
return clipboard.write(text)
}
<script setup lang="ts">
import { computed, ref } from 'vue'
import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import { uploadImageFile } from '@/apis/digital-creation'
import { useDigitalHumanDialogueStore } from '@/store/modules/digital-human-dialogue'
import { fetchGetBackgroundImageList } from '@/apis/digital-human-dialogue'
import {
fetchGetBackgroundImageList,
fetchSearchBackgroundImageList,
handleDeleteBackgroundImageById,
handleUploadBackgroundImageFile,
} from '@/apis/digital-human-dialogue'
interface BackgroundImageItem {
id?: number
......@@ -50,7 +54,19 @@ async function getBackgroundImageList() {
}
}
async function handleSearchImageList() {}
async function handleSearchImageList(searchNameValue: string) {
if (!searchNameValue) {
getBackgroundImageList()
return
}
const res = await fetchSearchBackgroundImageList<BackgroundImageItem[]>(searchNameValue)
if (res.code === 0) {
publicBackgroundImageList.value = res.data.filter((i) => i.imageSource === 'PUBLIC')
personBackgroundImageList.value = res.data.filter((i) => i.imageSource === 'PERSON')
}
}
async function uploadImage(event: any) {
const e = window.event || event
......@@ -78,7 +94,7 @@ async function uploadImage(event: any) {
uploadLoading.value = true
const res = await uploadImageFile(fileName, formData).finally(() => (uploadLoading.value = false))
const res = await handleUploadBackgroundImageFile(fileName, formData).finally(() => (uploadLoading.value = false))
if (res.code === 0) {
getBackgroundImageList()
......@@ -96,9 +112,13 @@ function handleDelete(id: number) {
content: '是否刪除該圖片?',
positiveText: '確認',
negativeText: '取消',
onPositiveClick: () => {
console.log(id)
window.$message.success('刪除成功')
onPositiveClick: async () => {
const res = await handleDeleteBackgroundImageById(id)
if (res.code === 0) {
window.$message.success('刪除成功')
getBackgroundImageList()
}
},
})
}
......@@ -128,13 +148,7 @@ function handleUpdateBackgroundImageType(backgroundImageType: string) {
</NButton>
</NButtonGroup>
<NInput
v-model:value="searchImageName"
round
placeholder="請輸入名稱"
@blur="handleSearchImageList"
@keyup.enter="handleSearchImageList"
>
<NInput v-model:value="searchImageName" round placeholder="請輸入名稱" @input="handleSearchImageList">
<template #prefix>
<CustomIcon class="text-lg" icon="mingcute:search-line" />
</template>
......
......@@ -59,7 +59,6 @@ watch(
)
onMounted(() => {
currentSelectedAudioType.value = 'cantonese'
getDigitalTimbreList()
})
......@@ -72,6 +71,10 @@ async function getDigitalTimbreList() {
}
}
function handleUpdateAudioType(audioType: string) {
digitalHumanDialogueStore.humanInfo.timebreId = audioType === 'mandarin' ? '5132' : '101019'
}
async function handleSearch(value: string) {
const res = await fetchTimbreByExample<DigitalHumanDialogueTimbreItem[]>(value)
if (res.code === 0) {
......@@ -95,14 +98,13 @@ function handleClickAudioCard(timbreId: string) {
size="small"
:options="audioTypeList"
placeholder="請選擇語言"
@update:value="handleUpdateAudioType"
/>
</div>
<DigitalAudioCard
:dialogue-timbre-item="digitalTimbreValue"
:show-toggle="isMandarinAudioType"
@toggle="showAll = true"
/>
<div v-show="isMandarinAudioType">
<DigitalAudioCard :dialogue-timbre-item="digitalTimbreValue" :show-toggle="true" @toggle="showAll = true" />
</div>
<div class="mt-4 text-lg">聲音</div>
<div class="mt-4 flex items-center gap-2">
......
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useDigitalHumanDialogueStore } from '@/store/modules/digital-human-dialogue'
import { ImageItem } from '@/store/types/creation'
import { DigitalImageItem } from '../../dialogue-type'
interface Props {
imageItem: ImageItem
imageItem: DigitalImageItem
}
interface Emits {
......
......@@ -9,14 +9,14 @@ import {
fetchInfoByImageName,
} from '@/apis/digital-creation'
import { ImageItem, ImageType } from '@/store/types/creation'
import { useDigitalHumanDialogueStore } from '@/store/modules/digital-human-dialogue'
import { DigitalImageItem, ImageType } from '../../dialogue-type'
const digitalHumanDialogueStore = useDigitalHumanDialogueStore()
const threeDImageList = ref<ImageItem[]>([])
const twoDBoutiqueImageList = ref<ImageItem[]>([])
const twoDFewShotImageList = ref<ImageItem[]>([])
const allImageList = ref<ImageItem[]>([])
const threeDImageList = ref<DigitalImageItem[]>([])
const twoDBoutiqueImageList = ref<DigitalImageItem[]>([])
const twoDFewShotImageList = ref<DigitalImageItem[]>([])
const allImageList = ref<DigitalImageItem[]>([])
const showAll = ref(false)
const searchImageName = ref('')
......@@ -26,9 +26,9 @@ onMounted(() => {
async function getDigitalImageList() {
const [res1, res2, res3] = await Promise.all([
fetch3DImageList<ImageItem[]>(),
fetch2DBoutiqueImageList<ImageItem[]>(),
fetch2DFewShotImageList<ImageItem[]>(),
fetch3DImageList<DigitalImageItem[]>(),
fetch2DBoutiqueImageList<DigitalImageItem[]>(),
fetch2DFewShotImageList<DigitalImageItem[]>(),
])
res1.code === 0 && (threeDImageList.value = res1.data)
res2.code === 0 && (twoDBoutiqueImageList.value = res2.data)
......@@ -36,7 +36,7 @@ async function getDigitalImageList() {
}
async function handleSearchImage() {
const res = await fetchInfoByImageName<ImageItem[]>(searchImageName.value)
const res = await fetchInfoByImageName<DigitalImageItem[]>(searchImageName.value)
if (res.code === 0) {
allImageList.value = res.data
}
......
<script setup lang="ts">
import { computed } from 'vue'
import { computed, ref, watch } from 'vue'
import { useDigitalHumanDialogueStore } from '@/store/modules/digital-human-dialogue'
import { fetchGetInfoByFigureId } from '@/apis/digital-human-dialogue'
const digitalHumanDialogueStore = useDigitalHumanDialogueStore()
const figureImageUrl = ref('')
const figureId = computed(() => {
return digitalHumanDialogueStore.humanInfo.figureId
})
const backgroundImageUrl = computed(() => {
return digitalHumanDialogueStore.backgroundInfo.backgroundUrl
})
const isEmptyPreview = computed(() => {
return !figureImageUrl.value || !backgroundImageUrl.value
})
watch(
() => figureId.value,
(newValue) => {
newValue && handleGetInfoByFigureId(newValue)
},
{ immediate: true },
)
async function handleGetInfoByFigureId(figureId: string) {
const res = await fetchGetInfoByFigureId<{ imageUrl: string }>(figureId)
if (res.code === 0) {
figureImageUrl.value = res.data.imageUrl
}
}
</script>
<template>
<div class="h-[calc(100%-190px)] w-[calc(100%-32px)] overflow-hidden rounded-2xl bg-white">
<img v-show="backgroundImageUrl" :src="backgroundImageUrl" alt="背景圖" class="h-full w-full object-cover" />
<div class="relative h-[calc(100%-190px)] w-[calc(100%-32px)] overflow-hidden rounded-2xl bg-white">
<div
v-if="isEmptyPreview"
class="flex h-full w-full select-none items-center justify-center text-xs text-[#84868c]"
>
請你在右側選擇一個數字人
</div>
<img
v-show="backgroundImageUrl"
:src="backgroundImageUrl"
alt="背景圖"
class="absolute left-0 top-0 h-full w-full object-cover"
/>
<div class="absolute left-0 top-0 w-1/2">
<img v-show="figureImageUrl" :src="figureImageUrl" alt="數字人" class="h-full w-full" />
</div>
</div>
</template>
......@@ -2,6 +2,7 @@
import { computed } from 'vue'
import CustomModal from '@/components/custom-modal/custom-modal.vue'
import { AI_INDEX_URLS } from '@/config/base-url'
import { copyToClip } from '@/utils/copy'
interface Props {
isShowModal: boolean
......@@ -33,6 +34,7 @@ const showModal = computed({
})
function handleCopyLink() {
copyToClip(shareLink.value)
window.$message.success('複製成功')
}
</script>
......
......@@ -39,6 +39,7 @@ function handleUpdatePerambleStatus(isOpenPeramble: boolean) {
</template>
<NInput
v-show="digitalHumanDialogueSystemInfo.perambleStatus === 'Y'"
v-model:value="digitalHumanDialogueSystemInfo.preamble"
type="textarea"
placeholder="請描述角色的開場話術"
......
......@@ -43,6 +43,7 @@ function handleUpdateRefuseAnswerStatus(isOpenRefuseAnswer: boolean) {
</template>
<NInput
v-show="digitalHumanDialogueSystemInfo.chitchatStatus === 'Y'"
v-model:value="digitalHumanDialogueSystemInfo.chitchat"
type="textarea"
placeholder="請描述角色進行閒聊的範圍"
......@@ -76,6 +77,7 @@ function handleUpdateRefuseAnswerStatus(isOpenRefuseAnswer: boolean) {
</template>
<NInput
v-show="digitalHumanDialogueSystemInfo.refuseAnswerStatus === 'Y'"
v-model:value="digitalHumanDialogueSystemInfo.refuseAnswer"
type="textarea"
placeholder="請描述角色拒絕回答的範圍"
......
......@@ -23,6 +23,10 @@ const backgroundImageUrl = computed(() => {
return digitalHumanDialogueStore.backgroundInfo.backgroundUrl
})
const isEmptyPreview = computed(() => {
return !figureImageUrl.value || !backgroundImageUrl.value
})
async function handleGetInfoByFigureId(figureId: string) {
const res = await fetchGetInfoByFigureId<{ imageUrl: string }>(figureId)
......@@ -34,6 +38,13 @@ async function handleGetInfoByFigureId(figureId: string) {
<template>
<div class="relative h-[667px] w-[375px] overflow-hidden rounded-2xl bg-white">
<div
v-if="isEmptyPreview"
class="flex h-full w-full select-none items-center justify-center text-xs text-[#84868c]"
>
請你在右側選擇一個數字人
</div>
<img
v-show="backgroundImageUrl"
:src="backgroundImageUrl"
......
......@@ -9,3 +9,17 @@ export interface DigitalHumanDialogueTimbreItem {
iconUrl: string
isAudioPlay: boolean
}
export enum ImageType {
THREE_D = 'THREE_D',
TWO_D_BOUTIQUE = 'TWO_D_BOUTIQUE',
TWO_D_FEW_SHOT = 'TWO_D_FEW_SHOT',
}
export interface DigitalImageItem {
id: number
imageType: ImageType
imageName: string
figureId: string
imageUrl: string
}
<script setup lang="ts">
import { ref } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import CreateDigitalHumanDialogueModal from '../components/create-digital-human-dialogue-modal.vue'
import PublishDigitalHumanDialogueModal from '../components/publish-digital-human-dialogue-modal.vue'
import { useDigitalHumanDialogueStore } from '@/store/modules/digital-human-dialogue'
import {
fetchGetDigitalHumanDialogueConfigByConfigId,
fetchPublishDigitalHumanDialogue,
fetchSaveDigitalHumanDialogueConfig,
} from '@/apis/digital-human-dialogue'
import { DigitalHumanDialogueConfig } from '@/store/types/digital-human-dialogue'
const router = useRouter()
const digitalHumanDialogueStore = useDigitalHumanDialogueStore()
const isEditDigitalHumanDialogueTitle = ref(false)
const currentConfigId = ref('')
const digitalHumanDialogueTitle = ref(digitalHumanDialogueStore.baseInfo.title)
const isEditDigitalHumanDialogueTitle = ref(false)
const isShowPublishDialogueModal = ref(false)
const isUnSavedDigitalHumanDialogueConfig = ref(false)
const digitalHumanDialogueConfig = computed(() => {
return digitalHumanDialogueStore.$state
})
watch(
() => digitalHumanDialogueConfig.value,
() => {
isUnSavedDigitalHumanDialogueConfig.value = true
},
{ deep: true },
)
onMounted(() => {
if (router.currentRoute.value.params.configId) {
currentConfigId.value = router.currentRoute.value.params.configId as string
handleGetDigitalHumanDialogueConfig()
return
}
const showExportModal = ref(false)
router.replace({ name: 'Root' })
})
async function handleGetDigitalHumanDialogueConfig() {
fetchGetDigitalHumanDialogueConfigByConfigId<DigitalHumanDialogueConfig>(currentConfigId.value)
.then(async (res) => {
if (res.code === 0) {
await digitalHumanDialogueStore.updateDigitalHumanDialogue(res.data)
isUnSavedDigitalHumanDialogueConfig.value = false
}
})
.catch(() => {
router.replace({ name: 'Home' })
})
}
function handleBackHome() {
router.replace({ name: 'Home' })
function handleBack() {
if (isUnSavedDigitalHumanDialogueConfig.value) {
window.$dialog.info({
title: '提示',
content: '請保存修改內容後再返回上一級頁面',
negativeText: '直接返回',
positiveText: '保 存',
onNegativeClick: () => {
router.back()
},
onPositiveClick: async () => {
const res = await fetchSaveDigitalHumanDialogueConfig(digitalHumanDialogueConfig.value)
if (res.code === 0) {
window.$message.success('保存成功')
router.back()
}
},
})
return
}
router.back()
}
function handleShowEditDigitalHumanDialogueTitle() {
isEditDigitalHumanDialogueTitle.value = true
digitalHumanDialogueTitle.value = digitalHumanDialogueStore.baseInfo.title
}
function handleSaveDigitalHumanDialogueTitle() {
async function handleSaveDigitalHumanDialogueTitle() {
isEditDigitalHumanDialogueTitle.value = false
if (!digitalHumanDialogueTitle.value) {
......@@ -35,25 +96,39 @@ function handleSaveDigitalHumanDialogueTitle() {
return
}
window.$message.success('保存成功')
const res = await fetchSaveDigitalHumanDialogueConfig(digitalHumanDialogueConfig.value)
if (res.code === 0) {
window.$message.success('保存成功')
isUnSavedDigitalHumanDialogueConfig.value = false
}
}
function handleSaveDigitalHumanDialogueConfig() {
window.$message.success('保存成功')
async function handleSaveDigitalHumanDialogueConfig() {
const res = await fetchSaveDigitalHumanDialogueConfig(digitalHumanDialogueConfig.value)
if (res.code === 0) {
window.$message.success('保存成功')
isUnSavedDigitalHumanDialogueConfig.value = false
}
}
function handlePublishDigitalHumanDialogue() {
isShowPublishDialogueModal.value = true
window.$message.success('發佈成功')
async function handlePublishDigitalHumanDialogue() {
const res = await fetchPublishDigitalHumanDialogue(currentConfigId.value)
if (res.code === 0) {
isShowPublishDialogueModal.value = true
window.$message.success('發佈成功')
}
}
</script>
<template>
<header class="flex h-14 items-center justify-between bg-white px-4">
<div class="flex items-center">
<CustomIcon class="mr-4 cursor-pointer text-lg" icon="mingcute:left-line" @click="handleBackHome" />
<CustomIcon class="mr-4 cursor-pointer text-lg" icon="mingcute:left-line" @click="handleBack" />
<div v-show="!isEditDigitalHumanDialogueTitle" class="flex items-center">
<span class="font-500">{{ digitalHumanDialogueTitle }}</span>
<span class="font-500">{{ digitalHumanDialogueConfig.baseInfo.title }}</span>
<CustomIcon
icon="bxs:edit"
class="text-theme-color ml-1 cursor-pointer text-lg"
......@@ -75,7 +150,13 @@ function handlePublishDigitalHumanDialogue() {
<div class="flex items-center">
<div class="flex items-center gap-4">
<NButton class="w-[72px]! h-[32px]! rounded-md!" @click="handleSaveDigitalHumanDialogueConfig"> 保存 </NButton>
<NButton
class="w-[72px]! h-[32px]! rounded-md!"
:disabled="!isUnSavedDigitalHumanDialogueConfig"
@click="handleSaveDigitalHumanDialogueConfig"
>
保存
</NButton>
<NButton class="w-[72px]! h-[32px]! rounded-md!" type="info" @click="handlePublishDigitalHumanDialogue">
發佈
</NButton>
......@@ -83,12 +164,6 @@ function handlePublishDigitalHumanDialogue() {
</div>
</header>
<CreateDigitalHumanDialogueModal
v-model:is-show-modal="showExportModal"
modal-title="新建對話"
:btn-loading="false"
/>
<PublishDigitalHumanDialogueModal
v-model:is-show-modal="isShowPublishDialogueModal"
modal-title="發佈詳情"
......
<script setup lang="ts">
import { onMounted } from 'vue'
import HeaderBar from './header-bar.vue'
import MainContent from './main-content.vue'
import SideBar from './side-bar.vue'
onMounted(() => {})
</script>
<template>
......
......@@ -59,10 +59,13 @@ onMounted(() => {
async function handleGetDiaglogList() {
dialogueTableLoading.value = true
const res = await fetchGetDigitalHumanDialogueList<DiaglogueTableItem[]>(searchQuery.value)
const res = await fetchGetDigitalHumanDialogueList<DiaglogueTableItem[]>(searchQuery.value, {
pagingInfo: pagingInfo.value,
})
if (res.code === 0) {
digitalHumanDialogueList.value = res.data
pagingInfo.value = res.pagingInfo as PaginationInfo
dialogueTableLoading.value = false
}
}
......@@ -79,6 +82,7 @@ async function handleMultiDeleteDiaglogueConfig() {
if (res.code === 0) {
window.$message.success('刪除成功')
checkedConfigIdList.value = []
digitalHumanDialogueList.value.length === 1 && (pagingInfo.value.pageNo = pagingInfo.value.pageNo - 1)
await handleGetDiaglogList()
}
},
......@@ -190,7 +194,7 @@ function handleDeleteDiaglogueConfig(configId: string) {
const res = await fetchDelectDigitalHumanDialogueConfigByConfigId(configId)
if (res.code === 0) {
window.$message.success('刪除成功')
// agentAppList.value.length === 1 && (pagingInfo.value.pageNo = pagingInfo.value.pageNo - 1)
digitalHumanDialogueList.value.length === 1 && (pagingInfo.value.pageNo = pagingInfo.value.pageNo - 1)
await handleGetDiaglogList()
}
},
......@@ -201,6 +205,17 @@ function handleShowPubishDetailModal(configId: string) {
isShowPublishDigitalHumanDialogueModal.value = true
publishDetailConfigId.value = configId
}
function handleGetDialogueListUpdatePageNo(pageNo: number) {
pagingInfo.value.pageNo = pageNo
handleGetDiaglogList()
}
function handleGetDialogueListUpdatePageSize(pageSize: number) {
pagingInfo.value.pageNo = 1
pagingInfo.value.pageSize = pageSize
handleGetDiaglogList()
}
</script>
<template>
......@@ -244,29 +259,35 @@ function handleShowPubishDetailModal(configId: string) {
</div>
</div>
<NDataTable
:loading="dialogueTableLoading"
:bordered="false"
:single-line="false"
:columns="dialogueTableColumns"
:data="digitalHumanDialogueList"
:row-key="(row: DiaglogueTableItem) => row.configId"
:scroll-x="1056"
:max-height="tableContentY"
@update:checked-row-keys="handleUpdateCheckedDialogueList"
>
<template #empty>
<div :style="{ height: tableContentY + 'px' }" class="flex items-center justify-center">
<div v-show="!dialogueTableLoading" class="flex flex-col items-center justify-center">
<div class="h-[123px] w-[156px] bg-[url('@/assets/images/empty-dialogue.png')] bg-[length:100%_100%]" />
<span class="mt-3 text-[#5b647a]">{{ emtpyDialogueText }}</span>
<div :style="{ height: tableContentY + 48 + 'px' }">
<NDataTable
:loading="dialogueTableLoading"
:bordered="false"
:single-line="false"
:columns="dialogueTableColumns"
:data="digitalHumanDialogueList"
:row-key="(row: DiaglogueTableItem) => row.configId"
:scroll-x="1056"
:max-height="tableContentY"
@update:checked-row-keys="handleUpdateCheckedDialogueList"
>
<template #empty>
<div :style="{ height: tableContentY + 'px' }" class="flex items-center justify-center">
<div v-show="!dialogueTableLoading" class="flex flex-col items-center justify-center">
<div class="h-[123px] w-[156px] bg-[url('@/assets/images/empty-dialogue.png')] bg-[length:100%_100%]" />
<span class="mt-3 text-[#5b647a]">{{ emtpyDialogueText }}</span>
</div>
</div>
</div>
</template>
</NDataTable>
</template>
</NDataTable>
</div>
<div v-show="isShowPagination" class="mt-5 flex w-full justify-end">
<CustomPagination :paging-info="pagingInfo" />
<CustomPagination
:paging-info="pagingInfo"
@update-page-no="handleGetDialogueListUpdatePageNo"
@update-page-size="handleGetDialogueListUpdatePageSize"
/>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment