From 34af9a2cd41fb88985d05d57e9fa425bc98990cc Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 30 六月 2026 16:12:22 +0800
Subject: [PATCH] 线路巡检、安全设施巡检模块开发

---
 src/api/safeProduction/safetyFacility.js                      |  122 ++
 src/pages.json                                                |   77 +
 src/api/safeProduction/lineInspection.js                      |  129 ++
 src/pages/safeProduction/safetyFacility/rectificationEdit.vue |  281 +++++
 src/pages/works.vue                                           |   18 
 src/pages/safeProduction/safetyFacility/ledgerEdit.vue        |  211 ++++
 src/pages/safeProduction/lineInspection/edit.vue              |  274 +++++
 src/pages/safeProduction/lineInspection/hazardRectify.vue     |   68 +
 src/pages/safeProduction/lineInspection/recordList.vue        |  197 ++++
 src/pages/safeProduction/safetyFacility/inspectionEdit.vue    |  262 +++++
 src/pages/safeProduction/lineInspection/hazardList.vue        |  189 +++
 src/pages/safeProduction/lineInspection/index.vue             |  313 ++++++
 src/pages/safeProduction/lineInspection/hazardEdit.vue        |  123 ++
 src/pages/safeProduction/lineInspection/recordEdit.vue        |  160 +++
 src/pages/safeProduction/safetyFacility/index.vue             |  488 +++++++++
 15 files changed, 2,912 insertions(+), 0 deletions(-)

