mirror of
				https://github.com/veops/cmdb.git
				synced 2025-11-04 05:36:17 +08:00 
			
		
		
		
	feat(ui): update ci type choice config
This commit is contained in:
		@@ -54,6 +54,12 @@
 | 
			
		||||
      <div class="content unicode" style="display: block;">
 | 
			
		||||
          <ul class="icon_lists dib-box">
 | 
			
		||||
          
 | 
			
		||||
            <li class="dib">
 | 
			
		||||
              <span class="icon iconfont"></span>
 | 
			
		||||
                <div class="name">veops-department</div>
 | 
			
		||||
                <div class="code-name">&#xe998;</div>
 | 
			
		||||
              </li>
 | 
			
		||||
          
 | 
			
		||||
            <li class="dib">
 | 
			
		||||
              <span class="icon iconfont"></span>
 | 
			
		||||
                <div class="name">duose-changwenben (1)</div>
 | 
			
		||||
@@ -5514,9 +5520,9 @@
 | 
			
		||||
<pre><code class="language-css"
 | 
			
		||||
>@font-face {
 | 
			
		||||
  font-family: 'iconfont';
 | 
			
		||||
  src: url('iconfont.woff2?t=1724135954264') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1724135954264') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1724135954264') format('truetype');
 | 
			
		||||
  src: url('iconfont.woff2?t=1724653006782') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1724653006782') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1724653006782') format('truetype');
 | 
			
		||||
}
 | 
			
		||||
</code></pre>
 | 
			
		||||
          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
 | 
			
		||||
@@ -5542,6 +5548,15 @@
 | 
			
		||||
      <div class="content font-class">
 | 
			
		||||
        <ul class="icon_lists dib-box">
 | 
			
		||||
          
 | 
			
		||||
          <li class="dib">
 | 
			
		||||
            <span class="icon iconfont veops-department"></span>
 | 
			
		||||
            <div class="name">
 | 
			
		||||
              veops-department
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="code-name">.veops-department
 | 
			
		||||
            </div>
 | 
			
		||||
          </li>
 | 
			
		||||
          
 | 
			
		||||
          <li class="dib">
 | 
			
		||||
            <span class="icon iconfont duose-changwenben1"></span>
 | 
			
		||||
            <div class="name">
 | 
			
		||||
