action.vue 11.3 KB
<template>
  <CollapseContainer style="background-color: #f2f2f2" :title="`执行动作 ${actionIndex + 1}`">
    <template #action>
      <Tooltip title="移除" v-if="actionData.length > 1">
        <Icon
          icon="fluent:delete-off-20-regular"
          size="20"
          class="mr-2 cursor-pointer"
          @click="handleDelete(actionIndex)"
        />
      </Tooltip>
    </template>
    <BasicForm @register="registerAction">
      <template #outTarget="{ model, field }">
        <Select
          :options="options"
          v-model:value="model[field]"
          @change="changeOutTarget"
          placeholder="请选择执行动作"
          allowClear
      /></template>
      <template #alarmConfigSlot="{ model, field }">
        <a-select
          allowClear
          placeholder="请选择告警配置"
          v-model:value="model[field]"
          style="width: 205px; margin-left: 10px"
          :options="alarmConfigOptions.map((item) => ({ value: item.value, label: item.label }))"
        >
          <template #dropdownRender="{ menuNode: menu }">
            <v-nodes :vnodes="menu" />
            <a-divider style="margin: 4px 0" />
            <div @click="handleOpenAlarmConfig" style="padding: 4px 0; cursor: pointer">
              <plus-outlined />
              新增告警配置
            </div>
          </template>
        </a-select>
      </template>
      <template #doContext>
        <div class="flex">
          <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
          <Tooltip
            title='{"method":"setDOValue","params":{"devID":"492S211218028819","data":{"DO1":1}}}'
            class="ml-2"
          >
            <QuestionCircleOutlined style="font-size: 1rem" />
          </Tooltip>
        </div>
      </template>
      <template #clearAlarm>
        <Checkbox v-model:checked="checked" @change="handleCheckedChange"> 清除告警 </Checkbox>
        <Tooltip title="清除告警与触发器一一对应">
          <QuestionCircleOutlined />
        </Tooltip>
      </template>
    </BasicForm>
    <template v-for="(item, index) in clearRuleList" :key="item">
      <Card
        :bordered="false"
        style="border: 2px dashed #d9d9d9; margin-top: 1rem"
        :bodyStyle="{ padding: 0 }"
      >
        <ClearAlarm
          :clearRuleList="clearRuleList"
          :index="index"
          :ref="refItem.clearRuleRefs"
          @delete="deleteClearRule"
        />
      </Card>
    </template>

    <a-button v-if="checked && isAddClearRule" class="mt-4" type="primary" @click="addClearRule"
      >新增清除告警</a-button
    >
  </CollapseContainer>
  <AlarmConfigDrawer @register="registerAlarmContactDrawer" @success="handleSuccess" />
</template>

<script lang="ts">
  import { defineComponent } from 'vue';
  export default defineComponent({
    components: {
      VNodes: (_, { attrs }) => {
        return attrs.vnodes;
      },
    },
    inheritAttrs: false,
  });
