From fca0461c6014fc7dd1b9848017fd3bbae3f8d7de Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 20 四月 2026 09:21:07 +0800
Subject: [PATCH] 进销存升级 1.财务模块前端页面(routerjs文件后面要回退)

---
 src/views/financialManagement/receivable/salesOut.vue       |  271 ++
 src/views/financialManagement/payable/payment.vue           |  376 +++
 src/views/financialManagement/generalLedger/index.vue       |  290 ++
 src/views/financialManagement/receivable/receipt.vue        |  355 +++
 src/views/financialManagement/voucher/index.vue             |  418 ++++
 src/views/financialManagement/receivable/invoiceApply.vue   |  358 +++
 src/router/index.js                                         |  113 +
 src/views/financialManagement/assets/fixedAssets.vue        |  461 ++++
 src/views/financialManagement/receivable/salesReturn.vue    |  305 +++
 src/views/financialManagement/payable/input-invoice.vue     |  404 ++++
 src/views/financialManagement/payable/paymentApply.vue      |  359 +++
 src/views/financialManagement/payable/reconciliation.vue    |  254 ++
 src/views/financialManagement/payable/purchaseIn.vue        |  331 +++
 src/views/financialManagement/assets/intangibleAssets.vue   |  457 ++++
 src/views/financialManagement/receivable/reconciliation.vue |  258 ++
 src/views/financialManagement/receivable/outputInvoice.vue  |  368 +++
 src/views/financialManagement/voucher/detailLedger.vue      |  289 ++
 src/views/financialManagement/voucher/generalLedger.vue     |  230 ++
 18 files changed, 5,897 insertions(+), 0 deletions(-)

diff --git a/src/router/index.js b/src/router/index.js
index f342004..52c31d4 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -119,6 +119,119 @@
       },
     ],
   },
+  // 璐㈠姟绠$悊妯″潡璺敱
+  {
+    path: "/financial",
+    component: Layout,
+    hidden: false,
+    redirect: "/financial/general-ledger",
+    alwaysShow: true,
+    meta: { title: "璐㈠姟绠$悊", icon: "money" },
+    children: [
+      {
+        path: "general-ledger",
+        component: () => import("@/views/financialManagement/generalLedger/index.vue"),
+        name: "GeneralLedger",
+        meta: { title: "鎬诲笎绉戠洰" }
+      },
+      {
+        path: "sales-out",
+        component: () => import("@/views/financialManagement/receivable/salesOut.vue"),
+        name: "SalesOut",
+        meta: { title: "閿�鍞嚭搴�" }
+      },
+      {
+        path: "sales-return",
+        component: () => import("@/views/financialManagement/receivable/salesReturn.vue"),
+        name: "SalesReturn",
+        meta: { title: "閿�鍞��璐�" }
+      },
+      {
+        path: "receivable-reconciliation",
+        component: () => import("@/views/financialManagement/receivable/reconciliation.vue"),
+        name: "ReceivableReconciliation",
+        meta: { title: "搴旀敹瀵硅处" }
+      },
+      {
+        path: "invoice-apply",
+        component: () => import("@/views/financialManagement/receivable/invoiceApply.vue"),
+        name: "InvoiceApply",
+        meta: { title: "寮�绁ㄧ敵璇�" }
+      },
+      {
+        path: "output-invoice",
+        component: () => import("@/views/financialManagement/receivable/outputInvoice.vue"),
+        name: "OutputInvoice",
+        meta: { title: "閿�椤瑰彂绁�" }
+      },
+      {
+        path: "receipt",
+        component: () => import("@/views/financialManagement/receivable/receipt.vue"),
+        name: "Receipt",
+        meta: { title: "鏀舵鍗�" }
+      },
+      {
+        path: "purchase-in",
+        component: () => import("@/views/financialManagement/payable/purchaseIn.vue"),
+        name: "PurchaseIn",
+        meta: { title: "閲囪喘鍏ュ簱" }
+      },
+      {
+        path: "payable-reconciliation",
+        component: () => import("@/views/financialManagement/payable/reconciliation.vue"),
+        name: "PayableReconciliation",
+        meta: { title: "搴斾粯瀵硅处" }
+      },
+      {
+        path: "input-invoice",
+        component: () => import("@/views/financialManagement/payable/input-invoice.vue"),
+        name: "InputInvoice",
+        meta: { title: "杩涢」鍙戠エ" }
+      },
+      {
+        path: "payment-apply",
+        component: () => import("@/views/financialManagement/payable/paymentApply.vue"),
+        name: "PaymentApply",
+        meta: { title: "浠樻鐢宠" }
+      },
+      {
+        path: "payment",
+        component: () => import("@/views/financialManagement/payable/payment.vue"),
+        name: "Payment",
+        meta: { title: "浠樻鍗�" }
+      },
+      {
+        path: "fixed-assets",
+        component: () => import("@/views/financialManagement/assets/fixedAssets.vue"),
+        name: "FixedAssets",
+        meta: { title: "鍥哄畾璧勪骇" }
+      },
+      {
+        path: "intangible-assets",
+        component: () => import("@/views/financialManagement/assets/intangibleAssets.vue"),
+        name: "IntangibleAssets",
+        meta: { title: "鏃犲舰璧勪骇" }
+      },
+      {
+        path: "voucher",
+        component: () => import("@/views/financialManagement/voucher/index.vue"),
+        name: "Voucher",
+        meta: { title: "鍑瘉" }
+      },
+      {
+        path: "voucher-general-ledger",
+        component: () => import("@/views/financialManagement/voucher/generalLedger.vue"),
+        name: "VoucherGeneralLedger",
+        meta: { title: "绉戠洰鎬诲笎" }
+      },
+      {
+        path: "voucher-detail-ledger",
+        component: () => import("@/views/financialManagement/voucher/detailLedger.vue"),
+        name: "VoucherDetailLedger",
+        meta: { title: "绉戠洰鏄庣粏甯�" }
+      }
+    ]
+  }
 ];
 
 // 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇
