From 30dc46174a37613366081bd1abab8eb71c171f7f Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期五, 16 一月 2026 16:17:46 +0800
Subject: [PATCH] 浪潮对接单点登录:MES制造执行系统功能迁移
---
src/views/index.vue | 246 +-
src/views/productionManagement/operationScheduling/components/formDia.vue | 151
src/views/productionManagement/productionCosting/index.vue | 266 +-
src/api/productionManagement/productionOrder.js | 55
src/views/productionManagement/productionDispatching/components/formDia.vue | 130
src/views/productionManagement/productionDispatching/index.vue | 286 +--
src/views/productionManagement/operationScheduling/index.vue | 402 ++--
src/router/index.js | 40
/dev/null | 1587 -------------------
src/views/productionManagement/productionReporting/index.vue | 686 ++++----
src/views/reportAnalysis/reportManagement/index.vue | 401 +---
src/views/productionManagement/productionOrder/index.vue | 505 ++++-
.env.production | 2
vite.config.js | 12
src/views/productionManagement/productionReporting/components/formDia.vue | 88
15 files changed, 1,557 insertions(+), 3,300 deletions(-)
diff --git a/.env.production b/.env.production
index eee707f..34de4c8 100644
--- a/.env.production
+++ b/.env.production
@@ -1,5 +1,5 @@
# 椤甸潰鏍囬
-VITE_APP_TITLE = 涓皬浼佷笟鏁板瓧鍖栬浆鍨嬩簩绾у椁愬寘
+VITE_APP_TITLE = 鑺-MES鍒堕�犳墽琛岀郴缁�
# 鐢熶骇鐜閰嶇疆
VITE_APP_ENV = 'production'
diff --git a/src/api/collaborativeApproval/approvalProcess.js b/src/api/collaborativeApproval/approvalProcess.js
deleted file mode 100644
index 415bed8..0000000
--- a/src/api/collaborativeApproval/approvalProcess.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// 鍗忓悓瀹℃壒
-import request from "@/utils/request";
-
-export function approveProcessListPage(query) {
- return request({
- url: '/approveProcess/list',
- method: 'get',
- params: query,
- })
-}
-export function getDept(query) {
- return request({
- url: '/approveProcess/getDept',
- method: 'get',
- params: query,
- })
-}
-export function approveProcessGetInfo(query) {
- return request({
- url: '/approveProcess/get',
- method: 'get',
- params: query,
- })
-}
-// 鏂板瀹℃壒娴佺▼
-export function approveProcessAdd(query) {
- return request({
- url: '/approveProcess/add',
- method: 'post',
- data: query,
- })
-}
-// 淇敼瀹℃壒娴佺▼
-export function approveProcessUpdate(query) {
- return request({
- url: '/approveProcess/update',
- method: 'post',
- data: query,
- })
-}
-// 鎻愪氦瀹℃壒
-export function updateApproveNode(query) {
- return request({
- url: '/approveNode/updateApproveNode',
- method: 'post',
- data: query,
- })
-}
-// 鍒犻櫎瀹℃壒娴佺▼
-export function approveProcessDelete(query) {
- return request({
- url: '/approveProcess/deleteIds',
- method: 'delete',
- data: query,
- })
-}
-// 鏌ヨ瀹℃壒娴佺▼
-export function approveProcessDetails(query) {
- return request({
- url: '/approveNode/details/' + query,
- method: 'get',
- })
-}
\ No newline at end of file
diff --git a/src/api/collaborativeApproval/attendanceManagement.js b/src/api/collaborativeApproval/attendanceManagement.js
deleted file mode 100644
index 3c99775..0000000
--- a/src/api/collaborativeApproval/attendanceManagement.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍋囨湡璁剧疆鍒楄〃
-export function listHolidaySettings(query) {
- return request({
- url: "/holidaySettings/getList",
- method: "get",
- params: query,
- });
-}
-//鏌ヨ骞村亣瑙勫垯鍒楄〃
-export function listAnnualLeaveSettingList(query) {
- return request({
- url: "/holidaySettings/getAnnualLeaveSettingList",
- method: "get",
- params: query,
- });
-}
-//鏌ヨ鍔犵彮瑙勫垯鍒楄〃
-export function listOvertimeSettingList(query) {
- return request({
- url: "/holidaySettings/getOvertimeSettingList",
- method: "get",
- params: query,
- });
-}
-//鏌ヨ宸ヤ綔鏃堕棿瑙勫垯鍒楄〃
-export function listWorkingHoursSettingList(query) {
- return request({
- url: "/holidaySettings/getWorkingHoursSettingList",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板鍋囨湡璁剧疆
-export function addHolidaySettings(data) {
- return request({
- url: "/holidaySettings/add",
- method: "post",
- data: data,
- });
-}
-//鏂板骞村亣瑙勫垯
-export function addAnnualLeaveSetting(data) {
- return request({
- url: "/holidaySettings/addAnnualLeaveSetting",
- method: "post",
- data: data,
- });
-}
-//鏂板鍔犵彮瑙勫垯
-export function addOvertimeSetting(data) {
- return request({
- url: "/holidaySettings/addOvertimeSetting",
- method: "post",
- data: data,
- });
-}
-//鏂板宸ヤ綔鏃堕棿瑙勫垯
-export function addWorkingHoursSetting(data) {
- return request({
- url: "/holidaySettings/addWorkingHoursSetting",
- method: "post",
- data: data,
- });
-}
-
-
-// 淇敼鍋囨湡璁剧疆
-export function updateHolidaySettings(data) {
- return request({
- url: "/holidaySettings/update",
- method: "post",
- data: data,
- });
-}
-// 淇敼骞村亣瑙勫垯
-export function updateAnnualLeaveSetting(data) {
- return request({
- url: "/holidaySettings/updateAnnualLeaveSetting",
- method: "post",
- data: data,
- });
-}
-// 淇敼鍔犵彮瑙勫垯
-export function updateOvertimeSetting(data) {
- return request({
- url: "/holidaySettings/updateOvertimeSetting",
- method: "post",
- data: data,
- });
-}
-// 淇敼宸ヤ綔鏃堕棿瑙勫垯
-export function updateWorkingHoursSetting(data) {
- return request({
- url: "/holidaySettings/updateWorkingHoursSetting",
- method: "post",
- data: data,
- });
-}
-
-// 鎵归噺鍒犻櫎鍋囨湡璁剧疆
-export function delHolidaySettings(query) {
- return request({
- url: "/holidaySettings/delete",
- method: "delete",
- data: query,
- });
-}
-// 鎵归噺鍒犻櫎骞村亣瑙勫垯
-export function delAnnualLeaveSetting(query) {
- return request({
- url: "/holidaySettings/deleteAnnualLeaveSetting",
- method: "delete",
- data: query,
- });
-}
-// 鎵归噺鍒犻櫎鍔犵彮瑙勫垯
-export function delOvertimeSetting(query) {
- return request({
- url: "/holidaySettings/deleteOvertimeSetting",
- method: "delete",
- data: query,
- });
-}
-// 鎵归噺鍒犻櫎宸ヤ綔鏃堕棿瑙勫垯
-export function delWorkingHoursSetting(query) {
- return request({
- url: "/holidaySettings/deleteWorkingHoursSetting",
- method: "delete",
- data: query,
- });
-}
-
-
diff --git a/src/api/collaborativeApproval/enterpriseBook.js b/src/api/collaborativeApproval/enterpriseBook.js
deleted file mode 100644
index 2140b89..0000000
--- a/src/api/collaborativeApproval/enterpriseBook.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ涓汉閫氳褰�
-// 涓汉閫氳褰曢�氬父鏄敤鎴锋敹钘忔垨棰戠箒鑱旂郴鐨勪汉鍛�
-export function getPersonalContacts(page,query) {
- return request({
- url: '/staffContactsPersonal/getList',
- method: 'get',
- params: {
- ...page,
- ...query
- }
- })
-}
-
-// 娣诲姞鑱旂郴浜哄埌涓汉閫氳褰�
-export function addPersonalContact(data) {
- return request({
- url: '/staffContactsPersonal/add',
- method: 'post',
- data: data
- })
-}
-
-// 浠庝釜浜洪�氳褰曠Щ闄よ仈绯讳汉
-export function removePersonalContact(id) {
- return request({
- url: '/staffContactsPersonal/delete/' + id,
- method: 'delete'
- })
-}
-
-// 鏌ヨ鍏叡閫氳褰�
-// 鍏叡閫氳褰曢�氬父鏄墍鏈夊憳宸ュ彲瑙佺殑鑱旂郴鏂瑰紡
-export function getPublicContacts(query) {
- return request({
- url: '/staff/contacts/public/list',
- method: 'get',
- params: query
- })
-}
-
-// 鏌ヨ鍗曚綅閫氳褰�
-// 鍗曚綅閫氳褰曢�氬父鎸夐儴闂ㄧ粍缁囩殑鍛樺伐鑱旂郴鏂瑰紡
-export function getCompanyContacts(query) {
- return request({
- url: '/staff/contacts/company/list',
- method: 'get',
- params: query
- })
-}
-
-// 鏌ヨ閮ㄩ棬閫氳褰曟爲缁撴瀯
-export function getDepartmentTree() {
- return request({
- url: '/staff/contacts/department/tree',
- method: 'get'
- })
-}
-
-// 鑾峰彇鍛樺伐璇︾粏淇℃伅
-export function getEmployeeDetail(employeeId) {
- return request({
- url: '/staff/staffOnJob/' + employeeId,
- method: 'get'
- })
-}
\ No newline at end of file
diff --git a/src/api/collaborativeApproval/knowledgeBase.js b/src/api/collaborativeApproval/knowledgeBase.js
deleted file mode 100644
index b195525..0000000
--- a/src/api/collaborativeApproval/knowledgeBase.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鐭ヨ瘑搴撳垪琛�
-export function listKnowledgeBase(query) {
- return request({
- url: "/knowledgeBase/getList",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ鐭ヨ瘑搴撹缁�
-// export function getKnowledgeBase(knowledgeBaseId) {
-// return request({
-// url: "/collaborativeApproval/knowledgeBase/" + knowledgeBaseId,
-// method: "get",
-// });
-// }
-
-// 鏂板鐭ヨ瘑搴�
-export function addKnowledgeBase(data) {
- return request({
- url: "/knowledgeBase/add",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼鐭ヨ瘑搴�
-export function updateKnowledgeBase(data) {
- return request({
- url: "/knowledgeBase/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎鐭ヨ瘑搴�
-export function delKnowledgeBase(query) {
- return request({
- url: "/knowledgeBase/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 鎵归噺鍒犻櫎鐭ヨ瘑搴�
-export function delKnowledgeBaseBatch(knowledgeBaseIds) {
- return request({
- url: "/knowledgeBase/batch",
- method: "delete",
- data: knowledgeBaseIds,
- });
-}
-
diff --git a/src/api/collaborativeApproval/meeting.js b/src/api/collaborativeApproval/meeting.js
deleted file mode 100644
index 20df8b1..0000000
--- a/src/api/collaborativeApproval/meeting.js
+++ /dev/null
@@ -1,118 +0,0 @@
-import request from "@/utils/request";
-
-export function getMeetingRoomList(data) {
- return request({
- url: "/meeting/roomList",
- method: "post",
- data: data,
- });
-}
-
-export function saveRoom(data) {
- return request({
- url: "/meeting/saveRoom",
- method: "post",
- data: data,
- });
-}
-
-export function delRoom(id) {
- return request({
- url: "/meeting/delRoom/"+id,
- method: "delete",
- });
-}
-
-export function getRoomEnum() {
- return request({
- url: "/meeting/roomEnum",
- method: "get",
- });
-}
-
-export function getDraftList(data){
- return request({
- url: "/meeting/draftList",
- method: "post",
- data: data,
- });
-}
-
-export function saveDraft(data) {
- return request({
- url: "/meeting/saveDraft",
- method: "post",
- data: data,
- });
-}
-
-export function delDraft(id) {
- return request({
- url: "/meeting/delDraft/"+id,
- method: "delete",
- });
-}
-
-export function saveMeetingApplication(data){
- return request({
- url: "/meeting/saveMeetingApplication",
- method: "post",
- data: data,
- });
-}
-
-export function getExamineList(data) {
- return request({
- url: "/meeting/applicationList",
- method: "post",
- data: data,
- });
-}
-
-
-export function getMeetingUseList(data){
- return request({
- url: "/meeting/meetingUseList",
- method: "post",
- data: data,
- });
-}
-
-export function getMeetingPublish(data){
- return request({
- url: "/meeting/meetingPublishList",
- method: "post",
- data: data
- });
-}
-
-
-export function getMeetingMinutesByMeetingId(id){
- return request({
- url: "/meeting/getMeetingMinutesByMeetingId/"+id,
- method: "get",
- });
-}
-
-export function saveMeetingMinutes(data){
- return request({
- url: "/meeting/saveMeetingMinutes",
- method: "post",
- data: data,
- });
-}
-
-
-export function getMeetSummary(){
- return request({
- url: "/meeting/getMeetSummary",
- method: "get",
- });
-}
-
-export function getMeetSummaryItems(){
- return request({
- url: "/meeting/getMeetSummaryItems",
- method: "get",
- });
-}
diff --git a/src/api/collaborativeApproval/noticeManagement.js b/src/api/collaborativeApproval/noticeManagement.js
deleted file mode 100644
index 0f4e8b3..0000000
--- a/src/api/collaborativeApproval/noticeManagement.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ鍏憡鍒楄〃
-export function listNotice(query) {
- return request({
- url: '/collaborativeApproval/notice/page',
- method: 'get',
- params: query
- })
-}
-
-// 鏌ヨ鍏憡璇︾粏
-export function getNotice(noticeId) {
- return request({
- url: '/collaborativeApproval/notice/' + noticeId,
- method: 'get'
- })
-}
-
-// 鏂板鍏憡
-export function addNotice(data) {
- return request({
- url: '/collaborativeApproval/notice/add',
- method: 'post',
- data: data
- })
-}
-
-// 淇敼鍏憡
-export function updateNotice(data) {
- return request({
- url: '/collaborativeApproval/notice/update',
- method: 'put',
- data: data
- })
-}
-
-// 鍒犻櫎鍏憡
-export function delNotice(ids) {
- return request({
- url: '/collaborativeApproval/notice/' + ids,
- method: 'delete',
- })
-}
-
-// 鑾峰彇鍏憡鏁伴噺
-export function getCount() {
- return request({
- url: '/collaborativeApproval/notice/count',
- method: 'get',
- })
-}
diff --git a/src/api/collaborativeApproval/notificationManagement.js b/src/api/collaborativeApproval/notificationManagement.js
deleted file mode 100644
index abaeaa4..0000000
--- a/src/api/collaborativeApproval/notificationManagement.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ閫氱煡鍒楄〃
-export function listNotification(query) {
- return request({
- url: "/notificationManagement/getList",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板閫氱煡
-export function addNotification(data) {
- return request({
- url: "/notificationManagement/add",
- method: "post",
- data: data,
- });
-}
-//鏂板浼氳
-export function addOnlineMeeting(data) {
- return request({
- url: "/notificationManagement/addOnlineMeeting",
- method: "post",
- data: data,
- });
-}
-//鏂板鏂囦欢鍏变韩
-export function addFileSharing(data) {
- return request({
- url: "/notificationManagement/addFileSharing",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼閫氱煡
-export function updateNotification(data) {
- return request({
- url: "/notificationManagement/update",
- method: "post",
- data: data,
- });
-}
-
-// 鎵归噺鍒犻櫎閫氱煡
-export function delNotification(query) {
- return request({
- url: "/notificationManagement/delete",
- method: "delete",
- data: query,
- });
-}
-
-// // 鎵归噺鍒犻櫎鐭ヨ瘑搴�
-// export function delKnowledgeBaseBatch(knowledgeBaseIds) {
-// return request({
-// url: "/knowledgeBase/batch",
-// method: "delete",
-// data: knowledgeBaseIds,
-// });
-// }
-
diff --git a/src/api/collaborativeApproval/officeSupplies.js b/src/api/collaborativeApproval/officeSupplies.js
deleted file mode 100644
index 340293b..0000000
--- a/src/api/collaborativeApproval/officeSupplies.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ鍔炲叕鐗╄祫鍒楄〃
-export function listPage(query) {
- return request({
- url: '/officeSupplies/listPage',
- method: 'get',
- params: query
- })
-}
-
-// 鏂板鍔炲叕鐗╄祫
-export function add(data) {
- return request({
- url: '/officeSupplies/add',
- method: 'post',
- data
- })
-}
-
-// 淇敼鍔炲叕鐗╄祫
-export function update(data) {
- return request({
- url: '/officeSupplies/update',
- method: 'post',
- data
- })
-}
-
-// 鍒犻櫎鍔炲叕鐗╄祫
-export function deleteOff(data) {
- return request({
- url: '/officeSupplies/delete',
- method: 'delete',
- data
- })
-}
diff --git a/src/api/collaborativeApproval/planTemplate.js b/src/api/collaborativeApproval/planTemplate.js
deleted file mode 100644
index 24a6ac4..0000000
--- a/src/api/collaborativeApproval/planTemplate.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ璁″垝鍒楄〃
-export function listDutyPlan(query) {
- return request({
- url: "/dutyPlan/getList",
- method: "get",
- params: query
- });
-}
-//鏁版嵁
-export function NumDutyPlan(query) {
- return request({
- url: "/dutyPlan/getNum",
- method: "get",
- params: query
- });
-}
-
-// 鏂板璁″垝
-export function addDutyPlan(data) {
- return request({
- url: "/dutyPlan/add",
- method: "post",
- data: data,
- });
-}
-
-
-// 淇敼璁″垝
-export function updateDutyPlan(data) {
- return request({
- url: "/dutyPlan/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎璁″垝
-export function delDutyPlan(query) {
- return request({
- url: "/dutyPlan/delete",
- method: "delete",
- data: query,
- });
-}
-// 瀵煎嚭璁″垝
-export function exportDutyPlan(query) {
- return request({
- url: "/dutyPlan/export",
- method: "post",
- params: query,
- });
-}
-
-// // 鎵归噺鍒犻櫎璁″垝
-// export function delDutyPlanBatch(dutyPlanIds) {
-// return request({
-// url: "/dutyPlan/batch",
-// method: "delete",
-// data: dutyPlanIds,
-// });
-// }
-
diff --git a/src/api/collaborativeApproval/rpaManagement.js b/src/api/collaborativeApproval/rpaManagement.js
deleted file mode 100644
index 273bf9f..0000000
--- a/src/api/collaborativeApproval/rpaManagement.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨRPA鍒楄〃
-export function listRpa(query) {
- return request({
- url: "/rpaProcessAutomation/getList",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨRPA璇︾粏
-export function getRpa(rpaId) {
- return request({
- url: "/collaborativeApproval/rpa/" + rpaId,
- method: "get",
- });
-}
-
-// 鏂板RPA
-export function addRpa(data) {
- return request({
- url: "/rpaProcessAutomation/add",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼RPA
-export function updateRpa(data) {
- return request({
- url: "/rpaProcessAutomation/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎RPA
-export function delRpa(query) {
- return request({
- url: "/rpaProcessAutomation/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 鎵归噺鍒犻櫎RPA
-export function delRpaBatch(rpaIds) {
- return request({
- url: "/collaborativeApproval/rpa/batch",
- method: "delete",
- data: rpaIds,
- });
-}
-
-// 鍚姩RPA
-export function startRpa(rpaId) {
- return request({
- url: "/collaborativeApproval/rpa/start/" + rpaId,
- method: "post",
- });
-}
-
-// 鍋滄RPA
-export function stopRpa(rpaId) {
- return request({
- url: "/collaborativeApproval/rpa/stop/" + rpaId,
- method: "post",
- });
-}
-
-// 鑾峰彇RPA鐘舵��
-export function getRpaStatus(rpaId) {
- return request({
- url: "/collaborativeApproval/rpa/status/" + rpaId,
- method: "get",
- });
-}
diff --git a/src/api/collaborativeApproval/sealManagement.js b/src/api/collaborativeApproval/sealManagement.js
deleted file mode 100644
index cb990b3..0000000
--- a/src/api/collaborativeApproval/sealManagement.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍗扮珷鐢宠鍒楄〃
-export function listSealApplication(page,query) {
- return request({
- url: "/sealApplicationManagement/getList",
- method: "get",
- params: {
- ...page,
- ...query},
- });
-}
-// 鏌ヨ瑙勭珷鍒跺害鍒楄〃
-export function listRuleManagement(page,query) {
- return request({
- url: "/rulesRegulationsManagement/getList",
- method: "get",
- params: {
- ...page,
- ...query},
- });
-}
-// 鏌ヨ闃呰鐘舵�佸垪琛�
-export function getReadingStatusList(page,query) {
- return request({
- url: "/rulesRegulationsManagement/getReadingStatusList",
- method: "get",
- params: {
- ...page,
- ...query},
- });
-}
-// 鏍规嵁瑙勫垯id鏌ヨ闃呰鐘舵�佸垪琛�
-export function getReadingStatusByRuleId(id) {
- return request({
- url: "/rulesRegulationsManagement/getReadingStatusByRuleId/"+id,
- method: "get"
- });
-}
-
-// 鏂板鍗扮珷鐢宠
-export function addSealApplication(data) {
- return request({
- url: "/sealApplicationManagement/add",
- method: "post",
- data: data,
- });
-}
-// 鏂板瑙勭珷鍒跺害
-export function addRuleManagement(data) {
- return request({
- url: "/rulesRegulationsManagement/add",
- method: "post",
- data: data,
- });
-}
-// 鏂板闃呰鐘舵��
-export function addReadingStatus(data) {
- return request({
- url: "/rulesRegulationsManagement/addReadingStatus",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼鍗扮珷鐢宠
-export function updateSealApplication(data) {
- return request({
- url: "/sealApplicationManagement/update",
- method: "post",
- data: data,
- });
-}
-// 淇敼瑙勭珷鍒跺害
-export function updateRuleManagement(data) {
- return request({
- url: "/rulesRegulationsManagement/update",
- method: "post",
- data: data,
- });
-}
-// 淇敼闃呰鐘舵��
-export function updateReadingStatus(data) {
- return request({
- url: "/rulesRegulationsManagement/updateReadingStatus",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎鍗扮珷鐢宠
-export function delSealApplication(query) {
- return request({
- url: "/sealApplicationManagement/delete",
- method: "delete",
- data: query,
- });
-}
-// 鍒犻櫎瑙勭珷鍒跺害
-export function delRuleManagement(query) {
- return request({
- url: "/rulesRegulationsManagement/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 鎵归噺鍒犻櫎鐭ヨ瘑搴�
-export function delKnowledgeBaseBatch(knowledgeBaseIds) {
- return request({
- url: "/knowledgeBase/batch",
- method: "delete",
- data: knowledgeBaseIds,
- });
-}
-
diff --git a/src/api/customerService/index.js b/src/api/customerService/index.js
deleted file mode 100644
index b92033b..0000000
--- a/src/api/customerService/index.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// 鍞悗鏈嶅姟
-import request from "@/utils/request";
-
-// 鍙嶉鐧昏-鍒嗛〉鏌ヨ
-export function afterSalesServiceListPage(query) {
- return request({
- url: '/afterSalesService/listPage',
- method: 'get',
- params: query,
- })
-}
-// 鍙嶉鐧昏-鍒犻櫎
-export function afterSalesServiceDelete(query) {
- return request({
- url: '/afterSalesService/delete',
- method: 'delete',
- data: query,
- })
-}
-// 鍙嶉鐧昏-鍒犻櫎
-export function afterSalesServiceAdd(query) {
- return request({
- url: '/afterSalesService/add',
- method: 'post',
- data: query,
- })
-}
-// 鍙嶉鐧昏-鍒犻櫎
-export function afterSalesServiceUpdate(query) {
- return request({
- url: '/afterSalesService/update',
- method: 'post',
- data: query,
- })
-}
-// 鍙嶉鐧昏-鎻愪氦澶勭悊
-export function afterSalesServiceDispose(query) {
- return request({
- url: '/afterSalesService/dispose',
- method: 'post',
- data: query,
- })
-}
-
-// 涓存湡鍞悗绠$悊-鍒嗛〉鏌ヨ
-export function expiryAfterSalesListPage(query) {
- return request({
- url: '/expiryAfterSales/listPage',
- method: 'get',
- params: query,
- })
-}
-
-// 涓存湡鍞悗绠$悊-鏂板
-export function expiryAfterSalesAdd(query) {
- return request({
- url: '/expiryAfterSales/add',
- method: 'post',
- data: query,
- })
-}
-
-// 涓存湡鍞悗绠$悊-鏇存柊
-export function expiryAfterSalesUpdate(query) {
- return request({
- url: '/expiryAfterSales/update',
- method: 'post',
- data: query,
- })
-}
-
-// 涓存湡鍞悗绠$悊-鍒犻櫎
-export function expiryAfterSalesDelete(query) {
- return request({
- url: '/expiryAfterSales/delete',
- method: 'delete',
- data: query,
- })
-}
\ No newline at end of file
diff --git a/src/api/energyManagement/index.js b/src/api/energyManagement/index.js
deleted file mode 100644
index f2c5494..0000000
--- a/src/api/energyManagement/index.js
+++ /dev/null
@@ -1,127 +0,0 @@
-// 鑳芥簮绠$悊
-import request from "@/utils/request";
-
-// 璁惧鑳借��-鍒嗛〉鏌ヨ
-export function equipmentEnergyListPage(query) {
- return request({
- url: "/equipmentEnergyConsumption/listPage",
- method: "get",
- params: query,
- });
-}
-// -鑳芥簮瓒嬪娍-鍒嗛〉鏌ヨ
-export function listPageByTrend(query) {
- return request({
- url: "/equipmentEnergyConsumption/listPageByTrend",
- method: "get",
- params: query,
- });
-}
-// 鍖哄煙-鍒嗛〉鏌ヨ
-export function areaListPage(query) {
- return request({
- url: "/electricityConsumptionArea/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 鍖哄煙-鏍�
-export function areaListTree(query) {
- return request({
- url: "/electricityConsumptionArea/list",
- method: "get",
- params: query,
- });
-}
-// 鏃堕棿鍛ㄦ湡-鍒嗛〉鏌ヨ
-export function periodListPage(query) {
- return request({
- url: "/energyPeriod/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 璁惧鑳借��-鍒犻櫎
-export function equipmentEnergyDelete(query) {
- return request({
- url: "/equipmentEnergyConsumption/delete",
- method: "delete",
- data: query,
- });
-}
-// 鍖哄煙-鍒犻櫎
-export function areaDelete(query) {
- return request({
- url: "/electricityConsumptionArea/delete",
- method: "delete",
- data: query,
- });
-}
-// 鏃堕棿鍛ㄦ湡-鍒犻櫎
-export function periodDelete(query) {
- return request({
- url: "/energyPeriod/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 璁惧鑳借��-鏂板
-export function equipmentEnergyAdd(query) {
- return request({
- url: "/equipmentEnergyConsumption/add",
- method: "post",
- data: query,
- });
-}
-// 鍖哄煙-鏂板
-export function areaAdd(query) {
- return request({
- url: "/electricityConsumptionArea/add",
- method: "post",
- data: query,
- });
-}
-
-// 鏃堕棿鍛ㄦ湡-鏂板
-export function periodAdd(query) {
- return request({
- url: "/energyPeriod/add",
- method: "post",
- data: query,
- });
-}
-// 璁惧鑳借��-淇敼
-export function equipmentEnergyUpdate(query) {
- return request({
- url: "/equipmentEnergyConsumption/update",
- method: "post",
- data: query,
- });
-}
-//鍖哄煙-淇敼
-export function areaUpdate(query) {
- return request({
- url: "/electricityConsumptionArea/update",
- method: "post",
- data: query,
- });
-}
-// 鏃堕棿鍛ㄦ湡-淇敼
-export function periodUpdate(query) {
- return request({
- url: "/energyPeriod/update",
- method: "post",
- data: query,
- });
-}
-
-// 璁惧涓嬫媺妗嗘煡璇�
-export function deviceList(query) {
- return request({
- url: "/equipmentEnergyConsumption/deviceList",
- method: "get",
- });
-}
diff --git a/src/api/energyManagement/waterManagement.js b/src/api/energyManagement/waterManagement.js
deleted file mode 100644
index 6dbf115..0000000
--- a/src/api/energyManagement/waterManagement.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// 鐢ㄦ按绠$悊
-import request from "@/utils/request";
-
-// 鐢ㄦ按璁惧-鍒嗛〉鏌ヨ
-export function waterEquipmentListPage(query) {
- return request({
- url: '/waterRecord/listPage',
- method: 'get',
- params: query,
- })
-}
-
-// 鐢ㄦ按瓒嬪娍-鍒嗛〉鏌ヨ
-export function listPageByWaterTrend(query) {
- return request({
- url: '/waterRecord/listPageByTrend',
- method: 'get',
- params: query,
- })
-}
-
-// 鐢ㄦ按璁惧-鍒犻櫎
-export function waterEquipmentDelete(query) {
- return request({
- url: '/waterRecord/delete',
- method: 'delete',
- data: query,
- })
-}
-
-// 鐢ㄦ按璁惧-鏂板
-export function waterEquipmentAdd(query) {
- return request({
- url: '/waterRecord/add',
- method: 'post',
- data: query,
- })
-}
-
-// 鐢ㄦ按璁惧-淇敼
-export function waterEquipmentUpdate(query) {
- return request({
- url: '/waterRecord/update',
- method: 'post',
- data: query,
- })
-}
-
-// 鐢ㄦ按璁惧涓嬫媺妗嗘煡璇�
-export function waterDeviceList(query) {
- return request({
- url: '/device/ledger/page',
- method: 'get',
- params: query,
- })
-}
-
-// 姘磋垂绠$悊-鍒嗛〉鏌ヨ
-export function waterBillListPage(query) {
- return request({
- url: '/waterBill/listPage',
- method: 'get',
- params: query,
- })
-}
-
-// 姘磋垂绠$悊-鏂板
-export function waterBillAdd(query) {
- return request({
- url: '/waterBill/add',
- method: 'post',
- data: query,
- })
-}
-
-// 姘磋垂绠$悊-淇敼
-export function waterBillUpdate(query) {
- return request({
- url: '/waterBill/update',
- method: 'post',
- data: query,
- })
-}
-
-// 姘磋垂绠$悊-鍒犻櫎
-export function waterBillDelete(query) {
- return request({
- url: '/waterBill/delete',
- method: 'delete',
- data: query,
- })
-}
-
diff --git a/src/api/equipmentManagement/brand.js b/src/api/equipmentManagement/brand.js
deleted file mode 100644
index 040cb38..0000000
--- a/src/api/equipmentManagement/brand.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// 璁惧鍝佺墝绠$悊 - 鏈湴鍋囨暟鎹� API锛堜娇鐢� localStorage 鎸佷箙鍖栵級
-
-const STORAGE_KEY = 'EQUIPMENT_BRANDS';
-
-function readStore() {
- try {
- const raw = localStorage.getItem(STORAGE_KEY);
- if (raw) {
- const parsed = JSON.parse(raw);
- if (Array.isArray(parsed)) return parsed;
- }
- } catch (e) {
- // ignore
- }
- // 鍒濆鍖栦竴浜涚ず渚嬫暟鎹�
- const initial = [
- { id: 1, name: '瑗块棬瀛�', country: '寰峰浗', description: '宸ヤ笟鑷姩鍖栦笌鐢垫皵宸ョ▼鍝佺墝', createdAt: Date.now() - 86400000 * 10 },
- { id: 2, name: '鏂借�愬痉', country: '娉曞浗', description: '鑳芥簮绠$悊涓庤嚜鍔ㄥ寲', createdAt: Date.now() - 86400000 * 7 },
- { id: 3, name: '涓夎彵鐢垫満', country: '鏃ユ湰', description: '鐢垫皵涓庤嚜鍔ㄥ寲璁惧', createdAt: Date.now() - 86400000 * 3 },
- ];
- localStorage.setItem(STORAGE_KEY, JSON.stringify(initial));
- return initial;
-}
-
-function writeStore(list) {
- localStorage.setItem(STORAGE_KEY, JSON.stringify(list));
-}
-
-function nextId(list) {
- const maxId = list.reduce((max, item) => Math.max(max, Number(item.id) || 0), 0);
- return maxId + 1;
-}
-
-export function getBrandPage(params = {}) {
- const { current = 1, size = 10, name } = params;
- const list = readStore();
- let filtered = list;
- if (name) {
- const kw = String(name).trim();
- filtered = filtered.filter((b) =>
- (b.name && b.name.includes(kw)) || (b.country && b.country.includes(kw))
- );
- }
- const start = (current - 1) * size;
- const end = start + Number(size);
- const records = filtered.slice(start, end);
- return Promise.resolve({
- code: 200,
- data: {
- total: filtered.length,
- records,
- },
- msg: 'ok',
- });
-}
-
-export function getBrandById(id) {
- const list = readStore();
- const item = list.find((i) => String(i.id) === String(id));
- return Promise.resolve({ code: 200, data: item || null, msg: 'ok' });
-}
-
-export function addBrand(data) {
- const list = readStore();
- const item = { ...data };
- item.id = nextId(list);
- item.createdAt = Date.now();
- list.unshift(item);
- writeStore(list);
- return Promise.resolve({ code: 200, data: item, msg: '鏂板鎴愬姛' });
-}
-
-export function editBrand(data) {
- const list = readStore();
- const index = list.findIndex((i) => String(i.id) === String(data.id));
- if (index !== -1) {
- list[index] = { ...list[index], ...data };
- writeStore(list);
- return Promise.resolve({ code: 200, data: list[index], msg: '淇敼鎴愬姛' });
- }
- return Promise.resolve({ code: 404, data: null, msg: '鏈壘鍒拌鍝佺墝' });
-}
-
-export function delBrand(idOrIds) {
- const list = readStore();
- const ids = Array.isArray(idOrIds) ? idOrIds.map(String) : [String(idOrIds)];
- const newList = list.filter((i) => !ids.includes(String(i.id)));
- writeStore(newList);
- return Promise.resolve({ code: 200, data: null, msg: '鍒犻櫎鎴愬姛' });
-}
-
-
-
diff --git a/src/api/equipmentManagement/calibration.js b/src/api/equipmentManagement/calibration.js
deleted file mode 100644
index 54b99f9..0000000
--- a/src/api/equipmentManagement/calibration.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// 妫�瀹氭牎鍑嗚褰�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function ledgerRecordListPage(query) {
- return request({
- url: "/measuringInstrumentLedgerRecord/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏍″噯
-export function ledgerRecordVerifying(query) {
- return request({
- url: "/measuringInstrumentLedger/verifying",
- method: "post",
- data: query,
- });
-}
-// 淇敼鏍″噯
-export function ledgerRecordUpdate(query) {
- return request({
- url: "/measuringInstrumentLedgerRecord/update",
- method: "post",
- data: query,
- });
-}
\ No newline at end of file
diff --git a/src/api/equipmentManagement/defectManagement.js b/src/api/equipmentManagement/defectManagement.js
deleted file mode 100644
index c52eff9..0000000
--- a/src/api/equipmentManagement/defectManagement.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import request from '@/utils/request';
-
-// 鐧昏缂洪櫡
-export function registerDefect(data) {
- return request({
- url: '/defect/add',
- method: 'post',
- data
- });
-}
-
-// 鑾峰彇缂洪櫡鍒楄〃
-export function getDefectList() {
- return request({
- url: '/defect/page',
- method: 'get'
- });
-}
-
-// 娑堥櫎缂洪櫡-淇敼鐘舵��
-export function eliminateDefect(data) {
- return request({
- url: '/defect/update',
- method: 'post',
- data
- });
-}
-//鍒犻櫎
-export function deleteDefect(id) {
- return request({
- url: '/defect/delete',
- method: 'delete',
- id
- });
-}
-
-
-// 鑾峰彇缂洪櫡璁惧鍙拌处
-export function getDefectLedger(deviceLedgerId) {
- return request({
- url: '/defect//find/' + deviceLedgerId,
- method: 'get'
- });
-}
\ No newline at end of file
diff --git a/src/api/equipmentManagement/deviceInfo.js b/src/api/equipmentManagement/deviceInfo.js
deleted file mode 100644
index d71b713..0000000
--- a/src/api/equipmentManagement/deviceInfo.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import request from "@/utils/request";
-
-// 鑾峰彇璁惧鍩烘湰淇℃伅
-export function getDeviceInfo(params) {
- return request({
- url: "/device/ledger/scanDevice",
- method: "get",
- params,
- });
-}
diff --git a/src/api/equipmentManagement/ledger.js b/src/api/equipmentManagement/ledger.js
deleted file mode 100644
index d1b65b0..0000000
--- a/src/api/equipmentManagement/ledger.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import request from "@/utils/request";
-
-export const getLedgerPage = (params) => {
- return request({
- url: "/device/ledger/page",
- method: "get",
- params,
- });
-};
-export const getLedgerById = (id) => {
- return request({
- url: `/device/ledger/${id}`,
- method: "get",
- });
-};
-
-export const addLedger = (data) => {
- return request({
- url: "/device/ledger",
- method: "post",
- data,
- });
-};
-export const editLedger = (data) => {
- return request({
- url: "/device/ledger",
- method: "put",
- data,
- });
-};
-
-export const delLedger = (id) => {
- return request({
- url: `/device/ledger/${id}`,
- method: "delete",
- });
-};
-
-export const getDeviceLedger = () => {
- return request({
- url: "/device/ledger/getDeviceLedger",
- method: "get",
- });
-};
diff --git a/src/api/equipmentManagement/measurementEquipment.js b/src/api/equipmentManagement/measurementEquipment.js
deleted file mode 100644
index a22c034..0000000
--- a/src/api/equipmentManagement/measurementEquipment.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// 璁¢噺鍣ㄥ叿鍙拌处
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function measuringInstrumentListPage(query) {
- return request({
- url: "/measuringInstrumentLedger/listPage",
- method: "get",
- params: query,
- });
-}
-// 鍒犻櫎
-export function measuringInstrumentDelete(query) {
- return request({
- url: "/measuringInstrumentLedger/delete",
- method: "delete",
- data: query,
- });
-}
-// 鏂板
-export function measuringInstrumentAdd(query) {
- return request({
- url: "/measuringInstrumentLedger/add",
- method: "post",
- data: query,
- });
-}
-// 淇敼
-export function measuringInstrumentUpdate(query) {
- return request({
- url: "/measuringInstrumentLedger/update",
- method: "post",
- data: query,
- });
-}
\ No newline at end of file
diff --git a/src/api/equipmentManagement/repair.js b/src/api/equipmentManagement/repair.js
deleted file mode 100644
index 0233ae6..0000000
--- a/src/api/equipmentManagement/repair.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import request from "@/utils/request";
-
-/**
- * @desc 璁惧鎶ヤ慨鍒楄〃
- * @param {鍒嗛〉鏌ヨ} params
- * @returns
- */
-export const getRepairPage = (params) => {
- return request({
- url: "/device/repair/page",
- method: "get",
- params,
- });
-};
-
-/**
- * @desc 鏂板鎶ヤ慨
- * @param {鎶ヤ慨鍙傛暟} data
- * @returns
- */
-export const addRepair = (data) => {
- return request({
- url: "/device/repair",
- method: "post",
- data,
- });
-};
-
-/**
- * @desc 缂栬緫鎶ヤ慨
- * @param {鎶ヤ慨鍙傛暟} data
- * @returns
- */
-export const editRepair = (data) => {
- return request({
- url: "/device/repair",
- method: "put",
- data,
- });
-};
-
-/**
- * @desc 鏍规嵁id鏌ヨ涓�鏉℃姤淇�
- * @param {鎶ヤ慨id} id
- * @returns
- */
-export const getRepairById = (id) => {
- return request({
- url: `/device/repair/${id}`,
- method: "get",
- });
-};
-
-/**
- * @desc 鍒犻櫎鎶ヤ慨
- * @param {缂栧彿} ids
- * @returns
- */
-export const delRepair = (ids) => {
- return request({
- url: `/device/repair/${ids}`,
- method: "delete",
- });
-};
-
-export const addMaintain = (data) => {
- return request({
- url: `/device/repair/repair`,
- method: "post",
- data,
- });
-};
diff --git a/src/api/equipmentManagement/spareParts.js b/src/api/equipmentManagement/spareParts.js
deleted file mode 100644
index 2b64689..0000000
--- a/src/api/equipmentManagement/spareParts.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import request from "@/utils/request";
-/**
- * 澶囦欢鍒嗙被-鏍戝垪琛�
- */
-export const getSparePartsTree = (params) => {
- return request({
- url: "/spareParts/getTree",
- method: "get",
- params,
- });
-};
-/**
- * 澶囦欢鍒嗙被-鍒嗛〉鏌ヨ鍒楄〃
- */
-export const getSparePartsList = (params) => {
- return request({
- url: "/spareParts/listPage",
- method: "get",
- params,
- });
-};
-
-/**
- * @desc 鏂板
- */
-export const addSparePart = (data) => {
- return request({
- url: "/spareParts/add",
- method: "post",
- data,
- });
-};
-
-/**
- * @desc 缂栬緫
- */
-export const editSparePart = (data) => {
- return request({
- url: "/spareParts/update",
- method: "post",
- data,
- });
-};
-
-/**
- * @desc 鍒犻櫎鎶ヤ慨
- * @param {缂栧彿} ids
- * @returns
- */
-export const delSparePart = (id) => {
- return request({
- url: '/spareParts/delete/'+id,
- method: "delete",
-
- });
-};
-
-
diff --git a/src/api/equipmentManagement/upkeep.js b/src/api/equipmentManagement/upkeep.js
deleted file mode 100644
index c091670..0000000
--- a/src/api/equipmentManagement/upkeep.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import request from "@/utils/request";
-
-/**
- * @desc 璁惧淇濆吇鍒楄〃鍒嗛〉鏌ヨ
- * @param {鍒嗛〉鏌ヨ鍏ュ弬} params
- * @returns
- */
-export const getUpkeepPage = (params) => {
- return request({
- url: "/device/maintenance/page",
- method: "get",
- params,
- });
-};
-
-/**
- * @desc 璁惧淇濆吇璇︽儏
- * @param {淇濆吇浣嗙紪鍙穧 id
- * @returns
- */
-export const getUpkeepById = (id) => {
- return request({
- url: `/device/maintenance/${id}`,
- method: "get",
- });
-};
-
-/**
- * @desc 璁惧淇濆吇鏂板
- * @param {鏂板淇濆吇琛ㄥ崟} data
- * @returns
- */
-export const addUpkeep = (data) => {
- return request({
- url: "/device/maintenance",
- method: "post",
- data,
- });
-};
-
-/**
- * @desc 璁惧淇濆吇缂栬緫
- * @param {缂栬緫淇濆吇琛ㄥ崟} data
- * @returns
- */
-export const editUpkeep = (data) => {
- return request({
- url: "/device/maintenance",
- method: "put",
- data,
- });
-};
-
-/**
- * @desc 鏂板淇濆吇琛ㄥ崟
- * @param {鏂板淇濆吇琛ㄥ崟} data
- * @returns
- */
-export const addMaintenance = (data) => {
- return request({
- url: "/device/maintenance/maintenance",
- method: "post",
- data,
- });
-};
-
-export const delUpkeep = (id) => {
- return request({
- url: `/device/maintenance/${id}`,
- method: "delete",
- });
-};
diff --git a/src/api/fileManagement/bookshelf.js b/src/api/fileManagement/bookshelf.js
deleted file mode 100644
index 0a4a748..0000000
--- a/src/api/fileManagement/bookshelf.js
+++ /dev/null
@@ -1,128 +0,0 @@
-import request from "@/utils/request";
-
-/**
- * 涔︽灦绠$悊鐩稿叧API鎺ュ彛
- * 鍖呭惈浠撳簱绠$悊銆佽揣鏋剁鐞嗐�佸浘涔︾鐞嗙瓑鍔熻兘鐨勬帴鍙�
- */
-
-/**
- * 鑾峰彇浠撳簱鍒楄〃
- * @description 鑾峰彇鎵�鏈変粨搴撶殑鍩烘湰淇℃伅鍒楄〃
- * @returns {Promise} 杩斿洖浠撳簱鍒楄〃鏁版嵁
- */
-export function getWarehouseList() {
- return request({
- url: "/warehouse/tree",
- method: "get",
- });
-}
-
-/**
- * 鏂板浠撳簱
- * @description 鍒涘缓鏂扮殑浠撳簱璁板綍
- * @param {Object} data 浠撳簱淇℃伅瀵硅薄锛屽寘鍚粨搴撳悕绉扮瓑瀛楁
- * @returns {Promise} 杩斿洖鏂板缁撴灉
- */
-export function addWarehouse(data) {
- return request({
- url: "/warehouse/add",
- method: "post",
- data,
- });
-}
-
-/**
- * 鏇存柊浠撳簱淇℃伅
- * @description 淇敼鐜版湁浠撳簱鐨勫熀鏈俊鎭�
- * @param {Object} data 浠撳簱淇℃伅瀵硅薄锛屽繀椤诲寘鍚粨搴揑D
- * @returns {Promise} 杩斿洖鏇存柊缁撴灉
- */
-export function updateWarehouse(data) {
- return request({
- url: "/warehouse/update",
- method: "put",
- data,
- });
-}
-
-/**
- * 鍒犻櫎浠撳簱
- * @description 鏍规嵁浠撳簱ID鍒犻櫎鎸囧畾鐨勪粨搴撹褰�
- * @param {string|number} id 浠撳簱ID
- * @returns {Promise} 杩斿洖鍒犻櫎缁撴灉
- */
-export function deleteWarehouse(data) {
- return request({
- url: `/warehouse/delete/`,
- method: "delete",
- data,
- });
-}
-
-/**
- * 鑾峰彇璐ф灦鍒楄〃
- * @description 鏍规嵁浠撳簱ID鑾峰彇璇ヤ粨搴撲笅鐨勬墍鏈夎揣鏋朵俊鎭�
- * @param {string|number} warehouseId 浠撳簱ID
- * @returns {Promise} 杩斿洖璐ф灦鍒楄〃鏁版嵁
- */
-export function getShelfList(warehouseId) {
- return request({
- url: `/shelf/list/${warehouseId}`,
- method: "get",
- });
-}
-
-/**
- * 鏂板璐ф灦
- * @description 鍦ㄦ寚瀹氫粨搴撲笅鍒涘缓鏂扮殑璐ф灦璁板綍
- * @param {Object} data 璐ф灦淇℃伅瀵硅薄锛屽寘鍚揣鏋跺悕绉般�佸眰鏁般�佸垪鏁扮瓑瀛楁
- * @returns {Promise} 杩斿洖鏂板缁撴灉
- */
-export function addShelf(data) {
- return request({
- url: "/warehouse/goodsShelves/add",
- method: "post",
- data,
- });
-}
-
-/**
- * 鏇存柊璐ф灦淇℃伅
- * @description 淇敼鐜版湁璐ф灦鐨勫熀鏈俊鎭�
- * @param {Object} data 璐ф灦淇℃伅瀵硅薄锛屽繀椤诲寘鍚揣鏋禝D
- * @returns {Promise} 杩斿洖鏇存柊缁撴灉
- */
-export function updateShelf(data) {
- return request({
- url: "/warehouse/goodsShelves/update",
- method: "put",
- data,
- });
-}
-
-/**
- * 鍒犻櫎璐ф灦
- * @description 鏍规嵁璐ф灦ID鍒犻櫎鎸囧畾鐨勮揣鏋惰褰�
- * @param {string|number} id 璐ф灦ID
- * @returns {Promise} 杩斿洖鍒犻櫎缁撴灉
- */
-export function deleteShelf(id) {
- return request({
- url: `/warehouse/goodsShelves/delete/${id}`,
- method: "delete",
- });
-}
-
-/**
- * 鑾峰彇浠撳簱缁撴瀯
- * @description 鑾峰彇鎸囧畾浠撳簱鐨勫畬鏁寸粨鏋勪俊鎭紝鍖呮嫭璐ф灦銆佸眰鏁般�佸垪鏁扮瓑
- * @param {string|number} warehouseId 浠撳簱ID
- * @returns {Promise} 杩斿洖浠撳簱鐨勫畬鏁寸粨鏋勬暟鎹�
- */
-export function getWarehouseStructure(data) {
- return request({
- url: `/warehouse/goodsShelvesRowcol/list`,
- method: "get",
- params: data,
- });
-}
diff --git a/src/api/fileManagement/borrow.js b/src/api/fileManagement/borrow.js
deleted file mode 100644
index 1f4c72c..0000000
--- a/src/api/fileManagement/borrow.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import request from "@/utils/request";
-
-// 鏂囨。鍊熼槄绠$悊鐩稿叧鎺ュ彛
-
-// 鑾峰彇鏂囨。鍒楄〃锛堢敤浜庡�熼槄涔︾睄閫夋嫨锛�
-export function getDocumentList() {
- return request({
- url: "/documentation/list",
- method: "get",
- });
-}
-
-// 鍊熼槄鍒嗛〉鏌ヨ
-export function getBorrowList(params) {
- return request({
- url: "/documentationBorrowManagement/listPage",
- method: "get",
- params: params,
- });
-}
-
-// 鏂板鍊熼槄
-export function addBorrow(data) {
- return request({
- url: "/documentationBorrowManagement/add",
- method: "post",
- data: data,
- });
-}
-
-// 鏇存柊鍊熼槄
-export function updateBorrow(data) {
- return request({
- url: "/documentationBorrowManagement/update",
- method: "put",
- data: data,
- });
-}
-
-// 鍒犻櫎鍊熼槄
-export function deleteBorrow(ids) {
- return request({
- url: "/documentationBorrowManagement/delete",
- method: "delete",
- data: ids,
- });
-}
diff --git a/src/api/fileManagement/document.js b/src/api/fileManagement/document.js
deleted file mode 100644
index f3d5f4f..0000000
--- a/src/api/fileManagement/document.js
+++ /dev/null
@@ -1,189 +0,0 @@
-import request from "@/utils/request";
-
-// 鑾峰彇鍒嗙被鏍�
-export function getCategoryTree() {
- return request({
- url: "/warehouse/documentClassification/getList",
- method: "get",
- });
-}
-
-// 鏂板鍒嗙被
-export function addCategory(data) {
- return request({
- url: "/warehouse/documentClassification/add",
- method: "post",
- data: {
- category: data.category,
- parentId: data.parentId,
- },
- });
-}
-
-// 淇敼鍒嗙被
-export function updateCategory(data) {
- return request({
- url: "/warehouse/documentClassification/update",
- method: "put",
- data: {
- id: data.id,
- category: data.category,
- },
- });
-}
-
-// 鍒犻櫎鍒嗙被
-export function deleteCategory(ids) {
- return request({
- url: "/warehouse/documentClassification/delete",
- method: "delete",
- data: ids,
- });
-}
-
-// 鑾峰彇鏂囨。鍒楄〃锛堝垎椤碉級
-export function getDocumentList(query) {
- return request({
- url: "/documentation/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板鏂囨。
-export function addDocument(data) {
- return request({
- url: "/documentation/add",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼鏂囨。
-export function updateDocument(data) {
- return request({
- url: "/documentation/update",
- method: "put",
- data: data,
- });
-}
-
-// 鍒犻櫎鏂囨。
-export function deleteDocument(ids) {
- return request({
- url: "/documentation/delete",
- method: "delete",
- data: ids,
- });
-}
-
-// 鑾峰彇鏂囨。璇︽儏
-export function getDocumentDetail(id) {
- return request({
- url: "/document/" + id,
- method: "get",
- });
-}
-
-// 鎼滅储鏂囨。
-export function searchDocument(query) {
- return request({
- url: "/document/search",
- method: "get",
- params: query,
- });
-}
-
-// 鑾峰彇浠撳簱缁撴瀯
-export function getWarehouseStructure() {
- return request({
- url: "/document/warehouse/structure",
- method: "get",
- });
-}
-
-// 闄勪欢绠$悊鐩稿叧鎺ュ彛
-// 娣诲姞闄勪欢
-export function addDocumentationFile(data) {
- return request({
- url: "/documentation/documentationFile/add",
- method: "post",
- data: data,
- });
-}
-
-// 鑾峰彇闄勪欢鍒楄〃
-export function getDocumentationFileList(params) {
- return request({
- url: "/documentation/documentationFile/listPage",
- method: "get",
- params: params,
- });
-}
-
-// 鍒犻櫎闄勪欢
-export function deleteDocumentationFile(ids) {
- return request({
- url: "/documentation/documentationFile/del",
- method: "delete",
- data: ids,
- });
-}
-
-// 鏂囨。鍊熼槄绠$悊鐩稿叧鎺ュ彛
-export function getBorrowList(params) {
- return request({
- url: "/documentationBorrowManagement/listPage",
- method: "get",
- params: params,
- });
-}
-
-export function addBorrow(data) {
- return request({
- url: "/documentationBorrowManagement/add",
- method: "post",
- data: data,
- });
-}
-
-export function updateBorrow(data) {
- return request({
- url: "/documentationBorrowManagement/update",
- method: "put",
- data: data,
- });
-}
-
-export function deleteBorrow(ids) {
- return request({
- url: "/documentationBorrowManagement/delete",
- method: "delete",
- data: ids,
- });
-}
-
-// 缁熻鐩稿叧鎺ュ彛
-// 鑾峰彇鎬讳綋缁熻鏁版嵁
-export function getDocumentationOverview() {
- return request({
- url: "/documentation/overview",
- method: "get",
- });
-}
-
-// 鑾峰彇鍒嗙被缁熻鏁版嵁
-export function getDocumentationCategoryStats() {
- return request({
- url: "/documentation/category",
- method: "get",
- });
-}
-
-// 鑾峰彇鐘舵�佺粺璁℃暟鎹�
-export function getDocumentationStatusStats() {
- return request({
- url: "/documentation/status",
- method: "get",
- });
-}
diff --git a/src/api/fileManagement/return.js b/src/api/fileManagement/return.js
deleted file mode 100644
index 9021ac9..0000000
--- a/src/api/fileManagement/return.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ褰掕繕璁板綍
-export function getReturnListPage(query) {
- return request({
- url: "/documentationBorrowManagement/listPageReturn",
- method: "get",
- params: query,
- });
-}
-
-// 褰掕繕鎿嶄綔
-export function returnDocument(data) {
- return request({
- url: "/documentationBorrowManagement/revent",
- method: "put",
- data: data,
- });
-}
-
-// 鍒犻櫎褰掕繕璁板綍
-export function deleteReturn(ids) {
- return request({
- url: "/documentationBorrowManagement/reventDelete",
- method: "delete",
- data: ids,
- });
-}
-//鏍规嵁涔︾睄id鏌ヨ鍊熼槄璁板綍
-export function getBorrowListByDocumentationId(id) {
- return request({
- url: "/documentationBorrowManagement/getByDocumentationId/"+id,
- method: "get"
- });
-}
-
-// 鏇存柊鍊熼槄璁板綍
-export function updateBorrow(data) {
- return request({
- url: "/documentationBorrowManagement/update",
- method: "put",
- data: data,
- });
-}
-
-// 褰掕繕鏇存柊
-export function reventUpdate(data) {
- return request({
- url: "/documentationBorrowManagement/reventUpdate",
- method: "put",
- data: data,
- });
-}
-
-// 鑾峰彇鏂囨。鍒楄〃
-export function getDocumentList() {
- return request({
- url: "/documentationBorrowManagement/list",
- method: "get",
- });
-}
diff --git a/src/api/fileManagement/statistics.js b/src/api/fileManagement/statistics.js
deleted file mode 100644
index d77375c..0000000
--- a/src/api/fileManagement/statistics.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import request from "@/utils/request";
-
-// 鑾峰彇妗f鎬讳綋缁熻
-export function getDocumentStatistics() {
- return request({
- url: "/fileManagement/statistics/overview",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f鍒嗙被缁熻
-export function getCategoryStatistics() {
- return request({
- url: "/fileManagement/statistics/category",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f鐘舵�佺粺璁�
-export function getStatusStatistics() {
- return request({
- url: "/fileManagement/statistics/status",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f鍊熼槄缁熻
-export function getBorrowStatistics() {
- return request({
- url: "/fileManagement/statistics/borrow",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f骞村害缁熻
-export function getYearStatistics() {
- return request({
- url: "/fileManagement/statistics/year",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f浣嶇疆缁熻
-export function getLocationStatistics() {
- return request({
- url: "/fileManagement/statistics/location",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f瓒嬪娍缁熻
-export function getTrendStatistics(params) {
- return request({
- url: "/fileManagement/statistics/trend",
- method: "get",
- params: params,
- });
-}
-
-// 鑾峰彇妗f鍊熼槄鎺掕
-export function getBorrowRanking() {
- return request({
- url: "/fileManagement/statistics/borrowRanking",
- method: "get",
- });
-}
-
-// 鑾峰彇妗f鍒嗙被璇︽儏缁熻
-export function getCategoryDetailStatistics(categoryId) {
- return request({
- url: `/fileManagement/statistics/categoryDetail/${categoryId}`,
- method: "get",
- });
-}
-
diff --git a/src/api/financialManagement/expenseManagement.js b/src/api/financialManagement/expenseManagement.js
deleted file mode 100644
index a22af1b..0000000
--- a/src/api/financialManagement/expenseManagement.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍒楄〃
-export const listPage = (params) => {
- return request({
- url: "/account/accountExpense/listPage",
- method: "get",
- params,
- });
-};
-export const listPageAnalysis = (params) => {
- return request({
- url: "/account/accountExpense/report/analysis",
- method: "get",
- params,
- });
-};
-
-// 鏂板
-export function add(data) {
- return request({
- url: "/account/accountExpense/add",
- method: "post",
- data: data,
- });
-}
-
-// 缂栬緫
-export function update(data) {
- return request({
- url: "/account/accountExpense/update",
- method: "post",
- data: data,
- });
-}
-
-//瀵煎嚭
-export const exportAccountExpense = (query) => {
- return request({
- url: "/account/accountExpense/export",
- method: "post",
- data: query,
- responseType: "blob",
- });
-};
-
-export const delAccountExpense = (query) => {
- return request({
- url: `account/accountExpense/del`,
- method: "delete",
- data: query,
- });
-};
-
-export const getAccountExpense = (id) => {
- return request({
- url: `/account/accountExpense/${id}`,
- method: "get",
- });
-};
-
-// 鏌ヨ闄勪欢鍒楄〃
-export function fileListPage(query) {
- return request({
- url: "/account/accountFile/listPage",
- method: "get",
- params: query,
- });
-}
-// 淇濆瓨闄勪欢鍒楄〃
-export function fileAdd(query) {
- return request({
- url: "/account/accountFile/add",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎闄勪欢鍒楄〃
-export function fileDel(query) {
- return request({
- url: "/account/accountFile/del",
- method: "delete",
- data: query,
- });
-}
diff --git a/src/api/financialManagement/financialStatements.js b/src/api/financialManagement/financialStatements.js
deleted file mode 100644
index 537d36f..0000000
--- a/src/api/financialManagement/financialStatements.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import request from "@/utils/request";
-
-// 鏍规嵁鏃ユ湡鏌ヨ
-export const reportForms = (params) => {
- console.log(params);
- return request({
- url: "/account/accountExpense/report/forms",
- method: "get",
- params,
- });
-};
-
-// 鏌ヨ姣忔湀鏁版嵁-鏀跺叆
-export const reportIncome = (params) => {
- console.log(params);
- return request({
- url: "/account/accountExpense/report/income",
- method: "get",
- params,
- });
-};
-
-// 鏌ヨ姣忔湀鏁版嵁-鏀嚭
-export const reportExpense = (params) => {
- console.log(params);
- return request({
- url: "/account/accountExpense/report/expense",
- method: "get",
- params,
- });
-};
diff --git a/src/api/financialManagement/revenueManagement.js b/src/api/financialManagement/revenueManagement.js
deleted file mode 100644
index 090ddf8..0000000
--- a/src/api/financialManagement/revenueManagement.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍒楄〃
-export const listPage = (params) => {
- return request({
- url: "/account/accountIncome/listPage",
- method: "get",
- params,
- });
-};
-
-// 鏂板
-export function add(data) {
- return request({
- url: "/account/accountIncome/add",
- method: "post",
- data: data,
- });
-}
-
-// 缂栬緫
-export function update(data) {
- return request({
- url: "/account/accountIncome/update",
- method: "post",
- data: data,
- });
-}
-
-//瀵煎嚭
-export const exportAccountIncome = (query) => {
- return request({
- url: "/account/accountIncome/export",
- method: "post",
- data: query,
- responseType: "blob",
- });
-};
-
-export const delAccountIncome = (query) => {
- return request({
- url: `account/accountIncome/del`,
- method: "delete",
- data: query,
- });
-};
-
-export const getAccountIncome = (id) => {
- return request({
- url: `/account/accountIncome/${id}`,
- method: "get",
- });
-};
-
-// 鏌ヨ闄勪欢鍒楄〃
-export function fileListPage(query) {
- return request({
- url: "/account/accountFile/listPage",
- method: "get",
- params: query,
- });
-}
-// 淇濆瓨闄勪欢鍒楄〃
-export function fileAdd(query) {
- return request({
- url: "/account/accountFile/add",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎闄勪欢鍒楄〃
-export function fileDel(query) {
- return request({
- url: "/account/accountFile/del",
- method: "delete",
- data: query,
- });
-}
diff --git a/src/api/inspectionManagement/index.js b/src/api/inspectionManagement/index.js
deleted file mode 100644
index d0c444a..0000000
--- a/src/api/inspectionManagement/index.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// 宸℃绠$悊
-import request from '@/utils/request'
-
-// 宸℃浠诲姟琛ㄨ〃鏌ヨ
-export function inspectionTaskList(query) {
- return request({
- url: '/inspectionTask/list',
- method: 'get',
- params: query
- })
-}
-// 宸℃浠诲姟琛ㄦ柊澧炰慨鏀�
-export function addOrEditInspectionTask(query) {
- return request({
- url: '/inspectionTask/addOrEditInspectionTask',
- method: 'post',
- data: query
- })
-}
-// 宸℃浠诲姟琛ㄥ垹闄�
-export function delInspectionTask(query) {
- return request({
- url: '/inspectionTask/delInspectionTask',
- method: 'delete',
- data: query
- })
-}
-// 瀹氭椂宸℃浠诲姟琛ㄥ垹闄�
-export function delTimingTask(query) {
- return request({
- url: '/timingTask/delTimingTask',
- method: 'delete',
- data: query
- })
-}
-
-// /inspectionTask/addOrEditInspectionTask
-// 宸℃涓婁紶
-export function uploadInspectionTask(query) {
- return request({
- url: '/inspectionTask/addOrEditInspectionTask',
- method: 'post',
- data: query
- })
-}
-// 瀹氭椂宸℃浠诲姟琛ㄦ煡璇�
-export function timingTaskList(query) {
- return request({
- url: '/timingTask/list',
- method: 'get',
- params: query
- })
-}
-// 瀹氭椂宸℃浠诲姟琛ㄦ柊澧炰慨鏀�
-export function addOrEditTimingTask(query) {
- return request({
- url: '/timingTask/addOrEditTimingTask',
- method: 'post',
- data: query
- })
-}
\ No newline at end of file
diff --git a/src/api/inspectionUpload/index.js b/src/api/inspectionUpload/index.js
deleted file mode 100644
index 0d954e2..0000000
--- a/src/api/inspectionUpload/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// 宸℃涓婁紶
-import request from '@/utils/request'
-
-// 浜岀淮鐮佺鐞嗚〃鏌ヨ
-export function qrCodeList(query) {
- return request({
- url: '/qrCode/list',
- method: 'get',
- params: query
- })
-}
-// 浜岀淮鐮佹壂鐮佽褰曡〃鏌ヨ
-export function qrCodeScanRecordList(query) {
- return request({
- url: '/qrCodeScanRecord/list',
- method: 'get',
- params: query
- })
-}
-// 浜岀淮鐮佺鐞嗚〃鏂板淇敼
-export function addOrEditQrCode(query) {
- return request({
- url: '/qrCode/addOrEditQrCode',
- method: 'post',
- data: query
- })
-}
-// 浜岀淮鐮佹壂鐮佽褰曡〃鏂板淇敼
-export function addOrEditQrCodeRecord(query) {
- return request({
- url: '/qrCodeScanRecord/addOrEditQrCodeRecord',
- method: 'post',
- data: query
- })
-}
-// 浜岀淮鐮佹壂鐮佽褰曡〃鏂板淇敼
-export function delQrCode(query) {
- return request({
- url: '/qrCode/delQrCode',
- method: 'delete',
- data: query
- })
-}
\ No newline at end of file
diff --git a/src/api/inventoryManagement/stockIn.js b/src/api/inventoryManagement/stockIn.js
deleted file mode 100644
index 5e104f7..0000000
--- a/src/api/inventoryManagement/stockIn.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍏ュ簱淇℃伅鍒楄〃
-export const getStockInPage = (params) => {
- return request({
- url: "/stockin/listPage",
- method: "get",
- params,
- });
-};
-
-// 淇敼鍏ュ簱瀛樹俊鎭�
-export const updateStockIn = (data) => {
- return request({
- url: "/stockin/update",
- method: "post",
- data,
- });
-};
-
-// 淇敼搴撳瓨淇℃伅
-export const updateManagement = (data) => {
- return request({
- url: "/stockin/updateManagement",
- method: "post",
- data,
- });
-};
-
-// 鏂板鍟嗗搧鍏ュ簱淇℃伅
-export function addSutockIn(data) {
- return request({
- url: '/stockin/add',
- method: 'post',
- data: data
- })
-}
-
-// 鍒犻櫎鍏ュ簱淇℃伅
-export function delStockIn(ids) {
- return request({
- url: '/stockin/del',
- method: 'post',
- data: ids
- })
-}
-
-// 瀵煎嚭鍏ュ簱淇℃伅
-export function exportStockIn(query) {
- return request({
- url: '/stockin/export',
- method: 'get',
- params: query,
- responseType: 'blob'
- })
-}
-
-export function selectProductRecordListByPuechaserId(query) {
- return request({
- url: '/stockin/productlist',
- method: 'get',
- params: query
- })
-}
-
-
-//
-
diff --git a/src/api/inventoryManagement/stockManage.js b/src/api/inventoryManagement/stockManage.js
deleted file mode 100644
index bb2081b..0000000
--- a/src/api/inventoryManagement/stockManage.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ搴撳瓨淇℃伅鍒楄〃
-export const getStockManagePage = (params) => {
- return request({
- url: "/stockin/listPageCopy",
- method: "get",
- params,
- });
-};
-
-
-// 淇敼搴撳瓨淇℃伅
-export const updateStockManage = (data) => {
- return request({
- url: "/stockmanagement/update",
- method: "put",
- data,
- });
-};
-
-// 鍒犻櫎搴撳瓨淇℃伅
-export function delStockManage(ids) {
- return request({
- url: '/stockin/del',
- method: 'post',
- data: ids
- })
-}
-
-// 瀵煎嚭搴撳瓨淇℃伅
-export function exportStockManage(query) {
- return request({
- url: '/stockmanagement/export',
- method: 'get',
- params: query,
- responseType: 'blob'
- })
-}
-
-//鍑哄簱鎺ュ彛
-export const stockOut = (data) => {
- return request({
- url: '/stockmanagement/stockout',
- method: 'post',
- data: data
- })
-}
-
-//鏍规嵁id鑾峰彇搴撳瓨淇℃伅
-export function getStockManageById(id) {
- return request({
- url: '/stockmanagement/' + id,
- method: 'get'
- })
-}
-
-//
\ No newline at end of file
diff --git a/src/api/inventoryManagement/stockOut.js b/src/api/inventoryManagement/stockOut.js
deleted file mode 100644
index 5d410d9..0000000
--- a/src/api/inventoryManagement/stockOut.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import request from "@/utils/request";
-
-//鏌ヨ鍑哄簱鍒楄〃
-export const getStockOutPage = (params) => {
- return request({
- url: "/stockmanagement/listPage",
- method: "get",
- params,
- });
-};
-
-//鏂板鍑哄簱淇℃伅
-export const addStockOut = (data) => {
- return request({
- url: '/stockout/add',
- method: 'post',
- data: data
- })
-}
-
-//淇敼鍑哄簱淇℃伅
-export const updateStockOut = (data) => {
- return request({
- url: "/stockout/update",
- method: "put",
- data,
- });
-}
-
-//鍒犻櫎鍑哄簱淇℃伅
-export const delStockOut = (ids) => {
- return request({
- url: '/stockmanagement/del',
- method: 'post',
- data: ids
- })
-}
-
-//瀵煎嚭鍑哄簱淇℃伅
-export const exportStockOut = (query) => {
- return request({
- url: '/stockmanagement/export',
- method: 'get',
- params: query,
- responseType: 'blob'
- })
-}
\ No newline at end of file
diff --git a/src/api/inventoryManagement/stockReport.js b/src/api/inventoryManagement/stockReport.js
deleted file mode 100644
index 6d1a3ce..0000000
--- a/src/api/inventoryManagement/stockReport.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import request from "@/utils/request";
-
-// 鑾峰彇搴撳瓨鏃ユ姤缁熻
-export const getStockDailyReport = (params) => {
- return request({
- url: "/stockin/getReportList",
- method: "get",
- params,
- });
-};
-// 鑾峰彇搴撳瓨鏈堟姤缁熻
-export const getStockMonthlyReport = (params) => {
- return request({
- url: "/stockin/getReportList",
- method: "get",
- params,
- });
-};
-
-// 鑾峰彇浣滀笟鎶ヨ〃缁熻
-export const getWorkReport = (params) => {
- return request({
- url: "/stockin/getReportList",
- method: "get",
- params,
- });
-};
-
-// 鑾峰彇搴撳瓨杩涘嚭瀛樼粺璁�
-export const getStockInOutReport = (params) => {
- return request({
- url: "/stockin/getReportList",
- method: "get",
- params,
- });
-};
-
-// 瀵煎嚭搴撳瓨鎶ヨ〃
-export const exportStockReport = (params) => {
- return request({
- url: "/stockin/exportCopy",
- method: "post",
- params,
- responseType: 'blob'
- });
-};
-
-// 鑾峰彇搴撳瓨瓒嬪娍鏁版嵁
-export const getStockTrendData = (params) => {
- return request({
- url: "/stockreport/trend",
- method: "get",
- params,
- });
-};
diff --git a/src/api/inventoryManagement/stockWarning.js b/src/api/inventoryManagement/stockWarning.js
deleted file mode 100644
index 65e641a..0000000
--- a/src/api/inventoryManagement/stockWarning.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ鍌ㄦ皵缃愰璀﹀垪琛�
-export const getStockWarningPage = (page, params) => {
- return request({
- url: "/gasTankWarning/listPage",
- method: "get",
- params: {
- ...page,
- ...params
- },
- });
-};
-
-// 鏂板鍌ㄦ皵缃愰璀﹁鍒�
-export const addStockWarning = (data) => {
- return request({
- url: "/gasTankWarning/add",
- method: "post",
- data: data,
- });
-};
-
-// 淇敼鍌ㄦ皵缃愰璀﹁鍒�
-export const updateStockWarning = (data) => {
- return request({
- url: "/gasTankWarning/update",
- method: "post",
- data: data,
- });
-};
-
-// 鍒犻櫎鍌ㄦ皵缃愰璀﹁鍒�
-export const deleteStockWarning = (ids) => {
- return request({
- url: "/gasTankWarning/delete",
- method: "delete",
- data: ids,
- });
-};
-
-// 鎵归噺澶勭悊鍌ㄦ皵缃愰璀�
-export const batchProcessStockWarning = (data) => {
- return request({
- url: "/gasTankWarning/batchProcess",
- method: "post",
- data,
- });
-};
-
-// 瀵煎嚭鍌ㄦ皵缃愰璀︽暟鎹�
-export const exportStockWarning = (params) => {
- return request({
- url: "/gasTankWarning/export",
- method: "get",
- params,
- responseType: "blob",
- });
-};
-
-// 鏍规嵁ID鑾峰彇鍌ㄦ皵缃愰璀﹁鎯�
-export const getStockWarningById = (id) => {
- return request({
- url: `/gasTankWarning/${id}`,
- method: "get",
- });
-};
-
-// 鍚敤/绂佺敤棰勮瑙勫垯
-export const toggleStockWarningStatus = (data) => {
- return request({
- url: "/gasTankWarning/toggleStatus",
- method: "put",
- data,
- });
-};
-
-// 鑾峰彇棰勮缁熻淇℃伅
-export const getStockWarningStatistics = () => {
- return request({
- url: "/gasTankWarning/statistics",
- method: "get",
- });
-};
diff --git a/src/api/lavorissce/ledger.js b/src/api/lavorissce/ledger.js
deleted file mode 100644
index f4f710c..0000000
--- a/src/api/lavorissce/ledger.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import request from '@/utils/request'
-
-// 鍒嗛〉鏌ヨ
-export function listPage(query) {
- return request({
- url: '/lavorIssue/listPage',
- method: 'get',
- params: query
- })
-}
-
-// 鍒嗛〉鏌ヨ
-export function statistics(params) {
- return request({
- url: '/lavorIssue/statistics',
- method: 'get',
- params
- })
-}
-
-export function statisticsList(params) {
- return request({
- url: '/lavorIssue/statisticsList',
- method: 'get',
- params
- })
-}
-
-// 娣诲姞
-export function add(data) {
- return request({
- url: '/lavorIssue/add',
- method: 'post',
- data
- })
-}
-
-// 淇敼
-export function update(data) {
- return request({
- url: '/lavorIssue/update',
- method: 'post',
- data
- })
-}
-
-// 鍒犻櫎
-export function deleteLedger(data) {
- return request({
- url: '/lavorIssue/delete',
- method: 'delete',
- data
- })
-}
-
diff --git a/src/api/oaSystem/projectManagement.js b/src/api/oaSystem/projectManagement.js
deleted file mode 100644
index 56c9287..0000000
--- a/src/api/oaSystem/projectManagement.js
+++ /dev/null
@@ -1,154 +0,0 @@
-import request from "@/utils/request";
-import { parseStrEmpty } from "@/utils/ruoyi";
-
-// 鏌ヨ椤圭洰鍒楄〃
-export function listProject(query) {
- return request({
- url: "/oA/project/listPage",
- method: "get",
- params: query
- });
-}
-
-// 鏌ヨ椤圭洰鍒楄〃璇︾粏
-export function getProject(query) {
- return request({
- url: "oA/project/getList",
- method: "get"
- });
-}
-
-// 鏂板椤圭洰
-export function addProject(data) {
- return request({
- url: "/oA/project/add",
- method: "post",
- data: data
- });
-}
-
-// 淇敼椤圭洰
-export function updateProject(data) {
- return request({
- url: "/oA/project/update",
- method: "post",
- data: data
- });
-}
-
-// 鍒犻櫎椤圭洰
-export function delProject(projectId) {
- return request({
- url: "/oA/project/delete/" + projectId,
- method: "delete"
- });
-}
-// 瀵煎嚭椤圭洰
-export function exportProject(data) {
- return request({
- url: "/oA/project/export",
- method: "post",
- data: data
- });
-}
-// // 鎵归噺鍒犻櫎椤圭洰
-// export function delProjectBatch(projectIds) {
-// return request({
-// url: "/oaSystem/project/batch",
-// method: "delete",
-// data: projectIds
-// });
-// }
-
-// 鏍规嵁椤圭洰闃舵id鏌ヨ椤圭洰闃舵浠诲姟鍒楄〃
-export function listProjectTask(phaseId) {
- return request({
- url: "/oA/projectPhaseTask/listByPhaseId/"+ phaseId,
- method: "get"
- });
-}
-
-// // 鏌ヨ椤圭洰浠诲姟璇︾粏
-// export function getProjectTask(taskId) {
-// return request({
-// url: "/oaSystem/project/task/" + taskId,
-// method: "get"
-// });
-// }
-
-// 鏂板椤圭洰闃舵浠诲姟
-export function addProjectTask(data) {
- return request({
- url: "/oA/projectPhaseTask/add",
- method: "post",
- data: data
- });
-}
-
-// 淇敼椤圭洰闃舵浠诲姟
-export function updateProjectTask(data) {
- return request({
- url: "/oA/projectPhaseTask/update",
- method: "post",
- data: data
- });
-}
-
-// 鍒犻櫎椤圭洰闃舵浠诲姟
-export function delProjectTask(taskId) {
- return request({
- url: "/oA/projectPhaseTask/delete/" + taskId,
- method: "delete"
- });
-}
-
-// 椤圭洰id鏌ヨ椤圭洰闃舵鍒楄〃
-export function listProjectPhase(projectId) {
- return request({
- url: "/oA/projectPhase/listByProjectId/" + projectId,
- method: "get"
- });
-}
-// 鏂板椤圭洰闃舵
-export function addProjectPhase(data) {
- return request({
- url: "/oA/projectPhase/add",
- method: "post",
- data: data
- });
-}
-
-// 淇敼椤圭洰闃舵
-export function updateProjectPhase(data) {
- return request({
- url: "/oA/projectPhase/update",
- method: "post",
- data: data
- });
-
-}
-// 鍒犻櫎椤圭洰闃舵
-export function delProjectPhase(phaseId) {
- return request({
- url: "/oA/projectPhase/delete/" + phaseId,
- method: "delete"
- })
-}
-//
-
-// // 鏌ヨ椤圭洰閲岀▼纰戝垪琛�
-// export function listProjectMilestone(query) {
-// return request({
-// url: "/oaSystem/project/milestone/list",
-// method: "get",
-// params: query
-// });
-// }
-
-// // 椤圭洰缁熻淇℃伅
-// export function getProjectStatistics() {
-// return request({
-// url: "/oaSystem/project/statistics",
-// method: "get"
-// });
-// }
\ No newline at end of file
diff --git a/src/api/procurementManagement/advancedPriceManagement.js b/src/api/procurementManagement/advancedPriceManagement.js
deleted file mode 100644
index a30921c..0000000
--- a/src/api/procurementManagement/advancedPriceManagement.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// 楂樼骇閲囪喘浠锋牸绠$悊API鎺ュ彛
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ浠锋牸鍒楄〃
-export function listPage(query) {
- return request({
- url: "/procurementPriceManagement/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板浠锋牸
-export function add(data) {
- return request({
- url: "/procurementPriceManagement/add",
- method: "post",
- data: data,
- });
-}
-
-// 鏇存柊浠锋牸
-export function update(data) {
- return request({
- url: "/procurementPriceManagement/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎浠锋牸
-export function del(data) {
- return request({
- url: `/procurementPriceManagement/del`,
- method: "delete",
- data
- });
-}
diff --git a/src/api/procurementManagement/arrivalManagement.js b/src/api/procurementManagement/arrivalManagement.js
deleted file mode 100644
index 107fc3c..0000000
--- a/src/api/procurementManagement/arrivalManagement.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function listPage(query) {
- return request({
- url: "/inboundManagement/listPage",
- method: "get",
- params: query,
- });
-}
-
-export function listPageCopy(query) {
- return request({
- url: "/inboundManagement/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏂板
-export function add(data) {
- return request({
- url: "/inboundManagement/add",
- method: "post",
- data
- });
-}
-// 淇敼
-export function update(data) {
- return request({
- url: "/inboundManagement/update",
- method: "post",
- data
- });
-}
-// 鍒犻櫎閿�鍞彴璐�
-export function del(data) {
- return request({
- url: "/inboundManagement/del",
- method: "delete",
- data
- });
-}
\ No newline at end of file
diff --git a/src/api/procurementManagement/invoiceEntry.js b/src/api/procurementManagement/invoiceEntry.js
deleted file mode 100644
index 8325aa7..0000000
--- a/src/api/procurementManagement/invoiceEntry.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// 閲囪喘-鏉ョエ鐧昏鎺ュ彛
-import request from "@/utils/request";
-
-// 鏌ヨ閲囪喘鍚堝悓鍙�
-export function getProduct(query) {
- return request({
- url: "/purchase/ledger/getProduct",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨid閲囪喘鍚堝悓鍙�
-export function getPurchaseNoById(query) {
- return request({
- url: "/purchase/ledger/getPurchaseNoById",
- method: "get",
- params: query,
- });
-}
-// 鏍规嵁閲囪喘鍚堝悓鍙锋煡璇㈣缁嗕俊鎭�
-export function getInfo(query) {
- return request({
- url: "/purchase/ledger/getInfo",
- method: "get",
- params: query,
- });
-}
-// 涓诲垪琛ㄦ煡璇�
-export function gePurchaseList(query) {
- return request({
- url: "/purchase/ledger/list",
- method: "get",
- params: query,
- });
-}
-// 涓诲垪琛ㄦ煡璇�
-export function getRegistrationById(query) {
- return request({
- url: "/purchase/registration/getRegistrationById",
- method: "get",
- params: query,
- });
-}
-// 鏂板缂栬緫鏉ョエ鐧昏
-export function addOrUpdateRegistration(query) {
- return request({
- url: "/purchase/registration/addOrUpdateRegistration",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎鏉ョエ鐧昏
-export function delRegistration(query) {
- return request({
- url: "/purchase/registration/delRegistration",
- method: "delete",
- data: query,
- });
-}
-
-// 涓诲垪琛ㄦ煡璇�
-export function gePurchaseListPage(query) {
- return request({
- url: "/purchase/ledger/listPage",
- method: "get",
- params: query,
- });
-}
diff --git a/src/api/procurementManagement/paymentEntry.js b/src/api/procurementManagement/paymentEntry.js
deleted file mode 100644
index 6ef0eb9..0000000
--- a/src/api/procurementManagement/paymentEntry.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// 閲囪喘浠樻鐧昏椤甸潰鎺ュ彛
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function registrationList(query) {
- return request({
- url: "/purchase/paymentRegistration/list",
- method: "get",
- params: query,
- });
-}
-// 鏌ヨ璇︽儏
-export function registrationInfo(query) {
- return request({
- url: "/purchase/paymentRegistration/" + query,
- method: "get",
- });
-}
-// 鏍规嵁閲囪喘鍚堝悓鍙锋煡璇㈣鎯�
-export function byPurchaseId(query) {
- return request({
- url: "/purchase/paymentRegistration/byPurchaseId/" + query,
- method: "get",
- });
-}
-// 鏌ヨ閲囪喘鍚堝悓鍙�
-export function getPurchaseNo() {
- return request({
- url: "/purchase/ledger/getPurchaseNo",
- method: "get",
- });
-}
-// 鏂板
-export function paymentRegistrationAdd(query) {
- return request({
- url: "/purchase/paymentRegistration",
- method: "post",
- data: query,
- });
-}
-// 淇敼
-export function paymentRegistrationEdit(query) {
- return request({
- url: "/purchase/paymentRegistration",
- method: "put",
- data: query,
- });
-}
-// 鍒犻櫎
-export function paymentRegistrationDel(query) {
- return request({
- url: "/purchase/paymentRegistration/delete",
- method: "delete",
- data: query,
- });
-}
-// 鑾峰彇鍙戠エ鍙峰拰鍙戠エ閲戦
-export function getTicketNo(query) {
- return request({
- url: "/purchase/registration/getTicketNo",
- method: "get",
- params: query,
- });
-}
-// 鍒嗛〉鏌ヨ
-export function paymentHistoryList(query) {
- return request({
- url: "/purchase/paymentRegistration/paymentHistoryList",
- method: "get",
- params: query,
- });
-}
-
-// 鍒嗛〉鏌ヨ
-export function paymentHistoryListPage(query) {
- return request({
- url: "/purchase/paymentRegistration/paymentHistoryListPage",
- method: "get",
- params: query,
- });
-}
diff --git a/src/api/procurementManagement/paymentLedger.js b/src/api/procurementManagement/paymentLedger.js
deleted file mode 100644
index 3e20b78..0000000
--- a/src/api/procurementManagement/paymentLedger.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 閲囪喘鍙拌处椤甸潰鎺ュ彛
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function paymentLedgerList(query) {
- return request({
- url: "/purchase/paymentRegistration/paymentLedgerList",
- method: "get",
- params: query,
- });
-}
-
-// 鍒嗛〉鏌ヨ
-export function paymentRecordList(supplierId) {
- return request({
- url: "/purchase/paymentRegistration/getPaymentRecordList/" + supplierId,
- method: "get",
- });
-}
diff --git a/src/api/procurementManagement/procurementInvoiceLedger.js b/src/api/procurementManagement/procurementInvoiceLedger.js
deleted file mode 100644
index 76f8410..0000000
--- a/src/api/procurementManagement/procurementInvoiceLedger.js
+++ /dev/null
@@ -1,125 +0,0 @@
-// 閲囪喘-鏉ョエ鍙拌处鎺ュ彛
-import request from "@/utils/request";
-
-// 鏌ヨ鍒楄〃
-export function invoiceList(query) {
- return request({
- url: "/purchase/registration/list",
- method: "get",
- params: query,
- });
-}
-// 鏌ヨ璇︽儏
-// export function getInvoiceById(query) {
-// return request({
-// url: "/purchase/registration/getRegistrationById",
-// method: "get",
-// params: query,
-// });
-// }
-// 鏂板銆佺紪杈�
-export function addOrUpdateInvoice(query) {
- return request({
- url: "/purchase/invoice/addOrUpdateInvoice",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎
-export function delInvoice(query) {
- return request({
- url: "/purchase/invoice/delInvoice",
- method: "delete",
- data: query,
- });
-}
-// 鍒犻櫎鏉ョエ鍙拌处
-export function delRegistration(query) {
- return request({
- url: "/purchase/registration/delRegistration",
- method: "delete",
- data: query,
- });
-}
-// 鍒犻櫎闄勪欢
-export function delCommonFile(query) {
- return request({
- url: "/commonFile/delCommonFile",
- method: "delete",
- data: query,
- });
-}
-// 瀛愯〃鏍兼煡璇�
-export function productRecordList(query) {
- return request({
- url: "/purchase/registration/productRecordList",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ鍒楄〃
-export function invoiceListPage(query) {
- return request({
- url: "/purchase/registration/listPage",
- method: "get",
- params: query,
- });
-}
-
-export function productRecordPage(query) {
- return request({
- url: "/purchase/registration/productRecordPage",
- method: "get",
- params: query,
- });
-}
-
-export function productUploadFile(data) {
- return request({
- url: "/file/uploadFile",
- method: "post",
- data: data,
- });
-}
-
-export function getProductRecordById(params) {
- return request({
- url: "/purchase/registration/getProductRecordById",
- method: "get",
- params: params,
- });
-}
-
-export function updateRegistration(data) {
- return request({
- url: "/purchase/registration/updateRegistration",
- method: "post",
- data: data,
- });
-}
-
-// 鏌ヨ浠樻鐧昏瀛愬垪琛�
-export function registrationListPageGetById(query) {
- return request({
- url: "/purchase/registration/getById",
- method: "get",
- params: query,
- });
-}
-// 淇敼浠樻娴佹按
-export function updatePaymentRegistration(query) {
- return request({
- url: "/purchase/registration/updatePaymentRegistration",
- method: "put",
- data: query,
- });
-}
-// 鍒犻櫎浠樻娴佹按
-export function delPaymentRegistration(query) {
- return request({
- url: "/purchase/registration/delPaymentRegistration",
- method: "delete",
- data: query,
- });
-}
diff --git a/src/api/procurementManagement/procurementLedger.js b/src/api/procurementManagement/procurementLedger.js
deleted file mode 100644
index 9fb284e..0000000
--- a/src/api/procurementManagement/procurementLedger.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// 閲囪喘鍙拌处椤甸潰鎺ュ彛
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function purchaseList(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,
- });
-}
-// 瀛愯〃鏍兼煡璇�
-export function productList(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,
- });
-}
-// 鍒犻櫎
-export function delPurchase(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,
- });
-}
-// 鏌ヨ璇︽儏
-export function getOptions(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,
- });
-}
-
-export function createPurchaseNo() {
- return request({
- url: "/purchase/ledger/createPurchaseNo",
- method: "get",
- });
-}
diff --git a/src/api/procurementManagement/procurementPlan.js b/src/api/procurementManagement/procurementPlan.js
deleted file mode 100644
index 48a1a74..0000000
--- a/src/api/procurementManagement/procurementPlan.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ閲囪喘璁″垝鍒楄〃
-export function listPage(query) {
- return request({
- url: "/procurementPlan/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板閲囪喘璁″垝
-export function add(data) {
- return request({
- url: "/procurementPlan/add",
- method: "post",
- data,
- });
-}
-
-// 淇敼閲囪喘璁″垝
-export function update(data) {
- return request({
- url: "/procurementPlan/update",
- method: "post",
- data,
- });
-}
-
-// 鍒犻櫎閲囪喘璁″垝
-export function del(data) {
- return request({
- url: "/procurementPlan/del",
- method: "delete",
- data,
- });
-}
-
-// 鍒犻櫎閲囪喘璁″垝
-export function listPageCopy(query) {
- return request({
- url: "/stockin/listPageCopy",
- method: "get",
- params: query,
- });
-}
-
diff --git a/src/api/procurementManagement/projectProfit.js b/src/api/procurementManagement/projectProfit.js
deleted file mode 100644
index 7fb1660..0000000
--- a/src/api/procurementManagement/projectProfit.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function getPurchaseList(query) {
- return request({
- url: "/purchase/report/list",
- method: "get",
- params: query,
- });
-}
diff --git a/src/api/procurementManagement/returnManagement.js b/src/api/procurementManagement/returnManagement.js
deleted file mode 100644
index e765701..0000000
--- a/src/api/procurementManagement/returnManagement.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function listPage(query) {
- return request({
- url: "/returnManagement/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏂板
-export function add(data) {
- return request({
- url: "/returnManagement/add",
- method: "post",
- data
- });
-}
-// 淇敼
-export function update(data) {
- return request({
- url: "/returnManagement/update",
- method: "post",
- data
- });
-}
-// 鍒犻櫎閿�鍞彴璐�
-export function del(data) {
- return request({
- url: "/returnManagement/del",
- method: "delete",
- data
- });
-}
\ No newline at end of file
diff --git a/src/api/procurementManagement/taxComparison.js b/src/api/procurementManagement/taxComparison.js
deleted file mode 100644
index 726a27f..0000000
--- a/src/api/procurementManagement/taxComparison.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function getTaxList(query) {
- return request({
- url: "/purchase/report/listVat",
- method: "get",
- params: query,
- });
-}
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index ab3dc06..fc13b6f 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -3,17 +3,50 @@
// 鍒嗛〉鏌ヨ
export function schedulingListPage(query) {
- return request({
- url: "/salesLedger/scheduling/listPage",
- method: "get",
- params: query,
- });
+ return request({
+ url: "/productionOrder/listPage",
+ method: "get",
+ params: query,
+ });
}
// 鐢熶骇娲惧伐
export function productionDispatch(query) {
- return request({
- url: "/salesLedger/scheduling/productionDispatch",
- method: "post",
- data: query,
- });
-}
\ No newline at end of file
+ return request({
+ url: "/salesLedger/scheduling/productionDispatch",
+ method: "post",
+ data: query,
+ });
+}
+
+// 鏂板鐢熶骇璁㈠崟
+export function addProductionOrder(query) {
+ return request({
+ url: "/productionOrder/addProductionOrder",
+ method: "post",
+ data: query,
+ });
+}
+// 淇敼鐢熶骇璁㈠崟
+export function updateProductionOrder(query) {
+ return request({
+ url: "/productionOrder/updateProductionOrder",
+ method: "post",
+ data: query,
+ });
+}
+// 鍒犻櫎鐢熶骇璁㈠崟
+export function deleteProductionOrder(query) {
+ return request({
+ url: "/productionOrder/deleteProductionOrder",
+ method: "delete",
+ data: query,
+ });
+}
+// 鎶ヨ〃鍒嗘瀽
+export function reportAnalysis(query) {
+ return request({
+ url: "/productionOrder/reportAnalysis",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/api/salesManagement/deliveryLedger.js b/src/api/salesManagement/deliveryLedger.js
deleted file mode 100644
index bb8689f..0000000
--- a/src/api/salesManagement/deliveryLedger.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// 鍙戣揣鍙拌处椤甸潰鎺ュ彛
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function deliveryLedgerListPage(query) {
- return request({
- url: "/shippingInfo/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 淇敼鍙戣揣鍙拌处
-export function addOrUpdateDeliveryLedger(query) {
- return request({
- url: "/shippingInfo/update",
- method: "post",
- data: query,
- });
-}
-
-// 鍒犻櫎鍙戣揣鍙拌处
-export function delDeliveryLedger(query) {
- return request({
- url: "/shippingInfo/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 鏂板鍙戣揣淇℃伅
-export function addShippingInfo(data) {
- return request({
- url: "/shippingInfo/add",
- method: "post",
- data,
- });
-}
-
diff --git a/src/api/salesManagement/invoiceLedger.js b/src/api/salesManagement/invoiceLedger.js
deleted file mode 100644
index 6a54493..0000000
--- a/src/api/salesManagement/invoiceLedger.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// 寮�绁ㄥ彴璐﹂〉闈㈡帴鍙�
-import request from '@/utils/request'
-
-// 鍒嗛〉鏌ヨ
-export function invoiceLedgerList(query) {
- return request({
- url: '/invoiceLedger/page',
- method: 'get',
- params: query
- })
-}
-
-// 鏂板
-export function invoiceLedgerSaveOrUpdate(query) {
- return request({
- url: '/invoiceLedger/saveOrUpdate',
- method: 'post',
- data: query
- })
-}
-
-// 寮�绁ㄥ彴璐﹀垹闄�
-export function invoiceLedgerDel(query) {
- return request({
- url: '/invoiceLedger/del',
- method: 'delete',
- data: query
- })
-}
-
-// 璇︽儏鏌ヨ
-export function invoiceLedgerDetail(query) {
- return request({
- url: '/invoiceLedger/info',
- method: 'get',
- params: query
- })
-}
-
-// 闄勪欢鎻愪氦
-export function commitFile(query) {
- return request({
- url: '/invoiceLedger/commitFile',
- method: 'post',
- data: query
- })
-}
-
-// 寮�绁ㄥ彴璐﹂儴鍒嗕篃鏌ヨ
-export function invoiceLedgerListNoPage(query) {
- return request({
- url: '/invoiceLedger/list',
- method: 'get',
- data: query
- })
-}
-
-// 鍒嗛〉鏌ヨ
-export function invoiceLedgerSalesAccount(query) {
- return request({
- url: '/invoiceLedger/salesAccount',
- method: 'get',
- params: query
- })
-}
-
-// 浜у搧寮�绁ㄨ褰曞垎椤垫煡璇�
-export function registrationProductPage(query) {
- return request({
- url: '/invoiceLedger/registrationProductPage',
- method: 'get',
- params: query
- })
-}
-
-// 浜у搧寮�绁ㄨ鎯呮煡璇�
-export function invoiceLedgerProductInfo(query) {
- return request({
- url: '/invoiceLedger/invoiceLedgerProductInfo',
- method: 'get',
- params: query
- })
-}
-
-export function delInvoiceLedgerByRegProductId(invoiceRegistrationProductId) {
- return request({
- url: '/invoiceLedger/delInvoiceLedger/'+ invoiceRegistrationProductId,
- method: 'delete'
- })
-}
-
-
diff --git a/src/api/salesManagement/invoiceRegistration.js b/src/api/salesManagement/invoiceRegistration.js
deleted file mode 100644
index 4bc33ce..0000000
--- a/src/api/salesManagement/invoiceRegistration.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from '@/utils/request'
-
-// 鍒嗛〉鏌ヨ
-export function invoiceRegistrationList(query) {
- return request({
- url: '/invoiceRegistration/listPage',
- method: 'get',
- params: query
- })
-}
-// 寮�绁ㄧ櫥璁版柊澧�
-export function invoiceRegistrationSave(query) {
- return request({
- url: '/invoiceRegistration/save',
- method: 'post',
- data: query
- })
-}
-// 寮�绁ㄧ櫥璁板垹闄�
-export function invoiceRegistrationDel(query) {
- return request({
- url: '/invoiceRegistration/del',
- method: 'delete',
- data: query
- })
-}
-// 瀛愯〃鏍兼煡璇�
-export function productList(query) {
- return request({
- url: '/invoiceRegistration/productList',
- method: 'get',
- params: query
- })
-}
-
-// 寮�绁ㄧ櫥璁拌鎯�
-export function invoiceRegistrationDetail(query) {
- return request({
- url: '/invoiceRegistration/detail',
- method: 'get',
- params: query
- })
-}
-
-// 瀵煎嚭寮�绁ㄧ櫥璁�
-export function invoiceRegistrationExport(query) {
- return request({
- url: '/invoiceRegistration/export',
- method: 'get',
- params: query,
- responseType: 'blob'
- })
-}
diff --git a/src/api/salesManagement/paymentShipping.js b/src/api/salesManagement/paymentShipping.js
deleted file mode 100644
index c163540..0000000
--- a/src/api/salesManagement/paymentShipping.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function listPage(query) {
- return request({
- url: "/paymentShipping/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏂板
-export function add(data) {
- return request({
- url: "/paymentShipping/add",
- method: "post",
- data
- });
-}
-// 淇敼
-export function update(data) {
- return request({
- url: "/paymentShipping/update",
- method: "post",
- data
- });
-}
-// 鍒犻櫎閿�鍞彴璐�
-export function deletePaymentShipping(data) {
- return request({
- url: "/paymentShipping/delete",
- method: "delete",
- data
- });
-}
\ No newline at end of file
diff --git a/src/api/salesManagement/receiptPayment.js b/src/api/salesManagement/receiptPayment.js
deleted file mode 100644
index b5d0cf5..0000000
--- a/src/api/salesManagement/receiptPayment.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// 寮�绁ㄧ櫥璁伴〉闈㈡帴鍙�
-import request from '@/utils/request'
-
-// 鏂板/淇敼
-export function receiptPaymentSaveOrUpdate(query) {
- return request({
- url: '/receiptPayment/saveOrUpdate',
- method: 'post',
- data: query
- })
-}
-
-// 瀹㈡埛寰�鏉ヨ褰曟煡璇�
-export function customerInteractions(query) {
- return request({
- url: '/receiptPayment/customerInteractions',
- method: 'get',
- params: query
- })
-}
-
-// 璇︽儏
-export function receiptPaymentInfo(query) {
- return request({
- url: '/receiptPayment/info',
- method: 'get',
- params: query
- })
-}
-
-// 鍒犻櫎
-export function receiptPaymentDel(query) {
- return request({
- url: '/receiptPayment/del',
- method: 'delete',
- data: query
- })
-}
-
-// 鏌ヨ宸茬粡缁戝畾鍙戠エ鐨勫紑绁ㄥ彴璐�
-export function bindInvoiceNoRegPage(query) {
- return request({
- url: '/receiptPayment/bindInvoiceNoRegPage',
- method: 'get',
- params: query
- })
-}
-
-// 寮�绁ㄥ彴璐﹁鎯�
-export function invoiceInfo(query) {
- return request({
- url: '/receiptPayment/invoiceInfo',
- method: 'get',
- params: query
- })
-}
-
-// 璇㈠洖娆捐褰�
-export function receiptPaymentHistoryList(query) {
- return request({
- url: '/receiptPayment/receiptPaymentHistoryList',
- method: 'get',
- params: query
- })
-}
-
-/**
- * 鏌ヨ鍥炴璁板綍鍒嗛〉鏌ヨ
- */
-export function receiptPaymentHistoryListPage(query) {
- return request({
- url: '/receiptPayment/receiptPaymentHistoryListPage',
- method: 'get',
- params: query
- })
-}
-
-export function receiptPaymentHistoryListNoPage(query) {
- return request({
- url: '/receiptPayment/receiptPaymentHistoryListNoPage',
- method: 'get',
- params: query
- })
-}
diff --git a/src/api/salesManagement/salesLedger.js b/src/api/salesManagement/salesLedger.js
deleted file mode 100644
index 6548927..0000000
--- a/src/api/salesManagement/salesLedger.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function ledgerList(query) {
- return request({
- url: "/sales/ledger/list",
- method: "get",
- params: query,
- });
-}
-// 瀛愯〃鏍兼煡璇�
-export function productList(query) {
- return request({
- url: "/sales/product/list",
- method: "get",
- params: query,
- });
-}
-// 鏌ヨ瀹㈡埛鍚嶇О鍒楄〃
-export function customerList(query) {
- return request({
- url: "/basic/customer/customerList",
- method: "get",
- params: query,
- });
-}
-// 鏂板銆佷慨鏀归攢鍞彴璐�
-export function addOrUpdateSalesLedger(query) {
- return request({
- url: "/sales/ledger/addOrUpdateSalesLedger",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎閿�鍞彴璐�
-export function delLedger(query) {
- return request({
- url: "/sales/ledger/delLedger",
- method: "delete",
- data: query,
- });
-}
-// 鏌ヨ閿�鍞彴璐﹁鎯�
-export function getSalesLedgerWithProducts(query) {
- return request({
- url: "/sales/ledger/getSalesLedgerWithProducts",
- method: "get",
- params: query,
- });
-}
-// 瀹炴椂淇敼浜у搧淇℃伅
-export function addOrUpdateSalesLedgerProduct(query) {
- return request({
- url: "/sales/product/addOrUpdateSalesLedgerProduct",
- method: "post",
- data: query,
- });
-}
-// 鍒犻櫎浜у搧
-export function delProduct(query) {
- return request({
- url: "/sales/product/delProduct",
- method: "delete",
- data: query,
- });
-}
-// 涓婁紶闄勪欢
-export function upload(query) {
- return request({
- url: "/file/upload",
- method: "post",
- data: query,
- responseType: "blob",
- });
-}
-// 缂栬緫鏃跺垹闄ら檮浠�
-export function delLedgerFile(query) {
- return request({
- url: "/sales/ledger/delLedgerFile",
- method: "delete",
- data: query,
- });
-}
-
-// 閿�鍞笉鍒嗛〉鏌ヨ
-export function ledgerListNoPage(query) {
- return request({
- url: "/sales/ledger/listNoPage",
- method: "get",
- params: query,
- });
-}
-
-// 鍒嗛〉鏌ヨ
-export function ledgerListPage(query) {
- return request({
- url: "/sales/ledger/listPage",
- method: "get",
- params: query,
- });
-}
-
-// 鏍规嵁閿�鍞悎鍚屽彿鏌ヤ骇鍝佷俊鎭�
-export function getProductInfoByContractNo(query) {
- return request({
- url: "/purchase/ledger/getProductBySalesNo",
- method: "get",
- params: query,
- });
-}
-// 閿�鍞彴璐﹂〉闈㈠彂璐э紝鏌ヨ搴撳瓨鏄惁鍏呰冻
-export function getProductInventory(query) {
- return request({
- url: "/sales/ledger/getProductInventory",
- method: "get",
- params: query,
- });
-}
\ No newline at end of file
diff --git a/src/api/salesManagement/salesQuotation.js b/src/api/salesManagement/salesQuotation.js
deleted file mode 100644
index 4329dd9..0000000
--- a/src/api/salesManagement/salesQuotation.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// 閿�鍞姤浠烽〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ鎶ヤ环鍗曞垪琛�
-export function getQuotationList(query) {
- return request({
- url: "/sales/quotation/list",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ鎶ヤ环鍗曡鎯�
-export function getQuotationDetail(query) {
- return request({
- url: "/sales/quotation/detail",
- method: "get",
- params: query,
- });
-}
-
-// 鏂板鎶ヤ环鍗�
-export function addQuotation(data) {
- return request({
- url: "/sales/quotation/add",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼鎶ヤ环鍗�
-export function updateQuotation(data) {
- return request({
- url: "/sales/quotation/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎鎶ヤ环鍗�
-export function deleteQuotation(query) {
- return request({
- url: "/sales/quotation/delete",
- method: "delete",
- data: query,
- });
-}
-
-// 鍙戦�佹姤浠峰崟
-export function sendQuotation(data) {
- return request({
- url: "/sales/quotation/send",
- method: "post",
- data: data,
- });
-}
-
-// 鎶ヤ环鍗曡浆璁㈠崟
-export function convertToOrder(data) {
- return request({
- url: "/sales/quotation/convertToOrder",
- method: "post",
- data: data,
- });
-}
-
-// 鏌ヨ瀹㈡埛鍒楄〃
-export function getCustomerList(query) {
- return request({
- url: "/basic/customer/list",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ浜у搧鍒楄〃
-export function getProductList(query) {
- return request({
- url: "/basic/product/list",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ涓氬姟鍛樺垪琛�
-export function getSalespersonList(query) {
- return request({
- url: "/system/user/salespersonList",
- method: "get",
- params: query,
- });
-}
-
-// 瀵煎嚭鎶ヤ环鍗�
-export function exportQuotation(query) {
- return request({
- url: "/sales/quotation/export",
- method: "get",
- params: query,
- responseType: "blob",
- });
-}
-
-// 鎵撳嵃鎶ヤ环鍗�
-export function printQuotation(query) {
- return request({
- url: "/sales/quotation/print",
- method: "get",
- params: query,
- responseType: "blob",
- });
-}
diff --git a/src/api/salesManagement/salespersonManagement.js b/src/api/salesManagement/salespersonManagement.js
deleted file mode 100644
index 5c5cf66..0000000
--- a/src/api/salesManagement/salespersonManagement.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// 閿�鍞彴璐﹂〉闈㈡帴鍙�
-import request from "@/utils/request";
-
-// 鍒嗛〉鏌ヨ
-export function listPage(query) {
- return request({
- url: "/salespersonManagement/listPage",
- method: "get",
- params: query,
- });
-}
-// 鏂板
-export function add(data) {
- return request({
- url: "/salespersonManagement/add",
- method: "post",
- data
- });
-}
-// 淇敼
-export function update(data) {
- return request({
- url: "/salespersonManagement/update",
- method: "post",
- data
- });
-}
-// 鍒犻櫎閿�鍞彴璐�
-export function deleteSalespersonManagement(data) {
- return request({
- url: "/salespersonManagement/delete",
- method: "delete",
- data
- });
-}
\ No newline at end of file
diff --git a/src/api/salesManagement/strategyControl.js b/src/api/salesManagement/strategyControl.js
deleted file mode 100644
index d86864e..0000000
--- a/src/api/salesManagement/strategyControl.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// 绛栫暐绠℃帶椤甸潰鎺ュ彛
-import request from "@/utils/request";
-
-// ========== 浠锋牸绛栫暐閰嶇疆 ==========
-
-// 鍒嗛〉鏌ヨ浠锋牸绛栫暐鍒楄〃
-export function getPriceStrategyList(query) {
- return request({
- url: "/sales/priceStrategy/list",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ浠锋牸绛栫暐璇︽儏
-export function getPriceStrategyDetail(id) {
- return request({
- url: "/sales/priceStrategy/detail",
- method: "get",
- params: { id },
- });
-}
-
-// 鏂板浠锋牸绛栫暐
-export function addPriceStrategy(data) {
- return request({
- url: "/sales/priceStrategy/add",
- method: "post",
- data: data,
- });
-}
-
-// 淇敼浠锋牸绛栫暐
-export function updatePriceStrategy(data) {
- return request({
- url: "/sales/priceStrategy/update",
- method: "post",
- data: data,
- });
-}
-
-// 鍒犻櫎浠锋牸绛栫暐
-export function deletePriceStrategy(id) {
- return request({
- url: "/sales/priceStrategy/delete",
- method: "delete",
- params: { id },
- });
-}
-
-// 鍚敤/绂佺敤浠锋牸绛栫暐
-export function togglePriceStrategy(data) {
- return request({
- url: "/sales/priceStrategy/toggle",
- method: "post",
- data: data,
- });
-}
-
-// ========== 鍚堝悓鎵ц鐩戞帶 ==========
-
-// 鑾峰彇鍚堝悓鎵ц缁熻鏁版嵁
-export function getContractStats(query) {
- return request({
- url: "/sales/contract/stats",
- method: "get",
- params: query,
- });
-}
-
-// 鍒嗛〉鏌ヨ鍚堝悓鎵ц鍒楄〃
-export function getContractExecutionList(query) {
- return request({
- url: "/sales/contract/executionList",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ鍚堝悓鎵ц璇︽儏
-export function getContractExecutionDetail(contractNo) {
- return request({
- url: "/sales/contract/executionDetail",
- method: "get",
- params: { contractNo },
- });
-}
-
-// 鏇存柊鍚堝悓鎵ц杩涘害
-export function updateContractProgress(data) {
- return request({
- url: "/sales/contract/updateProgress",
- method: "post",
- data: data,
- });
-}
-
-// ========== 鍘嗗彶姣斾环鍒嗘瀽 ==========
-
-// 鏌ヨ鍘嗗彶浠锋牸瀵规瘮鏁版嵁
-export function getPriceComparisonList(query) {
- return request({
- url: "/sales/priceComparison/list",
- method: "get",
- params: query,
- });
-}
-
-// 鑾峰彇浠锋牸瓒嬪娍鍥捐〃鏁版嵁
-export function getPriceTrendChart(query) {
- return request({
- url: "/sales/priceComparison/trendChart",
- method: "get",
- params: query,
- });
-}
-
-// 瀵煎嚭鍘嗗彶姣斾环鏁版嵁
-export function exportPriceComparison(query) {
- return request({
- url: "/sales/priceComparison/export",
- method: "get",
- params: query,
- responseType: "blob",
- });
-}
-
-// ========== 鍒╂鼎鍒嗘瀽 ==========
-
-// 鑾峰彇鍒╂鼎缁熻鏁版嵁
-export function getProfitStats(query) {
- return request({
- url: "/sales/profit/stats",
- method: "get",
- params: query,
- });
-}
-
-// 鍒嗛〉鏌ヨ鍒╂鼎鍒嗘瀽鍒楄〃
-export function getProfitAnalysisList(query) {
- return request({
- url: "/sales/profit/analysisList",
- method: "get",
- params: query,
- });
-}
-
-// 鑾峰彇鍒╂鼎瓒嬪娍鍥捐〃鏁版嵁
-export function getProfitTrendChart(query) {
- return request({
- url: "/sales/profit/trendChart",
- method: "get",
- params: query,
- });
-}
-
-// 璁$畻姣涘埄鐜�
-export function calculateGrossProfit(data) {
- return request({
- url: "/sales/profit/calculate",
- method: "post",
- data: data,
- });
-}
-
-// 瀵煎嚭鍒╂鼎鍒嗘瀽鎶ヨ〃
-export function exportProfitAnalysis(query) {
- return request({
- url: "/sales/profit/export",
- method: "get",
- params: query,
- responseType: "blob",
- });
-}
-
-// ========== 鍏叡鎺ュ彛 ==========
-
-// 鏌ヨ瀹㈡埛鍒楄〃锛堢敤浜庝笅鎷夐�夋嫨锛�
-export function getCustomerOptions() {
- return request({
- url: "/basic/customer/options",
- method: "get",
- });
-}
-
-// 鏌ヨ浜у搧鍒楄〃锛堢敤浜庝笅鎷夐�夋嫨锛�
-export function getProductOptions(query) {
- return request({
- url: "/basic/product/options",
- method: "get",
- params: query,
- });
-}
-
-// 鏌ヨ閿�鍞尯鍩熷垪琛�
-export function getRegionOptions() {
- return request({
- url: "/basic/region/options",
- method: "get",
- });
-}
-
diff --git a/src/router/index.js b/src/router/index.js
index e5dc580..16a11e0 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -85,27 +85,27 @@
},
],
},
- {
- path: "/device-info",
- component: () => import("@/views/equipmentManagement/deviceInfo/index.vue"),
- hidden: true,
- name: "DeviceInfo",
- meta: { title: "璁惧淇℃伅", icon: "monitor" },
- },
+ // {
+ // path: "/device-info",
+ // component: () => import("@/views/equipmentManagement/deviceInfo/index.vue"),
+ // hidden: true,
+ // name: "DeviceInfo",
+ // meta: { title: "璁惧淇℃伅", icon: "monitor" },
+ // },
// 娣诲姞椤圭洰璇︽儏椤甸潰璺敱閰嶇疆
- {
- path: "/oaSystem/projectManagement/projectDetail",
- component: Layout,
- hidden: true,
- children: [
- {
- path: ":projectId",
- component: () => import("@/views/oaSystem/projectManagement/projectDetail.vue"),
- name: "ProjectDetail",
- meta: { title: "椤圭洰璇︽儏", activeMenu: "/oaSystem/projectManagement" },
- },
- ],
- },
+ // {
+ // path: "/oaSystem/projectManagement/projectDetail",
+ // component: Layout,
+ // hidden: true,
+ // children: [
+ // {
+ // path: ":projectId",
+ // component: () => import("@/views/oaSystem/projectManagement/projectDetail.vue"),
+ // name: "ProjectDetail",
+ // meta: { title: "椤圭洰璇︽儏", activeMenu: "/oaSystem/projectManagement" },
+ // },
+ // ],
+ // },
];
// 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇
diff --git a/src/views/basicData/customerFile/index.vue b/src/views/basicData/customerFile/index.vue
deleted file mode 100644
index 2d53a72..0000000
--- a/src/views/basicData/customerFile/index.vue
+++ /dev/null
@@ -1,604 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.customerName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <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="info" plain icon="Upload" @click="handleImport"
- >瀵煎叆</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"
- ></PIMTable>
- </div>
- <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"
- >
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="绾崇◣浜鸿瘑鍒彿锛�"
- prop="taxpayerIdentificationNumber"
- >
- <el-input
- v-model="form.taxpayerIdentificationNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍏徃鍦板潃锛�" prop="companyAddress">
- <el-input
- v-model="form.companyAddress"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏徃鐢佃瘽锛�" prop="companyPhone">
- <el-input
- v-model="form.companyPhone"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="閾惰鍩烘湰鎴凤細" prop="basicBankAccount">
- <el-input
- v-model="form.basicBankAccount"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閾惰璐﹀彿锛�" prop="bankAccount">
- <el-input
- v-model="form.bankAccount"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="寮�鎴疯鍙凤細" prop="bankCode">
- <el-input
- v-model="form.bankCode"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30" v-for="(contact, index) in formYYs.contactList" :key="index">
- <el-col :span="12">
- <el-form-item label="鑱旂郴浜猴細" prop="contactPerson">
- <el-input v-model="contact.contactPerson" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactPhone">
- <div style="display: flex; align-items: center;width: 100%;">
- <el-input v-model="contact.contactPhone" placeholder="璇疯緭鍏�" clearable />
- <el-button @click="removeContact(index)" type="danger" circle style="margin-left: 5px;">
- <el-icon><Close /></el-icon>
- </el-button>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- <el-button @click="addNewContact" style="margin-bottom: 10px;">+ 鏂板鑱旂郴浜�</el-button>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="缁存姢浜猴細" prop="maintainer">
- <el-select
- v-model="form.maintainer"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.nickName"
- :label="item.nickName"
- :value="item.nickName"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁存姢鏃堕棿锛�" prop="maintenanceTime">
- <el-date-picker
- style="width: 100%"
- v-model="form.maintenanceTime"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- 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>
- <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
- <el-dialog
- :title="upload.title"
- v-model="upload.open"
- width="400px"
- append-to-body
- >
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url + '?updateSupport=' + upload.updateSupport"
- :disabled="upload.isUploading"
- :before-upload="upload.beforeUpload"
- :on-progress="upload.onProgress"
- :on-success="upload.onSuccess"
- :on-error="upload.onError"
- :on-change="upload.onChange"
- :auto-upload="false"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
- <el-link
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate"
- >涓嬭浇妯℃澘</el-link
- >
- </div>
- </template>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {onMounted, ref} from "vue";
-import { Search } from "@element-plus/icons-vue";
-import {
- addCustomer,
- delCustomer,
- getCustomer,
- listCustomer,
- updateCustomer,
-} from "@/api/basicData/customerFile.js";
-import { ElMessageBox } from "element-plus";
-import { userListNoPage } from "@/api/system/user.js";
-import useUserStore from "@/store/modules/user";
-import { getToken } from "@/utils/auth.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore();
-
-const tableColumn = ref([
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 220,
- },
- {
- label: "绾崇◣浜鸿瘑鍒爜",
- prop: "taxpayerIdentificationNumber",
- width: 220,
- },
- {
- label: "鍦板潃鍙婅仈绯绘柟寮�",
- prop: "addressPhone",
- width: 250,
- },
- {
- label: "鑱旂郴浜�",
- prop: "contactPerson",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "contactPhone",
- width:150
- },
- {
- label: "閾惰鍩烘湰鎴�",
- prop: "basicBankAccount",
- width: 220,
- },
- {
- label: "閾惰璐﹀彿",
- prop: "bankAccount",
- width: 220,
- },
- {
- label: "寮�鎴疯鍙�",
- prop: "bankCode",
- width:220
- },
- {
- label: "缁存姢浜�",
- prop: "maintainer",
- },
- {
- label: "缁存姢鏃堕棿",
- prop: "maintenanceTime",
- width: 100,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const userList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const total = ref(0);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const formYYs = ref({ // 鍏朵粬瀛楁...
- contactList: [
- {
- contactPerson: "",
- contactPhone: ""
- }
- ]
-});
-const data = reactive({
- searchForm: {
- customerName: "",
- },
- form: {
- customerName: "",
- taxpayerIdentificationNumber: "",
- companyAddress: "",
- companyPhone: "",
- contactPerson: "",
- contactPhone: "",
- maintainer: "",
- maintenanceTime: "",
- basicBankAccount: "",
- bankAccount: "",
- bankCode: "",
- },
- rules: {
- customerName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxpayerIdentificationNumber: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- companyAddress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- companyPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- // contactPerson: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- // contactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- maintainer: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
- maintenanceTime: [
- { required: false, message: "璇烽�夋嫨", trigger: "change" },
- ],
- basicBankAccount: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- bankAccount: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- bankCode: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/basic/customer/importData",
- // 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
- beforeUpload: (file) => {
- console.log('鏂囦欢鍗冲皢涓婁紶', file);
- // 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
- const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
- if (!isValid) {
- proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
- }
- return isValid;
- },
- // 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
- onChange: (file, fileList) => {
- console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
- },
- // 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
- onSuccess: (response, file, fileList) => {
- console.log('涓婁紶鎴愬姛', response, file, fileList);
- upload.isUploading = false;
- if(response.code === 200){
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- upload.open = false;
- proxy.$refs["uploadRef"].clearFiles();
- getList();
- }else if(response.code === 500){
- proxy.$modal.msgError(response.msg);
- }else{
- proxy.$modal.msgWarning(response.msg);
- }
- },
- // 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
- onError: (error, file, fileList) => {
- console.error('涓婁紶澶辫触', error, file, fileList);
- upload.isUploading = false;
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- },
- // 鏂囦欢涓婁紶杩涘害鍥炶皟
- onProgress: (event, file, fileList) => {
- console.log('涓婁紶涓�...', event.percent);
- }
-});
-const { searchForm, form, rules } = toRefs(data);
-const addNewContact = () => {
- formYYs.value.contactList.push({
- contactPerson: "",
- contactPhone: ""
- });
-};
-
-const removeContact = (index) => {
- if (formYYs.value.contactList.length > 1) {
- formYYs.value.contactList.splice(index, 1);
- }
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- listCustomer({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- page.total = res.total;
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- upload.isUploading = true;
- proxy.$refs["uploadRef"].submit();
-}
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "瀹㈡埛瀵煎叆";
- upload.open = true;
-}
-/** 涓嬭浇妯℃澘 */
-function importTemplate() {
- proxy.download("/basic/customer/downloadTemplate", {}, "瀹㈡埛瀵煎叆妯℃澘.xlsx");
-}
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- operationType.value = type;
- form.value = {};
- form.value.maintainer = userStore.nickName;
- formYYs.value.contactList = [
- {
- contactPerson: "",
- contactPhone: ""
- }
- ];
- form.value.maintenanceTime = getCurrentDate();
- userListNoPage().then((res) => {
- userList.value = res.data;
- });
- if (type === "edit") {
- getCustomer(row.id).then((res) => {
- form.value = { ...res.data };
- formYYs.value.contactList = res.data.contactPerson.split(",").map((item, index) => {
- return {
- contactPerson: item,
- contactPhone: res.data.contactPhone.split(",")[index]
- }
- });
-
- });
- }
- dialogFormVisible.value = true;
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- if (operationType.value === "edit") {
- submitEdit();
- } else {
- submitAdd();
- }
- }
- });
-};
-// 鎻愪氦鏂板
-const submitAdd = () => {
- if(formYYs.value.contactList.length < 1){
- return proxy.$modal.msgWarning("璇疯嚦灏戞坊鍔犱竴涓仈绯讳汉");
- }
- form.value.contactPerson = formYYs.value.contactList.map(item => item.contactPerson).join(",");
- form.value.contactPhone = formYYs.value.contactList.map(item => item.contactPhone).join(",");
- addCustomer(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鎻愪氦淇敼
-const submitEdit = () => {
- form.value.contactPerson = formYYs.value.contactList.map(item => item.contactPerson).join(",");
- form.value.contactPhone = formYYs.value.contactList.map(item => item.contactPhone).join(",");
- updateCustomer(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/basic/customer/export", {}, "瀹㈡埛妗f.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.maintainer !== userStore.nickName);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delCustomer(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/basicData/product/ImportExcel/index.vue b/src/views/basicData/product/ImportExcel/index.vue
deleted file mode 100644
index c25d254..0000000
--- a/src/views/basicData/product/ImportExcel/index.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-<template>
- <el-button type="info" plain icon="Upload" @click="handleImport">
- 瀵煎叆
- </el-button>
- <el-dialog v-model="upload.open" :title="upload.title">
- <FileUpload
- ref="fileUploadRef"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url + '?updateSupport=' + upload.updateSupport"
- :disabled="upload.isUploading"
- :showTip="false"
- @success="handleFileSuccess"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { reactive } from "vue";
-import { getToken } from "@/utils/auth.js";
-import { FileUpload } from "@/components/Upload";
-import { ElMessage } from "element-plus";
-
-defineOptions({
- name: "浜у搧缁存姢瀵煎叆",
-});
-
-const emits = defineEmits(["uploadSuccess"]);
-const fileUploadRef = ref();
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙渚涘簲鍟嗗鍏ワ級
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
-});
-// 鐐瑰嚮瀵煎叆
-const handleImport = () => {
- upload.open = true;
- upload.title = "浜у搧瀵煎叆";
-};
-
-const submitFileForm = () => {
- fileUploadRef.value.uploadApi();
-};
-
-const handleFileSuccess = (response) => {
- const { code, msg } = response;
- if (code == 200) {
- ElMessage({ message: "瀵煎叆鎴愬姛", type: "success" });
- upload.open = false;
- emits("uploadSuccess");
- } else {
- ElMessage({ message: msg, type: "error" });
- }
-};
-</script>
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
deleted file mode 100644
index b88d678..0000000
--- a/src/views/basicData/product/index.vue
+++ /dev/null
@@ -1,500 +0,0 @@
-<template>
- <div class="app-container product-view">
- <div class="left">
- <div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
- clearable
- prefix-icon="Search"
- />
- <el-button
- type="primary"
- @click="openProDia('addOne')"
- style="margin-left: 10px"
- >鏂板浜у搧澶х被</el-button
- >
- </div>
- <div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="list"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- default-expand-all
- :default-expanded-keys="expandedKeys"
- :draggable="true"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'label' }"
- highlight-current
- node-key="id"
- style="
- height: calc(100vh - 190px);
- overflow-y: scroll;
- scrollbar-width: none;
- "
- >
- <template #default="{ node, data }">
- <div class="custom-tree-node">
- <span class="tree-node-content">
- <el-icon class="orange-icon">
- <component :is="data.children && data.children.length > 0
- ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
- </el-icon>
- {{ data.label }}
- </span>
- <div>
- <el-button
- type="primary"
- link
- @click="openProDia('edit', data)"
- >
- 缂栬緫
- </el-button>
- <el-button type="primary" link @click="openProDia('add', data)" :disabled="node.level >= 3">
- 娣诲姞浜у搧
- </el-button>
- <el-button
- v-if="!node.childNodes.length"
- style="margin-left: 4px"
- type="danger"
- link
- @click="remove(node, data)"
- >
- 鍒犻櫎
- </el-button>
- </div>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- <div class="right">
- <div style="margin-bottom: 10px" v-if="isShowButton">
- <el-button type="primary" @click="openModelDia('add')">
- 鏂板瑙勬牸鍨嬪彿
- </el-button>
- <ImportExcel @uploadSuccess="getModelList" />
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- >
- 鍒犻櫎
- </el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
- </div>
- <el-dialog v-model="productDia" title="浜у搧" width="400px" @keydown.enter.prevent>
- <el-form
- :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef"
- >
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="浜у搧鍚嶇О锛�" prop="productName">
- <el-input
- v-model="form.productName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- clearable
- @keydown.enter.prevent
- />
- </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="closeProDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <el-dialog
- v-model="modelDia"
- title="瑙勬牸鍨嬪彿"
- width="400px"
- @close="closeModelDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="modelForm"
- label-width="140px"
- label-position="top"
- :rules="modelRules"
- ref="modelFormRef"
- >
- <el-row>
- <el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
- <el-input
- v-model="modelForm.model"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- clearable
- @keydown.enter.prevent
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="modelForm.unit"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- @keydown.enter.prevent
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitModelForm">纭</el-button>
- <el-button @click="closeModelDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import {
- addOrEditProduct,
- addOrEditProductModel,
- delProduct,
- delProductModel,
- modelListPage,
- productTreeList,
-} from "@/api/basicData/product.js";
-import ImportExcel from "./ImportExcel/index.vue";
-
-const { proxy } = getCurrentInstance();
-const tree = ref(null);
-const containerRef = ref(null);
-
-const productDia = ref(false);
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const search = ref("");
-const currentId = ref("");
-const currentParentId = ref("");
-const operationType = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const tableColumn = ref([
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "model",
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openModelDia("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const isShowButton = ref(false);
-const selectedRows = ref([]);
-const page = reactive({
- current: 1,
- size: 10,
- total: 0,
-});
-const data = reactive({
- form: {
- productName: "",
- },
- rules: {
- productName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
- modelForm: {
- model: "",
- unit: "",
- },
- modelRules: {
- model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules, modelForm, modelRules } = toRefs(data);
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
- treeLoad.value = true;
- productTreeList()
- .then((res) => {
- list.value = res;
- list.value.forEach((a) => {
- expandedKeys.value.push(a.label);
- });
- treeLoad.value = false;
- })
- .catch((err) => {
- treeLoad.value = false;
- });
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
- proxy.$refs.tree.filter(search.value);
-};
-// 鎵撳紑浜у搧寮规
-const openProDia = (type, data) => {
- operationType.value = type;
- productDia.value = true;
- form.value.productName = "";
- if (type === "edit") {
- form.value.productName = data.productName;
- }
-};
-// 鎵撳紑瑙勬牸鍨嬪彿寮规
-const openModelDia = (type, data) => {
- modelOperationType.value = type;
- modelDia.value = true;
- modelForm.value.model = "";
- modelForm.value.model = "";
- modelForm.value.id = "";
- if (type === "edit") {
- modelForm.value = { ...data };
- }
-};
-// 鎻愪氦浜у搧鍚嶇О淇敼
-const submitForm = () => {
- proxy.$refs.formRef.validate((valid) => {
- if (valid) {
- if (operationType.value === "add") {
- form.value.parentId = currentId.value;
- form.value.id = "";
- } else if (operationType.value === "addOne") {
- form.value.id = "";
- form.value.parentId = "";
- } else {
- form.value.id = currentId.value;
- form.value.parentId = "";
- }
- addOrEditProduct(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProDia();
- getProductTreeList();
- });
- }
- });
-};
-// 鍏抽棴浜у搧寮规
-const closeProDia = () => {
- proxy.$refs.formRef.resetFields();
- productDia.value = false;
-};
-
-// 鍒犻櫎浜у搧
-const remove = (node, data) => {
- let ids = [];
- ids.push(data.id);
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delProduct(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getProductTreeList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
- // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
- isShowButton.value = !(val.children && val.children.length > 0);
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
- getModelList();
-};
-
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
- proxy.$refs.modelFormRef.validate((valid) => {
- if (valid) {
- modelForm.value.productId = currentId.value;
- addOrEditProductModel(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- });
- }
- });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
- proxy.$refs.modelFormRef.resetFields();
- modelDia.value = false;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ瑙勬牸鍨嬪彿
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getModelList();
-};
-const getModelList = () => {
- tableLoading.value = true;
- modelListPage({
- id: currentId.value,
- current: page.current,
- size: page.size,
- }).then((res) => {
- console.log("res", res);
- tableData.value = res.records;
- page.total = res.total;
- tableLoading.value = false;
- });
-};
-// 鍒犻櫎瑙勬牸鍨嬪彿
-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(() => {
- tableLoading.value = true;
- delProductModel(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getModelList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
- if (!value) {
- //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
- return true;
- }
- // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
- let val = value.toLowerCase();
- return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
- if (data.label.indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
- if (level === 1) {
- return false;
- }
- // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let parentData = node.parent;
- // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let index = 0;
- while (index < level - 1) {
- // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
- if (parentData.data.label.indexOf(value) !== -1) {
- return true;
- }
- // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
- parentData = parentData.parent;
- index++;
- }
- // 娌″尮閰嶅埌杩斿洖false
- return false;
-};
-getProductTreeList();
-</script>
-
-<style scoped>
-.product-view {
- display: flex;
-}
-.left {
- width: 380px;
- padding: 16px;
- background: #ffffff;
-}
-.right {
- width: calc(100% - 380px);
- padding: 16px;
- margin-left: 20px;
- background: #ffffff;
-}
-.custom-tree-node {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
-}
-.tree-node-content {
- display: flex;
- align-items: center; /* 鍨傜洿灞呬腑 */
- height: 100%;
-}
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
-}
-</style>
diff --git a/src/views/basicData/supplierManage/index.vue b/src/views/basicData/supplierManage/index.vue
deleted file mode 100644
index 5d55907..0000000
--- a/src/views/basicData/supplierManage/index.vue
+++ /dev/null
@@ -1,542 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗘。妗堬細</span>
- <el-input
- v-model="searchForm.supplierName"
- style="width: 240px"
- placeholder="杈撳叆渚涘簲鍟嗗悕绉版悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <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="info" plain icon="Upload" @click="handleImport"
- >瀵煎叆</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"
- ></PIMTable>
- </div>
- <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"
- >
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input
- v-model="form.supplierName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="绾崇◣浜鸿瘑鍒彿锛�"
- prop="taxpayerIdentificationNum"
- >
- <el-input
- v-model="form.taxpayerIdentificationNum"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍏徃鍦板潃锛�" prop="companyAddress">
- <el-input
- v-model="form.companyAddress"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏徃鐢佃瘽锛�" prop="companyPhone">
- <el-input
- v-model="form.companyPhone"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="寮�鎴疯锛�" prop="bankAccountName">
- <el-input
- v-model="form.bankAccountName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璐﹀彿锛�" prop="bankAccountNum">
- <el-input
- v-model="form.bankAccountNum"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鑱旂郴浜猴細" prop="contactUserName">
- <el-input
- v-model="form.contactUserName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactUserPhone">
- <el-input
- v-model="form.contactUserPhone"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="缁存姢浜猴細" prop="maintainUserId">
- <el-select
- v-model="form.maintainUserId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.nickName"
- :label="item.nickName"
- :value="item.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁存姢鏃堕棿锛�" prop="maintainTime">
- <el-date-picker
- style="width: 100%"
- v-model="form.maintainTime"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- 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>
-
- <!-- 渚涘簲鍟嗗鍏ュ璇濇 -->
- <el-dialog
- :title="upload.title"
- v-model="upload.open"
- width="400px"
- append-to-body
- >
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url + '?updateSupport=' + upload.updateSupport"
- :disabled="upload.isUploading"
- :on-progress="handleFileUploadProgress"
- :on-success="handleFileSuccess"
- :on-error="handleFileError"
- :auto-upload="false"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
- <el-link
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate"
- >涓嬭浇妯℃澘</el-link
- >
- </div>
- </template>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { onMounted, ref } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { delSupplier } from "@/api/basicData/supplierManageFile.js";
-import { ElMessageBox } from "element-plus";
-import { userListNoPage } from "@/api/system/user.js";
-import {
- addSupplier,
- getSupplier,
- listSupplier,
- updateSupplier,
-} from "@/api/basicData/supplierManageFile.js";
-import useUserStore from "@/store/modules/user";
-import { getToken } from "@/utils/auth.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore();
-
-const tableColumn = ref([
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width: 250,
- },
- {
- label: "绾崇◣浜鸿瘑鍒彿",
- prop: "taxpayerIdentificationNum",
- width: 230,
- },
- {
- label: "鍏徃鍦板潃",
- prop: "companyAddress",
- width: 220,
- },
- {
- label: "鑱旂郴鏂瑰紡",
- prop: "companyPhone",
- width:150
- },
- {
- label: "寮�鎴疯",
- prop: "bankAccountName",
- width: 220,
- },
- {
- label: "璐﹀彿",
- prop: "bankAccountNum",
- width: 220,
- },
- {
- label: "鑱旂郴浜�",
- prop: "contactUserName",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "contactUserPhone",
- width: 150,
- },
- {
- label: "缁存姢浜�",
- prop: "maintainUserName",
- },
-
- {
- label: "缁存姢鏃堕棿",
- prop: "maintainTime",
- width:100
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const userList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- supplierName: "",
- },
- form: {
- supplierName: "",
- taxpayerIdentificationNum: "",
- companyAddress: "",
- companyPhone: "",
- bankAccountName: "",
- bankAccountNum: "",
- contactUserName: "",
- contactUserPhone: "",
- maintainUserId: "",
- maintainTime: "",
- },
- rules: {
- supplierName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxpayerIdentificationNum: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- companyAddress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- companyPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- bankAccountName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- bankAccountNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contactUserName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- contactUserPhone: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- maintainUserId: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
- maintainTime: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { searchForm, form, rules } = toRefs(data);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- upload.isUploading = true;
- proxy.$refs["uploadRef"].submit();
-}
-const getList = () => {
- tableLoading.value = true;
- listSupplier({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙渚涘簲鍟嗗鍏ワ級
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
- updateSupport: 1,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
-});
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "渚涘簲鍟嗗鍏�";
- upload.open = true;
-}
-/** 涓嬭浇妯℃澘 */
-function importTemplate() {
- proxy.download("/system/supplier/downloadTemplate", {}, "渚涘簲鍟嗗鍏ユā鏉�.xlsx");
-}
-
-/**鏂囦欢涓婁紶涓鐞� */
-const handleFileUploadProgress = (event, file, fileList) => {
- upload.isUploading = true;
-};
-
-/** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
-const handleFileSuccess = (response, file, fileList) => {
- upload.isUploading = false;
- if(response.code === 200){
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- upload.open = false;
- proxy.$refs["uploadRef"].clearFiles();
- getList();
- }else if(response.code === 500){
- proxy.$modal.msgError(response.msg);
- }else{
- proxy.$modal.msgWarning(response.msg);
- }
-};
-
-/** 鏂囦欢涓婁紶澶辫触澶勭悊 */
-const handleFileError = (error, file, fileList) => {
- upload.isUploading = false;
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- operationType.value = type;
- form.value = {};
- form.value.maintainUserId = userStore.id;
- form.value.maintainTime = getCurrentDate();
- userListNoPage().then((res) => {
- userList.value = res.data;
- });
- if (type === "edit") {
- getSupplier(row.id).then((res) => {
- form.value = { ...res.data };
- });
- }
- dialogFormVisible.value = true;
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- if (operationType.value === "edit") {
- submitEdit();
- } else {
- submitAdd();
- }
- }
- });
-};
-// 鎻愪氦鏂板
-const submitAdd = () => {
- addSupplier(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鎻愪氦淇敼
-const submitEdit = () => {
- updateSupplier(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/system/supplier/export", {}, "渚涘簲鍟嗘。妗�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delSupplier(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/chatHome/chatHomeIndex/MobileChat.vue b/src/views/chatHome/chatHomeIndex/MobileChat.vue
deleted file mode 100644
index adeb5e7..0000000
--- a/src/views/chatHome/chatHomeIndex/MobileChat.vue
+++ /dev/null
@@ -1,461 +0,0 @@
-<template>
- <div class="mobile-chat-wrapper" style="height: 91vh;">
- <div class="chat-history">
- <div class="chat-content" ref="chatContent">
- <div class="chat-wrapper" v-for="(item, index) in chatList" :key="index">
- <div class="chat-friend" v-if="item.uid !== '1001'">
- <div class="info-time">
- <img :src="item.headImg" alt="" />
- <span>{{ item.name }}</span>
- <span>{{ item.time }}</span>
- </div>
- <div class="chat-text" v-if="item.chatType == 0">
- <template v-if="isSend && index === chatList.length - 1">
- <span class="flash_cursor"></span>
- </template>
- <template v-else>
- <pre style="font-family: none;">{{ item.msg }}</pre>
- </template>
- </div>
- <div class="chat-img" v-if="item.chatType == 1">
- <img :src="item.msg" alt="琛ㄦ儏" v-if="item.extend.imgType == 1" style="width: 100px; height: 100px" />
- <el-image :src="item.msg" :preview-src-list="srcImgList" v-else> </el-image>
- </div>
- <div class="chat-img" v-if="item.chatType == 2">
- <div class="word-file">
- <FileCard :fileType="item.extend.fileType" :file="item.msg"></FileCard>
- </div>
- </div>
- </div>
- <div class="chat-me" v-else>
- <div class="info-time">
- <span>{{ item.name }}</span>
- <span>{{ item.time }}</span>
- <img :src="item.headImg" alt="" />
- </div>
- <div class="chat-text" v-if="item.chatType == 0">
- {{ item.msg }}
- </div>
- <div class="chat-img" v-if="item.chatType == 1">
- <img :src="item.msg" alt="琛ㄦ儏" v-if="item.extend.imgType == 1" style="width: 100px; height: 100px" />
- <el-image style="max-width: 300px; border-radius: 10px" :src="item.msg" :preview-src-list="srcImgList" v-else> </el-image>
- </div>
- <div class="chat-img" v-if="item.chatType == 2">
- <div class="word-file">
- <FileCard :fileType="item.extend.fileType" :file="item.msg"></FileCard>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="chat-input-wrapper">
- <div style="display: flex; align-items: center">
- <input v-model="inputMsg" @change="sendText" :disabled="loading" class="input-text" autofocus placeholder="缁欏皬鏅哄彂閫佹秷鎭�" />
- <img class="send-icon" src="@/assets/img/emoji/rocket.png" alt="" @click="sendText" />
-
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick,onActivated } from 'vue'
-import { useRoute } from 'vue-router'
-import { animation } from '@/utils/util'
-import chatGPTHeadImg from '@/assets/img/head_portrait1.png'
-import headPortrait from '@/assets/img/head_portrait.jpg'
-import FileCard from '@/components/FileCard.vue'
-import { ElMessage } from "element-plus"
-import {checking} from './ai-wd.js'
-
-// 瀹氫箟鍝嶅簲寮忔暟鎹�
-const route = useRoute()
-const chatContent = ref(null)
-const ws = ref(null)
-const chatList = ref([
- {
- headImg: chatGPTHeadImg,
- name: '灏忔櫤',
- time: new Date().toLocaleTimeString(),
- msg: ' 灏忔櫤涓烘偍鏈嶅姟',
- chatType: 0,
- uid: '1002'
- }
-])
-const inputMsg = ref('')
-const isSend = ref(false)
-const fileList = ref([])
-const isProcessing = ref(false)
-const loading = ref(true)
-const srcImgList = ref([])
-
-// 鍒犻櫎鍥剧墖
-const deleteImg = (index) => {
- if (index >= 0 && index < fileList.value.length) {
- fileList.value.splice(index, 1)
- }
-}
-
-// WebSocket娑堟伅鎺ユ敹
-const websocketonmessage = (e) => {
- const redata = JSON.parse(e.data)
- //鏁版嵁鎺ユ敹
- let chatGPT = {
- headImg: headPortrait,
- name: 'DeepSeek',
- time: new Date().toLocaleTimeString(),
- msg: redata[0].text,
- chatType: 0, //淇℃伅绫诲瀷锛�0鏂囧瓧锛�1鍥剧墖
- uid: '1002' //uid
- }
- sendMsg(chatGPT)
- isSend.value = false
-}
-
-// WebSocket鍙戦�佹秷鎭�
-const websocketsend = (Data) => {
- console.log("鍗冲皢鍙戦�佹秷鎭�", Data)
- if (ws.value && ws.value.readyState === WebSocket.OPEN) {
- console.log("鍙戦�佹秷鎭�", ws.value)
- console.log("鍙戦�佹秷鎭�", Data)
- let fileUrls = fileList.value.map(item => item.file.fileUrl)
- //鏁版嵁鍙戦��
- ws.value.send(Data + ":" + fileUrls.join(","))
- fileList.value = []
- inputMsg.value = ''
- }
-}
-
-// 鍙戦�佹枃鏈秷鎭�
-const sendText = () => {
- if (inputMsg.value) {
- let chatMsg = {
- headImg: headPortrait,
- name: '鍗ч緳',
- time: new Date().toLocaleTimeString(),
- msg: inputMsg.value,
- chatType: 0, //淇℃伅绫诲瀷锛�0鏂囧瓧锛�1鍥剧墖
- uid: '1001' //uid
- }
- chatList.value.push(chatMsg)
- let chatGPT = {
- headImg: chatGPTHeadImg,
- name: '灏忔櫤',
- time: new Date().toLocaleTimeString(),
- msg: "",
- chatType: 0, //淇℃伅绫诲瀷锛�0鏂囧瓧锛�1鍥剧墖
- uid: '1002' //uid
- }
- chatList.value.push(chatGPT) // 灏嗘帴鏀跺埌鐨勬秷鎭瓨鍌ㄥ埌 messages 鏁扮粍
- simulateStreamingOutput(chatGPT, inputMsg.value)
- inputMsg.value = ''
-
- } else {
- ElMessage({
- message: '娑堟伅涓嶈兘涓虹┖鍝',
- type: 'warning'
- })
- }
-}
-
-// 鍙戦�佷俊鎭�
-const sendMsg = (msgList) => {
- chatList.value.push(msgList)
- scrollBottom()
-}
-
-// 鑾峰彇绐楀彛楂樺害骞舵粴鍔ㄨ嚦鏈�搴曞眰
-const scrollBottom = () => {
- nextTick(() => {
- const scrollDom = chatContent.value
- animation(scrollDom, scrollDom.scrollHeight - scrollDom.offsetHeight)
- })
-}
-
-// 缁勪欢鎸傝浇鏃舵墽琛�
-onActivated(() => {
- chatList.value = []
- chatList.value.push({
- headImg: chatGPTHeadImg,
- name: '灏忔櫤',
- time: new Date().toLocaleTimeString(),
- msg: '灏忔櫤涓烘偍鏈嶅姟',
- chatType: 0,
- uid: '1002'
- })
- chatList.value.push({
- headImg: headPortrait,
- name: '鍗ч緳',
- time: new Date().toLocaleTimeString(),
- msg: route.query.keyWord,
- chatType: 0,
- uid: '1001'
- })
- // 娣诲姞涓�涓┖鐨勫洖澶嶆秷鎭崰浣�
- const replyMsg = {
- headImg: chatGPTHeadImg,
- name: '灏忔櫤',
- time: new Date().toLocaleTimeString(),
- msg: '',
- chatType: 0,
- uid: '1002'
- }
- chatList.value.push(replyMsg)
- scrollBottom()
- loading.value = false
- // 濡傛灉鏈夋煡璇㈠叧閿瓧锛屽垯妯℃嫙娴佸紡杈撳嚭
- if (route.query.keyWord) {
- simulateStreamingOutput(replyMsg, route.query.keyWord)
- }
-})
-// 妯℃嫙娴佸紡杈撳嚭
-const simulateStreamingOutput = async (msgObj, keyWord) => {
- loading.value = true
- // 鐢熸垚0.8-1.3绉掍箣闂寸殑闅忔満寤惰繜
- const delay = Math.random() * 500 + 800
-
- // 妯℃嫙鍥炲鍐呭锛堝疄闄呭簲鐢ㄤ腑搴斾粠API鑾峰彇锛�
- const responseText = `鍏充簬"${keyWord}"鐨勯棶棰橈紝鎴戞潵涓烘偍瑙g瓟锛歕n` + checking(keyWord)
-
- isSend.value = true
-
- let index = 0
- setTimeout(() => {
- const interval = setInterval(() => {
- isSend.value = true
- if (index < responseText.length) {
- msgObj.msg += responseText.charAt(index)
- index++
- isSend.value = false
- scrollBottom()
- } else {
- clearInterval(interval)
- isSend.value = false
- loading.value = false
- }
- }, 50) // 姣�50ms杈撳嚭涓�涓瓧绗︼紝妯℃嫙娴佸紡鏁堟灉
- }, delay)
-
-}
-</script>
-
-<style lang="scss" scoped>
-.mobile-chat-wrapper {
- display: flex;
- flex-direction: column;
- overflow: hidden;
- height: 91vh;
- position: relative;
- background-color: white;
-
- .chat-history {
- flex: 1 1 0;
- overflow-y: auto;
- }
-
- .chat-input-wrapper {
- padding: 8px 16px 8px 8px;
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- .file-tt{
- flex-direction: column;
- width: 200px;
- display: flex;
- padding: 5px;
- border-radius: 5px;
- margin-right: 5px;
- background: #cacaca;
- .file-item{
- width: 200px;
- overflow:hidden;
- word-wrap: break-word;
- text-overflow:ellipsis;
- display:-webkit-box;
- -webkit-box-orient:vertical;
- -webkit-line-clamp:2;
- }
- }
-
- .send-icon {
- height: 40px;
- margin-left: 16px;
- }
- .input-text{
- font-size: 18px;
- width: 100%;
- border-radius: 20px;
- height: 80px;
- padding-left: 10px;
- //padding-top: 10px;
- border: none;
- color: black; /* 淇敼鏂囨湰棰滆壊涓虹櫧鑹� */
- background-color: #f5f4f4; /* 淇敼鑳屾櫙棰滆壊涓烘繁鐏拌壊 */
- }
- }
-
- .chat-content {
- width: 100%;
- height: 80%;
- overflow-y: scroll;
- padding: 20px;
- box-sizing: border-box;
-
- &::-webkit-scrollbar {
- width: 0;
- /* Safari,Chrome 闅愯棌婊氬姩鏉� */
- height: 0;
- /* Safari,Chrome 闅愯棌婊氬姩鏉� */
- display: none;
- /* 绉诲姩绔�乸ad 涓奡afari锛孋hrome锛岄殣钘忔粴鍔ㄦ潯 */
- }
-
- .chat-wrapper {
- position: relative;
- word-break: break-all;
-
- .chat-friend {
- width: 100%;
- float: left;
- margin-bottom: 20px;
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- align-items: flex-start;
-
- .chat-text {
- max-width: 90%;
- padding: 20px;
- border-radius: 20px 20px 20px 5px;
- background-color: rgb(245, 248, 248);
- color: black;
-
- &:hover {
- background-color: rgb(232, 232, 232);
- }
-
- pre {
- white-space: break-spaces;
- }
- }
-
- .chat-img {
- img {
- width: 100px;
- height: 100px;
- }
- }
-
- .info-time {
- margin: 10px 0;
- color: black;
- font-size: 14px;
-
- img {
- width: 30px;
- height: 30px;
- border-radius: 50%;
- vertical-align: middle;
- margin-right: 10px;
- }
-
- span:last-child {
- color: rgb(101, 104, 115);
- margin-left: 10px;
- vertical-align: middle;
- }
- }
- }
-
- .chat-me {
- width: 100%;
- float: right;
- margin-bottom: 20px;
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: flex-end;
- align-items: flex-end;
-
- .chat-text {
- float: right;
- max-width: 90%;
- padding: 20px;
- border-radius: 20px 20px 5px 20px;
- background-color: rgb(29, 144, 245);
- color: #fff;
-
- &:hover {
- background-color: rgb(26, 129, 219);
- }
- }
-
- .chat-img {
- img {
- max-width: 300px;
- max-height: 200px;
- border-radius: 10px;
- }
- }
-
- .info-time {
- margin: 10px 0;
- color: black;
- font-size: 14px;
- display: flex;
- justify-content: flex-end;
-
- img {
- width: 30px;
- height: 30px;
- border-radius: 50%;
- vertical-align: middle;
- margin-left: 10px;
- }
-
- span {
- line-height: 30px;
- }
-
- span:first-child {
- color: rgb(101, 104, 115);
- margin-right: 10px;
- vertical-align: middle;
- }
- }
- }
- }
- }
- .flash_cursor {
- width: 20px;
- height: 30px;
- display: inline-block;
- background: #d6e3f5;
- opacity: 1;
- animation: glow 800ms ease-out infinite alternate;
- }
- @keyframes glow {
- 0% {
- opacity: 1;
- }
-
- 25% {
- opacity: 0.5;
- }
-
- 50% {
- opacity: 0;
- }
-
- 75% {
- opacity: 0.5;
- }
-
- 100% {
- opacity: 1;
- }
- }
-}
-</style>
diff --git a/src/views/chatHome/chatHomeIndex/ai-jz.js b/src/views/chatHome/chatHomeIndex/ai-jz.js
deleted file mode 100644
index 02ee6dc..0000000
--- a/src/views/chatHome/chatHomeIndex/ai-jz.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export function jam() {
- return ""
-}
\ No newline at end of file
diff --git a/src/views/chatHome/chatHomeIndex/ai-wd.js b/src/views/chatHome/chatHomeIndex/ai-wd.js
deleted file mode 100644
index c5b83d5..0000000
--- a/src/views/chatHome/chatHomeIndex/ai-wd.js
+++ /dev/null
@@ -1,393 +0,0 @@
-export function gasLeaks() {
- return "1. 璁捐涓庤澶囬�夋嫨\n" +
- "閫夌敤楂樿川閲忔潗鏂欙細绠¢亾銆侀榾闂ㄣ�佸偍缃愮瓑璁惧搴旈�夌敤鑰愯厫铓�銆佽�愰珮鍘嬬殑鏉愭枡锛屽苟绗﹀悎瀹夊叏鏍囧噯锛堝ASME銆丄PI绛夛級銆俓n" +
- "\n" +
- "瀹夊叏璁捐锛歕n" +
- "\n" +
- "瀹夎鍐椾綑鐨勫畨鍏ㄨ缃紙濡傚弻閲嶉榾闂ㄣ�佺垎鐮寸墖銆佸畨鍏ㄩ榾绛夛級銆俓n" +
- "\n" +
- "璁剧疆姘斾綋娉勬紡妫�娴嬬郴缁燂紙濡傚彲鐕冩皵浣撴姤璀﹀櫒銆佹湁姣掓皵浣撲紶鎰熷櫒锛夈�俓n" +
- "\n" +
- "閲囩敤灏侀棴寮忕郴缁熻璁★紝鍑忓皯寮�鏀炬帴鍙c�俓n" +
- "\n" +
- "閫氶绯荤粺锛氬湪鍙兘娉勬紡鐨勫尯鍩熷畨瑁呭己鍒堕�氶璁惧锛岄槻姝㈡皵浣撹仛闆嗐�俓n" +
- "\n" +
- "2. 瀹夎涓庣淮鎶n" +
- "瑙勮寖瀹夎锛氱敱涓撲笟浜哄憳杩涜璁惧瀹夎锛岀‘淇濈閬撶剨鎺ャ�佸瘑灏佺瓑鐜妭鏃犵己闄枫�俓n" +
- "\n" +
- "瀹氭湡妫�鏌ワ細\n" +
- "\n" +
- "瀵圭閬撱�侀榾闂ㄣ�佽繛鎺ュ杩涜娉勬紡妫�娴嬶紙濡傚帇鍔涙祴璇曘�佽秴澹版尝妫�娴嬨�佽偉鐨傛按妫�婕忥級銆俓n" +
- "\n" +
- "鏇存崲鑰佸寲鎴栬厫铓�鐨勯儴浠躲�俓n" +
- "\n" +
- "棰勯槻鎬х淮鎶わ細鍒跺畾缁存姢璁″垝锛屽畾鏈熸鼎婊戦榾闂ㄣ�佹洿鎹㈠瘑灏佷欢绛夈�俓n" +
- "\n" +
- "3. 鎿嶄綔绠$悊\n" +
- "涓ユ牸鎿嶄綔瑙勭▼锛歕n" +
- "\n" +
- "鎿嶄綔浜哄憳闇�鍩硅涓婂矖锛岀啛鎮夋皵浣撶壒鎬у拰搴旀�ユ祦绋嬨�俓n" +
- "\n" +
- "閬垮厤瓒呭帇銆佽秴娓╂垨閿欒鎿嶄綔銆俓n" +
- "\n" +
- "鐩戞帶绯荤粺锛歕n" +
- "\n" +
- "瀹炴椂鐩戞祴鍘嬪姏銆佹俯搴︺�佹祦閲忕瓑鍙傛暟锛岃缃嚜鍔ㄦ姤璀﹀拰鑱旈攣鍋滄満瑁呯疆銆俓n" +
- "\n" +
- "浣跨敤姘斾綋妫�娴嬩华锛堝绾㈠銆佺數鍖栧浼犳劅鍣級鐩戞祴鐜娴撳害銆俓n" +
- "\n" +
- "鏄庣‘鏍囪瘑锛氬湪鍗遍櫓鍖哄煙鏍囨槑姘斾綋绫诲瀷銆侀闄╃瓑绾у強闃叉姢瑕佹眰銆俓n" +
- "\n" +
- "4. 娉勬紡搴旀�ユ帾鏂絓n" +
- "搴旀�ヨ澶囷細\n" +
- "\n" +
- "閰嶅闃叉瘨闈㈠叿銆佸懠鍚稿櫒銆侀槻鎶ゆ湇绛変釜浜洪槻鎶よ澶囷紙PPE锛夈�俓n" +
- "\n" +
- "灏辫繎鏀剧疆娉勬紡搴旀�ュ寘锛堝鍫垫紡鑳躲�佸瘑灏佸甫锛夈�俓n" +
- "\n" +
- "绱ф�ュ搷搴旓細\n" +
- "\n" +
- "绔嬪嵆鍒囨柇姘旀簮锛堝叧闂笂娓搁榾闂ㄦ垨鍚姩绱ф�ュ垏鏂郴缁燂級銆俓n" +
- "\n" +
- "鍚姩閫氶璁惧绋�閲婃皵浣撴祿搴︺�俓n" +
- "\n" +
- "鐤忔暎浜哄憳骞朵笂鎶ヤ笓涓氶儴闂紙濡傛秷闃层�佺幆淇濓級銆俓n" +
- "\n" +
- "搴旀�ラ妗堬細瀹氭湡婕旂粌娉勬紡澶勭疆娴佺▼锛岀‘淇濅汉鍛樼啛鎮夊垎宸ャ�俓n" +
- "\n" +
- "5. 鍌ㄥ瓨涓庤繍杈撳畨鍏╘n" +
- "鍌ㄥ瓨瑕佹眰锛歕n" +
- "\n" +
- "鍌ㄧ綈杩滅鐏簮銆侀珮娓╁尯锛屽苟璁剧疆鍥村牥闃叉鎵╂暎銆俓n" +
- "\n" +
- "娑插寲姘斾綋鍌ㄧ綈闇�閰嶅娉勫帇瑁呯疆銆俓n" +
- "\n" +
- "杩愯緭瀹夊叏锛歕n" +
- "\n" +
- "浣跨敤鍚堣鐨勮繍杈撹溅杈嗭紝鍥哄畾姘旂摱闃叉纰版挒銆俓n" +
- "\n" +
- "杩愯緭閫斾腑鐩戞帶杞﹁締鐘舵�侊紙濡侴PS銆佹俯搴︿紶鎰熷櫒锛夈�俓n" +
- "\n" +
- "6. 浜哄憳鍩硅涓庢枃鍖朶n" +
- "瀹夊叏鍩硅锛氬畾鏈熷紑灞曟皵浣撳嵄瀹炽�侀槻鎶ゆ帾鏂藉拰搴旀�ュ鐞嗙殑鍩硅銆俓n" +
- "\n" +
- "瀹夊叏鏂囧寲锛氶紦鍔卞憳宸ユ姤鍛婃綔鍦ㄩ闄╋紝寤虹珛鈥滈浂娉勬紡鈥濈鐞嗙洰鏍囥�俓n" +
- "\n" +
- "7. 娉曡涓庢爣鍑哱n" +
- "閬靛畧鐩稿叧娉曡锛堝OSHA銆丟B 50493銆婄煶娌瑰寲宸ュ彲鐕冩皵浣撳拰鏈夋瘨姘斾綋妫�娴嬫姤璀﹁璁¤鑼冦�嬶級銆俓n" +
- "\n" +
- "瀹氭湡杩涜瀹夊叏瀹¤锛岀‘淇濈鍚堣涓氭爣鍑嗐�俓n" +
- "\n" +
- "甯歌鍗遍櫓姘斾綋娉勬紡鐨勯拡瀵规�ф帾鏂絓n" +
- "鍙噧姘斾綋锛堝鐢茬兎銆佹阿姘旓級锛氶槻鐖嗙數鍣ㄣ�佹秷闄ら潤鐢点�俓n" +
- "\n" +
- "鏈夋瘨姘斾綋锛堝姘皵銆佺~鍖栨阿锛夛細閰嶅涓撶敤杩囨护寮忔垨渚涙哀寮忓懠鍚稿櫒銆俓n" +
- "\n" +
- "绐掓伅鎬ф皵浣擄紙濡傛爱姘斻�佷簩姘у寲纰筹級锛氱洃娴嬫哀姘旀祿搴︼紝閬垮厤瀵嗛棴绌洪棿浣滀笟銆俓n" +
- "\n" +
- "閫氳繃浠ヤ笂鎺柦鐨勭患鍚堝簲鐢紝鍙ぇ骞呴檷浣庢皵浣撴硠婕忛闄╋紝淇濋殰浜哄憳瀹夊叏鍜岀幆澧冨仴搴枫�傝嫢鍙戠敓娉勬紡锛岄渶浼樺厛纭繚浜哄憳鎾ょ锛屽啀鐢变笓涓氫汉鍛樺缃�俓n" +
- "\n" +
- "鏈洖绛旂敱 AI 鐢熸垚锛屽唴瀹逛粎渚涘弬鑰冿紝璇蜂粩缁嗙攧鍒��"
-}
-
-export function shipping() {
- return "涓�銆佺珛鍗冲簲鎬ュ搷搴擻n" +
- "1. 鍙戠幇娉勬紡鏃剁殑绱ф�ヨ鍔╘n" +
- "鍋滆溅骞堕殧绂荤幇鍦猴細\n" +
- "\n" +
- "杩愯緭杞﹁締绔嬪嵆鍋滈潬鍦ㄧ┖鏃枫�佽繙绂讳汉缇ゅ拰鐏簮鐨勪綅缃�俓n" +
- "\n" +
- "璁剧疆璀︽垝绾匡紙鑷冲皯50~100绫冲崐寰勶紝鏍规嵁姘斾綋鎬ц川璋冩暣锛夛紝绂佹鏃犲叧浜哄憳杩涘叆銆俓n" +
- "\n" +
- "鍒囨柇娉勬紡婧愶細\n" +
- "\n" +
- "鍏抽棴瀹瑰櫒闃�闂ㄦ垨灏佸牭鐮存崯澶勶紙濡備娇鐢ㄥ簲鎬ュ牭婕忓伐鍏凤級銆俓n" +
- "\n" +
- "鑻ラ榾闂ㄦ崯鍧忥紝灏濊瘯杞Щ鍓╀綑姘斾綋鑷冲鐢ㄥ鍣紙闇�涓撲笟浜哄憳鎿嶄綔锛夈�俓n" +
- "\n" +
- "鎶ヨ涓庝笂鎶ワ細\n" +
- "\n" +
- "鎷ㄦ墦搴旀�ョ數璇濓紙濡傛秷闃�119銆佺幆淇濋儴闂級锛岃鏄庢皵浣撶被鍨嬨�佹硠婕忛噺銆佷綅缃瓑淇℃伅銆俓n" +
- "\n" +
- "鑱旂郴杩愯緭鍏徃鍙婅揣涓伙紝鑾峰彇鎶�鏈敮鎻达紙濡侻SDS瀹夊叏鏁版嵁琛級銆俓n" +
- "\n" +
- "2. 浜哄憳闃叉姢涓庣枏鏁n" +
- "绌挎埓闃叉姢瑁呭锛歕n" +
- "\n" +
- "鍙噧姘斾綋锛氶槻鐖嗗伐鍏�+闃查潤鐢垫湇锛涙湁姣掓皵浣擄細姝e帇寮忓懠鍚稿櫒+闃插寲鏈嶃�俓n" +
- "\n" +
- "鏃犻槻鎶よ澶囨椂锛岀珛鍗虫挙绂昏嚦涓婇鏂瑰悜銆俓n" +
- "\n" +
- "鐤忔暎鍛ㄨ竟鍖哄煙锛歕n" +
- "\n" +
- "鏍规嵁姘斾綋鎵╂暎鑼冨洿锛堝弬鑰冨簲鎬ュ搷搴旀寚鍗桬RG锛夌枏鏁e眳姘戞垨浣滀笟浜哄憳銆俓n" +
- "\n" +
- "閬垮厤浣庢醇澶勬粸鐣欙紙鏌愪簺姘斾綋姣旂┖姘旈噸锛屽纭寲姘級銆俓n" +
- "\n" +
- "3. 鎺у埗娉勬紡鎵╂暎\n" +
- "鐗╃悊鏂规硶锛歕n" +
- "\n" +
- "瑕嗙洊娉勬紡鍙o紙濡傜敤娴告按妫夎鍑忓皯鎸ュ彂锛屼絾绂佺敤浜庨亣姘村弽搴旀皵浣撳姘皵锛夈�俓n" +
- "\n" +
- "绛戝牑鍥村牭娑蹭綋娉勬紡鐗╋紝闃叉娴佸叆涓嬫按閬撴垨娌虫祦銆俓n" +
- "\n" +
- "鍖栧鏂规硶锛歕n" +
- "\n" +
- "涓拰澶勭悊锛堝姘ㄦ皵娉勬紡鍠锋磼绋�鐩愰吀锛岄渶涓撲笟浜哄憳鎿嶄綔锛夈�俓n" +
- "\n" +
- "浣跨敤鍚搁檮鏉愭枡锛堝娲绘�х偔銆佹矙鍦熷惛闄勬湁鏈烘皵浣擄級銆�"
-}
-
-export function operate(){
- return "涓�銆佹搷浣滀笉褰撳彂鐢熷悗鐨勫簲鎬ュ鐞哱n" +
- "1. 绔嬪嵆鎺у埗浜嬫晠\n" +
- "鍋滄鎿嶄綔锛歕n" +
- "\n" +
- "鎸変笅绱ф�ュ仠鏈烘寜閽紝鍏抽棴鏈�杩戠殑涓婃父闃�闂ㄣ�俓n" +
- "\n" +
- "鍚姩搴旀�ラ妗堬細\n" +
- "\n" +
- "灏忓瀷娉勬紡锛氫娇鐢ㄥ簲鎬ュ牭婕忓伐鍏凤紙濡傚瘑灏佽兌銆佸す鍏凤級銆俓n" +
- "\n" +
- "澶у瀷娉勬紡锛氱枏鏁d汉鍛橈紝鎶ヨ姹傚姪锛�119/鐜繚閮ㄩ棬锛夈�俓n" +
- "\n" +
- "2. 浜哄憳瀹夊叏\n" +
- "鎾ょ涓庨殧绂伙細\n" +
- "\n" +
- "閫嗛鎾ょ鑷充笂椋庡悜瀹夊叏鍖猴紝閬垮厤浣庢醇澶勶紙閲嶆皵浣撶Н鑱氾級銆俓n" +
- "\n" +
- "鎬ユ晳鎺柦锛歕n" +
- "\n" +
- "鍚稿叆鏈夋瘨姘斾綋锛氱Щ鑷崇┖姘旀柊椴滃锛屽繀瑕佹椂浜哄伐鍛煎惛銆俓n" +
- "\n" +
- "鐨偆鎺ヨЕ锛氱珛鍗崇敤娓呮按鍐叉礂15鍒嗛挓锛堣厫铓�鎬ф皵浣擄級銆俓n" +
- "\n" +
- "3. 浜嬫晠璋冩煡涓庢暣鏀筡n" +
- "鏍规湰鍘熷洜鍒嗘瀽锛圧CA锛夛細\n" +
- "\n" +
- "鏄搷浣滃け璇�佸煿璁笉瓒筹紝杩樻槸璁惧缂洪櫡锛焅n" +
- "\n" +
- "鏀硅繘鎺柦锛歕n" +
- "\n" +
- "淇鎿嶄綔瑙勭▼锛屽鍔犺绀烘爣璇嗐�俓n" +
- "\n" +
- "瀵硅矗浠讳汉鍐嶅煿璁紝蹇呰鏃惰皟宀椼��"
-}
-
-export function emergency(){
- return "涓�銆佷紭鍖栧簲鎬ュ搷搴旂殑鍏抽敭鎺柦\n" +
- "1. 瀹屽杽搴旀�ラ妗圽n" +
- "閽堝鎬ц璁★細\n" +
- "\n" +
- "鍩轰簬HAZOP锛堝嵄闄╀笌鍙搷浣滄�у垎鏋愶級璇嗗埆鎵�鏈夋綔鍦ㄩ闄╁満鏅�俓n" +
- "\n" +
- "鍒跺畾鍒嗙骇鍝嶅簲鏈哄埗锛堝皬娉勬紡鐜板満澶勭疆銆佸ぇ娉勬紡鍏ㄥ憳鐤忔暎锛夈�俓n" +
- "\n" +
- "鏄庣‘鑱岃矗锛歕n" +
- "\n" +
- "璁剧珛搴旀�ユ寚鎸ラ儴锛屾寚瀹氭�绘寚鎸ャ�侀�氳缁勩�佹姠闄╃粍銆佸尰鐤楃粍绛夈�俓n" +
- "\n" +
- "纭繚24灏忔椂鍊肩彮鍒跺害锛岃仈绯绘柟寮忓疄鏃舵洿鏂般�俓n" +
- "\n" +
- "鑱斿姩澶栭儴璧勬簮锛歕n" +
- "\n" +
- "涓庢秷闃层�佺幆淇濄�佸尰闄㈡彁鍓嶇璁㈡晳鎻村崗璁紝鏄庣‘鍗忎綔娴佺▼銆俓n" +
- "\n" +
- "2. 寮哄寲搴旀�ヨ祫婧愪繚闅淺n" +
- "瑁呭涓庣墿璧勶細\n" +
- "\n" +
- "閰嶅瓒抽噺涓旀湁鏁堢殑搴旀�ヨ澶囷紝鍖呮嫭锛歕n" +
- "\n" +
- "涓汉闃叉姢瑁呭锛圥PE锛夛細闃叉瘨闈㈠叿銆佸寲瀛﹂槻鎶ゆ湇銆俓n" +
- "\n" +
- "鍫垫紡宸ュ叿锛氬瘑灏佽兌銆佸す鍏枫�佸揩閫熷皝鍫靛櫒銆俓n" +
- "\n" +
- "鍚搁檮/涓拰鏉愭枡锛氭椿鎬х偔銆佹矙鍦熴�佺█纰辨恫锛堢敤浜庨吀鎬ф皵浣擄級銆俓n" +
- "\n" +
- "瀹氭湡妫�鏌ャ�佺淮鎶ゅ拰鏇存崲锛堝姘旂摱鍘嬪姏銆佷紶鎰熷櫒鐢垫睜锛夈�俓n" +
- "\n" +
- "搴旀�ヨ溅杈嗕笌閫氶亾锛歕n" +
- "\n" +
- "纭繚鏁戞彺杞﹁締鍙揩閫熸姷杈炬硠婕忕偣锛堟竻闄よ矾闅滐紝鏍囪瘑搴旀�ヨ矾绾匡級銆俓n" +
- "\n" +
- "鍏抽敭鍖哄煙璁剧疆搴旀�ユ礂鐪煎櫒銆佸柗娣嬬郴缁熴�俓n" +
- "\n" +
- "3. 鍔犲己浜哄憳鍩硅涓庤兘鍔涘缓璁綷n" +
- "鍒嗗眰鍩硅锛歕n" +
- "\n" +
- "鍩哄眰浜哄憳锛氭帉鎻″熀鏈簲鎬ュ缃紙濡傚叧闂榾闂ㄣ�佷娇鐢ㄧ伃鐏櫒锛夈�俓n" +
- "\n" +
- "搴旀�ュ皬缁勶細涓撲笟鍫垫紡銆佷激鍛樻�ユ晳銆佹皵浣撴娴嬫妧鑳姐�俓n" +
- "\n" +
- "绠$悊灞傦細鎸囨尌鍐崇瓥銆佸獟浣撴矡閫氥�佹硶寰嬪悎瑙勩�俓n" +
- "\n" +
- "瀹炴垬鍖栬�冩牳锛歕n" +
- "\n" +
- "閫氳繃妯℃嫙绐佸彂娉勬紡锛堝鐩叉紨锛夋楠屽搷搴旈�熷害銆俓n" +
- "\n" +
- "涓嶅悎鏍艰�呴渶閲嶆柊鍩硅銆俓n" +
- "\n" +
- "4. 瀹氭湡婕旂粌涓庢寔缁敼杩沑n" +
- "婕旂粌棰戠巼锛歕n" +
- "\n" +
- "姣忓搴﹁嚦灏�1娆℃闈㈡帹婕旓紝姣忓勾2娆$患鍚堝疄鎴樻紨缁冦�俓n" +
- "\n" +
- "鍦烘櫙璁捐锛歕n" +
- "\n" +
- "妯℃嫙澶嶆潅鎯呭喌锛堝澶滈棿鍋滅數銆佸浜哄彈浼わ級銆俓n" +
- "\n" +
- "寮曞叆鈥滅獊鍙戝彉閲忊�濓紙濡傞鍚戠獊鍙樸�佷簩娆℃硠婕忥級銆俓n" +
- "\n" +
- "澶嶇洏涓庝紭鍖栵細\n" +
- "\n" +
- "璁板綍婕旂粌涓殑闂锛堝閫氳寤惰繜銆佽澶囩己澶憋級銆俓n" +
- "\n" +
- "鏇存柊棰勬骞朵笅鍙戝涔犮�俓n" +
- "\n" +
- "5. 鎶�鏈崌绾т笌鏅鸿兘鍖栨敮鎸乗n" +
- "瀹炴椂鐩戞祴涓庨璀︼細\n" +
- "\n" +
- "閮ㄧ讲鐗╄仈缃戯紙IoT锛変紶鎰熷櫒锛岀洃娴嬫皵浣撴祿搴︺�佽澶囩姸鎬併�俓n" +
- "\n" +
- "璁剧疆鑷姩鑱旈攣鎺у埗锛堝娉勬紡鏃惰仈鍔ㄥ叧闂榾闂ㄥ苟鍚姩閫氶锛夈�俓n" +
- "\n" +
- "搴旀�ラ�氳绯荤粺锛歕n" +
- "\n" +
- "浣跨敤闃茬垎瀵硅鏈恒�佸崼鏄熺數璇濓紙淇濋殰淇″彿瑕嗙洊锛夈�俓n" +
- "\n" +
- "寤虹珛搴旀�ュ箍鎾郴缁燂紙濡傚巶鍖鸿鎶ャ�佺煭淇$兢鍙戯級銆俓n" +
- "\n" +
- "鏁板瓧鍖栭妗堬細\n" +
- "\n" +
- "灏嗗簲鎬ラ妗堝綍鍏ョЩ鍔ㄧ粓绔紝瀹炵幇涓�閿皟闃呫�佹楠ゆ寚寮曘��"
-}
-
-export function compliance(){
- return "涓�銆佸父瑙佺殑鍚堣鎬ч棶棰榎n" +
- "1. 璁稿彲涓庤祫璐ㄧ己澶盶n" +
- "闂锛歕n" +
- "\n" +
- "鏈彇寰楀嵄闄╁寲瀛﹀搧缁忚惀璁稿彲璇佹垨瀹夊叏鐢熶骇璁稿彲璇併�俓n" +
- "\n" +
- "鐗圭浣滀笟浜哄憳锛堝鍘嬪姏瀹瑰櫒鎿嶄綔宸ワ級鏃犺瘉涓婂矖銆俓n" +
- "\n" +
- "椋庨櫓锛歕n" +
- "\n" +
- "鐩戠閮ㄩ棬澶勭綒锛堝缃氭銆佽矗浠ゅ仠浜э級銆俓n" +
- "\n" +
- "淇濋櫓鎷掕禂锛堜簨鏁呭彂鐢熸椂锛夈�俓n" +
- "\n" +
- "2. 瀹夊叏璁捐涓嶈揪鏍嘰n" +
- "闂锛歕n" +
- "\n" +
- "鍌ㄧ綈銆佺閬撴湭鎸塆B/T 150锛堝帇鍔涘鍣ㄦ爣鍑嗭級璁捐銆俓n" +
- "\n" +
- "鏈畨瑁呭彲鐕�/鏈夋瘨姘斾綋鎶ヨ鍣紙杩濆弽GB 50493锛夈�俓n" +
- "\n" +
- "椋庨櫓锛歕n" +
- "\n" +
- "璁惧澶辨晥瀵艰嚧娉勬紡鎴栫垎鐐搞�俓n" +
- "\n" +
- "涓嶇鍚堝簲鎬ョ鐞嗛儴鎴朞SHA妫�鏌ヨ姹傘�俓n" +
- "\n" +
- "3. 鎿嶄綔涓庣淮鎶よ繚瑙刓n" +
- "闂锛歕n" +
- "\n" +
- "鏈墽琛屼綔涓氱エ鍒跺害锛堝鍔ㄧ伀浣滀笟鏈鎵癸級銆俓n" +
- "\n" +
- "鏈畾鏈熸楠屽帇鍔涘鍣紙杩濆弽TSG 21-2016锛夈�俓n" +
- "\n" +
- "椋庨櫓锛歕n" +
- "\n" +
- "杩濊鎿嶄綔寮曞彂浜嬫晠锛堝鐒婃帴寮曞彂鍙噧姘斾綋鐖嗙偢锛夈�俓n" +
- "\n" +
- "璁惧鑰佸寲瀵艰嚧绐佸彂娉勬紡銆俓n" +
- "\n" +
- "4. 搴旀�ョ鐞嗕笉鍚堣\n" +
- "闂锛歕n" +
- "\n" +
- "鏈埗瀹氬簲鎬ラ妗堟垨鏈妗堬紙杩濆弽銆婄敓浜у畨鍏ㄤ簨鏁呭簲鎬ユ潯渚嬨�嬶級銆俓n" +
- "\n" +
- "鏈厤澶囧簲鎬ョ墿璧勶紙濡傞槻姣掗潰鍏枫�佸牭婕忓伐鍏凤級銆俓n" +
- "\n" +
- "椋庨櫓锛歕n" +
- "\n" +
- "浜嬫晠鍙戠敓鏃舵棤娉曟湁鏁堟帶鍒讹紝瀵艰嚧鎹熷け鎵╁ぇ銆俓n" +
- "\n" +
- "闈复鐢熸�佺幆澧冮儴杩借矗锛堝鍖栧鍝佹薄鏌撳湡澹�/姘翠綋锛夈�俓n" +
- "\n" +
- "5. 璁板綍涓庢姤鍛婄己澶盶n" +
- "闂锛歕n" +
- "\n" +
- "鏈繚瀛樺畨鍏ㄦ鏌ヨ褰曟垨鍩硅妗f銆俓n" +
- "\n" +
- "鏈寜瑙勫畾涓婃姤娉勬紡浜嬫晠锛堝鐬掓姤銆佽繜鎶ワ級銆俓n" +
- "\n" +
- "椋庨櫓锛歕n" +
- "\n" +
- "浜嬫晠璋冩煡鏃舵棤娉曡嚜璇佸悎瑙勶紝鎵挎媴鍏ㄨ矗銆俓n" +
- "\n" +
- "琚垪鍏ュ畨鍏ㄧ敓浜ч粦鍚嶅崟锛屽奖鍝嶄紒涓氫俊瑾夈��"
-}
-
-export function monitoring(){
- return "涓�銆佸浐瀹氬紡鐩戞祴鎶�鏈痋n" +
- "1. 鍌寲鐕冪儳寮忎紶鎰熷櫒\n" +
- "鍘熺悊锛氬彲鐕冩皵浣撳湪閾備笣琛ㄩ潰鐕冪儳瀵艰嚧鐢甸樆鍙樺寲\n" +
- "\n" +
- "浼樺娍锛氭垚鏈綆锛堬骏500-2000/涓級銆佸搷搴斿揩锛�<10s锛塡n" +
- "\n" +
- "灞�闄愶細鏄撲腑姣掞紙纭�/纭寲鍚堢墿锛夈�佸鍛界煭锛�2-3骞达級\n" +
- "\n" +
- "閫傜敤锛氱煶鍖栧巶鍙噧姘旂洃娴嬶紙鐢茬兎銆佹阿姘旂瓑锛塡n" +
- "\n" +
- "2. 鐢靛寲瀛︿紶鎰熷櫒\n" +
- "鍘熺悊锛氭皵浣撲笌鐢佃В娑插彂鐢熸哀鍖栬繕鍘熷弽搴斾骇鐢熺數娴乗n" +
- "\n" +
- "浼樺娍锛歱pb绾ф娴嬶紙濡侶2S妫�娴嬩笅闄�0.1ppm锛塡n" +
- "\n" +
- "灞�闄愶細鍙楁俯婀垮害褰卞搷锛堥渶瀹氭湡鏍″噯锛塡n" +
- "\n" +
- "閫傜敤锛氭湁姣掓皵浣擄紙Cl鈧傘�丯H鈧冦�丆O绛夛級\n" +
- "\n" +
- "3. 绾㈠鍚告敹寮忥紙NDIR锛塡n" +
- "鍘熺悊锛氭皵浣撳鐗瑰畾绾㈠娉㈡鐨勫惛鏀剁巼妫�娴媆n" +
- "\n" +
- "浼樺娍锛氬厤鏍″噯锛堝鍛�5-10骞达級銆佹姉涓瘨\n" +
- "\n" +
- "灞�闄愶細楂樻垚鏈紙锟�5000+/涓級\n" +
- "\n" +
- "閫傜敤锛欳O鈧傘�丆H鈧勭瓑娓╁姘斾綋鐩戞祴\n" +
- "\n" +
- "4. 婵�鍏夊厜璋憋紙TDLAS锛塡n" +
- "鍘熺悊锛氬彲璋冭皭婵�鍏変簩鏋佺鎵弿姘斾綋鍚告敹绾縗n" +
- "\n" +
- "浼樺娍锛歱pm绾х簿搴︺�佸搷搴攎s绾n" +
- "\n" +
- "灞�闄愶細闇�鍏夊瀵瑰噯锛堝畨瑁呭鏉傦級\n" +
- "\n" +
- "閫傜敤锛氱閬撳井娉勬紡妫�娴嬶紙澶╃劧姘旈暱杈撶绾匡級"
-}
-
-export function checking(keyWord){
- if(keyWord.includes("姘斾綋娉勬紡")){
- return gasLeaks();
- }
- if(keyWord.includes("瀹瑰櫒澶辨晥")){
- return shipping();
- }
- if(keyWord.includes("鎿嶄綔涓嶅綋")){
- return operate();
- }
- if(keyWord.includes("鍝嶅簲涓嶈冻")){
- return emergency();
- }
- if(keyWord.includes("鍚堣鎬�")){
- return compliance();
- }
- if(keyWord.includes("鐩戞祴鎶�鏈�")){
- return monitoring();
- }
- return "涓嶅ソ鎰忔�濓紝灏忔櫤杩樺湪鎴愰暱杩囩▼涓紝鎮ㄧ殑闂宸茬粡瓒呰繃灏忔櫤鐨勫鐞嗚寖鍥翠簡銆�";
-
-}
\ No newline at end of file
diff --git a/src/views/chatHome/chatHomeIndex/home.vue b/src/views/chatHome/chatHomeIndex/home.vue
deleted file mode 100644
index 7796284..0000000
--- a/src/views/chatHome/chatHomeIndex/home.vue
+++ /dev/null
@@ -1,175 +0,0 @@
-<template>
-<div class="home">
- <div style="background: white;color: black;font-size: 30px;" class="logo">
- <div class="logo-one" style="font-weight: bold">
-<!-- <img src="/src/assets/img/logo.png" style="width: 50px;height: 50px;margin: 0 10px" />-->
- <div><i>澶фā鍨婣I灏忔櫤姝e湪涓烘偍鏈嶅姟</i></div>
- </div>
- <div class="input">
- <input type="text" v-model="keyWord" class="input-text" placeholder="缁欏皬鏅哄彂閫佹秷鎭�" @keyup.enter="sendMsg" />
- <div style="font-size: 13px;color: #808080;display: flex;justify-content: space-between;padding: 10px;">
- <div style="display: flex;justify-content: center;align-items: center;">
-<!-- <div style="display: flex;justify-content: center;align-items: center;">-->
-<!-- <img src="/src/assets/img/logo.png" style="width: 15px;height: 15px;margin: 0 5px" />-->
-<!-- <span>娣卞害鎬濊��(R1)</span>-->
-<!-- </div>-->
-<!-- <div style="display: flex;justify-content: center;align-items: center;">-->
-<!-- <img src="/src/assets/img/logo.png" style="width: 15px;height: 15px;margin: 0 5px" />-->
-<!-- <span>鑱旂綉鎼滅储</span>-->
-<!-- </div>-->
- </div>
- <div style="display: flex;justify-content: center;align-items: center;margin-right: 5px;">
-<!-- <img src="/src/assets/img/logo.png" style="width: 25px;height: 25px;margin: 0 5px" />-->
- <img src="@/assets/img/emoji/rocket.png" style="width: 25px;height: 25px;margin: 0 5px" @click="sendMsg"/>
- </div>
- </div>
- </div>
- <div style="width: 780px;">
- <div style="font-weight: bold;margin: 30px 0;">鐑棬鎺ㄨ崘</div>
- <div class="keywords">
- <div class="keywordss" @click="sendMsgDefault(keyWordOne)">
- <p class="fontSize aaa">{{keyWordOne}}</p>
- <p class="fontSize">闃�闂ㄣ�佺閬撴垨瀹瑰櫒瀵嗗皝澶辨晥瀵艰嚧姘斾綋娉勬紡锛堝姘皵銆佹皑姘旓級銆�</p>
- <p class="fontSize">鍚庢灉锛氫腑姣掋�佺垎鐐搞�佺幆澧冩薄鏌撱��</p>
- </div>
- <div class="keywordss" @click="sendMsgDefault(keyWordTwo)">
- <p class="fontSize aaa">{{keyWordTwo}}</p>
- <p class="fontSize">閽㈢摱鎴栫綈浣撳洜鏉愭枡鐤插姵銆佽厫铓�鎴栬秴鍘嬬牬瑁�</p>
- <p class="fontSize">鍘熷洜锛氭湭瀹氭湡妫�娴嬨�佽繚瑙勫厖瑁呮垨澶栭儴鎾炲嚮銆傘��</p>
- </div>
- </div>
- <div class="keywords">
- <div class="keywordss" @click="sendMsgDefault(keyWordFive)">
- <p class="fontSize aaa">{{keyWordFive}}</p>
- <p class="fontSize">瑁呭嵏杩囩▼涓繚瑙勬搷浣滐紙濡傞噹铔惉杩愩�佹贩瑁呯蹇岀墿璐級銆�</p>
- <p class="fontSize">杩愯緭閫斾腑鏈浐瀹氬鍣紝瀵艰嚧纰版挒鎴栧�惧�掋��</p>
- </div>
- <div class="keywordss" @click="sendMsgDefault(keyWordSix)">
- <p class="fontSize aaa">{{keyWordSix}}</p>
- <p class="fontSize">缂轰箯娉勬紡搴旀�ラ妗堬紝浜哄憳鍩硅涓嶈冻銆�</p>
- <p class="fontSize">鏁戞彺璁惧锛堝闃叉瘨闈㈠叿銆佸牭婕忓伐鍏凤級缂哄け鎴栧け鏁堛��</p>
- </div>
- </div>
- <div class="keywords">
- <div class="keywordss" @click="sendMsgDefault(keyWordServen)">
- <p class="fontSize aaa">{{keyWordServen}}</p>
- <p class="fontSize">鏈彇寰楄繍杈撹祫璐紙濡侫DR/RID绛夊浗闄呰鑼冿級銆�</p>
- <p class="fontSize">璺嚎瑙勫垝涓嶅悎瑙勶紙濡傜┛瓒婁汉鍙e瘑闆嗗尯锛夈��</p>
- </div>
- <div class="keywordss" @click="sendMsgDefault(keyWordEight)">
- <p class="fontSize aaa">{{keyWordEight}}</p>
- <p class="fontSize">浼犳劅鍣ㄩ儴缃诧紙濡傜孩澶栨皵浣撴帰娴嬪櫒銆佺數鍖栧浼犳劅鍣級銆�</p>
- <p class="fontSize">瀹炴椂鏁版嵁浼犺緭鑷崇洃鎺у钩鍙帮紝瑙﹀彂鎶ヨ銆�</p>
- </div>
- </div>
- </div>
- </div>
-
- <div></div>
-</div>
-</template>
-
-<script setup>
-import { ref,onMounted } from "vue";
-import {useRoute,useRouter} from "vue-router"
-const route = useRoute();
-const router = useRouter();
-const keyWord = ref('');
-const keyWordOne = ref('鍗遍櫓姘斾綋娉勬紡鎬庝箞鍔�');
-const keyWordTwo = ref('杩愯緭瀹瑰櫒澶辨晥鎬庝箞鍔�');
-const keyWordFive = ref('鎿嶄綔涓嶅綋鎬庝箞鍔�');
-const keyWordSix = ref('搴旀�ュ搷搴斾笉瓒虫�庝箞鍔�');
-const keyWordServen = ref('鍚堣鎬ч棶棰�');
-const keyWordEight = ref('娉勬紡鐩戞祴鎶�鏈湁鍝簺');
-
-const sendMsg = () => {
- router.push({ path: '/main/MobileChat',query:{ keyWord: keyWord.value} })
-}
-
-const sendMsgDefault = (value) => {
- router.push({ path: '/main/MobileChat',query:{ keyWord: value} })
-}
-
-</script>
-
-<style lang="scss" scoped>
-.home {
- width: 100%;
- height: 91vh;
- display: flex;
- flex-direction: column;
- align-items: center;
-
- .logo {
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- z-index: 99;
- width: 100%;
- height: 100%;
- color: #fff;
- cursor: pointer;
- overflow: hidden;
- background-color: #F0F6F9;
-
- .keywords {
- display: flex;
- width: 100%;
- height: 90px;
- line-height: 80px;
- justify-content: space-between;
- margin: 10px 0;
-
- .keywordss {
- box-shadow: 0px 2px 5px #b8b8b8;
- width: 48%;
- background: #e0edfc;
- border-radius: 10px;
-
- .aaa {
- font-weight: bold;
- font-size: 15px !important;
- }
-
- .fontSize {
- font-size: 13px;
- height: 20px;
- line-height: 20px;
- margin: 6px;
- }
- }
- }
-
- .logo-one {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-bottom: 20px;
- }
-
- .input {
- width: 780px;
- height: 150px;
- background: #f5f4f4;
- border-radius: 20px;
-
- .input-text {
- font-size: 18px;
- width: 568px;
- border-radius: 20px 20px 0 0;
- height: 90px;
- padding-left: 10px;
- border: none;
- color: black;
- background-color: #f5f4f4;
- }
-
- .input-text:focus {
- outline: none;
- border: none;
- }
- }
- }
-}
-</style>
diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
deleted file mode 100644
index 403cab6..0000000
--- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
+++ /dev/null
@@ -1,371 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'"
- width="700px"
- @close="closeDia"
- >
- <el-form :model="form" label-width="140px" label-position="top" ref="formRef">
- <el-row>
- <el-col :span="24">
- <el-form-item label="娴佺▼缂栧彿锛�" prop="approveId">
- <el-input v-model="form.approveId" placeholder="鑷姩缂栧彿" clearable disabled/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptId">
- <el-select
- disabled
- v-model="form.approveDeptId"
- placeholder="閫夋嫨閮ㄩ棬"
- >
- <el-option
- v-for="user in productOptions"
- :key="user.deptId"
- :label="user.deptName"
- :value="user.deptId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="瀹℃壒浜嬬敱锛�" prop="approveReason">
- <el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" disabled/>
- </el-form-item>
- </el-col>
- </el-row>
- <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鐢宠浜猴細" prop="approveUser">
- <el-select
- v-model="form.approveUser"
- placeholder="閫夋嫨浜哄憳"
- disabled
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
- <el-date-picker
- v-model="form.approveTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <el-form :model="{ activities }" ref="formRef" label-position="top">
- <el-steps :active="getActiveStep()" finish-status="success" process-status="process" align-center direction="vertical">
- <el-step
- v-for="(activity, index) in activities"
- :key="index"
- finish-status="success"
- :title="getNodeTitle(index, activities.length)"
- :description="activity.approveNodeUser"
- :icon="getNodeIcon(activity, index)"
- >
- <template #icon>
- <el-icon v-if="activity.approveNodeStatus === 2" color="red" :size="22"><WarningFilled /></el-icon>
- <el-icon v-else-if="activity.isShen" color="#1890ff" :size="22"><Edit /></el-icon>
- <el-icon v-else-if="activity.approveNodeStatus === 1" color="#67C23A" :size="26"><Check /></el-icon>
- <el-icon v-else color="#C0C4CC" :size="22"><MoreFilled /></el-icon>
- </template>
- <template #title>
- <span style="color: #000000">{{ getNodeTitle(index, activities.length) }}</span>
- </template>
- <template #description>
- <div class="node-user">
- <div class="avatar-wrapper">
- <img :src="userStore.avatar" class="user-avatar" alt=""/>
- </div>
- <span style="color: #000000">{{ activity.approveNodeUser }}-{{activity.isApproval}}</span>
- </div>
- <div v-if="!activity.isShen" class="node-reason">
- <span>瀹℃壒鎰忚锛�</span>{{ activity.approveNodeReason }}
- </div>
- <div v-if="!activity.isShen" class="node-reason">
- <span>绛惧悕锛�</span>
- <img :src="activity.urlTem" class="signImg" alt="" v-if="activity.urlTem"/>
- </div>
- <div v-else-if="activity.isShen">
- <el-form-item
- :prop="'activities.' + index + '.approveNodeReason'"
- :rules="[{ required: true, message: '瀹℃壒鎰忚涓嶈兘涓虹┖', trigger: 'blur' }]"
- >
- <el-input v-model="activity.approveNodeReason" clearable type="textarea" :disabled="operationType === 'view'"></el-input>
- </el-form-item>
- </div>
- </template>
- </el-step>
- </el-steps>
- </el-form>
- <template #footer v-if="operationType === 'approval'">
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm(2)">涓嶉�氳繃</el-button>
- <el-button type="primary" @click="openSignatureDialog(1)">閫氳繃</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 鐢靛瓙绛惧悕寮圭獥锛坴ue3-signature-pad锛� -->
- <el-dialog v-model="signatureDialogVisible" title="鐢靛瓙绛惧悕" width="600px" append-to-body>
- <vueEsign
- ref="esign"
- class="mySign"
- :width="800"
- :height="300"
- :isCrop="isCrop"
- :lineWidth="lineWidth"
- :lineColor="lineColor"
- />
- <div style="margin-top:10px;">
- <el-button @click="clearSignature">娓呴櫎</el-button>
- <el-button type="primary" @click="confirmSignature">纭畾</el-button>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { getCurrentInstance, reactive, ref, toRefs } from "vue";
-import vueEsign from "vue-esign";
-import {
- approveProcessDetails,
- getDept,
- updateApproveNode
-} from "@/api/collaborativeApproval/approvalProcess.js";
-import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
-import { getToken } from "@/utils/auth";
-const emit = defineEmits(['close'])
-const { proxy } = getCurrentInstance()
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const activities = ref([])
-const formRef = ref(null);
-const userStore = useUserStore()
-const productOptions = ref([]);
-const userList = ref([])
-const data = reactive({
- form: {
- approveTime: "",
- approveId: "",
- approveUser: "",
- approveDeptId: "",
- approveReason: "",
- checkResult: "",
- },
-});
-const { form } = toRefs(data);
-const signatureDialogVisible = ref(false);
-const signatureImg = ref('');
-let submitStatus = null; // 涓存椂瀛樺偍閫氳繃/涓嶉�氳繃鐘舵��
-const isCrop = ref("");
-const esign = ref(null);
-const lineWidth = ref(0);
-const lineColor = ref("#000000");
-
-// 涓婁紶閰嶇疆
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-// 鑺傜偣鏍囬
-const getNodeTitle = (index, len) => {
- if (index === len - 1) return '缁撴潫';
- return '瀹℃壒';
-};
-
-// 鑾峰彇褰撳墠婵�娲绘楠�
-const getActiveStep = () => {
- // 濡傛灉鎵�鏈� isShen 閮戒负 false锛岃繑鍥炴渶鍚庝竴涓楠わ紙鍏ㄩ儴瀹屾垚锛�
- const hasActive = activities.value.some(a => a.isShen === true);
- if (!hasActive) return activities.value.length;
- // 褰撳墠鑺傜偣绱㈠紩
- return activities.value.findIndex(a => a.isShen == true);
-};
-// 姝ラicon
-const getNodeIcon = (activity, index) => {
- if (activity.approveNodeStatus === 2) return 'el-icon-warning'; // 涓嶉�氳繃
- if (activity.isShen) return 'Edit';
- return '';
-};
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- form.value = {...row}
- getProductOptions()
- approveProcessDetails(row.approveId).then((res) => {
- activities.value = res.data
- // 澧炲姞isApproval瀛楁
- activities.value.forEach(item => {
- if (item.url && item.url.includes('word')) {
- item.urlTem = item.url.replaceAll('word', 'img')
- } else {
- item.urlTem = item.url
- }
- if (item.approveNodeStatus === 2) {
- item.isApproval = '宸查┏鍥�';
- } else if (item.approveNodeStatus === 1) {
- item.isApproval = '宸插悓鎰�';
- } else {
- item.isApproval = '鏈鎵�';
- }
- })
- })
-}
-const getProductOptions = () => {
- getDept().then((res) => {
- productOptions.value = res.data;
- });
-};
-// 鎵撳紑绛惧悕寮圭獥
-const openSignatureDialog = (status) => {
- submitStatus = status;
- signatureDialogVisible.value = true;
-};
-// 娓呴櫎绛惧悕
-const clearSignature = () => {
- esign.value.reset();
-};
-// 纭绛惧悕
-const confirmSignature = () => {
- esign.value.generate().then((res) => {
- console.log(res);
- // 灏哹ase64杞崲涓轰簩杩涘埗
- const base64Data = res.split(',')[1]; // 绉婚櫎data:image/png;base64,鍓嶇紑
- const binaryString = atob(base64Data);
- const bytes = new Uint8Array(binaryString.length);
- for (let i = 0; i < binaryString.length; i++) {
- bytes[i] = binaryString.charCodeAt(i);
- }
- signatureImg.value = bytes;
-
- // 鍒涘缓鏂囦欢瀵硅薄鐢ㄤ簬涓婁紶
- const blob = new Blob([bytes], { type: 'image/png' });
- const file = new File([blob], 'signature.png', { type: 'image/png' });
-
- // 鍒涘缓FormData
- const formData = new FormData();
- formData.append('file', file);
-
- // 涓婁紶绛惧悕鍥剧墖
- fetch(upload.url, {
- method: 'POST',
- headers: upload.headers,
- body: formData
- })
- .then(response => response.json())
- .then(data => {
- if (data.code === 200) {
- console.log('data---', data)
- let tempFileIds = [];
- tempFileIds.push(data.data.tempId);
- signatureDialogVisible.value = false;
- clearSignature();
- // 鍙湁閫氳繃鏃舵墠浼犻�掔鍚嶆枃浠禝D
- if (submitStatus === 1) {
- submitForm(submitStatus, tempFileIds);
- } else {
- submitForm(submitStatus);
- }
- } else {
- proxy.$modal.msgError("绛惧悕鍥剧墖涓婁紶澶辫触锛�" + data.msg);
- }
- })
- .catch(error => {
- console.error('涓婁紶澶辫触:', error);
- proxy.$modal.msgError("绛惧悕鍥剧墖涓婁紶澶辫触");
- });
- }).catch((err) => {
- console.log(err);
- proxy.$modal.msgWarning("璇峰厛绛惧悕锛�");
- })
-};
-// 鎻愪氦瀹℃壒
-const submitForm = (status, tempFileIds) => {
- const filteredActivities = activities.value.filter(activity => activity.isShen);
- filteredActivities[0].approveNodeStatus = status;
- // 鍙湁閫氳繃鏃舵墠闇�瑕佺鍚�
- if (status === 1 && tempFileIds) {
- filteredActivities[0].tempFileIds = tempFileIds;
- }
- // 鍒ゆ柇鏄惁涓烘渶鍚庝竴姝�
- const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1;
- updateApproveNode({ ...filteredActivities[0], isLast }).then(() => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-.node-user {
- margin: 10px 0;
- font-size: 16px;
- font-weight: 600;
- display: flex;
- align-items: center;
- gap: 8px;
-}
-.node-status {
- color: #1890ff;
- margin-left: 8px;
- font-size: 14px;
-}
-.node-reason {
- font-size: 15px;
- color: #333;
- margin: 10px 0;
-}
-.user-avatar {
- cursor: pointer;
- width: 30px;
- height: 30px;
- border-radius: 50px;
-}
-.signImg {
- cursor: pointer;
- width: 200px;
- height: 60px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
deleted file mode 100644
index 24bb1d0..0000000
--- a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
+++ /dev/null
@@ -1,361 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'"
- width="50%"
- @close="closeDia"
- >
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-row>
- <el-col :span="24">
- <el-form-item label="娴佺▼缂栧彿锛�" prop="approveId">
- <el-input v-model="form.approveId" placeholder="鑷姩缂栧彿" clearable disabled/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptId">
- <el-select
- disabled
- v-model="form.approveDeptId"
- placeholder="閫夋嫨閮ㄩ棬"
- >
- <el-option
- v-for="user in productOptions"
- :key="user.deptId"
- :label="user.deptName"
- :value="user.deptId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item :label="props.approveType == 5 ? '閲囪喘璇存槑锛�' : '瀹℃壒浜嬬敱锛�'" prop="approveReason">
- <el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" />
- </el-form-item>
- </el-col>
- </el-row>
- <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
- <el-row>
- <el-col :span="24">
- <el-form-item>
- <template #label>
- <span>瀹℃壒浜洪�夋嫨锛�</span>
- <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">鏂板鑺傜偣</el-button>
- </template>
- <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
- <div
- v-for="(node, index) in approverNodes"
- :key="node.id"
- style="margin-right: 30px; text-align: center; margin-bottom: 10px;"
- >
- <div>
- <span>瀹℃壒浜�</span>
- 鈫�
- </div>
- <el-select
- v-model="node.userId"
- placeholder="閫夋嫨浜哄憳"
- style="width: 120px; margin-bottom: 8px;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- <div>
- <el-button
- type="danger"
- size="small"
- @click="removeApproverNode(index)"
- v-if="approverNodes.length > 1"
- >鍒犻櫎</el-button>
- </div>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鐢宠浜猴細" prop="approveUser">
- <el-select
- v-model="form.approveUser"
- placeholder="閫夋嫨浜哄憳"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
- <el-date-picker
- v-model="form.approveTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
- :on-success="handleUploadSuccess" :on-remove="handleRemove">
- <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
- <template #tip v-if="operationType !== 'view'">
- <div class="el-upload__tip">
- 鏂囦欢鏍煎紡鏀寔
- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
- </div>
- </template>
- </el-upload>
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {
- approveProcessAdd, approveProcessGetInfo,
- approveProcessUpdate,
- getDept
-} from "@/api/collaborativeApproval/approvalProcess.js";
-import {
- delLedgerFile,
-} from "@/api/salesManagement/salesLedger.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getToken } from "@/utils/auth";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-import useUserStore from "@/store/modules/user";
-const userStore = useUserStore();
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const fileList = ref([]);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-const data = reactive({
- form: {
- approveTime: "",
- approveId: "",
- approveUser: "",
- approveDeptId: "",
- approveReason: "",
- checkResult: "",
- tempFileIds: [],
- approverList: [] // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
- },
- rules: {
- approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" },],
- approveId: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- approveUser: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- approveDeptId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- approveReason: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- checkResult: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-const productOptions = ref([]);
-const currentApproveStatus = ref(0)
-const props = defineProps({
- approveType: {
- type: [Number, String],
- default: 0
- }
-})
-
-// 瀹℃壒浜鸿妭鐐圭浉鍏�
-const approverNodes = ref([
- { id: 1, userId: null }
-])
-let nextApproverId = 2
-const userList = ref([])
-function addApproverNode() {
- approverNodes.value.push({ id: nextApproverId++, userId: null })
-}
-function removeApproverNode(index) {
- approverNodes.value.splice(index, 1)
-}
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- console.log('openDialog', type, row)
- operationType.value = type;
- dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- getProductOptions();
- form.value = {}
- approverNodes.value = [
- { id: 1, userId: null }
- ]
- form.value.approveUser = userStore.id;
- form.value.approveTime = getCurrentDate();
-
- // 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅骞惰缃儴闂↖D
- form.value.approveDeptId = userStore.currentDeptId
- if (operationType.value === 'edit') {
- fileList.value = row.commonFileList
- form.value.tempFileIds = fileList.value.map(file => file.id)
- currentApproveStatus.value = row.approveStatus
- approveProcessGetInfo({id: row.approveId,approveReason: '1'}).then(res => {
- form.value = {...res.data}
- // 鍙嶆樉瀹℃壒浜�
- if (res.data && res.data.approveUserIds) {
- const userIds = res.data.approveUserIds.split(',')
- approverNodes.value = userIds.map((userId, idx) => ({
- id: idx + 1,
- userId: parseInt(userId.trim())
- }))
- nextApproverId = userIds.length + 1
- } else {
- approverNodes.value = [{ id: 1, userId: null }]
- nextApproverId = 2
- }
- })
- }
-}
-const getProductOptions = () => {
- getDept().then((res) => {
- productOptions.value = res.data;
- });
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
- form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
- form.value.approveType = props.approveType
- // 瀹℃壒浜哄繀濉牎楠�
- const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
- if (hasEmptyApprover) {
- proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒")
- return
- }
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- if (operationType.value === "add" || currentApproveStatus.value == 3) {
- approveProcessAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- approveProcessUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- fileList.value = []
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- // 鏍℃鏂囦欢澶у皬
- // if (file.size > 1024 * 1024 * 10) {
- // proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- // return false;
- // }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- // 纭繚 tempFileIds 瀛樺湪涓斾负鏁扮粍
- if (!form.value.tempFileIds) {
- form.value.tempFileIds = [];
- }
- form.value.tempFileIds.push(res.data.tempId);
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/fileList.vue b/src/views/collaborativeApproval/approvalProcess/fileList.vue
deleted file mode 100644
index da37db2..0000000
--- a/src/views/collaborativeApproval/approvalProcess/fileList.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<template>
- <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
- <el-table :data="tableData" border height="40vh">
- <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">
- <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
- <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import filePreview from '@/components/filePreview/index.vue'
-
-const dialogVisible = ref(false)
-const tableData = ref([])
-const { proxy } = getCurrentInstance();
-const filePreviewRef = ref()
-const handleClose = () => {
- dialogVisible.value = false
-}
-const open = (list) => {
- dialogVisible.value = true
- tableData.value = list
-}
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-
-}
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-defineExpose({
- open
-})
-</script>
-
-<style></style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
deleted file mode 100644
index 13e155b..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ /dev/null
@@ -1,295 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">娴佺▼缂栧彿锛�</span>
- <el-input
- v-model="searchForm.approveId"
- style="width: 240px"
- placeholder="璇疯緭鍏ユ祦绋嬬紪鍙锋悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title ml10">瀹℃壒鐘舵�侊細</span>
- <el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
- <el-option label="寰呭鏍�" :value="0" />
- <el-option label="瀹℃牳涓�" :value="1" />
- <el-option label="瀹℃牳瀹屾垚" :value="2" />
- <el-option label="瀹℃牳鏈�氳繃" :value="3" />
- <el-option label="宸查噸鏂版彁浜�" :value="4" />
- </el-select>
- <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>
- <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
- <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
- <FileList ref="fileListRef" />
- </div>
-</template>
-
-<script setup>
-import FileList from "./fileList.vue";
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
-import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
-import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
-import useUserStore from "@/store/modules/user";
-
-// 瀹氫箟缁勪欢鎺ユ敹鐨刾rops
-const props = defineProps({
- approveType: {
- type: [Number, String],
- default: 0
- }
-});
-
-const userStore = useUserStore();
-
-
-const data = reactive({
- searchForm: {
- approveId: "",
- approveStatus: "",
- },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
- {
- label: "瀹℃壒鐘舵��",
- prop: "approveStatus",
- dataType: "tag",
- width: 100,
- formatData: (params) => {
- if (params == 0) {
- return "寰呭鏍�";
- } else if (params == 1) {
- return "瀹℃牳涓�";
- } else if (params == 2) {
- return "瀹℃牳瀹屾垚";
- } else if (params == 4) {
- return "宸查噸鏂版彁浜�";
- } else {
- return '涓嶉�氳繃';
- }
- },
- formatType: (params) => {
- if (params == 0) {
- return "warning";
- } else if (params == 1) {
- return "primary";
- } else if (params == 2) {
- return "success";
- } else if (params == 4) {
- return "";
- } else {
- return 'danger';
- }
- },
- },
- {
- label: "娴佺▼缂栧彿",
- prop: "approveId",
- width: 170
- },
- {
- label: "鐢宠閮ㄩ棬",
- prop: "approveDeptName",
- width: 220
- },
- {
- label: "瀹℃壒浜嬬敱",
- prop: "approveReason",
- width: 200
- },
- {
- label: "鐢宠浜�",
- prop: "approveUserName",
- width: 120
- },
- {
- label: "鐢宠鏃ユ湡",
- prop: "approveTime",
- width: 200
- },
- {
- label: "缁撴潫鏃ユ湡",
- prop: "approveOverTime",
- width: 120
- },
- {
- label: "褰撳墠瀹℃壒浜�",
- prop: "approveUserCurrentName",
- width: 120
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 230,
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
- },
- {
- name: "瀹℃牳",
- type: "text",
- clickFun: (row) => {
- openApprovalDia("approval", row);
- },
- disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
- },
- {
- name: "璇︽儏",
- type: "text",
- clickFun: (row) => {
- openApprovalDia('view', row);
- },
- },
- {
- name: "闄勪欢",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0
-});
-const infoFormDia = ref()
-const approvalDia = ref()
-const { proxy } = getCurrentInstance()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const fileListRef = ref(null)
-const downLoadFile = (row) => {
- fileListRef.value.open(row.commonFileList)
-
-}
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- approveProcessListPage({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 瀵煎嚭
-const handleOut = () => {
- const type = Number(props.approveType || 0)
- const urlMap = {
- 0: "/approveProcess/exportZero",
- 1: "/approveProcess/exportOne",
- 2: "/approveProcess/exportTwo",
- 3: "/approveProcess/exportThree",
- 4: "/approveProcess/exportFour",
- 5: "/approveProcess/exportFive",
- }
- const url = urlMap[type] || urlMap[0]
- const nameMap = {
- 0: "鍗忓悓瀹℃壒绠$悊琛�",
- 1: "鍏嚭绠$悊瀹℃壒琛�",
- 2: "璇峰亣绠$悊瀹℃壒琛�",
- 3: "鍑哄樊绠$悊瀹℃壒琛�",
- 4: "鎶ラ攢绠$悊瀹℃壒琛�",
- 5: "閲囪喘鐢宠瀹℃壒琛�",
- }
- const fileName = nameMap[type] || nameMap[0]
- proxy.download(url, {}, `${fileName}.xlsx`)
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑鏂板銆佺紪杈戝脊妗�
-const openForm = (type, row) => {
- nextTick(() => {
- infoFormDia.value?.openDialog(type, row)
- })
-};
-// 鎵撳紑鏂板妫�楠屽脊妗�
-const openApprovalDia = (type, row) => {
- nextTick(() => {
- approvalDia.value?.openDialog(type, row)
- })
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.approveId);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- approveProcessDelete(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/collaborativeApproval/approvalProcess/index1.vue b/src/views/collaborativeApproval/approvalProcess/index1.vue
deleted file mode 100644
index c46c68a..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index1.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
- <div class="container">
- <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
- <ApprovalProcessIndex :approveType="1" />
- </div>
-</template>
-
-<script setup>
-import ApprovalProcessIndex from './index.vue'
-
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
- name: 'ApprovalProcessIndex1'
-})
-</script>
-
-<style scoped>
-.container {
- width: 100%;
- height: 100%;
-}
-</style>
diff --git a/src/views/collaborativeApproval/approvalProcess/index2.vue b/src/views/collaborativeApproval/approvalProcess/index2.vue
deleted file mode 100644
index 7c15c3e..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index2.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
- <div class="container">
- <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
- <ApprovalProcessIndex :approveType="2" />
- </div>
-</template>
-
-<script setup>
-import ApprovalProcessIndex from './index.vue'
-
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
- name: 'ApprovalProcessIndex1'
-})
-</script>
-
-<style scoped>
-.container {
- width: 100%;
- height: 100%;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index3.vue b/src/views/collaborativeApproval/approvalProcess/index3.vue
deleted file mode 100644
index 3afb6f5..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index3.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
- <div class="container">
- <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
- <ApprovalProcessIndex :approveType="3" />
- </div>
-</template>
-
-<script setup>
-import ApprovalProcessIndex from './index.vue'
-
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
- name: 'ApprovalProcessIndex1'
-})
-</script>
-
-<style scoped>
-.container {
- width: 100%;
- height: 100%;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index4.vue b/src/views/collaborativeApproval/approvalProcess/index4.vue
deleted file mode 100644
index 77236af..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index4.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
- <div class="container">
- <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
- <ApprovalProcessIndex :approveType="4" />
- </div>
-</template>
-
-<script setup>
-import ApprovalProcessIndex from './index.vue'
-
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
- name: 'ApprovalProcessIndex1'
-})
-</script>
-
-<style scoped>
-.container {
- width: 100%;
- height: 100%;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index5.vue b/src/views/collaborativeApproval/approvalProcess/index5.vue
deleted file mode 100644
index 2e0f4f3..0000000
--- a/src/views/collaborativeApproval/approvalProcess/index5.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
- <div class="container">
- <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
- <ApprovalProcessIndex :approveType="5" />
- </div>
-</template>
-
-<script setup>
-import ApprovalProcessIndex from './index.vue'
-
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
- name: 'ApprovalProcessIndex1'
-})
-</script>
-
-<style scoped>
-.container {
- width: 100%;
- height: 100%;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/attendanceManagement/index.vue b/src/views/collaborativeApproval/attendanceManagement/index.vue
deleted file mode 100644
index f6a3e3c..0000000
--- a/src/views/collaborativeApproval/attendanceManagement/index.vue
+++ /dev/null
@@ -1,1244 +0,0 @@
-<template>
- <div class="app-container">
- <el-tabs v-model="activeTab" type="border-card">
- <!-- 鍋囨湡璁剧疆 -->
- <el-tab-pane label="鍋囨湡璁剧疆" name="holiday">
- <div class="tab-content">
- <el-button type="primary" @click="openDialog('holiday', 'add')">鏂板鍋囨湡</el-button>
-
- <el-table :data="holidayData" border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="name" label="鍋囨湡鍚嶇О" />
- <el-table-column prop="type" label="鍋囨湡绫诲瀷">
- <template #default="scope">
- <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="startDate" label="寮�濮嬫棩鏈�" />
- <el-table-column prop="endDate" label="缁撴潫鏃ユ湡" />
- <el-table-column prop="days" label="澶╂暟" align="center" />
- <el-table-column prop="status" label="鐘舵��" >
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" fixed="right">
- <template #default="scope">
- <el-button type="primary" size="small" @click="openDialog('holiday', 'edit', scope.row)">缂栬緫</el-button>
- <el-button type="danger" size="small" @click="deleteItem('holiday', scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-tab-pane>
-
- <!-- 骞村亣璁剧疆 -->
- <el-tab-pane label="骞村亣璁剧疆" name="annual">
- <div class="tab-content">
- <el-button type="primary" @click="openDialog('annual', 'add')">鏂板骞村亣瑙勫垯</el-button>
-
- <el-table :data="annualData" border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="employeeType" label="鍛樺伐绫诲瀷">
- <template #default="scope">
- <el-tag :type="getTagType(scope.row.employeeType)">{{ getTypeLabel(scope.row.employeeType) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="workYears" label="宸ヤ綔骞撮檺" />
- <el-table-column prop="annualDays" label="骞村亣澶╂暟" align="center" />
- <el-table-column prop="maxCarryOver" label="鏈�澶х粨杞ぉ鏁�" align="center" />
- <el-table-column prop="status" label="鐘舵��">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" fixed="right">
- <template #default="scope">
- <el-button type="primary" size="small" @click="openDialog('annual', 'edit', scope.row)">缂栬緫</el-button>
- <el-button type="danger" size="small" @click="deleteItem('annual', scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-tab-pane>
-
- <!-- 鍔犵彮璁剧疆 -->
- <el-tab-pane label="鍔犵彮璁剧疆" name="overtime">
- <div class="tab-content">
- <el-button type="primary" @click="openDialog('overtime', 'add')">鏂板鍔犵彮瑙勫垯</el-button>
-
- <el-table :data="overtimeData" border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="name" label="瑙勫垯鍚嶇О" />
- <el-table-column prop="type" label="鍔犵彮绫诲瀷" >
- <template #default="scope">
- <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="startTime" label="寮�濮嬫椂闂�" />
- <el-table-column prop="endTime" label="缁撴潫鏃堕棿" />
- <el-table-column prop="rate" label="鍊嶇巼" align="center" />
- <el-table-column prop="status" label="鐘舵��" >
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" fixed="right">
- <template #default="scope">
- <el-button type="primary" size="small" @click="openDialog('overtime', 'edit', scope.row)">缂栬緫</el-button>
- <el-button type="danger" size="small" @click="deleteItem('overtime', scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-tab-pane>
-
- <!-- 涓婄彮鏃堕棿璁剧疆 -->
- <el-tab-pane label="涓婄彮鏃堕棿璁剧疆" name="worktime">
- <div class="tab-content">
- <el-button type="primary" @click="openDialog('worktime', 'add')">鏂板鏃堕棿娈�</el-button>
-
- <el-table :data="worktimeData" border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="name" label="鏃堕棿娈靛悕绉�" />
- <el-table-column prop="startTime" label="涓婄彮鏃堕棿"/>
- <el-table-column prop="endTime" label="涓嬬彮鏃堕棿" />
- <el-table-column prop="flexibleStart" label="寮规�т笂鐝�">
- <template #default="scope">
- <el-tag :type="scope.row.flexibleStart === 'true' ? 'success' : 'info'">
- {{ scope.row.flexibleStart === 'true' ? '鏄�' : '鍚�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="flexibleMinutes" label="寮规�ф椂闂�(鍒嗛挓)" width="120" align="center" />
- <el-table-column prop="status" label="鐘舵��" >
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" fixed="right">
- <template #default="scope">
- <el-button type="primary" size="small" @click="openDialog('worktime', 'edit', scope.row)">缂栬緫</el-button>
- <el-button type="danger" size="small" @click="deleteItem('worktime', scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-tab-pane>
-
- <!-- 鎵撳崱璁板綍 -->
- <el-tab-pane label="鎵撳崱璁板綍" name="attendance">
- <div class="tab-content">
- <div style="margin-bottom: 20px;">
- <el-date-picker
- v-model="attendanceDate"
- type="date"
- placeholder="閫夋嫨鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="margin-right: 10px;"
- @change="filterAttendanceData"
- />
- <el-select
- v-model="attendanceStatus"
- placeholder="閫夋嫨鐘舵��"
- style="width: 120px; margin-right: 10px;"
- @change="filterAttendanceData"
- >
- <el-option label="鍏ㄩ儴" value="" />
- <el-option label="姝e父" value="normal" />
- <el-option label="杩熷埌" value="late" />
- <el-option label="鏃╅��" value="early" />
- <el-option label="缂哄嫟" value="absent" />
- </el-select>
- <el-button type="primary" @click="exportAttendance">瀵煎嚭璁板綍</el-button>
- </div>
-
- <el-table :data="filteredAttendanceData" border style="width: 100%;">
- <el-table-column prop="employeeName" label="鍛樺伐濮撳悕" width="120" />
- <el-table-column prop="department" label="閮ㄩ棬" width="120" />
- <el-table-column prop="date" label="鏃ユ湡" width="120" />
- <el-table-column prop="clockInTime" label="涓婄彮鎵撳崱" width="120" />
- <el-table-column prop="clockOutTime" label="涓嬬彮鎵撳崱" width="120" />
- <el-table-column prop="workHours" label="宸ヤ綔鏃堕暱" width="100" align="center" />
- <el-table-column prop="status" label="鐘舵��" width="100" align="center">
- <template #default="scope">
- <el-tag :type="getAttendanceTagType(scope.row.status)">{{ getAttendanceStatusLabel(scope.row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="location" label="鎵撳崱鍦扮偣" width="150" />
- <el-table-column prop="remark" label="澶囨敞" min-width="150" />
- </el-table>
- </div>
- </el-tab-pane>
- </el-tabs>
-
- <!-- 閫氱敤寮圭獥 -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
- <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
- <el-form-item label="鍚嶇О" prop="name" v-if="currentType !== 'annual'">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" />
- </el-form-item>
-
- <el-form-item label="绫诲瀷" prop="type" v-if="currentType === 'holiday' || currentType === 'overtime'">
- <el-select v-model="form.type" placeholder="璇烽�夋嫨绫诲瀷" style="width: 100%">
- <el-option
- v-for="option in getTypeOptions()"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </el-form-item>
-
- <el-form-item label="鍛樺伐绫诲瀷" prop="employeeType" v-if="currentType === 'annual'">
- <el-select v-model="form.employeeType" placeholder="璇烽�夋嫨鍛樺伐绫诲瀷" style="width: 100%">
- <!-- <el-option label="姝e紡鍛樺伐" value="regular" />
- <el-option label="璇曠敤鏈熷憳宸�" value="probation" />
- <el-option label="瀹炰範鐢�" value="intern" /> -->
- <el-option
- v-for="option in getTypeOptions()"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </el-form-item>
-
- <el-form-item label="宸ヤ綔骞撮檺" prop="workYears" v-if="currentType === 'annual'">
- <el-input v-model="form.workYears" placeholder="濡傦細1-3骞淬��3-5骞寸瓑" />
- </el-form-item>
-
- <el-form-item label="骞村亣澶╂暟" prop="annualDays" v-if="currentType === 'annual'">
- <el-input-number v-model="form.annualDays" :min="0" :max="365" style="width: 100%" />
- </el-form-item>
-
- <el-form-item label="鏈�澶х粨杞ぉ鏁�" prop="maxCarryOver" v-if="currentType === 'annual'">
- <el-input-number v-model="form.maxCarryOver" :min="0" :max="30" style="width: 100%" />
- </el-form-item>
-
- <el-form-item label="鏃ユ湡鑼冨洿" prop="dateRange" v-if="currentType === 'holiday'">
- <el-date-picker
- v-model="form.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- style="width: 100%"
- @change="calculateDays"
- />
- </el-form-item>
-
- <el-form-item label="澶╂暟" prop="days" v-if="currentType === 'holiday'">
- <el-input-number v-model="form.days" :min="0" style="width: 100%" />
- </el-form-item>
-
- <el-form-item label="寮�濮嬫椂闂�" prop="startTime" v-if="currentType === 'overtime'">
- <el-time-picker
- v-model="form.startTime"
- placeholder="寮�濮嬫椂闂�"
- format="HH:mm"
- value-format="HH:mm"
- style="width: 100%"
- @change="validateTimeField('startTime')"
- />
- </el-form-item>
-
- <el-form-item label="缁撴潫鏃堕棿" prop="endTime" v-if="currentType === 'overtime'">
- <el-time-picker
- v-model="form.endTime"
- placeholder="缁撴潫鏃堕棿"
- format="HH:mm"
- value-format="HH:mm"
- style="width: 100%"
- @change="validateTimeField('endTime')"
- />
- </el-form-item>
-
- <el-form-item label="鍊嶇巼" prop="rate" v-if="currentType === 'overtime'">
- <el-input-number v-model="form.rate" :min="1" :max="3" :step="0.5" style="width: 100%" />
- </el-form-item>
-
- <el-form-item label="涓婄彮鏃堕棿" prop="workStartTime" v-if="currentType === 'worktime'">
- <el-time-picker
- v-model="form.workStartTime"
- placeholder="涓婄彮鏃堕棿"
- format="HH:mm"
- value-format="HH:mm"
- style="width: 100%"
- @change="validateTimeField('workStartTime')"
- />
- </el-form-item>
-
- <el-form-item label="涓嬬彮鏃堕棿" prop="workEndTime" v-if="currentType === 'worktime'">
- <el-time-picker
- v-model="form.workEndTime"
- placeholder="涓嬬彮鏃堕棿"
- format="HH:mm"
- value-format="HH:mm"
- style="width: 100%"
- @change="validateTimeField('workEndTime')"
- />
- </el-form-item>
-
- <el-form-item label="寮规�т笂鐝�" prop="flexibleStart" v-if="currentType === 'worktime'">
- <el-switch v-model="form.flexibleStart" />
- </el-form-item>
-
- <el-form-item label="寮规�ф椂闂�(鍒嗛挓)" prop="flexibleMinutes" v-if="currentType === 'worktime' && form.flexibleStart">
- <el-input-number v-model="form.flexibleMinutes" :min="0" :max="120" style="width: 100%" />
- </el-form-item>
-
- <el-form-item label="鐘舵��" prop="status">
- <el-radio-group v-model="form.status">
- <el-radio value="active">鍚敤</el-radio>
- <el-radio value="inactive">鍋滅敤</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
-
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { listHolidaySettings, addHolidaySettings, updateHolidaySettings, delHolidaySettings, listAnnualLeaveSettingList, addAnnualLeaveSetting, updateAnnualLeaveSetting, delAnnualLeaveSetting, listOvertimeSettingList, addOvertimeSetting, updateOvertimeSetting, delOvertimeSetting, listWorkingHoursSettingList, addWorkingHoursSetting, updateWorkingHoursSetting, delWorkingHoursSetting } from '@/api/collaborativeApproval/attendanceManagement.js'
-
-// 褰撳墠婵�娲荤殑鏍囩椤�
-const activeTab = ref('holiday')
-
-// 寮圭獥鐩稿叧
-const dialogVisible = ref(false)
-const dialogTitle = ref('')
-const currentType = ref('')
-const currentAction = ref('')
-const currentEditId = ref('')
-const formRef = ref()
-const page = {
- current: 1,
- size: 20,
- total: 0,
- }
-const holidayData = ref([])
-const annualData = ref([])
-const overtimeData = ref([])
-const worktimeData = ref([])
-
-// 鎵撳崱璁板綍鐩稿叧鏁版嵁
-const attendanceData = ref([])
-const filteredAttendanceData = ref([])
-const attendanceDate = ref('')
-const attendanceStatus = ref('')
-
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
- name: '',
- type: '',
- dateRange: [],
- startDate: '',
- endDate: '',
- days: 0,
- employeeType: '',
- workYears: '',
- annualDays: 0,
- maxCarryOver: 0,
- startTime: '', // 鍔犵彮寮�濮嬫椂闂�
- endTime: '', // 鍔犵彮缁撴潫鏃堕棿
- workStartTime: '', // 涓婄彮鏃堕棿
- workEndTime: '', // 涓嬬彮鏃堕棿
- rate: 1.5,
- flexibleStart: false,
- flexibleMinutes: 30,
- status: 'active'
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }],
- type: [{ required: true, message: '璇烽�夋嫨绫诲瀷', trigger: 'change' }],
- dateRange: [{ required: true, message: '璇烽�夋嫨鏃ユ湡鑼冨洿', trigger: 'change' }],
- days: [{ required: true, message: '璇疯緭鍏ュぉ鏁�', trigger: 'blur' }],
- employeeType: [{ required: true, message: '璇烽�夋嫨鍛樺伐绫诲瀷', trigger: 'change' }],
- workYears: [{ required: true, message: '璇疯緭鍏ュ伐浣滃勾闄�', trigger: 'blur' }],
- annualDays: [{ required: true, message: '璇疯緭鍏ュ勾鍋囧ぉ鏁�', trigger: 'blur' }],
- maxCarryOver: [{ required: true, message: '璇疯緭鍏ユ渶澶х粨杞ぉ鏁�', trigger: 'blur' }],
- startTime: [{
- required: true,
- message: '璇烽�夋嫨寮�濮嬫椂闂�',
- trigger: 'change',
- validator: (rule, value, callback) => {
- if (!value) {
- callback(new Error('璇烽�夋嫨寮�濮嬫椂闂�'))
- } else {
- callback()
- }
- }
- }],
- endTime: [{
- required: true,
- message: '璇烽�夋嫨缁撴潫鏃堕棿',
- trigger: 'change',
- validator: (rule, value, callback) => {
- if (!value) {
- callback(new Error('璇烽�夋嫨缁撴潫鏃堕棿'))
- } else {
- callback()
- }
- }
- }],
- workStartTime: [{
- required: true,
- message: '璇烽�夋嫨涓婄彮鏃堕棿',
- trigger: 'change',
- validator: (rule, value, callback) => {
- if (!value) {
- callback(new Error('璇烽�夋嫨涓婄彮鏃堕棿'))
- } else {
- callback()
- }
- }
- }],
- workEndTime: [{
- required: true,
- message: '璇烽�夋嫨涓嬬彮鏃堕棿',
- trigger: 'change',
- validator: (rule, value, callback) => {
- if (!value) {
- callback(new Error('璇烽�夋嫨涓嬬彮鏃堕棿'))
- } else {
- callback()
- }
- }
- }],
- rate: [{ required: true, message: '璇疯緭鍏ュ�嶇巼', trigger: 'blur' }]
-}
-// 宸ュ叿鍑芥暟
-const getTagType = (type) => {
- const tagMap = {
- legal: 'success', adjustment: 'warning', special: 'info', company: 'primary',
- weekday: 'primary', weekend: 'warning', holiday: 'danger', night: 'info',
- regular: 'success', probation: 'info', intern: 'danger'
- }
- return tagMap[type] || 'info'
-}
-
-const getTypeLabel = (type) => {
- const labelMap = {
- legal: '娉曞畾鑺傚亣鏃�', adjustment: '璋冧紤鏃�', special: '鐗规畩鍋囨湡', company: '鍏徃鍋囨湡',
- weekday: '宸ヤ綔鏃ュ姞鐝�', weekend: '鍛ㄦ湯鍔犵彮', holiday: '鑺傚亣鏃ュ姞鐝�', night: '娣卞鍔犵彮',
- regular: '姝e紡鍛樺伐', probation: '璇曠敤鏈熷憳宸�', intern: '瀹炰範鐢�'
- }
- return labelMap[type] || type
-}
-
-// 鎵撳崱璁板綍鐩稿叧宸ュ叿鍑芥暟
-const getAttendanceTagType = (status) => {
- const tagMap = {
- normal: 'success',
- late: 'warning',
- early: 'warning',
- absent: 'danger'
- }
- return tagMap[status] || 'info'
-}
-
-const getAttendanceStatusLabel = (status) => {
- const labelMap = {
- normal: '姝e父',
- late: '杩熷埌',
- early: '鏃╅��',
- absent: '缂哄嫟'
- }
- return labelMap[status] || status
-}
-
-const getTypeOptions = () => {
- if (currentType.value === 'holiday') {
- return [
- { label: '娉曞畾鑺傚亣鏃�', value: 'legal' },
- { label: '璋冧紤鏃�', value: 'adjustment' },
- { label: '鐗规畩鍋囨湡', value: 'special' },
- { label: '鍏徃鍋囨湡', value: 'company' }
- ]
- } else if (currentType.value === 'overtime') {
- return [
- { label: '宸ヤ綔鏃ュ姞鐝�', value: 'weekday' },
- { label: '鍛ㄦ湯鍔犵彮', value: 'weekend' },
- { label: '鑺傚亣鏃ュ姞鐝�', value: 'holiday' },
- { label: '娣卞鍔犵彮', value: 'night' }
- ]
- } else if (currentType.value === 'annual') {
- return [
- { label: '姝e紡鍛樺伐', value: 'regular' },
- { label: '璇曠敤鏈熷憳宸�', value: 'probation' },
- { label: '瀹炰範鐢�', value: 'intern' }
- ]
- }
- return []
-}
-
-// 璁$畻鍋囨湡澶╂暟
-const calculateDays = () => {
- try {
- if (form.dateRange && form.dateRange.length === 2 && form.dateRange[0] && form.dateRange[1]) {
- const start = new Date(form.dateRange[0])
- const end = new Date(form.dateRange[1])
- form.startDate = start.toISOString().split('T')[0]
- form.endDate = end.toISOString().split('T')[0]
-
- if (isNaN(start.getTime()) || isNaN(end.getTime())) {
- console.warn('鏃犳晥鐨勬棩鏈熸牸寮�')
- return
- }
-
- const diffTime = Math.abs(end - start)
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1
- form.days = diffDays
- }
- } catch (error) {
- console.error('璁$畻澶╂暟澶辫触:', error)
- }
-}
-
-// 楠岃瘉鏃堕棿鏍煎紡
-// const validateTime = (time) => {
-// if (!time) return ''
-// if (typeof time === 'string') return time
-// if (time instanceof Date) {
-// return time.toTimeString().slice(0, 5)
-// }
-// return ''
-// }
-
-// 楠岃瘉鏃堕棿瀛楁
-const validateTimeField = (fieldName) => {
- try {
- const value = form[fieldName]
- if (value && typeof value === 'object' && value.hour !== undefined) {
- // 濡傛灉鏄椂闂村璞★紝杞崲涓哄瓧绗︿覆鏍煎紡
- const hours = value.hour.toString().padStart(2, '0')
- const minutes = value.minute.toString().padStart(2, '0')
- form[fieldName] = `${hours}:${minutes}`
- }
- } catch (error) {
- console.error(`楠岃瘉鏃堕棿瀛楁 ${fieldName} 澶辫触:`, error)
- form[fieldName] = ''
- }
-}
-
-// 鎵撳紑寮圭獥
-const openDialog = (type, action, row = null) => {
- try {
- currentType.value = type
- currentAction.value = action
-
- if (action === 'add') {
- dialogTitle.value = `鏂板${getTypeName(type)}`
- currentEditId.value = ''
- resetForm()
- } else if (action === 'edit' && row) {
- dialogTitle.value = `缂栬緫${getTypeName(type)}`
- currentEditId.value = row.id
- fillForm(row)
- }
-
- dialogVisible.value = true
- } catch (error) {
- console.error('鎵撳紑寮圭獥澶辫触:', error)
- ElMessage.error('鎵撳紑寮圭獥澶辫触锛岃閲嶈瘯')
- }
-}
-
-const getTypeName = (type) => {
- const nameMap = {
- holiday: '鍋囨湡',
- annual: '骞村亣瑙勫垯',
- overtime: '鍔犵彮瑙勫垯',
- worktime: '鏃堕棿娈�'
- }
- return nameMap[type] || ''
-}
-
-const resetForm = () => {
- Object.assign(form, {
- name: '',
- type: '',
- dateRange: [],
- startDate: '',
- endDate: '',
- days: 0,
- employeeType: '',
- workYears: '',
- annualDays: 0,
- maxCarryOver: 0,
- startTime: '',
- endTime: '',
- workStartTime: '',
- workEndTime: '',
- rate: 1.5,
- flexibleStart: false,
- flexibleMinutes: 30,
- status: 'active'
- })
-}
-
-const fillForm = (row) => {
- if (currentType.value === 'holiday') {
- Object.assign(form, {
- name: row.name,
- type: row.type,
- dateRange: [new Date(row.startDate), new Date(row.endDate)],
- startDate: row.startDate,
- endDate: row.endDate,
- days: row.days,
- status: row.status
- })
- } else if (currentType.value === 'annual') {
- Object.assign(form, {
- employeeType: row.employeeType,
- workYears: row.workYears,
- annualDays: row.annualDays,
- maxCarryOver: row.maxCarryOver,
- status: row.status
- })
- } else if (currentType.value === 'overtime') {
- Object.assign(form, {
- name: row.name,
- type: row.type,
- startTime: row.startTime || '',
- endTime: row.endTime || '',
- rate: row.rate,
- status: row.status
- })
- } else if (currentType.value === 'worktime') {
- Object.assign(form, {
- name: row.name,
- workStartTime: row.startTime || '',
- workEndTime: row.endTime || '',
- flexibleStart: row.flexibleStart,
- flexibleMinutes: row.flexibleMinutes,
- status: row.status
- })
- }
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- if (!formRef.value) {
- ElMessage.error('琛ㄥ崟寮曠敤涓嶅瓨鍦�')
- return
- }
-
- await formRef.value.validate()
-
- if (currentAction.value === 'add') {
- addItem()
- } else if (currentAction.value === 'edit') {
- editItem()
- }
-
- dialogVisible.value = false
- ElMessage.success('鎿嶄綔鎴愬姛')
- } catch (error) {
- console.error('琛ㄥ崟楠岃瘉澶辫触:', error)
- ElMessage.error('琛ㄥ崟楠岃瘉澶辫触锛岃妫�鏌ヨ緭鍏�')
- }
-}
-
-const addItem = () => {
-
- if (currentType.value === 'holiday') {
- const params = {
- name: form.name,
- type: form.type,
- startDate: form.startDate,
- endDate: form.endDate,
- days: form.days,
- status: form.status
- }
- addHolidaySettings(params).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- // dialogVisible.value = false;
- getHolidaySettingsList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else if (currentType.value === 'annual') {
- // annualData.value.push(newItem)
- const params = {
- employeeType: form.employeeType,
- workYears: form.workYears,
- annualDays: form.annualDays,
- maxCarryOver: form.maxCarryOver,
- status: form.status
- }
- addAnnualLeaveSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- // dialogVisible.value = false;
- getAnnualLeaveSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else if (currentType.value === 'overtime') {
- const params = {
- name: form.name,
- type: form.type,
- startTime: form.startTime || '',
- endTime: form.endTime || '',
- rate: form.rate,
- status: form.status
- }
- addOvertimeSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- // dialogVisible.value = false;
- getOvertimeSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // newItem.startTime = form.startTime || ''
- // newItem.endTime = form.endTime || ''
- // overtimeData.value.push(newItem)
- } else if (currentType.value === 'worktime') {
- const params = {
- name: form.name,
- startTime: form.workStartTime || '',
- endTime: form.workEndTime || '',
- flexibleStart: form.flexibleStart,
- flexibleMinutes: form.flexibleMinutes,
- status: form.status
- }
- addWorkingHoursSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- getWorkingHoursSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // newItem.startTime = form.workStartTime || ''
- // newItem.endTime = form.workEndTime || ''
- // worktimeData.value.push(newItem)
- }
-}
-
-const editItem = () => {
- let dataArray
- let index
-
- if (currentType.value === 'holiday') {
- const params = {
- id: currentEditId.value,
- name: form.name,
- type: form.type,
- startDate: form.dateRange[0].toISOString().split('T')[0],
- endDate: form.dateRange[1].toISOString().split('T')[0],
- days: form.days,
- status: form.status
- }
- updateHolidaySettings(params).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- // dialogVisible.value = false;
- getHolidaySettingsList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else if (currentType.value === 'annual') {
- const params = {
- id: currentEditId.value,
- employeeType: form.employeeType,
- workYears: form.workYears,
- annualDays: form.annualDays,
- maxCarryOver: form.maxCarryOver,
- status: form.status
- }
- updateAnnualLeaveSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- getAnnualLeaveSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else if (currentType.value === 'overtime') {
- const params = {
- id: currentEditId.value,
- name: form.name,
- type: form.type,
- startTime: form.startTime || '',
- endTime: form.endTime || '',
- rate: form.rate,
- status: form.status
- }
- updateOvertimeSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- getOvertimeSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-
- // dataArray = overtimeData.value
- // index = dataArray.findIndex(item => item.id === currentEditId.value)
- // if (index > -1) {
- // dataArray[index] = {
- // ...dataArray[index],
- // name: form.name,
- // type: form.type,
- // startTime: form.startTime || '',
- // endTime: form.endTime || '',
- // rate: form.rate,
- // status: form.status
- // }
- // }
- } else if (currentType.value === 'worktime') {
- const params = {
- id: currentEditId.value,
- name: form.name,
- startTime: form.workStartTime || '',
- endTime: form.workEndTime || '',
- flexibleStart: form.flexibleStart,
- flexibleMinutes: form.flexibleMinutes,
- status: form.status
- }
- updateWorkingHoursSetting(params).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- getWorkingHoursSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // dataArray = worktimeData.value
- // index = dataArray.findIndex(item => item.id === currentEditId.value)
- // if (index > -1) {
- // dataArray[index] = {
- // ...dataArray[index],
- // name: form.name,
- // startTime: form.workStartTime || '',
- // endTime: form.workEndTime || '',
- // flexibleStart: form.flexibleStart,
- // flexibleMinutes: form.flexibleMinutes,
- // status: form.status
- // }
- // }
- }
-}
-
-// 鎵撳崱璁板綍杩囨护鍔熻兘
-const filterAttendanceData = () => {
- let filtered = attendanceData.value
-
- // 鎸夋棩鏈熻繃婊�
- if (attendanceDate.value) {
- filtered = filtered.filter(item => item.date === attendanceDate.value)
- }
-
- // 鎸夌姸鎬佽繃婊�
- if (attendanceStatus.value) {
- filtered = filtered.filter(item => item.status === attendanceStatus.value)
- }
-
- filteredAttendanceData.value = filtered
-}
-
-// 瀵煎嚭鎵撳崱璁板綍
-const exportAttendance = () => {
- ElMessage.success('瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-// 鍒濆鍖栨墦鍗¤褰曞亣鏁版嵁
-const initAttendanceData = () => {
- const mockData = [
- {
- id: 1,
- employeeName: '闄堝織寮�',
- department: '鎶�鏈儴',
- date: '2025-08-15',
- clockInTime: '09:00:00',
- clockOutTime: '18:00:00',
- workHours: '8.0h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 2,
- employeeName: '鏉庨洩姊�',
- department: '甯傚満閮�',
- date: '2025-08-16',
- clockInTime: '08:58:00',
- clockOutTime: '18:05:00',
- workHours: '8.12h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 3,
- employeeName: '鐜嬪缓鍗�',
- department: '浜轰簨閮�',
- date: '2025-08-16',
- clockInTime: '09:02:00',
- clockOutTime: '18:00:00',
- workHours: '7.97h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 4,
- employeeName: '璧垫檽涓�',
- department: '璐㈠姟閮�',
- date: '2025-09-02',
- clockInTime: '08:55:00',
- clockOutTime: '18:10:00',
- workHours: '8.25h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 5,
- employeeName: '寮犲浗搴�',
- department: '鎶�鏈儴',
- date: '2025-09-02',
- clockInTime: '09:00:00',
- clockOutTime: '18:30:00',
- workHours: '8.5h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: '鍔犵彮'
- },
- {
- id: 6,
- employeeName: '鍒樻槑杈�',
- department: '杩愯惀閮�',
- date: '2025-09-03',
- clockInTime: '09:05:00',
- clockOutTime: '18:00:00',
- workHours: '7.92h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 7,
- employeeName: '瀛欎附鍗�',
- department: '璁捐閮�',
- date: '2025-09-03',
- clockInTime: '08:59:00',
- clockOutTime: '18:02:00',
- workHours: '8.05h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 8,
- employeeName: '鍛ㄥ缓鍐�',
- department: '閿�鍞儴',
- date: '2025-09-04',
- clockInTime: '09:15:00',
- clockOutTime: '18:00:00',
- workHours: '7.75h',
- status: 'late',
- location: '鍏徃鎬婚儴',
- remark: '浜ら�氬牭濉�'
- },
- {
- id: 9,
- employeeName: '鍚村皬鑺�',
- department: '瀹㈡湇閮�',
- date: '2025-09-04',
- clockInTime: '09:01:00',
- clockOutTime: '18:00:00',
- workHours: '7.98h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 10,
- employeeName: '椹枃鏉�',
- department: '鎶�鏈儴',
- date: '2025-09-05',
- clockInTime: '08:57:00',
- clockOutTime: '17:30:00',
- workHours: '7.55h',
- status: 'early',
- location: '鍏徃鎬婚儴',
- remark: '鏈夋�ヤ簨鎻愬墠绂诲紑'
- },
- {
- id: 11,
- employeeName: '鏋楁檽涓�',
- department: '琛屾斂閮�',
- date: '2025-09-05',
- clockInTime: '09:03:00',
- clockOutTime: '18:08:00',
- workHours: '8.08h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 12,
- employeeName: '榛勭編鐜�',
- department: '璐㈠姟閮�',
- date: '2025-09-06',
- clockInTime: '',
- clockOutTime: '',
- workHours: '0h',
- status: 'absent',
- location: '',
- remark: '璇风梾鍋�'
- },
- {
- id: 13,
- employeeName: '閮戞捣娑�',
- department: '甯傚満閮�',
- date: '2025-08-14',
- clockInTime: '09:00:00',
- clockOutTime: '18:00:00',
- workHours: '8.0h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 14,
- employeeName: '璋附濞�',
- department: '浜轰簨閮�',
- date: '2025-08-20',
- clockInTime: '08:58:00',
- clockOutTime: '18:03:00',
- workHours: '8.08h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 15,
- employeeName: '浣曞織浼�',
- department: '鎶�鏈儴',
- date: '2025-08-21',
- clockInTime: '09:10:00',
- clockOutTime: '18:00:00',
- workHours: '7.83h',
- status: 'late',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 16,
- employeeName: '璁搁泤鑺�',
- department: '璁捐閮�',
- date: '2025-08-22',
- clockInTime: '09:01:00',
- clockOutTime: '18:00:00',
- workHours: '7.98h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 17,
- employeeName: '閭撳缓骞�',
- department: '杩愯惀閮�',
- date: '2025-09-10',
- clockInTime: '08:59:00',
- clockOutTime: '18:05:00',
- workHours: '8.1h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- },
- {
- id: 18,
- employeeName: '鏇惧皬绾�',
- department: '瀹㈡湇閮�',
- date: '2025-09-11',
- clockInTime: '09:02:00',
- clockOutTime: '18:00:00',
- workHours: '7.97h',
- status: 'normal',
- location: '鍏徃鎬婚儴',
- remark: ''
- }
- ]
-
- attendanceData.value = mockData
- filteredAttendanceData.value = mockData
-}
-
-// 鍒犻櫎椤圭洰
-const deleteItem = (type, row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓」鐩悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [];
- let dataArray
- if (type === 'holiday') {
- ids.push(row.id)
- delHolidaySettings(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- ids = []
- getHolidaySettingsList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- else if (type === 'annual') {
- ids.push(row.id)
- delAnnualLeaveSetting(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- ids = []
- getAnnualLeaveSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- else if (type === 'overtime') {
- ids.push(row.id)
- delOvertimeSetting(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- ids = []
- getOvertimeSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- else if (type === 'worktime') {
- ids.push(row.id)
- delWorkingHoursSetting(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- ids = []
- getWorkingHoursSettingList()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
-
- // const index = dataArray.findIndex(item => item.id === row.id)
- // if (index > -1) {
- // dataArray.splice(index, 1)
- // ElMessage.success('鍒犻櫎鎴愬姛')
- // }
- })
-}
-// 鑾峰彇鍋囨湡璁剧疆鍒楄〃
-const getHolidaySettingsList = () => {
- // tableLoading.value = true;
- listHolidaySettings({...page.value})
- .then(res => {
- // tableLoading.value = false;
- holidayData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- // tableLoading.value = false;
- })
-};
-// 鑾峰彇骞村亣瑙勫垯鍒楄〃
-const getAnnualLeaveSettingList = () => {
-
- listAnnualLeaveSettingList({...page.value})
- .then(res => {
- // console.log(res.data)
- annualData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- })
-};
-// 鑾峰彇鍔犵彮瑙勫垯鍒楄〃
-const getOvertimeSettingList = () => {
-
- listOvertimeSettingList({...page.value})
- .then(res => {
- // console.log(res.data)
- overtimeData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- })
-};
-// 鑾峰彇宸ヤ綔鏃堕棿瑙勫垯鍒楄〃
-const getWorkingHoursSettingList = () => {
-
- listWorkingHoursSettingList({...page.value})
- .then(res => {
- // console.log(res.data)
- worktimeData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- })
-};
-onMounted(() => {
- getHolidaySettingsList()
- getAnnualLeaveSettingList()
- getOvertimeSettingList()
- getWorkingHoursSettingList()
- initAttendanceData()
- console.log('鑰冨嫟绠$悊椤甸潰鍔犺浇瀹屾垚')
-})
-
-onUnmounted(() => {
- // 娓呯悊宸ヤ綔
- dialogVisible.value = false
- currentType.value = ''
- currentAction.value = ''
- currentEditId.value = ''
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.tab-content {
- padding: 20px 0;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-tabs__content) {
- padding: 20px;
-}
-
-:deep(.el-form-item) {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/enterpriseBook/index.vue b/src/views/collaborativeApproval/enterpriseBook/index.vue
deleted file mode 100644
index 0b33a32..0000000
--- a/src/views/collaborativeApproval/enterpriseBook/index.vue
+++ /dev/null
@@ -1,798 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 澶撮儴瀵艰埅 -->
- <!-- <div class="header">
- <h2>浼佷笟閫氳褰曠鐞�</h2>
- <p>绠$悊涓汉銆佸叕鍏卞拰鍗曚綅鐨勮仈绯绘柟寮�</p>
- </div> -->
-
- <!-- 鏍囩椤靛垏鎹� -->
- <el-tabs v-model="activeTab" @tab-change="handleTabChange" type="border-card">
- <el-tab-pane label="涓汉閫氳褰�" name="personal">
- <div class="tab-content">
- <!-- 鎼滅储妗� -->
- <el-input
- v-model="personalSearch.staffName"
- placeholder="鎼滅储鑱旂郴浜�"
- clearable
- prefix-icon="Search"
- class="search-input"
- @keyup.enter="getPersonalContactsList"
- />
- <el-button style="margin: 0 0 20px 20px;" type="primary" @click="showAddContactDialog=true">娣诲姞鑱旂郴浜�</el-button>
- <!-- 鑱旂郴浜哄垪琛� -->
- <div class="contact-list">
- <div
- v-for="contact in personalContacts"
- :key="contact.id"
- class="contact-card"
- @click="showContactDetail(contact)"
- >
- <div class="contact-avatar">{{ contact.staffName.charAt(0) }}</div>
- <div class="contact-info">
- <h4>{{ contact.staffName }}</h4>
- <p>{{ contact.profession }} - {{ contact.postJob }}</p>
- <div class="contact-phone">{{ contact.phone }}</div>
- </div>
- <div class="contact-actions">
- <!-- <el-button
- type="text"
- icon="Phone"
- @click.stop="callContact(contact)"
- ></el-button> -->
- <el-button
- type="text"
- icon="Message"
- @click.stop="messageContact(contact)"
- ></el-button>
- <el-button
- type="text"
- icon="Delete"
- @click.stop="removeFromPersonalContacts(contact.id)"
- ></el-button>
- </div>
- </div>
-
- <!-- 绌虹姸鎬�
- <div v-if="personalContacts.length === 0 && !loading" class="empty-state">
- <el-empty description="鏆傛棤鑱旂郴浜�" />
- <el-button type="primary" @click="showAddContactDialog=true">娣诲姞鑱旂郴浜�</el-button>
- </div> -->
- </div>
- </div>
- </el-tab-pane>
-
- <el-tab-pane label="鍏叡閫氳褰�" name="public">
- <div class="tab-content">
- <!-- 鎼滅储妗� -->
- <el-input
- v-model="publicSearch.staffName"
- placeholder="鎼滅储鍏叡鑱旂郴浜�"
- clearable
- prefix-icon="Search"
- class="search-input"
- @keyup.enter="getPublicContactsList"
- />
-
- <!-- 鑱旂郴浜哄垪琛� publicContacts-->
- <div class="contact-list">
- <div
- v-for="contact in EmployeeList"
- :key="contact.id"
- class="contact-card"
- @click="showContactDetail(contact)"
- >
- <div class="contact-avatar">{{ contact.staffName.charAt(0) }}</div>
- <div class="contact-info">
- <h4>{{ contact.staffName }}</h4>
- <p>{{ contact.postJob }} - {{ contact.profession }}</p>
- <div class="contact-phone">{{ contact.phone }}</div>
- </div>
- <div class="contact-actions">
- <!-- <el-button
- type="text"
- icon="Phone"
- @click.stop="callContact(contact)"
- ></el-button> -->
- <el-button
- type="text"
- icon="Message"
- @click.stop="messageContact(contact)"
- ></el-button>
- <el-button
- type="text"
- icon="Delete"
- :type="isInPersonalContacts(contact.id) ? 'primary' : ''"
- @click.stop="togglePersonalContact(contact)"
- ></el-button>
- </div>
- </div>
- </div>
- </div>
- </el-tab-pane>
-
- <el-tab-pane label="鍗曚綅閫氳褰�" name="company">
- <div class="tab-content">
- <div class="company-contacts-layout">
- <!-- 宸︿晶閮ㄩ棬鏍� -->
- <div class="department-tree">
- <!-- <h3>閮ㄩ棬缁撴瀯</h3>
- <el-tree
- :data="departmentTree"
- :props="{ label: 'deptName', children: 'children' }"
- node-key="deptId"
- ref="departmentTreeRef"
- highlight-current
- default-expand-all
- @node-click="handleDepartmentClick"
- /> -->
- <el-col >
- <div class="head-container">
- <el-input
- v-model="deptName"
- placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
- clearable
- prefix-icon="Search"
- style="margin-bottom: 20px"
- />
- </div>
- <div class="head-container">
- <el-tree
- :data="departmentTree"
- :props="{ label: 'label', children: 'children' }"
- :expand-on-click-node="false"
- :filter-node-method="filterNode"
- ref="deptTreeRef"
- node-key="id"
- highlight-current
- default-expand-all
- @node-click="handleDepartmentClick"
- />
- </div>
- </el-col>
- </div>
-
- <!-- 鍙充晶閮ㄩ棬鎴愬憳 -->
- <div class="department-members">
- <h3>{{ currentDepartment?.label || '鍏ㄩ儴鎴愬憳' }}</h3>
- <el-input
- v-model="companySearch.staffName"
- placeholder="鎼滅储閮ㄩ棬鎴愬憳"
- clearable
- prefix-icon="Search"
- class="search-input"
- @keyup.enter="getCompanyContactsList"
- />
-
- <div class="contact-list">
- <div
- v-for="contact in companyContacts"
- :key="contact.id"
- class="contact-card"
- @click="showContactDetail(contact)"
- >
- <div class="contact-avatar">{{ contact.staffName.charAt(0) }}</div>
- <div class="contact-info">
- <h4>{{ contact.staffName }}</h4>
- <p>{{ contact.profession }}</p>
- <div class="contact-phone">{{ contact.phone }}</div>
- </div>
- <div class="contact-actions">
-
- <el-button
- type="text"
- icon="Message"
- @click.stop="messageContact(contact)"
- ></el-button>
- <el-button
- type="text"
- icon="Delete"
- :type="isInPersonalContacts(contact.id) ? 'primary' : ''"
- @click.stop="togglePersonalContact(contact)"
- ></el-button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </el-tab-pane>
- </el-tabs>
-
- <!-- 鑱旂郴浜鸿鎯呭脊绐� -->
- <el-dialog
- v-model="showDetailDialog"
- title="鑱旂郴浜鸿鎯�"
- width="400px"
- >
- <div v-if="selectedContact" class="contact-detail">
- <div class="detail-avatar">{{ selectedContact.staffName?.charAt(0) }}</div>
- <h3>{{ selectedContact.staffName }}</h3>
- <p class="detail-position">{{ selectedContact.profession }} - {{ selectedContact.postJob }}</p>
-
- <div class="detail-info">
- <div class="info-item">
- <span class="label">缂栧彿锛�</span>
- <span class="value">{{ selectedContact.staffNo }}</span>
- </div>
- <div class="info-item">
- <span class="label">鎵嬫満鍙风爜锛�</span>
- <span class="value">{{ selectedContact.phone }}</span>
- </div>
- <div class="info-item">
- <span class="label">閭锛�</span>
- <span class="value">{{ selectedContact.sex }}</span>
- </div>
- <div class="info-item">
- <span class="label">浣忓潃锛�</span>
- <span class="value">{{ selectedContact.adress || '鏆傛棤' }}</span>
- </div>
- </div>
- </div>
- <template #footer>
- <el-button @click="showDetailDialog = false">鍏抽棴</el-button>
- <el-button
- type="primary"
- v-if="activeTab !== 'personal'"
- @click="togglePersonalContact(selectedContact); showDetailDialog = false"
- >
- {{ isInPersonalContacts(selectedContact?.id) ? '浠庝釜浜洪�氳褰曠Щ闄�' : '娣诲姞鍒颁釜浜洪�氳褰�' }}
- </el-button>
- </template>
- </el-dialog>
-
- <!-- 娣诲姞鑱旂郴浜哄脊绐� -->
- <el-dialog
- v-model="showAddContactDialog"
- title="娣诲姞鑱旂郴浜�"
- width="500px"
- >
- <el-form :model="addContactForm" ref="addContactFormRef" label-width="80px">
- <!-- <el-form-item label="濮撳悕" prop="name">
- <el-input v-model="addContactForm.name" placeholder="璇疯緭鍏ュ鍚�" />
- </el-form-item>
- <el-form-item label="鎵嬫満鍙风爜" prop="phone">
- <el-input v-model="addContactForm.phone" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" />
- </el-form-item>
- <el-form-item label="閭" prop="email">
- <el-input v-model="addContactForm.email" placeholder="璇疯緭鍏ラ偖绠�" />
- </el-form-item>
- <el-form-item label="閮ㄩ棬" prop="department">
- <el-input v-model="addContactForm.department" placeholder="璇疯緭鍏ラ儴闂�" />
- </el-form-item> -->
- <el-form-item label="濮撳悕" prop="name">
- <!-- <select v-model="addContactForm.contactId">
- <option v-for="item in EmployeeList" :key="item.id" :value="item.id">{{ item.staffName }}</option>
- </select> -->
- <el-select v-model="addContactForm.contactId" placeholder="璇烽�夋嫨" style="width: 100%">
- <el-option
- v-for="option in EmployeeList"
- :key="option.id"
- :label="option.staffName"
- :value="option.id"
- />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="showAddContactDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="addContact">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {
- getPersonalContacts,
- addPersonalContact,
- removePersonalContact,
- getPublicContacts,
- getCompanyContacts,
- getDepartmentTree,
- getEmployeeDetail
-} from '@/api/collaborativeApproval/enterpriseBook.js'
-import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {
- changeUserStatus,
- listUser,
- resetUserPwd,
- delUser,
- getUser,
- updateUser,
- addUser,
- deptTreeSelect,
-} from "@/api/system/user";
-
-// 鏍囩椤电姸鎬�
-const activeTab = ref('personal')
-const loading = ref(false)
-const EmployeeList = ref([])
-const page = reactive({
- pageNum: 1,
- pageSize: 10,
- total: 0,
-})
-// 涓汉閫氳褰曟暟鎹�
-const personalContacts = ref([])
-const personalSearch = ref({
- staffName: '',
-})
-
-// 鍏叡閫氳褰曟暟鎹�
-const publicContacts = ref([])
-const publicSearch = ref({
- staffName: '',
- staffState: 1
-})
-
-// 鍗曚綅閫氳褰曟暟鎹�
-const companyContacts = ref([])
-const companySearch = ref({
- staffName: '',
- staffState: 1
-})
-const departmentTree = ref([])
-const departmentTreeRef = ref(null)
-const currentDepartment = ref(null)
-
-// 寮圭獥鐘舵��
-const showDetailDialog = ref(false)
-const showAddContactDialog = ref(false)
-const selectedContact = ref(null)
-
-// 娣诲姞鑱旂郴浜鸿〃鍗�
-const addContactForm = reactive({
- contactId: '',
- name: '',
- phone: '',
- email: '',
- department: '',
- position: ''
-})
-const addContactFormRef = ref(null)
-
-// 鍒濆鍖栨暟鎹�
-onMounted(() => {
- getEmployeeList()
- getPersonalContactsList()
- if (activeTab.value === 'public') {
- getPublicContactsList()
- } else if (activeTab.value === 'company') {
- getDepartmentTreeData()
- getCompanyContactsList()
- }
-})
-
-// 澶勭悊鏍囩椤靛垏鎹�
-const handleTabChange = (tabName) => {
- if (tabName === 'public') {
- getPublicContactsList()
- } else if (tabName === 'company') {
- getDepartmentTreeData()
- getCompanyContactsList()
- }
-}
-
-// 鑾峰彇涓汉閫氳褰曞垪琛�
-const getPersonalContactsList = async () => {
- loading.value = true
- getPersonalContacts(page,personalSearch.value).then(res => {
- personalContacts.value = res.data.records
- })
- loading.value = false
-}
-
-// 鑾峰彇鍏叡閫氳褰曞垪琛�
-const getPublicContactsList = async () => {
- loading.value = true
- getEmployeeList()
- // publicContacts.value = generateMockPublicContacts()
- loading.value = false
-}
- //鑾峰彇鍛樺伐鍒楄〃
-const getEmployeeList = async () => {
- staffJoinListPage(publicSearch.value).then(res => {
- console.log(res.data.records)
- EmployeeList.value = res.data.records
- }).catch(err => {})
-}
-// 鑾峰彇鍗曚綅閫氳褰曞垪琛�
-const getCompanyContactsList = async () => {
- loading.value = true
- staffJoinListPage(companySearch.value).then(res => {
- // console.log(res.data.records)
- companyContacts.value = res.data.records
- }).catch(err => {})
-
- loading.value = false
- loading.value = false
- // }
-}
-
-// 鑾峰彇閮ㄩ棬鏍戠粨鏋�
-const getDepartmentTreeData = async () => {
- deptTreeSelect().then((response) => {
- // console.log("Tree",response.data)
- departmentTree.value = response.data;
- // enabledDeptOptions.value = filterDisabledDept(
- // JSON.parse(JSON.stringify(response.data))
- // );
- });
-}
-// /** 杩囨护绂佺敤鐨勯儴闂� */
-// function filterDisabledDept(deptList) {
-// return deptList.filter((dept) => {
-// if (dept.disabled) {
-// return false;
-// }
-// if (dept.children && dept.children.length) {
-// dept.children = filterDisabledDept(dept.children);
-// }
-// return true;
-// });
-// }
-// 澶勭悊閮ㄩ棬鐐瑰嚮
-const handleDepartmentClick = (data) => {
- // console.log("鐐瑰嚮",data)
- companySearch.value = {
- ...companySearch.value,
- deptId: data.id,
- }
- // currentDepartment.value = data.id
- // 鑾峰彇璇ラ儴闂ㄧ殑鎴愬憳鍒楄〃
-
- getCompanyContactsList()
-}
-
-// 鏄剧ず鑱旂郴浜鸿鎯�
-const showContactDetail = async (contact) => {
- selectedContact.value = contact
- showDetailDialog.value = true
-}
-
-// 鎷ㄦ墦鐢佃瘽
-const callContact = (contact) => {
- ElMessage.info(`姝e湪鎷ㄦ墦 ${contact.name} 鐨勭數璇�: ${contact.phone}`)
-}
-
-// 鍙戦�佹秷鎭�
-const messageContact = (contact) => {
- ElMessage.info(`姝e湪鍙戦�佹秷鎭粰 ${contact.name}`)
-}
-
-
-// 娣诲姞鑱旂郴浜�
-const addContact = async () => {
-
- try {
- // 琛ㄥ崟楠岃瘉
- // if (!addContactForm.name || !addContactForm.phone) {
- // ElMessage.warning('璇峰~鍐欏鍚嶅拰鎵嬫満鍙风爜')
- // return
- // }
-
- const res = await addPersonalContact(addContactForm)
- if (res.code === 200) {
- ElMessage.success('娣诲姞鎴愬姛')
- showAddContactDialog.value = false
- getPersonalContactsList()
- // 閲嶇疆琛ㄥ崟
- Object.keys(addContactForm).forEach(key => {
- addContactForm[key] = ''
- })
- }
- } catch (error) {
- ElMessage.error('娣诲姞澶辫触')
- // 妯℃嫙娣诲姞鎴愬姛
- personalContacts.value.push({
- ...addContactForm,
- id: Date.now(),
- createTime: new Date().toISOString()
- })
- ElMessage.success('娣诲姞鎴愬姛')
- showAddContactDialog.value = false
- // 閲嶇疆琛ㄥ崟
- Object.keys(addContactForm).forEach(key => {
- addContactForm[key] = ''
- })
- }
-}
-
-// 浠庝釜浜洪�氳褰曠Щ闄�
-const removeFromPersonalContacts = async (contactId) => {
- ElMessageBox.confirm(
- '纭畾瑕佷粠涓汉閫氳褰曚腑绉婚櫎璇ヨ仈绯讳汉鍚楋紵',
- '鎻愮ず',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(async () => {
- try {
- const res = await removePersonalContact(contactId)
- if (res.code === 200) {
- ElMessage.success('绉婚櫎鎴愬姛')
- getPersonalContactsList()
- }
- } catch (error) {
- ElMessage.error('绉婚櫎澶辫触')
- // 妯℃嫙绉婚櫎鎴愬姛
- // personalContacts.value = personalContacts.value.filter(item => item.id !== contactId)
- ElMessage.success('绉婚櫎鎴愬姛')
- }
- })
-}
-
-// 鍒囨崲涓汉閫氳褰�
-const togglePersonalContact = async (contact) => {
- const isInPersonal = isInPersonalContacts(contact.id)
- const contactId = contact.id
- if (isInPersonal) {
- // 浠庝釜浜洪�氳褰曠Щ闄�
- //鏍规嵁contactId鏌ユ壘personalContacts涓搴旂殑椤癸紝鐒跺悗鍒犻櫎璇ラ」
- const index = personalContacts.value.findIndex(item => item.contactId === contactId)
- const personId = personalContacts.value[index].id
- // console.log(personId)
- await removeFromPersonalContacts(personId)
- } else {
- // 娣诲姞鍒颁釜浜洪�氳褰�
- try {
- const res = await addPersonalContact({contactId: contactId})
- if (res.code === 200) {
- ElMessage.success('娣诲姞鎴愬姛')
- getPersonalContactsList()
- }
- } catch (error) {
- ElMessage.error('娣诲姞澶辫触')
- // 妯℃嫙娣诲姞鎴愬姛
- // personalContacts.value.push({
- // ...contact,
- // id: contact.id || Date.now(),
- // createTime: new Date().toISOString()
- // })
- // ElMessage.success('娣诲姞鎴愬姛')
- }
- }
-}
-
-// 妫�鏌ユ槸鍚﹀湪涓汉閫氳褰曚腑
-const isInPersonalContacts = (contactId) => {
- return personalContacts.value.some(item => item.contactId === contactId)
-}
-
-// 鐢熸垚妯℃嫙閮ㄩ棬鏍戞暟鎹�
-const generateMockDepartmentTree = () => {
- return [
- {
- deptId: 1,
- deptName: '鎶�鏈儴',
- children: [
- {
- deptId: 101,
- deptName: '鍓嶇缁�'
- },
- {
- deptId: 102,
- deptName: '鍚庣缁�'
- },
- {
- deptId: 103,
- deptName: '娴嬭瘯缁�'
- }
- ]
- },
- {
- deptId: 2,
- deptName: '浜у搧閮�'
- },
- {
- deptId: 3,
- deptName: '浜轰簨閮�'
- },
- {
- deptId: 4,
- deptName: '璐㈠姟閮�'
- }
- ]
-}
-
-// 鐢熸垚妯℃嫙鍗曚綅閫氳褰曟暟鎹�
-// const generateMockCompanyContacts = (deptName) => {
-// const allContacts = getEmployeeList()
-
-// if (deptName) {
-// return allContacts.filter(contact => contact.postJob === deptName)
-// }
-// return allContacts
-// }
-
-</script>
-
-<style scoped>
-.header {
- margin-bottom: 20px;
- padding: 15px;
- background: #f5f7fa;
- border-radius: 8px;
-}
-
-.header h2 {
- margin: 0 0 5px 0;
- color: #303133;
-}
-
-.header p {
- margin: 0;
- color: #909399;
- font-size: 14px;
-}
-
-.tab-content {
- padding: 15px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-}
-
-.search-input {
- margin-bottom: 20px;
- width: 300px;
-}
-
-.contact-list {
- display: flex;
- flex-wrap: wrap;
- gap: 15px;
-}
-
-.contact-card {
- display: flex;
- align-items: center;
- padding: 15px;
- width: 500px;
- background: #f8f9fa;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.3s;
-}
-
-.contact-card:hover {
- background: #e9ecef;
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
-}
-
-.contact-avatar {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 48px;
- height: 48px;
- background: #409eff;
- color: #fff;
- font-size: 20px;
- font-weight: bold;
- border-radius: 50%;
- margin-right: 15px;
-}
-
-.contact-info {
- flex: 1;
-}
-
-.contact-info h4 {
- margin: 0 0 5px 0;
- color: #303133;
- font-size: 16px;
-}
-
-.contact-info p {
- margin: 0 0 5px 0;
- color: #606266;
- font-size: 14px;
-}
-
-.contact-phone {
- color: #409eff;
- font-size: 14px;
-}
-
-.contact-actions {
- display: flex;
- gap: 5px;
-}
-
-.empty-state {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 60px 20px;
- color: #909399;
-}
-
-.company-contacts-layout {
- display: flex;
- gap: 20px;
-}
-
-.department-tree {
- width: 250px;
- padding: 15px;
- background: #f8f9fa;
- border-radius: 8px;
-}
-
-.department-tree h3 {
- margin: 0 0 15px 0;
- padding-bottom: 10px;
- border-bottom: 1px solid #e4e7ed;
- color: #303133;
- font-size: 16px;
-}
-
-.department-members {
- flex: 1;
-}
-
-.department-members h3 {
- margin: 0 0 15px 0;
- color: #303133;
- font-size: 16px;
-}
-
-.contact-detail {
- text-align: center;
-}
-
-.detail-avatar {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 80px;
- height: 80px;
- background: #409eff;
- color: #fff;
- font-size: 32px;
- font-weight: bold;
- border-radius: 50%;
- margin: 0 auto 20px;
-}
-
-.contact-detail h3 {
- margin: 0 0 10px 0;
- color: #303133;
- font-size: 20px;
-}
-
-.detail-position {
- margin: 0 0 30px 0;
- color: #606266;
- font-size: 14px;
-}
-
-.detail-info {
- text-align: left;
-}
-
-.info-item {
- margin-bottom: 15px;
-}
-
-.info-item .label {
- display: inline-block;
- width: 100px;
- color: #909399;
- font-size: 14px;
-}
-
-.info-item .value {
- color: #303133;
- font-size: 14px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/knowledgeBase/index.vue b/src/views/collaborativeApproval/knowledgeBase/index.vue
deleted file mode 100644
index cb643ad..0000000
--- a/src/views/collaborativeApproval/knowledgeBase/index.vue
+++ /dev/null
@@ -1,826 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鐭ヨ瘑鏍囬锛�</span>
- <el-input
- v-model="searchForm.title"
- style="width: 240px"
- placeholder="璇疯緭鍏ョ煡璇嗘爣棰樻悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title ml10">鐭ヨ瘑绫诲瀷锛�</span>
- <el-select v-model="searchForm.type" clearable @change="handleQuery" style="width: 240px">
- <el-option label="鍚堝悓鐗规壒" :value="'contract'" />
- <el-option label="瀹℃壒妗堜緥" :value="'approval'" />
- <el-option label="瑙e喅鏂规" :value="'solution'" />
- <el-option label="缁忛獙鎬荤粨" :value="'experience'" />
- <el-option label="鎿嶄綔鎸囧崡" :value="'guide'" />
- </el-select>
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
- 鎼滅储
- </el-button>
- </div>
- <div>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="openForm('add')">鏂板鐭ヨ瘑</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>
-
- <!-- 鏂板/缂栬緫鐭ヨ瘑寮圭獥 -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="800px"
- :close-on-click-modal="false"
- >
- <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐭ヨ瘑鏍囬" prop="title">
- <el-input v-model="form.title" placeholder="璇疯緭鍏ョ煡璇嗘爣棰�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐭ヨ瘑绫诲瀷" prop="type">
- <el-select v-model="form.type" placeholder="璇烽�夋嫨鐭ヨ瘑绫诲瀷" style="width: 100%">
- <el-option label="鍚堝悓鐗规壒" value="contract" />
- <el-option label="瀹℃壒妗堜緥" value="approval" />
- <el-option label="瑙e喅鏂规" value="solution" />
- <el-option label="缁忛獙鎬荤粨" value="experience" />
- <el-option label="鎿嶄綔鎸囧崡" value="guide" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閫傜敤鍦烘櫙" prop="scenario">
- <el-input v-model="form.scenario" placeholder="璇疯緭鍏ラ�傜敤鍦烘櫙" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙e喅鏁堢巼" prop="efficiency">
- <el-select v-model="form.efficiency" placeholder="璇烽�夋嫨瑙e喅鏁堢巼" style="width: 100%">
- <el-option label="鏄捐憲鎻愬崌" value="high" />
- <el-option label="涓�鑸彁鍗�" value="medium" />
- <el-option label="杞诲井鎻愬崌" value="low" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="闂鎻忚堪" prop="problem">
- <el-input
- v-model="form.problem"
- type="textarea"
- :rows="3"
- placeholder="璇锋弿杩伴亣鍒扮殑闂"
- />
- </el-form-item>
- <el-form-item label="瑙e喅鏂规" prop="solution">
- <el-input
- v-model="form.solution"
- type="textarea"
- :rows="4"
- placeholder="璇疯缁嗘弿杩拌В鍐虫柟妗�"
- />
- </el-form-item>
- <el-form-item label="鍏抽敭瑕佺偣" prop="keyPoints">
- <el-input
- v-model="form.keyPoints"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ叧閿鐐癸紝鐢ㄩ�楀彿鍒嗛殧"
- />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍒涘缓浜�" prop="creator">
- <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浣跨敤娆℃暟" prop="usageCount">
- <el-input-number v-model="form.usageCount" :min="0" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 鏌ョ湅鐭ヨ瘑璇︽儏寮圭獥 -->
- <el-dialog
- v-model="viewDialogVisible"
- title="鐭ヨ瘑璇︽儏"
- width="900px"
- :close-on-click-modal="false"
- >
- <div class="knowledge-detail">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鐭ヨ瘑鏍囬" :span="2">
- <span class="detail-title">{{ currentKnowledge.title }}</span>
- </el-descriptions-item>
- <el-descriptions-item label="鐭ヨ瘑绫诲瀷">
- <el-tag :type="getTypeTagType(currentKnowledge.type)">
- {{ getTypeLabel(currentKnowledge.type) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="閫傜敤鍦烘櫙">
- {{ currentKnowledge.scenario }}
- </el-descriptions-item>
- <el-descriptions-item label="瑙e喅鏁堢巼">
- <el-tag :type="getEfficiencyTagType(currentKnowledge.efficiency)">
- {{ getEfficiencyLabel(currentKnowledge.efficiency) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="浣跨敤娆℃暟">
- <el-tag type="info">{{ currentKnowledge.usageCount }} 娆�</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鍒涘缓浜�">
- {{ currentKnowledge.creator }}
- </el-descriptions-item>
- <el-descriptions-item label="鍒涘缓鏃堕棿">
- {{ currentKnowledge.createTime }}
- </el-descriptions-item>
- </el-descriptions>
-
- <div class="detail-section">
- <h4>闂鎻忚堪</h4>
- <div class="detail-content">{{ currentKnowledge.problem }}</div>
- </div>
-
- <div class="detail-section">
- <h4>瑙e喅鏂规</h4>
- <div class="detail-content">{{ currentKnowledge.solution }}</div>
- </div>
-
- <div class="detail-section">
- <h4>鍏抽敭瑕佺偣</h4>
- <div class="key-points">
- <el-tag
- v-for="(point, index) in currentKnowledge.keyPoints.split(',')"
- :key="index"
- type="success"
- style="margin-right: 8px; margin-bottom: 8px;"
- >
- {{ point.trim() }}
- </el-tag>
- </div>
- </div>
-
- <div class="detail-section">
- <h4>浣跨敤缁熻</h4>
- <div class="usage-stats">
- <el-row :gutter="20">
- <el-col :span="8">
- <div class="stat-item">
- <div class="stat-number">{{ currentKnowledge.usageCount }}</div>
- <div class="stat-label">浣跨敤娆℃暟</div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="stat-item">
- <div class="stat-number">{{ getEfficiencyScore(currentKnowledge.efficiency) }}%</div>
- <div class="stat-label">鏁堢巼鎻愬崌</div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="stat-item">
- <div class="stat-number">{{ getTimeSaved(currentKnowledge.efficiency) }}</div>
- <div class="stat-label">骞冲潎鑺傜渷鏃堕棿</div>
- </div>
- </el-col>
- </el-row>
- </div>
- </div>
- </div>
-
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="viewDialogVisible = false">鍏抽棴</el-button>
- <el-button type="primary" @click="copyKnowledge">澶嶅埗鐭ヨ瘑</el-button>
- <!-- <el-button type="success" @click="markAsFavorite">鏀惰棌@</el-button> -->
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import { listKnowledgeBase, delKnowledgeBase,addKnowledgeBase,updateKnowledgeBase } from "@/api/collaborativeApproval/knowledgeBase.js";
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- title: [
- { required: true, message: "璇疯緭鍏ョ煡璇嗘爣棰�", trigger: "blur" }
- ],
- type: [
- { required: true, message: "璇烽�夋嫨鐭ヨ瘑绫诲瀷", trigger: "change" }
- ],
- problem: [
- { required: true, message: "璇锋弿杩伴亣鍒扮殑闂", trigger: "blur" }
- ],
- solution: [
- { required: true, message: "璇疯缁嗘弿杩拌В鍐虫柟妗�", trigger: "blur" }
- ]
-};
-
-// 鍝嶅簲寮忔暟鎹�
-const data = reactive({
- searchForm: {
- title: "",
- type: "",
- },
- tableLoading: false,
- page: {
- current: 1,
- size: 20,
- total: 0,
- },
- tableData: [],
- selectedIds: [],
- form: {
- title: "",
- type: "",
- scenario: "",
- efficiency: "",
- problem: "",
- solution: "",
- keyPoints: "",
- creator: "",
- usageCount: 0
- },
- dialogVisible: false,
- dialogTitle: "",
- dialogType: "add",
- viewDialogVisible: false,
- currentKnowledge: {}
-});
-
-const {
- searchForm,
- tableLoading,
- page,
- tableData,
- selectedIds,
- form,
- dialogVisible,
- dialogTitle,
- dialogType,
- viewDialogVisible,
- currentKnowledge
-} = toRefs(data);
-
-// 琛ㄥ崟寮曠敤
-const formRef = ref();
-
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumn = ref([
- {
- label: "鐭ヨ瘑鏍囬",
- prop: "title",
- showOverflowTooltip: true,
- },
- {
- label: "鐭ヨ瘑绫诲瀷",
- prop: "type",
- dataType: "tag",
- formatData: (params) => {
- const typeMap = {
- contract: "鍚堝悓鐗规壒",
- approval: "瀹℃壒妗堜緥",
- solution: "瑙e喅鏂规",
- experience: "缁忛獙鎬荤粨",
- guide: "鎿嶄綔鎸囧崡"
- };
- return typeMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- contract: "success",
- approval: "warning",
- solution: "primary",
- experience: "info",
- guide: "danger"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "閫傜敤鍦烘櫙",
- prop: "scenario",
- width: 150,
- showOverflowTooltip: true,
- },
- {
- label: "瑙e喅鏁堢巼",
- prop: "efficiency",
- dataType: "tag",
- formatData: (params) => {
- const efficiencyMap = {
- high: "鏄捐憲鎻愬崌",
- medium: "涓�鑸彁鍗�",
- low: "杞诲井鎻愬崌"
- };
- return efficiencyMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- high: "success",
- medium: "warning",
- low: "info"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "浣跨敤娆℃暟",
- prop: "usageCount",
- width: 100,
- align: "center"
- },
- {
- label: "鍒涘缓浜�",
- prop: "creator",
- width: 120,
- },
- {
- label: "鍒涘缓鏃堕棿",
- prop: "createTime",
- width: 180,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 200,
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- }
- },
- {
- name: "鏌ョ湅",
- type: "text",
- clickFun: (row) => {
- viewKnowledge(row);
- }
- }
- ]
- }
-]);
-
-// 妯℃嫙鏁版嵁
-// let mockData = [
-// {
-// id: "1",
-// title: "鐗规畩鍚堝悓瀹℃壒娴佺▼浼樺寲鏂规",
-// type: "contract",
-// scenario: "澶ч鍚堝悓蹇�熷鎵�",
-// efficiency: "high",
-// problem: "澶ч鍚堝悓瀹℃壒娴佺▼澶嶆潅锛屽鎵规椂闂撮暱锛屽奖鍝嶄笟鍔¤繘灞�",
-// solution: "寤虹珛缁胯壊閫氶亾锛屽绗﹀悎鏉′欢鐨勫悎鍚岄噰鐢ㄧ畝鍖栧鎵规祦绋嬶紝鐢遍儴闂ㄨ礋璐d汉鐩存帴瀹℃壒锛屽钩鍧囧鎵规椂闂翠粠3澶╃缉鐭嚦1澶�",
-// keyPoints: "缁胯壊閫氶亾鏉′欢,绠�鍖栨祦绋�,瀹℃壒鏉冮檺,鏃堕棿鎺у埗",
-// creator: "寮犵粡鐞�",
-// usageCount: 15,
-// createTime: "2024-01-15 10:30:00"
-// },
-// {
-// id: "2",
-// title: "璺ㄩ儴闂ㄥ崗浣滃鎵圭粡楠屾�荤粨",
-// type: "experience",
-// scenario: "澶氶儴闂ㄥ崗浣滈」鐩�",
-// efficiency: "medium",
-// problem: "璺ㄩ儴闂ㄩ」鐩鎵规椂锛屽悇閮ㄩ棬鎰忚涓嶇粺涓�锛屽鎵硅繘搴︾紦鎱�",
-// solution: "寤虹珛椤圭洰鍗忚皟鏈哄埗锛屾寚瀹氶」鐩礋璐d汉锛屽畾鏈熷彫寮�鍗忚皟浼氳锛岀粺涓�鍚勬柟鎰忚鍚庡啀杩涜瀹℃壒",
-// keyPoints: "椤圭洰鍗忚皟,瀹氭湡浼氳,缁熶竴鎰忚,璐熻矗浜哄埗搴�",
-// creator: "鏉庝富绠�",
-// usageCount: 8,
-// createTime: "2024-01-14 15:20:00"
-// },
-// {
-// id: "3",
-// title: "绱ф�ラ噰璐鎵规搷浣滄寚鍗�",
-// type: "guide",
-// scenario: "绱ф�ラ噰璐渶姹�",
-// efficiency: "high",
-// problem: "绱ф�ラ噰璐椂瀹℃壒娴佺▼澶嶆潅锛屾棤娉曟弧瓒崇揣鎬ラ渶姹�",
-// solution: "鍒跺畾绱ф�ラ噰璐鎵规爣鍑嗭紝鏄庣‘绱ф�ョ▼搴﹀垎绾э紝涓嶅悓绾у埆閲囩敤涓嶅悓瀹℃壒娴佺▼锛岀‘淇濈揣鎬ラ渶姹傚緱鍒板強鏃跺鐞�",
-// keyPoints: "绱ф�ュ垎绾�,鏍囧噯鍒跺畾,娴佺▼绠�鍖�,鍙婃椂澶勭悊",
-// creator: "鐜嬩笓鍛�",
-// usageCount: 12,
-// createTime: "2024-01-13 09:15:00"
-// }
-// ];
-
-// 鐭ヨ瘑鏍囬妯℃澘
-const titleTemplates = [
- "{type}瀹℃壒娴佺▼浼樺寲鏂规",
- "{scenario}澶勭悊缁忛獙鎬荤粨",
- "{type}鐗规畩鎯呭喌澶勭悊鎸囧崡",
- "{scenario}蹇�熷鎵规柟妗�",
- "{type}鏍囧噯鍖栨搷浣滄祦绋�",
- "{scenario}闂瑙e喅鏂规",
- "{type}鏈�浣冲疄璺垫�荤粨",
- "{scenario}鏁堢巼鎻愬崌鏂规"
-];
-
-// 鐭ヨ瘑绫诲瀷閰嶇疆
-const knowledgeTypes = [
- { type: "contract", label: "鍚堝悓鐗规壒", efficiency: "high" },
- { type: "approval", label: "瀹℃壒妗堜緥", efficiency: "medium" },
- { type: "solution", label: "瑙e喅鏂规", efficiency: "high" },
- { type: "experience", label: "缁忛獙鎬荤粨", efficiency: "medium" },
- { type: "guide", label: "鎿嶄綔鎸囧崡", efficiency: "low" }
-];
-
-// 鍦烘櫙鍒楄〃
-const scenarios = ["澶ч鍚堝悓瀹℃壒", "璺ㄩ儴闂ㄥ崗浣�", "绱ф�ラ噰璐�", "鐗规畩鐢宠", "娴佺▼浼樺寲", "闂澶勭悊", "鏍囧噯鍖栧缓璁�", "鏁堢巼鎻愬崌"];
-
-// 鑷姩鐢熸垚鏂版暟鎹�
-const generateNewData = () => {
- const newId = (mockData.length + 1).toString();
- const now = new Date();
- const randomType = knowledgeTypes[Math.floor(Math.random() * knowledgeTypes.length)];
- const randomScenario = scenarios[Math.floor(Math.random() * scenarios.length)];
-
- // 鐢熸垚闅忔満鏍囬
- let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
- title = title
- .replace('{type}', randomType.label)
- .replace('{scenario}', randomScenario);
-
- const newKnowledge = {
- id: newId,
- title: title,
- type: randomType.type,
- scenario: randomScenario,
- efficiency: randomType.efficiency,
- problem: `鍦�${randomScenario}杩囩▼涓亣鍒扮殑闂鎻忚堪...`,
- solution: `閽堝${randomScenario}鐨勮В鍐虫柟妗堝拰鎿嶄綔姝ラ...`,
- keyPoints: "鍏抽敭瑕佺偣1,鍏抽敭瑕佺偣2,鍏抽敭瑕佺偣3,鍏抽敭瑕佺偣4",
- creator: ["寮犵粡鐞�", "鏉庝富绠�", "鐜嬩笓鍛�", "鍒樻�荤洃"][Math.floor(Math.random() * 4)],
- usageCount: Math.floor(Math.random() * 20) + 1,
- createTime: now.toLocaleString()
- };
-
- // 娣诲姞鍒版暟鎹紑澶�
- mockData.unshift(newKnowledge);
-
- // 淇濇寔鏁版嵁閲忓湪鍚堢悊鑼冨洿鍐咃紙鏈�澶氫繚鐣�30鏉★級
- if (mockData.length > 30) {
- mockData = mockData.slice(0, 30);
- }
-
- console.log(`[${new Date().toLocaleString()}] 鑷姩鐢熸垚鏂扮煡璇�: ${title}`);
-};
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- getList();
- startAutoRefresh();
-});
-
-// 寮�濮嬭嚜鍔ㄥ埛鏂�
-const startAutoRefresh = () => {
- setInterval(() => {
- generateNewData();
- getList();
- }, 600000); // 10鍒嗛挓鍒锋柊涓�娆� (10 * 60 * 1000 = 600000ms)
-};
-
-// 鏌ヨ鏁版嵁
-const handleQuery = () => {
- page.value.current = 1;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- listKnowledgeBase({...page.value, ...searchForm.value})
- .then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-
-// 鍒嗛〉澶勭悊
-const pagination = (obj) => {
- page.value.current = obj.page;
- page.value.size = obj.limit;
- handleQuery();
-};
-
-// 閫夋嫨鍙樺寲澶勭悊
-const handleSelectionChange = (selection) => {
- selectedIds.value = selection.map(item => item.id);
-};
-
-// 鎵撳紑琛ㄥ崟
-const openForm = (type, row = null) => {
- dialogType.value = type;
- if (type === "add") {
- dialogTitle.value = "鏂板鐭ヨ瘑";
- // 閲嶇疆琛ㄥ崟
- Object.assign(form.value, {
- title: "",
- type: "",
- scenario: "",
- efficiency: "",
- problem: "",
- solution: "",
- keyPoints: "",
- creator: "",
- usageCount: 0
- });
- } else if (type === "edit" && row) {
- dialogTitle.value = "缂栬緫鐭ヨ瘑";
- Object.assign(form.value, {
- id: row.id,
- title: row.title,
- type: row.type,
- scenario: row.scenario,
- efficiency: row.efficiency,
- problem: row.problem,
- solution: row.solution,
- keyPoints: row.keyPoints,
- creator: row.creator,
- usageCount: row.usageCount
- });
- }
- dialogVisible.value = true;
-};
-
-// 鏌ョ湅鐭ヨ瘑璇︽儏
-const viewKnowledge = (row) => {
- currentKnowledge.value = { ...row };
- viewDialogVisible.value = true;
-};
-
-// 鑾峰彇绫诲瀷鏍囩绫诲瀷
-const getTypeTagType = (type) => {
- const typeMap = {
- contract: "success",
- approval: "warning",
- solution: "primary",
- experience: "info",
- guide: "danger"
- };
- return typeMap[type] || "info";
-};
-
-// 鑾峰彇绫诲瀷鏍囩鏂囨湰
-const getTypeLabel = (type) => {
- const typeMap = {
- contract: "鍚堝悓鐗规壒",
- approval: "瀹℃壒妗堜緥",
- solution: "瑙e喅鏂规",
- experience: "缁忛獙鎬荤粨",
- guide: "鎿嶄綔鎸囧崡"
- };
- return typeMap[type] || type;
-};
-
-// 鑾峰彇鏁堢巼鏍囩绫诲瀷
-const getEfficiencyTagType = (efficiency) => {
- const typeMap = {
- high: "success",
- medium: "warning",
- low: "info"
- };
- return typeMap[efficiency] || "info";
-};
-
-// 鑾峰彇鏁堢巼鏍囩鏂囨湰
-const getEfficiencyLabel = (efficiency) => {
- const efficiencyMap = {
- high: "鏄捐憲鎻愬崌",
- medium: "涓�鑸彁鍗�",
- low: "杞诲井鎻愬崌"
- };
- return efficiencyMap[efficiency] || efficiency;
-};
-
-// 鑾峰彇鏁堢巼鎻愬崌鐧惧垎姣�
-const getEfficiencyScore = (efficiency) => {
- const scoreMap = {
- high: 40,
- medium: 25,
- low: 15
- };
- return scoreMap[efficiency] || 0;
-};
-
-// 鑾峰彇骞冲潎鑺傜渷鏃堕棿
-const getTimeSaved = (efficiency) => {
- const timeMap = {
- high: "2-3澶�",
- medium: "1-2澶�",
- low: "0.5-1澶�"
- };
- return timeMap[efficiency] || "鏈煡";
-};
-
-// 澶嶅埗鐭ヨ瘑
-const copyKnowledge = () => {
- const knowledgeText = `
- 鐭ヨ瘑鏍囬锛�${currentKnowledge.value.title}
- 鐭ヨ瘑绫诲瀷锛�${getTypeLabel(currentKnowledge.value.type)}
- 閫傜敤鍦烘櫙锛�${currentKnowledge.value.scenario}
- 闂鎻忚堪锛�${currentKnowledge.value.problem}
- 瑙e喅鏂规锛�${currentKnowledge.value.solution}
- 鍏抽敭瑕佺偣锛�${currentKnowledge.value.keyPoints}
- 鍒涘缓浜猴細${currentKnowledge.value.creator}
- `.trim();
-
- // 澶嶅埗鍒板壀璐存澘
- navigator.clipboard.writeText(knowledgeText).then(() => {
- ElMessage.success("鐭ヨ瘑鍐呭宸插鍒跺埌鍓创鏉�");
- }).catch(() => {
- ElMessage.error("澶嶅埗澶辫触锛岃鎵嬪姩澶嶅埗");
- });
-};
-
-// 鏀惰棌鐭ヨ瘑
-const markAsFavorite = () => {
- // 澧炲姞浣跨敤娆℃暟
- const index = mockData.findIndex(item => item.id === currentKnowledge.value.id);
- if (index !== -1) {
- mockData[index].usageCount += 1;
- currentKnowledge.value.usageCount += 1;
- }
-
- ElMessage.success("宸叉敹钘忥紝浣跨敤娆℃暟+1");
-};
-
-// 鎻愪氦鐭ヨ瘑琛ㄥ崟
-const submitForm = async () => {
- try {
- await formRef.value.validate();
- if (dialogType.value === "add") {
- // 鏂板鐭ヨ瘑
- addKnowledgeBase({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else {
- updateKnowledgeBase({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- } catch (error) {
- console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
- }
-};
-
-// 鍒犻櫎鐭ヨ瘑
-const handleDelete = () => {
- if (selectedIds.value.length === 0) {
- ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鐭ヨ瘑");
- return;
- }
-
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- // console.log(selectedIds.value);
- delKnowledgeBase(selectedIds.value).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- selectedIds.value = [];
- getList();
- }
- })
- }).catch(() => {
- // 鐢ㄦ埛鍙栨秷
- });
-};
-
-// 瀵煎嚭
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
- proxy.download('/knowledgeBase/export', { ...searchForm.value }, '鐭ヨ瘑搴�.xlsx')
-}
-</script>
-
-<style scoped>
-.auto-refresh-info {
- margin-bottom: 15px;
-}
-
-.auto-refresh-info .el-alert {
- border-radius: 8px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-.knowledge-detail {
- padding: 20px 0;
-}
-
-.detail-title {
- font-size: 18px;
- font-weight: bold;
- color: #303133;
-}
-
-.detail-section {
- margin-top: 24px;
-}
-
-.detail-section h4 {
- margin: 0 0 12px 0;
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- border-left: 4px solid #409eff;
- padding-left: 12px;
-}
-
-.detail-content {
- background: #f8f9fa;
- padding: 16px;
- border-radius: 6px;
- line-height: 1.6;
- color: #606266;
- white-space: pre-wrap;
-}
-
-.key-points {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
-}
-
-.usage-stats {
- margin-top: 16px;
-}
-
-.stat-item {
- text-align: center;
- padding: 20px;
- background: #f8f9fa;
- border-radius: 8px;
-}
-
-.stat-number {
- font-size: 24px;
- font-weight: bold;
- color: #409eff;
- margin-bottom: 8px;
-}
-
-.stat-label {
- font-size: 14px;
- color: #909399;
-}
-</style>
diff --git a/src/views/collaborativeApproval/meetingBoard/index.vue b/src/views/collaborativeApproval/meetingBoard/index.vue
deleted file mode 100644
index dfbb922..0000000
--- a/src/views/collaborativeApproval/meetingBoard/index.vue
+++ /dev/null
@@ -1,346 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳鐪嬫澘</h2>
-<!-- <el-button type="primary" @click="createMeeting">鍒涘缓浼氳</el-button>-->
- </div>
-
- <!-- 浼氳缁熻鍗$墖 -->
- <div class="stats-cards">
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-number">{{ stats.total }}</div>
- <div class="stat-label">鎬讳細璁暟</div>
- </div>
- </el-card>
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-number">{{ stats.underWay }}</div>
- <div class="stat-label">杩涜涓�</div>
- </div>
- </el-card>
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-number">{{ stats.completed }}</div>
- <div class="stat-label">宸插畬鎴�</div>
- </div>
- </el-card>
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-number">{{ stats.toStart }}</div>
- <div class="stat-label">鍗冲皢寮�濮�</div>
- </div>
- </el-card>
- </div>
-
- <!-- 浼氳鍒楄〃 -->
- <div class="meeting-list">
- <el-card v-for="meeting in meetings" :key="meeting.id" class="meeting-card">
- <div class="meeting-header">
- <div class="meeting-title">
- <h3>{{ meeting.title }}</h3>
- <el-tag :type="getStatusType(meeting.status)" size="small">
- {{ getStatusText(meeting.status) }}
- </el-tag>
- </div>
- <div class="meeting-time">
- {{dayjs(meeting.startTime).format("YYYY-MM-DD")}}<el-icon><Clock /></el-icon>
- {{ formatTime(meeting.startTime) }} - {{ formatTime(meeting.endTime) }}
- </div>
- </div>
-
- <div class="meeting-info">
- <div class="info-item">
- <el-icon><Location /></el-icon>
- <span>{{ meeting.location }}</span>
- </div>
- <div class="info-item">
- <el-icon><User /></el-icon>
- <span>涓绘寔浜�: {{ meeting.host }}</span>
- </div>
- <div class="info-item">
- <el-icon><UserFilled /></el-icon>
- <span>鍙備細浜烘暟: {{ meeting.participants.length }}浜�</span>
- </div>
- </div>
-
- <div class="meeting-agenda">
- <h4>浼氳绾</h4>
- <div class="agenda-list">
- <div class="editor-container">
- <div
- v-html="meeting.content"
- />
- </div>
- </div>
- </div>
- </el-card>
- </div>
-
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage } from 'element-plus'
-import { Clock, Location, User, UserFilled } from '@element-plus/icons-vue'
-import Editor from "@/components/Editor/index.vue";
-import {getMeetSummaryItems,getMeetSummary} from '@/api/collaborativeApproval/meeting.js'
-import dayjs from "dayjs";
-
-// 缁熻鏁版嵁
-const stats = ref({
- total: 0,
- underWay: 0,
- completed: 0,
- toStart: 0
-})
-
-// 浼氳鏁版嵁
-const meetings = ref([
-
-])
-
-// 瀵硅瘽妗嗙浉鍏�
-const dialogVisible = ref(false)
-const meetingForm = reactive({
- title: '',
- timeRange: [],
- location: '',
- host: '',
- description: ''
-})
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- '2': 'success',
- '1': 'warning',
- '0': 'info'
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- '2': '杩涜涓�',
- '1': '鍗冲皢寮�濮�',
- '0': '宸插畬鎴�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鑾峰彇璁▼鐘舵�佺被鍨�
-const getAgendaStatusType = (status) => {
- const statusMap = {
- 'completed': 'success',
- 'active': 'warning',
- 'pending': 'info'
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇璁▼鐘舵�佹枃鏈�
-const getAgendaStatusText = (status) => {
- const statusMap = {
- 'completed': '宸插畬鎴�',
- 'active': '杩涜涓�',
- 'pending': '寰呭紑濮�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鏍煎紡鍖栨椂闂�
-const formatTime = (timeStr) => {
- const date = new Date(timeStr)
- return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
-}
-
-
-onMounted( async () => {
- let [resp1,resp2] = await Promise.all([getMeetSummary(),getMeetSummaryItems()])
- stats.value = resp1.data
- meetings.value = resp2.data.map(item => {
- return {
- ...item,
- participants: JSON.parse(item.participants)
- }
- })
- console.log('浼氳鐪嬫澘椤甸潰鍔犺浇瀹屾垚')
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.stats-cards {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- gap: 20px;
- margin-bottom: 30px;
-}
-
-.stat-card {
- text-align: center;
-}
-
-.stat-content {
- padding: 10px;
-}
-
-.stat-number {
- font-size: 32px;
- font-weight: bold;
- color: #409eff;
- margin-bottom: 8px;
-}
-
-.stat-label {
- font-size: 14px;
- color: #606266;
-}
-
-.meeting-list {
- display: grid;
- gap: 20px;
-}
-
-.meeting-card {
- border-radius: 8px;
-}
-
-.meeting-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 15px;
-}
-
-.meeting-title {
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.meeting-title h3 {
- margin: 0;
- color: #303133;
-}
-
-.meeting-time {
- display: flex;
- align-items: center;
- gap: 5px;
- color: #606266;
- font-size: 14px;
-}
-
-.meeting-info {
- display: flex;
- gap: 20px;
- margin-bottom: 20px;
- flex-wrap: wrap;
-}
-
-.info-item {
- display: flex;
- align-items: center;
- gap: 5px;
- color: #606266;
- font-size: 14px;
-}
-
-.meeting-agenda {
- margin-bottom: 20px;
-}
-
-.meeting-agenda h4 {
- margin: 0 0 15px 0;
- color: #303133;
- font-size: 16px;
-}
-
-.agenda-list {
- display: flex;
- flex-direction: column;
- gap: 10px;
-}
-
-.agenda-item {
- display: flex;
- align-items: center;
- gap: 15px;
- padding: 10px;
- border-radius: 6px;
- background-color: #f5f7fa;
-}
-
-.agenda-item.active {
- background-color: #fdf6ec;
- border-left: 3px solid #e6a23c;
-}
-
-.agenda-item.completed {
- background-color: #f0f9ff;
- border-left: 3px solid #409eff;
-}
-
-.agenda-time {
- font-weight: bold;
- color: #606266;
- min-width: 80px;
-}
-
-.agenda-content {
- flex: 1;
- color: #303133;
-}
-
-.meeting-actions {
- display: flex;
- gap: 10px;
- justify-content: flex-end;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-@media (max-width: 768px) {
- .stats-cards {
- grid-template-columns: repeat(2, 1fr);
- }
-
- .meeting-header {
- flex-direction: column;
- gap: 10px;
- }
-
- .meeting-info {
- flex-direction: column;
- gap: 10px;
- }
-
- .meeting-actions {
- flex-direction: column;
- }
-}
-</style>
diff --git a/src/views/collaborativeApproval/noticeManagement/index.vue b/src/views/collaborativeApproval/noticeManagement/index.vue
deleted file mode 100644
index 77bc697..0000000
--- a/src/views/collaborativeApproval/noticeManagement/index.vue
+++ /dev/null
@@ -1,731 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎼滅储琛ㄥ崟 -->
- <div class="search_form">
- <div>
- <el-button type="primary" @click="openForm('add')">鏂板鍏憡</el-button>
- <el-button type="danger" plain @click="handleDelete" :disabled="!selectedIds.length">鍒犻櫎</el-button>
- </div>
- </div>
-
- <!-- 閫氱煡鍏憡鏉� -->
- <div class="notice-board">
- <!-- 鏀惧亣閫氱煡鍖哄煙 -->
- <div class="notice-section" v-if="holidayNoticeCount > 0">
- <div class="section-header">
- <h3>馃搮 鏀惧亣閫氱煡</h3>
- <span class="section-count">{{ holidayNoticeCount }}鏉�</span>
- </div>
- <div class="notice-cards">
- <div
- v-for="notice in holidayNotices"
- :key="notice.id"
- class="notice-card holiday-card"
- :class="{ 'urgent': notice.priority === '3' }"
- >
- <div class="card-header">
- <div class="card-title">
- <el-icon class="holiday-icon">
- <Calendar/>
- </el-icon>
- {{ notice.title }}
- </div>
- <div class="card-actions">
- <el-button link type="primary" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDelete(notice.id)">鍒犻櫎</el-button>
- </div>
- </div>
- <div class="card-content">
- <p>{{ notice.content }}</p>
- </div>
- <div class="card-footer">
- <div class="card-meta">
- <span class="priority" :class="'priority-' + notice.priority">
- {{ getPriorityText(notice.priority) }}
- </span>
- <span class="status" :class="'status-' + getNoticeStatus(notice)">
- {{ getStatusText(getNoticeStatus(notice)) }}
- </span>
- </div>
- <div class="card-info">
- <span class="creator">{{ notice.createUserName }}</span>
- <span class="expiration" v-if="notice.expirationDate">鎴鏃ユ湡锛歿{ notice.expirationDate }}</span>
- </div>
- </div>
- <div class="card-remark" v-if="notice.remark">
- <el-icon>
- <InfoFilled/>
- </el-icon>
- <span>{{ notice.remark }}</span>
- </div>
- </div>
- </div>
- </div>
-
- <pagination
- v-if="holidayNoticePage.total > 0"
- :total="holidayNoticePage.total"
- :page="holidayNoticePage.current"
- :limit="holidayNoticePage.size"
- @pagination="handleHolidayNoticeCurrentChange"
- />
-
- <!-- 璁惧缁翠慨閫氱煡鍖哄煙 -->
- <div class="notice-section" v-if="maintenanceNoticeCount > 0">
- <div class="section-header">
- <h3>馃敡 璁惧缁翠慨閫氱煡</h3>
- <span class="section-count">{{ maintenanceNoticeCount }}鏉�</span>
- </div>
- <div class="notice-cards">
- <div
- v-for="notice in maintenanceNotices"
- :key="notice.id"
- class="notice-card maintenance-card"
- :class="{ 'urgent': notice.priority === '3' }"
- >
- <div class="card-header">
- <div class="card-title">
- <el-icon class="maintenance-icon">
- <Tools/>
- </el-icon>
- {{ notice.title }}
- </div>
- <div class="card-actions">
- <el-button link type="primary" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDelete(notice.id)">鍒犻櫎</el-button>
- </div>
- </div>
- <div class="card-content">
- <p>{{ notice.content }}</p>
- </div>
- <div class="card-footer">
- <div class="card-meta">
- <span class="priority" :class="'priority-' + notice.priority">
- {{ getPriorityText(notice.priority) }}
- </span>
- <span class="status" :class="'status-' + getNoticeStatus(notice)">
- {{ getStatusText(getNoticeStatus(notice)) }}
- </span>
- </div>
- <div class="card-info">
- <span class="creator">{{ notice.createUserName }}</span>
- <span class="expiration" v-if="notice.expirationDate">鎴鏃ユ湡锛歿{ notice.expirationDate }}</span>
- </div>
- </div>
- <div class="card-remark" v-if="notice.remark">
- <el-icon>
- <InfoFilled/>
- </el-icon>
- <span>{{ notice.remark }}</span>
- </div>
- </div>
- </div>
- </div>
-
- <pagination
- v-if="maintenanceNoticePage.total > 0"
- :total="maintenanceNoticePage.total"
- :page="maintenanceNoticePage.current"
- :limit="maintenanceNoticePage.size"
- @pagination="handleMaintenanceNoticeCurrentChange"
- />
-
- <!-- 绌虹姸鎬� -->
- <div class="empty-state" v-if="holidayNotices.length === 0 && maintenanceNotices.length === 0">
- <el-empty description="鏆傛棤閫氱煡鍏憡"/>
- </div>
- </div>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- :title="dialogTitle"
- v-model="dialogVisible"
- width="800px"
- append-to-body
- @close="resetForm"
- >
- <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
- <el-row>
- <el-col :span="12">
- <el-form-item label="鍏憡鏍囬" prop="title">
- <el-input v-model="form.title" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏憡绫诲瀷" prop="type">
- <el-select v-model="form.type" placeholder="璇烽�夋嫨鍏憡绫诲瀷" style="width: 100%">
- <el-option label="鏀惧亣閫氱煡" :value="1"/>
- <el-option label="璁惧缁翠慨閫氱煡" :value="2"/>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="鐘舵��">
- <el-radio-group v-model="form.status">
- <el-radio :value="0">鑽夌</el-radio>
- <el-radio :value="1">姝e紡鍙戝竷</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浼樺厛绾�">
- <el-select v-model="form.priority" placeholder="璇烽�夋嫨浼樺厛绾�" style="width: 100%">
- <el-option label="鏅��" :value="1"/>
- <el-option label="閲嶈" :value="2"/>
- <el-option label="绱ф��" :value="3"/>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="杩囨湡鏃堕棿" prop="expirationDate">
- <el-date-picker v-model="form.expirationDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date"
- placeholder="璇烽�夋嫨" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鍏憡鍐呭" prop="content">
- <el-input
- v-model="form.content"
- type="textarea"
- :rows="6"
- placeholder="璇疯緭鍏ュ叕鍛婂唴瀹�"
- maxlength="500"
- show-word-limit
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="澶囨敞">
- <el-input
- v-model="form.remark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- maxlength="200"
- show-word-limit
- />
- </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="dialogVisible = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {Search, Calendar, Tools, InfoFilled} from "@element-plus/icons-vue";
-import {onMounted, ref, reactive, toRefs, computed} from "vue";
-import {ElMessage, ElMessageBox} from "element-plus";
-import useUserStore from "@/store/modules/user";
-import {
- addNotice,
- delNotice,
- getCount,
- listNotice,
- updateNotice
-} from "../../../api/collaborativeApproval/noticeManagement.js";
-import pagination from "../../../components/PIMTable/Pagination.vue";
-
-const userStore = useUserStore();
-
-// 鍝嶅簲寮忔暟鎹�
-const data = reactive({
- searchForm: {
- title: "",
- type: undefined,
- status: undefined,
- },
- form: {
- id: undefined,
- title: "",
- type: null,
- content: "",
- status: 0,
- priority: 1,
- remark: "",
- expirationDate: "",
- },
- rules: {
- title: [
- {required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur"}
- ],
- type: [
- {required: true, message: "璇烽�夋嫨鍏憡绫诲瀷", trigger: "change"}
- ],
- content: [
- {required: true, message: "鍏憡鍐呭涓嶈兘涓虹┖", trigger: "blur"}
- ],
- expirationDate: [
- {required: true, message: "璇烽�夋嫨鏃ユ湡", trigger: "change"}
- ]
- }
-});
-
-const {searchForm, form, rules} = toRefs(data);
-
-// 椤甸潰鐘舵��
-const dialogVisible = ref(false);
-const dialogTitle = ref("");
-const selectedIds = ref([]);
-const formRef = ref();
-
-
-// 璁$畻灞炴��
-const filteredNotices = computed(() => {
- let filtered = [...mockData];
-
- if (searchForm.value.noticeTitle) {
- filtered = filtered.filter(item =>
- item.noticeTitle.includes(searchForm.value.noticeTitle)
- );
- }
- if (searchForm.value.noticeType) {
- filtered = filtered.filter(item =>
- item.noticeType === searchForm.value.noticeType
- );
- }
- if (searchForm.value.status !== "") {
- filtered = filtered.filter(item =>
- item.status === searchForm.value.status
- );
- }
-
- return filtered;
-});
-
-// 鏂规硶瀹氫箟
-const handleQuery = () => {
- // 鎼滅储鍔熻兘淇濇寔涓嶅彉锛屼絾鏁版嵁閫氳繃璁$畻灞炴�ц嚜鍔ㄨ繃婊�
-};
-
-const resetQuery = () => {
- searchForm.value = {
- title: "",
- type: "",
- status: ""
- };
-};
-
-const getPriorityText = (priority) => {
- const priorityMap = {"1": "鏅��", "2": "閲嶈", "3": "绱ф��"};
- return priorityMap[priority] || "鏅��";
-};
-
-const getStatusText = (status) => {
- const statusMap = {"0": "鑽夌", "1": "宸插彂甯�", "2": "宸茶繃鏈�"};
- return statusMap[status] || "鏈煡";
-};
-
-const isNoticeExpired = (notice) => {
- if (!notice || !notice.expirationDate) {
- return false;
- }
-
- const expiration = new Date(notice.expirationDate);
-
- if (Number.isNaN(expiration.getTime())) {
- return false;
- }
-
- expiration.setHours(23, 59, 59, 999);
-
- return new Date() > expiration;
-};
-
-const getNoticeStatus = (notice) => {
- const normalizedStatus = notice && notice.status !== undefined && notice.status !== null
- ? String(notice.status)
- : "0";
-
- return isNoticeExpired(notice) ? "2" : normalizedStatus;
-};
-
-const openForm = (type) => {
- if (type === 'add') {
- dialogTitle.value = "鏂板鍏憡";
- form.value = {
- id: undefined,
- title: "",
- type: undefined,
- content: "",
- status: 0,
- priority: 1,
- remark: "",
- expirationDate: "",
- };
- }
- dialogVisible.value = true;
-};
-
-const handleEdit = (row) => {
- if (isNoticeExpired(row)) {
- ElMessage.warning("宸茶繃鏈熺殑鍏憡涓嶅彲缂栬緫");
- return;
- }
- dialogTitle.value = "缂栬緫鍏憡";
- form.value = {...row};
- dialogVisible.value = true;
-};
-
-const handleDelete = (id) => {
- ElMessageBox.confirm(
- "纭鍒犻櫎杩欐潯鍏憡鍚楋紵",
- "鎻愮ず",
- {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning"
- }
- ).then(() => {
- delNotice(id).then(res => {
- ElMessage.success("鍒犻櫎鎴愬姛");
- resetTable()
- })
- });
-};
-
-const submitForm = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (form.value.id) {
- // 缂栬緫妯″紡
- updateNotice(form.value).then(res => {
- ElMessage.success("淇敼鎴愬姛");
- resetTable()
- })
- } else {
- // 鏂板妯″紡
- addNotice(form.value).then(res => {
- ElMessage.success("鏂板鎴愬姛");
- resetTable()
- })
- }
- dialogVisible.value = false;
- }
- });
-};
-
-const holidayNoticeCount = ref()
-const maintenanceNoticeCount = ref()
-const fetchCount = () => {
- getCount().then(res => {
- holidayNoticeCount.value = res.data.filter(item => {
- return item.type === 1
- })[0].count;
- maintenanceNoticeCount.value = res.data.filter(item => {
- return item.type === 2
- })[0].count;
- });
-}
-
-const holidayNotices = ref([])
-const maintenanceNotices = ref([])
-const holidayNoticePage = ref({
- total: 0,
- current: 1,
- size: 9
-})
-
-const maintenanceNoticePage = ref({
- total: 0,
- current: 1,
- size: 9
-})
-
-const fetchHolidayNotices = () => {
- listNotice({...holidayNoticePage.value, type: 1}).then(res => {
- holidayNotices.value = res.data.records
- holidayNoticePage.value.total = res.data.total
- });
-};
-
-const fetchMaintenanceNotices = () => {
- listNotice({...holidayNoticePage.value, type: 2}).then(res => {
- maintenanceNotices.value = res.data.records
- maintenanceNoticePage.value.total = res.data.total
- });
-};
-
-const handleHolidayNoticeCurrentChange = (val) => {
- holidayNoticePage.value.size = val.limit
- holidayNoticePage.value.current = val.page
- fetchHolidayNotices()
-};
-
-const handleMaintenanceNoticeCurrentChange = (val) => {
- maintenanceNoticePage.value.size = val.limit
- maintenanceNoticePage.value.current = val.page
- fetchMaintenanceNotices()
-};
-
-const resetTable = () => {
- holidayNoticePage.value.current = 1
- holidayNoticePage.value.size = 9
- maintenanceNoticePage.value.current = 1
- maintenanceNoticePage.value.size = 9
- fetchHolidayNotices()
- fetchMaintenanceNotices()
- fetchCount()
-};
-
-const resetForm = () => {
- formRef.value?.resetFields();
-};
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- fetchCount()
- fetchHolidayNotices()
- fetchMaintenanceNotices()
-});
-</script>
-
-<style scoped>
-.search_form {
- background: #fff;
- padding: 20px;
- margin-bottom: 20px;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.search_title {
- font-weight: 500;
- color: #333;
- margin-right: 8px;
-}
-
-.ml10 {
- margin-left: 10px;
-}
-
-.notice-board {
- background: #f5f7fa;
- padding: 20px;
- border-radius: 8px;
-}
-
-.notice-section {
- margin-bottom: 30px;
-}
-
-.section-header {
- display: flex;
- align-items: center;
- margin-bottom: 20px;
- padding: 0 10px;
-}
-
-.section-header h3 {
- margin: 0;
- color: #303133;
- font-size: 18px;
- font-weight: 600;
-}
-
-.section-count {
- margin-left: 10px;
- background: #409eff;
- color: white;
- padding: 2px 8px;
- border-radius: 12px;
- font-size: 12px;
-}
-
-.notice-cards {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
- gap: 20px;
-}
-
-.notice-card {
- background: white;
- border-radius: 12px;
- padding: 20px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
- border-left: 4px solid transparent;
-}
-
-.notice-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
-}
-
-.holiday-card {
- border-left-color: #67c23a;
-}
-
-.maintenance-card {
- border-left-color: #e6a23c;
-}
-
-.urgent {
- border-left-color: #f56c6c;
- background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%);
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 15px;
-}
-
-.card-title {
- display: flex;
- align-items: center;
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- flex: 1;
-}
-
-.holiday-icon {
- color: #67c23a;
- margin-right: 8px;
- font-size: 18px;
-}
-
-.maintenance-icon {
- color: #e6a23c;
- margin-right: 8px;
- font-size: 18px;
-}
-
-.card-actions {
- display: flex;
- gap: 8px;
-}
-
-.card-content {
- margin-bottom: 15px;
-}
-
-.card-content p {
- margin: 0;
- color: #606266;
- line-height: 1.6;
- font-size: 14px;
-}
-
-.card-footer {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 10px;
-}
-
-.card-meta {
- display: flex;
- gap: 8px;
-}
-
-.priority, .status {
- padding: 2px 8px;
- border-radius: 12px;
- font-size: 12px;
- font-weight: 500;
-}
-
-.priority-1 {
- background: #f0f9ff;
- color: #0369a1;
-}
-
-.priority-2 {
- background: #fef3c7;
- color: #d97706;
-}
-
-.priority-3 {
- background: #fef2f2;
- color: #dc2626;
-}
-
-.status-0 {
- background: #f3f4f6;
- color: #6b7280;
-}
-
-.status-1 {
- background: #d1fae5;
- color: #059669;
-}
-
-.status-2 {
- background: #fef3c7;
- color: #d97706;
-}
-
-.card-info {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- font-size: 12px;
- color: #909399;
-}
-
-.creator {
- font-weight: 500;
- margin-bottom: 2px;
-}
-
-.expiration {
- margin-top: 2px;
-}
-
-.card-remark {
- display: flex;
- align-items: center;
- gap: 6px;
- padding: 8px 12px;
- background: #f8f9fa;
- border-radius: 6px;
- font-size: 12px;
- color: #606266;
- border-left: 3px solid #409eff;
-}
-
-.empty-state {
- text-align: center;
- padding: 60px 20px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .notice-cards {
- grid-template-columns: 1fr;
- }
-
- .search_form {
- flex-direction: column;
- gap: 15px;
- }
-
- .search_form > div {
- width: 100%;
- }
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/index.vue b/src/views/collaborativeApproval/notificationManagement/index.vue
deleted file mode 100644
index 37c13cf..0000000
--- a/src/views/collaborativeApproval/notificationManagement/index.vue
+++ /dev/null
@@ -1,1200 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">閫氱煡鏍囬锛�</span>
- <el-input
- v-model="searchForm.title"
- style="width: 240px"
- placeholder="璇疯緭鍏ラ�氱煡鏍囬鎼滅储"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title ml10">閫氱煡绫诲瀷锛�</span>
- <el-select v-model="searchForm.type" clearable @change="handleQuery" style="width: 240px">
- <el-option label="鏀惧亣閫氱煡" :value="'holiday'" />
- <el-option label="澶勭綒閫氱煡" :value="'penalty'" />
- <el-option label="寮�浼氶�氱煡" :value="'meeting'" />
- <el-option label="涓存椂閫氱煡" :value="'temporary'" />
- <el-option label="姝e紡閫氱煡" :value="'formal'" />
- </el-select>
- <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 type="success" @click="openMeetingDialog">鍦ㄧ嚎浼氳</el-button>
- <el-button type="warning" @click="openFileShareDialog">鏂囦欢鍏变韩</el-button>
- <!-- <el-button type="info" @click="refreshEmployees">鍒锋柊鍛樺伐</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>
-
- <!-- 鏂板/缂栬緫閫氱煡寮圭獥 -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="800px"
- :close-on-click-modal="false"
- >
- <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閫氱煡鏍囬" prop="title">
- <el-input v-model="form.title" placeholder="璇疯緭鍏ラ�氱煡鏍囬" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閫氱煡绫诲瀷" prop="type">
- <el-select v-model="form.type" placeholder="璇烽�夋嫨閫氱煡绫诲瀷" style="width: 100%">
- <el-option label="鏀惧亣閫氱煡" value="holiday" />
- <el-option label="澶勭綒閫氱煡" value="penalty" />
- <el-option label="寮�浼氶�氱煡" value="meeting" />
- <el-option label="涓存椂閫氱煡" value="temporary" />
- <el-option label="姝e紡閫氱煡" value="formal" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浼樺厛绾�" prop="priority">
- <el-select v-model="form.priority" placeholder="璇烽�夋嫨浼樺厛绾�" style="width: 100%">
- <el-option label="鏅��" value="low" />
- <el-option label="閲嶈" value="medium" />
- <el-option label="绱ф��" value="high" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈夋晥鏈熻嚦" prop="expireDate">
- <el-date-picker
- v-model="form.expireDate"
- type="date"
- placeholder="璇烽�夋嫨鏈夋晥鏈�"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="鎺ユ敹閮ㄩ棬" prop="departments">
- <el-select
- v-model="form.departments"
- multiple
- placeholder="璇烽�夋嫨鎺ユ敹閮ㄩ棬"
- style="width: 100%"
- >
- <el-option
- v-for="dept in departments"
- :key="dept"
- :label="dept"
- :value="dept"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鍚屾鏂瑰紡" prop="syncMethods">
- <el-checkbox-group v-model="form.syncMethods">
- <el-checkbox
- v-for="method in syncMethods"
- :key="method.value"
- :label="method.value"
- >
- {{ method.label }}
- </el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- <el-form-item label="閫氱煡鍐呭" prop="content">
- <el-input
- v-model="form.content"
- type="textarea"
- :rows="4"
- placeholder="璇疯緭鍏ラ�氱煡鍐呭"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 鍦ㄧ嚎浼氳寮圭獥 -->
- <el-dialog
- v-model="meetingDialogVisible"
- title="鍒涘缓鍦ㄧ嚎浼氳"
- width="700px"
- :close-on-click-modal="false"
- >
- <el-form ref="meetingFormRef" :model="meetingForm" :rules="meetingRules" label-width="120px">
- <el-form-item label="浼氳鏍囬" prop="title">
- <el-input v-model="meetingForm.title" placeholder="璇疯緭鍏ヤ細璁爣棰�" />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫椂闂�" prop="startTime">
- <el-date-picker
- v-model="meetingForm.startTime"
- type="datetime"
- value-format="YYYY-MM-DD HH:mm:ss"
- format="YYYY-MM-DD HH:mm:ss"
- placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浼氳鏃堕暱" prop="duration">
- <el-input-number
- v-model="meetingForm.duration"
- :min="15"
- :max="480"
- :step="15"
- style="width: 100%"
- />
- <span style="margin-left: 10px">鍒嗛挓</span>
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="浼氳骞冲彴" prop="platform">
- <el-select v-model="meetingForm.platform" placeholder="璇烽�夋嫨浼氳骞冲彴" style="width: 100%">
- <el-option
- v-for="platform in meetingPlatforms"
- :key="platform.value"
- :label="platform.label"
- :value="platform.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鍙備細浜哄憳" prop="participants">
- <el-select
- v-model="meetingForm.participants"
- multiple
- filterable
- remote
- :remote-method="filterEmployees"
- :loading="employeesLoading"
- placeholder="璇烽�夋嫨鍙備細浜哄憳"
- style="width: 100%"
- >
- <el-option-group
- v-for="group in employeeGroups"
- :key="group.label"
- :label="group.label"
- >
- <el-option
- v-for="employee in group.options"
- :key="employee.value"
- :label="`${employee.label} (${employee.dept})`"
- :value="employee.value"
- >
- <div style="display: flex; justify-content: space-between; align-items: center;">
- <div>
- <div style="font-weight: 500;">{{ employee.label }}</div>
- <div style="color: #909399; font-size: 12px;">{{ employee.dept }}</div>
- </div>
- <div style="text-align: right; font-size: 12px; color: #909399;">
- <div v-if="employee.phone">{{ employee.phone }}</div>
- <div v-if="employee.email">{{ employee.email }}</div>
- </div>
- </div>
- </el-option>
- </el-option-group>
- </el-select>
- <div style="margin-top: 8px; color: #909399; font-size: 12px;">
- 宸查�夋嫨 {{ meetingForm.participants.length }} 浜�
- </div>
- <!-- 宸查�夋嫨浜哄憳璇︽儏 -->
- <div v-if="meetingForm.participants.length > 0" style="margin-top: 10px;">
- <el-tag
- v-for="participantId in meetingForm.participants"
- :key="participantId"
- closable
- @close="removeParticipant(participantId)"
- style="margin-right: 8px; margin-bottom: 8px;"
- >
- {{ getEmployeeName(participantId) }}
- </el-tag>
- </div>
- </el-form-item>
- <el-form-item label="浼氳鎻忚堪" prop="description">
- <el-input
- v-model="meetingForm.description"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ヤ細璁弿杩�"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="meetingDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="createMeeting">鍒涘缓浼氳</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 鏂囦欢鍏变韩寮圭獥 -->
- <el-dialog
- v-model="fileShareDialogVisible"
- title="鏂囦欢鍏变韩"
- width="700px"
- :close-on-click-modal="false"
- >
- <el-form ref="fileShareFormRef" :model="fileShareForm" :rules="fileShareRules" label-width="120px">
- <el-form-item label="鍏变韩鏍囬" prop="title">
- <el-input v-model="fileShareForm.title" placeholder="璇疯緭鍏ュ叡浜爣棰�" />
- </el-form-item>
- <el-form-item label="鍏变韩鎻忚堪" prop="description">
- <el-input
- v-model="fileShareForm.description"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ叡浜弿杩�"
- />
- </el-form-item>
- <el-form-item label="鎺ユ敹閮ㄩ棬" prop="departments">
- <el-select
- v-model="fileShareForm.departments"
- multiple
- placeholder="璇烽�夋嫨鎺ユ敹閮ㄩ棬"
- style="width: 100%"
- >
- <el-option
- v-for="dept in departments"
- :key="dept"
- :label="dept"
- :value="dept"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="涓婁紶鏂囦欢" prop="files">
- <el-upload
- ref="uploadRef"
- :auto-upload="false"
- :on-change="handleFileChange"
- :on-remove="removeFile"
- :file-list="fileList"
- multiple
- :limit="10"
- accept=".doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx,.txt,.jpg,.jpeg,.png,.gif"
- >
- <el-button type="primary">閫夋嫨鏂囦欢</el-button>
- <template #tip>
- <div class="el-upload__tip">
- 鏀寔涓婁紶鏂囨。銆佸浘鐗囩瓑鏍煎紡锛屽崟涓枃浠朵笉瓒呰繃10MB锛屾渶澶�10涓枃浠�
- </div>
- </template>
- </el-upload>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="fileShareDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="shareFiles">鍏变韩鏂囦欢</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs, computed } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
-import { listNotification, addNotification, updateNotification, delNotification,addOnlineMeeting,addFileSharing } from "@/api/collaborativeApproval/notificationManagement.js";
-import { id } from "element-plus/es/locales.mjs";
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- title: [
- { required: true, message: "璇疯緭鍏ラ�氱煡鏍囬", trigger: "blur" }
- ],
- type: [
- { required: true, message: "璇烽�夋嫨閫氱煡绫诲瀷", trigger: "change" }
- ],
- content: [
- { required: true, message: "璇疯緭鍏ラ�氱煡鍐呭", trigger: "blur" }
- ]
-};
-
-const meetingRules = {
- title: [
- { required: true, message: "璇疯緭鍏ヤ細璁爣棰�", trigger: "blur" }
- ],
- startTime: [
- { required: true, message: "璇烽�夋嫨浼氳寮�濮嬫椂闂�", trigger: "change" }
- ],
- participants: [
- { required: true, message: "璇烽�夋嫨鍙備細浜哄憳", trigger: "change" }
- ]
-};
-
-const fileShareRules = {
- title: [
- { required: true, message: "璇疯緭鍏ュ叡浜爣棰�", trigger: "blur" }
- ],
- description: [
- { required: true, message: "璇疯緭鍏ュ叡浜弿杩�", trigger: "blur" }
- ]
-};
-
-// 鍝嶅簲寮忔暟鎹�
-const data = reactive({
- searchForm: {
- title: "",
- type: "",
- status: "",
- },
- tableLoading: false,
- page: {
- current: 1,
- size: 20,
- total: 0,
- },
- tableData: [],
- selectedIds: [],
- // 鏂板閫氱煡鐩稿叧
- form: {
- title: "",
- type: "",
- priority: "",
- content: "",
- departments: [],
- expireDate: "",
- syncMethods: []
- },
- dialogVisible: false,
- dialogTitle: "",
- dialogType: "add",
- // 鍦ㄧ嚎浼氳鐩稿叧
- meetingDialogVisible: false,
- meetingForm: {
- title: "",
- startTime: "",
- duration: 60,
- participants: [],
- description: "",
- platform: "wechat"
- },
- // 鏂囦欢鍏变韩鐩稿叧
- fileShareDialogVisible: false,
- fileShareForm: {
- title: "",
- description: "",
- departments: [],
- files: []
- },
- fileList: []
-});
-
-const {
- searchForm,
- tableLoading,
- page,
- tableData,
- selectedIds,
- form,
- dialogVisible,
- dialogTitle,
- dialogType,
- meetingDialogVisible,
- meetingForm,
- fileShareDialogVisible,
- fileShareForm,
- fileList
-} = toRefs(data);
-
-// 琛ㄥ崟寮曠敤
-const formRef = ref();
-const meetingFormRef = ref();
-const fileShareFormRef = ref();
-
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumn = ref([
- {
- label: "閫氱煡鏍囬",
- prop: "title",
- showOverflowTooltip: true,
- },
- {
- label: "閫氱煡绫诲瀷",
- prop: "type",
- dataType: "tag",
- formatData: (params) => {
- const typeMap = {
- holiday: "鏀惧亣閫氱煡",
- penalty: "澶勭綒閫氱煡",
- meeting: "寮�浼氶�氱煡",
- temporary: "涓存椂閫氱煡",
- formal: "姝e紡閫氱煡"
- };
- return typeMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- holiday: "success",
- penalty: "danger",
- meeting: "warning",
- temporary: "info",
- formal: "primary"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "浼樺厛绾�",
- prop: "priority",
- dataType: "tag",
- formatData: (params) => {
- const priorityMap = {
- low: "鏅��",
- medium: "閲嶈",
- high: "绱ф��"
- };
- return priorityMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- low: "info",
- medium: "warning",
- high: "danger"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- const statusMap = {
- draft: "鑽夌",
- published: "宸插彂甯�",
- expired: "宸茶繃鏈�"
- };
- return statusMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- draft: "info",
- published: "success",
- expired: "danger"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "鎺ユ敹閮ㄩ棬",
- prop: "departments",
- width: 150,
- showOverflowTooltip: true,
- formatData: (params) => {
- if (!params || params.length === 0) return "鍏ㄩ儴閮ㄩ棬";
- return params.join(", ");
- }
- },
- {
- label: "鏈夋晥鏈熻嚦",
- prop: "expireDate",
- width: 150,
- formatData: (params) => {
- if (!params) return "姘镐箙鏈夋晥";
- return params;
- }
- },
- {
- label: "鍒涘缓鏃堕棿",
- prop: "createTime",
- width: 180,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 280,
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- }
- },
- {
- name: "鍙戝竷",
- type: "text",
- clickFun: (row) => {
- publishNotification(row);
- },
- },
- {
- name: "鎾ゅ洖",
- type: "text",
- clickFun: (row) => {
- revokeNotification(row);
- },
- }
- ]
- }
-]);
-// 閫氱煡鏍囬妯℃澘
-const titleTemplates = [
- "鍏充簬{year}骞磠holiday}鏀惧亣瀹夋帓鐨勯�氱煡",
- "{dept}閮ㄩ棬{meeting}浼氳閫氱煡",
- "鍛樺伐{behavior}琛屼负瑙勮寖鎻愰啋",
- "{company}閲嶈浜嬮」閫氱煡",
- "{dept}閮ㄩ棬宸ヤ綔瀹夋帓閫氱煡",
- "鍏充簬{project}椤圭洰杩涘害鐨勯�氱煡",
- "{dept}閮ㄩ棬浜哄憳璋冩暣閫氱煡",
- "鍏徃{policy}鏀跨瓥鏇存柊閫氱煡"
-];
-
-// 閫氱煡绫诲瀷閰嶇疆
-const notificationTypes = [
- { type: "holiday", label: "鏀惧亣閫氱煡", priority: "high" },
- { type: "meeting", label: "寮�浼氶�氱煡", priority: "medium" },
- { type: "penalty", label: "澶勭綒閫氱煡", priority: "high" },
- { type: "temporary", label: "涓存椂閫氱煡", priority: "low" },
- { type: "formal", label: "姝e紡閫氱煡", priority: "medium" }
-];
-
-// 閮ㄩ棬鍒楄〃
-const departments = ["鎶�鏈儴", "閿�鍞儴", "浜轰簨閮�", "璐㈠姟閮�", "杩愯惀閮�", "甯傚満閮�", "瀹㈡湇閮�"];
-
-// 浜哄憳鍒楄〃
-const employees = ref([]);
-const employeesLoading = ref(false);
-
-// 鑾峰彇鍦ㄨ亴鍛樺伐鍒楄〃
-const getEmployeesList = async () => {
- try {
- employeesLoading.value = true;
- // 浼樺厛浣跨敤绯荤粺鐢ㄦ埛鎺ュ彛锛堟寜绉熸埛鑾峰彇锛�
- const userResponse = await userListNoPageByTenantId();
-
- if (userResponse.data) {
- employees.value = userResponse.data.map(user => ({
- label: user.nickName || user.userName || '鏈煡濮撳悕',
- value: user.userId || user.id,
- dept: user.dept?.deptName || '鏈煡閮ㄩ棬',
- phone: user.phonenumber || '',
- email: user.email || '',
- status: user.status || '0'
- })).filter(user => user.status === '0'); // 鍙樉绀烘甯哥姸鎬佺殑鐢ㄦ埛
- } else {
- // 濡傛灉绯荤粺鐢ㄦ埛鎺ュ彛澶辫触锛屼娇鐢ㄥ憳宸ュ彴璐︽帴鍙�
- const response = await staffOnJobListPage({
- pageNum: 1,
- pageSize: 1000,
- staffState: 1 // 鍦ㄨ亴鐘舵��
- });
-
- if (response.data && response.data.records) {
- employees.value = response.data.records.map(employee => ({
- label: employee.staffName || employee.name || '鏈煡濮撳悕',
- value: employee.staffNo || employee.id || employee.staffId,
- dept: employee.deptName || employee.department || '鏈煡閮ㄩ棬',
- phone: employee.phone || employee.mobile || '',
- email: employee.email || '',
- status: '0'
- }));
- }
- }
- } catch (error) {
- console.error('鑾峰彇鍛樺伐鍒楄〃澶辫触:', error);
- // 濡傛灉鎺ュ彛閮藉け璐ワ紝浣跨敤榛樿鏁版嵁
- employees.value = [
- { label: "寮犱笁", value: "001", dept: "鎶�鏈儴", phone: "13800138001", email: "zhangsan@company.com", status: "0" },
- { label: "鏉庡洓", value: "002", dept: "閿�鍞儴", phone: "13800138002", email: "lisi@company.com", status: "0" },
- { label: "鐜嬩簲", value: "003", dept: "浜轰簨閮�", phone: "13800138003", email: "wangwu@company.com", status: "0" }
- ];
- } finally {
- employeesLoading.value = false;
- }
-};
-
-// 鍛樺伐鍒嗙粍
-const employeeGroups = computed(() => {
- const groups = {};
- employees.value.forEach(employee => {
- const dept = employee.dept || '鍏朵粬閮ㄩ棬';
- if (!groups[dept]) {
- groups[dept] = [];
- }
- groups[dept].push(employee);
- });
-
- // 鎸夐儴闂ㄥ悕绉版帓搴忥紝纭繚鏄剧ず椤哄簭涓�鑷�
- return Object.keys(groups)
- .sort()
- .map(dept => ({
- label: dept,
- options: groups[dept].sort((a, b) => a.label.localeCompare(b.label, 'zh-CN'))
- }));
-});
-
-// 杩囨护鍛樺伐锛堣繙绋嬫悳绱級
-const filterEmployees = (query) => {
- if (query !== '') {
- const lowerQuery = query.toLowerCase();
- return employees.value.filter(employee =>
- employee.label.toLowerCase().includes(lowerQuery) ||
- employee.dept.toLowerCase().includes(lowerQuery) ||
- (employee.phone && employee.phone.includes(query)) ||
- (employee.email && employee.email.toLowerCase().includes(lowerQuery))
- );
- } else {
- return employees.value;
- }
-};
-
-// 鍒锋柊鍛樺伐鍒楄〃
-const refreshEmployees = async () => {
- ElMessage.info("姝e湪鍒锋柊鍛樺伐鍒楄〃...");
- await getEmployeesList();
-
- // 缁熻鍚勯儴闂ㄤ汉鏁�
- const deptStats = {};
- employees.value.forEach(emp => {
- const dept = emp.dept || '鍏朵粬閮ㄩ棬';
- deptStats[dept] = (deptStats[dept] || 0) + 1;
- });
-
- const deptInfo = Object.entries(deptStats)
- .map(([dept, count]) => `${dept}: ${count}浜篳)
- .join(', ');
-
- ElMessage.success(`鍛樺伐鍒楄〃鍒锋柊瀹屾垚锛屽叡 ${employees.value.length} 浜� (${deptInfo})`);
-};
-
-// 鑾峰彇鍛樺伐濮撳悕
-const getEmployeeName = (employeeId) => {
- const employee = employees.value.find(emp => emp.value === employeeId);
- return employee ? employee.label : '鏈煡浜哄憳';
-};
-
-// 鑾峰彇鍛樺伐璇︾粏淇℃伅
-const getEmployeeInfo = (employeeId) => {
- const employee = employees.value.find(emp => emp.value === employeeId);
- if (!employee) return null;
-
- return {
- name: employee.label,
- dept: employee.dept,
- phone: employee.phone,
- email: employee.email
- };
-};
-
-// 绉婚櫎鍙備細浜哄憳
-const removeParticipant = (participantId) => {
- const index = meetingForm.value.participants.indexOf(participantId);
- if (index > -1) {
- meetingForm.value.participants.splice(index, 1);
- }
-};
-
-// 鍚屾鏂瑰紡閫夐」
-const syncMethods = [
- { label: "浼佷笟寰俊", value: "wechat" },
- { label: "閽夐拤", value: "dingtalk" },
- { label: "閭欢", value: "email" },
- { label: "鐭俊", value: "sms" }
-];
-
-// 浼氳骞冲彴閫夐」
-const meetingPlatforms = [
- { label: "浼佷笟寰俊浼氳", value: "wechat" },
- { label: "閽夐拤浼氳", value: "dingtalk" },
- { label: "鑵捐浼氳", value: "tencent" },
- { label: "Zoom", value: "zoom" }
-];
-
-// 鑷姩鐢熸垚鏂版暟鎹�
-const generateNewData = () => {
- const newId = (mockData.length + 1).toString();
- const now = new Date();
- const randomType = notificationTypes[Math.floor(Math.random() * notificationTypes.length)];
- const randomDept = departments[Math.floor(Math.random() * departments.length)];
-
- // 鐢熸垚闅忔満鏍囬
- let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
- title = title
- .replace('{year}', now.getFullYear())
- .replace('{holiday}', ['鏄ヨ妭', '鍥藉簡', '涓', '鍏冩棪'][Math.floor(Math.random() * 4)])
- .replace('{dept}', randomDept)
- .replace('{meeting}', ['鍛ㄤ緥浼�', '鏈堝害鎬荤粨', '椤圭洰璇勫', '鍩硅浼氳'][Math.floor(Math.random() * 4)])
- .replace('{behavior}', ['鑰冨嫟', '鐫�瑁�', '宸ヤ綔鎬佸害', '鍥㈤槦鍗忎綔'][Math.floor(Math.random() * 4)])
- .replace('{company}', ['鍏徃', '闆嗗洟', '鎬婚儴'][Math.floor(Math.random() * 4)])
- .replace('{project}', ['鏁板瓧鍖栬浆鍨�', '浜у搧鍗囩骇', '甯傚満鎷撳睍', '浜烘墠鍩瑰吇'][Math.floor(Math.random() * 4)])
- .replace('{policy}', ['鑰冨嫟', '钖叕', '绂忓埄', '鏅嬪崌'][Math.floor(Math.random() * 4)]);
-
- // 闅忔満鐘舵��
- const statuses = ['draft', 'published'];
- const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
-
- // 闅忔満浼樺厛绾�
- const priorities = ['low', 'medium', 'high'];
- const randomPriority = priorities[Math.floor(Math.random() * priorities.length)];
-
- const newNotification = {
- id: newId,
- title: title,
- type: randomType.type,
- priority: randomPriority,
- status: randomStatus,
- content: `杩欐槸${title}鐨勮缁嗗唴瀹癸紝璇风浉鍏充汉鍛樻敞鎰忔煡鐪�...`,
- departments: [randomDept],
- expireDate: new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 30澶╁悗杩囨湡
- syncMethods: ["wechat", "dingtalk"],
- createTime: now.toLocaleString()
- };
-
- // 娣诲姞鍒版暟鎹紑澶�
- mockData.unshift(newNotification);
-
- // 淇濇寔鏁版嵁閲忓湪鍚堢悊鑼冨洿鍐咃紙鏈�澶氫繚鐣�20鏉★級
- if (mockData.length > 20) {
- mockData = mockData.slice(0, 20);
- }
-
- console.log(`[${new Date().toLocaleString()}] 鑷姩鐢熸垚鏂伴�氱煡: ${title}`);
-};
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- getList();
- getEmployeesList(); // 鑾峰彇鍛樺伐鍒楄〃
- startAutoRefresh();
-});
-
-// 寮�濮嬭嚜鍔ㄥ埛鏂�
-const startAutoRefresh = () => {
- setInterval(() => {
- generateNewData();
- getList();
- }, 600000); // 10鍒嗛挓鍒锋柊涓�娆� (10 * 60 * 1000 = 600000ms)
-};
-
-// 鏌ヨ鏁版嵁
-const handleQuery = () => {
- page.value.current = 1;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- listNotification({...page.value, ...searchForm.value})
- .then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.value.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-
-// 鍒嗛〉澶勭悊
-const pagination = (obj) => {
- page.value.current = obj.page;
- page.value.size = obj.limit;
- handleQuery();
-};
-
-// 閫夋嫨鍙樺寲澶勭悊
-const handleSelectionChange = (selection) => {
- selectedIds.value = selection.map(item => item.id);
-};
-
-// 鎵撳紑琛ㄥ崟
-const openForm = (type, row = null) => {
- dialogType.value = type;
- if (type === "add") {
- dialogTitle.value = "鏂板閫氱煡";
- // 閲嶇疆琛ㄥ崟
- Object.assign(form.value, {
- id: "",
- title: "",
- type: "",
- priority: "",
- content: "",
- departments: [],
- expireDate: "",
- status: "draft",
- syncMethods: []
- });
- } else if (type === "edit" && row) {
- dialogTitle.value = "缂栬緫閫氱煡";
- Object.assign(form.value, {
- id: row.id,
- title: row.title,
- type: row.type,
- priority: row.priority,
- content: row.content || "",
- departments: row.departments || [],
- expireDate: row.expireDate || "",
- status: row.status,
- syncMethods: row.syncMethods || []
- });
- }
- dialogVisible.value = true;
-};
-
-// 鎵撳紑鍦ㄧ嚎浼氳寮圭獥
-const openMeetingDialog = () => {
- // 閲嶇疆琛ㄥ崟
- Object.assign(meetingForm.value, {
- title: "",
- startTime: "",
- duration: 60,
- participants: [],
- description: "",
- platform: "wechat"
- });
- meetingDialogVisible.value = true;
-};
-
-// 鎵撳紑鏂囦欢鍏变韩寮圭獥
-const openFileShareDialog = () => {
- // 閲嶇疆琛ㄥ崟
- Object.assign(fileShareForm.value, {
- title: "",
- description: "",
- departments: [],
- files: []
- });
- fileList.value = [];
- fileShareDialogVisible.value = true;
-};
-
-// 鎵嬪姩鍒锋柊鏁版嵁
-const manualRefresh = () => {
- generateNewData();
- getList();
- ElMessage.success("鎵嬪姩鍒锋柊瀹屾垚锛屽凡鐢熸垚鏂伴�氱煡");
-};
-
-// 鎻愪氦閫氱煡琛ㄥ崟
-const submitForm = async () => {
- try {
- await formRef.value.validate();
-
- if (dialogType.value === "add") {
- // 鏂板閫氱煡
- addNotification({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else {
- // 缂栬緫閫氱煡
- updateNotification({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- } catch (error) {
- console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
- }
-};
-
-// 鍒涘缓浼氳
-const createMeeting = async () => {
- try {
- await meetingFormRef.value.validate();
-
- // 妯℃嫙鍒涘缓浼氳
- const meetingInfo = {
- title: meetingForm.value.title,
- startTime: meetingForm.value.startTime,
- duration: meetingForm.value.duration,
- participants: meetingForm.value.participants,
- description: meetingForm.value.description,
- platform: meetingForm.value.platform
- };
- // 鏂板浼氳
- addOnlineMeeting({...meetingInfo}).then(res => {
- if(res.code == 200){
- ElMessage.success("浼氳娣诲姞鎴愬姛");
- meetingDialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // 妯℃嫙鍙戦�佸埌浼佷笟寰俊/閽夐拤
- // const platformName = meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "鏈煡骞冲彴";
- // ElMessage.success(`浼氳鍒涘缓鎴愬姛锛佷細璁甀D: ${meetingInfo.meetingId}锛屽皢閫氳繃${platformName}鍙戦�侀�氱煡`);
-
- // 鑾峰彇鍙備細浜哄憳淇℃伅
- const participantNames = meetingForm.value.participants.map(participantId => {
- const employee = employees.value.find(emp => emp.value === participantId);
- return employee ? employee.label : '鏈煡浜哄憳';
- }).join('銆�');
-
- // 鑾峰彇鍙備細浜哄憳璇︾粏淇℃伅
- const participantDetails = meetingForm.value.participants.map(participantId => {
- const employee = employees.value.find(emp => emp.value === participantId);
- return employee ? {
- name: employee.label,
- dept: employee.dept,
- phone: employee.phone,
- email: employee.email
- } : null;
- }).filter(Boolean);
-
- // 灏嗕細璁俊鎭坊鍔犲埌閫氱煡鍒楄〃
- const meetingNotification = {
- title: `[浼氳閫氱煡] ${meetingInfo.title}`,
- type: "meeting",
- priority: "high",
- status: "published",
- content: `浼氳鏃堕棿: ${meetingInfo.startTime}锛屾椂闀�: ${meetingInfo.duration}鍒嗛挓锛屽钩鍙�: ${meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "鏈煡骞冲彴"}锛屽弬浼氫汉鍛�: ${participantNames}锛屽叡${participantDetails.length}浜篳,
- departments: [],
- expireDate: "",
- syncMethods: [meetingForm.value.platform]
- };
- addNotification({...meetingNotification}).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- // dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // mockData.unshift(meetingNotification);
- // getList();
- } catch (error) {
- console.error("浼氳琛ㄥ崟楠岃瘉澶辫触:", error);
- }
-};
-
-// 鏂囦欢涓婁紶澶勭悊
-const handleFileChange = (file) => {
- const isLt10M = file.size / 1024 / 1024 < 10;
- if (!isLt10M) {
- ElMessage.error("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
- return false;
- }
-
- const fileInfo = {
- name: file.name,
- size: file.size,
- type: file.type,
- uid: file.uid
- };
-
- fileList.value.push(fileInfo);
- fileShareForm.value.files.push(fileInfo.name);
- return false; // 闃绘鑷姩涓婁紶
-};
-
-// 绉婚櫎鏂囦欢
-const removeFile = (file) => {
- const index = fileList.value.findIndex(item => item.uid === file.uid);
- if (index !== -1) {
- const index2 = fileShareForm.value.files.findIndex(item => item.uid === file.uid);
- if (index2 !== -1) {
- fileShareForm.value.files.splice(index2, 1);
- }
- fileList.value.splice(index, 1);
- }
-};
-
-// 鍏变韩鏂囦欢
-const shareFiles = async () => {
- try {
- await fileShareFormRef.value.validate();
-
- if (fileShareForm.value.files.length === 0) {
- ElMessage.warning("璇疯嚦灏戦�夋嫨涓�涓枃浠�");
- return;
- }
-
- // 妯℃嫙鏂囦欢鍏变韩
- const shareInfo = {
- title: fileShareForm.value.title,
- description: fileShareForm.value.description,
- departments: fileShareForm.value.departments,
- files: fileShareForm.value.files,
- };
- addFileSharing({...shareInfo}).then(res => {
- if(res.code == 200){
- ElMessage.success("鏂囦欢鍏变韩鎴愬姛");
- fileShareDialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-
- // ElMessage.success(`鏂囦欢鍏变韩鎴愬姛锛佸叡浜獻D: ${shareInfo.shareId}锛屽凡閫氱煡鐩稿叧閮ㄩ棬`);
-
-
- // 灏嗘枃浠跺叡浜俊鎭坊鍔犲埌閫氱煡鍒楄〃
- const fileShareNotification = {
- title: `[鏂囦欢鍏变韩] ${shareInfo.title}`,
- type: "temporary",
- priority: "medium",
- status: "published",
- content: `鍏变韩鎻忚堪: ${shareInfo.description}锛屾枃浠舵暟閲�: ${shareInfo.files.length}涓猔,
- departments: shareInfo.departments,
- expireDate: "",
- syncMethods: ["wechat", "dingtalk"],
- };
- addNotification({...fileShareNotification}).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- // dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-
- // mockData.unshift(fileShareNotification);
- // getList();
- } catch (error) {
- console.error("鏂囦欢鍏变韩琛ㄥ崟楠岃瘉澶辫触:", error);
- }
-};
-
-// 鍙戝竷閫氱煡
-const publishNotification = (row) => {
- Object.assign(form.value, {
- id: row.id,
- title: row.title,
- type: row.type,
- priority: row.priority,
- content: row.content || "",
- departments: row.departments || [],
- expireDate: row.expireDate || "",
- status: row.status,
- syncMethods: row.syncMethods || []
- });
- form.value.status = "published";
- updateNotification({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("閫氱煡鍙戝竷鎴愬姛");
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-};
-
-// 鎾ゅ洖閫氱煡
-const revokeNotification = (row) => {
- Object.assign(form.value, {
- id: row.id,
- title: row.title,
- type: row.type,
- priority: row.priority,
- content: row.content || "",
- departments: row.departments || [],
- expireDate: row.expireDate || "",
- status: row.status,
- syncMethods: row.syncMethods || []
- });
- form.value.status = "draft";
- updateNotification({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("閫氱煡宸叉挙鍥�");
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-};
-
-// 鍒犻櫎閫氱煡
-const handleDelete = () => {
- let ids = [];
- if (selectedIds.value.length > 0) {
- ids = selectedIds.value;
- }else{
- ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑閫氱煡");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- delNotification(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- selectedIds.value = [];
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }).catch(() => {
- // 鐢ㄦ埛鍙栨秷
- });
-};
-</script>
-
-<style scoped>
-.auto-refresh-info {
- margin-bottom: 15px;
-}
-
-.auto-refresh-info .el-alert {
- border-radius: 8px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-.el-upload__tip {
- color: #909399;
- font-size: 12px;
- margin-top: 8px;
-}
-
-.el-checkbox-group {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
-}
-
-.el-checkbox {
- margin-right: 0;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue b/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
deleted file mode 100644
index 1a2859a..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetApplication/index.vue
+++ /dev/null
@@ -1,398 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳鐢宠</h2>
- </div>
-
- <!-- 鐢宠绫诲瀷閫夋嫨 -->
- <el-card class="type-card">
- <div class="type-selector">
- <div
- v-for="type in applicationTypes"
- :key="type.value"
- class="type-item"
- :class="{ active: currentType === type.value }"
- @click="changeType(type.value)"
- >
- <div class="type-icon">
- <el-icon :size="24"><component :is="type.icon"/></el-icon>
- </div>
- <div class="type-info">
- <div class="type-name">{{ type.name }}</div>
- <div class="type-desc">{{ type.desc }}</div>
- </div>
- </div>
- </div>
- </el-card>
-
- <!-- 浼氳鐢宠琛ㄥ崟 -->
- <el-card>
- <div class="form-header">
- <h3>{{ getCurrentTypeName() }}鐢宠</h3>
- </div>
-
- <el-form
- ref="meetingFormRef"
- :model="meetingForm"
- :rules="rules"
- label-width="100px"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浼氳涓婚" prop="title">
- <el-input v-model="meetingForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�"/>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浼氳瀹�" prop="roomId">
- <el-select v-model="meetingForm.roomId" placeholder="璇烽�夋嫨浼氳瀹�" style="width: 100%">
- <el-option
- v-for="room in meetingRooms"
- :key="room.id"
- :label="`${room.name} (${room.location})`"
- :value="room.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓绘寔浜�" prop="host">
- <el-input v-model="meetingForm.host" placeholder="璇疯緭鍏ヤ富鎸佷汉濮撳悕"/>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浼氳鏃ユ湡" prop="meetingDate">
- <el-date-picker
- v-model="meetingForm.meetingDate"
- type="date"
- placeholder="璇烽�夋嫨浼氳鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- :disabled-date="disabledDate"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <!-- 绌哄垪锛屼繚鎸佸竷灞� -->
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫椂闂�" prop="startTime">
- <el-select
- v-model="meetingForm.startTime"
- placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
- style="width: 100%"
- >
- <el-option
- v-for="time in timeOptions"
- :key="time.value"
- :label="time.label"
- :value="time.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃堕棿" prop="endTime">
- <el-select
- v-model="meetingForm.endTime"
- placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
- style="width: 100%"
- >
- <el-option
- v-for="time in timeOptions"
- :key="time.value"
- :label="time.label"
- :value="time.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="鍙備細浜哄憳" prop="participants">
- <el-select
- v-model="meetingForm.participants"
- multiple
- filterable
- placeholder="璇烽�夋嫨鍙備細浜哄憳"
- style="width: 100%"
- >
- <el-option
- v-for="person in employees"
- :key="person.id"
- :label="`${person.staffName} (${person.postJob})`"
- :value="person.id"
- />
- </el-select>
- </el-form-item>
-
- <el-form-item label="浼氳璇存槑" prop="description">
- <el-input
- v-model="meetingForm.description"
- type="textarea"
- :rows="4"
- placeholder="璇疯緭鍏ヤ細璁鏄�"
- />
- </el-form-item>
- </el-form>
-
- <div class="form-footer">
- <el-button @click="resetForm">閲嶇疆</el-button>
- <el-button type="primary" @click="submitForm">鎻愪氦</el-button>
- </div>
- </el-card>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, onMounted} from 'vue'
-import {ElMessage} from 'element-plus'
-import {Plus, Document, Promotion, Bell} from '@element-plus/icons-vue'
-import {getRoomEnum, saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
-
-// 褰撳墠鐢宠绫诲瀷
-const currentType = ref('department') // approval: 瀹℃壒娴佺▼, department: 閮ㄩ棬绾�, notification: 閫氱煡鍙戝竷
-
-// 鐢宠绫诲瀷閫夐」
-const applicationTypes = ref([
- {
- value: 'approval',
- name: '瀹℃壒娴佺▼浼氳',
- desc: '闇�瑕佺粡杩囧绾у鎵圭殑浼氳鐢宠',
- icon: Document
- },
- {
- value: 'department',
- name: '閮ㄩ棬绾т細璁�',
- desc: '閮ㄩ棬鍐呴儴浼氳鐢宠娴佺▼',
- icon: Promotion
- },
- {
- value: 'notification',
- name: '浼氳閫氱煡',
- desc: '鏃犻渶瀹℃壒鐩存帴鍙戝竷鐨勪細璁�氱煡',
- icon: Bell
- }
-])
-
-// 琛ㄥ崟鏁版嵁
-const meetingForm = reactive({
- title: '',
- type: '',
- roomId: '',
- host: '',
- meetingDate: '',
- startTime: '',
- endTime: '',
- participants: [],
- description: ''
-})
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- title: [{required: true, message: '璇疯緭鍏ヤ細璁富棰�', trigger: 'blur'}],
- roomId: [{required: true, message: '璇烽�夋嫨浼氳瀹�', trigger: 'change'}],
- host: [{required: true, message: '璇疯緭鍏ヤ富鎸佷汉', trigger: 'blur'}],
- meetingDate: [{required: true, message: '璇烽�夋嫨浼氳鏃ユ湡', trigger: 'change'}],
- startTime: [{required: true, message: '璇烽�夋嫨寮�濮嬫椂闂�', trigger: 'change'}],
- endTime: [{required: true, message: '璇烽�夋嫨缁撴潫鏃堕棿', trigger: 'change'}],
- participants: [{required: true, message: '璇烽�夋嫨鍙備細浜哄憳', trigger: 'change'}]
-}
-
-// 琛ㄥ崟寮曠敤
-const meetingFormRef = ref(null)
-
-// 浼氳瀹ゅ垪琛�
-const meetingRooms = ref([])
-
-// 鍛樺伐鍒楄〃
-const employees = ref([])
-
-// 鏃堕棿閫夐」锛堜互鍗婂皬鏃朵负闂撮殧锛�
-const timeOptions = ref([])
-
-// 鍒濆鍖栨椂闂撮�夐」
-const initTimeOptions = () => {
- const options = []
- for (let hour = 8; hour <= 18; hour++) {
- // 姣忎釜灏忔椂娣诲姞涓や釜閫夐」锛氭暣鐐瑰拰鍗婄偣
- options.push({
- value: `${hour.toString().padStart(2, '0')}:00`,
- label: `${hour.toString().padStart(2, '0')}:00`
- })
-
- if (hour < 18) { // 18:00涔嬪悗娌℃湁鍗婄偣閫夐」
- options.push({
- value: `${hour.toString().padStart(2, '0')}:30`,
- label: `${hour.toString().padStart(2, '0')}:30`
- })
- }
- }
- timeOptions.value = options
-}
-
-// 绂佺敤鏃ユ湡锛堢鐢ㄤ粖澶╀箣鍓嶇殑鏃ユ湡锛�
-const disabledDate = (time) => {
- // 绂佺敤浠婂ぉ涔嬪墠鐨勬棩鏈�
- return time.getTime() < Date.now() - 86400000
-}
-
-// 鍒囨崲鐢宠绫诲瀷
-const changeType = (type) => {
- currentType.value = type
-}
-
-// 鑾峰彇褰撳墠绫诲瀷鍚嶇О
-const getCurrentTypeName = () => {
- const type = applicationTypes.value.find(t => t.value === currentType.value)
- return type ? type.name : ''
-}
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
- meetingFormRef.value?.resetFields()
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- meetingFormRef.value?.validate((valid) => {
- if (valid) {
-
- let formData = {...meetingForm}
- formData.applicationType = currentType.value
- formData.startTime = `${meetingForm.meetingDate} ${meetingForm.startTime}:00`
- formData.endTime = `${meetingForm.meetingDate} ${meetingForm.endTime}:00`
- formData.participants = JSON.stringify(formData.participants)
- console.log(formData)
- saveMeetingApplication(formData).then(() => {
-
- // 妯℃嫙鎻愪氦鎿嶄綔
- ElMessage.success(`${getCurrentTypeName()}鎻愪氦鎴愬姛`)
-
- // 鏍规嵁涓嶅悓绫诲瀷鎵ц涓嶅悓鎿嶄綔
- switch (currentType.value) {
- case 'approval':
- ElMessage.info('浼氳宸叉彁浜ゅ鎵规祦绋�')
- break
- case 'department':
- ElMessage.info('閮ㄩ棬绾т細璁敵璇峰凡鎻愪氦')
- break
- case 'notification':
- ElMessage.info('浼氳閫氱煡宸插彂甯�')
- break
- }
- resetForm()
- })
-
- }
- })
-}
-
-// 椤甸潰鍔犺浇鏃跺垵濮嬪寲
-onMounted(() => {
- initTimeOptions()
- getRoomEnum().then(res => {
- meetingRooms.value = res.data
- })
- getStaffOnJob().then(res => {
- employees.value = res.data.sort((a, b) => a.postJob.localeCompare(b.postJob))
- })
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.type-card {
- margin-bottom: 20px;
-}
-
-.type-selector {
- display: flex;
- gap: 20px;
-}
-
-.type-item {
- flex: 1;
- display: flex;
- align-items: center;
- padding: 20px;
- border: 1px solid #ebeef5;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.3s;
-}
-
-.type-item:hover {
- border-color: #409eff;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-}
-
-.type-item.active {
- border-color: #409eff;
- background-color: #ecf5ff;
-}
-
-.type-icon {
- margin-right: 15px;
- color: #409eff;
-}
-
-.type-name {
- font-size: 16px;
- font-weight: 500;
- color: #303133;
- margin-bottom: 5px;
-}
-
-.type-desc {
- font-size: 14px;
- color: #909399;
-}
-
-.form-header {
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 1px solid #ebeef5;
-}
-
-.form-header h3 {
- margin: 0;
- color: #303133;
-}
-
-.form-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
- margin-top: 30px;
- padding-top: 20px;
- border-top: 1px solid #ebeef5;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetDraft/index.vue b/src/views/collaborativeApproval/notificationManagement/meetDraft/index.vue
deleted file mode 100644
index 0c62b8b..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetDraft/index.vue
+++ /dev/null
@@ -1,495 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳鑽夌</h2>
- <el-button type="primary" @click="handleAdd">
- <el-icon><Plus /></el-icon>
- 鏂板缓鑽夌
- </el-button>
- </div>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :model="searchForm" label-width="100px" inline>
- <el-form-item label="浼氳涓婚">
- <el-input v-model="searchForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�" clearable />
- </el-form-item>
- <el-form-item label="浼氳鏃ユ湡">
- <el-date-picker
- v-model="searchForm.meetingDate"
- type="date"
- placeholder="璇烽�夋嫨浼氳鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 鑽夌鍒楄〃 -->
- <el-card>
- <el-table v-loading="loading" :data="draftList" border>
- <el-table-column prop="title" label="浼氳涓婚" align="center" min-width="200" show-overflow-tooltip />
- <el-table-column prop="room" label="浼氳瀹�" align="center" width="120" />
- <el-table-column prop="host" label="涓绘寔浜�" align="center" width="120" />
- <el-table-column prop="meetingTime" label="浼氳鏃堕棿" align="center" width="180">
- <template #default="scope">
- {{ formatDateTime(scope.row.meetingTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="participants" label="鍙備細浜烘暟" align="center" width="100">
- <template #default="scope">
- {{ scope.row.participants }}浜�
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" align="center" width="180" />
- <el-table-column label="鎿嶄綔" align="center" width="200" fixed="right">
- <template #default="scope">
- <el-button type="primary" link @click="viewDraft(scope.row)">鏌ョ湅</el-button>
- <el-button type="primary" link @click="editDraft(scope.row)">缂栬緫</el-button>
- <el-button type="danger" link @click="deleteDraft(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 浼氳鑽夌璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="浼氳鑽夌璇︽儏"
- v-model="detailDialogVisible"
- width="800px"
- >
- <div v-if="currentDraft">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浼氳涓婚">{{ currentDraft.title }}</el-descriptions-item>
- <el-descriptions-item label="浼氳缂栧彿">{{ currentDraft.meetingId }}</el-descriptions-item>
- <el-descriptions-item label="浼氳瀹�">{{ currentDraft.room }}</el-descriptions-item>
- <el-descriptions-item label="涓绘寔浜�">{{ currentDraft.host }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2">
- {{ formatDateTime(currentDraft.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="鍒涘缓鏃堕棿">{{ currentDraft.createTime }}</el-descriptions-item>
- </el-descriptions>
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- {{ currentDraft.participantList }}
- </div>
- </div>
-
- <div class="content-section mt-20">
- <h4>浼氳璇存槑</h4>
- <div class="meeting-description">{{ currentDraft.description }}</div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鏂板缓/缂栬緫鑽夌瀵硅瘽妗� -->
- <el-dialog
- :title="dialogTitle"
- v-model="editDialogVisible"
- width="700px"
- >
- <el-form :model="meetingForm" :rules="rules" ref="meetingFormRef" label-width="100px">
- <el-form-item label="浼氳涓婚" prop="title">
- <el-input v-model="meetingForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�" />
- </el-form-item>
- <el-form-item label="浼氳瀹�" prop="room">
- <el-select v-model="meetingForm.roomId" placeholder="璇烽�夋嫨浼氳瀹�" style="width: 100%">
- <el-option v-for="(v,k) in roomList" :label="v.name" :value="v.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="涓绘寔浜�" prop="host">
- <el-input v-model="meetingForm.host" placeholder="璇疯緭鍏ヤ富鎸佷汉" />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浼氳鏃ユ湡" prop="meetingDate">
- <el-date-picker
- v-model="meetingForm.meetingDate"
- type="date"
- placeholder="璇烽�夋嫨浼氳鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- :disabled-date="disabledDate"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <!-- 绌哄垪锛屼繚鎸佸竷灞� -->
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫椂闂�" prop="startTime">
- <el-select
- v-model="meetingForm.startTime"
- placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
- style="width: 100%"
- >
- <el-option
- v-for="time in timeOptions"
- :key="time.value"
- :label="time.label"
- :value="time.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃堕棿" prop="endTime">
- <el-select
- v-model="meetingForm.endTime"
- placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
- style="width: 100%"
- >
- <el-option
- v-for="time in timeOptions"
- :key="time.value"
- :label="time.label"
- :value="time.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="鍙備細浜烘暟" prop="participants">
- <el-input
- v-model="meetingForm.participants"
- type="number"
- placeholder="璇疯緭鍏ュ弬浼氫汉鏁�"
- />
- </el-form-item>
- <el-form-item label="鍙備細浜哄憳" prop="participants">
- <el-input
- v-model="meetingForm.participantList"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ弬浼氫汉鍛橈紝鐢ㄩ�楀彿鍒嗛殧"
- />
- </el-form-item>
- <el-form-item label="浼氳璇存槑">
- <el-input
- v-model="meetingForm.description"
- type="textarea"
- :rows="4"
- placeholder="璇疯緭鍏ヤ細璁鏄�"
- />
- </el-form-item>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="editDialogVisible = 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 { Plus } from '@element-plus/icons-vue'
-import Pagination from '@/components/Pagination/index.vue'
-import {getRoomEnum,getDraftList,saveDraft,delDraft} from '@/api/collaborativeApproval/meeting.js'
-import dayjs from "dayjs";
-// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 鎬绘潯鏁�
-const total = ref(0)
-
-// 鑽夌鍒楄〃鏁版嵁
-const draftList = ref([])
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- title: '',
- meetingDate: ''
-})
-
-// 鏄惁鏄剧ず瀵硅瘽妗�
-const detailDialogVisible = ref(false)
-const editDialogVisible = ref(false)
-
-const roomList = ref([])
-
-// 瀵硅瘽妗嗘爣棰�
-const dialogTitle = ref('')
-
-// 褰撳墠鏌ョ湅鐨勮崏绋�
-const currentDraft = ref(null)
-
-// 琛ㄥ崟寮曠敤
-const meetingFormRef = ref(null)
-
-// 鏃堕棿閫夐」锛堜互鍗婂皬鏃朵负闂撮殧锛屽伐浣滄椂闂�8:00-18:00锛�
-const timeOptions = ref([])
-
-// 琛ㄥ崟鏁版嵁
-const meetingForm = reactive({
- id: '',
- meetingId: '',
- title: '',
- roomId: '',
- host: '',
- meetingDate: '',
- startTime: '',
- endTime: '',
- participants: 0,
- participantList: '',
- description: '',
- createTime: ''
-})
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- title: [{ required: true, message: '璇疯緭鍏ヤ細璁富棰�', trigger: 'blur' }],
- roomId: [{ required: true, message: '璇烽�夋嫨浼氳瀹�', trigger: 'change' }],
- host: [{ required: true, message: '璇疯緭鍏ヤ富鎸佷汉', trigger: 'blur' }],
- meetingDate: [{ required: true, message: '璇烽�夋嫨浼氳鏃ユ湡', trigger: 'change' }],
- startTime: [{ required: true, message: '璇烽�夋嫨寮�濮嬫椂闂�', trigger: 'change' }],
- endTime: [{ required: true, message: '璇烽�夋嫨缁撴潫鏃堕棿', trigger: 'change' }]
-}
-
-// 鍒濆鍖栨椂闂撮�夐」锛堜互鍗婂皬鏃朵负闂撮殧锛屽伐浣滄椂闂�8:00-18:00锛�
-const initTimeOptions = () => {
- const options = []
- for (let hour = 8; hour <= 18; hour++) {
- // 姣忎釜灏忔椂娣诲姞涓や釜閫夐」锛氭暣鐐瑰拰鍗婄偣
- options.push({
- value: `${hour.toString().padStart(2, '0')}:00`,
- label: `${hour.toString().padStart(2, '0')}:00`
- })
-
- if (hour < 18) { // 18:00涔嬪悗娌℃湁鍗婄偣閫夐」
- options.push({
- value: `${hour.toString().padStart(2, '0')}:30`,
- label: `${hour.toString().padStart(2, '0')}:30`
- })
- }
- }
- timeOptions.value = options
-}
-
-// 绂佺敤鏃ユ湡锛堢鐢ㄤ粖澶╀箣鍓嶇殑鏃ユ湡锛�
-const disabledDate = (time) => {
- // 绂佺敤浠婂ぉ涔嬪墠鐨勬棩鏈�
- return time.getTime() < Date.now() - 86400000
-}
-
-// 鏌ヨ鏁版嵁
-const getList = async () => {
- loading.value = true
-
- let resp = await getDraftList({...queryParams,...searchForm})
- queryParams.current = resp.data.current
- draftList.value = resp.data.records.map(it=>{
- it.room = roomList.value.find(room=>it.roomId===room.id).name ?? ""
- it.meetingTime = `${it.meetingDate} ${dayjs(it.startTime).format("HH:mm")} ~ ${dayjs(it.endTime).format("HH:mm")}`
- return it
- })
-
- loading.value = false
-
-}
-
-// 鎼滅储鎸夐挳鎿嶄綔
-const handleSearch = () => {
- queryParams.pageNum = 1
- getList()
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- Object.assign(searchForm, {
- title: '',
- createTime: []
- })
- handleSearch()
-}
-
-// 娣诲姞鎸夐挳鎿嶄綔
-const handleAdd = () => {
- dialogTitle.value = '鏂板缓鑽夌'
- resetForm()
- editDialogVisible.value = true
-}
-
-// 鏌ョ湅鑽夌璇︽儏
-const viewDraft = (row) => {
- currentDraft.value = row
- detailDialogVisible.value = true
-}
-
-// 缂栬緫鑽夌
-const editDraft = (row) => {
- dialogTitle.value = '缂栬緫鑽夌'
- Object.assign(meetingForm, {
- id: row.id,
- meetingId: row.meetingId,
- title: row.title,
- room: row.room,
- roomId: row.id,
- host: row.host,
- meetingDate: row.meetingTime.split(' ')[0],
- startTime: row.meetingTime.split(' ')[1],
- endTime: row.meetingTime.split(' ')[3],
- participants: row.participants,
- participantList: row.participantList,
- description: row.description,
- createTime: row.createTime
- })
- editDialogVisible.value = true
-}
-
-// 鍒犻櫎鑽夌
-const deleteDraft = (row) => {
- ElMessageBox.confirm(
- `纭鍒犻櫎浼氳鑽夌 "${row.title}"?`,
- '鍒犻櫎鑽夌',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- delDraft(row.id).then(resp=>{
- ElMessage.success('鑽夌鍒犻櫎鎴愬姛')
- getList()
- })
-
- }).catch(() => {})
-}
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
- Object.assign(meetingForm, {
- id: '',
- meetingId: '',
- title: '',
- room: '',
- host: '',
- meetingDate: '',
- startTime: '',
- endTime: '',
- participants: 0,
- participantList: '',
- description: '',
- createTime: ''
- })
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- meetingFormRef.value.validate((valid) => {
- if (valid) {
- let formData = {...meetingForm}
- formData.startTime = dayjs(meetingForm.meetingDate + ' ' + meetingForm.startTime).format("YYYY-MM-DD HH:mm:ss")
- formData.endTime = dayjs(meetingForm.meetingDate + ' ' + meetingForm.endTime).format("YYYY-MM-DD HH:mm:ss")
- saveDraft(formData).then(()=>{
- ElMessage.success('淇濆瓨鎴愬姛')
- editDialogVisible.value = false
- getList()
- })
- }
- })
-}
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateTime) => {
- if (!dateTime) return ''
- return dateTime.replace(' ', '\n')
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(() => {
- initTimeOptions()
- getList()
- getRoomEnum().then((res) => {
- roomList.value = res.data
- })
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-.content-section h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.participants-list {
- min-height: 40px;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
-}
-
-.meeting-description {
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
- white-space: pre-wrap;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue b/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
deleted file mode 100644
index 0883ec3..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetExamine/index.vue
+++ /dev/null
@@ -1,418 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳瀹℃壒</h2>
- </div>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :model="searchForm" inline>
- <el-form-item label="浼氳涓婚">
- <el-input v-model="searchForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�" clearable/>
- </el-form-item>
- <el-form-item label="鐢宠浜�">
- <el-input v-model="searchForm.applicant" placeholder="璇疯緭鍏ョ敵璇蜂汉" clearable/>
- </el-form-item>
- <el-form-item label="瀹℃壒鐘舵��">
- <el-select style="width: 100px" v-model="searchForm.status" placeholder="璇烽�夋嫨瀹℃壒鐘舵��" clearable>
- <el-option label="寰呭鎵�" value="0"/>
- <el-option label="宸查�氳繃" value="1"/>
- <el-option label="鏈鎵�" value="2"/>
- <el-option label="宸插彇娑�" value="3"/>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 浼氳瀹℃壒鍒楄〃 -->
- <el-card>
- <el-table v-loading="loading" :data="approvalList" border>
- <el-table-column prop="title" label="浼氳涓婚" align="center" min-width="200" show-overflow-tooltip/>
- <el-table-column prop="applicant" label="鐢宠浜�" align="center" width="120"/>
- <el-table-column prop="host" label="涓荤悊浜�" align="center" width="120"/>
- <el-table-column prop="meetingTime" label="浼氳鏃堕棿" align="center" width="180">
- <template #default="scope">
- {{ formatDateTime(scope.row.meetingTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="location" label="浼氳鍦扮偣" align="center" width="150"/>
- <el-table-column prop="participants" label="鍙備細浜烘暟" align="center" width="100">
- <template #default="scope">
- {{ scope.row.participants.length }}浜�
- </template>
- </el-table-column>
- <el-table-column prop="status" label="瀹℃壒鐘舵��" align="center" width="120">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" align="center" width="200" fixed="right">
- <template #default="scope">
- <el-button type="primary" link @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button
- v-if="scope.row.status == '0'"
- type="primary"
- link
- @click="handleApproval(scope.row)"
- >
- 瀹℃壒
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 浼氳璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="浼氳璇︽儏"
- v-model="detailDialogVisible"
- width="800px"
- >
- <div v-if="currentMeeting">
- <el-descriptions label-width="100px" class="meeting-desc" :column="2" border>
- <el-descriptions-item label="浼氳涓婚" label-class-name="nowrap-label">{{
- currentMeeting.title
- }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�" label-class-name="nowrap-label">{{
- currentMeeting.applicant
- }}</el-descriptions-item>
- <el-descriptions-item label="涓荤悊浜�" label-class-name="nowrap-label">{{
- currentMeeting.host
- }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2" label-class-name="nowrap-label">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣" label-class-name="nowrap-label">{{
- currentMeeting.location
- }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟" label-class-name="nowrap-label">{{
- currentMeeting.participants.length
- }}浜�</el-descriptions-item>
- <el-descriptions-item label="瀹℃壒鐘舵��" label-class-name="nowrap-label">
- <el-tag :type="getStatusType(currentMeeting.status)">
- {{ getStatusText(currentMeeting.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿" label-class-name="nowrap-label">{{
- currentMeeting.createTime
- }}</el-descriptions-item>
- <el-descriptions-item style="max-height: 400px" label="浼氳璇存槑" :span="2"
- label-class-name="nowrap-label">{{ currentMeeting.description }}</el-descriptions-item>
- </el-descriptions>
-
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- <el-tag
- v-for="participant in currentMeeting.participants"
- :key="participant.id"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ participant.name }}
- </el-tag>
- </div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浼氳瀹℃壒瀵硅瘽妗� -->
- <el-dialog
- title="浼氳瀹℃壒"
- v-model="approvalDialogVisible"
- >
- <div v-if="currentMeeting">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浼氳涓婚">{{ currentMeeting.title }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentMeeting.applicant }}</el-descriptions-item>
- <el-descriptions-item label="涓荤悊浜�">{{ currentMeeting.host }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣">{{ currentMeeting.location }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟">{{ currentMeeting.participants.length }}浜�</el-descriptions-item>
- </el-descriptions>
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- <el-tag
- v-for="participant in currentMeeting.participants"
- :key="participant.id"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ participant.name }}
- </el-tag>
- </div>
- </div>
-
- <div v-show="false" class="approval-opinion mt-20">
- <h4>瀹℃壒鎰忚</h4>
- <el-input
- v-model="approvalOpinion"
- type="textarea"
- placeholder="璇疯緭鍏ュ鎵规剰瑙�"
- :rows="4"
- />
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="approvalDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="danger" @click="submitApproval('2')">涓嶉�氳繃</el-button>
- <el-button type="primary" @click="submitApproval('1')">閫� 杩�</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/Pagination/index.vue'
-import {getRoomEnum, getExamineList,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
-import dayjs from "dayjs";
-
-// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 鎬绘潯鏁�
-const total = ref(0)
-const roomEnum = ref([])
-const staffList = ref([])
-// 瀹℃壒鍒楄〃鏁版嵁
-const approvalList = ref([])
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- title: '',
- applicant: '',
- status: ''
-})
-
-// 鏄惁鏄剧ず瀵硅瘽妗�
-const detailDialogVisible = ref(false)
-const approvalDialogVisible = ref(false)
-
-// 褰撳墠鏌ョ湅鐨勪細璁�
-const currentMeeting = ref(null)
-
-// 瀹℃壒鎰忚
-const approvalOpinion = ref('')
-
-// 鏌ヨ鏁版嵁
-const getList = async () => {
- loading.value = true
- let resp = await getExamineList({...searchForm, ...queryParams})
- approvalList.value = resp.data.records.map(it => {
- let room = roomEnum.value.find(room => it.roomId === room.id)
- it.location = `${room.name}(${room.location})`
- let staffs = JSON.parse(it.participants)
- it.staffCount = staffs.size
- it.meetingTime = `${it.meetingDate} ${dayjs(it.startTime).format('HH:mm:ss')} ~ ${dayjs(it.endTime).format('HH:mm:ss')}`
- it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
- return {
- id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
- }
- })
-
-
- return it
- })
- total.value = resp.data.total
- loading.value = false
-}
-
-// 鎼滅储鎸夐挳鎿嶄綔
-const handleSearch = () => {
- queryParams.pageNum = 1
- getList()
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- Object.assign(searchForm, {
- title: '',
- applicant: '',
- status: ''
- })
- handleSearch()
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetail = (row) => {
- currentMeeting.value = row
- detailDialogVisible.value = true
-}
-
-// 澶勭悊瀹℃壒
-const handleApproval = (row) => {
- currentMeeting.value = row
- approvalOpinion.value = ''
- approvalDialogVisible.value = true
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- '0': 'info', // 寰呭鎵�
- '1': 'success', // 宸查�氳繃
- '2': 'warning', // 鏈�氳繃
- '3': 'danger' // 鍙栨秷
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- '0': '寰呭鎵�',
- '1': '宸查�氳繃',
- '2': '鏈�氳繃',
- '3': '宸插彇娑�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateTime) => {
- if (!dateTime) return ''
- return dateTime.replace(' ', '\n')
-}
-
-// 鎻愪氦瀹℃壒
-const submitApproval = (status) => {
- // if (status === 'approved' && !approvalOpinion.value.trim()) {
- // ElMessage.warning('璇峰~鍐欏鎵规剰瑙�')
- // return
- // }
-
- ElMessageBox.confirm(
- `纭${status === '1' ? '閫氳繃' : '涓嶉�氳繃'}璇ヤ細璁敵璇凤紵`,
- '瀹℃壒纭',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- saveMeetingApplication({
- id: currentMeeting.value.id,
- status: status
- }).then(resp=>{
- // 鏇存柊浼氳鐘舵��
- currentMeeting.value.status = status
-
- ElMessage.success('瀹℃壒鎻愪氦鎴愬姛')
- approvalDialogVisible.value = false
- getList()
- })
-
- }).catch(() => {
- })
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(async () => {
- const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
- roomEnum.value = resp1.data
- staffList.value = resp2.data
-
- await getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-.content-section h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.participants-list {
- min-height: 40px;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
-}
-
-.approval-opinion h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.nowrap-label {
- white-space: nowrap !important;
-}
-
-.description-content {
- white-space: pre-wrap;
- word-wrap: break-word;
- line-height: 1.6;
- padding: 10px;
- background-color: #f5f7fa;
- border-radius: 4px;
- min-height: 60px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue b/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue
deleted file mode 100644
index 2e9d9a9..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue
+++ /dev/null
@@ -1,371 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳瀹や娇鐢ㄦ煡璇�</h2>
- </div>
-
- <!-- 鏌ヨ鏉′欢 -->
- <el-card class="search-card">
- <el-form :model="queryForm" label-width="80px" inline>
- <el-form-item label="鏌ヨ鏃ユ湡">
- <el-date-picker
- v-model="queryForm.meetingDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- :clearable="false"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 浼氳瀹や娇鐢ㄦ儏鍐� -->
- <el-card class="table-container" :loading="loading">
- <div class="time-table">
- <!-- 琛ㄥご -->
- <div class="table-header">
- <div class="header-cell room-header">浼氳瀹�</div>
- <div
- v-for="timeSlot in timeSlots"
- :key="timeSlot.value"
- class="header-cell time-header"
- >
- {{ timeSlot.label }}
- </div>
- </div>
-
- <!-- 琛ㄦ牸鍐呭 -->
- <div class="table-body">
- <div
- v-for="room in roomUsage"
- :key="room.id"
- class="table-row"
- >
- <div class="cell room-cell">{{ room.name }}</div>
- <div class="cells-container">
- <template v-for="(cell, index) in generateMeetingCells(room)" :key="index">
- <div
- class="cell content-cell"
- :class="[cell.type, `status-${cell.meeting?.status || '0'}`]"
- :style="{ flex: cell.span-0.2 }"
- @click="viewMeetingDetails(cell)"
- >
- <div v-if="cell.type === 'meeting'" class="meeting-content">
- <div class="meeting-title">{{ cell.meeting.title }}</div>
- <div class="meeting-time">{{ cell.startTime }}-{{ cell.endTime }}</div>
- </div>
- <div v-else class="free-content">
- 绌洪棽
- </div>
- </div>
- </template>
- </div>
- </div>
- </div>
- </div>
- </el-card>
-
- <!-- 浼氳璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="浼氳璇︽儏"
- v-model="detailDialogVisible"
- width="800px"
- >
- <div v-if="currentMeeting">
- <el-descriptions :column="1" border>
- <el-descriptions-item label="浼氳涓婚">{{ currentMeeting.title }}</el-descriptions-item>
- <el-descriptions-item label="浼氳瀹�">{{ currentMeeting.room }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿">{{ currentMeeting.time }}</el-descriptions-item>
- <el-descriptions-item label="涓绘寔浜�">{{ currentMeeting.host }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟">{{ currentMeeting.participants }}浜�</el-descriptions-item>
- <el-descriptions-item label="浼氳璇存槑">{{ currentMeeting.description }}</el-descriptions-item>
- </el-descriptions>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, onMounted} from 'vue'
-import {ElMessage} from 'element-plus'
-import {getMeetingUseList} from "@/api/collaborativeApproval/meeting.js"
-import dayjs from "dayjs";
-
-// 鏌ヨ琛ㄥ崟
-const queryForm = reactive({
- meetingDate: dayjs().format('YYYY-MM-DD')
-})
-let loading = ref(false)
-// 鏃堕棿娈碉紙浠ュ崐灏忔椂涓洪棿闅旓級
-const timeSlots = ref([])
-
-// 浼氳瀹や娇鐢ㄦ儏鍐�
-const roomUsage = ref([])
-
-// 褰撳墠鏌ョ湅鐨勪細璁�
-const currentMeeting = ref(null)
-
-// 鏄惁鏄剧ず璇︽儏瀵硅瘽妗�
-const detailDialogVisible = ref(false)
-
-// 鍒濆鍖栨椂闂存Ы锛堜互鍗婂皬鏃朵负闂撮殧锛屼粠8:00鍒�18:00锛�
-const initTimeSlots = () => {
- const slots = []
- for (let hour = 8; hour < 18; hour++) {
- // 姣忎釜灏忔椂娣诲姞涓や釜鏃堕棿娈碉細鏁寸偣鍜屽崐鐐�
- slots.push({
- label: `${hour.toString().padStart(2, '0')}:00`,
- value: `${hour.toString().padStart(2, '0')}:00`
- })
-
- if (hour < 18) { // 鍒�17:30涓烘
- slots.push({
- label: `${hour.toString().padStart(2, '0')}:30`,
- value: `${hour.toString().padStart(2, '0')}:30`
- })
- }
- }
- timeSlots.value = slots
-}
-
-// 鐢熸垚浼氳瀹ょ殑鏃堕棿鍗曞厓鏍�
-const generateMeetingCells = (room) => {
- const cells = []
- const meetings = room.meetings || []
- const occupiedSlots = new Set()
-
- // 澶勭悊姣忎釜浼氳
- for (const meeting of meetings) {
-
- const startIdx = timeSlots.value.findIndex(slot => slot.value === meeting.startTime)
- let endIdx = timeSlots.value.findIndex(slot => slot.value === meeting.endTime)
- if (endIdx === -1) {
- endIdx = timeSlots.value.length
- }
- console.log('endIdx111', endIdx)
- if (startIdx !== -1 && endIdx !== -1) {
- // 鏍囪琚崰鐢ㄧ殑鏃堕棿娈�
- for (let i = startIdx; i < endIdx; i++) {
- occupiedSlots.add(timeSlots.value[i].value)
- }
-
- // 鍒涘缓浼氳鍗曞厓鏍�
- cells.push({
- type: 'meeting',
- meeting: meeting,
- span: endIdx - startIdx,
- startTime: meeting.startTime,
- endTime: meeting.endTime
- })
- }
- }
-
- // 澶勭悊绌洪棽鏃堕棿娈�
- for (let i = 0; i < timeSlots.value.length; i++) {
- const slot = timeSlots.value[i]
- if (!occupiedSlots.has(slot.value)) {
- // 鏌ユ壘杩炵画鐨勭┖闂叉椂闂存
- let span = 1
- while (i + span < timeSlots.value.length &&
- !occupiedSlots.has(timeSlots.value[i + span].value)) {
- occupiedSlots.add(timeSlots.value[i + span].value)
- span++
- }
-
- cells.push({
- type: 'free',
- span: span,
- time: slot.value
- })
- }
- }
-
- // 鎸夋椂闂存帓搴�
- cells.sort((a, b) => {
- const timeA = a.startTime || a.time
- const timeB = b.startTime || b.time
- return timeSlots.value.findIndex(s => s.value === timeA) -
- timeSlots.value.findIndex(s => s.value === timeB)
- })
- console.log('cells', cells)
- return cells
-}
-
-// 鏌ョ湅浼氳璇︽儏
-const viewMeetingDetails = (cell) => {
- if (cell && cell.type === 'meeting') {
- currentMeeting.value = cell.meeting
- detailDialogVisible.value = true
- } else {
- ElMessage.info('璇ユ椂闂存浼氳瀹ょ┖闂�')
- }
-}
-
-// 鏌ヨ鎸夐挳鎿嶄綔
-const handleSearch = async () => {
- loading.value = true
- let resp = await getMeetingUseList({...queryForm})
- roomUsage.value = resp.data
- loading.value = false
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- queryForm.date = dayjs().format('YYYY-MM-DD')
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(() => {
- // 鍒濆鍖栨椂闂存Ы
- initTimeSlots()
-
- // 榛樿鏌ヨ浠婂ぉ鐨勬暟鎹�
- const today = new Date()
- queryForm.date = today.toISOString().split('T')[0]
- handleSearch()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.table-container {
- padding: 0;
-}
-
-.time-table {
- width: 100%;
- border-collapse: collapse;
-}
-
-.table-header {
- display: flex;
- border: 1px solid;
-}
-
-.table-row {
- display: flex;
- border: 1px solid #ebeef5;
- border-top: none;
-}
-
-.header-cell {
- padding: 12px 5px;
- text-align: center;
- font-weight: bold;
- border-right: 1px solid;
- min-height: 20px;
-}
-
-.room-header {
- width: 120px;
-}
-
-.time-header {
- flex: 1;
-}
-
-.cell {
- padding: 15px 5px;
- text-align: center;
- border-right: 1px solid;
- min-height: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
- word-break: break-word;
- line-height: 1.2;
-}
-
-.room-cell {
- width: 120px;
- font-weight: bold;
-}
-
-.cells-container {
- flex: 1;
- display: flex;
-}
-
-.content-cell {
- min-height: 60px;
- cursor: pointer;
- transition: all 0.3s;
-}
-
-.content-cell:hover {
- opacity: 0.8;
-}
-
-.free {
- color: #f56c6c;
-}
-
-.meeting {
- display: flex;
- flex-direction: column;
- justify-content: center;
-}
-
-.status-1 {
- background-color: #fef0f0;
- color: #d14646;
-}
-
-.status-0 {
- background-color: #c7ddc8;
- color: rgba(230, 162, 60, 0.29);
-}
-
-.meeting-content {
- width: 100%;
-}
-
-.meeting-title {
- font-weight: bold;
- margin-bottom: 5px;
-}
-
-.meeting-time {
- font-size: 12px;
-}
-
-.free-content {
- color: #909399;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue b/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
deleted file mode 100644
index 3f0fc69..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
+++ /dev/null
@@ -1,416 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳鍙戝竷</h2>
- </div>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :model="searchForm" inline>
- <el-form-item label="浼氳涓婚">
- <el-input v-model="searchForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�" clearable/>
- </el-form-item>
- <el-form-item label="鐢宠浜�">
- <el-input v-model="searchForm.applicant" placeholder="璇疯緭鍏ョ敵璇蜂汉" clearable/>
- </el-form-item>
- <el-form-item label="鍙戝竷鐘舵��">
- <el-select style="width: 100px" v-model="searchForm.status" placeholder="璇烽�夋嫨鍙戝竷鐘舵��" clearable>
- <el-option label="寰呭彂甯�" value="0"/>
- <el-option label="宸插彂甯�" value="1"/>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 浼氳鍙戝竷鍒楄〃 -->
- <el-card>
- <el-table v-loading="loading" :data="approvalList" border>
- <el-table-column prop="title" label="浼氳涓婚" align="center" min-width="200" show-overflow-tooltip/>
- <el-table-column prop="applicant" label="鐢宠浜�" align="center" width="120"/>
- <el-table-column prop="host" label="涓荤悊浜�" align="center" width="120"/>
- <el-table-column prop="meetingTime" label="浼氳鏃堕棿" align="center" width="180">
- <template #default="scope">
- {{ formatDateTime(scope.row.meetingTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="location" label="浼氳鍦扮偣" align="center" width="150"/>
- <el-table-column prop="participants" label="鍙備細浜烘暟" align="center" width="100">
- <template #default="scope">
- {{ scope.row.participants.length }}浜�
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鍙戝竷鐘舵��" align="center" width="120">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" align="center" width="200" fixed="right">
- <template #default="scope">
- <el-button type="primary" link @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button
- v-if="scope.row.status == '0'"
- type="primary"
- link
- @click="handleApproval(scope.row)"
- >
- 鍙戝竷
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 浼氳璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="浼氳璇︽儏"
- v-model="detailDialogVisible"
- width="800px"
- >
- <div v-if="currentMeeting">
- <el-descriptions label-width="100px" class="meeting-desc" :column="2" border>
- <el-descriptions-item label="浼氳涓婚" label-class-name="nowrap-label">{{
- currentMeeting.title
- }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�" label-class-name="nowrap-label">{{
- currentMeeting.applicant
- }}</el-descriptions-item>
- <el-descriptions-item label="涓荤悊浜�" label-class-name="nowrap-label">{{
- currentMeeting.host
- }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2" label-class-name="nowrap-label">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣" label-class-name="nowrap-label">{{
- currentMeeting.location
- }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟" label-class-name="nowrap-label">{{
- currentMeeting.participants.length
- }}浜�</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鐘舵��" label-class-name="nowrap-label">
- <el-tag :type="getStatusType(currentMeeting.status)">
- {{ getStatusText(currentMeeting.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿" label-class-name="nowrap-label">{{
- currentMeeting.createTime
- }}</el-descriptions-item>
- <el-descriptions-item style="max-height: 400px" label="浼氳璇存槑" :span="2"
- label-class-name="nowrap-label">{{ currentMeeting.description }}</el-descriptions-item>
- </el-descriptions>
-
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- <el-tag
- v-for="participant in currentMeeting.participants"
- :key="participant.id"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ participant.name }}
- </el-tag>
- </div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浼氳鍙戝竷瀵硅瘽妗� -->
- <el-dialog
- title="浼氳鍙戝竷"
- v-model="approvalDialogVisible"
- >
- <div v-if="currentMeeting">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浼氳涓婚">{{ currentMeeting.title }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentMeeting.applicant }}</el-descriptions-item>
- <el-descriptions-item label="涓荤悊浜�">{{ currentMeeting.host }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣">{{ currentMeeting.location }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟">{{ currentMeeting.participants.length }}浜�</el-descriptions-item>
- </el-descriptions>
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- <el-tag
- v-for="participant in currentMeeting.participants"
- :key="participant.id"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ participant.name }}
- </el-tag>
- </div>
- </div>
-
- <div class="approval-opinion mt-20">
- <h4>鍙戝竷鎰忚</h4>
- <el-input
- v-model="publishComment"
- type="textarea"
- placeholder="璇疯緭鍏ュ彂甯冩剰瑙�"
- :rows="4"
- />
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="approvalDialogVisible = false">鍙� 娑�</el-button>
-<!-- <el-button type="danger" @click="submitApproval('2')">涓嶉�氳繃</el-button>-->
- <el-button type="primary" @click="submitApproval('1')">鍙� 甯�</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/Pagination/index.vue'
-import {getRoomEnum, getMeetingPublish,saveMeetingApplication} from '@/api/collaborativeApproval/meeting.js'
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
-import dayjs from "dayjs";
-
-// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 鎬绘潯鏁�
-const total = ref(0)
-const roomEnum = ref([])
-const staffList = ref([])
-// 鍙戝竷鍒楄〃鏁版嵁
-const approvalList = ref([])
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- title: '',
- applicant: '',
- status: ''
-})
-
-// 鏄惁鏄剧ず瀵硅瘽妗�
-const detailDialogVisible = ref(false)
-const approvalDialogVisible = ref(false)
-
-// 褰撳墠鏌ョ湅鐨勪細璁�
-const currentMeeting = ref(null)
-
-// 鍙戝竷鎰忚
-const publishComment = ref('')
-
-// 鏌ヨ鏁版嵁
-const getList = async () => {
- loading.value = true
- let resp = await getMeetingPublish({...searchForm, ...queryParams})
- approvalList.value = resp.data.records.map(it => {
- let room = roomEnum.value.find(room => it.roomId === room.id)
- it.location = `${room.name}(${room.location})`
- let staffs = JSON.parse(it.participants)
- it.staffCount = staffs.size
- it.status = it.publishStatus
- it.meetingTime = `${it.meetingDate} ${dayjs(it.startTime).format('HH:mm:ss')} ~ ${dayjs(it.endTime).format('HH:mm:ss')}`
- it.participants = staffList.value.filter(staff => staffs.some(id=>id === staff.id)).map(staff => {
- return {
- id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
- }
- })
-
-
- return it
- })
- total.value = resp.data.total
- loading.value = false
-}
-
-// 鎼滅储鎸夐挳鎿嶄綔
-const handleSearch = () => {
- queryParams.pageNum = 1
- getList()
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- Object.assign(searchForm, {
- title: '',
- applicant: '',
- status: ''
- })
- handleSearch()
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetail = (row) => {
- currentMeeting.value = row
- detailDialogVisible.value = true
-}
-
-// 澶勭悊鍙戝竷
-const handleApproval = (row) => {
- currentMeeting.value = row
- publishComment.value = ''
- approvalDialogVisible.value = true
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- '0': 'info', // 寰呭彂甯�
- '1': 'success', // 宸查�氳繃
- '2': 'danger', // 鏈�氳繃
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- '0': '寰呭彂甯�',
- '1': '宸插彂甯�',
- '2': '宸插彇娑�',
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateTime) => {
- if (!dateTime) return ''
- return dateTime.replace(' ', '\n')
-}
-
-// 鎻愪氦鍙戝竷
-const submitApproval = (status) => {
- // if (status === 'approved' && !publishComment.value.trim()) {
- // ElMessage.warning('璇峰~鍐欏彂甯冩剰瑙�')
- // return
- // }
-
- ElMessageBox.confirm(
- `纭${status === '1' ? '鍙戝竷' : '鍙栨秷'}璇ヤ細璁紵`,
- '鍙戝竷纭',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- saveMeetingApplication({
- id: currentMeeting.value.id,
- publishStatus: status,
- publishComment: publishComment.value
- }).then(resp=>{
- // 鏇存柊浼氳鐘舵��
- currentMeeting.value.status = status
-
- ElMessage.success('鍙戝竷鎻愪氦鎴愬姛')
- approvalDialogVisible.value = false
- getList()
- })
-
- }).catch(() => {
- })
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(async () => {
- const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
- roomEnum.value = resp1.data
- staffList.value = resp2.data
-
- await getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-.content-section h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.participants-list {
- min-height: 40px;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
-}
-
-.approval-opinion h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.nowrap-label {
- white-space: nowrap !important;
-}
-
-.description-content {
- white-space: pre-wrap;
- word-wrap: break-word;
- line-height: 1.6;
- padding: 10px;
- background-color: #f5f7fa;
- border-radius: 4px;
- min-height: 60px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/meetSetting/index.vue b/src/views/collaborativeApproval/notificationManagement/meetSetting/index.vue
deleted file mode 100644
index 371bde7..0000000
--- a/src/views/collaborativeApproval/notificationManagement/meetSetting/index.vue
+++ /dev/null
@@ -1,315 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳瀹よ缃�</h2>
- <div>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="handleAdd">
- <el-icon><Plus /></el-icon>
- 鏂板浼氳瀹�
- </el-button>
- </div>
- </div>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :model="searchForm" label-width="100px" inline>
- <el-form-item label="浼氳瀹ゅ悕绉�">
- <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ヤ細璁鍚嶇О" clearable />
- </el-form-item>
- <el-form-item label="浣嶇疆">
- <el-input v-model="searchForm.location" placeholder="璇疯緭鍏ヤ綅缃�" clearable />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 浼氳瀹ゅ垪琛� -->
- <el-card>
- <el-table v-loading="loading" :data="meetingRoomList" border>
- <el-table-column prop="name" label="浼氳瀹ゅ悕绉�" align="center" />
- <el-table-column prop="location" label="浣嶇疆" align="center" />
- <el-table-column prop="capacity" label="瀹圭撼浜烘暟" align="center" />
- <el-table-column prop="equipment" label="璁惧閰嶇疆" align="center">
- <template #default="scope">
- <el-tag v-for="item in scope.row.equipment" :key="item" style="margin-right: 5px; margin-bottom: 5px;">
- {{ item }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" align="center" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
- {{ scope.row.status === 1 ? '鍚敤' : '绂佺敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" align="center" width="200">
- <template #default="scope">
- <el-button type="primary" link @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button type="danger" link @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 娣诲姞/缂栬緫瀵硅瘽妗� -->
- <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px" @close="cancel">
- <el-form ref="meetingRoomFormRef" :model="meetingRoomForm" :rules="rules" label-width="100px">
- <el-form-item label="浼氳瀹ゅ悕绉�" prop="name">
- <el-input v-model="meetingRoomForm.name" placeholder="璇疯緭鍏ヤ細璁鍚嶇О" />
- </el-form-item>
- <el-form-item label="浣嶇疆" prop="location">
- <el-input v-model="meetingRoomForm.location" placeholder="璇疯緭鍏ヤ細璁浣嶇疆" />
- </el-form-item>
- <el-form-item label="瀹圭撼浜烘暟" prop="capacity">
- <el-input-number v-model="meetingRoomForm.capacity" :min="1" placeholder="璇疯緭鍏ュ绾充汉鏁�" />
- </el-form-item>
- <el-form-item label="璁惧閰嶇疆" prop="equipment">
- <el-select v-model="meetingRoomForm.equipment" multiple placeholder="璇烽�夋嫨璁惧閰嶇疆" style="width: 100%">
- <el-option
- v-for="item in equipmentOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-radio-group v-model="meetingRoomForm.status">
- <el-radio :label="1">鍚敤</el-radio>
- <el-radio :label="0">绂佺敤</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="澶囨敞" prop="remark">
- <el-input v-model="meetingRoomForm.remark" type="textarea" placeholder="璇疯緭鍏ュ娉�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancel">鍙� 娑�</el-button>
- <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus } from '@element-plus/icons-vue'
-import Pagination from '@/components/Pagination/index.vue'
-import {getMeetingRoomList,saveRoom,delRoom} from '@/api/collaborativeApproval/meeting.js'
-
-// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 鎬绘潯鏁�
-const total = ref(0)
-
-// 浼氳瀹ゅ垪琛ㄦ暟鎹�
-const meetingRoomList = ref([])
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- name: '',
- location: ''
-})
-
-// 瀵硅瘽妗嗘爣棰�
-const dialogTitle = ref('')
-
-// 鏄惁鏄剧ず瀵硅瘽妗�
-const dialogVisible = ref(false)
-
-// 璁惧閰嶇疆閫夐」
-const equipmentOptions = ref([
- { value: '鎶曞奖浠�', label: '鎶曞奖浠�' },
- { value: '鐢佃', label: '鐢佃' },
- { value: '闊冲搷', label: '闊冲搷' },
- { value: '鐢佃瘽', label: '鐢佃瘽' },
- { value: '瑙嗛浼氳绯荤粺', label: '瑙嗛浼氳绯荤粺' },
- { value: '鐧芥澘', label: '鐧芥澘' },
- { value: '鍐欏瓧鏉�', label: '鍐欏瓧鏉�' },
- { value: '鏃犵嚎缃戠粶', label: '鏃犵嚎缃戠粶' }
-])
-
-// 琛ㄥ崟鏁版嵁
-const meetingRoomForm = reactive({
- id: undefined,
- name: '',
- location: '',
- capacity: 10,
- equipment: [],
- status: 1,
- remark: ''
-})
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- name: [{ required: true, message: '浼氳瀹ゅ悕绉颁笉鑳戒负绌�', trigger: 'blur' }],
- location: [{ required: true, message: '浣嶇疆涓嶈兘涓虹┖', trigger: 'blur' }],
- capacity: [{ required: true, message: '瀹圭撼浜烘暟涓嶈兘涓虹┖', trigger: 'blur' }]
-}
-
-// 琛ㄥ崟寮曠敤
-const meetingRoomFormRef = ref(null)
-
-// 鏌ヨ鏁版嵁
-const getList = async () => {
- loading.value = true
-
- let resp = await getMeetingRoomList({...searchForm,...queryParams})
- meetingRoomList.value = resp.data.records.map(it=>{
- it.equipment = it.equipment.split(',')
- return it;
- })
- total.value = resp.data.total
- loading.value = false
-
-}
-
-// 鎼滅储鎸夐挳鎿嶄綔
-const handleSearch = () => {
- queryParams.current = 1
- getList()
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- Object.assign(searchForm, {
- name: '',
- location: ''
- })
- handleSearch()
-}
-
-// 娣诲姞鎸夐挳鎿嶄綔
-const handleAdd = () => {
- dialogTitle.value = '娣诲姞浼氳瀹�'
- dialogVisible.value = true
-}
-
-// 淇敼鎸夐挳鎿嶄綔
-const handleEdit = (row) => {
- dialogTitle.value = '淇敼浼氳瀹�'
- Object.assign(meetingRoomForm, row)
- dialogVisible.value = true
-}
-
-// 鍒犻櫎鎸夐挳鎿嶄綔
-const handleDelete = (row) => {
- ElMessageBox.confirm(
- `鏄惁纭鍒犻櫎浼氳瀹� "${row.name}"?`,
- '璀﹀憡',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- // 妯℃嫙鍒犻櫎鎿嶄綔
- delRoom(row.id).then(resp=>{
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- })
-
- }).catch(() => {})
-}
-
-// 鍙栨秷鎸夐挳
-const cancel = () => {
- dialogVisible.value = false
- reset()
-}
-
-// 琛ㄥ崟閲嶇疆
-const reset = () => {
- Object.assign(meetingRoomForm, {
- id: undefined,
- name: '',
- location: '',
- capacity: 10,
- equipment: [],
- status: 1,
- remark: ''
- })
- meetingRoomFormRef.value?.resetFields()
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- meetingRoomFormRef.value?.validate((valid) => {
- if (valid) {
- // 妯℃嫙鎻愪氦鎿嶄綔
-
- let formData = {... meetingRoomForm}
- formData.equipment = formData.equipment.join(',')
- saveRoom(formData).then(resp=>{
- ElMessage.success('淇濆瓨鎴愬姛')
- dialogVisible.value = false
- getList()
- })
- }
- })
-}
-
-// 瀵煎嚭
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
- proxy.download('/meeting/export', { ...searchForm }, '浼氳瀹よ缃�.xlsx')
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(() => {
- getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/summary/index.vue b/src/views/collaborativeApproval/notificationManagement/summary/index.vue
deleted file mode 100644
index 04eaa4a..0000000
--- a/src/views/collaborativeApproval/notificationManagement/summary/index.vue
+++ /dev/null
@@ -1,403 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>浼氳绾</h2>
- </div>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :model="searchForm" inline>
- <el-form-item label="浼氳涓婚">
- <el-input v-model="searchForm.title" placeholder="璇疯緭鍏ヤ細璁富棰�" clearable />
- </el-form-item>
- <el-form-item label="鐢宠浜�">
- <el-input v-model="searchForm.applicant" placeholder="璇疯緭鍏ョ敵璇蜂汉" clearable />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 浼氳鍒楄〃 -->
- <el-card>
- <el-table v-loading="loading" :data="meetingList" border>
- <el-table-column prop="title" label="浼氳涓婚" align="center" min-width="200" show-overflow-tooltip />
- <el-table-column prop="applicant" label="鐢宠浜�" align="center" width="120" />
- <el-table-column prop="host" label="涓绘寔浜�" align="center" width="120" />
- <el-table-column prop="meetingTime" label="浼氳鏃堕棿" align="center" width="180">
- <template #default="scope">
- {{ formatDateTime(scope.row.meetingTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="location" label="浼氳鍦扮偣" align="center" width="150" />
- <el-table-column prop="participants" label="鍙備細浜烘暟" align="center" width="100">
- <template #default="scope">
- {{ scope.row.participants.length }}浜�
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" align="center" width="200" fixed="right">
- <template #default="scope">
- <el-button type="primary" link @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button
- type="primary"
- link
- @click="addMinutes(scope.row)"
- >
- 娣诲姞绾
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 浼氳璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="浼氳璇︽儏"
- v-model="detailDialogVisible"
- width="800px"
- >
- <div v-if="currentMeeting">
- <el-descriptions label-width="100px" class="meeting-desc" :column="2" border>
- <el-descriptions-item label="浼氳涓婚" label-class-name="nowrap-label">{{
- currentMeeting.title
- }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�" label-class-name="nowrap-label">{{
- currentMeeting.applicant
- }}</el-descriptions-item>
- <el-descriptions-item label="涓绘寔浜�" label-class-name="nowrap-label">{{
- currentMeeting.host
- }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2" label-class-name="nowrap-label">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣" label-class-name="nowrap-label">{{
- currentMeeting.location
- }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟" label-class-name="nowrap-label">{{
- currentMeeting.participants.length
- }}浜�</el-descriptions-item>
- <el-descriptions-item label="瀹℃壒鐘舵��" label-class-name="nowrap-label">
- <el-tag :type="getStatusType(currentMeeting.status)">
- {{ getStatusText(currentMeeting.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿" label-class-name="nowrap-label">{{
- currentMeeting.createTime
- }}</el-descriptions-item>
- <el-descriptions-item style="max-height: 400px" label="浼氳璇存槑" :span="2"
- label-class-name="nowrap-label">{{ currentMeeting.description }}</el-descriptions-item>
- </el-descriptions>
-
- <div class="content-section mt-20">
- <h4>鍙備細浜哄憳</h4>
- <div class="participants-list">
- <el-tag
- v-for="participant in currentMeeting.participants"
- :key="participant.id"
- style="margin-right: 10px; margin-bottom: 10px;"
- >
- {{ participant.name }}
- </el-tag>
- </div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 娣诲姞浼氳绾瀵硅瘽妗� -->
- <el-dialog
- title="娣诲姞浼氳绾"
- v-model="minutesDialogVisible"
- width="80%"
- @close="handleCloseMinutesDialog"
- >
- <div v-if="currentMeeting">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浼氳涓婚">{{ currentMeeting.title }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentMeeting.applicant }}</el-descriptions-item>
- <el-descriptions-item label="涓绘寔浜�">{{ currentMeeting.host }}</el-descriptions-item>
- <el-descriptions-item label="浼氳鏃堕棿" :span="2">
- {{ formatDateTime(currentMeeting.meetingTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="浼氳鍦扮偣">{{ currentMeeting.location }}</el-descriptions-item>
- <el-descriptions-item label="鍙備細浜烘暟">{{ currentMeeting.participants.length }}浜�</el-descriptions-item>
- </el-descriptions>
-
- <div class="content-section mt-20">
- <h4>浼氳绾鍐呭</h4>
- <div class="editor-container">
- <Editor
- v-model="minutesContent"
- :min-height="400"
- />
- </div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="minutesDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="submitMinutes">淇� 瀛�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage } from 'element-plus'
-import Pagination from '@/components/Pagination/index.vue'
-import Editor from '@/components/Editor/index.vue'
-import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js'
-import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js"
-import dayjs from "dayjs"
-
-// 鏁版嵁鍒楄〃鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 鎬绘潯鏁�
-const total = ref(0)
-const roomEnum = ref([])
-const staffList = ref([])
-
-// 浼氳鍒楄〃鏁版嵁
-const meetingList = ref([])
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- title: '',
- applicant: '',
- // status: '1' // 榛樿鍙樉绀哄凡閫氳繃瀹℃壒鐨勪細璁�
-})
-
-// 鏄惁鏄剧ず瀵硅瘽妗�
-const detailDialogVisible = ref(false)
-const minutesDialogVisible = ref(false)
-
-// 褰撳墠鏌ョ湅鐨勪細璁�
-const currentMeeting = ref(null)
-
-// 浼氳绾鍐呭
-const minutesContent = ref('')
-const minutesContentId = ref('')
-
-// 鏌ヨ鏁版嵁
-const getList = async () => {
- loading.value = true
- let resp = await getMeetingPublish({ ...searchForm, ...queryParams })
- meetingList.value = resp.data.records.map(it => {
- let room = roomEnum.value.find(room => it.roomId === room.id)
- it.location = `${room.name}(${room.location})`
- let staffs = JSON.parse(it.participants)
- it.staffCount = staffs.size
- it.meetingTime = `${it.meetingDate} ${dayjs(it.startTime).format('HH:mm:ss')} ~ ${dayjs(it.endTime).format('HH:mm:ss')}`
- it.participants = staffList.value.filter(staff => staffs.some(id => id === staff.id)).map(staff => {
- return {
- id: staff.id,
- name: `${staff.staffName}(${staff.postJob})`
- }
- })
-
- return it
- })
- total.value = resp.data.total
- loading.value = false
-}
-
-// 鎼滅储鎸夐挳鎿嶄綔
-const handleSearch = () => {
- queryParams.current = 1
- getList()
-}
-
-// 閲嶇疆鎼滅储琛ㄥ崟
-const resetSearch = () => {
- Object.assign(searchForm, {
- title: '',
- applicant: '',
- // status: '1'
- })
- handleSearch()
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetail = (row) => {
- currentMeeting.value = row
- detailDialogVisible.value = true
-}
-
-// 娣诲姞浼氳绾
-const addMinutes = async (row) => {
- let resp = await getMeetingMinutesByMeetingId(row.id)
- currentMeeting.value = row
- if (resp.data){
- minutesContent.value = resp.data.content
- minutesContentId.value = resp.data.id
- }else {
- minutesContent.value = `<h2>${row.title}浼氳绾</h2>
-<p><strong>浼氳鏃堕棿锛�</strong>${row.meetingTime}</p>
-<p><strong>浼氳鍦扮偣锛�</strong>${row.location}</p>
-<p><strong>涓绘寔浜猴細</strong>${row.host}</p>
-<p><strong>鍙備細浜哄憳锛�</strong></p>
-<ol>
- ${row.participants.map(p => `<li>${p.name}</li>`).join('')}
-</ol>
-<p><strong>浼氳鍐呭锛�</strong></p>
-<ol>
- <li>璁涓�锛�
- <ul>
- <li>璁ㄨ鍐呭锛�</li>
- <li>鍐宠浜嬮」锛�</li>
- </ul>
- </li>
- <li>璁浜岋細
- <ul>
- <li>璁ㄨ鍐呭锛�</li>
- <li>鍐宠浜嬮」锛�</li>
- </ul>
- </li>
-</ol>
-<p><strong>澶囨敞锛�</strong></p>`
- }
-
- minutesDialogVisible.value = true
-}
-
-// 鎻愪氦浼氳绾
-const submitMinutes = () => {
- if (!minutesContent.value) {
- ElMessage.warning('璇疯緭鍏ヤ細璁邯瑕佸唴瀹�')
- return
- }
- saveMeetingMinutes({
- id: minutesContentId.value,
- content: minutesContent.value,
- meetingId: currentMeeting.value.id,
- title: currentMeeting.value.title
- }).then(resp=>{
- console.log('浼氳绾鍐呭:', minutesContent.value)
- ElMessage.success('浼氳绾淇濆瓨鎴愬姛')
- minutesDialogVisible.value = false
- })
-
-}
-
-// 鍏抽棴浼氳绾瀵硅瘽妗�
-const handleCloseMinutesDialog = () => {
- minutesContent.value = ''
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- '0': 'info', // 寰呭鎵�
- '1': 'success', // 宸查�氳繃
- '2': 'warning', // 鏈�氳繃
- '3': 'danger' // 鍙栨秷
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- '0': '寰呭鎵�',
- '1': '宸查�氳繃',
- '2': '鏈�氳繃',
- '3': '宸插彇娑�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateTime) => {
- if (!dateTime) return ''
- return dateTime.replace(' ', '\n')
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(async () => {
- const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()])
- roomEnum.value = resp1.data
- staffList.value = resp2.data
-
- await getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-.content-section h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.participants-list {
- min-height: 40px;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
-}
-
-.nowrap-label {
- white-space: nowrap !important;
-}
-
-.editor-container {
- border: 1px solid #dcdfe6;
- border-radius: 4px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/officeSupplies/index.vue b/src/views/collaborativeApproval/officeSupplies/index.vue
deleted file mode 100644
index a2d1c6d..0000000
--- a/src/views/collaborativeApproval/officeSupplies/index.vue
+++ /dev/null
@@ -1,512 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <template #header>
- <div class="card-header">
- <span>鍔炲叕鐗╄祫鐢宠绠$悊</span>
- <el-button type="primary" @click="openShow()">
- <el-icon><Plus /></el-icon>
- 鏂板缓鐢宠
- </el-button>
- </div>
- </template>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
- <el-form-item label="鐢宠缂栧彿" prop="code">
- <el-input
- v-model="queryParams.code"
- placeholder="璇疯緭鍏ョ敵璇风紪鍙�"
- clearable
- style="width: 200px"
- @keyup.enter="handleQuery"
- />
- </el-form-item>
- <el-form-item label="鐢宠浜�" prop="applicant">
- <el-input
- v-model="queryParams.applicant"
- placeholder="璇疯緭鍏ョ敵璇蜂汉"
- clearable
- style="width: 200px"
- @keyup.enter="handleQuery"
- />
- </el-form-item>
- <el-form-item label="鐢宠鐘舵��" prop="status">
- <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 200px">
- <el-option label="寰呭鎵�" value="1" />
- <el-option label="宸查�氳繃" value="3" />
- <el-option label="宸叉嫆缁�" value="2" />
- <el-option label="宸插彂鏀�" value="4" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery">
- <el-icon><Search /></el-icon>
- 鎼滅储
- </el-button>
- <el-button @click="resetQuery">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleExport">
- <el-icon><Download /></el-icon>
- 瀵煎嚭
- </el-button>
- </el-form-item>
- </el-form>
-
- <!-- 琛ㄦ牸鍖哄煙 -->
- <el-table
- v-loading="loading"
- :data="officeList"
- @selection-change="handleSelectionChange"
- style="width: 100%"
- >
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="鐢宠缂栧彿" align="center" prop="code" width="180" />
- <el-table-column label="鐢宠浜�" align="center" prop="applicant" width="120" />
- <el-table-column label="閮ㄩ棬" align="center" prop="dept" width="120" />
- <el-table-column label="鐗╄祫绫诲瀷" align="center" prop="materialType" width="120">
- <template #default="scope">
- <el-tag v-if="scope.row.materialType === 1" type="info">鍏朵粬</el-tag>
- <el-tag v-if="scope.row.materialType === 2" type="success">娓呮磥鐢ㄥ搧</el-tag>
- <el-tag v-if="scope.row.materialType === 3" type="warning">鐢靛瓙璁惧</el-tag>
- <el-tag v-if="scope.row.materialType === 4" type="danger">鍔炲叕鐢ㄥ搧</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鐢宠鏁伴噺" align="center" prop="applyNum" width="100" />
- <el-table-column label="鐢宠鍘熷洜" align="center" prop="reason" min-width="200" show-overflow-tooltip />
- <el-table-column label="鐢宠鐘舵��" align="center" prop="status" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鐢宠鏃堕棿" align="center" prop="applyTime" width="180" />
- <el-table-column label="瀹℃壒浜�" align="center" prop="approval" width="120" />
- <el-table-column label="瀹℃壒鏃堕棿" align="center" prop="approvalTime" width="180" />
- <el-table-column label="鍙戞斁鏃堕棿" align="center" prop="issueTime" width="180" />
- <el-table-column label="鎿嶄綔" align="center" fixed="right" class-name="small-padding fixed-width" width="200">
- <template #default="scope">
- <el-button
- v-if="scope.row.status === 1"
- type="primary"
- link
- @click="handleApprove(scope.row)"
- >
- 瀹℃壒
- </el-button>
- <el-button
- v-if="scope.row.status === 3"
- type="success"
- link
- @click="handleIssue(scope.row)"
- >
- 鍙戞斁
- </el-button>
- <el-button
- type="info"
- link
- @click="handleDetail(scope.row)"
- >
- 璇︽儏
- </el-button>
- <el-button
- v-if="scope.row.status === 2"
- type="danger"
- link
- @click="handleDelete(scope.row)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.current"
- v-model:limit="queryParams.size"
- @pagination="getList"
- />
- </el-card>
-
- <!-- 鐢宠瀵硅瘽妗� -->
- <el-dialog
- v-model="showApplyDialog"
- title="鍔炲叕鐗╄祫鐢宠"
- width="600px"
- append-to-body
- >
- <el-form ref="applyFormRef" :model="applyForm" :rules="applyRules" label-width="100px">
- <el-form-item label="鐢宠浜�" prop="applicant">
- <el-input v-model="applyForm.applicant" placeholder="璇疯緭鍏ョ敵璇蜂汉鍚嶇О" />
- </el-form-item>
- <el-form-item label="閮ㄩ棬" prop="dept">
- <el-input v-model="applyForm.dept" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" />
- </el-form-item>
- <el-form-item label="鐗╄祫绫诲瀷" prop="materialType">
- <el-select v-model="applyForm.materialType" placeholder="璇烽�夋嫨鐗╄祫绫诲瀷" style="width: 100%">
- <el-option label="鍔炲叕鐢ㄥ搧" value="4" />
- <el-option label="鐢靛瓙璁惧" value="3" />
- <el-option label="娓呮磥鐢ㄥ搧" value="2" />
- <el-option label="鍏朵粬" value="1" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍏蜂綋鐗╁搧" prop="itemName">
- <el-input v-model="applyForm.itemName" placeholder="璇疯緭鍏ュ叿浣撶墿鍝佸悕绉�" />
- </el-form-item>
- <el-form-item label="鐢宠鏁伴噺" prop="applyNum">
- <el-input-number v-model="applyForm.applyNum" :min="1" :max="999" style="width: 100%" />
- </el-form-item>
- <el-form-item label="鐢宠鍘熷洜" prop="reason">
- <el-input
- v-model="applyForm.reason"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ョ敵璇峰師鍥�"
- />
- </el-form-item>
- <el-form-item label="绱ф�ョ▼搴�" prop="urgency">
- <el-radio-group v-model="applyForm.urgency">
- <el-radio label="1">鏅��</el-radio>
- <el-radio label="2">绱ф��</el-radio>
- <el-radio label="3">闈炲父绱ф��</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="showApplyDialog = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="submitApply">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 瀹℃壒瀵硅瘽妗� -->
- <el-dialog
- v-model="showApproveDialog"
- title="瀹℃壒鐢宠"
- width="500px"
- append-to-body
- >
- <el-form ref="approveFormRef" :model="approveForm" :rules="approveRules" label-width="100px">
- <el-form-item label="瀹℃壒缁撴灉" prop="approveResult">
- <el-radio-group v-model="approveForm.approveResult">
- <el-radio label="3">閫氳繃</el-radio>
- <el-radio label="2">鎷掔粷</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="瀹℃壒鎰忚" prop="approvalOpinions">
- <el-input
- v-model="approveForm.approvalOpinions"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ鎵规剰瑙�"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="showApproveDialog = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="submitApprove">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 璇︽儏瀵硅瘽妗� -->
- <el-dialog
- v-model="showDetailDialog"
- title="鐢宠璇︽儏"
- width="700px"
- append-to-body
- >
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鐢宠缂栧彿">{{ currentDetail.code }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentDetail.applicant }}</el-descriptions-item>
- <el-descriptions-item label="閮ㄩ棬">{{ currentDetail.dept }}</el-descriptions-item>
- <el-descriptions-item label="鐗╄祫绫诲瀷">{{ currentDetail.materialType }}</el-descriptions-item>
- <el-descriptions-item label="鍏蜂綋鐗╁搧">{{ currentDetail.itemName }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鏁伴噺">{{ currentDetail.applyNum }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鍘熷洜" :span="2">{{ currentDetail.reason }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鐘舵��">
- <el-tag :type="getStatusType(currentDetail.status)">
- {{ getStatusText(currentDetail.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿">{{ currentDetail.applyTime }}</el-descriptions-item>
- <el-descriptions-item label="瀹℃壒浜�">{{ currentDetail.approval || '-' }}</el-descriptions-item>
- <el-descriptions-item label="瀹℃壒鏃堕棿">{{ currentDetail.approvalTime || '-' }}</el-descriptions-item>
- <el-descriptions-item label="瀹℃壒鎰忚" :span="2">{{ currentDetail.approvalOpinions || '-' }}</el-descriptions-item>
- <el-descriptions-item label="鍙戞斁鏃堕棿">{{ currentDetail.issueTime || '-' }}</el-descriptions-item>
- <el-descriptions-item label="鍙戞斁浜�">{{ currentDetail.issueUser || '-' }}</el-descriptions-item>
- </el-descriptions>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {listPage,add,update,deleteOff} from "@/api/collaborativeApproval/officeSupplies.js"
-import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
-import Cookies from 'js-cookie'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search, Refresh, Download, Check } from '@element-plus/icons-vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const showSearch = ref(true)
-const showApplyDialog = ref(false)
-const showApproveDialog = ref(false)
-const showDetailDialog = ref(false)
-const multipleSelection = ref([])
-const officeList = ref([])
-const total = ref(0)
-const suppliesList = ref([])
-const currentDetail = ref({})
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- current: 1,
- size: 10,
- code: '',
- applicant: '',
- status: ''
-})
-
-// 鐢宠琛ㄥ崟
-const applyForm = reactive({
- applicant: '',
- dept: '',
- materialType: '',
- itemName: '',
- applyNum: 1,
- reason: '',
- urgency: '1'
-})
-
-// 瀹℃壒琛ㄥ崟
-const approveForm = reactive({
- approveResult: '3',
- approvalOpinions: ''
-})
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const applyRules = {
- applicant: [{ required: true, message: '璇烽�夋嫨鐗╄祫绫诲瀷', trigger: 'blur' }],
- dept: [{ required: true, message: '璇烽�夋嫨鐗╄祫绫诲瀷', trigger: 'blur' }],
- materialType: [{ required: true, message: '璇烽�夋嫨鐗╄祫绫诲瀷', trigger: 'change' }],
- itemName: [{ required: true, message: '璇疯緭鍏ュ叿浣撶墿鍝佸悕绉�', trigger: 'blur' }],
- applyNum: [{ required: true, message: '璇疯緭鍏ョ敵璇锋暟閲�', trigger: 'blur' }],
- reason: [{ required: true, message: '璇疯緭鍏ョ敵璇峰師鍥�', trigger: 'blur' }]
-}
-
-const approveRules = {
- approveResult: [{ required: true, message: '璇烽�夋嫨瀹℃壒缁撴灉', trigger: 'change' }],
- approvalOpinions: [{ required: true, message: '璇疯緭鍏ュ鎵规剰瑙�', trigger: 'blur' }]
-}
-
-const openShow = () => {
- showApplyDialog.value = true
- resetApplyForm()
-}
-
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- loading.value = true
- listPage(queryParams).then(res => {
- total.value = res.data.total
- loading.value = false
- officeList.value = res.data.records
- })
-}
-
-// 鏌ヨ
-const handleQuery = () => {
- queryParams.current = 1
- getList()
-}
-
-// 閲嶇疆鏌ヨ
-const resetQuery = () => {
- queryParams.code = ''
- queryParams.applicant = ''
- queryParams.status = ''
- handleQuery()
-}
-
-// 澶氶��
-const handleSelectionChange = (selection) => {
- multipleSelection.value = selection
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- 1: 'warning',
- 3: 'success',
- 2: 'danger',
- 4: 'info'
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- 1: '寰呭鎵�',
- 3: '宸查�氳繃',
- 2: '宸叉嫆缁�',
- 4: '宸插彂鏀�'
- }
- return statusMap[status] || status
-}
-
-// 鎻愪氦鐢宠
-const submitApply = () => {
- add(applyForm).then(() => {
- ElMessage.success('鐢宠鎴愬姛')
- getList()
- showApplyDialog.value = false
- resetApplyForm()
- })
-
-
-
-}
-
-//閲嶇疆琛ㄥ崟
-const resetApplyForm = () => {
- // 閲嶇疆琛ㄥ崟
- Object.assign(applyForm, {
- applicant: '',
- dept: '',
- materialType: '',
- itemName: '',
- applyNum: 1,
- reason: '',
- urgency: '1'
- })
-}
-
-// 瀹℃壒
-const handleApprove = (row) => {
- currentDetail.value = row
- showApproveDialog.value = true
-}
-
-const formatDate = (date) => {
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- const hours = String(date.getHours()).padStart(2, '0')
- const minutes = String(date.getMinutes()).padStart(2, '0')
- const sends = String(date.getSeconds()).padStart(2, '0')
- return `${year}-${month}-${day} ${hours}:${minutes}:${sends}`
-}
-
-// 鎻愪氦瀹℃壒
-const submitApprove = () => {
- currentDetail.value.status = approveForm.approveResult
- // 浠巆ookie涓幏鍙栧綋鍓嶇櫥褰曠敤鎴峰悕绉�
- currentDetail.value.approval = Cookies.get('username')
- currentDetail.value.approvalTime = formatDate(new Date())
- currentDetail.value.approvalOpinions = approveForm.approvalOpinions
- update(currentDetail.value).then((res) => {
- if(res.code === 200){
- showApproveDialog.value = false
- ElMessage.success('瀹℃壒瀹屾垚')
- getList()
-
- // 閲嶇疆琛ㄥ崟
- Object.assign(approveForm, {
- approveResult: '3',
- approvalOpinions: ''
- })
- }
- })
-
-}
-
-// 鍙戞斁
-const handleIssue = (row) => {
- row.status = 4
- row.issueTime = formatDate(new Date())
- row.issueUser = Cookies.get('username')
- update(row).then((res) =>{
- if(res.code === 200){
- ElMessage.success('鍙戞斁瀹屾垚')
- getList()
- }
- })
-}
-
-// 鏌ョ湅璇︽儏
-const handleDetail = (row) => {
- currentDetail.value = row
- showDetailDialog.value = true
-}
-
-// 鍒犻櫎
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ョ敵璇峰悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- deleteOff(ids).then((res) =>{
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- })
- })
-}
-const { proxy } = getCurrentInstance();
-// 瀵煎嚭
-const handleExport = () => {
- ElMessageBox.confirm("鎵�鏈夌殑鍐呭灏嗚瀵煎嚭锛屾槸鍚︾‘璁ゅ鍑猴紵", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/officeSupplies/export", {}, "鍔炲叕鐗╄祫.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-}
-
-// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
-onMounted(() => {
- getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.mb8 {
- margin-bottom: 8px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-descriptions__label) {
- width: 120px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/planTemplate/index.vue b/src/views/collaborativeApproval/planTemplate/index.vue
deleted file mode 100644
index 0af6d8b..0000000
--- a/src/views/collaborativeApproval/planTemplate/index.vue
+++ /dev/null
@@ -1,867 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤堕儴鎿嶄綔鏍� -->
- <div class="header-actions">
- <div class="left-actions">
- <el-select v-model="currentLevel" placeholder="閫夋嫨璁″垝绾у埆" style="width: 150px" @change="handleLevelChange">
- <el-option label="涓汉璁″垝" value="personal" />
- <el-option label="灏忕粍璁″垝" value="group" />
- <el-option label="閮ㄩ棬璁″垝" value="department" />
- <el-option label="鍏徃璁″垝" value="company" />
- </el-select>
- <el-select v-model="currentPeriod" placeholder="閫夋嫨鏃堕棿鍛ㄦ湡" style="width: 120px; margin-left: 10px" @change="handlePeriodChange">
- <el-option label="鍛ㄨ鍒�" value="week" />
- <el-option label="鏈堣鍒�" value="month" />
- <el-option label="骞磋鍒�" value="year" />
- </el-select>
- <el-date-picker
- v-model="currentDate"
- :type="datePickerType"
- placeholder="閫夋嫨鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 180px; margin-left: 10px"
- @change="handleDateChange"
- />
- </div>
- <div class="right-actions">
- <el-button type="primary" @click="handleAddPlan">鏂板璁″垝</el-button>
- <el-button @click="handleExport">瀵煎嚭璁″垝</el-button>
- <!-- <el-button @click="handleShare">鍏变韩璁″垝@</el-button> -->
- </div>
- </div>
-
- <!-- 璁″垝姒傝鍗$墖 -->
- <div class="overview-cards">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-card class="overview-card">
- <div class="card-content">
- <div class="card-icon personal">
- <el-icon><User /></el-icon>
- </div>
- <div class="card-info">
- <div class="card-title">涓汉璁″垝</div>
- <div class="card-number">{{ overviewData.personal.total }}</div>
- <div class="card-progress">
- <el-progress :percentage="overviewData.personal.completion" :stroke-width="6" />
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="overview-card">
- <div class="card-content">
- <div class="card-icon group">
- <el-icon><UserFilled /></el-icon>
- </div>
- <div class="card-info">
- <div class="card-title">灏忕粍璁″垝</div>
- <div class="card-number">{{ overviewData.group.total }}</div>
- <div class="card-progress">
- <el-progress :percentage="overviewData.group.completion" :stroke-width="6" />
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="overview-card">
- <div class="card-content">
- <div class="card-icon department">
- <el-icon><OfficeBuilding /></el-icon>
- </div>
- <div class="card-info">
- <div class="card-title">閮ㄩ棬璁″垝</div>
- <div class="card-number">{{ overviewData.department.total }}</div>
- <div class="card-progress">
- <el-progress :percentage="overviewData.department.completion" :stroke-width="6" />
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="overview-card">
- <div class="card-content">
- <div class="card-icon company">
- <el-icon><House /></el-icon>
- </div>
- <div class="card-info">
- <div class="card-title">鍏徃璁″垝</div>
- <div class="card-number">{{ overviewData.company.total }}</div>
- <div class="card-progress">
- <el-progress :percentage="overviewData.company.completion" :stroke-width="6" />
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璁″垝鍒楄〃 -->
- <div class="plan-content">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>{{ getCurrentLevelText() }} - {{ getCurrentPeriodText() }}</span>
- <div>
- <el-button size="small" @click="handleRefresh">鍒锋柊</el-button>
- <!-- <el-button size="small" @click="handleFilter">绛涢�堾</el-button> -->
- </div>
- </div>
- </template>
-
- <div class="plan-list">
- <div v-for="plan in planList" :key="plan.id" class="plan-item">
- <div class="plan-header">
- <div class="plan-title">
- <el-tag :type="getPriorityType(plan.priority)" size="small">{{ getPriorityText(plan.priority) }}</el-tag>
- <span class="title-text">{{ plan.title }}</span>
- </div>
- <div class="plan-actions">
- <el-button size="small" @click="handleEditPlan(plan)">缂栬緫</el-button>
- <el-button size="small" @click="handleViewDetail(plan)">璇︽儏</el-button>
- <el-dropdown @command="(command) => handleMoreAction(plan, command)">
- <el-button size="small">
- 鏇村<el-icon class="el-icon--right"><ArrowDown /></el-icon>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <!-- <el-dropdown-item command="share">鍏变韩@</el-dropdown-item> -->
- <el-dropdown-item command="copy">澶嶅埗</el-dropdown-item>
- <el-dropdown-item command="delete" divided>鍒犻櫎</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </div>
-
- <div class="plan-content">
- <div class="plan-description">{{ plan.description }}</div>
- <div class="plan-meta">
- <div class="meta-item">
- <el-icon><Calendar /></el-icon>
- <span>{{ plan.startDate }} - {{ plan.endDate }}</span>
- </div>
- <div class="meta-item">
- <el-icon><User /></el-icon>
- <span>{{ plan.assignee }}</span>
- </div>
- <div class="meta-item">
- <el-icon><Clock /></el-icon>
- <span>杩涘害: {{ plan.progress }}%</span>
- </div>
- <div class="meta-item">
- <el-icon><Flag /></el-icon>
- <span>{{ getStatusText(plan.status) }}</span>
- </div>
- </div>
-
- <div class="plan-progress">
- <el-progress
- :percentage="plan.progress"
- :color="getProgressColor(plan.progress)"
- :stroke-width="8"
- />
- </div>
-
- <div class="plan-tags">
- <el-tag v-for="tag in plan.tags" :key="tag" size="small" style="margin-right: 5px">
- {{ tag }}
- </el-tag>
- </div>
- </div>
- </div>
- </div>
- </el-card>
- </div>
-
- <!-- 鏂板/缂栬緫璁″垝瀵硅瘽妗� -->
- <el-dialog
- v-model="planDialogVisible"
- :title="operationType === 'add' ? '鍙戝竷璁″垝' : '缂栬緫璁″垝'"
- width="600px"
- @close="handleDialogClose"
- >
- <el-form :model="planForm" :rules="planRules" ref="planFormRef" label-width="100px">
- <el-form-item label="璁″垝鏍囬" prop="title">
- <el-input v-model="planForm.title" placeholder="璇疯緭鍏ヨ鍒掓爣棰�" />
- </el-form-item>
- <el-form-item label="璁″垝鎻忚堪" prop="description">
- <el-input
- v-model="planForm.description"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ヨ鍒掓弿杩�"
- />
- </el-form-item>
- <el-form-item label="璁″垝绾у埆" prop="level">
- <el-select v-model="planForm.level" placeholder="閫夋嫨璁″垝绾у埆" style="width: 100%">
- <el-option label="涓汉璁″垝" value="personal" />
- <el-option label="灏忕粍璁″垝" value="group" />
- <el-option label="閮ㄩ棬璁″垝" value="department" />
- <el-option label="鍏徃璁″垝" value="company" />
- </el-select>
- </el-form-item>
- <el-form-item label="鏃堕棿鍛ㄦ湡" prop="period">
- <el-select v-model="planForm.period" placeholder="閫夋嫨鏃堕棿鍛ㄦ湡" style="width: 100%">
- <el-option label="鍛ㄨ鍒�" value="week" />
- <el-option label="鏈堣鍒�" value="month" />
- <el-option label="骞磋鍒�" value="year" />
- </el-select>
- </el-form-item>
- <el-form-item label="寮�濮嬫椂闂�" prop="startDate">
- <el-date-picker
- v-model="planForm.startDate"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- placeholder="閫夋嫨寮�濮嬫椂闂�"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="缁撴潫鏃堕棿" prop="endDate">
- <el-date-picker
- v-model="planForm.endDate"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- placeholder="閫夋嫨缁撴潫鏃堕棿"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="璐熻矗浜�" prop="assignee">
- <el-input v-model="planForm.assignee" placeholder="璇疯緭鍏ヨ礋璐d汉" />
- </el-form-item>
- <el-form-item label="浼樺厛绾�" prop="priority">
- <el-select v-model="planForm.priority" placeholder="閫夋嫨浼樺厛绾�" style="width: 100%">
- <el-option label="楂�" value="high" />
- <el-option label="涓�" value="medium" />
- <el-option label="浣�" value="low" />
- </el-select>
- </el-form-item>
- <!-- <el-form-item label="鏍囩">
- <el-input v-model="planForm.tags" placeholder="璇疯緭鍏ユ爣绛撅紝鐢ㄩ�楀彿鍒嗛殧" />
- </el-form-item> -->
- <el-form-item label="鏍囩" prop="tags">
- <!-- <el-checkbox-group v-model="planForm.tags">
- <el-checkbox label="all"></el-checkbox>
- <el-checkbox label="manager">绠$悊灞�</el-checkbox>
- <el-checkbox label="hr">浜轰簨閮ㄩ棬</el-checkbox>
- <el-checkbox label="finance">璐㈠姟閮ㄩ棬</el-checkbox>
- <el-checkbox label="tech">鎶�鏈儴闂�</el-checkbox>
- </el-checkbox-group> -->
- <el-select
- v-model="planForm.tags"
- multiple
- placeholder="璇烽�夋嫨鏍囩"
- style="width: 100%"
- >
- <el-option
- v-for="dept in departments"
- :key="dept"
- :label="dept"
- :value="dept"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="planForm.status" placeholder="閫夋嫨鐘舵��" style="width: 100%">
- <el-option label="鏈紑濮�" value="not_started" />
- <el-option label="杩涜涓�" value="in_progress" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="宸叉殏鍋�" value="paused" />
- </el-select>
- </el-form-item>
- <el-form-item label="杩涘害" prop="progress">
- <el-input-number
- v-model="planForm.progress"
- min="0"
- max="100"
- step="1"
- placeholder="璇疯緭鍏ヨ繘搴�"
- style="width: 100%"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="planDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSavePlan">淇濆瓨</el-button>
- </span>
- </template>
- </el-dialog>
- <!-- 璁″垝璇︽儏瀵硅瘽妗� -->
- <el-dialog v-model="showPlanDetailDialog" title="璁″垝璇︽儏" width="700px">
- <div v-if="currentPlanDetail" class="mb10">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="璁″垝鏍囬">{{ currentPlanDetail.title }}</el-descriptions-item>
- <el-descriptions-item label="璁″垝鎻忚堪">{{ currentPlanDetail.description }}</el-descriptions-item>
- <el-descriptions-item label="璁″垝绾у埆">{{ getCurrentLevelText(currentPlanDetail.level) }}</el-descriptions-item>
- <el-descriptions-item label="鏃堕棿鍛ㄦ湡">{{ getCurrentPeriodText(currentPlanDetail.period) }}</el-descriptions-item>
- <el-descriptions-item label="寮�濮嬫椂闂�">{{ currentPlanDetail.startDate }}</el-descriptions-item>
- <el-descriptions-item label="缁撴潫鏃堕棿">{{ currentPlanDetail.endDate }}</el-descriptions-item>
- <el-descriptions-item label="璐熻矗浜�">{{ currentPlanDetail.assignee }}</el-descriptions-item>
- <el-descriptions-item label="浼樺厛绾�">{{ getPriorityText(currentPlanDetail.priority) }}</el-descriptions-item>
- <el-descriptions-item label="鏍囩">{{ currentPlanDetail.tags.join(', ') }}</el-descriptions-item>
- <el-descriptions-item label="鐘舵��">{{ getStatusText(currentPlanDetail.status) }}</el-descriptions-item>
- <el-descriptions-item label="杩涘害">{{ currentPlanDetail.progress }}%</el-descriptions-item>
- </el-descriptions>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-const { proxy } = getCurrentInstance();
-import {
- User,
- UserFilled,
- OfficeBuilding,
- House,
- Calendar,
- Clock,
- Flag,
- ArrowDown
-} from '@element-plus/icons-vue'
-import { listDutyPlan, addDutyPlan, updateDutyPlan, delDutyPlan,NumDutyPlan,exportDutyPlan } from '@/api/collaborativeApproval/planTemplate.js'
-
-// 鍝嶅簲寮忔暟鎹�
-const operationType = ref('add')
-const currentLevel = ref('personal')
-const currentPeriod = ref('week')
-const currentDate = ref(new Date())
-const planDialogVisible = ref(false)
-const dialogTitle = ref('鏂板璁″垝')
-const planFormRef = ref()
-const showPlanDetailDialog = ref(false)
-const currentPlanDetail = ref(null)
-
-// 琛ㄥ崟鏁版嵁
-const planForm = reactive({
- id: '',
- title: '',
- description: '',
- level: 'personal',
- period: 'week',
- startDate: '',
- endDate: '',
- assignee: '',
- priority: 'medium',
- tags: [],
- status: '',
- progress: 0
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const planRules = {
- title: [{ required: true, message: '璇疯緭鍏ヨ鍒掓爣棰�', trigger: 'blur' }],
- description: [{ required: true, message: '璇疯緭鍏ヨ鍒掓弿杩�', trigger: 'blur' }],
- level: [{ required: true, message: '璇烽�夋嫨璁″垝绾у埆', trigger: 'change' }],
- period: [{ required: true, message: '璇烽�夋嫨鏃堕棿鍛ㄦ湡', trigger: 'change' }],
- startDate: [{ required: true, message: '璇烽�夋嫨寮�濮嬫椂闂�', trigger: 'change' }],
- endDate: [{ required: true, message: '璇烽�夋嫨缁撴潫鏃堕棿', trigger: 'change' }],
- assignee: [{ required: true, message: '璇疯緭鍏ヨ礋璐d汉', trigger: 'blur' }],
- priority: [{ required: true, message: '璇烽�夋嫨浼樺厛绾�', trigger: 'change' }]
-}
-const departments = ["浜у搧", "鍒嗘瀽", "璋冪爺",'鎶�鏈�', '鏋舵瀯', '璁捐','甯傚満', '鎺ㄥ箍', '钀ラ攢'];
-// 姒傝鏁版嵁
-const overviewData = reactive({
- personal: { total: 0, completion: 0 },
- group: { total: 0, completion: 0 },
- department: { total: 0, completion: 0 },
- company: { total: 0, completion: 0 }
-})
-
-// 璁″垝鍒楄〃鏁版嵁
-const planList = ref([])
-
-// 璁$畻灞炴��
-const datePickerType = computed(() => {
- switch (currentPeriod.value) {
- case 'week':
- return 'week'
- case 'month':
- return 'month'
- case 'year':
- return 'year'
- default:
- return 'date'
- }
-})
-
-// 鏂规硶
-const handleLevelChange = (value) => {
- console.log('璁″垝绾у埆鍙樻洿:', value)
- getPlanList()
- // 杩欓噷鍙互鏍规嵁绾у埆绛涢�夋暟鎹�
-}
-
-const handlePeriodChange = (value) => {
- console.log('鏃堕棿鍛ㄦ湡鍙樻洿:', value)
- getPlanList()
- // 杩欓噷鍙互鏍规嵁鍛ㄦ湡绛涢�夋暟鎹�
-}
-
-const handleDateChange = (value) => {
- console.log('鏃ユ湡鍙樻洿:', value)
- getPlanList()
- // 杩欓噷鍙互鏍规嵁鏃ユ湡绛涢�夋暟鎹�
-}
-
-const handleAddPlan = () => {
- operationType.value = 'add'
- dialogTitle.value = '鏂板璁″垝'
- planDialogVisible.value = true
- // 閲嶇疆琛ㄥ崟
- Object.keys(planForm).forEach(key => {
- planForm[key] = ''
- })
- planForm.level = 'personal'
- planForm.period = 'week'
- planForm.priority = 'medium'
- planForm.status = 'not_started'
- planForm.progress = 0
-}
-
-const handleEditPlan = (plan) => {
- operationType.value = 'edit'
- dialogTitle.value = '缂栬緫璁″垝'
- planDialogVisible.value = true
- Object.assign(planForm, plan)
- // // 濉厖琛ㄥ崟鏁版嵁
- // Object.keys(planForm).forEach(key => {
- // if (key === 'tags') {
- // planForm[key] = plan[key].join(', ')
- // } else {
- // planForm[key] = plan[key]
- // }
- // })
-}
-
-const handleViewDetail = (plan) => {
- currentPlanDetail.value = plan
- showPlanDetailDialog.value = true
- // ElMessage.info(`鏌ョ湅璁″垝璇︽儏: ${plan.title}`)
-}
-
-const handleMoreAction = async(plan,command) => {
- let ids = [];
- ids.push(plan.id);
- console.log("ids",ids)
- switch (command) {
- case 'share':
- ElMessage.success('璁″垝宸插叡浜�')
- break
- case 'copy':
- const knowledgeText = `
- 璁″垝鏍囬锛�${plan.title}
- 璁″垝鎻忚堪锛�${plan.description}
- 璁″垝绾у埆锛�${getCurrentLevelText(plan.level)}
- 鏃堕棿鍛ㄦ湡锛�${getCurrentPeriodText(plan.period)}
- 寮�濮嬫椂闂达細${plan.startDate}
- 缁撴潫鏃堕棿锛�${plan.endDate}
- 璐熻矗浜猴細${plan.assignee}
- 浼樺厛绾э細${getPriorityText(plan.priority)}
- 鏍囩锛�${plan.tags.join(', ')}
- 鐘舵�侊細${getStatusText(plan.status)}
- 杩涘害锛�${plan.progress}%
- `.trim();
-
- // 澶嶅埗鍒板壀璐存澘
- navigator.clipboard.writeText(knowledgeText).then(() => {
- ElMessage.success("鐭ヨ瘑鍐呭宸插鍒跺埌鍓创鏉�");
- }).catch(() => {
- ElMessage.error("澶嶅埗澶辫触锛岃鎵嬪姩澶嶅埗");
- });
- // ElMessage.success('璁″垝宸插鍒�')
- break
- case 'delete':
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓鍒掑悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
-
- delDutyPlan(ids).then(res => {
- if (res.code === 200) {
- ElMessage.success('璁″垝宸插垹闄�')
- ids.value = [];
- getPlanList()
- }
- })
- })
- break
- }
-}
-//
-const handleSavePlan = async () => {
- try {
- await planFormRef.value.validate()
- if (operationType.value === 'add') {
- addDutyPlan(planForm).then(res => {
- if (res.code === 200) {
- ElMessage.success('璁″垝淇濆瓨鎴愬姛')
- planDialogVisible.value = false
- }
- getPlanList()
- })
- } else {
-
- updateDutyPlan(planForm).then(res => {
- if (res.code === 200) {
- ElMessage.success('璁″垝淇濆瓨鎴愬姛')
- planDialogVisible.value = false
- }
- getPlanList()
- })
- }
- } catch (error) {
- console.log('琛ㄥ崟楠岃瘉澶辫触:', error)
- }
-}
-
-const handleDialogClose = () => {
- planFormRef.value?.resetFields()
-}
-
-const handleRefresh = () => {
- getPlanList()
- // ElMessage.success('鏁版嵁宸插埛鏂�')
-}
-
-const handleFilter = () => {
- ElMessage.info('鎵撳紑绛涢�夐潰鏉�')
-}
-
-const handleExport = () => {
- ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- // exportDutyPlan().then(res => {
-
- // })
- proxy.download("/dutyPlan/export", {}, "璁″垝绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-const handleShare = () => {
- ElMessage.success('璁″垝宸插叡浜�')
-}
-
-const getCurrentLevelText = () => {
- const levelMap = {
- personal: '涓汉璁″垝',
- group: '灏忕粍璁″垝',
- department: '閮ㄩ棬璁″垝',
- company: '鍏徃璁″垝'
- }
- return levelMap[currentLevel.value] || '涓汉璁″垝'
-}
-
-const getCurrentPeriodText = () => {
- const periodMap = {
- week: '鍛ㄨ鍒�',
- month: '鏈堣鍒�',
- year: '骞磋鍒�'
- }
- return periodMap[currentPeriod.value] || '鍛ㄨ鍒�'
-}
-
-const getPriorityType = (priority) => {
- const typeMap = {
- high: 'danger',
- medium: 'warning',
- low: 'info'
- }
- return typeMap[priority] || 'info'
-}
-
-const getPriorityText = (priority) => {
- const textMap = {
- high: '楂�',
- medium: '涓�',
- low: '浣�'
- }
- return textMap[priority] || '涓�'
-}
-
-const getStatusText = (status) => {
- const statusMap = {
- not_started: '鏈紑濮�',
- in_progress: '杩涜涓�',
- completed: '宸插畬鎴�',
- paused: '宸叉殏鍋�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-const getProgressColor = (progress) => {
- if (progress >= 80) return '#67C23A'
- if (progress >= 50) return '#E6A23C'
- return '#F56C6C'
-}
-//鑾峰彇鏁版嵁鍒楄〃
-const getPlanList = async () => {
- const params = {
- level: currentLevel.value,
- period: currentPeriod.value,
- queryDate:currentDate.value
- }
- listDutyPlan(params).then(res => {
- if (res.code === 200) {
- planList.value = res.data.records
- }
- }).catch(err => {
- console.log(err)
- })
-}
-//鑾峰彇鏁版嵁
-const getPlanNum = async () => {
- NumDutyPlan().then(res => {
- if (res.code === 200) {
- // console.log(res.data)
- //璁茬粨鏋滈噷闈㈢殑鏁版嵁鏍规嵁level 璧嬪�肩粰overviewData
- res.data.forEach(item => {
- overviewData[item.level].total = item.num
- overviewData[item.level].completion = item.completion
- })
-
- }
- }).catch(err => {
- console.log(err)
- })
-}
-
-onMounted(() => {
- getPlanList()
- getPlanNum()
- console.log('澶氱骇璁″垝妯℃澘椤甸潰宸插姞杞�')
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 100vh;
-}
-
-.header-actions {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- background: white;
- padding: 20px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.left-actions {
- display: flex;
- align-items: center;
-}
-
-.right-actions {
- display: flex;
- gap: 10px;
-}
-
-.overview-cards {
- margin-bottom: 20px;
-}
-
-.overview-card {
- height: 120px;
-}
-
-.card-content {
- display: flex;
- align-items: center;
- height: 100%;
-}
-
-.card-icon {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 15px;
- font-size: 24px;
- color: white;
-}
-
-.card-icon.personal {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-}
-
-.card-icon.group {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
-}
-
-.card-icon.department {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-}
-
-.card-icon.company {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
-}
-
-.card-info {
- flex: 1;
-}
-
-.card-title {
- font-size: 14px;
- color: #666;
- margin-bottom: 5px;
-}
-
-.card-number {
- font-size: 24px;
- font-weight: bold;
- color: #333;
- margin-bottom: 10px;
-}
-
-.card-progress {
- width: 100%;
-}
-
-.plan-content {
- background: white;
- border-radius: 8px;
- overflow: hidden;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: bold;
- color: #333;
-}
-
-.header-actions {
- display: flex;
- gap: 10px;
-}
-
-.plan-list {
- padding: 20px 0;
-}
-
-.plan-item {
- border: 1px solid #e4e7ed;
- border-radius: 8px;
- margin-bottom: 15px;
- padding: 20px;
- transition: all 0.3s ease;
-}
-
-.plan-item:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transform: translateY(-2px);
-}
-
-.plan-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
-}
-
-.plan-title {
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.title-text {
- font-size: 16px;
- font-weight: bold;
- color: #333;
-}
-
-.plan-actions {
- display: flex;
- gap: 10px;
-}
-
-.plan-content {
- margin-bottom: 15px;
-}
-
-.plan-description {
- color: #666;
- margin-bottom: 15px;
- line-height: 1.6;
-}
-
-.plan-meta {
- display: flex;
- flex-wrap: wrap;
- gap: 20px;
- margin-bottom: 15px;
-}
-
-.meta-item {
- display: flex;
- align-items: center;
- gap: 5px;
- color: #666;
- font-size: 14px;
-}
-
-.plan-progress {
- margin-bottom: 15px;
-}
-
-.plan-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 5px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .header-actions {
- flex-direction: column;
- gap: 15px;
- }
-
- .left-actions {
- flex-wrap: wrap;
- gap: 10px;
- }
-
- .plan-meta {
- flex-direction: column;
- gap: 10px;
- }
-
- .plan-header {
- flex-direction: column;
- align-items: flex-start;
- gap: 10px;
- }
-}
-</style>
diff --git a/src/views/collaborativeApproval/processTracking/index.vue b/src/views/collaborativeApproval/processTracking/index.vue
deleted file mode 100644
index 67f5106..0000000
--- a/src/views/collaborativeApproval/processTracking/index.vue
+++ /dev/null
@@ -1,498 +0,0 @@
-<template>
- <div class="process-tracking">
- <div class="header">
- <h2>杩囩▼杩借釜</h2>
- <el-button type="primary" @click="refreshData">鍒锋柊鏁版嵁</el-button>
- </div>
-
- <!-- 椤圭洰鐘舵�佺粺璁� -->
- <div class="status-cards">
- <el-row :gutter="20">
- <el-col :span="6" v-for="(item, index) in statusStats" :key="index">
- <el-card class="status-card" :class="item.type">
- <div class="card-content">
- <div class="card-icon">
- <el-icon :size="24">
- <component :is="item.icon" />
- </el-icon>
- </div>
- <div class="card-info">
- <div class="card-title">{{ item.label }}</div>
- <div class="card-count">{{ item.count }}</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 椤圭洰鍒楄〃 -->
- <el-card class="project-list">
- <template #header>
- <div class="card-header">
- <span>椤圭洰鍒楄〃</span>
- <el-button type="text" @click="toggleView">
- {{ viewMode === 'table' ? '鍒囨崲鍒扮敇鐗瑰浘' : '鍒囨崲鍒板垪琛�' }}
- </el-button>
- </div>
- </template>
-
- <!-- 琛ㄦ牸瑙嗗浘 -->
- <div v-if="viewMode === 'table'">
- <el-table :data="projectList" style="width: 100%">
- <el-table-column prop="name" label="椤圭洰鍚嶇О" />
- <el-table-column prop="manager" label="璐熻矗浜�"/>
- <el-table-column label="鐘舵��" >
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">
- {{ getStatusText(row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="杩涘害" width="150">
- <template #default="{ row }">
- <el-progress :percentage="row.progress" :status="getProgressStatus(row.status)" />
- </template>
- </el-table-column>
- <el-table-column prop="startDate" label="寮�濮嬫椂闂�" width="120" />
- <el-table-column prop="endDate" label="缁撴潫鏃堕棿" width="120" />
- <el-table-column label="鎿嶄綔" width="150">
- <template #default="{ row }">
- <el-button type="text" @click="updateStatus(row)">鏇存柊鐘舵��</el-button>
- <el-button type="text" @click="viewDetails(row)">璇︽儏</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
-
- <!-- 鐢樼壒鍥捐鍥� -->
- <div v-else class="gantt-container">
- <div ref="ganttChart" style="width: 100%; height: 400px;"></div>
- </div>
- </el-card>
-
- <!-- 鐘舵�佹洿鏂板璇濇 -->
- <el-dialog v-model="statusDialogVisible" title="鏇存柊椤圭洰鐘舵��" width="400px">
- <el-form :model="statusForm" label-width="80px">
- <el-form-item label="椤圭洰鍚嶇О">
- <el-input v-model="statusForm.name" disabled />
- </el-form-item>
- <el-form-item label="褰撳墠鐘舵��">
- <el-select v-model="statusForm.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="鏈紑濮�" value="not_started" />
- <el-option label="杩涜涓�" value="in_progress" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="寤舵湡" value="delayed" />
- </el-select>
- </el-form-item>
- <el-form-item label="杩涘害">
- <el-slider v-model="statusForm.progress" :max="100" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="statusDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="confirmStatusUpdate">纭</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { ElMessage } from 'element-plus'
-import { Clock, Loading, Check, Warning } from '@element-plus/icons-vue'
-import * as echarts from 'echarts'
-
-// 鍝嶅簲寮忔暟鎹�
-const viewMode = ref('table')
-const statusDialogVisible = ref(false)
-const ganttChart = ref(null)
-let chartInstance = null
-
-// 鐘舵�佺粺璁℃暟鎹�
-const statusStats = reactive([
- { label: '鏈紑濮�', count: 3, type: 'not-started', icon: Clock },
- { label: '杩涜涓�', count: 5, type: 'in-progress', icon: Loading },
- { label: '宸插畬鎴�', count: 8, type: 'completed', icon: Check },
- { label: '寤舵湡', count: 2, type: 'delayed', icon: Warning }
-])
-
-// 椤圭洰鍒楄〃鏁版嵁
-const projectList = reactive([
- {
- id: 1,
- name: '姹囨槦閽欎笟鐢熶骇绾挎墿寤洪」鐩�',
- manager: '闄堝織寮�',
- status: 'completed',
- progress: 100,
- startDate: '2024-01-01',
- endDate: '2024-01-15'
- },
- {
- id: 2,
- name: '鏂板瀷鐜繚閽欑矇宸ヨ壓鐮斿彂',
- manager: '鏋楅洩宄�',
- status: 'in_progress',
- progress: 75,
- startDate: '2024-01-10',
- endDate: '2024-01-25'
- },
- {
- id: 3,
- name: '姹囨槦閽欎笟ERP绯荤粺鍗囩骇',
- manager: '鐜嬮泤鐞�',
- status: 'in_progress',
- progress: 60,
- startDate: '2024-01-20',
- endDate: '2024-02-10'
- },
- {
- id: 4,
- name: '鐭垮北寮�閲囪鍙瘉缁湡鐢宠',
- manager: '璧典紵涓�',
- status: 'in_progress',
- progress: 45,
- startDate: '2024-01-25',
- endDate: '2024-02-15'
- },
- {
- id: 5,
- name: '鐜繚璁惧鍗囩骇鏀归��',
- manager: '鏉庝匠娆�',
- status: 'delayed',
- progress: 30,
- startDate: '2024-01-15',
- endDate: '2024-01-30'
- },
- {
- id: 6,
- name: '骞村害瀹夊叏鐢熶骇鍩硅璁″垝',
- manager: '寮犲缓鍥�',
- status: 'not_started',
- progress: 0,
- startDate: '2024-02-01',
- endDate: '2024-02-20'
- }
-])
-
-// 鐘舵�佹洿鏂拌〃鍗�
-const statusForm = reactive({
- id: null,
- name: '',
- status: '',
- progress: 0
-})
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const typeMap = {
- not_started: 'info',
- in_progress: 'warning',
- completed: 'success',
- delayed: 'danger'
- }
- return typeMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const textMap = {
- not_started: '鏈紑濮�',
- in_progress: '杩涜涓�',
- completed: '宸插畬鎴�',
- delayed: '寤舵湡'
- }
- return textMap[status] || '鏈煡'
-}
-
-// 鑾峰彇杩涘害鐘舵��
-const getProgressStatus = (status) => {
- if (status === 'completed') return 'success'
- if (status === 'delayed') return 'exception'
- return null
-}
-
-// 鍒囨崲瑙嗗浘妯″紡
-const toggleView = () => {
- viewMode.value = viewMode.value === 'table' ? 'gantt' : 'table'
- if (viewMode.value === 'gantt') {
- nextTick(() => {
- initGanttChart()
- })
- }
-}
-
-// 鍒濆鍖栫敇鐗瑰浘
-const initGanttChart = () => {
- if (!ganttChart.value) return
-
- if (chartInstance) {
- chartInstance.dispose()
- }
-
- chartInstance = echarts.init(ganttChart.value)
-
- // 鍑嗗鐢樼壒鍥炬暟鎹�
- const data = projectList.map((project, index) => ({
- name: project.name,
- value: [
- index,
- new Date(project.startDate).getTime(),
- new Date(project.endDate).getTime(),
- project.progress
- ],
- itemStyle: {
- color: getGanttColor(project.status)
- }
- }))
-
- const option = {
- title: {
- text: '椤圭洰鐢樼壒鍥�',
- left: 'center'
- },
- tooltip: {
- formatter: (params) => {
- const project = projectList[params.value[0]]
- return `
- <div>
- <strong>${project.name}</strong><br/>
- 璐熻矗浜�: ${project.manager}<br/>
- 鐘舵��: ${getStatusText(project.status)}<br/>
- 杩涘害: ${project.progress}%<br/>
- 寮�濮嬫椂闂�: ${project.startDate}<br/>
- 缁撴潫鏃堕棿: ${project.endDate}
- </div>
- `
- }
- },
- grid: {
- left: '15%',
- right: '10%',
- top: '15%',
- bottom: '15%'
- },
- xAxis: {
- type: 'time',
- axisLabel: {
- formatter: (value) => {
- return echarts.format.formatTime('MM-dd', value)
- }
- }
- },
- yAxis: {
- type: 'category',
- data: projectList.map(p => p.name),
- inverse: true
- },
- series: [{
- type: 'custom',
- renderItem: (params, api) => {
- const categoryIndex = api.value(0)
- const start = api.coord([api.value(1), categoryIndex])
- const end = api.coord([api.value(2), categoryIndex])
- const height = api.size([0, 1])[1] * 0.6
-
- return {
- type: 'rect',
- shape: {
- x: start[0],
- y: start[1] - height / 2,
- width: end[0] - start[0],
- height: height
- },
- style: api.style()
- }
- },
- data: data
- }]
- }
-
- chartInstance.setOption(option)
-}
-
-// 鑾峰彇鐢樼壒鍥鹃鑹�
-const getGanttColor = (status) => {
- const colorMap = {
- not_started: '#909399',
- in_progress: '#E6A23C',
- completed: '#67C23A',
- delayed: '#F56C6C'
- }
- return colorMap[status] || '#909399'
-}
-
-// 鏇存柊鐘舵��
-const updateStatus = (project) => {
- statusForm.id = project.id
- statusForm.name = project.name
- statusForm.status = project.status
- statusForm.progress = project.progress
- statusDialogVisible.value = true
-}
-
-// 纭鐘舵�佹洿鏂�
-const confirmStatusUpdate = () => {
- const project = projectList.find(p => p.id === statusForm.id)
- if (project) {
- project.status = statusForm.status
- project.progress = statusForm.progress
-
- // 鏇存柊缁熻鏁版嵁
- updateStatusStats()
-
- // 濡傛灉鏄敇鐗瑰浘瑙嗗浘锛岄噸鏂版覆鏌�
- if (viewMode.value === 'gantt') {
- nextTick(() => {
- initGanttChart()
- })
- }
-
- ElMessage.success('鐘舵�佹洿鏂版垚鍔�')
- }
- statusDialogVisible.value = false
-}
-
-// 鏇存柊鐘舵�佺粺璁�
-const updateStatusStats = () => {
- const stats = {
- not_started: 0,
- in_progress: 0,
- completed: 0,
- delayed: 0
- }
-
- projectList.forEach(project => {
- stats[project.status]++
- })
-
- statusStats[0].count = stats.not_started
- statusStats[1].count = stats.in_progress
- statusStats[2].count = stats.completed
- statusStats[3].count = stats.delayed
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetails = (project) => {
- ElMessage.info(`鏌ョ湅椤圭洰璇︽儏: ${project.name}`)
-}
-
-// 鍒锋柊鏁版嵁
-const refreshData = () => {
- // 妯℃嫙瀹炴椂鏇存柊
- const randomProject = projectList[Math.floor(Math.random() * projectList.length)]
- if (randomProject.status === 'in_progress') {
- randomProject.progress = Math.min(100, randomProject.progress + Math.floor(Math.random() * 10))
- if (randomProject.progress === 100) {
- randomProject.status = 'completed'
- }
- }
-
- updateStatusStats()
-
- if (viewMode.value === 'gantt') {
- nextTick(() => {
- initGanttChart()
- })
- }
-
- ElMessage.success('鏁版嵁宸插埛鏂�')
-}
-
-onMounted(() => {
- updateStatusStats()
-})
-</script>
-
-<style scoped>
-.process-tracking {
- padding: 20px;
-}
-
-.header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.header h2 {
- margin: 0;
- color: #303133;
-}
-
-.status-cards {
- margin-bottom: 20px;
-}
-
-.status-card {
- cursor: pointer;
- transition: all 0.3s;
-}
-
-.status-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.card-content {
- display: flex;
- align-items: center;
-}
-
-.card-icon {
- margin-right: 15px;
- padding: 10px;
- border-radius: 8px;
-}
-
-.status-card.not-started .card-icon {
- background-color: #f4f4f5;
- color: #909399;
-}
-
-.status-card.in-progress .card-icon {
- background-color: #fdf6ec;
- color: #E6A23C;
-}
-
-.status-card.completed .card-icon {
- background-color: #f0f9ff;
- color: #67C23A;
-}
-
-.status-card.delayed .card-icon {
- background-color: #fef0f0;
- color: #F56C6C;
-}
-
-.card-info {
- flex: 1;
-}
-
-.card-title {
- font-size: 14px;
- color: #909399;
- margin-bottom: 5px;
-}
-
-.card-count {
- font-size: 24px;
- font-weight: bold;
- color: #303133;
-}
-
-.project-list {
- margin-top: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.gantt-container {
- min-height: 400px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/reportGeneration/index.vue b/src/views/collaborativeApproval/reportGeneration/index.vue
deleted file mode 100644
index c160ad7..0000000
--- a/src/views/collaborativeApproval/reportGeneration/index.vue
+++ /dev/null
@@ -1,596 +0,0 @@
-<template>
- <div class="report-generation">
- <!-- 椤甸潰澶撮儴 -->
- <div class="page-header">
- <h2>椤圭洰鎬荤粨鎶ュ憡鐢熸垚</h2>
- <div class="header-actions">
- <el-button v-if="!reportGenerated" type="primary" @click="generateReport" :loading="generating">
- <el-icon><Document /></el-icon>
- 鐢熸垚鎶ュ憡
- </el-button>
- <el-button v-if="reportGenerated" type="primary" @click="resetConfig">
- <el-icon><Refresh /></el-icon>
- 鐢熸垚鏂版姤鍛�
- </el-button>
- <el-button @click="exportReport" :disabled="!reportGenerated">
- <el-icon><Download /></el-icon>
- 瀵煎嚭鎶ュ憡
- </el-button>
- </div>
- </div>
-
- <!-- 鎶ュ憡閰嶇疆鍖哄煙 -->
- <el-card class="config-card" v-if="!reportGenerated">
- <template #header>
- <span>鎶ュ憡閰嶇疆</span>
- </template>
- <el-form :model="reportConfig" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О">
- <el-select v-model="reportConfig.projectId" placeholder="璇烽�夋嫨椤圭洰">
- <el-option
- v-for="project in projectList"
- :key="project.id"
- :label="project.name"
- :value="project.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎶ュ憡鍛ㄦ湡">
- <el-date-picker
- v-model="reportConfig.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </el-card>
-
- <!-- 鎶ュ憡鍐呭灞曠ず鍖哄煙 -->
- <div v-if="reportGenerated" class="report-content">
- <!-- 椤圭洰鍩烘湰淇℃伅 -->
- <el-card class="report-section">
- <template #header>
- <span>椤圭洰鍩烘湰淇℃伅</span>
- </template>
- <el-descriptions :column="2" border>
- <el-descriptions-item label="椤圭洰鍚嶇О">{{ reportData.projectInfo.name }}</el-descriptions-item>
- <el-descriptions-item label="椤圭洰缁忕悊">{{ reportData.projectInfo.manager }}</el-descriptions-item>
- <el-descriptions-item label="寮�濮嬫椂闂�">{{ reportData.projectInfo.startDate }}</el-descriptions-item>
- <el-descriptions-item label="缁撴潫鏃堕棿">{{ reportData.projectInfo.endDate }}</el-descriptions-item>
- <el-descriptions-item label="椤圭洰鐘舵��">
- <el-tag :type="getStatusType(reportData.projectInfo.status)">
- {{ reportData.projectInfo.status }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鎬婚绠�">{{ reportData.projectInfo.budget }}</el-descriptions-item>
- </el-descriptions>
- </el-card>
-
- <!-- 浠诲姟瀹屾垚鐜囩粺璁� -->
- <el-card class="report-section">
- <template #header>
- <span>浠诲姟瀹屾垚鐜囩粺璁�</span>
- </template>
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="completion-stats">
- <div class="stat-item">
- <div class="stat-label">鎬讳换鍔℃暟</div>
- <div class="stat-value">{{ reportData.taskStats.total }}</div>
- </div>
- <div class="stat-item">
- <div class="stat-label">宸插畬鎴�</div>
- <div class="stat-value completed">{{ reportData.taskStats.completed }}</div>
- </div>
- <div class="stat-item">
- <div class="stat-label">杩涜涓�</div>
- <div class="stat-value in-progress">{{ reportData.taskStats.inProgress }}</div>
- </div>
- <div class="stat-item">
- <div class="stat-label">鏈紑濮�</div>
- <div class="stat-value pending">{{ reportData.taskStats.pending }}</div>
- </div>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="completion-rate">
- <el-progress
- type="circle"
- :percentage="reportData.taskStats.completionRate"
- :width="150"
- :stroke-width="8"
- >
- <template #default="{ percentage }">
- <span class="percentage-value">{{ percentage }}%</span>
- <div class="percentage-label">瀹屾垚鐜�</div>
- </template>
- </el-progress>
- </div>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 闂璁板綍缁熻 -->
- <el-card class="report-section">
- <template #header>
- <span>闂璁板綍缁熻</span>
- </template>
- <el-row :gutter="20">
- <el-col :span="8">
- <div class="issue-summary">
- <div class="summary-item">
- <div class="summary-label">鎬婚棶棰樻暟</div>
- <div class="summary-value">{{ reportData.issueStats.total }}</div>
- </div>
- <div class="summary-item">
- <div class="summary-label">宸茶В鍐�</div>
- <div class="summary-value resolved">{{ reportData.issueStats.resolved }}</div>
- </div>
- <div class="summary-item">
- <div class="summary-label">寰呰В鍐�</div>
- <div class="summary-value pending">{{ reportData.issueStats.pending }}</div>
- </div>
- </div>
- </el-col>
- <el-col :span="16">
- <el-table :data="reportData.issueStats.topIssues" size="small">
- <el-table-column prop="title" label="涓昏闂" />
- <el-table-column prop="severity" label="涓ラ噸绋嬪害" width="100">
- <template #default="{ row }">
- <el-tag :type="getSeverityType(row.severity)" size="small">
- {{ row.severity }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="80">
- <template #default="{ row }">
- <el-tag :type="row.status === '宸茶В鍐�' ? 'success' : 'warning'" size="small">
- {{ row.status }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 寤惰鍒嗘瀽 -->
- <el-card class="report-section">
- <template #header>
- <span>寤惰鍒嗘瀽</span>
- </template>
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="delay-stats">
- <div class="delay-item">
- <div class="delay-label">寤惰浠诲姟鏁�</div>
- <div class="delay-value">{{ reportData.delayAnalysis.delayedTasks }}</div>
- </div>
- <div class="delay-item">
- <div class="delay-label">骞冲潎寤惰澶╂暟</div>
- <div class="delay-value">{{ reportData.delayAnalysis.avgDelayDays }}</div>
- </div>
- <div class="delay-item">
- <div class="delay-label">鏈�澶у欢璇ぉ鏁�</div>
- <div class="delay-value">{{ reportData.delayAnalysis.maxDelayDays }}</div>
- </div>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="delay-reasons">
- <h4>涓昏寤惰鍘熷洜</h4>
- <ul>
- <li v-for="reason in reportData.delayAnalysis.reasons" :key="reason.reason">
- {{ reason.reason }} ({{ reason.count }}娆�)
- </li>
- </ul>
- </div>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 鍥㈤槦缁╂晥 -->
- <el-card class="report-section">
- <template #header>
- <span>鍥㈤槦缁╂晥</span>
- </template>
- <el-table :data="reportData.teamPerformance" size="small">
- <el-table-column prop="name" label="鎴愬憳濮撳悕" />
- <el-table-column prop="completedTasks" label="瀹屾垚浠诲姟鏁�" />
- <el-table-column prop="completionRate" label="瀹屾垚鐜�" width="100">
- <template #default="{ row }">
- <el-progress :percentage="row.completionRate" :show-text="false" />
- <span style="margin-left: 10px;">{{ row.completionRate }}%</span>
- </template>
- </el-table-column>
- <el-table-column prop="performance" label="缁╂晥璇勭骇" width="100">
- <template #default="{ row }">
- <el-tag :type="getPerformanceType(row.performance)">
- {{ row.performance }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 鎬荤粨涓庡缓璁� -->
- <el-card class="report-section">
- <template #header>
- <span>鎬荤粨涓庡缓璁�</span>
- </template>
- <div class="summary-content">
- <h4>椤圭洰鎬荤粨</h4>
- <p>{{ reportData.summary.conclusion }}</p>
-
- <h4>鏀硅繘寤鸿</h4>
- <ul>
- <li v-for="suggestion in reportData.summary.suggestions" :key="suggestion">
- {{ suggestion }}
- </li>
- </ul>
- </div>
- </el-card>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { Document, Download, Refresh } from '@element-plus/icons-vue'
-import { ElMessage } from 'element-plus'
-
-// 鍝嶅簲寮忔暟鎹�
-const generating = ref(false)
-const reportGenerated = ref(false)
-
-// 鎶ュ憡閰嶇疆
-const reportConfig = reactive({
- projectId: '',
- dateRange: []
-})
-
-// 椤圭洰鍒楄〃
-const projectList = ref([
- { id: 1, name: '浜у搧搴撳瓨绠$悊绯荤粺' },
- { id: 2, name: '瀹㈡埛鍏崇郴绠$悊骞冲彴' },
- { id: 3, name: '璐㈠姟绠$悊绯荤粺鍗囩骇' },
- { id: 4, name: '绉诲姩绔簲鐢ㄥ紑鍙�' }
-])
-
-// 鎶ュ憡鏁版嵁
-const reportData = ref({})
-
-// 妯℃嫙鎶ュ憡鏁版嵁
-const mockReportData = {
- projectInfo: {
- name: '浜у搧搴撳瓨绠$悊绯荤粺',
- manager: '寮犱笁',
- startDate: '2024-01-01',
- endDate: '2024-03-31',
- status: '宸插畬鎴�',
- budget: '楼500,000'
- },
- taskStats: {
- total: 45,
- completed: 38,
- inProgress: 5,
- pending: 2,
- completionRate: 84
- },
- issueStats: {
- total: 12,
- resolved: 9,
- pending: 3,
- topIssues: [
- { title: '鏁版嵁搴撹繛鎺ヨ秴鏃�', severity: '楂�', status: '宸茶В鍐�' },
- { title: '鍓嶇椤甸潰鍝嶅簲鎱�', severity: '涓�', status: '宸茶В鍐�' },
- { title: '鏉冮檺楠岃瘉寮傚父', severity: '楂�', status: '寰呰В鍐�' },
- { title: '鎶ヨ〃瀵煎嚭鍔熻兘缂哄け', severity: '涓�', status: '寰呰В鍐�' }
- ]
- },
- delayAnalysis: {
- delayedTasks: 8,
- avgDelayDays: 3.5,
- maxDelayDays: 12,
- reasons: [
- { reason: '闇�姹傚彉鏇�', count: 3 },
- { reason: '鎶�鏈毦棰�', count: 2 },
- { reason: '璧勬簮涓嶈冻', count: 2 },
- { reason: '澶栭儴渚濊禆', count: 1 }
- ]
- },
- teamPerformance: [
- { name: '鏉庡洓', completedTasks: 12, completionRate: 92, performance: '浼樼' },
- { name: '鐜嬩簲', completedTasks: 10, completionRate: 85, performance: '鑹ソ' },
- { name: '璧靛叚', completedTasks: 8, completionRate: 78, performance: '鑹ソ' },
- { name: '閽变竷', completedTasks: 8, completionRate: 72, performance: '涓�鑸�' }
- ],
- summary: {
- conclusion: '鏈」鐩暣浣撴墽琛屾儏鍐佃壇濂斤紝浠诲姟瀹屾垚鐜囪揪鍒�84%锛屽洟闃熷崗浣滄晥鐜囪緝楂樸�備富瑕侀棶棰橀泦涓湪鎶�鏈疄鐜板拰闇�姹傚彉鏇存柟闈紝閫氳繃鍙婃椂娌熼�氬拰鎶�鏈敾鍏筹紝澶ч儴鍒嗛棶棰樺凡寰楀埌瑙e喅銆�',
- suggestions: [
- '鍔犲己闇�姹傚垎鏋愰樁娈电殑宸ヤ綔锛屽噺灏戝悗鏈熼渶姹傚彉鏇�',
- '寤虹珛鎶�鏈毦棰橀璀︽満鍒讹紝鎻愬墠璇嗗埆鍜岃В鍐虫妧鏈闄�',
- '浼樺寲鍥㈤槦璧勬簮閰嶇疆锛屾彁楂樻暣浣撳伐浣滄晥鐜�',
- '瀹屽杽椤圭洰绠$悊娴佺▼锛屽姞寮鸿繃绋嬬洃鎺�'
- ]
- }
-}
-
-// 鐢熸垚鎶ュ憡
-const generateReport = async () => {
- if (!reportConfig.projectId) {
- ElMessage.warning('璇烽�夋嫨椤圭洰')
- return
- }
-
- generating.value = true
-
- // 妯℃嫙鐢熸垚鎶ュ憡鐨勮繃绋�
- setTimeout(() => {
- reportData.value = mockReportData
- reportGenerated.value = true
- generating.value = false
- ElMessage.success('鎶ュ憡鐢熸垚鎴愬姛')
- }, 2000)
-}
-
-// 瀵煎嚭鎶ュ憡
-const exportReport = () => {
- ElMessage.success('鎶ュ憡瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-// 閲嶇疆閰嶇疆锛岀敓鎴愭柊鎶ュ憡
-const resetConfig = () => {
- reportGenerated.value = false
- reportData.value = {}
- // 閲嶇疆閰嶇疆涓洪粯璁ゅ��
- reportConfig.projectId = 1
- const endDate = new Date()
- const startDate = new Date()
- startDate.setDate(startDate.getDate() - 30)
- reportConfig.dateRange = [
- startDate.toISOString().split('T')[0],
- endDate.toISOString().split('T')[0]
- ]
- ElMessage.success('宸查噸缃厤缃紝鍙互鐢熸垚鏂版姤鍛�')
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- '宸插畬鎴�': 'success',
- '杩涜涓�': 'warning',
- '鏈紑濮�': 'info',
- '宸叉殏鍋�': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇涓ラ噸绋嬪害绫诲瀷
-const getSeverityType = (severity) => {
- const severityMap = {
- '楂�': 'danger',
- '涓�': 'warning',
- '浣�': 'success'
- }
- return severityMap[severity] || 'info'
-}
-
-// 鑾峰彇缁╂晥绫诲瀷
-const getPerformanceType = (performance) => {
- const performanceMap = {
- '浼樼': 'success',
- '鑹ソ': 'primary',
- '涓�鑸�': 'warning',
- '寰呮敼杩�': 'danger'
- }
- return performanceMap[performance] || 'info'
-}
-
-// 缁勪欢鎸傝浇鏃跺垵濮嬪寲
-onMounted(() => {
- // 璁剧疆榛樿椤圭洰
- reportConfig.projectId = 1
- // 璁剧疆榛樿鏃ユ湡鑼冨洿锛堟渶杩�30澶╋級
- const endDate = new Date()
- const startDate = new Date()
- startDate.setDate(startDate.getDate() - 30)
- reportConfig.dateRange = [
- startDate.toISOString().split('T')[0],
- endDate.toISOString().split('T')[0]
- ]
-})
-</script>
-
-<style scoped>
-.report-generation {
- padding: 20px;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0;
- color: #303133;
-}
-
-.header-actions {
- display: flex;
- gap: 10px;
-}
-
-.config-card {
- margin-bottom: 20px;
-}
-
-.report-content {
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-
-.report-section {
- margin-bottom: 20px;
-}
-
-.completion-stats {
- display: flex;
- justify-content: space-around;
- padding: 20px 0;
-}
-
-.stat-item {
- text-align: center;
-}
-
-.stat-label {
- font-size: 14px;
- color: #909399;
- margin-bottom: 8px;
-}
-
-.stat-value {
- font-size: 24px;
- font-weight: bold;
- color: #303133;
-}
-
-.stat-value.completed {
- color: #67c23a;
-}
-
-.stat-value.in-progress {
- color: #e6a23c;
-}
-
-.stat-value.pending {
- color: #909399;
-}
-
-.completion-rate {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 200px;
-}
-
-.percentage-value {
- font-size: 20px;
- font-weight: bold;
- color: #409eff;
-}
-
-.percentage-label {
- font-size: 12px;
- color: #909399;
- margin-top: 4px;
-}
-
-.issue-summary {
- display: flex;
- flex-direction: column;
- gap: 20px;
- padding: 20px 0;
-}
-
-.summary-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.summary-label {
- font-size: 14px;
- color: #606266;
-}
-
-.summary-value {
- font-size: 18px;
- font-weight: bold;
- color: #303133;
-}
-
-.summary-value.resolved {
- color: #67c23a;
-}
-
-.summary-value.pending {
- color: #e6a23c;
-}
-
-.delay-stats {
- display: flex;
- flex-direction: column;
- gap: 20px;
- padding: 20px 0;
-}
-
-.delay-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.delay-label {
- font-size: 14px;
- color: #606266;
-}
-
-.delay-value {
- font-size: 18px;
- font-weight: bold;
- color: #e6a23c;
-}
-
-.delay-reasons h4 {
- margin: 0 0 15px 0;
- color: #303133;
-}
-
-.delay-reasons ul {
- margin: 0;
- padding-left: 20px;
-}
-
-.delay-reasons li {
- margin-bottom: 8px;
- color: #606266;
-}
-
-.summary-content h4 {
- margin: 0 0 10px 0;
- color: #303133;
-}
-
-.summary-content p {
- line-height: 1.6;
- color: #606266;
- margin-bottom: 20px;
-}
-
-.summary-content ul {
- margin: 0;
- padding-left: 20px;
-}
-
-.summary-content li {
- margin-bottom: 8px;
- color: #606266;
- line-height: 1.5;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/rpaManagement/index.vue b/src/views/collaborativeApproval/rpaManagement/index.vue
deleted file mode 100644
index 9e5b504..0000000
--- a/src/views/collaborativeApproval/rpaManagement/index.vue
+++ /dev/null
@@ -1,366 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">绋嬪簭鍚嶏細</span>
- <el-input
- v-model="searchForm.programName"
- style="width: 240px"
- placeholder="璇疯緭鍏ョ▼搴忓悕鎼滅储"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title ml10">鎵ц鐘舵�侊細</span>
- <el-select v-model="searchForm.status" clearable @change="handleQuery" style="width: 240px">
- <el-option label="杩愯涓�" :value="'running'" />
- <el-option label="宸插仠姝�" :value="'stopped'" />
- <el-option label="寮傚父" :value="'error'" />
- </el-select>
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
- 鎼滅储
- </el-button>
- </div>
- <div>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="openForm('add')">鏂板</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>
-
- <!-- RPA琛ㄥ崟寮圭獥 -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="500px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="formRef"
- :model="form"
- :rules="rules"
- label-width="100px"
- >
- <el-form-item label="绋嬪簭鍚�" prop="programName">
- <el-input
- v-model="form.programName"
- placeholder="璇疯緭鍏ョ▼搴忓悕"
- clearable
- />
- </el-form-item>
- <el-form-item label="鎵ц鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鎵ц鐘舵��" style="width: 100%">
- <el-option label="杩愯涓�" value="running" />
- <el-option label="宸插仠姝�" value="stopped" />
- <el-option label="寮傚父" value="error" />
- </el-select>
- </el-form-item>
- <el-form-item label="鎻忚堪" prop="description">
- <el-input
- v-model="form.description"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏PA绋嬪簭鎻忚堪"
- clearable
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import {listRpa, addRpa, updateRpa, delRpa, delRpaBatch} from "@/api/collaborativeApproval/rpaManagement.js";
-// 鍝嶅簲寮忔暟鎹�
-const data = reactive({
- searchForm: {
- programName: "",
- status: "",
- },
- form: {
- programName: "",
- status: "",
- description: ""
- },
- dialogVisible: false,
- dialogTitle: "",
- dialogType: "add",
- tableLoading: false,
- page: {
- current: 1,
- size: 20,
- total: 0,
- },
- tableData: [],
-});
-
-const { searchForm, form, dialogVisible, dialogTitle, dialogType, selectedIds, tableLoading, page, tableData } = toRefs(data);
-
-// 琛ㄥ崟寮曠敤
-const formRef = ref();
-// 閫夋嫨鐨勮鏁版嵁
-const selectedRows = ref([]);
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- programName: [
- { required: true, message: "璇疯緭鍏ョ▼搴忓悕", trigger: "blur" }
- ],
- status: [
- { required: true, message: "璇烽�夋嫨鎵ц鐘舵��", trigger: "change" }
- ]
-};
-
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumn = ref([
- {
- label: "绋嬪簭鍚�",
- prop: "programName",
- // width: 200,
- },
- {
- label: "鎵ц鐘舵��",
- prop: "status",
- dataType: "tag",
- // width: 120,
- formatData: (params) => {
- const statusMap = {
- running: "杩愯涓�",
- stopped: "宸插仠姝�",
- error: "寮傚父"
- };
- return statusMap[params] || params;
- },
- formatType: (params) => {
- const typeMap = {
- running: "success",
- stopped: "info",
- error: "danger"
- };
- return typeMap[params] || "info";
- }
- },
- {
- label: "鎻忚堪",
- prop: "description",
- // width: 300,
- showOverflowTooltip: true,
- },
- {
- label: "鍒涘缓鏃堕棿",
- prop: "createTime",
- // width: 180,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: "right",
- width: 150,
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- }
- },
- // {
- // name: "寮�濮�",
- // type: "text",
- // clickFun: (row) => {
- // handleStart(row);
- // },
- // disabled: (row) => row.status !== 'stopped'
- // },
- // {
- // name: "鍋滄",
- // type: "text",
- // clickFun: (row) => {
- // handleStop(row);
- // },
- // disabled: (row) => row.status === 'stopped'
- // }
- ]
- }
-]);
-
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- getList();
-});
-
-// 鏌ヨ鏁版嵁
-const handleQuery = () => {
- // page.value.current = 1;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- listRpa({...page.value, ...searchForm.value})
- .then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-
-// 鍒嗛〉澶勭悊
-const pagination = (obj) => {
- page.value.current = obj.page;
- page.value.size = obj.limit;
- handleQuery();
-};
-
-// 閫夋嫨鍙樺寲澶勭悊
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑琛ㄥ崟
-const openForm = (type, row) => {
- dialogType.value = type;
- dialogVisible.value = true;
-
- if (type === "add") {
- dialogTitle.value = "娣诲姞RPA";
- } else {
- dialogTitle.value = "缂栬緫RPA";
- form.value = { ...row };
- }
-};
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- if (!formRef.value) return;
-
- try {
- await formRef.value.validate();
-
- if (dialogType.value === "add") {
- // 娣诲姞鏂癛PA
- addRpa({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- form.value = {
- programName: "",
- status: "",
- description: ""
- },
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } else {
- // 缂栬緫RPA
- updateRpa({...form.value}).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- dialogVisible.value = false;
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- }
- } catch (error) {
- console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
- }
-};
-
-// 寮�濮婻PA
-const handleStart = (row) => {
- ElMessageBox.confirm(`纭畾瑕佸惎鍔≧PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- row.status = "running";
- ElMessage.success("RPA鍚姩鎴愬姛");
- getList();
- }).catch(() => {
- // 鐢ㄦ埛鍙栨秷
- });
-};
-
-// 鍋滄RPA
-const handleStop = (row) => {
- ElMessageBox.confirm(`纭畾瑕佸仠姝PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- row.status = "stopped";
- ElMessage.success("RPA鍋滄鎴愬姛");
- getList();
- }).catch(() => {
- // 鐢ㄦ埛鍙栨秷
- });
-};
-
-// 鍒犻櫎RPA
-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(() => {
- delRpa(ids).then((res) => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭鍔熻兘
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
- proxy.download('/rpaProcessAutomation/export', { ...searchForm.value }, 'RPA绠$悊.xlsx')
-}
-</script>
-
-<style scoped></style>
diff --git a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
deleted file mode 100644
index 4063295..0000000
--- a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
+++ /dev/null
@@ -1,753 +0,0 @@
-<template>
- <div class="app-container">
-
- <!-- 瑙勭珷鍒跺害绠$悊-->
- <el-card class="box-card">
- <template #header>
- <div class="card-header">
- <span>瑙勭珷鍒跺害鍙戝竷</span>
- </div>
- </template>
- <div class="tab-content">
- <el-row :gutter="20" class="mb-20">
- <span class="ml-10">鍒跺害鏍囬锛�</span>
- <el-col :span="6">
- <el-input v-model="regulationSearchForm.title" placeholder="璇疯緭鍏ュ埗搴︽爣棰�" clearable />
- </el-col>
- <span class="search_title">鍒跺害鍒嗙被锛�</span>
- <el-col :span="4">
- <el-select v-model="regulationSearchForm.category" placeholder="鍒跺害鍒嗙被" clearable>
- <el-option label="浜轰簨鍒跺害" value="hr" />
- <el-option label="璐㈠姟鍒跺害" value="finance" />
- <el-option label="瀹夊叏鍒跺害" value="safety" />
- <el-option label="鎶�鏈埗搴�" value="tech" />
- </el-select>
- </el-col>
- <el-col :span="8">
- <el-button type="primary" @click="searchRegulations">鎼滅储</el-button>
- <el-button @click="resetRegulationSearch">閲嶇疆</el-button>
- <el-button @click="handleExport">瀵煎嚭</el-button>
- <el-button type="success" @click="handleAdd">
- 鍙戝竷鍒跺害
- </el-button>
- </el-col>
- </el-row>
-
- <el-table :data="regulations" border v-loading="tableLoading" style="width: 100%">
- <el-table-column prop="regulationNum" label="鍒跺害缂栧彿" width="120" />
- <el-table-column prop="title" label="鍒跺害鏍囬" min-width="150" />
- <el-table-column prop="category" label="鍒嗙被" width="120">
- <template #default="scope">
- <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="version" label="鐗堟湰" width="120" />
- <el-table-column prop="createUserName" label="鍙戝竷浜�" width="120" />
- <el-table-column prop="createTime" label="鍙戝竷鏃堕棿" width="180" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="readCount" label="宸茶浜烘暟" width="100" />
- <el-table-column label="鎿嶄綔" width="250" fixed="right">
- <template #default="scope">
- <el-button link @click="viewRegulation(scope.row)">鏌ョ湅</el-button>
- <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="danger" @click="repealEdit(scope.row)">搴熷純</el-button>
- <el-button link type="success" @click="viewVersionHistory(scope.row)">鐗堟湰鍘嗗彶</el-button>
- <el-button link type="warning" @click="viewReadStatus(scope.row)">闃呰鐘舵��</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-card>
-
- <!-- 鐢ㄥ嵃鐢宠瀵硅瘽妗� -->
- <!-- <el-dialog v-model="showSealApplyDialog" title="鐢宠鐢ㄥ嵃" width="600px">
- <el-form :model="sealForm" :rules="sealRules" ref="sealFormRef" label-width="100px">
- <el-form-item label="鐢宠缂栧彿" prop="applicationNum">
- <el-input v-model="sealForm.applicationNum" placeholder="璇疯緭鍏ョ敵璇风紪鍙�" />
- </el-form-item>
- <el-form-item label="鐢宠鏍囬" prop="title">
- <el-input v-model="sealForm.title" placeholder="璇疯緭鍏ョ敵璇锋爣棰�" />
- </el-form-item>
- <el-form-item label="鐢ㄥ嵃绫诲瀷" prop="sealType">
- <el-select v-model="sealForm.sealType" placeholder="璇烽�夋嫨鐢ㄥ嵃绫诲瀷" style="width: 100%">
- <el-option label="鍏珷" value="official" />
- <el-option label="鍚堝悓涓撶敤绔�" value="contract" />
- <el-option label="璐㈠姟涓撶敤绔�" value="finance" />
- <el-option label="娉曚汉绔�" value="legal" />
- </el-select>
- </el-form-item>
- <el-form-item label="鐢宠鍘熷洜" prop="reason">
- <el-input v-model="sealForm.reason" type="textarea" :rows="4" placeholder="璇疯缁嗚鏄庣敤鍗板師鍥�" />
- </el-form-item>
- <el-form-item label="绱ф�ョ▼搴�" prop="urgency">
- <el-radio-group v-model="sealForm.urgency">
- <el-radio label="normal">鏅��</el-radio>
- <el-radio label="urgent">绱ф��</el-radio>
- <el-radio label="very-urgent">鐗规��</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showSealApplyDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitSealApplication">鎻愪氦鐢宠</el-button>
- </span>
- </template>
- </el-dialog> -->
-
- <!-- 瑙勭珷鍒跺害鍙戝竷瀵硅瘽妗� -->
- <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? '鍙戝竷鍒跺害' : '缂栬緫鍒跺害'" width="800px">
- <el-form :model="regulationForm" :rules="regulationRules" ref="regulationFormRef" label-width="100px">
- <el-form-item label="鍒跺害缂栧彿" prop="regulationNum">
- <el-input v-model="regulationForm.regulationNum" placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
- </el-form-item>
- <el-form-item label="鍒跺害鏍囬" prop="title">
- <el-input v-model="regulationForm.title" placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
- </el-form-item>
- <el-form-item label="鍒跺害鍒嗙被" prop="category">
- <el-select v-model="regulationForm.category" placeholder="璇烽�夋嫨鍒跺害鍒嗙被" style="width: 100%">
- <el-option label="浜轰簨鍒跺害" value="hr" />
- <el-option label="璐㈠姟鍒跺害" value="finance" />
- <el-option label="瀹夊叏鍒跺害" value="safety" />
- <el-option label="鎶�鏈埗搴�" value="tech" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍒跺害鍐呭" prop="content">
- <el-input v-model="regulationForm.content" type="textarea" :rows="10" placeholder="璇疯緭鍏ュ埗搴﹁缁嗗唴瀹�" />
- </el-form-item>
- <el-form-item label="鍒跺害鐗堟湰" prop="version">
- <el-input v-model="regulationForm.version" placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
- </el-form-item>
- <el-form-item label="鐢熸晥鏃堕棿" prop="effectiveTime">
- <el-date-picker v-model="regulationForm.effectiveTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- <el-form-item label="閫傜敤鑼冨洿" prop="scope">
- <el-checkbox-group v-model="regulationForm.scope">
- <el-checkbox label="all">鍏ㄤ綋鍛樺伐</el-checkbox>
- <el-checkbox label="manager">绠$悊灞�</el-checkbox>
- <el-checkbox label="hr">浜轰簨閮ㄩ棬</el-checkbox>
- <el-checkbox label="finance">璐㈠姟閮ㄩ棬</el-checkbox>
- <el-checkbox label="tech">鎶�鏈儴闂�</el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- <el-form-item label="鏄惁闇�瑕佺‘璁�" prop="requireConfirm">
- <el-switch v-model="regulationForm.requireConfirm" />
- <span class="ml-10">寮�鍚悗鍛樺伐闇�瑕侀槄璇荤‘璁�</span>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showRegulationDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitRegulation">鍙戝竷鍒跺害</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 鐢ㄥ嵃璇︽儏瀵硅瘽妗� -->
- <!-- <el-dialog v-model="showSealDetailDialog" title="鐢ㄥ嵃鐢宠璇︽儏" width="700px">
- <div v-if="currentSealDetail" class="mb10">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鐢宠缂栧彿">{{ currentSealDetail.id }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鏍囬">{{ currentSealDetail.title }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentSealDetail.createUserName }}</el-descriptions-item>
- <el-descriptions-item label="鎵�灞為儴闂�">{{ currentSealDetail.department }}</el-descriptions-item>
- <el-descriptions-item label="鐢ㄥ嵃绫诲瀷">{{ getSealTypeText(currentSealDetail.sealType) }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿">{{ currentSealDetail.createTime }}</el-descriptions-item>
- <el-descriptions-item label="鐘舵��">
- <el-tag :type="getStatusType(currentSealDetail.status)">
- {{ getStatusText(currentSealDetail.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鍘熷洜" :span="2">{{ currentSealDetail.reason }}</el-descriptions-item>
- </el-descriptions>
- </div>
- </el-dialog> -->
-
- <!-- 瑙勭珷鍒跺害璇︽儏瀵硅瘽妗� -->
- <el-dialog v-model="showRegulationDetailDialog" title="瑙勭珷鍒跺害璇︽儏" width="800px">
- <div v-if="currentRegulationDetail">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鍒跺害缂栧彿">{{ currentRegulationDetail.id }}</el-descriptions-item>
- <el-descriptions-item label="鍒跺害鏍囬">{{ currentRegulationDetail.title }}</el-descriptions-item>
- <el-descriptions-item label="鍒嗙被">{{ getCategoryText(currentRegulationDetail.category) }}</el-descriptions-item>
- <el-descriptions-item label="鐗堟湰">{{ currentRegulationDetail.version }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷浜�">{{ currentRegulationDetail.createUserName }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鏃堕棿">{{ currentRegulationDetail.createTime }}</el-descriptions-item>
- </el-descriptions>
- <div class="mt-20">
- <h4>鍒跺害鍐呭</h4>
- <div class="regulation-content">{{ currentRegulationDetail.content }}</div>
- </div>
- <!-- 濡傛灉tableData>0 鏄剧ず -->
- <div style="margin: 10px 0;" v-if="tableData && tableData.length > 0" >
- <el-button type="success" @click="resetForm(currentRegulationDetail)">纭鏌ョ湅</el-button>
- </div>
- </div>
- </el-dialog>
-
- <!-- 鐗堟湰鍘嗗彶瀵硅瘽妗� -->
- <el-dialog v-model="showVersionHistoryDialog" title="鐗堟湰鍘嗗彶" width="800px">
- <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px">
- <el-table-column prop="version" label="鐗堟湰鍙�" width="100" />
- <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
- <el-table-column prop="createUserName" label="鏇存柊浜�" width="120" />
- <el-table-column prop="changeLog" label="鍙樻洿璇存槑">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
-
- <!-- 闃呰鐘舵�佸璇濇 -->
- <el-dialog v-model="showReadStatusDialog" title="闃呰鐘舵��" width="800px">
- <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px">
- <el-table-column prop="employee" label="鍛樺伐濮撳悕" width="120" />
- <el-table-column prop="department" label="鎵�灞為儴闂�" width="150" />
- <el-table-column prop="createTime" label="闃呰鏃堕棿" width="180" />
- <el-table-column prop="confirmTime" label="纭鏃堕棿" width="180" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'confirmed' ? 'success' : 'warning'">
- {{ scope.row.status === 'confirmed' ? '宸茬‘璁�' : '鏈‘璁�' }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus } from '@element-plus/icons-vue'
-import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js'
-import { el } from 'element-plus/es/locales.mjs'
-import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import useUserStore from '@/store/modules/user'
-import { userLoginFacotryList } from "@/api/system/user.js"
-
-// 鍝嶅簲寮忔暟鎹�
-const currentUser = ref(null)
-const activeTab = ref('seal')
-const operationType = ref('add')
-const tableData = ref([])
-// 鐢ㄥ嵃鐢宠鐩稿叧
-const userStore = useUserStore()
-const showSealApplyDialog = ref(false)
-const tableLoading = ref(false)
-const showSealDetailDialog = ref(false)
-const currentSealDetail = ref(null)
-const sealFormRef = ref()
-const sealForm = reactive({
- applicationNum: '',
- title: '',
- sealType: '',
- reason: '',
- urgency: 'normal',
- status: 'pending'
-})
-
-const sealRules = {
- applicationNum: [{ required: true, message: '璇疯緭鍏ョ敵璇风紪鍙�', trigger: 'blur' }],
- title: [{ required: true, message: '璇疯緭鍏ョ敵璇锋爣棰�', trigger: 'blur' }],
- sealType: [{ required: true, message: '璇烽�夋嫨鐢ㄥ嵃绫诲瀷', trigger: 'change' }],
- reason: [{ required: true, message: '璇疯緭鍏ョ敵璇峰師鍥�', trigger: 'blur' }]
-}
-
-const sealSearchForm = reactive({
- title: '',
- status: ''
-})
-// 鍒嗛〉鍙傛暟
-const page = reactive({
- current: 1,
- size: 10,
- total: 0
-})
-// 瑙勭珷鍒跺害鐩稿叧
-const showRegulationDialog = ref(false)
-const showRegulationDetailDialog = ref(false)
-const showVersionHistoryDialog = ref(false)
-const showReadStatusDialog = ref(false)
-const currentRegulationDetail = ref(null)
-const regulationFormRef = ref()
-const regulationForm = reactive({
- id: '',
- regulationNum: '',
- title: '',
- category: '',
- content: '',
- version: '',
- status: 'active',
- readCount: 0,
- effectiveTime: '',
- scope: [],
- requireConfirm: false
-})
-
-const readStatus = ref({
- id: '',
- ruleId: '',
- employee: '',
- department: '',
- createTime: '',
- confirmTime: '',
- status: 'unconfirmed'
-})
-
-const regulationRules = {
- title: [{ required: true, message: '璇疯緭鍏ュ埗搴︽爣棰�', trigger: 'blur' }],
- category: [{ required: true, message: '璇烽�夋嫨鍒跺害鍒嗙被', trigger: 'change' }],
- content: [{ required: true, message: '璇疯緭鍏ュ埗搴﹀唴瀹�', trigger: 'blur' }],
- effectiveTime: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃堕棿', trigger: 'change' }],
- scope: [{ required: true, message: '璇烽�夋嫨閫傜敤鑼冨洿', trigger: 'change' }]
-}
-
-const regulationSearchForm = reactive({
- title: '',
- category: ''
-})
-
-// 鍋囨暟鎹�
-const sealApplications = ref([])
-
-const regulations = ref([])
-
-const versionHistory = ref([])
-
-const readStatusList = ref([])
- // { employee: '闄堝織寮�', department: '閿�鍞儴', readTime: '2025-01-11 10:30:00', confirmTime: '2025-01-11 10:35:00', status: 'confirmed' },
- // { employee: '鍒橀泤濠�', department: '鎶�鏈儴', readTime: '2025-01-11 14:20:00', confirmTime: '', status: 'unconfirmed' },
- // { employee: '鐜嬪缓鍥�', department: '璐㈠姟閮�', readTime: '2025-01-12 09:15:00', confirmTime: '2025-01-12 09:20:00', status: 'confirmed' }
-
-// 鐢ㄥ嵃鐢宠鐘舵��
-const getStatusType = (status) => {
- const statusMap = {
- pending: 'warning',
- approved: 'success',
- rejected: 'danger'
- }
- return statusMap[status] || 'info'
-}
-// 鍒跺害鐘舵��
-const getStatusText = (status) => {
- const statusMap = {
- pending: '寰呭鎵�',
- approved: '宸查�氳繃',
- rejected: '宸叉嫆缁�'
- }
- return statusMap[status] || '鏈煡'
-}
-// 鐢ㄥ嵃绫诲瀷
-const getSealTypeText = (sealType) => {
- const sealTypeMap = {
- official: '鍏珷',
- contract: '鍚堝悓涓撶敤绔�',
- finance: '璐㈠姟涓撶敤绔�',
- tegal: '鎶�鏈笓鐢ㄧ珷'
- }
- return sealTypeMap[sealType] || '鏈煡'
-}
-// 鍒跺害鍒嗙被
-const getCategoryText = (category) => {
- const categoryMap = {
- hr: '浜轰簨鍒跺害',
- finance: '璐㈠姟鍒跺害',
- safety: '瀹夊叏鍒跺害',
- tech: '鎶�鏈埗搴�'
- }
- return categoryMap[category] || '鏈煡'
-}
-// 鎼滅储鍗扮珷鐢宠
-const searchSealApplications = () => {
- page.current=1
- getSealApplicationList()
-
- // ElMessage.success('鎼滅储瀹屾垚')
-}
-// 閲嶇疆鍗扮珷鐢宠鎼滅储
-const resetSealSearch = () => {
- sealSearchForm.title = ''
- sealSearchForm.status = ''
- searchSealApplications()
-}
-// 鎼滅储鍒跺害
-const searchRegulations = () => {
- page.current=1
- getRegulationList()
-}
-// 閲嶇疆鍒跺害鎼滅储
-const resetRegulationSearch = () => {
- regulationSearchForm.title = ''
- regulationSearchForm.category = ''
- searchRegulations()
-}
-// 鎻愪氦鐢ㄥ嵃鐢宠
-const submitSealApplication = async () => {
- try {
- await sealFormRef.value.validate()
- addSealApplication(sealForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鐢宠鎻愪氦鎴愬姛')
- showSealApplyDialog.value = false
- getSealApplicationList()
- Object.assign(sealForm, {
- applicationNum: '',
- title: '',
- sealType: '',
- reason: '',
- urgency: 'normal',
- status: 'pending'
- })
- }
- }).catch(err => {
- ElMessage.error(err.msg)
- })
-
- } catch (error) {
- ElMessage.error('璇峰畬鍠勭敵璇蜂俊鎭�')
- }
-}
-// 鏂板
-const handleAdd = () => {
- operationType.value = 'add'
- resetRegulationForm()
- showRegulationDialog.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
- operationType.value = 'edit'
- Object.assign(regulationForm, row)
- showRegulationDialog.value = true
-}
-// 搴熷純
-const repealEdit = (row) => {
- operationType.value = 'edit'
- Object.assign(regulationForm, row)
- regulationForm.status = 'repealed'
- ElMessageBox.confirm('纭搴熷純璇ュ埗搴︼紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- updateRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害搴熷純鎴愬姛')
- // showRegulationDialog.value = false
- getRegulationList()
- resetRegulationForm()
- }
- })
- }).catch(() => {
- ElMessage({
- type: 'info',
- message: '宸插彇娑堝簾寮�'
- })
- })
-}
-// 鍙戝竷鍒跺害
-const submitRegulation = async () => {
- try {
- await regulationFormRef.value.validate()
- if(operationType.value == 'add'){
- addRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害鍙戝竷鎴愬姛')
- showRegulationDialog.value = false
- getRegulationList()
- resetRegulationForm()
- }
- })
- }else{
- updateRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害缂栬緫鎴愬姛')
- showRegulationDialog.value = false
- resetRegulationForm()
- getRegulationList()
- }})}
- }catch(err){
- ElMessage.error(err.msg)
- }
-}
-//閲嶇疆鍒跺害琛ㄥ崟
-const resetRegulationForm = () => {
- Object.assign(regulationForm, {
- id: '',
- regulationNum: '',
- title: '',
- category: '',
- content: '',
- version: '',
- status: 'active',
- readCount: 0,
- effectiveTime: '',
- scope: [],
- requireConfirm: false
-})
-}
-
-
-// 鏌ョ湅鐢ㄥ嵃鐢宠璇︽儏
-const viewSealDetail = (row) => {
- currentSealDetail.value = row
- showSealDetailDialog.value = true
-}
-// 瀹℃壒鐢ㄥ嵃鐢宠
-const approveSeal = (row) => {
- console.log(row)
- ElMessageBox.confirm('纭閫氳繃璇ョ敤鍗扮敵璇凤紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- row.status = 'approved'
- updateSealApplication(row).then(res => {
- if(res.code == 200){
- ElMessage.success('瀹℃壒閫氳繃')
- }
- })
- })
-}
-// 鎷掔粷鐢ㄥ嵃鐢宠
-const rejectSeal = (row) => {
- ElMessageBox.prompt('璇疯緭鍏ユ嫆缁濆師鍥�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- inputPattern: /\S+/,
- inputErrorMessage: '鎷掔粷鍘熷洜涓嶈兘涓虹┖'
- }).then(({ value }) => {
- row.status = 'rejected'
- updateSealApplication(row).then(res => {
- if(res.code == 200){
- ElMessage.success('瀹℃壒鎷掔粷')
- }
- })
- ElMessage.success('宸叉嫆缁濈敵璇�')
- })
-}
-// 鑾峰彇鍦ㄨ亴鍛樺伐鍒楄〃
-const getList = () => {
- tableLoading.value = true;
- //鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛淇℃伅
- getUserProfile().then(res => {
- if(res.code == 200){
- console.log(res.data.userName)
- currentUser.value = res.data.userName
- }
- })
- staffJoinListPage({staffState: 1}).then(res => {
- tableLoading.value = false;
- // tableData.value = res.data.records
- // //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
- tableData.value = res.data.records.filter(item => item.staffName === currentUser.value)
- console.log("tableData",tableData.value)
- page.total = res.data.total;
-
- if(tableData.value.length == 0){
- ElMessage.error('褰撳墠鐢ㄦ埛鏈姞鍏ヤ换浣曢儴闂�')
- }
- }).catch(err => {
- tableLoading.value = false;
- })
-
-
-};
-
-// 鏌ョ湅鍒跺害鐗堟湰鍘嗗彶
-const viewVersionHistory = (row) => {
- showVersionHistoryDialog.value = true
- const params = {
-
- category: row.category
- }
- listRuleManagement(page,params).then(res => {
- if(res.code == 200){
- versionHistory.value = res.data.records
- }
- })
-}
-// 鏌ョ湅鍒跺害璇︽儏
-const viewRegulation = (row) => {
- getList()
- currentRegulationDetail.value = row
- showRegulationDetailDialog.value = true
- getReadingStatusByRuleId(row.id).then(res => {
- if(res.code == 200){
- readStatusList.value = res.data
- if(readStatusList.value.length==0 && tableData.value.length>0){
- const params = {
- ruleId: row.id,
- employee: tableData.value[0].staffName,
- department: tableData.value[0].postJob,
- status: 'unconfirmed'
- }
- addReadingStatus(params).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害闃呰鎴愬姛')
- }
- })
- }
- }
- })
-
-}
-// 鏌ョ湅鍒跺害闃呰鐘舵��
-const viewReadStatus = (row) => {
- showReadStatusDialog.value = true
- //鏌ョ湅闃呰鐘舵�佸垪琛�
- getReadingStatusByRuleId(row.id).then(res => {
- if(res.code == 200){
- readStatusList.value = res.data
- }
- })
-}
-
-//纭鏌ョ湅
-const resetForm = (row) => {
- console.log("row",row)
- row.readCount = row.readCount + 1
-
- updateRuleManagement(row).then(res => {
- if(res.code == 200){
- ElMessage.success('鏌ョ湅鏁伴噺淇敼鎴愬姛')
- //淇敼闃呰鐘舵��
- //鏍规嵁鍒跺害id鍜屽綋鍓嶇櫥褰曠殑鍛樺伐寰楀埌闃呰鐘舵��
- // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName )
- // if(item.length>0){
- // item[0].status = 'confirmed',
- // item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
- // }
- // 绛涢�夊綋鍓嶅憳宸ュ搴旇鍒跺害鐨勯槄璇荤姸鎬佽褰�
- let statusItem = readStatusList.value.find(item => item.employee === tableData.value[0].staffName && item.ruleId === row.id);
-
- if (statusItem) {
- // 濡傛灉鎵惧埌璁板綍锛屾洿鏂扮姸鎬佸拰纭鏃堕棿
- statusItem.status = 'confirmed';
- // 鏍煎紡鍖栨椂闂翠负"YYYY-MM-DD HH:mm:ss"鏍煎紡
- const now = new Date();
- statusItem.confirmTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
- // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
-
- updateReadingStatus(statusItem).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害闃呰鐘舵�佷慨鏀规垚鍔�')
- }
- })
- }
-
- }
- })
-}
-
-// 瀵煎嚭瑙勭珷鍒跺害
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
- proxy.download('/rulesRegulationsManagement/export', { ...regulationSearchForm }, '瑙勭珷鍒跺害.xlsx')
-}
-
-// 鑾峰彇鍗扮珷鐢宠鍒楄〃鏁版嵁
-const getSealApplicationList = async () => {
- tableLoading.value = true
- listSealApplication(page,sealSearchForm)
- .then(res => {
- //鑾峰彇褰撳墠鐧诲綍鐨勯儴闂ㄤ俊鎭�
-// 鑾峰彇褰撳墠鐧诲綍鐨勯儴闂ㄤ俊鎭苟杩囨护鏁版嵁
- const currentFactoryName = userStore.currentFactoryName
- if (currentFactoryName) {
- // 鏍规嵁currentFactoryName杩囨护鍑篸epartment鐩稿悓鐨勬暟鎹�
- sealApplications.value = res.data.records.filter(item => item.department === currentFactoryName)
- // 鏇存柊杩囨护鍚庣殑鎬绘暟
- page.value.total = sealApplications.value.length
- } else {
- // 濡傛灉娌℃湁currentFactoryName锛屽垯鏄剧ず鎵�鏈夋暟鎹�
- sealApplications.value = res.data.records
- page.value.total = res.data.total
- }
- // sealApplications.value = res.data.records
- // page.value.total = res.data.total;
- tableLoading.value = false;
-
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-// 鑾峰彇瑙勭珷鍒跺害鍒楄〃鏁版嵁
-const getRegulationList = async () => {
- tableLoading.value = true
- listRuleManagement(page,regulationSearchForm)
- .then(res => {
-
- regulations.value = res.data.records
- // 杩囨护鎺夊凡搴熷純鐨勫埗搴�
- // regulations.value = res.data.records.filter(item => item.status !== 'repealed')
- page.value.total = res.data.total;
- tableLoading.value = false;
-
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-
-onMounted(() => {
- // 鍒濆鍖�
- getSealApplicationList()
- getRegulationList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.tab-content {
- padding: 20px 0;
-}
-
-.mb-20 {
- margin-bottom: 20px;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.ml-10 {
- margin-left: 10px;
-}
-
-.regulation-content {
- background-color: #f5f5f5;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
- white-space: pre-wrap;
- height: 200px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
deleted file mode 100644
index 88d33dc..0000000
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ /dev/null
@@ -1,764 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <template #header>
- <div class="card-header">
- <span>鐢ㄥ嵃绠$悊鍙戝竷</span>
- </div>
- </template>
-
-
- <!-- 鐢ㄥ嵃鐢宠绠$悊 -->
- <div class="tab-content">
- <el-row :gutter="20" class="mb-20 ">
- <span class="ml-10">鐢ㄥ嵃鏍囬锛�</span>
- <el-col :span="6">
- <el-input v-model="sealSearchForm.title" placeholder="璇疯緭鍏ョ敵璇锋爣棰�" clearable />
- </el-col>
- <span class="search_title">瀹℃壒鐘舵�侊細</span>
- <el-col :span="6">
- <el-select v-model="sealSearchForm.status" placeholder="瀹℃壒鐘舵��" clearable>
- <el-option label="寰呭鎵�" value="pending" />
- <el-option label="宸查�氳繃" value="approved" />
- <el-option label="宸叉嫆缁�" value="rejected" />
- </el-select>
- </el-col>
- <el-col :span="8">
- <el-button type="primary" @click="searchSealApplications">鎼滅储</el-button>
- <el-button @click="resetSealSearch">閲嶇疆</el-button>
- <el-button @click="handleExport">瀵煎嚭</el-button>
- <el-button type="primary" @click="showSealApplyDialog = true">鐢宠鐢ㄥ嵃
- </el-button>
- </el-col>
- </el-row>
-
- <el-table :data="sealApplications" border v-loading="tableLoading" style="width: 100%">
- <el-table-column prop="applicationNum" label="鐢宠缂栧彿" width="120" />
- <el-table-column prop="title" label="鐢宠鏍囬" min-width="200" />
- <el-table-column prop="createUserName" label="鐢宠浜�" width="120" />
- <el-table-column prop="department" label="鎵�灞為儴闂�" width="150" />
- <el-table-column prop="sealType" label="鐢ㄥ嵃绫诲瀷" width="120">
- <template #default="scope">
- {{ getSealTypeText(scope.row.sealType) }}
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鐢宠鏃堕棿" width="180" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right">
- <template #default="scope">
- <el-button link @click="viewSealDetail(scope.row)">鏌ョ湅</el-button>
- <el-button
- v-if="scope.row.status === 'pending'"
- link
- type="primary"
- @click="approveSeal(scope.row)"
- >
- 瀹℃壒
- </el-button>
- <el-button
- v-if="scope.row.status === 'pending'"
- link
- type="danger"
- @click="rejectSeal(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" />
- </div>
- </el-card>
-
- <!-- 鐢ㄥ嵃鐢宠瀵硅瘽妗� -->
- <el-dialog v-model="showSealApplyDialog" title="鐢宠鐢ㄥ嵃" width="600px">
- <el-form :model="sealForm" :rules="sealRules" ref="sealFormRef" label-width="100px">
- <el-form-item label="鐢宠缂栧彿" prop="applicationNum">
- <el-input v-model="sealForm.applicationNum" placeholder="璇疯緭鍏ョ敵璇风紪鍙�" />
- </el-form-item>
- <el-form-item label="鐢宠鏍囬" prop="title">
- <el-input v-model="sealForm.title" placeholder="璇疯緭鍏ョ敵璇锋爣棰�" />
- </el-form-item>
- <el-form-item label="鐢ㄥ嵃绫诲瀷" prop="sealType">
- <el-select v-model="sealForm.sealType" placeholder="璇烽�夋嫨鐢ㄥ嵃绫诲瀷" style="width: 100%">
- <el-option label="鍏珷" value="official" />
- <el-option label="鍚堝悓涓撶敤绔�" value="contract" />
- <el-option label="璐㈠姟涓撶敤绔�" value="finance" />
- <el-option label="娉曚汉绔�" value="legal" />
- </el-select>
- </el-form-item>
- <el-form-item label="鐢宠鍘熷洜" prop="reason">
- <el-input v-model="sealForm.reason" type="textarea" :rows="4" placeholder="璇疯缁嗚鏄庣敤鍗板師鍥�" />
- </el-form-item>
- <el-form-item label="绱ф�ョ▼搴�" prop="urgency">
- <el-radio-group v-model="sealForm.urgency">
- <el-radio label="normal">鏅��</el-radio>
- <el-radio label="urgent">绱ф��</el-radio>
- <el-radio label="very-urgent">鐗规��</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showSealApplyDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitSealApplication">鎻愪氦鐢宠</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 瑙勭珷鍒跺害鍙戝竷瀵硅瘽妗� -->
- <!-- <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? '鍙戝竷鍒跺害' : '缂栬緫鍒跺害'" width="800px">
- <el-form :model="regulationForm" :rules="regulationRules" ref="regulationFormRef" label-width="100px">
- <el-form-item label="鍒跺害缂栧彿" prop="regulationNum">
- <el-input v-model="regulationForm.regulationNum" placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
- </el-form-item>
- <el-form-item label="鍒跺害鏍囬" prop="title">
- <el-input v-model="regulationForm.title" placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
- </el-form-item>
- <el-form-item label="鍒跺害鍒嗙被" prop="category">
- <el-select v-model="regulationForm.category" placeholder="璇烽�夋嫨鍒跺害鍒嗙被" style="width: 100%">
- <el-option label="浜轰簨鍒跺害" value="hr" />
- <el-option label="璐㈠姟鍒跺害" value="finance" />
- <el-option label="瀹夊叏鍒跺害" value="safety" />
- <el-option label="鎶�鏈埗搴�" value="tech" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍒跺害鍐呭" prop="content">
- <el-input v-model="regulationForm.content" type="textarea" :rows="10" placeholder="璇疯緭鍏ュ埗搴﹁缁嗗唴瀹�" />
- </el-form-item>
- <el-form-item label="鍒跺害鐗堟湰" prop="version">
- <el-input v-model="regulationForm.version" placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
- </el-form-item>
- <el-form-item label="鐢熸晥鏃堕棿" prop="effectiveTime">
- <el-date-picker v-model="regulationForm.effectiveTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- <el-form-item label="閫傜敤鑼冨洿" prop="scope">
- <el-checkbox-group v-model="regulationForm.scope">
- <el-checkbox label="all">鍏ㄤ綋鍛樺伐</el-checkbox>
- <el-checkbox label="manager">绠$悊灞�</el-checkbox>
- <el-checkbox label="hr">浜轰簨閮ㄩ棬</el-checkbox>
- <el-checkbox label="finance">璐㈠姟閮ㄩ棬</el-checkbox>
- <el-checkbox label="tech">鎶�鏈儴闂�</el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- <el-form-item label="鏄惁闇�瑕佺‘璁�" prop="requireConfirm">
- <el-switch v-model="regulationForm.requireConfirm" />
- <span class="ml-10">寮�鍚悗鍛樺伐闇�瑕侀槄璇荤‘璁�</span>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showRegulationDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitRegulation">鍙戝竷鍒跺害</el-button>
- </span>
- </template>
- </el-dialog> -->
-
- <!-- 鐢ㄥ嵃璇︽儏瀵硅瘽妗� -->
- <el-dialog v-model="showSealDetailDialog" title="鐢ㄥ嵃鐢宠璇︽儏" width="700px">
- <div v-if="currentSealDetail" class="mb10">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鐢宠缂栧彿">{{ currentSealDetail.id }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鏍囬">{{ currentSealDetail.title }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠浜�">{{ currentSealDetail.createUserName }}</el-descriptions-item>
- <el-descriptions-item label="鎵�灞為儴闂�">{{ currentSealDetail.department }}</el-descriptions-item>
- <el-descriptions-item label="鐢ㄥ嵃绫诲瀷">{{ getSealTypeText(currentSealDetail.sealType) }}</el-descriptions-item>
- <el-descriptions-item label="鐢宠鏃堕棿">{{ currentSealDetail.createTime }}</el-descriptions-item>
- <el-descriptions-item label="鐘舵��">
- <el-tag :type="getStatusType(currentSealDetail.status)">
- {{ getStatusText(currentSealDetail.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐢宠鍘熷洜" :span="2">{{ currentSealDetail.reason }}</el-descriptions-item>
- </el-descriptions>
- </div>
- </el-dialog>
-
- <!-- 瑙勭珷鍒跺害璇︽儏瀵硅瘽妗� -->
- <el-dialog v-model="showRegulationDetailDialog" title="瑙勭珷鍒跺害璇︽儏" width="800px">
- <div v-if="currentRegulationDetail">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鍒跺害缂栧彿">{{ currentRegulationDetail.id }}</el-descriptions-item>
- <el-descriptions-item label="鍒跺害鏍囬">{{ currentRegulationDetail.title }}</el-descriptions-item>
- <el-descriptions-item label="鍒嗙被">{{ getCategoryText(currentRegulationDetail.category) }}</el-descriptions-item>
- <el-descriptions-item label="鐗堟湰">{{ currentRegulationDetail.version }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷浜�">{{ currentRegulationDetail.createUserName }}</el-descriptions-item>
- <el-descriptions-item label="鍙戝竷鏃堕棿">{{ currentRegulationDetail.createTime }}</el-descriptions-item>
- </el-descriptions>
- <div class="mt-20">
- <h4>鍒跺害鍐呭</h4>
- <div class="regulation-content">{{ currentRegulationDetail.content }}</div>
- </div>
- <!-- 濡傛灉tableData>0 鏄剧ず -->
- <div style="margin: 10px 0;" v-if="tableData && tableData.length > 0" >
- <el-button type="success" @click="resetForm(currentRegulationDetail)">纭鏌ョ湅</el-button>
- </div>
- </div>
- </el-dialog>
-
- <!-- 鐗堟湰鍘嗗彶瀵硅瘽妗� -->
- <el-dialog v-model="showVersionHistoryDialog" title="鐗堟湰鍘嗗彶" width="800px">
- <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px">
- <el-table-column prop="version" label="鐗堟湰鍙�" width="100" />
- <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
- <el-table-column prop="createUserName" label="鏇存柊浜�" width="120" />
- <el-table-column prop="changeLog" label="鍙樻洿璇存槑">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '鐢熸晥涓�' : '宸插簾姝�' }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
-
- <!-- 闃呰鐘舵�佸璇濇 -->
- <el-dialog v-model="showReadStatusDialog" title="闃呰鐘舵��" width="800px">
- <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px">
- <el-table-column prop="employee" label="鍛樺伐濮撳悕" width="120" />
- <el-table-column prop="department" label="鎵�灞為儴闂�" width="150" />
- <el-table-column prop="createTime" label="闃呰鏃堕棿" width="180" />
- <el-table-column prop="confirmTime" label="纭鏃堕棿" width="180" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'confirmed' ? 'success' : 'warning'">
- {{ scope.row.status === 'confirmed' ? '宸茬‘璁�' : '鏈‘璁�' }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus } from '@element-plus/icons-vue'
-import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js'
-import { el } from 'element-plus/es/locales.mjs'
-import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import useUserStore from '@/store/modules/user'
-import { userLoginFacotryList } from "@/api/system/user.js"
-
-// 鍝嶅簲寮忔暟鎹�
-const currentUser = ref(null)
-const activeTab = ref('seal')
-const operationType = ref('add')
-const tableData = ref([])
-// 鐢ㄥ嵃鐢宠鐩稿叧
-const userStore = useUserStore()
-const showSealApplyDialog = ref(false)
-const tableLoading = ref(false)
-const showSealDetailDialog = ref(false)
-const currentSealDetail = ref(null)
-const sealFormRef = ref()
-const sealForm = reactive({
- applicationNum: '',
- title: '',
- sealType: '',
- reason: '',
- urgency: 'normal',
- status: 'pending'
-})
-
-const sealRules = {
- applicationNum: [{ required: true, message: '璇疯緭鍏ョ敵璇风紪鍙�', trigger: 'blur' }],
- title: [{ required: true, message: '璇疯緭鍏ョ敵璇锋爣棰�', trigger: 'blur' }],
- sealType: [{ required: true, message: '璇烽�夋嫨鐢ㄥ嵃绫诲瀷', trigger: 'change' }],
- reason: [{ required: true, message: '璇疯緭鍏ョ敵璇峰師鍥�', trigger: 'blur' }]
-}
-
-const sealSearchForm = reactive({
- title: '',
- status: ''
-})
-// 鍒嗛〉鍙傛暟
-const page = reactive({
- current: 1,
- size: 100,
- total: 0
-})
-// 瑙勭珷鍒跺害鐩稿叧
-const showRegulationDialog = ref(false)
-const showRegulationDetailDialog = ref(false)
-const showVersionHistoryDialog = ref(false)
-const showReadStatusDialog = ref(false)
-const currentRegulationDetail = ref(null)
-const regulationFormRef = ref()
-const regulationForm = reactive({
- id: '',
- regulationNum: '',
- title: '',
- category: '',
- content: '',
- version: '',
- status: 'active',
- readCount: 0,
- effectiveTime: '',
- scope: [],
- requireConfirm: false
-})
-
-const readStatus = ref({
- id: '',
- ruleId: '',
- employee: '',
- department: '',
- createTime: '',
- confirmTime: '',
- status: 'unconfirmed'
-})
-
-const regulationRules = {
- title: [{ required: true, message: '璇疯緭鍏ュ埗搴︽爣棰�', trigger: 'blur' }],
- category: [{ required: true, message: '璇烽�夋嫨鍒跺害鍒嗙被', trigger: 'change' }],
- content: [{ required: true, message: '璇疯緭鍏ュ埗搴﹀唴瀹�', trigger: 'blur' }],
- effectiveTime: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃堕棿', trigger: 'change' }],
- scope: [{ required: true, message: '璇烽�夋嫨閫傜敤鑼冨洿', trigger: 'change' }]
-}
-
-const regulationSearchForm = reactive({
- title: '',
- category: ''
-})
-
-// 鍋囨暟鎹�
-const sealApplications = ref([])
-
-const regulations = ref([])
-
-const versionHistory = ref([])
-
-const readStatusList = ref([])
- // { employee: '闄堝織寮�', department: '閿�鍞儴', readTime: '2025-01-11 10:30:00', confirmTime: '2025-01-11 10:35:00', status: 'confirmed' },
- // { employee: '鍒橀泤濠�', department: '鎶�鏈儴', readTime: '2025-01-11 14:20:00', confirmTime: '', status: 'unconfirmed' },
- // { employee: '鐜嬪缓鍥�', department: '璐㈠姟閮�', readTime: '2025-01-12 09:15:00', confirmTime: '2025-01-12 09:20:00', status: 'confirmed' }
-
-// 鐢ㄥ嵃鐢宠鐘舵��
-const getStatusType = (status) => {
- const statusMap = {
- pending: 'warning',
- approved: 'success',
- rejected: 'danger'
- }
- return statusMap[status] || 'info'
-}
-// 鍒跺害鐘舵��
-const getStatusText = (status) => {
- const statusMap = {
- pending: '寰呭鎵�',
- approved: '宸查�氳繃',
- rejected: '宸叉嫆缁�'
- }
- return statusMap[status] || '鏈煡'
-}
-// 鐢ㄥ嵃绫诲瀷
-const getSealTypeText = (sealType) => {
- const sealTypeMap = {
- official: '鍏珷',
- contract: '鍚堝悓涓撶敤绔�',
- finance: '璐㈠姟涓撶敤绔�',
- tegal: '鎶�鏈笓鐢ㄧ珷'
- }
- return sealTypeMap[sealType] || '鏈煡'
-}
-// 鍒跺害鍒嗙被
-const getCategoryText = (category) => {
- const categoryMap = {
- hr: '浜轰簨鍒跺害',
- finance: '璐㈠姟鍒跺害',
- safety: '瀹夊叏鍒跺害',
- tech: '鎶�鏈埗搴�'
- }
- return categoryMap[category] || '鏈煡'
-}
-// 鎼滅储鍗扮珷鐢宠
-const searchSealApplications = () => {
- page.current=1
- getSealApplicationList()
-
- // ElMessage.success('鎼滅储瀹屾垚')
-}
-// 閲嶇疆鍗扮珷鐢宠鎼滅储
-const resetSealSearch = () => {
- sealSearchForm.title = ''
- sealSearchForm.status = ''
- searchSealApplications()
-}
-// 鎼滅储鍒跺害
-const searchRegulations = () => {
- page.current=1
- getRegulationList()
-}
-// 閲嶇疆鍒跺害鎼滅储
-const resetRegulationSearch = () => {
- regulationSearchForm.title = ''
- regulationSearchForm.category = ''
- searchRegulations()
-}
-// 鎻愪氦鐢ㄥ嵃鐢宠
-const submitSealApplication = async () => {
- try {
- await sealFormRef.value.validate()
- addSealApplication(sealForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鐢宠鎻愪氦鎴愬姛')
- showSealApplyDialog.value = false
- getSealApplicationList()
- Object.assign(sealForm, {
- applicationNum: '',
- title: '',
- sealType: '',
- reason: '',
- urgency: 'normal',
- status: 'pending'
- })
- }
- }).catch(err => {
- ElMessage.error(err.msg)
- })
-
- } catch (error) {
- ElMessage.error('璇峰畬鍠勭敵璇蜂俊鎭�')
- }
-}
-// 鏂板
-const handleAdd = () => {
- operationType.value = 'add'
- resetRegulationForm()
- showRegulationDialog.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
- operationType.value = 'edit'
- Object.assign(regulationForm, row)
- showRegulationDialog.value = true
-}
-// 搴熷純
-const repealEdit = (row) => {
- operationType.value = 'edit'
- Object.assign(regulationForm, row)
- regulationForm.status = 'repealed'
- ElMessageBox.confirm('纭搴熷純璇ュ埗搴︼紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- updateRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害搴熷純鎴愬姛')
- // showRegulationDialog.value = false
- getRegulationList()
- resetRegulationForm()
- }
- })
- }).catch(() => {
- ElMessage({
- type: 'info',
- message: '宸插彇娑堝簾寮�'
- })
- })
-}
-// 鍙戝竷鍒跺害
-const submitRegulation = async () => {
- try {
- await regulationFormRef.value.validate()
- if(operationType.value == 'add'){
- addRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害鍙戝竷鎴愬姛')
- showRegulationDialog.value = false
- getRegulationList()
- resetRegulationForm()
- }
- })
- }else{
- updateRuleManagement(regulationForm).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害缂栬緫鎴愬姛')
- showRegulationDialog.value = false
- resetRegulationForm()
- getRegulationList()
- }})}
- }catch(err){
- ElMessage.error(err.msg)
- }
-}
-//閲嶇疆鍒跺害琛ㄥ崟
-const resetRegulationForm = () => {
- Object.assign(regulationForm, {
- id: '',
- regulationNum: '',
- title: '',
- category: '',
- content: '',
- version: '',
- status: 'active',
- readCount: 0,
- effectiveTime: '',
- scope: [],
- requireConfirm: false
-})
-}
-
-
-// 鏌ョ湅鐢ㄥ嵃鐢宠璇︽儏
-const viewSealDetail = (row) => {
- currentSealDetail.value = row
- showSealDetailDialog.value = true
-}
-// 瀹℃壒鐢ㄥ嵃鐢宠
-const approveSeal = (row) => {
- console.log(row)
- ElMessageBox.confirm('纭閫氳繃璇ョ敤鍗扮敵璇凤紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- row.status = 'approved'
- updateSealApplication(row).then(res => {
- if(res.code == 200){
- ElMessage.success('瀹℃壒閫氳繃')
- }
- })
- })
-}
-// 鎷掔粷鐢ㄥ嵃鐢宠
-const rejectSeal = (row) => {
- ElMessageBox.prompt('璇疯緭鍏ユ嫆缁濆師鍥�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- inputPattern: /\S+/,
- inputErrorMessage: '鎷掔粷鍘熷洜涓嶈兘涓虹┖'
- }).then(({ value }) => {
- row.status = 'rejected'
- updateSealApplication(row).then(res => {
- if(res.code == 200){
- ElMessage.success('瀹℃壒鎷掔粷')
- }
- })
- ElMessage.success('宸叉嫆缁濈敵璇�')
- })
-}
-// 鑾峰彇鍦ㄨ亴鍛樺伐鍒楄〃
-const getList = () => {
- tableLoading.value = true;
- //鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛淇℃伅
- getUserProfile().then(res => {
- if(res.code == 200){
- console.log(res.data.userName)
- currentUser.value = res.data.userName
- }
- })
- staffJoinListPage({staffState: 1, ...page}).then(res => {
- tableLoading.value = false;
- // tableData.value = res.data.records
- // //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
- tableData.value = res.data.records.filter(item => item.staffName === currentUser.value)
- page.total = res.data.total;
-
- if(tableData.value.length == 0){
- ElMessage.error('褰撳墠鐢ㄦ埛鏈姞鍏ヤ换浣曢儴闂�')
- }
- }).catch(err => {
- tableLoading.value = false;
- })
-
-
-};
-
-// 鏌ョ湅鍒跺害鐗堟湰鍘嗗彶
-const viewVersionHistory = (row) => {
- showVersionHistoryDialog.value = true
- const params = {
-
- category: row.category
- }
- listRuleManagement(page,params).then(res => {
- if(res.code == 200){
- versionHistory.value = res.data.records
- }
- })
-}
-// 鏌ョ湅鍒跺害璇︽儏
-const viewRegulation = (row) => {
- getList()
- currentRegulationDetail.value = row
- showRegulationDetailDialog.value = true
- getReadingStatusByRuleId(row.id).then(res => {
- if(res.code == 200){
- readStatusList.value = res.data
- if(readStatusList.value.length==0 && tableData.value.length>0){
- const params = {
- ruleId: row.id,
- employee: tableData.value[0].staffName,
- department: tableData.value[0].postJob,
- status: 'unconfirmed'
- }
- addReadingStatus(params).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害闃呰鎴愬姛')
- }
- })
- }
- }
- })
-
-}
-// 鏌ョ湅鍒跺害闃呰鐘舵��
-const viewReadStatus = (row) => {
- showReadStatusDialog.value = true
- //鏌ョ湅闃呰鐘舵�佸垪琛�
- getReadingStatusByRuleId(row.id).then(res => {
- if(res.code == 200){
- readStatusList.value = res.data
- }
- })
-}
-
-//纭鏌ョ湅
-const resetForm = (row) => {
- console.log("row",row)
- row.readCount = row.readCount + 1
-
- updateRuleManagement(row).then(res => {
- if(res.code == 200){
- ElMessage.success('鏌ョ湅鏁伴噺淇敼鎴愬姛')
- //淇敼闃呰鐘舵��
- //鏍规嵁鍒跺害id鍜屽綋鍓嶇櫥褰曠殑鍛樺伐寰楀埌闃呰鐘舵��
- // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName )
- // if(item.length>0){
- // item[0].status = 'confirmed',
- // item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
- // }
- // 绛涢�夊綋鍓嶅憳宸ュ搴旇鍒跺害鐨勯槄璇荤姸鎬佽褰�
- let statusItem = readStatusList.value.find(item => item.employee === tableData.value[0].staffName && item.ruleId === row.id);
-
- if (statusItem) {
- // 濡傛灉鎵惧埌璁板綍锛屾洿鏂扮姸鎬佸拰纭鏃堕棿
- statusItem.status = 'confirmed';
- // 鏍煎紡鍖栨椂闂翠负"YYYY-MM-DD HH:mm:ss"鏍煎紡
- const now = new Date();
- statusItem.confirmTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
- // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0];
-
- updateReadingStatus(statusItem).then(res => {
- if(res.code == 200){
- ElMessage.success('鍒跺害闃呰鐘舵�佷慨鏀规垚鍔�')
- }
- })
- }
-
- }
- })
-}
-
-// 瀵煎嚭鐢ㄥ嵃鐢宠
-const { proxy } = getCurrentInstance()
-const handleExport = () => {
- proxy.download('/sealApplicationManagement/export', { ...sealSearchForm }, '鐢ㄥ嵃鐢宠.xlsx')
-}
-
-// 鑾峰彇鍗扮珷鐢宠鍒楄〃鏁版嵁
-const getSealApplicationList = async () => {
- tableLoading.value = true
- listSealApplication(page,sealSearchForm)
- .then(res => {
- //鑾峰彇褰撳墠鐧诲綍鐨勯儴闂ㄤ俊鎭�
-// 鑾峰彇褰撳墠鐧诲綍鐨勯儴闂ㄤ俊鎭苟杩囨护鏁版嵁
- const currentFactoryName = userStore.currentFactoryName
- if (currentFactoryName) {
- // 鏍规嵁currentFactoryName杩囨护鍑篸epartment鐩稿悓鐨勬暟鎹�
- sealApplications.value = res.data.records.filter(item => item.department === currentFactoryName)
- // 鏇存柊杩囨护鍚庣殑鎬绘暟
- page.total = sealApplications.value.length
- } else {
- // 濡傛灉娌℃湁currentFactoryName锛屽垯鏄剧ず鎵�鏈夋暟鎹�
- sealApplications.value = res.data.records
- page.total = res.data.total
- }
- // sealApplications.value = res.data.records
- // page.value.total = res.data.total;
- tableLoading.value = false;
-
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-// 鑾峰彇瑙勭珷鍒跺害鍒楄〃鏁版嵁
-const getRegulationList = async () => {
- tableLoading.value = true
- listRuleManagement(page,regulationSearchForm)
- .then(res => {
-
- regulations.value = res.data.records
- // 杩囨护鎺夊凡搴熷純鐨勫埗搴�
- // regulations.value = res.data.records.filter(item => item.status !== 'repealed')
- page.total = res.data.total;
- tableLoading.value = false;
-
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-
-onMounted(() => {
- // 鍒濆鍖�
- getSealApplicationList()
- getRegulationList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.tab-content {
- padding: 20px 0;
-}
-
-.mb-20 {
- margin-bottom: 20px;
-}
-
-.mt-20 {
- margin-top: 20px;
-}
-
-.ml-10 {
- margin-left: 10px;
-}
-
-.regulation-content {
- background-color: #f5f5f5;
- padding: 15px;
- border-radius: 4px;
- line-height: 1.6;
- white-space: pre-wrap;
- height: 200px;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-</style>
diff --git a/src/views/collaborativeApproval/warningSystem/index.vue b/src/views/collaborativeApproval/warningSystem/index.vue
deleted file mode 100644
index ddab6c0..0000000
--- a/src/views/collaborativeApproval/warningSystem/index.vue
+++ /dev/null
@@ -1,305 +0,0 @@
-<template>
- <div class="warning-system">
- <h2>棰勮鑱斿姩鏈哄埗</h2>
-
- <!-- 缁熻鍗$墖 -->
- <div class="stats">
- <div class="stat-card red">
- <span class="number">2</span>
- <span class="label">绾㈣壊棰勮</span>
- </div>
- <div class="stat-card orange">
- <span class="number">1</span>
- <span class="label">姗欒壊棰勮</span>
- </div>
- <div class="stat-card yellow">
- <span class="number">1</span>
- <span class="label">榛勮壊棰勮</span>
- </div>
- <div class="stat-card green">
- <span class="number">1</span>
- <span class="label">缁胯壊棰勮</span>
- </div>
- </div>
-
- <!-- 棰勮鍒楄〃 -->
- <div class="warning-list">
- <h3>棰勮鍒楄〃</h3>
- <table>
- <thead>
- <tr>
- <th>缂栧彿</th>
- <th>鏍囬</th>
- <th>绫诲瀷</th>
- <th>绛夌骇</th>
- <th>鐘舵��</th>
- <th>鎿嶄綔</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="warning in warnings" :key="warning.id">
- <td>{{ warning.id }}</td>
- <td>{{ warning.title }}</td>
- <td>{{ warning.type }}</td>
- <td>
- <span :class="['level-tag', warning.level]">
- {{ warning.levelText }}
- </span>
- </td>
- <td>
- <span :class="['status-tag', warning.status]">
- {{ warning.statusText }}
- </span>
- </td>
- <td>
- <button @click="viewDetail(warning)">鏌ョ湅璇︽儏</button>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <!-- 璇︽儏瀵硅瘽妗� -->
- <div v-if="showDetail" class="modal">
- <div class="modal-content">
- <h3>棰勮璇︽儏</h3>
- <div v-if="currentWarning">
- <p><strong>缂栧彿锛�</strong>{{ currentWarning.id }}</p>
- <p><strong>鏍囬锛�</strong>{{ currentWarning.title }}</p>
- <p><strong>绫诲瀷锛�</strong>{{ currentWarning.type }}</p>
- <p><strong>绛夌骇锛�</strong>{{ currentWarning.levelText }}</p>
- <p><strong>鎻忚堪锛�</strong>{{ currentWarning.description }}</p>
- <p><strong>褰卞搷锛�</strong>{{ currentWarning.impact }}</p>
- <p><strong>寤鸿锛�</strong>{{ currentWarning.suggestions }}</p>
- </div>
- <button @click="showDetail = false">鍏抽棴</button>
- </div>
- </div>
- </div>
-</template>
-
-<script>
-export default {
- name: 'WarningSystem',
- data() {
- return {
- showDetail: false,
- currentWarning: null,
- warnings: [
- {
- id: 'W001',
- title: '椤圭洰棰勭畻瓒呮敮棰勮',
- type: '璐㈠姟棰勮',
- level: 'red',
- levelText: '绾㈣壊棰勮',
- status: 'pending',
- statusText: '寰呭鐞�',
- responsible: '闄堝織寮�',
- description: 'A椤圭洰棰勭畻鎵ц鐜囧凡杈�95%锛岄璁″皢瓒呭嚭棰勭畻鑼冨洿銆�',
- impact: '褰卞搷椤圭洰鏁翠綋璐㈠姟鎸囨爣锛屽彲鑳藉鑷撮」鐩簭鎹�',
- suggestions: '鏆傚仠闈炲繀瑕佹敮鍑猴紝浼樺寲璧勬簮閰嶇疆锛岀敵璇烽绠楄皟鏁�'
- },
- {
- id: 'W002',
- title: '鍚堝悓鍒版湡棰勮',
- type: '鍚堣棰勮',
- level: 'orange',
- levelText: '姗欒壊棰勮',
- status: 'processing',
- statusText: '澶勭悊涓�',
- responsible: '鏉庝富绠�',
- description: '涓庝緵搴斿晢B鐨勫悎鍚屽皢浜�2024骞�1鏈�25鏃ュ埌鏈熴��',
- impact: '褰卞搷渚涘簲閾剧ǔ瀹氭�э紝鍙兘瀵艰嚧鏈嶅姟涓柇',
- suggestions: '璇勪及渚涘簲鍟嗚〃鐜帮紝鍑嗗缁鏉愭枡锛屽埗瀹氬閫夋柟妗�'
- },
- {
- id: 'W003',
- title: '璁惧缁存姢棰勮',
- type: '杩愯惀棰勮',
- level: 'yellow',
- levelText: '榛勮壊棰勮',
- status: 'pending',
- statusText: '寰呭鐞�',
- responsible: '鐜嬪伐绋嬪笀',
- description: '鐢熶骇绾胯澶嘋宸茶繍琛�8000灏忔椂锛屾帴杩戠淮鎶ゅ懆鏈熴��',
- impact: '鍙兘褰卞搷鐢熶骇鏁堢巼鍜屼骇鍝佽川閲�',
- suggestions: '瀹夋帓缁存姢鏃堕棿锛屽噯澶囧浠讹紝鍒跺畾缁存姢璁″垝'
- },
- {
- id: 'W004',
- title: '浜哄憳閰嶇疆棰勮',
- type: '杩愯惀棰勮',
- level: 'green',
- levelText: '缁胯壊棰勮',
- status: 'resolved',
- statusText: '宸茶В鍐�',
- responsible: '璧礖R',
- description: '鎶�鏈儴闂ㄤ汉鍛橀厤缃厖瓒筹紝椤圭洰杩涘害姝e父銆�',
- impact: '鏃犺礋闈㈠奖鍝�',
- suggestions: '缁х画鐩戞帶浜哄憳閰嶇疆鎯呭喌'
- },
- {
- id: 'W005',
- title: '璐ㄩ噺浜嬫晠棰勮',
- type: '杩愯惀棰勮',
- level: 'red',
- levelText: '绾㈣壊棰勮',
- status: 'pending',
- statusText: '寰呭鐞�',
- responsible: '闄堝織寮�',
- description: '浜у搧D鍦ㄥ鎴风幇鍦哄嚭鐜拌川閲忛棶棰樸��',
- impact: '褰卞搷瀹㈡埛婊℃剰搴︼紝鍙兘閫犳垚缁忔祹鎹熷け',
- suggestions: '绔嬪嵆鍙洖闂浜у搧锛屽垎鏋愬師鍥狅紝鍒跺畾鏀硅繘鎺柦'
- }
- ]
- }
- },
- methods: {
- viewDetail(warning) {
- this.currentWarning = warning
- this.showDetail = true
- }
- }
-}
-</script>
-
-<style scoped>
-.warning-system {
- padding: 20px;
- max-width: 1200px;
- margin: 0 auto;
-}
-
-h2 {
- color: #333;
- margin-bottom: 30px;
-}
-
-.stats {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- gap: 20px;
- margin-bottom: 30px;
-}
-
-.stat-card {
- padding: 20px;
- border-radius: 8px;
- color: white;
- text-align: center;
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-}
-
-.stat-card.red { background: linear-gradient(135deg, #ff6b6b, #ee5a52); }
-.stat-card.orange { background: linear-gradient(135deg, #ffa726, #ff9800); }
-.stat-card.yellow { background: linear-gradient(135deg, #ffd54f, #ffc107); }
-.stat-card.green { background: linear-gradient(135deg, #66bb6a, #4caf50); }
-
-.stat-card .number {
- display: block;
- font-size: 32px;
- font-weight: bold;
- margin-bottom: 8px;
-}
-
-.stat-card .label {
- font-size: 14px;
- opacity: 0.9;
-}
-
-.warning-list h3 {
- margin-bottom: 20px;
- color: #333;
-}
-
-table {
- width: 100%;
- border-collapse: collapse;
- background: white;
- border-radius: 8px;
- overflow: hidden;
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-}
-
-th, td {
- padding: 12px;
- text-align: left;
- border-bottom: 1px solid #eee;
-}
-
-th {
- background: #f8f9fa;
- font-weight: 600;
- color: #333;
-}
-
-.level-tag, .status-tag {
- padding: 4px 8px;
- border-radius: 4px;
- font-size: 12px;
- color: white;
-}
-
-.level-tag.red { background: #f56c6c; }
-.level-tag.orange { background: #e6a23c; }
-.level-tag.yellow { background: #e6a23c; }
-.level-tag.green { background: #67c23a; }
-
-.status-tag.pending { background: #f56c6c; }
-.status-tag.processing { background: #e6a23c; }
-.status-tag.resolved { background: #67c23a; }
-
-button {
- padding: 6px 12px;
- margin: 0 4px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 12px;
- background: #409eff;
- color: white;
-}
-
-.modal {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0,0,0,0.5);
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.modal-content {
- background: white;
- padding: 30px;
- border-radius: 8px;
- max-width: 600px;
- width: 90%;
- max-height: 80vh;
- overflow-y: auto;
-}
-
-.modal-content h3 {
- margin-bottom: 20px;
- color: #333;
-}
-
-.modal-content p {
- margin-bottom: 15px;
- line-height: 1.6;
-}
-
-.modal-content strong {
- color: #333;
-}
-
-.modal-content button {
- background: #409eff;
- color: white;
- padding: 10px 20px;
- font-size: 14px;
-}
-</style>
diff --git a/src/views/customerService/afterSalesHandling/components/formDia.vue b/src/views/customerService/afterSalesHandling/components/formDia.vue
deleted file mode 100644
index cfdb01c..0000000
--- a/src/views/customerService/afterSalesHandling/components/formDia.vue
+++ /dev/null
@@ -1,212 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="鍞悗澶勭悊"
- width="70%"
- @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="feedbackDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.feedbackDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐧昏浜猴細" prop="checkUserId">
- <el-select
- v-model="form.checkUserId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="闂鎻忚堪锛�" prop="proDesc">
- <el-input
- v-model="form.proDesc"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- type="textarea"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="澶勭悊缁撴灉锛�" prop="disRes">
- <el-input
- v-model="form.disRes"
- placeholder="璇疯緭鍏�"
- clearable
- :disabled="operationType === 'view'"
- type="textarea"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="澶勭悊浜猴細" prop="disposeUserId">
- <el-select
- v-model="form.disposeUserId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="澶勭悊鏃堕棿锛�" prop="disDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.disDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import {afterSalesServiceAdd, afterSalesServiceDispose, afterSalesServiceUpdate} from "@/api/customerService/index.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- feedbackDate: "",
- checkUserId: "",
- customerName: "",
- proDesc: "",
- disposeUserId: "",
- disDate: "",
- disRes: "",
- },
- rules: {
- feedbackDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- checkUserId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- customerName: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- proDesc: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- disRes: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- disposeUserId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- disDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- }
-})
-const { form, rules } = toRefs(data);
-const userList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- form.value = {...row}
- form.value.disposeUserId = userStore.id;
- form.value.disDate = getCurrentDate();
-}
-// const setName = (code) => {
-// const index = userList.value.findIndex(item => item.deviceModel === code);
-// if (index > -1) {
-// console.log(userList)
-// form.value.name = userList.value[index].deviceName;
-// }
-// }
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- afterSalesServiceDispose(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- })
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/customerService/afterSalesHandling/index.vue b/src/views/customerService/afterSalesHandling/index.vue
deleted file mode 100644
index 65a7551..0000000
--- a/src/views/customerService/afterSalesHandling/index.vue
+++ /dev/null
@@ -1,252 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鍙嶉鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.feedbackDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- @change="handleQuery"
- />
- <span class="search_title ml10">澶勭悊鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.disDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- @change="handleQuery"
- />
- <span style = "margin-left: 10px;" class="search_title">澶勭悊鐘舵�侊細</span>
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 140px" clearable>
- <el-option label="寰呭鐞�" :value="1"></el-option>
- <el-option label="宸插鐞�" :value="2"></el-option>
- </el-select>
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- <el-button @click="handleOut" style="margin-left: 10px">瀵煎嚭</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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, getCurrentInstance, nextTick} from "vue";
-import FormDia from "@/views/customerService/afterSalesHandling/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {afterSalesServiceDelete, afterSalesServiceListPage} from "@/api/customerService/index.js";
-import useUserStore from "@/store/modules/user.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-
-const data = reactive({
- searchForm: {
- feedbackDate: "",
- disDate: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
- {
- label: "澶勭悊鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- if (params == 1) {
- return "寰呭鐞�";
- } else if (params == 2) {
- return "宸插鐞�";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- if (params == 1) {
- return "danger";
- } else if (params == 2) {
- return "success";
- } else {
- return null;
- }
- },
- },
- {
- label: "鍙嶉鏃ユ湡",
- prop: "feedbackDate",
- width: 150,
- },
- {
- label: "鐧昏浜�",
- prop: "checkNickName",
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 200,
- },
- {
- label: "闂鎻忚堪",
- prop: "proDesc",
- width:300
- },
- {
- label: "鍏宠仈閮ㄩ棬",
- prop: "deptName",
- width: 200,
- },
- {
- label: "澶勭悊浜�",
- prop: "disposeNickName",
- },
- {
- label: "澶勭悊缁撴灉",
- prop: "disRes",
- width: 200,
- },
- {
- label: "澶勭悊鏃ユ湡",
- prop: "disDate",
- width: 150,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: 120,
- operation: [
- {
- name: "澶勭悊",
- type: "text",
- clickFun: (row) => {
- openForm("approve", row);
- },
- disabled: (row) => {
- return row.status !== 1
- }
- },
- {
- name: "鏌ョ湅",
- type: "text",
- clickFun: (row) => {
- openForm("view", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const selectedRows = ref([]);
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- afterSalesServiceListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-// 鎵撳紑寮规
-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(() => {
- tableLoading.value = true;
- afterSalesServiceDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/afterSalesService/exportTwo", {}, "鍞悗澶勭悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/customerService/expiryAfterSales/components/formDia.vue b/src/views/customerService/expiryAfterSales/components/formDia.vue
deleted file mode 100644
index a6ae725..0000000
--- a/src/views/customerService/expiryAfterSales/components/formDia.vue
+++ /dev/null
@@ -1,291 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="dialogTitle"
- width="70%"
- @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="productName">
- <el-input
- v-model="form.productName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浜у搧鎵瑰彿锛�" prop="batchNumber">
- <el-input
- v-model="form.batchNumber"
- placeholder="璇疯緭鍏ヤ骇鍝佹壒鍙�"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="涓存湡鏃ユ湡锛�" prop="expiryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.expiryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨涓存湡鏃ユ湡"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="搴撳瓨鏁伴噺锛�" prop="stockQuantity">
- <el-input-number
- v-model="form.stockQuantity"
- :min="0"
- placeholder="璇疯緭鍏ュ簱瀛樻暟閲�"
- style="width: 100%"
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactPhone">
- <el-input
- v-model="form.contactPhone"
- placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="闂鎻忚堪锛�" prop="problemDesc">
- <el-input
- v-model="form.problemDesc"
- placeholder="璇疯緭鍏ラ棶棰樻弿杩�"
- clearable
- :disabled="operationType === 'view'"
- type="textarea"
- :rows="3"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30" v-if="operationType !== 'add'">
- <el-col :span="12">
- <el-form-item label="澶勭悊浜猴細" prop="handlerId">
- <el-select
- v-model="form.handlerId"
- placeholder="璇烽�夋嫨澶勭悊浜�"
- clearable
- :disabled="operationType === 'view'"
- style="width: 100%"
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="澶勭悊鏃ユ湡锛�" prop="handleDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.handleDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨澶勭悊鏃ユ湡"
- clearable
- :disabled="operationType === 'view'"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30" v-if="operationType !== 'add'">
- <el-col :span="24">
- <el-form-item label="澶勭悊缁撴灉锛�" prop="handleResult">
- <el-input
- v-model="form.handleResult"
- placeholder="璇疯緭鍏ュ鐞嗙粨鏋�"
- clearable
- :disabled="operationType === 'view'"
- type="textarea"
- :rows="3"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm" v-if="operationType !== 'view'">纭</el-button>
- <el-button @click="closeDia">{{ operationType === 'view' ? '鍏抽棴' : '鍙栨秷' }}</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, computed} from "vue";
-import useUserStore from "@/store/modules/user.js";
-// import {userListNoPageByTenantId} from "@/api/system/user.js"; // 鏆傛椂娉ㄩ噴鎺夛紝浣跨敤鍋囨暟鎹�
-// import {expiryAfterSalesAdd, expiryAfterSalesUpdate} from "@/api/customerService/index.js"; // 鏆傛椂娉ㄩ噴鎺夛紝浣跨敤鍋囨暟鎹�
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const dialogTitle = computed(() => {
- switch (operationType.value) {
- case 'add':
- return '鏂板涓存湡鍞悗';
- case 'edit':
- return '缂栬緫涓存湡鍞悗';
- case 'view':
- return '鏌ョ湅涓存湡鍞悗';
- default:
- return '涓存湡鍞悗绠$悊';
- }
-});
-
-const data = reactive({
- form: {
- id: "",
- productName: "",
- batchNumber: "",
- expiryDate: "",
- stockQuantity: 0,
- customerName: "",
- contactPhone: "",
- problemDesc: "",
- handlerId: "",
- handleDate: "",
- handleResult: "",
- status: 1
- },
- rules: {
- productName: [{required: true, message: "璇疯緭鍏ヤ骇鍝佸悕绉�", trigger: "blur"}],
- batchNumber: [{required: true, message: "璇疯緭鍏ヤ骇鍝佹壒鍙�", trigger: "blur"}],
- expiryDate: [{required: true, message: "璇烽�夋嫨涓存湡鏃ユ湡", trigger: "change"}],
- stockQuantity: [{required: true, message: "璇疯緭鍏ュ簱瀛樻暟閲�", trigger: "blur"}],
- customerName: [{required: true, message: "璇疯緭鍏ュ鎴峰悕绉�", trigger: "blur"}],
- contactPhone: [
- {required: true, message: "璇疯緭鍏ヨ仈绯荤數璇�", trigger: "blur"},
- {pattern: /^1[3-9]\d{9}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur"}
- ],
- problemDesc: [{required: true, message: "璇疯緭鍏ラ棶棰樻弿杩�", trigger: "blur"}],
- }
-})
-const { form, rules } = toRefs(data);
-const userList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
-
- // 妯℃嫙鑾峰彇鐢ㄦ埛鍒楄〃
- userList.value = [
- { userId: 1, nickName: "寮犱笁" },
- { userId: 2, nickName: "鏉庡洓" },
- { userId: 3, nickName: "鐜嬩簲" },
- { userId: 4, nickName: "璧靛叚" },
- { userId: 5, nickName: "瀛欏叓" }
- ];
-
- if (type === 'add') {
- // 鏂板鏃堕噸缃〃鍗�
- form.value = {
- id: "",
- productName: "",
- batchNumber: "",
- expiryDate: "",
- stockQuantity: 0,
- customerName: "",
- contactPhone: "",
- problemDesc: "",
- handlerId: "",
- handleDate: "",
- handleResult: "",
- status: 1
- };
- } else {
- // 缂栬緫鎴栨煡鐪嬫椂濉厖鏁版嵁
- form.value = { ...row };
- if (type === 'edit' && !form.value.handlerId) {
- form.value.handlerId = userStore.id;
- form.value.handleDate = getCurrentDate();
- }
- }
-}
-
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- // 妯℃嫙鎻愪氦鎿嶄綔
- setTimeout(() => {
- console.log("妯℃嫙鎻愪氦鐨勬暟鎹�:", form.value);
- proxy.$modal.msgSuccess(operationType.value === 'add' ? "鏂板鎴愬姛" : "鏇存柊鎴愬姛");
- closeDia();
- }, 300);
- }
- });
-}
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0");
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/customerService/expiryAfterSales/index.vue b/src/views/customerService/expiryAfterSales/index.vue
deleted file mode 100644
index df44504..0000000
--- a/src/views/customerService/expiryAfterSales/index.vue
+++ /dev/null
@@ -1,258 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">涓存湡鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.expiryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- @change="handleQuery"
- />
- <span class="search_title ml10">澶勭悊鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.handleDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- @change="handleQuery"
- />
- <span style = "margin-left: 10px;" class="search_title">澶勭悊鐘舵�侊細</span>
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 140px" clearable>
- <el-option label="寰呭鐞�" :value="1"></el-option>
- <el-option label="宸插鐞�" :value="2"></el-option>
- </el-select>
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- <el-button @click="resetQuery" style="margin-left: 10px"
- >閲嶇疆</el-button
- >
- </div>
- </div>
- <div class="table_actions" style="margin-bottom: 10px;">
- <el-button type="primary" @click="openForm('add')">鏂板</el-button>
- <el-button type="danger" @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- >
- <!-- 琛ㄦ牸鎻掓Ы -->
- <template #status="{ row }">
- <el-tag :type="row.status === 1 ? 'warning' : 'success'">
- {{ row.status === 1 ? '寰呭鐞�' : '宸插鐞�' }}
- </el-tag>
- </template>
-
- <template #operation="{ row }">
- <el-button type="primary" link @click="openForm('view', row)">鏌ョ湅</el-button>
- <el-button type="primary" link @click="openForm('edit', row)" v-if="row.status === 1">缂栬緫</el-button>
- </template>
- </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/customerService/expiryAfterSales/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-// import {expiryAfterSalesDelete, expiryAfterSalesListPage} from "@/api/customerService/index.js"; // 鏆傛椂娉ㄩ噴鎺夛紝浣跨敤鍋囨暟鎹�
-import useUserStore from "@/store/modules/user.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-
-const data = reactive({
- searchForm: {
- expiryDate: "",
- handleDate: "",
- status: ""
- },
- tableData: [],
- page: {
- current: 1,
- size: 10,
- total: 0,
- },
- selectedRows: [],
- tableLoading: false,
- formDia: null,
- tableColumn: [
- {
- label: "涓存湡浜у搧鍚嶇О",
- prop: "productName",
- width: "",
- },
- {
- label: "浜у搧鎵瑰彿",
- prop: "batchNumber",
- width: "",
- },
- {
- label: "涓存湡鏃ユ湡",
- prop: "expiryDate",
- width: "",
- },
- {
- label: "搴撳瓨鏁伴噺",
- prop: "stockQuantity",
- width: "",
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: "",
- },
- {
- label: "闂鎻忚堪",
- prop: "problemDesc",
- width: "",
- },
- {
- label: "澶勭悊鐘舵��",
- prop: "status",
- width: "",
- slot: true,
- },
- {
- label: "澶勭悊浜�",
- prop: "handlerName",
- width: "",
- },
- {
- label: "澶勭悊鏃ユ湡",
- prop: "handleDate",
- width: "",
- },
- {
- label: "鎿嶄綔",
- prop: "operation",
- slot: true,
- width: "200",
- },
- ],
-});
-
-const {
- searchForm,
- tableData,
- page,
- selectedRows,
- tableLoading,
- formDia,
- tableColumn,
-} = toRefs(data);
-
-// 鏌ヨ
-const handleQuery = () => {
- page.value.current = 1;
- getList();
-};
-
-// 閫夋嫨
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 閲嶇疆
-const resetQuery = () => {
- proxy.resetForm("queryRef");
- searchForm.value = {
- expiryDate: "",
- handleDate: "",
- status: ""
- };
- handleQuery();
-};
-
-// 鍒嗛〉
-const pagination = (obj) => {
- page.value.current = obj.page;
- page.value.size = obj.limit;
- getList();
-};
-
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- tableLoading.value = true;
- // 鍙栨秷娉ㄩ噴骞朵娇鐢ㄧ湡瀹濧PI
- // expiryAfterSalesListPage({
- // ...searchForm.value,
- // current: page.value.current,
- // size: page.value.size
- // }).then(res => {
- // tableData.value = res.data.records;
- // page.value.total = res.data.total;
- // tableLoading.value = false;
- // });
-
- // 鏆傛椂杩斿洖绌烘暟鎹�
- tableData.value = [];
- page.value.total = 0;
- tableLoading.value = false;
-};
-
-// 鎵撳紑寮规
-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(() => {
- tableLoading.value = true;
- // 鍙栨秷娉ㄩ噴骞朵娇鐢ㄧ湡瀹濧PI
- // expiryAfterSalesDelete(ids).then(() => {
- // proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- // getList();
- // }).finally(() => {
- // tableLoading.value = false;
- // });
-
- // 鏆傛椂妯℃嫙鍒犻櫎鎴愬姛
- tableLoading.value = false;
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/customerService/feedbackRegistration/components/formDia.vue b/src/views/customerService/feedbackRegistration/components/formDia.vue
deleted file mode 100644
index a37002b..0000000
--- a/src/views/customerService/feedbackRegistration/components/formDia.vue
+++ /dev/null
@@ -1,167 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="鍞悗鐧昏"
- width="70%"
- @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="feedbackDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.feedbackDate"
- 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="checkUserId">
- <el-select
- v-model="form.checkUserId"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="闂鎻忚堪锛�" prop="proDesc">
- <el-input
- v-model="form.proDesc"
- placeholder="璇疯緭鍏�"
- clearable
- type="textarea"
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- feedbackDate: "",
- checkUserId: "",
- customerName: "",
- proDesc: "",
- },
- rules: {
- feedbackDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- checkUserId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- customerName: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- proDesc: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- }
-})
-const { form, rules } = toRefs(data);
-const userList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- form.value = {}
- proxy.resetForm("formRef");
- form.value.checkUserId = userStore.id;
- form.value.feedbackDate = getCurrentDate();
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- if (type === "edit") {
- form.value = {...row}
- }
-}
-// const setName = (code) => {
-// const index = userList.value.findIndex(item => item.deviceModel === code);
-// if (index > -1) {
-// console.log(userList)
-// form.value.name = userList.value[index].deviceName;
-// }
-// }
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "add") {
- afterSalesServiceAdd(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- })
- } else {
- afterSalesServiceUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/customerService/feedbackRegistration/index.vue b/src/views/customerService/feedbackRegistration/index.vue
deleted file mode 100644
index 3d97ef8..0000000
--- a/src/views/customerService/feedbackRegistration/index.vue
+++ /dev/null
@@ -1,229 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鍙嶉鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.feedbackDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- @change="handleQuery"
- />
- <span style="margin-left: 10px;" class="search_title">澶勭悊鐘舵�侊細</span>
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 140px" clearable>
- <el-option label="寰呭鐞�" :value="1"></el-option>
- <el-option label="宸插鐞�" :value="2"></el-option>
- </el-select>
- <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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, getCurrentInstance, nextTick} from "vue";
-import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {afterSalesServiceDelete, afterSalesServiceListPage} from "@/api/customerService/index.js";
-import useUserStore from "@/store/modules/user.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-
-const data = reactive({
- searchForm: {
- feedbackDate: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
- {
- label: "澶勭悊鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- if (params == 1) {
- return "寰呭鐞�";
- } else if (params == 2) {
- return "宸插鐞�";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- if (params == 1) {
- return "danger";
- } else if (params == 2) {
- return "success";
- } else {
- return null;
- }
- },
- },
- {
- label: "鍙嶉鏃ユ湡",
- prop: "feedbackDate",
- width: 150,
- },
- {
- label: "鐧昏浜�",
- prop: "checkNickName",
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 200,
- },
- {
- label: "闂鎻忚堪",
- prop: "proDesc",
- width:300
- },
- {
- label: "鍏宠仈閮ㄩ棬",
- prop: "deptName",
- width: 200,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- disabled: (row) => {
- return row.status !== 1
- }
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const selectedRows = ref([]);
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- afterSalesServiceListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.checkUserId !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- afterSalesServiceDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/afterSalesService/export", {}, "鍙嶉鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/demo/fakePage/index.vue b/src/views/demo/fakePage/index.vue
deleted file mode 100644
index 42cef72..0000000
--- a/src/views/demo/fakePage/index.vue
+++ /dev/null
@@ -1,248 +0,0 @@
-<template>
- <div class="app-container">
- <el-card shadow="never">
- <div class="toolbar">
- <el-input
- v-model="query.keyword"
- placeholder="鎼滅储鍚嶇О/绫诲埆"
- clearable
- style="width: 240px"
- @keyup.enter="handleSearch"
- />
- <el-select
- v-model="query.status"
- placeholder="鐘舵��"
- clearable
- style="width: 140px; margin-left: 12px"
- >
- <el-option label="鍚敤" value="鍚敤" />
- <el-option label="鍋滅敤" value="鍋滅敤" />
- </el-select>
- <el-button type="primary" style="margin-left: 12px" @click="handleSearch">鏌ヨ</el-button>
- <el-button @click="resetQuery">閲嶇疆</el-button>
- <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-column prop="id" label="缂栧彿" width="90" sortable />
- <el-table-column prop="name" label="鍚嶇О" min-width="140" />
- <el-table-column prop="category" label="绫诲埆" width="120" />
- <el-table-column prop="stock" label="搴撳瓨" width="100" sortable />
- <el-table-column prop="price" label="鍗曚环(楼)" width="120">
- <template #default="scope">{{ formatPrice(scope.row.price) }}</template>
- </el-table-column>
- <el-table-column label="鐘舵��" width="120">
- <template #default="scope">
- <el-tag :type="scope.row.status === '鍚敤' ? 'success' : 'info'">{{ scope.row.status }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="updatedAt" label="鏇存柊鏃堕棿" min-width="160" />
- <el-table-column label="鎿嶄綔" width="180" fixed="right">
- <template #default="scope">
- <el-button link type="primary" @click="openEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <div class="pagination">
- <el-pagination
- background
- layout="total, sizes, prev, pager, next, jumper"
- :total="filteredList.length"
- :page-sizes="[5, 10, 20, 50]"
- :page-size="pager.pageSize"
- :current-page="pager.pageNum"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="isEdit ? '缂栬緫' : '鏂板'" width="520px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="90px">
- <el-form-item label="鍚嶇О" prop="name">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" />
- </el-form-item>
- <el-form-item label="绫诲埆" prop="category">
- <el-select v-model="form.category" 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="stock">
- <el-input v-model.number="form.stock" type="number" min="0" />
- </el-form-item>
- <el-form-item label="鍗曚环(楼)" prop="price">
- <el-input v-model.number="form.price" type="number" min="0" step="0.01" />
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-radio-group v-model="form.status">
- <el-radio label="鍚敤">鍚敤</el-radio>
- <el-radio label="鍋滅敤">鍋滅敤</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
- </template>
- </el-dialog>
- </div>
-
-</template>
-
-<script setup>
-import { ref, reactive, computed, nextTick } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-
-defineOptions({ name: 'FakePage' })
-
-const query = reactive({
- keyword: '',
- status: ''
-})
-
-const pager = reactive({
- pageNum: 1,
- pageSize: 10
-})
-
-const allList = ref(generateMockData())
-
-const filteredList = computed(() => {
- const keyword = (query.keyword || '').trim()
- const status = query.status
- return allList.value.filter(item => {
- const hitKeyword = !keyword || item.name.includes(keyword) || item.category.includes(keyword)
- const hitStatus = !status || item.status === status
- return hitKeyword && hitStatus
- })
-})
-
-const pagedList = computed(() => {
- const start = (pager.pageNum - 1) * pager.pageSize
- const end = start + pager.pageSize
- return filteredList.value.slice(start, end)
-})
-
-function handleSearch() {
- pager.pageNum = 1
-}
-
-function resetQuery() {
- query.keyword = ''
- query.status = ''
- pager.pageNum = 1
-}
-
-function handleSizeChange(size) {
- pager.pageSize = size
- pager.pageNum = 1
-}
-
-function handleCurrentChange(page) {
- pager.pageNum = page
-}
-
-function formatPrice(val) {
- return Number(val || 0).toFixed(2)
-}
-
-// 鏂板/缂栬緫
-const dialogVisible = ref(false)
-const isEdit = ref(false)
-const formRef = ref()
-const form = reactive({ id: null, name: '', category: '', stock: 0, price: 0, status: '鍚敤' })
-
-const rules = {
- name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }],
- category: [{ required: true, message: '璇烽�夋嫨绫诲埆', trigger: 'change' }],
- stock: [{ required: true, message: '璇疯緭鍏ュ簱瀛�', trigger: 'blur' }],
- price: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }]
-}
-
-function openCreate() {
- isEdit.value = false
- Object.assign(form, { id: null, name: '', category: '', stock: 0, price: 0, status: '鍚敤' })
- dialogVisible.value = true
- nextTick(() => formRef.value?.clearValidate?.())
-}
-
-function openEdit(row) {
- isEdit.value = true
- Object.assign(form, JSON.parse(JSON.stringify(row)))
- dialogVisible.value = true
- nextTick(() => formRef.value?.clearValidate?.())
-}
-
-function submitForm() {
- formRef.value?.validate?.((valid) => {
- if (!valid) return
- if (isEdit.value) {
- const index = allList.value.findIndex(x => x.id === form.id)
- if (index > -1) {
- allList.value[index] = { ...form, updatedAt: nowString() }
- ElMessage.success('宸蹭繚瀛�')
- }
- } else {
- const newId = Date.now()
- allList.value.unshift({ ...form, id: newId, updatedAt: nowString() })
- ElMessage.success('宸叉柊澧�')
- }
- dialogVisible.value = false
- })
-}
-
-function handleDelete(row) {
- ElMessageBox.confirm(`纭鍒犻櫎銆�${row.name}銆戝悧锛焋, '鎻愮ず', { type: 'warning' })
- .then(() => {
- allList.value = allList.value.filter(x => x.id !== row.id)
- ElMessage.success('宸插垹闄�')
- })
- .catch(() => {})
-}
-
-function generateMockData() {
- const categories = ['鍘熸枡', '鍗婃垚鍝�', '鎴愬搧']
- const statusOptions = ['鍚敤', '鍋滅敤']
- const list = []
- for (let i = 1; i <= 36; i++) {
- list.push({
- id: i,
- name: `鐗╂枡-${i.toString().padStart(3, '0')}`,
- category: categories[i % categories.length],
- stock: Math.floor(Math.random() * 1000),
- price: (Math.random() * 500 + 10).toFixed(2),
- status: statusOptions[i % 2],
- updatedAt: nowString()
- })
- }
- return list
-}
-
-function nowString() {
- const d = new Date()
- const yyyy = d.getFullYear()
- const MM = String(d.getMonth() + 1).padStart(2, '0')
- const dd = String(d.getDate()).padStart(2, '0')
- const hh = String(d.getHours()).padStart(2, '0')
- const mm = String(d.getMinutes()).padStart(2, '0')
- const ss = String(d.getSeconds()).padStart(2, '0')
- return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`
-}
-</script>
-
-<style scoped>
-.toolbar {
- margin-bottom: 12px;
-}
-.pagination {
- margin-top: 12px;
- text-align: right;
-}
-</style>
-
-
-
diff --git a/src/views/energyManagement/carbonManagement/index.vue b/src/views/energyManagement/carbonManagement/index.vue
deleted file mode 100644
index 5a4be25..0000000
--- a/src/views/energyManagement/carbonManagement/index.vue
+++ /dev/null
@@ -1,1553 +0,0 @@
-<template>
- <div class="carbon-management">
- <!-- 椤甸潰澶撮儴 -->
- <div class="page-header">
- <div class="header-content">
- <h1 class="page-title">纰虫帓鏀剧鐞嗙郴缁�</h1>
- <p class="page-subtitle">鍩轰簬ISO 14064鏍囧噯 路 GHG Protocol鏍哥畻鏍囧噯</p>
- </div>
- <div class="header-stats">
- <div class="stat-item">
- <span class="stat-label">鎬荤⒊鎺掓斁閲�</span>
- <span class="stat-value">{{totalEmissions}} tCO鈧俥</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">鏈湀鍑忔帓</span>
- <span class="stat-value reduction">-{{monthlyReduction}}%</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">纰充腑鍜岃繘搴�</span>
- <span class="stat-value">{{neutralProgress}}%</span>
- </div>
- </div>
- </div>
-
- <!-- 涓昏鍐呭鍖哄煙 -->
- <div class="dashboard-content">
- <!-- 椤堕儴鏁版嵁闈㈡澘 -->
- <div class="top-panels">
- <div class="data-panel top-left">
- <div class="panel-title">褰撳墠纰虫帓鏀�</div>
- <div class="panel-value">{{carbonData.scope1}} <span class="unit">tCO鈧俥</span></div>
- <div class="panel-subtitle">鑼冨洿1鐩存帴鎺掓斁</div>
- </div>
- <div class="data-panel top-center">
- <div class="panel-title">鑳借�楃洃娴�</div>
- <div class="panel-value">{{carbonData.scope2}} <span class="unit">tCO鈧俥</span></div>
- <div class="panel-subtitle">鑼冨洿2闂存帴鎺掓斁</div>
- </div>
- <div class="data-panel top-right">
- <div class="panel-title">渚涘簲閾炬帓鏀�</div>
- <div class="panel-value">{{carbonData.scope3}} <span class="unit">tCO鈧俥</span></div>
- <div class="panel-subtitle">鑼冨洿3渚涘簲閾炬帓鏀�</div>
- </div>
- <div class="data-panel top-far-right">
- <div class="panel-title">鍑忔帓杩涘害</div>
- <div class="panel-value">{{neutralProgress}} <span class="unit">%</span></div>
- <div class="panel-subtitle">纰充腑鍜岀洰鏍�</div>
- </div>
- </div>
-
- <!-- 涓績涓昏鍥惧尯鍩� -->
- <div class="center-main-view">
- <!-- 宸︿晶鎺у埗闈㈡澘 -->
- <div class="left-control-panel">
- <div class="control-section">
- <div class="section-title">纰虫帓鏀捐寖鍥�</div>
- <el-radio-group v-model="selectedScope" @change="updateScopeData" class="vertical-radio">
- <el-radio-button :value="'all'">鍏ㄩ儴鑼冨洿</el-radio-button>
- <el-radio-button :value="'scope1'">鑼冨洿1</el-radio-button>
- <el-radio-button :value="'scope2'">鑼冨洿2</el-radio-button>
- <el-radio-button :value="'scope3'">鑼冨洿3</el-radio-button>
- </el-radio-group>
- </div>
- <div class="control-section">
- <div class="section-title">鐩戞祴灞傜骇</div>
- <el-radio-group v-model="heatmapLevel" @change="updateHeatmapLevel" class="vertical-radio">
- <el-radio-button :value="'device'">璁惧绾�</el-radio-button>
- <el-radio-button :value="'line'">浜х嚎绾�</el-radio-button>
- <el-radio-button :value="'enterprise'">浼佷笟绾�</el-radio-button>
- </el-radio-group>
- </div>
- </div>
-
- <!-- 涓績鐑姏鍥� -->
- <div class="main-heatmap">
- <div class="heatmap-header">
- <h2 class="main-title">纰宠冻杩圭儹鍔涘浘鍒嗘瀽</h2>
- <div class="date-selector">
- <el-date-picker
- v-model="selectedDate"
- type="date"
- placeholder="閫夋嫨鏃ユ湡"
- size="small"
- @change="updateHeatmapData"
- />
- </div>
- </div>
- <div class="heatmap-view">
- <Echarts ref="heatmapChart"
- :series="heatmapSeries"
- :xAxis="heatmapXAxis"
- :yAxis="heatmapYAxis"
- :tooltip="heatmapTooltip"
- :visualMap="heatmapVisualMap"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 450px"></Echarts>
- </div>
- </div>
-
- <!-- 鍙充晶鏁版嵁闈㈡澘 -->
- <div class="right-data-panel">
- <div class="data-section">
- <div class="section-title">瀹炴椂鐩戞帶</div>
- <div class="mini-chart">
- <Echarts ref="realtimeChart"
- :series="realtimeSeries"
- :xAxis="realtimeXAxis"
- :chartStyle="chartStyle"
- :yAxis="realtimeYAxis"
- :tooltip="realtimeTooltip"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 300px"></Echarts>
- </div>
- </div>
- <div class="data-section">
- <div class="section-title">瓒嬪娍鍒嗘瀽</div>
- <div class="trend-controls">
- <el-radio-group v-model="trendPeriod" size="small" @change="updateTrendData">
- <el-radio-button :value="'week'">鍛�</el-radio-button>
- <el-radio-button :value="'month'">鏈�</el-radio-button>
- <el-radio-button :value="'year'">骞�</el-radio-button>
- </el-radio-group>
- </div>
- <div class="mini-chart">
- <Echarts ref="trendChart"
- :series="trendSeries"
- :xAxis="trendXAxis"
- :yAxis="trendYAxis"
- :tooltip="trendTooltip"
- :chartStyle="chartStyle"
- :legend="trendLegend"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 200px"></Echarts>
- </div>
- </div>
- </div>
- </div>
-
- <!-- 搴曢儴杩涘害闈㈡澘 -->
- <div class="bottom-progress-panel">
- <div class="progress-section">
- <div class="progress-title">2024骞村噺鎺掔洰鏍�</div>
- <div class="progress-data">
- <span class="current">{{reductionTarget.current}}</span>
- <span class="separator">/</span>
- <span class="target">{{reductionTarget.target}} tCO鈧俥</span>
- </div>
- <el-progress :percentage="reductionTarget.percentage" :stroke-width="6" color="#00E676"/>
- </div>
- <div class="progress-section">
- <div class="progress-title">纰充腑鍜岃繘搴�</div>
- <div class="progress-data">
- <span class="current">{{neutralTarget.current}}</span>
- <span class="separator">/</span>
- <span class="target">{{neutralTarget.target}} tCO鈧俥</span>
- </div>
- <el-progress :percentage="neutralTarget.percentage" :stroke-width="6" color="#00D4FF"/>
- </div>
- </div>
-
- <!-- 搴曢儴鏁版嵁琛ㄦ牸 -->
- <div class="bottom-data-table">
- <div class="table-panel">
- <div class="table-header">
- <h3 class="table-title">纰虫帓鏀捐缁嗘暟鎹�</h3>
- <div class="table-controls">
- <el-input
- v-model="searchKeyword"
- placeholder="鎼滅储璁惧鎴栦骇绾�"
- size="small"
- style="width: 200px; margin-right: 10px;"
- />
- <el-button type="primary" size="small" @click="exportData">瀵煎嚭鏁版嵁</el-button>
- </div>
- </div>
- <el-table :data="filteredTableData" style="width: 100%" height="180">
- <el-table-column prop="name" label="璁惧/浜х嚎" width="150"/>
- <el-table-column prop="type" label="绫诲瀷" width="100"/>
- <el-table-column prop="scope1" label="鑼冨洿1鎺掓斁" width="120"/>
- <el-table-column prop="scope2" label="鑼冨洿2鎺掓斁" width="120"/>
- <el-table-column prop="scope3" label="鑼冨洿3鎺掓斁" width="120"/>
- <el-table-column prop="total" label="鎬绘帓鏀鹃噺" width="120"/>
- <el-table-column prop="efficiency" label="纰虫晥鐜�" width="100"/>
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">{{scope.row.status}}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
-import * as echarts from 'echarts'
-import Echarts from '@/components/Echarts/echarts.vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const selectedScope = ref('all')
-const heatmapLevel = ref('device')
-const selectedDate = ref(new Date())
-const trendPeriod = ref('week')
-const searchKeyword = ref('')
-
-// 纰虫帓鏀炬暟鎹�
-const carbonData = ref({
- scope1: 125.6,
- scope2: 89.3,
- scope3: 234.7
-})
-const chartStyle = {
- width: '96%',
- height: '110%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-}
-// 璁$畻灞炴��
-const totalEmissions = computed(() => {
- return (carbonData.value.scope1 + carbonData.value.scope2 + carbonData.value.scope3).toFixed(1)
-})
-
-const monthlyReduction = ref(8.5)
-
-// 璁$畻纰充腑鍜岃繘搴︾櫨鍒嗘瘮
-const neutralProgress = computed(() => {
- return Math.round(neutralTarget.value.percentage)
-})
-
-// 鍑忔帓鐩爣鏁版嵁
-const reductionTarget = ref({
- current: 320.5,
- target: 500,
- percentage: 64.1
-})
-
-const neutralTarget = ref({
- current: 1250,
- target: 3800,
- percentage: 32.9
-})
-
-// 瀹炴椂鐩戞帶鍥捐〃閰嶇疆
-const realtimeSeries = ref([
- {
- name: '瀹炴椂纰虫帓鏀�',
- type: 'line',
- smooth: true,
- data: generateRealtimeData(),
- itemStyle: {
- color: '#FF6B6B'
- },
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: 'rgba(255, 107, 107, 0.3)' },
- { offset: 1, color: 'rgba(255, 107, 107, 0.1)' }
- ])
- }
- }
-])
-
-const realtimeXAxis = [{
- type: 'category',
- data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
- axisLabel: { color: '#B8C8E0' }
-}]
-
-const realtimeYAxis = [{
- type: 'value',
- name: 'tCO鈧俥/h',
- axisLabel: { color: '#B8C8E0' },
- nameTextStyle: { color: '#B8C8E0' }
-}]
-
-const realtimeTooltip = {
- trigger: 'axis',
- formatter: '{b}: {c} tCO鈧俥/h'
-}
-
-// 鐑姏鍥鹃厤缃�
-const heatmapSeries = ref([
- {
- name: '纰虫帓鏀鹃噺',
- type: 'heatmap',
- data: generateHeatmapData(),
- label: {
- show: false
- },
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
-])
-
-const heatmapXAxis = [{
- type: 'category',
- data: Array.from({length: 24}, (_, i) => `${i}:00`),
- splitArea: { show: true },
- axisLabel: { color: '#B8C8E0' }
-}]
-
-const heatmapYAxis = [{
- type: 'category',
- data: ['璁惧A', '璁惧B', '璁惧C', '璁惧D', '璁惧E', '璁惧F', '璁惧G'],
- splitArea: { show: true },
- axisLabel: { color: '#B8C8E0' }
-}]
-
-const heatmapTooltip = {
- trigger: 'item',
- formatter: function (params) {
- const [hour, device] = params.data
- const value = params.value[2]
- return `璁惧: ${heatmapYAxis[0].data[device]}<br/>鏃堕棿: ${hour}:00<br/>纰虫帓鏀鹃噺: ${value} tCO鈧俥`
- }
-}
-
-const heatmapVisualMap = ref({
- min: 0,
- max: 50,
- calculable: true,
- orient: 'horizontal',
- left: 'center',
- bottom: '5%',
- inRange: {
- color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
- },
- textStyle: { color: '#B8C8E0' }
-})
-
-// 瓒嬪娍鍒嗘瀽鍥捐〃閰嶇疆
-const trendSeries = ref([
- {
- name: '鑼冨洿1',
- type: 'line',
- data: [120, 132, 101, 134, 90, 230, 210],
- itemStyle: { color: '#FF6B6B' }
- },
- {
- name: '鑼冨洿2',
- type: 'line',
- data: [220, 182, 191, 234, 290, 330, 310],
- itemStyle: { color: '#4ECDC4' }
- },
- {
- name: '鑼冨洿3',
- type: 'line',
- data: [150, 232, 201, 154, 190, 330, 410],
- itemStyle: { color: '#45B7D1' }
- }
-])
-
-const trendXAxis = [{
- type: 'category',
- data: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'],
- axisLabel: { color: '#B8C8E0' }
-}]
-
-const trendYAxis = [{
- type: 'value',
- name: 'tCO鈧俥',
- axisLabel: { color: '#B8C8E0' },
- nameTextStyle: { color: '#B8C8E0' }
-}]
-
-const trendTooltip = {
- trigger: 'axis'
-}
-
-const trendLegend = {
- data: ['鑼冨洿1', '鑼冨洿2', '鑼冨洿3'],
- textStyle: { color: '#B8C8E0' }
-}
-
-// 琛ㄦ牸鏁版嵁
-const carbonTableData = ref([
- { name: '鐢熶骇绾緼', type: '浜х嚎', scope1: 45.2, scope2: 32.1, scope3: 18.7, total: 96.0, efficiency: '鑹ソ', status: '姝e父' },
- { name: '璁惧B-01', type: '璁惧', scope1: 12.5, scope2: 8.3, scope3: 5.2, total: 26.0, efficiency: '浼樼', status: '姝e父' },
- { name: '鐢熶骇绾緾', type: '浜х嚎', scope1: 38.7, scope2: 28.9, scope3: 15.4, total: 83.0, efficiency: '鑹ソ', status: '鍛婅' },
- { name: '璁惧D-02', type: '璁惧', scope1: 15.8, scope2: 11.2, scope3: 7.1, total: 34.1, efficiency: '涓�鑸�', status: '姝e父' },
- { name: '鐢熶骇绾縀', type: '浜х嚎', scope1: 52.3, scope2: 39.6, scope3: 22.8, total: 114.7, efficiency: '寰呬紭鍖�', status: '鍛婅' }
-])
-
-// 鐢熸垚瀹炴椂鏁版嵁
-function generateRealtimeData() {
- return Array.from({length: 24}, () => (Math.random() * 20 + 10).toFixed(1))
-}
-
-// 鐢熸垚鐑姏鍥炬暟鎹�
-function generateHeatmapData() {
- const data = []
- let yAxisLength = 7 // 榛樿璁惧绾�
- let baseMultiplier = 1 // 鍩虹鍊嶆暟
-
- // 鏍规嵁灞傜骇纭畾Y杞撮暱搴﹀拰鏁版嵁鑼冨洿
- if (heatmapLevel.value === 'line') {
- yAxisLength = 5
- baseMultiplier = 2 // 浜х嚎绾ф暟鎹洿澶�
- } else if (heatmapLevel.value === 'enterprise') {
- yAxisLength = 3
- baseMultiplier = 4 // 浼佷笟绾ф暟鎹渶澶�
- }
-
- for (let i = 0; i < yAxisLength; i++) {
- for (let j = 0; j < 24; j++) {
- let value
- // 绠�鍖栫殑鏃堕棿娈甸�昏緫
- if (j >= 8 && j <= 18) {
- // 宸ヤ綔鏃堕棿鎺掓斁閲忚緝楂�
- value = Math.random() * 30 + 20
- } else if (j >= 19 && j <= 22) {
- // 鏅氶棿鎺掓斁閲忎腑绛�
- value = Math.random() * 20 + 10
- } else {
- // 娣卞鍜屽噷鏅ㄦ帓鏀鹃噺杈冧綆
- value = Math.random() * 10 + 2
- }
-
- // 娣诲姞璁惧宸紓鍜屽眰绾у�嶆暟
- value *= (0.8 + i * 0.1) * baseMultiplier
-
- data.push([j, i, Math.round(value * 10) / 10])
- }
- }
- return data
-}
-
-// 鏇存柊鑼冨洿鏁版嵁
-function updateScopeData() {
- // 鏍规嵁閫夋嫨鐨勮寖鍥存洿鏂版墍鏈夌浉鍏冲浘琛ㄦ暟鎹�
- const scopeMultiplier = {
- 'all': 1,
- 'scope1': 0.3,
- 'scope2': 0.4,
- 'scope3': 0.3
- }
-
- const multiplier = scopeMultiplier[selectedScope.value] || 1
-
- // 鏇存柊纰虫帓鏀炬暟鎹樉绀�
- if (selectedScope.value === 'all') {
- carbonData.value = {
- scope1: 125.6,
- scope2: 89.3,
- scope3: 234.7
- }
- } else {
- const baseTotal = 125.6 + 89.3 + 234.7
- carbonData.value = {
- scope1: selectedScope.value === 'scope1' ? 125.6 : 0,
- scope2: selectedScope.value === 'scope2' ? 89.3 : 0,
- scope3: selectedScope.value === 'scope3' ? 234.7 : 0
- }
- }
-
- // 鏇存柊鐑姏鍥炬暟鎹�
- heatmapSeries.value[0].data = generateHeatmapData().map(item => [
- item[0], item[1], Math.round(item[2] * multiplier * 10) / 10
- ])
-
- // 鏇存柊瀹炴椂鐩戞帶鏁版嵁
- realtimeSeries.value[0].data = generateRealtimeData().map(val =>
- Math.round(parseFloat(val) * multiplier * 10) / 10
- )
-}
-
-// 鏇存柊鐑姏鍥惧眰绾�
-function updateHeatmapLevel() {
- // 鏍规嵁灞傜骇鏇存柊Y杞存暟鎹拰visualMap鑼冨洿
- if (heatmapLevel.value === 'device') {
- heatmapYAxis[0].data = ['閿呯倝A', '鍘嬬缉鏈築', '鍐峰嵈濉擟', '椋庢満D', '娉礒', '鍙樺帇鍣‵', '鐢垫満G']
- heatmapVisualMap.value.max = 50
- } else if (heatmapLevel.value === 'line') {
- heatmapYAxis[0].data = ['鐢熶骇绾�1', '鐢熶骇绾�2', '鐢熶骇绾�3', '鐢熶骇绾�4', '鐢熶骇绾�5']
- heatmapVisualMap.value.max = 100
- } else {
- heatmapYAxis[0].data = ['鍘傚尯A', '鍘傚尯B', '鍘傚尯C']
- heatmapVisualMap.value.max = 200
- }
-
- // 鏇存柊鐑姏鍥炬暟鎹�
- heatmapSeries.value[0].data = generateHeatmapData()
-
- // 鏇存柊琛ㄦ牸鏁版嵁浠ュ尮閰嶅綋鍓嶅眰绾�
- updateTableDataForLevel()
-}
-
-// 鏍规嵁灞傜骇鏇存柊琛ㄦ牸鏁版嵁
-function updateTableDataForLevel() {
- const levelConfigs = {
- device: [
- { name: '閿呯倝A', type: '璁惧', scope1: 45.2, scope2: 32.1, scope3: 18.7, total: 96.0, efficiency: '鑹ソ', status: '姝e父' },
- { name: '鍘嬬缉鏈築', type: '璁惧', scope1: 38.5, scope2: 28.3, scope3: 15.2, total: 82.0, efficiency: '浼樼', status: '姝e父' },
- { name: '鍐峰嵈濉擟', type: '璁惧', scope1: 22.8, scope2: 18.9, scope3: 12.3, total: 54.0, efficiency: '鑹ソ', status: '鍛婅' },
- { name: '椋庢満D', type: '璁惧', scope1: 15.6, scope2: 12.4, scope3: 8.1, total: 36.1, efficiency: '涓�鑸�', status: '姝e父' },
- { name: '娉礒', type: '璁惧', scope1: 12.3, scope2: 9.8, scope3: 6.4, total: 28.5, efficiency: '浼樼', status: '姝e父' }
- ],
- line: [
- { name: '鐢熶骇绾�1', type: '浜х嚎', scope1: 125.6, scope2: 89.3, scope3: 56.8, total: 271.7, efficiency: '鑹ソ', status: '姝e父' },
- { name: '鐢熶骇绾�2', type: '浜х嚎', scope1: 98.4, scope2: 72.1, scope3: 45.2, total: 215.7, efficiency: '浼樼', status: '姝e父' },
- { name: '鐢熶骇绾�3', type: '浜х嚎', scope1: 87.2, scope2: 65.8, scope3: 41.6, total: 194.6, efficiency: '鑹ソ', status: '鍛婅' },
- { name: '鐢熶骇绾�4', type: '浜х嚎', scope1: 76.9, scope2: 58.3, scope3: 37.1, total: 172.3, efficiency: '涓�鑸�', status: '姝e父' },
- { name: '鐢熶骇绾�5', type: '浜х嚎', scope1: 65.7, scope2: 49.2, scope3: 31.8, total: 146.7, efficiency: '寰呬紭鍖�', status: '鍛婅' }
- ],
- enterprise: [
- { name: '鍘傚尯A', type: '鍘傚尯', scope1: 456.8, scope2: 334.7, scope3: 212.5, total: 1004.0, efficiency: '鑹ソ', status: '姝e父' },
- { name: '鍘傚尯B', type: '鍘傚尯', scope1: 387.2, scope2: 289.6, scope3: 184.3, total: 861.1, efficiency: '浼樼', status: '姝e父' },
- { name: '鍘傚尯C', type: '鍘傚尯', scope1: 298.5, scope2: 223.8, scope3: 142.7, total: 665.0, efficiency: '鑹ソ', status: '鍛婅' }
- ]
- }
-
- carbonTableData.value = levelConfigs[heatmapLevel.value] || levelConfigs.device
-}
-
-// 鏇存柊鐑姏鍥炬暟鎹紙鏃ユ湡鍙樺寲鏃讹級
-function updateHeatmapData() {
- heatmapSeries.value[0].data = generateHeatmapData()
-
- // 鍚屾椂鏇存柊鍏朵粬鐩稿叧鏁版嵁
- updateScopeData()
-}
-
-// 鏇存柊瓒嬪娍鏁版嵁
-function updateTrendData() {
- const trendDataConfigs = {
- week: {
- xAxisData: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'],
- scope1Data: [120, 132, 101, 134, 90, 80, 75],
- scope2Data: [220, 182, 191, 234, 190, 150, 140],
- scope3Data: [150, 232, 201, 154, 190, 120, 110]
- },
- month: {
- xAxisData: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�'],
- scope1Data: [1200, 1150, 1300, 1250, 1180, 1320, 1280, 1350, 1220, 1290, 1160, 1100],
- scope2Data: [2200, 2100, 2350, 2280, 2150, 2400, 2320, 2450, 2180, 2380, 2120, 2050],
- scope3Data: [1800, 1750, 1950, 1880, 1820, 2000, 1920, 2100, 1850, 1980, 1780, 1720]
- },
- year: {
- xAxisData: ['2019', '2020', '2021', '2022', '2023', '2024'],
- scope1Data: [14500, 14200, 13800, 13500, 13100, 12800],
- scope2Data: [26800, 26200, 25600, 25000, 24400, 23800],
- scope3Data: [22400, 21800, 21200, 20600, 20000, 19400]
- }
- }
-
- const config = trendDataConfigs[trendPeriod.value] || trendDataConfigs.week
-
- // 鏇存柊X杞存暟鎹�
- trendXAxis[0].data = config.xAxisData
-
- // 鏇存柊绯诲垪鏁版嵁
- trendSeries.value = [
- {
- name: '鑼冨洿1',
- type: 'line',
- data: config.scope1Data,
- itemStyle: { color: '#FF6B6B' },
- smooth: true
- },
- {
- name: '鑼冨洿2',
- type: 'line',
- data: config.scope2Data,
- itemStyle: { color: '#4ECDC4' },
- smooth: true
- },
- {
- name: '鑼冨洿3',
- type: 'line',
- data: config.scope3Data,
- itemStyle: { color: '#45B7D1' },
- smooth: true
- }
- ]
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-function getStatusType(status) {
- switch (status) {
- case '姝e父': return 'success'
- case '鍛婅': return 'warning'
- case '寮傚父': return 'danger'
- default: return 'info'
- }
-}
-
-// 瀵煎嚭鏁版嵁
-function exportData() {
- // 鍑嗗瀵煎嚭鏁版嵁
- const exportDataSet = {
- 鍩烘湰淇℃伅: {
- 瀵煎嚭鏃堕棿: new Date().toLocaleString('zh-CN'),
- 鏁版嵁灞傜骇: heatmapLevel.value === 'device' ? '璁惧绾�' : heatmapLevel.value === 'line' ? '浜х嚎绾�' : '浼佷笟绾�',
- 閫夋嫨鑼冨洿: selectedScope.value === 'all' ? '鍏ㄩ儴鑼冨洿' : `鑼冨洿${selectedScope.value.slice(-1)}`,
- 閫夋嫨鏃ユ湡: selectedDate.value ? selectedDate.value.toLocaleDateString('zh-CN') : '浠婃棩'
- },
- 纰虫帓鏀剧粺璁�: {
- 鑼冨洿1鐩存帴鎺掓斁: carbonData.value.scope1 + ' tCO鈧俥',
- 鑼冨洿2闂存帴鎺掓斁: carbonData.value.scope2 + ' tCO鈧俥',
- 鑼冨洿3渚涘簲閾炬帓鏀�: carbonData.value.scope3 + ' tCO鈧俥',
- 鎬绘帓鏀鹃噺: totalEmissions.value + ' tCO鈧俥'
- },
- 璇︾粏鏁版嵁: carbonTableData.value,
- 鐑姏鍥炬暟鎹�: heatmapSeries.value[0].data.map(item => ({
- 鏃堕棿: `${item[0]}:00`,
- 璁惧搴忓彿: item[1],
- 璁惧鍚嶇О: heatmapYAxis.data[item[1]],
- 纰虫帓鏀鹃噺: item[2] + ' tCO鈧俥'
- }))
- }
-
- // 鍒涘缓CSV鍐呭
- let csvContent = '\uFEFF' // BOM for UTF-8
-
- // 鍩烘湰淇℃伅
- csvContent += '鍩烘湰淇℃伅\n'
- Object.entries(exportDataSet.鍩烘湰淇℃伅).forEach(([key, value]) => {
- csvContent += `${key},${value}\n`
- })
- csvContent += '\n'
-
- // 纰虫帓鏀剧粺璁�
- csvContent += '纰虫帓鏀剧粺璁n'
- Object.entries(exportDataSet.纰虫帓鏀剧粺璁�).forEach(([key, value]) => {
- csvContent += `${key},${value}\n`
- })
- csvContent += '\n'
-
- // 璇︾粏鏁版嵁琛ㄦ牸
- csvContent += '璇︾粏鏁版嵁\n'
- csvContent += '鍚嶇О,绫诲瀷,鑼冨洿1鎺掓斁,鑼冨洿2鎺掓斁,鑼冨洿3鎺掓斁,鎬绘帓鏀鹃噺,纰虫晥鐜�,鐘舵�乗n'
- exportDataSet.璇︾粏鏁版嵁.forEach(row => {
- csvContent += `${row.name},${row.type},${row.scope1},${row.scope2},${row.scope3},${row.total},${row.efficiency},${row.status}\n`
- })
- csvContent += '\n'
-
- // 鐑姏鍥炬暟鎹紙鍓�50鏉★級
- csvContent += '鐑姏鍥炬暟鎹紙鍓�50鏉★級\n'
- csvContent += '鏃堕棿,璁惧鍚嶇О,纰虫帓鏀鹃噺\n'
- exportDataSet.鐑姏鍥炬暟鎹�.slice(0, 50).forEach(row => {
- csvContent += `${row.鏃堕棿},${row.璁惧鍚嶇О},${row.纰虫帓鏀鹃噺}\n`
- })
-
- // 鍒涘缓涓嬭浇閾炬帴
- const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
- const link = document.createElement('a')
- const url = URL.createObjectURL(blob)
- link.setAttribute('href', url)
- link.setAttribute('download', `纰虫帓鏀炬暟鎹甠${new Date().toISOString().slice(0, 10)}.csv`)
- link.style.visibility = 'hidden'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
-
- // 鏄剧ず鎴愬姛娑堟伅
- console.log('纰虫帓鏀炬暟鎹鍑烘垚鍔�')
-}
-
-// 鎼滅储杩囨护鍔熻兘
-const filteredTableData = computed(() => {
- if (!searchKeyword.value) {
- return carbonTableData.value
- }
- return carbonTableData.value.filter(item =>
- item.name.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
- item.type.toLowerCase().includes(searchKeyword.value.toLowerCase())
- )
-})
-
-// 鐑姏鍥剧偣鍑讳簨浠跺鐞�
-function handleHeatmapClick(params) {
- if (params.componentType === 'series') {
- const [hour, deviceIndex, value] = params.data
- const deviceName = heatmapYAxis.data[deviceIndex]
- console.log(`鐐瑰嚮浜嗚澶�: ${deviceName}, 鏃堕棿: ${hour}:00, 鎺掓斁閲�: ${value} tCO鈧俥`)
-
- // 鍙互鍦ㄨ繖閲屾坊鍔犺缁嗕俊鎭脊绐楁垨璺宠浆鍒拌缁嗛〉闈�
- }
-}
-
-onMounted(() => {
- // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栨搷浣�
- console.log('纰崇鐞嗛〉闈㈠凡鍔犺浇')
-
- // 鍒濆鍖栫儹鍔涘浘鏁版嵁
- updateHeatmapLevel()
-
- // 鍒濆鍖栬秼鍔挎暟鎹�
- updateTrendData()
-
- // 鍒濆鍖栬寖鍥存暟鎹�
- updateScopeData()
-
- // 璁剧疆瀹氭椂鍣紝姣�30绉掓洿鏂颁竴娆″疄鏃舵暟鎹�
- const timer = setInterval(() => {
- realtimeSeries.value[0].data = generateRealtimeData()
- }, 30000)
-
- // 娓呯悊瀹氭椂鍣�
- onBeforeUnmount(() => {
- clearInterval(timer)
- })
-})
-
-// 娣诲姞鐑姏鍥剧偣鍑讳簨浠剁粦瀹�
-function bindHeatmapEvents() {
- // 杩欎釜鍑芥暟鍙互鐢ㄦ潵缁戝畾鐑姏鍥剧殑鐐瑰嚮浜嬩欢
- // 鍦ㄥ疄闄呬娇鐢ㄤ腑锛屽彲浠ラ�氳繃ECharts鐨勪簨浠剁郴缁熸潵瀹炵幇
-}
-</script>
-
-<style scoped>
-.carbon-management {
- min-height: 100vh;
- background:
- radial-gradient(ellipse at top, rgba(29, 78, 216, 0.15), transparent 50%),
- radial-gradient(ellipse at bottom, rgba(139, 92, 246, 0.15), transparent 50%),
- linear-gradient(135deg, #0a0f1c 0%, #1e293b 25%, #0f172a 50%, #1e293b 75%, #0a0f1c 100%);
- padding: 20px;
- font-family: 'Inter', 'Microsoft YaHei', sans-serif;
- overflow: hidden;
- position: relative;
-}
-
-.carbon-management::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background:
- radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
- radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
- radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.05) 0%, transparent 50%);
- pointer-events: none;
-
-}
-
-
-
-.page-header {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.95) 0%, rgba(30, 41, 59, 0.9) 100%),
- radial-gradient(circle at top right, rgba(59, 130, 246, 0.1), transparent 50%);
- border: 1px solid rgba(148, 163, 184, 0.2);
- border-radius: 20px;
- padding: 40px;
- margin-bottom: 30px;
- box-shadow:
- 0 25px 50px -12px rgba(0, 0, 0, 0.4),
- 0 0 0 1px rgba(255, 255, 255, 0.05),
- inset 0 1px 0 rgba(255, 255, 255, 0.1);
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
- overflow: hidden;
- backdrop-filter: blur(20px);
-
-}
-
-.page-header:hover {
- transform: translateY(-2px);
- box-shadow:
- 0 32px 64px -12px rgba(0, 0, 0, 0.5),
- 0 0 0 1px rgba(255, 255, 255, 0.1),
- inset 0 1px 0 rgba(255, 255, 255, 0.15);
-}
-
-.page-header::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background:
- linear-gradient(45deg, rgba(59, 130, 246, 0.08) 0%, rgba(147, 51, 234, 0.08) 50%, rgba(236, 72, 153, 0.08) 100%);
- pointer-events: none;
-
-}
-
-
-
-.header-content {
- flex: 1;
- position: relative;
- z-index: 1;
-}
-
-.page-title {
- font-size: 28px;
- font-weight: bold;
- color: #ffffff;
- margin: 0 0 8px 0;
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
-}
-
-.page-subtitle {
- font-size: 14px;
- color: #B8C8E0;
- margin: 0;
-}
-
-.header-stats {
- display: flex;
- gap: 40px;
- position: relative;
- z-index: 1;
-}
-
-.stat-item {
- text-align: center;
- padding: 20px;
- background:
- linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(147, 51, 234, 0.15) 100%),
- radial-gradient(circle at center, rgba(255, 255, 255, 0.05), transparent 70%);
- border-radius: 12px;
- border: 1px solid rgba(148, 163, 184, 0.2);
- position: relative;
- overflow: hidden;
-
- backdrop-filter: blur(10px);
-}
-
-.stat-item:hover {
- transform: translateY(-2px) scale(1.05);
- box-shadow:
- 0 20px 25px -5px rgba(59, 130, 246, 0.3),
- 0 10px 10px -5px rgba(59, 130, 246, 0.2);
-}
-
-.stat-item::before {
- content: '';
- position: absolute;
- top: 0;
- left: -100%;
- width: 100%;
- height: 100%;
- background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
-
-}
-
-.stat-item:hover::before {
- left: 100%;
-}
-
-.stat-label {
- display: block;
- font-size: 12px;
- color: #94A3B8;
- margin-bottom: 8px;
- font-weight: 500;
- letter-spacing: 0.5px;
- text-transform: uppercase;
-}
-
-.stat-value {
- display: block;
- font-size: 28px;
- font-weight: 700;
- color: #00D4FF;
- text-shadow:
- 0 0 20px rgba(0, 212, 255, 0.6),
- 0 0 40px rgba(0, 212, 255, 0.3);
- position: relative;
- z-index: 1;
-}
-
-.stat-value.reduction {
- color: #00E676;
- text-shadow:
- 0 0 20px rgba(0, 230, 118, 0.6),
- 0 0 40px rgba(0, 230, 118, 0.3);
-}
-
-.dashboard-content {
- display: flex;
- flex-direction: column;
- gap: 20px;
- min-height: calc(100vh - 200px);
-}
-
-.top-panels {
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr;
- gap: 20px;
- height: 120px;
-}
-
-.data-panel {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%),
- radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 10px 10px -5px rgba(0, 0, 0, 0.2),
- 0 0 0 1px rgba(255, 255, 255, 0.05);
- backdrop-filter: blur(16px);
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- text-align: center;
-}
-
-.panel-title {
- font-size: 12px;
- color: #94A3B8;
- margin-bottom: 8px;
- font-weight: 500;
- letter-spacing: 0.5px;
- text-transform: uppercase;
-}
-
-.panel-value {
- font-size: 24px;
- font-weight: 700;
- color: #00D4FF;
- text-shadow:
- 0 0 20px rgba(0, 212, 255, 0.6),
- 0 0 40px rgba(0, 212, 255, 0.3);
- margin-bottom: 4px;
-}
-
-.panel-subtitle {
- font-size: 11px;
- color: #B8C8E0;
- font-weight: 400;
-}
-
-.unit {
- font-size: 16px;
- color: #94A3B8;
-}
-
-.center-main-view {
- display: grid;
- grid-template-columns: 200px 1fr 300px;
- gap: 20px;
- flex: 1;
-}
-
-.left-control-panel {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 0 0 1px rgba(255, 255, 255, 0.05);
- backdrop-filter: blur(16px);
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-
-.control-section {
- display: flex;
- flex-direction: column;
- gap: 10px;
-}
-
-.section-title {
- font-size: 14px;
- font-weight: 600;
- color: #ffffff;
- margin-bottom: 8px;
-}
-
-.vertical-radio {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-
-.main-heatmap {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 0 0 1px rgba(255, 255, 255, 0.05);
- backdrop-filter: blur(16px);
- display: flex;
- flex-direction: column;
-}
-
-.heatmap-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 1px solid rgba(148, 163, 184, 0.2);
-}
-
-.main-title {
- font-size: 18px;
- font-weight: bold;
- color: #ffffff;
- margin: 0;
-}
-
-.date-selector {
- display: flex;
- align-items: center;
-}
-
-.heatmap-view {
- flex: 1;
-}
-
-.right-data-panel {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 0 0 1px rgba(255, 255, 255, 0.05);
- backdrop-filter: blur(16px);
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-
-.data-section {
- display: flex;
- flex-direction: column;
- gap: 10px;
-}
-
-.mini-chart {
- width: 100%;
-}
-
-.trend-controls {
- margin-bottom: 10px;
-}
-
-.bottom-progress-panel {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 40px;
- height: 100px;
-}
-
-.progress-section {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 0 0 1px rgba(255, 255, 255, 0.05);
- backdrop-filter: blur(16px);
- display: flex;
- flex-direction: column;
- justify-content: center;
-}
-
-.progress-title {
- font-size: 14px;
- font-weight: 600;
- color: #ffffff;
- margin-bottom: 8px;
-}
-
-.progress-data {
- display: flex;
- align-items: baseline;
- gap: 4px;
- margin-bottom: 12px;
-}
-
-.progress-data .current {
- font-size: 20px;
- font-weight: 700;
- color: #00D4FF;
-}
-
-.progress-data .separator {
- font-size: 16px;
- color: #94A3B8;
-}
-
-.progress-data .target {
- font-size: 14px;
- color: #B8C8E0;
-}
-
-.bottom-data-table {
- margin-top: 20px;
-}
-
-.table-panel {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%),
- radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 20px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 10px 10px -5px rgba(0, 0, 0, 0.2),
- 0 0 0 1px rgba(255, 255, 255, 0.05),
- inset 0 1px 0 rgba(255, 255, 255, 0.1);
- backdrop-filter: blur(16px);
-}
-
-.table-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
- padding-bottom: 10px;
- border-bottom: 1px solid rgba(148, 163, 184, 0.2);
-}
-
-.table-title {
- font-size: 16px;
- font-weight: 600;
- color: #ffffff;
- margin: 0;
-}
-
-.table-controls {
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.panel-card {
- background:
- linear-gradient(135deg, rgba(15, 27, 46, 0.9) 0%, rgba(30, 41, 59, 0.85) 100%),
- radial-gradient(circle at bottom left, rgba(59, 130, 246, 0.08), transparent 50%);
- border: 1px solid rgba(148, 163, 184, 0.15);
- border-radius: 16px;
- padding: 24px;
- box-shadow:
- 0 20px 25px -5px rgba(0, 0, 0, 0.3),
- 0 10px 10px -5px rgba(0, 0, 0, 0.2),
- 0 0 0 1px rgba(255, 255, 255, 0.05),
- inset 0 1px 0 rgba(255, 255, 255, 0.1);
- position: relative;
- overflow: hidden;
- backdrop-filter: blur(16px);
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-}
-
-
-
-.heatmap-card {
- height: 500px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 1px solid rgba(81, 129, 219, 0.3);
- position: relative;
- z-index: 1;
-}
-
-.card-title {
- font-size: 18px;
- font-weight: bold;
- color: #ffffff;
- margin: 0;
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
-}
-
-.heatmap-controls {
- display: flex;
- align-items: center;
-}
-
-.scope-stats {
- display: flex;
- flex-direction: column;
- gap: 15px;
- position: relative;
- z-index: 1;
-}
-
-.scope-item {
- display: flex;
- align-items: center;
- padding: 20px;
- border-radius: 12px;
- background:
- linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(147, 51, 234, 0.12) 100%),
- radial-gradient(circle at top, rgba(255, 255, 255, 0.05), transparent 60%);
- border-left: 4px solid #00D4FF;
- border: 1px solid rgba(148, 163, 184, 0.15);
- position: relative;
- overflow: hidden;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- backdrop-filter: blur(8px);
-}
-
-.scope-item:hover {
- transform: translateY(-3px);
- box-shadow:
- 0 15px 30px -5px rgba(59, 130, 246, 0.25),
- 0 0 0 1px rgba(255, 255, 255, 0.1);
-}
-
-.scope-item::after {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 2px;
- background: linear-gradient(90deg, #3B82F6, #8B5CF6, #EC4899);
- opacity: 0;
- transition: opacity 0.3s ease;
-}
-
-.scope-item:hover::after {
- opacity: 1;
-}
-
-/* 纰虫帓鏀剧粺璁℃牱寮� */
-.carbon-stats {
- display: flex;
- justify-content: space-between;
- margin-bottom: 20px;
- gap: 15px;
-}
-
-.carbon-stat-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 12px;
- padding: 20px;
- background:
- linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(147, 51, 234, 0.12) 100%),
- radial-gradient(circle at top, rgba(255, 255, 255, 0.05), transparent 60%);
- border-radius: 12px;
- border: 1px solid rgba(148, 163, 184, 0.15);
- flex: 1;
- position: relative;
- overflow: hidden;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- backdrop-filter: blur(8px);
-}
-
-.carbon-stat-item:hover {
- transform: translateY(-3px);
- box-shadow:
- 0 15px 30px -5px rgba(59, 130, 246, 0.25),
- 0 0 0 1px rgba(255, 255, 255, 0.1);
-}
-
-.carbon-stat-item::after {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 2px;
- background: linear-gradient(90deg, #3B82F6, #8B5CF6, #EC4899);
- opacity: 0;
- transition: opacity 0.3s ease;
-}
-
-.carbon-stat-item:hover::after {
- opacity: 1;
-}
-
-.carbon-label {
- color: #94A3B8;
- font-size: 11px;
- text-align: center;
- font-weight: 500;
- letter-spacing: 0.5px;
- text-transform: uppercase;
-}
-
-.carbon-value {
- color: #00D4FF;
- font-size: 18px;
- font-weight: 700;
- text-shadow:
- 0 0 15px rgba(0, 212, 255, 0.6),
- 0 0 30px rgba(0, 212, 255, 0.3);
- position: relative;
-}
-
-.scope-item.scope1 {
- border-left-color: #FF6B6B;
-}
-
-.scope-item.scope2 {
- border-left-color: #FFD93D;
-}
-
-.scope-item.scope3 {
- border-left-color: #6BCF7F;
-}
-
-.scope-icon {
- font-size: 24px;
- margin-right: 15px;
-}
-
-.scope-info {
- flex: 1;
-}
-
-.scope-name {
- display: block;
- font-weight: bold;
- color: #ffffff;
- margin-bottom: 5px;
-}
-
-.scope-value {
- display: block;
- font-size: 20px;
- font-weight: bold;
- color: #00D4FF;
- margin-bottom: 3px;
- text-shadow: 0 0 8px rgba(0, 212, 255, 0.5);
-}
-
-.scope-desc {
- display: block;
- font-size: 12px;
- color: #B8C8E0;
-}
-
-.target-progress {
- display: flex;
- flex-direction: column;
- gap: 20px;
- position: relative;
- z-index: 1;
-}
-
-.progress-item {
- padding: 15px;
- background: rgba(81, 129, 219, 0.1);
- border-radius: 8px;
- border: 1px solid rgba(81, 129, 219, 0.2);
-}
-
-.progress-info {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
-}
-
-.progress-label {
- font-weight: bold;
- color: #ffffff;
-}
-
-.progress-value {
- color: #B8C8E0;
- font-size: 14px;
-}
-
-.bottom-panel {
- margin-top: 20px;
-}
-
-.table-controls {
- display: flex;
- align-items: center;
-}
-
-/* Element Plus 缁勪欢娣辫壊涓婚鏍峰紡 */
-:deep(.el-table) {
- background: transparent !important;
- color: #ffffff !important;
-}
-
-:deep(.el-table th) {
- background: rgba(81, 129, 219, 0.2) !important;
- color: #ffffff !important;
- border-bottom: 1px solid rgba(81, 129, 219, 0.3) !important;
-}
-
-:deep(.el-table td) {
- background: transparent !important;
- color: #B8C8E0 !important;
- border-bottom: 1px solid rgba(81, 129, 219, 0.1) !important;
-}
-
-:deep(.el-table tr:hover > td) {
- background: rgba(81, 129, 219, 0.1) !important;
-}
-
-:deep(.el-input__wrapper) {
- background: rgba(15, 27, 46, 0.8) !important;
- border: 1px solid rgba(81, 129, 219, 0.3) !important;
- color: #ffffff !important;
-}
-
-:deep(.el-input__inner) {
- color: #ffffff !important;
-}
-
-:deep(.el-button--primary) {
- background: linear-gradient(135deg, #5181DB, #D369E0) !important;
- border: none !important;
- box-shadow: 0 0 10px rgba(81, 129, 219, 0.5) !important;
-}
-
-/* 鍨傜洿鍗曢�夋寜閽粍鏍峰紡 */
-:deep(.vertical-radio) {
- display: flex !important;
- flex-direction: column !important;
- gap: 6px !important;
-}
-
-:deep(.vertical-radio .el-radio-button) {
- margin: 0 !important;
- width: 100% !important;
-}
-
-:deep(.vertical-radio .el-radio-button__inner) {
- background: rgba(59, 130, 246, 0.1) !important;
- border: 1px solid rgba(148, 163, 184, 0.2) !important;
- color: #B8C8E0 !important;
- border-radius: 8px !important;
- padding: 10px 16px !important;
- width: 100% !important;
- text-align: center !important;
- font-size: 12px !important;
- font-weight: 500 !important;
-}
-
-:deep(.vertical-radio .el-radio-button__inner:hover) {
- background: rgba(59, 130, 246, 0.2) !important;
- border-color: rgba(59, 130, 246, 0.4) !important;
- color: #ffffff !important;
-}
-
-:deep(.vertical-radio .el-radio-button.is-active .el-radio-button__inner) {
- background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
- border-color: #3B82F6 !important;
- color: #ffffff !important;
- box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important;
-}
-
-:deep(.vertical-radio .el-radio-button:first-child .el-radio-button__inner) {
- border-left: 1px solid rgba(148, 163, 184, 0.2) !important;
-}
-
-:deep(.el-radio-group .el-radio-button__inner) {
- background: rgba(59, 130, 246, 0.1) !important;
- border: 1px solid rgba(148, 163, 184, 0.2) !important;
- color: #B8C8E0 !important;
- border-radius: 6px !important;
- padding: 6px 12px !important;
- margin: 0 2px !important;
- font-size: 12px !important;
-}
-
-:deep(.el-radio-group .el-radio-button__inner:hover) {
- background: rgba(59, 130, 246, 0.2) !important;
- border-color: rgba(59, 130, 246, 0.4) !important;
- color: #ffffff !important;
-}
-
-:deep(.el-radio-group .el-radio-button.is-active .el-radio-button__inner) {
- background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
- border-color: #3B82F6 !important;
- color: #ffffff !important;
- box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important;
-}
-
-:deep(.el-date-editor .el-input__wrapper) {
- background: rgba(15, 27, 46, 0.8) !important;
- border: 1px solid rgba(81, 129, 219, 0.3) !important;
-}
-
-:deep(.el-progress-bar__outer) {
- background: rgba(81, 129, 219, 0.2) !important;
-}
-
-:deep(.el-tag) {
- background: rgba(81, 129, 219, 0.2) !important;
- border: 1px solid rgba(81, 129, 219, 0.3) !important;
- color: #ffffff !important;
-}
-
-:deep(.el-tag.el-tag--success) {
- background: rgba(0, 230, 118, 0.2) !important;
- border-color: rgba(0, 230, 118, 0.3) !important;
- color: #00E676 !important;
-}
-
-:deep(.el-tag.el-tag--warning) {
- background: rgba(255, 193, 7, 0.2) !important;
- border-color: rgba(255, 193, 7, 0.3) !important;
- color: #FFC107 !important;
-}
-
-:deep(.el-tag.el-tag--danger) {
- background: rgba(244, 67, 54, 0.2) !important;
- border-color: rgba(244, 67, 54, 0.3) !important;
- color: #F44336 !important;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 1200px) {
- .main-content {
- flex-direction: column;
- }
-
- .header-stats {
- gap: 20px;
- }
-}
-
-@media (max-width: 768px) {
- .page-header {
- flex-direction: column;
- text-align: center;
- gap: 20px;
- }
-
- .header-stats {
- justify-content: center;
- }
-
- .carbon-management {
- padding: 10px;
- }
-}
-</style>
\ No newline at end of file
diff --git a/src/views/energyManagement/dynamicEnergySaving/index.vue b/src/views/energyManagement/dynamicEnergySaving/index.vue
deleted file mode 100644
index b641276..0000000
--- a/src/views/energyManagement/dynamicEnergySaving/index.vue
+++ /dev/null
@@ -1,659 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 杈圭紭璁$畻鐘舵�佺洃鎺� -->
- <el-row :gutter="20" class="status-section">
- <el-col :span="8">
- <el-card class="status-card">
- <div class="status-item">
- <div class="status-icon">
- <el-icon><Monitor /></el-icon>
- </div>
- <div class="status-info">
- <div class="status-title">杈圭紭鏈嶅姟鍣ㄧ姸鎬�</div>
- <div class="status-value" :class="edgeServerStatus.status">
- {{ edgeServerStatus.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}
- </div>
- <div class="status-detail">鏈�鍚庡績璺�: {{ formatTime(edgeServerStatus.lastHeartbeat) }}</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="8">
- <el-card class="status-card">
- <div class="status-item">
- <div class="status-icon">
- <el-icon><Cpu /></el-icon>
- </div>
- <div class="status-info">
- <div class="status-title">妯″瀷杩愯鐘舵��</div>
- <div class="status-value" :class="modelStatus.status">
- {{ modelStatus.status === 'running' ? '杩愯涓�' : '宸插仠姝�' }}
- </div>
- <div class="status-detail">杩愯妯″瀷: {{ modelStatus.modelCount }}涓�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="8">
- <el-card class="status-card">
- <div class="status-item">
- <div class="status-icon">
- <el-icon><TrendCharts /></el-icon>
- </div>
- <div class="status-info">
- <div class="status-title">鑺傝兘鏁堟灉</div>
- <div class="status-value success">{{ energySavingRate.toFixed(1) }}%</div>
- <div class="status-detail">绱鑺傝兘: {{ totalEnergySaved.toFixed(1) }}kWh</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 娉ㄦ按娉甸鐜囦紭鍖栨帶鍒� -->
- <el-card class="control-section">
- <template #header>
- <span>娉ㄦ按娉甸鐜囦紭鍖栨帶鍒�</span>
- </template>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="pump-control">
- <h4>瀹炴椂鍙傛暟鐩戞帶</h4>
- <el-form label-width="120px">
- <el-form-item label="鍦板眰鍘嬪姏 (MPa)">
- <el-input v-model="pumpData.formationPressure" readonly>
- <template #append>MPa</template>
- </el-input>
- </el-form-item>
- <el-form-item label="褰撳墠娉甸�� (Hz)">
- <el-input v-model="pumpData.currentFrequency" readonly>
- <template #append>Hz</template>
- </el-input>
- </el-form-item>
- <el-form-item label="浼樺寲鍚庢车閫� (Hz)">
- <el-input v-model="pumpData.optimizedFrequency" readonly>
- <template #append>Hz</template>
- </el-input>
- </el-form-item>
- <el-form-item label="鑳借�楅檷浣�">
- <el-progress
- :percentage="pumpData.energyReduction"
- :color="getProgressColor"
- :format="format => `${format}%`"
- />
- </el-form-item>
- <el-form-item label="娴侀噺 (m鲁/h)">
- <el-input v-model="pumpData.flowRate" readonly>
- <template #append>m鲁/h</template>
- </el-input>
- </el-form-item>
- <el-form-item label="鍔熺巼 (kW)">
- <el-input v-model="pumpData.power" readonly>
- <template #append>kW</template>
- </el-input>
- </el-form-item>
- </el-form>
- </div>
- </el-col>
-
- <el-col :span="12">
- <div class="pump-chart">
- <h4>棰戠巼浼樺寲瓒嬪娍</h4>
- <div ref="frequencyChart" style="height: 300px;"></div>
- </div>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" class="control-buttons">
- <el-col :span="24">
- <el-button
- type="primary"
- :disabled="!canControl"
- @click="applyOptimization"
- >
- 搴旂敤浼樺寲璁剧疆
- </el-button>
- <el-button
- type="warning"
- :disabled="!canControl"
- @click="emergencyStop"
- >
- 绱ф�ュ仠姝�
- </el-button>
- <el-button
- type="info"
- @click="showOptimizationHistory"
- >
- 浼樺寲鍘嗗彶
- </el-button>
- <el-button
- type="success"
- @click="toggleAutoRefresh"
- >
- {{ autoRefreshStatus ? '鍋滄鑷姩鍒锋柊' : '寮�鍚嚜鍔ㄥ埛鏂�' }}
- </el-button>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 杈圭紭璁$畻妯″瀷閰嶇疆 -->
- <el-card class="model-section">
- <template #header>
- <span>杈圭紭璁$畻妯″瀷閰嶇疆</span>
- </template>
-
- <el-table :data="modelConfigs" style="width: 100%">
- <el-table-column prop="modelName" label="妯″瀷鍚嶇О" />
- <el-table-column prop="version" label="鐗堟湰" />
- <el-table-column prop="status" label="鐘舵��">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
- {{ scope.row.status === 'active' ? '婵�娲�' : '寰呮満' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="accuracy" label="鍑嗙‘鐜�" />
- <el-table-column prop="lastUpdate" label="鏈�鍚庢洿鏂�" />
- <el-table-column label="鎿嶄綔">
- <template #default="scope">
- <el-button
- size="small"
- @click="updateModel(scope.row)"
- >
- 鏇存柊妯″瀷
- </el-button>
- <el-button
- size="small"
- type="danger"
- @click="deleteModel(scope.row)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 鑳借�楀垎鏋愬浘琛� -->
- <el-card class="analysis-section">
- <template #header>
- <span>鑳借�楀垎鏋�</span>
- </template>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <div ref="energyChart" style="height: 400px;"></div>
- </el-col>
- <el-col :span="12">
- <div ref="savingChart" style="height: 400px;"></div>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 浼樺寲鍘嗗彶瀵硅瘽妗� -->
- <el-dialog v-model="historyDialogVisible" title="浼樺寲鍘嗗彶璁板綍" width="80%">
- <el-table :data="optimizationHistory" style="width: 100%">
- <el-table-column prop="timestamp" label="鏃堕棿" />
- <el-table-column prop="formationPressure" label="鍦板眰鍘嬪姏 (MPa)" />
- <el-table-column prop="oldFrequency" label="鍘熼鐜� (Hz)" />
- <el-table-column prop="newFrequency" label="鏂伴鐜� (Hz)" />
- <el-table-column prop="energySaved" label="鑺傝兘 (kWh)" />
- <el-table-column prop="status" label="鐘舵��">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'success' ? 'success' : 'warning'">
- {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, onUnmounted, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Monitor, Cpu, TrendCharts } from '@element-plus/icons-vue'
-import * as echarts from 'echarts'
-
-// 鍝嶅簲寮忔暟鎹�
-const edgeServerStatus = ref({ status: 'online', lastHeartbeat: Date.now() })
-const modelStatus = ref({ status: 'running', modelCount: 3 })
-const energySavingRate = ref(15.8)
-const totalEnergySaved = ref(1250.5)
-const pumpData = ref({
- formationPressure: 25.6,
- currentFrequency: 45.2,
- optimizedFrequency: 42.1,
- energyReduction: 23,
- flowRate: 180.5,
- power: 85.3
-})
-
-const modelConfigs = ref([
- {
- modelName: '娉ㄦ按娉甸鐜囦紭鍖栨ā鍨�',
- version: 'v2.1.0',
- status: 'active',
- accuracy: '94.2%',
- lastUpdate: '2025-01-15 14:30:00'
- },
- {
- modelName: '鍦板眰鍘嬪姏棰勬祴妯″瀷',
- version: 'v1.8.5',
- status: 'active',
- accuracy: '91.7%',
- lastUpdate: '2025-01-14 09:15:00'
- },
- {
- modelName: '鑳借�楀垎鏋愭ā鍨�',
- version: 'v2.0.3',
- status: 'standby',
- accuracy: '89.3%',
- lastUpdate: '2025-01-13 16:45:00'
- }
-])
-
-const historyDialogVisible = ref(false)
-const optimizationHistory = ref([])
-
-// 鍥捐〃寮曠敤
-const frequencyChart = ref(null)
-const energyChart = ref(null)
-const savingChart = ref(null)
-
-// 鑷姩鍒锋柊鐩稿叧
-const autoRefreshStatus = ref(true)
-const autoRefreshTimer = ref(null)
-const chartInstances = ref([])
-
-// 璁$畻灞炴��
-const canControl = computed(() => {
- return edgeServerStatus.value.status === 'online' && modelStatus.value.status === 'running'
-})
-
-const getProgressColor = computed(() => {
- return (percentage) => {
- if (percentage < 20) return '#909399'
- if (percentage < 40) return '#E6A23C'
- if (percentage < 60) return '#409EFF'
- return '#67C23A'
- }
-})
-
-// 鐢熸垚妯℃嫙鏁版嵁
-const generateMockData = () => {
- // 鐢熸垚闅忔満鍦板眰鍘嬪姏 (20-30 MPa)
- const formationPressure = 20 + Math.random() * 10
-
- // 鏍规嵁鍦板眰鍘嬪姏璁$畻浼樺寲棰戠巼
- const baseFrequency = 40 + (formationPressure - 25) * 2
- const currentFrequency = baseFrequency + (Math.random() - 0.5) * 4
- const optimizedFrequency = Math.max(35, baseFrequency - Math.random() * 3)
-
- // 璁$畻鑳借�楅檷浣�
- const energyReduction = Math.round((currentFrequency - optimizedFrequency) / currentFrequency * 100)
-
- // 璁$畻娴侀噺鍜屽姛鐜�
- const flowRate = 150 + Math.random() * 60
- const power = 70 + Math.random() * 30
-
- // 鏇存柊娉垫暟鎹�
- pumpData.value = {
- formationPressure: parseFloat(formationPressure.toFixed(1)),
- currentFrequency: parseFloat(currentFrequency.toFixed(1)),
- optimizedFrequency: parseFloat(optimizedFrequency.toFixed(1)),
- energyReduction: Math.min(energyReduction, 35),
- flowRate: parseFloat(flowRate.toFixed(1)),
- power: parseFloat(power.toFixed(1))
- }
-
- // 鏇存柊鑺傝兘鏁堟灉
- energySavingRate.value = 12 + Math.random() * 8
- totalEnergySaved.value += Math.random() * 2
-
- // 鏇存柊杈圭紭鏈嶅姟鍣ㄧ姸鎬�
- edgeServerStatus.value.lastHeartbeat = Date.now()
-
- // 闅忔満鏇存柊妯″瀷鐘舵��
- if (Math.random() > 0.95) {
- modelStatus.value.modelCount = Math.max(1, modelStatus.value.modelCount + (Math.random() > 0.5 ? 1 : -1))
- }
-
- // 娣诲姞浼樺寲鍘嗗彶璁板綍
- if (Math.random() > 0.7) {
- addOptimizationHistory()
- }
-
- // 鏇存柊鍥捐〃鏁版嵁
- updateCharts()
-}
-
-// 娣诲姞浼樺寲鍘嗗彶璁板綍
-const addOptimizationHistory = () => {
- const timestamp = new Date().toLocaleString()
- const record = {
- timestamp,
- formationPressure: pumpData.value.formationPressure,
- oldFrequency: pumpData.value.currentFrequency,
- newFrequency: pumpData.value.optimizedFrequency,
- energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
- status: Math.random() > 0.1 ? 'success' : 'failed'
- }
-
- optimizationHistory.value.unshift(record)
-
- // 淇濇寔鏈�澶�100鏉¤褰�
- if (optimizationHistory.value.length > 100) {
- optimizationHistory.value = optimizationHistory.value.slice(0, 100)
- }
-}
-
-// 鏇存柊鍥捐〃鏁版嵁
-const updateCharts = () => {
- chartInstances.value.forEach(instance => {
- if (instance && instance.setOption) {
- // 杩欓噷鍙互鏇存柊鍥捐〃鏁版嵁
- // 涓轰簡绠�鍖栵紝鎴戜滑鍙槸閲嶆柊鍒濆鍖栧浘琛�
- }
- })
-}
-
-// 鏂规硶
-const refreshData = () => {
- generateMockData()
- ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
-}
-
-const applyOptimization = async () => {
- try {
- await ElMessageBox.confirm('纭畾瑕佸簲鐢ㄥ綋鍓嶇殑浼樺寲璁剧疆鍚楋紵', '纭鎿嶄綔', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
-
- // 搴旂敤浼樺寲璁剧疆
- pumpData.value.currentFrequency = pumpData.value.optimizedFrequency
- ElMessage.success('浼樺寲璁剧疆搴旂敤鎴愬姛')
- refreshData()
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('搴旂敤浼樺寲璁剧疆澶辫触')
- }
- }
-}
-
-const emergencyStop = async () => {
- try {
- await ElMessageBox.confirm('纭畾瑕佺揣鎬ュ仠姝㈡墍鏈夋敞姘存车鍚楋紵', '绱ф�ユ搷浣�', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'error'
- })
-
- // 鎵ц绱ф�ュ仠姝㈤�昏緫
- pumpData.value.currentFrequency = 0
- pumpData.value.optimizedFrequency = 0
- ElMessage.success('绱ф�ュ仠姝㈡墽琛屾垚鍔�')
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('绱ф�ュ仠姝㈡墽琛屽け璐�')
- }
- }
-}
-
-const showOptimizationHistory = () => {
- historyDialogVisible.value = true
-}
-
-const updateModel = (model) => {
- ElMessage.info(`鏇存柊妯″瀷: ${model.modelName}`)
-}
-
-const deleteModel = async (model) => {
- try {
- await ElMessageBox.confirm(`纭畾瑕佸垹闄ゆā鍨� ${model.modelName} 鍚楋紵`, '纭鍒犻櫎', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
-
- const index = modelConfigs.value.findIndex(m => m.modelName === model.modelName)
- if (index > -1) {
- modelConfigs.value.splice(index, 1)
- ElMessage.success('妯″瀷鍒犻櫎鎴愬姛')
- }
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('妯″瀷鍒犻櫎澶辫触')
- }
- }
-}
-
-const toggleAutoRefresh = () => {
- autoRefreshStatus.value = !autoRefreshStatus.value
- if (autoRefreshStatus.value) {
- startAutoRefresh()
- ElMessage.success('鑷姩鍒锋柊宸插紑鍚�')
- } else {
- stopAutoRefresh()
- ElMessage.info('鑷姩鍒锋柊宸插叧闂�')
- }
-}
-
-const startAutoRefresh = () => {
- stopAutoRefresh() // 鍏堝仠姝箣鍓嶇殑瀹氭椂鍣�
- autoRefreshTimer.value = setInterval(() => {
- generateMockData()
- }, 60000) // 1鍒嗛挓 = 60000姣
-}
-
-const stopAutoRefresh = () => {
- if (autoRefreshTimer.value) {
- clearInterval(autoRefreshTimer.value)
- autoRefreshTimer.value = null
- }
-}
-
-const formatTime = (timestamp) => {
- return new Date(timestamp).toLocaleTimeString()
-}
-
-// 鍒濆鍖栧浘琛�
-const initCharts = () => {
- // 棰戠巼浼樺寲瓒嬪娍鍥�
- const frequencyChartInstance = echarts.init(frequencyChart.value)
- const frequencyOption = {
- title: { text: '娉甸鐜囦紭鍖栬秼鍔�' },
- tooltip: { trigger: 'axis' },
- legend: { data: ['褰撳墠棰戠巼', '浼樺寲棰戠巼', '鍦板眰鍘嬪姏'] },
- xAxis: { type: 'category', data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'] },
- yAxis: [
- { type: 'value', name: '棰戠巼 (Hz)' },
- { type: 'value', name: '鍘嬪姏 (MPa)' }
- ],
- series: [
- {
- name: '褰撳墠棰戠巼',
- type: 'line',
- data: [45.2, 44.8, 45.5, 45.1, 44.9, 45.2]
- },
- {
- name: '浼樺寲棰戠巼',
- type: 'line',
- data: [42.1, 41.8, 42.3, 41.9, 41.7, 42.1]
- },
- {
- name: '鍦板眰鍘嬪姏',
- type: 'line',
- yAxisIndex: 1,
- data: [25.6, 25.8, 26.1, 25.9, 25.7, 25.6]
- }
- ]
- }
- frequencyChartInstance.setOption(frequencyOption)
- chartInstances.value.push(frequencyChartInstance)
-
- // 鑳借�楀垎鏋愬浘
- const energyChartInstance = echarts.init(energyChart.value)
- const energyOption = {
- title: { text: '鏃ヨ兘鑰楀姣�' },
- tooltip: { trigger: 'item' },
- legend: { orient: 'vertical', left: 'left',top: 'center' },
- series: [
- {
- name: '鑳借�楀垎甯�',
- type: 'pie',
- radius: '50%',
- data: [
- { value: 45, name: '娉ㄦ按娉�' },
- { value: 25, name: '鐓ф槑绯荤粺' },
- { value: 20, name: '閫氶绯荤粺' },
- { value: 10, name: '鍏朵粬璁惧' }
- ]
- }
- ]
- }
- energyChartInstance.setOption(energyOption)
- chartInstances.value.push(energyChartInstance)
-
- // 鑺傝兘鏁堟灉鍥�
- const savingChartInstance = echarts.init(savingChart.value)
- const savingOption = {
- title: { text: '鑺傝兘鏁堟灉瓒嬪娍' },
- tooltip: { trigger: 'axis' },
- xAxis: { type: 'category', data: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'] },
- yAxis: { type: 'value', name: '鑺傝兘鐜� (%)' },
- series: [
- {
- name: '鑺傝兘鐜�',
- type: 'bar',
- data: [12.5, 15.2, 18.7, 16.3, 19.1, 17.8, 15.8]
- }
- ]
- }
- savingChartInstance.setOption(savingOption)
- chartInstances.value.push(savingChartInstance)
-}
-
-// 鐢熸垚鍒濆鍘嗗彶鏁版嵁
-const generateInitialHistory = () => {
- for (let i = 0; i < 20; i++) {
- const timestamp = new Date(Date.now() - i * 3600000).toLocaleString()
- const record = {
- timestamp,
- formationPressure: parseFloat((20 + Math.random() * 10).toFixed(1)),
- oldFrequency: parseFloat((40 + Math.random() * 10).toFixed(1)),
- newFrequency: parseFloat((35 + Math.random() * 8).toFixed(1)),
- energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
- status: Math.random() > 0.1 ? 'success' : 'failed'
- }
- optimizationHistory.value.push(record)
- }
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- initCharts()
- generateInitialHistory()
- refreshData()
- if (autoRefreshStatus.value) {
- startAutoRefresh()
- }
-})
-
-onUnmounted(() => {
- stopAutoRefresh()
- chartInstances.value.forEach(instance => {
- if (instance && instance.dispose) {
- instance.dispose()
- }
- })
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-
-
-.status-section {
- margin-bottom: 20px;
-}
-
-.status-card {
- height: 140px;
-}
-
-.status-item {
- display: flex;
- align-items: center;
- height: 100%;
-}
-
-.status-icon {
- font-size: 48px;
- margin-right: 20px;
- color: #409EFF;
-}
-
-.status-info {
- flex: 1;
-}
-
-.status-title {
- font-size: 14px;
- color: #909399;
- margin-bottom: 8px;
-}
-
-.status-value {
- font-size: 24px;
- font-weight: bold;
- margin-bottom: 8px;
-}
-
-.status-detail {
- font-size: 12px;
- color: #909399;
-}
-
-.status-value.online,
-.status-value.running {
- color: #67C23A;
-}
-
-.status-value.offline,
-.status-value.stopped {
- color: #F56C6C;
-}
-
-.status-value.success {
- color: #67C23A;
-}
-
-.control-section,
-.model-section,
-.analysis-section {
- margin-bottom: 20px;
-}
-
-.pump-control h4,
-.pump-chart h4 {
- margin-bottom: 20px;
- color: #303133;
-}
-
-.control-buttons {
- margin-top: 20px;
- text-align: center;
-}
-
-.control-buttons .el-button {
- margin: 0 10px;
-}
-</style>
diff --git a/src/views/energyManagement/energyArea/index.vue b/src/views/energyManagement/energyArea/index.vue
deleted file mode 100644
index 63feff8..0000000
--- a/src/views/energyManagement/energyArea/index.vue
+++ /dev/null
@@ -1,511 +0,0 @@
-<template>
- <div class="app-container product-view">
- <div class="left">
- <div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
- clearable
- prefix-icon="Search"
- />
- <el-button
- type="primary"
- @click="openProDia('addOne')"
- style="margin-left: 10px"
- >鏂板鐖跺尯鍩�</el-button
- >
- </div>
- <div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="list"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- default-expand-all
- :default-expanded-keys="expandedKeys"
- :draggable="true"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'label' }"
- highlight-current
- node-key="id"
- style="
- height: calc(100vh - 190px);
- overflow-y: scroll;
- scrollbar-width: none;
- margin-top: 10px;
- "
- >
- <template #default="{ node, data }">
- <div class="custom-tree-node">
- <span class="tree-node-content">
- <el-icon class="orange-icon">
- <component :is="data.children && data.children.length > 0
- ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
- </el-icon>
- {{ data.label }}
- </span>
- <div>
- <el-button
- type="primary"
- link
- @click="openProDia('edit', data)"
- >
- 缂栬緫
- </el-button>
- <el-button type="primary" link @click="openModelDia('add','', data.id)">
- 娣诲姞瀛愬尯鍩�
- </el-button>
- <el-button
- v-if="!node.childNodes.length"
- style="margin-left: 4px"
- type="danger"
- link
- @click="remove(node, data)"
- >
- 鍒犻櫎
- </el-button>
- </div>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- <div class="right">
- <div style="margin-bottom: 10px" v-if="isShowButton">
- <el-button type="primary" @click="openModelDia('add')">
- 鏂板瀛愬尯鍩�
- </el-button>
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- >
- 鍒犻櫎
- </el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
- </div>
- <el-dialog v-model="productDia" title="鍖哄煙" width="400px" @keydown.enter.prevent>
- <el-form
- :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef"
- >
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="鍖哄煙鍚嶇О锛�" prop="areaName">
- <el-input
- v-model="form.areaName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- clearable
- @keydown.enter.prevent
- />
- </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="closeProDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <el-dialog
- v-model="modelDia"
- title="瀛愬尯鍩�"
- width="400px"
- @close="closeModelDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="modelForm"
- label-width="140px"
- label-position="top"
- :rules="modelRules"
- ref="modelFormRef"
- >
- <el-form-item label="鐖跺尯鍩燂細" prop="fuId">
- <el-cascader v-model="modelForm.fuId" :options="list" :props="{
- value: 'id',
- label: 'label',
- children: 'children',
- checkStrictly: true,
- }" />
- </el-form-item>
- <el-form-item label="鍖哄煙绫诲瀷锛�" prop="areaType">
- <el-select v-model="modelForm.areaType" placeholder="璇烽�夋嫨">
- <el-option v-for="item in area_type" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍖哄煙鍚嶇О锛�" prop="areaName">
- <el-input
- v-model="modelForm.areaName"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- @keydown.enter.prevent
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitModelForm">纭</el-button>
- <el-button @click="closeModelDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import {
- areaAdd,
- areaDelete,
- areaListPage,
- areaListTree,
-} from "@/api/energyManagement/index.js";
-
-const { proxy } = getCurrentInstance();
-const tree = ref(null);
-const containerRef = ref(null);
-
-const productDia = ref(false);
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const search = ref("");
-const currentId = ref("");
-const currentParentId = ref("");
-const operationType = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const {area_type} = proxy.useDict("area_type")
-const tableColumn = ref([
- {
- label: "鍖哄煙鍚嶇О",
- prop: "areaName",
- },
- {
- label: "鍖哄煙绫诲瀷",
- prop: "areaType",
- dataType: "tag",
- formatData: (row) => {
- return area_type.value.find(item => item.value == row)?.label;
- }
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openModelDia("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const isShowButton = ref(false);
-const selectedRows = ref([]);
-const page = reactive({
- current: 1,
- size: 10,
- total: 0,
-});
-const data = reactive({
- form: {
- areaName: "",
- },
- rules: {
- areaName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
- modelForm: {
- areaName: "",
- fuId: "",
- },
- modelRules: {
- areaName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- fuId: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
- },
-});
-const { form, rules, modelForm, modelRules } = toRefs(data);
-
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
- treeLoad.value = true;
- areaListTree()
- .then((res) => {
- list.value = res;
- list.value.forEach((a) => {
- expandedKeys.value.push(a.label);
- });
- treeLoad.value = false;
- })
- .catch((err) => {
- treeLoad.value = false;
- });
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
- proxy.$refs.tree.filter(search.value);
-};
-// 鎵撳紑浜у搧寮规
-const openProDia = (type, data) => {
- operationType.value = type;
- productDia.value = true;
- form.value.areaName = "";
- if (type === "edit") {
- form.value.areaName = data.areaName;
- }
-};
-// 鎵撳紑瑙勬牸鍨嬪彿寮规
-const openModelDia = (type, data,fatherId) => {
- modelOperationType.value = type;
- modelDia.value = true;
- modelForm.value.fuId = "";
- modelForm.value.areaType = "";
- modelForm.value.areaName = "";
- modelForm.value.id = "";
- modelForm.value.fuId = fatherId;
- if (type === "edit") {
- modelForm.value = { ...data };
- }
-};
-// 鎻愪氦浜у搧鍚嶇О淇敼
-const submitForm = () => {
- proxy.$refs.formRef.validate((valid) => {
- if (valid) {
- if (operationType.value === "add") {
- form.value.parentId = currentId.value;
- form.value.id = "";
- } else if (operationType.value === "addOne") {
- form.value.id = "";
- form.value.parentId = "";
- } else {
- form.value.id = currentId.value;
- form.value.parentId = "";
- }
- areaAdd(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProDia();
- getProductTreeList();
- });
- }
- });
-};
-// 鍏抽棴浜у搧寮规
-const closeProDia = () => {
- proxy.$refs.formRef.resetFields();
- productDia.value = false;
-};
-
-// 鍒犻櫎浜у搧
-const remove = (node, data) => {
- let ids = [];
- ids.push(data.id);
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- areaDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getProductTreeList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
- // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
- isShowButton.value = !(val.children && val.children.length > 0);
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
- getModelList(true);
-};
-
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
- proxy.$refs.modelFormRef.validate((valid) => {
- if (valid) {
- modelForm.value.fuId = currentId.value;
- areaAdd(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- getProductTreeList();
- });
- }
- });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
- proxy.$refs.modelFormRef.resetFields();
- modelDia.value = false;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ瑙勬牸鍨嬪彿
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getModelList();
-};
-const getModelList = (val = false) => {
- tableLoading.value = true;
- let obj = {
- id: currentId.value,
- fuId:currentId.value,
- current: page.current,
- size: page.size
- }
- if(val){
- delete obj.id;
- }else{
- delete obj.fuId
- }
- areaListPage(obj).then((res) => {
- console.log("res", res);
- tableData.value = res.data.records;
- page.total = res.data.total;
- tableLoading.value = false;
- });
-};
-// 鍒犻櫎瑙勬牸鍨嬪彿
-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(() => {
- tableLoading.value = true;
- areaDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getModelList();
- getProductTreeList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
- if (!value) {
- //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
- return true;
- }
- // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
- let val = value.toLowerCase();
- return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
- if (data.label.indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
- if (level === 1) {
- return false;
- }
- // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let parentData = node.parent;
- // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let index = 0;
- while (index < level - 1) {
- // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
- if (parentData.data.label.indexOf(value) !== -1) {
- return true;
- }
- // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
- parentData = parentData.parent;
- index++;
- }
- // 娌″尮閰嶅埌杩斿洖false
- return false;
-};
-getProductTreeList();
-</script>
-
-<style scoped>
-.product-view {
- display: flex;
-}
-.left {
- width: 380px;
- padding: 16px;
- background: #ffffff;
-}
-.right {
- width: calc(100% - 380px);
- padding: 16px;
- margin-left: 20px;
- background: #ffffff;
-}
-.custom-tree-node {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
-}
-.tree-node-content {
- display: flex;
- align-items: center; /* 鍨傜洿灞呬腑 */
- height: 100%;
-}
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
-}
-</style>
diff --git a/src/views/energyManagement/energyCockpit/index.vue b/src/views/energyManagement/energyCockpit/index.vue
deleted file mode 100644
index 9281e37..0000000
--- a/src/views/energyManagement/energyCockpit/index.vue
+++ /dev/null
@@ -1,1380 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>鑳芥簮椹鹃┒鑸�</h2>
- <div class="header-info">
- <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
- <el-button type="primary" size="small" @click="refreshData">
- <el-icon><Refresh /></el-icon>
- 鍒锋柊鏁版嵁
- </el-button>
- </div>
- </div>
-
- <!-- 瀹炴椂鑳借�楃洃鎺� -->
- <div class="real-time-monitor">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-card class="monitor-card">
- <template #header>
- <div class="card-header">
- <span>鐢靛姏娑堣��</span>
- <el-tag type="success" size="small">瀹炴椂</el-tag>
- </div>
- </template>
- <div class="monitor-content">
- <div class="monitor-value">
- <span class="value">{{ electricityConsumption }}</span>
- <span class="unit">kW路h</span>
- </div>
- <div class="monitor-trend">
- <span class="trend-label">瓒嬪娍锛�</span>
- <el-tag :type="getTrendType(electricityTrend)" size="small">
- {{ electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(electricityTrend) }}%
- </el-tag>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="8">
- <el-card class="monitor-card">
- <template #header>
- <div class="card-header">
- <span>姘存秷鑰�</span>
- <el-tag type="primary" size="small">瀹炴椂</el-tag>
- </div>
- </template>
- <div class="monitor-content">
- <div class="monitor-value">
- <span class="value">{{ waterConsumption }}</span>
- <span class="unit">m鲁</span>
- </div>
- <div class="monitor-trend">
- <span class="trend-label">瓒嬪娍锛�</span>
- <el-tag :type="getTrendType(waterTrend)" size="small">
- {{ waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(waterTrend) }}%
- </el-tag>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="8">
- <el-card class="monitor-card">
- <template #header>
- <div class="card-header">
- <span>姘斾綋娑堣��</span>
- <el-tag type="warning" size="small">瀹炴椂</el-tag>
- </div>
- </template>
- <div class="monitor-content">
- <div class="monitor-value">
- <span class="value">{{ gasConsumption }}</span>
- <span class="unit">m鲁</span>
- </div>
- <div class="monitor-trend">
- <span class="trend-label">瓒嬪娍锛�</span>
- <el-tag :type="getTrendType(gasTrend)" size="small">
- {{ gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(gasTrend) }}%
- </el-tag>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 鑳借�楄秼鍔垮垎鏋� -->
- <div class="trend-analysis">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>鑳借�楄秼鍔垮垎鏋�</span>
- <div class="time-selector">
- <el-radio-group v-model="trendTimeUnit" @change="handleTrendTimeChange">
- <el-radio value="hour">灏忔椂</el-radio>
- <el-radio value="day">鏃�</el-radio>
- <el-radio value="week">鍛�</el-radio>
- <el-radio value="month">鏈�</el-radio>
- <el-radio value="year">骞�</el-radio>
- </el-radio-group>
- </div>
- </div>
- </template>
- <div class="chart-container">
- <div ref="trendChart" style="width: 100%; height: 400px;"></div>
- </div>
- </el-card>
- </div>
-
- <!-- 鑳借�楃粺璁′笌鎺掑悕 -->
- <div class="statistics-ranking">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-card class="statistics-card">
- <template #header>
- <div class="card-header">
- <span class="card-title">鑳借�楃粺璁℃姤琛�</span>
- <div class="header-actions">
- <el-select v-model="statisticsPeriod" @change="handleStatisticsChange" size="small" style="width: 100px;">
- <el-option label="鏃ョ粺璁�" value="day" />
- <el-option label="鍛ㄧ粺璁�" value="week" />
- <el-option label="鏈堢粺璁�" value="month" />
- <el-option label="骞寸粺璁�" value="year" />
- </el-select>
- </div>
- </div>
- </template>
- <div class="statistics-content">
- <div class="statistics-item">
- <span class="label">鎬昏兘鑰楋細</span>
- <span class="value">{{ totalEnergyConsumption }} kW路h</span>
- </div>
- <div class="statistics-item">
- <span class="label">鍚屾瘮锛�</span>
- <span class="value" :class="getComparisonClass(yearOverYear)">
- {{ yearOverYear > 0 ? '+' : '' }}{{ yearOverYear }}%
- </span>
- </div>
- <div class="statistics-item">
- <span class="label">鐜瘮锛�</span>
- <span class="value" :class="getComparisonClass(monthOverMonth)">
- {{ monthOverMonth > 0 ? '+' : '' }}{{ monthOverMonth }}%
- </span>
- </div>
- <div class="statistics-item">
- <span class="label">鑺傝兘鐜囷細</span>
- <span class="value success">{{ energySavingRate }}%</span>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card class="ranking-card">
- <template #header>
- <div class="card-header">
- <span class="card-title">鑳借�楁帓鍚�</span>
- <el-select v-model="rankingType" @change="handleRankingChange" size="small" style="width: 120px;">
- <el-option label="閮ㄩ棬鎺掑悕" value="department" />
- <el-option label="杞﹂棿鎺掑悕" value="workshop" />
- <el-option label="璁惧鎺掑悕" value="equipment" />
- </el-select>
- </div>
- </template>
- <div class="ranking-list">
- <div v-for="(item, index) in rankingList" :key="index" class="ranking-item">
- <div class="ranking-number" :class="getRankingClass(index + 1)">{{ index + 1 }}</div>
- <div class="ranking-info">
- <div class="ranking-name">{{ item.name }}</div>
- <div class="ranking-value">{{ item.value }} kW路h</div>
- </div>
- <div class="ranking-trend">
- <el-tag :type="getTrendType(item.trend)" size="small">
- {{ item.trend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(item.trend) }}%
- </el-tag>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 寮傚父鍒嗘瀽涓庢櫤鑳芥帶鍒� -->
- <div class="analysis-control">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-card class="abnormal-card">
- <template #header>
- <div class="card-header">
- <span class="card-title">寮傚父鍒嗘瀽</span>
- <el-tag type="danger" size="small">{{ abnormalCount }}涓紓甯�</el-tag>
- </div>
- </template>
- <div class="abnormal-list">
- <div v-for="(item, index) in abnormalList" :key="index" class="abnormal-item">
- <div class="abnormal-icon">
- <el-icon :color="getAbnormalColor(item.level)">
- <Warning v-if="item.level === 'warning'" />
- <CircleClose v-else />
- </el-icon>
- </div>
- <div class="abnormal-content">
- <div class="abnormal-title">{{ item.title }}</div>
- <div class="abnormal-desc">{{ item.description }}</div>
- <div class="abnormal-time">{{ item.time }}</div>
- </div>
- <div class="abnormal-action">
- <el-button link size="small" @click="handleAbnormal(item)">澶勭悊</el-button>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card class="control-card">
- <template #header>
- <div class="card-header">
- <span class="card-title">鏅鸿兘鎺у埗绯荤粺</span>
- <el-switch v-model="autoControlEnabled" @change="handleAutoControlChange" />
- </div>
- </template>
- <div class="control-content">
- <div class="control-item">
- <span class="label">宄拌胺骞崇數浠风鐞嗭細</span>
- <el-tag :type="getPriceType(currentPriceType)" size="small">
- {{ getPriceTypeText(currentPriceType) }}
- </el-tag>
- </div>
- <div class="control-item">
- <span class="label">璐熻嵎棰勬祴锛�</span>
- <span class="value">{{ loadForecast }} kW</span>
- </div>
- <div class="control-item">
- <span class="label">鑷姩鍚仠锛�</span>
- <el-tag :type="autoStartStop ? 'success' : 'info'" size="small">
- {{ autoStartStop ? '宸插惎鐢�' : '宸茬鐢�' }}
- </el-tag>
- </div>
- <div class="control-item">
- <span class="label">鏅鸿兘璋冭妭锛�</span>
- <el-progress :percentage="intelligentAdjustment" :color="getProgressColor" />
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 鐜繚鎸囨爣 -->
- <div class="environmental-indicators">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>鐜繚鎸囨爣鐩戞帶</span>
- </div>
- </template>
- <el-row :gutter="20">
- <el-col :span="8">
- <div class="indicator-item">
- <div class="indicator-title">纰虫帓鏀鹃噺</div>
- <div class="indicator-value">{{ carbonEmission }} kg</div>
- <div class="indicator-trend">
- <span>鍚屾瘮锛�</span>
- <span :class="getComparisonClass(carbonEmissionTrend)">
- {{ carbonEmissionTrend > 0 ? '+' : '' }}{{ carbonEmissionTrend }}%
- </span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="indicator-item">
- <div class="indicator-title">鐜繚杈炬爣鐜�</div>
- <div class="indicator-value">{{ environmentalCompliance }}%</div>
- <div class="indicator-trend">
- <span>鐩爣锛�</span>
- <span class="success">95%</span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="indicator-item">
- <div class="indicator-title">缁胯壊鑳芥簮鍗犳瘮</div>
- <div class="indicator-value">{{ greenEnergyRatio }}%</div>
- <div class="indicator-trend">
- <span>鐩爣锛�</span>
- <span class="success">30%</span>
- </div>
- </div>
- </el-col>
- </el-row>
- </el-card>
- </div>
-
- <!-- 澶氱淮搴︽姤琛� -->
- <div class="multi-dimensional-reports">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>澶氱淮搴︽姤琛�</span>
- </div>
- </template>
- <div class="report-filters">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-form-item label="鏃堕棿缁村害">
- <el-select v-model="reportTimeDimension" placeholder="閫夋嫨鏃堕棿缁村害">
- <el-option label="灏忔椂" value="hour" />
- <el-option label="鏃�" value="day" />
- <el-option label="鍛�" value="week" />
- <el-option label="鏈�" value="month" />
- <el-option label="骞�" value="year" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="閮ㄩ棬缁村害">
- <el-select v-model="reportDepartmentDimension" placeholder="閫夋嫨閮ㄩ棬">
- <el-option label="鍏ㄩ儴閮ㄩ棬" value="all" />
- <el-option label="鐢熶骇閮�" value="production" />
- <el-option label="鎶�鏈儴" value="technology" />
- <el-option label="琛屾斂閮�" value="administration" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="璁惧缁村害">
- <el-select v-model="reportEquipmentDimension" placeholder="閫夋嫨璁惧绫诲瀷">
- <el-option label="鍏ㄩ儴璁惧" value="all" />
- <el-option label="鐢靛姏璁惧" value="electricity" />
- <el-option label="姘村鐞嗚澶�" value="water" />
- <el-option label="姘斾綋璁惧" value="gas" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item>
- <el-button type="primary" @click="generateReport">鐢熸垚鎶ヨ〃</el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </div>
- <div class="report-preview">
- <div class="report-data">
- <el-row :gutter="20">
- <el-col :span="8">
- <div class="data-card">
- <div class="data-title">鐢靛姏娑堣��</div>
- <div class="data-value">{{ reportData.electricity }} kW路h</div>
- <div class="data-trend">
- <span :class="getTrendClass(reportData.electricityTrend)">
- {{ reportData.electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.electricityTrend) }}%
- </span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="data-card">
- <div class="data-title">姘存秷鑰�</div>
- <div class="data-value">{{ reportData.water }} m鲁</div>
- <div class="data-trend">
- <span :class="getTrendClass(reportData.waterTrend)">
- {{ reportData.waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.waterTrend) }}%
- </span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="data-card">
- <div class="data-title">姘斾綋娑堣��</div>
- <div class="data-value">{{ reportData.gas }} m鲁</div>
- <div class="data-trend">
- <span :class="getTrendClass(reportData.gasTrend)">
- {{ reportData.gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.gasTrend) }}%
- </span>
- </div>
- </div>
- </el-col>
- </el-row>
-
- <div class="report-chart">
- <div class="chart-title">鑳借�楄秼鍔垮浘</div>
- <div class="chart-bars">
- <div v-for="(item, index) in reportData.chartData" :key="index" class="chart-bar">
- <div class="bar-label">{{ item.label }}</div>
- <div class="bar-container">
- <div class="bar-fill" :style="{ height: item.percentage + '%', backgroundColor: item.color }"></div>
- </div>
- <div class="bar-value">{{ item.value }}</div>
- </div>
- </div>
- </div>
-
- <div class="report-summary">
- <div class="summary-item">
- <span class="summary-label">鎬昏兘鑰楋細</span>
- <span class="summary-value">{{ reportData.totalEnergy }} kW路h</span>
- </div>
- <div class="summary-item">
- <span class="summary-label">骞冲潎鑳借�楋細</span>
- <span class="summary-value">{{ reportData.averageEnergy }} kW路h</span>
- </div>
- <div class="summary-item">
- <span class="summary-label">鑳借�楁晥鐜囷細</span>
- <span class="summary-value">{{ reportData.efficiency }}%</span>
- </div>
- </div>
- </div>
- </div>
- </el-card>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import * as echarts from 'echarts'
-import {
- Refresh,
- Download,
- Warning,
- CircleClose,
- Document,
- Edit,
- Bell
-} from '@element-plus/icons-vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const lastUpdateTime = ref('')
-const electricityConsumption = ref(0)
-const waterConsumption = ref(0)
-const gasConsumption = ref(0)
-const electricityTrend = ref(0)
-const waterTrend = ref(0)
-const gasTrend = ref(0)
-
-// 瓒嬪娍鍒嗘瀽
-const trendTimeUnit = ref('day')
-const trendChart = ref(null)
-let chartInstance = null
-
-// 缁熻鎶ヨ〃
-const statisticsPeriod = ref('month')
-const totalEnergyConsumption = ref(0)
-const yearOverYear = ref(0)
-const monthOverMonth = ref(0)
-const energySavingRate = ref(0)
-
-// 鑳借�楁帓鍚�
-const rankingType = ref('department')
-const rankingList = ref([])
-
-// 寮傚父鍒嗘瀽
-const abnormalCount = ref(0)
-const abnormalList = ref([])
-
-// 鏅鸿兘鎺у埗
-const autoControlEnabled = ref(true)
-const currentPriceType = ref('peak')
-const loadForecast = ref(0)
-const autoStartStop = ref(true)
-const intelligentAdjustment = ref(0)
-
-// 鐜繚鎸囨爣
-const carbonEmission = ref(0)
-const carbonEmissionTrend = ref(0)
-const environmentalCompliance = ref(0)
-const greenEnergyRatio = ref(0)
-
-// 澶氱淮搴︽姤琛�
-const reportTimeDimension = ref('month')
-const reportDepartmentDimension = ref('all')
-const reportEquipmentDimension = ref('all')
-const reportData = ref({
- electricity: 0,
- water: 0,
- gas: 0,
- electricityTrend: 0,
- waterTrend: 0,
- gasTrend: 0,
- totalEnergy: 0,
- averageEnergy: 0,
- efficiency: 0,
- chartData: []
-})
-
-// 瀹氭椂鍣�
-let updateTimer = null
-
-// 鑾峰彇瓒嬪娍绫诲瀷鏍峰紡
-const getTrendType = (trend) => {
- if (trend > 0) return 'danger'
- if (trend < 0) return 'success'
- return 'info'
-}
-
-// 鑾峰彇瀵规瘮绫诲瀷鏍峰紡
-const getComparisonClass = (value) => {
- if (value > 0) return 'danger'
- if (value < 0) return 'success'
- return 'info'
-}
-
-// 鑾峰彇鎺掑悕鏍峰紡
-const getRankingClass = (rank) => {
- if (rank === 1) return 'ranking-first'
- if (rank === 2) return 'ranking-second'
- if (rank === 3) return 'ranking-third'
- return 'ranking-normal'
-}
-
-// 鑾峰彇寮傚父棰滆壊
-const getAbnormalColor = (level) => {
- return level === 'warning' ? '#E6A23C' : '#F56C6C'
-}
-
-// 鑾峰彇鐢典环绫诲瀷鏍峰紡
-const getPriceType = (type) => {
- const typeMap = {
- peak: 'danger',
- normal: 'warning',
- valley: 'success'
- }
- return typeMap[type] || 'info'
-}
-
-// 鑾峰彇鐢典环绫诲瀷鏂囨湰
-const getPriceTypeText = (type) => {
- const typeMap = {
- peak: '宄版椂',
- normal: '骞虫椂',
- valley: '璋锋椂'
- }
- return typeMap[type] || '鏈煡'
-}
-
-// 鑾峰彇杩涘害鏉¢鑹�
-const getProgressColor = (percentage) => {
- if (percentage < 50) return '#67C23A'
- if (percentage < 80) return '#E6A23C'
- return '#F56C6C'
-}
-
-// 鑾峰彇瓒嬪娍鏍峰紡
-const getTrendClass = (trend) => {
- if (trend > 0) return 'trend-up'
- if (trend < 0) return 'trend-down'
- return 'trend-stable'
-}
-
-// 妯℃嫙鏁版嵁鐢熸垚
-const generateMockData = () => {
- // 瀹炴椂鑳借�楁暟鎹�
- electricityConsumption.value = Math.floor(Math.random() * 1000) + 2000
- waterConsumption.value = Math.floor(Math.random() * 100) + 150
- gasConsumption.value = Math.floor(Math.random() * 50) + 80
-
- // 瓒嬪娍鏁版嵁
- electricityTrend.value = (Math.random() * 20 - 10).toFixed(1)
- waterTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
- gasTrend.value = (Math.random() * 12 - 6).toFixed(1)
-
- // 缁熻鏁版嵁
- totalEnergyConsumption.value = Math.floor(Math.random() * 50000) + 100000
- yearOverYear.value = (Math.random() * 20 - 10).toFixed(1)
- monthOverMonth.value = (Math.random() * 15 - 7.5).toFixed(1)
- energySavingRate.value = (Math.random() * 10 + 5).toFixed(1)
-
- // 鎺掑悕鏁版嵁
- rankingList.value = [
- { name: '鐢熶骇杞﹂棿A', value: Math.floor(Math.random() * 5000) + 10000, trend: (Math.random() * 20 - 10).toFixed(1) },
- { name: '鐢熶骇杞﹂棿B', value: Math.floor(Math.random() * 4000) + 8000, trend: (Math.random() * 20 - 10).toFixed(1) },
- { name: '鎶�鏈爺鍙戦儴', value: Math.floor(Math.random() * 3000) + 6000, trend: (Math.random() * 20 - 10).toFixed(1) },
- { name: '琛屾斂鍔炲叕鍖�', value: Math.floor(Math.random() * 2000) + 4000, trend: (Math.random() * 20 - 10).toFixed(1) },
- { name: '鍚庡嫟淇濋殰鍖�', value: Math.floor(Math.random() * 1500) + 3000, trend: (Math.random() * 20 - 10).toFixed(1) }
- ].sort((a, b) => b.value - a.value)
-
- // 寮傚父鏁版嵁
- abnormalCount.value = Math.floor(Math.random() * 5) + 1
- abnormalList.value = [
- { level: 'warning', title: '鐢靛姏璐熻嵎杩囬珮', description: '鐢熶骇杞﹂棿A鐢靛姏璐熻嵎杈惧埌85%锛屽缓璁鏌ヨ澶囪繍琛岀姸鎬�', time: '2鍒嗛挓鍓�' },
- { level: 'error', title: '姘村帇寮傚父', description: '姘村鐞嗚澶囧帇鍔涘紓甯革紝褰撳墠鍘嬪姏0.3MPa锛屼綆浜庢甯歌寖鍥�', time: '5鍒嗛挓鍓�' }
- ]
-
- // 鏅鸿兘鎺у埗鏁版嵁
- loadForecast.value = Math.floor(Math.random() * 500) + 1500
- intelligentAdjustment.value = Math.floor(Math.random() * 30) + 60
-
- // 鐜繚鎸囨爣
- carbonEmission.value = Math.floor(Math.random() * 1000) + 5000
- carbonEmissionTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
- environmentalCompliance.value = (Math.random() * 5 + 95).toFixed(1)
- greenEnergyRatio.value = (Math.random() * 10 + 25).toFixed(1)
-
- // 鏇存柊鏈�鍚庢洿鏂版椂闂�
- lastUpdateTime.value = new Date().toLocaleString()
-
- // 鍚屾椂鏇存柊鎶ヨ〃鏁版嵁
- generateReportData()
-}
-
-// 鍒濆鍖栬秼鍔垮浘琛�
-const initTrendChart = () => {
- if (chartInstance) {
- chartInstance.dispose()
- }
-
- chartInstance = echarts.init(trendChart.value)
-
- const option = {
- title: {
- text: '鑳借�楄秼鍔垮垎鏋�',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['鐢靛姏', '姘�', '姘斾綋'],
- bottom: 10
- },
- xAxis: {
- type: 'category',
- data: generateTimeData()
- },
- yAxis: {
- type: 'value',
- name: '娑堣�楅噺'
- },
- series: [
- {
- name: '鐢靛姏',
- type: 'line',
- data: generateSeriesData(),
- smooth: true
- },
- {
- name: '姘�',
- type: 'line',
- data: generateSeriesData(),
- smooth: true
- },
- {
- name: '姘斾綋',
- type: 'line',
- data: generateSeriesData(),
- smooth: true
- }
- ]
- }
-
- chartInstance.setOption(option)
-}
-
-// 鐢熸垚鏃堕棿鏁版嵁
-const generateTimeData = () => {
- const data = []
- const now = new Date()
-
- switch (trendTimeUnit.value) {
- case 'hour':
- for (let i = 23; i >= 0; i--) {
- const time = new Date(now.getTime() - i * 60 * 60 * 1000)
- data.unshift(time.getHours() + ':00')
- }
- break
- case 'day':
- for (let i = 29; i >= 0; i--) {
- const time = new Date(now.getTime() - i * 24 * 60 * 60 * 1000)
- data.unshift(time.getDate() + '鏃�')
- }
- break
- case 'week':
- for (let i = 11; i >= 0; i--) {
- data.unshift(`绗�${12 - i}鍛╜)
- }
- break
- case 'month':
- for (let i = 11; i >= 0; i--) {
- const month = (12 - i) % 12 || 12
- data.unshift(`${month}鏈坄)
- }
- break
- case 'year':
- for (let i = 4; i >= 0; i--) {
- const year = new Date().getFullYear() - i
- data.unshift(`${year}骞碻)
- }
- break
- }
-
- return data
-}
-
-// 鐢熸垚绯诲垪鏁版嵁
-const generateSeriesData = () => {
- const data = []
- const count = trendTimeUnit.value === 'hour' ? 24 :
- trendTimeUnit.value === 'day' ? 30 :
- trendTimeUnit.value === 'week' ? 12 :
- trendTimeUnit.value === 'month' ? 12 : 5
-
- for (let i = 0; i < count; i++) {
- data.push(Math.floor(Math.random() * 1000) + 500)
- }
-
- return data
-}
-
-// 澶勭悊瓒嬪娍鏃堕棿鍙樺寲
-const handleTrendTimeChange = () => {
- nextTick(() => {
- initTrendChart()
- })
-}
-
-// 澶勭悊缁熻鍛ㄦ湡鍙樺寲
-const handleStatisticsChange = () => {
- generateMockData()
-}
-
-// 澶勭悊鎺掑悕绫诲瀷鍙樺寲
-const handleRankingChange = () => {
- // 鏍规嵁绫诲瀷閲嶆柊鐢熸垚鎺掑悕鏁版嵁
- generateMockData()
-}
-
-// 澶勭悊鑷姩鎺у埗鍙樺寲
-const handleAutoControlChange = (value) => {
- ElMessage.success(`鏅鸿兘鎺у埗绯荤粺宸�${value ? '鍚敤' : '绂佺敤'}`)
-}
-
-// 澶勭悊寮傚父
-const handleAbnormal = (item) => {
- ElMessage.info(`姝e湪澶勭悊寮傚父锛�${item.title}`)
-}
-
-// 鍒锋柊鏁版嵁
-const refreshData = () => {
- generateMockData()
- if (chartInstance) {
- initTrendChart()
- }
- ElMessage.success('鏁版嵁宸插埛鏂�')
-}
-
-// 瀵煎嚭缁熻
-const exportStatistics = () => {
- ElMessage.success('缁熻鏁版嵁瀵煎嚭鎴愬姛')
-}
-
-// 瀵煎嚭鐜繚鎶ュ憡
-const exportEnvironmentalReport = () => {
- ElMessage.success('鐜繚鎶ュ憡瀵煎嚭鎴愬姛')
-}
-
-// 鐢熸垚鑷畾涔夋姤琛�
-const generateCustomReport = () => {
- ElMessage.info('鑷畾涔夋姤琛ㄥ姛鑳藉紑鍙戜腑...')
-}
-
-// 璁㈤槄鎶ヨ〃
-const subscribeReport = () => {
- ElMessage.info('鎶ヨ〃璁㈤槄鍔熻兘寮�鍙戜腑...')
-}
-
-// 鐢熸垚鎶ヨ〃鏁版嵁
-const generateReportData = () => {
- // 鐢熸垚鍩虹鏁版嵁
- reportData.value.electricity = Math.floor(Math.random() * 5000) + 8000
- reportData.value.water = Math.floor(Math.random() * 200) + 300
- reportData.value.gas = Math.floor(Math.random() * 100) + 150
-
- // 鐢熸垚瓒嬪娍鏁版嵁
- reportData.value.electricityTrend = (Math.random() * 20 - 10).toFixed(1)
- reportData.value.waterTrend = (Math.random() * 15 - 7.5).toFixed(1)
- reportData.value.gasTrend = (Math.random() * 12 - 6).toFixed(1)
-
- // 璁$畻鎬昏兘鑰楀拰骞冲潎鑳借��
- reportData.value.totalEnergy = reportData.value.electricity + reportData.value.water * 0.1 + reportData.value.gas * 0.05
- reportData.value.averageEnergy = Math.floor(reportData.value.totalEnergy / 3)
- reportData.value.efficiency = (Math.random() * 20 + 80).toFixed(1)
-
- // 鐢熸垚鍥捐〃鏁版嵁
- const labels = ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩']
- const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399', '#9c27b0', '#ff9800']
-
- reportData.value.chartData = labels.map((label, index) => ({
- label,
- value: Math.floor(Math.random() * 1000) + 500,
- percentage: Math.floor(Math.random() * 40) + 30,
- color: colors[index]
- }))
-}
-
-// 鐢熸垚鎶ヨ〃
-const generateReport = () => {
- generateReportData()
- ElMessage.success('鎶ヨ〃鐢熸垚鎴愬姛')
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// 鍚姩瀹氭椂鏇存柊
-const startAutoUpdate = () => {
- updateTimer = setInterval(() => {
- generateMockData()
- if (chartInstance) {
- initTrendChart()
- }
- }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
-}
-
-// 鍋滄瀹氭椂鏇存柊
-const stopAutoUpdate = () => {
- if (updateTimer) {
- clearInterval(updateTimer)
- updateTimer = null
- }
-}
-
-// 缁勪欢鎸傝浇
-onMounted(() => {
- generateMockData()
- nextTick(() => {
- initTrendChart()
- })
- startAutoUpdate()
-})
-
-// 缁勪欢鍗歌浇
-onUnmounted(() => {
- stopAutoUpdate()
- if (chartInstance) {
- chartInstance.dispose()
- }
-})
-</script>
-
-<style lang="scss" scoped>
-.app-container {
- padding: 12px;
- background: #f5f5f5;
- min-height: 100vh;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- padding: 16px;
- background: white;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-
- h2 {
- margin: 0;
- color: #303133;
- font-size: 22px;
- }
-
- .header-info {
- display: flex;
- align-items: center;
- gap: 12px;
-
- .update-time {
- color: #909399;
- font-size: 14px;
- }
- }
-}
-
-.real-time-monitor {
- margin-bottom: 12px;
-
- .monitor-card {
- .monitor-content {
- text-align: center;
- padding: 16px 0;
-
- .monitor-value {
- margin-bottom: 12px;
-
- .value {
- font-size: 28px;
- font-weight: bold;
- color: #409eff;
- }
-
- .unit {
- font-size: 14px;
- color: #909399;
- margin-left: 4px;
- }
- }
-
- .monitor-trend {
- .trend-label {
- font-size: 14px;
- color: #606266;
- margin-right: 6px;
- }
- }
- }
- }
-}
-
-.trend-analysis {
- margin-bottom: 12px;
-
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .time-selector {
- .el-radio-group {
- .el-radio {
- margin-right: 4px;
- }
- }
- }
- }
-
- .chart-container {
- padding: 16px 0;
- }
-}
-
-.statistics-ranking {
- margin-bottom: 12px;
-
- .statistics-card, .ranking-card {
- height: 100%;
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
- border-radius: 8px;
- transition: all 0.3s ease;
-
- &:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
- }
- }
-
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 12px 16px;
- border-bottom: 1px solid #f0f0f0;
- background: #fafafa;
-
- .card-title {
- font-size: 15px;
- font-weight: 600;
- color: #303133;
- }
-
- .header-actions {
- display: flex;
- gap: 8px;
- align-items: center;
- }
- }
-
- .statistics-content {
- padding: 16px;
-
- .statistics-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- padding: 10px 12px;
- background: #f8f9fa;
- border-radius: 6px;
- transition: background-color 0.3s ease;
-
- &:hover {
- background: #e9ecef;
- }
-
- &:last-child {
- margin-bottom: 0;
- }
-
- .label {
- color: #606266;
- font-size: 14px;
- font-weight: 500;
- }
-
- .value {
- font-weight: bold;
- font-size: 15px;
-
- &.success {
- color: #67c23a;
- }
- }
- }
- }
-
- .ranking-list {
- padding: 16px;
-
- .ranking-item {
- display: flex;
- align-items: center;
- padding: 12px;
- margin-bottom: 6px;
- background: #f8f9fa;
- border-radius: 6px;
- transition: all 0.3s ease;
-
- &:hover {
- background: #e9ecef;
- transform: translateX(4px);
- }
-
- &:last-child {
- margin-bottom: 0;
- }
-
- .ranking-number {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-weight: bold;
- font-size: 14px;
- margin-right: 12px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-
- &.ranking-first {
- background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
- color: #fff;
- }
-
- &.ranking-second {
- background: linear-gradient(135deg, #c0c0c0 0%, #d4d4d4 100%);
- color: #fff;
- }
-
- &.ranking-third {
- background: linear-gradient(135deg, #cd7f32 0%, #daa520 100%);
- color: #fff;
- }
-
- &.ranking-normal {
- background: linear-gradient(135deg, #f5f5f5 0%, #e9ecef 100%);
- color: #909399;
- }
- }
-
- .ranking-info {
- flex: 1;
-
- .ranking-name {
- font-weight: 600;
- color: #303133;
- margin-bottom: 4px;
- font-size: 14px;
- }
-
- .ranking-value {
- color: #606266;
- font-size: 13px;
- font-weight: 500;
- }
- }
-
- .ranking-trend {
- margin-left: 12px;
- }
- }
- }
-}
-
-.analysis-control {
- margin-bottom: 20px;
-
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
-
- .abnormal-list {
- .abnormal-item {
- display: flex;
- align-items: flex-start;
- padding: 15px 0;
- border-bottom: 1px solid #f0f0f0;
-
- &:last-child {
- border-bottom: none;
- }
-
- .abnormal-icon {
- margin-right: 15px;
- margin-top: 2px;
- }
-
- .abnormal-content {
- flex: 1;
-
- .abnormal-title {
- font-weight: bold;
- color: #303133;
- margin-bottom: 5px;
- }
-
- .abnormal-desc {
- color: #606266;
- font-size: 14px;
- margin-bottom: 5px;
- }
-
- .abnormal-time {
- color: #909399;
- font-size: 12px;
- }
- }
-
- .abnormal-action {
- margin-left: 15px;
- }
- }
- }
-
- .control-content {
- .control-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-
- &:last-child {
- margin-bottom: 0;
- }
-
- .label {
- color: #606266;
- font-size: 14px;
- }
-
- .value {
- font-weight: bold;
- color: #303133;
- }
- }
- }
-}
-
-.environmental-indicators {
- margin-bottom: 20px;
-
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .header-actions {
- display: flex;
- gap: 10px;
- }
- }
-
- .indicator-item {
- text-align: center;
- padding: 20px 0;
-
- .indicator-title {
- color: #606266;
- font-size: 14px;
- margin-bottom: 10px;
- }
-
- .indicator-value {
- font-size: 24px;
- font-weight: bold;
- color: #409eff;
- margin-bottom: 10px;
- }
-
- .indicator-trend {
- font-size: 12px;
- color: #909399;
-
- .success {
- color: #67c23a;
- }
- }
- }
-}
-
-.multi-dimensional-reports {
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .header-actions {
- display: flex;
- gap: 10px;
- }
- }
-
- .report-filters {
- padding: 20px 0;
- border-bottom: 1px solid #f0f0f0;
- margin-bottom: 20px;
- }
-
- .report-preview {
- .report-data {
- padding: 20px 0;
-
- .data-card {
- text-align: center;
- padding: 16px;
- background: #f8f9fa;
- border-radius: 8px;
- margin-bottom: 16px;
-
- .data-title {
- color: #606266;
- font-size: 14px;
- margin-bottom: 8px;
- }
-
- .data-value {
- font-size: 20px;
- font-weight: bold;
- color: #303133;
- margin-bottom: 8px;
- }
-
- .data-trend {
- font-size: 12px;
-
- .trend-up {
- color: #f56c6c;
- }
-
- .trend-down {
- color: #67c23a;
- }
-
- .trend-stable {
- color: #909399;
- }
- }
- }
-
- .report-chart {
- margin: 20px 0;
- padding: 20px;
- background: #f8f9fa;
- border-radius: 8px;
-
- .chart-title {
- text-align: center;
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- margin-bottom: 16px;
- }
-
- .chart-bars {
- display: flex;
- justify-content: space-around;
- align-items: flex-end;
- height: 120px;
-
- .chart-bar {
- text-align: center;
- flex: 1;
- margin: 0 8px;
-
- .bar-label {
- font-size: 12px;
- color: #606266;
- margin-bottom: 8px;
- }
-
- .bar-container {
- height: 80px;
- background: #e9ecef;
- border-radius: 4px;
- position: relative;
- margin-bottom: 8px;
- }
-
- .bar-fill {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- border-radius: 4px;
- transition: height 0.3s ease;
- }
-
- .bar-value {
- font-size: 12px;
- color: #303133;
- font-weight: 500;
- }
- }
- }
- }
-
- .report-summary {
- display: flex;
- justify-content: space-around;
- padding: 20px;
- background: #f8f9fa;
- border-radius: 8px;
-
- .summary-item {
- text-align: center;
-
- .summary-label {
- display: block;
- color: #606266;
- font-size: 14px;
- margin-bottom: 8px;
- }
-
- .summary-value {
- font-size: 18px;
- font-weight: bold;
- color: #303133;
- }
- }
- }
- }
- }
-}
-
-// 閫氱敤鏍峰紡
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.success {
- color: #67c23a;
-}
-
-.danger {
- color: #f56c6c;
-}
-
-.warning {
- color: #e6a23c;
-}
-
-.info {
- color: #909399;
-}
-</style>
diff --git a/src/views/energyManagement/energyPeriodTime/index.vue b/src/views/energyManagement/energyPeriodTime/index.vue
deleted file mode 100644
index 49bb226..0000000
--- a/src/views/energyManagement/energyPeriodTime/index.vue
+++ /dev/null
@@ -1,462 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鏃ユ湡锛�</span>
- <!-- <el-time-picker
- style="width: 240px;margin-right: 10px"
- v-model="searchForm.startTime"
- value-format="HH:mm:ss"
- format="HH:mm:ss"
- type="time"
- placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
- clearable
- /> -->
- <el-date-picker
- v-model="searchForm.date"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- />
- <!-- <el-time-picker
- v-model="searchForm.timeRange"
- is-range
- arrow-control
- range-separator="To"
- start-placeholder="閫夋嫨缁撴潫鏃堕棿"
- end-placeholder="閫夋嫨缁撴潫鏃堕棿"
- /> -->
- <span class="search_title">鐢典环锛堝厓/搴︼級锛�</span>
- <el-input
- v-model="searchForm.price"
- style="width: 240px"
- placeholder="璇疯緭鍏ョ數浠�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</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"
- ></PIMTable>
- </div>
- <el-dialog
- v-model="dialogFormVisible"
- title="鐢ㄧ數鏃舵绠$悊"
- width="70%"
- @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="date">
- <el-date-picker
- style="width: 100%"
- v-model="form.date"
- 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="price">
- <el-input
- v-model="form.price"
- placeholder="璇疯緭鍏ョ數浠�"
- clearable
- type="number"
- step="0.01"
- min="0"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="宄版锛�" prop="peak">
- <el-input
- v-model="form.peak"
- placeholder="璇疯緭鍏ュ嘲娈�"
- clearable
- type="number"
- step="0.01"
- min="0"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璋锋锛�" prop="valley">
- <el-input
- v-model="form.valley"
- placeholder="璇疯緭鍏ヨ胺娈�"
- clearable
- type="number"
- step="0.01"
- min="0"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞虫锛�" prop="flat">
- <el-input
- v-model="form.flat"
- placeholder="璇疯緭鍏ュ钩娈�"
- clearable
- type="number"
- step="0.01"
- min="0"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="灏栨锛�" prop="sharp">
- <el-input
- v-model="form.sharp"
- placeholder="璇疯緭鍏ュ皷娈�"
- clearable
- type="number"
- step="0.01"
- min="0"
- />
- </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>
- </div>
-</template>
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, getCurrentInstance} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import {periodListPage,periodDelete,periodAdd,periodUpdate} from "@/api/energyManagement/index.js";
-const { proxy } = getCurrentInstance();
-
-const data = reactive({
- searchForm: {
- date: "",
- price: ""
- },
- form: {
- date: "",
- price: "",
- peak: "",
- valley: "",
- flat: "",
- sharp: ""
- }
-});
-const { searchForm,form } = toRefs(data);
-const page = ref({
- current: 1,
- size: 100,
- total: 0
-});
-const dialogFormVisible = ref(false);
-const selectedRows = ref([]);
-const operationType = ref('');
-const tableData = ref([]);
-const emit = defineEmits(['close'])
-const tableLoading = ref(false);
-const tableColumn = ref([
- // {
- // label: "鏃舵鍚嶇О",
- // prop: "timeName",
- // width: 200,
- // },
- {
- label: "鏃ユ湡",
- prop: "date",
- width: 200,
- },
- {
- label: "鐢典环锛堝厓/搴︼級",
- prop: "price",
- width: 200,
- },
- {
- label: "宄版",
- prop: "peak",
- },
- {
- label: "璋锋",
- prop: "valley",
- },
- {
- label: "骞虫",
- prop: "flat",
- },
- {
- label: "灏栨",
- prop: "sharp",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/equipmentEnergyConsumption/importData",
- // 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
- beforeUpload: (file) => {
- console.log('鏂囦欢鍗冲皢涓婁紶', file);
- // 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
- const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
- if (!isValid) {
- proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
- }
- return isValid;
- },
- // 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
- onChange: (file, fileList) => {
- console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
- },
- // 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
- onSuccess: (response, file, fileList) => {
- console.log('涓婁紶鎴愬姛', response, file, fileList);
- if(response.code === 200){
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- }else if(response.code === 500){
- ElMessageBox.error(response.msg);
- }else{
- ElMessageBox.warning(response.msg);
- }
- },
- // 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
- onError: (error, file, fileList) => {
- console.error('涓婁紶澶辫触', error, file, fileList);
- ElMessageBox.error("鏂囦欢涓婁紶澶辫触");
- },
- // 鏂囦欢涓婁紶杩涘害鍥炶皟
- onProgress: (event, file, fileList) => {
- console.log('涓婁紶涓�...', event.percent);
- }
-});
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-//閲嶇疆
-const resetFilters = () => {
- searchForm.value = {
- date: "",
- price: ""
- };
- getList();
-
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- periodListPage({ ...searchForm.value, ...page.value }).then((res) => {
- tableLoading.value = false;
- if (res && res.data) {
- tableData.value = res.data.records || [];
- page.value.total = res.data.total || 0;
- } else {
- tableData.value = [];
- page.value.total = 0;
- ElMessageBox.warning('鏈幏鍙栧埌鏁版嵁');
- }
- })
- .catch((err) => {
- tableLoading.value = false;
- console.error('鏁版嵁鍔犺浇澶辫触:', err);
- ElMessageBox.error('鏁版嵁鍔犺浇澶辫触锛岃閲嶈瘯');
- });
-};
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- // form.value.maintainer = userStore.nickName;
- // form.value.maintenanceTime = getCurrentDate();
- form.value = {}
- proxy.resetForm("formRef");
- periodListPage().then((res) => {
- codeList.value = res.data;
- });
- if (type === "edit") {
- form.value = {...row}
- }
-}
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- openDialog(type, row)
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "add") {
- periodAdd(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- getList()
- })
- } else {
- periodUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- getList()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "璁惧鑳借��";
- upload.open = true;
- // 娓呯┖涓婃涓婁紶鐨勬枃浠跺垪琛�
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-function importTemplate() {
- proxy.download(
- "/equipmentEnergyConsumption/export",
- {},
- '璁惧鑳借�楀鍏ユā鐗�.xlsx'
- );
-}
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- proxy.$refs["uploadRef"].submit();
-}
-
-/** 寮规鍏抽棴鏃舵竻绌烘枃浠跺垪琛� */
-function handleDialogClose() {
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-
-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(() => {
- tableLoading.value = true;
- periodDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/energyPeriod/export", {}, "鐢ㄧ數鏃舵绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/energyManagement/energyPower/components/formDia.vue b/src/views/energyManagement/energyPower/components/formDia.vue
deleted file mode 100644
index 518a254..0000000
--- a/src/views/energyManagement/energyPower/components/formDia.vue
+++ /dev/null
@@ -1,235 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="璁惧鑳借��"
- width="70%"
- @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="code">
- <el-select
- v-model="form.code"
- placeholder="璇烽�夋嫨"
- clearable
- @change="setName"
- :disabled="operationType !== 'add'"
- >
- <el-option
- v-for="item in codeList"
- :key="item.deviceModel"
- :label="item.deviceName"
- :value="item.deviceModel"
- >
- {{item.deviceName + '--' + item.deviceModel}}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢ㄧ數娑堣�楀尯鍩燂細" prop="electricityConsumptionAreaId">
- <el-cascader
- v-model="form.electricityConsumptionAreaId"
- :options="areaList"
- :props="{
- value: 'id',
- label: 'label',
- children: 'children',
- checkStrictly: true,
- }"
- placeholder="璇烽�夋嫨鍖哄煙"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="姣忔棩闄愬埗鐢甸噺锛�" prop="everyNum">
- <el-input
- v-model="form.everyNum"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰濆畾鍔熺巼锛�" prop="powerRating">
- <el-input
- v-model="form.powerRating"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹為檯鍔熺巼锛�" prop="powerActual">
- <el-input
- v-model="form.powerActual"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="杩愯鏃堕棿锛�" prop="runDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.runDate"
- 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="dayNum">
- <el-input
- v-model="form.dayNum"
- 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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate, areaListTree} from "@/api/energyManagement/index.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- name: "",
- code: "",
- everyNum: "",
- powerRating: "",
- powerActual: "",
- runDate: "",
- dayNum: "",
- electricityConsumptionAreaId: "",
- },
- rules: {
- code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- runDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- everyNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- powerRating: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- powerActual: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- dayNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- electricityConsumptionAreaId: [{ required: true, message: "璇烽�夋嫨鍖哄煙", trigger: "change" }],
- },
-})
-const { form, rules } = toRefs(data);
-const codeList = ref([])
-const areaList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- // form.value.maintainer = userStore.nickName;
- // form.value.maintenanceTime = getCurrentDate();
- form.value = {}
- proxy.resetForm("formRef");
-
- // 鑾峰彇璁惧鍒楄〃
- deviceList().then((res) => {
- codeList.value = res.data;
- });
-
- // 鑾峰彇鍖哄煙鍒楄〃
- areaListTree().then((res) => {
- areaList.value = res;
- console.log("areaList", res);
- });
-
- if (type === "edit") {
- form.value = {...row}
- // 缂栬緫鏃讹紝灏嗗崟涓狪D杞崲涓烘暟缁勬牸寮忕敤浜庡洖鏄�
- if (row.electricityConsumptionAreaId) {
- form.value.electricityConsumptionAreaId = [row.electricityConsumptionAreaId];
- }
- }
-}
-const setName = (code) => {
- const index = codeList.value.findIndex(item => item.deviceModel === code);
- if (index > -1) {
- console.log(codeList)
- form.value.name = codeList.value[index].deviceName;
- }
-}
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- // 鎻愪氦鍓嶅鐞� electricityConsumptionAreaId锛屽彇鏁扮粍鐨勬渶鍚庝竴涓��
- const submitData = { ...form.value };
- if (Array.isArray(submitData.electricityConsumptionAreaId) && submitData.electricityConsumptionAreaId.length > 0) {
- submitData.electricityConsumptionAreaId = submitData.electricityConsumptionAreaId[submitData.electricityConsumptionAreaId.length - 1];
- }
-
- if (operationType.value === "add") {
- equipmentEnergyAdd(submitData).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- })
- } else {
- equipmentEnergyUpdate(submitData).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/energyManagement/energyPower/index.vue b/src/views/energyManagement/energyPower/index.vue
deleted file mode 100644
index 6311019..0000000
--- a/src/views/energyManagement/energyPower/index.vue
+++ /dev/null
@@ -1,322 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">璁惧鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.name"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <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 type="info" plain icon="Upload" @click="handleImport">瀵煎叆</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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- <el-dialog
- :title="upload.title"
- v-model="upload.open"
- width="400px"
- append-to-body
- @close="handleDialogClose"
- >
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url"
- :disabled="upload.isUploading"
- :before-upload="upload.beforeUpload"
- :on-progress="upload.onProgress"
- :on-success="upload.onSuccess"
- :on-error="upload.onError"
- :on-change="upload.onChange"
- :auto-upload="false"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
- <el-link
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate"
- >涓嬭浇妯℃澘</el-link
- >
- </div>
- </template>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, getCurrentInstance} from "vue";
-import FormDia from "@/views/energyManagement/energyPower/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import {equipmentEnergyDelete, equipmentEnergyListPage} from "@/api/energyManagement/index.js";
-const { proxy } = getCurrentInstance();
-
-const data = reactive({
- searchForm: {
- name: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const selectedRows = ref([]);
-const tableColumn = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "name",
- width: 200,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "code",
- width: 200,
- },
- {
- label: "棰濆畾鍔熺巼",
- prop: "powerRating",
- },
- {
- label: "瀹為檯鍔熺巼",
- prop: "powerActual",
- },
- {
- label: "杩愯鏃堕棿",
- prop: "runDate",
- width:150
- },
- {
- label: "褰撴棩鐢ㄧ數閲�",
- prop: "dayNum",
- width: 150,
- },
- // {
- // label: "绱鐢ㄧ數閲�",
- // prop: "sumNum",
- // width: 150,
- // },
- {
- label: "姣忔棩闄愬埗鐢甸噺",
- prop: "everyNum",
- width:220
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/equipmentEnergyConsumption/importData",
- // 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
- beforeUpload: (file) => {
- console.log('鏂囦欢鍗冲皢涓婁紶', file);
- // 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
- const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
- if (!isValid) {
- proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
- }
- return isValid;
- },
- // 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
- onChange: (file, fileList) => {
- console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
- },
- // 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
- onSuccess: (response, file, fileList) => {
- console.log('涓婁紶鎴愬姛', response, file, fileList);
- if(response.code === 200){
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- }else if(response.code === 500){
- proxy.$modal.msgError(response.msg);
- }else{
- proxy.$modal.msgWarning(response.msg);
- }
- },
- // 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
- onError: (error, file, fileList) => {
- console.error('涓婁紶澶辫触', error, file, fileList);
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- },
- // 鏂囦欢涓婁紶杩涘害鍥炶皟
- onProgress: (event, file, fileList) => {
- console.log('涓婁紶涓�...', event.percent);
- }
-});
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- equipmentEnergyListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "璁惧鑳借��";
- upload.open = true;
- // 娓呯┖涓婃涓婁紶鐨勬枃浠跺垪琛�
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-function importTemplate() {
- proxy.download(
- "/equipmentEnergyConsumption/export",
- {},
- '璁惧鑳借�楀鍏ユā鐗�.xlsx'
- );
-}
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- proxy.$refs["uploadRef"].submit();
-}
-
-/** 寮规鍏抽棴鏃舵竻绌烘枃浠跺垪琛� */
-function handleDialogClose() {
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-
-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(() => {
- tableLoading.value = true;
- equipmentEnergyDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/equipmentEnergyConsumption/export", {}, "鑳芥簮鍔熺巼.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/energyManagement/energyTrends/index.vue b/src/views/energyManagement/energyTrends/index.vue
deleted file mode 100644
index 7f67be7..0000000
--- a/src/views/energyManagement/energyTrends/index.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">璁惧鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.name"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- <el-button @click="handleOut" style="margin-left: 10px">瀵煎嚭</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"
- ></PIMTable>
- </div>
-
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, getCurrentInstance} from "vue";
-import {listPageByTrend} from "@/api/energyManagement/index.js";
-import { ElMessageBox } from "element-plus";
-
-const { proxy } = getCurrentInstance();
-
-const data = reactive({
- searchForm: {
- name: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "name",
- width: 220,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "code",
- width: 220,
- },
- {
- label: "杩愯鏃堕棿",
- prop: "runDate",
- width: 250,
- },
- {
- label: "鏄ㄦ棩鐢ㄧ數閲�",
- prop: "toDayNum",
- },
- {
- label: "鏈湀骞冲潎鐢甸噺",
- prop: "avgNum",
- width:150
- },
- {
- label: "瓒嬪娍",
- prop: "trend",
- width: 220,
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- listPageByTrend({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/equipmentEnergyConsumption/exportTwo", {}, "鑳芥簮瓒嬪娍.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/energyManagement/gasManagement/index.vue b/src/views/energyManagement/gasManagement/index.vue
deleted file mode 100644
index a9b9abe..0000000
--- a/src/views/energyManagement/gasManagement/index.vue
+++ /dev/null
@@ -1,624 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>鐢ㄦ皵绠$悊绯荤粺</h2>
- <div class="header-info">
- <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
- <el-button type="primary" size="small" @click="refreshData">
- <el-icon><Refresh /></el-icon>
- 鍒锋柊鏁版嵁
- </el-button>
- </div>
- </div>
-
- <!-- 缁熻鍗$墖鍖哄煙 -->
- <div class="stats-cards">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-icon gas-device">
- <el-icon size="32"><Box /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ totalDevices }}</div>
- <div class="stat-label">鍦ㄧ敤璁惧</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-icon daily-consumption">
- <el-icon size="32"><TrendCharts /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ dailyConsumption }} m鲁</div>
- <div class="stat-label">鏃ヨ�楅噺</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-icon monthly-consumption">
- <el-icon size="32"><DataLine /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-value">{{ monthlyConsumption }} m鲁</div>
- <div class="stat-label">鏈堣�楅噺</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card">
- <div class="stat-content">
- <div class="stat-icon gas-price">
- <el-icon size="32"><Money /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-value">楼{{ gasUnitPrice }}</div>
- <div class="stat-label">姘斾綋鍗曚环</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璐圭敤缁熻鍖哄煙 -->
- <div class="cost-stats">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-card class="cost-card">
- <template #header>
- <div class="card-header">
- <span>鏃ヨ垂鐢ㄧ粺璁�</span>
- <el-tag type="success" size="small">浠婃棩</el-tag>
- </div>
- </template>
- <div class="cost-content">
- <div class="cost-main">
- <span class="cost-amount">楼{{ dailyTotalCost.toFixed(2) }}</span>
- <span class="cost-unit">鍏�</span>
- </div>
- <div class="cost-details">
- <div class="cost-item">
- <span>娑堣�楅噺锛�</span>
- <span>{{ dailyConsumption }} m鲁</span>
- </div>
- <div class="cost-item">
- <span>鍗曚环锛�</span>
- <span>楼{{ gasUnitPrice }}/m鲁</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card class="cost-card">
- <template #header>
- <div class="card-header">
- <span>鏈堣垂鐢ㄧ粺璁�</span>
- <el-tag type="primary" size="small">鏈湀</el-tag>
- </div>
- </template>
- <div class="cost-content">
- <div class="cost-main">
- <span class="cost-amount">楼{{ monthlyTotalCost.toFixed(2) }}</span>
- <span class="cost-unit">鍏�</span>
- </div>
- <div class="cost-details">
- <div class="cost-item">
- <span>娑堣�楅噺锛�</span>
- <span>{{ monthlyConsumption }} m鲁</span>
- </div>
- <div class="cost-item">
- <span>骞冲潎鍗曚环锛�</span>
- <span>楼{{ gasUnitPrice }}/m鲁</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璁惧鍒楄〃鍖哄煙 -->
- <div class="device-section">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>璁惧鐩戞帶</span>
- <div class="header-actions">
- <el-button type="primary" size="small" @click="addDevice">
- <el-icon><Plus /></el-icon>
- 娣诲姞璁惧
- </el-button>
- </div>
- </div>
- </template>
-
- <el-table :data="deviceList" border style="width: 100%" v-loading="tableLoading">
- <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 />
- <el-table-column label="璁惧绫诲瀷" prop="deviceType" width="120" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" width="150" show-overflow-tooltip />
- <el-table-column label="褰撳墠鍘嬪姏(MPa)" prop="currentPressure" width="130" show-overflow-tooltip>
- <template #default="scope">
- <span :class="getPressureClass(scope.row.currentPressure)">
- {{ scope.row.currentPressure }}
- </span>
- </template>
- </el-table-column>
- <el-table-column label="褰撳墠娓╁害(鈩�)" prop="currentTemperature" width="130" show-overflow-tooltip>
- <template #default="scope">
- <span :class="getTemperatureClass(scope.row.currentTemperature)">
- {{ scope.row.currentTemperature }}
- </span>
- </template>
- </el-table-column>
- <el-table-column label="姘斾綋娴撳害(ppm)" prop="gasConcentration" width="140" show-overflow-tooltip>
- <template #default="scope">
- <span :class="getConcentrationClass(scope.row.gasConcentration)">
- {{ scope.row.gasConcentration }}
- </span>
- </template>
- </el-table-column>
- <el-table-column label="杩愯鐘舵��" prop="status" width="100" show-overflow-tooltip>
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)" size="small">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鏈�鍚庢洿鏂�" prop="lastUpdate" width="160" show-overflow-tooltip />
- <el-table-column label="鎿嶄綔" align="center" width="100" fixed="right">
- <template #default="scope">
- <el-button link size="small" @click="editDevice(scope.row)">
- 缂栬緫
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </div>
-
- <!-- 娣诲姞/缂栬緫璁惧寮圭獥 -->
- <el-dialog v-model="deviceDialogVisible" :title="dialogTitle" width="600px">
- <el-form :model="deviceForm" :rules="deviceRules" ref="deviceFormRef" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁惧缂栧彿" prop="deviceCode">
- <el-input v-model="deviceForm.deviceCode" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О" prop="deviceName">
- <el-input v-model="deviceForm.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁惧绫诲瀷" prop="deviceType">
- <el-select v-model="deviceForm.deviceType" placeholder="璇烽�夋嫨璁惧绫诲瀷" style="width: 100%">
- <el-option label="娑插寲姘斿偍缃�" value="娑插寲姘斿偍缃�" />
- <el-option label="鍘嬬缉姘斿偍缃�" value="鍘嬬缉姘斿偍缃�" />
- <el-option label="澶╃劧姘斿偍缃�" value="澶╃劧姘斿偍缃�" />
- <el-option label="姘ф皵鍌ㄧ綈" value="姘ф皵鍌ㄧ綈" />
- <el-option label="鍏朵粬" value="鍏朵粬" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
- <el-input v-model="deviceForm.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁捐鍘嬪姏(MPa)" prop="designPressure">
- <el-input-number v-model="deviceForm.designPressure" :min="0" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹圭Н(m鲁)" prop="volume">
- <el-input-number v-model="deviceForm.volume" :min="0" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button @click="deviceDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="saveDevice">淇濆瓨</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {
- Refresh,
- Box,
- TrendCharts,
- DataLine,
- Money,
- Plus
-} from '@element-plus/icons-vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const lastUpdateTime = ref('')
-const totalDevices = ref(0)
-const dailyConsumption = ref(0)
-const monthlyConsumption = ref(0)
-const gasUnitPrice = ref(0)
-const dailyTotalCost = ref(0)
-const monthlyTotalCost = ref(0)
-const deviceList = ref([])
-const tableLoading = ref(false)
-const deviceDialogVisible = ref(false)
-const dialogTitle = ref('')
-const deviceFormRef = ref()
-
-// 璁惧琛ㄥ崟鏁版嵁
-const deviceForm = reactive({
- deviceCode: '',
- deviceName: '',
- deviceType: '',
- specification: '',
- designPressure: 0,
- volume: 0
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const deviceRules = {
- deviceCode: [{ required: true, message: '璇疯緭鍏ヨ澶囩紪鍙�', trigger: 'blur' }],
- deviceName: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
- deviceType: [{ required: true, message: '璇烽�夋嫨璁惧绫诲瀷', trigger: 'change' }],
- specification: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
- designPressure: [{ required: true, message: '璇疯緭鍏ヨ璁″帇鍔�', trigger: 'blur' }],
- volume: [{ required: true, message: '璇疯緭鍏ュ绉�', trigger: 'blur' }]
-}
-
-// 瀹氭椂鍣�
-let updateTimer = null
-
-// 妯℃嫙鏁版嵁鐢熸垚
-const generateMockData = () => {
- // 鏇存柊缁熻鏁版嵁
- totalDevices.value = Math.floor(Math.random() * 8) // 0-7鍙拌澶�
- dailyConsumption.value = Math.floor(Math.random() * 100) + 200 // 200-300 m鲁
- monthlyConsumption.value = Math.floor(Math.random() * 2000) + 5000 // 5000-7000 m鲁
- gasUnitPrice.value = (Math.random() * 2 + 3).toFixed(2) // 3-5鍏�/m鲁
-
- // 璁$畻璐圭敤
- dailyTotalCost.value = dailyConsumption.value * gasUnitPrice.value
- monthlyTotalCost.value = monthlyConsumption.value * gasUnitPrice.value
-
- // 鏇存柊璁惧鍒楄〃鏁版嵁
- deviceList.value = Array.from({ length: totalDevices.value }, (_, index) => ({
- id: index + 1,
- deviceCode: `GT${String(index + 1).padStart(3, '0')}`,
- deviceName: `鍌ㄦ皵缃�${index + 1}`,
- deviceType: ['娑插寲姘斿偍缃�', '鍘嬬缉姘斿偍缃�', '澶╃劧姘斿偍缃�', '姘ф皵鍌ㄧ綈'][Math.floor(Math.random() * 4)],
- specification: `${Math.floor(Math.random() * 50) + 50}m鲁`,
- currentPressure: (Math.random() * 2 + 0.5).toFixed(2),
- currentTemperature: (Math.random() * 20 + 15).toFixed(1),
- gasConcentration: (Math.random() * 10).toFixed(2),
- status: ['running', 'stopped', 'warning', 'error'][Math.floor(Math.random() * 4)],
- lastUpdate: new Date().toLocaleString()
- }))
-
- // 鏇存柊鏈�鍚庢洿鏂版椂闂�
- lastUpdateTime.value = new Date().toLocaleString()
-}
-
-// 鑾峰彇鍘嬪姏鐘舵�佹牱寮�
-const getPressureClass = (pressure) => {
- const p = parseFloat(pressure)
- if (p < 0.8) return 'pressure-low'
- if (p > 1.5) return 'pressure-high'
- return 'pressure-normal'
-}
-
-// 鑾峰彇娓╁害鐘舵�佹牱寮�
-const getTemperatureClass = (temperature) => {
- const t = parseFloat(temperature)
- if (t < 10 || t > 35) return 'temperature-warning'
- return 'temperature-normal'
-}
-
-// 鑾峰彇娴撳害鐘舵�佹牱寮�
-const getConcentrationClass = (concentration) => {
- const c = parseFloat(concentration)
- if (c > 5) return 'concentration-warning'
- return 'concentration-normal'
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const statusMap = {
- running: 'success',
- stopped: 'info',
- warning: 'warning',
- error: 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusMap = {
- running: '杩愯涓�',
- stopped: '宸插仠姝�',
- warning: '璀﹀憡',
- error: '鏁呴殰'
- }
- return statusMap[status] || '鏈煡'
-}
-
-// 鍒锋柊鏁版嵁
-const refreshData = () => {
- generateMockData()
- ElMessage.success('鏁版嵁宸插埛鏂�')
-}
-
-// 娣诲姞璁惧
-const addDevice = () => {
- dialogTitle.value = '娣诲姞璁惧'
- Object.keys(deviceForm).forEach(key => {
- deviceForm[key] = key === 'designPressure' || key === 'volume' ? 0 : ''
- })
- deviceDialogVisible.value = true
-}
-
-// 缂栬緫璁惧
-const editDevice = (row) => {
- dialogTitle.value = '缂栬緫璁惧'
- Object.keys(deviceForm).forEach(key => {
- if (row[key] !== undefined) {
- deviceForm[key] = row[key]
- }
- })
- deviceDialogVisible.value = true
-}
-
-
-
-// 淇濆瓨璁惧
-const saveDevice = () => {
- deviceFormRef.value.validate((valid) => {
- if (valid) {
- ElMessage.success('淇濆瓨鎴愬姛')
- deviceDialogVisible.value = false
- refreshData()
- }
- })
-}
-
-
-
-// 鍚姩瀹氭椂鏇存柊
-const startAutoUpdate = () => {
- updateTimer = setInterval(() => {
- generateMockData()
- }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
-}
-
-// 鍋滄瀹氭椂鏇存柊
-const stopAutoUpdate = () => {
- if (updateTimer) {
- clearInterval(updateTimer)
- updateTimer = null
- }
-}
-
-// 缁勪欢鎸傝浇
-onMounted(() => {
- generateMockData()
- startAutoUpdate()
-})
-
-// 缁勪欢鍗歌浇
-onUnmounted(() => {
- stopAutoUpdate()
-})
-</script>
-
-<style lang="scss" scoped>
-.app-container {
- padding: 20px;
- background: #f5f5f5;
- min-height: 100vh;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding: 20px;
- background: white;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-
- h2 {
- margin: 0;
- color: #303133;
- font-size: 24px;
- }
-
- .header-info {
- display: flex;
- align-items: center;
- gap: 15px;
-
- .update-time {
- color: #909399;
- font-size: 14px;
- }
- }
-}
-
-.stats-cards {
- margin-bottom: 20px;
-
- .stat-card {
- .stat-content {
- display: flex;
- align-items: center;
- padding: 10px;
-
- .stat-icon {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 15px;
-
- &.gas-device {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
- }
-
- &.daily-consumption {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
- color: white;
- }
-
- &.monthly-consumption {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
- color: white;
- }
-
- &.gas-price {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
- color: white;
- }
- }
-
- .stat-info {
- .stat-value {
- font-size: 24px;
- font-weight: bold;
- color: #303133;
- line-height: 1;
- }
-
- .stat-label {
- font-size: 14px;
- color: #909399;
- margin-top: 5px;
- }
- }
- }
- }
-}
-
-.cost-stats {
- margin-bottom: 20px;
-
- .cost-card {
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
-
- .cost-content {
- text-align: center;
- padding: 20px 0;
-
- .cost-main {
- margin-bottom: 15px;
-
- .cost-amount {
- font-size: 36px;
- font-weight: bold;
- color: #409eff;
- }
-
- .cost-unit {
- font-size: 16px;
- color: #909399;
- margin-left: 5px;
- }
- }
-
- .cost-details {
- .cost-item {
- display: flex;
- justify-content: space-between;
- margin-bottom: 8px;
- font-size: 14px;
- color: #606266;
-
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- }
- }
-}
-
-.device-section {
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .header-actions {
- display: flex;
- gap: 10px;
- }
- }
-}
-
-// 鐘舵�佹牱寮�
-.pressure-low {
- color: #e6a23c;
- font-weight: bold;
-}
-
-.pressure-normal {
- color: #67c23a;
- font-weight: bold;
-}
-
-.pressure-high {
- color: #f56c6c;
- font-weight: bold;
-}
-
-.temperature-normal {
- color: #67c23a;
- font-weight: bold;
-}
-
-.temperature-warning {
- color: #e6a23c;
- font-weight: bold;
-}
-
-.concentration-normal {
- color: #67c23a;
- font-weight: bold;
-}
-
-.concentration-warning {
- color: #f56c6c;
- font-weight: bold;
-}
-</style>
diff --git a/src/views/energyManagement/meterCollection/index.vue b/src/views/energyManagement/meterCollection/index.vue
deleted file mode 100644
index dfa5617..0000000
--- a/src/views/energyManagement/meterCollection/index.vue
+++ /dev/null
@@ -1,556 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>鐢佃〃閲囬泦绠$悊</span>
- <el-button style="float: right; padding: 3px 0" link @click="refreshData">
- <i class="el-icon-refresh"></i> 鍒锋柊
- </el-button>
- </div>
-
- <!-- 娴嬭瘯鎸夐挳 -->
- <el-row :gutter="20" style="margin-bottom: 15px;">
- <el-col :span="24">
- <el-button @click="addTestData" type="primary" size="small">娣诲姞娴嬭瘯鏁版嵁</el-button>
- <el-button @click="clearData" type="danger" size="small">娓呯┖鏁版嵁</el-button>
- <el-button @click="testChart" type="success" size="small">娴嬭瘯鍥捐〃</el-button>
- </el-col>
- </el-row>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.meterNo"
- placeholder="璇疯緭鍏ョ數琛ㄧ紪鍙�"
- clearable
- @keyup.enter.native="handleSearch"
- >
- <i slot="prefix" class="el-input__icon el-icon-search"></i>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.location" placeholder="璇烽�夋嫨浣嶇疆" clearable>
- <el-option label="鐢熶骇杞﹂棿A" value="杞﹂棿A"></el-option>
- <el-option label="鐢熶骇杞﹂棿B" value="杞﹂棿B"></el-option>
- <el-option label="鍔炲叕鍖哄煙" value="鍔炲叕鍖�"></el-option>
- <el-option label="閰嶇數瀹�" value="閰嶇數瀹�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-date-picker
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="yyyy-MM-dd"
- value-format="yyyy-MM-dd"
- />
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-col>
- </el-row>
-
- <!-- 鐢佃〃鍒楄〃 -->
- <el-table
- :data="meterList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="meterNo" label="鐢佃〃缂栧彿" width="120" />
- <el-table-column prop="location" label="瀹夎浣嶇疆" width="120" />
- <el-table-column prop="meterType" label="鐢佃〃绫诲瀷" width="120" />
- <el-table-column prop="voltage" label="鐢靛帇绛夌骇" width="100" />
- <el-table-column prop="currentReading" label="褰撳墠璇绘暟(kWh)" width="140" />
- <el-table-column prop="lastReading" label="涓婃璇绘暟(kWh)" width="140" />
- <el-table-column prop="consumption" label="鐢ㄧ數閲�(kWh)" width="120" />
- <el-table-column prop="power" label="鍔熺巼(kW)" width="100" />
- <el-table-column prop="powerFactor" label="鍔熺巼鍥犳暟" width="100" />
- <el-table-column prop="status" label="鐘舵��" width="80">
- <template #default="scope">
- <el-tag :type="scope.row.status === '姝e父' ? 'success' : 'danger'">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="lastUpdateTime" label="鏈�鍚庢洿鏂版椂闂�" width="160" />
- <el-table-column label="鎿嶄綔" width="180" fixed="right" align="center">
- <template #default="scope">
- <el-button link @click="viewDetails(scope.row)">
- 鏌ョ湅璇︽儏
- </el-button>
- <el-button link @click="manualCollection(scope.row)">
- 鎵嬪姩閲囬泦
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <!-- 鍒嗛〉 -->
- <pagination
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.currentPage"
- :limit="pagination.pageSize"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 璇︽儏瀵硅瘽妗� -->
- <el-dialog
- title="鐢佃〃璇︽儏"
- v-model="detailDialogVisible"
- width="60%"
- @opened="onDialogOpened"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="detail-item">
- <label>鐢佃〃缂栧彿:</label>
- <span>{{ currentMeter.meterNo }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>瀹夎浣嶇疆:</label>
- <span>{{ currentMeter.location }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鐢佃〃绫诲瀷:</label>
- <span>{{ currentMeter.meterType }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鐢靛帇绛夌骇:</label>
- <span>{{ currentMeter.voltage }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>褰撳墠璇绘暟:</label>
- <span>{{ currentMeter.currentReading }} kWh</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>涓婃璇绘暟:</label>
- <span>{{ currentMeter.lastReading }} kWh</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鐢ㄧ數閲�:</label>
- <span>{{ currentMeter.consumption }} kWh</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鍔熺巼:</label>
- <span>{{ currentMeter.power }} kW</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鍔熺巼鍥犳暟:</label>
- <span>{{ currentMeter.powerFactor }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鐘舵��:</label>
- <el-tag :type="currentMeter.status === '姝e父' ? 'success' : 'danger'">
- {{ currentMeter.status }}
- </el-tag>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="detail-item">
- <label>鏈�鍚庢洿鏂版椂闂�:</label>
- <span>{{ currentMeter.lastUpdateTime }}</span>
- </div>
- </el-col>
- </el-row>
-
- <!-- 鐢ㄧ數瓒嬪娍鍥� -->
- <div style="margin-top: 20px;">
- <h4>24灏忔椂鐢ㄧ數瓒嬪娍</h4>
- <div ref="chartContainer" style="height: 300px;"></div>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script>
-import * as echarts from 'echarts'
-
-export default {
- name: 'MeterCollection',
- data() {
- return {
- loading: false,
- searchForm: {
- meterNo: '',
- location: '',
- dateRange: []
- },
- meterList: [],
- pagination: {
- currentPage: 1,
- pageSize: 10,
- total: 0
- },
- detailDialogVisible: false,
- currentMeter: {},
- chart: null
- }
- },
- created() {
- // 绔嬪嵆鐢熸垚涓�浜涙祴璇曟暟鎹�
- this.meterList = [
- {
- id: 1,
- meterNo: 'M001',
- location: '杞﹂棿A',
- meterType: '鏅鸿兘鐢佃〃',
- voltage: '380V',
- currentReading: 8500,
- lastReading: 8400,
- consumption: 100,
- power: '75.5',
- powerFactor: '0.85',
- status: '姝e父',
- lastUpdateTime: '2025-01-15 10:30:00'
- },
- {
- id: 2,
- meterNo: 'M002',
- location: '杞﹂棿B',
- meterType: '澶氬姛鑳界數琛�',
- voltage: '220V',
- currentReading: 6200,
- lastReading: 6100,
- consumption: 100,
- power: '45.2',
- powerFactor: '0.92',
- status: '姝e父',
- lastUpdateTime: '2025-01-15 10:25:00'
- }
- ]
- this.pagination.total = this.meterList.length
- },
- mounted() {
- // 寤惰繜涓�鐐规椂闂村啀璋冪敤锛岀‘淇滵OM宸茬粡娓叉煋
- this.$nextTick(() => {
- this.getMeterList()
- })
- },
- watch: {
- meterList: {
- handler(newVal) {
- console.log('meterList鏁版嵁鍙樺寲:', newVal)
- },
- deep: true,
- immediate: true
- }
- },
- methods: {
- // 鑾峰彇鐢佃〃鍒楄〃
- getMeterList() {
- this.loading = true
- // 妯℃嫙API璋冪敤
- setTimeout(() => {
- const mockData = this.generateMockData()
- this.meterList = mockData
- this.pagination.total = this.meterList.length
- this.loading = false
- }, 500)
- },
-
- // 鐢熸垚妯℃嫙鏁版嵁
- generateMockData() {
- const locations = ['杞﹂棿A', '杞﹂棿B', '鍔炲叕鍖�', '閰嶇數瀹�']
- const meterTypes = ['鏅鸿兘鐢佃〃', '澶氬姛鑳界數琛�', '鏅�氱數琛�']
- const voltages = ['220V', '380V', '10kV']
- const statuses = ['姝e父', '寮傚父']
-
- const data = []
- for (let i = 1; i <= 25; i++) {
- const currentReading = Math.floor(Math.random() * 10000) + 5000
- const lastReading = currentReading - Math.floor(Math.random() * 100) - 10
- const consumption = currentReading - lastReading
- const power = Math.random() * 100 + 20
- const powerFactor = (Math.random() * 0.3 + 0.7).toFixed(2)
-
- data.push({
- id: i,
- meterNo: `M${String(i).padStart(3, '0')}`,
- location: locations[Math.floor(Math.random() * locations.length)],
- meterType: meterTypes[Math.floor(Math.random() * meterTypes.length)],
- voltage: voltages[Math.floor(Math.random() * voltages.length)],
- currentReading: currentReading,
- lastReading: lastReading,
- consumption: consumption,
- power: power.toFixed(2),
- powerFactor: powerFactor,
- status: statuses[Math.floor(Math.random() * statuses.length)],
- lastUpdateTime: this.formatDate(new Date(Date.now() - Math.random() * 86400000))
- })
- }
- return data
- },
-
- // 鏍煎紡鍖栨棩鏈�
- formatDate(date) {
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- const hours = String(date.getHours()).padStart(2, '0')
- const minutes = String(date.getMinutes()).padStart(2, '0')
- return `${year}-${month}-${day} ${hours}:${minutes}`
- },
-
- // 鎼滅储
- handleSearch() {
- this.pagination.currentPage = 1
- this.getMeterList()
- },
-
- // 閲嶇疆鎼滅储
- resetSearch() {
- this.searchForm = {
- meterNo: '',
- location: '',
- dateRange: []
- }
- this.handleSearch()
- },
-
- // 鏌ョ湅璇︽儏
- viewDetails(row) {
- this.currentMeter = row
- this.detailDialogVisible = true
- },
-
- // 瀵硅瘽妗嗘墦寮�鍚庡垵濮嬪寲鍥捐〃
- onDialogOpened() {
- this.$nextTick(() => {
- setTimeout(() => {
- this.initChart()
- }, 100)
- })
- },
-
- // 鎵嬪姩閲囬泦
- manualCollection(row) {
- this.$message.success(`姝e湪閲囬泦鐢佃〃 ${row.meterNo} 鐨勬暟鎹�...`)
- // 妯℃嫙閲囬泦杩囩▼
- setTimeout(() => {
- row.currentReading = Math.floor(Math.random() * 100) + row.currentReading
- row.lastUpdateTime = this.formatDate(new Date())
- this.$message.success('鏁版嵁閲囬泦瀹屾垚')
- }, 1000)
- },
-
- // 鍒锋柊鏁版嵁
- refreshData() {
- this.getMeterList()
- this.$message.success('鏁版嵁宸插埛鏂�')
- },
-
- // 娣诲姞娴嬭瘯鏁版嵁
- addTestData() {
- const testData = {
- id: Date.now(),
- meterNo: `M${String(this.meterList.length + 1).padStart(3, '0')}`,
- location: '娴嬭瘯浣嶇疆',
- meterType: '娴嬭瘯鐢佃〃',
- voltage: '220V',
- currentReading: Math.floor(Math.random() * 10000) + 1000,
- lastReading: Math.floor(Math.random() * 5000) + 500,
- consumption: Math.floor(Math.random() * 100) + 10,
- power: (Math.random() * 100 + 10).toFixed(2),
- powerFactor: (Math.random() * 0.3 + 0.7).toFixed(2),
- status: '姝e父',
- lastUpdateTime: this.formatDate(new Date())
- }
- this.meterList.push(testData)
- this.pagination.total = this.meterList.length
- this.$message.success('娴嬭瘯鏁版嵁宸叉坊鍔�')
- },
-
- // 娓呯┖鏁版嵁
- clearData() {
- this.meterList = []
- this.pagination.total = 0
- this.$message.success('鏁版嵁宸叉竻绌�')
- },
-
- // 娴嬭瘯鍥捐〃
- testChart() {
- this.$message.info('鍥捐〃娴嬭瘯鍔熻兘')
- // 鍒涘缓涓�涓祴璇曞璇濇鏉ユ祴璇曞浘琛�
- this.currentMeter = {
- meterNo: 'TEST001',
- location: '娴嬭瘯浣嶇疆',
- meterType: '娴嬭瘯鐢佃〃',
- voltage: '220V',
- currentReading: 1000,
- lastReading: 900,
- consumption: 100,
- power: '50.0',
- powerFactor: '0.85',
- status: '姝e父',
- lastUpdateTime: '2025-01-15 12:00:00'
- }
- this.detailDialogVisible = true
- },
-
- // 鍒嗛〉澶у皬鏀瑰彉
- handleSizeChange(val) {
- this.pagination.pageSize = val
- this.getMeterList()
- },
-
- // 褰撳墠椤垫敼鍙�
- handleCurrentChange(val) {
- this.pagination.pageSize = val.limit
- this.pagination.currentPage = val.page
- this.getMeterList()
- },
-
- // 鍒濆鍖栧浘琛�
- initChart() {
- try {
- if (this.chart) {
- this.chart.dispose()
- this.chart = null
- }
-
- // 纭繚DOM鍏冪礌瀛樺湪
- if (!this.$refs.chartContainer) {
- console.error('鍥捐〃瀹瑰櫒涓嶅瓨鍦紝绛夊緟DOM鏇存柊...')
- // 濡傛灉瀹瑰櫒涓嶅瓨鍦紝绛夊緟涓�涓嬪啀璇�
- setTimeout(() => {
- this.initChart()
- }, 100)
- return
- }
-
- // 妫�鏌ュ鍣ㄥ昂瀵�
- const container = this.$refs.chartContainer
- if (container.offsetWidth === 0 || container.offsetHeight === 0) {
- setTimeout(() => {
- this.initChart()
- }, 100)
- return
- }
- this.chart = echarts.init(container)
-
- // 鐢熸垚24灏忔椂妯℃嫙鏁版嵁
- const hours = []
- const consumption = []
- for (let i = 0; i < 24; i++) {
- hours.push(`${i}:00`)
- consumption.push(Math.floor(Math.random() * 50) + 20)
- }
-
- const option = {
- title: {
- text: '24灏忔椂鐢ㄧ數閲忚秼鍔�',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis',
- formatter: '{b}<br/>鐢ㄧ數閲�: {c} kWh'
- },
- xAxis: {
- type: 'category',
- data: hours,
- axisLabel: {
- rotate: 45
- }
- },
- yAxis: {
- type: 'value',
- name: '鐢ㄧ數閲� (kWh)'
- },
- series: [{
- data: consumption,
- type: 'line',
- smooth: true,
- areaStyle: {
- opacity: 0.3
- },
- itemStyle: {
- color: '#409EFF'
- }
- }]
- }
-
- this.chart.setOption(option)
- } catch (error) {
- console.error('鍥捐〃鍒濆鍖栧け璐�:', error)
- this.$message.error('鍥捐〃鍒濆鍖栧け璐�: ' + error.message)
- }
- }
- },
-
- beforeUnmount() {
- if (this.chart) {
- try {
- this.chart.dispose()
- this.chart = null
- } catch (error) {
- console.error('娓呯悊鍥捐〃澶辫触:', error)
- }
- }
- }
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-
-.pagination {
- margin-top: 20px;
- text-align: right;
-}
-
-.el-table {
- margin-top: 20px;
-}
-
-.detail-item {
- margin-bottom: 15px;
- padding: 10px;
- border: 1px solid #ebeef5;
- border-radius: 4px;
- background-color: #fafafa;
-}
-
-.detail-item label {
- font-weight: bold;
- color: #606266;
- margin-right: 10px;
- min-width: 100px;
- display: inline-block;
-}
-
-.detail-item span {
- color: #303133;
-}
-
-.detail-item .el-tag {
- margin-left: 0;
-}
-</style>
diff --git a/src/views/energyManagement/waterManagement/components/formDia.vue b/src/views/energyManagement/waterManagement/components/formDia.vue
deleted file mode 100644
index 2e58ea0..0000000
--- a/src/views/energyManagement/waterManagement/components/formDia.vue
+++ /dev/null
@@ -1,221 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="鐢ㄦ按璁惧"
- width="70%"
- @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="deviceModel">
- <el-select
- v-model="form.deviceModel"
- placeholder="璇烽�夋嫨"
- clearable
- @change="setName"
- :disabled="operationType !== 'add'"
- >
- <el-option
- v-for="item in codeList"
- :key="item.deviceModel"
- :label="item.deviceName"
- :value="item.deviceModel"
- >
- {{item.deviceName + '--' + item.deviceModel}}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="姣忔棩闄愬埗姘撮噺锛�" prop="waterDayLimit">
- <el-input
- v-model="form.waterDayLimit"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="棰濆畾娴侀噺锛�" prop="ratedRate">
- <el-input
- v-model="form.ratedRate"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹為檯娴侀噺锛�" prop="actualTraffic">
- <el-input
- v-model="form.actualTraffic"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="杩愯鏃堕棿锛�" prop="runTime">
- <el-date-picker
- style="width: 100%"
- v-model="form.runTime"
- 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="waterDay">
- <el-input
- v-model="form.waterDay"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="姘磋垂鍗曚环锛�" prop="waterPrice">
- <el-input
- v-model="form.waterPrice"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢ㄦ按绫诲瀷锛�" prop="type">
- <el-select
- v-model="form.type"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="宸ヤ笟鐢ㄦ按" value="industrial" />
- <el-option label="鐢熸椿鐢ㄦ按" value="domestic" />
- <el-option label="娑堥槻鐢ㄦ按" value="fire" />
- <el-option label="缁垮寲鐢ㄦ按" value="greening" />
- </el-select>
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, nextTick} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {waterDeviceList, waterEquipmentAdd, waterEquipmentUpdate} from "@/api/energyManagement/waterManagement.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- deviceName: "",
- deviceModel: "",
- waterDayLimit: "",
- ratedRate: "",
- actualTraffic: "",
- runTime: "",
- waterDay: "",
- waterPrice: "",
- type: "",
- },
- rules: {
- deviceModel: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- runTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- waterDayLimit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- ratedRate: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- actualTraffic: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- waterDay: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- waterPrice: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- type: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-})
-const { form, rules } = toRefs(data);
-const codeList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- form.value = {}
- proxy.resetForm("formRef");
- waterDeviceList({size: -1}).then((res) => {
- codeList.value = res.data.records;
- });
- if (type === "edit") {
- form.value = {...row}
- }
-}
-const setName = (code) => {
- const index = codeList.value.findIndex(item => item.deviceModel === code);
- if (index > -1) {
- console.log(codeList)
- form.value.name = codeList.value[index].deviceName;
- }
-}
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "add") {
- waterEquipmentAdd(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- })
- } else {
- waterEquipmentUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/energyManagement/waterManagement/components/waterBillForm.vue b/src/views/energyManagement/waterManagement/components/waterBillForm.vue
deleted file mode 100644
index a132041..0000000
--- a/src/views/energyManagement/waterManagement/components/waterBillForm.vue
+++ /dev/null
@@ -1,210 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="姘磋垂绠$悊"
- width="70%"
- @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="code">
- <el-select
- v-model="form.code"
- placeholder="璇烽�夋嫨"
- clearable
- @change="setName"
- :disabled="operationType !== 'add'"
- >
- <el-option
- v-for="item in codeList"
- :key="item.deviceModel"
- :label="item.deviceName"
- :value="item.deviceModel"
- >
- {{item.deviceName + '--' + item.deviceModel}}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢ㄦ按閲忥細" prop="waterConsumption">
- <el-input
- v-model="form.waterConsumption"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="姘磋垂鍗曚环锛�" prop="waterPrice">
- <el-input
- v-model="form.waterPrice"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="姘磋垂閲戦锛�" prop="waterBill">
- <el-input
- v-model="form.waterBill"
- placeholder="鑷姩璁$畻"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="璁¤垂鏃ユ湡锛�" prop="billDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.billDate"
- 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="waterType">
- <el-select
- v-model="form.waterType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="宸ヤ笟鐢ㄦ按" value="industrial" />
- <el-option label="鐢熸椿鐢ㄦ按" value="domestic" />
- <el-option label="娑堥槻鐢ㄦ按" value="fire" />
- <el-option label="缁垮寲鐢ㄦ按" value="greening" />
- </el-select>
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, nextTick, watch} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {waterDeviceList, waterBillAdd, waterBillUpdate} from "@/api/energyManagement/waterManagement.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- name: "",
- code: "",
- waterConsumption: "",
- waterPrice: "",
- waterBill: "",
- billDate: "",
- waterType: "",
- },
- rules: {
- code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- waterConsumption: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- waterPrice: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- billDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- waterType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-})
-const { form, rules } = toRefs(data);
-const codeList = ref([])
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- form.value = {}
- proxy.resetForm("formRef");
- waterDeviceList().then((res) => {
- codeList.value = res.data;
- });
- if (type === "edit") {
- form.value = {...row}
- }
-}
-const setName = (code) => {
- const index = codeList.value.findIndex(item => item.deviceModel === code);
- if (index > -1) {
- console.log(codeList)
- form.value.name = codeList.value[index].deviceName;
- }
-}
-
-// 璁$畻姘磋垂閲戦
-const calculateWaterBill = () => {
- if (form.value.waterConsumption && form.value.waterPrice) {
- form.value.waterBill = (parseFloat(form.value.waterConsumption) * parseFloat(form.value.waterPrice)).toFixed(2);
- }
-}
-
-// 鐩戝惉鐢ㄦ按閲忓拰姘磋垂鍗曚环鍙樺寲
-watch([() => form.value.waterConsumption, () => form.value.waterPrice], () => {
- calculateWaterBill();
-});
-
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "add") {
- waterBillAdd(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- closeDia()
- })
- } else {
- waterBillUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/energyManagement/waterManagement/index.vue b/src/views/energyManagement/waterManagement/index.vue
deleted file mode 100644
index 4ada029..0000000
--- a/src/views/energyManagement/waterManagement/index.vue
+++ /dev/null
@@ -1,329 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">璁惧鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.deviceName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <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 type="info" plain icon="Upload" @click="handleImport">瀵煎叆</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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- <el-dialog
- :title="upload.title"
- v-model="upload.open"
- width="400px"
- append-to-body
- @close="handleDialogClose"
- >
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url"
- :disabled="upload.isUploading"
- :before-upload="upload.beforeUpload"
- :on-progress="upload.onProgress"
- :on-success="upload.onSuccess"
- :on-error="upload.onError"
- :on-change="upload.onChange"
- :auto-upload="false"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
- <el-link
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate"
- >涓嬭浇妯℃澘</el-link
- >
- </div>
- </template>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, reactive, nextTick, getCurrentInstance} from "vue";
-import FormDia from "@/views/energyManagement/waterManagement/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import {waterEquipmentDelete, waterEquipmentListPage} from "@/api/energyManagement/waterManagement.js";
-const { proxy } = getCurrentInstance();
-
-const data = reactive({
- searchForm: {
- name: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const selectedRows = ref([]);
-const tableColumn = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "deviceName",
- width: 200,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "deviceModel",
- width: 200,
- },
- {
- label: "棰濆畾娴侀噺",
- prop: "ratedRate",
- },
- {
- label: "瀹為檯娴侀噺",
- prop: "actualTraffic",
- },
- {
- label: "杩愯鏃堕棿",
- prop: "runTime",
- width:150
- },
- {
- label: "褰撴棩鐢ㄦ按閲�",
- prop: "waterDay",
- width: 150,
- },
- {
- label: "姣忔棩闄愬埗姘撮噺",
- prop: "waterDayLimit",
- width:220
- },
- {
- label: "姘磋垂鍗曚环",
- prop: "waterPrice",
- width: 120,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/waterRecord/importData",
- // 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
- beforeUpload: (file) => {
- console.log('鏂囦欢鍗冲皢涓婁紶', file);
- // 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
- const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
- if (!isValid) {
- proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
- }
- return isValid;
- },
- // 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
- onChange: (file, fileList) => {
- console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
- },
- // 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
- onSuccess: (response, file, fileList) => {
- console.log('涓婁紶鎴愬姛', response, file, fileList);
- if(response.code === 200){
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- }else if(response.code === 500){
- proxy.$modal.msgError(response.msg);
- }else{
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
- upload.open = false;
- getList();
- },
- // 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
- onError: (error, file, fileList) => {
- console.log('涓婁紶澶辫触', error, file, fileList);
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- upload.open = false;
- },
- // 鏂囦欢涓婁紶杩涘害鏀瑰彉鏃剁殑鍥炶皟
- onProgress: (event, file, fileList) => {
- console.log('涓婁紶杩涘害', event, file, fileList);
- upload.isUploading = true;
- },
-});
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- waterEquipmentListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- }).catch(() => {
- tableLoading.value = false;
- })
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "鐢ㄦ按璁惧";
- upload.open = true;
- // 娓呯┖涓婃涓婁紶鐨勬枃浠跺垪琛�
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-function importTemplate() {
- proxy.download(
- "/waterRecord/export",
- {},
- '鐢ㄦ按璁惧瀵煎叆妯$増.xlsx'
- );
-}
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- proxy.$refs["uploadRef"].submit();
-}
-
-/** 寮规鍏抽棴鏃舵竻绌烘枃浠跺垪琛� */
-function handleDialogClose() {
- nextTick(() => {
- proxy.$refs["uploadRef"]?.clearFiles();
- });
-}
-
-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(() => {
- tableLoading.value = true;
- waterEquipmentDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/waterRecord/export", {}, "鐢ㄦ按绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/energyManagement/waterManagement/waterBill.vue b/src/views/energyManagement/waterManagement/waterBill.vue
deleted file mode 100644
index ea382f0..0000000
--- a/src/views/energyManagement/waterManagement/waterBill.vue
+++ /dev/null
@@ -1,181 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">璁惧鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.name"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <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 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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, reactive, nextTick} from "vue";
-import FormDia from "@/views/energyManagement/waterManagement/components/waterBillForm.vue";
-import {ElMessageBox} from "element-plus";
-import {waterBillDelete, waterBillListPage} from "@/api/energyManagement/waterManagement.js";
-const { proxy } = getCurrentInstance();
-
-const data = reactive({
- searchForm: {
- name: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const selectedRows = ref([]);
-const tableColumn = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "name",
- width: 200,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "code",
- width: 200,
- },
- {
- label: "鐢ㄦ按閲�",
- prop: "waterConsumption",
- },
- {
- label: "姘磋垂鍗曚环",
- prop: "waterPrice",
- },
- {
- label: "姘磋垂閲戦",
- prop: "waterBill",
- width:150
- },
- {
- label: "璁¤垂鏃ユ湡",
- prop: "billDate",
- width: 150,
- },
- {
- label: "鐢ㄦ按绫诲瀷",
- prop: "waterType",
- width:120
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- waterBillListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-// 鎵撳紑寮规
-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(() => {
- tableLoading.value = true;
- waterBillDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/energyManagement/waterManagement/waterTrends.vue b/src/views/energyManagement/waterManagement/waterTrends.vue
deleted file mode 100644
index 12e45fc..0000000
--- a/src/views/energyManagement/waterManagement/waterTrends.vue
+++ /dev/null
@@ -1,118 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">璁惧鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.name"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</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"
- ></PIMTable>
- </div>
- </div>
-</template>
-
-<script setup>
-import {Search} from "@element-plus/icons-vue";
-import {onMounted, ref, reactive} from "vue";
-import {listPageByWaterTrend} from "@/api/energyManagement/waterManagement.js";
-
-const data = reactive({
- searchForm: {
- name: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const selectedRows = ref([]);
-const tableColumn = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "name",
- width: 220,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "code",
- width: 220,
- },
- {
- label: "杩愯鏃堕棿",
- prop: "runDate",
- width: 250,
- },
- {
- label: "鏄ㄦ棩鐢ㄦ按閲�",
- prop: "toDayNum",
- },
- {
- label: "鏈湀骞冲潎姘撮噺",
- prop: "avgNum",
- width:150
- },
- {
- label: "瓒嬪娍",
- prop: "trend",
- width: 220,
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- listPageByWaterTrend({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/equipmentManagement/brand/index.vue b/src/views/equipmentManagement/brand/index.vue
deleted file mode 100644
index 6607cc8..0000000
--- a/src/views/equipmentManagement/brand/index.vue
+++ /dev/null
@@ -1,217 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="鍝佺墝鍚嶇О/鍥藉">
- <el-input
- v-model="filters.name"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ叧閿瘝"
- clearable
- prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
-
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="openAdd" icon="Plus"> 鏂板 </el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleSelection.length <= 0"
- @click="handleBatchDelete"
- >鎵归噺鍒犻櫎</el-button>
- </div>
- </div>
-
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- </PIMTable>
- </div>
-
- <el-dialog v-model="visible" :title="dialogTitle" width="520px" destroy-on-close>
- <el-form :model="form" ref="formRef" :rules="rules" label-width="90px">
- <el-form-item label="鍝佺墝鍚嶇О" prop="name">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ搧鐗屽悕绉�" />
- </el-form-item>
- <el-form-item label="鎵�灞炲浗瀹�" prop="country">
- <el-input v-model="form.country" placeholder="璇疯緭鍏ュ浗瀹�/鍦板尯" />
- </el-form-item>
- <el-form-item label="鎻忚堪" prop="description">
- <el-input v-model="form.description" type="textarea" :rows="3" placeholder="鍙~鍐欏搧鐗岀畝浠�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="visible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-
-</template>
-
-<script setup>
-import { ref, getCurrentInstance, onMounted } from 'vue'
-import { ElMessageBox, ElMessage } from 'element-plus'
-import { usePaginationApi } from '@/hooks/usePaginationApi'
-import { getBrandPage, addBrand, editBrand, delBrand } from '@/api/equipmentManagement/brand'
-
-defineOptions({ name: '璁惧鍝佺墝绠$悊' })
-
-const { proxy } = getCurrentInstance()
-
-const multipleSelection = ref([])
-const formRef = ref()
-const visible = ref(false)
-const dialogTitle = ref('鏂板鍝佺墝')
-const form = ref({ id: undefined, name: '', country: '', description: '' })
-
-const rules = {
- name: [{ required: true, message: '璇疯緭鍏ュ搧鐗屽悕绉�', trigger: 'blur' }],
- country: [{ required: true, message: '璇疯緭鍏ユ墍灞炲浗瀹�', trigger: 'blur' }]
-}
-
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- getBrandPage,
- { name: undefined },
- [
- { label: '鍝佺墝鍚嶇О', align: 'center', prop: 'name' },
- { label: '鎵�灞炲浗瀹�', align: 'center', prop: 'country' },
- { label: '鎻忚堪', align: 'center', prop: 'description' },
- { label: '鍒涘缓鏃堕棿', align: 'center', prop: 'createdAt' },
- {
- dataType: 'action',
- label: '鎿嶄綔',
- align: 'center',
- fixed: 'right',
- width: 140,
- operation: [
- {
- name: '缂栬緫',
- type: 'text',
- clickFun: (row) => openEdit(row),
- },
- {
- name: '鍒犻櫎',
- type: 'text',
- clickFun: (row) => handleDelete(row.id),
- }
- ]
- }
- ]
-)
-
-const handleSelectionChange = (list) => {
- multipleSelection.value = list
-}
-
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page
- pagination.pageSize = limit
- onCurrentChange(page)
-}
-
-function resetForm() {
- form.value = { id: undefined, name: '', country: '', description: '' }
-}
-
-function openAdd() {
- resetForm()
- dialogTitle.value = '鏂板鍝佺墝'
- visible.value = true
-}
-
-function openEdit(row) {
- form.value = { id: row.id, name: row.name, country: row.country, description: row.description }
- dialogTitle.value = '缂栬緫鍝佺墝'
- visible.value = true
-}
-
-function handleSubmit() {
- formRef.value.validate(async (valid) => {
- if (!valid) return
- const isEdit = Boolean(form.value.id)
- const api = isEdit ? editBrand : addBrand
- const { code, msg } = await api({ ...form.value })
- if (code === 200) {
- ElMessage.success(isEdit ? '淇敼鎴愬姛' : '鏂板鎴愬姛')
- visible.value = false
- getTableData()
- } else {
- ElMessage.error(msg || '鎿嶄綔澶辫触')
- }
- })
-}
-
-function handleDelete(id) {
- ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ搧鐗�, 鏄惁缁х画?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }).then(async () => {
- const { code } = await delBrand(id)
- if (code === 200) {
- ElMessage.success('鍒犻櫎鎴愬姛')
- getTableData()
- }
- })
-}
-
-function handleBatchDelete() {
- if (multipleSelection.value.length === 0) return
- ElMessageBox.confirm('灏嗗垹闄ら�変腑鐨勫搧鐗岋紝鏄惁缁х画锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }).then(async () => {
- const ids = multipleSelection.value.map((i) => i.id)
- const { code } = await delBrand(ids)
- if (code === 200) {
- ElMessage.success('鍒犻櫎鎴愬姛')
- getTableData()
- }
- })
-}
-
-onMounted(() => {
- getTableData()
-})
-
-</script>
-
-<style scoped lang="scss">
-.table_list { margin-top: unset; }
-.actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
-}
-</style>
-
-
diff --git a/src/views/equipmentManagement/calibration/index.vue b/src/views/equipmentManagement/calibration/index.vue
deleted file mode 100644
index affce9d..0000000
--- a/src/views/equipmentManagement/calibration/index.vue
+++ /dev/null
@@ -1,215 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">妫�瀹氭棩鏈燂細</span>
- <el-date-picker
- v-model="searchForm.recordDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 160px"
- @change="handleQuery"
- />
- <span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.entryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 160px"
- @change="handleQuery"
- />
- <span class="search_title ml10">璁¢噺鍣ㄥ叿缂栧彿锛�</span>
- <el-input v-model="searchForm.code" placeholder="璇疯緭鍏ョ紪鍙�" clearable style="width: 240px" @change="handleQuery"/>
-<!-- <span class="search_title ml10">鐘舵�侊細</span>-->
-<!-- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 160px" clearable>-->
-<!-- <el-option label="鏈夋晥" :value="1"></el-option>-->
-<!-- <el-option label="閫炬湡" :value="2"></el-option>-->
-<!-- </el-select>-->
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button @click="handleOut">瀵煎嚭</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"
- ></PIMTable>
- </div>
- <calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
- </div>
-</template>
-
-<script setup>
-import {onMounted, ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import useUserStore from "@/store/modules/user.js";
-import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
-import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-
-const data = reactive({
- searchForm: {
- recordDate: "",
- code: "",
- entryDate: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
- // {
- // label: "鐘舵��",
- // prop: "status",
- // dataType: "tag",
- // formatData: (params) => {
- // if (params == 1) {
- // return "鏈夋晥";
- // } else if (params == 2) {
- // return "閫炬湡";
- // } else {
- // return null;
- // }
- // },
- // formatType: (params) => {
- // if (params == 1) {
- // return "success";
- // } else if (params == 2) {
- // return "danger";
- // } else {
- // return null;
- // }
- // },
- // },
- {
- label: "妫�瀹氭棩鏈�",
- prop: "recordDate",
- width: 130,
- },
- {
- label: "璁¢噺鍣ㄥ叿缂栧彿",
- prop: "code",
- width: 150,
- },
- {
- label: "璁¢噺鍣ㄥ叿鍚嶇О",
- prop: "name",
- width: 200,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "model",
- width:200
- },
- {
- label: "鏈夋晥鏈�",
- prop: "valid",
- width: 100,
- },
- {
- label: "褰曞叆浜�",
- prop: "userName",
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "entryDate",
- width: 130,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openCalibrationDia("edit", row);
- }
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const selectedRows = ref([]);
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const calibrationDia = ref()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- ledgerRecordListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- }).catch((err) => {
- tableLoading.value = false;
- })
-};
-
-// 鎵撳紑妫�瀹氭牎鍑嗗脊妗�
-const openCalibrationDia = (type, row) => {
- nextTick(() => {
- calibrationDia.value?.openDialog(type, row)
- })
-}
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/measuringInstrumentLedgerRecord/export", {}, "妫�瀹氭牎鍑嗚褰�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/defectManagement/index.vue b/src/views/equipmentManagement/defectManagement/index.vue
deleted file mode 100644
index f35454f..0000000
--- a/src/views/equipmentManagement/defectManagement/index.vue
+++ /dev/null
@@ -1,221 +0,0 @@
-<template>
- <div class="defect-management">
- <!-- 鎿嶄綔鎸夐挳 -->
- <div class="actions">
- <el-button type="primary" @click="showRegisterDialog = true">鐧昏缂洪櫡</el-button>
- </div>
-
- <!-- 缂洪櫡鍒楄〃 -->
- <el-table :data="defectList" style="width: 100%; margin-top: 10px;" border>
- <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="180"></el-table-column>
- <el-table-column prop="defectDescription" label="缂洪櫡鎻忚堪" win-width="300"></el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="220">
- <template #default="{ row }">
- <el-tag :type="row.status === '涓ラ噸缂洪櫡' ? 'danger' : 'success'">
- {{ row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="220">
- <template #default="{ row }">
- <el-button
- v-if="row.status === '涓ラ噸缂洪櫡' || row.status === '涓�鑸己闄�'"
- type="text"
- @click="eliminateDefect(row)"
- >
- 娑堥櫎缂洪櫡
- </el-button>
- <!-- <el-button
- v-if="row.status === '涓ラ噸缂洪櫡'"
- type="text"
- @click="transferToRepairOrder(row.id)"
- >
- 杞淮淇崟
- </el-button> -->
- <el-button type="text" @click="getLedger(row.deviceLedgerId)">
- 鏌ョ湅鍙拌处
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 缂洪櫡鐧昏瀵硅瘽妗� -->
- <el-dialog title="鐧昏璁惧缂洪櫡" v-model="showRegisterDialog" width="50%">
- <el-form :model="defectForm" :rules="defectRules" ref="defectFormRef" label-width="100px">
- <el-form-item label="璁惧鍚嶇О" prop="deviceName">
- <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel">
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="缂洪櫡鎻忚堪" prop="defectDescription">
- <el-input type="textarea" v-model="defectForm.defectDescription"></el-input>
- </el-form-item>
- <el-form-item label="璁惧鐘舵��" prop="status">
- <el-radio-group v-model="defectForm.status">
- <el-radio label="姝e父">姝e父</el-radio>
- <el-radio label="涓�鑸己闄�">涓�鑸己闄�</el-radio>
- <el-radio label="涓ラ噸缂洪櫡">涓ラ噸缂洪櫡</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showRegisterDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitDefectForm">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 缂洪櫡璁惧鍙拌处瀵硅瘽妗� -->
- <el-dialog title="缂洪櫡璁惧鍙拌处" v-model="showLedgerDialog" width="80%">
- <el-table :data="ledgerList" style="width: 100%; margin-top: 10px;" border>
- <el-table-column prop="deviceName" label="璁惧鍚嶇О"></el-table-column>
- <el-table-column prop="defectDescription" label="缂洪櫡鎻忚堪"></el-table-column>
- <el-table-column prop="status" label="鐘舵��"></el-table-column>
- <el-table-column prop="eliminateTime" label="娑堢己鏃堕棿"></el-table-column>
- </el-table>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue';
-import { ElMessage } from 'element-plus';
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-// 鍋囪浠ヤ笅鏄悗绔帴鍙�
-import {
- registerDefect,
- getDefectList,
- eliminateDefect as apiEliminateDefect,
- getDefectLedger,
- deleteDefect
-} from '@/api/equipmentManagement/defectManagement';
-
-// 缂洪櫡鍒楄〃
-const defectList = ref([]);
-// 鐧昏瀵硅瘽妗嗘樉绀虹姸鎬�
-const showRegisterDialog = ref(false);
-// 鍙拌处瀵硅瘽妗嗘樉绀虹姸鎬�
-const showLedgerDialog = ref(false);
-// 缂洪櫡琛ㄥ崟
-const defectForm = reactive({
- deviceLedgerId: '',
- defectDescription: '',
- status: '',
-});
-const deviceOptions = ref([]);
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const defectRules = reactive({
- deviceLedgerId: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
- defectDescription: [{ required: true, message: '璇疯緭鍏ョ己闄锋弿杩�', trigger: 'blur' }]
-});
-// 琛ㄥ崟寮曠敤
-const defectFormRef = ref(null);
-// 鍙拌处鍒楄〃
-const ledgerList = ref([]);
-
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- // console.log(data);
- deviceOptions.value = data;
-};
-
-// 鑾峰彇缂洪櫡鍒楄〃
-const fetchDefectList = async () => {
- try {
- const res = await getDefectList();
- if (res.code === 200) {
- defectList.value = res.data.records;
- } else {
- ElMessage.error(res.message || '鑾峰彇缂洪櫡鍒楄〃澶辫触');
- }
- } catch (error) {
- ElMessage.error('鑾峰彇缂洪櫡鍒楄〃澶辫触');
- }
-};
-
-// 鎻愪氦缂洪櫡鐧昏琛ㄥ崟
-const submitDefectForm = async () => {
- if (!defectFormRef.value) return;
- try {
- await defectFormRef.value.validate();
- const res = await registerDefect(defectForm);
- if (res.code === 200) {
- ElMessage.success('缂洪櫡鐧昏鎴愬姛');
- showRegisterDialog.value = false;
- fetchDefectList();
- } else {
- ElMessage.error(res.message || '缂洪櫡鐧昏澶辫触');
- }
- } catch (error) {
- ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�');
- }
-};
-
-// 娑堥櫎缂洪櫡
-const eliminateDefect = async (row) => {
-
- try {
- const res = await apiEliminateDefect(row);
- if (res.code === 200) {
- ElMessage.success('缂洪櫡娑堥櫎鎴愬姛');
- fetchDefectList();
- } else {
- ElMessage.error(res.message || '缂洪櫡娑堥櫎澶辫触');
- }
- } catch (error) {
- ElMessage.error('缂洪櫡娑堥櫎澶辫触');
- }
-};
-
-// // 杞淮淇伐鍗�
-// const transferToRepairOrder = async (id) => {
-// try {
-// const res = await transferToRepair(id);
-// if (res.code === 200) {
-// ElMessage.success('杞淮淇伐鍗曟垚鍔�');
-// } else {
-// ElMessage.error(res.message || '杞淮淇伐鍗曞け璐�');
-// }
-// } catch (error) {
-// ElMessage.error('杞淮淇伐鍗曞け璐�');
-// }
-// };
-
-// 鑾峰彇缂洪櫡璁惧鍙拌处
-const getLedger = async (deviceLedgerId) => {
- try {
- const res = await getDefectLedger(deviceLedgerId);
- if (res.code === 200) {
- ledgerList.value = res.data.records;
- showLedgerDialog.value = true;
- } else {
- ElMessage.error(res.message || '鑾峰彇缂洪櫡璁惧鍙拌处澶辫触');
- }
- } catch (error) {
- ElMessage.error('鑾峰彇缂洪櫡璁惧鍙拌处澶辫触');
- }
-};
-
-// 缁勪欢鎸傝浇鏃惰幏鍙栫己闄峰垪琛�
-const onMounted = () => {
- fetchDefectList();
- loadDeviceName();
-};
-onMounted();
-</script>
-
-<style scoped>
-.defect-management {
- padding: 20px;
-}
-
-.actions {
- margin-bottom: 10px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/deviceInfo/index.vue b/src/views/equipmentManagement/deviceInfo/index.vue
deleted file mode 100644
index de162cc..0000000
--- a/src/views/equipmentManagement/deviceInfo/index.vue
+++ /dev/null
@@ -1,190 +0,0 @@
-<template>
- <div class="device-info-container">
- <div class="page-header">
- <h1>璁惧淇℃伅</h1>
- <div class="device-status" :class="deviceStatusClass">
- {{ deviceStatusText }}
- </div>
- </div>
-
- <div class="info-card">
- <div class="card-header">鍩烘湰淇℃伅</div>
- <div class="card-content">
- <div class="info-row">
- <span class="label">璁惧鍚嶇О锛�</span>
- <span class="value">{{ deviceInfo.deviceName }}</span>
- </div>
- <div class="info-row">
- <span class="label">瑙勬牸鍨嬪彿锛�</span>
- <span class="value">{{ deviceInfo.deviceModel }}</span>
- </div>
- <div class="info-row">
- <span class="label">鐢熶骇鍘傚锛�</span>
- <span class="value">{{ deviceInfo.supplierName }}</span>
- </div>
- <div class="info-row">
- <span class="label">鍗曚綅锛�</span>
- <span class="value">{{ deviceInfo.unit }}</span>
- </div>
- </div>
- </div>
-
- <div class="info-card">
- <div class="card-header">缁存姢淇℃伅</div>
- <div class="card-content">
- <div class="maintenance-info">
- <div class="maintenance-item">
- <span class="label">鏈�鍚庣淮鎶わ細</span>
- <span class="value">{{ deviceInfo.updateTime }}</span>
- </div>
- <div class="maintenance-item">
- <span class="label">涓嬫缁存姢锛�</span>
- <span class="value">{{ deviceInfo.createTime }}</span>
- </div>
- <div class="maintenance-item">
- <span class="label">缁存姢鐘舵�侊細</span>
- <span class="value status-normal">{{ deviceInfo.statusText }}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, computed } from 'vue'
-import { useRoute } from 'vue-router'
-import { ElMessage } from 'element-plus'
-import {
- getDeviceInfo,
-} from '@/api/equipmentManagement/deviceInfo'
-
-const route = useRoute()
-
-const deviceInfo = reactive({
- deviceName: '',
- deviceModel: '',
- supplierName: '',
- unit: '',
- statusText:'姝e父',
- updateTime:'',
- createTime:''
-})
-
-const deviceStatusClass = computed(() => {
- return 'status-normal'
-})
-
-const deviceStatusText = computed(() => {
- return '姝e父'
-})
-
-const fetchDeviceInfo = async (deviceId) => {
- try {
- // 鑾峰彇璁惧淇℃伅
- const deviceResponse = await getDeviceInfo({id:deviceId})
- if (deviceResponse.code === 200) {
- Object.assign(deviceInfo, deviceResponse.data)
- }
-
-
- } catch (error) {
-
- ElMessage.warning('浣跨敤妯℃嫙鏁版嵁锛屽疄闄匒PI璋冪敤澶辫触')
- }
-}
-
-onMounted(() => {
- const deviceId = route.query.deviceId || route.params.deviceId || ''
- fetchDeviceInfo(deviceId)
-})
-</script>
-
-<style scoped>
-.device-info-container {
- min-height: 100vh;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- padding: 20px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
-}
-
-.page-header {
- background: rgba(255, 255, 255, 0.95);
- border-radius: 16px;
- padding: 20px;
- margin-bottom: 20px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.page-header h1 {
- margin: 0;
- color: #2c3e50;
- font-size: 24px;
-}
-
-.device-status {
- padding: 8px 16px;
- border-radius: 20px;
- font-size: 14px;
- color: white;
- background: #52c41a;
-}
-
-.info-card {
- background: rgba(255, 255, 255, 0.95);
- border-radius: 16px;
- margin-bottom: 20px;
- overflow: hidden;
-}
-
-.card-header {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
- padding: 16px 20px;
- font-weight: 500;
-}
-
-.card-content {
- padding: 20px;
-}
-
-.info-row, .maintenance-item {
- display: flex;
- margin-bottom: 12px;
- align-items: center;
-}
-
-.label {
- width: 100px;
- color: #666;
- font-size: 14px;
-}
-
-.value {
- flex: 1;
- color: #2c3e50;
- font-weight: 500;
-}
-
-.status-normal {
- color: #52c41a;
-}
-
-
-
-@media (max-width: 768px) {
- .device-info-container {
- padding: 16px;
- }
-
- .page-header h1 {
- font-size: 20px;
- }
-
- .label {
- width: 80px;
- }
-}
-</style>
diff --git a/src/views/equipmentManagement/gasTank/simple.vue b/src/views/equipmentManagement/gasTank/simple.vue
deleted file mode 100644
index 4cb2d76..0000000
--- a/src/views/equipmentManagement/gasTank/simple.vue
+++ /dev/null
@@ -1,566 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>閲嶅瀷缃愬紡璐ц溅鐩戞帶</h2>
- <div class="header-actions">
-<!-- <el-button type="primary" @click="addTank">鏂板鍌ㄧ綈</el-button>-->
-<!-- <el-button @click="exportData">瀵煎嚭鏁版嵁</el-button>-->
- </div>
- </div>
-
- <!-- 鍥涗釜涓昏妯″潡 -->
- <div class="modules-container">
- <!-- 1. 鍩烘湰淇℃伅妯″潡 -->
- <el-card class="module-card">
- <template #header>
- <div class="card-header">
- <span>1. 鍩烘湰淇℃伅</span>
- <el-button type="text" @click="handleEditBasicInfo">缂栬緫</el-button>
- </div>
- </template>
- <div class="info-grid">
- <div class="info-item">
- <label>鍌ㄧ綈缂栧彿锛�</label>
- <span>{{ basicInfo.tankCode }}</span>
- </div>
- <div class="info-item">
- <label>鍌ㄧ綈鍚嶇О锛�</label>
- <span>{{ basicInfo.tankName }}</span>
- </div>
- <div class="info-item">
- <label>鍌ㄧ綈绫诲瀷锛�</label>
- <span>{{ basicInfo.tankType }}</span>
- </div>
- <div class="info-item">
- <label>璁捐鍘嬪姏锛�</label>
- <span>{{ basicInfo.designPressure }} MPa</span>
- </div>
- <div class="info-item">
- <label>宸ヤ綔鍘嬪姏锛�</label>
- <span>{{ basicInfo.workingPressure }} MPa</span>
- </div>
- <div class="info-item">
- <label>瀹圭Н锛�</label>
- <span>{{ basicInfo.volume }} m鲁</span>
- </div>
- </div>
- </el-card>
-
- <!-- 2. 鐩戞祴鍙傛暟妯″潡 -->
- <el-card class="module-card">
- <template #header>
- <div class="card-header">
- <span>2. 鐩戞祴鍙傛暟</span>
- <el-button type="text" @click="refreshMonitoring">鍒锋柊</el-button>
- </div>
- </template>
- <div class="monitoring-grid">
- <div class="monitor-item">
- <div class="monitor-label">鍘嬪姏</div>
- <div class="monitor-value" :class="getStatusClass(monitoringData.pressureStatus)">
- {{ monitoringData.pressure }} MPa
- </div>
- <div class="monitor-status">{{ monitoringData.pressureStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
- </div>
- <div class="monitor-item">
- <div class="monitor-label">娓╁害</div>
- <div class="monitor-value" :class="getStatusClass(monitoringData.temperatureStatus)">
- {{ monitoringData.temperature }} 鈩�
- </div>
- <div class="monitor-status">{{ monitoringData.temperatureStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
- </div>
- <div class="monitor-item">
- <div class="monitor-label">姘斾綋娴撳害</div>
- <div class="monitor-value" :class="getStatusClass(monitoringData.gasStatus)">
- {{ monitoringData.gasConcentration }} ppm
- </div>
- <div class="monitor-status">{{ monitoringData.gasStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
- </div>
- <div class="monitor-item">
- <div class="monitor-label">娴侀噺</div>
- <div class="monitor-value" :class="getStatusClass(monitoringData.flowStatus)">
- {{ monitoringData.flow }} m鲁/h
- </div>
- <div class="monitor-status">{{ monitoringData.flowStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
- </div>
- </div>
- </el-card>
-
- <!-- 3. 瀹夊叏瑁呯疆妯″潡 -->
- <el-card class="module-card">
- <template #header>
- <div class="card-header">
- <span>3. 瀹夊叏瑁呯疆</span>
- <el-button type="text" @click="checkSafetyDevices">妫�鏌�</el-button>
- </div>
- </template>
- <div class="safety-grid">
- <div class="safety-item" v-for="device in safetyDevices" :key="device.name">
-
- <div class="device-info">
- <div class="device-name">{{ device.name }}</div>
- <div class="device-status" :class="device.status">
- {{ device.status === 'normal' ? '姝e父' : '寮傚父' }}
- </div>
- </div>
- </div>
- </div>
- </el-card>
-
- <!-- 4. 缁存姢璁板綍妯″潡 -->
- <el-card class="module-card">
- <template #header>
- <div class="card-header">
- <span>4. 缁存姢璁板綍</span>
- <el-button type="text" @click="addMaintenanceRecord">娣诲姞璁板綍</el-button>
- </div>
- </template>
- <div class="maintenance-list">
- <div class="maintenance-item" v-for="record in maintenanceRecords" :key="record.id">
- <div class="record-header">
- <span class="record-date">{{ record.date }}</span>
- <el-tag :type="record.type === 'inspection' ? 'primary' : 'success'" size="small">
- {{ record.type === 'inspection' ? '妫�楠�' : '缁存姢' }}
- </el-tag>
- </div>
- <div class="record-content">
- <div class="record-title">{{ record.title }}</div>
- <div class="record-desc">{{ record.description }}</div>
- <div class="record-operator">鎿嶄綔浜猴細{{ record.operator }}</div>
- </div>
- </div>
- </div>
- </el-card>
- </div>
-
- <!-- 缂栬緫鍩烘湰淇℃伅寮圭獥 -->
- <el-dialog v-model="basicInfoDialogVisible" title="缂栬緫鍩烘湰淇℃伅" width="600px">
- <el-form :model="editBasicInfo" label-width="120px">
- <el-form-item label="鍌ㄧ綈缂栧彿">
- <el-input v-model="editBasicInfo.tankCode" />
- </el-form-item>
- <el-form-item label="鍌ㄧ綈鍚嶇О">
- <el-input v-model="editBasicInfo.tankName" />
- </el-form-item>
- <el-form-item label="鍌ㄧ綈绫诲瀷">
- <el-select v-model="editBasicInfo.tankType" style="width: 100%">
- <el-option label="娑插寲姘斾綋鍌ㄧ綈" value="娑插寲姘斾綋鍌ㄧ綈" />
- <el-option label="鍘嬪姏瀹瑰櫒" value="鍘嬪姏瀹瑰櫒" />
- <el-option label="甯稿帇鍌ㄧ綈" value="甯稿帇鍌ㄧ綈" />
- </el-select>
- </el-form-item>
- <el-form-item label="璁捐鍘嬪姏">
- <el-input-number v-model="editBasicInfo.designPressure" :precision="2" style="width: 100%" />
- </el-form-item>
- <el-form-item label="宸ヤ綔鍘嬪姏">
- <el-input-number v-model="editBasicInfo.workingPressure" :precision="2" style="width: 100%" />
- </el-form-item>
- <el-form-item label="瀹圭Н">
- <el-input-number v-model="editBasicInfo.volume" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="basicInfoDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="saveBasicInfo">淇濆瓨</el-button>
- </template>
- </el-dialog>
-
- <!-- 娣诲姞缁存姢璁板綍寮圭獥 -->
- <el-dialog v-model="maintenanceDialogVisible" title="娣诲姞缁存姢璁板綍" width="600px">
- <el-form :model="newMaintenanceRecord" label-width="120px">
- <el-form-item label="璁板綍绫诲瀷">
- <el-select v-model="newMaintenanceRecord.type" style="width: 100%">
- <el-option label="妫�楠�" value="inspection" />
- <el-option label="缁存姢" value="maintenance" />
- </el-select>
- </el-form-item>
- <el-form-item label="鏍囬">
- <el-input v-model="newMaintenanceRecord.title" />
- </el-form-item>
- <el-form-item label="鎻忚堪">
- <el-input type="textarea" v-model="newMaintenanceRecord.description" :rows="3" />
- </el-form-item>
- <el-form-item label="鎿嶄綔浜�">
- <el-input v-model="newMaintenanceRecord.operator" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="maintenanceDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="saveMaintenanceRecord">淇濆瓨</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage } from 'element-plus'
-
-// 鍩烘湰淇℃伅
-const basicInfo = reactive({
- tankCode: 'GT001',
- tankName: '娑插寲姘斿偍缃怉',
- tankType: '娑插寲姘斾綋鍌ㄧ綈',
- designPressure: 1.6,
- workingPressure: 0.8,
- volume: 100.5
-})
-
-// 鐩戞祴鍙傛暟
-const monitoringData = reactive({
- pressure: 0.8,
- pressureStatus: 'normal',
- temperature: 25.5,
- temperatureStatus: 'normal',
- gasConcentration: 0.1,
- gasStatus: 'normal',
- flow: 15.2,
- flowStatus: 'normal'
-})
-
-// 瀹夊叏瑁呯疆
-const safetyDevices = ref([
- { name: '瀹夊叏闃�', status: 'normal' },
- { name: '鍘嬪姏浼犳劅鍣�', status: 'normal' },
- { name: '娓╁害浼犳劅鍣�', status: 'normal' },
- { name: '姘斾綋妫�娴嬪櫒', status: 'normal' },
- { name: '鐖嗙牬鐗�', status: 'normal' },
- { name: '娉勫帇瑁呯疆', status: 'normal' }
-])
-
-// 缁存姢璁板綍
-const maintenanceRecords = ref([
- {
- id: 1,
- date: '2025-01-15',
- type: 'inspection',
- title: '骞村害妫�楠�',
- description: '鎸夌収TSG 21-2016鏍囧噯杩涜骞村害妫�楠岋紝璁惧鐘舵�佽壇濂�',
- operator: '寮犲伐绋嬪笀'
- },
- {
- id: 2,
- date: '2025-02-20',
- type: 'maintenance',
- title: '瀹夊叏闃�缁存姢',
- description: '鏇存崲瀹夊叏闃�瀵嗗皝鍦堬紝鏍″噯鍘嬪姏璁惧畾鍊�',
- operator: '鏉庢妧甯�'
- },
- {
- id: 3,
- date: '2025-03-10',
- type: 'inspection',
- title: '鍘嬪姏娴嬭瘯',
- description: '杩涜鍘嬪姏瀹瑰櫒姘村帇璇曢獙锛岀鍚堣璁¤姹�',
- operator: '鐜嬫楠屽憳'
- }
-])
-
-// 寮圭獥鎺у埗
-const basicInfoDialogVisible = ref(false)
-const maintenanceDialogVisible = ref(false)
-
-// 缂栬緫琛ㄥ崟鏁版嵁
-const editBasicInfo = reactive({ ...basicInfo })
-const newMaintenanceRecord = reactive({
- type: 'inspection',
- title: '',
- description: '',
- operator: ''
-})
-
-// 鑾峰彇鐘舵�佹牱寮忕被
-const getStatusClass = (status) => {
- return status === 'normal' ? 'status-normal' : 'status-warning'
-}
-
-// 鏂板鍌ㄧ綈
-const addTank = () => {
- ElMessage.success('鏂板鍌ㄧ綈鍔熻兘')
-}
-
-// 瀵煎嚭鏁版嵁
-const exportData = () => {
- ElMessage.success('瀵煎嚭鎴愬姛')
-}
-
-// 缂栬緫鍩烘湰淇℃伅
-const handleEditBasicInfo = () => {
- Object.assign(editBasicInfo, basicInfo)
- basicInfoDialogVisible.value = true
-}
-
-// 淇濆瓨鍩烘湰淇℃伅
-const saveBasicInfo = () => {
- Object.assign(basicInfo, editBasicInfo)
- basicInfoDialogVisible.value = false
- ElMessage.success('淇濆瓨鎴愬姛')
-}
-
-// 鍒锋柊鐩戞祴鏁版嵁
-const refreshMonitoring = () => {
- // 妯℃嫙鏁版嵁鏇存柊
- monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
- monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
- monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
- monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
- ElMessage.success('鏁版嵁宸插埛鏂�')
-}
-
-// 妫�鏌ュ畨鍏ㄨ缃�
-const checkSafetyDevices = () => {
- // 妯℃嫙妫�鏌ヨ繃绋�
- safetyDevices.value.forEach(device => {
- device.status = Math.random() > 0.1 ? 'normal' : 'warning'
- })
- ElMessage.success('瀹夊叏瑁呯疆妫�鏌ュ畬鎴�')
-}
-
-// 娣诲姞缁存姢璁板綍
-const addMaintenanceRecord = () => {
- newMaintenanceRecord.type = 'inspection'
- newMaintenanceRecord.title = ''
- newMaintenanceRecord.description = ''
- newMaintenanceRecord.operator = ''
- maintenanceDialogVisible.value = true
-}
-
-// 淇濆瓨缁存姢璁板綍
-const saveMaintenanceRecord = () => {
- const record = {
- id: Date.now(),
- date: new Date().toISOString().split('T')[0],
- ...newMaintenanceRecord
- }
- maintenanceRecords.value.unshift(record)
- maintenanceDialogVisible.value = false
- ElMessage.success('璁板綍娣诲姞鎴愬姛')
-}
-
-// 妯℃嫙瀹炴椂鏁版嵁鏇存柊
-onMounted(() => {
- setInterval(() => {
- monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
- monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
- monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
- monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
- }, 5000)
-})
-</script>
-
-<style lang="scss" scoped>
-.app-container {
- padding: 20px;
- background: #f5f5f5;
- min-height: 100vh;
-}
-
-.page-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding: 20px;
- background: white;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-
- h2 {
- margin: 0;
- color: #303133;
- }
-
- .header-actions {
- display: flex;
- gap: 10px;
- }
-}
-
-.modules-container {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 20px;
-}
-
-.module-card {
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: bold;
- color: #303133;
- }
-}
-
-.info-grid {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 15px;
-
- .info-item {
- display: flex;
- justify-content: space-between;
- padding: 10px;
- background: #f8f9fa;
- border-radius: 4px;
-
- label {
- font-weight: bold;
- color: #606266;
- }
-
- span {
- color: #303133;
- }
- }
-}
-
-.monitoring-grid {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 15px;
-
- .monitor-item {
- text-align: center;
- padding: 15px;
- background: #f8f9fa;
- border-radius: 8px;
- border: 2px solid transparent;
-
- .monitor-label {
- font-size: 14px;
- color: #606266;
- margin-bottom: 8px;
- }
-
- .monitor-value {
- font-size: 20px;
- font-weight: bold;
- margin-bottom: 5px;
-
- &.status-normal {
- color: #67c23a;
- }
-
- &.status-warning {
- color: #e6a23c;
- }
- }
-
- .monitor-status {
- font-size: 12px;
- color: #909399;
- }
- }
-}
-
-.safety-grid {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 15px;
-
- .safety-item {
- display: flex;
- align-items: center;
- padding: 15px;
- background: #f8f9fa;
- border-radius: 8px;
- border: 2px solid transparent;
-
- .device-icon {
- margin-right: 15px;
- }
-
- .device-info {
- flex: 1;
-
- .device-name {
- font-weight: bold;
- color: #303133;
- margin-bottom: 5px;
- }
-
- .device-status {
- font-size: 12px;
- padding: 2px 8px;
- border-radius: 10px;
- display: inline-block;
-
- &.normal {
- background: #f0f9ff;
- color: #409eff;
- }
-
- &.warning {
- background: #fef7e0;
- color: #e6a23c;
- }
- }
- }
- }
-}
-
-.maintenance-list {
- max-height: 300px;
- overflow-y: auto;
-
- .maintenance-item {
- padding: 15px;
- border-bottom: 1px solid #ebeef5;
- margin-bottom: 10px;
-
- &:last-child {
- border-bottom: none;
- margin-bottom: 0;
- }
-
- .record-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-
- .record-date {
- font-size: 14px;
- color: #909399;
- }
- }
-
- .record-content {
- .record-title {
- font-weight: bold;
- color: #303133;
- margin-bottom: 5px;
- }
-
- .record-desc {
- font-size: 14px;
- color: #606266;
- margin-bottom: 5px;
- line-height: 1.4;
- }
-
- .record-operator {
- font-size: 12px;
- color: #909399;
- }
- }
- }
-}
-
-// 鍝嶅簲寮忚璁�
-@media (max-width: 1200px) {
- .modules-container {
- grid-template-columns: 1fr;
- }
-}
-
-@media (max-width: 768px) {
- .info-grid,
- .monitoring-grid,
- .safety-grid {
- grid-template-columns: 1fr;
- }
-}
-</style>
diff --git a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue b/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
deleted file mode 100644
index 79ff5b0..0000000
--- a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
+++ /dev/null
@@ -1,231 +0,0 @@
-<template>
- <div>
- <el-dialog :title="operationType === 'add' ? '鏂板宸℃浠诲姟' : '缂栬緫宸℃浠诲姟'"
- v-model="dialogVisitable" width="800px" @close="cancel">
- <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
- <el-row>
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О" prop="taskId">
- <el-select v-model="form.taskId" @change="setDeviceModel">
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="宸℃浜�" prop="inspector">
- <el-select v-model="form.inspector" placeholder="璇烽�夋嫨" multiple clearable>
- <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="澶囨敞" prop="remarks">
- <el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="12">
- <el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
- <el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
- <el-option label="姣忔棩" value="DAILY"/>
- <el-option label="姣忓懆" value="WEEKLY"/>
- <el-option label="姣忔湀" value="MONTHLY"/>
- <!-- <el-option label="瀛e害" value="QUARTERLY"/> -->
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
- value-format="HH:mm" />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
- <el-option label="鍛ㄤ竴" value="MON"/>
- <el-option label="鍛ㄤ簩" value="TUE"/>
- <el-option label="鍛ㄤ笁" value="WED"/>
- <el-option label="鍛ㄥ洓" value="THU"/>
- <el-option label="鍛ㄤ簲" value="FRI"/>
- <el-option label="鍛ㄥ叚" value="SAT"/>
- <el-option label="鍛ㄦ棩" value="SUN"/>
- </el-select>
- <el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
- value-format="HH:mm" style="width: 50%"/>
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-date-picker
- v-model="form.frequencyDetail"
- type="datetime"
- clearable
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- format="DD,HH:mm"
- value-format="DD,HH:mm"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
- <el-form-item label="鏃ユ湡" prop="frequencyDetail">
- <el-date-picker
- v-model="form.frequencyDetail"
- type="datetime"
- clearable
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- format="MM,DD,HH:mm"
- value-format="MM,DD,HH:mm"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancel">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">淇濆瓨</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {reactive, ref} from "vue";
-import useUserStore from '@/store/modules/user'
-import {addOrEditTimingTask} from "@/api/inspectionManagement/index.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const userStore = useUserStore()
-const dialogVisitable = ref(false);
-const operationType = ref('add');
-const deviceOptions = ref([]);
-const data = reactive({
- form: {
- taskId: undefined,
- taskName: undefined,
- inspector: '',
- inspectorIds: '',
- remarks: '',
- frequencyType: '',
- frequencyDetail: '',
- week: '',
- time: ''
- },
- rules: {
- taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
- inspector: [{ required: true, message: "璇疯緭鍏ュ贰妫�浜�", trigger: "blur" },],
- }
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- if (option) {
- form.value.taskName = option.deviceName;
- }
-}
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
- dialogVisitable.value = true
- operationType.value = type
-
- // 閲嶇疆琛ㄥ崟
- resetForm();
-
- // 鍔犺浇鐢ㄦ埛鍒楄〃
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
-
- // 鍔犺浇璁惧鍒楄〃
- await loadDeviceName();
-
- if (type === 'edit' && row) {
- form.value = {...row}
- form.value.inspector = form.value.inspectorIds.split(',').map(Number)
-
- // 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
- if (form.value.taskId) {
- setDeviceModel(form.value.taskId);
- }
- }
-}
-
-// 鍏抽棴瀵硅瘽妗�
-const cancel = () => {
- resetForm()
- dialogVisitable.value = false
- emit('closeDia')
-}
-
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
- if (proxy.$refs.formRef) {
- proxy.$refs.formRef.resetFields()
- }
- // 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
- form.value = {
- taskId: undefined,
- taskName: undefined,
- inspector: '',
- inspectorIds: '',
- remarks: '',
- frequencyType: '',
- frequencyDetail: '',
- week: '',
- time: ''
- }
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate(async valid => {
- if (valid) {
- try {
- form.value.inspectorIds = form.value.inspector.join(',')
- delete form.value.inspector
-
- if (form.value.frequencyType === 'WEEKLY') {
- let frequencyDetail = ''
- frequencyDetail = form.value.week + ',' + form.value.time
- form.value.frequencyDetail = frequencyDetail
- }
-
- let res = await userStore.getInfo()
- form.value.registrantId = res.user.userId
-
- await addOrEditTimingTask(form.value)
- cancel()
- proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
- } catch (error) {
- proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
- }
- }
- })
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/inspectionManagement/components/qrCodeDia.vue b/src/views/equipmentManagement/inspectionManagement/components/qrCodeDia.vue
deleted file mode 100644
index 136c18c..0000000
--- a/src/views/equipmentManagement/inspectionManagement/components/qrCodeDia.vue
+++ /dev/null
@@ -1,132 +0,0 @@
-<template>
- <div>
- <el-dialog :title="operationType === 'add' ? '鏂板浜岀淮鐮�' : '缂栬緫浜岀淮鐮�'"
- v-model="dialogVisitable" width="500px" @close="cancel">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
- <el-row>
- <el-col :span="24">
- <el-form-item label="璁惧鍚嶇О" prop="deviceName">
- <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" maxlength="30" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鎵�鍦ㄤ綅缃弿杩�" prop="location">
- <el-input v-model="form.location" placeholder="璇疯緭鍏ユ墍鍦ㄤ綅缃弿杩�" maxlength="30"/>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <div>
- <el-button type="primary" @click="submitForm">鐢熸垚骞舵墦鍗颁簩缁寸爜</el-button>
- </div>
- <div v-if="isShowQrCode" class="print-section" ref="qrCodeContainer" id="qrCodeContainer">
- <vue-qrcode :value="qrCodeValue" :width="qrCodeSize"></vue-qrcode>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import useUserStore from "@/store/modules/user.js";
-import {reactive, ref} from "vue";
-import printJS from 'print-js';
-import {addOrEditQrCode} from "@/api/inspectionUpload/index.js";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const userStore = useUserStore()
-const dialogVisitable = ref(false);
-const isShowQrCode = ref(false);
-const operationType = ref('add');
-
-const qrCodeValue = ref('');
-const qrCodeSize = ref(100);
-const data = reactive({
- form: {
- deviceName: '',
- location: '',
- qrCodeId: '',
- id: ''
- },
- rules: {
- deviceName: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
- location: [{ required: true, message: '璇疯緭鍏ュ湴鐐�', trigger: 'blur' }]
- }
-})
-const { form, rules } = toRefs(data)
-
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
- dialogVisitable.value = true
- qrCodeValue.value = ''
- isShowQrCode.value = false;
- if (type === 'edit') {
- form.value.id = row.id
- form.value.qrCodeId = row.id
- form.value.deviceName = row.deviceName
- form.value.location = row.location
- // 灏嗚〃鍗曟暟鎹浆涓� JSON 瀛楃涓蹭綔涓轰簩缁寸爜鍐呭
- qrCodeValue.value = JSON.stringify(form.value);
- isShowQrCode.value = true;
- }
-}
-// 鎻愪氦鍚堝苟琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- addOrEditQrCode(form.value).then((res) => {
- form.value.qrCodeId = res.data
- })
- // 灏嗚〃鍗曟暟鎹浆涓� JSON 瀛楃涓蹭綔涓轰簩缁寸爜鍐呭
- qrCodeValue.value = JSON.stringify(form.value);
- isShowQrCode.value = true;
- showQrCode()
- }
- })
-}
-const showQrCode = () => {
- // 寤惰繜鎵ц鎵撳嵃锛岄伩鍏� DOM 鏇存柊鍓嶅氨璋冪敤鎵撳嵃
- setTimeout(() => {
- printJS({
- printable: 'qrCodeContainer',//椤甸潰
- type: "html",//鏂囨。绫诲瀷
- maxWidth: 360,
- style: `@page {
- margin:0;
- size: 400px 75px collapse;
- margin-top:3px;
- &:first-of-type{
- margin-top:0 !important;
- }
- }
- html{
- zoom:100%;
- }
- @media print{
- width: 400px;
- height: 75px;
- margin:0;
- }`,
- targetStyles: ["*"], // 浣跨敤dom鐨勬墍鏈夋牱寮忥紝寰堥噸瑕�
- font_size: '0.20cm',
- });
- }, 300);
-}
-// 鍏抽棴鍚堝苟琛ㄥ崟
-const cancel = () => {
- proxy.resetForm("formRef")
- dialogVisitable.value = false
- emit('closeDia')
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-.print-section {
- text-align: center;
- margin-top: 30px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
deleted file mode 100644
index d1c9d8d..0000000
--- a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
+++ /dev/null
@@ -1,246 +0,0 @@
-<template>
- <div>
- <el-dialog title="鏌ョ湅闄勪欢"
- v-model="dialogVisitable" width="800px" @close="cancel">
- <div class="upload-container">
- <!-- 鐢熶骇鍓� -->
- <div class="form-container">
- <div class="title">鐢熶骇鍓�</div>
-
- <!-- 鍥剧墖鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <img v-for="(item, index) in beforeProductionImgs" :key="index"
- @click="showMedia(beforeProductionImgs, index, 'image')"
- :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
- </div>
-
- <!-- 瑙嗛鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <div
- v-for="(videoUrl, index) in beforeProductionVideos"
- :key="index"
- @click="showMedia(beforeProductionVideos, index, 'video')"
- style="position: relative; margin: 10px; cursor: pointer;"
- >
- <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
- <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
- </div>
- <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
- </div>
- </div>
- </div>
-
- <!-- 鐢熶骇鍚� -->
- <div class="form-container">
- <div class="title">鐢熶骇鍚�</div>
-
- <!-- 鍥剧墖鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <img v-for="(item, index) in afterProductionImgs" :key="index"
- @click="showMedia(afterProductionImgs, index, 'image')"
- :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
- </div>
-
- <!-- 瑙嗛鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <div
- v-for="(videoUrl, index) in afterProductionVideos"
- :key="index"
- @click="showMedia(afterProductionVideos, index, 'video')"
- style="position: relative; margin: 10px; cursor: pointer;"
- >
- <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
- <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
- </div>
- <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
- </div>
- </div>
- </div>
-
- <!-- 鐢熶骇闂 -->
- <div class="form-container">
- <div class="title">鐢熶骇闂</div>
-
- <!-- 鍥剧墖鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <img v-for="(item, index) in productionIssuesImgs" :key="index"
- @click="showMedia(productionIssuesImgs, index, 'image')"
- :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
- </div>
-
- <!-- 瑙嗛鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <div
- v-for="(videoUrl, index) in productionIssuesVideos"
- :key="index"
- @click="showMedia(productionIssuesVideos, index, 'video')"
- style="position: relative; margin: 10px; cursor: pointer;"
- >
- <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
- <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
- </div>
- <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
- </div>
- </div>
- </div>
- </div>
- </el-dialog>
-
- <!-- 缁熶竴濯掍綋鏌ョ湅鍣� -->
- <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer">
- <div class="media-viewer-content" @click.stop>
- <!-- 鍥剧墖 -->
- <vue-easy-lightbox
- v-if="mediaType === 'image'"
- :visible="isMediaViewerVisible"
- :imgs="mediaList"
- :index="currentMediaIndex"
- @hide="closeMediaViewer"
- ></vue-easy-lightbox>
-
- <!-- 瑙嗛 -->
- <div v-else-if="mediaType === 'video'" style="position: relative;">
- <Video
- :src="mediaList[currentMediaIndex]"
- autoplay
- controls
- style="max-width: 90vw; max-height: 80vh;"
- />
- </div>
- </div>
- </div>
- </div>
-</template>
-<script setup>
-import { ref } from 'vue';
-import VueEasyLightbox from 'vue-easy-lightbox';
-
-// 鎺у埗寮圭獥鏄剧ず
-const dialogVisitable = ref(false);
-
-// 鍥剧墖鏁扮粍
-const beforeProductionImgs = ref([]);
-const afterProductionImgs = ref([]);
-const productionIssuesImgs = ref([]);
-
-// 瑙嗛鏁扮粍
-const beforeProductionVideos = ref([]);
-const afterProductionVideos = ref([]);
-const productionIssuesVideos = ref([]);
-
-// 濯掍綋鏌ョ湅鍣ㄧ姸鎬�
-const isMediaViewerVisible = ref(false);
-const currentMediaIndex = ref(0);
-const mediaList = ref([]); // 瀛樺偍褰撳墠瑕佹煡鐪嬬殑濯掍綋鍒楄〃锛堝惈鍥剧墖鍜岃棰戝璞★級
-const mediaType = ref('image'); // image | video
-
-// 澶勭悊姣忎竴绫绘暟鎹細鍒嗙鍥剧墖鍜岃棰�
-function processItems(items) {
- const images = [];
- const videos = [];
- items.forEach(item => {
- if (item.contentType?.startsWith('image/')) {
- images.push(item.url);
- } else if (item.contentType?.startsWith('video/')) {
- videos.push(item.url);
- }
- });
- return { images, videos };
-}
-
-// 鎵撳紑寮圭獥骞跺姞杞芥暟鎹�
-const openDialog = async (row) => {
- const { images: beforeImgs, videos: beforeVids } = processItems(row.beforeProduction);
- const { images: afterImgs, videos: afterVids } = processItems(row.afterProduction);
- const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues);
-
- beforeProductionImgs.value = beforeImgs;
- beforeProductionVideos.value = beforeVids;
-
- afterProductionImgs.value = afterImgs;
- afterProductionVideos.value = afterVids;
-
- productionIssuesImgs.value = issueImgs;
- productionIssuesVideos.value = issueVids;
-
- dialogVisitable.value = true;
-};
-
-// 鏄剧ず濯掍綋锛堝浘鐗� or 瑙嗛锛�
-function showMedia(mediaArray, index, type) {
- mediaList.value = mediaArray;
- currentMediaIndex.value = index;
- mediaType.value = type;
- isMediaViewerVisible.value = true;
-}
-
-// 鍏抽棴濯掍綋鏌ョ湅鍣�
-function closeMediaViewer() {
- isMediaViewerVisible.value = false;
- mediaList.value = [];
- mediaType.value = 'image';
-}
-
-// 琛ㄥ崟鍏抽棴鏂规硶
-const cancel = () => {
- dialogVisitable.value = false;
-};
-
-defineExpose({ openDialog });
-</script>
-<style scoped lang="scss">
-.upload-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- border: 1px solid #dcdfe6;
- box-sizing: border-box;
-
- .form-container {
- flex: 1;
- width: 100%;
- margin-bottom: 20px;
- }
-}
-
-.title {
- font-size: 14px;
- color: #165dff;
- line-height: 20px;
- font-weight: 600;
- padding-left: 10px;
- position: relative;
- margin: 6px 0;
-
- &::before {
- content: "";
- position: absolute;
- left: 0;
- top: 3px;
- width: 4px;
- height: 14px;
- background-color: #165dff;
- }
-}
-
-.media-viewer-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.8);
- z-index: 9999;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.media-viewer-content {
- position: relative;
- max-width: 90vw;
- max-height: 90vh;
- overflow: hidden;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/inspectionManagement/components/viewQrCodeFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/viewQrCodeFiles.vue
deleted file mode 100644
index f8e923a..0000000
--- a/src/views/equipmentManagement/inspectionManagement/components/viewQrCodeFiles.vue
+++ /dev/null
@@ -1,169 +0,0 @@
-<template>
- <div>
- <el-dialog title="鏌ョ湅闄勪欢"
- v-model="dialogVisitable" width="800px" @close="cancel">
- <div class="upload-container">
- <div class="form-container">
- <div class="title">宸℃闄勪欢</div>
- <!-- 鍥剧墖鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <img v-for="(item, index) in beforeProductionImgs" :key="index"
- @click="showMedia(beforeProductionImgs, index, 'image')"
- :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
- </div>
-
- <!-- 瑙嗛鍒楄〃 -->
- <div style="display: flex; flex-wrap: wrap;">
- <div
- v-for="(videoUrl, index) in beforeProductionVideos"
- :key="index"
- @click="showMedia(beforeProductionVideos, index, 'video')"
- style="position: relative; margin: 10px; cursor: pointer;"
- >
- <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
- <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
- </div>
- <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
- </div>
- </div>
- </div>
- </div>
- </el-dialog>
- <!-- 缁熶竴濯掍綋鏌ョ湅鍣� -->
- <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer">
- <div class="media-viewer-content" @click.stop>
- <!-- 鍥剧墖 -->
- <vue-easy-lightbox
- v-if="mediaType === 'image'"
- :visible="isMediaViewerVisible"
- :imgs="mediaList"
- :index="currentMediaIndex"
- @hide="closeMediaViewer"
- ></vue-easy-lightbox>
-
- <!-- 瑙嗛 -->
- <div v-else-if="mediaType === 'video'" style="position: relative;">
- <Video
- :src="mediaList[currentMediaIndex]"
- autoplay
- controls
- style="max-width: 90vw; max-height: 80vh;"
- />
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-// 鎺у埗寮圭獥鏄剧ず
-import VueEasyLightbox from "vue-easy-lightbox";
-
-const dialogVisitable = ref(false);
-// 鍥剧墖鏁扮粍
-const beforeProductionImgs = ref([]);
-// 瑙嗛鏁扮粍
-const beforeProductionVideos = ref([]);
-// 濯掍綋鏌ョ湅鍣ㄧ姸鎬�
-const isMediaViewerVisible = ref(false);
-const currentMediaIndex = ref(0);
-const mediaList = ref([]); // 瀛樺偍褰撳墠瑕佹煡鐪嬬殑濯掍綋鍒楄〃锛堝惈鍥剧墖鍜岃棰戝璞★級
-const mediaType = ref('image'); // image | video
-
-// 鎵撳紑寮圭獥骞跺姞杞芥暟鎹�
-const openDialog = async (row) => {
- const { images: beforeImgs, videos: beforeVids } = processItems(row.storageBlobDTO);
-
- beforeProductionImgs.value = beforeImgs;
- beforeProductionVideos.value = beforeVids;
- dialogVisitable.value = true;
-};
-// 鏄剧ず濯掍綋锛堝浘鐗� or 瑙嗛锛�
-function showMedia(mediaArray, index, type) {
- mediaList.value = mediaArray;
- currentMediaIndex.value = index;
- mediaType.value = type;
- isMediaViewerVisible.value = true;
-}
-// 鍏抽棴濯掍綋鏌ョ湅鍣�
-function closeMediaViewer() {
- isMediaViewerVisible.value = false;
- mediaList.value = [];
- mediaType.value = 'image';
-}
-// 琛ㄥ崟鍏抽棴鏂规硶
-const cancel = () => {
- dialogVisitable.value = false;
-};
-// 澶勭悊姣忎竴绫绘暟鎹細鍒嗙鍥剧墖鍜岃棰�
-function processItems(items) {
- const images = [];
- const videos = [];
- items.forEach(item => {
- if (item.contentType?.startsWith('image/')) {
- images.push(item.url);
- } else if (item.contentType?.startsWith('video/')) {
- videos.push(item.url);
- }
- });
- return { images, videos };
-}
-defineExpose({ openDialog });
-</script>
-
-<style scoped lang="scss">
-.upload-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- border: 1px solid #dcdfe6;
- box-sizing: border-box;
-
- .form-container {
- flex: 1;
- width: 100%;
- margin-bottom: 20px;
- }
-}
-
-.title {
- font-size: 14px;
- color: #165dff;
- line-height: 20px;
- font-weight: 600;
- padding-left: 10px;
- position: relative;
- margin: 6px 0;
-
- &::before {
- content: "";
- position: absolute;
- left: 0;
- top: 3px;
- width: 4px;
- height: 14px;
- background-color: #165dff;
- }
-}
-
-.media-viewer-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.8);
- z-index: 9999;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.media-viewer-content {
- position: relative;
- max-width: 90vw;
- max-height: 90vh;
- overflow: hidden;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
deleted file mode 100644
index 3e4e31e..0000000
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ /dev/null
@@ -1,357 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :inline="true" :model="queryParams" class="search-form">
- <el-form-item label="鎼滅储">
- <el-input
- v-model="queryParams.searchAll"
- placeholder="璇疯緭鍏ュ叧閿瓧"
- clearable
- :style="{ width: '100%' }"
- />
- </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>
- <el-card>
- <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;">
- <el-radio-group v-model="activeRadio" @change="radioChange">
- <el-radio-button v-for="tab in radios"
- :key="tab.name"
- :label="tab.label"
- :value="tab.name"/>
- </el-radio-group>
- <!-- 鎿嶄綔鎸夐挳鍖� -->
- <el-space v-if="activeRadio !== 'task'">
- <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">鏂板缓</el-button>
- <el-button type="danger" :icon="Delete" @click="handleDelete">鍒犻櫎</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </el-space>
- <el-space v-else>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </el-space>
- </div>
- <div>
- <div>
- <PIMTable :table-loading="tableLoading"
- :table-data="tableData"
- :column="tableColumns"
- @selection-change="handleSelectionChange"
- :is-selection="true"
- :border="true"
- :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }"
- >
- <template #inspector="{ row }">
- <div class="person-tags">
- <!-- 璋冭瘯淇℃伅锛屼笂绾挎椂鍒犻櫎 -->
- <!-- {{ console.log('inspector data:', row.inspector) }} -->
- <template v-if="row.inspector && row.inspector.length > 0">
- <el-tag
- v-for="(person, index) in row.inspector"
- :key="index"
- size="small"
- type="primary"
- class="person-tag"
- >
- {{ person }}
- </el-tag>
- </template>
- <span v-else class="no-data">--</span>
- </div>
- </template>
- </PIMTable>
- </div>
- <pagination
- v-if="total>0"
- :page="pageNum"
- :limit="pageSize"
- :total="total"
- @pagination="handlePagination"
- :layout="'total, prev, pager, next, jumper'"
- />
- </div>
- </el-card>
- <form-dia ref="formDia" @closeDia="handleQuery"></form-dia>
- <view-files ref="viewFiles"></view-files>
- </div>
-</template>
-
-<script setup>
-import { Delete, Plus } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
-import { ElMessageBox } from "element-plus";
-
-// 缁勪欢寮曞叆
-import Pagination from "@/components/Pagination/index.vue";
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue";
-import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue";
-
-// 鎺ュ彛寮曞叆
-import {
- delTimingTask,
- inspectionTaskList,
- timingTaskList
-} from "@/api/inspectionManagement/index.js";
-
-// 鍏ㄥ眬鍙橀噺
-const { proxy } = getCurrentInstance();
-const formDia = ref();
-const viewFiles = ref();
-
-// 鏌ヨ鍙傛暟
-const queryParams = reactive({
- searchAll: "",
-});
-
-// 鍗曢�夋閰嶇疆
-const activeRadio = ref("taskManage");
-const radios = reactive([
- { name: "taskManage", label: "瀹氭椂浠诲姟绠$悊" },
- { name: "task", label: "瀹氭椂浠诲姟璁板綍" },
-]);
-
-// 琛ㄦ牸鏁版嵁
-const selectedRows = ref([]);
-const tableData = ref([]);
-const operationsArr = ref([]);
-const tableColumns = ref([]);
-const tableLoading = ref(false);
-const total = ref(0);
-const pageNum = ref(1);
-const pageSize = ref(10);
-
-// 鍒楅厤缃�
-const columns = ref([
- { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 160 },
- { prop: "remarks", label: "澶囨敞", minWidth: 150 },
- { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 150, slot: "inspector" },
- {
- prop: "frequencyType",
- label: "棰戞",
- minWidth: 150,
- formatter: (_, __, val) => ({
- DAILY: "姣忔棩",
- WEEKLY: "姣忓懆",
- MONTHLY: "姣忔湀",
- QUARTERLY: "瀛e害"
- }[val] || "")
- },
- {
- prop: "frequencyDetail",
- label: "寮�濮嬫棩鏈熶笌鏃堕棿",
- minWidth: 150,
- formatter: (row, column, cellValue) => {
- // 鍏堝垽鏂槸鍚︽槸瀛楃涓�
- if (typeof cellValue !== 'string') return '';
- let val = cellValue;
- const replacements = {
- MON: '鍛ㄤ竴',
- TUE: '鍛ㄤ簩',
- WED: '鍛ㄤ笁',
- THU: '鍛ㄥ洓',
- FRI: '鍛ㄤ簲',
- SAT: '鍛ㄥ叚',
- SUN: '鍛ㄦ棩'
- };
- // 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
- return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]);
- }
- },
- { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
- { prop: "createTime", label: "鐧昏鏃ユ湡", minWidth: 100 },
-]);
-
-// 鎿嶄綔鍒楅厤缃�
-const getOperationColumn = (operations) => {
- if (!operations || operations.length === 0) return null;
-
- const operationConfig = {
- label: "鎿嶄綔",
- width: 130,
- fixed: "right",
- dataType: "action",
- operation: operations.map(op => {
- switch (op) {
- case 'edit':
- return {
- name: "缂栬緫",
- clickFun: handleAdd,
- color: "#409EFF"
- };
- case 'viewFile':
- return {
- name: "鏌ョ湅闄勪欢",
- clickFun: viewFile,
- color: "#67C23A"
- };
- default:
- return null;
- }
- }).filter(Boolean)
- };
-
- return operationConfig;
-};
-
-onMounted(() => {
- radioChange('taskManage');
-});
-
-// 鍗曢�夊彉鍖�
-const radioChange = (value) => {
- if (value === "taskManage") {
- const operationColumn = getOperationColumn(['edit']);
- tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
- operationsArr.value = ['edit'];
- } else if (value === "task") {
- const operationColumn = getOperationColumn(['viewFile']);
- tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
- operationsArr.value = ['viewFile'];
- }
- pageNum.value = 1;
- pageSize.value = 10;
- getList();
-};
-
-// 鏌ヨ鎿嶄綔
-const handleQuery = () => {
- pageNum.value = 1;
- pageSize.value = 10;
- getList();
-};
-// 鍒嗛〉澶勭悊
-const handlePagination = (val) => {
- pageNum.value = val.page;
- pageSize.value = val.size;
- getList();
-};
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- tableLoading.value = true;
-
- const params = { ...queryParams, size: pageSize.value, current: pageNum.value };
-
- let apiCall;
- if (activeRadio.value === "task") {
- apiCall = inspectionTaskList(params);
- } else {
- apiCall = timingTaskList(params);
- }
-
- apiCall.then(res => {
- const rawData = res.data.records || [];
- // 澶勭悊 inspector 瀛楁锛屽皢瀛楃涓茶浆鎹负鏁扮粍锛堥�傜敤浜庢墍鏈夋儏鍐碉級
- tableData.value = rawData.map(item => {
- const processedItem = { ...item };
-
- // 澶勭悊 inspector 瀛楁
- if (processedItem.inspector) {
- if (typeof processedItem.inspector === 'string') {
- // 瀛楃涓叉寜閫楀彿鍒嗗壊
- processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s);
- } else if (!Array.isArray(processedItem.inspector)) {
- // 闈炴暟缁勮浆涓烘暟缁�
- processedItem.inspector = [processedItem.inspector];
- }
- } else {
- // 绌哄�艰涓虹┖鏁扮粍
- processedItem.inspector = [];
- }
-
- return processedItem;
- });
- total.value = res.data.total || 0;
- }).finally(() => {
- tableLoading.value = false;
- });
-};
-
-// 閲嶇疆鏌ヨ
-const resetQuery = () => {
- for (const key in queryParams) {
- if (!["pageNum", "pageSize"].includes(key)) {
- queryParams[key] = "";
- }
- }
- handleQuery();
-};
-
-// 鏂板 / 缂栬緫
-const handleAdd = (row) => {
- const type = row ? 'edit' : 'add';
- nextTick(() => {
- formDia.value?.openDialog(type, row);
- });
-};
-
-// 鏌ョ湅闄勪欢
-const viewFile = (row) => {
- nextTick(() => {
- viewFiles.value?.openDialog(row);
- });
-};
-
-// 鍒犻櫎鎿嶄綔
-const handleDelete = () => {
- if (!selectedRows.value.length) {
- proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
- return;
- }
-
- const deleteIds = selectedRows.value.map(item => item.id);
-
- proxy.$modal.confirm('鏄惁纭鍒犻櫎鎵�閫夋暟鎹」锛�').then(() => {
- return delTimingTask(deleteIds);
- }).then(() => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- handleQuery();
- }).catch(() => {});
-};
-
-// 澶氶�夊彉鏇�
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- // 鏍规嵁褰撳墠閫変腑鐨勬爣绛鹃〉璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
- if (activeRadio.value === "taskManage") {
- // 瀹氭椂浠诲姟绠$悊
- proxy.download("/timingTask/export", {}, "瀹氭椂浠诲姟绠$悊.xlsx");
- } else if (activeRadio.value === "task") {
- // 瀹氭椂浠诲姟璁板綍
- proxy.download("/inspectionTask/export", {}, "瀹氭椂浠诲姟璁板綍.xlsx");
- }
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-</script>
-
-<style scoped>
-.person-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 4px;
-}
-
-.person-tag {
- margin-right: 4px;
- margin-bottom: 2px;
-}
-
-.no-data {
- color: #909399;
- font-size: 14px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/iotMonitor/index.vue b/src/views/equipmentManagement/iotMonitor/index.vue
deleted file mode 100644
index de62866..0000000
--- a/src/views/equipmentManagement/iotMonitor/index.vue
+++ /dev/null
@@ -1,317 +0,0 @@
-<template>
- <div class="app-container iot-monitor">
- <div class="header">
- <div class="title">瀹炴椂宸ュ喌鐩戞帶锛圛oT锛�</div>
- <div class="actions">
- <el-button type="primary" @click="toggleCollecting">{{ collecting ? '鏆傚仠閲囬泦' : '鍚姩閲囬泦' }}</el-button>
- <el-button @click="resetAll">閲嶇疆</el-button>
- <span class="ts">涓婃鏇存柊鏃堕棿锛歿{ lastUpdatedDisplay }}</span>
- </div>
- </div>
-
-<!-- <el-alert-->
-<!-- title="杈圭紭棰勮瑙勫垯锛氳酱鎵跨(鎹�-鎸姩鍊煎亸绂诲熀绾柯�5%瑙﹀彂鍛婅锛涙俯搴�/鍘嬪姏瓒婄晫瑙﹀彂鎻愰啋"-->
-<!-- type="info"-->
-<!-- :closable="false"-->
-<!-- show-icon-->
-<!-- class="rule-alert"-->
-<!-- />-->
-
- <el-row :gutter="16">
- <el-col v-for="dev in devices" :key="dev.id" :span="12">
- <el-card :class="['device-card', dev.hasAlert ? 'is-alert' : '']">
- <template #header>
- <div class="card-header">
- <div class="card-title">
- <span class="device-name">{{ dev.name }}</span>
- <el-tag :type="dev.hasAlert ? 'danger' : 'success'" size="small">{{ dev.hasAlert ? '鍛婅' : '姝e父' }}</el-tag>
- </div>
- <div class="meta">绫诲瀷锛歿{ dev.type }}锝滃熀绾挎尟鍔細{{ dev.baseline.vibration.toFixed(2) }} mm/s</div>
- </div>
- </template>
-
- <div class="metrics">
- <div class="metric" :class="{ 'metric-alert': dev.alerts.vibration }">
- <div class="metric-head">
- <span>鎸姩(mm/s)</span>
- <el-tag :type="dev.alerts.vibration ? 'danger' : 'info'" size="small">{{ dev.alerts.vibration ? '卤5%瓒婄晫' : '鍩虹嚎卤5%' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.vibration).toFixed(2) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: 'mm/s' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.vibration }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#409EFF']"
- />
- </div>
-
- <div class="metric" :class="{ 'metric-alert': dev.alerts.temperature }">
- <div class="metric-head">
- <span>娓╁害(掳C)</span>
- <el-tag :type="dev.alerts.temperature ? 'warning' : 'info'" size="small">{{ dev.alerts.temperature ? '瓒婄晫' : '20~80' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.temperature).toFixed(1) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: '掳C' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.temperature }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#E6A23C']"
- />
- </div>
-
- <div class="metric" :class="{ 'metric-alert': dev.alerts.pressure }">
- <div class="metric-head">
- <span>鍘嬪姏(MPa)</span>
- <el-tag :type="dev.alerts.pressure ? 'warning' : 'info'" size="small">{{ dev.alerts.pressure ? '瓒婄晫' : '0.2~1.5' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.pressure).toFixed(2) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: 'MPa' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.pressure }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#67C23A']"
- />
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
-import { ElNotification } from 'element-plus'
-import Echarts from '@/components/Echarts/echarts.vue'
-
-defineOptions({ name: 'IoTMonitor' })
-
-const windowSize = 30
-const collecting = ref(true)
-const lastUpdated = ref(Date.now())
-const lastUpdatedDisplay = computed(() => new Date(lastUpdated.value).toLocaleTimeString())
-
-const xAxisLabels = ref(Array.from({ length: windowSize }, (_, i) => i - (windowSize - 1)).map(n => `${n}s`))
-
-function makeSeries(fill, decimals = 2) {
- return Array.from({ length: windowSize }, () => Number(fill.toFixed(decimals)))
-}
-
-const devices = reactive([
- {
- id: 'water-pump',
- name: '璁惧1',
- type: '绉诲姩瑁呭',
- baseline: { vibration: 9 },
- initial: { temperature: 40, pressure: 0.70 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(9),
- temperature: makeSeries(40, 1),
- pressure: makeSeries(0.7, 2),
- },
- },
- {
- id: 'fluid-supply-truck',
- name: '璁惧2',
- type: '绉诲姩瑁呭',
- baseline: { vibration: 7 },
- initial: { temperature: 30, pressure: 0.60 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(7),
- temperature: makeSeries(30, 1),
- pressure: makeSeries(0.6, 2),
- },
- },
- {
- id: 'fracturing-truck',
- name: '璁惧3',
- type: '绉诲姩瑁呭',
- baseline: { vibration: 12 },
- initial: { temperature: 65, pressure: 1.40 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(12),
- temperature: makeSeries(65, 1),
- pressure: makeSeries(1.4, 2),
- },
- },
- {
- id: 'oil-tank-truck',
- name: '璁惧4',
- type: '绉诲姩瑁呭',
- baseline: { vibration: 6 },
- initial: { temperature: 28, pressure: 0.50 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(6),
- temperature: makeSeries(28, 1),
- pressure: makeSeries(0.5, 2),
- },
- },
-])
-
-function currentValue(arr) {
- return arr[arr.length - 1] ?? 0
-}
-
-function pushWindow(arr, val) {
- if (arr.length >= windowSize) arr.shift()
- arr.push(val)
-}
-
-function clamp(val, min, max) { return Math.max(min, Math.min(max, val)) }
-
-function tickDevice(dev) {
- const vibBase = dev.baseline.vibration
- // 鎸姩锛氬熀绾柯�2%闅忔満娉㈠姩锛�5%姒傜巼瑙﹀彂8%~12%灏栧嘲妯℃嫙鍛婅
- const spike = Math.random() < 0.05
- const vibNoise = vibBase * (spike ? (1 + (Math.random() * 0.08 + 0.04) * (Math.random() < 0.5 ? -1 : 1)) : (1 + (Math.random() - 0.5) * 0.04))
- const vibVal = Number(vibNoise.toFixed(2))
- pushWindow(dev.series.vibration, vibVal)
-
- // 娓╁害锛氱紦鎱㈤殢鏈烘父璧帮紝骞舵坊鍔犲伓鍙戦珮娓╁亸绉�
- const tPrev = currentValue(dev.series.temperature)
- const tDrift = tPrev + (Math.random() - 0.5) * 0.8 + (Math.random() < 0.02 ? 6 : 0)
- const tVal = Number(clamp(tDrift, 15, 95).toFixed(1))
- pushWindow(dev.series.temperature, tVal)
-
- // 鍘嬪姏锛氬皬骞呮尝鍔紝鍋跺彂浣庡帇/楂樺帇
- const pPrev = currentValue(dev.series.pressure)
- const pDrift = pPrev + (Math.random() - 0.5) * 0.05 + (Math.random() < 0.02 ? (Math.random() < 0.5 ? -0.3 : 0.3) : 0)
- const pVal = Number(clamp(pDrift, 0.05, 2.0).toFixed(2))
- pushWindow(dev.series.pressure, pVal)
-
- // 杈圭紭璁$畻闃堝�煎垽鏂�
- const vibDelta = Math.abs(vibVal - vibBase) / vibBase
- const vibAlert = vibDelta > 0.05
- const tAlert = tVal < 20 || tVal > 80
- const pAlert = pVal < 0.2 || pVal > 1.5
-
- const prevHasAlert = dev.hasAlert
- dev.alerts.vibration = vibAlert
- dev.alerts.temperature = tAlert
- dev.alerts.pressure = pAlert
- dev.hasAlert = vibAlert || tAlert || pAlert
-
- if (dev.hasAlert && !prevHasAlert) {
- const reasons = []
- if (vibAlert) reasons.push(`鎸姩鍋忕卤5% (褰撳墠 ${vibVal} / 鍩虹嚎 ${vibBase})`)
- if (tAlert) reasons.push(`娓╁害瓒婄晫 (褰撳墠 ${tVal}掳C, 鏈熸湜 20~80掳C) `)
- if (pAlert) reasons.push(`鍘嬪姏瓒婄晫 (褰撳墠 ${pVal}MPa, 鏈熸湜 0.2~1.5MPa) `)
- ElNotification({
- title: `${dev.name} 鍛婅`,
- message: reasons.join('锛�'),
- type: vibAlert ? 'error' : 'warning',
- duration: 5000,
- })
- }
-}
-
-let timer = null
-function start() {
- if (timer) return
- timer = setInterval(() => {
- if (!collecting.value) return
- devices.forEach(tickDevice)
- lastUpdated.value = Date.now()
- }, 10000)
-}
-
-function stop() {
- if (timer) {
- clearInterval(timer)
- timer = null
- }
-}
-
-function toggleCollecting() { collecting.value = !collecting.value }
-
-function resetAll() {
- devices.forEach(dev => {
- dev.series.vibration = makeSeries(dev.baseline.vibration)
- const t0 = dev.initial?.temperature ?? 45
- const p0 = dev.initial?.pressure ?? 0.8
- dev.series.temperature = makeSeries(t0, 1)
- dev.series.pressure = makeSeries(p0, 2)
- dev.alerts.vibration = false
- dev.alerts.temperature = false
- dev.alerts.pressure = false
- dev.hasAlert = false
- })
- lastUpdated.value = Date.now()
-}
-
-onMounted(() => {
- start()
-})
-
-onBeforeUnmount(() => {
- stop()
-})
-</script>
-
-<style lang="scss" scoped>
-.iot-monitor {
- .header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 12px;
- .title { font-size: 18px; font-weight: 600; }
- .actions { display: flex; align-items: center; gap: 8px; }
- .ts { color: #909399; font-size: 12px; }
- }
- .rule-alert { margin-bottom: 12px; }
-}
-
-.device-card {
- margin-bottom: 16px;
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
- &.is-alert { border-color: #F56C6C; box-shadow: 0 0 0 2px rgba(245,108,108,0.2) inset; }
- .card-header {
- display: flex; flex-direction: column; gap: 4px;
- .card-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
- .meta { color: #909399; font-size: 12px; }
- }
- .metrics {
- display: grid;
- grid-template-columns: 1fr;
- gap: 12px;
- }
-}
-
-.metric {
- border: 1px solid #ebeef5;
- border-radius: 6px;
- padding: 8px 8px 0 8px;
- &-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; font-size: 13px; color: #606266; }
- &-value { font-size: 20px; font-weight: 600; margin: 2px 0 6px 0; }
-}
-
-.metric-alert {
- border-color: #F56C6C;
- background: #FFF6F6;
-}
-
-@media (min-width: 1200px) {
- .device-card .metrics { grid-template-columns: 1fr 1fr 1fr; }
-}
-</style>
-
-
diff --git a/src/views/equipmentManagement/iotMonitor/indexWD.vue b/src/views/equipmentManagement/iotMonitor/indexWD.vue
deleted file mode 100644
index d98afe2..0000000
--- a/src/views/equipmentManagement/iotMonitor/indexWD.vue
+++ /dev/null
@@ -1,317 +0,0 @@
-<template>
- <div class="app-container iot-monitor">
- <div class="header">
- <div class="title">瀹炴椂宸ュ喌鐩戞帶锛圛oT锛�</div>
- <div class="actions">
- <el-button type="primary" @click="toggleCollecting">{{ collecting ? '鏆傚仠閲囬泦' : '鍚姩閲囬泦' }}</el-button>
- <el-button @click="resetAll">閲嶇疆</el-button>
- <span class="ts">涓婃鏇存柊鏃堕棿锛歿{ lastUpdatedDisplay }}</span>
- </div>
- </div>
-
-<!-- <el-alert-->
-<!-- title="杈圭紭棰勮瑙勫垯锛氳酱鎵跨(鎹�-鎸姩鍊煎亸绂诲熀绾柯�5%瑙﹀彂鍛婅锛涙俯搴�/鍘嬪姏瓒婄晫瑙﹀彂鎻愰啋"-->
-<!-- type="info"-->
-<!-- :closable="false"-->
-<!-- show-icon-->
-<!-- class="rule-alert"-->
-<!-- />-->
-
- <el-row :gutter="16">
- <el-col v-for="dev in devices" :key="dev.id" :span="12">
- <el-card :class="['device-card', dev.hasAlert ? 'is-alert' : '']">
- <template #header>
- <div class="card-header">
- <div class="card-title">
- <span class="device-name">{{ dev.name }}</span>
- <el-tag :type="dev.hasAlert ? 'danger' : 'success'" size="small">{{ dev.hasAlert ? '鍛婅' : '姝e父' }}</el-tag>
- </div>
- <div class="meta">绫诲瀷锛歿{ dev.type }}锝滃熀绾挎尟鍔細{{ dev.baseline.vibration.toFixed(2) }} mm/s</div>
- </div>
- </template>
-
- <div class="metrics">
- <div class="metric" :class="{ 'metric-alert': dev.alerts.vibration }">
- <div class="metric-head">
- <span>鎸姩(mm/s)</span>
- <el-tag :type="dev.alerts.vibration ? 'danger' : 'info'" size="small">{{ dev.alerts.vibration ? '卤5%瓒婄晫' : '鍩虹嚎卤5%' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.vibration).toFixed(2) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: 'mm/s' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.vibration }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#409EFF']"
- />
- </div>
-
- <div class="metric" :class="{ 'metric-alert': dev.alerts.temperature }">
- <div class="metric-head">
- <span>娓╁害(掳C)</span>
- <el-tag :type="dev.alerts.temperature ? 'warning' : 'info'" size="small">{{ dev.alerts.temperature ? '瓒婄晫' : '20~80' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.temperature).toFixed(1) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: '掳C' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.temperature }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#E6A23C']"
- />
- </div>
-
- <div class="metric" :class="{ 'metric-alert': dev.alerts.pressure }">
- <div class="metric-head">
- <span>鍘嬪姏(MPa)</span>
- <el-tag :type="dev.alerts.pressure ? 'warning' : 'info'" size="small">{{ dev.alerts.pressure ? '瓒婄晫' : '0.2~1.5' }}</el-tag>
- </div>
- <div class="metric-value">{{ currentValue(dev.series.pressure).toFixed(2) }}</div>
- <Echarts
- :xAxis="[{ type: 'category', data: xAxisLabels }]"
- :yAxis="[{ type: 'value', name: 'MPa' }]"
- :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.pressure }]"
- :tooltip="{ trigger: 'axis' }"
- :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
- :chartStyle="{ height: '160px', width: '100%' }"
- :lineColors="['#67C23A']"
- />
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
-import { ElNotification } from 'element-plus'
-import Echarts from '@/components/Echarts/echarts.vue'
-
-defineOptions({ name: 'IoTMonitor' })
-
-const windowSize = 30
-const collecting = ref(true)
-const lastUpdated = ref(Date.now())
-const lastUpdatedDisplay = computed(() => new Date(lastUpdated.value).toLocaleTimeString())
-
-const xAxisLabels = ref(Array.from({ length: windowSize }, (_, i) => i - (windowSize - 1)).map(n => `${n}s`))
-
-function makeSeries(fill, decimals = 2) {
- return Array.from({ length: windowSize }, () => Number(fill.toFixed(decimals)))
-}
-
-const devices = reactive([
- {
- id: 'hydrocyclone-desander',
- name: '璁惧1',
- type: '鍒嗙璁惧',
- baseline: { vibration: 8 },
- initial: { temperature: 35, pressure: 0.85 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(8),
- temperature: makeSeries(35, 1),
- pressure: makeSeries(0.85, 2),
- },
- },
- {
- id: 'high-pressure-separator',
- name: '璁惧2',
- type: '鍒嗙璁惧',
- baseline: { vibration: 6 },
- initial: { temperature: 45, pressure: 1.20 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(6),
- temperature: makeSeries(45, 1),
- pressure: makeSeries(1.2, 2),
- },
- },
- {
- id: 'heating-throttle-pressure',
- name: '璁惧3',
- type: '璋冨帇璁惧',
- baseline: { vibration: 10 },
- initial: { temperature: 75, pressure: 1.80 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(10),
- temperature: makeSeries(75, 1),
- pressure: makeSeries(1.8, 2),
- },
- },
- {
- id: 'three-phase-separator',
- name: '璁惧4',
- type: '鍒嗙璁惧',
- baseline: { vibration: 7 },
- initial: { temperature: 38, pressure: 0.95 },
- alerts: { vibration: false, temperature: false, pressure: false },
- hasAlert: false,
- series: {
- vibration: makeSeries(7),
- temperature: makeSeries(38, 1),
- pressure: makeSeries(0.95, 2),
- },
- },
-])
-
-function currentValue(arr) {
- return arr[arr.length - 1] ?? 0
-}
-
-function pushWindow(arr, val) {
- if (arr.length >= windowSize) arr.shift()
- arr.push(val)
-}
-
-function clamp(val, min, max) { return Math.max(min, Math.min(max, val)) }
-
-function tickDevice(dev) {
- const vibBase = dev.baseline.vibration
- // 鎸姩锛氬熀绾柯�2%闅忔満娉㈠姩锛�5%姒傜巼瑙﹀彂8%~12%灏栧嘲妯℃嫙鍛婅
- const spike = Math.random() < 0.05
- const vibNoise = vibBase * (spike ? (1 + (Math.random() * 0.08 + 0.04) * (Math.random() < 0.5 ? -1 : 1)) : (1 + (Math.random() - 0.5) * 0.04))
- const vibVal = Number(vibNoise.toFixed(2))
- pushWindow(dev.series.vibration, vibVal)
-
- // 娓╁害锛氱紦鎱㈤殢鏈烘父璧帮紝骞舵坊鍔犲伓鍙戦珮娓╁亸绉�
- const tPrev = currentValue(dev.series.temperature)
- const tDrift = tPrev + (Math.random() - 0.5) * 0.8 + (Math.random() < 0.02 ? 6 : 0)
- const tVal = Number(clamp(tDrift, 15, 95).toFixed(1))
- pushWindow(dev.series.temperature, tVal)
-
- // 鍘嬪姏锛氬皬骞呮尝鍔紝鍋跺彂浣庡帇/楂樺帇
- const pPrev = currentValue(dev.series.pressure)
- const pDrift = pPrev + (Math.random() - 0.5) * 0.05 + (Math.random() < 0.02 ? (Math.random() < 0.5 ? -0.3 : 0.3) : 0)
- const pVal = Number(clamp(pDrift, 0.05, 2.0).toFixed(2))
- pushWindow(dev.series.pressure, pVal)
-
- // 杈圭紭璁$畻闃堝�煎垽鏂�
- const vibDelta = Math.abs(vibVal - vibBase) / vibBase
- const vibAlert = vibDelta > 0.05
- const tAlert = tVal < 20 || tVal > 80
- const pAlert = pVal < 0.2 || pVal > 1.5
-
- const prevHasAlert = dev.hasAlert
- dev.alerts.vibration = vibAlert
- dev.alerts.temperature = tAlert
- dev.alerts.pressure = pAlert
- dev.hasAlert = vibAlert || tAlert || pAlert
-
- if (dev.hasAlert && !prevHasAlert) {
- const reasons = []
- if (vibAlert) reasons.push(`鎸姩鍋忕卤5% (褰撳墠 ${vibVal} / 鍩虹嚎 ${vibBase})`)
- if (tAlert) reasons.push(`娓╁害瓒婄晫 (褰撳墠 ${tVal}掳C, 鏈熸湜 20~80掳C) `)
- if (pAlert) reasons.push(`鍘嬪姏瓒婄晫 (褰撳墠 ${pVal}MPa, 鏈熸湜 0.2~1.5MPa) `)
- ElNotification({
- title: `${dev.name} 鍛婅`,
- message: reasons.join('锛�'),
- type: vibAlert ? 'error' : 'warning',
- duration: 5000,
- })
- }
-}
-
-let timer = null
-function start() {
- if (timer) return
- timer = setInterval(() => {
- if (!collecting.value) return
- devices.forEach(tickDevice)
- lastUpdated.value = Date.now()
- }, 10000)
-}
-
-function stop() {
- if (timer) {
- clearInterval(timer)
- timer = null
- }
-}
-
-function toggleCollecting() { collecting.value = !collecting.value }
-
-function resetAll() {
- devices.forEach(dev => {
- dev.series.vibration = makeSeries(dev.baseline.vibration)
- const t0 = dev.initial?.temperature ?? 45
- const p0 = dev.initial?.pressure ?? 0.8
- dev.series.temperature = makeSeries(t0, 1)
- dev.series.pressure = makeSeries(p0, 2)
- dev.alerts.vibration = false
- dev.alerts.temperature = false
- dev.alerts.pressure = false
- dev.hasAlert = false
- })
- lastUpdated.value = Date.now()
-}
-
-onMounted(() => {
- start()
-})
-
-onBeforeUnmount(() => {
- stop()
-})
-</script>
-
-<style lang="scss" scoped>
-.iot-monitor {
- .header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 12px;
- .title { font-size: 18px; font-weight: 600; }
- .actions { display: flex; align-items: center; gap: 8px; }
- .ts { color: #909399; font-size: 12px; }
- }
- .rule-alert { margin-bottom: 12px; }
-}
-
-.device-card {
- margin-bottom: 16px;
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
- &.is-alert { border-color: #F56C6C; box-shadow: 0 0 0 2px rgba(245,108,108,0.2) inset; }
- .card-header {
- display: flex; flex-direction: column; gap: 4px;
- .card-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
- .meta { color: #909399; font-size: 12px; }
- }
- .metrics {
- display: grid;
- grid-template-columns: 1fr;
- gap: 12px;
- }
-}
-
-.metric {
- border: 1px solid #ebeef5;
- border-radius: 6px;
- padding: 8px 8px 0 8px;
- &-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; font-size: 13px; color: #606266; }
- &-value { font-size: 20px; font-weight: 600; margin: 2px 0 6px 0; }
-}
-
-.metric-alert {
- border-color: #F56C6C;
- background: #FFF6F6;
-}
-
-@media (min-width: 1200px) {
- .device-card .metrics { grid-template-columns: 1fr 1fr 1fr; }
-}
-</style>
-
-
diff --git a/src/views/equipmentManagement/kplMonitor/index.vue b/src/views/equipmentManagement/kplMonitor/index.vue
deleted file mode 100644
index 178b658..0000000
--- a/src/views/equipmentManagement/kplMonitor/index.vue
+++ /dev/null
@@ -1,714 +0,0 @@
-<template>
- <div class="kpl-monitor-container">
- <!-- 椤甸潰澶撮儴 -->
- <div class="page-header">
- <div class="header-content">
- <h1>KPL鐩戞帶鍒嗘瀽</h1>
- <p>璁惧鍏抽敭鎬ц兘鎸囨爣鐩戞帶涓庣淮淇濈瓥鐣ヤ紭鍖�</p>
- </div>
- <div class="time-range">
- <el-date-picker
- v-model="timeRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- value-format="YYYY-MM-DD"
- @change="fetchKPLData"
- />
- </div>
- </div>
-
- <!-- 鍏抽敭鎸囨爣姒傝 -->
- <div class="metrics-overview">
- <div class="metric-card mtbf-card">
- <div class="metric-icon">鈴憋笍</div>
- <div class="metric-content">
- <div class="metric-title">MTBF</div>
- <div class="metric-subtitle">骞冲潎鏃犳晠闅滄椂闂�</div>
- <div class="metric-value">{{ currentMTBF }}<span class="unit">灏忔椂</span></div>
- <div class="metric-trend" :class="mtbfTrendClass">
- <span class="trend-icon">{{ mtbfTrendText }}</span>
- <span class="trend-text">{{ Math.abs(mtbfChange) }}%</span>
- </div>
- </div>
- </div>
-
- <div class="metric-card mttr-card">
- <div class="metric-icon">馃敡</div>
- <div class="metric-content">
- <div class="metric-title">MTTR</div>
- <div class="metric-subtitle">骞冲潎淇鏃堕棿</div>
- <div class="metric-value">{{ currentMTTR }}<span class="unit">灏忔椂</span></div>
- <div class="metric-trend" :class="mttrTrendClass">
- <span class="trend-icon">{{ mttrTrendText }}</span>
- <span class="trend-text">{{ Math.abs(mttrChange) }}%</span>
- </div>
- </div>
- </div>
-
- <div class="metric-card availability-card">
- <div class="metric-icon">馃搳</div>
- <div class="metric-content">
- <div class="metric-title">璁惧鍙敤鐜�</div>
- <div class="metric-subtitle">杩愯鏁堢巼鎸囨爣</div>
- <div class="metric-value">{{ currentAvailability }}<span class="unit">%</span></div>
- <div class="metric-trend" :class="availabilityTrendClass">
- <span class="trend-icon">{{ availabilityTrendText }}</span>
- <span class="trend-text">{{ Math.abs(availabilityChange) }}%</span>
- </div>
- </div>
- </div>
- </div>
-
- <!-- 瓒嬪娍鍒嗘瀽鍥捐〃 -->
- <div class="charts-section">
- <div class="chart-container">
- <div class="chart-header">
- <h3>MTBF & MTTR 瓒嬪娍鍒嗘瀽</h3>
- <div class="chart-legend">
- <span class="legend-item mtbf-legend">
- <span class="legend-color"></span>
- MTBF (骞冲潎鏃犳晠闅滄椂闂�)
- </span>
- <span class="legend-item mttr-legend">
- <span class="legend-color"></span>
- MTTR (骞冲潎淇鏃堕棿)
- </span>
- </div>
- </div>
- <div class="chart-wrapper">
- <div ref="trendChart" class="chart"></div>
- </div>
- </div>
- </div>
-
- <!-- 缁翠繚绛栫暐寤鸿 -->
- <div class="recommendations-section">
- <div class="section-header">
- <h3>缁翠繚绛栫暐浼樺寲寤鸿</h3>
- <p>鍩轰簬褰撳墠鎸囨爣鍒嗘瀽锛屼负鎮ㄦ彁渚涢拡瀵规�х殑浼樺寲寤鸿</p>
- </div>
- <div class="recommendations-grid">
- <div
- v-for="(recommendation, index) in recommendations"
- :key="index"
- class="recommendation-card"
- >
- <div class="recommendation-icon">{{ recommendation.icon }}</div>
- <div class="recommendation-content">
- <h4>{{ recommendation.title }}</h4>
- <p>{{ recommendation.description }}</p>
- <div class="recommendation-priority" :class="recommendation.priority">
- {{ recommendation.priorityText }}
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, computed, nextTick } from 'vue'
-import * as echarts from 'echarts'
-
-// 鐢熸垚妯℃嫙鏁版嵁
-const generateMockData = () => {
- const months = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
- const mtbfData = months.map(() => Math.floor(Math.random() * 200 + 300)) // 300-500灏忔椂
- const mttrData = months.map(() => Math.floor(Math.random() * 8 + 4)) // 4-12灏忔椂
-
- return {
- months,
- mtbfData,
- mttrData
- }
-}
-
-const timeRange = ref([
- new Date(new Date().getFullYear(), 0, 1).toISOString().split('T')[0],
- new Date().toISOString().split('T')[0]
-])
-
-const mockData = reactive(generateMockData())
-
-// 璁$畻褰撳墠鎸囨爣鍊�
-const currentMTBF = computed(() => mockData.mtbfData[mockData.mtbfData.length - 1])
-const currentMTTR = computed(() => mockData.mttrData[mockData.mttrData.length - 1])
-const currentAvailability = computed(() =>
- Math.round((currentMTBF.value / (currentMTBF.value + currentMTTR.value)) * 100)
-)
-
-// 璁$畻鍙樺寲瓒嬪娍
-const mtbfChange = computed(() => {
- const current = currentMTBF.value
- const previous = mockData.mtbfData[mockData.mtbfData.length - 2] || current
- return Math.round(((current - previous) / previous) * 100)
-})
-
-const mttrChange = computed(() => {
- const current = currentMTTR.value
- const previous = mockData.mttrData[mockData.mttrData.length - 2] || current
- return Math.round(((current - previous) / previous) * 100)
-})
-
-const availabilityChange = computed(() => {
- const current = currentAvailability.value
- const previous = Math.round(
- (mockData.mtbfData[mockData.mtbfData.length - 2] /
- (mockData.mtbfData[mockData.mtbfData.length - 2] + mockData.mttrData[mockData.mttrData.length - 2])) * 100
- ) || current
- return Math.round(((current - previous) / previous) * 100)
-})
-
-// 瓒嬪娍鏍峰紡鍜屾枃鏈�
-const mtbfTrendClass = computed(() => mtbfChange.value >= 0 ? 'trend-up' : 'trend-down')
-const mttrTrendClass = computed(() => mttrChange.value <= 0 ? 'trend-up' : 'trend-down')
-const availabilityTrendClass = computed(() => availabilityChange.value >= 0 ? 'trend-up' : 'trend-down')
-
-const mtbfTrendText = computed(() => mtbfChange.value >= 0 ? '鈫�' : '鈫�')
-const mttrTrendText = computed(() => mttrChange.value <= 0 ? '鈫�' : '鈫�')
-const availabilityTrendText = computed(() => availabilityChange.value >= 0 ? '鈫�' : '鈫�')
-
-// 鏅鸿兘缁翠繚寤鸿
-const recommendations = computed(() => {
- const suggestions = []
-
- // MTBF鐩稿叧寤鸿
- if (currentMTBF.value < 400) {
- suggestions.push({
- icon: '馃敡',
- title: '鎻愬崌MTBF',
- description: '褰撳墠MTBF杈冧綆锛屽缓璁姞寮洪闃叉�х淮鎶わ紝瀹氭湡妫�鏌ュ叧閿儴浠讹紝寤堕暱璁惧鏃犳晠闅滆繍琛屾椂闂�',
- priority: 'high',
- priorityText: '楂樹紭鍏堢骇'
- })
- }
-
- // MTTR鐩稿叧寤鸿
- if (currentMTTR.value > 8) {
- suggestions.push({
- icon: '鈿�',
- title: '浼樺寲MTTR',
- description: '褰撳墠MTTR杈冮珮锛屽缓璁紭鍖栫淮淇祦绋嬶紝鎻愰珮缁翠慨浜哄憳鎶�鑳斤紝缂╃煭鏁呴殰淇鏃堕棿',
- priority: 'high',
- priorityText: '楂樹紭鍏堢骇'
- })
- }
-
- // 鍙敤鐜囩浉鍏冲缓璁�
- if (currentAvailability.value < 95) {
- suggestions.push({
- icon: '馃搱',
- title: '鎻愬崌鍙敤鐜�',
- description: '璁惧鍙敤鐜囨湁寰呮彁鍗囷紝寤鸿浼樺寲缁翠繚璁″垝瀹夋帓锛屽噺灏戣鍒掑鍋滄満鏃堕棿',
- priority: 'medium',
- priorityText: '涓紭鍏堢骇'
- })
- }
-
- // 缁煎悎寤鸿
- if (currentMTBF.value >= 400 && currentMTTR.value <= 8 && currentAvailability.value >= 95) {
- suggestions.push({
- icon: '鉁�',
- title: '杩愯鐘跺喌鑹ソ',
- description: '褰撳墠璁惧杩愯鐘跺喌鑹ソ锛屽悇椤规寚鏍囧潎杈惧埌棰勬湡锛屽缓璁户缁繚鎸佺幇鏈夌淮淇濈瓥鐣�',
- priority: 'low',
- priorityText: '浣庝紭鍏堢骇'
- })
- }
-
- // 棰勯槻鎬у缓璁�
- suggestions.push({
- icon: '馃搵',
- title: '棰勯槻鎬х淮鎶�',
- description: '寤鸿寤虹珛璁惧鍋ュ悍妗f锛屽畾鏈熷垎鏋愯澶囪繍琛屾暟鎹紝鎻愬墠璇嗗埆娼滃湪鏁呴殰椋庨櫓',
- priority: 'medium',
- priorityText: '涓紭鍏堢骇'
- })
-
- return suggestions
-})
-
-// 鍥捐〃瀹炰緥
-let trendChart = null
-
-const initChart = () => {
- nextTick(() => {
- trendChart = echarts.init(document.querySelector('.chart'))
- trendChart.setOption({
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'cross'
- }
- },
- legend: {
- data: ['MTBF', 'MTTR'],
- top: 10
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- data: mockData.months,
- axisLine: {
- lineStyle: {
- color: '#e0e0e0'
- }
- }
- },
- yAxis: [
- {
- type: 'value',
- name: 'MTBF (灏忔椂)',
- position: 'left',
- axisLine: {
- lineStyle: {
- color: '#1890ff'
- }
- },
- axisLabel: {
- formatter: '{value}h'
- }
- },
- {
- type: 'value',
- name: 'MTTR (灏忔椂)',
- position: 'right',
- axisLine: {
- lineStyle: {
- color: '#52c41a'
- }
- },
- axisLabel: {
- formatter: '{value}h'
- }
- }
- ],
- series: [
- {
- name: 'MTBF',
- type: 'line',
- yAxisIndex: 0,
- data: mockData.mtbfData,
- smooth: true,
- lineStyle: {
- color: '#1890ff',
- width: 3
- },
- itemStyle: {
- color: '#1890ff'
- },
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: 'rgba(24, 144, 255, 0.3)' },
- { offset: 1, color: 'rgba(24, 144, 255, 0.1)' }
- ])
- }
- },
- {
- name: 'MTTR',
- type: 'line',
- yAxisIndex: 1,
- data: mockData.mttrData,
- smooth: true,
- lineStyle: {
- color: '#52c41a',
- width: 3
- },
- itemStyle: {
- color: '#52c41a'
- },
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: 'rgba(82, 196, 26, 0.3)' },
- { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
- ])
- }
- }
- ]
- })
- })
-}
-
-const fetchKPLData = () => {
- // 妯℃嫙鏁版嵁鍒锋柊
- Object.assign(mockData, generateMockData())
-
- // 閲嶆柊娓叉煋鍥捐〃
- if (trendChart) {
- trendChart.setOption({
- xAxis: {
- data: mockData.months
- },
- series: [
- {
- data: mockData.mtbfData
- },
- {
- data: mockData.mttrData
- }
- ]
- })
- }
-}
-
-onMounted(() => {
- initChart()
-
- // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
- window.addEventListener('resize', () => {
- if (trendChart) trendChart.resize()
- })
-})
-</script>
-
-<style scoped>
-.kpl-monitor-container {
- min-height: 100vh;
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
- padding: 24px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
-}
-
-/* 椤甸潰澶撮儴 */
-.page-header {
- background: white;
- border-radius: 12px;
- padding: 24px;
- margin-bottom: 24px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.header-content h1 {
- margin: 0 0 8px 0;
- color: #1f2937;
- font-size: 28px;
- font-weight: 700;
-}
-
-.header-content p {
- margin: 0;
- color: #6b7280;
- font-size: 16px;
-}
-
-.time-range {
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-/* 鎸囨爣姒傝 */
-.metrics-overview {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 20px;
- margin-bottom: 24px;
-}
-
-.metric-card {
- background: white;
- border-radius: 12px;
- padding: 24px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- display: flex;
- align-items: center;
- gap: 16px;
- transition: transform 0.2s ease, box-shadow 0.2s ease;
-}
-
-.metric-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
-}
-
-.metric-icon {
- font-size: 32px;
- width: 60px;
- height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 12px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-}
-
-.mtbf-card .metric-icon {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-}
-
-.mttr-card .metric-icon {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
-}
-
-.availability-card .metric-icon {
- background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
-}
-
-.metric-content {
- flex: 1;
-}
-
-.metric-title {
- font-size: 18px;
- font-weight: 600;
- color: #1f2937;
- margin-bottom: 4px;
-}
-
-.metric-subtitle {
- font-size: 14px;
- color: #6b7280;
- margin-bottom: 12px;
-}
-
-.metric-value {
- font-size: 32px;
- font-weight: 700;
- color: #1f2937;
- margin-bottom: 8px;
-}
-
-.unit {
- font-size: 16px;
- font-weight: 500;
- color: #6b7280;
- margin-left: 4px;
-}
-
-.metric-trend {
- display: flex;
- align-items: center;
- gap: 4px;
- font-size: 14px;
- font-weight: 600;
-}
-
-.trend-up {
- color: #10b981;
-}
-
-.trend-down {
- color: #ef4444;
-}
-
-.trend-icon {
- font-size: 16px;
-}
-
-/* 鍥捐〃鍖哄煙 */
-.charts-section {
- margin-bottom: 24px;
-}
-
-.chart-container {
- background: white;
- border-radius: 12px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- overflow: hidden;
-}
-
-.chart-header {
- padding: 20px 24px;
- border-bottom: 1px solid #e5e7eb;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.chart-header h3 {
- margin: 0;
- color: #1f2937;
- font-size: 18px;
- font-weight: 600;
-}
-
-.chart-legend {
- display: flex;
- gap: 20px;
-}
-
-.legend-item {
- display: flex;
- align-items: center;
- gap: 8px;
- font-size: 14px;
- color: #6b7280;
-}
-
-.legend-color {
- width: 12px;
- height: 12px;
- border-radius: 2px;
-}
-
-.mtbf-legend .legend-color {
- background: #1890ff;
-}
-
-.mttr-legend .legend-color {
- background: #52c41a;
-}
-
-.chart-wrapper {
- padding: 20px;
- height: 400px;
-}
-
-.chart {
- width: 100%;
- height: 100%;
-}
-
-/* 寤鸿鍖哄煙 */
-.recommendations-section {
- background: white;
- border-radius: 12px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- overflow: hidden;
-}
-
-.section-header {
- padding: 24px;
- border-bottom: 1px solid #e5e7eb;
-}
-
-.section-header h3 {
- margin: 0 0 8px 0;
- color: #1f2937;
- font-size: 20px;
- font-weight: 600;
-}
-
-.section-header p {
- margin: 0;
- color: #6b7280;
- font-size: 14px;
-}
-
-.recommendations-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
- gap: 20px;
- padding: 24px;
-}
-
-.recommendation-card {
- background: #f8fafc;
- border-radius: 8px;
- padding: 20px;
- display: flex;
- gap: 16px;
- transition: transform 0.2s ease, box-shadow 0.2s ease;
-}
-
-.recommendation-card:hover {
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.recommendation-icon {
- font-size: 24px;
- width: 40px;
- height: 40px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- background: white;
- flex-shrink: 0;
-}
-
-.recommendation-content {
- flex: 1;
-}
-
-.recommendation-content h4 {
- margin: 0 0 8px 0;
- color: #1f2937;
- font-size: 16px;
- font-weight: 600;
-}
-
-.recommendation-content p {
- margin: 0 0 12px 0;
- color: #6b7280;
- font-size: 14px;
- line-height: 1.5;
-}
-
-.recommendation-priority {
- display: inline-block;
- padding: 4px 8px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
-}
-
-.priority.high {
- background: #fef2f2;
- color: #dc2626;
-}
-
-.priority.medium {
- background: #fffbeb;
- color: #d97706;
-}
-
-.priority.low {
- background: #f0fdf4;
- color: #16a34a;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .kpl-monitor-container {
- padding: 16px;
- }
-
- .page-header {
- flex-direction: column;
- gap: 16px;
- align-items: stretch;
- }
-
- .metrics-overview {
- grid-template-columns: 1fr;
- }
-
- .recommendations-grid {
- grid-template-columns: 1fr;
- }
-
- .chart-wrapper {
- height: 300px;
- }
-
- .chart-legend {
- flex-direction: column;
- gap: 8px;
- }
-}
-
-@media (max-width: 480px) {
- .metric-card {
- flex-direction: column;
- text-align: center;
- }
-
- .recommendation-card {
- flex-direction: column;
- text-align: center;
- }
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
deleted file mode 100644
index d14f4ff..0000000
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ /dev/null
@@ -1,239 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О" prop="deviceName">
- <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel">
- <el-input v-model="form.deviceModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
- <el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟�" prop="supplierName">
- <el-input v-model="form.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀛樻斁浣嶇疆" prop="storageLocation">
- <el-input v-model="form.storageLocation" placeholder="璇疯緭鍏ュ瓨鏀句綅缃�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍗曚綅" prop="unit">
- <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
- <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏁伴噺" prop="number">
- <el-input-number :min="1" style="width: 100%"
- v-model="form.number"
- disabled
- placeholder="璇疯緭鍏ユ暟閲�"
- @change="mathNum"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚◣鍗曚环" prop="taxIncludingPriceUnit">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="form.taxIncludingPriceUnit"
- placeholder="璇疯緭鍏ュ惈绋庡崟浠�"
- maxlength="10"
- @change="mathNum"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚◣鎬讳环" prop="taxIncludingPriceTotal">
- <el-input
- v-model="form.taxIncludingPriceTotal"
- placeholder="鑷姩鐢熸垚"
- type="number"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绋庣巼(%)" prop="taxRate">
- <!-- <el-input
- v-model="form.taxRate"
- placeholder="璇疯緭鍏ョ◣鐜�"
- type="number"
- >
- <template #append> % </template>
- </el-input> -->
- <el-select
- v-model="form.taxRate"
- placeholder="璇烽�夋嫨"
- clearable
- @change="mathNum"
- >
- <el-option label="1" :value="1" />
- <el-option label="6" :value="6" />
- <el-option label="13" :value="13" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓嶅惈绋庢�讳环" prop="unTaxIncludingPriceTotal">
- <el-input
- v-model="form.unTaxIncludingPriceTotal"
- placeholder="鑷姩鐢熸垚"
- type="number"
- disabled
- />
- </el-form-item>
- </el-col>
- <!-- <el-col :span="12">
- <el-form-item label="褰曞叆浜�" prop="createUser">
- <el-input v-model="form.createUser" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
- </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"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="date"
- placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰勮杩愯鏃堕棿" prop="planRuntimeTime">
- <el-date-picker
- style="width: 100%"
- v-model="form.planRuntimeTime"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-// import useUserStore from "@/store/modules/user";
-import { getLedgerById } from "@/api/equipmentManagement/ledger";
-import dayjs from "dayjs";
-import {
- calculateTaxIncludeTotalPrice,
- calculateTaxExclusiveTotalPrice,
-} from "@/utils/summarizeTable";
-import { ElMessage } from "element-plus";
-import {ref} from "vue";
-
-defineOptions({
- name: "璁惧鍙拌处琛ㄥ崟",
-});
-const formRef = ref(null);
-const operationType = ref('');
-const formRules = {
- deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
- planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
- deviceName: undefined, // 璁惧鍚嶇О
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- deviceBrand: undefined, // 璁惧鍝佺墝
- supplierName: undefined, // 渚涘簲鍟�
- storageLocation: undefined, // 瀛樻斁浣嶇疆
- enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
- unit: undefined, // 鍗曚綅
- number: 1, // 鏁伴噺
- taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
- taxIncludingPriceTotal: undefined, // 鍚◣鎬讳环
- taxRate: undefined, // 绋庣巼
- unTaxIncludingPriceTotal: undefined, // 涓嶅惈绋庢�讳环
- // createUser: useUserStore().nickName, // 褰曞叆浜�
- createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 褰曞叆鏃ユ湡
- planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 褰曞叆鏃ユ湡
-});
-
-const loadForm = async (id) => {
- if (id) {
- operationType.value = 'edit'
- }
- const { code, data } = await getLedgerById(id);
- if (code == 200) {
- form.deviceName = data.deviceName;
- form.deviceModel = data.deviceModel;
- form.deviceBrand = data.deviceBrand;
- form.supplierName = data.supplierName;
- form.storageLocation = data.storageLocation;
- form.enableDepreciation = data.enableDepreciation;
- form.unit = data.unit;
- form.number = 1;
- form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
- form.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
- form.taxRate = data.taxRate;
- form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
- form.createTime = data.createTime;
- }
-};
-
-const mathNum = () => {
- if (!form.taxIncludingPriceUnit) {
- ElMessage.error("璇疯緭鍏ュ崟浠�");
- return;
- }
- form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice(
- form.taxIncludingPriceUnit,
- form.number
- );
- if (form.taxRate) {
- form.unTaxIncludingPriceTotal = calculateTaxExclusiveTotalPrice(
- form.taxIncludingPriceTotal,
- form.taxRate
- );
- }
-};
-
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
- formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
- resetForm();
- clearValidate();
-};
-
-defineExpose({
- form,
- loadForm,
- resetForm,
- clearValidate,
- resetFormAndValidate,
- formRef,
-});
-</script>
diff --git a/src/views/equipmentManagement/ledger/Modal.vue b/src/views/equipmentManagement/ledger/Modal.vue
deleted file mode 100644
index 0cea56c..0000000
--- a/src/views/equipmentManagement/ledger/Modal.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" @close="close">
- <Form ref="formRef"></Form>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import { addLedger, editLedger } from "@/api/equipmentManagement/ledger";
-import Form from "./Form.vue";
-import { ElMessage } from "element-plus";
-const { proxy } = getCurrentInstance()
-
-defineOptions({
- name: "璁惧鍙拌处鏂板缂栬緫",
-});
-
-const emits = defineEmits(["success"]);
-
-const formRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧鍙拌处" });
-
-const sendForm = () => {
- proxy.$refs.formRef.$refs.formRef.validate(async valid => {
- if (valid) {
- const {code} = id.value
- ? await editLedger({id: id.value, ...formRef.value.form})
- : await addLedger(formRef.value.form);
- if (code == 200) {
- emits("success");
- ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
- close();
- } else {
- loading.value = false;
- }
- }
- })
-};
-
-const close = () => {
- formRef.value.resetFormAndValidate();
- closeModal();
-};
-
-const loadForm = async (id) => {
- openModal(id);
- await nextTick();
- formRef.value.loadForm(id);
-};
-
-defineExpose({
- openModal,
- loadForm,
-});
-</script>
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
deleted file mode 100644
index 6af5543..0000000
--- a/src/views/equipmentManagement/ledger/index.vue
+++ /dev/null
@@ -1,357 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="璁惧鍚嶇О">
- <el-input
- v-model="filters.deviceName"
- style="width: 240px"
- placeholder="璇疯緭鍏ヨ澶囧悕绉�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="filters.deviceModel"
- style="width: 240px"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="渚涘簲鍟�">
- <el-input
- v-model="filters.supplierName"
- style="width: 240px"
- placeholder="璇疯緭鍏ヤ緵搴斿晢"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="鍗曚綅">
- <el-input
- v-model="filters.unit"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="褰曞叆鏃ユ湡:">
- <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="deleteRow(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </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>
- <Modal ref="modalRef" @success="getTableData"></Modal>
- <el-dialog v-model="qrDialogVisible" title="浜岀淮鐮�" width="300px">
- <div style="text-align:center;">
- <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
- <div style="margin-top:6px;font-size:14px;color:#333;">{{ qrRowData?.deviceName }}</div>
- <div style="margin:10px 0;">
- <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
- </div>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-// import { Search } from "@element-plus/icons-vue";
-import { getLedgerPage, delLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted, getCurrentInstance } from "vue";
-import Modal from "./Modal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import dayjs from "dayjs";
-import QRCode from "qrcode";
-import { ref } from "vue";
-
-defineOptions({
- name: "璁惧鍙拌处",
-});
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-const { proxy } = getCurrentInstance();
-const modalRef = ref();
-const qrDialogVisible = ref(false);
-const qrCodeUrl = ref("");
-const qrRowData = ref(null);
-
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- getLedgerPage,
- {
- deviceName: undefined,
- deviceModel: undefined,
- supplierName: undefined,
- unit: undefined,
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- [
- {
- label: "璁惧鍚嶇О",
- align: "center",
- prop: "deviceName",
- },
- {
- label: "瑙勬牸鍨嬪彿",
- align: "center",
- prop: "deviceModel",
- },
- {
- label: "璁惧鍝佺墝",
- align: "center",
- prop: "deviceBrand",
- },
- {
- label: "渚涘簲鍟�",
- align: "center",
- prop: "supplierName",
- },
- {
- label: "鍗曚綅",
- align: "center",
- prop: "unit",
- },
- {
- label: "瀛樻斁浣嶇疆",
- align: "center",
- prop: "storageLocation",
- },
- {
- label: "鏁伴噺",
- align: "center",
- prop: "number",
- },
- {
- label: "鍚◣鍗曚环",
- align: "center",
- prop: "taxIncludingPriceUnit",
- },
- {
- label: "鍚◣鎬讳环",
- align: "center",
- prop: "taxIncludingPriceTotal",
- },
- {
- label: "绋庣巼",
- align: "center",
- prop: "taxRate",
- },
- {
- label: "涓嶅惈绋庢�讳环",
- align: "center",
- prop: "unTaxIncludingPriceTotal",
- },
- {
- label: "鍚敤鎶樻棫",
- align: "center",
- prop: "enableDepreciation",
- formatData: (v) => (v ? "鏄�" : "鍚�"),
- },
- {
- label: "褰曞叆浜�",
- align: "center",
- prop: "createUser",
- },
- {
- label: "褰曞叆鏃ユ湡",
- align: "center",
- prop: "createTime",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: 150,
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- edit(row.id)
- },
- },
- {
- name: "鐢熸垚浜岀淮鐮�",
- type: "text",
- clickFun: (row) => {
- showQRCode(row)
- },
- },
- ],
- },
- ]
-);
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-const add = () => {
- modalRef.value.openModal();
-};
-const edit = (id) => {
- modalRef.value.loadForm(id);
-};
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-const deleteRow = (id) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await delLedger(id);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "鍒犻櫎鎴愬姛",
- });
- getTableData();
- }
- });
-};
-
-const changeDaterange = (value) => {
- if (value) {
- filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- filters.entryDateStart = undefined;
- filters.entryDateEnd = undefined;
- }
- getTableData();
-};
-
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/device/ledger/export`, {}, "璁惧鍙拌处妗f.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-const showQRCode = async (row) => {
- // 鐩存帴浣跨敤URL锛屼笉瑕佺敤JSON.stringify鍖呰
- const qrContent = proxy.javaApi + '/device-info?deviceId=' + row.id;
- qrCodeUrl.value = await QRCode.toDataURL(qrContent);
- qrRowData.value = row;
- qrDialogVisible.value = true;
-};
-
-const downloadQRCode = () => {
- const name = qrRowData.value?.deviceName || "浜岀淮鐮�";
- const img = new Image();
- img.src = qrCodeUrl.value;
- img.onload = () => {
- const padding = 10;
- const qrSize = 200;
- const textHeight = 24; // space for text
- const width = qrSize + padding * 2;
- const height = qrSize + padding * 2 + textHeight;
- const canvas = document.createElement("canvas");
- canvas.width = width;
- canvas.height = height;
- const ctx = canvas.getContext("2d");
- // background
- ctx.fillStyle = "#ffffff";
- ctx.fillRect(0, 0, width, height);
- // draw QR centered
- ctx.drawImage(img, padding, padding, qrSize, qrSize);
- // draw name centered below
- ctx.fillStyle = "#333";
- ctx.font = "14px Arial";
- ctx.textAlign = "center";
- ctx.textBaseline = "middle";
- const maxTextWidth = width - padding * 2;
- let displayName = name;
- // ellipsis if too long
- while (ctx.measureText(displayName).width > maxTextWidth && displayName.length > 0) {
- displayName = displayName.slice(0, -1);
- }
- if (displayName !== name) displayName = displayName + "鈥�";
- ctx.fillText(displayName, width / 2, qrSize + padding + textHeight / 2);
-
- const dataUrl = canvas.toDataURL("image/png");
- const a = document.createElement("a");
- a.href = dataUrl;
- a.download = `${name}.png`;
- a.click();
- };
-};
-
-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/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
deleted file mode 100644
index 8987485..0000000
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ /dev/null
@@ -1,266 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="璁¢噺鍣ㄥ叿"
- width="50%"
- @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="customerName">
- <el-input
- v-model="form.code"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁¢噺鍣ㄥ叿鍚嶇О锛�" prop="proDesc">
- <el-input
- v-model="form.name"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="妫�瀹氭棩鏈燂細" prop="recordDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.recordDate"
- 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="valid">
- <el-input
- v-model="form.valid"
- placeholder="璇疯緭鍏�"
- clearable
- >
- <template #append>鏃�</template>
- </el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="褰曞叆浜猴細" prop="userId">
- <el-select
- v-model="form.userId"
- placeholder="璇烽�夋嫨"
- disabled
- clearable
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.entryDate"
- 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="24">-->
-<!-- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">-->
-<!-- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload-->
-<!-- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"-->
-<!-- :on-success="handleUploadSuccess" :on-remove="handleRemove">-->
-<!-- <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>-->
-<!-- <template #tip v-if="operationType !== 'view'">-->
-<!-- <div class="el-upload__tip">-->
-<!-- 鏂囦欢鏍煎紡鏀寔-->
-<!-- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
-<!-- </div>-->
-<!-- </template>-->
-<!-- </el-upload>-->
-<!-- </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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js";
-import {getToken} from "@/utils/auth.js";
-import {ledgerRecordUpdate, ledgerRecordVerifying} from "@/api/equipmentManagement/calibration.js";
-import {delLedgerFile} from "@/api/salesManagement/salesLedger.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- code: "",
- name: "",
- valid: "",
- recordDate: "",
- userId: "",
- entryDate: "",
- tempFileIds: []
- },
- rules: {
- code: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- name: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- valid: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- recordDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- userId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- entryDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- }
-})
-const { form, rules } = toRefs(data);
-const userList = ref([])
-const fileList = ref([]);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- console.log(row)
- operationType.value = type;
- dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- fileList.value = []
- if(type !== "add"){
- form.value.tempFileIds = [];
- }
- if (type === "edit") {
- form.value.valid = row.valid;
- form.value.recordDate = row.recordDate;
- fileList.value = row.commonFiles;
- }
- if(type === "add"){
- fileList.value = row.commonFiles;
- }
-
- form.value.id = row.id;
- form.value.code = row.code;
- form.value.name = row.name;
- form.value.userId = userStore.id;
- form.value.entryDate = getCurrentDate();
-}
-
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- form.value.tempFileIds.push(file.tempId);
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "verifying") {
- ledgerRecordVerifying(form.value).then(response => {
- proxy.$modal.msgSuccess("妫�瀹氭牎鍑嗘垚鍔�")
- closeDia()
- })
- } else {
- ledgerRecordUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
deleted file mode 100644
index 891316d..0000000
--- a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
+++ /dev/null
@@ -1,252 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="璁¢噺鍣ㄥ叿"
- width="50%"
- @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="code">
- <el-input
- v-model="form.code"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁¢噺鍣ㄥ叿鍚嶇О锛�" prop="name">
- <el-input
- v-model="form.name"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
- <el-input
- v-model="form.model"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰勮涓嬫妫�瀹氭棩鏈燂細" prop="nextDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.nextDate"
- 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="userId">
- <el-select
- v-model="form.userId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="recordDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.recordDate"
- 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="24">-->
-<!-- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">-->
-<!-- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload-->
-<!-- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"-->
-<!-- :on-success="handleUploadSuccess" :on-remove="handleRemove">-->
-<!-- <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>-->
-<!-- <template #tip v-if="operationType !== 'view'">-->
-<!-- <div class="el-upload__tip">-->
-<!-- 鏂囦欢鏍煎紡鏀寔-->
-<!-- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
-<!-- </div>-->
-<!-- </template>-->
-<!-- </el-upload>-->
-<!-- </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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js";
-import {getToken} from "@/utils/auth.js";
-import {measuringInstrumentAdd, measuringInstrumentUpdate} from "@/api/equipmentManagement/measurementEquipment.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const userStore = useUserStore();
-
-const data = reactive({
- form: {
- code: "",
- name: "",
- model: "",
- validDate: "",
- nextDate: "",
- userId: "",
- recordDate: "",
- tempFileIds: []
- },
- rules: {
- code: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- name: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- model: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- validDate: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
- nextDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- userId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- recordDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
- }
-})
-const { form, rules } = toRefs(data);
-const userList = ref([])
-const fileList = ref([]);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- fileList.value = []
- form.value.userId = userStore.id;
- form.value.recordDate = getCurrentDate();
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- if (type === "edit") {
- form.value = {...row}
- }
-}
-
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- form.value.tempFileIds.push(res.data.tempId)
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-
-const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "add") {
- measuringInstrumentAdd(form.value).then(response => {
- proxy.$modal.msgSuccess("鏂板鎴愬姛")
- form.value.tempFileIds = []
- closeDia()
- })
- } else {
- measuringInstrumentUpdate(form.value).then(response => {
- proxy.$modal.msgSuccess("淇敼鎴愬姛")
- form.value.tempFileIds = []
- closeDia()
- })
- }
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/filesDia.vue b/src/views/equipmentManagement/measurementEquipment/filesDia.vue
deleted file mode 100644
index f752496..0000000
--- a/src/views/equipmentManagement/measurementEquipment/filesDia.vue
+++ /dev/null
@@ -1,202 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="涓婁紶闄勪欢"
- width="50%"
- @close="closeDia"
- >
- <div style="margin-bottom: 10px;text-align: right">
- <el-upload
- v-model:file-list="fileList"
- class="upload-demo"
- :action="uploadUrl"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: inline;margin-right: 10px"
- >
- <el-button type="primary">涓婁紶闄勪欢</el-button>
- </el-upload>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- height="500"
- >
- </PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
- fileAdd,
- fileDel,
- fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
- {
- label: "鏂囦欢鍚嶇О",
- prop: "name",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "涓嬭浇",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- {
- name: "棰勮",
- type: "text",
- clickFun: (row) => {
- lookFile(row);
- },
- }
- ],
- },
-]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
- Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
- accountType.value = type;
- dialogFormVisible.value = true;
- currentId.value = row.id;
- getList()
-}
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
- tableData.value = res.data.records;
- total.value = res.data.total;
- })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
- // 濡傛灉涓婁紶鎴愬姛
- if (res.code == 200) {
- const fileRow = {}
- fileRow.name = res.data.originalName
- fileRow.url = res.data.tempPath
- uploadFile(fileRow)
- } else {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
-}
-function uploadFile(file) {
- file.accountId = currentId.value;
- file.accountType = accountType.value;
- fileAdd(file).then(res => {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- getList()
- })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-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(() => {
- fileDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
deleted file mode 100644
index e983a99..0000000
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ /dev/null
@@ -1,276 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">褰曞叆鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.recordDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 160px"
- @change="handleQuery"
- />
- <span class="search_title ml10">璁¢噺鍣ㄥ叿缂栧彿锛�</span>
- <el-input v-model="searchForm.code" placeholder="璇疯緭鍏ョ紪鍙�" clearable style="width: 240px" @change="handleQuery"/>
- <span class="search_title ml10">鐘舵�侊細</span>
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 160px" clearable>
- <el-option label="鏈夋晥" :value="1"></el-option>
- <el-option label="閫炬湡" :value="2"></el-option>
- </el-select>
- <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 type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- <el-button @click="handleOut">瀵煎嚭</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"
- ></PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- <calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
- <files-dia ref="filesDia"></files-dia>
- </div>
-</template>
-
-<script setup>
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/equipmentManagement/measurementEquipment/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import useUserStore from "@/store/modules/user.js";
-import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
-import {
- measuringInstrumentDelete,
- measuringInstrumentListPage
-} from "@/api/equipmentManagement/measurementEquipment.js";
-import FilesDia from "./filesDia.vue";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-
-const data = reactive({
- searchForm: {
- recordDate: "",
- code: "",
- status: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
- {
- label: "鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- if (params == 1) {
- return "鏈夋晥";
- } else if (params == 2) {
- return "閫炬湡";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- if (params == 1) {
- return "success";
- } else if (params == 2) {
- return "danger";
- } else {
- return null;
- }
- },
- },
- {
- label: "鏈�杩戜竴娆℃瀹氭棩鏈�",
- prop: "mostDate",
- width: 130,
- },
- {
- label: "璁¢噺鍣ㄥ叿缂栧彿",
- prop: "code",
- width: 150,
- },
- {
- label: "璁¢噺鍣ㄥ叿鍚嶇О",
- prop: "name",
- width: 200,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "model",
- width:200
- },
- {
- label: "鏈夋晥鏈�",
- prop: "valid",
- width: 130,
- },
- {
- label: "棰勮涓嬫妫�瀹氭棩鏈�",
- prop: "nextDate",
- width: 130,
- },
- {
- label: "褰曞叆浜�",
- prop: "userName",
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "recordDate",
- width: 130,
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- width: '130',
- fixed: 'right',
- operation: [
- {
- name: "妫�瀹氭牎鍑�",
- type: "text",
- clickFun: (row) => {
- openCalibrationDia("verifying", row);
- },
- },
- {
- name: "闄勪欢",
- type: "text",
- clickFun: (row) => {
- openFilesFormDia(row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const filesDia = ref()
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const selectedRows = ref([]);
-
-// 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
- console.log(row)
- nextTick(() => {
- filesDia.value?.openDialog( row,'璁¢噺鍣ㄥ叿鍙拌处')
- })
-};
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const formDia = ref()
-const calibrationDia = ref()
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- measuringInstrumentListPage({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- }).catch((err) => {
- tableLoading.value = false;
- })
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-// 鎵撳紑妫�瀹氭牎鍑嗗脊妗�
-const openCalibrationDia = (type, row) => {
- nextTick(() => {
- calibrationDia.value?.openDialog(type, row)
- })
-}
-
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.userId !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- measuringInstrumentDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/measuringInstrumentLedger/export", {}, "璁¢噺鍣ㄥ叿鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/operationManagement/index.vue b/src/views/equipmentManagement/operationManagement/index.vue
deleted file mode 100644
index 008cc2c..0000000
--- a/src/views/equipmentManagement/operationManagement/index.vue
+++ /dev/null
@@ -1,370 +0,0 @@
-<template>
- <div class="app-container">
-
- <!-- 绛涢�夋潯浠� -->
- <div class="filter-section">
- <el-select v-model="deviceFilter" placeholder="璁惧鐘舵�佺瓫閫�" clearable style="width: 200px; margin-right: 10px;">
- <el-option label="鍏ㄩ儴" value="all" />
- <el-option label="杩愯涓�" value="start" />
- <el-option label="鍋滄杩愯" value="stop" />
- </el-select>
- </div>
-
- <!-- 璁惧鍚仠璁板綍琛ㄦ牸 -->
- <el-card class="table-card">
- <template #header>
- <span>璁惧杩愯璁板綍</span>
- </template>
- <el-table
- :data="filteredDeviceRecords"
- style="width: 100%"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- :row-class-name="getRowClassName"
- v-loading="loading"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column
- label="璁惧鍚嶇О"
- prop="deviceName"
- show-overflow-tooltip
- />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="deviceModel"
- show-overflow-tooltip
- />
- <el-table-column
- label="璁惧鐘舵��"
- prop="status"
- width="150"
- align="center"
- >
- <template #default="scope">
- <!-- 瓒呮椂鏈惎鍔ㄦ椂鏄剧ず璀﹀憡 -->
- <el-tag
- v-if="isOverdue(scope.row)"
- type="warning"
- size="small"
- effect="dark"
- >
- <el-icon><Warning /></el-icon>
- 瓒呮椂鏈惎鍔�
- </el-tag>
- <!-- 姝e父鐘舵�佹椂鏄剧ず璁惧鐘舵�� -->
- <el-tag
- v-else
- :type="getDeviceStatusType(scope.row.status)"
- size="small"
- >
- <el-icon v-if="scope.row.status === '杩愯涓�'"><VideoPlay /></el-icon>
- <el-icon v-else><VideoPause /></el-icon>
- {{ scope.row.status || '鏈煡' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="璁″垝杩愯鏃堕棿"
- prop="planRuntimeTime"
- width="150"
- align="center"
- >
- <template #default="scope">
- {{ scope.row.planRuntimeTime || '-' }}
- </template>
- </el-table-column>
- <el-table-column
- label="寮�濮嬭繍琛屾椂闂�"
- prop="startRuntimeTime"
- width="180"
- align="center"
- >
- <template #default="scope">
- {{ scope.row.startRuntimeTime || '-' }}
- </template>
- </el-table-column>
- <el-table-column
- label="缁撴潫杩愯鏃堕棿"
- prop="endRuntimeTime"
- width="180"
- align="center"
- >
- <template #default="scope">
- {{ scope.row.endRuntimeTime || '-' }}
- </template>
- </el-table-column>
- <el-table-column
- label="杩愯鏃堕暱"
- prop="runtimeDuration"
- width="120"
- align="center"
- >
- <template #default="scope">
- {{ scope.row.runtimeDuration || '-' }}
- </template>
- </el-table-column>
- <el-table-column
- label="鎿嶄綔"
- width="120"
- align="center"
- >
- <template #default="scope">
- <!-- 瓒呮椂鏈惎鍔ㄦ椂鏄剧ず鍚姩鎸夐挳 -->
- <el-button
- v-if="isOverdue(scope.row)"
- type="warning"
- size="small"
- @click="changeDeviceStatus(scope.row, '鍚姩杩愯')"
- >
- <el-icon><VideoPlay /></el-icon>
- 绔嬪嵆鍚姩
- </el-button>
- <!-- 姝e父鐘舵�佹椂鏄剧ず瀵瑰簲鐨勬搷浣滄寜閽� -->
- <template v-else>
- <el-button
- v-if="scope.row.status === '杩愯涓�'"
- type="danger"
- size="small"
- @click="changeDeviceStatus(scope.row, '鍋滄杩愯')"
- >
- <el-icon><VideoPause /></el-icon>
- 鍋滄杩愯
- </el-button>
- <el-button
- v-else
- type="success"
- size="small"
- @click="changeDeviceStatus(scope.row, '鍚姩杩愯')"
- >
- <el-icon><VideoPlay /></el-icon>
- 鍚姩杩愯
- </el-button>
- </template>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
-
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, computed } from 'vue'
-import { ElMessage } from 'element-plus'
-import {
- VideoPlay,
- VideoPause,
- Warning
-} from '@element-plus/icons-vue'
-import {editLedger, getLedgerPage} from "@/api/equipmentManagement/ledger.js";
-
-// 鍝嶅簲寮忔暟鎹�
-const deviceFilter = ref('all')
-const loading = ref(false)
-const total = ref(0)
-const queryParams = ref({
- current: -1,
- size: -1
-})
-
-// 绉婚櫎姒傝鏁版嵁锛屽洜涓虹幇鍦ㄤ娇鐢ㄨ〃鏍煎睍绀�
-
-// 璁惧鍚仠璁板綍鏁版嵁
-const deviceRecords = ref([])
-const allDeviceRecords = ref([]) // 瀛樺偍鎵�鏈夊師濮嬫暟鎹�
-
-// 鏍规嵁绛涢�夋潯浠惰繃婊ゆ暟鎹�
-const filteredDeviceRecords = computed(() => {
- let filtered = allDeviceRecords.value
-
- // 鏍规嵁璁惧鐘舵�佺瓫閫�
- if (deviceFilter.value !== 'all') {
- if (deviceFilter.value === 'start') {
- filtered = filtered.filter(device => device.status === '杩愯涓�')
- } else if (deviceFilter.value === 'stop') {
- filtered = filtered.filter(device => device.status === '鍋滄杩愯')
- }
- }
-
- return filtered
-})
-
-// 妫�鏌ヨ澶囨槸鍚﹁秴鏃舵湭鍚姩
-const isOverdue = (device) => {
- if (!device.planRuntimeTime || device.status === '杩愯涓�' || device.startRuntimeTime) {
- return false
- }
-
- const planTime = new Date(device.planRuntimeTime)
- const currentTime = new Date()
-
- return currentTime > planTime
-}
-
-// 鏂规硶
-const getList = async () => {
- loading.value = true
- try {
- const response = await getLedgerPage(queryParams.value)
- if (response.code === 200) {
- allDeviceRecords.value = response.data.records || []
- total.value = response.data.total || 0
- }
- } catch (error) {
- console.error('鑾峰彇璁惧鍒楄〃澶辫触:', error)
- ElMessage.error('鑾峰彇璁惧鍒楄〃澶辫触')
- } finally {
- loading.value = false
- }
-}
-
-const changeDeviceStatus = async (device, status) => {
- try {
- const currentTime = new Date().toLocaleString('zh-CN', {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false
- }).replace(/\//g, '-')
-
- // 鏇存柊璁惧鐘舵�佸拰鐩稿叧鏃堕棿瀛楁
- if (status === '鍚姩杩愯') {
- device.status = '杩愯涓�'
- device.startRuntimeTime = currentTime
- device.endRuntimeTime = null // 娓呯┖缁撴潫鏃堕棿
- device.runtimeDuration = null // 娓呯┖杩愯鏃堕暱
- } else {
- device.status = '鍋滄杩愯'
- device.endRuntimeTime = currentTime
- // 璁$畻杩愯鏃堕暱
- if (device.startRuntimeTime) {
- const startTime = new Date(device.startRuntimeTime)
- const endTime = new Date(currentTime)
- const duration = endTime - startTime
- const hours = Math.floor(duration / (1000 * 60 * 60))
- const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60))
- device.runtimeDuration = `${hours}灏忔椂${minutes}鍒嗛挓`
- }
- }
- const params = {
- id: device.id,
- status: device.status,
- planRuntimeTime: device.planRuntimeTime,
- startRuntimeTime: device.startRuntimeTime,
- endRuntimeTime: device.endRuntimeTime,
- runtimeDuration: device.runtimeDuration,
- }
- // 璋冪敤API鏇存柊璁惧鐘舵��
- const response = await editLedger(params)
- if (response.code === 200) {
- ElMessage.success(`${device.deviceName} ${status}鎴愬姛`)
- // 鍒锋柊鍒楄〃
- await getList()
- } else {
- ElMessage.error(response.msg || '鎿嶄綔澶辫触')
- }
- } catch (error) {
- console.error('鏇存柊璁惧鐘舵�佸け璐�:', error)
- ElMessage.error('鎿嶄綔澶辫触')
- }
-}
-
-const getDeviceStatusType = (status) => {
- if (status === '杩愯涓�') {
- return 'success'
- } else if (status === '鍋滄杩愯') {
- return 'danger'
- } else {
- return 'info'
- }
-}
-
-// 鑾峰彇琛ㄦ牸琛岀殑绫诲悕
-const getRowClassName = ({ row }) => {
- if (isOverdue(row)) {
- return 'overdue-row'
- }
- return ''
-}
-
-
-
-// 缁勪欢鎸傝浇鏃跺垵濮嬪寲鏁版嵁
-onMounted(() => {
- getList()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
- background: #f5f7fa;
- min-height: 100vh;
-}
-
-
-.filter-section {
- margin-bottom: 20px;
- padding: 15px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- display: flex;
- justify-content: flex-start;
-}
-
-.table-card {
- margin-bottom: 20px;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-}
-
-:deep(.el-card__header) {
- background: #f8f9fa;
- border-bottom: 1px solid #e9ecef;
- font-weight: 500;
- font-size: 16px;
-}
-
-:deep(.el-table .el-table__header-wrapper th) {
- background-color: #F0F1F5 !important;
- color: #333333;
- font-weight: 600;
-}
-
-:deep(.el-table .el-table__body-wrapper td) {
- padding: 12px 0;
-}
-
-:deep(.el-select) {
- width: 100%;
-}
-
-:deep(.el-tag) {
- display: inline-flex;
- align-items: center;
- gap: 4px;
-}
-
-/* 瓒呮椂鏈惎鍔ㄨ鐨勬牱寮� */
-:deep(.overdue-row) {
- background-color: #fef0f0 !important;
- border-left: 4px solid #f56c6c;
-}
-
-:deep(.overdue-row:hover) {
- background-color: #fde2e2 !important;
-}
-
-:deep(.overdue-row td) {
- background-color: transparent !important;
-}
-</style>
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
deleted file mode 100644
index bbb25c1..0000000
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<template>
- <el-form :model="form" label-width="80px">
- <el-form-item label="缁翠慨浜�">
- <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
- </el-form-item>
- <el-form-item label="缁翠慨缁撴灉">
- <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
- </el-form-item>
- <el-form-item label="缁翠慨鏃ユ湡">
- <el-date-picker
- v-model="form.maintenanceTime"
- placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="datetime"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
- name: "璁惧缁翠慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
- maintenanceName: undefined, // 缁翠慨鍚嶇О
- maintenanceResult: undefined, // 缁翠慨缁撴灉
- maintenanceTime: undefined, // 缁翠慨鏃ユ湡
-});
-
-const setForm = (data) => {
- form.maintenanceName = data.maintenanceName ?? userStore.nickName;
- form.maintenanceResult = data.maintenanceResult;
- form.maintenanceTime =
- dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") ??
- dayjs().format("YYYY-MM-DD HH:mm:ss");
-};
-
-const getForm = () => {
- return form;
-};
-
-defineExpose({
- getForm,
- setForm,
- resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Form/RepairForm.vue b/src/views/equipmentManagement/repair/Form/RepairForm.vue
deleted file mode 100644
index 1fadde4..0000000
--- a/src/views/equipmentManagement/repair/Form/RepairForm.vue
+++ /dev/null
@@ -1,113 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-row>
- <el-col :span="12">
- <el-form-item label="璁惧鍚嶇О">
- <el-select v-model="form.deviceLedgerId" @change="setDeviceModel">
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎶ヤ慨鏃ユ湡">
- <el-date-picker
- v-model="form.repairTime"
- placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎶ヤ慨浜�">
- <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="鏁呴殰鐜拌薄">
- <el-input
- v-model="form.remark"
- :rows="2"
- type="textarea"
- placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
- name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const deviceOptions = ref([]);
-
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-const { form, resetForm } = useFormData({
- deviceLedgerId: undefined, // 璁惧Id
- deviceName: undefined, // 璁惧鍚嶇О
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- repairTime: undefined, // 鎶ヤ慨鏃ユ湡
- repairName: userStore.nickName, // 鎶ヤ慨浜�
- remark: undefined, // 鏁呴殰鐜拌薄
-});
-
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
- return form;
-};
-
-const setForm = (data) => {
- form.deviceLedgerId = data.deviceLedgerId;
- form.deviceName = data.deviceName;
- form.deviceModel = data.deviceModel;
- form.repairTime = data.repairTime;
- form.repairName = data.repairName;
- form.remark = data.remark;
-};
-
-// onMounted(() => {
-// loadDeviceName();
-// });
-
-defineExpose({
- loadDeviceName,
- resetForm,
- getForm,
- setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
deleted file mode 100644
index 309be0e..0000000
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<template>
- <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr">
- <MaintainForm ref="maintainFormRef" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import MaintainForm from "../Form/MaintainForm.vue";
-import { addMaintain } from "@/api/equipmentManagement/repair";
-
-defineOptions({
- name: "缁翠慨妯℃�佹",
-});
-
-const maintainFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧缁翠慨" });
-
-const sendForm = async () => {
- loading.value = true;
- const form = await maintainFormRef.value.getForm();
- const { code } = await addMaintain({ id: id.value, ...form });
- if (code == 200) {
- emits("ok");
- maintainFormRef.value.resetForm();
- closeModal();
- }
- loading.value = false;
-};
-
-const open = async (id, row) => {
- openModal(id);
- await nextTick();
- maintainFormRef.value.setForm(row);
-};
-
-defineExpose({
- open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
deleted file mode 100644
index 8441da2..0000000
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
- <el-dialog v-model="visible" :title="modalOptions.title" @close="close">
- <RepairForm ref="repairFormRef" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import RepairForm from "../Form/RepairForm.vue";
-import {
- addRepair,
- editRepair,
- getRepairById,
-} from "@/api/equipmentManagement/repair";
-import { ElMessage } from "element-plus";
-
-defineOptions({
- name: "璁惧鎶ヤ慨寮圭獥",
-});
-
-const emits = defineEmits(["ok"]);
-
-const repairFormRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧鎶ヤ慨" });
-
-const sendForm = async () => {
- loading.value = true;
- const form = await repairFormRef.value.getForm();
- const { code } = id.value
- ? await editRepair({ id: unref(id), ...form })
- : await addRepair(form);
- if (code == 200) {
- ElMessage.success(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
- closeModal();
- emits("ok");
- }
- loading.value = false;
-};
-
-const openAdd = async () => {
- openModal();
- await nextTick();
- await repairFormRef.value.loadDeviceName();
-};
-
-const openEdit = async (id) => {
- const { data } = await getRepairById(id);
- openModal(id);
- await nextTick();
- await repairFormRef.value.loadDeviceName();
- await repairFormRef.value.setForm(data);
-};
-
-const close = () => {
- repairFormRef.value.resetForm();
- closeModal();
-};
-
-defineExpose({
- openAdd,
- openEdit,
-});
-</script>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
deleted file mode 100644
index 1a2ff1e..0000000
--- a/src/views/equipmentManagement/repair/index.vue
+++ /dev/null
@@ -1,326 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="璁惧鍚嶇О">
- <el-input
- v-model="filters.deviceName"
- style="width: 240px"
- placeholder="璇疯緭鍏ヨ澶囧悕绉�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="filters.deviceModel"
- style="width: 240px"
- placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="鏁呴殰鐜拌薄">
- <el-input
- v-model="filters.remark"
- style="width: 240px"
- placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="缁翠慨浜�">
- <el-input
- v-model="filters.maintenanceName"
- style="width: 240px"
- placeholder="璇疯緭鍏ョ淮淇汉"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="鎶ヤ慨鏃ユ湡">
- <el-date-picker
- v-model="filters.repairTimeStr"
- type="date"
- placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,2)"
- />
- </el-form-item>
- <el-form-item label="缁翠慨鏃ユ湡">
- <el-date-picker
- v-model="filters.maintenanceTimeStr"
- type="date"
- placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,1)"
- />
- </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">
- <el-text class="mx-1" size="large">璁惧鎶ヤ慨</el-text>
- <div>
- <el-button
- type="primary"
- icon="Plus"
- :disabled="multipleList.length !== 1"
- @click="addMaintain"
- >
- 鏂板缁翠慨
- </el-button>
- <el-button type="success" icon="Van" @click="addRepair">
- 鏂板鎶ヤ慨
- </el-button>
- <el-button @click="handleOut">
- 瀵煎嚭
- </el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="delRepairByIds(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #statusRef="{ row }">
- <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
- <el-tag v-if="row.status === 0" type="danger">寰呯淮淇�</el-tag>
- </template>
- <template #operation="{ row }">
- <el-button
- type="primary"
- text
- icon="editPen"
- @click="editRepair(row.id)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="danger"
- text
- icon="delete"
- @click="delRepairByIds(row.id)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </PIMTable>
- </div>
- <RepairModal ref="repairModalRef" @ok="getTableData" />
- <MaintainModal ref="maintainModalRef" @ok="getTableData" />
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
-import { onMounted, getCurrentInstance } from "vue";
-import RepairModal from "./Modal/RepairModal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import dayjs from "dayjs";
-import MaintainModal from "./Modal/MaintainModal.vue";
-
-defineOptions({
- name: "璁惧鎶ヤ慨",
-});
-
-const { proxy } = getCurrentInstance();
-
-// 妯℃�佹瀹炰緥
-const repairModalRef = ref();
-const maintainModalRef = ref();
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-
-// 琛ㄦ牸閽╁瓙
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- getRepairPage,
- {
- deviceName: undefined,
- deviceModel: undefined,
- remark: undefined,
- maintenanceName: undefined,
- repairTimeStr: undefined,
- maintenanceTimeStr: undefined,
- },
- [
- {
- label: "璁惧鍚嶇О",
- align: "center",
- prop: "deviceName",
- },
- {
- label: "瑙勬牸鍨嬪彿",
- align: "center",
- prop: "deviceModel",
- },
- {
- label: "鎶ヤ慨鏃ユ湡",
- align: "center",
- prop: "repairTime",
- formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
- },
- {
- label: "鎶ヤ慨浜�",
- align: "center",
- prop: "repairName",
- },
- {
- label: "鏁呴殰鐜拌薄",
- align: "center",
- prop: "remark",
- },
- {
- label: "缁翠慨浜�",
- align: "center",
- prop: "maintenanceName",
- },
- {
- label: "缁翠慨缁撴灉",
- align: "center",
- prop: "maintenanceResult",
- },
- {
- label: "缁翠慨鏃ユ湡",
- align: "center",
- prop: "maintenanceTime",
- formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
- },
- {
- label: "鐘舵��",
- align: "center",
- prop: "status",
- dataType: "slot",
- slot: "statusRef",
- },
- {
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "200px",
- },
- ]
-);
-
-// type === 1 缁翠慨 2鎶ヤ慨闂�
-const handleDateChange = (value,type) => {
- filters.maintenanceTimeStr = null
- filters.c = null
- if(type === 1){
- if (value) {
- filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD");
- }
- }else{
- if (value) {
- filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD");
- }
- }
- getTableData();
-};
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-// 鏂板鎶ヤ慨
-const addRepair = () => {
- repairModalRef.value.openAdd();
-};
-
-// 缂栬緫鎶ヤ慨
-const editRepair = (id) => {
- repairModalRef.value.openEdit(id);
-};
-
-// 鏂板缁翠慨
-const addMaintain = () => {
- const row = multipleList.value[0];
- maintainModalRef.value.open(row.id, row);
-};
-
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-
-// 鍗曡鍒犻櫎
-const delRepairByIds = async (ids) => {
- ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await delRepair(ids);
- if (code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- getTableData();
- }
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/device/repair/export", {}, "璁惧鎶ヤ慨.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-
-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/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
deleted file mode 100644
index f91d76f..0000000
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ /dev/null
@@ -1,417 +0,0 @@
-<template>
- <div class="spare-part-category">
- <div class="table_list">
- <div class="actions">
- <el-text class="mx-1" size="large">璁惧鍒嗙被</el-text>
- <div>
- <el-button @click="fetchTreeData" :loading="loading">鍒锋柊</el-button>
- <el-button type="primary" @click="addCategory" >鏂板</el-button>
- </div>
- </div>
- <el-table
- v-loading="loading"
- :data="renderTableData"
- style="width: 100%; margin-top: 10px;"
- border
- row-key="id"
- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
- >
- <el-table-column prop="name" label="鍒嗙被鍚嶇О" width="450">
- <template #default="{ row }">
- <span :style="{ paddingLeft: getIndentation(row) + 'px' }">
- {{ row.name }}
- </span>
- </template>
- </el-table-column>
- <el-table-column prop="sparePartsNo" label="鍒嗙被缂栧彿" width="200"></el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="{ row }">
- <el-tag type="success" size="small">{{ row.status }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="description" label="鎻忚堪" win-width="330"></el-table-column>
- <el-table-column label="鎿嶄綔" width="180" fixed="right">
- <template #default="{ row }">
- <el-button
- type="text"
- size="small"
- @click="() => editCategory(row)"
- :disabled="loading"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="text"
- size="small"
- @click="() => deleteCategory(row.id)"
- style="color: #f56c6c;"
- :disabled="loading"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <el-dialog title="鍒嗙被绠$悊" v-model="dialogVisible" width="60%">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-form-item label="鍒嗙被鍚嶇О" prop="name">
- <el-input v-model="form.name"></el-input>
- </el-form-item>
- <el-form-item label="鍒嗙被缂栧彿" prop="sparePartsNo">
- <el-input v-model="form.sparePartsNo"></el-input>
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="姝e父" value="姝e父"></el-option>
- <el-option label="绂佺敤" value="绂佺敤"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="鎻忚堪" prop="description">
- <el-input v-model="form.description"></el-input>
- </el-form-item>
- <el-form-item label="涓婄骇鍒嗙被" prop="parentId">
- <el-select v-model="form.parentId" placeholder="璇烽�夋嫨涓婄骇鍒嗙被">
- <el-option label="鏃犱笂绾у垎绫�" :value="null"></el-option>
- <el-option
- v-for="(item, index) in categories"
- :key="index"
- :label="item.name"
- :value="item.id"
-
- ></el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false" :disabled="formLoading">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, computed, onMounted, reactive, watch } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { getSparePartsList, addSparePart, editSparePart, delSparePart,getSparePartsTree } from "@/api/equipmentManagement/spareParts";
-
-// 鍔犺浇鐘舵��
-const loading = ref(false);
-const formLoading = ref(false);
-// 瀵硅瘽妗嗘樉绀虹姸鎬�
-const dialogVisible = ref(false);
-// 缂栬緫 ID
-const editId = ref(null);
-// 琛ㄦ牸鏁版嵁
-const categories = ref([]);
-// 娓叉煋鐢ㄧ殑琛ㄦ牸鏁版嵁
-// const renderTableData = computed(() => buildTree(categories.value));
-const renderTableData = ref([]);
-const operationType = ref('add')
-// 琛ㄥ崟寮曠敤
-const formRef = ref(null);
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
- id:'',
- name: '',
- sparePartsNo: '',
- status: '',
- description: '',
- parentId: null
-});
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = reactive({
- name: [
- { required: true, message: '璇疯緭鍏ュ垎绫诲悕绉�', trigger: 'blur' }
- ],
- sparePartsNo: [
- { required: true, message: '璇疯緭鍏ュ垎绫荤紪鍙�', trigger: 'blur' }
- ],
- status: [
- { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
- ]
-});
-// 鑾峰彇缂╄繘閲�
-const getIndentation = (row) => {
- // 杩欓噷绠�鍗曡繑鍥� 20锛屽彲鏍规嵁瀹為檯闇�姹傚疄鐜板眰绾х缉杩涢�昏緫
- return 20;
-};
-// 瀹氫箟 buildTree 鍑芥暟
-const buildTree = (flatData) => {
- const map = {};
- const result = [];
- if(flatData){
- return result;
- }
- flatData.forEach(item => {
- map[item.id] = { ...item, children: [] };
- });
- flatData.forEach(item => {
- if (item.parentId === null || !map[item.parentId]) {
- result.push(map[item.id]);
- } else {
- map[item.parentId].children.push(map[item.id]);
- }
- });
- return result;
-};
-//鑾峰彇鏍戝舰缁撴瀯
-const fetchTreeData = async () => {
- fetchCategories();
- try {
- const res = await getSparePartsTree();
- if (res.code === 200) {
- renderTableData.value = res.data;
- } else {
- ElMessage.error(res.message || '鑾峰彇鍒嗙被鍒楄〃澶辫触');
- }
- }catch (error) {
- ElMessage.error('鑾峰彇鍒嗙被鍒楄〃澶辫触');
- }
-}
-
-// 鑾峰彇鍒嗙被鍒楄〃
-const fetchCategories = async () => {
- loading.value = true;
- try {
- const res = await getSparePartsList();
- if (res.code === 200) {
- categories.value = res.data.records;
- } else {
- ElMessage.error(res.message || '鑾峰彇鍒嗙被鍒楄〃澶辫触');
- }
- } catch (error) {
- ElMessage.error('鑾峰彇鍒嗙被鍒楄〃澶辫触');
- } finally {
- loading.value = false;
- }
-};
-
-// 鏂板鍒嗙被
-const addCategory = () => {
- form.id = '';
- form.name = '';
- form.sparePartsNo = '';
- form.status = '';
- form.description = '';
- form.parentId = null;
- operationType.value = 'add'
- dialogVisible.value = true;
- console.log('dialogVisible 鏇存柊涓�', dialogVisible.value);
-};
-
-// 缂栬緫鍒嗙被
-const editCategory = (row) => {
- Object.assign(form, row);
- operationType.value = 'edit'
- dialogVisible.value = true;
-};
-
-// 鍒犻櫎鍒嗙被
-const deleteCategory = async (id) => {
- try {
- await ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ垎绫伙紝鏄惁缁х画?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- });
- loading.value = true;
- const res = await delSparePart(id);
- if (res.code === 200) {
- ElMessage.success('鍒犻櫎鎴愬姛');
- fetchTreeData();
- } else {
- ElMessage.error(res.message || '鍒犻櫎澶辫触');
- }
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('鍒犻櫎澶辫触');
- }
- } finally {
- loading.value = false;
- }
-};
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- if (!formRef.value) return;
- try {
- await formRef.value.validate();
- formLoading.value = true;
- if (operationType.value === 'edit') {
- let res = await editSparePart(form);
- if (res.code === 200) {
- ElMessage.success('缂栬緫鎴愬姛');
- dialogVisible.value = false;
- fetchTreeData();
- }
- } else {
- let res = await addSparePart(form);
- if (res.code === 200) {
- ElMessage.success('缂栬緫鎴愬姛');
- dialogVisible.value = false;
- fetchTreeData();
- }
- }
- } catch (error) {
- ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�');
- } finally {
- formLoading.value = false;
- }
-};
-
-// 缁勪欢鎸傝浇鏃惰幏鍙栧垎绫诲垪琛�
-onMounted(() => {
- fetchCategories();
- fetchTreeData();
-});
-</script>
-
-<style scoped>
-.spare-part-category {
- padding: 20px;
-}
-.table_list {
- margin-top: unset;
-}
-.actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- align-items: center;
-}
-
-/* 宓屽鏍戝舰缁撴瀯鏍峰紡 */
-.nested-tree-node {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- padding: 0 4px;
- height: 30px;
- line-height: 30px;
-}
-
-.category-code {
- color: #606266;
- font-size: 12px;
- margin-left: 8px;
-}
-
-.tree-actions {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-left: auto;
-}
-
-/* 琛ㄦ牸鏍峰紡璋冩暣 */
-.el-table {
- font-size: 14px;
-}
-
-.el-table__header-wrapper th {
- background-color: #f5f7fa;
- font-weight: 600;
-}
-
-.el-table__row:hover > td {
- background-color: #fafafa;
-}
-
-/* 宓屽鏍戝舰缁撴瀯鐗瑰畾鏍峰紡 */
-.nested-tree {
- background-color: transparent;
-}
-
-.nested-tree .el-tree-node__content {
- height: auto;
- background-color: transparent;
-}
-
-/* 鎼滅储妗嗘牱寮忚皟鏁� */
-.actions .el-input {
- margin-right: 10px;
- width: 200px;
-}
-
-/* 鎸夐挳缁勬牱寮� */
-.actions > div {
- display: flex;
- gap: 10px;
-}
-
-/* 纭繚琛ㄦ牸涓殑鎿嶄綔鎸夐挳涓嶄細琚埅鏂� */
-.el-table-column--fixed-right .el-button {
- margin: 0 2px;
-}
-
-/* 鏍戝舰鑺傜偣鍐呭鏍峰紡 */
-.nested-tree .el-tree-node__expand-icon {
- font-size: 12px;
- margin-right: 4px;
-}
-
-/* 绌虹姸鎬佹牱寮� */
-.el-table .cell:empty::before {
- content: '-';
- color: #c0c4cc;
-}
-
-/* 灞曞紑/鎶樺彔鍔熻兘鏍峰紡 */
-.expand-icon {
- display: inline-block;
- width: 20px;
- height: 20px;
- text-align: center;
- line-height: 20px;
- cursor: pointer;
- font-size: 12px;
- color: #909399;
-}
-
-.expand-icon.expanded {
- color: #409eff;
-}
-
-/* 灞曞紑鍐呭鏍峰紡 */
-.expand-content {
- padding: 10px 20px;
-}
-
-/* 瀛愮骇鍐呭鏍峰紡 */
-.child-content {
- padding-left: 40px;
-}
-
-/* 鏃犲瓙鍒嗙被鎻愮ず鏍峰紡 */
-.no-children {
- padding: 10px 20px;
- color: #909399;
- font-size: 14px;
-}
-
-/* 纭繚灞曞紑鐨勮〃鏍兼牱寮忔纭� */
-.el-table .el-table__expanded-cell {
- background-color: #fafafa;
-}
-
-/* 灞曞紑鐨勫瓙琛ㄦ牸鏍峰紡 */
-.el-table .el-table {
- border-top: none;
- border-bottom: none;
-}
-
-/* 灞曞紑鐨勫瓙琛ㄦ牸鍗曞厓鏍兼牱寮� */
-.expand-content .el-table__body-wrapper .el-table__row {
- background-color: #ffffff;
-}
-
-.expand-content .el-table__body-wrapper .el-table__row:hover > td {
- background-color: #fafafa;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
deleted file mode 100644
index bc3db70..0000000
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-form-item label="瀹為檯淇濆吇浜�">
- <el-input
- v-model="form.maintenanceActuallyName"
- placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
- ></el-input>
- </el-form-item>
- <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
- <el-date-picker
- v-model="form.maintenanceActuallyTime"
- placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="datetime"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="淇濆吇缁撴灉">
- <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
- <el-option label="瀹屽ソ" :value="1"></el-option>
- <el-option label="缁翠慨" :value="0"></el-option>
- </el-select>
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
- name: "淇濆吇琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
- maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
- maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
- maintenanceResult: undefined, // 淇濆吇缁撴灉
-});
-
-const setForm = (data) => {
- form.maintenanceActuallyName =
- data.maintenanceActuallyName ?? userStore.nickName;
- form.maintenanceActuallyTime =
- dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") ??
- dayjs().format("YYYY-MM-DD HH:mm:ss");
- form.maintenanceResult = data.maintenanceResult;
-};
-
-const getForm = () => {
- return form;
-};
-
-defineExpose({
- getForm,
- setForm,
- resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
deleted file mode 100644
index 1d94b68..0000000
--- a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
+++ /dev/null
@@ -1,97 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px">
- <el-form-item label="璁惧鍚嶇О">
- <el-select
- v-model="form.deviceLedgerId"
- @change="setDeviceModel"
- placeholder="璇烽�夋嫨璁惧"
- >
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- disabled
- />
- </el-form-item>
- <el-form-item label="璁″垝淇濆吇鏃ユ湡">
- <el-date-picker
- style="width: 100%"
- v-model="form.maintenancePlanTime"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD HH:mm:ss"
- type="date"
- placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
- clearable
- />
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-
-defineOptions({
- name: "璁″垝琛ㄥ崟",
-});
-
-const deviceOptions = ref([]);
-const loadDeviceName = async () => {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data;
-};
-
-const { form, resetForm } = useFormData({
- deviceLedgerId: undefined, // 璁惧Id
- deviceName: undefined, // 璁惧鍚嶇О
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
-});
-
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
- return form;
-};
-
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
-const setForm = (data) => {
- form.deviceLedgerId = data.deviceLedgerId;
- form.deviceName = data.deviceName;
- form.deviceModel = data.deviceModel;
- form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
- "YYYY-MM-DD HH:mm:ss"
- );
-};
-
-const loadForm = () => {};
-
-onMounted(() => {
- loadDeviceName();
-});
-
-defineExpose({
- loadForm,
- resetForm,
- getForm,
- setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
deleted file mode 100644
index 0afd512..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
- <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr">
- <MaintenanceForm ref="maintenanceFormRef" />
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import MaintenanceForm from "../Form/MaintenanceForm.vue";
-import { useModal } from "@/hooks/useModal";
-import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-
-defineOptions({
- name: "淇濆吇妯℃�佹",
-});
-
-const maintenanceFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧淇濆吇" });
-
-/**
- * @desc 淇濆瓨淇濆吇
- */
-const sendForm = async () => {
- loading.value = true;
- const form = await maintenanceFormRef.value.getForm();
- const { code } = await addMaintenance({ id: id.value, ...form });
- if (code == 200) {
- emits("ok");
- maintenanceFormRef.value.resetForm();
- closeModal();
- }
- loading.value = false;
-};
-
-const open = async (id, row) => {
- openModal(id);
- await nextTick();
- maintenanceFormRef.value.setForm(row);
-};
-defineExpose({
- open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
deleted file mode 100644
index d9cf246..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-<template>
- <el-dialog
- v-model="visible"
- :title="modalOptions.title"
- width="30%"
- @close="close"
- >
- <PlanForm ref="planFormRef"></PlanForm>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import PlanForm from "../Form/PlanForm";
-import {
- addUpkeep,
- editUpkeep,
- getUpkeepById,
-} from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-
-defineOptions({
- name: "璁惧淇濆吇鏂板璁″垝",
-});
-
-const emits = defineEmits(["ok"]);
-const planFormRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "璁惧淇濆吇璁″垝" });
-
-const openEdit = async (id) => {
- const { data } = await getUpkeepById(id);
- openModal(id);
- await nextTick();
- await planFormRef.value.setForm(data);
-};
-
-const sendForm = async () => {
- loading.value = true;
- const form = await planFormRef.value.getForm();
- const { code } = id.value
- ? await editUpkeep({ id: unref(id), ...form })
- : await addUpkeep(form);
- if (code == 200) {
- ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
- closeModal();
- emits("ok");
- }
- loading.value = false;
-};
-
-const close = () => {
- planFormRef.value.resetForm();
- closeModal();
-};
-
-defineExpose({
- openModal,
- openEdit,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
deleted file mode 100644
index 5612bb6..0000000
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ /dev/null
@@ -1,313 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="璁惧鍚嶇О">
- <el-input
- v-model="filters.deviceName"
- style="width: 240px"
- placeholder="璇疯緭鍏ヨ澶囧悕绉�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="璁″垝淇濆吇鏃ユ湡">
- <el-date-picker
- v-model="filters.maintenancePlanTime"
- type="date"
- placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,2)"
- />
- </el-form-item>
- <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
- <el-date-picker
- v-model="filters.maintenanceActuallyTime"
- type="date"
- placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
- size="default"
- @change="(date) => handleDateChange(date,1)"
- />
- </el-form-item>
- <el-form-item label="瀹為檯淇濆吇浜�">
- <el-input
- v-model="filters.maintenanceActuallyName"
- 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">
- <el-text class="mx-1" size="large">璁惧淇濆吇</el-text>
- <div>
- <el-button
- type="primary"
- icon="Plus"
- :disabled="multipleList.length !== 1"
- @click="addMaintain"
- >
- 鏂板淇濆吇
- </el-button>
- <el-button type="success" icon="Van" @click="addPlan">
- 鏂板璁″垝
- </el-button>
- <el-button @click="handleOut">
- 瀵煎嚭
- </el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="delRepairByIds(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #maintenanceResultRef="{ row }">
- <el-tag v-if="row.maintenanceResult === 1" type="success">
- 瀹屽ソ
- </el-tag>
- <el-tag v-if="row.maintenanceResult === 0" type="danger">
- 缁翠慨
- </el-tag>
- </template>
- <template #statusRef="{ row }">
- <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
- <el-tag v-if="row.status === 0" type="danger">寰呬繚鍏�</el-tag>
- </template>
- <template #operation="{ row }">
- <el-button
- type="primary"
- text
- icon="editPen"
- @click="editPlan(row.id)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="danger"
- text
- icon="delete"
- @click="delRepairByIds(row.id)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </PIMTable>
- </div>
- <PlanModal ref="planModalRef" @ok="getTableData" />
- <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep";
-import { onMounted, getCurrentInstance } from "vue";
-import PlanModal from "./Modal/PlanModal.vue";
-import MaintenanceModal from "./Modal/MaintenanceModal.vue";
-import dayjs from "dayjs";
-import { ElMessageBox, ElMessage } from "element-plus";
-
-defineOptions({
- name: "璁惧淇濆吇",
-});
-
-const { proxy } = getCurrentInstance();
-
-// 璁″垝寮圭獥鎺у埗鍣�
-const planModalRef = ref();
-// 淇濆吇寮圭獥鎺у埗鍣�
-const maintainModalRef = ref();
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-// 琛ㄦ牸閽╁瓙
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(getUpkeepPage, {
- deviceName: undefined,
- maintenancePlanTime: undefined,
- maintenanceActuallyTime: undefined,
- maintenanceActuallyName: undefined,
-}, [
- {
- label: "璁惧鍚嶇О",
- align: "center",
- prop: "deviceName",
- },
- {
- label: "瑙勬牸鍨嬪彿",
- align: "center",
- prop: "deviceModel",
- },
- {
- label: "璁″垝淇濆吇鏃ユ湡",
- align: "center",
- prop: "maintenancePlanTime",
- formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
- },
- {
- label: "褰曞叆浜�",
- align: "center",
- prop: "createUserName",
- },
- {
- label: "褰曞叆鏃ユ湡",
- align: "center",
- prop: "createTime",
- formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
- width: 200,
- },
- {
- label: "瀹為檯淇濆吇浜�",
- align: "center",
- prop: "maintenanceActuallyName",
- },
- {
- label: "瀹為檯淇濆吇鏃ユ湡",
- align: "center",
- prop: "maintenanceActuallyTime",
- formatData: (cell) =>
- cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
- },
- {
- label: "淇濆吇缁撴灉",
- align: "center",
- prop: "maintenanceResult",
- dataType: "slot",
- slot: "maintenanceResultRef",
- },
- {
- label: "鐘舵��",
- align: "center",
- prop: "status",
- dataType: "slot",
- slot: "statusRef",
- },
- {
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "200px",
- },
-]);
-// type == 1瀹為檯淇濆吇鏃堕棿 2璁″垝淇濆吇鏃堕棿
-const handleDateChange = (value,type) => {
- filters.maintenanceActuallyTimeReq = null
- filters.maintenancePlanTimeReq = null
- if(type === 1){
- if (value) {
- filters.maintenanceActuallyTimeReq = dayjs(value).format("YYYY-MM-DD");
- }
- }else{
- if (value) {
- filters.maintenancePlanTimeReq = dayjs(value).format("YYYY-MM-DD");
- }
- }
- getTableData();
-};
-
-// 鏂板淇濆吇
-const addMaintain = () => {
- const row = multipleList.value[0];
- maintainModalRef.value.open(row.id, row);
-};
-
-// 鏂板璁″垝
-const addPlan = () => {
- planModalRef.value.openModal();
-};
-
-// 缂栬緫璁″垝
-const editPlan = (id) => {
- planModalRef.value.openEdit(id);
-};
-
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-
-// 鍗曡鍒犻櫎
-const delRepairByIds = async (ids) => {
- ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await delUpkeep(ids);
- if (code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- getTableData();
- }
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/device/maintenance/export", {}, "璁惧淇濆吇.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-
-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/example/DynamicTableExample.vue b/src/views/example/DynamicTableExample.vue
deleted file mode 100644
index 038cd43..0000000
--- a/src/views/example/DynamicTableExample.vue
+++ /dev/null
@@ -1,354 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search-form">
- <el-form :inline="true" :model="searchForm">
- <el-form-item label="閮ㄩ棬">
- <el-input
- v-model="searchForm.department"
- placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item label="濮撳悕">
- <el-input
- v-model="searchForm.name"
- placeholder="璇疯緭鍏ュ鍚�"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="handleReset">閲嶇疆</el-button>
- <el-button type="success" @click="handleAdd">鏂板</el-button>
- </el-form-item>
- </el-form>
- </div>
-
- <div class="table-container">
- <DynamicTable
- ref="dynamicTableRef"
- :data="tableData"
- :dict-types="dictTypes"
- :loading="loading"
- :show-selection="true"
- :show-actions="true"
- :show-pagination="true"
- :pagination="pagination"
- height="calc(100vh - 280px)"
- @selection-change="handleSelectionChange"
- @edit="handleEdit"
- @delete="handleDelete"
- @select-change="handleSelectChange"
- @input-change="handleInputChange"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="600px"
- append-to-body
- >
- <el-form
- ref="formRef"
- :model="form"
- :rules="rules"
- label-width="100px"
- >
- <el-form-item label="閮ㄩ棬" prop="department">
- <el-input v-model="form.department" placeholder="璇疯緭鍏ラ儴闂�" />
- </el-form-item>
- <el-form-item label="濮撳悕" prop="name">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�" />
- </el-form-item>
- <el-form-item label="宸ュ彿" prop="employeeId">
- <el-input v-model="form.employeeId" placeholder="璇疯緭鍏ュ伐鍙�" />
- </el-form-item>
-
- <!-- 鍔ㄦ�佽〃鍗曢」锛氭牴鎹瓧鍏哥敓鎴� -->
- <el-form-item
- v-for="dictItem in dynamicFormItems"
- :key="dictItem.value"
- :label="dictItem.label"
- :prop="dictItem.value"
- >
- <el-select
- v-model="form[dictItem.value]"
- placeholder="璇烽�夋嫨"
- style="width: 100%"
- >
- <el-option
- v-for="option in dictItem.options"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </el-form-item>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import DynamicTable from '@/components/DynamicTable/index.vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogTitle = ref('')
-const editIndex = ref(-1)
-const selectedRows = ref([])
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- department: '',
- name: ''
-})
-
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([
- {
- id: 1,
- department: '鎶�鏈儴',
- name: '寮犱笁',
- employeeId: 'EMP001',
- status: '1',
- level: '2',
- position: '1'
- },
- {
- id: 2,
- department: '浜轰簨閮�',
- name: '鏉庡洓',
- employeeId: 'EMP002',
- status: '0',
- level: '1',
- position: '2'
- },
- {
- id: 3,
- department: '璐㈠姟閮�',
- name: '鐜嬩簲',
- employeeId: 'EMP003',
- status: '1',
- level: '3',
- position: '1'
- }
-])
-
-// 瀛楀吀绫诲瀷閰嶇疆
-const dictTypes = ref([
- 'sys_normal_disable', // 鐘舵�佸瓧鍏�
- 'sys_user_level', // 绾у埆瀛楀吀
- 'sys_user_position' // 鑱屼綅瀛楀吀
-])
-
-// 鍒嗛〉閰嶇疆
-const pagination = reactive({
- current: 1,
- size: 10,
- total: 0
-})
-
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
- department: '',
- name: '',
- employeeId: '',
- status: '',
- level: '',
- position: ''
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- department: [
- { required: true, message: '璇疯緭鍏ラ儴闂�', trigger: 'blur' }
- ],
- name: [
- { required: true, message: '璇疯緭鍏ュ鍚�', trigger: 'blur' }
- ],
- employeeId: [
- { required: true, message: '璇疯緭鍏ュ伐鍙�', trigger: 'blur' }
- ]
-}
-
-// 鍔ㄦ�佽〃鍗曢」
-const dynamicFormItems = computed(() => {
- // 杩欓噷鍙互鏍规嵁瀛楀吀鏁版嵁鍔ㄦ�佺敓鎴愯〃鍗曢」
- return [
- {
- label: '鐘舵��',
- value: 'status',
- options: [
- { label: '鍚敤', value: '1' },
- { label: '绂佺敤', value: '0' }
- ]
- },
- {
- label: '绾у埆',
- value: 'level',
- options: [
- { label: '鍒濈骇', value: '1' },
- { label: '涓骇', value: '2' },
- { label: '楂樼骇', value: '3' }
- ]
- },
- {
- label: '鑱屼綅',
- value: 'position',
- options: [
- { label: '鍛樺伐', value: '1' },
- { label: '涓荤', value: '2' },
- { label: '缁忕悊', value: '3' }
- ]
- }
- ]
-})
-
-// 缁勪欢寮曠敤
-const dynamicTableRef = ref(null)
-const formRef = ref(null)
-
-// 浜嬩欢澶勭悊鍑芥暟
-const handleSearch = () => {
- // 瀹炵幇鎼滅储閫昏緫
- console.log('鎼滅储鏉′欢:', searchForm)
- ElMessage.success('鎼滅储鍔熻兘寰呭疄鐜�')
-}
-
-const handleReset = () => {
- searchForm.department = ''
- searchForm.name = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板鍛樺伐'
- editIndex.value = -1
- resetForm()
- dialogVisible.value = true
-}
-
-const handleEdit = (row, index) => {
- dialogTitle.value = '缂栬緫鍛樺伐'
- editIndex.value = index
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handleDelete = async (row, index) => {
- try {
- await ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- type: 'warning'
- })
-
- tableData.value.splice(index, 1)
- ElMessage.success('鍒犻櫎鎴愬姛')
- } catch (error) {
- // 鐢ㄦ埛鍙栨秷鍒犻櫎
- }
-}
-
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection
-}
-
-const handleSelectChange = (row, prop, value) => {
- console.log('閫夋嫨鍙樺寲:', row, prop, value)
- // 鍙互鍦ㄨ繖閲屽鐞嗘暟鎹洿鏂伴�昏緫
-}
-
-const handleInputChange = (row, prop, value) => {
- console.log('杈撳叆鍙樺寲:', row, prop, value)
- // 鍙互鍦ㄨ繖閲屽鐞嗘暟鎹洿鏂伴�昏緫
-}
-
-const handleSizeChange = (size) => {
- pagination.size = size
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
-const handleCurrentChange = (current) => {
- pagination.current = current
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
-const handleSubmit = async () => {
- try {
- await formRef.value.validate()
-
- if (editIndex.value === -1) {
- // 鏂板
- const newRow = {
- id: Date.now(),
- ...form
- }
- tableData.value.push(newRow)
- ElMessage.success('鏂板鎴愬姛')
- } else {
- // 缂栬緫
- Object.assign(tableData.value[editIndex.value], form)
- ElMessage.success('缂栬緫鎴愬姛')
- }
-
- dialogVisible.value = false
- } catch (error) {
- console.error('琛ㄥ崟楠岃瘉澶辫触:', error)
- }
-}
-
-const resetForm = () => {
- Object.assign(form, {
- department: '',
- name: '',
- employeeId: '',
- status: '',
- level: '',
- position: ''
- })
- formRef.value?.resetFields()
-}
-
-// 缁勪欢鎸傝浇鏃跺垵濮嬪寲鏁版嵁
-onMounted(() => {
- pagination.total = tableData.value.length
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.search-form {
- margin-bottom: 20px;
- padding: 20px;
- background-color: #f5f5f5;
- border-radius: 4px;
-}
-
-.table-container {
- background-color: #fff;
- border-radius: 4px;
- padding: 20px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-</style>
diff --git a/src/views/example/SimpleExample.vue b/src/views/example/SimpleExample.vue
deleted file mode 100644
index fb528eb..0000000
--- a/src/views/example/SimpleExample.vue
+++ /dev/null
@@ -1,135 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 绠�鍗曠殑鎼滅储鍖哄煙 -->
- <el-card class="search-card">
- <el-form :inline="true">
- <el-form-item label="閮ㄩ棬">
- <el-input v-model="searchForm.department" placeholder="璇疯緭鍏ラ儴闂�" clearable />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="handleReset">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 鍔ㄦ�佽〃鏍� -->
- <el-card class="table-card">
- <template #header>
- <div class="card-header">
- <span>鍛樺伐淇℃伅琛�</span>
- <el-button type="primary" size="small" @click="handleAdd">鏂板鍛樺伐</el-button>
- </div>
- </template>
-
- <DynamicTable
- :data="tableData"
- :dict-types="dictTypes"
- :loading="loading"
- :show-selection="true"
- :show-actions="true"
- height="400px"
- @selection-change="handleSelectionChange"
- @edit="handleEdit"
- @delete="handleDelete"
- />
- </el-card>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue'
-import { ElMessage } from 'element-plus'
-import DynamicTable from '@/components/DynamicTable/index.vue'
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- department: ''
-})
-
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([
- {
- id: 1,
- department: '鎶�鏈儴',
- name: '寮犱笁',
- employeeId: 'EMP001',
- sys_normal_disable: '1', // 鐘舵��
- sys_user_level: '2', // 绾у埆
- sys_user_position: '1' // 鑱屼綅
- },
- {
- id: 2,
- department: '浜轰簨閮�',
- name: '鏉庡洓',
- employeeId: 'EMP002',
- sys_normal_disable: '0', // 鐘舵��
- sys_user_level: '1', // 绾у埆
- sys_user_position: '2' // 鑱屼綅
- }
-])
-
-// 瀛楀吀绫诲瀷
-const dictTypes = ref([
- 'sys_normal_disable', // 鐘舵�侊細鍚敤/绂佺敤
- 'sys_user_level', // 绾у埆锛氬垵绾�/涓骇/楂樼骇
- 'sys_user_position' // 鑱屼綅锛氬憳宸�/涓荤/缁忕悊
-])
-
-// 鍔犺浇鐘舵��
-const loading = ref(false)
-
-// 浜嬩欢澶勭悊
-const handleSearch = () => {
- loading.value = true
- // 妯℃嫙鎼滅储
- setTimeout(() => {
- loading.value = false
- ElMessage.success('鎼滅储瀹屾垚')
- }, 1000)
-}
-
-const handleReset = () => {
- searchForm.department = ''
-}
-
-const handleAdd = () => {
- ElMessage.info('鏂板鍔熻兘寰呭疄鐜�')
-}
-
-const handleSelectionChange = (selection) => {
- console.log('閫変腑鐨勮:', selection)
-}
-
-const handleEdit = (row, index) => {
- ElMessage.info(`缂栬緫绗�${index + 1}琛屾暟鎹甡)
-}
-
-const handleDelete = (row, index) => {
- ElMessage.warning(`鍒犻櫎绗�${index + 1}琛屾暟鎹甡)
-}
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.table-card {
- margin-bottom: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-:deep(.el-form-item) {
- margin-bottom: 0;
-}
-</style>
diff --git a/src/views/fileManagement/bookshelf/detail.vue b/src/views/fileManagement/bookshelf/detail.vue
deleted file mode 100644
index 5d7d3ac..0000000
--- a/src/views/fileManagement/bookshelf/detail.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<template>
- <div class="detail-container">
- <div class="header">
- <el-button @click="handleBack" type="primary" size="small">杩斿洖</el-button>
- <h2>鍥句功璇︽儏</h2>
- </div>
-
- <div class="content" v-loading="loading">
- <el-card v-if="current">
- <template #header>
- <div class="card-header">
- <span>鍩烘湰淇℃伅</span>
- </div>
- </template>
-
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鍥句功缂栧彿">{{ current.docNumber }}</el-descriptions-item>
- <el-descriptions-item label="鍥句功鍚嶇О">{{ current.docName }}</el-descriptions-item>
- <el-descriptions-item label="鍏ュ簱鏃堕棿">{{ current.createTime }}</el-descriptions-item>
- <!-- <el-descriptions-item label="褰撳墠浣嶇疆">{{ current.currentLocation }}</el-descriptions-item> -->
- <el-descriptions-item label="鐘舵��">{{ current.docStatus }}</el-descriptions-item>
- </el-descriptions>
-
- <!-- <div class="additional-info" v-if="current.description">
- <h4>鍥句功绠�浠�</h4>
- <p>{{ current.description }}</p>
- </div> -->
- </el-card>
-
- <el-empty v-else description="鏆傛棤鏁版嵁" />
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-
-// 瀹氫箟props
-const props = defineProps({
- current: {
- type: Object,
- required: true
- }
-})
-
-// 瀹氫箟emits
-const emit = defineEmits(['hanldeBack'])
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-// const bookInfo = ref(null)
-
-// 鏂规硶
-const handleBack = () => {
- emit('hanldeBack')
-}
-
-</script>
-
-<style scoped>
-.detail-container {
- padding: 20px;
- height: 100%;
- background-color: #f5f5f5;
-}
-
-.header {
- display: flex;
- align-items: center;
- margin-bottom: 20px;
- background-color: #fff;
- padding: 15px 20px;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.header h2 {
- margin: 0 0 0 20px;
- color: #333;
-}
-
-.content {
- background-color: #fff;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.card-header {
- font-weight: bold;
- color: #333;
-}
-
-.additional-info {
- margin-top: 20px;
- padding-top: 20px;
- border-top: 1px solid #ebeef5;
-}
-
-.additional-info h4 {
- margin: 0 0 10px 0;
- color: #333;
- font-size: 16px;
-}
-
-.additional-info p {
- margin: 0;
- color: #666;
- line-height: 1.6;
-}
-</style>
diff --git a/src/views/fileManagement/bookshelf/index.vue b/src/views/fileManagement/bookshelf/index.vue
deleted file mode 100644
index 2689900..0000000
--- a/src/views/fileManagement/bookshelf/index.vue
+++ /dev/null
@@ -1,688 +0,0 @@
-<template>
- <div class="sample">
- <div class="main-content" v-if="!isDetail">
- <div class="search">
- <div class="search_thing">
- <div class="search_label">浠撳簱鍚嶇О锛�</div>
- <div class="search_input">
- <el-select v-model="entity.warehouseId" placeholder="閫夋嫨浠撳簱" size="small" @change="warehouseChange">
- <el-option v-for="item in warehouse" :key="item.id" :label="item.label" :value="item.id">
- </el-option>
- </el-select>
- </div>
- </div>
- <div class="search_thing">
- <div class="search_label">璐ф灦锛�</div>
- <div class="search_input">
- <el-select v-model="entity.shelfId" placeholder="閫夋嫨璐ф灦" size="small" @change="handleShelf">
- <el-option v-for="item in shelf" :key="item.id" :label="item.label" :value="item.id">
- </el-option>
- </el-select>
- </div>
- </div>
- <!-- <div class="search_thing">
- <el-button size="small" @click="handleShelf(entity.shelfId,'')">閲嶇疆</el-button>
- <el-button size="small" type="primary" @click="handleShelf(entity.shelfId)">鏌ヨ</el-button>
- </div> -->
- <div class="btns">
- <el-button size="small" style="color:#3A7BFA" @click="keepVisible=true">缁存姢</el-button>
- <el-button size="small" style="color:#3A7BFA" @click="warehouseVisible=true,isEdit=false">娣诲姞浠撳簱</el-button>
- <el-button size="small" style="color:#3A7BFA" @click="shelvesVisible=true,isEdit=false"
- :disabled="entity.warehouseId==null">娣诲姞璐ф灦</el-button>
- </div>
- </div>
- <div class="table" v-loading="tableLoading">
- <table class="tables" style="table-layout:fixed;" v-if="tableList.length>0">
- <tbody>
- <tr v-for="(item,index) in tableList" :key="index">
- <td v-for="(m,i) in item" :key="i" class="content">
- <h4 v-if="m.row!=undefined">{{ m.row }} - {{ m.col }}</h4>
- <ul>
- <el-tooltip
- effect="dark"
- placement="top"
- v-for="(n,j) in m.documentationDtoList"
- :key="j">
- <template #content><span>{{ n.docName }}</span>
- <span> [{{ n.docNumber }}]</span></template>
- <li class="green"
- @click="handelDetail(n)">
- <i></i>
- <span>{{ n.docName }}</span>
- <span> [{{ n.docNumber }}] <span :style="{ color: getStatusColor(n.docStatus) }">锛坽{ n.docStatus }}锛�</span></span>
- </li>
- </el-tooltip>
- </ul>
- </td>
- </tr>
- <tr>
- <td v-for="(item,index) in rowList" :key="index" style="background: ghostwhite;height: 20px;">{{ item }}
- </td>
- </tr>
- </tbody>
- </table>
- <span v-else style="color: rgb(144, 147, 153);display: inline-block;position: absolute;top: 60%;left: 50%;transform: translate(-50%,-50%);">鏆傛棤鏁版嵁</span>
- </div>
- </div>
- <Detail v-else @hanldeBack="isDetail=false" :current="current" />
-
- <!-- 搴撲綅缁存姢瀵硅瘽妗� -->
- <el-dialog v-model="keepVisible" title="搴撲綅缁存姢" width="350px" :append-to-body="true">
- <el-tree :data="warehouse" ref="tree" node-key="id"
- highlight-current v-if="keepVisible"
- empty-text="鏆傛棤鏁版嵁">
- <template #default="{ node, data }">
- <div class="custom-tree-node" style="width: 100%;">
- <el-row style="width: 100%;display: flex;align-items: center;">
- <el-col :span="14">
- <span>
- <el-icon v-if="node.level < 2" class="folder-icon">
- <FolderOpened />
- </el-icon>
- <el-icon v-else class="file-icon">
- <Document />
- </el-icon>
- {{ data.label }}
- </span>
- </el-col>
- <el-col :span="10" v-if="node.level<3">
- <el-button type="link" size="small" :icon="Edit" @click.stop="handleEdit(data,node.level)">
- </el-button>
- <el-button type="danger" size="small" :icon="Delete" @click.stop="handleDelete(data,node.level)">
- </el-button>
- </el-col>
- </el-row>
- </div>
- </template>
- </el-tree>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="keepVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="keepVisible = false" >纭� 瀹�</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 浠撳簱鏂板/淇敼瀵硅瘽妗� -->
- <el-dialog v-model="warehouseVisible" :title="isEdit?'浠撳簱淇敼':'浠撳簱鏂板'" width="350px">
- <el-row>
- <el-col class="search_thing" :span="24">
- <div class="search_label"><span class="required-span">* </span>浠撳簱鍚嶇О锛�</div>
- <div class="search_input">
- <el-input v-model="name" size="small" @keyup.enter="confirmWarehouse"></el-input>
- </div>
- </el-col>
- </el-row>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="warehouseVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="confirmWarehouse" :loading="upLoadWarehouse">纭� 瀹�</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 璐ф灦鏂板/淇敼瀵硅瘽妗� -->
- <el-dialog v-model="shelvesVisible" :title="isEdit?'璐ф灦淇敼':'璐ф灦鏂板'" width="350px">
- <el-row>
- <el-col class="search_thing" :span="24">
- <div class="search_label"><span class="required-span">* </span>璐ф灦鍚嶇О锛�</div>
- <div class="search_input">
- <el-input v-model="shelves.name" size="small"></el-input>
- </div>
- </el-col>
- </el-row>
- <el-row>
- <el-col class="search_thing" :span="24">
- <div class="search_label"><span class="required-span">* </span>璐ф灦灞傛暟锛�</div>
- <div class="search_input">
- <el-input v-model="shelves.row" size="small"></el-input>
- </div>
- </el-col>
- </el-row>
- <el-row>
- <el-col class="search_thing" :span="24">
- <div class="search_label"><span class="required-span">* </span>璐ф灦鍒楁暟锛�</div>
- <div class="search_input">
- <el-input v-model="shelves.col" size="small"></el-input>
- </div>
- </el-col>
- </el-row>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="shelvesVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="confirmShelves" :loading="upLoadShelves">纭� 瀹�</el-button>
- </span>
- </template>
- </el-dialog>
-
-
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, watch } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Edit, Delete, FolderOpened, Document } from '@element-plus/icons-vue'
-import { getWarehouseList, addWarehouse, updateWarehouse, deleteWarehouse, getWarehouseStructure, addShelf, updateShelf, deleteShelf } from '@/api/fileManagement/bookshelf'
-import Detail from './detail.vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const entity = reactive({
- warehouseId: null,
- shelfId: null
-})
-
-const warehouse = ref([])
-const shelf = ref([])
-const keepVisible = ref(false)
-const warehouseVisible = ref(false)
-const shelvesVisible = ref(false)
-const upLoadWarehouse = ref(false)
-const upLoadShelves = ref(false)
-const tableList = ref([])
-const rowList = ref([])
-const value = ref('')
-const name = ref('')
-const shelves = reactive({})
-const isEdit = ref(false)
-const isDetail = ref(false)
-const currentEdit = ref(null)
-const tableLoading = ref(false)
-const current = ref({})
-
-// 妯℃澘寮曠敤
-const organization = ref(null)
-
-// 鐩戝惉鍣�
-watch(isEdit, (newVal) => {
- if (!newVal) {
- Object.keys(shelves).forEach(key => delete shelves[key])
- }
-})
-
-// 鏂规硶
-
-const selectList = async () => {
- // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
- const res = await getWarehouseList()
- warehouse.value = res.data
-
- if (warehouse.value.length == 0) {
- entity.warehouseId = ''
- entity.shelfId = ''
- tableList.value = []
- }
-
-
-
- if (!entity.warehouseId && warehouse.value.length > 0) {
- entity.warehouseId = warehouse.value[0].id
- warehouseChange(entity.warehouseId)
- if (shelf.value.length > 0) {
- entity.shelfId = shelf.value[0].id
- handleShelf(entity.shelfId)
- } else {
- tableList.value = []
- }
- } else if (warehouse.value.length > 0) {
- warehouseChange(entity.warehouseId)
- if (shelf.value.length > 0) {
- entity.shelfId = shelf.value[0].id
- handleShelf(entity.shelfId)
- } else {
- tableList.value = []
- }
- }
-}
-
-const confirmWarehouse = () => {
- if (!name.value) {
- ElMessage.error('璇峰~鍐欎粨搴撳悕绉�')
- return
- }
- upLoadWarehouse.value = true
-
- if (currentEdit.value && currentEdit.value.id) {
- // 淇敼浠撳簱
- // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
- updateWarehouse({
- id: currentEdit.value.id,
- warehouseName: name.value
- }).then(res => {
- upLoadWarehouse.value = false
- warehouseVisible.value = false
- currentEdit.value = null
- ElMessage.success('淇敼鎴愬姛')
- selectList()
- name.value = ''
- warehouseChange(entity.warehouseId)
- })
-
- } else {
- // 鏂板浠撳簱
- // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
- addWarehouse({
- warehouseName: name.value
- }).then(res => {
- upLoadWarehouse.value = false
- warehouseVisible.value = false
- ElMessage.success('娣诲姞鎴愬姛')
- selectList()
- name.value = ''
- warehouseChange(entity.warehouseId)
- })
- }
-}
-
-const confirmShelves = () => {
- if (!shelves.name) {
- ElMessage.error('璇峰~鍐欒揣鏋跺悕绉�')
- return
- }
- if (!shelves.row) {
- ElMessage.error('璇峰~鍐欒揣鏋跺眰鏁�')
- return
- }
- if (!shelves.col) {
- ElMessage.error('璇峰~鍐欒揣鏋跺垪鏁�')
- return
- }
- upLoadShelves.value = true
-
- if (currentEdit.value && currentEdit.value.id) {
- // 淇敼
- updateShelf({
- id: currentEdit.value.id,
- name: shelves.name,
- row: Number(shelves.row),
- col: Number(shelves.col),
- warehouseId: entity.warehouseId
- }).then(res => {
- upLoadShelves.value = false
- shelvesVisible.value = false
- ElMessage.success('淇敼鎴愬姛')
- selectList()
- currentEdit.value = {}
- }).catch(err => {
- upLoadShelves.value = false
- shelvesVisible.value = false
- ElMessage.error('淇敼澶辫触')
- })
-
- } else {
- // 鏂板
- // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
- addShelf({
- name: shelves.name,
- row: Number(shelves.row),
- col: Number(shelves.col),
- warehouseId: entity.warehouseId
- }).then(res => {
- upLoadShelves.value = false
- shelvesVisible.value = false
- ElMessage.success('娣诲姞鎴愬姛')
- selectList()
- Object.keys(shelves).forEach(key => delete shelves[key])
- }).catch(err => {
- upLoadShelves.value = false
- shelvesVisible.value = false
- ElMessage.error('娣诲姞澶辫触')
- })
- }
- warehouseChange(entity.warehouseId)
-}
-
-
-
-const handleDelete = (row, level) => {
- ElMessageBox.confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning"
- }).then(() => {
- if (level == 1) {
- // 鍒犻櫎浠撳簱
- deleteWarehouse([row.id]).then(res => {
- ElMessage.success('鍒犻櫎鎴愬姛')
- selectList()
- })
- } else {
- // 鍒犻櫎璐ф灦
- deleteShelf({
- id: row.id
- }).then(res => {
- ElMessage.success('鍒犻櫎鎴愬姛')
- selectList()
- })
- }
- warehouseChange(entity.warehouseId)
- }).catch(() => {})
-}
-
-const handleEdit = (data, level) => {
- isEdit.value = true
- if (level == 1) {
- warehouseVisible.value = true
- currentEdit.value = data
- name.value = data.label
- } else {
- shelvesVisible.value = true
- currentEdit.value = data
- Object.assign(shelves, {
- name: data.label,
- row: data.row,
- col: data.col,
- warehouseId: data.warehouseId
- })
- }
-}
-
-const handelDetail = (row) => {
- current.value = row
- isDetail.value = true
-}
-
-// 鏍规嵁鏂囨。鐘舵�佽繑鍥炲搴旂殑棰滆壊
-const getStatusColor = (status) => {
- if (status === '姝e父') {
- return '#34BD66' // 缁胯壊
- } else if (status === '鍊熷嚭') {
- return '#F56C6C' // 绾㈣壊
- }
- return '#606266' // 榛樿棰滆壊
-}
-
-const warehouseChange = (val) => {
-tableList.value = []
-let map = warehouse.value.find(a => {
- return a && a.id === val ? a : null
-})
-if (map && map.children) {
- shelf.value = map.children
- entity.shelfId = ''
-} else {
- shelf.value = []
-}
-currentEdit.value = null
-}
-
-const handleShelf = async(e) => {
- if (e) {
- tableLoading.value = true
- let data = []
- const res = await getWarehouseStructure({warehouseGoodsShelvesId:e})
- if(res.code == 200){
- data = res.data.map(m=>{
- m.books = m.documentationDtoList|[]
- return m
- })
- }else{
- ElMessage.error(res.message)
- }
- setTimeout(() => {
- tableLoading.value = false
- let set = new Set()
- tableList.value = []
- let arr = []
-
- if (data && data.length > 0) {
- data.forEach(m => {
- if (m && m.row && m.col) {
- set.add(m.col)
- if (arr.length > 0) {
- if (arr.find(n => n.row == m.row)) {
- arr.push(m)
- } else {
- tableList.value.push(arr)
- arr = []
- arr.push(m)
- }
- } else {
- arr.push(m)
- }
- }
- })
-
- if (arr.length > 0) {
- tableList.value.push(arr)
- }
- }
-
- rowList.value = []
- for (let i = 0; i < set.size; i++) {
- rowList.value.push(`${i + 1} 鍒梎)
- }
- console.log(6666, tableList.value,rowList.value,data)
- }, 1000)
- }
-}
-
-
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- selectList()
-})
-</script>
-
-<style scoped>
- .main-content {
- width: 100%;
- height: 100%;
- padding: 20px;
- box-sizing: border-box;
- }
-
- .title {
- height: 20px;
- line-height: 20px;
- margin-bottom: 20px;
- }
-
- .search {
- background-color: #fff;
- height: 80px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20px;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- margin-bottom: 20px;
- }
-
- .search_thing {
- display: flex;
- align-items: center;
- height: 50px;
- margin-right: 20px;
- }
-
- .search_label {
- width: 90px;
- font-size: 14px;
- text-align: right;
- color: #606266;
- font-weight: 500;
- margin-right: 10px;
- }
-
- .search_input {
- width: 200px;
- }
-
- .table {
- background-color: #fff;
- width: 100%;
- height: calc(100% - 100px);
- padding: 20px;
- overflow-y: auto;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- }
-
- .el-form-item {
- margin-bottom: 16px;
- }
-
- .btns {
- display: flex;
- align-items: center;
- gap: 10px;
- }
-
- .tables {
- width: 100%;
- height: 100%;
- border-collapse: collapse;
- border: 1px solid #e4e7ed;
- }
-
- .tables th {
- font-size: 14px;
- border: 1px solid #e4e7ed;
- background-color: #fafafa;
- padding: 8px;
- font-weight: 500;
- }
-
- .tables td {
- font-size: 12px;
- text-align: center;
- vertical-align: top;
- border: 1px solid #e4e7ed;
- padding: 8px;
- box-sizing: border-box;
- height: 120px;
- background-color: #fff;
- }
-
- .tables ul {
- list-style-type: none;
- }
-
- .tables ul li {
- border-radius: 3px;
- padding: 4px 10px;
- box-sizing: border-box;
- margin-bottom: 5px;
- font-size: 12px;
- display: flex;
- align-items: center;
- justify-content: start;
- color: #333333;
- cursor: pointer;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-
- .tables h4 {
- color: #999999;
- font-size: 14px;
- font-weight: 400;
- padding: 6px 0;
- }
-
- .tables i {
- display: inline-block;
- width: 6px;
- height: 6px;
- border-radius: 50%;
- margin-right: 6px;
- }
-
- li:hover {
- background: rgba(58, 123, 250, 0.18);
- }
-
- li:hover i {
- background: #3A7BFA;
- }
-
- li:hover .num {
- color: #3A7BFA;
- }
-
- .green {
- background: #E0F6EA;
- }
-
- .green i {
- background: #34BD66;
- }
-
- .green .num {
- color: #34BD66;
- }
-
- .el-dialog {
- position: relative;
- }
-
- .shaoma {
- display: flex;
- align-items: center;
- font-size: 14px;
- color: #3A7BFA;
- position: absolute;
- top: 23px;
- right: 54px;
- cursor: pointer;
- }
-
- .folder-icon {
- color: #409eff;
- font-size: 16px;
- margin-right: 6px;
- }
-
- .file-icon {
- color: #67c23a;
- font-size: 16px;
- margin-right: 6px;
- }
-
- .node_i {
- color: orange;
- font-size: 18px;
- }
-
- .custom-tree-node .el-button {
- opacity: 0;
- }
-
- .custom-tree-node:hover .el-button {
- opacity: 1;
- }
-
- :deep(.el-loading-mask) {
- z-index: 10;
- }
-
- .required-span {
- color: #f56c6c;
- }
-
- .table-row {
- border-bottom: 1px solid #e4e7ed;
- }
-
- .table-row:last-child {
- border-bottom: none;
- }
-
- .column-header {
- background-color: #fafafa !important;
- font-weight: 500;
- color: #606266;
- }
-
- .content {
- transition: background-color 0.2s ease;
- }
-
- .content:hover {
- background-color: #f5f7fa;
- }
-</style>
diff --git a/src/views/fileManagement/borrow/index.vue b/src/views/fileManagement/borrow/index.vue
deleted file mode 100644
index 705a0f8..0000000
--- a/src/views/fileManagement/borrow/index.vue
+++ /dev/null
@@ -1,647 +0,0 @@
-<template>
- <div class="app-container borrow-view">
- <!-- 鏌ヨ鍖哄煙 -->
- <div class="search-container">
- <el-form :model="searchForm" :inline="true" class="search-form">
- <el-form-item label="鍊熼槄鐘舵�侊細">
- <el-select v-model="searchForm.borrowStatus" placeholder="璇烽�夋嫨鍊熼槄鐘舵��" clearable style="width: 150px">
- <el-option label="鍊熼槄" value="鍊熼槄" />
- <el-option label="褰掕繕" value="褰掕繕" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍊熼槄浜猴細">
- <el-input
- v-model="searchForm.borrower"
- placeholder="璇疯緭鍏ュ�熼槄浜�"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item label="鍊熼槄鏃ユ湡鑼冨洿锛�">
- <el-date-picker
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 300px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">
- <el-icon><Search /></el-icon>
- 鏌ヨ
- </el-button>
- <el-button @click="handleReset">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- </el-form-item>
- <el-form-item style="margin-left: auto;">
- <el-button type="primary" @click="openBorrowDia('add')">
- <el-icon><Plus /></el-icon>
- 鏂板鍊熼槄
- </el-button>
- <el-button @click="handleOut">
- 瀵煎嚭
- </el-button>
- <el-button
- type="danger"
- @click="handleBatchDelete"
- :disabled="selectedRows.length === 0"
- >
- <el-icon><Delete /></el-icon>
- 鎵归噺鍒犻櫎 ({{ selectedRows.length }})
- </el-button>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 琛ㄦ牸鍖哄煙 -->
- <div class="table-container">
- <PIMTable
- :table-data="borrowList"
- :column="tableColumns"
- :is-selection="true"
- :border="true"
- :table-loading="tableLoading"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- layout: 'total, sizes, prev, pager, next, jumper'
- }"
- @selection-change="handleSelectionChange"
- @pagination="handlePagination"
- />
- </div>
-
- <!-- 鍊熼槄鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- v-model="borrowDia"
- :title="borrowOperationType === 'add' ? '鏂板鍊熼槄' : '缂栬緫鍊熼槄'"
- width="800px"
- @close="closeBorrowDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="borrowForm"
- label-width="140px"
- :rules="borrowRules"
- ref="borrowFormRef"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍊熼槄浜猴細" prop="borrower">
- <el-input v-model="borrowForm.borrower" placeholder="璇疯緭鍏ュ�熼槄浜�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍊熼槄涔︾睄锛�" prop="documentationId">
- <!-- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="width: 100%" @change="handleScanContent">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select> -->
- <div style="display: flex; gap: 10px;">
- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="flex: 1;width: 100px;" @change="handleSelectChange">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select>
- <el-input
- v-model="scanContent"
- placeholder="鎵爜杈撳叆"
- style="width: 100px;"
- @input="handleScanContent"
- clearable
- />
- </div>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍊熼槄鏃ユ湡锛�" prop="borrowDate">
- <el-date-picker
- v-model="borrowForm.borrowDate"
- type="date"
- placeholder="閫夋嫨鍊熼槄鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="搴斿綊杩樻棩鏈燂細" prop="dueReturnDate">
- <el-date-picker
- v-model="borrowForm.dueReturnDate"
- type="date"
- placeholder="閫夋嫨搴斿綊杩樻棩鏈�"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="鍊熼槄鐩殑锛�" prop="borrowPurpose">
- <el-input v-model="borrowForm.borrowPurpose" placeholder="璇疯緭鍏ュ�熼槄鐩殑" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞锛�" prop="remark">
- <el-input
- v-model="borrowForm.remark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitBorrowForm">纭</el-button>
- <el-button @click="closeBorrowDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from "vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import { Search, Refresh, Plus, Delete } from '@element-plus/icons-vue';
-import PIMTable from '@/components/PIMTable/PIMTable.vue';
-import { getBorrowList, addBorrow, updateBorrow, deleteBorrow, getDocumentList } from '@/api/fileManagement/borrow';
-
-const { proxy } = getCurrentInstance();
-
-// 鍝嶅簲寮忔暟鎹�
-const borrowDia = ref(false);
-const borrowOperationType = ref("");
-const tableLoading = ref(false);
-const borrowList = ref([]);
-const selectedRows = ref([]);
-const documentList = ref([]); // 鏂囨。鍒楄〃锛岀敤浜庡�熼槄涔︾睄閫夋嫨
-const scanContent = ref() // 鎵爜鍐呭
-// 鍒嗛〉鐩稿叧
-const pagination = reactive({
- currentPage: 1,
- pageSize: 10,
- total: 0,
-});
-
-// 鏌ヨ琛ㄥ崟
-const searchForm = reactive({
- documentationId: "",
- borrowStatus: "",
- borrower: "",
- returnerId: "",
- dateRange: []
-});
-
-// 鍊熼槄琛ㄥ崟
-const borrowForm = reactive({
- id: "",
- documentationId: "",
- borrower: "",
- returnerId: "",
- borrowPurpose: "",
- borrowDate: "",
- dueReturnDate: "",
- returnDate: "",
- borrowStatus: "",
- remark: ""
-});
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const borrowRules = reactive({
-
- borrower: [{ required: true, message: "璇疯緭鍏ュ�熼槄浜�", trigger: "blur" }],
- borrowPurpose: [{ required: true, message: "璇疯緭鍏ュ�熼槄鐩殑", trigger: "blur" }],
- borrowDate: [{ required: true, message: "璇烽�夋嫨鍊熼槄鏃ユ湡", trigger: "change" }],
- dueReturnDate: [{ required: true, message: "璇烽�夋嫨搴斿綊杩樻棩鏈�", trigger: "change" }],
- borrowStatus: [{ required: true, message: "璇烽�夋嫨鍊熼槄鐘舵��", trigger: "change" }]
-});
-
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumns = ref([
- {
- label: '鏂囨。鍚嶇О',
- prop: 'docName',
- width: '200',
- },
- { label: '鍊熼槄浜�', prop: 'borrower' },
- { label: '鍊熼槄鐩殑', prop: 'borrowPurpose' },
- { label: '鍊熼槄鏃ユ湡', prop: 'borrowDate' },
- { label: '搴斿綊杩樻棩鏈�', prop: 'dueReturnDate' },
- {
- label: '鍊熼槄鐘舵��',
- prop: 'borrowStatus',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- return params;
- },
- formatType: (params) => {
- if (params === '褰掕繕') return 'success';
- if (params === '鍊熼槄') return 'warning';
- return 'info';
- }
- },
- { label: '澶囨敞', prop: 'remark', width: '150' },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: '150',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openBorrowDia('edit', row)
- },
- },
- {
- name: "鍒犻櫎",
- type: "text",
- clickFun: (row) => {
- handleDelete(row)
- },
- },
- ],
- }
-]);
-
-// 鍒濆鍖栨暟鎹�
-const initData = async () => {
- await Promise.all([
- loadDocumentList(),
- loadBorrowList()
- ]);
-};
-
-// 鍔犺浇鏂囨。鍒楄〃
-const loadDocumentList = async () => {
- try {
- const res = await getDocumentList();
- if (res.code === 200) {
- documentList.value = res.data || [];
- console.log("shuju",documentList.value)
- } else {
- ElMessage.error(res.msg || "鑾峰彇鏂囨。鍒楄〃澶辫触");
- documentList.value = [];
- }
- } catch (error) {
- ElMessage.error("鑾峰彇鏂囨。鍒楄〃澶辫触锛岃閲嶈瘯");
- documentList.value = [];
- }
-};
-
-// 鍔犺浇鍊熼槄鍒楄〃
-const loadBorrowList = async () => {
- try {
- tableLoading.value = true;
-
- // 鏋勫缓鏌ヨ鍙傛暟
- const query = {
- page: pagination.currentPage,
- size: pagination.pageSize,
- documentationId: searchForm.documentationId || undefined,
- borrowStatus: searchForm.borrowStatus || undefined,
- borrower: searchForm.borrower || undefined,
- returnerId: searchForm.returnerId || undefined,
- entryDateStart: searchForm.dateRange && searchForm.dateRange.length > 0 ? searchForm.dateRange[0] : undefined,
- entryDateEnd: searchForm.dateRange && searchForm.dateRange.length > 1 ? searchForm.dateRange[1] : undefined
- };
-
- // 绉婚櫎undefined鐨勫弬鏁�
- Object.keys(query).forEach(key => {
- if (query[key] === undefined) {
- delete query[key];
- }
- });
-
- const res = await getBorrowList(query);
- if (res.code === 200) {
- borrowList.value = res.data.records || [];
- pagination.total = res.data.total || 0;
- } else {
- ElMessage.error(res.msg || "鑾峰彇鍊熼槄鍒楄〃澶辫触");
- borrowList.value = [];
- pagination.total = 0;
- }
-
- // 閲嶇疆閫夋嫨鐘舵��
- selectedRows.value = [];
- } catch (error) {
- ElMessage.error("鑾峰彇鍊熼槄鍒楄〃澶辫触锛岃閲嶈瘯");
- borrowList.value = [];
- pagination.total = 0;
- } finally {
- tableLoading.value = false;
- }
-};
-
-// 鏌ヨ
-const handleSearch = () => {
- pagination.currentPage = 1;
- loadBorrowList();
-};
-
-// 閲嶇疆鏌ヨ
-const handleReset = () => {
- searchForm.documentationId = "";
- searchForm.borrowStatus = "";
- searchForm.borrower = "";
- searchForm.returnerId = "";
- searchForm.dateRange = [];
- pagination.currentPage = 1;
- loadBorrowList();
- ElMessage.success("鏌ヨ鏉′欢宸查噸缃�");
-};
-
-// 澶勭悊涓嬫媺閫夋嫨鍙樺寲
-const handleSelectChange = (value) => {
- // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
- scanContent.value = '';
-};
-
-// 澶勭悊鎵爜鍐呭
-const handleScanContent = async (value) => {
- if (!value) return;
- try {
- // 鏌ユ壘鎵弿鍐呭瀵瑰簲鐨勬枃妗�
- const matchedDoc = documentList.value.find(item =>
- item.id == value
- );
- console.log("matchedDoc", matchedDoc);
-
-
- if (matchedDoc) {
-
- // 鎵惧埌鍖归厤鐨勬枃妗o紝璁剧疆琛ㄥ崟鍊�
- borrowForm.documentationId = matchedDoc.id;
- ElMessage.success(`宸查�夋嫨: ${matchedDoc.docName || matchedDoc.name}`);
- } else {
- // 鏈壘鍒板尮閰嶇殑鏂囨。锛屾彁绀虹敤鎴�
- ElMessage.warning('鏈壘鍒板搴旂殑涔︾睄锛岃妫�鏌ユ壂鐮佸唴瀹规垨鎵嬪姩閫夋嫨');
- }
- } catch (error) {
- ElMessage.error('鎵爜澶勭悊澶辫触锛岃閲嶈瘯');
- console.error('鎵爜澶勭悊閿欒:', error);
- }
-}
-// 鎵撳紑鍊熼槄寮规
-const openBorrowDia = async (type, data) => {
- // 鍏堝埛鏂版枃妗e垪琛�
- await loadDocumentList();
-
- borrowOperationType.value = type;
- borrowDia.value = true;
- scanContent.value = ''; // 娓呯┖鎵爜鍐呭
-
- if (type === "edit") {
- // 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
- Object.assign(borrowForm, data);
- } else {
- // 鏂板妯″紡锛屾竻绌鸿〃鍗�
- Object.keys(borrowForm).forEach(key => {
- borrowForm[key] = "";
- });
- // 璁剧疆榛樿鐘舵��
- borrowForm.borrowStatus = "鍊熼槄";
- // 璁剧疆褰撳墠鏃ユ湡涓哄�熼槄鏃ユ湡
- borrowForm.borrowDate = new Date().toISOString().split('T')[0];
- }
-};
-
-// 鍏抽棴鍊熼槄寮规
-const closeBorrowDia = () => {
- proxy.$refs.borrowFormRef.resetFields();
- borrowDia.value = false;
- scanContent.value = ''; // 娓呯┖鎵爜鍐呭
-};
-
-// 鎻愪氦鍊熼槄琛ㄥ崟
-const submitBorrowForm = () => {
- proxy.$refs.borrowFormRef.validate(async (valid) => {
- if (valid) {
- try {
- if (borrowOperationType.value === "edit") {
- // 缂栬緫妯″紡锛屾洿鏂扮幇鏈夋暟鎹�
- const res = await updateBorrow({
- borrower:borrowForm.borrower,
- id: borrowForm.id,
- borrowPurpose: borrowForm.borrowPurpose,
- borrowDate: borrowForm.borrowDate,
- dueReturnDate: borrowForm.dueReturnDate,
- returnDate: borrowForm.returnDate,
- remark: borrowForm.remark
- });
-
- if (res.code === 200) {
- ElMessage.success("缂栬緫鎴愬姛");
- await loadBorrowList();
- closeBorrowDia();
- } else {
- ElMessage.error(res.msg || "缂栬緫澶辫触");
- }
- } else {
- // 鏂板妯″紡锛屾坊鍔犳柊鏁版嵁
- const res = await addBorrow({
- documentationId: borrowForm.documentationId,
- borrower: borrowForm.borrower,
- returnerId: borrowForm.returnerId,
- borrowPurpose: borrowForm.borrowPurpose,
- borrowDate: borrowForm.borrowDate,
- dueReturnDate: borrowForm.dueReturnDate,
- returnDate: borrowForm.returnDate,
- borrowStatus: borrowForm.borrowStatus,
- remark: borrowForm.remark
- });
-
- if (res.code === 200) {
- ElMessage.success("鏂板鎴愬姛");
- await loadBorrowList();
- closeBorrowDia();
- } else {
- ElMessage.error(res.msg || "鏂板澶辫触");
- }
- }
- } catch (error) {
- ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯");
- }
- }
- });
-};
-
-// 鍒犻櫎鍊熼槄璁板綍
-const handleDelete = (row) => {
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄よ繖鏉″�熼槄璁板綍鍚楋紵`,
- "鍒犻櫎鎻愮ず",
- {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }
- ).then(async () => {
- try {
- const res = await deleteBorrow([row.id]);
- if (res.code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- await loadBorrowList();
- } else {
- ElMessage.error(res.msg || "鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- }).catch(() => {
- ElMessage.info("宸插彇娑堝垹闄�");
- });
-};
-
-// 鎵归噺鍒犻櫎
-const handleBatchDelete = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑璁板綍");
- return;
- }
-
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉″�熼槄璁板綍鍚楋紵`,
- "鎵归噺鍒犻櫎鎻愮ず",
- {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }
- ).then(async () => {
- try {
- const selectedIds = selectedRows.value.map(row => row.id);
- const res = await deleteBorrow(selectedIds);
- if (res.code === 200) {
- ElMessage.success("鎵归噺鍒犻櫎鎴愬姛");
- await loadBorrowList();
- } else {
- ElMessage.error(res.msg || "鎵归噺鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鎵归噺鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- }).catch(() => {
- ElMessage.info("宸插彇娑堝垹闄�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/documentationBorrowManagement/export", {}, "鍊熼槄鐧昏.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-
-// 閫夋嫨鍙樺寲浜嬩欢
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 澶勭悊鍒嗛〉鍙樺寲
-const handlePagination = (current, size) => {
- pagination.currentPage = current;
- pagination.pageSize = size;
- loadBorrowList();
-};
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- initData();
-});
-</script>
-
-<style scoped>
-.borrow-view {
- padding: 20px;
-}
-
-.search-container {
- background: #ffffff;
- padding: 20px;
- border-radius: 8px;
- margin-bottom: 20px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.search-form {
- margin: 0;
-}
-
-.table-container {
- background: #ffffff;
- border-radius: 8px;
- overflow: hidden;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.empty-data {
- text-align: center;
- color: #909399;
- padding: 40px;
- font-size: 14px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-form-item__label) {
- font-weight: 500;
- color: #303133;
-}
-
-:deep(.el-input__wrapper) {
- box-shadow: 0 0 0 1px #dcdfe6 inset;
-}
-
-:deep(.el-input__wrapper:hover) {
- box-shadow: 0 0 0 1px #c0c4cc inset;
-}
-
-:deep(.el-input__wrapper.is-focus) {
- box-shadow: 0 0 0 1px #409eff inset;
-}
-</style>
diff --git a/src/views/fileManagement/document/attachmentManager.vue b/src/views/fileManagement/document/attachmentManager.vue
deleted file mode 100644
index a4e1d43..0000000
--- a/src/views/fileManagement/document/attachmentManager.vue
+++ /dev/null
@@ -1,426 +0,0 @@
-<template>
- <el-dialog v-model="dialogVisible" title="闄勪欢绠$悊" width="60%" :before-close="handleClose">
- <div class="attachment-manager">
- <!-- 涓婁紶鍖哄煙 -->
- <div class="upload-section">
- <el-upload
- ref="uploadRef"
- :action="uploadUrl"
- :headers="uploadHeaders"
- :before-upload="handleBeforeUpload"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- :on-remove="handleRemove"
- :file-list="fileList"
- multiple
- :limit="10"
- :show-file-list="false"
- :data="{documentId: currentDocumentId}"
- accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.xml,.jpg,.jpeg,.png,.gif,.bmp,.rar,.zip,.7z"
- >
- <el-button type="primary" :icon="Plus">涓婁紶闄勪欢</el-button>
- <template #tip>
- <div class="el-upload__tip">
- 鏀寔鏍煎紡锛歞oc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
- <br>鍗曚釜鏂囦欢澶у皬涓嶈秴杩�50MB
- </div>
- </template>
- </el-upload>
- </div>
-
- <!-- 闄勪欢鍒楄〃 -->
- <div class="attachment-list">
- <el-table :data="fileList" border height="400px" v-loading="loading">
- <el-table-column label="搴忓彿" type="index" width="60" align="center" />
- <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="200" show-overflow-tooltip />
- <el-table-column label="鏂囦欢澶у皬" prop="size" width="100" align="center">
- <template #default="scope">
- {{ formatFileSize(scope.row.size) }}
- </template>
- </el-table-column>
- <el-table-column label="涓婁紶鏃堕棿" prop="uploadTime" width="160" align="center">
- <template #default="scope">
- {{ formatDate(scope.row.uploadTime) }}
- </template>
- </el-table-column>
- <el-table-column label="鐘舵��" prop="status" width="80" align="center">
- <template #default="scope">
- <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'" size="small">
- {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column fixed="right" label="鎿嶄綔" width="200" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="previewFile(scope.row)">
- 棰勮
- </el-button>
- <el-button link type="primary" size="small" @click="downloadFile(scope.row)">
- 涓嬭浇
- </el-button>
- <el-button link type="danger" size="small" @click="removeFile(scope.row)">
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
-
- <!-- 鏂囦欢棰勮缁勪欢 -->
- <filePreview ref="filePreviewRef" />
- </el-dialog>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus } from '@element-plus/icons-vue'
-import { getToken } from "@/utils/auth"
-import { addDocumentationFile, getDocumentationFileList, deleteDocumentationFile } from '@/api/fileManagement/document'
-import filePreview from '@/components/filePreview/index.vue'
-
-const props = defineProps({
- // documentId 閫氳繃 open 浜嬩欢浼犲叆锛屼笉闇�瑕佷綔涓� props
-})
-
-const emit = defineEmits(['update:attachments'])
-
-const dialogVisible = ref(false)
-const loading = ref(false)
-const fileList = ref([])
-const uploadRef = ref()
-const filePreviewRef = ref()
-const currentDocumentId = ref('') // 鍐呴儴绠$悊褰撳墠鏂囨。ID
-
-// 涓婁紶閰嶇疆
-const uploadUrl = import.meta.env.VITE_APP_BASE_API + "/file/upload"
-const uploadHeaders = computed(() => ({
- Authorization: "Bearer " + getToken()
-}))
-
-// 鎵撳紑寮规
-const open = (attachments = [], documentId = '') => {
- dialogVisible.value = true
- currentDocumentId.value = documentId // 璁剧疆褰撳墠鏂囨。ID
- // 濡傛灉鏈夋枃妗D锛屽垯鍔犺浇闄勪欢鍒楄〃
- if (documentId) {
- loadAttachmentList(documentId)
- } else {
- fileList.value = attachments || []
- // total.value = fileList.value.length // Removed total.value
- }
- // currentPage.value = 1 // Removed currentPage.value
-}
-
-// 鍔犺浇闄勪欢鍒楄〃
-const loadAttachmentList = async (documentId) => {
- try {
- loading.value = true
- const params = {
- page: 1, // Always load from page 1
- size: 1000, // Load all for now
- documentationId: documentId
- }
-
- const res = await getDocumentationFileList(params)
- if (res.code === 200) {
- const records = res.data
-
- // 杞崲鏁版嵁鏍煎紡
- fileList.value = records.map(item => ({
- id: item.id,
- name: item.name,
- size: item.fileSize,
- url: item.url,
- uploadTime: item.createTime || item.uploadTime,
- status: 'success',
- uid: item.id
- }))
-
- // total.value = totalCount // Removed total.value
- } else {
- ElMessage.error(res.msg || '鑾峰彇闄勪欢鍒楄〃澶辫触')
- fileList.value = []
- // total.value = 0 // Removed total.value
- }
- } catch (error) {
- console.error('鑾峰彇闄勪欢鍒楄〃澶辫触:', error)
- ElMessage.error('鑾峰彇闄勪欢鍒楄〃澶辫触')
- fileList.value = []
- // total.value = 0 // Removed total.value
- } finally {
- loading.value = false
- }
-}
-
-// 鍏抽棴寮规
-const handleClose = () => {
- dialogVisible.value = false
- emit('update:attachments', fileList.value)
-}
-
-// 鏂囦欢涓婁紶鍓嶆牎楠�
-const handleBeforeUpload = (file) => {
- // 妫�鏌ユ枃浠跺ぇ灏忥紙50MB锛�
- const isLt50M = file.size / 1024 / 1024 < 50
- if (!isLt50M) {
- ElMessage.error('鏂囦欢澶у皬涓嶈兘瓒呰繃50MB!')
- return false
- }
-
- // 妫�鏌ユ枃浠剁被鍨�
- const allowedTypes = [
- 'application/msword',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'application/vnd.ms-excel',
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'application/vnd.ms-powerpoint',
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
- 'application/pdf',
- 'text/plain',
- 'text/xml',
- 'image/jpeg',
- 'image/png',
- 'image/gif',
- 'image/bmp',
- 'application/x-rar-compressed',
- 'application/zip',
- 'application/x-7z-compressed'
- ]
-
- if (!allowedTypes.includes(file.type)) {
- ElMessage.error('涓嶆敮鎸佺殑鏂囦欢绫诲瀷!')
- return false
- }
-
- return true
-}
-
-// 鏂囦欢涓婁紶鎴愬姛
-const handleUploadSuccess = (response, file, fileList) => {
- console.log('鏂囦欢涓婁紶鎴愬姛鍝嶅簲:', response);
- console.log('鏂囦欢淇℃伅:', file);
-
- if (response.code === 200) {
- // 鏋勫缓闄勪欢鏁版嵁 - 纭繚姝g‘鑾峰彇URL
- const attachmentData = {
- name: file.name,
- url: response.data.url || response.data.path || response.data.tempPath || file.url,
- fileSize: file.size,
- documentationId: currentDocumentId.value
- };
-
- console.log('鏋勫缓鐨勯檮浠舵暟鎹�:', attachmentData);
-
- // 璋冪敤淇濆瓨闄勪欢鎺ュ彛
- saveAttachment(attachmentData, file, fileList);
- } else {
- ElMessage.error(response.msg || '鏂囦欢涓婁紶澶辫触')
- }
-}
-
-// 淇濆瓨闄勪欢淇℃伅
-const saveAttachment = async (attachmentData, file, fileList) => {
- try {
- console.log('寮�濮嬩繚瀛橀檮浠讹紝鏁版嵁:', attachmentData);
-
- // 纭繚URL瀛楁瀛樺湪涓旀湁鏁�
- if (!attachmentData.url) {
- console.error('闄勪欢URL涓虹┖锛屾棤娉曚繚瀛�');
- ElMessage.error('鏂囦欢URL鑾峰彇澶辫触锛屾棤娉曚繚瀛橀檮浠�');
- return;
- }
-
- const res = await addDocumentationFile(attachmentData);
- console.log('淇濆瓨闄勪欢鎺ュ彛鍝嶅簲:', res);
-
- if (res.code === 200) {
- const newFile = {
- id: res.data.id || Date.now(),
- name: attachmentData.name,
- size: attachmentData.fileSize,
- url: attachmentData.url,
- uploadTime: new Date().toISOString(),
- status: 'success',
- uid: file.uid
- }
-
- console.log('鍒涘缓鐨勬柊鏂囦欢瀵硅薄:', newFile);
- fileList.push(newFile)
- ElMessage.success('鏂囦欢涓婁紶骞朵繚瀛樻垚鍔�')
-
- // 淇濆瓨鎴愬姛鍚庡埛鏂伴檮浠跺垪琛�
- if (currentDocumentId.value) {
- await loadAttachmentList(currentDocumentId.value);
- }
- } else {
- ElMessage.error(res.msg || '淇濆瓨闄勪欢淇℃伅澶辫触')
- // 淇濆瓨澶辫触鏃剁Щ闄ゆ枃浠�
- const index = fileList.findIndex(item => item.uid === file.uid)
- if (index > -1) {
- fileList.splice(index, 1)
- }
- }
- } catch (error) {
- console.error('淇濆瓨闄勪欢澶辫触:', error)
- ElMessage.error('淇濆瓨闄勪欢淇℃伅澶辫触')
- // 淇濆瓨澶辫触鏃剁Щ闄ゆ枃浠�
- const index = fileList.findIndex(item => item.uid === file.uid)
- if (index > -1) {
- fileList.splice(index, 1)
- }
- }
-}
-
-// 鏂囦欢涓婁紶澶辫触
-const handleUploadError = (error, file, fileList) => {
- console.error('鏂囦欢涓婁紶澶辫触:', error);
- console.error('澶辫触鐨勬枃浠�:', file);
- console.error('褰撳墠鏂囦欢鍒楄〃:', fileList);
-
- ElMessage.error('鏂囦欢涓婁紶澶辫触锛岃妫�鏌ョ綉缁滆繛鎺ユ垨鏂囦欢鏍煎紡')
-}
-
-// 绉婚櫎鏂囦欢
-const handleRemove = (file, fileList) => {
- const index = fileList.findIndex(item => item.uid === file.uid)
- if (index > -1) {
- fileList.splice(index, 1)
- // total.value = fileList.length // Removed total.value
- }
-}
-
-// 鍒犻櫎鏂囦欢
-const removeFile = (file) => {
- ElMessageBox.confirm(`纭畾瑕佸垹闄ゆ枃浠� "${file.name}" 鍚楋紵`, '鍒犻櫎纭', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(async () => {
- try {
- // 璋冪敤鍒犻櫎鎺ュ彛
- const res = await deleteDocumentationFile([file.id]);
- if (res.code === 200) {
- // 浠庢湰鍦板垪琛ㄤ腑绉婚櫎
- const index = fileList.value.findIndex(item => item.id === file.id);
- if (index > -1) {
- fileList.value.splice(index, 1);
- }
- ElMessage.success('鍒犻櫎鎴愬姛');
-
- // 濡傛灉鏈夋枃妗D锛屽埛鏂伴檮浠跺垪琛�
- if (currentDocumentId.value) {
- await loadAttachmentList(currentDocumentId.value);
- }
- } else {
- ElMessage.error(res.msg || '鍒犻櫎澶辫触');
- }
- } catch (error) {
- console.error('鍒犻櫎闄勪欢澶辫触:', error);
- ElMessage.error('鍒犻櫎闄勪欢澶辫触');
- }
- }).catch(() => {
- // 鍙栨秷鍒犻櫎
- })
-}
-
-// 棰勮鏂囦欢
-const previewFile = (file) => {
- if (file.url) {
- filePreviewRef.value.open(file.url)
- } else {
- ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曢瑙�')
- }
-}
-
-// 涓嬭浇鏂囦欢
-const downloadFile = (file) => {
- if (file.url) {
- // 鍒涘缓涓嬭浇閾炬帴
- const link = document.createElement('a')
- link.href = file.url
- link.download = file.name
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
- ElMessage.success('寮�濮嬩笅杞芥枃浠�')
- } else {
- ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曚笅杞�')
- }
-}
-
-// 鏍煎紡鍖栨枃浠跺ぇ灏�
-const formatFileSize = (bytes) => {
- if (bytes === 0) return '0 B'
- const k = 1024
- const sizes = ['B', 'KB', 'MB', 'GB']
- const i = Math.floor(Math.log(bytes) / Math.log(k))
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
-}
-
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (dateString) => {
- if (!dateString) return ''
- const date = new Date(dateString)
- return date.toLocaleString('zh-CN', {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit'
- })
-}
-
-// 娴嬭瘯鏂囦欢涓婁紶
-const testUpload = () => {
- console.log('褰撳墠鏂囨。ID:', currentDocumentId.value);
- console.log('涓婁紶URL:', uploadUrl);
- console.log('涓婁紶Headers:', uploadHeaders.value);
-}
-
-// 鏆撮湶鏂规硶
-defineExpose({
- open,
- loadAttachmentList,
- testUpload
-})
-</script>
-
-<style scoped>
-.attachment-manager {
- padding: 20px;
-}
-
-.upload-section {
- margin-bottom: 20px;
- padding: 20px;
- background-color: #f8f9fa;
- border-radius: 8px;
- border: 2px dashed #d9d9d9;
-}
-
-.upload-section:hover {
- border-color: #409eff;
-}
-
-.attachment-list {
- margin-bottom: 20px;
-}
-
-.el-upload__tip {
- margin-top: 10px;
- color: #666;
- font-size: 12px;
- line-height: 1.5;
-}
-
-:deep(.el-upload) {
- width: 100%;
-}
-
-:deep(.el-upload-dragger) {
- width: 100%;
- height: 120px;
-}
-</style>
diff --git a/src/views/fileManagement/document/index.vue b/src/views/fileManagement/document/index.vue
deleted file mode 100644
index a0d824a..0000000
--- a/src/views/fileManagement/document/index.vue
+++ /dev/null
@@ -1,1416 +0,0 @@
-<template>
- <div class="app-container document-view">
- <div class="left">
- <div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
- clearable
- prefix-icon="Search"
- />
- <el-button
- type="primary"
- @click="openCategoryDia('addOne')"
- style="margin-left: 10px"
- >鏂板鍒嗙被</el-button
- >
- </div>
- <div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="categoryList"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- default-expand-all
- :default-expanded-keys="expandedKeys"
- :draggable="true"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'category' }"
- highlight-current
- node-key="id"
- style="
- height: calc(100vh - 190px);
- overflow-y: scroll;
- scrollbar-width: none;
- margin-top: 10px;
- "
- >
- <template #default="{ node, data }">
- <div class="custom-tree-node">
- <span class="tree-node-content">
- <el-icon class="orange-icon">
- <component :is="data.children && data.children.length > 0
- ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
- </el-icon>
- {{ data.category }}
- </span>
- <div>
- <el-button
- type="primary"
- link
- @click="openCategoryDia('edit', data)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="primary"
- link
- @click="openCategoryDia('addSub', data)"
- v-if="node.level < 2"
- >
- 娣诲姞瀛愬垎绫�
- </el-button>
- <el-button
- v-if="!node.childNodes.length"
- style="margin-left: 4px"
- type="danger"
- link
- @click="removeCategory(node, data)"
- >
- 鍒犻櫎
- </el-button>
- </div>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- <div class="right">
- <div style="margin-bottom: 10px" v-if="isShowButton">
- <el-button type="primary" @click="openDocumentDia('add')">
- 鏂板鏂囨。
- </el-button>
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- :disabled="selectedRows.length === 0"
- >
- 鍒犻櫎 ({{ selectedRows.length }})
- </el-button>
- </div>
- <div class="table-container">
-
- <!-- PIMTable 缁勪欢 -->
- <PIMTable
- :table-data="documentList"
- :column="tableColumns"
- :is-selection="true"
- :border="true"
- :table-loading="tableLoading"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- layout: 'total, sizes, prev, pager, next, jumper'
- }"
- @selection-change="handleSelectionChange"
- @pagination="handlePagination"
- />
- </div>
- </div>
-
- <!-- 鍒嗙被鏂板/淇敼瀵硅瘽妗� -->
- <el-dialog v-model="categoryDia" title="鍒嗙被" width="400px" @keydown.enter.prevent>
- <el-form
- :model="categoryForm"
- label-width="140px"
- label-position="top"
- :rules="categoryRules"
- ref="categoryFormRef"
- >
- <el-row :gutter="30">
- <el-col :span="24" v-if="categoryOperationType === 'addSub'">
- <el-form-item label="鐖跺垎绫伙細" prop="parentName">
- <el-input
- v-model="categoryForm.parentName"
- placeholder="鐖跺垎绫诲悕绉�"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="鍒嗙被鍚嶇О锛�" prop="category">
- <el-input
- v-model="categoryForm.category"
- placeholder="璇疯緭鍏ュ垎绫诲悕绉�"
- clearable
- @keydown.enter.prevent
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitCategoryForm">纭</el-button>
- <el-button @click="closeCategoryDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
-<el-dialog
- v-model="qrCodeDialogVisible"
- title="鏂囨。浜岀淮鐮�"
- width="400px"
- @close="closeQrCodeDialog"
- >
- <div class="qr-code-container">
- <div v-if="qrCodeUrl" class="qr-code-image">
- <img :src="qrCodeUrl" alt="鏂囨。浜岀淮鐮�" class="qr-image" />
- <div class="qr-info">
- <p><strong>鏂囨。鍚嶇О锛�</strong>{{ currentDocument.docName }}</p>
- <p><strong>鏂囨。缂栧彿锛�</strong>{{ currentDocument.docNumber }}</p>
- </div>
- </div>
- <div v-else class="qr-loading">
- <el-icon class="is-loading"><Loading /></el-icon>
- <p>姝e湪鐢熸垚浜岀淮鐮�...</p>
- </div>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeQrCodeDialog">鍏抽棴</el-button>
- <el-button
- v-if="qrCodeUrl"
- type="primary"
- @click="downloadQRCode"
- icon="Download"
- >
- 涓嬭浇浜岀淮鐮�
- </el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 鏂囨。鏂板/淇敼瀵硅瘽妗� -->
- <el-dialog
- v-model="documentDia"
- :title="documentOperationType === 'add' ? '鏂板鏂囨。' : '缂栬緫鏂囨。'"
- width="600px"
- @close="closeDocumentDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="documentForm"
- label-width="140px"
- label-position="top"
- :rules="documentRules"
- ref="documentFormRef"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。鍚嶇О锛�" prop="docName">
- <el-input v-model="documentForm.docName" placeholder="璇疯緭鍏�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="骞村害锛�" prop="year">
- <el-date-picker
- v-model="documentForm.year"
- type="year"
- value-format="YYYY"
- format="YYYY"
- placeholder="閫夋嫨骞村害"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。缂栧彿锛�" prop="docNumber">
- <el-input v-model="documentForm.docNumber" placeholder="璇疯緭鍏�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璐d换浜猴細" prop="responsiblePerson">
- <el-input v-model="documentForm.responsiblePerson" placeholder="璇疯緭鍏�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。鍒嗙被锛�" prop="documentClassificationId">
- <el-select v-model="documentForm.documentClassificationId" placeholder="璇烽�夋嫨鏂囨。鍒嗙被" style="width: 100%">
- <el-option
- v-for="item in categoryList"
- :key="item.id"
- :label="item.category"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏂囨。鏀剧疆浣嶇疆锛�" prop="warehouseGoodsShelvesRowcolId">
- <el-tree-select
- v-model="documentForm.warehouseGoodsShelvesRowcolId"
- :data="locationTree"
- placeholder="璇烽�夋嫨鏂囦欢鏀剧疆浣嶇疆"
- clearable
- check-strictly
- :render-after-expand="false"
- :props="{ children: 'children', label: 'label', value: 'value' }"
- style="width: 100%"
- @change="handleLocationChange"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。鏃ユ湡锛�" prop="docData">
- <el-date-picker
- v-model="documentForm.docData"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- placeholder="閫夋嫨鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="淇濈鏈熼檺锛�" prop="retentionPeriod">
- <el-select v-model="documentForm.retentionPeriod" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in retention_period"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="淇濆瘑绾у埆锛�" prop="securityLevel">
- <el-select v-model="documentForm.securityLevel" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in confidentiality_level"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍒嗘暟锛�" prop="copyCount">
- <el-input v-model="documentForm.copyCount" placeholder="璇疯緭鍏�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="椤垫暟锛�" prop="pageCount">
- <el-input v-model="documentForm.pageCount" placeholder="璇疯緭鍏�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏂囨。绫诲埆锛�" prop="docCategory">
- <el-select v-model="documentForm.docCategory" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in document_type"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。绉嶇被锛�" prop="docType">
- <el-select v-model="documentForm.docType" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in document_categories"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绱ф�ョ▼搴︼細" prop="urgencyLevel">
- <el-select v-model="documentForm.urgencyLevel" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in document_urgency"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。鐘舵�侊細" prop="docStatus">
- <el-select v-model="documentForm.docStatus" placeholder="璇烽�夋嫨">
- <el-option
- v-for="item in document_status"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞锛�" prop="remark">
- <el-input
- v-model="documentForm.remark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitDocumentForm">纭</el-button>
- <el-button @click="closeDocumentDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <AttachmentManager ref="attachmentManagerRef" />
- </div>
- </template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance, toRefs, watch } from "vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import { ArrowRight, Folder, FolderOpened, Tickets, Document } from '@element-plus/icons-vue';
-import PIMTable from '@/components/PIMTable/PIMTable.vue';
-import { getToken } from "@/utils/auth";
-import { getCategoryTree, addCategory, updateCategory, deleteCategory, getDocumentList, addDocument, updateDocument, deleteDocument, getDocumentDetail, searchDocument, getWarehouseStructure } from '@/api/fileManagement/document'
-import { getWarehouseList } from '@/api/fileManagement/bookshelf'
-import AttachmentManager from './attachmentManager.vue'
-import { useDict } from '@/utils/dict'
-
-const { proxy } = getCurrentInstance();
-const tree = ref(null);
-const containerRef = ref(null);
-// 瀵煎叆qrcode搴�
-import QRCode from 'qrcode'
-import { Loading, Download } from '@element-plus/icons-vue'
-// 浣跨敤瀛楀吀鏁版嵁
-const { confidentiality_level, document_urgency, document_status, document_type, document_categories, retention_period } = useDict('confidentiality_level', 'document_urgency', 'document_status', 'document_type', 'document_categories', 'retention_period')
-
-// 鐩戝惉瀛楀吀鏁版嵁鍙樺寲
-watch([confidentiality_level, document_urgency, document_status, document_type, document_categories, retention_period], () => {
- // 瀛楀吀鏁版嵁宸叉洿鏂�
-}, { immediate: true, deep: true });
-
-const categoryDia = ref(false);
-const documentDia = ref(false);
-const categoryOperationType = ref("");
-const documentOperationType = ref("");
-const search = ref("");
-const currentId = ref("");
-const currentParentId = ref("");
-const treeLoad = ref(false);
-const categoryList = ref([]);
-const expandedKeys = ref([]);
-const documentList = ref([]);
-const isShowButton = ref(false);
-const selectedRows = ref([]);
-const selectAll = ref(false);
-const isIndeterminate = ref(false);
-const tableLoading = ref(false);
-const attachmentManagerRef = ref(null);
-
-// 鏂囦欢涓婁紶閰嶇疆
-const upload = reactive({
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-// 浣嶇疆鏍戞暟鎹�
-const locationTree = ref([]);
-
-// 浜岀淮鐮佺浉鍏冲彉閲�
-const qrCodeDialogVisible = ref(false)
-const qrCodeUrl = ref('')
-const currentDocument = ref({})
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumns = ref([
- { label: '鏂囨。鍚嶇О', prop: 'docName', width: '200' },
- { label: '鏂囨。缂栧彿', prop: 'docNumber', width: '120' },
- { label: '骞村害', prop: 'year', width: '80' },
- { label: '璐d换浜�', prop: 'responsiblePerson', width: '100' },
- {
- label: '鏂囨。鏀剧疆浣嶇疆',
- prop: 'warehouseGoodsShelvesRowcolId',
- width: '150',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- return getLocationName(params);
- }
- },
- { label: '鏂囨。鏃ユ湡', prop: 'docData', width: '120' },
- {
- label: '淇濈鏈熼檺',
- prop: 'retentionPeriod',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!retention_period.value || retention_period.value.length === 0) {
- return params;
- }
- const item = retention_period.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!retention_period.value || retention_period.value.length === 0) {
- return 'info';
- }
- const item = retention_period.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- {
- label: '淇濆瘑绾у埆',
- prop: 'securityLevel',
- width: '80',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!confidentiality_level.value || confidentiality_level.value.length === 0) {
- return params;
- }
- const item = confidentiality_level.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!confidentiality_level.value || confidentiality_level.value.length === 0) {
- return 'info';
- }
- const item = confidentiality_level.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- { label: '鍒嗘暟', prop: 'copyCount', width: '80' },
- { label: '椤垫暟', prop: 'pageCount', width: '80' },
- {
- label: '鏂囨。绫诲埆',
- prop: 'docCategory',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!document_type.value || document_type.value.length === 0) {
- return params;
- }
- const item = document_type.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!document_type.value || document_type.value.length === 0) {
- return 'info';
- }
- const item = document_type.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- {
- label: '鏂囨。绉嶇被',
- prop: 'docType',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!document_categories.value || document_categories.value.length === 0) {
- return params;
- }
- const item = document_categories.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!document_categories.value || document_categories.value.length === 0) {
- return 'info';
- }
- const item = document_categories.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- {
- label: '绱ф�ョ▼搴�',
- prop: 'urgencyLevel',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!document_urgency.value || document_urgency.value.length === 0) {
- return params;
- }
- const item = document_urgency.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!document_urgency.value || document_urgency.value.length === 0) {
- return 'info';
- }
- const item = document_urgency.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- {
- label: '鏂囨。鐘舵��',
- prop: 'docStatus',
- width: '100',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- if (!document_status.value || document_status.value.length === 0) {
- return params;
- }
- const item = document_status.value.find(item => item.value == params);
- return item ? item.label : params;
- },
- formatType: (params) => {
- if (params === null || params === undefined || params === '') return 'info';
- if (!document_status.value || document_status.value.length === 0) {
- return 'info';
- }
- const item = document_status.value.find(item => item.value == params);
- const validTypes = ['success', 'warning', 'danger', 'info'];
- return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info';
- }
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: '200',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openDocumentDia('edit', row)
- },
- },
- {
- name: "闄勪欢",
- type: "text",
- clickFun: (row) => {
- openAttachment(row)
- },
- },
- {
- name: "鐢熸垚浜岀淮鐮�",
- type: "text",
- clickFun: (row) => {
- generateQRCode(row)
- },
- },
- ],
- }
-]);
-// 鐢熸垚浜岀淮鐮�
-const generateQRCode = async (row) => {
- try {
- // 妫�鏌ュ繀瑕佸瓧娈�
- if (!row.docName || !row.docNumber) {
- ElMessage.warning('鏂囨。淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚浜岀淮鐮�')
- return
- }
-
- currentDocument.value = row
- qrCodeUrl.value = ''
- qrCodeDialogVisible.value = true
-
- // 鏋勫缓浜岀淮鐮佸唴瀹�
- // const qrContent = `${row.id}|${row.docName}|${row.docNumber}`
- const qrContent = `${row.id}`
- // 鐢熸垚浜岀淮鐮�
- qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
- width: 256,
- margin: 2,
- color: {
- dark: '#000000',
- light: '#FFFFFF'
- },
- errorCorrectionLevel: 'M'
- })
-
- // ElMessage.success('浜岀淮鐮佺敓鎴愭垚鍔燂紒')
-
- } catch (error) {
- console.error('鐢熸垚浜岀淮鐮佸け璐�:', error)
- ElMessage.error('鐢熸垚浜岀淮鐮佸け璐ワ細' + error.message)
- qrCodeDialogVisible.value = false
- }
-}
-
-// 涓嬭浇浜岀淮鐮�
-const downloadQRCode = () => {
- if (!qrCodeUrl.value) {
- ElMessage.warning('璇峰厛鐢熸垚浜岀淮鐮�')
- return
- }
-
- const a = document.createElement('a')
- a.href = qrCodeUrl.value
- a.download = `${currentDocument.value.docName}_浜岀淮鐮乢${new Date().getTime()}.png`
- document.body.appendChild(a)
- a.click()
- document.body.removeChild(a)
- ElMessage.success('涓嬭浇鎴愬姛锛�')
-}
-
-// 鍏抽棴浜岀淮鐮佸脊绐�
-const closeQrCodeDialog = () => {
- qrCodeDialogVisible.value = false
- qrCodeUrl.value = ''
- currentDocument.value = {}
-}
-// 鍒嗙被琛ㄥ崟
-const categoryForm = reactive({
- category: "",
- parentId: "",
- parentName: "",
-});
-
-const categoryRules = reactive({
- category: [{ required: true, message: "璇疯緭鍏ュ垎绫诲悕绉�", trigger: "blur" }],
-});
-
-// 鏂囨。琛ㄥ崟
-const documentForm = reactive({
- id: "",
- documentClassificationId: "",
- docName: "",
- docNumber: "",
- year: "",
- responsiblePerson: "",
- warehouseGoodsShelvesRowcolId: "",
- docData: "",
- retentionPeriod: "",
- securityLevel: "",
- copyCount: "",
- pageCount: "",
- docCategory: "",
- docType: "",
- urgencyLevel: "",
- docStatus: "",
- remark: "",
- attachments: [], // 鏂板闄勪欢鏁扮粍
-});
-
-const documentRules = reactive({
- docName: [{ required: true, message: "璇疯緭鍏ユ枃妗e悕绉�", trigger: "blur" }],
- docNumber: [{ required: true, message: "璇疯緭鍏ユ枃妗g紪鍙�", trigger: "blur" }],
- year: [{ required: true, message: "璇烽�夋嫨骞村害", trigger: "change" }],
- documentClassificationId: [{ required: true, message: "璇烽�夋嫨鏂囨。鍒嗙被", trigger: "change" }],
- warehouseGoodsShelvesRowcolId: [{ required: true, message: "璇烽�夋嫨鏂囨。鏀剧疆浣嶇疆", trigger: "change" }],
-});
-
-// 鍒嗛〉鐩稿叧
-const pagination = reactive({
- currentPage: 1,
- pageSize: 10,
- total: 0,
-});
-
-// 鍒濆鍖栧垎绫绘爲鏁版嵁
-const initCategoryTree = async() => {
- try {
- treeLoad.value = true;
- const res = await getCategoryTree();
- if (res.code === 200) {
- categoryList.value = res.data || [];
-
- // 璁剧疆灞曞紑鐨勮妭鐐�
- expandedKeys.value = [];
- categoryList.value.forEach((item) => {
- if (item.id) {
- expandedKeys.value.push(item.id);
- }
- });
- } else {
- ElMessage.error(res.msg || "鑾峰彇鍒嗙被鏍戝け璐�");
- }
- } catch (error) {
- ElMessage.error("鑾峰彇鍒嗙被鏍戝け璐ワ紝璇烽噸璇�");
- } finally {
- treeLoad.value = false;
- }
-};
-
-// 鍒濆鍖栦粨搴撲綅缃暟鎹�
-const initLocationTree = async() => {
- try {
- const res = await getWarehouseList();
- if (res.code === 200) {
- // 杞崲鏁版嵁鏍煎紡锛岄�傞厤el-tree-select缁勪欢
- locationTree.value = transformWarehouseData(res.data || []);
- } else {
- ElMessage.error(res.msg || "鑾峰彇浠撳簱浣嶇疆澶辫触");
- }
- } catch (error) {
- ElMessage.error("鑾峰彇浠撳簱浣嶇疆澶辫触锛岃閲嶈瘯");
- }
-};
-
-// 杞崲浠撳簱鏁版嵁鏍煎紡
-const transformWarehouseData = (data) => {
- return data.map(item => ({
- id: item.id,
- label: item.name || item.warehouseName || item.label,
- value: item.id,
- children: item.children ? transformWarehouseData(item.children) : []
- }));
-};
-
-// 鏍规嵁ID鑾峰彇浣嶇疆鍚嶇О
-const getLocationName = (locationId) => {
- if (!locationId || !locationTree.value || locationTree.value.length === 0) {
- return locationId || '-';
- }
-
- const findLocation = (tree, id) => {
- for (let item of tree) {
- if (item.value === locationId || item.id === locationId) {
- return item.label;
- }
- if (item.children && item.children.length > 0) {
- const result = findLocation(item.children, id);
- if (result) return result;
- }
- }
- return null;
- };
-
- const locationName = findLocation(locationTree.value, locationId);
- return locationName || locationId;
-};
-
-// 杩囨护鍒嗙被鏍�
-const searchFilter = () => {
- if (proxy.$refs.tree) {
- proxy.$refs.tree.filter(search.value);
- }
-};
-
-// 鎵撳紑鍒嗙被寮规
-const openCategoryDia = (type, data) => {
- categoryOperationType.value = type;
- categoryDia.value = true;
- categoryForm.category = "";
- categoryForm.parentId ="";
- categoryForm.parentName = "";
-
- if (type === "edit") {
- categoryForm.category = data.category;
- // 淇濆瓨褰撳墠缂栬緫鐨勫垎绫籌D
- currentId.value = data.id;
- } else if (type === "addSub") {
- categoryForm.parentId = data.id;
- categoryForm.parentName = data.category;
- }
-};
-
-// 鎵撳紑鏂囨。寮规
-const openDocumentDia = (type, data) => {
- documentOperationType.value = type;
- documentDia.value = true;
-
- if (type === "edit") {
- // 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
- Object.assign(documentForm, data);
- documentForm.retentionPeriod = String(documentForm.retentionPeriod)
- documentForm.securityLevel = String(documentForm.securityLevel)
- documentForm.docCategory = String(documentForm.docCategory)
- documentForm.docType = String(documentForm.docType)
- documentForm.urgencyLevel = String(documentForm.urgencyLevel)
- documentForm.docStatus = String(documentForm.docStatus)
-
- // 鍔犺浇闄勪欢淇℃伅
- if (data.attachments) {
- documentForm.attachments = [...data.attachments];
- } else {
- documentForm.attachments = [];
- }
- } else {
- // 鏂板妯″紡锛屾竻绌鸿〃鍗�
- Object.keys(documentForm).forEach(key => {
- documentForm[key] = "";
- });
- documentForm.attachments = []; // 鏂板妯″紡涓嬩篃娓呯┖闄勪欢
- // 璁剧疆榛樿鍊� - 浣跨敤瀛楀吀鏁版嵁鐨勭涓�涓�夐」浣滀负榛樿鍊�
- if (document_status.value && document_status.value.length > 0) {
- documentForm.docStatus = document_status.value[0].value;
- }
- if (document_urgency.value && document_urgency.value.length > 0) {
- documentForm.urgencyLevel = document_urgency.value[0].value;
- }
- }
-};
-
-// 鎻愪氦鍒嗙被琛ㄥ崟
-const submitCategoryForm = () => {
- proxy.$refs.categoryFormRef.validate(async (valid) => {
- if (valid) {
- try {
- if (categoryOperationType.value === "addSub") {
- // 娣诲姞瀛愬垎绫�
- const res = await addCategory({
- category: categoryForm.category,
- parentId: categoryForm.parentId
- });
- if (res.code === 200) {
- ElMessage.success("娣诲姞瀛愬垎绫绘垚鍔�");
- // 閲嶆柊鍔犺浇鍒嗙被鏍�
- await initCategoryTree();
- } else {
- ElMessage.error(res.msg || "娣诲姞瀛愬垎绫诲け璐�");
- }
- } else if (categoryOperationType.value === "edit") {
- // 缂栬緫鍒嗙被
- const res = await updateCategory({
- id: currentId.value,
- category: categoryForm.category
- });
- if (res.code === 200) {
- ElMessage.success("缂栬緫鍒嗙被鎴愬姛");
- // 閲嶆柊鍔犺浇鍒嗙被鏍�
- await initCategoryTree();
- } else {
- ElMessage.error(res.msg || "缂栬緫鍒嗙被澶辫触");
- }
- } else {
- // 鏂板椤剁骇鍒嗙被
- const res = await addCategory({
- category: categoryForm.category,
- parentId: null
- });
- if (res.code === 200) {
- ElMessage.success("鏂板鍒嗙被鎴愬姛");
- // 閲嶆柊鍔犺浇鍒嗙被鏍�
- await initCategoryTree();
- } else {
- ElMessage.error(res.msg || "鏂板鍒嗙被澶辫触");
- }
- }
-
- closeCategoryDia();
- } catch (error) {
- ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯");
- }
- }
- });
-};
-
-// 鍏抽棴鍒嗙被寮规
-const closeCategoryDia = () => {
- proxy.$refs.categoryFormRef.resetFields();
- categoryForm.parentId = "";
- categoryForm.parentName = "";
- categoryDia.value = false;
-};
-
-// 鍒犻櫎鍒嗙被
-const removeCategory = (node, data) => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(async () => {
- try {
- const res = await deleteCategory([data.id]);
- if (res.code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- // 閲嶆柊鍔犺浇鍒嗙被鏍�
- await initCategoryTree();
- } else {
- ElMessage.error(res.msg || "鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- })
- .catch(() => {
- ElMessage("宸插彇娑�");
- });
-};
-
-// 閫夋嫨鍒嗙被
-const handleNodeClick = (val, node, el) => {
- // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
- isShowButton.value = true;
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
-
- // 娓呯┖閫夋嫨鐘舵��
- selectedRows.value = [];
- selectAll.value = false;
- isIndeterminate.value = false;
-
- // 閲嶇疆鍒嗛〉
- pagination.currentPage = 1;
- pagination.total = 0;
-
- // 鍔犺浇鏂囨。鍒楄〃
- if (isShowButton.value) {
- loadDocumentList();
- } else {
- // 濡傛灉涓嶆槸鍙跺瓙鑺傜偣锛屾竻绌烘枃妗e垪琛�
- documentList.value = [];
- }
-};
-
-// 鎻愪氦鏂囨。琛ㄥ崟
-const submitDocumentForm = () => {
- proxy.$refs.documentFormRef.validate(async (valid) => {
- if (valid) {
- try {
- // 鏋勫缓鎻愪氦鏁版嵁
- const submitData = {
- ...documentForm,
- // 璁剧疆褰撳墠閫変腑鐨勫垎绫籌D
- documentClassificationId: currentId.value || documentForm.documentClassificationId,
- // 娣诲姞闄勪欢淇℃伅
- // attachments: documentForm.attachments
- };
-
- if (documentOperationType.value === "edit") {
- // 缂栬緫妯″紡锛屾洿鏂扮幇鏈夋暟鎹�
- const res = await updateDocument(submitData);
- if (res.code === 200) {
- ElMessage.success("缂栬緫鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囨。鍒楄〃
- await loadDocumentList();
- // 鍒锋柊闄勪欢鍒楄〃
- if (attachmentManagerRef.value && documentForm.id) {
- attachmentManagerRef.value.loadAttachmentList(documentForm.id);
- }
- } else {
- ElMessage.error(res.msg || "缂栬緫澶辫触");
- }
- } else {
- // 鏂板妯″紡锛屾坊鍔犳柊鏁版嵁
- const res = await addDocument(submitData);
- if (res.code === 200) {
- ElMessage.success("鏂板鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囨。鍒楄〃
- await loadDocumentList();
- // 鍒锋柊闄勪欢鍒楄〃
- if (attachmentManagerRef.value && res.data && res.data.id) {
- attachmentManagerRef.value.loadAttachmentList(res.data.id);
- }
- } else {
- ElMessage.error(res.msg || "鏂板澶辫触");
- }
- }
- closeDocumentDia();
- } catch (error) {
- ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯");
- }
- }
- });
-};
-
-// 鍏抽棴鏂囨。寮规
-const closeDocumentDia = () => {
- proxy.$refs.documentFormRef.resetFields();
- documentDia.value = false;
- // 娓呯┖琛ㄥ崟鏁版嵁
- Object.keys(documentForm).forEach(key => {
- documentForm[key] = "";
- });
- documentForm.attachments = []; // 鍏抽棴寮规鏃朵篃娓呯┖闄勪欢
-};
-
-// 澶勭悊浣嶇疆閫夋嫨鍙樺寲
-const handleLocationChange = (value) => {
- if (value) {
- // 妫�鏌ラ�夋嫨鐨勬槸鍚︿负鍙跺瓙鑺傜偣
- const isLeafNode = checkIfLeafNode(locationTree.value, value);
- if (!isLeafNode) {
- ElMessage.warning("璇烽�夋嫨鏈�搴曞眰鐨勪綅缃紙濡傦細鏌滃眰锛�");
- documentForm.warehouseGoodsShelvesRowcolId = "";
- return;
- }
- }
-};
-
-// 妫�鏌ユ槸鍚︿负鍙跺瓙鑺傜偣
-const checkIfLeafNode = (tree, value) => {
- for (let item of tree) {
- if (item.value === value || item.id === value) {
- // 濡傛灉娌℃湁瀛愯妭鐐癸紝鍒欎负鍙跺瓙鑺傜偣
- return !item.children || item.children.length === 0;
- }
- if (item.children && item.children.length > 0) {
- const result = checkIfLeafNode(item.children, value);
- if (result !== null) {
- return result;
- }
- }
- }
- return null;
-};
-
-// 鍒犻櫎鏂囨。
-const handleDelete = () => {
- if (selectedRows.value.length > 0) {
- ElMessageBox.confirm(`纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉¤褰曞悧锛焋, "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(async () => {
- try {
- const selectedIds = selectedRows.value.map(row => row.id);
- const res = await deleteDocument(selectedIds);
- if (res.code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囨。鍒楄〃
- await loadDocumentList();
- } else {
- ElMessage.error(res.msg || "鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- })
- .catch(() => {
- ElMessage("宸插彇娑�");
- });
- } else {
- ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
- }
-};
-
-// PIMTable 閫夋嫨鍙樺寲浜嬩欢
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-
- // 鏇存柊鍏ㄩ�夌姸鎬�
- const selectedCount = selection.length;
- const totalCount = documentList.value.length;
-
- if (selectedCount === 0) {
- selectAll.value = false;
- isIndeterminate.value = false;
- } else if (selectedCount === totalCount) {
- selectAll.value = true;
- isIndeterminate.value = false;
- } else {
- selectAll.value = false;
- isIndeterminate.value = true;
- }
-};
-
-// 鍔犺浇鏂囨。鍒楄〃
-const loadDocumentList = async () => {
- try {
- tableLoading.value = true;
-
- // 鏋勫缓鏌ヨ鍙傛暟
- const query = {
- page: pagination.currentPage,
- size: pagination.pageSize,
- documentClassificationId:currentId.value
- };
-
- const res = await getDocumentList(query);
- if (res.code === 200) {
- documentList.value = res.data.records || [];
- pagination.total = res.data.total || 0;
- } else {
- ElMessage.error(res.msg || "鑾峰彇鏂囨。鍒楄〃澶辫触");
- documentList.value = [];
- pagination.total = 0;
- }
-
- // 閲嶇疆閫夋嫨鐘舵��
- selectedRows.value = [];
- selectAll.value = false;
- isIndeterminate.value = false;
- } catch (error) {
- ElMessage.error("鑾峰彇鏂囨。鍒楄〃澶辫触锛岃閲嶈瘯");
- documentList.value = [];
- pagination.total = 0;
- } finally {
- tableLoading.value = false;
- }
-};
-
-// 澶勭悊鍒嗛〉鍙樺寲
-const handlePagination = (current, size) => {
- pagination.currentPage = current;
- pagination.pageSize = size;
- loadDocumentList();
-};
-
-// 璋冪敤tree杩囨护鏂规硶
-const filterNode = (value, data, node) => {
- if (!value) {
- return true;
- }
- let val = value.toLowerCase();
- return chooseNode(val, data, node);
-};
-
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐�
-const chooseNode = (value, data, node) => {
- if (data.category && data.category.toLowerCase().indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- if (level === 1) {
- return false;
- }
- let parentData = node.parent;
- let index = 0;
- while (index < level - 1) {
- if (parentData.data.category && parentData.data.category.toLowerCase().indexOf(value) !== -1) {
- return true;
- }
- parentData = parentData.parent;
- index++;
- }
- return false;
-};
-
-// 鎵撳紑闄勪欢
-const openAttachment = (row) => {
- attachmentManagerRef.value.open([], row.id);
-};
-
-onMounted(() => {
- initCategoryTree();
- initLocationTree();
-
- // 涓嶅湪鍒濆鍖栨椂鍔犺浇鏂囨。鍒楄〃锛岀瓑寰呯敤鎴烽�夋嫨鍒嗙被鍚庡啀鍔犺浇
-});
-</script>
-
-<style scoped>
-.document-view {
- display: flex;
- height: 100%;
-}
-
-.left {
- width: 380px;
- padding: 16px;
- background: #ffffff;
- border-right: 1px solid #e4e7ed;
-}
-
-.right {
- width: calc(100% - 380px);
- padding: 16px;
- background: #ffffff;
-}
-
-.custom-tree-node {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
-}
-
-.tree-node-content {
- display: flex;
- align-items: center;
- height: 100%;
-}
-
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px;
-}
-
-.table-container {
- background: #ffffff;
- border-radius: 8px;
- overflow: hidden;
- position: relative;
-}
-
-.add-row {
- display: flex;
- align-items: center;
- gap: 8px;
- background-color: #f5f7fa;
- cursor: pointer;
- transition: background-color 0.2s ease;
- padding: 12px 16px;
- margin-bottom: 16px;
- border-radius: 6px;
- border: 1px dashed #d9d9d9;
-}
-
-.add-row:hover {
- background-color: #e4e7ed;
- border-color: #c0c4cc;
-}
-
-.add-icon {
- color: #909399;
- font-size: 16px;
-}
-
-.add-row span {
- color: #606266;
- font-size: 14px;
-}
-
-.empty-data {
- text-align: center;
- color: #909399;
- padding: 40px;
- font-size: 14px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-.operation-column {
- position: absolute;
- right: 0;
- top: 0;
- width: 120px;
- background: #ffffff;
- border-left: 1px solid #e4e7ed;
- z-index: 1;
- box-shadow: -2px 0 4px rgba(0, 0, 0, 0.1);
-}
-
-.operation-header {
- height: 40px;
- line-height: 40px;
- text-align: center;
- background: #fafafa;
- border-bottom: 1px solid #e4e7ed;
- font-weight: 500;
- color: #606266;
-}
-
-.operation-cell {
- height: 40px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-bottom: 1px solid #e4e7ed;
-}
-
-.operation-cell:last-child {
- border-bottom: none;
-}
-
-.attachment-section {
- width: 100%;
-}
-
-.attachment-list {
- margin-bottom: 10px;
-}
-
-.attachment-item {
- display: flex;
- align-items: center;
- padding: 8px 12px;
- background-color: #f5f7fa;
- border-radius: 4px;
- margin-bottom: 8px;
-}
-
-.file-icon {
- margin-right: 8px;
- color: #409eff;
-}
-
-.file-name {
- flex: 1;
- color: #606266;
- font-size: 14px;
-}
-/* 浜岀淮鐮侀瑙堟牱寮� */
-.qr-code-container {
- text-align: center;
- padding: 20px;
-}
-
-.qr-code-image {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 20px;
-}
-
-.qr-image {
- max-width: 100%;
- height: auto;
- border: 2px solid #e0e0e0;
- border-radius: 8px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.qr-info {
- text-align: left;
- background: #f8f9fa;
- padding: 15px;
- border-radius: 8px;
- min-width: 300px;
-}
-
-.qr-info p {
- margin: 8px 0;
- color: #666;
- font-size: 14px;
-}
-
-.qr-loading {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 15px;
- padding: 40px 0;
-}
-
-.qr-loading .el-icon {
- font-size: 32px;
- color: #409EFF;
-}
-
-.qr-loading p {
- color: #666;
- margin: 0;
-}
-</style>
diff --git a/src/views/fileManagement/return/index.vue b/src/views/fileManagement/return/index.vue
deleted file mode 100644
index 34e733f..0000000
--- a/src/views/fileManagement/return/index.vue
+++ /dev/null
@@ -1,699 +0,0 @@
-<template>
- <div class="app-container return-view">
- <!-- 鏌ヨ鍖哄煙 -->
- <div class="search-container">
- <el-form :model="searchForm" :inline="true" class="search-form">
- <!-- <el-form-item label="鍊熼槄鐘舵�侊細">
- <el-select v-model="searchForm.borrowStatus" placeholder="璇烽�夋嫨鍊熼槄鐘舵��" clearable style="width: 150px">
- <el-option label="鍊熼槄" value="鍊熼槄" />
- <el-option label="褰掕繕" value="褰掕繕" />
- </el-select>
- </el-form-item> -->
- <el-form-item label="鍊熼槄浜猴細">
- <el-input
- v-model="searchForm.borrower"
- placeholder="璇疯緭鍏ュ�熼槄浜�"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item label="褰掕繕浜猴細">
- <el-input
- v-model="searchForm.returner"
- placeholder="璇疯緭鍏ュ綊杩樹汉"
- clearable
- style="width: 200px"
- />
- </el-form-item>
- <el-form-item label="褰掕繕鏃ユ湡鑼冨洿锛�">
- <el-date-picker
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 300px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">
- <el-icon><Search /></el-icon>
- 鏌ヨ
- </el-button>
- <el-button @click="handleReset">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- </el-form-item>
- <el-form-item style="margin-left: auto;">
- <el-button type="primary" @click="openReturnDia('add')">
- <el-icon><Plus /></el-icon>
- 鏂板褰掕繕
- </el-button>
- <el-button @click="handleOut">
- 瀵煎嚭
- </el-button>
- <el-button
- type="danger"
- @click="handleBatchDelete"
- :disabled="selectedRows.length === 0"
- >
- <el-icon><Delete /></el-icon>
- 鎵归噺鍒犻櫎 ({{ selectedRows.length }})
- </el-button>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 琛ㄦ牸鍖哄煙 -->
- <div class="table-container">
- <PIMTable
- :table-data="returnList"
- :column="tableColumns"
- :is-selection="true"
- :border="true"
- :table-loading="tableLoading"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- layout: 'total, sizes, prev, pager, next, jumper'
- }"
- @selection-change="handleSelectionChange"
- @pagination="handlePagination"
- />
- </div>
-
- <!-- 褰掕繕鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- v-model="returnDia"
- :title="returnOperationType === 'add' ? '鏂板褰掕繕' : '缂栬緫褰掕繕'"
- width="800px"
- @close="closeReturnDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="returnForm"
- label-width="140px"
- :rules="returnRules"
- ref="returnFormRef"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏂囨。锛�" prop="borrowId">
- <!-- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="flex: 1;" @change="handleDocumentChange">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select> -->
- <div style="display: flex; gap: 10px;">
- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="width: 120px;" @change="handleDocumentChange">
- <el-option
- v-for="item in documentList"
- :key="item.id"
- :label="item.docName || item.name"
- :value="item.id"
- />
- </el-select>
- <el-input
- v-model="scanContent"
- placeholder="鎵爜杈撳叆"
- style="flex: 1;"
- @input="handleScanContent"
- clearable
- />
- </div>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍊熼槄浜猴細" prop="borrower">
- <el-input v-model="returnForm.borrower" placeholder="鍊熼槄浜哄皢鏍规嵁鏂囨。閫夋嫨鑷姩甯﹀嚭" disabled />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="褰掕繕浜猴細" prop="returner">
- <el-input v-model="returnForm.returner" placeholder="璇疯緭鍏ュ綊杩樹汉" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰掕繕鏃ユ湡锛�" prop="returnDate">
- <el-date-picker
- v-model="returnForm.returnDate"
- type="date"
- placeholder="閫夋嫨褰掕繕鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="搴斿綊杩樻棩鏈燂細" prop="dueReturnDate">
- <el-date-picker
- v-model="returnForm.dueReturnDate"
- type="date"
- placeholder="搴斿綊杩樻棩鏈熷皢鏍规嵁鏂囨。閫夋嫨鑷姩甯﹀嚭"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞璇存槑锛�" prop="remark">
- <el-input
- v-model="returnForm.remark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ娉ㄨ鏄�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitReturnForm">纭</el-button>
- <el-button @click="closeReturnDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, getCurrentInstance } from "vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import { Search, Refresh, Plus, Delete } from '@element-plus/icons-vue';
-import PIMTable from '@/components/PIMTable/PIMTable.vue';
-import { getReturnListPage, returnDocument, deleteReturn, getDocumentList, updateBorrow, reventUpdate,getBorrowListByDocumentationId } from '@/api/fileManagement/return';
-
-const { proxy } = getCurrentInstance();
-
-// 鍝嶅簲寮忔暟鎹�
-const returnDia = ref(false);
-const returnOperationType = ref("");
-const tableLoading = ref(false);
-const returnList = ref([]);
-const selectedRows = ref([]);
-const documentList = ref([]); // 鏂囨。鍒楄〃
-const borrowInfoList = ref([]); // 鍊熼槄淇℃伅鍒楄〃
-const scanContent = ref(); // 鎵爜鍐呭
-
-// 鍒嗛〉鐩稿叧
-const pagination = reactive({
- currentPage: 1,
- pageSize: 10,
- total: 0,
-});
-
-// 鏌ヨ琛ㄥ崟
-const searchForm = reactive({
- borrowStatus: "",
- borrower: "",
- returner: "",
- dateRange: []
-});
-
-// 褰掕繕琛ㄥ崟
-const returnForm = reactive({
- id: "",
- borrowId: "",
- borrower: "",
- returner: "",
- borrowStatus: "",
- returnDate: "",
- dueReturnDate: "",
- remark: ""
-});
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const returnRules = reactive({
- borrowId: [{ required: true, message: "璇烽�夋嫨鏂囨。", trigger: "change" }],
- returner: [{ required: true, message: "璇疯緭鍏ュ綊杩樹汉", trigger: "blur" }],
- returnDate: [{ required: true, message: "璇烽�夋嫨褰掕繕鏃ユ湡", trigger: "change" }]
-});
-
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumns = ref([
- {
- label: '鏂囨。鍚嶇О',
- prop: 'docName',
- width: '200',
- },
- { label: '鍊熼槄浜�', prop: 'borrower' },
- { label: '褰掕繕浜�', prop: 'returner' },
- {
- label: '鍊熼槄鐘舵��',
- prop: 'borrowStatus',
- dataType: 'tag',
- formatData: (params) => {
- if (params === null || params === undefined || params === '') return '-';
- return params;
- },
- formatType: (params) => {
- if (params === '褰掕繕') return 'success';
- if (params === '鍊熼槄') return 'warning';
- return 'info';
- }
- },
- { label: '褰掕繕鏃ユ湡', prop: 'returnDate' },
- { label: '搴斿綊杩樻棩鏈�', prop: 'dueReturnDate' },
- { label: '澶囨敞', prop: 'remark', width: '150' },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: '150',
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openReturnDia('edit', row)
- },
- },
- {
- name: "鍒犻櫎",
- type: "text",
- clickFun: (row) => {
- handleDelete(row)
- },
- },
- ],
- }
-]);
-
-// 鍒濆鍖栨暟鎹�
-const initData = async () => {
- await Promise.all([
- loadDocumentList(),
- loadReturnList()
- ]);
-};
-
-// 鍔犺浇鏂囨。鍒楄〃
-const loadDocumentList = async () => {
- try {
- const res = await getDocumentList();
- if (res.code === 200) {
- documentList.value = res.data || [];
- } else {
- ElMessage.error(res.msg || "鑾峰彇鏂囨。鍒楄〃澶辫触");
- documentList.value = [];
- }
- } catch (error) {
- ElMessage.error("鑾峰彇鏂囨。鍒楄〃澶辫触锛岃閲嶈瘯");
- documentList.value = [];
- }
-};
-
-// 鍔犺浇褰掕繕鍒楄〃
-const loadReturnList = async () => {
- try {
- tableLoading.value = true;
-
- // 鏋勫缓鏌ヨ鍙傛暟
- const query = {
- page: pagination.currentPage,
- size: pagination.pageSize,
- borrowStatus: searchForm.borrowStatus || undefined,
- borrower: searchForm.borrower || undefined,
- returner: searchForm.returner || undefined,
- entryDateStart: searchForm.dateRange && searchForm.dateRange.length > 0 ? searchForm.dateRange[0] : undefined,
- entryDateEnd: searchForm.dateRange && searchForm.dateRange.length > 1 ? searchForm.dateRange[1] : undefined
- };
-
- // 绉婚櫎undefined鐨勫弬鏁�
- Object.keys(query).forEach(key => {
- if (query[key] === undefined) {
- delete query[key];
- }
- });
-
- const res = await getReturnListPage(query);
- if (res.code === 200) {
- returnList.value = res.data.records || [];
- pagination.total = res.data.total || 0;
- } else {
- ElMessage.error(res.msg || "鑾峰彇褰掕繕鍒楄〃澶辫触");
- returnList.value = [];
- pagination.total = 0;
- }
-
- // 閲嶇疆閫夋嫨鐘舵��
- selectedRows.value = [];
- } catch (error) {
- ElMessage.error("鑾峰彇褰掕繕鍒楄〃澶辫触锛岃閲嶈瘯");
- returnList.value = [];
- pagination.total = 0;
- } finally {
- tableLoading.value = false;
- }
-};
-
-// 鏌ヨ
-const handleSearch = () => {
- pagination.currentPage = 1;
- loadReturnList();
-};
-
-// 閲嶇疆鏌ヨ
-const handleReset = () => {
- searchForm.borrowStatus = "";
- searchForm.borrower = "";
- searchForm.returner = "";
- searchForm.dateRange = [];
- pagination.currentPage = 1;
- loadReturnList();
- ElMessage.success("鏌ヨ鏉′欢宸查噸缃�");
-};
-
-// 鎵撳紑褰掕繕寮规
-const openReturnDia = (type, data) => {
- returnOperationType.value = type;
- returnDia.value = true;
- scanContent.value = ''; // 娓呯┖鎵爜鍐呭
- borrowInfoList.value = []; // 娓呯┖鍊熼槄淇℃伅鍒楄〃
-
- if (type === "edit") {
- // 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
- Object.assign(returnForm, data);
- // 缂栬緫妯″紡涓嬶紝鏂囨。閫夋嫨鍚庤嚜鍔ㄥ~鍏呭�熼槄浜哄拰搴斿綊杩樻棩鏈�
- if (returnForm.borrowId) {
- handleDocumentChange(returnForm.borrowId);
- }
- } else {
- // 鏂板妯″紡锛屾竻绌鸿〃鍗�
- Object.keys(returnForm).forEach(key => {
- returnForm[key] = "";
- });
- // 璁剧疆榛樿鐘舵��
- returnForm.borrowStatus = "褰掕繕";
- // 璁剧疆褰撳墠鏃ユ湡涓哄綊杩樻棩鏈�
- returnForm.returnDate = new Date().toISOString().split('T')[0];
- }
-};
-
-// 鍏抽棴褰掕繕寮规
-const closeReturnDia = () => {
- proxy.$refs.returnFormRef.resetFields();
- returnDia.value = false;
- scanContent.value = ''; // 娓呯┖鎵爜鍐呭
- borrowInfoList.value = []; // 娓呯┖鍊熼槄淇℃伅鍒楄〃
-};
-
-// 鎻愪氦褰掕繕琛ㄥ崟
-const submitReturnForm = () => {
- proxy.$refs.returnFormRef.validate(async (valid) => {
- if (valid) {
- try {
- if (returnOperationType.value === "edit") {
- // 缂栬緫妯″紡锛岃皟鐢ㄥ綊杩樻洿鏂版帴鍙�
- const res = await reventUpdate({
- id: returnForm.id,
- documentationId: returnForm.documentationId,
- borrower: returnForm.borrower,
- returner: returnForm.returner,
- borrowStatus: returnForm.borrowStatus,
- returnDate: returnForm.returnDate,
- dueReturnDate: returnForm.dueReturnDate,
- remark: returnForm.remark
- });
-
- if (res.code === 200) {
- ElMessage.success("缂栬緫鎴愬姛");
- await loadReturnList();
- closeReturnDia();
- } else {
- ElMessage.error(res.msg || "缂栬緫澶辫触");
- }
- } else {
- // 鏂板妯″紡锛岃皟鐢ㄥ綊杩樻帴鍙�
- const res = await returnDocument({
- borrowId: returnForm.borrowId,
- borrower: returnForm.borrower,
- returner: returnForm.returner,
- borrowStatus: returnForm.borrowStatus,
- returnDate: returnForm.returnDate,
- dueReturnDate: returnForm.dueReturnDate,
- remark: returnForm.remark
- });
-
- if (res.code === 200) {
- ElMessage.success("鏂板鎴愬姛");
- await loadReturnList();
- closeReturnDia();
- } else {
- ElMessage.error(res.msg || "鏂板澶辫触");
- }
- }
- } catch (error) {
- ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯");
- }
- }
- });
-};
-
-// 鍒犻櫎褰掕繕璁板綍
-const handleDelete = (row) => {
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄よ繖鏉″綊杩樿褰曞悧锛焋,
- "鍒犻櫎鎻愮ず",
- {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }
- ).then(async () => {
- try {
- const res = await deleteReturn([row.id]);
- if (res.code === 200) {
- ElMessage.success("鍒犻櫎鎴愬姛");
- await loadReturnList();
- } else {
- ElMessage.error(res.msg || "鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- }).catch(() => {
- ElMessage.info("宸插彇娑堝垹闄�");
- });
-};
-
-// 鎵归噺鍒犻櫎
-const handleBatchDelete = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑璁板綍");
- return;
- }
-
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉″綊杩樿褰曞悧锛焋,
- "鎵归噺鍒犻櫎鎻愮ず",
- {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }
- ).then(async () => {
- try {
- const selectedIds = selectedRows.value.map(row => row.id);
- const res = await deleteReturn(selectedIds);
- if (res.code === 200) {
- ElMessage.success("鎵归噺鍒犻櫎鎴愬姛");
- await loadReturnList();
- } else {
- ElMessage.error(res.msg || "鎵归噺鍒犻櫎澶辫触");
- }
- } catch (error) {
- ElMessage.error("鎵归噺鍒犻櫎澶辫触锛岃閲嶈瘯");
- }
- }).catch(() => {
- ElMessage.info("宸插彇娑堝垹闄�");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/documentationBorrowManagement/exportrevent", {}, "褰掕繕鐧昏.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-
-// 閫夋嫨鍙樺寲浜嬩欢
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 澶勭悊鍒嗛〉鍙樺寲
-const handlePagination = (current, size) => {
- pagination.currentPage = current;
- pagination.pageSize = size;
- loadReturnList();
-};
-// 澶勭悊鎵爜鍐呭
-const handleScanContent = async (value) => {
- if (!value) return;
-
- try {
- // 璋冪敤API鏍规嵁涔︾睄ID鑾峰彇鍊熼槄淇℃伅
- const res = await getBorrowListByDocumentationId(value);
-
- if (res.code === 200 && res.data && res.data.length > 0) {
- // 淇濆瓨鑾峰彇鍒扮殑鍊熼槄淇℃伅鍒楄〃
- borrowInfoList.value = res.data;
-
- // 濡傛灉鍙湁涓�鏉¤褰曪紝鐩存帴閫夋嫨
- if (res.data.length === 1) {
- const borrowInfo = res.data[0];
- returnForm.borrowId = borrowInfo.id;
- returnForm.borrower = borrowInfo.borrower || borrowInfo.borrowerName || '';
- returnForm.dueReturnDate = borrowInfo.dueReturnDate || borrowInfo.expectedReturnDate || '';
- ElMessage.success(`宸查�夋嫨: ${borrowInfo.docName || borrowInfo.name}`);
- } else {
- // 濡傛灉鏈夊鏉¤褰曪紝鏄剧ず閫夋嫨鎻愮ず
- ElMessage.success(`鎵惧埌 ${res.data.length} 鏉$浉鍏冲�熼槄璁板綍锛岃浠庝笅鎷夊垪琛ㄤ腑閫夋嫨`);
- // 閲嶆柊鍔犺浇鏂囨。鍒楄〃锛屽寘鍚渶鏂扮殑鍊熼槄淇℃伅
- await loadDocumentList();
- }
- } else {
- // 鏈壘鍒板尮閰嶇殑鍊熼槄璁板綍
- ElMessage.warning('鏈壘鍒板搴旂殑鍊熼槄璁板綍锛岃妫�鏌ユ壂鐮佸唴瀹规垨鎵嬪姩閫夋嫨');
- }
- } catch (error) {
- ElMessage.error('鎵爜澶勭悊澶辫触锛岃閲嶈瘯');
- console.error('鎵爜澶勭悊閿欒:', error);
- }
-};
-// 澶勭悊鏂囨。閫夋嫨鍙樺寲
-// 澶勭悊鏂囨。閫夋嫨鍙樺寲
-const handleDocumentChange = (borrowId) => {
- // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
- scanContent.value = '';
-
- if (borrowId) {
- // 浼樺厛浠庡�熼槄淇℃伅鍒楄〃涓煡鎵�
- let selectedInfo;
- if (borrowInfoList.value.length > 0) {
- selectedInfo = borrowInfoList.value.find(info => info.id === borrowId);
- }
-
- // 濡傛灉鍊熼槄淇℃伅鍒楄〃涓病鏈夋壘鍒帮紝浠庢枃妗e垪琛ㄤ腑鏌ユ壘
- if (!selectedInfo) {
- selectedInfo = documentList.value.find(doc => doc.id === borrowId);
- }
-
- if (selectedInfo) {
- // 鑷姩濉厖鍊熼槄浜哄拰搴斿綊杩樻棩鏈�
- returnForm.borrower = selectedInfo.borrower || selectedInfo.borrowerName || '';
- returnForm.dueReturnDate = selectedInfo.dueReturnDate || selectedInfo.expectedReturnDate || '';
- }
- } else {
- // 娓呯┖鐩稿叧瀛楁
- returnForm.borrower = '';
- returnForm.dueReturnDate = '';
- }
-};
-// const handleDocumentChange = (documentId) => {
-// // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
-// scanContent.value = '';
-// if (documentId) {
-// // 鏍规嵁閫夋嫨鐨勬枃妗D锛屼粠鏂囨。鍒楄〃涓煡鎵惧搴旂殑鏂囨。淇℃伅
-// const selectedDoc = documentList.value.find(doc => doc.id === documentId);
-// if (selectedDoc) {
-// // 鑷姩濉厖鍊熼槄浜哄拰搴斿綊杩樻棩鏈�
-// returnForm.borrower = selectedDoc.borrower || selectedDoc.borrowerName || '';
-// returnForm.dueReturnDate = selectedDoc.dueReturnDate || selectedDoc.expectedReturnDate || '';
-// }
-// } else {
-// // 娓呯┖鐩稿叧瀛楁
-// returnForm.borrower = '';
-// returnForm.dueReturnDate = '';
-// }
-// };
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- initData();
-});
-</script>
-
-<style scoped>
-.return-view {
- padding: 20px;
-}
-
-.search-container {
- background: #ffffff;
- padding: 20px;
- border-radius: 8px;
- margin-bottom: 20px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.search-form {
- margin: 0;
-}
-
-.table-container {
- background: #ffffff;
- border-radius: 8px;
- overflow: hidden;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.empty-data {
- text-align: center;
- color: #909399;
- padding: 40px;
- font-size: 14px;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-form-item__label) {
- font-weight: 500;
- color: #303133;
-}
-
-:deep(.el-input__wrapper) {
- box-shadow: 0 0 0 1px #dcdfe6 inset;
-}
-
-:deep(.el-input__wrapper:hover) {
- box-shadow: 0 0 0 1px #c0c4cc inset;
-}
-
-:deep(.el-input__wrapper.is-focus) {
- box-shadow: 0 0 0 1px #409eff inset;
-}
-</style>
diff --git a/src/views/fileManagement/statistics/index.vue b/src/views/fileManagement/statistics/index.vue
deleted file mode 100644
index 42b81e4..0000000
--- a/src/views/fileManagement/statistics/index.vue
+++ /dev/null
@@ -1,539 +0,0 @@
-<template>
- <div class="app-container statistics-container">
-
- <!-- 鎬讳綋缁熻鍗$墖 -->
- <el-row :gutter="20" class="statistics-cards">
- <el-col :span="6" v-for="(item, index) in overviewData" :key="index">
- <el-card class="statistics-card" :class="item.type">
- <div class="card-content">
- <div class="card-icon">
- <el-icon :size="32">
- <component :is="item.icon" />
- </el-icon>
- </div>
- <div class="card-info">
- <div class="card-number">
- <el-skeleton-item v-if="loading" variant="text" style="width: 60px; height: 32px;" />
- <span v-else>{{ item.value }}</span>
- </div>
- <div class="card-label">{{ item.label }}</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 鍥捐〃鍖哄煙 -->
- <el-row :gutter="20" class="charts-section">
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>妗f鍒嗙被缁熻</span>
- </div>
- </template>
- <div class="chart-container">
- <div ref="categoryChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>妗f鐘舵�佺粺璁�</span>
- </div>
- </template>
- <div class="chart-container">
- <div ref="statusChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, nextTick, onUnmounted } from "vue";
-import { ElMessage } from "element-plus";
-import { Refresh } from "@element-plus/icons-vue";
-import * as echarts from "echarts";
-import {
- getDocumentationOverview,
- getDocumentationCategoryStats,
- getDocumentationStatusStats
-} from "@/api/fileManagement/document";
-import {
- Document,
- Folder,
- Tickets,
- Calendar
-} from "@element-plus/icons-vue";
-
-// 鍝嶅簲寮忔暟鎹�
-const overviewData = ref([
- {
- label: "鎬绘。妗堟暟",
- value: 0,
- icon: "Document",
- type: "primary",
- },
- {
- label: "鍒嗙被鏁伴噺",
- value: 0,
- icon: "Folder",
- type: "success",
- },
- {
- label: "鍊熷嚭妗f",
- value: 0,
- icon: "Tickets",
- type: "warning",
- },
- {
- label: "鏈湀鏂板",
- value: 0,
- icon: "Calendar",
- type: "info",
- },
-]);
-
-const categoryChartRef = ref(null);
-const statusChartRef = ref(null);
-
-// 鍥捐〃瀹炰緥
-let categoryChart = null;
-let statusChart = null;
-
-// 鍔犺浇鐘舵��
-const loading = ref(false);
-const autoRefreshInterval = ref(null);
-
-// 鑷姩鍒锋柊寮�鍏�
-const autoRefreshEnabled = ref(true);
-
-// 鑷姩鍒锋柊闂撮殧锛�5鍒嗛挓锛�
-const AUTO_REFRESH_INTERVAL = 5 * 60 * 1000;
-
-// 鍚姩鑷姩鍒锋柊
-const startAutoRefresh = () => {
- if (autoRefreshInterval.value) {
- clearInterval(autoRefreshInterval.value);
- }
- if (autoRefreshEnabled.value) {
- autoRefreshInterval.value = setInterval(() => {
- refreshData();
- }, AUTO_REFRESH_INTERVAL);
- }
-};
-
-// 鍋滄鑷姩鍒锋柊
-const stopAutoRefresh = () => {
- if (autoRefreshInterval.value) {
- clearInterval(autoRefreshInterval.value);
- autoRefreshInterval.value = null;
- }
-};
-
-// 鍒囨崲鑷姩鍒锋柊鐘舵��
-const toggleAutoRefresh = (value) => {
- if (value) {
- startAutoRefresh();
- } else {
- stopAutoRefresh();
- }
-};
-
-// 鍔犺浇鎬讳綋缁熻鏁版嵁
-const loadOverviewData = async () => {
- try {
- const response = await getDocumentationOverview();
- if (response.code === 200) {
- const data = response.data;
- overviewData.value[0].value = data.totalDocsCount || 0;
- overviewData.value[1].value = data.categoryNumCount || 0;
- overviewData.value[2].value = data.borrowedDocsCount || 0;
- overviewData.value[3].value = data.monthlyAddedDocsCount || 0;
- }
- } catch (error) {
- console.error('鍔犺浇鎬讳綋缁熻鏁版嵁澶辫触:', error);
- ElMessage.error('鍔犺浇鎬讳綋缁熻鏁版嵁澶辫触');
- }
-};
-
-// 鍔犺浇鍒嗙被缁熻鏁版嵁
-const loadCategoryData = async () => {
- try {
- const response = await getDocumentationCategoryStats();
- if (response.code === 200) {
- renderCategoryChart(response.data);
- }
- } catch (error) {
- console.error('鍔犺浇鍒嗙被缁熻鏁版嵁澶辫触:', error);
- ElMessage.error('鍔犺浇鍒嗙被缁熻鏁版嵁澶辫触');
- }
-};
-
-// 鍔犺浇鐘舵�佺粺璁℃暟鎹�
-const loadStatusData = async () => {
- try {
- const response = await getDocumentationStatusStats();
- if (response.code === 200) {
- renderStatusChart(response.data);
- }
- } catch (error) {
- console.error('鍔犺浇鐘舵�佺粺璁℃暟鎹け璐�:', error);
- ElMessage.error('鍔犺浇鐘舵�佺粺璁℃暟鎹け璐�');
- }
-};
-
-// 鍒锋柊鏁版嵁
-const refreshData = async () => {
- loading.value = true;
- try {
- await Promise.all([
- loadOverviewData(),
- loadCategoryData(),
- loadStatusData()
- ]);
- ElMessage.success('鏁版嵁鍒锋柊鎴愬姛');
- } catch (error) {
- console.error('鍒锋柊鏁版嵁澶辫触:', error);
- ElMessage.error('鍒锋柊鏁版嵁澶辫触');
- } finally {
- loading.value = false;
- }
-};
-
-// 鍒濆鍖栧浘琛�
-const initCharts = () => {
- // 寤惰繜鍒濆鍖栵紝纭繚DOM鍏冪礌宸茬粡娓叉煋
- setTimeout(() => {
- if (categoryChartRef.value) {
- categoryChart = echarts.init(categoryChartRef.value);
- }
-
- if (statusChartRef.value) {
- statusChart = echarts.init(statusChartRef.value);
- }
-
- // 鍒濆鍖栧畬鎴愬悗鍔犺浇鏁版嵁
- loadCategoryData();
- loadStatusData();
- }, 300);
-};
-
-// 娓叉煋鍒嗙被缁熻鍥捐〃
-const renderCategoryChart = (data) => {
- if (!categoryChart) return;
- let newData = data.map(item => {
- return {
- name: item.category,
- value: item.count
- }
- })
-
- const option = {
- title: {
- text: "妗f鍒嗙被鍒嗗竷",
- left: "center",
- textStyle: {
- fontSize: 16,
- fontWeight: "normal",
- },
- },
- tooltip: {
- trigger: "item",
- formatter: "{a} <br/>{b}: {c} ({d}%)",
- },
- legend: {
- orient: "vertical",
- left: "left",
- top: "middle",
- },
- series: [
- {
- name: "妗f鏁伴噺",
- type: "pie",
- radius: ["40%", "70%"],
- center: ["60%", "50%"],
- data: newData || [
- { name: "鎶�鏈枃妗�", value: 450 },
- { name: "绠$悊鏂囨。", value: 320 },
- { name: "璐㈠姟鏂囨。", value: 280 },
- { name: "浜轰簨鏂囨。", value: 200 },
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: "rgba(0, 0, 0, 0.5)",
- },
- },
- },
- ],
- };
-
- try {
- categoryChart.setOption(option);
- } catch (error) {
- console.error('鍒嗙被鍥捐〃娓叉煋澶辫触:', error);
- }
-};
-
-// 娓叉煋鐘舵�佺粺璁″浘琛�
-const renderStatusChart = (data) => {
- if (!statusChart) return;
- let newData = data.map(item => {
- return {
- name: item.docStatus,
- value: item.count
- }
- })
- const option = {
- title: {
- text: "妗f鐘舵�佸垎甯�",
- left: "center",
- textStyle: {
- fontSize: 16,
- fontWeight: "normal",
- },
- },
- tooltip: {
- trigger: "item",
- formatter: "{a} <br/>{b}: {c} ({d}%)",
- },
- legend: {
- orient: "vertical",
- left: "left",
- top: "middle",
- },
- series: [
- {
- name: "妗f鏁伴噺",
- type: "pie",
- radius: ["40%", "70%"],
- center: ["60%", "50%"],
- roseType: false,
- data: newData || [
- { name: "姝e父", value: 1150, itemStyle: { color: "#67C23A" } },
- { name: "鍊熷嚭", value: 89, itemStyle: { color: "#E6A23C" } },
- { name: "涓㈠け", value: 8, itemStyle: { color: "#F56C6C" } },
- { name: "鎹熷潖", value: 4, itemStyle: { color: "#909399" } },
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: "rgba(0, 0, 0, 0.5)",
- },
- },
- },
- ],
- };
-
- try {
- statusChart.setOption(option);
- } catch (error) {
- console.error('鐘舵�佸浘琛ㄦ覆鏌撳け璐�:', error);
- }
-};
-
-onMounted(() => {
- loadOverviewData();
- initCharts();
- startAutoRefresh();
-});
-
-// 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
-onUnmounted(() => {
- stopAutoRefresh();
-});
-</script>
-
-<style scoped>
-.statistics-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- color: white;
-}
-
-.page-header h2 {
- color: white;
- margin-bottom: 10px;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- color: rgba(255, 255, 255, 0.9);
- font-size: 14px;
- margin: 0 0 15px 0;
-}
-
-.header-controls {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-top: 10px;
- gap: 20px;
-}
-
-.refresh-btn {
- margin-left: 20px;
-}
-
-.statistics-cards {
- margin-bottom: 30px;
-}
-
-.statistics-card {
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
- border: none;
- overflow: hidden;
-}
-
-.statistics-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
-}
-
-.statistics-card.primary {
- border-left: 4px solid #409EFF;
- background: linear-gradient(135deg, #409EFF 0%, #36a3f7 100%);
-}
-
-.statistics-card.success {
- border-left: 4px solid #67C23A;
- background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
-}
-
-.statistics-card.warning {
- border-left: 4px solid #E6A23C;
- background: linear-gradient(135deg, #E6A23C 0%, #ebb563 100%);
-}
-
-.statistics-card.info {
- border-left: 4px solid #909399;
- background: linear-gradient(135deg, #909399 0%, #a6a9ad 100%);
-}
-
-.card-content {
- display: flex;
- align-items: center;
- padding: 20px;
-}
-
-.card-icon {
- margin-right: 20px;
- color: white;
-}
-
-.card-info {
- flex: 1;
-}
-
-.card-number {
- font-size: 32px;
- font-weight: 600;
- color: white;
- margin-bottom: 5px;
-}
-
-.card-label {
- font-size: 14px;
- color: rgba(255, 255, 255, 0.9);
-}
-
-.charts-section {
- margin-bottom: 30px;
-}
-
-.chart-card {
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- border: none;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: 600;
- color: #303133;
- padding: 15px 20px;
- border-bottom: 1px solid #ebeef5;
-}
-
-.chart-container {
- height: 400px;
- padding: 20px;
-}
-
-.chart {
- width: 100%;
- height: 100%;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .statistics-container {
- padding: 10px;
- }
-
- .page-header {
- padding: 15px;
- }
-
- .page-header h2 {
- font-size: 24px;
- }
-
- .header-controls {
- flex-direction: column;
- gap: 15px;
- }
-
- .refresh-btn {
- margin-left: 0;
- }
-
- .statistics-cards .el-col {
- margin-bottom: 15px;
- }
-
- .charts-section .el-col {
- margin-bottom: 20px;
- }
-
- .chart-container {
- height: 300px;
- }
-}
-
-@media (max-width: 480px) {
- .page-header h2 {
- font-size: 20px;
- }
-
- .card-number {
- font-size: 24px;
- }
-
- .chart-container {
- height: 250px;
- }
-}
-</style>
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
deleted file mode 100644
index 06bf4cf..0000000
--- a/src/views/financialManagement/accounting/index.vue
+++ /dev/null
@@ -1,231 +0,0 @@
-<template>
- <div class="app-container">
- <el-row :gutter="16" class="mb-16">
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">缁熶竴浼氳绉戠洰浣撶郴</div>
- <el-tree
- :data="accountTree"
- node-key="code"
- :props="{ label: 'label', children: 'children' }"
- highlight-current
- default-expand-all
- />
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">鍑瘉妯℃澘</div>
- <el-table :data="voucherTemplates" border size="small">
- <el-table-column prop="name" label="妯℃澘鍚嶇О" min-width="140" />
- <el-table-column prop="bizScene" label="涓氬姟鍦烘櫙" min-width="140" />
- <el-table-column prop="debit" label="鍊熸柟绉戠洰" min-width="160" />
- <el-table-column prop="credit" label="璐锋柟绉戠洰" min-width="160" />
- <el-table-column prop="auxDims" label="杈呭姪鏍哥畻缁村害" min-width="180">
- <template #default="scope">
- <el-space wrap>
- <el-tag v-for="dim in scope.row.auxDims" :key="dim" size="small" type="info">{{ dim }}</el-tag>
- </el-space>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="16" class="mb-16">
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">涓氬姟娴佺▼ 鈫� 鍑瘉鑷姩鐢熸垚</div>
- <div class="toolbar">
- <el-text type="info">婕旂ず鏁版嵁浠呯敤浜庡睍绀虹粨鏋勪笌瀛楁</el-text>
- </div>
- <el-table :data="generatedVouchers" border size="small">
- <el-table-column prop="date" label="鏃ユ湡" width="110" />
- <el-table-column prop="bizScene" label="涓氬姟鍦烘櫙" min-width="120" />
- <el-table-column prop="summary" label="鎽樿" min-width="160" />
- <el-table-column prop="amount" label="閲戦(楼)" width="110" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === '宸茬敓鎴�' ? 'success' : 'warning'">{{ scope.row.status }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">澶氱淮杈呭姪鏍哥畻</div>
- <div class="dims">
- <el-tag type="success">瀹㈡埛</el-tag>
- <el-tag type="warning">椤圭洰</el-tag>
- <el-tag type="info">閮ㄩ棬</el-tag>
- <el-tag type="primary">绠$悊鍛�</el-tag>
- </div>
- <el-table :data="auxSummary" size="small" border>
- <el-table-column prop="dimension" label="缁村害" width="100" />
- <el-table-column prop="category" label="绫诲埆" min-width="140" />
- <el-table-column prop="debit" label="鍊熸柟(鏈湡)" width="110" />
- <el-table-column prop="credit" label="璐锋柟(鏈湡)" width="110" />
- <el-table-column prop="balance" label="浣欓" width="100" />
- </el-table>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="16" class="mb-16">
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">缁撹处浠诲姟锛堟湀/瀛�/骞达級</div>
- <div class="toolbar">
- <el-space>
- <el-button size="small" @click="runClose('鏈堢粨')">鎵ц鏈堢粨</el-button>
- <el-button size="small" @click="runClose('瀛f姤')">鎵ц瀛f姤</el-button>
- <el-button size="small" @click="runClose('骞村害缁撹处')">鎵ц骞村害缁撹处</el-button>
- </el-space>
- </div>
- <el-timeline style="margin-top: 6px;">
- <el-timeline-item
- v-for="item in closingTasks"
- :key="item.id"
- :type="item.type"
- :timestamp="item.time"
- placement="top"
- >
- <div class="close-item">
- <div class="title">{{ item.name }}</div>
- <el-tag :type="item.status === '瀹屾垚' ? 'success' : 'info'" size="small">{{ item.status }}</el-tag>
- </div>
- </el-timeline-item>
- </el-timeline>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card shadow="hover">
- <div class="section-title">瀹¤鐣欑棔涓庡鎵规潈闄�</div>
- <el-table :data="auditTrail" border size="small">
- <el-table-column prop="time" label="鏃堕棿" width="160" />
- <el-table-column prop="action" label="鍔ㄤ綔" min-width="160" />
- <el-table-column prop="bizScene" label="鍏宠仈涓氬姟" min-width="140" />
- <el-table-column prop="role" label="鎵ц瑙掕壊" width="120" />
- <el-table-column prop="result" label="缁撴灉" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.result === '閫氳繃' ? 'success' : (scope.row.result === '椹冲洖' ? 'danger' : 'info')">
- {{ scope.row.result }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
-</template>
-
-<script setup>
-import { ref } from 'vue'
-
-// 绉戠洰鏍戯紙绀轰緥锛�
-const accountTree = ref([
- { code: '1001', label: '璧勪骇', children: [
- { code: '100101', label: '搴撳瓨鐜伴噾' },
- { code: '100102', label: '閾惰瀛樻' },
- { code: '1122', label: '搴旀敹璐︽' },
- { code: '1601', label: '鍥哄畾璧勪骇' },
- ]},
- { code: '2001', label: '璐熷��', children: [
- { code: '2202', label: '搴斾粯璐︽' },
- { code: '2241', label: '鍏朵粬搴斾粯娆�' },
- ]},
- { code: '3001', label: '鎵�鏈夎�呮潈鐩�', children: [
- { code: '3103', label: '鏈勾鍒╂鼎' },
- ]},
- { code: '4001', label: '鎴愭湰璐圭敤', children: [
- { code: '5601', label: '鍒堕�犺垂鐢�' },
- { code: '6602', label: '绠$悊璐圭敤' },
- ]},
-])
-
-// 鍑瘉妯℃澘锛堢ず渚嬶級
-const voucherTemplates = ref([
- { name: '閿�鍞敹鍏ョ‘璁�', bizScene: '閿�鍞嚭搴�', debit: '1122 搴旀敹璐︽', credit: '6001 涓昏惀涓氬姟鏀跺叆', auxDims: ['瀹㈡埛','椤圭洰'] },
- { name: '閲囪喘搴斾粯纭', bizScene: '閲囪喘鍏ュ簱', debit: '1403 鍦ㄩ�旂墿璧�', credit: '2202 搴斾粯璐︽', auxDims: ['椤圭洰','閮ㄩ棬'] },
- { name: '璐圭敤鎶ラ攢', bizScene: '璐圭敤鍗�', debit: '6602 绠$悊璐圭敤', credit: '1002 閾惰瀛樻', auxDims: ['閮ㄩ棬'] },
- { name: '鍥哄畾璧勪骇鎶樻棫', bizScene: '鏈堟湯鎶樻棫', debit: '6602 绠$悊璐圭敤', credit: '1602 绱鎶樻棫', auxDims: ['閮ㄩ棬'] },
-])
-
-// 鑷姩鐢熸垚鐨勫嚟璇侊紙绀轰緥锛�
-const generatedVouchers = ref([
- { date: '2025-10-01', bizScene: '閿�鍞嚭搴�', summary: '纭搴旀敹涓庢敹鍏�', amount: 128000, status: '宸茬敓鎴�' },
- { date: '2025-10-03', bizScene: '閲囪喘鍏ュ簱', summary: '纭鍒拌揣搴斾粯', amount: 56000, status: '宸茬敓鎴�' },
- { date: '2025-10-05', bizScene: '璐圭敤鍗�', summary: '鍔炲叕璐圭敤鎶ラ攢', amount: 3200, status: '宸茬敓鎴�' },
-])
-
-// 鏃犳ā鎷熺敓鎴愭搷浣滐紝浠呭睍绀洪潤鎬佺ず渚嬫暟鎹�
-
-// 杈呭姪鏍哥畻绀轰緥姹囨�伙紙鏃犱釜浜哄鍚嶏紝浠呯淮搴︾被鍒級
-const auxSummary = ref([
- { dimension: '瀹㈡埛', category: '閲嶇偣瀹㈡埛闆嗗悎', debit: 320000, credit: 210000, balance: 110000 },
- { dimension: '椤圭洰', category: '椤圭洰A', debit: 150000, credit: 120000, balance: 30000 },
- { dimension: '閮ㄩ棬', category: '杩愯惀涓績', debit: 42000, credit: 18000, balance: 24000 },
- { dimension: '绠$悊鍛�', category: '绯荤粺瑙掕壊', debit: 0, credit: 0, balance: 0 },
-])
-
-// 缁撹处浠诲姟
-const closingTasks = ref([
- { id: 1, name: '2025骞�10鏈� 鏈堢粨', time: '2025-10-31 18:00', status: '瀹屾垚', type: 'success' },
- { id: 2, name: '2025骞碤4 瀛f姤', time: '2025-12-31 18:00', status: '璁″垝', type: 'info' },
- { id: 3, name: '2025骞村害 骞村害缁撹处', time: '2025-12-31 23:00', status: '璁″垝', type: 'info' },
-])
-
-function runClose(kind) {
- closingTasks.value.unshift({
- id: Date.now(),
- name: `${new Date().getFullYear()}骞�${kind}`,
- time: new Date().toISOString().replace('T',' ').slice(0,16),
- status: '瀹屾垚',
- type: 'success',
- })
-}
-
-// 瀹¤鐣欑棔锛堜笉鍚釜浜哄鍚嶏紝浠呰鑹�/鏈哄埗锛�
-const auditTrail = ref([
- { time: '2025-10-01 09:12', action: '閿�鍞嚭搴撹Е鍙戝嚟璇佺敓鎴�', bizScene: '閿�鍞嚭搴�', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
- { time: '2025-10-03 14:20', action: '閲囪喘鍏ュ簱瑙﹀彂搴斾粯纭', bizScene: '閲囪喘鍏ュ簱', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
- { time: '2025-10-05 10:03', action: '璐圭敤鍗曞鎵�', bizScene: '璐圭敤鍗�', role: '璐㈠姟瀹℃壒', result: '閫氳繃' },
- { time: '2025-10-08 16:45', action: '鍑瘉杩囪处', bizScene: '鎬昏处', role: '浼氳瀹℃牳', result: '閫氳繃' },
- { time: '2025-10-31 18:05', action: '鏈堢粨瀹屾垚骞堕攣璐�', bizScene: '鎬昏处', role: '绯荤粺鑷姩鍖�', result: '閫氳繃' },
-])
-</script>
-
-<style scoped lang="scss">
-.app-container {
- padding: 16px;
-}
-.page-header {
- margin-bottom: 12px;
- h2 { margin: 0 0 6px 0; font-weight: 600; }
- p { margin: 0; color: #666; }
-}
-.section-title {
- position: relative;
- padding-left: 10px;
- margin-bottom: 10px;
- font-weight: 700;
-}
-.section-title::before {
- content: '';
- position: absolute;
- left: 0; top: 0.2em;
- width: 4px; height: 1.2em;
- background: #002FA7;
- border-radius: 2px;
-}
-.mb-16 { margin-bottom: 16px; }
-.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
-.dims { display: flex; gap: 8px; margin-bottom: 10px; }
-.close-item { display: flex; align-items: center; gap: 8px; }
-</style>
-
-
diff --git a/src/views/financialManagement/expenseManagement/Form.vue b/src/views/financialManagement/expenseManagement/Form.vue
deleted file mode 100644
index 9cfe5da..0000000
--- a/src/views/financialManagement/expenseManagement/Form.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
- <el-form-item label="鏀嚭鏃ユ湡" prop="expenseDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.expenseDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- clearable
- />
- </el-form-item>
- <el-form-item label="鏀嚭绫诲瀷" prop="expenseType">
- <el-select
- v-model="form.expenseType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in expense_types" :key="index" />
- </el-select>
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
- <el-input v-model="form.supplierName" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="鏀嚭閲戦" prop="expenseMoney">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="form.expenseMoney"
- placeholder="璇疯緭鍏�"
- />
- </el-form-item>
- <el-form-item label="鏀嚭鎻忚堪" prop="expenseDescribed">
- <el-input v-model="form.expenseDescribed" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="浠樻鏂瑰紡" prop="expenseMethod">
- <el-select
- v-model="form.expenseMethod"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in checkout_payment" :key="index" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
- <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="澶囨敞" prop="note">
- <el-input
- v-model="form.note"
- placeholder="澶囨敞"
- />
- </el-form-item>
-
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getAccountExpense } from "@/api/financialManagement/expenseManagement";
-import {ref} from "vue";
-const { proxy } = getCurrentInstance();
-
-
-defineOptions({
- name: "鏂板鏀嚭",
-});
-const { expense_types } = proxy.useDict("expense_types");
-const { checkout_payment } = proxy.useDict("checkout_payment");
-const formRef = ref(null);
-const formRules = {
- supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- expenseMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- expenseDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- expenseDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- expenseType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- expenseMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
- expenseDate: undefined, // 鏀嚭鏃ユ湡
- expenseType: undefined, // 鏀嚭绫诲瀷
- supplierName: undefined, // 瀹㈡埛鍚嶇О
- expenseMoney: undefined, // 鏀嚭閲戦
- expenseDescribed: undefined, // 鏀嚭鎻忚堪
- expenseMethod: undefined, // 鏀舵鏂瑰紡
- invoiceNumber: undefined, // 鍙戠エ鍙风爜
- note: undefined, // 澶囨敞
-});
-
-const loadForm = async (id) => {
- const { code, data } = await getAccountExpense(id);
- if (code == 200) {
- form.expenseDate = data.expenseDate;
- form.expenseType = data.expenseType;
- form.supplierName = data.supplierName;
- form.expenseMoney = data.expenseMoney;
- form.expenseDescribed = data.expenseDescribed;
- form.expenseMethod = data.expenseMethod;
- form.invoiceNumber = data.invoiceNumber;
- form.note = data.note;
- }
-};
-
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
- formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
- resetForm();
- clearValidate();
-};
-
-defineExpose({
- form,
- loadForm,
- resetForm,
- clearValidate,
- resetFormAndValidate,
- formRef,
-});
-</script>
diff --git a/src/views/financialManagement/expenseManagement/Modal.vue b/src/views/financialManagement/expenseManagement/Modal.vue
deleted file mode 100644
index 8e5b171..0000000
--- a/src/views/financialManagement/expenseManagement/Modal.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
- <Form ref="formRef"></Form>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import { add, update } from "@/api/financialManagement/expenseManagement";
-import Form from "./Form.vue";
-import { ElMessage } from "element-plus";
-const { proxy } = getCurrentInstance()
-
-defineOptions({
- name: "鏀嚭鏂板缂栬緫",
-});
-
-const emits = defineEmits(["success"]);
-
-const formRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "鏀嚭" });
-
-const sendForm = () => {
- proxy.$refs.formRef.$refs.formRef.validate(async valid => {
- if (valid) {
- const {code} = id.value
- ? await update({id: id.value, ...formRef.value.form})
- : await add(formRef.value.form);
- if (code == 200) {
- emits("success");
- ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
- close();
- } else {
- loading.value = false;
- }
- }
- })
-};
-
-const close = () => {
- formRef.value.resetFormAndValidate();
- closeModal();
-};
-
-const loadForm = async (id) => {
- openModal(id);
- await nextTick();
- formRef.value.loadForm(id);
-};
-
-defineExpose({
- openModal,
- loadForm,
-});
-</script>
diff --git a/src/views/financialManagement/expenseManagement/index.vue b/src/views/financialManagement/expenseManagement/index.vue
deleted file mode 100644
index a45c32d..0000000
--- a/src/views/financialManagement/expenseManagement/index.vue
+++ /dev/null
@@ -1,276 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="鏀嚭鏃ユ湡:">
- <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item label="浠樻鏂瑰紡:">
- <el-select
- v-model="filters.expenseMethod"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 200px;"
- >
- <el-option
- v-for="item in checkout_payment"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="deleteRow(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #operation="{ row }">
- <el-button type="primary" text @click="edit(row.id)" icon="editPen">
- 缂栬緫
- </el-button>
- <el-button
- type="primary"
- text
- @click="openFilesFormDia(row)"
- >
- 闄勪欢
- </el-button>
- </template>
- </PIMTable>
- </div>
- <Modal ref="modalRef" @success="getTableData"></Modal>
- <files-dia ref="filesDia"></files-dia>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountExpense } from "@/api/financialManagement/expenseManagement";
-import { onMounted, getCurrentInstance } from "vue";
-import Modal from "./Modal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import dayjs from "dayjs";
-import FilesDia from "../revenueManagement/filesDia.vue";
-
-defineOptions({
- name: "鏀嚭绠$悊",
-});
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-const { proxy } = getCurrentInstance();
-const modalRef = ref();
-const { checkout_payment } = proxy.useDict("checkout_payment");
-const { expense_types } = proxy.useDict("expense_types");
-const filesDia = ref()
-
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- listPage,
- {
- expenseMethod: undefined,
- entryDate: undefined,
- },
- [
- {
- label: "鏀嚭鏃ユ湡",
- align: "center",
- prop: "expenseDate",
- },
- {
- label: "鏀嚭绫诲瀷",
- align: "center",
- prop: "expenseType",
- dataType: "tag",
- formatData: (params) => {
- if (expense_types.value.find((m) => m.value == params)) {
- return expense_types.value.find((m) => m.value == params).label;
- } else {
- return null
- }
- },
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- align: "center",
- prop: "supplierName",
-
- },
- {
- label: "鏀嚭閲戦",
- align: "center",
- prop: "expenseMoney",
-
- },
- {
- label: "鏀嚭鎻忚堪",
- align: "center",
- prop: "expenseDescribed",
-
- },
- {
- label: "浠樻鏂瑰紡",
- align: "center",
- prop: "expenseMethod",
- dataType: "tag",
- formatData: (params) => {
- if (checkout_payment.value.find((m) => m.value == params)) {
- return checkout_payment.value.find((m) => m.value == params).label;
- } else {
- return null
- }
- },
- },
- {
- label: "鍙戠エ鍙风爜",
- align: "center",
- prop: "invoiceNumber",
-
- },
- {
- label: "澶囨敞",
- align: "center",
- prop: "note",
-
- },
- {
- label: "褰曞叆浜�",
- align: "center",
- prop: "inputUser",
- },
- {
- label: "褰曞叆鏃ユ湡",
- align: "center",
- prop: "inputTime",
-
- },
- {
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "200px",
- },
- ]
-);
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-const add = () => {
- modalRef.value.openModal();
-};
-const edit = (id) => {
- modalRef.value.loadForm(id);
-};
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-const deleteRow = (id) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await delAccountExpense(id);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "鍒犻櫎鎴愬姛",
- });
- getTableData();
- }
- });
-};
-
-const changeDaterange = (value) => {
- if (value) {
- filters.entryDate = value;
- filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- filters.entryDate = null;
- filters.entryDateStart = undefined;
- filters.entryDateEnd = undefined;
- }
- getTableData();
-};
-
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/account/accountExpense/export`, {}, "鏀嚭鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
- nextTick(() => {
- filesDia.value?.openDialog( row,'鏀嚭')
- })
-};
-
-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/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
deleted file mode 100644
index e5f9b23..0000000
--- a/src/views/financialManagement/financialStatements/index.vue
+++ /dev/null
@@ -1,507 +0,0 @@
- <template>
- <div style="padding: 20px;">
- <!-- 椤甸潰鏍囬鍜屾棩鏈熺瓫閫� -->
- <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
- <el-date-picker
- v-model="dateRange"
- type="daterange"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- clearable
- @change="handleDateChange"
- class="w-full md:w-auto"
- style="margin-right: 30px;"
- />
-
- <el-button
- type="primary"
- icon="Refresh"
- @click="resetDateRange"
- size="default"
- >
- 閲嶇疆
- </el-button>
- </div>
-
- <main class="container mx-auto px-4 pb-10">
- <!-- 璐㈠姟鎸囨爣鍗$墖 -->
- <div class="grid-container">
- <!-- 鎬绘敹鍏� -->
- <el-card class="bg1">
- <p>鎬绘敹鍏�</p>
- <h3>
- 楼{{ pageInfo.totalIncome }}
- </h3>
- </el-card>
-
- <!-- 鏀跺叆绗旀暟 -->
- <el-card class="bg2">
- <p>鏀跺叆绗旀暟</p>
- <h3>
- {{ pageInfo.incomeNumber }}
- </h3>
- </el-card>
-
- <!-- 鎬绘敮鍑� -->
- <el-card class="bg3">
- <p>鎬绘敮鍑�</p>
- <h3>
- 楼{{ pageInfo.totalExpense }}
- </h3>
- </el-card>
-
- <!-- 鏀嚭绗旀暟 -->
- <el-card class="bg4">
- <p>鏀嚭绗旀暟</p>
- <h3>
- {{ pageInfo.expenseNumber }}
- </h3>
- </el-card>
-
- <!-- 鍑�鏀跺叆 -->
- <el-card class="bg5">
- <p>鍑�鏀跺叆</p>
- <h3>
- 楼{{ pageInfo.netRevenue }}
- </h3>
- </el-card>
- </div>
-
- <!-- 鏀跺叆缁熻鍥捐〃 -->
- <div class="grid-layout">
- <el-card style="margin-bottom: 20px;">
- <h2 class="section-title">鏀跺叆缁熻(鍏�)</h2>
- <div class="echarts">
- <Echarts :legend="pieLegend0" :chartStyle="chartStylePie"
- :series="materialPieSeries0"
- :tooltip="pieTooltip" style="height: 260px;width: 35%;">
- <div class="chart-num">
- <span style="font-size: 22px;">鏀跺叆</span>
- <span style="font-size: 36px;
- font-weight: 500;
- font-family: 'MyCustomFont', sans-serif;">{{ pageInfo.totalIncome }}</span>
- </div>
- </Echarts>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="lineLegend"
- :series="lineSeries0"
- :tooltip="tooltip"
- :xAxis="xAxis0"
- :yAxis="yAxis0"
- style="height: 260px;width: 64%;"></Echarts>
- </div>
- </el-card>
-
- <!-- 鏀嚭缁熻鍥捐〃 -->
- <el-card>
- <h2 class="section-title">鏀嚭缁熻(鍏�)</h2>
- <div class="echarts">
- <Echarts ref="chart"
- :legend="pieLegend1"
- :chartStyle="chartStylePie"
- :series="materialPieSeries1"
- :tooltip="pieTooltip"
- style="height: 260px;width: 35%;">
- <div class="chart-num">
- <span style="font-size: 22px;">鏀嚭</span>
- <span style="font-size: 36px;
- font-weight: 500;
- font-family: 'MyCustomFont', sans-serif;">{{ pageInfo.totalExpense }}</span>
- </div></Echarts>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="lineLegend"
- :series="lineSeries1"
- :tooltip="tooltip"
- :xAxis="xAxis1"
- :yAxis="yAxis1"
- style="height: 260px;width: 64%;"></Echarts>
- </div>
- </el-card>
- </div>
- </main>
- </div>
-</template>
-
-<script setup>
-import { ref, computed, onMounted, reactive } from 'vue';
-import 'element-plus/dist/index.css';
-import Echarts from "@/components/Echarts/echarts.vue";
-import { reportForms,reportIncome,reportExpense } from "@/api/financialManagement/financialStatements";
-import dayjs from "dayjs";
-
-// 鏃ユ湡鑼冨洿
-const dateRange = ref(null);
-const chartStyle = {
- width: '100%',
- height: '100%', // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
- position:'relative',
-}
-const grid = {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
-}
-const lineLegend = {
- show: false,
-}
-// 鎶樼嚎鍥炬彁绀烘
-const tooltip = reactive({
- trigger: 'axis',
- axisPointer: {
- type: 'line',
- lineStyle: { color: '#aaa' }
- },
- // 鑷畾涔夊唴瀹�
- formatter: function (params) {
- if (!params || !params.length) return ''
- const axisLabel = params[0].axisValueLabel || params[0].axisValue || ''
- const rows = params
- .map(p => {
- const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`
- return `${colorDot}${p.seriesName}: ${p.value}`
- })
- .join('<br/>')
- return `<div>${axisLabel}</div><div>${rows}</div>`
- }
-})
-const months = ['1鏈�','2鏈�','3鏈�','4鏈�','5鏈�','6鏈�','7鏈�','8鏈�','9鏈�','10鏈�','11鏈�','12鏈�'];
-const lineSeries0 = ref([])
-const lineSeries1 = ref([])
-
-const xAxis0 = ref([
- {
- type: 'category',
- axisTick: { show: true, alignWithLabel: true },
- data: months,
- },
-]);
-const xAxis1 = ref([
- {
- type: 'category',
- axisTick: { show: true, alignWithLabel: true },
- data: months,
- },
-]);
-const yAxis0 = [
-{
- type: 'value',
- name: '鏀跺叆缁熻', // 宸︿晶y杞�
- position: 'left',
- min: 0,
- // 鍧愭爣杞村悕绉版牱寮�
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
- },
- }
-]
-
-const yAxis1 = [
-{
- type: 'value',
- name: '鏀嚭缁熻', // 宸︿晶y杞�
- position: 'left',
- min: 0,
- // 鍧愭爣杞村悕绉版牱寮�
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
- },
- }
-]
-
-const chartStylePie = {
- width: '100%',
- height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-}
-const pieColors = ['#F04864','#FACC14', '#8543E0', '#1890FF', '#13C2C2','#2FC25B']; // 鍙牴鎹疄闄呰皟鏁�
-const pieData0 = ref([]);
-const pieData1 = ref([]);
-
-const pieLegend0 = computed(() => ({
- show: true,
- top: 'center',
- left: '60%',
- orient: 'vertical',
- icon: 'circle',
- data: pieData0.value.map(item => item.name),
- formatter: function(name) {
- const item = pieData0.value.find(i => i.name === name);
- if (!item) return name;
- return `${name} | ${item.percent} ${item.amount}`;
- },
- textStyle: {
- color: '#333',
- fontSize: 14,
- lineHeight: 26,
- }
-}));
-const pieLegend1 = computed(() => ({
- show: true,
- top: 'center',
- left: '60%',
- orient: 'vertical',
- icon: 'circle',
- data: pieData1.value.map(item => item.name),
- formatter: function(name) {
- const item = pieData1.value.find(i => i.name === name);
- if (!item) return name;
- return `${name} | ${item.percent} ${item.amount}`;
- },
- textStyle: {
- color: '#333',
- fontSize: 14,
- lineHeight: 26,
- }
-}));
-
-const materialPieSeries0 = computed(() => [
- {
- type: 'pie',
- radius: ['50%', '65%'],
- center: ['25%', '50%'],
- avoidLabelOverlap: false,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 2
- },
- label: {
- show: false
- },
- data: pieData0.value,
- color: pieColors
- }
-]);
-const materialPieSeries1 = computed(() => [
- {
- type: 'pie',
- radius: ['50%', '65%'],
- center: ['25%', '50%'],
- avoidLabelOverlap: false,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 2
- },
- label: {
- show: false
- },
- data: pieData1.value,
- color: pieColors
- }
-]);
-const pieTooltip = reactive({
- trigger: 'item',
- formatter: function(params) {
- // 妫�鏌ユ暟鎹槸鍚﹀瓨鍦�
- if (!params.data) return params.name;
- // 鎷兼帴瀹屾暣鍐呭
- return `
- <div>
- <div style="color:${params.color};font-size:16px;">鈼�</div>
- <div>${params.name}</div>
- <div>鍗犳瘮锛�${params.data.percent}</div>
- <div>閲戦锛�${params.data.amount}</div>
- </div>
- `;
- }
-})
-
-
-const pageInfo = ref({
-})
-
-const getData = async () => {
- if (!dateRange.value || !dateRange.value.length) {
- return;
- }
- try {
- const {code,data} = await reportForms({entryDateStart:dateRange.value[0], entryDateEnd:dateRange.value[1]});
- if(code === 200) {
- pageInfo.value = data
- pieData0.value = data.incomeType.map(item=>({
- name:item.typeName,
- value:item.account,
- percent:`${item.proportion*100}%`,
- amount:`楼${item.account}`
- }))
- pieData1.value = data.expenseType.map(item=>({
- name:item.typeName,
- value:item.account,
- percent:`${item.proportion*100}%`,
- amount:`楼${item.account}`
- }))
-
- }
- } catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
- try{
- const {code,data} = await reportIncome();
- if(code==200){
- lineSeries0.value = data.map(item=>({
- name:item.typeName,
- type: 'line',
- data:item.account.map(item=>Number(item))
- }))
-
- }
- }catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
- try{
- const {code,data} = await reportExpense();
- if(code==200){
- lineSeries1.value = data.map(item=>({
- name:item.typeName,
- type: 'line',
- data:item.account.map(item=>Number(item))
- }))
-
- }
- }catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
-};
-
-
-// 鍒濆鍖�
-onMounted(() => {
- // 涓嶈缃粯璁ゆ棩鏈燂紝鐢辩敤鎴锋墜鍔ㄩ�夋嫨
-});
-
-// 澶勭悊鏃ユ湡鑼冨洿鍙樺寲
-const handleDateChange = (newRange) => {
- dateRange.value = newRange;
- if (newRange && newRange.length === 2) {
- getData()
- }
-};
-
-// 閲嶇疆鏃ユ湡鑼冨洿
-const resetDateRange = () => {
- dateRange.value = null;
-};
-
-</script>
-
-<style scoped lang="scss">
-/* 鍩虹鏍峰紡琛ュ厖 */
-:root {
- --el-color-primary: #4f46e5;
-}
-.el-card{
- position: relative;
- border-radius: 12px;
- padding: 14px 10px 10px 10px;
- box-shadow: 0 2px 8px #eee;
- :deep(.el-card__body){
- padding: 10px 20px !important;
- }
- &.bg1{
- background: url(@/assets/icons/png/1.png) no-repeat 100% 100% !important;
- }
- &.bg2{
- background: url(@/assets/icons/png/2.png) no-repeat 100% 100% !important;
- }
- &.bg3{
- background: url(@/assets/icons/png/3.png) no-repeat 100% 100% !important;
- }
- &.bg4{
- background: url(@/assets/icons/png/4.png) no-repeat 100% 100% !important;
- }
- &.bg5{
- background: url(@/assets/icons/png/5.png) no-repeat 100% 100% !important;
- }
-}
-
-.grid-container {
- /* grid 瀹瑰櫒鍩虹鏍峰紡 */
- display: grid;
- gap: 1rem; /* gap-4 瀵瑰簲 1rem (16px) */
- margin-bottom: 2rem; /* mb-8 瀵瑰簲 2rem (32px) */
-
- p{
- font-size: 22px;
- margin-top: 0px;
- color: #fff;
- }
- h3{
- font-size: 36px;
- font-weight: 500;
- font-family: 'MyCustomFont', sans-serif;
- margin: 10px 0;
- color: #fff;
- }
-
-}
-
-/* 绉诲姩绔粯璁ゆ牱寮� (grid-cols-1) */
-.grid-container {
- grid-template-columns: repeat(1, minmax(0, 1fr));
-}
-
-/* 灏忓睆骞曞強浠ヤ笂 (sm:grid-cols-2) */
-@media (min-width: 640px) {
- .grid-container {
- grid-template-columns: repeat(2, minmax(0, 1fr));
- }
-}
-
-/* 澶у睆骞曞強浠ヤ笂 (lg:grid-cols-5) */
-@media (min-width: 1024px) {
- .grid-container {
- grid-template-columns: repeat(5, minmax(0, 1fr));
- }
-}
-
-/* 鍗$墖鎮仠鏁堟灉澧炲己 */
-.el-card:hover {
- transform: translateY(-2px);
-}
-.echarts{
- display: flex;
- justify-content: space-between;
-}
-
-/* 鍥捐〃瀹瑰櫒鏍峰紡 */
-.el-chart {
- width: 100%;
- height: 100%;
-}
-.section-title {
- position: relative;
- font-size: 18px;
- color: #333;
- padding-left: 10px;
- margin-bottom: 10px;
- font-weight: 700;
-}
-
-.section-title::before {
- position: absolute;
- left: 0;
- top: 0px;
- content: '';
- width: 4px;
- height: 18px;
- background-color: #002FA7;
- border-radius: 2px;
-}
-.chart-num{
- position: absolute;
- z-index: 3;
- top: 92px;
- left: 92px;
- display: flex;
- flex-direction: column;
- justify-content: center;
-}
-</style>
diff --git a/src/views/financialManagement/revenueManagement/Form.vue b/src/views/financialManagement/revenueManagement/Form.vue
deleted file mode 100644
index 67b175e..0000000
--- a/src/views/financialManagement/revenueManagement/Form.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
- <el-form-item label="鏀跺叆鏃ユ湡" prop="incomeDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.incomeDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- clearable
- />
- </el-form-item>
- <el-form-item label="鏀跺叆绫诲瀷" prop="incomeType">
- <el-select
- v-model="form.incomeType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in income_types" :key="index" />
- </el-select>
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚嶇О" prop="customerName">
- <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="鏀跺叆閲戦" prop="incomeMoney">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="form.incomeMoney"
- placeholder="璇疯緭鍏�"
- />
- </el-form-item>
- <el-form-item label="鏀跺叆鎻忚堪" prop="incomeDescribed">
- <el-input v-model="form.incomeDescribed" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="鏀舵鏂瑰紡" prop="incomeMethod">
- <el-select
- v-model="form.incomeMethod"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in payment_methods" :key="index" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber">
- <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
- </el-form-item>
- <el-form-item label="澶囨敞" prop="note">
- <el-input
- v-model="form.note"
- placeholder="澶囨敞"
- />
- </el-form-item>
-
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getAccountIncome } from "@/api/financialManagement/revenueManagement";
-import {ref} from "vue";
-const { proxy } = getCurrentInstance();
-
-
-defineOptions({
- name: "鏂板鏀跺叆",
-});
-const { income_types } = proxy.useDict("income_types");
-const { payment_methods } = proxy.useDict("payment_methods");
-const formRef = ref(null);
-const formRules = {
- customerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- incomeMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- incomeDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- incomeDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- incomeType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- incomeMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
- incomeDate: undefined, // 鏀跺叆鏃ユ湡
- incomeType: undefined, // 鏀跺叆绫诲瀷
- customerName: undefined, // 瀹㈡埛鍚嶇О
- incomeMoney: undefined, // 鏀跺叆閲戦
- incomeDescribed: undefined, // 鏀跺叆鎻忚堪
- incomeMethod: undefined, // 鏀舵鏂瑰紡
- invoiceNumber: undefined, // 鍙戠エ鍙风爜
- note: undefined, // 澶囨敞
-});
-
-const loadForm = async (id) => {
- const { code, data } = await getAccountIncome(id);
- if (code == 200) {
- form.incomeDate = data.incomeDate;
- form.incomeType = data.incomeType;
- form.customerName = data.customerName;
- form.incomeMoney = data.incomeMoney;
- form.incomeDescribed = data.incomeDescribed;
- form.incomeMethod = data.incomeMethod;
- form.invoiceNumber = data.invoiceNumber;
- form.note = data.note;
- }
-};
-
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
- formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
- resetForm();
- clearValidate();
-};
-
-defineExpose({
- form,
- loadForm,
- resetForm,
- clearValidate,
- resetFormAndValidate,
- formRef,
-});
-</script>
diff --git a/src/views/financialManagement/revenueManagement/Modal.vue b/src/views/financialManagement/revenueManagement/Modal.vue
deleted file mode 100644
index 480b4fd..0000000
--- a/src/views/financialManagement/revenueManagement/Modal.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
- <Form ref="formRef"></Form>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import { add, update } from "@/api/financialManagement/revenueManagement";
-import Form from "./Form.vue";
-import { ElMessage } from "element-plus";
-const { proxy } = getCurrentInstance()
-
-defineOptions({
- name: "鏀跺叆鏂板缂栬緫",
-});
-
-const emits = defineEmits(["success"]);
-
-const formRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "鏀跺叆" });
-
-const sendForm = () => {
- proxy.$refs.formRef.$refs.formRef.validate(async valid => {
- if (valid) {
- const {code} = id.value
- ? await update({id: id.value, ...formRef.value.form})
- : await add(formRef.value.form);
- if (code == 200) {
- emits("success");
- ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
- close();
- } else {
- loading.value = false;
- }
- }
- })
-};
-
-const close = () => {
- formRef.value.resetFormAndValidate();
- closeModal();
-};
-
-const loadForm = async (id) => {
- openModal(id);
- await nextTick();
- formRef.value.loadForm(id);
-};
-
-defineExpose({
- openModal,
- loadForm,
-});
-</script>
diff --git a/src/views/financialManagement/revenueManagement/filesDia.vue b/src/views/financialManagement/revenueManagement/filesDia.vue
deleted file mode 100644
index f752496..0000000
--- a/src/views/financialManagement/revenueManagement/filesDia.vue
+++ /dev/null
@@ -1,202 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="涓婁紶闄勪欢"
- width="50%"
- @close="closeDia"
- >
- <div style="margin-bottom: 10px;text-align: right">
- <el-upload
- v-model:file-list="fileList"
- class="upload-demo"
- :action="uploadUrl"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: inline;margin-right: 10px"
- >
- <el-button type="primary">涓婁紶闄勪欢</el-button>
- </el-upload>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- height="500"
- >
- </PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
- fileAdd,
- fileDel,
- fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
- {
- label: "鏂囦欢鍚嶇О",
- prop: "name",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "涓嬭浇",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- {
- name: "棰勮",
- type: "text",
- clickFun: (row) => {
- lookFile(row);
- },
- }
- ],
- },
-]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
- Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
- accountType.value = type;
- dialogFormVisible.value = true;
- currentId.value = row.id;
- getList()
-}
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
- tableData.value = res.data.records;
- total.value = res.data.total;
- })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
- // 濡傛灉涓婁紶鎴愬姛
- if (res.code == 200) {
- const fileRow = {}
- fileRow.name = res.data.originalName
- fileRow.url = res.data.tempPath
- uploadFile(fileRow)
- } else {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
-}
-function uploadFile(file) {
- file.accountId = currentId.value;
- file.accountType = accountType.value;
- fileAdd(file).then(res => {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- getList()
- })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-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(() => {
- fileDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/financialManagement/revenueManagement/index.vue b/src/views/financialManagement/revenueManagement/index.vue
deleted file mode 100644
index 9dcd23e..0000000
--- a/src/views/financialManagement/revenueManagement/index.vue
+++ /dev/null
@@ -1,276 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="鏀跺叆鏃ユ湡:">
- <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item label="鏀舵鏂瑰紡:">
- <el-select
- v-model="filters.incomeMethod"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 200px;"
- >
- <el-option
- v-for="item in payment_methods"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="deleteRow(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #operation="{ row }">
- <el-button type="primary" text @click="edit(row.id)" icon="editPen">
- 缂栬緫
- </el-button>
- <el-button
- type="primary"
- text
- @click="openFilesFormDia(row)"
- >
- 闄勪欢
- </el-button>
- </template>
- </PIMTable>
- </div>
- <Modal ref="modalRef" @success="getTableData"></Modal>
- <files-dia ref="filesDia"></files-dia>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountIncome } from "@/api/financialManagement/revenueManagement";
-import { onMounted, getCurrentInstance } from "vue";
-import Modal from "./Modal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import dayjs from "dayjs";
-import FilesDia from "./filesDia.vue";
-
-defineOptions({
- name: "鏀跺叆绠$悊",
-});
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-const { proxy } = getCurrentInstance();
-const modalRef = ref();
-const { payment_methods } = proxy.useDict("payment_methods");
-const { income_types } = proxy.useDict("income_types");
-const filesDia = ref()
-
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- listPage,
- {
- incomeMethod: undefined,
- entryDate: undefined,
- },
- [
- {
- label: "鏀跺叆鏃ユ湡",
- align: "center",
- prop: "incomeDate",
- },
- {
- label: "鏀跺叆绫诲瀷",
- align: "center",
- prop: "incomeType",
- dataType: "tag",
- formatData: (params) => {
- if (income_types.value.find((m) => m.value == params)) {
- return income_types.value.find((m) => m.value == params).label;
- } else {
- return null
- }
- },
- },
- {
- label: "瀹㈡埛鍚嶇О",
- align: "center",
- prop: "customerName",
-
- },
- {
- label: "鏀跺叆閲戦",
- align: "center",
- prop: "incomeMoney",
-
- },
- {
- label: "鏀跺叆鎻忚堪",
- align: "center",
- prop: "incomeDescribed",
-
- },
- {
- label: "鏀舵鏂瑰紡",
- align: "center",
- prop: "incomeMethod",
- dataType: "tag",
- formatData: (params) => {
- if (payment_methods.value.find((m) => m.value == params)) {
- return payment_methods.value.find((m) => m.value == params).label;
- } else {
- return null
- }
- },
- },
- {
- label: "鍙戠エ鍙风爜",
- align: "center",
- prop: "invoiceNumber",
-
- },
- {
- label: "澶囨敞",
- align: "center",
- prop: "note",
-
- },
- {
- label: "褰曞叆浜�",
- align: "center",
- prop: "inputUser",
- },
- {
- label: "褰曞叆鏃ユ湡",
- align: "center",
- prop: "inputTime",
-
- },
- {
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "200px",
- },
- ]
-);
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-const add = () => {
- modalRef.value.openModal();
-};
-const edit = (id) => {
- modalRef.value.loadForm(id);
-};
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-const deleteRow = (id) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await delAccountIncome(id);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "鍒犻櫎鎴愬姛",
- });
- getTableData();
- }
- });
-};
-
-const changeDaterange = (value) => {
- if (value) {
- filters.entryDate = value;
- filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- filters.entryDate = null;
- filters.entryDateStart = undefined;
- filters.entryDateEnd = undefined;
- }
- getTableData();
-};
-
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/account/accountIncome/export`, {}, "鏀跺叆鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
- nextTick(() => {
- filesDia.value?.openDialog( row,'鏀跺叆')
- })
-};
-
-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/index.vue b/src/views/index.vue
index 2888b16..3f75ad3 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 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="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,12 +155,12 @@
<!-- :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>
+<!-- <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>
@@ -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/dispatchLog/index.vue b/src/views/inventoryManagement/dispatchLog/index.vue
deleted file mode 100644
index 3eb5758..0000000
--- a/src/views/inventoryManagement/dispatchLog/index.vue
+++ /dev/null
@@ -1,865 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
- <el-input
- v-model="searchForm.supplierName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <span class="search_title ml10">鍑哄簱鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.timeStr"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- @change="handleQuery"
- />
- <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>
- <el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
- </div>
- </div>
- <div class="table_list">
- <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"
- height="calc(100vh - 18.5em)"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="鍑哄簱鏃ユ湡"
- prop="createTime"
- min-width="250"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- width="250"
- show-overflow-tooltip
- />
- <el-table-column
- label="浜у搧澶х被"
- prop="productCategory"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍗曚綅"
- prop="unit"
- width="80"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍑哄簱鏁伴噺"
- prop="inboundNum"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="绋庣巼(%)"
- prop="taxRate"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- width="180"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍑哄簱浜�"
- prop="createBy"
- width="80"
- show-overflow-tooltip
- />
- <!-- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- min-width="60"
- align="center"
- >
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="openForm('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"
- />
- </div>
-
- <!-- 鎵撳嵃棰勮寮圭獥 -->
- <el-dialog
- v-model="printPreviewVisible"
- title="鎵撳嵃棰勮"
- width="90%"
- :close-on-click-modal="false"
- class="print-preview-dialog"
- >
- <div class="print-preview-container">
- <div class="print-preview-header">
- <el-button type="primary" @click="executePrint">鎵ц鎵撳嵃</el-button>
- <el-button @click="printPreviewVisible = false">鍏抽棴棰勮</el-button>
- </div>
- <div class="print-preview-content">
- <div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
- 鏆傛棤鎵撳嵃鏁版嵁
- </div>
- <div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
- 鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
- </div>
- <div v-for="(item, index) in printData" :key="index" class="print-page">
- <div class="delivery-note">
- <div class="header">
- <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
- <div class="document-title">闆跺敭鍙戣揣鍗�</div>
- </div>
-
- <div class="info-section">
- <div class="info-row">
- <div>
- <span class="label">鍙戣揣鏃ユ湡锛�</span>
- <span class="value">{{ formatDate(item.createTime) }}</span>
- </div>
- <div>
-
- <span class="label">瀹㈡埛鍚嶇О锛�</span>
- <span class="value">{{ item.supplierName || '寮犵埍鏈�' }}</span>
- </div>
- </div>
- <div class="info-row">
- <span class="label">鍗曞彿锛�</span>
- <span class="value">{{ item.code }}</span>
- </div>
- </div>
-
- <div class="table-section">
- <table class="product-table">
- <thead>
- <tr>
- <th>浜у搧鍚嶇О</th>
- <th>瑙勬牸鍨嬪彿</th>
- <th>鍗曚綅</th>
- <th>鍗曚环</th>
- <th>闆跺敭鏁伴噺</th>
- <th>闆跺敭閲戦</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>{{ item.productCategory || '鐮傜伆鐮�' }}</td>
- <td>{{ item.specificationModel || '鏍囧噯' }}</td>
- <td>{{ item.unit || '鍧�' }}</td>
- <td>{{ item.taxInclusiveUnitPrice || '0' }}</td>
- <td>{{ item.inboundNum || '2000' }}</td>
- <td>{{ item.taxInclusiveTotalPrice || '0' }}</td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td class="label">鍚堣</td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value">{{ item.inboundNum || '2000' }}</td>
- <td class="total-value">{{ item.taxInclusiveTotalPrice || '0' }}</td>
- </tr>
- </tfoot>
- </table>
- </div>
-
- <div class="footer-section">
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鏀惰揣鐢佃瘽锛�</span>
- <span class="value"></span>
- </div>
- <div class="footer-item">
- <span class="label">鏀惰揣浜猴細</span>
- <span class="value"></span>
- </div>
- <div class="footer-item address-item">
- <span class="label">鏀惰揣鍦板潃锛�</span>
- <span class="value address-value"></span>
- </div>
- </div>
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鎿嶄綔鍛橈細</span>
- <span class="value">{{ userStore.nickName || '鎾曞紑鍓�' }}</span>
- </div>
- <div class="footer-item">
- <span class="label">鎵撳嵃鏃ユ湡锛�</span>
- <span class="value">{{ formatDateTime(new Date()) }}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </el-dialog>
-
-
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import useUserStore from "@/store/modules/user";
-import {
- getStockOutPage,
- delStockOut,
-} from "@/api/inventoryManagement/stockOut.js";
-
-const userStore = useUserStore();
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-
-// 鎵撳嵃鐩稿叧
-const printPreviewVisible = ref(false);
-const printData = ref([]);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const data = reactive({
- searchForm: {
- supplierName: "",
- timeStr: "",
- },
- form: {
- supplierId: null,
- supplierName: '',
- productId: null,
- productName: '',
- userId: userStore.userId,
- nickName: '',
- model: '',
- productModelId: null,
- unit: '',
- productrecordId: null,
- taxInclusiveUnitPrice: '',
- taxInclusiveTotalPrice: '',
- taxRate: '',
- taxExclusiveTotalPrice: '',
- inboundTime: '',
- inboundBatch: '',
- inboundQuantity: ''
- },
-});
-const { searchForm } = toRefs(data);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- getStockOutPage({ ...searchForm.value, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- tableData.value.map((item) => {
- item.children = [];
- });
- total.value = res.data.total;
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter((item) => item.id);
- console.log("selection", selectedRows.value);
-};
-const expandedRowKeys = ref([]);
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, [
- "contractAmount",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/stockmanagement/export", {}, "鍑哄簱鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鍒犻櫎
-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(() => {
- delStockOut({ids:ids}).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鎵撳嵃鍔熻兘
-const handlePrint = () => {
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
- return;
- }
- printData.value = [...selectedRows.value];
- console.log('鎵撳嵃鏁版嵁:', printData.value);
- printPreviewVisible.value = true;
-};
-
-// 鎵ц鎵撳嵃
-const executePrint = () => {
- console.log('寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:', printData.value.length);
- console.log('鎵撳嵃鏁版嵁:', printData.value);
-
- // 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
- const printWindow = window.open('', '_blank', 'width=800,height=600');
-
- // 鏋勫缓鎵撳嵃鍐呭
- let printContent = `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>鎵撳嵃棰勮</title>
- <style>
- body {
- margin: 0;
- padding: 0;
- font-family: "SimSun", serif;
- background: white;
- }
- .print-page {
- width: 200mm;
- height: 75mm;
- padding: 10mm;
- padding-left: 20mm;
- background: white;
- box-sizing: border-box;
- page-break-after: always;
- page-break-inside: avoid;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
- .delivery-note {
- width: 100%;
- height: 100%;
- font-size: 12px;
- line-height: 1.2;
- display: flex;
- flex-direction: column;
- color: #000;
- }
- .header {
- text-align: center;
- margin-bottom: 8px;
- }
- .company-name {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 4px;
- }
- .document-title {
- font-size: 16px;
- font-weight: bold;
- }
- .info-section {
- margin-bottom: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .info-row {
- line-height: 20px;
- }
- .label {
- font-weight: bold;
- width: 60px;
- font-size: 12px;
- }
- .value {
- margin-right: 20px;
- min-width: 80px;
- font-size: 12px;
- }
- .table-section {
- margin-bottom: 40px;
- // flex: 0.6;
- }
- .product-table {
- width: 100%;
- border-collapse: collapse;
- border: 1px solid #000;
- }
- .product-table th, .product-table td {
- border: 1px solid #000;
- padding: 6px;
- text-align: center;
- font-size: 12px;
- line-height: 1.4;
- }
- .product-table th {
- font-weight: bold;
- }
- .total-value {
- font-weight: bold;
- }
- .footer-section {
- margin-top: auto;
- }
- .footer-row {
- display: flex;
- margin-bottom: 3px;
- line-height: 22px;
- justify-content: space-between;
- }
- .footer-item {
- display: flex;
- margin-right: 20px;
- }
- .footer-item .label {
- font-weight: bold;
- width: 80px;
- font-size: 12px;
- }
- .footer-item .value {
- min-width: 80px;
- font-size: 12px;
- }
- .address-item .address-value {
- min-width: 200px;
- }
- @media print {
- body {
- margin: 0;
- padding: 0;
- }
- .print-page {
- margin: 0;
- padding: 10mm;
- /* padding-left: 20mm; */
- page-break-inside: avoid;
- page-break-after: always;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
- }
- </style>
- </head>
- <body>
- `;
-
- // 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
- printData.value.forEach((item, index) => {
- printContent += `
- <div class="print-page">
- <div class="delivery-note">
- <div class="header">
- <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
- <div class="document-title">闆跺敭鍙戣揣鍗�</div>
- </div>
-
- <div class="info-section">
- <div class="info-row">
- <div>
- <span class="label">鍙戣揣鏃ユ湡锛�</span>
- <span class="value">${formatDate(item.createTime)}</span>
- </div>
- <div>
- <span class="label">瀹㈡埛鍚嶇О锛�</span>
- <span class="value">${item.supplierName || '寮犵埍鏈�'}</span>
- </div>
- </div>
- <div class="info-row">
- <span class="label">鍗曞彿锛�</span>
- <span class="value">${item.code || ''}</span>
- </div>
- </div>
-
- <div class="table-section">
- <table class="product-table">
- <thead>
- <tr>
- <th>浜у搧鍚嶇О</th>
- <th>瑙勬牸鍨嬪彿</th>
- <th>鍗曚綅</th>
- <th>鍗曚环</th>
- <th>闆跺敭鏁伴噺</th>
- <th>闆跺敭閲戦</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>${item.productCategory || '鐮傜伆鐮�'}</td>
- <td>${item.specificationModel || '鏍囧噯'}</td>
- <td>${item.unit || '鍧�'}</td>
- <td>${item.taxInclusiveUnitPrice || '0'}</td>
- <td>${item.inboundNum || '2000'}</td>
- <td>${item.taxInclusiveTotalPrice || '0'}</td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td class="label">鍚堣</td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value">${item.inboundNum || '2000'}</td>
- <td class="total-value">${item.taxInclusiveTotalPrice || '0'}</td>
- </tr>
- </tfoot>
- </table>
- </div>
-
- <div class="footer-section">
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鏀惰揣鐢佃瘽锛�</span>
- <span class="value"></span>
- </div>
- <div class="footer-item">
- <span class="label">鏀惰揣浜猴細</span>
- <span class="value"></span>
- </div>
- <div class="footer-item address-item">
- <span class="label">鏀惰揣鍦板潃锛�</span>
- <span class="value address-value"></span>
- </div>
- </div>
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鎿嶄綔鍛橈細</span>
- <span class="value">${userStore.nickName || '鎾曞紑鍓�'}</span>
- </div>
- <div class="footer-item">
- <span class="label">鎵撳嵃鏃ユ湡锛�</span>
- <span class="value">${formatDateTime(new Date())}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- `;
- });
-
- printContent += `
- </body>
- </html>
- `;
-
- // 鍐欏叆鍐呭鍒版柊绐楀彛
- printWindow.document.write(printContent);
- printWindow.document.close();
-
- // 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
- printWindow.onload = () => {
- setTimeout(() => {
- printWindow.print();
- printWindow.close();
- printPreviewVisible.value = false;
- }, 500);
- };
-};
-
-
-
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (dateString) => {
- if (!dateString) return getCurrentDate();
- const date = new Date(dateString);
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- return `${year}/${month}/${day}`;
-};
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (date) => {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- const hours = String(date.getHours()).padStart(2, "0");
- const minutes = String(date.getMinutes()).padStart(2, "0");
- const seconds = String(date.getSeconds()).padStart(2, "0");
- return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.print-preview-dialog {
- .el-dialog__body {
- padding: 0;
- max-height: 80vh;
- overflow-y: auto;
- }
-}
-
-.print-preview-container {
- .print-preview-header {
- padding: 15px;
- border-bottom: 1px solid #e4e7ed;
- text-align: center;
-
- .el-button {
- margin: 0 10px;
- }
- }
-
- .print-preview-content {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 400px;
- }
-}
-
-.print-page {
- width: 220mm;
- height: 90mm;
- padding: 10mm;
- margin: 0 auto;
- background: white;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
- margin-bottom: 10px;
- box-sizing: border-box;
-}
-
-.delivery-note {
- width: 100%;
- height: 100%;
- font-family: "SimSun", serif;
- font-size: 10px;
- line-height: 1.2;
- display: flex;
- flex-direction: column;
-}
-
-.header {
- text-align: center;
- margin-bottom: 8px;
-
- .company-name {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 4px;
- }
-
- .document-title {
- font-size: 16px;
- font-weight: bold;
- }
-}
-
-.info-section {
- margin-bottom: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .info-row {
- line-height: 20px;
-
- .label {
- font-weight: bold;
- width: 60px;
- font-size: 14px;
- }
-
- .value {
- margin-right: 20px;
- min-width: 80px;
- font-size: 14px;
- }
- }
-}
-
-.table-section {
- margin-bottom: 4px;
- flex: 1;
-
- .product-table {
- width: 100%;
- border-collapse: collapse;
- border: 1px solid #000;
-
- th, td {
- border: 1px solid #000;
- padding: 6px;
- text-align: center;
- font-size: 14px;
- line-height: 1.4;
- }
-
- th {
- font-weight: bold;
- }
-
- .total-label {
- text-align: right;
- font-weight: bold;
- }
-
- .total-value {
- font-weight: bold;
- }
- }
-}
-
-.footer-section {
- .footer-row {
- display: flex;
- margin-bottom: 3px;
- line-height: 20px;
- justify-content: space-between;
-
- .footer-item {
- display: flex;
- margin-right: 20px;
-
- .label {
- font-weight: bold;
- width: 80px;
- font-size: 14px;
- }
-
- .value {
- min-width: 80px;
- font-size: 14px;
- }
-
- &.address-item {
- .address-value {
- min-width: 200px;
- }
- }
- }
- }
-}
-
-@media print {
- .app-container {
- display: none;
- }
-
- .print-page {
- box-shadow: none;
- margin: 0;
- padding: 10mm;
- padding-left: 20mm;
- page-break-inside: avoid;
- page-break-after: always;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
-}
-</style>
diff --git a/src/views/inventoryManagement/index.vue b/src/views/inventoryManagement/index.vue
deleted file mode 100644
index f371e26..0000000
--- a/src/views/inventoryManagement/index.vue
+++ /dev/null
@@ -1,309 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鍙戞斁瀛e害锛�</span>
- <el-select
- style="width: 200px;"
- @change="handleQuery"
- v-model="searchForm.season"
- placeholder="璇烽�夋嫨"
- :clearable="false"
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in jidu" :key="item.value" />
- </el-select>
- <span class="search_title ml10">鍛樺伐鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.staffName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="deleteRow(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <div class="table_list">
- <el-table
- ref="tableRef"
- v-loading="tableLoading"
- :data="tableData"
- border
- height="calc(100vh - 21em)"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- style="width: 100%"
- @selection-change="handleSelectionChange"
- >
- <!-- 閫夋嫨鍒� -->
- <el-table-column
- align="center"
- type="selection"
- width="55"
- fixed="left"
- />
-
- <!-- 搴忓彿鍒� -->
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- fixed="left"
- />
-
- <!-- 鍥哄畾鍒楋細濮撳悕 -->
- <el-table-column
- label="濮撳悕"
- prop="staffName"
- width="100"
- show-overflow-tooltip
- align="center"
- fixed="left"
- />
-
- <!-- 鍥哄畾鍒楋細宸ュ彿 -->
- <el-table-column
- label="宸ュ彿"
- prop="staffNo"
- width="100"
- show-overflow-tooltip
- align="center"
- fixed="left"
- />
-
- <!-- 鍔ㄦ�佸垪锛氭牴鎹瓧鍏告覆鏌� -->
- <el-table-column
- v-for="(dictItem, index) in sys_lavor_issue"
- :key="dictItem.value"
- :label="dictItem.label"
- :prop="dictItem.value"
- show-overflow-tooltip
- >
- </el-table-column>
-
- <!-- 鎿嶄綔鍒� -->
- <el-table-column
- label="鎿嶄綔"
- width="150"
- align="center"
- fixed="right"
- >
- <template #default="scope">
- <el-button
- type="primary"
- link
- size="small"
- @click="edit(scope.row)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="danger"
- link
- size="small"
- :disabled="!!scope.row.adoptedDate"
- @click="adopted(scope.row)"
- >
- 棰嗙敤
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination :total="total" layout="total, sizes, prev, pager, next, jumper"
- :page="page.current" :limit="page.size" @pagination="paginationChange" />
- </div>
- <!-- <Modal ref="modalRef" @success="handleQuery"></Modal> -->
- <!-- <files-dia ref="filesDia"></files-dia> -->
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, reactive, toRefs, nextTick, getCurrentInstance } from 'vue'
-import dayjs from "dayjs";
-// import Modal from "./Modal.vue";
-// import FilesDia from "./filesDia.vue";
-import Pagination from "@/components/Pagination/index.vue";
-import {listPage, deleteLedger, update} from "@/api/lavorissce/ledger.js";
-import {ElMessageBox, ElMessage} from "element-plus";
-const { proxy } = getCurrentInstance();
-import { getCurrentMonth } from "@/utils/util"
-
-const page = ref({
- current: 1,
- size: 100,
-})
-const total = ref(0)
-// 鍝嶅簲寮忔暟鎹�
-const tableRef = ref(null)
-const tableData = ref([])
-const tableLoading = ref(false)
-const { sys_lavor_issue } = proxy.useDict("sys_lavor_issue")
-const data = reactive({
- searchForm: {
- season: "",
- staffName: "",
- },
-});
-const { searchForm } = toRefs(data);
-
-const modalRef = ref();
-// const filesDia = ref();
-const multipleList = ref([]);
-const jidu = ref([
- {
- value: '1',
- label: '绗竴瀛e害'
- },
- {
- value: '2',
- label: '绗簩瀛e害'
- },
- {
- value: '3',
- label: '绗笁瀛e害'
- },
- {
- value: '4',
- label: '绗洓瀛e害'
- }
-])
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.value.current = 1;
- getList();
-};
-// 鑾峰彇瀛楀吀鏁版嵁
-const getList = async () => {
- tableLoading.value = true;
- const params = { ...searchForm.value, ...page.value };
- listPage(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- total.value = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-const add = () => {
- modalRef.value.openModal();
-};
-const edit = (row) => {
- modalRef.value.loadForm(row);
-};
-const deleteRow = (id) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await deleteLedger(id);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "鍒犻櫎鎴愬姛",
- });
- await getList();
- }
- });
-};
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/lavorIssue/exportCopy`, {season: searchForm.value.season}, "鍔充繚鍙拌处.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-const adopted = (row) => {
- ElMessageBox.confirm("鏄惁纭棰嗙敤?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const params = {
- id: row.id,
- adoptedDate: dayjs().format("YYYY-MM-DD")
- }
- const { code } = await update(params);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "棰嗙敤鎴愬姛",
- });
- await getList();
- }
- })
-}
-// 鎵撳紑闄勪欢寮规
-// const openFilesFormDia = (row) => {
-// nextTick(() => {
-// filesDia.value?.openDialog( row,'鏀跺叆')
-// })
-// };
-// 浜嬩欢澶勭悊鍑芥暟
-const handleSelectionChange = (selection) => {
- multipleList.value = selection;
-}
-
-const paginationChange = (pagination) => {
- page.value.current = pagination.page;
- page.value.size = pagination.limit;
- getList();
-}
-
-// 缁勪欢鎸傝浇鏃跺姞杞藉瓧鍏告暟鎹�
-onMounted(() => {
- handleQuery()
-})
-</script>
-
-<style scoped>
-.dynamic-table-container {
- width: 100%;
-}
-
-.pagination-container {
- margin-top: 20px;
- display: flex;
- justify-content: flex-end;
-}
-
-:deep(.el-table .el-table__header-wrapper th) {
- background-color: #F0F1F5 !important;
- color: #333333;
- font-weight: 600;
-}
-
-:deep(.el-table .el-table__body-wrapper td) {
- padding: 8px 0;
-}
-
-:deep(.el-select) {
- width: 100%;
-}
-
-:deep(.el-input) {
- width: 100%;
-}
-</style>
diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
deleted file mode 100644
index d8ce8f8..0000000
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ /dev/null
@@ -1,293 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
- <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
- clearable prefix-icon="Search" />
- <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.timeStr"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- @change="handleQuery"
- />
- <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">
- <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" height="calc(100vh - 18.5em)">
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
- <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
- <el-table-column label="搴撳瓨鏁伴噺" prop="inboundNum0" width="90" show-overflow-tooltip />
- <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm(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" />
- </div>
- <el-dialog v-model="dialogFormVisible" :title="'鏂板鍑哄簱'" width="40%" @close="closeDia">
- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
- <el-form-item label="鍑哄簱鏁伴噺锛�" prop="salesContractNo">
- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.inboundQuantity" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- <el-form-item label="鍑哄簱鏃ユ湡锛�" prop="projectName">
- <el-date-picker style="width: 100%" v-model="form.inboundTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
- type="date" placeholder="璇烽�夋嫨" clearable />
- </el-form-item>
- <el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
- <el-select v-model="form.nickName" placeholder="璇烽�夋嫨" clearable>
- <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
- </el-select>
- </el-form-item>
- </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>
- </div>
-</template>
-
-<script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
-import { userListNoPageByTenantId } from "@/api/system/user.js";
-import {
- getStockInPage
-} from "@/api/inventoryManagement/stockIn.js";
-import {
- getStockManagePage,
- delStockManage,
- stockOut,
-} from "@/api/inventoryManagement/stockManage.js";
-
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
-const tableData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
-const tableLoading = ref(false)
-const page = reactive({
- current: 1,
- size: 100,
-})
-const total = ref(0)
-const fileList = ref([])
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const dialogFormVisible = ref(false)
-const data = reactive({
- searchForm: {
- supplierName: '',
- inboundQuantity:'',
- inboundTime:'',
- nickName: '',
- userId: '',
- timeStr: '',
- },
- form: {
- productrecordId: '',
- },
- rules: {
- inboundTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- inboundQuantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- nickname: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }]
- }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1
- getList()
-}
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList()
-}
-const getList = () => {
- tableLoading.value = true
- getStockInPage({ ...searchForm.value, ...page }).then(res => {
- tableLoading.value = false
- tableData.value = res.data.records
- total.value = res.data.total
- console.log('res', res.data.records)
- }).catch(() => {
- tableLoading.value = false
- })
-}
-
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode.label; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.id);
- console.log('selection', selectedRows.value)
-}
-const expandedRowKeys = ref([])
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-};
-const currentRowId = ref(null) // 鏂板锛氬瓨鍌ㄥ綋鍓嶆搷浣滅殑琛孖D
-
-const currentRowNum = ref(0)
-const salesLedgerProductId = ref(null);
-
-// 鎵撳紑寮规
-const openForm = async (row) => {
- dialogFormVisible.value = true
- currentRowId.value = row.id
- currentRowNum.value = row.inboundNum0
- salesLedgerProductId.value = row.salesLedgerProductId
- form.value = {}
- // 鍒濆鍖栬〃鍗曟暟鎹�
- form.value = {
- productrecordId: '',
- inboundQuantity: '', // 鍑哄簱鏁伴噺娓呯┖
- inboundTime: getCurrentDate(), // 榛樿褰撳墠鏃ユ湡
- nickName: '', // 榛樿褰撳墠鐢ㄦ埛
- }
- console.log('form',form.value)
- // 鍔犺浇鐢ㄦ埛鍒楄〃
- try {
- const userLists = await userListNoPageByTenantId()
- userList.value = userLists.data
- } catch (error) {
- console.error('鍔犺浇鐢ㄦ埛鍒楄〃澶辫触:', error)
- }
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- let num = Number(form.value.inboundQuantity)
- if(num <= 0 || num > currentRowNum.value){
- return proxy.$modal.msgWarning("璇峰~鍏ユ湁鏁堟暟瀛�")
- }
- proxy.$refs["formRef"].validate(valid => {
- if (valid && currentRowId.value) {
- const outData = {
- id: currentRowId.value, // 鍘熷璁板綍ID
- salesLedgerProductId: salesLedgerProductId.value,
- quantity: form.value.inboundQuantity, // 鍑哄簱鏁伴噺
- time: form.value.inboundTime, // 鍑哄簱鏃堕棿
- userId: form.value.nickName // 鎿嶄綔浜�
- }
- console.log(outData)
-
- stockOut(outData).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
- closeDia()
- getList()
- }).catch(err => {
- proxy.$modal.msgError("鍑哄簱澶辫触")
- })
- }
- })
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef")
- dialogFormVisible.value = false
-}
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm(
- '鏄惁纭瀵煎嚭锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
-}
-// 鍒犻櫎
-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(() => {
- delStockManage(ids).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
-}
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, '0'); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
-}
-onMounted(() => {
- getList()
-})
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
deleted file mode 100644
index 3db10d7..0000000
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ /dev/null
@@ -1,558 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
- <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
- clearable prefix-icon="Search" />
- <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.timeStr"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- @change="handleQuery"
- />
- <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">
- <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" height="calc(100vh - 18.5em)">
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鎵规" prop="inboundBatches" width="160" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
- <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
- <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm('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" />
- </div>
-
- <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">
- <el-form-item label="閲囪喘璁㈠崟鍙�" prop="purchaseContractNumber">
- <el-select
- v-model="form.purchaseContractNumber"
- placeholder="璇烽�夋嫨閲囪喘璁㈠崟鍙�"
- clearable
- filterable
- remote
- :remote-method="loadPurchaseOptions"
- :loading="loadingPurchaseOptions"
- @change="handlePurchaseChange"
- :disabled="operationType === 'edit'"
- style="width: 100%"
- >
- <el-option
- v-for="item in purchaseOptions"
- :key="item.purchaseContractNumber"
- :label="formatPurchaseOption(item)"
- :value="item.purchaseContractNumber"
- />
- </el-select>
- </el-form-item>
- <el-table
- :data="productList"
- border
- v-loading="loadingProducts"
- @selection-change="handleSelectionChange"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="100" />
- <el-table-column label="閲囪喘鏁伴噺" prop="quantity" width="100" />
- <el-table-column label="寰呭叆搴撴暟閲�" prop="quantity0" width="100" />
- <el-table-column label="鏈鍏ュ簱鏁伴噺" prop="quantityStock" width="150">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
- </template>
- </el-table-column>
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="120" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
-import {
- getStockInPage,
- updateStockIn,
- addSutockIn,
- delStockIn,
- selectProductRecordListByPuechaserId
-} from "@/api/inventoryManagement/stockIn.js";
-import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js";
-
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
-
-const tableData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
-
-const purchaseOptions = ref([])
-const loadingPurchaseOptions = ref(false)
-
-
-const loading = ref(false);
-const tableLoading = ref(false)
-
-const page = reactive({
- current: 1,
- size: 100,
-})
-const total = ref(0)
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')// 鎿嶄綔绫诲瀷: 'add' 鎴� 'edit'
-const dialogFormVisible = ref(false)// 寮规鏄剧ず鐘舵��
-const productList = ref([]);// 浜у搧鍒楄〃鏁版嵁
-const loadingProducts = ref(false);// 浜у搧鍔犺浇鐘舵��
-const productSelectedRows = ref([]) // 浜у搧琛ㄦ牸閫変腑琛�
-const data = reactive({
- searchForm: {
- supplierName: '',
- timeStr: '',
- },
- form: {
- id: null,
- purchaseContractNumber: '', // 閲囪喘璁㈠崟鍙�
- supplierId: null, // 渚涘簲鍟咺D
- supplierName: '', // 渚涘簲鍟嗗悕绉�
- inboundTime: '', // 鍏ュ簱鏃堕棿
- inboundBatch: '', // 鍏ュ簱鎵规
- recorderId: userStore.userId, // 褰曞叆浜篒D
- recorderName: userStore.name, // 褰曞叆浜哄鍚�
- entryDate: getCurrentDate(), // 褰曞叆鏃ユ湡
- remark: '', // 澶囨敞
- },
- rules: {
- purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
- supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
- inboundTime: [{ required: true, message: "璇烽�夋嫨鍏ュ簱鏃堕棿", trigger: "change" }],
- inboundBatch: [{ required: true, message: "璇疯緭鍏ュ叆搴撴壒娆�", trigger: "blur" }]
- }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-const formatPurchaseOption = (item = {}) => {
- const contract = item.purchaseContractNumber || '--';
- const supplier = item.supplierName ? ` 路 ${item.supplierName}` : '';
- return `${contract}${supplier}`;
-};
-
-const loadPurchaseOptions = async (keyword = '') => {
- try {
- loadingPurchaseOptions.value = true;
- const res = await purchaseListPage({
- current: -1,
- size: -1,
- purchaseContractNumber: keyword,
- });
- const records = res.data?.records || [];
- purchaseOptions.value = records;
- if (
- form.value.purchaseContractNumber &&
- !purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === form.value.purchaseContractNumber
- )
- ) {
- purchaseOptions.value.push({
- purchaseContractNumber: form.value.purchaseContractNumber,
- supplierName: form.value.supplierName,
- supplierId: form.value.supplierId,
- });
- }
- } finally {
- loadingPurchaseOptions.value = false;
- }
-};
-
-const handlePurchaseChange = (value) => {
- form.value.purchaseContractNumber = value || '';
- const matched = purchaseOptions.value.find(
- (item) => item.purchaseContractNumber === value
- );
- if (matched) {
- form.value.supplierName = matched.supplierName || form.value.supplierName;
- form.value.supplierId = matched.supplierId || form.value.supplierId;
- }
- if (!value) {
- productList.value = [];
- return;
- }
- fetchProductsByContract();
-};
-const exceedsAddLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting)) {
- return false;
- }
- return stock > waiting;
-};
-
-const exceedsEditLimit = (product) => {
- const stock = Number(product?.quantityStock ?? 0);
- const waiting = Number(product?.quantity0 ?? 0);
- const original = Number(product?.originalQuantityStock ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) {
- return false;
- }
- return stock > waiting + original;
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1
- getList()
-}
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList()
-}
-const getList = () => {
- tableLoading.value = true
- getStockInPage({ ...searchForm.value, ...page }).then(res => {
- tableLoading.value = false
- tableData.value = res.data.records
- total.value = res.data.total
- console.log('tableData:', tableData.value)
- }).catch(() => {
- tableLoading.value = false
- })
-}
-
-
-// 璋冪敤selectProductRecordListByPuechaserId杩欎釜鏂规硶鏍规嵁鍚堝悓鏌ヨ鍒癷d锛屽啀璋冪敤getProductRecordByhetong杩欎釜鏂规硶鏍规嵁id鏌ヨ鍒颁骇鍝佽鍗曡褰�
-// 鏂板鏍规嵁鍚堝悓鍙锋煡璇骇鍝佽褰曠殑鏂规硶
-const fetchProductsByContract = async () =>
-{
- if (!form.value.purchaseContractNumber) {
- proxy.$modal.msgWarning('璇烽�夋嫨鍚堝悓鍙�')
- return
- }
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鏌ヨ浜у搧璁板綍
- const productRes = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber
- });
- console.log('productRes:', productRes)
- if (!productRes.data || productRes.data.length === 0) {
- proxy.$modal.msgWarning('璇ュ悎鍚屼笅娌℃湁浜у搧璁板綍')
- productList.value = [];
- return
- }
- // 澶勭悊浜у搧鏁版嵁锛屾坊鍔犳湰娆″叆搴撴暟閲忓瓧娈�
- productList.value = productRes.data.map(item => ({
- ...item,
- quantityStock: 0,
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0),
- }))
- } catch (error) {
- console.error('鏌ヨ浜у搧璁板綍澶辫触:', error)
- proxy.$modal.msgError('鏌ヨ浜у搧璁板綍澶辫触')
- productList.value = [];
- } finally {
- loadingProducts.value = false
- }
-}
-
-
-// 鎵撳紑寮规
- const openForm = async (type, row) => {
- operationType.value = type
- dialogFormVisible.value = true
- selectedRows.value = []
- await loadPurchaseOptions();
-
- if (type === 'add') {
- // 鏂板鏃跺垵濮嬪寲琛ㄥ崟
- form.value = {
- id: null,
- purchaseContractNumber: '',
- supplierId: null,
- supplierName: '',
- inboundTime: '',
- inboundBatch: '',
- recorderId: userStore.userId,
- recorderName: userStore.name,
- entryDate: getCurrentDate(),
- remark: ''
- }
- productList.value = [] // 娓呯┖浜у搧鍒楄〃
- } else {
- form.value = JSON.parse(JSON.stringify(row))
- try {
- loadingProducts.value = true
- // 鏍规嵁鍚堝悓鍙峰姞杞藉搴旂殑浜у搧鍒楄〃锛堝亣璁� getProductByContract 鏄彲鐢ㄦ帴鍙o級
- const res = await selectProductRecordListByPuechaserId({
- purchaseContractNumber: form.value.purchaseContractNumber,
- id: row.id
- });
- productList.value = res.data.map(item => ({
- ...item,
- quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0),
- }))
- selectedRows.value = productList.value
- } catch (error) {
- console.error('鍔犺浇浜у搧澶辫触:', error)
- proxy.$modal.msgError('鍔犺浇浜у搧澶辫触')
- productList.value = []
- } finally {
- loadingProducts.value = false
- }
- }
- }
-
- const updatePro = async () => {
- // 鍑嗗鎻愪氦鏁版嵁
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨浜у搧');
- return;
- }
- const target = selectedRows.value[0];
- const stock = Number(target?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- proxy.$modal.msgWarning('璇峰~鍐欐湁鏁堢殑鍏ュ簱鏁伴噺');
- return;
- }
- if (exceedsEditLimit(target)) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺涓嶈兘瓒呰繃鍘熷叆搴撴暟閲忎笌寰呭叆搴撴暟閲忎箣鍜�');
- return;
- }
- const stockInData = {
- id: selectedRows.value[0].recordId,
- quantityStock: Number(selectedRows.value[0].quantityStock),// 浣跨敤鏂版牸寮忓寲鍑芥暟
- };
- await updateStockIn(stockInData)
- proxy.$modal.msgSuccess('淇敼鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
- }
-
-// 鎻愪氦琛ㄥ崟
- const submitForm = async () => {
- // 楠岃瘉鑷冲皯閫夋嫨浜嗕竴涓骇鍝�
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning('璇峰厛閫夋嫨閲囪喘鍚堝悓骞堕�夋嫨浜у搧')
- return
- }
- if(operationType.value !== 'add'){
- await updatePro()
- return
- }
- try {
- await proxy.$refs.formRef.validate()
- // 楠岃瘉鍏ュ簱鏁伴噺
- const invalidProducts = selectedRows.value.filter((product) => {
- const stock = Number(product?.quantityStock ?? 0);
- if (!Number.isFinite(stock) || stock <= 0) {
- return true;
- }
- return exceedsAddLimit(product);
- })
-
- if (invalidProducts.length > 0) {
- proxy.$modal.msgError('鏈鍏ュ簱鏁伴噺闇�澶т簬0锛屼笖涓嶈兘瓒呰繃寰呭叆搴撴暟閲�')
- return
- }
-
- // 鍑嗗鎻愪氦鏁版嵁 - 淇敼涓哄悗绔渶瑕佺殑鏍煎紡
- const stockInData = {
- // 鍏ュ簱鍗曞熀鏈俊鎭�
- ...form.value,
- inboundTime: formatDateTime(form.value.inboundTime),
- nickName: userStore.nickName,
- details: selectedRows.value.map(product => ({
- id: product.id,
- // id: product.salesLedgerProductId,
- inboundQuantity: Number(product.quantityStock)
- })),
- };
- // 璋冪敤API
- loading.value = true
- await addSutockIn(stockInData)
-
- proxy.$modal.msgSuccess('鏂板鍏ュ簱鎴愬姛')
- closeDia()
- getList() // 鍒锋柊鍒楄〃
-
- } catch (error) {
- console.error('鎻愪氦澶辫触:', error)
- if (!error.errors) {
- proxy.$modal.msgError('鎿嶄綔澶辫触锛岃閲嶈瘯')
- }
- } finally {
- loading.value = false
- }
- }
-
-// 鍏抽棴寮规
- const closeDia = () => {
- proxy.$refs.formRef.resetFields()
- dialogFormVisible.value = false
-
- }
-// 琛ㄦ牸閫夋嫨鏁版嵁
- const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.id);
- }
-
- const expandedRowKeys = ref([])
-
-// 涓昏〃鍚堣鏂规硶
- const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
- };
-
-// 瀵煎嚭
- const handleOut = () => {
- ElMessageBox.confirm(
- '鏄惁纭瀵煎嚭锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- proxy.download("/stockin/export", {}, '鍏ュ簱鍙拌处.xlsx')
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-// 鍒犻櫎
- const handleDelete = () => {
- let ids = []
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map(item => item.id);
- } else {
- proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
- return
- }
- ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- delStockIn({ids:ids}).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
- }
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-// 淇敼涓烘洿閫氱敤鐨勬棩鏈熸椂闂存牸寮忓寲鍑芥暟
-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}`; // 淇濇寔鍘熸湁 getCurrentDate 鍔熻兘
- }
-
- // 鏂板鏃堕棿閮ㄥ垎鏍煎紡鍖�
- 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}`;
-}
-
-// 淇濇寔鍘熸湁 getCurrentDate 鐨勫吋瀹规��
-function getCurrentDate() {
- return formatDateTime(new Date(), false);
-}
-
-
-
-
- onMounted(() => {
- getList()
- })
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/inventoryManagement/stockManagement/index.vue b/src/views/inventoryManagement/stockManagement/index.vue
deleted file mode 100644
index f80aa94..0000000
--- a/src/views/inventoryManagement/stockManagement/index.vue
+++ /dev/null
@@ -1,426 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉帮細</span>
- <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" @change="handleQuery"
- clearable prefix-icon="Search" />
- <span class="search_title ml10">鍏ュ簱鏃ユ湡锛�</span>
- <el-date-picker
- v-model="searchForm.timeStr"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- @change="handleQuery"
- />
- <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">
- <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%"
- :row-class-name="tableRowClassName"
- :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="鍏ュ簱鏃ユ湡" prop="createTime" width="100" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被" prop="productCategory" width="100" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="200" show-overflow-tooltip />
- <el-table-column label="鍗曚綅" prop="unit" width="80" show-overflow-tooltip />
- <el-table-column label="搴撳瓨鏁伴噺" prop="inboundNum0" width="100" show-overflow-tooltip />
- <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="130" show-overflow-tooltip />
- <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="100" show-overflow-tooltip />
- <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
- <el-table-column label="鍏ュ簱浜�" prop="createBy" width="80" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm('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" />
- </div>
- <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">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input disabled v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浜у搧澶х被锛�" prop="productId">
- <el-select disabled v-model="form.productCategory" placeholder="璇烽�夋嫨" clearable filterable>
- <el-option v-for="item in productList" :key="item.id" :label="item.productName"
- :value="item.productName" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productManageId">
- <el-select disabled v-model="form.specificationModel" placeholder="璇峰厛閫夋嫨浜у搧澶х被" clearable filterable :disabled="!form.productCategory">
- <el-option v-for="item in productModelList" :key="item.id" :label="item.model"
- :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍗曚綅锛�" prop="customerId">
- <el-input disabled v-model="form.unit" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="搴撳瓨鏃堕棿锛�" prop="projectName">
- <el-date-picker style="width: 100%" v-model="form.updateTime" 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="projectName">
- <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="customerId">
- <el-input disabled v-model="form.taxInclusiveUnitPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚◣鎬讳环锛�" prop="customerContractNo">
- <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
-
- <el-col :span="12">
- <el-form-item label="绋庣巼锛�" prop="customerId">
- <el-input disabled v-model="form.taxRate" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓嶅惈绋庢�讳环锛�" prop="entryDate">
- <el-input disabled v-model="form.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍑哄簱浜猴細" prop="entryPerson">
- <el-select v-model="form.createUser" placeholder="璇烽�夋嫨" clearable>
- <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
- </el-select>
- </el-form-item>
- </el-col>
-<!-- <el-col :span="12">-->
-<!-- <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">-->
-<!-- <el-input v-model="form.warnNum" 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>
- </div>
-</template>
-
-<script setup>
-import pagination from '@/components/PIMTable/Pagination.vue'
-import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
-import { ElMessageBox } from "element-plus";
-import useUserStore from '@/store/modules/user'
-import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { productTreeList,modelList } from "@/api/basicData/product.js"
-import {
- getStockManagePage,
- delStockManage,
-} from "@/api/inventoryManagement/stockManage.js";
-import {
- updateManagement,updateStockIn
-} from "@/api/inventoryManagement/stockIn.js";
-
-
-
-const userStore = useUserStore()
-const { proxy } = getCurrentInstance()
-const tableData = ref([])
-const productData = ref([])
-const selectedRows = ref([])
-const userList = ref([])
-const productList = ref([])
-const productModelList = ref([])
-// const customerOption = ref([])
-const tableLoading = ref(false)
-const page = reactive({
- current: 1,
- size: 100,
-})
-const total = ref(0)
-const fileList = ref([])
-const loading = ref(false);
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')
-const dialogFormVisible = ref(false)
-const data = reactive({
- searchForm: {
- supplierName: '',
- timeStr: '',
- },
- form: {
- supplierId: null,
- supplierName: '',
- productId: null,
- productName: '',
- userId: userStore.userId,
- nickName: '',
- productModelId: null,
- model: '',
- unit: '',
- productrecordId: null,
- taxInclusiveUnitPrice: '',
- taxInclusiveTotalPrice: '',
- taxRate: '',
- taxExclusiveTotalPrice: '',
- inboundTime: '',
- inboundBatch: '',
- stockQuantity: '',
- boundTime: '',
- warnNum: '', // 鏂板鏈�浣庡簱瀛樺瓧娈�
- salesLedgerProductId: null,
- },
- rules: {
- supplierName: [{ required: true, message: '璇疯緭鍏ヤ緵搴斿晢鍚嶇О', trigger: 'blur' }],
- productCategory: [{ required: true, message: '璇烽�夋嫨浜у搧澶х被', trigger: 'change' }],
- specificationModel: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
- unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }],
- stockQuantity: [{ required: true, message: '璇疯緭鍏ュ嚭搴撴暟閲�', trigger: 'blur' }],
- taxInclusiveUnitPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' }],
- taxInclusiveTotalPrice: [{ required: true, message: '璇疯緭鍏ュ惈绋庢�讳环', trigger: 'blur' }],
- taxRate: [{ required: true, message: '璇疯緭鍏ョ◣鐜�', trigger: 'blur' }],
- taxExclusiveTotalPrice: [{ required: true, message: '璇疯緭鍏ヤ笉鍚◣鎬讳环', trigger: 'blur' }],
- boundTime: [{ required: true, message: '璇烽�夋嫨搴撳瓨鏃堕棿', trigger: 'change' }],
- inboundTime: [{ required: true, message: '璇烽�夋嫨鍏ュ簱鏃堕棿', trigger: 'change' }],
- inboundPerson: [{ required: true, message: '璇烽�夋嫨鍑哄簱浜�', trigger: 'change' }],
- warnNum: [{ required: true, message: '璇疯緭鍏ユ渶浣庡簱瀛�', trigger: 'blur' }],
- }
-})
-const { searchForm, form, rules } = toRefs(data)
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1
- getList()
-}
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList()
-}
-const getList = () => {
- tableLoading.value = true
- getStockManagePage({ ...searchForm.value, ...page }).then(res => {
- tableLoading.value = false
- tableData.value = res.data.records
- total.value = res.data.total
- // 鏁版嵁鍔犺浇瀹屾垚鍚庢鏌ュ簱瀛�
- // checkStockAndCreatePurchase();
- }).catch(() => {
- tableLoading.value = false
- })
-}
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.id);
- console.log('selection', selectedRows.value)
-}
-const expandedRowKeys = ref([])
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
-};
-
-// 琛ㄦ牸琛岀被鍚�
-const tableRowClassName = ({ row }) => {
- const stock = Number(row?.inboundNum0 ?? 0);
- const warn = Number(row?.warnNum ?? 0);
- if (!Number.isFinite(stock) || !Number.isFinite(warn)) {
- return '';
- }
- return stock < warn ? 'row-low-stock' : '';
-};
-
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
- operationType.value = type
- form.value = {}
- productData.value = []
- let userLists = await userListNoPageByTenantId()
- userList.value = userLists.data
- if (type === 'edit') {
- form.value = { ...row }
- productTreeList().then(res =>{
- productList.value = res
- productList.value.forEach(i =>{
- if (i.label === row.productCategory) {
- modelList({ id: i.id }).then((res) => {
- productModelList.value = res;
- });
- }
- })
- })
- }
- form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
- dialogFormVisible.value = true
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- console.log(form.value)
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
-
- updateManagement(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛")
- closeDia()
- getList()
- // 鎻愪氦鍚庢鏌ュ簱瀛樺苟灏濊瘯鍒涘缓璇疯喘鍗�
- // checkStockAndCreatePurchase();
- })
- }
- })
-}
-// 妫�鏌ュ簱瀛樺苟鍒涘缓璇疯喘鍗�
-// const checkStockAndCreatePurchase = async () => {
-// const stockList = tableData.value;
-// // handList()
-// for (const item of stockList) {
-// if (item.inboundNum0 < item.warnNum) {
-// try {
-// const stockInData = {
-// id: item.id,
-// quantityStock: item.warnNum + item.totalInboundNum,// 浣跨敤鏂版牸寮忓寲鍑芥暟
-// };
-// loading.value = true
-// await updateStockIn(stockInData)
-// proxy.$modal.msgSuccess(`浜у搧 ${item.productCategory} 淇敼鍏ュ簱鎴愬姛`)
-// loading.value = false
-// } catch (error) {
-// proxy.$modal.msgError(`浜у搧 ${item.productCategory} 鐢熸垚璇疯喘鍗曞け璐ワ紝璇锋墜鍔ㄥ鐞哷);
-//
-// }
-// }
-// }
-// };
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef")
- dialogFormVisible.value = false
-}
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm(
- '鏄惁纭瀵煎嚭锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- proxy.download("/stockin/exportCopy", {}, '搴撳瓨淇℃伅.xlsx')
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
-}
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = []
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map(item => item.id);
- } else {
- proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁')
- return
- }
- ElMessageBox.confirm(
- '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- '瀵煎嚭', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning',
- }
- ).then(() => {
- delStockManage({ids:ids}).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- getList()
- })
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�")
- })
-}
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, '0'); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
-}
-onMounted(() => {
- getList()
- // checkStockAndCreatePurchase();
- // 姣忓皬鏃舵鏌ヤ竴娆″簱瀛�
- // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
-
-// onUnmounted(() => {
-// // 缁勪欢鍗歌浇鏃舵竻闄ゅ畾鏃跺櫒
-// clearInterval(intervalId);
-// });
-})
-</script>
-
-<style scoped lang="scss">
-:deep(.row-low-stock td) {
- background-color: #fde2e2;
- color: #c45656;
-}
-
-:deep(.row-low-stock:hover > td) {
- background-color: #fcd4d4;
-}
-</style>
diff --git a/src/views/inventoryManagement/stockReport/index.vue b/src/views/inventoryManagement/stockReport/index.vue
deleted file mode 100644
index 354c775..0000000
--- a/src/views/inventoryManagement/stockReport/index.vue
+++ /dev/null
@@ -1,719 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎼滅储琛ㄥ崟 -->
- <div class="search_form">
- <div class="search_left">
- <span class="search_title">鎶ヨ〃绫诲瀷锛�</span>
- <el-select
- v-model="searchForm.reportType"
- style="width: 150px;"
- placeholder="璇烽�夋嫨"
- @change="handleReportTypeChange"
- >
- <el-option label="鏃ユ姤" value="daily" />
- <el-option label="鏈堟姤" value="monthly" />
- <el-option label="浣滀笟鎶ヨ〃" value="work" />
- <el-option label="杩涘嚭瀛樻姤琛�" value="inout" />
- </el-select>
-
- <span class="search_title ml10">鏃堕棿鑼冨洿锛�</span>
- <el-date-picker
- v-if="searchForm.reportType === 'daily'"
- v-model="searchForm.singleDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 200px;"
- />
- <el-date-picker
- v-else-if="searchForm.reportType === 'monthly'"
- v-model="searchForm.monthRange"
- type="monthrange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫湀浠�"
- end-placeholder="缁撴潫鏈堜唤"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 240px;"
- />
- <el-date-picker
- v-else
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 240px;"
- />
-
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
- 鏌ヨ
- </el-button>
- <el-button @click="handleReset">閲嶇疆</el-button>
- </div>
-
- <div class="search_right">
- <el-button type="success" @click="handleExport" icon="Download">
- 瀵煎嚭鎶ヨ〃
- </el-button>
- </div>
- </div>
-
- <!-- 缁熻鍗$墖 -->
- <div class="stats_cards" v-if="reportData.summary">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-card class="stats_card">
- <div class="stats_content">
- <div class="stats_icon in">
- <el-icon><TrendCharts /></el-icon>
- </div>
- <div class="stats_info">
- <div class="stats_value">{{ reportData.summary.totalIn || 0 }}</div>
- <div class="stats_label">鎬诲叆搴撻噺</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stats_card">
- <div class="stats_content">
- <div class="stats_icon out">
- <el-icon><TrendCharts /></el-icon>
- </div>
- <div class="stats_info">
- <div class="stats_value">{{ reportData.summary.totalOut || 0 }}</div>
- <div class="stats_label">鎬诲嚭搴撻噺</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stats_card">
- <div class="stats_content">
- <div class="stats_icon stock">
- <el-icon><Box /></el-icon>
- </div>
- <div class="stats_info">
- <div class="stats_value">{{ reportData.summary.currentStock || 0 }}</div>
- <div class="stats_label">褰撳墠搴撳瓨</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stats_card">
- <div class="stats_content">
- <div class="stats_icon turnover">
- <el-icon><Refresh /></el-icon>
- </div>
- <div class="stats_info">
- <div class="stats_value">{{ reportData.summary.turnoverRate || 0 }}%</div>
- <div class="stats_label">鍛ㄨ浆鐜�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 鍥捐〃鍖哄煙 -->
- <div class="chart_section" v-if="reportData.chartData">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-card>
- <template #header>
- <span>搴撳瓨瓒嬪娍鍥�</span>
- </template>
- <div ref="trendChart" style="height: 300px;"></div>
- </el-card>
- </el-col>
- <el-col :span="12">
- <el-card>
- <template #header>
- <span>杩涘嚭搴撳姣�</span>
- </template>
- <div ref="comparisonChart" style="height: 300px;"></div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
- <div class="table_section">
- <el-card>
- <template #header>
- <span>{{ getTableTitle() }}</span>
- </template>
- <el-table
- v-loading="tableLoading"
- :data="reportData.tableData"
- border
- height="400"
- style="width: 100%"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column
- v-if="searchForm.reportType === 'daily'"
- label="鏃ユ湡"
- prop="createTime"
- width="100"
- align="center"
- />
- <el-table-column
- v-if="searchForm.reportType === 'monthly'"
- label="鏈堜唤"
- prop="createTime"
- width="100"
- align="center"
- />
- <el-table-column
- label="鍏ュ簱鏃堕棿"
- prop="createTime"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍏ュ簱鎵规"
- prop="inboundBatches"
- width="160"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- min-width="240"
- show-overflow-tooltip
- />
- <el-table-column
- label="浜у搧澶х被"
- prop="productCategory"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- min-width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍗曚綅"
- prop="unit"
- width="70"
- show-overflow-tooltip
- />
- <!-- <el-table-column
- label="鏈熷垵搴撳瓨"
- prop="beginStock"
- width="100"
- align="center"
- /> -->
- <el-table-column
- label="鍏ュ簱鏁伴噺"
- prop="inboundNum"
- width="100"
- align="center"
- />
- <!-- <el-table-column
- label="鍑哄簱鏁伴噺"
- prop=""
- width="100"
- align="center"
- /> -->
- <el-table-column
- label="鐜板湪搴撳瓨"
- prop="inboundNum0"
- width="100"
- align="center"
- />
- <el-table-column
- label="鍚◣鍗曚环"
- prop="taxInclusiveUnitPrice"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚◣鎬讳环"
- prop="taxInclusiveTotalPrice"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="绋庣巼(%)"
- prop="taxRate"
- width="80"
- show-overflow-tooltip
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环"
- prop="taxExclusiveTotalPrice"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍏ュ簱浜�"
- prop="createBy"
- width="80"
- show-overflow-tooltip
- />
- <el-table-column
- v-if="searchForm.reportType === 'work'"
- label="鎿嶄綔浜哄憳"
- prop="operator"
- width="80"
- align="center"
- />
- <el-table-column
- v-if="searchForm.reportType === 'work'"
- label="鎿嶄綔鏃堕棿"
- prop="operateTime"
- width="150"
- align="center"
- />
- </el-table>
- </el-card>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { ElMessage } from 'element-plus'
-import * as echarts from 'echarts'
-import {
- getStockDailyReport,
- getStockMonthlyReport,
- getWorkReport,
- getStockInOutReport,
- exportStockReport
-} from '@/api/inventoryManagement/stockReport'
-
-
-const { proxy } = getCurrentInstance()
-// 鍝嶅簲寮忔暟鎹�
-const tableLoading = ref(false)
-const trendChart = ref(null)
-const comparisonChart = ref(null)
-
-const searchForm = reactive({
- reportType: 'daily',
- singleDate: '',
- dateRange: [],
- monthRange: []
-})
-
-const reportData = ref({
- summary: null,
- chartData: null,
- tableData: []
-})
-
-// 鑾峰彇琛ㄦ牸鏍囬
-const getTableTitle = () => {
- const typeMap = {
- daily: '鏃ユ姤璇︾粏鏁版嵁',
- monthly: '鏈堟姤璇︾粏鏁版嵁',
- work: '浣滀笟鎶ヨ〃璇︾粏鏁版嵁',
- inout: '杩涘嚭瀛樻姤琛ㄨ缁嗘暟鎹�'
- }
- return typeMap[searchForm.reportType] || '鎶ヨ〃璇︾粏鏁版嵁'
-}
-
-// 鎶ヨ〃绫诲瀷鏀瑰彉
-const handleReportTypeChange = () => {
- reportData.value = {
- summary: null,
- chartData: null,
- tableData: []
- }
-}
-
-// 鏌ヨ鏁版嵁
-const handleQuery = async () => {
- if (!validateSearchForm()) {
- return
- }
-
- tableLoading.value = true
- try {
- const params = getQueryParams()
- let response
-
- switch (searchForm.reportType) {
- case 'daily':
- response = await getStockDailyReport(params)
- break
- case 'monthly':
- response = await getStockMonthlyReport(params)
- break
- case 'work':
- response = await getWorkReport(params)
- break
- case 'inout':
- response = await getStockInOutReport(params)
- break
- default:
- throw new Error('鏈煡鐨勬姤琛ㄧ被鍨�')
- }
-
- if (response.code === 200) {
- // generateMockData()
- reportData.value.tableData = response.data.tableData
- reportData.value.summary = response.data.summary
- reportData.value.chartData = response.data.chartData
- nextTick(() => {
- initCharts()
- })
-
- }
- } catch (error) {
- ElMessage.error('鏌ヨ澶辫触锛�' + error.message)
- } finally {
- tableLoading.value = false
- }
-}
-// // 鐢熸垚鍋囨暟鎹�
-// const generateMockData = () => {
-// // 鐢熸垚缁熻鍗$墖鍋囨暟鎹�
-// const summary = {
-// totalIn: 1000,
-// totalOut: 600,
-// currentStock: 400,
-// turnoverRate: 30
-// }
-
-// // 鐢熸垚鍥捐〃鍋囨暟鎹�
-// const trendDates = ['2025-09-15', '2025-09-16', '2025-09-17', '2025-09-18', '2025-09-19']
-// const trendValues = [300, 350, 400, 380, 420]
-// const comparisonDates = ['2025-09-15', '2025-09-16', '2025-09-17']
-// const inValues = [100, 150, 200]
-// const outValues = [80, 120, 100]
-
-// const chartData = {
-// trendDates,
-// trendValues,
-// comparisonDates,
-// inValues,
-// outValues
-// }
-
-// reportData.value = {
-// summary,
-// chartData,
-// tableData: []
-// }
-// }
-// 楠岃瘉鎼滅储琛ㄥ崟
-const validateSearchForm = () => {
- if (searchForm.reportType === 'daily') {
- if (!searchForm.singleDate) {
- ElMessage.warning('璇烽�夋嫨鏃ユ湡')
- return false
- }
- } else if (searchForm.reportType === 'work' || searchForm.reportType === 'inout') {
- if (!searchForm.dateRange || searchForm.dateRange.length !== 2) {
- ElMessage.warning('璇烽�夋嫨鏃ユ湡鑼冨洿')
- return false
- }
- } else if (searchForm.reportType === 'monthly') {
- if (!searchForm.monthRange || searchForm.monthRange.length !== 2) {
- ElMessage.warning('璇烽�夋嫨鏈堜唤鑼冨洿')
- return false
- }
- }
- return true
-}
-
-// 鑾峰彇鏌ヨ鍙傛暟
-const getQueryParams = () => {
- const params = {
- reportType: searchForm.reportType,
- reportDate: "",
- startMonth: "",
- endMonth: "",
- startDate: "",
- endDate: ""
- }
-
- if (searchForm.reportType === 'daily') {
- params.reportDate = searchForm.singleDate
- } else if (searchForm.reportType === 'monthly') {
- params.startMonth = searchForm.monthRange[0]
- params.endMonth = searchForm.monthRange[1]
- } else {
- params.startDate = searchForm.dateRange[0]
- params.endDate = searchForm.dateRange[1]
- }
-
- return params
-}
-
-// 閲嶇疆鎼滅储
-const handleReset = () => {
- searchForm.reportType = 'daily'
- searchForm.singleDate = ''
- searchForm.dateRange = []
- searchForm.monthRange = []
- reportData.value = {
- summary: null,
- chartData: null,
- tableData: []
- }
-}
-
-// 瀵煎嚭鎶ヨ〃
-const handleExport = async () => {
- if (!validateSearchForm()) {
- return
- }
-
- try {
- const params = getQueryParams()
- // const response = await exportStockReport(params)
- proxy.download("/stockin/exportCopy", params, '搴撳瓨鎶ヨ〃.xlsx')
- // 鍒涘缓涓嬭浇閾炬帴
- // const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
- // const url = window.URL.createObjectURL(blob)
- // const link = document.createElement('a')
- // link.href = url
- // link.download = `${getTableTitle()}_${new Date().getTime()}.xlsx`
- // document.body.appendChild(link)
- // link.click()
- // document.body.removeChild(link)
- // window.URL.revokeObjectURL(url)
-
- // ElMessage.success('瀵煎嚭鎴愬姛')
- } catch (error) {
- ElMessage.error('瀵煎嚭澶辫触锛�' + error.message)
- }
-}
-
-// 鍒濆鍖栧浘琛�
-const initCharts = () => {
- if (!reportData.value.chartData) return
-
- initTrendChart()
- initComparisonChart()
-}
-
-// 鍒濆鍖栬秼鍔垮浘
-const initTrendChart = () => {
- if (!trendChart.value) return
-
- const chart = echarts.init(trendChart.value)
- const option = {
- title: {
- text: '搴撳瓨鍙樺寲瓒嬪娍',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['搴撳瓨閲�'],
- top: 30
- },
- xAxis: {
- type: 'category',
- data: reportData.value.chartData.trendDates || []
- },
- yAxis: {
- type: 'value'
- },
- series: [{
- name: '搴撳瓨閲�',
- type: 'line',
- data: reportData.value.chartData.trendValues || [],
- smooth: true,
- itemStyle: {
- color: '#409EFF'
- }
- }]
- }
- chart.setOption(option)
-}
-
-// 鍒濆鍖栧姣斿浘
-const initComparisonChart = () => {
- if (!comparisonChart.value) return
-
- const chart = echarts.init(comparisonChart.value)
- const option = {
- title: {
- text: '杩涘嚭搴撳姣�',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['鍏ュ簱', '鍑哄簱'],
- top: 30
- },
- xAxis: {
- type: 'category',
- data: reportData.value.chartData.comparisonDates || []
- },
- yAxis: {
- type: 'value'
- },
- series: [
- {
- name: '鍏ュ簱',
- type: 'bar',
- data: reportData.value.chartData.inValues || [],
- itemStyle: {
- color: '#67C23A'
- }
- },
- {
- name: '鍑哄簱',
- type: 'bar',
- data: reportData.value.chartData.outValues || [],
- itemStyle: {
- color: '#F56C6C'
- }
- }
- ]
- }
- chart.setOption(option)
-}
-
-// 缁勪欢鎸傝浇鏃惰缃粯璁ゆ椂闂�
-onMounted(() => {
- const today = new Date()
- searchForm.singleDate = today.toISOString().split('T')[0]
-
- const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000)
- searchForm.dateRange = [
- yesterday.toISOString().split('T')[0],
- today.toISOString().split('T')[0]
- ]
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.search_form {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding: 20px;
- background: #fff;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.search_left {
- display: flex;
- align-items: center;
-}
-
-.search_title {
- font-weight: 500;
- color: #333;
- margin-right: 8px;
-}
-
-.ml10 {
- margin-left: 10px;
-}
-
-.stats_cards {
- margin-bottom: 20px;
-}
-
-.stats_card {
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-}
-
-.stats_content {
- display: flex;
- align-items: center;
- padding: 10px 0;
-}
-
-.stats_icon {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 15px;
- font-size: 24px;
- color: #fff;
-}
-
-.stats_icon.in {
- background: linear-gradient(135deg, #67C23A, #85CE61);
-}
-
-.stats_icon.out {
- background: linear-gradient(135deg, #F56C6C, #F78989);
-}
-
-.stats_icon.stock {
- background: linear-gradient(135deg, #409EFF, #66B1FF);
-}
-
-.stats_icon.turnover {
- background: linear-gradient(135deg, #E6A23C, #EEBE77);
-}
-
-.stats_info {
- flex: 1;
-}
-
-.stats_value {
- font-size: 24px;
- font-weight: bold;
- color: #333;
- line-height: 1;
- margin-bottom: 5px;
-}
-
-.stats_label {
- font-size: 14px;
- color: #666;
-}
-
-.chart_section {
- margin-bottom: 20px;
-}
-
-.table_section {
- margin-bottom: 20px;
-}
-
-:deep(.el-card__header) {
- background: #f8f9fa;
- border-bottom: 1px solid #e9ecef;
- font-weight: 500;
-}
-
-:deep(.el-table .el-table__header-wrapper th) {
- background-color: #F0F1F5 !important;
- color: #333333;
- font-weight: 600;
-}
-
-:deep(.el-table .el-table__body-wrapper td) {
- padding: 8px 0;
-}
-</style>
diff --git a/src/views/inventoryManagement/stockWarning/index.vue b/src/views/inventoryManagement/stockWarning/index.vue
deleted file mode 100644
index d0d5834..0000000
--- a/src/views/inventoryManagement/stockWarning/index.vue
+++ /dev/null
@@ -1,943 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎼滅储琛ㄥ崟 -->
- <div class="search_form">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="鍌ㄦ皵缃愬悕绉帮細">
- <el-input v-model="searchForm.tankName" placeholder="璇疯緭鍏ュ偍姘旂綈鍚嶇О" clearable style="width: 200px" />
- </el-form-item>
- <el-form-item label="鍌ㄦ皵缃愮被鍨嬶細">
- <el-select v-model="searchForm.tankType" placeholder="璇烽�夋嫨鍌ㄦ皵缃愮被鍨�" clearable style="width: 200px">
- <el-option label="娑插寲姘斿偍缃�" value="娑插寲姘斿偍缃�" />
- <el-option label="鍘嬬缉姘斿偍缃�" value="鍘嬬缉姘斿偍缃�" />
- <el-option label="澶╃劧姘斿偍缃�" value="澶╃劧姘斿偍缃�" />
- <el-option label="姘ф皵鍌ㄧ綈" value="姘ф皵鍌ㄧ綈" />
- </el-select>
- </el-form-item>
- <el-form-item label="棰勮绫诲瀷锛�">
- <el-select v-model="searchForm.warningType" placeholder="璇烽�夋嫨棰勮绫诲瀷" clearable style="width: 200px">
- <el-option label="姘斾綋涓嶈冻" value="姘斾綋涓嶈冻" />
- <el-option label="鍘嬪姏寮傚父" value="鍘嬪姏寮傚父" />
- <el-option label="娓╁害寮傚父" value="娓╁害寮傚父" />
- <el-option label="娉勬紡棰勮" value="娉勬紡棰勮" />
- </el-select>
- </el-form-item>
- <el-form-item label="棰勮绾у埆锛�">
- <el-select v-model="searchForm.warningLevel" placeholder="璇烽�夋嫨棰勮绾у埆" clearable style="width: 200px">
- <el-option label="绱ф��" value="绱ф��" />
- <el-option label="閲嶈" value="閲嶈" />
- <el-option label="涓�鑸�" value="涓�鑸�" />
- </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="table-operations">
- <el-button type="primary" @click="handleAdd">鏂板棰勮瑙勫垯</el-button>
- <!-- <el-button type="success" @click="handleBatchProcess">鎵归噺澶勭悊@</el-button> -->
- <el-button @click="handleExport">瀵煎嚭</el-button>
- </div>
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- style="width: 100%"
- height="calc(100vh - 280px)"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-
- <!-- 鍩虹淇℃伅瀛楁 -->
- <el-table-column label="鍌ㄦ皵缃愮紪鐮�" prop="tankCode" width="120" show-overflow-tooltip />
- <el-table-column label="鍌ㄦ皵缃愬悕绉�" prop="tankName" width="200" show-overflow-tooltip />
- <el-table-column label="鍌ㄦ皵缃愮被鍨�" prop="tankType" width="120" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="150" show-overflow-tooltip />
- <el-table-column label="瀹圭Н(m鲁)" prop="volume" width="100" show-overflow-tooltip />
-
- <!-- 搴撳瓨鐩稿叧瀛楁 -->
- <el-table-column label="褰撳墠姘斾綋閲�" prop="currentGasLevel" width="120" show-overflow-tooltip>
- <template #default="scope">
- <span :class="getGasLevelClass(scope.row)">{{ scope.row.currentGasLevel }}%</span>
- </template>
- </el-table-column>
- <el-table-column label="瀹夊叏姘斾綋閲�" prop="safetyGasLevel" width="120" show-overflow-tooltip />
- <el-table-column label="鏈�浣庢皵浣撻噺" prop="minGasLevel" width="120" show-overflow-tooltip />
- <el-table-column label="鏈�楂樻皵浣撻噺" prop="maxGasLevel" width="120" show-overflow-tooltip />
- <el-table-column label="褰撳墠鍘嬪姏(MPa)" prop="currentPressure" width="140" show-overflow-tooltip />
-
- <!-- 棰勮瑙勫垯瀛楁 -->
- <el-table-column label="棰勮绫诲瀷" prop="warningType" width="100" show-overflow-tooltip>
- <template #default="scope">
- <el-tag :type="getWarningTypeTag(scope.row.warningType)">
- {{ scope.row.warningType }}
- </el-tag>
- </template>
- </el-table-column>
- <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="warningThreshold" width="100" show-overflow-tooltip />
- <el-table-column label="鏄惁鍚敤" prop="isEnabled" width="100" show-overflow-tooltip>
- <template #default="scope">
- <el-switch v-model="scope.row.isEnabled" @change="handleEnableChange(scope.row)" />
- </template>
- </el-table-column>
-
- <!-- 鏃堕棿鐩稿叧瀛楁 -->
- <el-table-column label="棰勮鏃堕棿" prop="warningTime" width="150" show-overflow-tooltip />
- <el-table-column label="棰勮鎸佺画澶╂暟" prop="warningDuration" width="120" show-overflow-tooltip />
- <el-table-column label="鏈�鍚庢洿鏂版椂闂�" prop="lastUpdateTime" width="150" show-overflow-tooltip />
- <el-table-column label="棰勮鍏呰鏃堕棿" prop="expectedRefillTime" 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-column fixed="right" label="鎿嶄綔" width="200" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="handleEdit(scope.row)">缂栬緫</el-button>
-<!-- <el-button link type="success" size="small" @click="handleProcess(scope.row)">澶勭悊@</el-button>-->
- <el-button link type="danger" size="small" @click="handleDelete(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"
- />
- </div>
-
- <!-- 鏂板/缂栬緫棰勮瑙勫垯寮圭獥 -->
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板棰勮瑙勫垯' : '缂栬緫棰勮瑙勫垯'"
- width="50%"
- @close="closeDialog"
- >
- <el-form :model="form" :rules="rules" ref="formRef" label-width="140px">
- <el-row :gutter="20">
- <!-- 鍩虹淇℃伅 -->
- <el-col :span="12">
- <el-form-item label="鍌ㄦ皵缃愮紪鐮侊細" prop="tankCode">
- <el-input v-model="form.tankCode" placeholder="璇疯緭鍏ュ偍姘旂綈缂栫爜" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍌ㄦ皵缃愬悕绉帮細" prop="tankName">
- <el-input v-model="form.tankName" placeholder="璇疯緭鍏ュ偍姘旂綈鍚嶇О" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍌ㄦ皵缃愮被鍨嬶細" prop="tankType">
- <el-select v-model="form.tankType" placeholder="璇烽�夋嫨鍌ㄦ皵缃愮被鍨�" style="width: 100%">
- <el-option label="娑插寲姘斿偍缃�" value="娑插寲姘斿偍缃�" />
- <el-option label="鍘嬬缉姘斿偍缃�" value="鍘嬬缉姘斿偍缃�" />
- <el-option label="澶╃劧姘斿偍缃�" value="澶╃劧姘斿偍缃�" />
- <el-option label="姘ф皵鍌ㄧ綈" value="姘ф皵鍌ㄧ綈" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="specificationModel">
- <el-input v-model="form.specificationModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瀹圭Н(m鲁)锛�" prop="volume">
- <el-input-number v-model="form.volume" :min="0" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰撳墠姘斾綋閲�(%)锛�" prop="currentGasLevel">
- <el-input-number v-model="form.currentGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <!-- 搴撳瓨鐩稿叧 -->
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瀹夊叏姘斾綋閲�(%)锛�" prop="safetyGasLevel">
- <el-input-number v-model="form.safetyGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈�浣庢皵浣撻噺(%)锛�" prop="minGasLevel">
- <el-input-number v-model="form.minGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鏈�楂樻皵浣撻噺(%)锛�" prop="maxGasLevel">
- <el-input-number v-model="form.maxGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰撳墠鍘嬪姏(MPa)锛�" prop="currentPressure">
- <el-input-number v-model="form.currentPressure" :min="0" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <!-- 棰勮瑙勫垯 -->
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="棰勮绫诲瀷锛�" prop="warningType">
- <el-select v-model="form.warningType" placeholder="璇烽�夋嫨棰勮绫诲瀷" style="width: 100%">
- <el-option label="姘斾綋涓嶈冻" value="姘斾綋涓嶈冻" />
- <el-option label="鍘嬪姏寮傚父" value="鍘嬪姏寮傚父" />
- <el-option label="娓╁害寮傚父" value="娓╁害寮傚父" />
- <el-option label="娉勬紡棰勮" value="娉勬紡棰勮" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰勮绾у埆锛�" prop="warningLevel">
- <el-select v-model="form.warningLevel" placeholder="璇烽�夋嫨棰勮绾у埆" style="width: 100%">
- <el-option label="绱ф��" value="绱ф��" />
- <el-option label="閲嶈" value="閲嶈" />
- <el-option label="涓�鑸�" value="涓�鑸�" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="棰勮闃堝�硷細" prop="warningThreshold">
- <el-input-number v-model="form.warningThreshold" :min="0" :precision="2" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏄惁鍚敤锛�" prop="isEnabled">
- <el-switch v-model="form.isEnabled" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <!-- 鏃堕棿鐩稿叧 -->
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="棰勮鏃堕棿锛�" prop="warningTime">
- <el-date-picker
- v-model="form.warningTime"
- type="datetime"
- placeholder="璇烽�夋嫨棰勮鏃堕棿"
- style="width: 100%"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰勮鍏呰鏃堕棿锛�" prop="expectedRefillTime">
- <el-date-picker
- v-model="form.expectedRefillTime"
- type="datetime"
- placeholder="璇烽�夋嫨棰勮鍏呰鏃堕棿"
- style="width: 100%"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="棰勮缂烘皵鏃堕棿锛�" prop="expectedShortageTime">
- <el-date-picker
- v-model="form.expectedShortageTime"
- type="datetime"
- placeholder="璇烽�夋嫨棰勮缂烘皵鏃堕棿"
- style="width: 100%"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="棰勮瑙勫垯鎻忚堪锛�" prop="warningRule">
- <el-input
- v-model="form.warningRule"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ラ璀﹁鍒欐弿杩�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDialog">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 缂烘皵棰勮寮规 -->
- <el-dialog
- v-model="shortageWarningVisible"
- title="鈿狅笍 缂烘皵棰勮"
- width="400px"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :show-close="false"
- >
- <div class="shortage-warning-content">
- <div class="warning-icon">
- <el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon>
- </div>
- <div class="warning-message">
- <h3>{{ currentWarningTank.tankName }}</h3>
- <p>鍌ㄦ皵缃愬凡缂烘皵锛岃鍙婃椂澶勭悊锛�</p>
- <p class="warning-details">
- 鍌ㄦ皵缃愮紪鐮侊細{{ currentWarningTank.tankCode }}<br>
- 鍌ㄦ皵缃愮被鍨嬶細{{ currentWarningTank.tankType }}<br>
- 褰撳墠姘斾綋閲忥細{{ currentWarningTank.currentGasLevel }}%
- </p>
- </div>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="handleShortageWarning">绔嬪嵆澶勭悊</el-button>
- <el-button @click="closeShortageWarning">绋嶅悗澶勭悊</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 缂烘皵棰勮寮规 -->
- <el-dialog
- v-model="shortageWarningVisible"
- title="鈿狅笍 缂烘皵棰勮"
- width="400px"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :show-close="false"
- >
- <div class="shortage-warning-content">
- <div class="warning-icon">
- <el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon>
- </div>
- <div class="warning-message">
- <h3>{{ currentWarningTank.tankName }}</h3>
- <p>鍌ㄦ皵缃愬凡缂烘皵锛岃鍙婃椂澶勭悊锛�</p>
- <p class="warning-details">
- 鍌ㄦ皵缃愮紪鐮侊細{{ currentWarningTank.tankCode }}<br>
- 鍌ㄦ皵缃愮被鍨嬶細{{ currentWarningTank.tankType }}<br>
- 褰撳墠姘斾綋閲忥細{{ currentWarningTank.currentGasLevel }}%
- </p>
- </div>
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="handleShortageWarning">绔嬪嵆澶勭悊</el-button>
- <el-button @click="closeShortageWarning">绋嶅悗澶勭悊</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { WarningFilled } from '@element-plus/icons-vue'
-import pagination from '@/components/PIMTable/Pagination.vue'
-// 娉ㄩ噴鎺堿PI瀵煎叆锛屼娇鐢ㄥ亣鏁版嵁
-import {
- getStockWarningPage,
- addStockWarning,
- updateStockWarning,
- deleteStockWarning,
- batchProcessStockWarning,
- exportStockWarning,
- toggleStockWarningStatus
-} from '@/api/inventoryManagement/stockWarning.js'
-
-const { proxy } = getCurrentInstance()
-
-// 鍝嶅簲寮忔暟鎹�
-const tableData = ref([])
-const tableLoading = ref(false)
-const selectedRows = ref([])
-const dialogFormVisible = ref(false)
-const operationType = ref('add')
-const total = ref(0)
-
-// 缂烘皵棰勮鐩稿叧
-const shortageWarningVisible = ref(false)
-const currentWarningTank = ref({})
-const countdownTimer = ref(null)
-
-// 鍒嗛〉鍙傛暟
-const page = reactive({
- current: 1,
- size: 10,
- total: 0
-})
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- tankName: '',
- tankType: '',
- warningType: '',
- warningLevel: ''
-})
-
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
- id: null,
- tankCode: '',
- tankName: '',
- tankType: '',
- specificationModel: '',
- volume: 0,
- currentGasLevel: 0,
- safetyGasLevel: 0,
- minGasLevel: 0,
- maxGasLevel: 0,
- currentPressure: 0,
- warningType: '',
- warningLevel: '',
- warningThreshold: 0,
- isEnabled: true,
- warningTime: '',
- warningDuration: 0,
- lastUpdateTime: '',
- expectedRefillTime: '',
- expectedShortageTime: '',
- warningRule: ''
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- tankCode: [{ required: true, message: '璇疯緭鍏ュ偍姘旂綈缂栫爜', trigger: 'blur' }],
- tankName: [{ required: true, message: '璇疯緭鍏ュ偍姘旂綈鍚嶇О', trigger: 'blur' }],
- tankType: [{ required: true, message: '璇烽�夋嫨鍌ㄦ皵缃愮被鍨�', trigger: 'change' }],
- warningType: [{ required: true, message: '璇烽�夋嫨棰勮绫诲瀷', trigger: 'change' }],
- warningLevel: [{ required: true, message: '璇烽�夋嫨棰勮绾у埆', trigger: 'change' }],
- warningThreshold: [{ required: true, message: '璇疯緭鍏ラ璀﹂槇鍊�', trigger: 'blur' }]
-}
-
-// 鑾峰彇鍊掕鏃朵俊鎭�
-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'
- }
-}
-
-// 妫�鏌ョ己姘旈璀�
-const checkShortageWarnings = () => {
- tableData.value.forEach(tank => {
- if (tank.expectedShortageTime) {
- const countdown = getCountdown(tank.expectedShortageTime)
- if (countdown.isExpired && !tank.warningShown) {
- // 鏍囪宸叉樉绀洪璀︼紝閬垮厤閲嶅寮规
- tank.warningShown = true
- showShortageWarning(tank)
- }
- }
- })
-}
-
-// 鏄剧ず缂烘皵棰勮寮规
-const showShortageWarning = (tank) => {
- currentWarningTank.value = tank
- shortageWarningVisible.value = true
-
- // 鎾斁鎻愮ず闊筹紙鍙�夛級
- // const audio = new Audio('/path/to/warning-sound.mp3')
- // audio.play()
-}
-
-// 澶勭悊缂烘皵棰勮
-const handleShortageWarning = () => {
- ElMessage.success(`姝e湪澶勭悊鍌ㄦ皵缃� ${currentWarningTank.value.tankName} 鐨勭己姘旈棶棰榒)
- shortageWarningVisible.value = false
- // 杩欓噷鍙互璋冪敤澶勭悊API
-}
-// 澶勭悊缂烘皵棰勮
-const closeShortageWarning = () => {
- // ElMessage.success(`姝e湪澶勭悊鍌ㄦ皵缃� ${currentWarningTank.value.tankName} 鐨勭己姘旈棶棰榒)
- shortageWarningVisible.value = false
- // 杩欓噷鍙互璋冪敤澶勭悊API
-}
-
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = async () => {
- tableLoading.value = true
- getStockWarningPage(page, searchForm)
- .then(res => {
-
- tableData.value = res.data.records
- page.value.total = res.data.total;
- tableLoading.value = false;
- // 妫�鏌ョ己姘旈璀�
- checkShortageWarnings()
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-
-// 鎼滅储
-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 handleSelectionChange = (selection) => {
- selectedRows.value = selection
-}
-
-// 鏂板
-const handleAdd = () => {
- operationType.value = 'add'
- // resetForm()
- dialogFormVisible.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
- operationType.value = 'edit'
- Object.assign(form, row)
- dialogFormVisible.value = true
-}
-
-// 澶勭悊棰勮
-const handleProcess = async (row) => {
- try {
- // 妯℃嫙API璋冪敤寤惰繜
- await new Promise(resolve => setTimeout(resolve, 300))
- ElMessage.success(`姝e湪澶勭悊棰勮锛�${row.tankName}`)
- // getList()
- } catch (error) {
- ElMessage.error('澶勭悊棰勮澶辫触')
- }
-}
-
-// 鍒犻櫎
-const handleDelete = async (row) => {
- try {
- await ElMessageBox.confirm(`纭畾瑕佸垹闄ら璀﹁鍒欙細${row.tankName}鍚楋紵`, '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
- let ids = [];
- ids.push(row.id);
- deleteStockWarning(ids).then(res => {
- if(res.code == 200){
- ElMessage.success("鍒犻櫎鎴愬姛");
- ids.value = [];
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // // 妯℃嫙API璋冪敤寤惰繜
- // await new Promise(resolve => setTimeout(resolve, 300))
- // ElMessage.success('鍒犻櫎鎴愬姛')
- // getList()
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('鍒犻櫎澶辫触')
- }
- }
-}
-
-// 鎵归噺澶勭悊
-const handleBatchProcess = async () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning('璇烽�夋嫨瑕佸鐞嗙殑棰勮')
- return
- }
-
- try {
- // 妯℃嫙API璋冪敤寤惰繜
- await new Promise(resolve => setTimeout(resolve, 500))
- ElMessage.success(`鎵归噺澶勭悊浜� ${selectedRows.value.length} 鏉¢璀)
- getList()
- } catch (error) {
- ElMessage.error('鎵归噺澶勭悊澶辫触')
- }
-}
-
-// 瀵煎嚭
-const handleExport = async () => {
- // if (selectedRows.value.length === 0) {
- // exportStockWarning().then(res => {
- // // // 鍒涘缓涓嬭浇閾炬帴
- // // const blob = new Blob([res.data], { type: 'text/csv;charset=utf-8;' })
- // // const url = window.URL.createObjectURL(blob)
- // // const link = document.createElement('a')
- // // link.href = url
- // // link.download = `鍌ㄦ皵缃愰璀︽暟鎹甠${new Date().getTime()}.csv`
- // // link.click()
- // // window.URL.revokeObjectURL(url)
- // }).catch(err => {
- // ElMessage.error(err.msg);
- // })
- // }else{
- // let ids = [];
- // selectedRows.value.forEach(item => {
- // ids.push(item.id);
- // })
- // exportStockWarning(ids).then(res => {
- // // // 鍒涘缓涓嬭浇閾炬帴
- // // const blob = new Blob([res.data], { type: 'text/csv;charset=utf-8;' })
- // // const url = window.URL.createObjectURL(blob)
- // // const link = document.createElement('a')
- // // link.href = url
- // // link.download = `鍌ㄦ皵缃愰璀︽暟鎹甠${new Date().getTime()}.csv`
- // // link.click()
- // // window.URL.revokeObjectURL(url)
- // }).catch(err => {
- // ElMessage.error(err.msg);
- // })
- // }
-
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/gasTankWarning/export", {ids: selectedRows.value.map(item => item.id)}, "鍌ㄦ皵缃愰璀�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-}
-
-
-
-// // 鍚敤鐘舵�佸彉鍖�
-const handleEnableChange = async (row) => {
-
- try {
- updateStockWarning(row).then(res => {
- if(res.code == 200){
- ElMessage.success(`${row.tankName} 鐨勫惎鐢ㄧ姸鎬佸凡鏇存柊`);
- getList();
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- } catch (error) {
- ElMessage.error('鐘舵�佹洿鏂板け璐�')
- // 鎭㈠鍘熺姸鎬�
- row.isEnabled = !row.isEnabled
- }
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- await proxy.$refs.formRef.validate()
-
- // 妯℃嫙API璋冪敤寤惰繜
- // await new Promise(resolve => setTimeout(resolve, 500))
-
- if (operationType.value === 'add') {
- addStockWarning(form).then(res => {
- if(res.code == 200){
- ElMessage.success("娣诲姞鎴愬姛");
- dialogFormVisible.value = false
- getList()
- resetForm()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
-
- // ElMessage.success('鏂板鎴愬姛')
- } else {
- updateStockWarning(form).then(res => {
- if(res.code == 200){
- ElMessage.success("鏇存柊鎴愬姛");
- dialogFormVisible.value = false
- getList()
- resetForm()
- }
- }).catch(err => {
- ElMessage.error(err.msg);
- })
- // ElMessage.success('缂栬緫鎴愬姛')
- }
-
- // closeDialog()
- // getList()
- } catch (error) {
- if (!error.errors) {
- ElMessage.error(operationType.value === 'add' ? '鏂板澶辫触' : '缂栬緫澶辫触')
- }
- }
-}
-
-// 鍏抽棴寮圭獥
-const closeDialog = () => {
- dialogFormVisible.value = false
- // resetForm()
-}
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
- Object.keys(form).forEach(key => {
- if (key === 'isEnabled') {
- form[key] = true
- } else if (typeof form[key] === 'number') {
- form[key] = 0
- } else {
- form[key] = ''
- }
- })
- proxy.$refs.formRef?.resetFields()
-}
-
-// 鑾峰彇姘斾綋閲忔牱寮忕被
-const getGasLevelClass = (row) => {
- if (row.currentGasLevel < row.minGasLevel) {
- return 'text-danger'
- } else if (row.currentGasLevel > row.maxGasLevel) {
- return 'text-warning'
- }
- return 'text-success'
-}
-
-// 鑾峰彇棰勮绫诲瀷鏍囩鏍峰紡
-const getWarningTypeTag = (type) => {
- const typeMap = {
- '姘斾綋涓嶈冻': 'danger',
- '鍘嬪姏寮傚父': 'warning',
- '娓╁害寮傚父': 'info',
- '娉勬紡棰勮': 'danger'
- }
- return typeMap[type] || 'info'
-}
-
-// 鑾峰彇棰勮绾у埆鏍囩鏍峰紡
-const getWarningLevelTag = (level) => {
- const levelMap = {
- '绱ф��': 'danger',
- '閲嶈': 'warning',
- '涓�鑸�': 'info'
- }
- return levelMap[level] || 'info'
-}
-
-// 鍚姩鍊掕鏃跺畾鏃跺櫒
-const startCountdownTimer = () => {
- countdownTimer.value = setInterval(() => {
- checkShortageWarnings()
- }, 60000) // 姣忓垎閽熸鏌ヤ竴娆�
-}
-
-// 鍋滄鍊掕鏃跺畾鏃跺櫒
-const stopCountdownTimer = () => {
- if (countdownTimer.value) {
- clearInterval(countdownTimer.value)
- countdownTimer.value = null
- }
-}
-
-// 椤甸潰鍔犺浇
-onMounted(() => {
- getList()
- startCountdownTimer()
-})
-
-// 椤甸潰鍗歌浇
-onUnmounted(() => {
- stopCountdownTimer()
-})
-</script>
-
-<style scoped lang="scss">
-.app-container {
- padding: 20px;
-
- .table-operations {
- text-align: right;
- margin-bottom: 20px;
-
- .el-button {
- margin-right: 10px;
- }
- }
-
- .table_list {
- background: #fff;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- }
-
- .text-danger {
- color: #f56c6c;
- font-weight: bold;
- }
-
- .text-warning {
- color: #e6a23c;
- font-weight: bold;
- }
-
- .text-success {
- color: #67c23a;
- font-weight: bold;
- }
-
- .dialog-footer {
- text-align: right;
- }
-
- // 鍊掕鏃舵牱寮�
- .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; }
- }
-
- // 缂烘皵棰勮寮规鏍峰紡
- .shortage-warning-content {
- text-align: center;
- padding: 20px 0;
-
- .warning-icon {
- margin-bottom: 20px;
- }
-
- .warning-message {
- h3 {
- color: #f56c6c;
- margin-bottom: 10px;
- }
-
- p {
- margin-bottom: 10px;
- color: #606266;
- }
-
- .warning-details {
- background: #f5f7fa;
- padding: 15px;
- border-radius: 4px;
- text-align: left;
- font-size: 14px;
- line-height: 1.6;
- }
- }
- }
-}
-</style>
diff --git a/src/views/lavorissue/ledger/Form.vue b/src/views/lavorissue/ledger/Form.vue
deleted file mode 100644
index 7031957..0000000
--- a/src/views/lavorissue/ledger/Form.vue
+++ /dev/null
@@ -1,154 +0,0 @@
-<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
- <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptId">
- <el-select
- v-model="form.deptId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option :label="item.deptName" :value="item.deptId" v-for="(item,index) in productOptions" :key="deptId" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍛樺伐鍚嶇О" prop="staffId">
- <el-select
- v-model="form.staffId"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.staffName" :value="item.id" v-for="(item,index) in personList" :key="id" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍔充繚绫诲瀷" prop="dictType">
- <el-select
- v-model="form.dictType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in sys_lavor_issue_type" :key="value" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍔充繚闃插叿" prop="dictId">
- <el-select
- v-model="form.dictId"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in sys_lavor_issue" :key="value" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍙戞斁鏁伴噺" prop="num">
- <el-input-number :step="1" :min="0" style="width: 100%"
- v-model="form.num"
- placeholder="璇疯緭鍏�"
- />
- </el-form-item>
- <el-form-item label="杩涘巶鏃ユ湡" prop="factoryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.factoryDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- clearable
- />
- </el-form-item>
- <el-form-item label="鍙戞斁鏃ユ湡" prop="issueDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.issueDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- clearable
- />
- </el-form-item>
-
- </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import {ref,onMounted} from "vue";
-import useUserStore from "@/store/modules/user";
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
-import {deepCopySameProperties} from '@/utils/util'
-const userStore = useUserStore();
-import {
- getDept
-} from "@/api/collaborativeApproval/approvalProcess.js";
-const { proxy } = getCurrentInstance();
-
-
-defineOptions({
- name: "鏂板鏀跺叆",
-});
-const { sys_lavor_issue } = proxy.useDict("sys_lavor_issue")
-const { sys_lavor_issue_type } = proxy.useDict("sys_lavor_issue_type")
-const formRef = ref(null);
-const productOptions = ref([]);
-const personList = ref([]);
-const formRules = {
- deptId: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- dictType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- staffId: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
- dictId: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- num: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- adoptedDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- factoryDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
- issueDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
-}
-
-const { form, resetForm } = useFormData({
- deptId: undefined, //
- dictType: undefined,
- staffId: undefined, //
- dictId: undefined, //
- num: undefined, //
- adoptedDate: undefined,
- factoryDate: undefined,
- issueDate: undefined,
-});
-const getPersonList = () => {
- getStaffOnJob().then(res => {
- personList.value = res.data
- })
-};
-const loadForm = (data) => {
- deepCopySameProperties(data, form)
-};
-
-const getProductOptions = () => {
- getDept().then((res) => {
- productOptions.value = res.data;
- });
-}
-// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
-const clearValidate = () => {
- formRef.value?.clearValidate();
-};
-
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetFormAndValidate = () => {
- resetForm();
- clearValidate();
- form.deptId = userStore.currentDeptId
- getProductOptions();
- getPersonList();
-};
-onMounted(() => {
- form.deptId = userStore.currentDeptId
- getProductOptions();
- getPersonList();
-})
-defineExpose({
- form,
- resetForm,
- clearValidate,
- loadForm,
- resetFormAndValidate,
- formRef,
-});
-</script>
diff --git a/src/views/lavorissue/ledger/Modal.vue b/src/views/lavorissue/ledger/Modal.vue
deleted file mode 100644
index 5d63236..0000000
--- a/src/views/lavorissue/ledger/Modal.vue
+++ /dev/null
@@ -1,70 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
- <Form ref="formRef"></Form>
- <template #footer>
- <el-button type="primary" @click="sendForm" :loading="loading">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import { add, update } from "@/api/lavorissce/ledger";
-import Form from "./Form.vue";
-import { ElMessage } from "element-plus";
-const { proxy } = getCurrentInstance()
-
-defineOptions({
- name: "鏀跺叆鏂板缂栬緫",
-});
-
-const emits = defineEmits(["success"]);
-
-const formRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "鍔充繚鍙拌处" });
-
-const sendForm = () => {
- proxy.$refs.formRef.$refs.formRef.validate(async valid => {
- if (valid) {
- const {code} = id.value
- ? await update({id: id.value, ...formRef.value.form})
- : await add(formRef.value.form);
- if (code == 200) {
- emits("success");
- ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
- close();
- } else {
- loading.value = false;
- }
- }
- })
-};
-
-const close = () => {
- formRef.value.resetFormAndValidate();
- closeModal();
-};
-
-const loadForm = async (row) => {
- openModal(row.id);
- await nextTick();
- formRef.value.loadForm(row);
-
-};
-
-defineExpose({
- openModal,
- loadForm,
-});
-</script>
diff --git a/src/views/lavorissue/ledger/filesDia.vue b/src/views/lavorissue/ledger/filesDia.vue
deleted file mode 100644
index f752496..0000000
--- a/src/views/lavorissue/ledger/filesDia.vue
+++ /dev/null
@@ -1,202 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="涓婁紶闄勪欢"
- width="50%"
- @close="closeDia"
- >
- <div style="margin-bottom: 10px;text-align: right">
- <el-upload
- v-model:file-list="fileList"
- class="upload-demo"
- :action="uploadUrl"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: inline;margin-right: 10px"
- >
- <el-button type="primary">涓婁紶闄勪欢</el-button>
- </el-upload>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- height="500"
- >
- </PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
- fileAdd,
- fileDel,
- fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
- {
- label: "鏂囦欢鍚嶇О",
- prop: "name",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "涓嬭浇",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- {
- name: "棰勮",
- type: "text",
- clickFun: (row) => {
- lookFile(row);
- },
- }
- ],
- },
-]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
- Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
- accountType.value = type;
- dialogFormVisible.value = true;
- currentId.value = row.id;
- getList()
-}
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
- tableData.value = res.data.records;
- total.value = res.data.total;
- })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
- // 濡傛灉涓婁紶鎴愬姛
- if (res.code == 200) {
- const fileRow = {}
- fileRow.name = res.data.originalName
- fileRow.url = res.data.tempPath
- uploadFile(fileRow)
- } else {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
-}
-function uploadFile(file) {
- file.accountId = currentId.value;
- file.accountType = accountType.value;
- fileAdd(file).then(res => {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- getList()
- })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-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(() => {
- fileDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/lavorissue/ledger/index.vue b/src/views/lavorissue/ledger/index.vue
deleted file mode 100644
index 19d0e59..0000000
--- a/src/views/lavorissue/ledger/index.vue
+++ /dev/null
@@ -1,300 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="鍙戞斁瀛e害:" prop="season">
- <el-select
- style="width: 200px;"
- @change="handleQuery"
- v-model="filters.season"
- placeholder="璇烽�夋嫨"
- :clearable="false"
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in jidu" :key="value" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍛樺伐鍚嶇О:">
- <el-input
- v-model="filters.staffName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- <el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0"
- @click="deleteRow(multipleList.map((item) => item.id))"
- >
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #operation="{ row }">
- <el-button type="primary" text @click="edit(row)" icon="editPen">
- 缂栬緫
- </el-button>
- <el-button type="primary" :disabled="row.adoptedDate ? true : false" text @click="adopted(row)">
- 棰嗙敤
- </el-button>
- </template>
- </PIMTable>
- </div>
- <Modal ref="modalRef" @success="getTableData"></Modal>
- <files-dia ref="filesDia"></files-dia>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage,deleteLedger,update } from "@/api/lavorissce/ledger";
-import { onMounted, getCurrentInstance } from "vue";
-import Modal from "./Modal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
-import dayjs from "dayjs";
-import FilesDia from "./filesDia.vue";
-import { getCurrentMonth } from "@/utils/util"
-
-// 琛ㄦ牸澶氶�夋閫変腑椤�
-const multipleList = ref([]);
-const { proxy } = getCurrentInstance();
-const modalRef = ref();
-const { payment_methods } = proxy.useDict("payment_methods");
-const { income_types } = proxy.useDict("income_types");
-const filesDia = ref()
-
-const {
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- listPage,
- {
- staffName: '',
- season: getCurrentMonth(),
- },
- [
- {
- label: "鍔充繚鍗曞彿",
- align: "center",
- prop: "orderNo",
- },
- {
- label: "鍛樺伐鍚嶇О",
- align: "center",
- prop: "staffName",
- },
- {
- label: "鍛樺伐缂栧彿",
- align: "center",
- prop: "staffNo"
- },
-
- {
- label: "鍔充繚绫诲瀷",
- align: "center",
- prop: "dictTypeName",
-
- },
- {
- label: "鍔充繚闃插叿",
- align: "center",
- prop: "dictName",
-
- },
- {
- label: "鍙戞斁鏁伴噺",
- align: "center",
- prop: "num",
-
- },
- {
- label: "杩涘巶鏃ユ湡",
- align: "center",
- prop: "factoryDate",
-
- },
- {
- label: "鍙戞斁鏃ユ湡",
- align: "center",
- prop: "issueDate",
-
- },
- {
- label: "棰嗙敤鏃ユ湡",
- align: "center",
- prop: "adoptedDate",
-
- },
- {
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "200px",
- },
- ]
-);
-
-const jidu = ref([
- {
- value: '1',
- label: '绗竴瀛e害'
- },
- {
- value: '2',
- label: '绗簩瀛e害'
- },
- {
- value: '3',
- label: '绗笁瀛e害'
- },
- {
- value: '4',
- label: '绗洓瀛e害'
- }
-])
-
-// 澶氶�夊悗鍋氫粈涔�
-const handleSelectionChange = (selectionList) => {
- multipleList.value = selectionList;
-};
-
-const adopted = (row) => {
- ElMessageBox.confirm("鏄惁纭棰嗙敤?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const params = {
- id: row.id,
- adoptedDate: dayjs().format("YYYY-MM-DD")
- }
- const { code } = await update(params);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "棰嗙敤鎴愬姛",
- });
- getTableData();
- }
- })
-}
-
-const add = () => {
- modalRef.value.openModal();
-};
-const edit = (row) => {
- modalRef.value.loadForm(row);
-};
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- getTableData();
-};
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-const deleteRow = (id) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(async () => {
- const { code } = await deleteLedger(id);
- if (code == 200) {
- ElMessage({
- type: "success",
- message: "鍒犻櫎鎴愬姛",
- });
- getTableData();
- }
- });
-};
-
-const changeDaterange = (value) => {
- if (value) {
- filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- filters.entryDateStart = undefined;
- filters.entryDateEnd = undefined;
- }
- getTableData();
-};
-
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/lavorIssue/export`, {}, "鍔充繚鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
- nextTick(() => {
- filesDia.value?.openDialog( row,'鏀跺叆')
- })
-};
-
-onMounted(() => {
- filters.entryDate = [
- dayjs().format("YYYY-MM-DD"),
- dayjs().add(1, "day").format("YYYY-MM-DD"),
- ]
- filters.entryDateStart = dayjs().format("YYYY-MM-DD")
- filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
- 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/lavorissue/statistics/index.vue b/src/views/lavorissue/statistics/index.vue
deleted file mode 100644
index 2c34f67..0000000
--- a/src/views/lavorissue/statistics/index.vue
+++ /dev/null
@@ -1,285 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鍙戞斁瀛e害锛�</span>
- <el-select
- style="width: 200px;"
- @change="handleQuery"
- v-model="searchForm.season"
- placeholder="璇烽�夋嫨"
- @clear="clearSeason"
- clearable
- :disabled="searchForm.issueDate ? true : false"
-
- >
- <el-option :label="item.label" :value="item.value" v-for="(item,index) in jidu" :key="item.value" />
- </el-select>
- <span class="search_title ml10">鍙戞斁鏈堜唤锛�</span>
- <el-date-picker
- style="width: 200px;"
- :disabled="searchForm.season ? true : false"
- v-model="searchForm.issueDate"
- @change="handleQuery"
- @clear="clearIssueDaten"
- type="month"
- value-format="YYYY-MM-DD"
- format="YYYY-MM"
- placeholder="璇烽�夋嫨鏈堜唤"
- clearable
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- <el-button type="primary" @click="resetHandleQuery" style="margin-left: 10px"
- >閲嶇疆</el-button
- >
- </div>
- <div>
- <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
- </div>
- </div>
- <div class="table_list">
- <div class="actions">
- <div class="head" @click="handleQuery(1)">宸查鍙栧姵淇濇暟閲�:{{statisticsObj.ylqNum}}</div>
- <div class="head" @click="handleQuery(2)">鏈鍙栧姵淇濇暟閲�: {{ statisticsObj.wlqNum }}</div>
- <div class="head" @click="handleQuery(3)">瓒呮椂宸查鍙栧姵淇濇暟閲�: {{statisticsObj.csylqNum}}</div>
- <div class="head" @click="handleQuery(4)">瓒呮椂鏈鍙栧姵淇濇暟閲�: {{statisticsObj.cswlqNum}}</div>
- </div>
- <el-table
- ref="tableRef"
- v-loading="tableLoading"
- :data="tableData"
- border
- height="calc(100vh - 21em)"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- style="width: 100%"
- @selection-change="handleSelectionChange"
- >
- <!-- 閫夋嫨鍒� -->
- <el-table-column
- align="center"
- type="selection"
- width="55"
- fixed="left"
- />
-
- <!-- 搴忓彿鍒� -->
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- fixed="left"
- />
-
- <!-- 鍥哄畾鍒楋細濮撳悕 -->
- <el-table-column
- label="濮撳悕"
- prop="staffName"
- width="100"
- show-overflow-tooltip
- align="center"
- fixed="left"
- />
-
- <!-- 鍥哄畾鍒楋細宸ュ彿 -->
- <el-table-column
- label="宸ュ彿"
- prop="staffNo"
- width="100"
- show-overflow-tooltip
- align="center"
- fixed="left"
- />
-
- <!-- 鍔ㄦ�佸垪锛氭牴鎹瓧鍏告覆鏌� -->
- <el-table-column
- v-for="(dictItem, index) in sys_lavor_issue"
- :key="dictItem.value"
- :label="dictItem.label"
- :prop="dictItem.value"
- show-overflow-tooltip
- >
- </el-table-column>
- </el-table>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, reactive, toRefs, nextTick, getCurrentInstance } from 'vue'
-import dayjs from "dayjs";
-import {statisticsList, statistics} from "@/api/lavorissce/ledger.js";
-import {ElMessageBox, ElMessage} from "element-plus";
-const { proxy } = getCurrentInstance();
-import { getCurrentMonth } from "@/utils/util"
-
-const page = ref({
- current: 1,
- size: 100,
-})
-const total = ref(0)
-// 鍝嶅簲寮忔暟鎹�
-const tableRef = ref(null)
-const tableData = ref([])
-const tableLoading = ref(false)
-const { sys_lavor_issue } = proxy.useDict("sys_lavor_issue")
-const data = reactive({
- searchForm: {
- season: getCurrentMonth(),
- issueDate: "",
- status: 0
- },
-});
-const { searchForm } = toRefs(data);
-
-const modalRef = ref();
-const filesDia = ref();
-const multipleList = ref([]);
-const jidu = ref([
- {
- value: '1',
- label: '绗竴瀛e害'
- },
- {
- value: '2',
- label: '绗簩瀛e害'
- },
- {
- value: '3',
- label: '绗笁瀛e害'
- },
- {
- value: '4',
- label: '绗洓瀛e害'
- }
-])
-const clearSeason = () => {
- console.log("req")
- searchForm.value.season = ""
- searchForm.value.issueDate = dayjs().format("YYYY-MM-DD");
-}
-
-const clearIssueDaten = () => {
- searchForm.value.issueDate = ""
- searchForm.value.season = getCurrentMonth()
-}
-const statisticsObj = ref({
- ylqNum: 0, // 宸查鍙栨暟閲�
- wlqNum: 0, // 鏈鍙栨暟閲�
- csylqNum: 0, // 瓒呮椂宸查鍙栨暟閲�
- cswlqNum: 0 // 瓒呮椂鏈鍙栨暟閲�
-})
-const resetHandleQuery = () => {
- searchForm.value.issueDate = "";
- searchForm.value.season = getCurrentMonth();
- handleQuery(0)
-};
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = (status) => {
- switch (status){
- case 1:
- searchForm.value.status = 1
- break;
- case 2:
- searchForm.value.status = 2
- break;
- case 3:
- searchForm.value.status = 3
- break;
- case 4:
- searchForm.value.status = 4
- break;
- default:
- searchForm.value.status = 0
- }
- getList();
- getStatistics();
-};
-
-const getStatistics = () => {
- statistics(searchForm.value).then(res => {
- statisticsObj.value.cswlqNum = res.data.cswlqNum
- statisticsObj.value.csylqNum = res.data.csylqNum
- statisticsObj.value.ylqNum = res.data.ylqNum
- statisticsObj.value.wlqNum = res.data.wlqNum
- })
-}
-// 鑾峰彇瀛楀吀鏁版嵁
-const getList = async () => {
- tableLoading.value = true;
- const params = { ...searchForm.value};
- statisticsList(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data;
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/lavorIssue/exportCopy`, {season: searchForm.value.season,issueDate: searchForm.value.issueDate}, "鍔充繚鍙拌处.xlsx");
- })
- .catch(() => {
- ElMessage.info("宸插彇娑�");
- });
-};
-
-// 浜嬩欢澶勭悊鍑芥暟
-const handleSelectionChange = (selection) => {
- multipleList.value = selection;
-}
-
-// 缁勪欢鎸傝浇鏃跺姞杞藉瓧鍏告暟鎹�
-onMounted(() => {
- handleQuery()
-})
-</script>
-
-<style scoped>
-.dynamic-table-container {
- width: 100%;
-}
-
-.pagination-container {
- margin-top: 20px;
- display: flex;
- justify-content: flex-end;
-}
-
-:deep(.el-table .el-table__header-wrapper th) {
- background-color: #F0F1F5 !important;
- color: #333333;
- font-weight: 600;
-}
-
-:deep(.el-table .el-table__body-wrapper td) {
- padding: 8px 0;
-}
-
-:deep(.el-select) {
- width: 100%;
-}
-
-:deep(.el-input) {
- width: 100%;
-}
-.actions {
- display: flex;
- justify-content: space-around;
- align-items: center;
- margin-bottom: 30px;
-}
-.head{
- cursor: pointer;
- font-size: 18px;
- font-weight: 600;
-}
-</style>
diff --git a/src/views/monitorManagement/areaControl/index.vue b/src/views/monitorManagement/areaControl/index.vue
deleted file mode 100644
index 1dd5a36..0000000
--- a/src/views/monitorManagement/areaControl/index.vue
+++ /dev/null
@@ -1,264 +0,0 @@
-<template>
- <div class="app-container">
- <el-row :gutter="16">
- <el-col :span="16">
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>鍖哄煙绠$悊锛堝弻閲嶉棬绂侊級</span>
- <div class="header-actions">
- <el-select v-model="selectedPlant" placeholder="閫夋嫨鍘傚尯" size="small" style="width: 160px" @change="filterZones">
- <el-option v-for="plant in plants" :key="plant.id" :label="plant.name" :value="plant.id" />
- </el-select>
- <el-switch v-model="onlyCritical" inline-prompt :active-text="'浠呭叧閿尯'" :inactive-text="'鍏ㄩ儴'" @change="filterZones" />
- </div>
- </div>
- </template>
- <el-table :data="filteredZones" border style="width: 100%" height="320">
- <el-table-column type="index" width="60" label="搴忓彿" align="center" />
- <el-table-column prop="name" label="鍖哄煙鍚嶇О" min-width="160" show-overflow-tooltip />
- <el-table-column prop="zoneType" label="绫诲瀷" width="120" />
- <el-table-column label="鍙岄棬鑱斿姩" width="120" align="center">
- <template #default="{ row }">
- <el-tag v-if="row.dualAccess" type="success">宸插惎鐢�</el-tag>
- <el-tag v-else type="info">鏈惎鐢�</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍦ㄧ嚎浜烘暟" width="100" align="center">
- <template #default="{ row }">{{ row.currentPersons }}</template>
- </el-table-column>
- <el-table-column label="瀹夊叏鐘舵��" width="140" align="center">
- <template #default="{ row }">
- <el-tag :type="row.status === '姝e父' ? 'success' : row.status === '棰勮' ? 'warning' : 'danger'">
- {{ row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
- <template #default="{ row }">
- <el-button link type="primary" size="small" @click="toggleDual(row)">
- {{ row.dualAccess ? '鍋滅敤鍙岄棬' : '鍚敤鍙岄棬' }}
- </el-button>
- <el-button link type="success" size="small" @click="openAccessSim(row)">妯℃嫙寮�闂�</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>鍩硅鑱斿姩锛堟湭瀹屾垚/杩囨湡绂佹杩涘叆锛�</span>
- <div class="header-actions">
- <el-input v-model="accessSim.personId" placeholder="浜哄憳宸ュ彿" size="small" style="width: 140px" />
- <el-select v-model="accessSim.targetZoneId" placeholder="閫夋嫨鐩爣鍖哄煙" size="small" style="width: 180px">
- <el-option v-for="z in zones" :key="z.id" :label="z.name" :value="z.id" />
- </el-select>
- <el-button type="primary" size="small" @click="simulateAccess">妫�楠屽噯鍏�</el-button>
- </div>
- </div>
- </template>
- <el-descriptions :column="3" border size="small" v-if="accessResult">
- <el-descriptions-item label="宸ュ彿">{{ accessResult.person.id }}锛坽{ accessResult.person.dept }}锛�</el-descriptions-item>
- <el-descriptions-item label="鍩硅鐘舵��">
- <el-tag :type="accessResult.person.training.valid ? 'success' : 'danger'">
- {{ accessResult.person.training.valid ? '鏈夋晥' : '澶辨晥/鏈畬鎴�' }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐩爣鍖哄煙">{{ accessResult.zone.name }}</el-descriptions-item>
- <el-descriptions-item label="鏈�杩戝煿璁�">{{ accessResult.person.training.lastDate }}</el-descriptions-item>
- <el-descriptions-item label="閫傚矖璇佹湁鏁堟湡">{{ accessResult.person.training.expireDate }}</el-descriptions-item>
- <el-descriptions-item label="鍑嗗叆缁撴灉">
- <el-tag :type="accessResult.allowed ? 'success' : 'danger'">{{ accessResult.allowed ? '鍏佽杩涘叆' : '绂佹杩涘叆' }}</el-tag>
- </el-descriptions-item>
- </el-descriptions>
- <el-empty v-else description="璇疯緭鍏ヤ汉鍛樹笌鍖哄煙杩涜妫�楠�" />
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>浣╂埓璁惧婊炵暀鍛婅锛堝嵄闄╁尯瓒呮椂锛�</span>
- <div class="header-actions">
- <el-select v-model="stayThreshold" size="small" style="width: 140px">
- <el-option :value="10" label="闃堝�� 10 鍒嗛挓" />
- <el-option :value="20" label="闃堝�� 20 鍒嗛挓" />
- <el-option :value="30" label="闃堝�� 30 鍒嗛挓" />
- </el-select>
- <el-switch v-model="alarmOn" inline-prompt :active-text="'鍛婅寮�'" :inactive-text="'鍛婅鍏�'" />
- </div>
- </div>
- </template>
- <el-timeline style="max-height: 520px; overflow: auto">
- <el-timeline-item v-for="(item, idx) in alarms" :key="idx" :type="item.level" :timestamp="item.time">
- <div class="alarm-item">
- <div class="title">
- {{ item.personId }} 路 {{ item.zoneName }} 路 婊炵暀 {{ item.stayMins }} 鍒嗛挓
- </div>
- <div class="desc">璁惧锛歿{ item.deviceId }}锛堜俊鍙峰己搴� {{ item.rssi }} dBm锛�</div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </el-card>
- </el-col>
- </el-row>
- </div>
- <el-dialog v-model="doorSimVisible" title="闂ㄧ寮�闂ㄦā鎷�" width="420px">
- <el-form :model="doorSim" label-width="90px">
- <el-form-item label="鍖哄煙">
- <el-input v-model="doorSim.zoneName" disabled />
- </el-form-item>
- <el-form-item label="闂ㄧ1">
- <el-switch v-model="doorSim.door1" />
- </el-form-item>
- <el-form-item label="闂ㄧ2">
- <el-switch v-model="doorSim.door2" />
- </el-form-item>
- <el-alert type="info" show-icon :closable="false" title="鍙岄棬鍧囦负寮�鍚柟鍙�氳" />
- </el-form>
- <template #footer>
- <el-button @click="doorSimVisible = false">鍏抽棴</el-button>
- <el-button type="primary" :disabled="!(doorSim.door1 && doorSim.door2)" @click="confirmPass">閫氳</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted } from "vue";
-
-// 鍘傚尯涓庡尯鍩燂紙鐓ょ偔琛屼笟璇箟銆佸敖閲忚创杩戠湡瀹烇級
-const plants = ref([
- { id: "P01", name: "涓�鍙烽�夌叅鍘�" },
- { id: "P02", name: "浜屽彿娲楃叅鍒嗗巶" },
-]);
-const zones = ref([
- { id: "Z01", plantId: "P01", name: "涓帶瀹�", zoneType: "鎺у埗瀹�", dualAccess: true, currentPersons: 4, status: "姝e父" },
- { id: "Z02", plantId: "P01", name: "鐓ゅ満A鍖�", zoneType: "鍫嗗瓨鍖�", dualAccess: true, currentPersons: 12, status: "棰勮" },
- { id: "Z03", plantId: "P01", name: "鍗遍櫓鍝佸簱", zoneType: "鍗卞寲鍝�", dualAccess: true, currentPersons: 1, status: "姝e父" },
- { id: "Z04", plantId: "P01", name: "楂樺帇閰嶇數瀹�", zoneType: "鐢垫皵闂�", dualAccess: true, currentPersons: 2, status: "姝e父" },
- { id: "Z05", plantId: "P02", name: "鐨甫寤婂寳娈�", zoneType: "杈撻�佸粖閬�", dualAccess: false, currentPersons: 5, status: "姝e父" },
- { id: "Z06", plantId: "P02", name: "绛涘垎杞﹂棿", zoneType: "浣滀笟鍖�", dualAccess: false, currentPersons: 9, status: "棰勮" },
-]);
-
-const selectedPlant = ref(plants.value[0].id);
-const onlyCritical = ref(true);
-const filteredZones = ref([]);
-
-function filterZones() {
- const data = zones.value.filter((z) => z.plantId === selectedPlant.value);
- filteredZones.value = onlyCritical.value ? data.filter((z) => z.dualAccess) : data;
-}
-
-function toggleDual(row) {
- row.dualAccess = !row.dualAccess;
- filterZones();
-}
-
-// 闂ㄧ寮�闂ㄦā鎷�
-const doorSimVisible = ref(false);
-const doorSim = reactive({ zoneId: "", zoneName: "", door1: false, door2: false });
-function openAccessSim(row) {
- doorSim.zoneId = row.id;
- doorSim.zoneName = row.name;
- doorSim.door1 = false;
- doorSim.door2 = false;
- doorSimVisible.value = true;
-}
-function confirmPass() {
- doorSimVisible.value = false;
-}
-
-// 鍩硅鑱斿姩妯℃嫙
-const persons = ref([
- { id: "EMP1001", dept: "鐢熶骇涓�闃�", training: { valid: true, lastDate: "2025-09-12", expireDate: "2026-09-12" } },
- { id: "EMP1018", dept: "鏈虹數鐝�", training: { valid: false, lastDate: "2024-07-03", expireDate: "2025-07-03" } },
- { id: "EMP1022", dept: "瀹夌洃绉�", training: { valid: true, lastDate: "2025-08-01", expireDate: "2026-08-01" } },
-]);
-const accessSim = reactive({ personId: "", targetZoneId: "" });
-const accessResult = ref(null);
-
-function simulateAccess() {
- const person = persons.value.find((p) => p.id === accessSim.personId);
- const zone = zones.value.find((z) => z.id === accessSim.targetZoneId);
- if (!person || !zone) {
- accessResult.value = null;
- return;
- }
- const allowed = person.training.valid && (zone.zoneType !== "鍗卞寲鍝�" || person.dept === "瀹夌洃绉�");
- accessResult.value = { allowed, person, zone };
-}
-
-// 浣╂埓璁惧婊炵暀鍛婅锛堝亣鏁版嵁瀹氭椂鎺ㄩ�侊級
-const stayThreshold = ref(20);
-const alarmOn = ref(true);
-const alarms = ref([
- { time: "09:35", level: "warning", personId: "EMP1001", zoneName: "鐓ゅ満A鍖�", stayMins: 18, deviceId: "TAG-7A12", rssi: -67 },
-]);
-
-let timer = null;
-function pushMockAlarm() {
- if (!alarmOn.value) return;
- const candidates = [
- { personId: "EMP1018", zoneName: "绛涘垎杞﹂棿", base: 12 },
- { personId: "EMP1022", zoneName: "楂樺帇閰嶇數瀹�", base: 9 },
- { personId: "EMP1001", zoneName: "鐓ゅ満A鍖�", base: 16 },
- ];
- const pick = candidates[Math.floor(Math.random() * candidates.length)];
- const stay = pick.base + Math.floor(Math.random() * 10);
- if (stay >= stayThreshold.value) {
- const now = new Date();
- const hh = String(now.getHours()).padStart(2, "0");
- const mm = String(now.getMinutes()).padStart(2, "0");
- alarms.value.unshift({
- time: `${hh}:${mm}`,
- level: stay >= stayThreshold.value + 10 ? "danger" : "warning",
- personId: pick.personId,
- zoneName: pick.zoneName,
- stayMins: stay,
- deviceId: `TAG-${Math.random().toString(16).slice(2, 6).toUpperCase()}`,
- rssi: -60 - Math.floor(Math.random() * 15),
- });
- if (alarms.value.length > 30) alarms.value.pop();
- }
-}
-
-onMounted(() => {
- filterZones();
- timer = setInterval(pushMockAlarm, 4500);
-});
-
-// 绂诲紑鏃舵竻鐞�
-if (import.meta.hot) {
- import.meta.hot.dispose(() => {
- if (timer) clearInterval(timer);
- });
-}
-</script>
-
-<style scoped lang="scss">
-.section-card {
- margin-bottom: 16px;
-}
-.card-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-.header-actions {
- display: flex;
- gap: 8px;
- align-items: center;
-}
-.alarm-item .title {
- font-weight: 600;
- margin-bottom: 4px;
-}
-.alarm-item .desc {
- color: #666;
- font-size: 12px;
-}
-</style>
-
-
diff --git a/src/views/monitorManagement/videoMonitor/index.vue b/src/views/monitorManagement/videoMonitor/index.vue
deleted file mode 100644
index b78c7f5..0000000
--- a/src/views/monitorManagement/videoMonitor/index.vue
+++ /dev/null
@@ -1,990 +0,0 @@
-<template>
- <div class="app-container">
- <el-row :gutter="16">
- <!-- 宸︿晶锛氳棰戠洃鎺у垪琛ㄤ笌鎶撴媿璁板綍 -->
- <el-col :span="16">
- <!-- 瑙嗛鐩戞帶鍒楄〃 -->
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>瑙嗛鐩戞帶鐐逛綅绠$悊</span>
- <div class="header-actions">
- <el-select v-model="selectedArea" placeholder="閫夋嫨鍖哄煙" size="small" style="width: 160px" @change="filterCameras">
- <el-option label="鍏ㄩ儴鍖哄煙" value="all" />
- <el-option v-for="area in areas" :key="area.id" :label="area.name" :value="area.id" />
- </el-select>
- <el-select v-model="cameraStatus" placeholder="璁惧鐘舵��" size="small" style="width: 120px" @change="filterCameras">
- <el-option label="鍏ㄩ儴鐘舵��" value="all" />
- <el-option label="鍦ㄧ嚎" value="online" />
- <el-option label="绂荤嚎" value="offline" />
- </el-select>
- </div>
- </div>
- </template>
- <el-table :data="filteredCameras" border style="width: 100%" max-height="320">
- <el-table-column type="index" width="50" label="搴忓彿" align="center" />
- <el-table-column prop="name" label="鐩戞帶鐐逛綅" min-width="140" show-overflow-tooltip />
- <el-table-column prop="areaName" label="鎵�灞炲尯鍩�" width="120" />
- <el-table-column label="璁惧鐘舵��" width="100" align="center">
- <template #default="{ row }">
- <el-tag :type="row.status === 'online' ? 'success' : 'danger'" size="small">
- {{ row.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="AI璇嗗埆" width="100" align="center">
- <template #default="{ row }">
- <el-tag v-if="row.aiEnabled" type="success" size="small">宸插惎鐢�</el-tag>
- <el-tag v-else type="info" size="small">鏈惎鐢�</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="闂ㄧ鑱斿姩" width="100" align="center">
- <template #default="{ row }">
- <el-tag v-if="row.doorLinked" type="primary" size="small">宸茬粦瀹�</el-tag>
- <el-tag v-else type="info" size="small">鏈粦瀹�</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
- <template #default="{ row }">
- <el-button link type="primary" size="small" @click="viewRealtime(row)">瀹炴椂鐢婚潰</el-button>
- <el-button link type="success" size="small" @click="viewCaptures(row)">鎶撴媿璁板綍</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 闂ㄧ鎶撴媿璁板綍 -->
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>闂ㄧ鎶撴媿璁板綍</span>
- <div class="header-actions">
- <el-date-picker
- v-model="captureDate"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- size="small"
- style="width: 260px"
- @change="loadCaptures"
- />
- <el-select v-model="captureEventType" placeholder="浜嬩欢绫诲瀷" size="small" style="width: 100px" clearable>
- <el-option label="鍏ㄩ儴" value="" />
- <el-option label="杩涘叆" value="entry" />
- <el-option label="绂诲紑" value="exit" />
- </el-select>
- <el-input v-model="captureSearch" placeholder="鎼滅储宸ュ彿/鍖哄煙" size="small" style="width: 140px" clearable>
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- <el-button type="primary" size="small" @click="exportCaptures">
- <el-icon><Download /></el-icon>
- 瀵煎嚭
- </el-button>
- </div>
- </div>
- </template>
-
- <!-- 缁熻淇℃伅 -->
- <div class="capture-stats">
- <el-row :gutter="16">
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-label">浠婃棩鎶撴媿</div>
- <div class="stat-value">{{ captureStats.today }}</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-label">杩涘叆璁板綍</div>
- <div class="stat-value" style="color: #67c23a">{{ captureStats.entry }}</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-label">绂诲紑璁板綍</div>
- <div class="stat-value" style="color: #e6a23c">{{ captureStats.exit }}</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-label">浣庡尮閰嶅害</div>
- <div class="stat-value" style="color: #f56c6c">{{ captureStats.lowMatch }}</div>
- </div>
- </el-col>
- </el-row>
- </div>
-
- <el-table
- :data="paginatedCaptures"
- border
- style="width: 100%"
- max-height="350"
- @selection-change="handleCaptureSelection"
- >
- <el-table-column type="selection" width="45" align="center" />
- <el-table-column type="index" width="50" label="搴忓彿" align="center" :index="indexMethod" />
- <el-table-column prop="time" label="鎶撴媿鏃堕棿" width="155" sortable />
- <el-table-column prop="personId" label="宸ュ彿" width="110" show-overflow-tooltip />
- <el-table-column prop="department" label="閮ㄩ棬" width="100" show-overflow-tooltip />
- <el-table-column prop="areaName" label="鍖哄煙" width="110" show-overflow-tooltip />
- <el-table-column label="闂ㄧ浜嬩欢" width="90" align="center">
- <template #default="{ row }">
- <el-tag :type="row.eventType === 'entry' ? 'success' : 'warning'" size="small">
- {{ row.eventType === 'entry' ? '杩涘叆' : '绂诲紑' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="浜鸿劯鍖归厤" width="95" align="center" sortable :sort-method="(a, b) => a.faceMatch - b.faceMatch">
- <template #default="{ row }">
- <el-tag :type="getFaceMatchType(row.faceMatch)" size="small">
- {{ row.faceMatch }}%
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="cameraName" label="鎽勫儚澶�" width="120" show-overflow-tooltip />
- <el-table-column label="鎿嶄綔" width="150" align="center" fixed="right">
- <template #default="{ row }">
- <el-button link type="primary" size="small" @click="viewSnapshot(row)">
- <el-icon><View /></el-icon>
- 鏌ョ湅
- </el-button>
- <el-button link type="success" size="small" @click="downloadSnapshot(row)">
- <el-icon><Download /></el-icon>
- 涓嬭浇
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <div class="pagination-container">
- <el-pagination
- v-model:current-page="capturePage"
- v-model:page-size="capturePageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="filteredCaptures.length"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
- </el-col>
-
- <!-- 鍙充晶锛氳繚瑙勫憡璀� -->
- <el-col :span="8">
- <el-card shadow="never" class="section-card">
- <template #header>
- <div class="card-header">
- <span>杩濊琛屼负鍛婅</span>
- <div class="header-actions">
- <el-badge :value="unreadAlarmCount" :max="99" type="danger">
- <el-switch v-model="alarmEnabled" inline-prompt active-text="鍛婅寮�" inactive-text="鍛婅鍏�" />
- </el-badge>
- </div>
- </div>
- </template>
- <el-tabs v-model="alarmTab" type="border-card" style="height: 650px">
- <el-tab-pane label="鍏ㄩ儴鍛婅" name="all">
- <div>
- <el-timeline style="max-height: 580px; overflow-y: auto; padding-right: 10px">
- <el-timeline-item
- v-for="(alarm, idx) in displayAlarms"
- :key="idx"
- :type="getAlarmType(alarm.type)"
- :timestamp="alarm.time"
- :hollow="alarm.handled"
- >
- <div class="alarm-item" :class="{ handled: alarm.handled }">
- <div class="alarm-header">
- <el-tag :type="getAlarmTagType(alarm.type)" size="small">{{ alarm.typeText }}</el-tag>
- <span class="alarm-area">{{ alarm.areaName }}</span>
- </div>
- <div class="alarm-content">
- {{ alarm.description }}
- </div>
- <div class="alarm-footer">
- <span class="alarm-camera">鎽勫儚澶�: {{ alarm.cameraName }}</span>
- <el-button
- v-if="!alarm.handled"
- link
- type="primary"
- size="small"
- @click="handleAlarm(alarm)"
- >
- 澶勭悊
- </el-button>
- <span v-else class="handled-text">宸插鐞�</span>
- </div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </el-tab-pane>
- <el-tab-pane label="寮洪棷鍛婅" name="intrusion">
- <div>
- <el-timeline style="max-height: 580px; overflow-y: auto; padding-right: 10px">
- <el-timeline-item
- v-for="(alarm, idx) in intrusionAlarms"
- :key="idx"
- type="danger"
- :timestamp="alarm.time"
- >
- <div class="alarm-item">
- <div class="alarm-header">
- <el-tag type="danger" size="small">寮洪棷鍛婅</el-tag>
- <span class="alarm-area">{{ alarm.areaName }}</span>
- </div>
- <div class="alarm-content">{{ alarm.description }}</div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </el-tab-pane>
- <el-tab-pane label="灏鹃殢鍛婅" name="tailgating">
- <div>
- <el-timeline style="max-height: 580px; overflow-y: auto; padding-right: 10px">
- <el-timeline-item
- v-for="(alarm, idx) in tailgatingAlarms"
- :key="idx"
- type="warning"
- :timestamp="alarm.time"
- >
- <div class="alarm-item">
- <div class="alarm-header">
- <el-tag type="warning" size="small">灏鹃殢鍛婅</el-tag>
- <span class="alarm-area">{{ alarm.areaName }}</span>
- </div>
- <div class="alarm-content">{{ alarm.description }}</div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </el-tab-pane>
- <el-tab-pane label="澶氫汉閫氳" name="multiple">
- <div>
- <el-timeline style="max-height: 580px; overflow-y: auto; padding-right: 10px">
- <el-timeline-item
- v-for="(alarm, idx) in multipleAlarms"
- :key="idx"
- type="warning"
- :timestamp="alarm.time"
- >
- <div class="alarm-item">
- <div class="alarm-header">
- <el-tag type="warning" size="small">澶氫汉閫氳</el-tag>
- <span class="alarm-area">{{ alarm.areaName }}</span>
- </div>
- <div class="alarm-content">{{ alarm.description }}</div>
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </el-tab-pane>
- </el-tabs>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 瀹炴椂鐢婚潰瀵硅瘽妗� -->
- <el-dialog v-model="realtimeVisible" :title="`瀹炴椂鐩戞帶 - ${currentCamera.name}`" width="800px">
- <div class="video-container">
- <div class="video-placeholder">
- <el-icon :size="80" color="#909399"><VideoCameraFilled /></el-icon>
- <div class="video-info">
- <p>鎽勫儚澶�: {{ currentCamera.name }}</p>
- <p>浣嶇疆: {{ currentCamera.areaName }}</p>
- <p>鐘舵��: <el-tag :type="currentCamera.status === 'online' ? 'success' : 'danger'" size="small">{{ currentCamera.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}</el-tag></p>
- <p class="tip">锛堝疄闄呯幆澧冨皢鏄剧ず瀹炴椂瑙嗛娴侊級</p>
- </div>
- </div>
- </div>
- <template #footer>
- <el-button @click="realtimeVisible = false">鍏抽棴</el-button>
- <el-button type="primary" @click="captureSnapshot">鎵嬪姩鎶撴媿</el-button>
- </template>
- </el-dialog>
-
- <!-- 蹇収鏌ョ湅瀵硅瘽妗� -->
- <el-dialog v-model="snapshotVisible" title="鎶撴媿蹇収璇︽儏" width="800px" :close-on-click-modal="false">
- <div class="snapshot-dialog-body">
- <el-row :gutter="20">
- <el-col :span="14">
- <div class="snapshot-preview">
- <div class="snapshot-placeholder">
- <el-icon :size="80" color="#909399"><Picture /></el-icon>
- <p>鎶撴媿鍥剧墖棰勮</p>
- <p class="tip">锛堝疄闄呯幆澧冨皢鏄剧ず楂樻竻鎶撴媿鍥剧墖锛�</p>
- <div class="snapshot-tools">
- <el-button-group>
- <el-button size="small">
- <el-icon><ZoomIn /></el-icon>
- 鏀惧ぇ
- </el-button>
- <el-button size="small">
- <el-icon><ZoomOut /></el-icon>
- 缂╁皬
- </el-button>
- <el-button size="small">
- <el-icon><RefreshRight /></el-icon>
- 鏃嬭浆
- </el-button>
- </el-button-group>
- </div>
- </div>
- </div>
- </el-col>
- <el-col :span="10">
- <el-descriptions :column="1" border size="small">
- <el-descriptions-item label="鎶撴媿鏃堕棿">
- <el-icon><Clock /></el-icon>
- {{ currentSnapshot.time }}
- </el-descriptions-item>
- <el-descriptions-item label="宸ュ彿">
- <el-icon><User /></el-icon>
- {{ currentSnapshot.personId }}
- </el-descriptions-item>
- <el-descriptions-item label="閮ㄩ棬">
- {{ currentSnapshot.department }}
- </el-descriptions-item>
- <el-descriptions-item label="鎵�灞炲尯鍩�">
- <el-icon><Location /></el-icon>
- {{ currentSnapshot.areaName }}
- </el-descriptions-item>
- <el-descriptions-item label="鎽勫儚澶�">
- <el-icon><VideoCameraFilled /></el-icon>
- {{ currentSnapshot.cameraName }}
- </el-descriptions-item>
- <el-descriptions-item label="浜嬩欢绫诲瀷">
- <el-tag :type="currentSnapshot.eventType === 'entry' ? 'success' : 'warning'" size="small">
- {{ currentSnapshot.eventType === 'entry' ? '杩涘叆' : '绂诲紑' }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="浜鸿劯鍖归厤搴�">
- <el-progress
- :percentage="currentSnapshot.faceMatch"
- :color="currentSnapshot.faceMatch >= 90 ? '#67c23a' : '#e6a23c'"
- :stroke-width="12"
- >
- <span style="font-size: 12px">{{ currentSnapshot.faceMatch }}%</span>
- </el-progress>
- </el-descriptions-item>
- <el-descriptions-item label="浣撴俯妫�娴�">
- <span :style="{ color: currentSnapshot.temperature > 37.3 ? '#f56c6c' : '#67c23a' }">
- {{ currentSnapshot.temperature }}掳C
- </span>
- <el-tag v-if="currentSnapshot.temperature > 37.3" type="danger" size="small" style="margin-left: 8px">
- 寮傚父
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鍙g僵浣╂埓">
- <el-tag :type="currentSnapshot.maskWearing ? 'success' : 'warning'" size="small">
- {{ currentSnapshot.maskWearing ? '宸蹭僵鎴�' : '鏈僵鎴�' }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="瀹夊叏甯�">
- <el-tag :type="currentSnapshot.helmetWearing ? 'success' : 'danger'" size="small">
- {{ currentSnapshot.helmetWearing ? '宸蹭僵鎴�' : '鏈僵鎴�' }}
- </el-tag>
- </el-descriptions-item>
- </el-descriptions>
- </el-col>
- </el-row>
-
- <div class="snapshot-notes">
- <el-divider content-position="left">澶囨敞淇℃伅</el-divider>
- <el-input
- v-model="currentSnapshot.notes"
- type="textarea"
- :rows="3"
- placeholder="娣诲姞澶囨敞淇℃伅..."
- />
- </div>
-
- </div>
-
- <template #footer>
- <div class="dialog-footer-custom">
- <div>
- <el-button size="small" @click="printSnapshot">
- <el-icon><Printer /></el-icon>
- 鎵撳嵃
- </el-button>
- </div>
- <div>
- <el-button @click="snapshotVisible = false">鍏抽棴</el-button>
- <el-button type="success" @click="downloadSnapshot(currentSnapshot)">
- <el-icon><Download /></el-icon>
- 涓嬭浇鍥剧墖
- </el-button>
- <el-button type="primary" @click="saveNotes">淇濆瓨澶囨敞</el-button>
- </div>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
-import {
- VideoCameraFilled, Picture, Search, Download, View,
- Clock, User, Location, ZoomIn, ZoomOut, RefreshRight, Printer
-} from "@element-plus/icons-vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-
-// 鍖哄煙鏁版嵁
-const areas = ref([
- { id: "A01", name: "鐓ゅ満鍏ュ彛" },
- { id: "A02", name: "娲楃叅杞﹂棿" },
- { id: "A03", name: "鍗遍櫓鍝佸簱" },
- { id: "A04", name: "涓帶瀹�" },
- { id: "A05", name: "閰嶇數瀹�" },
-]);
-
-// 鎽勫儚澶存暟鎹�
-const cameras = ref([
- { id: "C001", name: "鐓ゅ満鍏ュ彛涓滈棬", areaId: "A01", areaName: "鐓ゅ満鍏ュ彛", status: "online", aiEnabled: true, doorLinked: true },
- { id: "C002", name: "鐓ゅ満鍏ュ彛瑗块棬", areaId: "A01", areaName: "鐓ゅ満鍏ュ彛", status: "online", aiEnabled: true, doorLinked: true },
- { id: "C003", name: "娲楃叅杞﹂棿涓婚�氶亾", areaId: "A02", areaName: "娲楃叅杞﹂棿", status: "online", aiEnabled: true, doorLinked: true },
- { id: "C004", name: "娲楃叅杞﹂棿涓滀晶", areaId: "A02", areaName: "娲楃叅杞﹂棿", status: "online", aiEnabled: false, doorLinked: false },
- { id: "C005", name: "鍗遍櫓鍝佸簱澶ч棬", areaId: "A03", areaName: "鍗遍櫓鍝佸簱", status: "online", aiEnabled: true, doorLinked: true },
- { id: "C006", name: "鍗遍櫓鍝佸簱鍐呴儴", areaId: "A03", areaName: "鍗遍櫓鍝佸簱", status: "offline", aiEnabled: true, doorLinked: false },
- { id: "C007", name: "涓帶瀹ゅ叆鍙�", areaId: "A04", areaName: "涓帶瀹�", status: "online", aiEnabled: true, doorLinked: true },
- { id: "C008", name: "閰嶇數瀹ら棬绂�", areaId: "A05", areaName: "閰嶇數瀹�", status: "online", aiEnabled: true, doorLinked: true },
-]);
-
-const selectedArea = ref("all");
-const cameraStatus = ref("all");
-const filteredCameras = ref([]);
-
-function filterCameras() {
- let result = cameras.value;
- if (selectedArea.value !== "all") {
- result = result.filter(c => c.areaId === selectedArea.value);
- }
- if (cameraStatus.value !== "all") {
- result = result.filter(c => c.status === cameraStatus.value);
- }
- filteredCameras.value = result;
-}
-
-// 闂ㄧ鎶撴媿璁板綍
-const captureDate = ref([new Date(), new Date()]);
-const captureSearch = ref("");
-const captureEventType = ref("");
-const capturePage = ref(1);
-const capturePageSize = ref(10);
-const selectedCaptures = ref([]);
-
-// 鐢熸垚鏇村妯℃嫙鏁版嵁
-const generateCaptureData = () => {
- const departments = ["鐢熶骇涓�闃�", "鏈虹數鐝�", "瀹夌洃绉�", "璋冨害瀹�", "鍖栭獙瀹�", "杩愯緭闃�", "缁翠慨鐝�", "浠撳偍绉�"];
- const areaList = ["鐓ゅ満鍏ュ彛", "娲楃叅杞﹂棿", "鍗遍櫓鍝佸簱", "涓帶瀹�", "閰嶇數瀹�"];
- const cameraList = [
- "鐓ゅ満鍏ュ彛涓滈棬", "鐓ゅ満鍏ュ彛瑗块棬", "娲楃叅杞﹂棿涓婚�氶亾", "娲楃叅杞﹂棿涓滀晶",
- "鍗遍櫓鍝佸簱澶ч棬", "鍗遍櫓鍝佸簱鍐呴儴", "涓帶瀹ゅ叆鍙�", "閰嶇數瀹ら棬绂�"
- ];
-
- const data = [];
- const now = new Date();
-
- for (let i = 0; i < 86; i++) {
- const randomMinutes = Math.floor(Math.random() * 1440); // 24灏忔椂鍐�
- const captureTime = new Date(now.getTime() - randomMinutes * 60 * 1000);
- const hh = String(captureTime.getHours()).padStart(2, "0");
- const mm = String(captureTime.getMinutes()).padStart(2, "0");
- const ss = String(captureTime.getSeconds()).padStart(2, "0");
-
- const area = areaList[Math.floor(Math.random() * areaList.length)];
- const eventType = Math.random() > 0.5 ? "entry" : "exit";
- const faceMatch = Math.floor(Math.random() * 15) + 85; // 85-100
- const temperature = (36.0 + Math.random() * 1.5).toFixed(1);
-
- data.push({
- id: i + 1,
- time: `2025-10-28 ${hh}:${mm}:${ss}`,
- personId: `EMP${String(1001 + i).padStart(4, '0')}`,
- department: departments[Math.floor(Math.random() * departments.length)],
- areaName: area,
- cameraName: cameraList[Math.floor(Math.random() * cameraList.length)],
- eventType: eventType,
- faceMatch: faceMatch,
- temperature: parseFloat(temperature),
- maskWearing: Math.random() > 0.1,
- helmetWearing: Math.random() > 0.15,
- notes: ""
- });
- }
-
- return data.sort((a, b) => b.time.localeCompare(a.time));
-};
-
-const captures = ref(generateCaptureData());
-
-// 缁熻淇℃伅
-const captureStats = computed(() => {
- const today = captures.value.length;
- const entry = captures.value.filter(c => c.eventType === 'entry').length;
- const exit = captures.value.filter(c => c.eventType === 'exit').length;
- const lowMatch = captures.value.filter(c => c.faceMatch < 90).length;
-
- return { today, entry, exit, lowMatch };
-});
-
-// 杩囨护鎶撴媿璁板綍
-const filteredCaptures = computed(() => {
- let result = captures.value;
-
- // 鎸夊叧閿瘝鎼滅储
- if (captureSearch.value) {
- const keyword = captureSearch.value.toLowerCase();
- result = result.filter(c =>
- c.personId.toLowerCase().includes(keyword) ||
- c.areaName.toLowerCase().includes(keyword)
- );
- }
-
- // 鎸変簨浠剁被鍨嬭繃婊�
- if (captureEventType.value) {
- result = result.filter(c => c.eventType === captureEventType.value);
- }
-
- return result;
-});
-
-// 鍒嗛〉鏁版嵁
-const paginatedCaptures = computed(() => {
- const start = (capturePage.value - 1) * capturePageSize.value;
- const end = start + capturePageSize.value;
- return filteredCaptures.value.slice(start, end);
-});
-
-// 鍒嗛〉绱㈠紩鏂规硶
-const indexMethod = (index) => {
- return (capturePage.value - 1) * capturePageSize.value + index + 1;
-};
-
-function loadCaptures() {
- ElMessage.success("宸插姞杞介�夊畾鏃ユ湡鑼冨洿鐨勬姄鎷嶈褰�");
-}
-
-function handleSizeChange(val) {
- capturePageSize.value = val;
- capturePage.value = 1;
-}
-
-function handleCurrentChange(val) {
- capturePage.value = val;
-}
-
-function handleCaptureSelection(selection) {
- selectedCaptures.value = selection;
-}
-
-function getFaceMatchType(faceMatch) {
- if (faceMatch >= 95) return 'success';
- if (faceMatch >= 90) return 'info';
- if (faceMatch >= 85) return 'warning';
- return 'danger';
-}
-
-// 瀵煎嚭鎶撴媿璁板綍
-function exportCaptures() {
- if (filteredCaptures.value.length === 0) {
- ElMessage.warning("娌℃湁鍙鍑虹殑璁板綍");
- return;
- }
- ElMessage.success(`姝e湪瀵煎嚭 ${filteredCaptures.value.length} 鏉℃姄鎷嶈褰�...`);
- // 瀹為檯鐜涓繖閲屼細璋冪敤瀵煎嚭鎺ュ彛
-}
-
-// 涓嬭浇蹇収
-function downloadSnapshot(capture) {
- ElMessage.success(`姝e湪涓嬭浇 ${capture.personId} 鐨勬姄鎷嶅浘鐗�...`);
- // 瀹為檯鐜涓繖閲屼細涓嬭浇鍥剧墖鏂囦欢
-}
-
-// 鎵撳嵃蹇収
-function printSnapshot() {
- ElMessage.info("姝e湪鍑嗗鎵撳嵃...");
- // 瀹為檯鐜涓繖閲屼細璋冪敤鎵撳嵃鍔熻兘
-}
-
-// 淇濆瓨澶囨敞
-function saveNotes() {
- ElMessage.success("澶囨敞淇℃伅宸蹭繚瀛�");
- snapshotVisible.value = false;
-}
-
-// 鍛婅鏁版嵁
-const alarmEnabled = ref(true);
-const alarmTab = ref("all");
-const alarms = ref([
- {
- id: 1,
- time: "09:25:15",
- type: "intrusion",
- typeText: "寮洪棷鍛婅",
- areaName: "鍗遍櫓鍝佸簱",
- cameraName: "鍗遍櫓鍝佸簱澶ч棬",
- description: "妫�娴嬪埌鏈巿鏉冧汉鍛樺己琛岄棷鍏ワ紝鏈埛鍗$洿鎺ュ紑闂�",
- handled: false
- },
- {
- id: 2,
- time: "09:18:42",
- type: "tailgating",
- typeText: "灏鹃殢鍛婅",
- areaName: "涓帶瀹�",
- cameraName: "涓帶瀹ゅ叆鍙�",
- description: "妫�娴嬪埌灏鹃殢琛屼负锛屼竴浜哄埛鍗″悗涓や汉杩涘叆",
- handled: false
- },
- {
- id: 3,
- time: "09:10:28",
- type: "multiple",
- typeText: "澶氫汉閫氳",
- areaName: "鐓ゅ満鍏ュ彛",
- cameraName: "鐓ゅ満鍏ュ彛涓滈棬",
- description: "妫�娴嬪埌3浜哄悓鏃堕�氳繃鍗曚汉闂ㄧ閫氶亾",
- handled: true
- },
-]);
-
-const unreadAlarmCount = computed(() => alarms.value.filter(a => !a.handled).length);
-
-const displayAlarms = computed(() => {
- if (alarmTab.value === "all") return alarms.value;
- return alarms.value.filter(a => a.type === alarmTab.value);
-});
-
-const intrusionAlarms = computed(() => alarms.value.filter(a => a.type === "intrusion"));
-const tailgatingAlarms = computed(() => alarms.value.filter(a => a.type === "tailgating"));
-const multipleAlarms = computed(() => alarms.value.filter(a => a.type === "multiple"));
-
-function getAlarmType(type) {
- const typeMap = { intrusion: "danger", tailgating: "warning", multiple: "warning" };
- return typeMap[type] || "info";
-}
-
-function getAlarmTagType(type) {
- const typeMap = { intrusion: "danger", tailgating: "warning", multiple: "warning" };
- return typeMap[type] || "info";
-}
-
-function handleAlarm(alarm) {
- alarm.handled = true;
- ElMessage.success("鍛婅宸叉爣璁颁负宸插鐞�");
-}
-
-// 瀹炴椂鐢婚潰
-const realtimeVisible = ref(false);
-const currentCamera = ref({});
-
-function viewRealtime(camera) {
- currentCamera.value = camera;
- realtimeVisible.value = true;
-}
-
-function captureSnapshot() {
- ElMessage.success("鎶撴媿鎴愬姛锛屽凡淇濆瓨鑷虫姄鎷嶈褰�");
-}
-
-// 鏌ョ湅鎶撴媿璁板綍璇︽儏
-const snapshotVisible = ref(false);
-const currentSnapshot = ref({});
-
-function viewSnapshot(capture) {
- currentSnapshot.value = capture;
- snapshotVisible.value = true;
-}
-
-function viewCaptures(camera) {
- ElMessage.info(`鏌ョ湅 ${camera.name} 鐨勫巻鍙叉姄鎷嶈褰昤);
-}
-
-// 妯℃嫙鍛婅鎺ㄩ��
-let alarmTimer = null;
-const alarmTemplates = [
- { type: "intrusion", typeText: "寮洪棷鍛婅", areas: ["鍗遍櫓鍝佸簱", "閰嶇數瀹�", "涓帶瀹�"] },
- { type: "tailgating", typeText: "灏鹃殢鍛婅", areas: ["涓帶瀹�", "閰嶇數瀹�", "鍗遍櫓鍝佸簱"] },
- { type: "multiple", typeText: "澶氫汉閫氳", areas: ["鐓ゅ満鍏ュ彛", "娲楃叅杞﹂棿"] },
-];
-
-function pushMockAlarm() {
- if (!alarmEnabled.value) return;
-
- const template = alarmTemplates[Math.floor(Math.random() * alarmTemplates.length)];
- const area = template.areas[Math.floor(Math.random() * template.areas.length)];
- const camera = cameras.value.find(c => c.areaName === area);
-
- const now = new Date();
- const hh = String(now.getHours()).padStart(2, "0");
- const mm = String(now.getMinutes()).padStart(2, "0");
- const ss = String(now.getSeconds()).padStart(2, "0");
-
- let description = "";
- if (template.type === "intrusion") {
- description = "妫�娴嬪埌鏈巿鏉冧汉鍛樺己琛岄棷鍏ワ紝鏈埛鍗$洿鎺ュ紑闂�";
- } else if (template.type === "tailgating") {
- description = "妫�娴嬪埌灏鹃殢琛屼负锛屼竴浜哄埛鍗″悗涓や汉杩涘叆";
- } else if (template.type === "multiple") {
- const count = Math.floor(Math.random() * 3) + 2;
- description = `妫�娴嬪埌${count}浜哄悓鏃堕�氳繃鍗曚汉闂ㄧ閫氶亾`;
- }
-
- alarms.value.unshift({
- id: Date.now(),
- time: `${hh}:${mm}:${ss}`,
- type: template.type,
- typeText: template.typeText,
- areaName: area,
- cameraName: camera ? camera.name : area + "鐩戞帶",
- description: description,
- handled: false
- });
-
- // 闄愬埗鍛婅鍒楄〃闀垮害
- if (alarms.value.length > 50) {
- alarms.value = alarms.value.slice(0, 50);
- }
-}
-
-onMounted(() => {
- filterCameras();
- // 姣忛殧8绉掓ā鎷熶竴娆″憡璀�
- alarmTimer = setInterval(pushMockAlarm, 8000);
-});
-
-onBeforeUnmount(() => {
- if (alarmTimer) {
- clearInterval(alarmTimer);
- }
-});
-</script>
-
-<style scoped lang="scss">
-.section-card {
- margin-bottom: 16px;
-}
-
-.card-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-.header-actions {
- display: flex;
- gap: 8px;
- align-items: center;
-}
-
-.alarm-item {
- padding: 8px;
- background: #f5f7fa;
- border-radius: 4px;
-
- &.handled {
- opacity: 0.6;
- }
-}
-
-.alarm-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 6px;
-}
-
-.alarm-area {
- font-weight: 600;
- color: #303133;
-}
-
-.alarm-content {
- color: #606266;
- font-size: 14px;
- margin-bottom: 6px;
- line-height: 1.5;
-}
-
-.alarm-footer {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 12px;
- color: #909399;
-}
-
-.alarm-camera {
- flex: 1;
-}
-
-.handled-text {
- color: #67c23a;
- font-size: 12px;
-}
-
-.video-container {
- width: 100%;
- height: 450px;
- background: #000;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.video-placeholder {
- text-align: center;
- color: #909399;
-}
-
-.video-info {
- margin-top: 20px;
-
- p {
- margin: 8px 0;
- font-size: 14px;
- }
-
- .tip {
- color: #c0c4cc;
- font-size: 12px;
- margin-top: 16px;
- }
-}
-
-.snapshot-placeholder {
- margin-top: 20px;
- height: 300px;
- background: #f5f7fa;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border-radius: 4px;
- color: #909399;
-
- p {
- margin: 8px 0;
- }
-
- .tip {
- color: #c0c4cc;
- font-size: 12px;
- }
-}
-
-:deep(.el-tabs--border-card) {
- border: none;
- box-shadow: none;
-}
-
-:deep(.el-tabs__content) {
- padding: 10px;
-}
-
-// 鎶撴媿璁板綍缁熻
-.capture-stats {
- margin-bottom: 16px;
- padding: 16px;
- background: #f5f7fa;
- border-radius: 4px;
-}
-
-.stat-item {
- text-align: center;
- padding: 8px;
- background: #fff;
- border-radius: 4px;
-}
-
-.stat-label {
- font-size: 13px;
- color: #909399;
- margin-bottom: 8px;
-}
-
-.stat-value {
- font-size: 24px;
- font-weight: bold;
- color: #303133;
-}
-
-// 鍒嗛〉瀹瑰櫒
-.pagination-container {
- margin-top: 16px;
- display: flex;
- justify-content: flex-end;
-}
-
-// 蹇収棰勮
-.snapshot-preview {
- width: 100%;
-}
-
-.snapshot-placeholder {
- width: 100%;
- height: 420px;
- background: #f5f7fa;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border-radius: 4px;
- border: 1px dashed #dcdfe6;
- color: #909399;
-
- p {
- margin: 8px 0;
- font-size: 14px;
- }
-
- .tip {
- color: #c0c4cc;
- font-size: 12px;
- }
-}
-
-.snapshot-tools {
- margin-top: 20px;
-}
-
-.snapshot-notes {
- margin-top: 20px;
-
- :deep(.el-divider__text) {
- font-weight: 600;
- color: #606266;
- }
-}
-
-.dialog-footer-custom {
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- > div {
- display: flex;
- gap: 8px;
- }
-}
-
-// 鎻忚堪鍒楄〃鏍峰紡浼樺寲
-:deep(.el-descriptions__label) {
- width: 100px;
-}
-
-:deep(.el-descriptions__content) {
- display: flex;
- align-items: center;
- gap: 4px;
-}
-</style>
-
diff --git a/src/views/oaSystem/projectManagement/components/milestoneList.vue b/src/views/oaSystem/projectManagement/components/milestoneList.vue
deleted file mode 100644
index 47b0027..0000000
--- a/src/views/oaSystem/projectManagement/components/milestoneList.vue
+++ /dev/null
@@ -1,289 +0,0 @@
-// ... existing code ...
-<template>
- <div class="milestone-list-container">
- <el-timeline>
- <el-timeline-item
- v-for="milestone in milestoneList"
- :key="milestone.phaseId"
- :timestamp="milestone.endDate"
- >
- <el-card>
- <template #header>
- <div class="card-header">
- <span>{{ milestone.phaseName }}</span>
- <div class="milestone-actions">
- <el-button type="text" size="small" @click="handleEdit(milestone)">缂栬緫</el-button>
- <el-button type="text" size="small" @click="handleDelete(milestone)" danger>鍒犻櫎</el-button>
- </div>
- </div>
- </template>
- <div class="milestone-content">
- <p>{{ milestone.description }}</p>
- <div class="milestone-status">
- <el-tag :type="getStatusType(milestone.status)">{{ getStatusText(milestone.status) }}</el-tag>
- </div>
- </div>
- </el-card>
- </el-timeline-item>
- </el-timeline>
-
- <!-- 鏃犻噷绋嬬鏃剁殑鎻愮ず -->
- <div v-if="milestoneList.length === 0" class="empty-tip">
- <el-empty description="鏆傛棤閲岀▼纰戞暟鎹�" />
- </div>
-
- <!-- 缂栬緫閲岀▼纰戝璇濇 -->
- <el-dialog
- v-model="dialogVisible"
- :title="'缂栬緫閲岀▼纰�: ' + (form.phaseName || '')"
- width="600px"
- :close-on-click-modal="false"
- >
- <el-form
- ref="formRef"
- :model="form"
- :rules="rules"
- label-width="100px"
- >
- <el-form-item label="閲岀▼纰戝悕绉�" prop="phaseName">
- <el-input v-model="form.phaseName" placeholder="璇疯緭鍏ラ噷绋嬬鍚嶇О" />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
- <el-date-picker
- v-model="form.startDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="form.endDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨缁撴潫鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="鏈紑濮�" value="notStarted" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="宸插欢杩�" value="delayed" />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitEditForm">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, watch, reactive } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { getProject, listProjectPhase, updateProjectPhase,delProjectPhase } from '@/api/oaSystem/projectManagement';
-
-const props = defineProps({
- projectId: {
- type: String,
- required: true
- }
-});
-
-const emit = defineEmits(['refresh']);
-
-const milestoneList = ref([]);
-const dialogVisible = ref(false);
-const formRef = ref(null);
-const form = reactive({
- phaseId: '',
- phaseName: '',
- startDate: '',
- endDate: '',
- status: 'notStarted',
- projectId: props.projectId
-});
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
- phaseName: [
- { required: true, message: '璇疯緭鍏ラ噷绋嬬鍚嶇О', trigger: 'blur' },
- { min: 2, max: 50, message: '闀垮害鍦� 2 鍒� 50 涓瓧绗�', trigger: 'blur' }
- ],
- status: [
- { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
- ]
-};
-
-// 鑾峰彇閲岀▼纰戝垪琛�
-const getMilestoneList = async () => {
- try {
- listProjectPhase(props.projectId).then(res => {
- milestoneList.value = res.data.rows || res.data;
- // 鎸夌洰鏍囨棩鏈熸帓搴�
- // milestoneList.value.sort((a, b) => new Date(a.endDate) - new Date(b.endDate));
- })
- } catch (error) {
- ElMessage.error('鑾峰彇閲岀▼纰戝垪琛ㄥけ璐�');
- console.error('鑾峰彇閲岀▼纰戝垪琛ㄥけ璐�:', error);
- }
-};
-
-// 缂栬緫閲岀▼纰�
-const handleEdit = (milestone) => {
- // 澶嶅埗閲岀▼纰戞暟鎹埌琛ㄥ崟
- Object.assign(form, {
- phaseId: milestone.phaseId,
- phaseName: milestone.phaseName,
- description: milestone.description,
- endDate: milestone.endDate,
- status: milestone.status,
- projectId: props.projectId
- });
- dialogVisible.value = true;
-};
-
-// 鎻愪氦缂栬緫琛ㄥ崟
-const submitEditForm = async () => {
- try {
- await formRef.value.validate();
-
- // 鍙戦�佹洿鏂拌姹�
- const res = await updateProjectPhase(form);
-
- if (res.code === 200) {
- ElMessage.success('閲岀▼纰戠紪杈戞垚鍔�');
- dialogVisible.value = false;
- getMilestoneList(); // 鍒锋柊鍒楄〃
- emit('refresh'); // 閫氱煡鐖剁粍浠跺埛鏂�
- } else {
- ElMessage.error(res.msg || '閲岀▼纰戠紪杈戝け璐�');
- }
- } catch (error) {
- if (error.name === 'ValidationError') {
- // 琛ㄥ崟楠岃瘉澶辫触锛孍lement Plus浼氳嚜鍔ㄦ彁绀�
- return;
- }
- ElMessage.error('閲岀▼纰戠紪杈戝け璐�');
- console.error('缂栬緫閲岀▼纰戝け璐�:', error);
- }
-};
-
-// 鍒犻櫎閲岀▼纰�
-const handleDelete = (milestone) => {
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄ら噷绋嬬 "${milestone.phaseName}" 鍚楋紵鍒犻櫎鍚庡皢鏃犳硶鎭㈠銆俙,
- '鍒犻櫎纭',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- )
- .then(async () => {
- try {
- // 璋冪敤鍒犻櫎API
- const res = await delProjectPhase(milestone.phaseId);
-
- if (res.code === 200) {
- ElMessage.success('閲岀▼纰戝垹闄ゆ垚鍔�');
- getMilestoneList(); // 鍒锋柊鍒楄〃
- emit('refresh'); // 閫氱煡鐖剁粍浠跺埛鏂�
- } else {
- ElMessage.error(res.msg || '閲岀▼纰戝垹闄ゅけ璐�');
- }
- } catch (error) {
- ElMessage.error('閲岀▼纰戝垹闄ゅけ璐�');
- console.error('鍒犻櫎閲岀▼纰戝け璐�:', error);
- }
- })
- .catch(() => {
- // 鐢ㄦ埛鍙栨秷鍒犻櫎
- ElMessage.info('宸插彇娑堝垹闄�');
- });
-};
-
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusType = (status) => {
- const statusTypeMap = {
- notStarted: 'info',
- completed: 'success',
- delayed: 'danger'
- };
- return statusTypeMap[status] || 'default';
-};
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusTextMap = {
- notStarted: '鏈紑濮�',
- completed: '宸插畬鎴�',
- delayed: '宸插欢杩�'
- };
- return statusTextMap[status] || status;
-};
-
-// 鐩戝惉椤圭洰ID鍙樺寲
-watch(() => props.projectId, () => {
- if (props.projectId) {
- getMilestoneList();
- }
-});
-
-// 鍒濆鍖�
-onMounted(() => {
- if (props.projectId) {
- getMilestoneList();
- }
-});
-</script>
-
-<style scoped>
-.milestone-list-container {
- padding: 10px 0;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.milestone-actions {
- display: flex;
- gap: 10px;
-}
-
-.milestone-content {
- padding: 10px 0;
-}
-
-.milestone-status {
- margin-top: 10px;
-}
-
-.empty-tip {
- margin-top: 40px;
- text-align: center;
-}
-
-.dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
-}
-</style>
diff --git a/src/views/oaSystem/projectManagement/components/phaseGoalList.vue b/src/views/oaSystem/projectManagement/components/phaseGoalList.vue
deleted file mode 100644
index 5054299..0000000
--- a/src/views/oaSystem/projectManagement/components/phaseGoalList.vue
+++ /dev/null
@@ -1,165 +0,0 @@
-
-<template>
- <div class="phase-goal-list-container">
- <el-table
- v-loading="loading"
- :data="phaseGoalList"
- style="width: 100%"
- >
- <el-table-column prop="phaseName" label="鎵�灞為樁娈�" width="180" />
- <el-table-column prop="taskName" label="鐩爣鍚嶇О" min-width="200" />
- <el-table-column prop="targetValue" label="鐩爣鍊�" width="120" />
- <el-table-column prop="currentValue" label="褰撳墠鍊�" width="120" />
- <el-table-column prop="unit" label="鍗曚綅" width="80" />
- <el-table-column prop="targetDate" label="鐩爣鏃ユ湡" width="120" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">{{ getStatusText(scope.row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="completionRate" label="瀹屾垚搴�" width="120">
- <template #default="scope">
- <el-progress :percentage="scope.row.completionRate" :stroke-width="6" />
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="150" fixed="right">
- <template #default="scope">
- <el-button type="text" size="small" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button type="text" size="small" @click="handleDelete(scope.row)" danger>鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鏃犻樁娈电洰鏍囨椂鐨勬彁绀� -->
- <div v-if="!loading && phaseGoalList.length === 0" class="empty-tip">
- <el-empty description="鏆傛棤闃舵鐩爣鏁版嵁" />
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted, watch } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { listProjectPhase, updateProjectTask, delProjectTask } from '@/api/oaSystem/projectManagement';
-
-const props = defineProps({
- projectId: {
- type: String,
- required: true
- }
-});
-
-const emit = defineEmits(['refresh']);
-
-const phaseGoalList = ref([]);
-const loading = ref(true);
-
-// 鑾峰彇闃舵鐩爣鍒楄〃
-const getPhaseGoalList = async () => {
- loading.value = true;
- try {
- const { data } = await listProjectPhase(props.projectId);
- // 鍋囪phase鏁版嵁涓寘鍚簡鐩爣淇℃伅
- // 杩欓噷绠�鍖栧鐞嗭紝瀹為檯搴旇璋冪敤涓撻棬鐨勮幏鍙栭樁娈电洰鏍囩殑API
- const phases = data.rows || data;
- phaseGoalList.value = [];
-
- phases.forEach(phase => {
- if (phase.oaProjectPhaseTasks && phase.oaProjectPhaseTasks.length > 0) {
- phase.oaProjectPhaseTasks.forEach(goal => {
- phaseGoalList.value.push({
- ...goal,
- phaseName: phase.phaseName
- });
- });
- }
- });
- } catch (error) {
- ElMessage.error('鑾峰彇闃舵鐩爣鍒楄〃澶辫触');
- console.error('鑾峰彇闃舵鐩爣鍒楄〃澶辫触:', error);
- } finally {
- loading.value = false;
- }
-};
-
-// 缂栬緫闃舵鐩爣
-const handleEdit = (goal) => {
- // 瑙﹀彂鐖剁粍浠剁殑缂栬緫浜嬩欢锛屼紶閫掔洰鏍囨暟鎹�
- emit('editGoal', goal);
-};
-
-// 鍒犻櫎闃舵鐩爣
-const handleDelete = async (goal) => {
- try {
- await ElMessageBox.confirm(
- `纭畾瑕佸垹闄ょ洰鏍囥��${goal.taskName}銆嶅悧锛焋,
- '纭鍒犻櫎',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- );
-
- // 璋冪敤鍒犻櫎API
- await delProjectTask(goal.taskId);
- ElMessage.success('鍒犻櫎闃舵鐩爣鎴愬姛');
-
- // 鍒锋柊鍒楄〃
- getPhaseGoalList();
- emit('refresh');
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('鍒犻櫎闃舵鐩爣澶辫触');
- console.error('鍒犻櫎闃舵鐩爣澶辫触:', error);
- }
- }
-};
-
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusType = (status) => {
- const statusTypeMap = {
- notStarted: 'info',
- inProgress: 'primary',
- completed: 'success',
- delayed: 'danger'
- };
- return statusTypeMap[status] || 'default';
-};
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusTextMap = {
- notStarted: '鏈紑濮�',
- inProgress: '杩涜涓�',
- completed: '宸插畬鎴�',
- delayed: '宸插欢杩�'
- };
- return statusTextMap[status] || status;
-};
-
-// 鐩戝惉椤圭洰ID鍙樺寲
-watch(() => props.projectId, () => {
- if (props.projectId) {
- getPhaseGoalList();
- }
-});
-
-// 鍒濆鍖�
-onMounted(() => {
- if (props.projectId) {
- getPhaseGoalList();
- }
-});
-</script>
-
-<style scoped>
-.phase-goal-list-container {
- padding: 10px 0;
-}
-
-.empty-tip {
- margin-top: 40px;
- text-align: center;
-}
-</style>
diff --git a/src/views/oaSystem/projectManagement/components/projectForm.vue b/src/views/oaSystem/projectManagement/components/projectForm.vue
deleted file mode 100644
index 50b671c..0000000
--- a/src/views/oaSystem/projectManagement/components/projectForm.vue
+++ /dev/null
@@ -1,221 +0,0 @@
-<template>
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="璇疯緭鍏ラ」鐩悕绉�"
- maxlength="50"
- />
- </el-form-item>
- <el-form-item label="椤圭洰鎻忚堪" prop="description">
- <el-input
- v-model="form.description"
- type="textarea"
- :rows="4"
- placeholder="璇疯緭鍏ラ」鐩弿杩�"
- />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
- <el-date-picker
- v-model="form.startDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="form.endDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨缁撴潫鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="椤圭洰璐熻矗浜�" prop="managerId">
- <!-- <el-input
- v-model="form.managerName"
- placeholder="璇烽�夋嫨椤圭洰璐熻矗浜�"
- readonly
- @focus="showUserSelect = true"
- /> -->
- <!-- <el-input
- v-model="userSearchKey"
- placeholder="鎼滅储鐢ㄦ埛"
- v-if="showUserSelect"
- @keyup.enter="searchUsers"
- style="margin-top: 10px"
- /> -->
- <el-select
- v-model="form.managerId"
- style="width: 100%; margin-top: 10px"
- @change="selectUser"
- filterable
- remote
- :remote-method="searchUsers"
- :loading="userLoading"
- placeholder="閫夋嫨椤圭洰璐熻矗浜�"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="椤圭洰瀹屾垚搴�" prop="completionRate">
- <el-slider v-model="form.completionRate" :max="100" />
- </el-form-item>
- <el-form-item label="椤圭洰鐘舵��" prop="status">
- <el-radio-group v-model="form.status">
- <el-radio label="planning">瑙勫垝涓�</el-radio>
- <el-radio label="inProgress">杩涜涓�</el-radio>
- <el-radio label="completed">宸插畬鎴�</el-radio>
- <el-radio label="paused">宸叉殏鍋�</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
-</template>
-
-<script setup>
-import { ref, watch, defineExpose } from 'vue';
-import { listUser } from '@/api/system/user';
-import { ElMessage } from 'element-plus';
-const props = defineProps({
- form: {
- type: Object,
- required: true
- },
- rules: {
- type: Object,
- required: true
- },
- visible: {
- type: Boolean,
- required: true
- }
-});
-
-const formRef = ref();
-const showUserSelect = ref(false);
-const userSearchKey = ref('');
-const userList = ref([]);
-const userLoading = ref(false);
-// 妯℃嫙鐢ㄦ埛鏁版嵁
-const mockUserData = [
- { userId: '1', nickName: '寮犱笁', userName: 'zhangsan' },
- { userId: '2', nickName: '鏉庡洓', userName: 'lisi' },
- { userId: '3', nickName: '鐜嬩簲', userName: 'wangwu' },
- { userId: '4', nickName: '璧靛叚', userName: 'zhaoliu' },
- { userId: '5', nickName: '閽变竷', userName: 'qianqi' },
- { userId: '6', nickName: '瀛欏叓', userName: 'sunba' },
- { userId: '7', nickName: '鍛ㄤ節', userName: 'zhoujiu' },
- { userId: '8', nickName: '鍚村崄', userName: 'wushi' }
-];
-// 鎼滅储鐢ㄦ埛
-const searchUsers = async (query) => {
- userLoading.value = true;
- try {
- // 妯℃嫙缃戠粶寤惰繜
- await new Promise(resolve => setTimeout(resolve, 300));
-
- // 姝g‘璁剧疆鐢ㄦ埛鍒楄〃
- if (!query) {
- userList.value = [...mockUserData];
- } else {
- userList.value = mockUserData.filter(user =>
- user.nickName.includes(query) || user.userName.includes(query)
- );
- }
- } catch (error) {
- console.error('鎼滅储鐢ㄦ埛澶辫触:', error);
- } finally {
- userLoading.value = false;
- }
-};
-
-// 閫夋嫨鐢ㄦ埛
-const selectUser = (userId) => {
- // 鍏堜粠userList鏌ユ壘锛屽鏋滄壘涓嶅埌鍐嶄粠mockUserData涓煡鎵�
- let selectedUser = userList.value.find(user => user.userId === userId);
- if (!selectedUser) {
- selectedUser = mockUserData.find(user => user.userId === userId);
- }
-
- // 浣跨敤Vue.set纭繚鍝嶅簲寮忔洿鏂�
- if (selectedUser) {
- Object.assign(props.form, { managerName: selectedUser.nickName });
- } else {
- Object.assign(props.form, { managerName: '' });
- }
- showUserSelect.value = false;
-};
-
-// 閲嶇疆琛ㄥ崟
-const resetFields = () => {
- if (formRef.value) {
- formRef.value.resetFields();
- }
- showUserSelect.value = false;
- userSearchKey.value = '';
- userList.value = [];
-};
-
-// 楠岃瘉琛ㄥ崟
-const validate = () => {
- return new Promise((resolve, reject) => {
- if (formRef.value) {
- formRef.value.validate((valid) => {
- if (valid) {
- // 棰濆楠岃瘉锛氱粨鏉熸棩鏈熶笉鑳芥棭浜庡紑濮嬫棩鏈�
- if (props.form.startDate && props.form.endDate) {
- const startDate = new Date(props.form.startDate);
- const endDate = new Date(props.form.endDate);
- if (endDate < startDate) {
- ElMessage.error('缁撴潫鏃ユ湡涓嶈兘鏃╀簬寮�濮嬫棩鏈�');
- reject(new Error('鏃ユ湡楠岃瘉澶辫触'));
- return;
- }
- }
- resolve();
- } else {
- reject(new Error('琛ㄥ崟楠岃瘉澶辫触'));
- }
- });
- } else {
- resolve();
- }
- });
-};
-
-// 鐩戝惉瀵硅瘽妗嗘樉绀虹姸鎬�
-watch(() => props.visible, (newVisible) => {
- if (!newVisible) {
- resetFields();
- // 寤惰繜閲嶇疆锛岀‘淇濇暟鎹凡缁忔彁浜ゅ埌鍚庣
- // setTimeout(() => {
- // resetFields();
- // }, 300);
- }
-});
-
-// 鏆撮湶鏂规硶
-defineExpose({
- resetFields,
- validate
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/oaSystem/projectManagement/components/taskTree.vue b/src/views/oaSystem/projectManagement/components/taskTree.vue
deleted file mode 100644
index 11e3ae8..0000000
--- a/src/views/oaSystem/projectManagement/components/taskTree.vue
+++ /dev/null
@@ -1,834 +0,0 @@
-<template>
- <div class="task-tree-container">
- <!-- 浠诲姟鏍戞搷浣滄寜閽� -->
- <div class="tree-actions mb10">
- <el-button type="primary" size="small" icon="Plus" @click="handleAddTask">娣诲姞浠诲姟</el-button>
- <el-button type="success" size="small" icon="RefreshRight" @click="refreshTree">鍒锋柊</el-button>
- <el-button type="info" size="small" icon="Filter" @click="toggleFilter">
- {{ showFilter ? '闅愯棌绛涢��' : '鏄剧ず绛涢��' }}
- </el-button>
- </div>
-
- <!-- 绛涢�夋潯浠� -->
- <div v-if="showFilter" class="filter-section mb10">
- <el-form :inline="true" :model="filterParams">
- <el-form-item label="浠诲姟鐘舵��">
- <el-select v-model="filterParams.status" placeholder="鍏ㄩ儴" clearable style="width: 120px">
- <el-option label="鏈紑濮�" value="notStarted" />
- <el-option label="杩涜涓�" value="inProgress" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="宸查�炬湡" value="overdue" />
- </el-select>
- </el-form-item>
- <el-form-item label="璐熻矗浜�">
- <el-input v-model="filterParams.assignee" placeholder="杈撳叆璐熻矗浜�" clearable style="width: 150px" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" size="small" @click="filterTree">绛涢��</el-button>
- <el-button size="small" @click="resetFilter">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 浠诲姟鏍� -->
- <div class="tree-content">
- <el-tree
- v-loading="loading"
- :data="taskTreeData"
- :props="defaultProps"
- :expand-on-click-node="false"
- node-key="nodeId"
- ref="treeRef"
- @node-contextmenu="handleContextMenu"
- @node-click="handleNodeClick"
- >
- <template #default="{ node, data }">
- <!-- 鑺傜偣鍐呭 -->
- <div class="tree-node-content" :class="{ 'phase-node': data.type === 'phase', 'task-node': data.type === 'task' }">
- <!-- 鑺傜偣鍥炬爣 -->
- <div class="node-icon">
- <i v-if="data.type === 'phase'" class="el-icon-folder text-primary" />
- <i v-else-if="data.status === 'completed'" class="el-icon-circle-check text-success" />
- <i v-else-if="data.status === 'inProgress'" class="el-icon-circle-check text-primary" />
- <i v-else-if="data.status === 'overdue'" class="el-icon-alarm-clock text-danger" />
- <i v-else class="el-icon-circle-close text-gray-400" />
- </div>
-
- <!-- 鑺傜偣鏍囬鍜屾弿杩� -->
- <div class="node-info">
- <div class="node-title" :class="{ 'overdue-title': data.type === 'task' && data.status === 'overdue' }">
- {{ node.label }}
- <span v-if="data.type === 'task' && data.priority === 'high'" class="priority-tag">楂樹紭</span>
- <span v-else-if="data.type === 'task' && data.priority === 'medium'" class="priority-tag medium">涓紭</span>
- </div>
- <div v-if="data.description" class="node-description">{{ data.description }}</div>
-
- <!-- 浠诲姟鍏冧俊鎭� -->
- <div v-if="data.type === 'task'" class="task-meta">
- <span class="meta-item">
- <i class="el-icon-user"></i>
- {{ data.assigneeName || '鏈垎閰�' }}
- </span>
- <span class="meta-item">
- <i class="el-icon-calendar"></i>
- {{ formatDateRange(data.startDate, data.endDate) }}
- </span>
- </div>
- </div>
-
- <!-- 浠诲姟杩涘害鏉� -->
- <div v-if="data.type === 'task'" class="task-progress">
- <el-progress :percentage="data.progress || 0" :stroke-width="4" :show-text="false" />
- </div>
-
- <!-- 鎿嶄綔鎸夐挳 -->
- <div class="node-actions">
- <el-button
- v-if="data.type === 'task'"
- type="text"
- size="small"
- icon="Edit"
- @click.stop="handleEditTask(data)"
- v-hasPermi="['oaSystem:task:edit']"
- />
- <el-button
- v-if="data.type === 'phase'"
- type="text"
- size="small"
- icon="Plus"
- @click.stop="handleAddTaskUnderPhase(data)"
- v-hasPermi="['oaSystem:task:add']"
- />
- <el-button
- type="text"
- size="small"
- icon="Delete"
- @click.stop="handleDeleteNode(data)"
- v-hasPermi="['oaSystem:task:remove']"
- />
- </div>
- </div>
- </template>
- </el-tree>
- </div>
-
- <!-- 鍙抽敭鑿滃崟 -->
- <div v-if="showContextMenu" :style="contextMenuStyle" class="context-menu">
- <el-menu @select="handleContextMenuSelect">
- <el-menu-item v-if="selectedNode.type === 'task'" index="edit">缂栬緫浠诲姟</el-menu-item>
- <el-menu-item v-if="selectedNode.type === 'phase'" index="addTask">娣诲姞瀛愪换鍔�</el-menu-item>
- <el-menu-item index="delete">鍒犻櫎</el-menu-item>
- <el-menu-item index="expandAll">灞曞紑鍏ㄩ儴</el-menu-item>
- <el-menu-item index="collapseAll">鏀惰捣鍏ㄩ儴</el-menu-item>
- </el-menu>
- </div>
-
- <!-- 浠诲姟琛ㄥ崟瀵硅瘽妗� -->
- <el-dialog :title="dialogTitle" v-model="dialogOpen" width="600px" append-to-body>
- <el-form ref="taskFormRef" :model="taskForm" :rules="taskRules" label-width="80px">
- <el-form-item label="浠诲姟鍚嶇О" prop="taskName">
- <el-input v-model="taskForm.taskName" placeholder="璇疯緭鍏ヤ换鍔″悕绉�" />
- </el-form-item>
- <el-form-item label="璐熻矗浜�" prop="assigneeId">
- <el-input v-model="taskForm.assigneeId" placeholder="璇疯緭鍏ヨ礋璐d汉ID" />
- </el-form-item>
- <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
- <el-date-picker
- v-model="taskForm.startDate"
- type="date"
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="taskForm.endDate"
- type="date"
- placeholder="閫夋嫨缁撴潫鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="浼樺厛绾�" prop="priority">
- <el-select v-model="taskForm.priority" placeholder="閫夋嫨浼樺厛绾�">
- <el-option label="浣�" value="low" />
- <el-option label="涓�" value="medium" />
- <el-option label="楂�" value="high" />
- </el-select>
- </el-form-item>
- <el-form-item label="杩涘害" prop="progress">
- <el-input-number v-model="taskForm.progress" :min="0" :max="100" style="width: 100%" />
- </el-form-item>
- <el-form-item label="鎻忚堪" prop="description">
- <el-input v-model="taskForm.description" type="textarea" placeholder="璇疯緭鍏ヤ换鍔℃弿杩�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogOpen = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitTaskForm">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, watch, onMounted } from 'vue';
-import { ElMessage, ElMessageBox, ElMenu, ElMenuItem } from 'element-plus';
-// import { getProject, addTask, updateTask, deleteTask, deletePhase } from '@/api/oaSystem/projectManagement';
-
-const props = defineProps({
- projectId: {
- type: String,
- required: true
- }
-});
-
-const emit = defineEmits(['refresh']);
-
-// 缁勪欢鐘舵��
-const loading = ref(false);
-const treeRef = ref();
-const showContextMenu = ref(false);
-const contextMenuStyle = ref({});
-const selectedNode = ref({});
-const showFilter = ref(false);
-const dialogOpen = ref(false);
-const dialogTitle = ref('');
-const taskFormRef = ref();
-
-// 绛涢�夊弬鏁�
-const filterParams = reactive({
- status: '',
- assignee: ''
-});
-
-// 浠诲姟琛ㄥ崟鏁版嵁
-const taskForm = reactive({
- taskId: undefined,
- taskName: '',
- description: '',
- startDate: '',
- endDate: '',
- assigneeId: '',
- assigneeName: '',
- status: 'notStarted',
- progress: 0,
- priority: 'medium',
- phaseId: '',
- projectId: props.projectId
-});
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const taskRules = {
- taskName: [
- { required: true, message: '浠诲姟鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' },
- { min: 2, max: 50, message: '浠诲姟鍚嶇О闀垮害鍦� 2 鍒� 50 涓瓧绗�', trigger: 'blur' }
- ],
- startDate: [
- { required: true, message: '寮�濮嬫棩鏈熶笉鑳戒负绌�', trigger: 'change' }
- ],
- endDate: [
- { required: true, message: '缁撴潫鏃ユ湡涓嶈兘涓虹┖', trigger: 'change' }
- ],
- assigneeId: [
- { required: true, message: '璐熻矗浜轰笉鑳戒负绌�', trigger: 'blur' }
- ],
- progress: [
- { required: true, message: '杩涘害涓嶈兘涓虹┖', trigger: 'blur' },
- { type: 'number', min: 0, max: 100, message: '杩涘害蹇呴』鍦� 0 鍒� 100 涔嬮棿', trigger: 'blur' }
- ]
-};
-
-// 浠诲姟鏍戞暟鎹�
-const rawTaskTreeData = ref([]);
-
-// 妯℃嫙浠诲姟鏁版嵁
-const mockTaskData = {
- 'PRJ2023001': [
- {
- phaseId: 'PHASE001',
- phaseName: '闇�姹傚垎鏋�',
- startDate: '2023-11-01',
- endDate: '2023-11-15',
- status: 'completed',
- tasks: [
- {
- taskId: 'TASK001',
- taskName: '闇�姹傝皟鐮�',
- description: '璋冪爺鐢ㄦ埛闇�姹傚拰涓氬姟娴佺▼',
- startDate: '2023-11-01',
- endDate: '2023-11-05',
- assigneeId: 'USER001',
- assigneeName: '寮犱笁',
- status: 'completed',
- progress: 100,
- priority: 'medium'
- },
- {
- taskId: 'TASK002',
- taskName: '闇�姹傛枃妗g紪鍐�',
- description: '缂栧啓璇︾粏鐨勯渶姹傝鏍艰鏄庝功',
- startDate: '2023-11-06',
- endDate: '2023-11-15',
- assigneeId: 'USER002',
- assigneeName: '鏉庡洓',
- status: 'completed',
- progress: 100,
- priority: 'high'
- }
- ]
- },
- {
- phaseId: 'PHASE002',
- phaseName: '绯荤粺璁捐',
- startDate: '2023-11-16',
- endDate: '2023-12-10',
- status: 'completed',
- tasks: [
- {
- taskId: 'TASK003',
- taskName: '绯荤粺鏋舵瀯璁捐',
- description: '璁捐绯荤粺鏁翠綋鏋舵瀯',
- startDate: '2023-11-16',
- endDate: '2023-11-25',
- assigneeId: 'USER003',
- assigneeName: '鐜嬩簲',
- status: 'completed',
- progress: 100,
- priority: 'high'
- },
- {
- taskId: 'TASK004',
- taskName: '鏁版嵁搴撹璁�',
- description: '璁捐鏁版嵁搴撹〃缁撴瀯鍜屽叧绯�',
- startDate: '2023-11-26',
- endDate: '2023-12-10',
- assigneeId: 'USER004',
- assigneeName: '璧靛叚',
- status: 'completed',
- progress: 100,
- priority: 'medium'
- }
- ]
- },
- {
- phaseId: 'PHASE003',
- phaseName: '寮�鍙戝疄鐜�',
- startDate: '2023-12-11',
- endDate: '2024-01-31',
- status: 'inProgress',
- tasks: [
- {
- taskId: 'TASK005',
- taskName: '鍓嶇寮�鍙�',
- description: '寮�鍙戠敤鎴风晫闈㈠拰浜や簰閫昏緫',
- startDate: '2023-12-11',
- endDate: '2024-01-15',
- assigneeId: 'USER005',
- assigneeName: '閽变竷',
- status: 'inProgress',
- progress: 70,
- priority: 'high'
- },
- {
- taskId: 'TASK006',
- taskName: '鍚庣寮�鍙�',
- description: '寮�鍙戜笟鍔¢�昏緫鍜孉PI鎺ュ彛',
- startDate: '2023-12-11',
- endDate: '2024-01-20',
- assigneeId: 'USER006',
- assigneeName: '瀛欏叓',
- status: 'inProgress',
- progress: 60,
- priority: 'high'
- }
- ]
- }
- ],
- // 榛樿鏁版嵁
- default: [
- {
- phaseId: 'PHASE_DEFAULT1',
- phaseName: '鍑嗗闃舵',
- startDate: '2023-01-01',
- endDate: '2023-03-31',
- status: 'completed',
- tasks: [
- {
- taskId: 'TASK_DEFAULT1',
- taskName: '椤圭洰鍚姩',
- description: '鍙紑椤圭洰鍚姩浼氳',
- startDate: '2023-01-01',
- endDate: '2023-01-05',
- assigneeId: 'USER_DEFAULT1',
- assigneeName: '璐熻矗浜篈',
- status: 'completed',
- progress: 100,
- priority: 'high'
- }
- ]
- },
- {
- phaseId: 'PHASE_DEFAULT2',
- phaseName: '鎵ц闃舵',
- startDate: '2023-04-01',
- endDate: '2023-09-30',
- status: 'inProgress',
- tasks: [
- {
- taskId: 'TASK_DEFAULT2',
- taskName: '鏍稿績鍔熻兘寮�鍙�',
- description: '寮�鍙戠郴缁熸牳蹇冨姛鑳芥ā鍧�',
- startDate: '2023-04-01',
- endDate: '2023-06-30',
- assigneeId: 'USER_DEFAULT2',
- assigneeName: '璐熻矗浜築',
- status: 'inProgress',
- progress: 50,
- priority: 'high'
- }
- ]
- }
- ]
-};
-
-const taskTreeData = computed(() => {
- // 搴旂敤绛涢�夋潯浠�
- if (!showFilter.value || (!filterParams.status && !filterParams.assignee)) {
- return rawTaskTreeData.value;
- }
-
- // 娣辨嫹璐濆師濮嬫暟鎹互閬垮厤淇敼
- const filteredData = JSON.parse(JSON.stringify(rawTaskTreeData.value));
-
- // 閫掑綊绛涢�夎妭鐐�
- const filterNodes = (nodes) => {
- const result = [];
-
- nodes.forEach(node => {
- // 瀵逛簬闃舵鑺傜偣锛屾鏌ュ叾瀛愪换鍔℃槸鍚︾鍚堢瓫閫夋潯浠�
- if (node.type === 'phase' && node.children) {
- const filteredChildren = filterNodes(node.children);
- if (filteredChildren.length > 0) {
- // 淇濈暀鑷冲皯鏈変竴涓瓙浠诲姟绗﹀悎鏉′欢鐨勯樁娈�
- node.children = filteredChildren;
- result.push(node);
- }
- }
- // 瀵逛簬浠诲姟鑺傜偣锛岀洿鎺ュ簲鐢ㄧ瓫閫夋潯浠�
- else if (node.type === 'task') {
- const statusMatch = !filterParams.status || node.status === filterParams.status;
- const assigneeMatch = !filterParams.assignee ||
- (node.assigneeName && node.assigneeName.includes(filterParams.assignee));
-
- if (statusMatch && assigneeMatch) {
- result.push(node);
- }
- }
- });
-
- return result;
- };
-
- return filterNodes(filteredData);
-});
-
-// 鏍戣妭鐐归厤缃�
-const defaultProps = {
- children: 'children',
- label: (data) => {
- if (data.type === 'phase') {
- return `${data.phaseName}`;
- } else {
- return `${data.taskName}`;
- }
- }
-};
-
-// 鍔犺浇浠诲姟鏍戞暟鎹�
-const loadTaskTree = async () => {
- loading.value = true;
- // try {
- // const { data } = await getProject(props.projectId);
- // rawTaskTreeData.value = buildTaskTree(data.phases || []);
- // } catch (error) {
- // ElMessage.error('鍔犺浇浠诲姟鏍戝け璐�');
- // console.error('鍔犺浇浠诲姟鏍戝け璐�:', error);
- // } finally {
- // loading.value = false;
- // }
- try {
- // 妯℃嫙缃戠粶寤惰繜
- await new Promise(resolve => setTimeout(resolve, 500));
-
- // 浣跨敤妯℃嫙鏁版嵁鏇夸唬API璇锋眰
- const phases = mockTaskData[props.projectId] || mockTaskData.default;
- rawTaskTreeData.value = buildTaskTree(phases);
- } catch (error) {
- ElMessage.error('鍔犺浇浠诲姟鏍戝け璐�');
- console.error('鍔犺浇浠诲姟鏍戝け璐�:', error);
- } finally {
- loading.value = false;
- }
-};
-
-// 鏋勫缓浠诲姟鏍�
-const buildTaskTree = (phases) => {
- return phases.map(phase => ({
- nodeId: phase.phaseId,
- phaseId: phase.phaseId,
- phaseName: phase.phaseName,
- type: 'phase',
- children: (phase.tasks || []).map(task => ({
- nodeId: task.taskId,
- taskId: task.taskId,
- taskName: task.taskName,
- description: task.description,
- startDate: task.startDate,
- endDate: task.endDate,
- assigneeId: task.assigneeId,
- assigneeName: task.assigneeName,
- status: task.status,
- progress: task.progress,
- priority: task.priority,
- phaseId: task.phaseId,
- projectId: props.projectId,
- type: 'task'
- }))
- }));
-};
-
-// 鏍煎紡鍖栨棩鏈熻寖鍥�
-const formatDateRange = (startDate, endDate) => {
- if (!startDate || !endDate) return '';
- return `${startDate} - ${endDate}`;
-};
-
-// 鍒锋柊鏍�
-const refreshTree = () => {
- loadTaskTree();
- // 閫氱煡鐖剁粍浠跺埛鏂版暟鎹�
- emit('refresh');
-};
-
-// 鍒囨崲绛涢�夐潰鏉�
-const toggleFilter = () => {
- showFilter.value = !showFilter.value;
-};
-
-// 搴旂敤绛涢��
-const filterTree = () => {
- // 绛涢�夐�昏緫宸茬粡鍦╟omputed涓疄鐜�
-};
-
-// 閲嶇疆绛涢��
-const resetFilter = () => {
- filterParams.status = '';
- filterParams.assignee = '';
-};
-
-// 澶勭悊鑺傜偣鐐瑰嚮
-const handleNodeClick = (data, node) => {
- // 鍒囨崲灞曞紑/鏀惰捣鐘舵��
- if (data.type === 'phase') {
- node.expanded = !node.expanded;
- }
-};
-
-// 澶勭悊鍙抽敭鑿滃崟
-const handleContextMenu = (event, data) => {
- event.preventDefault();
- selectedNode.value = data;
- contextMenuStyle.value = {
- position: 'fixed',
- left: `${event.clientX}px`,
- top: `${event.clientY}px`,
- zIndex: 1000
- };
- showContextMenu.value = true;
-};
-
-// 澶勭悊鍙抽敭鑿滃崟閫夋嫨
-const handleContextMenuSelect = (index) => {
- showContextMenu.value = false;
- switch (index) {
- case 'edit':
- if (selectedNode.value.type === 'task') {
- handleEditTask(selectedNode.value);
- }
- break;
- case 'addTask':
- if (selectedNode.value.type === 'phase') {
- handleAddTaskUnderPhase(selectedNode.value);
- }
- break;
- case 'delete':
- handleDeleteNode(selectedNode.value);
- break;
- case 'expandAll':
- treeRef.value?.expandAll();
- break;
- case 'collapseAll':
- treeRef.value?.collapseAll();
- break;
- }
-};
-
-// 娣诲姞浠诲姟
-const handleAddTask = () => {
- resetTaskForm();
- dialogTitle.value = '娣诲姞浠诲姟';
- dialogOpen.value = true;
-};
-
-// 鍦ㄦ寚瀹氶樁娈典笅娣诲姞浠诲姟
-const handleAddTaskUnderPhase = (phase) => {
- resetTaskForm();
- taskForm.phaseId = phase.phaseId;
- dialogTitle.value = '娣诲姞瀛愪换鍔�';
- dialogOpen.value = true;
-};
-
-// 缂栬緫浠诲姟
-const handleEditTask = (task) => {
- resetTaskForm();
- Object.assign(taskForm, { ...task });
- dialogTitle.value = '缂栬緫浠诲姟';
- dialogOpen.value = true;
-};
-
-// 鍒犻櫎鑺傜偣
-const handleDeleteNode = async (node) => {
- const confirmMessage = node.type === 'phase'
- ? `纭畾瑕佸垹闄ら樁娈� "${node.phaseName}" 鍙婂叾鎵�鏈夊瓙浠诲姟鍚楋紵`
- : `纭畾瑕佸垹闄や换鍔� "${node.taskName}" 鍚楋紵`;
-
- await ElMessageBox.confirm(confirmMessage, '纭鎿嶄綔', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).catch(() => {
- throw new Error('鍙栨秷鍒犻櫎');
- });
-
- try {
- if (node.type === 'phase') {
- await deletePhase(node.phaseId);
- } else {
- await deleteTask(node.taskId);
- }
- ElMessage.success('鍒犻櫎鎴愬姛');
- refreshTree();
- } catch (error) {
- if (error.message !== '鍙栨秷鍒犻櫎') {
- ElMessage.error('鍒犻櫎澶辫触');
- console.error('鍒犻櫎澶辫触:', error);
- }
- }
-};
-
-// 閲嶇疆浠诲姟琛ㄥ崟
-const resetTaskForm = () => {
- taskForm.taskId = undefined;
- taskForm.taskName = '';
- taskForm.description = '';
- taskForm.startDate = '';
- taskForm.endDate = '';
- taskForm.assigneeId = '';
- taskForm.assigneeName = '';
- taskForm.status = 'notStarted';
- taskForm.progress = 0;
- taskForm.priority = 'medium';
- taskForm.phaseId = '';
- taskForm.projectId = props.projectId;
-
- if (taskFormRef.value) {
- taskFormRef.value.resetFields();
- }
-};
-
-// 鎻愪氦浠诲姟琛ㄥ崟
-const submitTaskForm = async () => {
- try {
- await taskFormRef.value.validate();
-
- if (taskForm.taskId) {
- await updateTask(taskForm);
- ElMessage.success('淇敼浠诲姟鎴愬姛');
- } else {
- await addTask(taskForm);
- ElMessage.success('娣诲姞浠诲姟鎴愬姛');
- }
-
- dialogOpen.value = false;
- refreshTree();
- } catch (error) {
- console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
- }
-};
-
-// 鐐瑰嚮鍏朵粬鍖哄煙鍏抽棴鍙抽敭鑿滃崟
-document.addEventListener('click', () => {
- if (showContextMenu.value) {
- showContextMenu.value = false;
- }
-});
-
-// 鐩戝惉椤圭洰ID鍙樺寲
-watch(() => props.projectId, (newProjectId) => {
- if (newProjectId) {
- loadTaskTree();
- }
-});
-
-// 鍒濆鍖�
-onMounted(() => {
- loadTaskTree();
-});
-</script>
-
-<style scoped>
-.task-tree-container {
- padding: 10px;
-}
-
-.tree-actions {
- display: flex;
- gap: 10px;
- align-items: center;
-}
-
-.filter-section {
- background: #f5f7fa;
- padding: 10px;
- border-radius: 4px;
-}
-
-.tree-content {
- background: #fff;
- border: 1px solid #ebeef5;
- border-radius: 4px;
- padding: 10px;
- max-height: 600px;
- overflow-y: auto;
-}
-
-.tree-node-content {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 5px 0;
- min-height: 40px;
-}
-
-.phase-node {
- font-weight: bold;
- color: #409eff;
-}
-
-.task-node {
- color: #606266;
-}
-
-.node-icon {
- display: flex;
- align-items: center;
- width: 20px;
-}
-
-.node-info {
- flex: 1;
- min-width: 0;
-}
-
-.node-title {
- font-weight: 500;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- margin-bottom: 2px;
-}
-
-.overdue-title {
- color: #f56c6c;
- font-weight: bold;
-}
-
-.priority-tag {
- background: #f56c6c;
- color: white;
- font-size: 10px;
- padding: 1px 4px;
- border-radius: 2px;
- margin-left: 5px;
-}
-
-.priority-tag.medium {
- background: #e6a23c;
-}
-
-.node-description {
- font-size: 12px;
- color: #909399;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.task-meta {
- display: flex;
- gap: 15px;
- font-size: 12px;
- color: #909399;
- margin-top: 2px;
-}
-
-.meta-item {
- display: flex;
- align-items: center;
- gap: 3px;
-}
-
-.task-progress {
- width: 120px;
- margin: 0 10px;
-}
-
-.node-actions {
- display: flex;
- gap: 5px;
- opacity: 0;
- transition: opacity 0.3s;
-}
-
-.tree-node-content:hover .node-actions {
- opacity: 1;
-}
-
-.context-menu {
- background: white;
- border: 1px solid #ebeef5;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- border-radius: 4px;
-}
-
-.context-menu .el-menu {
- min-width: 120px;
- border: none;
-}
-
-.context-menu .el-menu-item {
- padding: 0 15px;
- height: 36px;
- line-height: 36px;
-}
-
-.context-menu .el-menu-item:hover {
- background-color: #f5f7fa;
-}
-
-.text-gray-400 {
- color: #c0c4cc;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/oaSystem/projectManagement/index.vue b/src/views/oaSystem/projectManagement/index.vue
deleted file mode 100644
index 2a0ec3a..0000000
--- a/src/views/oaSystem/projectManagement/index.vue
+++ /dev/null
@@ -1,481 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤堕儴鎼滅储鍜屾搷浣滄爮 -->
- <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="80px">
- <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
- <el-input
- v-model="queryParams.projectName"
- placeholder="璇疯緭鍏ラ」鐩悕绉�"
- clearable
- style="width: 240px"
- @keyup.enter="handleQuery"
- />
- </el-form-item>
- <el-form-item label="璐熻矗浜�" prop="managerName">
- <el-input
- v-model="queryParams.managerName"
- placeholder="璇疯緭鍏ヨ礋璐d汉濮撳悕"
- clearable
- style="width: 240px"
- @keyup.enter="handleQuery"
- />
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select
- v-model="queryParams.status"
- placeholder="椤圭洰鐘舵��"
- clearable
- style="width: 150px"
- >
- <el-option label="瑙勫垝涓�" value="planning" />
- <el-option label="杩涜涓�" value="inProgress" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="宸叉殏鍋�" value="paused" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
- <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
-
- <!-- 宸ュ叿鏍� -->
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button
- type="primary"
- plain
- icon="Plus"
- @click="handleAdd"
- v-hasPermi="['oaSystem:project:add']"
- >鏂板椤圭洰</el-button>
- </el-col>
- <!-- <el-col :span="1.5">
- <el-button
- type="success"
- plain
- icon="Edit"
- :disabled="single"
- @click="handleUpdate"
- v-hasPermi="['oaSystem:project:edit']"
- >缂栬緫椤圭洰</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="danger"
- plain
- icon="Delete"
- :disabled="multiple"
- @click="handleDelete"
- v-hasPermi="['oaSystem:project:remove']"
- >鍒犻櫎椤圭洰</el-button>
- </el-col> -->
- <el-col :span="1.5">
- <el-button
- type="warning"
- plain
- icon="Download"
- @click="handleExport"
- v-hasPermi="['oaSystem:project:export']"
- >瀵煎嚭椤圭洰</el-button>
- </el-col>
- </el-row>
-
- <!-- 椤圭洰鍒楄〃琛ㄦ牸 -->
- <el-table
- v-loading="loading"
- :data="projectList"
- @selection-change="handleSelectionChange"
- >
- <el-table-column type="selection" width="50" align="center" />
- <el-table-column
- label="椤圭洰缂栧彿"
- align="center"
- prop="projectId"
- width="100"
- />
- <el-table-column
- label="椤圭洰鍚嶇О"
- align="center"
- prop="projectName"
- :show-overflow-tooltip="true"
- />
- <el-table-column
- label="璐熻矗浜�"
- align="center"
- prop="managerName"
- />
- <el-table-column
- label="寮�濮嬫棩鏈�"
- align="center"
- prop="startDate"
- width="120"
- />
- <el-table-column
- label="缁撴潫鏃ユ湡"
- align="center"
- prop="endDate"
- width="120"
- />
- <el-table-column
- label="鐘舵��"
- align="center"
- prop="status"
- width="90"
- >
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">{{ getStatusText(scope.row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="瀹屾垚搴�"
- align="center"
- prop="completionRate"
- width="100"
- >
- <template #default="scope">
- <el-progress :percentage="scope.row.completionRate" :stroke-width="6" />
- </template>
- </el-table-column>
- <el-table-column
- label="鎿嶄綔"
- align="center"
- width="180"
- class-name="small-padding fixed-width"
- >
- <template #default="scope">
- <el-button
- link
- type="primary"
- icon="Search"
- @click="handleView(scope.row)"
- v-hasPermi="['oaSystem:project:query']"
- >璇︽儏</el-button>
- <el-button
- link
- type="primary"
- icon="Edit"
- @click="handleUpdate(scope.row)"
- v-hasPermi="['oaSystem:project:edit']"
- >缂栬緫</el-button>
- <el-button
- link
- type="danger"
- icon="Delete"
- @click="handleDelete(scope.row)"
- v-hasPermi="['oaSystem:project:remove']"
- >鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉缁勪欢 -->
- <pagination
- v-show="total > 0"
- :total="total"
- v-model:page="queryParams.pageNum"
- v-model:limit="queryParams.pageSize"
- @pagination="getList"
- />
-
- <!-- 椤圭洰琛ㄥ崟瀵硅瘽妗� -->
- <el-dialog :title="title" v-model="open" width="600px" append-to-body>
- <project-form
- ref="projectFormRef"
- :form="form"
- :rules="rules"
- :visible="open"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancel">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import Pagination from '@/components/Pagination';
-import ProjectForm from './components/projectForm.vue';
-import { useRouter } from 'vue-router';
-const { proxy } = getCurrentInstance();
-// 瀵煎叆椤圭洰绠$悊API鎺ュ彛
-import { listProject, addProject, updateProject, delProject, exportProject } from '@/api/oaSystem/projectManagement';
-// import { listUser } from '@/api/system/user'; // 瀵煎叆鐢ㄦ埛鍒楄〃API鎺ュ彛
-
-// 鍒涘缓router瀹炰緥
-const router = useRouter();
-
-// 琛ㄦ牸鏁版嵁
-const projectList = ref([]);
-const loading = ref(true);
-const total = ref(0);
-const queryParams = reactive({
- pageNum: 1,
- pageSize: 10,
- projectName: '',
- managerName: '',
- status: ''
-});
-
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
- projectId: undefined,
- projectName: '',
- description: '',
- startDate: '',
- endDate: '',
- managerId: '',
- managerName: '',
- status: 'planning',
- completionRate: 0
-});
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- projectName: [
- { required: true, message: '椤圭洰鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' },
- { min: 2, max: 50, message: '椤圭洰鍚嶇О闀垮害鍦� 2 鍒� 50 涓瓧绗�', trigger: 'blur' }
- ],
- startDate: [
- { required: true, message: '寮�濮嬫棩鏈熶笉鑳戒负绌�', trigger: 'change' }
- ],
- endDate: [
- { required: true, message: '缁撴潫鏃ユ湡涓嶈兘涓虹┖', trigger: 'change' }
- ],
- managerId: [
- { required: true, message: '璐熻矗浜轰笉鑳戒负绌�', trigger: 'blur' }
- ]
-};
-
-// 瀵硅瘽妗嗙姸鎬�
-const open = ref(false);
-const title = ref('');
-const projectFormRef = ref();
-const queryRef = ref();
-
-// 閫変腑鐘舵��
-const multiple = computed(() => {
- return selectedRowKeys.value.length === 0;
-});
-const single = computed(() => {
- return selectedRowKeys.value.length !== 1;
-});
-const selectedRowKeys = ref([]);
-
-// 鑾峰彇椤圭洰鍒楄〃
-const getList = async () => {
- loading.value = true;
- try {
- const { data } = await listProject(queryParams);
- projectList.value = data.records;
- total.value = data.total;
- } catch (error) {
- ElMessage.error('鑾峰彇椤圭洰鍒楄〃澶辫触');
- console.error('鑾峰彇椤圭洰鍒楄〃澶辫触:', error);
- } finally {
- loading.value = false;
- }
-};
-
-// 鎼滅储
-const handleQuery = () => {
- queryParams.pageNum = 1;
- getList();
-};
-
-// 閲嶇疆
-const resetQuery = () => {
- if (queryRef.value) {
- queryRef.value.resetFields();
- }
- handleQuery();
-};
-
-// 閫変腑琛屽彉鍖�
-const handleSelectionChange = (selection) => {
- selectedRowKeys.value = selection.map(item => item.projectId);
-};
-
-// 鏂板椤圭洰
-const handleAdd = () => {
- resetForm();
- open.value = true;
- title.value = '鏂板椤圭洰';
-};
-
-// 缂栬緫椤圭洰
-const handleUpdate = async (row) => {
- resetForm();
- const projectId = row.projectId || selectedRowKeys.value[0];
- try {
- // const { data } = await getProject(projectId);
- Object.assign(form, row);
- open.value = true;
- title.value = '缂栬緫椤圭洰';
- } catch (error) {
- ElMessage.error('鑾峰彇椤圭洰璇︽儏澶辫触');
- console.error('鑾峰彇椤圭洰璇︽儏澶辫触:', error);
- }
-};
-
-// 鍒犻櫎椤圭洰
-const handleDelete = async (row) => {
- // const projectIds = row.projectId ? [row.projectId] : selectedRowKeys.value;
- const projectNames = row.projectName ? [row.projectName] :
- projectList.value.filter(item => projectIds.includes(item.projectId)).map(item => item.projectName);
-
- const confirmMessage = `纭畾瑕佸垹闄ら」鐩� "${projectNames.join('銆�')}" 鍚楋紵`;
- await ElMessageBox.confirm(confirmMessage, '纭鎿嶄綔', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).catch(() => {
- throw new Error('鍙栨秷鍒犻櫎');
- });
-
- try {
- // if (projectIds.length === 1) {
- await delProject(row.projectId);
- // } else {
- // await delProjectBatch(projectIds);
- // }
- ElMessage.success('鍒犻櫎鎴愬姛');
- getList();
- } catch (error) {
- if (error.message !== '鍙栨秷鍒犻櫎') {
- ElMessage.error('鍒犻櫎澶辫触');
- console.error('鍒犻櫎椤圭洰澶辫触:', error);
- }
- }
- // try {
- // await ElMessageBox.confirm(confirmMessage, '纭鎿嶄綔', {
- // confirmButtonText: '纭畾',
- // cancelButtonText: '鍙栨秷',
- // type: 'warning'
- // });
-
- // // 妯℃嫙缃戠粶寤惰繜
- // await new Promise(resolve => setTimeout(resolve, 300));
-
-
- // ElMessage.success('鍒犻櫎鎴愬姛');
- // getList();
- // } catch (error) {
- // if (error !== 'cancel') {
- // console.error('鍒犻櫎椤圭洰澶辫触:', error);
- // }
- // }
-};
-
-// 鏌ョ湅椤圭洰璇︽儏
-const handleView = (row) => {
- const projectId = row.projectId;
- // 璺宠浆鍒伴」鐩鎯呴〉闈�
- router.push({
- path: `/oaSystem/projectManagement/projectDetail/${projectId}`,
- query: { projectName: row.projectName }
- });
-};
-
-// 瀵煎嚭椤圭洰
-const handleExport = async () => {
- let ids = [];
- if (selectedRowKeys.value.length > 0) {
- ids = selectedRowKeys.value; // 瀵煎嚭閫変腑鐨勯」鐩�
- } else {
- ids = projectList.value.map(item => item.projectId); // 瀵煎嚭鎵�鏈夐」鐩�
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download(`/oA/project/export/${ids.join(',')}`, {}, "椤圭洰鏁版嵁.xlsx");
- ElMessage.success("瀵煎嚭鎴愬姛");
- ids = [];
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- await projectFormRef.value.validate();
-
- if (form.projectId) {
- await updateProject(form);
- ElMessage.success('淇敼椤圭洰鎴愬姛');
- } else {
- console.log("form",form);
- await addProject(form);
- ElMessage.success('鏂板椤圭洰鎴愬姛');
- }
- open.value = false;
- getList();
- } catch (error) {
- console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
- }
-};
-
-// 鍙栨秷
-const cancel = () => {
- open.value = false;
- resetForm();
-};
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
- form.projectId = undefined;
- form.projectName = '';
- form.description = '';
- form.startDate = '';
- form.endDate = '';
- form.managerId = '';
- form.managerName = '';
- form.status = 'planning';
- form.completionRate = 0;
- if (projectFormRef.value) {
- projectFormRef.value.resetFields();
- }
-};
-
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusType = (status) => {
- const statusTypeMap = {
- planning: 'info',
- inProgress: 'primary',
- completed: 'success',
- paused: 'warning'
- };
- return statusTypeMap[status] || 'default';
-};
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusTextMap = {
- planning: '瑙勫垝涓�',
- inProgress: '杩涜涓�',
- completed: '宸插畬鎴�',
- paused: '宸叉殏鍋�'
- };
- return statusTextMap[status] || status;
-};
-
-// 鍒濆鍖�
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/oaSystem/projectManagement/projectDetail.vue b/src/views/oaSystem/projectManagement/projectDetail.vue
deleted file mode 100644
index c3b0779..0000000
--- a/src/views/oaSystem/projectManagement/projectDetail.vue
+++ /dev/null
@@ -1,565 +0,0 @@
-// ... existing code ...
-<template>
- <div class="app-container">
- <!-- 椤圭洰鍩烘湰淇℃伅 -->
- <el-card class="mb20">
- <template #header>
- <div class="card-header">
- <span>椤圭洰鍩烘湰淇℃伅</span>
- </div>
- </template>
- <el-descriptions :column="2" border>
- <el-descriptions-item label="椤圭洰鍚嶇О">{{ projectInfo.projectName }}</el-descriptions-item>
- <el-descriptions-item label="椤圭洰璐熻矗浜�">{{ projectInfo.managerName }}</el-descriptions-item>
- <el-descriptions-item label="寮�濮嬫棩鏈�">{{ projectInfo.startDate }}</el-descriptions-item>
- <el-descriptions-item label="缁撴潫鏃ユ湡">{{ projectInfo.endDate }}</el-descriptions-item>
- <el-descriptions-item label="椤圭洰鐘舵��">
- <el-tag :type="getStatusType(projectInfo.status)">{{ getStatusText(projectInfo.status) }}</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="瀹屾垚搴�">
- <el-progress :percentage="projectInfo.completionRate" :stroke-width="6" />
- </el-descriptions-item>
- <el-descriptions-item label="椤圭洰鎻忚堪" :span="2">{{ projectInfo.description || '-' }}</el-descriptions-item>
- </el-descriptions>
- </el-card>
-
- <!-- 椤圭洰杩涘害姒傝 -->
- <el-card class="mb20">
- <template #header>
- <div class="card-header">
- <span>椤圭洰杩涘害姒傝</span>
- </div>
- </template>
- <el-row :gutter="20">
- <el-col :span="6">
- <div class="progress-item">
- <div class="progress-title">鎬讳綋杩涘害</div>
- <div class="progress-number">{{ projectInfo.completionRate }}%</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="progress-item">
- <div class="progress-title">闃舵鎬绘暟</div>
- <div class="progress-number">{{ statistics.totalPhases }}</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="progress-item">
- <div class="progress-title">浠诲姟鎬绘暟</div>
- <div class="progress-number">{{ statistics.totalTasks }}</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="progress-item">
- <div class="progress-title">宸插畬鎴愪换鍔�</div>
- <div class="progress-number">{{ statistics.completedTasks }}</div>
- </div>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 闃舵鍜屼换鍔$鐞� -->
- <!-- <el-card class="mb20">
- <template #header>
- <div class="card-header">
- <span>椤圭洰浠诲姟缁撴瀯</span>
- <el-button type="primary" size="small" @click="handleAddPhase">娣诲姞闃舵</el-button>
- </div>
- </template>
- <task-tree :project-id="projectId" @refresh="getProjectDetail" />
- </el-card> -->
-
- <!-- 閲岀▼纰戠鐞� -->
- <el-card class="mb20">
- <template #header>
- <div class="card-header">
- <span>椤圭洰闃舵閲岀▼纰�</span>
- <el-button type="primary" size="small" @click="handleAddMilestone">娣诲姞閲岀▼纰�</el-button>
- </div>
- </template>
- <milestone-list :project-id="projectId" @refresh="getProjectDetail" :key="`milestone-${refreshProjectId}`"/>
- </el-card>
-
- <!-- 闃舵鐩爣绠$悊 -->
- <el-card>
- <template #header>
- <div class="card-header">
- <span>闃舵浠诲姟</span>
- <el-button type="primary" size="small" @click="handleAddPhaseGoal">娣诲姞闃舵鐩爣</el-button>
- </div>
- </template>
- <phase-goal-list :project-id="projectId" @refresh="getProjectDetail" @editGoal="handleEditPhaseGoal" :key="`phaseGoal-${refreshProjectId}`"/>
- </el-card>
-
- <!-- 閲岀▼纰戠鐞嗗脊妗� -->
- <el-dialog :title="title" v-model="open" width="600px" append-to-body>
- <el-form :model="form" ref="formRef" label-width="100px">
- <el-form-item label="椤圭洰闃舵鍚嶇О" prop="phaseName">
- <el-input
- v-model="form.phaseName"
- placeholder="璇疯緭鍏ラ」鐩樁娈靛悕绉�"
- maxlength="50"
- />
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
- <el-date-picker
- v-model="form.startDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨寮�濮嬫棩鏈�"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="form.endDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨缁撴潫鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="鐘舵��" prop="status">
- <el-radio-group v-model="form.status">
- <el-radio label="notStarted">鏈紑濮�</el-radio>
- <el-radio label="completed">宸插畬鎴�</el-radio>
- <el-radio label="delayed">宸插欢杩�</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancel">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 闃舵浠诲姟绠$悊寮规 -->
- <el-dialog :title="goalTitle" v-model="goalOpen" width="600px" append-to-body>
- <el-form :model="goalForm" ref="goalFormRef" label-width="100px">
- <el-form-item label="鎵�灞為樁娈�" prop="phaseId">
- <el-select v-model="goalForm.phaseId" placeholder="璇烽�夋嫨鎵�灞為樁娈�">
- <el-option
- v-for="phase in phaseList"
- :key="phase.phaseId"
- :label="phase.phaseName"
- :value="phase.phaseId"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鐩爣鍚嶇О" prop="taskName">
- <el-input
- v-model="goalForm.taskName"
- placeholder="璇疯緭鍏ョ洰鏍囧悕绉�"
- maxlength="50"
- />
- </el-form-item>
- <el-form-item label="鐩爣鍊�" prop="targetValue">
- <el-input-number
- v-model="goalForm.targetValue"
- :min="0"
- :precision="2"
- placeholder="璇疯緭鍏ョ洰鏍囧��"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="褰撳墠鍊�" prop="currentValue">
- <el-input-number
- v-model="goalForm.currentValue"
- :min="0"
- :precision="2"
- placeholder="璇疯緭鍏ュ綋鍓嶅��"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="鍗曚綅" prop="unit">
- <el-input
- v-model="goalForm.unit"
- placeholder="璇疯緭鍏ュ崟浣�"
- maxlength="10"
- />
- </el-form-item>
- <el-form-item label="浠诲姟瀹屾垚鏃ユ湡" prop="targetDate">
- <el-date-picker
- v-model="goalForm.targetDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨鐩爣鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
- <el-date-picker
- v-model="goalForm.startDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨鐩爣鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="goalForm.endDate"
- type="date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- placeholder="閫夋嫨鐩爣鏃ユ湡"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="goalForm.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="鏈紑濮�" value="notStarted" />
- <el-option label="杩涜涓�" value="inProgress" />
- <el-option label="宸插畬鎴�" value="completed" />
- <el-option label="宸插欢杩�" value="delayed" />
- </el-select>
- </el-form-item>
- <!-- <el-form-item label="瀹屾垚搴�" prop="completionRate">
- <el-input-number
- v-model="goalForm.completionRate"
- :min="0"
- :max="100"
- :precision="2"
- placeholder="璇疯緭鍏ュ畬鎴愬害"
- style="width: 100%"
- />
- </el-form-item> -->
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="cancelGoal">鍙栨秷</el-button>
- <el-button type="primary" @click="submitGoalForm">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, watch } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { ElMessage } from 'element-plus';
-import TaskTree from './components/taskTree.vue';
-import MilestoneList from './components/milestoneList.vue';
-import ProjectForm from './components/projectForm.vue';
-import PhaseGoalList from './components/phaseGoalList.vue';
-import { getProject, addProjectPhase, listProjectPhase, addProjectTask, updateProjectTask } from '@/api/oaSystem/projectManagement';
-
-const route = useRoute();
-const router = useRouter();
-const open = ref(false);
-const title = ref('');
-const projectFormRef = ref();
-const formRef = ref();
-// 椤圭洰ID
-// 鍦ㄥ叾浠杛ef瀹氫箟闄勮繎娣诲姞
-const refreshProjectId = ref(0);
-
-const projectId = ref(route.params.projectId);
-
-// 椤圭洰淇℃伅
-const projectInfo = reactive({
- projectId: '',
- projectName: '',
- description: '',
- startDate: '',
- endDate: '',
- managerId: '',
- managerName: '',
- status: 'planning',
- completionRate: 0
-});
-
-// 缁熻淇℃伅
-const statistics = reactive({
- totalPhases: 0,
- totalTasks: 0,
- completedTasks: 0
-});
-const form = reactive({
- phaseId: '',
- phaseName: '',
- startDate: '',
- endDate: '',
- status: 'planning',
- oaProjectId: projectId.value,
-})
-
-// 闃舵鐩爣鐩稿叧
-const goalOpen = ref(false);
-const goalTitle = ref('');
-const goalFormRef = ref();
-const phaseList = ref([]);
-const goalForm = reactive({
- taskId: '',
- phaseId: '',
- taskName: '',
- targetValue: 100,
- currentValue: 0,
- unit: '%',
- targetDate: '',
- startDate: '',
- endDate: '',
- status: 'notStarted',
- completionRate: 0
-});
-
-// 鑾峰彇椤圭洰璇︽儏
-const getProjectDetail = async () => {
- try {
- getProject().then((res)=>{
- console.log("椤圭洰璇︽儏",res)
- const projectData = res.data[projectId.value];
- // 鏇存柊椤圭洰淇℃伅
- Object.assign(projectInfo, projectData);
-
- // 鏇存柊缁熻淇℃伅
- updateStatistics(projectData);
-
- // 寮哄埗鏇存柊DOM浠ョ‘淇濆瓙缁勪欢鑳芥纭埛鏂�
- // 杩欓噷閫氳繃瑙﹀彂refreshProjectId浜嬩欢鏉ュ己鍒跺埛鏂板瓙缁勪欢
- refreshProjectId.value++;
- })
- } catch (error) {
- ElMessage.error('鑾峰彇椤圭洰璇︽儏澶辫触');
- console.error('鑾峰彇椤圭洰璇︽儏澶辫触:', error);
- }
-};
-
-// 鏇存柊缁熻淇℃伅
-const updateStatistics = (projectData) => {
- // 杩欓噷鍋囪projectData涓寘鍚簡缁熻淇℃伅
- // 濡傛灉娌℃湁锛岄渶瑕佸崟鐙姹傜粺璁℃暟鎹�
- statistics.totalPhases = projectData.phases ? projectData.phases.length : 0;
- statistics.totalTasks = projectData.tasks ? projectData.tasks.length : 0;
- statistics.completedTasks = projectData.tasks ?
- projectData.tasks.filter(task => task.status === 'completed').length : 0;
-};
-
-// 鑾峰彇椤圭洰闃舵鍒楄〃
-const getPhaseList = async () => {
- try {
- const { data } = await listProjectPhase(projectId.value);
- phaseList.value = data.rows || data;
- } catch (error) {
- ElMessage.error('鑾峰彇椤圭洰闃舵鍒楄〃澶辫触');
- console.error('鑾峰彇椤圭洰闃舵鍒楄〃澶辫触:', error);
- }
-};
-
-// 璁$畻瀹屾垚搴�
-const calculateCompletionRate = () => {
- if (goalForm.targetValue > 0) {
- goalForm.completionRate = Math.min(Math.round((goalForm.currentValue / goalForm.targetValue) * 100), 100);
- } else {
- goalForm.completionRate = 0;
- }
-};
-
-// 娣诲姞闃舵
-const handleAddPhase = () => {
- // resetForm();
- ElMessage.info('娣诲姞闃舵鍔熻兘寰呭疄鐜�');
-};
-
-// 娣诲姞閲岀▼纰�
-const handleAddMilestone = () => {
- resetForm();
- open.value = true;
- title.value = '鏂板椤圭洰闃舵';
-};
-
-// 娣诲姞闃舵浠诲姟
-const handleAddPhaseGoal = () => {
- goalForm.taskId = '';
- goalForm.phaseId = '';
- goalForm.taskName = '';
- goalForm.targetValue = 0;
- goalForm.currentValue = 0;
- goalForm.unit = '%';
- goalForm.targetDate = '';
- goalForm.startDate = '';
- goalForm.endDate = '';
- goalForm.status = 'notStarted';
- goalForm.completionRate = 0;
- if (goalFormRef.value) {
- goalFormRef.value.resetFields();
- }
- getPhaseList();
- goalTitle.value = '鏂板闃舵鐩爣';
- goalOpen.value = true;
-};
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- await formRef.value.validate();
-
- if (form.phaseId) {
- // await updateProject(form);
- // ElMessage.success('淇敼椤圭洰闃舵鎴愬姛');
- } else {
- console.log("form",form);
- await addProjectPhase(form);
- ElMessage.success('鏂板椤圭洰闃舵鎴愬姛');
- getProjectDetail();
- }
- open.value = false;
- } catch (error) {
- console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
- }
-};
-
-// 鎻愪氦闃舵浠诲姟琛ㄥ崟
-const submitGoalForm = async () => {
- try {
- await goalFormRef.value.validate();
- calculateCompletionRate();
-
- const goalData = {
- ...goalForm,
- oaProjectId: projectId.value
- };
-
- if (goalForm.taskId) {
- await updateProjectTask(goalData);
- ElMessage.success('淇敼闃舵鐩爣鎴愬姛');
-
- } else {
- await addProjectTask(goalData);
- ElMessage.success('鏂板闃舵鐩爣鎴愬姛');
-
- }
- // 璋冪敤getProjectDetail鍒锋柊鎵�鏈夌浉鍏虫暟鎹�
- getProjectDetail();
- goalOpen.value = false;
-
- } catch (error) {
- console.error('鎻愪氦闃舵鐩爣琛ㄥ崟澶辫触:', error);
- }
-};
-
-// 閲嶇疆閲岀▼纰戣〃鍗�
-const resetForm = () => {
- form.phaseId = '';
- form.phaseName = '';
- form.startDate = '';
- form.endDate = '';
- form.status = 'planning';
- form.oaProjectId = projectId.value;
- if (formRef.value) {
- formRef.value.resetFields();
- }
-};
-
-// 鍙栨秷闃舵浠诲姟鎿嶄綔
-const cancelGoal = () => {
- goalOpen.value = false;
-};
-
-// 鍙栨秷鎿嶄綔
-const cancel = () => {
- open.value = false;
-};
-// 缂栬緫闃舵浠诲姟
-const handleEditPhaseGoal = async (goal) => {
- // 澶嶅埗鐩爣鏁版嵁鍒拌〃鍗�
- Object.assign(goalForm, goal);
-
- // 鑾峰彇椤圭洰闃舵鍒楄〃
- await getPhaseList();
-
- // 鎵撳紑缂栬緫寮圭獥
- goalTitle.value = '缂栬緫闃舵鐩爣';
- goalOpen.value = true;
-};
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusType = (status) => {
- const statusTypeMap = {
- planning: 'info',
- inProgress: 'primary',
- completed: 'success',
- paused: 'warning'
- };
- return statusTypeMap[status] || 'default';
-};
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- const statusTextMap = {
- planning: '瑙勫垝涓�',
- inProgress: '杩涜涓�',
- completed: '宸插畬鎴�',
- paused: '宸叉殏鍋�'
- };
- return statusTextMap[status] || status;
-};
-
-// 鐩戝惉璺敱鍙傛暟鍙樺寲
-watch(() => route.params.projectId, (newProjectId) => {
- // console.log('璺敱鍙傛暟鍙樺寲:', projectId);
- if (newProjectId) {
- projectId.value = newProjectId;
- getProjectDetail();
- }
-});
-
-// 鐩戝惉褰撳墠鍊煎拰鐩爣鍊煎彉鍖栵紝閲嶆柊璁$畻瀹屾垚搴�
-watch(() => [goalForm.currentValue, goalForm.targetValue], () => {
- calculateCompletionRate();
-});
-
-// 鍒濆鍖�
-onMounted(() => {
- if (projectId.value) {
- getProjectDetail();
- }
-});
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.progress-item {
- text-align: center;
- padding: 20px;
- background-color: #f5f7fa;
- border-radius: 8px;
-}
-
-.progress-title {
- font-size: 14px;
- color: #606266;
- margin-bottom: 10px;
-}
-
-.progress-number {
- font-size: 24px;
- font-weight: bold;
- color: #409eff;
-}
-
-.mb20 {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/personnelManagement/analytics/index.vue b/src/views/personnelManagement/analytics/index.vue
deleted file mode 100644
index 2bca335..0000000
--- a/src/views/personnelManagement/analytics/index.vue
+++ /dev/null
@@ -1,710 +0,0 @@
-<template>
- <div class="app-container analytics-container">
-
- <!-- 鍏抽敭鎸囨爣鍗$墖 -->
- <el-row :gutter="20" class="metrics-cards">
- <el-col :span="6" v-for="(item, index) in keyMetrics" :key="index">
- <el-card class="metric-card" :class="item.type">
- <div class="card-content">
- <div class="card-icon">
- <el-icon :size="32">
- <component :is="item.icon" />
- </el-icon>
- </div>
- <div class="card-info">
- <div class="card-number">
- <el-skeleton-item v-if="loading" variant="text" style="width: 60px; height: 32px;" />
- <span v-else>{{ item.value }}{{ item.unit }}</span>
- </div>
- <div class="card-label">{{ item.label }}</div>
- <div class="card-trend" :class="item.trend > 0 ? 'positive' : 'negative'" v-if="item.showTrend !== false">
- <el-icon>
- <component :is="item.trend > 0 ? 'ArrowUp' : 'ArrowDown'" />
- </el-icon>
- {{ Math.abs(item.trend) }}%
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 鍥捐〃鍖哄煙 -->
- <el-row :gutter="20" class="charts-section">
- <!-- 鍛樺伐娴佸姩鐜囪秼鍔垮浘 -->
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>鍛樺伐娴佸姩鐜囪秼鍔�</span>
- <el-tag type="info">杩�12涓湀</el-tag>
- </div>
- </template>
- <div class="chart-container">
- <div ref="turnoverChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
-
- <!-- 閮ㄩ棬浜哄憳鍒嗗竷 -->
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>閮ㄩ棬浜哄憳鍒嗗竷</span>
- <el-tag type="success">褰撳墠鐘舵��</el-tag>
- </div>
- </template>
- <div class="chart-container">
- <div ref="departmentChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 绗簩琛屽浘琛� -->
- <el-row :gutter="20" class="charts-section">
- <!-- 缂栧埗杈炬垚鐜� -->
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>缂栧埗杈炬垚鐜�</span>
- <el-tag type="warning">鍚勯儴闂ㄥ姣�</el-tag>
- </div>
- </template>
- <div class="chart-container">
- <div ref="staffingChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
-
- <!-- 鍛樺伐娴佸け鍘熷洜鍒嗘瀽 -->
- <el-col :span="12">
- <el-card class="chart-card">
- <template #header>
- <div class="card-header">
- <span>鍛樺伐娴佸け鍘熷洜鍒嗘瀽</span>
- <el-tag type="danger">骞村害缁熻</el-tag>
- </div>
- </template>
- <div class="chart-container">
- <div ref="attritionChartRef" class="chart"></div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { ElMessage } from 'element-plus'
-import {
- Refresh,
- User,
- TrendCharts,
- DataAnalysis,
- PieChart,
- ArrowUp,
- ArrowDown
-} from '@element-plus/icons-vue'
-import * as echarts from 'echarts'
-import { staffOnJobListPage } from '@/api/personnelManagement/employeeRecord.js'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const autoRefreshEnabled = ref(true)
-const autoRefreshInterval = ref(null)
-
-// 鍥捐〃寮曠敤
-const turnoverChartRef = ref(null)
-const departmentChartRef = ref(null)
-const staffingChartRef = ref(null)
-const attritionChartRef = ref(null)
-
-// 鍥捐〃瀹炰緥
-let turnoverChart = null
-let departmentChart = null
-let staffingChart = null
-let attritionChart = null
-
-// 鑷姩鏇存柊闂撮殧锛�10鍒嗛挓锛�
-const AUTO_REFRESH_INTERVAL = 10 * 60 * 1000
-
-// 鍏抽敭鎸囨爣鏁版嵁
-const keyMetrics = ref([
- {
- label: '鍛樺伐娴佸姩鐜�',
- value: 0,
- unit: '%',
- icon: 'TrendCharts',
- type: 'primary',
- trend: 0
- },
- {
- label: '鍛樺伐娴佸け鐜�',
- value: 0,
- unit: '%',
- icon: 'User',
- type: 'danger',
- trend: 0
- },
- {
- label: '缂栧埗杈炬垚鐜�',
- value: 0,
- unit: '%',
- icon: 'DataAnalysis',
- type: 'success',
- trend: 0
- },
- {
- label: '鍦ㄨ亴鍛樺伐鏁�',
- value: 0,
- unit: '浜�',
- icon: 'PieChart',
- type: 'warning',
- trend: 0,
- showTrend: false
- }
-])
-
-// 閮ㄩ棬鏁版嵁
-const departmentData = ref([])
-
-// 鑾峰彇鍦ㄨ亴鍛樺伐鏁�
-const getStaffCount = async () => {
- try {
- const res = await staffOnJobListPage({ staffState: 1, current: 1, size: 1 })
- if (res && res.data) {
- keyMetrics.value[3].value = res.data.total || 0
- }
- } catch (error) {
- console.error('鑾峰彇鍦ㄨ亴鍛樺伐鏁板け璐�:', error)
- }
-}
-
-// 鍚姩鑷姩鍒锋柊
-const startAutoRefresh = () => {
- if (autoRefreshInterval.value) {
- clearInterval(autoRefreshInterval.value)
- }
- if (autoRefreshEnabled.value) {
- autoRefreshInterval.value = setInterval(() => {
- refreshData()
- }, AUTO_REFRESH_INTERVAL)
- }
-}
-
-// 鍋滄鑷姩鍒锋柊
-const stopAutoRefresh = () => {
- if (autoRefreshInterval.value) {
- clearInterval(autoRefreshInterval.value)
- autoRefreshInterval.value = null
- }
-}
-
-// 鍒囨崲鑷姩鍒锋柊鐘舵��
-const toggleAutoRefresh = (value) => {
- if (value) {
- startAutoRefresh()
- } else {
- stopAutoRefresh()
- }
-}
-
-// 鐢熸垚妯℃嫙鏁版嵁
-const generateMockData = () => {
- // 鐢熸垚鍏抽敭鎸囨爣鏁版嵁
- keyMetrics.value[0].value = (Math.random() * 5 + 2).toFixed(1)
- keyMetrics.value[0].trend = (Math.random() * 3 - 1.5).toFixed(1)
-
- keyMetrics.value[1].value = (Math.random() * 3 + 1).toFixed(1)
- keyMetrics.value[1].trend = (Math.random() * 2 - 1).toFixed(1)
-
- keyMetrics.value[2].value = (Math.random() * 15 + 85).toFixed(1)
- keyMetrics.value[2].trend = (Math.random() * 3 - 1.5).toFixed(1)
-
- // 鐢熸垚閮ㄩ棬鏁版嵁
- const departments = ['鎶�鏈儴', '閿�鍞儴', '浜轰簨閮�', '璐㈠姟閮�', '鐢熶骇閮�', '甯傚満閮�']
- departmentData.value = departments.map(dept => ({
- department: dept,
- currentStaff: Math.floor(Math.random() * 30 + 20),
- plannedStaff: Math.floor(Math.random() * 10 + 35),
- staffingRate: Math.floor(Math.random() * 20 + 80),
- turnoverRate: (Math.random() * 4 + 1).toFixed(1),
- attritionRate: (Math.random() * 2 + 0.5).toFixed(1),
- newHires: Math.floor(Math.random() * 5 + 1),
- resignations: Math.floor(Math.random() * 3 + 1),
- status: Math.random() > 0.7 ? '寮傚父' : '姝e父'
- }))
-}
-
-// 鍒锋柊鏁版嵁
-const refreshData = async () => {
- loading.value = true
- try {
- // 妯℃嫙API璋冪敤寤惰繜
- await new Promise(resolve => setTimeout(resolve, 500))
-
- generateMockData()
- renderAllCharts()
-
- if (!autoRefreshEnabled.value) {
- ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
- }
- } catch (error) {
- console.error('鍒锋柊鏁版嵁澶辫触:', error)
- ElMessage.error('鍒锋柊鏁版嵁澶辫触')
- } finally {
- loading.value = false
- }
-}
-
-// 鍒濆鍖栧浘琛�
-const initCharts = () => {
- setTimeout(() => {
- if (turnoverChartRef.value) {
- turnoverChart = echarts.init(turnoverChartRef.value)
- }
- if (departmentChartRef.value) {
- departmentChart = echarts.init(departmentChartRef.value)
- }
- if (staffingChartRef.value) {
- staffingChart = echarts.init(staffingChartRef.value)
- }
- if (attritionChartRef.value) {
- attritionChart = echarts.init(attritionChartRef.value)
- }
-
- renderAllCharts()
- }, 300)
-}
-
-// 娓叉煋鎵�鏈夊浘琛�
-const renderAllCharts = () => {
- renderTurnoverChart()
- renderDepartmentChart()
- renderStaffingChart()
- renderAttritionChart()
-}
-
-// 娓叉煋鍛樺伐娴佸姩鐜囪秼鍔垮浘
-const renderTurnoverChart = () => {
- if (!turnoverChart) return
-
- const months = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
- const turnoverData = months.map(() => (Math.random() * 5 + 2).toFixed(1))
- const attritionData = months.map(() => (Math.random() * 3 + 1).toFixed(1))
-
- const option = {
- title: {
- text: '鍛樺伐娴佸姩鐜囪秼鍔�',
- left: 'center',
- textStyle: { fontSize: 16, fontWeight: 'normal' }
- },
- tooltip: {
- trigger: 'axis',
- axisPointer: { type: 'cross' }
- },
- legend: {
- data: ['娴佸姩鐜�', '娴佸け鐜�'],
- bottom: 10
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '15%',
- top: '15%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- data: months,
- boundaryGap: false
- },
- yAxis: {
- type: 'value',
- axisLabel: { formatter: '{value}%' }
- },
- series: [
- {
- name: '娴佸姩鐜�',
- type: 'line',
- data: turnoverData,
- smooth: true,
- lineStyle: { color: '#409EFF' },
- itemStyle: { color: '#409EFF' }
- },
- {
- name: '娴佸け鐜�',
- type: 'line',
- data: attritionData,
- smooth: true,
- lineStyle: { color: '#F56C6C' },
- itemStyle: { color: '#F56C6C' }
- }
- ]
- }
-
- turnoverChart.setOption(option)
-}
-
-// 娓叉煋閮ㄩ棬浜哄憳鍒嗗竷鍥�
-const renderDepartmentChart = () => {
- if (!departmentChart) return
-
- const data = departmentData.value.map(item => ({
- name: item.department,
- value: item.currentStaff
- }))
-
- const option = {
- title: {
- text: '閮ㄩ棬浜哄憳鍒嗗竷',
- left: 'center',
- textStyle: { fontSize: 16, fontWeight: 'normal' }
- },
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}: {c}浜� ({d}%)'
- },
- legend: {
- orient: 'vertical',
- left: 'left',
- top: 'middle'
- },
- series: [
- {
- name: '浜哄憳鏁伴噺',
- type: 'pie',
- radius: ['40%', '70%'],
- center: ['60%', '50%'],
- data: data,
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- }
-
- departmentChart.setOption(option)
-}
-
-// 娓叉煋缂栧埗杈炬垚鐜囧浘
-const renderStaffingChart = () => {
- if (!staffingChart) return
-
- const departments = departmentData.value.map(item => item.department)
- const rates = departmentData.value.map(item => item.staffingRate)
-
- const option = {
- title: {
- text: '缂栧埗杈炬垚鐜�',
- left: 'center',
- textStyle: { fontSize: 16, fontWeight: 'normal' }
- },
- tooltip: {
- trigger: 'axis',
- axisPointer: { type: 'shadow' }
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '15%',
- top: '15%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- data: departments,
- axisLabel: { rotate: 45 }
- },
- yAxis: {
- type: 'value',
- axisLabel: { formatter: '{value}%' },
- max: 100
- },
- series: [
- {
- name: '杈炬垚鐜�',
- type: 'bar',
- data: rates,
- itemStyle: {
- color: function(params) {
- const value = params.value
- if (value >= 90) return '#67C23A'
- if (value >= 80) return '#E6A23C'
- return '#F56C6C'
- }
- }
- }
- ]
- }
-
- staffingChart.setOption(option)
-}
-
-// 娓叉煋鍛樺伐娴佸け鍘熷洜鍒嗘瀽鍥�
-const renderAttritionChart = () => {
- if (!attritionChart) return
-
- const reasons = ['钖祫寰呴亣', '鑱屼笟鍙戝睍', '宸ヤ綔鐜', '涓汉鍘熷洜', '鍏朵粬']
- const data = reasons.map(() => Math.floor(Math.random() * 20 + 5))
-
- const option = {
- title: {
- text: '鍛樺伐娴佸け鍘熷洜鍒嗘瀽',
- left: 'center',
- textStyle: { fontSize: 16, fontWeight: 'normal' }
- },
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}: {c}浜� ({d}%)'
- },
- legend: {
- orient: 'vertical',
- left: 'left',
- top: 'middle'
- },
- series: [
- {
- name: '娴佸け浜烘暟',
- type: 'pie',
- radius: '50%',
- center: ['60%', '50%'],
- data: reasons.map((reason, index) => ({
- name: reason,
- value: data[index]
- })),
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- }
-
- attritionChart.setOption(option)
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- generateMockData()
- getStaffCount()
- initCharts()
- startAutoRefresh()
-})
-
-onUnmounted(() => {
- stopAutoRefresh()
-})
-</script>
-
-<style scoped>
-.analytics-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- color: white;
-}
-
-.page-header h2 {
- color: white;
- margin-bottom: 10px;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- color: rgba(255, 255, 255, 0.9);
- font-size: 14px;
- margin: 0 0 15px 0;
-}
-
-.header-controls {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 20px;
-}
-
-.refresh-btn {
- margin-left: 20px;
-}
-
-.metrics-cards {
- margin-bottom: 30px;
-}
-
-.metric-card {
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
- border: none;
- overflow: hidden;
-}
-
-.metric-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
-}
-
-.metric-card.primary {
- border-left: 4px solid #409EFF;
- background: linear-gradient(135deg, #409EFF 0%, #36a3f7 100%);
-}
-
-.metric-card.danger {
- border-left: 4px solid #F56C6C;
- background: linear-gradient(135deg, #F56C6C 0%, #f78989 100%);
-}
-
-.metric-card.success {
- border-left: 4px solid #67C23A;
- background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
-}
-
-.metric-card.warning {
- border-left: 4px solid #E6A23C;
- background: linear-gradient(135deg, #E6A23C 0%, #ebb563 100%);
-}
-
-.card-content {
- display: flex;
- align-items: center;
- padding: 20px;
-}
-
-.card-icon {
- margin-right: 20px;
- color: white;
-}
-
-.card-info {
- flex: 1;
-}
-
-.card-number {
- font-size: 32px;
- font-weight: 600;
- color: white;
- margin-bottom: 5px;
-}
-
-.card-label {
- font-size: 14px;
- color: rgba(255, 255, 255, 0.9);
- margin-bottom: 5px;
-}
-
-.card-trend {
- font-size: 12px;
- display: flex;
- align-items: center;
- gap: 4px;
-}
-
-.card-trend.positive {
- color: #67C23A;
-}
-
-.card-trend.negative {
- color: #F56C6C;
-}
-
-.charts-section {
- margin-bottom: 30px;
-}
-
-.chart-card {
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- border: none;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: 600;
- color: #303133;
- padding: 15px 20px;
- border-bottom: 1px solid #ebeef5;
-}
-
-.chart-container {
- height: 350px;
- padding: 20px;
-}
-
-.chart {
- width: 100%;
- height: 100%;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .analytics-container {
- padding: 10px;
- }
-
- .page-header {
- padding: 15px;
- }
-
- .page-header h2 {
- font-size: 24px;
- }
-
- .header-controls {
- flex-direction: column;
- gap: 15px;
- }
-
- .refresh-btn {
- margin-left: 0;
- }
-
- .metrics-cards .el-col {
- margin-bottom: 15px;
- }
-
- .charts-section .el-col {
- margin-bottom: 20px;
- }
-
- .chart-container {
- height: 300px;
- }
-}
-
-@media (max-width: 480px) {
- .page-header h2 {
- font-size: 20px;
- }
-
- .card-number {
- font-size: 24px;
- }
-
- .chart-container {
- height: 250px;
- }
-}
-</style>
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
deleted file mode 100644
index 3c9674c..0000000
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="璇︽儏"
- width="70%"
- @close="closeDia"
- >
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- height="600"
- ></PIMTable>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const tableColumn = ref([
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- label: "鍚堝悓寮�濮嬫棩鏈�",
- prop: "contractStartTime",
- },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractEndTime",
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- staffOnJobInfo({staffNo: row.staffNo}).then(res => {
- tableData.value = res.data
- })
- }
-}
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
deleted file mode 100644
index f752496..0000000
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ /dev/null
@@ -1,202 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="涓婁紶闄勪欢"
- width="50%"
- @close="closeDia"
- >
- <div style="margin-bottom: 10px;text-align: right">
- <el-upload
- v-model:file-list="fileList"
- class="upload-demo"
- :action="uploadUrl"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: inline;margin-right: 10px"
- >
- <el-button type="primary">涓婁紶闄勪欢</el-button>
- </el-upload>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- height="500"
- >
- </PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
- fileAdd,
- fileDel,
- fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
- {
- label: "鏂囦欢鍚嶇О",
- prop: "name",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "涓嬭浇",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- {
- name: "棰勮",
- type: "text",
- clickFun: (row) => {
- lookFile(row);
- },
- }
- ],
- },
-]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
- Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
- accountType.value = type;
- dialogFormVisible.value = true;
- currentId.value = row.id;
- getList()
-}
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
- tableData.value = res.data.records;
- total.value = res.data.total;
- })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
- // 濡傛灉涓婁紶鎴愬姛
- if (res.code == 200) {
- const fileRow = {}
- fileRow.name = res.data.originalName
- fileRow.url = res.data.tempPath
- uploadFile(fileRow)
- } else {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
-}
-function uploadFile(file) {
- file.accountId = currentId.value;
- file.accountType = accountType.value;
- fileAdd(file).then(res => {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- getList()
- })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-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(() => {
- fileDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
deleted file mode 100644
index 9fcd73a..0000000
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ /dev/null
@@ -1,321 +0,0 @@
-<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.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- <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 type="info" @click="handleImport">瀵煎叆</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>
-
- <!-- 鍚堝悓瀵煎叆瀵硅瘽妗� -->
- <el-dialog
- :title="upload.title"
- v-model="upload.open"
- width="400px"
- append-to-body
- >
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :headers="upload.headers"
- :action="upload.url + '?updateSupport=' + upload.updateSupport"
- :disabled="upload.isUploading"
- :on-progress="handleFileUploadProgress"
- :on-success="handleFileSuccess"
- :auto-upload="false"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
- <!-- <el-link
- type="primary"
- :underline="false"
- style="font-size: 12px; vertical-align: baseline"
- @click="importTemplate"
- >涓嬭浇妯℃澘</el-link
- > -->
- </div>
- </template>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
- <files-dia ref="filesDia"></files-dia>
- </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref } from "vue";
-import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
-import { ElMessageBox } from "element-plus";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
-import dayjs from "dayjs";
-import { getToken } from "@/utils/auth.js";
-import FilesDia from "./filesDia.vue";
-const data = reactive({
- searchForm: {
- staffName: "",
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
-});
-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: "age",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "phone",
- width: 150
- },
- {
- label: "绱ф�ヨ仈绯讳汉",
- prop: "emergencyContact",
- width: 120
- },
- {
- label: "绱ф�ヨ仈绯讳汉鐢佃瘽",
- prop: "emergencyContactPhone",
- width: 150
- },
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- // {
- // label: "鍚堝悓寮�濮嬫棩鏈�",
- // prop: "contractStartTime",
- // width: 120
- // },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractExpireTime",
- width: 120
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- fixed: 'right',
- width: 120,
- operation: [
- {
- name: "璇︽儏",
- type: "text",
- clickFun: (row) => {
- openForm("edit", row);
- },
- },
- {
- name: "闄勪欢",
- type: "text",
- clickFun: (row) => {
- openFilesFormDia(row);
- },
- },
- ],
- },
-]);
-const filesDia = ref()
-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 changeDaterange = (value) => {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- if (value) {
- searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- }
- getList();
-};
-// 鎵撳紑闄勪欢寮规
-const openFilesFormDia = (row) => {
- console.log(row)
- nextTick(() => {
- filesDia.value?.openDialog( row,'鍚堝悓')
- })
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- staffOnJobListPage(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙鍚堝悓瀵煎叆锛�
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙鍚堝悓瀵煎叆锛�
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
- updateSupport: 1,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import",
-});
-/** 瀵煎叆鎸夐挳鎿嶄綔 */
-function handleImport() {
- upload.title = "鍚堝悓瀵煎叆";
- upload.open = true;
-}
-/** 鎻愪氦涓婁紶鏂囦欢 */
-function submitFileForm() {
- console.log(upload.url + '?updateSupport=' + upload.updateSupport)
- proxy.$refs["uploadRef"].submit();
-}
-/**鏂囦欢涓婁紶涓鐞� */
-const handleFileUploadProgress = (event, file, fileList) => {
- upload.isUploading = true;
-};
-/** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
-const handleFileSuccess = (response, file, fileList) => {
- upload.open = false;
- upload.isUploading = false;
- proxy.$refs["uploadRef"].handleRemove(file);
- getList();
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
deleted file mode 100644
index d77eb90..0000000
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ /dev/null
@@ -1,354 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板绂昏亴' : '缂栬緫绂昏亴'"
- width="70%"
- @close="closeDia"
- >
- <!-- 鍛樺伐淇℃伅灞曠ず鍖哄煙 -->
- <div class="info-section">
- <div class="info-title">鍛樺伐淇℃伅</div>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">濮撳悕锛�</span>
- <el-select v-model="form.staffName" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">
- <el-option
- v-for="item in personList"
- :key="item.id"
- :label="item.staffName"
- :value="item.staffName"
- />
- </el-select>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鍛樺伐缂栧彿锛�</span>
- <span class="info-value">{{ form.staffNo || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鎬у埆锛�</span>
- <span class="info-value">{{ form.sex || '-' }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鎴风睄浣忓潃锛�</span>
- <span class="info-value">{{ form.nativePlace || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">宀椾綅锛�</span>
- <span class="info-value">{{ form.postJob || '-' }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鐜颁綇鍧�锛�</span>
- <span class="info-value">{{ form.adress || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">绗竴瀛﹀巻锛�</span>
- <span class="info-value">{{ form.firstStudy || '-' }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">涓撲笟锛�</span>
- <span class="info-value">{{ form.profession || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">骞撮緞锛�</span>
- <span class="info-value">{{ form.age || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鑱旂郴鐢佃瘽锛�</span>
- <span class="info-value">{{ form.phone || '-' }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">绱ф�ヨ仈绯讳汉锛�</span>
- <span class="info-value">{{ form.emergencyContact || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�</span>
- <span class="info-value">{{ form.emergencyContactPhone || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鍚堝悓寮�濮嬫棩鏈燂細</span>
- <span class="info-value">{{ form.contractStartTime || '-' }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">鍚堝悓缁撴潫鏃ユ湡锛�</span>
- <span class="info-value">{{ form.contractEndTime || '-' }}</span>
- </div>
- </el-col>
- </el-row>
- </div>
-
- <!-- 绂昏亴淇℃伅濉啓鍖哄煙 -->
- <!-- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef" style="margin-top: 20px">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绂昏亴鏃ユ湡锛�" prop="dimissionDate">
- <el-date-picker
- v-model="form.dimissionDate"
- type="date"
- placeholder="璇烽�夋嫨绂昏亴鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绂昏亴鍘熷洜锛�" prop="dimissionReason">
- <el-input
- v-model="form.dimissionReason"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ョ鑱屽師鍥�"
- maxlength="500"
- show-word-limit
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- dimissionDate: "",
- dimissionReason: "",
- staffState: "",
- },
- rules: {
- staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳", trigger: "change" }],
- dimissionDate: [{ required: true, message: "璇烽�夋嫨绂昏亴鏃ユ湡", trigger: "change" }],
- dimissionReason: [{ required: true, message: "璇疯緭鍏ョ鑱屽師鍥�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- getList()
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- })
- }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- // 琛ㄥ崟宸叉敞閲婏紝鐩存帴鎻愪氦锛屼笉杩涜楠岃瘉
- if (!form.value.staffName) {
- proxy.$modal.msgError("璇烽�夋嫨浜哄憳");
- return;
- }
- form.value.staffState = 0
- if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- staffJoinUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
-}
-// 鍏抽棴寮规
-const closeDia = () => {
- // 琛ㄥ崟宸叉敞閲婏紝鎵嬪姩閲嶇疆琛ㄥ崟鏁版嵁
- form.value = {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- dimissionDate: "",
- dimissionReason: "",
- staffState: "",
- };
- dialogFormVisible.value = false;
- emit('close')
-};
-
-const personList = ref([]);
-
-/**
- * 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
- */
-const getList = () => {
- staffOnJobListPage({
- current: -1,
- size: -1,
- staffState: 1
- }).then(res => {
- personList.value = res.data.records || []
- })
-};
-
-const handleSelect = (val) => {
- let obj = personList.value.find(item => item.staffName === val)
- if (obj) {
- let {
- sex,
- phone,
- staffNo,
- nativePlace,
- postJob,
- adress,
- firstStudy,
- profession,
- age,
- emergencyContact,
- emergencyContactPhone,
- contractTerm,
- contractStartTime,
- contractEndTime,
- staffName
- } = obj
- // 淇濈暀绂昏亴鏃ユ湡鍜岀鑱屽師鍥狅紝鍙洿鏂板憳宸ヤ俊鎭�
- form.value = {
- ...form.value,
- sex,
- phone,
- staffNo,
- nativePlace,
- postJob,
- adress,
- firstStudy,
- profession,
- age,
- emergencyContact,
- emergencyContactPhone,
- contractTerm,
- contractStartTime,
- contractEndTime,
- staffName
- }
- }
-}
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-.info-section {
- background: #f5f7fa;
- padding: 20px;
- border-radius: 8px;
- margin-bottom: 20px;
-}
-
-.info-title {
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- margin-bottom: 20px;
- padding-bottom: 10px;
- border-bottom: 1px solid #e4e7ed;
-}
-
-.info-item {
- display: flex;
- align-items: center;
- margin-bottom: 16px;
- min-height: 32px;
-}
-
-.info-label {
- min-width: 140px;
- color: #606266;
- font-size: 14px;
- font-weight: 500;
-}
-
-.info-value {
- flex: 1;
- color: #303133;
- font-size: 14px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
deleted file mode 100644
index ae90d99..0000000
--- a/src/views/personnelManagement/dimission/index.vue
+++ /dev/null
@@ -1,279 +0,0 @@
-<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/dimission/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: "age",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "phone",
- width:150
- },
- {
- label: "绱ф�ヨ仈绯讳汉",
- prop: "emergencyContact",
- width: 120
- },
- {
- label: "绱ф�ヨ仈绯讳汉鐢佃瘽",
- prop: "emergencyContactPhone",
- width:150
- },
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- label: "鍚堝悓寮�濮嬫棩鏈�",
- prop: "contractStartTime",
- width: 120
- },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractEndTime",
- width: 120
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- 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: 0}).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-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: 0}, "浜哄憳绂昏亴.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/employeeRecord/components/formDia.vue b/src/views/personnelManagement/employeeRecord/components/formDia.vue
deleted file mode 100644
index 3c9674c..0000000
--- a/src/views/personnelManagement/employeeRecord/components/formDia.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="璇︽儏"
- width="70%"
- @close="closeDia"
- >
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- height="600"
- ></PIMTable>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const tableColumn = ref([
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- label: "鍚堝悓寮�濮嬫棩鏈�",
- prop: "contractStartTime",
- },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractEndTime",
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- staffOnJobInfo({staffNo: row.staffNo}).then(res => {
- tableData.value = res.data
- })
- }
-}
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
deleted file mode 100644
index 5a0d07c..0000000
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ /dev/null
@@ -1,241 +0,0 @@
-<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.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- <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/employeeRecord/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
-import dayjs from "dayjs";
-
-const data = reactive({
- searchForm: {
- staffName: "",
- entryDate: undefined, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
-});
-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: "age",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "phone",
- width:150
- },
- {
- label: "绱ф�ヨ仈绯讳汉",
- prop: "emergencyContact",
- width: 120
- },
- {
- label: "绱ф�ヨ仈绯讳汉鐢佃瘽",
- prop: "emergencyContactPhone",
- width:150
- },
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- // {
- // label: "鍚堝悓寮�濮嬫棩鏈�",
- // prop: "contractStartTime",
- // width: 120
- // },
- {
- label: "鍚堝悓缁撴潫鏃ユ湡",
- prop: "contractExpireTime",
- 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 changeDaterange = (value) => {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- if (value) {
- searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.value.entryDateEnd = dayjs(value[1]).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;
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- staffOnJobListPage({...params, staffState: 1}).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- nextTick(() => {
- formDia.value?.openDialog(type, row)
- })
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍦ㄨ亴鍛樺伐鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/onboarding/components/formDia.vue
deleted file mode 100644
index a13d6ba..0000000
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ /dev/null
@@ -1,254 +0,0 @@
-<template>
- <div>
- <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">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
- <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffName">
- <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鎬у埆锛�" prop="sex">
- <el-select v-model="form.sex">
- <el-option label="鐢�" value="鐢�" />
- <el-option label="濂�" value="濂�" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
- <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="宀椾綅锛�" prop="postJob">
- <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
- <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
- <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓撲笟锛�" prop="profession">
- <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞撮緞锛�" prop="age">
- <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
- <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
- <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
- <el-date-picker
- v-model="form.contractStartTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- @change="calculateContractTerm"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
- <el-date-picker
- v-model="form.contractEndTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- @change="calculateContractTerm"
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- staffState: "",
- },
- rules: {
- staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
- calculateContractTerm();
- })
- } else {
- form.value.id = ''
- }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- form.value.staffState = 1
- if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- staffJoinUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
- if (form.value.contractStartTime && form.value.contractEndTime) {
- const startDate = new Date(form.value.contractStartTime);
- const endDate = new Date(form.value.contractEndTime);
-
- if (endDate > startDate) {
- // 璁$畻骞翠唤宸�
- const yearDiff = endDate.getFullYear() - startDate.getFullYear();
- const monthDiff = endDate.getMonth() - startDate.getMonth();
- const dayDiff = endDate.getDate() - startDate.getDate();
-
- let years = yearDiff;
-
- // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
- if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
- years = yearDiff - 1;
- }
-
- form.value.contractTerm = Math.max(0, years);
- } else {
- form.value.contractTerm = 0;
- }
- } else {
- form.value.contractTerm = 0;
- }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue b/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
deleted file mode 100644
index fa0c9e6..0000000
--- a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
+++ /dev/null
@@ -1,386 +0,0 @@
-<template>
- <div>
- <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">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
- <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffName">
- <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鎬у埆锛�" prop="sex">
- <el-select v-model="form.sex">
- <el-option label="鐢�" value="鐢�" />
- <el-option label="濂�" value="濂�" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
- <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="宀椾綅锛�" prop="postJob">
- <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
- <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
- <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓撲笟锛�" prop="profession">
- <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="骞撮緞锛�" prop="age">
- <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
- <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
- <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓绛捐鏃ユ湡锛�" prop="trialStartDate">
- <el-date-picker
- v-model="form.trialStartDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="鍔冲姩鍚堝悓鏈熼檺閫夋嫨锛�" prop="dateSelect">
- <el-radio-group v-model="form.dateSelect">
- <el-radio :value="'A'">
- A銆佹湁鍥哄畾鏈熼檺
- </el-radio>
- <el-radio :value="'B'">
- B銆佹棤鍥哄畾鏈熼檺
- </el-radio>
- <el-radio :value="'C'">
- C銆佷互瀹屾垚涓�瀹氬伐浣滀换鍔′负鏈熼檺
- </el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30" v-if="showProbationDates">
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熷紑濮嬫棩鏈燂細" prop="signDate">
- <el-date-picker
- v-model="form.signDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熺粨鏉熸棩鏈燂細" prop="trialEndDate">
- <el-date-picker
- v-model="form.trialEndDate"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
-<!-- <el-row :gutter="30">-->
-<!-- <el-col :span="12">-->
-<!-- <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">-->
-<!-- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>-->
-<!-- </el-form-item>-->
-<!-- </el-col>-->
-<!-- </el-row>-->
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
- <el-date-picker
- v-model="form.contractStartTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12" v-if="showContractEnd">
- <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
- <el-date-picker
- v-model="form.contractEndTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="璇曠敤鏈熷伐璧勶細" prop="proSalary">
- <el-input-number placeholder="璇疯緭鍏ヨ瘯鐢ㄦ湡宸ヨ祫" :precision="2"
- :step="100"
- :min="0" v-model="form.proSalary" style="width: 100%"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="宸ヨ祫鎶ラ叕锛�" prop="salarySelect">
- <el-radio-group v-model="form.salarySelect" class="salary-radio-group">
- <el-radio :value="'A'" class="salary-radio-item">
- A銆佷箼鏂圭殑宸ヨ祫鎶ラ叕鎸夌収鐢叉柟渚濇硶鍒跺畾鐨勮绔犲埗搴︿腑鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曠‘瀹氾紝鏍规嵁涔欐柟鐨勫伐浣滃矖浣嶇‘瀹氬叾姣忔湀宸ヨ祫銆�
- </el-radio>
- <el-radio :value="'B'" class="salary-radio-item">
- B銆佺敳鏂瑰涔欐柟瀹炶鍩烘湰宸ヨ祫鍜岀哗鏁堝伐璧勭浉缁撳悎鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曪紝涔欐柟鐨勬敹鍏ュ寘鎷熀鏈伐璧勩�佽椁愩�佷氦閫氥�佺敓娲讳綇瀹跨瓑鍚勯」琛ュ姪锛屽鏈夊彉鍔ㄦ牴鎹唴閮ㄥ伐璧勫垎閰嶅姙娉曡皟鏁村叾宸ヨ祫锛涚哗鏁堝伐璧勬牴鎹箼鏂圭殑宸ヤ綔涓氱哗銆佸姵鍔ㄦ垚鏋滃拰瀹為檯璐$尞鎸夌収鍐呴儴鍒嗛厤鍔炴硶鑰冩牳纭畾銆�
- </el-radio>
- <el-radio :value="'C'" class="salary-radio-item">
- C銆佺敳鏂瑰疄琛岃浠跺伐璧勫埗锛屼互鐢叉柟鎺ュ埌璁㈠崟鍙婂叕鍙哥敓浜ц鍒掞紝鎸夌収瀹氶鍜岃浠跺崟浠凤紝鏍规嵁涔欐柟瀹屾垚鐨勪笟缁╋紝鎸夋椂瓒抽鏀粯涔欐柟鐨勫伐璧勬姤閰��
- </el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绂忓埄寰呴亣锛�" prop="remark">
- <el-input v-model="form.remark" 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>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance, computed, watch} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- staffNo: "",
- staffName: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- adress: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- dateSelect: "",
- signDate: "",
- trialEndDate: "",
- proSalary: null,
- trialStartDate: "",
- salarySelect: "",
- // contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- staffState: "",
- },
- rules: {
- staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- remark: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- dateSelect: [{ required: true, message: "璇烽�夋嫨鍔冲姩鍚堝悓鏈熼檺", trigger: "change" }],
- signDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- trialEndDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- trialStartDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- salarySelect: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鎶ラ叕鏂瑰紡", trigger: "change" }],
- // contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-
-const showContractEnd = computed(() => form.value.dateSelect === "A");
-const showProbationDates = computed(() => form.value.dateSelect === "A" || form.value.dateSelect === "B");
-
-watch(() => form.value.dateSelect, (type) => {
- if (type !== "A") {
- form.value.contractEndTime = "";
- }
-
- if (type === "C") {
- form.value.signDate = "";
- form.value.trialEndDate = "";
- form.value.proSalary = null;
- }
-}, { immediate: true });
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...res.data}
- // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
- // calculateContractTerm();
- })
- }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- form.value.staffState = 1
- if (operationType.value === "add") {
- staffJoinAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- staffJoinUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 璁$畻鍚堝悓骞撮檺
-// const calculateContractTerm = () => {
-// if (form.value.contractStartTime && form.value.contractEndTime) {
-// const startDate = new Date(form.value.contractStartTime);
-// const endDate = new Date(form.value.contractEndTime);
-//
-// if (endDate > startDate) {
-// // 璁$畻骞翠唤宸�
-// const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-// const monthDiff = endDate.getMonth() - startDate.getMonth();
-// const dayDiff = endDate.getDate() - startDate.getDate();
-//
-// let years = yearDiff;
-//
-// // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-// if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-// years = yearDiff - 1;
-// }
-//
-// form.value.contractTerm = Math.max(0, years);
-// } else {
-// form.value.contractTerm = 0;
-// }
-// } else {
-// form.value.contractTerm = 0;
-// }
-// };
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-.salary-radio-group {
- display: flex;
- gap: 12px;
-}
-
-.salary-radio-item {
- white-space: normal;
- word-wrap: break-word;
- line-height: 1.6;
- align-items: flex-start;
-}
-
-.salary-radio-item :deep(.el-radio__label) {
- white-space: normal;
- word-wrap: break-word;
- line-height: 1.6;
- padding-left: 8px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
deleted file mode 100644
index 9151a6c..0000000
--- a/src/views/personnelManagement/onboarding/index.vue
+++ /dev/null
@@ -1,280 +0,0 @@
-<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 FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.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: "age",
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "phone",
- width:150
- },
- {
- label: "绱ф�ヨ仈绯讳汉",
- prop: "emergencyContact",
- width: 120
- },
- {
- label: "鑱旂郴鐢佃瘽",
- prop: "emergencyContactPhone",
- width:150
- },
- // {
- // label: "鍚堝悓骞撮檺",
- // prop: "contractTerm",
- // },
- {
- 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;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-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/personnelManagement/payrollManagement/components/formDia.vue b/src/views/personnelManagement/payrollManagement/components/formDia.vue
deleted file mode 100644
index e4cf0b3..0000000
--- a/src/views/personnelManagement/payrollManagement/components/formDia.vue
+++ /dev/null
@@ -1,315 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板钖祫' : '缂栬緫钖祫'"
- width="50%"
- @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="payDate">
- <el-date-picker
- v-model="form.payDate"
- type="month"
- value-format="YYYY-MM-DD"
- format="YYYY-MM"
- placeholder="璇烽�夋嫨鏈堜唤"
- clearable
- :disabled="operationType === 'edit'"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="濮撳悕锛�" prop="staffId">
- <el-select v-model="form.staffId" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect" :disabled="operationType === 'edit'">
- <el-option
- v-for="item in personList"
- :key="item.id"
- :label="item.staffName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="搴斿嚭鍕ゅぉ鏁帮細" prop="shouldAttendedNum">
- <el-input v-model="form.shouldAttendedNum" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹為檯鍑哄嫟澶╂暟锛�" prop="actualAttendedNum">
- <el-input v-model="form.actualAttendedNum" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍩烘湰宸ヨ祫锛�" prop="basicSalary">
- <el-input v-model="form.basicSalary" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="宀椾綅宸ヨ祫锛�" prop="postSalary">
- <el-input v-model="form.postSalary" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍏ョ鑱岀己鍕ゆ墸娆撅細" prop="deductionAbsenteeism">
- <el-input v-model="form.deductionAbsenteeism" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐥呭亣鎵f锛�" prop="sickLeaveDeductions">
- <el-input v-model="form.sickLeaveDeductions" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="浜嬪亣鎵f锛�" prop="deductionPersonalLeave">
- <el-input v-model="form.deductionPersonalLeave" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="蹇樿鎵撳崱鎵f锛�" prop="forgetClockDeduct">
- <el-input v-model="form.forgetClockDeduct" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="缁╂晥寰楀垎锛�" prop="performanceScore">
- <el-input v-model="form.performanceScore" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁╂晥宸ヨ祫锛�" prop="performancePay">
- <el-input v-model="form.performancePay" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="搴斿彂鍚堣锛�" prop="payableWages">
- <el-input v-model="form.payableWages" placeholder="璇疯緭鍏�" clearable type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绀句繚涓汉锛�" prop="socialSecurityIndividuals">
- <el-input v-model="form.socialSecurityIndividuals" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绀句繚鍏徃锛�" prop="socialSecurityCompanies">
- <el-input v-model="form.socialSecurityCompanies" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绀句繚鍚堣锛�" prop="socialSecurityTotal">
- <el-input v-model="form.socialSecurityTotal" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍏Н閲戜釜浜猴細" prop="providentFundIndividuals">
- <el-input v-model="form.providentFundIndividuals" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏Н閲戝叕鍙革細" prop="providentFundCompany">
- <el-input v-model="form.providentFundCompany" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍏Н閲戝悎璁★細" prop="providentFundTotal">
- <el-input v-model="form.providentFundTotal" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="搴旂◣宸ヨ祫锛�" prop="taxableWaget">
- <el-input v-model="form.taxableWaget" :precision="0" :step="1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="涓汉鎵�寰楃◣锛�" prop="personalIncomeTax">
- <el-input v-model="form.personalIncomeTax" :step="0.1" style="width: 100%" type="number"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹炲彂宸ヨ祫锛�" prop="actualWages">
- <el-input v-model="form.actualWages" style="width: 100%" type="number"/>
- </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>
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
- form: {
- payDate: "",
- staffId: "",
- name: "",
- shouldAttendedNum: "",
- actualAttendedNum: "",
- basicSalary: "",
- postSalary: "",
- deductionAbsenteeism: "",
- sickLeaveDeductions: "",
- deductionPersonalLeave: "",
- forgetClockDeduct: "",
- performanceScore: "",
- performancePay: "",
- payableWages: "",
- socialSecurityIndividuals: "",
- socialSecurityCompanies: "",
- socialSecurityTotal: "",
- providentFundIndividuals: "",
- providentFundCompany: "",
- providentFundTotal: "",
- taxableWaget: "",
- personalIncomeTax: "",
- actualWages: "",
- },
- rules: {
- payDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
- staffId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
- staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- shouldAttendedNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- actualAttendedNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- basicSalary: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- postSalary: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- deductionAbsenteeism: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- sickLeaveDeductions: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- deductionPersonalLeave: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- forgetClockDeduct: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- performanceScore: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- performancePay: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- payableWages: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- socialSecurityIndividuals: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- socialSecurityCompanies: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- socialSecurityTotal: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- providentFundIndividuals: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- providentFundCompany: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- providentFundTotal: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxableWaget: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- personalIncomeTax: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- actualWages: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-const personList = ref([]);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
- operationType.value = type;
- dialogFormVisible.value = true;
- getStaffOnJob().then(res => {
- personList.value = res.data
- })
- form.value = {}
- if (operationType.value === 'edit') {
- getStaffJoinInfo(row.id).then(res => {
- form.value = {...row}
- form.value.payDate = form.value.payDate + '-01'
- })
- }
-}
-const handleSelect = (value) => {
- console.log('value', value)
- const index = personList.value.findIndex(row => row.id === value)
- if (index > -1) {
- form.value.name = personList.value[index].staffName
- }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
- proxy.$refs.formRef.validate(valid => {
- if (valid) {
- form.value.staffState = 1
- if (operationType.value === "add") {
- compensationAdd(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- } else {
- compensationUpdate(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
- }
- }
- })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
- if (form.value.contractStartTime && form.value.contractEndTime) {
- const startDate = new Date(form.value.contractStartTime);
- const endDate = new Date(form.value.contractEndTime);
-
- if (endDate > startDate) {
- // 璁$畻骞翠唤宸�
- const yearDiff = endDate.getFullYear() - startDate.getFullYear();
- const monthDiff = endDate.getMonth() - startDate.getMonth();
- const dayDiff = endDate.getDate() - startDate.getDate();
-
- let years = yearDiff;
-
- // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
- if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
- years = yearDiff - 1;
- }
-
- form.value.contractTerm = Math.max(0, years);
- } else {
- form.value.contractTerm = 0;
- }
- } else {
- form.value.contractTerm = 0;
- }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- emit('close')
-};
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/payrollManagement/index.vue b/src/views/personnelManagement/payrollManagement/index.vue
deleted file mode 100644
index 24e3dd8..0000000
--- a/src/views/personnelManagement/payrollManagement/index.vue
+++ /dev/null
@@ -1,307 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">濮撳悕锛�</span>
- <el-input
- v-model="searchForm.name"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title ml10">鏈堜唤锛�</span>
- <el-date-picker
- v-model="searchForm.payDateStr"
- type="month"
- @change="handleQuery"
- value-format="YYYY-MM"
- format="YYYY-MM"
- placeholder="璇烽�夋嫨鏈堜唤"
- style="width: 240px"
- clearable
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="openForm('add')">鏂板钖祫</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, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
-import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue";
-import {staffJoinDel} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js";
-
-const data = reactive({
- searchForm: {
- name: "",
- payDateStr: "",
- },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
- {
- label: "钖祫鏈堜唤",
- prop: "payDate",
- },
- {
- label: "濮撳悕",
- prop: "name",
- },
- {
- label: "搴斿嚭鍕ゅぉ鏁�",
- prop: "shouldAttendedNum",
- width:100
- },
- {
- label: "瀹為檯鍑哄嫟澶╂暟",
- prop: "actualAttendedNum",
- width:110
- },
- {
- label: "鍩烘湰宸ヨ祫",
- prop: "basicSalary",
- },
- {
- label: "宀椾綅宸ヨ祫",
- prop: "postSalary",
- width:100
- },
- {
- label: "鍏ョ鑱岀己鍕ゆ墸娆�",
- prop: "deductionAbsenteeism",
- width:130
- },
- {
- label: "鐥呭亣鎵f",
- prop: "sickLeaveDeductions",
- width:100
- },
- {
- label: "浜嬪亣鎵f",
- prop: "deductionPersonalLeave",
- width:100
- },
- {
- label: "蹇樿鎵撳崱鎵f",
- prop: "forgetClockDeduct",
- width:110
- },
- {
- label: "缁╂晥寰楀垎",
- prop: "performanceScore",
- width:150
- },
- {
- label: "缁╂晥宸ヨ祫",
- prop: "performancePay",
- width: 120
- },
- {
- label: "搴斿彂鍚堣",
- prop: "payableWages",
- width:150
- },
- {
- label: "绀句繚涓汉",
- prop: "socialSecurityIndividuals",
- },
- {
- label: "绀句繚鍏徃",
- prop: "socialSecurityCompanies",
- width: 120
- },
- {
- label: "绀句繚鍚堣",
- prop: "socialSecurityTotal",
- width: 120
- },
- {
- label: "鍏Н閲戜釜浜�",
- prop: "providentFundIndividuals",
- width: 120
- },
- {
- label: "鍏Н閲戝叕鍙�",
- prop: "providentFundCompany",
- width: 120
- },
- {
- label: "鍏Н閲戝悎璁�",
- prop: "providentFundTotal",
- width: 120
- },
- {
- label: "搴旂◣宸ヨ祫",
- prop: "taxableWaget",
- },
- {
- label: "涓汉鎵�寰楃◣",
- prop: "personalIncomeTax",
- width: 120
- },
- {
- label: "瀹炲彂宸ヨ祫",
- prop: "actualWages",
- 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;
- compensationListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-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(() => {
- compensationDelete(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("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭钖祫绠$悊
-const handleExport = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/compensationPerformance/export", { ...searchForm.value, ...page }, "钖祫绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/scheduling/index.vue b/src/views/personnelManagement/scheduling/index.vue
deleted file mode 100644
index 251dbe9..0000000
--- a/src/views/personnelManagement/scheduling/index.vue
+++ /dev/null
@@ -1,618 +0,0 @@
-<template>
- <div class="app-container scheduling-container">
- <!-- 绛涢�夊尯鍩� -->
- <div class="filter-section">
- <el-form :inline="true" :model="filterForm" class="filter-form">
- <el-form-item label="鍛樺伐濮撳悕锛�">
- <el-input
- v-model="filterForm.staffName"
- placeholder="璇疯緭鍏ュ憳宸ュ鍚�"
- clearable
- style="width: 150px"
- />
- </el-form-item>
- <el-form-item label="鐝绫诲瀷锛�">
- <el-select v-model="filterForm.shiftType" placeholder="璇烽�夋嫨鐝" clearable style="width: 120px">
- <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/>
- </el-select>
- </el-form-item>
- <el-form-item label="鏃ユ湡鑼冨洿锛�">
- <el-date-picker
- v-model="filterForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 250px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleFilter">
- <el-icon><Search/></el-icon>
- 绛涢��
- </el-button>
- <el-button @click="resetFilter">
- <el-icon><Refresh/></el-icon>
- 閲嶇疆
- </el-button>
- <el-button @click="handleExport">
- <el-icon><Download/></el-icon>
- 瀵煎嚭
- </el-button>
- <el-button type="primary" @click="openScheduleDialog('add')">
- <el-icon><Plus/></el-icon>
- 鏂板鎺掔彮
- </el-button>
- </el-form-item>
- </el-form>
- </div>
-
- <!-- 鎺掔彮琛ㄦ牸 -->
- <div class="table-section">
- <el-table
- :data="scheduleList"
- border
- :loading="tableLoading"
- stripe
- style="width: 100%"
- height="calc(100vh - 18.5em)"
- @selection-change="handleSelectionChange"
- >
- <el-table-column type="selection" width="55"/>
- <el-table-column prop="staffName" label="鍛樺伐濮撳悕" width="120"/>
- <el-table-column prop="staffNo" label="鍛樺伐宸ュ彿" width="100"/>
- <el-table-column prop="department" label="閮ㄩ棬" width="120">
- <template #default="scope">
- {{ (department_type.find(i => i.value === String(scope.row.department)) || {}).label }}
- </template>
- </el-table-column>
- <el-table-column prop="shiftType" label="鐝绫诲瀷" width="100">
- <template #default="scope">
- <el-tag :type="getShiftTagType(scope.row.shiftType)">
- {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="workDate" label="宸ヤ綔鏃ユ湡" width="120"/>
- <el-table-column prop="startTime" label="寮�濮嬫椂闂�" width="100"/>
- <el-table-column prop="endTime" label="缁撴潫鏃堕棿" width="100"/>
- <el-table-column prop="workHours" label="宸ヤ綔鏃堕暱" width="100">
- <template #default="scope">
- {{ scope.row.workHours }}灏忔椂
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusTagType(scope.row.status)">
- {{ (schedule_status.find(i => i.value === String(scope.row.status)) || {}).label }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="remark" label="澶囨敞" min-width="150"/>
- <el-table-column label="鎿嶄綔" width="200" fixed="right">
- <template #default="scope">
- <el-button
- type="primary"
- size="small"
- @click="openScheduleDialog('edit', scope.row)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="danger"
- size="small"
- @click="handleDelete(scope.row)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-if="tableCount > 0"
- :total="tableCount"
- :page="filterForm.current"
- :limit="filterForm.size"
- @pagination="paginationChange"
- />
- </div>
-
- <!-- 鎵归噺鎿嶄綔 -->
- <div class="batch-actions" v-if="selectedRows.length > 0">
- <el-button
- type="danger"
- @click="handleBatchDelete"
- :disabled="selectedRows.length === 0"
- >
- 鎵归噺鍒犻櫎 ({{ selectedRows.length }})
- </el-button>
- </div>
-
- <!-- 鎺掔彮鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- v-model="scheduleDialog"
- :title="dialogType === 'add' ? '鏂板鎺掔彮' : '缂栬緫鎺掔彮'"
- width="700px"
- @close="closeScheduleDialog"
- >
- <el-form
- :model="scheduleForm"
- :rules="scheduleRules"
- ref="scheduleFormRef"
- label-width="120px"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍛樺伐濮撳悕锛�" prop="staffId">
- <el-select v-model="scheduleForm.staffId" placeholder="璇疯緭鍏ュ憳宸ュ鍚�" style="width: 100%"
- @change="handleSelectStaff">
- <el-option v-for="item in personList" :label="item.staffName" :value="item.id" :key="item.id"/>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍛樺伐宸ュ彿锛�" prop="staffNo">
- <el-input :disabled="true" v-model="scheduleForm.staffNo" placeholder=""/>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閮ㄩ棬锛�" prop="department">
- <el-select v-model="scheduleForm.department" placeholder="璇烽�夋嫨閮ㄩ棬" style="width: 100%">
- <el-option v-for="item in department_type" :label="item.label" :value="item.value" :key="item.value"/>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐝绫诲瀷锛�" prop="shiftType">
- <el-select v-model="scheduleForm.shiftType" placeholder="璇烽�夋嫨鐝" style="width: 100%">
- <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="宸ヤ綔鏃ユ湡锛�" prop="workDate">
- <el-date-picker
- v-model="scheduleForm.workDate"
- type="date"
- placeholder="閫夋嫨宸ヤ綔鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐘舵�侊細" prop="status">
- <el-select v-model="scheduleForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option v-for="item in schedule_status" :label="item.label" :value="item.value" :key="item.value"/>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="寮�濮嬫椂闂达細" prop="startTime">
- <el-time-picker
- v-model="scheduleForm.startTime"
- placeholder="閫夋嫨寮�濮嬫椂闂�"
- style="width: 100%"
- format="HH:mm"
- value-format="HH:mm"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="缁撴潫鏃堕棿锛�" prop="endTime">
- <el-time-picker
- v-model="scheduleForm.endTime"
- placeholder="閫夋嫨缁撴潫鏃堕棿"
- style="width: 100%"
- format="HH:mm"
- value-format="HH:mm"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞锛�" prop="remark">
- <el-input
- v-model="scheduleForm.remark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitScheduleForm">纭</el-button>
- <el-button @click="closeScheduleDialog">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue'
-import {ElMessage, ElMessageBox} from 'element-plus'
-import {useDict} from "@/utils/dict.js"
-import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue'
-import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js"
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
-import dayjs from "dayjs";
-import pagination from "@/components/PIMTable/Pagination.vue";
-
-const { proxy } = getCurrentInstance();
-
-const tableCount = ref(0)
-// 鍝嶅簲寮忔暟鎹�
-const scheduleDialog = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-const scheduleFormRef = ref()
-
-// 绛涢�夎〃鍗�
-const filterForm = reactive({
- staffName: '',
- shiftType: '',
- dateRange: [],
- current:1,
- size: 10
-})
-
-// 鎺掔彮琛ㄥ崟
-const scheduleForm = reactive({
- id: '',
- staffId: '',
- staffNo: '',
- department: '',
- shiftType: '',
- workDate: '',
- startTime: '',
- endTime: '',
- workStartTime: '',
- workEndTime: '',
- workHours: 0,
- status: '',
- remark: ''
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const scheduleRules = reactive({
- staffId: [{required: true, message: '璇烽�夋嫨鍛樺伐', trigger: 'change'}],
- department: [{required: true, message: '璇烽�夋嫨閮ㄩ棬', trigger: 'change'}],
- shiftType: [{required: true, message: '璇烽�夋嫨鐝绫诲瀷', trigger: 'change'}],
- workDate: [{required: true, message: '璇烽�夋嫨宸ヤ綔鏃ユ湡', trigger: 'change'}],
- startTime: [{required: true, message: '璇烽�夋嫨寮�濮嬫椂闂�', trigger: 'change'}],
- endTime: [{required: true, message: '璇烽�夋嫨缁撴潫鏃堕棿', trigger: 'change'}],
- status: [{required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change'}]
-})
-const tableLoading = ref(false)
-
-//瀛楀吀
-const {department_type, schedule_status, shift_type} = useDict("department_type", "schedule_status", "shift_type")
-// 浜哄憳鍒楄〃
-const personList = ref([]);
-
-// 妯℃嫙鎺掔彮鏁版嵁
-const scheduleList = ref([])
-
-
-/**
- * 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
- */
-const getPersonList = () => {
- getStaffOnJob().then(res => {
- personList.value = res.data
- })
-};
-const paginationChange = (obj) => {
- filterForm.current = obj.page;
- filterForm.size = obj.limit;
- handleFilter();
-};
-
-const handleSelectStaff = (val) => {
- let obj = personList.value.find(item => item.id === val)
- scheduleForm.staffNo = obj.staffNo
-
-}
-
-// 鑾峰彇鐝鏍囩绫诲瀷
-const getShiftTagType = (shiftType) => {
- const typeMap = Object.fromEntries(shift_type.value.map(i => [i.value, i.elTagType]))
- return typeMap[shiftType] || 'info'
-}
-
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusTagType = (status) => {
- const typeMap = Object.fromEntries(schedule_status.value.map(i => [i.value, i.elTagType]))
- return typeMap[status] || 'info'
-}
-
-// 绛涢��
-const handleFilter = async () => {
- tableLoading.value = true
- let searchForm = {
- ...filterForm,
- ...(filterForm.dateRange.length > 0 && {
- startDate: filterForm.dateRange[0],
- endDate: filterForm.dateRange[1],
- })
- }
- let resp = await listPage(searchForm)
- tableCount.value = resp.data.total
- scheduleList.value = resp.data.records.map(it => {
- return {
- ...it,
- 'startTime': dayjs(it.workStartTime).format('HH:mm'),
- 'endTime': dayjs(it.workEndTime).format('HH:mm'),
- }
- })
- tableLoading.value = false
-
-}
-
-// 閲嶇疆绛涢��
-const resetFilter = () => {
- filterForm.staffName = ''
- filterForm.shiftType = ''
- filterForm.dateRange = []
-}
-
-// 鎵撳紑鎺掔彮瀵硅瘽妗�
-const openScheduleDialog = (type, data) => {
- dialogType.value = type
- scheduleDialog.value = true
- getPersonList()
- if (type === 'edit' && data) {
- // 缂栬緫妯″紡锛屽鍒舵暟鎹�
- Object.assign(scheduleForm, {...data})
- } else {
- // 鏂板妯″紡锛岄噸缃〃鍗�
- Object.keys(scheduleForm).forEach(key => {
- scheduleForm[key] = ''
- })
- // scheduleForm.status = '宸插畨鎺�'
- scheduleForm.workDate = new Date().toISOString().split('T')[0]
- }
-}
-
-// 鍏抽棴鎺掔彮瀵硅瘽妗�
-const closeScheduleDialog = () => {
- scheduleFormRef.value?.resetFields()
- scheduleDialog.value = false
-}
-
-// 璁$畻宸ヤ綔鏃堕暱
-const calculateWorkHours = () => {
- if (scheduleForm.workDate && scheduleForm.startTime && scheduleForm.endTime) {
- // 浣跨敤 workDate 涓� startTime 鍜� endTime 缁勫悎
- const startDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.startTime}`)
- const endDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.endTime}`)
-
- // 澶勭悊璺ㄥぉ鎯呭喌锛堢粨鏉熸椂闂存棭浜庡紑濮嬫椂闂达級
- if (endDateTime < startDateTime) {
- // 璺ㄥぉ锛屽皢缁撴潫鏃ユ湡鍔犱竴澶�
- endDateTime.setDate(endDateTime.getDate() + 1)
- }
- // 璁$畻宸ヤ綔鏃堕暱锛堝皬鏃讹級
- const diffMs = endDateTime - startDateTime
- const diffHours = diffMs / (1000 * 60 * 60)
- scheduleForm.workHours = Math.round(diffHours * 100) / 100
- scheduleForm.workStartTime = dayjs(startDateTime).format("YYYY-MM-DD HH:mm:ss")
- scheduleForm.workEndTime = dayjs(endDateTime).format("YYYY-MM-DD HH:mm:ss")
-
- }
-}
-
-// 鎻愪氦鎺掔彮琛ㄥ崟
-const submitScheduleForm = async () => {
- const valid = await scheduleFormRef.value.validate()
- if (!valid) return
-
- calculateWorkHours()
- const newSchedule = {...scheduleForm}
-
- try {
- await save(newSchedule)
- ElMessage.success('淇濆瓨鎺掔彮鎴愬姛')
-
- handleFilter()
- closeScheduleDialog()
- } catch (err) {
- ElMessage.error('淇濆瓨澶辫触')
- }
-}
-
-// 鍒犻櫎鎺掔彮
-const handleDelete = (row) => {
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄� ${row.staffName} 鐨勬帓鐝褰曞悧锛焋,
- '鍒犻櫎鎻愮ず',
- {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- del(row.id)
- ElMessage.success('鍒犻櫎鎴愬姛')
- handleFilter()
- }).catch(() => {
- ElMessage.info('宸插彇娑堝垹闄�')
- })
-}
-
-// 鎵归噺鍒犻櫎
-const handleBatchDelete = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑璁板綍')
- return
- }
-
- ElMessageBox.confirm(
- `纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉℃帓鐝褰曞悧锛焋,
- '鎵归噺鍒犻櫎鎻愮ず',
- {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- delByIds(selectedRows.value.map(item => item.id))
- handleFilter()
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
- }).catch(() => {
- ElMessage.info('宸插彇娑堝垹闄�')
- })
-}
-
-// 閫夋嫨鍙樺寲浜嬩欢
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection
-}
-
-// 瀵煎嚭
-const handleExport = () => {
- let searchForm = {
- ...filterForm,
- ...(filterForm.dateRange.length > 0 && {
- startDate: filterForm.dateRange[0],
- endDate: filterForm.dateRange[1],
- })
- }
- proxy.download('/staff/staffScheduling/export', {}, '浜哄憳鎺掔彮.xlsx')
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- // 椤甸潰鍒濆鍖�
- handleFilter()
-})
-</script>
-
-<style scoped>
-.scheduling-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- color: white;
-}
-
-.page-header h2 {
- color: white;
- margin-bottom: 10px;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- color: rgba(255, 255, 255, 0.9);
- font-size: 14px;
- margin: 0 0 15px 0;
-}
-
-.header-controls {
- display: flex;
- justify-content: center;
- gap: 15px;
-}
-
-.filter-section {
- background: white;
- padding: 20px;
- border-radius: 8px;
- margin-bottom: 20px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.filter-form {
- margin: 0;
-}
-
-.table-section {
- background: white;
- border-radius: 8px;
- overflow: hidden;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- margin-bottom: 20px;
-}
-
-.batch-actions {
- background: white;
- padding: 15px 20px;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-form-item__label) {
- font-weight: 500;
- color: #303133;
-}
-
-:deep(.el-input__wrapper) {
- box-shadow: 0 0 0 1px #dcdfe6 inset;
-}
-
-:deep(.el-input__wrapper:hover) {
- box-shadow: 0 0 0 1px #c0c4cc inset;
-}
-
-:deep(.el-input__wrapper.is-focus) {
- box-shadow: 0 0 0 1px #409eff inset;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .scheduling-container {
- padding: 10px;
- }
-
- .page-header {
- padding: 15px;
- }
-
- .page-header h2 {
- font-size: 24px;
- }
-
- .header-controls {
- flex-direction: column;
- gap: 10px;
- }
-}
-
-@media (max-width: 768px) {
- .filter-form .el-form-item {
- margin-bottom: 10px;
- }
-}
-</style>
diff --git a/src/views/personnelManagement/selfService/index.vue b/src/views/personnelManagement/selfService/index.vue
deleted file mode 100644
index ca683c0..0000000
--- a/src/views/personnelManagement/selfService/index.vue
+++ /dev/null
@@ -1,804 +0,0 @@
-<template>
- <div class="app-container self-service-container">
-
- <!-- 鍔熻兘瀵艰埅鍗$墖 -->
- <el-row :gutter="20" class="nav-cards">
- <el-col :span="6" v-for="(item, index) in navItems" :key="index">
- <el-card class="nav-card" @click="handleNavClick(item.type)">
- <div class="nav-content">
- <el-icon :size="40" class="nav-icon">
- <component :is="item.icon" />
- </el-icon>
- <h3>{{ item.title }}</h3>
- <p>{{ item.desc }}</p>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 涓昏鍐呭鍖哄煙 -->
- <div class="main-content">
- <!-- 鑰冨嫟璁板綍 -->
- <el-card v-if="currentView === 'attendance'" class="content-card">
- <template #header>
- <div class="card-header">
- <span>涓汉鑰冨嫟璁板綍</span>
- <el-button type="primary" @click="addAttendanceRecord">鏂板璁板綍</el-button>
- </div>
- </template>
- <el-table :data="attendanceData" style="width: 100%" :loading="tableLoading">
- <el-table-column prop="date" label="鏃ユ湡" />
- <el-table-column prop="checkIn" label="绛惧埌鏃堕棿" />
- <el-table-column prop="checkOut" label="绛鹃��鏃堕棿" />
- <el-table-column prop="workHours" label="宸ヤ綔鏃堕暱" width="100" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.status === '姝e父' ? 'success' : 'danger'">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="150">
- <template #default="scope">
- <el-button size="small" @click="editAttendanceRecord(scope.row)">缂栬緫</el-button>
- <el-button size="small" type="danger" @click="deleteAttendanceRecord(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 钖祫鍗� -->
- <el-card v-if="currentView === 'salary'" class="content-card">
- <template #header>
- <div class="card-header">
- <span>钖祫鍗曟煡璇�</span>
- <el-date-picker v-model="payDateStr" type="month" placeholder="閫夋嫨鏈堜唤" value-format="YYYY-MM" format="YYYY-MM" @change="changMonth"/>
- </div>
- </template>
- <el-table :data="salaryData" style="width: 100%">
- <el-table-column prop="payDate" label="鏈堜唤" />
- <el-table-column prop="basicSalary" label="鍩烘湰宸ヨ祫" />
- <el-table-column prop="bonus" label="濂栭噾" />
- <el-table-column prop="deduction" label="鎵f" />
- <el-table-column prop="actualWages" label="瀹炲彂宸ヨ祫" />
- <el-table-column prop="status" label="鐘舵��" >
- <template #default="scope">
- <el-tag :type="scope.row.status === '宸插彂鏀�' ? 'success' : 'warning'">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 鍋囨湡鐢宠 -->
- <el-card v-if="currentView === 'leave'" class="content-card">
- <template #header>
- <div class="card-header">
- <span>鍋囨湡鐢宠绠$悊</span>
- <el-button type="primary" @click="openLeaveForm">鐢宠鍋囨湡</el-button>
- </div>
- </template>
- <el-table :data="leaveData" style="width: 100%">
- <el-table-column prop="type" label="鍋囨湡绫诲瀷" />
- <el-table-column prop="startDate" label="寮�濮嬫棩鏈�" />
- <el-table-column prop="endDate" label="缁撴潫鏃ユ湡" />
- <el-table-column prop="days" label="澶╂暟" width="80" />
- <el-table-column prop="reason" label="鐢宠鍘熷洜" />
- <el-table-column prop="status" label="瀹℃壒鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="150">
- <template #default="scope">
- <el-button size="small" @click="editLeaveRecord(scope.row)">缂栬緫</el-button>
- <el-button size="small" type="danger" @click="deleteLeaveRecord(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 涓汉淇℃伅 -->
- <el-card v-if="currentView === 'profile'" class="content-card">
- <template #header>
- <div class="card-header">
- <span>涓汉淇℃伅缁存姢</span>
- <el-button type="primary" @click="editProfileForm">缂栬緫淇℃伅</el-button>
- </div>
- </template>
- <el-descriptions :column="2" border>
- <el-descriptions-item label="濮撳悕">{{ profile.name }}</el-descriptions-item>
- <el-descriptions-item label="宸ュ彿">{{ profile.employeeId }}</el-descriptions-item>
- <el-descriptions-item label="閮ㄩ棬">{{ profile.department }}</el-descriptions-item>
- <el-descriptions-item label="鑱屼綅">{{ profile.position }}</el-descriptions-item>
- <el-descriptions-item label="鍏ヨ亴鏃ユ湡">{{ profile.hireDate }}</el-descriptions-item>
- <el-descriptions-item label="鑱旂郴鐢佃瘽">{{ profile.phone }}</el-descriptions-item>
- <el-descriptions-item label="閭">{{ profile.email }}</el-descriptions-item>
- <el-descriptions-item label="鍦板潃">{{ profile.adress }}</el-descriptions-item>
- </el-descriptions>
- </el-card>
- </div>
-
- <!-- 鍋囨湡鐢宠寮圭獥 -->
- <el-dialog v-model="showLeaveDialog" :title="leaveOperationType === 'add' ? '鐢宠鍋囨湡' : '缂栬緫鍋囨湡'" width="500px">
- <el-form :model="leaveForm" label-width="100px">
- <el-form-item label="鍋囨湡绫诲瀷">
- <el-select v-model="leaveForm.type" placeholder="璇烽�夋嫨鍋囨湡绫诲瀷">
- <el-option label="骞村亣" value="骞村亣" />
- <el-option label="鐥呭亣" value="鐥呭亣" />
- <el-option label="璋冧紤" value="璋冧紤" />
- <el-option label="浜嬪亣" value="浜嬪亣" />
- </el-select>
- </el-form-item>
- <el-form-item label="寮�濮嬫棩鏈�">
- <el-date-picker v-model="leaveForm.startDate" type="date" placeholder="閫夋嫨寮�濮嬫棩鏈�" />
- </el-form-item>
- <el-form-item label="缁撴潫鏃ユ湡">
- <el-date-picker v-model="leaveForm.endDate" type="date" placeholder="閫夋嫨缁撴潫鏃ユ湡" />
- </el-form-item>
- <el-form-item label="鐢宠鍘熷洜">
- <el-input v-model="leaveForm.reason" type="textarea" rows="3" />
- </el-form-item>
- <!-- <el-form-item label="瀹℃壒鐘舵��">
- <el-select v-model="leaveForm.status" placeholder="璇烽�夋嫨瀹℃壒鐘舵��">
- <el-option label="瀹℃壒涓�" value="瀹℃壒涓�" />
- <el-option label="宸查�氳繃" value="宸查�氳繃" />
- <el-option label="宸叉嫆缁�" value="宸叉嫆缁�" />
- </el-select>
- </el-form-item> -->
- </el-form>
- <template #footer>
- <el-button @click="showLeaveDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitLeaveApplication">鎻愪氦鐢宠</el-button>
- </template>
- </el-dialog>
-
- <!-- 鏂板-缂栬緫鑰冨嫟璁板綍寮圭獥 -->
- <el-dialog v-model="showAttendanceDialog" :title="operationType === 'add' ? '鏂板鑰冨嫟璁板綍' : '缂栬緫鑰冨嫟璁板綍'" width="500px">
- <el-form :model="attendanceForm" :rules="attendanceRules" ref="attendanceFormRef" label-width="100px">
- <el-form-item label="鏃ユ湡" prop="date">
- <el-date-picker v-model="attendanceForm.date" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="閫夋嫨鏃ユ湡" />
- </el-form-item>
- <el-form-item label="绛惧埌鏃堕棿" prop="checkIn">
- <el-time-picker v-model="attendanceForm.checkIn" placeholder="閫夋嫨绛惧埌鏃堕棿" format="HH:mm" value-format="HH:mm" />
- </el-form-item>
- <el-form-item label="绛鹃��鏃堕棿" prop="checkOut">
- <el-time-picker v-model="attendanceForm.checkOut" placeholder="閫夋嫨绛鹃��鏃堕棿" format="HH:mm" value-format="HH:mm" />
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="attendanceForm.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="姝e父" value="姝e父" />
- <el-option label="杩熷埌" value="杩熷埌" />
- <el-option label="鏃╅��" value="鏃╅��" />
- <el-option label="缂哄嫟" value="缂哄嫟" />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="showAttendanceDialog = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitAttendance">鎻愪氦</el-button>
- </template>
- </el-dialog>
-
- <!-- 涓汉淇℃伅缂栬緫寮圭獥 -->
- <el-dialog v-model="editProfile" title="缂栬緫涓汉淇℃伅" width="500px">
- <el-form :model="profileForm" label-width="100px">
- <el-form-item label="濮撳悕">
- <el-input v-model="profileForm.name" />
- </el-form-item>
- <el-form-item label="鑱旂郴鐢佃瘽">
- <el-input v-model="profileForm.phone" />
- </el-form-item>
- <el-form-item label="閭">
- <el-input v-model="profileForm.email" />
- </el-form-item>
- <el-form-item label="鍦板潃">
- <el-input v-model="profileForm.adress" type="textarea" rows="2" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="editProfile = false">鍙栨秷</el-button>
- <el-button type="primary" @click="saveProfile">淇濆瓨</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, watch, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {
- Calendar,
- Money,
- Clock,
- User
-} from '@element-plus/icons-vue'
-import { personalAttendanceRecordsListPage, personalAttendanceRecordsAdd, personalAttendanceRecordsUpdate, personalAttendanceRecordsDelete, holidayApplicationListPage, holidayApplicationAdd, holidayApplicationUpdate, holidayApplicationDelete } from '@/api/personnelManagement/selfService'
-import { compensationListPage, compensationAdd, compensationUpdate, compensationDelete } from '@/api/personnelManagement/payrollManagement'
-
-const { proxy } = getCurrentInstance()
-import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinUpdate, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import { fa, id } from 'element-plus/es/locales.mjs'
-
-const tableLoading = ref(false)
-// 鍒嗛〉鍙傛暟
-const page = reactive({
- current: 1,
- size: 10,
- total: 0
-})
-
-// 褰撳墠瑙嗗浘
-const currentView = ref('attendance')
-
-// 瀵艰埅椤�
-const navItems = [
- { type: 'attendance', title: '鑰冨嫟璁板綍', desc: '鏌ヨ涓汉鑰冨嫟淇℃伅', icon: 'Calendar' },
- { type: 'salary', title: '钖祫鍗�', desc: '鏌ョ湅钖祫鍙戞斁璁板綍', icon: 'Money' },
- { type: 'leave', title: '鍋囨湡鐢宠', desc: '鍦ㄧ嚎鐢宠鍚勭被鍋囨湡', icon: 'Clock' },
- { type: 'profile', title: '涓汉淇℃伅', desc: '缁存姢涓汉鍩烘湰淇℃伅', icon: 'User' }
-]
-
-// 鑰冨嫟鏁版嵁
-const attendanceData = ref([])
-
-// 钖祫鏁版嵁
-const salaryData = ref([])
-
-
-// 鍋囨湡鏁版嵁
-const leaveData = ref([])
-
-const currentUser = ref()
-const user= ref()
-// 涓汉淇℃伅
-const profile = ref({
- id: '',
- name: '',
- employeeId: '',
- department: '',
- position: '',
- hireDate: '',
- phone: '',
- email: '',
- adress: ''
- })
-
-// 寮圭獥鎺у埗
-const showLeaveDialog = ref(false)
-const editProfile = ref(false)
-const payDateStr = ref('')
-
-// 琛ㄥ崟鏁版嵁
-const leaveForm = reactive({
- id: '',
- type: '',
- startDate: '',
- endDate: '',
- days: 0,
- reason: '',
- status: ''
-})
-const profileForm = reactive({
- name: "",
- email: "",
- adress: "",
- phone: "",
-})
-const joinForm = reactive({
- id: "",
- staffNo: "",
- staffName: "",
- email: "",
- adress: "",
- sex: "",
- nativePlace: "",
- postJob: "",
- firstStudy: "",
- profession: "",
- age: 0,
- phone: "",
- emergencyContact: "",
- emergencyContactPhone: "",
- contractTerm: 0,
- contractStartTime: "",
- contractEndTime: "",
- staffState: 1,
-})
-
-// 鏂板鑰冨嫟璁板綍锛氬脊绐椾笌琛ㄥ崟
-const operationType = ref('add')
-const leaveOperationType = ref('add')
-const showAttendanceDialog = ref(false)
-const attendanceFormRef = ref(null)
-const attendanceForm = reactive({
- id: '',
- date: '',
- checkIn: '',
- checkOut: '',
- workHours: '',
- status: '姝e父'
-})
-const attendanceRules = {
- date: [{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }],
- checkIn: [{ required: true, message: '璇烽�夋嫨绛惧埌鏃堕棿', trigger: 'change' }],
- checkOut: [{ required: true, message: '璇烽�夋嫨绛鹃��鏃堕棿', trigger: 'change' }],
- status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
-
-// 澶勭悊瀵艰埅鐐瑰嚮
-const handleNavClick = (type) => {
- currentView.value = type
-}
-
-// 鑾峰彇鐘舵�佺被鍨�
-const getStatusType = (status) => {
- const types = {
- '宸查�氳繃': 'success',
- '瀹℃壒涓�': 'warning',
- '宸叉嫆缁�': 'danger'
- }
- return types[status] || 'info'
-}
-
-// 鏂板鑰冨嫟璁板綍锛堟墦寮�寮圭獥骞堕濉粯璁ゅ�硷級
-const addAttendanceRecord = () => {
- operationType.value = 'add'
- attendanceForm.date = new Date().toISOString().split('T')[0]
- attendanceForm.checkIn = '09:00'
- attendanceForm.checkOut = '18:00'
- attendanceForm.status = '姝e父'
- showAttendanceDialog.value = true
-}
-
-// 璁$畻宸ユ椂
-const computeWorkHours = (inStr, outStr) => {
- const [inH, inM] = inStr.split(':').map(n => parseInt(n, 10))
- const [outH, outM] = outStr.split(':').map(n => parseInt(n, 10))
- const inMin = inH * 60 + inM
- const outMin = outH * 60 + outM
- const diff = Math.max(0, outMin - inMin)
- const h = Math.floor(diff / 60)
- const m = diff % 60
- return m === 0 ? `${h}灏忔椂` : `${h}灏忔椂${m}鍒哷
-}
-
-// 缂栬緫鑰冨嫟璁板綍
-const editAttendanceRecord = (row) => {
- operationType.value = 'edit'
- Object.assign(attendanceForm, row)
- showAttendanceDialog.value = true
-}
-// 鎻愪氦鏂板-缂栬緫鑰冨嫟璁板綍
-const submitAttendance = () => {
- // if (!attendanceFormRef.value) return
- const workHours = computeWorkHours(attendanceForm.checkIn, attendanceForm.checkOut)
- const newRecord = {
- date: attendanceForm.date,
- checkIn: attendanceForm.checkIn,
- checkOut: attendanceForm.checkOut,
- workHours,
- status: attendanceForm.status
- }
- if (operationType.value === 'add') {
- personalAttendanceRecordsAdd(newRecord)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鑰冨嫟璁板綍娣诲姞鎴愬姛')
- getPersonalAttendanceRecordsList()
- showAttendanceDialog.value = false
- // 閲嶇疆琛ㄥ崟
- attendanceForm.date = ''
- attendanceForm.checkIn = ''
- attendanceForm.checkOut = ''
- attendanceForm.status = '姝e父'
- }
- }).catch(err => {
- ElMessage.error('鑰冨嫟璁板綍娣诲姞澶辫触')
- })
- }else{
- attendanceForm.workHours = computeWorkHours(attendanceForm.checkIn, attendanceForm.checkOut)
- personalAttendanceRecordsUpdate(attendanceForm)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鑰冨嫟璁板綍鏇存柊鎴愬姛')
- getPersonalAttendanceRecordsList()
- showAttendanceDialog.value = false
- // 閲嶇疆琛ㄥ崟
- attendanceForm.date = ''
- attendanceForm.checkIn = ''
- attendanceForm.checkOut = ''
- attendanceForm.status = '姝e父'
- }
- }).catch(err => {
- ElMessage.error('鑰冨嫟璁板綍鏇存柊澶辫触')
- })
- }
- // attendanceFormRef.value.validate((valid) => {
- // if (!valid) return
-
-
- // })
-}
-// 鍒犻櫎鑰冨嫟璁板綍
-const deleteAttendanceRecord = (row) => {
-
- ElMessageBox.confirm('纭畾鍒犻櫎璇ヨ�冨嫟璁板綍鍚楋紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- personalAttendanceRecordsDelete(row.id)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鑰冨嫟璁板綍鍒犻櫎鎴愬姛')
- getPersonalAttendanceRecordsList()
- }
- }).catch(err => {
- ElMessage.error('鑰冨嫟璁板綍鍒犻櫎澶辫触')
- })
- }).catch(() => {
- ElMessage({
- type: 'info',
- message: '宸插彇娑堝垹闄�'
- })
- })
-}
-// 鐢宠鍋囨湡
-const openLeaveForm = () => {
- leaveOperationType.value = 'add'
- showLeaveDialog.value = true
- // leaveForm.type = ''
- // leaveForm.startDate = ''
- // leaveForm.endDate = ''
- // leaveForm.days = 0
- // leaveForm.reason = ''
- // leaveForm.status = 'warning'
-}
-// 缂栬緫鍋囨湡璁板綍
-const editLeaveRecord = (row) => {
- leaveOperationType.value = 'edit'
- showLeaveDialog.value = true
- Object.assign(leaveForm, row)
- // ElMessage.info('缂栬緫鍔熻兘寮�鍙戜腑...')
-}
-
-// 鍒犻櫎鍋囨湡璁板綍
-const deleteLeaveRecord = (row) => {
- ElMessageBox.confirm('纭畾鍒犻櫎璇ュ亣鏈熻褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- holidayApplicationDelete(row.id)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鍋囨湡璁板綍鍒犻櫎鎴愬姛')
- getHolidayApplicationList()
- }
- }).catch(err => {
- ElMessage.error('鍋囨湡璁板綍鍒犻櫎澶辫触')
- })
- }).catch(() => {
- ElMessage({
- type: 'info',
- message: '宸插彇娑堝垹闄�'
- })
- })
-}
-
-//璁$畻鍋囨湡澶╂暟
-const calculateDays = () => {
- try {
- if (leaveForm.startDate && leaveForm.endDate) {
- const start = new Date(leaveForm.startDate)
- const end = new Date(leaveForm.endDate)
- leaveForm.startDate = start.toISOString().split('T')[0]
- leaveForm.endDate = end.toISOString().split('T')[0]
-
- if (isNaN(start.getTime()) || isNaN(end.getTime())) {
- console.warn('鏃犳晥鐨勬棩鏈熸牸寮�')
- return
- }
-
- const diffTime = Math.abs(end - start)
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1
- leaveForm.days = diffDays
- }
- } catch (error) {
- console.error('璁$畻澶╂暟澶辫触:', error)
- }
-}
-
-// 鎻愪氦鍋囨湡鐢宠
-const submitLeaveApplication = () => {
- if (leaveOperationType.value === 'add') {
- if (!leaveForm.type || !leaveForm.startDate || !leaveForm.endDate || !leaveForm.reason) {
- ElMessage.warning('璇峰~鍐欏畬鏁翠俊鎭�')
- return
- }
- calculateDays()
- const newLeave = {
- type: leaveForm.type,
- startDate: leaveForm.startDate,
- endDate: leaveForm.endDate,
- days: leaveForm.days, // 绠�鍗曡绠�
- reason: leaveForm.reason,
- status: '瀹℃壒涓�'
- }
-
- holidayApplicationAdd(newLeave)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鍋囨湡鐢宠鎻愪氦鎴愬姛')
- getHolidayApplicationList()
- showLeaveDialog.value = false
- // 閲嶇疆琛ㄥ崟
- Object.keys(leaveForm).forEach(key => {
- leaveForm[key] = ''
- })
- }
- }).catch(err => {
- ElMessage.error('鍋囨湡鐢宠鎻愪氦澶辫触')
- })
- }else{
- calculateDays()
- holidayApplicationUpdate(leaveForm)
- .then(res => {
- if (res.code === 200) {
- ElMessage.success('鍋囨湡鐢宠鏇存柊鎴愬姛')
- getHolidayApplicationList()
- showLeaveDialog.value = false
- // 閲嶇疆琛ㄥ崟
- Object.keys(leaveForm).forEach(key => {
- leaveForm[key] = ''
- })
- }
- }).catch(err => {
- ElMessage.error('鍋囨湡鐢宠鏇存柊澶辫触')
- })
- }
-}
-
-// 鑾峰彇涓汉淇℃伅
-const getProfile = () => {
- tableLoading.value = true;
- getUserProfile().then(res => {
- if (res.code === 200) {
- currentUser.value = res.data
- // console.log("----",currentUser.value)
- //寰楀埌浜哄憳鍒楄〃
- staffJoinListPage({staffState: 1}).then(res => {
- //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
- // let tableData = res.data.records
- user.value = res.data.records.find(item => item.staffName === currentUser.value.userName)
- // console.log("++++",user.value)
- if(user.value){
- profile.value.id=user.value.id
- profile.value.name=user.value.staffName
- profile.value.employeeId=user.value.staffNo
- profile.value.phone=user.value.phone
- profile.value.email=currentUser.value.email
- profile.value.adress=user.value.adress
- profile.value.position=user.value.postJob
- profile.value.hireDate=user.value.createTime
- profile.value.department=currentUser.value.deptNames
- }
- // console.log(profile.value)
- // tableLoading.value = false;
- }).catch(err => {})
- }
- }).catch(err => {
- tableLoading.value = false;
- ElMessage.error('鑾峰彇涓汉淇℃伅澶辫触')
- })
-}
-// 淇濆瓨涓汉淇℃伅
-const saveProfile = async () => {
- tableLoading.value = true;
- try {
- const userRes = await getUserProfile();
- if (userRes.code === 200) {
- currentUser.value = userRes.data;
- const staffListRes = await staffJoinListPage({ staffState: 1 });
- user.value = staffListRes.data.records.find(item => item.staffName === currentUser.value.userName);
- // console.log("++++", user.value);
-
- Object.assign(joinForm, user.value);
- joinForm.staffName = profileForm.name;
- joinForm.phone = profileForm.phone;
- joinForm.email = profileForm.email;
- joinForm.adress = profileForm.adress;
- console.log(joinForm)
- // 璋冪敤鏇存柊涓汉淇℃伅鐨勬帴鍙�
- staffJoinUpdate(joinForm).then(res => {
- if (res.code === 200) {
- ElMessage.success('涓汉淇℃伅淇濆瓨鎴愬姛');
- getProfile();
- editProfile.value = false;
- }
- }).catch(err => {
- ElMessage.error('涓汉淇℃伅淇濆瓨澶辫触');
- })
- }
- } catch (err) {
- ElMessage.error('鑾峰彇涓汉淇℃伅澶辫触');
- } finally {
- tableLoading.value = false;
- }
-};
-
-// 缂栬緫涓汉淇℃伅
-const editProfileForm = () => {
- editProfile.value = true;
- Object.assign(profileForm, {
- name: profile.value.name,
- phone: profile.value.phone,
- email: profile.value.email,
- adress: profile.value.adress,
- });
-};
-
-//鏈堜唤鏀瑰彉
-const changMonth = () => {
- getCompensationList()
-}
-//鑾峰彇鑰冨嫟璁板綍鍒楄〃
-const getPersonalAttendanceRecordsList = async () => {
- tableLoading.value = true
- personalAttendanceRecordsListPage(page)
- .then(res => {
-
- attendanceData.value = res.data.records
- page.value.total = res.data.total;
- tableLoading.value = false;
-
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-//钖祫鍗曟煡璇�
-const getCompensationList = async () => {
- tableLoading.value = true
- compensationListPage({...page,payDateStr:payDateStr.value})
- .then(res => {
- salaryData.value = res.data.records
- //杩囨护鍑哄綋鍓嶆湀浠界殑鎵f鍚堣
- salaryData.value.forEach(item => {
- item.deduction =0 + item.deductionAbsenteeism+item.sickLeaveDeductions+item.deductionPersonalLeave+item.forgetClockDeduct,
- item.bonus=0,
- item.status='宸插彂鏀�'
- })
-
- page.value.total = res.data.total;
- tableLoading.value = false;
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-//鑾峰彇鍋囨湡鐢宠鍒楄〃
-const getHolidayApplicationList = async () => {
- tableLoading.value = true
- holidayApplicationListPage(page)
- .then(res => {
- leaveData.value = res.data.records
- page.value.total = res.data.total;
- tableLoading.value = false;
- }).catch(err => {
- tableLoading.value = false;
- })
-}
-onMounted(() => {
- // 鍒濆鍖�
- getPersonalAttendanceRecordsList()
- getCompensationList()
- getHolidayApplicationList()
- getProfile()
-})
-</script>
-
-<style scoped>
-.self-service-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- color: white;
-}
-
-.page-header h2 {
- color: white;
- margin-bottom: 10px;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- color: rgba(255, 255, 255, 0.9);
- font-size: 14px;
- margin: 0;
-}
-
-.nav-cards {
- margin-bottom: 30px;
-}
-
-.nav-card {
- cursor: pointer;
- transition: all 0.3s ease;
- border-radius: 12px;
- border: none;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.nav-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
-}
-
-.nav-content {
- text-align: center;
- padding: 20px;
-}
-
-.nav-icon {
- color: #409EFF;
- margin-bottom: 15px;
-}
-
-.nav-content h3 {
- margin: 0 0 10px 0;
- color: #303133;
- font-size: 18px;
-}
-
-.nav-content p {
- margin: 0;
- color: #909399;
- font-size: 14px;
-}
-
-.main-content {
- margin-bottom: 30px;
-}
-
-.content-card {
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- border: none;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: 600;
- color: #303133;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .self-service-container {
- padding: 10px;
- }
-
- .nav-cards .el-col {
- margin-bottom: 15px;
- }
-
- .page-header h2 {
- font-size: 24px;
- }
-}
-</style>
diff --git a/src/views/procurementManagement/advancedPriceManagement/index.vue b/src/views/procurementManagement/advancedPriceManagement/index.vue
deleted file mode 100644
index 597b39b..0000000
--- a/src/views/procurementManagement/advancedPriceManagement/index.vue
+++ /dev/null
@@ -1,784 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true" label-width="100px">
- <el-form-item label="鍟嗗搧鍚嶇О锛�">
- <el-input v-model="searchForm.productName" placeholder="璇疯緭鍏ュ晢鍝佸悕绉�" clearable style="width: 200px" />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗭細">
- <el-select v-model="searchForm.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px">
- <el-option v-for="supplier in supplierList" :key="supplier.id" :label="supplier.name" :value="supplier.id" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch" :loading="loading">
- <el-icon><Search /></el-icon>
- 鎼滅储
- </el-button>
- <el-button @click="resetSearch">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 鍔熻兘鎸夐挳鍖哄煙 -->
- <el-card class="action-card" shadow="never">
- <div class="action-buttons">
- <el-button type="primary" @click="openDialog('add')">
- <el-icon><Plus /></el-icon>
- 鏂板浠锋牸
- </el-button>
- <el-button type="success" @click="openBatchDiscountDialog">
- <el-icon><Discount /></el-icon>
- 鎵归噺鎶樻墸
- </el-button>
- <el-button type="info" @click="exportData">
- <el-icon><Download /></el-icon>
- 瀵煎嚭鏁版嵁
- </el-button>
- <el-button type="danger" @click="handleBatchDelete" :disabled="selectedRows.length === 0">
- <el-icon><Delete /></el-icon>
- 鎵归噺鍒犻櫎
- </el-button>
- </div>
- </el-card>
-
-
- <!-- 涓昏〃鏍� -->
- <el-card class="table-card" shadow="never">
- <el-table
- :data="tableData"
- border
- v-loading="loading"
- @selection-change="handleSelectionChange"
- :default-sort="{ prop: 'updateTime', order: 'descending' }"
- >
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="鍟嗗搧淇℃伅" min-width="200">
- <template #default="{ row }">
- <div class="product-info">
- <div class="product-name">{{ row.productName }}</div>
- <div class="product-spec">{{ row.specification }}</div>
- <div class="product-code">缂栫爜: {{ row.productCode }}</div>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="150" />
- <el-table-column label="鍩虹浠锋牸" width="120" align="right">
- <template #default="{ row }">
- <span class="price-text">楼{{ row.basePrice }}</span>
- </template>
- </el-table-column>
- <el-table-column label="鎶樻墸淇℃伅" width="150">
- <template #default="{ row }">
- <div v-if="row.discountType">
- <el-tag :type="getDiscountTagType(row.discountType)" size="small">
- {{ getDiscountText(row.discountType) }}
- </el-tag>
- <div class="discount-value">{{ row.discountValue }}{{ row.discountType === 'percentage' ? '%' : '鍏�' }}</div>
- </div>
- <span v-else class="no-discount">鏃犳姌鎵�</span>
- </template>
- </el-table-column>
- <el-table-column label="瀹為檯浠锋牸" width="120" align="right">
- <template #default="{ row }">
- <span class="final-price">楼{{ calculateFinalPrice(row) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="浠锋牸鎺у埗" width="120">
- <template #default="{ row }">
- <div class="price-control">
- <div v-if="row.minPrice" class="control-item">
- 鏈�浣�: 楼{{ row.minPrice }}
- </div>
- <div v-if="row.maxPrice" class="control-item">
- 鏈�楂�: 楼{{ row.maxPrice }}
- </div>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鐘舵��" width="100" align="center">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- <div v-if="isPriceWarning(row)" class="warning-indicator">
- <el-icon color="#F56C6C"><Warning /></el-icon>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="180" />
- <el-table-column label="鏇存柊鏃堕棿" prop="updateTime" width="180" sortable />
- <el-table-column label="鎿嶄綔" width="250" align="center" fixed="right">
- <template #default="{ row }">
- <el-button type="primary" link @click="openDialog('edit', row)">
- <el-icon><Edit /></el-icon>
- 缂栬緫
- </el-button>
- <el-button type="danger" link @click="handleDelete(row)">
- <el-icon><Delete /></el-icon>
- 鍒犻櫎
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <div class="pagination-wrapper">
- <el-pagination
- v-model:current-page="pagination.current"
- v-model:page-size="pagination.size"
- :page-sizes="[10, 20, 50, 100]"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" width="800px">
- <el-form :model="formData" :rules="formRules" ref="formRef" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍟嗗搧鍚嶇О" prop="productName">
- <el-select v-model="formData.productName" placeholder="璇烽�夋嫨鍟嗗搧" style="width: 100%" filterable>
- <el-option v-for="product in productList" :key="product.id" :label="product.name" :value="product.name" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍟嗗搧缂栫爜" prop="productCode">
- <el-input v-model="formData.productCode" placeholder="璇疯緭鍏ュ晢鍝佺紪鐮�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
- <el-input v-model="formData.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟�" prop="supplierName">
- <el-select v-model="formData.supplierName" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%">
- <el-option v-for="supplier in supplierList" :key="supplier.id" :label="supplier.name" :value="supplier.name" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍩虹浠锋牸" prop="basePrice">
- <el-input-number v-model="formData.basePrice" :min="0" :precision="2" placeholder="璇疯緭鍏ュ熀纭�浠锋牸" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍗曚綅">
- <el-input v-model="formData.unit" placeholder="璇疯緭鍏ュ崟浣�" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <!-- 鎶樻墸璁剧疆 -->
- <el-divider content-position="left">鎶樻墸璁剧疆</el-divider>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鎶樻墸绫诲瀷">
- <el-select v-model="formData.discountType" placeholder="璇烽�夋嫨鎶樻墸绫诲瀷" style="width: 100%">
- <el-option label="鏃犳姌鎵�" value="" />
- <el-option label="鐧惧垎姣旀姌鎵�" value="percentage" />
- <el-option label="鍥哄畾閲戦" value="fixed" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎶樻墸鍊�" v-if="formData.discountType && formData.discountType !== 'tiered'">
- <el-input-number
- v-model="formData.discountValue"
- :min="0"
- :max="formData.discountType === 'percentage' ? 100 : undefined"
- :precision="2"
- placeholder="璇疯緭鍏ユ姌鎵e��"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎶樻墸鏈夋晥鏈�">
- <el-date-picker
- v-model="formData.discountEndTime"
- type="datetime"
- placeholder="閫夋嫨缁撴潫鏃堕棿"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <!-- 浠锋牸鎺у埗 -->
- <el-divider content-position="left">浠锋牸鎺у埗</el-divider>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鏈�浣庝环鏍�">
- <el-input-number v-model="formData.minPrice" :min="0" :precision="2" placeholder="鏈�浣庝环鏍�" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鏈�楂樹环鏍�">
- <el-input-number v-model="formData.maxPrice" :min="0" :precision="2" placeholder="鏈�楂樹环鏍�" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="棰勮闃堝��(%)">
- <el-input-number v-model="formData.warningThreshold" :min="0" :max="100" :precision="1" placeholder="棰勮闃堝��" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐢熸晥鏃堕棿" prop="effectiveTime">
- <el-date-picker v-model="formData.effectiveTime" type="datetime" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="澶辨晥鏃堕棿">
- <el-date-picker v-model="formData.expireTime" type="datetime" placeholder="閫夋嫨澶辨晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="璋冧环鍘熷洜" prop="reason">
- <el-select v-model="formData.reason" placeholder="璇烽�夋嫨璋冧环鍘熷洜" style="width: 100%">
- <el-option label="甯傚満浠锋牸鍙樺姩" value="market" />
- <el-option label="鎴愭湰鍙樺寲" value="cost" />
- <el-option label="渚涘簲鍟嗚皟鏁�" value="supplier" />
- <el-option label="瀛h妭鎬ц皟鏁�" value="seasonal" />
- <el-option label="淇冮攢娲诲姩" value="promotion" />
- <el-option label="鍏朵粬鍘熷洜" value="other" />
- </el-select>
- </el-form-item>
-
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
- </template>
- </el-dialog>
-
- <!-- 鎵归噺鎶樻墸瀵硅瘽妗� -->
- <el-dialog v-model="batchDiscountVisible" title="鎵归噺璁剧疆鎶樻墸" width="600px">
- <el-form :model="batchDiscountForm" label-width="120px">
- <el-form-item label="鎶樻墸绫诲瀷">
- <el-select v-model="batchDiscountForm.discountType" placeholder="璇烽�夋嫨鎶樻墸绫诲瀷" style="width: 100%">
- <el-option label="鐧惧垎姣旀姌鎵�" value="percentage" />
- <el-option label="鍥哄畾閲戦" value="fixed" />
- </el-select>
- </el-form-item>
- <el-form-item label="鎶樻墸鍊�">
- <el-input-number
- v-model="batchDiscountForm.discountValue"
- :min="0"
- :max="batchDiscountForm.discountType === 'percentage' ? 100 : undefined"
- :precision="2"
- placeholder="璇疯緭鍏ユ姌鎵e��"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="鐢熸晥鏃堕棿">
- <el-date-picker v-model="batchDiscountForm.effectiveTime" type="datetime" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- <el-form-item label="澶辨晥鏃堕棿">
- <el-date-picker v-model="batchDiscountForm.expireTime" type="datetime" placeholder="閫夋嫨澶辨晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- <el-form-item label="閫傜敤鍟嗗搧">
- <div class="selected-items">
- 宸查�夋嫨 {{ selectedRows.length }} 涓晢鍝�
- </div>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="batchDiscountVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleBatchDiscount">纭畾</el-button>
- </template>
- </el-dialog>
-
- <!-- 浠锋牸鎺у埗瀵硅瘽妗� -->
- <el-dialog v-model="priceControlVisible" title="浠锋牸鎺у埗璁剧疆" width="700px">
- <el-form :model="priceControlForm" label-width="120px">
- <el-form-item label="榛樿鏈�浣庝环鏍�">
- <el-input-number v-model="priceControlForm.defaultMinPrice" :min="0" :precision="2" style="width: 200px" />
- </el-form-item>
- <el-form-item label="榛樿鏈�楂樹环鏍�">
- <el-input-number v-model="priceControlForm.defaultMaxPrice" :min="0" :precision="2" style="width: 200px" />
- </el-form-item>
- <el-form-item label="浠锋牸鍙樺姩闃堝��">
- <el-input-number v-model="priceControlForm.changeThreshold" :min="0" :max="100" :precision="1" style="width: 200px" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="priceControlVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handlePriceControl">淇濆瓨璁剧疆</el-button>
- </template>
- </el-dialog>
-
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {
- Search, Refresh, Plus, Discount, Setting, Download, Delete, Edit,
- Warning
-} from '@element-plus/icons-vue'
-import { listPage, update, del, add } from '@/api/procurementManagement/advancedPriceManagement'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const submitLoading = ref(false)
-const dialogVisible = ref(false)
-const batchDiscountVisible = ref(false)
-const priceControlVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-const formRef = ref()
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- productName: '',
- supplierId: ''
-})
-
-const total = ref(0)
-
-// 鍒嗛〉
-const pagination = reactive({
- current: 1,
- size: 10
-})
-
-
-// 琛ㄥ崟鏁版嵁
-const formData = reactive({
- productName: '',
- productCode: '',
- specification: '',
- supplierName: '',
- basePrice: 0,
- unit: '',
- discountType: '',
- discountValue: 0,
- discountEndTime: '',
- tieredDiscount: [],
- minPrice: null,
- maxPrice: null,
- warningThreshold: 10,
- effectiveTime: '',
- expireTime: '',
- reason: '',
- remark: ''
-})
-
-const tableData = ref([])
-
-// 鎵归噺鎶樻墸琛ㄥ崟
-const batchDiscountForm = reactive({
- discountType: 'percentage',
- discountValue: 0,
- effectiveTime: '',
- expireTime: ''
-})
-
-// 浠锋牸鎺у埗琛ㄥ崟
-const priceControlForm = reactive({
- defaultMinPrice: 0,
- defaultMaxPrice: 0,
- changeThreshold: 10,
-})
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = {
- productName: [{ required: true, message: '璇烽�夋嫨鍟嗗搧鍚嶇О', trigger: 'change' }],
- productCode: [{ required: true, message: '璇疯緭鍏ュ晢鍝佺紪鐮�', trigger: 'blur' }],
- supplierName: [{ required: true, message: '璇烽�夋嫨渚涘簲鍟�', trigger: 'change' }],
- basePrice: [{ required: true, message: '璇疯緭鍏ュ熀纭�浠锋牸', trigger: 'blur' }],
- effectiveTime: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃堕棿', trigger: 'change' }],
- reason: [{ required: true, message: '璇烽�夋嫨璋冧环鍘熷洜', trigger: 'change' }]
-}
-
-const supplierList = ref([
- { id: 1, name: '浼樿川浜旈噾渚涘簲鍟�' },
- { id: 2, name: '閽㈡潗璐告槗鍏徃' },
- { id: 3, name: '寤烘潗鎵瑰彂鍟�' }
-])
-
-const productList = ref([
- { id: 1, name: '楂樺己搴﹁灪鏍�' },
- { id: 2, name: '涓嶉攬閽㈢' },
- { id: 3, name: '閾濆悎閲戝瀷鏉�' }
-])
-
-
-// 鏂规硶
-const calculateFinalPrice = (row) => {
- let finalPrice = row.basePrice
- if (row.discountType === 'percentage') {
- finalPrice = row.basePrice * (1 - row.discountValue / 100)
- } else if (row.discountType === 'fixed') {
- finalPrice = row.basePrice - row.discountValue
- }
- return Math.max(finalPrice, 0)
-}
-
-const getDiscountTagType = (discountType) => {
- const typeMap = {
- percentage: 'success',
- fixed: 'warning',
- tiered: 'info'
- }
- return typeMap[discountType] || 'info'
-}
-
-const getDiscountText = (discountType) => {
- const textMap = {
- percentage: '鐧惧垎姣�',
- fixed: '鍥哄畾閲戦'
- }
- return textMap[discountType] || '鏈煡'
-}
-
-const getStatusType = (status) => {
- const statusMap = {
- active: 'success',
- pending: 'warning',
- expired: 'info'
- }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = {
- active: '鏈夋晥',
- pending: '寰呯敓鏁�',
- expired: '宸茶繃鏈�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-const isPriceWarning = (row) => {
- if (!row.priceControl) return false
- const finalPrice = calculateFinalPrice(row)
- return finalPrice < row.priceControl.minPrice || finalPrice > row.priceControl.maxPrice
-}
-
-
-const handleSearch = () => {
- loading.value = true
- // 妯℃嫙API璋冪敤
- listPage({ ...searchForm, ...pagination}).then(res => {
- tableData.value = res.data.records
- total.value = res.data.total
- loading.value = false
- })
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, {
- productName: '',
- supplierId: ''
- })
- handleSearch()
-}
-
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- if (type === 'edit' && row.id) {
- Object.assign(formData, {
- ...row,
- minPrice: row.priceControl?.minPrice,
- maxPrice: row.priceControl?.maxPrice,
- tieredDiscount: row.tieredDiscount || []
- })
- } else {
- resetFormData()
- }
- dialogVisible.value = true
-}
-
-const resetFormData = () => {
- Object.assign(formData, {
- productName: '',
- productCode: '',
- specification: '',
- supplierName: '',
- basePrice: 0,
- unit: '',
- discountType: '',
- discountValue: 0,
- discountEndTime: '',
- tieredDiscount: [],
- minPrice: null,
- maxPrice: null,
- warningThreshold: 10,
- effectiveTime: '',
- expireTime: '',
- reason: '',
- remark: ''
- })
-}
-
-const addTieredRow = () => {
- formData.tieredDiscount.push({
- minQty: 0,
- maxQty: 0,
- discount: 0
- })
-}
-
-const removeTieredRow = (index) => {
- formData.tieredDiscount.splice(index, 1)
-}
-
-const handleSubmit = async () => {
- if (!formRef.value) return
-
- try {
- await formRef.value.validate()
- submitLoading.value = true
-
- if (dialogType.value === 'add') {
- add(formData).then(res => {
- if (res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- handleSearch()
- }
- })
- } else {
- update(formData).then(res => {
- if (res.code === 200){
- ElMessage.success('缂栬緫鎴愬姛')
- handleSearch()
- }
- })
- }
-
- } catch (error) {
- console.error('琛ㄥ崟楠岃瘉澶辫触:', error)
- }finally {
- dialogVisible.value = false
- submitLoading.value = false
- }
-}
-
-const openBatchDiscountDialog = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning('璇峰厛閫夋嫨瑕佽缃姌鎵g殑鍟嗗搧')
- return
- }
- batchDiscountVisible.value = true
-}
-
-const handleBatchDiscount = () => {
- // 鎵归噺璁剧疆鎶樻墸閫昏緫
- selectedRows.value.forEach(row => {
- row.discountType = batchDiscountForm.discountType
- row.discountValue = batchDiscountForm.discountValue
- update(row).then(res => {
- handleSearch()
- })
- })
- ElMessage.success('鎶樻墸璁剧疆鎴愬姛')
- batchDiscountVisible.value = false
-
-}
-
-const openPriceControlDialog = () => {
- priceControlVisible.value = true
-}
-
-const handlePriceControl = () => {
- ElMessage.success('浠锋牸鎺у埗璁剧疆宸蹭繚瀛�')
- priceControlVisible.value = false
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- del(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- handleSearch()
- }
- })
- })
-}
-
-const handleBatchDelete = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning('璇峰厛閫夋嫨瑕佸垹闄ょ殑璁板綍')
- return
- }
-
- ElMessageBox.confirm(`纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉¤褰曞悧锛焋, '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- del(selectedRows.value.map(item => item.id)).then(i =>{
- if(i.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- handleSearch()
- }
- })
- })
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-
-const handleSizeChange = (size) => {
- pagination.size = size
- handleSearch()
-}
-
-const handleCurrentChange = (page) => {
- pagination.current = page
- handleSearch()
-}
-const { proxy } = getCurrentInstance();
-
-const exportData = () => {
- ElMessageBox.confirm("鍐呭灏嗚瀵煎嚭锛屾槸鍚︾‘璁ゅ鍑猴紵", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/procurementPriceManagement/export", {}, "閲囪喘浠锋牸绠$悊.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- handleSearch()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.search-card, .action-card, .table-card {
- margin-bottom: 20px;
-}
-
-.action-buttons {
- display: flex;
- gap: 10px;
- flex-wrap: wrap;
-}
-
-
-.product-info {
- line-height: 1.4;
-}
-
-.product-name {
- font-weight: bold;
- color: #303133;
-}
-
-.product-spec, .product-code {
- font-size: 12px;
- color: #909399;
-}
-
-.price-text {
- font-weight: bold;
- color: #409EFF;
-}
-
-.final-price {
- font-weight: bold;
- color: #67C23A;
- font-size: 16px;
-}
-
-.discount-value {
- font-size: 12px;
- color: #E6A23C;
- margin-top: 2px;
-}
-
-.no-discount {
- color: #C0C4CC;
- font-size: 12px;
-}
-
-.price-control {
- font-size: 12px;
- line-height: 1.3;
-}
-
-.control-item {
- color: #909399;
-}
-
-.warning-indicator {
- margin-top: 2px;
-}
-
-.pagination-wrapper {
- display: flex;
- justify-content: end;
- margin-top: 20px;
-}
-
-.selected-items {
- color: #409EFF;
- font-weight: bold;
-}
-
-
-.mt-2 {
- margin-top: 8px;
-}
-
-.ml-2 {
- margin-left: 8px;
-}
-
-:deep(.el-table) {
- font-size: 13px;
-}
-
-:deep(.el-table th) {
- background-color: #fafafa;
-}
-
-:deep(.el-card__body) {
- padding: 15px;
-}
-
-:deep(.el-divider__text) {
- font-weight: bold;
- color: #409EFF;
-}
-</style>
diff --git a/src/views/procurementManagement/arrivalManagement/index.vue b/src/views/procurementManagement/arrivalManagement/index.vue
deleted file mode 100644
index 060d2f1..0000000
--- a/src/views/procurementManagement/arrivalManagement/index.vue
+++ /dev/null
@@ -1,240 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="閲囪喘璁㈠崟鍙凤細">
- <el-input v-model="searchForm.orderNo" placeholder="璇疯緭鍏ヨ鍗曞彿" clearable />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О" clearable />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <el-button type="primary" @click="openDialog('add')">鏂板鍒拌揣</el-button>
- <el-button type="danger" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
- </div>
-
- <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="鍒拌揣鍗曞彿" prop="arrivalNo" width="180" />
- <el-table-column label="閲囪喘璁㈠崟鍙�" prop="orderNo" width="180" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column label="鍒拌揣鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍒拌揣鏁伴噺" prop="arrivalQuantity" width="100" />
- <el-table-column label="鍒拌揣鏃堕棿" prop="arrivalTime" width="180" />
- <el-table-column label="鎿嶄綔" width="200" align="center">
- <template #default="{ row }">
- <el-button type="primary" link @click="openDialog('edit', row)">缂栬緫</el-button>
- <el-button type="success" v-if="row.status === 'pending'" link @click="handleReceive(row)">鏀惰揣</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- <!-- 鍒嗛〉 -->
- <pagination
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.current"
- :limit="pagination.size"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板鍒拌揣' : '缂栬緫鍒拌揣'" width="600px">
- <el-form :model="formData" label-width="120px">
- <el-form-item label="鍒拌揣鍗曞彿">
- <el-input v-model="formData.arrivalNo" placeholder="鍒拌揣鍗曞彿" />
- </el-form-item>
- <el-form-item label="閲囪喘璁㈠崟鍙�">
- <el-input v-model="formData.orderNo" placeholder="閲囪喘璁㈠崟鍙�" />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-input v-model="formData.supplierName" placeholder="渚涘簲鍟嗗悕绉�" />
- </el-form-item>
- <el-form-item label="鍒拌揣鏁伴噺">
- <el-input-number :min="0" v-model="formData.arrivalQuantity" placeholder="鍒拌揣鏁伴噺" />
- </el-form-item>
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive,onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {listPage,add,update,del} from "@/api/procurementManagement/arrivalManagement.js"
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-onMounted(() => {
- getList()
-})
-
-const tableData = ref([])
-
-const getList = () => {
- loading.value = true
- listPage({...searchForm,...pagination}).then(res =>{
- if(res.code === 200){
- tableData.value = res.data.records
- total.value = res.data.total
- loading.value = false
- }
- })
-}
-
-const pagination = reactive({
- current: 1,
- size: 10
-})
-
-const total = ref(0)
-
-const handleCurrentChange = (val) => {
- pagination.current = val.page
- pagination.size = val.limit
- getList()
-}
-
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-
-const searchForm = reactive({
- orderNo: '',
- supplierName: ''
-})
-
-const formData = reactive({
- arrivalNo: '',
- arrivalQuantity: 0,
- orderNo: '',
- supplierName: '',
- remark: '',
- status: 'pending'
-})
-
-const getStatusType = (status) => {
- const statusMap = { pending: 'warning', received: 'success', stored: 'info' }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = { pending: '寰呮敹璐�', received: '宸叉敹璐�', stored: '宸插叆搴�' }
- return statusMap[status] || '鏈煡'
-}
-
-const handleSearch = () => {
- loading.value = true
- getList()
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, { orderNo: '', supplierName: '' })
-}
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- if (type === 'edit' && row.id) {
- obj.id = row.id
- Object.assign(formData, { orderNo: row.orderNo, supplierName: row.supplierName, remark: row.remark, arrivalQuantity: row.arrivalQuantity,arrivalNo: row.arrivalNo })
- } else {
- Object.assign(formData, { orderNo: '', supplierName: '', remark: '',arrivalQuantity: 0,arrivalNo: '' })
- }
- dialogVisible.value = true
-}
-
-const obj = reactive({
- id:''
-})
-
-const handleSubmit = () => {
- if (dialogType.value === 'add') {
- add(formData).then(res => {
- if(res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- getList()
- }
- })
- }else{
- update({...formData, ...obj}).then(res => {
- if(res.code === 200){
- ElMessage.success('缂栬緫鎴愬姛')
- getList()
- }
- })
- }
- dialogVisible.value = false
-}
-
-const handleReceive = (row) => {
- row.status = 'received'
- update(row).then(res => {
- if(res.code === 200){
- ElMessage.success('鏀惰揣鎴愬姛')
- getList()
- }
- })
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- del(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- }
- })
- })
-}
-
-const handleBatchDelete = () => {
- ElMessageBox.confirm('纭畾瑕佸垹闄ら�変腑鐨勮褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = selectedRows.value.map(item => item.id)
- del(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- }
- })
- })
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-</script>
-
-<style scoped>
-.app-container { padding: 20px; }
-.search-card { margin-bottom: 20px; }
-.table-card { margin-bottom: 20px; }
-.table-header { margin-bottom: 20px; }
-</style>
diff --git a/src/views/procurementManagement/index.vue b/src/views/procurementManagement/index.vue
deleted file mode 100644
index bf54384..0000000
--- a/src/views/procurementManagement/index.vue
+++ /dev/null
@@ -1,418 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>閲囪喘绠$悊绯荤粺</h2>
- <p>缁熶竴绠$悊閲囪喘鍏ㄦ祦绋嬶紝鎻愬崌閲囪喘鏁堢巼涓庤川閲�</p>
- </div>
-
- <!-- 鍔熻兘妯″潡鍗$墖 -->
- <el-row :gutter="20" class="module-cards">
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/purchaseOrder')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#409EFF"><Document /></el-icon>
- </div>
- <div class="card-info">
- <h3>閲囪喘璁㈠崟绠$悊</h3>
- <p>鏂板缓銆佺紪杈戙�佸垹闄ら噰璐鍗曪紝閫夋嫨渚涘簲鍟嗭紝濉啓鍟嗗搧鏄庣粏</p>
- <div class="card-stats">
- <span>寰呭鏍�: {{ stats.pendingOrders }}</span>
- <span>宸插鏍�: {{ stats.approvedOrders }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/arrivalManagement')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#67C23A"><Box /></el-icon>
- </div>
- <div class="card-info">
- <h3>鍒拌揣绠$悊</h3>
- <p>鑷姩鍏宠仈閲囪喘璁㈠崟锛屽綍鍏ュ埌璐у晢鍝佷俊鎭紝鏀寔鎵撳嵃鏌ョ湅</p>
- <div class="card-stats">
- <span>寰呮敹璐�: {{ stats.pendingArrivals }}</span>
- <span>宸叉敹璐�: {{ stats.receivedArrivals }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/qualityInspection')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#E6A23C"><Search /></el-icon>
- </div>
- <div class="card-info">
- <h3>璐ㄦ绠$悊</h3>
- <p>鍒拌揣鍚庤嚜鍔ㄧ敓鎴愯川妫�鍗曪紝濉啓鍚堟牸涓庝笉鍚堟牸鍟嗗搧鏁伴噺鍙婂師鍥�</p>
- <div class="card-stats">
- <span>寰呰川妫�: {{ stats.pendingInspections }}</span>
- <span>宸插畬鎴�: {{ stats.completedInspections }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" class="module-cards">
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/returnManagement')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#F56C6C"><RefreshLeft /></el-icon>
- </div>
- <div class="card-info">
- <h3>閫�璐х鐞�</h3>
- <p>鐢熸垚閲囪喘閫�璐у崟鍜岃川妫�閫�璐у崟锛屾敮鎸佺瓫閫夋煡璇笌鍗曟嵁璇︽儏</p>
- <div class="card-stats">
- <span>寰呭鏍�: {{ stats.pendingReturns }}</span>
- <span>宸插鏍�: {{ stats.approvedReturns }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/priceManagement')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#909399"><Money /></el-icon>
- </div>
- <div class="card-info">
- <h3>浠锋牸绠$悊</h3>
- <p>鏍规嵁鍟嗗搧鍙婂競鍦轰环鏍煎彉鍖栬繘琛岄噰璐环璋冩暣锛岃嚜鍔ㄦ洿鏂伴噰璐崟鎹�</p>
- <div class="card-stats">
- <span>鏈夋晥浠锋牸: {{ stats.activePrices }}</span>
- <span>寰呯敓鏁�: {{ stats.pendingPrices }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/procurementPlan')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#9C27B0"><Calendar /></el-icon>
- </div>
- <div class="card-info">
- <h3>閲囪喘璁″垝</h3>
- <p>鏅鸿兘閲囪喘璁″垝閰嶇疆锛岃嚜鍔ㄨ绠楅噰璐渶姹傦紝鑰冭檻搴撳瓨鍜屽畨鍏ㄥ簱瀛�</p>
- <div class="card-stats">
- <span>娲昏穬璁″垝: {{ stats.activePlans }}</span>
- <span>寰呰绠�: {{ stats.pendingCalculations }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" class="module-cards">
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/procurementLedger')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#9C27B0"><List /></el-icon>
- </div>
- <div class="card-info">
- <h3>閲囪喘鍙拌处</h3>
- <p>鏌ョ湅閲囪喘鍘嗗彶璁板綍锛岀粺璁″垎鏋愰噰璐暟鎹紝鐢熸垚閲囪喘鎶ヨ〃</p>
- <div class="card-stats">
- <span>鎬昏鍗�: {{ stats.totalOrders }}</span>
- <span>鎬婚噾棰�: 楼{{ stats.totalAmount.toFixed(2) }}</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/procurementReport')">
- <div class="card-content">
- <div class="card-icon">
- <el-icon size="48" color="#FF6B6B"><TrendCharts /></el-icon>
- </div>
- <div class="card-info">
- <h3>閲囪喘鎶ヨ〃</h3>
- <p>閲囪喘璁㈠崟鎵ц姹囨�汇�佹槑缁嗗垎鏋愩�佷笟鍔$粺璁°�佷緵搴斿晢渚涜揣姹囨��</p>
- <div class="card-stats">
- <span>鎶ヨ〃绫诲瀷: 4绉�</span>
- <span>鏁版嵁鏇存柊: 瀹炴椂</span>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 缁熻姒傝 -->
- <el-card class="stats-card" shadow="never">
- <template #header>
- <div class="card-header">
- <span>閲囪喘缁熻姒傝</span>
- <el-button type="primary" size="small" @click="refreshStats">鍒锋柊鏁版嵁</el-button>
- </div>
- </template>
-
- <el-row :gutter="20">
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-number">{{ stats.totalOrders }}</div>
- <div class="stat-label">閲囪喘璁㈠崟鎬绘暟</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-number">{{ stats.totalAmount.toFixed(2) }}</div>
- <div class="stat-label">閲囪喘鎬婚噾棰�(涓囧厓)</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-number">{{ stats.avgDeliveryTime }}</div>
- <div class="stat-label">骞冲潎浜や粯澶╂暟</div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-item">
- <div class="stat-number">{{ stats.qualityRate }}%</div>
- <div class="stat-label">璐ㄦ鍚堟牸鐜�</div>
- </div>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 鏈�杩戞椿鍔� -->
- <el-card class="activity-card" shadow="never">
- <template #header>
- <span>鏈�杩戞椿鍔�</span>
- </template>
-
- <el-timeline>
- <el-timeline-item
- v-for="(activity, index) in recentActivities"
- :key="index"
- :timestamp="activity.time"
- :type="activity.type"
- >
- {{ activity.content }}
- </el-timeline-item>
- </el-timeline>
- </el-card>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted } from 'vue'
-import { useRouter } from 'vue-router'
-import { Document, Box, Search, RefreshLeft, Money, List, Calendar, TrendCharts } from '@element-plus/icons-vue'
-
-const router = useRouter()
-
-// 缁熻鏁版嵁
-const stats = ref({
- pendingOrders: 5,
- approvedOrders: 25,
- pendingArrivals: 3,
- receivedArrivals: 18,
- pendingInspections: 2,
- completedInspections: 15,
- pendingReturns: 1,
- approvedReturns: 3,
- activePrices: 45,
- pendingPrices: 2,
- activePlans: 8,
- pendingCalculations: 3,
- totalOrders: 30,
- totalAmount: 125.8,
- avgDeliveryTime: 7,
- qualityRate: 96.5
-})
-
-// 鏈�杩戞椿鍔�
-const recentActivities = ref([
- {
- time: '2025-12-01 18:30',
- content: '鏂板閲囪喘璁㈠崟 PO20241201004',
- type: 'primary'
- },
- {
- time: '2025-12-01 17:45',
- content: '瀹屾垚璐ㄦ鍗� QI20241201002',
- type: 'success'
- },
- {
- time: '2025-12-01 16:20',
- content: '鍒拌揣鍗� AR20241201003 宸叉敹璐�',
- type: 'success'
- },
- {
- time: '2025-12-01 15:15',
- content: '浠锋牸璋冩暣锛氬晢鍝丅 浠� 楼80 璋冩暣涓� 楼75',
- type: 'warning'
- },
- {
- time: '2025-12-01 14:30',
- content: '閫�璐у崟 RT20241201003 宸插鏍�',
- type: 'info'
- }
-])
-
-// 瀵艰埅鍒版寚瀹氶〉闈�
-const navigateTo = (path) => {
- router.push(path)
-}
-
-// 鍒锋柊缁熻鏁版嵁
-const refreshStats = () => {
- // 妯℃嫙鍒锋柊鏁版嵁
- stats.value.pendingOrders = Math.floor(Math.random() * 10) + 1
- stats.value.totalAmount = (Math.random() * 100 + 100).toFixed(1)
-}
-
-onMounted(() => {
- // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 10px;
- color: white;
-}
-
-.page-header h2 {
- margin: 0 0 10px 0;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- margin: 0;
- font-size: 16px;
- opacity: 0.9;
-}
-
-.module-cards {
- margin-bottom: 20px;
-}
-
-.module-card {
- cursor: pointer;
- transition: all 0.3s ease;
- border: none;
- border-radius: 12px;
-}
-
-.module-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
-}
-
-.card-content {
- display: flex;
- align-items: center;
- padding: 20px;
-}
-
-.card-icon {
- margin-right: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 80px;
- height: 80px;
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
- border-radius: 50%;
- color: white;
-}
-
-.card-info h3 {
- margin: 0 0 10px 0;
- font-size: 18px;
- font-weight: 600;
- color: #303133;
-}
-
-.card-info p {
- margin: 0 0 15px 0;
- font-size: 14px;
- color: #606266;
- line-height: 1.5;
-}
-
-.card-stats {
- display: flex;
- gap: 15px;
-}
-
-.card-stats span {
- font-size: 12px;
- color: #909399;
- background-color: #f5f7fa;
- padding: 4px 8px;
- border-radius: 4px;
-}
-
-.stats-card {
- margin-bottom: 20px;
- border-radius: 12px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.stat-item {
- text-align: center;
- padding: 20px;
-}
-
-.stat-number {
- font-size: 32px;
- font-weight: 600;
- color: #409EFF;
- margin-bottom: 8px;
-}
-
-.stat-label {
- font-size: 14px;
- color: #606266;
-}
-
-.activity-card {
- border-radius: 12px;
-}
-
-.el-timeline-item {
- padding-bottom: 20px;
-}
-
-.el-timeline-item:last-child {
- padding-bottom: 0;
-}
-</style>
diff --git a/src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue b/src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue
deleted file mode 100644
index 24a368a..0000000
--- a/src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<template>
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableData="dataList"
- :tableLoading="loading"
- :summaryMethod="summarizeChildrenTable"
- :isShowSummary="true"
- height="auto"
- >
- </PIMTable>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { productList } from "@/api/procurementManagement/procurementLedger.js";
-import { nextTick } from "vue";
-const { proxy } = getCurrentInstance();
-
-defineOptions({
- name: "鏉ョエ鐧昏鎶樺彔琛�",
-});
-
-const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
-} = usePaginationApi(
- productList,
- {
- salesLedgerId: undefined,
- type: 2,
- },
- [
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- label: "鏁伴噺",
- prop: "quantity",
- },
- {
- label: "绋庣巼(%)",
- prop: "taxRate",
- },
- {
- label: "鍚◣鍗曚环(鍏�)",
- prop: "taxInclusiveUnitPrice",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : "-";
- },
- },
- {
- label: "鍚◣鎬讳环(鍏�)",
- prop: "taxInclusiveTotalPrice",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : "-";
- },
- },
- {
- label: "涓嶅惈绋庢�讳环(鍏�)",
- prop: "taxExclusiveTotalPrice",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : "-";
- },
- },
- {
- label: "鏈鏉ョエ閲戦(鍏�)",
- prop: "ticketsAmount",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : "-";
- },
- },
- {
- label: "鏈潵绁ㄦ暟",
- prop: "futureTickets",
- },
- {
- label: "鏈潵绁ㄩ噾棰�(鍏�)",
- prop: "futureTicketsAmount",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : "-";
- },
- },
- ],
- {},
- {},
- (data) => {
- dataList.value = data;
- }
-);
-
-const getList = async (id) => {
- await nextTick();
- filters.salesLedgerId = id;
- getTableData();
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(
- param,
- [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "ticketsNum",
- "ticketsAmount",
- "futureTickets",
- "futureTicketsAmount",
- ],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-defineExpose({
- getList,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/procurementManagement/invoiceEntry/components/Modal.vue b/src/views/procurementManagement/invoiceEntry/components/Modal.vue
deleted file mode 100644
index f29b78a..0000000
--- a/src/views/procurementManagement/invoiceEntry/components/Modal.vue
+++ /dev/null
@@ -1,456 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" width="70%">
- <el-form
- ref="formRef"
- :model="form"
- :rules="rules"
- label-width="120px"
- label-position="top"
- >
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseLedgerNo">
- <el-input v-model="form.purchaseLedgerNo" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
- <el-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input
- v-model="form.supplierName"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
- <el-input
- v-model="form.invoiceNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="form.invoiceAmount"
- placeholder="鑷姩濉厖"
- clearable
- :disabled="true"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆浜猴細" prop="issUer">
- <el-input
- v-model="form.issUer"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="寮�绁ㄦ棩鏈燂細" prop="entryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.entryDate"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓婁紶闄勪欢">
- <FileUpload
- :showTip="false"
- accept="*"
- :autoUpload="true"
- :action="action"
- :headers="{
- Authorization: 'Bearer ' + getToken(),
- }"
- :limit="10"
- @success="uploadSuccess"
- @remove="removeFile"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="enterDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.enterDate"
- type="date"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="浜у搧淇℃伅锛�"> </el-form-item>
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableData="form.productData"
- :summaryMethod="summarizeChildrenTable"
- :isShowSummary="true"
- height="auto"
- >
- <template #ticketsNumRef="{ row }">
- <el-input-number
- v-model="row.ticketsNum"
- placeholder="璇疯緭鍏�"
- :min="0"
- :step="0.1"
- :precision="2"
- clearable
- style="width: 100%"
- @change="invoiceNumBlur(row)"
- />
- </template>
- <template #ticketsAmountRef="{ row }">
- <el-input-number
- v-model="row.ticketsAmount"
- placeholder="璇疯緭鍏�"
- :min="0"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="invoiceAmountBlur(row)"
- />
- </template>
- </PIMTable>
- </el-form>
- <template #footer>
- <el-button type="primary" :loading="modalLoading" @click="submitForm">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { ref, getCurrentInstance } from "vue";
-import { defineEmits } from 'vue';
-import { useModal } from "@/hooks/useModal";
-import useFormData from "@/hooks/useFormData";
-import FileUpload from "@/components/Upload/FileUpload.vue";
-import {
- getPurchaseNoById,
- getInfo,
- addOrUpdateRegistration,
-} from "@/api/procurementManagement/invoiceEntry.js";
-import { getPurchaseById } from "@/api/procurementManagement/procurementLedger.js";
-import { getToken } from "@/utils/auth";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
- name: "鏉ョエ鐧昏妯℃�佹",
-});
-
-const userStore = useUserStore();
-const action = import.meta.env.VITE_APP_BASE_API + "/file/upload";
-const formRef = ref();
-const { proxy } = getCurrentInstance();
-const { form } = useFormData({
- purchaseLedgerNo: undefined, // 閲囪喘鍚堝悓鍙�
- salesContractNo: undefined, // 閿�鍞悎鍚屽彿
- supplierName: undefined, // 渚涘簲鍟嗗悕绉�
- projectName: undefined, // 椤圭洰鍚嶇О
- invoiceNumber: undefined, // 鍙戠エ鍙�
- invoiceAmount: undefined, // 鍙戠エ閲戦(鍏�)
- issUerId: userStore.id, // 褰曞叆浜�
- issUer: userStore.nickName, // 褰曞叆浜�
- entryDate: undefined, // 寮�绁ㄦ棩鏈�
- salesContractNoId: undefined, // 寮�绁ㄦ棩鏈�
- enterDate: dayjs().format("YYYY-MM-DD"),
- productData: [], // 琛ㄦ牸
- tempFileIds: [], // 鏂囦欢
-});
-
-const rules = ref({
- invoiceNumber: [
- { required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur" },
- { type: "string" },
- ],
- invoiceAmount: [
- { required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
- ],
- entryDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
- enterDate: [{ required: true, message: "璇烽�夋嫨褰曞叆鏃ユ湡", trigger: "change" }],
-});
-
-const {
- id,
- visible,
- loading: modalLoading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({
- title: "鏉ョエ鐧昏",
-});
-
-const emit = defineEmits(['refreshList']);
-
-const columns = [
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 120,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 120,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- width: 80,
- },
- {
- label: "鏁伴噺",
- prop: "quantity",
- width: 80,
- },
- {
- label: "绋庣巼(%)",
- prop: "taxRate",
- width: 80,
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "registerDate",
- width: 120,
- },
- {
- label: "鍚◣鍗曚环(鍏�)",
- prop: "taxInclusiveUnitPrice",
- width: 150,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : 0;
- },
- },
- {
- label: "鍚◣鎬讳环(鍏�)",
- prop: "taxInclusiveTotalPrice",
- width: 150,
- formatData: (val) => {
- return parseFloat(val).toFixed(2) ?? 0;
- },
- },
- {
- label: "涓嶅惈绋庢�讳环(鍏�)",
- prop: "taxExclusiveTotalPrice",
- width: 150,
- formatData: (val) => {
- return parseFloat(val).toFixed(2) ?? 0;
- },
- },
- {
- label: "鏈鏉ョエ鏁�",
- prop: "ticketsNum",
- dataType: "slot",
- slot: "ticketsNumRef",
- width: 180,
- align: "center",
- },
- {
- label: "鏈鏉ョエ閲戦(鍏�)",
- prop: "ticketsAmount",
- dataType: "slot",
- slot: "ticketsAmountRef",
- width: 180,
- align: "center",
- },
- {
- label: "鏈潵绁ㄦ暟",
- prop: "futureTickets",
- width: 100,
- },
- {
- label: "鏈潵绁ㄩ噾棰�(鍏�)",
- prop: "futureTicketsAmount",
- width: 200,
- },
-];
-
-const getTableData = async (type, id) => {
- if (type == "add") {
- const { data } = await getPurchaseNoById({ id });
- form.purchaseLedgerNo = data.purchaseContractNumber;
- form.invoiceAmount = data.invoiceAmount;
- form.invoiceNumber = data.invoiceNumber;
- form.entryDate = data.entryDate;
- form.salesContractNoId = data.salesContractNoId;
-
- const { data: infoData } = await getInfo({ id });
- form.salesContractNo = infoData.salesContractNo;
- form.projectName = infoData.projectName;
- form.supplierName = infoData.supplierName;
- form.productData = infoData.productData;
- } else if (type == "edit") {
- const data = await getPurchaseById({ id, type: 2 });
- form.purchaseLedgerNo = data.purchaseContractNumber;
- form.invoiceAmount = data.invoiceAmount;
- form.invoiceNumber = data.invoiceNumber;
- form.salesContractNo = data.salesContractNo;
- form.projectName = data.projectName;
- form.supplierName = data.supplierName;
- form.entryDate = data.entryDate;
- form.productData = data.productData;
- }
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "ticketsNum",
- "ticketsAmount",
- "ticketsAmountRef",
- "futureTickets",
- "futureTicketsAmount",
- ]);
-};
-//鏈鏉ョエ鏁板け鐒︽搷浣�
-const invoiceNumBlur = (row) => {
- if (!row.ticketsNum || row.ticketsNum === "") {
- row.ticketsNum = 0;
- }
- if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) {
- proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
- row.ticketsNum = 0;
- return;
- }
- // 璁$畻鏈鏉ョエ閲戦
- row.ticketsAmount = (row.ticketsNum * row.taxInclusiveUnitPrice).toFixed(2)
- // 璁$畻鏈潵绁ㄦ暟
- row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
- // 璁$畻鏈潵绁ㄩ噾棰�
- row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
- calculateinvoiceAmount();
-};
-
-// 鏈鏉ョエ閲戦澶辩劍鎿嶄綔
-const invoiceAmountBlur = (row) => {
- if (!row.ticketsAmount) {
- row.ticketsAmount = 0;
- }
- // 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰�
- if (row.ticketsAmount > row.tempFutureTicketsAmount) {
- proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�");
- row.ticketsAmount = 0;
- }
- // 璁$畻鏈鏉ョエ鏁�
- row.ticketsNum = Number(
- (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2)
- );
- // 璁$畻鏈潵绁ㄦ暟
- row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
- // 璁$畻鏈潵绁ㄩ噾棰�
- row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
- calculateinvoiceAmount();
-};
-
-const calculateinvoiceAmount = () => {
- let invoiceAmountTotal = 0;
- form.productData.forEach((item) => {
- if (item.ticketsAmount) {
- invoiceAmountTotal += Number(item.ticketsAmount);
- }
- });
- form.invoiceAmount = invoiceAmountTotal.toFixed(2);
-};
-
-const open = (type, eid) => {
- openModal();
- getTableData(type, eid);
- id.value = eid;
-};
-
-const uploadSuccess = (response) => {
- form.tempFileIds.push(response.data.tempId);
- console.log(form);
-};
-
-const removeFile = (file) => {
- const { tempId } = file.response.data;
- form.tempFileIds = form.tempFileIds.filter((item) => item !== tempId);
-};
-
-const closeAndRefresh = () => {
- closeModal();
- emit('refreshList');
-};
-
-const submitForm = () => {
- formRef.value.validate(async (valid, fields) => {
- if (valid) {
- // modalLoading.value = true;
- const { code } = await addOrUpdateRegistration({
- purchaseLedgerId: id.value,
- purchaseContractNumber: form.purchaseLedgerNo,
- invoiceNumber: form.invoiceNumber,
- invoiceAmount: form.invoiceAmount,
- salesContractNo: form.salesContractNo,
- projectName: form.projectName,
- productData: form.productData,
- issueDate: form.entryDate,
- issUerId: form.issUerId, // 褰曞叆浜篿d
- issUer: form.issUer, // 褰曞叆浜�
- salesContractNoId: form.salesContractNoId,
- supplierName: form.supplierName,
- tempFileIds: form.tempFileIds,
- enterDate: form.enterDate,
- type: 4,
- });
- modalLoading.value = false;
- if (code == 200) {
- closeAndRefresh();
- }
- } else {
- modalLoading.value = false;
- }
- });
-};
-
-defineExpose({
- open,
- closeAndRefresh,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/procurementManagement/invoiceEntry/index.vue b/src/views/procurementManagement/invoiceEntry/index.vue
deleted file mode 100644
index 87e08e9..0000000
--- a/src/views/procurementManagement/invoiceEntry/index.vue
+++ /dev/null
@@ -1,310 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :model="filters" :inline="true">
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-input
- v-model="filters.supplierName"
- placeholder="璇疯緭鍏ュ悕绉版悳绱�"
- clearable
- prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="閲囪喘璁㈠崟鍙凤細">
- <el-input
- v-model="filters.purchaseContractNumber"
- placeholder="璇疯緭鍏�"
- clearable
- prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
-
- <el-form-item label="閿�鍞悎鍚屽彿">
- <el-input
- v-model="filters.salesContractNo"
- placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿"
- clearable
- />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О">
- <el-input
- v-model="filters.projectName"
- placeholder="璇疯緭鍏ラ」鐩悕绉�"
- clearable
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
- <el-button @click="resetFilters"> 閲嶇疆 </el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="handleAdd('add')">
- 鏂板鐧昏
- </el-button>
-<!-- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
- </div>
- </div>
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableData="dataList"
- :tableLoading="loading"
- :isSelection="true"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- :expand-row-keys="expandRowKeys"
- :summaryMethod="summarizeMainTable"
- :isShowSummary="true"
- @expand-change="expandChange"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #expand="{ row }">
- <ExpandTable ref="expandTableRef" />
- </template>
- <template #operation="{ row }">
- <el-button
- text
- type="primary"
- size="small"
- @click="handleEdit('edit', row.id)"
- >
- 缂栬緫
- </el-button>
- </template>
- </PIMTable>
- </div>
- <Modal ref="modalRef" @refreshList="getTableData"></Modal>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import {delRegistration, gePurchaseListPage} from "@/api/procurementManagement/invoiceEntry.js";
-import { nextTick, onMounted, getCurrentInstance, ref } from "vue";
-import ExpandTable from "./components/ExpandTable.vue";
-import Modal from "./components/Modal.vue";
-import {ElMessageBox} from "element-plus";
-
-defineOptions({
- name: "鏉ョエ鐧昏",
-});
-
-const { proxy } = getCurrentInstance();
-const expandRowKeys = ref([]);
-const expandTableRef = ref();
-const modalRef = ref();
-const selectedRows = ref([]);
-
-const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- gePurchaseListPage,
- {
- purchaseContractNumber: undefined,
- },
- [
- {
- type: "expand",
- dataType: "slot",
- slot: "expand",
- },
- {
- label: "閲囪喘璁㈠崟鍙�",
- prop: "purchaseContractNumber",
- width:150
- },
- {
- label: "閿�鍞悎鍚屽彿",
- prop: "salesContractNo",
- width:150
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width:300
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:400
- },
- {
- label: "褰曞叆浜�",
- prop: "recorderName",
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "entryDate",
- width:110
- },
- {
- label: "鍚堝悓閲戦(鍏�)",
- prop: "contractAmount",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : 0;
- },
- },
- {
- label: "宸叉潵绁ㄩ噾棰�(鍏�)",
- prop: "receiptPaymentAmount",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : 0;
- },
- },
- {
- label: "寰呮潵绁ㄩ噾棰�(鍏�)",
- prop: "unReceiptPaymentAmount",
- width:200,
- formatData: (val) => {
- return val ? parseFloat(val).toFixed(2) : 0;
- },
- },
- // {
- // fixed: "right",
- // label: "鎿嶄綔",
- // dataType: "slot",
- // slot: "operation",
- // align: "center",
- // width: "200px",
- // },
- ]
-);
-
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection.filter(
- (item) => item.purchaseContractNumber !== undefined
- );
-};
-
-const handleAdd = (type) => {
- if (selectedRows.value.length !== 1) {
- proxy.$modal.msgWarning("璇峰厛閫変腑涓�鏉℃暟鎹�");
- return;
- }
- modalRef.value.open(type, selectedRows.value[0].id);
-};
-
-const handleEdit = (type, id) => {
- modalRef.value.open(type, id);
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/registration/export", {}, "鏉ョエ鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭閲囪喘鍙拌处
-const handleExport = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/ledger/exportOne", {}, "鏉ョエ鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 鏂板鍒ゆ柇锛氬鏋滄湁閫変腑鐨勬暟鎹病鏈塼icketRegistrationId锛屾彁绀哄苟缁堟
- const noTicket = selectedRows.value.some(item => !item.ticketRegistrationId);
- if (noTicket) {
- proxy.$modal.msgWarning("閲囪喘鍙拌处杩樻湭杩涜鏉ョエ鐧昏,鏃犳硶杩涜鍒犻櫎鎿嶄綔");
- return;
- }
- ids = selectedRows.value.map((item) => item.ticketRegistrationId);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delRegistration(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-const expandChange = async (row, expandedRows) => {
- if (expandedRows.length > 0) {
- await nextTick();
- expandTableRef.value.getList(row.id);
- }
-};
-
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- ["contractAmount", "receiptPaymentAmount", "unReceiptPaymentAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-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/procurementManagement/invoiceEntry/indexOld.vue b/src/views/procurementManagement/invoiceEntry/indexOld.vue
deleted file mode 100644
index 1b4c6b9..0000000
--- a/src/views/procurementManagement/invoiceEntry/indexOld.vue
+++ /dev/null
@@ -1,727 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">閲囪喘鍚堝悓鍙凤細</span>
- <el-input
- v-model="searchForm.purchaseContractNumber"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <el-button
- type="primary"
- @click="handleQuery"
- style="margin-left: 10px"
- >
- 鎼滅储
- </el-button>
- </div>
- <div>
- <el-button type="primary" @click="handleAdd">鏂板鐧昏</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- </div>
- <div class="table_list">
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- height="calc(100vh - 18.5em)"
- >
- <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-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column label="鏈鏉ョエ鏁�" prop="ticketsNum" />
- <el-table-column
- label="鏈鏉ョエ閲戦(鍏�)"
- prop="ticketsAmount"
- :formatter="formattedNumber"
- />
- <el-table-column label="鏈潵绁ㄦ暟" prop="futureTickets" />
- <el-table-column
- label="鏈潵绁ㄩ噾棰�(鍏�)"
- prop="futureTicketsAmount"
- :formatter="formattedNumber"
- />
- </el-table>
- </template>
- </el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="閲囪喘鍚堝悓鍙�"
- prop="purchaseContractNumber"
- show-overflow-tooltip
- />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- show-overflow-tooltip
- />
- <el-table-column
- label="椤圭洰鍚嶇О"
- prop="projectName"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚堝悓閲戦(鍏�)"
- prop="contractAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="宸插紑绁ㄩ噾棰�(鍏�)"
- prop="receiptPaymentAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="寰呭紑绁ㄩ噾棰�(鍏�)"
- prop="unReceiptPaymentAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- min-width="60"
- align="center"
- >
- <template #default="scope">
- <el-button
- text
- type="primary"
- size="small"
- @click="openForm('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"
- />
- </div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板鏉ョエ鐧昏' : '缂栬緫鏉ョエ鐧昏'"
- width="80%"
- @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="purchaseLedgerNo">
- <el-input v-model="form.purchaseLedgerNo" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
- <el-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input
- v-model="form.supplierName"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
- <el-input
- v-model="form.invoiceNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
- <el-input
- type="number"
- :step="0.01"
- v-model="form.invoiceAmount"
- placeholder="鑷姩濉厖"
- clearable
- :disabled="true"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="褰曞叆浜猴細" prop="issUer">
- <el-input
- v-model="form.issUer"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="寮�绁ㄦ棩鏈燂細" prop="issueDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.issueDate"
- type="date"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="涓婁紶闄勪欢">
- <FileUpload :showTip="false" accept="*" :autoUpload="true" />
- </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"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row> -->
- <el-row>
- <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
- </el-row>
- <el-table
- :data="productData"
- border
- @selection-change="productSelected"
- show-summary
- style="width: 100%"
- :summary-method="summarizeChildrenTable"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="鏁伴噺" prop="quantity" width="70" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
- <el-table-column label="褰曞叆鏃ユ湡" prop="createTime" width="120" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- width="200"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- width="200"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- width="200"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column label="鏈鏉ョエ鏁�" prop="ticketsNum" width="170">
- <template #default="scope">
- <el-input-number
- v-model="scope.row.ticketsNum"
- placeholder="璇烽�夋嫨"
- :min="0"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="invoiceNumBlur(scope.row)"
- />
- </template>
- </el-table-column>
- <el-table-column
- label="鏈鏉ョエ閲戦(鍏�)"
- prop="ticketsAmount"
- :min="0"
- :step="0.1"
- :formatter="formattedNumber"
- width="200"
- >
- <template #default="scope">
- <el-input-number
- v-model="scope.row.ticketsAmount"
- placeholder="璇烽�夋嫨"
- :min="0"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="invoiceAmountBlur(scope.row)"
- />
- </template>
- </el-table-column>
- <el-table-column
- label="鏈潵绁ㄦ暟"
- prop="futureTickets"
- :formatter="
- (row) =>
- row.futureTickets == null || row.futureTickets === ''
- ? row.quantity
- : row.futureTickets
- "
- >
- </el-table-column>
- <el-table-column
- label="鏈潵绁ㄩ噾棰�(鍏�)"
- prop="futureTicketsAmount"
- :formatter="
- (row) =>
- row.futureTicketsAmount !== undefined &&
- row.futureTicketsAmount !== null &&
- row.futureTicketsAmount !== ''
- ? row.futureTicketsAmount
- : row.taxExclusiveTotalPrice
- "
- >
- </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>
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import { userListNoPage } from "@/api/system/user.js";
-import { productList } from "@/api/procurementManagement/procurementLedger.js";
-import useUserStore from "@/store/modules/user";
-import FileUpload from "@/components/Upload/FileUpload.vue";
-
-const userStore = useUserStore();
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const userList = ref([]);
-const purchaseLedgerList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
-import {
- addOrUpdateRegistration,
- delRegistration,
- gePurchaseListPage,
- getInfo,
- getProduct,
- getPurchaseNoById,
- getRegistrationById,
-} from "@/api/procurementManagement/invoiceEntry.js";
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- purchaseContractNumber: "",
- },
- form: {
- issueDate: "", // 寮�绁ㄦ棩鏈�
- purchaseLedgerId: "",
- purchaseLedgerNo: "",
- issUerId: "", // 寮�绁ㄤ汉id
- issUer: "", // 寮�绁ㄤ汉濮撳悕
- invoiceNumber: "", // 鍙戠エ鍙�
- invoiceAmount: "", // 鍙戠エ閲戦
- createTime: "", // 褰曞叆鏃ユ湡
- },
- rules: {
- invoiceNumber: [
- { required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur" },
- { type: "string" },
- ],
- invoiceAmount: [
- { required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
- ],
- },
-});
-const { searchForm, form, rules } = toRefs(data);
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const currentId = ref("");
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- gePurchaseListPage({ ...searchForm.value, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- tableData.value.map((item) => {
- item.children = [];
- });
- total.value = res.total;
- expandedRowKeys.value = [];
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2) ?? 0;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection.filter(
- (item) => item.purchaseContractNumber !== undefined
- );
-};
-const productSelected = (selectedRows) => {
- productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 2 }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- ["contractAmount", "receiptPaymentAmount", "unReceiptPaymentAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(
- param,
- [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "ticketsNum",
- "ticketsAmount",
- "futureTickets",
- "futureTicketsAmount",
- ],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-
-const handleAdd = () => {
- if (selectedRows.value.length !== 1) {
- proxy.$modal.msgWarning("璇峰厛閫変腑涓�鏉℃暟鎹�");
- return;
- }
- openForm("add", selectedRows.value[0]);
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- invoiceNumBlur(row);
- operationType.value = type;
- form.value = {};
- productData.value = [];
- fileList.value = [];
- form.value.issUerId = userStore.id;
- form.value.issUer = userStore.name;
- form.value.issueDate = getNowFormatDate();
- userListNoPage().then((res) => {
- userList.value = res.data;
- });
- // 鏂板鏃朵紶鍏ュ綋鍓嶈id骞舵煡璇㈤噰璐悎鍚屽彿
- if (type === "add" && row && row.id) {
- form.value.purchaseLedgerId = row.id;
- getPurchaseNoById({ id: row.id }).then((res) => {
- let result = res.data;
- purchaseLedgerList.value = result;
- form.value.purchaseLedgerNo = result.purchaseContractNumber;
- form.value.invoiceAmount = result.invoiceAmount;
- form.value.invoiceNumber = result.invoiceNumber;
- setInfo(result.id);
- });
- } else {
- getProduct().then((res) => {
- purchaseLedgerList.value = res;
- });
- }
- if (type === "edit") {
- currentId.value = row.id;
- getRegistrationById({ id: row.id }).then((res) => {
- const { code, data } = res;
- if (code == 200) {
- form.value.invoiceAmount = data.invoiceAmount;
- productData.value = data.productData;
- if (data.salesLedgerFiles) {
- fileList.value = data.salesLedgerFiles;
- } else {
- fileList.value = [];
- }
- }
- });
- }
- dialogFormVisible.value = true;
-};
-// 閫夋嫨閲囪喘鍚堝悓鍙疯祴鍊�
-const setInfo = (value) => {
- getInfo({ id: value }).then((res) => {
- let result = res.data;
- form.value.salesContractNo = result.salesContractNo;
- form.value.projectName = result.projectName;
- productData.value = result.productData;
- form.value.supplierName = result.supplierName;
- });
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- form.value.productData = proxy.HaveJson(productData.value);
- addOrUpdateRegistration(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/registration/export", {}, "鏉ョエ鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鍒犻櫎
-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(() => {
- delRegistration(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-//鏈鏉ョエ鏁板け鐒︽搷浣�
-const invoiceNumBlur = (row) => {
- if (!row.ticketsNum || row.ticketsNum === "") {
- row.ticketsNum = 0;
- }
- if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) {
- proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
- row.ticketsNum = 0;
- return;
- }
- // 璁$畻鏈鏉ョエ閲戦
- row.ticketsAmount = row.ticketsNum * row.taxInclusiveUnitPrice;
- // 璁$畻鏈潵绁ㄦ暟
- row.futureTickets = row.tempFutureTickets - row.ticketsNum;
- // 璁$畻鏈潵绁ㄩ噾棰�
- row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
- calculateinvoiceAmount();
-};
-// 鏈鏉ョエ閲戦澶辩劍鎿嶄綔
-const invoiceAmountBlur = (row) => {
- if (!row.ticketsAmount) {
- row.ticketsAmount = 0;
- }
- // 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰�
- if (row.ticketsAmount > row.tempFutureTicketsAmount) {
- proxy.$modal.msgWarning("鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�");
- row.ticketsAmount = 0;
- }
- // 璁$畻鏈鏉ョエ鏁�
- row.ticketsNum = (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2);
- // 璁$畻鏈潵绁ㄦ暟
- row.futureTickets = row.tempFutureTickets - row.ticketsNum;
- // 璁$畻鏈潵绁ㄩ噾棰�
- row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
- calculateinvoiceAmount();
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡鍑芥暟
-function getNowFormatDate() {
- let date = new Date(),
- year = date.getFullYear(), //鑾峰彇瀹屾暣鐨勫勾浠�(4浣�)
- month = date.getMonth() + 1, //鑾峰彇褰撳墠鏈堜唤(0-11,0浠h〃1鏈�)
- strDate = date.getDate(); // 鑾峰彇褰撳墠鏃�(1-31)
- if (month < 10) month = `0${month}`; // 濡傛灉鏈堜唤鏄釜浣嶆暟锛屽湪鍓嶉潰琛�0
- if (strDate < 10) strDate = `0${strDate}`; // 濡傛灉鏃ユ槸涓綅鏁帮紝鍦ㄥ墠闈㈣ˉ0
- return `${year}-${month}-${strDate}`;
-}
-
-function calculateinvoiceAmount() {
- console.log("productData", productData.value);
- var invoiceAmountTotal = 0;
- productData.value.forEach((item) => {
- if (item.ticketsAmount) {
- invoiceAmountTotal += item.ticketsAmount;
- }
- });
- form.value.invoiceAmount = invoiceAmountTotal.toFixed(2);
-}
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/procurementManagement/paymentEntry/index.vue b/src/views/procurementManagement/paymentEntry/index.vue
deleted file mode 100644
index 658b027..0000000
--- a/src/views/procurementManagement/paymentEntry/index.vue
+++ /dev/null
@@ -1,613 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :inline="true" :model="searchForm" style="width: 100%">
- <el-row justify="space-between">
- <el-col :span="20">
- <el-form-item label="渚涘簲鍟嗗悕绉�/鍚堝悓鍙�">
- <el-input
- v-model="searchForm.supplierNameOrContractNo"
- style="width: 240px"
- placeholder="杈撳叆渚涘簲鍟嗗悕绉�/鍚堝悓鍙锋悳绱�"
- clearable
- prefix-icon="Search"
- @change="handleQuery"
- />
- </el-form-item>
- <el-form-item>
- <el-checkbox
- v-model="searchForm.status"
- label="涓嶆樉绀哄緟浠樻涓�0"
- @change="handleQuery"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- </el-form-item>
- </el-col>
- <el-col :span="4">
- <el-form-item style="float: right; margin-right: unset">
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- <el-button type="primary" @click="openForm('add')">
- 鏂板浠樻
- </el-button>
-<!-- <el-button type="danger" plain @click="handleDelete">-->
-<!-- 鍒犻櫎-->
-<!-- </el-button>-->
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :expandRowKeys="expandedRowKeys"
- :isSelection="true"
- :isShowSummary="isShowSummarySon"
- :summaryMethod="summarizeMainTable1"
- @selection-change="handleSelectionChange"
- @expand-change="expandChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="page.total"
- >
- <template #expand="{ row }">
- <el-table
- :data="expandData"
- border
- show-summary
- v-loading="childrenLoading"
- :summary-method="summarizeMainTable2"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浠樻鏃ユ湡" prop="paymentDate" />
- <el-table-column label="浠樻閲戦" prop="currentPaymentAmount">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="scope.row.currentPaymentAmount"
- :disabled="!scope.row.editType"
- :precision="2"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </template>
- </el-table-column>
- <el-table-column label="浠樻鏂瑰紡" prop="paymentMethod">
- <template #default="scope">
- <el-select
- :disabled="!scope.row.editType"
- v-model="scope.row.paymentMethod"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="鐢垫眹" value="鐢垫眹" />
- <el-option label="鎵垮厬" value="鎵垮厬" />
- </el-select>
- </template>
- </el-table-column>
- <el-table-column label="鐧昏浜�" prop="registrant" />
- <el-table-column label="鐧昏鏃ユ湡" prop="registrationtDate" />
- <el-table-column label="鎿嶄綔" width="150">
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="changeEditType(scope.row)"
- v-if="!scope.row.editType"
- >缂栬緫</el-button
- >
- <el-button
- link
- type="primary"
- size="small"
- @click="saveReceiptPayment(scope.row)"
- v-if="scope.row.editType"
- >淇濆瓨</el-button
- >
- <el-button
- link
- type="primary"
- size="small"
- @click="handleDelete(scope.row)"
- >鍒犻櫎</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- </template>
- </PIMTable>
- </div>
- <el-dialog
- v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板浠樻鐧昏' : '缂栬緫浠樻鐧昏'"
- width="60%"
- @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="purchaseContractNumber">
- <el-input
- v-model="form.purchaseContractNumber"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
- <el-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input
- v-model="form.supplierName"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNumber">
- <el-input
- v-model="form.invoiceNumber"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
- <el-input
- v-model="form.invoiceAmount"
- placeholder="鑷姩濉厖"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈浠樻閲戦锛�" prop="currentPaymentAmount">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- :precision="2"
- v-model="form.currentPaymentAmount"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡锛�" prop="paymentMethod">
- <el-select
- v-model="form.paymentMethod"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="鐢垫眹" value="鐢垫眹" />
- <el-option label="鎵垮厬" value="鎵垮厬" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浠樻鏃ユ湡锛�" prop="paymentDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.paymentDate"
- 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="registrant">
- <el-input
- v-model="form.registrant"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐧昏鏃ユ湡锛�" prop="registrationtDate">
- <el-input
- v-model="form.registrationtDate"
- 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>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, toRefs, getCurrentInstance, nextTick, onMounted } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { ElMessageBox } from "element-plus";
-import useUserStore from "@/store/modules/user.js";
-import {
- byPurchaseId,
- paymentRegistrationAdd,
- paymentRegistrationDel,
- paymentRegistrationEdit,
- getTicketNo,
-} from "@/api/procurementManagement/paymentEntry.js";
-import {
- delPaymentRegistration,
- invoiceListPage,
- registrationListPageGetById,
- updatePaymentRegistration
-} from "@/api/procurementManagement/procurementInvoiceLedger.js";
-import useFormData from "@/hooks/useFormData";
-
-const { proxy } = getCurrentInstance();
-const tableColumn = ref([
- {
- type: "expand",
- dataType: "slot",
- slot: "expand",
- },
- {
- label: "閲囪喘鍚堝悓鍙�",
- prop: "purchaseContractNumber",
- },
- {
- label: "閿�鍞悎鍚屽彿",
- prop: "salesContractNo",
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width:240
- },
- {
- label: "浠樻鐘舵��",
- prop: "statusName",
- dataType: "tag",
- formatType: (params) => {
- if (params == '鏈畬鎴愪粯娆�') {
- return "danger";
- } else if (params == '宸插畬鎴愪粯娆�') {
- return "success";
- } else {
- return null;
- }
- },
- },
- {
- label: "鍙戠エ鍙�",
- prop: "invoiceNumber",
- width:200
- },
- {
- label: "鍙戠エ閲戦(鍏�)",
- prop: "invoiceAmount",
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "宸蹭粯娆鹃噾棰�(鍏�)",
- prop: "paymentAmountTotal",
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "寰呬粯娆鹃噾棰�(鍏�)",
- prop: "unPaymentAmountTotal",
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "褰曞叆浜�",
- prop: "issUer",
- },
-]);
-const tableData = ref([]);
-const expandData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const childrenLoading = ref(false);
-const userStore = useUserStore();
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- supplierNameOrContractNo: "",
- status: false,
- },
- form: {
- purchaseContractNumber: "",
- purchaseLedgerId: "",
- salesContractNo: "",
- supplierName: "",
- invoiceNumber: "",
- invoiceAmount: "",
- taxRate: "",
- currentPaymentAmount: "",
- paymentMethod: "",
- registrant: "",
- registrantId: "",
- paymentDate: "",
- registrationtDate: "",
- },
- rules: {
- purchaseLedgerId: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- currentPaymentAmount: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- paymentMethod: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoiceNumber: [
- { required: true, message: "璇烽�夋嫨閲囪喘鍚堝悓鍙�", trigger: "change" },
- ],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm, resetForm } = useFormData(data.searchForm);
-const isShowSummarySon = ref(true);
-const expandedRowKeys = ref([]);
-
-const getStatusTagType = (statusName = '') => {
- const normalized = statusName.trim();
- if (!normalized) return 'info';
- return normalized === '鏈畬鎴愪粯娆�' ? 'danger' : 'success';
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable1 = (param) => {
- return proxy.summarizeTable(
- param,
- ["invoiceAmount", "paymentAmountTotal", "unPaymentAmountTotal"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable2 = (param) => {
- return proxy.summarizeTable(param, ["currentPaymentAmount"], {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- });
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- invoiceListPage({ ...searchForm, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- page.total = res.total;
- if (expandedRowKeys.value.length > 0) {
- const arr = []
- const index = tableData.value.findIndex(item => item.id === expandedRowKeys.value[0]);
- if (index > -1) {
- arr.push(tableData.value[index]);
- expandChange(tableData.value[index], arr)
- }
- }
- });
-};
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- nextTick(() => {
- expandedRowKeys.value = [];
- try {
- childrenLoading.value = true;
- registrationListPageGetById({ id: row.id }).then((res) => {
- childrenLoading.value = false;
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- expandData.value = res;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- childrenLoading.value = false;
- console.log(error);
- }
- })
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 缂栬緫淇敼鐘舵��
-const changeEditType = (row) => {
- row.editType = !row.editType;
-};
-// 淇濆瓨鍥炴璁板綍
-const saveReceiptPayment = (row) => {
- let updateData = {
- id: row.id,
- currentPaymentAmount: row.currentPaymentAmount,
- paymentMethod: row.paymentMethod,
- };
- updatePaymentRegistration(updateData).then((res) => {
- row.editType = !row.editType;
- getList();
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- if (selectedRows.value.length !== 1) {
- proxy.$message.error("璇烽�夋嫨涓�鏉″彂绁ㄦ暟鎹�");
- return;
- }
- if (selectedRows.value[0].unPaymentAmountTotal == 0) {
- proxy.$message.warning("鏃犻渶鍐嶄粯娆�");
- return;
- }
- operationType.value = type;
- form.value = {};
- form.value = { ...selectedRows.value[0] };
- form.value.ticketRegistrationId = selectedRows.value[0].id;
- form.value.id = null;
- // 鏌ヨ閲囪喘鍚堝悓鍙�
- form.value.registrationtDate = getCurrentDate();
- form.value.paymentDate = getCurrentDate();
- form.value.registrant = userStore.name;
- dialogFormVisible.value = true;
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- if (operationType.value === "edit") {
- submitEdit();
- } else {
- submitAdd();
- }
- }
- });
-};
-// 鎻愪氦鏂板
-const submitAdd = () => {
- paymentRegistrationAdd(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鎻愪氦淇敼
-const submitEdit = () => {
- paymentRegistrationEdit(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 鍒犻櫎
-const handleDelete = (row) => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delPaymentRegistration(row.id)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-// 瀵煎嚭
-const handleExport = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/registration/exportOne", { ...searchForm, ...page }, "浠樻鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-::v-deep(.el-checkbox__label) {
- font-weight: bold;
-}
-</style>
diff --git a/src/views/procurementManagement/paymentHistory/index.vue b/src/views/procurementManagement/paymentHistory/index.vue
deleted file mode 100644
index c38b4b0..0000000
--- a/src/views/procurementManagement/paymentHistory/index.vue
+++ /dev/null
@@ -1,188 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="閲囪喘鍚堝悓鍙�">
- <el-input
- v-model="searchForm.purchaseContractNumber"
- style="width: 240px"
- placeholder="杈撳叆閲囪喘鍚堝悓鍙锋悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-input
- v-model="searchForm.searchText"
- style="width: 240px"
- placeholder="杈撳叆渚涘簲鍟嗗悕绉版悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="浠樻鏃ユ湡">
- <el-date-picker
- v-model="searchForm.paymentDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="daterange"
- start-placeholder="寮�濮嬫椂闂�"
- end-placeholder="缁撴潫鏃堕棿"
- clearable
- @change="changeDateRange"
- @clear="clearRange"
- />
- </el-form-item>
- <el-form-item>
- <el-button
- type="primary"
- @click="handleQuery"
- style="margin-left: 10px"
- >
- 鎼滅储
- </el-button>
- <el-button @click="handleExport">瀵煎嚭</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- :isShowSummary="isShowSummarySon"
- :summaryMethod="summarizeMainTable1"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="page.total"
- ></PIMTable>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, getCurrentInstance, onMounted } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { paymentHistoryListPage } from "@/api/procurementManagement/paymentEntry.js";
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-
-const { proxy } = getCurrentInstance();
-const isShowSummarySon = ref(true);
-const tableColumn = ref([
- {
- label: "閲囪喘鍚堝悓鍙�",
- prop: "purchaseContractNumber",
- },
- {
- label: "浠樻鏃ユ湡",
- prop: "paymentDate",
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width:240
- },
- {
- label: "浠樻閲戦",
- prop: "currentPaymentAmount",
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "浠樻鏂瑰紡",
- prop: "paymentMethod",
- },
- {
- label: "鐧昏浜�",
- prop: "registrant",
- },
- {
- label: "鐧昏鏃ユ湡",
- prop: "registrationtDate",
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const total = ref(0);
-const { form: searchForm } = useFormData({
- searchText: undefined,
- purchaseContractNumber: undefined,
- paymentDate: [],
- paymentDateStart: undefined,
- paymentDateEnd: undefined,
-});
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { paymentDate, ...rest } = searchForm;
- paymentHistoryListPage({ ...rest, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- page.total = res.total;
- });
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable1 = (param) => {
- return proxy.summarizeTable(param, ["currentPaymentAmount"], {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-const changeDateRange = (date) => {
- if (date) {
- searchForm.paymentDateStart = date[0];
- searchForm.paymentDateEnd = date[1];
- getList();
- }
-};
-
-const clearRange = () => {
- searchForm.paymentDate = [];
- searchForm.paymentDateStart = undefined;
- searchForm.paymentDateEnd = undefined;
- getList();
-};
-
-// 瀵煎嚭
-const handleExport = () => {
- const { paymentDate, ...rest } = searchForm;
- proxy.download("/purchase/paymentRegistration/export", { ...rest, ...page }, "浠樻娴佹按.xlsx");
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-</style>
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
deleted file mode 100644
index 741e6ac..0000000
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ /dev/null
@@ -1,315 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉�:</span>
- <el-input
- v-model="searchForm.supplierName"
- style="width: 240px"
- placeholder="杈撳叆渚涘簲鍟嗗悕绉�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div></div>
- </div>
- <el-row :gutter="20">
- <el-col :span="14">
- <div class="table_list">
- <el-table
- ref="multipleTable"
- border
- v-loading="tableLoading"
- :data="tableData"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- height="calc(100vh - 18.5em)"
- :highlight-current-row="true"
- style="width: 100%"
- tooltip-effect="dark"
- @row-click="rowClick"
- :show-summary="isShowSummary"
- :summary-method="summarizeMainTable"
- class="lims-table"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column
- label="鍙戠エ閲戦(鍏�)"
- prop="invoiceAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="浠樻閲戦(鍏�)"
- prop="paymentAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="搴斾粯閲戦(鍏�)"
- prop="payableAmount"
- show-overflow-tooltip
- >
- <template #default="{ row, column }">
- <el-text type="danger">
- {{ formattedNumber(row, column, row.payableAmount) }}
- </el-text>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :layout="page.layout"
- :page="page.current"
- :limit="page.size"
- />
- </div>
- </el-col>
- <el-col :span="10">
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumnSon"
- :tableData="originalTableDataSon"
- :isSelection="false"
- :tableLoading="tableLoadingSon"
- :isShowSummary="isShowSummarySon"
- :summaryMethod="summarizeMainTable1"
- height="calc(100vh - 18.5em)"
- >
- <template #payableAmountSlot="{ row }">
- <el-text type="danger">
- {{ parseFloat(row.payableAmount).toFixed(2) }}
- </el-text>
- </template>
- </PIMTable>
- <pagination
- v-show="sonTotal > 0"
- :total="sonTotal"
- @pagination="sonPaginationSearch"
- :layout="page.layout"
- :page="sonPage.current"
- :limit="sonPage.size"
- />
- </div>
- </el-col>
- </el-row>
- </div>
-</template>
-
-<script setup>
-import { ref, toRefs } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import {
- paymentLedgerList,
- paymentRecordList,
-} from "@/api/procurementManagement/paymentLedger.js";
-import Pagination from "../../../components/PIMTable/Pagination.vue";
-
-const tableColumn = ref([
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width:240
- },
- {
- label: "鍙戠エ閲戦(鍏�)",
- prop: "invoiceAmount",
- },
- {
- label: "浠樻閲戦(鍏�)",
- prop: "paymentAmount",
- },
- {
- label: "搴斾粯閲戦(鍏�)",
- prop: "payableAmount",
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const data = reactive({
- searchForm: {
- supplierNameOrContractNo: "",
- },
-});
-const page = reactive({
- current: 1,
- size: 100,
-});
-const sonPage = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const sonTotal = ref(0);
-const isShowSummary = ref(true);
-const { searchForm } = toRefs(data);
-const currentSupplierId = ref("");
-const rowClick = (row) => {
- currentSupplierId.value = row.supplierId;
- getPaymenRecordtList(row.supplierId);
-};
-// 瀛愭ā鍧�
-const tableColumnSon = ref([
- {
- label: "鍙戠敓鏃ユ湡",
- prop: "happenTime",
- width: 110,
- },
- {
- label: "鍙戠エ閲戦(鍏�)",
- prop: "invoiceAmount",
- width: 200,
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "浠樻閲戦(鍏�)",
- prop: "currentPaymentAmount",
- width: 200,
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "搴斾粯閲戦(鍏�)",
- dataType: "slot",
- width: 200,
- prop: "payableAmount",
- slot: "payableAmountSlot",
- },
-]);
-const tableDataSon = ref([]);
-const originalTableDataSon = ref([]);
-const tableLoadingSon = ref(false);
-const isShowSummarySon = ref(true);
-const detailPageNum = ref(1);
-const detailPageSize = ref(10);
-const { proxy } = getCurrentInstance();
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- ["invoiceAmount", "paymentAmount", "payableAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable1 = (param) => {
- let summarizeTable = proxy.summarizeTable(
- param,
- ["invoiceAmount", "currentPaymentAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
- if (originalTableDataSon.value.length > 0) {
- summarizeTable[summarizeTable.length - 1] =
- originalTableDataSon.value[
- originalTableDataSon.value.length - 1
- ].payableAmount.toFixed(2);
- } else {
- summarizeTable[summarizeTable.length - 1] = 0.0;
- }
- return summarizeTable;
-};
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- paymentLedgerList({
- ...searchForm.value,
- ...page,
- detailPageNum: detailPageNum.value, // 鏂板
- detailPageSize: detailPageSize.value, // 鏂板
- }).then((res) => {
- let result = res.data;
- tableLoading.value = false;
- tableData.value = result.records || [];
- total.value = result.total || 0;
- if (tableData.value.length > 0) {
- getPaymenRecordtList(tableData.value[0].supplierId);
- currentSupplierId.value = tableData.value[0].supplierId;
- }
- });
-};
-
-const getPaymenRecordtList = (supplierId) => {
- tableLoadingSon.value = true;
- paymentRecordList(supplierId)
- .then((res) => {
- tableLoadingSon.value = false;
- tableDataSon.value = res.data;
- handlePagination({ page: 1, limit: sonPage.size });
- sonTotal.value = res.data.length;
- })
- .catch((e) => {
- tableLoadingSon.value = false;
- });
-};
-const handlePagination = ({ page, limit }) => {
- sonPage.current = page;
- sonPage.size = limit;
-
- const start = (page - 1) * limit;
- const end = start + limit;
-
- originalTableDataSon.value = tableDataSon.value.slice(start, end);
-};
-
-const sonPaginationSearch = (pagination) => {
- // 鎺ユ敹鍒嗛〉鍣ㄥ弬鏁� { page, limit }
- handlePagination(pagination);
-};
-const formattedNumber = (row, column, cellValue) => {
- if (column.property !== "supplierName") {
- return parseFloat(cellValue).toFixed(2);
- } else {
- return cellValue;
- }
-};
-getList();
-</script>
-
-<style scoped lang="scss">
-.el-pagination {
- width: 100%;
- height: 55px;
- display: flex;
- justify-content: flex-end;
- float: right;
- flex-direction: row;
- align-items: center;
- background: #fff;
- margin: -20px 0 0 0;
- padding: 0 20px;
-}
-.pagination-container {
- margin-top: 0;
-}
-</style>
diff --git a/src/views/procurementManagement/priceManagement/index.vue b/src/views/procurementManagement/priceManagement/index.vue
deleted file mode 100644
index 006ce3c..0000000
--- a/src/views/procurementManagement/priceManagement/index.vue
+++ /dev/null
@@ -1,276 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="鍟嗗搧鍚嶇О锛�">
- <el-input v-model="searchForm.productName" placeholder="璇疯緭鍏ュ晢鍝佸悕绉�" clearable />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О" clearable />
- </el-form-item>
- <el-form-item label="浠锋牸鐘舵�侊細">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="鏈夋晥" value="active" />
- <el-option label="宸茶繃鏈�" value="expired" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <el-button type="primary" @click="openDialog('add')">鏂板浠锋牸</el-button>
- <el-button type="success" @click="handleBatchUpdate">鎵归噺鏇存柊</el-button>
- <el-button type="danger" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
- </div>
-
- <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column label="鍘熶环鏍�" prop="oldPrice" width="120">
- <template #default="{ row }">楼{{ row.oldPrice.toFixed(2) }}</template>
- </el-table-column>
- <el-table-column label="鏂颁环鏍�" prop="newPrice" width="120">
- <template #default="{ row }">楼{{ row.newPrice.toFixed(2) }}</template>
- </el-table-column>
- <el-table-column label="璋冧环骞呭害" prop="priceChange" width="120">
- <template #default="{ row }">
- <span :style="{ color: row.priceChange >= 0 ? '#f56c6c' : '#67c23a' }">
- {{ row.priceChange >= 0 ? '+' : '' }}{{ row.priceChange.toFixed(2) }}%
- </span>
- </template>
- </el-table-column>
- <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="180" />
- <el-table-column label="鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" align="center">
- <template #default="{ row }">
- <el-button type="primary" link @click="openDialog('edit', row)">缂栬緫</el-button>
- <el-button type="success" link @click="handleApply(row)" v-if="row.status === 'pending'">搴旂敤</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板浠锋牸' : '缂栬緫浠锋牸'" width="600px">
- <el-form :model="formData" label-width="120px">
- <el-form-item label="鍟嗗搧鍚嶇О">
- <el-select v-model="formData.productName" placeholder="璇烽�夋嫨鍟嗗搧" style="width: 100%">
- <el-option label="鍟嗗搧A" value="鍟嗗搧A" />
- <el-option label="鍟嗗搧B" value="鍟嗗搧B" />
- <el-option label="鍟嗗搧C" value="鍟嗗搧C" />
- </el-select>
- </el-form-item>
- <el-form-item label="瑙勬牸鍨嬪彿">
- <el-input v-model="formData.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-select v-model="formData.supplierName" 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="鍘熶环鏍�">
- <el-input v-model="formData.oldPrice" placeholder="璇疯緭鍏ュ師浠锋牸" type="number" />
- </el-form-item>
- <el-form-item label="鏂颁环鏍�">
- <el-input v-model="formData.newPrice" placeholder="璇疯緭鍏ユ柊浠锋牸" type="number" />
- </el-form-item>
- <el-form-item label="鐢熸晥鏃堕棿">
- <el-date-picker v-model="formData.effectiveTime" type="datetime" placeholder="閫夋嫨鐢熸晥鏃堕棿" style="width: 100%" />
- </el-form-item>
- <el-form-item label="璋冧环鍘熷洜">
- <el-select v-model="formData.reason" placeholder="璇烽�夋嫨璋冧环鍘熷洜" style="width: 100%">
- <el-option label="甯傚満浠锋牸鍙樺姩" value="market" />
- <el-option label="鎴愭湰鍙樺寲" value="cost" />
- <el-option label="渚涘簲鍟嗚皟鏁�" value="supplier" />
- <el-option label="鍏朵粬鍘熷洜" value="other" />
- </el-select>
- </el-form-item>
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-
-const searchForm = reactive({
- productName: '',
- supplierName: '',
- status: ''
-})
-
-const formData = reactive({
- productName: '',
- specification: '',
- supplierName: '',
- oldPrice: 0,
- newPrice: 0,
- effectiveTime: '',
- reason: '',
- remark: ''
-})
-
-const mockData = [
- {
- id: 1,
- productName: '鍟嗗搧A',
- specification: '瑙勬牸1',
- supplierName: '渚涘簲鍟咥',
- oldPrice: 50.00,
- newPrice: 55.00,
- priceChange: 10.00,
- effectiveTime: '2025-12-01 00:00:00',
- status: 'active',
- reason: '甯傚満浠锋牸鍙樺姩',
- remark: '甯傚満浠锋牸涓婃定'
- },
- {
- id: 2,
- productName: '鍟嗗搧B',
- specification: '瑙勬牸2',
- supplierName: '渚涘簲鍟咮',
- oldPrice: 80.00,
- newPrice: 75.00,
- priceChange: -6.25,
- effectiveTime: '2025-12-01 00:00:00',
- status: 'active',
- reason: '鎴愭湰鍙樺寲',
- remark: '鎴愭湰涓嬮檷'
- }
-]
-
-const tableData = ref([...mockData])
-
-const getStatusType = (status) => {
- const statusMap = { active: 'success', expired: 'info', pending: 'warning' }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = { active: '鏈夋晥', expired: '宸茶繃鏈�', pending: '寰呯敓鏁�' }
- return statusMap[status] || '鏈煡'
-}
-
-const handleSearch = () => {
- loading.value = true
- setTimeout(() => { loading.value = false }, 500)
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, { productName: '', supplierName: '', status: '' })
-}
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- if (type === 'edit' && row.id) {
- Object.assign(formData, {
- productName: row.productName,
- specification: row.specification,
- supplierName: row.supplierName,
- oldPrice: row.oldPrice,
- newPrice: row.newPrice,
- effectiveTime: row.effectiveTime,
- reason: row.reason,
- remark: row.remark
- })
- } else {
- Object.assign(formData, {
- productName: '',
- specification: '',
- supplierName: '',
- oldPrice: 0,
- newPrice: 0,
- effectiveTime: '',
- reason: '',
- remark: ''
- })
- }
- dialogVisible.value = true
-}
-
-const handleSubmit = () => {
- if (dialogType.value === 'add') {
- const priceChange = ((formData.newPrice - formData.oldPrice) / formData.oldPrice) * 100
- const newPrice = {
- id: Date.now(),
- productName: formData.productName,
- specification: formData.specification,
- supplierName: formData.supplierName,
- oldPrice: formData.oldPrice,
- newPrice: formData.newPrice,
- priceChange: priceChange,
- effectiveTime: formData.effectiveTime,
- status: 'pending',
- reason: formData.reason,
- remark: formData.remark
- }
- tableData.value.unshift(newPrice)
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
-}
-
-const handleApply = (row) => {
- row.status = 'active'
- ElMessage.success('浠锋牸宸插簲鐢�')
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = tableData.value.findIndex(item => item.id === row.id)
- if (index !== -1) {
- tableData.value.splice(index, 1)
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const handleBatchUpdate = () => {
- ElMessage.success('鎵归噺鏇存柊鎴愬姛')
-}
-
-const handleBatchDelete = () => {
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-</script>
-
-<style scoped>
-.app-container { padding: 20px; }
-.search-card { margin-bottom: 20px; }
-.table-card { margin-bottom: 20px; }
-.table-header { margin-bottom: 20px; }
-</style>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue b/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
deleted file mode 100644
index f939be4..0000000
--- a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
+++ /dev/null
@@ -1,128 +0,0 @@
-<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-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>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getProductRecordById } from "@/api/procurementManagement/procurementInvoiceLedger";
-const { proxy } = getCurrentInstance()
-
-defineOptions({
- name: "鏉ョエ鍙拌处琛ㄥ崟",
-});
-const temFutureTickets = ref(0)
-const { form, resetForm } = useFormData({
- id: undefined,
- purchaseContractNumber: undefined, // 閲囪喘鍚堝悓鍙�
- salesContractNo: undefined, // 閿�鍞悎鍚屽彿
- createdAt: undefined, // 鍒涘缓鏃堕棿
- invoiceNumber: undefined, // 鍙戠エ鍙�
- ticketsNum: undefined, // 鏉ョエ鏁�
- ticketsAmount: undefined, // 鏉ョエ閲戦
- taxInclusiveUnitPrice: 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 inputTicketsNum = (val) => {
- // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
- if (!form.taxInclusiveUnitPrice || Number(form.taxInclusiveUnitPrice) === 0) {
- proxy.$modal.msgWarning("鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟");
- return;
- }
- if (Number(form.ticketsNum) > Number(temFutureTickets.value)) {
- proxy.$modal.msgWarning("寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
- form.ticketsNum = temFutureTickets.value
- }
-
- // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
- const futureTickets = Number(temFutureTickets.value) - Number(form.ticketsNum);
- form.futureTickets = Number(futureTickets.toFixed(2));
- form.ticketsAmount = Number(ticketsAmount.toFixed(2));
-};
-const inputTicketsAmount = (val) => {
- // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
- if (!form.taxInclusiveUnitPrice || Number(form.taxInclusiveUnitPrice) === 0) {
- proxy.$modal.msgWarning("鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟");
- 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))
- return;
- }
-
- // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsNum = Number(val) / Number(form.taxInclusiveUnitPrice);
- form.ticketsNum = Number(ticketsNum.toFixed(2));
-};
-
-defineExpose({
- load,
- form,
- resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/Modal/EditModal.vue b/src/views/procurementManagement/procurementInvoiceLedger/Modal/EditModal.vue
deleted file mode 100644
index 82b4164..0000000
--- a/src/views/procurementManagement/procurementInvoiceLedger/Modal/EditModal.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-<template>
- <el-dialog :title="modalOptions.title" v-model="visible" @close="close">
- <EditForm ref="editFormRef" />
- <template #footer>
- <el-button type="primary" :loading="loading" @click="sendForm">
- {{ modalOptions.confirmText }}
- </el-button>
- <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import EditForm from "../Form/EditForm.vue";
-import { updateRegistration } from "@/api/procurementManagement/procurementInvoiceLedger";
-import { ElMessage } from "element-plus";
-
-defineOptions({
- name: "鏉ョエ鍙拌处缂栬緫",
-});
-const emits = defineEmits(["success"]);
-
-const saleLedgerProjectId = ref('')
-const editFormRef = ref();
-const {
- id,
- visible,
- loading,
- openModal,
- modalOptions,
- handleConfirm,
- closeModal,
-} = useModal({ title: "鏉ョエ鍙拌处" });
-
-const open = async (row) => {
- openModal(row.id);
- saleLedgerProjectId.value = row.saleLedgerProjectId;
- await nextTick();
- editFormRef.value.load(row.id);
-};
-
-const close = () => {
- editFormRef.value.resetForm();
- closeModal();
-};
-
-const sendForm = async () => {
- const form = editFormRef.value.form;
- form.saleLedgerProjectId = saleLedgerProjectId.value;
- const { code } = await updateRegistration(form);
- if (code === 200) {
- emits("success");
- ElMessage({ message: "鎿嶄綔鎴愬姛", type: "success" });
- close();
- }
-};
-
-defineExpose({
- open,
-});
-</script>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/Modal/UploadModal.vue b/src/views/procurementManagement/procurementInvoiceLedger/Modal/UploadModal.vue
deleted file mode 100644
index b82bd10..0000000
--- a/src/views/procurementManagement/procurementInvoiceLedger/Modal/UploadModal.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-<template>
- <el-dialog v-model="upload.open" :title="upload.title" :width="500">
- <FileUpload
- ref="fileUploadRef"
- accept=".xlsx, .xls, .pdf"
- :headers="upload.headers"
- :autoUpload="true"
- :action="upload.url"
- :disabled="upload.isUploading"
- :showTip="false"
- :limit="10"
- @success="handleFileSuccess"
- @remove="removeFile"
- />
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
- <el-button @click="upload.open = false">鍙� 娑�</el-button>
- </div>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { reactive } from "vue";
-import { getToken } from "@/utils/auth.js";
-import { FileUpload } from "@/components/Upload";
-import { ElMessage } from "element-plus";
-import { ref } from "vue";
-import useFormData from "@/hooks/useFormData";
-
-defineOptions({
- name: "鏉ョエ鍙拌处闄勪欢琛ュ厖",
-});
-
-const { form, resetForm } = useFormData({
- id: undefined,
- tempFileIds: [],
-});
-const emits = defineEmits(["uploadSuccess"]);
-const fileUploadRef = ref();
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙渚涘簲鍟嗗鍏ワ級
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
-});
-// 鐐瑰嚮瀵煎叆
-const handleImport = (id) => {
- form.id = id;
- upload.open = true;
- upload.title = "鏉ョエ鍙拌处闄勪欢琛ュ厖";
-};
-
-const submitFileForm = () => {
- emits("uploadSuccess", form);
- resetForm();
- upload.open = false;
- // 娓呯┖鏂囦欢鍒楄〃
- fileUploadRef.value.fileList = [];
-};
-
-const handleFileSuccess = (response) => {
- if (response.code == 200) {
- form.tempFileIds.push(response.data.tempId);
- console.log('form',form);
- ElMessage({ message: "瀵煎叆鎴愬姛", type: "success" });
- } else {
- ElMessage({ message: response.msg, type: "error" });
- }
-};
-
-const removeFile = (file) => {
- const { tempId } = file.response.data;
- form.tempFileIds = form.tempFileIds.filter((item) => item !== tempId);
-};
-
-defineExpose({
- handleImport,
-});
-</script>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/index.vue b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
deleted file mode 100644
index b33e3e4..0000000
--- a/src/views/procurementManagement/procurementInvoiceLedger/index.vue
+++ /dev/null
@@ -1,360 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="閲囪喘鍚堝悓鍙�">
- <el-input
- v-model="filters.purchaseContractNumber"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="渚涘簲鍟�">
- <el-input
- v-model="filters.supplierName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- clearable
- :prefix-icon="Search"
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item label="鏉ョエ鏃ユ湡">
- <el-date-picker
- style="width: 240px"
- v-model="filters.createdAt"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="daterange"
- start-placeholder="寮�濮嬫椂闂�"
- end-placeholder="缁撴潫鏃堕棿"
- clearable
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData">鎼滅储</el-button>
- <el-button @click="resetFilters"> 閲嶇疆 </el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableLoading="loading"
- :tableData="dataList"
- :isSelection="true"
- height="calc(100vh - 19.5em)"
- :isShowSummary="true"
- :summaryMethod="summarizeMainTable"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
- >
- <template #commonFilesRef="{ row }">
- <el-dropdown @command="(command) => handleCommand(command, row)">
- <el-button link :icon="Files" type="danger"> 闄勪欢 </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item
- v-if="row.commonFiles.length !== 0"
- :icon="Download"
- command="download"
- >
- 涓嬭浇
- </el-dropdown-item>
- <el-dropdown-item :icon="Upload" command="upload">
- 涓婁紶
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </template>
- <template #operation="{ row }">
- <el-button
- type="primary"
- text
- @click="openEdit(row)"
- >
- 缂栬緫
- </el-button>
- <el-button
- type="primary"
- text
- @click="handleDelete(row)"
- >
- 鍒犻櫎
- </el-button>
- </template>
- </PIMTable>
- </div>
- <UploadModal ref="modalRef" @uploadSuccess="uploadSuccess"></UploadModal>
- <EditModal ref="editmodalRef" @success="getTableData"></EditModal>
- </div>
-</template>
-
-<script setup>
-import { ref, getCurrentInstance } from "vue";
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import {
- Files,
- Download,
- Search,
- Upload,
- EditPen,
-} from "@element-plus/icons-vue";
-import {
- delRegistration,
- productRecordPage,
- productUploadFile,
-} from "@/api/procurementManagement/procurementInvoiceLedger.js";
-import { onMounted } from "vue";
-import { ElMessageBox } from "element-plus";
-import UploadModal from "./Modal/UploadModal.vue";
-import EditModal from "./Modal/EditModal.vue";
-import useUserStore from "@/store/modules/user.js";
-import {delInvoiceLedgerByRegProductId} from "@/api/salesManagement/invoiceLedger.js";
-const userStore = useUserStore();
-
-defineOptions({
- name: "鏉ョエ鍙拌处",
-});
-
-const modalRef = ref();
-const editmodalRef = ref();
-
-const { proxy } = getCurrentInstance();
-const multipleVal = ref([]);
-const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- productRecordPage,
- {
- purchaseContractNumber: undefined, // 閲囪喘鍚堝悓鍙�
- supplierName: undefined, // 渚涘簲鍟�
- createdAt: [], // 鏉ョエ鏃ユ湡
- },
- [
- {
- label: "閲囪喘鍚堝悓鍙�",
- prop: "purchaseContractNumber",
- width: 150,
- },
- {
- label: "閿�鍞悎鍚屽彿",
- prop: "salesContractNo",
- width: 150,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width: 240,
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- width: 240,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 150,
- },
- {
- label: "鍙戠エ鍙�",
- prop: "invoiceNumber",
- width: 200,
- },
- {
- label: "鍚堝悓閲戦(鍏�)",
- prop: "taxInclusiveTotalPrice",
- width: 200,
- formatData: (cell) => {
- return cell ? parseFloat(cell).toFixed(2) : 0;
- },
- },
- {
- label: "寮�绁ㄦ棩鏈�",
- prop: "createdAt",
- width: 110,
- },
- {
- label: "寮�绁ㄩ噾棰�",
- prop: "ticketsAmount",
- width: 200,
- formatData: (cell) => {
- return cell ? parseFloat(cell).toFixed(2) : 0;
- },
- },
- {
- label: "涓嶅惈绋庨噾棰�",
- prop: "unTicketsPrice",
- width: 200,
- formatData: (cell) => {
- return cell ? parseFloat(cell).toFixed(2) : 0;
- },
- },
- {
- label: "澧炲�肩◣",
- prop: "invoiceAmount",
- width: 200,
- },
- {
- label: "褰曞叆浜�",
- prop: "issUer",
- width: 200,
- },
- {
- label: "闄勪欢",
- align: "center",
- prop: "commonFiles",
- dataType: "slot",
- fixed: "right",
- slot: "commonFilesRef",
- width: 120,
- },
- {
- fixed: "right",
- width: 150,
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- },
- ],
- {},
- {
- createdAt: (aim) => ({
- createdAtStart: aim ? aim[0] : undefined,
- createdAtEnd: aim ? aim[1] : undefined,
- }),
- }
-);
-
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- [
- "taxInclusiveTotalPrice",
- "ticketsAmount",
- "unTicketsPrice",
- "invoiceAmount",
- ],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-
-const handleSelectionChange = (val) => {
- multipleVal.value = val;
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/registration/export", {}, "鏉ョエ鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-const handleFiles = (fileList) => {
- fileList.forEach((e) => {
- proxy.$download.name(e.url);
- });
-};
-
-const changePage = ({ page, limit }) => {
- pagination.currentPage = page;
- pagination.pageSize = limit;
- onCurrentChange(page);
-};
-
-const handleCommand = (command, row) => {
- switch (command) {
- case "download":
- handleFiles(row.commonFiles);
- break;
- case "upload":
- console.log(row.commonFiles);
- openUoload(row.ticketRegistrationId);
- break;
- }
-};
-
-const openUoload = (id) => {
- modalRef.value.handleImport(id);
-};
-
-const openEdit = (row) => {
- editmodalRef.value.open(row);
-};
-
-// 涓婁紶鎴愬姛鍚庡仛浠�涔�
-const uploadSuccess = async (data) => {
- const { code } = await productUploadFile({
- ticketRegistrationId: data.id,
- tempFileIds: data.tempFileIds,
- });
- if (code === 200) {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- getTableData();
- }
-};
-// 鍒犻櫎
-const handleDelete = (row) => {
- let ids = [];
- ids.push(row.id);
- ElMessageBox.confirm("璇ュ紑绁ㄥ彴璐﹀皢琚垹闄�,鏄惁纭鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- loading.value = true;
- delRegistration(ids).then((res) => {
- getTableData();
- });
- loading.value = false;
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getTableData();
-});
-</script>
-
-<style lang="scss" scoped>
-.table_list {
- margin-top: unset;
-}
-.tagBox {
- margin-top: 4px;
-}
-</style>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue b/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
deleted file mode 100644
index 987e6a4..0000000
--- a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
+++ /dev/null
@@ -1,311 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">閲囪喘鍚堝悓鍙凤細</span>
- <el-input
- v-model="searchForm.purchaseContractNumber"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title" style="margin-left: 10px">渚涘簲鍟嗭細</span>
- <el-input
- v-model="searchForm.supplierName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <span class="search_title" style="margin-left: 10px">鏉ョエ鏃ユ湡锛�</span>
- <el-date-picker
- style="width: 240px"
- v-model="searchForm.issueDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="daterange"
- start-placeholder="寮�濮嬫椂闂�"
- end-placeholder="缁撴潫鏃堕棿"
- clearable
- @change="changeDateRange"
- @clear="clearRange"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </div>
- </div>
- <div class="table_list">
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- height="calc(100vh - 18.5em)"
- >
- <el-table-column align="center" label="搴忓彿" type="index" width="55" />
- <el-table-column type="expand">
- <template #default="props">
- <el-table
- :data="props.row.children"
- border
- show-summary
- :summary-method="summarizeChildrenTable"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column label="鏈鏉ョエ鏁�" prop="ticketsNum" />
- <el-table-column
- label="鏈鏉ョエ閲戦(鍏�)"
- prop="ticketsAmount"
- :formatter="formattedNumber"
- />
- <el-table-column label="鏈潵绁ㄦ暟" prop="futureTickets" />
- <el-table-column
- label="鏈潵绁ㄩ噾棰�(鍏�)"
- prop="futureTicketsAmount"
- :formatter="formattedNumber"
- />
- </el-table>
- </template>
- </el-table-column>
- <el-table-column
- label="閲囪喘鍚堝悓鍙�"
- prop="purchaseContractNumber"
- show-overflow-tooltip
- />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍙戠エ鍙�"
- prop="invoiceNumber"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚堝悓閲戦(鍏�)"
- prop="invoiceAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column label="寮�绁ㄤ汉" prop="issUer" show-overflow-tooltip />
- <el-table-column
- label="寮�绁ㄦ棩鏈�"
- prop="issueDate"
- show-overflow-tooltip
- />
- </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 pagination from "@/components/PIMTable/Pagination.vue";
-import { ref } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { ElMessageBox } from "element-plus";
-import {
- invoiceListPage,
- productRecordList,
-} from "@/api/procurementManagement/procurementInvoiceLedger.js";
-import dayjs from "dayjs";
-
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const data = reactive({
- searchForm: {
- purchaseContractNumber: "",
- supplierName: "",
- issueDate: [
- dayjs().startOf("month").format("YYYY-MM-DD"),
- dayjs().endOf("month").format("YYYY-MM-DD"),
- ],
- issueDateStart: dayjs().startOf("month").format("YYYY-MM-DD"),
- issueDateEnd: dayjs().endOf("month").format("YYYY-MM-DD"),
- },
- form: {
- issueDate: "", // 寮�绁ㄦ棩鏈�
- purchaseLedgerId: "",
- purchaseLedgerNo: "",
- issUerId: "", // 寮�绁ㄤ汉id
- issUer: "", // 寮�绁ㄤ汉濮撳悕
- },
- rules: {
- purchaseLedgerId: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- },
-});
-const { searchForm } = toRefs(data);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { issueDate, ...rest } = searchForm.value;
- invoiceListPage({ ...rest, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- tableData.value.map((item) => {
- item.children = [];
- });
- total.value = res.total;
- expandedRowKeys.value = [];
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productRecordList({ id: row.id }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ["invoiceAmount"], {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- });
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(
- param,
- [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "ticketsNum",
- "ticketsAmount",
- "futureTickets",
- "futureTicketsAmount",
- ],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/registration/export", {}, "鏉ョエ鐧昏.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-const changeDateRange = (date) => {
- if (date) {
- searchForm.value.receiptPaymentDateStart = date[0];
- searchForm.value.receiptPaymentDateEnd = date[1];
- getList();
- }
-};
-
-const clearRange = () => {
- searchForm.value.issueDate = [];
- searchForm.value.issueDateStart = undefined;
- searchForm.value.issueDateEnd = undefined;
- getList();
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
deleted file mode 100644
index 571e7ab..0000000
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ /dev/null
@@ -1,1609 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="閲囪喘鍚堝悓鍙凤細">
- <el-input
- v-model="searchForm.purchaseContractNumber"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="閿�鍞悎鍚屽彿锛�">
- <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О锛�">
- <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="褰曞叆鏃ユ湡锛�">
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- </el-form-item>
- </el-form>
- </div>
-
- </div>
- <div class="table_list">
- <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
- <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
- <el-button type="success" @click="openScanAddDialog">鎵爜鏂板</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- height="calc(100vh - 18.5em)"
- >
- <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-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- </el-table>
- </template>
- </el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="閲囪喘鍚堝悓鍙�"
- prop="purchaseContractNumber"
- width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="渚涘簲鍟嗗悕绉�"
- width="240"
- prop="supplierName"
- show-overflow-tooltip
- />
- <el-table-column
- label="椤圭洰鍚嶇О"
- prop="projectName"
- width="420"
- show-overflow-tooltip
- />
- <el-table-column
- label="浠樻鏂瑰紡"
- width="100"
- prop="paymentMethod"
- show-overflow-tooltip
- />
- <el-table-column
- label="鍚堝悓閲戦(鍏�)"
- prop="contractAmount"
- width="200"
- show-overflow-tooltip
- :formatter="formattedNumber"
- />
- <el-table-column
- label="褰曞叆浜�"
- prop="recorderName"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- label="褰曞叆鏃ユ湡"
- prop="entryDate"
- width="100"
- show-overflow-tooltip
- />
- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- min-width="150"
- align="center"
- >
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="openForm('edit', scope.row)"
- >缂栬緫</el-button
- >
- <el-button
- link
- type="success"
- size="small"
- @click="showQRCode(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"
- />
- </div>
- <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"
- >
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
- <el-input
- v-model="form.purchaseContractNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
- <el-select
- v-model="form.salesLedgerId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="salesLedgerChange"
- >
- <el-option
- v-for="item in salesContractList"
- :key="item.id"
- :label="item.salesContractNo"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
- <el-select
- v-model="form.supplierId"
- placeholder="璇烽�夋嫨"
- clearable
- filterable
- allow-create
- >
- <el-option
- v-for="item in supplierList"
- :key="item.id"
- :label="item.supplierName"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡">
- <el-input
- v-model="form.paymentMethod"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.executionDate"
- 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="recorderId">
- <el-select
- v-model="form.recorderId"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- >
- <el-option
- v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.entryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
- <el-button type="primary" @click="openProductForm('add')"
- >娣诲姞</el-button
- >
- <el-button plain type="danger" @click="deleteProduct"
- >鍒犻櫎</el-button
- >
- </el-form-item>
- </el-row>
- <el-table
- :data="productData"
- border
- @selection-change="productSelected"
- show-summary
- :summary-method="summarizeProTable"
- >
- <el-table-column align="center" type="selection" width="55" />
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="鏁伴噺" prop="quantity" width="70" />
- <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column
- fixed="right"
- label="鎿嶄綔"
- min-width="60"
- align="center"
- >
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="openProductForm('edit', scope.row, scope.$index)"
- >缂栬緫</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="澶囨敞路锛�" prop="remark">
- <el-input
- v-model="form.remark"
- placeholder="璇疯緭鍏�"
- clearable
- type="textarea"
- :rows="2"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload
- v-model:file-list="fileList"
- :action="upload.url"
- multiple
- ref="fileUpload"
- auto-upload
- :headers="upload.headers"
- :before-upload="handleBeforeUpload"
- :on-error="handleUploadError"
- :on-success="handleUploadSuccess"
- :on-remove="handleRemove"
- >
- <el-button type="primary">涓婁紶</el-button>
- <template #tip>
- <div class="el-upload__tip">
- 鏂囦欢鏍煎紡鏀寔
- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
- </div>
- </template>
- </el-upload>
- </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>
- <el-dialog
- v-model="productFormVisible"
- :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
- width="40%"
- @close="closeProductDia"
- >
- <el-form
- :model="productForm"
- label-width="140px"
- label-position="top"
- :rules="productRules"
- ref="productFormRef"
- >
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="浜у搧澶х被锛�" prop="productId">
- <el-tree-select
- v-model="productForm.productId"
- placeholder="璇烽�夋嫨"
- clearable
- check-strictly
- @change="getModels"
- :data="productOptions"
- :render-after-expand="false"
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
- <el-select
- v-model="productForm.productModelId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="getProductModel"
- >
- <el-option
- v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="productForm.unit"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
- <el-select
- v-model="productForm.taxRate"
- placeholder="璇烽�夋嫨"
- clearable
- @change="mathNum"
- >
- <el-option label="1" value="1" />
- <el-option label="6" value="6" />
- <el-option label="13" value="13" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
- <el-input-number
- v-model="productForm.taxInclusiveUnitPrice"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="mathNum"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏁伴噺锛�" prop="quantity">
- <el-input-number
- :step="0.1"
- clearable
- :precision="2"
- style="width: 100%"
- v-model="productForm.quantity"
- placeholder="璇疯緭鍏�"
- @change="mathNum"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
- <el-input-number
- v-model="productForm.taxInclusiveTotalPrice"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- @change="reverseMathNum('taxInclusiveTotalPrice')"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="涓嶅惈绋庢�讳环(鍏�)锛�"
- prop="taxExclusiveTotalPrice"
- >
- <el-input
- v-model="productForm.taxExclusiveTotalPrice"
- @change="reverseMathNum('taxExclusiveTotalPrice')"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
- <el-select
- v-model="productForm.invoiceType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
- <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
- <el-input-number
- v-model="productForm.warnNum"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitProduct">纭</el-button>
- <el-button @click="closeProductDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
- <el-dialog
- v-model="qrCodeDialogVisible"
- title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
- width="400px"
- center
- >
- <div style="text-align: center;">
- <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
- <div style="margin: 20px;">
- <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
- </div>
- </div>
- </el-dialog>
-
- <!-- 鎵爜鏂板瀵硅瘽妗� -->
- <el-dialog
- v-model="scanAddDialogVisible"
- title="鎵爜鏂板閲囪喘鍙拌处"
- width="70%"
- @close="closeScanAddDialog"
- >
- <el-form
- :model="scanAddForm"
- label-width="140px"
- label-position="top"
- :rules="scanAddRules"
- ref="scanAddFormRef"
- >
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="鎵爜鍐呭锛�">
- <el-input
- v-model="scanAddForm.scanContent"
- type="textarea"
- :rows="3"
- placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
- @input="parseScanContent"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
- <el-input
- v-model="scanAddForm.purchaseContractNumber"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
- <el-input
- v-model="scanAddForm.supplierName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="scanAddForm.projectName"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚堝悓閲戦(鍏�)锛�" prop="contractAmount">
- <el-input-number
- v-model="scanAddForm.contractAmount"
- :precision="2"
- :step="0.1"
- clearable
- style="width: 100%"
- placeholder="璇疯緭鍏�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡锛�">
- <el-input
- v-model="scanAddForm.paymentMethod"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆浜猴細">
- <el-input v-model="scanAddForm.recorderName" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞锛�">
- <el-input
- v-model="scanAddForm.remark"
- type="textarea"
- :rows="2"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitScanAdd">纭鏂板</el-button>
- <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鎵爜鐧昏瀵硅瘽妗� -->
- <el-dialog
- v-model="scanDialogVisible"
- title="鎵爜鐧昏"
- width="60%"
- @close="closeScanDialog"
- >
- <el-form
- :model="scanForm"
- label-width="120px"
- label-position="left"
- :rules="scanRules"
- ref="scanFormRef"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閲囪喘鍚堝悓鍙凤細">
- <el-input v-model="scanForm.purchaseContractNumber" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="scanForm.supplierName" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�">
- <el-input v-model="scanForm.projectName" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎵爜鏃堕棿锛�">
- <el-input v-model="scanForm.scanTime" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鎵爜浜猴細">
- <el-input v-model="scanForm.scannerName" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鎵爜鐘舵�侊細">
- <el-tag :type="scanForm.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
- {{ scanForm.scanStatus }}
- </el-tag>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="鎵爜澶囨敞锛�">
- <el-input
- v-model="scanForm.scanRemark"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="鎵爜璁板綍锛�">
- <el-table :data="scanRecords" border style="width: 100%">
- <el-table-column label="搴忓彿" type="index" width="60" align="center" />
- <el-table-column label="鎵爜鏃堕棿" prop="scanTime" width="180" />
- <el-table-column label="鎵爜浜�" prop="scannerName" width="120" />
- <el-table-column label="鎵爜鐘舵��" prop="scanStatus" width="100">
- <template #default="scope">
- <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
- {{ scope.row.scanStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="澶囨敞" prop="scanRemark" />
- </el-table>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitScan">纭鎵爜</el-button>
- <el-button @click="closeScanDialog">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { getToken } from "@/utils/auth";
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { ElMessageBox } from "element-plus";
-import { userListNoPage } from "@/api/system/user.js";
-import {
- getSalesLedgerWithProducts,
- addOrUpdateSalesLedgerProduct,
- delProduct,
- delLedgerFile,
- getProductInfoByContractNo,
-} from "@/api/salesManagement/salesLedger.js";
-import {
- addOrEditPurchase,
- delPurchase,
- getSalesNo,
- purchaseListPage,
- productList,
- getPurchaseById,
- getOptions,
- createPurchaseNo,
-} from "@/api/procurementManagement/procurementLedger.js";
-import useFormData from "@/hooks/useFormData.js";
-import QRCode from "qrcode";
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const modelOptions = ref([]);
-const userList = ref([]);
-const productOptions = ref([]);
-const salesContractList = ref([]);
-const supplierList = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
-import useUserStore from "@/store/modules/user";
-import { modelList, productTreeList } from "@/api/basicData/product.js";
-import dayjs from "dayjs";
-
-const userStore = useUserStore();
-
-// 浜岀淮鐮佺浉鍏冲彉閲�
-const qrCodeDialogVisible = ref(false);
-const qrCodeUrl = ref("");
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- supplierName: "", // 渚涘簲鍟嗗悕绉�
- purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
- salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
- projectName: "", // 椤圭洰鍚嶇О
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- form: {
- purchaseContractNumber: "",
- salesLedgerId: "",
- projectName: "",
- recorderId: "",
- entryDate: "",
- productData: [],
- supplierName: "",
- supplierId: "",
- paymentMethod: "",
- executionDate: "",
- },
- rules: {
- purchaseContractNumber: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm } = useFormData(data.searchForm);
-
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const productOperationIndex = ref("");
-const currentId = ref("");
-const productFormData = reactive({
- productForm: {
- productId: "",
- productCategory: "",
- productModelId: "",
- specificationModel: "",
- unit: "",
- quantity: "",
- taxInclusiveUnitPrice: "",
- taxRate: "",
- taxInclusiveTotalPrice: "",
- taxExclusiveTotalPrice: "",
- invoiceType: "",
- warnNum: "",
- },
- productRules: {
- productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxInclusiveUnitPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- warnNum: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
- taxInclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { productForm, productRules } = toRefs(productFormData);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-
-const changeDaterange = (value) => {
- if (value) {
- searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.entryDateStart = undefined;
- searchForm.entryDateEnd = undefined;
- }
- handleQuery();
-};
-
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(
- param,
- [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "ticketsNum",
- "ticketsAmount",
- "futureTickets",
- "futureTicketsAmount",
- ],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { entryDate, ...rest } = searchForm;
- purchaseListPage({ ...rest, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- tableData.value.map((item) => {
- item.children = [];
- });
- total.value = res.data.total;
- expandedRowKeys.value = [];
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-const productSelected = (selectedRows) => {
- productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 2 }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ["contractAmount"]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeProTable = (param) => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
-};
-// 鎵撳紑寮规
-const openForm = (type, row) => {
- operationType.value = type;
- form.value = {};
- productData.value = [];
- fileList.value = [];
- if (operationType.value == "add") {
- createPurchaseNo().then((res) => {
- form.value.purchaseContractNumber = res.data;
- });
- }
- userListNoPage().then((res) => {
- userList.value = res.data;
- });
- getSalesNo().then((res) => {
- salesContractList.value = res;
- });
- getOptions().then((res) => {
- supplierList.value = res.data;
- });
- form.value.recorderId = userStore.id;
- form.value.entryDate = getCurrentDate();
- if (type === "edit") {
- currentId.value = row.id;
- getPurchaseById({ id: row.id, type: 2 }).then((res) => {
- form.value = { ...res };
- productData.value = form.value.productData;
- if (form.value.salesLedgerFiles) {
- fileList.value = form.value.salesLedgerFiles;
- } else {
- fileList.value = [];
- }
- });
- }
- dialogFormVisible.value = true;
-};
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- // 鏍℃鏂囦欢澶у皬
- if (file.size > 1024 * 1024 * 10) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- return false;
- }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- console.log("handleRemove", file.id);
- if (file.size > 1024 * 1024 * 10) {
- // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
- return;
- }
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- if (productData.value.length > 0) {
- form.value.productData = proxy.HaveJson(productData.value);
- } else {
- proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
- return;
- }
- let tempFileIds = [];
- if (fileList.value.length > 0) {
- tempFileIds = fileList.value.map((item) => item.tempId);
- }
- form.value.tempFileIds = tempFileIds;
- form.value.type = 2;
- addOrEditPurchase(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 鎵撳紑浜у搧寮规
-const openProductForm = (type, row, index) => {
- productOperationType.value = type;
- productOperationIndex.value = index;
- productForm.value = {};
- proxy.resetForm("productFormRef");
- if (type === "edit") {
- productForm.value = { ...row };
- }
- productFormVisible.value = true;
- getProductOptions();
-};
-const getProductOptions = () => {
- productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- });
-};
-const getModels = (value) => {
- if (value) {
- productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
- modelList({ id: value }).then((res) => {
- modelOptions.value = res;
- });
- } else {
- productForm.value.productCategory = "";
- modelOptions.value = [];
- }
-};
-const getProductModel = (value) => {
- const index = modelOptions.value.findIndex((item) => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
- } else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
- }
-};
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitProduct = () => {
- proxy.$refs["productFormRef"].validate((valid) => {
- if (valid) {
- if (operationType.value === "edit") {
- submitProductEdit();
- } else {
- if (productOperationType.value === "add") {
- productData.value.push({ ...productForm.value });
- console.log("productData.value---", productData.value);
- } else {
- productData.value[productOperationIndex.value] = {
- ...productForm.value,
- };
- }
- closeProductDia();
- }
- }
- });
-};
-const submitProductEdit = () => {
- productForm.value.salesLedgerId = currentId.value;
- productForm.value.type = 2;
- addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProductDia();
- getPurchaseById({ id: currentId.value, type: 2 }).then((res) => {
- productData.value = res.productData;
- });
- });
-};
-// 鍒犻櫎浜у搧
-const deleteProduct = () => {
- if (productSelectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- if (operationType.value === "add") {
- productSelectedRows.value.forEach((selectedRow) => {
- const index = productData.value.findIndex(
- (product) => product.id === selectedRow.id
- );
- if (index !== -1) {
- productData.value.splice(index, 1);
- }
- });
- } else {
- let ids = [];
- if (productSelectedRows.value.length > 0) {
- ids = productSelectedRows.value.map((item) => item.id);
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delProduct(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- closeProductDia();
- getSalesLedgerWithProducts({ id: currentId.value, type: 2 }).then(
- (res) => {
- productData.value = res.productData;
- }
- );
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
- }
-};
-// 鍏抽棴浜у搧寮规
-const closeProductDia = () => {
- proxy.resetForm("productFormRef");
- productFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
- const unauthorizedData = selectedRows.value.filter(item => item.recorderName !== userStore.nickName);
- if (unauthorizedData.length > 0) {
- proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delPurchase(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-const mathNum = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (!productForm.value.taxInclusiveUnitPrice) {
- return;
- }
- if (!productForm.value.quantity) {
- return;
- }
- // 鍚◣鎬讳环璁$畻
- productForm.value.taxInclusiveTotalPrice =
- proxy.calculateTaxIncludeTotalPrice(
- productForm.value.taxInclusiveUnitPrice,
- productForm.value.quantity
- );
- if (productForm.value.taxRate) {
- // 涓嶅惈绋庢�讳环璁$畻
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-};
-const reverseMathNum = (field) => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- const taxRate = Number(productForm.value.taxRate);
- if (!taxRate) return;
- if (field === 'taxInclusiveTotalPrice') {
- // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
- }
- // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
- }
- // 鍙嶇畻涓嶅惈绋庢�讳环
- productForm.value.taxExclusiveTotalPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)).toFixed(2);
- } else if (field === 'taxExclusiveTotalPrice') {
- // 鍙嶇畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice =
- (Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)).toFixed(2);
- // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2);
- }
- // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity =
- (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2);
- }
- }
-};
-// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
-const salesLedgerChange = async (row) => {
- console.log("row", row);
- var index = salesContractList.value.findIndex((item) => item.id == row);
- console.log("index", index);
- if (index > -1) {
- form.value.projectName = salesContractList.value[index].projectName;
- await querygProductInfoByContractNo();
- }
-};
-
-const querygProductInfoByContractNo = async () => {
- const { code, data } = await getProductInfoByContractNo({
- contractNo: form.value.salesLedgerId,
- });
- if (code == 200) {
- productData.value = data;
- }
-};
-
-// 鏄剧ず浜岀淮鐮�
-const showQRCode = async (row) => {
- try {
- // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
- const qrContent = row.purchaseContractNumber || '';
- // 妫�鏌ュ唴瀹规槸鍚︿负绌�
- if (!qrContent || qrContent.trim() === '') {
- proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
- return;
- }
- qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
- width: 200,
- margin: 2,
- color: {
- dark: '#000000',
- light: '#FFFFFF'
- }
- });
- qrCodeDialogVisible.value = true;
- } catch (error) {
- console.error('鐢熸垚浜岀淮鐮佸け璐�:', error);
- proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
- }
-};
-
-// 涓嬭浇浜岀淮鐮�
-const downloadQRCode = () => {
- if (!qrCodeUrl.value) {
- proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
- return;
- }
-
- const a = document.createElement('a');
- a.href = qrCodeUrl.value;
- a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${new Date().getTime()}.png`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
-};
-
-// 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
-const scanAddDialogVisible = ref(false);
-const scanAddForm = reactive({
- scanContent: "",
- purchaseContractNumber: "",
- supplierName: "",
- projectName: "",
- contractAmount: "",
- paymentMethod: "",
- recorderName: "",
- scanRemark: "",
-});
-const scanAddRules = {
- purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
- supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }],
- projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
-};
-
-// 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
-const scanDialogVisible = ref(false);
-const scanForm = reactive({
- purchaseContractNumber: "",
- supplierName: "",
- projectName: "",
- scanTime: "",
- scannerName: "",
- scanStatus: "鏈壂鐮�",
- scanRemark: "",
-});
-const scanRules = {
- scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
-};
-const scanRecords = ref([]);
-
-// 鎵撳紑鎵爜鏂板瀵硅瘽妗�
-const openScanAddDialog = () => {
- scanAddForm.scanContent = "";
- scanAddForm.purchaseContractNumber = "";
- scanAddForm.supplierName = "";
- scanAddForm.projectName = "";
- scanAddForm.contractAmount = "";
- scanAddForm.paymentMethod = "";
- scanAddForm.recorderName = userStore.nickName;
- scanAddForm.scanRemark = "";
- scanAddDialogVisible.value = true;
-};
-
-// 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
-const parseScanContent = (content) => {
- if (!content) return;
-
- // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
- // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡椤圭洰|閲戦|浠樻鏂瑰紡
- const parts = content.split('|');
- if (parts.length >= 3) {
- scanAddForm.purchaseContractNumber = parts[0] || "";
- scanAddForm.supplierName = parts[1] || "";
- scanAddForm.projectName = parts[2] || "";
- scanAddForm.contractAmount = parts[3] || "";
- scanAddForm.paymentMethod = parts[4] || "";
- }
-};
-
-// 鍏抽棴鎵爜鏂板瀵硅瘽妗�
-const closeScanAddDialog = () => {
- scanAddDialogVisible.value = false;
- proxy.resetForm("scanAddFormRef");
-};
-
-// 鎻愪氦鎵爜鏂板
-const submitScanAdd = () => {
- proxy.$refs["scanAddFormRef"].validate((valid) => {
- if (valid) {
- // 鏋勫缓鏂板鏁版嵁
- const newData = {
- purchaseContractNumber: scanAddForm.purchaseContractNumber,
- supplierName: scanAddForm.supplierName,
- projectName: scanAddForm.projectName,
- contractAmount: scanAddForm.contractAmount,
- paymentMethod: scanAddForm.paymentMethod,
- recorderName: scanAddForm.recorderName,
- entryDate: getCurrentDate(),
- remark: scanAddForm.scanRemark,
- type: 2
- };
-
- // 妯℃嫙鏂板鎴愬姛
- proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
- closeScanAddDialog();
-
- // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
- // getList();
- }
- });
-};
-
-// 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
-const openScanDialog = (row) => {
- scanForm.purchaseContractNumber = row.purchaseContractNumber;
- scanForm.supplierName = row.supplierName;
- scanForm.projectName = row.projectName;
- scanForm.scanTime = getCurrentDateTime();
- scanForm.scannerName = userStore.nickName;
- scanForm.scanStatus = "鏈壂鐮�";
- scanForm.scanRemark = "";
- scanRecords.value = [];
- scanDialogVisible.value = true;
-};
-
-// 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
-const closeScanDialog = () => {
- scanDialogVisible.value = false;
- proxy.resetForm("scanFormRef");
-};
-
-// 鎻愪氦鎵爜鐧昏
-const submitScan = () => {
- proxy.$refs["scanFormRef"].validate((valid) => {
- if (valid) {
- // 娣诲姞鎵爜璁板綍
- scanRecords.value.push({
- ...scanForm,
- id: Date.now(), // 妯℃嫙ID
- scanTime: getCurrentDateTime(),
- });
- scanForm.scanStatus = "宸叉壂鐮�";
- scanForm.scanRemark = scanForm.scanRemark || "鏃�";
- proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
- closeScanDialog();
- }
- });
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
-function getCurrentDateTime() {
- const now = new Date();
- const year = now.getFullYear();
- const month = String(now.getMonth() + 1).padStart(2, "0");
- const day = String(now.getDate()).padStart(2, "0");
- const hours = String(now.getHours()).padStart(2, "0");
- const minutes = String(now.getMinutes()).padStart(2, "0");
- const seconds = String(now.getSeconds()).padStart(2, "0");
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-}
-
-
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/procurementManagement/procurementPlan/index.vue b/src/views/procurementManagement/procurementPlan/index.vue
deleted file mode 100644
index 14424cc..0000000
--- a/src/views/procurementManagement/procurementPlan/index.vue
+++ /dev/null
@@ -1,784 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎼滅储鍖哄煙 -->
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true" class="search-form">
- <el-form-item label="璁″垝鍚嶇О">
- <el-input v-model="searchForm.planName" placeholder="璇疯緭鍏ヨ鍒掑悕绉�" clearable />
- </el-form-item>
- <el-form-item label="鐘舵��">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 150px">
- <el-option label="鍚敤" value="active" />
- <el-option label="绂佺敤" value="disabled" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">
- <el-icon><Search /></el-icon>
- 鎼滅储
- </el-button>
- <el-button @click="handleReset">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 鎿嶄綔鎸夐挳 -->
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <div class="table-title">閲囪喘璁″垝鍒楄〃</div>
- <div class="table-actions">
- <el-button type="primary" @click="handleAdd">
- <el-icon><Plus /></el-icon>
- 鏂板璁″垝
- </el-button>
- <el-button type="info" @click="handleExport">
- <el-icon><Download /></el-icon>
- 瀵煎嚭
- </el-button>
- </div>
- </div>
-
- <!-- 鏁版嵁琛ㄦ牸 -->
- <el-table
- v-loading="loading"
- :data="tableData"
- stripe
- border
- style="width: 100%"
- >
- <el-table-column prop="planName" label="璁″垝鍚嶇О" min-width="150" />
- <el-table-column prop="description" label="鎻忚堪" min-width="200" show-overflow-tooltip />
- <el-table-column prop="formula" label="璁$畻鍏紡" min-width="200" show-overflow-tooltip>
- <template #default="{ row }">
- <el-tag type="info" size="small">{{ row.formula }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="80" align="center">
- <template #default="{ row }">
- <el-tag :type="row.status === 'active' ? 'success' : 'info'" size="small">
- {{ row.status === 'active' ? '鍚敤' : '绂佺敤' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="updateTime" label="鏈�鍚庤绠楁椂闂�" width="160" />
- <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
- <template #default="{ row }">
- <el-button type="primary" link @click="handleEdit(row)">缂栬緫</el-button>
- <el-button type="success" link @click="handleCalculate(row)">璁$畻</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <div class="pagination-container">
- <el-pagination
- v-model:current-page="pagination.current"
- v-model:page-size="pagination.size"
- :page-sizes="[10, 20, 50, 100]"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogType === 'add' ? '鏂板閲囪喘璁″垝' : '缂栬緫閲囪喘璁″垝'"
- width="1000px"
- :close-on-click-modal="false"
- >
- <div class="form-container">
- <!-- 鍩烘湰淇℃伅 -->
- <div class="form-section">
- <div class="section-title">鍩烘湰淇℃伅</div>
- <el-form
- ref="formRef"
- :model="formData"
- :rules="formRules"
- label-width="120px"
- >
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="缂栫爜" prop="code">
- <el-input v-model="formData.code" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍚嶇О" prop="planName" required>
- <el-input v-model="formData.planName" placeholder="璇疯緭鍏ヨ鍒掑悕绉�" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="鎻忚堪" prop="description">
- <el-input
- v-model="formData.description"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ヨ鍒掓弿杩�"
- />
- </el-form-item>
-
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="formData.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option label="鍚敤" value="active" />
- <el-option label="绂佺敤" value="disabled" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏄惁绯荤粺棰勭疆">
- <el-checkbox v-model="formData.isSystemPreset">鏄�</el-checkbox>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
-
- <!-- 璁$畻鍙傛暟 -->
- <div class="form-section">
- <div class="section-title">璁$畻鍙傛暟</div>
- <el-tabs v-model="activeTab" class="param-tabs">
- <el-tab-pane label="闇�姹傚弬鏁�" name="demand">
- <div class="checkbox-group">
- <el-checkbox v-model="formData.considerExistingStock">鑰冭檻鐜版湁搴撳瓨</el-checkbox>
- <el-checkbox v-model="formData.warehouseControl">浠撳簱杩愯MRP鐨勬帶鍒�</el-checkbox>
- <el-checkbox v-model="formData.calculateTotalDemand">璁$畻鎬婚渶姹�</el-checkbox>
- <el-checkbox v-model="formData.considerSafetyStock">鑰冭檻瀹夊叏搴撳瓨</el-checkbox>
- <el-checkbox v-model="formData.considerLockedStock">鑰冭檻閿佸簱</el-checkbox>
- <el-checkbox v-model="formData.notConsiderMaterialAux">涓嶈�冭檻鐗╂枡杈呭姪灞炴��</el-checkbox>
- <el-checkbox v-model="formData.negativeStockAsDemand">璐熷簱瀛樹綔涓洪渶姹�</el-checkbox>
- </div>
- </el-tab-pane>
- <el-tab-pane label="璁$畻鍙傛暟" name="calculation">
- <div class="checkbox-group">
- <el-checkbox v-model="formData.considerExistingStock">鑰冭檻鐜版湁搴撳瓨</el-checkbox>
- <el-checkbox v-model="formData.warehouseControl">浠撳簱杩愯MRP鐨勬帶鍒�</el-checkbox>
- <el-checkbox v-model="formData.calculateTotalDemand">璁$畻鎬婚渶姹�</el-checkbox>
- <el-checkbox v-model="formData.considerSafetyStock">鑰冭檻瀹夊叏搴撳瓨</el-checkbox>
- <el-checkbox v-model="formData.considerLockedStock">鑰冭檻閿佸簱</el-checkbox>
- <el-checkbox v-model="formData.notConsiderMaterialAux">涓嶈�冭檻鐗╂枡杈呭姪灞炴��</el-checkbox>
- <el-checkbox v-model="formData.negativeStockAsDemand">璐熷簱瀛樹綔涓洪渶姹�</el-checkbox>
- </div>
- </el-tab-pane>
- </el-tabs>
- </div>
-
- <!-- 姹囨�诲悎骞堕�夐」 -->
- <div class="form-section">
- <div class="section-title">姹囨�诲悎骞堕�夐」</div>
- <div class="checkbox-group">
- <el-checkbox v-model="formData.summaryMaterial">鐗╂枡</el-checkbox>
- <el-checkbox v-model="formData.summaryAuxAttributes">杈呭姪灞炴��</el-checkbox>
- <el-checkbox v-model="formData.summaryDemandDate">闇�姹傛棩鏈�</el-checkbox>
- </div>
- </div>
-
- <!-- 璁$畻鍏紡 -->
- <div class="form-section">
- <div class="section-title">璁$畻鍏紡</div>
- <div class="formula-input-section">
- <el-form-item label="璁$畻鍏紡" prop="formula" required>
- <el-input
- v-model="formData.formula"
- placeholder="渚嬪: 棰勮鍑哄簱鏁伴噺 - 鐜版湁搴撳瓨 + 瀹夊叏搴撳瓨 - 棰勮鍏ュ簱鏁伴噺"
- @input="validateFormula"
- />
- </el-form-item>
- <div class="formula-help">
- <el-text type="info" size="small">
- 鏀寔鍙橀噺锛氶璁″嚭搴撴暟閲忋�佺幇鏈夊簱瀛樸�佸畨鍏ㄥ簱瀛樸�侀璁″叆搴撴暟閲�
- </el-text>
- </div>
- </div>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
- <el-dialog
- v-model="productSelectDialogVisible"
- title="閫夋嫨浜у搧"
- width="800px"
- :close-on-click-modal="false"
- >
- <div class="product-select">
- <el-alert
- title="璇烽�夋嫨瑕佽绠楃殑浜у搧"
- type="info"
- :closable="false"
- show-icon
- >
- <template #default>
- <p>閫夋嫨浜у搧鍚庯紝绯荤粺灏嗘牴鎹綋鍓嶈绠楀叕寮忓拰浜у搧搴撳瓨鎯呭喌杩涜璁$畻銆�</p>
- </template>
- </el-alert>
-
- <el-table
- v-loading="productLoading"
- :data="productList"
- @selection-change="handleProductSelectionChange"
- stripe
- border
- style="width: 100%; margin-top: 20px;"
- >
- <el-table-column type="selection" width="55" />
- <el-table-column prop="productCategory" label="浜у搧澶х被" min-width="150" />
- <el-table-column prop="specificationModel" label="浜у搧瑙勬牸" width="120" />
- <el-table-column prop="inboundNum0" label="鐜版湁搴撳瓨" width="100" align="right" />
- <el-table-column prop="inboundNum" label="瀹夊叏搴撳瓨" width="100" align="right" />
- <el-table-column prop="inboundNum" label="棰勮鍑哄簱" width="100" align="right" />
- <el-table-column prop="inboundNum0" label="棰勮鍏ュ簱" width="100" align="right" />
- </el-table>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="productSelectDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleConfirmProductSelection" :disabled="selectedProducts.length === 0">
- 纭璁$畻
- </el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 璁$畻缁撴灉瀵硅瘽妗� -->
- <el-dialog
- v-model="calculateDialogVisible"
- title="閲囪喘璁$畻缁撴灉"
- width="1000px"
- :close-on-click-modal="false"
- >
- <div class="calculate-result">
- <el-alert
- title="璁$畻缁撴灉"
- type="success"
- :closable="false"
- show-icon
- >
- <template #default>
- <p>鍩轰簬褰撳墠閰嶇疆鐨勮绠楀叕寮忓拰搴撳瓨鎯呭喌锛岀郴缁熷凡璁$畻鍑哄悇浜у搧鐨勯噰璐渶姹傘��</p>
- </template>
- </el-alert>
-
- <el-table :data="calculateResult" stripe border style="width: 100%; margin-top: 20px;">
- <el-table-column prop="productCategory" label="浜у搧澶х被" min-width="150" />
- <el-table-column prop="specificationModel" label="浜у搧瑙勬牸" width="120" />
- <el-table-column prop="inboundNum0" label="鐜版湁搴撳瓨" width="100" align="right" />
- <el-table-column prop="inboundNum" label="瀹夊叏搴撳瓨" width="100" align="right" />
- <el-table-column prop="inboundNum" label="棰勮鍑哄簱鏁伴噺" width="120" align="right" />
- <el-table-column prop="inboundNum0" label="棰勮鍏ュ簱鏁伴噺" width="120" align="right" />
- <el-table-column prop="weeklyNetDemand" label="鎸夊懆鍑�闇�姹�" width="120" align="right">
- <template #default="{ row }">
- <el-tag :type="row.weeklyNetDemand > 0 ? 'warning' : 'success'" size="small">
- {{ row.weeklyNetDemand }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="suggestedPurchase" label="寤鸿閲囪喘" width="100" align="right">
- <template #default="{ row }">
- <el-tag :type="row.suggestedPurchase > 0 ? 'danger' : 'success'" size="small">
- {{ row.suggestedPurchase }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="calculateDialogVisible = false">鍏抽棴</el-button>
- <el-button type="primary" @click="handleCreatePurchaseOrder">纭</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Search, Refresh, Plus, Download } from '@element-plus/icons-vue'
-import {listPage,add,update,del,listPageCopy} from "@/api/procurementManagement/procurementPlan.js"
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const submitLoading = ref(false)
-const dialogVisible = ref(false)
-const productSelectDialogVisible = ref(false)
-const calculateDialogVisible = ref(false)
-const dialogType = ref('add')
-const productLoading = ref(false)
-const selectedProducts = ref([])
-const currentPlan = ref(null)
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- planName: '',
- status: ''
-})
-
-// 鍒嗛〉鏁版嵁
-const pagination = reactive({
- current: 1,
- size: 20
-})
-
-// 琛ㄥ崟鏁版嵁
-const formData = reactive({
- code: '',
- planName: '',
- description: '',
- status: '',
- isSystemPreset: false,
- formula: '',
- // 璁$畻鍙傛暟
- considerExistingStock: false,
- warehouseControl: false,
- calculateTotalDemand: false,
- considerSafetyStock: false,
- considerLockedStock: false,
- notConsiderMaterialAux: false,
- negativeStockAsDemand: false,
- // 姹囨�诲悎骞堕�夐」
- summaryMaterial: false,
- summaryAuxAttributes: false,
- summaryDemandDate: false
-})
-
-// 褰撳墠婵�娲荤殑鏍囩椤�
-const activeTab = ref('demand')
-
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = {
- planName: [
- { required: true, message: '璇疯緭鍏ヨ鍒掑悕绉�', trigger: 'blur' }
- ],
- status: [
- { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
- ],
- formula: [
- { required: true, message: '璇疯緭鍏ヨ绠楀叕寮�', trigger: 'blur' }
- ]
-}
-
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([])
-
-// 浜у搧鍒楄〃鏁版嵁
-const productList = ref([
- {
- id: 4,
- productName: '浜у搧D',
- productCode: 'PD004',
- existingStock: 90,
- safetyStock: 40,
- expectedOutbound: 160,
- expectedInbound: 35
- }
-])
-
-// 璁$畻缁撴灉鏁版嵁
-const calculateResult = ref([
- {
- productName: '浜у搧A',
- existingStock: 100,
- safetyStock: 50,
- expectedOutbound: 200,
- expectedInbound: 30,
- weeklyNetDemand: 120,
- suggestedPurchase: 150
- },
- {
- productName: '浜у搧B',
- existingStock: 80,
- safetyStock: 30,
- expectedOutbound: 150,
- expectedInbound: 20,
- weeklyNetDemand: 100,
- suggestedPurchase: 120
- }
-])
-const total = ref(0)
-// 鏂规硶
-const handleSearch = () => {
- pagination.current = 1
- loadData()
-}
-
-const handleReset = () => {
- Object.assign(searchForm, {
- planName: '',
- status: ''
- })
- handleSearch()
-}
-
-const loadData = () => {
- loading.value = true
- listPage({...searchForm,...pagination}).then(res => {
- if(res.code === 200){
- tableData.value = res.data.records
- total.value = res.data.total
- loading.value = false
- }
- })
-}
-
-const handleAdd = () => {
- dialogType.value = 'add'
- resetForm()
- // 鑷姩鐢熸垚缂栫爜
- formData.code = 'CGJH' + String(Date.now()).slice(-4)
- dialogVisible.value = true
-}
-
-const handleEdit = (row) => {
- dialogType.value = 'edit'
- Object.assign(formData, row)
- dialogVisible.value = true
-}
-
-const handleDelete = async (row) => {
- try {
- await ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓噰璐鍒掑悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
- let ids = [row.id]
- del(ids).then(res =>{
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- loadData()
- }
- })
- } catch {
- // 鐢ㄦ埛鍙栨秷鍒犻櫎
- }
-}
-
-const handleSubmit = async () => {
- try {
- // 琛ㄥ崟楠岃瘉
- if (!formData.planName || !formData.formula) {
- ElMessage.error('璇峰~鍐欏繀濉」')
- return
- }
-
- submitLoading.value = true
-
- if (dialogType.value === 'add') {
- add(formData).then(res => {
- if(res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- dialogVisible.value = false
- loadData()
- }
- })
- } else {
- // 缂栬緫
- update(formData).then(res => {
- if(res.code === 200){
- ElMessage.success('缂栬緫鎴愬姛')
- dialogVisible.value = false
- loadData()
- }
- })
- }
-
-
- } catch (error) {
- ElMessage.error('鎿嶄綔澶辫触')
- } finally {
- submitLoading.value = false
- }
-}
-
-const resetForm = () => {
- Object.assign(formData, {
- code: '',
- planName: '',
- description: '',
- status: '',
- isSystemPreset: false,
- formula: '棰勮鍑哄簱鏁伴噺 - 鐜版湁搴撳瓨 + 瀹夊叏搴撳瓨 - 棰勮鍏ュ簱鏁伴噺',
- // 璁$畻鍙傛暟
- considerExistingStock: false,
- warehouseControl: false,
- calculateTotalDemand: false,
- considerSafetyStock: false,
- considerLockedStock: false,
- notConsiderMaterialAux: false,
- negativeStockAsDemand: false,
- // 姹囨�诲悎骞堕�夐」
- summaryMaterial: false,
- summaryAuxAttributes: false,
- summaryDemandDate: false
- })
- activeTab.value = 'demand'
-}
-
-const validateFormula = () => {
- // 绠�鍗曠殑鍏紡楠岃瘉
- const formula = formData.formula
- if (formula && !/^[a-zA-Z\u4e00-\u9fa5\s\*\+\-\/\(\)\d\.]+$/.test(formula)) {
- ElMessage.warning('鍏紡鏍煎紡鍙兘涓嶆纭紝璇锋鏌�')
- }
-}
-
-const handleCalculate = (row) => {
- currentPlan.value = row
- productSelectDialogVisible.value = true
- loadProductList()
-}
-
-const loadProductList = () => {
- productLoading.value = true
- // 妯℃嫙鍔犺浇浜у搧鏁版嵁
- listPageCopy({size:-1}).then(res => {
- if(res.code === 200){
- productList.value = res.data.records
- productLoading.value = false
- }
- })
-}
-
-const handleProductSelectionChange = (selection) => {
- selectedProducts.value = selection
-}
-
-const handleConfirmProductSelection = () => {
- if (selectedProducts.value.length === 0) {
- ElMessage.warning('璇烽�夋嫨瑕佽绠楃殑浜у搧')
- return
- }
-
- ElMessage.success(`姝e湪璁$畻 ${currentPlan.value.planName} 鐨勯噰璐渶姹�...`)
- productSelectDialogVisible.value = false
-
- // 鏍规嵁閫夋嫨鐨勪骇鍝佸拰璁$畻鍏紡杩涜璁$畻
- calculateWithSelectedProducts()
-}
-
-const calculateWithSelectedProducts = () => {
- // 妯℃嫙璁$畻杩囩▼
- // 鏍规嵁閫夋嫨鐨勪骇鍝佹洿鏂拌绠楃粨鏋�
- const result = selectedProducts.value.map(product => {
- // 杩欓噷搴旇鏍规嵁瀹為檯鐨勮绠楀叕寮忚繘琛岃绠�
- // 绀轰緥锛氶璁″嚭搴撴暟閲� - 鐜版湁搴撳瓨 + 瀹夊叏搴撳瓨 - 棰勮鍏ュ簱鏁伴噺
- const weeklyNetDemand = product.inboundNum - product.inboundNum0 + product.inboundNum - product.inboundNum0
- const suggestedPurchase = Math.max(0, weeklyNetDemand)
-
- return {
- productCategory: product.productCategory,
- specificationModel: product.specificationModel,
- inboundNum0: product.inboundNum0,
- inboundNum: product.inboundNum,
- weeklyNetDemand: weeklyNetDemand,
- suggestedPurchase: suggestedPurchase
- }
- })
-
- calculateResult.value = result
- calculateDialogVisible.value = true
-}
-
-
-const handleCreatePurchaseOrder = () => {
- calculateDialogVisible.value = false
-}
-const { proxy } = getCurrentInstance();
-const handleExport = () => {
- ElMessageBox.confirm("鍐呭灏嗚瀵煎嚭锛屾槸鍚︾‘璁ゅ鍑猴紵", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/procurementPlan/export", {}, "閲囪喘璁″垝.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-}
-
-
-const handleSizeChange = (size) => {
- pagination.size = size
- loadData()
-}
-
-const handleCurrentChange = (current) => {
- pagination.current = current
- loadData()
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- loadData()
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
-}
-
-.page-header {
- margin-bottom: 20px;
-}
-
-.page-header h2 {
- margin: 0 0 8px 0;
- color: #303133;
- font-size: 24px;
- font-weight: 600;
-}
-
-.page-header p {
- margin: 0;
- color: #909399;
- font-size: 14px;
-}
-
-.search-card {
- margin-bottom: 20px;
-}
-
-.search-form {
- margin-bottom: 0;
-}
-
-.table-card {
- margin-bottom: 20px;
-}
-
-.table-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-
-.table-title {
- font-size: 16px;
- font-weight: 600;
- color: #303133;
-}
-
-.table-actions {
- display: flex;
- gap: 10px;
-}
-
-.pagination-container {
- margin-top: 20px;
- display: flex;
- justify-content: end;
-}
-
-.form-container {
- padding: 0 20px;
-}
-
-.formula-help {
- margin-top: 5px;
-}
-
-.calculate-result {
- padding: 20px 0;
-}
-
-.dialog-footer {
- text-align: right;
-}
-
-:deep(.el-card__body) {
- padding: 20px;
-}
-
-:deep(.el-table) {
- font-size: 14px;
-}
-
-:deep(.el-form-item__label) {
- font-weight: 500;
-}
-
-.form-container {
- padding: 0;
-}
-
-.form-section {
- margin-bottom: 24px;
- border: 1px solid #e4e7ed;
- border-radius: 6px;
- overflow: hidden;
-}
-
-.section-title {
- background-color: #f5f7fa;
- padding: 12px 16px;
- font-weight: 600;
- color: #303133;
- border-bottom: 1px solid #e4e7ed;
-}
-
-.form-section .el-form {
- padding: 20px;
-}
-
-.param-tabs {
- padding: 20px;
-}
-
-.param-tabs :deep(.el-tabs__header) {
- margin-bottom: 20px;
-}
-
-.param-tabs :deep(.el-tabs__item.is-active) {
- color: #f56c6c;
- border-bottom-color: #f56c6c;
-}
-
-.checkbox-group {
- display: flex;
- flex-wrap: wrap;
- gap: 16px;
-}
-
-.checkbox-group .el-checkbox {
- margin-right: 0;
- margin-bottom: 8px;
-}
-
-.formula-input-section {
- padding: 20px;
-}
-
-.formula-input-section .el-form-item {
- margin-bottom: 12px;
-}
-
-.formula-help {
- text-align: center;
- margin-top: 8px;
-}
-</style>
diff --git a/src/views/procurementManagement/procurementReport/index.vue b/src/views/procurementManagement/procurementReport/index.vue
deleted file mode 100644
index 33a0e91..0000000
--- a/src/views/procurementManagement/procurementReport/index.vue
+++ /dev/null
@@ -1,856 +0,0 @@
-<template>
- <div class="app-container">
- <!-- 鎶ヨ〃閫夋嫨鍣� -->
- <el-card class="report-selector" shadow="never">
- <el-tabs v-model="activeReport" @tab-change="handleReportChange">
- <el-tab-pane label="閲囪喘璁㈠崟鎵ц姹囨�昏〃" name="orderSummary">
- <template #label>
- <span class="tab-label">
- <el-icon><Document /></el-icon>
- 閲囪喘璁㈠崟鎵ц姹囨�昏〃
- </span>
- </template>
- </el-tab-pane>
- <el-tab-pane label="閲囪喘璁㈠崟鎵ц鏄庣粏琛�" name="orderDetail">
- <template #label>
- <span class="tab-label">
- <el-icon><List /></el-icon>
- 閲囪喘璁㈠崟鎵ц鏄庣粏琛�
- </span>
- </template>
- </el-tab-pane>
- <el-tab-pane label="閲囪喘涓氬姟姹囨�昏〃" name="businessSummary">
- <template #label>
- <span class="tab-label">
- <el-icon><TrendCharts /></el-icon>
- 閲囪喘涓氬姟姹囨�昏〃
- </span>
- </template>
- </el-tab-pane>
- <el-tab-pane label="渚涘簲鍟嗕緵璐ф眹鎬昏〃" name="supplierSummary">
- <template #label>
- <span class="tab-label">
- <el-icon><Shop /></el-icon>
- 渚涘簲鍟嗕緵璐ф眹鎬昏〃
- </span>
- </template>
- </el-tab-pane>
- </el-tabs>
- </el-card>
-
- <!-- 鏌ヨ鏉′欢 -->
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true" class="search-form">
- <el-form-item label="鏃堕棿鑼冨洿锛�">
- <el-date-picker
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- style="width: 240px"
- />
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗭細" v-if="activeReport === 'supplierSummary'">
- <el-select v-model="searchForm.supplierId" placeholder="璇烽�夋嫨渚涘簲鍟�" clearable style="width: 200px">
- <el-option
- v-for="supplier in supplierList"
- :key="supplier.id"
- :label="supplier.name"
- :value="supplier.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="鍟嗗搧绫诲埆锛�" v-if="activeReport === 'businessSummary'">
- <el-select v-model="searchForm.categoryId" placeholder="璇烽�夋嫨鍟嗗搧绫诲埆" clearable style="width: 200px">
- <el-option
- v-for="category in categoryList"
- :key="category.id"
- :label="category.name"
- :value="category.id"
- />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch" :loading="loading">
- <el-icon><Search /></el-icon>
- 鏌ヨ
- </el-button>
- <el-button @click="resetSearch">
- <el-icon><Refresh /></el-icon>
- 閲嶇疆
- </el-button>
- <el-button type="success" @click="exportReport">
- <el-icon><Download /></el-icon>
- 瀵煎嚭
- </el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 鎶ヨ〃鍐呭 -->
- <el-card class="report-content" shadow="never">
- <!-- 閲囪喘璁㈠崟鎵ц姹囨�昏〃 -->
- <div v-if="activeReport === 'orderSummary'" class="report-section">
- <div class="section-header">
- <h3>閲囪喘璁㈠崟鎵ц姹囨�昏〃</h3>
- <div class="summary-stats">
- <div class="stat-item">
- <span class="stat-label">鎬昏鍗曟暟锛�</span>
- <span class="stat-value">{{ orderSummaryStats.totalOrders }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">鎬婚噾棰濓細</span>
- <span class="stat-value">楼{{ orderSummaryStats.totalAmount.toLocaleString() }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">瀹屾垚鐜囷細</span>
- <span class="stat-value">{{ orderSummaryStats.completionRate }}%</span>
- </div>
- </div>
- </div>
-
- <el-table :data="orderSummaryData" border v-loading="loading" stripe style="width: 100%">
- <el-table-column label="璁㈠崟缂栧彿" prop="orderNo" width="180" fixed="left" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" min-width="150" />
- <el-table-column label="璁㈠崟鏃ユ湡" prop="orderDate" width="120" />
- <el-table-column label="璁″垝浜ゆ湡" prop="plannedDelivery" width="120" />
- <el-table-column label="瀹為檯浜ゆ湡" prop="actualDelivery" width="120" />
- <el-table-column label="璁㈠崟閲戦" prop="orderAmount" width="120">
- <template #default="{ row }">楼{{ row.orderAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="宸蹭粯閲戦" prop="paidAmount" width="120">
- <template #default="{ row }">楼{{ row.paidAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="瀹屾垚鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="瀹屾垚鐜�" prop="completionRate" width="100">
- <template #default="{ row }">{{ row.completionRate }}%</template>
- </el-table-column>
- <el-table-column label="寤惰繜澶╂暟" prop="delayDays" width="100">
- <template #default="{ row }">
- <span :class="{ 'delay-text': row.delayDays > 0 }">{{ row.delayDays }}</span>
- </template>
- </el-table-column>
- </el-table>
- </div>
-
- <!-- 閲囪喘璁㈠崟鎵ц鏄庣粏琛� -->
- <div v-if="activeReport === 'orderDetail'" class="report-section">
- <div class="section-header">
- <h3>閲囪喘璁㈠崟鎵ц鏄庣粏琛�</h3>
- <div class="summary-stats">
- <div class="stat-item">
- <span class="stat-label">鏄庣粏鏉℃暟锛�</span>
- <span class="stat-value">{{ orderDetailStats.totalItems }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">宸叉敹璐э細</span>
- <span class="stat-value">{{ orderDetailStats.receivedItems }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">寰呮敹璐э細</span>
- <span class="stat-value">{{ orderDetailStats.pendingItems }}</span>
- </div>
- </div>
- </div>
-
- <el-table :data="orderDetailData" border v-loading="loading" stripe style="width: 100%">
- <el-table-column label="璁㈠崟缂栧彿" prop="orderNo" width="150" fixed="left" />
- <el-table-column label="鍟嗗搧缂栫爜" prop="productCode" width="120" />
- <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="200" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" min-width="150" />
- <el-table-column label="鍗曚綅" prop="unit" width="80" />
- <el-table-column label="璁″垝鏁伴噺" prop="plannedQuantity" width="100" />
- <el-table-column label="宸叉敹璐ф暟閲�" prop="receivedQuantity" width="120" />
- <el-table-column label="寰呮敹璐ф暟閲�" prop="pendingQuantity" width="120" />
- <el-table-column label="鍗曚环" prop="unitPrice" width="100">
- <template #default="{ row }">楼{{ row.unitPrice.toFixed(2) }}</template>
- </el-table-column>
- <el-table-column label="灏忚" prop="subtotal" width="120">
- <template #default="{ row }">楼{{ row.subtotal.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="鏀惰揣鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getReceiptStatusType(row.status)">{{ getReceiptStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鏈�鍚庢敹璐ф棩鏈�" prop="lastReceiptDate" width="120" />
- </el-table>
- </div>
-
- <!-- 閲囪喘涓氬姟姹囨�昏〃 -->
- <div v-if="activeReport === 'businessSummary'" class="report-section">
- <div class="section-header">
- <h3>閲囪喘涓氬姟姹囨�昏〃</h3>
- <div class="summary-stats">
- <div class="stat-item">
- <span class="stat-label">閲囪喘鎬婚锛�</span>
- <span class="stat-value">楼{{ businessSummaryStats.totalAmount.toLocaleString() }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">鍟嗗搧绉嶇被锛�</span>
- <span class="stat-value">{{ businessSummaryStats.productTypes }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">渚涘簲鍟嗘暟锛�</span>
- <span class="stat-value">{{ businessSummaryStats.supplierCount }}</span>
- </div>
- </div>
- </div>
-
- <el-table :data="businessSummaryData" border v-loading="loading" stripe style="width: 100%">
- <el-table-column label="鍟嗗搧绫诲埆" prop="category" width="150" fixed="left" />
- <el-table-column label="鍟嗗搧缂栫爜" prop="productCode" width="120" />
- <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="200" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" min-width="150" />
- <el-table-column label="閲囪喘鏁伴噺" prop="purchaseQuantity" width="120" />
- <el-table-column label="閲囪喘閲戦" prop="purchaseAmount" width="120">
- <template #default="{ row }">楼{{ row.purchaseAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="骞冲潎鍗曚环" prop="avgPrice" width="100">
- <template #default="{ row }">楼{{ row.avgPrice.toFixed(2) }}</template>
- </el-table-column>
- <el-table-column label="閲囪喘娆℃暟" prop="purchaseCount" width="100" />
- <el-table-column label="涓昏渚涘簲鍟�" prop="mainSupplier" min-width="150" />
- <el-table-column label="鏈�鍚庨噰璐棩鏈�" prop="lastPurchaseDate" width="120" />
- </el-table>
- </div>
-
- <!-- 渚涘簲鍟嗕緵璐ф眹鎬昏〃 -->
- <div v-if="activeReport === 'supplierSummary'" class="report-section">
- <div class="section-header">
- <h3>渚涘簲鍟嗕緵璐ф眹鎬昏〃</h3>
- <div class="summary-stats">
- <div class="stat-item">
- <span class="stat-label">渚涘簲鍟嗘�绘暟锛�</span>
- <span class="stat-value">{{ supplierSummaryStats.totalSuppliers }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">渚涜揣鎬婚锛�</span>
- <span class="stat-value">楼{{ supplierSummaryStats.totalAmount.toLocaleString() }}</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">骞冲潎璇勫垎锛�</span>
- <span class="stat-value">{{ supplierSummaryStats.avgRating.toFixed(1) }}</span>
- </div>
- </div>
- </div>
-
- <el-table :data="supplierSummaryData" border v-loading="loading" stripe style="width: 100%">
- <el-table-column label="渚涘簲鍟嗙紪鐮�" prop="supplierCode" width="120" fixed="left" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" min-width="200" />
- <el-table-column label="鑱旂郴浜�" prop="contactPerson" width="120" />
- <el-table-column label="鑱旂郴鐢佃瘽" prop="phone" width="130" />
- <el-table-column label="渚涜揣璁㈠崟鏁�" prop="orderCount" width="120" />
- <el-table-column label="渚涜揣閲戦" prop="supplyAmount" width="120">
- <template #default="{ row }">楼{{ row.supplyAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="宸蹭粯閲戦" prop="paidAmount" width="120">
- <template #default="{ row }">楼{{ row.paidAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="鏈粯閲戦" prop="unpaidAmount" width="120">
- <template #default="{ row }">楼{{ row.unpaidAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column label="鎸夋椂浜よ揣鐜�" prop="onTimeRate" width="120">
- <template #default="{ row }">{{ row.onTimeRate }}%</template>
- </el-table-column>
- <el-table-column label="璐ㄩ噺璇勫垎" prop="qualityRating" width="100">
- <template #default="{ row }">
- <el-rate v-model="row.qualityRating" disabled show-score text-color="#ff9900" />
- </template>
- </el-table-column>
- <el-table-column label="鍚堜綔鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getSupplierStatusType(row.status)">{{ getSupplierStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage } from 'element-plus'
-import { Document, List, TrendCharts, Shop, Search, Refresh, Download } from '@element-plus/icons-vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const activeReport = ref('orderSummary')
-
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- dateRange: [],
- supplierId: '',
- categoryId: ''
-})
-
-// 渚涘簲鍟嗗垪琛�
-const supplierList = ref([
- { id: 1, name: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃' },
- { id: 2, name: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�' },
- { id: 3, name: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃' },
- { id: 4, name: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃' },
- { id: 5, name: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�' }
-])
-
-// 鍟嗗搧绫诲埆鍒楄〃
-const categoryList = ref([
- { id: 1, name: '鐢靛瓙鍏冨櫒浠�' },
- { id: 2, name: '鏈烘璁惧' },
- { id: 3, name: '鍘熸潗鏂�' },
- { id: 4, name: '鍔炲叕鐢ㄥ搧' },
- { id: 5, name: '鍖呰鏉愭枡' }
-])
-
-// 缁熻鏁版嵁
-const orderSummaryStats = ref({
- totalOrders: 156,
- totalAmount: 2580000,
- completionRate: 87.5
-})
-
-const orderDetailStats = ref({
- totalItems: 1248,
- receivedItems: 1089,
- pendingItems: 159
-})
-
-const businessSummaryStats = ref({
- totalAmount: 2580000,
- productTypes: 89,
- supplierCount: 25
-})
-
-const supplierSummaryStats = ref({
- totalSuppliers: 25,
- totalAmount: 2580000,
- avgRating: 4.2
-})
-
-// 閲囪喘璁㈠崟鎵ц姹囨�昏〃鏁版嵁
-const orderSummaryData = ref([
- {
- orderNo: 'PO20241201001',
- supplierName: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
- orderDate: '2024-12-01',
- plannedDelivery: '2024-12-15',
- actualDelivery: '2024-12-14',
- orderAmount: 125000,
- paidAmount: 100000,
- status: 'completed',
- completionRate: 100,
- delayDays: -1
- },
- {
- orderNo: 'PO20241201002',
- supplierName: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
- orderDate: '2024-12-02',
- plannedDelivery: '2024-12-20',
- actualDelivery: '2024-12-22',
- orderAmount: 280000,
- paidAmount: 140000,
- status: 'partial',
- completionRate: 75,
- delayDays: 2
- },
- {
- orderNo: 'PO20241201003',
- supplierName: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
- orderDate: '2024-12-03',
- plannedDelivery: '2024-12-25',
- actualDelivery: '',
- orderAmount: 180000,
- paidAmount: 0,
- status: 'pending',
- completionRate: 0,
- delayDays: 0
- },
- {
- orderNo: 'PO20241201004',
- supplierName: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃',
- orderDate: '2024-12-04',
- plannedDelivery: '2024-12-18',
- actualDelivery: '2024-12-18',
- orderAmount: 95000,
- paidAmount: 95000,
- status: 'completed',
- completionRate: 100,
- delayDays: 0
- },
- {
- orderNo: 'PO20241201005',
- supplierName: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�',
- orderDate: '2024-12-05',
- plannedDelivery: '2024-12-28',
- actualDelivery: '',
- orderAmount: 220000,
- paidAmount: 0,
- status: 'pending',
- completionRate: 0,
- delayDays: 0
- }
-])
-
-// 閲囪喘璁㈠崟鎵ц鏄庣粏琛ㄦ暟鎹�
-const orderDetailData = ref([
- {
- orderNo: 'PO20241201001',
- productCode: 'EL001',
- productName: '鐢甸樆鍣� 1K惟 卤5%',
- specification: '1/4W 纰宠啘鐢甸樆',
- unit: '涓�',
- plannedQuantity: 1000,
- receivedQuantity: 1000,
- pendingQuantity: 0,
- unitPrice: 0.15,
- subtotal: 150,
- status: 'completed',
- lastReceiptDate: '2024-12-14'
- },
- {
- orderNo: 'PO20241201001',
- productCode: 'EL002',
- productName: '鐢靛鍣� 100渭F',
- specification: '25V 閾濈數瑙g數瀹�',
- unit: '涓�',
- plannedQuantity: 500,
- receivedQuantity: 500,
- pendingQuantity: 0,
- unitPrice: 0.85,
- subtotal: 425,
- status: 'completed',
- lastReceiptDate: '2024-12-14'
- },
- {
- orderNo: 'PO20241201002',
- productCode: 'ME001',
- productName: '绮惧瘑杞存壙',
- specification: '6205-2RS 娣辨矡鐞冭酱鎵�',
- unit: '涓�',
- plannedQuantity: 200,
- receivedQuantity: 150,
- pendingQuantity: 50,
- unitPrice: 25.5,
- subtotal: 5100,
- status: 'partial',
- lastReceiptDate: '2024-12-20'
- },
- {
- orderNo: 'PO20241201002',
- productCode: 'ME002',
- productName: '涓嶉攬閽㈣灪涓�',
- specification: 'M8脳20 304涓嶉攬閽�',
- unit: '涓�',
- plannedQuantity: 1000,
- receivedQuantity: 1000,
- pendingQuantity: 0,
- unitPrice: 0.8,
- subtotal: 800,
- status: 'completed',
- lastReceiptDate: '2024-12-20'
- },
- {
- orderNo: 'PO20241201003',
- productCode: 'SM001',
- productName: '鏅鸿兘浼犳劅鍣�',
- specification: '娓╁害浼犳劅鍣� DS18B20',
- unit: '涓�',
- plannedQuantity: 300,
- receivedQuantity: 0,
- pendingQuantity: 300,
- unitPrice: 12.5,
- subtotal: 3750,
- status: 'pending',
- lastReceiptDate: ''
- }
-])
-
-// 閲囪喘涓氬姟姹囨�昏〃鏁版嵁
-const businessSummaryData = ref([
- {
- category: '鐢靛瓙鍏冨櫒浠�',
- productCode: 'EL001',
- productName: '鐢甸樆鍣� 1K惟 卤5%',
- specification: '1/4W 纰宠啘鐢甸樆',
- purchaseQuantity: 5000,
- purchaseAmount: 750,
- avgPrice: 0.15,
- purchaseCount: 8,
- mainSupplier: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
- lastPurchaseDate: '2024-12-01'
- },
- {
- category: '鐢靛瓙鍏冨櫒浠�',
- productCode: 'EL002',
- productName: '鐢靛鍣� 100渭F',
- specification: '25V 閾濈數瑙g數瀹�',
- purchaseQuantity: 2500,
- purchaseAmount: 2125,
- avgPrice: 0.85,
- purchaseCount: 6,
- mainSupplier: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
- lastPurchaseDate: '2024-12-01'
- },
- {
- category: '鏈烘璁惧',
- productCode: 'ME001',
- productName: '绮惧瘑杞存壙',
- specification: '6205-2RS 娣辨矡鐞冭酱鎵�',
- purchaseQuantity: 800,
- purchaseAmount: 20400,
- avgPrice: 25.5,
- purchaseCount: 4,
- mainSupplier: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
- lastPurchaseDate: '2024-12-02'
- },
- {
- category: '鏈烘璁惧',
- productCode: 'ME002',
- productName: '涓嶉攬閽㈣灪涓�',
- specification: 'M8脳20 304涓嶉攬閽�',
- purchaseQuantity: 5000,
- purchaseAmount: 4000,
- avgPrice: 0.8,
- purchaseCount: 12,
- mainSupplier: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
- lastPurchaseDate: '2024-12-02'
- },
- {
- category: '鏅鸿兘璁惧',
- productCode: 'SM001',
- productName: '鏅鸿兘浼犳劅鍣�',
- specification: '娓╁害浼犳劅鍣� DS18B20',
- purchaseQuantity: 1200,
- purchaseAmount: 15000,
- avgPrice: 12.5,
- purchaseCount: 5,
- mainSupplier: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
- lastPurchaseDate: '2024-12-03'
- }
-])
-
-// 渚涘簲鍟嗕緵璐ф眹鎬昏〃鏁版嵁
-const supplierSummaryData = ref([
- {
- supplierCode: 'SUP001',
- supplierName: '姹熻嫃鍗庤仈鐢靛瓙绉戞妧鏈夐檺鍏徃',
- contactPerson: '寮犵粡鐞�',
- phone: '0512-88888888',
- orderCount: 45,
- supplyAmount: 850000,
- paidAmount: 680000,
- unpaidAmount: 170000,
- onTimeRate: 95,
- qualityRating: 4.5,
- status: 'active'
- },
- {
- supplierCode: 'SUP002',
- supplierName: '涓婃捣绮惧瘑鏈烘鍒堕�犳湁闄愬叕鍙�',
- contactPerson: '鏉庢��',
- phone: '021-66666666',
- orderCount: 32,
- supplyAmount: 1200000,
- paidAmount: 900000,
- unpaidAmount: 300000,
- onTimeRate: 88,
- qualityRating: 4.2,
- status: 'active'
- },
- {
- supplierCode: 'SUP003',
- supplierName: '娣卞湷鏅鸿兘璁惧鏈夐檺鍏徃',
- contactPerson: '鐜嬪伐绋嬪笀',
- phone: '0755-77777777',
- orderCount: 28,
- supplyAmount: 680000,
- paidAmount: 400000,
- unpaidAmount: 280000,
- onTimeRate: 92,
- qualityRating: 4.3,
- status: 'active'
- },
- {
- supplierCode: 'SUP004',
- supplierName: '鍖椾含鏂版潗鏂欑鎶�鏈夐檺鍏徃',
- contactPerson: '闄堝崥澹�',
- phone: '010-55555555',
- orderCount: 18,
- supplyAmount: 320000,
- paidAmount: 250000,
- unpaidAmount: 70000,
- onTimeRate: 85,
- qualityRating: 4.0,
- status: 'active'
- },
- {
- supplierCode: 'SUP005',
- supplierName: '骞垮窞鐢靛瓙鍏冨櫒浠舵湁闄愬叕鍙�',
- contactPerson: '鍒樼粡鐞�',
- phone: '020-44444444',
- orderCount: 22,
- supplyAmount: 480000,
- paidAmount: 200000,
- unpaidAmount: 280000,
- onTimeRate: 78,
- qualityRating: 3.8,
- status: 'warning'
- }
-])
-
-// 鏂规硶
-const handleReportChange = (tabName) => {
- activeReport.value = tabName
- handleSearch()
-}
-
-const handleSearch = () => {
- loading.value = true
- // 妯℃嫙API璋冪敤
- setTimeout(() => {
- loading.value = false
- ElMessage.success('鏌ヨ瀹屾垚')
- }, 1000)
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, {
- dateRange: [],
- supplierId: '',
- categoryId: ''
- })
- handleSearch()
-}
-
-const exportReport = () => {
- ElMessage.success('瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-// 鐘舵�佺浉鍏虫柟娉�
-const getStatusType = (status) => {
- const statusMap = {
- completed: 'success',
- partial: 'warning',
- pending: 'info'
- }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = {
- completed: '宸插畬鎴�',
- partial: '閮ㄥ垎瀹屾垚',
- pending: '寰呮墽琛�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-const getReceiptStatusType = (status) => {
- const statusMap = {
- completed: 'success',
- partial: 'warning',
- pending: 'info'
- }
- return statusMap[status] || 'info'
-}
-
-const getReceiptStatusText = (status) => {
- const statusMap = {
- completed: '宸叉敹璐�',
- partial: '閮ㄥ垎鏀惰揣',
- pending: '寰呮敹璐�'
- }
- return statusMap[status] || '鏈煡'
-}
-
-const getSupplierStatusType = (status) => {
- const statusMap = {
- active: 'success',
- warning: 'warning',
- inactive: 'info'
- }
- return statusMap[status] || 'info'
-}
-
-const getSupplierStatusText = (status) => {
- const statusMap = {
- active: '姝e父鍚堜綔',
- warning: '闇�鍏虫敞',
- inactive: '鏆傚仠鍚堜綔'
- }
- return statusMap[status] || '鏈煡'
-}
-
-onMounted(() => {
- // 璁剧疆榛樿鏃堕棿鑼冨洿涓烘渶杩�30澶�
- const endDate = new Date()
- const startDate = new Date()
- startDate.setDate(startDate.getDate() - 30)
-
- searchForm.dateRange = [
- startDate.toISOString().split('T')[0],
- endDate.toISOString().split('T')[0]
- ]
-})
-</script>
-
-<style scoped>
-.app-container {
- padding: 20px;
- background-color: #f5f7fa;
- min-height: 100vh;
-}
-
-.page-header {
- text-align: center;
- margin-bottom: 20px;
- padding: 20px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 10px;
- color: white;
-}
-
-.page-header h2 {
- margin: 0 0 10px 0;
- font-size: 28px;
- font-weight: 600;
-}
-
-.page-header p {
- margin: 0;
- font-size: 16px;
- opacity: 0.9;
-}
-
-.report-selector {
- margin-bottom: 20px;
- border-radius: 8px;
-}
-
-.tab-label {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.search-card {
- margin-bottom: 20px;
- border-radius: 8px;
-}
-
-.search-form {
- margin-bottom: 0;
-}
-
-.report-content {
- border-radius: 8px;
-}
-
-.report-section {
- min-height: 400px;
-}
-
-.section-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 2px solid #e4e7ed;
-}
-
-.section-header h3 {
- margin: 0;
- font-size: 20px;
- font-weight: 600;
- color: #303133;
-}
-
-.summary-stats {
- display: flex;
- gap: 30px;
-}
-
-.stat-item {
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-.stat-label {
- font-size: 14px;
- color: #606266;
- margin-bottom: 5px;
-}
-
-.stat-value {
- font-size: 18px;
- font-weight: 600;
- color: #409EFF;
-}
-
-.delay-text {
- color: #F56C6C;
- font-weight: 600;
-}
-
-:deep(.el-table) {
- border-radius: 8px;
- overflow: hidden;
- width: 100% !important;
-}
-
-:deep(.el-table__body-wrapper) {
- width: 100% !important;
-}
-
-:deep(.el-table__header-wrapper) {
- width: 100% !important;
-}
-
-:deep(.el-table th) {
- background-color: #f8f9fa;
- color: #606266;
- font-weight: 600;
-}
-
-:deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
- background-color: #fafafa;
-}
-
-:deep(.el-tabs__header) {
- margin-bottom: 0;
-}
-
-:deep(.el-tabs__nav-wrap) {
- padding: 0 20px;
-}
-
-:deep(.el-tabs__item) {
- font-size: 16px;
- font-weight: 500;
-}
-
-:deep(.el-tabs__item.is-active) {
- color: #409EFF;
-}
-
-:deep(.el-rate) {
- display: flex;
- align-items: center;
-}
-
-:deep(.el-rate__text) {
- margin-left: 8px;
- font-size: 14px;
- color: #606266;
-}
-</style>
diff --git a/src/views/procurementManagement/purchaseOrder/index.vue b/src/views/procurementManagement/purchaseOrder/index.vue
deleted file mode 100644
index 79ca2fe..0000000
--- a/src/views/procurementManagement/purchaseOrder/index.vue
+++ /dev/null
@@ -1,188 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="渚涘簲鍟嗗悕绉帮細">
- <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О" clearable />
- </el-form-item>
- <el-form-item label="璁㈠崟鐘舵�侊細">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="鑽夌" value="draft" />
- <el-option label="寰呭鏍�" value="pending" />
- <el-option label="宸插鏍�" value="approved" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <el-button type="primary" @click="openDialog('add')">鏂板璁㈠崟</el-button>
- <el-button type="danger" @click="handleBatchDelete" :disabled="!selectedRows.length">鎵归噺鍒犻櫎</el-button>
- </div>
-
- <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="璁㈠崟缂栧彿" prop="orderNo" width="180" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column label="璁㈠崟鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎬婚噾棰�" prop="totalAmount" width="120">
- <template #default="{ row }">楼{{ row.totalAmount.toFixed(2) }}</template>
- </el-table-column>
- <el-table-column label="鍒涘缓鏃堕棿" prop="createTime" width="180" />
- <el-table-column label="鎿嶄綔" width="200" align="center">
- <template #default="{ row }">
- <el-button type="primary" size="small" @click="openDialog('edit', row)">缂栬緫</el-button>
- <el-button type="success" size="small" @click="viewDetails(row)">鏌ョ湅</el-button>
- <el-button type="danger" size="small" @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閲囪喘璁㈠崟' : '缂栬緫閲囪喘璁㈠崟'" width="800px">
- <el-form :model="formData" ref="formRef" label-width="120px">
- <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
- <el-select v-model="formData.supplierName" placeholder="璇烽�夋嫨渚涘簲鍟�" style="width: 100%">
- <el-option label="渚涘簲鍟咥" value="渚涘簲鍟咥" />
- <el-option label="渚涘簲鍟咮" value="渚涘簲鍟咮" />
- </el-select>
- </el-form-item>
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-
-const searchForm = reactive({
- supplierName: '',
- status: ''
-})
-
-const formData = reactive({
- supplierName: '',
- remark: ''
-})
-
-const mockData = [
- {
- id: 1,
- orderNo: 'PO20241201001',
- supplierName: '渚涘簲鍟咥',
- status: 'approved',
- totalAmount: 12500.00,
- createTime: '2025-12-01 10:30:00',
- remark: '甯歌閲囪喘'
- }
-]
-
-const tableData = ref([...mockData])
-
-const getStatusType = (status) => {
- const statusMap = { draft: 'info', pending: 'warning', approved: 'success' }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = { draft: '鑽夌', pending: '寰呭鏍�', approved: '宸插鏍�' }
- return statusMap[status] || '鏈煡'
-}
-
-const handleSearch = () => {
- loading.value = true
- setTimeout(() => {
- loading.value = false
- }, 500)
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, { supplierName: '', status: '' })
-}
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- if (type === 'edit' && row.id) {
- Object.assign(formData, { supplierName: row.supplierName, remark: row.remark })
- } else {
- Object.assign(formData, { supplierName: '', remark: '' })
- }
- dialogVisible.value = true
-}
-
-const handleSubmit = () => {
- if (dialogType.value === 'add') {
- const newOrder = {
- id: Date.now(),
- orderNo: `PO${Date.now()}`,
- supplierName: formData.supplierName,
- status: 'draft',
- totalAmount: 0,
- createTime: new Date().toLocaleString(),
- remark: formData.remark
- }
- tableData.value.unshift(newOrder)
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
-}
-
-const viewDetails = (row) => {
- ElMessage.info('鏌ョ湅璇︽儏鍔熻兘')
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = tableData.value.findIndex(item => item.id === row.id)
- if (index !== -1) {
- tableData.value.splice(index, 1)
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const handleBatchDelete = () => {
- if (selectedRows.value.length === 0) {
- ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑璁板綍')
- return
- }
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-</script>
-
-<style scoped>
-.app-container { padding: 20px; }
-.search-card { margin-bottom: 20px; }
-.table-card { margin-bottom: 20px; }
-.table-header { margin-bottom: 20px; }
-</style>
diff --git a/src/views/procurementManagement/qualityInspection/index.vue b/src/views/procurementManagement/qualityInspection/index.vue
deleted file mode 100644
index 8d90243..0000000
--- a/src/views/procurementManagement/qualityInspection/index.vue
+++ /dev/null
@@ -1,285 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="璐ㄦ鍗曞彿锛�" style="width: 300px;">
- <el-input v-model="searchForm.inspectionNo" placeholder="璇疯緭鍏ヨ川妫�鍗曞彿" clearable />
- </el-form-item>
- <el-form-item label="璐ㄦ鐘舵�侊細" style="width: 300px;">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="寰呰川妫�" value="pending" />
- <el-option label="璐ㄦ涓�" value="inspecting" />
- <el-option label="宸插畬鎴�" value="completed" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <el-button type="primary" @click="openDialog('add')">鏂板璐ㄦ鍗�</el-button>
- <el-button type="success" @click="handleBatchComplete">鎵归噺瀹屾垚</el-button>
- <el-button type="danger" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
- </div>
-
- <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="璐ㄦ鍗曞彿" prop="inspectionNo" width="180" />
- <el-table-column label="鍒拌揣鍗曞彿" prop="arrivalNo" width="180" />
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column label="璐ㄦ鐘舵��" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍚堟牸鏁伴噺" prop="qualifiedQuantity" width="100" />
- <el-table-column label="涓嶅悎鏍兼暟閲�" prop="unqualifiedQuantity" width="100" />
- <el-table-column label="璐ㄦ鏃堕棿" prop="inspectionTime" width="180" />
- <el-table-column label="鎿嶄綔" width="200" align="center">
- <template #default="{ row }">
- <el-button type="primary" link @click="openDialog('edit', row)">缂栬緫</el-button>
- <el-button type="success" link @click="handleComplete(row)" v-if="row.status !== 'completed'">瀹屾垚</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板璐ㄦ鍗�' : '缂栬緫璐ㄦ鍗�'" width="1000px">
- <el-form :model="formData" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍒拌揣鍗曞彿">
- <el-select v-model="formData.arrivalNo" placeholder="璇烽�夋嫨鍒拌揣鍗�" style="width: 100%">
- <el-option label="AR20241201001" value="AR20241201001" />
- <el-option label="AR20241201002" value="AR20241201002" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-input v-model="formData.supplierName" placeholder="渚涘簲鍟嗗悕绉�" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="璐ㄦ鍟嗗搧">
- <div class="product-list" style="width: 100%;">
- <el-table :data="formData.products" border width="100%">
- <el-table-column label="鍟嗗搧鍚嶇О" width="150">
- <template #default="{ row }">
- <el-input v-model="row.productName" placeholder="璇疯緭鍏ュ晢鍝佸悕绉�" />
- </template>
- </el-table-column>
- <el-table-column label="瑙勬牸鍨嬪彿" width="150">
- <template #default="{ row }">
- <el-input v-model="row.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
- </template>
- </el-table-column>
- <el-table-column label="鍒拌揣鏁伴噺" width="150">
- <template #default="{ row }">
- <el-input-number v-model="row.arrivalQuantity" :min="0" placeholder="鏁伴噺" style="width: 100%;"/>
- </template>
- </el-table-column>
- <el-table-column label="鍚堟牸鏁伴噺" width="150">
- <template #default="{ row }">
- <el-input-number v-model="row.qualifiedQuantity" :min="0" placeholder="鏁伴噺" style="width: 100%;"/>
- </template>
- </el-table-column>
- <el-table-column label="涓嶅悎鏍兼暟閲�" width="150">
- <template #default="{ row }">
- <el-input-number v-model="row.unqualifiedQuantity" :min="0" placeholder="鏁伴噺" style="width: 100%;"/>
- </template>
- </el-table-column>
- <el-table-column label="涓嶅悎鏍煎師鍥�" width="200">
- <template #default="{ row }">
- <el-input v-model="row.unqualifiedReason" placeholder="璇疯緭鍏ヤ笉鍚堟牸鍘熷洜" />
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="100">
- <template #default="{ $index }">
- <el-button type="danger" link @click="removeProduct($index)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- <div class="add-product-btn">
- <el-button type="primary" @click="addProduct">娣诲姞鍟嗗搧</el-button>
- </div>
- </div>
- </el-form-item>
-
- <el-form-item label="璐ㄦ鍛�">
- <el-input v-model="formData.inspector" placeholder="璇疯緭鍏ヨ川妫�鍛樺鍚�" />
- </el-form-item>
-
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-
-const searchForm = reactive({
- inspectionNo: '',
- status: ''
-})
-
-const formData = reactive({
- arrivalNo: '',
- supplierName: '',
- products: [],
- inspector: '',
- remark: ''
-})
-
-const mockData = [
- {
- id: 1,
- inspectionNo: 'QI20241201001',
- arrivalNo: 'AR20241201001',
- supplierName: '渚涘簲鍟咥',
- status: 'completed',
- qualifiedQuantity: 240,
- unqualifiedQuantity: 10,
- inspectionTime: '2025-12-01 16:30:00',
- inspector: '闄堝織寮�',
- remark: '璐ㄦ瀹屾垚'
- }
-]
-
-const tableData = ref([...mockData])
-
-const getStatusType = (status) => {
- const statusMap = { pending: 'info', inspecting: 'warning', completed: 'success' }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = { pending: '寰呰川妫�', inspecting: '璐ㄦ涓�', completed: '宸插畬鎴�' }
- return statusMap[status] || '鏈煡'
-}
-
-const handleSearch = () => {
- loading.value = true
- setTimeout(() => { loading.value = false }, 500)
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, { inspectionNo: '', status: '' })
-}
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- if (type === 'edit' && row.id) {
- Object.assign(formData, {
- arrivalNo: row.arrivalNo,
- supplierName: row.supplierName,
- inspector: row.inspector,
- remark: row.remark
- })
- } else {
- Object.assign(formData, {
- arrivalNo: '',
- supplierName: '',
- products: [],
- inspector: '',
- remark: ''
- })
- }
- dialogVisible.value = true
-}
-
-const handleSubmit = () => {
- if (dialogType.value === 'add') {
- const newInspection = {
- id: Date.now(),
- inspectionNo: `QI${Date.now()}`,
- arrivalNo: formData.arrivalNo,
- supplierName: formData.supplierName,
- status: 'pending',
- qualifiedQuantity: 0,
- unqualifiedQuantity: 0,
- inspectionTime: new Date().toLocaleString(),
- inspector: formData.inspector,
- remark: formData.remark
- }
- tableData.value.unshift(newInspection)
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
-}
-
-const handleComplete = (row) => {
- row.status = 'completed'
- ElMessage.success('璐ㄦ瀹屾垚')
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = tableData.value.findIndex(item => item.id === row.id)
- if (index !== -1) {
- tableData.value.splice(index, 1)
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const handleBatchComplete = () => {
- ElMessage.success('鎵归噺瀹屾垚鎴愬姛')
-}
-
-const handleBatchDelete = () => {
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-
-const addProduct = () => {
- formData.products.push({
- productName: '',
- specification: '',
- arrivalQuantity: 0,
- qualifiedQuantity: 0,
- unqualifiedQuantity: 0,
- unqualifiedReason: ''
- })
-}
-
-const removeProduct = (index) => {
- formData.products.splice(index, 1)
-}
-</script>
-
-<style scoped>
-.app-container { padding: 20px; }
-.search-card { margin-bottom: 20px; }
-.table-card { margin-bottom: 20px; }
-.table-header { margin-bottom: 20px; }
-.product-list { border: 1px solid #dcdfe6; border-radius: 4px; padding: 15px; }
-.product-item { margin-bottom: 15px; padding: 10px; background-color: #f5f7fa; border-radius: 4px; }
-.add-product-btn { margin-top: 15px; text-align: center; }
-</style>
diff --git a/src/views/procurementManagement/returnManagement/index.vue b/src/views/procurementManagement/returnManagement/index.vue
deleted file mode 100644
index 2a54083..0000000
--- a/src/views/procurementManagement/returnManagement/index.vue
+++ /dev/null
@@ -1,274 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="search-card" shadow="never">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="閫�璐у崟鍙凤細" style="width: 300px;">
- <el-input v-model="searchForm.returnNo" placeholder="璇疯緭鍏ラ��璐у崟鍙�" clearable />
- </el-form-item>
- <el-form-item label="閫�璐х被鍨嬶細" style="width: 300px;">
- <el-select v-model="searchForm.returnType" placeholder="璇烽�夋嫨绫诲瀷" clearable>
- <el-option label="閲囪喘閫�璐�" value="purchase" />
- <el-option label="璐ㄦ閫�璐�" value="quality" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <el-card class="table-card" shadow="never">
- <div class="table-header">
- <el-button type="primary" @click="openDialog('add')">鏂板閫�璐у崟</el-button>
- <el-button type="danger" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
- </div>
-
- <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="閫�璐у崟鍙�" prop="returnNo" width="180" />
- <el-table-column label="鍏宠仈鍗曞彿" prop="relatedNo" width="180" />
- <el-table-column label="閫�璐х被鍨�" prop="returnType" width="100">
- <template #default="{ row }">
- <el-tag :type="row.returnType === 'purchase' ? 'danger' : 'warning'">
- {{ getReturnTypeText(row.returnType) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" />
- <el-table-column label="閫�璐х姸鎬�" prop="status" width="100">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍒涘缓鏃堕棿" prop="createTime" width="180" />
- <el-table-column label="鎿嶄綔" width="200" align="center">
- <template #default="{ row }">
- <el-button type="primary" link @click="openDialog('edit', row)">缂栬緫</el-button>
- <el-button type="success" link @click="handleApprove(row)" v-if="row.status === 'pending'">瀹℃牳</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- <!-- 鍒嗛〉 -->
- <pagination
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.current"
- :limit="pagination.size"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板閫�璐у崟' : '缂栬緫閫�璐у崟'" width="600px">
- <el-form :model="formData" label-width="120px">
- <el-form-item label="閫�璐х被鍨�">
- <el-select v-model="formData.returnType" placeholder="璇烽�夋嫨閫�璐х被鍨�" style="width: 100%">
- <el-option label="閲囪喘閫�璐�" value="purchase" />
- <el-option label="璐ㄦ閫�璐�" value="quality" />
- </el-select>
- </el-form-item>
- <el-form-item label="鍏宠仈鍗曞彿">
- <el-select v-model="formData.relatedNo" placeholder="璇烽�夋嫨鍏宠仈鍗曞彿" style="width: 100%">
- <el-option v-for="item in onList" :key="item.arrivalNo" :label="item.arrivalNo" :value="item.arrivalNo" />
- </el-select>
- </el-form-item>
- <el-form-item label="渚涘簲鍟嗗悕绉�">
- <el-input v-model="formData.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О" />
- </el-form-item>
- <el-form-item label="閫�璐у師鍥�">
- <el-select v-model="formData.returnReason" placeholder="璇烽�夋嫨閫�璐у師鍥�" style="width: 100%">
- <el-option label="璐ㄩ噺闂" value="quality" />
- <el-option label="瑙勬牸涓嶇" value="specification" />
- <el-option label="鏁伴噺閿欒" value="quantity" />
- </el-select>
- </el-form-item>
- <el-form-item label="澶囨敞">
- <el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit">纭畾</el-button>
- </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 {listPage,add,update,del} from "@/api/procurementManagement/returnManagement.js"
-import {listPageCopy} from "@/api/procurementManagement/arrivalManagement.js"
-
-onMounted(() => {
- getList()
- list()
-})
-const onList = ref([])
-const list = () =>{
- listPageCopy({current:-1}).then(res=>{
- if(res.code === 200){
- onList.value = res.data.records
- }
- })
-}
-const tableData = ref([])
-const getList = () => {
- loading.value = true
- listPage({...searchForm,...pagination}).then(res =>{
- if(res.code === 200){
- tableData.value = res.data.records
- console.log(tableData.value)
- total.value = res.data.total
- loading.value = false
- }
- })
-}
-
-const loading = ref(false)
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const selectedRows = ref([])
-
-
-const pagination = reactive({
- current: 1,
- size: 10
-})
-
-const total = ref(0)
-
-const searchForm = reactive({
- returnNo: '',
- returnType: ''
-})
-
-const formData = reactive({
- returnType: '',
- relatedNo: '',
- supplierName: '',
- returnReason: '',
- remark: '',
- status: ''
-})
-
-const getReturnTypeText = (type) => {
- const typeMap = { purchase: '閲囪喘閫�璐�', quality: '璐ㄦ閫�璐�' }
- return typeMap[type] || '鏈煡'
-}
-
-const getStatusType = (status) => {
- const statusMap = { pending: 'warning', approved: 'success', returned: 'info' }
- return statusMap[status] || 'info'
-}
-
-const getStatusText = (status) => {
- const statusMap = { pending: '寰呭鏍�', approved: '宸插鏍�', returned: '宸查��璐�' }
- return statusMap[status] || '鏈煡'
-}
-
-const handleSearch = () => {
- loading.value = true
- getList()
-}
-
-const resetSearch = () => {
- Object.assign(searchForm, { returnNo: '', returnType: '' })
-}
-
-const openDialog = (type, row = {}) => {
- dialogType.value = type
- obj.id = row.id
- if (type === 'edit' && row.id) {
- Object.assign(formData, {
- returnType: row.returnType,
- relatedNo: row.relatedNo,
- supplierName: row.supplierName,
- returnReason: row.returnReason,
- remark: row.remark,
- status: row.status
- })
- } else {
- Object.assign(formData, {
- returnType: '',
- relatedNo: '',
- supplierName: '',
- returnReason: '',
- remark: '',
- status: 'pending'
- })
- }
- dialogVisible.value = true
-}
-const obj = reactive({
- id: ''
-})
-const handleSubmit = () => {
- if (dialogType.value === 'add') {
- formData.status = 'pending'
- add(formData).then(res => {
- if(res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- getList()
- }
- })
- }else{
- update({...formData,...obj}).then(res => {
- if(res.code === 200){
- ElMessage.success('淇敼鎴愬姛')
- getList()
- }
- })
- }
- dialogVisible.value = false
-}
-
-const handleApprove = (row) => {
- row.status = 'approved'
- update(row).then(res => {
- if(res.code === 200){
- ElMessage.success('瀹℃牳鎴愬姛')
- getList()
- }
- })
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭畾瑕佸垹闄よ繖鏉¤褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- del(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- }
- })
- })
-}
-
-const handleBatchDelete = () => {
- let ids = selectedRows.value.map(item => item.id)
- del(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鎵归噺鍒犻櫎鎴愬姛')
- getList()
- }
- })
-}
-
-const handleSelectionChange = (rows) => {
- selectedRows.value = rows
-}
-</script>
-
-<style scoped>
-.app-container { padding: 20px; }
-.search-card { margin-bottom: 20px; }
-.table-card { margin-bottom: 20px; }
-.table-header { margin-bottom: 20px; }
-</style>
diff --git a/src/views/procurementManagement/thePaymentLedger/index.vue b/src/views/procurementManagement/thePaymentLedger/index.vue
deleted file mode 100644
index 5fa9e6f..0000000
--- a/src/views/procurementManagement/thePaymentLedger/index.vue
+++ /dev/null
@@ -1,101 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">渚涘簲鍟嗗悕绉�/鍚堝悓鍙凤細</span>
- <el-input
- v-model="searchForm.supplierNameOrContractNo"
- style="width: 240px"
- placeholder="杈撳叆渚涘簲鍟嗗悕绉�/鍚堝悓鍙锋悳绱�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="total"
- ></PIMTable>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { registrationList } from "@/api/procurementManagement/paymentEntry.js";
-const tableColumn = ref([
- {
- label: "浠樻鏃ユ湡",
- prop: "paymentDate",
- },
- {
- label: "渚涘簲鍟嗗悕绉�",
- prop: "supplierName",
- },
- {
- label: "浠樻閲戦",
- prop: "currentPaymentAmount",
- },
- {
- label: "鐧昏浜�",
- prop: "registrant",
- },
- {
- label: "鐧昏鏃ユ湡",
- prop: "registrationtDate",
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const purchaseLedgerList = ref([]);
-const invoiceNumberList = ref([]);
-const page = reactive({
- current: 1,
- size: 10,
-});
-const total = ref(0);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- supplierNameOrContractNo: "",
- },
-});
-const { searchForm, form, rules } = toRefs(data);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = ({ current, limit }) => {
- page.current = current;
- page.size = limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- registrationList({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.rows;
- total.value = res.total;
- });
-};
-getList();
-</script>
-
-<style scoped lang="scss"></style>
diff --git a/src/views/productManagement/productIdentifier/index.vue b/src/views/productManagement/productIdentifier/index.vue
deleted file mode 100644
index 59d8f90..0000000
--- a/src/views/productManagement/productIdentifier/index.vue
+++ /dev/null
@@ -1,708 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.productName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.identifierType" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" clearable>
- <el-option label="浜岀淮鐮�" value="浜岀淮鐮�"></el-option>
- <el-option label="闃蹭吉鐮�" value="闃蹭吉鐮�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="宸茬敓鎴�" value="宸茬敓鎴�"></el-option>
- <el-option label="宸插垎閰�" value="宸插垎閰�"></el-option>
- <el-option label="宸蹭娇鐢�" value="宸蹭娇鐢�"></el-option>
- <el-option label="宸蹭綔搴�" value="宸蹭綔搴�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button style="float: right;" type="primary" @click="handleAdd">
- 鏂板鏍囪瘑
- </el-button>
- </el-col>
- </el-row>
-
- <!-- 浜у搧鏍囪瘑鍒楄〃 -->
- <el-table
- :data="filteredList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="id" label="ID" width="80" align="center"/>
- <el-table-column prop="productName" label="浜у搧鍚嶇О" width="150" />
- <el-table-column prop="productCode" label="浜у搧缂栫爜" width="120" />
- <el-table-column prop="batchNo" label="鎵规鍙�" width="120" />
- <el-table-column prop="identifierType" label="鏍囪瘑绫诲瀷" width="100">
- <template #default="scope">
- <el-tag :type="getIdentifierTypeType(scope.row.identifierType)">
- {{ scope.row.identifierType }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="identifierCode" label="鏍囪瘑鐮�" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="generateTime" label="鐢熸垚鏃堕棿" width="160" />
- <el-table-column label="鎿嶄綔" fixed="right" align="center" width="280">
- <template #default="scope">
- <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
- <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="success" @click="generateQRCode(scope.row)">鐢熸垚浜岀淮鐮�</el-button>
- <el-button link type="primary" @click="handleExport(scope.row)">瀵煎嚭</el-button>
- <el-button link type="primary" @click="handleReassign(scope.row)" v-if="scope.row.status === '宸插垎閰�'">閲嶆柊鍒嗛厤</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.currentPage"
- :limit="pagination.pageSize"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浜у搧鍚嶇О" prop="productName">
- <el-input v-model="form.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浜у搧缂栫爜" prop="productCode">
- <el-input v-model="form.productCode" placeholder="璇疯緭鍏ヤ骇鍝佺紪鐮�"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鎵规鍙�" prop="batchNo">
- <el-input v-model="form.batchNo" placeholder="璇疯緭鍏ユ壒娆″彿"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏍囪瘑绫诲瀷" prop="identifierType">
- <el-select v-model="form.identifierType" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" style="width: 100%">
- <el-option label="浜岀淮鐮�" value="浜岀淮鐮�"></el-option>
- <el-option label="闃蹭吉鐮�" value="闃蹭吉鐮�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐢熸垚鏁伴噺" prop="quantity">
- <el-input-number v-model="form.quantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option label="宸茬敓鎴�" value="宸茬敓鎴�"></el-option>
- <el-option label="宸插垎閰�" value="宸插垎閰�"></el-option>
- <el-option label="宸蹭娇鐢�" value="宸蹭娇鐢�"></el-option>
- <el-option label="宸蹭綔搴�" value="宸蹭綔搴�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞" prop="remark">
- <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鏍囪瘑鐢熸垚瀵硅瘽妗� -->
- <el-dialog v-model="generateDialogVisible" title="鏍囪瘑鐢熸垚" width="500px">
- <el-form label-width="100px">
- <el-form-item label="浜у搧鍚嶇О">
- <span>{{ currentProduct.productName }}</span>
- </el-form-item>
- <el-form-item label="浜у搧缂栫爜">
- <span>{{ currentProduct.productCode }}</span>
- </el-form-item>
- <el-form-item label="鎵规鍙�">
- <span>{{ currentProduct.batchNo }}</span>
- </el-form-item>
- <el-form-item label="鏍囪瘑绫诲瀷">
- <span>{{ currentProduct.identifierType }}</span>
- </el-form-item>
- <el-form-item label="鐢熸垚鏁伴噺" prop="generateQuantity">
- <el-input-number v-model="generateQuantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
- </el-form-item>
- <el-form-item label="缂栫爜瑙勫垯" prop="codeRule">
- <el-select v-model="codeRule" placeholder="璇烽�夋嫨缂栫爜瑙勫垯" style="width: 100%">
- <el-option label="浜у搧缂栫爜+鎵规鍙�+搴忓彿" value="浜у搧缂栫爜+鎵规鍙�+搴忓彿"></el-option>
- <el-option label="鏃堕棿鎴�+闅忔満鏁�" value="鏃堕棿鎴�+闅忔満鏁�"></el-option>
- <el-option label="鑷畾涔夎鍒�" value="鑷畾涔夎鍒�"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="鑷畾涔夊墠缂�" prop="customPrefix" v-if="codeRule === '鑷畾涔夎鍒�'">
- <el-input v-model="customPrefix" placeholder="璇疯緭鍏ヨ嚜瀹氫箟鍓嶇紑"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="generateDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="generateIdentifiers">鐢� 鎴�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 閲嶆柊鍒嗛厤瀵硅瘽妗� -->
- <el-dialog v-model="reassignDialogVisible" title="閲嶆柊鍒嗛厤鏍囪瘑" width="500px">
- <el-form label-width="100px">
- <el-form-item label="浜у搧鍚嶇О">
- <span>{{ currentProduct.productName }}</span>
- </el-form-item>
- <el-form-item label="鏍囪瘑鐮�">
- <span>{{ currentProduct.identifierCode }}</span>
- </el-form-item>
- <el-form-item label="鏂版壒娆″彿" prop="newBatchNo">
- <el-input v-model="newBatchNo" placeholder="璇疯緭鍏ユ柊鎵规鍙�"></el-input>
- </el-form-item>
- <el-form-item label="鍒嗛厤鍘熷洜" prop="reassignReason">
- <el-input type="textarea" v-model="reassignReason" rows="3" placeholder="璇疯緭鍏ラ噸鏂板垎閰嶅師鍥�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="reassignDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="saveReassign">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浜岀淮鐮侀瑙堝璇濇 -->
- <el-dialog v-model="qrCodeDialogVisible" title="浜岀淮鐮侀瑙�" width="500px" center>
- <div class="qr-preview-container">
- <div v-if="qrCodeUrl" class="qr-image-container">
- <img :src="qrCodeUrl" alt="浜岀淮鐮�" class="qr-image" />
- <div class="qr-info">
- <p><strong>浜у搧鍚嶇О锛�</strong>{{ currentQRProduct.productName }}</p>
- <p><strong>浜у搧缂栫爜锛�</strong>{{ currentQRProduct.productCode }}</p>
- <p><strong>鎵规鍙凤細</strong>{{ currentQRProduct.batchNo }}</p>
- <p><strong>鏍囪瘑鐮侊細</strong>{{ currentQRProduct.identifierCode }}</p>
- <p><strong>鏍囪瘑绫诲瀷锛�</strong>{{ currentQRProduct.identifierType }}</p>
- </div>
- </div>
- <div v-else class="qr-loading">
- <el-icon class="is-loading"><Loading /></el-icon>
- <p>姝e湪鐢熸垚浜岀淮鐮�...</p>
- </div>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="qrCodeDialogVisible = false">鍏抽棴</el-button>
- <el-button
- v-if="qrCodeUrl"
- type="primary"
- @click="copyQRContent"
- icon="CopyDocument"
- >
- 澶嶅埗鍐呭
- </el-button>
- <el-button
- v-if="qrCodeUrl"
- type="success"
- @click="downloadQRCode"
- icon="Download"
- >
- 涓嬭浇浜岀淮鐮�
- </el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search, Loading, Download } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-import QRCode from 'qrcode'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- productName: '',
- identifierType: '',
- status: ''
-})
-
-const identifierList = ref([
- {
- id: 1,
- productName: '宸ヤ笟浼犳劅鍣ˋ鍨�',
- productCode: 'SENSOR001',
- batchNo: 'B202312001',
- identifierType: '浜岀淮鐮�',
- identifierCode: 'QR_SENSOR001_B202312001_001',
- status: '宸插垎閰�',
- generateTime: '2023-12-01 10:00:00',
- remark: '閲嶈浜у搧鏍囪瘑'
- },
- {
- id: 2,
- productName: '鎺у埗闈㈡澘B鍨�',
- productCode: 'PANEL002',
- batchNo: 'B202312002',
- identifierType: '闃蹭吉鐮�',
- identifierCode: 'SEC_PANEL002_B202312002_001',
- status: '宸茬敓鎴�',
- generateTime: '2023-12-02 14:30:00',
- remark: '甯歌浜у搧鏍囪瘑'
- },
- {
- id: 3,
- productName: '鏁版嵁閲囬泦鍣–鍨�',
- productCode: 'COLLECTOR003',
- batchNo: 'B202312003',
- identifierType: '闃蹭吉鐮�',
- identifierCode: 'SEC_COLLECTOR003_B202312003_001',
- status: '宸蹭娇鐢�',
- generateTime: '2023-12-03 09:15:00',
- remark: '娴嬭瘯浜у搧鏍囪瘑'
- }
-])
-
-const pagination = reactive({
- total: 3,
- currentPage: 1,
- pageSize: 10
-})
-
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板鏍囪瘑')
-const form = reactive({
- productName: '',
- productCode: '',
- batchNo: '',
- identifierType: '',
- quantity: 1,
- status: '宸茬敓鎴�',
- remark: ''
-})
-
-const rules = {
- productName: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佸悕绉�', trigger: 'blur' }],
- productCode: [{ required: true, message: '璇疯緭鍏ヤ骇鍝佺紪鐮�', trigger: 'blur' }],
- batchNo: [{ required: true, message: '璇疯緭鍏ユ壒娆″彿', trigger: 'blur' }],
- identifierType: [{ required: true, message: '璇烽�夋嫨鏍囪瘑绫诲瀷', trigger: 'change' }],
- quantity: [{ required: true, message: '璇疯緭鍏ョ敓鎴愭暟閲�', trigger: 'blur' }],
- status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
-
-const isEdit = ref(false)
-const editId = ref(null)
-const generateDialogVisible = ref(false)
-const reassignDialogVisible = ref(false)
-const currentProduct = ref({})
-const generateQuantity = ref(1)
-const codeRule = ref('')
-const customPrefix = ref('')
-const newBatchNo = ref('')
-const reassignReason = ref('')
-const formRef = ref()
-
-// 浜岀淮鐮佺浉鍏冲彉閲�
-const qrCodeDialogVisible = ref(false)
-const qrCodeUrl = ref('')
-const currentQRProduct = ref({})
-
-// 璁$畻灞炴��
-const filteredList = computed(() => {
- let list = identifierList.value
- if (searchForm.productName) {
- list = list.filter(item => item.productName.includes(searchForm.productName))
- }
- if (searchForm.identifierType) {
- list = list.filter(item => item.identifierType === searchForm.identifierType)
- }
- if (searchForm.status) {
- list = list.filter(item => item.status === searchForm.status)
- }
- return list
-})
-
-// 鏂规硶
-const getIdentifierTypeType = (type) => {
- const typeMap = {
- '浜岀淮鐮�': 'success',
- '闃蹭吉鐮�': 'warning'
- }
- return typeMap[type] || 'info'
-}
-
-const getStatusType = (status) => {
- const statusMap = {
- '宸茬敓鎴�': 'info',
- '宸插垎閰�': 'primary',
- '宸蹭娇鐢�': 'success',
- '宸蹭綔搴�': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-const handleSearch = () => {
- // 鎼滅储閫昏緫宸插湪computed涓鐞�
-}
-
-const resetSearch = () => {
- searchForm.productName = ''
- searchForm.identifierType = ''
- searchForm.status = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板鏍囪瘑'
- isEdit.value = false
- form.productName = ''
- form.productCode = ''
- form.batchNo = ''
- form.identifierType = ''
- form.quantity = 1
- form.status = '宸茬敓鎴�'
- form.remark = ''
- dialogVisible.value = true
-}
-
-const handleView = (row) => {
- // 鏌ョ湅鏍囪瘑璇︽儏
- ElMessage.info('鏌ョ湅鏍囪瘑璇︽儏鍔熻兘寰呭疄鐜�')
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫鏍囪瘑'
- isEdit.value = true
- editId.value = row.id
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handleExport = (row) => {
- // 瀵煎嚭鏍囪瘑
- ElMessage.success(`宸插鍑烘爣璇�: ${row.identifierCode}`)
-}
-
-const handleReassign = (row) => {
- currentProduct.value = row
- newBatchNo.value = ''
- reassignReason.value = ''
- reassignDialogVisible.value = true
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ユ爣璇嗗悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = identifierList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- identifierList.value.splice(index, 1)
- pagination.total--
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-// 鐢熸垚浜岀淮鐮�
-const generateQRCode = async (row) => {
- try {
- // 妫�鏌ュ繀瑕佸瓧娈�
- if (!row.productName || !row.productCode || !row.batchNo) {
- ElMessage.warning('浜у搧淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚浜岀淮鐮�')
- return
- }
-
- currentQRProduct.value = row
- qrCodeUrl.value = ''
- qrCodeDialogVisible.value = true
-
- // 鏋勫缓浜岀淮鐮佸唴瀹�
- let qrContent = ''
- if (row.identifierType === '浜岀淮鐮�') {
- qrContent = `${row.productName}|${row.productCode}|${row.batchNo}|${row.identifierCode}`
- } else if (row.identifierType === '闃蹭吉鐮�') {
- // 闃蹭吉鐮佹牸寮忥細SEC_浜у搧缂栫爜_鎵规鍙穇鏃堕棿鎴砡闅忔満鏁�
- const timestamp = Date.now()
- const random = Math.random().toString(36).substr(2, 8)
- qrContent = `SEC_${row.productCode}_${row.batchNo}_${timestamp}_${random}`
- }
-
- // 鐢熸垚浜岀淮鐮�
- qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
- width: 256,
- margin: 2,
- color: {
- dark: '#000000',
- light: '#FFFFFF'
- },
- errorCorrectionLevel: row.identifierType === '闃蹭吉鐮�' ? 'H' : 'M'
- })
-
- ElMessage.success('浜岀淮鐮佺敓鎴愭垚鍔燂紒')
-
- } catch (error) {
- console.error('鐢熸垚浜岀淮鐮佸け璐�:', error)
- ElMessage.error('鐢熸垚浜岀淮鐮佸け璐ワ細' + error.message)
- qrCodeDialogVisible.value = false
- }
-}
-
-// 涓嬭浇浜岀淮鐮�
-const downloadQRCode = () => {
- if (!qrCodeUrl.value) {
- ElMessage.warning('璇峰厛鐢熸垚浜岀淮鐮�')
- return
- }
-
- const a = document.createElement('a')
- a.href = qrCodeUrl.value
- a.download = `${currentQRProduct.value.productName}_${currentQRProduct.value.identifierType}_${new Date().getTime()}.png`
- document.body.appendChild(a)
- a.click()
- document.body.removeChild(a)
- ElMessage.success('涓嬭浇鎴愬姛锛�')
-}
-
-// 澶嶅埗浜岀淮鐮佸唴瀹�
-const copyQRContent = async () => {
- if (!currentQRProduct.value) {
- ElMessage.warning('娌℃湁鍙鍒剁殑鍐呭')
- return
- }
-
- try {
- let content = ''
- if (currentQRProduct.value.identifierType === '浜岀淮鐮�') {
- content = `${currentQRProduct.value.productName}|${currentQRProduct.value.productCode}|${currentQRProduct.value.batchNo}|${currentQRProduct.value.identifierCode}`
- } else if (currentQRProduct.value.identifierType === '闃蹭吉鐮�') {
- const timestamp = Date.now()
- const random = Math.random().toString(36).substr(2, 8)
- content = `SEC_${currentQRProduct.value.productCode}_${currentQRProduct.value.batchNo}_${timestamp}_${random}`
- }
-
- await navigator.clipboard.writeText(content)
- ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
- } catch (error) {
- // 闄嶇骇鏂规
- const textArea = document.createElement('textarea')
- textArea.value = content
- document.body.appendChild(textArea)
- textArea.select()
- document.execCommand('copy')
- document.body.removeChild(textArea)
- ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
- }
-}
-
-const generateIdentifiers = () => {
- if (!codeRule.value) {
- ElMessage.warning('璇烽�夋嫨缂栫爜瑙勫垯')
- return
- }
-
- // 鐢熸垚鏍囪瘑鐨勯�昏緫
- const newIdentifiers = []
- for (let i = 1; i <= generateQuantity.value; i++) {
- let identifierCode = ''
- if (codeRule.value === '浜у搧缂栫爜+鎵规鍙�+搴忓彿') {
- identifierCode = `${currentProduct.value.productCode}_${currentProduct.value.batchNo}_${String(i).padStart(3, '0')}`
- } else if (codeRule.value === '鏃堕棿鎴�+闅忔満鏁�') {
- identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`
- } else if (codeRule.value === '鑷畾涔夎鍒�') {
- identifierCode = `${customPrefix.value || 'CUSTOM'}_${Date.now()}_${i}`
- }
-
- newIdentifiers.push({
- id: Math.max(...identifierList.value.map(item => item.id)) + i,
- productName: currentProduct.value.productName,
- productCode: currentProduct.value.productCode,
- batchNo: currentProduct.value.batchNo,
- identifierType: currentProduct.value.identifierType,
- identifierCode: identifierCode,
- status: '宸茬敓鎴�',
- generateTime: new Date().toLocaleString(),
- remark: '鎵归噺鐢熸垚'
- })
- }
-
- identifierList.value.push(...newIdentifiers)
- pagination.total += newIdentifiers.length
- ElMessage.success(`鎴愬姛鐢熸垚 ${newIdentifiers.length} 涓爣璇哷)
- generateDialogVisible.value = false
-}
-
-const saveReassign = () => {
- if (!newBatchNo.value) {
- ElMessage.warning('璇疯緭鍏ユ柊鎵规鍙�')
- return
- }
-
- const index = identifierList.value.findIndex(item => item.id === currentProduct.value.id)
- if (index > -1) {
- identifierList.value[index].batchNo = newBatchNo.value
- identifierList.value[index].status = '宸插垎閰�'
- ElMessage.success('鏍囪瘑閲嶆柊鍒嗛厤鎴愬姛')
- reassignDialogVisible.value = false
- }
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (isEdit.value) {
- // 缂栬緫
- const index = identifierList.value.findIndex(item => item.id === editId.value)
- if (index > -1) {
- identifierList.value[index] = { ...form, id: editId.value }
- ElMessage.success('缂栬緫鎴愬姛')
- }
- } else {
- // 鏂板
- const newId = Math.max(...identifierList.value.map(item => item.id)) + 1
-
- // 鏍规嵁鏍囪瘑绫诲瀷鐢熸垚涓嶅悓鐨勬爣璇嗙爜
- let identifierCode = ''
- if (form.identifierType === '浜岀淮鐮�') {
- identifierCode = `QR_${form.productCode}_${form.batchNo}_001`
- } else if (form.identifierType === '闃蹭吉鐮�') {
- identifierCode = `SEC_${form.productCode}_${form.batchNo}_001`
- }
-
- identifierList.value.push({
- ...form,
- id: newId,
- identifierCode: identifierCode,
- generateTime: new Date().toLocaleString()
- })
- pagination.total++
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val.page
- pagination.pageSize = val.limit
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-
-.quick-actions-row {
- margin-bottom: 20px;
-}
-
-.quick-actions-row .el-alert {
- margin-bottom: 0;
-}
-
-.quick-actions-row .el-alert p {
- margin: 5px 0;
- font-size: 14px;
- line-height: 1.5;
-}
-
-/* 浜岀淮鐮侀瑙堟牱寮� */
-.qr-preview-container {
- text-align: center;
- padding: 20px;
-}
-
-.qr-image-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 20px;
-}
-
-.qr-image {
- max-width: 100%;
- height: auto;
- border: 2px solid #e0e0e0;
- border-radius: 8px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.qr-info {
- text-align: left;
- background: #f8f9fa;
- padding: 15px;
- border-radius: 8px;
- min-width: 300px;
-}
-
-.qr-info p {
- margin: 8px 0;
- color: #666;
- font-size: 14px;
-}
-
-.qr-loading {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 15px;
- padding: 40px 0;
-}
-
-.qr-loading .el-icon {
- font-size: 32px;
- color: #409EFF;
-}
-
-.qr-loading p {
- color: #666;
- margin: 0;
-}
-</style>
diff --git a/src/views/productionManagement/operationScheduling/components/formDia.vue b/src/views/productionManagement/operationScheduling/components/formDia.vue
index a4f36bf..8906312 100644
--- a/src/views/productionManagement/operationScheduling/components/formDia.vue
+++ b/src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -7,8 +7,8 @@
@close="closeDia"
>
<el-button type="primary" @click="addRow" style="margin-bottom: 10px;">鏂板</el-button>
- <span style="font-size: 18px;margin-left: 10px">寰呮帓浜ф暟閲忥細{{pendingNum}}</span>
- <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id">
+ <span style="font-size: 18px;margin-left: 10px">寰呮帓浜ф暟閲忥細{{pendingNum}}</span>
+ <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id" stripe>
<el-table-column label="搴忓彿" width="60">
<template #default="scope">
{{ scope.$index + 1 }}
@@ -16,7 +16,11 @@
</el-table-column>
<el-table-column label="宸ュ簭" prop="process">
<template #default="scope">
- <el-input v-model="scope.row.process" placeholder="璇疯緭鍏ュ伐搴�" />
+ <el-input
+ v-model="scope.row.process"
+ placeholder="璇疯緭鍏ュ伐搴�"
+ clearable
+ />
</template>
</el-table-column>
<el-table-column label="鍗曚綅" prop="unit">
@@ -26,28 +30,28 @@
</el-table-column>
<el-table-column label="鎺掍骇鏁伴噺" width="200" prop="schedulingNum">
<template #default="scope">
- <el-input-number
- v-model="scope.row.schedulingNum"
- placeholder="璇疯緭鍏�"
- :min="0"
- :step="0.1"
- :precision="2"
- clearable
- style="width: 100%"
- />
+ <el-input-number
+ v-model="scope.row.schedulingNum"
+ placeholder="璇疯緭鍏�"
+ :min="0"
+ :step="0.1"
+ :precision="2"
+ clearable
+ style="width: 100%"
+ />
</template>
</el-table-column>
<el-table-column label="宸ユ椂瀹氶" width="200" prop="workHours">
<template #default="scope">
- <el-input-number
- v-model="scope.row.workHours"
- placeholder="璇疯緭鍏�"
- :min="0"
- :step="0.1"
- :precision="2"
- clearable
- style="width: 100%"
- />
+ <el-input-number
+ v-model="scope.row.workHours"
+ placeholder="璇疯緭鍏�"
+ :min="0"
+ :step="0.1"
+ :precision="2"
+ clearable
+ style="width: 100%"
+ />
</template>
</el-table-column>
<el-table-column label="鎺掍骇鏃ユ湡" prop="schedulingDate">
@@ -57,18 +61,18 @@
</el-table-column>
<el-table-column label="鎺掍骇浜�" prop="schedulingUserId">
<template #default="scope">
- <el-select
- v-model="scope.row.schedulingUserId"
- placeholder="閫夋嫨浜哄憳"
- style="width: 100%;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
+ <el-select
+ v-model="scope.row.schedulingUserId"
+ placeholder="閫夋嫨浜哄憳"
+ style="width: 100%;"
+ >
+ <el-option
+ v-for="user in userList"
+ :key="user.userId"
+ :label="user.nickName"
+ :value="user.userId"
+ />
+ </el-select>
</template>
</el-table-column>
<el-table-column label="鎿嶄綔" width="80">
@@ -77,12 +81,12 @@
</template>
</el-table-column>
</el-table>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ </div>
+ </template>
</el-dialog>
</div>
</template>
@@ -92,13 +96,12 @@
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {processScheduling} from "@/api/productionManagement/operationScheduling.js";
const { proxy } = getCurrentInstance()
-const { work_step } = proxy.useDict("work_step")
const emit = defineEmits(['close'])
const dialogFormVisible = ref(false);
const operationType = ref('')
const tableData = ref([
- { process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' }
+ { process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' }
]);
const unitFromRow = ref('');
const idFromRow = ref('');
@@ -109,10 +112,10 @@
const openDialog = (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- pendingNum.value = row.pendingNum
+ userListNoPageByTenantId().then((res) => {
+ userList.value = res.data;
+ });
+ pendingNum.value = row.pendingNum
if (row && row.unit !== undefined) {
unitFromRow.value = row.unit;
idFromRow.value = row.id;
@@ -125,36 +128,36 @@
}
}
const submitForm = () => {
- // 1. 妫�鏌ユ瘡涓�琛屾槸鍚﹀~鍐欏畬鏁�
- for (let i = 0; i < tableData.value.length; i++) {
- const row = tableData.value[i];
- if (
- !row.process ||
- !row.schedulingDate ||
- row.schedulingNum === '' || row.schedulingNum === null ||
- !row.schedulingUserId ||
- row.workHours === '' || row.workHours === null ||
- !row.unit
- ) {
- proxy.$modal.msgError(`绗�${i + 1}琛屾暟鎹湭濉啓瀹屾暣`);
- return;
- }
- }
- // 2. 鍚堣鎺掍骇鏁伴噺
- const totalSchedulingNum = tableData.value.reduce((sum, row) => {
- return sum + Number(row.schedulingNum || 0);
- }, 0);
- if (totalSchedulingNum > Number(pendingNum.value)) {
- proxy.$modal.msgError('鎺掍骇鏁伴噺鍚堣涓嶈兘瓒呰繃寰呮帓浜ф暟閲�');
- return;
- }
- processScheduling(tableData.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
+ // 1. 妫�鏌ユ瘡涓�琛屾槸鍚﹀~鍐欏畬鏁�
+ for (let i = 0; i < tableData.value.length; i++) {
+ const row = tableData.value[i];
+ if (
+ !row.process ||
+ !row.schedulingDate ||
+ row.schedulingNum === '' || row.schedulingNum === null ||
+ !row.schedulingUserId ||
+ row.workHours === '' || row.workHours === null ||
+ !row.unit
+ ) {
+ proxy.$modal.msgError(`绗�${i + 1}琛屾暟鎹湭濉啓瀹屾暣`);
+ return;
+ }
+ }
+ // 2. 鍚堣鎺掍骇鏁伴噺
+ const totalSchedulingNum = tableData.value.reduce((sum, row) => {
+ return sum + Number(row.schedulingNum || 0);
+ }, 0);
+ if (totalSchedulingNum > Number(pendingNum.value)) {
+ proxy.$modal.msgError('鎺掍骇鏁伴噺鍚堣涓嶈兘瓒呰繃寰呮帓浜ф暟閲�');
+ return;
+ }
+ processScheduling(tableData.value).then((res) => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ })
}
const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ['schedulingNum']);
+ return proxy.summarizeTable(param, ['schedulingNum']);
};
// 鍏抽棴寮规
const closeDia = () => {
@@ -175,4 +178,4 @@
<style scoped>
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/productionManagement/operationScheduling/index.vue b/src/views/productionManagement/operationScheduling/index.vue
index 082b782..134050d 100644
--- a/src/views/productionManagement/operationScheduling/index.vue
+++ b/src/views/productionManagement/operationScheduling/index.vue
@@ -1,53 +1,42 @@
<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="瀹㈡埛鍚嶇О:">
- <el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- style="width: 200px;"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О:">
- <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- style="width: 200px;"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="娲惧伐鏃ユ湡:">
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item label="鐘舵��:">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 140px" clearable>
- <el-option label="寰呮帓浜�" :value="1"></el-option>
- <el-option label="宸叉帓浜�" :value="3"></el-option>
- <el-option label="鎺掍骇涓�" :value="2"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div style="text-align: right" class="mb10">
- <el-button type="primary" @click="openForm">宸ュ簭鎺掍骇</el-button>
- <el-button type="danger" @click="handleDelete" plain>鍙栨秷鎺掍骇</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </div>
- <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>
+ <div class="app-container">
+ <div class="search_form">
+ <el-form :model="searchForm" :inline="true">
+ <el-form-item label="娲惧伐鏃ユ湡:">
+ <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ </el-form-item>
+ <el-form-item label="鐘舵��:">
+ <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 140px" clearable>
+ <el-option label="寰呮帓浜�" :value="1"></el-option>
+ <el-option label="宸叉帓浜�" :value="3"></el-option>
+ <el-option label="鎺掍骇涓�" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="table_list">
+ <div style="text-align: right" class="mb10">
+ <el-button type="primary" @click="openForm">宸ュ簭鎺掍骇</el-button>
+ <el-button type="danger" @click="handleDelete" plain>鍙栨秷鎺掍骇</el-button>
+ </div>
+ <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>
@@ -58,104 +47,87 @@
import {listPageProcess, productionDispatchDelete} from "@/api/productionManagement/operationScheduling.js";
const data = reactive({
- searchForm: {
- staffName: "",
- status: 1,
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
+ searchForm: {
+ staffName: "",
+ status: 1,
+ entryDate: [
+ dayjs().format("YYYY-MM-DD"),
+ dayjs().add(1, "day").format("YYYY-MM-DD"),
+ ], // 褰曞叆鏃ユ湡
+ entryDateStart: dayjs().format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
+ },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
- {
- label: "鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- if (params == 3) {
- return "宸叉帓浜�";
- } else if (params == 1) {
- return "寰呮帓浜�";
- } else {
- return '鎺掍骇涓�';
- }
- },
- formatType: (params) => {
- if (params == 3) {
- return "success";
- } else if (params == 1) {
- return "primary";
- } else {
- return 'warning';
- }
- },
- },
- {
- label: "娲惧伐鏃ユ湡",
- prop: "schedulingDate",
- width: 120,
- },
- {
- label: "娲惧伐浜�",
- prop: "schedulingUserName",
- },
- {
- label: "鍚堝悓鍙�",
- prop: "salesContractNo",
- width: 200,
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width: 200,
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 200,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:300
- },
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 150,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 150,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- label: "鎺掍骇鎬绘暟",
- prop: "schedulingNum",
- },
- {
- label: "宸叉帓浜ф暟閲�",
- prop: "successNum",
- width: 100,
- },
- {
- label: "寰呮帓浜ф暟閲�",
- prop: "pendingNum",
- width: 100,
- },
+ {
+ label: "鐘舵��",
+ prop: "status",
+ dataType: "tag",
+ formatData: (params) => {
+ if (params == 3) {
+ return "宸叉帓浜�";
+ } else if (params == 1) {
+ return "寰呮帓浜�";
+ } else {
+ return '鎺掍骇涓�';
+ }
+ },
+ formatType: (params) => {
+ if (params == 3) {
+ return "success";
+ } else if (params == 1) {
+ return "primary";
+ } else {
+ return 'warning';
+ }
+ },
+ },
+ {
+ label: "娲惧伐鏃ユ湡",
+ prop: "schedulingDate",
+ width: 120,
+ },
+ {
+ label: "娲惧伐浜�",
+ prop: "schedulingUserName",
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ width: 150,
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ width: 150,
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "鎺掍骇鎬绘暟",
+ prop: "schedulingNum",
+ },
+ {
+ label: "宸叉帓浜ф暟閲�",
+ prop: "successNum",
+ width: 100,
+ },
+ {
+ label: "寰呮帓浜ф暟閲�",
+ prop: "pendingNum",
+ width: 100,
+ },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
- current: 1,
- size: 100,
- total: 0,
+ current: 1,
+ size: 100,
+ total: 0,
});
const formDia = ref()
const { proxy } = getCurrentInstance()
@@ -163,109 +135,93 @@
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1;
- getList();
+ page.current = 1;
+ getList();
};
const changeDaterange = (value) => {
- if (value) {
- searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- }
- handleQuery();
+ if (value) {
+ searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+ searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+ } else {
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ }
+ handleQuery();
};
const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
};
const getList = () => {
- tableLoading.value = true;
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- listPageProcess(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records.map(item => ({
- ...item,
- pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.successNum) || 0)
- }));
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
+ tableLoading.value = true;
+ const params = { ...searchForm.value, ...page };
+ params.entryDate = undefined
+ listPageProcess(params).then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records.map(item => ({
+ ...item,
+ pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.successNum) || 0)
+ }));
+ page.total = res.data.total;
+ }).catch(err => {
+ tableLoading.value = false;
+ })
};
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
+ selectedRows.value = selection;
};
// 鎵撳紑寮规
const openForm = (type, row) => {
- if (selectedRows.value.length !== 1) {
- proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
- return;
- }
- if (selectedRows.value[0].pendingNum == 0) {
- proxy.$message.warning("鏃犻渶鍐嶆帓浜�");
- return;
- }
- nextTick(() => {
- formDia.value?.openDialog(type, selectedRows.value[0])
- })
+ if (selectedRows.value.length !== 1) {
+ proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
+ return;
+ }
+ if (selectedRows.value[0].pendingNum == 0) {
+ proxy.$message.warning("鏃犻渶鍐嶆帓浜�");
+ return;
+ }
+ nextTick(() => {
+ formDia.value?.openDialog(type, selectedRows.value[0])
+ })
};
// 鍒犻櫎
const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- // 鏂板锛氬垽鏂槸鍚︽湁宸叉帓浜х殑鏁版嵁
- const hasScheduled = selectedRows.value.some(item => item.status == 3);
- if (hasScheduled) {
- proxy.$modal.msgWarning("宸叉帓浜ф暟鎹笉鑳藉彇娑堟帓浜�");
- return;
- }
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("鏄惁纭鍙栨秷鎺掍骇锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- productionDispatchDelete(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍙栨秷鎺掍骇鎴愬姛");
- getList();
- })
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ // 鏂板锛氬垽鏂槸鍚︽湁宸叉帓浜х殑鏁版嵁
+ const hasScheduled = selectedRows.value.some(item => item.status == 3);
+ if (hasScheduled) {
+ proxy.$modal.msgWarning("宸叉帓浜ф暟鎹笉鑳藉彇娑堟帓浜�");
+ return;
+ }
+ ids = selectedRows.value.map((item) => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("鏄惁纭鍙栨秷鎺掍骇锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ productionDispatchDelete(ids)
+ .then((res) => {
+ proxy.$modal.msgSuccess("鍙栨秷鎺掍骇鎴愬姛");
+ getList();
+ })
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/salesLedger/scheduling/exportTwo", {}, "宸ュ簭鎺掍骇.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
onMounted(() => {
- getList();
+ getList();
});
</script>
diff --git a/src/views/productionManagement/productionCosting/index.vue b/src/views/productionManagement/productionCosting/index.vue
index 76e7414..c3873f2 100644
--- a/src/views/productionManagement/productionCosting/index.vue
+++ b/src/views/productionManagement/productionCosting/index.vue
@@ -1,44 +1,44 @@
<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">鐢熶骇鏃ユ湡锛�</span>
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- <span class="search_title ml10">鐢熶骇浜猴細</span>
- <el-input
- v-model="searchForm.schedulingUserName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </div>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
- </div>
- </div>
+ <div class="app-container">
+ <div class="search_form">
+ <div>
+ <span class="search_title">鐢熶骇鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ <span class="search_title ml10">鐢熶骇浜猴細</span>
+ <el-input
+ v-model="searchForm.schedulingUserName"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ @change="handleQuery"
+ clearable
+ prefix-icon="Search"
+ />
+ <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+ >鎼滅储</el-button
+ >
+ </div>
+ <div>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ ></PIMTable>
+ </div>
+ </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {
- listCustomer,
+ listCustomer,
} from "@/api/basicData/customerFile.js";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
@@ -46,140 +46,120 @@
const { proxy } = getCurrentInstance();
const tableColumn = ref([
- {
- label: "鐢熶骇鏃ユ湡",
- prop: "schedulingDate",
- width: 120,
- },
- {
- label: "鐢熶骇浜�",
- prop: "schedulingUserName",
- width: 90,
- },
- {
- label: "鍚堝悓鍙�",
- prop: "salesContractNo",
- width: 220,
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width: 250,
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 250,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:300
- },
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 160,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 160,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- label: "宸ュ簭",
- prop: "process",
- },
- {
- label: "鐢熶骇鏁伴噺",
- prop: "finishedNum",
- width: 100,
- },
- {
- label: "宸ユ椂瀹氶",
- prop: "workHours",
- width: 100,
- },
- {
- label: "宸ヨ祫",
- prop: "wages",
- width: 100,
- },
+ {
+ label: "鐢熶骇鏃ユ湡",
+ prop: "schedulingDate",
+ width: 120,
+ },
+ {
+ label: "鐢熶骇浜�",
+ prop: "schedulingUserName",
+ width: 90,
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ width: 160,
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ width: 160,
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "宸ュ簭",
+ prop: "process",
+ },
+ {
+ label: "鐢熶骇鏁伴噺",
+ prop: "finishedNum",
+ width: 100,
+ },
+ {
+ label: "宸ユ椂瀹氶",
+ prop: "workHours",
+ width: 100,
+ },
+ {
+ label: "宸ヨ祫",
+ prop: "wages",
+ width: 100,
+ },
]);
const tableData = ref([]);
const tableLoading = ref(false);
const page = reactive({
- current: 1,
- size: 100,
- total: 0,
+ current: 1,
+ size: 100,
+ total: 0,
});
const data = reactive({
- searchForm: {
- schedulingUserName: "",
- entryDate: [
- dayjs().format("YYYY-MM-DD"),
- dayjs().add(1, "day").format("YYYY-MM-DD"),
- ], // 褰曞叆鏃ユ湡
- entryDateStart: dayjs().format("YYYY-MM-DD"),
- entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
- },
+ searchForm: {
+ schedulingUserName: "",
+ entryDate: [
+ dayjs().format("YYYY-MM-DD"),
+ dayjs().add(1, "day").format("YYYY-MM-DD"),
+ ], // 褰曞叆鏃ユ湡
+ entryDateStart: dayjs().format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
+ },
});
const { searchForm } = toRefs(data);
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1;
- getList();
+ page.current = 1;
+ getList();
};
const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
};
const changeDaterange = (value) => {
- if (value) {
- searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- }
- handleQuery();
+ if (value) {
+ searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+ searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+ } else {
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ }
+ handleQuery();
};
const getList = () => {
- tableLoading.value = true;
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- productionAccountingListPage(params).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- });
+ tableLoading.value = true;
+ const params = { ...searchForm.value, ...page };
+ params.entryDate = undefined
+ productionAccountingListPage(params).then((res) => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+ page.total = res.data.total;
+ });
};
// 瀵煎嚭
const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/basic/customer/export", {}, "鐢熶骇鏍哥畻.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
onMounted(() => {
- getList();
+ getList();
});
</script>
diff --git a/src/views/productionManagement/productionDispatching/components/formDia.vue b/src/views/productionManagement/productionDispatching/components/formDia.vue
index a60f751..60619d1 100644
--- a/src/views/productionManagement/productionDispatching/components/formDia.vue
+++ b/src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -9,61 +9,55 @@
<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="projectName">
- <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable disabled/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
<el-form-item label="浜у搧澶х被锛�" prop="productCategory">
<el-input v-model="form.productCategory" placeholder="璇疯緭鍏�" clearable disabled/>
</el-form-item>
</el-col>
- </el-row>
- <el-row :gutter="30">
<el-col :span="12">
<el-form-item label="鎬绘暟閲忥細" prop="quantity">
<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/>
- </el-form-item>
+ <el-form-item label="寰呮帓浜ф暟閲忥細" prop="pendingQuantity">
+ <el-input v-model="form.pendingQuantity" placeholder="璇疯緭鍏�" clearable disabled/>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈鎺掍骇鏁伴噺锛�" prop="schedulingNum">
+ <el-input-number
+ v-model="form.schedulingNum"
+ placeholder="璇疯緭鍏�"
+ :min="0"
+ :step="0.1"
+ :precision="2"
+ clearable
+ @change="changeNum"
+ style="width: 100%"
+ />
+ </el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鏈鎺掍骇鏁伴噺锛�" prop="schedulingNum">
- <el-input-number
- v-model="form.schedulingNum"
- placeholder="璇疯緭鍏�"
- :min="0"
- :step="0.1"
- :precision="2"
- clearable
- @change="changeNum"
- style="width: 100%"
- />
- </el-form-item>
+ <el-form-item label="娲惧伐浜猴細" prop="schedulingUserId">
+ <el-select
+ v-model="form.schedulingUserId"
+ placeholder="閫夋嫨浜哄憳"
+ style="width: 100%;"
+ >
+ <el-option
+ v-for="user in userList"
+ :key="user.userId"
+ :label="user.nickName"
+ :value="user.userId"
+ />
+ </el-select>
+ </el-form-item>
</el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="娲惧伐浜猴細" prop="schedulingUserId">
- <el-select
- v-model="form.schedulingUserId"
- placeholder="閫夋嫨浜哄憳"
- style="width: 100%;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
<el-col :span="12">
<el-form-item label="娲惧伐鏃ユ湡锛�" prop="schedulingDate">
<el-date-picker
@@ -103,18 +97,18 @@
const operationType = ref('')
const data = reactive({
form: {
- projectName: "",
- productCategory: "",
- quantity: "",
- schedulingNum: "",
- schedulingUserId: "",
- schedulingDate: "",
- pendingQuantity: "",
+ productCategory: "",
+ quantity: "",
+ schedulingNum: "",
+ schedulingUserId: "",
+ schedulingDate: "",
+ pendingQuantity: "",
+ salesLedgerProductId: "",
},
rules: {
- schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
- schedulingUserId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
- schedulingDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
+ schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
+ schedulingUserId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
+ schedulingDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" },],
},
});
const { form, rules } = toRefs(data);
@@ -125,30 +119,34 @@
const openDialog = (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- form.value = {...row}
- form.value.schedulingNum = 0
- form.value.schedulingUserId = userStore.id
- form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
+ userListNoPageByTenantId().then((res) => {
+ 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");
}
//
const changeNum = (value) => {
- if (value > form.value.pendingQuantity) {
- form.value.schedulingNum = form.value.pendingQuantity;
- proxy.$modal.msgWarning('鎺掍骇鏁伴噺涓嶅彲澶т簬寰呮帓浜ф暟閲�')
- }
+ if (value > form.value.pendingQuantity) {
+ form.value.schedulingNum = form.value.pendingQuantity;
+ proxy.$modal.msgWarning('鎺掍骇鏁伴噺涓嶅彲澶т簬寰呮帓浜ф暟閲�')
+ }
}
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
proxy.$refs.formRef.validate(valid => {
if (valid) {
- productionDispatch(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- })
+ productionDispatch(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ })
}
})
}
@@ -166,4 +164,4 @@
<style scoped>
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/productionManagement/productionDispatching/index.vue b/src/views/productionManagement/productionDispatching/index.vue
index 527880f..840e17b 100644
--- a/src/views/productionManagement/productionDispatching/index.vue
+++ b/src/views/productionManagement/productionDispatching/index.vue
@@ -1,50 +1,31 @@
<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.customerName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <span class="search_title ml10">椤圭洰鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.projectName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- <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>
- </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>
+ <div class="app-container">
+ <div class="search_form">
+ <div>
+ <span class="search_title">褰曞叆鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
+ </div>
+ <div>
+ <el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</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>
@@ -52,81 +33,61 @@
import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
-import { ElMessageBox } from "element-plus";
const data = reactive({
- searchForm: {
- customerName: "",
- projectName: "",
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
+ searchForm: {
+ entryDate: [
+ dayjs().format("YYYY-MM-DD"),
+ dayjs().add(1, "day").format("YYYY-MM-DD"),
+ ], // 褰曞叆鏃ユ湡
+ entryDateStart: dayjs().format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
+ },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
- {
- label: "鍚堝悓鍙�",
- prop: "salesContractNo",
- width: 220,
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width: 250,
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 250,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:300
- },
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 160,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 220,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- width:90
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "entryDate",
- width: 120,
- },
- {
- label: "鏁伴噺",
- prop: "quantity",
- },
- {
- label: "鎺掍骇鏁伴噺",
- prop: "schedulingNum",
- width: 100,
- },
- {
- label: "寰呮帓鏁伴噺",
- prop: "pendingQuantity",
- width: 100,
- },
+ {
+ label: "褰曞叆鏃ユ湡",
+ prop: "registerDate",
+ width: 120,
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ width: 160,
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ width: 220,
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ width:90
+ },
+ {
+ label: "鏁伴噺",
+ prop: "quantity",
+ },
+ {
+ label: "鎺掍骇鏁伴噺",
+ prop: "schedulingNum",
+ width: 100,
+ },
+ {
+ label: "寰呮帓鏁伴噺",
+ prop: "pendingQuantity",
+ width: 100,
+ },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
- current: 1,
- size: 100,
- total: 0,
+ current: 1,
+ size: 100,
+ total: 0,
});
const formDia = ref()
const { proxy } = getCurrentInstance()
@@ -134,78 +95,69 @@
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1;
- getList();
+ page.current = 1;
+ getList();
};
const changeDaterange = (value) => {
- if (value) {
- searchForm.value.entryDateStart = value[0];
- searchForm.value.entryDateEnd = value[1];
- } else {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- }
- handleQuery();
+ if (value) {
+ searchForm.value.entryDateStart = value[0];
+ searchForm.value.entryDateEnd = value[1];
+ } else {
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ }
+ handleQuery();
};
const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
};
const getList = () => {
- tableLoading.value = true;
- // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- schedulingListPage(params).then((res) => {
- tableLoading.value = false;
- // 澶勭悊姣忔潯鏁版嵁锛屽鍔爌endingQuantity瀛楁
- tableData.value = res.data.records.map(item => ({
- ...item,
- pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
- }));
- page.total = res.data.total;
- }).catch(() => {
- tableLoading.value = false;
- })
+ tableLoading.value = true;
+ // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
+ const params = { ...searchForm.value, ...page };
+ params.entryDate = undefined
+ schedulingListPage(params).then((res) => {
+ tableLoading.value = false;
+ // 澶勭悊姣忔潯鏁版嵁锛屽鍔爌endingQuantity瀛楁
+ tableData.value = res.data.records.map(item => ({
+ ...item,
+ pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
+ }));
+ page.total = res.data.total;
+ }).catch(() => {
+ tableLoading.value = false;
+ })
};
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
+ selectedRows.value = selection;
};
// 鎵撳紑寮规
const openForm = (type) => {
- if (selectedRows.value.length !== 1) {
- proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
- return;
- }
- if (selectedRows.value[0].pendingQuantity == 0) {
- proxy.$message.warning("鏃犻渶鍐嶆淳宸�");
- return;
- }
- nextTick(() => {
- formDia.value?.openDialog(type, selectedRows.value[0])
- })
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/salesLedger/scheduling/exportOne", {}, "鐢熶骇娲惧伐.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ if (selectedRows.value.length !== 1) {
+ proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
+ return;
+ }
+ if (selectedRows.value[0].pendingQuantity == 0) {
+ proxy.$message.warning("鏃犻渶鍐嶆淳宸�");
+ return;
+ }
+ nextTick(() => {
+ formDia.value?.openDialog(type, selectedRows.value[0])
+ })
};
onMounted(() => {
- getList();
+ searchForm.value.entryDate = [
+ dayjs().format("YYYY-MM-DD"),
+ dayjs().add(1, "day").format("YYYY-MM-DD"),
+ ]
+ searchForm.value.entryDateStart = dayjs().format("YYYY-MM-DD")
+ searchForm.value.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
+ getList();
});
</script>
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 9928d46..8183ab1 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -1,197 +1,382 @@
<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.customerName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <span class="search_title ml10">椤圭洰鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.projectName"
- style="width: 240px"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- <div>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </div>
- </div>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
- </div>
- </div>
+ <div class="app-container">
+ <div class="search_form">
+ <div>
+ <span class="search_title">浜у搧澶х被锛�</span>
+<!-- <el-tree-select-->
+<!-- v-model="searchForm.productCategory"-->
+<!-- :data="productOptions"-->
+<!-- placeholder="璇烽�夋嫨"-->
+<!-- clearable-->
+<!-- check-strictly-->
+<!-- :render-after-expand="false"-->
+<!-- style="width: 240px"-->
+<!-- @change="handleQuery"-->
+<!-- />-->
+ <el-input
+ v-model="searchForm.productCategory"
+ style="width: 240px"
+ placeholder="璇疯緭鍏�"
+ @change="handleQuery"
+ clearable
+ prefix-icon="Search"
+ />
+ <span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
+ <el-date-picker v-model="searchForm.registerDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+ >鎼滅储</el-button
+ >
+ </div>
+ <div>
+ <el-button type="primary" @click="openDialog('create')">鏂板璁㈠崟</el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ >
+ <template #action="{ row }">
+ <el-button type="primary" link @click="handleEdit(row)">缂栬緫</el-button>
+ <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </PIMTable>
+ </div>
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="40%" @close="closeDialog">
+ <el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
+ <el-form-item label="褰曞叆鏃ユ湡" prop="registerDate">
+ <el-date-picker v-model="form.registerDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="璇烽�夋嫨褰曞叆鏃ユ湡" style="width: 100%"/>
+ </el-form-item>
+ <el-form-item label="浜у搧澶х被" prop="productCategory">
+ <el-input
+ v-model="form.productCategory"
+ placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�"
+ clearable
+ />
+ </el-form-item>
+ <el-form-item label="瑙勬牸鍨嬪彿" prop="specificationModel">
+ <el-input
+ v-model="form.specificationModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ clearable
+ />
+ </el-form-item>
+ <el-form-item label="鍗曚綅" prop="unit">
+ <el-input
+ v-model="form.unit"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ />
+ </el-form-item>
+ <el-form-item label="鏁伴噺" prop="quantity">
+ <el-input-number v-model="form.quantity" :min="0" :step="0.1" style="width: 100%"/>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button @click="closeDialog">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
</template>
<script setup>
-import {onMounted, ref} from "vue";
+import {onMounted, ref, reactive, toRefs, getCurrentInstance} from "vue";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
-import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
+import {schedulingListPage, addProductionOrder, updateProductionOrder, deleteProductionOrder} from "@/api/productionManagement/productionOrder.js";
+import {productTreeList} from "@/api/basicData/product.js";
const { proxy } = getCurrentInstance();
const tableColumn = ref([
- {
- label: "褰曞叆鏃ユ湡",
- prop: "entryDate",
- width: 120,
- },
- {
- label: "鍚堝悓鍙�",
- prop: "salesContractNo",
- width: 220,
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width: 250,
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 250,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:300
- },
- {
- label: "浠樻鐘舵��",
- prop: "status",
- dataType: "tag",
- formatType: (params) => {
- if (params == '鏈畬鎴�') {
- return "danger";
- } else if (params == '宸插畬鎴�') {
- return "success";
- } else {
- return null;
- }
- },
- },
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 160,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 220,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- width:90
- },
- {
- label: "鏁伴噺",
- prop: "quantity",
- },
- {
- label: "鎺掍骇鏁伴噺",
- prop: "schedulingNum",
- width: 100,
- },
- {
- label: "瀹屽伐鏁伴噺",
- prop: "successNum",
- width: 100,
- },
+ {
+ label: "褰曞叆鏃ユ湡",
+ prop: "registerDate",
+ width: 120,
+ },
+ {
+ label: "鐢熶骇璁㈠崟鍙�",
+ prop: "orderNo",
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "鏁伴噺",
+ prop: "quantity",
+ },
+ // {
+ // label: "鎺掍骇鏁伴噺",
+ // prop: "schedulingNum",
+ // width: 100,
+ // },
+ // {
+ // label: "瀹屽伐鏁伴噺",
+ // prop: "successNum",
+ // width: 100,
+ // },
+ {
+ label: "鎿嶄綔",
+ prop: "action",
+ width: 120,
+ fixed: "right",
+ dataType: "slot",
+ align: "center",
+ slot: "action"
+ }
]);
const tableData = ref([]);
const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
+const page = ref({
+ current: 1,
+ size: 100,
+ total: 0,
});
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const dialogMode = ref(""); // 'create' 鎴� 'edit'
+const formRef = ref();
+const productOptions = ref([]);
+const form = reactive({
+ id: null,
+ registerDate: dayjs().format("YYYY-MM-DD"),
+ productCategory: "",
+ specificationModel: "",
+ unit: "",
+ quantity: null,
+});
+const formRules = {
+ registerDate: [{ required: true, message: "璇烽�夋嫨褰曞叆鏃ユ湡", trigger: "change" }],
+ productCategory: [{ required: true, message: "璇疯緭鍏ヤ骇鍝佸ぇ绫�", trigger: "blur" }],
+ specificationModel: [{ required: true, message: "璇疯緭鍏ヨ鏍煎瀷鍙�", trigger: "blur" }],
+ unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+ quantity: [{ required: true, message: "璇疯緭鍏ユ暟閲�", trigger: "blur" }],
+};
const data = reactive({
- searchForm: {
- customerName: "",
- projectName: "",
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
+ searchForm: {
+ productCategory: "",
+ registerDate: null, // 褰曞叆鏃ユ湡
+ entryDateStart: undefined,
+ entryDateEnd: undefined,
+ },
});
const { searchForm } = toRefs(data);
+
+const openDialog = (mode, row = null) => {
+ dialogMode.value = mode;
+ if (mode === 'create') {
+ dialogTitle.value = "鏂板鐢熶骇璁㈠崟";
+ resetForm();
+ } else if (mode === 'edit') {
+ dialogTitle.value = "缂栬緫鐢熶骇璁㈠崟";
+ resetForm();
+
+ console.log('缂栬緫鏁版嵁:', row);
+
+ // 濉厖缂栬緫鏁版嵁
+ form.id = row.id;
+ form.registerDate = row.registerDate;
+ form.productCategory = row.productCategory;
+ form.specificationModel = row.specificationModel;
+ form.unit = row.unit;
+ form.quantity = row.quantity;
+ }
+
+ dialogVisible.value = true;
+};
+
+const closeDialog = () => {
+ dialogVisible.value = false;
+};
+
+const resetForm = () => {
+ form.id = null;
+ form.registerDate = dayjs().format("YYYY-MM-DD");
+ form.productCategory = "";
+ form.specificationModel = "";
+ form.unit = "";
+ form.quantity = null;
+};
+
+const submitForm = () => {
+ formRef.value?.validate(async (valid) => {
+ if (!valid) return;
+ try {
+ const payload = {
+ registerDate: form.registerDate,
+ productCategory: form.productCategory,
+ specificationModel: form.specificationModel,
+ unit: form.unit,
+ quantity: form.quantity,
+ };
+
+ if (dialogMode.value === 'create') {
+ await addProductionOrder(payload);
+ proxy.$modal.msgSuccess("鏂板鎴愬姛");
+ } else if (dialogMode.value === 'edit') {
+ payload.id = form.id;
+ await updateProductionOrder(payload);
+ proxy.$modal.msgSuccess("缂栬緫鎴愬姛");
+ }
+
+ closeDialog();
+ getList();
+ } catch (err) {
+ console.error(`${dialogMode.value === 'create' ? '鏂板' : '缂栬緫'}澶辫触`, err);
+ proxy.$modal.msgError(`${dialogMode.value === 'create' ? '鏂板' : '缂栬緫'}澶辫触锛岃閲嶈瘯`);
+ }
+ });
+};
+
+// 缂栬緫鏂规硶
+const handleEdit = (row) => {
+ openDialog('edit', row);
+};
+
+// 鍒犻櫎鏂规硶
+const handleDelete = (row) => {
+ proxy.$modal.confirm(`纭畾瑕佸垹闄ょ敓浜ц鍗�"${row.orderNo}"鍚楋紵`, "鍒犻櫎纭", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(async () => {
+ try {
+ await deleteProductionOrder([row.id]);
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList(); // 鍒锋柊鍒楄〃
+ } catch (err) {
+ console.error("鍒犻櫎澶辫触", err);
+ proxy.$modal.msgError("鍒犻櫎澶辫触锛岃閲嶈瘯");
+ }
+ }).catch(() => {
+ proxy.$modal.msg("宸插彇娑堝垹闄�");
+ });
+};
+
+const getProductOptions = () => {
+ return productTreeList().then((res) => {
+ productOptions.value = convertIdToValue(res || []);
+ });
+};
+
+const convertIdToValue = (data) => {
+ return data.map((item) => {
+ const { id, children, ...rest } = item;
+ const newItem = {
+ ...rest,
+ value: id,
+ };
+ if (children && children.length > 0) {
+ newItem.children = convertIdToValue(children);
+ }
+ return newItem;
+ });
+};
+
+const findNodeById = (nodes, value) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].value === value) {
+ return nodes[i].label;
+ }
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const label = findNodeById(nodes[i].children, value);
+ if (label) return label;
+ }
+ }
+ return null;
+};
+
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1;
- getList();
+ page.value.current = 1;
+ getList();
};
const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
+ page.value.current = obj.page;
+ page.value.size = obj.limit;
+ getList();
};
const changeDaterange = (value) => {
- if (value) {
- searchForm.value.entryDateStart = value[0];
- searchForm.value.entryDateEnd = value[1];
- } else {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- }
- handleQuery();
+ if (value) {
+ searchForm.value.entryDateStart = value[0];
+ searchForm.value.entryDateEnd = value[1];
+ } else {
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ }
+ handleQuery();
};
const getList = () => {
- tableLoading.value = true;
- // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- schedulingListPage(params).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- }).catch(() => {
- tableLoading.value = false;
- })
+ tableLoading.value = true;
+ // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁鍜� total 瀛楁
+ const { total, ...pageParams } = page.value;
+ const params = { ...searchForm.value, ...pageParams };
+ params.registerDate = undefined;
+ if (params.productCategory) {
+ // 濡傛灉鏄璞$被鍨嬶紝鑾峰彇鍏秎abel锛堝悕绉帮級鑰屼笉鏄痸alue锛圛D锛�
+ if (typeof params.productCategory === "object") {
+ params.productCategory = findNodeById(productOptions.value, params.productCategory) || params.productCategory;
+ }
+ // 濡傛灉鏄疘D锛岃浆鎹负鍚嶇О
+ else if (typeof params.productCategory === "string" || typeof params.productCategory === "number") {
+ const categoryName = findNodeById(productOptions.value, params.productCategory);
+ if (categoryName) {
+ params.productCategory = categoryName;
+ }
+ }
+ }
+ schedulingListPage(params).then((res) => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+ page.value.total = res.data.total;
+ }).catch(() => {
+ tableLoading.value = false;
+ })
};
// 瀵煎嚭
const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/salesLedger/scheduling/export", {}, "鐢熶骇璁㈠崟.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ // proxy.download("/salesLedger/scheduling/export", {}, "鐢熶骇璁㈠崟.xlsx");
+ proxy.download("/productionOrder/export", {}, "鐢熶骇璁㈠崟.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
onMounted(() => {
- getList();
+ getProductOptions();
+ // 涓嶈缃粯璁ゆ棩鏈燂紝鍏ㄩ儴鏉′欢涓虹┖鍔犺浇
+ searchForm.value.registerDate = null;
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ getList();
});
</script>
diff --git a/src/views/productionManagement/productionReporting/components/formDia.vue b/src/views/productionManagement/productionReporting/components/formDia.vue
index 89f6c76..a9a8a3e 100644
--- a/src/views/productionManagement/productionReporting/components/formDia.vue
+++ b/src/views/productionManagement/productionReporting/components/formDia.vue
@@ -15,16 +15,16 @@
</el-col>
<el-col :span="12">
<el-form-item label="鏈鐢熶骇鏁伴噺锛�" prop="finishedNum">
- <el-input-number
- v-model="form.finishedNum"
- placeholder="璇疯緭鍏�"
- :min="0"
- :step="0.1"
- :precision="2"
- clearable
- style="width: 100%"
- @change="changeNum"
- />
+ <el-input-number
+ v-model="form.finishedNum"
+ placeholder="璇疯緭鍏�"
+ :min="0"
+ :step="0.1"
+ :precision="2"
+ clearable
+ style="width: 100%"
+ @change="changeNum"
+ />
</el-form-item>
</el-col>
</el-row>
@@ -36,22 +36,22 @@
</el-col>
</el-row>
<el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鐢熶骇浜猴細" prop="schedulingUserId">
- <el-select
- v-model="form.schedulingUserId"
- placeholder="閫夋嫨浜哄憳"
- style="width: 100%;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐢熶骇浜猴細" prop="schedulingUserId">
+ <el-select
+ v-model="form.schedulingUserId"
+ placeholder="閫夋嫨浜哄憳"
+ style="width: 100%;"
+ >
+ <el-option
+ v-for="user in userList"
+ :key="user.userId"
+ :label="user.nickName"
+ :value="user.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
<el-col :span="12">
<el-form-item label="鐢熶骇鏃ユ湡锛�" prop="schedulingDate">
<el-date-picker
@@ -90,14 +90,14 @@
const operationType = ref('')
const data = reactive({
form: {
- successNum: "",
- schedulingNum: "",
- finishedNum: "",
- schedulingUserId: "",
- schedulingDate: "",
+ successNum: "",
+ schedulingNum: "",
+ finishedNum: "",
+ schedulingUserId: "",
+ schedulingDate: "",
},
rules: {
- schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
+ schedulingNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
},
});
const { form, rules } = toRefs(data);
@@ -106,18 +106,18 @@
const openDialog = (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- form.value = {...row}
+ userListNoPageByTenantId().then((res) => {
+ userList.value = res.data;
+ });
+ form.value = {...row}
}
const changeNum = (value) => {
- if (value > form.value.schedulingNum) {
- form.value.finishedNum = form.value.schedulingNum;
- proxy.$modal.msgWarning('鏈鐢熶骇鏁伴噺涓嶅彲澶т簬鎺掍骇鏁伴噺')
- }
- form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum;
+ if (value > form.value.schedulingNum) {
+ form.value.finishedNum = form.value.schedulingNum;
+ proxy.$modal.msgWarning('鏈鐢熶骇鏁伴噺涓嶅彲澶т簬鎺掍骇鏁伴噺')
+ }
+ form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum;
}
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
@@ -125,12 +125,12 @@
if (valid) {
form.value.staffState = 1
if (operationType.value === "add") {
- productionReport(form.value).then(res => {
+ productionReport(form.value).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
closeDia();
})
} else {
- productionReportUpdate(form.value).then(res => {
+ productionReportUpdate(form.value).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
closeDia();
})
@@ -152,4 +152,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 996a00b..6061796 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -1,135 +1,126 @@
<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="瀹㈡埛鍚嶇О:">
- <el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- style="width: 200px;"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О:">
- <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- style="width: 200px;"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="鎺掍骇鏃ユ湡:">
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item label="鐘舵��:">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 140px" clearable>
- <el-option label="寰呯敓浜�" :value="1"></el-option>
- <el-option label="宸叉姤宸�" :value="3"></el-option>
- <el-option label="鐢熶骇涓�" :value="2"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div style="text-align: right" class="mb10">
- <el-button type="primary" @click="openForm('add')">鐢熶骇鎶ュ伐</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- :expandRowKeys="expandedRowKeys"
- @expand-change="expandChange"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="page.total"
- >
- <template #expand="{ row }">
- <el-table
- :data="expandData"
- border
- show-summary
- :summary-method="summarizeMainTable"
- v-loading="childrenLoading"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="鏈鐢熶骇鏁伴噺" prop="finishedNum" align="center" width="400">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="scope.row.finishedNum"
- :disabled="!scope.row.editType"
- :precision="2"
- placeholder="璇疯緭鍏�"
- clearable
- @change="changeNum(scope.row)"
- />
- </template>
- </el-table-column>
-<!-- <el-table-column label="寰呯敓浜ф暟閲�" prop="pendingNum" width="240" align="center"></el-table-column>-->
- <el-table-column label="鐢熶骇浜�" prop="schedulingUserId" width="400">
- <template #default="scope">
- <el-select
- v-model="scope.row.schedulingUserId"
- placeholder="閫夋嫨浜哄憳"
- :disabled="!scope.row.editType"
- style="width: 100%;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </template>
- </el-table-column>
- <el-table-column label="鐢熶骇鏃ユ湡" prop="schedulingDate" width="400">
- <template #default="scope">
- <el-date-picker
- v-model="scope.row.schedulingDate"
- type="date"
- :disabled="!scope.row.editType"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="60">
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="changeEditType(scope.row)"
- v-if="!scope.row.editType"
- >缂栬緫</el-button
- >
- <el-button
- link
- type="primary"
- size="small"
- @click="saveReceiptPayment(scope.row)"
- v-if="scope.row.editType"
- >淇濆瓨</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- </template>
- </PIMTable>
- </div>
- <form-dia ref="formDia" @close="handleQuery"></form-dia>
- </div>
+ <div class="app-container">
+ <div class="search_form">
+ <el-form :model="searchForm" :inline="true">
+ <el-form-item label="鎺掍骇鏃ユ湡:">
+ <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ </el-form-item>
+ <el-form-item label="鐘舵��:">
+ <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 140px" clearable>
+ <el-option label="寰呯敓浜�" :value="1"></el-option>
+ <el-option label="宸叉姤宸�" :value="3"></el-option>
+ <el-option label="鐢熶骇涓�" :value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="table_list">
+ <div style="text-align: right" class="mb10">
+ <el-button type="primary" @click="openForm('add')">鐢熶骇鎶ュ伐</el-button>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ :expandRowKeys="expandedRowKeys"
+ @expand-change="expandChange"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ :total="page.total"
+ >
+ <template #expand="{ row }">
+ <el-table
+ :data="expandData"
+ border
+ show-summary
+ stripe
+ :summary-method="summarizeMainTable"
+ v-loading="childrenLoading"
+ >
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="鏈鐢熶骇鏁伴噺" prop="finishedNum" align="center" width="400">
+ <template #default="scope">
+ <el-input-number :step="0.01" :min="0" style="width: 100%"
+ v-model="scope.row.finishedNum"
+ :disabled="!scope.row.editType"
+ :precision="2"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="changeNum(scope.row)"
+ />
+ </template>
+ </el-table-column>
+ <!-- <el-table-column label="寰呯敓浜ф暟閲�" prop="pendingNum" width="240" align="center"></el-table-column>-->
+ <el-table-column label="鐢熶骇浜�" prop="schedulingUserId" width="400">
+ <template #default="scope">
+ <el-select
+ v-model="scope.row.schedulingUserId"
+ placeholder="閫夋嫨浜哄憳"
+ :disabled="!scope.row.editType"
+ style="width: 100%;"
+ >
+ <el-option
+ v-for="user in userList"
+ :key="user.userId"
+ :label="user.nickName"
+ :value="user.userId"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+ <el-table-column label="鐢熶骇鏃ユ湡" prop="schedulingDate" width="400">
+ <template #default="scope">
+ <el-date-picker
+ v-model="scope.row.schedulingDate"
+ type="date"
+ :disabled="!scope.row.editType"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ clearable
+ style="width: 100%"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="60">
+ <template #default="scope">
+ <el-button
+ link
+ type="primary"
+ size="small"
+ @click="changeEditType(scope.row)"
+ v-if="!scope.row.editType"
+ :disabled="scope.row.parentStatus === 3"
+ >缂栬緫</el-button
+ >
+ <el-button
+ link
+ type="primary"
+ size="small"
+ @click="saveReceiptPayment(scope.row)"
+ v-if="scope.row.editType"
+ >淇濆瓨</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+ </template>
+ </PIMTable>
+ </div>
+ <form-dia ref="formDia" @close="handleQuery"></form-dia>
+ </div>
</template>
<script setup>
@@ -139,124 +130,107 @@
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import {
- productionReportUpdate,
- workListPage,
- workListPageById
+ productionReportUpdate,
+ workListPage,
+ workListPageById
} from "@/api/productionManagement/productionReporting.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
const data = reactive({
- searchForm: {
- staffName: "",
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
+ searchForm: {
+ staffName: "",
+ entryDate: [
+ dayjs().format("YYYY-MM-DD"),
+ dayjs().add(1, "day").format("YYYY-MM-DD"),
+ ], // 褰曞叆鏃ユ湡
+ entryDateStart: dayjs().format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
+ },
});
const { searchForm } = toRefs(data);
const expandedRowKeys = ref([]);
const expandData = ref([]);
const userList = ref([])
const tableColumn = ref([
- {
- type: "expand",
- dataType: "slot",
- slot: "expand",
- },
- {
- label: "鐘舵��",
- prop: "status",
- dataType: "tag",
- formatData: (params) => {
- if (params == 3) {
- return "宸叉姤宸�";
- } else if (params == 1) {
- return "寰呯敓浜�";
- } else {
- return '鐢熶骇涓�';
- }
- },
- formatType: (params) => {
- if (params == 3) {
- return "success";
- } else if (params == 1) {
- return "primary";
- } else {
- return 'warning';
- }
- },
- },
- {
- label: "鎺掍骇鏃ユ湡",
- prop: "schedulingDate",
- width: 120,
- },
- {
- label: "鎺掍骇浜�",
- prop: "schedulingUserName",
- },
- {
- label: "鍚堝悓鍙�",
- prop: "salesContractNo",
- width: 200,
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width: 200,
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: 200,
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:300
- },
- {
- label: "浜у搧澶х被",
- prop: "productCategory",
- width: 150,
- },
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "specificationModel",
- width: 150,
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- label: "宸ュ簭",
- prop: "process",
- },
- {
- label: "鎺掍骇鏁伴噺",
- prop: "schedulingNum",
- width: 100,
- },
- {
- label: "鐢熶骇鏁伴噺",
- prop: "finishedNum",
- width: 100,
- },
- {
- label: "寰呯敓浜ф暟閲�",
- prop: "pendingFinishNum",
- width: 100,
- },
+ {
+ type: "expand",
+ dataType: "slot",
+ slot: "expand",
+ },
+ {
+ label: "鐘舵��",
+ prop: "status",
+ dataType: "tag",
+ formatData: (params) => {
+ if (params == 3) {
+ return "宸叉姤宸�";
+ } else if (params == 1) {
+ return "寰呯敓浜�";
+ } else {
+ return '鐢熶骇涓�';
+ }
+ },
+ formatType: (params) => {
+ if (params == 3) {
+ return "success";
+ } else if (params == 1) {
+ return "primary";
+ } else {
+ return 'warning';
+ }
+ },
+ },
+ {
+ label: "鎺掍骇鏃ユ湡",
+ prop: "schedulingDate",
+ width: 120,
+ },
+ {
+ label: "鎺掍骇浜�",
+ prop: "schedulingUserName",
+ },
+ {
+ label: "浜у搧澶х被",
+ prop: "productCategory",
+ width: 150,
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "specificationModel",
+ width: 150,
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "宸ュ簭",
+ prop: "process",
+ },
+ {
+ label: "鎺掍骇鏁伴噺",
+ prop: "schedulingNum",
+ width: 100,
+ },
+ {
+ label: "鐢熶骇鏁伴噺",
+ prop: "finishedNum",
+ width: 100,
+ },
+ {
+ label: "寰呯敓浜ф暟閲�",
+ prop: "pendingFinishNum",
+ width: 100,
+ },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const childrenLoading = ref(false);
const page = reactive({
- current: 1,
- size: 100,
- total: 0,
+ current: 1,
+ size: 100,
+ total: 0,
});
const formDia = ref()
const { proxy } = getCurrentInstance()
@@ -264,163 +238,163 @@
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
- page.current = 1;
- getList();
+ page.current = 1;
+ getList();
};
const changeDaterange = (value) => {
- if (value) {
- searchForm.value.entryDateStart = value[0];
- searchForm.value.entryDateEnd = value[1];
- } else {
- searchForm.value.entryDateStart = undefined;
- searchForm.value.entryDateEnd = undefined;
- }
- handleQuery();
+ if (value) {
+ searchForm.value.entryDateStart = value[0];
+ searchForm.value.entryDateEnd = value[1];
+ } else {
+ searchForm.value.entryDateStart = undefined;
+ searchForm.value.entryDateEnd = undefined;
+ }
+ handleQuery();
};
const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
};
const getList = () => {
- tableLoading.value = true;
- const params = { ...searchForm.value, ...page };
- params.entryDate = undefined
- expandedRowKeys.value = []
- workListPage(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records.map(item => ({
- ...item,
- pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
- }));
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
+ tableLoading.value = true;
+ const params = { ...searchForm.value, ...page };
+ params.entryDate = undefined
+ expandedRowKeys.value = []
+ workListPage(params).then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records.map(item => ({
+ ...item,
+ pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
+ }));
+ page.total = res.data.total;
+ }).catch(err => {
+ tableLoading.value = false;
+ })
};
// 灞曞紑琛�
const expandChange = (row, expandedRows) => {
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- if (expandedRows.length > 0) {
- nextTick(() => {
- expandedRowKeys.value = [];
- try {
- childrenLoading.value = true;
- workListPageById({ id: row.id }).then((res) => {
- childrenLoading.value = false;
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- expandData.value = res.data.map(item => ({
- ...item,
- pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0),
- parentStatus: row.status // 鏂板鐖惰〃鐘舵��
- }));
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- childrenLoading.value = false;
- console.log(error);
- }
- })
- } else {
- expandedRowKeys.value = [];
- }
+ userListNoPageByTenantId().then((res) => {
+ userList.value = res.data;
+ });
+ if (expandedRows.length > 0) {
+ nextTick(() => {
+ expandedRowKeys.value = [];
+ try {
+ childrenLoading.value = true;
+ workListPageById({ id: row.id }).then((res) => {
+ childrenLoading.value = false;
+ const index = tableData.value.findIndex((item) => item.id === row.id);
+ if (index > -1) {
+ expandData.value = res.data.map(item => ({
+ ...item,
+ pendingNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0),
+ parentStatus: row.status // 鏂板鐖惰〃鐘舵��
+ }));
+ }
+ expandedRowKeys.value.push(row.id);
+ });
+ } catch (error) {
+ childrenLoading.value = false;
+ console.log(error);
+ }
+ })
+ } else {
+ expandedRowKeys.value = [];
+ }
};
const changeNum = (row) => {
- // 鎵惧埌鐖惰〃鏍兼暟鎹�
- const parentRow = tableData.value.find(item => item.id === expandedRowKeys.value[0]);
- // 璁$畻鎵�鏈夊瓙琛ㄦ牸 finishedNum 鐨勬�诲拰
- const totalFinishedNum = expandData.value.reduce((sum, item) => sum + (Number(item.finishedNum) || 0), 0);
- // 鐖惰〃鏍肩殑鎺掍骇鏁伴噺
- const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0;
-
- if (totalFinishedNum > schedulingNum) {
- // 鍥為��鏈杈撳叆
- row.finishedNum = schedulingNum - (totalFinishedNum - Number(row.finishedNum));
- proxy.$modal.msgWarning('鎵�鏈夋湰娆$敓浜ф暟閲忎箣鍜屼笉鍙ぇ浜庢帓浜ф暟閲�');
- }
- row.pendingNum = row.schedulingNum - row.finishedNum;
+ // 鎵惧埌鐖惰〃鏍兼暟鎹�
+ const parentRow = tableData.value.find(item => item.id === expandedRowKeys.value[0]);
+ // 璁$畻鎵�鏈夊瓙琛ㄦ牸 finishedNum 鐨勬�诲拰
+ const totalFinishedNum = expandData.value.reduce((sum, item) => sum + (Number(item.finishedNum) || 0), 0);
+ // 鐖惰〃鏍肩殑鎺掍骇鏁伴噺
+ const schedulingNum = parentRow ? Number(parentRow.schedulingNum) : 0;
+
+ if (totalFinishedNum > schedulingNum) {
+ // 鍥為��鏈杈撳叆
+ row.finishedNum = schedulingNum - (totalFinishedNum - Number(row.finishedNum));
+ proxy.$modal.msgWarning('鎵�鏈夋湰娆$敓浜ф暟閲忎箣鍜屼笉鍙ぇ浜庢帓浜ф暟閲�');
+ }
+ row.pendingNum = row.schedulingNum - row.finishedNum;
}
// 缂栬緫淇敼鐘舵��
const changeEditType = (row) => {
- row.editType = !row.editType;
+ row.editType = !row.editType;
};
// 淇濆瓨璁板綍
const saveReceiptPayment = (row) => {
- productionReportUpdate(row).then((res) => {
- row.editType = !row.editType;
- getList();
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- });
+ productionReportUpdate(row).then((res) => {
+ row.editType = !row.editType;
+ getList();
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ });
};
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
+ selectedRows.value = selection;
};
const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, [
- "finishedNum"
- ]);
+ return proxy.summarizeTable(param, [
+ "finishedNum"
+ ]);
};
// 鎵撳紑寮规
const openForm = (type, row) => {
- if (selectedRows.value.length !== 1) {
- proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
- return;
- }
- if (selectedRows.value[0].pendingFinishNum == 0) {
- proxy.$message.warning("鏃犻渶鍐嶆姤宸�");
- return;
- }
- nextTick(() => {
- const rowInfo = type === 'add' ? selectedRows.value[0] : row
- formDia.value?.openDialog(type, rowInfo)
- })
+ if (selectedRows.value.length !== 1) {
+ proxy.$message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
+ return;
+ }
+ if (selectedRows.value[0].pendingFinishNum == 0) {
+ proxy.$message.warning("鏃犻渶鍐嶆姤宸�");
+ return;
+ }
+ nextTick(() => {
+ const rowInfo = type === 'add' ? selectedRows.value[0] : row
+ formDia.value?.openDialog(type, rowInfo)
+ })
};
// 鍒犻櫎
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("宸插彇娑�");
- });
+ 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("/salesLedger/work/export", {}, "鐢熶骇鎶ュ伐.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
onMounted(() => {
- getList();
+ getList();
});
</script>
diff --git a/src/views/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
deleted file mode 100644
index 9848898..0000000
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ /dev/null
@@ -1,1493 +0,0 @@
-<template>
- <div class="data-dashboard">
- <!-- 鍏ㄥ睆鎸夐挳 - 绉诲姩鍒板乏涓婅 -->
- <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '閫�鍑哄叏灞�' : '鍏ㄥ睆鏄剧ず'">
- <svg v-if="!isFullscreen" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"/>
- </svg>
- <svg v-else width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/>
- </svg>
- </button>
-
- <!-- 椤堕儴鏍囬鏍� -->
- <div class="dashboard-header">
- <div class="factory-name">{{ userStore.currentFactoryName }}</div>
- </div>
-
- <!-- 涓昏鍐呭鍖哄煙 -->
- <div class="dashboard-content">
- <!-- 宸︿晶鍖哄煙 -->
- <div class="left-panel">
- <!-- 瀹㈡埛淇℃伅缁熻鍒嗘瀽 -->
- <div class="panel-header">
- <span class="panel-title">瀹㈡埛淇℃伅缁熻鍒嗘瀽</span>
- </div>
- <div class="panel-item-customers">
- <div class="panel-title-second">
- <div class="panel-title-icon"></div>
- <div class="total-customers">
- <span class="label">鎬诲悎鍚岄噾棰�(鍏�)</span>
- <span class="value">{{sum}}</span>
- </div>
-<!-- <div class="jiantou"></div>-->
- </div>
- <!-- 楗煎浘鍖哄煙 -->
- <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px">
- <div style="width: 240px; height: 240px; background-image: url('/src/assets/BI/zonghetongbingtubiankuang@2x.png'); background-size: contain; background-position: center; background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;">
- <Echarts ref="chart" :legend="pieLegend" :chartStyle="chartStylePie"
- :series="materialPieSeries"
- :tooltip="pieTooltip"
- :options="{backgroundColor: 'transparent'}"
- style="margin-left: 5px;"></Echarts>
- </div>
- <ul class="contract-list" style="margin: 0; padding: 0; display: flex; flex-direction: column;justify-content: space-around; height: 100%; overflow-y: auto; scroll-behavior: smooth;" ref="refContractList">
- <li v-for="item in materialPieSeries[0].data" :key="item.name" style="list-style: none; margin-bottom: 12px;">
- <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="font-weight: 700;font-size: 16px;color: #85B1E4;">锟{item.value}}</div>
- </div>
- </li>
- </ul>
- </div>
- </div>
-
- <!-- 璐ㄩ噺缁熻 -->
- <div class="panel-header">
- <span class="panel-title">璐ㄩ噺缁熻</span>
- </div>
- <div class="main-panel">
- <div class="panel-item-customers">
- <div class="quality-cards">
- <div class="quality-cardSec">
- <div class="quality-card one"></div>
- <div class="quality-cardTitle">
- <div>鍘熸潗鏂欏凡妫�娴嬫暟</div>
- <div>{{qualityStatisticsObject.supplierNum}}浠�</div>
- </div>
- </div>
- <div class="quality-cardSec">
- <div class="quality-card two"></div>
- <div class="quality-cardTitle">
- <div>杩囩▼妫�楠屾暟閲�</div>
- <div>{{qualityStatisticsObject.processNum}}浠�</div>
- </div>
- </div>
- <div class="quality-cardSec">
- <div class="quality-card three"></div>
- <div class="quality-cardTitle">
- <div>鍑哄巶宸叉鏁伴噺</div>
- <div>{{qualityStatisticsObject.factoryNum}}浠�</div>
- </div>
- </div>
- </div>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="barLegend"
- :series="barSeries1"
- :tooltip="tooltip"
- :xAxis="xAxis1"
- :yAxis="yAxis1"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 260px"></Echarts>
- </div>
- </div>
- </div>
-
- <!-- 涓棿鍖哄煙 -->
- <div class="center-panel">
- <!-- 椤堕儴缁熻鍗$墖 -->
- <div class="stats-cards">
- <div class="stat-card">
- <img src="@/assets/BI/icon@2x.png" alt="鍥炬爣" class="card-icon" />
- <div class="card-content">
- <span class="card-label">鍛樺伐鎬绘暟</span>
- <span class="card-value">{{totalStaff}}</span>
- </div>
- </div>
- <div class="stat-card">
- <img src="@/assets/BI/icon@2x.png" alt="鍥炬爣" class="card-icon" />
- <div class="card-content">
- <span class="card-label">瀹㈡埛鎬绘暟</span>
- <span class="card-value">{{totalCustomers}}</span>
- </div>
- </div>
- <div class="stat-card">
- <img src="@/assets/BI/icon@2x.png" alt="鍥炬爣" class="card-icon" />
- <div class="card-content">
- <span class="card-label">渚涘簲鍟嗘�绘暟</span>
- <span class="card-value">{{totalSuppliers}}</span>
- </div>
- </div>
- </div>
-
- <!-- 璁惧缁熻 -->
- <div class="equipment-stats">
- <div class="equipment-header">
- <img src="@/assets/BI/shujutongjiicon@2x.png" alt="鍥炬爣" class="equipment-icon" />
- <span class="equipment-title">璁惧缁熻</span>
- </div>
- <div class="equipment-items">
- <div class="equipment-item">
- <span class="equipment-value">{{equipmentNum}}</span>
- <span class="equipment-label">璁惧鎬绘暟</span>
- </div>
- <div class="equipment-item">
- <span class="equipment-value">{{equipmentRepair}}</span>
- <span class="equipment-label">寰呯淮淇澶�</span>
- </div>
- <div class="equipment-item">
- <span class="equipment-value">{{equipmentMaintain}}</span>
- <span class="equipment-label">寰呬繚鍏昏澶�</span>
- </div>
- <div class="equipment-item">
- <span class="equipment-value">{{totalMeasuring}}</span>
- <span class="equipment-label">璁¢噺鍣ㄥ叿鎬绘暟</span>
- </div>
- </div>
- </div>
-
- <!-- 浜嬩欢鍚嶇О -->
- <div class="event-info">
- <div class="event-header">
- <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
- <span class="event-title">浜嬩欢鍚嶇О</span>
- </div>
- <div class="event-content">
- <ul class="todo-list" v-if="todoList.length > 0" ref="refTodoList">
- <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="financial-header">
- <span class="financial-title">璐㈠姟鍒嗘瀽</span>
- </div>
- <div class="main-panel">
- <div class="panel-item-customers">
- <div class="event-header">
- <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="鍥炬爣" class="event-icon" />
- <span class="event-title">缁忚惀鎴愭灉鍒嗘瀽</span>
- </div>
- <Echarts ref="chart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="barLegend1"
- :series="barSeries11"
- :tooltip="tooltip"
- :xAxis="xAxis3"
- :yAxis="yAxis3"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 300px"></Echarts>
- </div>
- </div>
- </div>
-
- <!-- 鍙充晶鍖哄煙 -->
- <div class="right-panel">
- <!-- 搴旀敹搴斾粯缁熻 -->
- <div class="panel-header">
- <span class="panel-title">搴旀敹搴斾粯缁熻</span>
- </div>
- <div class="panel-item-customers">
- <div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
- <div class="section-title">搴旀敹搴斾粯缁熻</div>
- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group">
- <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"
- :legend="barLegend2"
- :series="barSeries"
- :tooltip="tooltip"
- :xAxis="xAxis"
- :yAxis="yAxis"
- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"
- style="height: 260px"></Echarts>
- </div>
-
- <!-- 鍥炴涓庡紑绁ㄥ垎鏋� -->
- <div class="panel-header">
- <span class="panel-title">鍥炴涓庡紑绁ㄥ垎鏋�</span>
- </div>
- <div class="panel-item-customers" style="padding-top: 60px;">
- <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries"
- :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" :options="{backgroundColor: 'transparent', textStyle: {color: '#FFFFFF'}}" style="height: 270px;"></Echarts>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import * as echarts from 'echarts'
-import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
-import autofit from 'autofit.js'
-import Echarts from "@/components/Echarts/echarts.vue";
-import useUserStore from '@/store/modules/user'
-import {
- analysisCustomerContractAmounts, getAmountHalfYear,
- homeTodos,
- qualityStatistics,
- statisticsReceivablePayable
-} from "@/api/viewIndex.js";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
-import {listCustomer} from "@/api/basicData/customerFile.js";
-import {listSupplier} from "@/api/basicData/supplierManageFile.js";
-import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
-import {getRepairPage} from "@/api/equipmentManagement/repair.js";
-import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js";
-import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js";
-import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js";
-
-// 鍏ㄥ睆鐩稿叧鐘舵��
-const isFullscreen = ref(false);
-
-// 鐢ㄦ埛store
-const userStore = useUserStore()
-
-// 鍝嶅簲寮忔暟鎹�
-const currentTime = ref('')
-const currentDate = ref('')
-const timer = ref(null)
-const charts = ref([])
-
-// 鍥捐〃寮曠敤
-const customerPieChartRef = ref(null)
-const salesBarChartRef = ref(null)
-const dataBarChartRef = ref(null)
-const financialAreaChartRef = ref(null)
-const realtimeLineChartRef = ref(null)
-const refContractList = ref(null)
-const refTodoList = ref(null)
-const timerScroll = ref(null)
-
-const chartStylePie = {
- width: '140%',
- height: '140%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-}
-const materialPieSeries = ref([
- {
- type: 'pie',
- radius: ['0%', '90%'],
- avoidLabelOverlap: false,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 0
- },
- label: {
- show: false
- },
- data: []
- }
-])
-const pieLegend = reactive({
- show: false,
-})
-const sum = ref(0)
-const totalStaff = ref(0)
-const totalCustomers = ref(0)
-const totalSuppliers = ref(0)
-const yny = ref(0)
-const chain = ref(0)
-const equipmentNum = ref(0)
-const equipmentRepair = ref(0)
-const equipmentMaintain = ref(0)
-const totalMeasuring = ref(0)
-const pieTooltip = reactive({
- trigger: 'item',
- formatter: function (params) {
- // 鍔ㄦ�佺敓鎴愭彁绀轰俊鎭紝鍩轰簬鏁版嵁椤圭殑 name 灞炴��
- const description = params.name === '鏈湀鍥炴閲戦' ? '鏈湀鍥炴閲戦' : '搴旀敹娆鹃噾棰�';
- return `<div style="color: #B8C8E0">${description} ${params.value}鍏� ${params.percent}%</div>`;
- },
- position: 'right'
-})
-
-const qualityStatisticsObject = ref({
- supplierNum: 0,
- processNum: 0,
- factoryNum: 0,
-})
-const chartStyle = {
- width: '100%',
- height: '150%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-}
-const barSeries = ref([
- {
- name: '搴斾粯閲戦',
- type: 'bar',
- data: [],
- label: {
- show: true,
- },
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#00A4ED' },
- { offset: 1, color: '#4EE4FF' }
- ])
- }
- },
- {
- name: '搴旀敹閲戦',
- type: 'bar',
- data: [],
- label: {
- show: true,
- },
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#537EF5' },
- { offset: 1, color: '#9061F8' }
- ])
- }
- }
-])
-const radio1 = ref(1)
-const barColors2 = ['#5181DB', '#D369E0', '#F2CA6D', '#60CCA8']
-const grid = {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
-}
-const lineLegend = {
- show: true,
- textStyle: { color: '#B8C8E0' },
- data: ['寮�绁�', '鍥炴']
-}
-const lineSeries = ref([
- {
- type: 'line',
- data: [],
- label: {
- show: true
- },
- showSymbol: true, // 鏄剧ず鍦嗙偣
- },
-])
-const tooltipLine = {
- trigger: 'axis',
-}
-const yAxis2 = ref([
- {
- type: 'value',
- }
-])
-const xAxis2 = ref([
- {
- type: 'category',
- data: [],
- axisLabel: {
- interval: 0,
- formatter: function(value) {
- return value.replace(/~/g, '\n');
- },
- }
- }
-])
-const barLegend2 = {
- show: true,
- textStyle: { color: '#B8C8E0' },
- data: ['搴斾粯閲戦', '搴旀敹閲戦']
-}
-const barLegend = {
- show: true,
- textStyle: { color: '#B8C8E0' },
- data: ['鍘熸潗鏂欎笉鍚堟牸鏁�', '杩囩▼涓嶅悎鏍兼暟', '鍑哄巶涓嶅悎鏍兼暟']
-}
-const barLegend1 = {
- show: true,
- textStyle: { color: '#B8C8E0' },
- data: ['鎬绘敹鍏�', '鎬绘敮鍑�', '鍑�鏀跺叆']
-}
-const barSeries11 = ref([
- {
- name: '鎬绘敹鍏�',
- type: 'bar',
- barGap: 0,
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#00A4ED' },
- { offset: 0, color: '#4EE4FF' }
- ]
- }
- },
- data: []
- },
- {
- name: '鎬绘敮鍑�',
- type: 'bar',
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#3378FF' },
- { offset: 0, color: '#4E8AFF' }
- ]
- }
- },
- data: []
- },
- {
- name: '鍑�鏀跺叆',
- type: 'bar',
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#537EF5' },
- { offset: 0, color: '#9061F8' }
- ]
- }
- },
- data: []
- },
-])
-const barSeries1 = ref([
- {
- name: '鍘熸潗鏂欎笉鍚堟牸鏁�',
- type: 'bar',
- barGap: 0,
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#00A4ED' },
- { offset: 0, color: '#4EE4FF' }
- ]
- }
- },
- data: []
- },
- {
- name: '杩囩▼涓嶅悎鏍兼暟',
- type: 'bar',
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#3378FF' },
- { offset: 0, color: '#4E8AFF' }
- ]
- }
- },
- data: []
- },
- {
- name: '鍑哄巶涓嶅悎鏍兼暟',
- type: 'bar',
- emphasis: {
- focus: 'series'
- },
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- { offset: 1, color: '#537EF5' },
- { offset: 0, color: '#9061F8' }
- ]
- }
- },
- data: []
- },
-])
-const tooltip = {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- },
- formatter: function (params) {
- let result = params[0].axisValueLabel + '<br/>';
- params.forEach(item => {
- result += `<div style="color: #B8C8E0">${item.marker} ${item.seriesName}: ${item.value}</div>`;
- });
- return result;
- }
-}
-const xAxis = [{
- type: 'value',
-}]
-const yAxis = [{
- type: 'category',
- data: ['搴旀敹搴斾粯缁熻']
-}]
-const xAxis1 = ref([{
- type: 'category',
- axisTick: { show: false },
- axisLabel: { color: '#B8C8E0' },
- data: []
-}])
-const yAxis1 = [{
- type: 'value',
- axisLabel: { color: '#B8C8E0' }
-}]
-const xAxis3 = ref([{
- type: 'category',
- axisTick: { show: false },
- axisLabel: { color: '#B8C8E0' },
- data: []
-}])
-const yAxis3 = [{
- type: 'value',
- axisLabel: { color: '#B8C8E0' }
-}]
-
-// 寰呭姙浜嬮」
-const todoList = ref([])
-
-// 绐楀彛澶у皬鍙樺寲澶勭悊
-const handleResize = () => {
- charts.value.forEach(chart => {
- if (chart && chart.resize) {
- chart.resize()
- }
- })
-}
-
-// 閿�姣佸浘琛ㄥ疄渚�
-const disposeCharts = () => {
- charts.value.forEach(chart => {
- if (chart && chart.dispose) {
- chart.dispose()
- }
- })
- charts.value = []
-}
-// 鍚堝悓閲戦
-const analysisCustomer = () => {
- analysisCustomerContractAmounts().then((res) => {
- sum.value = res.data.sum
- yny.value = res.data.yny
- chain.value = res.data.chain
- // 涓烘瘡涓暟鎹」鍒嗛厤闅忔満棰滆壊
- materialPieSeries.value[0].data = res.data.item.map(item => ({
- ...item,
- itemStyle: { color: getRandomColor() }
- }))
- })
-}
-// 璐ㄦ缁熻
-const qualityStatisticsInfo = () => {
- qualityStatistics().then((res) => {
- res.data.item.forEach(item => {
- xAxis1.value[0].data.push(item.date)
- barSeries1.value[0].data.push(item.supplierNum)
- barSeries1.value[1].data.push(item.processNum)
- barSeries1.value[2].data.push(item.factoryNum)
- })
- qualityStatisticsObject.value.supplierNum = res.data.supplierNum
- qualityStatisticsObject.value.processNum = res.data.processNum
- qualityStatisticsObject.value.factoryNum = res.data.factoryNum
- })
-}
-// 璐㈠姟缁熻
-const accountStatisticsInfo = () => {
- listPageAnalysis().then((res) => {
- xAxis3.value[0].data = res.data.days
- barSeries11.value[0].data = res.data.totalIncome
- barSeries11.value[1].data = res.data.totalExpense
- barSeries11.value[2].data = res.data.netIncome
- })
-}
-const getNum = () => {
- const params = {
- pageNum: -1,
- pageSize: -1,
- }
- staffOnJobListPage({...params, staffState: 1}).then(res => {
- totalStaff.value = res.data.total
- })
- listCustomer(params).then((res) => {
- totalCustomers.value = res.total;
- });
- listSupplier(params).then((res) => {
- totalSuppliers.value = res.data.total
- });
-}
-const getLedgerNum = () => {
- const params = {
- pageNum: -1,
- pageSize: -1,
- }
- getLedgerPage(params).then((res) => {
- equipmentNum.value = res.data.total
- });
- getRepairPage(params).then((res) => {
- equipmentRepair.value = res.data.total
- });
- getUpkeepPage(params).then((res) => {
- equipmentMaintain.value = res.data.total
- });
- measuringInstrumentListPage(params).then((res) => {
- totalMeasuring.value = res.data.total
- });
-}
-// 寰呭姙浜嬮」
-const todoInfoS = () => {
- homeTodos().then((res) => {
- todoList.value = res.data
- // 鍦ㄨ幏鍙栧埌寰呭姙浜嬮」鏁版嵁鍚庯紝鍒濆鍖栨粴鍔ㄥ姛鑳�
- nextTick(() => {
- initTodoListScroll()
- })
- })
-}
-// 搴斾粯搴旀敹缁熻
-const statisticsReceivable = (type) => {
- statisticsReceivablePayable({type: radio1.value}).then((res) => {
- // 璁剧疆搴斾粯閲戦鏁版嵁
- barSeries.value[0].data = [
- { value: res.data.payableMoney }
- ]
- // 璁剧疆搴旀敹閲戦鏁版嵁
- barSeries.value[1].data = [
- { value: res.data.receivableMoney }
- ]
- })
-}
-const getAmountHalfYearNum = async () => {
- const res = await getAmountHalfYear()
- console.log(res)
- const monthName = []
- const receiptAmount = []
- const invoiceAmount = []
- res.data.forEach(item => {
- monthName.push(item.month)
- receiptAmount.push(item.receiptAmount)
- invoiceAmount.push(item.invoiceAmount)
- })
- // 姝g‘鍝嶅簲寮忚祴鍊硷細鍒涘缓鏂扮殑 xAxis 鍜� series 瀵硅薄
- xAxis2.value[0].data = monthName
- xAxis2.value[0].data = monthName.map(item => item.replace(/~/g, '\n~'));
- lineSeries.value = [
- {
- name: '寮�绁�',
- type: 'line',
- data: receiptAmount,
- stack: 'Total',
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- {
- offset: 0,
- color: 'rgba(131, 207, 255, 1)'
- },
- {
- offset: 1,
- color: 'rgba(186, 228, 255, 1)'
- }
- ])
- },
- itemStyle: {
- color: '#2D99FF',
- borderColor: '#2D99FF'
- },
- emphasis: {
- focus: 'series'
- },
- lineStyle: {
- width: 0
- },
- showSymbol: true,
- },
- {
- name: '鍥炴',
- type: 'line',
- data: invoiceAmount,
- stack: 'Total',
- lineStyle: {
- width: 0
- },
- itemStyle: {
- color: '#83CFFF',
- borderColor: '#83CFFF'
- },
- showSymbol: true,
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- {
- offset: 0,
- color: 'rgba(54, 153, 255, 1)'
- },
- {
- offset: 1,
- color: 'rgba(89, 169, 254, 1)'
- }
- ])
- },
- emphasis: {
- focus: 'series'
- },
- }
- ]
-}
-
-// 鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
-const autoSwitchTimer = ref(null)
-// 鍒濆鍖栧緟鍔炰簨椤瑰垪琛ㄦ粴鍔ㄥ姛鑳�
-const initTodoListScroll = () => {
- const todoList = refTodoList.value
- // 寮哄埗鍚敤婊氬姩锛屼笉妫�鏌ヤ换浣曟潯浠�
- if (todoList) {
- // 鍒涘缓涓�涓厠闅嗛」锛岀敤浜庡疄鐜版棤缂濇粴鍔�
- const scrollItems = Array.from(todoList.querySelectorAll('li'))
- if (scrollItems.length > 0) {
- // 纭繚鏈夎冻澶熺殑椤圭洰鐢ㄤ簬婊氬姩
- // 濡傛灉椤圭洰澶皯锛屽澶嶅埗鍑犳浠ョ‘淇濇粴鍔ㄦ晥鏋�
- if (scrollItems.length < 4) {
- const originalItems = [...scrollItems]
- for (let i = 0; i < 4; i++) {
- originalItems.forEach(item => {
- const clone = item.cloneNode(true)
- todoList.appendChild(clone)
- })
- }
- // 閲嶆柊鑾峰彇鎵�鏈夐」鐩�
- scrollItems.push(...Array.from(todoList.querySelectorAll('li')).slice(scrollItems.length));
- }
- const itemHeight = scrollItems[0]?.offsetHeight || 0
- const containerHeight = todoList.clientHeight
- const cloneCount = Math.ceil(containerHeight / itemHeight) + 2
-
- // 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
- for (let i = 0; i < cloneCount; i++) {
- const clone = scrollItems[i % scrollItems.length].cloneNode(true)
- todoList.appendChild(clone)
- }
-
- let scrollPosition = 0
- const scrollSpeed = 1.5 // 澧炲姞婊氬姩閫熷害锛屼娇婊氬姩鏇村姞鏄庢樉
- const pauseTime = 3000 // 婊氬姩鏆傚仠鏃堕棿
- let isPaused = false
- let lastTimestamp = 0
-
- // 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
- function scrollAnimation(timestamp) {
- if (!lastTimestamp) lastTimestamp = timestamp
- const deltaTime = timestamp - lastTimestamp
- lastTimestamp = timestamp
-
- if (!isPaused) {
- scrollPosition += scrollSpeed * (deltaTime / 16) // 鏍囧噯鍖栦负60fps鐨勯�熷害
-
- // 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
- const maxScroll = Math.max(todoList.scrollHeight - containerHeight - cloneCount * itemHeight, itemHeight * scrollItems.length)
- if (scrollPosition >= maxScroll) {
- scrollPosition = 0
- todoList.scrollTop = 0
- } else {
- todoList.scrollTop = scrollPosition
- }
- }
-
- todoList._animationFrame = requestAnimationFrame(scrollAnimation)
- }
-
- // 鍚姩婊氬姩鍔ㄧ敾
- todoList._animationFrame = requestAnimationFrame(scrollAnimation)
-
- // 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
- const pauseTimer = setInterval(() => {
- isPaused = !isPaused
- }, pauseTime)
-
- // 娓呯悊瀹氭椂鍣�
- todoList._pauseTimer = pauseTimer
- }
- }
-}
-const getRandomColor = () => {
- // 鐢熸垚娴呰壊锛歊銆丟銆丅 鍒嗛噺閮藉湪 150-255 涔嬮棿
- const r = Math.floor(Math.random() * 106) + 150; // 150-255
- const g = Math.floor(Math.random() * 106) + 150; // 150-255
- const b = Math.floor(Math.random() * 106) + 150; // 150-255
- // 灏� RGB 杞崲涓哄崄鍏繘鍒堕鑹�
- return '#' + r.toString(16).padStart(2, '0') + g.toString(16).padStart(2, '0') + b.toString(16).padStart(2, '0');
-}
-
-// 鏇存柊鏃堕棿
-const updateTime = () => {
- const now = new Date()
- currentTime.value = now.toLocaleTimeString('zh-CN', { hour12: false })
- currentDate.value = now.toLocaleDateString('zh-CN', {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- weekday: 'long'
- })
-}
-
-// 鍒濆鍖栨椂闂�
-const initTime = () => {
- updateTime()
- timer.value = setInterval(updateTime, 1000)
-}
-// 鍏ㄥ睆鍔熻兘瀹炵幇 - 閽堝data-dashboard鍏冪礌
-const toggleFullscreen = () => {
- const element = document.querySelector('.data-dashboard')
-
- if (!element) return
-
- if (!isFullscreen.value) {
- if (element.requestFullscreen) {
- element.requestFullscreen()
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen()
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen()
- }
- } else {
- if (document.exitFullscreen) {
- document.exitFullscreen()
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen()
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen()
- }
- }
-}
-
-// 鐩戝惉鍏ㄥ睆鍙樺寲浜嬩欢
-const handleFullscreenChange = () => {
- const fullscreenElement = document.fullscreenElement ||
- document.webkitFullscreenElement ||
- document.msFullscreenElement
- isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('data-dashboard')
-}
-
-// 鐢熷懡鍛ㄦ湡閽╁瓙
-onMounted(() => {
- initTime()
- // 浣跨敤nextTick纭繚DOM瀹屽叏娓叉煋鍚庡啀鍒濆鍖栧浘琛�
- nextTick(() => {
- // 鍒濆鍖朼utofit鑷�傚簲
- autofit.init({ dh: 1080, dw: 1920, el: '.data-dashboard', resize: true }, false)
-
- // 娣诲姞鑷姩婊氬姩鍔ㄧ敾鏁堟灉 - 瀹㈡埛淇℃伅鍒楄〃
- const contractList = refContractList.value
- if (contractList && contractList.scrollHeight > contractList.clientHeight) {
- // 鍒涘缓涓�涓厠闅嗛」锛岀敤浜庡疄鐜版棤缂濇粴鍔�
- const scrollItems = Array.from(contractList.querySelectorAll('li'))
- const itemHeight = scrollItems[0]?.offsetHeight || 0
- const containerHeight = contractList.clientHeight
- const cloneCount = Math.ceil(containerHeight / itemHeight) + 2
-
- // 鍏嬮殕鍓嶅嚑涓」鐩苟娣诲姞鍒板垪琛ㄦ湯灏撅紝瀹炵幇鏃犵紳婊氬姩
- for (let i = 0; i < cloneCount; i++) {
- const clone = scrollItems[i % scrollItems.length].cloneNode(true)
- contractList.appendChild(clone)
- }
-
- let scrollPosition = 0
- const scrollSpeed = 1.5 // 澧炲姞婊氬姩閫熷害锛屼娇婊氬姩鏇村姞鏄庢樉
- const pauseTime = 3000 // 婊氬姩鏆傚仠鏃堕棿
- let isPaused = false
- let lastTimestamp = 0
-
- // 杩炵画婊氬姩鍔ㄧ敾鍑芥暟
- function scrollAnimation(timestamp) {
- if (!lastTimestamp) lastTimestamp = timestamp
- const deltaTime = timestamp - lastTimestamp
- lastTimestamp = timestamp
-
- if (!isPaused) {
- scrollPosition += scrollSpeed * (deltaTime / 16) // 鏍囧噯鍖栦负60fps鐨勯�熷害
-
- // 褰撴粴鍔ㄨ秴杩囧師濮嬪唴瀹归暱搴︽椂锛岄噸缃綅缃疄鐜版棤缂濇粴鍔�
- if (scrollPosition >= contractList.scrollHeight - containerHeight - cloneCount * itemHeight) {
- scrollPosition = 0
- contractList.scrollTop = 0
- } else {
- contractList.scrollTop = scrollPosition
- }
- }
-
- timerScroll.value = requestAnimationFrame(scrollAnimation)
- }
-
- // 鍚姩婊氬姩鍔ㄧ敾
- timerScroll.value = requestAnimationFrame(scrollAnimation)
-
- // 璁剧疆婊氬姩-鏆傚仠-婊氬姩鐨勫惊鐜晥鏋�
- const pauseTimer = setInterval(() => {
- isPaused = !isPaused
- }, pauseTime)
-
- // 娓呯悊瀹氭椂鍣�
- contractList._pauseTimer = pauseTimer
- }
-
- // 寰呭姙浜嬮」鍒楄〃婊氬姩鍔熻兘宸茬Щ鑷硉odoInfoS鍑芥暟涓紝鍦ㄨ幏鍙栨暟鎹悗鍒濆鍖�
- })
-
- window.addEventListener('resize', handleResize)
- analysisCustomer()
- qualityStatisticsInfo()
- accountStatisticsInfo()
- getNum()
- getLedgerNum()
- todoInfoS()
- statisticsReceivable()
- getAmountHalfYearNum()
-
- // 璁剧疆鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣紝姣�10绉掑垏鎹竴娆�
- autoSwitchTimer.value = setInterval(() => {
- // 寰幆鍒囨崲锛�1(鍛�) -> 2(鏈�) -> 3(瀛e害) -> 1(鍛�)
- radio1.value = radio1.value === 3 ? 1 : radio1.value + 1
- statisticsReceivable()
- }, 10000) // 10绉掑垏鎹竴娆�
-})
-
-onBeforeUnmount(() => {
- if (timer.value) {
- clearInterval(timer.value)
- }
- if (timerScroll.value) {
- cancelAnimationFrame(timerScroll.value)
- }
- // 娓呯悊婊氬姩鍒楄〃鐨勬殏鍋滃畾鏃跺櫒
- const contractList = refContractList.value
- if (contractList && contractList._pauseTimer) {
- clearInterval(contractList._pauseTimer)
- }
-
- // 娓呯悊寰呭姙浜嬮」鍒楄〃鐨勫姩鐢诲拰瀹氭椂鍣�
- const todoList = refTodoList.value
- if (todoList) {
- if (todoList._animationFrame) {
- cancelAnimationFrame(todoList._animationFrame)
- todoList._animationFrame = null
- }
- if (todoList._pauseTimer) {
- clearInterval(todoList._pauseTimer)
- todoList._pauseTimer = null
- }
- }
-
- // 娓呯悊鑷姩杞崲鍛ㄣ�佹湀銆佸搴︾殑瀹氭椂鍣�
- if (autoSwitchTimer.value) {
- clearInterval(autoSwitchTimer.value)
- autoSwitchTimer.value = null
- }
-
- window.removeEventListener('resize', handleResize)
- window.removeEventListener('fullscreenchange', handleFullscreenChange)
- window.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
- window.removeEventListener('MSFullscreenChange', handleFullscreenChange)
- // 绉婚櫎鎴戜滑娣诲姞鐨刟utofit鍔ㄦ�佽皟鏁寸洃鍚櫒
- if (window._autofitUpdateHandler) {
- window.removeEventListener('resize', window._autofitUpdateHandler)
- delete window._autofitUpdateHandler
- }
- disposeCharts()
- // 鍏抽棴autofit
- autofit.off()
-})
-</script>
-
-<style scoped>
-.data-dashboard {
- position: relative;
- width: 100%;
- height: 100%;
- background-image: url("@/assets/BI/backImage@2x.png");
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
-}
-
-/* 鍏ㄥ睆鐘舵�佺殑鏍峰紡 */
-.data-dashboard:fullscreen {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- background-color: inherit;
- z-index: 9999;
-}
-
-/* Webkit娴忚鍣ㄥ墠缂� */
-.data-dashboard:-webkit-full-screen {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- background-color: inherit;
- z-index: 9999;
-}
-
-/* MS娴忚鍣ㄥ墠缂� */
-.data-dashboard:-ms-fullscreen {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- background-color: inherit;
- z-index: 9999;
-}
-
-
-.dashboard-header {
- position: relative;
- z-index: 1;
- height: 170px;
- background-image: url("@/assets/BI/biaoti.png");
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.factory-name {
- font-weight: 600;
-font-size: 52px;
-color: #FFFFFF;
-top: 32px;
-position: absolute;
-}
-
-.fullscreen-btn {
- position: absolute;
- top: 10px;
- left: 20px;
- width: 40px;
- height: 40px;
- background: rgba(0, 20, 60, 0.8);
- border: 1px solid rgba(0, 212, 255, 0.3);
- border-radius: 6px;
- color: #00d4ff;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.3s;
- z-index: 10000;
-}
-
-.fullscreen-btn:hover {
- background: rgba(0, 30, 90, 0.9);
- border-color: rgba(0, 212, 255, 0.5);
-}
-
-.dashboard-content {
- position: relative;
- z-index: 1;
- display: flex;
- gap: 30px;
- padding: 0 30px;
- height: calc(100% - 120px);
- overflow: hidden;
-}
-
-/* 纭繚鍚勯潰鏉胯兘澶熸纭樉绀� */
-.left-panel, .center-panel, .right-panel {
- overflow: hidden;
-}
-
-.left-panel,
-.right-panel {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 24px;
- width: 520px;
-}
-
-.center-panel {
- flex: 1.5;
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-.panel-item-customers {
- border: 1px solid #1A58B0;
- padding: 18px;
- width: 100%;
- height: 540px;
-}
-.panel-title-second {
- height: 60px;
- display: flex;
- gap: 12px;
- margin-bottom: 20px;
- align-items: center;
-}
-.quality-cards {
- display: flex;
- gap: 12px;
- width: 100%;
- height: 94px;
- justify-content: space-between;
- align-items: center;
-}
-.quality-cardSec {
- display: flex;
-}
-.quality-cardTitle {
- font-weight: 400;
- font-size: 14px;
- color: #FFFFFF;
- display: flex;
- align-items: flex-start;
- flex-direction: column;
-}
-.quality-card {
- width: 80px;
- height: 60px;
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
-}
-.quality-card.one {
- background-image: url("@/assets/BI/yuancailiaoyijianicon@2x.png");
-}
-.quality-card.two {
- background-image: url("@/assets/BI/guochengyijianicon@2x.png");
-}
-.quality-card.three {
- background-image: url("@/assets/BI/chuchangyijianicon@2x.png");
-
-}
-.panel-title-icon {
- width: 60px;
- height: 60px;
- background-image: url("@/assets/BI/hetongicon.png");
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
-}
-
-.panel-header {
- background-image: url("@/assets/BI/kehuhetongback@2x.png");
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
-}
-
-.panel-title {
- width: 100%;
- font-weight: 500;
- font-size: 16px;
- color: #D9ECFF;
- padding-left: 46px;
- line-height: 36px;
-}
-.total-customers {
- background-image: url("@/assets/BI/hetongjineback@2x.png");
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- width: 90%;
- height: 60px;
- display: flex;
- align-items: center;
- padding: 0 20px;
- gap: 20px;
-}
-
-.total-customers .label {
- font-weight: 500;
- font-size: 16px;
- color: #FFFFFF;
-}
-
-.total-customers .value {
- font-weight: 500;
- font-size: 40px;
- background: linear-gradient(360deg, #008BFD 0%, #FFFFFF 100%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
-}
-
-.contract-list {
- margin-top: 16px;
- font-size: 14px;
- color: #666;
- list-style: none;
- padding: 0;
- height: 82%;
- overflow-y: auto;
- width: 460px;
- /* 闅愯棌婊氬姩鏉′絾淇濈暀婊氬姩鍔熻兘 */
- scrollbar-width: none; /* Firefox */
- -ms-overflow-style: none; /* IE鍜孍dge */
-}
-
-/* Chrome銆丼afari鍜孫pera */
-.contract-list::-webkit-scrollbar {
- display: none;
-}
-.line {
- position: relative;
- width: 230px;
-}
-.line::after {
- content: '';
- position: absolute;
- right: 2px;
- top: 0;
- bottom: 0;
- width: 1px;
- background-color: #C9C5C5;
- border-radius: 2px;
-}
-.contract-list li {
- margin-top: 10px;
-}
-.stats-cards {
- display: flex;
- gap: 30px;
-}
-
-.stat-card {
- flex: 1;
- display: flex;
- align-items: center;
- background-image: url("@/assets/BI/border@2x.png");
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
- height: 142px;
-}
-
-.card-icon {
- width: 100px;
- height: 100px;
- margin: 20px 20px 0 10px;
-}
-
-.card-content {
- display: flex;
- flex-direction: column;
- gap: 10px;
-}
-
-.card-value {
- font-weight: 500;
- font-size: 40px;
- background: linear-gradient(360deg, #008BFD 0%, #FFFFFF 100%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
-}
-
-.card-label {
- font-weight: 400;
- font-size: 19px;
- color: rgba(208,231,255,0.7);
-}
-
-.equipment-stats {
- border: 1px solid #1A58B0;
- padding: 18px;
- height: 240px;
-}
-.equipment-header {
- font-weight: 500;
- font-size: 21px;
- display: flex;
- border-bottom: 1px solid;
- border-image: linear-gradient( 270deg, rgba(0,126,255,0) 0%, rgba(0,126,255,0.4549) 35%, #007EFF 78%, #007EFF 100%) 1;
- padding-bottom: 2px;
-}
-.equipment-title {
- font-weight: 500;
- font-size: 21px;
- background: linear-gradient(360deg, #056DFF 0%, #43E8FC 100%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
- line-height: 50px;
-}
-.equipment-icon {
- width: 50px;
- height: 50px;
-}
-.equipment-items {
- display: flex;
- justify-content: space-around;
- gap: 30px;
-}
-
-.equipment-item {
- text-align: center;
-}
-
-.equipment-value {
- display: block;
- font-weight: 500;
- font-size: 40px;
- color: #FFFFFF;
- width: 120px;
- height: 110px;
- line-height: 110px;
- background-image: url("@/assets/BI/shujutongji@2x.png");
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
- margin-bottom: 8px;
-}
-
-.equipment-label {
- font-weight: 500;
- font-size: 21px;
- color: #FFFFFE;
-}
-
-.event-info {
- background-image: url("@/assets/BI/shijianmingchengbeijing@2x.png");
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
- padding: 20px;
- height: 186px;
-}
-.event-header {
- display: flex;
- align-items: center;
-}
-.event-icon {
- width: 40px;
- height: 40px;
-}
-.event-title {
- font-weight: 500;
- font-size: 24px;
- color: #FFFFFE;
- line-height: 30px;
-}
-.todo-list {
- list-style: none;
- padding: 0;
- margin: 0;
- height: 120px; /* 鎸夌敤鎴疯姹傝皟鏁撮珮搴� */
- overflow: hidden;
- font-size: 15px;
-}
-.todo-list li {
- border-radius: 8px;
- margin-bottom: 12px;
- padding: 12px 40px;
- height: 74px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-.todo-title {
- font-weight: 400;
- font-size: 20px;
- color: #FFFFFE;
- position: relative;
-}
-.todo-title::before {
- content: ''; /* 蹇呴渶锛岃〃绀鸿繖閲屾湁涓�涓唴瀹� */
- position: absolute;
- left: -10px; /* 瀹氫綅鍒板乏渚� */
- top: 50%; /* 鍨傜洿灞呬腑 */
- transform: translateY(-50%); /* 寰皟鍨傜洿灞呬腑 */
- width: 6px; /* 鍦嗙殑鐩村緞 */
- height: 6px; /* 鍦嗙殑鐩村緞 */
- background: #498CEB;
- border-radius: 50%; /* 璁╁叾鍙樻垚鍦嗗舰 */
-}
-.todo-division {
- font-weight: 400;
- font-size: 20px;
- color: #FFFFFE;
-}
-.todo-time {
- font-weight: 400;
- font-size: 20px;
- color: #FFFFFE;
-}
-.financial-header {
- background-image: url("@/assets/BI/caiwufenxiback@2x.png");
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
-}
-.financial-title {
- width: 100%;
- font-weight: 500;
- font-size: 16px;
- color: #D9ECFF;
- padding-left: 46px;
- line-height: 36px;
-}
-
-/* 鑷畾涔夊崟閫夋寜閽粍鏍峰紡 */
-.custom-radio-group :deep(.el-radio-button__inner) {
- background-color: transparent;
- color: white;
- border-color: rgba(255, 255, 255, 0.3);
-}
-
-.custom-radio-group :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
- background-color: rgba(255, 255, 255, 0.2);
- color: white;
- border-color: rgba(255, 255, 255, 0.5);
- box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5);
-}
-</style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
deleted file mode 100644
index 1aa36c1..0000000
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ /dev/null
@@ -1,128 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true" label-width="80px">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <el-input v-model="filters.customerName" placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
- <el-button @click="resetFilters"> 閲嶇疆 </el-button>
- <el-button @click="handleOut"> 瀵煎嚭 </el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableLoading="loading"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @pagination="changePage"
- ></PIMTable>
- </div>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { getPurchaseList } from "@/api/procurementManagement/projectProfit";
-import { onMounted, getCurrentInstance } from "vue";
-import { ElMessageBox } from "element-plus";
-
-const { proxy } = getCurrentInstance();
-
-defineOptions({
- name: "椤圭洰鍒╂鼎",
-});
-
-const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- getPurchaseList,
- {
- customerName: undefined,
- },
- [
- {
- label: "閿�鍞悎鍚屽彿",
- align: "center",
- prop: "customerContractNo",
- },
- {
- label: "瀹㈡埛鍚嶇О",
- align: "center",
- prop: "customerName",
- },
- {
- label: "椤圭洰鍚嶇О",
- align: "center",
- prop: "projectName",
- },
- {
- label: "鍚堝悓閲戦",
- align: "center",
- prop: "contractAmount",
- },
- {
- label: "閲囪喘閲戦",
- align: "center",
- prop: "purchaseAmount",
- },
- {
- label: "鍒╂鼎",
- align: "center",
- prop: "balance",
- },
- {
- label: "鍒╂鼎鐜�",
- align: "center",
- prop: "balanceRatio",
- },
- {
- label: "澧炲�肩◣",
- align: "center",
- prop: "balanceAmount",
- },
- ]
-);
-
-const changePage = ({ page }) => {
- pagination.currentPage = page;
- onCurrentChange(page);
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/report/export", {}, "椤圭洰鍒╂鼎.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getTableData();
-});
-</script>
-<style lang="scss" scoped>
-.table_list {
- margin-top: unset;
-}
-</style>
diff --git a/src/views/reportAnalysis/reportManagement.vue b/src/views/reportAnalysis/reportManagement.vue
deleted file mode 100644
index 3c87550..0000000
--- a/src/views/reportAnalysis/reportManagement.vue
+++ /dev/null
@@ -1,733 +0,0 @@
-<template>
- <div class="report-management">
- <!-- 椤甸潰鏍囬 -->
- <div class="page-header">
- <h2>鎶ヨ〃绠$悊</h2>
- <p>鎻愪緵鏍峰搧杩涘害銆佽澶囦娇鐢ㄣ�佹娴嬮」鐩�侀鐢ㄨ褰曠瓑鍚勭被鑷姩缁熻鎶ヨ〃</p>
- </div>
-
- <!-- 绛涢�夋潯浠� -->
- <el-card class="filter-card" shadow="never">
- <el-form :model="filterForm" inline>
- <el-form-item label="鏃堕棿鑼冨洿">
- <el-date-picker
- v-model="filterForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- @change="handleFilterChange"
- />
- </el-form-item>
- <el-form-item label="鎶ヨ〃绫诲瀷">
- <el-select v-model="filterForm.reportType" placeholder="璇烽�夋嫨鎶ヨ〃绫诲瀷" @change="handleFilterChange">
- <el-option label="鏍峰搧杩涘害鎶ヨ〃" value="sample" />
- <el-option label="璁惧浣跨敤鎶ヨ〃" value="equipment" />
- <el-option label="妫�娴嬮」鐩姤琛�" value="inspection" />
- <el-option label="棰嗙敤璁板綍鎶ヨ〃" value="usage" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleFilterChange">鏌ヨ</el-button>
- <el-button @click="resetFilter">閲嶇疆</el-button>
- <el-button type="success" @click="exportReport">瀵煎嚭鎶ヨ〃</el-button>
- </el-form-item>
- </el-form>
- </el-card>
-
- <!-- 缁熻鍗$墖 -->
- <div class="statistics-cards">
- <el-row :gutter="20">
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Box /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.totalSamples }}</div>
- <div class="stat-label">鎬绘牱鍝佹暟</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Tools /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.activeEquipment }}</div>
- <div class="stat-label">鍦ㄧ敤璁惧</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><Document /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.completedInspections }}</div>
- <div class="stat-label">宸插畬鎴愭娴�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="6">
- <el-card class="stat-card" shadow="hover">
- <div class="stat-content">
- <div class="stat-icon">
- <el-icon><ShoppingCart /></el-icon>
- </div>
- <div class="stat-info">
- <div class="stat-number">{{ statistics.totalUsage }}</div>
- <div class="stat-label">鎬婚鐢ㄦ鏁�</div>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 鍥捐〃鍖哄煙 -->
- <div class="charts-container">
- <el-row :gutter="20">
- <!-- 鏍峰搧杩涘害鍥捐〃 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>鏍峰搧杩涘害缁熻</span>
- <el-button type="text" @click="refreshSampleChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="sampleChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
-
- <!-- 璁惧浣跨敤鍥捐〃 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>璁惧浣跨敤鐜囩粺璁�</span>
- <el-button type="text" @click="refreshEquipmentChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="equipmentChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" style="margin-top: 20px;">
- <!-- 妫�娴嬮」鐩粺璁� -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>妫�娴嬮」鐩垎甯�</span>
- <el-button type="text" @click="refreshInspectionChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="inspectionChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
-
- <!-- 棰嗙敤璁板綍瓒嬪娍 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>棰嗙敤璁板綍瓒嬪娍</span>
- <el-button type="text" @click="refreshUsageChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="usageChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-
- <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
- <el-card class="table-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>璇︾粏鏁版嵁</span>
- <div>
- <el-button type="primary" size="small" @click="refreshTable">鍒锋柊</el-button>
- <el-button type="success" size="small" @click="exportTable">瀵煎嚭</el-button>
- </div>
- </div>
- </template>
-
- <el-table
- :data="tableData"
- style="width: 100%"
- v-loading="tableLoading"
- stripe
- border
- >
- <el-table-column prop="id" label="缂栧彿" width="80" />
- <el-table-column prop="name" label="鍚嶇О" />
- <el-table-column prop="type" label="绫诲瀷" width="120" />
- <el-table-column prop="status" label="鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="progress" label="杩涘害" width="120">
- <template #default="scope">
- <el-progress :percentage="scope.row.progress" :status="getProgressStatus(scope.row.progress)" />
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" width="180" />
- <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
- <el-table-column label="鎿嶄綔" width="150" fixed="right">
- <template #default="scope">
- <el-button type="text" size="small" @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button type="text" size="small" @click="editItem(scope.row)">缂栬緫</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <div class="pagination-container">
- <el-pagination
- v-model:current-page="pagination.currentPage"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import * as echarts from 'echarts'
-import { Box, Tools, Document, ShoppingCart } from '@element-plus/icons-vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const filterForm = reactive({
- dateRange: [],
- reportType: 'sample'
-})
-
-const statistics = reactive({
- totalSamples: 1250,
- activeEquipment: 45,
- completedInspections: 890,
- totalUsage: 2340
-})
-
-const tableData = ref([])
-const tableLoading = ref(false)
-const pagination = reactive({
- currentPage: 1,
- pageSize: 20,
- total: 0
-})
-
-// 鍥捐〃寮曠敤
-const sampleChartRef = ref(null)
-const equipmentChartRef = ref(null)
-const inspectionChartRef = ref(null)
-const usageChartRef = ref(null)
-
-// 鍥捐〃瀹炰緥
-let sampleChart = null
-let equipmentChart = null
-let inspectionChart = null
-let usageChart = null
-
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
- // 妯℃嫙琛ㄦ牸鏁版嵁
- tableData.value = [
- {
- id: 'SP001',
- name: '鏍峰搧A-001',
- type: '閲戝睘鏉愭枡',
- status: '妫�娴嬩腑',
- progress: 75,
- createTime: '2025-01-15 09:30:00',
- updateTime: '2025-01-20 14:20:00'
- },
- {
- id: 'SP002',
- name: '鏍峰搧B-002',
- type: '濉戞枡鍒跺搧',
- status: '宸插畬鎴�',
- progress: 100,
- createTime: '2025-01-10 10:15:00',
- updateTime: '2025-01-18 16:45:00'
- },
- {
- id: 'SP003',
- name: '鏍峰搧C-003',
- type: '鐢靛瓙鍏冧欢',
- status: '寰呮娴�',
- progress: 0,
- createTime: '2025-01-22 08:45:00',
- updateTime: '2025-01-22 08:45:00'
- },
- {
- id: 'EQ001',
- name: '妫�娴嬭澶嘇',
- type: '鍏夎氨浠�',
- status: '浣跨敤涓�',
- progress: 60,
- createTime: '2025-01-05 14:20:00',
- updateTime: '2025-01-20 11:30:00'
- },
- {
- id: 'EQ002',
- name: '妫�娴嬭澶嘊',
- type: '鏄惧井闀�',
- status: '绌洪棽',
- progress: 0,
- createTime: '2025-01-08 16:10:00',
- updateTime: '2025-01-19 09:15:00'
- }
- ]
-
- pagination.total = tableData.value.length
-}
-
-// 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
-const initSampleChart = () => {
- if (sampleChartRef.value) {
- sampleChart = echarts.init(sampleChartRef.value)
- const option = {
- title: {
- text: '鏍峰搧杩涘害鍒嗗竷',
- left: 'center'
- },
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}: {c} ({d}%)'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: '鏍峰搧鐘舵��',
- type: 'pie',
- radius: ['40%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: 'center'
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '18',
- fontWeight: 'bold'
- }
- },
- labelLine: {
- show: false
- },
- data: [
- { value: 450, name: '宸插畬鎴�' },
- { value: 320, name: '妫�娴嬩腑' },
- { value: 280, name: '寰呮娴�' },
- { value: 200, name: '宸叉殏鍋�' }
- ]
- }
- ]
- }
- sampleChart.setOption(option)
- }
-}
-
-// 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
-const initEquipmentChart = () => {
- if (equipmentChartRef.value) {
- equipmentChart = echarts.init(equipmentChartRef.value)
- const option = {
- title: {
- text: '璁惧浣跨敤鐜�',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- }
- },
- xAxis: {
- type: 'category',
- data: ['鍏夎氨浠�', '鏄惧井闀�', '纭害璁�', '鎷夊姏鏈�', '鍐插嚮鏈�', '閲戠浉浠�']
- },
- yAxis: {
- type: 'value',
- name: '浣跨敤鐜�(%)'
- },
- series: [
- {
- name: '浣跨敤鐜�',
- type: 'bar',
- data: [85, 60, 75, 90, 45, 70],
- label: {
- show: true,
- position: 'inside',
- align: 'center',
- verticalAlign: 'middle',
- formatter: '{c}%',
- color: '#fff'
- },
- itemStyle: {
- color: function(params) {
- const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
- return colors[params.dataIndex]
- }
- }
- }
- ]
- }
- equipmentChart.setOption(option)
- }
-}
-
-// 鍒濆鍖栨娴嬮」鐩浘琛�
-const initInspectionChart = () => {
- if (inspectionChartRef.value) {
- inspectionChart = echarts.init(inspectionChartRef.value)
- const option = {
- title: {
- text: '妫�娴嬮」鐩垎甯�',
- left: 'center'
- },
- tooltip: {
- trigger: 'item'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: '妫�娴嬮」鐩�',
- type: 'pie',
- radius: '50%',
- data: [
- { value: 335, name: '鐗╃悊鎬ц兘' },
- { value: 310, name: '鍖栧鍒嗘瀽' },
- { value: 234, name: '灏哄娴嬮噺' },
- { value: 135, name: '澶栬妫�鏌�' },
- { value: 148, name: '鍏朵粬妫�娴�' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- }
- inspectionChart.setOption(option)
- }
-}
-
-// 鍒濆鍖栭鐢ㄨ褰曞浘琛�
-const initUsageChart = () => {
- if (usageChartRef.value) {
- usageChart = echarts.init(usageChartRef.value)
- const option = {
- title: {
- text: '棰嗙敤璁板綍瓒嬪娍',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['棰嗙敤娆℃暟', '褰掕繕娆℃暟']
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
- },
- yAxis: {
- type: 'value'
- },
- series: [
- {
- name: '棰嗙敤娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330]
- },
- {
- name: '褰掕繕娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320]
- }
- ]
- }
- usageChart.setOption(option)
- }
-}
-
-// 浜嬩欢澶勭悊鍑芥暟
-const handleFilterChange = () => {
- ElMessage.success('绛涢�夋潯浠跺凡鏇存柊')
- // 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
-}
-
-const resetFilter = () => {
- filterForm.dateRange = []
- filterForm.reportType = 'sample'
- ElMessage.info('绛涢�夋潯浠跺凡閲嶇疆')
-}
-
-const exportReport = () => {
- ElMessage.success('鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-const refreshSampleChart = () => {
- initSampleChart()
- ElMessage.success('鏍峰搧杩涘害鍥捐〃宸插埛鏂�')
-}
-
-const refreshEquipmentChart = () => {
- initEquipmentChart()
- ElMessage.success('璁惧浣跨敤鍥捐〃宸插埛鏂�')
-}
-
-const refreshInspectionChart = () => {
- initInspectionChart()
- ElMessage.success('妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊')
-}
-
-const refreshUsageChart = () => {
- initUsageChart()
- ElMessage.success('棰嗙敤璁板綍鍥捐〃宸插埛鏂�')
-}
-
-const refreshTable = () => {
- tableLoading.value = true
- setTimeout(() => {
- tableLoading.value = false
- ElMessage.success('琛ㄦ牸鏁版嵁宸插埛鏂�')
- }, 1000)
-}
-
-const exportTable = () => {
- ElMessage.success('琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-const handleSizeChange = (val) => {
- pagination.pageSize = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
-const getStatusType = (status) => {
- const statusMap = {
- '宸插畬鎴�': 'success',
- '妫�娴嬩腑': 'warning',
- '寰呮娴�': 'info',
- '宸叉殏鍋�': 'danger',
- '浣跨敤涓�': 'primary',
- '绌洪棽': 'info'
- }
- return statusMap[status] || 'info'
-}
-
-const getProgressStatus = (progress) => {
- if (progress === 100) return 'success'
- if (progress >= 80) return 'warning'
- if (progress >= 50) return ''
- return 'exception'
-}
-
-const viewDetail = (row) => {
- ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`)
-}
-
-const editItem = (row) => {
- ElMessage.info(`缂栬緫椤圭洰: ${row.name}`)
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- initData()
- nextTick(() => {
- initSampleChart()
- initEquipmentChart()
- initInspectionChart()
- initUsageChart()
- })
-
- // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
- window.addEventListener('resize', () => {
- sampleChart?.resize()
- equipmentChart?.resize()
- inspectionChart?.resize()
- usageChart?.resize()
- })
-})
-</script>
-
-<style scoped>
-.report-management {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 100vh;
-}
-
-.page-header {
- margin-bottom: 20px;
- text-align: center;
-}
-
-.page-header h2 {
- color: #303133;
- margin-bottom: 8px;
- font-size: 24px;
- font-weight: 600;
-}
-
-.page-header p {
- color: #909399;
- font-size: 14px;
- margin: 0;
-}
-
-.filter-card {
- margin-bottom: 20px;
-}
-
-.statistics-cards {
- margin-bottom: 20px;
-}
-
-.stat-card {
- height: 120px;
-}
-
-.stat-content {
- display: flex;
- align-items: center;
- height: 100%;
-}
-
-.stat-icon {
- width: 60px;
- height: 60px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 20px;
- font-size: 24px;
- color: white;
-}
-
-.stat-card:nth-child(1) .stat-icon {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-}
-
-.stat-card:nth-child(2) .stat-icon {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
-}
-
-.stat-card:nth-child(3) .stat-icon {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-}
-
-.stat-card:nth-child(4) .stat-icon {
- background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
-}
-
-.stat-info {
- flex: 1;
-}
-
-.stat-number {
- font-size: 28px;
- font-weight: bold;
- color: #303133;
- margin-bottom: 8px;
-}
-
-.stat-label {
- font-size: 14px;
- color: #909399;
-}
-
-.charts-container {
- margin-bottom: 20px;
-}
-
-.chart-card {
- margin-bottom: 20px;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.chart-container {
- height: 300px;
- width: 100%;
-}
-
-.table-card {
- margin-bottom: 20px;
-}
-
-.pagination-container {
- margin-top: 20px;
- text-align: right;
-}
-
-:deep(.el-card__header) {
- padding: 15px 20px;
- border-bottom: 1px solid #ebeef5;
- background-color: #fafafa;
-}
-
-:deep(.el-card__body) {
- padding: 20px;
-}
-
-:deep(.el-table) {
- margin-bottom: 20px;
-}
-
-:deep(.el-progress) {
- margin: 0;
-}
-
-:deep(.el-tag) {
- margin: 0;
-}
-</style>
diff --git a/src/views/reportAnalysis/reportManagement/index.vue b/src/views/reportAnalysis/reportManagement/index.vue
index 2adfb54..be7b2c4 100644
--- a/src/views/reportAnalysis/reportManagement/index.vue
+++ b/src/views/reportAnalysis/reportManagement/index.vue
@@ -16,22 +16,13 @@
@change="handleFilterChange"
/>
</el-form-item>
- <el-form-item label="鎶ヨ〃绫诲瀷">
- <el-select v-model="filterForm.reportType" placeholder="璇烽�夋嫨鎶ヨ〃绫诲瀷" @change="handleFilterChange" style="width: 300px">
- <el-option label="鏍峰搧杩涘害鎶ヨ〃" value="sample" />
- <el-option label="璁惧浣跨敤鎶ヨ〃" value="equipment" />
- <el-option label="妫�娴嬮」鐩姤琛�" value="inspection" />
- <el-option label="棰嗙敤璁板綍鎶ヨ〃" value="usage" />
- </el-select>
- </el-form-item>
<el-form-item>
<el-button type="primary" @click="handleFilterChange">鏌ヨ</el-button>
<el-button @click="resetFilter">閲嶇疆</el-button>
- <el-button type="success" @click="exportReport">瀵煎嚭鎶ヨ〃</el-button>
</el-form-item>
</el-form>
</el-card>
-
+
<!-- 缁熻鍗$墖 -->
<div class="statistics-cards">
<el-row :gutter="20">
@@ -43,7 +34,7 @@
</div>
<div class="stat-info">
<div class="stat-number">{{ statistics.totalSamples }}</div>
- <div class="stat-label">鎬绘牱鍝佹暟</div>
+ <div class="stat-label">鎬昏鍗曟暟</div>
</div>
</div>
</el-card>
@@ -56,7 +47,7 @@
</div>
<div class="stat-info">
<div class="stat-number">{{ statistics.activeEquipment }}</div>
- <div class="stat-label">鍦ㄧ敤璁惧</div>
+ <div class="stat-label">寰呯敓浜ф暟閲�</div>
</div>
</div>
</el-card>
@@ -69,7 +60,7 @@
</div>
<div class="stat-info">
<div class="stat-number">{{ statistics.completedInspections }}</div>
- <div class="stat-label">宸插畬鎴愭娴�</div>
+ <div class="stat-label">宸茬敓浜ф暟閲�</div>
</div>
</div>
</el-card>
@@ -82,14 +73,14 @@
</div>
<div class="stat-info">
<div class="stat-number">{{ statistics.totalUsage }}</div>
- <div class="stat-label">鎬婚鐢ㄦ鏁�</div>
+ <div class="stat-label">鎬绘牳绠楀伐鏃�</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
-
+
<!-- 鍥捐〃鍖哄煙 -->
<div class="charts-container">
<el-row :gutter="20">
@@ -98,69 +89,37 @@
<el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
- <span>鏍峰搧杩涘害缁熻</span>
- <el-button link @click="refreshSampleChart">鍒锋柊</el-button>
+ <span>鐢熶骇鎶ュ伐缁熻</span>
</div>
</template>
<div ref="sampleChartRef" class="chart-container"></div>
</el-card>
</el-col>
-
+
<!-- 璁惧浣跨敤鍥捐〃 -->
<el-col :span="12">
<el-card class="chart-card" shadow="hover">
<template #header>
<div class="card-header">
- <span>璁惧浣跨敤鐜囩粺璁�</span>
- <el-button link @click="refreshEquipmentChart">鍒锋柊</el-button>
+ <span>鐢熶骇鏍哥畻缁熻</span>
</div>
</template>
<div ref="equipmentChartRef" class="chart-container"></div>
</el-card>
</el-col>
</el-row>
-
- <el-row :gutter="20" style="margin-top: 20px;">
- <!-- 妫�娴嬮」鐩粺璁� -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>妫�娴嬮」鐩垎甯�</span>
- <el-button link @click="refreshInspectionChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="inspectionChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
-
- <!-- 棰嗙敤璁板綍瓒嬪娍 -->
- <el-col :span="12">
- <el-card class="chart-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span>棰嗙敤璁板綍瓒嬪娍</span>
- <el-button link @click="refreshUsageChart">鍒锋柊</el-button>
- </div>
- </template>
- <div ref="usageChartRef" class="chart-container"></div>
- </el-card>
- </el-col>
- </el-row>
</div>
-
+
<!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
<el-card class="table-card" shadow="hover">
<template #header>
<div class="card-header">
- <span>璇︾粏鏁版嵁</span>
+ <span>鐢熶骇鎶ュ伐璇︽儏</span>
<div>
- <el-button type="primary" size="small" @click="refreshTable">鍒锋柊</el-button>
- <el-button type="success" size="small" @click="exportTable">瀵煎嚭</el-button>
</div>
</div>
</template>
-
+
<el-table
:data="tableData"
style="width: 100%"
@@ -169,40 +128,28 @@
border
>
<el-table-column prop="id" label="缂栧彿" width="80" />
- <el-table-column prop="name" label="鍚嶇О" />
+ <el-table-column prop="orderNo" label="鐢熶骇璁㈠崟鍙�" />
+ <el-table-column prop="productCategory" label="浜у搧澶х被" />
+ <el-table-column prop="specificationModel" label="瑙勬牸鍨嬪彿" />
+ <el-table-column prop="unit" label="鍗曚綅" />
+ <el-table-column prop="schedulingUserName" label="鎺掍骇浜�" />
+ <el-table-column prop="schedulingDate" label="鎺掍骇鏃ユ湡" />
+ <el-table-column prop="process" label="宸ュ簭" />
+ <el-table-column prop="schedulingNum" label="鎺掍骇鏁伴噺" />
+ <el-table-column prop="finishedNum" label="鐢熶骇鏁伴噺" />
+ <el-table-column prop="pendingFinishNum" label="寰呯敓浜ф暟閲�" >
+ <template #default="scope">
+ <span>{{ scope.row.schedulingNum - scope.row.finishedNum }}</span>
+ </template>
+ </el-table-column>
<el-table-column prop="status" label="鐘舵��">
<template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
+ <el-tag :type="getStatusType(scope.row.status).type">
+ {{ getStatusType(scope.row.status).label }}
</el-tag>
</template>
</el-table-column>
- <el-table-column prop="progress" label="杩涘害">
- <template #default="scope">
- <el-progress :percentage="scope.row.progress" :status="getProgressStatus(scope.row.progress)" />
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" width="180" />
- <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" width="180" />
- <el-table-column label="鎿嶄綔" width="150" fixed="right">
- <template #default="scope">
- <el-button link size="small" @click="viewDetail(scope.row)">鏌ョ湅</el-button>
- <el-button link size="small" @click="editItem(scope.row)">缂栬緫</el-button>
- </template>
- </el-table-column>
</el-table>
-
- <div class="pagination-container">
- <el-pagination
- v-model:current-page="pagination.currentPage"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
</el-card>
</div>
</template>
@@ -212,6 +159,7 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import * as echarts from 'echarts'
import { Box, Tools, Document, ShoppingCart } from '@element-plus/icons-vue'
+import {reportAnalysis} from '@/api/productionManagement/productionOrder'
// 鍝嶅簲寮忔暟鎹�
const filterForm = reactive({
@@ -220,25 +168,18 @@
})
const statistics = reactive({
- totalSamples: 1250,
- activeEquipment: 45,
- completedInspections: 890,
- totalUsage: 2340
+ totalSamples: 0,
+ activeEquipment: 0,
+ completedInspections: 0,
+ totalUsage: 0
})
const tableData = ref([])
const tableLoading = ref(false)
-const pagination = reactive({
- currentPage: 1,
- pageSize: 20,
- total: 0
-})
// 鍥捐〃寮曠敤
const sampleChartRef = ref(null)
const equipmentChartRef = ref(null)
-const inspectionChartRef = ref(null)
-const usageChartRef = ref(null)
// 鍥捐〃瀹炰緥
let sampleChart = null
@@ -248,60 +189,34 @@
// 鍒濆鍖栨暟鎹�
const initData = () => {
- // 妯℃嫙琛ㄦ牸鏁版嵁
- tableData.value = [
- {
- id: 'SP001',
- name: '鏍峰搧A-001',
- type: '閲戝睘鏉愭枡',
- status: '妫�娴嬩腑',
- progress: 75,
- createTime: '2025-01-15 09:30:00',
- updateTime: '2025-01-20 14:20:00'
- },
- {
- id: 'SP002',
- name: '鏍峰搧B-002',
- type: '濉戞枡鍒跺搧',
- status: '宸插畬鎴�',
- progress: 100,
- createTime: '2025-01-10 10:15:00',
- updateTime: '2025-01-18 16:45:00'
- },
- {
- id: 'SP003',
- name: '鏍峰搧C-003',
- type: '鐢靛瓙鍏冧欢',
- status: '寰呮娴�',
- progress: 0,
- createTime: '2025-01-22 08:45:00',
- updateTime: '2025-01-22 08:45:00'
- },
- {
- id: 'EQ001',
- name: '妫�娴嬭澶嘇',
- type: '鍏夎氨浠�',
- status: '浣跨敤涓�',
- progress: 60,
- createTime: '2025-01-05 14:20:00',
- updateTime: '2025-01-20 11:30:00'
- },
- {
- id: 'EQ002',
- name: '妫�娴嬭澶嘊',
- type: '鏄惧井闀�',
- status: '绌洪棽',
- progress: 0,
- createTime: '2025-01-08 16:10:00',
- updateTime: '2025-01-19 09:15:00'
- }
- ]
-
- pagination.total = tableData.value.length
+ let startDate=null,endDate=null;
+ if(filterForm.dateRange && filterForm.dateRange.length===2){
+ startDate = filterForm.dateRange[0];
+ endDate = filterForm.dateRange[1];
+ }
+ reportAnalysis({startDate:startDate,endDate:endDate}).then(res=>{
+ statistics.totalSamples = res.data.totalData.totalOrderNum
+ statistics.activeEquipment = res.data.totalData.tobeProduced
+ statistics.completedInspections = res.data.totalData.finishProduced
+ statistics.totalUsage = res.data.totalData.totalWorkhours
+ // 鍒濆鍖栧浘琛�
+ let chartData = res.data.productData?res.data.productData:{
+ finishProduced:0,
+ inProduced:0,
+ tobeProduced:0
+ };
+ initSampleChart([
+ { value: chartData.finishProduced, name: '宸插畬鎴�' },
+ { value: chartData.inProduced, name: '鐢熶骇涓�' },
+ { value: chartData.tobeProduced, name: '寰呮姤宸�' },
+ ])
+ initEquipmentChart(res.data.workHours)
+ tableData.value = res.data.productDetails
+ })
}
// 鍒濆鍖栨牱鍝佽繘搴﹀浘琛�
-const initSampleChart = () => {
+const initSampleChart = (charData) => {
if (sampleChartRef.value) {
sampleChart = echarts.init(sampleChartRef.value)
const option = {
@@ -336,12 +251,7 @@
labelLine: {
show: false
},
- data: [
- { value: 450, name: '宸插畬鎴�' },
- { value: 320, name: '妫�娴嬩腑' },
- { value: 280, name: '寰呮娴�' },
- { value: 200, name: '宸叉殏鍋�' }
- ]
+ data: charData
}
]
}
@@ -350,8 +260,16 @@
}
// 鍒濆鍖栬澶囦娇鐢ㄥ浘琛�
-const initEquipmentChart = () => {
+const initEquipmentChart = (chartData) => {
if (equipmentChartRef.value) {
+ let processData = [];
+ let workHoursData = [];
+ if(chartData){
+ chartData.forEach(item=>{
+ processData.push(item.process);
+ workHoursData.push(item.workHours);
+ })
+ }
equipmentChart = echarts.init(equipmentChartRef.value)
const option = {
title: {
@@ -365,22 +283,23 @@
},
xAxis: {
type: 'category',
- data: ['鍏夎氨浠�', '鏄惧井闀�', '纭害璁�', '鎷夊姏鏈�', '鍐插嚮鏈�', '閲戠浉浠�']
+ data: processData,
+ name: '宸ュ簭'
},
yAxis: {
type: 'value',
- name: '浣跨敤鐜�(%)'
+ name: '鏍哥畻宸ユ椂'
},
series: [
{
- name: '浣跨敤鐜�',
+ name: '鏍哥畻宸ユ椂',
type: 'bar',
- data: [85, 60, 75, 90, 45, 70],
+ data: workHoursData,
itemStyle: {
- color: function(params) {
- const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
- return colors[params.dataIndex]
- }
+ // color: function(params) {
+ // const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
+ // return colors[params.dataIndex]
+ // }
}
}
]
@@ -389,92 +308,10 @@
}
}
-// 鍒濆鍖栨娴嬮」鐩浘琛�
-const initInspectionChart = () => {
- if (inspectionChartRef.value) {
- inspectionChart = echarts.init(inspectionChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'item'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: '妫�娴嬮」鐩�',
- type: 'pie',
- radius: '50%',
- data: [
- { value: 335, name: '鐗╃悊鎬ц兘' },
- { value: 310, name: '鍖栧鍒嗘瀽' },
- { value: 234, name: '灏哄娴嬮噺' },
- { value: 135, name: '澶栬妫�鏌�' },
- { value: 148, name: '鍏朵粬妫�娴�' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- }
- inspectionChart.setOption(option)
- }
-}
-
-// 鍒濆鍖栭鐢ㄨ褰曞浘琛�
-const initUsageChart = () => {
- if (usageChartRef.value) {
- usageChart = echarts.init(usageChartRef.value)
- const option = {
- title: {
- show: false
- },
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['棰嗙敤娆℃暟', '褰掕繕娆℃暟']
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
- },
- yAxis: {
- type: 'value'
- },
- series: [
- {
- name: '棰嗙敤娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330]
- },
- {
- name: '褰掕繕娆℃暟',
- type: 'line',
- stack: 'Total',
- data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320]
- }
- ]
- }
- usageChart.setOption(option)
- }
-}
-
// 浜嬩欢澶勭悊鍑芥暟
const handleFilterChange = () => {
- ElMessage.success('绛涢�夋潯浠跺凡鏇存柊')
// 杩欓噷鍙互鏍规嵁绛涢�夋潯浠堕噸鏂板姞杞芥暟鎹�
+ initData()
}
const resetFilter = () => {
@@ -483,62 +320,13 @@
ElMessage.info('绛涢�夋潯浠跺凡閲嶇疆')
}
-const exportReport = () => {
- ElMessage.success('鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-const refreshSampleChart = () => {
- initSampleChart()
- ElMessage.success('鏍峰搧杩涘害鍥捐〃宸插埛鏂�')
-}
-
-const refreshEquipmentChart = () => {
- initEquipmentChart()
- ElMessage.success('璁惧浣跨敤鍥捐〃宸插埛鏂�')
-}
-
-const refreshInspectionChart = () => {
- initInspectionChart()
- ElMessage.success('妫�娴嬮」鐩浘琛ㄥ凡鍒锋柊')
-}
-
-const refreshUsageChart = () => {
- initUsageChart()
- ElMessage.success('棰嗙敤璁板綍鍥捐〃宸插埛鏂�')
-}
-
-const refreshTable = () => {
- tableLoading.value = true
- setTimeout(() => {
- tableLoading.value = false
- ElMessage.success('琛ㄦ牸鏁版嵁宸插埛鏂�')
- }, 1000)
-}
-
-const exportTable = () => {
- ElMessage.success('琛ㄦ牸瀵煎嚭鍔熻兘寮�鍙戜腑...')
-}
-
-const handleSizeChange = (val) => {
- pagination.pageSize = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val
- // 閲嶆柊鍔犺浇鏁版嵁
-}
-
const getStatusType = (status) => {
const statusMap = {
- '宸插畬鎴�': 'success',
- '妫�娴嬩腑': 'warning',
- '寰呮娴�': 'info',
- '宸叉殏鍋�': 'danger',
- '浣跨敤涓�': 'primary',
- '绌洪棽': 'info'
+ '3': {type:'success',label:'宸插畬鎴�'},
+ '2': {type:'warning',label:'鐢熶骇涓�'},
+ '1': {type:'info',label:'寰呯敓浜�'}
}
- return statusMap[status] || 'info'
+ return statusMap[status] || {type:'info',label:'鏈煡鐘舵��'}
}
const getProgressStatus = (progress) => {
@@ -548,24 +336,9 @@
return 'exception'
}
-const viewDetail = (row) => {
- ElMessage.info(`鏌ョ湅璇︽儏: ${row.name}`)
-}
-
-const editItem = (row) => {
- ElMessage.info(`缂栬緫椤圭洰: ${row.name}`)
-}
-
// 鐢熷懡鍛ㄦ湡
onMounted(() => {
initData()
- nextTick(() => {
- initSampleChart()
- initEquipmentChart()
- initInspectionChart()
- initUsageChart()
- })
-
// 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌皟鏁村浘琛ㄥぇ灏�
window.addEventListener('resize', () => {
sampleChart?.resize()
@@ -581,11 +354,6 @@
padding: 20px;
background-color: #f5f5f5;
min-height: 100vh;
-}
-
-.page-header {
- margin-bottom: 20px;
- text-align: center;
}
.page-header h2 {
@@ -684,11 +452,6 @@
.table-card {
margin-bottom: 20px;
-}
-
-.pagination-container {
- margin-top: 20px;
- text-align: right;
}
:deep(.el-card__header) {
diff --git a/src/views/reportAnalysis/taxComparison/index.vue b/src/views/reportAnalysis/taxComparison/index.vue
deleted file mode 100644
index d27ab07..0000000
--- a/src/views/reportAnalysis/taxComparison/index.vue
+++ /dev/null
@@ -1,118 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="filters" :inline="true">
- <el-form-item label="鏃ユ湡">
- <el-date-picker
- style="width: 240px"
- v-model="filters.month"
- value-format="YYYY-MM"
- format="YYYY-MM"
- type="month"
- placeholder="閫夋嫨鏈堜唤"
- clearable
- @change="getTableData"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="getTableData"> 鎼滅储 </el-button>
- <el-button @click="resetFilters"> 閲嶇疆 </el-button>
- <el-button @click="handleOut"> 瀵煎嚭 </el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableData="dataList"
- :page="{
- current: pagination.currentPage,
- size: pagination.pageSize,
- total: pagination.total,
- }"
- @pagination="changePage"
- />
- </div>
- </div>
-</template>
-
-<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { onMounted, getCurrentInstance } from "vue";
-import { getTaxList } from "@/api/procurementManagement/taxComparison";
-import { ElMessageBox } from "element-plus";
-
-const { proxy } = getCurrentInstance();
-
-defineOptions({
- name: "澧炲�肩◣姣斿",
-});
-
-const {
- loading,
- filters,
- columns,
- dataList,
- pagination,
- getTableData,
- resetFilters,
- onCurrentChange,
-} = usePaginationApi(
- getTaxList,
- {
- month: [], // 鏉ョエ鏃ユ湡
- },
- [
- {
- label: "鏈堜唤",
- prop: "month",
- align: "center",
- },
- {
- label: "閿�椤圭◣棰�",
- prop: "jtaxAmount",
- align: "center",
- },
- {
- label: "杩涢」绋庨",
- prop: "xtaxAmount",
- align: "center",
- },
- {
- label: "閿�-杩�",
- prop: "taxAmount",
- align: "center",
- },
- ],
- {}
-);
-
-const changePage = ({ page }) => {
- pagination.currentPage = page;
- onCurrentChange(page);
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/purchase/report/exportTwo", {}, "澧炲�肩◣姣斿.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getTableData();
-});
-</script>
-
-<style lang="scss" scoped>
-.table_list {
- margin-top: unset;
-}
-</style>
diff --git a/src/views/salesManagement/customerManagement/index.vue b/src/views/salesManagement/customerManagement/index.vue
deleted file mode 100644
index f66b5f4..0000000
--- a/src/views/salesManagement/customerManagement/index.vue
+++ /dev/null
@@ -1,423 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.name"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.region" placeholder="璇烽�夋嫨鍖哄煙" clearable>
- <el-option label="鍗庝笢鍖�" value="鍗庝笢鍖�"></el-option>
- <el-option label="鍗庡崡鍖�" value="鍗庡崡鍖�"></el-option>
- <el-option label="鍗庡寳鍖�" value="鍗庡寳鍖�"></el-option>
- <el-option label="瑗垮崡鍖�" value="瑗垮崡鍖�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.level" placeholder="璇烽�夋嫨瀹㈡埛绛夌骇" clearable>
- <el-option label="VIP瀹㈡埛" value="VIP瀹㈡埛"></el-option>
- <el-option label="閲嶈瀹㈡埛" value="閲嶈瀹㈡埛"></el-option>
- <el-option label="鏅�氬鎴�" value="鏅�氬鎴�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button style="float: right;" type="primary" @click="handleAdd">
- 鏂板瀹㈡埛
- </el-button>
- </el-col>
- </el-row>
-
- <!-- 瀹㈡埛鍒楄〃 -->
- <el-table
- :data="filteredList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="id" label="ID" width="80" align="center"/>
- <el-table-column prop="name" label="瀹㈡埛鍚嶇О" width="150" />
- <el-table-column prop="contactPerson" label="鑱旂郴浜�" width="100" />
- <el-table-column prop="phone" label="鑱旂郴鐢佃瘽" width="140" />
- <el-table-column prop="email" label="閭" />
- <el-table-column prop="region" label="鍖哄煙" width="100" />
- <el-table-column prop="level" label="瀹㈡埛绛夌骇" width="100">
- <template #default="scope">
- <el-tag :type="getLevelType(scope.row.level)">
- {{ scope.row.level }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="salesperson" label="璐熻矗涓氬姟鍛�" width="120" />
- <el-table-column prop="status" label="鐘舵��" width="80">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="primary" @click="handleAllocation(scope.row)">鍒嗛厤</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.currentPage"
- :limit="pagination.pageSize"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О" prop="name">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鎴峰悕绉�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鑱旂郴浜�" prop="contactPerson">
- <el-input v-model="form.contactPerson" placeholder="璇疯緭鍏ヨ仈绯讳汉"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閭" prop="email">
- <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍖哄煙" prop="region">
- <el-select v-model="form.region" placeholder="璇烽�夋嫨鍖哄煙" style="width: 100%">
- <el-option label="鍗庝笢鍖�" value="鍗庝笢鍖�"></el-option>
- <el-option label="鍗庡崡鍖�" value="鍗庡崡鍖�"></el-option>
- <el-option label="鍗庡寳鍖�" value="鍗庡寳鍖�"></el-option>
- <el-option label="瑗垮崡鍖�" value="瑗垮崡鍖�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛绛夌骇" prop="level">
- <el-select v-model="form.level" placeholder="璇烽�夋嫨瀹㈡埛绛夌骇" style="width: 100%">
- <el-option label="VIP瀹㈡埛" value="VIP瀹㈡埛"></el-option>
- <el-option label="閲嶈瀹㈡埛" value="閲嶈瀹㈡埛"></el-option>
- <el-option label="鏅�氬鎴�" value="鏅�氬鎴�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璐熻矗涓氬姟鍛�" prop="salesperson">
- <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%">
- <el-option label="闄堝織寮�" value="闄堝織寮�"></el-option>
- <el-option label="鍒橀泤濠�" value="鍒橀泤濠�"></el-option>
- <el-option label="鐜嬪缓鍥�" value="鐜嬪缓鍥�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option label="娲昏穬" value="娲昏穬"></el-option>
- <el-option label="娼滃湪" value="娼滃湪"></el-option>
- <el-option label="娴佸け" value="娴佸け"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 瀹㈡埛鍒嗛厤瀵硅瘽妗� -->
- <el-dialog v-model="allocationDialogVisible" title="瀹㈡埛鍒嗛厤" width="500px">
- <el-form label-width="100px">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <span>{{ currentCustomer.name }}</span>
- </el-form-item>
- <el-form-item label="褰撳墠涓氬姟鍛�">
- <span>{{ currentCustomer.salesperson }}</span>
- </el-form-item>
- <el-form-item label="閲嶆柊鍒嗛厤">
- <el-select v-model="newSalesperson" placeholder="璇烽�夋嫨鏂颁笟鍔″憳" style="width: 100%">
- <el-option label="闄堝織寮�" value="闄堝織寮�"></el-option>
- <el-option label="鍒橀泤濠�" value="鍒橀泤濠�"></el-option>
- <el-option label="鐜嬪缓鍥�" value="鐜嬪缓鍥�"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="鍒嗛厤鍘熷洜">
- <el-input v-model="allocationReason" type="textarea" rows="3" placeholder="璇疯緭鍏ュ垎閰嶅師鍥�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="allocationDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="saveAllocation">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- name: '',
- region: '',
- level: ''
-})
-
-const customerList = ref([
- {
- id: 1,
- name: '涓婃捣绉戞妧鏈夐檺鍏徃',
- contactPerson: '闄堝織寮�',
- phone: '021-12345678',
- email: 'zhang@shanghai-tech.com',
- region: '鍗庝笢鍖�',
- level: 'VIP瀹㈡埛',
- salesperson: '闄堝織寮�',
- status: '娲昏穬'
- },
- {
- id: 2,
- name: '娣卞湷鐢靛瓙鏈夐檺鍏徃',
- contactPerson: '鍒橀泤濠�',
- phone: '0755-87654321',
- email: 'li@shenzhen-elec.com',
- region: '鍗庡崡鍖�',
- level: '閲嶈瀹㈡埛',
- salesperson: '鍒橀泤濠�',
- status: '娲昏穬'
- },
- {
- id: 3,
- name: '鍖椾含璐告槗鍏徃',
- contactPerson: '鐜嬪缓鍥�',
- phone: '010-11223344',
- email: 'wang@beijing-trade.com',
- region: '鍗庡寳鍖�',
- level: '鏅�氬鎴�',
- salesperson: '鐜嬪缓鍥�',
- status: '娼滃湪'
- }
-])
-
-const pagination = reactive({
- total: 3,
- currentPage: 1,
- pageSize: 10
-})
-
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板瀹㈡埛')
-const form = reactive({
- name: '',
- contactPerson: '',
- phone: '',
- email: '',
- region: '',
- level: '',
- salesperson: '',
- status: '娲昏穬'
-})
-
-const rules = {
- name: [{ required: true, message: '璇疯緭鍏ュ鎴峰悕绉�', trigger: 'blur' }],
- contactPerson: [{ required: true, message: '璇疯緭鍏ヨ仈绯讳汉', trigger: 'blur' }],
- phone: [{ required: true, message: '璇疯緭鍏ヨ仈绯荤數璇�', trigger: 'blur' }],
- email: [{ required: true, message: '璇疯緭鍏ラ偖绠�', trigger: 'blur' }],
- region: [{ required: true, message: '璇烽�夋嫨鍖哄煙', trigger: 'change' }],
- level: [{ required: true, message: '璇烽�夋嫨瀹㈡埛绛夌骇', trigger: 'change' }],
- salesperson: [{ required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'change' }],
- status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
-
-const isEdit = ref(false)
-const editId = ref(null)
-const allocationDialogVisible = ref(false)
-const currentCustomer = ref({})
-const newSalesperson = ref('')
-const allocationReason = ref('')
-const formRef = ref()
-
-// 璁$畻灞炴��
-const filteredList = computed(() => {
- let list = customerList.value
- if (searchForm.name) {
- list = list.filter(item => item.name.includes(searchForm.name))
- }
- if (searchForm.region) {
- list = list.filter(item => item.region === searchForm.region)
- }
- if (searchForm.level) {
- list = list.filter(item => item.level === searchForm.level)
- }
- return list
-})
-
-// 鏂规硶
-const getLevelType = (level) => {
- const levelMap = {
- 'VIP瀹㈡埛': 'danger',
- '閲嶈瀹㈡埛': 'warning',
- '鏅�氬鎴�': 'info'
- }
- return levelMap[level] || 'info'
-}
-
-const getStatusType = (status) => {
- const statusMap = {
- '娲昏穬': 'success',
- '娼滃湪': 'warning',
- '娴佸け': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-const handleSearch = () => {
- // 鎼滅储閫昏緫宸插湪computed涓鐞�
-}
-
-const resetSearch = () => {
- searchForm.name = ''
- searchForm.region = ''
- searchForm.level = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板瀹㈡埛'
- isEdit.value = false
- form.name = ''
- form.contactPerson = ''
- form.phone = ''
- form.email = ''
- form.region = ''
- form.level = ''
- form.salesperson = ''
- form.status = '娲昏穬'
- dialogVisible.value = true
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫瀹㈡埛'
- isEdit.value = true
- editId.value = row.id
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ュ鎴峰悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = customerList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- customerList.value.splice(index, 1)
- pagination.total--
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const handleAllocation = (row) => {
- currentCustomer.value = row
- newSalesperson.value = ''
- allocationReason.value = ''
- allocationDialogVisible.value = true
-}
-
-const saveAllocation = () => {
- if (!newSalesperson.value) {
- ElMessage.warning('璇烽�夋嫨鏂颁笟鍔″憳')
- return
- }
-
- const index = customerList.value.findIndex(item => item.id === currentCustomer.value.id)
- if (index > -1) {
- customerList.value[index].salesperson = newSalesperson.value
- ElMessage.success('瀹㈡埛鍒嗛厤鎴愬姛')
- allocationDialogVisible.value = false
- }
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (isEdit.value) {
- // 缂栬緫
- const index = customerList.value.findIndex(item => item.id === editId.value)
- if (index > -1) {
- customerList.value[index] = { ...form, id: editId.value }
- ElMessage.success('缂栬緫鎴愬姛')
- }
- } else {
- // 鏂板
- const newId = Math.max(...customerList.value.map(item => item.id)) + 1
- customerList.value.push({
- ...form,
- id: newId
- })
- pagination.total++
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val.page
- pagination.pageSize = val.limit
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/salesManagement/deliveryLedger/index.vue b/src/views/salesManagement/deliveryLedger/index.vue
deleted file mode 100644
index b10c80e..0000000
--- a/src/views/salesManagement/deliveryLedger/index.vue
+++ /dev/null
@@ -1,312 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="閿�鍞鍗曞彿锛�">
- <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="杞︾墝鍙凤細">
- <el-input v-model="searchForm.shippingCarNumber" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- </div>
- <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
- :row-key="(row) => row.id" style="width: 100%" height="calc(100vh - 18.5em)">
- <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 />
- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip />
- <el-table-column label="鍙戣揣鏃堕棿" prop="shippingDate" show-overflow-tooltip />
- <el-table-column label="鍙戣揣杞︾墝鍙�" prop="shippingCarNumber" show-overflow-tooltip />
- <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">缂栬緫</el-button>
- <el-button link type="danger" size="small" @click="handleDeleteSingle(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" />
- </div>
- <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板鍙戣揣鍙拌处' : '缂栬緫鍙戣揣鍙拌处'" width="50%"
- @close="closeDia">
- <el-form :model="form" label-width="120px" label-position="top" :rules="rules" ref="formRef">
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="閿�鍞鍗曪細" prop="salesContractNo">
- <el-select v-model="form.salesContractNo" placeholder="璇烽�夋嫨" clearable filterable
- @change="handleSalesOrderChange" style="width: 100%" :disabled="operationType === 'edit'">
- <el-option v-for="item in salesOrderOptions" :key="item.salesContractNo"
- :label="item.salesContractNo" :value="item.salesContractNo">
- {{ item.salesContractNo + ' - ' + item.customerName }}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'edit'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="鍙戣揣鏃堕棿锛�" prop="shippingDate">
- <el-date-picker style="width: 100%" v-model="form.shippingDate" 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="24">
- <el-form-item label="鍙戣揣杞︾墝鍙凤細" prop="shippingCarNumber">
- <el-input v-model="form.shippingCarNumber" 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>
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref, reactive, toRefs, getCurrentInstance } from "vue";
-import { ElMessageBox } from "element-plus";
-import {
- deliveryLedgerListPage,
- addOrUpdateDeliveryLedger,
- delDeliveryLedger,
-} from "@/api/salesManagement/deliveryLedger.js";
-
-
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const salesOrderOptions = ref([]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- salesContractNo: "", // 閿�鍞鍗曞彿
- shippingCarNumber: "", // 杞︾墝鍙�
- },
- form: {
- id: null,
- salesContractNo: "",
- customerName: "",
- shippingDate: "",
- shippingCarNumber: "",
- },
- rules: {
- salesContractNo: [{ required: true, message: "璇烽�夋嫨閿�鍞鍗�", trigger: "change" }],
- customerName: [{ required: true, message: "璇疯緭鍏ュ鎴峰悕绉�", trigger: "blur" }],
- shippingDate: [{ required: true, message: "璇烽�夋嫨鍙戣揣鏃堕棿", trigger: "change" }],
- shippingCarNumber: [{ required: true, message: "璇疯緭鍏ュ彂璐ц溅鐗屽彿", trigger: "blur" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { searchForm } = toRefs(data);
-
-
-
-// 鏌ヨ鍒楄〃
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-
-const getList = () => {
- tableLoading.value = true;
- deliveryLedgerListPage({ ...searchForm.value, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records || [];
- total.value = res.data.total || 0;
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-
-// 閿�鍞鍗曞彉鍖栨椂鑷姩濉厖瀹㈡埛鍚嶇О
-const handleSalesOrderChange = (value) => {
- const selectedOrder = salesOrderOptions.value.find(item => item.salesContractNo === value);
- if (selectedOrder) {
- form.value.customerName = selectedOrder.customerName;
- }
-};
-
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
- operationType.value = type;
- if (type === 'edit' && row) {
- form.value = {
- id: row.id ?? null,
- salesContractNo: row.salesContractNo ?? "",
- customerName: row.customerName ?? "",
- shippingDate: row.shippingDate || getCurrentDate(),
- shippingCarNumber: row.shippingCarNumber ?? "",
- };
- } else {
- form.value = {
- id: null,
- salesContractNo: "",
- customerName: "",
- shippingDate: getCurrentDate(),
- shippingCarNumber: "",
- };
- }
-
- dialogFormVisible.value = true;
-};
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- const payload = {
- id: form.value.id,
- shippingDate: form.value.shippingDate,
- shippingCarNumber: form.value.shippingCarNumber,
- };
- addOrUpdateDeliveryLedger(payload).then((res) => {
- proxy.$modal.msgSuccess("鎿嶄綔鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/shippingInfo/export", {}, "鍙戣揣鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鎵归噺鍒犻櫎
-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(() => {
- delDeliveryLedger(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鍗曚釜鍒犻櫎
-const handleDeleteSingle = (row) => {
- ElMessageBox.confirm("姝ゆ搷浣滃皢鍒犻櫎璇ヨ褰曪紝鏄惁纭锛�", "鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delDeliveryLedger([row.id]).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0");
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-
-.actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
-}
-</style>
-
diff --git a/src/views/salesManagement/indicatorStats/index.vue b/src/views/salesManagement/indicatorStats/index.vue
deleted file mode 100644
index 617ef6f..0000000
--- a/src/views/salesManagement/indicatorStats/index.vue
+++ /dev/null
@@ -1,246 +0,0 @@
-<template>
- <div class="app-container indicator-stats">
- <el-card class="box-card">
- <!-- KPI 姹囨�� -->
- <el-row :gutter="20" class="stats-row">
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #ecf5ff;">
- <el-icon :size="30" color="#409eff"><Document /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.orderCount.toLocaleString() }}</div>
- <div class="stat-label">璁㈠崟鏁伴噺</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f0f9ff;">
- <el-icon :size="30" color="#67c23a"><Tickets /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">楼{{ indicatorKpis.salesAmount.toLocaleString() }}</div>
- <div class="stat-label">閿�鍞</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #fef0f0;">
- <el-icon :size="30" color="#e6a23c"><Van /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.shipmentRate }}%</div>
- <div class="stat-label">鍙戣揣鐜�</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f4f4f5;">
- <el-icon :size="30" color="#f56c6c"><Wallet /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.collectionRate }}%</div>
- <div class="stat-label">鍥炴鐜�</div>
- </div>
- </div>
- </el-col>
- </el-row>
-
- <!-- 缁村害绛涢�� -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-select v-model="indicatorFilter.product" placeholder="浜у搧" clearable>
- <el-option label="鍏ㄩ儴浜у搧" value="" />
- <el-option label="P.O 42.5鏅�氱閰哥洂姘存偿" value="P.O 42.5鏅�氱閰哥洂姘存偿" />
- <el-option label="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" value="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" />
- <el-option label="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" value="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="indicatorFilter.customer" placeholder="瀹㈡埛" clearable>
- <el-option label="鍏ㄩ儴瀹㈡埛" value="" />
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟" />
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�" />
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="indicatorFilter.region" placeholder="鍖哄煙" clearable>
- <el-option label="鍏ㄩ儴鍖哄煙" value="" />
- <el-option label="鍗庝笢鍦板尯" value="鍗庝笢鍦板尯" />
- <el-option label="鍗庡崡鍦板尯" value="鍗庡崡鍦板尯" />
- <el-option label="鍗庡寳鍦板尯" value="鍗庡寳鍦板尯" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-date-picker v-model="indicatorFilter.dateRange" type="daterange" range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%" />
- </el-col>
- <el-col :span="24" style="text-align: right; margin-top: 10px;">
- <el-button type="primary" @click="applyIndicatorFilter">鏌ヨ</el-button>
- <el-button @click="resetIndicatorFilter">閲嶇疆</el-button>
- <el-button @click="exportIndicatorTable">瀵煎嚭鎶ヨ〃</el-button>
- <el-button @click="exportIndicatorChart">瀵煎嚭鍥捐〃</el-button>
- </el-col>
- </el-row>
-
- <!-- 鍥捐〃鍖� -->
- <div class="chart-container">
- <div ref="indicatorChartRef" style="width: 100%; height: 360px;"></div>
- </div>
-
- <!-- 涓氱哗缁熻锛堝洟闃熺淮搴︼紝鏃犱釜浜哄鍚嶏級 -->
- <el-table :data="teamPerformanceList" border stripe style="margin-top: 20px;">
- <el-table-column prop="team" label="閿�鍞洟闃�"/>
- <el-table-column prop="orderCount" label="璁㈠崟鏁�"/>
- <el-table-column prop="salesAmount" label="閿�鍞">
- <template #default="scope">楼{{ scope.row.salesAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column prop="shipmentRate" label="鍙戣揣鐜�">
- <template #default="scope">{{ scope.row.shipmentRate }}%</template>
- </el-table-column>
- <el-table-column prop="collectionRate" label="鍥炴鐜�">
- <template #default="scope">{{ scope.row.collectionRate }}%</template>
- </el-table-column>
- <el-table-column prop="attainment" label="鐩爣杈炬垚鐜�">
- <template #default="scope">
- <el-tag :type="scope.row.attainment >= 100 ? 'success' : scope.row.attainment >= 80 ? 'warning' : 'danger'">
- {{ scope.row.attainment }}%
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
-import { Document, Van, Tickets, Wallet } from '@element-plus/icons-vue'
-import * as echarts from 'echarts'
-
-const indicatorKpis = reactive({
- orderCount: 1280,
- salesAmount: 9650000,
- shipmentRate: 89.2,
- collectionRate: 76.4
-})
-
-const indicatorFilter = reactive({
- product: '',
- customer: '',
- region: '',
- dateRange: []
-})
-
-const indicatorChartRef = ref(null)
-let indicatorChart = null
-
-const teamPerformanceList = ref([
- { team: '鍗庝笢澶у尯', orderCount: 320, salesAmount: 2850000, shipmentRate: 90, collectionRate: 80, attainment: 105 },
- { team: '鍗庡寳澶у尯', orderCount: 280, salesAmount: 2150000, shipmentRate: 86, collectionRate: 73, attainment: 92 },
- { team: '鍗庡崡澶у尯', orderCount: 210, salesAmount: 1850000, shipmentRate: 88, collectionRate: 70, attainment: 78 },
- { team: '瑗垮崡澶у尯', orderCount: 180, salesAmount: 1500000, shipmentRate: 83, collectionRate: 68, attainment: 74 }
-])
-
-const initIndicatorChart = () => {
- if (!indicatorChartRef.value) return
- if (indicatorChart) indicatorChart.dispose()
- indicatorChart = echarts.init(indicatorChartRef.value)
- const option = {
- title: { text: '澶氱淮搴﹂攢鍞寚鏍囪秼鍔�', left: 'center' },
- tooltip: { trigger: 'axis' },
- legend: { data: ['璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�', '鍥炴鐜�'], top: 30 },
- grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
- xAxis: { type: 'category', data: ['2024-12', '2025-01', '2025-02', '2025-03', '2025-04', '2025-05'] },
- yAxis: [
- { type: 'value', name: '鏁伴噺/閲戦', axisLabel: { formatter: '{value}' } },
- { type: 'value', name: '姣斾緥(%)', min: 0, max: 100, axisLabel: { formatter: '{value}%' } }
- ],
- series: [
- { name: '璁㈠崟鏁�', type: 'bar', data: [180, 220, 210, 260, 205, 225], itemStyle: { color: '#409eff' } },
- { name: '閿�鍞', type: 'bar', data: [820, 950, 910, 1080, 980, 1020], itemStyle: { color: '#67c23a' } },
- { name: '鍙戣揣鐜�', type: 'line', yAxisIndex: 1, data: [86, 89, 88, 91, 87, 90], itemStyle: { color: '#e6a23c' } },
- { name: '鍥炴鐜�', type: 'line', yAxisIndex: 1, data: [72, 76, 74, 79, 75, 78], itemStyle: { color: '#f56c6c' } }
- ]
- }
- indicatorChart.setOption(option)
-}
-
-const applyIndicatorFilter = () => {
- const random = (base, delta) => {
- const v = base + Math.round((Math.random() - 0.5) * delta)
- return v < 0 ? 0 : v
- }
- indicatorKpis.orderCount = random(1280, 120)
- indicatorKpis.salesAmount = random(9650000, 350000)
- indicatorKpis.shipmentRate = (85 + Math.random() * 10).toFixed(1) * 1
- indicatorKpis.collectionRate = (70 + Math.random() * 12).toFixed(1) * 1
- setTimeout(() => initIndicatorChart(), 200)
-}
-
-const resetIndicatorFilter = () => {
- indicatorFilter.product = ''
- indicatorFilter.customer = ''
- indicatorFilter.region = ''
- indicatorFilter.dateRange = []
- applyIndicatorFilter()
-}
-
-const exportIndicatorTable = () => {
- const header = ['閿�鍞洟闃�', '璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�(%)', '鍥炴鐜�(%)', '鐩爣杈炬垚鐜�(%)']
- const rows = teamPerformanceList.value.map(r => [
- r.team,
- r.orderCount,
- r.salesAmount,
- r.shipmentRate,
- r.collectionRate,
- r.attainment
- ])
- const csv = [header, ...rows].map(r => r.join(',')).join('\n')
- const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
- const url = URL.createObjectURL(blob)
- const link = document.createElement('a')
- link.href = url
- link.download = '鎸囨爣缁熻-鍥㈤槦涓氱哗.csv'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
- URL.revokeObjectURL(url)
-}
-
-const exportIndicatorChart = () => {
- if (!indicatorChart) return
- const url = indicatorChart.getDataURL({ type: 'png', pixelRatio: 2, backgroundColor: '#fff' })
- const link = document.createElement('a')
- link.href = url
- link.download = '鎸囨爣缁熻-鍥捐〃.png'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
-}
-
-onMounted(() => {
- nextTick(() => initIndicatorChart())
-})
-</script>
-
-<style scoped>
-.indicator-stats {
- padding: 0;
-}
-.box-card { border: none; box-shadow: none; }
-.search-row { margin-bottom: 20px; }
-.stats-row { margin-bottom: 24px; }
-.stat-card { display: flex; align-items: center; padding: 20px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); }
-.stat-icon { width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 8px; margin-right: 16px; }
-.stat-content { flex: 1; }
-.stat-value { font-size: 28px; font-weight: bold; color: #303133; margin-bottom: 4px; }
-.stat-label { font-size: 14px; color: #909399; }
-.chart-container { margin: 20px 0; padding: 20px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); }
-</style>
-
-
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
deleted file mode 100644
index 8352dc6..0000000
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ /dev/null
@@ -1,445 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :inline="true" :model="searchForm">
- <el-form-item label="瀹㈡埛鍚嶇О/鍚堝悓鍙�">
- <el-input v-model="searchForm.searchText" style="width: 240px" placeholder="杈撳叆瀹㈡埛鍚嶇О/閿�鍞悎鍚屽彿鎼滅储"
- @change="handleQuery" clearable :prefix-icon="Search" />
- </el-form-item>
- <el-form-item label="寮�绁ㄦ棩鏈�">
- <el-date-picker style="width: 240px" v-model="searchForm.invoiceDate" value-format="YYYY-MM-DD"
- format="YYYY-MM-DD" type="daterange" start-placeholder="寮�濮嬫椂闂�" end-placeholder="缁撴潫鏃堕棿" clearable
- @change="changeDateRange" @clear="clearRange" />
- </el-form-item>
- <el-form-item label="褰曞叆鏃ユ湡">
- <el-date-picker style="width: 100%" v-model="searchForm.createTimeStart" value-format="YYYY-MM-DD HH:mm:ss"
- format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable @change="handleQuery" />
- </el-form-item>
- <el-form-item label="涓嶆樉绀烘湁鍙戠エ琛�">
- <el-checkbox v-model="searchForm.status" @change="handleQuery" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- <el-button @click="resetForm"> 閲嶇疆 </el-button>
- <el-button @click="handleOut" type="primary">瀵煎嚭</el-button>
- </el-form-item>
- </el-form>
- </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)">
- <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" />
- <el-table-column label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" show-overflow-tooltip width="180" />
- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip width="240" />
- <el-table-column label="椤圭洰" prop="projectName" width="320" />
- <el-table-column label="浜у搧澶х被" prop="productCategory" width="200" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="160" show-overflow-tooltip />
- <el-table-column label="鍙戠エ鍙�" prop="invoiceNo" width="200" show-overflow-tooltip />
- <el-table-column label="鍙戠エ閲戦(鍏�)" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber"
- width="200" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" show-overflow-tooltip />
- <el-table-column label="褰曞叆浜�" prop="invoicePerson" show-overflow-tooltip />
- <el-table-column label="褰曞叆鏃ユ湡" prop="createTime" show-overflow-tooltip :formatter="formatDate" width="180" />
- <el-table-column label="寮�绁ㄦ棩鏈�" prop="invoiceDate" show-overflow-tooltip width="120" />
- <el-table-column label="鍙戠エ" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right">
- <template #default="scope">
- <el-button v-if="scope.row.invoiceFileName" text bg type="primary"
- @click="handleFile(scope.row.commonFiles)">
- 鏌ョ湅闄勪欢
- </el-button>
- <el-button v-else link type="primary" @click="handleDownload(scope.row)">
- 涓婁紶
- </el-button>
- </template>
- </el-table-column>
- <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm(scope.row)">缂栬緫</el-button>
- <el-button link type="primary" size="small" @click="delInvoiceLedger(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" />
- </div>
- <el-dialog v-model="dialogFormVisible" title="寮�绁ㄥ彴璐﹂〉闈�" width="70%" @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="salesContractNo">
- <el-input v-model="form.salesContractNo" disabled></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input v-model="form.customerName" placeholder="鑷姩濉厖" clearable disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNo">
- <el-input v-model="form.invoiceNo" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item :label="`鍙戠エ閲戦(鍏�)锛� 鍚堝悓鎬婚(${form.taxInclusiveTotalPrice}鍏�)`" prop="invoiceTotal">
- <el-input-number :step="0.01" :min="0" :max="form.taxInclusiveTotalPrice" style="width: 100%" v-model="form.invoiceTotal" placeholder="璇疯緭鍏�" clearable :precision="2"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="寮�绁ㄤ汉锛�" prop="invoicePerson">
- <el-input v-model="form.invoicePerson" placeholder="璇疯緭鍏�" clearable disabled />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="寮�绁ㄦ棩鏈燂細" prop="invoiceDate">
- <el-date-picker style="width: 100%" v-model="form.invoiceDate" 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="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
- :headers="upload.headers" accept=".pdf" :limit="10" :before-upload="handleBeforeUpload"
- :on-error="handleUploadError" :on-success="handleUploadSuccess" :on-remove="handleRemove">
- <el-button type="primary">涓婁紶</el-button>
- <template #tip>
- <!-- 鏂囦欢鏍煎紡鏀寔 doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
- <div class="el-upload__tip">鏂囦欢鏍煎紡鏀寔 pdf</div>
- </template>
- </el-upload>
- </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>
- <el-dialog title="涓婁紶寮圭獥" width="50%" v-model="uploadModal">
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
- :headers="upload.headers" accept=".pdf" :limit="10" style="width: 100%" :on-exceed="handleExceed"
- :before-upload="handleBeforeUpload" :on-error="handleUploadError" :on-success="handleUploadSuccess"
- :on-remove="handleRemove">
- <el-button type="primary">涓婁紶</el-button>
- <template #tip>
- <div class="el-upload__tip">鏂囦欢鏍煎紡浠呮敮鎸� pdf</div>
- </template>
- </el-upload>
- </el-form-item>
- </el-col>
- </el-row>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="commiInvoicetFile" type="primary">纭</el-button>
- <el-button @click="uploadModal = false">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { ref } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { ElMessageBox } from "element-plus";
-import { getToken } from "@/utils/auth";
-import {
- invoiceLedgerSaveOrUpdate,
- invoiceLedgerProductInfo,
- commitFile,
- registrationProductPage,
- delInvoiceLedgerByRegProductId,
-} from "../../../api/salesManagement/invoiceLedger.js";
-import useUserStore from "@/store/modules/user.js";
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- searchText: "",
- status: false,
- invoiceDate: null,
- invoiceDateStart: undefined,
- invoiceDateEnd: undefined,
- createTimeStart: "", // 褰曞叆鏃ユ湡
- },
- form: {
- salesLedgerId: "",
- customerId: "",
- invoiceNo: "",
- invoiceTotal: "",
- taxRate: "",
- invoicePerson: "",
- invoiceDate: "",
- customerName: "",
- fileList: [],
- createTime: "", // 褰曞叆鏃ユ湡
- },
- rules: {
- salesLedgerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- invoiceNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoiceAmount: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoicePerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoiceDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerName: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm, resetForm } = useFormData(data.searchForm);
-const currentId = ref("");
-const userStore = useUserStore();
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/invoiceLedger/uploadFile",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-const matchFileType = ref(["pdf"]);
-const uploadModal = ref(false);
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-const formatDate = (row, column, cellValue) => {
- return dayjs(cellValue).format("YYYY-MM-DD HH:mm:ss");
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { invoiceDate, ...rest } = searchForm;
- registrationProductPage({ ...rest, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- total.value = res.data.total;
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, ["invoiceTotal"], {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- });
-};
-// 鎵撳紑寮规
-const openForm = (row) => {
- form.value = {};
- productData.value = [];
- fileList.value = [];
- currentId.value = row.id;
-
- invoiceLedgerProductInfo({ id: row.id }).then((res) => {
- form.value = { ...res.data };
- fileList.value = res.data.fileList;
- if (!form.value.invoicePerson) {
- form.value.invoicePerson = userStore.nickName;
- form.value.entryDate = getCurrentDate();
- }
- if (!form.value.invoiceDate) {
- form.value.invoiceDate = getCurrentDate();
- }
- });
- dialogFormVisible.value = true;
-};
-// 涓婁紶澶氫釜鏂囦欢灏辫鐩栧師鏉ョ殑
-const handleExceed = (files) => {
- proxy.$refs["fileUpload"].clearFiles();
- const file = files[0];
- file.uid = genFileId();
- proxy.$refs["fileUpload"].handleStart(file);
-};
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- console.log("file", file);
- // 鏍℃鏂囦欢澶у皬
- if (file.size > 1024 * 1024 * 10) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- return false;
- }
- // 鍒ゆ柇鏂囦欢鏍煎紡鏄惁绗﹀悎
- const fileType = file.name.split(".").pop().toLowerCase();
- if (!matchFileType.value.includes(fileType)) {
- proxy.$modal.msgError("鏂囦欢鏍煎紡涓嶅尮閰�");
- return false;
- }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- proxy.$refs["fileUpload"].handleRemove(file);
- fileList.value.push(res.data);
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- let index = fileList.value.findIndex((item) => item.url === file.url);
- if (index > -1) {
- fileList.value.splice(index, 1);
- }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- form.value.fileList = fileList.value;
- invoiceLedgerSaveOrUpdate(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/invoiceLedger/export", {}, "寮�绁ㄥ彴璐�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鎵撳紑闄勪欢涓婁紶寮圭獥
-const handleDownload = (val) => {
- fileList.value = [];
- uploadModal.value = true;
- currentId.value = val.id;
-};
-
-// 纭鏂囦欢涓婁紶
-const commiInvoicetFile = () => {
- const object = {
- fileList: fileList.value,
- id: currentId.value,
- };
- commitFile(object).then((res) => {
- if (res.code === 200) {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- uploadModal.value = false;
- }
- getList();
- currentId.value = "";
- fileList.value = [];
- });
-};
-// 鍒犻櫎寮�绁ㄥ彴璐�
-const delInvoiceLedger = (row) => {
- ElMessageBox.confirm("璇ュ彂绁ㄥ彴璐﹀皢琚垹闄�,鏄惁纭鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delInvoiceLedgerByRegProductId(row.id).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-const changeDateRange = (date) => {
- if (date) {
- searchForm.invoiceDateStart = date[0];
- searchForm.invoiceDateEnd = date[1];
- getList();
- }
-};
-
-const handleFile = (commonFiles) => {
- commonFiles.forEach((e) => {
- proxy.$download.name(e.url);
- });
-};
-
-const clearRange = () => {
- searchForm.invoiceDate = [];
- searchForm.invoiceDateStart = undefined;
- searchForm.invoiceDateEnd = undefined;
- getList();
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-</style>
diff --git a/src/views/salesManagement/invoiceRegistration/index.vue b/src/views/salesManagement/invoiceRegistration/index.vue
deleted file mode 100644
index 8bf1236..0000000
--- a/src/views/salesManagement/invoiceRegistration/index.vue
+++ /dev/null
@@ -1,686 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :inline="true" :model="searchForm">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <el-input
- v-model="searchForm.customerName"
- style="width: 240px"
- placeholder="璇疯緭鍏ュ悕绉版悳绱�"
- clearable
- :prefix-icon="Search"
- @change="handleQuery"
- />
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚堝悓鍙�">
- <el-input
- v-model="searchForm.customerContractNo"
- placeholder="璇疯緭鍏ュ鎴峰悎鍚屽彿"
- clearable
- />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О">
- <el-input
- v-model="searchForm.projectName"
- placeholder="璇疯緭鍏ラ」鐩悕绉�"
- clearable
- />
- </el-form-item>
- <el-form-item>
- <el-checkbox
- v-model="searchForm.status"
- label="涓嶆樉绀烘湭寮�绁ㄩ噾棰濅负0"
- @change="handleQuery"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- <el-button @click="resetForm"> 閲嶇疆 </el-button>
- <el-button @click="handleExport" style="margin-right: 10px">瀵煎嚭</el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div class="flex justify-between">
- <div></div>
- <div>
- <el-button type="primary" @click="openForm" style="margin-bottom: 8px">
- 鏂板鐧昏
- </el-button>
- </div>
- </div>
- <el-table
- :data="tableData"
- :border="true"
- height="calc(100vh - 21em)"
- v-loading="tableLoading"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- @selection-change="handleSelectionChange"
- >
- <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-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- width="150"
- />
- <el-table-column label="鍗曚綅" prop="unit" width="70" />
- <el-table-column label="鏁伴噺" prop="quantity" width="70" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="寮�绁ㄦ暟"
- prop="invoiceNum"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="寮�绁ㄩ噾棰�(鍏�)"
- prop="invoiceAmount"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鏈紑绁ㄦ暟"
- prop="noInvoiceNum"
- :formatter="formattedNumber"
- />
- <el-table-column
- label="鏈紑绁ㄩ噾棰�(鍏�)"
- prop="noInvoiceAmount"
- :formatter="formattedNumber"
- />
- </el-table>
- </template>
- </el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- show-overflow-tooltip
- width="200"
- />
- <el-table-column
- label="瀹㈡埛鍚堝悓鍙�"
- prop="customerContractNo"
- width="200"
- show-overflow-tooltip
- />
- <el-table-column
- label="瀹㈡埛鍚嶇О"
- prop="customerName"
- show-overflow-tooltip
- width="240"
- />
- <el-table-column label="涓氬姟鍛�" prop="salesman" show-overflow-tooltip width="90"/>
- <el-table-column
- label="椤圭洰鍚嶇О"
- prop="projectName"
- show-overflow-tooltip
- width="200"
- />
- <el-table-column
- label="鍚堝悓閲戦(鍏�)"
- prop="contractAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="220"
-
- />
- <el-table-column
- label="宸插紑绁ㄩ噾棰�(鍏�)"
- prop="invoiceTotal"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="120"
- />
- <el-table-column
- label="鏈紑绁ㄩ噾棰�(鍏�)"
- prop="noInvoiceAmountTotal"
- show-overflow-tooltip
- width="120"
- >
- <template #default="{ row, column }">
- <el-text type="danger">
- {{ formattedNumber(row, column, row.noInvoiceAmountTotal) }}
- </el-text>
- </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>
- <el-dialog
- v-model="dialogFormVisible"
- title="鏂板寮�绁ㄧ櫥璁伴〉闈�"
- width="85%"
- @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="salesContractNo">
- <el-input v-model="form.salesContractNo" disabled></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="鑷姩濉厖"
- disabled
- ></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="涓氬姟鍛橈細" prop="salesman">
- <el-input
- v-model="form.salesman"
- placeholder="鑷姩濉厖"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input
- v-model="form.projectName"
- placeholder="鑷姩濉厖"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="褰曞叆浜�" prop="createUer">
- <el-input v-model="form.createUer" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="寮�绁ㄦ棩鏈�" prop="issueDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.issueDate"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </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"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙风爜锛�" prop="invoiceNo">
- <el-input
- v-model="form.invoiceNo"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
- </el-row>
- <el-table
- :data="productData"
- border
- show-summary
- :summary-method="summarizeChildrenTable"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- width="150"
- />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" width="70" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
- <el-table-column
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber"
- width="150"
- />
- <el-table-column label="鏈寮�绁ㄦ暟" prop="currentInvoiceNum" width="180">
- <template #default="scope">
- <el-input-number :step="0.1" :min="0" style="width: 100%"
- :precision="2"
- v-model="scope.row.currentInvoiceNum"
- @change="invoiceNumBlur(scope.row)"
- ></el-input-number>
- </template>
- </el-table-column>
- <el-table-column
- label="鏈寮�绁ㄩ噾棰�(鍏�)"
- prop="currentInvoiceAmount"
- width="180"
- >
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- :precision="2"
- v-model="scope.row.currentInvoiceAmount"
- @change="invoiceAmountBlur(scope.row)"
- ></el-input-number>
- </template>
- </el-table-column>
- <el-table-column label="鏈紑绁ㄦ暟" prop="noInvoiceNum" width="120">
- <template #default="scope">
- <el-input
- type="number"
- min="0"
- disabled
- v-model="scope.row.noInvoiceNum"
- ></el-input>
- </template>
- </el-table-column>
- <el-table-column
- label="鏈紑绁ㄩ噾棰�(鍏�)"
- prop="noInvoiceAmount"
- width="200"
- >
- <template #default="scope">
- <el-input
- type="number"
- min="0"
- disabled
- v-model="scope.row.noInvoiceAmount"
- :formatter="formattedInputNumber"
- :precision="2"
- :step="0.01"
- ></el-input>
- </template>
- </el-table-column>
- <el-table-column label="鐧昏浜�" prop="register" width="100">
- <!-- <template #default="{ row }">
- <el-input
- v-model="row.register"
- placeholder="璇疯緭鍏ョ櫥璁颁汉"
- disabled
- />
- </template> -->
- </el-table-column>
- <el-table-column label="鐧昏鏃ユ湡" prop="registerDate" width="150">
- <!-- <template #default="{ row }">
- <el-date-picker
- style="width: 100%"
- v-model="row.registerDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- disabled
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { ElMessageBox } from "element-plus";
-// import {userListNoPage} from "@/api/system/user.js";
-import {
- getSalesLedgerWithProducts,
- ledgerListPage,
- productList,
-} from "@/api/salesManagement/salesLedger.js";
-import { invoiceRegistrationSave } from "@/api/salesManagement/invoiceRegistration.js";
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- customerName: "",
- status: false,
- customerContractNo: undefined, // 瀹㈡埛鍚堝悓鍙�
- projectName: undefined, // 椤圭洰鍚嶇О
- createUer: undefined, // 鐧昏浜�
- issueDate: undefined, // 寮�绁ㄦ棩鏈�
- createTime: undefined, // 褰曞叆鏃ユ湡锛�
- },
- form: {
- salesLedgerId: "",
- customerName: "",
- salesman: "",
- projectName: "",
- productData: [],
- invoiceNo: "",
- createUer: userStore.nickName,
- issueDate: dayjs().format("YYYY-MM-DD"),
- },
- rules: {
- salesLedgerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- createUer: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
- issueDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoiceNo: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
- createTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm, resetForm } = useFormData(data.searchForm);
-
-const formattedNumber = (row, column, cellValue) => {
- if (cellValue == 0) {
- return parseFloat(cellValue).toFixed(2);
- }
- if (cellValue) {
- return parseFloat(cellValue).toFixed(2);
- } else {
- return cellValue;
- }
-};
-
-const formattedInputNumber = (value) => {
- return value ? parseFloat(value).toFixed(2) : 0;
-};
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- ledgerListPage({ ...searchForm, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- total.value = res.total;
- expandedRowKeys.value = [];
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- console.log("selection", selection);
- selectedRows.value = selection.filter(
- (item) => item.salesContractNo !== undefined
- );
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, [
- "contractAmount",
- "invoiceTotal",
- "noInvoiceAmountTotal",
- ]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- "invoiceNum",
- "invoiceAmount",
- "currentInvoiceAmount",
- "noInvoiceNum",
- "noInvoiceAmount",
- "currentInvoiceNum",
- ]);
-};
-// 鎵撳紑寮规
-const openForm = () => {
- // 鍒ゆ柇鏄惁澶氶��
- if (selectedRows.value.length != 1) {
- proxy.$modal.msgError("璇烽�夋嫨涓�鏉″悎鍚�");
- return;
- }
- form.value = {};
- productData.value = [];
- getSalesLedgerWithProducts({ id: selectedRows.value[0].id }).then((res) => {
- form.value = { ...res };
- form.value.createTime = dayjs().format("YYYY-MM-DD");
- form.value.issueDate = dayjs().format("YYYY-MM-DD");
- form.value.createUer = userStore.nickName;
- productData.value = form.value.productData.map((item) => {
- return item;
- });
- dialogFormVisible.value = true;
- console.log("productData.value ", productData.value);
- });
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- form.value.productData = proxy.HaveJson(productData.value);
- invoiceRegistrationSave(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/invoiceRegistration/export", {}, "寮�绁ㄧ櫥璁颁俊鎭�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 瀵煎嚭閿�鍞彴璐�
-const handleExport = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/sales/ledger/exportOne", { ...searchForm, ...page }, "寮�绁ㄧ櫥璁�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-//鏈寮�绁ㄥけ鐒︽搷浣�
-const invoiceNumBlur = (row) => {
- if (!row.currentInvoiceNum) {
- row.currentInvoiceNum = 0;
- }
- if (row.currentInvoiceNum > row.tempNoInvoiceNum) {
- proxy.$modal.msgWarning("鏈寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
- row.currentInvoiceNum = 0;
- }
- // 璁$畻鏈寮�绁ㄩ噾棰�
- row.currentInvoiceAmount = (
- row.currentInvoiceNum * row.taxInclusiveUnitPrice
- ).toFixed(2);
- // 璁$畻鏈紑绁ㄦ暟
- row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
- 2
- );
- // 璁$畻鏈紑绁ㄩ噾棰�
- row.noInvoiceAmount = (
- row.tempnoInvoiceAmount - row.currentInvoiceAmount
- ).toFixed(2);
-};
-// 鏈寮�绁ㄩ噾棰濆け鐒︽搷浣�
-const invoiceAmountBlur = (row) => {
- if (!row.currentInvoiceAmount) {
- row.currentInvoiceAmount = 0;
- }
- // 璁$畻鏄惁瓒呰繃寮�绁ㄦ�婚噾棰�
- if (row.currentInvoiceAmount > row.tempnoInvoiceAmount) {
- proxy.$modal.msgWarning("鏈寮�绁ㄩ噾棰濅笉寰楀ぇ浜庢湭寮�绁ㄩ噾棰�");
- row.currentInvoiceAmount = 0;
- }
- // 璁$畻鏈寮�绁ㄦ暟
- row.currentInvoiceNum = (
- row.currentInvoiceAmount / row.taxInclusiveUnitPrice
- ).toFixed(2);
- console.log("row.currentInvoiceNum ", row.currentInvoiceNum);
- console.log(" row.originalNoInvoiceNum ", row.originalNoInvoiceNum);
- // 璁$畻鏈紑绁ㄦ暟
- row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed(
- 2
- );
- // 璁$畻鏈紑绁ㄩ噾棰�
- row.noInvoiceAmount = (
- row.tempnoInvoiceAmount - row.currentInvoiceAmount
- ).toFixed(2);
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-.flex {
- display: flex;
-}
-.justify-between {
- justify-content: space-between;
-}
-::v-deep(.el-checkbox__label) {
- font-weight: bold;
-}
-</style>
diff --git a/src/views/salesManagement/orderManagement/index.vue b/src/views/salesManagement/orderManagement/index.vue
deleted file mode 100644
index aac840f..0000000
--- a/src/views/salesManagement/orderManagement/index.vue
+++ /dev/null
@@ -1,495 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.orderNo"
- placeholder="璇疯緭鍏ヨ鍗曞彿"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.customer" placeholder="璇烽�夋嫨瀹㈡埛" clearable>
- <el-option label="涓婃捣绉戞妧鏈夐檺鍏徃" value="涓婃捣绉戞妧鏈夐檺鍏徃"></el-option>
- <el-option label="娣卞湷鐢靛瓙鏈夐檺鍏徃" value="娣卞湷鐢靛瓙鏈夐檺鍏徃"></el-option>
- <el-option label="鍖椾含璐告槗鍏徃" value="鍖椾含璐告槗鍏徃"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨璁㈠崟鐘舵��" clearable>
- <el-option label="寰呭鏍�" value="寰呭鏍�"></el-option>
- <el-option label="宸插鏍�" value="宸插鏍�"></el-option>
- <el-option label="宸插彂璐�" value="宸插彂璐�"></el-option>
- <el-option label="宸插畬鎴�" value="宸插畬鎴�"></el-option>
- <el-option label="宸插彇娑�" value="宸插彇娑�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button style="float: right;" type="primary" @click="handleAdd">
- 鏂板璁㈠崟
- </el-button>
- </el-col>
- </el-row>
-
- <!-- 璁㈠崟鍒楄〃 -->
- <el-table
- :data="filteredList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="id" label="ID" width="80" align="center"/>
- <el-table-column prop="orderNo" label="璁㈠崟鍙�" width="150" />
- <el-table-column prop="customer" label="瀹㈡埛鍚嶇О" />
- <el-table-column prop="salesperson" label="涓氬姟鍛�" width="100" />
- <el-table-column prop="orderDate" label="涓嬪崟鏃ユ湡" width="120" />
- <el-table-column prop="amount" label="璁㈠崟閲戦" width="120">
- <template #default="scope">
- 楼{{ scope.row.amount.toFixed(2) }}
- </template>
- </el-table-column>
- <el-table-column prop="paymentMethod" label="浠樻鏂瑰紡" width="120" />
- <el-table-column prop="status" label="璁㈠崟鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="250" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
- <el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.status === '寰呭鏍�'">缂栬緫</el-button>
- <el-button link type="primary" @click="handleReview(scope.row)" v-if="scope.row.status === '寰呭鏍�'">瀹℃牳</el-button>
- <el-button link type="primary" @click="handleTransfer(scope.row)" v-if="scope.row.status === '宸插鏍�'">杞崟</el-button>
- <el-button link type="danger" @click="handleCancel(scope.row)" v-if="scope.row.status === '寰呭鏍�'">鍙栨秷</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.currentPage"
- :limit="pagination.pageSize"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
- <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%">
- <el-option label="涓婃捣绉戞妧鏈夐檺鍏徃" value="涓婃捣绉戞妧鏈夐檺鍏徃"></el-option>
- <el-option label="娣卞湷鐢靛瓙鏈夐檺鍏徃" value="娣卞湷鐢靛瓙鏈夐檺鍏徃"></el-option>
- <el-option label="鍖椾含璐告槗鍏徃" value="鍖椾含璐告槗鍏徃"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓氬姟鍛�" prop="salesperson">
- <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%">
- <el-option label="闄堝織寮�" value="闄堝織寮�"></el-option>
- <el-option label="鍒橀泤濠�" value="鍒橀泤濠�"></el-option>
- <el-option label="鐜嬪缓鍥�" value="鐜嬪缓鍥�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁㈠崟鏃ユ湡" prop="orderDate">
- <el-date-picker
- v-model="form.orderDate"
- type="date"
- placeholder="閫夋嫨璁㈠崟鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁㈠崟閲戦" prop="amount">
- <el-input-number v-model="form.amount" :precision="2" :min="0" style="width: 100%"></el-input-number>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
- <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%">
- <el-option label="鍏ㄦ鍒颁粯" value="鍏ㄦ鍒颁粯"></el-option>
- <el-option label="鍒嗘湡浠樻" value="鍒嗘湡浠樻"></el-option>
- <el-option label="鏈堢粨" value="鏈堢粨"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="璁㈠崟鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option label="寰呭鏍�" value="寰呭鏍�"></el-option>
- <el-option label="宸插鏍�" value="宸插鏍�"></el-option>
- <el-option label="宸插彂璐�" value="宸插彂璐�"></el-option>
- <el-option label="宸插畬鎴�" value="宸插畬鎴�"></el-option>
- <el-option label="宸插彇娑�" value="宸插彇娑�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞" prop="remark">
- <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 璁㈠崟瀹℃牳瀵硅瘽妗� -->
- <el-dialog v-model="reviewDialogVisible" title="璁㈠崟瀹℃牳" width="500px">
- <el-form label-width="100px">
- <el-form-item label="璁㈠崟鍙�">
- <span>{{ currentOrder.orderNo }}</span>
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚嶇О">
- <span>{{ currentOrder.customer }}</span>
- </el-form-item>
- <el-form-item label="璁㈠崟閲戦">
- <span>楼{{ currentOrder.amount.toFixed(2) }}</span>
- </el-form-item>
- <el-form-item label="瀹℃牳缁撴灉" prop="reviewResult">
- <el-radio-group v-model="reviewResult">
- <el-radio label="閫氳繃">閫氳繃</el-radio>
- <el-radio label="鎷掔粷">鎷掔粷</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="瀹℃牳鎰忚" prop="reviewComment">
- <el-input type="textarea" v-model="reviewComment" rows="3" placeholder="璇疯緭鍏ュ鏍告剰瑙�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="reviewDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="saveReview">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 璁㈠崟杞崟瀵硅瘽妗� -->
- <el-dialog v-model="transferDialogVisible" title="璁㈠崟杞崟" width="500px">
- <el-form label-width="100px">
- <el-form-item label="璁㈠崟鍙�">
- <span>{{ currentOrder.orderNo }}</span>
- </el-form-item>
- <el-form-item label="褰撳墠涓氬姟鍛�">
- <span>{{ currentOrder.salesperson }}</span>
- </el-form-item>
- <el-form-item label="杞崟缁�" prop="newSalesperson">
- <el-select v-model="newSalesperson" placeholder="璇烽�夋嫨鏂颁笟鍔″憳" style="width: 100%">
- <el-option label="闄堝織寮�" value="闄堝織寮�"></el-option>
- <el-option label="鍒橀泤濠�" value="鍒橀泤濠�"></el-option>
- <el-option label="鐜嬪缓鍥�" value="鐜嬪缓鍥�"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="杞崟鍘熷洜" prop="transferReason">
- <el-input type="textarea" v-model="transferReason" rows="3" placeholder="璇疯緭鍏ヨ浆鍗曞師鍥�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="transferDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="saveTransfer">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- orderNo: '',
- customer: '',
- status: ''
-})
-
-const orderList = ref([
- {
- id: 1,
- orderNo: 'ORD202312001',
- customer: '涓婃捣绉戞妧鏈夐檺鍏徃',
- salesperson: '闄堝織寮�',
- orderDate: '2023-12-01',
- amount: 50000.00,
- paymentMethod: '鍏ㄦ鍒颁粯',
- status: '寰呭鏍�',
- remark: '閲嶈瀹㈡埛璁㈠崟'
- },
- {
- id: 2,
- orderNo: 'ORD202312002',
- customer: '娣卞湷鐢靛瓙鏈夐檺鍏徃',
- salesperson: '鍒橀泤濠�',
- orderDate: '2023-12-02',
- amount: 35000.00,
- paymentMethod: '鍒嗘湡浠樻',
- status: '宸插鏍�',
- remark: '甯歌璁㈠崟'
- },
- {
- id: 3,
- orderNo: 'ORD202312003',
- customer: '鍖椾含璐告槗鍏徃',
- salesperson: '鐜嬪缓鍥�',
- orderDate: '2023-12-03',
- amount: 28000.00,
- paymentMethod: '鏈堢粨',
- status: '宸插彂璐�',
- remark: '鏂板鎴疯鍗�'
- }
-])
-
-const pagination = reactive({
- total: 3,
- currentPage: 1,
- pageSize: 10
-})
-
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板璁㈠崟')
-const form = reactive({
- customer: '',
- salesperson: '',
- orderDate: '',
- amount: 0,
- paymentMethod: '',
- status: '寰呭鏍�',
- remark: ''
-})
-
-const rules = {
- customer: [{ required: true, message: '璇烽�夋嫨瀹㈡埛', trigger: 'change' }],
- salesperson: [{ required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'change' }],
- orderDate: [{ required: true, message: '璇烽�夋嫨璁㈠崟鏃ユ湡', trigger: 'change' }],
- amount: [{ required: true, message: '璇疯緭鍏ヨ鍗曢噾棰�', trigger: 'blur' }],
- paymentMethod: [{ required: true, message: '璇烽�夋嫨浠樻鏂瑰紡', trigger: 'change' }],
- status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
-
-const isEdit = ref(false)
-const editId = ref(null)
-const reviewDialogVisible = ref(false)
-const transferDialogVisible = ref(false)
-const currentOrder = ref({})
-const reviewResult = ref('')
-const reviewComment = ref('')
-const newSalesperson = ref('')
-const transferReason = ref('')
-const formRef = ref()
-
-// 璁$畻灞炴��
-const filteredList = computed(() => {
- let list = orderList.value
- if (searchForm.orderNo) {
- list = list.filter(item => item.orderNo.includes(searchForm.orderNo))
- }
- if (searchForm.customer) {
- list = list.filter(item => item.customer === searchForm.customer)
- }
- if (searchForm.status) {
- list = list.filter(item => item.status === searchForm.status)
- }
- return list
-})
-
-// 鏂规硶
-const getStatusType = (status) => {
- const statusMap = {
- '寰呭鏍�': 'warning',
- '宸插鏍�': 'primary',
- '宸插彂璐�': 'success',
- '宸插畬鎴�': 'success',
- '宸插彇娑�': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-const handleSearch = () => {
- // 鎼滅储閫昏緫宸插湪computed涓鐞�
-}
-
-const resetSearch = () => {
- searchForm.orderNo = ''
- searchForm.customer = ''
- searchForm.status = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板璁㈠崟'
- isEdit.value = false
- form.customer = ''
- form.salesperson = ''
- form.orderDate = ''
- form.amount = 0
- form.paymentMethod = ''
- form.status = '寰呭鏍�'
- form.remark = ''
- dialogVisible.value = true
-}
-
-const handleView = (row) => {
- // 鏌ョ湅璁㈠崟璇︽儏
- ElMessage.info('鏌ョ湅璁㈠崟璇︽儏鍔熻兘寰呭疄鐜�')
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫璁㈠崟'
- isEdit.value = true
- editId.value = row.id
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handleReview = (row) => {
- currentOrder.value = row
- reviewResult.value = ''
- reviewComment.value = ''
- reviewDialogVisible.value = true
-}
-
-const handleTransfer = (row) => {
- currentOrder.value = row
- newSalesperson.value = ''
- transferReason.value = ''
- transferDialogVisible.value = true
-}
-
-const handleCancel = (row) => {
- ElMessageBox.confirm('纭鍙栨秷璇ヨ鍗曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = orderList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- orderList.value[index].status = '宸插彇娑�'
- ElMessage.success('璁㈠崟宸插彇娑�')
- }
- })
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ヨ鍗曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = orderList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- orderList.value.splice(index, 1)
- pagination.total--
- ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const saveReview = () => {
- if (!reviewResult.value) {
- ElMessage.warning('璇烽�夋嫨瀹℃牳缁撴灉')
- return
- }
-
- const index = orderList.value.findIndex(item => item.id === currentOrder.value.id)
- if (index > -1) {
- if (reviewResult.value === '閫氳繃') {
- orderList.value[index].status = '宸插鏍�'
- ElMessage.success('璁㈠崟瀹℃牳閫氳繃')
- } else {
- orderList.value[index].status = '宸插彇娑�'
- ElMessage.success('璁㈠崟瀹℃牳鎷掔粷')
- }
- reviewDialogVisible.value = false
- }
-}
-
-const saveTransfer = () => {
- if (!newSalesperson.value) {
- ElMessage.warning('璇烽�夋嫨鏂颁笟鍔″憳')
- return
- }
-
- const index = orderList.value.findIndex(item => item.id === currentOrder.value.id)
- if (index > -1) {
- orderList.value[index].salesperson = newSalesperson.value
- ElMessage.success('璁㈠崟杞崟鎴愬姛')
- transferDialogVisible.value = false
- }
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (isEdit.value) {
- // 缂栬緫
- const index = orderList.value.findIndex(item => item.id === editId.value)
- if (index > -1) {
- orderList.value[index] = { ...form, id: editId.value }
- ElMessage.success('缂栬緫鎴愬姛')
- }
- } else {
- // 鏂板
- const newId = Math.max(...orderList.value.map(item => item.id)) + 1
- const orderNo = `ORD${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}${String(newId).padStart(3, '0')}`
- orderList.value.push({
- ...form,
- id: newId,
- orderNo: orderNo
- })
- pagination.total++
- ElMessage.success('鏂板鎴愬姛')
- }
- dialogVisible.value = false
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val.page
- pagination.pageSize = val.limit
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/salesManagement/paymentShipping/index.vue b/src/views/salesManagement/paymentShipping/index.vue
deleted file mode 100644
index 0bcfd87..0000000
--- a/src/views/salesManagement/paymentShipping/index.vue
+++ /dev/null
@@ -1,508 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.orderNo"
- placeholder="璇疯緭鍏ヨ鍗曞彿"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.paymentStatus" placeholder="璇烽�夋嫨浠樻鐘舵��" clearable>
- <el-option label="鏈粯娆�" value="鏈粯娆�"></el-option>
- <el-option label="宸蹭粯娆�" value="宸蹭粯娆�"></el-option>
- <el-option label="閮ㄥ垎浠樻" value="閮ㄥ垎浠樻"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.shippingStatus" placeholder="璇烽�夋嫨鍙戣揣鐘舵��" clearable>
- <el-option label="寰呭彂璐�" value="寰呭彂璐�"></el-option>
- <el-option label="宸插彂璐�" value="宸插彂璐�"></el-option>
- <el-option label="宸茬鏀�" value="宸茬鏀�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button style="float: right;" type="primary" @click="handleAdd">
- 鏂板璁板綍
- </el-button>
- </el-col>
- </el-row>
-
- <!-- 鏀粯涓庡彂璐у垪琛� -->
- <el-table
- :data="recordList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="id" label="ID" width="80" align="center"/>
- <el-table-column prop="orderNo" label="璁㈠崟鍙�" />
- <el-table-column prop="customer" label="瀹㈡埛鍚嶇О" />
- <el-table-column prop="orderAmount" label="璁㈠崟閲戦" width="120">
- <template #default="scope">
- 楼{{ scope.row.orderAmount }}
- </template>
- </el-table-column>
- <el-table-column prop="orderAmount" label="宸蹭粯娆鹃噾棰�" width="120">
- <template #default="scope">
- 楼{{ scope.row.paidAmount }}
- </template>
- </el-table-column>
- <el-table-column prop="paymentMethod" label="浠樻鏂瑰紡" width="120" />
- <el-table-column prop="paymentStatus" label="浠樻鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getPaymentStatusType(scope.row.paymentStatus)">
- {{ scope.row.paymentStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="shippingStatus" label="鍙戣揣鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getShippingStatusType(scope.row.shippingStatus)">
- {{ scope.row.shippingStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="shippingDate" label="鍙戣揣鏃ユ湡" width="120" />
- <el-table-column label="鎿嶄綔" width="250" fixed="right" align="center">
- <template #default="scope">
-<!-- <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>-->
- <el-button link type="primary" @click="handlePayment(scope.row)" v-if="scope.row.paymentStatus !== '宸蹭粯娆�'">浠樻</el-button>
- <el-button link type="primary" @click="handleShipping(scope.row)" v-if="scope.row.paymentStatus === '宸蹭粯娆�' && scope.row.shippingStatus === '寰呭彂璐�'">鍙戣揣</el-button>
- <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.current"
- :limit="pagination.size"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁㈠崟鍙�" prop="orderNo">
- <el-input v-model="form.orderNo" placeholder="璇疯緭鍏ヨ鍗曞彿" disabled></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
- <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%">
- <el-option label="涓婃捣绉戞妧鏈夐檺鍏徃" value="涓婃捣绉戞妧鏈夐檺鍏徃"></el-option>
- <el-option label="娣卞湷鐢靛瓙鏈夐檺鍏徃" value="娣卞湷鐢靛瓙鏈夐檺鍏徃"></el-option>
- <el-option label="鍖椾含璐告槗鍏徃" value="鍖椾含璐告槗鍏徃"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="璁㈠崟閲戦" prop="orderAmount">
- <el-input-number v-model="form.orderAmount" :precision="2" :min="0" style="width: 100%"></el-input-number>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
- <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%">
- <el-option label="鍏ㄦ鍒颁粯" value="鍏ㄦ鍒颁粯"></el-option>
- <el-option label="鍒嗘湡浠樻" value="鍒嗘湡浠樻"></el-option>
- <el-option label="鏈堢粨" value="鏈堢粨"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浠樻鐘舵��" prop="paymentStatus">
- <el-select v-model="form.paymentStatus" placeholder="璇烽�夋嫨浠樻鐘舵��" style="width: 100%">
- <el-option label="鏈粯娆�" value="鏈粯娆�"></el-option>
- <el-option label="宸蹭粯娆�" value="宸蹭粯娆�"></el-option>
- <el-option label="閮ㄥ垎浠樻" value="閮ㄥ垎浠樻"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戣揣鐘舵��" prop="shippingStatus">
- <el-select v-model="form.shippingStatus" placeholder="璇烽�夋嫨鍙戣揣鐘舵��" style="width: 100%">
- <el-option label="寰呭彂璐�" value="寰呭彂璐�"></el-option>
- <el-option label="宸插彂璐�" value="宸插彂璐�"></el-option>
- <el-option label="宸茬鏀�" value="宸茬鏀�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍙戣揣鏃ユ湡" prop="shippingDate">
- <el-date-picker
- v-model="form.shippingDate"
- type="date"
- placeholder="閫夋嫨鍙戣揣鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐗╂祦鍗曞彿" prop="trackingNo">
- <el-input v-model="form.trackingNo" placeholder="璇疯緭鍏ョ墿娴佸崟鍙�"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="澶囨敞" prop="remark">
- <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 浠樻瀵硅瘽妗� -->
- <el-dialog v-model="paymentDialogVisible" title="璁㈠崟浠樻" width="500px">
- <el-form label-width="100px">
- <el-form-item label="璁㈠崟鍙�">
- <span>{{ currentRecord.orderNo }}</span>
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚嶇О">
- <span>{{ currentRecord.customer }}</span>
- </el-form-item>
- <el-form-item label="璁㈠崟閲戦">
- <span>楼{{ currentRecord.orderAmount }}</span>
- </el-form-item>
- <el-form-item label="浠樻閲戦" prop="paymentAmount">
- <el-input-number v-model="paymentAmount" :precision="2" :min="0" :max="currentRecord.orderAmount" style="width: 100%"></el-input-number>
- </el-form-item>
- <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
- <el-select v-model="paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%">
- <el-option label="鐜伴噾" value="鐜伴噾"></el-option>
- <el-option label="閾惰杞处" value="閾惰杞处"></el-option>
- <el-option label="鏀粯瀹�" value="鏀粯瀹�"></el-option>
- <el-option label="寰俊鏀粯" value="寰俊鏀粯"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="浠樻澶囨敞" prop="paymentRemark">
- <el-input type="textarea" v-model="paymentRemark" rows="3" placeholder="璇疯緭鍏ヤ粯娆惧娉�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="paymentDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="savePayment">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鍙戣揣瀵硅瘽妗� -->
- <el-dialog v-model="shippingDialogVisible" title="璁㈠崟鍙戣揣" width="500px">
- <el-form label-width="100px">
- <el-form-item label="璁㈠崟鍙�">
- <span>{{ currentRecord.orderNo }}</span>
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚嶇О">
- <span>{{ currentRecord.customer }}</span>
- </el-form-item>
- <el-form-item label="鍙戣揣鏃ユ湡" prop="shippingDate">
- <el-date-picker
- v-model="shippingDate"
- type="date"
- placeholder="閫夋嫨鍙戣揣鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- <el-form-item label="鐗╂祦鍏徃" prop="logisticsCompany">
- <el-select v-model="logisticsCompany" placeholder="璇烽�夋嫨鐗╂祦鍏徃" style="width: 100%">
- <el-option label="椤轰赴閫熻繍" value="椤轰赴閫熻繍"></el-option>
- <el-option label="鍦嗛�氶�熼��" value="鍦嗛�氶�熼��"></el-option>
- <el-option label="涓�氬揩閫�" value="涓�氬揩閫�"></el-option>
- <el-option label="鐢抽�氬揩閫�" value="鐢抽�氬揩閫�"></el-option>
- <el-option label="闊佃揪閫熼��" value="闊佃揪閫熼��"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="鐗╂祦鍗曞彿" prop="trackingNo">
- <el-input v-model="trackingNo" placeholder="璇疯緭鍏ョ墿娴佸崟鍙�"></el-input>
- </el-form-item>
- <el-form-item label="鍙戣揣澶囨敞" prop="shippingRemark">
- <el-input type="textarea" v-model="shippingRemark" rows="3" placeholder="璇疯緭鍏ュ彂璐у娉�"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="shippingDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="saveShipping">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed,onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Plus, Search } from '@element-plus/icons-vue'
-import {listPage,add,update,deletePaymentShipping} from "@/api/salesManagement/paymentShipping.js"
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-const total = ref(0)
-onMounted(() => {
- getList()
-})
-
-const getList = () => {
- loading.value = true
- listPage({...searchForm,...pagination}).then(res => {
- if(res.code === 200){
- recordList.value = res.data.records
- total.value = res.data.total
- loading.value = false
- console.log(recordList.value)
- }
- })
-}
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- orderNo: '',
- paymentStatus: '',
- shippingStatus: ''
-})
-
-const recordList = ref([])
-
-const pagination = reactive({
- current: 1,
- size: 10
-})
-
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板璁板綍')
-const form = reactive({
- orderNo: '',
- customer: '',
- orderAmount: 0,
- paymentMethod: '',
- paymentStatus: '鏈粯娆�',
- shippingStatus: '寰呭彂璐�',
- shippingDate: '',
- trackingNo: '',
- remark: ''
-})
-
-const rules = {
- // orderNo: [{ required: true, message: '璇疯緭鍏ヨ鍗曞彿', trigger: 'blur' }],
- customer: [{ required: true, message: '璇烽�夋嫨瀹㈡埛', trigger: 'change' }],
- orderAmount: [{ required: true, message: '璇疯緭鍏ヨ鍗曢噾棰�', trigger: 'blur' }],
- paymentMethod: [{ required: true, message: '璇烽�夋嫨浠樻鏂瑰紡', trigger: 'change' }],
- paymentStatus: [{ required: true, message: '璇烽�夋嫨浠樻鐘舵��', trigger: 'change' }],
- shippingStatus: [{ required: true, message: '璇烽�夋嫨鍙戣揣鐘舵��', trigger: 'change' }]
-}
-
-const isEdit = ref(false)
-const editId = ref(null)
-const paymentDialogVisible = ref(false)
-const shippingDialogVisible = ref(false)
-const currentRecord = ref({})
-const paymentAmount = ref(0)
-const paymentMethod = ref('')
-const paymentRemark = ref('')
-const shippingDate = ref('')
-const logisticsCompany = ref('')
-const trackingNo = ref('')
-const shippingRemark = ref('')
-const formRef = ref()
-
-// 鏂规硶
-const getPaymentStatusType = (status) => {
- const statusMap = {
- '鏈粯娆�': 'danger',
- '宸蹭粯娆�': 'success',
- '閮ㄥ垎浠樻': 'warning'
- }
- return statusMap[status] || 'info'
-}
-
-const getShippingStatusType = (status) => {
- const statusMap = {
- '寰呭彂璐�': 'warning',
- '宸插彂璐�': 'primary',
- '宸茬鏀�': 'success'
- }
- return statusMap[status] || 'info'
-}
-
-const handleSearch = () => {
- // 鎼滅储閫昏緫宸插湪computed涓鐞�
- getList()
-}
-
-const resetSearch = () => {
- searchForm.orderNo = ''
- searchForm.paymentStatus = ''
- searchForm.shippingStatus = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板璁板綍'
- isEdit.value = false
- form.orderNo = ''
- form.customer = ''
- form.orderAmount = 0
- form.paymentMethod = ''
- form.paymentStatus = '鏈粯娆�'
- form.shippingStatus = '寰呭彂璐�'
- form.shippingDate = ''
- form.trackingNo = ''
- form.remark = ''
- dialogVisible.value = true
-}
-
-const handleView = (row) => {
- // 鏌ョ湅璁板綍璇︽儏
- ElMessage.info('鏌ョ湅璁板綍璇︽儏鍔熻兘寰呭疄鐜�')
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫璁板綍'
- isEdit.value = true
- editId.value = row.id
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handlePayment = (row) => {
- currentRecord.value = row
- paymentAmount.value = row.orderAmount - row.paidAmount
- paymentMethod.value = ''
- paymentRemark.value = ''
- paymentDialogVisible.value = true
-}
-
-const handleShipping = (row) => {
- currentRecord.value = row
- shippingDate.value = ''
- logisticsCompany.value = ''
- trackingNo.value = ''
- shippingRemark.value = ''
- shippingDialogVisible.value = true
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ヨ褰曞悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- deletePaymentShipping(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- }
- })
- })
-}
-
-const savePayment = () => {
- if (!paymentMethod.value) {
- ElMessage.warning('璇烽�夋嫨浠樻鏂瑰紡')
- return
- }
- currentRecord.value.paidAmount = Number(currentRecord.value.paidAmount) + paymentAmount.value
- if(currentRecord.value.paidAmount == currentRecord.value.orderAmount){
- currentRecord.value.paymentStatus = '宸蹭粯娆�'
- }else{
- currentRecord.value.paymentStatus = '閮ㄥ垎浠樻'
- }
- update(currentRecord.value).then(res => {
- if(res.code === 200){
- ElMessage.success('浠樻淇℃伅宸蹭繚瀛�')
- paymentDialogVisible.value = false
- getList()
- }
- })
-
-}
-
-const saveShipping = () => {
- if (!shippingDate.value || !logisticsCompany.value || !trackingNo.value) {
- ElMessage.warning('璇峰~鍐欏畬鏁寸殑鍙戣揣淇℃伅')
- return
- }
- currentRecord.value.shippingStatus = '宸插彂璐�'
- update(currentRecord.value).then(res => {
- if(res.code === 200){
- ElMessage.success('鍙戣揣淇℃伅宸蹭繚瀛�')
- shippingDialogVisible.value = false
- getList()
- }
- })
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (isEdit.value) {
- // 缂栬緫
- update(form).then(res => {
- if(res.code === 200){
- ElMessage.success('缂栬緫鎴愬姛')
- getList()
- }
- })
- } else {
- // 鏂板
- add(form).then(res => {
- if(res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- getList()
- }
- })
- }
- dialogVisible.value = false
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.current = val.page
- pagination.size = val.limit
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/salesManagement/receiptPayment/index.vue b/src/views/salesManagement/receiptPayment/index.vue
deleted file mode 100644
index 26f089b..0000000
--- a/src/views/salesManagement/receiptPayment/index.vue
+++ /dev/null
@@ -1,641 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :inline="true" :model="searchForm" style="width: 100%">
- <el-row justify="space-between">
- <el-col :span="24">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <el-input
- v-model="searchForm.customerName"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚堝悓鍙�">
- <el-input
- v-model="searchForm.customerContractNo"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О">
- <el-input
- v-model="searchForm.projectName"
- placeholder="璇疯緭鍏�"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item>
- <el-checkbox
- v-model="searchForm.status"
- label="涓嶆樉绀哄緟鍥炴涓�0"
- @change="handleQuery"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
- <div class="table_list">
- <div class="actions">
- <div></div>
- <div>
- <el-button type="primary" @click="openForm('add')">
- 鏂板鍥炴
- </el-button>
- <el-button icon="Download" @click="handleOut"> 瀵煎嚭 </el-button>
- </div>
- </div>
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- :expand-row-keys="expandedRowKeys"
- @expand-change="expandChange"
-
- height="calc(100vh - 21.5em)"
- >
- <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-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column label="鍥炴鏃ユ湡" prop="receiptPaymentDate" width="130"/>
- <el-table-column label="鍥炴閲戦" prop="receiptPaymentAmount">
- <template #default="scope">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- v-model="scope.row.receiptPaymentAmount"
- :disabled="!scope.row.editType"
- :precision="2"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </template>
- </el-table-column>
- <el-table-column label="鍥炴鏂瑰紡" prop="receiptPaymentType">
- <template #default="scope">
- <el-select
- v-model="scope.row.receiptPaymentType"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="!scope.row.editType"
- >
- <el-option
- v-for="item in receipt_payment_type"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </template>
- </el-table-column>
- <el-table-column label="鐧昏浜�" prop="registrant" width="90"/>
- <el-table-column label="鐧昏鏃ユ湡" prop="createTime" width="130"/>
- <el-table-column label="鎿嶄綔" width="150" align="center">
- <template #default="scope">
- <el-button
- link
- type="primary"
- size="small"
- @click="changeEditType(scope.row)"
- v-if="!scope.row.editType"
- >缂栬緫</el-button
- >
- <el-button
- link
- type="primary"
- size="small"
- @click="saveReceiptPayment(scope.row)"
- v-if="scope.row.editType"
- >淇濆瓨</el-button
- >
- <el-button
- link
- type="primary"
- size="small"
- @click="delReceiptRecord(scope.row)"
- >鍒犻櫎</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- </template>
- </el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- show-overflow-tooltip
- width="240"
- />
- <el-table-column
- label="瀹㈡埛鍚堝悓鍙�"
- prop="customerContractNo"
- show-overflow-tooltip
- width="240"
-
- />
- <el-table-column
- label="瀹㈡埛鍚嶇О"
- prop="customerName"
- show-overflow-tooltip
- width="240"
- />
- <el-table-column
- label="椤圭洰鍚嶇О"
- prop="projectName"
- show-overflow-tooltip
- width="340"
- />
- <el-table-column
- label="鍥炴鐘舵��"
- prop="statusName"
- width="120"
- >
- <template #default="{ row }">
- <el-tag :type="getStatusTagType(row.statusName)" disable-transitions>
- {{ row.statusName || "--" }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="浜у搧澶х被"
- prop="productCategory"
- show-overflow-tooltip
- width="100"
- />
- <el-table-column
- label="鍙戠エ鍙�"
- prop="invoiceNo"
- show-overflow-tooltip
- width="200"
- />
- <el-table-column
- label="鍙戠エ閲戦(鍏�)"
- prop="invoiceTotal"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column label="绋庣巼(%)" prop="taxRate" show-overflow-tooltip />
- <el-table-column
- label="鍥炴閲戦(鍏�)"
- prop="receiptPaymentAmountTotal"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="寰呭洖娆鹃噾棰�(鍏�)"
- prop="noReceiptAmount"
- show-overflow-tooltip
- width="200"
- >
- <template #default="{ row, column }">
- <el-text type="danger">
- {{ formattedNumber(row, column, row.noReceiptAmount) }}
- </el-text>
- </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>
- <el-dialog
- v-model="dialogFormVisible"
- title="鏂板鍥炴椤甸潰"
- width="70%"
- @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="salesContractNo">
- <el-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerName">
- <el-input
- v-model="form.customerName"
- placeholder="鑷姩濉厖"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ鍙凤細" prop="invoiceNo">
- <el-input
- v-model="form.invoiceNo"
- placeholder="鑷姩濉厖"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceTotal">
- <el-input
- type="number"
- v-model="form.invoiceTotal"
- placeholder="鑷姩濉厖"
- :step="0.01"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="绋庣巼锛�" prop="taxRate">
- <el-input
- type="number"
- v-model="form.taxRate"
- placeholder="鑷姩濉厖"
- :step="0.01"
- disabled
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈鍥炴閲戦锛�" prop="receiptPaymentAmount">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
- :precision="2"
- v-model="form.receiptPaymentAmount"
- placeholder="璇疯緭鍏�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍥炴褰㈠紡锛�" prop="receiptPaymentType">
- <el-select
- v-model="form.receiptPaymentType"
- placeholder="璇烽�夋嫨"
- clearable
- >
- <el-option
- v-for="item in receipt_payment_type"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍥炴鏃ユ湡锛�" prop="receiptPaymentDate">
- <el-date-picker
- style="width: 100%"
- v-model="form.receiptPaymentDate"
- 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="registrant">
- <el-input
- v-model="form.registrant"
- placeholder="璇疯緭鍏�"
- clearable
- disabled
- />
- </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>
- </div>
-</template>
-
-<script setup>
-import pagination from "@/components/PIMTable/Pagination.vue";
-import { onMounted, ref } from "vue";
-import {
- receiptPaymentSaveOrUpdate,
- bindInvoiceNoRegPage,
- invoiceInfo,
- receiptPaymentHistoryListNoPage,
- receiptPaymentDel,
-} from "../../../api/salesManagement/receiptPayment.js";
-import useUserStore from "@/store/modules/user";
-import { ElMessage, ElMessageBox } from "element-plus";
-import useFormData from "@/hooks/useFormData";
-
-const userStore = useUserStore();
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const expandedRowKeys = ref([]);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- searchText: "",
- status: true,
- customerName: "",
- customerContractNo: "",
- projectName: "",
- },
- form: {
- salesContractNo: "",
- customerName: "",
- invoiceNo: "",
- invoiceTotal: "",
- taxRate: "",
- receiptPaymentAmount: "",
- receiptPaymentType: "",
- registrant: "",
- receiptPaymentDate: "",
- },
- rules: {
- salesContractNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- invoiceNo: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- invoiceTotal: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- receiptPaymentAmount: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- receiptPaymentType: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- registrant: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- receiptPaymentDate: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm, resetForm } = useFormData(data.searchForm);
-const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
-
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-
-const getStatusTagType = (statusName = '') => {
- const normalized = statusName.trim();
- if (!normalized) return 'info';
- return normalized === '鏈畬鎴愬洖娆�' ? 'danger' : 'success';
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- bindInvoiceNoRegPage({ ...searchForm, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- total.value = res.data.total;
- if (expandedRowKeys.value.length > 0) {
- const arr = []
- const index = tableData.value.findIndex(item => item.id === expandedRowKeys.value[0]);
- if (index > -1) {
- arr.push(tableData.value[index]);
- expandChange(tableData.value[index], arr)
- }
- }
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- receiptPaymentHistoryListNoPage({
- invoiceLedgerId: row.id,
- type: 1,
- }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- if (res?.length > 0) {
- res.forEach((item) => {
- item.editType = false;
- });
- }
- tableData.value[index].children = res;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- console.log("selection", selection);
- selectedRows.value = selection.filter(
- (item) => item.customerContractNo !== null
- );
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- ["invoiceTotal", "receiptPaymentAmountTotal", "noReceiptAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(param, ["receiptPaymentAmount"]);
-};
-// 鎵撳紑寮规
-const openForm = () => {
- form.value = {};
- if (selectedRows.value.length !== 1) {
- proxy.$modal.msgError("璇烽�夋嫨涓�鏉℃暟鎹�");
- return;
- }
- if (selectedRows.value[0].noReceiptAmount == 0) {
- proxy.$modal.msgWarning("鏃犻渶鍐嶅洖娆�");
- return;
- }
- invoiceInfo({ id: selectedRows.value[0].id }).then((res) => {
- form.value = { ...res.data };
- form.value.invoiceLedgerId = form.value.id;
- form.value.id = "";
- form.value.registrant = userStore.nickName;
- });
- dialogFormVisible.value = true;
-};
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- receiptPaymentSaveOrUpdate(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-
-// 鍒犻櫎鍥炴璁板綍
-const delReceiptRecord = (row) => {
- console.log("row", row);
- ElMessageBox.confirm("纭鍒犻櫎璇ヨ褰曞悧锛�", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(async () => {
- try {
- let ids = [];
- ids.push(row.id);
- await receiptPaymentDel(ids);
- ElMessage.success("鍒犻櫎鎴愬姛");
- getList();
- } catch (error) {
- console.error("鍒犻櫎澶辫触:", error);
- ElMessage.error("鍒犻櫎澶辫触");
- }
- })
- .catch(() => {
- ElMessage.info("宸插彇娑堝垹闄�");
- });
-};
-
-// 缂栬緫淇敼鐘舵��
-const changeEditType = (row) => {
- row.editType = !row.editType;
-};
-
-// 淇濆瓨鍥炴璁板綍
-const saveReceiptPayment = (row) => {
- let updateData = {
- id: row.id,
- receiptPaymentType: row.receiptPaymentType,
- receiptPaymentAmount: row.receiptPaymentAmount,
- };
- receiptPaymentSaveOrUpdate(updateData).then((res) => {
- row.editType = !row.editType;
- getList();
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- });
-};
-
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- const ids = selectedRows.value.map((item) => item.id);
- proxy.download(
- `/receiptPayment/export`,
- { ids: `${ids}` },
- "鍥炴鐧昏妗f.xlsx"
- );
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-::v-deep(.el-checkbox__label) {
- font-weight: bold;
-}
-.actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
-}
-</style>
diff --git a/src/views/salesManagement/receiptPaymentHistory/index.vue b/src/views/salesManagement/receiptPaymentHistory/index.vue
deleted file mode 100644
index 589d567..0000000
--- a/src/views/salesManagement/receiptPaymentHistory/index.vue
+++ /dev/null
@@ -1,223 +0,0 @@
-<template>
- <div class="app-container">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="瀹㈡埛鍚嶇О">
- <el-input
- v-model="searchForm.searchText"
- placeholder="杈撳叆瀹㈡埛鍚嶇О鎼滅储"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚堝悓鍙�">
- <el-input
- v-model="searchForm.customerContractNo"
- placeholder="杈撳叆瀹㈡埛鍚堝悓鍙�"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О">
- <el-input
- v-model="searchForm.projectName"
- placeholder="杈撳叆椤圭洰鍚嶇О"
- @change="handleQuery"
- clearable
- :prefix-icon="Search"
- />
- </el-form-item>
- <el-form-item label="鍥炴鏃ユ湡">
- <el-date-picker
- v-model="searchForm.receiptPaymentDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="daterange"
- start-placeholder="寮�濮嬫椂闂�"
- end-placeholder="缁撴潫鏃堕棿"
- clearable
- style="width: 300px"
- @change="changeDateRange"
- @clear="clearRange"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- <el-button @click="handleExport">瀵煎嚭</el-button>
- </el-form-item>
- </el-form>
- <div class="table_list">
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- :isShowSummary="isShowSummarySon"
- :summaryMethod="summarizeMainTable1"
- :tableLoading="tableLoading"
- :total="page.total"
- @pagination="pagination"
- @selection-change="handleSelectionChange"
- ></PIMTable>
- </div>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, getCurrentInstance } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { receiptPaymentHistoryListPage } from "@/api/salesManagement/receiptPayment.js";
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-
-const { proxy } = getCurrentInstance();
-const tableColumn = ref([
- {
- label: "閿�鍞悎鍚屽彿",
- prop: "salesContractNo",
- width:240
- },
- {
- label: "瀹㈡埛鍚堝悓鍙�",
- prop: "customerContractNo",
- width:240
- },
- {
- label: "鍥炴鏃ユ湡",
- prop: "receiptPaymentDate",
- width:100
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width:240
- },
- {
- label: "椤圭洰鍚嶇О",
- prop: "projectName",
- width:200
- },
- {
- label: "鍥炴閲戦锛堝厓锛�",
- prop: "receiptPaymentAmount",
- width:200,
- formatData: (params) => {
- return params ? parseFloat(params).toFixed(2) : 0;
- },
- },
- {
- label: "鍥炴鏂瑰紡",
- prop: "receiptPaymentType",
- dataType: "tag",
- formatData: (params) => {
- if (params == 0) {
- return "鐢垫眹";
- } else if (params == 1) {
- return "鎵垮厬";
- } else {
- return null;
- }
- },
- formatType: (params) => {
- return "info";
- },
- },
- {
- label: "鐧昏浜�",
- prop: "registrant",
- },
- {
- label: "鐧昏鏃ユ湡",
- prop: "createTime",
- width:100
- },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
- total: 0,
-});
-const total = ref(0);
-
-const { form: searchForm } = useFormData({
- searchText: undefined,
- receiptPaymentDate: [],
- receiptPaymentDateStart: undefined,
- receiptPaymentDateEnd: undefined,
- customerContractNo: undefined,
- projectName: undefined,
-});
-const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
-const isShowSummarySon = ref(true);
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { receiptPaymentDate, ...rest } = searchForm;
- receiptPaymentHistoryListPage({ ...rest, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- page.total = res.total;
- });
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable1 = (param) => {
- return proxy.summarizeTable(param, ["receiptPaymentAmount"], {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- });
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-const changeDateRange = (date) => {
- if (date) {
- searchForm.receiptPaymentDateStart = dayjs(date[0]).format(
- "YYYY-MM-DD 00:00:00"
- );
- searchForm.receiptPaymentDateEnd = dayjs(date[1]).format(
- "YYYY-MM-DD 23:59:59"
- );
- getList();
- }
-};
-
-const clearRange = () => {
- searchForm.receiptPaymentDate = [];
- searchForm.receiptPaymentDateStart = undefined;
- searchForm.receiptPaymentDateEnd = undefined;
- getList();
-};
-
-// 瀵煎嚭
-const handleExport = () => {
- const { receiptPaymentDate, ...rest } = searchForm;
- proxy.download("/receiptPayment/exportOne", { ...rest, ...page }, "鍥炴娴佹按.xlsx");
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- margin-top: unset;
-}
-</style>
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
deleted file mode 100644
index 2cec625..0000000
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ /dev/null
@@ -1,271 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <div>
- <span class="search_title">瀹㈡埛鍚嶇О锛�</span>
- <el-input
- v-model="searchForm.searchText"
- style="width: 240px"
- placeholder="杈撳叆瀹㈡埛鍚嶇О鎼滅储"
- @change="handleQuery"
- clearable
- prefix-icon="Search"
- />
- <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
- >鎼滅储</el-button
- >
- </div>
- </div>
- <div style="display: flex">
- <div class="table_list">
- <el-table
- :data="tableData"
- border
- v-loading="tableLoading"
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable"
- @row-click="rowClickMethod"
- height="calc(100vh - 18.5em)"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column
- label="瀹㈡埛鍚嶇О"
- prop="customerName"
- show-overflow-tooltip
- width="200"
- />
- <el-table-column
- label="寮�绁ㄩ噾棰�(鍏�)"
- prop="invoiceTotal"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="鍥炴閲戦(鍏�)"
- prop="receiptPaymentAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="搴旀敹閲戦(鍏�)"
- prop="unReceiptPaymentAmount"
- show-overflow-tooltip
- width="200"
- >
- <template #default="{ row, column }">
- <el-text type="danger">
- {{ formattedNumber(row, column, row.unReceiptPaymentAmount) }}
- </el-text>
- </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 class="table_list">
- <el-table
- :data="receiptRecord"
- border
- :row-key="(row) => row.id"
- show-summary
- :summary-method="summarizeMainTable1"
- height="calc(100vh - 18.5em)"
- >
- <el-table-column
- align="center"
- label="搴忓彿"
- type="index"
- width="60"
- />
- <el-table-column
- label="鍙戠敓鏃ユ湡"
- prop="happenTime"
- show-overflow-tooltip
- width="110"
- />
- <el-table-column
- label="寮�绁ㄩ噾棰�(鍏�)"
- prop="invoiceAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="鍥炴閲戦(鍏�)"
- prop="receiptAmount"
- show-overflow-tooltip
- :formatter="formattedNumber"
- width="200"
- />
- <el-table-column
- label="搴旀敹閲戦(鍏�)"
- prop="unReceiptAmount"
- show-overflow-tooltip
- width="200"
- >
- <template #default="{ row, column }">
- <el-text type="danger">
- {{ formattedNumber(row, column, row.unReceiptAmount) }}
- </el-text>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="recordTotal > 0"
- :total="recordTotal"
- layout="total, sizes, prev, pager, next, jumper"
- :page="recordPage.current"
- :limit="recordPage.size"
- @pagination="recordPaginationChange"
- />
- </div>
- </div>
- </div>
-</template>
-
-<script setup>
-import {onMounted, ref} from "vue";
-import { invoiceLedgerSalesAccount } from "../../../api/salesManagement/invoiceLedger.js";
-import { customerInteractions } from "../../../api/salesManagement/receiptPayment.js";
-import Pagination from "../../../components/PIMTable/Pagination.vue";
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const receiptRecord = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const recordPage = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const recordTotal = ref(0);
-const data = reactive({
- searchForm: {
- searchText: "",
- invoiceDate: "",
- },
-});
-const customerId = ref("");
-const { searchForm } = toRefs(data);
-const originReceiptRecord = ref([]);
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- getList();
-};
-const paginationChange = (obj) => {
- console.log("paginationChange", current, limit);
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- invoiceLedgerSalesAccount({ ...searchForm.value, ...page }).then((res) => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- total.value = res.data.total;
- if (tableData.value.length > 0) {
- recordPage.current = 1;
- customerId.value = tableData.value[0].id;
- receiptPaymentList(customerId.value);
- }
- });
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(
- param,
- ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeMainTable1 = (param) => {
- var summarizeTable = proxy.summarizeTable(
- param,
- ["invoiceAmount", "receiptAmount", "unReceiptAmount"],
- {
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- }
- );
- // 鍙栨渶鍚庝竴琛屾暟鎹�;
- if (receiptRecord.value?.length > 0) {
- const index = tableData.value.findIndex(
- (item) => item.id == customerId.value
- );
- summarizeTable[summarizeTable.length - 1] =
- tableData.value[index].unReceiptPaymentAmount.toFixed(2);
- } else {
- summarizeTable[summarizeTable.length - 1] = 0.0;
- }
- return summarizeTable;
-};
-
-const receiptPaymentList = (id) => {
- const param = {
- customerId: id,
- };
- console.log("param", param);
- customerInteractions(param).then((res) => {
- originReceiptRecord.value = res.data;
- handlePagination({ page: 1, limit: recordPage.size });
- recordTotal.value = res.data.length;
- });
-};
-
-// 姹囨璁板綍鍒楄〃鍒嗛〉
-const recordPaginationChange = (pagination) => {
- handlePagination(pagination);
-};
-
-const rowClickMethod = (row) => {
- customerId.value = row.id;
- receiptPaymentList(customerId.value);
-};
-
-const handlePagination = ({ page, limit }) => {
- recordPage.current = page;
- recordPage.size = limit;
-
- const start = (page - 1) * limit;
- const end = start + limit;
-
- receiptRecord.value = originReceiptRecord.value.slice(start, end);
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.table_list {
- width: 50%;
-}
-</style>
diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue
deleted file mode 100644
index da37db2..0000000
--- a/src/views/salesManagement/salesLedger/fileList.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<template>
- <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
- <el-table :data="tableData" border height="40vh">
- <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">
- <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
- <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-dialog>
- <filePreview ref="filePreviewRef" />
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import filePreview from '@/components/filePreview/index.vue'
-
-const dialogVisible = ref(false)
-const tableData = ref([])
-const { proxy } = getCurrentInstance();
-const filePreviewRef = ref()
-const handleClose = () => {
- dialogVisible.value = false
-}
-const open = (list) => {
- dialogVisible.value = true
- tableData.value = list
-}
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-
-}
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-defineExpose({
- open
-})
-</script>
-
-<style></style>
\ No newline at end of file
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
deleted file mode 100644
index 94af430..0000000
--- a/src/views/salesManagement/salesLedger/index.vue
+++ /dev/null
@@ -1,1752 +0,0 @@
-<template>
- <div class="app-container">
- <div class="search_form">
- <el-form :model="searchForm" :inline="true">
- <el-form-item label="瀹㈡埛鍚嶇О锛�">
- <el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="瀹㈡埛鍚堝悓鍙凤細">
- <el-input v-model="searchForm.customerContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="閿�鍞悎鍚屽彿锛�">
- <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="椤圭洰鍚嶇О锛�">
- <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
- @change="handleQuery" />
- </el-form-item>
- <el-form-item label="褰曞叆鏃ユ湡锛�">
- <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
- </el-form-item>
- </el-form>
- </div>
- <div class="table_list">
- <div class="actions">
- <div></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>
- <el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
- </div>
- </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)">
- <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-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
- <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
- <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
- </el-table>
- </template>
- </el-table-column>
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="180" show-overflow-tooltip />
- <el-table-column label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" width="180" show-overflow-tooltip />
- <el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="300" show-overflow-tooltip />
- <el-table-column label="涓氬姟鍛�" prop="salesman" width="100" show-overflow-tooltip />
- <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="180" show-overflow-tooltip />
- <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="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 />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="200" align="center">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">缂栬緫</el-button>
-<!-- <el-button link type="primary" size="small" @click="openForm('view', scope.row)">璇︽儏</el-button>-->
- <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">闄勪欢</el-button>
- <el-button link type="primary" size="small" @click="openDeliveryForm(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" />
- </div>
- <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">
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
- <el-input v-model="form.salesContractNo" placeholder="鑷姩鐢熸垚" clearable disabled />
- </el-form-item>
- </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-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚堝悓鍙凤細" prop="customerContractNo">
- <el-input v-model="form.customerContractNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'"/>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
- <el-select v-model="form.customerId" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
- <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
- {{
- item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
- }}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
- <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
- <el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD"
- format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="褰曞叆浜猴細" prop="entryPerson">
- <el-select v-model="form.entryPerson" placeholder="璇烽�夋嫨" clearable @change="changs" disabled>
- <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
- <el-date-picker style="width: 100%" v-model="form.entryDate" 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="浠樻鏂瑰紡">
- <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
- <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">娣诲姞</el-button>
- <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
- :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" />
- <el-table-column label="浜у搧澶х被" prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
- <el-table-column label="鍗曚綅" prop="unit" />
- <el-table-column label="鏁伴噺" prop="quantity" />
- <el-table-column label="绋庣巼(%)" prop="taxRate" />
- <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
- <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
- <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
- <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center" v-if="operationType !== 'view'">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">缂栬緫</el-button>
- </template>
- </el-table-column>
- </el-table>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="澶囨敞路锛�" prop="remark">
- <el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
- <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
- :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
- :on-success="handleUploadSuccess" :on-remove="handleRemove">
- <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
- <template #tip v-if="operationType !== 'view'">
- <div class="el-upload__tip">
- 鏂囦欢鏍煎紡鏀寔
- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
- </div>
- </template>
- </el-upload>
- </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>
- <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" width="40%"
- @close="closeProductDia">
- <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
- <!-- <el-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable>
- <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
- </el-select> -->
- <el-tree-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable check-strictly
- @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
- <el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable @change="getProductModel">
- <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input v-model="productForm.unit" placeholder="璇疯緭鍏�" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
- <el-select v-model="productForm.taxRate" placeholder="璇烽�夋嫨" clearable @change="calculateFromTaxRate">
- <el-option label="1" value="1" />
- <el-option label="6" value="6" />
- <el-option label="13" value="13" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
- <el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
- :precision="2"
- placeholder="璇疯緭鍏�" clearable @change="calculateFromUnitPrice" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏁伴噺锛�" prop="quantity">
- <el-input-number :step="0.1" :min="0" v-model="productForm.quantity" placeholder="璇疯緭鍏�" clearable
- :precision="2"
- @change="calculateFromQuantity" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
- <el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable @change="calculateFromTotalPrice" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�" prop="taxExclusiveTotalPrice">
- <el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable @change="calculateFromExclusiveTotalPrice" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
- <el-select v-model="productForm.invoiceType" placeholder="璇烽�夋嫨" clearable>
- <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
- <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitProduct">纭</el-button>
- <el-button @click="closeProductDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 鎵撳嵃棰勮寮圭獥 -->
- <el-dialog
- v-model="printPreviewVisible"
- title="鎵撳嵃棰勮"
- width="90%"
- :close-on-click-modal="false"
- class="print-preview-dialog"
- >
- <div class="print-preview-container">
- <div class="print-preview-header">
- <el-button type="primary" @click="executePrint">鎵ц鎵撳嵃</el-button>
- <el-button @click="printPreviewVisible = false">鍏抽棴棰勮</el-button>
- </div>
- <div class="print-preview-content">
- <div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
- 鏆傛棤鎵撳嵃鏁版嵁
- </div>
- <div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
- 鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
- </div>
- <div v-for="(item, index) in printData" :key="index" class="print-page">
- <div class="delivery-note">
- <div class="header">
- <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
- <div class="document-title">闆跺敭鍙戣揣鍗�</div>
- </div>
-
- <div class="info-section">
- <div class="info-row">
- <div>
- <span class="label">鍙戣揣鏃ユ湡锛�</span>
- <span class="value">{{ formatDate(item.createTime) }}</span>
- </div>
- <div>
-
- <span class="label">瀹㈡埛鍚嶇О锛�</span>
- <span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
- </div>
- </div>
- <div class="info-row">
- <span class="label">鍗曞彿锛�</span>
- <span class="value">{{ item.salesContractNo }}</span>
- </div>
- </div>
-
- <div class="table-section">
- <table class="product-table">
- <thead>
- <tr>
- <th>浜у搧鍚嶇О</th>
- <th>瑙勬牸鍨嬪彿</th>
- <th>鍗曚綅</th>
- <th>鍗曚环</th>
- <th>闆跺敭鏁伴噺</th>
- <th>闆跺敭閲戦</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="product in item.products" :key="product.id">
- <td>{{ product.productCategory || '' }}</td>
- <td>{{ product.specificationModel || '' }}</td>
- <td>{{ product.unit || '' }}</td>
- <td>{{ product.taxInclusiveUnitPrice || '0' }}</td>
- <td>{{ product.quantity || '0' }}</td>
- <td>{{ product.taxInclusiveTotalPrice || '0' }}</td>
- </tr>
- <tr v-if="!item.products || item.products.length === 0">
- <td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td class="label">鍚堣</td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value">{{ getTotalQuantity(item.products) }}</td>
- <td class="total-value">{{ getTotalAmount(item.products) }}</td>
- </tr>
- </tfoot>
- </table>
- </div>
-
- <div class="footer-section">
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鏀惰揣鐢佃瘽锛�</span>
- <span class="value"></span>
- </div>
- <div class="footer-item">
- <span class="label">鏀惰揣浜猴細</span>
- <span class="value"></span>
- </div>
- <div class="footer-item address-item">
- <span class="label">鏀惰揣鍦板潃锛�</span>
- <span class="value address-value"></span>
- </div>
- </div>
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鎿嶄綔鍛橈細</span>
- <span class="value">{{ userStore.nickName || '鎾曞紑鍓�' }}</span>
- </div>
- <div class="footer-item">
- <span class="label">鎵撳嵃鏃ユ湡锛�</span>
- <span class="value">{{ formatDateTime(new Date()) }}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </el-dialog>
- <!-- 鍙戣揣寮规 -->
- <el-dialog
- v-model="deliveryFormVisible"
- title="鍙戣揣淇℃伅"
- width="40%"
- @close="closeDeliveryDia"
- >
- <el-form :model="deliveryForm" label-width="120px" label-position="top" :rules="deliveryRules" ref="deliveryFormRef">
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item label="鍙戣揣鏃ユ湡锛�" prop="shippingDate">
- <el-date-picker
- style="width: 100%"
- v-model="deliveryForm.shippingDate"
- 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="24">
- <el-form-item label="鍙戣揣杞︾墝鍙凤細" prop="shippingCarNumber">
- <el-input
- v-model="deliveryForm.shippingCarNumber"
- placeholder="璇疯緭鍏ュ彂璐ц溅鐗屽彿"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitDelivery">纭鍙戣揣</el-button>
- <el-button @click="closeDeliveryDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
- <FileList ref="fileListRef" />
- </div>
-</template>
-
-<script setup>
-import { getToken } from "@/utils/auth";
-import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref} from "vue";
-import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
-import {ElMessage, ElMessageBox} from "element-plus";
-import useUserStore from "@/store/modules/user";
-import { userListNoPage } from "@/api/system/user.js";
-import FileList from "./fileList.vue";
-import {
- ledgerListPage,
- productList,
- customerList,
- addOrUpdateSalesLedger,
- getSalesLedgerWithProducts,
- delLedger,
- addOrUpdateSalesLedgerProduct,
- delProduct,
- delLedgerFile, getProductInventory,
-} from "@/api/salesManagement/salesLedger.js";
-import { modelList, productTreeList } from "@/api/basicData/product.js";
-import useFormData from "@/hooks/useFormData.js";
-import dayjs from "dayjs";
-
-const userStore = useUserStore();
-const { proxy } = getCurrentInstance();
-const tableData = ref([]);
-const productData = ref([]);
-const selectedRows = ref([]);
-const productSelectedRows = ref([]);
-const userList = ref([]);
-const customerOption = ref([]);
-const productOptions = ref([]);
-const modelOptions = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const fileList = ref([]);
-
-// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
-const data = reactive({
- searchForm: {
- customerName: "", // 瀹㈡埛鍚嶇О
- customerContractNo: "", // 瀹㈡埛鍚堝悓缂栧彿
- salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
- projectName: "", // 椤圭洰鍚嶇О
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- form: {
- salesContractNo: "",
- salesman: "",
- customerContractNo: "",
- customerId: "",
- projectName: "",
- entryPerson: "",
- entryDate: "",
- maintenanceTime: "",
- productData: [],
- executionDate: "",
- paymentMethod: "",
- },
- rules: {
- salesman: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerContractNo: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- projectName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { form, rules } = toRefs(data);
-const { form: searchForm } = useFormData(data.searchForm);
-// 浜у搧琛ㄥ崟寮规鏁版嵁
-const productFormVisible = ref(false);
-const productOperationType = ref("");
-const currentId = ref("");
-const productFormData = reactive({
- productForm: {
- productCategory: "",
- specificationModel: "",
- unit: "",
- quantity: "",
- taxInclusiveUnitPrice: "",
- taxRate: "",
- taxInclusiveTotalPrice: "",
- taxExclusiveTotalPrice: "",
- invoiceType: "",
- },
- productRules: {
- productCategory: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- specificationModel: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxInclusiveUnitPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- taxInclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
-});
-const { productForm, productRules } = toRefs(productFormData);
-// 闃叉寰幆璁$畻鐨勬爣蹇�
-const isCalculating = ref(false);
-const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-// 鎵撳嵃鐩稿叧
-const printPreviewVisible = ref(false);
-const printData = ref([]);
-
-// 鍙戣揣鐩稿叧
-const deliveryFormVisible = ref(false);
-const currentDeliveryRow = ref(null);
-const deliveryFormData = reactive({
- deliveryForm: {
- shippingDate: "",
- shippingCarNumber: "",
- },
- deliveryRules: {
- shippingDate: [
- { required: true, message: "璇烽�夋嫨鍙戣揣鏃ユ湡", trigger: "change" }
- ],
- shippingCarNumber: [
- { required: true, message: "璇疯緭鍏ュ彂璐ц溅鐗屽彿", trigger: "blur" }
- ],
- },
-});
-const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
-
-const changeDaterange = (value) => {
- if (value) {
- searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.entryDateStart = undefined;
- searchForm.entryDateEnd = undefined;
- }
- handleQuery();
-};
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
- page.current = 1;
- expandedRowKeys.value = [];
- getList();
-};
-const paginationChange = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- tableLoading.value = true;
- const { entryDate, ...rest } = searchForm;
- ledgerListPage({ ...rest, ...page })
- .then((res) => {
- tableLoading.value = false;
- tableData.value = res.records;
- tableData.value.map((item) => {
- item.children = [];
- });
- total.value = res.total;
- })
- .catch(() => {
- tableLoading.value = false;
- });
-};
-// 鑾峰彇浜у搧澶х被tree鏁版嵁
-const getProductOptions = () => {
- productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- });
-};
-const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
-};
-// 鑾峰彇tree瀛愭暟鎹�
-const getModels = (value) => {
- productForm.value.productCategory = findNodeById(productOptions.value, value);
- modelList({ id: value }).then((res) => {
- modelOptions.value = res;
- });
-};
-const getProductModel = (value) => {
- console.log("value", value);
- const index = modelOptions.value.findIndex((item) => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
- } else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
- }
-};
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter((item) => item.children !== undefined);
- console.log("selection", selectedRows.value);
-};
-const productSelected = (selectedRows) => {
- productSelectedRows.value = selectedRows;
-};
-const expandedRowKeys = ref([]);
-// 灞曞紑琛�
-const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
- const index = tableData.value.findIndex((item) => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
-};
-// 涓昏〃鍚堣鏂规硶
-const summarizeMainTable = (param) => {
- return proxy.summarizeTable(param, [
- "contractAmount",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
-};
-// 瀛愯〃鍚堣鏂规硶
-const summarizeChildrenTable = (param) => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
-};
-// 鎵撳紑寮规
-const openForm = async (type, row) => {
- operationType.value = type;
- form.value = {};
- productData.value = [];
- let userLists = await userListNoPage();
- userList.value = userLists.data;
- customerList().then((res) => {
- customerOption.value = res;
- });
- form.value.entryPerson = userStore.id;
- if (type !== "add") {
- currentId.value = row.id;
- getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
- form.value = { ...res };
- form.value.entryPerson = Number(res.entryPerson);
- productData.value = form.value.productData;
- fileList.value = form.value.salesLedgerFiles;
- });
- }
- // let userAll = await userStore.getInfo()
- // userList.value.forEach(element => {
- // if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
- // form.value.entryPerson = userAll.user.userId // 璁剧疆榛樿涓氬姟鍛樹负褰撳墠鐢ㄦ埛
- // }
- // });
- form.value.entryDate = getCurrentDate(); // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
- dialogFormVisible.value = true;
-};
-function changs(val) {
- console.log(val);
-}
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- // 鏍℃鏂囦欢澶у皬
- // if (file.size > 1024 * 1024 * 10) {
- // proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- // return false;
- // }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
- proxy.$refs["formRef"].validate((valid) => {
- if (valid) {
- console.log('productData.value--', productData.value)
- if (productData.value !== null && productData.value.length > 0) {
- form.value.productData = proxy.HaveJson(productData.value);
- } else {
- proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
- return;
- }
- let tempFileIds = [];
- if (fileList.value !== null && fileList.value.length > 0) {
- tempFileIds = fileList.value.map((item) => item.tempId);
- }
- form.value.tempFileIds = tempFileIds;
- form.value.type = 1;
- addOrUpdateSalesLedger(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
- }
- });
-};
-// 鍏抽棴寮规
-const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
-};
-
-const productIndex = ref(0);
-// 鎵撳紑浜у搧寮规
-const openProductForm = (type, row,index) => {
- productOperationType.value = type;
- productForm.value = {};
- proxy.resetForm("productFormRef");
- if (type === "edit") {
- productForm.value = { ...row };
- productIndex.value = index;
- }
- productFormVisible.value = true;
- getProductOptions();
-};
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitProduct = () => {
- proxy.$refs["productFormRef"].validate((valid) => {
- if (valid) {
- if (operationType.value === "edit") {
- submitProductEdit();
- } else {
- if(productOperationType.value === "add"){
- productData.value.push({ ...productForm.value });
- }else{
- productData.value[productIndex.value] = { ...productForm.value }
- }
- closeProductDia();
- }
- }
- });
-};
-const submitProductEdit = () => {
- productForm.value.salesLedgerId = currentId.value;
- productForm.value.type = 1
- addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProductDia();
- getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => {
- productData.value = res.productData;
- });
- });
-};
-// 鍒犻櫎浜у搧
-const deleteProduct = () => {
- if (productSelectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- if (operationType.value === "add") {
- productSelectedRows.value.forEach((selectedRow) => {
- const index = productData.value.findIndex(
- (product) => product.id === selectedRow.id
- );
- if (index !== -1) {
- productData.value.splice(index, 1);
- }
- });
- } else {
- let ids = [];
- if (productSelectedRows.value.length > 0) {
- ids = productSelectedRows.value.map((item) => item.id);
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delProduct(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- closeProductDia();
- getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(
- (res) => {
- productData.value = res.productData;
- }
- );
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
- }
-};
-// 鍏抽棴浜у搧寮规
-const closeProductDia = () => {
- proxy.resetForm("productFormRef");
- productFormVisible.value = false;
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- proxy.download("/sales/ledger/export", {}, "閿�鍞彴璐�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 鍒犻櫎
-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(() => {
- delLedger(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鎵撳嵃鍔熻兘
-const handlePrint = async () => {
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
- return;
- }
-
- // 鏄剧ず鍔犺浇鐘舵��
- proxy.$modal.loading("姝e湪鑾峰彇浜у搧鏁版嵁锛岃绋嶅��...");
-
- try {
- // 涓烘瘡涓�変腑鐨勯攢鍞彴璐﹁褰曟煡璇㈠搴旂殑浜у搧鏁版嵁
- const printDataWithProducts = [];
-
- for (const row of selectedRows.value) {
- try {
- // 璋冪敤productList鎺ュ彛鏌ヨ浜у搧鏁版嵁
- const productRes = await productList({ salesLedgerId: row.id, type: 1 });
-
- // 灏嗕骇鍝佹暟鎹暣鍚堝埌閿�鍞彴璐﹁褰曚腑
- const rowWithProducts = {
- ...row,
- products: productRes.data || []
- };
-
- printDataWithProducts.push(rowWithProducts);
- } catch (error) {
- console.error(`鑾峰彇閿�鍞彴璐� ${row.id} 鐨勪骇鍝佹暟鎹け璐�:`, error);
- // 鍗充娇鏌愪釜璁板綍鐨勪骇鍝佹暟鎹幏鍙栧け璐ワ紝涔熻鍖呭惈璇ヨ褰�
- printDataWithProducts.push({
- ...row,
- products: []
- });
- }
- }
-
- printData.value = printDataWithProducts;
- console.log('鎵撳嵃鏁版嵁锛堝寘鍚骇鍝侊級:', printData.value);
- printPreviewVisible.value = true;
-
- } catch (error) {
- console.error('鑾峰彇浜у搧鏁版嵁澶辫触:', error);
- proxy.$modal.msgError("鑾峰彇浜у搧鏁版嵁澶辫触锛岃閲嶈瘯");
- } finally {
- proxy.$modal.closeLoading();
- }
-};
-// 鎵ц鎵撳嵃
-const executePrint = () => {
- console.log('寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:', printData.value.length);
- console.log('鎵撳嵃鏁版嵁:', printData.value);
-
- // 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
- const printWindow = window.open('', '_blank', 'width=800,height=600');
-
- // 鏋勫缓鎵撳嵃鍐呭
- let printContent = `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>鎵撳嵃棰勮</title>
- <style>
- body {
- margin: 0;
- padding: 0;
- font-family: "SimSun", serif;
- background: white;
- }
- .print-page {
- width: 200mm;
- height: 75mm;
- padding: 10mm;
- padding-left: 20mm;
- background: white;
- box-sizing: border-box;
- page-break-after: always;
- page-break-inside: avoid;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
- .delivery-note {
- width: 100%;
- height: 100%;
- font-size: 12px;
- line-height: 1.2;
- display: flex;
- flex-direction: column;
- color: #000;
- }
- .header {
- text-align: center;
- margin-bottom: 8px;
- }
- .company-name {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 4px;
- }
- .document-title {
- font-size: 16px;
- font-weight: bold;
- }
- .info-section {
- margin-bottom: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .info-row {
- line-height: 20px;
- }
- .label {
- font-weight: bold;
- width: 60px;
- font-size: 12px;
- }
- .value {
- margin-right: 20px;
- min-width: 80px;
- font-size: 12px;
- }
- .table-section {
- margin-bottom: 40px;
- // flex: 0.6;
- }
- .product-table {
- width: 100%;
- border-collapse: collapse;
- border: 1px solid #000;
- }
- .product-table th, .product-table td {
- border: 1px solid #000;
- padding: 6px;
- text-align: center;
- font-size: 12px;
- line-height: 1.4;
- }
- .product-table th {
- font-weight: bold;
- }
- .total-value {
- font-weight: bold;
- }
- .footer-section {
- margin-top: auto;
- }
- .footer-row {
- display: flex;
- margin-bottom: 3px;
- line-height: 22px;
- justify-content: space-between;
- }
- .footer-item {
- display: flex;
- margin-right: 20px;
- }
- .footer-item .label {
- font-weight: bold;
- width: 80px;
- font-size: 12px;
- }
- .footer-item .value {
- min-width: 80px;
- font-size: 12px;
- }
- .address-item .address-value {
- min-width: 200px;
- }
- @media print {
- body {
- margin: 0;
- padding: 0;
- }
- .print-page {
- margin: 0;
- padding: 10mm;
- /* padding-left: 20mm; */
- page-break-inside: avoid;
- page-break-after: always;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
- }
- </style>
- </head>
- <body>
- `;
-
- // 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
- printData.value.forEach((item, index) => {
- printContent += `
- <div class="print-page">
- <div class="delivery-note">
- <div class="header">
- <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
- <div class="document-title">闆跺敭鍙戣揣鍗�</div>
- </div>
-
- <div class="info-section">
- <div class="info-row">
- <div>
- <span class="label">鍙戣揣鏃ユ湡锛�</span>
- <span class="value">${formatDate(item.createTime)}</span>
- </div>
- <div>
- <span class="label">瀹㈡埛鍚嶇О锛�</span>
- <span class="value">${item.customerName || '寮犵埍鏈�'}</span>
- </div>
- </div>
- <div class="info-row">
- <span class="label">鍗曞彿锛�</span>
- <span class="value">${item.salesContractNo || ''}</span>
- </div>
- </div>
-
- <div class="table-section">
- <table class="product-table">
- <thead>
- <tr>
- <th>浜у搧鍚嶇О</th>
- <th>瑙勬牸鍨嬪彿</th>
- <th>鍗曚綅</th>
- <th>鍗曚环</th>
- <th>闆跺敭鏁伴噺</th>
- <th>闆跺敭閲戦</th>
- </tr>
- </thead>
- <tbody>
- ${item.products && item.products.length > 0 ?
- item.products.map(product => `
- <tr>
- <td>${product.productCategory || ''}</td>
- <td>${product.specificationModel || ''}</td>
- <td>${product.unit || ''}</td>
- <td>${product.taxInclusiveUnitPrice || '0'}</td>
- <td>${product.quantity || '0'}</td>
- <td>${product.taxInclusiveTotalPrice || '0'}</td>
- </tr>
- `).join('') :
- '<tr><td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td></tr>'
- }
- </tbody>
- <tfoot>
- <tr>
- <td class="label">鍚堣</td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value"></td>
- <td class="total-value">${getTotalQuantityForPrint(item.products)}</td>
- <td class="total-value">${getTotalAmountForPrint(item.products)}</td>
- </tr>
- </tfoot>
- </table>
- </div>
-
- <div class="footer-section">
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鏀惰揣鐢佃瘽锛�</span>
- <span class="value"></span>
- </div>
- <div class="footer-item">
- <span class="label">鏀惰揣浜猴細</span>
- <span class="value"></span>
- </div>
- <div class="footer-item address-item">
- <span class="label">鏀惰揣鍦板潃锛�</span>
- <span class="value address-value"></span>
- </div>
- </div>
- <div class="footer-row">
- <div class="footer-item">
- <span class="label">鎿嶄綔鍛橈細</span>
- <span class="value">${userStore.nickName || '鎾曞紑鍓�'}</span>
- </div>
- <div class="footer-item">
- <span class="label">鎵撳嵃鏃ユ湡锛�</span>
- <span class="value">${formatDateTime(new Date())}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- `;
- });
-
- printContent += `
- </body>
- </html>
- `;
-
- // 鍐欏叆鍐呭鍒版柊绐楀彛
- printWindow.document.write(printContent);
- printWindow.document.close();
-
- // 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
- printWindow.onload = () => {
- setTimeout(() => {
- printWindow.print();
- printWindow.close();
- printPreviewVisible.value = false;
- }, 500);
- };
-};
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (dateString) => {
- if (!dateString) return getCurrentDate();
- const date = new Date(dateString);
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- return `${year}/${month}/${day}`;
-};
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (date) => {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- const hours = String(date.getHours()).padStart(2, "0");
- const minutes = String(date.getMinutes()).padStart(2, "0");
- const seconds = String(date.getSeconds()).padStart(2, "0");
- return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
-};
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
-function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
-}
-
-// 璁$畻浜у搧鎬绘暟閲�
-const getTotalQuantity = (products) => {
- if (!products || products.length === 0) return '0';
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.quantity) || 0);
- }, 0);
- return total.toFixed(2);
-};
-
-// 璁$畻浜у搧鎬婚噾棰�
-const getTotalAmount = (products) => {
- if (!products || products.length === 0) return '0';
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
- }, 0);
- return total.toFixed(2);
-};
-
-// 鐢ㄤ簬鎵撳嵃鐨勮绠楀嚱鏁�
-const getTotalQuantityForPrint = (products) => {
- if (!products || products.length === 0) return '0';
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.quantity) || 0);
- }, 0);
- return total.toFixed(2);
-};
-
-const getTotalAmountForPrint = (products) => {
- if (!products || products.length === 0) return '0';
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
- }, 0);
- return total.toFixed(2);
-};
-
-const mathNum = () => {
- console.log("productForm.value", productForm.value);
- if (!productForm.value.taxInclusiveUnitPrice) {
- return;
- }
- if (!productForm.value.quantity) {
- return;
- }
- // 鍚◣鎬讳环璁$畻
- productForm.value.taxInclusiveTotalPrice =
- proxy.calculateTaxIncludeTotalPrice(
- productForm.value.taxInclusiveUnitPrice,
- productForm.value.quantity
- );
- if (productForm.value.taxRate) {
- // 涓嶅惈绋庢�讳环璁$畻
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-};
-
-// 鏍规嵁鍚◣鎬讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const calculateFromTotalPrice = () => {
- if (isCalculating.value) return;
-
- const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
- const quantity = parseFloat(productForm.value.quantity);
-
- if (!totalPrice || !quantity || quantity <= 0) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- totalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
-};
-
-// 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const calculateFromExclusiveTotalPrice = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
- const quantity = parseFloat(productForm.value.quantity);
- const taxRate = parseFloat(productForm.value.taxRate);
-
- if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
- return;
- }
-
- isCalculating.value = true;
-
- // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
- const taxRateDecimal = taxRate / 100;
- const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
- productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
-
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
-
- isCalculating.value = false;
-};
-
-// 鏍规嵁鏁伴噺鍙樺寲璁$畻鎬讳环
-const calculateFromQuantity = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const quantity = parseFloat(productForm.value.quantity);
- const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
-};
-
-// 鏍规嵁鍚◣鍗曚环鍙樺寲璁$畻鎬讳环
-const calculateFromUnitPrice = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const quantity = parseFloat(productForm.value.quantity);
- const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
-};
-
-// 鏍规嵁绋庣巼鍙樺寲璁$畻涓嶅惈绋庢�讳环
-const calculateFromTaxRate = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
- const taxRate = parseFloat(productForm.value.taxRate);
-
- if (!inclusiveTotalPrice || !taxRate) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻涓嶅惈绋庢�讳环
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- inclusiveTotalPrice,
- taxRate
- );
-
- isCalculating.value = false;
-};
-/**
- * 涓嬭浇鏂囦欢
- *
- * @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
- */
-const fileListRef = ref(null)
-const downLoadFile = (row) => {
- getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
- fileListRef.value.open(res.salesLedgerFiles)
- });
-}
-
-// 鎵撳紑鍙戣揣寮规
-const openDeliveryForm = (row) => {
- getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => {
- currentDeliveryRow.value = row;
- deliveryForm.value = {
- shippingDate: getCurrentDate(),
- shippingCarNumber: "",
- };
- deliveryFormVisible.value = true;
- }).catch(err => {
- ElMessage.error(err.msg);
- });
-};
-
-// 鎻愪氦鍙戣揣琛ㄥ崟
-const submitDelivery = () => {
- proxy.$refs["deliveryFormRef"].validate((valid) => {
- if (valid) {
- addShippingInfo({
- salesLedgerId: currentDeliveryRow.value.id,
- shippingDate: deliveryForm.value.shippingDate,
- shippingCarNumber: deliveryForm.value.shippingCarNumber,
- })
- .then(() => {
- proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
- closeDeliveryDia();
- getList();
- })
- .catch(() => {
- proxy.$modal.msgError("鍙戣揣澶辫触锛岃閲嶈瘯");
- });
- }
- });
-};
-
-// 鍏抽棴鍙戣揣寮规
-const closeDeliveryDia = () => {
- proxy.resetForm("deliveryFormRef");
- deliveryFormVisible.value = false;
- currentDeliveryRow.value = null;
-};
-
-onMounted(() => {
- getList();
-});
-</script>
-
-<style scoped lang="scss">
-.ml-10 {
- margin-left: 10px;
-}
-
-.table_list {
- margin-top: unset;
-}
-
-.actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
-}
-.print-preview-dialog {
- .el-dialog__body {
- padding: 0;
- max-height: 80vh;
- overflow-y: auto;
- }
-}
-
-.print-preview-container {
- .print-preview-header {
- padding: 15px;
- border-bottom: 1px solid #e4e7ed;
- text-align: center;
-
- .el-button {
- margin: 0 10px;
- }
- }
-
- .print-preview-content {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 400px;
- }
-}
-
-.print-page {
- width: 220mm;
- height: 90mm;
- padding: 10mm;
- margin: 0 auto;
- background: white;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
- margin-bottom: 10px;
- box-sizing: border-box;
-}
-
-.delivery-note {
- width: 100%;
- height: 100%;
- font-family: "SimSun", serif;
- font-size: 10px;
- line-height: 1.2;
- display: flex;
- flex-direction: column;
-}
-
-.header {
- text-align: center;
- margin-bottom: 8px;
-
- .company-name {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 4px;
- }
-
- .document-title {
- font-size: 16px;
- font-weight: bold;
- }
-}
-
-.info-section {
- margin-bottom: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .info-row {
- line-height: 20px;
-
- .label {
- font-weight: bold;
- width: 60px;
- font-size: 14px;
- }
-
- .value {
- margin-right: 20px;
- min-width: 80px;
- font-size: 14px;
- }
- }
-}
-
-.table-section {
- margin-bottom: 4px;
- flex: 1;
-
- .product-table {
- width: 100%;
- border-collapse: collapse;
- border: 1px solid #000;
-
- th, td {
- border: 1px solid #000;
- padding: 6px;
- text-align: center;
- font-size: 14px;
- line-height: 1.4;
- }
-
- th {
- font-weight: bold;
- }
-
- .total-label {
- text-align: right;
- font-weight: bold;
- }
-
- .total-value {
- font-weight: bold;
- }
- }
-}
-
-.footer-section {
- .footer-row {
- display: flex;
- margin-bottom: 3px;
- line-height: 20px;
- justify-content: space-between;
-
- .footer-item {
- display: flex;
- margin-right: 20px;
-
- .label {
- font-weight: bold;
- width: 80px;
- font-size: 14px;
- }
-
- .value {
- min-width: 80px;
- font-size: 14px;
- }
-
- &.address-item {
- .address-value {
- min-width: 200px;
- }
- }
- }
- }
-}
-
-@media print {
- .app-container {
- display: none;
- }
-
- .print-page {
- box-shadow: none;
- margin: 0;
- padding: 10mm;
- padding-left: 20mm;
- page-break-inside: avoid;
- page-break-after: always;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
-}
-</style>
diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
deleted file mode 100644
index cefc769..0000000
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ /dev/null
@@ -1,810 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="8">
- <el-input
- v-model="searchForm.quotationNo"
- placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="8">
- <el-select v-model="searchForm.customer" placeholder="璇烽�夋嫨瀹㈡埛" clearable>
- <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
- {{
- item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
- }}
- </el-option>
- </el-select>
- </el-col>
-<!-- <el-col :span="6">-->
-<!-- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鎶ヤ环鐘舵��" clearable>-->
-<!-- <el-option label="鑽夌" value="鑽夌"></el-option>-->
-<!-- <el-option label="宸插彂閫�" value="宸插彂閫�"></el-option>-->
-<!-- <el-option label="瀹㈡埛纭" value="瀹㈡埛纭"></el-option>-->
-<!-- <el-option label="宸茶繃鏈�" value="宸茶繃鏈�"></el-option>-->
-<!-- </el-select>-->
-<!-- </el-col>-->
- <el-col :span="8">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button style="float: right;" type="primary" @click="handleAdd">
- 鏂板鎶ヤ环
- </el-button>
- </el-col>
- </el-row>
-
- <!-- 鎶ヤ环鍒楄〃 -->
- <el-table
- :data="filteredList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
- <el-table-column prop="quotationNo" label="鎶ヤ环鍗曞彿" width="150" />
- <el-table-column prop="customer" label="瀹㈡埛鍚嶇О" />
- <el-table-column prop="salesperson" label="涓氬姟鍛�" width="100" />
- <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="120" />
- <el-table-column prop="validDate" label="鏈夋晥鏈熻嚦" width="120" />
- <el-table-column prop="totalAmount" label="鎶ヤ环閲戦" width="120">
- <template #default="scope">
- 楼{{ scope.row.totalAmount.toFixed(2) }}
- </template>
- </el-table-column>
-<!-- <el-table-column prop="status" label="鎶ヤ环鐘舵��" width="100">-->
-<!-- <template #default="scope">-->
-<!-- <el-tag :type="getStatusType(scope.row.status)">-->
-<!-- {{ scope.row.status }}-->
-<!-- </el-tag>-->
-<!-- </template>-->
-<!-- </el-table-column>-->
- <el-table-column label="鎿嶄綔" width="250" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
- <el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.status === '鑽夌'">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)" v-if="scope.row.status === '鑽夌'">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.currentPage"
- :limit="pagination.pageSize"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="1300px" :close-on-click-modal="false">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <!-- 鍩烘湰淇℃伅 -->
- <el-card class="form-card" shadow="never">
- <template #header>
- <span class="card-title">鍩烘湰淇℃伅</span>
- </template>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
- <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%" @change="handleCustomerChange">
- <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
- {{
- item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
- }}
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="涓氬姟鍛�" prop="salesperson">
- <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%">
- <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
- :value="item.nickName" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鎶ヤ环鏃ユ湡" prop="quotationDate">
- <el-date-picker
- v-model="form.quotationDate"
- type="date"
- placeholder="閫夋嫨鎶ヤ环鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鏈夋晥鏈熻嚦" prop="validDate">
- <el-date-picker
- v-model="form.validDate"
- type="date"
- placeholder="閫夋嫨鏈夋晥鏈�"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
- <el-select v-model="form.paymentMethod" placeholder="璇烽�夋嫨浠樻鏂瑰紡" style="width: 100%">
- <el-option label="鍏ㄦ鍒颁粯" value="鍏ㄦ鍒颁粯"></el-option>
- <el-option label="鍒嗘湡浠樻" value="鍒嗘湡浠樻"></el-option>
- <el-option label="鏈堢粨" value="鏈堢粨"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="浜よ揣鏈�" prop="deliveryPeriod">
- <el-date-picker
- v-model="form.deliveryPeriod"
- type="date"
- placeholder="閫夋嫨浜よ揣鏈�"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 浜у搧淇℃伅 -->
- <el-card class="form-card" shadow="never">
- <template #header>
- <div class="card-header">
- <span class="card-title">浜у搧淇℃伅</span>
- <el-button type="primary" size="small" @click="addProduct">娣诲姞浜у搧</el-button>
- </div>
- </template>
- <el-table :data="form.products" border style="width: 100%">
- <el-table-column prop="product" label="浜у搧鍚嶇О" width="200">
- <template #default="scope">
- <el-tree-select
- v-model="scope.row.productId"
- placeholder="璇烽�夋嫨"
- clearable
- check-strictly
- @change="getModels($event, scope.row)"
- :data="productOptions"
- :render-after-expand="false"
- style="width: 100%"
- />
- </template>
- </el-table-column>
- <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" width="150">
- <template #default="scope">
- <el-select
- v-model="scope.row.specificationId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="getProductModel($event, scope.row)"
- >
- <el-option
- v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id"
- />
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="quantity" label="鏁伴噺">
- <template #default="scope">
- <el-input-number v-model="scope.row.quantity" :min="1" :precision="0" style="width: 100%" />
- </template>
- </el-table-column>
- <el-table-column prop="unit" label="鍗曚綅">
- <template #default="scope">
- <el-input v-model="scope.row.unit" placeholder="鍗曚綅" />
- </template>
- </el-table-column>
- <el-table-column prop="unitPrice" label="鍗曚环">
- <template #default="scope">
- <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" @change="calculateAmount(scope.row)" />
- </template>
- </el-table-column>
- <el-table-column prop="amount" label="閲戦" width="120">
- <template #default="scope">
- <span>楼{{ scope.row.amount.toFixed(2) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="80" align="center">
- <template #default="scope">
- <el-button link type="danger" @click="removeProduct(scope.$index)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
-
- <!-- 璐圭敤淇℃伅 -->
- <el-card class="form-card" shadow="never">
- <template #header>
- <span class="card-title">璐圭敤淇℃伅</span>
- </template>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="浜у搧灏忚">
- <el-input-number v-model="form.subtotal" :precision="2" :min="0" style="width: 100%" readonly />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="杩愯垂">
- <el-input-number v-model="form.freight" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鍏朵粬璐圭敤">
- <el-input-number v-model="form.otherFee" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鎶樻墸鐜�(%)">
- <el-input-number v-model="form.discountRate" :precision="2" :min="0" :max="100" style="width: 100%" @change="calculateTotal" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎶樻墸閲戦">
- <el-input-number v-model="form.discountAmount" :precision="2" :min="0" style="width: 100%" readonly />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎶ヤ环鎬婚">
- <el-input-number v-model="form.totalAmount" :precision="2" :min="0" style="width: 100%" readonly />
- </el-form-item>
- </el-col>
- </el-row>
- </el-card>
-
- <!-- 澶囨敞淇℃伅 -->
- <el-card class="form-card" shadow="never">
- <template #header>
- <span class="card-title">澶囨敞淇℃伅</span>
- </template>
- <el-form-item label="澶囨敞" prop="remark">
- <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" rows="3"></el-input>
- </el-form-item>
- </el-card>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鏌ョ湅璇︽儏瀵硅瘽妗� -->
- <el-dialog v-model="viewDialogVisible" title="鎶ヤ环璇︽儏" width="800px">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鎶ヤ环鍗曞彿">{{ currentQuotation.quotationNo }}</el-descriptions-item>
- <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ currentQuotation.customer }}</el-descriptions-item>
- <el-descriptions-item label="涓氬姟鍛�">{{ currentQuotation.salesperson }}</el-descriptions-item>
- <el-descriptions-item label="鎶ヤ环鏃ユ湡">{{ currentQuotation.quotationDate }}</el-descriptions-item>
- <el-descriptions-item label="鏈夋晥鏈熻嚦">{{ currentQuotation.validDate }}</el-descriptions-item>
- <el-descriptions-item label="浠樻鏂瑰紡">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
- <el-descriptions-item label="浜よ揣鏈�">{{ currentQuotation.deliveryPeriod }}</el-descriptions-item>
-<!-- <el-descriptions-item label="鎶ヤ环鐘舵��">-->
-<!-- <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>-->
-<!-- </el-descriptions-item>-->
- <el-descriptions-item label="鎶ヤ环鎬婚" :span="2">
- <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">楼{{ currentQuotation.totalAmount?.toFixed(2) }}</span>
- </el-descriptions-item>
- </el-descriptions>
-
- <div style="margin-top: 20px;">
- <h4>浜у搧鏄庣粏</h4>
- <el-table :data="currentQuotation.products" border style="width: 100%">
- <el-table-column prop="product" label="浜у搧鍚嶇О" />
- <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" />
- <el-table-column prop="quantity" label="鏁伴噺" />
- <el-table-column prop="unit" label="鍗曚綅" />
- <el-table-column prop="unitPrice" label="鍗曚环">
- <template #default="scope">
- 楼{{ scope.row.unitPrice.toFixed(2) }}
- </template>
- </el-table-column>
- <el-table-column prop="amount" label="閲戦">
- <template #default="scope">
- 楼{{ scope.row.amount.toFixed(2) }}
- </template>
- </el-table-column>
- </el-table>
- </div>
-
- <div v-if="currentQuotation.remark" style="margin-top: 20px;">
- <h4>澶囨敞</h4>
- <p>{{ currentQuotation.remark }}</p>
- </div>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, onMounted, markRaw, shallowRef } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Search } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js'
-import {userListNoPage} from "@/api/system/user.js";
-import {customerList} from "@/api/salesManagement/salesLedger.js";
-import {modelList, productTreeList} from "@/api/basicData/product.js";
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- quotationNo: '',
- customer: '',
- status: ''
-})
-
-const quotationList = ref([])
-const productOptions = ref([]);
-const modelOptions = ref([]);
-const pagination = reactive({
- total: 3,
- currentPage: 1,
- pageSize: 100
-})
-
-const dialogVisible = ref(false)
-const viewDialogVisible = ref(false)
-const dialogTitle = ref('鏂板鎶ヤ环')
-const form = reactive({
- quotationNo: '',
- customer: '',
- salesperson: '',
- quotationDate: '',
- validDate: '',
- paymentMethod: '',
- deliveryPeriod: '',
- status: '鑽夌',
- remark: '',
- products: [],
- subtotal: 0,
- freight: 0,
- otherFee: 0,
- discountRate: 0,
- discountAmount: 0,
- totalAmount: 0
-})
-
-const rules = {
- customer: [{ required: true, message: '璇烽�夋嫨瀹㈡埛', trigger: 'change' }],
- salesperson: [{ required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'change' }],
- quotationDate: [{ required: true, message: '璇烽�夋嫨鎶ヤ环鏃ユ湡', trigger: 'change' }],
- validDate: [{ required: true, message: '璇烽�夋嫨鏈夋晥鏈�', trigger: 'change' }],
- paymentMethod: [{ required: true, message: '璇烽�夋嫨浠樻鏂瑰紡', trigger: 'change' }],
- deliveryPeriod: [{ required: true, message: '璇烽�夋嫨浜よ揣鏈�', trigger: 'change' }]
-}
-const userList = ref([]);
-const customerOption = ref([]);
-
-const isEdit = ref(false)
-const editId = ref(null)
-const currentQuotation = ref({})
-const formRef = ref()
-
-// 璁$畻灞炴��
-const filteredList = computed(() => {
- let list = quotationList.value
- if (searchForm.quotationNo) {
- list = list.filter(item => item.quotationNo.includes(searchForm.quotationNo))
- }
- if (searchForm.customer) {
- list = list.filter(item => item.customer === searchForm.customer)
- }
- if (searchForm.status) {
- list = list.filter(item => item.status === searchForm.status)
- }
- return list
-})
-
-// 鏂规硶
-const getStatusType = (status) => {
- const statusMap = {
- '鑽夌': 'info',
- '宸插彂閫�': 'primary',
- '瀹㈡埛纭': 'success',
- '宸茶繃鏈�': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-const resetSearch = () => {
- searchForm.quotationNo = ''
- searchForm.customer = ''
- searchForm.status = ''
-}
-
-const handleAdd = async () => {
- dialogTitle.value = '鏂板鎶ヤ环'
- isEdit.value = false
- resetForm()
- dialogVisible.value = true
- let userLists = await userListNoPage();
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
- userList.value = (userLists.data || []).map(item => ({
- userId: item.userId,
- nickName: item.nickName || '',
- userName: item.userName || ''
- }));
- getProductOptions();
- customerList().then((res) => {
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
- customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
- id: item.id,
- customerName: item.customerName || '',
- taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || ''
- }))
- });
-}
-const getProductOptions = () => {
- productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- });
-};
-function convertIdToValue(data) {
- return data.map((item) => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
-}
-const getModels = (value, row) => {
- if (!row) return;
- // 濡傛灉娓呯┖閫夋嫨锛屽垯娓呯┖鐩稿叧瀛楁
- if (!value) {
- row.productId = '';
- row.product = '';
- modelOptions.value = [];
- row.specificationId = '';
- row.specification = '';
- row.unit = '';
- return;
- }
- // 鏇存柊 productId锛坴-model 宸茬粡鑷姩鏇存柊锛岃繖閲岀‘淇濅竴鑷存�э級
- row.productId = value;
- // 鎵惧埌瀵瑰簲鐨� label 骞惰祴鍊肩粰 row.product
- const label = findNodeById(productOptions.value, value);
- if (label) {
- row.product = label;
- }
- // 鑾峰彇瑙勬牸鍨嬪彿鍒楄〃
- modelList({ id: value }).then((res) => {
- modelOptions.value = res || [];
- });
-};
-const getProductModel = (value, row) => {
- if (!row) return;
- // 濡傛灉娓呯┖閫夋嫨锛屽垯娓呯┖鐩稿叧瀛楁
- if (!value) {
- row.specificationId = '';
- row.specification = '';
- row.unit = '';
- return;
- }
- // 鏇存柊 specificationId锛坴-model 宸茬粡鑷姩鏇存柊锛岃繖閲岀‘淇濅竴鑷存�э級
- row.specificationId = value;
- const index = modelOptions.value.findIndex((item) => item.id === value);
- if (index !== -1) {
- row.specification = modelOptions.value[index].model;
- row.unit = modelOptions.value[index].unit;
- } else {
- row.specification = '';
- row.unit = '';
- }
-};
-const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥� label
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundLabel = findNodeById(nodes[i].children, productId);
- if (foundLabel) {
- return foundLabel; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖 label
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-};
-const handleView = (row) => {
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
- currentQuotation.value = {
- quotationNo: row.quotationNo || '',
- customer: row.customer || '',
- salesperson: row.salesperson || '',
- quotationDate: row.quotationDate || '',
- validDate: row.validDate || '',
- paymentMethod: row.paymentMethod || '',
- deliveryPeriod: row.deliveryPeriod || '',
- status: row.status || '',
- remark: row.remark || '',
- products: row.products ? row.products.map(product => ({
- productId: product.productId || '',
- product: product.product || product.productName || '',
- specificationId: product.specificationId || '',
- specification: product.specification || '',
- quantity: product.quantity || 0,
- unit: product.unit || '',
- unitPrice: product.unitPrice || 0,
- amount: product.amount || 0
- })) : [],
- totalAmount: row.totalAmount || 0
- }
- viewDialogVisible.value = true
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫鎶ヤ环'
- isEdit.value = true
- editId.value = row.id
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
- form.quotationNo = row.quotationNo || ''
- form.customer = row.customer || ''
- form.salesperson = row.salesperson || ''
- form.quotationDate = row.quotationDate || ''
- form.validDate = row.validDate || ''
- form.paymentMethod = row.paymentMethod || ''
- form.deliveryPeriod = row.deliveryPeriod || ''
- form.status = row.status || '鑽夌'
- form.remark = row.remark || ''
- form.products = row.products ? row.products.map(product => ({
- productId: product.productId || '',
- product: product.product || product.productName || '',
- specificationId: product.specificationId || '',
- specification: product.specification || '',
- quantity: product.quantity || 0,
- unit: product.unit || '',
- unitPrice: product.unitPrice || 0,
- amount: product.amount || 0
- })) : []
- form.subtotal = row.subtotal || 0
- form.freight = row.freight || 0
- form.otherFee = row.otherFee || 0
- form.discountRate = row.discountRate || 0
- form.discountAmount = row.discountAmount || 0
- form.totalAmount = row.totalAmount || 0
- dialogVisible.value = true
-}
-
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ユ姤浠峰崟鍚楋紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- const index = quotationList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- deleteQuotation(row.id).then(res=>{
- // console.log(res)
- if(res.code===200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- handleSearch()
- }
- })
- // quotationList.value.splice(index, 1)
- // pagination.total--
- // ElMessage.success('鍒犻櫎鎴愬姛')
- }
- })
-}
-
-const resetForm = () => {
- form.customer = ''
- form.salesperson = ''
- form.quotationDate = ''
- form.validDate = ''
- form.paymentMethod = ''
- form.deliveryPeriod = ''
- form.status = '鑽夌'
- form.remark = ''
- form.products = []
- form.subtotal = 0
- form.freight = 0
- form.otherFee = 0
- form.discountRate = 0
- form.discountAmount = 0
- form.totalAmount = 0
-}
-
-const addProduct = () => {
- form.products.push({
- productId: '',
- product: '',
- productName: '',
- specificationId: '',
- specification: '',
- quantity: 1,
- unit: '',
- unitPrice: 0,
- amount: 0
- })
-}
-
-const removeProduct = (index) => {
- form.products.splice(index, 1)
- calculateSubtotal()
-}
-
-const calculateAmount = (product) => {
- product.amount = product.quantity * product.unitPrice
- calculateSubtotal()
-}
-
-const calculateSubtotal = () => {
- form.subtotal = form.products.reduce((sum, product) => sum + product.amount, 0)
- calculateTotal()
-}
-
-const calculateTotal = () => {
- form.discountAmount = form.subtotal * (form.discountRate / 100)
- form.totalAmount = form.subtotal + form.freight + form.otherFee - form.discountAmount
-}
-
-const handleCustomerChange = () => {
- // 鍙互鏍规嵁瀹㈡埛淇℃伅鑷姩濉厖涓�浜涢粯璁ゅ��
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (form.products.length === 0) {
- ElMessage.warning('璇疯嚦灏戞坊鍔犱竴涓骇鍝�')
- return
- }
-
- if (isEdit.value) {
- // 缂栬緫
- const index = quotationList.value.findIndex(item => item.id === editId.value)
- if (index > -1) {
- updateQuotation(form).then(res=>{
- // console.log(res)
- if(res.code===200){
- ElMessage.success('缂栬緫鎴愬姛')
- dialogVisible.value = false
- handleSearch()
- }
- })
- // quotationList.value[index] = { ...form, id: editId.value }
- // ElMessage.success('缂栬緫鎴愬姛')
- }
- } else {
- // 鏂板
- // const newId = Math.max(...quotationList.value.map(item => item.id)) + 1
- form.quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}`
-
- addQuotation(form).then(res=>{
- // console.log(res)
- if(res.code===200){
- ElMessage.success('鏂板鎴愬姛')
- dialogVisible.value = false
- handleSearch()
- }
- })
-
- // quotationList.value.push({
- // ...form,
- // // id: newId,
- // quotationNo: quotationNo
- // })
- // pagination.total++
- // ElMessage.success('鏂板鎴愬姛')
- }
-
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.currentPage = val.page
- pagination.pageSize = val.limit
-}
-const handleSearch = ()=>{
- const params = {
- page:pagination,
- ...searchForm
- }
- getQuotationList(params).then(res=>{
- // console.log(res)
- if(res.code===200){
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鎴栧叾浠栧璞℃斁鍏ュ搷搴斿紡瀵硅薄
- quotationList.value = (res.data.records || []).map(item => ({
- id: item.id,
- quotationNo: item.quotationNo || '',
- customer: item.customer || '',
- salesperson: item.salesperson || '',
- quotationDate: item.quotationDate || '',
- validDate: item.validDate || '',
- paymentMethod: item.paymentMethod || '',
- deliveryPeriod: item.deliveryPeriod || '',
- status: item.status || '鑽夌',
- remark: item.remark || '',
- products: item.products ? item.products.map(product => ({
- productId: product.productId || '',
- product: product.product || product.productName || '',
- specificationId: product.specificationId || '',
- specification: product.specification || '',
- quantity: product.quantity || 0,
- unit: product.unit || '',
- unitPrice: product.unitPrice || 0,
- amount: product.amount || 0
- })) : [],
- subtotal: item.subtotal || 0,
- freight: item.freight || 0,
- otherFee: item.otherFee || 0,
- discountRate: item.discountRate || 0,
- discountAmount: item.discountAmount || 0,
- totalAmount: item.totalAmount || 0
- }))
- pagination.total = res.data.total
- }
- })
- customerList().then((res) => {
- // 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
- customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
- id: item.id,
- customerName: item.customerName || '',
- taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || ''
- }))
- });
-}
-
-onMounted(()=>{
- handleSearch()
-})
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-
-.form-card {
- margin-bottom: 20px;
-}
-
-.card-title {
- font-weight: bold;
- color: #303133;
-}
-
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.dialog-footer {
- text-align: right;
-}
-</style>
diff --git a/src/views/salesManagement/salespersonManagement/index.vue b/src/views/salesManagement/salespersonManagement/index.vue
deleted file mode 100644
index e597538..0000000
--- a/src/views/salesManagement/salespersonManagement/index.vue
+++ /dev/null
@@ -1,382 +0,0 @@
-<template>
- <div class="app-container">
- <el-card class="box-card">
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input
- v-model="searchForm.name"
- placeholder="璇疯緭鍏ヤ笟鍔″憳濮撳悕"
- clearable
- @keyup.enter="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.department" placeholder="璇烽�夋嫨閮ㄩ棬" clearable>
- <el-option label="閿�鍞儴" value="閿�鍞儴"></el-option>
- <el-option label="甯傚満閮�" value="甯傚満閮�"></el-option>
- <el-option label="瀹㈡湇閮�" value="瀹㈡湇閮�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="鍦ㄨ亴" value="鍦ㄨ亴"></el-option>
- <el-option label="绂昏亴" value="绂昏亴"></el-option>
- <el-option label="璇曠敤鏈�" value="璇曠敤鏈�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- <el-button type="primary" style="float: right;" @click="handleAdd">鏂板涓氬姟鍛�</el-button>
- </el-col>
- </el-row>
-
- <!-- 涓氬姟鍛樺垪琛� -->
- <el-table
- :data="filteredList"
- style="width: 100%"
- v-loading="loading"
- border
- stripe
- height="calc(100vh - 22em)"
- >
- <el-table-column prop="id" label="ID" width="80" align="center"/>
- <el-table-column prop="name" label="濮撳悕" width="120" />
- <el-table-column prop="phone" label="鑱旂郴鐢佃瘽" width="140" />
- <el-table-column prop="email" label="閭" width="200" />
- <el-table-column prop="department" label="閮ㄩ棬" width="100" />
- <el-table-column prop="position" label="鑱屼綅" width="100" />
- <el-table-column prop="hireDate" label="鍏ヨ亴鏃ユ湡" width="120" />
- <el-table-column prop="status" label="鐘舵��" width="80">
- <template #default="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="permissions" label="鏉冮檺">
- <template #default="scope">
- <el-tag v-for="perm in scope.row.permissionsList" :key="perm" size="small" style="margin-right: 5px;">
- {{ perm }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button link type="primary" @click="handlePermissions(scope.row)">鏉冮檺</el-button>
- <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <pagination
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="pagination.current"
- :limit="pagination.size"
- @pagination="handleCurrentChange"
- />
- </el-card>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="濮撳悕" prop="name">
- <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
- <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="閭" prop="email">
- <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="閮ㄩ棬" prop="department">
- <el-select v-model="form.department" placeholder="璇烽�夋嫨閮ㄩ棬" style="width: 100%">
- <el-option label="閿�鍞儴" value="閿�鍞儴"></el-option>
- <el-option label="甯傚満閮�" value="甯傚満閮�"></el-option>
- <el-option label="瀹㈡湇閮�" value="瀹㈡湇閮�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鑱屼綅" prop="position">
- <el-input v-model="form.position" placeholder="璇疯緭鍏ヨ亴浣�"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鍏ヨ亴鏃ユ湡" prop="hireDate">
- <el-date-picker
- v-model="form.hireDate"
- type="date"
- placeholder="閫夋嫨鍏ヨ亴鏃ユ湡"
- style="width: 100%"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
- <el-option label="鍦ㄨ亴" value="鍦ㄨ亴"></el-option>
- <el-option label="绂昏亴" value="绂昏亴"></el-option>
- <el-option label="璇曠敤鏈�" value="璇曠敤鏈�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
-
- <!-- 鏉冮檺璁剧疆瀵硅瘽妗� -->
- <el-dialog v-model="permissionDialogVisible" title="鏉冮檺璁剧疆" width="500px">
- <el-form label-width="100px">
- <el-form-item label="涓氬姟鍛樺鍚�">
- <span>{{ currentSalesperson.name }}</span>
- </el-form-item>
- <el-form-item label="鏉冮檺璁剧疆">
- <el-checkbox-group v-model="currentPermissions">
- <el-checkbox label="璁㈠崟绠$悊">璁㈠崟绠$悊</el-checkbox>
- <el-checkbox label="瀹㈡埛绠$悊">瀹㈡埛绠$悊</el-checkbox>
- <el-checkbox label="璐㈠姟绠$悊">璐㈠姟绠$悊</el-checkbox>
- <el-checkbox label="鍙戣揣绠$悊">鍙戣揣绠$悊</el-checkbox>
- <el-checkbox label="鎶ヨ〃鏌ョ湅">鎶ヨ〃鏌ョ湅</el-checkbox>
- <el-checkbox label="绯荤粺璁剧疆">绯荤粺璁剧疆</el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="permissionDialogVisible = false">鍙� 娑�</el-button>
- <el-button type="primary" @click="savePermissions">纭� 瀹�</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed,onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import {listPage,add,update,deleteSalespersonManagement} from '@/api/salesManagement/salespersonManagement.js'
-import { Plus, Search } from '@element-plus/icons-vue'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-const salespersonList = ref([])
-const total = ref(0)
-
-onMounted(() => {
- getList()
-})
-const getList = () => {
- loading.value = true
- listPage({...pagination,...searchForm}).then(res => {
- salespersonList.value = res.data.records
- total.value = res.data.total
- loading.value = false
- })
-}
-
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const searchForm = reactive({
- name: '',
- department: '',
- status: ''
-})
-
-
-
-const pagination = reactive({
- current: 1,
- size: 10
-})
-
-const dialogVisible = ref(false)
-const dialogTitle = ref('鏂板涓氬姟鍛�')
-const form = reactive({
- name: '',
- phone: '',
- email: '',
- department: '',
- position: '',
- hireDate: '',
- status: '鍦ㄨ亴'
-})
-
-const rules = {
- name: [{ required: true, message: '璇疯緭鍏ュ鍚�', trigger: 'blur' }],
- phone: [{ required: true, message: '璇疯緭鍏ヨ仈绯荤數璇�', trigger: 'blur' }],
- email: [{ required: true, message: '璇疯緭鍏ラ偖绠�', trigger: 'blur' }],
- department: [{ required: true, message: '璇烽�夋嫨閮ㄩ棬', trigger: 'change' }],
- position: [{ required: true, message: '璇疯緭鍏ヨ亴浣�', trigger: 'blur' }],
- hireDate: [{ required: true, message: '璇烽�夋嫨鍏ヨ亴鏃ユ湡', trigger: 'change' }],
- status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
-}
-
-const isEdit = ref(false)
-const editId = ref(null)
-const permissionDialogVisible = ref(false)
-const currentSalesperson = ref({})
-const currentPermissions = ref([])
-const formRef = ref()
-
-// 璁$畻灞炴��
-const filteredList = computed(() => {
- let list = salespersonList.value
- if (searchForm.name) {
- list = list.filter(item => item.name.includes(searchForm.name))
- }
- if (searchForm.department) {
- list = list.filter(item => item.department === searchForm.department)
- }
- if (searchForm.status) {
- list = list.filter(item => item.status === searchForm.status)
- }
- return list
-})
-
-// 鏂规硶
-const getStatusType = (status) => {
- const statusMap = {
- '鍦ㄨ亴': 'success',
- '绂昏亴': 'danger',
- '璇曠敤鏈�': 'warning'
- }
- return statusMap[status] || 'info'
-}
-
-const handleSearch = () => {
- getList()
- // 鎼滅储閫昏緫宸插湪computed涓鐞�
-}
-
-const resetSearch = () => {
- searchForm.name = ''
- searchForm.department = ''
- searchForm.status = ''
-}
-
-const handleAdd = () => {
- dialogTitle.value = '鏂板涓氬姟鍛�'
- isEdit.value = false
- form.name = ''
- form.phone = ''
- form.email = ''
- form.department = ''
- form.position = ''
- form.hireDate = ''
- form.status = '鍦ㄨ亴'
- dialogVisible.value = true
-}
-
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫涓氬姟鍛�'
- isEdit.value = true
- editId.value = row.id
- Object.assign(form, row)
- dialogVisible.value = true
-}
-
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ヤ笟鍔″憳鍚楋紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- let ids = [row.id]
- deleteSalespersonManagement(ids).then(res => {
- if(res.code === 200){
- ElMessage.success('鍒犻櫎鎴愬姛')
- getList()
- }
- })
- })
-}
-
-const handlePermissions = (row) => {
- currentSalesperson.value = row
- currentPermissions.value = row.permissions.split(",")
- permissionDialogVisible.value = true
-}
-
-const savePermissions = () => {
- let splice = currentPermissions.value;
- if(splice[0] === ''){
- splice.splice(0,1)
- }
- currentSalesperson.value.permissions = splice.join(",")
- update(currentSalesperson.value).then(res => {
- if(res.code === 200){
- ElMessage.success('鏉冮檺璁剧疆鎴愬姛')
- permissionDialogVisible.value = false
- getList()
- }
- })
-}
-
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- if (isEdit.value) {
- // 缂栬緫
- update(form).then(res => {
- if(res.code === 200){
- ElMessage.success('缂栬緫鎴愬姛')
- dialogVisible.value = false
- getList()
- }
- })
- } else {
- add(form).then(res => {
- if(res.code === 200){
- ElMessage.success('鏂板鎴愬姛')
- dialogVisible.value = false
- getList()
- }
- })
-
- }
-
- }
- })
-}
-
-const handleCurrentChange = (val) => {
- pagination.value.currentPage = val.page
- pagination.value.pageSize = val.limit
-}
-</script>
-
-<style scoped>
-.search-row {
- margin-bottom: 20px;
-}
-</style>
diff --git a/src/views/salesManagement/strategyControl/index.vue b/src/views/salesManagement/strategyControl/index.vue
deleted file mode 100644
index 629d255..0000000
--- a/src/views/salesManagement/strategyControl/index.vue
+++ /dev/null
@@ -1,1587 +0,0 @@
-<template>
- <div class="app-container strategy-control">
- <el-tabs v-model="activeTab" type="border-card" class="main-tabs" @tab-change="handleTabChange">
- <!-- 浠锋牸绛栫暐閰嶇疆 -->
- <el-tab-pane label="浠锋牸绛栫暐閰嶇疆" name="priceStrategy">
- <el-card class="box-card">
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-select v-model="priceSearchForm.customerName" placeholder="璇烽�夋嫨瀹㈡埛" clearable>
- <el-option label="鍏ㄩ儴瀹㈡埛" value=""></el-option>
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟"></el-option>
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�"></el-option>
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="priceSearchForm.productType" placeholder="璇烽�夋嫨姘存偿绫诲瀷" clearable>
- <el-option label="鍏ㄩ儴绫诲瀷" value=""></el-option>
- <el-option label="鏅�氱閰哥洂姘存偿" value="鏅�氱閰哥洂姘存偿"></el-option>
- <el-option label="鐭挎福纭呴吀鐩愭按娉�" value="鐭挎福纭呴吀鐩愭按娉�"></el-option>
- <el-option label="澶嶅悎纭呴吀鐩愭按娉�" value="澶嶅悎纭呴吀鐩愭按娉�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="priceSearchForm.strategyType" placeholder="绛栫暐绫诲瀷" clearable>
- <el-option label="鍏ㄩ儴绛栫暐" value=""></el-option>
- <el-option label="涓撳睘浠锋牸" value="涓撳睘浠锋牸"></el-option>
- <el-option label="闃舵鎶ヤ环" value="闃舵鎶ヤ环"></el-option>
- <el-option label="淇冮攢鎶樻墸" value="淇冮攢鎶樻墸"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="searchPriceStrategy">鏌ヨ</el-button>
- <el-button @click="resetPriceSearch">閲嶇疆</el-button>
- <el-button type="primary" @click="handleAddPriceStrategy">鏂板绛栫暐</el-button>
- </el-col>
- </el-row>
-
- <el-table :data="priceStrategyList" border stripe v-loading="priceLoading" height="calc(100vh - 26em)">
- <el-table-column prop="id" label="ID" width="60" align="center"/>
- <el-table-column prop="strategyNo" label="绛栫暐缂栧彿" width="150"/>
- <el-table-column prop="strategyType" label="绛栫暐绫诲瀷" width="100">
- <template #default="scope">
- <el-tag :type="getStrategyTypeColor(scope.row.strategyType)">
- {{ scope.row.strategyType }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="customerName" label="瀹㈡埛鍚嶇О" width="180"/>
- <el-table-column prop="productName" label="浜у搧鍚嶇О" width="200"/>
- <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" width="120"/>
- <el-table-column prop="basePrice" label="鍩虹浠锋牸" width="100">
- <template #default="scope">
- 楼{{ scope.row.basePrice }}/鍚�
- </template>
- </el-table-column>
- <el-table-column prop="strategyPrice" label="绛栫暐浠锋牸" width="120">
- <template #default="scope">
- <span style="color: #f56c6c; font-weight: bold;">
- {{ scope.row.strategyPrice }}
- </span>
- </template>
- </el-table-column>
- <el-table-column prop="validPeriod" label="鏈夋晥鏈�" width="200">
- <template #default="scope">
- {{ scope.row.startDate }} 鑷� {{ scope.row.endDate }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="80">
- <template #default="scope">
- <el-tag :type="scope.row.status === '鐢熸晥涓�' ? 'success' : 'info'">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleViewPriceStrategy(scope.row)">鏌ョ湅</el-button>
- <el-button link type="primary" @click="handleEditPriceStrategy(scope.row)">缂栬緫</el-button>
- <el-button link type="danger" @click="handleDeletePriceStrategy(scope.row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <pagination
- :total="pricePagination.total"
- :page="pricePagination.currentPage"
- :limit="pricePagination.pageSize"
- @pagination="handlePricePageChange"
- />
- </el-card>
- </el-tab-pane>
-
- <!-- 鍚堝悓鎵ц鐩戞帶 -->
- <el-tab-pane label="鍚堝悓鎵ц鐩戞帶" name="contractMonitor">
- <el-card class="box-card">
- <!-- 缁熻姒傝 -->
- <el-row :gutter="20" class="stats-row">
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #ecf5ff;">
- <el-icon :size="30" color="#409eff"><Document /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ contractStats.totalContracts }}</div>
- <div class="stat-label">鍚堝悓鎬绘暟</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f0f9ff;">
- <el-icon :size="30" color="#67c23a"><Van /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ contractStats.deliveryRate }}%</div>
- <div class="stat-label">浜や粯瀹屾垚鐜�</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #fef0f0;">
- <el-icon :size="30" color="#e6a23c"><Tickets /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ contractStats.invoiceRate }}%</div>
- <div class="stat-label">鍙戠エ寮�鍏风巼</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f4f4f5;">
- <el-icon :size="30" color="#f56c6c"><Wallet /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ contractStats.paymentRate }}%</div>
- <div class="stat-label">鍥炴瀹屾垚鐜�</div>
- </div>
- </div>
- </el-col>
- </el-row>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-input v-model="contractSearchForm.contractNo" placeholder="璇疯緭鍏ュ悎鍚岀紪鍙�" clearable>
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="6">
- <el-select v-model="contractSearchForm.customerName" placeholder="璇烽�夋嫨瀹㈡埛" clearable>
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟"></el-option>
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�"></el-option>
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="contractSearchForm.executionStatus" placeholder="鎵ц鐘舵��" clearable>
- <el-option label="寰呮墽琛�" value="寰呮墽琛�"></el-option>
- <el-option label="鎵ц涓�" value="鎵ц涓�"></el-option>
- <el-option label="宸插畬鎴�" value="宸插畬鎴�"></el-option>
- <el-option label="寮傚父" value="寮傚父"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-button type="primary" @click="searchContract">鏌ヨ</el-button>
- <el-button @click="resetContractSearch">閲嶇疆</el-button>
- </el-col>
- </el-row>
-
- <!-- 鍚堝悓鍒楄〃 -->
- <el-table :data="contractList" border stripe v-loading="contractLoading" height="calc(100vh - 36em)">
- <el-table-column type="expand">
- <template #default="scope">
- <div class="contract-detail-expand">
- <el-steps :active="getContractStep(scope.row)" align-center>
- <el-step title="璁㈠崟纭" :description="scope.row.orderDate">
- <template #icon>
- <el-icon :color="scope.row.orderStatus === '宸插畬鎴�' ? '#67c23a' : '#909399'">
- <Check v-if="scope.row.orderStatus === '宸插畬鎴�'" />
- <Clock v-else />
- </el-icon>
- </template>
- </el-step>
- <el-step title="璐х墿浜や粯" :description="`${scope.row.deliveryProgress}%`">
- <template #icon>
- <el-icon :color="scope.row.deliveryProgress === 100 ? '#67c23a' : '#409eff'">
- <Check v-if="scope.row.deliveryProgress === 100" />
- <Van v-else />
- </el-icon>
- </template>
- </el-step>
- <el-step title="鍙戠エ寮�鍏�" :description="`${scope.row.invoiceProgress}%`">
- <template #icon>
- <el-icon :color="scope.row.invoiceProgress === 100 ? '#67c23a' : '#e6a23c'">
- <Check v-if="scope.row.invoiceProgress === 100" />
- <Tickets v-else />
- </el-icon>
- </template>
- </el-step>
- <el-step title="娆鹃」鏀跺洖" :description="`${scope.row.paymentProgress}%`">
- <template #icon>
- <el-icon :color="scope.row.paymentProgress === 100 ? '#67c23a' : '#f56c6c'">
- <Check v-if="scope.row.paymentProgress === 100" />
- <Wallet v-else />
- </el-icon>
- </template>
- </el-step>
- </el-steps>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="contractNo" label="鍚堝悓缂栧彿" width="150"/>
- <el-table-column prop="customerName" label="瀹㈡埛鍚嶇О" width="180"/>
- <el-table-column prop="contractAmount" label="鍚堝悓閲戦" width="120">
- <template #default="scope">
- 楼{{ scope.row.contractAmount.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="signDate" label="绛捐鏃ユ湡" width="120"/>
- <el-table-column label="鎵ц杩涘害" width="150">
- <template #default="scope">
- <el-progress
- :percentage="scope.row.executionProgress"
- :color="getProgressColor(scope.row.executionProgress)"
- />
- </template>
- </el-table-column>
- <el-table-column prop="deliveryProgress" label="浜や粯杩涘害" width="100">
- <template #default="scope">
- {{ scope.row.deliveryProgress }}%
- </template>
- </el-table-column>
- <el-table-column prop="invoiceProgress" label="寮�绁ㄨ繘搴�" width="100">
- <template #default="scope">
- {{ scope.row.invoiceProgress }}%
- </template>
- </el-table-column>
- <el-table-column prop="paymentProgress" label="鍥炴杩涘害" width="100">
- <template #default="scope">
- {{ scope.row.paymentProgress }}%
- </template>
- </el-table-column>
- <el-table-column prop="executionStatus" label="鎵ц鐘舵��" width="100">
- <template #default="scope">
- <el-tag :type="getExecutionStatusType(scope.row.executionStatus)">
- {{ scope.row.executionStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="120" fixed="right" align="center">
- <template #default="scope">
- <el-button link type="primary" @click="handleViewContract(scope.row)">鏌ョ湅璇︽儏</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <pagination
- :total="contractPagination.total"
- :page="contractPagination.currentPage"
- :limit="contractPagination.pageSize"
- @pagination="handleContractPageChange"
- />
- </el-card>
- </el-tab-pane>
-
- <!-- 鍘嗗彶姣斾环鍒嗘瀽 -->
- <el-tab-pane label="鍘嗗彶姣斾环鍒嗘瀽" name="priceComparison">
- <el-card class="box-card">
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-select v-model="compareSearchForm.productName" placeholder="璇烽�夋嫨浜у搧" clearable>
- <el-option label="P.O 42.5鏅�氱閰哥洂姘存偿" value="P.O 42.5鏅�氱閰哥洂姘存偿"></el-option>
- <el-option label="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" value="P.S 32.5鐭挎福纭呴吀鐩愭按娉�"></el-option>
- <el-option label="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" value="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="8">
- <el-date-picker
- v-model="compareSearchForm.dateRange"
- type="daterange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�"
- end-placeholder="缁撴潫鏃ユ湡"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- />
- </el-col>
- <el-col :span="6">
- <el-select v-model="compareSearchForm.region" placeholder="閿�鍞尯鍩�" clearable>
- <el-option label="鍗庝笢鍦板尯" value="鍗庝笢鍦板尯"></el-option>
- <el-option label="鍗庡崡鍦板尯" value="鍗庡崡鍦板尯"></el-option>
- <el-option label="鍗庡寳鍦板尯" value="鍗庡寳鍦板尯"></el-option>
- </el-select>
- </el-col>
- <el-col :span="4">
- <el-button type="primary" @click="searchPriceComparison">鏌ヨ</el-button>
- <el-button @click="resetCompareSearch">閲嶇疆</el-button>
- </el-col>
- </el-row>
-
- <!-- 浠锋牸瓒嬪娍鍥� -->
- <div class="chart-container">
- <div ref="priceChartRef" style="width: 100%; height: 350px;"></div>
- </div>
-
- <!-- 鍘嗗彶浠锋牸鍒楄〃 -->
- <el-table :data="priceComparisonList" border stripe v-loading="compareLoading" style="margin-top: 20px;">
- <el-table-column prop="date" label="鏃ユ湡" width="120"/>
- <el-table-column prop="productName" label="浜у搧鍚嶇О" width="200"/>
- <el-table-column prop="specification" label="瑙勬牸" width="120"/>
- <el-table-column prop="customerName" label="瀹㈡埛" width="180"/>
- <el-table-column prop="region" label="鍖哄煙" width="100"/>
- <el-table-column prop="quantity" label="鏁伴噺(鍚�)" width="100" align="right">
- <template #default="scope">
- {{ scope.row.quantity.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="price" label="鎴愪氦鍗曚环" width="100">
- <template #default="scope">
- 楼{{ scope.row.price }}/鍚�
- </template>
- </el-table-column>
- <el-table-column prop="totalAmount" label="鎴愪氦閲戦" width="120">
- <template #default="scope">
- 楼{{ scope.row.totalAmount.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="priceChange" label="浠锋牸鍙樺姩" width="100">
- <template #default="scope">
- <span :style="{ color: scope.row.priceChange > 0 ? '#f56c6c' : scope.row.priceChange < 0 ? '#67c23a' : '#909399' }">
- {{ scope.row.priceChange > 0 ? '+' : '' }}{{ scope.row.priceChange }}
- </span>
- </template>
- </el-table-column>
- <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip/>
- </el-table>
- </el-card>
- </el-tab-pane>
-
- <!-- 鍒╂鼎鍒嗘瀽 -->
- <el-tab-pane label="鍒╂鼎鍒嗘瀽" name="profitAnalysis">
- <el-card class="box-card">
- <!-- 鍒╂鼎缁熻鍗$墖 -->
- <el-row :gutter="20" class="profit-stats-row">
- <el-col :span="8">
- <div class="profit-card">
- <div class="profit-header">鎬婚攢鍞</div>
- <div class="profit-value">楼{{ profitStats.totalSales.toLocaleString() }}</div>
- <div class="profit-footer">
- <span>杈冧笂鏈�</span>
- <span :class="profitStats.salesGrowth > 0 ? 'growth-up' : 'growth-down'">
- {{ profitStats.salesGrowth > 0 ? '+' : '' }}{{ profitStats.salesGrowth }}%
- </span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="profit-card">
- <div class="profit-header">鎬绘垚鏈�</div>
- <div class="profit-value">楼{{ profitStats.totalCost.toLocaleString() }}</div>
- <div class="profit-footer">
- <span>鎴愭湰鐜�</span>
- <span class="cost-rate">{{ profitStats.costRate }}%</span>
- </div>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="profit-card">
- <div class="profit-header">姣涘埄娑�</div>
- <div class="profit-value profit-highlight">楼{{ profitStats.grossProfit.toLocaleString() }}</div>
- <div class="profit-footer">
- <span>姣涘埄鐜�</span>
- <span class="gross-profit-rate">{{ profitStats.grossProfitRate }}%</span>
- </div>
- </div>
- </el-col>
- </el-row>
-
- <!-- 鎼滅储鍖哄煙 -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-select v-model="profitSearchForm.productType" placeholder="浜у搧绫诲瀷" clearable>
- <el-option label="鏅�氱閰哥洂姘存偿" value="鏅�氱閰哥洂姘存偿"></el-option>
- <el-option label="鐭挎福纭呴吀鐩愭按娉�" value="鐭挎福纭呴吀鐩愭按娉�"></el-option>
- <el-option label="澶嶅悎纭呴吀鐩愭按娉�" value="澶嶅悎纭呴吀鐩愭按娉�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="profitSearchForm.customerName" placeholder="瀹㈡埛鍚嶇О" clearable>
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟"></el-option>
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�"></el-option>
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�"></el-option>
- </el-select>
- </el-col>
- <el-col :span="8">
- <el-date-picker
- v-model="profitSearchForm.dateRange"
- type="monthrange"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫湀浠�"
- end-placeholder="缁撴潫鏈堜唤"
- value-format="YYYY-MM"
- style="width: 100%"
- />
- </el-col>
- <el-col :span="4">
- <el-button type="primary" @click="searchProfit">鏌ヨ</el-button>
- <el-button @click="resetProfitSearch">閲嶇疆</el-button>
- </el-col>
- </el-row>
-
- <!-- 鍒╂鼎鍒嗘瀽鍥捐〃 -->
- <div class="chart-container">
- <div ref="profitChartRef" style="width: 100%; height: 350px;"></div>
- </div>
-
- <!-- 鍒╂鼎鏄庣粏琛� -->
- <el-table :data="profitAnalysisList" border stripe v-loading="profitLoading" style="margin-top: 20px;" show-summary :summary-method="getProfitSummary">
- <el-table-column prop="orderNo" label="璁㈠崟缂栧彿" width="150"/>
- <el-table-column prop="customerName" label="瀹㈡埛鍚嶇О" width="180"/>
- <el-table-column prop="productName" label="浜у搧鍚嶇О" width="200"/>
- <el-table-column prop="quantity" label="鏁伴噺(鍚�)" width="100" align="right">
- <template #default="scope">
- {{ scope.row.quantity.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="salesPrice" label="閿�鍞崟浠�" width="100">
- <template #default="scope">
- 楼{{ scope.row.salesPrice }}
- </template>
- </el-table-column>
- <el-table-column prop="costPrice" label="鎴愭湰鍗曚环" width="100">
- <template #default="scope">
- 楼{{ scope.row.costPrice }}
- </template>
- </el-table-column>
- <el-table-column prop="salesAmount" label="閿�鍞噾棰�" width="120" align="right">
- <template #default="scope">
- 楼{{ scope.row.salesAmount.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="costAmount" label="鎴愭湰閲戦" width="120" align="right">
- <template #default="scope">
- 楼{{ scope.row.costAmount.toLocaleString() }}
- </template>
- </el-table-column>
- <el-table-column prop="grossProfit" label="姣涘埄娑�" width="120" align="right">
- <template #default="scope">
- <span :style="{ color: scope.row.grossProfit > 0 ? '#67c23a' : '#f56c6c', fontWeight: 'bold' }">
- 楼{{ scope.row.grossProfit.toLocaleString() }}
- </span>
- </template>
- </el-table-column>
- <el-table-column prop="grossProfitRate" label="姣涘埄鐜�" width="100">
- <template #default="scope">
- <el-tag :type="getProfitRateType(scope.row.grossProfitRate)">
- {{ scope.row.grossProfitRate }}%
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="orderDate" label="璁㈠崟鏃ユ湡" width="120"/>
- </el-table>
-
- <pagination
- :total="profitPagination.total"
- :page="profitPagination.currentPage"
- :limit="profitPagination.pageSize"
- @pagination="handleProfitPageChange"
- />
- </el-card>
- </el-tab-pane>
-
- <!-- 鎸囨爣缁熻锛堝缁村害閿�鍞垎鏋愶級 -->
- <el-tab-pane label="鎸囨爣缁熻" name="indicatorStats">
- <el-card class="box-card">
- <!-- KPI 姹囨�� -->
- <el-row :gutter="20" class="stats-row">
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #ecf5ff;">
- <el-icon :size="30" color="#409eff"><Document /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.orderCount.toLocaleString() }}</div>
- <div class="stat-label">璁㈠崟鏁伴噺</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f0f9ff;">
- <el-icon :size="30" color="#67c23a"><Tickets /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">楼{{ indicatorKpis.salesAmount.toLocaleString() }}</div>
- <div class="stat-label">閿�鍞</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #fef0f0;">
- <el-icon :size="30" color="#e6a23c"><Van /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.shipmentRate }}%</div>
- <div class="stat-label">鍙戣揣鐜�</div>
- </div>
- </div>
- </el-col>
- <el-col :span="6">
- <div class="stat-card">
- <div class="stat-icon" style="background: #f4f4f5;">
- <el-icon :size="30" color="#f56c6c"><Wallet /></el-icon>
- </div>
- <div class="stat-content">
- <div class="stat-value">{{ indicatorKpis.collectionRate }}%</div>
- <div class="stat-label">鍥炴鐜�</div>
- </div>
- </div>
- </el-col>
- </el-row>
-
- <!-- 缁村害绛涢�� -->
- <el-row :gutter="20" class="search-row">
- <el-col :span="6">
- <el-select v-model="indicatorFilter.product" placeholder="浜у搧" clearable>
- <el-option label="鍏ㄩ儴浜у搧" value="" />
- <el-option label="P.O 42.5鏅�氱閰哥洂姘存偿" value="P.O 42.5鏅�氱閰哥洂姘存偿" />
- <el-option label="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" value="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" />
- <el-option label="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" value="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="indicatorFilter.customer" placeholder="瀹㈡埛" clearable>
- <el-option label="鍏ㄩ儴瀹㈡埛" value="" />
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟" />
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�" />
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-select v-model="indicatorFilter.region" placeholder="鍖哄煙" clearable>
- <el-option label="鍏ㄩ儴鍖哄煙" value="" />
- <el-option label="鍗庝笢鍦板尯" value="鍗庝笢鍦板尯" />
- <el-option label="鍗庡崡鍦板尯" value="鍗庡崡鍦板尯" />
- <el-option label="鍗庡寳鍦板尯" value="鍗庡寳鍦板尯" />
- </el-select>
- </el-col>
- <el-col :span="6">
- <el-date-picker v-model="indicatorFilter.dateRange" type="daterange" range-separator="鑷�"
- start-placeholder="寮�濮嬫棩鏈�" end-placeholder="缁撴潫鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%" />
- </el-col>
- <el-col :span="24" style="text-align: right; margin-top: 10px;">
- <el-button type="primary" @click="applyIndicatorFilter">鏌ヨ</el-button>
- <el-button @click="resetIndicatorFilter">閲嶇疆</el-button>
- <el-button @click="exportIndicatorTable">瀵煎嚭鎶ヨ〃</el-button>
- <el-button @click="exportIndicatorChart">瀵煎嚭鍥捐〃</el-button>
- </el-col>
- </el-row>
-
- <!-- 鍥捐〃鍖� -->
- <div class="chart-container">
- <div ref="indicatorChartRef" style="width: 100%; height: 360px;"></div>
- </div>
-
- <!-- 涓氱哗缁熻锛堝洟闃熺淮搴︼紝鏃犱釜浜哄鍚嶏級 -->
- <el-table :data="teamPerformanceList" border stripe style="margin-top: 20px;">
- <el-table-column prop="team" label="閿�鍞洟闃�" width="140" />
- <el-table-column prop="orderCount" label="璁㈠崟鏁�" width="100" />
- <el-table-column prop="salesAmount" label="閿�鍞" width="140">
- <template #default="scope">楼{{ scope.row.salesAmount.toLocaleString() }}</template>
- </el-table-column>
- <el-table-column prop="shipmentRate" label="鍙戣揣鐜�" width="100">
- <template #default="scope">{{ scope.row.shipmentRate }}%</template>
- </el-table-column>
- <el-table-column prop="collectionRate" label="鍥炴鐜�" width="100">
- <template #default="scope">{{ scope.row.collectionRate }}%</template>
- </el-table-column>
- <el-table-column prop="attainment" label="鐩爣杈炬垚鐜�" width="120">
- <template #default="scope">
- <el-tag :type="scope.row.attainment >= 100 ? 'success' : scope.row.attainment >= 80 ? 'warning' : 'danger'">
- {{ scope.row.attainment }}%
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </el-tab-pane>
- </el-tabs>
-
- <!-- 浠锋牸绛栫暐瀵硅瘽妗� -->
- <el-dialog v-model="priceStrategyDialogVisible" :title="priceStrategyDialogTitle" width="900px" :close-on-click-modal="false">
- <el-form :model="priceStrategyForm" :rules="priceStrategyRules" ref="priceStrategyFormRef" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="绛栫暐绫诲瀷" prop="strategyType">
- <el-select v-model="priceStrategyForm.strategyType" placeholder="璇烽�夋嫨绛栫暐绫诲瀷" style="width: 100%;" :disabled="priceStrategyDialogMode === 'view'">
- <el-option label="涓撳睘浠锋牸" value="涓撳睘浠锋牸"></el-option>
- <el-option label="闃舵鎶ヤ环" value="闃舵鎶ヤ环"></el-option>
- <el-option label="淇冮攢鎶樻墸" value="淇冮攢鎶樻墸"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О" prop="customerName">
- <el-select v-model="priceStrategyForm.customerName" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%;" :disabled="priceStrategyDialogMode === 'view'">
- <el-option label="鍗庝笢寤烘潗闆嗗洟" value="鍗庝笢寤烘潗闆嗗洟"></el-option>
- <el-option label="闀挎睙娣峰嚌鍦熷叕鍙�" value="闀挎睙娣峰嚌鍦熷叕鍙�"></el-option>
- <el-option label="娴︽睙姘存偿鍒跺搧鍘�" value="娴︽睙姘存偿鍒跺搧鍘�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="浜у搧鍚嶇О" prop="productName">
- <el-select v-model="priceStrategyForm.productName" placeholder="璇烽�夋嫨浜у搧" style="width: 100%;" :disabled="priceStrategyDialogMode === 'view'">
- <el-option label="P.O 42.5鏅�氱閰哥洂姘存偿" value="P.O 42.5鏅�氱閰哥洂姘存偿"></el-option>
- <el-option label="P.S 32.5鐭挎福纭呴吀鐩愭按娉�" value="P.S 32.5鐭挎福纭呴吀鐩愭按娉�"></el-option>
- <el-option label="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�" value="P.C 32.5澶嶅悎纭呴吀鐩愭按娉�"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
- <el-input v-model="priceStrategyForm.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" :disabled="priceStrategyDialogMode === 'view'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鍩虹浠锋牸(鍏�/鍚�)" prop="basePrice">
- <el-input-number v-model="priceStrategyForm.basePrice" :min="0" :precision="2" style="width: 100%;" :disabled="priceStrategyDialogMode === 'view'" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="绛栫暐浠锋牸" prop="strategyPrice">
- <el-input v-model="priceStrategyForm.strategyPrice" placeholder="濡�: 楼350/鍚� 鎴� 9鎶�" :disabled="priceStrategyDialogMode === 'view'" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="鐢熸晥鏃ユ湡" prop="startDate">
- <el-date-picker
- v-model="priceStrategyForm.startDate"
- type="date"
- placeholder="閫夋嫨鐢熸晥鏃ユ湡"
- style="width: 100%"
- value-format="YYYY-MM-DD"
- :disabled="priceStrategyDialogMode === 'view'"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="澶辨晥鏃ユ湡" prop="endDate">
- <el-date-picker
- v-model="priceStrategyForm.endDate"
- type="date"
- placeholder="閫夋嫨澶辨晥鏃ユ湡"
- style="width: 100%"
- value-format="YYYY-MM-DD"
- :disabled="priceStrategyDialogMode === 'view'"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="绛栫暐璇存槑" prop="description">
- <el-input type="textarea" v-model="priceStrategyForm.description" :rows="3" placeholder="璇疯緭鍏ョ瓥鐣ヨ鏄�" :disabled="priceStrategyDialogMode === 'view'" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="priceStrategyDialogVisible = false">{{ priceStrategyDialogMode === 'view' ? '鍏抽棴' : '鍙栨秷' }}</el-button>
- <el-button v-if="priceStrategyDialogMode !== 'view'" type="primary" @click="handleSavePriceStrategy">淇濆瓨</el-button>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, nextTick, watch } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Document, Van, Tickets, Wallet, Check, Clock, Search } from '@element-plus/icons-vue'
-import * as echarts from 'echarts'
-import Pagination from '@/components/PIMTable/Pagination.vue'
-
-// 娲诲姩鏍囩椤�
-const activeTab = ref('priceStrategy')
-
-// ========== 浠锋牸绛栫暐閰嶇疆 ==========
-const priceLoading = ref(false)
-const priceSearchForm = reactive({
- customerName: '',
- productType: '',
- strategyType: ''
-})
-
-const priceStrategyList = ref([
- {
- id: 1,
- strategyNo: 'PS202501001',
- strategyType: '涓撳睘浠锋牸',
- customerName: '鍗庝笢寤烘潗闆嗗洟',
- productName: 'P.O 42.5鏅�氱閰哥洂姘存偿',
- specification: '50kg/琚�',
- basePrice: 380,
- strategyPrice: '楼350/鍚�',
- startDate: '2025-01-01',
- endDate: '2025-12-31',
- status: '鐢熸晥涓�',
- description: '鎴樼暐鍚堜綔瀹㈡埛涓撳睘浼樻儬浠锋牸'
- },
- {
- id: 2,
- strategyNo: 'PS202501002',
- strategyType: '闃舵鎶ヤ环',
- customerName: '闀挎睙娣峰嚌鍦熷叕鍙�',
- productName: 'P.S 32.5鐭挎福纭呴吀鐩愭按娉�',
- specification: '50kg/琚�',
- basePrice: 320,
- strategyPrice: '500鍚ㄤ互涓�9鎶�',
- startDate: '2025-01-01',
- endDate: '2025-06-30',
- status: '鐢熸晥涓�',
- description: '澶ф壒閲忛噰璐樁姊紭鎯�'
- },
- {
- id: 3,
- strategyNo: 'PS202501003',
- strategyType: '淇冮攢鎶樻墸',
- customerName: '娴︽睙姘存偿鍒跺搧鍘�',
- productName: 'P.C 32.5澶嶅悎纭呴吀鐩愭按娉�',
- specification: '50kg/琚�',
- basePrice: 300,
- strategyPrice: '8.5鎶�',
- startDate: '2025-01-15',
- endDate: '2025-02-28',
- status: '鐢熸晥涓�',
- description: '鏄ヨ妭淇冮攢娲诲姩'
- },
- {
- id: 4,
- strategyNo: 'PS202412015',
- strategyType: '涓撳睘浠锋牸',
- customerName: '鍗庝笢寤烘潗闆嗗洟',
- productName: 'P.C 32.5澶嶅悎纭呴吀鐩愭按娉�',
- specification: '50kg/琚�',
- basePrice: 300,
- strategyPrice: '楼285/鍚�',
- startDate: '2024-10-01',
- endDate: '2024-12-31',
- status: '宸茶繃鏈�',
- description: '绗洓瀛e害涓撳睘浠锋牸'
- }
-])
-
-const pricePagination = reactive({
- total: 4,
- currentPage: 1,
- pageSize: 10
-})
-
-const priceStrategyDialogVisible = ref(false)
-const priceStrategyDialogTitle = ref('鏂板浠锋牸绛栫暐')
-const priceStrategyDialogMode = ref('add') // add | edit | view
-const priceStrategyForm = reactive({
- strategyType: '',
- customerName: '',
- productName: '',
- specification: '',
- basePrice: 0,
- strategyPrice: '',
- startDate: '',
- endDate: '',
- description: ''
-})
-
-const priceStrategyRules = {
- strategyType: [{ required: true, message: '璇烽�夋嫨绛栫暐绫诲瀷', trigger: 'change' }],
- customerName: [{ required: true, message: '璇烽�夋嫨瀹㈡埛', trigger: 'change' }],
- productName: [{ required: true, message: '璇烽�夋嫨浜у搧', trigger: 'change' }],
- basePrice: [{ required: true, message: '璇疯緭鍏ュ熀纭�浠锋牸', trigger: 'blur' }],
- strategyPrice: [{ required: true, message: '璇疯緭鍏ョ瓥鐣ヤ环鏍�', trigger: 'blur' }],
- startDate: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃ユ湡', trigger: 'change' }],
- endDate: [{ required: true, message: '璇烽�夋嫨澶辨晥鏃ユ湡', trigger: 'change' }]
-}
-
-const priceStrategyFormRef = ref()
-
-// ========== 鍚堝悓鎵ц鐩戞帶 ==========
-const contractLoading = ref(false)
-const contractStats = reactive({
- totalContracts: 48,
- deliveryRate: 87.5,
- invoiceRate: 82.3,
- paymentRate: 75.6
-})
-
-const contractSearchForm = reactive({
- contractNo: '',
- customerName: '',
- executionStatus: ''
-})
-
-const contractList = ref([
- {
- id: 1,
- contractNo: 'CT202501001',
- customerName: '鍗庝笢寤烘潗闆嗗洟',
- contractAmount: 2850000,
- signDate: '2025-01-05',
- executionProgress: 85,
- deliveryProgress: 90,
- invoiceProgress: 85,
- paymentProgress: 75,
- executionStatus: '鎵ц涓�',
- orderStatus: '宸插畬鎴�',
- orderDate: '2025-01-05'
- },
- {
- id: 2,
- contractNo: 'CT202501002',
- customerName: '闀挎睙娣峰嚌鍦熷叕鍙�',
- contractAmount: 1650000,
- signDate: '2025-01-08',
- executionProgress: 95,
- deliveryProgress: 100,
- invoiceProgress: 100,
- paymentProgress: 85,
- executionStatus: '鎵ц涓�',
- orderStatus: '宸插畬鎴�',
- orderDate: '2025-01-08'
- },
- {
- id: 3,
- contractNo: 'CT202501003',
- customerName: '娴︽睙姘存偿鍒跺搧鍘�',
- contractAmount: 980000,
- signDate: '2025-01-12',
- executionProgress: 60,
- deliveryProgress: 65,
- invoiceProgress: 60,
- paymentProgress: 50,
- executionStatus: '鎵ц涓�',
- orderStatus: '宸插畬鎴�',
- orderDate: '2025-01-12'
- },
- {
- id: 4,
- contractNo: 'CT202412028',
- customerName: '鍗庝笢寤烘潗闆嗗洟',
- contractAmount: 3200000,
- signDate: '2024-12-15',
- executionProgress: 100,
- deliveryProgress: 100,
- invoiceProgress: 100,
- paymentProgress: 100,
- executionStatus: '宸插畬鎴�',
- orderStatus: '宸插畬鎴�',
- orderDate: '2024-12-15'
- },
- {
- id: 5,
- contractNo: 'CT202501004',
- customerName: '闀挎睙娣峰嚌鍦熷叕鍙�',
- contractAmount: 750000,
- signDate: '2025-01-20',
- executionProgress: 25,
- deliveryProgress: 30,
- invoiceProgress: 20,
- paymentProgress: 0,
- executionStatus: '寮傚父',
- orderStatus: '宸插畬鎴�',
- orderDate: '2025-01-20'
- }
-])
-
-const contractPagination = reactive({
- total: 5,
- currentPage: 1,
- pageSize: 10
-})
-
-// ========== 鍘嗗彶姣斾环鍒嗘瀽 ==========
-const compareLoading = ref(false)
-const compareSearchForm = reactive({
- productName: '',
- dateRange: [],
- region: ''
-})
-
-const priceComparisonList = ref([
- { date: '2025-01-20', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '鍗庝笢寤烘潗闆嗗洟', region: '鍗庝笢鍦板尯', quantity: 5000, price: 350, totalAmount: 1750000, priceChange: 0, remark: '闀挎湡鍚堜綔瀹㈡埛' },
- { date: '2025-01-15', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '娴︿笢鏂板尯寤虹瓚鍏徃', region: '鍗庝笢鍦板尯', quantity: 3000, price: 365, totalAmount: 1095000, priceChange: +15, remark: '鐜版鐜拌揣' },
- { date: '2025-01-10', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '闀挎睙娣峰嚌鍦熷叕鍙�', region: '鍗庝笢鍦板尯', quantity: 8000, price: 345, totalAmount: 2760000, priceChange: -5, remark: '澶ф壒閲忎紭鎯�' },
- { date: '2025-01-05', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '姹熻嫃宸ョ▼闆嗗洟', region: '鍗庝笢鍦板尯', quantity: 4500, price: 360, totalAmount: 1620000, priceChange: +10, remark: '宸ョ▼椤圭洰涓撶敤' },
- { date: '2024-12-28', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '鍗庝笢寤烘潗闆嗗洟', region: '鍗庝笢鍦板尯', quantity: 6000, price: 355, totalAmount: 2130000, priceChange: +5, remark: '骞村簳澶囪揣' },
- { date: '2024-12-20', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', specification: '50kg/琚�', customerName: '涓婃捣甯傛斂宸ョ▼', region: '鍗庝笢鍦板尯', quantity: 10000, price: 340, totalAmount: 3400000, priceChange: -10, remark: '鏀垮簻椤圭洰' }
-])
-
-const priceChartRef = ref(null)
-let priceChart = null
-
-// ========== 鍒╂鼎鍒嗘瀽 ==========
-const profitLoading = ref(false)
-const profitStats = reactive({
- totalSales: 15680000,
- totalCost: 11256000,
- grossProfit: 4424000,
- grossProfitRate: 28.2,
- salesGrowth: 12.5,
- costRate: 71.8
-})
-
-const profitSearchForm = reactive({
- productType: '',
- customerName: '',
- dateRange: []
-})
-
-const profitAnalysisList = ref([
- { orderNo: 'SO202501015', customerName: '鍗庝笢寤烘潗闆嗗洟', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', quantity: 5000, salesPrice: 350, costPrice: 245, salesAmount: 1750000, costAmount: 1225000, grossProfit: 525000, grossProfitRate: 30.0, orderDate: '2025-01-20' },
- { orderNo: 'SO202501012', customerName: '闀挎睙娣峰嚌鍦熷叕鍙�', productName: 'P.S 32.5鐭挎福纭呴吀鐩愭按娉�', quantity: 3500, salesPrice: 288, costPrice: 210, salesAmount: 1008000, costAmount: 735000, grossProfit: 273000, grossProfitRate: 27.1, orderDate: '2025-01-18' },
- { orderNo: 'SO202501008', customerName: '娴︽睙姘存偿鍒跺搧鍘�', productName: 'P.C 32.5澶嶅悎纭呴吀鐩愭按娉�', quantity: 2800, salesPrice: 255, costPrice: 185, salesAmount: 714000, costAmount: 518000, grossProfit: 196000, grossProfitRate: 27.5, orderDate: '2025-01-15' },
- { orderNo: 'SO202501005', customerName: '鍗庝笢寤烘潗闆嗗洟', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', quantity: 6000, salesPrice: 350, costPrice: 248, salesAmount: 2100000, costAmount: 1488000, grossProfit: 612000, grossProfitRate: 29.1, orderDate: '2025-01-10' },
- { orderNo: 'SO202501003', customerName: '姹熻嫃宸ョ▼闆嗗洟', productName: 'P.O 42.5鏅�氱閰哥洂姘存偿', quantity: 4500, salesPrice: 360, costPrice: 250, salesAmount: 1620000, costAmount: 1125000, grossProfit: 495000, grossProfitRate: 30.6, orderDate: '2025-01-08' },
- { orderNo: 'SO202412025', customerName: '闀挎睙娣峰嚌鍦熷叕鍙�', productName: 'P.S 32.5鐭挎福纭呴吀鐩愭按娉�', quantity: 8000, salesPrice: 290, costPrice: 215, salesAmount: 2320000, costAmount: 1720000, grossProfit: 600000, grossProfitRate: 25.9, orderDate: '2024-12-28' }
-])
-
-const profitPagination = reactive({
- total: 6,
- currentPage: 1,
- pageSize: 10
-})
-
-const profitChartRef = ref(null)
-let profitChart = null
-
-// ========== 鏂规硶 ==========
-
-// 浠锋牸绛栫暐鐩稿叧鏂规硶
-const getStrategyTypeColor = (type) => {
- const colorMap = {
- '涓撳睘浠锋牸': 'success',
- '闃舵鎶ヤ环': 'primary',
- '淇冮攢鎶樻墸': 'warning'
- }
- return colorMap[type] || 'info'
-}
-
-const searchPriceStrategy = () => {
- priceLoading.value = true
- setTimeout(() => {
- priceLoading.value = false
- }, 500)
-}
-
-const resetPriceSearch = () => {
- priceSearchForm.customerName = ''
- priceSearchForm.productType = ''
- priceSearchForm.strategyType = ''
-}
-
-const handleAddPriceStrategy = () => {
- priceStrategyDialogTitle.value = '鏂板浠锋牸绛栫暐'
- resetPriceStrategyForm()
- priceStrategyDialogMode.value = 'add'
- priceStrategyDialogVisible.value = true
-}
-
-const handleViewPriceStrategy = (row) => {
- priceStrategyDialogTitle.value = '鏌ョ湅浠锋牸绛栫暐'
- Object.assign(priceStrategyForm, row)
- priceStrategyDialogMode.value = 'view'
- priceStrategyDialogVisible.value = true
-}
-
-const handleEditPriceStrategy = (row) => {
- priceStrategyDialogTitle.value = '缂栬緫浠锋牸绛栫暐'
- Object.assign(priceStrategyForm, row)
- priceStrategyDialogMode.value = 'edit'
- priceStrategyDialogVisible.value = true
-}
-
-const handleDeletePriceStrategy = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ヤ环鏍肩瓥鐣ュ悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- // 鏈湴鍋囨暟鎹垹闄わ細浠庡垪琛ㄤ腑绉婚櫎骞舵洿鏂版�绘暟
- const index = priceStrategyList.value.findIndex(item => item.id === row.id)
- if (index > -1) {
- priceStrategyList.value.splice(index, 1)
- if (pricePagination.total > 0) pricePagination.total -= 1
- }
- ElMessage.success('鍒犻櫎鎴愬姛')
- })
-}
-
-const resetPriceStrategyForm = () => {
- Object.keys(priceStrategyForm).forEach(key => {
- if (key === 'basePrice') {
- priceStrategyForm[key] = 0
- } else {
- priceStrategyForm[key] = ''
- }
- })
-}
-
-const handleSavePriceStrategy = () => {
- priceStrategyFormRef.value.validate((valid) => {
- if (valid) {
- ElMessage.success('淇濆瓨鎴愬姛')
- priceStrategyDialogVisible.value = false
- }
- })
-}
-
-const handlePricePageChange = (val) => {
- pricePagination.currentPage = val.page
- pricePagination.pageSize = val.limit
-}
-
-// 鍚堝悓鎵ц鐩戞帶鐩稿叧鏂规硶
-const getExecutionStatusType = (status) => {
- const statusMap = {
- '寰呮墽琛�': 'info',
- '鎵ц涓�': 'primary',
- '宸插畬鎴�': 'success',
- '寮傚父': 'danger'
- }
- return statusMap[status] || 'info'
-}
-
-const getProgressColor = (percentage) => {
- if (percentage < 30) return '#f56c6c'
- if (percentage < 70) return '#e6a23c'
- return '#67c23a'
-}
-
-const getContractStep = (row) => {
- if (row.paymentProgress === 100) return 4
- if (row.invoiceProgress === 100) return 3
- if (row.deliveryProgress === 100) return 2
- if (row.orderStatus === '宸插畬鎴�') return 1
- return 0
-}
-
-const searchContract = () => {
- contractLoading.value = true
- setTimeout(() => {
- contractLoading.value = false
- }, 500)
-}
-
-const resetContractSearch = () => {
- contractSearchForm.contractNo = ''
- contractSearchForm.customerName = ''
- contractSearchForm.executionStatus = ''
-}
-
-const handleViewContract = (row) => {
- ElMessage.info('鏌ョ湅鍚堝悓璇︽儏: ' + row.contractNo)
-}
-
-const handleContractPageChange = (val) => {
- contractPagination.currentPage = val.page
- contractPagination.pageSize = val.limit
-}
-
-// 鍘嗗彶姣斾环鍒嗘瀽鐩稿叧鏂规硶
-const searchPriceComparison = () => {
- compareLoading.value = true
- setTimeout(() => {
- compareLoading.value = false
- initPriceChart()
- }, 500)
-}
-
-const resetCompareSearch = () => {
- compareSearchForm.productName = ''
- compareSearchForm.dateRange = []
- compareSearchForm.region = ''
-}
-
-const initPriceChart = () => {
- if (!priceChartRef.value) return
-
- if (priceChart) {
- priceChart.dispose()
- }
-
- priceChart = echarts.init(priceChartRef.value)
-
- const option = {
- title: {
- text: '姘存偿浠锋牸瓒嬪娍鍒嗘瀽',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis',
- formatter: '{b}<br/>{a}: 楼{c}/鍚�'
- },
- legend: {
- data: ['P.O 42.5鏅�氱閰哥洂姘存偿'],
- top: 30
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['2024-12-20', '2024-12-28', '2025-01-05', '2025-01-10', '2025-01-15', '2025-01-20']
- },
- yAxis: {
- type: 'value',
- name: '浠锋牸(鍏�/鍚�)',
- min: 330,
- max: 370
- },
- series: [
- {
- name: 'P.O 42.5鏅�氱閰哥洂姘存偿',
- type: 'line',
- data: [340, 355, 360, 345, 365, 350],
- smooth: true,
- itemStyle: {
- color: '#409eff'
- },
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: 'rgba(64, 158, 255, 0.3)' },
- { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
- ])
- }
- }
- ]
- }
-
- priceChart.setOption(option)
-}
-
-// 鍒╂鼎鍒嗘瀽鐩稿叧鏂规硶
-const searchProfit = () => {
- profitLoading.value = true
- setTimeout(() => {
- profitLoading.value = false
- initProfitChart()
- }, 500)
-}
-
-const resetProfitSearch = () => {
- profitSearchForm.productType = ''
- profitSearchForm.customerName = ''
- profitSearchForm.dateRange = []
-}
-
-const getProfitRateType = (rate) => {
- if (rate >= 30) return 'success'
- if (rate >= 25) return 'warning'
- return 'danger'
-}
-
-const getProfitSummary = (param) => {
- const { columns, data } = param
- const sums = []
- columns.forEach((column, index) => {
- if (index === 0) {
- sums[index] = '鍚堣'
- return
- }
- if (['quantity', 'salesAmount', 'costAmount', 'grossProfit'].includes(column.property)) {
- const values = data.map(item => Number(item[column.property]))
- if (!values.every(value => isNaN(value))) {
- const total = values.reduce((prev, curr) => {
- const value = Number(curr)
- if (!isNaN(value)) {
- return prev + curr
- } else {
- return prev
- }
- }, 0)
- sums[index] = column.property === 'quantity' ? total.toLocaleString() : '楼' + total.toLocaleString()
- }
- } else if (column.property === 'grossProfitRate') {
- // 璁$畻骞冲潎姣涘埄鐜�
- const totalSales = data.reduce((sum, item) => sum + item.salesAmount, 0)
- const totalProfit = data.reduce((sum, item) => sum + item.grossProfit, 0)
- sums[index] = ((totalProfit / totalSales) * 100).toFixed(1) + '%'
- }
- })
- return sums
-}
-
-const initProfitChart = () => {
- if (!profitChartRef.value) return
-
- if (profitChart) {
- profitChart.dispose()
- }
-
- profitChart = echarts.init(profitChartRef.value)
-
- const option = {
- title: {
- text: '閿�鍞笌鍒╂鼎瓒嬪娍鍒嗘瀽',
- left: 'center'
- },
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'cross',
- crossStyle: {
- color: '#999'
- }
- }
- },
- legend: {
- data: ['閿�鍞噾棰�', '鎴愭湰閲戦', '姣涘埄娑�', '姣涘埄鐜�'],
- top: 30
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: [
- {
- type: 'category',
- data: ['2024-12', '2025-01'],
- axisPointer: {
- type: 'shadow'
- }
- }
- ],
- yAxis: [
- {
- type: 'value',
- name: '閲戦(涓囧厓)',
- axisLabel: {
- formatter: '{value}'
- }
- },
- {
- type: 'value',
- name: '姣涘埄鐜�(%)',
- min: 0,
- max: 40,
- axisLabel: {
- formatter: '{value}%'
- }
- }
- ],
- series: [
- {
- name: '閿�鍞噾棰�',
- type: 'bar',
- data: [820, 950],
- itemStyle: {
- color: '#409eff'
- }
- },
- {
- name: '鎴愭湰閲戦',
- type: 'bar',
- data: [605, 670],
- itemStyle: {
- color: '#e6a23c'
- }
- },
- {
- name: '姣涘埄娑�',
- type: 'bar',
- data: [215, 280],
- itemStyle: {
- color: '#67c23a'
- }
- },
- {
- name: '姣涘埄鐜�',
- type: 'line',
- yAxisIndex: 1,
- data: [26.2, 29.5],
- itemStyle: {
- color: '#f56c6c'
- }
- }
- ]
- }
-
- profitChart.setOption(option)
-}
-
-const handleProfitPageChange = (val) => {
- profitPagination.currentPage = val.page
- profitPagination.pageSize = val.limit
-}
-
-// ========== 鎸囨爣缁熻锛堝缁村害鍒嗘瀽锛� ==========
-const indicatorKpis = reactive({
- orderCount: 1280,
- salesAmount: 9650000,
- shipmentRate: 89.2,
- collectionRate: 76.4
-})
-
-const indicatorFilter = reactive({
- product: '',
- customer: '',
- region: '',
- dateRange: []
-})
-
-const indicatorChartRef = ref(null)
-let indicatorChart = null
-
-const teamPerformanceList = ref([
- { team: '鍗庝笢鍥㈤槦A', orderCount: 320, salesAmount: 2850000, shipmentRate: 90, collectionRate: 80, attainment: 105 },
- { team: '鍗庡寳鍥㈤槦B', orderCount: 280, salesAmount: 2150000, shipmentRate: 86, collectionRate: 73, attainment: 92 },
- { team: '鍗庡崡鍥㈤槦C', orderCount: 210, salesAmount: 1850000, shipmentRate: 88, collectionRate: 70, attainment: 78 },
- { team: '瑗垮崡鍥㈤槦D', orderCount: 180, salesAmount: 1500000, shipmentRate: 83, collectionRate: 68, attainment: 74 }
-])
-
-const initIndicatorChart = () => {
- if (!indicatorChartRef.value) return
- if (indicatorChart) indicatorChart.dispose()
- indicatorChart = echarts.init(indicatorChartRef.value)
- const option = {
- title: { text: '澶氱淮搴﹂攢鍞寚鏍囪秼鍔�', left: 'center' },
- tooltip: { trigger: 'axis' },
- legend: { data: ['璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�', '鍥炴鐜�'], top: 30 },
- grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
- xAxis: { type: 'category', data: ['2024-12', '2025-01', '2025-02', '2025-03', '2025-04', '2025-05'] },
- yAxis: [
- { type: 'value', name: '鏁伴噺/閲戦', axisLabel: { formatter: '{value}' } },
- { type: 'value', name: '姣斾緥(%)', min: 0, max: 100, axisLabel: { formatter: '{value}%' } }
- ],
- series: [
- { name: '璁㈠崟鏁�', type: 'bar', data: [180, 220, 210, 260, 205, 225], itemStyle: { color: '#409eff' } },
- { name: '閿�鍞', type: 'bar', data: [820, 950, 910, 1080, 980, 1020], itemStyle: { color: '#67c23a' } },
- { name: '鍙戣揣鐜�', type: 'line', yAxisIndex: 1, data: [86, 89, 88, 91, 87, 90], itemStyle: { color: '#e6a23c' } },
- { name: '鍥炴鐜�', type: 'line', yAxisIndex: 1, data: [72, 76, 74, 79, 75, 78], itemStyle: { color: '#f56c6c' } }
- ]
- }
- indicatorChart.setOption(option)
-}
-
-const applyIndicatorFilter = () => {
- // 浣跨敤鍋囨暟鎹ā鎷熸煡璇紝鍒锋柊KPI鍜屽浘琛�
- // 浠呮紨绀猴細闅忔満寰皟浠ヤ綋鐜扮瓫閫夋晥鏋�
- const random = (base, delta) => {
- const v = base + Math.round((Math.random() - 0.5) * delta)
- return v < 0 ? 0 : v
- }
- indicatorKpis.orderCount = random(1280, 120)
- indicatorKpis.salesAmount = random(9650000, 350000)
- indicatorKpis.shipmentRate = (85 + Math.random() * 10).toFixed(1) * 1
- indicatorKpis.collectionRate = (70 + Math.random() * 12).toFixed(1) * 1
-
- setTimeout(() => initIndicatorChart(), 200)
-}
-
-const resetIndicatorFilter = () => {
- indicatorFilter.product = ''
- indicatorFilter.customer = ''
- indicatorFilter.region = ''
- indicatorFilter.dateRange = []
- applyIndicatorFilter()
-}
-
-const exportIndicatorTable = () => {
- // 瀵煎嚭鍥㈤槦涓氱哗涓篊SV锛堝亣瀵煎嚭锛�
- const header = ['閿�鍞洟闃�', '璁㈠崟鏁�', '閿�鍞', '鍙戣揣鐜�(%)', '鍥炴鐜�(%)', '鐩爣杈炬垚鐜�(%)']
- const rows = teamPerformanceList.value.map(r => [
- r.team,
- r.orderCount,
- r.salesAmount,
- r.shipmentRate,
- r.collectionRate,
- r.attainment
- ])
- const csv = [header, ...rows].map(r => r.join(',')).join('\n')
- const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
- const url = URL.createObjectURL(blob)
- const link = document.createElement('a')
- link.href = url
- link.download = '鎸囨爣缁熻-鍥㈤槦涓氱哗.csv'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
- URL.revokeObjectURL(url)
-}
-
-const exportIndicatorChart = () => {
- if (!indicatorChart) return
- const url = indicatorChart.getDataURL({ type: 'png', pixelRatio: 2, backgroundColor: '#fff' })
- const link = document.createElement('a')
- link.href = url
- link.download = '鎸囨爣缁熻-鍥捐〃.png'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- // 缁勪欢鎸傝浇鍚庝笉绔嬪嵆鍒濆鍖栧浘琛紝绛夊緟鐢ㄦ埛鍒囨崲鍒板搴旀爣绛鹃〉
-})
-
-// 鐩戝惉鏍囩椤靛垏鎹�
-watch(activeTab, (newVal) => {
- nextTick(() => {
- if (newVal === 'priceComparison') {
- initPriceChart()
- } else if (newVal === 'profitAnalysis') {
- initProfitChart()
- } else if (newVal === 'indicatorStats') {
- initIndicatorChart()
- }
- })
-})
-
-const handleTabChange = () => {
- // 鏍囩椤靛垏鎹㈠鐞�
-}
-</script>
-
-<style scoped>
-.strategy-control {
- padding: 0;
-}
-
-.main-tabs {
- border: none;
- box-shadow: none;
-}
-
-.main-tabs :deep(.el-tabs__content) {
- padding: 0;
-}
-
-.box-card {
- border: none;
- box-shadow: none;
-}
-
-.search-row {
- margin-bottom: 20px;
-}
-
-/* 缁熻鍗$墖鏍峰紡 */
-.stats-row {
- margin-bottom: 24px;
-}
-
-.stat-card {
- display: flex;
- align-items: center;
- padding: 20px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-}
-
-.stat-icon {
- width: 60px;
- height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- margin-right: 16px;
-}
-
-.stat-content {
- flex: 1;
-}
-
-.stat-value {
- font-size: 28px;
- font-weight: bold;
- color: #303133;
- margin-bottom: 4px;
-}
-
-.stat-label {
- font-size: 14px;
- color: #909399;
-}
-
-/* 鍚堝悓璇︽儏灞曞紑鏍峰紡 */
-.contract-detail-expand {
- padding: 30px 60px;
- background: #f5f7fa;
-}
-
-.contract-detail-expand :deep(.el-step__title) {
- font-size: 14px;
-}
-
-.contract-detail-expand :deep(.el-step__description) {
- font-size: 12px;
- margin-top: 4px;
-}
-
-/* 鍒╂鼎缁熻鍗$墖 */
-.profit-stats-row {
- margin-bottom: 24px;
-}
-
-.profit-card {
- padding: 24px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 12px;
- color: #fff;
- box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
-}
-
-.profit-card:nth-child(2) .profit-card {
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
-}
-
-.profit-card:nth-child(3) .profit-card {
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
-}
-
-.profit-header {
- font-size: 14px;
- opacity: 0.9;
- margin-bottom: 12px;
-}
-
-.profit-value {
- font-size: 32px;
- font-weight: bold;
- margin-bottom: 12px;
-}
-
-.profit-highlight {
- color: #fff;
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
-}
-
-.profit-footer {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 13px;
- opacity: 0.9;
-}
-
-.growth-up {
- color: #fff;
- font-weight: bold;
-}
-
-.growth-down {
- color: #ffd04b;
- font-weight: bold;
-}
-
-.cost-rate, .gross-profit-rate {
- font-weight: bold;
-}
-
-/* 鍥捐〃瀹瑰櫒 */
-.chart-container {
- margin: 20px 0;
- padding: 20px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-}
-</style>
-
diff --git a/vite.config.js b/vite.config.js
index 540ff94..f91bfe7 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -7,13 +7,13 @@
const env = loadEnv(mode, process.cwd());
const { VITE_APP_ENV } = env;
const baseUrl =
- env.VITE_APP_ENV === "development"
- ? "http://114.132.189.42:9036"
- : env.VITE_BASE_API;
+ VITE_APP_ENV === "development"
+ ? "http://127.0.0.1:8009" // 寮�鍙戠幆澧冨悗绔帴鍙�
+ : "http://10.136.12.71:8009"; // 鐢熶骇鐜鍚庣鎺ュ彛
const javaUrl =
- env.VITE_APP_ENV === "development"
- ? "http://114.132.189.42:9037"
- : env.VITE_JAVA_API;
+ VITE_APP_ENV === "development"
+ ? "http://127.0.0.1:8009" // 寮�鍙戠幆澧冨悗绔帴鍙�
+ : "http://10.136.12.71:8009"; // 鐢熶骇鐜鍚庣鎺ュ彛
return {
define:{
__BASE_API__: JSON.stringify(javaUrl)
--
Gitblit v1.9.3