@@ -13732,6 +13747,14 @@
 | 
			
		||||
      <div class="content symbol">
 | 
			
		||||
          <ul class="icon_lists dib-box">
 | 
			
		||||
          
 | 
			
		||||
            <li class="dib">
 | 
			
		||||
                <svg class="icon svg-icon" aria-hidden="true">
 | 
			
		||||
                  <use xlink:href="#veops-department"></use>
 | 
			
		||||
                </svg>
 | 
			
		||||
                <div class="name">veops-department</div>
 | 
			
		||||
                <div class="code-name">#veops-department</div>
 | 
			
		||||
            </li>
 | 
			
		||||
          
 | 
			
		||||
            <li class="dib">
 | 
			
		||||
                <svg class="icon svg-icon" aria-hidden="true">
 | 
			
		||||
                  <use xlink:href="#duose-changwenben1"></use>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: "iconfont"; /* Project id 3857903 */
 | 
			
		||||
  src: url('iconfont.woff2?t=1724135954264') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1724135954264') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1724135954264') format('truetype');
 | 
			
		||||
  src: url('iconfont.woff2?t=1724653006782') format('woff2'),
 | 
			
		||||
       url('iconfont.woff?t=1724653006782') format('woff'),
 | 
			
		||||
       url('iconfont.ttf?t=1724653006782') format('truetype');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.iconfont {
 | 
			
		||||
@@ -13,6 +13,10 @@
 | 
			
		||||
  -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.veops-department:before {
 | 
			
		||||
  content: "\e998";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.duose-changwenben1:before {
 | 
			
		||||
  content: "\e997";
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -5,6 +5,13 @@
 | 
			
		||||
  "css_prefix_text": "",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "glyphs": [
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "41570722",
 | 
			
		||||
      "name": "veops-department",
 | 
			
		||||
      "font_class": "veops-department",
 | 
			
		||||
      "unicode": "e998",
 | 
			
		||||
      "unicode_decimal": 59800
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "41437322",
 | 
			
		||||
      "name": "duose-changwenben (1)",
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -107,7 +107,9 @@
 | 
			
		||||
                    :type="choice[1].icon.name"
 | 
			
		||||
                  />
 | 
			
		||||
                </template>
 | 
			
		||||
                <span>{{ choice[0] }}</span>
 | 
			
		||||
                <a-tooltip placement="topLeft" :title="choice[1].label || choice[0]">
 | 
			
		||||
                  <span>{{ choice[1].label || choice[0] }}</span>
 | 
			
		||||
                </a-tooltip>
 | 
			
		||||
              </span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
@@ -138,7 +140,7 @@
 | 
			
		||||
              "
 | 
			
		||||
              target="_blank"
 | 
			
		||||
            >
 | 
			
		||||
              {{ item }}
 | 
			
		||||
              {{ getChoiceValueLabel(col, item) || item }}
 | 
			
		||||
            </a>
 | 
			
		||||
          </template>
 | 
			
		||||
          <PasswordField
 | 
			
		||||
@@ -163,7 +165,7 @@
 | 
			
		||||
                :style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
 | 
			
		||||
                :type="getChoiceValueIcon(col, value).name"
 | 
			
		||||
              />
 | 
			
		||||
              {{ value }}
 | 
			
		||||
              {{ getChoiceValueLabel(col, value) || value }}
 | 
			
		||||
            </span>
 | 
			
		||||
          </template>
 | 
			
		||||
        </template>
 | 
			
		||||
@@ -397,6 +399,14 @@ export default {
 | 
			
		||||
      return {}
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getChoiceValueLabel(col, colValue) {
 | 
			
		||||
      const _find = col?.filters?.find((item) => String(item[0]) === String(colValue))
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find[1]?.label || ''
 | 
			
		||||
      }
 | 
			
		||||
      return ''
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 开启当前 ci 详情弹窗
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,7 @@ export default {
 | 
			
		||||
      return { method, url, parameters, body, headers, authorization }
 | 
			
		||||
    },
 | 
			
		||||
    setParams(params) {
 | 
			
		||||
      const { method, url, parameters, body, headers, authorization = {} } = params ?? {}
 | 
			
		||||
      const { method = 'GET', url = '', parameters = {}, body = '', headers = {}, authorization = {} } = params ?? {}
 | 
			
		||||
      this.method = method
 | 
			
		||||
      this.url = url
 | 
			
		||||
      this.$refs.Parameters.parameters =
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ const cmdb_en = {
 | 
			
		||||
        advancedSettings: 'Advanced Settings',
 | 
			
		||||
        font: 'Font',
 | 
			
		||||
        color: 'Color',
 | 
			
		||||
        choiceValue: 'Predefined value',
 | 
			
		||||
        choiceValue: 'Select List',
 | 
			
		||||
        computedAttribute: 'Computed Attribute',
 | 
			
		||||
        computedAttributeTips: 'The value of this attribute is calculated through an expression constructed from other attributes of the CIType or by executing a piece of code. The reference method of the attribute is: {{ attribute name }}',
 | 
			
		||||
        addAttribute: 'New attribute',
 | 
			
		||||
@@ -293,7 +293,19 @@ const cmdb_en = {
 | 
			
		||||
        cascadeAttrTip: 'Cascading attributes note the order',
 | 
			
		||||
        enumValue: 'Value',
 | 
			
		||||
        label: 'Label',
 | 
			
		||||
        valueInputTip: 'Please input value'
 | 
			
		||||
        valueInputTip: 'Please input value',
 | 
			
		||||
        enumValueTip2: 'Enumeration values cannot be repeated',
 | 
			
		||||
        builtin: 'Built In',
 | 
			
		||||
        department: 'Department',
 | 
			
		||||
        user: 'User',
 | 
			
		||||
        userGroup: 'User Group',
 | 
			
		||||
        departmentTip: 'Scroll down to select all departments in the company structure for common settings',
 | 
			
		||||
        userGroupSelectTip: 'Please select user group',
 | 
			
		||||
        displayValue: 'Display Value',
 | 
			
		||||
        displayValueSelectTip: 'Please select Display Value',
 | 
			
		||||
        departmentCascadeDisplay: 'Cascade Display',
 | 
			
		||||
        filterUsers: 'Filter Users',
 | 
			
		||||
        enum: 'Enum',
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
        unselectAttributes: 'Unselected',
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ const cmdb_zh = {
 | 
			
		||||
        advancedSettings: '高级设置',
 | 
			
		||||
        font: '字体',
 | 
			
		||||
        color: '颜色',
 | 
			
		||||
        choiceValue: '预定义值',
 | 
			
		||||
        choiceValue: '下拉列表',
 | 
			
		||||
        computedAttribute: '计算属性',
 | 
			
		||||
        computedAttributeTips: '该属性的值是通过模型的其它属性构建的表达式或者执行一段代码的方式计算而来,属性的引用方法为: {{ 属性名 }}',
 | 
			
		||||
        addAttribute: '新增属性',
 | 
			
		||||
@@ -293,7 +293,19 @@ const cmdb_zh = {
 | 
			
		||||
        cascadeAttrTip: '级联属性注意顺序',
 | 
			
		||||
        enumValue: '枚举值',
 | 
			
		||||
        label: '标签',
 | 
			
		||||
        valueInputTip: '请输入枚举值'
 | 
			
		||||
        valueInputTip: '请输入枚举值',
 | 
			
		||||
        enumValueTip2: '枚举值不能重复',
 | 
			
		||||
        builtin: '内置',
 | 
			
		||||
        department: '部门',
 | 
			
		||||
        user: '用户',
 | 
			
		||||
        userGroup: '用户组',
 | 
			
		||||
        departmentTip: '下拉选择为通用设置公司架构里的所有部门',
 | 
			
		||||
        userGroupSelectTip: '请选择用户组',
 | 
			
		||||
        displayValue: '展示值',
 | 
			
		||||
        displayValueSelectTip: '请选择展示值',
 | 
			
		||||
        departmentCascadeDisplay: '部门级联显示',
 | 
			
		||||
        filterUsers: '筛选用户',
 | 
			
		||||
        enum: '枚举',
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
        unselectAttributes: '未选属性',
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,7 @@ export function getCITableColumns(data, attrList, width = 1600, height) {
 | 
			
		||||
            value_type: attr.value_type,
 | 
			
		||||
            sortable: !!attr.is_sortable,
 | 
			
		||||
            filters: attr.is_choice ? attr.choice_value : null,
 | 
			
		||||
            choice_builtin: null,
 | 
			
		||||
            width: Math.min(Math.max(100, ...data.map(item => strLength(item[attr.name]))), 350),
 | 
			
		||||
            is_link: attr.is_link,
 | 
			
		||||
            is_password: attr.is_password,
 | 
			
		||||
 
 | 
			
		||||
@@ -128,7 +128,9 @@
 | 
			
		||||
                      v-if="choice[1] && choice[1].icon && choice[1].icon.name"
 | 
			
		||||
                      :type="choice[1].icon.name"
 | 
			
		||||
                    />
 | 
			
		||||
                    {{ choice[0] }}
 | 
			
		||||
                    <a-tooltip placement="topLeft" :title="choice[1].label || choice[0]" >
 | 
			
		||||
                      {{ choice[1].label || choice[0] }}
 | 
			
		||||
                    </a-tooltip>
 | 
			
		||||
                  </span>
 | 
			
		||||
                </a-select-option>
 | 
			
		||||
              </a-select>
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
              :style="{ color: getChoiceValueIcon(attr, value).color, marginRight: '5px' }"
 | 
			
		||||
              :type="getChoiceValueIcon(attr, value).name"
 | 
			
		||||
            />
 | 
			
		||||
            {{ value }}</span
 | 
			
		||||
            {{ getChoiceValueLabel(attr, value) || value }}</span
 | 
			
		||||
          >
 | 
			
		||||
        </template>
 | 
			
		||||
        <span
 | 
			
		||||
@@ -66,7 +66,7 @@
 | 
			
		||||
            :style="{ color: getChoiceValueIcon(attr, ci[attr.name]).color, marginRight: '5px' }"
 | 
			
		||||
            :type="getChoiceValueIcon(attr, ci[attr.name]).name"
 | 
			
		||||
          />
 | 
			
		||||
          {{ ci[attr.name] }}
 | 
			
		||||
          {{ getChoiceValueLabel(attr, ci[attr.name]) || ci[attr.name] }}
 | 
			
		||||
        </span>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-else-if="attr.is_list">
 | 
			
		||||
@@ -134,7 +134,7 @@
 | 
			
		||||
                    :type="choice[1].icon.name"
 | 
			
		||||
                  />
 | 
			
		||||
                </template>
 | 
			
		||||
                {{ choice[0] }}
 | 
			
		||||
                {{ choice[1].label || choice[0] }}
 | 
			
		||||
              </span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
@@ -318,6 +318,15 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
      return {}
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getChoiceValueLabel(col, colValue) {
 | 
			
		||||
      const _find = col.choice_value.find((item) => String(item[0]) === String(colValue))
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find[1]?.label || ''
 | 
			
		||||
      }
 | 
			
		||||
      return ''
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getName(name) {
 | 
			
		||||
      return name ?? ''
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -233,6 +233,7 @@ export default {
 | 
			
		||||
            this.firstCIJsonAttr[item._type].forEach((attr) => {
 | 
			
		||||
              item[`${attr}`] = item[`${attr}`] ? JSON.stringify(item[`${attr}`]) : ''
 | 
			
		||||
            })
 | 
			
		||||
            this.formatCI(item, this.firstCIColumns)
 | 
			
		||||
            if (item.ci_type in firstCIs) {
 | 
			
		||||
              firstCIs[item.ci_type].push(item)
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -251,6 +252,7 @@ export default {
 | 
			
		||||
            this.secondCIJsonAttr[item._type].forEach((attr) => {
 | 
			
		||||
              item[`${attr}`] = item[`${attr}`] ? JSON.stringify(item[`${attr}`]) : ''
 | 
			
		||||
            })
 | 
			
		||||
            this.formatCI(item, this.secondCIColumns)
 | 
			
		||||
            if (item.ci_type in secondCIs) {
 | 
			
		||||
              secondCIs[item.ci_type].push(item)
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -261,6 +263,26 @@ export default {
 | 
			
		||||
        })
 | 
			
		||||
        .catch((e) => {})
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    formatCI(ci, columns) {
 | 
			
		||||
      Object.keys(ci).forEach((key) => {
 | 
			
		||||
        const attr = columns?.[ci?._type]?.find((item) => item?.params?.attr?.name === key)?.params?.attr
 | 
			
		||||
        if (attr?.is_choice && attr?.choice_value?.length) {
 | 
			
		||||
          if (attr?.is_list) {
 | 
			
		||||
            ci[key] = ci[key].map((value) => {
 | 
			
		||||
              const label = attr?.choice_value?.find((choice) => choice?.[0] === value)?.[1]?.label
 | 
			
		||||
              return label || ci[key]
 | 
			
		||||
            })
 | 
			
		||||
          } else {
 | 
			
		||||
            const label = attr?.choice_value?.find((choice) => choice?.[0] === ci[key])?.[1]?.label
 | 
			
		||||
            ci[key] = label || ci[key]
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      return ci
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async getParentCITypes() {
 | 
			
		||||
      const res = await getCITypeParent(this.typeId)
 | 
			
		||||
      this.parentCITypes = res.parents
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,9 @@
 | 
			
		||||
                    :type="choice[1].icon.name"
 | 
			
		||||
                  />
 | 
			
		||||
                </template>
 | 
			
		||||
                {{ choice[0] }}
 | 
			
		||||
                <a-tooltip placement="topLeft" :title="choice[1].label || choice[0]">
 | 
			
		||||
                  {{ choice[1].label || choice[0] }}
 | 
			
		||||
                </a-tooltip>
 | 
			
		||||
              </span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
@@ -90,7 +92,7 @@
 | 
			
		||||
              attr.name,
 | 
			
		||||
              {
 | 
			
		||||
                rules: [{ required: attr.is_required, message: $t('placeholder2') + `${attr.alias || attr.name}` }],
 | 
			
		||||
                initialValue: attr.default && attr.default.default ? attr.default.default : '',
 | 
			
		||||
                initialValue: attr.default && attr.default.default ? Array.isArray(attr.default.default) ? attr.default.default.join(',') : attr.default.default : '',
 | 
			
		||||
              },
 | 
			
		||||
            ]"
 | 
			
		||||
          >
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,18 @@ export default {
 | 
			
		||||
      tableData: [],
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  inject: ['providerGroupsData'],
 | 
			
		||||
  inject: {
 | 
			
		||||
    providerGroupsData: {
 | 
			
		||||
      default: () => {
 | 
			
		||||
        return () => {
 | 
			
		||||
          return {
 | 
			
		||||
            CITypeGroups: [],
 | 
			
		||||
            otherGroupAttributes: [],
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState({
 | 
			
		||||
      windowHeight: (state) => state.windowHeight,
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,8 @@
 | 
			
		||||
                !property.is_password &&
 | 
			
		||||
                !property.is_list &&
 | 
			
		||||
                !property.is_reference &&
 | 
			
		||||
                !property.is_bool
 | 
			
		||||
                !property.is_bool &&
 | 
			
		||||
                !(Array.isArray(property.choice_value) ? property.choice_value.length > 0 : false)
 | 
			
		||||
            "
 | 
			
		||||
            :title="$t(isShowId ? 'cmdb.ciType.cancelSetAsShow' : 'cmdb.ciType.setAsShow')"
 | 
			
		||||
          >
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@
 | 
			
		||||
      >
 | 
			
		||||
        <a-form-item
 | 
			
		||||
          :label-col="{ span: currentValueType === '6' ? 4 : 8 }"
 | 
			
		||||
          :wrapper-col="{ span: currentValueType === '6' ? 18 : 12 }"
 | 
			
		||||
          :wrapper-col="{ span: currentValueType === '6' ? 18 : 15 }"
 | 
			
		||||
          :label="$t('cmdb.ciType.defaultValue')"
 | 
			
		||||
        >
 | 
			
		||||
          <template>
 | 
			
		||||
@@ -367,7 +367,10 @@
 | 
			
		||||
              ref="preValueArea"
 | 
			
		||||
              :disabled="isShowComputedArea"
 | 
			
		||||
              :CITypeId="CITypeId"
 | 
			
		||||
              :enumValueType="enumValueType"
 | 
			
		||||
            />
 | 
			
		||||
 | 
			
		||||
            <a-button type="primary" size="small" ghost @click="resetPreValue" >{{ $t('reset') }}</a-button>
 | 
			
		||||
          </a-form-item>
 | 
			
		||||
        </a-col>
 | 
			
		||||
        <a-col :span="24" v-if="!['6', '7', '10', '11'].includes(currentValueType)">
 | 
			
		||||
@@ -442,6 +445,7 @@ import PreValueArea from './preValueArea.vue'
 | 
			
		||||
import FontArea from './fontArea.vue'
 | 
			
		||||
import RegSelect from '@/components/RegexSelect'
 | 
			
		||||
import ReferenceModelSelect from './attributeEdit/referenceModelSelect.vue'
 | 
			
		||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'AttributeEditForm',
 | 
			
		||||
@@ -474,6 +478,7 @@ export default {
 | 
			
		||||
 | 
			
		||||
      defaultForDatetime: '',
 | 
			
		||||
      re_check: {},
 | 
			
		||||
      enumValueType: ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@@ -686,6 +691,22 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
        const _find = attributes.find((item) => item.id === _record.id)
 | 
			
		||||
        if (!['6', '7', '10', '11'].includes(_record.value_type)) {
 | 
			
		||||
          switch (_record.value_type) {
 | 
			
		||||
            case '0':
 | 
			
		||||
            case '1':
 | 
			
		||||
              this.enumValueType = ENUM_VALUE_TYPE.NUMBER
 | 
			
		||||
              break
 | 
			
		||||
            case '3':
 | 
			
		||||
              this.enumValueType = ENUM_VALUE_TYPE.DATE_TIME
 | 
			
		||||
              break
 | 
			
		||||
            case '4':
 | 
			
		||||
              this.enumValueType = ENUM_VALUE_TYPE.DATE
 | 
			
		||||
              break
 | 
			
		||||
            default:
 | 
			
		||||
              this.enumValueType = ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
              break
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.$refs.preValueArea.setData({
 | 
			
		||||
            choice_value: (_find || {}).choice_value || [],
 | 
			
		||||
            choice_web_hook: _record.choice_web_hook,
 | 
			
		||||
@@ -715,8 +736,6 @@ export default {
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          delete values['default_show']
 | 
			
		||||
          delete values['is_required']
 | 
			
		||||
          const { default_value } = values
 | 
			
		||||
          if (values.value_type === '10') {
 | 
			
		||||
            values.default = { default: values.is_list ? default_value : Boolean(default_value) }
 | 
			
		||||
@@ -748,7 +767,6 @@ export default {
 | 
			
		||||
            values.default = { default: null }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          delete values.default_value
 | 
			
		||||
          if (values.is_computed) {
 | 
			
		||||
            const computedAreaData = this.$refs.computedArea.getData()
 | 
			
		||||
            values = { ...values, ...computedAreaData }
 | 
			
		||||
@@ -756,9 +774,18 @@ export default {
 | 
			
		||||
            // If it is a non-computed attribute, check to see if there is a predefined value
 | 
			
		||||
            if (!['6', '7', '10', '11'].includes(values.value_type)) {
 | 
			
		||||
              const preValueAreaData = this.$refs.preValueArea.getData()
 | 
			
		||||
              // 预定义值校验错误
 | 
			
		||||
              if (preValueAreaData?.isError) {
 | 
			
		||||
                return
 | 
			
		||||
              }
 | 
			
		||||
              values = { ...values, ...preValueAreaData }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          delete values['default_show']
 | 
			
		||||
          delete values['is_required']
 | 
			
		||||
          delete values.default_value
 | 
			
		||||
 | 
			
		||||
          const fontOptions = this.$refs.fontArea.getData()
 | 
			
		||||
 | 
			
		||||
          if (!['6', '10', '11'].includes(values.value_type)) {
 | 
			
		||||
@@ -831,10 +858,19 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    changeDefaultForDatetime(value) {
 | 
			
		||||
      this.defaultForDatetime = value
 | 
			
		||||
      if (value === '$custom_time') {
 | 
			
		||||
        this.form.setFieldsValue({
 | 
			
		||||
          default_value: undefined,
 | 
			
		||||
        })
 | 
			
		||||
      switch (value) {
 | 
			
		||||
        case '$custom_time':
 | 
			
		||||
          this.form.setFieldsValue({
 | 
			
		||||
            default_value: undefined,
 | 
			
		||||
          })
 | 
			
		||||
          break
 | 
			
		||||
        case '$updated_at':
 | 
			
		||||
          this.form.setFieldsValue({
 | 
			
		||||
            is_dynamic: true,
 | 
			
		||||
          })
 | 
			
		||||
          break
 | 
			
		||||
        default:
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    onClick({ key }) {
 | 
			
		||||
@@ -862,6 +898,12 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
      return []
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    resetPreValue() {
 | 
			
		||||
      if (this.$refs.preValueArea) {
 | 
			
		||||
        this.$refs.preValueArea.resetData()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {},
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -359,7 +359,10 @@
 | 
			
		||||
            :canDefineScript="canDefineScript"
 | 
			
		||||
            :disabled="isShowComputedArea"
 | 
			
		||||
            :CITypeId="CITypeId"
 | 
			
		||||
            :enumValueType="enumValueType"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <a-button type="primary" size="small" ghost @click="resetPreValue" >{{ $t('reset') }}</a-button>
 | 
			
		||||
        </a-form-item>
 | 
			
		||||
      </a-col>
 | 
			
		||||
      <a-col :span="24" v-if="!['6', '7', '10', '11'].includes(currentValueType)">
 | 
			
		||||
@@ -416,6 +419,7 @@ import FontArea from './fontArea.vue'
 | 
			
		||||
import RegSelect from '@/components/RegexSelect'
 | 
			
		||||
import { getPropertyIcon } from '../../utils/helper'
 | 
			
		||||
import ReferenceModelSelect from './attributeEdit/referenceModelSelect.vue'
 | 
			
		||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'CreateNewAttribute',
 | 
			
		||||
@@ -458,6 +462,7 @@ export default {
 | 
			
		||||
      defaultForDatetime: '',
 | 
			
		||||
 | 
			
		||||
      re_check: {},
 | 
			
		||||
      enumValueType: ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
@@ -485,8 +490,7 @@ export default {
 | 
			
		||||
          console.log(values)
 | 
			
		||||
          const { is_required, default_show, default_value, is_dynamic } = values
 | 
			
		||||
          const data = { is_required, default_show, is_dynamic }
 | 
			
		||||
          delete values.is_required
 | 
			
		||||
          delete values.default_show
 | 
			
		||||
 | 
			
		||||
          if (values.value_type === '10') {
 | 
			
		||||
            values.default = { default: values.is_list ? (default_value || null) : Boolean(default_value) }
 | 
			
		||||
          } else if (values.value_type === '0' && default_value) {
 | 
			
		||||
@@ -516,7 +520,7 @@ export default {
 | 
			
		||||
          } else {
 | 
			
		||||
            values.default = { default: null }
 | 
			
		||||
          }
 | 
			
		||||
          delete values.default_value
 | 
			
		||||
 | 
			
		||||
          if (values.is_computed) {
 | 
			
		||||
            const computedAreaData = this.$refs.computedArea.getData()
 | 
			
		||||
            values = { ...values, ...computedAreaData }
 | 
			
		||||
@@ -524,9 +528,18 @@ export default {
 | 
			
		||||
            // If it is a non-computed attribute, check to see if there is a predefined value
 | 
			
		||||
            if (!['6', '7', '10', '11'].includes(values.value_type)) {
 | 
			
		||||
              const preValueAreaData = this.$refs.preValueArea.getData()
 | 
			
		||||
              // 预定义值校验错误
 | 
			
		||||
              if (preValueAreaData?.isError) {
 | 
			
		||||
                return
 | 
			
		||||
              }
 | 
			
		||||
              values = { ...values, ...preValueAreaData }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          delete values.is_required
 | 
			
		||||
          delete values.default_show
 | 
			
		||||
          delete values.default_value
 | 
			
		||||
 | 
			
		||||
          const fontOptions = this.$refs.fontArea.getData()
 | 
			
		||||
 | 
			
		||||
          // 索引
 | 
			
		||||
@@ -587,6 +600,28 @@ export default {
 | 
			
		||||
        if (['6', '10', '11'].includes(value)) {
 | 
			
		||||
          this.re_check = {}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (value) {
 | 
			
		||||
          case '0':
 | 
			
		||||
          case '1':
 | 
			
		||||
            this.enumValueType = ENUM_VALUE_TYPE.NUMBER
 | 
			
		||||
            break
 | 
			
		||||
          case '3':
 | 
			
		||||
            this.enumValueType = ENUM_VALUE_TYPE.DATE_TIME
 | 
			
		||||
            break
 | 
			
		||||
          case '4':
 | 
			
		||||
            this.enumValueType = ENUM_VALUE_TYPE.DATE
 | 
			
		||||
            break
 | 
			
		||||
          default:
 | 
			
		||||
            this.enumValueType = ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
            break
 | 
			
		||||
        }
 | 
			
		||||
        if (['0', '1', '3', '4'].includes(value)) {
 | 
			
		||||
          if (this.$refs.preValueArea) {
 | 
			
		||||
            this.$refs.preValueArea.initEnumValue()
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.handleSwitchType({ valueType: value })
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
@@ -660,10 +695,19 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    changeDefaultForDatetime(value) {
 | 
			
		||||
      this.defaultForDatetime = value
 | 
			
		||||
      if (value === '$custom_time') {
 | 
			
		||||
        this.form.setFieldsValue({
 | 
			
		||||
          default_value: undefined,
 | 
			
		||||
        })
 | 
			
		||||
      switch (value) {
 | 
			
		||||
        case '$custom_time':
 | 
			
		||||
          this.form.setFieldsValue({
 | 
			
		||||
            default_value: undefined,
 | 
			
		||||
          })
 | 
			
		||||
          break
 | 
			
		||||
        case '$updated_at':
 | 
			
		||||
          this.form.setFieldsValue({
 | 
			
		||||
            is_dynamic: true,
 | 
			
		||||
          })
 | 
			
		||||
          break
 | 
			
		||||
        default:
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    onClick({ key }) {
 | 
			
		||||
@@ -688,6 +732,12 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
      return []
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    resetPreValue() {
 | 
			
		||||
      if (this.$refs.preValueArea) {
 | 
			
		||||
        this.$refs.preValueArea.resetData()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -545,7 +545,7 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    showIdSelectOptions() {
 | 
			
		||||
      const _showIdSelectOptions = this.currentTypeAttrs.filter(
 | 
			
		||||
        (item) => item.id !== this.unique_id && !['6'].includes(item.value_type) && !item.is_password && !item.is_list && !item.is_bool && !item.is_reference
 | 
			
		||||
        (item) => item.id !== this.unique_id && !['6'].includes(item.value_type) && !item.is_password && !item.is_list && !item.is_bool && !item.is_reference && !item?.choice_value?.length
 | 
			
		||||
      )
 | 
			
		||||
      if (this.showIdFilterInput) {
 | 
			
		||||
        return _showIdSelectOptions.filter(
 | 
			
		||||
 
 | 
			
		||||
@@ -7,33 +7,22 @@
 | 
			
		||||
    :tabBarStyle="{ borderBottom: 'none' }"
 | 
			
		||||
  >
 | 
			
		||||
    <a-tab-pane key="define" :disabled="disabled">
 | 
			
		||||
      <span style="font-size:12px;" slot="tab">{{ $t('define') }}</span>
 | 
			
		||||
      <PreValueTag type="add" :item="[]" @add="addNewValue" :disabled="disabled">
 | 
			
		||||
        <template #default>
 | 
			
		||||
          <a-button
 | 
			
		||||
            :style="{ marginBottom: '10px', fontSize: '12px', padding: '1px 7px' }"
 | 
			
		||||
            type="primary"
 | 
			
		||||
            ghost
 | 
			
		||||
            :disabled="disabled"
 | 
			
		||||
            size="small"
 | 
			
		||||
          >
 | 
			
		||||
            <a-icon type="plus" />{{ $t('add') }}</a-button
 | 
			
		||||
          >
 | 
			
		||||
        </template>
 | 
			
		||||
      </PreValueTag>
 | 
			
		||||
      <draggable :list="valueList" handle=".handle" :disabled="disabled">
 | 
			
		||||
        <PreValueTag
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          v-for="(item, index) in valueList"
 | 
			
		||||
          :key="`${item[0]}_${index}`"
 | 
			
		||||
          :item="item"
 | 
			
		||||
          @deleteValue="deleteValue"
 | 
			
		||||
          @editValue="editValue"
 | 
			
		||||
        />
 | 
			
		||||
      </draggable>
 | 
			
		||||
      <span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.enum') }}</span>
 | 
			
		||||
      <PreValueDefine
 | 
			
		||||
        v-model="valueList"
 | 
			
		||||
        :disabled="disabled"
 | 
			
		||||
        :enumValueType="enumValueType"
 | 
			
		||||
      />
 | 
			
		||||
    </a-tab-pane>
 | 
			
		||||
    <a-tab-pane key="builtin" :disabled="disabled">
 | 
			
		||||
      <div class="tab-builtin" slot="tab">
 | 
			
		||||
        <span class="tab-builtin-title">{{ $t('cmdb.ciType.builtin') }}</span>
 | 
			
		||||
        <span v-if="isOpenSource" class="tab-builtin-tag">Pro</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <PreValueBuiltIn ref="builtInRef" />
 | 
			
		||||
    </a-tab-pane>
 | 
			
		||||
    <a-tab-pane key="webhook" :disabled="disabled">
 | 
			
		||||
      <span style="font-size:12px;" slot="tab">Webhook</span>
 | 
			
		||||
      <span style="font-size:14px;" slot="tab">Webhook</span>
 | 
			
		||||
      <Webhook ref="webhook" style="margin-top:10px" />
 | 
			
		||||
      <a-form-model :model="form">
 | 
			
		||||
        <a-col :span="24">
 | 
			
		||||
@@ -59,7 +48,7 @@
 | 
			
		||||
      </a-form-model>
 | 
			
		||||
    </a-tab-pane>
 | 
			
		||||
    <a-tab-pane key="choice_other" :disabled="disabled">
 | 
			
		||||
      <span style="font-size:12px;" slot="tab">{{ $t('cmdb.ciType.choiceOther') }}</span>
 | 
			
		||||
      <span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.choiceOther') }}</span>
 | 
			
		||||
      <a-row :gutter="[24, 24]">
 | 
			
		||||
        <a-col :span="24">
 | 
			
		||||
          <a-form-item
 | 
			
		||||
@@ -179,11 +168,11 @@
 | 
			
		||||
      </a-row>
 | 
			
		||||
    </a-tab-pane>
 | 
			
		||||
    <a-tab-pane key="script" :disabled="disabled || !canDefineScript">
 | 
			
		||||
      <span style="font-size:12px;" slot="tab">{{ $t('cmdb.ciType.code') }}</span>
 | 
			
		||||
      <span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.code') }}</span>
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        :style="{ marginBottom: '5px' }"
 | 
			
		||||
        :label="$t('cmdb.ciType.cascadeAttr')"
 | 
			
		||||
        :label-col="{ span: 3 }"
 | 
			
		||||
        :label-col="{ span: $i18n.locale === 'en' ? 3 : 2 }"
 | 
			
		||||
        :wrapper-col="{ span: 19 }"
 | 
			
		||||
        :extra="scriptCodeExtraText"
 | 
			
		||||
        labelAlign="left"
 | 
			
		||||
@@ -191,7 +180,7 @@
 | 
			
		||||
        <a-select
 | 
			
		||||
          mode="multiple"
 | 
			
		||||
          style="width: 100%"
 | 
			
		||||
          placeholder="Please select"
 | 
			
		||||
          :placeholder="$t('placeholder2')"
 | 
			
		||||
          optionFilterProp="title"
 | 
			
		||||
          v-model="cascade_attributes"
 | 
			
		||||
        >
 | 
			
		||||
@@ -211,9 +200,11 @@
 | 
			
		||||
        <div>2. {{ $t('cmdb.ciType.computedAttrTip2') }}</div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <a-button size="small" @click="showAllPropDrawer">
 | 
			
		||||
        {{ $t('cmdb.ciType.viewAllAttr') }}
 | 
			
		||||
      </a-button>
 | 
			
		||||
      <div class="all-attr-btn">
 | 
			
		||||
        <a-button size="small" @click="showAllPropDrawer">
 | 
			
		||||
          {{ $t('cmdb.ciType.viewAllAttr') }}
 | 
			
		||||
        </a-button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <AllAttrDrawer ref="allAttrDrawer" />
 | 
			
		||||
 | 
			
		||||
      <CustomCodeMirror
 | 
			
		||||
@@ -237,6 +228,9 @@ import { getCITypeGroups } from '../../api/ciTypeGroup'
 | 
			
		||||
import { getCITypeCommonAttributesByTypeIds, getCITypeAttributesById } from '../../api/CITypeAttr'
 | 
			
		||||
import AttrFilter from './preValueAttr/attrFilter/index.vue'
 | 
			
		||||
import AllAttrDrawer from './allAttrDrawer.vue'
 | 
			
		||||
import PreValueDefine from './preValueAttr/define/index.vue'
 | 
			
		||||
import PreValueBuiltIn from './preValueAttr/builtin/index.vue'
 | 
			
		||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
 | 
			
		||||
 | 
			
		||||
import CustomCodeMirror from '@/components/CustomCodeMirror'
 | 
			
		||||
import 'codemirror/lib/codemirror.css'
 | 
			
		||||
@@ -245,7 +239,7 @@ require('codemirror/mode/python/python.js')
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'PreValueArea',
 | 
			
		||||
  components: { draggable, PreValueTag, ColorPicker, Webhook, AttrFilter, CustomCodeMirror, AllAttrDrawer },
 | 
			
		||||
  components: { draggable, PreValueTag, ColorPicker, Webhook, AttrFilter, CustomCodeMirror, AllAttrDrawer, PreValueDefine, PreValueBuiltIn },
 | 
			
		||||
  props: {
 | 
			
		||||
    disabled: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
@@ -259,12 +253,26 @@ export default {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: null,
 | 
			
		||||
    },
 | 
			
		||||
    // eslint-disable-next-line vue/require-default-prop
 | 
			
		||||
    enumValueType: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      defualt: ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      defautValueColor,
 | 
			
		||||
      activeKey: 'define', // define webhook
 | 
			
		||||
      valueList: [],
 | 
			
		||||
      valueList: [
 | 
			
		||||
        [
 | 
			
		||||
          '',
 | 
			
		||||
          {
 | 
			
		||||
            style: {},
 | 
			
		||||
            icon: {},
 | 
			
		||||
            label: ''
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      ],
 | 
			
		||||
      form: {
 | 
			
		||||
        ret_key: '',
 | 
			
		||||
      },
 | 
			
		||||
@@ -331,6 +339,10 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    async getCITypeAttributesById() {
 | 
			
		||||
      if (!this.CITypeId) {
 | 
			
		||||
        this.curModelAttrList = []
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      const res = await getCITypeAttributesById(this.CITypeId)
 | 
			
		||||
      let curModelAttrList = []
 | 
			
		||||
      if (res?.attributes?.length) {
 | 
			
		||||
@@ -339,47 +351,36 @@ export default {
 | 
			
		||||
      this.curModelAttrList = curModelAttrList
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addNewValue(newValue, newStyle, newIcon) {
 | 
			
		||||
      if (newValue) {
 | 
			
		||||
        const idx = this.valueList.findIndex((v) => v[0] === newValue)
 | 
			
		||||
        if (idx > -1) {
 | 
			
		||||
          this.$message.warning(this.$t('cmdb.ciType.valueExisted'))
 | 
			
		||||
        } else {
 | 
			
		||||
          this.valueList.push([newValue, { style: newStyle, icon: { ...newIcon } }])
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    deleteValue(item) {
 | 
			
		||||
      const _valueList = _.cloneDeep(this.valueList)
 | 
			
		||||
      const idx = _valueList.findIndex((v) => v[0] === item[0])
 | 
			
		||||
      if (idx > -1) {
 | 
			
		||||
        _valueList.splice(idx, 1)
 | 
			
		||||
        this.valueList = _valueList
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    editValue(item, newValue, newStyle, newIcon) {
 | 
			
		||||
      const _valueList = _.cloneDeep(this.valueList)
 | 
			
		||||
      const idx = _valueList.findIndex((v) => v[0] === item[0])
 | 
			
		||||
      if (idx > -1) {
 | 
			
		||||
        _valueList[idx] = [newValue, { style: newStyle, icon: { ...newIcon } }]
 | 
			
		||||
        this.valueList = _valueList
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getData() {
 | 
			
		||||
      if (this.activeKey === 'define') {
 | 
			
		||||
      if (this.activeKey === 'builtin') {
 | 
			
		||||
        return {
 | 
			
		||||
          choice_value: this.valueList,
 | 
			
		||||
          choice_web_hook: null,
 | 
			
		||||
          choice_other: null,
 | 
			
		||||
          choice_builtin: null,
 | 
			
		||||
        }
 | 
			
		||||
      } else if (this.activeKey === 'define') {
 | 
			
		||||
        if (this.validateDefine()) {
 | 
			
		||||
          return {
 | 
			
		||||
            isError: true
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          choice_value: this.valueList.filter((item) => item?.[0]),
 | 
			
		||||
          choice_web_hook: null,
 | 
			
		||||
          choice_other: null,
 | 
			
		||||
          choice_builtin: null
 | 
			
		||||
        }
 | 
			
		||||
      } else if (this.activeKey === 'webhook') {
 | 
			
		||||
        const choice_web_hook = this.$refs.webhook.getParams()
 | 
			
		||||
        choice_web_hook.ret_key = this.form.ret_key
 | 
			
		||||
        return { choice_value: [], choice_web_hook, choice_other: null }
 | 
			
		||||
        return { choice_value: [], choice_web_hook, choice_other: null, choice_builtin: null }
 | 
			
		||||
      } else if (this.activeKey === 'script') {
 | 
			
		||||
        return {
 | 
			
		||||
          choice_value: [],
 | 
			
		||||
          choice_web_hook: null,
 | 
			
		||||
          choice_builtin: null,
 | 
			
		||||
          choice_other: {
 | 
			
		||||
            script: this.script,
 | 
			
		||||
            cascade_attributes: this.cascade_attributes,
 | 
			
		||||
@@ -395,9 +396,22 @@ export default {
 | 
			
		||||
          choice_value: [],
 | 
			
		||||
          choice_web_hook: null,
 | 
			
		||||
          choice_other,
 | 
			
		||||
          choice_builtin: null,
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    validateDefine() {
 | 
			
		||||
      const valueList = this.valueList.filter((item) => item?.[0])
 | 
			
		||||
      const isRepeat = _.uniq(valueList.map(item => item?.[0] || '')).length !== valueList.length
 | 
			
		||||
      if (isRepeat) {
 | 
			
		||||
        this.$message.warning(this.$t('cmdb.ciType.enumValueTip2'))
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setData({ choice_value, choice_web_hook, choice_other }) {
 | 
			
		||||
      if (choice_web_hook) {
 | 
			
		||||
        this.activeKey = 'webhook'
 | 
			
		||||
@@ -425,7 +439,26 @@ export default {
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        this.valueList = choice_value
 | 
			
		||||
        let valueList = [[
 | 
			
		||||
          '',
 | 
			
		||||
          {
 | 
			
		||||
            style: {},
 | 
			
		||||
            icon: {},
 | 
			
		||||
            label: ''
 | 
			
		||||
          }
 | 
			
		||||
        ]]
 | 
			
		||||
        if (choice_value?.length) {
 | 
			
		||||
          valueList = choice_value.map((item) => {
 | 
			
		||||
            return [
 | 
			
		||||
              item[0],
 | 
			
		||||
              {
 | 
			
		||||
                ...item[1],
 | 
			
		||||
                label: item?.[1]?.['label'] || item[0]
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
        this.valueList = valueList
 | 
			
		||||
        this.activeKey = 'define'
 | 
			
		||||
      }
 | 
			
		||||
      const dom = document.querySelector('#preValueArea .ant-tabs-ink-bar')
 | 
			
		||||
@@ -436,6 +469,56 @@ export default {
 | 
			
		||||
        dom.style.backgroundColor = '#2f54eb'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    resetData() {
 | 
			
		||||
      this.activeKey = 'define'
 | 
			
		||||
      this.$set(this, 'valueList', [
 | 
			
		||||
        [
 | 
			
		||||
          '',
 | 
			
		||||
          {
 | 
			
		||||
            style: {},
 | 
			
		||||
            icon: {},
 | 
			
		||||
            label: ''
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      ])
 | 
			
		||||
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        if (this.$refs.builtInRef) {
 | 
			
		||||
          this.$refs.builtInRef.setData({})
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.$refs.webhook) {
 | 
			
		||||
          this.$refs.webhook.setParams({})
 | 
			
		||||
        }
 | 
			
		||||
        this.form.ret_key = ''
 | 
			
		||||
 | 
			
		||||
        this.script = ''
 | 
			
		||||
        this.cascade_attributes = []
 | 
			
		||||
        if (this.$refs.codemirror) {
 | 
			
		||||
          this.$refs.codemirror.initCodeMirror('')
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.choice_other = {
 | 
			
		||||
          type_ids: undefined,
 | 
			
		||||
          attr_id: undefined
 | 
			
		||||
        }
 | 
			
		||||
        if (this.$refs.attrFilter) {
 | 
			
		||||
          this.$refs.attrFilter.init(true, false)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    initEnumValue() {
 | 
			
		||||
      if (this.valueList) {
 | 
			
		||||
        const valueList = _.cloneDeep(this.valueList)
 | 
			
		||||
        valueList.forEach((item) => {
 | 
			
		||||
          item[0] = ''
 | 
			
		||||
        })
 | 
			
		||||
        this.$set(this, 'valueList', valueList)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setExpFromFilter(filterExp) {
 | 
			
		||||
      if (filterExp) {
 | 
			
		||||
        this.filterExp = `${filterExp}`
 | 
			
		||||
@@ -462,6 +545,24 @@ export default {
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.tab-builtin {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
 | 
			
		||||
  &-title {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-tag {
 | 
			
		||||
    background-color: #E1EFFF;
 | 
			
		||||
    color: #2F54EB;
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    padding: 0 3px;
 | 
			
		||||
    margin-left: 3px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pre-value-edit-color {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
@@ -481,6 +582,12 @@ export default {
 | 
			
		||||
  line-height: 22px;
 | 
			
		||||
  color: #a5a9bc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.all-attr-btn {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: flex-end;
 | 
			
		||||
  margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<style lang="less">
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
            (node) => {
 | 
			
		||||
              return {
 | 
			
		||||
                id: node[0],
 | 
			
		||||
                label: node[0],
 | 
			
		||||
                label: node[1].label || node[0],
 | 
			
		||||
                children: node.children,
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,104 @@
 | 
			
		||||
export const BUILT_IN_TYPE = {
 | 
			
		||||
  DEPARTMENT: 'department', // 部门
 | 
			
		||||
  USER: 'user', // 用户
 | 
			
		||||
  USER_GROUP: 'userGroup' // 用户组
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const DISPLAY_VALUE_SELECT = [
 | 
			
		||||
  { label: 'cs.companyStructure.nickname', value: 'nickname' },
 | 
			
		||||
  { label: 'cs.companyStructure.email', value: 'email' },
 | 
			
		||||
  { label: 'cs.companyStructure.mobile', value: 'mobile' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const USER_FILTER_SELECT = [
 | 
			
		||||
  { label: 'cs.companyStructure.nickname', value: 'nickname' },
 | 
			
		||||
  { label: 'cs.companyStructure.username', value: 'username' },
 | 
			
		||||
  { label: 'cs.companyStructure.email', value: 'email' },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.sex',
 | 
			
		||||
    value: 'sex',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.male', value: '男' },
 | 
			
		||||
      { label: 'cs.companyStructure.female', value: '女' },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  { label: 'cs.companyStructure.mobile', value: 'mobile' },
 | 
			
		||||
  { label: 'cs.companyStructure.departmentName', value: 'department_name' },
 | 
			
		||||
  { label: 'cs.companyStructure.positionName', value: 'position_name' },
 | 
			
		||||
  { label: 'cs.companyStructure.supervisor', value: 'direct_supervisor_id' },
 | 
			
		||||
  { label: 'cs.companyStructure.annualLeave', value: 'annual_leave' },
 | 
			
		||||
  { label: 'cs.companyStructure.currentCompany', value: 'current_company' },
 | 
			
		||||
  { label: 'cs.companyStructure.dfcEntryDate', value: 'dfc_entry_date' },
 | 
			
		||||
  { label: 'cs.companyStructure.entryDate', value: 'entry_date' },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.isInternship',
 | 
			
		||||
    value: 'is_internship',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.fullTime', value: 0 },
 | 
			
		||||
      { label: 'cs.companyStructure.internship', value: 1 },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  { label: 'cs.companyStructure.leaveDate', value: 'leave_date' },
 | 
			
		||||
  { label: 'cs.companyStructure.idCard', value: 'id_card' },
 | 
			
		||||
  { label: 'cs.companyStructure.nation', value: 'nation' },
 | 
			
		||||
  { label: 'cs.companyStructure.idPlace', value: 'id_place' },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.party',
 | 
			
		||||
    value: 'party',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.partyMember', value: '党员' },
 | 
			
		||||
      { label: 'cs.companyStructure.member', value: '团员' },
 | 
			
		||||
      { label: 'cs.companyStructure.masses', value: '群众' },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.householdRegistrationType',
 | 
			
		||||
    value: 'household_registration_type',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.town', value: '城镇' },
 | 
			
		||||
      { label: 'cs.companyStructure.agriculture', value: '农业' },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  { label: 'cs.companyStructure.hometown', value: 'hometown' },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.marry',
 | 
			
		||||
    value: 'marry',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.unmarried', value: '未婚' },
 | 
			
		||||
      { label: 'cs.companyStructure.married', value: '已婚' },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'cs.companyStructure.maxDegree',
 | 
			
		||||
    value: 'max_degree',
 | 
			
		||||
    is_choice: true,
 | 
			
		||||
    choice_value: [
 | 
			
		||||
      { label: 'cs.companyStructure.phd', value: '博士' },
 | 
			
		||||
      { label: 'cs.companyStructure.master', value: '硕士' },
 | 
			
		||||
      {
 | 
			
		||||
        label: 'cs.companyStructure.undergraduate',
 | 
			
		||||
        value: '本科',
 | 
			
		||||
      },
 | 
			
		||||
      { label: 'cs.companyStructure.specialist', value: '专科' },
 | 
			
		||||
      { label: 'cs.companyStructure.highSchool', value: '高中' },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  { label: 'cs.companyStructure.emergencyPerson', value: 'emergency_person' },
 | 
			
		||||
  { label: 'cs.companyStructure.emergencyPhone', value: 'emergency_phone' },
 | 
			
		||||
  { label: 'cs.companyStructure.bankCardNumber', value: 'bank_card_number' },
 | 
			
		||||
  { label: 'cs.companyStructure.bankCardName', value: 'bank_card_name' },
 | 
			
		||||
  { label: 'cs.companyStructure.openingBank', value: 'opening_bank' },
 | 
			
		||||
  { label: 'cs.companyStructure.accountOpeningLocation', value: 'account_opening_location' },
 | 
			
		||||
  { label: 'cs.companyStructure.birthDate', value: 'birth_date' },
 | 
			
		||||
  { label: 'cs.companyStructure.nationalityRegion', value: 'nationality_region' },
 | 
			
		||||
  { label: 'cs.companyStructure.birthPlace', value: 'birth_place' },
 | 
			
		||||
  { label: 'cs.companyStructure.firstEntryDate', value: 'first_entry_date' },
 | 
			
		||||
  { label: 'cs.companyStructure.estimatedDepartureDate', value: 'estimated_departure_date' },
 | 
			
		||||
  // { label: '角色', value: 'roles' },
 | 
			
		||||
  { label: 'cs.companyStructure.lastLogin', value: 'last_login' },
 | 
			
		||||
]
 | 
			
		||||
@@ -0,0 +1,279 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="builtin">
 | 
			
		||||
    <div class="builtin-tab">
 | 
			
		||||
      <div
 | 
			
		||||
        v-for="(item) in tabList"
 | 
			
		||||
        :key="item.key"
 | 
			
		||||
        :class="['builtin-tab-item', activeKey === item.key ? 'builtin-tab-item_active' : '']"
 | 
			
		||||
        @click="clickTab(item.key)"
 | 
			
		||||
      >
 | 
			
		||||
        <ops-icon :type="item.icon" class="builtin-tab-item-icon" />
 | 
			
		||||
        <span class="builtin-tab-item-title">{{ $t(item.title) }}</span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div
 | 
			
		||||
      v-if="activeKey === BUILT_IN_TYPE.DEPARTMENT"
 | 
			
		||||
      class="builtin-department"
 | 
			
		||||
    >
 | 
			
		||||
      <a-icon class="builtin-department-icon" type="info-circle" />
 | 
			
		||||
      <span class="builtin-department-tip">{{ $t('cmdb.ciType.departmentTip') }}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <a-form
 | 
			
		||||
      :form="form"
 | 
			
		||||
      v-show="activeKey === BUILT_IN_TYPE.USER"
 | 
			
		||||
      class="builtin-user"
 | 
			
		||||
    >
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        :label="$t('cmdb.ciType.filterUsers')"
 | 
			
		||||
        :label-col="formLayout.labelCol"
 | 
			
		||||
        :wrapper-col="formLayout.wrapperCol"
 | 
			
		||||
      >
 | 
			
		||||
        <UserFilterComp
 | 
			
		||||
          ref="userFilterRef"
 | 
			
		||||
        />
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        :label="$t('cmdb.ciType.departmentCascadeDisplay')"
 | 
			
		||||
        v-if="activeKey === BUILT_IN_TYPE.USER"
 | 
			
		||||
        :label-col="formLayout.labelCol"
 | 
			
		||||
        :wrapper-col="formLayout.wrapperCol"
 | 
			
		||||
      >
 | 
			
		||||
        <a-switch
 | 
			
		||||
          v-decorator="['cascade_display', { rules: [{ required: false }], valuePropName: 'checked', initialValue: false }]"
 | 
			
		||||
        ></a-switch>
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        v-if="activeKey === BUILT_IN_TYPE.USER"
 | 
			
		||||
        :label="$t('cmdb.ciType.displayValue')"
 | 
			
		||||
        :label-col="formLayout.labelCol"
 | 
			
		||||
        :wrapper-col="formLayout.wrapperCol"
 | 
			
		||||
      >
 | 
			
		||||
        <a-select
 | 
			
		||||
          class="builtin-select"
 | 
			
		||||
          v-decorator="['display_value', { rules: [{ required: true, message: $t('cmdb.ciType.displayValueSelectTip') }], initialValue: 'nickname' }]"
 | 
			
		||||
          showSearch
 | 
			
		||||
          optionFilterProp="title"
 | 
			
		||||
          :placeholder="$t('cmdb.ciType.displayValueSelectTip')"
 | 
			
		||||
        >
 | 
			
		||||
          <a-select-option
 | 
			
		||||
            v-for="(item) in DISPLAY_VALUE_SELECT"
 | 
			
		||||
            :value="item.value"
 | 
			
		||||
            :key="item.value"
 | 
			
		||||
            :title="$t(item.label)"
 | 
			
		||||
          >
 | 
			
		||||
            {{ $t(item.label) }}
 | 
			
		||||
          </a-select-option>
 | 
			
		||||
        </a-select>
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
    </a-form>
 | 
			
		||||
 | 
			
		||||
    <a-form
 | 
			
		||||
      :form="form"
 | 
			
		||||
      v-if="activeKey === BUILT_IN_TYPE.USER_GROUP"
 | 
			
		||||
      class="builtin-usergroup"
 | 
			
		||||
    >
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        :label="$t('cmdb.ciType.userGroup')"
 | 
			
		||||
        :label-col="formLayout.labelCol"
 | 
			
		||||
        :wrapper-col="formLayout.wrapperCol"
 | 
			
		||||
      >
 | 
			
		||||
        <a-select
 | 
			
		||||
          class="builtin-select"
 | 
			
		||||
          v-decorator="['user_group_key', { rules: [{ required: true, message: $t('cmdb.ciType.userGroupSelectTip') }] }]"
 | 
			
		||||
          showSearch
 | 
			
		||||
          optionFilterProp="title"
 | 
			
		||||
          :placeholder="$t('cmdb.ciType.userGroupSelectTip')"
 | 
			
		||||
        >
 | 
			
		||||
          <a-select-option
 | 
			
		||||
            v-for="(item) in userGroupList"
 | 
			
		||||
            :value="item.group_id"
 | 
			
		||||
            :key="item.group_id"
 | 
			
		||||
            :title="item.group_name"
 | 
			
		||||
          >
 | 
			
		||||
            {{ item.group_name }}
 | 
			
		||||
          </a-select-option>
 | 
			
		||||
        </a-select>
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
 | 
			
		||||
      <a-form-item
 | 
			
		||||
        :label-col="formLayout.labelCol"
 | 
			
		||||
        :wrapper-col="formLayout.wrapperCol"
 | 
			
		||||
        :label="$t('cmdb.ciType.displayValue')"
 | 
			
		||||
      >
 | 
			
		||||
        <a-select
 | 
			
		||||
          class="builtin-select"
 | 
			
		||||
          v-decorator="['display_value', { rules: [{ required: true, message: $t('cmdb.ciType.displayValueSelectTip') }], initialValue: 'nickname' }]"
 | 
			
		||||
          showSearch
 | 
			
		||||
          optionFilterProp="title"
 | 
			
		||||
          :placeholder="$t('cmdb.ciType.displayValueSelectTip')"
 | 
			
		||||
        >
 | 
			
		||||
          <a-select-option
 | 
			
		||||
            v-for="(item) in DISPLAY_VALUE_SELECT"
 | 
			
		||||
            :value="item.value"
 | 
			
		||||
            :key="item.value"
 | 
			
		||||
            :title="$t(item.label)"
 | 
			
		||||
          >
 | 
			
		||||
            {{ $t(item.label) }}
 | 
			
		||||
          </a-select-option>
 | 
			
		||||
        </a-select>
 | 
			
		||||
      </a-form-item>
 | 
			
		||||
    </a-form>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { BUILT_IN_TYPE, DISPLAY_VALUE_SELECT } from './constants.js'
 | 
			
		||||
import UserFilterComp from './userFilterComp/index.vue'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'PreValueBuiltIn',
 | 
			
		||||
  components: { UserFilterComp },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      BUILT_IN_TYPE,
 | 
			
		||||
      DISPLAY_VALUE_SELECT,
 | 
			
		||||
      activeKey: BUILT_IN_TYPE.DEPARTMENT,
 | 
			
		||||
      tabList: [
 | 
			
		||||
        {
 | 
			
		||||
          key: BUILT_IN_TYPE.DEPARTMENT,
 | 
			
		||||
          title: 'cmdb.ciType.department',
 | 
			
		||||
          icon: 'veops-department'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          key: BUILT_IN_TYPE.USER,
 | 
			
		||||
          title: 'cmdb.ciType.user',
 | 
			
		||||
          icon: 'icon-shidi-yonghu'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          key: BUILT_IN_TYPE.USER_GROUP,
 | 
			
		||||
          title: 'cmdb.ciType.userGroup',
 | 
			
		||||
          icon: 'ops-setting-group'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      userGroupList: [],
 | 
			
		||||
      allFlatEmployees: [],
 | 
			
		||||
      form: this.$form.createForm(this),
 | 
			
		||||
      formLayout: {
 | 
			
		||||
        labelCol: { span: 5 },
 | 
			
		||||
        wrapperCol: { span: 16 },
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    setData(data) {
 | 
			
		||||
      this.activeKey = data?.builtin_type || BUILT_IN_TYPE.DEPARTMENT
 | 
			
		||||
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        this.form.setFieldsValue({
 | 
			
		||||
          cascade_display: data?.cascade_display ?? false,
 | 
			
		||||
          display_value: data?.display_value ?? undefined,
 | 
			
		||||
          user_group_key: data?.user_group_key ?? undefined
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        this.$refs.userFilterRef.setRuleList(data?.filter_rule_list || [])
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getData() {
 | 
			
		||||
      let params = {}
 | 
			
		||||
      this.form.validateFields({ force: true }, (err, values) => {
 | 
			
		||||
        if (err) {
 | 
			
		||||
          params.isError = true
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        params = {
 | 
			
		||||
          ...values,
 | 
			
		||||
          builtin_type: this.activeKey,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.activeKey === BUILT_IN_TYPE.USER) {
 | 
			
		||||
          params.filter_rule_list = this.$refs.userFilterRef.getRuleList()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      return params
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async clickTab(key) {
 | 
			
		||||
      this.activeKey = key
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.builtin {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
 | 
			
		||||
  &-tab {
 | 
			
		||||
    padding: 4px 80px 20px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    gap: 60px;
 | 
			
		||||
 | 
			
		||||
    &-item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      border: solid 1px #E4E7ED;
 | 
			
		||||
      border-radius: 2px;
 | 
			
		||||
      padding: 0 20px;
 | 
			
		||||
      min-width: 72px;
 | 
			
		||||
      height: 64px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
 | 
			
		||||
      &-icon {
 | 
			
		||||
        font-size: 20px;
 | 
			
		||||
        color: #A5A9BC;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &-title {
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
        line-height: 14px;
 | 
			
		||||
        margin-top: 4px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &_active {
 | 
			
		||||
        border-color: #B1C9FF;
 | 
			
		||||
 | 
			
		||||
        .builtin-tab-item-icon {
 | 
			
		||||
          color: #7F97FA;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .builtin-tab-item-title {
 | 
			
		||||
          color: #2F54EB;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-department {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    margin-left: 60px;
 | 
			
		||||
 | 
			
		||||
    &-icon {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      color: #A5A9BC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &-tip {
 | 
			
		||||
      color: #4E5969;
 | 
			
		||||
      font-size: 14px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      margin-left: 4px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-select {
 | 
			
		||||
    width: 240px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
export const ruleTypeList = [
 | 
			
		||||
    { value: '&', label: 'cs.components.and' },
 | 
			
		||||
    { value: '|', label: 'cs.components.or' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const expList = [
 | 
			
		||||
    { value: 1, label: 'cs.components.equal' },
 | 
			
		||||
    { value: 2, label: 'cs.components.notEqual' },
 | 
			
		||||
    { value: 7, label: 'cs.components.isEmpty' },
 | 
			
		||||
    { value: 8, label: 'cs.components.isNotEmpty' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const compareTypeList = [
 | 
			
		||||
    { value: 5, label: 'cs.components.moreThan' },
 | 
			
		||||
    { value: 6, label: 'cs.components.lessThan' },
 | 
			
		||||
]
 | 
			
		||||
@@ -0,0 +1,143 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <treeselect
 | 
			
		||||
    class="employee-tree-select"
 | 
			
		||||
    :style="{ width: '100px' }"
 | 
			
		||||
    :disable-branch-nodes="!multiple"
 | 
			
		||||
    :multiple="multiple"
 | 
			
		||||
    :options="employeeTreeSelectOption"
 | 
			
		||||
    :placeholder="readOnly ? '' : placeholder || $t('cs.components.selectEmployee')"
 | 
			
		||||
    v-model="treeValue"
 | 
			
		||||
    :max-height="150"
 | 
			
		||||
    :noChildrenText="$t('cs.components.empty')"
 | 
			
		||||
    :noOptionsText="$t('cs.components.empty')"
 | 
			
		||||
    :class="className ? className : 'ops-setting-treeselect'"
 | 
			
		||||
    value-consists-of="LEAF_PRIORITY"
 | 
			
		||||
    :limit="limit"
 | 
			
		||||
    :limitText="(count) => `+ ${count}`"
 | 
			
		||||
    v-bind="$attrs"
 | 
			
		||||
    :zIndex="1050"
 | 
			
		||||
    :flat="flat"
 | 
			
		||||
  >
 | 
			
		||||
    <div
 | 
			
		||||
      :title="node.label"
 | 
			
		||||
      slot="option-label"
 | 
			
		||||
      slot-scope="{ node }"
 | 
			
		||||
      :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
    >
 | 
			
		||||
      {{ node.label }}
 | 
			
		||||
    </div>
 | 
			
		||||
  </treeselect>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Treeselect from '@riophae/vue-treeselect'
 | 
			
		||||
import { formatOption } from '@/utils/util'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'EmployeeTreeSelect',
 | 
			
		||||
  components: {
 | 
			
		||||
    Treeselect,
 | 
			
		||||
  },
 | 
			
		||||
  model: {
 | 
			
		||||
    prop: 'value',
 | 
			
		||||
    event: 'change',
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    value: {
 | 
			
		||||
      type: [String, Array, Number, null],
 | 
			
		||||
      default: null,
 | 
			
		||||
    },
 | 
			
		||||
    multiple: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
    className: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'ops-setting-treeselect',
 | 
			
		||||
    },
 | 
			
		||||
    placeholder: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '',
 | 
			
		||||
    },
 | 
			
		||||
    idType: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 3,
 | 
			
		||||
    },
 | 
			
		||||
    departmentKey: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'department_id',
 | 
			
		||||
    },
 | 
			
		||||
    employeeKey: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'employee_id',
 | 
			
		||||
    },
 | 
			
		||||
    limit: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 20,
 | 
			
		||||
    },
 | 
			
		||||
    flat: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {}
 | 
			
		||||
  },
 | 
			
		||||
  inject: {
 | 
			
		||||
    provide_allTreeDepAndEmp: {
 | 
			
		||||
      from: 'provide_allTreeDepAndEmp',
 | 
			
		||||
      default: () => {
 | 
			
		||||
        return () => {
 | 
			
		||||
          return []
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    readOnly: {
 | 
			
		||||
      from: 'readOnly',
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    treeValue: {
 | 
			
		||||
      get() {
 | 
			
		||||
        return this.value
 | 
			
		||||
      },
 | 
			
		||||
      set(val) {
 | 
			
		||||
        this.$emit('change', val)
 | 
			
		||||
        return val
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    allTreeDepAndEmp() {
 | 
			
		||||
      return this.provide_allTreeDepAndEmp()
 | 
			
		||||
    },
 | 
			
		||||
    employeeTreeSelectOption() {
 | 
			
		||||
      const option = formatOption(this.allTreeDepAndEmp, this.idType, false, this.departmentKey, this.employeeKey)
 | 
			
		||||
      return option
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  methods: {},
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.employee-tree-select {
 | 
			
		||||
  /deep/ .vue-treeselect__menu {
 | 
			
		||||
    width: 100px;
 | 
			
		||||
    overflow-x: auto;
 | 
			
		||||
 | 
			
		||||
    & > .vue-treeselect__list {
 | 
			
		||||
      width: fit-content;
 | 
			
		||||
      min-width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .vue-treeselect__label-container {
 | 
			
		||||
      width: max-content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .vue-treeselect__option {
 | 
			
		||||
      width: max-content;
 | 
			
		||||
      min-width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -0,0 +1,347 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="user-filter">
 | 
			
		||||
    <a-button
 | 
			
		||||
      v-if="!ruleList.length"
 | 
			
		||||
      type="primary"
 | 
			
		||||
      ghost
 | 
			
		||||
      size="small"
 | 
			
		||||
      class="add-btn"
 | 
			
		||||
      @click="handleAddRule"
 | 
			
		||||
    >
 | 
			
		||||
      <a-icon type="plus" />
 | 
			
		||||
      {{ $t('add') }}
 | 
			
		||||
    </a-button>
 | 
			
		||||
    <template v-else>
 | 
			
		||||
      <a-space :style="{ display: 'flex', marginBottom: '10px' }" v-for="(item, index) in ruleList" :key="item.id">
 | 
			
		||||
        <div :style="{ width: '50px', height: '24px', position: 'relative' }">
 | 
			
		||||
          <treeselect
 | 
			
		||||
            v-if="index"
 | 
			
		||||
            class="custom-treeselect"
 | 
			
		||||
            :style="{ width: '50px', '--custom-height': '36px', position: 'absolute', top: '-30px', left: 0 }"
 | 
			
		||||
            v-model="item.relation"
 | 
			
		||||
            :multiple="false"
 | 
			
		||||
            :clearable="false"
 | 
			
		||||
            searchable
 | 
			
		||||
            :options="ruleTypeList"
 | 
			
		||||
            :normalizer="
 | 
			
		||||
              (node) => {
 | 
			
		||||
                return {
 | 
			
		||||
                  id: node.value,
 | 
			
		||||
                  label: $t(node.label),
 | 
			
		||||
                  children: node.children,
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            "
 | 
			
		||||
          >
 | 
			
		||||
          </treeselect>
 | 
			
		||||
        </div>
 | 
			
		||||
        <treeselect
 | 
			
		||||
          class="custom-treeselect"
 | 
			
		||||
          :style="{ width: '140px', '--custom-height': '36px' }"
 | 
			
		||||
          v-model="item.column"
 | 
			
		||||
          :multiple="false"
 | 
			
		||||
          :clearable="false"
 | 
			
		||||
          searchable
 | 
			
		||||
          :options="userFilterSelect"
 | 
			
		||||
          :maxHeight="150"
 | 
			
		||||
          :normalizer="
 | 
			
		||||
            (node) => {
 | 
			
		||||
              return {
 | 
			
		||||
                id: node.value,
 | 
			
		||||
                label: $t(node.label),
 | 
			
		||||
                children: node.children,
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          "
 | 
			
		||||
        >
 | 
			
		||||
          <div
 | 
			
		||||
            slot="option-label"
 | 
			
		||||
            slot-scope="{ node }"
 | 
			
		||||
            :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
          >
 | 
			
		||||
            <a-tooltip :title="$t(node.label)">
 | 
			
		||||
              {{ $t(node.label) }}
 | 
			
		||||
            </a-tooltip>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
            slot="value-label"
 | 
			
		||||
            slot-scope="{ node }"
 | 
			
		||||
          >
 | 
			
		||||
            <a-tooltip :title="$t(node.label)">
 | 
			
		||||
              {{ $t(node.label) }}
 | 
			
		||||
            </a-tooltip>
 | 
			
		||||
          </div>
 | 
			
		||||
        </treeselect>
 | 
			
		||||
        <treeselect
 | 
			
		||||
          class="custom-treeselect"
 | 
			
		||||
          :style="{ width: '90px', '--custom-height': '36px' }"
 | 
			
		||||
          v-model="item.operator"
 | 
			
		||||
          :multiple="false"
 | 
			
		||||
          :clearable="false"
 | 
			
		||||
          searchable
 | 
			
		||||
          :options="[...expList, ...compareTypeList]"
 | 
			
		||||
          :maxHeight="150"
 | 
			
		||||
          :normalizer="
 | 
			
		||||
            (node) => {
 | 
			
		||||
              return {
 | 
			
		||||
                id: node.value,
 | 
			
		||||
                label: $t(node.label),
 | 
			
		||||
                children: node.children,
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          "
 | 
			
		||||
          @select="(value) => handleChangeExp(value, item, index)"
 | 
			
		||||
        >
 | 
			
		||||
          <div
 | 
			
		||||
            slot="option-label"
 | 
			
		||||
            slot-scope="{ node }"
 | 
			
		||||
            :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
          >
 | 
			
		||||
            <a-tooltip :title="$t(node.label)">
 | 
			
		||||
              {{ $t(node.label) }}
 | 
			
		||||
            </a-tooltip>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
            slot="value-label"
 | 
			
		||||
            slot-scope="{ node }"
 | 
			
		||||
          >
 | 
			
		||||
            <a-tooltip :title="$t(node.label)">
 | 
			
		||||
              {{ $t(node.label) }}
 | 
			
		||||
            </a-tooltip>
 | 
			
		||||
          </div>
 | 
			
		||||
        </treeselect>
 | 
			
		||||
        <treeselect
 | 
			
		||||
          class="custom-treeselect"
 | 
			
		||||
          :style="{ width: '100px', '--custom-height': '36px' }"
 | 
			
		||||
          v-model="item.value"
 | 
			
		||||
          :multiple="false"
 | 
			
		||||
          :clearable="false"
 | 
			
		||||
          searchable
 | 
			
		||||
          v-if="isChoiceByProperty(item.column) && (item.operator === 1 || item.operator === 2)"
 | 
			
		||||
          :options="getChoiceValueByProperty(item.column)"
 | 
			
		||||
          :placeholder="$t('cs.components.selectPlaceholder')"
 | 
			
		||||
          :normalizer="
 | 
			
		||||
            (node) => {
 | 
			
		||||
              return {
 | 
			
		||||
                id: node.value,
 | 
			
		||||
                label: $t(node.label),
 | 
			
		||||
                children: node.children,
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          "
 | 
			
		||||
        >
 | 
			
		||||
          <div
 | 
			
		||||
            :title="$t(node.label)"
 | 
			
		||||
            slot="option-label"
 | 
			
		||||
            slot-scope="{ node }"
 | 
			
		||||
            :style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
 | 
			
		||||
          >
 | 
			
		||||
            {{ $t(node.label) }}
 | 
			
		||||
          </div>
 | 
			
		||||
        </treeselect>
 | 
			
		||||
        <div v-else-if="item.column === 'direct_supervisor_id' && (item.operator === 1 || item.operator === 2)">
 | 
			
		||||
          <EmployeeTreeSelect v-model="item.value" className="custom-treeselect"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <a-input
 | 
			
		||||
          v-else-if="item.operator !== 7 && item.operator !== 8"
 | 
			
		||||
          size="small"
 | 
			
		||||
          v-model="item.value"
 | 
			
		||||
          :placeholder="item.exp === 'in' || item.exp === '~in' ? $t('cs.components.operatorInPlaceholder') : ''"
 | 
			
		||||
          class="ops-input"
 | 
			
		||||
        ></a-input>
 | 
			
		||||
        <a-tooltip :title="$t('cs.components.copy')">
 | 
			
		||||
          <a class="operation" @click="handleCopyRule(item)"><ops-icon type="veops-copy"/></a>
 | 
			
		||||
        </a-tooltip>
 | 
			
		||||
        <a-tooltip :title="$t('delete')">
 | 
			
		||||
          <a class="operation" @click="handleDeleteRule(item)"><ops-icon type="veops-reduce"/></a>
 | 
			
		||||
        </a-tooltip>
 | 
			
		||||
        <a-tooltip :title="$t('add')">
 | 
			
		||||
          <a class="operation" @click="handleAddRule"><ops-icon type="veops-increase"/></a>
 | 
			
		||||
        </a-tooltip>
 | 
			
		||||
      </a-space>
 | 
			
		||||
    </template>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { mapState } from 'vuex'
 | 
			
		||||
import _ from 'lodash'
 | 
			
		||||
import { v4 as uuidv4 } from 'uuid'
 | 
			
		||||
import Treeselect from '@riophae/vue-treeselect'
 | 
			
		||||
import { ruleTypeList, expList, compareTypeList } from './constants'
 | 
			
		||||
import { USER_FILTER_SELECT } from '../constants'
 | 
			
		||||
import EmployeeTreeSelect from './employeeTreeSelect.vue'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'UserFilterComp',
 | 
			
		||||
  components: {
 | 
			
		||||
    Treeselect,
 | 
			
		||||
    EmployeeTreeSelect
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      USER_FILTER_SELECT,
 | 
			
		||||
      ruleTypeList,
 | 
			
		||||
      expList,
 | 
			
		||||
      compareTypeList,
 | 
			
		||||
      ruleList: [],
 | 
			
		||||
      filterExp: '',
 | 
			
		||||
      userFilterSelect: [],
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(['user'])
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.initUserFilterSelect()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    initUserFilterSelect() {
 | 
			
		||||
      const permissions = this.user?.detailPermissions?.backend?.find((item) => item.name === 'Employee_Fields')?.permissions
 | 
			
		||||
      const userFilterSelect = USER_FILTER_SELECT.filter((item) => {
 | 
			
		||||
        return permissions.includes(item.value)
 | 
			
		||||
      })
 | 
			
		||||
      this.userFilterSelect = userFilterSelect
 | 
			
		||||
    },
 | 
			
		||||
    async setRuleList(ruleList) {
 | 
			
		||||
      this.ruleList = ruleList?.length ? ruleList : []
 | 
			
		||||
    },
 | 
			
		||||
    handleAddRule() {
 | 
			
		||||
      this.ruleList.push({
 | 
			
		||||
        id: uuidv4(),
 | 
			
		||||
        relation: '&',
 | 
			
		||||
        column: this.userFilterSelect?.[0]?.value ?? null,
 | 
			
		||||
        operator: 1,
 | 
			
		||||
        value: null,
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleCopyRule(item) {
 | 
			
		||||
      this.ruleList.push({ ...item, id: uuidv4() })
 | 
			
		||||
    },
 | 
			
		||||
    handleDeleteRule(item) {
 | 
			
		||||
      const idx = this.ruleList.findIndex((r) => r.id === item.id)
 | 
			
		||||
      if (idx > -1) {
 | 
			
		||||
        this.ruleList.splice(idx, 1)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getRuleList() {
 | 
			
		||||
      if (this.ruleList && this.ruleList.length) {
 | 
			
		||||
        const ruleList = _.cloneDeep(this.ruleList)
 | 
			
		||||
        ruleList.forEach((item, index) => {
 | 
			
		||||
          if (item.column === 'direct_supervisor_id') {
 | 
			
		||||
            ruleList[index].value = item.value ? (item.value + '').includes('-') ? +item.value.split('-')[1] : +item.value : 0
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        if (ruleList?.length > 0) {
 | 
			
		||||
          ruleList[0].relation = '&'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ruleList.map((rule) => {
 | 
			
		||||
          return _.omit(rule, 'id')
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return []
 | 
			
		||||
    },
 | 
			
		||||
    handleChangeExp({ value }, item, index) {
 | 
			
		||||
      const _ruleList = _.cloneDeep(this.ruleList)
 | 
			
		||||
      if (value === 7 || value === 8) {
 | 
			
		||||
         _ruleList[index] = {
 | 
			
		||||
          ..._ruleList[index],
 | 
			
		||||
          value: null,
 | 
			
		||||
          operator: value
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        _ruleList[index] = {
 | 
			
		||||
          ..._ruleList[index],
 | 
			
		||||
          operator: value,
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      this.ruleList = _ruleList
 | 
			
		||||
    },
 | 
			
		||||
    filterOption(input, option) {
 | 
			
		||||
      return option.componentOptions.children[1].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
 | 
			
		||||
    },
 | 
			
		||||
    isChoiceByProperty(column) {
 | 
			
		||||
      const _find = this.userFilterSelect.find((item) => item.value === column)
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find.is_choice
 | 
			
		||||
      }
 | 
			
		||||
      return false
 | 
			
		||||
    },
 | 
			
		||||
    getChoiceValueByProperty(column) {
 | 
			
		||||
      const _find = this.userFilterSelect.find((item) => item.value === column)
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find.choice_value
 | 
			
		||||
      }
 | 
			
		||||
      return []
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.user-filter {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  line-height: 36px;
 | 
			
		||||
 | 
			
		||||
  .ops-input {
 | 
			
		||||
    height: 36px;
 | 
			
		||||
    width: 100px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.table-filter {
 | 
			
		||||
  .table-filter-add {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
    & > a {
 | 
			
		||||
      padding: 2px 8px;
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: #f0faff;
 | 
			
		||||
        border-radius: 5px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .table-filter-extra-icon {
 | 
			
		||||
    padding: 0px 2px;
 | 
			
		||||
    &:hover {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      border-radius: 5px;
 | 
			
		||||
      background-color: #f0faff;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.add-btn {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  width: 80px;
 | 
			
		||||
  margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.table-filter-extra-operation {
 | 
			
		||||
  .ant-popover-inner-content {
 | 
			
		||||
    padding: 3px 4px;
 | 
			
		||||
    .operation {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      width: 90px;
 | 
			
		||||
      height: 30px;
 | 
			
		||||
      line-height: 30px;
 | 
			
		||||
      padding: 3px 4px;
 | 
			
		||||
      border-radius: 5px;
 | 
			
		||||
      transition: all 0.3s;
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: #f0faff;
 | 
			
		||||
      }
 | 
			
		||||
      > .anticon {
 | 
			
		||||
        margin-right: 10px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -39,3 +39,10 @@ export const compareTypeList = [
 | 
			
		||||
  { value: '3', label: '<' },
 | 
			
		||||
  { value: '4', label: '<=' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const ENUM_VALUE_TYPE = {
 | 
			
		||||
  INPUT: 'input',
 | 
			
		||||
  DATE: 'date',
 | 
			
		||||
  DATE_TIME: 'dateTIme',
 | 
			
		||||
  NUMBER: 'number'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,310 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <a-popover
 | 
			
		||||
      :visible="popoverVisible"
 | 
			
		||||
      placement="bottom"
 | 
			
		||||
      trigger="focus"
 | 
			
		||||
      overlayClassName="pre-value-edit-popover"
 | 
			
		||||
      @visibleChange="handleVisibleChange"
 | 
			
		||||
    >
 | 
			
		||||
      <div @click="popoverVisible = true" ref="popoverLabelRef">
 | 
			
		||||
        <a-input
 | 
			
		||||
          v-show="!labelData.label || popoverVisible"
 | 
			
		||||
          type="text"
 | 
			
		||||
          :style="{ width: '210px' }"
 | 
			
		||||
          :value="labelData.label"
 | 
			
		||||
          @change="changeLabel"
 | 
			
		||||
        >
 | 
			
		||||
        </a-input>
 | 
			
		||||
 | 
			
		||||
        <div
 | 
			
		||||
          class="pre-value-tag"
 | 
			
		||||
          :style="labelData.style ? labelData.style : {}"
 | 
			
		||||
          v-show="!popoverVisible && labelData.label"
 | 
			
		||||
        >
 | 
			
		||||
          <span>
 | 
			
		||||
            <img
 | 
			
		||||
              v-if="labelData.icon.id && labelData.icon.url"
 | 
			
		||||
              :src="`/api/common-setting/v1/file/${labelData.icon.url}`"
 | 
			
		||||
              :style="{ maxHeight: '12px', maxWidth: '12px', marginRight: '5px' }"
 | 
			
		||||
            />
 | 
			
		||||
            <ops-icon
 | 
			
		||||
              v-else-if="labelData.icon.name"
 | 
			
		||||
              :type="labelData.icon.name"
 | 
			
		||||
              :style="{ marginRight: '5px', color: labelData.icon.color || '#595959' }"
 | 
			
		||||
            />
 | 
			
		||||
            <a-tooltip :title="labelData.label">
 | 
			
		||||
              <span class="pre-value-tag-text">{{ labelData.label }}</span>
 | 
			
		||||
            </a-tooltip>
 | 
			
		||||
          </span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div ref="preValueEdit" slot="content">
 | 
			
		||||
        <a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('icon') }}</a-divider>
 | 
			
		||||
        <CustomIconSelect
 | 
			
		||||
          :style="{ marginLeft: '10px' }"
 | 
			
		||||
          :value="labelData.icon"
 | 
			
		||||
          @change="changeIcon"
 | 
			
		||||
        />
 | 
			
		||||
        <a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('cmdb.ciType.font') }}</a-divider>
 | 
			
		||||
        <div :style="{ display: 'flex', justifyContent: 'space-around' }">
 | 
			
		||||
          <div
 | 
			
		||||
            @click="changeFontStyle('fontWeight', 'bold')"
 | 
			
		||||
            :class="`attributes-font-icon ${labelData.style.fontWeight === 'bold' ? 'attributes-font-icon-selected' : ''}`"
 | 
			
		||||
          >
 | 
			
		||||
            <a-icon type="bold" />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            @click="changeFontStyle('fontStyle', 'italic')"
 | 
			
		||||
            :class="`attributes-font-icon ${labelData.style.fontStyle === 'italic' ? 'attributes-font-icon-selected' : ''}`"
 | 
			
		||||
          >
 | 
			
		||||
            <a-icon type="italic" />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            @click="changeFontStyle('textDecoration', 'underline')"
 | 
			
		||||
            :class="
 | 
			
		||||
              `attributes-font-icon ${labelData.style.textDecoration === 'underline' ? 'attributes-font-icon-selected' : ''}`
 | 
			
		||||
            "
 | 
			
		||||
          >
 | 
			
		||||
            <a-icon type="underline" />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('cmdb.ciType.color') }}</a-divider>
 | 
			
		||||
        <div :style="{ display: 'flex', justifyContent: 'space-around' }">
 | 
			
		||||
          <div class="attributes-font-color">
 | 
			
		||||
            <a-icon type="font-colors" />
 | 
			
		||||
            <el-color-picker
 | 
			
		||||
              size="mini"
 | 
			
		||||
              :value="labelData.style.color"
 | 
			
		||||
              @change="(v) => changeFontStyle('color', v)"
 | 
			
		||||
              :predefine="defaultBGColors"
 | 
			
		||||
            >
 | 
			
		||||
            </el-color-picker>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="attributes-font-color">
 | 
			
		||||
            <a-icon type="bg-colors" />
 | 
			
		||||
            <el-color-picker
 | 
			
		||||
              size="mini"
 | 
			
		||||
              :value="labelData.style.backgroundColor"
 | 
			
		||||
              @change="(v) => changeFontStyle('backgroundColor', v)"
 | 
			
		||||
              :predefine="defaultBGColors"
 | 
			
		||||
            >
 | 
			
		||||
            </el-color-picker>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('operation') }}</a-divider>
 | 
			
		||||
        <div style="text-align:right;">
 | 
			
		||||
          <a-tooltip
 | 
			
		||||
            :title="$t('delete')"
 | 
			
		||||
          >
 | 
			
		||||
            <a>
 | 
			
		||||
              <a-icon
 | 
			
		||||
                @click="handleDelete"
 | 
			
		||||
                style="margin-right:10px;color:red;"
 | 
			
		||||
                type="delete"
 | 
			
		||||
              />
 | 
			
		||||
            </a>
 | 
			
		||||
          </a-tooltip>
 | 
			
		||||
          <a-tooltip
 | 
			
		||||
            :title="$t('confirm')"
 | 
			
		||||
          >
 | 
			
		||||
            <a>
 | 
			
		||||
              <a-icon @click="popoverVisible = false" style="margin-right:10px;color:green;" type="check"/>
 | 
			
		||||
            </a>
 | 
			
		||||
          </a-tooltip>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </a-popover>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import _ from 'lodash'
 | 
			
		||||
import { ColorPicker } from 'element-ui'
 | 
			
		||||
import CustomIconSelect from '@/components/CustomIconSelect'
 | 
			
		||||
import { defautValueColor, defaultBGColors } from '@/modules/cmdb/utils/const.js'
 | 
			
		||||
import lang from 'element-ui/lib/locale/lang/en'
 | 
			
		||||
import locale from 'element-ui/lib/locale'
 | 
			
		||||
locale.use(lang)
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'DefineLabel',
 | 
			
		||||
  components: { ElColorPicker: ColorPicker, CustomIconSelect },
 | 
			
		||||
  props: {
 | 
			
		||||
    labelData: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: () => {},
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      defautValueColor,
 | 
			
		||||
      defaultBGColors,
 | 
			
		||||
      popoverVisible: false,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    document.addEventListener('click', this.eventListener)
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    document.removeEventListener('click', this.eventListener)
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    eventListener(e) {
 | 
			
		||||
      if (this.popoverVisible) {
 | 
			
		||||
        const dom = this.$refs.preValueEdit
 | 
			
		||||
        const dom_label = this.$refs.popoverLabelRef
 | 
			
		||||
        const dom_icon = document.getElementById(`custom-icon-select-popover`)
 | 
			
		||||
        e.stopPropagation()
 | 
			
		||||
        e.preventDefault()
 | 
			
		||||
        if (dom) {
 | 
			
		||||
          const isSelf =
 | 
			
		||||
            dom.contains(e.target) || (dom_label && dom_label.contains(e.target)) || (dom_icon && dom_icon.contains(e.target))
 | 
			
		||||
          if (!isSelf) {
 | 
			
		||||
            this.popoverVisible = false
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleDelete() {
 | 
			
		||||
      this.popoverVisible = false
 | 
			
		||||
      this.$emit('deleteData')
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeFontStyle(key, value) {
 | 
			
		||||
      const style = {
 | 
			
		||||
        ...(this.labelData.style || {}),
 | 
			
		||||
        [key]: this.labelData.style[key] === value ? 'initial' : value,
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('change', 'style', style)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeLabel(e) {
 | 
			
		||||
      const value = e.target.value
 | 
			
		||||
      this.$emit('change', 'label', value)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeIcon(value) {
 | 
			
		||||
      this.$emit('change', 'icon', value)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleVisibleChange(v) {
 | 
			
		||||
      if (!v) {
 | 
			
		||||
        this.popoverVisible = false
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.pre-value-edit-color {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  .pre-value-edit-color-item {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    width: 25px;
 | 
			
		||||
    height: 20px;
 | 
			
		||||
    margin: 5px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.pre-value-tag {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  padding: 4px 8px;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
 | 
			
		||||
  &-text {
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    text-wrap: nowrap;
 | 
			
		||||
    text-overflow: ellipsis;
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  > span {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &:hover .pre-value-tag-dropdown-icon {
 | 
			
		||||
    display: inline !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .pre-value-tag-dropdown {
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    color: #999999;
 | 
			
		||||
    &:hover {
 | 
			
		||||
      color: #2f54eb;
 | 
			
		||||
    }
 | 
			
		||||
    .pre-value-tag-dropdown-icon {
 | 
			
		||||
      display: none;
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      right: -10px;
 | 
			
		||||
      top: 8px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<style lang="less">
 | 
			
		||||
.pre-value-tag-input {
 | 
			
		||||
  border: none;
 | 
			
		||||
  border-bottom: 1px solid #d9d9d9;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  &:focus {
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.pre-value-edit-popover.ant-popover-placement-top .ant-popover-content {
 | 
			
		||||
  margin-bottom: -10px;
 | 
			
		||||
}
 | 
			
		||||
.pre-value-edit-popover.ant-popover-placement-bottom .ant-popover-content {
 | 
			
		||||
  margin-top: -10px;
 | 
			
		||||
}
 | 
			
		||||
.pre-value-edit-popover {
 | 
			
		||||
  .ant-popover-content {
 | 
			
		||||
    width: 150px;
 | 
			
		||||
    .ant-popover-arrow {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
    .ant-popover-inner-content {
 | 
			
		||||
      padding: 3px 4px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .attributes-font-icon {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    width: 30px;
 | 
			
		||||
    height: 30px;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    border: 1px solid #fff;
 | 
			
		||||
    &:hover {
 | 
			
		||||
      background-color: #eeeeee;
 | 
			
		||||
      border-color: #606266;
 | 
			
		||||
    }
 | 
			
		||||
    > i {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: 50%;
 | 
			
		||||
      left: 50%;
 | 
			
		||||
      transform: translate(-50%, -50%);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .attributes-font-icon-selected {
 | 
			
		||||
    background-color: #eeeeee;
 | 
			
		||||
  }
 | 
			
		||||
  .attributes-font-color {
 | 
			
		||||
    display: inline-flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    width: 50%;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -0,0 +1,245 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="define-wrap">
 | 
			
		||||
    <a-button
 | 
			
		||||
      v-if="!defineList.length"
 | 
			
		||||
      type="primary"
 | 
			
		||||
      ghost
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      size="small"
 | 
			
		||||
      class="add-btn"
 | 
			
		||||
      @click="addData"
 | 
			
		||||
    >
 | 
			
		||||
      <a-icon type="plus" />
 | 
			
		||||
      {{ $t('add') }}
 | 
			
		||||
    </a-button>
 | 
			
		||||
 | 
			
		||||
    <vxe-table
 | 
			
		||||
      v-else
 | 
			
		||||
      ref="xTable"
 | 
			
		||||
      :data="defineList"
 | 
			
		||||
      size="mini"
 | 
			
		||||
      show-header-overflow
 | 
			
		||||
      :row-config="{ height: 46 }"
 | 
			
		||||
      :min-height="75"
 | 
			
		||||
      border="outer"
 | 
			
		||||
      class="define-wrap-table"
 | 
			
		||||
    >
 | 
			
		||||
      <vxe-column field="value" width="230" :title="$t('cmdb.ciType.enumValue')">
 | 
			
		||||
        <template #header="{ column }">
 | 
			
		||||
          <span class="table-header-required">*</span>
 | 
			
		||||
          {{ column.title }}
 | 
			
		||||
        </template>
 | 
			
		||||
        <template #default="{ row, rowIndex }">
 | 
			
		||||
          <a-input
 | 
			
		||||
            v-if="enumValueType === ENUM_VALUE_TYPE.INPUT"
 | 
			
		||||
            :value="row.value"
 | 
			
		||||
            :placeholder="$t('cmdb.ciType.valueInputTip')"
 | 
			
		||||
            @change="(e) => changeValue(rowIndex, e.target.value)"
 | 
			
		||||
          ></a-input>
 | 
			
		||||
          <a-input-number
 | 
			
		||||
            v-else-if="enumValueType === ENUM_VALUE_TYPE.NUMBER"
 | 
			
		||||
            :value="row.value"
 | 
			
		||||
            @change="(v) => changeValue(rowIndex, v)"
 | 
			
		||||
          >
 | 
			
		||||
          </a-input-number>
 | 
			
		||||
          <a-date-picker
 | 
			
		||||
            v-else
 | 
			
		||||
            style="width: 100%"
 | 
			
		||||
            :value="row.value"
 | 
			
		||||
            :format="enumValueType === ENUM_VALUE_TYPE.DATE ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
 | 
			
		||||
            :showTime="enumValueType === ENUM_VALUE_TYPE.DATE ? false : { format: 'HH:mm:ss' }"
 | 
			
		||||
            @change="(e) => changeDate(rowIndex, e)"
 | 
			
		||||
          />
 | 
			
		||||
        </template>
 | 
			
		||||
      </vxe-column>
 | 
			
		||||
      <vxe-column width="230" :title="$t('cmdb.ciType.label')">
 | 
			
		||||
        <template #default="{ row, rowIndex }">
 | 
			
		||||
          <DefineLabel
 | 
			
		||||
            :labelData="row"
 | 
			
		||||
            @change="(key, value) => changeStyle(rowIndex, key, value)"
 | 
			
		||||
            @deleteData="handleClear(rowIndex)"
 | 
			
		||||
          />
 | 
			
		||||
        </template>
 | 
			
		||||
      </vxe-column>
 | 
			
		||||
    </vxe-table>
 | 
			
		||||
    <div class="define-wrap-action">
 | 
			
		||||
      <div
 | 
			
		||||
        v-for="(item, index) in defineList"
 | 
			
		||||
        :key="item.id"
 | 
			
		||||
        class="define-wrap-action-item"
 | 
			
		||||
      >
 | 
			
		||||
        <a-icon
 | 
			
		||||
          type="plus-circle"
 | 
			
		||||
          class="define-wrap-action-item-icon"
 | 
			
		||||
          @click="addData(index)"
 | 
			
		||||
        />
 | 
			
		||||
        <a-icon
 | 
			
		||||
          type="minus-circle"
 | 
			
		||||
          class="define-wrap-action-item-icon"
 | 
			
		||||
          @click="deleteData(index)"
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { v4 as uuidv4 } from 'uuid'
 | 
			
		||||
import _ from 'lodash'
 | 
			
		||||
import DefineLabel from './defineLabel.vue'
 | 
			
		||||
import { ENUM_VALUE_TYPE } from '../constants.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'PreValueDefine',
 | 
			
		||||
  components: {
 | 
			
		||||
    DefineLabel
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    value: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    },
 | 
			
		||||
    disabled: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    // 枚举值控件类型
 | 
			
		||||
    enumValueType: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ENUM_VALUE_TYPE.INPUT
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  model: {
 | 
			
		||||
    prop: 'value',
 | 
			
		||||
    event: 'change',
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      ENUM_VALUE_TYPE
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    defineList: {
 | 
			
		||||
      get() {
 | 
			
		||||
        return this.value.map((item) => {
 | 
			
		||||
          return {
 | 
			
		||||
            value: item?.[0] ?? '',
 | 
			
		||||
            ...(item?.[1] ?? {}),
 | 
			
		||||
            id: uuidv4()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      },
 | 
			
		||||
      set(val) {
 | 
			
		||||
        this.$emit('change', val.map((item) => {
 | 
			
		||||
          return [
 | 
			
		||||
            item?.value ?? '',
 | 
			
		||||
            {
 | 
			
		||||
              style: item?.style ?? {},
 | 
			
		||||
              icon: item?.icon ?? {},
 | 
			
		||||
              label: item?.label ?? '',
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        }))
 | 
			
		||||
        return val
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    addData(index) {
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list.splice(index + 1, 0, [
 | 
			
		||||
        '',
 | 
			
		||||
        {
 | 
			
		||||
          style: {},
 | 
			
		||||
          icon: {},
 | 
			
		||||
          label: ''
 | 
			
		||||
        }
 | 
			
		||||
      ])
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    },
 | 
			
		||||
    deleteData(index) {
 | 
			
		||||
      if (this.value.length <= 1) {
 | 
			
		||||
        this.$message.error(this.$t('cmdb.ad.deleteTip'))
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list.splice(index, 1)
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeValue(rowIndex, value) {
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list[rowIndex][0] = value
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeDate(rowIndex, e) {
 | 
			
		||||
      const format = this.enumValueType === ENUM_VALUE_TYPE.DATE ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
 | 
			
		||||
      const value = e.format(format)
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list[rowIndex][0] = value
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    changeStyle(rowIndex, key, value) {
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list[rowIndex][1] = {
 | 
			
		||||
        ...list[rowIndex][1],
 | 
			
		||||
        [key]: value
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleClear(rowIndex) {
 | 
			
		||||
      const list = _.cloneDeep(this.value)
 | 
			
		||||
      list[rowIndex][1] = {
 | 
			
		||||
        style: {},
 | 
			
		||||
        icon: {},
 | 
			
		||||
        label: ''
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('change', list)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
.define-wrap {
 | 
			
		||||
  display: flex;
 | 
			
		||||
 | 
			
		||||
  .add-btn {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    padding: 1px 7px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-table {
 | 
			
		||||
    flex-shrink: 0;
 | 
			
		||||
 | 
			
		||||
    .table-header-required {
 | 
			
		||||
      color: #FD4C6A;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /deep/ .ant-input-number {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-action {
 | 
			
		||||
    flex-shrink: 0;
 | 
			
		||||
    margin-left: 11px;
 | 
			
		||||
    padding-top: 36px;
 | 
			
		||||
 | 
			
		||||
    &-item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      height: 46px;
 | 
			
		||||
      gap: 12px;
 | 
			
		||||
 | 
			
		||||
      &-icon {
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        color: #2F54EB;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -179,6 +179,7 @@
 | 
			
		||||
          >
 | 
			
		||||
            <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in CITypes">
 | 
			
		||||
              {{ CIType.alias || CIType.name }}
 | 
			
		||||
              <span class="model-select-name">({{ CIType.name }})</span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
        </a-form-item>
 | 
			
		||||
@@ -674,6 +675,11 @@ export default {
 | 
			
		||||
.modal-attribute-action {
 | 
			
		||||
  margin-left: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.model-select-name {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  color: #A5A9BC;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<style lang="less">
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,10 @@
 | 
			
		||||
            @change="handleSourceTypeChange"
 | 
			
		||||
            :filterOption="filterOption"
 | 
			
		||||
          >
 | 
			
		||||
            <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">{{
 | 
			
		||||
              CIType.alias || CIType.name
 | 
			
		||||
            }}</a-select-option>
 | 
			
		||||
            <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">
 | 
			
		||||
              {{ CIType.alias || CIType.name }}
 | 
			
		||||
              <span class="model-select-name">({{ CIType.name }})</span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
        </a-form-item>
 | 
			
		||||
        <a-form-item :label="$t('cmdb.ciType.dstCIType')">
 | 
			
		||||
@@ -39,6 +40,7 @@
 | 
			
		||||
          >
 | 
			
		||||
            <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayTargetCITypes">
 | 
			
		||||
              {{ CIType.alias || CIType.name }}
 | 
			
		||||
              <span class="model-select-name">({{ CIType.name }})</span>
 | 
			
		||||
            </a-select-option>
 | 
			
		||||
          </a-select>
 | 
			
		||||
        </a-form-item>
 | 
			
		||||
@@ -408,4 +410,9 @@ export default {
 | 
			
		||||
.modal-attribute-action {
 | 
			
		||||
  margin-left: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.model-select-name {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  color: #A5A9BC;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,14 @@
 | 
			
		||||
                {{ id }}
 | 
			
		||||
              </a>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template #default="{row}" v-else-if="col.is_choice">
 | 
			
		||||
              <span
 | 
			
		||||
                v-for="value in (col.is_list ? row[col.field] : [row[col.field]])"
 | 
			
		||||
                :key="value"
 | 
			
		||||
              >
 | 
			
		||||
                {{ getChoiceValueLabel(col, value) || value }}
 | 
			
		||||
              </span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template #default="{row}" v-else-if="col.value_type == '6'">
 | 
			
		||||
              <span v-if="col.value_type == '6' && row[col.field]">{{ JSON.stringify(row[col.field]) }}</span>
 | 
			
		||||
            </template>
 | 
			
		||||
@@ -253,6 +261,14 @@ export default {
 | 
			
		||||
      this.currentPage = page
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getChoiceValueLabel(col, colValue) {
 | 
			
		||||
      const _find = col.filters.find((item) => String(item[0]) === String(colValue))
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find[1]?.label || ''
 | 
			
		||||
      }
 | 
			
		||||
      return ''
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@
 | 
			
		||||
                "
 | 
			
		||||
                target="_blank"
 | 
			
		||||
              >
 | 
			
		||||
                {{ item }}
 | 
			
		||||
                {{ getChoiceValueLabel(col, item) || item }}
 | 
			
		||||
              </a>
 | 
			
		||||
            </template>
 | 
			
		||||
            <PasswordField
 | 
			
		||||
@@ -143,11 +143,13 @@
 | 
			
		||||
                    margin: '2px',
 | 
			
		||||
                    ...getChoiceValueStyle(col, value),
 | 
			
		||||
                  }"
 | 
			
		||||
                ><ops-icon
 | 
			
		||||
                  :style="{ color: getChoiceValueIcon(col, value).color }"
 | 
			
		||||
                  :type="getChoiceValueIcon(col, value).name"
 | 
			
		||||
                />{{ value }}</span
 | 
			
		||||
                >
 | 
			
		||||
                  <ops-icon
 | 
			
		||||
                    :style="{ color: getChoiceValueIcon(col, value).color }"
 | 
			
		||||
                    :type="getChoiceValueIcon(col, value).name"
 | 
			
		||||
                  />
 | 
			
		||||
                  {{ getChoiceValueLabel(col, value) || value }}
 | 
			
		||||
                </span>
 | 
			
		||||
              </template>
 | 
			
		||||
              <span
 | 
			
		||||
                v-else
 | 
			
		||||
@@ -162,8 +164,8 @@
 | 
			
		||||
                  :style="{ color: getChoiceValueIcon(col, row[col.field]).color }"
 | 
			
		||||
                  :type="getChoiceValueIcon(col, row[col.field]).name"
 | 
			
		||||
                />
 | 
			
		||||
                {{ row[col.field] }}</span
 | 
			
		||||
              >
 | 
			
		||||
                {{ getChoiceValueLabel(col, row[col.field]) || row[col.field] }}
 | 
			
		||||
              </span>
 | 
			
		||||
            </template>
 | 
			
		||||
          </template>
 | 
			
		||||
        </vxe-column>
 | 
			
		||||
@@ -582,6 +584,13 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
      return {}
 | 
			
		||||
    },
 | 
			
		||||
    getChoiceValueLabel(col, colValue) {
 | 
			
		||||
      const _find = col?.filters?.find((item) => String(item[0]) === String(colValue))
 | 
			
		||||
      if (_find) {
 | 
			
		||||
        return _find[1]?.label || ''
 | 
			
		||||
      }
 | 
			
		||||
      return ''
 | 
			
		||||
    },
 | 
			
		||||
    handleExport() {
 | 
			
		||||
      this.$refs.batchDownload.open({
 | 
			
		||||
        preferenceAttrList: [
 | 
			
		||||
@@ -611,6 +620,7 @@ export default {
 | 
			
		||||
            return { ...item }
 | 
			
		||||
          }),
 | 
			
		||||
        ],
 | 
			
		||||
        original: true,
 | 
			
		||||
        download: false,
 | 
			
		||||
      })
 | 
			
		||||
      this.selectedRowKeys = []
 | 
			
		||||
 
 | 
			
		||||
@@ -1185,7 +1185,23 @@ export default {
 | 
			
		||||
            if (!res.result.length) {
 | 
			
		||||
              this.handleNullNodeTips(this.$t('cmdb.topo.noInstancePerm'))
 | 
			
		||||
            } else {
 | 
			
		||||
              this.currentNodeValues = res.result[0]
 | 
			
		||||
              const currentNodeValues = res.result[0]
 | 
			
		||||
              Object.keys(currentNodeValues).forEach((key) => {
 | 
			
		||||
                const attr = this.currentNodeAttributes.find((attr) => attr.name === key)
 | 
			
		||||
                if (attr?.choice_value?.length) {
 | 
			
		||||
                  if (Array.isArray(currentNodeValues[key])) {
 | 
			
		||||
                    currentNodeValues[key] = currentNodeValues[key].map((value) => {
 | 
			
		||||
                      const choice = attr.choice_value.find((choice) => value === choice?.[0])
 | 
			
		||||
                      return choice?.[1]?.label || value
 | 
			
		||||
                    })
 | 
			
		||||
                  } else {
 | 
			
		||||
                    const choice = attr.choice_value.find((choice) => currentNodeValues[key] === choice?.[0])
 | 
			
		||||
                    currentNodeValues[key] = choice?.[1]?.label || currentNodeValues[key]
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              })
 | 
			
		||||
 | 
			
		||||
              this.currentNodeValues = currentNodeValues
 | 
			
		||||
            }
 | 
			
		||||
          }).catch(error => {
 | 
			
		||||
            this.handleNullNodeTips(((error.response || {}).data || {}).message)
 | 
			
		||||
 
 | 
			
		||||
@@ -375,10 +375,9 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    async getAttributeList() {
 | 
			
		||||
      await getCITypeAttributesById(Number(this.typeId)).then((res) => {
 | 
			
		||||
        this.attrList = res.attributes
 | 
			
		||||
        this.attributes = res
 | 
			
		||||
      })
 | 
			
		||||
      const res = await getCITypeAttributesById(Number(this.typeId))
 | 
			
		||||
      this.attrList = res.attributes
 | 
			
		||||
      this.attributes = res
 | 
			
		||||
    },
 | 
			
		||||
    async getTreeViews() {
 | 
			
		||||
      this.subscribeTreeViewCiTypesLoading = true
 | 
			
		||||
@@ -519,10 +518,18 @@ export default {
 | 
			
		||||
 | 
			
		||||
    wrapTreeData(facet) {
 | 
			
		||||
      // 切面
 | 
			
		||||
      console.log('facet', facet)
 | 
			
		||||
      const _treeData = Object.values(facet)[0].map((item) => {
 | 
			
		||||
        let title = item[0]
 | 
			
		||||
        const attr = this.attrList.find((attr) => attr.name === item[2])
 | 
			
		||||
        if (attr?.choice_value?.length) {
 | 
			
		||||
          const choice = attr.choice_value.find((choice) => item[0] === choice?.[0])
 | 
			
		||||
          if (choice?.[1]?.label) {
 | 
			
		||||
            title = choice[1].label
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          title: item[0],
 | 
			
		||||
          title: title,
 | 
			
		||||
          childLength: item[1],
 | 
			
		||||
          key: this.treeKeys.join(this.keySplit) + this.keySplit + item[0],
 | 
			
		||||
          isLeaf: this.levels.length - 1 === this.treeKeys.length,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user