feat: Add tag management

v3.2
wangdan-fit2cloud 2025-10-20 15:02:04 +08:00
parent ba5f86d6df
commit 76ba9d0513
9 changed files with 110 additions and 55 deletions

View File

@ -102,10 +102,11 @@ export default {
label: 'Tag Management', label: 'Tag Management',
key: 'Tag', key: 'Tag',
value: 'Value', value: 'Value',
add: 'Add Tag', addTag: 'Add Tag',
setting: 'Tag Settings', setting: 'Tag Settings',
create: 'Create Tag', create: 'Create Tag',
edit: 'Edit Tag', edit: 'Edit Tag',
editValue: 'Edit Tag Value',
deleteConfirm: 'Confirm delete tag: ', deleteConfirm: 'Confirm delete tag: ',
deleteTip: 'After deletion, resources using this tag will have the tag removed. Please proceed with caution!', deleteTip: 'After deletion, resources using this tag will have the tag removed. Please proceed with caution!',
requiredMessage1: 'Please enter a tag', requiredMessage1: 'Please enter a tag',

View File

@ -97,10 +97,12 @@ export default {
label: '标签管理', label: '标签管理',
key: '标签', key: '标签',
value: '标签值', value: '标签值',
add: '添加标签', addTag: '添加标签',
addValue: '添加标签值',
setting: '标签设置', setting: '标签设置',
create: '创建标签', create: '创建标签',
edit: '编辑标签', edit: '编辑标签',
editValue: '编辑标签值',
deleteConfirm: '是否删除标签: ', deleteConfirm: '是否删除标签: ',
deleteTip: '删除后使用该标签的资源将会删除该标签,请谨慎操作!', deleteTip: '删除后使用该标签的资源将会删除该标签,请谨慎操作!',
requiredMessage1: '请输入标签', requiredMessage1: '请输入标签',

View File

@ -100,10 +100,11 @@ export default {
label: '標籤管理', label: '標籤管理',
key: '標籤', key: '標籤',
value: '標籤值', value: '標籤值',
add: '添加標籤', addTag: '添加標籤',
setting: '標籤設置', setting: '標籤設置',
create: '創建標籤', create: '創建標籤',
edit: '編輯標籤', edit: '編輯標籤',
editValue: '編輯標籤值',
deleteConfirm: '是否刪除標籤: ', deleteConfirm: '是否刪除標籤: ',
deleteTip: '刪除後使用該標籤的資源將會刪除該標籤,請謹慎操作!', deleteTip: '刪除後使用該標籤的資源將會刪除該標籤,請謹慎操作!',
requiredMessage1: '請輸入標籤', requiredMessage1: '請輸入標籤',

View File

@ -62,7 +62,7 @@
:disabled="multipleSelection.length === 0" :disabled="multipleSelection.length === 0"
v-if="permissionPrecise.doc_edit(id)" v-if="permissionPrecise.doc_edit(id)"
> >
{{ $t('views.document.tag.add') }} {{ $t('views.document.tag.addTag') }}
</el-button> </el-button>
<el-dropdown v-if="MoreFilledPermission0(id)"> <el-dropdown v-if="MoreFilledPermission0(id)">
<el-button class="ml-12 mr-12"> <el-button class="ml-12 mr-12">
@ -687,7 +687,7 @@ import permissionMap from '@/permission'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api' import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import TagDrawer from "./tag/TagDrawer.vue"; import TagDrawer from "./tag/TagDrawer.vue";
import TagSettingDrawer from "./tag/TagSettingDrawer.vue"; import TagSettingDrawer from "./tag/TagSettingDrawer.vue";
import AddTagDialog from "@/views/document/component/AddTagDialog.vue"; import AddTagDialog from "@/views/document/tag/MulAddTagDialog.vue";
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()

View File

@ -1,5 +1,9 @@
<template> <template>
<el-dialog v-model="dialogVisible" :title="$t('views.document.tag.create')" :before-close="close"> <el-dialog
v-model="dialogVisible"
:title="currentTagKey ? $t('views.document.tag.addValue') : $t('views.document.tag.create')"
:before-close="close"
>
<el-form <el-form
ref="FormRef" ref="FormRef"
:model="{ tags }" :model="{ tags }"
@ -76,7 +80,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import AppIcon from '@/components/app-icon/AppIcon.vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts' import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'

View File

@ -1,8 +1,9 @@
<template> <template>
<el-dialog <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
:title="$t('views.document.tag.edit')" :title="isEditKey ? $t('views.document.tag.edit') : $t('views.document.tag.editValue')"
:before-close="close" :before-close="close"
:width="isEditKey ? '500px' : '50%'"
> >
<el-form <el-form
ref="FormRef" ref="FormRef"
@ -11,23 +12,46 @@
require-asterisk-position="right" require-asterisk-position="right"
@submit.prevent @submit.prevent
> >
<el-form-item label="标签" v-if="isEditKey" <el-form-item
:rules="{ required: true, message: $t('views.document.tag.requiredMessage1'), trigger: 'blur' }" :label="$t('views.document.tag.key')"
prop="key"> v-if="isEditKey"
:rules="{
required: true,
message: $t('views.document.tag.requiredMessage1'),
trigger: 'blur',
}"
prop="key"
>
<el-input v-model="form.key"></el-input> <el-input v-model="form.key"></el-input>
</el-form-item> </el-form-item>
<div v-else class="flex-between"> <el-row :gutter="8" align="bottom" v-else>
<el-form-item label="标签" prop="key" <el-col :span="12">
style="width: 50%" <el-form-item
:rules="{ required: true, message: $t('views.document.tag.requiredMessage1'), trigger: 'blur' }"> :label="$t('views.document.tag.key')"
<el-input v-model="form.key" :disabled="true"></el-input> prop="key"
</el-form-item> :rules="{
<el-form-item label="标签值" prop="value" required: true,
style="width: 50%" message: $t('views.document.tag.requiredMessage1'),
:rules="{ required: true, message: $t('views.document.tag.requiredMessage2'), trigger: 'blur' }"> trigger: 'blur',
<el-input v-model="form.value"></el-input> }"
</el-form-item> >
</div> <el-input v-model="form.key" :disabled="true"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="$t('views.document.tag.value')"
prop="value"
:rules="{
required: true,
message: $t('views.document.tag.requiredMessage2'),
trigger: 'blur',
}"
>
<el-input v-model="form.value"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -39,12 +63,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { useRoute } from "vue-router"; import { useRoute } from 'vue-router'
import { loadSharedApi } from "@/utils/dynamics-api/shared-api.ts"; import { loadSharedApi } from '@/utils/dynamics-api/shared-api.ts'
const route = useRoute() const route = useRoute()
const { const {
params: {id}, // idknowledgeID params: { id }, // idknowledgeID
} = route as any } = route as any
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
@ -62,7 +86,7 @@ const isEditKey = ref(false)
const form = ref({ const form = ref({
id: '', id: '',
key: '', key: '',
value: '' value: '',
}) })
const loading = ref(false) const loading = ref(false)
@ -71,7 +95,7 @@ const dialogVisible = ref<boolean>(false)
const submit = () => { const submit = () => {
FormRef.value.validate((valid: boolean) => { FormRef.value.validate((valid: boolean) => {
if (valid) { if (valid) {
loadSharedApi({type: 'knowledge', systemType: apiType.value}) loadSharedApi({ type: 'knowledge', systemType: apiType.value })
.putTag(id, form.value.id, form.value, loading) .putTag(id, form.value.id, form.value, loading)
.then((res: any) => { .then((res: any) => {
close() close()
@ -93,6 +117,6 @@ const close = () => {
dialogVisible.value = false dialogVisible.value = false
} }
defineExpose({open, close}) defineExpose({ open, close })
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -64,7 +64,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import AppIcon from '@/components/app-icon/AppIcon.vue'
const emit = defineEmits(['addTags']) const emit = defineEmits(['addTags'])
const props = defineProps({ const props = defineProps({

View File

@ -26,45 +26,61 @@
:span-method="spanMethod" :span-method="spanMethod"
v-loading="loading" v-loading="loading"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@cell-mouse-enter="cellMouseEnter"
@cell-mouse-leave="cellMouseLeave"
> >
<el-table-column type="selection" width="55"/> <el-table-column type="selection" width="55"/>
<el-table-column :label="$t('views.document.tag.key')"> <el-table-column :label="$t('views.document.tag.key')">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> <div class="flex-between">
{{ row.key }} {{ row.key }}
<div> <div v-if="currentMouseId === row.id">
<el-button link> <span class="mr-4">
<AppIcon <el-tooltip effect="dark" :content="$t('views.document.tag.addValue')">
iconName="app-add-outlined" <el-button type="primary" text @click.stop="openCreateTagDialog(row)">
class="mr-4" <AppIcon iconName="app-add-outlined" />
@click="openCreateTagDialog(row)" </el-button>
/> </el-tooltip>
</el-button> </span>
<el-button link> <span class="mr-4">
<AppIcon iconName="app-edit" class="mr-4" @click="editTagKey(row)"/> <el-tooltip effect="dark" :content="$t('views.document.tag.edit')">
</el-button> <el-button type="primary" text @click.stop="editTagKey(row)">
<el-button link> <AppIcon iconName="app-edit" />
<AppIcon iconName="app-delete" class="mr-4" @click="delTag(row)"/> </el-button>
</el-button> </el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')">
<el-button type="primary" text @click.stop="delTag(row)">
<AppIcon iconName="app-delete" />
</el-button>
</el-tooltip>
</div> </div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('views.document.tag.value')"> <el-table-column :label="$t('views.document.tag.value')" class-name="border-l">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex-between"> <div class="flex-between">
{{ row.value }} {{ row.value }}
<div>
<el-button link>
<AppIcon iconName="app-edit" class="mr-4" @click="editTagValue(row)"/>
</el-button>
<el-button link>
<AppIcon iconName="app-delete" class="mr-4" @click="delTagValue(row)"/>
</el-button>
</div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('common.operation')" align="left" width="100" fixed="right">
<template #default="{ row }">
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('views.document.tag.editValue')">
<el-button type="primary" text @click.stop="editTagValue(row)">
<AppIcon iconName="app-edit" />
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')">
<el-button type="primary" text @click.stop="delTagValue(row)">
<AppIcon iconName="app-delete" />
</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table> </el-table>
</el-drawer> </el-drawer>
<CreateTagDialog ref="createTagDialogRef" @refresh="getList"/> <CreateTagDialog ref="createTagDialogRef" @refresh="getList"/>
@ -105,6 +121,15 @@ const loading = ref(false)
const debugVisible = ref(false) const debugVisible = ref(false)
const filterText = ref('') const filterText = ref('')
const tags = ref<Array<any>>([]) const tags = ref<Array<any>>([])
const currentMouseId = ref<number | null>(null)
function cellMouseEnter(row: any) {
currentMouseId.value = row.id
}
function cellMouseLeave() {
currentMouseId.value = null
}
// //
const tableData = computed(() => { const tableData = computed(() => {

View File

@ -6,7 +6,7 @@
<div class="flex-between"> <div class="flex-between">
<div> <div>
<el-button type="primary" @click="openAddTagDialog()"> <el-button type="primary" @click="openAddTagDialog()">
{{ $t('views.document.tag.add') }} {{ $t('views.document.tag.addTag') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0" @click="batchDelete"> <el-button :disabled="multipleSelection.length === 0" @click="batchDelete">
{{ $t('common.delete') }} {{ $t('common.delete') }}
@ -57,7 +57,7 @@ import { useRoute } from 'vue-router'
import { loadSharedApi } from "@/utils/dynamics-api/shared-api.ts" import { loadSharedApi } from "@/utils/dynamics-api/shared-api.ts"
import { MsgConfirm } from "@/utils/message.ts"; import { MsgConfirm } from "@/utils/message.ts";
import { t } from "@/locales"; import { t } from "@/locales";
import AddTagDialog from "@/views/document/component/AddTagDialog.vue"; import AddTagDialog from "@/views/document/tag/MulAddTagDialog.vue";
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
const props = defineProps({ const props = defineProps({