</script>
<script lang="ts" setup>
  import { ref, onMounted, nextTick, unref, computed, provide } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { Tooltip, Select, Checkbox, Card } from 'ant-design-vue';
  import { Icon } from '/@/components/Icon';
  import { actionSchema } from '../config/config.data';
  import jsoneditor from 'jsoneditor';
  import 'jsoneditor/dist/jsoneditor.min.css';
  import { QuestionCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
  import ClearAlarm from './ClearAlarm.vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useDrawer } from '/@/components/Drawer';
  import AlarmConfigDrawer from '/@/views/alarm/config/ContactDrawer.vue';

  const props = defineProps({
    actionIndex: {
      type: Number,
      required: true,
    },
    actionData: {
      type: Array,
      default: () => [],
    },
    triggerData: {
      type: Array,
      default: () => [],
    },
    deviceList: {
      type: Array,
      required: true,
    },
    arr: {
      type: Array,
      default: () => [],
    },
    provideOrgid: {
      type: String,
      default: '',
    },
  });
  const alarmConfigOptions: any = ref([]);
  const [registerAlarmContactDrawer, { openDrawer }] = useDrawer();
  async function handleSuccess() {
    emit('dynamicChangeAlarmConfig');
  }
  // 新增或编辑
  const handleOpenAlarmConfig = () => {
    openDrawer(true, {
      isUpdate: false,
    });
  };
  const isAddClearRule = computed(() => clearRuleList.value.length < props.triggerData.length);
  const refItem = {
    clearRuleRefs: ref([]),
  };
  const { createMessage } = useMessage();

  const emit = defineEmits(['deleteAction', 'getActionFormArr', 'dynamicChangeAlarmConfig']);
  const options = computed(() => {
    return [
      { label: '设备输出', value: 'DEVICE_OUT' },
      {
        label: '告警输出',
        value: 'MSG_NOTIFY',
        disabled:
          props.arr.filter((item) => item.outTarget === 'MSG_NOTIFY').length ||
          !props.triggerData.length,
      },
    ];
  });
  const changeOutTarget = () => {
    emit('getActionFormArr');
  };
  const [registerAction, { getFieldsValue, resetFields, updateSchema, setFieldsValue, validate }] =
    useForm({
      schemas: actionSchema,
      showActionButtonGroup: false,
    });

  // 获取整个执行动作表单值
  const getFieldsValueFunc = () => {
    const clearRule = refItem.clearRuleRefs.value.map((item) => {
      const predicate = item.conditionScreeningRef?.refItem?.conditionScreeningRefs?.value?.map(
        (item) => item.getFieldsValue()
      );
      return {
        ...item.getFieldsValue(),
        predicate,
        schedule: item.alarmScheduleRef.scheduleData,
      };
    });
    //TODO-fengtao-清除告警验证
    let deviceIdIsRequired = false;
    let attrIsRequired = false;
    let predicateIsRequired = false;
    let predicateDoubleIsRequired = false;
    let triggerTypeIsRequired = false;
    let type1IsRequired = false;
    if (clearRule) {
      clearRule.some((s) => {
        if (s.device == 'PART') {
          if (s.entityId == undefined) {
            deviceIdIsRequired = true;
          }
        }
        if (s.type2 == '' || s.type2 == null) {
          attrIsRequired = true;
        }
        if (s.type1 == '' || s.type1 == null) {
          type1IsRequired = true;
        }
        if (s.triggerType == '' || s.triggerType == null || s.triggerType == undefined) {
          triggerTypeIsRequired = true;
        }
        if (s.predicate == undefined) {
          predicateIsRequired = true;
        }
        if (s?.predicate) {
          s?.predicate.some((f) => {
            let arr = Object.keys(f);
            if (arr.length == 0) {
              predicateDoubleIsRequired = true;
            }
            if (f.operation == undefined) {
              predicateDoubleIsRequired = true;
            }
            if (f.value == undefined) {
              predicateDoubleIsRequired = true;
            }
          });
        }
      });
    }
    if (deviceIdIsRequired) return createMessage.error('请选择设备');
    if (attrIsRequired) return createMessage.error('请选择属性');
    if (predicateIsRequired) return createMessage.error('请填写条件筛选');
    if (predicateDoubleIsRequired) return createMessage.error('请填写条件筛选');
    if (triggerTypeIsRequired) return createMessage.error('请选择设备触发方式');
    if (type1IsRequired) return createMessage.error('请选择属性触发方式');
    //TODO-fengtao-清除告警验证
    //TODO-fengtao-设备验证
    const validate = getFieldsValue();
    if (validate.device == 'PART') {
      if (validate.deviceId == undefined) return createMessage.error('请选择设备');
    }
    //TODO-fengtao-设备验证
    return {
      ...getFieldsValue(),
      doContext: unref(jsonInstance.value)?.get(),
      clearRule,
    };
  };

  const setFieldsFormValueFun = (fieldsValue) => {
    setFieldsValue(fieldsValue);
  };
  const resetFieldsValueFunc = () => resetFields();

  const orgIdItem = ref('');
  const isUpdateItem = ref('');
  const deviceListItem = ref([]);

  //TODO-fengtao
  const updateFieldDeviceId = (deviceList, orgId, isUpdate, getMasterDeviceList) => {
    if (isUpdate.value) {
      orgIdItem.value = orgId.value;
    }
    orgIdItem.value = orgId.value;
    isUpdateItem.value = isUpdate.value;
    const options = getMasterDeviceList.value.map((m) => {
      return {
        value: m.id,
        label: m.name,
      };
    });
    deviceListItem.value = deviceList.value;
    updateSchema({
      field: 'deviceId',
      componentProps: {
        options,
      },
    });
  };
  //FT add 2022-10-27
  const updateEditFieldAlarmConfig = (alarmConfigList) => {
    alarmConfigOptions.value = alarmConfigList.value;
  };
  const updateFieldAlarmConfig = (alarmConfigList) => {
    alarmConfigOptions.value = alarmConfigList.value;
  };
  //FT add 2022-10-27

  const checked = ref(false);
  const validateForm = () => {
    return validate();
  };

  const handleDelete = (actionIndex) => {
    emit('deleteAction', actionIndex);
  };

  const clearRuleList = ref([]);
  const handleCheckedChange = (e: Event) => {
    if (!e.target.checked) {
      clearRuleList.value = [];
    } else {
      addClearRule();
    }
  };
  const addClearRule = () => {
    unref(clearRuleList).push(Date.now());
    nextTick(() => {
      setFields(refItem.clearRuleRefs);
    });
  };

  function setFields(refs) {
    unref(refs).map((item) => {
      item.updateFieldDeviceId(
        deviceListItem.value,
        props.provideOrgid || orgIdItem.value,
        isUpdateItem.value
      );
    });
  }
  const deleteClearRule = (index) => {
    unref(clearRuleList).splice(index, 1);
  };

  // json 以及初始化JSON
  const jsoneditorRef = ref();
  const jsonValue = ref({});
  const jsonInstance = ref();
  onMounted(() => {
    nextTick(() => {
      let options = {
        mode: 'code',
        mainMenuBar: false,
        statusBar: false,
      };
      let editor = new jsoneditor(jsoneditorRef.value, options);
      editor.set(jsonValue.value);
      jsonInstance.value = editor;
    });
  });

  const getJsonValue = () => unref(jsonInstance).get();
  const setJsonValue = (Json) => {
    nextTick(() => {
      unref(jsonInstance).set(Json);
    });
  };

  const operationType = ref<string>('');
  provide('operationType', operationType);

  const getRefItemConditionScreeningRefs = async () => {
    await nextTick();
    return refItem.clearRuleRefs.value.map(
      (item) => item.conditionScreeningRef.refItem.conditionScreeningRefs
    );
  };
  const setConditionScreeningList = (list) => {
    refItem.clearRuleRefs.value.map((item) => {
      item.conditionScreeningRef.conditionScreeningList = list;
    });
  };

  const setRichText = (list, index) => {
    refItem.clearRuleRefs.value[index].conditionScreeningRef.otherAttribute = list;
  };

  defineExpose({
    getFieldsValue,
    getFieldsValueFunc,
    setFieldsFormValueFun,
    resetFieldsValueFunc,
    updateFieldDeviceId,
    updateFieldAlarmConfig,
    validateForm,
    getJsonValue,
    setJsonValue,
    jsonInstance,
    updateEditFieldAlarmConfig,
    checked,
    getRefItemConditionScreeningRefs,
    setConditionScreeningList,
    setRichText,
    refItem,
    clearRuleList,
  });
</script>

<style>
  .jsoneditor {
    border: none;
  }
</style>