FormatterDialog.vue 6.28 KB
<template>
  <el-dialog
    v-if="dialogVisible"
    title="设置"
    width="50%"
    :visible.sync="dialogVisible"
    append-to-body
    destroy-on-close
    custom-class="setting-dialog"
    @close="dialogVisible = false"
  >
    <div style="margin-top: 5px">
      <el-radio-group
        v-model="selectedRow.formatterType"
        @change="clearFormatterData"
      >
        <el-radio label="1" size="small">文本</el-radio>
        <el-radio label="2" size="small">数据字典</el-radio>
      </el-radio-group>
      <el-button
        size="mini"
        style="margin-right: 50px; float: right"
        @click="clearFormatterType"
        >清除</el-button
      >
    </div>
    <div v-if="selectedRow.formatterType === '1'" style="margin-top: 5px">
      <div class="tip-message">
        类似固定选项的方式配置实际值和显示内容的映射关系,例如:实际值为:0,显示内容为:男士;实际值为:1,显示内容为:女士
      </div>
      <el-button
        type="primary"
        icon="el-icon-plus"
        style="margin-bottom: 16px"
        @click="addSetting"
        >添加</el-button
      >
      <el-form data-vv-scope="kanbanSettingForm">
        <el-table :data="selectedRow.formatterData" row-key="id" border>
          <el-table-column label="实际值">
            <template slot-scope="scope">
              <ht-input
                v-model="scope.row.key_"
                :maxlength="50"
                validate="required"
                show-word-limit
              />
            </template>
          </el-table-column>
          <el-table-column label="显示内容">
            <template slot-scope="scope">
              <ht-input
                v-model="scope.row.value_"
                :maxlength="50"
                show-word-limit
                validate="required"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button type="text" @click="removeSetting(scope.$index)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </div>
    <el-form
      v-else-if="selectedRow.formatterType === '2'"
      class="data-dictionary-form"
    >
      <ht-form-item label="数据字典选项">
        <Treeselect
          v-model="selectedRow.dataDictionary"
          :normalizer="normalizer"
          @select="dicNodeClick"
          :multiple="false"
          :appendToBody="true"
          :options="dataDictionaryOption"
          noOptionsText="暂无数据 "
          noChildrenText=" "
          placeholder="请选择"
          style="width: 80%"
          :disable-branch-nodes="true"
        />
      </ht-form-item>
    </el-form>

    <span slot="footer" class="dialog-footer">
      <el-button @click="closeDialog">取 消</el-button>
      <el-button type="primary" @click="confirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
import form from '@/api/form'
import Treeselect from '@riophae/vue-treeselect'
import deepmerge from 'deepmerge'
import utils from '@/hotent-ui-util.js'
export default {
  name: 'FormatterDialog',
  components: {
    Treeselect,
  },
  data() {
    return {
      dialogVisible: false,
      dataDictionaryOption: [],
      selectedRow: {},
      normalizer(node) {
        return {
          id: node.id,
          label: node.name,
          children:
            node.children && node.children.length > 0 ? node.children : 0, // 过滤掉children为null或[]
          isDefaultExpanded: false,
          isDisabled:
            node.hasOwnProperty('typeGroupKey') &&
            node.children &&
            node.children.length === 0,
        }
      },
    }
  },
  watch: {
    'selectedRow.formatterType': {
      handler(val) {
        if (val === '2') {
          this.dicClick()
        }
      },
      deep: true,
    },
  },
  methods: {
    open(row) {
      this.selectedRow = deepmerge({}, row, {clone: true})
      this.dialogVisible = true
    },
    confirm() {
      utils
        .validateForm(this, 'kanbanSettingForm')
        .then((result) => {
          if (this.selectedRow.formatterType === '2') {
            if (!this.selectedRow.dataDictionary) {
              this.$message.error(`请选择数据字典选项`)
              return false
            }
          }
          this.$emit('confirm', this.selectedRow)
          this.dialogVisible = false
        })
        .catch((items) => {
          this.$message.error(
            `有${items.length}个字段未通过校验,请正确填写表单内容。`
          )
        })
    },
    dicClick() {
      if (this.dataDictionaryOption && this.dataDictionaryOption.length > 0)
        return
      form.getCategory('DIC', (data) => {
        this.dataDictionaryOption = data.data
      })
    },
    dicNodeClick(data) {
      this.$set(this.selectedRow, 'dataDictionaryKey', data.typeKey)
      this.$set(this.selectedRow, 'dataDictionary', data.id)
      this.$requestConfig.getDictionaryByKey(data.typeKey).then((resp) => {
        this.$set(
          this.selectedRow,
          'formatterData',
          resp.map((data) => {
            return {key_: data.key, value_: data.name}
          })
        )
      })
    },
    clearFormatterData(val) {
      if (val !== '1') {
        this.$set(this.selectedRow, 'formatterData', [])
      }
    },
    clearFormatterType() {
      this.selectedRow.formatterType = ''
      this.selectedRow.formatterData = []
      this.selectedRow.dataDictionary = null
    },
    addSetting() {
      if (this.selectedRow.formatterData) {
        this.selectedRow.formatterData.push({
          key_: '',
          value_: '',
        })
      } else {
        this.$set(this.selectedRow, 'formatterData', [
          {
            key_: '',
            value_: '',
          },
        ])
      }
    },
    removeSetting(index) {
      this.selectedRow.formatterData.splice(index, 1)
    },
    closeDialog() {
      this.dialogVisible = false
      this.clearFormatterData()
    },
  },
}
</script>

<style lang="scss" scoped>
.tip-message {
  padding: 10px 16px;
  background: rgba(64, 158, 255, 0.1);
  border-radius: 2px;
  color: #409eff;
  margin: 20px 0;
}
.data-dictionary-form {
  margin-top: 15px;
}
</style>