소스 검색

标签组件 新增 导入增删查到数据库

zq 2 일 전
부모
커밋
208220ff43
2개의 변경된 파일207개의 추가작업 그리고 38개의 파일을 삭제
  1. 206 37
      src/views/book/courseware/create/components/base/label/Label.vue
  2. 1 1
      src/views/book/courseware/preview/components/label/LabelPreview.vue

+ 206 - 37
src/views/book/courseware/create/components/base/label/Label.vue

@@ -9,7 +9,7 @@
           :style="{ color: tag.color }"
           @close="handleClose(i)"
         >
-          {{ tag.text }}
+          {{ tag.name }}
         </el-tag>
         <el-input
           v-if="inputVisible"
@@ -19,14 +19,39 @@
           @keyup.enter.native="handleInputConfirm"
           @blur="handleInputConfirm"
         />
-        <el-button v-else class="button-new-tag" @click="showInput">+ 添加标签</el-button>
+        <el-button
+          v-else
+          class="button-new-tag"
+          :disabled="data.dynamicTags.length >= 16"
+          @click="showAddLabelTextInput"
+          >+ 添加标签</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 class="left-area">
+            <span class="tag-manager-title">常用标签 </span>
+            <span class="tag-manager-text" @click="editCommonTags()">
+              <SvgIcon icon-class="setup" size="14" />管理
+            </span>
+          </div>
+          <div class="right-area">
+            <el-upload
+              class=""
+              action="no"
+              :auto-upload="true"
+              :before-upload="beforeUpload"
+              :http-request="customUpload"
+              :show-file-list="false"
+              accept=".xls"
+            >
+              <el-button icon="el-icon-upload2">上传标签</el-button>
+            </el-upload>
+            <el-input v-model="labelName" placeholder="输入关键字" class="search-box">
+              <el-button slot="append" icon="el-icon-search" @click="getLabelList()" />
+            </el-input>
+          </div>
         </div>
         <div class="tag-manager-common tag-edit">
           <el-tag
@@ -36,18 +61,35 @@
             size="medium"
             :closable="closable"
             style="cursor: pointer"
-            @close="handleCloseCommonTag(i)"
+            @close="handleCloseCommonTag(tag.id)"
             @click="viewToDynamicTags(i)"
           >
-            {{ tag.text }}
+            {{ tag.name }}
           </el-tag>
         </div>
+        <p v-if="loading">加载中...</p>
+        <div class="block">
+          <el-pagination
+            background
+            :current-page="cur_page"
+            :page-sizes="[20, 40, 60, 80]"
+            :page-size="page_capacity"
+            layout="total, prev, pager, next, sizes, jumper"
+            :total="total_count"
+            @prev-click="changePage"
+            @next-click="changePage"
+            @current-change="changePage"
+            @size-change="changePageSize"
+          />
+        </div>
       </div>
     </template>
   </ModuleBase>
 </template>
 <script>
+import { fileUpload } from '@/api/app';
 import { getLabelData, labelColorList } from '@/views/book/courseware/data/label';
+import { AddLabel, DeleteLabel, PageQueryLabelList, ImportLabel } from '@/api/project.js';
 import ModuleMixin from '../../common/ModuleMixin';
 export default {
   name: 'LabelPage',
@@ -60,13 +102,15 @@ export default {
       inputValue: '',
       closable: false,
       commonTags: [], // 常用标签
+      page_capacity: 20,
+      cur_page: 1,
+      total_count: 0,
+      loading: false,
+      labelName: '',
     };
   },
   created() {
-    const storedData = localStorage.getItem('commonTags');
-    if (storedData) {
-      this.commonTags = JSON.parse(storedData);
-    }
+    this.getLabelList();
   },
   methods: {
     // 随机显示颜色
@@ -74,7 +118,7 @@ export default {
       let randomIndex = Math.floor(Math.random() * (this.labelColorList.length - 1)) + 1;
       return this.labelColorList[randomIndex].value;
     },
-    // 删除标签
+    // 删除动态标签
     handleClose(i) {
       this.data.dynamicTags.splice(i, 1);
     },
@@ -83,12 +127,24 @@ export default {
       this.closable = !this.closable;
     },
     // 删除常用标签
-    handleCloseCommonTag(i) {
-      this.commonTags.splice(i, 1);
-      this.saveToLocalStorage();
+    handleCloseCommonTag(id) {
+      this.$confirm('确定要删除该标签吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          DeleteLabel({ id }).then(() => {
+            this.getLabelList();
+            this.$message.success('删除成功!');
+          });
+        })
+        .catch((e) => {
+          console.error(e);
+        });
     },
