Commit e9a133f4 authored by shirlyn.guo's avatar shirlyn.guo 🤡

chore: 个人空间-应用样式优化

parent 024ccbb0
...@@ -137,3 +137,28 @@ export function fetchCreateAgentTitleAndDesc<T>(payload: { input: string }, cont ...@@ -137,3 +137,28 @@ export function fetchCreateAgentTitleAndDesc<T>(payload: { input: string }, cont
export function fetchGetLargeModelInfo<T>(modelName: string) { export function fetchGetLargeModelInfo<T>(modelName: string) {
return request.post<T>(`/agentApplicationInfoRest/getLargeModelInfo.json?query=${modelName}`) return request.post<T>(`/agentApplicationInfoRest/getLargeModelInfo.json?query=${modelName}`)
} }
/**
* * @param agentId 应用Id
* @returns 收藏应用
*/
export function fetchApplicationsCollectionStatusChange<T>(agentId: string) {
return request.post<T>(`/agentApplicationInfoRest/collectOrCancelAgentInPerson.json?agentId=${agentId}`)
}
/**
*
* @param payload payload 应用参数
* @returns 上架应用
*/
export function fetchSalePublishApplication<T>(payload: object) {
return request.post<T>('/bizAgentApplicationMallRest/publishAgentToMall.json', payload)
}
/**
* * @param agentPublishId 发布应用表的id
* @returns 下架应用
*/
export function fetchRemoveSalePublishApplication<T>(agentPublishId: number) {
return request.post<T>(`/bizAgentApplicationMallRest/unSaleAgentInMall.json?agentPublishId=${agentPublishId}`)
}
...@@ -48,18 +48,20 @@ useResizeObserver(rootContainer, (entries) => { ...@@ -48,18 +48,20 @@ useResizeObserver(rootContainer, (entries) => {
</script> </script>
<template> <template>
<div ref="rootContainer" class="h-full w-full"> <n-dialog-provider>
<MessageTipModal /> <div ref="rootContainer" class="h-full w-full">
<MessageTipModal />
<NConfigProvider <NConfigProvider
class="h-full w-full" class="h-full w-full"
:locale="currentLocale" :locale="currentLocale"
:date-locale="currentDateLocale" :date-locale="currentDateLocale"
:theme-overrides="themeOverrides" :theme-overrides="themeOverrides"
> >
<RouterView v-slot="{ Component }"> <RouterView v-slot="{ Component }">
<Component :is="Component" /> <Component :is="Component" />
</RouterView> </RouterView>
</NConfigProvider> </NConfigProvider>
</div> </div>
</n-dialog-provider>
</template> </template>
...@@ -52,6 +52,15 @@ common_module: ...@@ -52,6 +52,15 @@ common_module:
deletion_failed_please_try_again: '删除失败,请重试' deletion_failed_please_try_again: '删除失败,请重试'
select_all: '全选' select_all: '全选'
quit: '退出' quit: '退出'
all: '全部'
collect: '收藏'
listing_successfully: '上架成功'
listing_failed: '上架失败'
removal_successfully: '下架成功'
removal_failed: '下架失败'
collect_successfully: '收藏成功'
collect_unsubscribed: '已取消收藏'
cancel: '取消'
dialogue_module: dialogue_module:
continue_question_message: '你可以继续提问' continue_question_message: '你可以继续提问'
...@@ -68,6 +77,9 @@ common_module: ...@@ -68,6 +77,9 @@ common_module:
copy: '复制' copy: '复制'
delete: '删除' delete: '删除'
view: '查看' view: '查看'
analysis: '分析'
listing_applications: '上架应用'
remove_applications: '下架应用'
pagination_module: pagination_module:
page_no: '条' page_no: '条'
...@@ -134,14 +146,17 @@ personal_space_module: ...@@ -134,14 +146,17 @@ personal_space_module:
large_model: '模型名称' large_model: '模型名称'
agent_id: '应用ID' agent_id: '应用ID'
agent_publish_status: '发布状态' agent_publish_status: '发布状态'
modified_time: '最近编辑时间' modified_time: '最近编辑'
channel: '渠道' channel: '渠道'
channel_popover_text: '查看发布详情' channel_popover_text: '查看发布详情'
agent_copy: '的副本' agent_copy: '的副本'
empty_agent_list: '暂无应用' empty_agent_list: '暂无应用'
search_empty_agent_list: '暂⽆搜索结果,请换⼀个关键词进⾏搜索' search_empty_agent_list: '没有搜索到相关内容'
delete_agent_dialog_title: '确定要删除选中的应用吗?' delete_agent_dialog_title: '确定要删除选中的应用吗?'
delete_agent_dialog_content: '删除后,如需再次使用,请重新创建' delete_agent_dialog_content: '删除后,如需再次使用,请重新创建'
remove_applications_dialog_title: '确定要下架应用吗?'
already_bottom: '已经到底啦'
application_empty: '未创建应用'
agent_setting_module: agent_setting_module:
modified: '已变更' modified: '已变更'
...@@ -233,6 +248,28 @@ personal_space_module: ...@@ -233,6 +248,28 @@ personal_space_module:
share_link: '分享链接' share_link: '分享链接'
copy_share_url_success_message: '链接复制成功,快分享给你的好友吧!' copy_share_url_success_message: '链接复制成功,快分享给你的好友吧!'
agent_sale_module:
application_square_release_setting: '应用广场发布配置'
application_classification: '应用分类'
application_classification_null: '应用分类不能为空'
application_classify:
media_entertainment: '媒体文娱'
education_training: '教育培训'
business_services: '商业服务'
medical_health: '医疗健康'
efficiency_tools: '效率工具'
office_personnel: '办公人事'
marketing_commerce: '营销电商'
finance: '金融'
law: '法律'
culture_tourism: '文旅'
is_copy: '是否允许复制'
yes: '是'
no: '否'
confirm_release: '确认发布'
copy_tip: '选择「是」代表您允许平台的开发者和用户,复制您的应用配置进行二次开发来创建新应用。注意:私有配置不支持复制(私有配置包含:知识库、数据库)'
knowledge_module: knowledge_module:
search_knowledge_placeholder: '请输入知识库名称' search_knowledge_placeholder: '请输入知识库名称'
knowledge_name: '知识库名称' knowledge_name: '知识库名称'
......
...@@ -52,6 +52,15 @@ common_module: ...@@ -52,6 +52,15 @@ common_module:
deletion_failed_please_try_again: '刪除失敗,請重試' deletion_failed_please_try_again: '刪除失敗,請重試'
select_all: '全選' select_all: '全選'
quit: '退出' quit: '退出'
all: '全部'
collect: '收藏'
listing_successfully: '上架成功'
listing_failed: '上架失敗'
removal_successfully: '下架成功'
removal_failed: '下架失敗'
collect_successfully: '收藏成功'
collect_unsubscribed: '已取消收藏'
cancel: '取消'
dialogue_module: dialogue_module:
continue_question_message: '你可以繼續提問' continue_question_message: '你可以繼續提問'
...@@ -68,6 +77,9 @@ common_module: ...@@ -68,6 +77,9 @@ common_module:
copy: '複製' copy: '複製'
delete: '刪除' delete: '刪除'
view: '查看' view: '查看'
analysis: '分析'
listing_applications: '上架應用'
remove_applications: '下架應用'
pagination_module: pagination_module:
page_no: '條' page_no: '條'
...@@ -134,14 +146,17 @@ personal_space_module: ...@@ -134,14 +146,17 @@ personal_space_module:
large_model: '模型名稱' large_model: '模型名稱'
agent_id: '應用ID' agent_id: '應用ID'
agent_publish_status: '發佈狀態' agent_publish_status: '發佈狀態'
modified_time: '最近編輯時間' modified_time: '最近編輯'
channel: '渠道' channel: '渠道'
channel_popover_text: '查看發佈詳情' channel_popover_text: '查看發佈詳情'
agent_copy: '的副本' agent_copy: '的副本'
empty_agent_list: '暫無應用' empty_agent_list: '暫無應用'
search_empty_agent_list: '暫⽆搜索結果,請換⼀個關鍵詞進⾏搜索' search_empty_agent_list: '沒有蒐索到相關內容'
delete_agent_dialog_title: '確定要刪除選中的應用嗎?' delete_agent_dialog_title: '確定要刪除選中的應用嗎?'
delete_agent_dialog_content: '刪除後,如需再次使用,請重新創建' delete_agent_dialog_content: '刪除後,如需再次使用,請重新創建'
remove_applications_dialog_title: '確定要下架應用嗎?'
already_bottom: '已經到底啦'
application_empty: '未創建應用'
agent_setting_module: agent_setting_module:
modified: '已變更' modified: '已變更'
...@@ -233,6 +248,28 @@ personal_space_module: ...@@ -233,6 +248,28 @@ personal_space_module:
share_link: '分享鏈接' share_link: '分享鏈接'
copy_share_url_success_message: '鏈接複製成功,快分享給你的好友吧!' copy_share_url_success_message: '鏈接複製成功,快分享給你的好友吧!'
agent_sale_module:
application_square_release_setting: '應用廣場發佈配寘'
application_classification: '應用分類'
application_classification_null: '應用分類不能為空'
application_classify:
media_entertainment: '媒體文娛'
education_training: '教育培訓'
business_services: '商業服務'
medical_health: '醫療健康'
efficiency_tools: '效率工具'
office_personnel: '辦公人事'
marketing_commerce: '行銷電商'
finance: '金融'
law: '法律'
culture_tourism: '文旅'
is_copy: '是否允許複製'
yes: '是'
no: '否'
confirm_release: '確認發佈'
copy_tip: '選擇「是」代表您允許平臺的開發者和用戶,複製您的應用配寘進行二次開發來創建新應用。 注意:私有配寘不支持複製(私有配寘包含:知識庫、資料庫)'
knowledge_module: knowledge_module:
search_knowledge_placeholder: '請輸入知識庫名稱' search_knowledge_placeholder: '請輸入知識庫名稱'
knowledge_name: '知識庫名稱' knowledge_name: '知識庫名稱'
......
...@@ -17,6 +17,7 @@ export function defaultPersonalAppConfigState(): PersonalAppConfigState { ...@@ -17,6 +17,7 @@ export function defaultPersonalAppConfigState(): PersonalAppConfigState {
continuousQuestionStatus: 'default', continuousQuestionStatus: 'default',
continuousQuestionSystem: '', continuousQuestionSystem: '',
continuousQuestionTurn: 3, continuousQuestionTurn: 3,
variableStructure: [],
}, },
knowledgeConfig: { knowledgeConfig: {
knowledgeIds: [], knowledgeIds: [],
...@@ -28,6 +29,9 @@ export function defaultPersonalAppConfigState(): PersonalAppConfigState { ...@@ -28,6 +29,9 @@ export function defaultPersonalAppConfigState(): PersonalAppConfigState {
temperature: 0.5, temperature: 0.5,
}, },
modifiedTime: new Date(), modifiedTime: new Date(),
isCollect: '',
isSale: '',
agentPublishId: 1,
} }
} }
......
...@@ -13,6 +13,7 @@ export interface PersonalAppConfigState { ...@@ -13,6 +13,7 @@ export interface PersonalAppConfigState {
continuousQuestionStatus: 'default' | 'close' //追问状态 continuousQuestionStatus: 'default' | 'close' //追问状态
continuousQuestionSystem: string // 追问提示词 customizable时必填 continuousQuestionSystem: string // 追问提示词 customizable时必填
continuousQuestionTurn: number // 追问轮次 1-5 customizable时必填 continuousQuestionTurn: number // 追问轮次 1-5 customizable时必填
variableStructure: object[]
} }
knowledgeConfig: { knowledgeConfig: {
knowledgeIds: string[] //知识库ID knowledgeIds: string[] //知识库ID
...@@ -24,4 +25,7 @@ export interface PersonalAppConfigState { ...@@ -24,4 +25,7 @@ export interface PersonalAppConfigState {
temperature: number //多样性 0-1.00 temperature: number //多样性 0-1.00
} }
modifiedTime: Date modifiedTime: Date
isCollect: string
isSale: string
agentPublishId: number
} }
import { NImage, NPopover } from 'naive-ui'
import { h } from 'vue'
import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import { formatDateTime } from '@/utils/date-formatter'
import i18n from '@/locales'
const t = i18n.global.t
export function createPersonalAppColumn(handlePersonalAppTableAction: (actionType: string, agentId: string) => void) {
return [
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.agent_title')),
key: 'agentTitle',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 210,
fixed: 'left',
render(row: PersonalAppConfigState) {
return h(
'div',
{
style: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
},
{
default: () => [
h(NImage, {
width: '36px',
src: row.baseInfo.agentAvatar || 'https://gsst-poe-sit.gz.bcebos.com/data/20240911/1726041369632.webp',
showToolbar: false,
previewDisabled: true,
style: {
borderRadius: '8px',
height: '36px',
},
}),
h(
'span',
{
style: {
marginLeft: '12px',
fontWeight: '600',
flex: '1',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
className: 'hover:text-theme-color cursor-pointer',
onClick: () => handlePersonalAppTableAction('edit', row.baseInfo.agentId),
},
{
default: () => [
h(
NPopover,
{
props: { placement: 'top' },
style: { maxWidth: '200px' },
},
{
trigger: () =>
h(
'span',
{
style: {
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
width: '100%',
display: 'block',
},
},
row.baseInfo.agentTitle || '--',
),
default: () => h('span', {}, row.baseInfo.agentTitle || '--'),
},
),
],
},
),
],
},
)
},
},
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.large_model')),
key: 'largeModel',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 210,
render(row: PersonalAppConfigState) {
return row.commModelConfig.largeModel
},
},
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.agent_id')),
key: 'agentId',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 180,
render(row: PersonalAppConfigState) {
return h(
'div',
{
style: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
},
{
default: () => [
h(
'span',
{
style: {
flex: '1',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
},
{
default: () => [
h(
NPopover,
{
props: { placement: 'top' },
},
{
trigger: () => h('span', {}, row.baseInfo.agentId || '--'),
default: () => h('span', {}, row.baseInfo.agentId || '--'),
},
),
],
},
),
h(CustomIcon, {
icon: 'ion:copy-outline',
style: {
cursor: 'pointer',
color: '#000DFF',
},
onClick: () => handlePersonalAppTableAction('copyAgentId', row.baseInfo.agentId),
}),
],
},
)
},
},
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.agent_publish_status')),
key: 'agentPublishStatus',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 230,
render(row: PersonalAppConfigState) {
let publicText = '----'
let publicIcon = 'ion:close-circle-outline'
let bgColor = '#84868c'
let color = '#f2f5f9'
switch (row.baseInfo.agentPublishStatus) {
case 'draft':
publicText = 'common_module.unpublished'
publicIcon = 'gg:time'
bgColor = '#f2f5f9'
color = '#84868c'
break
case 'publish':
publicText = 'common_module.published'
publicIcon = 'gg:check-o'
bgColor = '#ecffe6'
color = '#30bf13'
break
}
return [
h(
'div',
{ style: { display: 'flex', alignItems: 'center' } },
{
default: () => [
h(
'div',
{
className: 'flex justify-center items-center',
style: {
backgroundColor: bgColor,
fontSize: '12px',
width: '72px',
height: '24px',
borderRadius: '4px',
marginRight: '6px',
},
},
{
default: () => [
h(CustomIcon, {
icon: publicIcon,
style: {
color,
fontSize: '16px',
marginRight: '4px',
},
}),
h(
'span',
{
style: {
color,
},
},
t(publicText),
),
],
},
),
// row.baseInfo.agentPublishStatus === 'publish' && formatDateTime(row.modifiedTime),
],
},
),
]
},
},
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.modified_time')),
key: 'modifiedTime',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 170,
render(row: PersonalAppConfigState) {
return formatDateTime(row.modifiedTime)
},
},
{
title: () => h('span', {}, t('personal_space_module.agent_module.agent_list_module.channel')),
key: 'channel',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 140,
render(row: PersonalAppConfigState) {
return [
row.baseInfo.agentPublishStatus === 'publish'
? h(
NPopover,
{
props: { placement: 'top' },
},
{
trigger: () =>
h(
'div',
{
className: 'flex justify-center items-center',
style: {
backgroundColor: '#e6f0ff',
borderRadius: '4px',
padding: '6px',
},
onClick: () => handlePersonalAppTableAction('openPublishDetail', row.baseInfo.agentId),
},
{
default: () => [
h(CustomIcon, {
icon: 'icon-park-solid:computer',
style: {
fontSize: '16px',
cursor: 'pointer',
color: '#000DFF',
},
}),
],
},
),
default: () =>
h('span', {}, t('personal_space_module.agent_module.agent_list_module.channel_popover_text')),
},
)
: '--',
]
},
},
{
title: () => h('span', {}, t('common_module.data_table_module.action')),
key: 'action',
align: 'left',
ellipsis: {
tooltip: true,
},
width: 190,
fixed: 'right',
render(row: PersonalAppConfigState) {
return [
h(
'span',
{
style: { marginRight: '20px' },
className: 'text-theme-color cursor-pointer hover:opacity-80',
onClick: () => handlePersonalAppTableAction('edit', row.baseInfo.agentId),
},
{ default: () => t('common_module.data_table_module.edit') },
),
h(
'span',
{
style: { marginRight: '20px' },
className: 'text-theme-color cursor-pointer hover:opacity-80',
onClick: () => handlePersonalAppTableAction('copy', row.baseInfo.agentId),
},
{ default: () => t('common_module.data_table_module.copy') },
),
h(
'span',
{
style: { marginRight: '20px', color: '#F25744' },
className: 'cursor-pointer hover:opacity-80',
onClick: () => handlePersonalAppTableAction('delete', row.baseInfo.agentId),
},
{ default: () => t('common_module.data_table_module.delete') },
),
]
},
},
]
}
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, ref } from 'vue' import { computed, ref, useTemplateRef, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import CustomIcon from '@/components/custom-icon/custom-icon.vue' import { Search, More, Star } from '@icon-park/vue-next'
import CustomPagination, { PaginationInfo } from '@/components/custom-pagination/custom-pagination.vue' import { PaginationInfo } from '@/components/custom-pagination/custom-pagination.vue'
import { createPersonalAppColumn } from './columns.ts' import { formatDateTime } from '@/utils/date-formatter'
import useTableScrollY from '@/composables/useTableScrollY.ts'
import { import {
fetchApplicationsCollectionStatusChange,
fetchDeleteApplication, fetchDeleteApplication,
fetchGetDebugApplicationInfo,
fetchGetApplicationList, fetchGetApplicationList,
fetchSaveAgentApplication, fetchRemoveSalePublishApplication,
} from '@/apis/agent-application.ts' } from '@/apis/agent-application.ts'
import { PersonalAppConfigState } from '@/store/types/personal-app-config.ts' import { PersonalAppConfigState } from '@/store/types/personal-app-config.ts'
import { copyToClip } from '@/utils/copy.ts' import { useScroll } from '@vueuse/core'
import { router } from '@/router/index.ts'
import SaleApplicationsConfigurationModal from './sale-applications-configuration-modal.vue'
import { defaultPersonalAppConfigState } from '@/store/modules/personal-app-config'
import searchEmptyImage from '@/assets/images/search-empty.png'
import applicationEmptyImage from '@/assets/images/application-empty.png'
const { t } = useI18n() const { t } = useI18n()
const router = useRouter() const cardContentWrapRef = useTemplateRef<HTMLDivElement>('cardContentWrapRef')
const smooth = ref(false)
const behavior = computed(() => (smooth.value ? 'smooth' : 'auto'))
const { arrivedState } = useScroll(cardContentWrapRef, { behavior })
const { pageContentWrapRef, tableContentY } = useTableScrollY(48 + 32 + 16 + 16 + 28) const selectedPublishStatusValue = ref('')
const isShowSaleApplicationsConfigurationModal = ref(false)
const saleApplicationsInfo = ref<PersonalAppConfigState>(defaultPersonalAppConfigState())
const columns = createPersonalAppColumn(handleClickPersonalAppTableAction) const publishStatusOptions = [
{
label: t('common_module.all'),
value: '',
},
{
label: t('common_module.published'),
value: 'publish',
},
{
label: t('common_module.collect'),
value: 'Y',
},
{
label: t('common_module.unpublished'),
value: 'draft',
},
]
const pagingInfo = ref<PaginationInfo>({ const pagingInfo = ref<PaginationInfo>({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 12,
totalPages: 0, totalPages: 0,
totalRows: 0, totalRows: 0,
}) })
...@@ -33,92 +60,75 @@ const pagingInfo = ref<PaginationInfo>({ ...@@ -33,92 +60,75 @@ const pagingInfo = ref<PaginationInfo>({
const agentAppList = ref<PersonalAppConfigState[]>([]) const agentAppList = ref<PersonalAppConfigState[]>([])
const agentSearchInputValue = ref('') const agentSearchInputValue = ref('')
const agentAppListTableLoading = ref(false) const agentAppListLoading = ref(false)
const emptyTableText = ref(t('personal_space_module.agent_module.agent_list_module.empty_agent_list')) const agentAppListBottomLoadingMore = ref(false)
const isLoadingPagination = computed(() => { const emptyTableText = ref(t('personal_space_module.agent_module.agent_list_module.application_empty'))
return tableContentY.value > 0
})
onMounted(async () => { const emptyTableImage = ref()
await handleGetApplicationList()
})
async function handleGetApplicationList() { watch(
agentAppListTableLoading.value = true () => arrivedState.bottom,
const res = await fetchGetApplicationList<PersonalAppConfigState[]>({ () => {
if (arrivedState.bottom) {
if (pagingInfo.value.pageNo < pagingInfo.value.totalPages) {
pagingInfo.value.pageNo += 1
agentAppListBottomLoadingMore.value = true
getApplicationList(true)
}
}
},
)
;(function () {
agentAppListLoading.value = true
getApplicationList()
})()
function getApplicationList(isLoadMore = false) {
if (!isLoadMore) {
pagingInfo.value.pageNo = 1
pagingInfo.value.totalPages = 0
pagingInfo.value.totalRows = 0
}
const isCollect = ref('')
const publishStatus = ref(selectedPublishStatusValue.value)
if (selectedPublishStatusValue.value === 'Y') {
isCollect.value = 'Y'
publishStatus.value = ''
}
const payload = {
query: agentSearchInputValue.value, query: agentSearchInputValue.value,
publishStatus: publishStatus.value,
isCollect: isCollect.value,
pagingInfo: pagingInfo.value, pagingInfo: pagingInfo.value,
}).finally(() => (agentAppListTableLoading.value = false))
if (res.code === 0) {
agentAppList.value = res.data
pagingInfo.value = res.pagingInfo as PaginationInfo
emptyTableText.value = agentSearchInputValue.value
? t('personal_space_module.agent_module.agent_list_module.search_empty_agent_list')
: t('personal_space_module.agent_module.agent_list_module.empty_agent_list')
} }
fetchGetApplicationList<PersonalAppConfigState[]>(payload)
.then((res) => {
if (res.code !== 0) return
agentAppList.value = isLoadMore ? [...agentAppList.value, ...res.data] : res.data
pagingInfo.value = res.pagingInfo as PaginationInfo
emptyTableText.value = agentSearchInputValue.value
? t('personal_space_module.agent_module.agent_list_module.search_empty_agent_list')
: t('personal_space_module.agent_module.agent_list_module.application_empty')
emptyTableImage.value =
agentSearchInputValue.value && agentAppList.value.length === 0 ? searchEmptyImage : applicationEmptyImage
})
.finally(() => {
agentAppListLoading.value = false
agentAppListBottomLoadingMore.value = false
})
} }
function handleClickPersonalAppTableAction(actionType: string, agentId: string) { function handleBasePublishingStatusGetAgentList() {
switch (actionType) { agentAppListLoading.value = true
case 'copyAgentId': getApplicationList()
handleCopyAgentId(agentId)
break
case 'openPublishDetail':
handleOpenPublishDetail(agentId)
break
case 'edit':
handleEditPersonalApp(agentId)
break
case 'copy':
handleCopyPersonalApp(agentId)
break
case 'delete':
handleDeletePersonalApp(agentId)
break
}
}
function handleCopyAgentId(agentId: string) {
copyToClip(agentId)
window.$message.success(t('common_module.copy_success_message'))
}
function handleOpenPublishDetail(agentId: string) {
router.push({
name: 'PersonalAppSetting',
query: {
tabKey: 'publish',
},
params: {
agentId,
},
})
}
function handleEditPersonalApp(agentId: string) {
router.push({
name: 'PersonalAppSetting',
params: {
agentId,
},
})
} }
async function handleCopyPersonalApp(agentId: string) { function handleEnterKeypress(event: KeyboardEvent) {
const res = await fetchGetDebugApplicationInfo<PersonalAppConfigState>(agentId) if (event.code === 'Enter' && !event.shiftKey) {
event.preventDefault()
if (res.code === 0) {
const payload = res.data
payload.baseInfo.agentId = ''
payload.baseInfo.agentTitle += t('personal_space_module.agent_module.agent_list_module.agent_copy')
payload.baseInfo.agentPublishStatus = 'draft'
await fetchSaveAgentApplication(payload)
await handleGetApplicationList() getApplicationList()
} }
} }
...@@ -129,39 +139,72 @@ function handleDeletePersonalApp(agentId: string) { ...@@ -129,39 +139,72 @@ function handleDeletePersonalApp(agentId: string) {
negativeText: t('common_module.cancel_btn_text'), negativeText: t('common_module.cancel_btn_text'),
positiveText: t('common_module.confirm_btn_text'), positiveText: t('common_module.confirm_btn_text'),
onPositiveClick: async () => { onPositiveClick: async () => {
const res = await fetchDeleteApplication(agentId) fetchDeleteApplication(agentId).then((res) => {
if (res.code === 0) { if (res.code !== 0) return
window.$message.success(t('common_module.delete_success_message')) window.$message.success(t('common_module.delete_success_message'))
agentAppList.value.length === 1 && (pagingInfo.value.pageNo = pagingInfo.value.pageNo - 1) agentAppList.value.length === 1 && (pagingInfo.value.pageNo = pagingInfo.value.pageNo - 1)
await handleGetApplicationList() getApplicationList()
} })
}, },
}) })
} }
async function handleEnterKeypress(event: KeyboardEvent) { function handleChangeApplicationsSaleStatus(personalApp: PersonalAppConfigState) {
if (event.code === 'Enter' && !event.shiftKey) { if (personalApp.isSale === 'N') {
event.preventDefault() saleApplicationsInfo.value = personalApp
isShowSaleApplicationsConfigurationModal.value = true
await handleGetApplicationList() } else {
fetchRemoveSalePublishApplication(personalApp.agentPublishId)
.then(() => {
personalApp.isSale = 'N'
window.$message.success(t('common_module.removal_successfully'))
})
.catch(() => {
window.$message.success(t('common_module.removal_failed'))
})
} }
} }
async function handleGetApplicationListUpdatePageNo(pageNo: number) { function handleEditPersonalApp(agentId: string) {
pagingInfo.value.pageNo = pageNo router.push({
await handleGetApplicationList() name: 'PersonalAppSetting',
params: {
agentId,
},
})
}
function handleApplicationsCollect(personalApp: PersonalAppConfigState) {
fetchApplicationsCollectionStatusChange(personalApp.baseInfo.agentId).then(() => {
if (personalApp.isCollect === 'Y') {
personalApp.isCollect = 'N'
window.$message.success(t('common_module.collect_unsubscribed'))
} else {
personalApp.isCollect = 'Y'
window.$message.success(t('common_module.collect_successfully'))
}
})
}
function handleSelectAddType() {
router.push({ name: 'PersonalAppSetting' })
} }
async function handleGetApplicationListUpdatePageSize(pageSize: number) { function handleAnalysisPersonalApp(personalApp: PersonalAppConfigState) {
pagingInfo.value.pageNo = 1 console.log('分析', personalApp)
pagingInfo.value.pageSize = pageSize
await handleGetApplicationList()
} }
</script> </script>
<template> <template>
<div ref="pageContentWrapRef" class="h-full"> <div class="h-full">
<div class="mb-4 flex justify-end"> <div class="mb-[13px] flex justify-between">
<n-space vertical class="w-[118px]">
<n-select
v-model:value="selectedPublishStatusValue"
:options="publishStatusOptions"
@update:value="handleBasePublishingStatusGetAgentList"
/>
</n-space>
<NInput <NInput
v-model:value="agentSearchInputValue" v-model:value="agentSearchInputValue"
:placeholder="t('personal_space_module.agent_module.agent_list_module.search_agent_placeholder')" :placeholder="t('personal_space_module.agent_module.agent_list_module.search_agent_placeholder')"
...@@ -169,43 +212,176 @@ async function handleGetApplicationListUpdatePageSize(pageSize: number) { ...@@ -169,43 +212,176 @@ async function handleGetApplicationListUpdatePageSize(pageSize: number) {
@keypress="handleEnterKeypress" @keypress="handleEnterKeypress"
> >
<template #suffix> <template #suffix>
<CustomIcon <Search
icon="tdesign:search" theme="outline"
class="cursor-pointer text-base text-[#999]" size="16"
@click="handleGetApplicationList" fill="#999"
:stroke-width="2"
class="cursor-pointer text-base"
@click="getApplicationList()"
/> />
</template> </template>
</NInput> </NInput>
</div> </div>
<div class="mb-4" :style="{ height: tableContentY + 48 + 'px' }"> <div ref="cardContentWrapRef" class="h-full max-h-[650px] overflow-y-auto pb-[16px]" style="scrollbar-width: none">
<NDataTable <div class="flex justify-center">
:loading="agentAppListTableLoading" <n-spin v-show="agentAppListLoading" size="large" />
:bordered="true" </div>
:bottom-bordered="true" <div v-show="!agentAppListLoading">
:single-line="false" <div v-if="agentAppList.length" class="flex flex-wrap justify-start">
:data="agentAppList" <div v-for="item in agentAppList" :key="item.baseInfo.agentId" class="mb-[18px] mr-[15px]">
:columns="columns" <n-card class="rounded-[10px]! w-[381px] shadow-[0_4px_10px_0px_rgba(103,103,103,.3)]">
:max-height="tableContentY" <div class="mt-[6px] flex cursor-pointer" @click="handleEditPersonalApp(item.baseInfo.agentId)">
:scroll-x="1330" <div class="mr-[22px] text-[14px]">
> <n-popover trigger="hover">
<template #empty> <template #trigger>
<div :style="{ height: tableContentY + 'px' }" class="flex items-center justify-center"> <div class="h-[23px] w-[205px] cursor-pointer truncate font-medium text-[#333333]">
{{ item.baseInfo.agentTitle || '--' }}
</div>
</template>
<span>{{ item.baseInfo.agentTitle || '--' }}</span>
</n-popover>
<div class="my-[18px] h-[44px] w-[196px] text-[#999999]">
<n-ellipsis :line-clamp="2">
{{ item.baseInfo.agentDesc }}
</n-ellipsis>
</div>
<n-button
:color="item.baseInfo.agentPublishStatus === 'draft' ? '#CCCCCC' : '#000DFF'"
class="h-[27px] w-[71px] rounded-[13px] border-[1px] text-[13px]"
ghost
round
>
{{
item.baseInfo.agentPublishStatus === 'draft'
? t('common_module.unpublished')
: t('common_module.published')
}}</n-button
>
</div>
<div><img :src="item.baseInfo.agentAvatar" width="101" height="99" /></div>
</div>
<template #footer>
<div class="flex h-[25px] justify-between">
<div class="line-height-[25px] text-[14px] text-[#999999]">
{{ t('personal_space_module.agent_module.agent_list_module.modified_time') }}
{{ formatDateTime(item.modifiedTime) }}
</div>
<div class="flex">
<Star
v-show="item.baseInfo.agentPublishStatus !== 'draft'"
theme="two-tone"
size="24"
:fill="item.isCollect === 'Y' ? ['#ffc06d', '#ffc06d'] : ['#333', '#fff']"
:stroke-width="2"
class="cursor-pointer transition-all delay-150 duration-300 ease-in-out"
@click="handleApplicationsCollect(item)"
/>
<n-popover
placement="bottom-end"
trigger="hover"
:show-arrow="false"
class="rounded-[10px]! px-[12px]! cursor-pointer"
>
<template #trigger>
<More
theme="outline"
size="24"
fill="#333"
:stroke-width="2"
class="ml-[12px] cursor-pointer"
/>
</template>
<div
v-show="item.baseInfo.agentPublishStatus !== 'draft'"
class="mb-[10px] w-full rounded-[5px] py-[4px] pl-[5px] text-[14px] text-[#333333] hover:bg-[#f1f1f1]"
@click="handleAnalysisPersonalApp(item)"
>
{{ t('common_module.data_table_module.analysis') }}
</div>
<div v-show="item.baseInfo.agentPublishStatus !== 'draft'">
<div v-show="item.isSale === 'Y'">
<n-popconfirm
:show-icon="false"
class="w-[170px]"
:positive-text="t('common_module.confirm_btn_text')"
:negative-text="t('common_module.cancel_btn_text')"
@positive-click="handleChangeApplicationsSaleStatus(item)"
>
<template #trigger>
<div
class="mb-[10px] w-full rounded-[5px] py-[4px] pl-[5px] text-[14px] text-[#333333] hover:bg-[#f1f1f1]"
>
{{ t('common_module.data_table_module.remove_applications') }}
</div>
</template>
{{
t('personal_space_module.agent_module.agent_list_module.remove_applications_dialog_title')
}}
</n-popconfirm>
</div>
<div v-show="item.isSale === 'N'">
<div
class="mb-[10px] w-full rounded-[5px] py-[4px] pl-[5px] text-[14px] text-[#333333] hover:bg-[#f1f1f1]"
@click="handleChangeApplicationsSaleStatus(item)"
>
{{ t('common_module.data_table_module.listing_applications') }}
</div>
</div>
</div>
<div
class="w-[96px] rounded-[5px] py-[4px] pl-[8px] text-[14px] text-[#F25744] hover:bg-[#f1f1f1]"
@click="handleDeletePersonalApp(item.baseInfo.agentId)"
>
{{ t('common_module.delete') }}
</div>
</n-popover>
</div>
</div>
</template>
</n-card>
</div>
<div v-for="item in 4" v-show="agentAppListBottomLoadingMore" :key="item" class="w-[380px]">
<n-skeleton text :repeat="12" />
</div>
</div>
<div v-else>
<div class="flex h-[650px] w-[full] items-center justify-center">
<div class="flex flex-col items-center justify-center"> <div class="flex flex-col items-center justify-center">
<img src="@/assets/images/empty.png" alt="empty" class="mb-2 h-[160px] w-[230px]" /> <img :src="emptyTableImage" alt="empty" class="mb-[20px] h-[68px] w-[68px]" />
<p class="text-base text-[#84868c]">{{ emptyTableText }}</p> <p class="mb-[14px] text-[14px] text-[#999999]">
{{ emptyTableText }}
</p>
<NButton
v-show="emptyTableText === t('personal_space_module.agent_module.agent_list_module.application_empty')"
type="primary"
:bordered="false"
:focusable="false"
@click="handleSelectAddType"
>
<span class="text-center text-[14px]">{{ t('common_module.create_agent_btn_text') }}</span>
</NButton>
</div> </div>
</div> </div>
</template> </div>
</NDataTable> </div>
<div
v-show="pagingInfo.pageNo === pagingInfo.totalPages && agentAppList.length !== 0"
class="mb-[50px] mt-[30px] flex justify-center text-center text-[14px] text-[#a9b4cc]"
>
<div class="relative top-[10px] h-[1px] w-[14px] bg-[#a9b4cc]"></div>
<div class="mb-[8px] w-[80px]">
{{ t('personal_space_module.agent_module.agent_list_module.already_bottom') }}
</div>
<div class="relative top-[10px] h-[1px] w-[14px] bg-[#a9b4cc]"></div>
</div>
</div> </div>
<SaleApplicationsConfigurationModal
<footer v-show="isLoadingPagination" class="flex justify-end"> v-model="isShowSaleApplicationsConfigurationModal"
<CustomPagination :data="saleApplicationsInfo"
:paging-info="pagingInfo" @update="(newValue: string) => (saleApplicationsInfo.isSale = newValue)"
@update-page-no="handleGetApplicationListUpdatePageNo" />
@update-page-size="handleGetApplicationListUpdatePageSize"
/>
</footer>
</div> </div>
</template> </template>
<script setup lang="ts">
import { fetchSalePublishApplication } from '@/apis/agent-application'
import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import { Close, Help, Notes, CheckSmall } from '@icon-park/vue-next'
import { ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
const isShowSaleApplicationsConfigurationModal = defineModel<boolean>()
const props = defineProps<{
data: PersonalAppConfigState
}>()
const emit = defineEmits<{
update: [value: string]
}>()
const { t } = useI18n()
const checkedClassifyValue = ref('')
const isCopy = ref('N')
const saleApplicationsId = ref(props.data.agentPublishId)
const isClassifyError = ref(false)
const applicationsClassify = [
{
value: 'mediaEntertainment',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.media_entertainment',
),
},
{
value: 'educationTraining',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.education_training',
),
},
{
value: 'businessServices',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.business_services',
),
},
{
value: 'medicalHealth',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.medical_health',
),
},
{
value: 'efficiencyTools',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.efficiency_tools',
),
},
{
value: 'officePersonnel',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.office_personnel',
),
},
{
value: 'marketingCommerce',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.marketing_commerce',
),
},
{
value: 'finance',
label: t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.finance'),
},
{
value: 'law',
label: t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.law'),
},
{
value: 'cultureTourism',
label: t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classify.culture_tourism',
),
},
]
watch(
() => checkedClassifyValue.value,
() => {
if (checkedClassifyValue.value !== '') isClassifyError.value = false
},
)
watch(
() => props.data,
(newVal) => {
saleApplicationsId.value = newVal.agentPublishId
},
)
function handleApplicationsSaleSettingModalClose() {
isShowSaleApplicationsConfigurationModal.value = false
checkedClassifyValue.value = ''
}
function handleApplicationReleaseBtn() {
if (!checkedClassifyValue.value) {
isClassifyError.value = true
return
}
const payload = {
agentPublishId: saleApplicationsId.value,
agentType: checkedClassifyValue.value,
isCopy: isCopy.value,
isSale: 'Y',
}
fetchSalePublishApplication(payload)
.then(() => {
emit('update', 'Y')
handleApplicationsSaleSettingModalClose()
window.$message.success(t('common_module.listing_successfully'))
isClassifyError.value = false
})
.catch(() => {
window.$message.success(t('common_module.listing_failed'))
})
}
function handleIsCopySwitchUpdateValue(value: string) {
isCopy.value = value
}
</script>
<template>
<n-modal v-model:show="isShowSaleApplicationsConfigurationModal" class="h-auto max-h-[720px]" :mask-closable="false">
<div class="flex flex-col items-center justify-center">
<div class="max-h-[720px] w-[720px] rounded-lg bg-white p-[24px]">
<div class="mb-[24px] flex items-center justify-between text-[20px] font-medium">
<div class="flex items-center">
<span class=" ">{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_square_release_setting',
)
}}</span>
<Notes theme="outline" size="17" fill="#333" class="ml-[8px]" />
</div>
<Close
theme="outline"
size="12"
fill="#00000073"
class="cursor-pointer"
@click="handleApplicationsSaleSettingModalClose"
/>
</div>
<div class="items-center justify-center rounded-[4px]">
<div class="mb-[16px] flex items-center text-[14px] text-[#151B26]">
<div class="bg-theme-color mr-[8px] h-[20px] w-[20px] rounded-2xl text-center text-[#fff]">1</div>
<div class="text-[16px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classification',
)
}}
</div>
<div class="text-[#f33e3e]">*</div>
</div>
<div class="flex flex-wrap justify-between">
<button
v-for="classify in applicationsClassify"
:key="classify.value"
:class="['classify-radio-button', { active: checkedClassifyValue === classify.value }]"
class="relative mb-[8px] mr-[4px] h-[26px] cursor-pointer rounded-[6px] border-[1px] border-[#edeef7] bg-[#edeef7] px-[8px] text-[12px]"
@click="checkedClassifyValue = classify.value"
>
<div
v-show="checkedClassifyValue === classify.value"
class="bg-theme-color absolute left-0 top-[-1px] h-[14px] w-[14px] rounded-[3px]"
style="clip-path: polygon(0 0, 100% 0, 0 100%)"
>
<CheckSmall theme="outline" size="10" fill="#fff" />
</div>
{{ classify.label }}
</button>
</div>
<div class="mb-[10px] h-[16px] text-red-500">
<div v-show="isClassifyError">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_sale_module.application_classification_null',
)
}}
</div>
</div>
<div class="mb-[12px] flex items-center">
<div class="bg-theme-color mr-[8px] h-[20px] w-[20px] rounded-2xl text-center text-[#fff]">2</div>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.is_copy') }}
<n-popover trigger="hover">
<template #trigger>
<Help theme="outline" size="16" fill="#333" class="ml-[5px] cursor-pointer" />
</template>
<div class="w-[250px]">
{{ t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.copy_tip') }}
</div>
</n-popover>
</div>
<n-switch size="small" checked-value="Y" unchecked-value="N" @update:value="handleIsCopySwitchUpdateValue"
><template #checked
>{{ t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.yes') }}
</template>
<template #unchecked>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.no') }}
</template></n-switch
>
</div>
<div class="">
<div class="flex max-h-[490px] justify-center overflow-y-hidden bg-[#f3f4fb]"></div>
<div class="mt-[24px] flex justify-end">
<button
class="hover:text-theme-color hover:border-theme-color !mr-[12px] box-content !h-[38px] !w-[74px] cursor-pointer rounded-[6px] border-[1px] border-solid border-[#dde3f0] px-[10px] outline-none transition-all duration-300 hover:border-[theme-color]"
@click="handleApplicationsSaleSettingModalClose"
>
{{ t('common_module.cancel') }}
</button>
<button
class="bg-theme-color !box-content !h-[38px] !w-[74px] cursor-pointer rounded-[6px] border-[1px] border-solid border-[#dde3f0] bg-[te] px-[10px] text-[#ffffff] transition-all duration-300 hover:bg-[#528EFF]"
@click="handleApplicationReleaseBtn()"
>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_sale_module.confirm_release') }}
</button>
</div>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="scss" scoped>
.classify-radio-button {
&.active {
background-color: #eef3fe;
border: 1px solid #000dff;
}
&:focus {
outline: none;
}
}
</style>
...@@ -53,6 +53,15 @@ declare namespace I18n { ...@@ -53,6 +53,15 @@ declare namespace I18n {
deletion_failed_please_try_again: string deletion_failed_please_try_again: string
select_all: string select_all: string
quit: string quit: string
all: string
collect: string
listing_successfully: string
listing_failed: string
removal_successfully: string
removal_failed: string
collect_successfully: string
collect_unsubscribed: string
cancel: string
dialogue_module: { dialogue_module: {
continue_question_message: string continue_question_message: string
...@@ -70,6 +79,9 @@ declare namespace I18n { ...@@ -70,6 +79,9 @@ declare namespace I18n {
copy: string copy: string
delete: string delete: string
view: string view: string
analysis: string
listing_applications: string
remove_applications: string
} }
pagination_module: { pagination_module: {
...@@ -78,6 +90,9 @@ declare namespace I18n { ...@@ -78,6 +90,9 @@ declare namespace I18n {
page_unit: string page_unit: string
total: string total: string
goto: string goto: string
remove_applications_dialog_title: string
already_bottom: string
application_empty: string
} }
} }
...@@ -240,6 +255,30 @@ declare namespace I18n { ...@@ -240,6 +255,30 @@ declare namespace I18n {
} }
} }
agent_sale_module: {
application_square_release_setting: string
application_classification: string
application_classification_null: string
application_classify: {
media_entertainment: string
education_training: string
business_services: string
medical_health: string
efficiency_tools: string
office_personnel: string
marketing_commerce: string
finance: string
law: string
culture_tourism: string
}
is_copy: string
yes: string
no: string
confirm_release: string
copy_tip: string
}
knowledge_module: { knowledge_module: {
search_knowledge_placeholder: string search_knowledge_placeholder: string
knowledge_name: string knowledge_name: string
......
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