diff --git a/src/api/safeProduction/lineInspection.js b/src/api/safeProduction/lineInspection.js
new file mode 100644
index 0000000..f1dc228
--- /dev/null
+++ b/src/api/safeProduction/lineInspection.js
@@ -0,0 +1,129 @@
+import request from "@/utils/request";
+
+export function getLineInspectionList(params) {
+  return request({
+    url: "/safeLineInspection/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getLineInspectionById(id) {
+  return request({
+    url: `/safeLineInspection/${id}`,
+    method: "get",
+  });
+}
+
+export function addLineInspection(data) {
+  return request({
+    url: "/safeLineInspection",
+    method: "post",
+    data,
+  });
+}
+
+export function updateLineInspection(data) {
+  return request({
+    url: "/safeLineInspection",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteLineInspection(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeLineInspection/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
+export function completeLineInspection(id) {
+  return request({
+    url: `/safeLineInspection/complete/${id}`,
+    method: "put",
+  });
+}
+
+export function getInspectionRecords(inspectionId) {
+  return request({
+    url: `/safeLineInspectionRecord/list/${inspectionId}`,
+    method: "get",
+  });
+}
+
+export function addInspectionRecord(data) {
+  return request({
+    url: "/safeLineInspectionRecord",
+    method: "post",
+    data,
+  });
+}
+
+export function updateInspectionRecord(data) {
+  return request({
+    url: "/safeLineInspectionRecord",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteInspectionRecord(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeLineInspectionRecord/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
+export function batchAddInspectionRecords(data) {
+  return request({
+    url: "/safeLineInspectionRecord/batch",
+    method: "post",
+    data,
+  });
+}
+
+export function getInspectionHazards(params) {
+  return request({
+    url: "/safeLineInspectionHazard/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getHazardsByInspectionId(inspectionId) {
+  return request({
+    url: `/safeLineInspectionHazard/list/${inspectionId}`,
+    method: "get",
+  });
+}
+
+export function addInspectionHazard(data) {
+  return request({
+    url: "/safeLineInspectionHazard",
+    method: "post",
+    data,
+  });
+}
+
+export function updateInspectionHazard(data) {
+  return request({
+    url: "/safeLineInspectionHazard",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteInspectionHazard(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeLineInspectionHazard/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
diff --git a/src/api/safeProduction/safetyFacility.js b/src/api/safeProduction/safetyFacility.js
new file mode 100644
index 0000000..f0f278b
--- /dev/null
+++ b/src/api/safeProduction/safetyFacility.js
@@ -0,0 +1,122 @@
+import request from "@/utils/request";
+
+export function getFacilityLedgerList(params) {
+  return request({
+    url: "/safeFacilityLedger/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getFacilityLedgerById(id) {
+  return request({
+    url: `/safeFacilityLedger/${id}`,
+    method: "get",
+  });
+}
+
+export function addFacilityLedger(data) {
+  return request({
+    url: "/safeFacilityLedger",
+    method: "post",
+    data,
+  });
+}
+
+export function updateFacilityLedger(data) {
+  return request({
+    url: "/safeFacilityLedger",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteFacilityLedger(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeFacilityLedger/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
+export function getFacilityInspectionList(params) {
+  return request({
+    url: "/safeFacilityInspection/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getFacilityInspectionById(id) {
+  return request({
+    url: `/safeFacilityInspection/${id}`,
+    method: "get",
+  });
+}
+
+export function addFacilityInspection(data) {
+  return request({
+    url: "/safeFacilityInspection",
+    method: "post",
+    data,
+  });
+}
+
+export function updateFacilityInspection(data) {
+  return request({
+    url: "/safeFacilityInspection",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteFacilityInspection(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeFacilityInspection/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
+export function getFacilityRectificationList(params) {
+  return request({
+    url: "/safeFacilityRectification/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getFacilityRectificationById(id) {
+  return request({
+    url: `/safeFacilityRectification/${id}`,
+    method: "get",
+  });
+}
+
+export function addFacilityRectification(data) {
+  return request({
+    url: "/safeFacilityRectification",
+    method: "post",
+    data,
+  });
+}
+
+export function updateFacilityRectification(data) {
+  return request({
+    url: "/safeFacilityRectification",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteFacilityRectification(ids) {
+  const joined = Array.isArray(ids) ? ids.join(",") : String(ids || "");
+  return request({
+    url: `/safeFacilityRectification/${joined}`,
+    method: "delete",
+    data: ids,
+  });
+}
+
diff --git a/src/pages.json b/src/pages.json
index a8b9e69..44f9193 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -1048,6 +1048,83 @@
       }
     },
     {
+      "path": "pages/safeProduction/lineInspection/index",
+      "style": {
+        "navigationBarTitleText": "绾胯矾宸℃",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/edit",
+      "style": {
+        "navigationBarTitleText": "宸℃浠诲姟",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/recordList",
+      "style": {
+        "navigationBarTitleText": "宸℃璁板綍",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/recordEdit",
+      "style": {
+        "navigationBarTitleText": "宸℃璁板綍",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/hazardList",
+      "style": {
+        "navigationBarTitleText": "闅愭偅绠$悊",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/hazardEdit",
+      "style": {
+        "navigationBarTitleText": "闅愭偅",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/lineInspection/hazardRectify",
+      "style": {
+        "navigationBarTitleText": "鏁存敼",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/safetyFacility/index",
+      "style": {
+        "navigationBarTitleText": "瀹夊叏璁炬柦宸℃",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/safetyFacility/ledgerEdit",
+      "style": {
+        "navigationBarTitleText": "璁炬柦鍙拌处",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/safetyFacility/inspectionEdit",
+      "style": {
+        "navigationBarTitleText": "璁炬柦宸℃",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/safeProduction/safetyFacility/rectificationEdit",
+      "style": {
+        "navigationBarTitleText": "鏁存敼",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/safeProduction/accidentReportingRecord/index",
       "style": {
         "navigationBarTitleText": "浜嬫晠鎶ュ憡璁板綍",
diff --git a/src/pages/safeProduction/lineInspection/edit.vue b/src/pages/safeProduction/lineInspection/edit.vue
new file mode 100644
index 0000000..0b55e10
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/edit.vue
@@ -0,0 +1,274 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="宸℃缂栧彿" required>
+        <up-input v-model="form.inspectionCode" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="宸℃鍚嶇О" required>
+        <up-input v-model="form.inspectionName" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="绾胯矾鍚嶇О" required>
+        <up-input v-model="form.lineName" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="宸℃绫诲瀷">
+        <up-input :model-value="inspectionTypeText" placeholder="璇烽�夋嫨" readonly @click="showTypeSheet = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showTypeSheet = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="璁″垝宸℃鏃堕棿">
+        <up-input :model-value="form.planTime" placeholder="璇烽�夋嫨" readonly @click="showPlanTimePicker = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showPlanTimePicker = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="宸℃浜�" required>
+        <up-input :model-value="inspectorText" placeholder="璇烽�夋嫨锛堝彲澶氶�夛級" readonly @click="openInspectorPopup" />
+        <template #right>
+          <up-icon name="arrow-right" @click="openInspectorPopup"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="澶囨敞">
+        <up-textarea v-model="form.remark" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+    </up-form>
+
+    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
+
+    <up-action-sheet
+      :show="showTypeSheet"
+      title="閫夋嫨宸℃绫诲瀷"
+      :actions="typeActions"
+      @select="onSelectType"
+      @close="showTypeSheet = false"
+    />
+
+    <up-datetime-picker
+      :show="showPlanTimePicker"
+      mode="datetime"
+      :value="planTimeValue"
+      @confirm="onPlanTimeConfirm"
+      @cancel="showPlanTimePicker = false"
+    />
+
+    <up-popup :show="showInspectorPopup" mode="bottom" @close="showInspectorPopup = false">
+      <view class="popup-container">
+        <view class="popup-header">
+          <text class="popup-title">閫夋嫨宸℃浜�</text>
+        </view>
+        <scroll-view scroll-y class="popup-scroll">
+          <up-checkbox-group v-model="inspectorIdsTemp">
+            <up-checkbox
+              v-for="u in userOptions"
+              :key="u.value"
+              :name="u.value"
+              :label="u.label"
+            ></up-checkbox>
+          </up-checkbox-group>
+        </scroll-view>
+        <view class="popup-footer">
+          <u-button size="small" @click="showInspectorPopup = false">鍙栨秷</u-button>
+          <u-button type="primary" size="small" @click="confirmInspector">纭畾</u-button>
+        </view>
+      </view>
+    </up-popup>
+  </view>
+</template>
+
+<script setup>
+  import { computed, onMounted, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import dayjs from "dayjs";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import { addLineInspection, updateLineInspection } from "@/api/safeProduction/lineInspection";
+  import { userListNoPage } from "@/api/system/user";
+
+  const loading = ref(false);
+  const form = ref({
+    id: null,
+    inspectionCode: "",
+    inspectionName: "",
+    lineName: "",
+    inspectionType: "",
+    planTime: "",
+    inspectorId: "",
+    inspectorIds: [],
+    remark: "",
+  });
+
+  const userOptions = ref([]);
+
+  const showTypeSheet = ref(false);
+  const showPlanTimePicker = ref(false);
+  const showInspectorPopup = ref(false);
+  const inspectorIdsTemp = ref([]);
+
+  const typeActions = [
+    { name: "瀹氭湡宸℃", value: "瀹氭湡宸℃" },
+    { name: "涓存椂宸℃", value: "涓存椂宸℃" },
+  ];
+
+  const pageTitle = computed(() => (form.value.id ? "缂栬緫宸℃浠诲姟" : "鏂板宸℃浠诲姟"));
+  const inspectionTypeText = computed(() => form.value.inspectionType || "");
+
+  const inspectorText = computed(() => {
+    const ids = Array.isArray(form.value.inspectorIds) ? form.value.inspectorIds : [];
+    if (ids.length === 0) return "";
+    const map = new Map(userOptions.value.map(x => [x.value, x.label]));
+    const names = ids.map(id => map.get(id)).filter(Boolean);
+    return names.join("锛�");
+  });
+
+  const planTimeValue = computed(() => {
+    if (!form.value.planTime) return Date.now();
+    const ts = dayjs(form.value.planTime).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const onSelectType = action => {
+    form.value.inspectionType = action.value;
+    showTypeSheet.value = false;
+  };
+
+  const onPlanTimeConfirm = e => {
+    const ts = e?.value;
+    form.value.planTime = dayjs(ts).format("YYYY-MM-DD HH:mm:ss");
+    showPlanTimePicker.value = false;
+  };
+
+  const openInspectorPopup = () => {
+    inspectorIdsTemp.value = [...(form.value.inspectorIds || [])];
+    showInspectorPopup.value = true;
+  };
+
+  const confirmInspector = () => {
+    form.value.inspectorIds = [...(inspectorIdsTemp.value || [])];
+    showInspectorPopup.value = false;
+  };
+
+  const handleSubmit = async () => {
+    const inspectionCode = String(form.value.inspectionCode || "").trim();
+    if (!inspectionCode) {
+      uni.showToast({ title: "璇疯緭鍏ュ贰妫�缂栧彿", icon: "none" });
+      return;
+    }
+    const inspectionName = String(form.value.inspectionName || "").trim();
+    if (!inspectionName) {
+      uni.showToast({ title: "璇疯緭鍏ュ贰妫�鍚嶇О", icon: "none" });
+      return;
+    }
+    const lineName = String(form.value.lineName || "").trim();
+    if (!lineName) {
+      uni.showToast({ title: "璇疯緭鍏ョ嚎璺悕绉�", icon: "none" });
+      return;
+    }
+    const inspectorIds = Array.isArray(form.value.inspectorIds) ? form.value.inspectorIds : [];
+    if (inspectorIds.length === 0) {
+      uni.showToast({ title: "璇烽�夋嫨宸℃浜�", icon: "none" });
+      return;
+    }
+
+    const payload = {
+      ...form.value,
+      inspectionCode,
+      inspectionName,
+      lineName,
+      inspectorId: inspectorIds.join(","),
+    };
+    delete payload.inspectorIds;
+
+    loading.value = true;
+    const api = payload.id ? updateLineInspection : addLineInspection;
+    api(payload)
+      .then(() => {
+        uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
+        uni.$emit("lineInspection:refresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "淇濆瓨澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  const initUsers = () => {
+    userListNoPage()
+      .then(res => {
+        const list = res?.data || [];
+        userOptions.value = list.map(u => ({
+          label: u.nickName,
+          value: u.userId,
+        }));
+      })
+      .catch(() => {});
+  };
+
+  onMounted(() => {
+    initUsers();
+  });
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const row = JSON.parse(decodeURIComponent(options.data));
+        const inspectorIds = row?.inspectorId
+          ? String(row.inspectorId)
+              .split(",")
+              .map(x => Number(String(x).trim()))
+              .filter(n => Number.isFinite(n))
+          : [];
+        form.value = {
+          ...form.value,
+          ...row,
+          inspectorIds,
+        };
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+
+  .popup-container {
+    background: #fff;
+    border-top-left-radius: 20rpx;
+    border-top-right-radius: 20rpx;
+    padding: 24rpx;
+    max-height: 70vh;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .popup-header {
+    padding-bottom: 16rpx;
+  }
+
+  .popup-title {
+    font-size: 30rpx;
+    font-weight: 600;
+    color: #333;
+  }
+
+  .popup-scroll {
+    flex: 1;
+    min-height: 0;
+    padding: 10rpx 0;
+  }
+
+  .popup-footer {
+    display: flex;
+    justify-content: flex-end;
+    gap: 16rpx;
+    padding-top: 16rpx;
+  }
+</style>
+
diff --git a/src/pages/safeProduction/lineInspection/hazardEdit.vue b/src/pages/safeProduction/lineInspection/hazardEdit.vue
new file mode 100644
index 0000000..d8d2541
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/hazardEdit.vue
@@ -0,0 +1,123 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="闅愭偅鎻忚堪" required>
+        <up-textarea v-model="form.hazardDesc" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+      <up-form-item label="闅愭偅绛夌骇" required>
+        <up-input :model-value="form.hazardLevel" placeholder="璇烽�夋嫨" readonly @click="showLevelSheet = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showLevelSheet = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="闅愭偅浣嶇疆" required>
+        <up-input v-model="form.hazardLocation" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+    </up-form>
+
+    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
+
+    <up-action-sheet
+      :show="showLevelSheet"
+      title="閫夋嫨闅愭偅绛夌骇"
+      :actions="levelActions"
+      @select="onSelectLevel"
+      @close="showLevelSheet = false"
+    />
+  </view>
+</template>
+
+<script setup>
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import { addInspectionHazard, updateInspectionHazard } from "@/api/safeProduction/lineInspection";
+
+  const loading = ref(false);
+  const inspectionId = ref(null);
+
+  const form = ref({
+    id: null,
+    inspectionId: null,
+    hazardDesc: "",
+    hazardLevel: "",
+    hazardLocation: "",
+  });
+
+  const showLevelSheet = ref(false);
+  const levelActions = [
+    { name: "涓�鑸�", value: "涓�鑸�" },
+    { name: "閲嶅ぇ", value: "閲嶅ぇ" },
+  ];
+
+  const pageTitle = computed(() => (form.value.id ? "缂栬緫闅愭偅" : "涓婃姤闅愭偅"));
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const onSelectLevel = action => {
+    form.value.hazardLevel = action.value;
+    showLevelSheet.value = false;
+  };
+
+  const handleSubmit = () => {
+    const hazardDesc = String(form.value.hazardDesc || "").trim();
+    if (!hazardDesc) {
+      uni.showToast({ title: "璇疯緭鍏ラ殣鎮f弿杩�", icon: "none" });
+      return;
+    }
+    const hazardLevel = String(form.value.hazardLevel || "").trim();
+    if (!hazardLevel) {
+      uni.showToast({ title: "璇烽�夋嫨闅愭偅绛夌骇", icon: "none" });
+      return;
+    }
+    const hazardLocation = String(form.value.hazardLocation || "").trim();
+    if (!hazardLocation) {
+      uni.showToast({ title: "璇疯緭鍏ラ殣鎮d綅缃�", icon: "none" });
+      return;
+    }
+
+    const payload = {
+      ...form.value,
+      inspectionId: inspectionId.value,
+      hazardDesc,
+      hazardLevel,
+      hazardLocation,
+    };
+
+    loading.value = true;
+    const api = payload.id ? updateInspectionHazard : addInspectionHazard;
+    api(payload)
+      .then(() => {
+        uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
+        uni.$emit("lineInspection:hazardsRefresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "淇濆瓨澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        inspectionId.value = obj.inspectionId;
+        if (obj?.row) {
+          form.value = { ...form.value, ...(obj.row || {}) };
+        }
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
+
diff --git a/src/pages/safeProduction/lineInspection/hazardList.vue b/src/pages/safeProduction/lineInspection/hazardList.vue
new file mode 100644
index 0000000..cfcdbf5
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/hazardList.vue
@@ -0,0 +1,189 @@
+<template>
+  <view class="hazard-list">
+    <PageHeader title="闅愭偅绠$悊"
+                @back="goBack" />
+    <view class="top-actions">
+      <u-button type="primary"
+                size="small"
+                :disabled="isCompleted"
+                @click="goAdd">涓婃姤闅愭偅</u-button>
+    </view>
+    <scroll-view scroll-y
+                 class="list-scroll ledger-list"
+                 v-if="hazards.length > 0">
+      <view v-for="row in hazards"
+            :key="row.id"
+            class="ledger-item">
+        <view class="item-header">
+          <view class="item-left">
+            <view class="document-icon">
+              <up-icon name="file-text"
+                       size="16"
+                       color="#ffffff"></up-icon>
+            </view>
+            <text class="item-id">{{ row.hazardCode || "闅愭偅" }}</text>
+          </view>
+          <view class="item-right">
+            <up-tag :text="row.status || '-'"
+                    :type="statusType(row.status)"
+                    size="mini" />
+          </view>
+        </view>
+        <up-divider></up-divider>
+        <view class="item-details">
+          <view class="detail-row">
+            <text class="detail-label">闅愭偅鎻忚堪</text>
+            <text class="detail-value">{{ row.hazardDesc || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">闅愭偅绛夌骇</text>
+            <text class="detail-value">{{ row.hazardLevel || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">闅愭偅浣嶇疆</text>
+            <text class="detail-value">{{ row.hazardLocation || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鏁存敼璐d换浜�</text>
+            <text class="detail-value">{{ row.rectifyUserName || "-" }}</text>
+          </view>
+        </view>
+        <view class="action-buttons">
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    :disabled="isCompleted"
+                    @click.stop="goEdit(row)">缂栬緫</u-button>
+          <u-button v-if="String(row.status) !== '宸叉暣鏀�'"
+                    size="small"
+                    class="action-btn fixed-btn"
+                    type="success"
+                    :disabled="isCompleted"
+                    @click.stop="goRectify(row)">
+            鏁存敼
+          </u-button>
+        </view>
+      </view>
+    </scroll-view>
+    <view v-else
+          class="no-data">
+      <up-empty mode="data"
+                text="鏆傛棤闅愭偅"></up-empty>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { computed, onMounted, ref } from "vue";
+  import { onLoad, onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import { getHazardsByInspectionId } from "@/api/safeProduction/lineInspection";
+
+  const inspectionId = ref(null);
+  const inspectionStatus = ref("");
+  const hazards = ref([]);
+
+  const isCompleted = computed(() => String(inspectionStatus.value) === "宸插畬鎴�");
+
+  const statusType = status => {
+    const map = {
+      寰呮暣鏀�: "error",
+      鏁存敼涓�: "warning",
+      宸叉暣鏀�: "success",
+    };
+    return map[status] || "info";
+  };
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const fetchHazards = () => {
+    if (!inspectionId.value) return;
+    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
+    getHazardsByInspectionId(inspectionId.value)
+      .then(res => {
+        hazards.value = res?.data || [];
+      })
+      .catch(() => {
+        uni.showToast({ title: "鍔犺浇澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        uni.hideLoading();
+      });
+  };
+
+  const goAdd = () => {
+    const data = encodeURIComponent(
+      JSON.stringify({ inspectionId: inspectionId.value })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/hazardEdit?data=${data}`,
+    });
+  };
+
+  const goEdit = row => {
+    const data = encodeURIComponent(
+      JSON.stringify({ inspectionId: inspectionId.value, row })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/hazardEdit?data=${data}`,
+    });
+  };
+
+  const goRectify = row => {
+    const data = encodeURIComponent(JSON.stringify({ row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/hazardRectify?data=${data}`,
+    });
+  };
+
+  onMounted(() => {
+    uni.$on("lineInspection:hazardsRefresh", fetchHazards);
+  });
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        inspectionId.value = obj.inspectionId;
+        inspectionStatus.value = obj.inspectionStatus || "";
+      } catch (e) {}
+    }
+  });
+
+  onShow(() => {
+    fetchHazards();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  .hazard-list {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 40rpx;
+  }
+
+  .top-actions {
+    padding: 20rpx;
+    display: flex;
+    justify-content: flex-end;
+  }
+
+  .action-buttons {
+    display: flex;
+    justify-content: flex-end;
+    gap: 20rpx;
+    padding-bottom: 30rpx;
+  }
+
+  .fixed-btn {
+    width: 160rpx;
+    margin: 0 !important;
+  }
+
+  .no-data {
+    padding-top: 200rpx;
+  }
+</style>
diff --git a/src/pages/safeProduction/lineInspection/hazardRectify.vue b/src/pages/safeProduction/lineInspection/hazardRectify.vue
new file mode 100644
index 0000000..868f9eb
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/hazardRectify.vue
@@ -0,0 +1,68 @@
+<template>
+  <view class="account-detail">
+    <PageHeader title="鏁存敼" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="鏁存敼璇存槑" required>
+        <up-textarea v-model="form.rectifyDesc" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+    </up-form>
+
+    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
+  </view>
+</template>
+
+<script setup>
+  import { ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import { updateInspectionHazard } from "@/api/safeProduction/lineInspection";
+
+  const loading = ref(false);
+  const hazardId = ref(null);
+
+  const form = ref({
+    rectifyDesc: "",
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const handleSubmit = () => {
+    const rectifyDesc = String(form.value.rectifyDesc || "").trim();
+    if (!rectifyDesc) {
+      uni.showToast({ title: "璇疯緭鍏ユ暣鏀硅鏄�", icon: "none" });
+      return;
+    }
+    if (!hazardId.value) return;
+
+    loading.value = true;
+    updateInspectionHazard({ id: hazardId.value, status: "宸叉暣鏀�", rectifyDesc })
+      .then(() => {
+        uni.showToast({ title: "鏁存敼鎴愬姛", icon: "success" });
+        uni.$emit("lineInspection:hazardsRefresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "鏁存敼澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        hazardId.value = obj?.row?.id;
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
+
diff --git a/src/pages/safeProduction/lineInspection/index.vue b/src/pages/safeProduction/lineInspection/index.vue
new file mode 100644
index 0000000..e952750
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/index.vue
@@ -0,0 +1,313 @@
+<template>
+  <view class="line-inspection">
+    <PageHeader title="绾胯矾宸℃"
+                @back="goBack" />
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input class="search-text"
+                    placeholder="璇疯緭鍏ュ贰妫�缂栧彿/宸℃鍚嶇О/绾胯矾鍚嶇О"
+                    v-model="keyword"
+                    @change="handleQuery"
+                    clearable />
+        </view>
+        <view class="filter-button"
+              @click="handleQuery">
+          <up-icon name="search"
+                   size="24"
+                   color="#999"></up-icon>
+        </view>
+      </view>
+    </view>
+    <scroll-view scroll-y
+                 class="list-scroll ledger-list"
+                 @scrolltolower="loadMore"
+                 v-if="list.length > 0">
+      <view v-for="row in list"
+            :key="row.id"
+            class="ledger-item">
+        <view class="item-header">
+          <view class="item-left">
+            <view class="document-icon">
+              <up-icon name="file-text"
+                       size="16"
+                       color="#ffffff"></up-icon>
+            </view>
+            <text class="item-id">{{ row.inspectionCode || "-" }}</text>
+          </view>
+          <view class="item-right">
+            <up-tag :text="row.status || '-'"
+                    :type="statusType(row.status)"
+                    size="mini" />
+          </view>
+        </view>
+        <up-divider></up-divider>
+        <view class="item-details">
+          <view class="detail-row">
+            <text class="detail-label">宸℃鍚嶇О</text>
+            <text class="detail-value">{{ row.inspectionName || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">绾胯矾鍚嶇О</text>
+            <text class="detail-value">{{ row.lineName || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">宸℃绫诲瀷</text>
+            <text class="detail-value">{{ row.inspectionType || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">璁″垝宸℃鏃堕棿</text>
+            <text class="detail-value">{{ row.planTime || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">宸℃浜�</text>
+            <text class="detail-value">{{ row.inspectorName || "-" }}</text>
+          </view>
+        </view>
+        <view class="action-buttons action-buttons-bottom">
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    :disabled="!canEdit(row)"
+                    @click.stop="goEdit(row)">缂栬緫</u-button>
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    type="primary"
+                    @click.stop="goRecords(row)">宸℃璁板綍</u-button>
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    type="primary"
+                    @click.stop="goHazards(row)">闅愭偅绠$悊</u-button>
+          <u-button v-if="String(row.status) === '宸℃涓�'"
+                    size="small"
+                    class="action-btn fixed-btn"
+                    type="success"
+                    @click.stop="handleComplete(row)">
+            瀹屾垚宸℃
+          </u-button>
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    type="error"
+                    :disabled="!canDelete(row)"
+                    @click.stop="handleDelete(row)">鍒犻櫎</u-button>
+        </view>
+      </view>
+      <up-loadmore :status="loadStatus" />
+    </scroll-view>
+    <view v-else
+          class="no-data">
+      <up-empty mode="data"
+                text="鏆傛棤鏁版嵁"></up-empty>
+    </view>
+    <view class="fab-button"
+          @click="goAdd">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff"></up-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { onMounted, reactive, ref } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    completeLineInspection,
+    deleteLineInspection,
+    getLineInspectionList,
+  } from "@/api/safeProduction/lineInspection";
+
+  const keyword = ref("");
+
+  const page = reactive({ current: 1, size: 20, total: 0 });
+  const list = ref([]);
+  const loadStatus = ref("loadmore");
+  const loading = ref(false);
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const statusType = status => {
+    const map = {
+      寰呭贰妫�: "info",
+      宸℃涓�: "warning",
+      宸插畬鎴�: "success",
+    };
+    return map[status] || "info";
+  };
+
+  const canEdit = row => String(row?.status) === "寰呭贰妫�";
+  const canDelete = row => String(row?.status) === "寰呭贰妫�";
+
+  const fetchList = () => {
+    if (loading.value) return;
+    loading.value = true;
+    loadStatus.value = "loading";
+    const kw = String(keyword.value || "").trim();
+    getLineInspectionList({
+      inspectionCode: kw,
+      inspectionName: kw,
+      lineName: kw,
+      ...page,
+    })
+      .then(res => {
+        const records = res?.data?.records || [];
+        const total = Number(res?.data?.total || 0);
+        page.total = total;
+        list.value = page.current === 1 ? records : [...list.value, ...records];
+        loadStatus.value =
+          list.value.length >= page.total ? "nomore" : "loadmore";
+      })
+      .catch(() => {
+        loadStatus.value = "loadmore";
+        uni.showToast({ title: "鍔犺浇澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  const handleQuery = () => {
+    page.current = 1;
+    list.value = [];
+    fetchList();
+  };
+
+  const loadMore = () => {
+    if (loadStatus.value !== "loadmore") return;
+    page.current++;
+    fetchList();
+  };
+
+  const goAdd = () => {
+    uni.navigateTo({ url: "/pages/safeProduction/lineInspection/edit" });
+  };
+
+  const goEdit = row => {
+    const data = encodeURIComponent(JSON.stringify(row || {}));
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/edit?data=${data}`,
+    });
+  };
+
+  const goRecords = row => {
+    const params = encodeURIComponent(
+      JSON.stringify({ inspectionId: row.id, inspectionStatus: row.status || "" })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/recordList?data=${params}`,
+    });
+  };
+
+  const goHazards = row => {
+    const params = encodeURIComponent(
+      JSON.stringify({ inspectionId: row.id, inspectionStatus: row.status || "" })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/hazardList?data=${params}`,
+    });
+  };
+
+  const handleDelete = row => {
+    if (!row?.id) return;
+    uni.showModal({
+      title: "鍒犻櫎",
+      content: "纭鍒犻櫎璇ュ贰妫�浠诲姟鍚楋紵",
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "鍒犻櫎涓�...", mask: true });
+        deleteLineInspection([row.id])
+          .then(() => {
+            uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
+            handleQuery();
+          })
+          .catch(() => {
+            uni.showToast({ title: "鍒犻櫎澶辫触", icon: "none" });
+          })
+          .finally(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  const handleComplete = row => {
+    if (!row?.id) return;
+    uni.showModal({
+      title: "瀹屾垚宸℃",
+      content: "纭瀹屾垚璇ュ贰妫�浠诲姟鍚楋紵",
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "鎻愪氦涓�...", mask: true });
+        completeLineInspection(row.id)
+          .then(() => {
+            uni.showToast({ title: "宸℃宸插畬鎴�", icon: "success" });
+            handleQuery();
+          })
+          .catch(() => {
+            uni.showToast({ title: "鎿嶄綔澶辫触", icon: "none" });
+          })
+          .finally(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  onMounted(() => {
+    handleQuery();
+  });
+
+  onShow(() => {
+    handleQuery();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  .line-inspection {
+    min-height: 100vh;
+    background: #f8f9fa;
+    position: relative;
+    padding-bottom: 140rpx;
+  }
+
+  .list-scroll {
+    flex: 1;
+    min-height: 0;
+  }
+
+  .action-buttons {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-end;
+    gap: 20rpx;
+    padding-bottom: 30rpx;
+  }
+
+  .fixed-btn {
+    width: 160rpx;
+    margin: 0 !important;
+  }
+
+  .fab-button {
+    position: fixed;
+    right: 30rpx;
+    bottom: 140rpx;
+    width: 96rpx;
+    height: 96rpx;
+    background: #3c9cff;
+    border-radius: 48rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-shadow: 0 8rpx 24rpx rgba(60, 156, 255, 0.3);
+    z-index: 1001;
+  }
+
+  .no-data {
+    padding-top: 200rpx;
+  }
+</style>
diff --git a/src/pages/safeProduction/lineInspection/recordEdit.vue b/src/pages/safeProduction/lineInspection/recordEdit.vue
new file mode 100644
index 0000000..7892c75
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/recordEdit.vue
@@ -0,0 +1,160 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="妫�鏌ョ偣" required>
+        <up-input v-model="form.checkPoint" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="妫�鏌ョ粨鏋�" required>
+        <up-input :model-value="form.checkResult" placeholder="璇烽�夋嫨" readonly @click="showResultSheet = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showResultSheet = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="妫�鏌ュ唴瀹�" required>
+        <up-textarea v-model="form.checkContent" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+      <up-form-item label="妫�鏌ヨ鏄�">
+        <up-textarea v-model="form.checkDesc" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+      <up-form-item label="妫�鏌ユ椂闂�">
+        <up-input :model-value="form.checkTime" placeholder="璇烽�夋嫨" readonly @click="showTimePicker = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showTimePicker = true"></up-icon>
+        </template>
+      </up-form-item>
+    </up-form>
+
+    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
+
+    <up-action-sheet
+      :show="showResultSheet"
+      title="閫夋嫨妫�鏌ョ粨鏋�"
+      :actions="resultActions"
+      @select="onSelectResult"
+      @close="showResultSheet = false"
+    />
+
+    <up-datetime-picker
+      :show="showTimePicker"
+      mode="datetime"
+      :value="checkTimeValue"
+      @confirm="onTimeConfirm"
+      @cancel="showTimePicker = false"
+    />
+  </view>
+</template>
+
+<script setup>
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import dayjs from "dayjs";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import { addInspectionRecord, updateInspectionRecord } from "@/api/safeProduction/lineInspection";
+
+  const loading = ref(false);
+  const inspectionId = ref(null);
+
+  const form = ref({
+    id: null,
+    inspectionId: null,
+    checkPoint: "",
+    checkContent: "",
+    checkResult: "姝e父",
+    checkDesc: "",
+    checkTime: "",
+  });
+
+  const showResultSheet = ref(false);
+  const showTimePicker = ref(false);
+
+  const resultActions = [
+    { name: "姝e父", value: "姝e父" },
+    { name: "寮傚父", value: "寮傚父" },
+  ];
+
+  const pageTitle = computed(() => (form.value.id ? "缂栬緫宸℃璁板綍" : "鏂板宸℃璁板綍"));
+
+  const checkTimeValue = computed(() => {
+    if (!form.value.checkTime) return Date.now();
+    const ts = dayjs(form.value.checkTime).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const onSelectResult = action => {
+    form.value.checkResult = action.value;
+    showResultSheet.value = false;
+  };
+
+  const onTimeConfirm = e => {
+    const ts = e?.value;
+    form.value.checkTime = dayjs(ts).format("YYYY-MM-DD HH:mm:ss");
+    showTimePicker.value = false;
+  };
+
+  const handleSubmit = () => {
+    const checkPoint = String(form.value.checkPoint || "").trim();
+    if (!checkPoint) {
+      uni.showToast({ title: "璇疯緭鍏ユ鏌ョ偣", icon: "none" });
+      return;
+    }
+    const checkContent = String(form.value.checkContent || "").trim();
+    if (!checkContent) {
+      uni.showToast({ title: "璇疯緭鍏ユ鏌ュ唴瀹�", icon: "none" });
+      return;
+    }
+    const checkResult = String(form.value.checkResult || "").trim();
+    if (!checkResult) {
+      uni.showToast({ title: "璇烽�夋嫨妫�鏌ョ粨鏋�", icon: "none" });
+      return;
+    }
+
+    const payload = {
+      ...form.value,
+      inspectionId: inspectionId.value,
+      checkPoint,
+      checkContent,
+      checkResult,
+      checkDesc: String(form.value.checkDesc || "").trim(),
+      checkTime: form.value.checkTime || "",
+    };
+
+    loading.value = true;
+    const api = payload.id ? updateInspectionRecord : addInspectionRecord;
+    api(payload)
+      .then(() => {
+        uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
+        uni.$emit("lineInspection:recordsRefresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "淇濆瓨澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        inspectionId.value = obj.inspectionId;
+        if (obj?.row) {
+          form.value = { ...form.value, ...(obj.row || {}) };
+        }
+      } catch (e) {}
+    }
+    if (!form.value.checkTime) form.value.checkTime = dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss");
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
+
diff --git a/src/pages/safeProduction/lineInspection/recordList.vue b/src/pages/safeProduction/lineInspection/recordList.vue
new file mode 100644
index 0000000..00d8630
--- /dev/null
+++ b/src/pages/safeProduction/lineInspection/recordList.vue
@@ -0,0 +1,197 @@
+<template>
+  <view class="record-list">
+    <PageHeader title="宸℃璁板綍"
+                @back="goBack" />
+    <view class="top-actions">
+      <u-button type="primary"
+                size="small"
+                :disabled="isCompleted"
+                @click="goAdd">鏂板璁板綍</u-button>
+    </view>
+    <scroll-view scroll-y
+                 class="list-scroll ledger-list"
+                 v-if="records.length > 0">
+      <view v-for="row in records"
+            :key="row.id"
+            class="ledger-item">
+        <view class="item-header">
+          <view class="item-left">
+            <view class="document-icon">
+              <up-icon name="file-text"
+                       size="16"
+                       color="#ffffff"></up-icon>
+            </view>
+            <text class="item-id">{{ row.checkPoint || "-" }}</text>
+          </view>
+          <view class="item-right">
+            <up-tag :text="row.checkResult || '-'"
+                    :type="row.checkResult === '姝e父' ? 'success' : 'error'"
+                    size="mini" />
+          </view>
+        </view>
+        <up-divider></up-divider>
+        <view class="item-details">
+          <view class="detail-row">
+            <text class="detail-label">妫�鏌ュ唴瀹�</text>
+            <text class="detail-value">{{ row.checkContent || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">妫�鏌ヨ鏄�</text>
+            <text class="detail-value">{{ row.checkDesc || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">妫�鏌ユ椂闂�</text>
+            <text class="detail-value">{{ row.checkTime || "-" }}</text>
+          </view>
+        </view>
+        <view class="action-buttons">
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    :disabled="isCompleted"
+                    @click.stop="goEdit(row)">缂栬緫</u-button>
+          <u-button size="small"
+                    class="action-btn fixed-btn"
+                    type="error"
+                    :disabled="isCompleted"
+                    @click.stop="handleDelete(row)">鍒犻櫎</u-button>
+        </view>
+      </view>
+    </scroll-view>
+    <view v-else
+          class="no-data">
+      <up-empty mode="data"
+                text="鏆傛棤璁板綍"></up-empty>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { computed, onMounted, ref } from "vue";
+  import { onLoad, onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    deleteInspectionRecord,
+    getInspectionRecords,
+  } from "@/api/safeProduction/lineInspection";
+
+  const inspectionId = ref(null);
+  const inspectionStatus = ref("");
+  const records = ref([]);
+
+  const isCompleted = computed(() => String(inspectionStatus.value) === "宸插畬鎴�");
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const fetchRecords = () => {
+    if (!inspectionId.value) return;
+    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
+    getInspectionRecords(inspectionId.value)
+      .then(res => {
+        records.value = res?.data || [];
+      })
+      .catch(() => {
+        uni.showToast({ title: "鍔犺浇澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        uni.hideLoading();
+      });
+  };
+
+  const goAdd = () => {
+    const data = encodeURIComponent(
+      JSON.stringify({ inspectionId: inspectionId.value })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/recordEdit?data=${data}`,
+    });
+  };
+
+  const goEdit = row => {
+    const data = encodeURIComponent(
+      JSON.stringify({ inspectionId: inspectionId.value, row })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/lineInspection/recordEdit?data=${data}`,
+    });
+  };
+
+  const handleDelete = row => {
+    if (!row?.id) return;
+    uni.showModal({
+      title: "鍒犻櫎",
+      content: "纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵",
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "鍒犻櫎涓�...", mask: true });
+        deleteInspectionRecord([row.id])
+          .then(() => {
+            uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
+            fetchRecords();
+          })
+          .catch(() => {
+            uni.showToast({ title: "鍒犻櫎澶辫触", icon: "none" });
+          })
+          .finally(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  onMounted(() => {
+    uni.$on("lineInspection:recordsRefresh", fetchRecords);
+  });
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        inspectionId.value = obj.inspectionId;
+        inspectionStatus.value = obj.inspectionStatus || "";
+      } catch (e) {}
+    }
+  });
+
+  onShow(() => {
+    fetchRecords();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  .record-list {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 40rpx;
+  }
+
+  .top-actions {
+    padding: 20rpx;
+    display: flex;
+    justify-content: flex-end;
+  }
+
+  .list-scroll {
+    flex: 1;
+    min-height: 0;
+  }
+
+  .action-buttons {
+    display: flex;
+    justify-content: flex-end;
+    gap: 20rpx;
+    padding-bottom: 30rpx;
+  }
+
+  .fixed-btn {
+    width: 160rpx;
+    margin: 0 !important;
+  }
+
+  .no-data {
+    padding-top: 200rpx;
+  }
+</style>
diff --git a/src/pages/safeProduction/safetyFacility/index.vue b/src/pages/safeProduction/safetyFacility/index.vue
new file mode 100644
index 0000000..c49da11
--- /dev/null
+++ b/src/pages/safeProduction/safetyFacility/index.vue
@@ -0,0 +1,488 @@
+<template>
+  <view class="safety-facility">
+    <PageHeader title="瀹夊叏璁炬柦宸℃"
+                @back="goBack" />
+    <view class="tabs-section">
+      <up-tabs v-model="activeTabIndex"
+               :list="tabList"
+               itemStyle="width: 33.33%;height: 80rpx;"
+               @change="onTabChange" />
+    </view>
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input class="search-text"
+                    v-model="keyword"
+                    :placeholder="searchPlaceholder"
+                    @change="handleSearch"
+                    clearable />
+        </view>
+        <view class="filter-button"
+              @click="handleSearch">
+          <up-icon name="search"
+                   size="24"
+                   color="#999"></up-icon>
+        </view>
+      </view>
+    </view>
+    <scroll-view scroll-y
+                 class="list-scroll ledger-list"
+                 @scrolltolower="loadMore"
+                 v-if="list.length > 0">
+      <view v-for="row in list"
+            :key="row.id"
+            class="ledger-item">
+        <view class="item-header"
+              @click="handleInspectionInfoClick(row)">
+          <view class="item-left">
+            <view class="document-icon">
+              <up-icon name="setting-fill"
+                       size="16"
+                       color="#ffffff"></up-icon>
+            </view>
+            <text class="item-id">{{ getCardTitle(row) }}</text>
+          </view>
+          <view class="item-right">
+            <text v-if="activeTab === 'ledger'"
+                  class="item-index">{{ row.facilityCode || "-" }}</text>
+            <up-tag v-else
+                    :text="row.status || '-'"
+                    :type="activeTab === 'inspection' ? (row.status === '寰呭贰妫�' ? 'info' : 'success') : rectStatusType(row.status)"
+                    size="mini" />
+          </view>
+        </view>
+        <up-divider></up-divider>
+        <view class="item-details"
+              @click="handleInspectionInfoClick(row)">
+          <template v-if="activeTab === 'ledger'">
+            <view class="detail-row">
+              <text class="detail-label">璁炬柦绫诲瀷</text>
+              <text class="detail-value">{{ row.facilityType || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">瑙勬牸鍨嬪彿</text>
+              <text class="detail-value">{{ row.facilitySpec || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">瀹夎浣嶇疆</text>
+              <text class="detail-value">{{ row.installLocation || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">瀹夎鏃堕棿</text>
+              <text class="detail-value">{{ row.installTime || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">涓嬫妫�鏌ユ椂闂�</text>
+              <text class="detail-value">{{ row.nextCheckTime || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐘舵��</text>
+              <up-tag :text="row.status || '-'"
+                      :type="facilityStatusType(row.status)"
+                      size="mini" />
+            </view>
+          </template>
+          <template v-else-if="activeTab === 'inspection'">
+            <view class="detail-row">
+              <text class="detail-label">璁炬柦鍚嶇О</text>
+              <text class="detail-value">{{ row.facilityName || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">璁炬柦缂栧彿</text>
+              <text class="detail-value">{{ row.facilityCode || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">宸℃绫诲瀷</text>
+              <text class="detail-value">{{ row.inspectionType || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">璁″垝宸℃鏃堕棿</text>
+              <text class="detail-value">{{ row.planTime || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">妫�鏌ョ粨鏋�</text>
+              <text class="detail-value">{{ row.checkResult || '-' }}</text>
+            </view>
+          </template>
+          <template v-else>
+            <view class="detail-row">
+              <text class="detail-label">璁炬柦鍚嶇О</text>
+              <text class="detail-value">{{ row.facilityName || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">闂鎻忚堪</text>
+              <text class="detail-value">{{ row.problemDesc || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">闂绛夌骇</text>
+              <text class="detail-value">{{ row.problemLevel || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鏁存敼璐d换浜�</text>
+              <text class="detail-value">{{ row.rectifyUserName || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">璁″垝鏁存敼鏃堕棿</text>
+              <text class="detail-value">{{ row.planTime || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">楠屾敹浜�</text>
+              <text class="detail-value">{{ row.verifyUserName || '-' }}</text>
+            </view>
+          </template>
+        </view>
+        <view class="action-buttons">
+          <template v-if="activeTab === 'ledger'">
+            <u-button size="small"
+                      class="action-btn fixed-btn"
+                      @click.stop="goLedgerEdit(row)">缂栬緫</u-button>
+            <u-button size="small"
+                      class="action-btn fixed-btn"
+                      type="primary"
+                      @click.stop="goInspectionAdd(row)">鍙戣捣宸℃</u-button>
+            <u-button size="small"
+                      class="action-btn fixed-btn"
+                      type="error"
+                      @click.stop="deleteLedger(row)">鍒犻櫎</u-button>
+          </template>
+          <template v-else-if="activeTab === 'inspection'">
+            <u-button v-if="String(row.status) === '寰呭贰妫�'"
+                      size="small"
+                      class="action-btn fixed-btn"
+                      type="primary"
+                      @click.stop="goInspectionDo(row)">宸℃</u-button>
+            <u-button v-if="String(row.checkResult) === '寮傚父'"
+                      size="small"
+                      class="action-btn fixed-btn"
+                      type="success"
+                      @click.stop="goRectificationAdd(row)">鏁存敼</u-button>
+            <u-button size="small"
+                      class="action-btn fixed-btn"
+                      type="error"
+                      :disabled="String(row.status) !== '寰呭贰妫�'"
+                      @click.stop="deleteInspection(row)">鍒犻櫎</u-button>
+          </template>
+          <template v-else>
+            <u-button v-if="String(row.status) === '寰呮暣鏀�' || String(row.status) === '鏁存敼涓�'"
+                      size="small"
+                      class="action-btn fixed-btn"
+                      type="success"
+                      @click.stop="goRectificationDo(row)">鏁存敼</u-button>
+            <u-button v-if="String(row.status) === '宸叉暣鏀�'"
+                      size="small"
+                      class="action-btn fixed-btn"
+                      type="primary"
+                      @click.stop="goRectificationVerify(row)">楠屾敹</u-button>
+            <u-button size="small"
+                      class="action-btn fixed-btn"
+                      @click.stop="goRectificationView(row)">鏌ョ湅</u-button>
+          </template>
+        </view>
+      </view>
+      <up-loadmore :status="loadStatus" />
+    </scroll-view>
+    <view v-else
+          class="no-data">
+      <up-empty mode="data"
+                text="鏆傛棤鏁版嵁"></up-empty>
+    </view>
+    <view v-if="activeTab === 'ledger'"
+          class="fab-button"
+          @click="goLedgerAdd">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff"></up-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { computed, onMounted, reactive, ref } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    deleteFacilityInspection,
+    deleteFacilityLedger,
+    getFacilityInspectionList,
+    getFacilityLedgerList,
+    getFacilityRectificationList,
+  } from "@/api/safeProduction/safetyFacility";
+
+  const tabList = reactive([
+    { name: "璁炬柦鍙拌处", value: "ledger" },
+    { name: "璁炬柦宸℃", value: "inspection" },
+    { name: "鏁存敼璺熻釜", value: "rectification" },
+  ]);
+
+  const activeTabIndex = ref(0);
+  const activeTab = computed(
+    () => tabList[activeTabIndex.value]?.value || "ledger"
+  );
+
+  const keyword = ref("");
+
+  const page = reactive({ current: 1, size: 10, total: 0 });
+  const list = ref([]);
+  const loadStatus = ref("loadmore");
+  const loading = ref(false);
+
+  const searchPlaceholder = computed(() => {
+    if (activeTab.value === "ledger") return "璁炬柦缂栧彿/璁炬柦鍚嶇О";
+    if (activeTab.value === "inspection") return "宸℃缂栧彿";
+    return "鐘舵�侊紙寰呮暣鏀�/鏁存敼涓�/宸叉暣鏀�/宸查獙鏀讹級";
+  });
+
+  const facilityStatusType = status => {
+    const map = { 姝e父: "success", 寮傚父: "error", 鎶ュ簾: "info" };
+    return map[status] || "info";
+  };
+  const rectStatusType = status => {
+    const map = {
+      寰呮暣鏀�: "error",
+      鏁存敼涓�: "warning",
+      宸叉暣鏀�: "success",
+      宸查獙鏀�: "info",
+    };
+    return map[status] || "info";
+  };
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const getCardTitle = row => {
+    if (activeTab.value === "ledger") return row.facilityName || "-";
+    if (activeTab.value === "inspection") return row.inspectionCode || "-";
+    return row.facilityName || "-";
+  };
+
+  const handleInspectionInfoClick = row => {
+    if (activeTab.value !== "inspection") return;
+    if (String(row?.status) === "寰呭贰妫�") return;
+    goInspectionView(row);
+  };
+
+  const resetAndQuery = () => {
+    page.current = 1;
+    page.total = 0;
+    list.value = [];
+    loadStatus.value = "loadmore";
+    fetchList();
+  };
+
+  const fetchList = () => {
+    if (loading.value) return;
+    loading.value = true;
+    loadStatus.value = "loading";
+
+    const reqPage = { current: page.current, size: page.size };
+    let req;
+    const kw = String(keyword.value || "").trim();
+    if (activeTab.value === "ledger") {
+      req = getFacilityLedgerList({
+        facilityCode: kw,
+        facilityName: kw,
+        ...reqPage,
+      });
+    } else if (activeTab.value === "inspection") {
+      req = getFacilityInspectionList({ inspectionCode: kw, ...reqPage });
+    } else {
+      req = getFacilityRectificationList({ status: kw, ...reqPage });
+    }
+
+    req
+      .then(res => {
+        const records = res?.data?.records || [];
+        const total = Number(res?.data?.total || 0);
+        page.total = total;
+        list.value = page.current === 1 ? records : [...list.value, ...records];
+        loadStatus.value =
+          list.value.length >= page.total ? "nomore" : "loadmore";
+      })
+      .catch(() => {
+        loadStatus.value = "loadmore";
+        uni.showToast({ title: "鍔犺浇澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  const handleSearch = () => {
+    resetAndQuery();
+  };
+
+  const loadMore = () => {
+    if (loadStatus.value !== "loadmore") return;
+    page.current++;
+    fetchList();
+  };
+
+  const onTabChange = val => {
+    activeTabIndex.value = val.index;
+    resetAndQuery();
+  };
+
+  const goLedgerAdd = () => {
+    uni.navigateTo({ url: "/pages/safeProduction/safetyFacility/ledgerEdit" });
+  };
+  const goLedgerEdit = row => {
+    const data = encodeURIComponent(JSON.stringify(row || {}));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/ledgerEdit?data=${data}`,
+    });
+  };
+  const goInspectionAdd = row => {
+    const data = encodeURIComponent(
+      JSON.stringify({ mode: "add", facility: row })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
+    });
+  };
+  const goInspectionDo = row => {
+    const data = encodeURIComponent(JSON.stringify({ mode: "do", row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
+    });
+  };
+  const goInspectionView = row => {
+    const data = encodeURIComponent(JSON.stringify({ mode: "view", row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
+    });
+  };
+  const goRectificationAdd = row => {
+    const data = encodeURIComponent(
+      JSON.stringify({ mode: "add", inspection: row })
+    );
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
+    });
+  };
+  const goRectificationDo = row => {
+    const data = encodeURIComponent(JSON.stringify({ mode: "do", row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
+    });
+  };
+  const goRectificationVerify = row => {
+    const data = encodeURIComponent(JSON.stringify({ mode: "verify", row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
+    });
+  };
+  const goRectificationView = row => {
+    const data = encodeURIComponent(JSON.stringify({ mode: "view", row }));
+    uni.navigateTo({
+      url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
+    });
+  };
+
+  const deleteLedger = row => {
+    if (!row?.id) return;
+    uni.showModal({
+      title: "鍒犻櫎",
+      content: "纭鍒犻櫎璇ヨ鏂藉悧锛�",
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "鍒犻櫎涓�...", mask: true });
+        deleteFacilityLedger([row.id])
+          .then(() => {
+            uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
+            resetAndQuery();
+          })
+          .catch(() => {
+            uni.showToast({ title: "鍒犻櫎澶辫触", icon: "none" });
+          })
+          .finally(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  const deleteInspection = row => {
+    if (!row?.id) return;
+    if (String(row.status) !== "寰呭贰妫�") return;
+    uni.showModal({
+      title: "鍒犻櫎",
+      content: "纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵",
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "鍒犻櫎涓�...", mask: true });
+        deleteFacilityInspection([row.id])
+          .then(() => {
+            uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
+            resetAndQuery();
+          })
+          .catch(() => {
+            uni.showToast({ title: "鍒犻櫎澶辫触", icon: "none" });
+          })
+          .finally(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  onMounted(() => {
+    uni.$on("safetyFacility:refresh", resetAndQuery);
+  });
+
+  onShow(() => {
+    resetAndQuery();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  .safety-facility {
+    min-height: 100vh;
+    background: #f8f9fa;
+    position: relative;
+    padding-bottom: 140rpx;
+  }
+
+  .tabs-section {
+    background: #fff;
+  }
+
+  .list-scroll {
+    flex: 1;
+    min-height: 0;
+  }
+
+  .action-buttons {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-end;
+    gap: 20rpx;
+    padding-bottom: 30rpx;
+  }
+
+  .fixed-btn {
+    width: 160rpx;
+    margin: 0 !important;
+  }
+
+  .fab-button {
+    position: fixed;
+    right: 30rpx;
+    bottom: 140rpx;
+    width: 96rpx;
+    height: 96rpx;
+    background: #3c9cff;
+    border-radius: 48rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-shadow: 0 8rpx 24rpx rgba(60, 156, 255, 0.3);
+    z-index: 1001;
+  }
+
+  .no-data {
+    padding-top: 200rpx;
+  }
+</style>
diff --git a/src/pages/safeProduction/safetyFacility/inspectionEdit.vue b/src/pages/safeProduction/safetyFacility/inspectionEdit.vue
new file mode 100644
index 0000000..af9a903
--- /dev/null
+++ b/src/pages/safeProduction/safetyFacility/inspectionEdit.vue
@@ -0,0 +1,262 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle"
+                @back="goBack" />
+    <up-form :model="form"
+             label-width="110">
+      <up-form-item label="璁炬柦鍚嶇О">
+        <up-input :model-value="facilityName"
+                  disabled
+                  placeholder="鑷姩甯﹀嚭" />
+      </up-form-item>
+      <up-form-item label="璁炬柦缂栧彿">
+        <up-input :model-value="facilityCode"
+                  disabled
+                  placeholder="鑷姩甯﹀嚭" />
+      </up-form-item>
+      <up-form-item label="宸℃缂栧彿"
+                    required>
+        <up-input v-model="form.inspectionCode"
+                  :disabled="isView"
+                  placeholder="璇疯緭鍏�"
+                  clearable />
+      </up-form-item>
+      <up-form-item label="宸℃绫诲瀷">
+        <up-input :model-value="form.inspectionType"
+                  placeholder="璇烽�夋嫨"
+                  readonly
+                  :disabled="isView"
+                  @click="openTypeSheet" />
+        <template #right>
+          <up-icon name="arrow-right"
+                   @click="openTypeSheet"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="璁″垝宸℃鏃堕棿">
+        <up-input :model-value="form.planTime"
+                  placeholder="璇烽�夋嫨"
+                  readonly
+                  :disabled="isView"
+                  @click="openPlanPicker" />
+        <template #right>
+          <up-icon name="arrow-right"
+                   @click="openPlanPicker"></up-icon>
+        </template>
+      </up-form-item>
+      <template v-if="mode === 'do' || mode === 'view'">
+        <up-form-item label="瀹為檯宸℃鏃堕棿">
+          <up-input :model-value="form.actualTime"
+                    disabled
+                    placeholder="鑷姩濉厖" />
+        </up-form-item>
+        <up-form-item label="妫�鏌ョ粨鏋�"
+                      :required="mode === 'do'">
+          <up-input :model-value="form.checkResult"
+                    placeholder="璇烽�夋嫨"
+                    readonly
+                    :disabled="isView"
+                    @click="openResultSheet" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="openResultSheet"></up-icon>
+          </template>
+        </up-form-item>
+        <up-form-item label="妫�鏌ヨ鏄�">
+          <up-textarea v-model="form.checkDesc"
+                       :disabled="isView"
+                       placeholder="璇疯緭鍏�"
+                       auto-height />
+        </up-form-item>
+      </template>
+    </up-form>
+    <FooterButtons :loading="loading"
+                   :confirmText="isView ? '杩斿洖' : '淇濆瓨'"
+                   @cancel="goBack"
+                   @confirm="handleSubmit" />
+    <up-action-sheet :show="showTypeSheet"
+                     title="閫夋嫨宸℃绫诲瀷"
+                     :actions="typeActions"
+                     @select="onSelectType"
+                     @close="showTypeSheet = false" />
+    <up-action-sheet :show="showResultSheet"
+                     title="閫夋嫨妫�鏌ョ粨鏋�"
+                     :actions="resultActions"
+                     @select="onSelectResult"
+                     @close="showResultSheet = false" />
+    <up-datetime-picker :show="showPlanPicker"
+                        mode="datetime"
+                        :value="planValue"
+                        @confirm="onPlanConfirm"
+                        @cancel="showPlanPicker = false" />
+  </view>
+</template>
+
+<script setup>
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import dayjs from "dayjs";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import {
+    addFacilityInspection,
+    updateFacilityInspection,
+  } from "@/api/safeProduction/safetyFacility";
+
+  const loading = ref(false);
+  const mode = ref("add");
+
+  const facilityName = ref("");
+  const facilityCode = ref("");
+
+  const form = ref({
+    id: null,
+    facilityId: null,
+    inspectionCode: "",
+    inspectionType: "瀹氭湡宸℃",
+    planTime: "",
+    checkResult: "",
+    checkDesc: "",
+    actualTime: "",
+    status: "",
+  });
+
+  const showTypeSheet = ref(false);
+  const showResultSheet = ref(false);
+  const showPlanPicker = ref(false);
+
+  const typeActions = [
+    { name: "瀹氭湡宸℃", value: "瀹氭湡宸℃" },
+    { name: "涓存椂宸℃", value: "涓存椂宸℃" },
+  ];
+  const resultActions = [
+    { name: "姝e父", value: "姝e父" },
+    { name: "寮傚父", value: "寮傚父" },
+  ];
+
+  const isView = computed(() => mode.value === "view");
+
+  const pageTitle = computed(() => {
+    if (mode.value === "add") return "鍙戣捣宸℃";
+    if (mode.value === "do") return "宸℃";
+    return "鏌ョ湅宸℃";
+  });
+
+  const planValue = computed(() => {
+    if (!form.value.planTime) return Date.now();
+    const ts = dayjs(form.value.planTime).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const openTypeSheet = () => {
+    if (isView.value) return;
+    showTypeSheet.value = true;
+  };
+
+  const openPlanPicker = () => {
+    if (isView.value) return;
+    showPlanPicker.value = true;
+  };
+
+  const openResultSheet = () => {
+    if (isView.value) return;
+    showResultSheet.value = true;
+  };
+
+  const onSelectType = action => {
+    if (isView.value) return;
+    form.value.inspectionType = action.value;
+    showTypeSheet.value = false;
+  };
+
+  const onSelectResult = action => {
+    if (isView.value) return;
+    form.value.checkResult = action.value;
+    showResultSheet.value = false;
+  };
+
+  const onPlanConfirm = e => {
+    if (isView.value) return;
+    form.value.planTime = dayjs(e?.value).format("YYYY-MM-DD HH:mm:ss");
+    showPlanPicker.value = false;
+  };
+
+  const handleSubmit = () => {
+    if (isView.value) {
+      goBack();
+      return;
+    }
+
+    const inspectionCode = String(form.value.inspectionCode || "").trim();
+    if (!inspectionCode) {
+      uni.showToast({ title: "璇疯緭鍏ュ贰妫�缂栧彿", icon: "none" });
+      return;
+    }
+    if (!form.value.facilityId) {
+      uni.showToast({ title: "缂哄皯璁炬柦淇℃伅", icon: "none" });
+      return;
+    }
+    if (!form.value.planTime) {
+      uni.showToast({ title: "璇烽�夋嫨璁″垝宸℃鏃堕棿", icon: "none" });
+      return;
+    }
+    if (mode.value === "do") {
+      const checkResult = String(form.value.checkResult || "").trim();
+      if (!checkResult) {
+        uni.showToast({ title: "璇烽�夋嫨妫�鏌ョ粨鏋�", icon: "none" });
+        return;
+      }
+      form.value.status = "宸插贰妫�";
+      form.value.actualTime = dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss");
+    }
+
+    const payload = {
+      ...form.value,
+      inspectionCode,
+      checkDesc: String(form.value.checkDesc || "").trim(),
+    };
+
+    loading.value = true;
+    const api = payload.id ? updateFacilityInspection : addFacilityInspection;
+    api(payload)
+      .then(() => {
+        uni.showToast({ title: "鎿嶄綔鎴愬姛", icon: "success" });
+        uni.$emit("safetyFacility:refresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "鎿嶄綔澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        mode.value = obj.mode || "add";
+        if (obj.facility) {
+          const f = obj.facility;
+          form.value.facilityId = f.id;
+          facilityName.value = f.facilityName || "";
+          facilityCode.value = f.facilityCode || "";
+        }
+        if (obj.row) {
+          const r = obj.row;
+          form.value = { ...form.value, ...(r || {}) };
+          facilityName.value = r.facilityName || facilityName.value;
+          facilityCode.value = r.facilityCode || facilityCode.value;
+        }
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
diff --git a/src/pages/safeProduction/safetyFacility/ledgerEdit.vue b/src/pages/safeProduction/safetyFacility/ledgerEdit.vue
new file mode 100644
index 0000000..22a0dcb
--- /dev/null
+++ b/src/pages/safeProduction/safetyFacility/ledgerEdit.vue
@@ -0,0 +1,211 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="璁炬柦缂栧彿" required>
+        <up-input v-model="form.facilityCode" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="璁炬柦鍚嶇О" required>
+        <up-input v-model="form.facilityName" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="璁炬柦绫诲瀷" required>
+        <up-input :model-value="form.facilityType" placeholder="璇烽�夋嫨" readonly @click="showTypeSheet = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showTypeSheet = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="瑙勬牸鍨嬪彿">
+        <up-input v-model="form.facilitySpec" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="瀹夎浣嶇疆" required>
+        <up-input v-model="form.installLocation" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="瀹夎鏃堕棿">
+        <up-input :model-value="form.installTime" placeholder="璇烽�夋嫨" readonly @click="showInstallPicker = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showInstallPicker = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="鐢熶骇鏃ユ湡">
+        <up-input :model-value="form.productionDate" placeholder="璇烽�夋嫨" readonly @click="showProductionPicker = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showProductionPicker = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="鏈夋晥鏈�(澶�)">
+        <up-input v-model="form.validPeriod" type="number" placeholder="璇疯緭鍏�" clearable />
+      </up-form-item>
+      <up-form-item label="涓嬫妫�鏌ユ椂闂�">
+        <up-input :model-value="nextCheckTime" placeholder="鏍规嵁瀹夎鏃堕棿+鏈夋晥鏈熻嚜鍔ㄨ绠�" disabled />
+      </up-form-item>
+      <up-form-item label="鐘舵��">
+        <up-input :model-value="form.status" placeholder="璇烽�夋嫨" readonly @click="showStatusSheet = true" />
+        <template #right>
+          <up-icon name="arrow-right" @click="showStatusSheet = true"></up-icon>
+        </template>
+      </up-form-item>
+      <up-form-item label="澶囨敞">
+        <up-textarea v-model="form.remark" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+    </up-form>
+
+    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
+
+    <up-action-sheet :show="showTypeSheet" title="閫夋嫨璁炬柦绫诲瀷" :actions="typeActions" @select="onSelectType" @close="showTypeSheet = false" />
+    <up-action-sheet :show="showStatusSheet" title="閫夋嫨鐘舵��" :actions="statusActions" @select="onSelectStatus" @close="showStatusSheet = false" />
+
+    <up-datetime-picker :show="showInstallPicker" mode="date" :value="installValue" @confirm="onInstallConfirm" @cancel="showInstallPicker = false" />
+    <up-datetime-picker :show="showProductionPicker" mode="date" :value="productionValue" @confirm="onProductionConfirm" @cancel="showProductionPicker = false" />
+  </view>
+</template>
+
+<script setup>
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import dayjs from "dayjs";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import { addFacilityLedger, updateFacilityLedger } from "@/api/safeProduction/safetyFacility";
+
+  const loading = ref(false);
+
+  const form = ref({
+    id: null,
+    facilityCode: "",
+    facilityName: "",
+    facilityType: "",
+    facilitySpec: "",
+    installLocation: "",
+    installTime: "",
+    productionDate: "",
+    validPeriod: "",
+    nextCheckTime: "",
+    status: "姝e父",
+    remark: "",
+  });
+
+  const showTypeSheet = ref(false);
+  const showStatusSheet = ref(false);
+  const showInstallPicker = ref(false);
+  const showProductionPicker = ref(false);
+
+  const typeActions = [
+    { name: "娑堥槻鍣ㄦ潗", value: "娑堥槻鍣ㄦ潗" },
+    { name: "瀹夊叏璁惧", value: "瀹夊叏璁惧" },
+    { name: "闃叉姢鐢ㄥ搧", value: "闃叉姢鐢ㄥ搧" },
+    { name: "鐩戞帶璁惧", value: "鐩戞帶璁惧" },
+  ];
+  const statusActions = [
+    { name: "姝e父", value: "姝e父" },
+    { name: "寮傚父", value: "寮傚父" },
+    { name: "鎶ュ簾", value: "鎶ュ簾" },
+  ];
+
+  const pageTitle = computed(() => (form.value.id ? "缂栬緫璁炬柦" : "鏂板璁炬柦"));
+
+  const nextCheckTime = computed(() => {
+    const installTime = form.value.installTime;
+    const validPeriod = Number(form.value.validPeriod);
+    if (!installTime || !Number.isFinite(validPeriod) || validPeriod <= 0) return "";
+    const d = dayjs(installTime);
+    if (!d.isValid()) return "";
+    return d.add(validPeriod, "day").format("YYYY-MM-DD");
+  });
+
+  const installValue = computed(() => {
+    if (!form.value.installTime) return Date.now();
+    const ts = dayjs(form.value.installTime).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+  const productionValue = computed(() => {
+    if (!form.value.productionDate) return Date.now();
+    const ts = dayjs(form.value.productionDate).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const onSelectType = action => {
+    form.value.facilityType = action.value;
+    showTypeSheet.value = false;
+  };
+  const onSelectStatus = action => {
+    form.value.status = action.value;
+    showStatusSheet.value = false;
+  };
+
+  const onInstallConfirm = e => {
+    form.value.installTime = dayjs(e?.value).format("YYYY-MM-DD");
+    showInstallPicker.value = false;
+  };
+  const onProductionConfirm = e => {
+    form.value.productionDate = dayjs(e?.value).format("YYYY-MM-DD");
+    showProductionPicker.value = false;
+  };
+
+  const handleSubmit = () => {
+    const facilityCode = String(form.value.facilityCode || "").trim();
+    if (!facilityCode) {
+      uni.showToast({ title: "璇疯緭鍏ヨ鏂界紪鍙�", icon: "none" });
+      return;
+    }
+    const facilityName = String(form.value.facilityName || "").trim();
+    if (!facilityName) {
+      uni.showToast({ title: "璇疯緭鍏ヨ鏂藉悕绉�", icon: "none" });
+      return;
+    }
+    const facilityType = String(form.value.facilityType || "").trim();
+    if (!facilityType) {
+      uni.showToast({ title: "璇烽�夋嫨璁炬柦绫诲瀷", icon: "none" });
+      return;
+    }
+    const installLocation = String(form.value.installLocation || "").trim();
+    if (!installLocation) {
+      uni.showToast({ title: "璇疯緭鍏ュ畨瑁呬綅缃�", icon: "none" });
+      return;
+    }
+
+    const payload = {
+      ...form.value,
+      facilityCode,
+      facilityName,
+      facilityType,
+      facilitySpec: String(form.value.facilitySpec || "").trim(),
+      installLocation,
+      validPeriod: form.value.validPeriod === "" ? null : Number(form.value.validPeriod),
+      nextCheckTime: nextCheckTime.value || null,
+      remark: String(form.value.remark || "").trim(),
+    };
+
+    loading.value = true;
+    const api = payload.id ? updateFacilityLedger : addFacilityLedger;
+    api(payload)
+      .then(() => {
+        uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
+        uni.$emit("safetyFacility:refresh");
+        goBack();
+      })
+      .catch(() => {
+        uni.showToast({ title: "淇濆瓨澶辫触", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const row = JSON.parse(decodeURIComponent(options.data));
+        form.value = { ...form.value, ...(row || {}) };
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
+
diff --git a/src/pages/safeProduction/safetyFacility/rectificationEdit.vue b/src/pages/safeProduction/safetyFacility/rectificationEdit.vue
new file mode 100644
index 0000000..9eb6111
--- /dev/null
+++ b/src/pages/safeProduction/safetyFacility/rectificationEdit.vue
@@ -0,0 +1,281 @@
+<template>
+  <view class="account-detail">
+    <PageHeader :title="pageTitle" @back="goBack" />
+    <up-form :model="form" label-width="110">
+      <up-form-item label="璁炬柦鍚嶇О">
+        <up-input :model-value="facilityName" disabled placeholder="鑷姩甯﹀嚭" />
+      </up-form-item>
+
+      <template v-if="mode !== 'verify'">
+        <up-form-item label="闂鎻忚堪" :required="mode === 'add'">
+          <up-textarea v-model="form.problemDesc" :disabled="isReadOnlyProblem" placeholder="璇疯緭鍏�" auto-height />
+        </up-form-item>
+        <up-form-item label="闂绛夌骇" :required="mode === 'add'">
+          <up-input
+            :model-value="form.problemLevel"
+            placeholder="璇烽�夋嫨"
+            readonly
+            :disabled="isReadOnlyProblem"
+            @click="openLevelSheet"
+          />
+          <template #right>
+            <up-icon name="arrow-right" @click="openLevelSheet"></up-icon>
+          </template>
+        </up-form-item>
+        <up-form-item label="璁″垝鏁存敼鏃堕棿" :required="mode === 'add'">
+          <up-input
+            :model-value="form.planTime"
+            placeholder="璇烽�夋嫨"
+            readonly
+            :disabled="isReadOnlyProblem"
+            @click="openPlanPicker"
+          />
+          <template #right>
+            <up-icon name="arrow-right" @click="openPlanPicker"></up-icon>
+          </template>
+        </up-form-item>
+      </template>
+
+      <up-form-item v-if="mode === 'do'" label="鏁存敼璇存槑" required>
+        <up-textarea v-model="form.rectifyDesc" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+
+      <up-form-item v-if="mode === 'verify'" label="楠屾敹璇存槑" required>
+        <up-textarea v-model="form.verifyDesc" placeholder="璇疯緭鍏�" auto-height />
+      </up-form-item>
+
+      <template v-if="mode === 'view'">
+        <up-form-item label="鏁存敼璇存槑">
+          <up-textarea :model-value="form.rectifyDesc" disabled auto-height />
+        </up-form-item>
+        <up-form-item label="楠屾敹璇存槑">
+          <up-textarea :model-value="form.verifyDesc" disabled auto-height />
+        </up-form-item>
+      </template>
+    </up-form>
+
+    <FooterButtons :loading="loading" :confirmText="confirmText" @cancel="goBack" @confirm="handleSubmit" />
+
+    <up-action-sheet
+      :show="showLevelSheet"
+      title="閫夋嫨闂绛夌骇"
+      :actions="levelActions"
+      @select="onSelectLevel"
+      @close="showLevelSheet = false"
+    />
+    <up-datetime-picker
+      :show="showPlanPicker"
+      mode="datetime"
+      :value="planValue"
+      @confirm="onPlanConfirm"
+      @cancel="showPlanPicker = false"
+    />
+  </view>
+</template>
+
+<script setup>
+  import { computed, ref } from "vue";
+  import { onLoad } from "@dcloudio/uni-app";
+  import dayjs from "dayjs";
+  import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
+  import {
+    addFacilityRectification,
+    updateFacilityRectification,
+  } from "@/api/safeProduction/safetyFacility";
+
+  const loading = ref(false);
+  const mode = ref("add");
+  const facilityName = ref("");
+
+  const form = ref({
+    id: null,
+    inspectionId: null,
+    facilityId: null,
+    problemDesc: "",
+    problemLevel: "",
+    planTime: "",
+    rectifyDesc: "",
+    verifyDesc: "",
+    status: "",
+    actualTime: "",
+    verifyTime: "",
+  });
+
+  const showLevelSheet = ref(false);
+  const showPlanPicker = ref(false);
+
+  const levelActions = [
+    { name: "涓�鑸�", value: "涓�鑸�" },
+    { name: "閲嶅ぇ", value: "閲嶅ぇ" },
+  ];
+
+  const isReadOnlyProblem = computed(() => mode.value !== "add");
+
+  const pageTitle = computed(() => {
+    if (mode.value === "add") return "鏂板鏁存敼";
+    if (mode.value === "do") return "鏁存敼";
+    if (mode.value === "verify") return "楠屾敹";
+    return "鏌ョ湅鏁存敼";
+  });
+
+  const confirmText = computed(() => {
+    if (mode.value === "view") return "杩斿洖";
+    return "淇濆瓨";
+  });
+
+  const planValue = computed(() => {
+    if (!form.value.planTime) return Date.now();
+    const ts = dayjs(form.value.planTime).valueOf();
+    return Number.isFinite(ts) ? ts : Date.now();
+  });
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  const openLevelSheet = () => {
+    if (mode.value !== "add") return;
+    showLevelSheet.value = true;
+  };
+
+  const openPlanPicker = () => {
+    if (mode.value !== "add") return;
+    showPlanPicker.value = true;
+  };
+
+  const onSelectLevel = action => {
+    if (mode.value !== "add") return;
+    form.value.problemLevel = action.value;
+    showLevelSheet.value = false;
+  };
+
+  const onPlanConfirm = e => {
+    if (mode.value !== "add") return;
+    form.value.planTime = dayjs(e?.value).format("YYYY-MM-DD HH:mm:ss");
+    showPlanPicker.value = false;
+  };
+
+  const handleSubmit = () => {
+    if (mode.value === "view") {
+      goBack();
+      return;
+    }
+
+    if (mode.value === "add") {
+      if (!form.value.inspectionId || !form.value.facilityId) {
+        uni.showToast({ title: "缂哄皯宸℃淇℃伅", icon: "none" });
+        return;
+      }
+      const problemDesc = String(form.value.problemDesc || "").trim();
+      if (!problemDesc) {
+        uni.showToast({ title: "璇疯緭鍏ラ棶棰樻弿杩�", icon: "none" });
+        return;
+      }
+      const problemLevel = String(form.value.problemLevel || "").trim();
+      if (!problemLevel) {
+        uni.showToast({ title: "璇烽�夋嫨闂绛夌骇", icon: "none" });
+        return;
+      }
+      if (!form.value.planTime) {
+        uni.showToast({ title: "璇烽�夋嫨璁″垝鏁存敼鏃堕棿", icon: "none" });
+        return;
+      }
+      const payload = { ...form.value, problemDesc, problemLevel };
+      loading.value = true;
+      addFacilityRectification(payload)
+        .then(() => {
+          uni.showToast({ title: "鎿嶄綔鎴愬姛", icon: "success" });
+          uni.$emit("safetyFacility:refresh");
+          goBack();
+        })
+        .catch(() => {
+          uni.showToast({ title: "鎿嶄綔澶辫触", icon: "none" });
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+      return;
+    }
+
+    if (mode.value === "do") {
+      if (!form.value.id) return;
+      const rectifyDesc = String(form.value.rectifyDesc || "").trim();
+      if (!rectifyDesc) {
+        uni.showToast({ title: "璇疯緭鍏ユ暣鏀硅鏄�", icon: "none" });
+        return;
+      }
+      const payload = {
+        ...form.value,
+        rectifyDesc,
+        status: "宸叉暣鏀�",
+        actualTime: dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss"),
+      };
+      loading.value = true;
+      updateFacilityRectification(payload)
+        .then(() => {
+          uni.showToast({ title: "鎿嶄綔鎴愬姛", icon: "success" });
+          uni.$emit("safetyFacility:refresh");
+          goBack();
+        })
+        .catch(() => {
+          uni.showToast({ title: "鎿嶄綔澶辫触", icon: "none" });
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+      return;
+    }
+
+    if (mode.value === "verify") {
+      if (!form.value.id) return;
+      const verifyDesc = String(form.value.verifyDesc || "").trim();
+      if (!verifyDesc) {
+        uni.showToast({ title: "璇疯緭鍏ラ獙鏀惰鏄�", icon: "none" });
+        return;
+      }
+      const payload = {
+        ...form.value,
+        verifyDesc,
+        status: "宸查獙鏀�",
+        verifyTime: dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss"),
+      };
+      loading.value = true;
+      updateFacilityRectification(payload)
+        .then(() => {
+          uni.showToast({ title: "鎿嶄綔鎴愬姛", icon: "success" });
+          uni.$emit("safetyFacility:refresh");
+          goBack();
+        })
+        .catch(() => {
+          uni.showToast({ title: "鎿嶄綔澶辫触", icon: "none" });
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+    }
+  };
+
+  onLoad(options => {
+    if (options?.data) {
+      try {
+        const obj = JSON.parse(decodeURIComponent(options.data));
+        mode.value = obj.mode || "add";
+        if (obj.inspection) {
+          const ins = obj.inspection;
+          form.value.inspectionId = ins.id;
+          form.value.facilityId = ins.facilityId;
+          facilityName.value = ins.facilityName || "";
+        }
+        if (obj.row) {
+          form.value = { ...form.value, ...(obj.row || {}) };
+          facilityName.value = obj.row.facilityName || facilityName.value;
+        }
+      } catch (e) {}
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+</style>
diff --git a/src/pages/works.vue b/src/pages/works.vue
index c484e70..336d6ed 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -511,6 +511,14 @@
       label: "鐗圭璁惧绠$悊",
     },
     {
+      icon: "/static/images/icon/xunjianshangchuan.svg",
+      label: "绾胯矾宸℃",
+    },
+    {
+      icon: "/static/images/icon/xunjianshangchuan.svg",
+      label: "瀹夊叏璁炬柦宸℃",
+    },
+    {
       icon: "/static/images/icon/weixianyuan.svg",
       label: "鍗遍櫓婧愬彴璐�",
     },
@@ -944,6 +952,16 @@
           url: "/pages/safeProduction/specialEquipmentManagement/index",
         });
         break;
+      case "绾胯矾宸℃":
+        uni.navigateTo({
+          url: "/pages/safeProduction/lineInspection/index",
+        });
+        break;
+      case "瀹夊叏璁炬柦宸℃":
+        uni.navigateTo({
+          url: "/pages/safeProduction/safetyFacility/index",
+        });
+        break;
       case "鍗遍櫓婧愬彴璐�":
         uni.navigateTo({
           url: "/pages/safeProduction/hazardSourceLedger/index",

--
Gitblit v1.9.3