Parcourir la source

完成标签组件

zq il y a 11 mois
Parent
commit
182de837c7

+ 167 - 3
src/views/book/courseware/create/components/base/label/Label.vue

@@ -1,22 +1,186 @@
 <template>
   <ModuleBase :type="data.type">
     <template #content>
-      <div></div>
+      <div class="tag-edit">
+        <el-tag
+          v-for="(tag, i) in data.dynamicTags"
+          :key="i"
+          closable
+          :style="{ color: tag.color }"
+          @close="handleClose(i)"
+        >
+          {{ tag.text }}
+        </el-tag>
+        <el-input
+          v-if="inputVisible"
+          ref="saveTagInput"
+          v-model="inputValue"
+          class="input-new-tag"
+          @keyup.enter.native="handleInputConfirm"
+          @blur="handleInputConfirm"
+        />
+        <el-button v-else class="button-new-tag" @click="showInput">+ 添加标签</el-button>
+      </div>
+      <hr style="margin: 16px 0; border-top: 1px solid #ededed" />
+      <div class="tag-manager">
+        <div class="tag-manager-box">
+          <span class="tag-manager-title">常用标签</span>
+          <SvgIcon icon-class="setup" size="14" />
+          <span class="tag-manager-text" @click="editCommonTags()">管理</span>
+        </div>
+        <div class="tag-manager-common tag-edit">
+          <el-tag
+            v-for="(tag, i) in commonTags"
+            :key="i"
+            effect="plain"
+            size="medium"
+            :closable="closable"
+            style="cursor: pointer"
+            @close="handleCloseCommonTag(i)"
+            @click="viewToDynamicTags(i)"
+          >
+            {{ tag.text }}
+          </el-tag>
+        </div>
+      </div>
     </template>
   </ModuleBase>
 </template>
 <script>
-import { getLabelData } from '@/views/book/courseware/data/label';
+import { getLabelData, labelColorList } from '@/views/book/courseware/data/label';
 import ModuleMixin from '../../common/ModuleMixin';
 export default {
   name: 'LabelPage',
   mixins: [ModuleMixin],
   data() {
     return {
+      labelColorList,
       data: getLabelData(),
+      inputVisible: false,
+      inputValue: '',
+      closable: false,
+      commonTags: [], // 常用标签
     };
   },
+  created() {
+    const storedData = localStorage.getItem('commonTags');
+    if (storedData) {
+      this.commonTags = JSON.parse(storedData);
+    }
+  },
+  methods: {
+    // 随机显示颜色
+    getRandomColor() {
+      let randomIndex = Math.floor(Math.random() * (this.labelColorList.length - 1)) + 1;
+      return this.labelColorList[randomIndex].value;
+    },
+    // 删除标签
+    handleClose(i) {
+      this.data.dynamicTags.splice(i, 1);
+    },
+    // 显示编辑标签图标
+    editCommonTags() {
+      this.closable = !this.closable;
+    },
+    // 删除常用标签
+    handleCloseCommonTag(i) {
+      this.commonTags.splice(i, 1);
+      this.saveToLocalStorage();
+    },
+    // 显示新增标签
+    showInput() {
+      this.inputVisible = true;
+      this.$nextTick((_) => {
+        this.$refs.saveTagInput.$refs.input.focus();
+      });
+    },
+    // 新增标签
+    handleInputConfirm() {
+      let inputValue = this.inputValue;
+      let label_color = this.data.property.label_color;
+      if (label_color === 'random') label_color = this.getRandomColor();
+      if (inputValue) {
+        this.data.dynamicTags.push({
+          text: inputValue,
+          color: label_color,
+        });
+        this.commonTags.push({
+          text: inputValue,
+          color: label_color,
+        });
+      }
+      this.inputVisible = false;
+      this.inputValue = '';
+      this.saveToLocalStorage();
+    },
+    // 点击常用标签显示到动态标签里
+    viewToDynamicTags(index) {
+      this.data.dynamicTags.push(this.commonTags[index]);
+    },
+    // 常用标签存储
+    saveToLocalStorage() {
+      // 将数据保存到localStorage中
+      localStorage.setItem('commonTags', JSON.stringify(this.commonTags));
+    },
+  },
 };
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.tag-edit {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+
+  :deep .el-tag {
+    height: 32px;
+    padding: 0 10px;
+    line-height: 30px;
+    color: var(--color1);
+    background-color: #fff;
+    border-color: var(--color1);
+    border-radius: 2px;
+
+    .el-tag__close:hover {
+      // color: #fff;
+      background-color: #ddd;
+    }
+
+    .el-tag__close {
+      color: var(--color1);
+    }
+  }
+
+  .button-new-tag {
+    height: 32px;
+    background-color: #f2f3f3;
+    border: 1px dashed #c9cdd4;
+  }
+
+  .input-new-tag {
+    width: 90px;
+  }
+}
+
+.tag-manager {
+  display: flex;
+  flex-direction: column;
+  row-gap: 10px;
+
+  .tag-manager-box {
+    display: flex;
+    column-gap: 4px;
+    align-items: center;
+    font-size: 14px;
+    font-weight: 500;
+    color: #000;
+    cursor: pointer;
+
+    .tag-manager-title {
+      margin-right: 6px;
+      color: rgba(0, 0, 0, 65%);
+      cursor: text;
+    }
+  }
+}
+</style>

