From c7b4b9a2f4c0f05aeb60a9e3f5fba5d9a3676f3f Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 18 八月 2025 16:22:42 +0800
Subject: [PATCH] 中强恒兴设备管理页面添加

---
 src/api/equipmentManagement/brand.js           |   92 +++++++++++++++
 src/views/equipmentManagement/brand/index.vue  |  217 ++++++++++++++++++++++++++++++++++++
 src/views/equipmentManagement/ledger/index.vue |   16 ++
 src/views/equipmentManagement/ledger/Form.vue  |   21 +++
 4 files changed, 346 insertions(+), 0 deletions(-)

diff --git a/src/api/equipmentManagement/brand.js b/src/api/equipmentManagement/brand.js
new file mode 100644
index 0000000..fd46a80
--- /dev/null
+++ b/src/api/equipmentManagement/brand.js
@@ -0,0 +1,92 @@
+// 璁惧鍝佺墝绠$悊 - 鏈湴鍋囨暟鎹� API锛堜娇鐢� localStorage 鎸佷箙鍖栵級
+
+const STORAGE_KEY = 'EQUIPMENT_BRANDS';
+
+function readStore() {
+  try {
+    const raw = localStorage.getItem(STORAGE_KEY);
+    if (raw) {
+      const parsed = JSON.parse(raw);
+      if (Array.isArray(parsed)) return parsed;
+    }
+  } catch (e) {
+    // ignore
+  }
+  // 鍒濆鍖栦竴浜涚ず渚嬫暟鎹�
+  const initial = [
+    { id: 1, name: '瑗块棬瀛�', country: '寰峰浗', description: '宸ヤ笟鑷姩鍖栦笌鐢垫皵宸ョ▼鍝佺墝', createdAt: Date.now() - 86400000 * 10 },
+    { id: 2, name: '鏂借�愬痉', country: '娉曞浗', description: '鑳芥簮绠$悊涓庤嚜鍔ㄥ寲', createdAt: Date.now() - 86400000 * 7 },
+    { id: 3, name: '涓夎彵鐢垫満', country: '鏃ユ湰', description: '鐢垫皵涓庤嚜鍔ㄥ寲璁惧', createdAt: Date.now() - 86400000 * 3 },
+  ];
+  localStorage.setItem(STORAGE_KEY, JSON.stringify(initial));
+  return initial;
+}
+
+function writeStore(list) {
+  localStorage.setItem(STORAGE_KEY, JSON.stringify(list));
+}
+
+function nextId(list) {
+  const maxId = list.reduce((max, item) => Math.max(max, Number(item.id) || 0), 0);
+  return maxId + 1;
+}
+
+export function getBrandPage(params = {}) {
+  const { current = 1, size = 10, name } = params;
+  const list = readStore();
+  let filtered = list;
+  if (name) {
+    const kw = String(name).trim();
+    filtered = filtered.filter((b) =>
+      (b.name && b.name.includes(kw)) || (b.country && b.country.includes(kw))
+    );
+  }
+  const start = (current - 1) * size;
+  const end = start + Number(size);
+  const records = filtered.slice(start, end);
+  return Promise.resolve({
+    code: 200,
+    data: {
+      total: filtered.length,
+      records,
+    },
+    msg: 'ok',
+  });
+}
+
+export function getBrandById(id) {
+  const list = readStore();
+  const item = list.find((i) => String(i.id) === String(id));
+  return Promise.resolve({ code: 200, data: item || null, msg: 'ok' });
+}
+
+export function addBrand(data) {
+  const list = readStore();
+  const item = { ...data };
+  item.id = nextId(list);
+  item.createdAt = Date.now();
+  list.unshift(item);
+  writeStore(list);
+  return Promise.resolve({ code: 200, data: item, msg: '鏂板鎴愬姛' });
+}
+
+export function editBrand(data) {
+  const list = readStore();
+  const index = list.findIndex((i) => String(i.id) === String(data.id));
+  if (index !== -1) {
+    list[index] = { ...list[index], ...data };
+    writeStore(list);
+    return Promise.resolve({ code: 200, data: list[index], msg: '淇敼鎴愬姛' });
+  }
+  return Promise.resolve({ code: 404, data: null, msg: '鏈壘鍒拌鍝佺墝' });
+}
+
+export function delBrand(idOrIds) {
+  const list = readStore();
+  const ids = Array.isArray(idOrIds) ? idOrIds.map(String) : [String(idOrIds)];
+  const newList = list.filter((i) => !ids.includes(String(i.id)));
+  writeStore(newList);
+  return Promise.resolve({ code: 200, data: null, msg: '鍒犻櫎鎴愬姛' });
+}
+
+
diff --git a/src/views/equipmentManagement/brand/index.vue b/src/views/equipmentManagement/brand/index.vue
new file mode 100644
index 0000000..6607cc8
--- /dev/null
+++ b/src/views/equipmentManagement/brand/index.vue
@@ -0,0 +1,217 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍝佺墝鍚嶇О/鍥藉">
+        <el-input
+          v-model="filters.name"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ュ叧閿瘝"
+          clearable
+          prefix-icon="Search"
+          @change="getTableData"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <div class="table_list">
+      <div class="actions">
+        <div></div>
+        <div>
+          <el-button type="primary" @click="openAdd" icon="Plus"> 鏂板 </el-button>
+          <el-button
+            type="danger"
+            icon="Delete"
+            :disabled="multipleSelection.length <= 0"
+            @click="handleBatchDelete"
+          >鎵归噺鍒犻櫎</el-button>
+        </div>
+      </div>
+
+      <PIMTable
+        rowKey="id"
+        isSelection
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @selection-change="handleSelectionChange"
+        @pagination="changePage"
+      >
+      </PIMTable>
+    </div>
+
+    <el-dialog v-model="visible" :title="dialogTitle" width="520px" destroy-on-close>
+      <el-form :model="form" ref="formRef" :rules="rules" label-width="90px">
+        <el-form-item label="鍝佺墝鍚嶇О" prop="name">
+          <el-input v-model="form.name" placeholder="璇疯緭鍏ュ搧鐗屽悕绉�" />
+        </el-form-item>
+        <el-form-item label="鎵�灞炲浗瀹�" prop="country">
+          <el-input v-model="form.country" placeholder="璇疯緭鍏ュ浗瀹�/鍦板尯" />
+        </el-form-item>
+        <el-form-item label="鎻忚堪" prop="description">
+          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="鍙~鍐欏搧鐗岀畝浠�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="visible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+  
+</template>
+
+<script setup>
+import { ref, getCurrentInstance, onMounted } from 'vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import { usePaginationApi } from '@/hooks/usePaginationApi'
+import { getBrandPage, addBrand, editBrand, delBrand } from '@/api/equipmentManagement/brand'
+
+defineOptions({ name: '璁惧鍝佺墝绠$悊' })
+
+const { proxy } = getCurrentInstance()
+
+const multipleSelection = ref([])
+const formRef = ref()
+const visible = ref(false)
+const dialogTitle = ref('鏂板鍝佺墝')
+const form = ref({ id: undefined, name: '', country: '', description: '' })
+
+const rules = {
+  name: [{ required: true, message: '璇疯緭鍏ュ搧鐗屽悕绉�', trigger: 'blur' }],
+  country: [{ required: true, message: '璇疯緭鍏ユ墍灞炲浗瀹�', trigger: 'blur' }]
+}
+
+const {
+  filters,
+  columns,
+  dataList,
+  pagination,
+  getTableData,
+  resetFilters,
+  onCurrentChange,
+} = usePaginationApi(
+  getBrandPage,
+  { name: undefined },
+  [
+    { label: '鍝佺墝鍚嶇О', align: 'center', prop: 'name' },
+    { label: '鎵�灞炲浗瀹�', align: 'center', prop: 'country' },
+    { label: '鎻忚堪', align: 'center', prop: 'description' },
+    { label: '鍒涘缓鏃堕棿', align: 'center', prop: 'createdAt' },
+    {
+      dataType: 'action',
+      label: '鎿嶄綔',
+      align: 'center',
+      fixed: 'right',
+      width: 140,
+      operation: [
+        {
+          name: '缂栬緫',
+          type: 'text',
+          clickFun: (row) => openEdit(row),
+        },
+        {
+          name: '鍒犻櫎',
+          type: 'text',
+          clickFun: (row) => handleDelete(row.id),
+        }
+      ]
+    }
+  ]
+)
+
+const handleSelectionChange = (list) => {
+  multipleSelection.value = list
+}
+
+const changePage = ({ page, limit }) => {
+  pagination.currentPage = page
+  pagination.pageSize = limit
+  onCurrentChange(page)
+}
+
+function resetForm() {
+  form.value = { id: undefined, name: '', country: '', description: '' }
+}
+
+function openAdd() {
+  resetForm()
+  dialogTitle.value = '鏂板鍝佺墝'
+  visible.value = true
+}
+
+function openEdit(row) {
+  form.value = { id: row.id, name: row.name, country: row.country, description: row.description }
+  dialogTitle.value = '缂栬緫鍝佺墝'
+  visible.value = true
+}
+
+function handleSubmit() {
+  formRef.value.validate(async (valid) => {
+    if (!valid) return
+    const isEdit = Boolean(form.value.id)
+    const api = isEdit ? editBrand : addBrand
+    const { code, msg } = await api({ ...form.value })
+    if (code === 200) {
+      ElMessage.success(isEdit ? '淇敼鎴愬姛' : '鏂板鎴愬姛')
+      visible.value = false
+      getTableData()
+    } else {
+      ElMessage.error(msg || '鎿嶄綔澶辫触')
+    }
+  })
+}
+
+function handleDelete(id) {
+  ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ搧鐗�, 鏄惁缁х画?', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning',
+  }).then(async () => {
+    const { code } = await delBrand(id)
+    if (code === 200) {
+      ElMessage.success('鍒犻櫎鎴愬姛')
+      getTableData()
+    }
+  })
+}
+
+function handleBatchDelete() {
+  if (multipleSelection.value.length === 0) return
+  ElMessageBox.confirm('灏嗗垹闄ら�変腑鐨勫搧鐗岋紝鏄惁缁х画锛�', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning',
+  }).then(async () => {
+    const ids = multipleSelection.value.map((i) => i.id)
+    const { code } = await delBrand(ids)
+    if (code === 200) {
+      ElMessage.success('鍒犻櫎鎴愬姛')
+      getTableData()
+    }
+  })
+}
+
+onMounted(() => {
+  getTableData()
+})
+
+</script>
+
+<style scoped lang="scss">
+.table_list { margin-top: unset; }
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+</style>
+
+
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index 0951fd8..108dbe4 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -12,13 +12,28 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
+        <el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
+          <el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
         <el-form-item label="渚涘簲鍟�" prop="supplierName">
           <el-input v-model="form.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
