gongchunyi
8 天以前 a798cdaa46f693eebabec6d999bfe32d055f4c48
src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
@@ -18,7 +18,7 @@
                        placeholder="请选择部门"
                        check-strictly
                        style="width: 100%"
                        :disabled="operationType === 'view'" />
                        :disabled="['edit', 'view'].includes(operationType)" />
      </el-form-item>
      <!-- 地点信息 -->
      <!-- <el-form-item label="地点名称"
@@ -28,8 +28,26 @@
                  :disabled="operationType === 'view'" />
      </el-form-item> -->
      <!-- 打卡范围 -->
      <el-form-item label="班次"
                    prop="shift">
        <el-select v-model="form.shift"
                   placeholder="请选择班次"
                   :disabled="operationType === 'view'"
                   style="width: 100%">
          <el-option v-for="item in shifts_list"
                     :key="item.value"
                     :label="item.label"
                     :value="item.value"
                     :disabled="
              operationType === 'add' &&
              (String(item.label || '').includes('假') ||
                String(item.label || '').includes('休'))
            " />
        </el-select>
      </el-form-item>
      <el-form-item label="打卡范围(m)"
                    prop="radius">
                    prop="radius"
                    v-show="!hideClockFields">
        <el-input-number v-model="form.radius"
                         :min="10"
                         :max="1000"
@@ -39,17 +57,18 @@
      </el-form-item>
      <!-- 高德地图选择 -->
      <el-form-item label="打卡位置"
                    prop="longitude">
                    prop="longitude"
                    v-show="!hideClockFields">
        <div class="map-container">
          <div class="map-header"
               style="margin-bottom: 10px">
            <el-button @click="getCurrentLocation">
            <!-- <el-button @click="getCurrentLocation">
              <el-icon>
                <Position />
              </el-icon>
              当前位置
            </el-button>
            <span style="margin-left: 10px; color: #909399;font-size: 12px;">点击地图选择位置</span>
            </el-button> -->
            <!-- <span style="margin-left: 10px; color: #909399;font-size: 12px;">点击地图选择位置</span> -->
          </div>
          <div id="map-container"
               class="map"
@@ -70,14 +89,16 @@
        </div>
      </el-form-item>
      <el-form-item label="地点名称"
                    prop="locationName">
                    prop="locationName"
                    v-show="!hideClockFields">
        <el-input v-model="form.locationName"
                  :disabled="operationType === 'view'"
                  placeholder="请输入地点名称" />
      </el-form-item>
      <!-- 上下班时间 -->
      <el-form-item label="上班时间"
                    prop="startAt">
                    prop="startAt"
                    v-show="!hideClockFields">
        <el-time-picker v-model="form.startAt"
                        format="HH:mm"
                        value-format="HH:mm"
@@ -85,7 +106,8 @@
                        :disabled="operationType === 'view'" />
      </el-form-item>
      <el-form-item label="下班时间"
                    prop="endAt">
                    prop="endAt"
                    v-show="!hideClockFields">
        <el-time-picker v-model="form.endAt"
                        format="HH:mm"
                        value-format="HH:mm"
@@ -98,12 +120,10 @@
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary"
                   @click="submitForm"
                   v-if="operationType !== 'view'">
          确定
        </el-button>
                   v-if="operationType !== 'view'">确定</el-button>
        <el-button @click="dialogVisible = false">取消</el-button>
      </span>
    </template>
  </el-dialog>
