Sfoglia il codice sorgente

完成告警列表、维护申报

Yue 2 anni fa
parent
commit
3aebdef81b

+ 5 - 1
src/components/Table/VbDataTable.vue

@@ -13,6 +13,7 @@ const props = withDefaults(
     method?: string
     configs?: AxiosRequestConfig
     queryParams?: any
+    autoSearch?: boolean //页面加载时自动查询
     data?: Array<any>
     total?: number //总数
     selectedItems?: Array<any>
@@ -61,6 +62,7 @@ const props = withDefaults(
     pageArray: () => {
       return [10, 25, 50]
     },
+    autoSearch: true,
     hasCheckbox: true,
     checkMultiple: false,
     sortOrder: "asc",
@@ -237,7 +239,9 @@ watch(
 //   }
 // })
 onMounted(() => {
-  search()
+  if (props.autoSearch) {
+    search()
+  }
 })
 defineExpose({ search })
 </script>

+ 16 - 16
src/core/config/rules.ts

@@ -44,36 +44,36 @@ export const RULE_KEYS = {
 }
 export const rules = {
   VB_REQUIRED: { required: true, message: "必填", trigger: "blur" },
-  VB_NUMBER: { type: "number", message: "请输入数字", trigger: ["blur"] },
-  VB_INT: { type: "integer", message: "请输入整数", trigger: ["blur"] },
-  VB_FLOAT: { type: "float", message: "请输入浮点数", trigger: ["blur"] },
-  VB_HEX: { type: "hex", message: "请输入16进制数字", trigger: ["blur"] },
-  VB_URL: { type: "url", message: "请输入正确的URL地址", trigger: ["blur"] },
-  VB_EMAIL: { type: "email", message: "请输入正确的电子邮箱", trigger: ["blur"] },
+  VB_NUMBER: { type: "number", message: "请填写数字", trigger: ["blur"] },
+  VB_INT: { type: "integer", message: "请填写整数", trigger: ["blur"] },
+  VB_FLOAT: { type: "float", message: "请填写浮点数", trigger: ["blur"] },
+  VB_HEX: { type: "hex", message: "请填写16进制数字", trigger: ["blur"] },
+  VB_URL: { type: "url", message: "请填写正确的URL地址", trigger: ["blur"] },
+  VB_EMAIL: { type: "email", message: "请填写正确的电子邮箱", trigger: ["blur"] },
   VB_DATE: { type: "date", message: "请选择日期", trigger: ["blur"] },
   VB_DATETIME: { type: "date", message: "请选择时间", trigger: ["blur"] },
-  VB_REQUIRED_NUMBER: { type: "number", required: true, message: "请输入数字", trigger: ["blur"] },
-  VB_REQUIRED_INT: { type: "integer", required: true, message: "请输入整数", trigger: ["blur"] },
-  VB_REQUIRED_FLOAT: { type: "float", required: true, message: "请输入浮点数", trigger: ["blur"] },
-  VB_REQUIRED_HEX: { type: "hex", required: true, message: "请输入16进制数字", trigger: ["blur"] },
+  VB_REQUIRED_NUMBER: { type: "number", required: true, message: "请填写数字", trigger: ["blur"] },
+  VB_REQUIRED_INT: { type: "integer", required: true, message: "请填写整数", trigger: ["blur"] },
+  VB_REQUIRED_FLOAT: { type: "float", required: true, message: "请填写浮点数", trigger: ["blur"] },
+  VB_REQUIRED_HEX: { type: "hex", required: true, message: "请填写16进制数字", trigger: ["blur"] },
   VB_REQUIRED_URL: [
-    { type: "string", required: true, message: "请输入URL地址", trigger: "blur" },
-    { type: "url", message: "请输入正确的URL地址", trigger: ["blur"] },
+    { type: "string", required: true, message: "请填写URL地址", trigger: "blur" },
+    { type: "url", message: "请填写正确的URL地址", trigger: ["blur"] },
   ],
   VB_REQUIRED_EMAIL: [
-    { type: "string", required: true, message: "请输入电子邮箱", trigger: "blur" },
-    { type: "email", message: "请输入正确的电子邮箱", trigger: ["blur"] },
+    { type: "string", required: true, message: "请填写电子邮箱", trigger: "blur" },
+    { type: "email", message: "请填写正确的电子邮箱", trigger: ["blur"] },
   ],
   VB_REQUIRED_DATE: { type: "date", required: true, message: "请选择日期", trigger: ["blur"] },
   VB_REQUIRED_DATETIME: { type: "date", required: true, message: "请选择时间", trigger: ["blur"] },
 }
 export const rulesFormat = {
-  VB_REQUIRED: '{ "required": true, "message": "请输入{0}", "trigger": ["blur"] }',
+  VB_REQUIRED: '{ "required": true, "message": "请填写{0}", "trigger": ["blur"] }',
   VB_MIN: '{"type": "string","min": {0}, "message": "至少{0}个字符", "trigger": ["blur"] }',
   VB_MAX: '{"type": "string","max": {0}, "message": "最多{0}个字符", "trigger": ["blur" ]}',
   VB_MIN_MAX: '{"type": "string","min": {0}, "max": {1}, "message": "长度在 {0} 到 {1} 个字符", "trigger": ["blur"]}',
   VB_N_MIN: '{"type": "number","min": {0}, "message": "最小{0}", "trigger": ["blur"] }',
   VB_N_MAX: '{"type": "number","max": {0}, "message": "最大{0}", "trigger": ["blur" ]}',
-  VB_N_MIN_MAX: '{"type": "number","min": {0}, "max": {1}, "message": "请输入 {0} 到 {1} 的数字", "trigger": ["blur"]}',
+  VB_N_MIN_MAX: '{"type": "number","min": {0}, "max": {1}, "message": "请填写 {0} 到 {1} 的数字", "trigger": ["blur"]}',
   VB_PATTERN: '{"pattern": {0}, "message": "{1}", "trigger": ["blur"]}',
 }

+ 8 - 0
src/router/menuMap/_purify.ts

@@ -9,6 +9,14 @@ export const menus: Array<MenuRouteMap> = [
     path: "/purify/washInfo",
     component: () => import("@/views/purify/washInfo.vue"),
   },
+  {
+    path: "/purifyMonitor",
+    icon: "fas fa-shower",
+  },
+  {
+    path: "/purifyMonitor/TWP",
+    component: () => import("@/views/purify/washInfo_company.vue"),
+  },
 ]
 
 export default menus

+ 12 - 0
src/router/menuMap/_warn.ts

@@ -17,5 +17,17 @@ export const menus: Array<MenuRouteMap> = [
     path: "/warn/qWarnList",
     component: () => import("@/views/warn/companyWarnList.vue"),
   },
+  {
+    path: "/Abnormal",
+    icon: "fas fa-exclamation-triangle",
+  },
+  {
+    path: "/Abnormal/AbnormalList",
+    component: () => import("@/views/warn/abnormal.vue"),
+  },
+  {
+    path: "/Abnormal/AbnormalTable",
+    component: () => import("@/views/warn/abnormal_declare.vue"),
+  },
 ]
 export default menus

+ 30 - 0
src/router/statictRouter.ts

@@ -98,4 +98,34 @@ export const staticRotuer: Array<RouteRecordRaw> = [
       },
     ],
   },
