New file |
| | |
| | | <template> |
| | | <!-- <a-button type="primary" @click="handleClick" style="margin-left: 10px">--> |
| | | <!-- <template #icon>--> |
| | | <!-- <icon-plus />--> |
| | | <!-- </template>--> |
| | | <!-- </a-button>--> |
| | | <a-modal |
| | | v-model:visible="visible" |
| | | title="创建智能体" |
| | | @before-open="handleOpened" |
| | | @cancel="handleCancel" |
| | | :footer="false" |
| | | title-align="start" |
| | | width="600px" |
| | | > |
| | | <a-form |
| | | ref="formRef" |
| | | :rules="rules" |
| | | :model="form" |
| | | @submit="handleSubmit" |
| | | :style="{ width: '90%', margin: '0 auto' }" |
| | | layout="vertical" |
| | | > |
| | | <a-form-item field="name" label="智能体名称"> |
| | | <a-input v-model="form.name" placeholder="请输入名称" /> |
| | | </a-form-item> |
| | | <a-form-item label="你希望智能体的角色是什么,具体完成什么任务?"> |
| | | <a-textarea |
| | | v-model="form.prompt_config.system" |
| | | placeholder="" |
| | | style="height: 180px" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item> |
| | | <div style="width: 100%; text-align: right"> |
| | | <a-button @click="visible = false">取消</a-button> |
| | | <a-button style="margin-left: 10px" type="primary" html-type="submit" |
| | | >确定</a-button |
| | | > |
| | | <editAgent |
| | | ref="editAgentKuai" |
| | | typeAngint="add" |
| | | :formData="form" |
| | | @cancelModal="handleCancel" |
| | | ></editAgent> |
| | | </div> |
| | | </a-form-item> |
| | | </a-form> |
| | | </a-modal> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { onMounted, onBeforeMount, reactive, ref } from 'vue'; |
| | | import editAgent from '@/views/dmx/IntelligentAgent/components/editAgent.vue'; |
| | | |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const editAgentKuai = ref(); |
| | | const form = reactive({ |
| | | name: '', |
| | | icon: '', |
| | | language: 'English', |
| | | prompt_config: { |
| | | empty_response: '', |
| | | prologue: '你好! 我是你的助理,有什么可以帮到你的吗?', |
| | | quote: true, |
| | | self_rag: true, |
| | | system: |
| | | '示例:\n' + |
| | | '你是 XX,具有 XX 经验,擅长 XX,…\n' + |
| | | '你的任务是 XX ,需要按照以下步骤执行:\n' + |
| | | '1. XX\n' + |
| | | '2. XX\n' + |
| | | '3. …\n', |
| | | parameters: [ |
| | | { |
| | | key: 'knowledge', |
| | | optional: false, |
| | | }, |
| | | ], |
| | | }, |
| | | kb_ids: [], |
| | | llm_id: 'qwen-plus', |
| | | llm_setting: { |
| | | temperature: 0.1, |
| | | top_p: 0.3, |
| | | presence_penalty: 0.4, |
| | | frequency_penalty: 0.7, |
| | | max_tokens: 512, |
| | | }, |
| | | similarity_threshold: 0.2, |
| | | vector_similarity_weight: 0.30000000000000004, |
| | | top_n: 8, |
| | | }); |
| | | const formRef = ref(null); |
| | | |
| | | const rules = { |
| | | name: [ |
| | | { |
| | | required: true, |
| | | message: '名称不允许为空', |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | const handleSubmit = ({ values, errors }) => { |
| | | console.log('values:', values, '\nerrors:', errors); |
| | | if (!errors) { |
| | | editAgentKuai.value.handleClick(form); |
| | | } |
| | | }; |
| | | |
| | | const handleClick = () => { |
| | | visible.value = true; |
| | | }; |
| | | defineExpose({ |
| | | handleClick, |
| | | }); |
| | | |
| | | const handleCancel = () => { |
| | | visible.value = false; |
| | | formRef.value.resetFields(); |
| | | form.name = ''; |
| | | }; |
| | | |
| | | const handleOpened = (el) => { |
| | | // Object.assign(form,{ |
| | | // name: '',// 用户名 |
| | | // nameJoin: '',// 昵称 |
| | | // post: '',// 岗位 |
| | | // txt: '',// 备注 |
| | | // }); |
| | | formRef.value.resetFields(); |
| | | form.name = ''; |
| | | form.prompt_config.system = |
| | | '示例:\n' + |
| | | '你是 XX,具有 XX 经验,擅长 XX,…\n' + |
| | | '你的任务是 XX ,需要按照以下步骤执行:\n' + |
| | | '1. XX\n' + |
| | | '2. XX\n' + |
| | | '3. …\n'+ |
| | | '{knowledge}'; |
| | | }; |
| | | |
| | | const file = ref(); |
| | | |
| | | onBeforeMount(() => {}); |
| | | onMounted(() => {}); |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="card-wrap"> |
| | | <a-card v-if="loading" :bordered="false" hoverable> |
| | | <slot name="skeleton"></slot> |
| | | </a-card> |
| | | <a-card v-else :bordered="false" hoverable> |
| | | <a-space align="start"> |
| | | <a-avatar |
| | | v-if="icon" |
| | | :size="24" |
| | | style="margin-right: 8px; background-color: #626aea" |
| | | > |
| | | <icon-filter /> |
| | | </a-avatar> |
| | | <a-card-meta> |
| | | <template #title> |
| | | <a-typography-text style="margin-right: 10px"> |
| | | {{ title }} |
| | | </a-typography-text> |
| | | <template v-if="showTag"> |
| | | <a-tag |
| | | v-if="open && isExpires === false" |
| | | size="small" |
| | | color="green" |
| | | > |
| | | <template #icon> |
| | | <icon-check-circle-fill /> |
| | | </template> |
| | | <span>{{ tagText }}</span> |
| | | </a-tag> |
| | | <a-tag v-else-if="isExpires" size="small" color="red"> |
| | | <template #icon> |
| | | <icon-check-circle-fill /> |
| | | </template> |
| | | <span>{{ expiresTagText }}</span> |
| | | </a-tag> |
| | | </template> |
| | | </template> |
| | | <template #description> |
| | | {{ description }} |
| | | <slot></slot> |
| | | </template> |
| | | </a-card-meta> |
| | | </a-space> |
| | | <template #actions> |
| | | <a-switch v-if="actionType === 'switch'" v-model="open" /> |
| | | <a-space v-else-if="actionType === 'button'"> |
| | | <template v-if="isExpires"> |
| | | <a-button type="outline" @click="renew"> |
| | | {{ expiresText }} |
| | | </a-button> |
| | | </template> |
| | | <template v-else> |
| | | <a-button v-if="open" @click="handleToggle"> |
| | | {{ closeTxt }} |
| | | </a-button> |
| | | <a-button v-else-if="!open" type="outline" @click="handleToggle"> |
| | | {{ openTxt }} |
| | | </a-button> |
| | | </template> |
| | | </a-space> |
| | | <div v-else> |
| | | <a-space> |
| | | <a-button @click="toggle(false)"> |
| | | {{ closeTxt }} |
| | | </a-button> |
| | | <a-button type="primary" @click="toggle(true)"> |
| | | {{ openTxt }} |
| | | </a-button> |
| | | </a-space> |
| | | </div> |
| | | </template> |
| | | </a-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref } from 'vue'; |
| | | import { useToggle } from '@vueuse/core'; |
| | | |
| | | const props = defineProps({ |
| | | loading: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | title: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | description: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | actionType: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | defaultValue: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | openTxt: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | closeTxt: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | expiresText: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | icon: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | showTag: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | tagText: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | expires: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | expiresTagText: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | }); |
| | | const [open, toggle] = useToggle(props.defaultValue); |
| | | const handleToggle = () => { |
| | | toggle(); |
| | | }; |
| | | const isExpires = ref(props.expires); |
| | | const renew = () => { |
| | | isExpires.value = false; |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .card-wrap { |
| | | height: 100%; |
| | | transition: all 0.3s; |
| | | border: 1px solid var(--color-neutral-3); |
| | | border-radius: 4px; |
| | | &:hover { |
| | | transform: translateY(-4px); |
| | | // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); |
| | | } |
| | | :deep(.arco-card) { |
| | | height: 100%; |
| | | border-radius: 4px; |
| | | .arco-card-body { |
| | | height: 100%; |
| | | .arco-space { |
| | | width: 100%; |
| | | height: 100%; |
| | | .arco-space-item { |
| | | height: 100%; |
| | | &:last-child { |
| | | flex: 1; |
| | | } |
| | | .arco-card-meta { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-flow: column; |
| | | .arco-card-meta-content { |
| | | flex: 1; |
| | | .arco-card-meta-description { |
| | | margin-top: 8px; |
| | | color: rgb(var(--gray-6)); |
| | | line-height: 20px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | .arco-card-meta-footer { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | :deep(.arco-card-meta-title) { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | // To prevent the shaking |
| | | line-height: 28px; |
| | | } |
| | | :deep(.arco-skeleton-line) { |
| | | &:last-child { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="list-wrap"> |
| | | <a-typography-title class="block-title" :heading="6"> |
| | | {{ $t('cardList.tab.title.content') }} |
| | | </a-typography-title> |
| | | <a-button class="add-button" type="primary" @click="addCard">添加</a-button> |
| | | |
| | | <a-row class="list-row" :gutter="24"> |
| | | <a-col |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | class="list-col" |
| | | > |
| | | <div class="card-wrap empty-wrap"> |
| | | <a-card :bordered="false" hoverable> |
| | | <a-result :status="null" title="Xinference模型是个很厉害的模型"> |
| | | <template #icon> |
| | | <icon-plus style="font-size: 20px" /> |
| | | </template> |
| | | </a-result> |
| | | </a-card> |
| | | </div> |
| | | </a-col> |
| | | <a-col |
| | | v-for="item in renderData" |
| | | :key="item.id" |
| | | class="list-col" |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | > |
| | | <CardWrap |
| | | :loading="loading" |
| | | :title="item.title" |
| | | :description="item.description" |
| | | :default-value="item.enable" |
| | | :action-type="item.actionType" |
| | | :icon="item.icon" |
| | | :open-txt="$t('cardList.content.inspection')" |
| | | :close-txt="$t('cardList.content.delete')" |
| | | :show-tag="false" |
| | | > |
| | | <a-descriptions |
| | | style="margin-top: 16px" |
| | | :data="item.data" |
| | | layout="inline-horizontal" |
| | | :column="2" |
| | | /> |
| | | <template #skeleton> |
| | | <a-skeleton :animation="true"> |
| | | <a-skeleton-line |
| | | :widths="['50%', '50%', '100%', '40%']" |
| | | :rows="4" |
| | | /> |
| | | <a-skeleton-line :widths="['40%']" :rows="1" /> |
| | | </a-skeleton> |
| | | </template> |
| | | </CardWrap> |
| | | </a-col> |
| | | </a-row> |
| | | |
| | | <a-modal v-model:visible="visible" @Ok="handleOk" @cancel="handleCancel"> |
| | | <template #title> 添加LLM </template> |
| | | <a-form |
| | | ref="formRef" |
| | | :size="form.size" |
| | | :model="form" |
| | | auto-label-width |
| | | @submit="handleSubmit" |
| | | > |
| | | <a-form-item |
| | | field="type" |
| | | label="模型类型" |
| | | :rules="[{ required: true, message: '不能为空' }]" |
| | | :validate-trigger="['change', 'input']" |
| | | > |
| | | <a-select |
| | | v-model="form.type" |
| | | placeholder="请选择模型类型" |
| | | allow-clear |
| | | > |
| | | <a-option>chartGpt 4</a-option> |
| | | <a-option>chartGpt o</a-option> |
| | | <a-option>LLM</a-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | |
| | | <a-form-item |
| | | field="UID" |
| | | label="模型UID" |
| | | :rules="[ |
| | | { required: true, message: '不能为空' }, |
| | | { minLength: 1, message: '至少一个字符' }, |
| | | ]" |
| | | :validate-trigger="['change', 'input']" |
| | | > |
| | | <a-input v-model="form.UID" placeholder="请输入模型UID" /> |
| | | </a-form-item> |
| | | |
| | | <a-form-item |
| | | field="Url" |
| | | label="基础Url" |
| | | :rules="[ |
| | | { required: true, message: '不能为空' }, |
| | | { minLength: 1, message: '至少一个字符' }, |
| | | ]" |
| | | :validate-trigger="['change', 'input']" |
| | | > |
| | | <a-input v-model="form.Url" placeholder="请输入基础Url" /> |
| | | </a-form-item> |
| | | |
| | | <a-form-item |
| | | field="vision" |
| | | label="是否支持 vision" |
| | | :validate-trigger="['change', 'input']" |
| | | > |
| | | <a-switch v-model="form.vision" /> |
| | | </a-form-item> |
| | | </a-form> |
| | | </a-modal> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { nextTick, reactive, ref } from 'vue'; |
| | | import { queryInspectionList, ServiceRecord } from '@/api/list'; |
| | | import useRequest from '@/hooks/request'; |
| | | import CardWrap from './card-wrap.vue'; |
| | | |
| | | const defaultValue: ServiceRecord[] = new Array(3).fill({}); |
| | | const { loading, response: renderData } = useRequest<ServiceRecord[]>( |
| | | queryInspectionList, |
| | | defaultValue |
| | | ); |
| | | const visible = ref(false); |
| | | const addCard = () => { |
| | | visible.value = true; |
| | | }; |
| | | |
| | | const formRef = ref(null); |
| | | const form = reactive({ |
| | | size: 'medium', |
| | | type: '', |
| | | UID: '', |
| | | Url: '', |
| | | vision: false, |
| | | }); |
| | | const handleOk = () => { |
| | | formRef.value.validate().then((res) => { |
| | | if (res) { |
| | | return; |
| | | } |
| | | renderData.value = renderData.value.concat({ |
| | | id: renderData.value.length + 1, |
| | | title: form.type, |
| | | description: form.Url, |
| | | icon: 'icon-setting', |
| | | actionType: 'inspection', |
| | | enable: true, |
| | | data: [ |
| | | { |
| | | label: '待质检数', |
| | | value: '120', |
| | | }, |
| | | { |
| | | label: '积压时长', |
| | | value: '60s', |
| | | }, |
| | | { |
| | | label: '待抽检数', |
| | | value: '0', |
| | | }, |
| | | ], |
| | | }); |
| | | visible.value = false; |
| | | }); |
| | | nextTick(() => { |
| | | visible.value = true; |
| | | }); |
| | | return false; |
| | | }; |
| | | const handleCancel = () => { |
| | | formRef.value.resetFields(); |
| | | visible.value = false; |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .card-wrap { |
| | | height: 100%; |
| | | transition: all 0.3s; |
| | | border: 1px solid var(--color-neutral-3); |
| | | &:hover { |
| | | transform: translateY(-4px); |
| | | } |
| | | :deep(.arco-card-meta-description) { |
| | | color: rgb(var(--gray-6)); |
| | | .arco-descriptions-item-label-inline { |
| | | font-weight: normal; |
| | | font-size: 12px; |
| | | color: rgb(var(--gray-6)); |
| | | } |
| | | .arco-descriptions-item-value-inline { |
| | | color: rgb(var(--gray-8)); |
| | | } |
| | | } |
| | | } |
| | | .empty-wrap { |
| | | height: 200px; |
| | | border-radius: 4px; |
| | | :deep(.arco-card) { |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 4px; |
| | | .arco-result-title { |
| | | color: rgb(var(--gray-6)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .list-wrap { |
| | | position: relative; |
| | | |
| | | ::v-deep .block-title { |
| | | height: 36px; |
| | | lin-height: 36px; |
| | | } |
| | | |
| | | .add-button { |
| | | position: absolute; |
| | | right: 20px; |
| | | top: 0; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <a-button |
| | | v-if="typeAngint == 'edit'" |
| | | type="text" |
| | | size="small" |
| | | @click="editClick" |
| | | > |
| | | <template #icon> |
| | | <icon-tool /> |
| | | </template> |
| | | </a-button> |
| | | <!-- <a-button v-if="typeAngint=='add'" style="margin-left: 10px" type="primary" @click="handleClick">确定</a-button>--> |
| | | <a-modal |
| | | v-model:visible="visible" |
| | | title="" |
| | | @before-open="handleOpened" |
| | | @cancel="handleCancel" |
| | | :footer="false" |
| | | title-align="start" |
| | | fullscreen |
| | | > |
| | | <div class="main-container"> |
| | | <div class="main-container-lf"> |
| | | <div style="padding: 10px;font-size: 16px;background: var(--color-neutral-3);">智能体配置</div> |
| | | <div style="display: flex;width: 100%;" :style="{height:height}"> |
| | | <div style="width: 50%;height: 100%"> |
| | | <div style="padding: 10px;font-size: 12px;color: #2a2a2b;">智能体画像</div> |
| | | <div> |
| | | <a-textarea v-model="system" placeholder="" disabled style="height: 400px;" /> |
| | | </div> |
| | | |
| | | </div> |
| | | <div style="width: 50%;border: 1px solid var(--color-neutral-3);background: var(--color-neutral-3)"> |
| | | <a-form ref="formRef" :rules="rules" :model="form" @submit="handleSubmit" layout="vertical" > |
| | | <a-collapse :default-active-key="['1']"> |
| | | <a-collapse-item header="基础信息" key="0" v-if="typeAngint == 'edit'"> |
| | | <a-input v-model="form.name" placeholder="请输入智能体名称" style="width:200px;margin-top: 10px" /> |
| | | </a-collapse-item> |
| | | <a-collapse-item header="AI模型配置" key="1"> |
| | | <a-form-item field="llm_id" label="模型"> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-select :size="'large'" field="llm_id" v-model="form.llm_id" :style="{width:'25rem'}" placeholder="请选择 ..."> |
| | | <a-optgroup |
| | | :label="index" |
| | | v-for="(item, index) in modelList" |
| | | :key="index" |
| | | > |
| | | <a-option |
| | | v-for="obj in item" |
| | | :key="obj.fid" |
| | | :disabled="!obj.available" |
| | | :value="obj.llm_id" |
| | | > |
| | | {{ obj.llm_name }} |
| | | </a-option> |
| | | </a-optgroup> |
| | | </a-select> |
| | | </a-space> |
| | | </a-form-item> |
| | | </a-collapse-item> |
| | | <a-collapse-item header="开场引导" :key="'2'" disabled> |
| | | </a-collapse-item> |
| | | <a-collapse-item header="知识库" key="3"> |
| | | <a-form-item field="kb_ids" label="知识库"> |
| | | <a-select |
| | | v-model="form.kb_ids" |
| | | :style="{ width: '25rem' }" |
| | | placeholder="请选择 ..." |
| | | multiple |
| | | > |
| | | <a-option |
| | | v-for="item in tabs" |
| | | :key="item.id" |
| | | :value="item.id" |
| | | >{{ item.name }}</a-option |
| | | > |
| | | </a-select> |
| | | </a-form-item> |
| | | </a-collapse-item> |
| | | <a-collapse-item header="工具" key="4" disabled> |
| | | </a-collapse-item> |
| | | <a-collapse-item header="工作流" key="5" disabled> |
| | | </a-collapse-item> |
| | | </a-collapse> |
| | | |
| | | <a-form-item> |
| | | <div |
| | | style=" |
| | | position: absolute; |
| | | right: 10px; |
| | | top: 0px; |
| | | z-index: 99999; |
| | | " |
| | | > |
| | | <!-- <a-button @click="visible = false">取消</a-button>--> |
| | | <a-button |
| | | style="margin-left: 10px" |
| | | type="primary" |
| | | html-type="submit" |
| | | >保存</a-button |
| | | > |
| | | </div> |
| | | </a-form-item> |
| | | </a-form> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="main-container-rt"> |
| | | <sessionAction></sessionAction> |
| | | </div> |
| | | </div> |
| | | </a-modal> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { onMounted, onBeforeMount, reactive, ref, nextTick } from 'vue'; |
| | | import { IconSend } from '@arco-design/web-vue/es/icon'; |
| | | import { queryKbList, queryModelList } from '@/api/kbList'; |
| | | import useLoading from '@/hooks/loading'; |
| | | import { dialogSet } from '@/api/Agent'; |
| | | import { Message } from '@arco-design/web-vue'; |
| | | import EventBus from "@/utils/EventBus"; |
| | | import sessionAction from "@/views/dmx/IntelligentAgent/components/sessionAction.vue"; |
| | | const { setLoading } = useLoading(true); |
| | | const props = defineProps(['typeAngint', 'formData']); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | const form = reactive({ |
| | | name: '', |
| | | icon: '', |
| | | language: 'English', |
| | | prompt_config: { |
| | | empty_response: '', |
| | | prologue: '你好! 我是你的助理,有什么可以帮到你的吗?', |
| | | quote: true, |
| | | self_rag: true, |
| | | system: |
| | | '示例:\n' + |
| | | '你是 XX,具有 XX 经验,擅长 XX,…\n' + |
| | | '你的任务是 XX ,需要按照以下步骤执行:\n' + |
| | | '1. XX\n' + |
| | | '2. XX\n' + |
| | | '3. …\n' + |
| | | '{knowlege}', |
| | | parameters: [ |
| | | { |
| | | key: 'knowledge', |
| | | optional: false, |
| | | }, |
| | | ], |
| | | }, |
| | | kb_ids: [], |
| | | llm_id: 'qwen-plus', |
| | | llm_setting: { |
| | | temperature: 0.1, |
| | | top_p: 0.3, |
| | | presence_penalty: 0.4, |
| | | frequency_penalty: 0.7, |
| | | max_tokens: 512, |
| | | }, |
| | | similarity_threshold: 0.2, |
| | | vector_similarity_weight: 0.30000000000000004, |
| | | top_n: 8, |
| | | }); |
| | | const system = ref(''); |
| | | const embdId = ref(''); |
| | | const modelList = ref({}); |
| | | const renderData = ref([]); |
| | | const formRef = ref(null); |
| | | let tabs = ref([]); |
| | | const height = ref('calc(100vh - 150px)'); |
| | | const emit = defineEmits(['cancelModal']); |
| | | const rules = { |
| | | name: [ |
| | | { |
| | | required: true, |
| | | message: '名称不允许为空', |
| | | }, |
| | | ], |
| | | llm_id: [ |
| | | { |
| | | required: true, |
| | | message: '模型不能为空', |
| | | }, |
| | | ], |
| | | kb_ids: [ |
| | | { |
| | | required: true, |
| | | message: '知识库不能为空', |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | const handleSubmit = async ({ values, errors }) => { |
| | | // console.log('values:', values, '\nerrors:', errors) |
| | | if(!errors){ |
| | | let title = '创建成功'; |
| | | let formNew = { ...form }; |
| | | if (props.typeAngint == 'edit') { |
| | | formNew.dialog_id = form.id; |
| | | delete formNew.id; |
| | | delete formNew.off; |
| | | title = '修改成功'; |
| | | } |
| | | const data = await dialogSet(formNew); |
| | | if (data.code == 0) { |
| | | Message.success(title); |
| | | handleCancel(); |
| | | EventBus.emit('queryList'); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const editClick = (data) => { |
| | | visible.value = true; |
| | | |
| | | console.log(props.formData); |
| | | Object.assign(form, props.formData); |
| | | console.log(form); |
| | | system.value = form.prompt_config.system; |
| | | }; |
| | | |
| | | const handleClick = (data) => { |
| | | visible.value = true; |
| | | nextTick(() => { |
| | | Object.assign(form, data); |
| | | console.log(form,'传值'); |
| | | system.value = form.prompt_config.system; |
| | | if(tabs.value && tabs.value.length>0){ |
| | | form.kb_ids = [tabs.value[0].id]; |
| | | } |
| | | }); |
| | | }; |
| | | defineExpose({ |
| | | handleClick, |
| | | }); |
| | | const handleBeforeOk = (done) => { |
| | | formRef.value.validate().then((res) => { |
| | | console.log('form:', form); |
| | | if (!form.name) { |
| | | done(false); |
| | | } else { |
| | | console.log('请求数据'); |
| | | } |
| | | }); |
| | | }; |
| | | const handleCancel = () => { |
| | | visible.value = false; |
| | | emit('cancelModal'); |
| | | }; |
| | | |
| | | const handleOpened = (el) => { |
| | | // formRef.value.resetFields(); |
| | | }; |
| | | const queryModel = async (params) => { |
| | | try { |
| | | const data = await queryModelList(params); |
| | | console.log(data.data, '大模型列表'); |
| | | modelList.value = data.data; |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | } |
| | | }; |
| | | const file = ref(); |
| | | |
| | | const onChange = (_, currentFile) => { |
| | | file.value = { |
| | | ...currentFile, |
| | | // url: URL.createObjectURL(currentFile.file), |
| | | }; |
| | | }; |
| | | const onProgress = (currentFile) => { |
| | | file.value = currentFile; |
| | | }; |
| | | |
| | | const knowledgeData = async (params = { page: 1, page_size: 20 }) => { |
| | | setLoading(true); |
| | | try { |
| | | const { data } = await queryKbList(params); |
| | | console.log(data, 'data'); |
| | | nextTick(() => { |
| | | tabs.value = data; |
| | | console.log(tabs.value, 'tabs'); |
| | | }); |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | onBeforeMount(() => { |
| | | queryModel({}); |
| | | knowledgeData(); |
| | | }); |
| | | onMounted(() => {}); |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .main-container { |
| | | width: 100%; |
| | | display: flex; |
| | | .main-container-lf { |
| | | width: 60%; |
| | | } |
| | | .main-container-rt { |
| | | position: relative; |
| | | width: 40%; |
| | | } |
| | | } |
| | | .bottom { |
| | | width: 100%; |
| | | position: absolute; |
| | | bottom: 40px; |
| | | left: 0; |
| | | .input { |
| | | margin-left: 20%; |
| | | width: 60%; |
| | | } |
| | | .text { |
| | | margin-left: 40%; |
| | | font-size: 12px; |
| | | color: lightgrey; |
| | | line-height: 40px; |
| | | } |
| | | } |
| | | :deep(.arco-textarea-wrapper.arco-textarea-disabled){ |
| | | background: var(--color-bg-2); |
| | | color: var(--color-text-1); |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="list-wrap"> |
| | | <a-typography-title class="block-title" :heading="6"> |
| | | {{ $t('cardList.tab.title.content') }} |
| | | </a-typography-title> |
| | | <a-row class="list-row" :gutter="24"> |
| | | <a-col |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | class="list-col" |
| | | > |
| | | <div class="card-wrap empty-wrap"> |
| | | <a-card :bordered="false" hoverable> |
| | | <a-result :status="null" :title="$t('cardList.content.action')"> |
| | | <template #icon> |
| | | <icon-plus style="font-size: 20px" /> |
| | | </template> |
| | | </a-result> |
| | | </a-card> |
| | | </div> |
| | | </a-col> |
| | | <a-col |
| | | v-for="item in renderData" |
| | | :key="item.id" |
| | | class="list-col" |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | > |
| | | <CardWrap |
| | | :loading="loading" |
| | | :title="item.title" |
| | | :description="item.description" |
| | | :default-value="item.enable" |
| | | :action-type="item.actionType" |
| | | :icon="item.icon" |
| | | :open-txt="$t('cardList.content.inspection')" |
| | | :close-txt="$t('cardList.content.delete')" |
| | | :show-tag="false" |
| | | > |
| | | <a-descriptions |
| | | style="margin-top: 16px" |
| | | :data="item.data" |
| | | layout="inline-horizontal" |
| | | :column="2" |
| | | /> |
| | | <template #skeleton> |
| | | <a-skeleton :animation="true"> |
| | | <a-skeleton-line |
| | | :widths="['50%', '50%', '100%', '40%']" |
| | | :rows="4" |
| | | /> |
| | | <a-skeleton-line :widths="['40%']" :rows="1" /> |
| | | </a-skeleton> |
| | | </template> |
| | | </CardWrap> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { queryInspectionList, ServiceRecord } from '@/api/list'; |
| | | import useRequest from '@/hooks/request'; |
| | | import CardWrap from './card-wrap.vue'; |
| | | |
| | | const defaultValue: ServiceRecord[] = new Array(3).fill({}); |
| | | const { loading, response: renderData } = useRequest<ServiceRecord[]>( |
| | | queryInspectionList, |
| | | defaultValue |
| | | ); |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .card-wrap { |
| | | height: 100%; |
| | | transition: all 0.3s; |
| | | border: 1px solid var(--color-neutral-3); |
| | | &:hover { |
| | | transform: translateY(-4px); |
| | | } |
| | | :deep(.arco-card-meta-description) { |
| | | color: rgb(var(--gray-6)); |
| | | .arco-descriptions-item-label-inline { |
| | | font-weight: normal; |
| | | font-size: 12px; |
| | | color: rgb(var(--gray-6)); |
| | | } |
| | | .arco-descriptions-item-value-inline { |
| | | color: rgb(var(--gray-8)); |
| | | } |
| | | } |
| | | } |
| | | .empty-wrap { |
| | | height: 200px; |
| | | border-radius: 4px; |
| | | :deep(.arco-card) { |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-radius: 4px; |
| | | .arco-result-title { |
| | | color: rgb(var(--gray-6)); |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="list-wrap"> |
| | | <a-typography-title class="block-title" :heading="6"> |
| | | {{ $t('cardList.tab.title.preset') }} |
| | | </a-typography-title> |
| | | <a-row class="list-row" :gutter="24"> |
| | | <a-col |
| | | v-for="item in renderData" |
| | | :key="item.id" |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | class="list-col" |
| | | style="min-height: 140px" |
| | | > |
| | | <CardWrap |
| | | :loading="loading" |
| | | :title="item.title" |
| | | :description="item.description" |
| | | :default-value="item.enable" |
| | | :action-type="item.actionType" |
| | | :tag-text="$t('cardList.preset.tag')" |
| | | > |
| | | <template #skeleton> |
| | | <a-skeleton :animation="true"> |
| | | <a-skeleton-line :widths="['100%', '40%']" :rows="2" /> |
| | | <a-skeleton-line :widths="['40%']" :rows="1" /> |
| | | </a-skeleton> |
| | | </template> |
| | | </CardWrap> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { queryRulesPresetList, ServiceRecord } from '@/api/list'; |
| | | import useRequest from '@/hooks/request'; |
| | | import CardWrap from './card-wrap.vue'; |
| | | |
| | | const defaultValue: ServiceRecord[] = new Array(6).fill({}); |
| | | const { loading, response: renderData } = useRequest<ServiceRecord[]>( |
| | | queryRulesPresetList, |
| | | defaultValue |
| | | ); |
| | | </script> |
| | | |
| | | <style scoped lang="less"></style> |
New file |
| | |
| | | <template> |
| | | <div :style="{ height: heightrg }"> |
| | | <div style="padding: 10px"> |
| | | <a-avatar :style="{ backgroundColor: '#3370ff' }"> |
| | | <img |
| | | :style="{ width: '100%' }" |
| | | alt="dessert" |
| | | src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" |
| | | /> |
| | | </a-avatar> |
| | | 调试预览 |
| | | </div> |
| | | <a-divider style="margin: 0; margin-left: 10px" /> |
| | | <a-scrollbar |
| | | ref="scrollbar" |
| | | id="home" |
| | | class="chat-list" |
| | | style="width: 90%; overflow: auto; height: 70vh; margin: 0px auto;" |
| | | > |
| | | <div class="chat-item" v-for="sessionDetail in sessionDetailList"> |
| | | <a-comment |
| | | v-if="sessionDetail.role === 'user'" |
| | | avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp" |
| | | > |
| | | <template #content> |
| | | <div :class="{ light: theme === 'light' }" style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none;padding: 16px;">{{ |
| | | sessionDetail.content |
| | | }}</div> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment |
| | | v-else-if="sessionDetail.role === 'assistant'" |
| | | avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp" |
| | | > |
| | | <template #content> |
| | | <a-card |
| | | class="chat-item-answer" |
| | | style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none" |
| | | > |
| | | <div :class="{ light: theme === 'light' }">{{ |
| | | sessionDetail.content |
| | | }}</div> |
| | | </a-card> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment |
| | | v-else-if="sessionDetail.role === 'last'" |
| | | avatar="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/9eeb1800d9b78349b24682c3518ac4a3.png~tplv-uwbnlip3yd-webp.webp" |
| | | > |
| | | <template #content> |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="displayedText" |
| | | class="chat-item-answer" |
| | | style="background-color: var(--color-bg-2);color: var(--color-text-3);border: none" |
| | | > |
| | | </a-textarea> |
| | | </template> |
| | | </a-comment> |
| | | </div> |
| | | </a-scrollbar> |
| | | <div class="bottom"> |
| | | <div class="input"> |
| | | <a-input |
| | | v-model="inputMsg" |
| | | @keydown.enter="sendMessage" |
| | | placeholder="输入您想了解的内容,按Enter发送" |
| | | > |
| | | <template #suffix> |
| | | <icon-send style="cursor: pointer" @click="sendMessage" /> |
| | | </template> </a-input |
| | | ></div> |
| | | <div class="text">内容由AI生成,仅供参考</div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | IconMoreVertical, |
| | | IconQuestionCircleFill, |
| | | IconPoweroff, |
| | | IconCommon, |
| | | IconSend, |
| | | } from '@arco-design/web-vue/es/icon'; |
| | | import img1 from '@/assets/images/u64.png'; |
| | | import img2 from '@/assets/images/u69.png'; |
| | | import img3 from '@/assets/images/u74.png'; |
| | | import { ref, onMounted, computed, reactive, nextTick, watch } from 'vue'; |
| | | import { useUserStore, useAppStore } from '@/store'; |
| | | import { |
| | | sessionListApi, |
| | | deleteSessionApi, |
| | | getSessionDetailsApi, |
| | | chatApi, |
| | | } from '@/api/session'; |
| | | import { Message } from '@arco-design/web-vue'; |
| | | const userStore = useUserStore(); |
| | | const appStore = useAppStore(); |
| | | const theme = computed(() => { |
| | | return appStore.theme; |
| | | }); |
| | | const heightrg = ref('calc(100vh - 100px)'); |
| | | const sessionList = ref([]); //会话列表 |
| | | const sessionDetailList = ref([]); //根据会话id出来的会话详情 |
| | | const activeSessionId = ref(''); |
| | | const inputMsg = ref(''); |
| | | const scrollbar = ref(null); |
| | | |
| | | const currIndex = ref(0); |
| | | const displayedText = ref(''); // 正在显示的文字 |
| | | let timer: number | null = null; |
| | | const streamStr = ref(''); |
| | | const modalObj = reactive({ add: false }); |
| | | //查询会话列表 |
| | | const querySessionList = async () => { |
| | | const { code, data } = await sessionListApi(); |
| | | if (code === 200) { |
| | | sessionList.value = data; |
| | | if (Array.isArray(data) && data.length > 0) { |
| | | activeSessionId.value = data[1].id; |
| | | const res = await getSessionDetailsApi(data[0].id); |
| | | if (res.code === 200) { |
| | | sessionDetailList.value = res.data.message; |
| | | refreshScroll(); |
| | | } |
| | | } |
| | | } else { |
| | | Message.warning('查询失败'); |
| | | } |
| | | }; |
| | | //根据会话id删除会话 |
| | | const deleteSession = async (session) => { |
| | | const { code } = await deleteSessionApi([session.id]); |
| | | if (code === 200) { |
| | | Message.success('删除成功'); |
| | | querySessionList(); |
| | | } |
| | | }; |
| | | // eslint-disable-next-line prettier/prettier |
| | | // 新增会话之后刷新会话列表 |
| | | const addSession = () => { |
| | | querySessionList(); |
| | | }; |
| | | // 初始化数据 |
| | | const initData = () => { |
| | | querySessionList(); |
| | | }; |
| | | // 获取登录信息 |
| | | const userName = computed(() => { |
| | | return userStore.name; |
| | | }); |
| | | const avatar = computed(() => { |
| | | return userStore.avatar; |
| | | }); |
| | | const refreshScroll = () => { |
| | | nextTick(() => { |
| | | const container = document.getElementById('home'); |
| | | scrollbar.value.scrollTop(container.scrollHeight); |
| | | }); |
| | | }; |
| | | // 根据会话id 查询会话详情 |
| | | const querySessionDetail = async (session) => { |
| | | activeSessionId.value = session.id; |
| | | const { code, data } = await getSessionDetailsApi(session.id); |
| | | if (code === 200) { |
| | | sessionDetailList.value = data.message; |
| | | refreshScroll(); //刷新滚动条位置 |
| | | } |
| | | }; |
| | | const sendMessage = async () => { |
| | | if (inputMsg.value) { |
| | | const { code, data } = await chatApi({ |
| | | conversation_id: activeSessionId.value, |
| | | messages: inputMsg.value, |
| | | }); |
| | | const res = await getSessionDetailsApi(activeSessionId.value); |
| | | if (res.code === 200) { |
| | | sessionDetailList.value = res.data.message.map((item, index) => { |
| | | if (index === res.data.message.length - 1) { |
| | | item.role = 'last'; |
| | | displayedText.value = ''; |
| | | currIndex.value = 0; |
| | | streamStr.value = item.content; |
| | | startDisplayStr(); |
| | | } |
| | | return item; |
| | | }); |
| | | refreshScroll(); |
| | | } |
| | | inputMsg.value = ''; |
| | | } else { |
| | | Message.warning('消息不能为空'); |
| | | } |
| | | }; |
| | | onMounted(() => { |
| | | initData(); |
| | | }); |
| | | //文字动态输出 |
| | | const startDisplayStr = () => { |
| | | if (timer) { |
| | | clearTimeout(timer!); |
| | | } |
| | | const res = streamStr.value; |
| | | // 将数组中的字符串拼接起来 |
| | | if (currIndex.value < res.length) { |
| | | displayedText.value += res[currIndex.value]; |
| | | currIndex.value++; |
| | | setTimeout(startDisplayStr, 100); |
| | | } else { |
| | | clearTimeout(timer!); |
| | | timer = null; |
| | | } |
| | | }; |
| | | watch( |
| | | () => scrollbar.value, |
| | | (newScroll, oldScroll) => { |
| | | if (newScroll) { |
| | | // 获取a-scroll的高度 |
| | | const height = newScroll.$el.offsetHeight; |
| | | console.log('a-scroll height changed to:', height); |
| | | } |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .container { |
| | | width: 100%; |
| | | display: flex; |
| | | } |
| | | //.light { |
| | | // color: white !important; |
| | | //} |
| | | .bottom { |
| | | width: 100%; |
| | | position: absolute; |
| | | bottom: 40px; |
| | | left: 0; |
| | | |
| | | .input { |
| | | margin-left: 20%; |
| | | width: 60%; |
| | | } |
| | | |
| | | .text { |
| | | margin-left: 40%; |
| | | font-size: 12px; |
| | | color: lightgrey; |
| | | line-height: 40px; |
| | | } |
| | | } |
| | | .chat-list { |
| | | width: 90%; |
| | | margin: 0px auto; |
| | | .chat-item { |
| | | margin-top: 20px; |
| | | .chat-item-answer { |
| | | color: white; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="list-wrap"> |
| | | <a-typography-title class="block-title" :heading="6"> |
| | | {{ $t('cardList.tab.title.service') }} |
| | | </a-typography-title> |
| | | <a-row class="list-row" :gutter="24"> |
| | | <a-col |
| | | v-for="item in renderData" |
| | | :key="item.id" |
| | | :xs="12" |
| | | :sm="12" |
| | | :md="12" |
| | | :lg="6" |
| | | :xl="6" |
| | | :xxl="6" |
| | | class="list-col" |
| | | style="min-height: 162px" |
| | | > |
| | | <CardWrap |
| | | :loading="loading" |
| | | :title="item.title" |
| | | :description="item.description" |
| | | :default-value="item.enable" |
| | | :action-type="item.actionType" |
| | | :expires="item.expires" |
| | | :open-txt="$t('cardList.service.open')" |
| | | :close-txt="$t('cardList.service.cancel')" |
| | | :expires-text="$t('cardList.service.renew')" |
| | | :tag-text="$t('cardList.service.tag')" |
| | | :expires-tag-text="$t('cardList.service.expiresTag')" |
| | | :icon="item.icon" |
| | | > |
| | | <template #skeleton> |
| | | <a-skeleton :animation="true"> |
| | | <a-skeleton-line :widths="['100%', '40%', '100%']" :rows="3" /> |
| | | <a-skeleton-line :widths="['40%']" :rows="1" /> |
| | | </a-skeleton> |
| | | </template> |
| | | </CardWrap> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { queryTheServiceList, ServiceRecord } from '@/api/list'; |
| | | import useRequest from '@/hooks/request'; |
| | | import CardWrap from './card-wrap.vue'; |
| | | |
| | | const defaultValue: ServiceRecord[] = new Array(4).fill({}); |
| | | const { loading, response: renderData } = useRequest<ServiceRecord[]>( |
| | | queryTheServiceList, |
| | | defaultValue |
| | | ); |
| | | </script> |
| | | |
| | | <style scoped lang="less"></style> |
New file |
| | |
| | | <template> |
| | | <div class="container"> |
| | | <Breadcrumb :items="['大模型', '智能体管理']" /> |
| | | <a-row :gutter="20" align="stretch"> |
| | | <a-col :span="24"> |
| | | <a-card class="general-card" :title="$t('智能体管理')"> |
| | | <div style="display: flex; justify-content: right"> |
| | | <a-input-search |
| | | :placeholder="$t('cardList.searchInput.placeholder')" |
| | | style="width: 240px" |
| | | @change="queryList" |
| | | /> |
| | | </div> |
| | | <a-divider style="margin: 10px 0" /> |
| | | <a-row justify="space-between"> |
| | | <a-col :span="24"> |
| | | <div style="display: flex; flex-wrap: wrap"> |
| | | <div |
| | | class="card-wrap" |
| | | style="cursor: pointer" |
| | | @click="handleAdd" |
| | | > |
| | | <a-card :bordered="false" hoverable> |
| | | <div style="margin-top: 30px; text-align: center"> |
| | | <a-avatar style="background: #3370ff"> |
| | | <icon-plus /> |
| | | </a-avatar> |
| | | </div> |
| | | <div class="arco-card-body-content"> |
| | | <div style="text-align: center; margin-top: 10px"> |
| | | 新建智能体 |
| | | </div> |
| | | <div |
| | | style=" |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | font-size: 12px; |
| | | color: #999999; |
| | | " |
| | | > |
| | | 通过描述角色和任务来创建你的智能体<br /> |
| | | 智能体可以调用多个工作流和工具 |
| | | </div> |
| | | </div> |
| | | <add-agent ref="addAgents"></add-agent> |
| | | <!-- <div style="position: absolute; bottom: 1rem; right: 1rem;">--> |
| | | <!-- <a-space>--> |
| | | <!-- </a-space>--> |
| | | <!-- </div>--> |
| | | </a-card> |
| | | </div> |
| | | <div |
| | | class="card-wrap" |
| | | v-for="(item, index) of agentList" |
| | | :key="item.id" |
| | | > |
| | | <a-card :bordered="false" hoverable> |
| | | <a-avatar :style="{ backgroundColor: '#3370ff' }"> |
| | | <img |
| | | :style="{ width: '100%' }" |
| | | alt="dessert" |
| | | src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" |
| | | /> |
| | | </a-avatar> |
| | | <a-switch |
| | | v-model="item.off" |
| | | style="position: absolute; top: 10px; right: 10px" |
| | | size="medium" |
| | | @change="handleChange(item)" |
| | | > |
| | | <template #checked> 上线 </template> |
| | | <template #unchecked> 下线 </template> |
| | | </a-switch> |
| | | <div class="arco-card-body-content"> |
| | | <div class="arco-card-body-content-top"> |
| | | <span style="font-size: 18px; font-weight: 900"> |
| | | {{ item.name }} |
| | | </span> |
| | | </div> |
| | | <div class="arco-card-body-content-down"> |
| | | {{ item.prompt_config.prologue }} |
| | | </div> |
| | | </div> |
| | | <div style="position: absolute; bottom: 1.4rem; left: 1rem"> |
| | | <icon-user /> |
| | | <span style="font-size: 12px"> |
| | | <!-- {{ item.name }}--> |
| | | </span> |
| | | </div> |
| | | <div style="position: absolute; bottom: 1rem; right: 1rem"> |
| | | <a-space> |
| | | <span v-show="!item.off"> |
| | | <editAgent |
| | | ref="editAgentKuai" |
| | | typeAngint="edit" |
| | | :formData="form" |
| | | @cancelModal="handleCancel" |
| | | ></editAgent> |
| | | </span> |
| | | <a-popconfirm |
| | | :content="'确定删除吗'" |
| | | type="warning" |
| | | @ok="deleteItem(item)" |
| | | > |
| | | <a-button type="text" size="small"> |
| | | <template #icon> |
| | | <icon-delete /> |
| | | </template> |
| | | </a-button> |
| | | </a-popconfirm> |
| | | </a-space> |
| | | </div> |
| | | </a-card> |
| | | </div> |
| | | </div> |
| | | </a-col> |
| | | </a-row> |
| | | </a-card> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, reactive, nextTick, onBeforeMount, onMounted, onBeforeUnmount } from "vue"; |
| | | import addAgent from '@/views/dmx/IntelligentAgent/components/addAgent.vue'; |
| | | import editAgent from '@/views/dmx/IntelligentAgent/components/editAgent.vue'; |
| | | import { kbdocumentrm, queryKbList } from '@/api/kbList'; |
| | | import { Message } from '@arco-design/web-vue'; |
| | | import { deletedialog, querydialogList } from '@/api/Agent'; |
| | | import useLoading from '@/hooks/loading'; |
| | | const { loading, setLoading } = useLoading(true); |
| | | import EventBus from '@/utils/EventBus'; |
| | | |
| | | let count = 5; |
| | | const activeKey = ref(1); |
| | | const addAgents = ref(); |
| | | const editAgentKuai = ref(); |
| | | const agentList = ref([ |
| | | // { |
| | | // key: 2, |
| | | // title: '内容质检', |
| | | // content: 'Content of Tab Panel 2', |
| | | // }, |
| | | // { |
| | | // key: 3, |
| | | // title: '开通服务', |
| | | // content: 'Content of Tab Panel 3', |
| | | // }, |
| | | // { |
| | | // key: 4, |
| | | // title: '规则预置', |
| | | // content: 'Content of Tab Panel 4', |
| | | // }, |
| | | ]); |
| | | const changeTabs = (val) => { |
| | | activeKey.value = val; |
| | | }; |
| | | const handleAdd = () => { |
| | | addAgents.value.handleClick(); |
| | | }; |
| | | const handleDelete = (key: any) => { |
| | | data.value = data.value.filter((item) => item.key !== key); |
| | | }; |
| | | |
| | | const visible = ref(false); |
| | | const formRef = ref(null); |
| | | const form = reactive({ |
| | | // size: 'medium', |
| | | // name: '', |
| | | }); |
| | | |
| | | const queryList = async (params = {}) => { |
| | | setLoading(true); |
| | | try { |
| | | const { data } = await querydialogList(params); |
| | | console.log(data, 'data'); |
| | | agentList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | off: true, |
| | | }; |
| | | }); |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | const deleteItem = async (row) => { |
| | | console.log(row); |
| | | let data = await deletedialog({ dialog_ids: [row.id] }); |
| | | if (data.code == 0) { |
| | | Message.success('删除成功'); |
| | | queryList(); |
| | | } |
| | | }; |
| | | const handleChange = async (item) => { |
| | | if (item) { |
| | | Object.assign(form, item); |
| | | } |
| | | }; |
| | | const handleCancel = () => { |
| | | queryList(); |
| | | }; |
| | | const handleSubmit = ({ values, errors }) => { |
| | | this.$refs.formRef.validate().then((res, a, b) => { |
| | | debugger; |
| | | console.log('values', values); |
| | | }); |
| | | }; |
| | | onBeforeMount(() => { |
| | | queryList(); |
| | | }); |
| | | onMounted(()=>{ |
| | | EventBus.on('queryList',()=>{ |
| | | queryList(); |
| | | }) |
| | | }) |
| | | onBeforeUnmount(()=>{ |
| | | EventBus.off('queryList') |
| | | }) |
| | | </script> |
| | | |
| | | <script lang="ts"> |
| | | export default { |
| | | name: 'Card', |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .container { |
| | | padding: 0 20px 20px 20px; |
| | | :deep(.arco-list-content) { |
| | | overflow-x: hidden; |
| | | } |
| | | |
| | | :deep(.arco-card-meta-title) { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | :deep(.arco-list-col) { |
| | | display: flex; |
| | | flex-direction: row; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | :deep(.arco-list-item) { |
| | | width: 33%; |
| | | } |
| | | |
| | | :deep(.block-title) { |
| | | margin: 0 0 12px 0; |
| | | font-size: 14px; |
| | | } |
| | | :deep(.list-wrap) { |
| | | // min-height: 140px; |
| | | .list-row { |
| | | align-items: stretch; |
| | | .list-col { |
| | | margin-bottom: 16px; |
| | | } |
| | | } |
| | | :deep(.arco-space) { |
| | | width: 100%; |
| | | .arco-space-item { |
| | | &:last-child { |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .card-wrap { |
| | | width: 23%; |
| | | height: 200px; |
| | | margin: 1%; |
| | | transition: all 0.3s; |
| | | border: 1px solid var(--color-neutral-3); |
| | | border-radius: 4px; |
| | | position: relative; |
| | | &:hover { |
| | | transform: translateY(-4px); |
| | | // box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.1); |
| | | } |
| | | :deep(.arco-card) { |
| | | height: 100%; |
| | | border-radius: 4px; |
| | | .arco-card-body { |
| | | height: 100%; |
| | | .arco-space { |
| | | width: 100%; |
| | | height: 100%; |
| | | .arco-space-item { |
| | | height: 100%; |
| | | &:last-child { |
| | | flex: 1; |
| | | } |
| | | .arco-card-meta { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-flow: column; |
| | | .arco-card-meta-content { |
| | | flex: 1; |
| | | .arco-card-meta-description { |
| | | margin-top: 8px; |
| | | color: rgb(var(--gray-6)); |
| | | line-height: 20px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | .arco-card-meta-footer { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | :deep(.arco-card-meta-title) { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | // To prevent the shaking |
| | | line-height: 28px; |
| | | } |
| | | :deep(.arco-skeleton-line) { |
| | | &:last-child { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | } |
| | | } |
| | | } |
| | | .arco-card-body-content { |
| | | .arco-card-body-content-top { |
| | | margin-top: 10px; |
| | | text-align: center; |
| | | } |
| | | .arco-card-body-content-down { |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | font-size: 12px; |
| | | color: #999999; |
| | | width: 100%; |
| | | height: 60px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | export default { |
| | | // 'menu.list.cardList': 'Card List', |
| | | 'menu.dmx.setting': 'GPT Setting', |
| | | 'cardList.tab.title.all': 'All', |
| | | 'cardList.tab.title.content': 'Quality Inspection', |
| | | 'cardList.tab.title.service': 'The service', |
| | | 'cardList.tab.title.preset': 'Rules Preset', |
| | | 'cardList.searchInput.placeholder': 'Search', |
| | | 'cardList.enable': 'Enable', |
| | | 'cardList.disable': 'Disable', |
| | | 'cardList.content.delete': 'Delete', |
| | | 'cardList.content.inspection': 'Inspection', |
| | | 'cardList.content.action': 'Click Create Qc Content queue', |
| | | 'cardList.service.open': 'Open', |
| | | 'cardList.service.cancel': 'Cancel', |
| | | 'cardList.service.renew': 'Contract of service', |
| | | 'cardList.service.tag': 'Opened', |
| | | 'cardList.service.expiresTag': 'Expired', |
| | | 'cardList.preset.tag': 'Enable', |
| | | }; |
New file |
| | |
| | | export default { |
| | | // 'menu.list.cardList': '卡片列表', |
| | | 'menu.dmx.setting': '大模型设置', |
| | | 'cardList.tab.title.all': '全部', |
| | | 'cardList.tab.title.content': '内容质检', |
| | | 'cardList.tab.title.service': '开通服务', |
| | | 'cardList.tab.title.preset': '规则预置', |
| | | 'cardList.searchInput.placeholder': '搜索', |
| | | // 'cardList.statistic.enable': '已启用', |
| | | // 'cardList.statistic.disable': '未启用', |
| | | 'cardList.content.delete': '删除', |
| | | 'cardList.content.inspection': '质检', |
| | | 'cardList.content.action': '点击创建质检内容队列', |
| | | 'cardList.service.open': '开通服务', |
| | | 'cardList.service.cancel': '取消服务', |
| | | 'cardList.service.renew': '续约服务', |
| | | 'cardList.service.tag': '已开通', |
| | | 'cardList.service.expiresTag': '已过期', |
| | | 'cardList.preset.tag': '已启用', |
| | | }; |
New file |
| | |
| | | import Mock from 'mockjs'; |
| | | import setupMock, { successResponseWrap } from '@/utils/setup-mock'; |
| | | import { ServiceRecord } from '@/api/list'; |
| | | |
| | | const qualityInspectionList: ServiceRecord[] = [ |
| | | { |
| | | id: 1, |
| | | name: 'quality', |
| | | title: '视频类-历史导入', |
| | | description: '2021-10-12 00:00:00', |
| | | data: [ |
| | | { |
| | | label: '待质检数', |
| | | value: '120', |
| | | }, |
| | | { |
| | | label: '积压时长', |
| | | value: '60s', |
| | | }, |
| | | { |
| | | label: '待抽检数', |
| | | value: '0', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: 'quality', |
| | | title: '图文类-图片版权', |
| | | description: '2021-12-11 18:30:00', |
| | | data: [ |
| | | { |
| | | label: '待质检数', |
| | | value: '120', |
| | | }, |
| | | { |
| | | label: '积压时长', |
| | | value: '60s', |
| | | }, |
| | | { |
| | | label: '待抽检数', |
| | | value: '0', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: 'quality', |
| | | title: '图文类-高清图片', |
| | | description: '2021-10-15 08:10:00', |
| | | data: [ |
| | | { |
| | | label: '待质检数', |
| | | value: '120', |
| | | }, |
| | | { |
| | | label: '积压时长', |
| | | value: '60s', |
| | | }, |
| | | { |
| | | label: '待抽检数', |
| | | value: '0', |
| | | }, |
| | | ], |
| | | }, |
| | | ]; |
| | | const theServiceList: ServiceRecord[] = [ |
| | | { |
| | | id: 1, |
| | | icon: 'code', |
| | | title: '漏斗分析', |
| | | description: |
| | | '用户行为分析之漏斗分析模型是企业实现精细化运营、进行用户行为分析的重要数据分析模型。', |
| | | enable: true, |
| | | actionType: 'button', |
| | | }, |
| | | { |
| | | id: 2, |
| | | icon: 'edit', |
| | | title: '用户分布', |
| | | description: |
| | | '快速诊断用户人群,地域细分情况,了解数据分布的集中度,以及主要的数据分布的区间段是什么。', |
| | | enable: true, |
| | | actionType: 'button', |
| | | expires: true, |
| | | }, |
| | | { |
| | | id: 3, |
| | | icon: 'user', |
| | | title: '资源分发', |
| | | description: |
| | | '移动端动态化资源分发解决方案。提供稳定大流量服务支持、灵活定制的分发圈选规则,通过离线化预加载。', |
| | | enable: false, |
| | | actionType: 'button', |
| | | }, |
| | | { |
| | | id: 4, |
| | | icon: 'user', |
| | | title: '用户画像分析', |
| | | description: |
| | | '用户画像就是将典型用户信息标签化,根据用户特征、业务场景和用户行为等信息,构建一个标签化的用户模型。', |
| | | enable: true, |
| | | actionType: 'button', |
| | | }, |
| | | ]; |
| | | const rulesPresetList: ServiceRecord[] = [ |
| | | { |
| | | id: 1, |
| | | title: '内容屏蔽规则', |
| | | description: |
| | | '用户在执行特定的内容分发任务时,可使用内容屏蔽规则根据特定标签,过滤内容集合。', |
| | | enable: true, |
| | | actionType: 'switch', |
| | | }, |
| | | { |
| | | id: 2, |
| | | title: '内容置顶规则', |
| | | description: |
| | | '该规则支持用户在执行特定内容分发任务时,对固定的几条内容置顶。', |
| | | enable: true, |
| | | actionType: 'switch', |
| | | }, |
| | | { |
| | | id: 3, |
| | | title: '内容加权规则', |
| | | description: '选定内容加权规则后可自定义从不同内容集合获取内容的概率。', |
| | | enable: false, |
| | | actionType: 'switch', |
| | | }, |
| | | { |
| | | id: 4, |
| | | title: '内容分发规则', |
| | | description: '内容分发时,对某些内容需要固定在C端展示的位置。', |
| | | enable: true, |
| | | actionType: 'switch', |
| | | }, |
| | | { |
| | | id: 5, |
| | | title: '违禁内容识别', |
| | | description: '精准识别赌博、刀枪、毒品、造假、贩假等违规物品和违规行为。', |
| | | enable: false, |
| | | actionType: 'switch', |
| | | }, |
| | | { |
| | | id: 6, |
| | | title: '多语言文字符号识别', |
| | | description: |
| | | '精准识别英语、维语、藏语、蒙古语、朝鲜语等多种语言以及emoji表情形态的语义识别。', |
| | | enable: false, |
| | | actionType: 'switch', |
| | | }, |
| | | ]; |
| | | |
| | | setupMock({ |
| | | setup() { |
| | | // Quality Inspection |
| | | Mock.mock(new RegExp('/api/list/quality-inspection'), () => { |
| | | return successResponseWrap( |
| | | qualityInspectionList.map((_, index) => ({ |
| | | ...qualityInspectionList[index % qualityInspectionList.length], |
| | | id: Mock.Random.guid(), |
| | | })) |
| | | ); |
| | | }); |
| | | |
| | | // the service |
| | | Mock.mock(new RegExp('/api/list/the-service'), () => { |
| | | return successResponseWrap( |
| | | theServiceList.map((_, index) => ({ |
| | | ...theServiceList[index % theServiceList.length], |
| | | id: Mock.Random.guid(), |
| | | })) |
| | | ); |
| | | }); |
| | | |
| | | // rules preset |
| | | Mock.mock(new RegExp('/api/list/rules-preset'), () => { |
| | | return successResponseWrap( |
| | | rulesPresetList.map((_, index) => ({ |
| | | ...rulesPresetList[index % rulesPresetList.length], |
| | | id: Mock.Random.guid(), |
| | | })) |
| | | ); |
| | | }); |
| | | }, |
| | | }); |