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