123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- <template>
- <el-dialog v-model="isShow" width="1100px" :before-close="handleClose">
- <el-form
- ref="ruleFormRef"
- :model="form"
- :rules="rules"
- label-position="top"
- label-width="200px"
- class="custom-comp-form"
- >
- <el-row
- type="flex"
- justify="space-between"
- align="middle"
- :gutter="10"
- class="first-row"
- >
- <el-col :span="15" class="first-row-first-col">
- <el-form-item prop="name">
- <el-tag size="small">规则名称</el-tag>
- <el-input v-model="form.name" />
- </el-form-item>
- </el-col>
- <el-col :span="9" class="first-row-second-col">
- <el-form-item prop="category">
- <el-tag size="small">报警类别</el-tag>
- <el-select v-model="form.category" class="select-mini">
- <el-option
- key="windturbine"
- label="风机"
- value="windturbine"
- ></el-option>
- <el-option
- key="inverter"
- label="逆变器"
- value="inverter"
- ></el-option>
- <el-option
- key="booststation"
- label="升压站"
- value="booststation"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item prop="rank">
- <el-tag size="small">报警级别</el-tag>
- <el-select v-model="form.rank" class="select-mini">
- <el-option key="1" label="低级" value="1" />
- <el-option key="2" label="低中级" value="2" />
- <el-option key="3" label="中级" value="3" />
- <el-option key="4" label="中高级" value="4" />
- <el-option key="5" label="高级" value="5" />
- </el-select>
- </el-form-item>
- <el-form-item prop="enabled">
- <el-tag size="small">是否启用</el-tag>
- <el-switch
- v-model="form.enabled"
- :active-value="true"
- :inactive-value="false"
- active-color="#13ce66"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="10" class="second-row">
- <el-col :span="6">
- <el-form-item prop="stationId">
- <el-tag size="small">风场</el-tag>
- <el-select
- v-model="form.stationId"
- style="width: 100%"
- @change="stationChange"
- >
- <el-option
- v-for="item in stationList"
- :key="item.id"
- :value="item.id"
- :label="item.name"
- />
- </el-select>
- </el-form-item>
- <el-form-item prop="modelId">
- <el-tag size="small">风机型号</el-tag>
- <el-select
- v-model="form.modelId"
- style="width: 100%"
- @change="modelIdChange"
- >
- <el-option
- v-for="item in state.modelList"
- :key="item"
- :value="item"
- :label="item"
- />
- </el-select>
- </el-form-item>
- <el-form-item prop="relatedParts">
- <el-tag size="small">所属部件</el-tag>
- <el-select v-model="form.relatedParts" style="width: 100%">
- <el-option
- v-for="i in state.relatePartList"
- :key="i.partCode"
- :value="i.partCode"
- :label="i.name"
- />
- </el-select>
- </el-form-item>
- <el-form-item prop="fault">
- <el-tag size="small">预警类型</el-tag>
- <el-select v-model="form.project" style="width: 100%">
- <el-option
- v-for="i in faultList"
- :key="i.value"
- :value="i.value"
- :label="i.name"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="9">
- <el-form-item prop="expression">
- <el-tag size="small">表达式</el-tag>
- <el-input
- type="textarea"
- rows="14"
- v-model="form.expression"
- :value="form.expression"
- id="expressionInput"
- />
- </el-form-item>
- </el-col>
- <el-col :span="9">
- <el-tabs type="border-card">
- <el-tab-pane label="AI测点">
- <el-input v-model="state.AIPointSearch"> </el-input>
- <el-table
- size="mini"
- fit
- :show-header="false"
- stripe
- height="204"
- :data="filterAIList"
- @row-dblclick="rowDbclick"
- >
- <el-table-column prop="uniformCode" />
- <el-table-column prop="name" />
- </el-table>
- </el-tab-pane>
- <el-tab-pane label="DI测点">
- <el-input v-model="state.DIPointSearch"> </el-input>
- <el-table
- size="mini"
- fit
- :show-header="false"
- stripe
- height="204"
- :data="filterDIList"
- @row-dblclick="rowDbclick"
- >
- <el-table-column prop="uniformCode" />
- <el-table-column prop="name" />
- </el-table>
- </el-tab-pane>
- <el-tab-pane label="函数">
- <el-table
- size="mini"
- fit
- :show-header="false"
- stripe
- height="240"
- :data="func"
- @row-dblclick="tabFuncRowClickHandle"
- >
- <el-table-column min-width="60%">
- <template #default="scope">
- <el-popover trigger="hover" placement="bottom">
- <p>描述:{{ scope.row.describe }}</p>
- <p>参数:{{ scope.row.param }}</p>
- <template #reference>
- <span size="medium" transition="fade-in-linear">{{
- scope.row.lab
- }}</span>
- </template>
- </el-popover>
- </template>
- </el-table-column>
- <el-table-column min-width="40%">
- <template #default="scope">
- <el-popover trigger="hover" placement="bottom">
- <p>描述:{{ scope.row.describe }}</p>
- <p>参数:{{ scope.row.param }}</p>
- <template #reference>
- <span size="medium" transition="fade-in-linear">{{
- scope.row.name
- }}</span>
- </template>
- </el-popover>
- </template>
- </el-table-column>
- </el-table>
- </el-tab-pane>
- <el-tab-pane label="运算符">
- <div class="operator">
- <el-button
- v-for="item in operator"
- :key="item"
- size="mini"
- class="buttons"
- @click="elInputSplit(item)"
- >
- {{ item }}
- </el-button>
- </div>
- </el-tab-pane>
- </el-tabs>
- </el-col>
- </el-row>
- <el-row :gutter="24">
- <el-col :span="24">
- <el-form-item prop="descriptionShow">
- <el-tag size="small">规则描述</el-tag>
- <el-input type="textarea" rows="4" v-model="form.descriptionShow" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <span class="footerButton">
- <el-button round size="mini" @click="closeDialog">取 消</el-button>
- <el-button round size="mini" @click="submitForm(ruleFormRef)"
- >确 定</el-button
- >
- </span>
- </template>
- </el-dialog>
- </template>
- <script setup>
- import { ref, onMounted, reactive, computed, watch, nextTick } from "vue";
- import { ElMessageBox, ElMessage } from "element-plus";
- import {
- // fetchAIPointList,
- // fetchDIPointList,
- // fetchRelatePart,
- custombj_postSave,
- fetch_electrical_point_ai,
- fetch_electrical_point_di,
- getWtModel,
- fetchRelatePartAndAlarmType,
- } from "@/api/zhbj/index.js";
- import { useStore } from "vuex";
- const store = useStore();
- const stationList = computed(() => store.state.stationList);
- onMounted(() => {
- getfetchRelatePart();
- });
- watch(
- () => props.isVisible,
- (val, old) => {
- isShow.value = val;
- },
- {
- deep: true,
- }
- );
- watch(
- () => props.form?.id,
- (val, old) => {
- if (val != "") {
- nextTick(async () => {
- getfetchAIPointList();
- getfetchDIPointList();
- });
- }
- },
- {
- deep: true,
- }
- );
- watch(
- () => props.form,
- (val, old) => {
- nextTick(() => {
- form.value = val;
- });
- },
- {
- deep: true,
- }
- );
- const isShow = ref(false);
- const form = ref({
- id: "",
- name: "",
- descriptionShow: "",
- expression: "",
- tag: "",
- rank: "",
- enabled: "1", // 1可用-0禁用
- modelId: "",
- ednaValue: "",
- category: "",
- range: 0,
- station: "",
- windturbine: "",
- line: "",
- project: "",
- electrical: "",
- taskstart: "",
- relatedParts: "",
- userName: "",
- });
- const emits = defineEmits(["close"]);
- const props = defineProps({
- isVisible: {
- type: Boolean,
- defaule: false,
- },
- form: {
- type: Object,
- },
- });
- const toEmits = () => {
- emits("close"); // 向父组件传递数据
- };
- const state = reactive({
- relatePartList: [],
- modelList: [],
- AIPointList: [],
- DIPointList: [],
- AIPointSearch: "",
- DIPointSearch: "",
- });
- const operator = [
- "+",
- "-",
- "*",
- "/",
- "(",
- ")",
- ">",
- ">=",
- "<",
- "<=",
- "==",
- "!=",
- "&&",
- "||",
- "!",
- "%",
- "true",
- "false",
- ".",
- ];
- const func = [
- {
- lab: "MR",
- name: "移动极差",
- param: "测点名,时间(秒)",
- describe: "是指两个或多个连续样本值中最大值与最小值之差",
- scene: "测点的移动极差超限报警",
- },
- {
- lab: "MAR",
- name: "均值极差",
- param: "测点名,时间(秒)",
- describe: "",
- scene: "测点的均值极差计算",
- },
- {
- lab: "RiseExceed",
- name: "上升趋势",
- param: "测点名,时间(秒),阈值",
- describe: "取测点在给定的时间范围内数据上升的量是否超过阈值",
- scene: "测点值的上升速度过快等",
- },
- {
- lab: "Sustain",
- name: "持续时间",
- param: "表达式,时间(秒)",
- describe:
- "判定状态(表达式成立)持续的时间是否超过给定的时间判断状态持续的时间",
- scene: "",
- },
- {
- lab: "LastUpdateTime",
- name: "最近数据时间",
- param: "测点名",
- describe: "",
- scene: "判定离线,状态持续时间等",
- },
- {
- lab: "abs",
- name: "取绝对值",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "acos",
- name: "反余弦",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "asin",
- name: "反正弦",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "atan",
- name: "反正切",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "atan2",
- name: "xy坐标转为极坐标",
- param: "x,y",
- describe: "",
- scene: "",
- },
- {
- lab: "ceiling",
- name: "向上取整",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "cos",
- name: "余弦",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "cosh",
- name: "双曲线余弦",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "exp",
- name: "欧拉数 e 的 double 次幂的值",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "floor",
- name: "向下取整",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "log",
- name: "自然对数",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "log10",
- name: "底数为 10 的对数",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "max",
- name: "比较最大值",
- param: "double a, double b",
- describe: "",
- scene: "",
- },
- {
- lab: "min",
- name: "比较最小值",
- param: "double a, double b",
- describe: "",
- scene: "",
- },
- {
- lab: "pow",
- name: "返回第一个参数的第二个参数次幂的值",
- param: "double a, double b",
- describe: "",
- scene: "",
- },
- {
- lab: "round",
- name: "返回最接近参数的 long,或int",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "sign",
- name: "负数返回-1.0,整数返回1.0,0返回0.0",
- param: "float f/double a",
- describe: "",
- scene: "",
- },
- {
- lab: "sin",
- name: "三角正弦值",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "sinh",
- name: "双曲线正弦",
- param: "double x",
- describe: "",
- scene: "",
- },
- {
- lab: "sqrt",
- name: "正平方根",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "tan",
- name: "正切",
- param: "double a",
- describe: "",
- scene: "",
- },
- {
- lab: "tanh",
- name: "双曲线正切",
- param: "double x",
- describe: "",
- scene: "",
- },
- { lab: "PI", name: "圆周率", param: "", describe: "", scene: "" },
- { lab: "E", name: "自然对数", param: "", describe: "", scene: "" },
- ];
- const faultList = [
- {
- value: "sensors",
- name: "传感器异常",
- },
- {
- value: "parts",
- name: "零部件隐患",
- },
- {
- value: "control",
- name: "控制参数优化",
- },
- {
- value: "performance",
- name: "性能下降",
- },
- ];
- const ruleFormRef = ref(null);
- const rules = reactive({
- name: [{ required: true, message: "请输入规则名称", trigger: "blur" }],
- category: [{ required: true, message: "请选择报警类别", trigger: "change" }],
- rank: [{ required: true, message: "请选择报警级别", trigger: "change" }],
- stationId: [{ required: true, message: "请选择风场", trigger: "change" }],
- expression: [
- { required: true, message: "表达式不能为空", trigger: "change" },
- ],
- });
- //stationChange
- const stationChange = async () => {
- form.value.modelId = "";
- getequipmentmodel_list();
- };
- //modelIdChange
- const modelIdChange = async () => {
- getfetchAIPointList();
- getfetchDIPointList();
- };
- //机型
- const getequipmentmodel_list = async () => {
- const { data } = await getWtModel(form.value.stationId);
- state.modelList = data;
- };
- //所属部件
- const getfetchRelatePart = async () => {
- const res = await fetchRelatePartAndAlarmType();
- state.relatePartList = res;
- };
- // 查询风场AI、DI测点
- const getfetchAIPointList = async () => {
- // const res = await fetchAIPointList(form.value.station, form.value.modelId);
- // state.AIPointList = res.sort(function (a, b) {
- // return a.uniformCode - b.uniformCode;
- // });
- };
- const filterAIList = computed(() =>
- state.AIPointList?.filter(
- (data) =>
- !state.AIPointSearch ||
- data.uniformCode.includes(state.AIPointSearch) ||
- data.name.includes(state.AIPointSearch)
- )
- );
- const filterDIList = computed(() =>
- state.DIPointList?.filter(
- (data) =>
- !state.DIPointSearch ||
- data.uniformCode.includes(state.DIPointSearch) ||
- data.name.includes(state.DIPointSearch)
- )
- );
- const getfetchDIPointList = async () => {
- const res = await fetchDIPointList(form.value.station, form.value.modelId);
- state.DIPointList = res.sort(function (a, b) {
- return a.uniformCode - b.uniformCode;
- });
- };
- // 函数点击事件
- const tabFuncRowClickHandle = (row) => {
- let elInput = document.getElementById("expressionInput");
- let startPos = elInput.selectionStart; //第0个字符到选中的字符
- let endPos = elInput.selectionEnd; //选中字符到末尾字符
- if (startPos === undefined || endPos === undefined) return;
- let txt = elInput.value;
- let func;
- if (
- row.lab === "MR" ||
- row.lab === "MAR" ||
- row.lab === "RiseExceed" ||
- row.lab === "Sustain" ||
- row.lab === "LastUpdateTime"
- ) {
- func = row.lab + "()";
- } else if (row.lab === "PI" || row.lab === "E") {
- func = "Math." + row.lab;
- } else {
- func = "Math." + row.lab + "()";
- }
- // 将插值添加到选中光标位置
- let result = txt.substring(0, startPos) + func + txt.substring(endPos);
- elInput.value = result;
- // 重新定义光标位置
- elInput.focus();
- if (row.lab === "PI" || row.lab === "E") {
- elInput.selectionStart = startPos + func.length;
- elInput.selectionEnd = startPos + func.length;
- } else {
- elInput.selectionStart = startPos + func.length - 1;
- elInput.selectionEnd = startPos + func.length - 1;
- }
- form.value.expression = result; // 赋值给表单中的的字段
- };
- //rowDbclick
- const rowDbclick = (row) => {
- elInputSplit(row.uniformCode);
- };
- // 表达式字符串拼接
- const elInputSplit = async (val) => {
- let elInput = document.getElementById("expressionInput");
- let startPos = elInput.selectionStart;
- let endPos = elInput.selectionEnd;
- if (startPos === undefined || endPos === undefined) return;
- let txt = elInput.value;
- let txtSplit = val;
- let result = txt.substring(0, startPos) + txtSplit + txt.substring(endPos);
- elInput.value = result;
- elInput.focus();
- elInput.selectionStart = startPos + txtSplit.length;
- elInput.selectionEnd = startPos + txtSplit.length;
- };
- //保存
- const save = async () => {
- const res = await custombj_postSave(form.value);
- console.warn(res);
- ElMessage.success(`保存成功!`);
- closeDialog();
- };
- //提交
- const submitForm = async (formEl) => {
- if (!formEl) return;
- await formEl.validate((valid, fields) => {
- if (valid) {
- save();
- } else {
- console.log("error submit!", fields);
- }
- });
- };
- //reset
- const resetForm = (formEl) => {
- formEl.resetFields();
- };
- //confirm关闭
- const handleClose = () => {
- ElMessageBox.confirm("确认关闭?")
- .then(() => {
- closeDialog();
- })
- .catch(() => {
- // catch error
- });
- };
- //关闭触发事件
- const closeDialog = () => {
- resetForm(ruleFormRef.value);
- state.AIPointList = [];
- state.DIPointList = [];
- toEmits();
- };
- </script>
- <style lang="scss" scoped>
- .col-box {
- display: flex;
- flex-direction: column;
- }
- .select-mini {
- width: 120px;
- }
- .el-tabs__content {
- padding: 0 !important;
- }
- .el-tabs--border-card {
- -webkit-box-shadow: none;
- box-shadow: none;
- }
- .border {
- border: solid red 1px;
- }
- .el-table--mini td {
- padding: 3px 0;
- }
- .el-button-group .el-button--primary {
- border: none;
- }
- .el-form--label-top .el-form-item__label {
- padding: 0;
- }
- </style>
|