Yue 2 lat temu
rodzic
commit
6cb7622124

+ 2 - 2
src/components/Modals/VbModal.vue

@@ -82,7 +82,7 @@ const props = withDefaults(
     confirmBtnText: "确认",
     confirmBtnClass: "btn btn-primary",
     confirmBtnStyle: "",
-    modalClass: "",
+    modalClass: "modal-lg ",
     modalDialogClass: "modal-dialog-centered",
     modalContentClass: "",
     modalHeaderClass: "",
@@ -210,7 +210,7 @@ onMounted(() => {
 defineExpose({ show })
 </script>
 <template>
-  <div ref="modalEl" class="modal modal-lg fade" :class="modalClass" :style="modalStyle" tabindex="-1" :id="id">
+  <div ref="modalEl" class="modal fade" :class="modalClass" :style="modalStyle" tabindex="-1" :id="id">
     <div class="modal-dialog" :class="modalDialogClass" :style="modalDialogStyle">
       <div class="modal-content" :class="modalContentClass" :style="modalContentStyle">
         <div class="modal-header py-3" :class="modalHeaderClass" :style="modalHeaderStyle">

+ 24 - 0
src/router/statictRouter.ts

@@ -126,6 +126,30 @@ export const staticRotuer: Array<RouteRecordRaw> = [
           breadcrumbs: ["异常申报", "异常列表", "清洗逾期告警详情"],
         },
       },
+      {
+        path: "/warnList/strongWarn",
+        component: () => import("@/views/warn/abnormalList/strongWarn.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["告警管理", "告警列表", "超标告警详情"],
+        },
+      },
+      {
+        path: "/warnList/disConnect",
+        component: () => import("@/views/warn/abnormalList/disConnect.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["告警管理", "告警列表", "设备离线告警详情"],
+        },
+      },
+      {
+        path: "/warnList/overdueWarn",
+        component: () => import("@/views/warn/abnormalList/overdueWarn.vue"),
+        meta: {
+          pageTitle: "超标告警详情",
+          breadcrumbs: ["告警管理", "告警列表", "清洗逾期告警详情"],
+        },
+      },
     ],
   },
 ]

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

@@ -38,7 +38,7 @@ const cols = ref([
   {
     name: "操作",
     field: "action",
-    width: 100,
+    width: 160,
   },
 ])
 const size = ref<any>("default")
@@ -180,7 +180,7 @@ function getDetail(row: any) {
     </template>
     <template #state="{ row }">
       <span class="badge" :class="`badge-${row.state == 0 ? 'primary' : row.state == 1 ? 'success' : 'danger'}`">
-        {{ row["state"] }}
+        {{ row["state"] == 0 ? "未回复" : "已回复" }}
       </span>
     </template>
     <template #notice_time="{ row }">

+ 266 - 2
src/views/warn/ouput.vue

@@ -1,7 +1,271 @@
 <script setup lang="ts">
-import { defineProps, reactive, ref, toRefs } from "vue"
+import { getAssetPath } from "@/core/helpers/assets"
+import RequestService from "@/core/services/RequestService"
+import moment from "moment"
+import { ref, computed, onMounted } from "vue"
+const cols = ref([
+  {
+    name: "区域",
+    field: "org_name",
+  },
+  {
+    name: "公司名称",
+    field: "name",
+  },
+  {
+    name: "排放超标次数",
+    field: "exceed_total",
+  },
+  {
+    name: "操作",
+    width: 150,
+    field: "action",
+  },
+])
+
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "180px" }
+
+const levelType = ref(0)
+const curDate = ref(new Date())
+const jidu = ref(1)
+const dateType = computed(() => {
+  return levelType.value == 0
+    ? "date"
+    : levelType.value == 1
+    ? "month"
+    : levelType.value == 2 || levelType.value == 3
+    ? "year"
+    : "date"
+})
+const dateLabel = computed(() => {
+  return levelType.value == 0
+    ? "日期"
+    : levelType.value == 1
+    ? "月份"
+    : levelType.value == 2 || levelType.value == 3
+    ? "年份"
+    : "日期"
+})
+const queryParams = ref({
+  type: 0,
+  date: moment(curDate.value).format("YYYYMMDD"),
+})
+const tableData = ref<any>({ red: [], black: [] })
+const redData = computed(() => {
+  return tableData.value.red
+})
+const blackData = computed(() => {
+  return tableData.value.black
+})
+const isLoading = ref(false)
+function loadTable() {
+  isLoading.value = true
+  RequestService.post("sys/companyRedBlack/query", { data: queryParams.value, successAlert: false })
+    .then((res) => {
+      isLoading.value = false
+      tableData.value = res.data
+    })
+    .catch(() => {
+      isLoading.value = false
+    })
+}
+function query() {
+  let date = ""
+  if (levelType.value == 0) {
+    date = moment(curDate.value).format("YYYYMMDD")
+  }
+  if (levelType.value == 1) {
+    date = moment(curDate.value).format("YYYYMM")
+  }
+  if (levelType.value == 2) {
+    date = moment(curDate.value).format("YYYY") + "0" + jidu.value
+  }
+  if (levelType.value == 3) {
+    date = moment(curDate.value).format("YYYY")
+  }
+  queryParams.value = {
+    type: levelType.value,
+    date: date,
+  }
+  loadTable()
+}
+function reset() {
+  jidu.value = 1
+  levelType.value = 0
+  curDate.value = new Date()
+  query()
+}
+function exported() {
+  let str = "/api/sys/companyRedBlack/export"
+  let date = ""
+  if (levelType.value == 0) {
+    date = moment(curDate.value).format("YYYYMMDD")
+  }
+  if (levelType.value == 1) {
+    date = moment(curDate.value).format("YYYYMM")
+  }
+  if (levelType.value == 2) {
+    date = moment(curDate.value).format("YYYY") + "0" + jidu.value
+  }
+  if (levelType.value == 3) {
+    date = moment(curDate.value).format("YYYY")
+  }
+  str += "?date=" + date + "&type=" + levelType.value
+  window.open(str)
+}
+const modal = ref()
+const details = ref<any>({})
+function detail(row: any) {
+  details.value = Object.assign({}, row)
+  if (details.value.warn_starttime) {
+    details.value.warn_starttime = moment(details.value.warn_starttime, "YYYYMMDD").format("YYYY-MM-DD")
+  }
+  modal.value.show()
+}
+onMounted(loadTable)
 </script>
 
 <template>
