From ec00255aab24865cd785e181704e502354b9c8f6 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 13 三月 2026 13:52:49 +0800
Subject: [PATCH] Merge branch 'dev_KT' of http://114.132.189.42:9002/r/product-inventory-APP-before into dev_KT

---
 src/pages/inspectionManagement/components/formDia.vue |  549 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 549 insertions(+), 0 deletions(-)

diff --git a/src/pages/inspectionManagement/components/formDia.vue b/src/pages/inspectionManagement/components/formDia.vue
new file mode 100644
index 0000000..e44d91e
--- /dev/null
+++ b/src/pages/inspectionManagement/components/formDia.vue
@@ -0,0 +1,549 @@
+<template>
+  <u-popup :show="dialogVisitable"
+           mode="center"
+           :round="12"
+           :zIndex="900"
+           @close="cancel">
+    <view class="popup-content">
+      <view class="popup-title">{{ operationType === "add" ? "鏂板宸℃浠诲姟" : "缂栬緫宸℃浠诲姟" }}</view>
+      <view class="form-body">
+        <view class="form-item">
+          <text class="label">璁惧鍚嶇О</text>
+          <picker mode="selector"
+                  :range="deviceOptions"
+                  range-key="deviceName"
+                  :value="deviceIndex"
+                  @change="onDeviceChange">
+            <view class="picker-value">{{ form.taskName || "璇烽�夋嫨璁惧" }}</view>
+          </picker>
+        </view>
+        <view class="form-item">
+          <text class="label">宸℃浜�</text>
+          <view class="picker-value inspector-picker"
+                @click="openInspectorPopup">
+            <text>{{ inspectorText || "璇烽�夋嫨宸℃浜�" }}</text>
+            <u-icon name="arrow-right"
+                    size="14"
+                    color="#999" />
+          </view>
+          <view class="inspector-tags"
+                v-if="form.inspector?.length">
+            <view v-for="userId in form.inspector"
+                  :key="userId"
+                  class="inspector-tag"
+                  @click="toggleInspector(userId)">
+              <text>{{ getUserName(userId) }}</text>
+              <u-icon name="close"
+                      size="11"
+                      color="#1677ff" />
+            </view>
+          </view>
+        </view>
+        <view class="form-item">
+          <text class="label">澶囨敞</text>
+          <u-textarea v-model="form.remarks"
+                      placeholder="璇疯緭鍏ュ娉�"
+                      :height="80"
+                      count />
+        </view>
+        <view class="form-item">
+          <text class="label">浠诲姟棰戠巼</text>
+          <picker mode="selector"
+                  :range="frequencyOptions"
+                  range-key="label"
+                  :value="frequencyIndex"
+                  @change="onFrequencyChange">
+            <view class="picker-value">{{ currentFrequencyLabel || "璇烽�夋嫨浠诲姟棰戠巼" }}</view>
+          </picker>
+        </view>
+        <view class="form-item"
+              v-if="form.frequencyType === 'DAILY'">
+          <text class="label">鏃堕棿</text>
+          <picker mode="time"
+                  :value="form.frequencyDetail || '08:00'"
+                  @change="onDailyTimeChange">
+            <view class="picker-value">{{ form.frequencyDetail || "璇烽�夋嫨鏃堕棿" }}</view>
+          </picker>
+        </view>
+        <view class="form-item"
+              v-if="form.frequencyType === 'WEEKLY'">
+          <text class="label">姣忓懆鏃ユ湡</text>
+          <picker mode="selector"
+                  :range="weekOptions"
+                  range-key="label"
+                  :value="weekIndex"
+                  @change="onWeekChange">
+            <view class="picker-value">{{ currentWeekLabel || "璇烽�夋嫨鏄熸湡" }}</view>
+          </picker>
+        </view>
+        <view class="form-item"
+              v-if="form.frequencyType === 'WEEKLY'">
+          <text class="label">姣忓懆鏃堕棿</text>
+          <picker mode="time"
+                  :value="form.time || '08:00'"
+                  @change="onWeekTimeChange">
+            <view class="picker-value">{{ form.time || "璇烽�夋嫨鏃堕棿" }}</view>
+          </picker>
+        </view>
+        <view class="form-item"
+              v-if="form.frequencyType === 'MONTHLY'">
+          <text class="label">姣忔湀鏃ユ湡涓庢椂闂�</text>
+          <picker mode="date"
+                  fields="day"
+                  :value="monthlyDate"
+                  @change="onMonthlyDateChange">
+            <view class="picker-value">{{ monthlyDate || "璇烽�夋嫨鏃ユ湡" }}</view>
+          </picker>
+          <picker mode="time"
+                  :value="monthlyTime"
+                  @change="onMonthlyTimeChange">
+            <view class="picker-value">{{ monthlyTime || "璇烽�夋嫨鏃堕棿" }}</view>
+          </picker>
+        </view>
+      </view>
+      <view class="popup-footer">
+        <u-button @click="cancel">鍙栨秷</u-button>
+        <u-button type="primary"
+                  @click="submitForm">淇濆瓨</u-button>
+      </view>
+    </view>
+  </u-popup>
+  <u-popup :show="showInspectorPopup"
+           mode="bottom"
+           :round="16"
+           :zIndex="1100"
+           @close="closeInspectorPopup">
+    <view class="inspector-popup">
+      <view class="inspector-header">
+        <text class="inspector-title">閫夋嫨宸℃浜�</text>
+      </view>
+      <scroll-view scroll-y
+                   class="inspector-list">
+        <view v-for="item in userList"
+              :key="item.userId"
+              class="inspector-row"
+              @click="toggleInspector(item.userId)">
+          <text class="inspector-name">{{ item.nickName }}</text>
+          <u-icon v-if="form.inspector.includes(item.userId)"
+                  name="checkmark-circle-fill"
+                  color="#1677ff"
+                  size="20" />
+          <u-icon v-else
+                  name=""
+                  color="#d5d8de"
+                  size="20" />
+        </view>
+      </scroll-view>
+      <view class="inspector-footer">
+        <u-button @click="closeInspectorPopup">鍙栨秷</u-button>
+        <u-button type="primary"
+                  @click="confirmInspector">纭畾</u-button>
+      </view>
+    </view>
+  </u-popup>
+</template>
+
+<script setup>
+  import { computed, reactive, ref } from "vue";
+  import useUserStore from "@/store/modules/user";
+  import { addOrEditTimingTask } from "@/api/inspectionManagement/index.js";
+  import { userListNoPageByTenantId } from "@/api/system/user.js";
+  import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+
+  const emit = defineEmits(["closeDia"]);
+  const userStore = useUserStore();
+  const dialogVisitable = ref(false);
+  const operationType = ref("add");
+  const deviceOptions = ref([]);
+  const userList = ref([]);
+  const showInspectorPopup = ref(false);
+
+  const defaultForm = () => ({
+    id: undefined,
+    taskId: undefined,
+    taskName: "",
+    inspector: [],
+    inspectorIds: "",
+    remarks: "",
+    frequencyType: "",
+    frequencyDetail: "",
+    week: "",
+    time: "",
+    registrantId: undefined,
+  });
+
+  const form = reactive(defaultForm());
+
+  const frequencyOptions = [
+    { label: "姣忔棩", value: "DAILY" },
+    { label: "姣忓懆", value: "WEEKLY" },
+    { label: "姣忔湀", value: "MONTHLY" },
+  ];
+
+  const weekOptions = [
+    { label: "鍛ㄤ竴", value: "MON" },
+    { label: "鍛ㄤ簩", value: "TUE" },
+    { label: "鍛ㄤ笁", value: "WED" },
+    { label: "鍛ㄥ洓", value: "THU" },
+    { label: "鍛ㄤ簲", value: "FRI" },
+    { label: "鍛ㄥ叚", value: "SAT" },
+    { label: "鍛ㄦ棩", value: "SUN" },
+  ];
+
+  const monthlyDate = ref("");
+  const monthlyTime = ref("");
+
+  const deviceIndex = computed(() => {
+    const index = deviceOptions.value.findIndex(item => item.id === form.taskId);
+    return index >= 0 ? index : 0;
+  });
+
+  const frequencyIndex = computed(() => {
+    const index = frequencyOptions.findIndex(item => item.value === form.frequencyType);
+    return index >= 0 ? index : 0;
+  });
+
+  const weekIndex = computed(() => {
+    const index = weekOptions.findIndex(item => item.value === form.week);
+    return index >= 0 ? index : 0;
+  });
+
+  const currentFrequencyLabel = computed(() => {
+    return frequencyOptions.find(item => item.value === form.frequencyType)?.label || "";
+  });
+
+  const currentWeekLabel = computed(() => {
+    return weekOptions.find(item => item.value === form.week)?.label || "";
+  });
+
+  const inspectorText = computed(() => {
+    if (!form.inspector?.length) return "";
+    const nameMap = new Map(userList.value.map(item => [item.userId, item.nickName]));
+    return form.inspector.map(id => nameMap.get(id)).filter(Boolean).join("銆�");
+  });
+
+  const resetForm = () => {
+    Object.assign(form, defaultForm());
+    monthlyDate.value = "";
+    monthlyTime.value = "";
+    showInspectorPopup.value = false;
+  };
+
+  const loadBaseData = async () => {
+    const [userRes, deviceRes] = await Promise.all([
+      userListNoPageByTenantId(),
+      getDeviceLedger(),
+    ]);
+    userList.value = userRes?.data || [];
+    deviceOptions.value = deviceRes?.data || [];
+  };
+
+  const parseWeeklyDetail = detail => {
+    if (!detail || typeof detail !== "string" || !detail.includes(",")) return;
+    const [week, time] = detail.split(",");
+    form.week = week || "";
+    form.time = time || "";
+  };
+
+  const parseMonthlyDetail = detail => {
+    if (!detail || typeof detail !== "string" || !detail.includes(",")) return;
+    const [day, time] = detail.split(",");
+    if (day) monthlyDate.value = `${new Date().getFullYear()}-${new Date().getMonth() + 1 < 10 ? `0${new Date().getMonth() + 1}` : new Date().getMonth() + 1}-${day.padStart(2, "0")}`;
+    if (time) monthlyTime.value = time;
+  };
+
+  const setDeviceModel = id => {
+    const matched = deviceOptions.value.find(item => item.id === id);
+    if (matched) {
+      form.taskId = matched.id;
+      form.taskName = matched.deviceName;
+    }
+  };
+
+  const openDialog = async (type, row) => {
+    operationType.value = type;
+    dialogVisitable.value = true;
+    resetForm();
+    try {
+      await loadBaseData();
+      if (type === "edit" && row) {
+        Object.assign(form, {
+          ...defaultForm(),
+          ...row,
+          inspector: String(row.inspectorIds || "")
+            .split(",")
+            .map(item => Number(item))
+            .filter(Boolean),
+        });
+        if (form.frequencyType === "WEEKLY") parseWeeklyDetail(form.frequencyDetail);
+        if (form.frequencyType === "MONTHLY") parseMonthlyDetail(form.frequencyDetail);
+      }
+    } catch (error) {
+      uni.showToast({
+        title: "鍒濆鍖栧け璐�",
+        icon: "none",
+      });
+    }
+  };
+
+  const onDeviceChange = e => {
+    const index = Number(e?.detail?.value || 0);
+    const selected = deviceOptions.value[index];
+    if (!selected) return;
+    setDeviceModel(selected.id);
+  };
+
+  const getUserName = userId => {
+    const user = userList.value.find(item => item.userId === userId);
+    return user?.nickName || "";
+  };
+
+  const openInspectorPopup = () => {
+    showInspectorPopup.value = true;
+  };
+
+  const closeInspectorPopup = () => {
+    showInspectorPopup.value = false;
+  };
+
+  const toggleInspector = userId => {
+    if (form.inspector.includes(userId)) {
+      form.inspector = form.inspector.filter(id => id !== userId);
+    } else {
+      form.inspector = [...form.inspector, userId];
+    }
+  };
+
+  const confirmInspector = () => {
+    showInspectorPopup.value = false;
+  };
+
+  const onFrequencyChange = e => {
+    const index = Number(e?.detail?.value || 0);
+    const selected = frequencyOptions[index];
+    form.frequencyType = selected?.value || "";
+    form.frequencyDetail = "";
+    form.week = "";
+    form.time = "";
+    monthlyDate.value = "";
+    monthlyTime.value = "";
+  };
+
+  const onDailyTimeChange = e => {
+    form.frequencyDetail = e?.detail?.value || "";
+  };
+
+  const onWeekChange = e => {
+    const index = Number(e?.detail?.value || 0);
+    const selected = weekOptions[index];
+    form.week = selected?.value || "";
+  };
+
+  const onWeekTimeChange = e => {
+    form.time = e?.detail?.value || "";
+  };
+
+  const onMonthlyDateChange = e => {
+    monthlyDate.value = e?.detail?.value || "";
+  };
+
+  const onMonthlyTimeChange = e => {
+    monthlyTime.value = e?.detail?.value || "";
+  };
+
+  const validateForm = () => {
+    if (!form.taskId) {
+      uni.showToast({ title: "璇烽�夋嫨璁惧", icon: "none" });
+      return false;
+    }
+    if (!form.inspector.length) {
+      uni.showToast({ title: "璇烽�夋嫨宸℃浜�", icon: "none" });
+      return false;
+    }
+    if (!form.frequencyType) {
+      uni.showToast({ title: "璇烽�夋嫨浠诲姟棰戠巼", icon: "none" });
+      return false;
+    }
+    if (form.frequencyType === "DAILY" && !form.frequencyDetail) {
+      uni.showToast({ title: "璇烽�夋嫨鏃堕棿", icon: "none" });
+      return false;
+    }
+    if (form.frequencyType === "WEEKLY" && (!form.week || !form.time)) {
+      uni.showToast({ title: "璇烽�夋嫨姣忓懆鏃ユ湡鍜屾椂闂�", icon: "none" });
+      return false;
+    }
+    if (form.frequencyType === "MONTHLY" && (!monthlyDate.value || !monthlyTime.value)) {
+      uni.showToast({ title: "璇烽�夋嫨姣忔湀鏃ユ湡鍜屾椂闂�", icon: "none" });
+      return false;
+    }
+    return true;
+  };
+
+  const buildFrequencyDetail = () => {
+    if (form.frequencyType === "WEEKLY") return `${form.week},${form.time}`;
+    if (form.frequencyType === "MONTHLY") {
+      const day = monthlyDate.value.split("-")[2] || "";
+      return `${day},${monthlyTime.value}`;
+    }
+    return form.frequencyDetail;
+  };
+
+  const submitForm = async () => {
+    if (!validateForm()) return;
+    try {
+      const userInfo = await userStore.getInfo();
+      const payload = {
+        ...form,
+        inspectorIds: form.inspector.join(","),
+        frequencyDetail: buildFrequencyDetail(),
+        registrantId: userInfo?.user?.userId,
+      };
+      delete payload.inspector;
+      delete payload.week;
+      delete payload.time;
+      await addOrEditTimingTask(payload);
+      uni.showToast({
+        title: "鎻愪氦鎴愬姛",
+        icon: "success",
+      });
+      cancel();
+    } catch (error) {
+      uni.showToast({
+        title: "鎻愪氦澶辫触锛岃閲嶈瘯",
+        icon: "none",
+      });
+    }
+  };
+
+  const cancel = () => {
+    dialogVisitable.value = false;
+    resetForm();
+    emit("closeDia");
+  };
+
+  defineExpose({ openDialog });
+</script>
+
+<style scoped lang="scss">
+  :deep(.uni-picker-container) {
+    z-index: 1200 !important;
+  }
+
+  .popup-content {
+    width: 88vw;
+    max-height: 80vh;
+    background: #fff;
+    border-radius: 20rpx;
+    overflow: hidden;
+  }
+
+  .popup-title {
+    text-align: center;
+    font-size: 32rpx;
+    color: #1f1f1f;
+    font-weight: 600;
+    padding: 24rpx 20rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+  }
+
+  .form-body {
+    padding: 24rpx;
+    max-height: 56vh;
+    overflow-y: auto;
+  }
+
+  .form-item {
+    margin-bottom: 20rpx;
+  }
+
+  .label {
+    display: block;
+    margin-bottom: 10rpx;
+    font-size: 24rpx;
+    color: #666;
+  }
+
+  .picker-value {
+    min-height: 72rpx;
+    background: #f7f8fa;
+    border-radius: 12rpx;
+    padding: 0 20rpx;
+    display: flex;
+    align-items: center;
+    color: #333;
+    font-size: 26rpx;
+  }
+
+  .inspector-picker {
+    justify-content: space-between;
+  }
+
+  .inspector-tags {
+    display: flex;
+    flex-wrap: wrap;
+    margin-top: 10rpx;
+    gap: 10rpx;
+  }
+
+  .inspector-tag {
+    display: flex;
+    align-items: center;
+    gap: 8rpx;
+    background: #edf3ff;
+    color: #1677ff;
+    font-size: 22rpx;
+    border-radius: 999rpx;
+    padding: 6rpx 14rpx;
+  }
+
+  .popup-footer {
+    display: flex;
+    gap: 16rpx;
+    padding: 20rpx 24rpx 24rpx;
+    border-top: 1rpx solid #f0f0f0;
+  }
+
+  .inspector-popup {
+    background: #fff;
+    border-radius: 24rpx 24rpx 0 0;
+    overflow: hidden;
+    max-height: 70vh;
+    padding-bottom: env(safe-area-inset-bottom);
+  }
+
+  .inspector-header {
+    padding: 24rpx;
+    text-align: center;
+    border-bottom: 1rpx solid #f0f0f0;
+  }
+
+  .inspector-title {
+    color: #1f1f1f;
+    font-size: 30rpx;
+    font-weight: 600;
+  }
+
+  .inspector-list {
+    max-height: 46vh;
+    padding: 0 24rpx;
+  }
+
+  .inspector-row {
+    min-height: 82rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1rpx solid #f5f5f5;
+  }
+
+  .inspector-name {
+    font-size: 26rpx;
+    color: #333;
+  }
+
+  .inspector-footer {
+    display: flex;
+    gap: 16rpx;
+    padding: 20rpx 24rpx 24rpx;
+  }
+</style>

--
Gitblit v1.9.3