12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133 |
- <template>
- <div class="layout-pd">
- <el-dialog
- v-model="Data.isShowDialog"
- style="width: 75%;"
- @close="handleDialogClose"
- @open="handleDialogOpen"
- >
- <!-- 标题区域 -->
- <div style="width: 100%;display: flex;justify-content: left;align-items: center;">
- <h1 style="margin-bottom: 10px;font-size: 24px;">{{ isEditing ? '编辑报警推送规则' : '添加报警推送规则' }}</h1>
- </div>
- <div style="margin-bottom: 10px ;">
- <hr />
- </div>
-
- <!-- 规则名称 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="规则名称:" style="width: 100%;" prop="ruleName">
- <el-input v-model="Data.Filter.ruleName" style="width: 100%;" placeholder="请输入" />
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 标签选择 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="标签:" style="width: 100%;" prop="tag">
- <el-select v-model="Data.Filter.tag" placeholder="请选择标签">
- <el-option
- v-for="item in Data.labelList"
- :key="item.id"
- :label="item.name"
- :value="item.code"
- />
- </el-select>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 推送用户选择(树形组件) -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="推送用户:" style="width: 100%;" prop="pushUserid">
- <el-tree
- ref="userTreeRef"
- :data="treeUserData"
- show-checkbox
- node-key="id"
- :props="treeProps"
- :check-strictly="false"
- :default-checked-keys="selectedUserIds"
- :default-expanded-keys="expandedKeys"
- @check="handleUserCheck"
- @node-click="handleNodeClick"
- style="width: 100%; max-height: 300px; overflow-y: auto; border: 1px solid #e5e7eb; border-radius: 4px; padding: 10px;"
- >
- <template #default="{ node, data }">
- <div class="tree-node-content">
- <span :class="{'role-node': data.isRole}">{{ data.label }}</span>
- <el-button
- v-if="data.isRole"
- type="text"
- size="small"
- @click.stop="toggleRoleExpand(node)"
- class="expand-btn"
- >
- </el-button>
- </div>
- </template>
- </el-tree>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 报警等级筛选下拉框 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="报警等级:" style="width: 100%;" prop="alarmLevel">
- <el-select
- v-model="Data.Filter.alarmLevel"
- placeholder="请选择报警等级"
- clearable
- @change="handleAlarmLevelChange"
- >
- <el-option
- v-for="item in alarmLevelDict"
- :key="item.id"
- :label="`${item.name}(${item.value})`"
- :value="item.code"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 油站选择 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="油站:" style="width: 100%;" prop="stationid">
- <el-select
- v-model="selectedStationIds"
- placeholder="请选择油站"
- multiple
- style="width: 100%;"
- ref="stationSelectRef"
- @change="handleStationChange"
- :key="stationSelectKey"
- >
- <el-option
- v-for="station in Data.stationList"
- :key="station.id"
- :label="station.name"
- :value="station.id"
- />
- </el-select>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 备注信息 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="备  注:" style="width: 100%;">
- <el-input type="textarea" rows="5" v-model="Data.Filter.remark" style="width: 100%;" placeholder="请输入" />
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 推送方式选择(包含总开关isPush) -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="推送方式:" style="width: 100%;" prop="pushMethod">
- <!-- 推送总开关(对应isPush参数) -->
- <el-row style="width: 100%;margin-bottom: 10px;">
- 是否推送<el-switch v-model="Data.isPush" style="margin-left: 3%;" />
- </el-row>
-
- <!-- 微信和邮箱开关(仅在总开关打开时显示) -->
- <template v-if="Data.isPush">
- <el-row style="width: 100%;">
- 微信公众号<el-switch v-model="Data.radioValue1" style="margin-left: 3%;" @change="radioChange" />
- </el-row>
- <el-row style="width: 100%;">
- 邮   箱<el-switch v-model="Data.radioValue2" style="margin-left: 3%;" @change="radioChange" />
- </el-row>
- </template>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 模板选择(受总开关控制) -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;" v-if="Data.isPush">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="模  板:" style="width: 50%;" prop="mode1">
- <el-select v-model="Data.mode1" class="m-2" placeholder="微信模板" v-if="Data.radioValue1" @change="modeChange">
- <el-option v-for="item in templateData.wxList" :key="item.id" :label="item.templateName" :value="item.id.toString()" />
- </el-select>
- </el-form-item>
- <el-form-item label="    " style="width: 100%;" prop="mode2">
- <el-select v-model="Data.mode2" class="m-2" placeholder="邮箱模板" v-if="Data.radioValue2" @change="modeChange">
- <el-option v-for="item in templateData.emailList" :key="item.id" :label="item.templateName" :value="item.id.toString()" />
- </el-select>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 正则匹配 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="正则匹配:" style="width: 100%;">
- <el-input type="textarea" rows="2" v-model="Data.Filter.regular" style="width: 100%;" placeholder="请输入" />
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 关键字匹配 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="关键字匹配:" style="width: 100%;">
- <el-input type="textarea" rows="5" v-model="Data.Filter.keyWord" style="width: 100%;" placeholder="如有多个关键字,请用英文“,”分割" />
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 优先级设置 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label=" 优先级:" style="width: 100%;" prop="taskPriority">
- <el-input-number v-model="Data.Filter.taskPriority" :controls="false" :min="1" :max="9" />
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 报警条件配置 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="报警条件配置" style="width: 100%;">
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 报警条件部分 -->
- <div v-if="Data.showAlarmConditions">
- <div v-for="(condition, index) in Data.condition" :key="index"
- style="width: 100%;display: flex;justify-content: center;align-items: center; margin-top: 10px;">
- <el-form :inline="true" @submit.stop.prevent :model="condition" :rules="conditionRules">
- <el-form-item :label="index === 0 ? '条  件:' : '附加条件:'" style="width: 130%; ">
- <el-row :gutter="20" style="width: 100%;">
- <!-- 报警设备 -->
- <el-col :span="8">
- <div style="flex:1;">
- <span style="margin-right: 13px;">报警设备:</span>
- <el-form-item prop="Left" style="display:flex">
- <el-select v-model="condition.Left" placeholder="请选择" >
- <el-option
- v-for="item in Data.alarmEquipment"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </el-form-item>
- </div>
- </el-col>
-
- <!-- 报警类型 -->
- <el-col :span="8">
- <div style="flex:1;">
- <span style="margin-right: 13px;">报警类型:</span>
- <el-form-item prop="inthe" style="display:flex">
- <el-select v-model="condition.inthe" placeholder="请选择" >
- <el-option
- v-for="item in Data.alarmType"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </el-form-item>
- </div>
- </el-col>
-
- <!-- 报警来源 -->
- <el-col :span="8">
- <div style="flex:1;">
- <span style="margin-right: 13px;">报警来源:</span>
- <el-form-item prop="Right" style="display:flex">
- <el-select v-model="condition.Right" placeholder="请选择">
- <el-option
- v-for="item in Data.alarmSource"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </el-form-item>
- </div>
- </el-col>
- </el-row>
- </el-form-item>
- </el-form>
- </div>
- </div>
-
- <!-- 报警条件添加/删除按钮 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-button type="primary" icon="ele-Plus" style="font-size: large" @click="addCondition" />
- <el-button v-if="Data.condition.length > 1" type="primary" icon="ele-Minus" style="font-size: large" @click="removeCondition" />
- </div>
- <!-- 维修条件配置 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent>
- <el-form-item label="维修条件配置" style="width: 100%;">
- </el-form-item>
- </el-form>
- </div>
- <!-- 维修条件部分 -->
- <div v-if="Data.showRepairConditions">
- <div v-for="(condition2, index) in Data.condition2" :key="index"
- style="width: 100%;display: flex;justify-content: center;align-items: center; margin-top: 10px;">
- <el-form :inline="true" @submit.stop.prevent :model="condition2" :rules="condition2Rules">
- <el-form-item :label="index === 0 ? '条  件:' : '附加条件:'" style="width: 130%;">
- <el-row :gutter="20" style="width: 100%;">
- <el-col :span="8">
- <div style="flex:1;">
- <span style="margin-right: 13px;">维修类型:</span>
- <el-form-item prop="Left" style="display:flex">
- <el-select v-model="condition2.Left" placeholder="请选择">
- <el-option
- v-for="item in Data.alarmproType"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </el-form-item>
- </div>
- </el-col>
-
- <el-col :span="8">
- <div style="flex:1;">
- <span style="margin-right: 13px;">维修状态:</span>
- <el-form-item prop="Right" style="display:flex">
- <el-select v-model="condition2.Right" placeholder="请选择" >
- <el-option
- v-for="item in Data.alarmproStatus"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- </el-form-item>
- </div>
- </el-col>
- </el-row>
- </el-form-item>
- </el-form>
- </div>
- </div>
-
- <!-- 维修条件添加/删除按钮 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-button type="primary" icon="ele-Plus" style="font-size: large" @click="addRepairCondition" />
- <el-button v-if="Data.condition2.length > 1" type="primary" icon="ele-Minus" style="font-size: large" @click="removeCondition2" />
- </div>
- <!-- 保存按钮 -->
- <div style="width: 100%;display: flex;justify-content: center;align-items: center;">
- <el-form :inline="true" @submit.stop.prevent style="width: 60%;">
- <el-row justify="end" style="margin-top: 30px;">
- <el-button @click="Data.isShowDialog = false">取消</el-button>
- <el-button type="primary" @click="submitForm" style="margin-left: 10px;">{{ isEditing ? '更新' : '保存' }}</el-button>
- </el-row>
- </el-form>
- </div>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts" name="AlarmRuleDialog">
- import { onMounted, reactive, ref, nextTick, computed, watch } from 'vue';
- import { alarmRluesFilterModel } from "/@/api/admin/AlarmService/alarmRulesDto";
- import { alarmRulesApi, stationApi } from "/@/api/admin/AlarmService/alarmRulesApi";
- import { RoleApi } from '/@/api/admin/Role'
- import { pushTemplateApi } from "/@/api/admin/AlarmService/pushTemplateApi";
- import { TemplateFilterDto } from "/@/api/admin/AlarmService/pushTemplateDto";
- import eventBus from "/@/utils/mitt";
- import { ElMessage, type FormRules } from 'element-plus'
- import { UserListItem, StationItem } from "/@/api/admin/AlarmService/alarmRulesDto";
- import { DictApi } from "/@/api/admin/Dict";
- import { PageInputDictGetPageDto } from "/@/api/admin/data-contracts";
- // 报警等级字典项接口定义
- interface DictItem {
- id: number;
- name: string;
- code: string; // 数据字典编码
- value: string;
- enabled: boolean;
- sort: number;
- }
- // 状态标识:是否为编辑模式
- const isEditing = ref(false);
- // 油站选择器相关引用和状态
- const stationSelectRef = ref();
- const stationSelectKey = ref(0);
- const selectedStationIds = ref<number[]>([]);
- const stationListLoaded = ref(false);
- // 树形组件引用
- const userTreeRef = ref();
- // 推送用户选择专用变量
- const selectedUserIds = ref<number[]>([]); // 存储选中的用户ID
- const expandedKeys = ref<string[]>([]); // 存储展开的角色节点ID
- // 树形结构配置
- const treeProps = {
- label: 'label',
- children: 'children',
- disabled: 'disabled'
- };
- // 条件验证规则
- const conditionRules = reactive<FormRules>({
- Left: [{ required: true, message: '请选择报警设备', trigger: 'change' }],
- inthe: [{ required: true, message: '请选择报警类型', trigger: 'change' }],
- Right: [{ required: true, message: '请选择报警来源', trigger: 'change' }]
- })
- const condition2Rules = reactive<FormRules>({
- Left: [{ required: true, message: '请选择维修类型', trigger: 'change' }],
- Right: [{ required: true, message: '请选择维修状态', trigger: 'change' }]
- })
- // 报警等级字典数据
- const alarmLevelDict = ref<DictItem[]>([]);
- const Data = reactive({
- isShowDialog: false,
- showAlarmConditions: false,
- showRepairConditions: false,
- isPush: false, // 是否推送(总开关,对应isPush参数)
- stationList: [] as StationItem[],
- Filter: {
- ruleName: '',
- roleMappingId: [] as number[],
- tag: "", // 标签参数(存储编码code)
- remark: '',
- pushMethod: '',
- pushTemplateMappingID: [] as number[],
- regular: '',
- keyWord:"",
- isExclusive: false,
- isExclusiveMaintenance: false,
- taskPriority: 1,
- triggerMethod: null,
- maintenanceTriggerMethod: null,
- conditionsJson: '' as any,
- maintenanceJson: '' as any,
- pushUserid: [] as number[], // 最终提交的用户ID数组
- stationid: [] as number[],
- userName: "",
- userPhone: "",
- userId: "",
- condition2: "",
- condition: "",
- mode1: '',
- id: 0,
- alarmLevel: undefined, // 报警等级参数(存储编码code)
- } as unknown as alarmRluesFilterModel & { alarmLevel?: string },
- roleList: [] as any,
- labelList: [] as Array<{ id: string; name: string; code: string }>, // 标签列表(包含code)
- userList: [] as UserListItem[],
- radioValue1: false, // 微信推送开关
- radioValue2: false, // 邮箱推送开关
- mode1: '', // 微信模板ID
- mode2: '', // 邮箱模板ID
- condition: [{ Left: '', inthe: '', Right: '' }], // 报警条件
- condition2: [{ Left: '', Right: '' }], // 维修条件
- alarmEquipment: ["安全装置","编码器","计控主板","监控微处理器","智能型控制阀","油气回收控制板","显示屏","计量器","加油机","油枪"],
- alarmType: ["加油机离线","通信异常","非法部件","厂商不符","绑定错误","监控微处理器报警","安全装置报警","加油机报警","检定"],
- alarmSource: ['云平台', '安全装置'],
- alarmproType: ["油机维修","装置维修"],
- alarmproStatus: ["正在维修","结束维修"]
- })
- // 转换用户列表为树形结构数据
- const treeUserData = computed(() => {
- return Data.userList.map((group: any) => {
- const roleId = `role_${group.roleName.replace(/\s+/g, '_')}`;
- return {
- id: roleId,
- label: `角色:${group.roleName}`,
- isRole: true,
- children: group.users.map((user: any) => ({
- id: Number(user.id),
- label: user.name || `用户${user.id}`,
- phone: user.phone || '',
- isRole: false,
- disabled: false
- }))
- };
- });
- });
- // 处理角色展开/折叠
- const toggleRoleExpand = (node: any) => {
- node.expanded = !node.expanded;
- if (node.expanded) {
- expandedKeys.value.push(node.id);
- } else {
- expandedKeys.value = expandedKeys.value.filter(key => key !== node.id);
- }
- };
- // 处理节点点击
- const handleNodeClick = (data: any, node: any) => {
- if (data.isRole) {
- toggleRoleExpand(node);
- }
- };
- // 处理用户选择
- const handleUserCheck = (data: any, checkInfo: any) => {
- const allCheckedIds = checkInfo.checkedKeys || [];
- const userIds = allCheckedIds
- .filter((id: any) => typeof id === 'number' && !isNaN(id));
- const uniqueUserIds = [...new Set(userIds)];
- selectedUserIds.value = uniqueUserIds;
- Data.Filter.pushUserid = uniqueUserIds;
- };
- // 监听油站选择变化
- const handleStationChange = (values: number[]) => {
- Data.Filter.stationid = [...values];
- };
- // 处理报警等级变化
- const handleAlarmLevelChange = (value: string) => {
- Data.Filter.alarmLevel = value;
- };
- // 获取用户列表
- const getUserList = async () => {
- try {
- const res = await new alarmRulesApi().getWxUserRole({});
- const userDataArray = res.data || [];
- const userMap = new Map<string, UserListItem[]>();
-
- userDataArray.forEach((roleObj: any) => {
- const roleName = roleObj.roleName || '未知角色';
- const validUsers = (roleObj.users || []).filter((user: any) => {
- const id = Number(user.id);
- return !isNaN(id) && id > 0;
- });
-
- validUsers.forEach((userObj: any) => {
- if (!userMap.has(roleName)) {
- userMap.set(roleName, []);
- }
- userMap.get(roleName)!.push({
- id: Number(userObj.id),
- name: userObj.name || `用户${userObj.id}`,
- phone: userObj.phone || '',
- roleName: roleName
- });
- });
- });
-
- Data.userList = Array.from(userMap.entries()).map(([role, users]) => ({
- roleName: role,
- users: users
- }));
- } catch (error) {
- console.error("获取用户列表失败:", error);
- ElMessage.error("用户列表加载失败");
- Data.userList = [];
- }
- };
- // 获取油站列表
- const getStationList = async () => {
- try {
- const requestData = {
- currentPage: 1,
- pageSize: 1000,
- dynamicFilter: {},
- filter: {}
- };
- const res = await new stationApi().getStationList(requestData);
- Data.stationList = res.data?.list || [];
- stationListLoaded.value = true;
- } catch (error) {
- console.error("获取油站列表失败:", error);
- stationListLoaded.value = true;
- }
- };
- // 获取报警等级字典数据
- const fetchAlarmLevelDict = async () => {
- try {
- const data: PageInputDictGetPageDto = {
- CurrentPage: 1,
- PageSize: 100,
- Filter: {
- dictTypeId: 685895581360197, // 报警等级字典类型ID
- name: ""
- }
- };
-
- const res = await new DictApi().getPage(data);
- if (res.success && res.data) {
- alarmLevelDict.value = res.data.list.map((item: any) => ({
- id: item.id,
- name: item.name,
- code: item.code,
- value: item.value,
- enabled: item.enabled,
- sort: item.sort
- })) as DictItem[];
- } else {
- console.error("获取报警等级字典数据失败", res.msg);
- }
- } catch (error) {
- console.error("获取报警等级字典数据异常", error);
- }
- };
- // 设置油站选择 - 修复油站信息不回显问题
- const setStationSelection = (ids: number[]) => {
- if (!stationListLoaded.value) {
- // 确保油站数据加载完成后再设置选中状态
- const checkLoaded = setInterval(() => {
- if (stationListLoaded.value) {
- clearInterval(checkLoaded);
- setStationSelection(ids);
- }
- }, 100);
- return;
- }
-
- const validIds = ids.filter(id =>
- Data.stationList.some(station => station.id === id)
- );
-
- nextTick(() => {
- selectedStationIds.value = [...validIds];
- Data.Filter.stationid = [...validIds];
- // 强制刷新选择器
- stationSelectKey.value++;
- });
- };
- const templateData = reactive({
- Filter: {
- currentPage: 1,
- pageSize: 100,
- filter: {
- templateName: "",
- templateType: "",
- templateContent: "",
- id: 0
- }
- } as TemplateFilterDto,
- wxList: [] as any,
- emailList: [] as any
- })
- // 推送方式变化处理
- const radioChange = () => {
- if (Data.isPush) { // 仅当总开关打开时处理
- if (Data.radioValue1) {
- Data.Filter.pushMethod = 'wx'
- if (Data.radioValue2) {
- Data.Filter.pushMethod += ',email'
- }
- } else {
- Data.Filter.pushMethod = Data.radioValue2 ? 'email' : '';
- }
- } else {
- Data.Filter.pushMethod = ''; // 总开关关闭时清空
- }
- };
- // 获取标签列表
- const getLabel = async () => {
- try {
- const res = await new RoleApi().getLabel({
- currentPage: 1,
- pageSize: 100,
- filter: {
- dictTypeId: 677693042573381
- }
- })
- Data.labelList = res.data?.list?.map((item: any) => ({
- id: item.id.toString(),
- name: item.name,
- code: item.code // 存储标签编码
- })) || []
- } catch (error) {
- console.error('获取标签失败:', error)
- Data.labelList = []
- }
- }
- // 获取角色列表
- const getRole = async () => {
- const res = await new RoleApi().getList()
- Data.roleList = res.data?.map((item: any) => ({ 'id': item.id, 'name': item.name })) || []
- }
- // 查询模板信息
- const funSelect = async () => {
- try {
- const res = await new pushTemplateApi().getData(templateData.Filter)
- const data = res?.data || [];
-
- templateData.wxList = data
- .filter((item: any) => item.templateType === "微信")
- .map((item: any) => ({ ...item, id: item.id.toString() }));
- templateData.emailList = data
- .filter((item: any) => item.templateType === "邮箱")
- .map((item: any) => ({ ...item, id: item.id.toString() }));
- } catch (error) {
- console.error('获取模板列表失败:', error);
- }
- }
- // 模板变化处理
- const modeChange = () => {
- Data.Filter.pushTemplateMappingID = [];
-
- if (Data.isPush && Data.radioValue1 && Data.mode1) {
- const wxItem = templateData.wxList.find((item: any) => item.id === Data.mode1);
- if (wxItem) Data.Filter.pushTemplateMappingID.push(Number(wxItem.id));
- }
-
- if (Data.isPush && Data.radioValue2 && Data.mode2) {
- const emailItem = templateData.emailList.find((item: any) => item.id === Data.mode2);
- if (emailItem) Data.Filter.pushTemplateMappingID.push(Number(emailItem.id));
- }
- }
- // 弹窗关闭处理
- const handleDialogClose = () => {};
- // 弹窗打开处理
- const handleDialogOpen = () => {
- if (!stationListLoaded.value) {
- getStationList();
- } else if (!isEditing.value) {
- selectedStationIds.value = [];
- }
- };
- // 重置表单
- const resetForm = () => {
- // 重置用户选择
- selectedUserIds.value = [];
- expandedKeys.value = [];
-
- // 重置表单数据
- Data.Filter = {
- ruleName: '',
- roleMappingId: [],
- tag: "",
- remark: '',
- pushMethod: '',
- pushTemplateMappingID: [],
- regular: '',
- keyWord: "",
- isExclusive: false,
- isExclusiveMaintenance: false,
- taskPriority: 1,
- triggerMethod: null,
- maintenanceTriggerMethod: null,
- conditionsJson: '',
- maintenanceJson: '',
- pushUserid: [],
- stationid: [],
- userName: "",
- userPhone: "",
- userId: "",
- condition2: "",
- condition: "",
- mode1: '',
- id: 0,
- alarmLevel: undefined,
- } as unknown as alarmRluesFilterModel & { alarmLevel?: string };
-
- // 重置推送相关状态
- Data.isPush = false;
- Data.radioValue1 = false;
- Data.radioValue2 = false;
- Data.mode1 = '';
- Data.mode2 = '';
-
- // 重置条件配置
- Data.showAlarmConditions = false;
- Data.showRepairConditions = false;
- Data.condition = [{ Left: '', inthe: '', Right: '' }];
- Data.condition2 = [{ Left: '', Right: '' }];
-
- // 重置油站选择
- selectedStationIds.value = [];
-
- // 确保树形组件重置
- nextTick(() => {
- if (userTreeRef.value) {
- userTreeRef.value.setCheckedKeys([]);
- }
- });
- };
- // 监听用户数据加载完成后,更新树形组件选中状态
- watch(
- () => Data.userList.length,
- (newVal) => {
- if (newVal > 0 && selectedUserIds.value.length > 0 && userTreeRef.value) {
- nextTick(() => {
- userTreeRef.value.setCheckedKeys(selectedUserIds.value);
- });
- }
- }
- );
- onMounted(() => {
- getLabel();
- getRole();
- funSelect();
- getUserList();
- getStationList();
- fetchAlarmLevelDict();
- });
- // 添加报警条件
- const addCondition = () => {
- if (!Data.showAlarmConditions) {
- Data.showAlarmConditions = true
- } else {
- const lastCondition = Data.condition[Data.condition.length - 1]
- if (!lastCondition.Left || !lastCondition.inthe || !lastCondition.Right) {
- ElMessage.warning('请先填写当前条件的所有字段')
- return
- }
- Data.condition.push({ Left: '', inthe: '', Right: '' })
- }
- }
- // 添加维修条件
- const addRepairCondition = () => {
- if (!Data.showRepairConditions) {
- Data.showRepairConditions = true
- } else {
- const lastCondition = Data.condition2[Data.condition2.length - 1]
- if (!lastCondition.Left || !lastCondition.Right) {
- ElMessage.warning('请先填写当前条件的所有字段')
- return
- }
- Data.condition2.push({ Left: '', Right: '' })
- }
- }
- // 删除报警条件
- const removeCondition = () => {
- if (Data.condition.length > 1) {
- Data.condition.pop()
- } else {
- Data.showAlarmConditions = false
- Data.condition = [{ Left: '', inthe: '', Right: '' }]
- }
- }
- // 删除维修条件
- const removeCondition2 = () => {
- if (Data.condition2.length > 1) {
- Data.condition2.pop()
- } else {
- Data.showRepairConditions = false
- Data.condition2 = [{ Left: '', Right: '' }]
- }
- }
- // 提交表单
- const submitForm = async () => {
- // 验证规则名称
- if (!Data.Filter.ruleName) {
- ElMessage.warning('请输入规则名称')
- return
- }
-
- // 验证推送用户
- if (!Array.isArray(selectedUserIds.value) || selectedUserIds.value.length === 0) {
- ElMessage.warning('请选择推送用户');
- return;
- }
-
- // // 验证油站选择
- // if (selectedStationIds.value.length === 0) {
- // ElMessage.warning('请选择油站');
- // return;
- // }
-
- // 验证推送配置(当isPush为true时)
- if (Data.isPush) {
- if (Data.radioValue1 && !Data.mode1) {
- ElMessage.warning('请选择微信模板')
- return
- }
- if (Data.radioValue2 && !Data.mode2) {
- ElMessage.warning('请选择邮箱模板')
- return
- }
- if (!Data.radioValue1 && !Data.radioValue2) {
- ElMessage.warning('请至少选择一种推送方式')
- return
- }
- }
-
- // 准备提交数据
- const submitData = {
- ...Data.Filter,
- conditionsJson: Data.showAlarmConditions ? JSON.stringify(Data.condition) : null,
- maintenanceJson: Data.showRepairConditions ? JSON.stringify(Data.condition2) : null,
- pushUserid: selectedUserIds.value,
- stationid: selectedStationIds.value,
- pushTemplateMappingID: Data.Filter.pushTemplateMappingID,
- tag: Data.Filter.tag || null,
- isPush: Data.isPush,
- alarmLevel: Data.Filter.alarmLevel
- }
-
- try {
- const api = new alarmRulesApi();
- if (isEditing.value && Data.Filter.id) {
- await api.addForm(submitData);
- ElMessage.success('更新成功');
- } else {
- await api.addForm(submitData);
- ElMessage.success('保存成功');
- }
- eventBus.emit('refreshView');
- Data.isShowDialog = false;
- // 提交成功后重置表单
- resetForm();
- } catch (error) {
- console.error(`${isEditing.value ? '更新' : '保存'}失败:`, error);
- ElMessage.error(`${isEditing.value ? '更新' : '保存'}失败,请稍后重试`);
- }
- }
- /**
- * 打开表单对话框 - 修复编辑时推送用户和油站信息被清空的问题
- */
- const openDialog = (row?: any) => {
- try {
- isEditing.value = !!row;
- resetForm();
-
- if (row) {
- // 处理用户ID - 修复推送用户不回显问题
- let pushUserIds: number[] = [];
- if (row.pushUserid) {
- if (Array.isArray(row.pushUserid)) {
- pushUserIds = row.pushUserid.map(id => Number(id)).filter(id => !isNaN(id) && id > 0);
- } else if (typeof row.pushUserid === 'string') {
- pushUserIds = row.pushUserid
- .split(',')
- .map(id => Number(id))
- .filter(id => !isNaN(id) && id > 0);
- } else if (typeof row.pushUserid === 'number' && !isNaN(row.pushUserid)) {
- pushUserIds = [row.pushUserid];
- }
- }
-
- // 立即设置选中的用户ID
- selectedUserIds.value = pushUserIds;
- Data.Filter.pushUserid = pushUserIds;
-
- // 处理油站ID - 修复油站信息不回显问题
- const stationIds = row.stationid
- ? (Array.isArray(row.stationid)
- ? row.stationid.map(Number)
- : [Number(row.stationid)])
- : [];
- // 复制行数据到表单
- Data.Filter = {
- ...row,
- roleMappingId: row.roleMappingId || [],
- pushTemplateMappingID: row.pushTemplateMappingID ?
- (Array.isArray(row.pushTemplateMappingID)
- ? row.pushTemplateMappingID.map(Number)
- : [Number(row.pushTemplateMappingID)]) : [],
- stationid: stationIds,
- id: row.id || 0,
- tag: row.tag || "",
- alarmLevel: row.alarmLevel || ""
- } as unknown as alarmRluesFilterModel & { alarmLevel?: string };
-
- // 处理标签编码回显
- if (row.tag) {
- let tagItem = Data.labelList.find((item: any) => item.code === row.tag);
- if (!tagItem && typeof row.tag === 'string') {
- tagItem = Data.labelList.find((item: any) => item.id === row.tag);
- }
- Data.Filter.tag = tagItem?.code || row.tag;
- }
-
- // 处理报警等级编码回显
- if (row.alarmLevel) {
- let levelItem = alarmLevelDict.value.find((item: any) => item.code === row.alarmLevel);
- if (!levelItem) {
- levelItem = alarmLevelDict.value.find((item: any) => item.value === row.alarmLevel);
- }
- Data.Filter.alarmLevel = levelItem?.code || row.alarmLevel;
- }
-
- // 处理推送开关和方式
- Data.isPush = row.isPush !== undefined ? row.isPush : false;
- const pushMethods = Array.isArray(row.pushMethod)
- ? row.pushMethod
- : (row.pushMethod?.split(',') || []);
- Data.radioValue1 = pushMethods.includes('wx');
- Data.radioValue2 = pushMethods.includes('email');
- radioChange();
-
- // 处理油站数据 - 确保油站选择正确设置
- setStationSelection(stationIds);
-
- // 处理模板
- const templateIds = Data.Filter.pushTemplateMappingID.map(id => id.toString());
- Data.mode1 = '';
- Data.mode2 = '';
- templateIds.forEach(strId => {
- const wxItem = templateData.wxList.find((item: any) => item.id === strId);
- if (wxItem) Data.mode1 = strId;
- const emailItem = templateData.emailList.find((item: any) => item.id === strId);
- if (emailItem) Data.mode2 = strId;
- });
-
- // 处理报警条件
- if (row.conditionsJson) {
- try {
- const conditions = JSON.parse(row.conditionsJson);
- if (Array.isArray(conditions) && conditions.length > 0) {
- Data.condition = conditions;
- Data.showAlarmConditions = true;
- }
- } catch (e) {
- console.error('解析报警条件失败:', e);
- }
- }
-
- // 处理维修条件
- if (row.maintenanceJson) {
- try {
- const maintenanceConditions = JSON.parse(row.maintenanceJson);
- if (Array.isArray(maintenanceConditions) && maintenanceConditions.length > 0) {
- Data.condition2 = maintenanceConditions;
- Data.showRepairConditions = true;
- }
- } catch (e) {
- console.error('解析维修条件失败:', e);
- }
- }
-
- // 确保用户数据加载完成后设置树形组件选中状态
- if (Data.userList.length > 0) {
- nextTick(() => {
- if (userTreeRef.value) {
- userTreeRef.value.setCheckedKeys(selectedUserIds.value);
- }
- });
- } else {
- // 如果用户数据尚未加载,等待加载完成后再设置
- const checkUserLoaded = setInterval(() => {
- if (Data.userList.length > 0) {
- clearInterval(checkUserLoaded);
- nextTick(() => {
- if (userTreeRef.value) {
- userTreeRef.value.setCheckedKeys(selectedUserIds.value);
- }
- });
- }
- }, 100);
- }
- }
- Data.isShowDialog = true;
- } catch (error) {
- console.error('打开弹窗时出错:', error);
- Data.isShowDialog = true;
- ElMessage.error('打开弹窗时出错,但已尝试显示');
- }
- };
- defineExpose({
- openDialog,
- })
- </script>
- <style scoped lang="scss">
- .my-el-link {
- font-size: 12px;
- }
- .el-form {
- width: 60%;
- }
- .el-form .el-col{
- margin: 0 !important;
- }
- ::v-deep .el-form-item__label {
- width: 100px;
- justify-content: start;
- }
- .el-input {
- width: 240px;
- }
- .el-select .el-input {
- width: 500px;
- }
- .el-row {
- margin-bottom: 20px;
- }
- .el-col {
- padding: 0 10px;
- }
- /* 树形组件样式 */
- .tree-node-content {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- padding: 2px 0;
- }
- .expand-btn {
- color: #409eff;
- padding: 0 5px;
- font-size: 12px;
- }
- ::v-deep .el-tree-node__content {
- padding: 2px 0;
- }
- ::v-deep .el-tree-node__label {
- font-weight: normal;
- }
- ::v-deep .el-tree-node.is-current > .el-tree-node__content {
- background-color: #f5f7fa;
- }
- ::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
- background-color: #f5f7fa;
- }
- </style>
|