+  {
+    path: "/",
+    component: () => import("@/layouts/main-layout/MainLayout.vue"),
+    children: [
+      {
+        path: "/AbnormalList/strongWarn",
+        component: () => import("@/views/warn/abnormalList/strongWarn.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["异常申报", "异常列表", "超标告警详情"],
+        },
+      },
+      {
+        path: "/AbnormalList/disConnect",
+        component: () => import("@/views/warn/abnormalList/disConnect.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["异常申报", "异常列表", "设备离线告警详情"],
+        },
+      },
+      {
+        path: "/AbnormalList/overdueWarn",
+        component: () => import("@/views/warn/abnormalList/overdueWarn.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["异常申报", "异常列表", "清洗逾期告警详情"],
+        },
+      },
+    ],
+  },
 ]

+ 2 - 2
src/views/analysisInfo/weekCleanList.vue

@@ -15,7 +15,7 @@ const cols = ref([
     field: "monitor_name",
   },
   {
-    name: "净化效能",
+    name: "清洁度",
     field: "clean_name",
   },
   {
@@ -66,7 +66,7 @@ const queryParams = ref({
         <tr class="text-center">
           <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">序号</th>
           <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">净化器名称</th>
-          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">净化效能</th>
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">清洁度</th>
           <th class="bg-light-primary" colspan="2">清洗周期</th>
           <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">最后清洗时间</th>
           <th class="bg-light-primary" colspan="2">上次清洗至今</th>

+ 328 - 2
src/views/examApproval/appReview.vue

@@ -1,7 +1,333 @@
 <script setup lang="ts">
-import { reactive, ref, toRefs } from "vue"
+import { ref, computed } from "vue"
+import configs from "@/core/config/Index"
+import router from "@/router"
+import Rs from "@/core/services/RequestService"
+import { ElInput, ElSelect } from "element-plus"
+import type { VbFormItem } from "@/components/Forms/models"
+const table = ref()
+const cols = ref([
+  {
+    name: "序号",
+    field: configs.TABLE_INDEX_FIELD,
+    width: 60,
+  },
+  {
+    name: "区域",
+    field: "org_name",
+  },
+  {
+    name: "企业名称",
+    field: "company_name",
+  },
+  {
+    name: "监测类型",
+    field: "monitoring_type_name",
+  },
+  {
+    name: "申报类型",
+    field: "declare_type_name",
+  },
+  {
+    name: "申报状态",
+    field: "audit_state_name",
+  },
+  {
+    name: "申报时间",
+    field: "abnormal_date",
+  },
+  {
+    name: "操作",
+    field: "action",
+    width: 100,
+  },
+])
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "180px" }
+const companyName = ref("")
+const orgId = ref<string | null>(null)
+const monitoringType = ref("")
+const auditState = ref("")
+const declareType = ref("")
+const queryParams = ref({})
+
+const jump = function (v: any) {
+  console.log("jump", v)
+  router.push({
+    path: "/goLineData/oilFumeConcentration",
+    query: {
+      comName: v.company_name,
+      company_id: v.company_id,
+      back: 1,
+    },
+  })
+}
+
+function query() {
+  const params = {
+    org_id: orgId.value,
+    company_name: companyName.value,
+    monitoring_type: monitoringType.value,
+    audit_state: auditState.value,
+    declare_type: declareType.value,
+  }
+  const keys = Object.keys(params)
+  keys.forEach((key) => {
+    if (params[key] == "") {
+      delete params[key]
+    }
+  })
+  queryParams.value = params
+}
+function reset() {
+  companyName.value = ""
+  orgId.value = "0"
+  monitoringType.value = ""
+  auditState.value = ""
+  declareType.value = ""
+  query()
+}
+const modal = ref<any>()
+const operationType = ref<"D" | "A">("D")
+
+const modalTitle = computed(() => {
+  return operationType.value == "D" ? "申报详情" : operationType.value == "A" ? "审核申报" : ""
+})
+const formData = ref({
+  declare_id: "",
+  audit_user: "",
+  audit_desc: "",
+  audit_state: "",
+  declare_type: "",
+})
+const formItems = computed(() => {
+  return (
+    operationType.value == "A"
+      ? [
+          {
+            field: "audit_org_name",
+            label: "审核机构:",
+            component: "innerText",
+            innerText: details.value.audit_org_name,
+          },
+          {
+            field: "audit_state",
+            label: "审核信息",
+            required: true,
+            component: ElSelect,
+            data: [
+              {
+                label: "审核通过",
+                value: "1",
+              },
+              {
+                label: "审核不通过",
+                value: "2",
+              },
+            ],
+            span: 12,
+          },
+          {
+            field: "audit_user",
+            label: "审核人",
+            required: true,
+            component: ElInput,
+            span: 12,
+          },
+          {
+            field: "audit_desc",
+            label: "审核意见",
+            required: true,
+            type: "textarea",
+            component: ElInput,
+          },
+        ]
+      : []
+  ) as Array<VbFormItem>
+})
+const details = ref<any>({})
+const detail = function (row: any) {
+  operationType.value = "D"
+  getDetail(row)
+}
+const audit = function (row: any) {
+  operationType.value = "A"
+
+  getDetail(row)
+}
+const download = () => {
+  if (details.value.annex_data_down_url) {
+    window.open(details.value.annex_data_down_url)
+  }
+}
+function getDetail(row: any) {
+  formData.value.declare_id = row.id
+  formData.value.declare_type = row.declare_type
+  formData.value.audit_state = "2"
+  Rs.get(`sys/orgDeclare/selectDeclare?id=${row.id}`).then((res) => {
+    details.value = Object.assign({}, res.data)
+    formData.value.audit_user = res.data.audit_user
+    formData.value.audit_desc = res.data.audit_desc
+    modal.value.show()
+  })
+}
+function onSave() {
+  if (operationType.value == "D") {
+    return
+  }
+  Rs.post("sys/orgDeclare/updateAbnormalDeclare", { data: formData.value }).then(() => {
+    table.value.search()
+  })
+}
 </script>
 
 <template>
-  <div>appReview</div>
+  <VbDataTable
+    ref="table"
+    :header="cols"
+    url="sys/orgDeclare/selectForMaintainDeclare"
+    method="post"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  >
+    <template v-slot:table-tool="">
+      <el-form class="align-items-center" :inline="true">
+        <el-form-item class="mb-0 me-5 align-items-center" label="商户名称">
+          <el-input class="" style="width: 180px" v-model="companyName" placeholder="请输入商户名称" :size="size" />
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="区域">
+          <OrgSelectTree v-model:value="orgId" style="width: 180px"></OrgSelectTree>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="申报类型">
+          <el-select v-model="declareType" :style="dySearchSelectStyle" clearable placeholder="请选择申报类型">
+            <el-option value="0" label="异常申报"></el-option>
+            <el-option value="1" label="维护申报"></el-option>
+            <el-option value="2" label="清洗填报"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="审核状态">
+          <el-select v-model="auditState" :style="dySearchSelectStyle" clearable placeholder="请选择审核状态">
+            <el-option value="0" label="未审核"></el-option>
+            <el-option value="1" label="审核通过"></el-option>
+            <el-option value="2" label="未审核通过"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="监测类型">
+          <DySelect
+            v-model="monitoringType"
+            :url="'sys/dict/getCompanyMonitoringType'"
+            :style="dySearchSelectStyle"
+            placeholder="请选择监测类型"
+          ></DySelect>
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center">
+          <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="query">查询</el-button>
+          <el-button class="ms-3 mt-0 btn btn-sm btn-light-primary btn-outline" @click="reset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </template>
+    <template #company_name="{ row }">
+      <span class="text-primary" @click="jump(row)" style="cursor: pointer">{{ row["company_name"] }}</span>
+    </template>
+    <template #audit_state_name="{ row }">
+      <span
+        class="badge"
+        :class="`badge-${row.audit_state == 0 ? 'primary' : row.audit_state == 1 ? 'success' : 'danger'}`"
+      >
+        {{ row["audit_state_name"] }}
+      </span>
+    </template>
+    <template #action="{ row }">
+      <span v-if="row.audit_state == 1" class="table-action" @click="detail(row)">详情</span>
+      <span v-else class="table-action" @click="audit(row)">审核</span>
+    </template>
+  </VbDataTable>
+  <VbModal v-model:modal="modal" :title="modalTitle" :form-data="formData" :form-items="formItems" @confirm="onSave">
+    <template #body>
+      <el-row v-if="details.declare_type">
+        <el-col :span="12">
+          <dl>
+            <dt>异常信息:</dt>
+            <dd>{{ details.maintain_type }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>时间:</dt>
+            <dd>{{ details.time }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>异常内容:</dt>
+            <dd>{{ details.content }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <el-row v-else>
+        <el-col :span="12">
+          <dl>
+            <dt>设备名称:</dt>
+            <dd>{{ details.device_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>维护类型:</dt>
+            <dd>{{ details.maintain_type }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>维护周期:</dt>
+            <dd>{{ details.time }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <div class="separator mt-2 mb-5"></div>
+
+      <el-row>
+        <el-col :span="12">
+          <dl>
+            <dt>企业名称:</dt>
+            <dd>{{ details.company_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>联系方式:</dt>
+            <dd>{{ details.user_phone }}</dd>
+          </dl>
+        </el-col>
+        <!-- <el-col :span="12">
+          <dl>
+            <dt>企业申报信息:</dt>
+            <dd>{{ details.content }}</dd>
+          </dl>
+        </el-col> -->
+        <el-col :span="12">
+          <dl>
+            <dt>情况描述:</dt>
+            <dd>{{ details.content }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>附件:</dt>
+            <dd>
+              <a v-if="details.annex_data_down_url" @click="download">点击下载</a>
+              <span v-else>暂无</span>
+            </dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>申报人:</dt>
+            <dd>{{ details.declare_user }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <div v-if="formItems.length" class="separator mt-2 mb-5"></div>
+    </template>
+  </VbModal>
 </template>

+ 320 - 2
src/views/examApproval/reptNotice.vue

@@ -1,7 +1,325 @@
 <script setup lang="ts">
-import { defineProps, reactive, ref, toRefs } from "vue"
+import { ref } from "vue"
+import configs from "@/core/config/Index"
+import router from "@/router"
+import Rs from "@/core/services/RequestService"
+import moment from "moment"
+const table = ref()
+const cols = ref([
+  {
+    name: "序号",
+    field: configs.TABLE_INDEX_FIELD,
+    width: 60,
+  },
+  {
+    name: "区域",
+    field: "org_name",
+  },
+  {
+    name: "企业名称",
+    field: "company_name",
+  },
+  {
+    name: "监测类型",
+    field: "monitoring_type_name",
+  },
+  {
+    name: "通知类型",
+    field: "notice_type_name",
+  },
+  {
+    name: "通知时间",
+    field: "notice_time",
+  },
+  {
+    name: "状态",
+    field: "state",
+  },
+  {
+    name: "操作",
+    field: "action",
+    width: 100,
+  },
+])
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "160px" }
+const companyName = ref("")
+const orgId = ref<string | null>(null)
+const monitoringType = ref("")
+const state = ref("")
+const type = ref("")
+const currentDate = ref<Date>(new Date())
+const queryParams = ref({
+  date: moment(currentDate.value).format("YYYYMMDD"),
+})
+
+const jump = function (v: any) {
+  console.log("jump", v)
+  router.push({
+    path: "/goLineData/oilFumeConcentration",
+    query: {
+      comName: v.company_name,
+      company_id: v.company_id,
+      back: 1,
+    },
+  })
+}
+
+function query() {
+  const params = {
+    org_id: orgId.value,
+    company_name: companyName.value,
+    monitoring_type: monitoringType.value,
+    state: state.value,
+    type: type.value,
+    date: moment(currentDate.value).format("YYYYMMDD"),
+  }
+
+  const keys = Object.keys(params)
+  keys.forEach((key) => {
+    if (params[key] == "") {
+      delete params[key]
+    }
+  })
+  queryParams.value = params
+}
+function reset() {
+  companyName.value = ""
+  orgId.value = "0"
+  monitoringType.value = ""
+  state.value = ""
+  type.value = ""
+  currentDate.value = new Date()
+  query()
+}
+const modal = ref<any>()
+const operationType = ref<"R" | "N">("R")
+
+const modalTitle = ref("")
+
+const details = ref<any>({})
+const reply = function (row: any) {
+  operationType.value = "R"
+  modalTitle.value = "告警通知"
+  getDetail(row)
+}
+const notity = function (row: any) {
+  operationType.value = "N"
+  if (row.type == 0) {
+    modalTitle.value = "告警通知"
+  } else if (row.type == 1) {
+    modalTitle.value = "清洗通知"
+  }
+  getDetail(row)
+}
+
+function getDetail(row: any) {
+  Rs.post(`sys/notice/getNoticeDetail`, { params: row.id }).then((res) => {
+    details.value = Object.assign({}, res.data)
+    details.value.clear_date = moment(res.data.clear_date, "YYYYMMDD").format("YYYY-MM-DD")
+    modal.value.show()
+  })
+}
 </script>
 
 <template>
-  <div>reptNotice</div>
+  <VbDataTable
+    ref="table"
+    :header="cols"
+    url="sys/notice/selectForPage"
+    method="post"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  >
+    <template v-slot:table-tool="">
+      <el-form class="align-items-center" :inline="true">
+        <el-form-item class="mb-0 me-5 align-items-center" label="商户名称">
+          <el-input class="" style="width: 180px" v-model="companyName" placeholder="请输入商户名称" :size="size" />
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="区域">
+          <OrgSelectTree v-model:value="orgId" style="width: 180px"></OrgSelectTree>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="通知类型">
+          <el-select v-model="type" :style="dySearchSelectStyle" clearable placeholder="请选择通知类型">
+            <el-option value="0" label="告警通知"></el-option>
+            <el-option value="1" label="清洗通知"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="状态">
+          <el-select v-model="state" :style="dySearchSelectStyle" clearable placeholder="请选择状态">
+            <el-option value="0" label="未回复"></el-option>
+            <el-option value="1" label="已回复"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="时间">
+          <el-date-picker
+            v-model="currentDate"
+            type="date"
+            placeholder="请选择时间"
+            :size="size"
+            :style="dySearchSelectStyle"
+            :clearable="false"
+          />
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="监测类型">
+          <DySelect
+            v-model="monitoringType"
+            :url="'sys/dict/getCompanyMonitoringType'"
+            :style="dySearchSelectStyle"
+            placeholder="请选择监测类型"
+          ></DySelect>
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center">
+          <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="query">查询</el-button>
+          <el-button class="ms-3 mt-0 btn btn-sm btn-light-primary btn-outline" @click="reset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </template>
+    <template #company_name="{ row }">
+      <span class="text-primary" @click="jump(row)" style="cursor: pointer">{{ row["company_name"] }}</span>
+    </template>
+    <template #state="{ row }">
+      <span class="badge" :class="`badge-${row.state == 0 ? 'primary' : row.state == 1 ? 'success' : 'danger'}`">
+        {{ row["state"] }}
+      </span>
+    </template>
+    <template #notice_time="{ row }">
+      {{ moment(row["notice_time"], "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") }}
+    </template>
+    <template #action="{ row }">
+      <span v-if="row.state == 1" class="table-action" @click="reply(row)">查看回复</span>
+      <span class="table-action" @click="notity(row)">查看通知</span>
+    </template>
+  </VbDataTable>
+  <VbModal v-model:modal="modal" :title="modalTitle">
+    <template #body>
+      <el-row v-if="operationType == 'R' && details.type == 1">
+        <el-col :span="12">
+          <dl>
+            <dt>是否清洗:</dt>
+            <dd>{{ details.is_clear ? "已清洗" : "未清洗" }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>清洗时间:</dt>
+            <dd>{{ details.clear_date }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>备注:</dt>
+            <dd>{{ details.remark }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <el-row v-if="operationType == 'R' && details.type == 0">
+        <el-col :span="12">
+          <dl>
+            <dt>设备名称:</dt>
+            <dd>{{ details.device_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>异常类型:</dt>
+            <dd>{{ details.warn_type_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>告警原因:</dt>
+            <dd>{{ details.content }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>异常原因:</dt>
+            <dd>{{ details.remark }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+
+      <el-row v-if="operationType == 'N' && details.type == 1">
+        <el-col :span="12">
+          <dl>
+            <dt>企业名称:</dt>
+            <dd>{{ details.company_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>清洗周期(天):</dt>
+            <dd>{{ details.clean_cycle_day }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>设施名称:</dt>
+            <dd>{{ details.device_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>清洗周期(小时):</dt>
+            <dd>{{ details.clean_cycle_hour }}</dd>
+          </dl>
+        </el-col>
+
+        <el-col :span="12">
+          <dl>
+            <dt>是否完成清洗:</dt>
+            <dd>{{ details.is_clear ? "已清洗" : "未清洗" }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <el-row v-if="operationType == 'N' && details.type == 0">
+        <el-col :span="12">
+          <dl>
+            <dt>企业名称:</dt>
+            <dd>{{ details.company_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>异常类型:</dt>
+            <dd>{{ details.warn_type_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>告警设备:</dt>
+            <dd>{{ details.device_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>告警时间:</dt>
+            <dd>{{ details.warn_time }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>通知内容:</dt>
+            <dd>{{ details.content }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+      <div class="separator mt-2 mb-5"></div>
+      <el-row v-if="operationType == 'N'">
+        <el-col :span="12">
+          <dl>
+            <dt>部门:</dt>
+            <dd>{{ details.org_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>通知人:</dt>
+            <dd>{{ details.notifier }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+    </template>
+  </VbModal>
 </template>

+ 182 - 0
src/views/purify/washInfo_company.vue

@@ -0,0 +1,182 @@
+<script setup lang="ts">
+import configs from "@/core/config/Index"
+import moment from "moment"
+import { ref } from "vue"
+
+const cols = ref([
+  {
+    name: "序号",
+    width: 60,
+    field: configs.TABLE_INDEX_FIELD,
+  },
+  {
+    name: "净化器名称",
+    field: "monitor_name",
+  },
+  {
+    name: "天数",
+    field: "day_condition",
+  },
+  {
+    name: "开机小时",
+    field: "hour_condition",
+  },
+  {
+    name: "最后清洗时间",
+    field: "last_clean_time",
+  },
+  {
+    name: "经过天数",
+    field: "run_day",
+  },
+  {
+    name: "开机小时数",
+    field: "run_hour",
+  },
+  {
+    name: "剩余天数",
+    field: "surplus_day",
+  },
+  {
+    name: "剩余小时数",
+    field: "surplus_hour",
+  },
+  {
+    name: "清洗记录",
+    field: "action",
+  },
+])
+const queryParams = ref({})
+const modal = ref()
+const modalTable = ref()
+const dateRange = ref<any>("")
+const col2s = ref<Array<any>>([
+  {
+    name: "设备名称",
+    field: "device_name",
+  },
+  {
+    name: "清洗时间",
+    field: "clean_start",
+  },
+  {
+    name: "清洗照片",
+    field: "pictures",
+  },
+])
+const queryParam2s = ref<any>({
+  device_id: "0",
+})
+const deviceId = ref("")
+function cleanList(row: any) {
+  deviceId.value = row.device_id
+  query()
+  modal.value.show()
+}
+function query() {
+  const params: any = {
+    device_id: deviceId.value + "",
+  }
+  if (dateRange.value[0]) {
+    params.clean_start = moment(dateRange.value[0]).format("YYYYMMDD")
+    params.clean_end = moment(dateRange.value[1]).format("YYYYMMDD")
+  }
+  //[moment(new Date()).add(-1, "M").toDate(), new Date()]
+  queryParam2s.value = params
+}
+function reset() {
+  dateRange.value = ""
+}
+</script>
+
+<template>
+  <VbDataTable
+    url="sys/purifierCondition/getCompanyCleanList"
+    :header="cols"
+    :query-params="queryParams"
+    method="post"
+    :has-checkbox="false"
+    :pagination="false"
+  >
+    <template #tableHeader>
+      <thead>
+        <tr class="text-center">
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">序号</th>
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">净化器名称</th>
+          <th class="bg-light-primary" colspan="2">清洗周期</th>
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">最后清洗时间</th>
+          <th class="bg-light-primary" colspan="2">上次清洗至今</th>
+          <th class="bg-light-primary" colspan="2">距下次清洗</th>
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">清洗记录</th>
+        </tr>
+        <tr class="text-center">
+          <th class="bg-light-primary">天数</th>
+          <th class="bg-light-primary">开机小时</th>
+          <th class="bg-light-primary">经过天数</th>
+          <th class="bg-light-primary">开机小时数</th>
+          <th class="bg-light-primary">剩余天数</th>
+          <th class="bg-light-primary">剩余小时数</th>
+        </tr>
+      </thead>
+    </template>
+
+    <template #last_clean_time="{ row }">
+      {{ moment(row.last_clean_time, "YYYYMMDDHHmmss").format("YYYY-MM-DD") }}
+    </template>
+    <template #action="{ row }">
+      <div class="text-danger text-center">
+        <span class="table-action" @click="cleanList(row)">清洗记录</span>
+      </div>
+    </template>
+  </VbDataTable>
+  <VbModal
+    v-model:modal="modal"
+    title="清洗记录"
+    close-btn-class="btn btn-primary"
+    :confirm-btn="false"
+    modal-dialog-style="max-width: 1100px;width: 1100px;"
+  >
+    <template #body>
+      <VbDataTable
+        ref="modalTable"
+        :header="col2s"
+        url="sys/purifierCondition/getEnterpriseCleanLog"
+        method="post"
+        :auto-search="false"
+        :query-params="queryParam2s"
+        :has-checkbox="false"
+      >
+        <template v-slot:table-tool="">
+          <el-form class="align-items-center" :inline="true">
+            <el-form-item class="mb-0 me-0 align-items-center" label="日期">
+              <el-date-picker
+                v-model="dateRange"
+                type="daterange"
+                range-separator="~"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                size="default"
+              />
+            </el-form-item>
+            <el-form-item class="mb-0 me-0 align-items-center">
+              <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="query">查询</el-button>
+              <el-button class="ms-3 mt-0 btn btn-sm btn-light-primary btn-outline" @click="reset">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </template>
+        <template #pictures="{ row }">
+          <div class="d-flex h-100 justify-content-center align-items-center p-3">
+            <el-image
+              :src="`/api/file/upload/res/${row.pictures}`"
+              :preview-src-list="[`/api/file/upload/res/${row.pictures}`]"
+              :hide-on-click-modal="true"
+              fit="cover"
+              style="height: 50px; width: 75px; max-width: none; border-radius: 0.475rem"
+              alt=""
+            />
+          </div>
+        </template>
+      </VbDataTable>
+    </template>
+  </VbModal>
+</template>

+ 1 - 1
src/views/purify/washInfo_details.vue

@@ -1,10 +1,10 @@
 <script setup lang="ts">
 import { ref } from "vue"
 import configs from "@/core/config/Index"
-import { useRoute } from "vue-router"
 import moment from "moment"
 import Rs from "@/core/services/RequestService"
 import { ElInput } from "element-plus"
+import { useRoute } from "vue-router"
 const route = useRoute()
 const active = ref(0)
 const cols = ref<Array<any>>([

+ 115 - 0
src/views/warn/abnormal.vue

@@ -0,0 +1,115 @@
+<script setup lang="ts">
+import { ref } from "vue"
+import moment from "moment"
+import router from "@/router"
+const cols = ref([
+  {
+    name: "设备名称",
+    field: "device_name",
+  },
+  {
+    name: "异常类型",
+    field: "warn_type_name",
+  },
+  {
+    name: "告警时间",
+    field: "warn_time",
+  },
+  {
+    name: "持续时间(分钟)",
+    field: "continue_time",
+  },
+  {
+    name: "操作",
+    field: "action",
+    width: 100,
+  },
+])
+const warnType = ref(null)
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "180px" }
+const dateRange = ref<any>([moment(new Date()).add(-1, "M").toDate(), new Date()])
+const queryParams = ref({
+  warn_type: warnType.value,
+  abnormal_state: null,
+  query_start_time: moment(dateRange.value[0]).format("YYYYMMDD"),
+  query_end_time: moment(dateRange.value[1]).format("YYYYMMDD"),
+})
+
+function query() {
+  queryParams.value = {
+    warn_type: warnType.value,
+    abnormal_state: null,
+    query_start_time: moment(dateRange.value[0]).format("YYYYMMDD"),
+    query_end_time: moment(dateRange.value[1]).format("YYYYMMDD"),
+  }
+}
+function reset() {
+  warnType.value = null
+  dateRange.value = [moment(new Date()).add(-1, "M").toDate(), new Date()]
+  query()
+}
+function detail(row: any) {
+  if (row.warn_type == "000100003" || row.warn_type == "000100005" || row.warn_type == "000100007") {
+    router.push({
+      path: "/AbnormalList/strongWarn",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  } else if (row.warn_type == "000100006") {
+    router.push({
+      path: "/AbnormalList/disConnect",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  } else {
+    router.push({
+      path: "/AbnormalList/overdueWarn",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  }
+}
+</script>
+
+<template>
+  <VbDataTable
+    ref="table"
+    :header="cols"
+    url="sys/companyDeclare/getCompanyWarnList"
+    method="post"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  >
+    <template v-slot:table-tool="">
+      <el-form class="align-items-center" :inline="true">
+        <el-form-item class="mb-0 me-5 align-items-center" label="异常类型">
+          <DySelect
+            v-model="warnType"
+            :url="'sys/dict/getList?code=000100001&key=temp'"
+            :formatRemoteData="(v:any)=>{return v?.list}"
+            :style="dySearchSelectStyle"
+            :size="size"
+            @clear="warnType = null"
+            placeholder="请选择异常类型"
+          ></DySelect>
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center" label="日期">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="~"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            size="default"
+          />
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center">
+          <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="query">查询</el-button>
+          <el-button class="ms-3 mt-0 btn btn-sm btn-light-primary btn-outline" @click="reset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </template>
+
+    <template #action="{ row }">
+      <span class="table-action" @click="detail(row)">查看</span>
+    </template>
+  </VbDataTable>
+</template>

+ 72 - 0
src/views/warn/abnormalList/disConnect.vue

@@ -0,0 +1,72 @@
+<script setup lang="ts">
+import Rs from "@/core/services/RequestService"
+import { ref, onMounted } from "vue"
+import { useRoute } from "vue-router"
+const route = useRoute()
+const options = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const chartTitle = ref("")
+const chartData = ref({})
+function getTitle() {
+  Rs.post("sys/warn/getWarnTitle", { data: options.value }).then((res) => {
+    chartTitle.value = res.data
+  })
+}
+function getChart() {
+  Rs.post("sys/warn/getWarnChartDataById", { data: options.value }).then((res) => {
+    chartData.value = res.data
+  })
+}
+const cols = ref([
+  {
+    name: "设备名称",
+    field: "device_name",
+  },
+  {
+    name: "启停阈值(A)",
+    field: "run_threshold",
+  },
+  {
+    name: "当天运行时间",
+    field: "run_time",
+  },
+  {
+    name: "当前设备状态",
+    field: "run_status",
+  },
+])
+const queryParams = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const lineOptions = { titleText: " " }
+function init() {
+  getTitle()
+  getChart()
+}
+
+onMounted(init)
+</script>
+
+<template>
+  <div class="card card-bordered mb-8">
+    <div class="card-header bg-light-primary min-h-50px">
+      <div class="card-title">
+        <h3 class="text-primary">{{ chartTitle }}</h3>
+      </div>
+    </div>
+    <div class="card-body p-5 h-325px">
+      <BaseChart :data="chartData" type="line" h="100%" :options="lineOptions"></BaseChart>
+    </div>
+  </div>
+  <VbDataTable
+    :header="cols"
+    url="sys/warn/getWarntableDataById"
+    method="post"
+    :no-page="true"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  ></VbDataTable>
+</template>

+ 191 - 0
src/views/warn/abnormalList/overdueWarn.vue

@@ -0,0 +1,191 @@
+<script setup lang="ts">
+import Rs from "@/core/services/RequestService"
+import moment from "moment"
+import { ref, onMounted, computed } from "vue"
+import { useRoute } from "vue-router"
+const route = useRoute()
+const options = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const type = ref(0)
+const chartTitle = ref("")
+const _chartData = ref({})
+const chartData = computed(() => {
+  const data: any = Object.assign({}, _chartData.value)
+  if (!data) {
+    return {}
+  }
+  const period = type.value == 0 ? data.day_condition : data.hour_condition
+  const overdue =
+    type.value == 0
+      ? data.run_day - data.day_condition > 0
+        ? data.run_day - data.day_condition
+        : 0
+      : data.run_hour - data.hour_condition > 0
+      ? data.run_hour - data.hour_condition
+      : 0
+
+  return {
+    chartData: [
+      {
+        categories: ["逾期时间", "周期时间"],
+        series: [
+          {
+            name: "辅助",
+            type: "bar",
+            stack: "总量",
+            barWidth: 80,
+            barMaxWidth: 80,
+            itemStyle: {
+              barBorderColor: "rgba(0,0,0,0)",
+              color: "rgba(0,0,0,0)",
+            },
+            data: [period, 0],
+          },
+          {
+            name: "时间",
+            type: "bar",
+            stack: "总量",
+            barWidth: 80,
+            barMaxWidth: 80,
+            label: {
+              show: true,
+              position: "right",
+            },
+            data: [
+              {
+                value: overdue,
+                itemStyle: {
+                  color: "rgba(242,99,123,0.75)",
+                },
+              },
+              {
+                value: period,
+                itemStyle: {
+                  color: "rgba(24,144,255,0.75)",
+                },
+              },
+            ],
+          },
+        ],
+        yzTitle: `${type.value == 0 ? "天" : "小时"}`,
+      },
+    ],
+  }
+})
+function getTitle() {
+  Rs.post("sys/warn/getWarnTitle", { data: options.value }).then((res) => {
+    chartTitle.value = res.data
+  })
+}
+function getChart() {
+  Rs.post("sys/warn/getCleanWarntableById", { data: options.value }).then((res) => {
+    _chartData.value = Object.assign({}, res.data[0])
+  })
+}
+const cols = ref([
+  {
+    name: "净化器名称",
+    field: "monitor_name",
+  },
+  {
+    name: "天数",
+    field: "day_condition",
+  },
+  {
+    name: "开机小时",
+    field: "hour_condition",
+  },
+  {
+    name: "上次清洗时间",
+    field: "last_clean_time",
+  },
+  {
+    name: "经过天数",
+    field: "run_day",
+  },
+  {
+    name: "开机小时数",
+    field: "run_hour",
+  },
+  {
+    name: "距下次清洗",
+    field: "surplus_day",
+  },
+  {
+    name: "剩余小时数",
+    field: "surplus_hour",
+  },
+])
+const queryParams = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const barOption = {
+  grid: { top: 10, right: 40 },
+  legend: { show: false },
+  titleText: " ",
+  direction: "y",
+  tooltip: {
+    formatter: "{b1}: {c1}",
+  },
+}
+function init() {
+  getTitle()
+  getChart()
+}
+
+onMounted(init)
+</script>
+
+<template>
+  <div class="card card-bordered mb-8">
+    <div class="card-header bg-light-primary min-h-50px">
+      <div class="card-title">
+        <h3 class="text-primary">{{ chartTitle }}</h3>
+      </div>
+      <div class="card-toolbar">
+        <el-radio-group v-model="type">
+          <el-radio-button :label="0">按天数</el-radio-button>
+          <el-radio-button :label="1">按小时数</el-radio-button>
+        </el-radio-group>
+      </div>
+    </div>
+    <div class="card-body p-5 h-325px">
+      <BaseChart :data="chartData" type="bar" h="100%" :options="barOption"></BaseChart>
+    </div>
+  </div>
+  <VbDataTable
+    :header="cols"
+    url="sys/warn/getCleanWarntableById"
+    method="post"
+    :no-page="true"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  >
+    <template #tableHeader>
+      <thead>
+        <tr class="text-center">
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">净化器名称</th>
+          <th class="bg-light-primary" colspan="2">清洗周期</th>
+          <th class="bg-light-primary" rowspan="2" style="vertical-align: middle">最后清洗时间</th>
+          <th class="bg-light-primary" colspan="2">上次清洗至今</th>
+          <th class="bg-light-primary" colspan="2">距下次清洗</th>
+        </tr>
+        <tr class="text-center">
+          <th class="bg-light-primary">天数</th>
+          <th class="bg-light-primary">开机小时</th>
+          <th class="bg-light-primary">经过天数</th>
+          <th class="bg-light-primary">开机小时数</th>
+          <th class="bg-light-primary">剩余天数</th>
+          <th class="bg-light-primary">剩余小时数</th>
+        </tr>
+      </thead>
+    </template>
+
+    <template #last_clean_time="{ row }">
+      {{ moment(row.last_clean_time, "YYYYMMDDHHmmss").format("YYYY-MM-DD") }}
+    </template>
+  </VbDataTable>
+</template>

+ 72 - 0
src/views/warn/abnormalList/strongWarn.vue

@@ -0,0 +1,72 @@
+<script setup lang="ts">
+import Rs from "@/core/services/RequestService"
+import { ref, onMounted } from "vue"
+import { useRoute } from "vue-router"
+const route = useRoute()
+const options = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const chartTitle = ref("")
+const chartData = ref({})
+function getTitle() {
+  Rs.post("sys/warn/getWarnTitle", { data: options.value }).then((res) => {
+    chartTitle.value = res.data
+  })
+}
+function getChart() {
+  Rs.post("sys/warn/getWarnChartDataById", { data: options.value }).then((res) => {
+    chartData.value = res.data
+  })
+}
+const cols = ref([
+  {
+    name: "浓度最大值(mg/m3)",
+    field: "warn_max_value",
+  },
+  {
+    name: "排放限值",
+    field: "warn_threshold",
+  },
+  {
+    name: "排放占比(%)",
+    field: "discharge_percent",
+  },
+  {
+    name: "发生时间",
+    field: "warn_max_time",
+  },
+])
+const queryParams = ref({
+  warn_id: route.query.id,
+  warn_type: route.query.type,
+})
+const lineOptions = { titleText: " " }
+function init() {
+  getTitle()
+  getChart()
+}
+
+onMounted(init)
+</script>
+
+<template>
+  <div class="card card-bordered mb-8">
+    <div class="card-header bg-light-primary min-h-50px">
+      <div class="card-title">
+        <h3 class="text-primary">{{ chartTitle }}</h3>
+      </div>
+    </div>
+    <div class="card-body p-5 h-325px">
+      <BaseChart :data="chartData" type="line" h="100%" :options="lineOptions"></BaseChart>
+    </div>
+  </div>
+  <VbDataTable
+    :header="cols"
+    url="sys/warn/getWarntableDataById"
+    method="post"
+    :no-page="true"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  ></VbDataTable>
+</template>

+ 296 - 0
src/views/warn/abnormal_declare.vue

@@ -0,0 +1,296 @@
+<script setup lang="ts">
+import { ref, computed } from "vue"
+import configs from "@/core/config/Index"
+import moment from "moment"
+import DySelect from "@/components/select/DySelect.vue"
+import { ElDatePicker, ElInput } from "element-plus"
+import type { VbFormItem } from "@/components/Forms/models"
+import Rs from "@/core/services/RequestService"
+
+const table = ref()
+const cols = ref<any>([
+  {
+    name: "序号",
+    field: configs.TABLE_INDEX_FIELD,
+    width: 60,
+  },
+  {
+    name: "设施名称",
+    field: "device_name",
+  },
+  {
+    name: "申报时间",
+    field: "abnormal_date",
+  },
+  {
+    name: "申报周期",
+    field: "maintain_times",
+    width: 350,
+  },
+
+  {
+    name: "申报类型",
+    field: "declare_type_name",
+  },
+  {
+    name: "审批状态",
+    field: "audit_state_name",
+  },
+  {
+    name: "操作",
+    field: "action",
+    width: 160,
+  },
+])
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "180px" }
+const auditStateSelectList = [
+  {
+    label: "未审核",
+    value: "0",
+  },
+  {
+    label: "审核通过",
+    value: "1",
+  },
+  {
+    label: "审核未通过",
+    value: "2",
+  },
+]
+const auditState = ref("")
+const dateRange = ref<any>("")
+const queryParams = ref({
+  audit_state: auditState.value,
+  declare_time_query_start: "",
+  declare_time_query_end: "",
+})
+function query() {
+  if (dateRange.value[0]) {
+    queryParams.value = {
+      audit_state: auditState.value,
+      declare_time_query_start: moment(dateRange.value[0]).format("YYYYMMDD"),
+      declare_time_query_end: moment(dateRange.value[1]).format("YYYYMMDD"),
+    }
+  } else {
+    queryParams.value = {
+      audit_state: auditState.value,
+      declare_time_query_start: "",
+      declare_time_query_end: "",
+    }
+  }
+}
+function reset() {
+  auditState.value = ""
+  dateRange.value = ""
+  query()
+}
+const operationType = ref<"D" | "C">("D")
+const modal = ref()
+const modalTitle = computed(() => {
+  return operationType.value == "C" ? "添加申报" : operationType.value == "D" ? "申报详情" : ""
+})
+const formItems = computed(() => {
+  return (
+    operationType.value == "C"
+      ? [
+          {
+            label: "维护设备",
+            field: "device_id",
+            placeholder: "请选择维护设备",
+            required: true,
+            component: DySelect,
+            props: {
+              url: "sys/monitor/getDeviceList",
+            },
+            span: 12,
+          },
+          {
+            label: "维护类型",
+            field: "maintain_type",
+            placeholder: "请选择维护类型",
+            required: true,
+            component: DySelect,
+            props: {
+              url: "sys/dict/getList?code=000120001&key=temp",
+              formatRemoteData: (v: any) => {
+                return v?.list
+              },
+            },
+            span: 12,
+          },
+          {
+            label: "维护周期",
+            field: "date",
+            required: true,
+            component: ElDatePicker,
+            props: {
+              type: "datetimerange",
+              startPlaceholder: "开始时间",
+              endPlaceholder: "结束时间",
+              rangeSeparator: "~",
+              format: "YYYY-MM-DD HH:mm",
+              disabledDate: (v: any) => {
+                if (v <= moment().add(7, "day")) {
+                  if (v >= moment().startOf("day")) {
+                    return false
+                  }
+                }
+                return true
+              },
+            },
+            span: 24,
+          },
+          {
+            label: "申报备注",
+            field: "description",
+            placeholder: "请输入申报备注",
+            component: ElInput,
+            type: "textarea",
+            span: 24,
+          },
+        ]
+      : operationType.value == "D"
+      ? []
+      : []
+  ) as Array<VbFormItem>
+})
+const formData = ref<any>({})
+const emptyDate = {
+  device_id: "",
+  description: "",
+  maintain_type: "",
+}
+function add() {
+  operationType.value = "C"
+  formData.value = Object.assign({}, emptyDate)
+  formData.value.date = ""
+  modal.value.show()
+}
+const details = ref<any>({})
+function detail(row: any) {
+  operationType.value = "D"
+  details.value = {
+    device_name: row.device_name,
+    description: row.description,
+    maintain_times: row.maintain_times.substring(0, 19),
+    maintain_times_end: row.maintain_times.substring(20, 39),
+    maintain_type_name: row.maintain_type_name,
+  }
+  modal.value.show()
+}
+function onSave() {
+  if (operationType.value == "D") {
+    return
+  }
+  const data = {
+    device_id: formData.value.device_id,
+    declare_type: "1",
+    description: formData.value.description,
+    maintain_type: formData.value.maintain_type,
+    begin_date: moment(formData.value.date[0]).format("YYYYMMDDHHmmss"),
+    end_date: moment(formData.value.date[1]).format("YYYYMMDDHHmmss"),
+  }
+  Rs.post("sys/companyDeclare/newDeclare", { data }).then(() => {
+    table.value.search()
+  })
+}
+</script>
+
+<template>
+  <VbDataTable
+    ref="table"
+    :header="cols"
+    url="sys/companyDeclare/getCompanyMaintainList"
+    method="post"
+    :query-params="queryParams"
+    :has-checkbox="false"
+  >
+    <template v-slot:table-tool="">
+      <el-form class="align-items-center" :inline="true">
+        <el-form-item class="mb-0 me-5 align-items-center">
+          <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="add">新建申报</el-button>
+        </el-form-item>
+        <el-form-item class="mb-0 me-5 align-items-center" label="审批状态">
+          <el-select v-model="auditState" :style="dySearchSelectStyle" :size="size" placeholder="请选择审批状态">
+            <el-option v-for="(v, i) in auditStateSelectList" :key="i" :label="v.label" :value="v.value"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center" label="日期">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="~"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            size="default"
+          />
+        </el-form-item>
+        <el-form-item class="mb-0 me-0 align-items-center">
+          <el-button class="ms-3 mt-0 btn btn-sm btn-primary" @click="query">查询</el-button>
+          <el-button class="ms-3 mt-0 btn btn-sm btn-light-primary btn-outline" @click="reset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </template>
+
+    <template #abnormal_date="{ row }">
+      {{ moment(row.abnormal_date, "YYYYMMDDHHmmss").format("YYYY-MM-DD") }}
+    </template>
+    <template #audit_state_name="{ row }">
+      <span
+        class="badge"
+        :class="`badge-${row.audit_state == 0 ? 'primary' : row.audit_state == 1 ? 'success' : 'danger'}`"
+      >
+        {{ row["audit_state_name"] }}
+      </span>
+    </template>
+
+    <template #action="{ row }">
+      <span class="table-action" @click="detail(row)">申报详情</span>
+    </template>
+  </VbDataTable>
+  <VbModal
+    v-model:modal="modal"
+    v-model:form-data="formData"
+    :form-items="formItems"
+    :title="modalTitle"
+    :confirm-btn="operationType == 'C'"
+    :close-btn-class="`btn btn-${operationType == 'C' ? 'light' : 'primary'}`"
+    @confirm="onSave"
+  >
+    <template v-if="operationType == 'D'" #body>
+      <el-row>
+        <el-col :span="12">
+          <dl>
+            <dt>维护设备:</dt>
+            <dd>{{ details.device_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>维护类型:</dt>
+            <dd>{{ details.maintain_type_name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>开始时间:</dt>
+            <dd>{{ details.maintain_times }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="12">
+          <dl>
+            <dt>结束时间:</dt>
+            <dd>{{ details.maintain_times_end }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>申报备注:</dt>
+            <dd>{{ details.description }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+    </template>
+  </VbModal>
+</template>