ApprovalComments.vue 7.07 KB
<template>
  <div class="approval-comments">
    <ht-input
      ref="opinionInput"
      v-model="opinion"
      type="textarea"
      display-style="block"
      placeholder="请输入意见内容......"
      name="审批意见"
      validate="required"
      :maxlength="approvalMaxlength"
      :max="approvalMaxlength"
      show-word-limit
      :autosize="{ minRows: 8 }"
    />
    <div class="common-words">
      <template v-for="commonOpinion in commonWordsList">
        <el-tag
          v-if="commonOpinion.length > 7"
          :key="commonOpinion"
          :title="commonOpinion"
          effect="plain"
          type="info"
          @click.native="choseCommonOpinion(commonOpinion)"
        >
          {{ commonOpinion.substring(0, 7) }}...
        </el-tag>
        <el-tag
          v-else
          :key="commonOpinion"
          effect="plain"
          type="info"
          @click.native="choseCommonOpinion(commonOpinion)"
        >
          {{ commonOpinion }}
        </el-tag>
      </template>
    </div>
    <div class="common-words-btns">
      <el-dropdown
        v-if="moreTagList && moreTagList.length"
        trigger="click"
        @command="choseCommonOpinion"
      >
        <i class="icon-daohanglan-gengduo more-dropdown-icon"></i>
        <el-dropdown-menu slot="dropdown" class="common-words__dropdown">
          <el-dropdown-item
            v-for="(item, index) in moreTagList"
            :key="index"
            :command="item"
          >
            {{ item }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-button
        title="添加常用语"
        icon="el-icon-plus"
        size="small"
        @click="addCommonOpinion"
      />
    </div>
  </div>
</template>
<script>
  import {
    savaCommonWords,
    getCommonWordsByDefKeyAndTypeId,
  } from '@/api/commonWords'
  export default {
    name: 'ApprovalComments',
    props: {
      defKey: {
        type: String,
        default: '',
      },
      approvalOpinion: {
        type: String,
        default: '',
      },
      approvalMaxlength: {
        type: Number,
        default: 500,
      },
    },
    data() {
      return {
        wordCount: 0,
        opinion: '',
        commonWordsList: [],
        moreTagList: [],
      }
    },
    watch: {
      approvalOpinion(val) {
        this.opinion = val
      },
      opinion(val) {
        this.$emit('get-opinion', val)
        this.opinionInput()
      },
    },

    created() {
      this.getCommonWordsList()
    },
    methods: {
      //获取常用语列表
      getCommonWordsList() {
        getCommonWordsByDefKeyAndTypeId(this.defKey, (res) => {
          if (res) {
            const firstShowTagNum = this.calculateTagCount(res, 332)
            const secondShowTagNum = this.calculateTagCount(
              res.slice(firstShowTagNum),
              332
            )
            this.moreTagList = res.slice(firstShowTagNum + secondShowTagNum)
            this.commonWordsList = res.filter(
              (item, index) => index < firstShowTagNum + secondShowTagNum
            )
          }
        })
      },
      //统计输入和选择常用语长度
      opinionInput() {
        this.wordCount = this.opinion.length
      },
      //选择常用语
      choseCommonOpinion(commonOpinion) {
        this.opinion += commonOpinion
        this.opinionInput()
        // 触发校验
        this.$nextTick(() => {
          this.$refs.opinionInput.$validator.validate()
        })
        if (this.opinion.length >= 500) {
          this.opinion = this.opinion.substr(0, 500)
          this.opinionInput()
          return
        }
      },
      //添加常用语
      addCommonOpinion() {
        if (!this.opinion) {
          this.$message.warning('请输入审批意见')
          return
        }
        this.$confirm(`确认添加 【${this.opinion}】 为常用语?`)
          .then(() => {
            const params = {
              expression: this.opinion,
              type: 4,
            }
            savaCommonWords(params).then((data) => {
              if (data.state) {
                this.$message({ type: 'success', message: data.message })
                this.getCommonWordsList()
              } else {
                this.$message({ type: 'error', message: data.message })
              }
            })
          })
          .catch(() => {})
      },
      calculateTagCount(tagList, containerWidth) {
        let tagCount = 0
        let currentWidth = 0

        for (let i = 0; i < tagList.length; i++) {
          const tag = tagList[i]
          const tagWidth = this.calculateTagWidth(tag)
          const TAG_MARGIN_RIGHT = 8
          if (currentWidth + tagWidth + TAG_MARGIN_RIGHT <= containerWidth) {
            currentWidth += tagWidth + TAG_MARGIN_RIGHT
            tagCount++
          } else {
            break
          }
        }
        return tagCount
      },
      calculateTagWidth(tag) {
        const TAG_FONT_SIZE = 12
        const TAG_LEFT_RIGHT_PADDING = 32
        const TAG_MAX_NUM_WORDS = 7
        const tagTextLength =
          tag.length > TAG_MAX_NUM_WORDS ? TAG_MAX_NUM_WORDS : tag.length

        return tagTextLength * TAG_FONT_SIZE + TAG_LEFT_RIGHT_PADDING
      },
    },
  }
</script>
<style lang="scss" scoped>
  .approval-comments {
    ::v-deep {
      div[aria-invalid='true'] + .field-tail__wrap {
        margin-bottom: 20px;
        .el-form-item__error {
          top: 91%;
        }
      }
    }
    .common-words {
      padding-top: 8px;

      .el-button {
        margin-right: 10px;
      }
      .word-count {
        float: right;
      }
      ::v-deep {
        .el-tag {
          margin-right: 8px;
          border-color: #dcdee0;
          border-radius: 4px;
          color: #262626;
          padding: 4px 16px;
          height: 32px;
          margin-bottom: 8px;
        }
        .el-tag + .el-tag {
          margin-left: 0;
        }
      }
    }

    ::v-deep {
      .inputs {
        .el-textarea__inner {
          border: none;
        }
      }
      .common-words-btns {
        display: flex;
        align-items: center;
        .el-button {
          padding: 7.8px 8.2px;
          background-color: var(--themeColor);
          color: #fff;
          border-radius: 4px;
          border-color: var(--themeColor);
          &:hover {
            background-color: var(--themeColor);
            border-color: var(--themeColor);
            color: #fff;
          }
          i {
            &:hover {
              opacity: 1;
            }
          }
        }
        .el-dropdown {
          width: 30px;
          height: 30px;
          border: 1px solid #dcdee0;
          text-align: center;
          border-radius: 4px;
          margin-right: 8px;
          cursor: pointer;
          .more-dropdown-icon {
            width: 30px;
            height: 30px;
            line-height: 30px;
            display: block;
          }
          &:hover {
            color: var(--themeColor);
            border-color: var(--themeColor);
          }
        }
      }
    }
    .el-tag {
      margin-right: 10px;
      cursor: pointer;
    }
  }
</style>