Przeglądaj źródła

[Feat 0000]联动配置页面新增、筛选

bobo04052021@163.com 3 dni temu
rodzic
commit
6262e765c3

+ 154 - 3
src/views/vent/home/configurable/components/preset/linkLog.vue

@@ -6,7 +6,7 @@
     <div class="search-area">
       <div class="title-top">
         <a-input v-model:value="searchWarn" placeholder="搜索" size="small" class="zxm-input zxm-input-sm" />
-        <div class="search-btn">
+        <div class="search-btn" @click="openFilterModal">
           <div class="btn-item">筛选</div>
         </div>
       </div>
@@ -35,12 +35,37 @@
         </div>
       </div>
     </div>
+
+    <!-- 筛选弹窗:日期选择 -->
+    <div class="filter-mask" v-if="filterVisible" @click.self="closeFilterModal">
+      <div class="filter-modal">
+        <div class="modal-header">
+          <span>自定义时间筛选</span>
+          <span class="close-icon" @click="closeFilterModal">×</span>
+        </div>
+        <div class="modal-form">
+          <div class="form-row">
+            <label class="form-label">开始日期:</label>
+            <a-date-picker v-model:value="filterForm.startDate" placeholder="请选择开始日期" class="date-picker" />
+          </div>
+          <div class="form-row">
+            <label class="form-label">结束日期:</label>
+            <a-date-picker v-model:value="filterForm.endDate" placeholder="请选择结束日期" class="date-picker" />
+          </div>
+        </div>
+        <div class="modal-footer">
+          <button class="btn-cancel" @click="closeFilterModal">取消</button>
+          <button class="btn-search" @click="confirmFilter">查询</button>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
-
+import { ref, reactive } from 'vue';
+import dayjs, { Dayjs } from 'dayjs';
+import { message } from 'ant-design-vue';
 let searchWarn = ref('');
 const timeType = ref(1);
 let tableData = ref<any[]>([
@@ -54,6 +79,44 @@ let tableData = ref<any[]>([
   { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
   { time: '14:31:22', rule: '001', grade: '触发', status: '温度65.3℃超过阈值' },
 ]);
+
+// 筛选弹窗控制
+const filterVisible = ref(false);
+// 筛选日期表单
+const filterForm = reactive<{ startDate: Dayjs | null; endDate: Dayjs | null }>({
+  startDate: null,
+  endDate: null,
+});
+
+// 打开筛选弹窗
+const openFilterModal = () => {
+  const today = dayjs();
+  const sevenDayAgo = dayjs().subtract(7, 'day');
+  filterForm.startDate = sevenDayAgo;
+  filterForm.endDate = today;
+  filterVisible.value = true;
+};
+
+// 关闭弹窗并重置日期
+const closeFilterModal = () => {
+  filterVisible.value = false;
+  filterForm.startDate = null;
+  filterForm.endDate = null;
+};
+
+// 确认筛选
+const confirmFilter = () => {
+  if (!filterForm.startDate || !filterForm.endDate) {
+    message.warning('请选择完整起止日期');
+    return;
+  }
+  if (filterForm.startDate.isAfter(filterForm.endDate)) {
+    message.warning('开始日期不能晚于结束日期');
+    return;
+  }
+  console.log('筛选参数:', searchWarn.value, filterForm.startDate.format('YYYY-MM-DD'), filterForm.endDate.format('YYYY-MM-DD'));
+  closeFilterModal();
+};
 </script>
 
 <style lang="less" scoped>
@@ -240,4 +303,92 @@ let tableData = ref<any[]>([
 .zxm-input-sm {
   padding: 0px 20px;
 }
+
+/* 筛选弹窗样式 */
+.filter-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.6);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 999;
+}
+.filter-modal {
+  width: 400px;
+  background: #0e3455;
+  border: 1px solid #01fefc;
+  border-radius: 6px;
+  color: #fff;
+}
+.modal-header {
+  height: 40px;
+  line-height: 40px;
+  padding: 0 16px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-bottom: 1px solid #114268;
+  color: #01fefc;
+  font-size: 14px;
+  font-weight: bold;
+}
+.close-icon {
+  font-size: 20px;
+  cursor: pointer;
+  color: #ccc;
+}
+.modal-form {
+  padding: 18px;
+}
+.form-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16px;
+  .form-label {
+    width: 90px;
+    font-size: 13px;
+  }
+  .date-picker {
+    flex: 1;
+    :deep(.ant-picker) {
+      background: #114268;
+      border: 1px solid #01fefc;
+      color: #fff;
+    }
+    :deep(.ant-picker-input input) {
+      color: #fff;
+    }
+  }
+}
+.modal-footer {
+  height: 48px;
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+  align-items: center;
+  padding: 0 16px;
+  border-top: 1px solid #114268;
+  .btn-cancel {
+    width: 80px;
+    height: 30px;
+    background: transparent;
+    border: 1px solid #01fefc;
+    color: #fff;
+    border-radius: 3px;
+    cursor: pointer;
+  }
+  .btn-search {
+    width: 80px;
+    height: 30px;
+    background: rgba(32, 166, 169);
+    border: 1px solid #01fefc;
+    color: #fff;
+    border-radius: 3px;
+    cursor: pointer;
+  }
+}
 </style>

+ 181 - 4
src/views/vent/home/configurable/components/preset/ruleTable.vue

@@ -4,7 +4,7 @@
       <div class="list-title">
         <span>联动规则列表</span>
       </div>
-      <div class="search-btn">
+      <div class="search-btn" @click="openAddModal">
         <div class="btn-item">新增</div>
       </div>
     </div>
@@ -25,12 +25,51 @@
         </div>
       </div>
     </div>
+
+    <!-- 新增联动规则弹窗 -->
+    <div class="modal-mask" v-if="modalVisible" @click.self="closeAddModal">
+      <div class="modal-box">
+        <div class="modal-header">
+          <span>新增联动规则</span>
+          <span class="modal-close" @click="closeAddModal">×</span>
+        </div>
+        <div class="modal-form">
+          <div class="form-row">
+            <label class="form-label">规则ID:</label>
+            <input v-model="form.time" class="form-input" placeholder="请输入规则ID" />
+          </div>
+          <div class="form-row">
+            <label class="form-label">规则名称:</label>
+            <input v-model="form.address" class="form-input" placeholder="请输入规则名称" />
+          </div>
+          <div class="form-row">
+            <label class="form-label">触发条件:</label>
+            <input v-model="form.grade" class="form-input" placeholder="例如:温度>60℃" />
+          </div>
+          <div class="form-row">
+            <label class="form-label">联动动作:</label>
+            <input v-model="form.action" class="form-input" placeholder="例如:声光报警" />
+          </div>
+          <div class="form-row">
+            <label class="form-label">状态:</label>
+            <select v-model="form.status" class="form-select">
+              <option value="启用">启用</option>
+              <option value="禁用">禁用</option>
+            </select>
+          </div>
+        </div>
+        <div class="modal-footer">
+          <button class="btn-cancel" @click="closeAddModal">取消</button>
+          <button class="btn-submit" @click="submitForm">确定</button>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue';
-
+import { ref, reactive } from 'vue';
+import { message } from 'ant-design-vue';
 let searchWarn = ref('');
 let titleList = ref<any[]>([
   { label: '规则ID', value: '1' },
@@ -47,8 +86,58 @@ let tableData = ref<any[]>([
   { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
   { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
   { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
-  { time: 'LINK001', address: '温度报警联动', grade: '温度>60℃', action: '声光报警', status: '启用' },
 ]);
+
+// 弹窗控制
+const modalVisible = ref(false);
+
+// 新增表单数据
+const form = reactive({
+  time: '',
+  address: '',
+  grade: '',
+  action: '',
+  status: '启用',
+});
+
+// 打开弹窗
+const openAddModal = () => {
+  modalVisible.value = true;
+};
+
+// 关闭弹窗并重置表单
+const closeAddModal = () => {
+  modalVisible.value = false;
+  // 重置表单
+  form.time = '';
+  form.address = '';
+  form.grade = '';
+  form.action = '';
+  form.status = '启用';
+};
+
+// 提交表单
+const submitForm = () => {
+  if (!form.time) {
+    message.warning('请输入规则ID');
+    return;
+  }
+  if (!form.address) {
+    message.warning('请输入规则名称');
+    return;
+  }
+  if (!form.grade) {
+    message.warning('请输入触发条件');
+    return;
+  }
+  if (!form.action) {
+    message.warning('请输入联动动作');
+    return;
+  }
+  // 添加到表格数组头部
+  tableData.value.unshift({ ...form });
+  closeAddModal();
+};
 </script>
 
 <style lang="less" scoped>
@@ -188,4 +277,92 @@ let tableData = ref<any[]>([
 .zxm-input-sm {
   padding: 0px 20px;
 }
+
+// 弹窗样式
+.modal-mask {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.1);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 999;
+}
+.modal-box {
+  width: 420px;
+  background: #0e3455;
+  border: 1px solid #01fefc;
+  border-radius: 6px;
+  color: #fff;
+}
+.modal-header {
+  height: 40px;
+  line-height: 40px;
+  padding: 0 16px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-bottom: 1px solid #114268;
+  color: #01fefc;
+  font-size: 14px;
+  font-weight: bold;
+}
+.modal-close {
+  font-size: 20px;
+  cursor: pointer;
+  color: #ccc;
+}
+.modal-form {
+  padding: 16px;
+}
+.form-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 14px;
+  .form-label {
+    width: 90px;
+    font-size: 13px;
+  }
+  .form-input,
+  .form-select {
+    flex: 1;
+    height: 32px;
+    padding: 0 10px;
+    background: #114268;
+    border: 1px solid #01fefc;
+    color: #fff;
+    border-radius: 3px;
+    outline: none;
+  }
+}
+.modal-footer {
+  height: 48px;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  gap: 12px;
+  padding: 0 16px;
+  border-top: 1px solid #114268;
+  .btn-cancel {
+    width: 80px;
+    height: 30px;
+    background: transparent;
+    border: 1px solid #01fefc;
+    color: #fff;
+    cursor: pointer;
+    border-radius: 3px;
+  }
+  .btn-submit {
+    width: 80px;
+    height: 30px;
+    background: #20a6a9;
+    border: 1px solid #01fefc;
+    color: #fff;
+    cursor: pointer;
+    border-radius: 3px;
+  }
+}
 </style>