|
@@ -0,0 +1,353 @@
|
|
|
+<template>
|
|
|
+ <div class="collect-tag-selector">
|
|
|
+ <div class="select-group-container">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in tagsList"
|
|
|
+ :key="index"
|
|
|
+ class="j-button-item"
|
|
|
+ :class="{
|
|
|
+ active: item.selected,
|
|
|
+ all: item.name === '全部'
|
|
|
+ }"
|
|
|
+ @click="buttonClick(item)"
|
|
|
+ >
|
|
|
+ {{ item.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <span class="manage-button" @click="onManageClick">标签管理</span>
|
|
|
+ <DrawerCard
|
|
|
+ customClass="drawer-class"
|
|
|
+ percent="600px"
|
|
|
+ :title="calcTitle"
|
|
|
+ :with-header="false"
|
|
|
+ confirmText="确定"
|
|
|
+ v-model="showDrawer"
|
|
|
+ @close="onCloseDrawer"
|
|
|
+ @saveData="onSaveDrawer"
|
|
|
+ >
|
|
|
+ <div class="tag-header flex">
|
|
|
+ <el-input
|
|
|
+ placeholder="输入标签"
|
|
|
+ v-model.trim="addTagInput"
|
|
|
+ maxlength="10"
|
|
|
+ clearable
|
|
|
+ @keyup.enter.native="addTagConfirmed">
|
|
|
+ </el-input>
|
|
|
+ <div class="add-tag-confirm-button flex no-select" @click="addTagConfirmed">确认添加</div>
|
|
|
+ </div>
|
|
|
+ <div class="tag-main">
|
|
|
+ <el-tag
|
|
|
+ :key="tag.value"
|
|
|
+ v-for="tag in drawerTags"
|
|
|
+ closable
|
|
|
+ type="info"
|
|
|
+ :disable-transitions="false"
|
|
|
+ @close="delThisTag(tag)">
|
|
|
+ {{ tag.name }} ( {{ tag.count }} )
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </DrawerCard>
|
|
|
+ <vDialog
|
|
|
+ customClass="custom-dialog"
|
|
|
+ width="380px"
|
|
|
+ top="30vh"
|
|
|
+ center
|
|
|
+ title="删除标签"
|
|
|
+ :show-close="false"
|
|
|
+ :visible.sync="dialog.delete"
|
|
|
+ @cancel="onDialogCancel"
|
|
|
+ @confirm="onDialogConfirm"
|
|
|
+ >
|
|
|
+ <div class="dialog-content">
|
|
|
+ <span v-if="currentItem.count === 0">确定删除{{currentItem.name ? ('“' + currentItem.name + '”') : '该'}}标签?</span>
|
|
|
+ <span v-else>警告:当前有{{currentItem.count}}条标讯使用了该标签,如果删除标签,那么对应的标讯也将删除该关联标签。</span>
|
|
|
+ </div>
|
|
|
+ </vDialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { Input, Tag, Dialog } from 'element-ui'
|
|
|
+import DrawerCard from '@/components/drawer/Drawer'
|
|
|
+import vDialog from '@/components/dialog/Dialog'
|
|
|
+export default {
|
|
|
+ name: 'CollectTags',
|
|
|
+ components: {
|
|
|
+ [Input.name]: Input,
|
|
|
+ [Tag.name]: Tag,
|
|
|
+ [Dialog.name]: Dialog,
|
|
|
+ DrawerCard,
|
|
|
+ vDialog
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ sourceList: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ singleChoice: {
|
|
|
+ // 是是否单选
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ tagsList: [],
|
|
|
+ defaultItemExp: {
|
|
|
+ name: '全部',
|
|
|
+ value: '',
|
|
|
+ selected: true
|
|
|
+ },
|
|
|
+ showDrawer: false,
|
|
|
+ addTagInput: '',
|
|
|
+ dialog: {
|
|
|
+ delete: false,
|
|
|
+ already: false
|
|
|
+ },
|
|
|
+ currentItem: {
|
|
|
+ name: '',
|
|
|
+ value: '',
|
|
|
+ count: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ model: {
|
|
|
+ prop: 'value',
|
|
|
+ event: 'change'
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ calcTitle() {
|
|
|
+ return `标签管理 <em class="highlight-text">${this.tagsList.length}</em>`
|
|
|
+ },
|
|
|
+ drawerTags() {
|
|
|
+ return this.tagsList.filter(item => item.name !== '全部')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value(val) {
|
|
|
+ this.setState(val)
|
|
|
+ },
|
|
|
+ sourceList() {
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.init()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() {
|
|
|
+ const list = [JSON.parse(JSON.stringify(this.defaultItemExp))]
|
|
|
+ this.sourceList.forEach((item) => {
|
|
|
+ list.push({
|
|
|
+ name: item.name,
|
|
|
+ value: item.value,
|
|
|
+ count: item.count,
|
|
|
+ selected: false
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.tagsList = list
|
|
|
+ },
|
|
|
+ buttonClick(item) {
|
|
|
+ if (item.name === this.defaultItemExp.name) {
|
|
|
+ this.setState()
|
|
|
+ } else {
|
|
|
+ if (this.singleChoice) {
|
|
|
+ this.setState()
|
|
|
+ this.tagsList[0].selected = false
|
|
|
+ item.selected = !item.selected
|
|
|
+ } else {
|
|
|
+ this.tagsList[0].selected = false
|
|
|
+ item.selected = !item.selected
|
|
|
+
|
|
|
+ // 子项全部选中则全部按钮选中,子项如果一个没有被选中,则全部按钮被选中
|
|
|
+ const { allNotSelected } = this.checkAllSelectedState()
|
|
|
+ if (allNotSelected) {
|
|
|
+ this.setState()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.onChange()
|
|
|
+ },
|
|
|
+ // 除了全部按钮之外的按钮的状态
|
|
|
+ checkAllSelectedState() {
|
|
|
+ const stateArr = []
|
|
|
+
|
|
|
+ this.tagsList.forEach((item) => {
|
|
|
+ if (item.value !== this.defaultItemExp.value) {
|
|
|
+ stateArr.push(item.selected)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ // 找不到false,就说明全部被选中
|
|
|
+ allSelected: stateArr.indexOf(false) === -1,
|
|
|
+ // 找不到true,就说明没有一个被选中
|
|
|
+ allNotSelected: stateArr.indexOf(true) === -1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onChange() {
|
|
|
+ const state = this.getState()
|
|
|
+ this.$emit('change', state)
|
|
|
+ },
|
|
|
+ setState(data = []) {
|
|
|
+ if (!Array.isArray) return
|
|
|
+ if (data.length === 0) {
|
|
|
+ this.tagsList.forEach((item) => (item.selected = false))
|
|
|
+ this.tagsList[0].selected = true
|
|
|
+ } else {
|
|
|
+ this.tagsList[0].selected = false
|
|
|
+ this.tagsList.forEach((item) => {
|
|
|
+ if (data.includes(item.value)) {
|
|
|
+ item.selected = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getState() {
|
|
|
+ const arr = []
|
|
|
+ if (this.tagsList[0].selected) {
|
|
|
+ return arr
|
|
|
+ }
|
|
|
+ return this.tagsList
|
|
|
+ .filter((item) => item.selected)
|
|
|
+ .map((item) => item.value)
|
|
|
+ },
|
|
|
+ onManageClick() {
|
|
|
+ this.$emit('manage')
|
|
|
+ this.showDrawer = true
|
|
|
+ },
|
|
|
+ onCloseDrawer() {
|
|
|
+ this.$emit('close')
|
|
|
+ this.showDrawer = false
|
|
|
+ },
|
|
|
+ onSaveDrawer() {
|
|
|
+ this.$emit('save')
|
|
|
+ this.showDrawer = false
|
|
|
+ },
|
|
|
+ addTagConfirmed() {
|
|
|
+ this.$emit('addTag', this.addTagInput)
|
|
|
+ this.addTagInput = ''
|
|
|
+ },
|
|
|
+ delThisTag(tag) {
|
|
|
+ this.dialog.delete = true
|
|
|
+ this.currentItem = tag
|
|
|
+ },
|
|
|
+ onDialogCancel() {
|
|
|
+ this.dialog.delete = false
|
|
|
+ this.$emit('cancel')
|
|
|
+ },
|
|
|
+ onDialogConfirm() {
|
|
|
+ this.dialog.delete = false
|
|
|
+ this.$emit('delTag', this.currentItem)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.collect-tag-selector{
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ .select-group-container{
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ .j-button-item{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: 0 5px;
|
|
|
+ padding: 1px 8px;
|
|
|
+ line-height: 20px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #F5F6F7;
|
|
|
+ border: 1px solid #ECECEC;
|
|
|
+ color: #1D1D1D;
|
|
|
+ cursor: pointer;
|
|
|
+ &.active,
|
|
|
+ &.hover{
|
|
|
+ background-color: #2abed1;
|
|
|
+ color: #fff;
|
|
|
+ border-color: #2abed1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .manage-button{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 4px 17px;
|
|
|
+ line-height: 22px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #2abed1;
|
|
|
+ color: #fff;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ ::v-deep{
|
|
|
+ .drawer-class{
|
|
|
+ .el-header{
|
|
|
+ padding: 20px;
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 32px;
|
|
|
+ border-bottom: 1px solid #ebebeb;
|
|
|
+ }
|
|
|
+ .tag-header{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 28px 28px 20px;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+ .add-tag-confirm-button{
|
|
|
+ margin-left: 16px;
|
|
|
+ height: 100%;
|
|
|
+ color: #2CB7CA;
|
|
|
+ white-space: nowrap;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .tag-main{
|
|
|
+ padding: 0 20px;
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: scroll;
|
|
|
+ .el-tag {
|
|
|
+ margin: 6px;
|
|
|
+ padding: 1px 8px;
|
|
|
+ height: auto;
|
|
|
+ color: #1d1d1d;
|
|
|
+ background-color: #f5f6f7;
|
|
|
+ border: 1px solid #ececec;
|
|
|
+ border-radius: 5px;
|
|
|
+ line-height: 22px;
|
|
|
+ cursor: pointer;
|
|
|
+ &:hover {
|
|
|
+ color: #2CB7CA;
|
|
|
+ border-color: #2CB7CA;
|
|
|
+ .el-icon-close {
|
|
|
+ color: #2CB7CA;
|
|
|
+ background: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .custom-dialog{
|
|
|
+ .dialog-content{
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .el-dialog__footer{
|
|
|
+ padding-bottom: 40px;
|
|
|
+ .dialog-footer{
|
|
|
+ flex-direction: row-reverse;
|
|
|
+ }
|
|
|
+ .action-button:not(:last-of-type){
|
|
|
+ margin-right: 0;
|
|
|
+ margin-left: 48px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|