From 648003a577ef7a03046269c77fc5cc64199945e7 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期二, 20 一月 2026 17:06:47 +0800
Subject: [PATCH] Merge branch 'dev_tide' into dev_tide_zlglxt_xinlan
---
src/views/index.vue | 250 +-
src/api/collaborativeApproval/enterpriseBook.js | 4
src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue | 147 +
src/api/procurementManagement/procurementLedger.js | 115
src/api/productionManagement/productionOrder.js | 2
src/views/system/user/authRole.vue | 2
src/views/environmentAccess/accessManagement/index.vue | 347 ++++
src/views/inventoryManagement/stockWarningLedger/index.vue | 347 ++++
src/utils/auth.js | 9
src/views/monitor/logininfor/index.vue | 2
src/views/monitor/operlog/index.vue | 2
src/api/inventoryManagement/stockManage.js | 2
src/views/salesManagement/invoiceLedger/index.vue | 6
src/views/system/role/authUser.vue | 2
src/views/monitor/job/log.vue | 2
src/views/equipmentManagement/ledger/index.vue | 18
vite.config.js | 14
src/api/inventoryManagement/stockWarningLedger.js | 10
src/views/personnelManagement/onboarding/index.vue | 348 ++++
src/views/productionManagement/operationScheduling/components/formDia.vue | 4
src/store/modules/user.js | 3
src/views/system/post/index.vue | 2
src/views/productionManagement/safetyMonitoring/index.vue | 4
src/views/energyManagement/gasManagement/index.vue | 2
src/router/index.js | 5
src/views/productionManagement/productionReporting/index.vue | 2
src/views/tool/gen/index.vue | 1
.env.production | 2
src/views/financialManagement/fundsManagement/index.vue | 298 +++
src/views/system/notice/index.vue | 2
src/api/financialManagement/financialReconciliation.js | 37
src/views/inventoryManagement/receiptManagement/components/formDia.vue | 3
src/views/salesManagement/receiptPaymentHistory/index.vue | 13
src/views/system/dict/index.vue | 2
src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue | 163 +
src/views/system/config/index.vue | 2
src/views/system/role/index.vue | 2
src/views/tideLogin.vue | 24
src/views/salesManagement/receiptPaymentLedger/index.vue | 2
src/views/productionManagement/productionDispatching/components/formDia.vue | 11
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue | 11
src/views/salesManagement/salesLedger/index.vue | 28
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue | 10
src/views/system/menu/index.vue | 1
src/api/financialManagement/fundsManagement.js | 37
src/views/system/dict/data.vue | 2
src/views/system/role/selectUser.vue | 2
src/views/tool/gen/editTable.vue | 2
src/views/tool/gen/importTable.vue | 2
src/views/salesManagement/salesLedger/fileList.vue | 2
src/views/environmentAccess/vehicleInformationCollection/index.vue | 577 ++++++
src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue | 230 +
src/views/monitor/job/index.vue | 2
src/views/demo/fakePage/index.vue | 2
src/views/environmentAccess/intelligentInspectionManagement/index.vue | 581 ++++++
src/views/environmentAccess/remoteMonitoringOfEquipment/index.vue | 633 +++++++
src/views/equipmentManagement/repair/index.vue | 1
src/components/PIMTable/PIMTable.vue | 1
src/views/monitor/online/index.vue | 1
src/views/financialManagement/financialReconciliation/index.vue | 291 +++
src/views/procurementManagement/paymentLedger/index.vue | 1
src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue | 2
src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue | 310 +++
src/views/energyManagement/dynamicEnergySaving/index.vue | 4
src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue | 147 +
65 files changed, 4,756 insertions(+), 337 deletions(-)
diff --git a/.env.production b/.env.production
index eee707f..5ac0eec 100644
--- a/.env.production
+++ b/.env.production
@@ -1,5 +1,5 @@
# 椤甸潰鏍囬
-VITE_APP_TITLE = 涓皬浼佷笟鏁板瓧鍖栬浆鍨嬩簩绾у椁愬寘
+VITE_APP_TITLE = 鏂扮紗-璐ㄩ噺妫�娴嬬鐞嗙郴缁�
# 鐢熶骇鐜閰嶇疆
VITE_APP_ENV = 'production'
diff --git a/src/api/collaborativeApproval/enterpriseBook.js b/src/api/collaborativeApproval/enterpriseBook.js
index 2140b89..4cc451a 100644
--- a/src/api/collaborativeApproval/enterpriseBook.js
+++ b/src/api/collaborativeApproval/enterpriseBook.js
@@ -8,7 +8,7 @@
method: 'get',
params: {
...page,
- ...query
+ ...query
}
})
}
@@ -64,4 +64,4 @@
url: '/staff/staffOnJob/' + employeeId,
method: 'get'
})
-}
\ No newline at end of file
+}
diff --git a/src/api/financialManagement/financialReconciliation.js b/src/api/financialManagement/financialReconciliation.js
new file mode 100644
index 0000000..d2c08d1
--- /dev/null
+++ b/src/api/financialManagement/financialReconciliation.js
@@ -0,0 +1,37 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ璐㈠姟瀵硅处鍙拌处
+export const getReconciliationPage = (params) => {
+ return request({
+ url: "/finance/reconciliation/page",
+ method: "get",
+ params,
+ });
+};
+
+// 鏂板瀵硅处璁板綍
+export const addReconciliation = (data) => {
+ return request({
+ url: "/finance/reconciliation",
+ method: "post",
+ data,
+ });
+};
+
+// 鏇存柊瀵硅处璁板綍
+export const updateReconciliation = (data) => {
+ return request({
+ url: "/finance/reconciliation",
+ method: "put",
+ data,
+ });
+};
+
+// 鍒犻櫎瀵硅处璁板綍锛堟敮鎸佹壒閲忥級
+export const deleteReconciliation = (ids) => {
+ return request({
+ url: "/finance/reconciliation",
+ method: "delete",
+ data: ids,
+ });
+};
diff --git a/src/api/financialManagement/fundsManagement.js b/src/api/financialManagement/fundsManagement.js
new file mode 100644
index 0000000..a970638
--- /dev/null
+++ b/src/api/financialManagement/fundsManagement.js
@@ -0,0 +1,37 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ璧勯噾绠$悊鍙拌处
+export const getFundsPage = (params) => {
+ return request({
+ url: "/finance/funds/page",
+ method: "get",
+ params,
+ });
+};
+
+// 鏂板璧勯噾璁板綍
+export const addFunds = (data) => {
+ return request({
+ url: "/finance/funds",
+ method: "post",
+ data,
+ });
+};
+
+// 鏇存柊璧勯噾璁板綍
+export const updateFunds = (data) => {
+ return request({
+ url: "/finance/funds",
+ method: "put",
+ data,
+ });
+};
+
+// 鍒犻櫎璧勯噾璁板綍锛堟敮鎸佹壒閲忥級
+export const deleteFunds = (ids) => {
+ return request({
+ url: "/finance/funds",
+ method: "delete",
+ data: ids,
+ });
+};
diff --git a/src/api/inventoryManagement/stockManage.js b/src/api/inventoryManagement/stockManage.js
index e2a4ebf..3c196fd 100644
--- a/src/api/inventoryManagement/stockManage.js
+++ b/src/api/inventoryManagement/stockManage.js
@@ -80,4 +80,4 @@
})
}
-//
\ No newline at end of file
+//
diff --git a/src/api/inventoryManagement/stockWarningLedger.js b/src/api/inventoryManagement/stockWarningLedger.js
new file mode 100644
index 0000000..0cdeb2d
--- /dev/null
+++ b/src/api/inventoryManagement/stockWarningLedger.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request";
+
+// 鏌ヨ搴撳瓨棰勮鍙拌处鍒楄〃
+export const getStockWarningLedgerPage = (params) => {
+ return request({
+ url: "/customStorageWarning/pageList",
+ method: "get",
+ params,
+ });
+};
diff --git a/src/api/procurementManagement/procurementLedger.js b/src/api/procurementManagement/procurementLedger.js
index 69a23f7..06a0c7e 100644
--- a/src/api/procurementManagement/procurementLedger.js
+++ b/src/api/procurementManagement/procurementLedger.js
@@ -3,74 +3,101 @@
// 鍒嗛〉鏌ヨ
export function purchaseList(query) {
- return request({
- url: "/purchase/ledger/list",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/purchase/ledger/list",
+ method: "get",
+ params: query,
+ });
}
// 鏌ヨ鍚堝悓鍙�
export function getSalesNo(query) {
- return request({
- url: "/purchase/ledger/getSalesNo",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/purchase/ledger/getSalesNo",
+ method: "get",
+ params: query,
+ });
}
// 瀛愯〃鏍兼煡璇�
export function productList(query) {
- return request({
- url: "/sales/product/list",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/sales/product/list",
+ method: "get",
+ params: query,
+ });
}
// 鏂板銆佺紪杈�
export function addOrEditPurchase(query) {
- return request({
- url: "/purchase/ledger/addOrEditPurchase",
- method: "post",
- data: query,
- });
+ return request({
+ url: "/purchase/ledger/addOrEditPurchase",
+ method: "post",
+ data: query,
+ });
}
// 鍒犻櫎
export function delPurchase(query) {
- return request({
- url: "/purchase/ledger/delPurchase",
- method: "delete",
- data: query,
- });
+ return request({
+ url: "/purchase/ledger/delPurchase",
+ method: "delete",
+ data: query,
+ });
}
// 鏌ヨ璇︽儏
export function getPurchaseById(query) {
- return request({
- url: "/purchase/ledger/getPurchaseById",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/purchase/ledger/getPurchaseById",
+ method: "get",
+ params: query,
+ });
}
// 鏌ヨ璇︽儏
export function getOptions(query) {
- return request({
- url: "/system/supplier/getOptions",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/system/supplier/getOptions",
+ method: "get",
+ params: query,
+ });
}
// 鏌ヨ閲囪喘鍙拌处鍒楄〃
export function purchaseListPage(query) {
- return request({
- url: "/purchase/ledger/listPage",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/purchase/ledger/listPage",
+ method: "get",
+ params: query,
+ });
}
export function createPurchaseNo() {
- return request({
- url: "/purchase/ledger/createPurchaseNo",
- method: "get",
- });
+ return request({
+ url: "/purchase/ledger/createPurchaseNo",
+ method: "get",
+ });
+}
+export function updateApprovalStatus(query) {
+ return request({
+ url: "/purchase/ledger/updateApprovalStatus",
+ method: "post",
+ data: query,
+ });
+}
+
+// 淇濆瓨閲囪喘妯℃澘
+// /purchase/ledger/addPurchaseTemplate
+export function addPurchaseTemplate(data) {
+ return request({
+ url: "/purchase/ledger/addPurchaseTemplate",
+ method: "post",
+ data: data,
+ });
+}
+
+// 鏌ヨ閲囪喘妯℃澘
+// /purchase/ledger/getPurchaseTemplateList
+export function getPurchaseTemplateList(query) {
+ return request({
+ url: "/purchase/ledger/getPurchaseTemplateList",
+ method: "get",
+ params: query,
+ });
}
export function updateApprovalStatus(query) {
return request({
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index 9f110a7..48b274c 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -113,4 +113,4 @@
method: "post",
data: data,
});
-}
\ No newline at end of file
+}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index dfbc231..52becd6 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -15,6 +15,7 @@
:expand-row-keys="expandRowKeys"
:show-summary="isShowSummary"
:summary-method="summaryMethod"
+ stripe
@row-click="rowClick"
@current-change="currentChange"
@selection-change="handleSelectionChange"
diff --git a/src/router/index.js b/src/router/index.js
index e5dc580..49da85f 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -42,6 +42,11 @@
component: () => import("@/views/login"),
hidden: true,
},
+{
+ path: "/callbacklccpn",
+ component: () => import("@/views/tideLogin.vue"),
+ hidden: true,
+},
{
path: "/register",
component: () => import("@/views/register"),
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 4f3eab4..f17234c 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -115,9 +115,6 @@
.then((res) => {
setToken(res.token);
this.token = res.token
- Vue.prototype.uploadHeader = {
- Authorization: "Bearer " + res.token,
- };
resolve();
})
.catch((error) => {
diff --git a/src/utils/auth.js b/src/utils/auth.js
index 88d7b6c..3817d17 100644
--- a/src/utils/auth.js
+++ b/src/utils/auth.js
@@ -3,13 +3,16 @@
const TokenKey = 'Admin-Token'
export function getToken() {
- return Cookies.get(TokenKey)
+ // return Cookies.get(TokenKey)
+ return sessionStorage.getItem(TokenKey)
}
export function setToken(token) {
- return Cookies.set(TokenKey, token)
+ // return Cookies.set(TokenKey, token)
+ return sessionStorage.setItem(TokenKey, token)
}
export function removeToken() {
- return Cookies.remove(TokenKey)
+ // return Cookies.remove(TokenKey)
+ return sessionStorage.removeItem(TokenKey)
}
diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
index 42aebd1..87fd37e 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -6,7 +6,7 @@
width="700px"
@close="closeDia"
>
- <el-form :model="form" label-width="140px" label-position="top" ref="formRef">
+ <el-form :model="form" :rules="rules" label-width="140px" label-position="top" ref="formRef">
<el-row>
<el-col :span="24">
<el-form-item label="娴佺▼缂栧彿锛�" prop="approveId">
@@ -218,8 +218,12 @@
approveReason: "",
checkResult: "",
},
+ rules: {
+ // 浣跨敤閮ㄩ棬ID鍋氬繀濉牎楠岋紝閬垮厤鍚嶇О鏈悓姝ュ鑷磋鎶�
+ approveDeptId: [{ required: true, message: "璇烽�夋嫨鐢宠閮ㄩ棬", trigger: "change" }],
+ },
});
-const { form } = toRefs(data);
+const { form, rules } = toRefs(data);
// 鑺傜偣鏍囬
const getNodeTitle = (index, len) => {
@@ -346,4 +350,4 @@
width: 200px;
height: 60px;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/demo/fakePage/index.vue b/src/views/demo/fakePage/index.vue
index 42cef72..7ef8b89 100644
--- a/src/views/demo/fakePage/index.vue
+++ b/src/views/demo/fakePage/index.vue
@@ -23,7 +23,7 @@
<el-button type="success" plain style="float: right" @click="openCreate">鏂板</el-button>
</div>
- <el-table :data="pagedList" border style="width: 100%" height="480">
+ <el-table :data="pagedList" border style="width: 100%" height="480" stripe>
<el-table-column prop="id" label="缂栧彿" width="90" sortable />
<el-table-column prop="name" label="鍚嶇О" min-width="140" />
<el-table-column prop="category" label="绫诲埆" width="120" />
diff --git a/src/views/energyManagement/dynamicEnergySaving/index.vue b/src/views/energyManagement/dynamicEnergySaving/index.vue
index b641276..30b5f0f 100644
--- a/src/views/energyManagement/dynamicEnergySaving/index.vue
+++ b/src/views/energyManagement/dynamicEnergySaving/index.vue
@@ -143,7 +143,7 @@
<span>杈圭紭璁$畻妯″瀷閰嶇疆</span>
</template>
- <el-table :data="modelConfigs" style="width: 100%">
+ <el-table :data="modelConfigs" style="width: 100%" stripe>
<el-table-column prop="modelName" label="妯″瀷鍚嶇О" />
<el-table-column prop="version" label="鐗堟湰" />
<el-table-column prop="status" label="鐘舵��">
@@ -193,7 +193,7 @@
<!-- 浼樺寲鍘嗗彶瀵硅瘽妗� -->
<el-dialog v-model="historyDialogVisible" title="浼樺寲鍘嗗彶璁板綍" width="80%">
- <el-table :data="optimizationHistory" style="width: 100%">
+ <el-table :data="optimizationHistory" style="width: 100%" stripe>
<el-table-column prop="timestamp" label="鏃堕棿" />
<el-table-column prop="formationPressure" label="鍦板眰鍘嬪姏 (MPa)" />
<el-table-column prop="oldFrequency" label="鍘熼鐜� (Hz)" />
diff --git a/src/views/energyManagement/gasManagement/index.vue b/src/views/energyManagement/gasManagement/index.vue
index a9b9abe..f067f7c 100644
--- a/src/views/energyManagement/gasManagement/index.vue
+++ b/src/views/energyManagement/gasManagement/index.vue
@@ -143,7 +143,7 @@
</div>
</template>
- <el-table :data="deviceList" border style="width: 100%" v-loading="tableLoading">
+ <el-table :data="deviceList" border style="width: 100%" v-loading="tableLoading" stripe>
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
<el-table-column label="璁惧缂栧彿" prop="deviceCode" width="120" show-overflow-tooltip />
<el-table-column label="璁惧鍚嶇О" prop="deviceName" width="150" show-overflow-tooltip />
diff --git a/src/views/environmentAccess/accessManagement/index.vue b/src/views/environmentAccess/accessManagement/index.vue
new file mode 100644
index 0000000..587dc78
--- /dev/null
+++ b/src/views/environmentAccess/accessManagement/index.vue
@@ -0,0 +1,347 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="闂ㄧ鍚嶇О">
+ <el-input
+ v-model="filters.name"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ラ棬绂佸悕绉�"
+ clearable
+ :prefix-icon="Search"
+ @change="getTableData"
+ />
+ </el-form-item>
+ <el-form-item label="闂ㄧ鐘舵��">
+ <el-select
+ v-model="filters.status"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨闂ㄧ鐘舵��"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="姝e父" value="1"></el-option>
+ <el-option label="寮傚父" value="0"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍖哄煙">
+ <el-input
+ v-model="filters.area"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ュ尯鍩�"
+ clearable
+ :prefix-icon="Search"
+ @change="getTableData"
+ />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+ <el-button @click="resetFilters">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ <div class="table_list">
+ <div class="actions">
+ <div></div>
+ <div>
+ <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+ <el-button type="danger" icon="Delete" :disabled="multipleList.length <= 0" @click="batchDelete">鎵归噺鍒犻櫎</el-button>
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ isSelection
+ :column="columns"
+ :tableData="dataList"
+ :page="{
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ total: pagination.total,
+ }"
+ @selection-change="handleSelectionChange"
+ @pagination="changePage"
+ >
+ </PIMTable>
+ </div>
+ <!-- 鏂板缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+ <el-form :model="formData" label-width="100px">
+ <el-form-item label="闂ㄧ鍚嶇О" required>
+ <el-input v-model="formData.name" placeholder="璇疯緭鍏ラ棬绂佸悕绉�"></el-input>
+ </el-form-item>
+ <el-form-item label="鍖哄煙" required>
+ <el-input v-model="formData.area" placeholder="璇疯緭鍏ュ尯鍩�"></el-input>
+ </el-form-item>
+ <el-form-item label="浣嶇疆" required>
+ <el-input v-model="formData.location" placeholder="璇疯緭鍏ュ叿浣撲綅缃�"></el-input>
+ </el-form-item>
+ <el-form-item label="鐘舵��" required>
+ <el-select v-model="formData.status" placeholder="璇烽�夋嫨鐘舵��">
+ <el-option label="姝e父" value="1"></el-option>
+ <el-option label="寮傚父" value="0"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鎻忚堪">
+ <el-input v-model="formData.description" type="textarea" rows="3" placeholder="璇疯緭鍏ユ弿杩颁俊鎭�"></el-input>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveData">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from 'vue';
+import { Search, Plus, Delete } from '@element-plus/icons-vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import dayjs from 'dayjs';
+
+// 瀹氫箟鍋囨暟鎹�
+const mockData = [
+ { id: 1, name: '涓滈棬闂ㄧ', area: '鐢熶骇鍖�', location: '涓滈棬鍏ュ彛', status: '1', lastUpdate: '2025-12-30 08:30:00', description: '涓昏鐢ㄤ簬鍛樺伐涓婁笅鐝�氳' },
+ { id: 2, name: '瑗块棬闂ㄧ', area: '浠撳偍鍖�', location: '瑗块棬鍏ュ彛', status: '1', lastUpdate: '2025-12-30 09:15:00', description: '涓昏鐢ㄤ簬鐗╂祦杞﹁締閫氳' },
+ { id: 3, name: '鍗楅棬闂ㄧ', area: '鍔炲叕鍖�', location: '鍗楅棬鍏ュ彛', status: '0', lastUpdate: '2025-12-30 10:20:00', description: '涓昏鐢ㄤ簬璁垮閫氳锛屽綋鍓嶆晠闅�' },
+ { id: 4, name: '鍖楅棬闂ㄧ', area: '鐢熶骇鍖�', location: '鍖楅棬鍏ュ彛', status: '1', lastUpdate: '2025-12-30 11:45:00', description: '涓昏鐢ㄤ簬鍘熸潗鏂欒繍杈撹溅杈嗛�氳' },
+ { id: 5, name: '涓帶瀹ら棬绂�', area: '涓帶鍖�', location: '涓帶瀹ら棬鍙�', status: '1', lastUpdate: '2025-12-30 13:20:00', description: '浠呴檺鎺堟潈浜哄憳杩涘叆' },
+];
+
+// 鍝嶅簲寮忔暟鎹�
+const filters = reactive({
+ name: '',
+ status: '',
+ area: ''
+});
+
+const dataList = ref([]);
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0
+});
+
+const multipleList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref('鏂板闂ㄧ');
+const formData = reactive({
+ id: '',
+ name: '',
+ area: '',
+ location: '',
+ status: '1',
+ description: ''
+});
+
+// 琛ㄦ牸鍒楅厤缃�
+const columns = [
+ {
+ label: '闂ㄧ鍚嶇О',
+ align: 'center',
+ prop: 'name',
+ },
+ {
+ label: '鍖哄煙',
+ align: 'center',
+ prop: 'area',
+ },
+ {
+ label: '浣嶇疆',
+ align: 'center',
+ prop: 'location',
+ },
+ {
+ label: '鐘舵��',
+ align: 'center',
+ prop: 'status',
+ formatter: (row) => {
+ return row.status === '1' ? '<el-tag type="success">姝e父</el-tag>' : '<el-tag type="danger">寮傚父</el-tag>';
+ }
+ },
+ {
+ label: '鏈�鍚庢洿鏂�',
+ align: 'center',
+ prop: 'lastUpdate',
+ },
+ {
+ label: '鎻忚堪',
+ align: 'center',
+ prop: 'description',
+ },
+ {
+ dataType: 'action',
+ label: '鎿嶄綔',
+ align: 'center',
+ fixed: 'right',
+ width: 140,
+ operation: [
+ {
+ name: '缂栬緫',
+ type: 'text',
+ clickFun: (row) => {
+ edit(row);
+ },
+ },
+ {
+ name: '鍒犻櫎',
+ type: 'text',
+ clickFun: (row) => {
+ deleteRow(row.id);
+ },
+ },
+ ],
+ },
+];
+
+// 杩囨护鍚庣殑鏁版嵁
+const filteredData = computed(() => {
+ return mockData.filter(item => {
+ const nameMatch = !filters.name || item.name.includes(filters.name);
+ const statusMatch = !filters.status || item.status === filters.status;
+ const areaMatch = !filters.area || item.area.includes(filters.area);
+ return nameMatch && statusMatch && areaMatch;
+ });
+});
+
+// 鑾峰彇琛ㄦ牸鏁版嵁
+const getTableData = () => {
+ pagination.total = filteredData.value.length;
+ const start = (pagination.currentPage - 1) * pagination.pageSize;
+ const end = start + pagination.pageSize;
+ dataList.value = filteredData.value.slice(start, end);
+};
+
+// 閲嶇疆杩囨护鍣�
+const resetFilters = () => {
+ filters.name = '';
+ filters.status = '';
+ filters.area = '';
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+// 鍒嗛〉鍙樺寲
+const changePage = ({ page, limit }) => {
+ pagination.currentPage = page;
+ pagination.pageSize = limit;
+ getTableData();
+};
+
+// 澶氶�夊鐞�
+const handleSelectionChange = (selectionList) => {
+ multipleList.value = selectionList;
+};
+
+// 鏂板
+const add = () => {
+ dialogTitle.value = '鏂板闂ㄧ';
+ formData.id = '';
+ formData.name = '';
+ formData.area = '';
+ formData.location = '';
+ formData.status = '1';
+ formData.description = '';
+ dialogVisible.value = true;
+};
+
+// 缂栬緫
+const edit = (row) => {
+ dialogTitle.value = '缂栬緫闂ㄧ';
+ formData.id = row.id;
+ formData.name = row.name;
+ formData.area = row.area;
+ formData.location = row.location;
+ formData.status = row.status;
+ formData.description = row.description;
+ dialogVisible.value = true;
+};
+
+// 淇濆瓨鏁版嵁
+const saveData = () => {
+ if (!formData.name || !formData.area || !formData.location) {
+ ElMessage.warning('璇峰~鍐欏繀濉瓧娈�');
+ return;
+ }
+
+ const currentTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
+ if (formData.id) {
+ // 缂栬緫
+ const index = mockData.findIndex(item => item.id === formData.id);
+ if (index !== -1) {
+ mockData[index] = {
+ ...formData,
+ lastUpdate: currentTime
+ };
+ ElMessage.success('缂栬緫鎴愬姛');
+ }
+ } else {
+ // 鏂板
+ const newId = Math.max(...mockData.map(item => item.id), 0) + 1;
+ mockData.unshift({
+ ...formData,
+ id: newId,
+ lastUpdate: currentTime
+ });
+ ElMessage.success('鏂板鎴愬姛');
+ }
+ dialogVisible.value = false;
+ getTableData();
+};
+
+// 鍒犻櫎
+const deleteRow = (id) => {
+ ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ラ棬绂佽褰�, 鏄惁缁х画?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ }).then(() => {
+ const index = mockData.findIndex(item => item.id === id);
+ if (index !== -1) {
+ mockData.splice(index, 1);
+ ElMessage.success('鍒犻櫎鎴愬姛');
+ getTableData();
+ }
+ }).catch(() => {});
+};
+
+// 鎵归噺鍒犻櫎
+const batchDelete = () => {
+ if (multipleList.value.length === 0) {
+ ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁');
+ return;
+ }
+
+ ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎鎵�閫夐棬绂佽褰�, 鏄惁缁х画?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ }).then(() => {
+ const ids = multipleList.value.map(item => item.id);
+ mockData.forEach((item, index) => {
+ if (ids.includes(item.id)) {
+ mockData.splice(index, 1);
+ }
+ });
+ ElMessage.success('鍒犻櫎鎴愬姛');
+ getTableData();
+ multipleList.value = [];
+ }).catch(() => {});
+};
+
+// 鍒濆鍖栨暟鎹�
+onMounted(() => {
+ getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+ margin-top: unset;
+}
+.actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/environmentAccess/intelligentInspectionManagement/index.vue b/src/views/environmentAccess/intelligentInspectionManagement/index.vue
new file mode 100644
index 0000000..47fe867
--- /dev/null
+++ b/src/views/environmentAccess/intelligentInspectionManagement/index.vue
@@ -0,0 +1,581 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="宸℃鍚嶇О">
+ <el-input
+ v-model="filters.name"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
+ clearable
+ :prefix-icon="Search"
+ @change="getTableData"
+ />
+ </el-form-item>
+ <el-form-item label="宸℃鐘舵��">
+ <el-select
+ v-model="filters.status"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨宸℃鐘舵��"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="寰呮墽琛�" value="0"></el-option>
+ <el-option label="鎵ц涓�" value="1"></el-option>
+ <el-option label="宸插畬鎴�" value="2"></el-option>
+ <el-option label="宸插彇娑�" value="3"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="宸℃绫诲瀷">
+ <el-select
+ v-model="filters.type"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨宸℃绫诲瀷"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="瀹氭湡宸℃" value="0"></el-option>
+ <el-option label="涓存椂宸℃" value="1"></el-option>
+ <el-option label="鏁呴殰宸℃" value="2"></el-option>
+ </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
+ type="danger"
+ icon="Delete"
+ :disabled="multipleList.length <= 0"
+ @click="batchDelete"
+ >鎵归噺鍒犻櫎</el-button
+ >
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ isSelection
+ :column="columns"
+ :tableData="dataList"
+ :page="{
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ total: pagination.total,
+ }"
+ @selection-change="handleSelectionChange"
+ @pagination="changePage"
+ >
+ </PIMTable>
+ </div>
+ <!-- 鏂板缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+ <el-form :model="formData" label-width="100px">
+ <el-form-item label="宸℃鍚嶇О" required>
+ <el-input
+ v-model="formData.name"
+ placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
+ ></el-input>
+ </el-form-item>
+ <el-form-item label="宸℃绫诲瀷" required>
+ <el-select v-model="formData.type" placeholder="璇烽�夋嫨宸℃绫诲瀷">
+ <el-option label="瀹氭湡宸℃" value="0"></el-option>
+ <el-option label="涓存椂宸℃" value="1"></el-option>
+ <el-option label="鏁呴殰宸℃" value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="宸℃鍖哄煙" required>
+ <el-input
+ v-model="formData.area"
+ placeholder="璇疯緭鍏ュ贰妫�鍖哄煙"
+ ></el-input>
+ </el-form-item>
+ <el-form-item label="宸℃浜哄憳" required>
+ <el-input
+ v-model="formData.inspector"
+ placeholder="璇疯緭鍏ュ贰妫�浜哄憳"
+ ></el-input>
+ </el-form-item>
+ <el-form-item label="璁″垝寮�濮嬫椂闂�" required>
+ <el-date-picker
+ v-model="formData.planStartTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝寮�濮嬫椂闂�"
+ style="width: 100%"
+ ></el-date-picker>
+ </el-form-item>
+ <el-form-item label="璁″垝缁撴潫鏃堕棿" required>
+ <el-date-picker
+ v-model="formData.planEndTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝缁撴潫鏃堕棿"
+ style="width: 100%"
+ ></el-date-picker>
+ </el-form-item>
+ <el-form-item label="宸℃鍐呭">
+ <el-input
+ v-model="formData.content"
+ type="textarea"
+ rows="3"
+ placeholder="璇疯緭鍏ュ贰妫�鍐呭"
+ ></el-input>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveData">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from "vue";
+import { Search, Plus, Delete } from "@element-plus/icons-vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import dayjs from "dayjs";
+
+// 瀹氫箟鍋囨暟鎹�
+const mockData = [
+ {
+ id: 1,
+ name: "涓滈棬鍖哄煙鏃ュ父宸℃",
+ type: "0",
+ status: "2",
+ planStartTime: "2025-12-30 08:00:00",
+ planEndTime: "2025-12-30 09:00:00",
+ actualStartTime: "2025-12-30 08:05:00",
+ actualEndTime: "2025-12-30 08:55:00",
+ inspector: "寮犱笁",
+ area: "涓滈棬鍖哄煙",
+ content: "妫�鏌ラ棬绂佽澶囪繍琛岀姸鎬併�佺幆澧冪洃娴嬭澶囨暟鎹�",
+ },
+ {
+ id: 2,
+ name: "瑗块棬鍖哄煙涓存椂宸℃",
+ type: "1",
+ status: "2",
+ planStartTime: "2025-12-30 10:00:00",
+ planEndTime: "2025-12-30 11:00:00",
+ actualStartTime: "2025-12-30 10:00:00",
+ actualEndTime: "2025-12-30 10:45:00",
+ inspector: "鏉庡洓",
+ area: "瑗块棬鍖哄煙",
+ content: "妫�鏌ュ紓甯告姤璀﹁澶�",
+ },
+ {
+ id: 3,
+ name: "鍗楅棬闂ㄧ鏁呴殰宸℃",
+ type: "2",
+ status: "1",
+ planStartTime: "2025-12-30 13:00:00",
+ planEndTime: "2025-12-30 14:00:00",
+ actualStartTime: "2025-12-30 13:10:00",
+ actualEndTime: "",
+ inspector: "鐜嬩簲",
+ area: "鍗楅棬鍖哄煙",
+ content: "淇闂ㄧ鏁呴殰",
+ },
+ {
+ id: 4,
+ name: "涓帶瀹ゅ畾鏈熷贰妫�",
+ type: "0",
+ status: "0",
+ planStartTime: "2025-12-31 09:00:00",
+ planEndTime: "2025-12-31 10:00:00",
+ actualStartTime: "",
+ actualEndTime: "",
+ inspector: "璧靛叚",
+ area: "涓帶鍖哄煙",
+ content: "妫�鏌ョ洃鎺ц澶囥�佹湇鍔″櫒杩愯鐘舵��",
+ },
+ {
+ id: 5,
+ name: "鍖楅棬鍖哄煙鏃ュ父宸℃",
+ type: "0",
+ status: "2",
+ planStartTime: "2025-12-30 15:00:00",
+ planEndTime: "2025-12-30 16:00:00",
+ actualStartTime: "2025-12-30 15:00:00",
+ actualEndTime: "2025-12-30 15:50:00",
+ inspector: "寮犱笁",
+ area: "鍖楅棬鍖哄煙",
+ content: "妫�鏌ヨ溅杈嗚瘑鍒澶囥�侀亾闂歌繍琛岀姸鎬�",
+ },
+];
+
+// 鍝嶅簲寮忔暟鎹�
+const filters = reactive({
+ name: "",
+ status: "",
+ type: "",
+});
+
+const dataList = ref([]);
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+});
+
+const multipleList = ref([]);
+const dialogVisible = ref(false);
+const dialogTitle = ref("鏂板宸℃");
+const formData = reactive({
+ id: "",
+ name: "",
+ type: "0",
+ status: "0",
+ planStartTime: "",
+ planEndTime: "",
+ actualStartTime: "",
+ actualEndTime: "",
+ inspector: "",
+ area: "",
+ content: "",
+});
+
+// 鐘舵�佹槧灏�
+const statusMap = {
+ '0': '<el-tag type="warning">寰呮墽琛�</el-tag>',
+ '1': '<el-tag type="primary">鎵ц涓�</el-tag>',
+ '2': '<el-tag type="success">宸插畬鎴�</el-tag>',
+ '3': '<el-tag type="danger">宸插彇娑�</el-tag>',
+};
+
+// 绫诲瀷鏄犲皠
+const typeMap = {
+ 0: "瀹氭湡宸℃",
+ 1: "涓存椂宸℃",
+ 2: "鏁呴殰宸℃",
+};
+
+// 琛ㄦ牸鍒楅厤缃�
+const columns = [
+ {
+ label: "宸℃鍚嶇О",
+ align: "center",
+ prop: "name",
+ },
+ {
+ label: "宸℃绫诲瀷",
+ align: "center",
+ prop: "type",
+ formatter: (row) => {
+ return typeMap[row.type];
+ },
+ },
+ {
+ label: "宸℃鐘舵��",
+ align: "center",
+ prop: "status",
+ formatter: (row) => {
+ return statusMap[row.status];
+ },
+ },
+ {
+ label: "璁″垝寮�濮嬫椂闂�",
+ align: "center",
+ prop: "planStartTime",
+ },
+ {
+ label: "璁″垝缁撴潫鏃堕棿",
+ align: "center",
+ prop: "planEndTime",
+ },
+ {
+ label: "瀹為檯寮�濮嬫椂闂�",
+ align: "center",
+ prop: "actualStartTime",
+ formatter: (row) => {
+ return row.actualStartTime || "-";
+ },
+ },
+ {
+ label: "瀹為檯缁撴潫鏃堕棿",
+ align: "center",
+ prop: "actualEndTime",
+ formatter: (row) => {
+ return row.actualEndTime || "-";
+ },
+ },
+ {
+ label: "宸℃浜哄憳",
+ align: "center",
+ prop: "inspector",
+ },
+ {
+ label: "宸℃鍖哄煙",
+ align: "center",
+ prop: "area",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 180,
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: (row) => {
+ edit(row);
+ },
+ },
+ {
+ name: "寮�濮嬫墽琛�",
+ type: "text",
+ clickFun: (row) => {
+ startInspection(row);
+ },
+ visible: (row) => {
+ return row.status === "0";
+ },
+ },
+ {
+ name: "瀹屾垚宸℃",
+ type: "text",
+ clickFun: (row) => {
+ completeInspection(row);
+ },
+ visible: (row) => {
+ return row.status === "1";
+ },
+ },
+ {
+ name: "鍙栨秷宸℃",
+ type: "text",
+ clickFun: (row) => {
+ cancelInspection(row);
+ },
+ visible: (row) => {
+ return ["0", "1"].includes(row.status);
+ },
+ },
+ {
+ name: "鍒犻櫎",
+ type: "text",
+ clickFun: (row) => {
+ deleteRow(row.id);
+ },
+ },
+ ],
+ },
+];
+
+// 杩囨护鍚庣殑鏁版嵁
+const filteredData = computed(() => {
+ return mockData.filter((item) => {
+ const nameMatch = !filters.name || item.name.includes(filters.name);
+ const statusMatch = !filters.status || item.status === filters.status;
+ const typeMatch = !filters.type || item.type === filters.type;
+ return nameMatch && statusMatch && typeMatch;
+ });
+});
+
+// 鑾峰彇琛ㄦ牸鏁版嵁
+const getTableData = () => {
+ pagination.total = filteredData.value.length;
+ const start = (pagination.currentPage - 1) * pagination.pageSize;
+ const end = start + pagination.pageSize;
+ dataList.value = filteredData.value.slice(start, end);
+};
+
+// 閲嶇疆杩囨护鍣�
+const resetFilters = () => {
+ filters.name = "";
+ filters.status = "";
+ filters.type = "";
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+// 鍒嗛〉鍙樺寲
+const changePage = ({ page, limit }) => {
+ pagination.currentPage = page;
+ pagination.pageSize = limit;
+ getTableData();
+};
+
+// 澶氶�夊鐞�
+const handleSelectionChange = (selectionList) => {
+ multipleList.value = selectionList;
+};
+
+// 鏂板
+const add = () => {
+ dialogTitle.value = "鏂板宸℃";
+ formData.id = "";
+ formData.name = "";
+ formData.type = "0";
+ formData.status = "0";
+ formData.planStartTime = "";
+ formData.planEndTime = "";
+ formData.actualStartTime = "";
+ formData.actualEndTime = "";
+ formData.inspector = "";
+ formData.area = "";
+ formData.content = "";
+ dialogVisible.value = true;
+};
+
+// 缂栬緫
+const edit = (row) => {
+ dialogTitle.value = "缂栬緫宸℃";
+ formData.id = row.id;
+ formData.name = row.name;
+ formData.type = row.type;
+ formData.status = row.status;
+ formData.planStartTime = row.planStartTime;
+ formData.planEndTime = row.planEndTime;
+ formData.actualStartTime = row.actualStartTime;
+ formData.actualEndTime = row.actualEndTime;
+ formData.inspector = row.inspector;
+ formData.area = row.area;
+ formData.content = row.content;
+ dialogVisible.value = true;
+};
+
+// 淇濆瓨鏁版嵁
+const saveData = () => {
+ if (
+ !formData.name ||
+ !formData.planStartTime ||
+ !formData.planEndTime ||
+ !formData.inspector ||
+ !formData.area
+ ) {
+ ElMessage.warning("璇峰~鍐欏繀濉瓧娈�");
+ return;
+ }
+
+ if (formData.id) {
+ // 缂栬緫
+ const index = mockData.findIndex((item) => item.id === formData.id);
+ if (index !== -1) {
+ mockData[index] = {
+ ...mockData[index],
+ ...formData,
+ };
+ ElMessage.success("缂栬緫鎴愬姛");
+ }
+ } else {
+ // 鏂板
+ const newId = Math.max(...mockData.map((item) => item.id), 0) + 1;
+ mockData.unshift({
+ ...formData,
+ id: newId,
+ });
+ ElMessage.success("鏂板鎴愬姛");
+ }
+ dialogVisible.value = false;
+ getTableData();
+};
+
+// 寮�濮嬪贰妫�
+const startInspection = (row) => {
+ const index = mockData.findIndex((item) => item.id === row.id);
+ if (index !== -1) {
+ mockData[index].status = "1";
+ mockData[index].actualStartTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+ ElMessage.success("宸℃宸插紑濮�");
+ getTableData();
+ }
+};
+
+// 瀹屾垚宸℃
+const completeInspection = (row) => {
+ const index = mockData.findIndex((item) => item.id === row.id);
+ if (index !== -1) {
+ mockData[index].status = "2";
+ mockData[index].actualEndTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+ ElMessage.success("宸℃宸插畬鎴�");
+ getTableData();
+ }
+};
+
+// 鍙栨秷宸℃
+const cancelInspection = (row) => {
+ ElMessageBox.confirm("纭畾瑕佸彇娑堣宸℃鍚�?", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ const index = mockData.findIndex((item) => item.id === row.id);
+ if (index !== -1) {
+ mockData[index].status = "3";
+ ElMessage.success("宸℃宸插彇娑�");
+ getTableData();
+ }
+ })
+ .catch(() => {});
+};
+
+// 鍒犻櫎
+const deleteRow = (id) => {
+ ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ贰妫�璁板綍, 鏄惁缁х画?", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ const index = mockData.findIndex((item) => item.id === id);
+ if (index !== -1) {
+ mockData.splice(index, 1);
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getTableData();
+ }
+ })
+ .catch(() => {});
+};
+
+// 鎵归噺鍒犻櫎
+const batchDelete = () => {
+ if (multipleList.value.length === 0) {
+ ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+ return;
+ }
+
+ ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎鎵�閫夊贰妫�璁板綍, 鏄惁缁х画?", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ const ids = multipleList.value.map((item) => item.id);
+ mockData.forEach((item, index) => {
+ if (ids.includes(item.id)) {
+ mockData.splice(index, 1);
+ }
+ });
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getTableData();
+ multipleList.value = [];
+ })
+ .catch(() => {});
+};
+
+// 鍒濆鍖栨暟鎹�
+onMounted(() => {
+ getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+ margin-top: unset;
+}
+.actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/environmentAccess/remoteMonitoringOfEquipment/index.vue b/src/views/environmentAccess/remoteMonitoringOfEquipment/index.vue
new file mode 100644
index 0000000..bdd0a7b
--- /dev/null
+++ b/src/views/environmentAccess/remoteMonitoringOfEquipment/index.vue
@@ -0,0 +1,633 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="璁惧鍚嶇О">
+ <el-input
+ v-model="filters.name"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ヨ澶囧悕绉�"
+ clearable
+ :prefix-icon="Search"
+ @change="getTableData"
+ />
+ </el-form-item>
+ <el-form-item label="璁惧鐘舵��">
+ <el-select
+ v-model="filters.status"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨璁惧鐘舵��"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="鍦ㄧ嚎" value="1"></el-option>
+ <el-option label="绂荤嚎" value="0"></el-option>
+ <el-option label="鏁呴殰" value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="璁惧绫诲瀷">
+ <el-select
+ v-model="filters.type"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨璁惧绫诲瀷"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="闂ㄧ璁惧" value="0"></el-option>
+ <el-option label="鐜鐩戞祴璁惧" value="1"></el-option>
+ <el-option label="瑙嗛鐩戞帶璁惧" value="2"></el-option>
+ <el-option label="鏅鸿兘閬撻椄" value="3"></el-option>
+ </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="monitor-container">
+ <div class="monitor-stats">
+ <div class="stat-card">
+ <div class="stat-title">鍦ㄧ嚎璁惧</div>
+ <div class="stat-value online">{{ onlineCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">绂荤嚎璁惧</div>
+ <div class="stat-value offline">{{ offlineCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">鏁呴殰璁惧</div>
+ <div class="stat-value error">{{ errorCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">璁惧鎬绘暟</div>
+ <div class="stat-value total">{{ totalCount }}</div>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="columns"
+ :tableData="dataList"
+ :page="{
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ total: pagination.total,
+ }"
+ @pagination="changePage"
+ >
+ </PIMTable>
+ </div>
+ </div>
+
+ <!-- 璁惧璇︽儏寮圭獥 -->
+ <el-dialog
+ v-model="detailVisible"
+ :title="`璁惧璇︽儏 - ${selectedDevice.name}`"
+ width="800px"
+ >
+ <div v-if="selectedDevice" class="device-detail">
+ <div class="detail-section">
+ <h3>鍩烘湰淇℃伅</h3>
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="璁惧鍚嶇О">{{
+ selectedDevice.name
+ }}</el-descriptions-item>
+ <el-descriptions-item label="璁惧绫诲瀷">{{
+ typeMap[selectedDevice.type]
+ }}</el-descriptions-item>
+ <el-descriptions-item label="璁惧鐘舵��">{{
+ statusMap[selectedDevice.status]
+ }}</el-descriptions-item>
+ <el-descriptions-item label="璁惧缂栧彿">{{
+ selectedDevice.code
+ }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夎浣嶇疆">{{
+ selectedDevice.location
+ }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夎鏃堕棿">{{
+ selectedDevice.installTime
+ }}</el-descriptions-item>
+ <el-descriptions-item label="鏈�鍚庣淮鎶ゆ椂闂�">{{
+ selectedDevice.maintainTime
+ }}</el-descriptions-item>
+ <el-descriptions-item label="璐d换浜�">{{
+ selectedDevice.responsiblePerson
+ }}</el-descriptions-item>
+ </el-descriptions>
+ </div>
+
+ <div class="detail-section">
+ <h3>瀹炴椂鏁版嵁</h3>
+ <div class="realtime-data">
+ <div
+ v-for="data in selectedDevice.realtimeData"
+ :key="data.name"
+ class="data-item"
+ >
+ <div class="data-name">{{ data.name }}</div>
+ <div class="data-value">{{ data.value }}{{ data.unit }}</div>
+ <div class="data-status" :class="data.status">
+ {{ data.status === "normal" ? "姝e父" : "寮傚父" }}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="detail-section">
+ <h3>鎺у埗鎿嶄綔</h3>
+ <div class="control-buttons">
+ <el-button
+ type="primary"
+ @click="controlDevice('restart')"
+ :disabled="selectedDevice.status !== '1'"
+ >閲嶅惎璁惧</el-button
+ >
+ <el-button
+ type="warning"
+ @click="controlDevice('reset')"
+ :disabled="selectedDevice.status !== '1'"
+ >閲嶇疆璁惧</el-button
+ >
+ <el-button
+ type="danger"
+ @click="controlDevice('shutdown')"
+ :disabled="selectedDevice.status !== '1'"
+ >鍏抽棴璁惧</el-button
+ >
+ <el-button
+ type="success"
+ @click="controlDevice('update')"
+ :disabled="selectedDevice.status !== '1'"
+ >鍥轰欢鏇存柊</el-button
+ >
+ </div>
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="detailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from "vue";
+import {
+ Search
+} from "@element-plus/icons-vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+// 瀹氫箟鍋囨暟鎹�
+const mockDevices = [
+ {
+ id: 1,
+ name: "涓滈棬闂ㄧ鎺у埗鍣�",
+ code: "DEV-20250001",
+ type: "0",
+ status: "1",
+ location: "涓滈棬鍏ュ彛",
+ installTime: "2025-01-15",
+ maintainTime: "2025-12-20",
+ responsiblePerson: "寮犱笁",
+ realtimeData: [
+ { name: "娓╁害", value: 23.5, unit: "鈩�", status: "normal" },
+ { name: "婀垮害", value: 45, unit: "%", status: "normal" },
+ { name: "杩愯鏃堕暱", value: 12560, unit: "h", status: "normal" },
+ { name: "闂ㄧ寮�鍏虫鏁�", value: 234, unit: "娆�/澶�", status: "normal" },
+ ],
+ },
+ {
+ id: 2,
+ name: "瑗块棬瑙嗛鐩戞帶",
+ code: "DEV-20250002",
+ type: "2",
+ status: "1",
+ location: "瑗块棬鍑哄彛",
+ installTime: "2025-02-20",
+ maintainTime: "2025-11-15",
+ responsiblePerson: "鏉庡洓",
+ realtimeData: [
+ { name: "瑙嗛娓呮櫚搴�", value: 1080, unit: "P", status: "normal" },
+ { name: "甯х巼", value: 25, unit: "fps", status: "normal" },
+ { name: "瀛樺偍绌洪棿", value: 78, unit: "%", status: "warning" },
+ { name: "缃戠粶寤惰繜", value: 12, unit: "ms", status: "normal" },
+ ],
+ },
+ {
+ id: 3,
+ name: "鍗楅棬鐜鐩戞祴浠�",
+ code: "DEV-20250003",
+ type: "1",
+ status: "2",
+ location: "鍗楅棬骞垮満",
+ installTime: "2025-03-10",
+ maintainTime: "2025-10-05",
+ responsiblePerson: "鐜嬩簲",
+ realtimeData: [
+ { name: "PM2.5", value: 85, unit: "渭g/m鲁", status: "error" },
+ { name: "PM10", value: 120, unit: "渭g/m鲁", status: "error" },
+ { name: "鍣0", value: 65, unit: "dB", status: "normal" },
+ { name: "椋庨��", value: 1.2, unit: "m/s", status: "normal" },
+ ],
+ },
+ {
+ id: 4,
+ name: "鍖楅棬鏅鸿兘閬撻椄",
+ code: "DEV-20250004",
+ type: "3",
+ status: "0",
+ location: "鍖楅棬鍏ュ彛",
+ installTime: "2025-04-05",
+ maintainTime: "2025-09-20",
+ responsiblePerson: "璧靛叚",
+ realtimeData: [
+ { name: "寮�鍏虫鏁�", value: 156, unit: "娆�/澶�", status: "normal" },
+ { name: "杩愯鐢靛帇", value: 220, unit: "V", status: "normal" },
+ { name: "杩愯鐢垫祦", value: 5.2, unit: "A", status: "normal" },
+ { name: "鏁呴殰浠g爜", value: "E001", unit: "", status: "error" },
+ ],
+ },
+ {
+ id: 5,
+ name: "涓帶瀹ゆ湇鍔″櫒",
+ code: "DEV-20250005",
+ type: "1",
+ status: "1",
+ location: "涓帶瀹�",
+ installTime: "2025-05-15",
+ maintainTime: "2025-12-01",
+ responsiblePerson: "瀛欎竷",
+ realtimeData: [
+ { name: "CPU浣跨敤鐜�", value: 45, unit: "%", status: "normal" },
+ { name: "鍐呭瓨浣跨敤鐜�", value: 68, unit: "%", status: "warning" },
+ { name: "纾佺洏浣跨敤鐜�", value: 82, unit: "%", status: "warning" },
+ { name: "缃戠粶娴侀噺", value: 125, unit: "Mbps", status: "normal" },
+ ],
+ },
+];
+
+// 鍝嶅簲寮忔暟鎹�
+const filters = reactive({
+ name: "",
+ status: "",
+ type: "",
+});
+
+const dataList = ref([]);
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+});
+
+const detailVisible = ref(false);
+const selectedDevice = ref({});
+
+// 鐘舵�佹槧灏�
+const statusMap = {
+ 0: '<el-tag type="warning">绂荤嚎</el-tag>',
+ 1: '<el-tag type="success">鍦ㄧ嚎</el-tag>',
+ 2: '<el-tag type="danger">鏁呴殰</el-tag>',
+};
+
+// 绫诲瀷鏄犲皠
+const typeMap = {
+ 0: "闂ㄧ璁惧",
+ 1: "鐜鐩戞祴璁惧",
+ 2: "瑙嗛鐩戞帶璁惧",
+ 3: "鏅鸿兘閬撻椄",
+};
+
+// 璁惧鏁伴噺缁熻
+const onlineCount = computed(() => {
+ return mockDevices.filter((device) => device.status === "1").length;
+});
+
+const offlineCount = computed(() => {
+ return mockDevices.filter((device) => device.status === "0").length;
+});
+
+const errorCount = computed(() => {
+ return mockDevices.filter((device) => device.status === "2").length;
+});
+
+const totalCount = computed(() => {
+ return mockDevices.length;
+});
+
+// 琛ㄦ牸鍒楅厤缃�
+const columns = [
+ {
+ label: "璁惧鍚嶇О",
+ align: "center",
+ prop: "name",
+ },
+ {
+ label: "璁惧缂栧彿",
+ align: "center",
+ prop: "code",
+ },
+ {
+ label: "璁惧绫诲瀷",
+ align: "center",
+ prop: "type",
+ formatter: (row) => {
+ return typeMap[row.type];
+ },
+ },
+ {
+ label: "璁惧鐘舵��",
+ align: "center",
+ prop: "status",
+ formatter: (row) => {
+ return statusMap[row.status];
+ },
+ },
+ {
+ label: "瀹夎浣嶇疆",
+ align: "center",
+ prop: "location",
+ },
+ {
+ label: "璐d换浜�",
+ align: "center",
+ prop: "responsiblePerson",
+ },
+ {
+ label: "鏈�鍚庣淮鎶ゆ椂闂�",
+ align: "center",
+ prop: "maintainTime",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 140,
+ operation: [
+ {
+ name: "鏌ョ湅璇︽儏",
+ type: "text",
+ clickFun: (row) => {
+ viewDetail(row);
+ },
+ },
+ {
+ name: "瀹炴椂鐩戞帶",
+ type: "text",
+ clickFun: (row) => {
+ realtimeMonitor(row);
+ },
+ visible: (row) => {
+ return row.status === "1";
+ },
+ },
+ {
+ name: "閲嶅惎璁惧",
+ type: "text",
+ clickFun: (row) => {
+ controlDevice("restart", row);
+ },
+ visible: (row) => {
+ return row.status === "1";
+ },
+ },
+ ],
+ },
+];
+
+// 杩囨护鍚庣殑鏁版嵁
+const filteredData = computed(() => {
+ return mockDevices.filter((item) => {
+ const nameMatch = !filters.name || item.name.includes(filters.name);
+ const statusMatch = !filters.status || item.status === filters.status;
+ const typeMatch = !filters.type || item.type === filters.type;
+ return nameMatch && statusMatch && typeMatch;
+ });
+});
+
+// 鑾峰彇琛ㄦ牸鏁版嵁
+const getTableData = () => {
+ pagination.total = filteredData.value.length;
+ const start = (pagination.currentPage - 1) * pagination.pageSize;
+ const end = start + pagination.pageSize;
+ dataList.value = filteredData.value.slice(start, end);
+};
+
+// 閲嶇疆杩囨护鍣�
+const resetFilters = () => {
+ filters.name = "";
+ filters.status = "";
+ filters.type = "";
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+// 鍒嗛〉鍙樺寲
+const changePage = ({ page, limit }) => {
+ pagination.currentPage = page;
+ pagination.pageSize = limit;
+ getTableData();
+};
+
+// 鏌ョ湅璁惧璇︽儏
+const viewDetail = (row) => {
+ selectedDevice.value = row;
+ detailVisible.value = true;
+};
+
+// 瀹炴椂鐩戞帶
+const realtimeMonitor = (row) => {
+ ElMessage.info(`姝e湪璺宠浆鍒�${row.name}鐨勫疄鏃剁洃鎺ч〉闈�...`);
+ // 杩欓噷鍙互璺宠浆鍒板疄鏃剁洃鎺ч〉闈㈡垨鎵撳紑鐩戞帶绐楀彛
+};
+
+// 璁惧鎺у埗
+const controlDevice = (action, row = selectedDevice.value) => {
+ const actionMap = {
+ restart: "閲嶅惎",
+ reset: "閲嶇疆",
+ shutdown: "鍏抽棴",
+ update: "鍥轰欢鏇存柊",
+ };
+
+ ElMessageBox.confirm(
+ `纭畾瑕佸璁惧 ${row.name} 鎵ц${actionMap[action]}鎿嶄綔鍚�?`,
+ "鎻愮ず",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }
+ )
+ .then(() => {
+ ElMessage.success(`璁惧${actionMap[action]}鎿嶄綔宸插彂閫乣);
+ // 妯℃嫙璁惧鍝嶅簲
+ setTimeout(() => {
+ ElMessage.success(`璁惧${actionMap[action]}鎿嶄綔鎵ц鎴愬姛`);
+ }, 1000);
+ })
+ .catch(() => {});
+};
+
+// 瀹氭椂鏇存柊璁惧鐘舵�侊紙妯℃嫙瀹炴椂鍙樺寲锛�
+const updateDeviceStatus = () => {
+ // 闅忔満鏇存柊涓�浜涜澶囩殑鐘舵�佸拰瀹炴椂鏁版嵁
+ mockDevices.forEach((device) => {
+ if (Math.random() > 0.8) {
+ // 80%姒傜巼涓嶆洿鏂�
+ return;
+ }
+
+ // 闅忔満鏇存柊鐘舵��
+ const statuses = ["0", "1", "2"];
+ device.status = statuses[Math.floor(Math.random() * statuses.length)];
+
+ // 鏇存柊瀹炴椂鏁版嵁
+ device.realtimeData.forEach((data) => {
+ if (data.name === "娓╁害") {
+ data.value = (20 + Math.random() * 10).toFixed(1);
+ data.status = data.value > 30 ? "error" : "normal";
+ } else if (data.name === "婀垮害") {
+ data.value = Math.floor(30 + Math.random() * 50);
+ data.status = data.value > 80 ? "error" : "normal";
+ } else if (data.name === "CPU浣跨敤鐜�") {
+ data.value = Math.floor(20 + Math.random() * 60);
+ data.status =
+ data.value > 80 ? "error" : data.value > 60 ? "warning" : "normal";
+ }
+ });
+ });
+
+ // 鍒锋柊琛ㄦ牸鏁版嵁
+ getTableData();
+};
+
+// 鍒濆鍖栨暟鎹�
+onMounted(() => {
+ getTableData();
+ // 姣�5绉掓洿鏂颁竴娆¤澶囩姸鎬�
+ const interval = setInterval(updateDeviceStatus, 5000);
+
+ // 娓呯悊瀹氭椂鍣�
+ return () => clearInterval(interval);
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+ margin-top: unset;
+}
+
+.monitor-container {
+ .monitor-stats {
+ display: flex;
+ gap: 20px;
+ margin-bottom: 20px;
+
+ .stat-card {
+ flex: 1;
+ background: #fff;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ text-align: center;
+
+ .stat-title {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 10px;
+ }
+
+ .stat-value {
+ font-size: 32px;
+ font-weight: bold;
+
+ &.online {
+ color: #67c23a;
+ }
+
+ &.offline {
+ color: #e6a23c;
+ }
+
+ &.error {
+ color: #f56c6c;
+ }
+
+ &.total {
+ color: #409eff;
+ }
+ }
+ }
+ }
+}
+
+.device-detail {
+ .detail-section {
+ margin-bottom: 20px;
+
+ h3 {
+ font-size: 16px;
+ font-weight: bold;
+ margin-bottom: 10px;
+ color: #303133;
+ }
+ }
+
+ .realtime-data {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 15px;
+
+ .data-item {
+ background: #f5f7fa;
+ padding: 15px;
+ border-radius: 8px;
+
+ .data-name {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 5px;
+ }
+
+ .data-value {
+ font-size: 24px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 5px;
+ }
+
+ .data-status {
+ font-size: 12px;
+ padding: 2px 8px;
+ border-radius: 10px;
+
+ &.normal {
+ background: #f0f9eb;
+ color: #67c23a;
+ }
+
+ &.warning {
+ background: #fdf6ec;
+ color: #e6a23c;
+ }
+
+ &.error {
+ background: #fef0f0;
+ color: #f56c6c;
+ }
+ }
+ }
+ }
+
+ .control-buttons {
+ display: flex;
+ gap: 10px;
+ margin-top: 10px;
+ }
+}
+</style>
diff --git a/src/views/environmentAccess/vehicleInformationCollection/index.vue b/src/views/environmentAccess/vehicleInformationCollection/index.vue
new file mode 100644
index 0000000..5669bfa
--- /dev/null
+++ b/src/views/environmentAccess/vehicleInformationCollection/index.vue
@@ -0,0 +1,577 @@
+<template>
+ <div class="app-container">
+ <el-form :model="filters" :inline="true">
+ <el-form-item label="杞︾墝鍙风爜">
+ <el-input
+ v-model="filters.plateNumber"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ヨ溅鐗屽彿鐮�"
+ clearable
+ :prefix-icon="Search"
+ @change="getTableData"
+ />
+ </el-form-item>
+ <el-form-item label="杞﹁締绫诲瀷">
+ <el-select
+ v-model="filters.vehicleType"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨杞﹁締绫诲瀷"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="灏忓瀷杞�" value="0"></el-option>
+ <el-option label="涓瀷杞�" value="1"></el-option>
+ <el-option label="澶у瀷杞�" value="2"></el-option>
+ <el-option label="鐗圭杞�" value="3"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="杩涘嚭鏂瑰悜">
+ <el-select
+ v-model="filters.direction"
+ style="width: 240px"
+ placeholder="璇烽�夋嫨杩涘嚭鏂瑰悜"
+ clearable
+ @change="getTableData"
+ >
+ <el-option label="杩�" value="0"></el-option>
+ <el-option label="鍑�" value="1"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="杩涘嚭鏃堕棿">
+ <el-date-picker
+ v-model="filters.timeRange"
+ type="daterange"
+ start-placeholder="寮�濮嬫椂闂�"
+ end-placeholder="缁撴潫鏃堕棿"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ format="YYYY-MM-DD HH:mm"
+ clearable
+ @change="changeTimeRange"
+ />
+ </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="vehicle-stats">
+ <div class="stat-card">
+ <div class="stat-title">浠婃棩杩涜溅鏁�</div>
+ <div class="stat-value in">{{ todayInCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">浠婃棩鍑鸿溅鏁�</div>
+ <div class="stat-value out">{{ todayOutCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">褰撳墠鍦ㄥ満杞﹁締</div>
+ <div class="stat-value present">{{ presentCount }}</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-title">浠婃棩鎬绘祦閲�</div>
+ <div class="stat-value total">{{ todayTotalCount }}</div>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="columns"
+ :tableData="dataList"
+ :page="{
+ current: pagination.currentPage,
+ size: pagination.pageSize,
+ total: pagination.total,
+ }"
+ @pagination="changePage"
+ >
+ </PIMTable>
+ </div>
+
+ <!-- 杞﹁締璇︽儏寮圭獥 -->
+ <el-dialog
+ v-model="detailVisible"
+ :title="`杞﹁締璇︽儏 - ${selectedVehicle.plateNumber}`"
+ width="700px"
+ >
+ <div v-if="selectedVehicle" class="vehicle-detail">
+ <div class="detail-section">
+ <h3>鍩烘湰淇℃伅</h3>
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="杞︾墝鍙风爜">{{
+ selectedVehicle.plateNumber
+ }}</el-descriptions-item>
+ <el-descriptions-item label="杞﹁締绫诲瀷">{{
+ typeMap[selectedVehicle.vehicleType]
+ }}</el-descriptions-item>
+ <el-descriptions-item label="杞﹁締棰滆壊">{{
+ selectedVehicle.color
+ }}</el-descriptions-item>
+ <el-descriptions-item label="杩涘嚭鏂瑰悜">{{
+ selectedVehicle.direction === "0" ? "杩�" : "鍑�"
+ }}</el-descriptions-item>
+ <el-descriptions-item label="杩涘嚭鏃堕棿">{{
+ selectedVehicle.timestamp
+ }}</el-descriptions-item>
+ <el-descriptions-item label="閫氶亾鍚嶇О">{{
+ selectedVehicle.channelName
+ }}</el-descriptions-item>
+ <el-descriptions-item label="璇嗗埆鏂瑰紡">{{
+ selectedVehicle.identifyMethod
+ }}</el-descriptions-item>
+ <el-descriptions-item label="杞﹁締鐘舵��">{{
+ statusMap[selectedVehicle.status]
+ }}</el-descriptions-item>
+ </el-descriptions>
+ </div>
+
+ <div class="detail-section">
+ <h3>杞﹁締鍥剧墖</h3>
+ <div class="vehicle-images">
+ <div class="image-item">
+ <div class="image-title">姝i潰鍥剧墖</div>
+ <el-image
+ :src="selectedVehicle.frontImage"
+ fit="cover"
+ style="width: 100%; height: 200px"
+ :preview-src-list="[
+ selectedVehicle.frontImage,
+ selectedVehicle.sideImage,
+ ]"
+ ></el-image>
+ </div>
+ <div class="image-item">
+ <div class="image-title">渚ч潰鍥剧墖</div>
+ <el-image
+ :src="selectedVehicle.sideImage"
+ fit="cover"
+ style="width: 100%; height: 200px"
+ :preview-src-list="[
+ selectedVehicle.sideImage,
+ selectedVehicle.frontImage,
+ ]"
+ ></el-image>
+ </div>
+ </div>
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="detailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from "vue";
+import { Search } from "@element-plus/icons-vue";
+import dayjs from "dayjs";
+
+// 瀹氫箟鍋囨暟鎹�
+const mockVehicles = [
+ {
+ id: 1,
+ plateNumber: "浜珹12345",
+ vehicleType: "0",
+ color: "鐧借壊",
+ direction: "0",
+ timestamp: "2025-12-31 08:15:30",
+ channelName: "涓滈棬閫氶亾",
+ identifyMethod: "杞︾墝璇嗗埆",
+ status: "0",
+ frontImage: "https://picsum.photos/id/1024/800/600",
+ sideImage: "https://picsum.photos/id/1025/800/600",
+ duration: "00:00:00",
+ present: true,
+ },
+ {
+ id: 2,
+ plateNumber: "娌狟67890",
+ vehicleType: "1",
+ color: "榛戣壊",
+ direction: "1",
+ timestamp: "2025-12-31 08:10:20",
+ channelName: "瑗块棬閫氶亾",
+ identifyMethod: "杞︾墝璇嗗埆",
+ status: "1",
+ frontImage: "https://picsum.photos/id/1026/800/600",
+ sideImage: "https://picsum.photos/id/1027/800/600",
+ duration: "01:25:30",
+ present: false,
+ },
+ {
+ id: 3,
+ plateNumber: "绮54321",
+ vehicleType: "0",
+ color: "绾㈣壊",
+ direction: "0",
+ timestamp: "2025-12-31 08:05:15",
+ channelName: "鍗楅棬閫氶亾",
+ identifyMethod: "IC鍗¤瘑鍒�",
+ status: "0",
+ frontImage: "https://picsum.photos/id/1028/800/600",
+ sideImage: "https://picsum.photos/id/1029/800/600",
+ duration: "00:05:45",
+ present: true,
+ },
+ {
+ id: 4,
+ plateNumber: "宸滵98765",
+ vehicleType: "2",
+ color: "钃濊壊",
+ direction: "0",
+ timestamp: "2025-12-31 08:00:00",
+ channelName: "鍖楅棬閫氶亾",
+ identifyMethod: "杞︾墝璇嗗埆",
+ status: "0",
+ frontImage: "https://picsum.photos/id/1030/800/600",
+ sideImage: "https://picsum.photos/id/1031/800/600",
+ duration: "00:10:30",
+ present: true,
+ },
+ {
+ id: 5,
+ plateNumber: "鑻廍13579",
+ vehicleType: "0",
+ color: "閾惰壊",
+ direction: "1",
+ timestamp: "2025-12-31 07:55:45",
+ channelName: "涓滈棬閫氶亾",
+ identifyMethod: "杞︾墝璇嗗埆",
+ status: "1",
+ frontImage: "https://picsum.photos/id/1032/800/600",
+ sideImage: "https://picsum.photos/id/1033/800/600",
+ duration: "02:30:15",
+ present: false,
+ },
+ {
+ id: 6,
+ plateNumber: "娴橣24680",
+ vehicleType: "3",
+ color: "榛勮壊",
+ direction: "0",
+ timestamp: "2025-12-31 07:50:30",
+ channelName: "鍗楅棬閫氶亾",
+ identifyMethod: "浜哄伐鐧昏",
+ status: "0",
+ frontImage: "https://picsum.photos/id/1034/800/600",
+ sideImage: "https://picsum.photos/id/1035/800/600",
+ duration: "00:15:30",
+ present: true,
+ },
+ {
+ id: 7,
+ plateNumber: "椴丟97531",
+ vehicleType: "1",
+ color: "缁胯壊",
+ direction: "1",
+ timestamp: "2025-12-31 07:45:15",
+ channelName: "瑗块棬閫氶亾",
+ identifyMethod: "杞︾墝璇嗗埆",
+ status: "1",
+ frontImage: "https://picsum.photos/id/1036/800/600",
+ sideImage: "https://picsum.photos/id/1037/800/600",
+ duration: "01:45:30",
+ present: false,
+ },
+ {
+ id: 8,
+ plateNumber: "璞獺86420",
+ vehicleType: "0",
+ color: "鐏拌壊",
+ direction: "0",
+ timestamp: "2025-12-31 07:40:00",
+ channelName: "鍖楅棬閫氶亾",
+ identifyMethod: "IC鍗¤瘑鍒�",
+ status: "0",
+ frontImage: "https://picsum.photos/id/1038/800/600",
+ sideImage: "https://picsum.photos/id/1039/800/600",
+ duration: "00:20:15",
+ present: true,
+ },
+];
+
+// 鍝嶅簲寮忔暟鎹�
+const filters = reactive({
+ plateNumber: "",
+ vehicleType: "",
+ direction: "",
+ timeRange: [],
+});
+
+const dataList = ref([]);
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+});
+
+const detailVisible = ref(false);
+const selectedVehicle = ref({});
+
+// 鏃堕棿鑼冨洿
+const timeRange = reactive({
+ startTime: "",
+ endTime: "",
+});
+
+// 鐘舵�佹槧灏�
+const statusMap = {
+ '0': '<el-tag type="success">姝e父</el-tag>',
+ '1': '<el-tag type="info">宸茬寮�</el-tag>',
+ '2': '<el-tag type="warning">寮傚父</el-tag>',
+};
+
+// 绫诲瀷鏄犲皠
+const typeMap = {
+ 0: "灏忓瀷杞�",
+ 1: "涓瀷杞�",
+ 2: "澶у瀷杞�",
+ 3: "鐗圭杞�",
+};
+
+// 缁熻鏁版嵁
+const todayInCount = computed(() => {
+ const today = dayjs().format("YYYY-MM-DD");
+ return mockVehicles.filter((vehicle) => {
+ return vehicle.direction === "0" && vehicle.timestamp.startsWith(today);
+ }).length;
+});
+
+const todayOutCount = computed(() => {
+ const today = dayjs().format("YYYY-MM-DD");
+ return mockVehicles.filter((vehicle) => {
+ return vehicle.direction === "1" && vehicle.timestamp.startsWith(today);
+ }).length;
+});
+
+const presentCount = computed(() => {
+ return mockVehicles.filter((vehicle) => vehicle.present).length;
+});
+
+const todayTotalCount = computed(() => {
+ const today = dayjs().format("YYYY-MM-DD");
+ return mockVehicles.filter((vehicle) => {
+ return vehicle.timestamp.startsWith(today);
+ }).length;
+});
+
+// 琛ㄦ牸鍒楅厤缃�
+const columns = [
+ {
+ label: "杞︾墝鍙风爜",
+ align: "center",
+ prop: "plateNumber",
+ },
+ {
+ label: "杞﹁締绫诲瀷",
+ align: "center",
+ prop: "vehicleType",
+ formatter: (row) => {
+ return typeMap[row.vehicleType];
+ },
+ },
+ {
+ label: "杞﹁締棰滆壊",
+ align: "center",
+ prop: "color",
+ },
+ {
+ label: "杩涘嚭鏂瑰悜",
+ align: "center",
+ prop: "direction",
+ formatter: (row) => {
+ return row.direction === "0" ? '<el-tag type="success">杩�</el-tag>' : '<el-tag type="info">鍑�</el-tag>';
+ },
+ },
+ {
+ label: "杩涘嚭鏃堕棿",
+ align: "center",
+ prop: "timestamp",
+ },
+ {
+ label: "閫氶亾鍚嶇О",
+ align: "center",
+ prop: "channelName",
+ },
+ {
+ label: "璇嗗埆鏂瑰紡",
+ align: "center",
+ prop: "identifyMethod",
+ },
+ {
+ label: "杞﹁締鐘舵��",
+ align: "center",
+ prop: "status",
+ formatter: (row) => {
+ return statusMap[row.status];
+ },
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 140,
+ operation: [
+ {
+ name: "鏌ョ湅璇︽儏",
+ type: "text",
+ clickFun: (row) => {
+ viewDetail(row);
+ },
+ },
+ ],
+ },
+];
+
+// 杩囨护鍚庣殑鏁版嵁
+const filteredData = computed(() => {
+ return mockVehicles.filter((item) => {
+ const plateMatch =
+ !filters.plateNumber || item.plateNumber.includes(filters.plateNumber);
+ const typeMatch =
+ !filters.vehicleType || item.vehicleType === filters.vehicleType;
+ const directionMatch =
+ !filters.direction || item.direction === filters.direction;
+ const timeMatch =
+ !timeRange.startTime ||
+ (item.timestamp >= timeRange.startTime &&
+ item.timestamp <= timeRange.endTime);
+ return plateMatch && typeMatch && directionMatch && timeMatch;
+ });
+});
+
+// 鑾峰彇琛ㄦ牸鏁版嵁
+const getTableData = () => {
+ pagination.total = filteredData.value.length;
+ const start = (pagination.currentPage - 1) * pagination.pageSize;
+ const end = start + pagination.pageSize;
+ dataList.value = filteredData.value.slice(start, end);
+};
+
+// 閲嶇疆杩囨护鍣�
+const resetFilters = () => {
+ filters.plateNumber = "";
+ filters.vehicleType = "";
+ filters.direction = "";
+ filters.timeRange = [];
+ timeRange.startTime = "";
+ timeRange.endTime = "";
+ pagination.currentPage = 1;
+ getTableData();
+};
+
+// 鍒嗛〉鍙樺寲
+const changePage = ({ page, limit }) => {
+ pagination.currentPage = page;
+ pagination.pageSize = limit;
+ getTableData();
+};
+
+// 鏃堕棿鑼冨洿鍙樺寲
+const changeTimeRange = (value) => {
+ if (value && value.length === 2) {
+ timeRange.startTime = value[0];
+ timeRange.endTime = value[1];
+ } else {
+ timeRange.startTime = "";
+ timeRange.endTime = "";
+ }
+ getTableData();
+};
+
+// 鏌ョ湅杞﹁締璇︽儏
+const viewDetail = (row) => {
+ selectedVehicle.value = row;
+ detailVisible.value = true;
+};
+
+// 鍒濆鍖栨暟鎹�
+onMounted(() => {
+ getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+ margin-top: unset;
+}
+
+.vehicle-stats {
+ display: flex;
+ gap: 20px;
+ margin-bottom: 20px;
+
+ .stat-card {
+ flex: 1;
+ background: #fff;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ text-align: center;
+
+ .stat-title {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 10px;
+ }
+
+ .stat-value {
+ font-size: 32px;
+ font-weight: bold;
+
+ &.in {
+ color: #67c23a;
+ }
+
+ &.out {
+ color: #409eff;
+ }
+
+ &.present {
+ color: #e6a23c;
+ }
+
+ &.total {
+ color: #909399;
+ }
+ }
+ }
+}
+
+.vehicle-detail {
+ .detail-section {
+ margin-bottom: 20px;
+
+ h3 {
+ font-size: 16px;
+ font-weight: bold;
+ margin-bottom: 10px;
+ color: #303133;
+ }
+ }
+
+ .vehicle-images {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 15px;
+
+ .image-item {
+ background: #f5f7fa;
+ padding: 15px;
+ border-radius: 8px;
+
+ .image-title {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 10px;
+ text-align: center;
+ }
+ }
+ }
+}
+</style>
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 62f0c6a..7ef5e8d 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -63,6 +63,8 @@
size: pagination.pageSize,
total: pagination.total,
}"
+ :isShowSummary="true"
+ :summaryMethod="summaryMethod"
@selection-change="handleSelectionChange"
@pagination="changePage"
>
@@ -90,6 +92,8 @@
import dayjs from "dayjs";
import QRCode from "qrcode";
import { ref } from "vue";
+import { summarizeTable } from "@/utils/summarizeTable";
+import {Search} from "@element-plus/icons-vue";
defineOptions({
name: "璁惧鍙拌处",
@@ -205,6 +209,20 @@
pagination.pageSize = limit;
onCurrentChange(page);
};
+
+// 鍚堣鏂规硶
+const summaryMethod = (param) => {
+ return summarizeTable(
+ param,
+ ['number', 'taxIncludingPriceTotal', 'unTaxIncludingPriceTotal', 'taxIncludingPriceUnit'],
+ {
+ number: { noDecimal: true },
+ taxIncludingPriceTotal: { decimalPlaces: 2 },
+ unTaxIncludingPriceTotal: { decimalPlaces: 2 }
+ }
+ );
+};
+
const deleteRow = (id) => {
ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?", "鎻愮ず", {
confirmButtonText: "纭畾",
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 477e880..fe39579 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -143,6 +143,7 @@
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
import MaintainModal from "./Modal/MaintainModal.vue";
+import {Search} from "@element-plus/icons-vue";
defineOptions({
name: "璁惧鎶ヤ慨",
diff --git a/src/views/financialManagement/financialReconciliation/index.vue b/src/views/financialManagement/financialReconciliation/index.vue
new file mode 100644
index 0000000..fa4db0a
--- /dev/null
+++ b/src/views/financialManagement/financialReconciliation/index.vue
@@ -0,0 +1,291 @@
+<template>
+ <div class="app-container">
+ <!-- 鎼滅储鍖� -->
+ <div class="search_form">
+ <el-form :inline="true" :model="searchForm">
+ <el-form-item label="寰�鏉ュ崟浣嶏細">
+ <el-input v-model="searchForm.counterparty" placeholder="璇疯緭鍏ュ線鏉ュ崟浣�" clearable style="width: 180px" />
+ </el-form-item>
+ <el-form-item label="瀵硅处鐘舵�侊細">
+ <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" clearable style="width: 150px">
+ <el-option label="鏈璐�" value="pending" />
+ <el-option label="瀵硅处涓�" value="processing" />
+ <el-option label="宸插畬鎴�" value="done" />
+ </el-select>
+ </el-form-item>
+ <!-- <el-form-item label="鏃ユ湡锛�">
+ <el-date-picker
+ v-model="searchForm.dateRange"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ />
+ </el-form-item> -->
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ <el-button @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <!-- 鎿嶄綔鍖� -->
+ <div class="actions">
+ <el-button type="primary" @click="openDialog('add')">鏂板</el-button>
+ <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+ </div>
+
+ <!-- 琛ㄦ牸 -->
+ <el-table
+ :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ style="width: 100%"
+ height="calc(100vh - 280px)"
+ :row-key="row => row.id"
+ >
+ <el-table-column type="selection" width="55" align="center" />
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="accountDate" label="瀵硅处鏃ユ湡" width="130" show-overflow-tooltip />
+ <el-table-column prop="counterparty" label="寰�鏉ュ崟浣�" width="180" show-overflow-tooltip />
+ <el-table-column prop="amount" label="瀵硅处閲戦(鍏�)" width="140" show-overflow-tooltip />
+ <el-table-column prop="statusText" label="鐘舵��" width="120" show-overflow-tooltip />
+ <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openDialog('edit', scope.row)">缂栬緫</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"
+ />
+
+ <!-- 寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="520px" @close="resetForm">
+ <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+ <el-form-item label="瀵硅处鏃ユ湡锛�" prop="accountDate">
+ <el-date-picker v-model="form.accountDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" style="width: 100%" />
+ </el-form-item>
+ <el-form-item label="寰�鏉ュ崟浣嶏細" prop="counterparty">
+ <el-input v-model="form.counterparty" placeholder="璇疯緭鍏ュ線鏉ュ崟浣�" />
+ </el-form-item>
+ <el-form-item label="瀵硅处閲戦(鍏�)锛�" prop="amount">
+ <el-input-number v-model="form.amount" :min="0" :precision="2" :step="100" style="width: 100%" />
+ </el-form-item>
+ <el-form-item label="鐘舵�侊細" prop="status">
+ <el-select v-model="form.status" placeholder="璇烽�夋嫨" style="width: 100%">
+ <el-option label="鏈璐�" value="pending" />
+ <el-option label="瀵硅处涓�" value="processing" />
+ <el-option label="宸插畬鎴�" value="done" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞锛�">
+ <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import pagination from '@/components/PIMTable/Pagination.vue'
+import {
+ getReconciliationPage,
+ addReconciliation,
+ updateReconciliation,
+ deleteReconciliation
+} from '@/api/financialManagement/financialReconciliation.js'
+
+const tableData = ref([])
+const tableLoading = ref(false)
+const selectedRows = ref([])
+const dialogVisible = ref(false)
+const dialogTitle = ref('鏂板')
+const formRef = ref(null)
+
+const page = reactive({
+ current: 1,
+ size: 100
+})
+const total = ref(0)
+
+const searchForm = reactive({
+ counterparty: '',
+ status: '',
+ dateRange: []
+})
+
+const form = reactive({
+ id: null,
+ accountDate: '',
+ counterparty: '',
+ amount: null,
+ status: '',
+ remark: ''
+})
+
+const rules = {
+ accountDate: [{ required: true, message: '璇烽�夋嫨瀵硅处鏃ユ湡', trigger: 'change' }],
+ counterparty: [{ required: true, message: '璇疯緭鍏ュ線鏉ュ崟浣�', trigger: 'blur' }],
+ amount: [{ required: true, message: '璇疯緭鍏ュ璐﹂噾棰�', trigger: 'blur' }],
+ status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
+}
+
+const statusTextMap = {
+ pending: '鏈璐�',
+ processing: '瀵硅处涓�',
+ done: '宸插畬鎴�'
+}
+
+// 鑾峰彇鍒楄〃
+const getList = () => {
+ tableLoading.value = true
+ const params = {
+ ...searchForm,
+ current: page.current,
+ size: page.size
+ }
+ if (params.dateRange && params.dateRange.length === 2) {
+ params.beginDate = params.dateRange[0]
+ params.endDate = params.dateRange[1]
+ }
+ delete params.dateRange
+
+ getReconciliationPage(params)
+ .then(res => {
+ if (res.code === 200) {
+ tableData.value = (res.data?.records || []).map(item => ({
+ ...item,
+ statusText: statusTextMap[item.status] || item.status
+ }))
+ total.value = res.data?.total || 0
+ }
+ })
+ .finally(() => {
+ tableLoading.value = false
+ })
+}
+
+const handleQuery = () => {
+ page.current = 1
+ getList()
+}
+const resetQuery = () => {
+ searchForm.counterparty = ''
+ searchForm.status = ''
+ searchForm.dateRange = []
+ handleQuery()
+}
+const paginationChange = (obj) => {
+ page.current = obj.page
+ page.size = obj.limit
+ getList()
+}
+
+const handleSelectionChange = (rows) => {
+ selectedRows.value = rows
+}
+
+const openDialog = (type, row) => {
+ dialogTitle.value = type === 'add' ? '鏂板瀵硅处璁板綍' : '缂栬緫瀵硅处璁板綍'
+ if (type === 'edit' && row) {
+ Object.assign(form, row)
+ } else {
+ resetForm()
+ }
+ dialogVisible.value = true
+}
+
+const resetForm = () => {
+ Object.assign(form, {
+ id: null,
+ date: '',
+ counterparty: '',
+ amount: null,
+ status: '',
+ remark: ''
+ })
+}
+
+const submitForm = () => {
+ formRef.value?.validate(valid => {
+ if (!valid) return
+ const payload = { ...form }
+ const request = payload.id ? updateReconciliation(payload) : addReconciliation(payload)
+ request
+ .then(res => {
+ if (res.code === 200) {
+ ElMessage.success('鎻愪氦鎴愬姛')
+ dialogVisible.value = false
+ getList()
+ }
+ })
+ .catch(err => {
+ ElMessage.error(err.msg || '鎻愪氦澶辫触')
+ })
+ })
+}
+
+const handleDelete = () => {
+ if (!selectedRows.value.length) {
+ ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑璁板綍')
+ return
+ }
+ ElMessageBox.confirm('纭鍒犻櫎閫変腑璁板綍鍚楋紵', '鎻愮ず', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ const ids = selectedRows.value.map(r => r.id)
+ deleteReconciliation(ids).then(res => {
+ if (res.code === 200) {
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ getList()
+ selectedRows.value = []
+ }
+ }).catch(err => {
+ ElMessage.error(err.msg || '鍒犻櫎澶辫触')
+ })
+ }).catch(() => {})
+}
+
+onMounted(() => {
+ getList()
+})
+</script>
+
+<style scoped lang="scss">
+.app-container {
+ padding: 20px;
+
+ .search_form {
+ background: #fff;
+ padding: 16px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+ }
+
+ .actions {
+ margin-bottom: 12px;
+ }
+}
+</style>
diff --git a/src/views/financialManagement/fundsManagement/index.vue b/src/views/financialManagement/fundsManagement/index.vue
new file mode 100644
index 0000000..845dc52
--- /dev/null
+++ b/src/views/financialManagement/fundsManagement/index.vue
@@ -0,0 +1,298 @@
+<template>
+ <div class="app-container">
+ <!-- 鎼滅储鍖� -->
+ <div class="search_form">
+ <el-form :inline="true" :model="searchForm">
+ <el-form-item label="璧勯噾绫诲瀷锛�">
+ <el-select v-model="searchForm.typeText" 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-input v-model="searchForm.account" placeholder="璇疯緭鍏ヨ处鎴�" clearable style="width: 160px" />
+ </el-form-item>
+ <!-- <el-form-item label="鏃ユ湡锛�">
+ <el-date-picker
+ v-model="searchForm.dateRange"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ />
+ </el-form-item> -->
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ <el-button @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <!-- 鎿嶄綔鍖� -->
+ <div class="actions">
+ <el-button type="primary" @click="openDialog('add')">鏂板</el-button>
+ <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+ </div>
+
+ <!-- 琛ㄦ牸 -->
+ <el-table
+ :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ style="width: 100%"
+ height="calc(100vh - 280px)"
+ :row-key="row => row.id"
+ >
+ <el-table-column type="selection" width="55" align="center" />
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="accountDate" label="鏃ユ湡" width="130" show-overflow-tooltip />
+ <el-table-column prop="typeText" label="璧勯噾绫诲瀷" width="120" show-overflow-tooltip />
+ <el-table-column prop="amount" label="閲戦(鍏�)" width="120" show-overflow-tooltip />
+ <el-table-column prop="account" label="璐︽埛" width="160" show-overflow-tooltip />
+ <el-table-column prop="counterparty" label="寰�鏉ュ崟浣�" width="180" show-overflow-tooltip />
+ <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+ <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+ <template #default="scope">
+ <el-button link type="primary" size="small" @click="openDialog('edit', scope.row)">缂栬緫</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"
+ />
+
+ <!-- 寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="520px" @close="resetForm">
+ <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+ <el-form-item label="鏃ユ湡锛�" prop="accountDate">
+ <el-date-picker v-model="form.accountDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" style="width: 100%" />
+ </el-form-item>
+ <el-form-item label="璧勯噾绫诲瀷锛�" prop="typeText">
+ <el-select v-model="form.typeText" placeholder="璇烽�夋嫨" style="width: 100%">
+ <el-option label="鏀跺叆" value="鏀跺叆" />
+ <el-option label="鏀嚭" value="鏀嚭" />
+ <el-option label="鍐呴儴杞处" value="鍐呴儴杞处" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="閲戦(鍏�)锛�" prop="amount">
+ <el-input-number v-model="form.amount" :min="0" :precision="2" :step="100" style="width: 100%" />
+ </el-form-item>
+ <el-form-item label="璐︽埛锛�" prop="account">
+ <el-input v-model="form.account" placeholder="璇疯緭鍏ヨ处鎴�" />
+ </el-form-item>
+ <el-form-item label="寰�鏉ュ崟浣嶏細" prop="counterparty">
+ <el-input v-model="form.counterparty" placeholder="璇疯緭鍏ュ線鏉ュ崟浣�" />
+ </el-form-item>
+ <el-form-item label="澶囨敞锛�">
+ <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import pagination from '@/components/PIMTable/Pagination.vue'
+import {
+ getFundsPage,
+ addFunds,
+ updateFunds,
+ deleteFunds
+} from '@/api/financialManagement/fundsManagement.js'
+
+const tableData = ref([])
+const tableLoading = ref(false)
+const selectedRows = ref([])
+const dialogVisible = ref(false)
+const dialogTitle = ref('鏂板')
+const formRef = ref(null)
+
+const page = reactive({
+ current: 1,
+ size: 100
+})
+const total = ref(0)
+
+const searchForm = reactive({
+ typeText: '',
+ account: '',
+ dateRange: []
+})
+
+const form = reactive({
+ id: null,
+ accountDate: '',
+ typeText: '',
+ amount: null,
+ account: '',
+ counterparty: '',
+ remark: ''
+})
+
+const rules = {
+ accountDate: [{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }],
+ typeText: [{ required: true, message: '璇烽�夋嫨璧勯噾绫诲瀷', trigger: 'change' }],
+ amount: [{ required: true, message: '璇疯緭鍏ラ噾棰�', trigger: 'blur' }],
+ account: [{ required: true, message: '璇疯緭鍏ヨ处鎴�', trigger: 'blur' }]
+}
+
+const typeTextMap = {
+ income: '鏀跺叆',
+ expense: '鏀嚭',
+ transfer: '鍐呴儴杞处'
+}
+
+// 鑾峰彇鍒楄〃
+const getList = () => {
+ tableLoading.value = true
+ const params = {
+ ...searchForm,
+ current: page.current,
+ size: page.size
+ }
+ // 鍏煎鍚庣瀛楁锛氳嫢鍚庣浣跨敤 typeText锛岃鐩存帴浼犻�掞紱鑻ヤ娇鐢� type锛岃涓庡悗绔榻�
+ if (params.dateRange && params.dateRange.length === 2) {
+ params.beginDate = params.dateRange[0]
+ params.endDate = params.dateRange[1]
+ }
+ delete params.dateRange
+
+ getFundsPage(params)
+ .then(res => {
+ if (res.code === 200) {
+ tableData.value = (res.data?.records || []).map(item => ({
+ ...item,
+ typeText: item.typeText || typeTextMap[item.typeText] || item.typeText
+ }))
+ total.value = res.data?.total || 0
+ }
+ })
+ .finally(() => {
+ tableLoading.value = false
+ })
+}
+
+const handleQuery = () => {
+ page.current = 1
+ getList()
+}
+const resetQuery = () => {
+ searchForm.typeText = ''
+ searchForm.account = ''
+ searchForm.dateRange = []
+ handleQuery()
+}
+const paginationChange = (obj) => {
+ page.current = obj.page
+ page.size = obj.limit
+ getList()
+}
+
+const handleSelectionChange = (rows) => {
+ selectedRows.value = rows
+}
+
+const openDialog = (type, row) => {
+ dialogTitle.value = type === 'add' ? '鏂板璧勯噾璁板綍' : '缂栬緫璧勯噾璁板綍'
+ if (type === 'edit' && row) {
+ Object.assign(form, row)
+ } else {
+ resetForm()
+ }
+ dialogVisible.value = true
+}
+
+const resetForm = () => {
+ Object.assign(form, {
+ id: null,
+ accountDate: '',
+ typeText: '',
+ amount: null,
+ account: '',
+ counterparty: '',
+ remark: ''
+ })
+}
+
+const submitForm = () => {
+ formRef.value?.validate(valid => {
+ if (!valid) return
+ const payload = { ...form }
+ const request = payload.id ? updateFunds(payload) : addFunds(payload)
+ request
+ .then(res => {
+ if (res.code === 200) {
+ ElMessage.success('鎻愪氦鎴愬姛')
+ dialogVisible.value = false
+ getList()
+ }
+ })
+ .catch(err => {
+ ElMessage.error(err.msg || '鎻愪氦澶辫触')
+ })
+ })
+}
+
+const handleDelete = () => {
+ if (!selectedRows.value.length) {
+ ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑璁板綍')
+ return
+ }
+ ElMessageBox.confirm('纭鍒犻櫎閫変腑璁板綍鍚楋紵', '鎻愮ず', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ const ids = selectedRows.value.map(r => r.id)
+ deleteFunds(ids).then(res => {
+ if (res.code === 200) {
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ getList()
+ selectedRows.value = []
+ }
+ }).catch(err => {
+ ElMessage.error(err.msg || '鍒犻櫎澶辫触')
+ })
+ }).catch(() => {})
+}
+
+onMounted(() => {
+ getList()
+})
+</script>
+
+<style scoped lang="scss">
+.app-container {
+ padding: 20px;
+
+ .search_form {
+ background: #fff;
+ padding: 16px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+ }
+
+ .actions {
+ margin-bottom: 12px;
+ }
+}
+</style>
diff --git a/src/views/index.vue b/src/views/index.vue
index 2888b16..ec00a3f 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -18,126 +18,126 @@
</div>
</div>
</div>
- <div class="data-cards">
- <div class="data-card sales">
- <div class="data-title">閿�鍞暟鎹�</div>
- <div class="data-num">
- <div>
- <div class="data-desc">鏈湀閿�鍞/鍏�</div>
- <div class="data-value">{{businessInfo.monthSaleMoney}}</div>
- </div>
- <div>
- <div class="data-desc">鏈紑绁ㄩ噾棰�/鍏�</div>
- <div class="data-value">{{businessInfo.monthSaleHaveMoney}}</div>
- </div>
- </div>
-
- </div>
- <div class="data-card purchase">
- <div class="data-title">閲囪喘鏁版嵁</div>
- <div class="data-num">
- <div>
- <div class="data-desc">鏈湀閲囪喘棰�/鍏�</div>
- <div class="data-value">{{businessInfo.monthPurchaseMoney}}</div>
- </div>
- <div>
- <div class="data-desc">寰呬粯娆鹃噾棰�/鍏�</div>
- <div class="data-value">{{businessInfo.monthPurchaseHaveMoney}}</div>
- </div>
- </div>
- </div>
- <div class="data-card inventory">
- <div class="data-title">搴撳瓨鏁版嵁</div>
- <div class="data-num">
- <div>
- <div class="data-desc">褰撳墠搴撳瓨鎬婚噺/浠�</div>
- <div class="data-value">{{businessInfo.inventoryNum}}</div>
- </div>
- <div>
- <div class="data-desc">浠婃棩鍏ュ簱/浠�</div>
- <div class="data-value">{{businessInfo.todayInventoryNum}}</div>
- </div>
- </div>
- </div>
- </div>
+<!-- <div class="data-cards">-->
+<!-- <div class="data-card sales">-->
+<!-- <div class="data-title">閿�鍞暟鎹�</div>-->
+<!-- <div class="data-num">-->
+<!-- <div>-->
+<!-- <div class="data-desc">鏈湀閿�鍞/鍏�</div>-->
+<!-- <div class="data-value">{{businessInfo.monthSaleMoney}}</div>-->
+<!-- </div>-->
+<!-- <div>-->
+<!-- <div class="data-desc">鏈紑绁ㄩ噾棰�/鍏�</div>-->
+<!-- <div class="data-value">{{businessInfo.monthSaleHaveMoney}}</div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- -->
+<!-- </div>-->
+<!-- <div class="data-card purchase">-->
+<!-- <div class="data-title">閲囪喘鏁版嵁</div>-->
+<!-- <div class="data-num">-->
+<!-- <div>-->
+<!-- <div class="data-desc">鏈湀閲囪喘棰�/鍏�</div>-->
+<!-- <div class="data-value">{{businessInfo.monthPurchaseMoney}}</div>-->
+<!-- </div>-->
+<!-- <div>-->
+<!-- <div class="data-desc">寰呬粯娆鹃噾棰�/鍏�</div>-->
+<!-- <div class="data-value">{{businessInfo.monthPurchaseHaveMoney}}</div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- <div class="data-card inventory">-->
+<!-- <div class="data-title">搴撳瓨鏁版嵁</div>-->
+<!-- <div class="data-num">-->
+<!-- <div>-->
+<!-- <div class="data-desc">褰撳墠搴撳瓨鎬婚噺/浠�</div>-->
+<!-- <div class="data-value">{{businessInfo.inventoryNum}}</div>-->
+<!-- </div>-->
+<!-- <div>-->
+<!-- <div class="data-desc">浠婃棩鍏ュ簱/浠�</div>-->
+<!-- <div class="data-value">{{businessInfo.todayInventoryNum}}</div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
</div>
<!-- 鍙筹細寰呭姙浜嬮」 -->
- <div class="todo-panel">
- <div class="section-title">寰呭姙浜嬮」</div>
- <ul class="todo-list" v-if="todoList.length > 0">
- <li v-for="item in todoList" :key="item.id">
- <div style="display: flex;flex-direction: column;justify-content: space-between;width: 100%;gap: 20px">
- <div style="display: flex;justify-content: space-between;align-items: center;">
- <div class="todo-title">寰呭姙缂栧彿锛歿{item.approveId}}</div>
- <div class="todo-division">閮ㄩ棬锛歿{item.approveDeptName}}</div>
- <div class="todo-time">{{item.approveTime}}</div>
- </div>
- <div class="todo-division">寰呭姙浜嬬敱锛歿{item.approveReason}}</div>
- </div>
- </li>
- </ul>
- <div v-else style="text-align: center">
- 鏆傛棤鏁版嵁
- </div>
- </div>
- </div>
-
- <!-- 涓儴妯悜涓ゆ爮 -->
- <div class="dashboard-row">
- <div class="main-panel">
- <div class="section-title">瀹㈡埛鍚堝悓閲戦鍒嗘瀽</div>
- <div class="contract-summary">
- <div class="contract-info">
- <img src="../assets/images/khtitle.png" alt="" style="width: 42px"/>
- <div class="contract-card">
- <div class="contract-name">鎬诲悎鍚岄噾棰�(鍏�)</div>
- <div class="contract-meta">
- <div class="main-amount">{{sum}}</div>
- <div>鍛ㄥ悓姣�: <span class="up">{{yny}}% </span> 鏃ョ幆姣�: <span class="up">{{chain}}% </span></div>
- </div>
- </div>
- </div>
- </div>
- <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 180px;margin-top: 20px">
- <div>
- <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
- :series="materialPieSeries"
- :tooltip="pieTooltip"></Echarts>
- </div>
- <ul class="contract-list">
- <li v-for="item in materialPieSeries[0].data" :key="item.name">
- <div style="display: flex;align-items: center;justify-content: space-between;width: 100%">
- <div class="line" :style="{color: item.itemStyle.color}">鈼弡{item.name}}</div>
- <div style="width: 70px">{{item.rate}}%</div>
- <div>锟{item.value}}</div>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="main-panel">
- <div style="display: flex;justify-content: space-between;">
- <div class="section-title">搴旀敹搴斾粯缁熻</div>
- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">
- <el-radio-button label="鎸夊懆" :value="1" />
- <el-radio-button label="鎸夋湀" :value="2" />
- <el-radio-button label="鎸夊搴�" :value="3" />
- </el-radio-group>
- </div>
- <Echarts ref="chart"
- :color="barColors2"
- :chartStyle="chartStyle"
- :grid="grid"
- :series="barSeries"
- :tooltip="tooltip"
- :xAxis="xAxis"
- :yAxis="yAxis"
- style="height: 260px"></Echarts>
- </div>
- </div>
-
+<!-- <div class="todo-panel">-->
+<!-- <div class="section-title">寰呭姙浜嬮」</div>-->
+<!-- <ul class="todo-list" v-if="todoList.length > 0">-->
+<!-- <li v-for="item in todoList" :key="item.id">-->
+<!-- <div style="display: flex;flex-direction: column;justify-content: space-between;width: 100%;gap: 20px">-->
+<!-- <div style="display: flex;justify-content: space-between;align-items: center;">-->
+<!-- <div class="todo-title">娴佺▼缂栧彿锛歿{item.approveId}}</div>-->
+<!-- <div class="todo-division">鐢宠閮ㄩ棬锛歿{item.approveDeptName}}</div>-->
+<!-- <div class="todo-time">{{item.approveTime}}</div>-->
+<!-- </div>-->
+<!-- <div class="todo-division">瀹℃壒浜嬬敱锛歿{item.approveReason}}</div>-->
+<!-- </div>-->
+<!-- </li>-->
+<!-- </ul>-->
+<!-- <div v-else style="text-align: center">-->
+<!-- 鏆傛棤鏁版嵁-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- -->
+<!-- <!– 涓儴妯悜涓ゆ爮 –>-->
+<!-- <div class="dashboard-row">-->
+<!-- <div class="main-panel">-->
+<!-- <div class="section-title">瀹㈡埛鍚堝悓閲戦鍒嗘瀽</div>-->
+<!-- <div class="contract-summary">-->
+<!-- <div class="contract-info">-->
+<!-- <img src="../assets/images/khtitle.png" alt="" style="width: 42px"/>-->
+<!-- <div class="contract-card">-->
+<!-- <div class="contract-name">鎬诲悎鍚岄噾棰�(鍏�)</div>-->
+<!-- <div class="contract-meta">-->
+<!-- <div class="main-amount">{{sum}}</div>-->
+<!-- <div>鍛ㄥ悓姣�: <span class="up">{{yny}}% </span> 鏃ョ幆姣�: <span class="up">{{chain}}% </span></div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 180px;margin-top: 20px">-->
+<!-- <div>-->
+<!-- <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"-->
+<!-- :series="materialPieSeries"-->
+<!-- :tooltip="pieTooltip"></Echarts>-->
+<!-- </div>-->
+<!-- <ul class="contract-list">-->
+<!-- <li v-for="item in materialPieSeries[0].data" :key="item.name">-->
+<!-- <div style="display: flex;align-items: center;justify-content: space-between;width: 100%">-->
+<!-- <div class="line" :style="{color: item.itemStyle.color}">鈼弡{item.name}}</div>-->
+<!-- <div style="width: 70px">{{item.rate}}%</div>-->
+<!-- <div>锟{item.value}}</div>-->
+<!-- </div>-->
+<!-- </li>-->
+<!-- </ul>-->
+<!-- </div>-->
+<!-- </div>-->
+<!-- <div class="main-panel">-->
+<!-- <div style="display: flex;justify-content: space-between;">-->
+<!-- <div class="section-title">搴旀敹搴斾粯缁熻</div>-->
+<!--<!– <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">–>-->
+<!--<!– <el-radio-button label="鎸夊懆" :value="1" />–>-->
+<!--<!– <el-radio-button label="鎸夋湀" :value="2" />–>-->
+<!--<!– <el-radio-button label="鎸夊搴�" :value="3" />–>-->
+<!--<!– </el-radio-group>–>-->
+<!-- </div>-->
+<!-- <Echarts ref="chart"-->
+<!-- :color="barColors2"-->
+<!-- :chartStyle="chartStyle"-->
+<!-- :grid="grid"-->
+<!-- :series="barSeries"-->
+<!-- :tooltip="tooltip"-->
+<!-- :xAxis="xAxis"-->
+<!-- :yAxis="yAxis"-->
+<!-- style="height: 260px"></Echarts>-->
+<!-- </div>-->
+<!-- </div>-->
+
<!-- 搴曢儴妯悜涓ゆ爮 -->
- <div class="dashboard-row">
+<!-- <div class="dashboard-row">-->
<!-- <div class="main-panel">-->
<!-- <div class="section-title">璐ㄩ噺缁熻</div>-->
<!-- <div class="quality-cards">-->
@@ -155,11 +155,11 @@
<!-- :yAxis="yAxis1"-->
<!-- style="height: 260px"></Echarts>-->
<!-- </div>-->
- <div class="main-panel">
- <div class="section-title">鍥炴涓庡紑绁ㄥ垎鏋�</div>
- <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries"
- :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" style="height: 270px;"></Echarts>
- </div>
+<!-- <div class="main-panel">-->
+<!-- <div class="section-title">鍥炴涓庡紑绁ㄥ垎鏋�</div>-->
+<!-- <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries"-->
+<!-- :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" style="height: 270px;"></Echarts>-->
+<!-- </div>-->
</div>
</div>
</template>
@@ -506,7 +506,7 @@
min-width: 0;
background-color: #EFF2FB; /* 浣跨敤鎸囧畾鐨勮儗鏅鑹� */
background-image: url("../assets/images/denglu.png");
- background-size: cover;
+ background-size: 100% 260%;
background-position: center;
background-repeat: no-repeat;
border-radius: 12px;
@@ -789,7 +789,7 @@
}
.quality-card.three {
background-image: url("../assets/images/chuchang.png");
-
+
}
.quality-card span {
color: #4fc3f7;
@@ -801,4 +801,4 @@
height: 220px;
margin-top: 10px;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDia.vue b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
index 5ea86b2..2a1476f 100644
--- a/src/views/inventoryManagement/receiptManagement/components/formDia.vue
+++ b/src/views/inventoryManagement/receiptManagement/components/formDia.vue
@@ -78,6 +78,7 @@
selectProductRecordListByPuechaserId
} from "@/api/inventoryManagement/stockIn.js";
import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
+import { getCurrentDate } from "@/utils/index.js";
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
@@ -195,7 +196,7 @@
const calculateTotalPrice = (row) => {
const quantityStock = Number(row?.quantityStock ?? 0);
const taxInclusiveUnitPrice = Number(row?.taxInclusiveUnitPrice ?? 0);
-
+
if (Number.isFinite(quantityStock) && Number.isFinite(taxInclusiveUnitPrice)) {
row.taxInclusiveTotalPrice = quantityStock * taxInclusiveUnitPrice;
} else {
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue
new file mode 100644
index 0000000..f0f9d75
--- /dev/null
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue
@@ -0,0 +1,310 @@
+<template>
+ <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鑷畾涔夊叆搴�' : '缂栬緫鑷畾涔夊叆搴�'" width="70%"
+ @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <div style="margin-bottom: 10px;" v-if="operationType === 'add'">
+ <el-button type="primary" @click="addProductRow">鏂板</el-button>
+ </div>
+ <el-table
+ :data="productList"
+ border
+ v-loading="loadingProducts"
+ >
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.productCategory" placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅" prop="unit" width="100">
+ <template #default="scope">
+ <el-input v-model="scope.row.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200">
+ <template #default="scope">
+ <el-input v-model="scope.row.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鐗╁搧绫诲瀷" prop="itemType" width="150">
+ <template #default="scope">
+ <el-input v-model="scope.row.itemType" placeholder="璇疯緭鍏ョ墿鍝佺被鍨�" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍏ュ簱鏃ユ湡" prop="inboundDate" width="180">
+ <template #default="scope">
+ <el-date-picker
+ v-model="scope.row.inboundDate"
+ type="date"
+ placeholder="璇烽�夋嫨鍏ュ簱鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" />
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ width="150"
+ >
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
+ <template #default="scope">
+ <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from 'vue'
+import useUserStore from '@/store/modules/user'
+import {
+ addStockInCustom,
+ updateStockInCustom,
+} from "@/api/inventoryManagement/stockIn.js";
+import { getCurrentDate } from "@/utils/index.js";
+
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close', 'success'])
+
+const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
+const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
+const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
+const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
+const loading = ref(false);
+
+function formatDateTime(date = new Date(), includeTime = true) {
+ const d = new Date(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+
+ if (!includeTime) {
+ return `${year}-${month}-${day}`;
+ }
+
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+
+const taxRateOptions = [
+ { label: '1', value: 1 },
+ { label: '6', value: 6 },
+ { label: '13', value: 13 },
+]
+
+const data = reactive({
+ form: {
+ id: null,
+ supplierId: null, // 渚涘簲鍟咺D
+ supplierName: '', // 渚涘簲鍟嗗悕绉�
+ recorderId: userStore.userId, // 褰曞叆浜篒D
+ recorderName: userStore.name, // 褰曞叆浜哄鍚�
+ entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
+ remark: '', // 澶囨敞
+ },
+ rules: {
+ supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }]
+ }
+})
+const { form, rules } = toRefs(data)
+
+// 鏂板浜у搧琛�
+const addProductRow = () => {
+ productList.value.push({
+ id: null,
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ supplierName: form.value.supplierName || '',
+ itemType: '',
+ inboundNum: 0,
+ inboundDate: getCurrentDate(), // 榛樿褰撳ぉ鏃ユ湡
+ // quantityStock: 0,
+ taxInclusiveUnitPrice: 0,
+ taxInclusiveTotalPrice: 0,
+ taxRate: null,
+ taxExclusiveTotalPrice: 0,
+ });
+};
+
+// 鍒犻櫎浜у搧琛�
+const removeProductRow = (index) => {
+ productList.value.splice(index, 1);
+};
+
+// 璁$畻鎬讳环锛堟牴鎹暟閲忋�佸崟浠峰拰鍚◣鍗曚环锛�
+const calculateTotalPrice = (row) => {
+ // 璁$畻鏅�氭�讳环锛歩nboundNum * taxInclusiveUnitPrice
+ const quantity = Number(row.inboundNum || 0);
+ const taxInclusiveUnitPrice = Number(row.taxInclusiveUnitPrice || 0);
+ row.taxInclusiveTotalPrice = quantity * taxInclusiveUnitPrice;
+ calculateExclusivePrice(row);
+};
+
+// 璁$畻涓嶅惈绋庢�讳环锛堟牴鎹惈绋庢�讳环鍜岀◣鐜囷級
+const calculateExclusivePrice = (row) => {
+ const taxInclusiveTotalPrice = Number(row.taxInclusiveTotalPrice || 0);
+ const taxRate = Number(row.taxRate || 0);
+ row.taxExclusiveTotalPrice = taxInclusiveTotalPrice / (1 + taxRate / 100);
+};
+
+const submitForm = async () => {
+ try {
+ await proxy.$refs.formRef.validate()
+
+ if (!productList.value.length) {
+ proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
+ return
+ }
+
+ // 楠岃瘉鑷畾涔夋坊鍔犵殑鏁版嵁蹇呭~瀛楁
+ for (let i = 0; i < productList.value.length; i++) {
+ const product = productList.value[i];
+ if (!product.productCategory || !product.specificationModel || !product.unit) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屼骇鍝佹暟鎹湭濉啓瀹屾暣锛堜骇鍝佸ぇ绫汇�佽鏍煎瀷鍙枫�佸崟浣嶄负蹇呭~锛塦)
+ return
+ }
+ if (!product.itemType) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鐗╁搧绫诲瀷`)
+ return
+ }
+ if (!product.inboundDate) {
+ proxy.$modal.msgError(`绗�${i + 1}琛岃閫夋嫨鍏ュ簱鏃ユ湡`)
+ return
+ }
+ const stock = Number(product?.inboundNum ?? 0);
+ if (!Number.isFinite(stock) || stock <= 0) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屾湰娆″叆搴撴暟閲忛渶澶т簬0`)
+ return
+ }
+ }
+
+ const payloadList = productList.value.map(product => ({
+ id: product.id ?? null,
+ inboundNum: Number(product.inboundNum),
+ productCategory: product.productCategory,
+ specificationModel: product.specificationModel,
+ unit: product.unit,
+ supplierName: product.supplierName || form.value.supplierName,
+ itemType: product.itemType,
+ inboundDate: formatDateTime(product.inboundDate, false),
+ taxRate: Number(product.taxRate || 0),
+ taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0),
+ taxInclusiveUnitPrice: Number(product.taxInclusiveUnitPrice || 0),
+ taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice || 0),
+ }));
+ loading.value = true
+ if (operationType.value === 'edit') {
+ const editPayload = payloadList[0]
+ await updateStockInCustom(editPayload)
+ } else {
+ await addStockInCustom(payloadList)
+ }
+
+ proxy.$modal.msgSuccess(operationType.value === 'edit' ? '缂栬緫鑷畾涔夊叆搴撴垚鍔�' : '鏂板鑷畾涔夊叆搴撴垚鍔�')
+ closeDia()
+ emit('success')
+
+ } catch (error) {
+ console.error('鎻愪氦澶辫触:', error)
+ if (!error.errors) {
+ proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
+ }
+ } finally {
+ loading.value = false
+ }
+}
+
+const closeDia = () => {
+ proxy.$refs.formRef.resetFields()
+ dialogFormVisible.value = false
+ productList.value = []
+ emit('close')
+}
+
+const openDialog = async (type, row) => {
+ operationType.value = type
+ dialogFormVisible.value = true
+
+ if (type === 'add') {
+ form.value = {
+ id: null,
+ supplierId: null,
+ supplierName: '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: ''
+ }
+ productList.value = []
+ } else {
+ // 缂栬緫妯″紡锛氬皢琛屾暟鎹~鍏呭埌琛ㄦ牸涓互鏀寔淇敼
+ form.value = {
+ id: row?.id ?? null,
+ supplierId: row?.supplierId ?? null,
+ supplierName: row?.supplierName ?? '',
+ recorderId: userStore.userId,
+ recorderName: userStore.name,
+ entryDate: getCurrentDate(),
+ remark: row?.remark ?? ''
+ }
+ productList.value = [{
+ id: row?.id ?? null,
+ productCategory: row?.productCategory ?? '',
+ specificationModel: row?.specificationModel ?? '',
+ unit: row?.unit ?? '',
+ supplierName: row?.supplierName ?? '',
+ itemType: row?.itemType ?? '',
+ inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0),
+ inboundDate: row?.inboundDate ?? row?.createTime ?? '',
+ taxRate: Number(row?.taxRate ?? 0),
+ taxInclusiveUnitPrice: Number(row?.taxInclusiveUnitPrice ?? 0),
+ taxInclusiveTotalPrice: Number(row?.taxInclusiveTotalPrice ?? 0),
+ taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0),
+ }]
+ }
+}
+
+defineExpose({
+ openDialog,
+})
+</script>
+
+<style scoped lang="scss"></style>
+
diff --git a/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
index 6048e18..c317a13 100644
--- a/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
+++ b/src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
@@ -53,10 +53,10 @@
<el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.unitPrice" @change="() => calculateTotalPrice(scope.row)" />
</template>
</el-table-column>
- <el-table-column
- label="鎬讳环(鍏�)"
- prop="totalPrice"
- width="150"
+ <el-table-column
+ label="鎬讳环(鍏�)"
+ prop="totalPrice"
+ width="150"
>
</el-table-column>
<el-table-column label="鎿嶄綔" width="80" v-if="operationType === 'add'">
@@ -81,6 +81,7 @@
import {
addStockInCustom, updateProduct
} from "@/api/inventoryManagement/stockIn.js";
+import { getCurrentDate } from "@/utils/index.js";
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
@@ -185,7 +186,7 @@
const submitForm = async () => {
try {
await proxy.$refs.formRef.validate()
-
+
if (!productList.value.length) {
proxy.$modal.msgError('璇疯嚦灏戞坊鍔犱竴鏉′骇鍝佹暟鎹�')
return
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue
new file mode 100644
index 0000000..e052ef9
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue
@@ -0,0 +1,163 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鏉愭枡搴撳瓨' : '缂栬緫鏉愭枡搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐗╁搧绫诲瀷锛�" prop="itemType">
+ <el-input disabled v-model="form.itemType" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="棰勮鍊硷細" prop="warnNum">
+ <el-input-number v-model="form.warnNum" placeholder="璇疯緭鍏ラ璀﹀��" clearable min="0" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+ <el-input v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+ <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="鑷姩璁$畻" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ itemType: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ taxInclusiveUnitPrice: '',
+ taxInclusiveTotalPrice: '',
+ warnNum: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ itemType: [{ required: true, message: '璇疯緭鍏ョ墿鍝佺被鍨�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }],
+ warnNum: [{ required: true, message: '璇疯緭鍏ラ璀﹀��', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氭�讳环 = 鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue
new file mode 100644
index 0000000..1653307
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue
@@ -0,0 +1,147 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鎴愬搧搴撳瓨' : '缂栬緫鎴愬搧搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍗曚环(鍏�)锛�" prop="unitPrice">
+ <el-input v-model="form.unitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鎬讳环(鍏�)锛�" prop="totalPrice">
+ <el-input disabled v-model="form.totalPrice" placeholder="鑷姩璁$畻" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ unitPrice: '',
+ totalPrice: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ unitPrice: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氭�讳环 = 鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.unitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.totalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue b/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue
new file mode 100644
index 0000000..5da2eee
--- /dev/null
+++ b/src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue
@@ -0,0 +1,147 @@
+<template>
+ <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍘熸枡搴撳瓨' : '缂栬緫鍘熸枡搴撳瓨'" width="70%"
+ @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia">
+ <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-input disabled v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
+ <el-input disabled v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍏ュ簱鏃堕棿锛�" prop="createTime">
+ <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+ type="date" placeholder="璇烽�夋嫨" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="搴撳瓨鏁伴噺锛�" prop="inboundNum">
+ <el-input v-model="form.inboundNum" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸插嚭搴撴暟閲忥細" prop="totalInboundNum">
+ <el-input disabled v-model="form.totalInboundNum" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="寰呭嚭搴撴暟閲忥細" prop="inboundNum0">
+ <el-input disabled v-model="form.inboundNum0" placeholder="璇疯緭鍏�" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+ <el-input v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable @input="calculateTotalPrice" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+ <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="鑷姩璁$畻" clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+
+const props = defineProps({
+ dialogFormVisible: Boolean,
+ operationType: String,
+ formData: Object
+})
+
+const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close'])
+
+const formRef = ref()
+
+const data = reactive({
+ form: {
+ productCategory: '',
+ specificationModel: '',
+ unit: '',
+ createTime: '',
+ inboundNum: '',
+ totalInboundNum: '',
+ inboundNum0: '',
+ taxInclusiveUnitPrice: '',
+ taxInclusiveTotalPrice: ''
+ },
+ rules: {
+ productCategory: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸ぇ绫�', trigger: 'blur' }],
+ specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
+ createTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
+ inboundNum: [{ required: true, message: '璇疯緭鍏ュ簱瀛樻暟閲�', trigger: 'blur' }],
+ taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' }]
+ }
+})
+
+const { form, rules } = toRefs(data)
+
+// 璁$畻鎬讳环锛氬惈绋庢�讳环 = 鍚◣鍗曚环 脳 鍓╀綑搴撳瓨
+const calculateTotalPrice = () => {
+ const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0
+ const stockQuantity = parseFloat(form.value.inboundNum) || 0 // 搴撳瓨鏁伴噺
+ const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // 宸插嚭搴撴暟閲�
+ const remainingStock = stockQuantity - outboundQuantity // 鍓╀綑搴撳瓨
+ form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2)
+}
+
+// 鐩戝惉formData鍙樺寲
+watch(() => props.formData, (newVal) => {
+ if (newVal) {
+ form.value = { ...newVal }
+ // 鏁版嵁鍙樺寲鍚庨噸鏂拌绠楁�讳环
+ calculateTotalPrice()
+ }
+}, { immediate: true })
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ emit('submit', form.value)
+ }
+ })
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ emit('close')
+ emit('update:dialogFormVisible', false)
+}
+
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+ text-align: center;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/stockWarningLedger/index.vue b/src/views/inventoryManagement/stockWarningLedger/index.vue
new file mode 100644
index 0000000..d78ea30
--- /dev/null
+++ b/src/views/inventoryManagement/stockWarningLedger/index.vue
@@ -0,0 +1,347 @@
+<template>
+ <div class="app-container">
+ <div class="search_form">
+ <el-form :model="searchForm" :inline="true">
+ <el-form-item label="浜у搧澶х被锛�">
+ <el-input
+ v-model="searchForm.productCategory"
+ placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�"
+ clearable
+ style="width: 200px"
+ />
+ </el-form-item>
+ <el-form-item label="瑙勬牸鍨嬪彿锛�">
+ <el-input
+ v-model="searchForm.specificationModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ clearable
+ style="width: 200px"
+ />
+ </el-form-item>
+ <el-form-item label="棰勮鐘舵�侊細">
+ <el-select
+ v-model="searchForm.warningStatus"
+ placeholder="璇烽�夋嫨棰勮鐘舵��"
+ clearable
+ style="width: 150px"
+ >
+ <el-option label="宸查璀�" value="宸查璀�" />
+ <el-option label="姝e父" value="姝e父" />
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ <el-button @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <div class="table_list">
+ <div class="actions"></div>
+ <el-table
+ :data="tableData"
+ border
+ v-loading="tableLoading"
+ style="width: 100%"
+ height="calc(100vh - 280px)"
+ >
+ <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+ <el-table-column label="鎵规鍙�" prop="code" width="130" show-overflow-tooltip />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" show-overflow-tooltip />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" show-overflow-tooltip />
+ <el-table-column label="褰撳墠搴撳瓨" prop="currentStock" width="120" show-overflow-tooltip>
+ <template #default="scope">
+ <span :class="getStockClass(scope.row)">{{ scope.row.currentStock || 0 }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏈�浣庡簱瀛�" prop="warnNum" width="120" show-overflow-tooltip />
+ <el-table-column label="棰勮绾у埆" prop="warningLevel" width="100" show-overflow-tooltip>
+ <template #default="scope">
+ <el-tag :type="getWarningLevelTag(scope.row.warningLevel)">
+ {{ scope.row.warningLevel || '-' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="棰勮鐘舵��" prop="warningStatus" width="100" show-overflow-tooltip>
+ <template #default="scope">
+ <el-tag :type="scope.row.warningStatus === '宸查璀�' ? 'danger' : 'success'">
+ {{ scope.row.warningStatus || '姝e父' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="棰勮鏃堕棿" prop="warningTime" width="150" show-overflow-tooltip />
+ <el-table-column label="棰勮缂鸿揣鏃堕棿" prop="expectedShortageTime" width="150" show-overflow-tooltip>
+ <template #default="scope">
+ <div v-if="scope.row.expectedShortageTime">
+ <div v-if="getCountdown(scope.row.expectedShortageTime).isExpired" class="countdown-expired">
+ <el-tag type="danger">宸茬己璐�</el-tag>
+ </div>
+ <div v-else class="countdown-timer">
+ <span :class="getCountdownClass(scope.row.expectedShortageTime)">
+ {{ getCountdown(scope.row.expectedShortageTime).text }}
+ </span>
+ </div>
+ </div>
+ <span v-else>-</span>
+ </template>
+ </el-table-column>
+ </el-table>
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"
+ />
+ </div>
+
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import pagination from '@/components/PIMTable/Pagination.vue'
+import {
+ getStockWarningLedgerPage
+} from '@/api/inventoryManagement/stockWarningLedger.js'
+
+// 鍝嶅簲寮忔暟鎹�
+const tableData = ref([])
+const tableLoading = ref(false)
+const total = ref(0)
+
+// 鍒嗛〉鍙傛暟
+const page = reactive({
+ current: 1,
+ size: 100
+})
+
+// 鎼滅储琛ㄥ崟
+const searchForm = reactive({
+ productCategory: '',
+ specificationModel: '',
+ warningStatus: ''
+})
+
+// 鑾峰彇鍒楄〃鏁版嵁
+const getList = () => {
+ tableLoading.value = true
+ const params = {
+ ...page,
+ ...searchForm
+ }
+ getStockWarningLedgerPage(params)
+ .then(res => {
+ tableLoading.value = false
+ if (res.code === 200) {
+ tableData.value = res.data.records || []
+ total.value = res.data.total || 0
+
+ // 璁$畻棰勮绾у埆鍜岀姸鎬�
+ tableData.value = tableData.value.map(item => {
+ const currentStock = parseFloat(item.inboundNum0 || item.currentStock || 0)
+ const warnNum = parseFloat(item.warnNum || 0)
+ const safetyStock = parseFloat(item.safetyStock || warnNum * 1.2)
+
+ // 璁$畻棰勮绾у埆
+ if (currentStock <= 0) {
+ item.warningLevel = '绱ф��'
+ item.warningStatus = '宸查璀�'
+ } else if (currentStock < warnNum) {
+ item.warningLevel = '閲嶈'
+ item.warningStatus = '宸查璀�'
+ } else if (currentStock < safetyStock) {
+ item.warningLevel = '涓�鑸�'
+ item.warningStatus = '宸查璀�'
+ } else {
+ item.warningLevel = ''
+ item.warningStatus = '姝e父'
+ }
+
+ // 璁$畻棰勮缂鸿揣鏃堕棿锛堝熀浜庢棩鍧囨秷鑰楅噺锛岃繖閲岀畝鍖栧鐞嗭級
+ if (item.warningStatus === '宸查璀�' && currentStock > 0 && warnNum > 0) {
+ const dailyConsumption = warnNum / 30 // 鍋囪30澶╂秷鑰楀畬鏈�浣庡簱瀛�
+ const daysRemaining = Math.floor(currentStock / dailyConsumption)
+ if (daysRemaining > 0) {
+ const date = new Date()
+ date.setDate(date.getDate() + daysRemaining)
+ item.expectedShortageTime = date.toISOString().split('T')[0]
+ }
+ }
+
+ item.currentStock = currentStock
+ item.safetyStock = safetyStock
+
+ return item
+ })
+ }
+ })
+ .catch(err => {
+ tableLoading.value = false
+ ElMessage.error(err.msg || '鑾峰彇鏁版嵁澶辫触')
+ })
+}
+
+// 鎼滅储
+const handleQuery = () => {
+ page.current = 1
+ getList()
+}
+
+// 閲嶇疆鎼滅储
+const resetQuery = () => {
+ Object.keys(searchForm).forEach(key => {
+ searchForm[key] = ''
+ })
+ handleQuery()
+}
+
+// 鍒嗛〉鍙樺寲
+const paginationChange = (obj) => {
+ page.current = obj.page
+ page.size = obj.limit
+ getList()
+}
+
+// 鑾峰彇搴撳瓨鏍峰紡绫�
+const getStockClass = (row) => {
+ const currentStock = parseFloat(row.currentStock || row.inboundNum0 || 0)
+ const warnNum = parseFloat(row.warnNum || 0)
+
+ if (currentStock <= 0) {
+ return 'text-danger'
+ } else if (currentStock < warnNum) {
+ return 'text-warning'
+ }
+ return 'text-success'
+}
+
+// 鑾峰彇棰勮绾у埆鏍囩鏍峰紡
+const getWarningLevelTag = (level) => {
+ const levelMap = {
+ '绱ф��': 'danger',
+ '閲嶈': 'warning',
+ '涓�鑸�': 'info'
+ }
+ return levelMap[level] || 'info'
+}
+
+// 鑾峰彇鍊掕鏃朵俊鎭�
+const getCountdown = (expectedTime) => {
+ if (!expectedTime) return { text: '-', isExpired: false }
+
+ const now = new Date().getTime()
+ const expected = new Date(expectedTime).getTime()
+ const diff = expected - now
+
+ if (diff <= 0) {
+ return { text: '宸茬己璐�', isExpired: true }
+ }
+
+ const days = Math.floor(diff / (1000 * 60 * 60 * 24))
+ const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
+ const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
+
+ if (days > 0) {
+ return { text: `${days}澶�${hours}灏忔椂`, isExpired: false }
+ } else if (hours > 0) {
+ return { text: `${hours}灏忔椂${minutes}鍒嗛挓`, isExpired: false }
+ } else {
+ return { text: `${minutes}鍒嗛挓`, isExpired: false }
+ }
+}
+
+// 鑾峰彇鍊掕鏃舵牱寮忕被
+const getCountdownClass = (expectedTime) => {
+ if (!expectedTime) return ''
+
+ const now = new Date().getTime()
+ const expected = new Date(expectedTime).getTime()
+ const diff = expected - now
+
+ if (diff <= 0) {
+ return 'countdown-expired'
+ } else if (diff <= 24 * 60 * 60 * 1000) { // 24灏忔椂鍐�
+ return 'countdown-urgent'
+ } else if (diff <= 7 * 24 * 60 * 60 * 1000) { // 7澶╁唴
+ return 'countdown-warning'
+ } else {
+ return 'countdown-normal'
+ }
+}
+
+// 椤甸潰鍔犺浇
+onMounted(() => {
+ getList()
+})
+</script>
+
+<style scoped lang="scss">
+.app-container {
+ padding: 20px;
+
+ .search_form {
+ background: #fff;
+ padding: 20px;
+ border-radius: 4px;
+ margin-bottom: 20px;
+ }
+
+ .table_list {
+ background: #fff;
+ border-radius: 4px;
+ padding: 20px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+ .actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ }
+ }
+
+ .text-danger {
+ color: #f56c6c;
+ font-weight: bold;
+ }
+
+ .text-warning {
+ color: #e6a23c;
+ font-weight: bold;
+ }
+
+ .text-success {
+ color: #67c23a;
+ font-weight: bold;
+ }
+
+ .countdown-timer {
+ font-weight: bold;
+ }
+
+ .countdown-normal {
+ color: #67c23a;
+ }
+
+ .countdown-warning {
+ color: #e6a23c;
+ }
+
+ .countdown-urgent {
+ color: #f56c6c;
+ animation: blink 1s infinite;
+ }
+
+ .countdown-expired {
+ color: #f56c6c;
+ font-weight: bold;
+ }
+
+ @keyframes blink {
+ 0%, 50% { opacity: 1; }
+ 51%, 100% { opacity: 0.5; }
+ }
+}
+</style>
diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue
index ee291a4..918be40 100644
--- a/src/views/monitor/job/index.vue
+++ b/src/views/monitor/job/index.vue
@@ -87,7 +87,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="浠诲姟缂栧彿" width="100" align="center" prop="jobId" />
<el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue
index b425e45..30ef218 100644
--- a/src/views/monitor/job/log.vue
+++ b/src/views/monitor/job/log.vue
@@ -96,7 +96,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="鏃ュ織缂栧彿" width="80" align="center" prop="jobLogId" />
<el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue
index aa42b52..bee51a1 100644
--- a/src/views/monitor/logininfor/index.vue
+++ b/src/views/monitor/logininfor/index.vue
@@ -93,7 +93,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table ref="logininforRef" v-loading="loading" :data="logininforList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
+ <el-table ref="logininforRef" v-loading="loading" :data="logininforList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" />
<el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue
index 21f6463..7a56ad5 100644
--- a/src/views/monitor/online/index.vue
+++ b/src/views/monitor/online/index.vue
@@ -28,6 +28,7 @@
v-loading="loading"
:data="onlineList.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
style="width: 100%;"
+ stripe
>
<el-table-column label="搴忓彿" width="50" type="index" align="center">
<template #default="scope">
diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue
index 92f9c35..edb57dd 100644
--- a/src/views/monitor/operlog/index.vue
+++ b/src/views/monitor/operlog/index.vue
@@ -107,7 +107,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table ref="operlogRef" v-loading="loading" :data="operlogList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
+ <el-table ref="operlogRef" v-loading="loading" :data="operlogList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange" stripe>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" />
<el-table-column label="绯荤粺妯″潡" align="center" prop="title" :show-overflow-tooltip="true" />
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
new file mode 100644
index 0000000..d993ee6
--- /dev/null
+++ b/src/views/personnelManagement/onboarding/index.vue
@@ -0,0 +1,348 @@
+<template>
+ <div class="app-container">
+ <div class="search_form">
+ <div>
+ <span class="search_title">濮撳悕锛�</span>
+ <el-input
+ v-model="searchForm.staffName"
+ style="width: 240px"
+ placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search"
+ />
+ <span style="margin-left: 10px;" class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
+ <el-date-picker
+ v-model="searchForm.entryDateStart"
+ type="date"
+ placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
+ size="default"
+ @change="(date) => handleDateChange(date,1)"
+ />
+ <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
+ <el-date-picker
+ v-model="searchForm.entryDateEnd"
+ type="date"
+ placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
+ size="default"
+ @change="(date) => handleDateChange(date,2)"
+ />
+ <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+ >鎼滅储</el-button
+ >
+ </div>
+ <div>
+ <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ :total="page.total"
+ ></PIMTable>
+ </div>
+ <form-dia ref="formDia" @close="handleQuery"></form-dia>
+ </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import {onMounted, ref} from "vue";
+import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
+import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {ElMessageBox} from "element-plus";
+import dayjs from "dayjs";
+
+const data = reactive({
+ searchForm: {
+ staffName: "",
+ },
+});
+const { searchForm } = toRefs(data);
+const tableColumn = ref([
+ {
+ label: "鐘舵��",
+ prop: "staffState",
+ dataType: "tag",
+ formatData: (params) => {
+ if (params == 0) {
+ return "绂昏亴";
+ } else if (params == 1) {
+ return "鍏ヨ亴";
+ } else {
+ return null;
+ }
+ },
+ formatType: (params) => {
+ if (params == 0) {
+ return "danger";
+ } else if (params == 1) {
+ return "primary";
+ } else {
+ return null;
+ }
+ },
+ },
+ {
+ label: "鍛樺伐缂栧彿",
+ prop: "staffNo",
+ },
+ {
+ label: "濮撳悕",
+ prop: "staffName",
+ },
+ {
+ label: "鎬у埆",
+ prop: "sex",
+ },
+ {
+ label: "绫嶈疮",
+ prop: "nativePlace",
+ },
+ {
+ label: "宀椾綅",
+ prop: "postJob",
+ },
+ {
+ label: "瀹跺涵浣忓潃",
+ prop: "adress",
+ width:200
+ },
+ {
+ label: "绗竴瀛﹀巻",
+ prop: "firstStudy",
+ },
+ {
+ label: "涓撲笟",
+ prop: "profession",
+ width:100
+ },
+ {
+ label: "韬唤璇佸彿",
+ prop: "identityCard",
+ width:200
+ },
+ {
+ label: "骞撮緞",
+ prop: "age",
+ },
+ {
+ label: "鑱旂郴鐢佃瘽",
+ prop: "phone",
+ width:150
+ },
+ {
+ label: "绱ф�ヨ仈绯讳汉",
+ prop: "emergencyContact",
+ width: 120
+ },
+ {
+ label: "鑱旂郴鐢佃瘽",
+ prop: "emergencyContactPhone",
+ width:150
+ },
+ {
+ label: "璇曠敤鏈燂紙鏈堬級",
+ prop: "probationPeriod",
+ width: 120,
+ },
+ // {
+ // label: "杞鏃ユ湡",
+ // prop: "probationEndDate",
+ // width: 120,
+ // formatData: (row) => {
+ // // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熻绠楄浆姝f棩鏈�
+ // if (row.contractStartTime && row.probationPeriod) {
+ // // 璁$畻杞鏃ユ湡锛堝悎鍚屽紑濮嬫棩鏈熷姞涓婅瘯鐢ㄦ湡鏈堟暟锛�
+ // return dayjs(row.contractStartTime).add(row.probationPeriod, 'month').format('YYYY-MM-DD');
+ // }
+ // return '';
+ // },
+ // formatType: (row) => {
+ // // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熸鏌ユ槸鍚︿复杩戣浆姝o紙7澶╁唴锛�
+ // if (row.contractStartTime && row.probationPeriod) {
+ // const probationEndDate = dayjs(row.contractStartTime).add(row.probationPeriod, 'month');
+ // const daysUntilProbationEnd = probationEndDate.diff(dayjs(), 'day');
+
+ // if (daysUntilProbationEnd >= 0 && daysUntilProbationEnd <= 7) {
+ // return 'warning'; // 浣跨敤璀﹀憡鏍峰紡鏍囪涓磋繎杞鐨勫憳宸�
+ // }
+ // }
+ // return '';
+ // }
+ // },
+ {
+ label: "鍚堝悓骞撮檺锛堝勾锛�",
+ prop: "contractTerm",
+ width: 120,
+ },
+ {
+ label: "鍚堝悓寮�濮嬫棩鏈�",
+ prop: "contractStartTime",
+ width: 120
+ },
+ {
+ label: "鍚堝悓缁撴潫鏃ユ湡",
+ prop: "contractEndTime",
+ width: 120
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: 'right',
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: (row) => {
+ openForm("edit", row);
+ },
+ },
+ ],
+ },
+]);
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+ current: 1,
+ size: 100,
+ total: 0,
+});
+const formDia = ref()
+const { proxy } = getCurrentInstance()
+
+const handleDateChange = (value,type) => {
+ searchForm.value.entryDateEnd = null
+ searchForm.value.entryDateStart = null
+ if(type === 1){
+ if (value) {
+ searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
+ }
+ }else{
+ if (value) {
+ searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
+ }
+ }
+ getList();
+};
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+ page.current = 1;
+ getList();
+};
+const pagination = (obj) => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
+const getList = () => {
+ tableLoading.value = true;
+ staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records
+ page.total = res.data.total;
+
+ // 妫�鏌ユ槸鍚︽湁涓磋繎杞鐨勫憳宸ュ苟鎻愰啋
+ checkProbationEnding(tableData.value);
+ }).catch(err => {
+ tableLoading.value = false;
+ })
+};
+// 妫�鏌ヤ复杩戣浆姝g殑鍛樺伐骞舵彁閱�
+const checkProbationEnding = (data) => {
+ const probationEndingSoon = [];
+
+ data.forEach(item => {
+ // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熸鏌�
+ if (item.contractStartTime && item.probationPeriod) {
+ const probationEndDate = dayjs(item.contractStartTime).add(item.probationPeriod, 'month');
+ const daysUntilProbationEnd = probationEndDate.diff(dayjs(), 'day');
+
+ if (daysUntilProbationEnd >= 0 && daysUntilProbationEnd <= 7) {
+ probationEndingSoon.push({
+ staffName: item.staffName,
+ probationEndDate: probationEndDate.format('YYYY-MM-DD'),
+ daysLeft: daysUntilProbationEnd
+ });
+ }
+ }
+ });
+
+ if (probationEndingSoon.length > 0) {
+ let message = '浠ヤ笅鍛樺伐灏嗗湪7澶╁唴杞锛歕n';
+ probationEndingSoon.forEach(item => {
+ message += `${item.staffName}锛�${item.probationEndDate}锛岃繕鏈�${item.daysLeft}澶╋級\n`;
+ });
+
+ // 鏄剧ず鎻愰啋娑堟伅
+ proxy.$modal.msgInfo(message);
+ }
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection;
+};
+
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+ nextTick(() => {
+ formDia.value?.openDialog(type, row)
+ })
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map((item) => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ staffJoinDel(ids).then((res) => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+// 瀵煎嚭
+const handleOut = () => {
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+onMounted(() => {
+ getList();
+});
+</script>
+
+<style scoped></style>
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
index 294561d..0d66ca4 100644
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ b/src/views/procurementManagement/paymentLedger/index.vue
@@ -29,6 +29,7 @@
height="calc(100vh - 18.5em)"
:highlight-current-row="true"
style="width: 100%"
+ stripe
tooltip-effect="dark"
@row-click="rowClick"
:show-summary="isShowSummary"
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue b/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
index f939be4..6290804 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
@@ -1,48 +1,48 @@
<template>
- <el-form :model="form">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細">
- <el-tag size="large">{{ form.purchaseContractNumber }}</el-tag>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�">
- <el-text>{{ form.salesContractNo }}</el-text>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚◣鍗曚环(鍏�)锛�">
- <el-text type="primary">{{ form.taxInclusiveUnitPrice }}</el-text>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍒涘缓鏃堕棿锛�">
- <el-text>{{ form.createdAt }}</el-text>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細">
- <el-input disabled v-model="form.invoiceNumber" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏉ョエ鏁帮細">
- <el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsNum" @change="inputTicketsNum" :precision="2"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈鏉ョエ閲戦(鍏�)锛�">
+ <el-form :model="form">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+ <el-tag size="large">{{ form.purchaseContractNumber }}</el-tag>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="閿�鍞悎鍚屽彿锛�">
+ <el-text>{{ form.salesContractNo }}</el-text>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍚◣鍗曚环(鍏�)锛�">
+ <el-text type="primary">{{ form.taxInclusiveUnitPrice }}</el-text>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿锛�">
+ <el-text>{{ form.createdAt }}</el-text>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍙戠エ鍙凤細">
+ <el-input v-model="form.invoiceNumber" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏉ョエ鏁帮細">
+ <el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsNum" @change="inputTicketsNum" :precision="2"/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈鏉ョエ閲戦(鍏�)锛�">
<el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsAmount" @change="inputTicketsAmount" :precision="2"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈潵绁ㄦ暟锛�">
- <el-text type="success">{{ form.futureTickets }}</el-text>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈潵绁ㄦ暟锛�">
+ <el-text type="success">{{ form.futureTickets }}</el-text>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
</template>
<script setup>
@@ -51,34 +51,43 @@
const { proxy } = getCurrentInstance()
defineOptions({
- name: "鏉ョエ鍙拌处琛ㄥ崟",
+ name: "鏉ョエ鍙拌处琛ㄥ崟",
});
-const temFutureTickets = ref(0)
+const temFutureTickets = ref(0) // 鍒濆鏈潵绁ㄦ暟
+const initialTicketsNum = ref(0) // 鍒濆鏉ョエ鏁�
+const initialTicketsAmount = ref(0) // 鍒濆鏉ョエ閲戦
+const quantity = ref(0) // 鎬绘暟閲�
const { form, resetForm } = useFormData({
- id: undefined,
- purchaseContractNumber: undefined, // 閲囪喘鍚堝悓鍙�
- salesContractNo: undefined, // 閿�鍞悎鍚屽彿
- createdAt: undefined, // 鍒涘缓鏃堕棿
- invoiceNumber: undefined, // 鍙戠エ鍙�
- ticketsNum: undefined, // 鏉ョエ鏁�
- ticketsAmount: undefined, // 鏉ョエ閲戦
+ id: undefined,
+ purchaseContractNumber: undefined, // 閲囪喘鍚堝悓鍙�
+ salesContractNo: undefined, // 閿�鍞悎鍚屽彿
+ createdAt: undefined, // 鍒涘缓鏃堕棿
+ invoiceNumber: undefined, // 鍙戠エ鍙�
+ ticketsNum: undefined, // 鏉ョエ鏁�
+ ticketsAmount: undefined, // 鏉ョエ閲戦
taxInclusiveUnitPrice: undefined, // 鍚◣鍗曚环
+ ticketRegistrationId: undefined, // 鍚◣鍗曚环
});
const load = async (id) => {
- const { code, data } = await getProductRecordById({ id });
- if (code === 200) {
- form.id = data.id;
- form.purchaseContractNumber = data.purchaseContractNumber;
- form.salesContractNo = data.salesContractNo;
- form.createdAt = data.createdAt;
- form.invoiceNumber = data.invoiceNumber;
- form.ticketsNum = data.ticketsNum;
- form.ticketsAmount = data.ticketsAmount.toFixed(2);
- form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice;
- form.futureTickets = data.futureTickets;
- temFutureTickets.value = data.futureTickets;
- }
+ const { code, data } = await getProductRecordById({ id });
+ if (code === 200) {
+ form.id = data.id;
+ form.purchaseContractNumber = data.purchaseContractNumber;
+ form.salesContractNo = data.salesContractNo;
+ form.createdAt = data.createdAt;
+ form.invoiceNumber = data.invoiceNumber;
+ form.ticketsNum = data.ticketsNum;
+ form.ticketsAmount = data.ticketsAmount ? Number(data.ticketsAmount).toFixed(2) : 0;
+ form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice;
+ form.futureTickets = data.futureTickets;
+ temFutureTickets.value = data.futureTickets;
+ initialTicketsNum.value = data.ticketsNum || 0;
+ initialTicketsAmount.value = data.ticketsAmount || 0;
+ form.ticketRegistrationId = data.ticketRegistrationId;
+ // 鑾峰彇鎬绘暟閲忥紝濡傛灉鏁版嵁涓湁 quantity 瀛楁鍒欎娇鐢紝鍚﹀垯浣跨敤鏉ョエ鏁�+鏈潵绁ㄦ暟
+ quantity.value = data.quantity || (Number(data.ticketsNum || 0) + Number(data.futureTickets || 0));
+ }
};
const inputTicketsNum = (val) => {
@@ -87,15 +96,44 @@
proxy.$modal.msgWarning("鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟");
return;
}
- if (Number(form.ticketsNum) > Number(temFutureTickets.value)) {
- proxy.$modal.msgWarning("寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
- form.ticketsNum = temFutureTickets.value
+
+ const newTicketsNum = Number(form.ticketsNum) || 0;
+ const currentTicketsNum = Number(initialTicketsNum.value) || 0;
+
+ // 璁$畻鏂板鐨勬潵绁ㄦ暟
+ const addedTicketsNum = newTicketsNum - currentTicketsNum;
+
+ // 璁$畻鏂扮殑鏈潵绁ㄦ暟 = 鍒濆鏈潵绁ㄦ暟 - 鏂板鐨勬潵绁ㄦ暟
+ const newFutureTickets = Number(temFutureTickets.value) - addedTicketsNum;
+
+ // 楠岃瘉锛氭柊鐨勬潵绁ㄦ暟 + 鏂扮殑鏈潵绁ㄦ暟 鈮� quantity
+ if (newTicketsNum + newFutureTickets > Number(quantity.value)) {
+ proxy.$modal.msgWarning(`鏉ョエ鏁�+鏈潵绁ㄦ暟涓嶈兘澶т簬鎬绘暟閲�(${quantity.value})`);
+ // 闄愬埗鏉ョエ鏁帮紝浣垮叾婊¤冻锛氭潵绁ㄦ暟 + 鏈潵绁ㄦ暟 鈮� quantity
+ // 鏈�澶ф潵绁ㄦ暟 = quantity - 鍒濆鏈潵绁ㄦ暟 + 鍒濆鏉ョエ鏁�
+ const maxTicketsNum = Number(quantity.value) - Number(temFutureTickets.value) + Number(initialTicketsNum.value);
+ form.ticketsNum = Math.max(0, Math.min(maxTicketsNum, newTicketsNum));
+ // 閲嶆柊璁$畻
+ const recalculatedAddedTicketsNum = Number(form.ticketsNum) - Number(initialTicketsNum.value);
+ const recalculatedFutureTickets = Number(temFutureTickets.value) - recalculatedAddedTicketsNum;
+ form.futureTickets = Number(recalculatedFutureTickets.toFixed(2));
+ const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
+ form.ticketsAmount = Number(ticketsAmount.toFixed(2));
+ return;
+ }
+
+ // 妫�鏌ユ柊澧炵殑鏉ョエ鏁版槸鍚﹀ぇ浜庡垵濮嬫湭鏉ョエ鏁�
+ if (addedTicketsNum > Number(temFutureTickets.value)) {
+ proxy.$modal.msgWarning("鏂板寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
+ form.ticketsNum = Number(initialTicketsNum.value) + Number(temFutureTickets.value);
}
// 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
- const futureTickets = Number(temFutureTickets.value) - Number(form.ticketsNum);
- form.futureTickets = Number(futureTickets.toFixed(2));
+ const finalTicketsNum = Number(form.ticketsNum) || 0;
+ const finalAddedTicketsNum = finalTicketsNum - Number(initialTicketsNum.value);
+ const finalFutureTickets = Number(temFutureTickets.value) - finalAddedTicketsNum;
+ const ticketsAmount = finalTicketsNum * Number(form.taxInclusiveUnitPrice);
+ form.futureTickets = Number(finalFutureTickets.toFixed(2));
form.ticketsAmount = Number(ticketsAmount.toFixed(2));
};
const inputTicketsAmount = (val) => {
@@ -105,23 +143,53 @@
return;
}
- if (Number(val) > Number(form.futureTickets*form.taxInclusiveUnitPrice)) {
- proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鎬婚噾棰�");
- form.ticketsAmount = (form.futureTickets*form.taxInclusiveUnitPrice).toFixed(2)
- const ticketsNum = Number(form.ticketsAmount) / Number(form.taxInclusiveUnitPrice);
- form.ticketsNum = Number(ticketsNum.toFixed(2))
+ const newTicketsAmount = Number(val) || 0;
+
+ // 璁$畻鏂扮殑鏉ョエ鏁�
+ const newTicketsNum = newTicketsAmount / Number(form.taxInclusiveUnitPrice);
+ const currentTicketsNum = Number(initialTicketsNum.value) || 0;
+
+ // 璁$畻鏂板鐨勬潵绁ㄦ暟
+ const addedTicketsNum = newTicketsNum - currentTicketsNum;
+
+ // 璁$畻鏂扮殑鏈潵绁ㄦ暟 = 鍒濆鏈潵绁ㄦ暟 - 鏂板鐨勬潵绁ㄦ暟
+ const newFutureTickets = Number(temFutureTickets.value) - addedTicketsNum;
+
+ // 楠岃瘉锛氭柊鐨勬潵绁ㄦ暟 + 鏂扮殑鏈潵绁ㄦ暟 鈮� quantity
+ if (newTicketsNum + newFutureTickets > Number(quantity.value)) {
+ proxy.$modal.msgWarning(`鏉ョエ鏁�+鏈潵绁ㄦ暟涓嶈兘澶т簬鎬绘暟閲�(${quantity.value})`);
+ // 闄愬埗鏉ョエ鏁帮紝浣垮叾婊¤冻锛氭潵绁ㄦ暟 + 鏈潵绁ㄦ暟 鈮� quantity
+ const maxTicketsNum = Number(quantity.value) - Number(temFutureTickets.value) + Number(initialTicketsNum.value);
+ form.ticketsNum = Math.max(0, Math.min(maxTicketsNum, newTicketsNum));
+ form.ticketsAmount = Number((form.ticketsNum * Number(form.taxInclusiveUnitPrice)).toFixed(2));
+ const recalculatedAddedTicketsNum = Number(form.ticketsNum) - Number(initialTicketsNum.value);
+ const recalculatedFutureTickets = Number(temFutureTickets.value) - recalculatedAddedTicketsNum;
+ form.futureTickets = Number(recalculatedFutureTickets.toFixed(2));
+ return;
+ }
+
+ // 妫�鏌ユ柊澧炵殑鏉ョエ閲戦鏄惁澶т簬鍒濆鏈潵绁ㄦ暟瀵瑰簲鐨勯噾棰�
+ const maxAddedAmount = Number(temFutureTickets.value * form.taxInclusiveUnitPrice);
+ if (addedTicketsNum > 0 && addedTicketsNum * Number(form.taxInclusiveUnitPrice) > maxAddedAmount) {
+ proxy.$modal.msgWarning("鏂板鏉ョエ閲戦涓嶅緱澶т簬鏈紑绁ㄩ噾棰�");
+ form.ticketsAmount = Number((initialTicketsAmount.value + maxAddedAmount).toFixed(2));
+ form.ticketsNum = Number((currentTicketsNum + Number(temFutureTickets.value)).toFixed(2));
+ form.futureTickets = 0;
return;
}
// 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsNum = Number(val) / Number(form.taxInclusiveUnitPrice);
- form.ticketsNum = Number(ticketsNum.toFixed(2));
+ const finalTicketsNum = Number(newTicketsNum.toFixed(2));
+ const finalAddedTicketsNum = finalTicketsNum - Number(initialTicketsNum.value);
+ const finalFutureTickets = Number(temFutureTickets.value) - finalAddedTicketsNum;
+ form.ticketsNum = finalTicketsNum;
+ form.futureTickets = Number(finalFutureTickets.toFixed(2));
};
defineExpose({
- load,
- form,
- resetForm,
+ load,
+ form,
+ resetForm,
});
</script>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue b/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
index 987e6a4..af38ab1 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
@@ -52,6 +52,7 @@
:summary-method="summarizeMainTable"
@expand-change="expandChange"
height="calc(100vh - 18.5em)"
+ stripe
>
<el-table-column align="center" label="搴忓彿" type="index" width="55" />
<el-table-column type="expand">
@@ -61,6 +62,7 @@
border
show-summary
:summary-method="summarizeChildrenTable"
+ stripe
>
<el-table-column
align="center"
diff --git a/src/views/productionManagement/operationScheduling/components/formDia.vue b/src/views/productionManagement/operationScheduling/components/formDia.vue
index 06b46ac..c443728 100644
--- a/src/views/productionManagement/operationScheduling/components/formDia.vue
+++ b/src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -156,7 +156,7 @@
unitFromRow.value = row?.unit ?? '';
idFromRow.value = row?.id ?? '';
specificationModelFromRow.value = row?.specificationModel ?? '';
-
+
userListNoPageByTenantId().then((res) => {
userList.value = res.data;
// 鎵惧埌瀛欏�╃殑鐢ㄦ埛ID骞惰缃负榛樿鍊�
@@ -248,4 +248,4 @@
<style scoped>
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue
index e7e6e15..a703c1c 100644
--- a/src/views/productionManagement/productionDispatching/components/formDia.vue
+++ b/src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -37,6 +37,9 @@
<el-input v-model="form.quantity" placeholder="璇疯緭鍏�" clearable disabled/>
</el-form-item>
</el-col>
+ </el-row>
+ <el-row :gutter="30">
+
<el-col :span="12">
<el-form-item label="寰呮帓浜ф暟閲忥細" prop="pendingQuantity">
<el-input v-model="form.pendingQuantity" placeholder="璇疯緭鍏�" clearable disabled/>
@@ -111,6 +114,7 @@
<script setup>
import {ref} from "vue";
+import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
import useUserStore from "@/store/modules/user.js";
@@ -131,6 +135,7 @@
schedulingDate: "",
pendingQuantity: "",
speculativeTradingName: "", // 缁戝畾鏈哄櫒鍚嶇О
+ salesLedgerProductId: "",
},
rules: {
schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
@@ -151,6 +156,10 @@
userList.value = res.data;
});
form.value = {...row}
+ // 缁戝畾澶栧眰浼犲叆鐨勪骇鍝両D鍒板悗绔渶瑕佺殑 salesLedgerProductId 瀛楁
+ form.value.salesLedgerProductId = row.id;
+ // 纭繚涓嶄細鎶婂師濮� id 褰撲綔鎺掍骇璁板綍涓婚敭浼犵粰鍚庣
+ delete form.value.id;
form.value.schedulingNum = 0
form.value.schedulingUserId = userStore.id
form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
@@ -188,4 +197,4 @@
<style scoped>
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index 6b543e7..6817bfd 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -197,7 +197,7 @@
prop: "unit",
width: 120,
},
-
+
{
label: "鍒涘缓鏃堕棿",
prop: "createTime",
diff --git a/src/views/productionManagement/safetyMonitoring/index.vue b/src/views/productionManagement/safetyMonitoring/index.vue
index 12922e7..30e19d6 100644
--- a/src/views/productionManagement/safetyMonitoring/index.vue
+++ b/src/views/productionManagement/safetyMonitoring/index.vue
@@ -173,7 +173,7 @@
:visible.sync="emergencyRecordsVisible"
width="800px"
>
- <el-table :data="emergencyRecords" style="width: 100%">
+ <el-table :data="emergencyRecords" style="width: 100%" stripe>
<el-table-column prop="time" label="鏃堕棿" width="180"></el-table-column>
<el-table-column prop="location" label="浣嶇疆" width="150"></el-table-column>
<el-table-column prop="type" label="绫诲瀷" width="120"></el-table-column>
@@ -211,7 +211,7 @@
<div class="sensor-data-section">
<h4>浼犳劅鍣ㄦ暟鎹�</h4>
- <el-table :data="currentEvent.sensorData" style="width: 100%">
+ <el-table :data="currentEvent.sensorData" style="width: 100%" stripe>
<el-table-column prop="sensor" label="浼犳劅鍣�"></el-table-column>
<el-table-column prop="methane" label="鐢茬兎娴撳害"></el-table-column>
<el-table-column prop="h2s" label="纭寲姘㈡祿搴�"></el-table-column>
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
index eec3a26..85d0cba 100644
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ b/src/views/salesManagement/invoiceLedger/index.vue
@@ -27,7 +27,7 @@
</div>
<div class="table_list">
<el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
- :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+ :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)" stripe>
<el-table-column align="center" type="selection" width="55" />
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
<el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip width="180" />
@@ -294,8 +294,8 @@
// 涓婁紶鍓嶆牎妫�
function handleBeforeUpload(file) {
// 鏍℃鏂囦欢澶у皬
- if (file.size > 1024 * 1024 * 10) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+ if (file.size > 1024 * 1024 * 50) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃50MB!");
return false;
}
// 鍒ゆ柇鏂囦欢鏍煎紡鏄惁绗﹀悎
diff --git a/src/views/salesManagement/receiptPaymentHistory/index.vue b/src/views/salesManagement/receiptPaymentHistory/index.vue
index f66bed7..8a53adf 100644
--- a/src/views/salesManagement/receiptPaymentHistory/index.vue
+++ b/src/views/salesManagement/receiptPaymentHistory/index.vue
@@ -101,19 +101,6 @@
{
label: "鍥炴鏂瑰紡",
prop: "receiptPaymentType",
- dataType: "tag",
- formatData: (params) => {
- if (params == 0) {
- return "鐢垫眹";
- } else if (params == 1) {
- return "鎵垮厬";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- return "info";
- },
},
{
label: "鐧昏浜�",
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index 7029cfc..ffeaee5 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -27,6 +27,7 @@
:summary-method="summarizeMainTable"
@row-click="rowClickMethod"
height="calc(100vh - 18.5em)"
+ stripe
>
<el-table-column
align="center"
@@ -81,6 +82,7 @@
:data="receiptRecord"
border
:row-key="(row) => row.id"
+ stripe
show-summary
:summary-method="summarizeMainTable1"
height="calc(100vh - 18.5em)"
diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue
index da37db2..e9e3b87 100644
--- a/src/views/salesManagement/salesLedger/fileList.vue
+++ b/src/views/salesManagement/salesLedger/fileList.vue
@@ -1,6 +1,6 @@
<template>
<el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
- <el-table :data="tableData" border height="40vh">
+ <el-table :data="tableData" border height="40vh" stripe>
<el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
<el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
<template #default="scope">
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 54114f1..59beb90 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -41,11 +41,11 @@
</div>
<el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
:expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
- :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
+ :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)" stripe>
<el-table-column align="center" type="selection" width="55" />
<el-table-column type="expand">
<template #default="props">
- <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
+ <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable" stripe>
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
<el-table-column label="浜у搧澶х被" prop="productCategory" />
<el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
@@ -98,6 +98,14 @@
<el-table-column label="浠樻鏂瑰紡" prop="paymentMethod" show-overflow-tooltip />
<el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="220" show-overflow-tooltip
:formatter="formattedNumber" />
+ <el-table-column label="宸插紑绁ㄩ噾棰�(鍏�)" prop="invoiceTotal" width="220" show-overflow-tooltip
+ :formatter="formattedNumber" />
+ <el-table-column label="鏈紑绁ㄩ噾棰�(鍏�)" prop="noInvoiceAmountTotal" width="220" show-overflow-tooltip
+ :formatter="formattedNumber" />
+ <el-table-column label="鍥炴閲戦(鍏�)" prop="receiptPaymentAmountTotal" width="220" show-overflow-tooltip
+ :formatter="formattedNumber" />
+ <el-table-column label="寰呭洖娆鹃噾棰�(鍏�)" prop="noReceiptAmount" width="220" show-overflow-tooltip
+ :formatter="formattedNumber" />
<el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
<el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
<el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
@@ -124,10 +132,12 @@
</el-col>
<el-col :span="12">
<el-form-item label="涓氬姟鍛橈細" prop="salesman">
- <el-select v-model="form.salesman" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
- <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
- :value="item.nickName" />
- </el-select>
+ <el-input
+ v-model="form.salesman"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
@@ -190,7 +200,7 @@
<el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >鍒犻櫎</el-button>
</el-form-item>
</el-row>
- <el-table :data="productData" border @selection-change="productSelected" show-summary
+ <el-table :data="productData" border @selection-change="productSelected" show-summary stripe
:summary-method="summarizeMainTable">
<el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" />
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
@@ -874,6 +884,10 @@
"contractAmount",
"taxInclusiveTotalPrice",
"taxExclusiveTotalPrice",
+ 'invoiceTotal',
+ 'noInvoiceAmountTotal',
+ 'receiptPaymentAmountTotal',
+ 'noReceiptAmount',
]);
};
// 瀛愯〃鍚堣鏂规硶
diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue
index 77d9f5a..9dd220d 100644
--- a/src/views/system/config/index.vue
+++ b/src/views/system/config/index.vue
@@ -96,7 +96,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="鍙傛暟涓婚敭" align="center" prop="configId" />
<el-table-column label="鍙傛暟鍚嶇О" align="center" prop="configName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue
index f4e2c6f..23ca2a9 100644
--- a/src/views/system/dict/data.vue
+++ b/src/views/system/dict/data.vue
@@ -86,7 +86,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" />
<el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel">
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
index 6c67e1b..98ac047 100644
--- a/src/views/system/dict/index.vue
+++ b/src/views/system/dict/index.vue
@@ -101,7 +101,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="瀛楀吀缂栧彿" align="center" prop="dictId" />
<el-table-column label="瀛楀吀鍚嶇О" align="center" prop="dictName" :show-overflow-tooltip="true"/>
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index bccb9e9..2257fb0 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -51,6 +51,7 @@
v-if="refreshTable"
v-loading="loading"
:data="menuList"
+ stripe
row-key="menuId"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue
index 8043db0..76ddd05 100644
--- a/src/views/system/notice/index.vue
+++ b/src/views/system/notice/index.vue
@@ -68,7 +68,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" />
<el-table-column
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
index 0e80652..39f807f 100644
--- a/src/views/system/post/index.vue
+++ b/src/views/system/post/index.vue
@@ -77,7 +77,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" />
<el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" />
diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue
index a460f3c..86243db 100644
--- a/src/views/system/role/authUser.vue
+++ b/src/views/system/role/authUser.vue
@@ -57,7 +57,7 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
- <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index d960674..a32ab4a 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -92,7 +92,7 @@
</el-row>
<!-- 琛ㄦ牸鏁版嵁 -->
- <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
+ <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" />
<el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" />
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index 3e3d8aa..193c9a5 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -26,7 +26,7 @@
</el-form-item>
</el-form>
<el-row>
- <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px">
+ <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px" stripe>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue
index 3935ab1..85a6f1b 100644
--- a/src/views/system/user/authRole.vue
+++ b/src/views/system/user/authRole.vue
@@ -17,7 +17,7 @@
</el-form>
<h4 class="form-header h4">瑙掕壊淇℃伅</h4>
- <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="roleRef" @selection-change="handleSelectionChange" :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)">
+ <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="roleRef" @selection-change="handleSelectionChange" :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)" stripe>
<el-table-column label="搴忓彿" width="55" type="index" align="center">
<template #default="scope">
<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
diff --git a/src/views/tideLogin.vue b/src/views/tideLogin.vue
index e4a82f7..c9ae3d4 100644
--- a/src/views/tideLogin.vue
+++ b/src/views/tideLogin.vue
@@ -1,15 +1,23 @@
<template>
<div></div>
</template>
-<script setup>
+<script>
import useUserStore from '@/store/modules/user'
-const userStore = useUserStore()
-let { proxy } = getCurrentInstance()
-function goLogin() {
- userStore.TideLogin({code : proxy.$route.query.code}).then(() => {
- proxy.$router.push({ path: redirect || "/" }).catch(() => { });
- })
+export default {
+ data() {
+ return {}
+ },
+ created() {
+ this.goLogin()
+ },
+ computed: {},
+ methods: {
+ goLogin() {
+ useUserStore().TideLogin({code : this.$route.query.code}).then(() => {
+ this.$router.push({ path: this.redirect || "/" }).catch(() => { });
+ })
+ }
+ }
}
-goLogin()
</script>
<style scoped></style>
diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue
index 874fc94..59aa03d 100644
--- a/src/views/tool/gen/editTable.vue
+++ b/src/views/tool/gen/editTable.vue
@@ -5,7 +5,7 @@
<basic-info-form ref="basicInfo" :info="info" />
</el-tab-pane>
<el-tab-pane label="瀛楁淇℃伅" name="columnInfo">
- <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
+ <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight" stripe>
<el-table-column label="搴忓彿" type="index" min-width="5%"/>
<el-table-column
label="瀛楁鍒楀悕"
diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue
index 23dbf28..ea2ebef 100644
--- a/src/views/tool/gen/importTable.vue
+++ b/src/views/tool/gen/importTable.vue
@@ -26,7 +26,7 @@
</el-form-item>
</el-form>
<el-row>
- <el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
+ <el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px" stripe>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="tableName" label="琛ㄥ悕绉�" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="tableComment" label="琛ㄦ弿杩�" :show-overflow-tooltip="true"></el-table-column>
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
index aaddeb6..4930cef 100644
--- a/src/views/tool/gen/index.vue
+++ b/src/views/tool/gen/index.vue
@@ -106,6 +106,7 @@
ref="genRef"
v-loading="loading"
:data="tableList"
+ stripe
@selection-change="handleSelectionChange"
:default-sort="defaultSort"
@sort-change="handleSortChange"
diff --git a/vite.config.js b/vite.config.js
index dc687a8..37bb1df 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -7,17 +7,11 @@
const env = loadEnv(mode, process.cwd());
const { VITE_APP_ENV } = env;
const baseUrl =
- env.VITE_APP_ENV === "development"
- ? "http://1.15.17.182:9003"
- : env.VITE_BASE_API;
- const javaUrl =
- env.VITE_APP_ENV === "development"
- ? "http://1.15.17.182:9002"
- : env.VITE_JAVA_API;
+ VITE_APP_ENV == "development"
+ ? "http://114.132.189.42:8089" // 寮�鍙戠幆澧冨悗绔帴鍙�
+ : "http://114.132.189.42:7003"; // 鐢熶骇鐜鍚庣鎺ュ彛
+
return {
- define:{
- __BASE_API__: JSON.stringify(javaUrl)
- },
// 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�
// 榛樿鎯呭喌涓嬶紝vite 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂
// 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆�
--
Gitblit v1.9.3