diff --git a/src/views/financialManagement/assets/fixedAssets.vue b/src/views/financialManagement/assets/fixedAssets.vue
new file mode 100644
index 0000000..1690a33
--- /dev/null
+++ b/src/views/financialManagement/assets/fixedAssets.vue
@@ -0,0 +1,461 @@
+<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"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @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>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" 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-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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+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", slot: "category" },
+  { label: "瑙勬牸鍨嬪彿", prop: "specification", width: "120" },
+  { label: "璧勪骇鍘熷��", prop: "originalValue", slot: "originalValue" },
+  { label: "绱鎶樻棫", prop: "accumulatedDepreciation", slot: "accumulatedDepreciation" },
+  { label: "璧勪骇鍑�鍊�", prop: "netValue", slot: "netValue" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "180", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const form = reactive({
+  assetCode: "",
+  assetName: "",
+  category: "",
+  specification: "",
+  purchaseDate: "",
+  originalValue: 0,
+  usefulLife: 5,
+  residualRate: 5,
+  accumulatedDepreciation: 0,
+  netValue: 0,
+  location: "",
+  department: "",
+  keeper: "",
+  status: "in_use",
+  remark: "",
+});
+
+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 mockData = [
+  { id: 1, assetCode: "GD2024001", assetName: "鍔炲叕鐢佃剳", category: "electronic", specification: "鑱旀兂ThinkPad X1", purchaseDate: "2023-01-15", originalValue: 8000, usefulLife: 5, residualRate: 5, accumulatedDepreciation: 1520, netValue: 6480, location: "鍔炲叕瀹�", department: "璐㈠姟閮�", keeper: "寮犱笁", status: "in_use", remark: "" },
+  { id: 2, assetCode: "GD2024002", assetName: "鎵撳嵃鏈�", category: "electronic", specification: "鎯犳櫘M479fdw", purchaseDate: "2023-03-20", originalValue: 3500, usefulLife: 5, residualRate: 5, accumulatedDepreciation: 532, netValue: 2968, location: "鏂囧嵃瀹�", department: "琛屾斂閮�", keeper: "鏉庡洓", status: "in_use", remark: "" },
+  { id: 3, assetCode: "GD2024003", assetName: "鍔炲叕妗屾", category: "furniture", specification: "瀹炴湪鍔炲叕妗�", purchaseDate: "2023-06-10", originalValue: 2500, usefulLife: 10, residualRate: 5, accumulatedDepreciation: 118.75, netValue: 2381.25, location: "鍔炲叕瀹�", department: "閿�鍞儴", keeper: "鐜嬩簲", status: "in_use", remark: "" },
+  { id: 4, assetCode: "GD2024004", assetName: "鍟嗗姟杞�", category: "vehicle", specification: "鍒厠GL8", purchaseDate: "2022-08-01", originalValue: 280000, usefulLife: 10, residualRate: 5, accumulatedDepreciation: 53200, netValue: 226800, location: "鍋滆溅鍦�", department: "琛屾斂閮�", keeper: "璧靛叚", status: "in_use", remark: "" },
+];
+
+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 map = { in_use: "鍦ㄧ敤", idle: "闂茬疆", scrapped: "鎶ュ簾" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { in_use: "success", idle: "warning", scrapped: "info" };
+  return map[status] || "";
+};
+
+const calculateNetValue = () => {
+  form.netValue = Number((form.originalValue - form.accumulatedDepreciation).toFixed(2));
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.assetCode) {
+    result = result.filter(item => item.assetCode.includes(filters.assetCode));
+  }
+  if (filters.assetName) {
+    result = result.filter(item => item.assetName.includes(filters.assetName));
+  }
+  if (filters.category) {
+    result = result.filter(item => item.category === filters.category);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+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;
+  dialogTitle.value = "鏂板鍥哄畾璧勪骇";
+  Object.assign(form, {
+    assetCode: "GD" + Date.now().toString().slice(-8),
+    assetName: "",
+    category: "",
+    specification: "",
+    purchaseDate: new Date().toISOString().split('T')[0],
+    originalValue: 0,
+    usefulLife: 5,
+    residualRate: 5,
+    accumulatedDepreciation: 0,
+    netValue: 0,
+    location: "",
+    department: "",
+    keeper: "",
+    status: "in_use",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍥哄畾璧勪骇";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅璧勪骇: ${row.assetName}`);
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ュ浐瀹氳祫浜у悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleDepreciation = () => {
+  ElMessageBox.confirm("纭杩涜鏈湀鎶樻棫璁℃彁鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    mockData.forEach(item => {
+      if (item.status === "in_use") {
+        const monthlyDepreciation = (item.originalValue * (1 - item.residualRate / 100)) / (item.usefulLife * 12);
+        item.accumulatedDepreciation = Number((item.accumulatedDepreciation + monthlyDepreciation).toFixed(2));
+        item.netValue = Number((item.originalValue - item.accumulatedDepreciation).toFixed(2));
+      }
+    });
+    ElMessage.success("鎶樻棫璁℃彁瀹屾垚");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      calculateNetValue();
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+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>
diff --git a/src/views/financialManagement/assets/intangibleAssets.vue b/src/views/financialManagement/assets/intangibleAssets.vue
new file mode 100644
index 0000000..f0b9af9
--- /dev/null
+++ b/src/views/financialManagement/assets/intangibleAssets.vue
@@ -0,0 +1,457 @@
+<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="patent" />
+          <el-option label="鍟嗘爣鏉�" value="trademark" />
+          <el-option label="钁椾綔鏉�" value="copyright" />
+          <el-option label="杞欢" value="software" />
+          <el-option label="鍦熷湴浣跨敤鏉�" value="land" />
+          <el-option label="鍏朵粬" value="other" />
+        </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="amortized" />
+        </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="totalAmortization" 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="handleAmortization" icon="Money">鎽婇攢璁℃彁</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #originalValue="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.originalValue) }}</span>
+        </template>
+        <template #accumulatedAmortization="{ row }">
+          <span class="text-warning">楼{{ formatMoney(row.accumulatedAmortization) }}</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>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" 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="patent" />
+                <el-option label="鍟嗘爣鏉�" value="trademark" />
+                <el-option label="钁椾綔鏉�" value="copyright" />
+                <el-option label="杞欢" value="software" />
+                <el-option label="鍦熷湴浣跨敤鏉�" value="land" />
+                <el-option label="鍏朵粬" value="other" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璇佷功缂栧彿" prop="certificateNo">
+              <el-input v-model="form.certificateNo" placeholder="璇疯緭鍏ヨ瘉涔︾紪鍙�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍙栧緱鏃ユ湡" prop="acquisitionDate">
+              <el-date-picker v-model="form.acquisitionDate" 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="amortizationPeriod">
+              <el-input-number v-model="form.amortizationPeriod" :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.accumulatedAmortization" 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="validityDate">
+              <el-date-picker v-model="form.validityDate" 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="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="amortized" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="璧勪骇鎻忚堪" prop="description">
+          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="璇疯緭鍏ヨ祫浜ф弿杩�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+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", slot: "category" },
+  { label: "璇佷功缂栧彿", prop: "certificateNo", width: "150" },
+  { label: "璧勪骇鍘熷��", prop: "originalValue", slot: "originalValue" },
+  { label: "绱鎽婇攢", prop: "accumulatedAmortization", slot: "accumulatedAmortization" },
+  { label: "璧勪骇鍑�鍊�", prop: "netValue", slot: "netValue" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "180", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const form = reactive({
+  assetCode: "",
+  assetName: "",
+  category: "",
+  certificateNo: "",
+  acquisitionDate: "",
+  originalValue: 0,
+  amortizationPeriod: 10,
+  residualRate: 0,
+  accumulatedAmortization: 0,
+  netValue: 0,
+  validityDate: "",
+  status: "in_use",
+  description: "",
+  remark: "",
+});
+
+const rules = {
+  assetName: [{ required: true, message: "璇疯緭鍏ヨ祫浜у悕绉�", trigger: "blur" }],
+  category: [{ required: true, message: "璇烽�夋嫨璧勪骇绫诲埆", trigger: "change" }],
+  acquisitionDate: [{ required: true, message: "璇烽�夋嫨鍙栧緱鏃ユ湡", trigger: "change" }],
+  originalValue: [{ required: true, message: "璇疯緭鍏ヨ祫浜у師鍊�", trigger: "blur" }],
+  amortizationPeriod: [{ required: true, message: "璇疯緭鍏ユ憡閿�骞撮檺", trigger: "blur" }],
+};
+
+const mockData = [
+  { id: 1, assetCode: "WX2024001", assetName: "ERP杞欢璁稿彲", category: "software", certificateNo: "SW-2023-001", acquisitionDate: "2023-01-01", originalValue: 50000, amortizationPeriod: 10, residualRate: 0, accumulatedAmortization: 5000, netValue: 45000, validityDate: "2033-01-01", status: "in_use", description: "浼佷笟璧勬簮璁″垝绠$悊绯荤粺", remark: "" },
+  { id: 2, assetCode: "WX2024002", assetName: "鍙戞槑涓撳埄", category: "patent", certificateNo: "ZL202210123456.7", acquisitionDate: "2022-06-15", originalValue: 100000, amortizationPeriod: 20, residualRate: 0, accumulatedAmortization: 3750, netValue: 96250, validityDate: "2042-06-15", status: "in_use", description: "涓�绉嶆柊鍨嬬敓浜у伐鑹�", remark: "" },
+  { id: 3, assetCode: "WX2024003", assetName: "鍟嗘爣鏉�", category: "trademark", certificateNo: "TM-2023-008", acquisitionDate: "2023-03-10", originalValue: 20000, amortizationPeriod: 10, residualRate: 0, accumulatedAmortization: 1500, netValue: 18500, validityDate: "2033-03-10", status: "in_use", description: "鍏徃鍝佺墝鍟嗘爣", remark: "" },
+  { id: 4, assetCode: "WX2024004", assetName: "鍦熷湴浣跨敤鏉�", category: "land", certificateNo: "鍦熷浗鐢�(2023)绗�001鍙�", acquisitionDate: "2023-07-01", originalValue: 500000, amortizationPeriod: 50, residualRate: 0, accumulatedAmortization: 5000, netValue: 495000, validityDate: "2073-07-01", status: "in_use", description: "宸ヤ笟鐢ㄥ湴浣跨敤鏉�", remark: "" },
+];
+
+const totalOriginalValue = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.originalValue), 0);
+});
+
+const totalAmortization = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.accumulatedAmortization), 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 = {
+    patent: "涓撳埄鏉�",
+    trademark: "鍟嗘爣鏉�",
+    copyright: "钁椾綔鏉�",
+    software: "杞欢",
+    land: "鍦熷湴浣跨敤鏉�",
+    other: "鍏朵粬",
+  };
+  return map[category] || category;
+};
+
+const getStatusLabel = (status) => {
+  const map = { in_use: "鍦ㄧ敤", idle: "闂茬疆", amortized: "宸叉憡閿�瀹屾瘯" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { in_use: "success", idle: "warning", amortized: "info" };
+  return map[status] || "";
+};
+
+const calculateNetValue = () => {
+  form.netValue = Number((form.originalValue - form.accumulatedAmortization).toFixed(2));
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.assetCode) {
+    result = result.filter(item => item.assetCode.includes(filters.assetCode));
+  }
+  if (filters.assetName) {
+    result = result.filter(item => item.assetName.includes(filters.assetName));
+  }
+  if (filters.category) {
+    result = result.filter(item => item.category === filters.category);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+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;
+  dialogTitle.value = "鏂板鏃犲舰璧勪骇";
+  Object.assign(form, {
+    assetCode: "WX" + Date.now().toString().slice(-8),
+    assetName: "",
+    category: "",
+    certificateNo: "",
+    acquisitionDate: new Date().toISOString().split('T')[0],
+    originalValue: 0,
+    amortizationPeriod: 10,
+    residualRate: 0,
+    accumulatedAmortization: 0,
+    netValue: 0,
+    validityDate: "",
+    status: "in_use",
+    description: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鏃犲舰璧勪骇";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅璧勪骇: ${row.assetName}`);
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ユ棤褰㈣祫浜у悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleAmortization = () => {
+  ElMessageBox.confirm("纭杩涜鏈湀鎽婇攢璁℃彁鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    mockData.forEach(item => {
+      if (item.status === "in_use") {
+        const monthlyAmortization = (item.originalValue * (1 - item.residualRate / 100)) / (item.amortizationPeriod * 12);
+        item.accumulatedAmortization = Number((item.accumulatedAmortization + monthlyAmortization).toFixed(2));
+        item.netValue = Number((item.originalValue - item.accumulatedAmortization).toFixed(2));
+        if (item.netValue <= 0) {
+          item.status = "amortized";
+          item.netValue = 0;
+        }
+      }
+    });
+    ElMessage.success("鎽婇攢璁℃彁瀹屾垚");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      calculateNetValue();
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+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>
diff --git a/src/views/financialManagement/generalLedger/index.vue b/src/views/financialManagement/generalLedger/index.vue
new file mode 100644
index 0000000..0b5d597
--- /dev/null
+++ b/src/views/financialManagement/generalLedger/index.vue
@@ -0,0 +1,290 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="绉戠洰缂栫爜:">
+        <el-input v-model="filters.subjectCode" placeholder="璇疯緭鍏ョ鐩紪鐮�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="绉戠洰鍚嶇О:">
+        <el-input v-model="filters.subjectName" placeholder="璇疯緭鍏ョ鐩悕绉�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="绉戠洰绫诲瀷:">
+        <el-select v-model="filters.subjectType" placeholder="璇烽�夋嫨" clearable style="width: 200px;">
+          <el-option label="璧勪骇绫�" value="asset" />
+          <el-option label="璐熷�虹被" value="liability" />
+          <el-option label="鏉冪泭绫�" value="equity" />
+          <el-option label="鎴愭湰绫�" value="cost" />
+          <el-option label="鎹熺泭绫�" value="profit_loss" />
+        </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></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #subjectType="{ row }">
+          <el-tag :type="getSubjectTypeType(row.subjectType)">{{ getSubjectTypeLabel(row.subjectType) }}</el-tag>
+        </template>
+        <template #balanceDirection="{ row }">
+          <el-tag :type="row.balanceDirection === 'debit' ? 'success' : 'danger'">
+            {{ row.balanceDirection === 'debit' ? '鍊熸柟' : '璐锋柟' }}
+          </el-tag>
+        </template>
+        <template #status="{ row }">
+          <el-tag :type="row.status === 'active' ? 'success' : 'info'">
+            {{ row.status === 'active' ? '鍚敤' : '绂佺敤' }}
+          </el-tag>
+        </template>
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="edit(row)">缂栬緫</el-button>
+          <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+        <el-form-item label="绉戠洰缂栫爜" prop="subjectCode">
+          <el-input v-model="form.subjectCode" placeholder="璇疯緭鍏ョ鐩紪鐮�" />
+        </el-form-item>
+        <el-form-item label="绉戠洰鍚嶇О" prop="subjectName">
+          <el-input v-model="form.subjectName" placeholder="璇疯緭鍏ョ鐩悕绉�" />
+        </el-form-item>
+        <el-form-item label="绉戠洰绫诲瀷" prop="subjectType">
+          <el-select v-model="form.subjectType" placeholder="璇烽�夋嫨绉戠洰绫诲瀷" style="width: 100%;">
+            <el-option label="璧勪骇绫�" value="asset" />
+            <el-option label="璐熷�虹被" value="liability" />
+            <el-option label="鏉冪泭绫�" value="equity" />
+            <el-option label="鎴愭湰绫�" value="cost" />
+            <el-option label="鎹熺泭绫�" value="profit_loss" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="浣欓鏂瑰悜" prop="balanceDirection">
+          <el-radio-group v-model="form.balanceDirection">
+            <el-radio label="debit">鍊熸柟</el-radio>
+            <el-radio label="credit">璐锋柟</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio label="active">鍚敤</el-radio>
+            <el-radio label="inactive">绂佺敤</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "鎬诲笎绉戠洰",
+});
+
+const filters = reactive({
+  subjectCode: "",
+  subjectName: "",
+  subjectType: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "绉戠洰缂栫爜", prop: "subjectCode", width: "120" },
+  { label: "绉戠洰鍚嶇О", prop: "subjectName", width: "150" },
+  { label: "绉戠洰绫诲瀷", prop: "subjectType", slot: "subjectType" },
+  { label: "浣欓鏂瑰悜", prop: "balanceDirection", slot: "balanceDirection" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "澶囨敞", prop: "remark", showOverflowTooltip: true },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "150", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const form = reactive({
+  subjectCode: "",
+  subjectName: "",
+  subjectType: "",
+  balanceDirection: "debit",
+  status: "active",
+  remark: "",
+});
+
+const rules = {
+  subjectCode: [{ required: true, message: "璇疯緭鍏ョ鐩紪鐮�", trigger: "blur" }],
+  subjectName: [{ required: true, message: "璇疯緭鍏ョ鐩悕绉�", trigger: "blur" }],
+  subjectType: [{ required: true, message: "璇烽�夋嫨绉戠洰绫诲瀷", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, subjectCode: "1001", subjectName: "搴撳瓨鐜伴噾", subjectType: "asset", balanceDirection: "debit", status: "active", remark: "" },
+  { id: 2, subjectCode: "1002", subjectName: "閾惰瀛樻", subjectType: "asset", balanceDirection: "debit", status: "active", remark: "" },
+  { id: 3, subjectCode: "1122", subjectName: "搴旀敹璐︽", subjectType: "asset", balanceDirection: "debit", status: "active", remark: "" },
+  { id: 4, subjectCode: "2202", subjectName: "搴斾粯璐︽", subjectType: "liability", balanceDirection: "credit", status: "active", remark: "" },
+  { id: 5, subjectCode: "4001", subjectName: "瀹炴敹璧勬湰", subjectType: "equity", balanceDirection: "credit", status: "active", remark: "" },
+  { id: 6, subjectCode: "5001", subjectName: "鐢熶骇鎴愭湰", subjectType: "cost", balanceDirection: "debit", status: "active", remark: "" },
+  { id: 7, subjectCode: "6001", subjectName: "涓昏惀涓氬姟鏀跺叆", subjectType: "profit_loss", balanceDirection: "credit", status: "active", remark: "" },
+  { id: 8, subjectCode: "6401", subjectName: "涓昏惀涓氬姟鎴愭湰", subjectType: "profit_loss", balanceDirection: "debit", status: "active", remark: "" },
+];
+
+const getSubjectTypeLabel = (type) => {
+  const map = {
+    asset: "璧勪骇绫�",
+    liability: "璐熷�虹被",
+    equity: "鏉冪泭绫�",
+    cost: "鎴愭湰绫�",
+    profit_loss: "鎹熺泭绫�",
+  };
+  return map[type] || type;
+};
+
+const getSubjectTypeType = (type) => {
+  const map = {
+    asset: "success",
+    liability: "danger",
+    equity: "warning",
+    cost: "info",
+    profit_loss: "primary",
+  };
+  return map[type] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.subjectCode) {
+    result = result.filter(item => item.subjectCode.includes(filters.subjectCode));
+  }
+  if (filters.subjectName) {
+    result = result.filter(item => item.subjectName.includes(filters.subjectName));
+  }
+  if (filters.subjectType) {
+    result = result.filter(item => item.subjectType === filters.subjectType);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.subjectCode = "";
+  filters.subjectName = "";
+  filters.subjectType = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板绉戠洰";
+  Object.assign(form, {
+    subjectCode: "",
+    subjectName: "",
+    subjectType: "",
+    balanceDirection: "debit",
+    status: "active",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫绉戠洰";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ョ鐩悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+</style>
diff --git a/src/views/financialManagement/payable/input-invoice.vue b/src/views/financialManagement/payable/input-invoice.vue
new file mode 100644
index 0000000..8258e96
--- /dev/null
+++ b/src/views/financialManagement/payable/input-invoice.vue
@@ -0,0 +1,404 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍙戠エ浠g爜:">
+        <el-input v-model="filters.invoiceCode" placeholder="璇疯緭鍏ュ彂绁ㄤ唬鐮�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="鍙戠エ鍙风爜:">
+        <el-input v-model="filters.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="渚涘簲鍟�:">
+        <el-select v-model="filters.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px;">
+          <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璁よ瘉鐘舵��:">
+        <el-select v-model="filters.certifyStatus" placeholder="璇烽�夋嫨璁よ瘉鐘舵��" clearable style="width: 150px;">
+          <el-option label="鏈璇�" value="uncertified" />
+          <el-option label="宸茶璇�" value="certified" />
+          <el-option label="璁よ瘉澶辫触" value="failed" />
+        </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-button type="success" @click="handleBatchCertify" icon="Check" :disabled="selectedRows.length === 0">鎵归噺璁よ瘉</el-button>
+        </div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">褰曞叆鍙戠エ</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 #amount="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #taxAmount="{ row }">
+          <span class="text-danger">楼{{ formatMoney(row.taxAmount) }}</span>
+        </template>
+        <template #totalAmount="{ row }">
+          <span class="text-success">楼{{ formatMoney(row.totalAmount) }}</span>
+        </template>
+        <template #certifyStatus="{ row }">
+          <el-tag :type="getCertifyStatusType(row.certifyStatus)">{{ getCertifyStatusLabel(row.certifyStatus) }}</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="success" link @click="handleCertify(row)" v-if="row.certifyStatus === 'uncertified'">璁よ瘉</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ浠g爜" prop="invoiceCode">
+              <el-input v-model="form.invoiceCode" placeholder="璇疯緭鍏ュ彂绁ㄤ唬鐮�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNo">
+              <el-input v-model="form.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟�" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%;">
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="寮�绁ㄦ棩鏈�" prop="invoiceDate">
+              <el-date-picker v-model="form.invoiceDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="閲戦(涓嶅惈绋�)" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" @change="calculateTax" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="绋庣巼" prop="taxRate">
+              <el-select v-model="form.taxRate" placeholder="璇烽�夋嫨绋庣巼" style="width: 100%;" @change="calculateTax">
+                <el-option label="0%" :value="0" />
+                <el-option label="3%" :value="3" />
+                <el-option label="6%" :value="6" />
+                <el-option label="9%" :value="9" />
+                <el-option label="13%" :value="13" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="绋庨">
+              <el-input v-model="form.taxAmount" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璁よ瘉鐘舵��" prop="certifyStatus">
+              <el-select v-model="form.certifyStatus" placeholder="璇烽�夋嫨璁よ瘉鐘舵��" style="width: 100%;" disabled>
+                <el-option label="鏈璇�" value="uncertified" />
+                <el-option label="宸茶璇�" value="certified" />
+                <el-option label="璁よ瘉澶辫触" value="failed" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璁よ瘉鏃ユ湡" prop="certifyDate">
+              <el-date-picker v-model="form.certifyDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍙戠エ鍐呭" prop="content">
+          <el-input v-model="form.content" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ彂绁ㄥ唴瀹�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "杩涢」鍙戠エ",
+});
+
+const filters = reactive({
+  invoiceCode: "",
+  invoiceNo: "",
+  supplierId: "",
+  certifyStatus: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鍙戠エ浠g爜", prop: "invoiceCode", width: "130" },
+  { label: "鍙戠エ鍙风爜", prop: "invoiceNo", width: "120" },
+  { label: "渚涘簲鍟�", prop: "supplierName", width: "180" },
+  { label: "寮�绁ㄦ棩鏈�", prop: "invoiceDate", width: "120" },
+  { label: "閲戦", prop: "amount", slot: "amount" },
+  { label: "绋庨", prop: "taxAmount", slot: "taxAmount" },
+  { label: "浠风◣鍚堣", prop: "totalAmount", slot: "totalAmount" },
+  { label: "璁よ瘉鐘舵��", prop: "certifyStatus", slot: "certifyStatus" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "180", fixed: "right" },
+];
+
+const dataList = ref([]);
+const selectedRows = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const supplierList = [
+  { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+  { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+  { id: 3, name: "骞垮窞鍖呰鏉愭枡鍘�" },
+  { id: 4, name: "娣卞湷浜旈噾閰嶄欢鍏徃" },
+];
+
+const form = reactive({
+  invoiceCode: "",
+  invoiceNo: "",
+  supplierId: "",
+  invoiceDate: "",
+  amount: 0,
+  taxRate: 13,
+  taxAmount: 0,
+  totalAmount: 0,
+  certifyStatus: "uncertified",
+  certifyDate: "",
+  content: "",
+  remark: "",
+});
+
+const rules = {
+  invoiceCode: [{ required: true, message: "璇疯緭鍏ュ彂绁ㄤ唬鐮�", trigger: "blur" }],
+  invoiceNo: [{ required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿鐮�", trigger: "blur" }],
+  supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+  invoiceDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur" }],
+  taxRate: [{ required: true, message: "璇烽�夋嫨绋庣巼", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, invoiceCode: "0440021001", invoiceNo: "12345678", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", invoiceDate: "2024-01-08", amount: 8000, taxRate: 13, taxAmount: 1040, totalAmount: 9040, certifyStatus: "certified", certifyDate: "2024-01-15", content: "鍘熸潗鏂欓噰璐�", remark: "" },
+  { id: 2, invoiceCode: "0440021002", invoiceNo: "87654321", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", invoiceDate: "2024-01-10", amount: 12000, taxRate: 13, taxAmount: 1560, totalAmount: 13560, certifyStatus: "uncertified", certifyDate: "", content: "鐢靛瓙鍏冨櫒浠�", remark: "" },
+  { id: 3, invoiceCode: "0440021003", invoiceNo: "11112222", supplierId: 3, supplierName: "骞垮窞鍖呰鏉愭枡鍘�", invoiceDate: "2024-01-12", amount: 3500, taxRate: 13, taxAmount: 455, totalAmount: 3955, certifyStatus: "certified", certifyDate: "2024-01-18", content: "鍖呰鏉愭枡", remark: "" },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const calculateTax = () => {
+  form.taxAmount = Number((form.amount * form.taxRate / 100).toFixed(2));
+  form.totalAmount = Number((form.amount + form.taxAmount).toFixed(2));
+};
+
+const getCertifyStatusLabel = (status) => {
+  const map = { uncertified: "鏈璇�", certified: "宸茶璇�", failed: "璁よ瘉澶辫触" };
+  return map[status] || status;
+};
+
+const getCertifyStatusType = (status) => {
+  const map = { uncertified: "info", certified: "success", failed: "danger" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.invoiceCode) {
+    result = result.filter(item => item.invoiceCode.includes(filters.invoiceCode));
+  }
+  if (filters.invoiceNo) {
+    result = result.filter(item => item.invoiceNo.includes(filters.invoiceNo));
+  }
+  if (filters.supplierId) {
+    result = result.filter(item => item.supplierId === filters.supplierId);
+  }
+  if (filters.certifyStatus) {
+    result = result.filter(item => item.certifyStatus === filters.certifyStatus);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.invoiceCode = "";
+  filters.invoiceNo = "";
+  filters.supplierId = "";
+  filters.certifyStatus = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "褰曞叆鍙戠エ";
+  Object.assign(form, {
+    invoiceCode: "",
+    invoiceNo: "",
+    supplierId: "",
+    invoiceDate: new Date().toISOString().split('T')[0],
+    amount: 0,
+    taxRate: 13,
+    taxAmount: 0,
+    totalAmount: 0,
+    certifyStatus: "uncertified",
+    certifyDate: "",
+    content: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍙戠エ";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鍙戠エ: ${row.invoiceCode}-${row.invoiceNo}`);
+};
+
+const handleCertify = (row) => {
+  ElMessageBox.confirm("纭璁よ瘉璇ュ彂绁ㄥ悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].certifyStatus = "certified";
+      mockData[index].certifyDate = new Date().toISOString().split('T')[0];
+    }
+    ElMessage.success("璁よ瘉鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleBatchCertify = () => {
+  ElMessageBox.confirm(`纭鎵归噺璁よ瘉閫変腑鐨� ${selectedRows.value.length} 寮犲彂绁ㄥ悧锛焋, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    selectedRows.value.forEach(row => {
+      const index = mockData.findIndex(item => item.id === row.id);
+      if (index !== -1 && mockData[index].certifyStatus === "uncertified") {
+        mockData[index].certifyStatus = "certified";
+        mockData[index].certifyDate = new Date().toISOString().split('T')[0];
+      }
+    });
+    ElMessage.success("鎵归噺璁よ瘉鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const supplier = supplierList.find(item => item.id === form.supplierId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, supplierName: supplier?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, supplierName: supplier?.name });
+        ElMessage.success("褰曞叆鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+
+.text-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/payable/payment.vue b/src/views/financialManagement/payable/payment.vue
new file mode 100644
index 0000000..3ea0df8
--- /dev/null
+++ b/src/views/financialManagement/payable/payment.vue
@@ -0,0 +1,376 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="浠樻鍗曞彿:">
+        <el-input v-model="filters.paymentCode" placeholder="璇疯緭鍏ヤ粯娆惧崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="渚涘簲鍟�:">
+        <el-select v-model="filters.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px;">
+          <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="浠樻鏂瑰紡:">
+        <el-select v-model="filters.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" clearable style="width: 150px;">
+          <el-option label="閾惰杞处" value="bank_transfer" />
+          <el-option label="鐜伴噾" value="cash" />
+          <el-option label="鏀エ" value="check" />
+          <el-option label="姹囩エ" value="draft" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鐘舵��:">
+        <el-select v-model="filters.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px;">
+          <el-option label="寰呬粯娆�" value="pending" />
+          <el-option label="宸插畬鎴�" value="completed" />
+          <el-option label="宸插彇娑�" value="cancelled" />
+        </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="totalPaymentAmount" precision="2" prefix="楼" />
+        </div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板浠樻</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #amount="{ row }">
+          <span class="text-danger">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #paymentMethod="{ row }">
+          <el-tag>{{ getPaymentMethodLabel(row.paymentMethod) }}</el-tag>
+        </template>
+        <template #status="{ row }">
+          <el-tag :type="row.status === 'completed' ? 'success' : row.status === 'pending' ? 'warning' : 'info'">
+            {{ row.status === 'completed' ? '宸插畬鎴�' : row.status === 'pending' ? '寰呬粯娆�' : '宸插彇娑�' }}
+          </el-tag>
+        </template>
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="view(row)">鏌ョ湅</el-button>
+          <el-button type="primary" link @click="edit(row)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="success" link @click="handleComplete(row)" v-if="row.status === 'pending'">瀹屾垚</el-button>
+          <el-button type="danger" link @click="handleCancel(row)" v-if="row.status === 'pending'">鍙栨秷</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻鍗曞彿" prop="paymentCode">
+              <el-input v-model="form.paymentCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏宠仈鐢宠鍗�" prop="applyCode">
+              <el-select v-model="form.applyCode" placeholder="璇烽�夋嫨鍏宠仈鐢宠鍗�" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in applyList" :key="item.applyCode" :label="item.applyCode" :value="item.applyCode" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟�" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浠樻鏃ユ湡" prop="paymentDate">
+              <el-date-picker v-model="form.paymentDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻閲戦" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
+              <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%;">
+                <el-option label="閾惰杞处" value="bank_transfer" />
+                <el-option label="鐜伴噾" value="cash" />
+                <el-option label="鏀エ" value="check" />
+                <el-option label="姹囩エ" value="draft" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閾惰璐﹀彿" prop="bankAccount" v-if="form.paymentMethod === 'bank_transfer'">
+              <el-input v-model="form.bankAccount" placeholder="璇疯緭鍏ラ摱琛岃处鍙�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="寮�鎴疯" prop="bankName" v-if="form.paymentMethod === 'bank_transfer'">
+              <el-input v-model="form.bankName" placeholder="璇疯緭鍏ュ紑鎴疯" />
+            </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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "浠樻鍗�",
+});
+
+const filters = reactive({
+  paymentCode: "",
+  supplierId: "",
+  paymentMethod: "",
+  status: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "浠樻鍗曞彿", prop: "paymentCode", width: "150" },
+  { label: "鍏宠仈鐢宠鍗�", prop: "applyCode", width: "150" },
+  { label: "渚涘簲鍟�", prop: "supplierName", width: "180" },
+  { label: "浠樻鏃ユ湡", prop: "paymentDate", width: "120" },
+  { label: "浠樻閲戦", prop: "amount", slot: "amount" },
+  { label: "浠樻鏂瑰紡", prop: "paymentMethod", slot: "paymentMethod" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "澶囨敞", prop: "remark", showOverflowTooltip: true },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "220", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const supplierList = [
+  { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+  { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+  { id: 3, name: "骞垮窞鍖呰鏉愭枡鍘�" },
+  { id: 4, name: "娣卞湷浜旈噾閰嶄欢鍏徃" },
+];
+
+const applyList = [
+  { applyCode: "FK2024001", supplierId: 1, amount: 5000 },
+  { applyCode: "FK2024002", supplierId: 2, amount: 8000 },
+  { applyCode: "FK2024003", supplierId: 3, amount: 3000 },
+];
+
+const form = reactive({
+  paymentCode: "",
+  applyCode: "",
+  supplierId: "",
+  paymentDate: "",
+  amount: 0,
+  paymentMethod: "bank_transfer",
+  bankAccount: "",
+  bankName: "",
+  remark: "",
+});
+
+const rules = {
+  applyCode: [{ required: true, message: "璇烽�夋嫨鍏宠仈鐢宠鍗�", trigger: "change" }],
+  supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+  paymentDate: [{ required: true, message: "璇烽�夋嫨浠樻鏃ユ湡", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ヤ粯娆鹃噾棰�", trigger: "blur" }],
+  paymentMethod: [{ required: true, message: "璇烽�夋嫨浠樻鏂瑰紡", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, paymentCode: "FKD2024001", applyCode: "FK2024001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", paymentDate: "2024-01-15", amount: 5000, paymentMethod: "bank_transfer", status: "completed", bankAccount: "6222021234567890123", bankName: "宸ュ晢閾惰", remark: "" },
+  { id: 2, paymentCode: "FKD2024002", applyCode: "FK2024002", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", paymentDate: "2024-01-18", amount: 8000, paymentMethod: "bank_transfer", status: "pending", bankAccount: "6222029876543210987", bankName: "寤鸿閾惰", remark: "" },
+  { id: 3, paymentCode: "FKD2024003", applyCode: "FK2024003", supplierId: 3, supplierName: "骞垮窞鍖呰鏉愭枡鍘�", paymentDate: "2024-01-20", amount: 3000, paymentMethod: "cash", status: "completed", remark: "" },
+];
+
+const totalPaymentAmount = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.amount), 0);
+});
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getPaymentMethodLabel = (method) => {
+  const map = {
+    bank_transfer: "閾惰杞处",
+    cash: "鐜伴噾",
+    check: "鏀エ",
+    draft: "姹囩エ",
+  };
+  return map[method] || method;
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.paymentCode) {
+    result = result.filter(item => item.paymentCode.includes(filters.paymentCode));
+  }
+  if (filters.supplierId) {
+    result = result.filter(item => item.supplierId === filters.supplierId);
+  }
+  if (filters.paymentMethod) {
+    result = result.filter(item => item.paymentMethod === filters.paymentMethod);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.paymentCode = "";
+  filters.supplierId = "";
+  filters.paymentMethod = "";
+  filters.status = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板浠樻";
+  Object.assign(form, {
+    paymentCode: "FKD" + Date.now().toString().slice(-8),
+    applyCode: "",
+    supplierId: "",
+    paymentDate: new Date().toISOString().split('T')[0],
+    amount: 0,
+    paymentMethod: "bank_transfer",
+    bankAccount: "",
+    bankName: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫浠樻";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅浠樻鍗�: ${row.paymentCode}`);
+};
+
+const handleComplete = (row) => {
+  ElMessageBox.confirm("纭璇ヤ粯娆惧崟宸插畬鎴愬悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "completed";
+    }
+    ElMessage.success("浠樻瀹屾垚");
+    getTableData();
+  });
+};
+
+const handleCancel = (row) => {
+  ElMessageBox.confirm("纭鍙栨秷璇ヤ粯娆惧崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "cancelled";
+    }
+    ElMessage.success("宸插彇娑�");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const supplier = supplierList.find(item => item.id === form.supplierId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, supplierName: supplier?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, supplierName: supplier?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/payable/paymentApply.vue b/src/views/financialManagement/payable/paymentApply.vue
new file mode 100644
index 0000000..82981d7
--- /dev/null
+++ b/src/views/financialManagement/payable/paymentApply.vue
@@ -0,0 +1,359 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鐢宠鍗曞彿:">
+        <el-input v-model="filters.applyCode" placeholder="璇疯緭鍏ョ敵璇峰崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="渚涘簲鍟�:">
+        <el-select v-model="filters.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px;">
+          <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鐘舵��:">
+        <el-select v-model="filters.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px;">
+          <el-option label="寰呭鎵�" value="pending" />
+          <el-option label="宸插鎵�" value="approved" />
+          <el-option label="宸查┏鍥�" value="rejected" />
+          <el-option label="宸蹭粯娆�" value="paid" />
+        </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></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板鐢宠</el-button>
+          <el-button @click="handleBatchApply" icon="Document" :disabled="selectedRows.length === 0">鎵归噺鐢宠</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 #amount="{ row }">
+          <span class="text-danger">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #paymentMethod="{ row }">
+          <el-tag>{{ getPaymentMethodLabel(row.paymentMethod) }}</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)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="success" link @click="handleAudit(row)" v-if="row.status === 'pending'">瀹℃壒</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐢宠鍗曞彿" prop="applyCode">
+              <el-input v-model="form.applyCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟�" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻閲戦" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
+              <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%;">
+                <el-option label="閾惰杞处" value="bank_transfer" />
+                <el-option label="鐜伴噾" value="cash" />
+                <el-option label="鏀エ" value="check" />
+                <el-option label="姹囩エ" value="draft" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐢宠鏃ユ湡" prop="applyDate">
+              <el-date-picker v-model="form.applyDate" 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="expectedDate">
+              <el-date-picker v-model="form.expectedDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍏宠仈鍏ュ簱鍗�" prop="relatedDocs">
+          <el-select v-model="form.relatedDocs" multiple placeholder="璇烽�夋嫨鍏宠仈鍏ュ簱鍗�" style="width: 100%;">
+            <el-option v-for="item in inList" :key="item.inCode" :label="item.inCode" :value="item.inCode" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="浠樻浜嬬敱" prop="reason">
+          <el-input v-model="form.reason" type="textarea" :rows="3" placeholder="璇疯緭鍏ヤ粯娆句簨鐢�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "浠樻鐢宠",
+});
+
+const filters = reactive({
+  applyCode: "",
+  supplierId: "",
+  status: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鐢宠鍗曞彿", prop: "applyCode", width: "150" },
+  { label: "渚涘簲鍟�", prop: "supplierName", width: "180" },
+  { label: "浠樻閲戦", prop: "amount", slot: "amount" },
+  { label: "浠樻鏂瑰紡", prop: "paymentMethod", slot: "paymentMethod" },
+  { label: "鐢宠鏃ユ湡", prop: "applyDate", width: "120" },
+  { label: "鏈熸湜浠樻鏃�", prop: "expectedDate", width: "120" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const selectedRows = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const supplierList = [
+  { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+  { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+  { id: 3, name: "骞垮窞鍖呰鏉愭枡鍘�" },
+  { id: 4, name: "娣卞湷浜旈噾閰嶄欢鍏徃" },
+];
+
+const inList = [
+  { inCode: "RK2024001", supplierId: 1 },
+  { inCode: "RK2024002", supplierId: 2 },
+  { inCode: "RK2024003", supplierId: 3 },
+];
+
+const form = reactive({
+  applyCode: "",
+  supplierId: "",
+  amount: 0,
+  paymentMethod: "bank_transfer",
+  applyDate: "",
+  expectedDate: "",
+  relatedDocs: [],
+  reason: "",
+  remark: "",
+});
+
+const rules = {
+  supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ヤ粯娆鹃噾棰�", trigger: "blur" }],
+  paymentMethod: [{ required: true, message: "璇烽�夋嫨浠樻鏂瑰紡", trigger: "change" }],
+  applyDate: [{ required: true, message: "璇烽�夋嫨鐢宠鏃ユ湡", trigger: "change" }],
+  expectedDate: [{ required: true, message: "璇烽�夋嫨鏈熸湜浠樻鏃ユ湡", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, applyCode: "FK2024001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", amount: 5000, paymentMethod: "bank_transfer", applyDate: "2024-01-12", expectedDate: "2024-01-15", status: "pending", relatedDocs: ["RK2024001"], reason: "鏀粯鍘熸潗鏂欒揣娆�", remark: "" },
+  { id: 2, applyCode: "FK2024002", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", amount: 8000, paymentMethod: "bank_transfer", applyDate: "2024-01-14", expectedDate: "2024-01-18", status: "approved", relatedDocs: ["RK2024002"], reason: "鏀粯鐢靛瓙鍏冨櫒浠惰揣娆�", remark: "" },
+  { id: 3, applyCode: "FK2024003", supplierId: 3, supplierName: "骞垮窞鍖呰鏉愭枡鍘�", amount: 3000, paymentMethod: "cash", applyDate: "2024-01-16", expectedDate: "2024-01-20", status: "paid", relatedDocs: ["RK2024003"], reason: "鏀粯鍖呰鏉愭枡璐ф", remark: "" },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getPaymentMethodLabel = (method) => {
+  const map = {
+    bank_transfer: "閾惰杞处",
+    cash: "鐜伴噾",
+    check: "鏀エ",
+    draft: "姹囩エ",
+  };
+  return map[method] || method;
+};
+
+const getStatusLabel = (status) => {
+  const map = { pending: "寰呭鎵�", approved: "宸插鎵�", rejected: "宸查┏鍥�", paid: "宸蹭粯娆�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { pending: "warning", approved: "success", rejected: "danger", paid: "primary" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.applyCode) {
+    result = result.filter(item => item.applyCode.includes(filters.applyCode));
+  }
+  if (filters.supplierId) {
+    result = result.filter(item => item.supplierId === filters.supplierId);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.applyCode = "";
+  filters.supplierId = "";
+  filters.status = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板浠樻鐢宠";
+  Object.assign(form, {
+    applyCode: "FK" + Date.now().toString().slice(-8),
+    supplierId: "",
+    amount: 0,
+    paymentMethod: "bank_transfer",
+    applyDate: new Date().toISOString().split('T')[0],
+    expectedDate: "",
+    relatedDocs: [],
+    reason: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫浠樻鐢宠";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鐢宠鍗�: ${row.applyCode}`);
+};
+
+const handleAudit = (row) => {
+  ElMessageBox.confirm("纭瀹℃壒閫氳繃璇ヤ粯娆剧敵璇峰悧锛�", "鎻愮ず", {
+    confirmButtonText: "閫氳繃",
+    cancelButtonText: "椹冲洖",
+    distinguishCancelAndClose: true,
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "approved";
+    }
+    ElMessage.success("瀹℃壒閫氳繃");
+    getTableData();
+  }).catch((action) => {
+    if (action === "cancel") {
+      const index = mockData.findIndex(item => item.id === row.id);
+      if (index !== -1) {
+        mockData[index].status = "rejected";
+      }
+      ElMessage.warning("宸查┏鍥�");
+      getTableData();
+    }
+  });
+};
+
+const handleBatchApply = () => {
+  ElMessage.success(`鎵归噺鐢宠 ${selectedRows.value.length} 鏉¤褰昤);
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const supplier = supplierList.find(item => item.id === form.supplierId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, supplierName: supplier?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, supplierName: supplier?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/payable/purchaseIn.vue b/src/views/financialManagement/payable/purchaseIn.vue
new file mode 100644
index 0000000..131fe49
--- /dev/null
+++ b/src/views/financialManagement/payable/purchaseIn.vue
@@ -0,0 +1,331 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍏ュ簱鍗曞彿:">
+        <el-input v-model="filters.inCode" placeholder="璇疯緭鍏ュ叆搴撳崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="渚涘簲鍟�:">
+        <el-select v-model="filters.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px;">
+          <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍏ュ簱鏃ユ湡:">
+        <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="鑷�" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" clearable />
+      </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="add" icon="Plus">鏂板鍏ュ簱</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #amount="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.amount) }}</span>
+        </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)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="danger" link @click="handleDelete(row)" v-if="row.status === 'pending'">鍒犻櫎</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鍗曞彿" prop="inCode">
+              <el-input v-model="form.inCode" placeholder="璇疯緭鍏ュ叆搴撳崟鍙�" :disabled="isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟�" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍏ュ簱鏃ユ湡" prop="inDate">
+              <el-date-picker v-model="form.inDate" 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="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍏ュ簱鏄庣粏" prop="details">
+          <el-table :data="form.details" border style="width: 100%">
+            <el-table-column prop="materialName" label="鐗╂枡鍚嶇О" width="150">
+              <template #default="{ $index }">
+                <el-input v-model="form.details[$index].materialName" placeholder="鐗╂枡鍚嶇О" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="spec" label="瑙勬牸" width="120">
+              <template #default="{ $index }">
+                <el-input v-model="form.details[$index].spec" placeholder="瑙勬牸" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="quantity" label="鏁伴噺" width="100">
+              <template #default="{ $index }">
+                <el-input-number v-model="form.details[$index].quantity" :min="0" style="width: 100%;" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="unitPrice" label="鍗曚环" width="120">
+              <template #default="{ $index }">
+                <el-input-number v-model="form.details[$index].unitPrice" :min="0" :precision="2" style="width: 100%;" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="total" label="閲戦" width="120">
+              <template #default="{ row }">
+                <span>楼{{ formatMoney(row.quantity * row.unitPrice) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="80">
+              <template #default="{ $index }">
+                <el-button type="danger" link @click="removeDetail($index)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-button type="primary" link @click="addDetail" style="margin-top: 10px;">+ 娣诲姞鏄庣粏</el-button>
+        </el-form-item>
+        <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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "閲囪喘鍏ュ簱",
+});
+
+const filters = reactive({
+  inCode: "",
+  supplierId: "",
+  dateRange: [],
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鍏ュ簱鍗曞彿", prop: "inCode", width: "150" },
+  { label: "渚涘簲鍟�", prop: "supplierName", width: "180" },
+  { label: "鍏ュ簱鏃ユ湡", prop: "inDate", width: "120" },
+  { label: "鍏ュ簱閲戦", prop: "amount", slot: "amount" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "澶囨敞", prop: "remark", showOverflowTooltip: true },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const supplierList = [
+  { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+  { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+  { id: 3, name: "骞垮窞鍖呰鏉愭枡鍘�" },
+  { id: 4, name: "娣卞湷浜旈噾閰嶄欢鍏徃" },
+];
+
+const form = reactive({
+  inCode: "",
+  supplierId: "",
+  inDate: "",
+  amount: 0,
+  details: [],
+  remark: "",
+});
+
+const rules = {
+  inCode: [{ required: true, message: "璇疯緭鍏ュ叆搴撳崟鍙�", trigger: "blur" }],
+  supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
+  inDate: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃ユ湡", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ュ叆搴撻噾棰�", trigger: "blur" }],
+};
+
+const mockData = [
+  { id: 1, inCode: "RK2024001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", inDate: "2024-01-10", amount: 8000, status: "approved", details: [{ materialName: "閽㈡潗", spec: "Q235", quantity: 10, unitPrice: 500 }], remark: "" },
+  { id: 2, inCode: "RK2024002", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", inDate: "2024-01-12", amount: 12000, status: "pending", details: [{ materialName: "鑺墖", spec: "STM32", quantity: 100, unitPrice: 80 }], remark: "" },
+  { id: 3, inCode: "RK2024003", supplierId: 3, supplierName: "骞垮窞鍖呰鏉愭枡鍘�", inDate: "2024-01-15", amount: 3500, status: "approved", details: [{ materialName: "绾哥", spec: "50*40*30", quantity: 500, unitPrice: 5 }], remark: "" },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getStatusLabel = (status) => {
+  const map = { pending: "寰呭鏍�", approved: "宸插鏍�", rejected: "宸查┏鍥�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { pending: "warning", approved: "success", rejected: "danger" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.inCode) {
+    result = result.filter(item => item.inCode.includes(filters.inCode));
+  }
+  if (filters.supplierId) {
+    result = result.filter(item => item.supplierId === filters.supplierId);
+  }
+  if (filters.dateRange && filters.dateRange.length === 2) {
+    result = result.filter(item => item.inDate >= filters.dateRange[0] && item.inDate <= filters.dateRange[1]);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.inCode = "";
+  filters.supplierId = "";
+  filters.dateRange = [];
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const addDetail = () => {
+  form.details.push({ materialName: "", spec: "", quantity: 0, unitPrice: 0 });
+};
+
+const removeDetail = (index) => {
+  form.details.splice(index, 1);
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板鍏ュ簱";
+  Object.assign(form, {
+    inCode: "RK" + Date.now().toString().slice(-8),
+    supplierId: "",
+    inDate: new Date().toISOString().split('T')[0],
+    amount: 0,
+    details: [{ materialName: "", spec: "", quantity: 0, unitPrice: 0 }],
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍏ュ簱";
+  Object.assign(form, row);
+  if (!form.details || form.details.length === 0) {
+    form.details = [{ materialName: "", spec: "", quantity: 0, unitPrice: 0 }];
+  }
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鍏ュ簱鍗�: ${row.inCode}`);
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ュ叆搴撳崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const supplier = supplierList.find(item => item.id === form.supplierId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, supplierName: supplier?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, supplierName: supplier?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/payable/reconciliation.vue b/src/views/financialManagement/payable/reconciliation.vue
new file mode 100644
index 0000000..06854b8
--- /dev/null
+++ b/src/views/financialManagement/payable/reconciliation.vue
@@ -0,0 +1,254 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="渚涘簲鍟�:">
+        <el-select v-model="filters.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px;">
+          <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瀵硅处鏈熼棿:">
+        <el-date-picker v-model="filters.startMonth" type="month" placeholder="寮�濮嬫湀浠�" value-format="YYYY-MM" style="width: 140px;" />
+        <span style="margin: 0 10px;">鑷�</span>
+        <el-date-picker v-model="filters.endMonth" type="month" placeholder="缁撴潫鏈堜唤" value-format="YYYY-MM" style="width: 140px;" />
+      </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-button type="primary" @click="generateStatement" icon="Document">鐢熸垚瀵硅处鍗�</el-button>
+        </div>
+        <div>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭瀵硅处鍗�</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #beginBalance="{ row }">
+          <span :class="row.beginBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.beginBalance) }}</span>
+        </template>
+        <template #currentPayable="{ row }">
+          <span class="text-danger">楼{{ formatMoney(row.currentPayable) }}</span>
+        </template>
+        <template #currentPayment="{ row }">
+          <span class="text-success">楼{{ formatMoney(row.currentPayment) }}</span>
+        </template>
+        <template #endBalance="{ row }">
+          <span :class="row.endBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.endBalance) }}</span>
+        </template>
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="viewDetail(row)">鏌ョ湅鏄庣粏</el-button>
+          <el-button type="primary" link @click="printStatement(row)">鎵撳嵃</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" append-to-body>
+      <div class="statement-header">
+        <h3>{{ currentSupplier }} 搴斾粯瀵硅处鍗�</h3>
+        <p>瀵硅处鏈熼棿: {{ currentPeriod }}</p>
+      </div>
+      <el-table :data="detailData" border style="width: 100%">
+        <el-table-column prop="date" label="鏃ユ湡" width="120" />
+        <el-table-column prop="type" label="绫诲瀷" width="100">
+          <template #default="{ row }">
+            <el-tag :type="row.type === '鍏ュ簱' ? 'success' : row.type === '閫�璐�' ? 'danger' : 'primary'">{{ row.type }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="code" label="鍗曟嵁缂栧彿" width="150" />
+        <el-table-column prop="debit" label="鍊熸柟(浠樻)" width="120">
+          <template #default="{ row }">
+            <span v-if="row.debit > 0" class="text-success">楼{{ formatMoney(row.debit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="credit" label="璐锋柟(搴斾粯)" width="120">
+          <template #default="{ row }">
+            <span v-if="row.credit > 0" class="text-danger">楼{{ formatMoney(row.credit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="balance" label="浣欓" width="120">
+          <template #default="{ row }">
+            <span :class="row.balance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.balance) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+      </el-table>
+      <template #footer>
+        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+        <el-button type="primary" @click="printDetail">鎵撳嵃</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "搴斾粯瀵硅处",
+});
+
+const filters = reactive({
+  supplierId: "",
+  startMonth: "",
+  endMonth: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "瀵硅处鍗曞彿", prop: "statementCode", width: "150" },
+  { label: "渚涘簲鍟�", prop: "supplierName", width: "180" },
+  { label: "瀵硅处鏈熼棿", prop: "period", width: "150" },
+  { label: "鏈熷垵浣欓", prop: "beginBalance", slot: "beginBalance" },
+  { label: "鏈湡搴斾粯", prop: "currentPayable", slot: "currentPayable" },
+  { label: "鏈湡浠樻", prop: "currentPayment", slot: "currentPayment" },
+  { label: "鏈熸湯浣欓", prop: "endBalance", slot: "endBalance" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "150", fixed: "right" },
+];
+
+const dataList = ref([]);
+const detailDialogVisible = ref(false);
+const currentSupplier = ref("");
+const currentPeriod = ref("");
+const detailData = ref([]);
+
+const supplierList = [
+  { id: 1, name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+  { id: 2, name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+  { id: 3, name: "骞垮窞鍖呰鏉愭枡鍘�" },
+  { id: 4, name: "娣卞湷浜旈噾閰嶄欢鍏徃" },
+];
+
+const mockData = [
+  { id: 1, statementCode: "DZ202401001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", period: "2024-01", beginBalance: 20000, currentPayable: 15000, currentPayment: 10000, endBalance: 25000 },
+  { id: 2, statementCode: "DZ202401002", supplierId: 2, supplierName: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�", period: "2024-01", beginBalance: 10000, currentPayable: 20000, currentPayment: 15000, endBalance: 15000 },
+  { id: 3, statementCode: "DZ202402001", supplierId: 1, supplierName: "鍖椾含鍘熸潗鏂欎緵搴斿晢", period: "2024-02", beginBalance: 25000, currentPayable: 18000, currentPayment: 20000, endBalance: 23000 },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.supplierId) {
+    result = result.filter(item => item.supplierId === filters.supplierId);
+  }
+  if (filters.startMonth && filters.endMonth) {
+    result = result.filter(item => item.period >= filters.startMonth && item.period <= filters.endMonth);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.supplierId = "";
+  filters.startMonth = "";
+  filters.endMonth = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const generateStatement = () => {
+  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
+  const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+  const supplier = supplierList[Math.floor(Math.random() * supplierList.length)];
+  mockData.unshift({
+    id: newId,
+    statementCode: "DZ" + Date.now(),
+    supplierId: supplier.id,
+    supplierName: supplier.name,
+    period: "2024-03",
+    beginBalance: Math.floor(Math.random() * 20000),
+    currentPayable: Math.floor(Math.random() * 25000),
+    currentPayment: Math.floor(Math.random() * 20000),
+    endBalance: Math.floor(Math.random() * 25000),
+  });
+  getTableData();
+};
+
+const viewDetail = (row) => {
+  currentSupplier.value = row.supplierName;
+  currentPeriod.value = row.period;
+  detailData.value = [
+    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "鏈熷垵浣欓" },
+    { date: row.period + "-05", type: "鍏ュ簱", code: "RK2024001", debit: 0, credit: 8000, balance: row.beginBalance + 8000, remark: "" },
+    { date: row.period + "-10", type: "浠樻", code: "FK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 3000, remark: "" },
+    { date: row.period + "-15", type: "鍏ュ簱", code: "RK2024002", credit: 12000, balance: row.beginBalance + 15000, remark: "" },
+    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 2000, credit: 0, balance: row.beginBalance + 13000, remark: "" },
+    { date: row.period + "-25", type: "浠樻", code: "FK2024002", debit: row.currentPayment - 5000, balance: row.endBalance, remark: "" },
+  ];
+  detailDialogVisible.value = true;
+};
+
+const printStatement = (row) => {
+  ElMessage.info(`鎵撳嵃瀵硅处鍗�: ${row.statementCode}`);
+};
+
+const printDetail = () => {
+  ElMessage.info("鎵撳嵃鏄庣粏");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-success {
+  color: #67c23a;
+}
+
+.text-danger {
+  color: #f56c6c;
+}
+
+.statement-header {
+  text-align: center;
+  margin-bottom: 20px;
+  h3 {
+    margin: 0 0 10px 0;
+  }
+  p {
+    color: #909399;
+    margin: 0;
+  }
+}
+</style>
diff --git a/src/views/financialManagement/receivable/invoiceApply.vue b/src/views/financialManagement/receivable/invoiceApply.vue
new file mode 100644
index 0000000..e637a3e
--- /dev/null
+++ b/src/views/financialManagement/receivable/invoiceApply.vue
@@ -0,0 +1,358 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鐢宠鍗曞彿:">
+        <el-input v-model="filters.applyCode" placeholder="璇疯緭鍏ョ敵璇峰崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鐘舵��:">
+        <el-select v-model="filters.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px;">
+          <el-option label="寰呭鏍�" value="pending" />
+          <el-option label="宸插鏍�" value="approved" />
+          <el-option label="宸查┏鍥�" value="rejected" />
+          <el-option label="宸插紑绁�" value="invoiced" />
+        </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></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板鐢宠</el-button>
+          <el-button @click="handleBatchApply" icon="Document" :disabled="selectedRows.length === 0">鎵归噺鐢宠</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 #amount="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #taxRate="{ row }">
+          <span>{{ row.taxRate }}%</span>
+        </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)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="success" link @click="handleAudit(row)" v-if="row.status === 'pending'">瀹℃牳</el-button>
+          <el-button type="warning" link @click="handleInvoice(row)" v-if="row.status === 'approved'">寮�绁�</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐢宠鍗曞彿" prop="applyCode">
+              <el-input v-model="form.applyCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛" prop="customerId">
+              <el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="寮�绁ㄩ噾棰�" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绋庣巼" prop="taxRate">
+              <el-select v-model="form.taxRate" placeholder="璇烽�夋嫨绋庣巼" style="width: 100%;">
+                <el-option label="0%" :value="0" />
+                <el-option label="3%" :value="3" />
+                <el-option label="6%" :value="6" />
+                <el-option label="9%" :value="9" />
+                <el-option label="13%" :value="13" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ绫诲瀷" prop="invoiceType">
+              <el-select v-model="form.invoiceType" placeholder="璇烽�夋嫨鍙戠エ绫诲瀷" style="width: 100%;">
+                <el-option label="澧炲�肩◣涓撶敤鍙戠エ" value="special" />
+                <el-option label="澧炲�肩◣鏅�氬彂绁�" value="normal" />
+                <el-option label="鐢靛瓙鍙戠エ" value="electronic" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢宠鏃ユ湡" prop="applyDate">
+              <el-date-picker v-model="form.applyDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍙戠エ鍐呭" prop="content">
+          <el-input v-model="form.content" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ彂绁ㄥ唴瀹�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "寮�绁ㄧ敵璇�",
+});
+
+const filters = reactive({
+  applyCode: "",
+  customerId: "",
+  status: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鐢宠鍗曞彿", prop: "applyCode", width: "150" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "寮�绁ㄩ噾棰�", prop: "amount", slot: "amount" },
+  { label: "绋庣巼", prop: "taxRate", slot: "taxRate" },
+  { label: "鍙戠エ绫诲瀷", prop: "invoiceTypeLabel", width: "130" },
+  { label: "鐢宠鏃ユ湡", prop: "applyDate", width: "120" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const selectedRows = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const form = reactive({
+  applyCode: "",
+  customerId: "",
+  amount: 0,
+  taxRate: 13,
+  invoiceType: "special",
+  applyDate: "",
+  content: "",
+  remark: "",
+});
+
+const rules = {
+  customerId: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ュ紑绁ㄩ噾棰�", trigger: "blur" }],
+  taxRate: [{ required: true, message: "璇烽�夋嫨绋庣巼", trigger: "change" }],
+  invoiceType: [{ required: true, message: "璇烽�夋嫨鍙戠エ绫诲瀷", trigger: "change" }],
+  applyDate: [{ required: true, message: "璇烽�夋嫨鐢宠鏃ユ湡", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, applyCode: "KP2024001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", amount: 5000, taxRate: 13, invoiceType: "special", invoiceTypeLabel: "澧炲�肩◣涓撶敤鍙戠エ", applyDate: "2024-01-15", status: "pending", content: "杞欢鏈嶅姟璐�", remark: "" },
+  { id: 2, applyCode: "KP2024002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", amount: 8000, taxRate: 13, invoiceType: "normal", invoiceTypeLabel: "澧炲�肩◣鏅�氬彂绁�", applyDate: "2024-01-16", status: "approved", content: "鍟嗗搧閿�鍞�", remark: "" },
+  { id: 3, applyCode: "KP2024003", customerId: 3, customerName: "骞垮窞瀹炰笟鏈夐檺鍏徃", amount: 12000, taxRate: 6, invoiceType: "electronic", invoiceTypeLabel: "鐢靛瓙鍙戠エ", applyDate: "2024-01-18", status: "invoiced", content: "鎶�鏈湇鍔¤垂", remark: "" },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getStatusLabel = (status) => {
+  const map = { pending: "寰呭鏍�", approved: "宸插鏍�", rejected: "宸查┏鍥�", invoiced: "宸插紑绁�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { pending: "warning", approved: "success", rejected: "danger", invoiced: "primary" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.applyCode) {
+    result = result.filter(item => item.applyCode.includes(filters.applyCode));
+  }
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.applyCode = "";
+  filters.customerId = "";
+  filters.status = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板寮�绁ㄧ敵璇�";
+  Object.assign(form, {
+    applyCode: "KP" + Date.now().toString().slice(-8),
+    customerId: "",
+    amount: 0,
+    taxRate: 13,
+    invoiceType: "special",
+    applyDate: new Date().toISOString().split('T')[0],
+    content: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫寮�绁ㄧ敵璇�";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鐢宠鍗�: ${row.applyCode}`);
+};
+
+const handleAudit = (row) => {
+  ElMessageBox.confirm("纭瀹℃牳閫氳繃璇ュ紑绁ㄧ敵璇峰悧锛�", "鎻愮ず", {
+    confirmButtonText: "閫氳繃",
+    cancelButtonText: "椹冲洖",
+    distinguishCancelAndClose: true,
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "approved";
+    }
+    ElMessage.success("瀹℃牳閫氳繃");
+    getTableData();
+  }).catch((action) => {
+    if (action === "cancel") {
+      const index = mockData.findIndex(item => item.id === row.id);
+      if (index !== -1) {
+        mockData[index].status = "rejected";
+      }
+      ElMessage.warning("宸查┏鍥�");
+      getTableData();
+    }
+  });
+};
+
+const handleInvoice = (row) => {
+  ElMessageBox.confirm("纭宸插紑鍏峰彂绁紵", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "invoiced";
+    }
+    ElMessage.success("寮�绁ㄥ畬鎴�");
+    getTableData();
+  });
+};
+
+const handleBatchApply = () => {
+  ElMessage.success(`鎵归噺鐢宠 ${selectedRows.value.length} 鏉¤褰昤);
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const customer = customerList.find(item => item.id === form.customerId);
+      const invoiceTypeMap = { special: "澧炲�肩◣涓撶敤鍙戠エ", normal: "澧炲�肩◣鏅�氬彂绁�", electronic: "鐢靛瓙鍙戠エ" };
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, customerName: customer?.name, invoiceTypeLabel: invoiceTypeMap[form.invoiceType] };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, customerName: customer?.name, invoiceTypeLabel: invoiceTypeMap[form.invoiceType], status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/receivable/outputInvoice.vue b/src/views/financialManagement/receivable/outputInvoice.vue
new file mode 100644
index 0000000..289905a
--- /dev/null
+++ b/src/views/financialManagement/receivable/outputInvoice.vue
@@ -0,0 +1,368 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍙戠エ浠g爜:">
+        <el-input v-model="filters.invoiceCode" placeholder="璇疯緭鍏ュ彂绁ㄤ唬鐮�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="鍙戠エ鍙风爜:">
+        <el-input v-model="filters.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </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></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">褰曞叆鍙戠エ</el-button>
+          <el-button @click="handleImport" icon="Upload">瀵煎叆</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #amount="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #taxAmount="{ row }">
+          <span class="text-danger">楼{{ formatMoney(row.taxAmount) }}</span>
+        </template>
+        <template #totalAmount="{ row }">
+          <span class="text-success">楼{{ formatMoney(row.totalAmount) }}</span>
+        </template>
+        <template #invoiceType="{ row }">
+          <el-tag :type="row.invoiceType === 'special' ? 'danger' : 'primary'">{{ row.invoiceTypeLabel }}</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>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ浠g爜" prop="invoiceCode">
+              <el-input v-model="form.invoiceCode" placeholder="璇疯緭鍏ュ彂绁ㄤ唬鐮�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNo">
+              <el-input v-model="form.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛" prop="customerId">
+              <el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="寮�绁ㄦ棩鏈�" prop="invoiceDate">
+              <el-date-picker v-model="form.invoiceDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍙戠エ绫诲瀷" prop="invoiceType">
+              <el-select v-model="form.invoiceType" placeholder="璇烽�夋嫨鍙戠エ绫诲瀷" style="width: 100%;" @change="handleInvoiceTypeChange">
+                <el-option label="澧炲�肩◣涓撶敤鍙戠エ" value="special" />
+                <el-option label="澧炲�肩◣鏅�氬彂绁�" value="normal" />
+                <el-option label="鐢靛瓙鍙戠エ" value="electronic" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绋庣巼" prop="taxRate">
+              <el-select v-model="form.taxRate" placeholder="璇烽�夋嫨绋庣巼" style="width: 100%;" @change="calculateTax">
+                <el-option label="0%" :value="0" />
+                <el-option label="3%" :value="3" />
+                <el-option label="6%" :value="6" />
+                <el-option label="9%" :value="9" />
+                <el-option label="13%" :value="13" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="閲戦(涓嶅惈绋�)" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" @change="calculateTax" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="绋庨">
+              <el-input v-model="form.taxAmount" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="浠风◣鍚堣">
+              <el-input v-model="form.totalAmount" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍙戠エ鍐呭" prop="content">
+          <el-input v-model="form.content" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ彂绁ㄥ唴瀹�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "閿�椤瑰彂绁�",
+});
+
+const filters = reactive({
+  invoiceCode: "",
+  invoiceNo: "",
+  customerId: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鍙戠エ浠g爜", prop: "invoiceCode", width: "130" },
+  { label: "鍙戠エ鍙风爜", prop: "invoiceNo", width: "120" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "寮�绁ㄦ棩鏈�", prop: "invoiceDate", width: "120" },
+  { label: "閲戦", prop: "amount", slot: "amount" },
+  { label: "绋庨", prop: "taxAmount", slot: "taxAmount" },
+  { label: "浠风◣鍚堣", prop: "totalAmount", slot: "totalAmount" },
+  { label: "鍙戠エ绫诲瀷", prop: "invoiceType", slot: "invoiceType" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "180", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const form = reactive({
+  invoiceCode: "",
+  invoiceNo: "",
+  customerId: "",
+  invoiceDate: "",
+  invoiceType: "special",
+  taxRate: 13,
+  amount: 0,
+  taxAmount: 0,
+  totalAmount: 0,
+  content: "",
+  remark: "",
+});
+
+const rules = {
+  invoiceCode: [{ required: true, message: "璇疯緭鍏ュ彂绁ㄤ唬鐮�", trigger: "blur" }],
+  invoiceNo: [{ required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿鐮�", trigger: "blur" }],
+  customerId: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
+  invoiceDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
+  invoiceType: [{ required: true, message: "璇烽�夋嫨鍙戠エ绫诲瀷", trigger: "change" }],
+  taxRate: [{ required: true, message: "璇烽�夋嫨绋庣巼", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur" }],
+};
+
+const mockData = [
+  { id: 1, invoiceCode: "0440021001", invoiceNo: "12345678", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", invoiceDate: "2024-01-15", amount: 5000, taxRate: 13, taxAmount: 650, totalAmount: 5650, invoiceType: "special", invoiceTypeLabel: "澧炲�肩◣涓撶敤鍙戠エ", content: "杞欢鏈嶅姟璐�", remark: "" },
+  { id: 2, invoiceCode: "0440021002", invoiceNo: "87654321", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", invoiceDate: "2024-01-16", amount: 8000, taxRate: 13, taxAmount: 1040, totalAmount: 9040, invoiceType: "normal", invoiceTypeLabel: "澧炲�肩◣鏅�氬彂绁�", content: "鍟嗗搧閿�鍞�", remark: "" },
+  { id: 3, invoiceCode: "0440021003", invoiceNo: "11112222", customerId: 3, customerName: "骞垮窞瀹炰笟鏈夐檺鍏徃", invoiceDate: "2024-01-18", amount: 12000, taxRate: 6, taxAmount: 720, totalAmount: 12720, invoiceType: "electronic", invoiceTypeLabel: "鐢靛瓙鍙戠エ", content: "鎶�鏈湇鍔¤垂", remark: "" },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const calculateTax = () => {
+  form.taxAmount = Number((form.amount * form.taxRate / 100).toFixed(2));
+  form.totalAmount = Number((form.amount + form.taxAmount).toFixed(2));
+};
+
+const handleInvoiceTypeChange = () => {
+  if (form.invoiceType === "special") {
+    form.taxRate = 13;
+  } else {
+    form.taxRate = 13;
+  }
+  calculateTax();
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.invoiceCode) {
+    result = result.filter(item => item.invoiceCode.includes(filters.invoiceCode));
+  }
+  if (filters.invoiceNo) {
+    result = result.filter(item => item.invoiceNo.includes(filters.invoiceNo));
+  }
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.invoiceCode = "";
+  filters.invoiceNo = "";
+  filters.customerId = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "褰曞叆鍙戠エ";
+  Object.assign(form, {
+    invoiceCode: "",
+    invoiceNo: "",
+    customerId: "",
+    invoiceDate: new Date().toISOString().split('T')[0],
+    invoiceType: "special",
+    taxRate: 13,
+    amount: 0,
+    taxAmount: 0,
+    totalAmount: 0,
+    content: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍙戠エ";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鍙戠エ: ${row.invoiceCode}-${row.invoiceNo}`);
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭浣滃簾璇ュ彂绁ㄥ悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("浣滃簾鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleImport = () => {
+  ElMessage.info("瀵煎叆鍔熻兘");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const customer = customerList.find(item => item.id === form.customerId);
+      const invoiceTypeMap = { special: "澧炲�肩◣涓撶敤鍙戠エ", normal: "澧炲�肩◣鏅�氬彂绁�", electronic: "鐢靛瓙鍙戠エ" };
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, customerName: customer?.name, invoiceTypeLabel: invoiceTypeMap[form.invoiceType] };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, customerName: customer?.name, invoiceTypeLabel: invoiceTypeMap[form.invoiceType] });
+        ElMessage.success("褰曞叆鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+
+.text-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/receivable/receipt.vue b/src/views/financialManagement/receivable/receipt.vue
new file mode 100644
index 0000000..51bb1f2
--- /dev/null
+++ b/src/views/financialManagement/receivable/receipt.vue
@@ -0,0 +1,355 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鏀舵鍗曞彿:">
+        <el-input v-model="filters.receiptCode" placeholder="璇疯緭鍏ユ敹娆惧崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鏀舵鏂瑰紡:">
+        <el-select v-model="filters.receiptMethod" placeholder="璇烽�夋嫨鏀舵鏂瑰紡" clearable style="width: 150px;">
+          <el-option label="閾惰杞处" value="bank_transfer" />
+          <el-option label="鐜伴噾" value="cash" />
+          <el-option label="鏀エ" value="check" />
+          <el-option label="姹囩エ" value="draft" />
+          <el-option label="鏀粯瀹�" value="alipay" />
+          <el-option label="寰俊" value="wechat" />
+        </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="totalReceiptAmount" precision="2" prefix="楼" />
+        </div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板鏀舵</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #amount="{ row }">
+          <span class="text-success">楼{{ formatMoney(row.amount) }}</span>
+        </template>
+        <template #receiptMethod="{ row }">
+          <el-tag>{{ getReceiptMethodLabel(row.receiptMethod) }}</el-tag>
+        </template>
+        <template #status="{ row }">
+          <el-tag :type="row.status === 'confirmed' ? 'success' : 'warning'">{{ row.status === 'confirmed' ? '宸茬‘璁�' : '寰呯‘璁�' }}</el-tag>
+        </template>
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="view(row)">鏌ョ湅</el-button>
+          <el-button type="primary" link @click="edit(row)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="success" link @click="handleConfirm(row)" v-if="row.status === 'pending'">纭</el-button>
+          <el-button type="danger" link @click="handleDelete(row)" v-if="row.status === 'pending'">鍒犻櫎</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏀舵鍗曞彿" prop="receiptCode">
+              <el-input v-model="form.receiptCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛" prop="customerId">
+              <el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏀舵鏃ユ湡" prop="receiptDate">
+              <el-date-picker v-model="form.receiptDate" 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="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏀舵鏂瑰紡" prop="receiptMethod">
+              <el-select v-model="form.receiptMethod" placeholder="璇烽�夋嫨鏀舵鏂瑰紡" style="width: 100%;">
+                <el-option label="閾惰杞处" value="bank_transfer" />
+                <el-option label="鐜伴噾" value="cash" />
+                <el-option label="鏀エ" value="check" />
+                <el-option label="姹囩エ" value="draft" />
+                <el-option label="鏀粯瀹�" value="alipay" />
+                <el-option label="寰俊" value="wechat" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閾惰璐﹀彿" prop="bankAccount" v-if="form.receiptMethod === 'bank_transfer'">
+              <el-input v-model="form.bankAccount" placeholder="璇疯緭鍏ラ摱琛岃处鍙�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍏宠仈鍗曟嵁" prop="relatedDocs">
+          <el-select v-model="form.relatedDocs" multiple placeholder="璇烽�夋嫨鍏宠仈鍗曟嵁" style="width: 100%;">
+            <el-option v-for="item in outList" :key="item.outCode" :label="item.outCode" :value="item.outCode" />
+          </el-select>
+        </el-form-item>
+        <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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "鏀舵鍗�",
+});
+
+const filters = reactive({
+  receiptCode: "",
+  customerId: "",
+  receiptMethod: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鏀舵鍗曞彿", prop: "receiptCode", width: "150" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "鏀舵鏃ユ湡", prop: "receiptDate", width: "120" },
+  { label: "鏀舵閲戦", prop: "amount", slot: "amount" },
+  { label: "鏀舵鏂瑰紡", prop: "receiptMethod", slot: "receiptMethod" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "澶囨敞", prop: "remark", showOverflowTooltip: true },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "220", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const outList = [
+  { outCode: "CK2024001", customerId: 1 },
+  { outCode: "CK2024002", customerId: 2 },
+  { outCode: "CK2024003", customerId: 3 },
+];
+
+const form = reactive({
+  receiptCode: "",
+  customerId: "",
+  receiptDate: "",
+  amount: 0,
+  receiptMethod: "bank_transfer",
+  bankAccount: "",
+  relatedDocs: [],
+  remark: "",
+});
+
+const rules = {
+  customerId: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
+  receiptDate: [{ required: true, message: "璇烽�夋嫨鏀舵鏃ユ湡", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ユ敹娆鹃噾棰�", trigger: "blur" }],
+  receiptMethod: [{ required: true, message: "璇烽�夋嫨鏀舵鏂瑰紡", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, receiptCode: "SK2024001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", receiptDate: "2024-01-16", amount: 3000, receiptMethod: "bank_transfer", status: "confirmed", relatedDocs: ["CK2024001"], remark: "" },
+  { id: 2, receiptCode: "SK2024002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", receiptDate: "2024-01-18", amount: 5000, receiptMethod: "cash", status: "pending", relatedDocs: ["CK2024002"], remark: "" },
+  { id: 3, receiptCode: "SK2024003", customerId: 3, customerName: "骞垮窞瀹炰笟鏈夐檺鍏徃", receiptDate: "2024-01-20", amount: 8000, receiptMethod: "alipay", status: "confirmed", relatedDocs: ["CK2024003"], remark: "" },
+];
+
+const totalReceiptAmount = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.amount), 0);
+});
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getReceiptMethodLabel = (method) => {
+  const map = {
+    bank_transfer: "閾惰杞处",
+    cash: "鐜伴噾",
+    check: "鏀エ",
+    draft: "姹囩エ",
+    alipay: "鏀粯瀹�",
+    wechat: "寰俊",
+  };
+  return map[method] || method;
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.receiptCode) {
+    result = result.filter(item => item.receiptCode.includes(filters.receiptCode));
+  }
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  if (filters.receiptMethod) {
+    result = result.filter(item => item.receiptMethod === filters.receiptMethod);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.receiptCode = "";
+  filters.customerId = "";
+  filters.receiptMethod = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板鏀舵";
+  Object.assign(form, {
+    receiptCode: "SK" + Date.now().toString().slice(-8),
+    customerId: "",
+    receiptDate: new Date().toISOString().split('T')[0],
+    amount: 0,
+    receiptMethod: "bank_transfer",
+    bankAccount: "",
+    relatedDocs: [],
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鏀舵";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鏀舵鍗�: ${row.receiptCode}`);
+};
+
+const handleConfirm = (row) => {
+  ElMessageBox.confirm("纭璇ユ敹娆惧崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "confirmed";
+    }
+    ElMessage.success("纭鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ユ敹娆惧崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const customer = customerList.find(item => item.id === form.customerId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, customerName: customer?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, customerName: customer?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.text-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/receivable/reconciliation.vue b/src/views/financialManagement/receivable/reconciliation.vue
new file mode 100644
index 0000000..fc6d7c1
--- /dev/null
+++ b/src/views/financialManagement/receivable/reconciliation.vue
@@ -0,0 +1,258 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瀵硅处鏈熼棿:">
+        <el-date-picker v-model="filters.startMonth" type="month" placeholder="寮�濮嬫湀浠�" value-format="YYYY-MM" style="width: 140px;" />
+        <span style="margin: 0 10px;">鑷�</span>
+        <el-date-picker v-model="filters.endMonth" type="month" placeholder="缁撴潫鏈堜唤" value-format="YYYY-MM" style="width: 140px;" />
+      </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-button type="primary" @click="generateStatement" icon="Document">鐢熸垚瀵硅处鍗�</el-button>
+        </div>
+        <div>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭瀵硅处鍗�</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #beginBalance="{ row }">
+          <span :class="row.beginBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.beginBalance) }}</span>
+        </template>
+        <template #currentReceivable="{ row }">
+          <span class="text-primary">楼{{ formatMoney(row.currentReceivable) }}</span>
+        </template>
+        <template #currentReceipt="{ row }">
+          <span class="text-success">楼{{ formatMoney(row.currentReceipt) }}</span>
+        </template>
+        <template #endBalance="{ row }">
+          <span :class="row.endBalance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.endBalance) }}</span>
+        </template>
+        <template #operation="{ row }">
+          <el-button type="primary" link @click="viewDetail(row)">鏌ョ湅鏄庣粏</el-button>
+          <el-button type="primary" link @click="printStatement(row)">鎵撳嵃</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog title="瀵硅处鏄庣粏" v-model="detailDialogVisible" width="900px" append-to-body>
+      <div class="statement-header">
+        <h3>{{ currentCustomer }} 搴旀敹瀵硅处鍗�</h3>
+        <p>瀵硅处鏈熼棿: {{ currentPeriod }}</p>
+      </div>
+      <el-table :data="detailData" border style="width: 100%">
+        <el-table-column prop="date" label="鏃ユ湡" width="120" />
+        <el-table-column prop="type" label="绫诲瀷" width="100">
+          <template #default="{ row }">
+            <el-tag :type="row.type === '鍑哄簱' ? 'success' : row.type === '閫�璐�' ? 'danger' : 'primary'">{{ row.type }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="code" label="鍗曟嵁缂栧彿" width="150" />
+        <el-table-column prop="debit" label="鍊熸柟(搴旀敹)" width="120">
+          <template #default="{ row }">
+            <span v-if="row.debit > 0" class="text-danger">楼{{ formatMoney(row.debit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="credit" label="璐锋柟(鏀舵)" width="120">
+          <template #default="{ row }">
+            <span v-if="row.credit > 0" class="text-success">楼{{ formatMoney(row.credit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="balance" label="浣欓" width="120">
+          <template #default="{ row }">
+            <span :class="row.balance >= 0 ? 'text-success' : 'text-danger'">楼{{ formatMoney(row.balance) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+      </el-table>
+      <template #footer>
+        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+        <el-button type="primary" @click="printDetail">鎵撳嵃</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "搴旀敹瀵硅处",
+});
+
+const filters = reactive({
+  customerId: "",
+  startMonth: "",
+  endMonth: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "瀵硅处鍗曞彿", prop: "statementCode", width: "150" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "瀵硅处鏈熼棿", prop: "period", width: "150" },
+  { label: "鏈熷垵浣欓", prop: "beginBalance", slot: "beginBalance" },
+  { label: "鏈湡搴旀敹", prop: "currentReceivable", slot: "currentReceivable" },
+  { label: "鏈湡鏀舵", prop: "currentReceipt", slot: "currentReceipt" },
+  { label: "鏈熸湯浣欓", prop: "endBalance", slot: "endBalance" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "150", fixed: "right" },
+];
+
+const dataList = ref([]);
+const detailDialogVisible = ref(false);
+const currentCustomer = ref("");
+const currentPeriod = ref("");
+const detailData = ref([]);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const mockData = [
+  { id: 1, statementCode: "DZ202401001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", period: "2024-01", beginBalance: 10000, currentReceivable: 15000, currentReceipt: 8000, endBalance: 17000 },
+  { id: 2, statementCode: "DZ202401002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", period: "2024-01", beginBalance: 5000, currentReceivable: 12000, currentReceipt: 10000, endBalance: 7000 },
+  { id: 3, statementCode: "DZ202402001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", period: "2024-02", beginBalance: 17000, currentReceivable: 20000, currentReceipt: 15000, endBalance: 22000 },
+];
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  if (filters.startMonth && filters.endMonth) {
+    result = result.filter(item => item.period >= filters.startMonth && item.period <= filters.endMonth);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.customerId = "";
+  filters.startMonth = "";
+  filters.endMonth = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const generateStatement = () => {
+  ElMessage.success("瀵硅处鍗曠敓鎴愭垚鍔�");
+  const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+  const customer = customerList[Math.floor(Math.random() * customerList.length)];
+  mockData.unshift({
+    id: newId,
+    statementCode: "DZ" + Date.now(),
+    customerId: customer.id,
+    customerName: customer.name,
+    period: "2024-03",
+    beginBalance: Math.floor(Math.random() * 10000),
+    currentReceivable: Math.floor(Math.random() * 20000),
+    currentReceipt: Math.floor(Math.random() * 15000),
+    endBalance: Math.floor(Math.random() * 20000),
+  });
+  getTableData();
+};
+
+const viewDetail = (row) => {
+  currentCustomer.value = row.customerName;
+  currentPeriod.value = row.period;
+  detailData.value = [
+    { date: row.period + "-01", type: "鏈熷垵", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "鏈熷垵浣欓" },
+    { date: row.period + "-05", type: "鍑哄簱", code: "CK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 5000, remark: "" },
+    { date: row.period + "-10", type: "鏀舵", code: "SK2024001", debit: 0, credit: 3000, balance: row.beginBalance + 2000, remark: "" },
+    { date: row.period + "-15", type: "鍑哄簱", code: "CK2024002", debit: 8000, credit: 0, balance: row.beginBalance + 10000, remark: "" },
+    { date: row.period + "-20", type: "閫�璐�", code: "TH2024001", debit: 0, credit: 2000, balance: row.beginBalance + 8000, remark: "" },
+    { date: row.period + "-25", type: "鏀舵", code: "SK2024002", credit: row.currentReceipt - 3000, balance: row.endBalance, remark: "" },
+  ];
+  detailDialogVisible.value = true;
+};
+
+const printStatement = (row) => {
+  ElMessage.info(`鎵撳嵃瀵硅处鍗�: ${row.statementCode}`);
+};
+
+const printDetail = () => {
+  ElMessage.info("鎵撳嵃鏄庣粏");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+
+.text-success {
+  color: #67c23a;
+}
+
+.text-danger {
+  color: #f56c6c;
+}
+
+.text-primary {
+  color: #409eff;
+}
+
+.statement-header {
+  text-align: center;
+  margin-bottom: 20px;
+  h3 {
+    margin: 0 0 10px 0;
+  }
+  p {
+    color: #909399;
+    margin: 0;
+  }
+}
+</style>
diff --git a/src/views/financialManagement/receivable/salesOut.vue b/src/views/financialManagement/receivable/salesOut.vue
new file mode 100644
index 0000000..15e5106
--- /dev/null
+++ b/src/views/financialManagement/receivable/salesOut.vue
@@ -0,0 +1,271 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍑哄簱鍗曞彿:">
+        <el-input v-model="filters.outCode" placeholder="璇疯緭鍏ュ嚭搴撳崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鍑哄簱鏃ユ湡:">
+        <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="鑷�" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" clearable />
+      </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="add" icon="Plus">鏂板鍑哄簱</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <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)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="danger" link @click="handleDelete(row)" v-if="row.status === 'pending'">鍒犻櫎</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍑哄簱鍗曞彿" prop="outCode">
+              <el-input v-model="form.outCode" placeholder="璇疯緭鍏ュ嚭搴撳崟鍙�" :disabled="isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛" prop="customerId">
+              <el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍑哄簱鏃ユ湡" prop="outDate">
+              <el-date-picker v-model="form.outDate" 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="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" 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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "閿�鍞嚭搴�",
+});
+
+const filters = reactive({
+  outCode: "",
+  customerId: "",
+  dateRange: [],
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鍑哄簱鍗曞彿", prop: "outCode", width: "150" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "鍑哄簱鏃ユ湡", prop: "outDate", width: "120" },
+  { label: "閲戦", prop: "amount", width: "120" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "澶囨敞", prop: "remark", showOverflowTooltip: true },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const form = reactive({
+  outCode: "",
+  customerId: "",
+  outDate: "",
+  amount: 0,
+  remark: "",
+});
+
+const rules = {
+  outCode: [{ required: true, message: "璇疯緭鍏ュ嚭搴撳崟鍙�", trigger: "blur" }],
+  customerId: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
+  outDate: [{ required: true, message: "璇烽�夋嫨鍑哄簱鏃ユ湡", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur" }],
+};
+
+const mockData = [
+  { id: 1, outCode: "CK2024001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", outDate: "2024-01-15", amount: 5000, status: "approved", remark: "" },
+  { id: 2, outCode: "CK2024002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", outDate: "2024-01-16", amount: 8000, status: "pending", remark: "" },
+  { id: 3, outCode: "CK2024003", customerId: 3, customerName: "骞垮窞瀹炰笟鏈夐檺鍏徃", outDate: "2024-01-18", amount: 12000, status: "approved", remark: "" },
+  { id: 4, outCode: "CK2024004", customerId: 4, customerName: "娣卞湷鐢靛瓙鍏徃", outDate: "2024-01-20", amount: 3500, status: "pending", remark: "" },
+];
+
+const getStatusLabel = (status) => {
+  const map = { pending: "寰呭鏍�", approved: "宸插鏍�", rejected: "宸查┏鍥�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { pending: "warning", approved: "success", rejected: "danger" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.outCode) {
+    result = result.filter(item => item.outCode.includes(filters.outCode));
+  }
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  if (filters.dateRange && filters.dateRange.length === 2) {
+    result = result.filter(item => item.outDate >= filters.dateRange[0] && item.outDate <= filters.dateRange[1]);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.outCode = "";
+  filters.customerId = "";
+  filters.dateRange = [];
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板鍑哄簱";
+  Object.assign(form, {
+    outCode: "CK" + Date.now(),
+    customerId: "",
+    outDate: "",
+    amount: 0,
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍑哄簱";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鍑哄簱鍗�: ${row.outCode}`);
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const customer = customerList.find(item => item.id === form.customerId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, customerName: customer?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, customerName: customer?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+const handleDelete = (row) => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ュ嚭搴撳崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData.splice(index, 1);
+    }
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+</style>
diff --git a/src/views/financialManagement/receivable/salesReturn.vue b/src/views/financialManagement/receivable/salesReturn.vue
new file mode 100644
index 0000000..7077b97
--- /dev/null
+++ b/src/views/financialManagement/receivable/salesReturn.vue
@@ -0,0 +1,305 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="閫�璐у崟鍙�:">
+        <el-input v-model="filters.returnCode" placeholder="璇疯緭鍏ラ��璐у崟鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="瀹㈡埛:">
+        <el-select v-model="filters.customerId" placeholder="璇烽�夋嫨瀹㈡埛" clearable style="width: 200px;">
+          <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="閫�璐ф棩鏈�:">
+        <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="鑷�" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" clearable />
+      </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="add" icon="Plus">鏂板閫�璐�</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <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)" v-if="row.status === 'pending'">缂栬緫</el-button>
+          <el-button type="success" link @click="handleAudit(row)" v-if="row.status === 'pending'">瀹℃牳</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫�璐у崟鍙�" prop="returnCode">
+              <el-input v-model="form.returnCode" placeholder="璇疯緭鍏ラ��璐у崟鍙�" :disabled="isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏宠仈鍑哄簱鍗�" prop="outCode">
+              <el-select v-model="form.outCode" placeholder="璇烽�夋嫨鍑哄簱鍗�" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in outList" :key="item.outCode" :label="item.outCode" :value="item.outCode" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛" prop="customerId">
+              <el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" :disabled="isEdit">
+                <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閫�璐ф棩鏈�" prop="returnDate">
+              <el-date-picker v-model="form.returnDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫�璐ч噾棰�" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閫�璐у師鍥�" prop="reason">
+              <el-input v-model="form.reason" placeholder="璇疯緭鍏ラ��璐у師鍥�" />
+            </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 @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "閿�鍞��璐�",
+});
+
+const filters = reactive({
+  returnCode: "",
+  customerId: "",
+  dateRange: [],
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "閫�璐у崟鍙�", prop: "returnCode", width: "150" },
+  { label: "瀹㈡埛鍚嶇О", prop: "customerName", width: "180" },
+  { label: "鍏宠仈鍑哄簱鍗�", prop: "outCode", width: "150" },
+  { label: "閫�璐ф棩鏈�", prop: "returnDate", width: "120" },
+  { label: "閫�璐ч噾棰�", prop: "amount", width: "120" },
+  { label: "閫�璐у師鍥�", prop: "reason", width: "150", showOverflowTooltip: true },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "200", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const customerList = [
+  { id: 1, name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+  { id: 2, name: "涓婃捣璐告槗鍏徃" },
+  { id: 3, name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+  { id: 4, name: "娣卞湷鐢靛瓙鍏徃" },
+];
+
+const outList = [
+  { outCode: "CK2024001", customerId: 1 },
+  { outCode: "CK2024002", customerId: 2 },
+  { outCode: "CK2024003", customerId: 3 },
+];
+
+const form = reactive({
+  returnCode: "",
+  outCode: "",
+  customerId: "",
+  returnDate: "",
+  amount: 0,
+  reason: "",
+  remark: "",
+});
+
+const rules = {
+  returnCode: [{ required: true, message: "璇疯緭鍏ラ��璐у崟鍙�", trigger: "blur" }],
+  outCode: [{ required: true, message: "璇烽�夋嫨鍏宠仈鍑哄簱鍗�", trigger: "change" }],
+  customerId: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
+  returnDate: [{ required: true, message: "璇烽�夋嫨閫�璐ф棩鏈�", trigger: "change" }],
+  amount: [{ required: true, message: "璇疯緭鍏ラ��璐ч噾棰�", trigger: "blur" }],
+};
+
+const mockData = [
+  { id: 1, returnCode: "TH2024001", outCode: "CK2024001", customerId: 1, customerName: "鍖椾含绉戞妧鏈夐檺鍏徃", returnDate: "2024-01-20", amount: 1000, reason: "璐ㄩ噺闂", status: "approved", remark: "" },
+  { id: 2, returnCode: "TH2024002", outCode: "CK2024002", customerId: 2, customerName: "涓婃捣璐告槗鍏徃", returnDate: "2024-01-22", amount: 500, reason: "瑙勬牸涓嶇", status: "pending", remark: "" },
+];
+
+const getStatusLabel = (status) => {
+  const map = { pending: "寰呭鏍�", approved: "宸插鏍�", rejected: "宸查┏鍥�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { pending: "warning", approved: "success", rejected: "danger" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.returnCode) {
+    result = result.filter(item => item.returnCode.includes(filters.returnCode));
+  }
+  if (filters.customerId) {
+    result = result.filter(item => item.customerId === filters.customerId);
+  }
+  if (filters.dateRange && filters.dateRange.length === 2) {
+    result = result.filter(item => item.returnDate >= filters.dateRange[0] && item.returnDate <= filters.dateRange[1]);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.returnCode = "";
+  filters.customerId = "";
+  filters.dateRange = [];
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板閫�璐�";
+  Object.assign(form, {
+    returnCode: "TH" + Date.now(),
+    outCode: "",
+    customerId: "",
+    returnDate: "",
+    amount: 0,
+    reason: "",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫閫�璐�";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅閫�璐у崟: ${row.returnCode}`);
+};
+
+const handleAudit = (row) => {
+  ElMessageBox.confirm("纭瀹℃牳閫氳繃璇ラ��璐у崟鍚楋紵", "鎻愮ず", {
+    confirmButtonText: "閫氳繃",
+    cancelButtonText: "椹冲洖",
+    distinguishCancelAndClose: true,
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "approved";
+    }
+    ElMessage.success("瀹℃牳閫氳繃");
+    getTableData();
+  }).catch((action) => {
+    if (action === "cancel") {
+      const index = mockData.findIndex(item => item.id === row.id);
+      if (index !== -1) {
+        mockData[index].status = "rejected";
+      }
+      ElMessage.warning("宸查┏鍥�");
+      getTableData();
+    }
+  });
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const customer = customerList.find(item => item.id === form.customerId);
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, customerName: customer?.name };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, customerName: customer?.name, status: "pending" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 15px;
+}
+</style>
diff --git a/src/views/financialManagement/voucher/detailLedger.vue b/src/views/financialManagement/voucher/detailLedger.vue
new file mode 100644
index 0000000..7f85790
--- /dev/null
+++ b/src/views/financialManagement/voucher/detailLedger.vue
@@ -0,0 +1,289 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="浼氳绉戠洰:">
+        <el-cascader v-model="filters.subject" :options="subjectOptions" :props="{ label: 'name', value: 'code' }" placeholder="璇烽�夋嫨浼氳绉戠洰" clearable style="width: 250px;" filterable />
+      </el-form-item>
+      <el-form-item label="杈呭姪鏍哥畻:">
+        <el-select v-model="filters.auxiliary" placeholder="璇烽�夋嫨杈呭姪鏍哥畻" clearable style="width: 180px;">
+          <el-option label="瀹㈡埛" value="customer" />
+          <el-option label="渚涘簲鍟�" value="supplier" />
+          <el-option label="閮ㄩ棬" value="department" />
+          <el-option label="鍛樺伐" value="employee" />
+          <el-option label="椤圭洰" value="project" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鏍哥畻瀵硅薄:">
+        <el-select v-model="filters.auxiliaryItem" placeholder="璇烽�夋嫨鏍哥畻瀵硅薄" clearable style="width: 200px;" :disabled="!filters.auxiliary">
+          <el-option v-for="item in auxiliaryItems" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鏈熼棿:">
+        <el-date-picker v-model="filters.startMonth" type="month" placeholder="寮�濮嬫湀浠�" value-format="YYYY-MM" style="width: 140px;" />
+        <span style="margin: 0 10px;">鑷�</span>
+        <el-date-picker v-model="filters.endMonth" type="month" placeholder="缁撴潫鏈堜唤" value-format="YYYY-MM" style="width: 140px;" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="getTableData">鏌ヨ</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
+        <el-button @click="handlePrint" icon="Printer">鎵撳嵃</el-button>
+        <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+      </el-form-item>
+    </el-form>
+
+    <div class="ledger-header" v-if="currentSubject">
+      <h2>绉戠洰鏄庣粏璐�</h2>
+      <p>绉戠洰: {{ currentSubject.code }} {{ currentSubject.name }}</p>
+      <p v-if="filters.auxiliary && filters.auxiliaryItem">杈呭姪鏍哥畻: {{ getAuxiliaryLabel() }}</p>
+      <p>鏈熼棿: {{ filters.startMonth }} 鑷� {{ filters.endMonth }}</p>
+    </div>
+
+    <div class="table_list">
+      <el-table :data="dataList" border style="width: 100%" show-summary :summary-method="getSummaries">
+        <el-table-column prop="date" label="鏃ユ湡" width="120" />
+        <el-table-column prop="voucherNo" label="鍑瘉瀛楀彿" width="120" />
+        <el-table-column prop="summary" label="鎽樿" min-width="200" show-overflow-tooltip />
+        <el-table-column label="鍊熸柟" width="150">
+          <template #default="{ row }">
+            <span v-if="row.debit > 0" class="text-danger">楼{{ formatMoney(row.debit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="璐锋柟" width="150">
+          <template #default="{ row }">
+            <span v-if="row.credit > 0" class="text-success">楼{{ formatMoney(row.credit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏂瑰悜" width="80">
+          <template #default="{ row }">
+            <el-tag :type="row.direction === '鍊�' ? 'success' : 'danger'" size="small">{{ row.direction }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="浣欓" width="150">
+          <template #default="{ row }">
+            <span :class="row.balance >= 0 ? 'text-primary' : 'text-warning'">楼{{ formatMoney(Math.abs(row.balance)) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <el-empty v-if="!currentSubject" description="璇烽�夋嫨浼氳绉戠洰鏌ヨ" style="margin-top: 50px;" />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed, watch } from "vue";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "绉戠洰鏄庣粏璐�",
+});
+
+const filters = reactive({
+  subject: [],
+  auxiliary: "",
+  auxiliaryItem: "",
+  startMonth: "2024-01",
+  endMonth: "2024-03",
+});
+
+const dataList = ref([]);
+
+const subjectOptions = [
+  {
+    code: "1122",
+    name: "搴旀敹璐︽",
+    children: [
+      { code: "112201", name: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+      { code: "112202", name: "涓婃捣璐告槗鍏徃" },
+      { code: "112203", name: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+    ],
+  },
+  {
+    code: "2202",
+    name: "搴斾粯璐︽",
+    children: [
+      { code: "220201", name: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+      { code: "220202", name: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+      { code: "220203", name: "骞垮窞鍖呰鏉愭枡鍘�" },
+    ],
+  },
+  {
+    code: "6602",
+    name: "绠$悊璐圭敤",
+    children: [
+      { code: "660201", name: "鍔炲叕璐�" },
+      { code: "660202", name: "宸梾璐�" },
+      { code: "660203", name: "涓氬姟鎷涘緟璐�" },
+    ],
+  },
+];
+
+const auxiliaryItems = computed(() => {
+  const map = {
+    customer: [
+      { value: "1", label: "鍖椾含绉戞妧鏈夐檺鍏徃" },
+      { value: "2", label: "涓婃捣璐告槗鍏徃" },
+      { value: "3", label: "骞垮窞瀹炰笟鏈夐檺鍏徃" },
+    ],
+    supplier: [
+      { value: "1", label: "鍖椾含鍘熸潗鏂欎緵搴斿晢" },
+      { value: "2", label: "涓婃捣鐢靛瓙鍏冨櫒浠跺叕鍙�" },
+      { value: "3", label: "骞垮窞鍖呰鏉愭枡鍘�" },
+    ],
+    department: [
+      { value: "1", label: "璐㈠姟閮�" },
+      { value: "2", label: "閿�鍞儴" },
+      { value: "3", label: "閲囪喘閮�" },
+    ],
+    employee: [
+      { value: "1", label: "寮犱笁" },
+      { value: "2", label: "鏉庡洓" },
+      { value: "3", label: "鐜嬩簲" },
+    ],
+    project: [
+      { value: "1", label: "椤圭洰A" },
+      { value: "2", label: "椤圭洰B" },
+      { value: "3", label: "椤圭洰C" },
+    ],
+  };
+  return map[filters.auxiliary] || [];
+});
+
+watch(() => filters.auxiliary, () => {
+  filters.auxiliaryItem = "";
+});
+
+const currentSubject = computed(() => {
+  if (!filters.subject || filters.subject.length === 0) return null;
+  const code = filters.subject[filters.subject.length - 1];
+  return findSubject(subjectOptions, code);
+});
+
+const findSubject = (options, code) => {
+  for (const item of options) {
+    if (item.code === code) return item;
+    if (item.children && item.children.length > 0) {
+      const found = findSubject(item.children, code);
+      if (found) return found;
+    }
+  }
+  return null;
+};
+
+const getAuxiliaryLabel = () => {
+  const item = auxiliaryItems.value.find(i => i.value === filters.auxiliaryItem);
+  return item ? item.label : "";
+};
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const mockData = [
+  { date: "2024-01-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 10000 },
+  { date: "2024-01-05", voucherNo: "璁�-0001", summary: "閿�鍞嚭搴�", debit: 5000, credit: 0, direction: "鍊�", balance: 15000 },
+  { date: "2024-01-10", voucherNo: "璁�-0002", summary: "鏀跺埌璐ф", debit: 0, credit: 3000, direction: "鍊�", balance: 12000 },
+  { date: "2024-01-15", voucherNo: "璁�-0003", summary: "閿�鍞嚭搴�", debit: 8000, credit: 0, direction: "鍊�", balance: 20000 },
+  { date: "2024-01-20", voucherNo: "璁�-0004", summary: "閿�鍞��璐�", debit: 0, credit: 2000, direction: "鍊�", balance: 18000 },
+  { date: "2024-01-25", voucherNo: "璁�-0005", summary: "鏀跺埌璐ф", debit: 0, credit: 5000, direction: "鍊�", balance: 13000 },
+  { date: "2024-01-31", voucherNo: "-", summary: "鏈湀鍚堣", debit: 13000, credit: 10000, direction: "鍊�", balance: 13000 },
+  { date: "2024-02-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 13000 },
+  { date: "2024-02-10", voucherNo: "璁�-0006", summary: "閿�鍞嚭搴�", debit: 6000, credit: 0, direction: "鍊�", balance: 19000 },
+  { date: "2024-02-15", voucherNo: "璁�-0007", summary: "鏀跺埌璐ф", debit: 0, credit: 4000, direction: "鍊�", balance: 15000 },
+  { date: "2024-02-28", voucherNo: "-", summary: "鏈湀鍚堣", debit: 6000, credit: 4000, direction: "鍊�", balance: 15000 },
+  { date: "2024-03-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 15000 },
+  { date: "2024-03-05", voucherNo: "璁�-0008", summary: "閿�鍞嚭搴�", debit: 7000, credit: 0, direction: "鍊�", balance: 22000 },
+  { date: "2024-03-10", voucherNo: "璁�-0009", summary: "鏀跺埌璐ф", debit: 0, credit: 6000, direction: "鍊�", balance: 16000 },
+  { date: "2024-03-31", voucherNo: "-", summary: "鏈湀鍚堣", debit: 7000, credit: 6000, direction: "鍊�", balance: 16000 },
+  { date: "2024-03-31", voucherNo: "-", summary: "鏈勾绱", debit: 26000, credit: 20000, direction: "鍊�", balance: 16000 },
+];
+
+const getTableData = () => {
+  if (!currentSubject.value) {
+    dataList.value = [];
+    return;
+  }
+  dataList.value = [...mockData];
+};
+
+const resetFilters = () => {
+  filters.subject = [];
+  filters.auxiliary = "";
+  filters.auxiliaryItem = "";
+  filters.startMonth = "2024-01";
+  filters.endMonth = "2024-03";
+  dataList.value = [];
+};
+
+const getSummaries = (param) => {
+  const { columns, data } = param;
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = "鍚堣";
+      return;
+    }
+    if (column.property === "debit") {
+      const values = data.map(item => Number(item.debit));
+      const sum = values.reduce((prev, curr) => prev + curr, 0);
+      sums[index] = "楼" + formatMoney(sum);
+    } else if (column.property === "credit") {
+      const values = data.map(item => Number(item.credit));
+      const sum = values.reduce((prev, curr) => prev + curr, 0);
+      sums[index] = "楼" + formatMoney(sum);
+    } else {
+      sums[index] = "";
+    }
+  });
+  return sums;
+};
+
+const handlePrint = () => {
+  ElMessage.info("鎵撳嵃鍔熻兘");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  // 榛樿涓嶅姞杞芥暟鎹紝闇�瑕侀�夋嫨绉戠洰
+});
+</script>
+
+<style lang="scss" scoped>
+.ledger-header {
+  text-align: center;
+  margin-bottom: 20px;
+  h2 {
+    margin: 0 0 10px 0;
+  }
+  p {
+    color: #606266;
+    margin: 5px 0;
+  }
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+
+.text-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+
+.text-warning {
+  color: #e6a23c;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/voucher/generalLedger.vue b/src/views/financialManagement/voucher/generalLedger.vue
new file mode 100644
index 0000000..5da2d70
--- /dev/null
+++ b/src/views/financialManagement/voucher/generalLedger.vue
@@ -0,0 +1,230 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="浼氳绉戠洰:">
+        <el-cascader v-model="filters.subject" :options="subjectOptions" :props="{ label: 'name', value: 'code' }" placeholder="璇烽�夋嫨浼氳绉戠洰" clearable style="width: 250px;" filterable />
+      </el-form-item>
+      <el-form-item label="鏈熼棿:">
+        <el-date-picker v-model="filters.startMonth" type="month" placeholder="寮�濮嬫湀浠�" value-format="YYYY-MM" style="width: 140px;" />
+        <span style="margin: 0 10px;">鑷�</span>
+        <el-date-picker v-model="filters.endMonth" type="month" placeholder="缁撴潫鏈堜唤" value-format="YYYY-MM" style="width: 140px;" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="getTableData">鏌ヨ</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
+        <el-button @click="handlePrint" icon="Printer">鎵撳嵃</el-button>
+        <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+      </el-form-item>
+    </el-form>
+
+    <div class="ledger-header" v-if="currentSubject">
+      <h2>绉戠洰鎬昏处</h2>
+      <p>绉戠洰: {{ currentSubject.code }} {{ currentSubject.name }}</p>
+      <p>鏈熼棿: {{ filters.startMonth }} 鑷� {{ filters.endMonth }}</p>
+    </div>
+
+    <div class="table_list">
+      <el-table :data="dataList" border style="width: 100%" show-summary :summary-method="getSummaries">
+        <el-table-column prop="date" label="鏃ユ湡" width="120" />
+        <el-table-column prop="voucherNo" label="鍑瘉瀛楀彿" width="120" />
+        <el-table-column prop="summary" label="鎽樿" min-width="200" show-overflow-tooltip />
+        <el-table-column label="鍊熸柟" width="150">
+          <template #default="{ row }">
+            <span v-if="row.debit > 0" class="text-danger">楼{{ formatMoney(row.debit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="璐锋柟" width="150">
+          <template #default="{ row }">
+            <span v-if="row.credit > 0" class="text-success">楼{{ formatMoney(row.credit) }}</span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏂瑰悜" width="80">
+          <template #default="{ row }">
+            <el-tag :type="row.direction === '鍊�' ? 'success' : 'danger'" size="small">{{ row.direction }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="浣欓" width="150">
+          <template #default="{ row }">
+            <span :class="row.balance >= 0 ? 'text-primary' : 'text-warning'">楼{{ formatMoney(Math.abs(row.balance)) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <el-empty v-if="!currentSubject" description="璇烽�夋嫨浼氳绉戠洰鏌ヨ" style="margin-top: 50px;" />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "绉戠洰鎬昏处",
+});
+
+const filters = reactive({
+  subject: [],
+  startMonth: "2024-01",
+  endMonth: "2024-03",
+});
+
+const dataList = ref([]);
+
+const subjectOptions = [
+  {
+    code: "1001",
+    name: "搴撳瓨鐜伴噾",
+    children: [],
+  },
+  {
+    code: "1002",
+    name: "閾惰瀛樻",
+    children: [
+      { code: "100201", name: "宸ュ晢閾惰" },
+      { code: "100202", name: "寤鸿閾惰" },
+    ],
+  },
+  {
+    code: "1122",
+    name: "搴旀敹璐︽",
+    children: [],
+  },
+  {
+    code: "2202",
+    name: "搴斾粯璐︽",
+    children: [],
+  },
+  {
+    code: "6001",
+    name: "涓昏惀涓氬姟鏀跺叆",
+    children: [],
+  },
+];
+
+const currentSubject = computed(() => {
+  if (!filters.subject || filters.subject.length === 0) return null;
+  const code = filters.subject[filters.subject.length - 1];
+  return findSubject(subjectOptions, code);
+});
+
+const findSubject = (options, code) => {
+  for (const item of options) {
+    if (item.code === code) return item;
+    if (item.children && item.children.length > 0) {
+      const found = findSubject(item.children, code);
+      if (found) return found;
+    }
+  }
+  return null;
+};
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const mockData = [
+  { date: "2024-01-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 100000 },
+  { date: "2024-01-05", voucherNo: "璁�-0001", summary: "閿�鍞敹鍏�", debit: 5650, credit: 0, direction: "鍊�", balance: 105650 },
+  { date: "2024-01-10", voucherNo: "璁�-0002", summary: "閲囪喘鏀嚭", debit: 0, credit: 8000, direction: "鍊�", balance: 97650 },
+  { date: "2024-01-15", voucherNo: "璁�-0003", summary: "鏀跺埌璐ф", debit: 10000, credit: 0, direction: "鍊�", balance: 107650 },
+  { date: "2024-01-20", voucherNo: "璁�-0004", summary: "鏀粯璐圭敤", debit: 0, credit: 5000, direction: "鍊�", balance: 102650 },
+  { date: "2024-01-31", voucherNo: "-", summary: "鏈湀鍚堣", debit: 15650, credit: 13000, direction: "鍊�", balance: 102650 },
+  { date: "2024-02-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 102650 },
+  { date: "2024-02-10", voucherNo: "璁�-0005", summary: "閿�鍞敹鍏�", debit: 8000, credit: 0, direction: "鍊�", balance: 110650 },
+  { date: "2024-02-15", voucherNo: "璁�-0006", summary: "閲囪喘鏀嚭", debit: 0, credit: 12000, direction: "鍊�", balance: 98650 },
+  { date: "2024-02-28", voucherNo: "-", summary: "鏈湀鍚堣", debit: 8000, credit: 12000, direction: "鍊�", balance: 98650 },
+  { date: "2024-03-01", voucherNo: "-", summary: "鏈熷垵浣欓", debit: 0, credit: 0, direction: "鍊�", balance: 98650 },
+  { date: "2024-03-05", voucherNo: "璁�-0007", summary: "閿�鍞敹鍏�", debit: 12000, credit: 0, direction: "鍊�", balance: 110650 },
+  { date: "2024-03-10", voucherNo: "璁�-0008", summary: "鏀粯宸ヨ祫", debit: 0, credit: 15000, direction: "鍊�", balance: 95650 },
+  { date: "2024-03-31", voucherNo: "-", summary: "鏈湀鍚堣", debit: 12000, credit: 15000, direction: "鍊�", balance: 95650 },
+  { date: "2024-03-31", voucherNo: "-", summary: "鏈勾绱", debit: 35650, credit: 40000, direction: "鍊�", balance: 95650 },
+];
+
+const getTableData = () => {
+  if (!currentSubject.value) {
+    dataList.value = [];
+    return;
+  }
+  dataList.value = [...mockData];
+};
+
+const resetFilters = () => {
+  filters.subject = [];
+  filters.startMonth = "2024-01";
+  filters.endMonth = "2024-03";
+  dataList.value = [];
+};
+
+const getSummaries = (param) => {
+  const { columns, data } = param;
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = "鍚堣";
+      return;
+    }
+    if (column.property === "debit") {
+      const values = data.map(item => Number(item.debit));
+      const sum = values.reduce((prev, curr) => prev + curr, 0);
+      sums[index] = "楼" + formatMoney(sum);
+    } else if (column.property === "credit") {
+      const values = data.map(item => Number(item.credit));
+      const sum = values.reduce((prev, curr) => prev + curr, 0);
+      sums[index] = "楼" + formatMoney(sum);
+    } else {
+      sums[index] = "";
+    }
+  });
+  return sums;
+};
+
+const handlePrint = () => {
+  ElMessage.info("鎵撳嵃鍔熻兘");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+onMounted(() => {
+  // 榛樿涓嶅姞杞芥暟鎹紝闇�瑕侀�夋嫨绉戠洰
+});
+</script>
+
+<style lang="scss" scoped>
+.ledger-header {
+  text-align: center;
+  margin-bottom: 20px;
+  h2 {
+    margin: 0 0 10px 0;
+  }
+  p {
+    color: #606266;
+    margin: 5px 0;
+  }
+}
+
+.text-primary {
+  color: #409eff;
+  font-weight: bold;
+}
+
+.text-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+
+.text-warning {
+  color: #e6a23c;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/financialManagement/voucher/index.vue b/src/views/financialManagement/voucher/index.vue
new file mode 100644
index 0000000..440336f
--- /dev/null
+++ b/src/views/financialManagement/voucher/index.vue
@@ -0,0 +1,418 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="鍑瘉瀛楀彿:">
+        <el-input v-model="filters.voucherNo" placeholder="璇疯緭鍏ュ嚟璇佸瓧鍙�" clearable style="width: 200px;" />
+      </el-form-item>
+      <el-form-item label="鍑瘉鏃ユ湡:">
+        <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="鑷�" start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" clearable />
+      </el-form-item>
+      <el-form-item label="鍒跺崟浜�:">
+        <el-select v-model="filters.creator" placeholder="璇烽�夋嫨鍒跺崟浜�" clearable style="width: 150px;">
+          <el-option label="寮犱笁" value="寮犱笁" />
+          <el-option label="鏉庡洓" value="鏉庡洓" />
+          <el-option label="鐜嬩簲" value="鐜嬩簲" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鐘舵��:">
+        <el-select v-model="filters.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px;">
+          <el-option label="鏈繃璐�" value="unposted" />
+          <el-option label="宸茶繃璐�" value="posted" />
+          <el-option label="宸蹭綔搴�" value="cancelled" />
+        </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="totalDebit" precision="2" prefix="楼" />
+          <el-statistic title="璐锋柟鍚堣" :value="totalCredit" precision="2" prefix="楼" style="margin-left: 30px;" />
+        </div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus">鏂板鍑瘉</el-button>
+          <el-button @click="handleImport" icon="Upload">瀵煎叆</el-button>
+          <el-button @click="handleOut" icon="Download">瀵煎嚭</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="dataList"
+        :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+        @pagination="changePage"
+      >
+        <template #debit="{ row }">
+          <span class="text-danger" v-if="row.debit > 0">楼{{ formatMoney(row.debit) }}</span>
+          <span v-else>-</span>
+        </template>
+        <template #credit="{ row }">
+          <span class="text-success" v-if="row.credit > 0">楼{{ formatMoney(row.credit) }}</span>
+          <span v-else>-</span>
+        </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)" v-if="row.status === 'unposted'">缂栬緫</el-button>
+          <el-button type="success" link @click="handlePost(row)" v-if="row.status === 'unposted'">杩囪处</el-button>
+          <el-button type="danger" link @click="handleCancel(row)" v-if="row.status === 'unposted'">浣滃簾</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="900px" append-to-body>
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鍑瘉瀛楀彿" prop="voucherNo">
+              <el-input v-model="form.voucherNo" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鍑瘉鏃ユ湡" prop="voucherDate">
+              <el-date-picker v-model="form.voucherDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="闄勪欢寮犳暟" prop="attachmentCount">
+              <el-input-number v-model="form.attachmentCount" :min="0" style="width: 100%;" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍑瘉鍒嗗綍" prop="entries">
+          <el-table :data="form.entries" border style="width: 100%">
+            <el-table-column type="index" label="搴忓彿" width="60" />
+            <el-table-column prop="subjectCode" label="绉戠洰缂栫爜" width="120">
+              <template #default="{ $index }">
+                <el-select v-model="form.entries[$index].subjectCode" placeholder="閫夋嫨绉戠洰" filterable style="width: 100%;" @change="(val) => handleSubjectChange(val, $index)">
+                  <el-option v-for="item in subjectList" :key="item.code" :label="item.code" :value="item.code" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column prop="subjectName" label="绉戠洰鍚嶇О" width="150">
+              <template #default="{ $index }">
+                <el-input v-model="form.entries[$index].subjectName" disabled />
+              </template>
+            </el-table-column>
+            <el-table-column prop="summary" label="鎽樿">
+              <template #default="{ $index }">
+                <el-input v-model="form.entries[$index].summary" placeholder="璇疯緭鍏ユ憳瑕�" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="debit" label="鍊熸柟閲戦" width="130">
+              <template #default="{ $index }">
+                <el-input-number v-model="form.entries[$index].debit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" />
+              </template>
+            </el-table-column>
+            <el-table-column prop="credit" label="璐锋柟閲戦" width="130">
+              <template #default="{ $index }">
+                <el-input-number v-model="form.entries[$index].credit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" />
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="80">
+              <template #default="{ $index }">
+                <el-button type="danger" link @click="removeEntry($index)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div style="display: flex; justify-content: space-between; margin-top: 10px;">
+            <el-button type="primary" link @click="addEntry">+ 娣诲姞鍒嗗綍</el-button>
+            <div>
+              <span style="margin-right: 20px;">鍚堣: 鍊熸柟 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">楼{{ formatMoney(totalDebitEntry) }}</span></span>
+              <span>璐锋柟 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">楼{{ formatMoney(totalCreditEntry) }}</span></span>
+            </div>
+          </div>
+        </el-form-item>
+        <el-form-item label="鍒跺崟浜�" prop="creator">
+          <el-input v-model="form.creator" disabled />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="submitForm" :disabled="totalDebitEntry !== totalCreditEntry">纭畾</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+defineOptions({
+  name: "鍑瘉绠$悊",
+});
+
+const filters = reactive({
+  voucherNo: "",
+  dateRange: [],
+  creator: "",
+  status: "",
+});
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+const columns = [
+  { label: "鍑瘉瀛楀彿", prop: "voucherNo", width: "120" },
+  { label: "鍑瘉鏃ユ湡", prop: "voucherDate", width: "120" },
+  { label: "鎽樿", prop: "summary", showOverflowTooltip: true },
+  { label: "鍊熸柟閲戦", prop: "debit", slot: "debit" },
+  { label: "璐锋柟閲戦", prop: "credit", slot: "credit" },
+  { label: "鍒跺崟浜�", prop: "creator", width: "100" },
+  { label: "鐘舵��", prop: "status", slot: "status" },
+  { label: "鎿嶄綔", prop: "operation", slot: "operation", width: "220", fixed: "right" },
+];
+
+const dataList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const formRef = ref(null);
+const isEdit = ref(false);
+const currentId = ref(null);
+
+const subjectList = [
+  { code: "1001", name: "搴撳瓨鐜伴噾" },
+  { code: "1002", name: "閾惰瀛樻" },
+  { code: "1122", name: "搴旀敹璐︽" },
+  { code: "2202", name: "搴斾粯璐︽" },
+  { code: "5001", name: "鐢熶骇鎴愭湰" },
+  { code: "6001", name: "涓昏惀涓氬姟鏀跺叆" },
+  { code: "6401", name: "涓昏惀涓氬姟鎴愭湰" },
+];
+
+const form = reactive({
+  voucherNo: "",
+  voucherDate: "",
+  attachmentCount: 0,
+  entries: [],
+  creator: "寮犱笁",
+  remark: "",
+});
+
+const rules = {
+  voucherDate: [{ required: true, message: "璇烽�夋嫨鍑瘉鏃ユ湡", trigger: "change" }],
+};
+
+const mockData = [
+  { id: 1, voucherNo: "璁�-0001", voucherDate: "2024-01-15", summary: "閿�鍞敹鍏�", debit: 5650, credit: 5650, creator: "寮犱笁", status: "posted", entries: [{ subjectCode: "1002", subjectName: "閾惰瀛樻", summary: "閿�鍞敹鍏�", debit: 5650, credit: 0 }, { subjectCode: "6001", subjectName: "涓昏惀涓氬姟鏀跺叆", summary: "閿�鍞敹鍏�", debit: 0, credit: 5000 }, { subjectCode: "2221", subjectName: "搴斾氦绋庤垂", summary: "閿�椤圭◣棰�", debit: 0, credit: 650 }] },
+  { id: 2, voucherNo: "璁�-0002", voucherDate: "2024-01-16", summary: "閲囪喘鍘熸潗鏂�", debit: 9040, credit: 9040, creator: "鏉庡洓", status: "unposted", entries: [{ subjectCode: "5001", subjectName: "鐢熶骇鎴愭湰", summary: "閲囪喘鍘熸潗鏂�", debit: 8000, credit: 0 }, { subjectCode: "2221", subjectName: "搴斾氦绋庤垂", summary: "杩涢」绋庨", debit: 1040, credit: 0 }, { subjectCode: "2202", subjectName: "搴斾粯璐︽", summary: "閲囪喘鍘熸潗鏂�", debit: 0, credit: 9040 }] },
+  { id: 3, voucherNo: "璁�-0003", voucherDate: "2024-01-18", summary: "鏀粯璐ф", debit: 5000, credit: 5000, creator: "寮犱笁", status: "posted", entries: [{ subjectCode: "2202", subjectName: "搴斾粯璐︽", summary: "鏀粯璐ф", debit: 5000, credit: 0 }, { subjectCode: "1002", subjectName: "閾惰瀛樻", summary: "鏀粯璐ф", debit: 0, credit: 5000 }] },
+];
+
+const totalDebit = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.debit), 0);
+});
+
+const totalCredit = computed(() => {
+  return dataList.value.reduce((sum, item) => sum + Number(item.credit), 0);
+});
+
+const totalDebitEntry = computed(() => {
+  return form.entries.reduce((sum, item) => sum + Number(item.debit || 0), 0);
+});
+
+const totalCreditEntry = computed(() => {
+  return form.entries.reduce((sum, item) => sum + Number(item.credit || 0), 0);
+});
+
+const formatMoney = (value) => {
+  if (value === undefined || value === null) return "0.00";
+  return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+};
+
+const getStatusLabel = (status) => {
+  const map = { unposted: "鏈繃璐�", posted: "宸茶繃璐�", cancelled: "宸蹭綔搴�" };
+  return map[status] || status;
+};
+
+const getStatusType = (status) => {
+  const map = { unposted: "warning", posted: "success", cancelled: "info" };
+  return map[status] || "";
+};
+
+const getTableData = () => {
+  let result = [...mockData];
+  if (filters.voucherNo) {
+    result = result.filter(item => item.voucherNo.includes(filters.voucherNo));
+  }
+  if (filters.dateRange && filters.dateRange.length === 2) {
+    result = result.filter(item => item.voucherDate >= filters.dateRange[0] && item.voucherDate <= filters.dateRange[1]);
+  }
+  if (filters.creator) {
+    result = result.filter(item => item.creator === filters.creator);
+  }
+  if (filters.status) {
+    result = result.filter(item => item.status === filters.status);
+  }
+  pagination.total = result.length;
+  dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize);
+};
+
+const resetFilters = () => {
+  filters.voucherNo = "";
+  filters.dateRange = [];
+  filters.creator = "";
+  filters.status = "";
+  pagination.currentPage = 1;
+  getTableData();
+};
+
+const changePage = ({ current, size }) => {
+  pagination.currentPage = current;
+  pagination.pageSize = size;
+  getTableData();
+};
+
+const addEntry = () => {
+  form.entries.push({ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 });
+};
+
+const removeEntry = (index) => {
+  form.entries.splice(index, 1);
+  calculateTotal();
+};
+
+const handleSubjectChange = (val, index) => {
+  const subject = subjectList.find(item => item.code === val);
+  if (subject) {
+    form.entries[index].subjectName = subject.name;
+  }
+};
+
+const calculateTotal = () => {
+  // 鑷姩璁$畻锛岀敱computed灞炴�у鐞�
+};
+
+const add = () => {
+  isEdit.value = false;
+  dialogTitle.value = "鏂板鍑瘉";
+  Object.assign(form, {
+    voucherNo: "璁�-" + String(mockData.length + 1).padStart(4, "0"),
+    voucherDate: new Date().toISOString().split('T')[0],
+    attachmentCount: 0,
+    entries: [{ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }],
+    creator: "寮犱笁",
+    remark: "",
+  });
+  dialogVisible.value = true;
+};
+
+const edit = (row) => {
+  isEdit.value = true;
+  currentId.value = row.id;
+  dialogTitle.value = "缂栬緫鍑瘉";
+  Object.assign(form, row);
+  dialogVisible.value = true;
+};
+
+const view = (row) => {
+  ElMessage.info(`鏌ョ湅鍑瘉: ${row.voucherNo}`);
+};
+
+const handlePost = (row) => {
+  ElMessageBox.confirm("纭杩囪处璇ュ嚟璇佸悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "info",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "posted";
+    }
+    ElMessage.success("杩囪处鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleCancel = (row) => {
+  ElMessageBox.confirm("纭浣滃簾璇ュ嚟璇佸悧锛�", "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    const index = mockData.findIndex(item => item.id === row.id);
+    if (index !== -1) {
+      mockData[index].status = "cancelled";
+    }
+    ElMessage.success("浣滃簾鎴愬姛");
+    getTableData();
+  });
+};
+
+const handleImport = () => {
+  ElMessage.info("瀵煎叆鍔熻兘");
+};
+
+const handleOut = () => {
+  ElMessage.success("瀵煎嚭鎴愬姛");
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      if (totalDebitEntry.value !== totalCreditEntry.value) {
+        ElMessage.error("鍊熻捶涓嶅钩琛★紝璇锋鏌ュ垎褰�");
+        return;
+      }
+      const summary = form.entries.find(e => e.debit > 0)?.summary || "";
+      if (isEdit.value) {
+        const index = mockData.findIndex(item => item.id === currentId.value);
+        if (index !== -1) {
+          mockData[index] = { ...mockData[index], ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value };
+        }
+        ElMessage.success("缂栬緫鎴愬姛");
+      } else {
+        const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1;
+        mockData.push({ id: newId, ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value, status: "unposted" });
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+      getTableData();
+    }
+  });
+};
+
+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-success {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.text-danger {
+  color: #f56c6c;
+  font-weight: bold;
+}
+</style>

--
Gitblit v1.9.3