-    // 显示新增标签
-    showInput() {
+    // 显示新增标签输入框
+    showAddLabelTextInput() {
       this.inputVisible = true;
       this.$nextTick(() => {
         this.$refs.saveTagInput.$refs.input.focus();
@@ -96,31 +152,118 @@ export default {
     },
     // 新增标签
     handleInputConfirm() {
-      let inputValue = this.inputValue;
+      let inputValue = this.inputValue.trim();
       let label_color = this.data.property.label_color;
       if (label_color === 'random') label_color = this.getRandomColor();
+      let dynamicTags = this.data.dynamicTags;
       if (inputValue) {
-        this.data.dynamicTags.push({
-          text: inputValue,
-          color: label_color,
-        });
-        this.commonTags.push({
-          text: inputValue,
-          color: label_color,
-        });
+        // 检查是否已存在相同标签(不区分大小写)
+        const existingTag = dynamicTags.find((tag) => tag.name === inputValue);
+        if (existingTag) {
+          this.$message.warning('常用标签已包含该标签,无需重复添加');
+        } else {
+          dynamicTags.push({
+            name: inputValue,
+            color: label_color,
+          });
+          this.addLabel(inputValue);
+        }
       }
       this.inputVisible = false;
       this.inputValue = '';
-      this.saveToLocalStorage();
     },
     // 点击常用标签显示到动态标签里
     viewToDynamicTags(index) {
-      this.data.dynamicTags.push(this.commonTags[index]);
+      if (this.data.dynamicTags.length >= 16) {
+        this.$message.warning('最多添加16个标签!');
+        return false;
+      }
+      // 检查是否已存在相同标签(不区分大小写)
+      let dynamicTags = this.data.dynamicTags;
+      let commonTag = this.commonTags[index].name;
+      const existingTag = dynamicTags.find((tag) => tag.name === commonTag);
+      if (existingTag) {
+        this.$message.warning('组件标签已包含该标签,无需重复加入');
+      } else {
+        let label_color = this.data.property.label_color;
+        if (label_color === 'random') label_color = this.getRandomColor();
+        this.data.dynamicTags.push({
+          name: commonTag,
+          color: label_color,
+        });
+      }
+    },
+    // 得到标签列表
+    getLabelList() {
+      let param_data = {
+        page_capacity: this.page_capacity,
+        cur_page: this.cur_page,
+        name: this.labelName,
+      };
+      PageQueryLabelList(param_data)
+        .then(({ total_count, label_list }) => {
+          this.total_count = total_count;
+          this.commonTags = label_list;
+        })
+        .catch(() => {
+          // 如果请求失败,回退页码
+          this.cur_page -= 1;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    changePage(number) {
+      this.cur_page = number;
+      this.getLabelList();
     },
-    // 常用标签存储
-    saveToLocalStorage() {
-      // 将数据保存到localStorage中
-      localStorage.setItem('commonTags', JSON.stringify(this.commonTags));
+    changePageSize(size) {
+      this.page_capacity = size;
+      this.getLabelList();
+    },
+    // 存储标签到系统
+    addLabel(name) {
+      AddLabel({ name })
+        .then(() => {
+          this.cur_page = 1;
+          this.getLabelList();
+        })
+        .catch((e) => {
+          console.error(e);
+        });
+    },
+    // 文件类型校验
+    beforeUpload(file) {
+      if (file.length > 0) {
+        this.$message.warning('只能上传一个表格文件');
+        return false;
+      }
+      const fileName = file.name;
+      const suffix = fileName.slice(fileName.lastIndexOf('.') + 1, fileName.length).toLowerCase();
+      //  , 'xlsx', 'csv'
+      if (!['xls'].includes(suffix)) {
+        this.$message.warning('文件格式不正确');
+        return false;
+      }
+    },
+    // 上传标签
+    customUpload(file) {
+      fileUpload('Mid', file, { isGlobalprogress: true }).then(({ file_info_list }) => {
+        // console.log(file_info_list);
+        if (file_info_list.length > 0) {
+          let file_id = file_info_list[0].file_id;
+          ImportLabel({ file_id })
+            .then(() => {
+              this.$message.success('导入成功!');
+              this.cur_page = 1;
+              this.getLabelList();
+            })
+            .catch((e) => {
+              this.$message.error(e);
+              console.error(e);
+            });
+        }
+      });
     },
   },
 };
@@ -169,17 +312,43 @@ export default {
 
   .tag-manager-box {
     display: flex;
-    column-gap: 4px;
+    column-gap: 10px;
     align-items: center;
+    justify-content: space-between;
     font-size: 14px;
     font-weight: 500;
     color: #000;
     cursor: pointer;
 
-    .tag-manager-title {
-      margin-right: 6px;
-      color: rgba(0, 0, 0, 65%);
-      cursor: text;
+    .left-area {
+      display: flex;
+      column-gap: 10px;
+      align-items: center;
+
+      .tag-manager-title {
+        color: rgba(0, 0, 0, 65%);
+        cursor: text;
+      }
+
+      .tag-manager-text {
+        display: flex;
+        column-gap: 2px;
+        align-items: center;
+      }
+    }
+
+    .right-area {
+      display: flex;
+      column-gap: 10px;
+
+      .search-box {
+        width: 200px;
+
+        :deep input {
+          background-color: #fff;
+          border-color: #dcdcdc;
+        }
+      }
     }
   }
 }

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

@@ -3,7 +3,7 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
     <div class="main">
       <el-tag v-for="(tag, i) in data.dynamicTags" :key="i" :style="{ color: tag.color }">
-        {{ tag.text }}
+        {{ tag.name }}
       </el-tag>
     </div>
   </div>