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