InputChannel.vue 3.69 KB
<template>
  <div v-for="(param, index) in dynamicInput.params" :key="index" class="mt-4 flex gap-2">
    <a-input disabled v-model:value="param.deviceName" class="w-1/2 flex-1" />
    <Select
      :placeholder="t('common.placeSelectChannelNumber')"
      v-model:value="param.channelNos"
      class="!w-1/2"
      :options="selectOptions"
      v-bind="createPickerSearch()"
      :disabled="disabled"
      @change="handleChange"
      mode="multiple"
      allowClear
    />
  </div>
</template>
<script lang="ts">
  export default {
    inheritAttrs: false,
  };
</script>
<script lang="ts" setup name="SelectAttributes">
  import { reactive, UnwrapRef, watchEffect, ref } from 'vue';
  import { propTypes } from '/@/utils/propTypes';
  import { DeviceChannelInterface } from '../config.data';
  import { createPickerSearch } from '/@/utils/pickerSearch';
  import { Select } from 'ant-design-vue';
  import { getDeviceChannelList } from '/@/api/camera/cameraManager';
  import { isArray } from '/@/utils/is';
  import cloneDeep from 'lodash-es/cloneDeep';
  import { useI18n } from '/@/hooks/web/useI18n';

  const props = defineProps({
    value: propTypes.object.def({}),
    disabled: {
      type: Boolean,
      required: false,
    },
  });

  const { t } = useI18n();

  const selectOptions = ref<LabelValueOptions>([]);

  //动态数据
  const dynamicInput: UnwrapRef<{ params: DeviceChannelInterface[] }> = reactive({ params: [] });

  const initVal = async () => {
    if (props.value?.value) {
      const res = await getDeviceChannelList(props.value?.value);
      if (isArray(res) && res.length !== 0) {
        selectOptions.value = res.map((channelItem) => ({
          label: channelItem.name,
          value: channelItem.channelId,
        }));
        selectOptions.value.unshift({
          label: t('common.selectAll'),
          value: 'all',
        });
      }
    }
    if (props.value) {
      dynamicInput.params.push({
        deviceName: props.value.label,
        deviceID: props.value.value,
        channelNos: props.value.channelNos,
      });
    }
  };

  //数值改变
  const valEffect = watchEffect(() => {
    initVal();
  });

  valEffect();

  const selectValues = ref<string[]>([]); // 保存选择的值

  const saveSelectValues = ref<Recordable>({});

  //chang改变
  const emitChange = () => {
    return saveSelectValues.value;
  };

  const excludeKeyAllValue = (value: LabelValueOptions) => {
    return value?.filter((selectItem) => selectItem.value !== 'all');
  };

  const handleChange = (_, options) => {
    // 全选
    const findSelectAll = options?.find((optionItem) => optionItem.value === 'all')?.value;
    if (findSelectAll) {
      dynamicInput.params[0].channelNos = ['all']; //全选
      excludeKeyAllValue(selectOptions.value)?.forEach(
        (disabledItem) => (disabledItem.disabled = true)
      );
      selectValues.value = cloneDeep(selectOptions.value)
        ?.filter((selectItem) => selectItem.value !== 'all')
        ?.map((mapItem) => mapItem.value);
    } else {
      excludeKeyAllValue(selectOptions.value)?.forEach(
        (disabledItem) => (disabledItem.disabled = false)
      );
    }
    const data = cloneDeep(options)?.map((mapItem) => mapItem.value);
    saveSelectValues.value = {
      ...dynamicInput.params[0],
      channelNos: findSelectAll ? selectValues.value : data,
    };
  };

  defineExpose({
    emitChange,
  });
</script>
<style scoped lang="css">
  .dynamic-delete-button {
    cursor: pointer;
    position: relative;
    top: 4px;
    font-size: 24px;
    color: #999;
    transition: all 0.3s;
  }

  .dynamic-delete-button:hover {
    color: #777;
  }

  .dynamic-delete-button[disabled] {
    cursor: not-allowed;
    opacity: 0.5;
  }
</style>