+ 25 - 4
src/views/book/courseware/create/components/base/label/LabelSetting.vue

@@ -27,9 +27,15 @@
         <SerialNumberPosition :position="property.sn_position" @changeNumberPosition="changeNumberPosition" />
       </el-form-item>
       <el-divider />
-      <el-form-item label="标签颜色">
-        <el-select v-model="property.label_color">
-          <el-option label="随机" value="random" />
+      <el-form-item label="标签颜色" :style="cssVars">
+        <el-select v-model="property.label_color" class="label-color">
+          <el-option
+            v-for="(color, i) in labelColorList"
+            :key="i"
+            :label="color.label"
+            :value="color.value"
+            :style="{ color: color.value === 'random' ? '#000' : color.value }"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="标签字体">
@@ -44,7 +50,7 @@
 <script>
 import SettingMixin from '@/views/book/courseware/create/components/common/SettingMixin';
 import { snGenerationMethodList } from '@/views/book/courseware/data/common';
-import { getLabelProperty } from '@/views/book/courseware/data/label';
+import { getLabelProperty, labelColorList } from '@/views/book/courseware/data/label';
 
 export default {
   name: 'LabelSetting',
@@ -52,10 +58,19 @@ export default {
   data() {
     return {
       snGenerationMethodList,
+      labelColorList,
       labelPosition: 'left',
       property: getLabelProperty(),
     };
   },
+  computed: {
+    cssVars() {
+      let _color = this.property.label_color;
+      return {
+        '--color1': _color === 'random' ? '#000' : _color,
+      };
+    },
+  },
   methods: {},
 };
 </script>
@@ -65,5 +80,11 @@ export default {
 
 .el-form {
   @include setting-base;
+
+  .label-color {
+    :deep .el-input__inner {
+      color: var(--color1) !important;
+    }
+  }
 }
 </style>

+ 1 - 0
src/views/book/courseware/create/components/common/ModuleBase.vue

@@ -204,6 +204,7 @@ export default {
     }
 
     &-content {
+      position: relative;
       padding: 8px;
       background-color: #fff;
 

+ 1 - 1
src/views/book/courseware/create/components/common/SettingMixin.js

@@ -7,7 +7,7 @@ import SelectSerialNumberStyle from '@/views/book/courseware/create/components/b
 const mixin = {
   data() {
     return {
-      param: {}, // 组件设置时传过来的特有参数
+      param: {},
       switchSerialNumber,
       computedQuestionNumber,
       snGenerationMethodList,

+ 17 - 1
src/views/book/courseware/data/label.js

@@ -13,7 +13,7 @@ export function getLabelProperty() {
     // 序号样式 solidBlockStyle实心方块 solidCircleStyle实心圆 hollowBlockStyle空心方块 hollowCircleStyle空心圆 defaultStyle默认无
     sn_style: 'solidBlockStyle',
     sn_background_color: '#ea3232', // 序号背景色
-    label_color: '随机', // 标签颜色
+    label_color: 'random', // 标签颜色:random随机、#F53F3F等部分定义好的颜色
     label_font: '中文', // 标签字体
   };
 }
@@ -22,6 +22,22 @@ export function getLabelData() {
   return {
     type: 'label',
     title: '标签',
+    dynamicTags: [], // 标签内容 {text:'标准',color:'#F53F3F'}
+    commonTags: [], // 常用标签{text:'标准',color:'#F53F3F'}(目前存储在本地缓存)
     property: getLabelProperty(),
   };
 }
+
+// 标签常用颜色
+export const labelColorList = [
+  { label: '随机', value: 'random' },
+  { label: '#F53F3F', value: '#F53F3F' },
+  { label: '#00B42A', value: '#00B42A' },
+  { label: '#0FC6C2', value: '#0FC6C2' },
+  { label: '#FF7D00', value: '#FF7D00' },
+  { label: '#F7BA1E', value: '#F7BA1E' },
+  { label: '#722ED1', value: '#722ED1' },
+  { label: '#F5319D', value: '#F5319D' },
+  { label: '#165DFF', value: '#165DFF' },
+  { label: '#3491FA', value: '#3491FA' },
+];

+ 21 - 1
src/views/book/courseware/preview/components/label/LabelPreview.vue

@@ -1,7 +1,11 @@
 <template>
   <div class="label-preview" :style="getAreaStyle()">
     <SerialNumberPosition :property="data.property" />
-    <div class="main"></div>
+    <div class="main">
+      <el-tag v-for="(tag, i) in data.dynamicTags" :key="i" :style="{ color: tag.color }">
+        {{ tag.text }}
+      </el-tag>
+    </div>
   </div>
 </template>
 
@@ -26,5 +30,21 @@ export default {
 
 .label-preview {
   @include preview-base;
+
+  .main {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+
+    :deep .el-tag {
+      height: 32px;
+      padding: 0 10px;
+      line-height: 30px;
+      color: var(--color1);
+      background-color: #fff;
+      border-color: var(--color1);
+      border-radius: 2px;
+    }
+  }
 }
 </style>