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