feat: application

This commit is contained in:
wangdan-fit2cloud 2025-07-01 19:16:58 +08:00
parent 3f6faa7592
commit 746fbe8705
16 changed files with 337 additions and 663 deletions

View File

@ -286,6 +286,16 @@ const speechToText: (
return post(`${prefix.value}/${application_id}/speech_to_text`, data, undefined, loading)
}
/**
* mcp
*/
const getMcpTools: (application_id: String, loading?: Ref<boolean>) => Promise<Result<any>> = (
application_id,
loading,
) => {
return get(`${prefix.value}/${application_id}/mcp_tools`, undefined, loading)
}
export default {
getAllApplication,
getApplication,
@ -310,4 +320,5 @@ export default {
playDemoText,
textToSpeech,
speechToText,
getMcpTools,
}

View File

@ -1,204 +0,0 @@
<template>
<el-dialog
:title="$t('views.document.generateQuestion.title')"
v-model="dialogVisible"
width="650"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<div class="content-height">
<el-form
ref="FormRef"
:model="form"
:rules="rules"
label-position="top"
require-asterisk-position="right"
>
<div class="update-info flex border-r-6 mb-16 p-8-12">
<div class="mt-4">
<AppIcon iconName="app-warning-colorful" style="font-size: 16px"></AppIcon>
</div>
<div class="ml-12 lighter">
<p>{{ $t('views.document.generateQuestion.tip1', { data: '{data}' }) }}</p>
<p>
{{ $t('views.document.generateQuestion.tip2')+ '<question></question>' +
$t('views.document.generateQuestion.tip3') }}
</p>
<p>{{ $t('views.document.generateQuestion.tip4') }}</p>
</div>
</div>
<el-form-item
:label="$t('views.application.form.aiModel.label')"
prop="model_id"
>
<ModelSelect
v-model="form.model_id"
:placeholder="$t('views.application.form.aiModel.placeholder')"
:options="modelOptions"
showFooter
:model-type="'LLM'"
></ModelSelect>
</el-form-item>
<el-form-item
:label="$t('views.application.form.prompt.label')"
prop="prompt"
>
<el-input
v-model="form.prompt"
:placeholder="$t('views.application.form.prompt.placeholder')"
:rows="7"
type="textarea"
/>
</el-form-item>
<el-form-item
v-if="['document', 'knowledge'].includes(apiType)"
:label="$t('components.selectParagraph.title')"
prop="state"
>
<el-radio-group v-model="state" class="radio-block">
<el-radio value="error" size="large">{{
$t('components.selectParagraph.error')
}}</el-radio>
<el-radio value="all" size="large">{{ $t('components.selectParagraph.all') }}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submitHandle(FormRef)" :disabled="!model || loading">
{{ $t('common.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import documentApi from '@/api/system-resource-management/document'
import paragraphApi from '@/api/system-resource-management/paragraph'
import knowledgeApi from '@/api/system-resource-management/knowledge'
import useStoreShared from '@/stores/modules-resource-management'
import useStore from '@/stores'
import { groupBy } from 'lodash'
import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
import type { FormInstance } from 'element-plus'
const route = useRoute()
const {
params: { id, documentId }, // idknowledgeID
} = route as any
const { model } = useStoreShared()
const { prompt, user } = useStore()
const emit = defineEmits(['refresh'])
const loading = ref<boolean>(false)
const dialogVisible = ref<boolean>(false)
const modelOptions = ref<any>(null)
const idList = ref<string[]>([])
const apiType = ref('') // documentparagraph
const state = ref<'all' | 'error'>('error')
const stateMap = {
all: ['0', '1', '2', '3', '4', '5', 'n'],
error: ['0', '1', '3', '4', '5', 'n']
}
const FormRef = ref()
const knowledgeId = ref<string>()
const userId = user.userInfo?.id as string
const form = ref(prompt.get(userId))
const rules = reactive({
model_id: [
{
required: true,
message: t('views.application.form.aiModel.placeholder'),
trigger: 'blur'
}
],
prompt: [
{
required: true,
message: t('views.application.form.prompt.placeholder'),
trigger: 'blur'
}
]
})
watch(dialogVisible, (bool) => {
if (!bool) {
form.value = prompt.get(userId)
FormRef.value?.clearValidate()
}
})
const open = (ids: string[], type: string, _knowledgeId?: string) => {
knowledgeId.value = _knowledgeId
getModelFn()
idList.value = ids
apiType.value = type
dialogVisible.value = true
}
const submitHandle = async (formEl: FormInstance) => {
if (!formEl) {
return
}
await formEl.validate((valid, fields) => {
if (valid) {
//
prompt.save(user.userInfo?.id as string, form.value)
if (apiType.value === 'paragraph') {
const data = {
...form.value,
paragraph_id_list: idList.value
}
paragraphApi.putBatchGenerateRelated(id, documentId, data, loading).then(() => {
MsgSuccess(t('views.document.generateQuestion.successMessage'))
emit('refresh')
dialogVisible.value = false
})
} else if (apiType.value === 'document') {
const data = {
...form.value,
document_id_list: idList.value,
state_list: stateMap[state.value]
}
documentApi.putBatchGenerateRelated(id, data, loading).then(() => {
MsgSuccess(t('views.document.generateQuestion.successMessage'))
emit('refresh')
dialogVisible.value = false
})
} else if (apiType.value === 'knowledge') {
const data = {
...form.value,
state_list: stateMap[state.value]
}
knowledgeApi.putGenerateRelated(id ? id : knowledgeId.value, data, loading).then(() => {
MsgSuccess(t('views.document.generateQuestion.successMessage'))
dialogVisible.value = false
})
}
}
})
}
function getModelFn() {
loading.value = true
knowledgeApi
.getKnowledgeModel()
.then((res: any) => {
modelOptions.value = groupBy(res?.data, 'provider')
loading.value = false
})
.catch(() => {
loading.value = false
})
}
defineExpose({ open })
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,176 @@
<template>
<el-form
ref="formRef"
:model="form"
label-position="top"
require-asterisk-position="right"
:rules="rules"
@submit.prevent
>
<el-form-item :label="$t('views.chatLog.selectKnowledge')" prop="knowledge_id">
<el-tree-select
v-model="form.knowledge_id"
:props="defaultProps"
node-key="id"
lazy
:load="loadTree"
:placeholder="$t('views.chatLog.selectKnowledgePlaceholder')"
@change="changeKnowledge"
:loading="optionLoading"
>
<template #default="{ data }">
<div class="flex align-center">
<KnowledgeIcon
class="mr-12"
:size="20"
v-if="data.resource_type !== 'folder'"
:type="data.type"
/>
<el-avatar v-else class="mr-12" shape="square" :size="20" style="background: none">
<img
src="@/assets/knowledge/icon_file-folder_colorful.svg"
style="width: 100%"
alt=""
/>
</el-avatar>
{{ data.name }}
</div>
</template>
</el-tree-select>
</el-form-item>
<el-form-item :label="$t('views.chatLog.saveToDocument')" prop="document_id">
<el-select
v-model="form.document_id"
filterable
:placeholder="$t('views.chatLog.documentPlaceholder')"
:loading="optionLoading"
@changeDocument="changeDocument"
>
<el-option v-for="item in documentList" :key="item.id" :label="item.name" :value="item.id">
{{ item.name }}
</el-option>
</el-select>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { ref, onUnmounted, reactive, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import useStore from '@/stores'
import { t } from '@/locales'
const props = defineProps<{
data?: {
type: Object
default: () => {}
}
apiType: 'systemShare' | 'workspace' | 'systemManage'
isApplicaton?: boolean
}>()
const { user } = useStore()
const emit = defineEmits(['changeKnowledge', 'changeDocument'])
const formRef = ref()
const form = ref<any>({
knowledge_id: '',
document_id: '',
})
const rules = reactive<FormRules>({
knowledge_id: [
{ required: true, message: t('views.chatLog.selectKnowledgePlaceholder'), trigger: 'change' },
],
document_id: [
{ required: true, message: t('views.chatLog.documentPlaceholder'), trigger: 'change' },
],
})
const defaultProps = {
children: 'children',
label: 'name',
isLeaf: (data: any) =>
data.resource_type ? data.resource_type !== 'folder' : data.workspace_id === 'None',
}
const loadTree = (node: any, resolve: any) => {
if (node.isLeaf) return resolve([])
const folder_id = node.level === 0 ? user.getWorkspaceId() : node.data.id
loadSharedApi({ type: 'knowledge', systemType: props.apiType })
.getKnowledgeList({ folder_id: folder_id }, optionLoading)
.then((res: any) => {
resolve(res.data)
})
}
const documentList = ref<any[]>([])
const optionLoading = ref(false)
function changeKnowledge(id: string) {
form.value.document_id = ''
getDocument(id)
emit('changeKnowledge', id)
}
function changeDocument(document_id: string) {
emit('changeKnowledge', document_id)
}
function getDocument(id: string) {
loadSharedApi({ type: 'document', systemType: props.apiType })
.getDocumentList(id, optionLoading)
.then((res: any) => {
documentList.value = res.data
if (props.isApplicaton) {
if (localStorage.getItem(id + 'chat_document_id')) {
form.value.document_id = localStorage.getItem(id + 'chat_document_id') as string
}
if (!documentList.value.find((v) => v.id === form.value.document_id)) {
form.value.document_id = ''
}
}
})
}
watch(
() => props.data,
(value: any) => {
if (value && JSON.stringify(value) !== '{}') {
form.value.knowledge_id = value.knowledge_id
form.value.document_id = value.document_id
}
},
{
immediate: true,
},
)
/*
表单校验
*/
function validate() {
if (!formRef.value) return
return formRef.value.validate((valid: any) => {
return valid
})
}
function clearValidate() {
form.value = {
knowledge_id: '',
document_id: '',
}
formRef.value?.clearValidate()
}
onUnmounted(() => {
clearValidate()
})
defineExpose({
validate,
form,
clearValidate,
})
</script>

View File

@ -1,21 +0,0 @@
<script setup lang="ts">
import PermissionConst from '@/utils/permission/data'
</script>
<template>
首页
<div v-hasPermission="PermissionConst.USER_READ.getWorkspacePermission('default')">
default工作空间用户只读
</div>
<div v-hasPermission="PermissionConst.USER_READ.getWorkspacePermission('default1')">
default1工作空间用户只读
</div>
<div v-hasPermission="PermissionConst.USER_READ">用户只读</div>
<div
v-hasPermission="
PermissionConst.KNOWLEDGE_READ.getWorkspaceResourcePermission('default', 'KNOWLEDGE', 'xxx')
"
>
default工作空间的知识库xxx权限
</div>
</template>

View File

@ -48,42 +48,14 @@
>
</el-input>
</el-form-item>
<el-form-item :label="$t('views.chatLog.selectKnowledge')" prop="knowledge_id">
<el-select
v-model="form.knowledge_id"
filterable
:placeholder="$t('views.chatLog.selectKnowledgePlaceholder')"
:loading="optionLoading"
@change="changeKnowledge"
>
<el-option v-for="item in knowledgeList" :key="item.id" :label="item.name" :value="item.id">
<span class="flex align-center">
<KnowledgeIcon v-if="item.knowledge_id" :type="item.type" />
{{ item.name }}
</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('views.chatLog.saveToDocument')" prop="document_id">
<el-select
v-model="form.document_id"
filterable
:placeholder="$t('views.chatLog.documentPlaceholder')"
:loading="optionLoading"
@change="changeDocument"
>
<el-option
v-for="item in documentList"
:key="item.id"
:label="item.name"
:value="item.id"
>
{{ item.name }}
</el-option>
</el-select>
</el-form-item>
</el-form>
<SelectKnowledgeDocument
ref="SelectKnowledgeDocumentRef"
:apiType="apiType"
@changeKnowledge="changeKnowledge"
@changeDocument="changeDocument"
:isApplicaton="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
@ -95,15 +67,13 @@
</el-dialog>
</template>
<script setup lang="ts">
import { ref, watch, reactive } from 'vue'
import { ref, watch, reactive, computed } from 'vue'
import { useRoute } from 'vue-router'
import SelectKnowledgeDocument from '@/components/select-knowledge-document/index.vue'
import type { FormInstance, FormRules } from 'element-plus'
import chatLogApi from '@/api/application/chat-log'
import imageApi from '@/api/image'
import documentApi from '@/api/knowledge/document'
import useStore from '@/stores'
import { t } from '@/locales'
const { application, user } = useStore()
const route = useRoute()
const {
@ -111,6 +81,10 @@ const {
} = route as any
const emit = defineEmits(['refresh'])
const apiType = computed<'workspace'>(() => {
return 'workspace'
})
const formRef = ref()
const toolbars = [
@ -145,6 +119,7 @@ const toolbars = [
const footers = ['markdownTotal', 0, '=', 1, 'scrollSwitch']
const SelectKnowledgeDocumentRef = ref()
const dialogVisible = ref<boolean>(false)
const loading = ref(false)
@ -154,22 +129,14 @@ const form = ref<any>({
problem_text: '',
title: '',
content: '',
knowledge_id: '',
document_id: '',
})
const rules = reactive<FormRules>({
content: [{ required: true, message: t('views.chatLog.form.content.placeholder'), trigger: 'blur' }],
knowledge_id: [
{ required: true, message: t('views.chatLog.selectKnowledgePlaceholder'), trigger: 'change' },
content: [
{ required: true, message: t('views.chatLog.form.content.placeholder'), trigger: 'blur' },
],
document_id: [{ required: true, message: t('views.chatLog.documentPlaceholder'), trigger: 'change' }],
})
const knowledgeList = ref<any[]>([])
const documentList = ref<any[]>([])
const optionLoading = ref(false)
watch(dialogVisible, (bool) => {
if (!bool) {
form.value = {
@ -178,12 +145,9 @@ watch(dialogVisible, (bool) => {
problem_text: '',
title: '',
content: '',
knowledge_id: '',
document_id: '',
}
knowledgeList.value = []
documentList.value = []
formRef.value?.clearValidate()
SelectKnowledgeDocumentRef.value?.clearValidate()
}
})
@ -209,43 +173,13 @@ const onUploadImg = async (files: any, callback: any) => {
function changeKnowledge(knowledge_id: string) {
localStorage.setItem(id + 'chat_knowledge_id', knowledge_id)
form.value.document_id = ''
getDocument(knowledge_id)
}
function changeDocument(document_id: string) {
localStorage.setItem(id + 'chat_document_id', document_id)
}
function getDocument(knowledge_id: string) {
documentApi.getDocumentList(knowledge_id, loading).then((res: any) => {
documentList.value = res.data
if (localStorage.getItem(id + 'chat_document_id')) {
form.value.document_id = localStorage.getItem(id + 'chat_document_id') as string
}
if (!documentList.value.find((v) => v.id === form.value.document_id)) {
form.value.document_id = ''
}
})
}
function getKnowledge_id() {
application.asyncGetApplicationKnowledge(id, loading).then((res: any) => {
knowledgeList.value = res.data
if (localStorage.getItem(id + 'chat_knowledge_id')) {
form.value.knowledge_id = localStorage.getItem(id + 'chat_knowledge_id') as string
if (!knowledgeList.value.find((v) => v.id === form.value.knowledge_id)) {
form.value.knowledge_id = ''
form.value.document_id = ''
} else {
getDocument(form.value.knowledge_id)
}
}
})
}
const open = (data: any) => {
getKnowledge_id()
form.value.chat_id = data.chat_id
form.value.record_id = data.id
form.value.problem_text = data.problem_text ? data.problem_text.substring(0, 256) : ''
@ -255,27 +189,29 @@ const open = (data: any) => {
}
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
await formEl.validate(async (valid) => {
if (valid) {
const obj = {
title: form.value.title,
content: form.value.content,
problem_text: form.value.problem_text,
if (await SelectKnowledgeDocumentRef.value?.validate()) {
const obj = {
title: form.value.title,
content: form.value.content,
problem_text: form.value.problem_text,
}
chatLogApi
.putChatRecordLog(
id,
form.value.chat_id,
form.value.record_id,
SelectKnowledgeDocumentRef.value.form.knowledge_id,
SelectKnowledgeDocumentRef.value.form.document_id,
obj,
loading,
)
.then((res: any) => {
emit('refresh', res.data)
dialogVisible.value = false
})
}
chatLogApi
.putChatRecordLog(
id,
form.value.chat_id,
form.value.record_id,
form.value.knowledge_id,
form.value.document_id,
obj,
loading,
)
.then((res: any) => {
emit('refresh', res.data)
dialogVisible.value = false
})
}
})
}

View File

@ -38,16 +38,10 @@
clearable
/>
<div style="display: flex; align-items: center" class="float-right">
<el-button
@click="dialogVisible = true"
v-if="permissionPrecise.chat_log_clear(id)"
>
<el-button @click="dialogVisible = true" v-if="permissionPrecise.chat_log_clear(id)">
{{ $t('views.chatLog.buttons.clearStrategy') }}
</el-button>
<el-button
@click="exportLog"
v-if="permissionPrecise.chat_log_export(id)"
>
<el-button @click="exportLog" v-if="permissionPrecise.chat_log_export(id)">
{{ $t('common.export') }}
</el-button>
<el-button
@ -215,60 +209,13 @@
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<el-form
ref="formRef"
:model="form"
label-position="top"
require-asterisk-position="right"
:rules="rules"
@submit.prevent
>
<el-form-item :label="$t('views.chatLog.selectKnowledge')" prop="knowledge_id">
<el-select
v-model="form.knowledge_id"
filterable
:placeholder="$t('views.chatLog.selectKnowledgePlaceholder')"
:loading="optionLoading"
@change="changeKnowledge"
>
<el-option
v-for="item in knowledgeList"
:key="item.id"
:label="item.name"
:value="item.id"
>
<span class="flex align-center">
<KnowledgeIcon :type="item.type" v-if="!item.knowledge_id" />
{{ item.name }}
</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('views.chatLog.saveToDocument')" prop="document_id">
<el-select
v-model="form.document_id"
filterable
:placeholder="$t('views.chatLog.documentPlaceholder')"
:loading="optionLoading"
@change="changeDocument"
>
<el-option
v-for="item in documentList"
:key="item.id"
:label="item.name"
:value="item.id"
>
{{ item.name }}
</el-option>
</el-select>
</el-form-item>
</el-form>
<SelectKnowledgeDocument ref="SelectKnowledgeDocumentRef" :apiType="apiType" />
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="documentDialogVisible = false">
{{ $t('common.cancel') }}
</el-button>
<el-button type="primary" @click="submitForm(formRef)" :loading="documentLoading">
<el-button type="primary" @click="submitForm" :loading="documentLoading">
{{ $t('common.save') }}
</el-button>
</span>
@ -281,29 +228,25 @@ import { ref, type Ref, onMounted, reactive, computed } from 'vue'
import { useRoute } from 'vue-router'
import { cloneDeep } from 'lodash'
import ChatRecordDrawer from './component/ChatRecordDrawer.vue'
import SelectKnowledgeDocument from '@/components/select-knowledge-document/index.vue'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import chatLogApi from '@/api/application/chat-log'
import documentApi from '@/api/knowledge/document'
import { beforeDay, datetimeFormat, nowDate } from '@/utils/time'
import useStore from '@/stores'
import type { Dict } from '@/api/type/common'
import { t } from '@/locales'
import type { FormInstance, FormRules } from 'element-plus'
import { ElTable } from 'element-plus'
import { PermissionConst, RoleConst } from '@/utils/permission/data'
import { hasPermission } from '@/utils/permission/index'
import permissionMap from '@/permission'
const route = useRoute()
const apiType = computed<'workspace'>(() => {
return 'workspace'
return 'workspace'
})
const permissionPrecise = computed(() => {
return permissionMap['application'][apiType.value]
})
const { application, chatLog, user } = useStore()
const {
params: { id },
@ -383,25 +326,6 @@ const filter = ref<any>({
comparer: 'and',
})
const form = ref<any>({
knowledge_id: '',
document_id: '',
})
const rules = reactive<FormRules>({
knowledge_id: [
{ required: true, message: t('views.chatLog.selectKnowledgePlaceholder'), trigger: 'change' },
],
document_id: [
{
required: true,
message: t('views.chatLog.documentPlaceholder'),
trigger: 'change',
},
],
})
const optionLoading = ref(false)
const documentList = ref<any[]>([])
function filterChange(val: string) {
@ -575,71 +499,28 @@ function saveCleanTime() {
})
}
function changeKnowledge(knowledge_id: string) {
localStorage.setItem(id + 'chat_knowledge_id', knowledge_id)
form.value.document_id = ''
getDocument(knowledge_id)
}
function changeDocument(document_id: string) {
localStorage.setItem(id + 'chat_document_id', document_id)
}
const knowledgeList = ref<any[]>([])
function getKnowledge() {
application.asyncGetApplicationKnowledge(id, documentLoading).then((res: any) => {
knowledgeList.value = res.data
if (localStorage.getItem(id + 'chat_knowledge_id')) {
form.value.knowledge_id = localStorage.getItem(id + 'chat_knowledge_id') as string
if (!knowledgeList.value.find((v) => v.id === form.value.knowledge_id)) {
form.value.knowledge_id = ''
form.value.document_id = ''
} else {
getDocument(form.value.knowledge_id)
const SelectKnowledgeDocumentRef = ref()
const submitForm = async () => {
if (await SelectKnowledgeDocumentRef.value?.validate()) {
const arr: string[] = []
multipleSelection.value.map((v) => {
if (v) {
arr.push(v.id)
}
})
const obj = {
...SelectKnowledgeDocumentRef.value.form,
chat_ids: arr,
}
})
}
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
const arr: string[] = []
multipleSelection.value.map((v) => {
if (v) {
arr.push(v.id)
}
})
await formEl.validate((valid) => {
if (valid) {
const obj = {
document_id: form.value.document_id,
knowledge_id: form.value.knowledge_id,
chat_ids: arr,
}
chatLogApi.postChatLogAddKnowledge(id, obj, documentLoading).then((res: any) => {
multipleTableRef.value?.clearSelection()
documentDialogVisible.value = false
})
}
})
}
function getDocument(knowledge_id: string) {
documentApi.getDocumentList(knowledge_id, documentLoading).then((res: any) => {
documentList.value = res.data
if (localStorage.getItem(id + 'chat_document_id')) {
form.value.document_id = localStorage.getItem(id + 'chat_document_id') as string
}
if (!documentList.value.find((v) => v.id === form.value.document_id)) {
form.value.document_id = ''
}
})
chatLogApi.postChatLogAddKnowledge(id, obj, documentLoading).then((res: any) => {
multipleTableRef.value?.clearSelection()
documentDialogVisible.value = false
})
}
}
function openDocumentDialog() {
getKnowledge()
formRef.value?.clearValidate()
SelectKnowledgeDocumentRef.value?.clearValidate()
documentDialogVisible.value = true
}

View File

@ -1,9 +1,7 @@
<template>
<login-layout v-if="!loading" v-loading="loading || sendLoading">
<LoginContainer
:subTitle="
theme.themeInfo?.slogan ? theme.themeInfo?.slogan : $t('theme.defaultSlogan')
"
:subTitle="theme.themeInfo?.slogan ? theme.themeInfo?.slogan : $t('theme.defaultSlogan')"
>
<h2 class="mb-24">{{ $t('views.login.forgotPassword') }}</h2>
<el-form
@ -81,12 +79,12 @@ import { t } from '@/locales'
import useStore from '@/stores'
const router = useRouter()
const { theme, user} = useStore()
const { theme, user } = useStore()
const CheckEmailForm = ref<CheckCodeRequest>({
email: '',
code: '',
type: 'reset_password'
type: 'reset_password',
})
const resetPasswordFormRef = ref<FormInstance>()
@ -95,7 +93,7 @@ const rules = ref<FormRules<CheckCodeRequest>>({
{
required: true,
message: t('views.login.loginForm.email.requiredMessage'),
trigger: 'blur'
trigger: 'blur',
},
{
validator: (rule, value, callback) => {
@ -106,10 +104,10 @@ const rules = ref<FormRules<CheckCodeRequest>>({
callback()
}
},
trigger: 'blur'
}
trigger: 'blur',
},
],
code: [{ required: true, message: t('views.login.verificationCode.placeholder') }]
code: [{ required: true, message: t('views.login.verificationCode.placeholder') }],
})
const loading = ref<boolean>(false)
const isDisabled = ref<boolean>(false)

View File

@ -64,6 +64,7 @@
editorId="preview-only"
:modelValue="data.content"
class="maxkb-md"
style="background: none"
/>
<ParagraphDialog

View File

@ -7,68 +7,17 @@
:close-on-press-escape="false"
@click.stop
>
<el-form
ref="formRef"
:model="form"
label-position="top"
require-asterisk-position="right"
:rules="rules"
@submit.prevent
>
<el-form-item :label="$t('views.chatLog.selectKnowledge')" prop="knowledge_id">
<el-tree-select
v-model="form.knowledge_id"
:props="defaultProps"
node-key="id"
lazy
:load="loadTree"
:placeholder="$t('views.chatLog.selectKnowledgePlaceholder')"
@change="changeKnowledge"
:loading="optionLoading"
>
<template #default="{ data }">
<div class="flex align-center">
<KnowledgeIcon
class="mr-12"
:size="20"
v-if="data.resource_type !== 'folder'"
:type="data.type"
/>
<el-avatar v-else class="mr-12" shape="square" :size="20" style="background: none">
<img
src="@/assets/knowledge/icon_file-folder_colorful.svg"
style="width: 100%"
alt=""
/>
</el-avatar>
{{ data.name }}
</div>
</template>
</el-tree-select>
</el-form-item>
<el-form-item :label="$t('views.chatLog.saveToDocument')" prop="document_id">
<el-select
v-model="form.document_id"
filterable
:placeholder="$t('views.chatLog.documentPlaceholder')"
:loading="optionLoading"
>
<el-option
v-for="item in documentList"
:key="item.id"
:label="item.name"
:value="item.id"
>
{{ item.name }}
</el-option>
</el-select>
</el-form-item>
</el-form>
<SelectKnowledgeDocument
ref="SelectKnowledgeDocumentRef"
:apiType="apiType"
@changeKnowledge="changeKnowledge"
@changeDocument="changeDocument"
:isApplicaton="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submitForm(formRef)" :loading="loading">
<el-button type="primary" @click="submitForm" :loading="loading">
{{ $t('views.document.setting.migration') }}
</el-button>
</span>
@ -78,10 +27,8 @@
<script setup lang="ts">
import { ref, watch, reactive, computed } from 'vue'
import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus'
import SelectKnowledgeDocument from '@/components/select-knowledge-document/index.vue'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import useStore from '@/stores'
import { t } from '@/locales'
const props = defineProps<{
apiType: 'systemShare' | 'workspace' | 'systemManage'
@ -91,104 +38,52 @@ const {
params: { id, documentId }, // idknowledgeID
} = route as any
const { user } = useStore()
const emit = defineEmits(['refresh'])
const formRef = ref()
const SelectKnowledgeDocumentRef = ref()
const dialogVisible = ref<boolean>(false)
const loading = ref(false)
const form = ref<any>({
knowledge_id: '',
document_id: '',
})
const rules = reactive<FormRules>({
knowledge_id: [
{ required: true, message: t('views.chatLog.selectKnowledgePlaceholder'), trigger: 'change' },
],
document_id: [
{ required: true, message: t('views.chatLog.documentPlaceholder'), trigger: 'change' },
],
})
const documentList = ref<any[]>([])
const optionLoading = ref(false)
const paragraphList = ref<string[]>([])
watch(dialogVisible, (bool) => {
if (!bool) {
form.value = {
knowledge_id: '',
document_id: '',
}
documentList.value = []
paragraphList.value = []
formRef.value?.clearValidate()
SelectKnowledgeDocumentRef.value?.clearValidate()
}
})
const defaultProps = {
children: 'children',
label: 'name',
isLeaf: (data: any) =>
data.resource_type ? data.resource_type !== 'folder' : data.workspace_id === 'None',
disabled: (data: any, node: any) => {
return data.id === id
},
}
const loadTree = (node: any, resolve: any) => {
if (node.isLeaf) return resolve([])
const folder_id = node.level === 0 ? user.getWorkspaceId() : node.data.id
loadSharedApi({ type: 'knowledge', systemType: props.apiType })
.getKnowledgeList({ folder_id: folder_id }, optionLoading)
.then((res: any) => {
resolve(res.data)
})
}
function changeKnowledge(id: string) {
form.value.document_id = ''
getDocument(id)
}
function getDocument(id: string) {
loadSharedApi({ type: 'document', systemType: props.apiType })
.getDocumentList(id, optionLoading)
.then((res: any) => {
documentList.value = res.data?.filter((v: any) => v.id !== documentId)
})
}
const open = (list: any) => {
paragraphList.value = list
formRef.value?.clearValidate()
dialogVisible.value = true
}
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
const obj = {
id_list: paragraphList.value,
}
loadSharedApi({ type: 'paragraph', systemType: props.apiType })
.putMigrateMulParagraph(
id,
documentId,
form.value.knowledge_id,
form.value.document_id,
obj,
loading,
)
.then(() => {
emit('refresh')
dialogVisible.value = false
})
const submitForm = async () => {
if (await SelectKnowledgeDocumentRef.value?.validate()) {
const obj = {
id_list: paragraphList.value,
}
})
loadSharedApi({ type: 'paragraph', systemType: props.apiType })
.putMigrateMulParagraph(
id,
documentId,
SelectKnowledgeDocumentRef.value.form.knowledge_id,
SelectKnowledgeDocumentRef.value.form.document_id,
obj,
loading,
)
.then(() => {
emit('refresh')
dialogVisible.value = false
})
}
}
function changeKnowledge(dataset_id: string) {
localStorage.setItem(id + 'chat_dataset_id', dataset_id)
}
function changeDocument(document_id: string) {
localStorage.setItem(id + 'chat_document_id', document_id)
}
defineExpose({ open })

View File

@ -207,13 +207,16 @@ function changeState(id: string) {
}
function refreshMigrateParagraph(data: any) {
console.log(data)
if (data) {
multipleSelection.value = [data]
multipleSelection.value = [data.id]
}
console.log(paragraphDetail.value)
console.log(multipleSelection.value)
paragraphDetail.value = paragraphDetail.value.filter(
(v) => !multipleSelection.value.includes(v.id),
)
getParagraphList()
console.log(paragraphDetail.value)
multipleSelection.value = []
MsgSuccess(t('views.document.tip.migrationSuccess'))
}
@ -316,7 +319,7 @@ function openGenerateDialog(row?: any) {
function onEnd(event?: any) {
const obj = {
paragraph_id: paragraphDetail.value[event.newIndex].id, // ID
new_position: paragraphDetail.value[event.newIndex+1].position, //
new_position: paragraphDetail.value[event.newIndex + 1].position, //
}
loadSharedApi({ type: 'paragraph', systemType: apiType.value }).putAdjustPosition(
id,

View File

@ -93,8 +93,8 @@ import authorizationApi from '@/api/system-shared/authorization'
import workspaceApi from '@/api/workspace/workspace'
const checkAll = ref(false)
const isIndeterminate = ref(true)
const checkedWorkspace = ref([])
const workspace = ref([])
const checkedWorkspace = ref<any[]>([])
const workspace = ref<any[]>([])
const listType = ref('WHITE_LIST')
const search = ref('')
let knowledge_id = ''
@ -158,6 +158,4 @@ defineExpose({
})
</script>
<style lang="scss">
.authorized-workspace {
}
</style>

View File

@ -1,7 +1,7 @@
import Components from '@/components'
import ElementPlus from 'element-plus'
import * as ElementPlusIcons from '@element-plus/icons-vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { HtmlResize } from '@logicflow/extension'
import { h as lh } from '@logicflow/core'
import { createApp, h } from 'vue'

View File

@ -223,33 +223,35 @@ const update_field = () => {
}
// todo
applicationApi
.getApplicationById(id, props.nodeModel.properties.node_data.application_id)
.getApplicationDetail(id)
.then((ok) => {
const old_api_input_field_list = cloneDeep(
props.nodeModel.properties.node_data.api_input_field_list
props.nodeModel.properties.node_data.api_input_field_list,
)
const old_user_input_field_list = cloneDeep(
props.nodeModel.properties.node_data.user_input_field_list
props.nodeModel.properties.node_data.user_input_field_list,
)
if (isWorkFlow(ok.data.type)) {
const nodeData = ok.data.work_flow.nodes[0].properties.node_data
const new_api_input_field_list = cloneDeep(
ok.data.work_flow.nodes[0].properties.api_input_field_list
ok.data.work_flow.nodes[0].properties.api_input_field_list,
)
const new_user_input_field_list = cloneDeep(
ok.data.work_flow.nodes[0].properties.user_input_field_list
ok.data.work_flow.nodes[0].properties.user_input_field_list,
)
const merge_api_input_field_list = (new_api_input_field_list || []).map((item: any) => {
const find_field = old_api_input_field_list.find(
(old_item: any) => old_item.variable == item.variable
(old_item: any) => old_item.variable == item.variable,
)
if (find_field) {
return {
...item,
value: find_field.value,
label:
typeof item.label === 'object' && item.label != null ? item.label.label : item.label
typeof item.label === 'object' && item.label != null
? item.label.label
: item.label,
}
} else {
return item
@ -258,18 +260,20 @@ const update_field = () => {
set(
props.nodeModel.properties.node_data,
'api_input_field_list',
merge_api_input_field_list
merge_api_input_field_list,
)
const merge_user_input_field_list = (new_user_input_field_list || []).map((item: any) => {
const find_field = old_user_input_field_list.find(
(old_item: any) => old_item.field == item.field
(old_item: any) => old_item.field == item.field,
)
if (find_field) {
return {
...item,
value: find_field.value,
label:
typeof item.label === 'object' && item.label != null ? item.label.label : item.label
typeof item.label === 'object' && item.label != null
? item.label.label
: item.label,
}
} else {
return item
@ -278,7 +282,7 @@ const update_field = () => {
set(
props.nodeModel.properties.node_data,
'user_input_field_list',
merge_user_input_field_list
merge_user_input_field_list,
)
const fileEnable = nodeData.file_upload_enable
const fileUploadSetting = nodeData.file_upload_setting

View File

@ -95,10 +95,7 @@
:label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.reference')"
value="referencing"
/>
<el-option
:label="$t('common.custom')"
value="custom"
/>
<el-option :label="$t('common.custom')" value="custom" />
</el-select>
</div>
</template>
@ -166,10 +163,7 @@
:label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.reference')"
value="referencing"
/>
<el-option
:label="$t('common.custom')"
value="custom"
/>
<el-option :label="$t('common.custom')" value="custom" />
</el-select>
</div>
</template>
@ -214,9 +208,14 @@ import { t } from '@/locales'
import { MsgError, MsgSuccess } from '@/utils/message'
import TooltipLabel from '@/components/dynamics-form/items/label/TooltipLabel.vue'
import NodeCascader from '@/workflow/common/NodeCascader.vue'
import { useRoute } from 'vue-router'
const props = defineProps<{ nodeModel: any }>()
const route = useRoute()
const {
params: { id },
} = route as any
const dynamicsFormRef = ref()
const loading = ref(false)
@ -262,16 +261,14 @@ function getTools() {
return
}
// todo
applicationApi
.getMcpTools({ mcp_servers: form_data.value.mcp_servers }, loading)
.then((res: any) => {
form_data.value.mcp_tools = res.data
MsgSuccess(t('views.applicationWorkflow.nodes.mcpNode.getToolsSuccess'))
// jsonmcp_server
form_data.value.mcp_server = form_data.value.mcp_tools.filter(
(item: any) => item.name === form_data.value.mcp_tool,
)[0].server
})
applicationApi.getMcpTools(id, loading).then((res: any) => {
form_data.value.mcp_tools = res.data
MsgSuccess(t('views.applicationWorkflow.nodes.mcpNode.getToolsSuccess'))
// jsonmcp_server
form_data.value.mcp_server = form_data.value.mcp_tools.filter(
(item: any) => item.name === form_data.value.mcp_tool,
)[0].server
})
}
function changeTool() {

View File

@ -89,6 +89,7 @@ import type { FormInstance } from 'element-plus'
import { ref, computed, onMounted } from 'vue'
import { isLastNode } from '@/workflow/common/data'
import applicationApi from '@/api/application/application'
import ToolApi from '@/api/tool/tool'
const props = defineProps<{ nodeModel: any }>()
@ -127,8 +128,7 @@ const update_field = () => {
return
}
//todo
applicationApi
.getToolLib(id, props.nodeModel.properties.node_data.tool_lib_id)
ToolApi.getToolById(props.nodeModel.properties.node_data.tool_lib_id)
.then((ok) => {
const old_input_field_list = props.nodeModel.properties.node_data.input_field_list
const merge_input_field_list = ok.data.input_field_list.map((item: any) => {
@ -141,7 +141,7 @@ const update_field = () => {
set(props.nodeModel.properties.node_data, 'input_field_list', merge_input_field_list)
set(props.nodeModel.properties, 'status', ok.data.is_active ? 200 : 500)
})
.catch((err) => {
.catch(() => {
set(props.nodeModel.properties, 'status', 500)
})
}

View File

@ -1,4 +1,3 @@
import { model } from '@/permission/model'
import { fileURLToPath, URL } from 'node:url'
import type { ProxyOptions } from 'vite'
import { defineConfig, loadEnv } from 'vite'
@ -37,7 +36,7 @@ export default defineConfig((conf: any) => {
const ENV = loadEnv(mode, envDir)
const proxyConf: Record<string, string | ProxyOptions> = {}
proxyConf['/admin/api'] = {
// target: 'http://47.92.195.88:8080',
// target: 'http://47.92.195.88:8080/',
target: 'http://127.0.0.1:8080',
changeOrigin: true,
}