From 8f9ff13bd611dea65751c6eebaccd4e292c4c0c6 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期三, 11 二月 2026 17:29:47 +0800
Subject: [PATCH] feat: 已进行开票、回款操作的销售台账需限制不能编辑删除原有产品

---
 src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue |  293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 293 insertions(+), 0 deletions(-)

diff --git a/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
new file mode 100644
index 0000000..1fd19f3
--- /dev/null
+++ b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
@@ -0,0 +1,293 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬鍜屾搷浣滄寜閽� -->
+    <div class="page-header">
+      <div class="title">鎵撳崱瑙勫垯閰嶇疆</div>
+      <div class="actions">
+        <el-button type="primary"
+                   @click="openForm('add')">
+          <el-icon>
+            <Plus />
+          </el-icon>
+          鏂板瑙勫垯
+        </el-button>
+      </div>
+    </div>
+    <!-- 鏌ヨ鏉′欢 -->
+    <!-- <el-form :model="searchForm"
+             :inline="true"
+             class="search-form mb16">
+      <el-form-item label="閮ㄩ棬锛�"
+                    prop="countId">
+        <el-tree-select v-model="searchForm.countId"
+                        :data="deptOptions"
+                        :props="{ value: 'id', label: 'label', children: 'children' }"
+                        value-key="id"
+                        placeholder="璇烽�夋嫨閮ㄩ棬"
+                        check-strictly
+                        style="width: 200px" />
+      </el-form-item>
+      <el-form-item label="鍦扮偣锛�"
+                    prop="locationName">
+        <el-input v-model="searchForm.locationName"
+                  placeholder="璇疯緭鍏ュ湴鐐瑰悕绉�"
+                  clearable
+                  style="width: 200px" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary"
+                   @click="fetchData">
+          <el-icon>
+            <Search />
+          </el-icon>
+          鎼滅储
+        </el-button>
+        <el-button @click="resetSearch">
+          <el-icon>
+            <Refresh />
+          </el-icon>
+          閲嶇疆
+        </el-button>
+      </el-form-item>
+    </el-form> -->
+    <!-- 瑙勫垯鍒楄〃 -->
+    <el-card shadow="never"
+             class="mb16">
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                style="width: 100%"
+                row-key="id">
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column label="閮ㄩ棬">
+          <template #default="scope">
+            {{ getDeptNameById(scope.row.sysDeptId) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="locationName"
+                         label="鍦扮偣鍚嶇О" />
+        <el-table-column prop="longitude"
+                         label="缁忓害" />
+        <el-table-column prop="latitude"
+                         label="绾害" />
+        <el-table-column prop="radius"
+                         label="鎵撳崱鑼冨洿(m)" />
+        <el-table-column prop="startAt"
+                         label="涓婄彮鏃堕棿">
+          <template #default="scope">
+            {{ scope.row.startAt }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="endAt"
+                         label="涓嬬彮鏃堕棿">
+          <template #default="scope">
+            {{ scope.row.endAt }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔"
+                         width="180"
+                         fixed="right"
+                         align="center">
+          <template #default="scope">
+            <el-button type="primary"
+                       size="small"
+                       link
+                       @click="openForm('edit', scope.row)">缂栬緫</el-button>
+            <el-button type="danger"
+                       size="small"
+                       link
+                       @click="handleDelete(scope.row.id)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :total="page.total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="paginationChange"
+                  class="mt10" />
+    </el-card>
+    <!-- 鏂板/缂栬緫瑙勫垯寮圭獥 -->
+    <rule-form ref="ruleFormRef"
+               v-model="dialogVisible"
+               :operation-type="operationType"
+               :row="currentRow"
+               @close="dialogVisible = false; fetchData()" />
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Plus, Edit, Delete, Search, Refresh } from "@element-plus/icons-vue";
+  import Pagination from "@/components/Pagination/index.vue";
+  import RuleForm from "./components/form.vue";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import {
+    getAttendanceRules,
+    deleteAttendanceRule,
+  } from "@/api/personnelManagement/attendanceRules.js";
+
+  const { proxy } = getCurrentInstance();
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉鍙傛暟
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 鏌ヨ琛ㄥ崟
+  const searchForm = reactive({
+    countId: "",
+    locationName: "",
+  });
+
+  // 閮ㄩ棬閫夐」
+  const deptOptions = ref([]);
+
+  // 寮圭獥鎺у埗
+  const dialogVisible = ref(false);
+  const operationType = ref("add");
+  const currentRow = ref({});
+  const ruleFormRef = ref();
+
+  // 鏍煎紡鍖栨椂闂�
+  const formatTime = timestamp => {
+    if (!timestamp) return "";
+    const date = new Date(timestamp);
+    return `${String(date.getHours()).padStart(2, "0")}:${String(
+      date.getMinutes()
+    ).padStart(2, "0")}`;
+  };
+
+  // 鑾峰彇閮ㄩ棬鍒楄〃
+  const fetchDeptOptions = () => {
+    deptTreeSelect().then(response => {
+      deptOptions.value = filterDisabledDept(
+        JSON.parse(JSON.stringify(response.data))
+      );
+    });
+  };
+
+  // 杩囨护绂佺敤鐨勯儴闂�
+  const filterDisabledDept = deptList => {
+    return deptList.filter(dept => {
+      if (dept.disabled) {
+        return false;
+      }
+      if (dept.children && dept.children.length) {
+        dept.children = filterDisabledDept(dept.children);
+      }
+      return true;
+    });
+  };
+
+  // 鏍规嵁閮ㄩ棬ID鏌ユ壘閮ㄩ棬鍚嶇О
+  const getDeptNameById = (deptId, deptList = deptOptions.value) => {
+    for (const dept of deptList) {
+      if (dept.id === deptId) {
+        return dept.label;
+      }
+      if (dept.children && dept.children.length) {
+        const name = getDeptNameById(deptId, dept.children);
+        if (name) {
+          return name;
+        }
+      }
+    }
+    return "";
+  };
+
+  // 鏌ヨ瑙勫垯鍒楄〃
+  const fetchData = () => {
+    tableLoading.value = true;
+    getAttendanceRules({ ...page, ...searchForm })
+      .then(res => {
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .finally(() => {
+        tableLoading.value = false;
+      });
+  };
+
+  // 鍒嗛〉鍙樻洿
+  const paginationChange = pagination => {
+    page.current = pagination.page;
+    page.size = pagination.limit;
+    fetchData();
+  };
+
+  // 閲嶇疆鎼滅储
+  const resetSearch = () => {
+    searchForm.countId = "";
+    searchForm.locationName = "";
+    fetchData();
+  };
+
+  // 鎵撳紑琛ㄥ崟
+  const openForm = (type, row = {}) => {
+    operationType.value = type;
+    currentRow.value = row;
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎瑙勫垯
+  const handleDelete = id => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ繖鏉¤鍒欏悧锛�", "鍒犻櫎纭", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        deleteAttendanceRule([id]).then(() => {
+          ElMessage.success("鍒犻櫎鎴愬姛");
+          fetchData();
+        });
+      })
+      .catch(() => {
+        // 鍙栨秷鍒犻櫎
+      });
+  };
+
+  // 鍒濆鍖�
+  onMounted(() => {
+    fetchDeptOptions();
+    fetchData();
+  });
+</script>
+
+<style scoped lang="scss">
+  .page-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+
+    .title {
+      font-size: 18px;
+      font-weight: 600;
+    }
+
+    .actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .mb16 {
+    margin-bottom: 16px;
+  }
+
+  .mt10 {
+    margin-top: 10px;
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.3