+        <el-form-item label="瀛樻斁浣嶇疆" prop="storageLocation">
+          <el-input v-model="form.storageLocation" placeholder="璇疯緭鍏ュ瓨鏀句綅缃�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
         <el-form-item label="鍗曚綅" prop="unit">
           <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
+          <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -133,7 +148,10 @@
 const { form, resetForm } = useFormData({
   deviceName: undefined, // 璁惧鍚嶇О
   deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  deviceBrand: undefined, // 璁惧鍝佺墝
   supplierName: undefined, // 渚涘簲鍟�
+  storageLocation: undefined, // 瀛樻斁浣嶇疆
+  enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
   unit: undefined, // 鍗曚綅
   number: undefined, // 鏁伴噺
   taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
@@ -152,7 +170,10 @@
   if (code == 200) {
     form.deviceName = data.deviceName;
     form.deviceModel = data.deviceModel;
+    form.deviceBrand = data.deviceBrand;
     form.supplierName = data.supplierName;
+    form.storageLocation = data.storageLocation;
+    form.enableDepreciation = data.enableDepreciation;
     form.unit = data.unit;
     form.number = data.number;
     form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 428a6d9..331cb37 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -146,6 +146,11 @@
       prop: "deviceModel",
     },
     {
+      label: "璁惧鍝佺墝",
+      align: "center",
+      prop: "deviceBrand",
+    },
+    {
       label: "渚涘簲鍟�",
       align: "center",
       prop: "supplierName",
@@ -154,6 +159,11 @@
       label: "鍗曚綅",
       align: "center",
       prop: "unit",
+    },
+    {
+      label: "瀛樻斁浣嶇疆",
+      align: "center",
+      prop: "storageLocation",
     },
     {
       label: "鏁伴噺",
@@ -181,6 +191,12 @@
       prop: "unTaxIncludingPriceTotal",
     },
     {
+      label: "鍚敤鎶樻棫",
+      align: "center",
+      prop: "enableDepreciation",
+      formatData: (v) => (v ? "鏄�" : "鍚�"),
+    },
+    {
       label: "褰曞叆浜�",
       align: "center",
       prop: "createUser",

--
Gitblit v1.9.3