|
@@ -1,288 +1,142 @@
|
|
|
<template>
|
|
|
- <div v-show="modelValue" class="edit-container">
|
|
|
- <div class="edit-header">
|
|
|
- <div class="title">视频标签</div>
|
|
|
- <i class="close" @click="handleClose" />
|
|
|
+ <Dialog v-model="show" title="视频标签" height="auto" @close="handleClose" @confirm="handleAdd">
|
|
|
+ <div class="title-box">
|
|
|
+ <div class="title">当前标签</div>
|
|
|
</div>
|
|
|
- <div class="edit-content">
|
|
|
- <div class="title-box">
|
|
|
- <div class="title">当前标签</div>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <div v-for="(item, index) in tags" :key="index" class="tag">{{ item.dict_label }}</div>
|
|
|
- </div>
|
|
|
- <div class="title-box">
|
|
|
- <div class="title">新增标签</div>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <el-select
|
|
|
- v-model="addTag2"
|
|
|
- :teleported="false"
|
|
|
- class="custom-select"
|
|
|
- popper-class="custom-select-popper"
|
|
|
- style="width: 300px; margin-left: 10px"
|
|
|
- >
|
|
|
- <el-option v-for="item in video_type" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- <div class="common-btn-primary" @click="handleAdd3">添加</div>
|
|
|
- </div>
|
|
|
- <div class="title-box">
|
|
|
- <div class="title">新建标签</div>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <div class="tag">{{ addTag }}</div>
|
|
|
- <el-input v-model="addTag" class="custom-input" placeholder="不超过20个字,回车添加" @keyup.enter="handleAdd"></el-input>
|
|
|
- </div>
|
|
|
- <div class="title-box2">
|
|
|
- <div class="title">最近标签</div>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <div v-for="(item, index) in recentTags" :key="index" class="tag" @click="handleAdd2(item)">{{ item.dict_label }}</div>
|
|
|
- </div>
|
|
|
- <div class="title-box3">
|
|
|
- <i class="icon-type" />
|
|
|
- <div class="title">类型</div>
|
|
|
- <el-select
|
|
|
- v-model="type"
|
|
|
- :teleported="false"
|
|
|
- class="custom-select"
|
|
|
- popper-class="custom-select-popper"
|
|
|
- style="width: 140px; margin-bottom: 10px"
|
|
|
- >
|
|
|
- <el-option label="全部" value="lx" />
|
|
|
- <el-option v-for="item in video_tag_type" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <div v-for="(item, index) in typeTags" :key="index" class="tag" @click="handleAdd2(item)">{{ item.dict_label }}</div>
|
|
|
- </div>
|
|
|
- <div class="title-box3">
|
|
|
- <i class="icon-industry" />
|
|
|
- <div class="title">行业</div>
|
|
|
- <el-select
|
|
|
- v-model="industry"
|
|
|
- :teleported="false"
|
|
|
- class="custom-select"
|
|
|
- popper-class="custom-select-popper"
|
|
|
- style="width: 140px; margin-bottom: 10px"
|
|
|
- >
|
|
|
- <el-option label="全部" value="hy" />
|
|
|
- <el-option v-for="item in video_tag_industry" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <div class="tags">
|
|
|
- <div v-for="(item, index) in industryTags" :key="index" class="tag" @click="handleAdd2(item)">{{ item.dict_label }}</div>
|
|
|
+ <div v-if="selectTags && selectTags.length > 0" class="tags">
|
|
|
+ <div v-for="(item, index) in selectTags" :key="index" class="tagActive">{{ item.label }}</div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="empty-text">暂无标签</div>
|
|
|
+ <div class="title-box" style="margin-top: 20px">
|
|
|
+ <div class="title">添加标签</div>
|
|
|
+ </div>
|
|
|
+ <div class="tags">
|
|
|
+ <div v-for="item in videoType" :key="item.value" :class="!!item.checked ? 'tagActive' : 'tag'" @click="handleSelect(item)">
|
|
|
+ {{ item.label }}
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </Dialog>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup name="VideoTagEdit">
|
|
|
-import { addVideoTag, addVideoTagLabel, getLxHyVideoTagInfo, getRecentlyVideoTagInfo } from '@/api/videoMonitor';
|
|
|
-import { showSuccessMsg } from '@/utils/notification';
|
|
|
+import { addVideoTag } from '@/api/videoMonitor';
|
|
|
+import { getDicts } from '@/api/system/dict/data';
|
|
|
|
|
|
-const props = defineProps({
|
|
|
- modelValue: Boolean,
|
|
|
- tags: [],
|
|
|
- id: String
|
|
|
-});
|
|
|
-const emits = defineEmits(['update:modelValue', 'updateVideoTag']);
|
|
|
-const proxy = getCurrentInstance()?.proxy;
|
|
|
-const { video_type, video_tag_type, video_tag_industry } = toRefs<any>(proxy?.useDict('video_type', 'video_tag_type', 'video_tag_industry'));
|
|
|
-let addTag = ref('');
|
|
|
-let addTag2 = ref('');
|
|
|
-let recentTags = ref([]);
|
|
|
-let type = ref('lx');
|
|
|
-let typeTags = ref([]);
|
|
|
-let industry = ref('hy');
|
|
|
-let industryTags = ref([]);
|
|
|
+interface Tag {
|
|
|
+ dict_label: string;
|
|
|
+ dict_value: string;
|
|
|
+}
|
|
|
+interface Props {
|
|
|
+ modelValue: boolean;
|
|
|
+ tags: Tag[];
|
|
|
+ id: string;
|
|
|
+}
|
|
|
|
|
|
-const getTypeList = () => {
|
|
|
- getLxHyVideoTagInfo({ dict_value: type.value }).then((res) => {
|
|
|
- typeTags.value = res.data;
|
|
|
- });
|
|
|
-};
|
|
|
-const getIndustryList = () => {
|
|
|
- getLxHyVideoTagInfo({ dict_value: industry.value }).then((res) => {
|
|
|
- industryTags.value = res.data;
|
|
|
- });
|
|
|
-};
|
|
|
-watch(
|
|
|
- () => props.id,
|
|
|
- () => {
|
|
|
- if (!!props.id) {
|
|
|
- getRecentlyVideoTagInfo().then((res) => {
|
|
|
- recentTags.value = res.data;
|
|
|
- });
|
|
|
- getTypeList();
|
|
|
- getIndustryList();
|
|
|
- } else {
|
|
|
- addTag.value = '';
|
|
|
- recentTags.value = [];
|
|
|
- typeTags.value = [];
|
|
|
- industryTags.value = [];
|
|
|
- }
|
|
|
+const props = defineProps<Props>();
|
|
|
+const emits = defineEmits(['update:modelValue', 'updateVideoTag']);
|
|
|
+let videoType = ref([]);
|
|
|
+const show = computed({
|
|
|
+ get() {
|
|
|
+ return props.modelValue;
|
|
|
},
|
|
|
- {
|
|
|
- immediate: true
|
|
|
+ set(newValue) {
|
|
|
+ emits('update:modelValue', newValue);
|
|
|
}
|
|
|
-);
|
|
|
+});
|
|
|
+let selectTags = ref([]);
|
|
|
+
|
|
|
//关闭
|
|
|
const handleClose = () => {
|
|
|
emits('update:modelValue', false);
|
|
|
};
|
|
|
+// 选择
|
|
|
+const handleSelect = (item) => {
|
|
|
+ item.checked = !item.checked;
|
|
|
+ const index = selectTags.value.findIndex((item2) => item2.value === item.value);
|
|
|
+ if (!!item.checked) {
|
|
|
+ if (index === -1) {
|
|
|
+ selectTags.value.push(item);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (index >= 0) {
|
|
|
+ selectTags.value.splice(index, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
const handleAdd = () => {
|
|
|
- addVideoTagLabel({
|
|
|
- video_code: props.id,
|
|
|
- dict_label: addTag.value,
|
|
|
- dict_type: 'video_type'
|
|
|
- }).then(() => {
|
|
|
- proxy.$modal.msgSuccess('新增成功');
|
|
|
- emits('updateVideoTag');
|
|
|
+ const tagsId = [];
|
|
|
+ selectTags.value.forEach((item) => {
|
|
|
+ tagsId.push(item.value);
|
|
|
});
|
|
|
- addTag.value = '';
|
|
|
-};
|
|
|
-const handleAdd2 = (item) => {
|
|
|
- addVideoTag({ video_code: props.id, dict_value: item.dict_value, dict_type: 'video_type' }).then(() => {
|
|
|
- proxy.$modal.msgSuccess('新增成功');
|
|
|
+ addVideoTag({ video_code: props.id, dict_value: tagsId, dict_type: 'video_type' }).then(() => {
|
|
|
+ showSuccessMsg('新增成功');
|
|
|
emits('updateVideoTag');
|
|
|
+ handleClose();
|
|
|
});
|
|
|
};
|
|
|
-const handleAdd3 = () => {
|
|
|
- addVideoTag({ video_code: props.id, dict_value: addTag2.value, dict_type: 'video_type' }).then(() => {
|
|
|
- proxy.$modal.msgSuccess('新增成功');
|
|
|
- emits('updateVideoTag');
|
|
|
+
|
|
|
+const getTagList = () => {
|
|
|
+ getDicts('video_type').then((res) => {
|
|
|
+ let data = [];
|
|
|
+ let data2 = [];
|
|
|
+ res.data.forEach((item) => {
|
|
|
+ const checked = !!props.tags && props.tags.findIndex((item2) => item2.dict_value === item.dictValue) > -1;
|
|
|
+ const obj = { label: item.dictLabel, value: item.dictValue, checked: checked };
|
|
|
+ if (!!checked) {
|
|
|
+ data2.push(obj);
|
|
|
+ }
|
|
|
+ data.push(obj);
|
|
|
+ });
|
|
|
+ videoType.value = data;
|
|
|
+ selectTags.value = data2;
|
|
|
});
|
|
|
};
|
|
|
+onMounted(() => {
|
|
|
+ getTagList();
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.edit-container {
|
|
|
- position: absolute;
|
|
|
- top: 50%;
|
|
|
- left: 50%;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- z-index: 100;
|
|
|
- width: 407px;
|
|
|
- height: 602px;
|
|
|
- background: url('@/assets/images/videoTagEdit/box1.png') no-repeat;
|
|
|
+.title-box {
|
|
|
+ width: 379px;
|
|
|
+ height: 39px;
|
|
|
+ background: url('@/assets/images/map/titleBox3.png') no-repeat;
|
|
|
background-size: 100% 100%;
|
|
|
- .edit-header {
|
|
|
- height: 40px;
|
|
|
+ padding-left: 22px;
|
|
|
+ .title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ padding-top: 6px;
|
|
|
+ padding-left: 3px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.tags {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: -5px;
|
|
|
+ .tag {
|
|
|
+ background: url('@/assets/images/map/tag2.png') no-repeat;
|
|
|
+ }
|
|
|
+ .tagActive {
|
|
|
+ background: url('@/assets/images/map/tag.png') no-repeat;
|
|
|
+ }
|
|
|
+ .tag,
|
|
|
+ .tagActive {
|
|
|
+ min-width: 146px;
|
|
|
+ height: 30px;
|
|
|
+ background-size: 100% 100%;
|
|
|
display: flex;
|
|
|
- justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- padding: 0 20px;
|
|
|
- position: relative;
|
|
|
- .title {
|
|
|
- color: transparent;
|
|
|
- background-image: linear-gradient(to bottom, #ffffff 30%, #edf7fe 50%, #5cc4fa 70%, #40a2e7 100%);
|
|
|
- -webkit-background-clip: text;
|
|
|
- background-clip: text;
|
|
|
- display: inline-block;
|
|
|
- font-family: 'YouSheBiaoTiHei';
|
|
|
- font-size: 24px;
|
|
|
- }
|
|
|
- .close {
|
|
|
- width: 16px;
|
|
|
- height: 16px;
|
|
|
- background: url('@/assets/images/videoTagEdit/close.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- &::before {
|
|
|
- content: '';
|
|
|
- width: 43px;
|
|
|
- height: 18px;
|
|
|
- background: url('@/assets/images/videoTagEdit/line1.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- position: absolute;
|
|
|
- bottom: -8px;
|
|
|
- left: 0;
|
|
|
- }
|
|
|
- &::after {
|
|
|
- content: '';
|
|
|
- width: calc(100% - 83px);
|
|
|
- height: 2px;
|
|
|
- background: url('@/assets/images/videoTagEdit/line2.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 47px;
|
|
|
- }
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 6px;
|
|
|
+ padding: 0 6px 0 5px;
|
|
|
+ cursor: pointer;
|
|
|
}
|
|
|
- .edit-content {
|
|
|
- margin-top: 10px;
|
|
|
- height: 500px;
|
|
|
- overflow-y: auto;
|
|
|
- .title-box {
|
|
|
- width: 379px;
|
|
|
- height: 39px;
|
|
|
- background: url('@/assets/images/map/titleBox3.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- padding-left: 30px;
|
|
|
- margin-top: 10px;
|
|
|
- .title {
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
- }
|
|
|
- .title-box2 {
|
|
|
- width: 135px;
|
|
|
- height: 24px;
|
|
|
- background: url('@/assets/images/map/rightMenu/titleBox2.png') no-repeat bottom left;
|
|
|
- background-size: 135px 20px;
|
|
|
- padding-left: 30px;
|
|
|
- margin-top: 10px;
|
|
|
- .title {
|
|
|
- font-size: 16px;
|
|
|
- color: #96aac1;
|
|
|
- }
|
|
|
- }
|
|
|
- .title-box3 {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-top: 10px;
|
|
|
- .title {
|
|
|
- font-size: 16px;
|
|
|
- color: #96aac1;
|
|
|
- margin: 0 6px;
|
|
|
- }
|
|
|
- .icon-type {
|
|
|
- width: 28px;
|
|
|
- height: 26px;
|
|
|
- background: url('@/assets/images/videoTagEdit/type.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- }
|
|
|
- .icon-industry {
|
|
|
- width: 26px;
|
|
|
- height: 27px;
|
|
|
- background: url('@/assets/images/videoTagEdit/industry.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- }
|
|
|
- }
|
|
|
- .tags {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- align-items: center;
|
|
|
- margin-top: -5px;
|
|
|
- .tag {
|
|
|
- min-width: 126px;
|
|
|
- height: 26px;
|
|
|
- background: url('@/assets/images/map/tag.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- margin-top: 10px;
|
|
|
- padding: 0 20px 0 15px;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- .custom-input {
|
|
|
- width: 230px;
|
|
|
- margin-left: 20px;
|
|
|
- margin-top: 10px;
|
|
|
- }
|
|
|
- }
|
|
|
+ .custom-input {
|
|
|
+ width: 222px;
|
|
|
+ margin-left: 6px;
|
|
|
+ margin-top: 6px;
|
|
|
}
|
|
|
}
|
|
|
</style>
|