From 55bf797dcc730b37bc691ebab2b51ff9db8ed245 Mon Sep 17 00:00:00 2001
From: zs <zhousong@weben-smart.com>
Date: 周二, 06 5月 2025 17:37:23 +0800
Subject: [PATCH] 修改代码样式

---
 HIAWms/web/src/components/Tag/Tag.tsx |  344 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 344 insertions(+), 0 deletions(-)

diff --git a/HIAWms/web/src/components/Tag/Tag.tsx b/HIAWms/web/src/components/Tag/Tag.tsx
new file mode 100644
index 0000000..45430ae
--- /dev/null
+++ b/HIAWms/web/src/components/Tag/Tag.tsx
@@ -0,0 +1,344 @@
+import {
+  defineComponent,
+  computed,
+  SetupContext,
+  ref,
+  PropType,
+  Fragment,
+  DefineComponent,
+  Component,
+} from 'vue'
+import styles from './Tag.module.scss'
+import Empty from '../Empty/Empty'
+import Icon from '../Icon/Icon'
+import isNil from 'lodash/isNil'
+interface OptionType {
+  label: string
+  value: string
+  name: string
+}
+
+interface DataType {
+  name?: string
+  label?: string
+  value?: string
+  description?: string
+  type?: string
+  [key: string]: any
+}
+
+interface TagProps {
+  data: DataType[]
+  options: OptionType[]
+  modelValue: string
+  [key: string]: any
+}
+
+export default defineComponent<TagProps>({
+  // @ts-ignore
+  name: 'Tag',
+  emits: ['click', 'update:modelValue', 'change', 'mouseenter', 'update:data'],
+  props: {
+    data: {
+      type: [Array, Object],
+      default: null,
+    },
+    options: {
+      type: Array,
+      default: null,
+    },
+    modelValue: {
+      type: [String, Number],
+      default: '',
+    },
+    trigger: {
+      type: String,
+      default: 'hover',
+    },
+    showClose: {
+      type: Boolean,
+      default: false,
+    },
+    showTip: {
+      type: Boolean,
+      default: false,
+    },
+    valueKey: {
+      type: String,
+      default: 'value',
+    },
+    labelKey: {
+      type: String,
+      default: 'label',
+    },
+    // 榛樿鍊�
+    defaultValue: {
+      type: String,
+      default: '',
+    },
+    // 榛樿鍊�
+    max: {
+      type: Number,
+      default: 999,
+    },
+  },
+  setup(props: TagProps, { attrs, slots, emit }: SetupContext) {
+    const key = props.valueKey
+    const label = props.labelKey
+    const visible = ref(false)
+
+    const modelData = computed({
+      get() {
+        return props.modelValue
+      },
+      set(value) {
+        emit('update:modelValue', value)
+      },
+    })
+    const data = computed({
+      get() {
+        return props.data
+      },
+      set(value) {
+        emit('update:data', value)
+      },
+    })
+    /**
+     * 閫夐」map
+     */
+    const optionsMap = computed(() => {
+      const acc: Record<string, any> = {}
+      props.options?.forEach((item: any) => {
+        acc[item[key]] = item
+      })
+      return acc
+    })
+    /**
+     * 鏍规嵁value鏌ユ壘label
+     * @param value
+     * @returns
+     */
+    const findOptionLabelByValue = (value: string) => {
+      const item: Record<string, any> = optionsMap.value[value]
+      return (
+        item?.[label] ||
+        item?.label ||
+        item?.name ||
+        props.defaultValue ||
+        value ||
+        ''
+      )
+    }
+    /**
+     * 閫夋嫨
+     * @param v
+     */
+    const onCommand = (v: any) => {
+      modelData.value = v
+      emit('change', modelData.value)
+    }
+    /**
+     * hover鏃惰Е鍙�
+     */
+    const onMouseenter = () => {
+      emit('mouseenter')
+    }
+
+    const currentName = computed(() => {
+      const v = modelData.value
+      return findOptionLabelByValue(v)
+    })
+    /**
+     * 褰搗-model:data鏃讹紝鐢熸晥
+     */
+    const onClose = (item: DataType, evt: Event) => {
+      evt?.stopPropagation()
+      data.value = data.value.filter((i) => i !== item)
+    }
+
+    const onVisibleChange = (v: boolean) => {
+      visible.value = v
+    }
+
+    /**
+     * click
+     * @param evt Event
+     */
+    const onClick = (evt: Event) => {
+      evt?.stopPropagation()
+      emit('click', evt)
+    }
+
+    const Tip = ($props: any, { slots }: SetupContext) => {
+      if ($props.showTip) {
+        return (
+          <el-tooltip
+            class="box-item"
+            effect="dark"
+            content={`<div style="max-width: 300px">${$props.v}</div>`}
+            raw-content
+            placement="top"
+            persistent={false}
+          >
+            {slots.default?.()}
+          </el-tooltip>
+          // <span title={$props.v}>{slots.default?.()}</span>
+        )
+      }
+      return slots.default?.()
+    }
+
+    const DRender: Component = () => {
+      const hideTip = !props.showTip
+      let max = props.max >= props.data.length ? props.data.length : props.max
+      max = max == 0 ? 1 : max
+      const d = props.data.slice(0, max) || []
+      const tags = d.map((item: DataType, index: any) => {
+        const msg =
+          item[label] ||
+          item.name ||
+          item.label ||
+          item.description ||
+          item.type
+        return (
+          <span
+            class={styles.tag}
+            style="margin: 0 5px 3px 0;cursor: initial;"
+            key={index}
+            onClick={onClick}
+          >
+            {hideTip ? (
+              // @ts-ignore
+              <Tip showTip={hideTip} v={msg}>
+                {msg}
+              </Tip>
+            ) : (
+              msg
+            )}
+
+            {props.showClose ? (
+              <Icon
+                class={styles.tagClose}
+                icon="tag_close"
+                width={8}
+                height={8}
+                onClick={(evt) => onClose(item, evt)}
+              />
+            ) : null}
+          </span>
+        )
+      })
+      if (props.data.length > max) {
+        const l = props.data.length - max
+        tags.push(
+          <div
+            class={styles.more}
+            style={{ fontSize: l >= 100 ? '11px' : '12px' }}
+          >
+            +{l}
+          </div>
+        )
+      }
+      return tags
+    }
+
+    return () => {
+      // showTip
+      // 澶歵ag鎯呭喌锛屼紶data[]
+      if (Array.isArray(props.data)) {
+        const msg = (item: DataType) =>
+          item[label] ||
+          item.name ||
+          item.label ||
+          item.description ||
+          item.type
+        const v = props.data.map((item) => msg(item))?.join('锛�')
+        return (
+          // @ts-ignore
+          <Tip showTip={props.showTip} v={v}>
+            <div class={styles.flex}>
+              <DRender />
+            </div>
+          </Tip>
+        )
+      }
+      // 涓嬫媺閫夋嫨hover
+      if (Array.isArray(props.options)) {
+        return (
+          <el-dropdown
+            trigger={'click'}
+            popperClass={styles.dropdown}
+            onCommand={onCommand}
+            placement="bottom-start"
+            max-height="230px"
+            onVisibleChange={onVisibleChange}
+            vSlots={{
+              dropdown: () =>
+                props.options.length ? (
+                  <el-dropdown-menu>
+                    {props.options.map((item: OptionType | any) => {
+                      return (
+                        <el-dropdown-item
+                          title={item[label] || item.label || item.name}
+                          command={item[key]}
+                          class={{
+                            [styles.isSelect]: modelData.value === item[key],
+                          }}
+                        >
+                          {item[label] || item.label || item.name}
+                        </el-dropdown-item>
+                      )
+                    })}
+                  </el-dropdown-menu>
+                ) : (
+                  <Empty />
+                ),
+            }}
+          >
+            <div
+              onMouseenter={onMouseenter}
+              class={{
+                [styles.tagSelect]: true,
+                [styles.isSelectTag]: visible.value,
+              }}
+            >
+              {!isNil(modelData.value) && currentName.value ? (
+                <span class={styles.tag} onClick={() => emit('click')}>
+                  {currentName.value}
+                </span>
+              ) : (
+                <div class={styles.pl}>璇烽�夋嫨</div>
+              )}
+              <Icon
+                class={styles.iconDown}
+                style={{
+                  transform: visible.value ? 'rotate(-180deg)' : 'rotate(0deg)',
+                }}
+                icon="d"
+                width={13}
+                height={12}
+              />
+            </div>
+          </el-dropdown>
+        )
+      }
+      // 榛樿鍙睍绀轰竴涓猼ag
+
+      const content = slots.default && slots.default()[0]?.children
+
+      return (
+        <span class={styles.tag} onClick={() => emit('click')}>
+          <el-tooltip
+            persistent={false}
+            class="box-item"
+            effect="dark"
+            content={content}
+            placement="top"
+          >
+            {slots.default && slots.default()}
+          </el-tooltip>
+        </span>
+      )
+    }
+  },
+})

--
Gitblit v1.9.3