From 41de91c90854bc2794d4fe5383aa5fb64f464028 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 16 六月 2026 11:27:32 +0800
Subject: [PATCH] pro 1.平遥县盛达铸造厂部署修改
---
src/views/financialManagement/assets/fixedAssets.vue | 495 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 495 insertions(+), 0 deletions(-)
diff --git a/src/views/financialManagement/assets/fixedAssets.vue b/src/views/financialManagement/assets/fixedAssets.vue
new file mode 100644
index 0000000..95eb017
--- /dev/null
+++ b/src/views/financialManagement/assets/fixedAssets.vue
@@ -0,0 +1,495 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="璧勪骇缂栧彿:">
+ <el-input v-model="filters.assetCode" placeholder="璇疯緭鍏ヨ祫浜х紪鍙�" clearable style="width: 200px;" />
+ </el-form-item>
+ <el-form-item label="璧勪骇鍚嶇О:">
+ <el-input v-model="filters.assetName" placeholder="璇疯緭鍏ヨ祫浜у悕绉�" clearable style="width: 200px;" />
+ </el-form-item>
+ <el-form-item label="璧勪骇绫诲埆:">
+ <el-select v-model="filters.category" placeholder="璇烽�夋嫨绫诲埆" clearable style="width: 150px;">
+ <el-option label="鎴垮眿寤虹瓚" value="building" />
+ <el-option label="鏈哄櫒璁惧" value="machine" />
+ <el-option label="杩愯緭宸ュ叿" value="vehicle" />
+ <el-option label="鐢靛瓙璁惧" value="electronic" />
+ <el-option label="鍔炲叕瀹跺叿" value="furniture" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鐘舵��:">
+ <el-select v-model="filters.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px;">
+ <el-option label="鍦ㄧ敤" value="in_use" />
+ <el-option label="闂茬疆" value="idle" />
+ <el-option label="鎶ュ簾" value="scrapped" />
+ </el-select>
+ </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>
+ <el-statistic title="璧勪骇鍘熷�煎悎璁�" :value="totalOriginalValue" precision="2" prefix="楼" />
+ <el-statistic title="绱鎶樻棫鍚堣" :value="totalDepreciation" precision="2" prefix="楼" style="margin-left: 30px;" />
+ <el-statistic title="鍑�鍊煎悎璁�" :value="totalNetValue" precision="2" prefix="楼" style="margin-left: 30px;" />
+ </div>
+ <div>
+ <el-button type="primary" @click="add" icon="Plus">鏂板璧勪骇</el-button>
+ <el-button type="warning" @click="handleDepreciation" icon="Money">鎶樻棫璁℃彁</el-button>
+ <!-- <el-button @click="handleOut" icon="Download">瀵煎嚭</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"
+ >
+ <template #originalValue="{ row }">
+ <span class="text-primary">楼{{ formatMoney(row.originalValue) }}</span>
+ </template>
+ <template #accumulatedDepreciation="{ row }">
+ <span class="text-warning">楼{{ formatMoney(row.accumulatedDepreciation) }}</span>
+ </template>
+ <template #netValue="{ row }">
+ <span class="text-success">楼{{ formatMoney(row.netValue) }}</span>
+ </template>
+ <template #category="{ row }">
+ <el-tag>{{ getCategoryLabel(row.category) }}</el-tag>
+ </template>
+ <template #status="{ row }">
+ <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag>
+ </template>
+ <template #operation="{ row }">
+ <el-button type="primary" link @click="view(row)">鏌ョ湅</el-button>
+ <el-button type="primary" link @click="edit(row)">缂栬緫</el-button>
+ <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </PIMTable>
+ </div>
+
+ <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false">
+ <el-form :model="form" :rules="rules" :disabled="isView" ref="formRef" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璧勪骇缂栧彿" prop="assetCode">
+ <el-input v-model="form.assetCode" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璧勪骇鍚嶇О" prop="assetName">
+ <el-input v-model="form.assetName" placeholder="璇疯緭鍏ヨ祫浜у悕绉�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璧勪骇绫诲埆" prop="category">
+ <el-select v-model="form.category" placeholder="璇烽�夋嫨璧勪骇绫诲埆" style="width: 100%;">
+ <el-option label="鎴垮眿寤虹瓚" value="building" />
+ <el-option label="鏈哄櫒璁惧" value="machine" />
+ <el-option label="杩愯緭宸ュ叿" value="vehicle" />
+ <el-option label="鐢靛瓙璁惧" value="electronic" />
+ <el-option label="鍔炲叕瀹跺叿" value="furniture" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
+ <el-input v-model="form.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璐疆鏃ユ湡" prop="purchaseDate">
+ <el-date-picker v-model="form.purchaseDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璧勪骇鍘熷��" prop="originalValue">
+ <el-input-number v-model="form.originalValue" :min="0" :precision="2" style="width: 100%;" @change="calculateNetValue" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="浣跨敤骞撮檺" prop="usefulLife">
+ <el-input-number v-model="form.usefulLife" :min="1" :max="50" style="width: 100%;" />
+ <span style="margin-left: 10px;">骞�</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="娈嬪�肩巼" prop="residualRate">
+ <el-input-number v-model="form.residualRate" :min="0" :max="10" :precision="2" style="width: 100%;" />
+ <span style="margin-left: 10px;">%</span>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="绱鎶樻棫">
+ <el-input v-model="form.accumulatedDepreciation" disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璧勪骇鍑�鍊�">
+ <el-input v-model="form.netValue" disabled />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="瀛樻斁鍦扮偣" prop="location">
+ <el-input v-model="form.location" placeholder="璇疯緭鍏ュ瓨鏀惧湴鐐�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="浣跨敤閮ㄩ棬" prop="department">
+ <el-input v-model="form.department" placeholder="璇疯緭鍏ヤ娇鐢ㄩ儴闂�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="淇濈浜�" prop="keeper">
+ <el-input v-model="form.keeper" placeholder="璇疯緭鍏ヤ繚绠′汉" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐘舵��" prop="status">
+ <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%;">
+ <el-option label="鍦ㄧ敤" value="in_use" />
+ <el-option label="闂茬疆" value="idle" />
+ <el-option label="鎶ュ簾" value="scrapped" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker v-model="createTimeDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="澶囨敞" prop="remark">
+ <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button v-if="!isView" type="primary" @click="submitForm">纭畾</el-button>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ </template>
+ </FormDialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import dayjs from "dayjs";
+import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import {
+ listFixedAssetPage,
+ addFixedAsset,
+ updateFixedAsset,
+ deleteFixedAsset,
+ depreciateFixedAsset,
+} from "@/api/financialManagement/fixedAsset";
+
+defineOptions({
+ name: "鍥哄畾璧勪骇",
+});
+
+const filters = reactive({
+ assetCode: "",
+ assetName: "",
+ category: "",
+ status: "",
+});
+
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+});
+
+const columns = [
+ { label: "璧勪骇缂栧彿", prop: "assetCode", width: "130" },
+ { label: "璧勪骇鍚嶇О", prop: "assetName", width: "150" },
+ { label: "璧勪骇绫诲埆", prop: "category", dataType: "slot", slot: "category" },
+ { label: "瑙勬牸鍨嬪彿", prop: "specification", width: "120" },
+ { label: "璧勪骇鍘熷��", prop: "originalValue", dataType: "slot", slot: "originalValue" },
+ { label: "绱鎶樻棫", prop: "accumulatedDepreciation", dataType: "slot", slot: "accumulatedDepreciation" },
+ { label: "璧勪骇鍑�鍊�", prop: "netValue", dataType: "slot", slot: "netValue" },
+ { label: "鐘舵��", prop: "status", dataType: "slot", slot: "status" },
+ { label: "鎿嶄綔", prop: "operation", dataType: "slot", slot: "operation", width: "180", fixed: "right" },
+];
+
+const dataList = ref([]);
+const multipleList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const isView = ref(false);
+const currentId = ref(null);
+const selectedIds = computed(() =>
+ multipleList.value
+ .map(item => item?.id)
+ .filter(id => id !== undefined && id !== null && id !== "")
+);
+
+const createDefaultForm = () => ({
+ assetCode: "",
+ assetName: "",
+ category: "",
+ specification: "",
+ purchaseDate: "",
+ originalValue: 0,
+ usefulLife: 5,
+ residualRate: 5,
+ accumulatedDepreciation: 0,
+ netValue: 0,
+ location: "",
+ department: "",
+ keeper: "",
+ status: "in_use",
+ remark: "",
+ createTime: "",
+});
+
+const form = reactive({
+ ...createDefaultForm(),
+});
+const createTimeDate = computed({
+ get: () => (form.createTime ? String(form.createTime).split(" ")[0] : ""),
+ set: (value) => {
+ form.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
+ },
+});
+
+const rules = {
+ assetName: [{ required: true, message: "璇疯緭鍏ヨ祫浜у悕绉�", trigger: "blur" }],
+ category: [{ required: true, message: "璇烽�夋嫨璧勪骇绫诲埆", trigger: "change" }],
+ purchaseDate: [{ required: true, message: "璇烽�夋嫨璐疆鏃ユ湡", trigger: "change" }],
+ originalValue: [{ required: true, message: "璇疯緭鍏ヨ祫浜у師鍊�", trigger: "blur" }],
+ usefulLife: [{ required: true, message: "璇疯緭鍏ヤ娇鐢ㄥ勾闄�", trigger: "blur" }],
+};
+
+const totalOriginalValue = computed(() => {
+ return dataList.value.reduce((sum, item) => sum + Number(item.originalValue), 0);
+});
+
+const totalDepreciation = computed(() => {
+ return dataList.value.reduce((sum, item) => sum + Number(item.accumulatedDepreciation), 0);
+});
+
+const totalNetValue = computed(() => {
+ return dataList.value.reduce((sum, item) => sum + Number(item.netValue), 0);
+});
+
+const formatMoney = (value) => {
+ if (value === undefined || value === null) return "0.00";
+ return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getCategoryLabel = (category) => {
+ const map = {
+ building: "鎴垮眿寤虹瓚",
+ machine: "鏈哄櫒璁惧",
+ vehicle: "杩愯緭宸ュ叿",
+ electronic: "鐢靛瓙璁惧",
+ furniture: "鍔炲叕瀹跺叿",
+ };
+ return map[category] || category;
+};
+
+const getStatusLabel = (status) => {
+ const key = String(status || "").toLowerCase();
+ const map = { in_use: "鍦ㄧ敤", idle: "闂茬疆", repair: "缁翠慨涓�", scrapped: "鎶ュ簾" };
+ return map[key] || status;
+};
+
+const getStatusType = (status) => {
+ const key = String(status || "").toLowerCase();
+ const map = { in_use: "success", idle: "warning", repair: "warning", scrapped: "info" };
+ return map[key] || "";
+};
+
+const calculateNetValue = () => {
+ const originalValue = Number(form.originalValue || 0);
+ const accumulatedDepreciation = Number(form.accumulatedDepreciation || 0);
+ form.netValue = Number((originalValue - accumulatedDepreciation).toFixed(2));
+};
+
+// 鑱旇皟绾﹀畾锛氬垎椤靛弬鏁板浐瀹氫负 current/size锛岃繑鍥� data.records/data.total
+const getTableData = async () => {
+ try {
+ const { data } = await listFixedAssetPage({
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ assetCode: filters.assetCode,
+ assetName: filters.assetName,
+ category: filters.category,
+ status: filters.status,
+ });
+ dataList.value = data?.records || [];
+ multipleList.value = [];
+ pagination.total = Number(data?.total || 0);
+ } catch (error) {
+ // 鎻愮ず鐢卞叏灞�璇锋眰鎷︽埅鍣ㄥ鐞嗭紝杩欓噷浠呴槻姝㈡湭鎹曡幏寮傚父
+ }
+};
+
+const handleSelectionChange = (selectionList) => {
+ multipleList.value = selectionList;
+};
+
+const resetFilters = () => {
+ filters.assetCode = "";
+ filters.assetName = "";
+ filters.category = "";
+ filters.status = "";
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+const changePage = ({ current, size }) => {
+ pagination.currentPage = current;
+ pagination.pageSize = size;
+ getTableData();
+};
+
+const add = () => {
+ isEdit.value = false;
+ isView.value = false;
+ currentId.value = null;
+ dialogTitle.value = "鏂板鍥哄畾璧勪骇";
+ Object.assign(form, createDefaultForm(), {
+ purchaseDate: new Date().toISOString().split('T')[0],
+ createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+ });
+ dialogVisible.value = true;
+};
+
+const edit = (row) => {
+ isEdit.value = true;
+ isView.value = false;
+ currentId.value = row.id;
+ dialogTitle.value = "缂栬緫鍥哄畾璧勪骇";
+ Object.assign(form, createDefaultForm(), row);
+ dialogVisible.value = true;
+};
+
+const view = (row) => {
+ edit(row);
+ isView.value = true;
+};
+
+const handleDelete = (row) => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ュ浐瀹氳祫浜у悧锛�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(async () => {
+ // 鑱旇皟绾﹀畾锛氬垹闄ゆ帴鍙d娇鐢� ids=1&ids=2
+ await deleteFixedAsset([row.id]);
+ if (dataList.value.length === 1 && pagination.currentPage > 1) {
+ pagination.currentPage -= 1;
+ }
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ await getTableData();
+ });
+};
+
+const handleDepreciation = () => {
+ const ids = selectedIds.value;
+ const confirmText = ids.length
+ ? `纭瀵归�変腑鐨� ${ids.length} 鏉¤祫浜ц繘琛屾湰鏈堟姌鏃ц鎻愬悧锛焋
+ : "纭杩涜鏈湀鎶樻棫璁℃彁鍚楋紵";
+ ElMessageBox.confirm(confirmText, "鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "info",
+ }).then(async () => {
+ await depreciateFixedAsset({ ids });
+ ElMessage.success("鎶樻棫璁℃彁瀹屾垚");
+ await getTableData();
+ });
+};
+
+const handleOut = () => {
+ ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+ if (isView.value) {
+ dialogVisible.value = false;
+ return;
+ }
+ formRef.value.validate(async valid => {
+ if (valid) {
+ try {
+ calculateNetValue();
+ const payload = { ...form };
+ if (isEdit.value) {
+ payload.id = currentId.value;
+ await updateFixedAsset(payload);
+ ElMessage.success("缂栬緫鎴愬姛");
+ } else {
+ await addFixedAsset(payload);
+ ElMessage.success("鏂板鎴愬姛");
+ }
+ dialogVisible.value = false;
+ await getTableData();
+ } catch (error) {
+ // 鎻愮ず鐢卞叏灞�璇锋眰鎷︽埅鍣ㄥ鐞嗭紝杩欓噷浠呴槻姝㈡湭鎹曡幏寮傚父
+ }
+ }
+ });
+};
+
+onMounted(() => {
+ getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+
+ > div:first-child {
+ display: flex;
+ align-items: center;
+ }
+}
+
+.text-primary {
+ color: #409eff;
+ font-weight: bold;
+}
+
+.text-warning {
+ color: #e6a23c;
+ font-weight: bold;
+}
+
+.text-success {
+ color: #67c23a;
+ font-weight: bold;
+}
+</style>
--
Gitblit v1.9.3