@@ -115,6 +135,7 @@
  import { Position } from "@element-plus/icons-vue";
  import { deptTreeSelect } from "@/api/system/user.js";
  import { addAttendanceRule } from "@/api/personnelManagement/attendanceRules.js";
  import { useDict } from "@/utils/dict";
  const props = defineProps({
    modelValue: {
@@ -140,9 +161,27 @@
  });
  const dialogTitle = computed(() => {
    if (props.operationType === "add") return "新增打卡规则";
    if (props.operationType === "edit") return "编辑打卡规则";
    return "查看打卡规则";
    if (props.operationType === "add") return "新增班次";
    if (props.operationType === "edit") return "编辑班次";
    return "查看班次";
  });
  // 获取班次字典值
  const { shifts_list } = useDict("shifts_list");
  const selectedShiftLabel = computed(() => {
    const item = shifts_list.value?.find(
      s => String(s.value) === String(form.shift)
    );
    return item?.label || "";
  });
  const hideClockFields = computed(() => {
    if (props.operationType === "view") return false;
    return (
      selectedShiftLabel.value.includes("假") ||
      selectedShiftLabel.value.includes("休")
    );
  });
  // 表单数据
@@ -156,41 +195,57 @@
    radius: 100,
    startAt: "09:00",
    endAt: "18:00",
    shift: "",
  });
  // 表单验证规则
  const rules = {
    sysDeptId: [{ required: true, message: "请选择部门", trigger: "change" }],
    locationName: [
      { required: true, message: "请输入地点名称", trigger: "blur" },
    ],
    longitude: [{ required: true, message: "请选择打卡位置", trigger: "blur" }],
    latitude: [{ required: true, message: "请选择打卡位置", trigger: "blur" }],
    radius: [{ required: true, message: "请输入打卡范围", trigger: "blur" }],
    startAt: [{ required: true, message: "请选择上班时间", trigger: "change" }],
    endAt: [
      { required: true, message: "请选择下班时间", trigger: "change" },
      {
        validator: (rule, value, callback) => {
          if (form.startAt && value) {
            const startParts = form.startAt.split(":");
            const endParts = value.split(":");
            const startTime =
              parseInt(startParts[0]) * 60 + parseInt(startParts[1]);
            const endTime = parseInt(endParts[0]) * 60 + parseInt(endParts[1]);
            if (endTime <= startTime) {
              callback(new Error("下班时间不能早于上班时间"));
  const rules = computed(() => {
    const base = {
      sysDeptId: [{ required: true, message: "请选择部门", trigger: "change" }],
      shift: [{ required: true, message: "请选择班次", trigger: "change" }],
    };
    if (hideClockFields.value) {
      return base;
    }
    return {
      ...base,
      locationName: [
        { required: true, message: "请输入地点名称", trigger: "blur" },
      ],
      longitude: [{ required: true, message: "请选择打卡位置", trigger: "blur" }],
      latitude: [{ required: true, message: "请选择打卡位置", trigger: "blur" }],
      radius: [{ required: true, message: "请输入打卡范围", trigger: "blur" }],
      startAt: [{ required: true, message: "请选择上班时间", trigger: "change" }],
      endAt: [
        { required: true, message: "请选择下班时间", trigger: "change" },
        {
          validator: (rule, value, callback) => {
            if (form.shift && ["夜班", "夜"].includes(form.shift)) {
              callback();
              return;
            }
            if (form.startAt && value) {
              const startParts = form.startAt.split(":");
              const endParts = value.split(":");
              const startTime =
                parseInt(startParts[0]) * 60 + parseInt(startParts[1]);
              const endTime = parseInt(endParts[0]) * 60 + parseInt(endParts[1]);
              if (endTime <= startTime) {
                callback(new Error("下班时间不能早于上班时间"));
              } else {
                callback();
              }
            } else {
              callback();
            }
          } else {
            callback();
          }
          },
          trigger: "change",
        },
        trigger: "change",
      },
    ],
  };
      ],
    };
  });
  // 部门选项
  const deptOptions = ref([]);
@@ -374,8 +429,8 @@
  watch(
    () => form.radius,
    newValue => {
      if (circle) {
        circle.setRadius(newValue);
      if (circle && newValue != null && newValue !== "") {
        circle.setRadius(Number(newValue));
      }
    }
  );
@@ -386,6 +441,29 @@
    () => {
      if (formRef.value && form.endAt) {
        formRef.value.validateField("endAt");
      }
    }
  );
  watch(
    () => hideClockFields.value,
    val => {
      if (!val) return;
      form.radius = null;
      form.longitude = "";
      form.latitude = "";
      form.locationName = "";
      form.startAt = "";
      form.endAt = "";
      if (formRef.value) {
        formRef.value.clearValidate([
          "radius",
          "longitude",
          "latitude",
          "locationName",
          "startAt",
          "endAt",
        ]);
      }
    }
  );
@@ -405,6 +483,7 @@
          radius: 100,
          startAt: "09:00",
          endAt: "18:00",
          shift: "",
        });
        // 如果是编辑或查看,填充数据
@@ -422,7 +501,9 @@
        // 初始化地图
        setTimeout(() => {
          initMap();
          if (!hideClockFields.value) {
            initMap();
          }
        }, 100);
      }
    }
@@ -493,4 +574,4 @@
  .mt8 {
    margin-top: 8px;
  }
</style>
</style>