-  <div>ouput</div>
+  <!--begin::Alert-->
+  <div class="alert alert-dismissible bg-primary d-flex flex-sm-row p-5 mb-10">
+    <div class="d-flex align-items-center text-light pe-0 pe-sm-10">
+      <span class="svg-icon svg-icon-3hx svg-icon-light me-6">
+        <inline-svg :src="getAssetPath('media/icons/duotune/abstract/abs026.svg')" />
+      </span>
+      <h4 class="light text-light mb-0 fs-2hx ls-2" style="font-family: 'fangsong'">餐饮红黑榜</h4>
+    </div>
+  </div>
+  <div class="tool">
+    <el-form class="align-items-center mb-5" :inline="true">
+      <el-form-item class="mb-0 me-5 align-items-center" label="周期">
+        <el-select v-model="levelType" :style="dySearchSelectStyle" placeholder="请选择周期">
+          <el-option label="日" :value="0"></el-option>
+          <el-option label="月" :value="1"></el-option>
+          <el-option label="季度" :value="2"></el-option>
+          <el-option label="年" :value="3"></el-option>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item class="mb-0 me-5 align-items-center" :label="dateLabel">
+        <el-date-picker
+          v-model="curDate"
+          :type="dateType"
+          range-separator="~"
+          placeholder="请选择日期"
+          :size="size"
+          style="width: 230px"
+          :clearable="false"
+        />
+      </el-form-item>
+      <el-form-item v-if="levelType == 2" class="mb-0 me-5 align-items-center" label="季度">
+        <el-select v-model="jidu" :style="dySearchSelectStyle" placeholder="请选择季度">
+          <el-option label="第一季度" :value="1"></el-option>
+          <el-option label="第二季度" :value="2"></el-option>
+          <el-option label="第三季度" :value="3"></el-option>
+          <el-option label="第四季度" :value="4"></el-option>
+        </el-select>
+      </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-button class="ms-3 mt-0 btn btn-sm btn-light-info btn-outline" @click="exported">导出</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+  <el-row :gutter="30">
+    <el-col :span="12">
+      <div class="card">
+        <div class="card-header">
+          <div class="card-title">
+            <h1 class="text-primary">红榜名单</h1>
+          </div>
+        </div>
+        <div class="card-body p-5">
+          <VbDataTable :data="redData" :header="cols" :loading="isLoading" :has-checkbox="false" :no-page="true">
+            <template #action="{ row }">
+              <div class="text-danger text-center">
+                <span class="table-action" @click="detail(row)">查看详情</span>
+              </div>
+            </template>
+          </VbDataTable>
+        </div>
+      </div>
+    </el-col>
+    <el-col :span="12">
+      <div class="card">
+        <div class="card-header">
+          <div class="card-title">
+            <h1 class="text-primary">黑榜名单</h1>
+          </div>
+        </div>
+        <div class="card-body p-5">
+          <VbDataTable :data="blackData" :header="cols" :loading="isLoading" :has-checkbox="false" :no-page="true">
+            <template #action="{ row }">
+              <div class="text-danger text-center">
+                <span class="table-action" @click="detail(row)">查看详情</span>
+              </div>
+            </template>
+          </VbDataTable>
+        </div>
+      </div>
+    </el-col>
+  </el-row>
+
+  <VbModal
+    v-model:modal="modal"
+    modal-class="modal-md"
+    title="详情"
+    :confirm-btn="false"
+    :close-btn-class="`btn btn-primary`"
+  >
+    <template #body>
+      <el-row>
+        <el-col :span="24">
+          <dl>
+            <dt>企业名称:</dt>
+            <dd>{{ details.name }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>油烟排放均值:</dt>
+            <dd>{{ details.smoke_density }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>颗粒物排放均值:</dt>
+            <dd>{{ details.pm25 }}</dd>
+          </dl>
+        </el-col>
+        <el-col :span="24">
+          <dl>
+            <dt>非甲烷排放均值:</dt>
+            <dd>{{ details.voc_density }}</dd>
+          </dl>
+        </el-col>
+      </el-row>
+    </template>
+  </VbModal>
 </template>
+<style lang="scss" scoped>
+.card-title {
+  h1 {
+    position: relative;
+    padding-left: 18px;
+    &:before {
+      content: "";
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
+      display: block;
+      width: 5px;
+      height: 30px;
+      background-color: var(--bs-primary);
+      border-radius: 5px;
+    }
+  }
+}
+</style>

+ 323 - 4
src/views/warn/warnList.vue

@@ -1,9 +1,328 @@
 <script setup lang="ts">
-import { defineProps, reactive, ref, toRefs } from "vue"
-import apis from "@/api/index"
-const company = ref<any>({})
+import { computed, ref } from "vue"
+import configs from "@/core/config/Index"
+import moment from "moment"
+import router from "@/router"
+import { ElInput } from "element-plus"
+import type { VbFormItem } from "@/components/Forms/models"
+import Rs from "@/core/services/RequestService"
+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: "warn_type_name",
+  },
+  {
+    name: "告警时间",
+    field: "warn_starttime",
+  },
+  // {
+  //   name: "处理时间",
+  //   field: "abnormal_date",
+  // },
+  {
+    name: "处理结果",
+    field: "abnormal_state_name",
+  },
+  {
+    name: "操作",
+    width: 210,
+    field: "action",
+  },
+])
+const jump = function (v: any) {
+  console.log("jump", v)
+  router.push({
+    path: "/goLineData/oilFumeConcentration",
+    query: {
+      back: 1,
+      comName: v.company_name,
+      company_id: v.company_id,
+    },
+  })
+}
+const size = ref<any>("default")
+const dySearchSelectStyle = { width: "180px" }
+const companyName = ref("")
+const orgId = ref<string | null>(null)
+const warnType = ref("")
+const abnormalState = ref("")
+const monitoringType = ref("")
+const dateRange = ref<[Date, Date]>([moment(new Date()).add(-7, "d").toDate(), new Date()])
+const queryParams = ref<any>({
+  query_start_time: moment(dateRange.value[0]).format("YYYYMMDD"),
+  query_end_time: moment(dateRange.value[1]).format("YYYYMMDD"),
+})
+function query() {
+  const params = {
+    query_start_time: moment(dateRange.value[0]).format("YYYYMMDD"),
+    query_end_time: moment(dateRange.value[1]).format("YYYYMMDD"),
+    warn_type: warnType.value,
+    abnormal_state: abnormalState.value,
+    monitoring_type: monitoringType.value,
+    company_name: companyName.value,
+    org_id: orgId.value,
+  }
+  const keys = Object.keys(params)
+  keys.forEach((key) => {
+    if (params[key] == "") {
+      delete params[key]
+    }
+  })
+  queryParams.value = params
+}
+function reset() {
+  companyName.value = ""
+  orgId.value = ""
+  warnType.value = ""
+  abnormalState.value = ""
+  monitoringType.value = ""
+  dateRange.value = [moment(new Date()).add(-7, "d").toDate(), new Date()]
+  query()
+}
+const modal = ref()
+const operationType = ref<"D" | "N">("D")
+const modalTitle = computed(() => {
+  return operationType.value == "D" ? "告警详情" : operationType.value == "N" ? "下发通知" : ""
+})
+const formData = ref<any>({})
+const formItems = computed(() => {
+  return (
+    operationType.value == "N"
+      ? [
+          {
+            label: "企业名称:",
+            field: "company_name",
+            component: "innerText",
+            span: 12,
+          },
+          {
+            label: "异常类型:",
+            field: "warn_type_name",
+            component: "innerText",
+            span: 12,
+          },
+          {
+            label: "告警设备:",
+            field: "device_name",
+            component: "innerText",
+            span: 12,
+          },
+          {
+            label: "告警时间:",
+            field: "warn_starttime",
+            component: "innerText",
+            span: 12,
+          },
+          {
+            label: "通知内容:",
+            field: "content",
+            placeholder: "请输入通知内容",
+            required: true,
+            component: ElInput,
+            type: "textarea",
+            span: 24,
+          },
+          {
+            label: "通知部门:",
+            field: "notice_org",
+            component: "innerText",
+            span: 12,
+          },
+          {
+            label: "通知人:",
+            field: "notifier",
+            placeholder: "请输入通知人",
+            required: true,
+            component: ElInput,
+            span: 24,
+          },
+        ]
+      : operationType.value == "D"
+      ? []
+      : []
+  ) as Array<VbFormItem>
+})
+const details = ref<any>({})
+function detail(row: any) {
+  operationType.value = "D"
+  if (row.warn_type == "000100003" || row.warn_type == "000100005" || row.warn_type == "000100007") {
+    router.push({
+      path: "/warnList/strongWarn",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  } else if (row.warn_type == "000100006") {
+    router.push({
+      path: "/warnList/disConnect",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  } else {
+    router.push({
+      path: "/warnList/overdueWarn",
+      query: { back: 1, id: row.id, type: row.warn_type },
+    })
+  }
+}
+
+function notity(row: any) {
+  formData.value = Object.assign({}, row)
+  formData.value.content = ""
+  formData.value.notifier = ""
+  if (formData.value.warn_starttime) {
+    formData.value.warn_starttime = moment(formData.value.warn_starttime, "YYYYMMDD").format("YYYY-MM-DD")
+  }
+  operationType.value = "N"
+  modal.value.show()
+}
+
+function onSave() {
+  if (operationType.value == "D") {
+    return
+  }
+  const data = {
+    name: formData.value.warn_type,
+    company_id: formData.value.company_id,
+    type: 0,
+    warn_id: formData.value.id,
+    content: formData.value.content,
+    notifier: formData.value.notifier,
+  }
+  Rs.post("sys/notice/sendNotice", { data }).then(() => {
+    table.value.search()
+  })
+}
 </script>
 
 <template>
-  <div>warnList -- {{ company.name }}</div>
+  <VbDataTable
+    ref="table"
+    :header="cols"
+    url="sys/warn/getWarnForPage"
+    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="dySearchSelectStyle"
+            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="dySearchSelectStyle"></OrgSelectTree>
+        </el-form-item>
+
+        <el-form-item class="mb-0 me-5 align-items-center" label="告警类型">
+          <DySelect
+            v-model="warnType"
+            :formatRemoteData="(v:any)=>{return v?.list}"
+            :url="'sys/dict/getList?code=000100001&key=temp'"
+            :style="dySearchSelectStyle"
+            placeholder="请选择告警类型"
+          ></DySelect>
+        </el-form-item>
+        <!-- <el-form-item class="mb-0 me-5 align-items-center" label="处理结果">
+          <DySelect
+            v-model="abnormalState"
+            :formatRemoteData="(v:any)=>{return v?.list}"
+            :url="'sys/dict/getList?code=000170000&key=temp'"
+            :style="dySearchSelectStyle"
+            placeholder="请选择处理结果"
+          ></DySelect>
+        </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-5 align-items-center" label="日期">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="~"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            :size="size"
+            style="width: 230px"
+          />
+        </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 #warn_starttime="{ row }">
+      {{ moment(row["warn_starttime"], "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") }}
+    </template>
+    <template #abnormal_date="{ row }">
+      {{ row["abnormal_date"] ? moment(row["abnormal_date"], "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : "" }}
+    </template>
+    <template #action="{ row }">
+      <div class="text-danger text-center">
+        <span class="table-action" @click="detail(row)">查看详情</span>
+        <span class="table-action" @click="notity(row)">下发通知</span>
+      </div>
+    </template>
+  </VbDataTable>
+  <VbModal
+    v-model:modal="modal"
+    v-model:form-data="formData"
+    :form-items="formItems"
+    :title="modalTitle"
+    :confirm-btn="operationType == 'N'"
+    :close-btn-class="`btn btn-${operationType == 'N' ? 'light' : 'primary'}`"
+    @confirm="onSave"
+  >
+    <template #body>
+      <el-row v-if="operationType == 'D'">
+        <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>
+    </template>
+  </VbModal>
 </template>