From bbaece97903edc584e917ec3d76183e7e5c69e16 Mon Sep 17 00:00:00 2001
From: 龚焕茏 <2842157468@qq.com>
Date: 星期五, 01 三月 2024 11:54:30 +0800
Subject: [PATCH] 安全隐患基础功能

---
 vite.config.ts                  |    4 
 src/api/dg/dangerInfo/index.ts  |   76 ++++
 src/api/dg/dangerTotal/index.ts |   63 +++
 src/api/dg/dangerInfo/types.ts  |  116 ++++++
 src/api/dg/dangerTotal/types.ts |  131 +++++++
 src/views/dg/danger/total.vue   |  311 +++++++++++++++++
 src/views/dg/danger/index.vue   |  351 +++++++++++++++++++
 7 files changed, 1,050 insertions(+), 2 deletions(-)

diff --git a/src/api/dg/dangerInfo/index.ts b/src/api/dg/dangerInfo/index.ts
new file mode 100644
index 0000000..6196d28
--- /dev/null
+++ b/src/api/dg/dangerInfo/index.ts
@@ -0,0 +1,76 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { DangerInfoVO, DangerInfoForm, DangerInfoQuery } from '@/api/dg/dangerInfo/types';
+
+/**
+ * 鏌ヨ瀹夊叏闅愭偅淇℃伅鍒楄〃
+ * @param query
+ * @returns {*}
+ */
+
+export const listDangerInfo = (query?: DangerInfoQuery): AxiosPromise<DangerInfoVO[]> => {
+  return request({
+    url: '/demo/dangerInfo/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 鏌ヨ瀹夊叏闅愭偅绫诲瀷鏉′欢
+ * @param query
+ * @returns {*}
+ */
+
+// export const dangerTypes = (): AxiosPromise<String[]> => {
+//   return request({
+//     url: '/demo/dangerInfo/getDangerType',
+//     method: 'get'
+//   });
+// };
+
+/**
+ * 鏌ヨ瀹夊叏闅愭偅淇℃伅璇︾粏
+ * @param id
+ */
+export const getDangerInfo = (id: string | number): AxiosPromise<DangerInfoVO> => {
+  return request({
+    url: '/demo/dangerInfo/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 鏂板瀹夊叏闅愭偅淇℃伅
+ * @param data
+ */
+export const addDangerInfo = (data: DangerInfoForm) => {
+  return request({
+    url: '/demo/dangerInfo',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 淇敼瀹夊叏闅愭偅淇℃伅
+ * @param data
+ */
+export const updateDangerInfo = (data: DangerInfoForm) => {
+  return request({
+    url: '/demo/dangerInfo',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 鍒犻櫎瀹夊叏闅愭偅淇℃伅
+ * @param id
+ */
+export const delDangerInfo = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/demo/dangerInfo/' + id,
+    method: 'delete'
+  });
+};
diff --git a/src/api/dg/dangerInfo/types.ts b/src/api/dg/dangerInfo/types.ts
new file mode 100644
index 0000000..784e9a6
--- /dev/null
+++ b/src/api/dg/dangerInfo/types.ts
@@ -0,0 +1,116 @@
+export interface DangerInfoVO {
+  /**
+   * 缂栧彿
+   */
+  id: string | number;
+
+  /**
+   * 閫氭姤鏃堕棿
+   */
+  notificationTime: string;
+
+  /**
+   * 闅愭偅绫诲瀷
+   */
+  dangerType: string;
+
+  /**
+   * 璐d换鍗曚綅
+   */
+  accountabilityUnit: string;
+
+  /**
+   * 鏁存敼鏃堕檺
+   */
+  rectificationTimeLimit: string;
+
+  /**
+   * 瀹屾垚鎯呭喌
+   */
+  performance: string;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status: number;
+
+}
+
+export interface DangerInfoForm extends BaseEntity {
+  /**
+   * 缂栧彿
+   */
+  id?: string | number;
+
+  /**
+   * 閫氭姤鏃堕棿
+   */
+  notificationTime?: string;
+
+  /**
+   * 闅愭偅绫诲瀷
+   */
+  dangerType?: string;
+
+  /**
+   * 璐d换鍗曚綅
+   */
+  accountabilityUnit?: string;
+
+  /**
+   * 鏁存敼鏃堕檺
+   */
+  rectificationTimeLimit?: string;
+
+  /**
+   * 瀹屾垚鎯呭喌
+   */
+  performance?: string;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status?: number;
+
+}
+
+export interface DangerInfoQuery extends PageQuery {
+
+  /**
+   * 閫氭姤鏃堕棿
+   */
+  notificationTime?: string;
+
+  /**
+   * 闅愭偅绫诲瀷
+   */
+  dangerType?: string;
+
+  /**
+   * 璐d换鍗曚綅
+   */
+  accountabilityUnit?: string;
+
+  /**
+   * 鏁存敼鏃堕檺
+   */
+  rectificationTimeLimit?: string;
+
+  /**
+   * 瀹屾垚鎯呭喌
+   */
+  performance?: string;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status?: number;
+
+    /**
+     * 鏃ユ湡鑼冨洿鍙傛暟
+     */
+    params?: any;
+}
+
+
+
diff --git a/src/api/dg/dangerTotal/index.ts b/src/api/dg/dangerTotal/index.ts
new file mode 100644
index 0000000..bdd703c
--- /dev/null
+++ b/src/api/dg/dangerTotal/index.ts
@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { DangerTotalVO, DangerTotalForm, DangerTotalQuery } from '@/api/demo/dangerTotal/types';
+
+/**
+ * 鏌ヨ瀹夊叏闅愭偅缁熻鍒楄〃
+ * @param query
+ * @returns {*}
+ */
+
+export const listDangerTotal = (query?: DangerTotalQuery): AxiosPromise<DangerTotalVO[]> => {
+  return request({
+    url: '/demo/dangerTotal/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 鏌ヨ瀹夊叏闅愭偅缁熻璇︾粏
+ * @param id
+ */
+export const getDangerTotal = (id: string | number): AxiosPromise<DangerTotalVO> => {
+  return request({
+    url: '/demo/dangerTotal/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 鏂板瀹夊叏闅愭偅缁熻
+ * @param data
+ */
+export const addDangerTotal = (data: DangerTotalForm) => {
+  return request({
+    url: '/demo/dangerTotal',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 淇敼瀹夊叏闅愭偅缁熻
+ * @param data
+ */
+export const updateDangerTotal = (data: DangerTotalForm) => {
+  return request({
+    url: '/demo/dangerTotal',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 鍒犻櫎瀹夊叏闅愭偅缁熻
+ * @param id
+ */
+export const delDangerTotal = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/demo/dangerTotal/' + id,
+    method: 'delete'
+  });
+};
diff --git a/src/api/dg/dangerTotal/types.ts b/src/api/dg/dangerTotal/types.ts
new file mode 100644
index 0000000..d02bf9d
--- /dev/null
+++ b/src/api/dg/dangerTotal/types.ts
@@ -0,0 +1,131 @@
+export interface DangerTotalVO {
+  /**
+   * 缂栧彿
+   */
+  id: string | number;
+
+  /**
+   * 闀囪鍚嶇О
+   */
+  townStreetName: string;
+
+  /**
+   * 骞村害/鏈堝害 1骞村害 2鏈堝害
+   */
+  period: number;
+
+  /**
+   * 鍛ㄦ湡
+   */
+  periodDate: string;
+
+  /**
+   * 鍙戠幇瀹夊叏闅愭偅
+   */
+  findSecurityRisks: number;
+
+  /**
+   * 涓嬪彂閫氱煡涔�
+   */
+  issueNotice: number;
+
+  /**
+   * 澶勭疆瀹夊叏闅愭偅
+   */
+  dealWithSecurityRisks: number;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status: number;
+
+}
+
+export interface DangerTotalForm extends BaseEntity {
+  /**
+   * 缂栧彿
+   */
+  id?: string | number;
+
+  /**
+   * 闀囪鍚嶇О
+   */
+  townStreetName?: string;
+
+  /**
+   * 骞村害/鏈堝害 1骞村害 2鏈堝害
+   */
+  period?: number;
+
+  /**
+   * 鍛ㄦ湡
+   */
+  periodDate?: string;
+
+  /**
+   * 鍙戠幇瀹夊叏闅愭偅
+   */
+  findSecurityRisks?: number;
+
+  /**
+   * 涓嬪彂閫氱煡涔�
+   */
+  issueNotice?: number;
+
+  /**
+   * 澶勭疆瀹夊叏闅愭偅
+   */
+  dealWithSecurityRisks?: number;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status?: number;
+
+}
+
+export interface DangerTotalQuery extends PageQuery {
+
+  /**
+   * 闀囪鍚嶇О
+   */
+  townStreetName?: string;
+
+  /**
+   * 骞村害/鏈堝害 1骞村害 2鏈堝害
+   */
+  period?: number;
+
+  /**
+   * 鍛ㄦ湡
+   */
+  periodDate?: string;
+
+  /**
+   * 鍙戠幇瀹夊叏闅愭偅
+   */
+  findSecurityRisks?: number;
+
+  /**
+   * 涓嬪彂閫氱煡涔�
+   */
+  issueNotice?: number;
+
+  /**
+   * 澶勭疆瀹夊叏闅愭偅
+   */
+  dealWithSecurityRisks?: number;
+
+  /**
+   * 鍚敤鐘舵�� 1鍚敤 2鏈惎鐢�
+   */
+  status?: number;
+
+    /**
+     * 鏃ユ湡鑼冨洿鍙傛暟
+     */
+    params?: any;
+}
+
+
+
diff --git a/src/views/dg/danger/index.vue b/src/views/dg/danger/index.vue
new file mode 100644
index 0000000..733b070
--- /dev/null
+++ b/src/views/dg/danger/index.vue
@@ -0,0 +1,351 @@
+<template>
+  <div class="p-2">
+    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+      <el-tab-pane label="瀹夊叏闅愭偅" name="first"></el-tab-pane>
+      <el-tab-pane label="闅愭偅缁熻" name="second"></el-tab-pane>
+    </el-tabs>
+    <div v-show="activeName=='first'">
+      <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="闅愭偅绫诲瀷" prop="notificationTime">
+            <el-select v-model="queryParams.dangerType" placeholder="璇烽�夋嫨" clearable style="width: 240px" @keyup.enter="handleQuery" >
+              <el-option v-for="item in dangerTypes" :key="item.dangerType" :label="item.dangerType" :value="item.dangerType"/>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="璐d换鍗曚綅" prop="accountabilityUnit">
+            <el-input v-model="queryParams.accountabilityUnit" placeholder="璇疯緭鍏ヨ矗浠诲崟浣�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨" clearable style="width: 240px" @keyup.enter="handleQuery" >
+              <el-option key="1" label="宸插惎鐢�" value="1" />
+              <el-option key="2" label="宸茬鐢�" value="2" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:dangerInfo:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:dangerInfo:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:dangerInfo:remove']">鍒犻櫎</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:dangerInfo:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="dangerInfoList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="搴忓彿" align="center" type="index" v-if="true" width="60" />
+        <el-table-column label="閫氭姤鏃堕棿" align="center" prop="notificationTime" />
+        <el-table-column label="闅愭偅绫诲瀷" align="center" prop="dangerType" />
+        <el-table-column label="璐d换鍗曚綅" align="center" prop="accountabilityUnit" />
+        <el-table-column label="鏁存敼鏃堕檺" align="center" prop="rectificationTimeLimit" />
+        <el-table-column label="瀹屾垚鎯呭喌" align="center" prop="performance" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <span v-show="scope.row['status'] == 1">宸插惎鐢�</span>
+            <span v-show="scope.row['status'] == 2" style="color: rgba(227, 70,101);">宸茬鐢�</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" />
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:dangerInfo:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:dangerInfo:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+          v-show="total>0"
+          :total="total"
+          v-model:page="queryParams.pageNum"
+          v-model:limit="queryParams.pageSize"
+          @pagination="getList"
+      />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰畨鍏ㄩ殣鎮d俊鎭璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="dangerInfoFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="閫氭姤鏃堕棿" prop="notificationTime">
+          <el-date-picker v-model="form.notificationTime" type="date" value-format="YYYY-MM-DD" placeholder="璇烽�夋嫨閫氭姤鏃堕棿" />
+        </el-form-item>
+        <el-form-item label="闅愭偅绫诲瀷" prop="dangerType">
+          <el-input v-model="form.dangerType" placeholder="璇疯緭鍏ラ殣鎮g被鍨�" />
+        </el-form-item>
+        <el-form-item label="璐d换鍗曚綅" prop="accountabilityUnit">
+          <el-input v-model="form.accountabilityUnit" placeholder="璇疯緭鍏ヨ矗浠诲崟浣�" />
+        </el-form-item>
+        <el-form-item label="鏁存敼鏃堕檺" prop="rectificationTimeLimit">
+          <el-date-picker v-model="form.rectificationTimeLimit" type="date" value-format="YYYY-MM-DD" placeholder="璇烽�夋嫨鏁存敼鏃堕檺" />
+        </el-form-item>
+        <el-form-item label="瀹屾垚鎯呭喌" prop="performance">
+          <el-input v-model="form.performance" placeholder="璇疯緭鍏ュ畬鎴愭儏鍐�" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-select v-model="form.status" placeholder="璇烽�夋嫨">
+            <el-option key="1" label="宸插惎鐢�" :value="1" />
+            <el-option key="2" label="宸茬鐢�" :value="2" />
+          </el-select>
+        </el-form-item>
+        <el-upload
+          label="涓婁紶鍥剧墖"
+          v-model:file-list="fileList"
+          action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
+          list-type="picture-card"
+          :on-preview="handlePictureCardPreview"
+          :on-remove="handleRemove"
+        >
+          <el-icon><Plus /></el-icon>
+        </el-upload>
+
+        <el-dialog v-model="dialogVisible">
+          <img w-full :src="dialogImageUrl" alt="Preview Image" />
+        </el-dialog>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    </div>
+    <div v-show="activeName=='second'">
+      2
+    </div>
+    
+  </div>
+</template>
+
+<script setup name="DangerInfo" lang="ts">
+import { listDangerInfo, getDangerInfo, delDangerInfo, addDangerInfo, updateDangerInfo } from '@/api/dg/dangerInfo';
+import { DangerInfoVO, DangerInfoQuery, DangerInfoForm } from '@/api/dg/dangerInfo/types';
+import type { TabsPaneContext, UploadProps, UploadUserFile } from "element-plus";
+const fileList = ref<UploadUserFile[]>([])
+
+const dialogImageUrl = ref('')
+const dialogVisible = ref(false)
+
+const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
+  console.log(uploadFile, uploadFiles)
+}
+
+const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
+  dialogImageUrl.value = uploadFile.url!
+  dialogVisible.value = true
+}
+const activeName = ref('first')
+const handleClick = (tab: TabsPaneContext) => {
+  tab.props.label
+}
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const activeIndex = ref('1')
+const activeIndex2 = ref('1')
+const handleSelect = (key: string, keyPath: string[]) => {
+  console.log(key, keyPath)
+}
+
+const dangerInfoList = ref<DangerInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const dangerInfoFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const dangerTypes = [
+  {
+    dangerType: '閬撹矾闅愭偅'
+  }];
+
+const initFormData: DangerInfoForm = {
+  id: undefined,
+  notificationTime: undefined,
+  dangerType: undefined,
+  accountabilityUnit: undefined,
+  rectificationTimeLimit: undefined,
+  performance: undefined,
+  status: 1,
+}
+const data = reactive<PageData<DangerInfoForm, DangerInfoQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    notificationTime: undefined,
+    dangerType: undefined,
+    accountabilityUnit: undefined,
+    rectificationTimeLimit: undefined,
+    performance: undefined,
+    status: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "缂栧彿涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    notificationTime: [
+      { required: true, message: "閫氭姤鏃堕棿涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    dangerType: [
+      { required: true, message: "闅愭偅绫诲瀷涓嶈兘涓虹┖", trigger: "change" }
+    ],
+    accountabilityUnit: [
+      { required: true, message: "璐d换鍗曚綅涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    rectificationTimeLimit: [
+      { required: true, message: "鏁存敼鏃堕檺涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    performance: [
+      { required: true, message: "瀹屾垚鎯呭喌涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    status: [
+      { required: true, message: "鍚敤鐘舵�� 1鍚敤 2鏈惎鐢ㄤ笉鑳戒负绌�", trigger: "change" }
+    ],
+    periodName: [
+      { required: true, message: "鍛ㄦ湡涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    periodYear: [
+      { required: true, message: "鍛ㄦ湡骞翠笉鑳戒负绌�", trigger: "blur" }
+    ],
+    periodMonth: [
+      { required: true, message: "鍛ㄦ湡鏈堜笉鑳戒负绌�", trigger: "blur" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 鏌ヨ瀹夊叏闅愭偅淇℃伅鍒楄〃 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listDangerInfo(queryParams.value);
+  dangerInfoList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 鏌ヨ瀹夊叏闅愭偅绫诲瀷鏌ヨ鏉′欢 */
+const getDangerTypes = async () => {
+  // dangerTypes.value = await getDangerTypes();
+}
+
+/** 鍙栨秷鎸夐挳 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 琛ㄥ崟閲嶇疆 */
+const reset = () => {
+  form.value = {...initFormData};
+  dangerInfoFormRef.value?.resetFields();
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 澶氶�夋閫変腑鏁版嵁 */
+const handleSelectionChange = (selection: DangerInfoVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "娣诲姞瀹夊叏闅愭偅淇℃伅";
+}
+
+/** 淇敼鎸夐挳鎿嶄綔 */
+const handleUpdate = async (row?: DangerInfoVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getDangerInfo(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "淇敼瀹夊叏闅愭偅淇℃伅";
+}
+
+/** 鎻愪氦鎸夐挳 */
+const submitForm = () => {
+  dangerInfoFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateDangerInfo(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addDangerInfo(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("淇敼鎴愬姛");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+const handleDelete = async (row?: DangerInfoVO) => {
+  if(row?.status == 1) { proxy?.$modal.msgWarning("褰撳墠涓哄凡鍚敤鐘舵�侊紝涓嶆敮鎸佸垹闄�"); return; }
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀹夊叏闅愭偅淇℃伅缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�').finally(() => loading.value = false);
+  await delDangerInfo(_ids);
+  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+  await getList();
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+const handleExport = () => {
+  proxy?.download('demo/dangerInfo/export', {
+    ...queryParams.value
+  }, `dangerInfo_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+  getDangerTypes();
+});
+</script>
diff --git a/src/views/dg/danger/total.vue b/src/views/dg/danger/total.vue
new file mode 100644
index 0000000..9b260f7
--- /dev/null
+++ b/src/views/dg/danger/total.vue
@@ -0,0 +1,311 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="闀囪鍚嶇О" prop="townStreetName">
+            <el-input v-model="queryParams.townStreetName" placeholder="璇疯緭鍏ラ晣琛楀悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="缁熻鍛ㄦ湡" prop="periodDate">
+            <el-input v-model="queryParams.periodDate" placeholder="璇疯緭鍏ョ粺璁″懆鏈�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨" clearable style="width: 240px" @keyup.enter="handleQuery" >
+              <el-option key="1" label="宸插惎鐢�" value="1" />
+              <el-option key="2" label="宸茬鐢�" value="2" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:dangerTotal:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:dangerTotal:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:dangerTotal:remove']">鍒犻櫎</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:dangerTotal:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="dangerTotalList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="搴忓彿" align="center" type="index" v-if="true" width="60" />
+        <el-table-column label="闀囪鍚嶇О" align="center" prop="townStreetName" />
+        <el-table-column label="缁熻鍛ㄦ湡" align="center" prop="periodDate" />
+        <el-table-column label="鍙戠幇瀹夊叏闅愭偅" align="center" prop="findSecurityRisks" />
+        <el-table-column label="涓嬪彂閫氱煡涔�" align="center" prop="issueNotice" />
+        <el-table-column label="澶勭疆瀹夊叏闅愭偅" align="center" prop="dealWithSecurityRisks" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <span v-show="scope.row['status'] == 1">宸插惎鐢�</span>
+            <span v-show="scope.row['status'] == 2" style="color: rgba(227, 70,101);">宸茬鐢�</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" />
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:dangerTotal:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:dangerTotal:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+          v-show="total>0"
+          :total="total"
+          v-model:page="queryParams.pageNum"
+          v-model:limit="queryParams.pageSize"
+          @pagination="getList"
+      />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰畨鍏ㄩ殣鎮g粺璁″璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="dangerTotalFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="闀囪鍚嶇О" prop="townStreetName" label-width="100">
+          <!-- <el-input v-model="form.townStreetName" placeholder="璇疯緭鍏ラ晣琛楀悕绉�" /> -->
+          <el-select v-model="form.townStreetName" placeholder="璇烽�夋嫨" clearable style="width: 240px" @keyup.enter="handleQuery" >
+              <el-option v-for="item in townStreetNames" :key="item.townStreetName" :label="item.townStreetName" :value="item.townStreetName"/>
+            </el-select>
+        </el-form-item>
+        <el-form-item label="缁熻鍛ㄦ湡" prop="periodDate" label-width="100">
+          <el-select v-model="form.period" placeholder="璇烽�夋嫨" style="width: 100px;">
+            <el-option key="1" label="骞村害" :value="1" />
+            <el-option key="2" label="鏈堝害" :value="2" />
+          </el-select>
+          &nbsp;
+          <el-date-picker v-model="form.periodDate" :type="pickerType" :value-format="pickerFormat" placeholder="璇烽�夋嫨缁熻鍛ㄦ湡" />
+        </el-form-item>
+        <el-form-item label="鍙戠幇闅愭偅" prop="findSecurityRisks" label-width="100">
+          <el-input v-model="form.findSecurityRisks" placeholder="璇疯緭鍏ュ彂鐜板畨鍏ㄩ殣鎮�" />
+        </el-form-item>
+        <el-form-item label="涓嬪彂閫氱煡涔�" prop="issueNotice" label-width="100">
+          <el-input v-model="form.issueNotice" placeholder="璇疯緭鍏ヤ笅鍙戦�氱煡涔�" />
+        </el-form-item>
+        <el-form-item label="澶勭疆闅愭偅" prop="dealWithSecurityRisks" label-width="100">
+          <el-input v-model="form.dealWithSecurityRisks" placeholder="璇疯緭鍏ュ缃畨鍏ㄩ殣鎮�" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status" label-width="100">
+          <el-select v-model="form.status" placeholder="璇烽�夋嫨">
+            <el-option key="1" label="宸插惎鐢�" :value="1" />
+            <el-option key="2" label="宸茬鐢�" :value="2" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="DangerTotal" lang="ts">
+import { listDangerTotal, getDangerTotal, delDangerTotal, addDangerTotal, updateDangerTotal } from '@/api/dg/dangerTotal';
+import { DangerTotalVO, DangerTotalQuery, DangerTotalForm } from '@/api/dg/dangerTotal/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const dangerTotalList = ref<DangerTotalVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const dangerTotalFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const townStreetNames = [
+  {
+    townStreetName: '骞哥琛楅亾',
+  },
+  {
+    townStreetName: '閾舵潖琛楅亾'
+  }];
+
+const initFormData: DangerTotalForm = {
+  id: undefined,
+  townStreetName: undefined,
+  period: 1,
+  periodDate: undefined,
+  findSecurityRisks: undefined,
+  issueNotice: undefined,
+  dealWithSecurityRisks: undefined,
+  status: undefined
+}
+const data = reactive<PageData<DangerTotalForm, DangerTotalQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    townStreetName: undefined,
+    period: undefined,
+    periodDate: undefined,
+    findSecurityRisks: undefined,
+    issueNotice: undefined,
+    dealWithSecurityRisks: undefined,
+    status: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "缂栧彿涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    townStreetName: [
+      { required: true, message: "闀囪鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    period: [
+      { required: true, message: "骞村害/鏈堝害 1骞村害 2鏈堝害涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    periodDate: [
+      { required: true, message: "鍛ㄦ湡涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    findSecurityRisks: [
+      { required: true, message: "鍙戠幇瀹夊叏闅愭偅涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    issueNotice: [
+      { required: true, message: "涓嬪彂閫氱煡涔︿笉鑳戒负绌�", trigger: "blur" }
+    ],
+    dealWithSecurityRisks: [
+      { required: true, message: "澶勭疆瀹夊叏闅愭偅涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    status: [
+      { required: true, message: "鍚敤鐘舵�� 1鍚敤 2鏈惎鐢ㄤ笉鑳戒负绌�", trigger: "change" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 鏌ヨ瀹夊叏闅愭偅缁熻鍒楄〃 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listDangerTotal(queryParams.value);
+  dangerTotalList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 鍙栨秷鎸夐挳 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 琛ㄥ崟閲嶇疆 */
+const reset = () => {
+  form.value = {...initFormData};
+  dangerTotalFormRef.value?.resetFields();
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 澶氶�夋閫変腑鏁版嵁 */
+const handleSelectionChange = (selection: DangerTotalVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "娣诲姞瀹夊叏闅愭偅缁熻";
+}
+
+/** 淇敼鎸夐挳鎿嶄綔 */
+const handleUpdate = async (row?: DangerTotalVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getDangerTotal(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "淇敼瀹夊叏闅愭偅缁熻";
+}
+
+/** 鎻愪氦鎸夐挳 */
+const submitForm = () => {
+  dangerTotalFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateDangerTotal(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addDangerTotal(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("淇敼鎴愬姛");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+const handleDelete = async (row?: DangerTotalVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀹夊叏闅愭偅缁熻缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�').finally(() => loading.value = false);
+  await delDangerTotal(_ids);
+  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+  await getList();
+}
+
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+const handleExport = () => {
+  proxy?.download('demo/dangerTotal/export', {
+    ...queryParams.value
+  }, `dangerTotal_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+
+/** 鍛ㄦ湡骞存垨鏈� */
+const pickerType = computed(() => {
+  return form.value.period === 1 ? 'year' : 'month';
+});
+
+const pickerFormat = computed(() => {
+  return form.value.period === 1 ? 'YYYY' : 'YYYY-MM';
+});
+</script>
diff --git a/vite.config.ts b/vite.config.ts
index 73449ef..f560144 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -26,8 +26,8 @@
       open: true,
       proxy: {
         [env.VITE_APP_BASE_API]: {
-          target: 'http://192.168.3.43:8080',
-          // target: 'http://localhost:8080',
+          // target: 'http://192.168.3.43:8080',
+          target: 'http://localhost:8080',
           changeOrigin: true,
           rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
         }

--
Gitblit v1.8.0