From 614b5e303ea058589c39a03e163aa0221b319dde Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 17 三月 2026 11:48:45 +0800
Subject: [PATCH] 军泰伟业app 1.添加营销管理模块和采购管理模块并联调
---
src/pages/cooperativeOffice/customerManage/detail.vue | 493
src/pages/managementMeetings/meetApplication/index.vue | 499
src/pages/sales/salesAccount/goOut.vue | 657 +
src/static/images/icon/huiyikanban@2x.png | 0
src/static/images/icon/huiyizongjie@2x.png | 0
src/api/managementMeetings/meetingSettings.js | 24
src/pages/procurementManagement/paymentEntry/add.vue | 455
src/static/images/tabbar/home.png | 0
src/api/cooperativeOffice/clientVisit.js | 24
src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue | 559
src/static/images/tabbar/my.png | 0
src/pages/managementMeetings/meetingSettings/index.vue | 244
src/pages/cooperativeOffice/collaborativeApproval/index5.vue | 17
src/static/images/icon/huiyishenpi@2x.png | 0
src/pages/managementMeetings/knowledgeBase/index.vue | 310
src/static/images/index/caigoushuju.png | 0
src/pages/cooperativeOffice/collaborativeApproval/approve.vue | 24
src/pages/managementMeetings/rulesRegulationsManagement/index.vue | 451
src/pages/equipmentManagement/repair/maintain.vue | 495
src/pages/cooperativeOffice/collaborativeApproval/index.vue | 641
src/pages/managementMeetings/meetingSettings/view.vue | 178
src/pages/sales/invoicingRegistration/index.vue | 454
src/pages/sales/salesAccount/index.vue | 476
src/pages/sales/invoiceLedger/index.vue | 1155 +
src/pages/sales/receiptPayment/add.vue | 477
src/static/images/icon/zhishiku@2x.png | 0
src/pages/cooperativeOffice/collaborativeApproval/index7.vue | 17
src/static/images/icon/huiyishenqing@2x.png | 0
src/pages/equipmentManagement/repair/index.vue | 347
src/static/images/icon/qingjiaguanli@2x.png | 0
src/api/personnelManagement/onboarding.js | 8
src/pages/managementMeetings/meetingList/index.vue | 537
src/pages/cooperativeOffice/collaborativeApproval/index1.vue | 17
src/static/images/icon/huiyifabu@2x.png | 0
src/static/images/icon/tongzhigonggao@2x.png | 0
src/pages/indexItem.vue | 1124 +
src/pages/managementMeetings/meetSummary/index.vue | 353
src/api/collaborativeApproval/approvalProcess.js | 1
src/static/images/index/num2.png | 0
src/static/images/tabbar/newBlue.png | 0
src/pages/equipmentManagement/repair/add.vue | 840
src/pages/managementMeetings/meetExamine/approve.vue | 470
src/pages/sales/receiptPaymentHistory/index.vue | 449
src/static/images/icon/caigouguanli.png | 0
src/pages/index.vue | 141
src/static/images/icon/huiyishezhi@2x.png | 0
src/pages/sales/invoiceLedger/detail.vue | 21
src/pages/cooperativeOffice/collaborativeApproval/index3.vue | 17
src/pages/equipmentManagement/upkeep/fileList.vue | 562
src/pages/managementMeetings/meetSummary/approve.vue | 560
src/pages/sales/salesAccount/out.vue | 407
src/static/images/icon/baojiaguanli.png | 0
src/api/collaborativeApproval/noticeManagement.js | 35
src/pages/sales/invoicingRegistration/view.vue | 5
src/static/images/icon/rukuguanli@2x.png | 0
src/pages/equipmentManagement/inspection/detail.vue | 1364 +-
src/pages/cooperativeOffice/clientVisit/detail.vue | 595
src/static/images/icon/zidingyichuku.png | 0
src/pages/cooperativeOffice/clientVisit/index.vue | 310
src/pages/procurementManagement/invoiceEntry/add.vue | 4
src/pages/equipmentManagement/runManagement/index.vue | 548
src/pages/procurementManagement/paymentEntry/index.vue | 369
src/pages/cooperativeOffice/collaborativeApproval/index6.vue | 17
src/static/images/icon/guizhangzhidu@2x.png | 0
src/pages/procurementManagement/invoiceEntry/index.vue | 439
src/static/images/icon/chukuguanli@2x.png | 0
src/api/salesManagement/deliveryLedger.js | 86
src/pages/sales/receiptPaymentLedger/index.vue | 285
src/pages/procurementManagement/procurementLedger/detail.vue | 2348 ++-
src/pages/managementMeetings/sealManagement/index.vue | 348
src/api/managementMeetings/knowledgeBase.js | 36
src/pages/procurementManagement/procurementInvoiceLedger/index.vue | 769
src/pages/sales/receiptPaymentLedger/detail.vue | 542
src/pages/managementMeetings/meetPublish/approve.vue | 497
src/pages/procurementManagement/receiptPaymentHistory/index.vue | 395
src/pages/sales/invoicingRegistration/add.vue | 11
src/pages/cooperativeOffice/collaborativeApproval/index8.vue | 17
src/pages/managementMeetings/meetingSettings/detail.vue | 344
src/pages/cooperativeOffice/collaborativeApproval/detail.vue | 1493 +-
src/api/managementMeetings/rulesRegulationsManagement.js | 82
src/pages/managementMeetings/knowledgeBase/detail.vue | 500
src/static/images/index/kucunshuju.png | 0
src/pages/equipmentManagement/inspection/index.vue | 881
src/static/images/icon/gongchuguanli@2x.png | 0
src/pages/cooperativeOffice/collaborativeApproval/contactSelect.vue | 10
src/static/images/icon/yongyinguanli@2x.png | 0
src/static/images/tabbar/workBlue.png | 0
src/pages/equipmentManagement/upkeep/index.vue | 491
src/pages/procurementManagement/procurementLedger/index.vue | 435
src/api/personnelManagement/attendance.js | 26
src/static/images/icon/huiyiliebiao@2x.png | 0
src/pages.json | 227
src/static/images/index/num1.png | 0
src/static/images/tabbar/myBlue.png | 0
src/pages/cooperativeOffice/collaborativeApproval/index2.vue | 17
src/pages/sales/salesAccount/view.vue | 340
src/pages/sales/salesAccount/detail.vue | 1863 +-
src/pages/managementMeetings/meetingBoard/index.vue | 393
src/api/managementMeetings/meetExamine.js | 60
src/static/images/icon/baoxiaoguanli.png | 0
src/static/images/index/num3.png | 0
src/static/images/icon/chuchaiguanli@2x.png | 0
src/static/images/tabbar/homeBlue.png | 0
src/pages/managementMeetings/sealManagement/detail.vue | 330
src/static/images/tabbar/work.png | 0
src/pages/sales/receiptPayment/index.vue | 370
src/pages/managementMeetings/meetPublish/index.vue | 348
src/pages/sales/deliveryLedger/index.vue | 785 +
src/api/managementMeetings/sealManagement.js | 28
src/pages/procurementManagement/paymentLedger/index.vue | 4
src/api/personnelManagement/monthlyStatistics.js | 65
src/pages/procurementManagement/paymentLedger/detail.vue | 521
src/pages/cooperativeOffice/noticeManagement/index.vue | 809 +
/dev/null | 0
src/static/images/tabbar/new.png | 0
src/pages/managementMeetings/rulesRegulationsManagement/detail.vue | 455
src/pages/cooperativeOffice/collaborativeApproval/index4.vue | 17
src/pages/cooperativeOffice/clientVisit/view.vue | 203
src/pages/managementMeetings/meetExamine/index.vue | 352
src/api/managementMeetings/meeting.js | 26
src/static/images/index/xiaoshoushuju.png | 0
src/pages/procurementManagement/procurementInvoiceLedger/detail.vue | 525
122 files changed, 25,094 insertions(+), 9,430 deletions(-)
diff --git a/src/api/collaborativeApproval/approvalProcess.js b/src/api/collaborativeApproval/approvalProcess.js
index 415bed8..47cf3ec 100644
--- a/src/api/collaborativeApproval/approvalProcess.js
+++ b/src/api/collaborativeApproval/approvalProcess.js
@@ -30,6 +30,7 @@
data: query,
})
}
+
// 淇敼瀹℃壒娴佺▼
export function approveProcessUpdate(query) {
return request({
diff --git a/src/api/collaborativeApproval/noticeManagement.js b/src/api/collaborativeApproval/noticeManagement.js
index fa1caec..a1a2a2c 100644
--- a/src/api/collaborativeApproval/noticeManagement.js
+++ b/src/api/collaborativeApproval/noticeManagement.js
@@ -3,7 +3,7 @@
// 鏌ヨ鍏憡鍒楄〃
export function listNotice(query) {
return request({
- url: '/collaborativeApproval/notice/list',
+ url: '/collaborativeApproval/notice/page',
method: 'get',
params: query
})
@@ -20,7 +20,7 @@
// 鏂板鍏憡
export function addNotice(data) {
return request({
- url: '/collaborativeApproval/notice',
+ url: '/collaborativeApproval/notice/add',
method: 'post',
data: data
})
@@ -29,41 +29,24 @@
// 淇敼鍏憡
export function updateNotice(data) {
return request({
- url: '/collaborativeApproval/notice',
+ url: '/collaborativeApproval/notice/update',
method: 'put',
data: data
})
}
// 鍒犻櫎鍏憡
-export function delNotice(noticeId) {
+export function delNotice(ids) {
return request({
- url: '/collaborativeApproval/notice/' + noticeId,
- method: 'delete'
- })
-}
-
-// 鎵归噺鍒犻櫎鍏憡
-export function delNoticeBatch(noticeIds) {
- return request({
- url: '/collaborativeApproval/notice/batch',
+ url: '/collaborativeApproval/notice/' + ids,
method: 'delete',
- data: noticeIds
})
}
-// 鍙戝竷鍏憡
-export function publishNotice(noticeId) {
+// 鑾峰彇鍏憡鏁伴噺
+export function getCount() {
return request({
- url: '/collaborativeApproval/notice/publish/' + noticeId,
- method: 'put'
- })
-}
-
-// 涓嬬嚎鍏憡
-export function offlineNotice(noticeId) {
- return request({
- url: '/collaborativeApproval/notice/offline/' + noticeId,
- method: 'put'
+ url: '/collaborativeApproval/notice/count',
+ method: 'get',
})
}
diff --git a/src/api/cooperativeOffice/clientVisit.js b/src/api/cooperativeOffice/clientVisit.js
index 64ba2a6..d7a9b47 100644
--- a/src/api/cooperativeOffice/clientVisit.js
+++ b/src/api/cooperativeOffice/clientVisit.js
@@ -9,6 +9,14 @@
data: data
})
}
+// 瀹㈡埛鎷滆绛惧埌
+export function clientVisitUpdate(data) {
+ return request({
+ url: '/customerVisits/update',
+ method: 'post',
+ data: data
+ })
+}
// 鑾峰彇鎷滆璁板綍鍒楄〃
export function getVisitRecords(query) {
@@ -17,4 +25,20 @@
method: 'get',
params: query
})
+}
+
+// 鍒犻櫎瀹㈡埛妗f
+export function delCustomer(ids) {
+ return request({
+ url: '/customerVisits/'+ids,
+ method: 'delete',
+ })
+}
+
+// 鏌ヨ瀹㈡埛妗f璇︾粏
+export function getCustomer(id) {
+ return request({
+ url: '/basic/customer/' + id,
+ method: 'get'
+ })
}
\ No newline at end of file
diff --git a/src/api/managementMeetings/knowledgeBase.js b/src/api/managementMeetings/knowledgeBase.js
new file mode 100644
index 0000000..ad0ce77
--- /dev/null
+++ b/src/api/managementMeetings/knowledgeBase.js
@@ -0,0 +1,36 @@
+// 鐭ヨ瘑搴撶浉鍏� API
+import request from '@/utils/request';
+
+
+export function listKnowledgeBase(params) {
+ return request({
+ url: '/knowledgeBase/getList',
+ method: 'get',
+ params
+ });
+}
+// 鏂板鐭ヨ瘑搴�
+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,
+ });
+}
\ No newline at end of file
diff --git a/src/api/managementMeetings/meetExamine.js b/src/api/managementMeetings/meetExamine.js
new file mode 100644
index 0000000..3a43e20
--- /dev/null
+++ b/src/api/managementMeetings/meetExamine.js
@@ -0,0 +1,60 @@
+import request from '@/utils/request';
+
+export function getExamineList(data) {
+ return request({
+ url: "/meeting/applicationList",
+ method: "post",
+ data: data,
+ });
+}
+
+export function getRoomEnum() {
+ return request({
+ url: "/meeting/roomEnum",
+ method: "get",
+ });
+}
+
+export function saveMeetingApplication(data){
+ return request({
+ url: "/meeting/saveMeetingApplication",
+ 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/managementMeetings/meeting.js b/src/api/managementMeetings/meeting.js
new file mode 100644
index 0000000..1f730a2
--- /dev/null
+++ b/src/api/managementMeetings/meeting.js
@@ -0,0 +1,26 @@
+import request from '@/utils/request';
+
+// 鑾峰彇浼氳浣跨敤鍒楄〃
+export function getMeetingUseList(data){
+ return request({
+ url: "/meeting/meetingUseList",
+ method: "post",
+ data: data,
+ });
+}
+
+// 淇濆瓨浼氳鐢宠
+export function saveMeetingApplication(data){
+ return request({
+ url: "/meeting/saveMeetingApplication",
+ method: "post",
+ data: data,
+ });
+}
+
+export function getRoomEnum() {
+ return request({
+ url: "/meeting/roomEnum",
+ method: "get",
+ });
+}
\ No newline at end of file
diff --git a/src/api/managementMeetings/meetingSettings.js b/src/api/managementMeetings/meetingSettings.js
new file mode 100644
index 0000000..0205270
--- /dev/null
+++ b/src/api/managementMeetings/meetingSettings.js
@@ -0,0 +1,24 @@
+// 浼氳绠$悊
+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",
+ });
+}
\ No newline at end of file
diff --git a/src/api/managementMeetings/rulesRegulationsManagement.js b/src/api/managementMeetings/rulesRegulationsManagement.js
new file mode 100644
index 0000000..b5cd48c
--- /dev/null
+++ b/src/api/managementMeetings/rulesRegulationsManagement.js
@@ -0,0 +1,82 @@
+import request from '@/utils/request';
+
+// 鏌ヨ瑙勭珷鍒跺害鍒楄〃
+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 updateRuleManagement(data) {
+ return request({
+ url: "/rulesRegulationsManagement/update",
+ method: "post",
+ data: data,
+ });
+}
+// 鏂板瑙勭珷鍒跺害
+export function addRuleManagement(data) {
+ return request({
+ url: "/rulesRegulationsManagement/add",
+ method: "post",
+ data: data,
+ });
+}
+
+// 闄勪欢鍒楄〃
+export function listRuleFiles(query) {
+ return request({
+ url: "/rulesRegulationsManagementFile/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏂板闄勪欢
+export function addRuleFile(data) {
+ return request({
+ url: "/rulesRegulationsManagementFile/add",
+ method: "post",
+ data,
+ });
+}
+
+// 鍒犻櫎闄勪欢锛堟敮鎸佷紶閫� id 鏁扮粍锛�
+export function delRuleFile(ids) {
+ return request({
+ url: "/rulesRegulationsManagementFile/del",
+ method: "delete",
+ data: ids,
+ });
+}
+// 涓婁紶闄勪欢
+export function upload(query) {
+ return request({
+ url: "/file/upload",
+ method: "post",
+ data: query,
+ responseType: "blob",
+ });
+}
\ No newline at end of file
diff --git a/src/api/managementMeetings/sealManagement.js b/src/api/managementMeetings/sealManagement.js
new file mode 100644
index 0000000..f4d4aa2
--- /dev/null
+++ b/src/api/managementMeetings/sealManagement.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鏌ヨ鍗扮珷鐢宠鍒楄〃
+export function listSealApplication(page,query) {
+ return request({
+ url: "/sealApplicationManagement/getList",
+ method: "get",
+ params: {
+ ...page,
+ ...query},
+ });
+}
+
+// 淇敼鍗扮珷鐢宠
+export function updateSealApplication(data) {
+ return request({
+ url: "/sealApplicationManagement/update",
+ method: "post",
+ data: data,
+ });
+}
+export function addSealApplication(data) {
+ return request({
+ url: "/sealApplicationManagement/add",
+ method: "post",
+ data: data,
+ });
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/attendance.js b/src/api/personnelManagement/attendance.js
new file mode 100644
index 0000000..f7a1798
--- /dev/null
+++ b/src/api/personnelManagement/attendance.js
@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+
+
+export function createPersonalAttendanceRecord(params) {
+ return request({
+ url: "/personalAttendanceRecords",
+ method: "post",
+ data: params,
+ });
+}
+
+export function findPersonalAttendanceRecords(query) {
+ return request({
+ url: "/personalAttendanceRecords/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function findTodayPersonalAttendanceRecord(query) {
+ return request({
+ url: "/personalAttendanceRecords/today",
+ method: "get",
+ params: query,
+ });
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/monthlyStatistics.js b/src/api/personnelManagement/monthlyStatistics.js
new file mode 100644
index 0000000..a070d0f
--- /dev/null
+++ b/src/api/personnelManagement/monthlyStatistics.js
@@ -0,0 +1,65 @@
+import request from "@/utils/request";
+
+// 浜哄憳钖祫鍙拌处鍒楄〃
+export function monthlyStatisticsListPage(query) {
+ return request({
+ url: "/compensationPerformance/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+// 浜哄憳钖祫鍙拌处璇︽儏
+export function monthlyStatisticsGet(id) {
+ return request({
+ url: "/monthlyStatistics/get",
+ method: "get",
+ params: { id },
+ });
+}
+
+// 鏂板浜哄憳钖祫鍙拌处
+export function monthlyStatisticsAdd(data) {
+ return request({
+ url: "/compensationPerformance/add",
+ method: "post",
+ data,
+ });
+}
+
+// 缂栬緫浜哄憳钖祫鍙拌处
+export function monthlyStatisticsUpdate(data) {
+ return request({
+ url: "/compensationPerformance/update",
+ method: "post",
+ data,
+ });
+}
+
+// 鍒犻櫎浜哄憳钖祫鍙拌处
+export function monthlyStatisticsDelete(ids) {
+ return request({
+ url: "/compensationPerformance/delete",
+ method: "delete",
+ data: ids,
+ });
+}
+
+// 瀵煎嚭浜哄憳钖祫鍙拌处
+export function monthlyStatisticsExport(query) {
+ return request({
+ url: "/compensationPerformance/export",
+ method: "get",
+ params: query,
+ responseType: "blob",
+ });
+}
+
+// 浜哄憳鍒楄〃
+export function staffOnJobList(query) {
+ return request({
+ url: "/staff/staffOnJob/list",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/api/personnelManagement/onboarding.js b/src/api/personnelManagement/onboarding.js
index 39dbf22..61de00a 100644
--- a/src/api/personnelManagement/onboarding.js
+++ b/src/api/personnelManagement/onboarding.js
@@ -47,3 +47,11 @@
method: "get",
});
}
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+ return request({
+ url: '/staff/staffOnJob/listPage',
+ method: 'get',
+ params: query,
+ })
+}
\ No newline at end of file
diff --git a/src/api/salesManagement/deliveryLedger.js b/src/api/salesManagement/deliveryLedger.js
new file mode 100644
index 0000000..755395c
--- /dev/null
+++ b/src/api/salesManagement/deliveryLedger.js
@@ -0,0 +1,86 @@
+// 鍙戣揣鍙拌处椤甸潰鎺ュ彛
+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 deductStock(query) {
+ return request({
+ url: "/shippingInfo/deductStock",
+ 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,
+ });
+}
+
+// 鍙戣揣鏄庣粏鎺ュ彛
+
+// 鍒嗛〉鏌ヨ鍙戣揣鏄庣粏
+export function shippingInfoDetailListPage(query) {
+ return request({
+ url: "/shippingInfoDetail/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏂板鍙戣揣鏄庣粏
+export function addShippingInfoDetail(data) {
+ return request({
+ url: "/shippingInfoDetail/add",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼鍙戣揣鏄庣粏
+export function updateShippingInfoDetail(data) {
+ return request({
+ url: "/shippingInfoDetail/update",
+ method: "post",
+ data,
+ });
+}
+
+// 鍒犻櫎鍙戣揣鏄庣粏
+export function delShippingInfoDetail(ids) {
+ return request({
+ url: "/shippingInfoDetail/delete",
+ method: "delete",
+ data: ids,
+ });
+}
+
diff --git a/src/pages.json b/src/pages.json
index 19aafe5..21a1b19 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -58,6 +58,27 @@
}
},
{
+ "path": "pages/sales/deliveryLedger/index",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣鍙拌处",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/sales/salesAccount/out",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣鐘舵��",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/sales/salesAccount/goOut",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣",
+ "navigationStyle": "custom"
+ }
+ },
+ {
"path": "pages/sales/salesAccount/detail",
"style": {
"navigationBarTitleText": "淇敼鍙拌处",
@@ -247,9 +268,184 @@
}
},
{
- "path": "pages/cooperativeOffice/collaborativeApproval/index",
+ "path": "pages/cooperativeOffice/collaborativeApproval/index1",
"style": {
- "navigationBarTitleText": "瀹℃壒绠$悊",
+ "navigationBarTitleText": "鍏嚭绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index2",
+ "style": {
+ "navigationBarTitleText": "璇峰亣绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index3",
+ "style": {
+ "navigationBarTitleText": "鍑哄樊绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index4",
+ "style": {
+ "navigationBarTitleText": "鎶ラ攢绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/indexItem",
+ "style": {
+ "navigationBarTitleText": "鑰冨嫟绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index5",
+ "style": {
+ "navigationBarTitleText": "閲囪喘绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index6",
+ "style": {
+ "navigationBarTitleText": "鎶ヤ环绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/cooperativeOffice/collaborativeApproval/index7",
+ "style": {
+ "navigationBarTitleText": "鍙戣揣瀹℃壒",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetingSettings/index",
+ "style": {
+ "navigationBarTitleText": "浼氳璁剧疆",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetingSettings/detail",
+ "style": {
+ "navigationBarTitleText": "浼氳瀹よ鎯�",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetingList/index",
+ "style": {
+ "navigationBarTitleText": "浼氳鍒楄〃",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetApplication/index",
+ "style": {
+ "navigationBarTitleText": "浼氳鐢宠",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetExamine/index",
+ "style": {
+ "navigationBarTitleText": "浼氳瀹℃壒",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetExamine/approve",
+ "style": {
+ "navigationBarTitleText": "瀹℃壒",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetPublish/index",
+ "style": {
+ "navigationBarTitleText": "浼氳鍙戝竷",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetPublish/approve",
+ "style": {
+ "navigationBarTitleText": "鍙戝竷",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetSummary/index",
+ "style": {
+ "navigationBarTitleText": "浼氳鎬荤粨",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetingBoard/index",
+ "style": {
+ "navigationBarTitleText": "浼氳鐪嬫澘",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/meetSummary/approve",
+ "style": {
+ "navigationBarTitleText": "鎬荤粨",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/knowledgeBase/index",
+ "style": {
+ "navigationBarTitleText": "鐭ヨ瘑搴�",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/sealManagement/index",
+ "style": {
+ "navigationBarTitleText": "鐢ㄥ嵃绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/sealManagement/detail",
+ "style": {
+ "navigationBarTitleText": "鐢ㄥ嵃璇︽儏",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/rulesRegulationsManagement/index",
+ "style": {
+ "navigationBarTitleText": "瑙勭珷鍒跺害绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/rulesRegulationsManagement/detail",
+ "style": {
+ "navigationBarTitleText": "瑙勭珷鍒跺害璇︽儏",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/rulesRegulationsManagement/fileList",
+ "style": {
+ "navigationBarTitleText": "瑙勭珷鍒跺害鏂囦欢绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/managementMeetings/knowledgeBase/detail",
+ "style": {
+ "navigationBarTitleText": "鐭ヨ瘑搴撹鎯�",
"navigationStyle": "custom"
}
},
@@ -296,6 +492,13 @@
}
},
{
+ "path": "pages/cooperativeOffice/noticeManagement/index",
+ "style": {
+ "navigationBarTitleText": "閫氱煡鍏憡",
+ "navigationStyle": "custom"
+ }
+ },
+ {
"path": "pages/equipmentManagement/ledger/index",
"style": {
"navigationBarTitleText": "璁惧鍙拌处",
@@ -306,6 +509,13 @@
"path": "pages/equipmentManagement/ledger/detail",
"style": {
"navigationBarTitleText": "璁惧鍙拌处璇︽儏",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/equipmentManagement/runManagement/index",
+ "style": {
+ "navigationBarTitleText": "杩愯绠$悊",
"navigationStyle": "custom"
}
},
@@ -348,6 +558,13 @@
"path": "pages/equipmentManagement/upkeep/maintain",
"style": {
"navigationBarTitleText": "缁翠慨淇濆吇",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/equipmentManagement/upkeep/fileList",
+ "style": {
+ "navigationBarTitleText": "淇濆吇鏂囦欢绠$悊",
"navigationStyle": "custom"
}
},
@@ -628,13 +845,13 @@
{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
- "selectedIconPath": "static/images/tabbar/home_.png",
+ "selectedIconPath": "static/images/tabbar/homeBlue.png",
"text": "棣栭〉"
},
{
"pagePath": "pages/mine",
- "iconPath": "static/images/tabbar/mine.png",
- "selectedIconPath": "static/images/tabbar/mine_.png",
+ "iconPath": "static/images/tabbar/my.png",
+ "selectedIconPath": "static/images/tabbar/myBlue.png",
"text": "鎴戠殑"
}
]
diff --git a/src/pages/cooperativeOffice/clientVisit/detail.vue b/src/pages/cooperativeOffice/clientVisit/detail.vue
index 9c0460e..0bab2d7 100644
--- a/src/pages/cooperativeOffice/clientVisit/detail.vue
+++ b/src/pages/cooperativeOffice/clientVisit/detail.vue
@@ -1,324 +1,383 @@
<template>
<view class="client-visit-detail">
- <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
-
- <u-form @submit="handleSignIn" ref="formRef" label-width="90">
+ <PageHeader title="瀹㈡埛鎷滆璇︽儏"
+ @back="goBack" />
+ <u-form @submit="handleSignIn"
+ ref="formRef"
+ label-width="90">
<!-- 瀹㈡埛淇℃伅 -->
<u-cell-group title="瀹㈡埛淇℃伅">
- <u-form-item label="瀹㈡埛鍚嶇О" prop="customerName" required border-bottom>
- <u-input
- v-model="form.customerName"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- />
+ <u-form-item label="瀹㈡埛鍚嶇О"
+ prop="customerName"
+ required
+ border-bottom>
+ <u-input v-model="form.customerName"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
</u-form-item>
- <u-form-item label="鑱旂郴浜�" prop="contact" border-bottom>
- <u-input
- v-model="form.contact"
- placeholder="璇疯緭鍏ヨ仈绯讳汉"
- />
+ <u-form-item label="鑱旂郴浜�"
+ prop="contact"
+ border-bottom>
+ <u-input v-model="form.contact"
+ placeholder="璇疯緭鍏ヨ仈绯讳汉" />
</u-form-item>
- <u-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone" border-bottom>
- <u-input
- v-model="form.contactPhone"
- placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
- />
+ <u-form-item label="鑱旂郴鐢佃瘽"
+ prop="contactPhone"
+ border-bottom>
+ <u-input v-model="form.contactPhone"
+ placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
</u-form-item>
</u-cell-group>
-
<!-- 鎷滆淇℃伅 -->
<u-cell-group title="鎷滆淇℃伅">
- <u-form-item label="鎷滆鐩殑" prop="purposeVisit" required border-bottom>
- <u-input
- v-model="form.purposeVisit"
- placeholder="璇疯緭鍏ユ嫓璁跨洰鐨�"
- />
+ <u-form-item label="鎷滆鐩殑"
+ prop="purposeVisit"
+ required
+ border-bottom>
+ <u-input v-model="form.purposeVisit"
+ placeholder="璇疯緭鍏ユ嫓璁跨洰鐨�" />
</u-form-item>
- <u-form-item label="鎷滆鏃堕棿" prop="purposeDate" required border-bottom>
- <u-input
- v-model="form.purposeDate"
- placeholder="璇烽�夋嫨鎷滆鏃堕棿"
- @click="showTimePicker"
- />
+ <u-form-item label="鎷滆鏃堕棿"
+ prop="purposeDate"
+ required
+ border-bottom>
+ <u-input v-model="form.purposeDate"
+ placeholder="璇烽�夋嫨鎷滆鏃堕棿"
+ @click="showTimePicker" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showTimePicker"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showTimePicker"></up-icon>
+ </template>
</u-form-item>
- <u-form-item label="鎷滆鍦扮偣" prop="visitAddress" required border-bottom>
- <u-input
- v-model="form.visitAddress"
- placeholder="璇疯緭鍏ユ嫓璁垮湴鐐�"
- >
+ <u-form-item label="鎷滆鍦扮偣"
+ prop="visitAddress"
+ required
+ border-bottom>
+ <u-input v-model="form.visitAddress"
+ placeholder="璇疯緭鍏ユ嫓璁垮湴鐐�">
<template #suffix>
- <u-icon name="map" @click="getCurrentLocation" class="location-icon" />
+ <u-icon name="map"
+ @click="getCurrentLocation"
+ class="location-icon" />
</template>
</u-input>
</u-form-item>
</u-cell-group>
-
<!-- 澶囨敞淇℃伅 -->
<u-cell-group title="澶囨敞淇℃伅">
- <u-form-item label="澶囨敞" prop="remark" border-bottom>
- <u-textarea
- v-model="form.remark"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
- :maxlength="200"
- count
- :autoHeight="true"
- />
+ <u-form-item label="澶囨敞"
+ prop="remark"
+ border-bottom>
+ <u-textarea v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+ :maxlength="200"
+ count
+ :autoHeight="true" />
</u-form-item>
</u-cell-group>
-
<!-- 鎻愪氦鎸夐挳 -->
<view class="footer-btns">
- <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
- <u-button class="sign-btn" type="primary" @click="handleSignIn" :loading="loading">绛惧埌</u-button>
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="sign-btn"
+ type="primary"
+ @click="handleSignIn"
+ :loading="loading">绛惧埌</u-button>
</view>
</u-form>
-
<!-- 鏃堕棿閫夋嫨鍣� -->
- <up-datetime-picker
- :show="showTime"
- v-model="currentTime"
- @confirm="onTimeConfirm"
- @cancel="showTime = false"
- mode="datetime"
- />
+ <up-datetime-picker :show="showTime"
+ v-model="currentTime"
+ @confirm="onTimeConfirm"
+ @cancel="showTime = false"
+ mode="datetime" />
</view>
</template>
<script setup>
-// 鏇挎崲 toast 鏂规硶
-defineOptions({name: 'client-visit-detail'})
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-import { ref, onMounted } from 'vue'
-import PageHeader from '@/components/PageHeader.vue'
-import { clientVisitSignIn } from '@/api/cooperativeOffice/clientVisit'
-import useUserStore from "@/store/modules/user"
-import dayjs from "dayjs"
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ clientVisitSignIn,
+ clientVisitUpdate,
+ } from "@/api/cooperativeOffice/clientVisit";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
+ import { onLoad } from "@dcloudio/uni-app";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 琛ㄥ崟鏁版嵁
-const form = ref({
- customerName: '',
- contact: '',
- contactPhone: '',
- visitingPeople: '',
- purposeVisit: '',
- purposeDate: '',
- visitAddress: '',
- latitude: '',
- longitude: '',
- locationAddress: '',
- remark: ''
-})
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ customerName: "",
+ contact: "",
+ contactPhone: "",
+ visitingPeople: "",
+ purposeVisit: "",
+ purposeDate: "",
+ visitAddress: "",
+ latitude: "",
+ longitude: "",
+ locationAddress: "",
+ remark: "",
+ });
-// 椤甸潰鐘舵��
-const loading = ref(false)
-const formRef = ref(null)
+ // 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
-// 鏃堕棿鐩稿叧
-const currentTime = ref(Date.now())
-const showTime = ref(false)
+ // 鏃堕棿鐩稿叧
+ const currentTime = ref(Date.now());
+ const showTime = ref(false);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
- uni.removeStorageSync('clientVisit')
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+ uni.removeStorageSync("clientVisit");
+ uni.navigateBack();
+ };
-// 鏄剧ず鏃堕棿閫夋嫨鍣�
-const showTimePicker = () => {
- showTime.value = true
-}
+ // 鏄剧ず鏃堕棿閫夋嫨鍣�
+ const showTimePicker = () => {
+ showTime.value = true;
+ };
-// 纭鏃堕棿閫夋嫨
-const onTimeConfirm = (e) => {
- console.log(e)
- form.value.purposeDate = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss')
- currentTime.value = e.value
- showTime.value = false;
-}
+ // 纭鏃堕棿閫夋嫨
+ const onTimeConfirm = e => {
+ console.log(e);
+ form.value.purposeDate = dayjs(e.value).format("YYYY-MM-DD HH:mm:ss");
+ currentTime.value = e.value;
+ showTime.value = false;
+ };
-// 鑾峰彇褰撳墠浣嶇疆
-const getCurrentLocation = () => {
- uni.showLoading({ title: '鑾峰彇浣嶇疆涓�...' })
-
- uni.getLocation({
- type: 'gcj02',
- success: (res) => {
- form.value.latitude = res.latitude
- form.value.longitude = res.longitude
-
- // 浣跨敤閫嗗湴鐞嗙紪鐮佽幏鍙栧湴鍧�淇℃伅
- uni.request({
- url: `https://restapi.amap.com/v3/geocode/regeo?key=c120a5dc69a9f61839f7763e6057005f&location=${res.longitude},${res.latitude}&radius=1000&extensions=all`,
- success: (geoRes) => {
- uni.hideLoading()
- if (geoRes.data.status === '1' && geoRes.data.regeocode) {
- const regeocode = geoRes.data.regeocode
- const address = regeocode.formatted_address
-
- // 浼樺厛鏄剧ず璇︾粏鍦板潃
- if (address) {
- form.value.visitAddress = address
- showToast('浣嶇疆鑾峰彇鎴愬姛')
+ // 鑾峰彇褰撳墠浣嶇疆
+ const getCurrentLocation = () => {
+ uni.showLoading({ title: "鑾峰彇浣嶇疆涓�..." });
+
+ uni.getLocation({
+ type: "gcj02",
+ success: res => {
+ form.value.latitude = res.latitude;
+ form.value.longitude = res.longitude;
+
+ // 浣跨敤閫嗗湴鐞嗙紪鐮佽幏鍙栧湴鍧�淇℃伅
+ uni.request({
+ url: `https://restapi.amap.com/v3/geocode/regeo?key=c120a5dc69a9f61839f7763e6057005f&location=${res.longitude},${res.latitude}&radius=1000&extensions=all`,
+ success: geoRes => {
+ uni.hideLoading();
+ if (geoRes.data.status === "1" && geoRes.data.regeocode) {
+ const regeocode = geoRes.data.regeocode;
+ const address = regeocode.formatted_address;
+
+ // 浼樺厛鏄剧ず璇︾粏鍦板潃
+ if (address) {
+ form.value.visitAddress = address;
+ showToast("浣嶇疆鑾峰彇鎴愬姛");
+ } else {
+ // 濡傛灉娌℃湁璇︾粏鍦板潃锛屽皾璇曠粍鍚堝湴鍧�淇℃伅
+ const addressComponent = regeocode.addressComponent;
+ const combinedAddress = `${addressComponent.province}${addressComponent.city}${addressComponent.district}${addressComponent.township}`;
+ form.value.visitAddress = combinedAddress;
+ showToast("浣嶇疆鑾峰彇鎴愬姛");
+ }
} else {
- // 濡傛灉娌℃湁璇︾粏鍦板潃锛屽皾璇曠粍鍚堝湴鍧�淇℃伅
- const addressComponent = regeocode.addressComponent
- const combinedAddress = `${addressComponent.province}${addressComponent.city}${addressComponent.district}${addressComponent.township}`
- form.value.visitAddress = combinedAddress
- showToast('浣嶇疆鑾峰彇鎴愬姛')
+ // API璋冪敤鎴愬姛浣嗘病鏈夎繑鍥炲湴鍧�淇℃伅
+ const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(
+ 4
+ )}, ${res.longitude.toFixed(4)}`;
+ form.value.visitAddress = fallbackAddress;
+ showToast("鑾峰彇鍒颁綅缃紝浣嗗湴鍧�瑙f瀽澶辫触");
}
- } else {
- // API璋冪敤鎴愬姛浣嗘病鏈夎繑鍥炲湴鍧�淇℃伅
- const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(4)}, ${res.longitude.toFixed(4)}`
- form.value.visitAddress = fallbackAddress
- showToast('鑾峰彇鍒颁綅缃紝浣嗗湴鍧�瑙f瀽澶辫触')
- }
- },
- fail: (err) => {
- uni.hideLoading()
- console.error('閫嗗湴鐞嗙紪鐮佸け璐�:', err)
-
- // 閫嗗湴鐞嗙紪鐮佸け璐ユ椂锛屾樉绀虹畝鍖栫殑浣嶇疆淇℃伅
- const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(4)}, ${res.longitude.toFixed(4)}`
- form.value.visitAddress = fallbackAddress
- showToast('浣嶇疆鑾峰彇鎴愬姛锛屼絾鍦板潃瑙f瀽澶辫触')
+ },
+ fail: err => {
+ uni.hideLoading();
+ console.error("閫嗗湴鐞嗙紪鐮佸け璐�:", err);
+
+ // 閫嗗湴鐞嗙紪鐮佸け璐ユ椂锛屾樉绀虹畝鍖栫殑浣嶇疆淇℃伅
+ const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(
+ 4
+ )}, ${res.longitude.toFixed(4)}`;
+ form.value.visitAddress = fallbackAddress;
+ showToast("浣嶇疆鑾峰彇鎴愬姛锛屼絾鍦板潃瑙f瀽澶辫触");
+ },
+ });
+ },
+ fail: err => {
+ uni.hideLoading();
+ console.error("鑾峰彇浣嶇疆澶辫触:", err);
+
+ // 鏄剧ず閿欒鎻愮ず骞跺紩瀵肩敤鎴锋鏌ユ潈闄�
+ showToast("鑾峰彇浣嶇疆澶辫触锛岃妫�鏌ュ畾浣嶆潈闄�");
+
+ // 寮曞鐢ㄦ埛妫�鏌ユ潈闄愯缃�
+ uni.showModal({
+ title: "浣嶇疆鏉冮檺鎻愮ず",
+ content:
+ "鑾峰彇浣嶇疆澶辫触锛屽彲鑳芥槸鍥犱负浣嶇疆鏉冮檺鏈紑鍚紝璇峰湪璁惧璁剧疆涓鏌ュ苟寮�鍚綅缃潈闄愩��",
+ confirmText: "鐭ラ亾浜�",
+ cancelText: "鍙栨秷",
+ success: res => {
+ if (res.confirm) {
+ // 鍙互灏濊瘯鎵撳紑璁剧疆椤甸潰锛堝鏋滄敮鎸侊級
+ if (uni.openSetting) {
+ uni.openSetting({
+ success: settingRes => {
+ console.log("璁剧疆缁撴灉:", settingRes);
+ },
+ });
+ }
+ }
+ },
+ });
+
+ // 澶辫触鏃舵樉绀洪敊璇俊鎭�
+ form.value.visitAddress = "浣嶇疆鑾峰彇澶辫触";
+ },
+ });
+ };
+
+ // 鎻愪氦绛惧埌
+ const handleSignIn = async () => {
+ if (!form.value.customerName) {
+ showToast("璇疯緭鍏ュ鎴峰悕绉�");
+ return;
+ }
+
+ if (!form.value.purposeVisit) {
+ showToast("璇疯緭鍏ユ嫓璁跨洰鐨�");
+ return;
+ }
+
+ if (!form.value.purposeDate) {
+ showToast("璇烽�夋嫨鎷滆鏃堕棿");
+ return;
+ }
+ if (!form.value.visitAddress) {
+ showToast("璇疯幏鍙栧綋鍓嶄綅缃�");
+ return;
+ }
+
+ try {
+ loading.value = true;
+
+ // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
+ const source =
+ form.value && typeof form.value === "object" ? form.value : {};
+ const submitData = {};
+ Object.keys(source).forEach(k => {
+ submitData[k] = source[k];
+ });
+ console.log("submitData", submitData);
+ if (isEdit.value) {
+ const { code } = await clientVisitUpdate(submitData);
+ if (code === 200) {
+ showToast("淇敼鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ } else {
+ loading.value = false;
+ showToast("绛惧埌澶辫触锛岃閲嶈瘯");
}
- })
- },
- fail: (err) => {
- uni.hideLoading()
- showToast('鑾峰彇浣嶇疆澶辫触锛岃妫�鏌ュ畾浣嶆潈闄�')
- console.error('鑾峰彇浣嶇疆澶辫触:', err)
-
- // 澶辫触鏃舵樉绀洪敊璇俊鎭�
- form.value.visitAddress = '浣嶇疆鑾峰彇澶辫触'
+ } else {
+ const { code } = await clientVisitSignIn(submitData);
+ if (code === 200) {
+ showToast("绛惧埌鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ } else {
+ loading.value = false;
+ showToast("绛惧埌澶辫触锛岃閲嶈瘯");
+ }
+ }
+ } catch (e) {
+ loading.value = false;
+ console.error("绛惧埌澶辫触:", e);
}
- })
-}
-
-// 鎻愪氦绛惧埌
-const handleSignIn = async () => {
- if (!form.value.customerName) {
- showToast('璇疯緭鍏ュ鎴峰悕绉�')
- return
- }
-
- if (!form.value.purposeVisit) {
- showToast('璇疯緭鍏ユ嫓璁跨洰鐨�')
- return
- }
-
- if (!form.value.purposeDate) {
- showToast('璇烽�夋嫨鎷滆鏃堕棿')
- return
- }
- if (!form.value.visitAddress) {
- showToast('璇疯幏鍙栧綋鍓嶄綅缃�')
- return
- }
-
- try {
- loading.value = true
-
- // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
- const source = (form.value && typeof form.value === 'object') ? form.value : {}
- const submitData = {}
- Object.keys(source).forEach((k) => {
- submitData[k] = source[k]
- })
- console.log('submitData', submitData)
-
- const { code } = await clientVisitSignIn(submitData)
-
- if (code === 200) {
- showToast('绛惧埌鎴愬姛')
- setTimeout(() => {
- goBack()
- }, 500)
+ };
+ const isEdit = ref(false);
+ onLoad(() => {
+ // 缂栬緫鎷滆鏃讹紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰�
+ const visit = uni.getStorageSync("clientVisit");
+ if (visit) {
+ form.value = visit;
+ isEdit.value = true;
+ console.log("form.value", form.value);
} else {
- loading.value = false
- showToast('绛惧埌澶辫触锛岃閲嶈瘯')
+ isEdit.value = false;
}
- } catch (e) {
- loading.value = false
- console.error('绛惧埌澶辫触:', e)
- }
-}
+ });
-// 鍒濆鍖栭〉闈㈡暟鎹�
-const initPageData = () => {
- // 璁剧疆榛樿鎷滆鏃堕棿涓哄綋鍓嶆椂闂�
- form.value.purposeDate = dayjs().format('YYYY-MM-DD HH:mm:ss')
- currentTime.value = Date.now()
-
- // 璁剧疆鎷滆浜轰负褰撳墠鐧诲綍鐢ㄦ埛鐨勬樀绉�
- form.value.visitingPeople = userStore.nickName || ''
-}
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const initPageData = () => {
+ // 璁剧疆榛樿鎷滆鏃堕棿涓哄綋鍓嶆椂闂�
+ form.value.purposeDate = dayjs().format("YYYY-MM-DD HH:mm:ss");
+ currentTime.value = Date.now();
-onMounted(() => {
- initPageData()
-})
+ // 璁剧疆鎷滆浜轰负褰撳墠鐧诲綍鐢ㄦ埛鐨勬樀绉�
+ form.value.visitingPeople = userStore.nickName || "";
+ };
+
+ onMounted(() => {
+ initPageData();
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-.client-visit {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 5rem;
-}
+ @import "@/static/scss/form-common.scss";
+ .client-visit {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
-.footer-btns {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background: #fff;
- display: flex;
- justify-content: space-around;
- align-items: center;
- padding: 0.75rem 0;
- box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
- z-index: 1000;
-}
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
-.cancel-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #666;
- background: #f5f5f5;
- border: 1px solid #ddd;
- width: 45%;
- height: 2.5rem;
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #666;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.sign-btn {
- font-weight: 500;
- font-size: 1rem;
- color: #fff;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border: none;
- width: 45%;
- height: 2.5rem;
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .sign-btn {
+ font-weight: 500;
+ font-size: 1rem;
+ color: #fff;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border: none;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.location-icon {
- color: #1989fa;
- font-size: 1.2rem;
-}
+ .location-icon {
+ color: #1989fa;
+ font-size: 1.2rem;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/clientVisit/index.vue b/src/pages/cooperativeOffice/clientVisit/index.vue
index 6ff2467..b8f2358 100644
--- a/src/pages/cooperativeOffice/clientVisit/index.vue
+++ b/src/pages/cooperativeOffice/clientVisit/index.vue
@@ -1,40 +1,43 @@
<template>
<view class="sales-accoun">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="瀹㈡埛鎷滆" @back="goBack" />
-
+ <PageHeader title="瀹㈡埛鎷滆"
+ @back="goBack" />
<!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
<view class="search-section">
<view class="search-bar">
<view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- v-model="customerName"
- @blur="getList"
- clearable
- />
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+ v-model="customerName"
+ @blur="getList"
+ clearable />
</view>
- <view class="filter-button" @click="getList">
- <u-icon name="search" size="24" color="#999"></u-icon>
+ <view class="filter-button"
+ @click="getList">
+ <u-icon name="search"
+ size="24"
+ color="#999"></u-icon>
</view>
</view>
</view>
-
<!-- 鎷滆璁板綍鍒楄〃 -->
- <view class="ledger-list" v-if="visitList.length > 0">
- <view v-for="(item, index) in visitList" :key="index">
+ <view class="ledger-list"
+ v-if="visitList.length > 0">
+ <view v-for="(item, index) in visitList"
+ :key="index">
<view class="ledger-item">
<view class="item-header">
<view class="item-left">
<view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
</view>
<text class="item-id">瀹㈡埛锛歿{ item.customerName }}</text>
</view>
</view>
<up-divider></up-divider>
-
<view class="item-details">
<view class="detail-row">
<text class="detail-label">鑱旂郴浜�</text>
@@ -60,155 +63,204 @@
<text class="detail-label">鎷滆浜�</text>
<text class="detail-value">{{ item.visitingPeople || '-' }}</text>
</view>
- <view class="detail-row" v-if="item.remark">
+ <view class="detail-row"
+ v-if="item.remark">
<text class="detail-label">澶囨敞</text>
<text class="detail-value">{{ item.remark }}</text>
</view>
</view>
-
<!-- 鎸夐挳鍖哄煙 -->
<view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- class="action-btn"
- @click="viewDetail(item)"
- >
+ <u-button type="info"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item)">
鏌ョ湅璇︽儏
</u-button>
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="editVisit(item)">
+ 缂栬緫
+ </u-button>
+ <!-- <u-button type="error"
+ size="small"
+ class="action-btn"
+ @click="deleteVisit(item)">
+ 鍒犻櫎
+ </u-button> -->
</view>
</view>
</view>
</view>
-
- <view v-else class="no-data">
+ <view v-else
+ class="no-data">
<text>鏆傛棤鎷滆璁板綍</text>
</view>
-
<!-- 娴姩鏂板鎸夐挳 -->
- <view class="fab-button" @click="addVisit">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
+ <view class="fab-button"
+ @click="addVisit">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
</view>
</view>
</template>
<script setup>
-import { ref, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { getVisitRecords } from '@/api/cooperativeOffice/clientVisit'
-import useUserStore from "@/store/modules/user"
-// 鏇挎崲 toast 鏂规硶
-defineOptions({name: 'client-visit-index'})
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ import { ref, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getVisitRecords,
+ delCustomer,
+ } from "@/api/cooperativeOffice/clientVisit";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-index" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-import dayjs from "dayjs"
+ import dayjs from "dayjs";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 鎼滅储鍏抽敭璇�
-const customerName = ref('')
+ // 鎼滅储鍏抽敭璇�
+ const customerName = ref("");
-// 鎷滆璁板綍鏁版嵁
-const visitList = ref([])
+ // 鎷滆璁板綍鏁版嵁
+ const visitList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const params = {
- current: -1,
- size: -1,
- customerName: customerName.value,
- }
- getVisitRecords(params)
- .then((res) => {
- visitList.value = res.records || res.data?.records || []
- closeToast()
- })
- .catch(() => {
- closeToast()
- showToast('鑾峰彇鏁版嵁澶辫触')
- })
-}
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ customerName: customerName.value,
+ };
+ getVisitRecords(params)
+ .then(res => {
+ visitList.value = res.records || res.data?.records || [];
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const addVisit = () => {
+ uni.removeStorageSync("clientVisit");
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/clientVisit/detail",
+ });
+ };
+ // 缂栬緫鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const editVisit = item => {
+ uni.setStorageSync("clientVisit", item);
+ // 缂栬緫鎷滆璺宠浆鍒扮櫥璁伴〉闈�
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/clientVisit/detail",
+ });
+ };
+ // 鍒犻櫎鎷滆
+ const deleteVisit = item => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄よ鎷滆璁板綍鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ deleteClientVisit(item.id);
+ }
+ },
+ });
+ };
+ // 鍒犻櫎鎷滆璁板綍
+ const deleteClientVisit = id => {
+ showLoadingToast("鍒犻櫎涓�...");
+ delCustomer(id)
+ .then(() => {
+ closeToast();
+ showToast("鍒犻櫎鎴愬姛");
+ getList();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鍒犻櫎澶辫触");
+ });
+ };
+ // 鏌ョ湅璇︽儏
+ const viewDetail = item => {
+ uni.setStorageSync("clientVisit", item);
+ // 鏌ョ湅璇︽儏璺宠浆鍒板彧璇诲睍绀洪〉闈�
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/clientVisit/view",
+ });
+ };
+
+ onMounted(() => {
+ getList();
});
-};
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
-
-// 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
-const addVisit = () => {
- uni.navigateTo({
- url: '/pages/cooperativeOffice/clientVisit/detail'
- })
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetail = (item) => {
- uni.setStorageSync('clientVisit', item)
- // 鏌ョ湅璇︽儏璺宠浆鍒板彧璇诲睍绀洪〉闈�
- uni.navigateTo({
- url: '/pages/cooperativeOffice/clientVisit/view'
- })
-}
-
-onMounted(() => {
- getList()
-})
-
-onShow(() => {
- getList()
-})
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import "../../../styles/sales-common.scss";
+ @import "../../../styles/sales-common.scss";
-// 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
-.sales-accoun {
- min-height: 100vh;
- background: #f8f9fa;
- position: relative;
- padding-bottom: 80px;
-}
+ // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+ .sales-accoun {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ padding-bottom: 80px;
+ }
-// 鐗瑰畾鐨勫浘鏍囨牱寮�
-.document-icon {
- background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
-}
+ // 鐗瑰畾鐨勫浘鏍囨牱寮�
+ .document-icon {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ }
-// 鐗规湁鏍峰紡
-.visit-status {
- display: flex;
- align-items: center;
-}
+ // 鐗规湁鏍峰紡
+ .visit-status {
+ display: flex;
+ align-items: center;
+ }
-.detail-value {
- word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
-}
+ .detail-value {
+ word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+ }
-// 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
-.fab-button {
- background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
- box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
-}
+ // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+ .fab-button {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+ }
</style>
diff --git a/src/pages/cooperativeOffice/clientVisit/view.vue b/src/pages/cooperativeOffice/clientVisit/view.vue
index f56ddb2..18d1d98 100644
--- a/src/pages/cooperativeOffice/clientVisit/view.vue
+++ b/src/pages/cooperativeOffice/clientVisit/view.vue
@@ -1,7 +1,7 @@
<template>
<view class="client-visit-detail">
- <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
-
+ <PageHeader title="瀹㈡埛鎷滆璇︽儏"
+ @back="goBack" />
<!-- 鍐呭瀹瑰櫒 -->
<view class="content-container">
<!-- 瀹㈡埛淇℃伅 -->
@@ -20,7 +20,6 @@
<text class="info-value">{{ form.contactPhone || '-' }}</text>
</view>
</view>
-
<!-- 鎷滆淇℃伅 -->
<view class="section">
<view class="section-title">鎷滆淇℃伅</view>
@@ -40,12 +39,12 @@
<text class="info-label">鎷滆浜�</text>
<text class="info-value">{{ form.visitingPeople || '-' }}</text>
</view>
- <view class="info-item" v-if="form.latitude && form.longitude">
+ <view class="info-item"
+ v-if="form.latitude && form.longitude">
<text class="info-label">缁忕含搴�</text>
<text class="info-value">{{ form.latitude }}, {{ form.longitude }}</text>
</view>
</view>
-
<!-- 澶囨敞淇℃伅 -->
<view class="section">
<view class="section-title">澶囨敞淇℃伅</view>
@@ -59,120 +58,120 @@
</template>
<script setup>
-// 鏇挎崲 toast 鏂规硶
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏇挎崲 toast 鏂规硶
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-import { ref, onMounted } from 'vue'
-import PageHeader from '@/components/PageHeader.vue'
-import useUserStore from "@/store/modules/user"
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 琛ㄥ崟鏁版嵁
-const form = ref({
- customerName: '',
- contact: '',
- contactPhone: '',
- visitingPeople: '',
- purposeVisit: '',
- purposeDate: '',
- visitAddress: '',
- latitude: '',
- longitude: '',
- locationAddress: '',
- remark: ''
-})
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ customerName: "",
+ contact: "",
+ contactPhone: "",
+ visitingPeople: "",
+ purposeVisit: "",
+ purposeDate: "",
+ visitAddress: "",
+ latitude: "",
+ longitude: "",
+ locationAddress: "",
+ remark: "",
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
- uni.removeStorageSync('clientVisit')
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+ uni.removeStorageSync("clientVisit");
+ uni.navigateBack();
+ };
-// 鍒濆鍖栭〉闈㈡暟鎹�
-const initPageData = () => {
- // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
- const row = uni.getStorageSync('clientVisit')
- if (row) {
- form.value = { ...row }
- } else {
- showToast('鏆傛棤鎷滆璁板綍鏁版嵁')
- }
-}
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const initPageData = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
+ const row = uni.getStorageSync("clientVisit");
+ if (row) {
+ form.value = { ...row };
+ } else {
+ showToast("鏆傛棤鎷滆璁板綍鏁版嵁");
+ }
+ };
-onMounted(() => {
- initPageData()
-})
+ onMounted(() => {
+ initPageData();
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
-.client-visit-detail {
- min-height: 100vh;
- background-color: #f8f9fa;
-}
+ .client-visit-detail {
+ min-height: 100vh;
+ background-color: #f8f9fa;
+ }
-.content-container {
- padding: 16px;
-}
+ .content-container {
+ padding: 16px;
+ }
-.section {
- background-color: #ffffff;
- border-radius: 12px;
- margin-bottom: 16px;
- overflow: hidden;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
-}
+ .section {
+ background-color: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ }
-.section-title {
- font-size: 16px;
- font-weight: 600;
- color: #333333;
- padding: 16px 16px 12px;
- border-bottom: 1px solid #f0f0f0;
-}
+ .section-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333333;
+ padding: 16px 16px 12px;
+ border-bottom: 1px solid #f0f0f0;
+ }
-.info-item {
- display: flex;
- padding: 14px 16px;
- border-bottom: 1px solid #f8f8f8;
- align-items: flex-start;
-}
+ .info-item {
+ display: flex;
+ padding: 14px 16px;
+ border-bottom: 1px solid #f8f8f8;
+ align-items: flex-start;
+ }
-.info-item:last-child {
- border-bottom: none;
-}
+ .info-item:last-child {
+ border-bottom: none;
+ }
-.info-label {
- font-size: 14px;
- color: #666666;
- min-width: 80px;
- flex-shrink: 0;
- line-height: 22px;
-}
+ .info-label {
+ font-size: 14px;
+ color: #666666;
+ min-width: 80px;
+ flex-shrink: 0;
+ line-height: 22px;
+ }
-.info-value {
- font-size: 14px;
- color: #333333;
- flex: 1;
- line-height: 22px;
- text-align: right;
-}
+ .info-value {
+ font-size: 14px;
+ color: #333333;
+ flex: 1;
+ line-height: 22px;
+ text-align: right;
+ }
-.multi-line {
- text-align: left;
- word-break: break-all;
- line-height: 1.6;
-}
+ .multi-line {
+ text-align: left;
+ word-break: break-all;
+ line-height: 1.6;
+ }
-.remark-item {
- padding-bottom: 16px;
-}
+ .remark-item {
+ padding-bottom: 16px;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
index f9e6ed2..aaad83e 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
@@ -25,6 +25,30 @@
<text class="info-label">鐢宠鏃ユ湡</text>
<text class="info-value">{{ approvalData.approveTime }}</text>
</view>
+
+ <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
+ <template v-if="approvalData.approveType === 2">
+ <view class="info-row">
+ <text class="info-label">璇峰亣寮�濮嬫椂闂�</text>
+ <text class="info-value">{{ approvalData.startDate || '-' }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">璇峰亣缁撴潫鏃堕棿</text>
+ <text class="info-value">{{ approvalData.endDate || '-' }}</text>
+ </view>
+ </template>
+
+ <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
+ <view v-if="approvalData.approveType === 3" class="info-row">
+ <text class="info-label">鍑哄樊鍦扮偣</text>
+ <text class="info-value">{{ approvalData.location || '-' }}</text>
+ </view>
+
+ <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
+ <view v-if="approvalData.approveType === 4" class="info-row">
+ <text class="info-label">鎶ラ攢閲戦</text>
+ <text class="info-value">{{ approvalData.price ? `楼${approvalData.price}` : '-' }}</text>
+ </view>
</view>
</view>
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/contactSelect.vue b/src/pages/cooperativeOffice/collaborativeApproval/contactSelect.vue
index d767ad9..31022f2 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/contactSelect.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/contactSelect.vue
@@ -1,11 +1,11 @@
<template>
<view class="contact-select">
<!-- 椤堕儴鏍囬鏍� -->
- <view class="header">
- <up-icon name="arrow-left" size="20" color="#333" @click="goBack" />
- <text class="title">閫夋嫨鑱旂郴浜�</text>
- <text class="confirm-btn" @click="confirmSelect">纭畾</text>
- </view>
+ <PageHeader title="閫夋嫨鑱旂郴浜�" @back="goBack">
+ <template #right>
+ <text class="confirm-btn" @click="confirmSelect">纭畾</text>
+ </template>
+ </PageHeader>
<!-- 鎼滅储妗� -->
<!-- <view class="search-section">-->
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
index a564628..04a4c18 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
@@ -1,85 +1,163 @@
<template>
<view class="account-detail">
- <PageHeader title="瀹℃壒娴佺▼" @back="goBack" />
-
+ <PageHeader title="瀹℃壒娴佺▼"
+ @back="goBack" />
<!-- 琛ㄥ崟鍖哄煙 -->
- <u-form ref="formRef" @submit="submitForm" :rules="rules" :model="form" label-width="140rpx">
- <u-form-item prop="approveReason" label="鐢宠浜嬬敱" required>
- <u-input
- v-model="form.approveReason"
- type="textarea"
- rows="2"
- auto-height
- maxlength="200"
- placeholder="璇疯緭鍏ョ敵璇蜂簨鐢�"
- show-word-limit
- />
+ <u-form ref="formRef"
+ @submit="submitForm"
+ :rules="rules"
+ :model="form"
+ label-width="140rpx">
+ <u-form-item prop="approveReason"
+ label="娴佺▼缂栧彿">
+ <u-input v-model="form.approveId"
+ disabled
+ placeholder="鑷姩缂栧彿" />
</u-form-item>
- <u-form-item prop="approveDeptName" label="鐢宠閮ㄩ棬" required>
- <u-input
- v-model="form.approveDeptName"
- readonly
- placeholder="璇烽�夋嫨鐢宠閮ㄩ棬"
- @click="showPicker = true"
- />
+ <u-form-item prop="approveReason"
+ :label="approveType === 5 ? '閲囪喘浜嬬敱' : '鐢宠浜嬬敱'"
+ required>
+ <u-input v-model="form.approveReason"
+ type="textarea"
+ rows="2"
+ auto-height
+ maxlength="200"
+ :placeholder="approveType === 5 ? '璇疯緭鍏ラ噰璐簨鐢�' : '璇疯緭鍏ョ敵璇蜂簨鐢�'"
+ show-word-limit />
+ </u-form-item>
+ <u-form-item prop="approveDeptName"
+ label="鐢宠閮ㄩ棬"
+ required>
+ <!-- <u-input v-model="form.approveDeptName"
+ placeholder="璇烽�夋嫨鐢宠閮ㄩ棬" /> -->
+ <u-input v-model="form.approveDeptName"
+ readonly
+ placeholder="璇烽�夋嫨鐢宠閮ㄩ棬"
+ @click="showPicker = true" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showPicker = true"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showPicker = true"></up-icon>
+ </template>
</u-form-item>
- <u-form-item prop="approveUser" label="鐢宠浜�" required>
- <u-input
- v-model="form.approveUserName"
- placeholder="璇疯緭鍏ョ敵璇蜂汉"
- readonly
- />
+ <u-form-item prop="approveUser"
+ label="鐢宠浜�"
+ required>
+ <u-input v-model="form.approveUserName"
+ placeholder="璇疯緭鍏ョ敵璇蜂汉"
+ readonly />
</u-form-item>
- <u-form-item prop="approveTime" label="鐢宠鏃ユ湡" required>
- <u-input
- v-model="form.approveTime"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showDatePicker"
- />
+ <u-form-item prop="approveTime"
+ label="鐢宠鏃ユ湡"
+ required>
+ <u-input v-model="form.approveTime"
+ readonly
+ placeholder="璇烽�夋嫨"
+ @click="showDatePicker" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showDatePicker"></up-icon>
+ </template>
+ </u-form-item>
+ <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
+ <template v-if="approveType === 2">
+ <u-form-item prop="startDate"
+ label="寮�濮嬫椂闂�"
+ required>
+ <u-input v-model="form.startDate"
+ readonly
+ placeholder="璇峰亣寮�濮嬫椂闂�"
+ @click="showStartDatePicker" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showStartDatePicker"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item prop="endDate"
+ label="缁撴潫鏃堕棿"
+ required>
+ <u-input v-model="form.endDate"
+ readonly
+ placeholder="璇峰亣缁撴潫鏃堕棿"
+ @click="showEndDatePicker" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showEndDatePicker"></up-icon>
+ </template>
+ </u-form-item>
+ </template>
+ <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
+ <u-form-item v-if="approveType === 3"
+ prop="location"
+ label="鍑哄樊鍦扮偣"
+ required>
+ <u-input v-model="form.location"
+ placeholder="璇疯緭鍏ュ嚭宸湴鐐�"
+ clearable />
+ </u-form-item>
+ <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
+ <u-form-item v-if="approveType === 4"
+ prop="price"
+ label="鎶ラ攢閲戦"
+ required>
+ <u-input v-model="form.price"
+ type="number"
+ placeholder="璇疯緭鍏ユ姤閿�閲戦"
+ clearable />
</u-form-item>
</u-form>
-
<!-- 閫夋嫨鍣ㄥ脊绐� -->
- <up-action-sheet
- :show="showPicker"
- :actions="productOptions"
- title="閫夋嫨閮ㄩ棬"
- @select="onConfirm"
- @close="showPicker = false"
- />
-
+ <up-action-sheet :show="showPicker"
+ :actions="productOptions"
+ title="閫夋嫨閮ㄩ棬"
+ @select="onConfirm"
+ @close="showPicker = false" />
<!-- 鏃ユ湡閫夋嫨鍣� -->
- <u-popup v-model="showDate" mode="bottom">
- <u-datetime-picker
- v-model="currentDate"
- title="閫夋嫨鏃ユ湡"
- mode="date"
- @confirm="onDateConfirm"
- @cancel="showDate = false"
- />
- </u-popup>
+ <up-popup :show="showDate"
+ mode="bottom"
+ @close="showDate = false">
+ <up-datetime-picker :show="true"
+ v-model="currentDate"
+ @confirm="onDateConfirm"
+ @cancel="showDate = false"
+ mode="date" />
+ </up-popup>
+ <!-- 璇峰亣寮�濮嬫椂闂撮�夋嫨鍣� -->
+ <up-popup :show="showStartDate"
+ mode="bottom"
+ @close="showStartDate = false">
+ <up-datetime-picker :show="true"
+ v-model="startDateValue"
+ @confirm="onStartDateConfirm"
+ @cancel="showStartDate = false"
+ mode="date" />
+ </up-popup>
+ <!-- 璇峰亣缁撴潫鏃堕棿閫夋嫨鍣� -->
+ <up-popup :show="showEndDate"
+ mode="bottom"
+ @close="showEndDate = false">
+ <up-datetime-picker :show="true"
+ v-model="endDateValue"
+ @confirm="onEndDateConfirm"
+ @cancel="showEndDate = false"
+ mode="date" />
+ </up-popup>
<!-- 瀹℃牳娴佺▼鍖哄煙 -->
<view class="approval-process">
<view class="approval-header">
<text class="approval-title">瀹℃牳娴佺▼</text>
<text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
</view>
-
<view class="approval-steps">
- <view v-for="(step, stepIndex) in approverNodes" :key="stepIndex" class="approval-step">
+ <view v-for="(step, stepIndex) in approverNodes"
+ :key="stepIndex"
+ class="approval-step">
<view class="step-dot"></view>
<view class="step-title">
<text>瀹℃壒浜�</text>
</view>
<view class="approver-container">
- <view v-if="step.nickName" class="approver-item">
+ <view v-if="step.nickName"
+ class="approver-item">
<view class="approver-avatar">
<text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
<view class="status-dot"></view>
@@ -87,664 +165,765 @@
<view class="approver-info">
<text class="approver-name">{{ step.nickName }}</text>
</view>
- <view class="delete-approver-btn" @click="removeApprover(stepIndex)">脳</view>
+ <view class="delete-approver-btn"
+ @click="removeApprover(stepIndex)">脳</view>
</view>
- <view v-else class="add-approver-btn" @click="addApprover(stepIndex)">
+ <view v-else
+ class="add-approver-btn"
+ @click="addApprover(stepIndex)">
<view class="add-circle">+</view>
<text class="add-label">閫夋嫨瀹℃壒浜�</text>
</view>
</view>
- <view class="step-line" v-if="stepIndex < approverNodes.length - 1"></view>
- <view class="delete-step-btn" v-if="approverNodes.length > 1" @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
+ <view class="step-line"
+ v-if="stepIndex < approverNodes.length - 1"></view>
+ <view class="delete-step-btn"
+ v-if="approverNodes.length > 1"
+ @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
</view>
</view>
-
<view class="add-step-btn">
- <u-button icon="plus" plain type="primary" style="width: 100%" @click="addApprovalStep">鏂板鑺傜偣</u-button>
+ <u-button icon="plus"
+ plain
+ type="primary"
+ style="width: 100%"
+ @click="addApprovalStep">鏂板鑺傜偣</u-button>
</view>
</view>
-
<!-- 搴曢儴鎸夐挳 -->
<view class="footer-btns">
- <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
- <u-button class="save-btn" @click="submitForm">淇濆瓨</u-button>
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="save-btn"
+ @click="submitForm">淇濆瓨</u-button>
</view>
</view>
</template>
<script setup>
-import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
-import PageHeader from "@/components/PageHeader.vue";
-import useUserStore from "@/store/modules/user";
-import { formatDateToYMD } from '@/utils/ruoyi'
-import {getDept, approveProcessGetInfo, approveProcessAdd, approveProcessUpdate} from "@/api/collaborativeApproval/approvalProcess";
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
-import {userListNoPageByTenantId} from "@/api/system/user";
+ import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { formatDateToYMD } from "@/utils/ruoyi";
+ import {
+ getDept,
+ approveProcessGetInfo,
+ approveProcessAdd,
+ approveProcessUpdate,
+ } from "@/api/collaborativeApproval/approvalProcess";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import { userListNoPageByTenantId } from "@/api/system/user";
-const data = reactive({
- form: {
- approveTime: "",
- approveId: "",
- approveUser: "",
- approveUserName: "",
- approveDeptName: "",
- approveDeptId: "",
- approveReason: "",
- checkResult: "",
- tempFileIds: [],
- approverList: [] // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
- },
- rules: {
- approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" },],
- approveId: [{ 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 result = ref("");
-const showPicker = ref(false);
-const productOptions = ref([]);
-const operationType = ref("");
-const currentApproveStatus = ref("");
-const approverNodes = ref([]);
-const userList = ref([]);
-const formRef = ref(null);
-const message = ref("");
-const showDate = ref(false)
-const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()])
-const userStore = useUserStore()
-
-const getProductOptions = () => {
- getDept().then((res) => {
- productOptions.value = res.data.map(item => ({
- value: item.deptId,
- name: item.deptName
- }))
- });
-};
-const fileList = ref([]);
-let nextApproverId = 2;
-
-onMounted(async () => {
- try {
- getProductOptions()
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data
- })
- form.value.approveUser = userStore.id
- form.value.approveUserName = userStore.nickName
- form.value.approveTime = getCurrentDate();
-
- // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧弬鏁�
- operationType.value = uni.getStorageSync('operationType') || 'add';
-
- // 濡傛灉鏄紪杈戞ā寮忥紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨暟鎹�
- if (operationType.value === 'edit') {
- const storedData = uni.getStorageSync('invoiceLedgerEditRow');
- if (storedData) {
- const row = JSON.parse(storedData);
- 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) => {
- const userIdNum = parseInt(userId.trim());
- // 浠巙serList涓壘鍒板搴旂殑鐢ㄦ埛淇℃伅
- const userInfo = userList.value.find(user => user.userId === userIdNum);
- return {
- id: idx + 1,
- userId: userIdNum,
- nickName: userInfo ? userInfo.nickName : null
- };
- });
- nextApproverId = userIds.length + 1;
- } else {
- // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
- approverNodes.value = [{ id: 1, userId: null, nickName: null }];
- nextApproverId = 2;
- }
- });
- }
- } else {
- // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
- approverNodes.value = [{ id: 1, userId: null }];
- }
-
- // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
- uni.$on('selectContact', handleSelectContact);
- } catch (error) {
- console.error("鑾峰彇閮ㄩ棬鏁版嵁澶辫触:", error);
- }
-});
-
-onUnmounted(() => {
- // 绉婚櫎浜嬩欢鐩戝惉
- uni.$off('selectContact', handleSelectContact);
-});
-
-const onConfirm = (item) => {
- // 璁剧疆閫変腑鐨勯儴闂�
- form.value.approveDeptName = item.name;
- // 纭繚璁剧疆鐨勬槸瀛楃涓茬被鍨嬬殑閮ㄩ棬ID
- form.value.approveDeptId = String(item.value || '');
- console.log('閮ㄩ棬閫夋嫨鍚庣殑鍊�:', {
- approveDeptId: form.value.approveDeptId,
- approveDeptName: form.value.approveDeptName
+ const data = reactive({
+ form: {
+ approveTime: "",
+ approveId: "",
+ approveUser: "",
+ approveUserName: "",
+ approveDeptName: "",
+ approveDeptId: "",
+ approveReason: "",
+ checkResult: "",
+ tempFileIds: [],
+ approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
+ startDate: "",
+ endDate: "",
+ location: "",
+ price: "",
+ },
+ rules: {
+ approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" }],
+ approveId: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ approveDeptId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ approveReason: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ checkResult: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+ startDate: [
+ { required: false, message: "璇烽�夋嫨寮�濮嬫椂闂�", trigger: "change" },
+ ],
+ endDate: [
+ { required: false, message: "璇烽�夋嫨缁撴潫鏃堕棿", trigger: "change" },
+ ],
+ location: [{ required: false, message: "璇疯緭鍏ュ嚭宸湴鐐�", trigger: "blur" }],
+ price: [{ required: false, message: "璇疯緭鍏ユ姤閿�閲戦", trigger: "blur" }],
+ },
});
- showPicker.value = false;
-};
+ const { form, rules } = toRefs(data);
+ const result = ref("");
+ const showPicker = ref(false);
+ const productOptions = ref([]);
+ const operationType = ref("");
+ const currentApproveStatus = ref("");
+ const approverNodes = ref([]);
+ const userList = ref([]);
+ const formRef = ref(null);
+ const message = ref("");
+ const showDate = ref(false);
+ const currentDate = ref(Date.now());
+ const showStartDate = ref(false);
+ const startDateValue = ref(Date.now());
+ const showEndDate = ref(false);
+ const endDateValue = ref(Date.now());
+ const userStore = useUserStore();
+ const approveType = ref(0);
-const goBack = () => {
- // 娓呴櫎鏈湴瀛樺偍鐨勬暟鎹�
- uni.removeStorageSync('operationType');
- uni.removeStorageSync('invoiceLedgerEditRow');
- uni.navigateBack();
-};
+ const getProductOptions = () => {
+ getDept().then(res => {
+ productOptions.value = res.data.map(item => ({
+ value: item.deptId,
+ name: item.deptName,
+ }));
+ });
+ };
+ const fileList = ref([]);
+ let nextApproverId = 2;
+ const getCurrentinfo = () => {
+ userStore.getInfo().then(res => {
+ form.value.approveDeptId = res.user.tenantId;
+ console.log(res.user.tenantId, "res.user.tenantId");
+ });
+ };
+ onMounted(async () => {
+ try {
+ getProductOptions();
+ userListNoPageByTenantId().then(res => {
+ userList.value = res.data;
+ });
+ form.value.approveUser = userStore.id;
+ form.value.approveUserName = userStore.nickName;
+ form.value.approveTime = getCurrentDate();
+ getCurrentinfo();
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧弬鏁�
+ operationType.value = uni.getStorageSync("operationType") || "add";
+ approveType.value = uni.getStorageSync("approveType") || 0;
-const submitForm = () => {
- // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
- const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
- if (hasEmptyStep) {
- showToast('璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�');
- return;
- }
-
- // 鎵嬪姩妫�鏌ュ繀濉瓧娈碉紝闃叉鍥犳暟鎹被鍨嬮棶棰樺鑷寸殑鏍¢獙澶辫触
- if (!form.value.approveReason || !form.value.approveReason.trim()) {
- showToast('璇疯緭鍏ョ敵璇蜂簨鐢�');
- return;
- }
-
- if (!form.value.approveDeptId || String(form.value.approveDeptId).trim() === '') {
- showToast('璇烽�夋嫨鐢宠閮ㄩ棬');
- return;
- }
-
- if (!form.value.approveTime) {
- showToast('璇烽�夋嫨鐢宠鏃ユ湡');
- return;
- }
-
- formRef.value.validate().then((valid) => {
- if (valid) {
- // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
- // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
- console.log('approverNodes---', approverNodes.value)
- form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
- form.value.approveType = 0
- if (operationType.value === "add" || currentApproveStatus.value == 3) {
- approveProcessAdd(form.value).then(res => {
- showToast("鎻愪氦鎴愬姛");
- goBack()
- })
- } else {
- approveProcessUpdate(form.value).then(res => {
- showToast("鎻愪氦鎴愬姛");
- goBack()
- })
- }
- }
- }).catch((error) => {
- console.error("琛ㄥ崟鏍¢獙澶辫触:", error);
- // 灏濊瘯鑾峰彇鍏蜂綋鐨勯敊璇瓧娈�
- if (error && error.errors) {
- const firstError = error.errors[0];
- if (firstError) {
- uni.showToast({
- title: firstError.message || '琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」',
- icon: 'none'
- });
- return;
+ // 濡傛灉鏄紪杈戞ā寮忥紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨暟鎹�
+ if (operationType.value === "edit") {
+ const storedData = uni.getStorageSync("invoiceLedgerEditRow");
+ if (storedData) {
+ const row = JSON.parse(storedData);
+ 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) => {
+ const userIdNum = parseInt(userId.trim());
+ // 浠巙serList涓壘鍒板搴旂殑鐢ㄦ埛淇℃伅
+ const userInfo = userList.value.find(
+ user => user.userId === userIdNum
+ );
+ return {
+ id: idx + 1,
+ userId: userIdNum,
+ nickName: userInfo ? userInfo.nickName : null,
+ };
+ });
+ nextApproverId = userIds.length + 1;
+ } else {
+ // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
+ approverNodes.value = [{ id: 1, userId: null, nickName: null }];
+ nextApproverId = 2;
+ }
+ }
+ );
+ }
+ } else {
+ // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
+ approverNodes.value = [{ id: 1, userId: null }];
}
+
+ // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
+ uni.$on("selectContact", handleSelectContact);
+ } catch (error) {
+ console.error("鑾峰彇閮ㄩ棬鏁版嵁澶辫触:", error);
}
- // 鏄剧ず閫氱敤閿欒淇℃伅
- uni.showToast({
- title: '琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」',
- icon: 'none'
- });
});
-};
-// 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
-const handleSelectContact = (data) => {
- const { stepIndex, contact } = data;
- // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
- approverNodes.value[stepIndex].userId = contact.userId;
- approverNodes.value[stepIndex].nickName = contact.nickName;
-};
-
-const addApprover = (stepIndex) => {
- // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
- uni.setStorageSync('stepIndex', stepIndex);
- uni.navigateTo({
- url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect"
+ onUnmounted(() => {
+ // 绉婚櫎浜嬩欢鐩戝惉
+ uni.$off("selectContact", handleSelectContact);
});
-};
-const addApprovalStep = () => {
- // 娣诲姞鏂扮殑瀹℃壒姝ラ
- approverNodes.value.push({ userId: null, nickName: null });
-};
-
-const removeApprover = (stepIndex) => {
- // 绉婚櫎瀹℃壒浜�
- approverNodes.value[stepIndex].userId = null;
- approverNodes.value[stepIndex].nickName = null;
-};
-
-const removeApprovalStep = (stepIndex) => {
- // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
- if (approverNodes.value.length > 1) {
- approverNodes.value.splice(stepIndex, 1);
- } else {
- uni.showToast({
- title: '鑷冲皯闇�瑕佷竴涓鎵规楠�',
- icon: 'none'
+ const onConfirm = item => {
+ // 璁剧疆閫変腑鐨勯儴闂�
+ form.value.approveDeptName = item.name;
+ // 纭繚璁剧疆鐨勬槸瀛楃涓茬被鍨嬬殑閮ㄩ棬ID
+ form.value.approveDeptId = String(item.value || "");
+ console.log("閮ㄩ棬閫夋嫨鍚庣殑鍊�:", {
+ approveDeptId: form.value.approveDeptId,
+ approveDeptName: form.value.approveDeptName,
});
+ showPicker.value = false;
+ };
+
+ const goBack = () => {
+ // 娓呴櫎鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("operationType");
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.removeStorageSync("approveType");
+ uni.navigateBack();
+ };
+
+ const submitForm = () => {
+ // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
+ const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
+ if (hasEmptyStep) {
+ showToast("璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�");
+ return;
+ }
+
+ // 鎵嬪姩妫�鏌ュ繀濉瓧娈碉紝闃叉鍥犳暟鎹被鍨嬮棶棰樺鑷寸殑鏍¢獙澶辫触
+ if (!form.value.approveReason || !form.value.approveReason.trim()) {
+ showToast("璇疯緭鍏ョ敵璇蜂簨鐢�");
+ return;
+ }
+
+ if (
+ !form.value.approveDeptId ||
+ String(form.value.approveDeptId).trim() === ""
+ ) {
+ showToast("璇烽�夋嫨鐢宠閮ㄩ棬");
+ return;
+ }
+
+ if (!form.value.approveTime) {
+ showToast("璇烽�夋嫨鐢宠鏃ユ湡");
+ return;
+ }
+
+ formRef.value
+ .validate()
+ .then(valid => {
+ if (valid) {
+ // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
+ // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
+ console.log("approverNodes---", approverNodes.value);
+ form.value.approveUserIds = approverNodes.value
+ .map(node => node.userId)
+ .join(",");
+ form.value.approveType = approveType.value;
+ form.value.approveDeptId = Number(form.value.approveDeptId);
+ // const submitForm = {
+ // approveDeptId: form.value.approveDeptId,
+ // approveDeptName: form.value.approveDeptName,
+ // approveReason: form.value.approveReason,
+ // approveTime: form.value.approveTime,
+ // approveType: form.value.approveType,
+ // approveUser: form.value.approveUser,
+ // approveUserIds: form.value.approveUserIds,
+ // endDate: form.value.endDate,
+ // startDate: form.value.startDate,
+ // };
+ // console.log("form.value---", form.value);
+ // console.log("submitForm", submitForm);
+
+ if (operationType.value === "add" || currentApproveStatus.value == 3) {
+ approveProcessAdd(form.value).then(res => {
+ showToast("鎻愪氦鎴愬姛");
+ goBack();
+ });
+ } else {
+ approveProcessUpdate(form.value).then(res => {
+ showToast("鎻愪氦鎴愬姛");
+ goBack();
+ });
+ }
+ }
+ })
+ .catch(error => {
+ console.error("琛ㄥ崟鏍¢獙澶辫触:", error);
+ // 灏濊瘯鑾峰彇鍏蜂綋鐨勯敊璇瓧娈�
+ if (error && error.errors) {
+ const firstError = error.errors[0];
+ if (firstError) {
+ uni.showToast({
+ title: firstError.message || "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ return;
+ }
+ }
+ // 鏄剧ず閫氱敤閿欒淇℃伅
+ uni.showToast({
+ title: "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ });
+ };
+
+ // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
+ const handleSelectContact = data => {
+ const { stepIndex, contact } = data;
+ // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = contact.userId;
+ approverNodes.value[stepIndex].nickName = contact.nickName;
+ };
+
+ const addApprover = stepIndex => {
+ // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
+ uni.setStorageSync("stepIndex", stepIndex);
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
+ });
+ };
+
+ const addApprovalStep = () => {
+ // 娣诲姞鏂扮殑瀹℃壒姝ラ
+ approverNodes.value.push({ userId: null, nickName: null });
+ };
+
+ const removeApprover = stepIndex => {
+ // 绉婚櫎瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = null;
+ approverNodes.value[stepIndex].nickName = null;
+ };
+
+ const removeApprovalStep = stepIndex => {
+ // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
+ if (approverNodes.value.length > 1) {
+ approverNodes.value.splice(stepIndex, 1);
+ } else {
+ uni.showToast({
+ title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
+ icon: "none",
+ });
+ }
+ };
+ // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+ const showDatePicker = () => {
+ showDate.value = true;
+ };
+
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.approveTime = formatDateToYMD(e.value);
+ currentDate.value = formatDateToYMD(e.value);
+ showDate.value = false;
+ };
+
+ // 鏄剧ず璇峰亣寮�濮嬫椂闂撮�夋嫨鍣�
+ const showStartDatePicker = () => {
+ showStartDate.value = true;
+ };
+
+ // 纭璇峰亣寮�濮嬫椂闂撮�夋嫨
+ const onStartDateConfirm = e => {
+ form.value.startDate = formatDateToYMD(e.value);
+ showStartDate.value = false;
+ };
+
+ const showEndDatePicker = () => {
+ showEndDate.value = true;
+ };
+
+ // 纭璇峰亣缁撴潫鏃堕棿閫夋嫨
+ const onEndDateConfirm = e => {
+ form.value.endDate = formatDateToYMD(e.value);
+ showEndDate.value = false;
+ };
+
+ // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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 showDatePicker = () => {
- showDate.value = true
-}
-
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
- form.value.approveTime = formatDateToYMD(e.value)
- currentDate.value = formatDateToYMD(e.value)
- showDate.value = false;
-}
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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}`;
-}
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
-.approval-process {
- background: #fff;
- margin: 16px;
- border-radius: 16px;
- padding: 16px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
-}
-
-.approval-header {
- margin-bottom: 16px;
-}
-
-.approval-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
- display: block;
- margin-bottom: 4px;
-}
-
-.approval-desc {
- font-size: 12px;
- color: #999;
-}
-
-/* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
-.approval-steps {
- padding-left: 22px;
- position: relative;
-
- &::before {
- content: '';
- position: absolute;
- left: 11px;
- top: 40px;
- bottom: 40px;
- width: 2px;
- background: linear-gradient(to bottom, #e6f7ff 0%, #bae7ff 50%, #91d5ff 100%);
- border-radius: 1px;
- }
-}
-
-.approval-step {
- position: relative;
- margin-bottom: 24px;
-
- &::before {
- content: '';
- position: absolute;
- left: -18px;
- top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
- width: 12px;
- height: 12px;
+ .approval-process {
background: #fff;
- border: 3px solid #006cfb;
- border-radius: 50%;
- z-index: 2;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ margin: 16px;
+ border-radius: 16px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
-}
-.step-title {
- top: 12px;
- margin-bottom: 12px;
- position: relative;
- margin-left: 6px;
-}
-
-.step-title text {
- font-size: 14px;
- color: #666;
- background: #f0f0f0;
- padding: 4px 12px;
- border-radius: 12px;
- position: relative;
- line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
-}
-
-.approver-item {
- display: flex;
- align-items: center;
- background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
- border-radius: 16px;
- padding: 16px;
- gap: 12px;
- position: relative;
- border: 1px solid #e6f7ff;
- box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
- transition: all 0.3s ease;
-}
-
-.approver-avatar {
- width: 48px;
- height: 48px;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
-}
-
-.avatar-text {
- color: #fff;
- font-size: 18px;
- font-weight: 600;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.approver-info {
- flex: 1;
- position: relative;
-}
-
-.approver-name {
- display: block;
- font-size: 16px;
- color: #333;
- font-weight: 500;
- position: relative;
-}
-
-.approver-dept {
- font-size: 12px;
- color: #999;
- background: rgba(0, 108, 251, 0.05);
- padding: 2px 8px;
- border-radius: 8px;
- display: inline-block;
- position: relative;
-
- &::before {
- content: '';
- position: absolute;
- left: 4px;
- top: 50%;
- transform: translateY(-50%);
- width: 2px;
- height: 2px;
- background: #006cfb;
- border-radius: 50%;
+ .approval-header {
+ margin-bottom: 16px;
}
-}
-.delete-approver-btn {
- font-size: 16px;
- color: #ff4d4f;
- background: linear-gradient(135deg, rgba(255, 77, 79, 0.1) 0%, rgba(255, 77, 79, 0.05) 100%);
- width: 28px;
- height: 28px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.3s ease;
- position: relative;
-}
+ .approval-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
-.add-approver-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
- border: 2px dashed #006cfb;
- border-radius: 16px;
- padding: 20px;
- color: #006cfb;
- font-size: 14px;
- position: relative;
- transition: all 0.3s ease;
-
- &::before {
- content: '';
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- width: 32px;
- height: 32px;
- border: 2px solid #006cfb;
- border-radius: 50%;
- opacity: 0;
+ .approval-desc {
+ font-size: 12px;
+ color: #999;
+ }
+
+ /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
+ .approval-steps {
+ padding-left: 22px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 11px;
+ top: 40px;
+ bottom: 40px;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ #e6f7ff 0%,
+ #bae7ff 50%,
+ #91d5ff 100%
+ );
+ border-radius: 1px;
+ }
+ }
+
+ .approval-step {
+ position: relative;
+ margin-bottom: 24px;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: -18px;
+ top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
+ width: 12px;
+ height: 12px;
+ background: #fff;
+ border: 3px solid #006cfb;
+ border-radius: 50%;
+ z-index: 2;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ .step-title {
+ top: 12px;
+ margin-bottom: 12px;
+ position: relative;
+ margin-left: 6px;
+ }
+
+ .step-title text {
+ font-size: 14px;
+ color: #666;
+ background: #f0f0f0;
+ padding: 4px 12px;
+ border-radius: 12px;
+ position: relative;
+ line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ padding: 16px;
+ gap: 12px;
+ position: relative;
+ border: 1px solid #e6f7ff;
+ box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
transition: all 0.3s ease;
}
-}
-.delete-step-btn {
- color: #ff4d4f;
- font-size: 12px;
- background: linear-gradient(135deg, rgba(255, 77, 79, 0.1) 0%, rgba(255, 77, 79, 0.05) 100%);
- padding: 6px 12px;
- border-radius: 12px;
- display: inline-block;
- position: relative;
- transition: all 0.3s ease;
-
- &::before {
- content: '';
- position: absolute;
- left: 6px;
- top: 50%;
- transform: translateY(-50%);
- width: 4px;
- height: 4px;
- background: #ff4d4f;
+ .approver-avatar {
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
-}
-.step-line {
- display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
-}
-
-.add-step-btn {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-.footer-btns {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background: #fff;
- display: flex;
- justify-content: space-around;
- align-items: center;
- padding: 0.75rem 0;
- box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
- z-index: 1000;
-}
-
-.cancel-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 6.375rem;
- background: #C7C9CC;
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
-
-.save-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 14rem;
- background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
-
-// 鍔ㄧ敾瀹氫箟
-@keyframes pulse {
- 0% {
- transform: scale(1);
- opacity: 1;
+ .avatar-text {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
- 50% {
- transform: scale(1.2);
- opacity: 0.7;
+
+ .approver-info {
+ flex: 1;
+ position: relative;
}
- 100% {
- transform: scale(1);
- opacity: 1;
+
+ .approver-name {
+ display: block;
+ font-size: 16px;
+ color: #333;
+ font-weight: 500;
+ position: relative;
}
-}
-@keyframes rotate {
- 0% {
- transform: rotate(0deg);
+ .approver-dept {
+ font-size: 12px;
+ color: #999;
+ background: rgba(0, 108, 251, 0.05);
+ padding: 2px 8px;
+ border-radius: 8px;
+ display: inline-block;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 4px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 2px;
+ height: 2px;
+ background: #006cfb;
+ border-radius: 50%;
+ }
}
- 100% {
- transform: rotate(360deg);
+
+ .delete-approver-btn {
+ font-size: 16px;
+ color: #ff4d4f;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s ease;
+ position: relative;
}
-}
-@keyframes ripple {
- 0% {
- transform: translate(-50%, -50%) scale(0.8);
- opacity: 1;
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
+ border: 2px dashed #006cfb;
+ border-radius: 16px;
+ padding: 20px;
+ color: #006cfb;
+ font-size: 14px;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: 32px;
+ height: 32px;
+ border: 2px solid #006cfb;
+ border-radius: 50%;
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
}
- 100% {
- transform: translate(-50%, -50%) scale(1.6);
- opacity: 0;
+
+ .delete-step-btn {
+ color: #ff4d4f;
+ font-size: 12px;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ padding: 6px 12px;
+ border-radius: 12px;
+ display: inline-block;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 6px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 4px;
+ height: 4px;
+ background: #ff4d4f;
+ border-radius: 50%;
+ }
}
-}
-/* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
-.step-line {
- position: absolute;
- left: 4px;
- top: 48px;
- width: 2px;
- height: calc(100% - 48px);
- background: #E5E7EB;
-}
+ .step-line {
+ display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
+ }
-.approver-container {
- display: flex;
- align-items: center;
- background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
- border-radius: 16px;
- gap: 12px;
- padding: 10px 0;
- background: transparent;
- border: none;
- box-shadow: none;
-}
+ .add-step-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
-.approver-item {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 8px 10px;
- background: transparent;
- border: none;
- box-shadow: none;
- border-radius: 0;
-}
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.approver-avatar {
- position: relative;
- width: 40px;
- height: 40px;
- border-radius: 50%;
- background: #F3F4F6;
- border: 2px solid #E5E7EB;
- display: flex;
- align-items: center;
- justify-content: center;
- animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
-}
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.avatar-text {
- font-size: 14px;
- color: #374151;
- font-weight: 600;
-}
+ // 鍔ㄧ敾瀹氫箟
+ @keyframes pulse {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.7;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ }
-.add-approver-btn {
- display: flex;
- align-items: center;
- gap: 8px;
- background: transparent;
- border: none;
- box-shadow: none;
- padding: 0;
-}
+ @keyframes rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
-.add-approver-btn .add-circle {
- width: 40px;
- height: 40px;
- border: 2px dashed #A0AEC0;
- border-radius: 50%;
- color: #6B7280;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 22px;
- line-height: 1;
-}
+ @keyframes ripple {
+ 0% {
+ transform: translate(-50%, -50%) scale(0.8);
+ opacity: 1;
+ }
+ 100% {
+ transform: translate(-50%, -50%) scale(1.6);
+ opacity: 0;
+ }
+ }
-.add-approver-btn .add-label {
- color: #3B82F6;
- font-size: 14px;
-}
+ /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
+ .step-line {
+ position: absolute;
+ left: 4px;
+ top: 48px;
+ width: 2px;
+ height: calc(100% - 48px);
+ background: #e5e7eb;
+ }
+
+ .approver-container {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ gap: 12px;
+ padding: 10px 0;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 10px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ border-radius: 0;
+ }
+
+ .approver-avatar {
+ position: relative;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: #f3f4f6;
+ border: 2px solid #e5e7eb;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
+ }
+
+ .avatar-text {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 600;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ padding: 0;
+ }
+
+ .add-approver-btn .add-circle {
+ width: 40px;
+ height: 40px;
+ border: 2px dashed #a0aec0;
+ border-radius: 50%;
+ color: #6b7280;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ line-height: 1;
+ }
+
+ .add-approver-btn .add-label {
+ color: #3b82f6;
+ font-size: 14px;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index.vue b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
index 8aab757..21a3f7b 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/index.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -1,315 +1,376 @@
// 瀹℃壒绠$悊涓婚〉闈�
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="瀹℃壒绠$悊" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ユ祦绋嬬紪鍙�"
- v-model="searchForm.approveId"
- clearable
- />
- </view>
- <view class="search-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 瀹℃壒鍒楄〃 -->
- <view class="ledger-list" v-if="ledgerList.length > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.approveId }}</text>
- </view>
- <view class="item-tag">
- <u-tag :type="getTagClass(item.approveStatus)">{{ formatReceiptType(item.approveStatus) }}</u-tag>
- </view>
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">鐢宠浜�</text>
- <text class="detail-value">{{ item.approveUserName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鐢宠閮ㄩ棬</text>
- <text class="detail-value">{{ item.approveDeptName }}</text>
- </view>
- <view class="detail-row-approveReason">
- <text class="detail-label">瀹℃壒浜嬬敱</text>
- <text class="detail-value highlightBlue">{{ item.approveReason }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鐢宠鏃ユ湡</text>
- <text class="detail-value">{{ item.approveTime }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">缁撴潫鏃ユ湡</text>
- <text class="detail-value">{{ item.approveOverTime }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row-user">
- <text class="detail-label">褰撳墠瀹℃壒浜�</text>
- <view class="detail-value approver-value">
- <view class="approver-chip">
- <text class="approver-name">{{ item.approveUserCurrentName || '鏈垎閰�' }}</text>
- </view>
- </view>
- </view>
- <view class="detail-row">
- <view class="actions">
- <u-button
- type="primary"
- size="small"
- class="action-btn edit"
- :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4"
- @click="handleItemClick(item)"
- >
- 缂栬緫
- </u-button>
- <u-button
- type="success"
- size="small"
- class="action-btn approve"
- :disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveUserCurrentId !== userStore.id"
- @click="approve(item)"
- >
- 瀹℃牳
- </u-button>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤瀹℃壒鏁版嵁</text>
- </view>
- <!-- 娴姩鎿嶄綔鎸夐挳 -->
- <view class="fab-button" @click="handleAdd">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader :title="pageTitle"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ユ祦绋嬬紪鍙�"
+ v-model="searchForm.approveId"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 瀹℃壒鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.approveId }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.approveStatus)">{{ formatReceiptType(item.approveStatus) }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐢宠浜�</text>
+ <text class="detail-value">{{ item.approveUserName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢宠閮ㄩ棬</text>
+ <text class="detail-value">{{ item.approveDeptName }}</text>
+ </view>
+ <view class="detail-row-approveReason">
+ <text class="detail-label">瀹℃壒浜嬬敱</text>
+ <text class="detail-value highlightBlue">{{ item.approveReason }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢宠鏃ユ湡</text>
+ <text class="detail-value">{{ item.approveTime }}</text>
+ </view>
+ <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
+ <template v-if="item.approveType === 2">
+ <view class="detail-row">
+ <text class="detail-label">璇峰亣寮�濮嬫椂闂�</text>
+ <text class="detail-value">{{ item.startDate || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">璇峰亣缁撴潫鏃堕棿</text>
+ <text class="detail-value">{{ item.endDate || '-' }}</text>
+ </view>
+ </template>
+ <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
+ <view v-if="item.approveType === 3"
+ class="detail-row">
+ <text class="detail-label">鍑哄樊鍦扮偣</text>
+ <text class="detail-value">{{ item.location || '-' }}</text>
+ </view>
+ <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
+ <view v-if="item.approveType === 4"
+ class="detail-row">
+ <text class="detail-label">鎶ラ攢閲戦</text>
+ <text class="detail-value highlightYellow">{{ item.price ? `楼${item.price}` : '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">缁撴潫鏃ユ湡</text>
+ <text class="detail-value">{{ item.approveOverTime }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row-user">
+ <text class="detail-label">褰撳墠瀹℃壒浜�</text>
+ <view class="detail-value approver-value">
+ <view class="approver-chip">
+ <text class="approver-name">{{ item.approveUserCurrentName || '鏈垎閰�' }}</text>
+ </view>
+ </view>
+ </view>
+ <view class="detail-row">
+ <view class="actions">
+ <u-button type="primary"
+ size="small"
+ class="action-btn edit"
+ :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4 || item.approveStatus == 8"
+ @click="handleItemClick(item)">
+ 缂栬緫
+ </u-button>
+ <u-button type="success"
+ size="small"
+ class="action-btn approve"
+ :disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveStatus == 8 || item.approveUserCurrentId !== userStore.id"
+ @click="approve(item)">
+ 瀹℃牳
+ </u-button>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤瀹℃壒鏁版嵁</text>
+ </view>
+ <!-- 娴姩鎿嶄綔鎸夐挳 -->
+ <view class="fab-button"
+ v-if="props.approveType != 5 && props.approveType != 6 && props.approveType != 7"
+ @click="handleAdd">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view>
+ </view>
</template>
<script setup>
- import {
- ref,
- toRefs,
- reactive
- } from "vue";
- import PageHeader from "@/components/PageHeader.vue";
- import {approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess";
- import {onShow} from "@dcloudio/uni-app";
- import useUserStore from "@/store/modules/user";
-
- const userStore = useUserStore()
- // 鏁版嵁
- const ledgerList = ref([]);
- const data = reactive({
- searchForm: {
- approveId: "",
- },
- });
- const { searchForm } = toRefs(data);
+ import { ref, toRefs, reactive } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { approveProcessListPage } from "@/api/collaborativeApproval/approvalProcess";
+ import { onLoad, onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
- // 杩斿洖涓婁竴椤�
- const goBack = () => {
- uni.navigateBack();
- };
- // 鏌ヨ鍒楄〃
- const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1,
- };
- approveProcessListPage({
- ...page,approveType: 0,...searchForm.value
- })
- .then((res) => {
- ledgerList.value = res.data.records;
- closeToast()
- })
- .catch(() => {
- closeToast()
- });
- };
- // 鏄剧ず鍔犺浇鎻愮ず
- const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
- };
+ // 鎺ユ敹鐖剁粍浠朵紶閫掔殑 approveType 鍙傛暟
+ const props = defineProps({
+ approveType: {
+ type: Number,
+ default: 0,
+ },
+ });
- // 鍏抽棴鎻愮ず
- const closeToast = () => {
- uni.hideLoading();
- };
+ // 鏄犲皠 approveType 鍒板搴旂殑椤甸潰鏍囬
+ const getPageTitle = type => {
+ const titleMap = {
+ 1: "鍏嚭绠$悊",
+ 2: "璇峰亣绠$悊",
+ 3: "鍑哄樊绠$悊",
+ 4: "鎶ラ攢绠$悊",
+ 5: "閲囪喘绠$悊",
+ 6: "鎶ヤ环绠$悊",
+ 7: "鍙戣揣瀹℃壒",
+ 8: "鍗遍櫓浣滀笟瀹℃壒",
+ };
+ return titleMap[type] || "瀹℃壒绠$悊";
+ };
- // 鏄剧ず绛涢�夐�夐」
- const showFilterOptions = () => {
- uni.showActionSheet({
- itemList: ["鎸夋棩鏈熺瓫閫�", "鎸夌姸鎬佺瓫閫�", "鎸夐噾棰濈瓫閫�"],
- success: (res) => {
- console.log("閫夋嫨浜嗙瓫閫夐�夐」:", res.tapIndex);
- },
- });
- };
- // 鏍煎紡鍖栧洖娆炬柟寮�
- const formatReceiptType = (params) => {
- if (params == 0) {
- return "寰呭鏍�";
- } else if (params == 1) {
- return "瀹℃牳涓�";
- } else if (params == 2) {
- return "瀹℃牳瀹屾垚";
- } else if (params == 4) {
- return "宸查噸鏂版彁浜�";
- } else {
- return '涓嶉�氳繃';
- }
- };
- // 鑾峰彇鏍囩鏍峰紡绫�
- const getTagClass = (type) => {
- if (type == 0) {
- return "warning";
- } else if (type == 1) {
- return "primary";
- } else if (type == 2) {
- return "success";
- } else if (type == 4) {
- return "primary";
- } else {
- return "error";
- }
- };
+ const pageTitle = getPageTitle(props.approveType);
- // 鐐瑰嚮鍒楄〃椤�
- const handleItemClick = (item) => {
- // 浣跨敤鏈湴瀛樺偍浼犻�掓暟鎹�
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item));
- uni.setStorageSync('operationType', 'edit');
- uni.setStorageSync('approveId', item.approveId);
- uni.navigateTo({
- url: "/pages/cooperativeOffice/collaborativeApproval/detail",
- });
- };
+ const userStore = useUserStore();
+ // 鏁版嵁
+ const ledgerList = ref([]);
+ const data = reactive({
+ searchForm: {
+ approveId: "",
+ },
+ });
+ const { searchForm } = toRefs(data);
- // 娣诲姞鏂拌褰�
- const handleAdd = () => {
- uni.setStorageSync('operationType', 'add');
- uni.navigateTo({
- url: "/pages/cooperativeOffice/collaborativeApproval/detail",
- });
- };
- // 鐐瑰嚮瀹℃牳
- const approve = (item) => {
- uni.setStorageSync('approveId', item.approveId);
- uni.navigateTo({
- url: "/pages/cooperativeOffice/collaborativeApproval/approve"
- })
- }
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ approveProcessListPage({
+ ...page,
+ approveType: props.approveType,
+ ...searchForm.value,
+ })
+ .then(res => {
+ ledgerList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
- onShow(() => {
- // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
- getList();
- });
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏄剧ず绛涢�夐�夐」
+ const showFilterOptions = () => {
+ uni.showActionSheet({
+ itemList: ["鎸夋棩鏈熺瓫閫�", "鎸夌姸鎬佺瓫閫�", "鎸夐噾棰濈瓫閫�"],
+ success: res => {
+ console.log("閫夋嫨浜嗙瓫閫夐�夐」:", res.tapIndex);
+ },
+ });
+ };
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭鏍�";
+ } else if (params == 1) {
+ return "瀹℃牳涓�";
+ } else if (params == 2) {
+ return "瀹℃牳瀹屾垚";
+ } else if (params == 4) {
+ return "宸查噸鏂版彁浜�";
+ } else {
+ return "涓嶉�氳繃";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "warning";
+ } else if (type == 1) {
+ return "primary";
+ } else if (type == 2) {
+ return "success";
+ } else if (type == 4) {
+ return "primary";
+ } else {
+ return "error";
+ }
+ };
+
+ // 鐐瑰嚮鍒楄〃椤�
+ const handleItemClick = item => {
+ // 浣跨敤鏈湴瀛樺偍浼犻�掓暟鎹�
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+ uni.setStorageSync("operationType", "edit");
+ uni.setStorageSync("approveId", item.approveId);
+ uni.setStorageSync("approveType", props.approveType);
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/detail",
+ });
+ };
+
+ // 娣诲姞鏂拌褰�
+ const handleAdd = () => {
+ uni.setStorageSync("operationType", "add");
+ uni.setStorageSync("approveType", props.approveType);
+ uni.navigateTo({
+ url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${props.approveType}`,
+ });
+ };
+ // 鐐瑰嚮瀹℃牳
+ const approve = item => {
+ uni.setStorageSync("approveId", item.approveId);
+ uni.setStorageSync("approveType", props.approveType);
+ uni.navigateTo({
+ url:
+ "/pages/cooperativeOffice/collaborativeApproval/approve?approveType=" +
+ props.approveType,
+ });
+ };
+
+ onLoad(options => {
+ // 瑙f瀽approveId
+ if (options.approveId) {
+ searchForm.value.approveId = options.approveId;
+ }
+ });
+
+ onShow(() => {
+ // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+ getList();
+ });
</script>
<style scoped lang="scss">
- @import "../../../styles/sales-common.scss";
+ @import "../../../styles/sales-common.scss";
- .u-divider {
- margin: 0 !important;
- }
+ .u-divider {
+ margin: 0 !important;
+ }
- // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
- .document-icon {
- background: #ed8d05;
- }
+ // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .document-icon {
+ background: #ed8d05;
+ }
- // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
- .fab-button {
- background: #ed8d05;
- }
+ // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .fab-button {
+ background: #ed8d05;
+ }
- // 鐗规湁鏍峰紡
- .detail-row-user {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
-
- .detail-row-approveReason {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 8px;
- }
+ // 鐗规湁鏍峰紡
+ .detail-row-user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
- .detail-value.highlightBlue {
- color: #2979ff;
- font-weight: 500;
- }
+ .detail-row-approveReason {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ }
- .detail-value.highlightYellow {
- color: #ed8d05;
- font-weight: 500;
- }
+ .detail-value.highlightBlue {
+ color: #2979ff;
+ font-weight: 500;
+ }
- .approver-value {
- display: flex;
- justify-content: flex-end;
- }
-
- .approver-chip {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- background: #f0f6ff;
- color: #2b7cff;
- border: 1px solid #e0efff;
- border-radius: 999px;
- padding: 4px 10px;
- max-width: 100%;
- }
-
- .approver-name {
- font-size: 12px;
- color: #2b7cff;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
+ .detail-value.highlightYellow {
+ color: #ed8d05;
+ font-weight: 500;
+ }
- .actions {
- display: flex;
- gap: 10px;
- align-items: center;
- justify-content: flex-end;
- }
+ .approver-value {
+ display: flex;
+ justify-content: flex-end;
+ }
- .action-btn {
- border-radius: 16px;
- height: 28px;
- line-height: 28px;
- padding: 0 12px;
- }
+ .approver-chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: #f0f6ff;
+ color: #2b7cff;
+ border: 1px solid #e0efff;
+ border-radius: 999px;
+ padding: 4px 10px;
+ max-width: 100%;
+ }
+ .approver-name {
+ font-size: 12px;
+ color: #2b7cff;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: flex-end;
+ }
+
+ .action-btn {
+ border-radius: 16px;
+ height: 28px;
+ line-height: 28px;
+ padding: 0 12px;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index1.vue b/src/pages/cooperativeOffice/collaborativeApproval/index1.vue
new file mode 100644
index 0000000..dc70530
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index1.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="1" />
+ </view>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+</script>
+
+<style scoped>
+.container {
+ width: 100%;
+ height: 100%;
+}
+</style>
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index2.vue b/src/pages/cooperativeOffice/collaborativeApproval/index2.vue
new file mode 100644
index 0000000..6da82b3
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index2.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="2" />
+ </view>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+</script>
+
+<style scoped>
+.container {
+ width: 100%;
+ height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index3.vue b/src/pages/cooperativeOffice/collaborativeApproval/index3.vue
new file mode 100644
index 0000000..8a4b231
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index3.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="3" />
+ </view>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+</script>
+
+<style scoped>
+.container {
+ width: 100%;
+ height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index4.vue b/src/pages/cooperativeOffice/collaborativeApproval/index4.vue
new file mode 100644
index 0000000..fc75609
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index4.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="4" />
+ </view>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+</script>
+
+<style scoped>
+.container {
+ width: 100%;
+ height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index5.vue b/src/pages/cooperativeOffice/collaborativeApproval/index5.vue
new file mode 100644
index 0000000..5338263
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index5.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="5" />
+ </view>
+</template>
+
+<script setup>
+ import ApprovalProcessIndex from "./index.vue";
+</script>
+
+<style scoped>
+ .container {
+ width: 100%;
+ height: 100%;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index6.vue b/src/pages/cooperativeOffice/collaborativeApproval/index6.vue
new file mode 100644
index 0000000..06ce277
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index6.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="6" />
+ </view>
+</template>
+
+<script setup>
+ import ApprovalProcessIndex from "./index.vue";
+</script>
+
+<style scoped>
+ .container {
+ width: 100%;
+ height: 100%;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index7.vue b/src/pages/cooperativeOffice/collaborativeApproval/index7.vue
new file mode 100644
index 0000000..bf1c18b
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index7.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="7" />
+ </view>
+</template>
+
+<script setup>
+ import ApprovalProcessIndex from "./index.vue";
+</script>
+
+<style scoped>
+ .container {
+ width: 100%;
+ height: 100%;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index8.vue b/src/pages/cooperativeOffice/collaborativeApproval/index8.vue
new file mode 100644
index 0000000..f0db8a1
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index8.vue
@@ -0,0 +1,17 @@
+<template>
+ <view class="container">
+ <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+ <ApprovalProcessIndex :approveType="8" />
+ </view>
+</template>
+
+<script setup>
+ import ApprovalProcessIndex from "./index.vue";
+</script>
+
+<style scoped>
+ .container {
+ width: 100%;
+ height: 100%;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/customerManage/detail.vue b/src/pages/cooperativeOffice/customerManage/detail.vue
new file mode 100644
index 0000000..e08e729
--- /dev/null
+++ b/src/pages/cooperativeOffice/customerManage/detail.vue
@@ -0,0 +1,493 @@
+<template>
+ <view class="customer-detail-page">
+ <!-- 椤甸潰澶撮儴 -->
+ <PageHeader title="瀹㈡埛璇︽儏"
+ @back="goBack" />
+ <!-- 璇︽儏鍐呭 -->
+ <view class="detail-content">
+ <!-- 瀹㈡埛鍩烘湰淇℃伅 -->
+ <view class="section">
+ <view class="section-title">瀹㈡埛鍩烘湰淇℃伅</view>
+ <view class="info-list">
+ <view class="info-item">
+ <text class="info-label">瀹㈡埛鍚嶇О</text>
+ <text class="info-value">{{ detailData.customerName || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">瀹㈡埛绫诲瀷</text>
+ <text class="info-value">{{ detailData.customerType || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">绾崇◣浜鸿瘑鍒彿</text>
+ <text class="info-value">{{ detailData.taxpayerIdentificationNumber || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍏徃鍦板潃</text>
+ <text class="info-value">{{ detailData.companyAddress || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍏徃鐢佃瘽</text>
+ <text class="info-value">{{ detailData.companyPhone || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鑱旂郴浜�</text>
+ <text class="info-value">{{ detailData.contactPerson || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鑱旂郴鐢佃瘽</text>
+ <text class="info-value">{{ detailData.contactPhone || '-' }}</text>
+ </view>
+ </view>
+ </view>
+ <!-- 璺熻繘璁板綍 -->
+ <view class="section">
+ <view class="section-title">
+ <view class="title-left">
+ <up-icon name="clock-fill"
+ size="16"
+ color="#409eff" />
+ <text>璺熻繘璁板綍</text>
+ </view>
+ <text class="record-count"
+ v-if="detailData.followUpList && detailData.followUpList.length > 0">
+ 鍏眥{ detailData.followUpList.length }}鏉�
+ </text>
+ </view>
+ <view v-if="detailData.followUpList && detailData.followUpList.length > 0"
+ class="follow-up-list">
+ <view v-for="(item, index) in detailData.followUpList"
+ :key="index"
+ class="follow-up-item">
+ <!-- 鏃堕棿杞村乏渚х嚎鏉� -->
+ <view class="timeline-left">
+ <view class="timeline-dot"></view>
+ <view class="timeline-line"
+ v-if="index !== detailData.followUpList.length - 1"></view>
+ </view>
+ <!-- 鍐呭鍖哄煙 -->
+ <view class="follow-up-content-wrapper">
+ <view class="follow-up-header">
+ <view class="follow-up-info">
+ <view class="user-info">
+ <up-icon name="account-fill"
+ size="14"
+ color="#909399" />
+ <text class="follow-up-name">{{ item.followerUserName || '-' }}</text>
+ </view>
+ <view class="time-info">
+ <up-icon name="clock"
+ size="12"
+ color="#c0c4cc" />
+ <text class="follow-up-time">{{ formatDateTime(item.followUpTime) }}</text>
+ </view>
+ </view>
+ <view class="follow-up-tags">
+ <up-tag type="primary"
+ size="mini">{{ item.followUpMethod || '-' }}</up-tag>
+ <up-tag :type="getFollowUpLevelType(item.followUpLevel)"
+ size="mini">{{ item.followUpLevel || '-' }}</up-tag>
+ </view>
+ </view>
+ <view class="follow-up-content">
+ <view class="content-label">
+ <up-icon name="edit-pen-fill"
+ size="12"
+ color="#c0c4cc" />
+ <text>璺熻繘鍐呭</text>
+ </view>
+ <view class="content-box">
+ <text class="content-text">{{ item.content || '-' }}</text>
+ </view>
+ </view>
+ <!-- <view v-if="item.fileList && item.fileList.length > 0"
+ class="follow-up-files">
+ <view class="files-header">
+ <up-icon name="folder-open"
+ size="12"
+ color="#c0c4cc" />
+ <text class="files-label">闄勪欢 ({{ item.fileList.length }})</text>
+ </view>
+ <view class="files-list">
+ <view v-for="(file, fileIndex) in item.fileList"
+ :key="fileIndex"
+ class="file-item">
+ <up-icon name="attach"
+ size="14"
+ color="#409eff" />
+ <text class="file-name">{{ file.name || '闄勪欢' + (fileIndex + 1) }}</text>
+ </view>
+ </view>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <up-empty mode="data"
+ text="鏆傛棤璺熻繘璁板綍" />
+ </view>
+ </view>
+ <!-- 閾惰淇℃伅 -->
+ <view class="section">
+ <view class="section-title">閾惰淇℃伅</view>
+ <view class="info-list">
+ <view class="info-item">
+ <text class="info-label">鍩烘湰閾惰璐︽埛</text>
+ <text class="info-value">{{ detailData.basicBankAccount || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">寮�鎴疯</text>
+ <text class="info-value">{{ detailData.bankAccount || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">閾惰璐﹀彿</text>
+ <text class="info-value">{{ detailData.bankCode || '-' }}</text>
+ </view>
+ </view>
+ </view>
+ <!-- 缁存姢淇℃伅 -->
+ <view class="section">
+ <view class="section-title">缁存姢淇℃伅</view>
+ <view class="info-list">
+ <view class="info-item">
+ <text class="info-label">缁存姢浜�</text>
+ <text class="info-value">{{ detailData.maintainer || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">缁存姢鏃堕棿</text>
+ <text class="info-value">{{ formatDateTime(detailData.maintenanceTime) }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getCustomer } from "@/api/cooperativeOffice/clientVisit";
+ import { onLoad, onShow } from "@dcloudio/uni-app";
+ import dayjs from "dayjs";
+
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageId = () => {
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1];
+ const options = currentPage.options || {};
+ return options.id || "";
+ };
+
+ // 璇︽儏鏁版嵁
+ const detailData = ref({});
+
+ // 鏍煎紡鍖栨棩鏈熸椂闂�
+ const formatDateTime = dateStr => {
+ if (!dateStr) return "-";
+ return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss");
+ };
+
+ // 鑾峰彇璺熻繘绾у埆鏍囩绫诲瀷
+ const getFollowUpLevelType = level => {
+ switch (level) {
+ case "闈炲父鐔熸倝":
+ return "success";
+ case "鐔熸倝":
+ return "primary";
+ case "涓�鑸�":
+ return "warning";
+ case "涓嶇啛鎮�":
+ return "error";
+ default:
+ return "info";
+ }
+ };
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const customerId = ref("");
+ // customerId
+ onLoad(options => {
+ // 瑙f瀽customerId
+ if (options.customerId) {
+ customerId.value = options.customerId;
+ getDetail();
+ }
+ });
+
+ // 鑾峰彇璇︽儏鏁版嵁
+ const getDetail = async () => {
+ if (!customerId.value) {
+ uni.showToast({
+ title: "鍙傛暟閿欒",
+ icon: "none",
+ });
+ return;
+ }
+
+ try {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ });
+
+ const res = await getCustomer(customerId.value);
+
+ if (res.code === 200) {
+ detailData.value = res.data;
+ } else {
+ uni.showToast({
+ title: res.msg || "鑾峰彇璇︽儏澶辫触",
+ icon: "none",
+ });
+ }
+ } catch (error) {
+ console.error("鍔犺浇璇︽儏鏁版嵁澶辫触:", error);
+ uni.showToast({
+ title: "缃戠粶閿欒",
+ icon: "none",
+ });
+ } finally {
+ uni.hideLoading();
+ }
+ };
+
+ onMounted(() => {});
+</script>
+
+<style scoped lang="scss">
+ .customer-detail-page {
+ min-height: 100vh;
+ background-color: #f5f5f5;
+ }
+
+ .detail-content {
+ padding: 16px;
+ }
+
+ .section {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
+
+ .section-title {
+ padding: 16px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .info-list {
+ padding: 8px 0;
+ }
+
+ .info-item {
+ display: flex;
+ padding: 12px 16px;
+ border-bottom: 1px solid #f8f8f8;
+ }
+
+ .info-item:last-child {
+ border-bottom: none;
+ }
+
+ .info-label {
+ width: 120px;
+ font-size: 14px;
+ color: #606266;
+ }
+
+ .info-value {
+ flex: 1;
+ font-size: 14px;
+ color: #303133;
+ text-align: right;
+ }
+
+ .section-title {
+ padding: 16px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ border-bottom: 1px solid #f0f0f0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .title-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .record-count {
+ font-size: 12px;
+ color: #909399;
+ font-weight: normal;
+ background: #f5f7fa;
+ padding: 2px 8px;
+ border-radius: 10px;
+ }
+
+ .follow-up-list {
+ padding: 0;
+ }
+
+ .follow-up-item {
+ display: flex;
+ padding: 16px;
+ position: relative;
+ }
+
+ .timeline-left {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-right: 12px;
+ padding-top: 4px;
+ }
+
+ .timeline-dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background: #409eff;
+ border: 2px solid #e6f2ff;
+ flex-shrink: 0;
+ }
+
+ .timeline-line {
+ width: 2px;
+ flex: 1;
+ background: #e4e7ed;
+ margin-top: 4px;
+ min-height: 40px;
+ }
+
+ .follow-up-content-wrapper {
+ flex: 1;
+ background: #f8f9fa;
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ .follow-up-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 12px;
+ }
+
+ .follow-up-info {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ }
+
+ .user-info {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .time-info {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ }
+
+ .follow-up-name {
+ font-size: 14px;
+ font-weight: 600;
+ color: #303133;
+ }
+
+ .follow-up-time {
+ font-size: 12px;
+ color: #909399;
+ }
+
+ .follow-up-tags {
+ display: flex;
+ gap: 6px;
+ flex-wrap: wrap;
+ }
+
+ .follow-up-content {
+ margin-bottom: 12px;
+ }
+
+ .content-label {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ color: #909399;
+ margin-bottom: 8px;
+ }
+
+ .content-box {
+ background: #ffffff;
+ border-radius: 6px;
+ padding: 10px 12px;
+ border-left: 3px solid #409eff;
+ }
+
+ .content-text {
+ font-size: 14px;
+ color: #303133;
+ line-height: 1.6;
+ word-break: break-all;
+ word-wrap: break-word;
+ }
+
+ .follow-up-files {
+ margin-top: 12px;
+ padding-top: 12px;
+ border-top: 1px dashed #e4e7ed;
+ }
+
+ .files-header {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ margin-bottom: 8px;
+ }
+
+ .files-label {
+ font-size: 12px;
+ color: #909399;
+ }
+
+ .files-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ }
+
+ .file-item {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 10px;
+ background: #ffffff;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+ }
+
+ .file-name {
+ font-size: 12px;
+ color: #606266;
+ }
+
+ .no-data {
+ padding: 40px 20px;
+ text-align: center;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/noticeManagement/index.vue b/src/pages/cooperativeOffice/noticeManagement/index.vue
new file mode 100644
index 0000000..d63a9b4
--- /dev/null
+++ b/src/pages/cooperativeOffice/noticeManagement/index.vue
@@ -0,0 +1,809 @@
+<template>
+ <view class="notice-page">
+ <PageHeader title="閫氱煡鍏憡"
+ @back="goBack" />
+ <!-- 鎼滅储琛ㄥ崟 -->
+ <!-- <view class="search_form">
+ <up-button type="primary" size="small" @click="openForm('add')">鏂板鍏憡</up-button>
+ <up-button type="error" size="small" plain @click="handleDeleteBatch" :disabled="!selectedIds.length">
+ 鍒犻櫎
+ </up-button>
+ </view> -->
+ <!-- 閫氱煡鍏憡鏉� -->
+ <view class="notice-board">
+ <!-- 缁熶竴閫氱煡鍖哄煙 -->
+ <view class="notice-section"
+ v-if="totalNoticeCount > 0">
+ <view class="section-header">
+ <h3>锟� 閫氱煡鍏憡</h3>
+ <text class="section-count">{{ totalNoticeCount }}鏉�</text>
+ </view>
+ <view class="notice-cards">
+ <!-- 鏀惧亣閫氱煡 -->
+ <view v-for="notice in holidayNotices"
+ :key="'holiday-' + notice.id"
+ class="notice-card holiday-card"
+ :class="{ 'urgent': notice.priority === '3' }">
+ <view class="card-header">
+ <view class="card-title">
+ <view class="holiday-icon">
+ <up-icon name="calendar"
+ size="18"
+ color="#67c23a" />
+ </view>
+ <text>{{ notice.title }}</text>
+ </view>
+ <!-- <view class="card-actions">-->
+ <!-- <up-button-->
+ <!-- text-->
+ <!-- type="primary"-->
+ <!-- size="mini"-->
+ <!-- @click="handleEdit(notice)"-->
+ <!-- :disabled="isNoticeExpired(notice)"-->
+ <!-- >-->
+ <!-- 缂栬緫-->
+ <!-- </up-button>-->
+ <!-- <up-button-->
+ <!-- text-->
+ <!-- type="error"-->
+ <!-- size="mini"-->
+ <!-- @click="handleDelete(notice.id)"-->
+ <!-- >-->
+ <!-- 鍒犻櫎-->
+ <!-- </up-button>-->
+ <!-- </view>-->
+ </view>
+ <view class="card-content">
+ <text>{{ notice.content }}</text>
+ </view>
+ <view class="card-footer">
+ <view class="card-meta">
+ <text class="type"
+ :class="'type-' + notice.type">
+ {{ notice.type }}
+ </text>
+ <text class="priority"
+ :class="'priority-' + notice.priority">
+ {{ getPriorityText(notice.priority) }}
+ </text>
+ <text class="status"
+ :class="'status-' + getNoticeStatus(notice)">
+ {{ getStatusText(getNoticeStatus(notice)) }}
+ </text>
+ </view>
+ <view class="card-info">
+ <text class="creator">{{ notice.createUserName }}</text>
+ <text class="expiration"
+ v-if="notice.expirationDate">鎴鏃ユ湡锛歿{ notice.expirationDate }}</text>
+ </view>
+ </view>
+ <view class="card-remark"
+ v-if="notice.remark">
+ <up-icon name="info-circle"
+ size="16"
+ color="#409eff" />
+ <text>{{ notice.remark }}</text>
+ </view>
+ </view>
+ <!-- 璁惧缁翠慨閫氱煡 -->
+ <view v-for="notice in maintenanceNotices"
+ :key="'maintenance-' + notice.id"
+ class="notice-card maintenance-card"
+ :class="{ 'urgent': notice.priority === '3' }">
+ <view class="card-header">
+ <view class="card-title">
+ <view class="maintenance-icon">
+ <up-icon name="wrench"
+ size="18"
+ color="#e6a23c" />
+ </view>
+ <text>{{ notice.title }}</text>
+ </view>
+ <view class="card-actions">
+ <!-- <up-button text
+ type="primary"
+ size="mini"
+ @click="handleEdit(notice)"
+ :disabled="isNoticeExpired(notice)">
+ 缂栬緫
+ </up-button>
+ <up-button text
+ type="error"
+ size="mini"
+ @click="handleDelete(notice.id)">
+ 鍒犻櫎
+ </up-button> -->
+ </view>
+ </view>
+ <view class="card-content">
+ <text>{{ notice.content }}</text>
+ </view>
+ <view class="card-footer">
+ <view class="card-meta">
+ <text class="priority"
+ :class="'priority-' + notice.priority">
+ {{ getPriorityText(notice.priority) }}
+ </text>
+ <text class="status"
+ :class="'status-' + getNoticeStatus(notice)">
+ {{ getStatusText(getNoticeStatus(notice)) }}
+ </text>
+ </view>
+ <view class="card-info">
+ <text class="creator">{{ notice.createUserName }}</text>
+ <text class="expiration"
+ v-if="notice.expirationDate">鎴鏃ユ湡锛歿{ notice.expirationDate }}</text>
+ </view>
+ </view>
+ <view class="card-remark"
+ v-if="notice.remark">
+ <up-icon name="info-circle"
+ size="16"
+ color="#409eff" />
+ <text>{{ notice.remark }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <!-- 绌虹姸鎬� -->
+ <view class="empty-state"
+ v-if="holidayNotices.length === 0 && maintenanceNotices.length === 0">
+ <text>鏆傛棤閫氱煡鍏憡</text>
+ </view>
+ </view>
+ <!-- 鏂板/缂栬緫寮圭獥 -->
+ <up-popup v-model:show="dialogVisible"
+ mode="bottom"
+ :round="18"
+ :safeAreaInsetBottom="true"
+ @close="resetForm">
+ <view class="dialog-container">
+ <view class="dialog-header">
+ <text class="dialog-title">{{ dialogTitle }}</text>
+ </view>
+ <view class="dialog-body">
+ <up-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ labelWidth="80">
+ <up-form-item label="鍏憡鏍囬"
+ prop="title">
+ <up-input v-model="form.title"
+ placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" />
+ </up-form-item>
+ <up-form-item label="鍏憡绫诲瀷"
+ prop="type">
+ <up-input v-model="form.type"
+ placeholder="璇疯緭鍏ュ叕鍛婄被鍨�" />
+ </up-form-item>
+ <up-form-item label="鐘舵��">
+ <up-radio-group v-model="form.status">
+ <up-radio :name="0">鑽夌</up-radio>
+ <up-radio :name="1">姝e紡鍙戝竷</up-radio>
+ </up-radio-group>
+ </up-form-item>
+ <up-form-item label="浼樺厛绾�"
+ prop="priority">
+ <up-select v-model="form.priority"
+ :options="priorityOptions"
+ placeholder="璇烽�夋嫨浼樺厛绾�" />
+ </up-form-item>
+ <up-form-item label="杩囨湡鏃堕棿"
+ prop="expirationDate">
+ <up-datetime-picker v-model="form.expirationDate"
+ mode="date"
+ @confirm="onExpireConfirm">
+ <up-input :value="form.expirationDate"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ readonly />
+ </up-datetime-picker>
+ </up-form-item>
+ <up-form-item label="鍏憡鍐呭"
+ prop="content">
+ <up-textarea v-model="form.content"
+ placeholder="璇疯緭鍏ュ叕鍛婂唴瀹�"
+ :maxlength="500"
+ count />
+ </up-form-item>
+ <up-form-item label="澶囨敞">
+ <up-textarea v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+ :maxlength="200"
+ count />
+ </up-form-item>
+ </up-form>
+ </view>
+ <view class="dialog-footer">
+ <up-button text="鍙栨秷"
+ type="info"
+ plain
+ @click="dialogVisible = false"
+ :customStyle="{ marginRight: '10px', flex: 1 }" />
+ <up-button text="纭畾"
+ type="primary"
+ @click="submitForm"
+ :customStyle="{ flex: 1 }" />
+ </view>
+ </view>
+ </up-popup>
+ </view>
+</template>
+
+<script setup>
+ import { onMounted, ref, reactive, toRefs } from "vue";
+ import { onReachBottom } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import {
+ addNotice,
+ delNotice,
+ getCount,
+ listNotice,
+ updateNotice,
+ } from "@/api/collaborativeApproval/noticeManagement.js";
+
+ 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 priorityOptions = [
+ { label: "鏅��", value: 1 },
+ { label: "閲嶈", value: 2 },
+ { label: "绱ф��", value: 3 },
+ ];
+
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ const onExpireConfirm = e => {
+ if (!e) return;
+ // uview-plus datetime-picker confirm 浜嬩欢杩斿洖鐨� value
+ const value = e.value || e;
+ form.value.expirationDate = value;
+ };
+
+ 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)) {
+ uni.showToast({
+ title: "宸茶繃鏈熺殑鍏憡涓嶅彲缂栬緫",
+ icon: "none",
+ });
+ return;
+ }
+ dialogTitle.value = "缂栬緫鍏憡";
+ form.value = { ...row };
+ dialogVisible.value = true;
+ };
+
+ const handleDelete = id => {
+ if (!id) return;
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "纭鍒犻櫎杩欐潯鍏憡鍚楋紵",
+ success: res => {
+ if (res.confirm) {
+ delNotice(id).then(() => {
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ resetTable();
+ });
+ }
+ },
+ });
+ };
+
+ // 棰勭暀鎵归噺鍒犻櫎锛堢洰鍓嶆湭瀹炵幇閫変腑閫昏緫锛屼粎鍗犱綅锛�
+ const handleDeleteBatch = () => {
+ if (!selectedIds.value.length) return;
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "纭鍒犻櫎閫変腑鐨勫叕鍛婂悧锛�",
+ success: res => {
+ if (res.confirm) {
+ // 鏍规嵁selectedIds鎵ц鎵归噺鍒犻櫎閫昏緫锛堝彲鎸夐渶鎵╁睍锛�
+ }
+ },
+ });
+ };
+
+ const submitForm = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ if (form.value.id) {
+ // 缂栬緫妯″紡
+ updateNotice(form.value).then(res => {
+ uni.showToast({
+ title: "淇敼鎴愬姛",
+ icon: "success",
+ });
+ resetTable();
+ });
+ } else {
+ // 鏂板妯″紡
+ addNotice(form.value).then(res => {
+ uni.showToast({
+ title: "鏂板鎴愬姛",
+ icon: "success",
+ });
+ resetTable();
+ });
+ }
+ dialogVisible.value = false;
+ }
+ });
+ };
+
+ const totalNoticeCount = ref(0);
+ const fetchCount = () => {
+ getCount().then(res => {
+ totalNoticeCount.value = res.data.reduce(
+ (total, item) => total + item.count,
+ 0
+ );
+ });
+ };
+
+ 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 isLoadingMore = ref(false);
+
+ const fetchHolidayNotices = (append = false) => {
+ listNotice({ ...holidayNoticePage.value }).then(res => {
+ const records = res?.data?.records || [];
+ holidayNoticePage.value.total = res?.data?.total || 0;
+ if (append && holidayNotices.value.length) {
+ holidayNotices.value = [...holidayNotices.value, ...records];
+ } else {
+ holidayNotices.value = records;
+ }
+ });
+ };
+
+ const fetchMaintenanceNotices = (append = false) => {
+ listNotice({ ...holidayNoticePage.value, type: 2 }).then(res => {
+ const records = res?.data?.records || [];
+ maintenanceNoticePage.value.total = res?.data?.total || 0;
+ if (append && maintenanceNotices.value.length) {
+ maintenanceNotices.value = [...maintenanceNotices.value, ...records];
+ } else {
+ maintenanceNotices.value = records;
+ }
+ });
+ };
+
+ const handleCurrentChange = val => {
+ holidayNoticePage.value.size = val.limit;
+ holidayNoticePage.value.current = val.page;
+ maintenanceNoticePage.value.size = val.limit;
+ maintenanceNoticePage.value.current = val.page;
+ fetchHolidayNotices();
+ 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();
+ });
+
+ // 涓婂垝鍔犺浇鏇村
+ onReachBottom(() => {
+ if (isLoadingMore.value) return;
+ isLoadingMore.value = true;
+
+ holidayNoticePage.value.current += 1;
+ maintenanceNoticePage.value.current += 1;
+
+ Promise.all([
+ new Promise(resolve => {
+ fetchHolidayNotices(true);
+ resolve();
+ }),
+ new Promise(resolve => {
+ fetchMaintenanceNotices(true);
+ resolve();
+ }),
+ ]).finally(() => {
+ isLoadingMore.value = false;
+ });
+ });
+</script>
+
+<style scoped>
+ .notice-page {
+ min-height: 100vh;
+ background: #f5f7fa;
+ padding-bottom: 16px;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .search_form {
+ background: #ffffff;
+ padding: 12px 16px;
+ margin: 8px 12px 12px;
+ border-radius: 10px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ }
+
+ .search_title {
+ font-weight: 500;
+ color: #333;
+ margin-right: 8px;
+ }
+
+ .ml10 {
+ margin-left: 10px;
+ }
+
+ .notice-board {
+ padding: 0 12px 16px;
+ }
+
+ .notice-section {
+ margin-bottom: 16px;
+ }
+
+ .section-header {
+ display: flex;
+ align-items: center;
+ margin: 4px 4px 12px;
+ }
+
+ .section-header h3 {
+ margin: 0;
+ color: #303133;
+ font-size: 16px;
+ font-weight: 600;
+ }
+
+ .section-count {
+ margin-left: 10px;
+ background: #409eff;
+ color: white;
+ padding: 2px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ }
+
+ .notice-cards {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ .notice-card {
+ background: white;
+ border-radius: 12px;
+ padding: 14px 14px 10px;
+ box-shadow: 0 4px 10px rgba(15, 23, 42, 0.06);
+ 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: 10px;
+ }
+
+ .card-title {
+ display: flex;
+ align-items: center;
+ font-size: 15px;
+ 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: 10px;
+ }
+
+ .card-content text {
+ color: #606266;
+ line-height: 1.6;
+ font-size: 13px;
+ }
+
+ .card-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 10px;
+ }
+
+ .card-meta {
+ display: flex;
+ gap: 8px;
+ }
+
+ .type,
+ .priority,
+ .status {
+ padding: 2px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ }
+
+ .type-1 {
+ background: #f0f9ff;
+ color: #0369a1;
+ }
+
+ .type-2 {
+ background: #fef3c7;
+ color: #d97706;
+ }
+
+ .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: 48px 16px;
+ color: #999;
+ font-size: 13px;
+ }
+
+ .dialog-footer {
+ text-align: right;
+ }
+
+ /* 绉诲姩绔脊绐楁牱寮� */
+ .dialog-container {
+ background: #ffffff;
+ border-radius: 18px 18px 0 0;
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .dialog-header {
+ padding: 16px 20px 8px 20px;
+ }
+
+ .dialog-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ }
+
+ .dialog-body {
+ flex: 1;
+ padding: 0 16px 12px 16px;
+ overflow-y: auto;
+ }
+
+ .dialog-footer {
+ display: flex;
+ padding: 12px 16px 16px 16px;
+ border-top: 1px solid #f0f0f0;
+ }
+
+ /* 鍝嶅簲寮忚璁� */
+ @media (max-width: 768px) {
+ .search_form {
+ flex-direction: column;
+ gap: 15px;
+ align-items: flex-start;
+ }
+
+ .search_form > div {
+ width: 100%;
+ display: flex;
+ gap: 10px;
+ }
+ }
+</style>
diff --git a/src/pages/equipmentManagement/inspection/detail.vue b/src/pages/equipmentManagement/inspection/detail.vue
index 4b62205..dc32840 100644
--- a/src/pages/equipmentManagement/inspection/detail.vue
+++ b/src/pages/equipmentManagement/inspection/detail.vue
@@ -1,20 +1,25 @@
<template>
<view class="inspection-detail">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="璁惧宸℃璇︽儏" @back="goBack" />
-
+ <PageHeader title="璁惧宸℃璇︽儏"
+ @back="goBack" />
<!-- 璁惧淇℃伅鍗$墖 -->
<view class="device-card">
<view class="device-header">
<view class="device-icon">
- <up-icon name="settings" size="24" color="#1890ff"></up-icon>
+ <up-icon name="settings"
+ size="24"
+ color="#1890ff"></up-icon>
</view>
<view class="device-info">
<text class="device-name">{{ deviceInfo.deviceName }}</text>
<text class="device-code">{{ deviceInfo.deviceCode }}</text>
</view>
- <view class="qr-scan" @click="scanDeviceQR">
- <up-icon name="scan" size="20" color="#1890ff"></up-icon>
+ <view class="qr-scan"
+ @click="scanDeviceQR">
+ <up-icon name="scan"
+ size="20"
+ color="#1890ff"></up-icon>
<text class="scan-text">鎵爜</text>
</view>
</view>
@@ -33,134 +38,131 @@
</view>
</view>
</view>
-
<!-- 宸℃椤圭洰娓呭崟 -->
<view class="inspection-items">
<view class="section-title">
- <up-icon name="list" size="18" color="#333"></up-icon>
+ <up-icon name="list"
+ size="18"
+ color="#333"></up-icon>
<text class="title-text">宸℃椤圭洰娓呭崟</text>
<text class="progress-text">({{ completedItems }}/{{ totalItems }})</text>
</view>
-
<view class="items-list">
- <view
- v-for="(item, index) in inspectionItems"
- :key="index"
- class="inspection-item"
- :class="{ 'completed': item.completed, 'abnormal': item.isAbnormal }"
- >
- <view class="item-header" @click="toggleItem(index)">
+ <view v-for="(item, index) in inspectionItems"
+ :key="index"
+ class="inspection-item"
+ :class="{ 'completed': item.completed, 'abnormal': item.isAbnormal }">
+ <view class="item-header"
+ @click="toggleItem(index)">
<view class="item-left">
- <view class="checkbox" :class="{ 'checked': item.completed }">
- <up-icon v-if="item.completed" name="checkmark" size="14" color="#ffffff"></up-icon>
+ <view class="checkbox"
+ :class="{ 'checked': item.completed }">
+ <up-icon v-if="item.completed"
+ name="checkmark"
+ size="14"
+ color="#ffffff"></up-icon>
</view>
<text class="item-name">{{ item.name }}</text>
</view>
<view class="item-status">
- <u-tag v-if="item.isAbnormal" type="error" size="mini">寮傚父</u-tag>
- <u-tag v-else-if="item.completed" type="success" size="mini">姝e父</u-tag>
- <u-tag v-else type="info" size="mini">寰呮</u-tag>
+ <u-tag v-if="item.isAbnormal"
+ type="error"
+ size="mini">寮傚父</u-tag>
+ <u-tag v-else-if="item.completed"
+ type="success"
+ size="mini">姝e父</u-tag>
+ <u-tag v-else
+ type="info"
+ size="mini">寰呮</u-tag>
</view>
</view>
-
<!-- 灞曞紑鐨勮鎯呭唴瀹� -->
- <view v-if="item.expanded" class="item-content">
+ <view v-if="item.expanded"
+ class="item-content">
<view class="item-description">
<text class="desc-text">{{ item.description }}</text>
</view>
-
<!-- 宸℃缁撴灉閫夋嫨 -->
<view class="result-section">
<text class="section-label">宸℃缁撴灉锛�</text>
<view class="result-options">
- <u-radio-group v-model="item.result" @change="onResultChange(index, $event)">
- <u-radio
- v-for="option in resultOptions"
- :key="option.value"
- :label="option.value"
- :name="option.label"
- size="small"
- >
+ <u-radio-group v-model="item.result"
+ @change="onResultChange(index, $event)">
+ <u-radio v-for="option in resultOptions"
+ :key="option.value"
+ :label="option.value"
+ :name="option.label"
+ size="small">
{{ option.label }}
</u-radio>
</u-radio-group>
</view>
</view>
-
<!-- 寮傚父鎯呭喌鎻忚堪 -->
- <view v-if="item.result === 'abnormal'" class="abnormal-section">
+ <view v-if="item.result === 'abnormal'"
+ class="abnormal-section">
<text class="section-label">寮傚父鎻忚堪锛�</text>
- <up-textarea
- v-model="item.abnormalDesc"
- placeholder="璇疯缁嗘弿杩板紓甯告儏鍐�"
- :maxlength="200"
- count
- height="80"
- ></up-textarea>
+ <up-textarea v-model="item.abnormalDesc"
+ placeholder="璇疯缁嗘弿杩板紓甯告儏鍐�"
+ :maxlength="200"
+ count
+ height="80"></up-textarea>
</view>
-
<!-- 鍥剧墖涓婁紶 -->
<view class="upload-section">
<text class="section-label">鐜板満鐓х墖锛�</text>
- <up-upload
- :fileList="item.images"
- @afterRead="(event) => afterRead(event, index, 'images')"
- @delete="(event) => deleteFile(event, index, 'images')"
- name="images"
- multiple
- :maxCount="5"
- :previewImage="true"
- >
+ <up-upload :fileList="item.images"
+ @afterRead="(event) => afterRead(event, index, 'images')"
+ @delete="(event) => deleteFile(event, index, 'images')"
+ name="images"
+ multiple
+ :maxCount="5"
+ :previewImage="true">
<view class="upload-btn">
- <up-icon name="camera" size="20" color="#999"></up-icon>
+ <up-icon name="camera"
+ size="20"
+ color="#999"></up-icon>
<text class="upload-text">娣诲姞鐓х墖</text>
</view>
</up-upload>
</view>
-
<!-- 瑙嗛涓婁紶 -->
<view class="upload-section">
<text class="section-label">鐜板満瑙嗛锛�</text>
- <up-upload
- :fileList="item.videos"
- @afterRead="(event) => afterRead(event, index, 'videos')"
- @delete="(event) => deleteFile(event, index, 'videos')"
- name="videos"
- :maxCount="2"
- accept="video"
- >
+ <up-upload :fileList="item.videos"
+ @afterRead="(event) => afterRead(event, index, 'videos')"
+ @delete="(event) => deleteFile(event, index, 'videos')"
+ name="videos"
+ :maxCount="2"
+ accept="video">
<view class="upload-btn">
- <up-icon name="play-circle" size="20" color="#999"></up-icon>
+ <up-icon name="play-circle"
+ size="20"
+ color="#999"></up-icon>
<text class="upload-text">娣诲姞瑙嗛</text>
</view>
</up-upload>
</view>
-
<!-- 澶囨敞 -->
<view class="remark-section">
<text class="section-label">澶囨敞锛�</text>
- <up-textarea
- v-model="item.remark"
- placeholder="璇疯緭鍏ュ娉ㄤ俊鎭紙鍙�夛級"
- :maxlength="100"
- count
- height="60"
- ></up-textarea>
+ <up-textarea v-model="item.remark"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭紙鍙�夛級"
+ :maxlength="100"
+ count
+ height="60"></up-textarea>
</view>
</view>
</view>
</view>
</view>
-
<!-- 搴曢儴鎿嶄綔鎸夐挳 -->
<view class="bottom-actions">
- <u-button
- type="primary"
- size="large"
- :disabled="!canSubmit"
- @click="submitInspection"
- :loading="submitting"
- >
+ <u-button type="primary"
+ size="large"
+ :disabled="!canSubmit"
+ @click="submitInspection"
+ :loading="submitting">
{{ allCompleted ? '鎻愪氦宸℃璁板綍' : `缁х画宸℃ (${completedItems}/${totalItems})` }}
</u-button>
</view>
@@ -168,638 +170,646 @@
</template>
<script setup>
-import { ref, computed, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { submitInspectionRecord } from '@/api/equipmentManagement/inspection'
-import dayjs from 'dayjs'
+ import { ref, computed, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { submitInspectionRecord } from "@/api/equipmentManagement/inspection";
+ import dayjs from "dayjs";
-// 璁惧淇℃伅
-const deviceInfo = ref({})
+ // 璁惧淇℃伅
+ const deviceInfo = ref({});
-// 宸℃椤圭洰鍒楄〃
-const inspectionItems = ref([])
+ // 宸℃椤圭洰鍒楄〃
+ const inspectionItems = ref([]);
-// 鎻愪氦鐘舵��
-const submitting = ref(false)
+ // 鎻愪氦鐘舵��
+ const submitting = ref(false);
-// 宸℃缁撴灉閫夐」
-const resultOptions = [
- { label: '姝e父', value: 'normal' },
- { label: '寮傚父', value: 'abnormal' }
-]
+ // 宸℃缁撴灉閫夐」
+ const resultOptions = [
+ { label: "姝e父", value: "normal" },
+ { label: "寮傚父", value: "abnormal" },
+ ];
-// 鏄剧ず鎻愮ず淇℃伅
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏄剧ず鎻愮ず淇℃伅
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-// 璁$畻灞炴��
-const totalItems = computed(() => inspectionItems.value.length)
-const completedItems = computed(() => inspectionItems.value.filter(item => item.completed).length)
-const allCompleted = computed(() => completedItems.value === totalItems.value && totalItems.value > 0)
-const canSubmit = computed(() => completedItems.value > 0)
+ // 璁$畻灞炴��
+ const totalItems = computed(() => inspectionItems.value.length);
+ const completedItems = computed(
+ () => inspectionItems.value.filter(item => item.completed).length
+ );
+ const allCompleted = computed(
+ () => completedItems.value === totalItems.value && totalItems.value > 0
+ );
+ const canSubmit = computed(() => completedItems.value > 0);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- if (completedItems.value > 0) {
- uni.showModal({
- title: '鎻愮ず',
- content: '褰撳墠鏈夋湭淇濆瓨鐨勫贰妫�璁板綍锛岀‘瀹氳绂诲紑鍚楋紵',
- success: (res) => {
- if (res.confirm) {
- uni.navigateBack()
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ if (completedItems.value > 0) {
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "褰撳墠鏈夋湭淇濆瓨鐨勫贰妫�璁板綍锛岀‘瀹氳绂诲紑鍚楋紵",
+ success: res => {
+ if (res.confirm) {
+ uni.navigateBack();
+ }
+ },
+ });
+ } else {
+ uni.navigateBack();
+ }
+ };
+
+ // 鎵弿璁惧浜岀淮鐮�
+ const scanDeviceQR = () => {
+ uni.scanCode({
+ success: res => {
+ console.log("鎵爜缁撴灉锛�", res);
+ if (res.result.includes(deviceInfo.value.deviceCode)) {
+ showToast("璁惧纭鎴愬姛");
+ // 璁板綍鎵爜鏃堕棿
+ deviceInfo.value.scanTime = new Date().toISOString();
+ } else {
+ showToast("璁惧浜岀淮鐮佷笉鍖归厤");
}
+ },
+ fail: err => {
+ console.log("鎵爜澶辫触锛�", err);
+ showToast("鎵爜澶辫触");
+ },
+ });
+ };
+
+ // 鍒囨崲宸℃椤圭洰
+ const toggleItem = index => {
+ inspectionItems.value[index].expanded =
+ !inspectionItems.value[index].expanded;
+ };
+
+ // 宸℃缁撴灉鏀瑰彉
+ const onResultChange = (index, value) => {
+ const item = inspectionItems.value[index];
+ item.result = value;
+ item.completed = true;
+ item.isAbnormal = value === "abnormal";
+
+ // 濡傛灉閫夋嫨姝e父锛屾竻绌哄紓甯告弿杩�
+ if (value === "normal") {
+ item.abnormalDesc = "";
+ }
+ };
+
+ // 鏂囦欢涓婁紶鍚庡鐞�
+ const afterRead = async (event, index, type) => {
+ const { file } = event;
+ const item = inspectionItems.value[index];
+
+ // 妯℃嫙涓婁紶杩囩▼
+ uni.showLoading({ title: "涓婁紶涓�..." });
+
+ try {
+ // 杩欓噷搴旇璋冪敤瀹為檯鐨勪笂浼燗PI
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ // 娣诲姞鍒板搴旂殑鏂囦欢鍒楄〃
+ if (type === "images") {
+ item.images = item.images || [];
+ item.images.push({
+ url: file.url,
+ name: file.name,
+ size: file.size,
+ });
+ } else if (type === "videos") {
+ item.videos = item.videos || [];
+ item.videos.push({
+ url: file.url,
+ name: file.name,
+ size: file.size,
+ });
}
- })
- } else {
- uni.navigateBack()
- }
-}
-// 鎵弿璁惧浜岀淮鐮�
-const scanDeviceQR = () => {
- uni.scanCode({
- success: (res) => {
- console.log('鎵爜缁撴灉锛�', res)
- if (res.result.includes(deviceInfo.value.deviceCode)) {
- showToast('璁惧纭鎴愬姛')
- // 璁板綍鎵爜鏃堕棿
- deviceInfo.value.scanTime = new Date().toISOString()
- } else {
- showToast('璁惧浜岀淮鐮佷笉鍖归厤')
+ uni.hideLoading();
+ showToast("涓婁紶鎴愬姛");
+ } catch (error) {
+ uni.hideLoading();
+ showToast("涓婁紶澶辫触");
+ }
+ };
+
+ // 鍒犻櫎鏂囦欢
+ const deleteFile = (event, index, type) => {
+ const item = inspectionItems.value[index];
+ if (type === "images") {
+ item.images.splice(event.index, 1);
+ } else if (type === "videos") {
+ item.videos.splice(event.index, 1);
+ }
+ };
+
+ // 鎻愪氦宸℃璁板綍
+ const submitInspection = async () => {
+ if (!canSubmit.value) {
+ showToast("璇疯嚦灏戝畬鎴愪竴椤瑰贰妫�");
+ return;
+ }
+
+ // 妫�鏌ュ紓甯搁」鐩槸鍚﹀~鍐欎簡鎻忚堪
+ const abnormalItems = inspectionItems.value.filter(item => item.isAbnormal);
+ for (const item of abnormalItems) {
+ if (!item.abnormalDesc || item.abnormalDesc.trim() === "") {
+ showToast(`璇峰~鍐�"${item.name}"鐨勫紓甯告弿杩癭);
+ return;
}
- },
- fail: (err) => {
- console.log('鎵爜澶辫触锛�', err)
- showToast('鎵爜澶辫触')
}
- })
-}
-// 鍒囨崲宸℃椤圭洰
-const toggleItem = (index) => {
- inspectionItems.value[index].expanded = !inspectionItems.value[index].expanded
-}
+ submitting.value = true;
-// 宸℃缁撴灉鏀瑰彉
-const onResultChange = (index, value) => {
- const item = inspectionItems.value[index]
- item.result = value
- item.completed = true
- item.isAbnormal = value === 'abnormal'
-
- // 濡傛灉閫夋嫨姝e父锛屾竻绌哄紓甯告弿杩�
- if (value === 'normal') {
- item.abnormalDesc = ''
- }
-}
+ try {
+ const recordData = {
+ deviceId: deviceInfo.value.id,
+ deviceCode: deviceInfo.value.deviceCode,
+ inspectionDate: dayjs().format("YYYY-MM-DD"),
+ inspector: deviceInfo.value.inspector,
+ scanTime: deviceInfo.value.scanTime,
+ items: inspectionItems.value.map(item => ({
+ name: item.name,
+ result: item.result,
+ completed: item.completed,
+ isAbnormal: item.isAbnormal,
+ abnormalDesc: item.abnormalDesc,
+ images: item.images || [],
+ videos: item.videos || [],
+ remark: item.remark,
+ })),
+ completedAt: new Date().toISOString(),
+ };
-// 鏂囦欢涓婁紶鍚庡鐞�
-const afterRead = async (event, index, type) => {
- const { file } = event
- const item = inspectionItems.value[index]
-
- // 妯℃嫙涓婁紶杩囩▼
- uni.showLoading({ title: '涓婁紶涓�...' })
-
- try {
- // 杩欓噷搴旇璋冪敤瀹為檯鐨勪笂浼燗PI
- await new Promise(resolve => setTimeout(resolve, 1000))
-
- // 娣诲姞鍒板搴旂殑鏂囦欢鍒楄〃
- if (type === 'images') {
- item.images = item.images || []
- item.images.push({
- url: file.url,
- name: file.name,
- size: file.size
- })
- } else if (type === 'videos') {
- item.videos = item.videos || []
- item.videos.push({
- url: file.url,
- name: file.name,
- size: file.size
- })
+ // 妯℃嫙API璋冪敤
+ await new Promise(resolve => setTimeout(resolve, 2000));
+
+ // 瀹為檯API璋冪敤
+ // await submitInspectionRecord(recordData)
+
+ showToast("宸℃璁板綍鎻愪氦鎴愬姛");
+
+ // 杩斿洖鍒楄〃椤甸潰
+ setTimeout(() => {
+ uni.navigateBack();
+ }, 1500);
+ } catch (error) {
+ showToast("鎻愪氦澶辫触锛岃閲嶈瘯");
+ } finally {
+ submitting.value = false;
}
-
- uni.hideLoading()
- showToast('涓婁紶鎴愬姛')
- } catch (error) {
- uni.hideLoading()
- showToast('涓婁紶澶辫触')
- }
-}
+ };
-// 鍒犻櫎鏂囦欢
-const deleteFile = (event, index, type) => {
- const item = inspectionItems.value[index]
- if (type === 'images') {
- item.images.splice(event.index, 1)
- } else if (type === 'videos') {
- item.videos.splice(event.index, 1)
- }
-}
-
-// 鎻愪氦宸℃璁板綍
-const submitInspection = async () => {
- if (!canSubmit.value) {
- showToast('璇疯嚦灏戝畬鎴愪竴椤瑰贰妫�')
- return
- }
-
- // 妫�鏌ュ紓甯搁」鐩槸鍚﹀~鍐欎簡鎻忚堪
- const abnormalItems = inspectionItems.value.filter(item => item.isAbnormal)
- for (const item of abnormalItems) {
- if (!item.abnormalDesc || item.abnormalDesc.trim() === '') {
- showToast(`璇峰~鍐�"${item.name}"鐨勫紓甯告弿杩癭)
- return
+ // 鍒濆鍖栨暟鎹�
+ const initData = () => {
+ // 浠庡瓨鍌ㄤ腑鑾峰彇褰撳墠宸℃淇℃伅
+ const currentInspection = uni.getStorageSync("currentInspection");
+ if (currentInspection) {
+ deviceInfo.value = currentInspection;
}
- }
-
- submitting.value = true
-
- try {
- const recordData = {
- deviceId: deviceInfo.value.id,
- deviceCode: deviceInfo.value.deviceCode,
- inspectionDate: dayjs().format('YYYY-MM-DD'),
- inspector: deviceInfo.value.inspector,
- scanTime: deviceInfo.value.scanTime,
- items: inspectionItems.value.map(item => ({
- name: item.name,
- result: item.result,
- completed: item.completed,
- isAbnormal: item.isAbnormal,
- abnormalDesc: item.abnormalDesc,
- images: item.images || [],
- videos: item.videos || [],
- remark: item.remark
- })),
- completedAt: new Date().toISOString()
- }
-
- // 妯℃嫙API璋冪敤
- await new Promise(resolve => setTimeout(resolve, 2000))
-
- // 瀹為檯API璋冪敤
- // await submitInspectionRecord(recordData)
-
- showToast('宸℃璁板綍鎻愪氦鎴愬姛')
-
- // 杩斿洖鍒楄〃椤甸潰
- setTimeout(() => {
- uni.navigateBack()
- }, 1500)
-
- } catch (error) {
- showToast('鎻愪氦澶辫触锛岃閲嶈瘯')
- } finally {
- submitting.value = false
- }
-}
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
- // 浠庡瓨鍌ㄤ腑鑾峰彇褰撳墠宸℃淇℃伅
- const currentInspection = uni.getStorageSync('currentInspection')
- if (currentInspection) {
- deviceInfo.value = currentInspection
- }
-
- // 妯℃嫙宸℃椤圭洰鏁版嵁
- inspectionItems.value = [
- {
- name: '璁惧澶栬妫�鏌�',
- description: '妫�鏌ヨ澶囧瑙傛槸鍚︽湁鎹熷潖銆侀攬铓�銆佸彉褰㈢瓑寮傚父鎯呭喌',
- completed: false,
- expanded: false,
- result: '',
- isAbnormal: false,
- abnormalDesc: '',
- images: [],
- videos: [],
- remark: ''
- },
- {
- name: '杩愯鐘舵�佹鏌�',
- description: '妫�鏌ヨ澶囪繍琛屾槸鍚︽甯革紝鏈夋棤寮傚父澹伴煶銆佹尟鍔ㄧ瓑',
- completed: false,
- expanded: false,
- result: '',
- isAbnormal: false,
- abnormalDesc: '',
- images: [],
- videos: [],
- remark: ''
- },
- {
- name: '瀹夊叏瑁呯疆妫�鏌�',
- description: '妫�鏌ュ悇绫诲畨鍏ㄨ缃槸鍚﹀畬濂斤紝瀹夊叏鏍囪瘑鏄惁娓呮櫚',
- completed: false,
- expanded: false,
- result: '',
- isAbnormal: false,
- abnormalDesc: '',
- images: [],
- videos: [],
- remark: ''
- },
- {
- name: '鐜鏉′欢妫�鏌�',
- description: '妫�鏌ヨ澶囧懆鍥寸幆澧冩槸鍚︾鍚堣姹傦紝閫氶銆佺収鏄庣瓑鏄惁姝e父',
- completed: false,
- expanded: false,
- result: '',
- isAbnormal: false,
- abnormalDesc: '',
- images: [],
- videos: [],
- remark: ''
- },
- {
- name: '浠〃璇绘暟璁板綍',
- description: '璁板綍鐩稿叧浠〃鐨勮鏁帮紝妫�鏌ユ槸鍚﹀湪姝e父鑼冨洿鍐�',
- completed: false,
- expanded: false,
- result: '',
- isAbnormal: false,
- abnormalDesc: '',
- images: [],
- videos: [],
- remark: ''
- }
- ]
-}
+ // 妯℃嫙宸℃椤圭洰鏁版嵁
+ inspectionItems.value = [
+ {
+ name: "璁惧澶栬妫�鏌�",
+ description: "妫�鏌ヨ澶囧瑙傛槸鍚︽湁鎹熷潖銆侀攬铓�銆佸彉褰㈢瓑寮傚父鎯呭喌",
+ completed: false,
+ expanded: false,
+ result: "",
+ isAbnormal: false,
+ abnormalDesc: "",
+ images: [],
+ videos: [],
+ remark: "",
+ },
+ {
+ name: "杩愯鐘舵�佹鏌�",
+ description: "妫�鏌ヨ澶囪繍琛屾槸鍚︽甯革紝鏈夋棤寮傚父澹伴煶銆佹尟鍔ㄧ瓑",
+ completed: false,
+ expanded: false,
+ result: "",
+ isAbnormal: false,
+ abnormalDesc: "",
+ images: [],
+ videos: [],
+ remark: "",
+ },
+ {
+ name: "瀹夊叏瑁呯疆妫�鏌�",
+ description: "妫�鏌ュ悇绫诲畨鍏ㄨ缃槸鍚﹀畬濂斤紝瀹夊叏鏍囪瘑鏄惁娓呮櫚",
+ completed: false,
+ expanded: false,
+ result: "",
+ isAbnormal: false,
+ abnormalDesc: "",
+ images: [],
+ videos: [],
+ remark: "",
+ },
+ {
+ name: "鐜鏉′欢妫�鏌�",
+ description: "妫�鏌ヨ澶囧懆鍥寸幆澧冩槸鍚︾鍚堣姹傦紝閫氶銆佺収鏄庣瓑鏄惁姝e父",
+ completed: false,
+ expanded: false,
+ result: "",
+ isAbnormal: false,
+ abnormalDesc: "",
+ images: [],
+ videos: [],
+ remark: "",
+ },
+ {
+ name: "浠〃璇绘暟璁板綍",
+ description: "璁板綍鐩稿叧浠〃鐨勮鏁帮紝妫�鏌ユ槸鍚﹀湪姝e父鑼冨洿鍐�",
+ completed: false,
+ expanded: false,
+ result: "",
+ isAbnormal: false,
+ abnormalDesc: "",
+ images: [],
+ videos: [],
+ remark: "",
+ },
+ ];
+ };
-onMounted(() => {
- initData()
-})
+ onMounted(() => {
+ initData();
+ });
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂版暟鎹�
-})
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂版暟鎹�
+ });
</script>
<style scoped lang="scss">
-.inspection-detail {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- min-height: 100vh;
- padding-bottom: 80px;
- position: relative;
-
- &::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 200px;
- background: linear-gradient(135deg, rgba(102, 126, 234, 0.8) 0%, rgba(118, 75, 162, 0.8) 100%);
- z-index: 0;
+ .inspection-detail {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ min-height: 100vh;
+ padding-bottom: 80px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 200px;
+ background: linear-gradient(
+ 135deg,
+ rgba(102, 126, 234, 0.8) 0%,
+ rgba(118, 75, 162, 0.8) 100%
+ );
+ z-index: 0;
+ }
}
-}
-.device-card {
- background: rgba(255, 255, 255, 0.95);
- backdrop-filter: blur(15px);
- margin: 10px 20px;
- border-radius: 20px;
- padding: 24px;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
- border: 1px solid rgba(255, 255, 255, 0.2);
- position: relative;
- z-index: 1;
- transition: all 0.3s ease;
-
- &:hover {
- transform: translateY(-2px);
- box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
- }
-}
+ .device-card {
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(15px);
+ margin: 10px 20px;
+ border-radius: 20px;
+ padding: 24px;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ position: relative;
+ z-index: 1;
+ transition: all 0.3s ease;
-.device-header {
- display: flex;
- align-items: center;
- gap: 16px;
- margin-bottom: 20px;
-}
-
-.device-icon {
- width: 56px;
- height: 56px;
- background: linear-gradient(135deg, #667eea, #764ba2);
- border-radius: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
- transition: all 0.3s ease;
-
- &:hover {
- transform: scale(1.05);
- }
-}
-
-.device-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.device-name {
- font-size: 20px;
- font-weight: 600;
- color: #1a1a1a;
- line-height: 1.3;
-}
-
-.device-code {
- font-size: 13px;
- color: #8c8c8c;
- font-weight: 500;
- padding: 4px 12px;
- background: rgba(140, 140, 140, 0.1);
- border-radius: 12px;
- display: inline-block;
- width: fit-content;
-}
-
-.qr-scan {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 6px;
- padding: 12px 16px;
- background: linear-gradient(135deg, #52c41a, #389e0d);
- border-radius: 12px;
- box-shadow: 0 4px 15px rgba(82, 196, 26, 0.3);
- transition: all 0.3s ease;
-
- &:hover {
- transform: scale(1.05);
- box-shadow: 0 6px 20px rgba(82, 196, 26, 0.4);
- }
-
- &:active {
- transform: scale(0.98);
- }
-}
-
-.scan-text {
- font-size: 13px;
- color: #ffffff;
- font-weight: 600;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.device-details {
- display: flex;
- flex-direction: column;
- gap: 12px;
- background: rgba(248, 250, 252, 0.8);
- border-radius: 16px;
- padding: 16px;
- backdrop-filter: blur(10px);
-}
-
-.detail-item {
- display: flex;
- align-items: center;
- font-size: 14px;
- padding: 8px 0;
- transition: all 0.2s ease;
-
- &:hover {
- background: rgba(255, 255, 255, 0.5);
- margin: 0 -8px;
- padding-left: 8px;
- padding-right: 8px;
- border-radius: 8px;
- }
-}
-
-.label {
- color: #595959;
- min-width: 80px;
- font-weight: 500;
-}
-
-.value {
- color: #262626;
- flex: 1;
- font-weight: 500;
-}
-
-.inspection-items {
- margin: 10px 20px;
- position: relative;
- z-index: 1;
-}
-
-.section-title {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 20px 0;
- border-bottom: 1px solid rgba(255, 255, 255, 0.2);
- background: rgba(255, 255, 255, 0.95);
- backdrop-filter: blur(15px);
- border-radius: 16px;
- padding: 20px;
- margin-bottom: 16px;
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
-}
-
-.title-text {
- font-size: 18px;
- font-weight: 600;
- color: #1a1a1a;
- flex: 1;
-}
-
-.progress-text {
- font-size: 15px;
- font-weight: 600;
- background: linear-gradient(135deg, #667eea, #764ba2);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
-}
-
-.items-list {
- background: rgba(255, 255, 255, 0.95);
- backdrop-filter: blur(15px);
- border-radius: 20px;
- overflow: hidden;
- margin-top: 0;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
- border: 1px solid rgba(255, 255, 255, 0.2);
-}
-
-.inspection-item {
- border-bottom: 1px solid rgba(0, 0, 0, 0.06);
- transition: all 0.3s ease;
-
- &:last-child {
- border-bottom: none;
- }
-
- &.completed {
- background: rgba(82, 196, 26, 0.05);
- border-left: 4px solid #52c41a;
- }
-
- &.abnormal {
- background: rgba(255, 77, 79, 0.05);
- border-left: 4px solid #ff4d4f;
- }
-
- &:hover {
- background: rgba(102, 126, 234, 0.05);
- }
-}
-
-.item-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 15px;
- cursor: pointer;
-}
-
-.item-left {
- display: flex;
- align-items: center;
- gap: 12px;
- flex: 1;
-}
-
-.checkbox {
- width: 20px;
- height: 20px;
- border: 2px solid #d9d9d9;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.3s;
-
- &.checked {
- background: #52c41a;
- border-color: #52c41a;
- }
-}
-
-.item-name {
- font-size: 15px;
- color: #333;
- font-weight: 500;
-}
-
-.item-status {
- flex-shrink: 0;
-}
-
-.item-content {
- padding: 0 15px 20px;
- border-top: 1px solid #f5f5f5;
-}
-
-.item-description {
- padding: 15px 0;
-}
-
-.desc-text {
- font-size: 14px;
- color: #666;
- line-height: 1.5;
-}
-
-.result-section,
-.abnormal-section,
-.upload-section,
-.remark-section {
- margin-top: 15px;
-}
-
-.section-label {
- display: block;
- font-size: 14px;
- color: #333;
- margin-bottom: 8px;
- font-weight: 500;
-}
-
-.result-options {
- display: flex;
- gap: 20px;
-}
-
-.upload-btn {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 88px;
- height: 88px;
- border: 2px dashed rgba(102, 126, 234, 0.3);
- border-radius: 16px;
- background: rgba(102, 126, 234, 0.05);
- gap: 8px;
- transition: all 0.3s ease;
-
- &:hover {
- border-color: rgba(102, 126, 234, 0.5);
- background: rgba(102, 126, 234, 0.1);
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
- }
-
- &:active {
- transform: translateY(0);
- }
-}
-
-.upload-text {
- font-size: 13px;
- color: #667eea;
- font-weight: 500;
-}
-
-.bottom-actions {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- background: rgba(255, 255, 255, 0.95);
- backdrop-filter: blur(20px);
- padding: 20px;
- border-top: 1px solid rgba(255, 255, 255, 0.2);
- box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.1);
- z-index: 10;
-
- button {
- height: 48px;
- border-radius: 16px;
- font-weight: 600;
- font-size: 16px;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
-
&:hover {
transform: translateY(-2px);
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
-
+ }
+
+ .device-header {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ margin-bottom: 20px;
+ }
+
+ .device-icon {
+ width: 56px;
+ height: 56px;
+ background: linear-gradient(135deg, #667eea, #764ba2);
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: scale(1.05);
+ }
+ }
+
+ .device-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ }
+
+ .device-name {
+ font-size: 20px;
+ font-weight: 600;
+ color: #1a1a1a;
+ line-height: 1.3;
+ }
+
+ .device-code {
+ font-size: 13px;
+ color: #8c8c8c;
+ font-weight: 500;
+ padding: 4px 12px;
+ background: rgba(140, 140, 140, 0.1);
+ border-radius: 12px;
+ display: inline-block;
+ width: fit-content;
+ }
+
+ .qr-scan {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ padding: 12px 16px;
+ background: linear-gradient(135deg, #52c41a, #389e0d);
+ border-radius: 12px;
+ box-shadow: 0 4px 15px rgba(82, 196, 26, 0.3);
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: scale(1.05);
+ box-shadow: 0 6px 20px rgba(82, 196, 26, 0.4);
+ }
+
+ &:active {
+ transform: scale(0.98);
+ }
+ }
+
+ .scan-text {
+ font-size: 13px;
+ color: #ffffff;
+ font-weight: 600;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+ }
+
+ .device-details {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ background: rgba(248, 250, 252, 0.8);
+ border-radius: 16px;
+ padding: 16px;
+ backdrop-filter: blur(10px);
+ }
+
+ .detail-item {
+ display: flex;
+ align-items: center;
+ font-size: 14px;
+ padding: 8px 0;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: rgba(255, 255, 255, 0.5);
+ margin: 0 -8px;
+ padding-left: 8px;
+ padding-right: 8px;
+ border-radius: 8px;
+ }
+ }
+
+ .label {
+ color: #595959;
+ min-width: 80px;
+ font-weight: 500;
+ }
+
+ .value {
+ color: #262626;
+ flex: 1;
+ font-weight: 500;
+ }
+
+ .inspection-items {
+ margin: 10px 20px;
+ position: relative;
+ z-index: 1;
+ }
+
+ .section-title {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 20px 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(15px);
+ border-radius: 16px;
+ padding: 20px;
+ margin-bottom: 16px;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+ }
+
+ .title-text {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1a1a1a;
+ flex: 1;
+ }
+
+ .progress-text {
+ font-size: 15px;
+ font-weight: 600;
+ background: linear-gradient(135deg, #667eea, #764ba2);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ }
+
+ .items-list {
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(15px);
+ border-radius: 20px;
+ overflow: hidden;
+ margin-top: 0;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ }
+
+ .inspection-item {
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+ transition: all 0.3s ease;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &.completed {
+ background: rgba(82, 196, 26, 0.05);
+ border-left: 4px solid #52c41a;
+ }
+
+ &.abnormal {
+ background: rgba(255, 77, 79, 0.05);
+ border-left: 4px solid #ff4d4f;
+ }
+
+ &:hover {
+ background: rgba(102, 126, 234, 0.05);
+ }
+ }
+
+ .item-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 15px;
+ cursor: pointer;
+ }
+
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex: 1;
+ }
+
+ .checkbox {
+ width: 20px;
+ height: 20px;
+ border: 2px solid #d9d9d9;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s;
+
+ &.checked {
+ background: #52c41a;
+ border-color: #52c41a;
+ }
+ }
+
+ .item-name {
+ font-size: 15px;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .item-status {
+ flex-shrink: 0;
+ }
+
+ .item-content {
+ padding: 0 15px 20px;
+ border-top: 1px solid #f5f5f5;
+ }
+
+ .item-description {
+ padding: 15px 0;
+ }
+
+ .desc-text {
+ font-size: 14px;
+ color: #666;
+ line-height: 1.5;
+ }
+
+ .result-section,
+ .abnormal-section,
+ .upload-section,
+ .remark-section {
+ margin-top: 15px;
+ }
+
+ .section-label {
+ display: block;
+ font-size: 14px;
+ color: #333;
+ margin-bottom: 8px;
+ font-weight: 500;
+ }
+
+ .result-options {
+ display: flex;
+ gap: 20px;
+ }
+
+ .upload-btn {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 88px;
+ height: 88px;
+ border: 2px dashed rgba(102, 126, 234, 0.3);
+ border-radius: 16px;
+ background: rgba(102, 126, 234, 0.05);
+ gap: 8px;
+ transition: all 0.3s ease;
+
+ &:hover {
+ border-color: rgba(102, 126, 234, 0.5);
+ background: rgba(102, 126, 234, 0.1);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
+ }
+
&:active {
transform: translateY(0);
}
}
-}
+
+ .upload-text {
+ font-size: 13px;
+ color: #667eea;
+ font-weight: 500;
+ }
+
+ .bottom-actions {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(20px);
+ padding: 20px;
+ border-top: 1px solid rgba(255, 255, 255, 0.2);
+ box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.1);
+ z-index: 10;
+
+ button {
+ height: 48px;
+ border-radius: 16px;
+ font-weight: 600;
+ font-size: 16px;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+ }
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/inspection/index.vue b/src/pages/equipmentManagement/inspection/index.vue
index bb949fa..c8fd6b5 100644
--- a/src/pages/equipmentManagement/inspection/index.vue
+++ b/src/pages/equipmentManagement/inspection/index.vue
@@ -1,8 +1,8 @@
<template>
<view class="inspection-page">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="璁惧宸℃" @back="goBack" />
-
+ <PageHeader title="璁惧宸℃"
+ @back="goBack" />
<!-- 缁熻淇℃伅鍗$墖 -->
<view class="stats-cards">
<view class="stat-card">
@@ -18,15 +18,20 @@
<text class="stat-label">寰呭贰妫�</text>
</view>
</view>
-
<!-- 宸℃娓呭崟 -->
- <view class="inspection-list" v-if="inspectionList.length > 0">
- <view v-for="(item, index) in inspectionList" :key="index">
- <view class="inspection-item" @click="startInspection(item)">
+ <view class="inspection-list"
+ v-if="inspectionList.length > 0">
+ <view v-for="(item, index) in inspectionList"
+ :key="index">
+ <view class="inspection-item"
+ @click="startInspection(item)">
<view class="item-header">
<view class="item-left">
- <view class="device-icon" :class="getStatusClass(item.status)">
- <up-icon :name="getStatusIcon(item.status)" size="16" color="#ffffff"></up-icon>
+ <view class="device-icon"
+ :class="getStatusClass(item.status)">
+ <up-icon :name="getStatusIcon(item.status)"
+ size="16"
+ color="#ffffff"></up-icon>
</view>
<view class="device-info">
<text class="device-name">{{ item.deviceName }}</text>
@@ -34,14 +39,13 @@
</view>
</view>
<view class="status-tag">
- <u-tag :type="getTagType(item.status)" size="mini">
+ <u-tag :type="getTagType(item.status)"
+ size="mini">
{{ getStatusText(item.status) }}
</u-tag>
</view>
</view>
-
<up-divider></up-divider>
-
<view class="item-details">
<view class="detail-row">
<text class="detail-label">璁惧缂栧彿</text>
@@ -55,472 +59,485 @@
<text class="detail-label">璐熻矗浜�</text>
<text class="detail-value">{{ item.inspector || '-' }}</text>
</view>
- <view class="detail-row" v-if="item.status === 2">
+ <view class="detail-row"
+ v-if="item.status === 2">
<text class="detail-label">瀹屾垚鏃堕棿</text>
<text class="detail-value">{{ formatDateTime(item.completedTime) || '-' }}</text>
</view>
</view>
-
<!-- 鎿嶄綔鎸夐挳 -->
<view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.status === 2"
- @click.stop="startInspection(item)"
- >
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ :disabled="item.status === 2"
+ @click.stop="startInspection(item)">
{{ item.status === 0 ? '寮�濮嬪贰妫�' : item.status === 1 ? '缁х画宸℃' : '鏌ョ湅璇︽儏' }}
</u-button>
- <u-button
- type="success"
- size="small"
- class="action-btn"
- :disabled="item.status !== 1"
- @click.stop="scanQRCode(item)"
- >
+ <u-button type="success"
+ size="small"
+ class="action-btn"
+ :disabled="item.status !== 1"
+ @click.stop="scanQRCode(item)">
鎵爜鎵撳崱
</u-button>
</view>
</view>
</view>
</view>
-
- <view v-else class="no-data">
- <up-empty mode="data" text="鏆傛棤宸℃浠诲姟"></up-empty>
+ <view v-else
+ class="no-data">
+ <up-empty mode="data"
+ text="鏆傛棤宸℃浠诲姟"></up-empty>
</view>
</view>
</template>
<script setup>
-import { ref, computed, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-// import { getInspectionList } from '@/api/inspectionUpload/index'
-import dayjs from 'dayjs'
+ import { ref, computed, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ // import { getInspectionList } from '@/api/inspectionUpload/index'
+ import dayjs from "dayjs";
-// 閫変腑鐨勬棩鏈�
-const selectedDate = ref(Date.now())
+ // 閫変腑鐨勬棩鏈�
+ const selectedDate = ref(Date.now());
-// 宸℃娓呭崟鏁版嵁
-const inspectionList = ref([])
+ // 宸℃娓呭崟鏁版嵁
+ const inspectionList = ref([]);
-// 鏄剧ず鎻愮ず淇℃伅
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏄剧ず鎻愮ず淇℃伅
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-// 璁$畻缁熻鏁版嵁
-const totalCount = computed(() => inspectionList.value.length)
-const completedCount = computed(() => inspectionList.value.filter(item => item.status === 2).length)
-const pendingCount = computed(() => inspectionList.value.filter(item => item.status === 0).length)
+ // 璁$畻缁熻鏁版嵁
+ const totalCount = computed(() => inspectionList.value.length);
+ const completedCount = computed(
+ () => inspectionList.value.filter(item => item.status === 2).length
+ );
+ const pendingCount = computed(
+ () => inspectionList.value.filter(item => item.status === 0).length
+ );
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 鏃ユ湡鏍煎紡鍖栧櫒
-const dateFormatter = (type, value) => {
- if (type === 'year') {
- return `${value}骞碻
- }
- if (type === 'month') {
- return `${value}鏈坄
- }
- if (type === 'day') {
- return `${value}鏃
- }
- return value
-}
-
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (timestamp) => {
- return dayjs(timestamp).format('YYYY骞碝M鏈圖D鏃�')
-}
-
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateStr) => {
- if (!dateStr) return ''
- return dayjs(dateStr).format('MM-DD HH:mm')
-}
-
-// 鏃ユ湡鏀瑰彉浜嬩欢
-const onDateChange = (value) => {
- selectedDate.value = value.value
- getList()
-}
-
-// 鑾峰彇鐘舵�佹牱寮忕被
-const getStatusClass = (status) => {
- switch (status) {
- case 0: return 'status-pending'
- case 1: return 'status-progress'
- case 2: return 'status-completed'
- default: return 'status-pending'
- }
-}
-
-// 鑾峰彇鐘舵�佸浘鏍�
-const getStatusIcon = (status) => {
- switch (status) {
- case 0: return 'clock'
- case 1: return 'play-circle'
- case 2: return 'checkmark-circle'
- default: return 'clock'
- }
-}
-
-// 鑾峰彇鏍囩绫诲瀷
-const getTagType = (status) => {
- switch (status) {
- case 0: return 'warning'
- case 1: return 'primary'
- case 2: return 'success'
- default: return 'info'
- }
-}
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
- switch (status) {
- case 0: return '寰呭贰妫�'
- case 1: return '宸℃涓�'
- case 2: return '宸插畬鎴�'
- default: return '鏈煡'
- }
-}
-
-// 寮�濮嬪贰妫�
-const startInspection = (item) => {
- // 瀛樺偍褰撳墠宸℃椤圭洰淇℃伅
- uni.setStorageSync('currentInspection', item)
- uni.navigateTo({
- url: '/pages/equipmentManagement/inspection/detail'
- })
-}
-
-// 鎵爜鎵撳崱
-const scanQRCode = (item) => {
- uni.scanCode({
- success: (res) => {
- console.log('鎵爜缁撴灉锛�', res)
- // 楠岃瘉浜岀淮鐮佸唴瀹�
- if (res.result.includes(item.deviceCode)) {
- showToast('鎵撳崱鎴愬姛')
- // 鏇存柊鎵撳崱鐘舵��
- updateCheckInStatus(item.id)
- } else {
- showToast('浜岀淮鐮佷笉鍖归厤锛岃鎵弿姝g‘鐨勮澶囦簩缁寸爜')
- }
- },
- fail: (err) => {
- console.log('鎵爜澶辫触锛�', err)
- showToast('鎵爜澶辫触')
+ // 鏃ユ湡鏍煎紡鍖栧櫒
+ const dateFormatter = (type, value) => {
+ if (type === "year") {
+ return `${value}骞碻;
}
- })
-}
+ if (type === "month") {
+ return `${value}鏈坄;
+ }
+ if (type === "day") {
+ return `${value}鏃;
+ }
+ return value;
+ };
-// 鏇存柊鎵撳崱鐘舵��
-const updateCheckInStatus = (id) => {
- // 杩欓噷搴旇璋冪敤API鏇存柊鎵撳崱鐘舵��
- // 鏆傛椂妯℃嫙鏇存柊鏈湴鏁版嵁
- const item = inspectionList.value.find(item => item.id === id)
- if (item) {
- item.checkInTime = new Date().toISOString()
- }
-}
+ // 鏍煎紡鍖栨棩鏈�
+ const formatDate = timestamp => {
+ return dayjs(timestamp).format("YYYY骞碝M鏈圖D鏃�");
+ };
-// 鏌ヨ宸℃娓呭崟
-const getList = () => {
- uni.showLoading({
- title: '鍔犺浇涓�...',
- mask: true
- })
-
- const params = {
- date: dayjs(selectedDate.value).format('YYYY-MM-DD')
- }
-
- // 妯℃嫙鏁版嵁锛屽疄闄呭簲璇ヨ皟鐢ˋPI
- setTimeout(() => {
- inspectionList.value = [
- {
- id: 1,
- deviceName: '绌哄帇鏈篈01',
- deviceCode: 'KYJ-A01',
- location: '鐢熶骇杞﹂棿A鍖�',
- inspectionTime: '08:00-09:00',
- inspector: '寮犱笁',
- status: 0, // 0:寰呭贰妫� 1:宸℃涓� 2:宸插畬鎴�
- completedTime: null
+ // 鏍煎紡鍖栨棩鏈熸椂闂�
+ const formatDateTime = dateStr => {
+ if (!dateStr) return "";
+ return dayjs(dateStr).format("MM-DD HH:mm");
+ };
+
+ // 鏃ユ湡鏀瑰彉浜嬩欢
+ const onDateChange = value => {
+ selectedDate.value = value.value;
+ getList();
+ };
+
+ // 鑾峰彇鐘舵�佹牱寮忕被
+ const getStatusClass = status => {
+ switch (status) {
+ case 0:
+ return "status-pending";
+ case 1:
+ return "status-progress";
+ case 2:
+ return "status-completed";
+ default:
+ return "status-pending";
+ }
+ };
+
+ // 鑾峰彇鐘舵�佸浘鏍�
+ const getStatusIcon = status => {
+ switch (status) {
+ case 0:
+ return "clock";
+ case 1:
+ return "play-circle";
+ case 2:
+ return "checkmark-circle";
+ default:
+ return "clock";
+ }
+ };
+
+ // 鑾峰彇鏍囩绫诲瀷
+ const getTagType = status => {
+ switch (status) {
+ case 0:
+ return "warning";
+ case 1:
+ return "primary";
+ case 2:
+ return "success";
+ default:
+ return "info";
+ }
+ };
+
+ // 鑾峰彇鐘舵�佹枃鏈�
+ const getStatusText = status => {
+ switch (status) {
+ case 0:
+ return "寰呭贰妫�";
+ case 1:
+ return "宸℃涓�";
+ case 2:
+ return "宸插畬鎴�";
+ default:
+ return "鏈煡";
+ }
+ };
+
+ // 寮�濮嬪贰妫�
+ const startInspection = item => {
+ // 瀛樺偍褰撳墠宸℃椤圭洰淇℃伅
+ uni.setStorageSync("currentInspection", item);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/inspection/detail",
+ });
+ };
+
+ // 鎵爜鎵撳崱
+ const scanQRCode = item => {
+ uni.scanCode({
+ success: res => {
+ console.log("鎵爜缁撴灉锛�", res);
+ // 楠岃瘉浜岀淮鐮佸唴瀹�
+ if (res.result.includes(item.deviceCode)) {
+ showToast("鎵撳崱鎴愬姛");
+ // 鏇存柊鎵撳崱鐘舵��
+ updateCheckInStatus(item.id);
+ } else {
+ showToast("浜岀淮鐮佷笉鍖归厤锛岃鎵弿姝g‘鐨勮澶囦簩缁寸爜");
+ }
},
- {
- id: 2,
- deviceName: '鍐峰嵈濉擝02',
- deviceCode: 'LQT-B02',
- location: '鐢熶骇杞﹂棿B鍖�',
- inspectionTime: '09:00-10:00',
- inspector: '鏉庡洓',
- status: 1,
- completedTime: null
+ fail: err => {
+ console.log("鎵爜澶辫触锛�", err);
+ showToast("鎵爜澶辫触");
},
- {
- id: 3,
- deviceName: '鍙樺帇鍣–03',
- deviceCode: 'BYQ-C03',
- location: '閰嶇數鎴�',
- inspectionTime: '10:00-11:00',
- inspector: '鐜嬩簲',
- status: 2,
- completedTime: '2024-01-15T10:30:00'
- }
- ]
- uni.hideLoading()
- }, 1000)
-
- // 瀹為檯API璋冪敤
- // getInspectionList(params)
- // .then((res) => {
- // inspectionList.value = res.records || res.data?.records || []
- // uni.hideLoading()
- // })
- // .catch(() => {
- // uni.hideLoading()
- // showToast('鑾峰彇鏁版嵁澶辫触')
- // })
-}
+ });
+ };
-onMounted(() => {
- getList()
-})
+ // 鏇存柊鎵撳崱鐘舵��
+ const updateCheckInStatus = id => {
+ // 杩欓噷搴旇璋冪敤API鏇存柊鎵撳崱鐘舵��
+ // 鏆傛椂妯℃嫙鏇存柊鏈湴鏁版嵁
+ const item = inspectionList.value.find(item => item.id === id);
+ if (item) {
+ item.checkInTime = new Date().toISOString();
+ }
+ };
-onShow(() => {
- getList()
-})
+ // 鏌ヨ宸℃娓呭崟
+ const getList = () => {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ mask: true,
+ });
+
+ const params = {
+ date: dayjs(selectedDate.value).format("YYYY-MM-DD"),
+ };
+
+ // 妯℃嫙鏁版嵁锛屽疄闄呭簲璇ヨ皟鐢ˋPI
+ setTimeout(() => {
+ inspectionList.value = [
+ {
+ id: 1,
+ deviceName: "绌哄帇鏈篈01",
+ deviceCode: "KYJ-A01",
+ location: "鐢熶骇杞﹂棿A鍖�",
+ inspectionTime: "08:00-09:00",
+ inspector: "寮犱笁",
+ status: 0, // 0:寰呭贰妫� 1:宸℃涓� 2:宸插畬鎴�
+ completedTime: null,
+ },
+ {
+ id: 2,
+ deviceName: "鍐峰嵈濉擝02",
+ deviceCode: "LQT-B02",
+ location: "鐢熶骇杞﹂棿B鍖�",
+ inspectionTime: "09:00-10:00",
+ inspector: "鏉庡洓",
+ status: 1,
+ completedTime: null,
+ },
+ {
+ id: 3,
+ deviceName: "鍙樺帇鍣–03",
+ deviceCode: "BYQ-C03",
+ location: "閰嶇數鎴�",
+ inspectionTime: "10:00-11:00",
+ inspector: "鐜嬩簲",
+ status: 2,
+ completedTime: "2024-01-15T10:30:00",
+ },
+ ];
+ uni.hideLoading();
+ }, 1000);
+
+ // 瀹為檯API璋冪敤
+ // getInspectionList(params)
+ // .then((res) => {
+ // inspectionList.value = res.records || res.data?.records || []
+ // uni.hideLoading()
+ // })
+ // .catch(() => {
+ // uni.hideLoading()
+ // showToast('鑾峰彇鏁版嵁澶辫触')
+ // })
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-.inspection-page {
- background: #ffffff;
- min-height: 100vh;
- padding-bottom: 20px;
-}
-
-
-
-
-
-.stats-cards {
- display: flex;
- gap: 10px;
- padding: 0 15px;
- margin: 15px 0;
-}
-
-.stat-card {
- flex: 1;
- background: #ffffff;
- border-radius: 12px;
- padding: 15px 12px;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 6px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid #f0f0f0;
- transition: all 0.3s ease;
-
- &:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ .inspection-page {
+ background: #ffffff;
+ min-height: 100vh;
+ padding-bottom: 20px;
}
-
- .stat-number {
- font-size: 24px;
- font-weight: 700;
- color: #1890ff;
+
+ .stats-cards {
+ display: flex;
+ gap: 10px;
+ padding: 0 15px;
+ margin: 15px 0;
}
-
- .stat-label {
+
+ .stat-card {
+ flex: 1;
+ background: #ffffff;
+ border-radius: 12px;
+ padding: 15px 12px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border: 1px solid #f0f0f0;
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ }
+
+ .stat-number {
+ font-size: 24px;
+ font-weight: 700;
+ color: #1890ff;
+ }
+
+ .stat-label {
+ font-size: 13px;
+ color: #666;
+ font-weight: 500;
+ }
+ }
+
+ .inspection-list {
+ padding: 0 15px;
+ }
+
+ .inspection-item {
+ background: #ffffff;
+ border-radius: 12px;
+ padding: 15px;
+ margin-bottom: 12px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border: 1px solid #f0f0f0;
+ transition: all 0.3s ease;
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ }
+ }
+
+ .item-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 12px;
+ }
+
+ .item-left {
+ display: flex;
+ align-items: flex-start;
+ gap: 12px;
+ flex: 1;
+ }
+
+ .device-icon {
+ width: 48px;
+ height: 48px;
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+ transition: all 0.3s ease;
+
+ &.status-pending {
+ background: linear-gradient(135deg, #faad14, #fa8c16);
+ box-shadow: 0 4px 16px rgba(250, 173, 20, 0.3);
+ }
+
+ &.status-progress {
+ background: linear-gradient(135deg, #1890ff, #096dd9);
+ box-shadow: 0 4px 16px rgba(24, 144, 255, 0.3);
+ }
+
+ &.status-completed {
+ background: linear-gradient(135deg, #52c41a, #389e0d);
+ box-shadow: 0 4px 16px rgba(82, 196, 26, 0.3);
+ }
+
+ &:hover {
+ transform: scale(1.05);
+ }
+ }
+
+ .device-info {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ }
+
+ .device-name {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1a1a1a;
+ line-height: 1.3;
+ }
+
+ .device-location {
font-size: 13px;
- color: #666;
+ color: #8c8c8c;
+ font-weight: 500;
+ padding: 2px 8px;
+ background: rgba(140, 140, 140, 0.1);
+ border-radius: 12px;
+ display: inline-block;
+ width: fit-content;
+ }
+
+ .status-tag {
+ flex-shrink: 0;
+ transform: scale(1.1);
+ }
+
+ .item-details {
+ margin: 15px 0;
+ background: rgba(248, 250, 252, 0.8);
+ border-radius: 12px;
+ padding: 12px;
+ backdrop-filter: blur(10px);
+ }
+
+ .detail-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 10px 0;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+ transition: all 0.2s ease;
+
+ &:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+
+ &:hover {
+ background: rgba(255, 255, 255, 0.5);
+ margin: 0 -8px;
+ padding-left: 8px;
+ padding-right: 8px;
+ border-radius: 8px;
+ }
+ }
+
+ .detail-label {
+ font-size: 14px;
+ color: #595959;
+ min-width: 80px;
font-weight: 500;
}
-}
-.inspection-list {
- padding: 0 15px;
-}
-
-.inspection-item {
- background: #ffffff;
- border-radius: 12px;
- padding: 15px;
- margin-bottom: 12px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid #f0f0f0;
- transition: all 0.3s ease;
-
- &:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ .detail-value {
+ font-size: 14px;
+ color: #262626;
+ text-align: right;
+ flex: 1;
+ font-weight: 500;
}
-}
-.item-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 12px;
-}
-
-.item-left {
- display: flex;
- align-items: flex-start;
- gap: 12px;
- flex: 1;
-}
-
-.device-icon {
- width: 48px;
- height: 48px;
- border-radius: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
-
- &.status-pending {
- background: linear-gradient(135deg, #faad14, #fa8c16);
- box-shadow: 0 4px 16px rgba(250, 173, 20, 0.3);
+ .action-buttons {
+ display: flex;
+ gap: 10px;
+ margin-top: 15px;
+ padding-top: 15px;
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
}
-
- &.status-progress {
- background: linear-gradient(135deg, #1890ff, #096dd9);
- box-shadow: 0 4px 16px rgba(24, 144, 255, 0.3);
+
+ .action-btn {
+ flex: 1;
+ height: 44px;
+ border-radius: 12px;
+ font-weight: 600;
+ font-size: 14px;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
}
-
- &.status-completed {
- background: linear-gradient(135deg, #52c41a, #389e0d);
- box-shadow: 0 4px 16px rgba(82, 196, 26, 0.3);
+
+ .no-data {
+ padding: 80px 20px;
+ text-align: center;
}
-
- &:hover {
- transform: scale(1.05);
- }
-}
-
-.device-info {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.device-name {
- font-size: 18px;
- font-weight: 600;
- color: #1a1a1a;
- line-height: 1.3;
-}
-
-.device-location {
- font-size: 13px;
- color: #8c8c8c;
- font-weight: 500;
- padding: 2px 8px;
- background: rgba(140, 140, 140, 0.1);
- border-radius: 12px;
- display: inline-block;
- width: fit-content;
-}
-
-.status-tag {
- flex-shrink: 0;
- transform: scale(1.1);
-}
-
-.item-details {
- margin: 15px 0;
- background: rgba(248, 250, 252, 0.8);
- border-radius: 12px;
- padding: 12px;
- backdrop-filter: blur(10px);
-}
-
-.detail-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 10px 0;
- border-bottom: 1px solid rgba(0, 0, 0, 0.06);
- transition: all 0.2s ease;
-
- &:last-child {
- border-bottom: none;
- padding-bottom: 0;
- }
-
- &:hover {
- background: rgba(255, 255, 255, 0.5);
- margin: 0 -8px;
- padding-left: 8px;
- padding-right: 8px;
- border-radius: 8px;
- }
-}
-
-.detail-label {
- font-size: 14px;
- color: #595959;
- min-width: 80px;
- font-weight: 500;
-}
-
-.detail-value {
- font-size: 14px;
- color: #262626;
- text-align: right;
- flex: 1;
- font-weight: 500;
-}
-
-.action-buttons {
- display: flex;
- gap: 10px;
- margin-top: 15px;
- padding-top: 15px;
- border-top: 1px solid rgba(0, 0, 0, 0.06);
-}
-
-.action-btn {
- flex: 1;
- height: 44px;
- border-radius: 12px;
- font-weight: 600;
- font-size: 14px;
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-
- &:hover {
- transform: translateY(-2px);
- box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
- }
-
- &:active {
- transform: translateY(0);
- }
-}
-
-.no-data {
- padding: 80px 20px;
- text-align: center;
-}
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/repair/add.vue b/src/pages/equipmentManagement/repair/add.vue
index 0940052..71de940 100644
--- a/src/pages/equipmentManagement/repair/add.vue
+++ b/src/pages/equipmentManagement/repair/add.vue
@@ -1,435 +1,489 @@
<template>
- <view class="repair-add">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader :title="operationType === 'edit' ? '缂栬緫鎶ヤ慨' : '鏂板鎶ヤ慨'" @back="goBack" />
-
- <!-- 琛ㄥ崟鍐呭 -->
- <u-form @submit="sendForm" ref="formRef" :rules="formRules" :model="form" label-width="110">
- <!-- 鍩烘湰淇℃伅 -->
- <u-cell-group title="鍩烘湰淇℃伅">
- <u-form-item label="璁惧鍚嶇О" prop="deviceLedgerId" required border-bottom>
- <u-input
- v-model="deviceNameText"
- placeholder="璇烽�夋嫨璁惧鍚嶇О"
- @click="showDevicePicker"
- clearable
- readonly=""
- />
- <template #right>
- <u-icon name="scan" @click="startScan" class="scan-icon" />
- </template>
- </u-form-item>
- <u-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel" border-bottom>
- <u-input
- v-model="form.deviceModel"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- clearable
- />
- </u-form-item>
- <u-form-item label="鎶ヤ慨鏃ユ湡" prop="repairTime" required border-bottom>
- <u-input
- v-model="form.repairTime"
- placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
- readonly
- @click="showDatePicker"
- clearable
- />
- <template #right>
- <u-icon name="arrow-right" @click="showDatePicker"></u-icon>
- </template>
- </u-form-item>
- <u-form-item label="鎶ヤ慨浜�" prop="repairName" required border-bottom>
- <u-input
- v-model="form.repairName"
- placeholder="璇疯緭鍏ユ姤淇汉"
- clearable
- />
- </u-form-item>
- <u-form-item label="鏁呴殰鐜拌薄" prop="remark" required border-bottom>
- <u-textarea
- v-model="form.remark"
- rows="3"
- placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
- clearable
- count
- maxlength="200"
- />
- </u-form-item>
- </u-cell-group>
-
- <!-- 鎻愪氦鎸夐挳 -->
- <view class="footer-btns">
- <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
- <u-button class="save-btn" type="primary" @click="sendForm" :loading="loading">淇濆瓨</u-button>
- </view>
- </u-form>
-
- <!-- 璁惧閫夋嫨鍣� -->
- <up-action-sheet
- :show="showDevice"
- :actions="deviceActionList"
- title="閫夋嫨璁惧鍚嶇О"
- @select="onDeviceSelect"
- @close="showDevice = false"
- />
-
- <!-- 鏃ユ湡閫夋嫨鍣� -->
- <up-datetime-picker
- :show="showDate"
- v-model="pickerDateValue"
- @confirm="onDateConfirm"
- @cancel="showDate = false"
- mode="date"
- />
- </view>
+ <view class="repair-add">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader :title="operationType === 'edit' ? '缂栬緫鎶ヤ慨' : '鏂板鎶ヤ慨'"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍐呭 -->
+ <u-form @submit="sendForm"
+ ref="formRef"
+ :rules="formRules"
+ :model="form"
+ label-width="110">
+ <!-- 鍩烘湰淇℃伅 -->
+ <u-cell-group title="鍩烘湰淇℃伅">
+ <u-form-item label="璁惧鍚嶇О"
+ prop="deviceLedgerId"
+ required
+ border-bottom>
+ <u-input v-model="deviceNameText"
+ placeholder="璇烽�夋嫨璁惧鍚嶇О"
+ @click="showDevicePicker"
+ clearable
+ readonly="" />
+ <template #right>
+ <u-icon name="scan"
+ @click="startScan"
+ class="scan-icon" />
+ </template>
+ </u-form-item>
+ <u-form-item label="瑙勬牸鍨嬪彿"
+ prop="deviceModel"
+ border-bottom>
+ <u-input v-model="form.deviceModel"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ clearable />
+ </u-form-item>
+ <u-form-item label="鎶ヤ慨鏃ユ湡"
+ prop="repairTime"
+ required
+ border-bottom>
+ <u-input v-model="form.repairTime"
+ placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+ readonly
+ @click="showDatePicker"
+ clearable />
+ <template #right>
+ <u-icon name="arrow-right"
+ @click="showDatePicker"></u-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鎶ヤ慨鐘舵��"
+ prop="repairTime"
+ required
+ border-bottom>
+ <u-input v-model="repairStatusText"
+ placeholder="璇烽�夋嫨鎶ヤ慨鐘舵��"
+ readonly
+ @click="openRepairStatusPicker"
+ clearable />
+ <template #right>
+ <u-icon name="arrow-right"
+ @click="openRepairStatusPicker"></u-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鎶ヤ慨浜�"
+ prop="repairName"
+ required
+ border-bottom>
+ <u-input v-model="form.repairName"
+ placeholder="璇疯緭鍏ユ姤淇汉"
+ clearable />
+ </u-form-item>
+ <u-form-item label="鏁呴殰鐜拌薄"
+ prop="remark"
+ required
+ border-bottom>
+ <u-textarea v-model="form.remark"
+ rows="3"
+ placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+ clearable
+ count
+ maxlength="200" />
+ </u-form-item>
+ </u-cell-group>
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="save-btn"
+ type="primary"
+ @click="sendForm"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 璁惧閫夋嫨鍣� -->
+ <up-action-sheet :show="showDevice"
+ :actions="deviceActionList"
+ title="閫夋嫨璁惧鍚嶇О"
+ @select="onDeviceSelect"
+ @close="showDevice = false" />
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <up-datetime-picker :show="showDate"
+ v-model="pickerDateValue"
+ @confirm="onDateConfirm"
+ @cancel="showDate = false"
+ mode="date" />
+ </view>
</template>
<script setup>
-import { ref, computed, onMounted, onUnmounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import PageHeader from '@/components/PageHeader.vue';
-import { getDeviceLedger } from '@/api/equipmentManagement/ledger';
-import { addRepair, editRepair, getRepairById } from '@/api/equipmentManagement/repair';
-import dayjs from "dayjs";
-import { formatDateToYMD } from '@/utils/ruoyi';
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ import { ref, computed, onMounted, onUnmounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+ import {
+ addRepair,
+ editRepair,
+ getRepairById,
+ } from "@/api/equipmentManagement/repair";
+ import dayjs from "dayjs";
+ import { formatDateToYMD } from "@/utils/ruoyi";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-defineOptions({
- name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
+ defineOptions({
+ name: "璁惧鎶ヤ慨琛ㄥ崟",
+ });
-// 琛ㄥ崟寮曠敤
-const formRef = ref(null);
-const operationType = ref('add');
-const loading = ref(false);
-const showDevice = ref(false);
-const showDate = ref(false);
-const pickerDateValue = ref(Date.now());
+ // 琛ㄥ崟寮曠敤
+ const formRef = ref(null);
+ const operationType = ref("add");
+ const loading = ref(false);
+ const showDevice = ref(false);
+ const showDate = ref(false);
+ const pickerDateValue = ref(Date.now());
-// 璁惧閫夐」
-const deviceOptions = ref([]);
-const deviceNameText = ref('');
-const deviceActionList = computed(() => {
- return deviceOptions.value.map(item => ({
- name: item.deviceName,
- value: item.id
- }));
-});
+ // 璁惧閫夐」
+ const deviceOptions = ref([]);
+ const deviceNameText = ref("");
+ const deviceActionList = computed(() => {
+ return deviceOptions.value.map(item => ({
+ name: item.deviceName,
+ value: item.id,
+ }));
+ });
-// 鎵爜鐩稿叧鐘舵��
-const isScanning = ref(false);
-const scanTimer = ref(null);
+ // 鎵爜鐩稿叧鐘舵��
+ const isScanning = ref(false);
+ const scanTimer = ref(null);
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = {
- deviceLedgerId: [{ required: true, trigger: "change", message: "璇烽�夋嫨璁惧鍚嶇О" }],
- repairTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨鎶ヤ慨鏃ユ湡" }],
- repairName: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ姤淇汉" }],
- remark: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ晠闅滅幇璞�" }],
-};
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ const formRules = {
+ deviceLedgerId: [
+ { required: true, trigger: "change", message: "璇烽�夋嫨璁惧鍚嶇О" },
+ ],
+ repairTime: [
+ { required: true, trigger: "change", message: "璇烽�夋嫨鎶ヤ慨鏃ユ湡" },
+ ],
+ repairName: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ姤淇汉" }],
+ remark: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ晠闅滅幇璞�" }],
+ };
-// 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
-const form = ref({
- deviceLedgerId: undefined, // 璁惧ID
- deviceModel: undefined, // 瑙勬牸鍨嬪彿
- repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡
- repairName: undefined, // 鎶ヤ慨浜�
- remark: undefined, // 鏁呴殰鐜拌薄
-});
+ // 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
+ const form = ref({
+ deviceLedgerId: undefined, // 璁惧ID
+ deviceModel: undefined, // 瑙勬牸鍨嬪彿
+ repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡
+ repairName: undefined, // 鎶ヤ慨浜�
+ remark: undefined, // 鏁呴殰鐜拌薄
+ });
-// 鍔犺浇璁惧鍒楄〃
-const loadDeviceName = async () => {
- try {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data || [];
- } catch (e) {
- showToast('鑾峰彇璁惧鍒楄〃澶辫触');
- }
-};
+ // 鎶ヤ慨鐘舵�侀�夐」
+ const repairStatusOptions = ref([
+ { name: "寰呯淮淇�", value: "0" },
+ { name: "瀹岀粨", value: "1" },
+ { name: "澶辫触", value: "2" },
+ ]);
+ const repairStatusText = ref("");
-// 璁剧疆璁惧瑙勬牸鍨嬪彿
-const setDeviceModel = (id) => {
- const option = deviceOptions.value.find((item) => item.id === id);
- if (option) {
- form.value.deviceModel = option.deviceModel;
- deviceNameText.value = option.deviceName;
- }
-};
+ // 鎵撳紑鎶ヤ慨鐘舵�侀�夋嫨鍣�
+ const openRepairStatusPicker = () => {
+ uni.showActionSheet({
+ itemList: repairStatusOptions.value.map(item => item.name),
+ success: res => {
+ form.value.status = repairStatusOptions.value[res.tapIndex].value;
+ repairStatusText.value = repairStatusOptions.value[res.tapIndex].name;
+ },
+ });
+ };
-// 鍔犺浇琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
-const loadForm = async (id) => {
- if (id) {
- operationType.value = 'edit';
- try {
- const { code, data } = await getRepairById(id);
- if (code == 200) {
- form.value.deviceLedgerId = data.deviceLedgerId;
- form.value.deviceModel = data.deviceModel;
- form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD");
- form.value.repairName = data.repairName;
- form.value.remark = data.remark;
- // 璁剧疆璁惧鍚嶇О鏄剧ず
- const device = deviceOptions.value.find(item => item.id === data.deviceLedgerId);
- if (device) {
- deviceNameText.value = device.deviceName;
- }
- }
- } catch (e) {
- showToast('鑾峰彇璇︽儏澶辫触');
- }
- } else {
- // 鏂板妯″紡
- operationType.value = 'add';
- }
-};
+ // 鍔犺浇璁惧鍒楄〃
+ const loadDeviceName = async () => {
+ try {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data || [];
+ } catch (e) {
+ showToast("鑾峰彇璁惧鍒楄〃澶辫触");
+ }
+ };
-// 鎵弿浜岀淮鐮佸姛鑳�
-const startScan = () => {
- if (isScanning.value) {
- showToast('姝e湪鎵弿涓紝璇风◢鍊�...');
- return;
- }
-
- // 璋冪敤uni-app鐨勬壂鐮丄PI
- uni.scanCode({
- scanType: ['qrCode', 'barCode'],
- success: (res) => {
- handleScanResult(res.result);
- },
- fail: (err) => {
- console.error('鎵爜澶辫触:', err);
- showToast('鎵爜澶辫触锛岃閲嶈瘯');
- }
- });
-};
+ // 璁剧疆璁惧瑙勬牸鍨嬪彿
+ const setDeviceModel = id => {
+ const option = deviceOptions.value.find(item => item.id === id);
+ if (option) {
+ form.value.deviceModel = option.deviceModel;
+ deviceNameText.value = option.deviceName;
+ }
+ };
-// 澶勭悊鎵爜缁撴灉
-const handleScanResult = (scanResult) => {
- if (!scanResult) {
- showToast('鎵爜缁撴灉涓虹┖');
- return;
- }
-
- isScanning.value = true;
- showToast('鎵爜鎴愬姛');
-
- // 3绉掑悗澶勭悊鎵爜缁撴灉
- scanTimer.value = setTimeout(() => {
- processScanResult(scanResult);
- isScanning.value = false;
- }, 100);
-};
-function getDeviceIdByRegExp(url) {
- // 鍖归厤deviceId=鍚庨潰鐨勬暟瀛�
- const reg = /deviceId=(\d+)/;
- const match = url.match(reg);
- // 濡傛灉鍖归厤鍒扮粨鏋滐紝杩斿洖鏁板瓧绫诲瀷锛屽惁鍒欒繑鍥瀗ull
- return match ? Number(match[1]) : null;
-}
+ // 鍔犺浇琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
+ const loadForm = async id => {
+ if (id) {
+ operationType.value = "edit";
+ try {
+ const { code, data } = await getRepairById(id);
+ if (code == 200) {
+ form.value.deviceLedgerId = data.deviceLedgerId;
+ form.value.deviceModel = data.deviceModel;
+ form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD");
+ form.value.repairName = data.repairName;
+ form.value.remark = data.remark;
+ repairStatusText.value =
+ repairStatusOptions.value.find(item => item.value == data.status)
+ ?.name || "";
+ // 璁剧疆璁惧鍚嶇О鏄剧ず
+ const device = deviceOptions.value.find(
+ item => item.id === data.deviceLedgerId
+ );
+ if (device) {
+ deviceNameText.value = device.deviceName;
+ }
+ }
+ } catch (e) {
+ showToast("鑾峰彇璇︽儏澶辫触");
+ }
+ } else {
+ // 鏂板妯″紡
+ operationType.value = "add";
+ }
+ };
-// 澶勭悊鎵爜缁撴灉骞跺尮閰嶈澶�
-const processScanResult = (scanResult) => {
- const deviceId = getDeviceIdByRegExp(scanResult);
- const matchedDevice = deviceOptions.value.find(item => item.id == deviceId);
-
- if (matchedDevice) {
- // 鎵惧埌鍖归厤鐨勮澶囷紝鑷姩濉厖
- form.value.deviceLedgerId = matchedDevice.id;
- deviceNameText.value = matchedDevice.deviceName;
- form.value.deviceModel = matchedDevice.deviceModel;
- showToast('璁惧淇℃伅宸茶嚜鍔ㄥ~鍏�');
- } else {
- // 鏈壘鍒板尮閰嶇殑璁惧
- showToast('鏈壘鍒板尮閰嶇殑璁惧锛岃鎵嬪姩閫夋嫨');
- }
-};
+ // 鎵弿浜岀淮鐮佸姛鑳�
+ const startScan = () => {
+ if (isScanning.value) {
+ showToast("姝e湪鎵弿涓紝璇风◢鍊�...");
+ return;
+ }
-// 鏄剧ず璁惧閫夋嫨鍣�
-const showDevicePicker = () => {
- showDevice.value = true;
-};
+ // 璋冪敤uni-app鐨勬壂鐮丄PI
+ uni.scanCode({
+ scanType: ["qrCode", "barCode"],
+ success: res => {
+ handleScanResult(res.result);
+ },
+ fail: err => {
+ console.error("鎵爜澶辫触:", err);
+ showToast("鎵爜澶辫触锛岃閲嶈瘯");
+ },
+ });
+ };
-// 纭璁惧閫夋嫨
-const onDeviceSelect = (e) => {
- form.value.deviceLedgerId = e.value;
- setDeviceModel(e.value);
- showDevice.value = false;
-};
+ // 澶勭悊鎵爜缁撴灉
+ const handleScanResult = scanResult => {
+ if (!scanResult) {
+ showToast("鎵爜缁撴灉涓虹┖");
+ return;
+ }
-// 鏄剧ず鏃ユ湡閫夋嫨鍣�
-const showDatePicker = () => {
- showDate.value = true;
-};
+ isScanning.value = true;
+ showToast("鎵爜鎴愬姛");
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
- form.value.repairTime = formatDateToYMD(e.value);
- pickerDateValue.value = dayjs(e.value).format("YYYY-MM-DD");
- showDate.value = false;
-};
+ // 3绉掑悗澶勭悊鎵爜缁撴灉
+ scanTimer.value = setTimeout(() => {
+ processScanResult(scanResult);
+ isScanning.value = false;
+ }, 100);
+ };
+ function getDeviceIdByRegExp(url) {
+ // 鍖归厤deviceId=鍚庨潰鐨勬暟瀛�
+ const reg = /deviceId=(\d+)/;
+ const match = url.match(reg);
+ // 濡傛灉鍖归厤鍒扮粨鏋滐紝杩斿洖鏁板瓧绫诲瀷锛屽惁鍒欒繑鍥瀗ull
+ return match ? Number(match[1]) : null;
+ }
-onShow(() => {
- // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
- getPageParams();
-});
+ // 澶勭悊鎵爜缁撴灉骞跺尮閰嶈澶�
+ const processScanResult = scanResult => {
+ const deviceId = getDeviceIdByRegExp(scanResult);
+ const matchedDevice = deviceOptions.value.find(item => item.id == deviceId);
-onMounted(() => {
- // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
- loadDeviceName();
- getPageParams();
-});
+ if (matchedDevice) {
+ // 鎵惧埌鍖归厤鐨勮澶囷紝鑷姩濉厖
+ form.value.deviceLedgerId = matchedDevice.id;
+ deviceNameText.value = matchedDevice.deviceName;
+ form.value.deviceModel = matchedDevice.deviceModel;
+ showToast("璁惧淇℃伅宸茶嚜鍔ㄥ~鍏�");
+ } else {
+ // 鏈壘鍒板尮閰嶇殑璁惧
+ showToast("鏈壘鍒板尮閰嶇殑璁惧锛岃鎵嬪姩閫夋嫨");
+ }
+ };
-// 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
-onUnmounted(() => {
- if (scanTimer.value) {
- clearTimeout(scanTimer.value);
- }
-});
+ // 鏄剧ず璁惧閫夋嫨鍣�
+ const showDevicePicker = () => {
+ showDevice.value = true;
+ };
-// 鎻愪氦琛ㄥ崟
-const sendForm = async () => {
- try {
- // 鎵嬪姩楠岃瘉琛ㄥ崟
- let isValid = true;
- let errorMessage = '';
- if (!form.value.deviceLedgerId) {
- isValid = false;
- errorMessage = '璇烽�夋嫨璁惧鍚嶇О';
- } else if (!form.value.repairTime || form.value.repairTime.trim() === '') {
- isValid = false;
- errorMessage = '璇烽�夋嫨鎶ヤ慨鏃ユ湡';
- } else if (!form.value.repairName || form.value.repairName.trim() === '') {
- isValid = false;
- errorMessage = '璇疯緭鍏ユ姤淇汉';
- } else if (!form.value.remark || form.value.remark.trim() === '') {
- isValid = false;
- errorMessage = '璇疯緭鍏ユ晠闅滅幇璞�';
- }
+ // 纭璁惧閫夋嫨
+ const onDeviceSelect = e => {
+ form.value.deviceLedgerId = e.value;
+ setDeviceModel(e.value);
+ showDevice.value = false;
+ };
- if (!isValid) {
- showToast(errorMessage);
- return;
- }
+ // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+ const showDatePicker = () => {
+ showDate.value = true;
+ };
- loading.value = true;
- const id = getPageId();
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.repairTime = formatDateToYMD(e.value);
+ pickerDateValue.value = dayjs(e.value).format("YYYY-MM-DD");
+ showDate.value = false;
+ };
- // 鍑嗗鎻愪氦鏁版嵁
- const submitData = { ...form.value };
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
+ getPageParams();
+ });
- const { code } = id
- ? await editRepair({ id: id, ...submitData })
- : await addRepair(submitData);
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
+ loadDeviceName();
+ getPageParams();
+ });
- if (code == 200) {
- showToast(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- } else {
- loading.value = false;
- }
- } catch (e) {
- loading.value = false;
- showToast('琛ㄥ崟楠岃瘉澶辫触');
- }
-};
+ // 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
+ onUnmounted(() => {
+ if (scanTimer.value) {
+ clearTimeout(scanTimer.value);
+ }
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.removeStorageSync('repairId');
- uni.navigateBack();
-};
+ // 鎻愪氦琛ㄥ崟
+ const sendForm = async () => {
+ try {
+ // 鎵嬪姩楠岃瘉琛ㄥ崟
+ let isValid = true;
+ let errorMessage = "";
+ if (!form.value.deviceLedgerId) {
+ isValid = false;
+ errorMessage = "璇烽�夋嫨璁惧鍚嶇О";
+ } else if (!form.value.repairTime || form.value.repairTime.trim() === "") {
+ isValid = false;
+ errorMessage = "璇烽�夋嫨鎶ヤ慨鏃ユ湡";
+ } else if (!form.value.repairName || form.value.repairName.trim() === "") {
+ isValid = false;
+ errorMessage = "璇疯緭鍏ユ姤淇汉";
+ } else if (!form.value.remark || form.value.remark.trim() === "") {
+ isValid = false;
+ errorMessage = "璇疯緭鍏ユ晠闅滅幇璞�";
+ }
-// 鑾峰彇椤甸潰鍙傛暟
-const getPageParams = () => {
- // 浣跨敤uni.getStorageSync鑾峰彇id
- const id = uni.getStorageSync('repairId');
-
- // 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
- if (id) {
- // 缂栬緫妯″紡锛岃幏鍙栬鎯�
- loadForm(id);
- // 鍙�夛細鑾峰彇鍚庢竻闄ゅ瓨鍌ㄧ殑id锛岄伩鍏嶅奖鍝嶅悗缁搷浣�
- uni.removeStorageSync('repairId');
- } else {
- // 鏂板妯″紡
- loadForm();
- }
-};
+ if (!isValid) {
+ showToast(errorMessage);
+ return;
+ }
-// 鑾峰彇椤甸潰ID
-const getPageId = () => {
- // 浣跨敤uni.getStorageSync鑾峰彇id
- const id = uni.getStorageSync('repairId');
- return id;
-};
+ loading.value = true;
+ const id = getPageId();
+
+ // 鍑嗗鎻愪氦鏁版嵁
+ const submitData = { ...form.value };
+
+ const { code } = id
+ ? await editRepair({ id: id, ...submitData })
+ : await addRepair(submitData);
+
+ if (code == 200) {
+ showToast(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+ setTimeout(() => {
+ uni.navigateBack();
+ }, 1500);
+ } else {
+ loading.value = false;
+ }
+ } catch (e) {
+ loading.value = false;
+ showToast("琛ㄥ崟楠岃瘉澶辫触");
+ }
+ };
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("repairId");
+ uni.navigateBack();
+ };
+
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浣跨敤uni.getStorageSync鑾峰彇id
+ const id = uni.getStorageSync("repairId");
+
+ // 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
+ if (id) {
+ // 缂栬緫妯″紡锛岃幏鍙栬鎯�
+ loadForm(id);
+ // 鍙�夛細鑾峰彇鍚庢竻闄ゅ瓨鍌ㄧ殑id锛岄伩鍏嶅奖鍝嶅悗缁搷浣�
+ uni.removeStorageSync("repairId");
+ } else {
+ // 鏂板妯″紡
+ loadForm();
+ }
+ };
+
+ // 鑾峰彇椤甸潰ID
+ const getPageId = () => {
+ // 浣跨敤uni.getStorageSync鑾峰彇id
+ const id = uni.getStorageSync("repairId");
+ return id;
+ };
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-.repair-add {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 5rem;
-}
+ @import "@/static/scss/form-common.scss";
+ .repair-add {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
-.footer-btns {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background: #fff;
- display: flex;
- justify-content: space-around;
- align-items: center;
- padding: 0.75rem 0;
- box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
- z-index: 1000;
-}
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
-.cancel-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 6.375rem;
- background: #C7C9CC;
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.save-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 14rem;
- background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-// 鍝嶅簲寮忚皟鏁�
-@media (max-width: 768px) {
- .submit-section {
- padding: 12px;
- }
-}
+ // 鍝嶅簲寮忚皟鏁�
+ @media (max-width: 768px) {
+ .submit-section {
+ padding: 12px;
+ }
+ }
-.tip-text {
- padding: 4px 16px 0 16px;
- font-size: 12px;
- color: #888;
-}
+ .tip-text {
+ padding: 4px 16px 0 16px;
+ font-size: 12px;
+ color: #888;
+ }
-.scan-icon {
- color: #1989fa;
- font-size: 18px;
- margin-left: 8px;
- cursor: pointer;
-}
+ .scan-icon {
+ color: #1989fa;
+ font-size: 18px;
+ margin-left: 8px;
+ cursor: pointer;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/repair/index.vue b/src/pages/equipmentManagement/repair/index.vue
index 49b2374..e280595 100644
--- a/src/pages/equipmentManagement/repair/index.vue
+++ b/src/pages/equipmentManagement/repair/index.vue
@@ -1,44 +1,49 @@
<template>
<view class="sales-account">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="璁惧鎶ヤ慨" @back="goBack" />
-
+ <PageHeader title="璁惧鎶ヤ慨"
+ @back="goBack" />
<!-- 鎼滅储鍖哄煙 -->
<view class="search-section">
<view class="search-bar">
<view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ヨ澶囧悕绉版悳绱�"
- v-model="searchKeyword"
- @change="getList"
- clearable
- />
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヨ澶囧悕绉版悳绱�"
+ v-model="searchKeyword"
+ @change="getList"
+ clearable />
</view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
</view>
</view>
</view>
-
<!-- 璁惧鎶ヤ慨鍒楄〃 -->
- <view class="ledger-list" v-if="repairList.length > 0">
- <view v-for="(item, index) in repairList" :key="index">
+ <view class="ledger-list"
+ v-if="repairList.length > 0">
+ <view v-for="(item, index) in repairList"
+ :key="index">
<view class="ledger-item">
<view class="item-header">
<view class="item-left">
<view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
</view>
<text class="item-id">璁惧鍚嶇О锛歿{ item.deviceName }}</text>
</view>
<view class="status-tag">
- <u-tag v-if="item.status === 1" type="success">瀹岀粨</u-tag>
- <u-tag v-if="item.status === 0" type="error">寰呯淮淇�</u-tag>
+ <u-tag v-if="item.status === 1"
+ type="success">瀹岀粨</u-tag>
+ <u-tag v-if="item.status === 0"
+ type="error">寰呯淮淇�</u-tag>
</view>
</view>
<up-divider></up-divider>
-
<view class="item-details">
<view class="detail-row">
<text class="detail-label">瑙勬牸鍨嬪彿</text>
@@ -69,197 +74,193 @@
<text class="detail-value">{{ formatDate(item.maintenanceTime) || '-' }}</text>
</view>
</view>
-
<!-- 鎸夐挳鍖哄煙 -->
<view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.status === 1"
- @click="edit(item.id)"
- >
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ :disabled="item.status === 1"
+ @click="edit(item.id)">
缂栬緫
</u-button>
- <u-button
- type="warning"
- size="small"
- class="action-btn"
- :disabled="item.status === 1"
- @click="addMaintain(item.id)"
- >
+ <u-button type="warning"
+ size="small"
+ class="action-btn"
+ :disabled="item.status === 1"
+ @click="addMaintain(item.id)">
鏂板缁翠慨
</u-button>
- <u-button
- type="error"
- size="small"
- plain
- class="action-btn"
- @click="delRepairByIds(item.id)"
- >
+ <u-button type="error"
+ size="small"
+ plain
+ class="action-btn"
+ @click="delRepairByIds(item.id)">
鍒犻櫎
</u-button>
</view>
</view>
</view>
</view>
-
- <view v-else class="no-data">
+ <view v-else
+ class="no-data">
<text>鏆傛棤璁惧鎶ヤ慨鏁版嵁</text>
</view>
<!-- 娴姩鎿嶄綔鎸夐挳 -->
- <view class="fab-button" @click="addRepair">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
- </view>
+ <view class="fab-button"
+ @click="addRepair">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view>
</view>
</template>
<script setup>
-import { ref, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { getRepairPage, delRepair } from '@/api/equipmentManagement/repair'
-import useUserStore from "@/store/modules/user"
+ import { ref, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
+ import useUserStore from "@/store/modules/user";
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 鎼滅储鍏抽敭璇�
-const searchKeyword = ref('')
+ // 鎼滅储鍏抽敭璇�
+ const searchKeyword = ref("");
-// 璁惧鎶ヤ慨鏁版嵁
-const repairList = ref([])
+ // 璁惧鎶ヤ慨鏁版嵁
+ const repairList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (dateStr) => {
- if (!dateStr) return ''
- const date = new Date(dateStr)
- 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 formatDate = dateStr => {
+ if (!dateStr) return "";
+ const date = new Date(dateStr);
+ 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 getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const params = {
- current: -1,
- size: -1,
- deviceName: searchKeyword.value || undefined
- }
- getRepairPage(params)
- .then((res) => {
- repairList.value = res.records || res.data?.records || []
- closeToast()
- })
- .catch(() => {
- closeToast()
- showToast('鑾峰彇鏁版嵁澶辫触')
- })
-}
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ deviceName: searchKeyword.value || undefined,
+ };
+ getRepairPage(params)
+ .then(res => {
+ repairList.value = res.records || res.data?.records || [];
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鏂板缁翠慨 - 璺宠浆鍒扮淮淇〉闈�
-const addMaintain = (id) => {
- if (!id) {
- showToast('鍙傛暟閿欒')
- return
- }
- // 浣跨敤uni.setStorageSync瀛樺偍id
- uni.setStorageSync('repairId', id)
- uni.navigateTo({
- url: '/pages/equipmentManagement/repair/maintain'
- })
-}
-
-// 鏂板鎶ヤ慨 - 璺宠浆鍒版姤淇〉闈�
-const addRepair = () => {
- uni.navigateTo({
- url: '/pages/equipmentManagement/repair/add'
- })
-}
-
-// 缂栬緫 - 璺宠浆鍒癮dd椤甸潰锛岄�氳繃id鍖哄垎鏂板杩樻槸缂栬緫
-const edit = (id) => {
- if (!id) return
- // 浣跨敤uni.setStorageSync瀛樺偍id
- uni.setStorageSync('repairId', id)
- uni.navigateTo({
- url: '/pages/equipmentManagement/repair/add'
- })
-}
-
-// 鍒犻櫎鎶ヤ慨鏁版嵁
-const delRepairByIds = async (ids) => {
- uni.showModal({
- title: '璀﹀憡',
- content: '纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?',
- confirmText: '纭畾',
- cancelText: '鍙栨秷',
- success: async (res) => {
- if (!res.confirm) return
- try {
- const response = await delRepair(ids)
- if (response.code === 200) {
- showToast('鍒犻櫎鎴愬姛')
- getList()
- } else {
- showToast('鍒犻櫎澶辫触')
- }
- } catch (e) {
- showToast('鍒犻櫎澶辫触')
- }
+ // 鏂板缁翠慨 - 璺宠浆鍒扮淮淇〉闈�
+ const addMaintain = id => {
+ if (!id) {
+ showToast("鍙傛暟閿欒");
+ return;
}
- })
-}
+ // 浣跨敤uni.setStorageSync瀛樺偍id
+ uni.setStorageSync("repairId", id);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/repair/maintain",
+ });
+ };
-onMounted(() => {
- getList()
-})
+ // 鏂板鎶ヤ慨 - 璺宠浆鍒版姤淇〉闈�
+ const addRepair = () => {
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/repair/add",
+ });
+ };
-onShow(() => {
- getList()
-})
+ // 缂栬緫 - 璺宠浆鍒癮dd椤甸潰锛岄�氳繃id鍖哄垎鏂板杩樻槸缂栬緫
+ const edit = id => {
+ if (!id) return;
+ // 浣跨敤uni.setStorageSync瀛樺偍id
+ uni.setStorageSync("repairId", id);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/repair/add",
+ });
+ };
+
+ // 鍒犻櫎鎶ヤ慨鏁版嵁
+ const delRepairByIds = async ids => {
+ uni.showModal({
+ title: "璀﹀憡",
+ content: "纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?",
+ confirmText: "纭畾",
+ cancelText: "鍙栨秷",
+ success: async res => {
+ if (!res.confirm) return;
+ try {
+ const response = await delRepair(ids);
+ if (response.code === 200) {
+ showToast("鍒犻櫎鎴愬姛");
+ getList();
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ } catch (e) {
+ showToast("鍒犻櫎澶辫触");
+ }
+ },
+ });
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 璁惧缁翠慨鐗规湁鏍峰紡
-.sales-account {
- padding-bottom: 80px; // 涓烘诞鍔ㄦ寜閽暀鍑虹┖闂�
-}
+ // 璁惧缁翠慨鐗规湁鏍峰紡
+ .sales-account {
+ padding-bottom: 80px; // 涓烘诞鍔ㄦ寜閽暀鍑虹┖闂�
+ }
-.status-tag {
- display: flex;
- align-items: center;
-}
+ .status-tag {
+ display: flex;
+ align-items: center;
+ }
-.action-buttons {
- gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
-}
+ .action-buttons {
+ gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/repair/maintain.vue b/src/pages/equipmentManagement/repair/maintain.vue
index aa8a8e3..46b45aa 100644
--- a/src/pages/equipmentManagement/repair/maintain.vue
+++ b/src/pages/equipmentManagement/repair/maintain.vue
@@ -1,256 +1,297 @@
<template>
- <view class="repair-maintain">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鏂板缁翠慨" @back="goBack" />
-
- <!-- 琛ㄥ崟鍐呭 -->
- <u-form ref="formRef" :model="form" :rules="formRules" label-width="140rpx">
- <!-- 鍩烘湰淇℃伅 -->
- <u-cell-group title="缁翠慨淇℃伅" inset>
- <u-form-item prop="maintenanceName" label="缁翠慨浜�" required>
- <u-input
- v-model="form.maintenanceName"
- placeholder="璇疯緭鍏ョ淮淇汉"
- clearable
- />
- </u-form-item>
- <u-form-item prop="maintenanceResult" label="缁翠慨缁撴灉" required>
- <u-input
- v-model="form.maintenanceResult"
- type="textarea"
- rows="3"
- placeholder="璇疯緭鍏ョ淮淇粨鏋�"
- clearable
- maxlength="200"
- show-word-limit
- />
- </u-form-item>
- <u-form-item label="缁翠慨鏃ユ湡" prop="maintenanceTime" required border-bottom>
- <u-input
- v-model="form.maintenanceTime"
- placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
- readonly
- @click="showDatePicker = true"
- clearable
- />
- <template #right>
- <u-icon name="arrow-right" @click="showDatePicker = true"></u-icon>
- </template>
- </u-form-item>
- </u-cell-group>
-
- <!-- 鎻愪氦鎸夐挳 -->
- <view class="footer-btns">
- <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
- <u-button class="save-btn" @click="submitForm" :loading="loading">淇濆瓨</u-button>
- </view>
- </u-form>
-
- <!-- 鏃ユ湡閫夋嫨鍣� -->
- <up-datetime-picker
- :show="showDatePicker"
- v-model="pickerDateValue"
- mode="datetime"
- title="閫夋嫨鏃ユ湡"
- format="YYYY-MM-DD HH:mm:ss"
- @confirm="onDateConfirm"
- @cancel="showDatePicker = false"
- />
- </view>
+ <view class="repair-maintain">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鏂板缁翠慨"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍐呭 -->
+ <u-form ref="formRef"
+ :model="form"
+ :rules="formRules"
+ label-width="140rpx">
+ <!-- 鍩烘湰淇℃伅 -->
+ <u-cell-group title="缁翠慨淇℃伅"
+ inset>
+ <u-form-item prop="maintenanceName"
+ label="缁翠慨浜�"
+ required>
+ <u-input v-model="form.maintenanceName"
+ placeholder="璇疯緭鍏ョ淮淇汉"
+ clearable />
+ </u-form-item>
+ <u-form-item prop="maintenanceResult"
+ label="缁翠慨缁撴灉"
+ required>
+ <u-input v-model="form.maintenanceResult"
+ type="textarea"
+ rows="3"
+ placeholder="璇疯緭鍏ョ淮淇粨鏋�"
+ clearable
+ maxlength="200"
+ show-word-limit />
+ </u-form-item>
+ <u-form-item label="缁翠慨鐘舵��"
+ prop="repairTime"
+ required
+ border-bottom>
+ <u-input v-model="repairStatusText"
+ placeholder="璇烽�夋嫨缁翠慨鐘舵��"
+ readonly
+ @click="openRepairStatusPicker"
+ clearable />
+ <template #right>
+ <u-icon name="arrow-right"
+ @click="openRepairStatusPicker"></u-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="缁翠慨鏃ユ湡"
+ prop="maintenanceTime"
+ required
+ border-bottom>
+ <u-input v-model="form.maintenanceTime"
+ placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+ readonly
+ @click="showDatePicker = true"
+ clearable />
+ <template #right>
+ <u-icon name="arrow-right"
+ @click="showDatePicker = true"></u-icon>
+ </template>
+ </u-form-item>
+ </u-cell-group>
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="save-btn"
+ @click="submitForm"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <up-datetime-picker :show="showDatePicker"
+ v-model="pickerDateValue"
+ mode="datetime"
+ title="閫夋嫨鏃ユ湡"
+ format="YYYY-MM-DD HH:mm:ss"
+ @confirm="onDateConfirm"
+ @cancel="showDatePicker = false" />
+ </view>
</template>
<script setup>
-import { ref, onMounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import PageHeader from '@/components/PageHeader.vue';
-import { addMaintain } from '@/api/equipmentManagement/repair';
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
+ import { ref, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { addMaintain } from "@/api/equipmentManagement/repair";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
-defineOptions({
- name: "璁惧缁翠慨琛ㄥ崟",
-});
+ defineOptions({
+ name: "璁惧缁翠慨琛ㄥ崟",
+ });
-const userStore = useUserStore();
+ const userStore = useUserStore();
-// 琛ㄥ崟寮曠敤
-const formRef = ref(null);
-const loading = ref(false);
-const showDatePicker = ref(false);
-const pickerDateValue = ref(Date.now());; // 浣跨敤鏃堕棿鎴�
+ // 琛ㄥ崟寮曠敤
+ const formRef = ref(null);
+ const loading = ref(false);
+ const showDatePicker = ref(false);
+ const pickerDateValue = ref(Date.now()); // 浣跨敤鏃堕棿鎴�
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = {
- maintenanceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏ョ淮淇汉" }],
- maintenanceResult: [{ required: true, trigger: "blur", message: "璇疯緭鍏ョ淮淇粨鏋�" }],
- maintenanceTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨缁翠慨鏃ユ湡" }],
-};
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ const formRules = {
+ maintenanceName: [
+ { required: true, trigger: "blur", message: "璇疯緭鍏ョ淮淇汉" },
+ ],
+ maintenanceResult: [
+ { required: true, trigger: "blur", message: "璇疯緭鍏ョ淮淇粨鏋�" },
+ ],
+ maintenanceTime: [
+ { required: true, trigger: "change", message: "璇烽�夋嫨缁翠慨鏃ユ湡" },
+ ],
+ };
+ const repairStatusOptions = ref([
+ { name: "寰呯淮淇�", value: "0" },
+ { name: "瀹岀粨", value: "1" },
+ { name: "澶辫触", value: "2" },
+ ]);
+ const repairStatusText = ref("瀹岀粨");
+ // 鎵撳紑鎶ヤ慨鐘舵�侀�夋嫨鍣�
+ const openRepairStatusPicker = () => {
+ uni.showActionSheet({
+ itemList: repairStatusOptions.value.map(item => item.name),
+ success: res => {
+ form.value.status = repairStatusOptions.value[res.tapIndex].value;
+ repairStatusText.value = repairStatusOptions.value[res.tapIndex].name;
+ },
+ });
+ };
+ // 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
+ const form = ref({
+ maintenanceName: userStore.nickName || "", // 榛樿浣跨敤褰撳墠鐢ㄦ埛鏄电О
+ maintenanceResult: undefined, // 缁翠慨缁撴灉
+ maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 缁翠慨鏃ユ湡锛堝彧鏄剧ず鏃ユ湡锛�
+ });
-// 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
-const form = ref({
- maintenanceName: userStore.nickName || '', // 榛樿浣跨敤褰撳墠鐢ㄦ埛鏄电О
- maintenanceResult: undefined, // 缁翠慨缁撴灉
- maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 缁翠慨鏃ユ湡锛堝彧鏄剧ず鏃ユ湡锛�
-});
+ // 鑷畾涔塻howToast鍑芥暟
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-// 鑷畾涔塻howToast鍑芥暟
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-};
+ // 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
+ const resetForm = () => {
+ form.value = {
+ maintenanceName: userStore.nickName || "",
+ maintenanceResult: undefined,
+ maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+ };
+ };
-// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
-const resetForm = () => {
- form.value = {
- maintenanceName: userStore.nickName || '',
- maintenanceResult: undefined,
- maintenanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
- };
-};
+ const resetFormAndValidate = () => {
+ resetForm();
+ };
-const resetFormAndValidate = () => {
- resetForm();
-};
+ // 鎻愪氦琛ㄥ崟
+ const submitForm = async () => {
+ try {
+ // 浣跨敤uview-plus鐨勮〃鍗曢獙璇佹柟寮�
+ const valid = await formRef.value.validate();
+ if (valid) {
+ submitFormData();
+ }
+ } catch (e) {
+ showToast("琛ㄥ崟楠岃瘉澶辫触");
+ }
+ };
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- try {
- // 浣跨敤uview-plus鐨勮〃鍗曢獙璇佹柟寮�
- const valid = await formRef.value.validate();
- if (valid) {
- submitFormData();
- }
- } catch (e) {
- showToast('琛ㄥ崟楠岃瘉澶辫触');
- }
-};
+ // 鎻愪氦琛ㄥ崟鏁版嵁
+ const submitFormData = async () => {
+ try {
+ loading.value = true;
+ const id = getPageId();
-// 鎻愪氦琛ㄥ崟鏁版嵁
-const submitFormData = async () => {
- try {
- loading.value = true;
- const id = getPageId();
-
- if (!id) {
- showToast('鍙傛暟閿欒');
- loading.value = false;
- return;
- }
-
- // 鍑嗗鎻愪氦鏁版嵁锛宮aintenanceTime 鍔犱笂褰撳墠鏃跺垎绉�
- const submitData = { ...form.value };
-
- const { code } = await addMaintain({ id: id, ...submitData });
-
- if (code == 200) {
- showToast('鏂板缁翠慨鎴愬姛');
- resetFormAndValidate();
- setTimeout(() => {
- goBack();
- }, 500);
- } else {
- loading.value = false;
- }
- } catch (e) {
- console.log(e);
-
- loading.value = false;
- showToast('鎿嶄綔澶辫触');
- }
-};
+ if (!id) {
+ showToast("鍙傛暟閿欒");
+ loading.value = false;
+ return;
+ }
+ form.value.status = Number(form.value.status);
+ // 鍑嗗鎻愪氦鏁版嵁锛宮aintenanceTime 鍔犱笂褰撳墠鏃跺垎绉�
+ const submitData = { ...form.value };
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.removeStorageSync('repairId');
- uni.navigateBack();
-};
+ const { code } = await addMaintain({ id: id, ...submitData });
-// 鑾峰彇椤甸潰ID
-const getPageId = () => {
- const id = uni.getStorageSync('repairId');
- return id;
-};
+ if (code == 200) {
+ showToast("鏂板缁翠慨鎴愬姛");
+ resetFormAndValidate();
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ } else {
+ loading.value = false;
+ }
+ } catch (e) {
+ console.log(e);
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
- form.value.maintenanceTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss')
- pickerDateValue.value = e.value
- showDatePicker.value = false;
-};
+ loading.value = false;
+ showToast("鎿嶄綔澶辫触");
+ }
+ };
-// 鍒濆鍖栬〃鍗曟暟鎹�
-const initForm = () => {
- // 璁剧疆缁翠慨浜轰负褰撳墠鐢ㄦ埛鏄电О
- form.value.maintenanceName = userStore.nickName || '';
- // 璁剧疆褰撳墠鏃ユ湡锛堝彧鍖呭惈骞存湀鏃ワ級
- form.value.maintenanceTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("repairId");
+ uni.navigateBack();
+ };
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺垵濮嬪寲琛ㄥ崟
- initForm();
-});
+ // 鑾峰彇椤甸潰ID
+ const getPageId = () => {
+ const id = uni.getStorageSync("repairId");
+ return id;
+ };
-onMounted(() => {
- // 椤甸潰鍔犺浇鏃跺垵濮嬪寲琛ㄥ崟
- initForm();
-});
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.maintenanceTime = dayjs(e.value).format("YYYY-MM-DD HH:mm:ss");
+ pickerDateValue.value = e.value;
+ showDatePicker.value = false;
+ };
+
+ // 鍒濆鍖栬〃鍗曟暟鎹�
+ const initForm = () => {
+ form.value.status = "1";
+ // 璁剧疆缁翠慨浜轰负褰撳墠鐢ㄦ埛鏄电О
+ form.value.maintenanceName = userStore.nickName || "";
+ // 璁剧疆褰撳墠鏃ユ湡锛堝彧鍖呭惈骞存湀鏃ワ級
+ form.value.maintenanceTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺垵濮嬪寲琛ㄥ崟
+ initForm();
+ });
+
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃跺垵濮嬪寲琛ㄥ崟
+ initForm();
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-.repair-maintain {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 5rem;
-}
+ @import "@/static/scss/form-common.scss";
+ .repair-maintain {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
-.footer-btns {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background: #fff;
- display: flex;
- justify-content: space-around;
- align-items: center;
- padding: 0.75rem 0;
- box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
- z-index: 1000;
-}
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
-.cancel-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 6.375rem;
- background: #C7C9CC;
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.save-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 14rem;
- background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-// 鍝嶅簲寮忚皟鏁�
-@media (max-width: 768px) {
- .submit-section {
- padding: 12px;
- }
-}
+ // 鍝嶅簲寮忚皟鏁�
+ @media (max-width: 768px) {
+ .submit-section {
+ padding: 12px;
+ }
+ }
-.tip-text {
- padding: 4px 16px 0 16px;
- font-size: 12px;
- color: #888;
-}
+ .tip-text {
+ padding: 4px 16px 0 16px;
+ font-size: 12px;
+ color: #888;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/runManagement/index.vue b/src/pages/equipmentManagement/runManagement/index.vue
new file mode 100644
index 0000000..05d1d4e
--- /dev/null
+++ b/src/pages/equipmentManagement/runManagement/index.vue
@@ -0,0 +1,548 @@
+<template>
+ <view class="notice-page">
+ <PageHeader title="杩愯绠$悊"
+ @back="goBack" />
+ <!-- 閫氱煡鍏憡鏉� -->
+ <view class="notice-board">
+ <!-- 缁熶竴閫氱煡鍖哄煙 -->
+ <view v-if="holidayNotices.length > 0"
+ class="notice-section">
+ <view class="section-header">
+ <h3>璁惧杩愯璁板綍</h3>
+ </view>
+ <view class="notice-cards">
+ <!-- 鏀惧亣閫氱煡 -->
+ <view v-for="notice in holidayNotices"
+ :key="'holiday-' + notice.id"
+ class="notice-card holiday-card"
+ :class="{ 'urgent': isOverdue(notice) }">
+ <view class="card-header">
+ <view class="card-title">
+ <view class="holiday-icon">
+ <up-icon name="calendar"
+ size="18"
+ color="#67c23a" />
+ </view>
+ <text>璁惧鍚嶇О锛歿{ notice.deviceName }}</text>
+ </view>
+ <view class="card-actions warning"
+ v-if="isOverdue(notice)">
+ <up-icon name="info-circle"
+ size="16"
+ color="#fff" />
+ <text>{{ '瓒呮椂鏈惎鍔�' }}</text>
+ </view>
+ <view v-else
+ class="card-actions"
+ :class="getTagType(notice.status)">
+ <up-icon :name="getIconName(notice.status)"
+ size="16"
+ color="#fff" />
+ <text>{{ notice.status || '鏈煡' }}</text>
+ </view>
+ </view>
+ <view class="card-content">
+ <text>瑙勬牸鍨嬪彿锛歿{ notice.deviceModel || "-" }}</text>
+ </view>
+ <view class="card-content">
+ <text>璁″垝杩愯鏃堕棿锛歿{ notice.planRuntimeTime || "-" }}</text>
+ </view>
+ <view class="card-content">
+ <text>寮�濮嬭繍琛屾椂闂达細{{ notice.startRuntimeTime || "-" }}</text>
+ </view>
+ <view class="card-content">
+ <text>缁撴潫杩愯鏃堕棿锛歿{ notice.endRuntimeTime || "-" }}</text>
+ </view>
+ <view class="card-content">
+ <text>杩愯鏃堕暱锛歿{ notice.runtimeDuration || "-" }}</text>
+ </view>
+ <up-button text
+ v-if="isOverdue(notice)"
+ type="warning"
+ size="small"
+ @click="handleEdit(notice, '鍚姩杩愯')"
+ :disabled="isNoticeExpired(notice)">
+ <up-icon name="play-circle"
+ size="16"
+ style="margin-right: 10rpx;"
+ color="#fff" />
+ 绔嬪嵆鍚姩
+ </up-button>
+ <up-button text
+ v-else-if="notice.status"
+ :type="getTagType2(notice.status)"
+ size="small"
+ @click="handleEdit(notice, notice.status === '杩愯涓�' ? '鍋滄杩愯' : '鍚姩杩愯')"
+ :disabled="isNoticeExpired(notice)">
+ <up-icon :name="getIconName2(notice.status)"
+ size="16"
+ color="#fff" />
+ {{ notice.status === '杩愯涓�' ? '鍋滄杩愯' : '绔嬪嵆鍚姩' }}
+ </up-button>
+ </view>
+ </view>
+ </view>
+ <!-- 绌虹姸鎬� -->
+ <view class="empty-state"
+ v-if="holidayNotices.length === 0 && maintenanceNotices.length === 0">
+ <text>鏆傛棤杩愯璁板綍</text>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { onMounted, ref } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getLedgerPage,
+ editLedger,
+ } from "@/api/equipmentManagement/runManagement.js";
+
+ // 鑾峰彇鏍囩绫诲瀷
+ const getTagType = status => {
+ switch (status) {
+ case "杩愯涓�":
+ return "success";
+ case "鍋滄杩愯":
+ return "error";
+ default:
+ return "info";
+ }
+ };
+ const getTagType2 = status => {
+ switch (status) {
+ case "鍋滄杩愯":
+ return "success";
+ case "杩愯涓�":
+ return "error";
+ default:
+ return "info";
+ }
+ };
+ // 鑾峰彇鍥炬爣鍚嶇О
+ const getIconName = status => {
+ switch (status) {
+ case "杩愯涓�":
+ return "play-circle";
+ case "鍋滄杩愯":
+ return "pause-circle";
+ default:
+ return "question-circle";
+ }
+ };
+ // 鑾峰彇鍥炬爣鍚嶇О2
+ const getIconName2 = status => {
+ switch (status) {
+ case "鍋滄杩愯":
+ return "play-circle";
+ case "杩愯涓�":
+ return "pause-circle";
+ default:
+ return "question-circle";
+ }
+ };
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const isOverdue = notice => {
+ if (
+ notice.status == "杩愯涓�" ||
+ !notice.planRuntimeTime ||
+ notice.startRuntimeTime
+ ) {
+ return false;
+ }
+ const planTime = new Date(notice.planRuntimeTime).getTime();
+ const currentTime = new Date().getTime();
+ return currentTime > planTime;
+ };
+
+ 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 handleEdit = 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) {
+ showToast(`${device.deviceName} ${status}鎴愬姛`);
+ // 鍒锋柊鍒楄〃
+ await fetchHolidayNotices();
+ } else {
+ showToast(response.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("鏇存柊璁惧鐘舵�佸け璐�:", error);
+ showToast("鎿嶄綔澶辫触");
+ }
+ };
+
+ const holidayNotices = ref([]);
+ const maintenanceNotices = ref([]);
+
+ const fetchHolidayNotices = (append = false) => {
+ getLedgerPage({}).then(res => {
+ holidayNotices.value = res?.data?.records || [];
+ });
+ };
+
+ // 鐢熷懡鍛ㄦ湡
+ onMounted(() => {
+ fetchHolidayNotices();
+ });
+</script>
+
+<style scoped>
+ .notice-page {
+ min-height: 100vh;
+ background: #f5f7fa;
+ padding-bottom: 16px;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .search_form {
+ background: #ffffff;
+ padding: 12px 16px;
+ margin: 8px 12px 12px;
+ border-radius: 10px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ }
+
+ .search_title {
+ font-weight: 500;
+ color: #333;
+ margin-right: 8px;
+ }
+
+ .ml10 {
+ margin-left: 10px;
+ }
+
+ .notice-board {
+ padding: 0 12px 16px;
+ }
+
+ .notice-section {
+ margin-bottom: 16px;
+ }
+
+ .section-header {
+ display: flex;
+ align-items: center;
+ margin: 4px 4px 12px;
+ }
+
+ .section-header h3 {
+ margin: 0;
+ color: #303133;
+ font-size: 16px;
+ font-weight: 600;
+ }
+
+ .section-count {
+ margin-left: 10px;
+ background: #409eff;
+ color: white;
+ padding: 2px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ }
+
+ .notice-cards {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ .notice-card {
+ background: white;
+ border-radius: 12px;
+ padding: 14px 14px 10px;
+ box-shadow: 0 4px 10px rgba(15, 23, 42, 0.06);
+ 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: #bec4c3;
+ }
+
+ .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: 10px;
+ }
+
+ .card-title {
+ display: flex;
+ align-items: center;
+ font-size: 15px;
+ 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;
+ padding: 4rpx 8rpx;
+ border-radius: 10rpx;
+ }
+
+ .card-content {
+ margin-bottom: 10px;
+ }
+
+ .card-content text {
+ color: #606266;
+ line-height: 1.6;
+ font-size: 13px;
+ }
+
+ .card-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 10px;
+ }
+
+ .card-meta {
+ display: flex;
+ gap: 8px;
+ }
+
+ .type,
+ .priority,
+ .status {
+ padding: 2px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ }
+
+ .type-1 {
+ background: #f0f9ff;
+ color: #0369a1;
+ }
+
+ .type-2 {
+ background: #fef3c7;
+ color: #d97706;
+ }
+
+ .priority-1 {
+ background: #f0f9ff;
+ color: #0369a1;
+ }
+
+ .priority-2 {
+ background: #fef3c7;
+ color: #d97706;
+ }
+ .success {
+ background: #67c23a;
+ color: #fff;
+ }
+ .error {
+ background: #f56c6c;
+ color: #fff;
+ }
+ .info {
+ background: #a8a9aa;
+ color: #fff;
+ }
+ .warning {
+ background: #e6a23c;
+ color: #fff;
+ }
+
+ .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: 48px 16px;
+ color: #999;
+ font-size: 13px;
+ }
+
+ .dialog-footer {
+ text-align: right;
+ }
+
+ /* 绉诲姩绔脊绐楁牱寮� */
+ .dialog-container {
+ background: #ffffff;
+ border-radius: 18px 18px 0 0;
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .dialog-header {
+ padding: 16px 20px 8px 20px;
+ }
+
+ .dialog-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ }
+
+ .dialog-body {
+ flex: 1;
+ padding: 0 16px 12px 16px;
+ overflow-y: auto;
+ }
+
+ .dialog-footer {
+ display: flex;
+ padding: 12px 16px 16px 16px;
+ border-top: 1px solid #f0f0f0;
+ }
+
+ /* 鍝嶅簲寮忚璁� */
+ @media (max-width: 768px) {
+ .search_form {
+ flex-direction: column;
+ gap: 15px;
+ align-items: flex-start;
+ }
+
+ .search_form > div {
+ width: 100%;
+ display: flex;
+ gap: 10px;
+ }
+ }
+</style>
diff --git a/src/pages/equipmentManagement/upkeep/fileList.vue b/src/pages/equipmentManagement/upkeep/fileList.vue
new file mode 100644
index 0000000..b4d4b7f
--- /dev/null
+++ b/src/pages/equipmentManagement/upkeep/fileList.vue
@@ -0,0 +1,562 @@
+<template>
+ <view class="file-list-page">
+ <!-- 椤甸潰澶撮儴 -->
+ <PageHeader title="闄勪欢绠$悊"
+ @back="goBack" />
+ <!-- 闄勪欢鍒楄〃 -->
+ <view class="file-list-container">
+ <view v-if="fileList.length > 0"
+ class="file-list">
+ <view v-for="(file, index) in fileList"
+ :key="file.id || index"
+ class="file-item">
+ <!-- 鏂囦欢鍥炬爣 -->
+ <!-- <view class="file-icon"
+ :class="getFileIconClass(file.fileType)">
+ <up-icon :name="getFileIcon(file.fileType)"
+ size="24"
+ color="#ffffff" />
+ </view> -->
+ <!-- 鏂囦欢淇℃伅 -->
+ <view class="file-info">
+ <text class="file-name">{{ file.name }}</text>
+ <!-- <text class="file-meta">{{ formatFileSize(file.fileSize) }} 路 {{ file.uploadTime || file.createTime }}</text> -->
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="file-actions">
+ <!-- <u-button size="small"
+ type="primary"
+ plain
+ @click="previewFile(file)">棰勮</u-button> -->
+ <u-button size="small"
+ type="info"
+ plain
+ @click="downloadFile(file)">涓嬭浇骞堕瑙�</u-button>
+ <u-button size="small"
+ type="error"
+ plain
+ @click="confirmDelete(file, index)">鍒犻櫎</u-button>
+ </view>
+ </view>
+ </view>
+ <!-- 绌虹姸鎬� -->
+ <view v-else
+ class="empty-state">
+ <up-icon name="document"
+ size="64"
+ color="#c0c4cc" />
+ <text class="empty-text">鏆傛棤闄勪欢</text>
+ </view>
+ </view>
+ <!-- <a rel="nofollow"
+ id="downloadLink"
+ href="#"
+ style="display:none;">涓嬭浇鏂囨湰鏂囦欢</a> -->
+ <!-- 涓婁紶鎸夐挳 -->
+ <view class="upload-button"
+ @click="chooseFile">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff" />
+ <text class="upload-text">涓婁紶闄勪欢</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import config from "@/config";
+ import { getToken } from "@/utils/auth";
+ // import { saveAs } from "file-saver";
+ import {
+ listMaintenanceTaskFiles,
+ addMaintenanceTaskFile,
+ delMaintenanceTaskFile,
+ } from "@/api/equipmentManagement/upkeep";
+ import { blobValidate } from "@/utils/ruoyi";
+
+ // 闄勪欢鍒楄〃
+ const fileList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // const request = axios.create({
+ // baseURL: "URL.com",
+ // adapter: axiosAdapterUniapp,
+ // });
+ // 鑾峰彇鏂囦欢鍥炬爣
+ const getFileIcon = fileType => {
+ const iconMap = {
+ doc: "document",
+ docx: "document",
+ xls: "grid",
+ xlsx: "grid",
+ pdf: "document",
+ ppt: "copy",
+ pptx: "copy",
+ txt: "document",
+ jpg: "image",
+ jpeg: "image",
+ png: "image",
+ gif: "image",
+ zip: "folder",
+ rar: "folder",
+ };
+ return iconMap[fileType.toLowerCase()] || "document";
+ };
+
+ // 鑾峰彇鏂囦欢鍥炬爣鏍峰紡绫�
+ const getFileIconClass = fileType => {
+ const colorMap = {
+ doc: "blue",
+ docx: "blue",
+ xls: "green",
+ xlsx: "green",
+ pdf: "red",
+ ppt: "orange",
+ pptx: "orange",
+ txt: "gray",
+ jpg: "purple",
+ jpeg: "purple",
+ png: "purple",
+ gif: "purple",
+ zip: "yellow",
+ rar: "yellow",
+ };
+ return colorMap[fileType.toLowerCase()] || "gray";
+ };
+
+ // 鏍煎紡鍖栨枃浠跺ぇ灏�
+ 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 chooseFile = () => {
+ uni.chooseImage({
+ count: 9,
+ sizeType: ["original", "compressed"],
+ sourceType: ["album", "camera"],
+ success: res => {
+ console.log(res, "閫夋嫨鍥剧墖鎴愬姛");
+ uploadFiles(res.tempFiles);
+ },
+ fail: err => {
+ console.error("閫夋嫨鍥剧墖澶辫触:", err);
+ showToast("閫夋嫨鏂囦欢澶辫触");
+ },
+ });
+ // uni.chooseFile({
+ // count: 9,
+ // extension: [
+ // ".doc",
+ // ".docx",
+ // ".xls",
+ // ".xlsx",
+ // ".pdf",
+ // ".ppt",
+ // ".pptx",
+ // ".txt",
+ // ".jpg",
+ // ".jpeg",
+ // ".png",
+ // ".gif",
+ // ".zip",
+ // ".rar",
+ // ],
+ // success: res => {
+ // console.log(res, "閫夋嫨鏂囦欢鎴愬姛");
+ // uploadFiles(res.tempFiles);
+ // },
+ // fail: err => {
+ // showToast("閫夋嫨鏂囦欢澶辫触");
+ // },
+ // });
+ };
+
+ // 涓婁紶鏂囦欢
+ const uploadFiles = tempFiles => {
+ console.log(tempFiles, "涓婁紶鏂囦欢1");
+ tempFiles.forEach((tempFile, index) => {
+ // 鏄剧ず涓婁紶涓彁绀�
+ uni.showLoading({
+ title: "涓婁紶涓�...",
+ mask: true,
+ });
+ console.log(tempFile, "涓婁紶鏂囦欢2");
+ // 1. 鐩存帴浣跨敤 uni.uploadFile 涓婁紶鏂囦欢
+ uni.uploadFile({
+ url: config.baseUrl + "/file/upload",
+ filePath: tempFile.path,
+ name: "file",
+ header: {
+ Authorization: "Bearer " + getToken(),
+ },
+ success: uploadRes => {
+ uni.hideLoading();
+ console.log(uploadRes, "涓婁紶鏂囦欢3");
+
+ try {
+ const res = JSON.parse(uploadRes.data);
+ console.log(res, "涓婁紶鏂囦欢4");
+ if (res.code === 200) {
+ // 2. 鎻愬彇鏂囦欢淇℃伅
+ const fileName = tempFile.name
+ ? tempFile.name
+ : tempFile.path.split("/").pop();
+ // const fileType = fileName.split(".").pop();
+ // 3. 鏋勯�犱繚瀛樻枃浠朵俊鎭殑鍙傛暟
+ const saveData = {
+ name: fileName,
+ deviceMaintenanceId: upkeepId.value,
+ url: res.data.tempPath || "",
+ };
+ console.log(saveData, "淇濆瓨鏂囦欢淇℃伅鍙傛暟");
+ // 4. 璋冪敤 addRuleFile 鎺ュ彛淇濆瓨鏂囦欢淇℃伅
+ addMaintenanceTaskFile(saveData)
+ .then(addRes => {
+ if (addRes.code === 200) {
+ // 5. 娣诲姞鍒版枃浠跺垪琛�
+ const newFile = {
+ ...addRes.data,
+ uploadTime: new Date().toLocaleString(),
+ };
+ // fileList.value.push(newFile);
+ getFileList();
+ showToast("涓婁紶鎴愬姛");
+ } else {
+ showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+ }
+ })
+ .catch(err => {
+ console.error("淇濆瓨鏂囦欢淇℃伅澶辫触:", err);
+ showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+ });
+ } else {
+ showToast("鏂囦欢涓婁紶澶辫触");
+ }
+ } catch (e) {
+ console.error("瑙f瀽涓婁紶缁撴灉澶辫触:", e);
+ showToast("涓婁紶澶辫触");
+ }
+ },
+ fail: err => {
+ uni.hideLoading();
+ console.error("涓婁紶澶辫触:", err);
+ showToast("涓婁紶澶辫触");
+ },
+ });
+ });
+ };
+ // 涓嬭浇鏂囦欢
+ const downloadFile = file => {
+ var url =
+ config.baseUrl +
+ "/common/download?fileName=" +
+ encodeURIComponent(file.url) +
+ "&delete=true";
+ console.log(url, "url");
+
+ uni
+ .downloadFile({
+ url: url,
+ responseType: "blob",
+ header: { Authorization: "Bearer " + getToken() },
+ })
+ .then(res => {
+ let osType = uni.getStorageSync("deviceInfo").osName;
+ let filePath = res.tempFilePath;
+ if (osType === "ios") {
+ uni.openDocument({
+ filePath: filePath,
+ showMenu: true,
+ success: res => {},
+ fail: err => {
+ console.log("uni.openDocument--fail");
+ reject(err);
+ },
+ });
+ } else {
+ uni.saveFile({
+ tempFilePath: filePath,
+ success: fileRes => {
+ uni.showToast({
+ icon: "none",
+ mask: true,
+ title:
+ "鏂囦欢宸蹭繚瀛橈細Android/data/uni.UNI720216F/apps/__UNI__720216F/" +
+ fileRes.savedFilePath, //淇濆瓨璺緞
+ duration: 3000,
+ });
+ setTimeout(() => {
+ //鎵撳紑鏂囨。鏌ョ湅
+ uni.openDocument({
+ filePath: fileRes.savedFilePath,
+ success: function (res) {},
+ });
+ }, 1000);
+ },
+ fail: err => {
+ console.log("uni.save--fail");
+ reject(err);
+ },
+ });
+ }
+ // const isBlob = blobValidate(res.data);
+ // if (isBlob) {
+ // const blob = new Blob([res.data], { type: "text/plain" });
+ // const url = URL.createObjectURL(blob);
+ // const downloadLink = document.getElementById("downloadLink");
+ // downloadLink.href = url;
+ // downloadLink.download = file.name;
+ // downloadLink.click();
+ // showToast("涓嬭浇鎴愬姛");
+ // } else {
+ // showToast("涓嬭浇澶辫触");
+ // }
+ })
+ .catch(err => {
+ console.error("涓嬭浇澶辫触:", err);
+ showToast("涓嬭浇澶辫触");
+ });
+ };
+
+ // 纭鍒犻櫎
+ const confirmDelete = (file, index) => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄ら檮浠� "${file.name}" 鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ deleteFile(file.id, index);
+ }
+ },
+ });
+ };
+
+ // 鍒犻櫎鏂囦欢
+ const deleteFile = (fileId, index) => {
+ uni.showLoading({
+ title: "鍒犻櫎涓�...",
+ mask: true,
+ });
+
+ delMaintenanceTaskFile([fileId])
+ .then(res => {
+ uni.hideLoading();
+ if (res.code === 200) {
+ // fileList.value.splice(index, 1);
+ getFileList();
+ showToast("鍒犻櫎鎴愬姛");
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ })
+ .catch(err => {
+ uni.hideLoading();
+ showToast("鍒犻櫎澶辫触");
+ });
+ };
+
+ // 鏄剧ず鎻愮ず
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ const rulesRegulationsManagementId = ref("");
+ const upkeepId = ref("");
+ // 椤甸潰鍔犺浇鏃�
+ onMounted(() => {
+ // 浠� API 鑾峰彇闄勪欢鍒楄〃
+
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙� rulesRegulationsManagementId
+ rulesRegulationsManagementId.value = uni.getStorageSync(
+ "rulesRegulationsManagement"
+ );
+ upkeepId.value = uni.getStorageSync("upkeepId");
+ getFileList();
+ });
+
+ // 鑾峰彇闄勪欢鍒楄〃
+ const getFileList = () => {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ mask: true,
+ });
+
+ listMaintenanceTaskFiles({
+ current: 1,
+ size: 100,
+ deviceMaintenanceId: upkeepId.value,
+ rulesRegulationsManagementId: upkeepId.value,
+ })
+ .then(res => {
+ uni.hideLoading();
+ if (res.code === 200) {
+ fileList.value = res.data.records || [];
+ } else {
+ showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+ }
+ })
+ .catch(err => {
+ uni.hideLoading();
+ showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+ });
+ };
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .file-list-page {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 100rpx;
+ }
+
+ .file-list-container {
+ padding: 20rpx;
+ }
+
+ .file-list {
+ background: #ffffff;
+ border-radius: 8rpx;
+ overflow: hidden;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+ }
+
+ .file-item {
+ display: flex;
+ align-items: center;
+ padding: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+
+ .file-icon {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 8rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-right: 20rpx;
+
+ &.blue {
+ background: #409eff;
+ }
+
+ &.green {
+ background: #67c23a;
+ }
+
+ &.red {
+ background: #f56c6c;
+ }
+
+ &.orange {
+ background: #e6a23c;
+ }
+
+ &.gray {
+ background: #909399;
+ }
+
+ &.purple {
+ background: #909399;
+ }
+
+ &.yellow {
+ background: #e6a23c;
+ }
+ }
+
+ .file-info {
+ flex: 1;
+ min-width: 0;
+ }
+
+ .file-name {
+ display: block;
+ font-size: 16px;
+ color: #303133;
+ margin-bottom: 8rpx;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .file-meta {
+ display: block;
+ font-size: 12px;
+ color: #909399;
+ }
+
+ .file-actions {
+ display: flex;
+ gap: 12rpx;
+ }
+
+ .empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 100rpx 0;
+ background: #ffffff;
+ border-radius: 8rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+ }
+
+ .empty-text {
+ font-size: 14px;
+ color: #909399;
+ margin-top: 20rpx;
+ }
+
+ .upload-button {
+ position: fixed;
+ bottom: 40rpx;
+ right: 40rpx;
+ width: 130rpx;
+ height: 130rpx;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4);
+ z-index: 1000;
+ }
+
+ .upload-text {
+ font-size: 10px;
+ color: #ffffff;
+ margin-top: 4rpx;
+ }
+
+ .upload-progress {
+ padding: 40rpx 0;
+ }
+
+ .upload-progress-text {
+ display: block;
+ text-align: center;
+ margin-top: 20rpx;
+ font-size: 14px;
+ color: #606266;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/upkeep/index.vue b/src/pages/equipmentManagement/upkeep/index.vue
index d11eb48..cca1b04 100644
--- a/src/pages/equipmentManagement/upkeep/index.vue
+++ b/src/pages/equipmentManagement/upkeep/index.vue
@@ -1,44 +1,50 @@
<template>
<view class="sales-account">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="璁惧淇濆吇" @back="goBack" />
-
+ <PageHeader title="璁惧淇濆吇"
+ @back="goBack" />
<!-- 鎼滅储鍖哄煙 -->
<view class="search-section">
<view class="search-bar">
<view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ヨ澶囧悕绉版悳绱�"
- v-model="searchKeyword"
- @change="getList"
- clearable
- />
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヨ澶囧悕绉版悳绱�"
+ v-model="searchKeyword"
+ @change="getList"
+ clearable />
</view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
</view>
</view>
</view>
-
<!-- 璁惧淇濆吇鍒楄〃 -->
- <view class="ledger-list" v-if="upkeepList.length > 0">
- <view v-for="(item, index) in upkeepList" :key="index">
- <view class="ledger-item" @click="toggleSelection(item)">
+ <view class="ledger-list"
+ v-if="upkeepList.length > 0">
+ <view v-for="(item, index) in upkeepList"
+ :key="index">
+ <view class="ledger-item"
+ @click="toggleSelection(item)">
<view class="item-header">
<view class="item-left">
<view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
</view>
<text class="item-id">璁惧鍚嶇О锛歿{ item.deviceName }}</text>
</view>
<view class="status-tag">
- <u-tag v-if="item.status === 1" type="success">瀹岀粨</u-tag>
- <u-tag v-if="item.status === 0" type="error">寰呬繚鍏�</u-tag>
+ <u-tag v-if="item.status === 1"
+ type="success">瀹岀粨</u-tag>
+ <u-tag v-if="item.status === 0"
+ type="error">寰呬繚鍏�</u-tag>
</view>
</view>
<up-divider></up-divider>
-
<view class="item-details">
<view class="detail-row">
<text class="detail-label">瑙勬牸鍨嬪彿</text>
@@ -67,267 +73,282 @@
<view class="detail-row">
<text class="detail-label">淇濆吇缁撴灉</text>
<view class="detail-value">
- <u-tag v-if="item.maintenanceResult === 1" type="success" size="mini">
- 瀹屽ソ
- </u-tag>
- <u-tag v-if="item.maintenanceResult === 0" type="error" size="mini">
- 缁翠慨
- </u-tag>
- <text v-if="item.maintenanceResult === undefined || item.maintenanceResult === null">-</text>
- </view>
+ <u-tag v-if="item.maintenanceResult === 1"
+ type="success"
+ size="mini">
+ 瀹屽ソ
+ </u-tag>
+ <u-tag v-if="item.maintenanceResult === 0"
+ type="error"
+ size="mini">
+ 缁翠慨
+ </u-tag>
+ <text v-if="item.maintenanceResult === undefined || item.maintenanceResult === null">-</text>
+ </view>
</view>
</view>
-
<!-- 鎸夐挳鍖哄煙 -->
<view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.status === 1"
- @click.stop="edit(item.id)"
- >
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ :disabled="item.status === 1"
+ @click.stop="edit(item.id)">
缂栬緫
</u-button>
- <u-button
- type="warning"
- size="small"
- class="action-btn"
- :disabled="item.status === 1"
- @click.stop="addMaintain(item.id)"
- >
+ <u-button type="warning"
+ size="small"
+ class="action-btn"
+ :disabled="item.status === 1"
+ @click.stop="addMaintain(item.id)">
淇濆吇
</u-button>
- <u-button
- type="error"
- size="small"
- plain
- class="action-btn"
- @click.stop="delUpkeepByIds(item.id)"
- >
+ <u-button type="error"
+ size="small"
+ plain
+ class="action-btn"
+ @click.stop="delUpkeepByIds(item.id)">
鍒犻櫎
+ </u-button>
+ <u-button type="warning"
+ size="small"
+ class="action-btn"
+ @click.stop="addFile(item.id)">
+ 闄勪欢
</u-button>
</view>
</view>
</view>
</view>
-
- <view v-else class="no-data">
+ <view v-else
+ class="no-data">
<text>鏆傛棤璁惧淇濆吇鏁版嵁</text>
</view>
-
<!-- 娴姩鏂板鎸夐挳 -->
- <view class="fab-button" @click="addPlan">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
+ <view class="fab-button"
+ @click="addPlan">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
</view>
</view>
</template>
<script setup>
-import { ref, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { getUpkeepPage, delUpkeep } from '@/api/equipmentManagement/upkeep'
-import useUserStore from "@/store/modules/user"
-// 鏄剧ず鎻愮ず淇℃伅
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-};
-import dayjs from "dayjs"
+ import { ref, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep";
+ import useUserStore from "@/store/modules/user";
+ // 鏄剧ず鎻愮ず淇℃伅
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import dayjs from "dayjs";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 鎼滅储鍏抽敭璇�
-const searchKeyword = ref('')
+ // 鎼滅储鍏抽敭璇�
+ const searchKeyword = ref("");
-// 璁惧淇濆吇鏁版嵁
-const upkeepList = ref([])
+ // 璁惧淇濆吇鏁版嵁
+ const upkeepList = ref([]);
-// 澶氶�夊垪琛�
-const multipleList = ref([])
+ // 澶氶�夊垪琛�
+ const multipleList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 鏍煎紡鍖栨棩鏈�
-const formatDate = (dateStr) => {
- if (!dateStr) return ''
- return dayjs(dateStr).format("YYYY-MM-DD")
-}
+ // 鏍煎紡鍖栨棩鏈�
+ const formatDate = dateStr => {
+ if (!dateStr) return "";
+ return dayjs(dateStr).format("YYYY-MM-DD");
+ };
-// 鏍煎紡鍖栨棩鏈熸椂闂�
-const formatDateTime = (dateStr) => {
- if (!dateStr) return ''
- return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss")
-}
+ // 鏍煎紡鍖栨棩鏈熸椂闂�
+ const formatDateTime = dateStr => {
+ if (!dateStr) return "";
+ return dayjs(dateStr).format("YYYY-MM-DD HH:mm:ss");
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const params = {
- current: -1,
- size: -1,
- deviceName: searchKeyword.value || undefined
- }
- getUpkeepPage(params)
- .then((res) => {
- // 濡傛灉res.data涓嶆槸鏁扮粍锛岃缃负绌烘暟缁�
- upkeepList.value = res.records || res.data?.records || []
- closeToast()
- })
- .catch(() => {
- closeToast()
- showToast('鑾峰彇鏁版嵁澶辫触')
- })
-}
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ deviceName: searchKeyword.value || undefined,
+ };
+ getUpkeepPage(params)
+ .then(res => {
+ // 濡傛灉res.data涓嶆槸鏁扮粍锛岃缃负绌烘暟缁�
+ upkeepList.value = res.records || res.data?.records || [];
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
+ // 鏂板闄勪欢 - 璺宠浆鍒伴檮浠堕〉闈�
+ const addFile = id => {
+ // 浣跨敤鏈湴瀛樺偍浼犻�抜d
+ uni.setStorageSync("upkeepId", id);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/upkeep/fileList",
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鍒囨崲閫夋嫨鐘舵��
-const toggleSelection = (item) => {
- const index = multipleList.value.findIndex(selected => selected.id === item.id)
- if (index > -1) {
- multipleList.value.splice(index, 1)
- } else {
- multipleList.value.push(item)
- }
-}
-
-// 妫�鏌ユ槸鍚﹀凡閫夋嫨
-const isSelected = (item) => {
- return multipleList.value.some(selected => selected.id === item.id)
-}
-
-// 鏂板淇濆吇 - 璺宠浆鍒颁繚鍏婚〉闈�
-const addMaintain = (id) => {
- if (!id && multipleList.value.length !== 1) {
- showToast('璇烽�夋嫨涓�鏉¤褰�')
- return
- }
- const targetId = id || multipleList.value[0].id
- // 浣跨敤鏈湴瀛樺偍浼犻�抜d
- uni.setStorageSync('repairId', targetId)
- uni.navigateTo({
- url: '/pages/equipmentManagement/upkeep/maintain'
- })
-}
-
-// 鏂板璁″垝 - 璺宠浆鍒版柊澧為〉闈�
-const addPlan = () => {
- uni.navigateTo({
- url: '/pages/equipmentManagement/upkeep/add'
- })
-}
-
-// 缂栬緫 - 璺宠浆鍒癮dd椤甸潰锛岄�氳繃id鍖哄垎鏂板杩樻槸缂栬緫
-const edit = (id) => {
- if (!id) return
- // 浣跨敤鏈湴瀛樺偍浼犻�抜d
- uni.setStorageSync('repairId', id)
- uni.navigateTo({
- url: '/pages/equipmentManagement/upkeep/add'
- })
-}
-
-// 鍒犻櫎淇濆吇鏁版嵁
-const delUpkeepByIds = async (ids) => {
- const deleteIds = Array.isArray(ids) ? ids : [ids]
- if (deleteIds.length === 0) {
- showToast('璇烽�夋嫨瑕佸垹闄ょ殑璁板綍')
- return
- }
-
- uni.showModal({
- title: '璀﹀憡',
- content: '纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?',
- confirmText: '纭畾',
- cancelText: '鍙栨秷',
- success: async (res) => {
- if (!res.confirm) return
- try {
- // 閫愪釜鍒犻櫎
- for (const id of deleteIds) {
- const response = await delUpkeep(id)
- if (response.code !== 200) {
- showToast('鍒犻櫎澶辫触')
- return
- }
- }
- showToast('鍒犻櫎鎴愬姛')
- multipleList.value = []
- getList()
- } catch (e) {
- showToast('鍒犻櫎澶辫触')
- }
+ // 鍒囨崲閫夋嫨鐘舵��
+ const toggleSelection = item => {
+ const index = multipleList.value.findIndex(
+ selected => selected.id === item.id
+ );
+ if (index > -1) {
+ multipleList.value.splice(index, 1);
+ } else {
+ multipleList.value.push(item);
}
- })
-}
+ };
-onMounted(() => {
- getList()
-})
+ // 妫�鏌ユ槸鍚﹀凡閫夋嫨
+ const isSelected = item => {
+ return multipleList.value.some(selected => selected.id === item.id);
+ };
-onShow(() => {
- getList()
-})
+ // 鏂板淇濆吇 - 璺宠浆鍒颁繚鍏婚〉闈�
+ const addMaintain = id => {
+ if (!id && multipleList.value.length !== 1) {
+ showToast("璇烽�夋嫨涓�鏉¤褰�");
+ return;
+ }
+ const targetId = id || multipleList.value[0].id;
+ // 浣跨敤鏈湴瀛樺偍浼犻�抜d
+ uni.setStorageSync("repairId", targetId);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/upkeep/maintain",
+ });
+ };
+
+ // 鏂板璁″垝 - 璺宠浆鍒版柊澧為〉闈�
+ const addPlan = () => {
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/upkeep/add",
+ });
+ };
+
+ // 缂栬緫 - 璺宠浆鍒癮dd椤甸潰锛岄�氳繃id鍖哄垎鏂板杩樻槸缂栬緫
+ const edit = id => {
+ if (!id) return;
+ // 浣跨敤鏈湴瀛樺偍浼犻�抜d
+ uni.setStorageSync("repairId", id);
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/upkeep/add",
+ });
+ };
+
+ // 鍒犻櫎淇濆吇鏁版嵁
+ const delUpkeepByIds = async ids => {
+ const deleteIds = Array.isArray(ids) ? ids : [ids];
+ if (deleteIds.length === 0) {
+ showToast("璇烽�夋嫨瑕佸垹闄ょ殑璁板綍");
+ return;
+ }
+
+ uni.showModal({
+ title: "璀﹀憡",
+ content: "纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?",
+ confirmText: "纭畾",
+ cancelText: "鍙栨秷",
+ success: async res => {
+ if (!res.confirm) return;
+ try {
+ // 閫愪釜鍒犻櫎
+ for (const id of deleteIds) {
+ const response = await delUpkeep(id);
+ if (response.code !== 200) {
+ showToast("鍒犻櫎澶辫触");
+ return;
+ }
+ }
+ showToast("鍒犻櫎鎴愬姛");
+ multipleList.value = [];
+ getList();
+ } catch (e) {
+ showToast("鍒犻櫎澶辫触");
+ }
+ },
+ });
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 璁惧淇濆吇鐗规湁鏍峰紡
-.sales-account {
- padding-bottom: 80px; // 涓烘诞鍔ㄦ寜閽暀鍑虹┖闂�
-}
+ // 璁惧淇濆吇鐗规湁鏍峰紡
+ .sales-account {
+ padding-bottom: 80px; // 涓烘诞鍔ㄦ寜閽暀鍑虹┖闂�
+ }
-.action-section {
- padding: 10px 20px;
- background: #ffffff;
- border-bottom: 1px solid #f0f0f0;
-}
+ .action-section {
+ padding: 10px 20px;
+ background: #ffffff;
+ border-bottom: 1px solid #f0f0f0;
+ }
-.action-section .action-buttons {
- gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
- justify-content: flex-start;
-}
+ .action-section .action-buttons {
+ gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
+ justify-content: flex-start;
+ }
-.checkbox-wrapper {
- display: flex;
- align-items: center;
-}
+ .checkbox-wrapper {
+ display: flex;
+ align-items: center;
+ }
-.status-tag {
- display: flex;
- align-items: center;
-}
+ .status-tag {
+ display: flex;
+ align-items: center;
+ }
-.detail-label {
- min-width: 80px; // 涓庡叕鍏辨牱寮忎腑鐨� 60px 涓嶅悓
-}
+ .detail-label {
+ min-width: 80px; // 涓庡叕鍏辨牱寮忎腑鐨� 60px 涓嶅悓
+ }
-.detail-value {
- display: flex;
- justify-content: flex-end;
- align-items: center;
-}
+ .detail-value {
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ }
-.ledger-item .action-buttons {
- gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
-}
+ .ledger-item .action-buttons {
+ gap: 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 12px 涓嶅悓
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 315c1b6..e1dc475 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -86,29 +86,29 @@
</view>
</view>
<!-- 鍗忓悓鍔炲叕妯″潡 -->
- <view class="common-module collaboration-module">
- <view class="module-header">
- <view class="module-title-container">
- <text class="module-title">鍗忓悓鍔炲叕</text>
- </view>
- </view>
- <view class="module-content">
- <up-grid :border="false"
- col="4">
- <up-grid-item v-for="(item, index) in collaborationItems"
- :key="index"
- @click="handleCommonItemClick(item)">
- <view class="icon-container"
- :style="{ background: item.bgColor }">
- <up-icon :name="item.icon"
- :size="58"
- color="#ffffff"></up-icon>
- </view>
- <text class="item-label">{{item.label}}</text>
- </up-grid-item>
- </up-grid>
- </view>
- </view>
+ <view class="common-module collaboration-module">
+ <view class="module-header">
+ <view class="module-title-container">
+ <text class="module-title">鍗忓悓鍔炲叕</text>
+ </view>
+ </view>
+ <view class="module-content">
+ <up-grid :border="false"
+ col="4">
+ <up-grid-item v-for="(item, index) in collaborationItems"
+ :key="index"
+ @click="handleCommonItemClick(item)">
+ <view class="icon-container"
+ :style="{ background: item.bgColor }">
+ <up-icon :name="item.icon"
+ :size="58"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-label">{{item.label}}</text>
+ </up-grid-item>
+ </up-grid>
+ </view>
+ </view>
<!-- 鐢熶骇绠℃帶妯″潡 -->
<!-- <view class="common-module production-module">-->
<!-- <view class="module-header">-->
@@ -235,6 +235,10 @@
label: "寮�绁ㄥ彴璐�",
},
{
+ icon: "/static/images/icon/kaipiaotaizhang@2x.png",
+ label: "鍙戣揣鍙拌处",
+ },
+ {
icon: "/static/images/icon/huikuandengji@2x.png",
label: "鍥炴鐧昏",
},
@@ -277,16 +281,37 @@
]);
// 鍗忓悓鍔炲叕鍔熻兘鏁版嵁
- const collaborationItems = reactive([
- {
- icon: "/static/images/icon/xietongshenpi@2x.png",
- label: "鍗忓悓瀹℃壒",
- },
- {
- icon: "/static/images/icon/kehubaifang@2x.png",
- label: "瀹㈡埛鎷滆",
- },
- ]);
+ // 鍗忓悓鍔炲叕鍔熻兘鏁版嵁
+ const collaborationItems = reactive([
+ {
+ icon: "/static/images/icon/baoxiaoguanli.png",
+ label: "鍗忓悓瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/huiyiliebiao@2x.png",
+ label: "浼氳绠$悊",
+ },
+ {
+ icon: "/static/images/icon/tongzhigonggao@2x.png",
+ label: "閫氱煡鍏憡",
+ },
+ {
+ icon: "/static/images/icon/zhishiku@2x.png",
+ label: "鐭ヨ瘑搴�",
+ },
+ {
+ icon: "/static/images/icon/yongyinguanli@2x.png",
+ label: "鐢ㄥ嵃绠$悊",
+ },
+ {
+ icon: "/static/images/icon/guizhangzhidu@2x.png",
+ label: "瑙勭珷鍒跺害",
+ },
+ {
+ icon: "/static/images/icon/kehubaifang@2x.png",
+ label: "瀹㈡埛鎷滆",
+ },
+ ]);
// 鐢熶骇绠℃帶鍔熻兘鏁版嵁
const productionItems = reactive([
@@ -376,6 +401,11 @@
url: "/pages/sales/invoiceLedger/index",
});
break;
+ case "鍙戣揣鍙拌处":
+ uni.navigateTo({
+ url: "/pages/sales/deliveryLedger/index",
+ });
+ break;
case "鍥炴鐧昏":
uni.navigateTo({
url: "/pages/sales/receiptPayment/index",
@@ -421,16 +451,41 @@
url: "/pages/procurementManagement/paymentLedger/index",
});
break;
- case "鍗忓悓瀹℃壒":
- uni.navigateTo({
- url: "/pages/cooperativeOffice/collaborativeApproval/index",
- });
- break;
- case "瀹㈡埛鎷滆":
- uni.navigateTo({
- url: "/pages/cooperativeOffice/clientVisit/index",
- });
- break;
+ case "鍗忓悓瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/indexItem?label=鍗忓悓瀹℃壒",
+ });
+ break;
+ case "浼氳绠$悊":
+ uni.navigateTo({
+ url: "/pages/indexItem?label=浼氳绠$悊",
+ });
+ break;
+ case "閫氱煡鍏憡":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/noticeManagement/index",
+ });
+ break;
+ case "鐭ヨ瘑搴�":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/knowledgeBase/index",
+ });
+ break;
+ case "鐢ㄥ嵃绠$悊":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/sealManagement/index",
+ });
+ break;
+ case "瑙勭珷鍒跺害":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/rulesRegulationsManagement/index",
+ });
+ break;
+ case "瀹㈡埛鎷滆":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/clientVisit/index",
+ });
+ break;
case "鐢熶骇璁㈠崟":
uni.navigateTo({
url: "/pages/productionManagement/productionOrder/index",
diff --git a/src/pages/indexItem.vue b/src/pages/indexItem.vue
new file mode 100644
index 0000000..c2b6633
--- /dev/null
+++ b/src/pages/indexItem.vue
@@ -0,0 +1,1124 @@
+<template>
+ <view class="content">
+ <PageHeader :title="operationType"
+ @back="goBack" />
+ <view class="common-module collaboration-module">
+ <view class="module-header">
+ <view class="module-title-container">
+ <text class="module-title">{{ operationType }}</text>
+ </view>
+ </view>
+ <view class="module-content">
+ <up-grid :border="false"
+ col="4">
+ <up-grid-item v-for="(item, index) in commonItems"
+ :key="index"
+ @click="handleCommonItemClick(item)">
+ <view class="icon-container"
+ :style="{ background: item.bgColor }">
+ <up-icon :name="item.icon"
+ :size="58"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-label">{{item.label}}</text>
+ </up-grid-item>
+ </up-grid>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { onMounted, reactive, ref } from "vue";
+ import useUserStore from "@/store/modules/user";
+ import { onLoad } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+
+ const userStore = useUserStore();
+ const kaoqin = reactive([
+ {
+ icon: "/static/images/icon/gongchuguanli@2x.png",
+ label: "鍏嚭绠$悊",
+ },
+ {
+ icon: "/static/images/icon/qingjiaguanli@2x.png",
+ label: "璇峰亣绠$悊",
+ },
+ {
+ icon: "/static/images/icon/chuchaiguanli@2x.png",
+ label: "鍑哄樊绠$悊",
+ },
+ ]);
+ const caiwu = reactive([
+ {
+ icon: "/static/images/icon/baoxiaoguanli.png",
+ label: "鎶ラ攢绠$悊",
+ },
+ {
+ icon: "/static/images/icon/caigouguanli.png",
+ label: "閲囪喘瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/baojiaguanli.png",
+ label: "鎶ヤ环瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/chukuguanli@2x.png",
+ label: "鍙戣揣瀹℃壒",
+ },
+ ]);
+ // 鑰冨嫟璐㈠姟鍚堝苟鑿滃崟锛堣�冨嫟3涓� + 璐㈠姟4涓� = 7涓級
+ const kaoqinCaiwu = reactive([
+ {
+ icon: "/static/images/icon/gongchuguanli@2x.png",
+ label: "鍏嚭绠$悊",
+ },
+ {
+ icon: "/static/images/icon/qingjiaguanli@2x.png",
+ label: "璇峰亣绠$悊",
+ },
+ {
+ icon: "/static/images/icon/chuchaiguanli@2x.png",
+ label: "鍑哄樊绠$悊",
+ },
+ {
+ icon: "/static/images/icon/baoxiaoguanli.png",
+ label: "鎶ラ攢绠$悊",
+ },
+ {
+ icon: "/static/images/icon/caigouguanli.png",
+ label: "閲囪喘瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/baojiaguanli.png",
+ label: "鎶ヤ环瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/chukuguanli@2x.png",
+ label: "鍙戣揣瀹℃壒",
+ },
+ ]);
+
+ const huiyi = reactive([
+ {
+ icon: "/static/images/icon/huiyishezhi@2x.png",
+ label: "浼氳璁剧疆",
+ },
+ {
+ icon: "/static/images/icon/huiyiliebiao@2x.png",
+ label: "浼氳鍒楄〃",
+ },
+ {
+ icon: "/static/images/icon/huiyishenqing@2x.png",
+ label: "浼氳鐢宠",
+ },
+ {
+ icon: "/static/images/icon/huiyishenpi@2x.png",
+ label: "浼氳瀹℃壒",
+ },
+ {
+ icon: "/static/images/icon/huiyifabu@2x.png",
+ label: "浼氳鍙戝竷",
+ },
+ {
+ icon: "/static/images/icon/huiyizongjie@2x.png",
+ label: "浼氳鎬荤粨",
+ },
+ {
+ icon: "/static/images/icon/huiyikanban@2x.png",
+ label: "浼氳鐪嬫澘",
+ },
+ ]);
+ const commonItems = ref([]);
+ // 澶勭悊甯哥敤鍔熻兘鐐瑰嚮
+ const handleCommonItemClick = item => {
+ // 鏍规嵁涓嶅悓鐨勫姛鑳介」杩涜璺宠浆
+ switch (item.label) {
+ case "閿�鍞彴璐�":
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/index",
+ });
+ break;
+ case "寮�绁ㄧ櫥璁�":
+ uni.navigateTo({
+ url: "/pages/sales/invoicingRegistration/index",
+ });
+ break;
+ case "寮�绁ㄥ彴璐�":
+ uni.navigateTo({
+ url: "/pages/sales/invoiceLedger/index",
+ });
+ break;
+ case "鍥炴鐧昏":
+ uni.navigateTo({
+ url: "/pages/sales/receiptPayment/index",
+ });
+ break;
+ case "鍥炴娴佹按":
+ uni.navigateTo({
+ url: "/pages/sales/receiptPaymentHistory/index",
+ });
+ break;
+ case "瀹㈡埛寰�鏉�":
+ uni.navigateTo({
+ url: "/pages/sales/receiptPaymentLedger/index",
+ });
+ break;
+ case "閲囪喘鍙拌处":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/procurementLedger/index",
+ });
+ break;
+ case "鏉ョエ鐧昏":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/invoiceEntry/index",
+ });
+ break;
+ case "鏉ョエ鍙拌处":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/procurementInvoiceLedger/index",
+ });
+ break;
+ case "浠樻鐧昏":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/paymentEntry/index",
+ });
+ break;
+ case "浠樻娴佹按":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/receiptPaymentHistory/index",
+ });
+ break;
+ case "渚涘簲鍟嗗線鏉�":
+ uni.navigateTo({
+ url: "/pages/procurementManagement/paymentLedger/index",
+ });
+ break;
+ case "鍏嚭绠$悊":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index1",
+ });
+ break;
+ case "璇峰亣绠$悊":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index2",
+ });
+ break;
+ case "鍑哄樊绠$悊":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index3",
+ });
+ break;
+ case "鎶ラ攢绠$悊":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index4",
+ });
+ break;
+ case "閲囪喘瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index5",
+ });
+ break;
+ case "鎶ヤ环瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index6",
+ });
+ break;
+ case "鍙戣揣瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index7",
+ });
+ break;
+ case "浼氳璁剧疆":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetingSettings/index",
+ });
+ break;
+ case "浼氳鍒楄〃":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetingList/index",
+ });
+ break;
+ case "浼氳鐢宠":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetApplication/index",
+ });
+ break;
+ case "浼氳瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetExamine/index",
+ });
+ break;
+ case "浼氳鍙戝竷":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetPublish/index",
+ });
+ break;
+ case "浼氳鎬荤粨":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetSummary/index",
+ });
+ break;
+ case "浼氳鐪嬫澘":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetingBoard/index",
+ });
+ break;
+ case "閫氱煡鍏憡":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/noticeManagement/index",
+ });
+ break;
+ case "鐭ヨ瘑搴�":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/knowledgeBase/index",
+ });
+ break;
+ case "鐢ㄥ嵃绠$悊":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/sealManagement/index",
+ });
+ break;
+ case "瑙勭珷鍒跺害":
+ uni.navigateTo({
+ url: "/pages/managementMeetings/rulesRegulationsManagement/index",
+ });
+ break;
+
+ case "鍗忓悓瀹℃壒":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/index",
+ });
+ break;
+ case "瀹㈡埛鎷滆":
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/clientVisit/index",
+ });
+ break;
+ case "鐢熶骇璁㈠崟":
+ uni.navigateTo({
+ url: "/pages/productionManagement/productionOrder/index",
+ });
+ break;
+ case "鐢熶骇娲惧伐":
+ uni.navigateTo({
+ url: "/pages/productionManagement/productionDispatching/index",
+ });
+ break;
+ case "宸ュ簭鎺掍骇":
+ uni.navigateTo({
+ url: "/pages/productionManagement/processScheduling/index",
+ });
+ break;
+ case "鐢熶骇鏍哥畻":
+ uni.navigateTo({
+ url: "/pages/productionManagement/productionAccounting/index",
+ });
+ break;
+ case "璁惧鍙拌处":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/ledger/index",
+ });
+ break;
+ case "璁惧鎶ヤ慨":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/repair/index",
+ });
+ break;
+ case "璁惧淇濆吇":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/upkeep/index",
+ });
+ break;
+ case "璁惧宸℃":
+ uni.navigateTo({
+ url: "/pages/inspectionUpload/index",
+ });
+ break;
+ case "鍒嗘瀽杩芥函":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/faultAnalysis/index",
+ });
+ break;
+ case "鏅鸿兘娲惧崟":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/smartDispatch/index",
+ });
+ break;
+ case "浣滀笟鎸囧":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/sop/index",
+ });
+ break;
+ case "缁撴灉楠岃瘉":
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/verification/index",
+ });
+ break;
+ default:
+ uni.showToast({
+ title: `鐐瑰嚮浜�${item.label}`,
+ icon: "none",
+ });
+ }
+ };
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ onMounted(() => {
+ // 璁剧疆鐢ㄦ埛淇℃伅
+ userStore.getInfo();
+ });
+ const operationType = ref("");
+ onLoad(options => {
+ if (options.label) {
+ // 澶勭悊 URL 鍙傛暟鍙兘鍖呭惈鍏朵粬鏌ヨ鍙傛暟鐨勬儏鍐碉紙濡傦細鍗忓悓瀹℃壒?approveType=6锛�
+ // 鍙彁鍙� label 鍙傛暟鐨勫�硷紝鍘婚櫎鍙兘闄勫姞鐨勬煡璇㈠弬鏁�
+ let labelValue = options.label;
+ // 濡傛灉 label 鍖呭惈 ? 绗﹀彿锛屽彧鍙� ? 涔嬪墠鐨勯儴鍒�
+ if (labelValue.includes("?")) {
+ labelValue = labelValue.split("?")[0];
+ }
+ operationType.value = labelValue;
+ if (operationType.value === "鑰冨嫟绠$悊") {
+ commonItems.value = kaoqin;
+ } else if (operationType.value === "浼氳绠$悊") {
+ commonItems.value = huiyi;
+ } else if (operationType.value === "璐㈠姟绠$悊") {
+ commonItems.value = caiwu;
+ } else if (operationType.value === "鍗忓悓瀹℃壒") {
+ commonItems.value = kaoqinCaiwu;
+ operationType.value = "鍗忓悓瀹℃壒";
+ }
+ }
+ console.log(operationType.value);
+ console.log(commonItems.value);
+ });
+</script>
+
+
+<style scoped lang="scss">
+ .content {
+ background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%);
+ min-height: 100vh;
+ padding: 1.25rem;
+ /* 涓烘墍鏈夎澶囪缃熀纭�padding-top */
+ padding-top: 40px;
+ position: relative;
+
+ /* iOS璁惧浣跨敤env()鍑芥暟澶勭悊瀹夊叏鍖哄煙 */
+ padding-top: env(safe-area-inset-top);
+
+ /* 涓哄畨鍗撹澶囪缃洿澶х殑椤堕儴鍐呰竟璺� */
+ /* #ifdef APP-PLUS && !MP && !H5 */
+ padding-top: 45px;
+ /* #endif */
+
+ /* H5鍜屽皬绋嬪簭骞冲彴鐨勯�氱敤鏍峰紡 */
+ /* #ifdef H5 || MP */
+ padding-top: 30px;
+ /* #endif */
+
+ &::before {
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(41, 121, 255, 0.03)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
+ pointer-events: none;
+ z-index: -1;
+ }
+
+ &::after {
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: radial-gradient(
+ circle at 20% 80%,
+ rgba(41, 121, 255, 0.02) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ circle at 80% 20%,
+ rgba(156, 39, 176, 0.02) 0%,
+ transparent 50%
+ );
+ pointer-events: none;
+ z-index: -1;
+ }
+ }
+
+ .header-section {
+ margin-bottom: 1rem;
+ animation: fadeInDown 0.6s ease-out;
+ /* 涓哄畨鍗撹澶囬澶栬皟鏁村ご閮ㄤ綅缃� */
+ /* #ifdef APP-PLUS && !MP && !H5 */
+ margin-top: 10px;
+ /* #endif */
+ }
+
+ .currentFactory {
+ margin-top: 0.5rem;
+ margin-left: 0.25rem;
+ font-weight: 500;
+ display: flex;
+ }
+
+ .factoryName {
+ width: auto;
+ }
+
+ :deep(.u-text) {
+ align-items: center;
+ }
+
+ .hero-section {
+ margin-bottom: 1rem;
+ animation: fadeInUp 0.6s ease-out 0.1s both;
+ }
+
+ .bg-img {
+ width: 100%;
+ height: 8.75rem;
+ background-image: url("../static/images/banner/backview.png");
+ background-size: cover;
+ border-radius: 0.75rem;
+ position: relative;
+ overflow: hidden;
+ box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.15);
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: conic-gradient(
+ from 0deg,
+ transparent,
+ rgba(255, 255, 255, 0.1),
+ transparent,
+ rgba(255, 255, 255, 0.05),
+ transparent
+ );
+ animation: rotate 20s linear infinite;
+ }
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 7.5rem;
+ height: 7.5rem;
+ background: radial-gradient(
+ circle,
+ rgba(255, 255, 255, 0.15) 0%,
+ transparent 70%
+ );
+ border-radius: 50%;
+ transform: translate(2.5rem, -2.5rem);
+ }
+ }
+
+ .hero-content {
+ position: relative;
+ z-index: 1;
+ padding: 1.25rem 1.25rem 1.6rem 1.25rem;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ }
+
+ .hero-title {
+ color: #ffffff;
+ font-size: 1.625rem;
+ font-weight: 700;
+ letter-spacing: 0.03125rem;
+ text-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5);
+ }
+ .hero-subtitle {
+ font-size: 0.8125rem;
+ margin-top: 0.375rem;
+ }
+ .hero-wave {
+ height: 2.75rem;
+ }
+
+ .hero-subtitle {
+ color: rgba(255, 255, 255, 0.9);
+ font-size: 0.8125rem;
+ margin-top: 0.375rem;
+ font-weight: 400;
+ text-shadow: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.5);
+ }
+
+ .hero-wave {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 2.75rem;
+ background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'><path fill='%23ffffff' fill-opacity='0.2' d='M0,224L48,218.7C96,213,192,203,288,197.3C384,192,480,192,576,176C672,160,768,128,864,122.7C960,117,1056,139,1152,144C1248,149,1344,139,1392,133.3L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'></path></svg>")
+ no-repeat bottom center/cover;
+ pointer-events: none;
+ }
+
+ .notice-section {
+ margin-bottom: 1rem;
+ animation: fadeInUp 0.6s ease-out 0.2s both;
+ }
+
+ .notice {
+ width: 100%;
+ background: linear-gradient(135deg, #eaf2ff 0%, #bbdefb 100%);
+ border: 0.0625rem solid #e3f2fd;
+ border-radius: 0.75rem;
+ padding: 1rem;
+ box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.08);
+ position: relative;
+ overflow: hidden;
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: linear-gradient(
+ 45deg,
+ transparent,
+ rgba(255, 255, 255, 0.6),
+ transparent
+ );
+ animation: shine 4s infinite;
+ }
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 5rem;
+ height: 5rem;
+ background: radial-gradient(
+ circle,
+ rgba(255, 255, 255, 0.2) 0%,
+ transparent 70%
+ );
+ border-radius: 50%;
+ transform: translate(1.875rem, -1.875rem);
+ }
+
+ &:hover {
+ transform: translateY(-0.125rem);
+ box-shadow: 0 0.5rem 1.875rem rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ @keyframes shine {
+ 0% {
+ transform: translateX(-100%) translateY(-100%) rotate(45deg);
+ }
+ 100% {
+ transform: translateX(100%) translateY(100%) rotate(45deg);
+ }
+ }
+
+ @keyframes fadeInDown {
+ from {
+ opacity: 0;
+ transform: translateY(-1.25rem);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(1.25rem);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes fadeInScale {
+ 0% {
+ opacity: 0;
+ transform: translateY(0.5rem) scale(0.96);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+ }
+
+ .notice-content {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ position: relative;
+ z-index: 1;
+ }
+
+ .notice-left {
+ margin-right: 1rem;
+ }
+
+ .notice-status {
+ font-weight: 600;
+ font-size: 1rem;
+ color: #1976d2;
+ }
+
+ .notice-separator {
+ width: 0.0625rem;
+ height: 1.5rem;
+ background: #e0e0e0;
+ margin-right: 1rem;
+ }
+
+ .notice-right {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex: 1;
+ }
+
+ .notice-label {
+ color: #333;
+ font-size: 0.875rem;
+ font-weight: 500;
+ margin-right: 0.75rem;
+ }
+
+ .notice-text {
+ font-weight: 400;
+ font-size: 0.875rem;
+ color: #666666;
+ }
+
+ .notice-number {
+ font-weight: 600;
+ font-size: 1rem;
+ color: #1976d2;
+ margin-left: 0.25rem;
+ }
+
+ .notice-unit {
+ font-weight: 600;
+ font-size: 1rem;
+ color: #1976d2;
+ margin-left: 0.25rem;
+ }
+
+ /* 鍔熻兘妯″潡鏍峰紡 */
+ .common-module {
+ margin-bottom: 1.5rem;
+ background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
+ border-radius: 1rem;
+ padding: 1rem;
+ box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06);
+ border: none;
+ position: relative;
+ overflow: hidden;
+ transition: all 0.3s ease;
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 3.75rem;
+ height: 3.75rem;
+ background: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 0.02) 0%,
+ transparent 70%
+ );
+ border-radius: 50%;
+ transform: translate(1.875rem, -1.875rem);
+ }
+ }
+
+ .marketing-module {
+ --module-color: #2979ff;
+ }
+
+ .purchase-module {
+ --module-color: #1976d2;
+ }
+
+ .collaboration-module {
+ --module-color: #4caf50;
+ }
+
+ .production-module {
+ --module-color: #ff9800;
+ }
+
+ .equipment-module {
+ --module-color: #9c27b0;
+ }
+
+ .module-header {
+ margin-bottom: 1.5rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .module-title-container {
+ display: flex;
+ align-items: center;
+ }
+
+ .module-title {
+ color: #333333;
+ font-size: 1.125rem;
+ font-weight: 600;
+ position: relative;
+ }
+
+ .module-subtitle {
+ color: #666666;
+ font-size: 0.75rem;
+ font-weight: 400;
+ margin-left: 0.5rem;
+ }
+
+ .module-content {
+ width: 100%;
+ display: grid;
+ gap: 1rem;
+ }
+
+ .icon-container {
+ width: 3.25rem;
+ height: 3.25rem;
+ border-radius: 0.75rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 0.375rem;
+ box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12);
+ transition: all 0.2s ease;
+ position: relative;
+ overflow: hidden;
+ animation: fadeInScale 0.5s ease both;
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 255, 255, 0.1) 0%,
+ transparent 50%,
+ rgba(255, 255, 255, 0.05) 100%
+ );
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ }
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border-radius: 0.75rem;
+ background: linear-gradient(
+ 45deg,
+ transparent,
+ rgba(255, 255, 255, 0.2),
+ transparent
+ );
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ }
+
+ &:hover {
+ transform: translateY(-0.1875rem) scale(1.02);
+ box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18);
+
+ &::before,
+ &::after {
+ opacity: 1;
+ }
+ }
+
+ &:active {
+ transform: scale(0.97);
+ box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18);
+ }
+ }
+
+ .item-label {
+ font-size: 0.8125rem;
+ color: #555555;
+ text-align: center;
+ display: block;
+ line-height: 1.4;
+ font-weight: 500;
+ margin-top: 0.25rem;
+ margin-bottom: 0.625rem;
+ }
+
+ .grid-text {
+ font-size: 0.875rem;
+ color: #909399;
+ padding: 0.625rem 0 1.25rem 0;
+ /* #ifndef APP-PLUS */
+ box-sizing: border-box;
+ /* #endif */
+ }
+
+ /* 鏆楄壊妯″紡閫傞厤 */
+ @media (prefers-color-scheme: dark) {
+ .content {
+ background: linear-gradient(135deg, #121317 0%, #161a20 100%);
+ }
+ .content::before {
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255, 255, 255, 0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
+ }
+ .common-module {
+ background: linear-gradient(135deg, #1e1f24 0%, #23252b 100%);
+ box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35);
+ }
+ .module-title {
+ color: #e9edf3;
+ }
+ .module-subtitle,
+ .item-label,
+ .notice-text,
+ .notice-unit,
+ .notice-label {
+ color: #c7cbd3;
+ }
+ .notice {
+ background: linear-gradient(135deg, #1b2330 0%, #1a2432 100%);
+ border-color: rgba(255, 255, 255, 0.06);
+ box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4);
+ }
+ .notice-status,
+ .notice-number {
+ color: #8ab4ff;
+ }
+ .bg-img {
+ background: linear-gradient(135deg, #1f4fb9 0%, #0e3a8a 100%);
+ }
+ }
+
+ @keyframes rotate {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes fadeInDown {
+ from {
+ opacity: 0;
+ transform: translateY(-1.25rem);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(1.25rem);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes fadeInScale {
+ 0% {
+ opacity: 0;
+ transform: translateY(0.5rem) scale(0.96);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+ }
+
+ .notice-left {
+ margin-right: 1rem;
+ }
+ .notice-status {
+ font-size: 1rem;
+ }
+ .notice-separator {
+ width: 0.0625rem;
+ height: 1.5rem;
+ margin-right: 1rem;
+ }
+ .notice-label {
+ font-size: 0.875rem;
+ margin-right: 0.75rem;
+ }
+ .notice-text {
+ font-size: 0.875rem;
+ }
+ .notice-number {
+ font-size: 1rem;
+ margin-left: 0.25rem;
+ }
+ .notice-unit {
+ font-size: 0.875rem;
+ margin-left: 0.125rem;
+ }
+
+ .common-module {
+ margin-bottom: 1.5rem;
+ background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
+ border-radius: 1rem;
+ padding: 1rem;
+ box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06);
+ border: none;
+ position: relative;
+ overflow: hidden;
+ transition: all 0.3s ease;
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 3.75rem;
+ height: 3.75rem;
+ background: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 0.02) 0%,
+ transparent 70%
+ );
+ border-radius: 50%;
+ transform: translate(1.875rem, -1.875rem);
+ }
+ }
+
+ .marketing-module {
+ --module-color: #2979ff;
+ }
+
+ .purchase-module {
+ --module-color: #1976d2;
+ }
+
+ .collaboration-module {
+ --module-color: #4caf50;
+ }
+
+ .production-module {
+ --module-color: #ff9800;
+ }
+
+ .equipment-module {
+ --module-color: #9c27b0;
+ }
+
+ .module-header {
+ margin-bottom: 1.5rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .module-title-container {
+ display: flex;
+ align-items: center;
+ }
+
+ .module-title {
+ color: #333333;
+ font-size: 1.125rem;
+ font-weight: 600;
+ position: relative;
+ }
+
+ .module-subtitle {
+ color: #666666;
+ font-size: 0.75rem;
+ font-weight: 400;
+ margin-left: 0.5rem;
+ }
+
+ .module-content {
+ width: 100%;
+ display: grid;
+ gap: 1rem;
+ }
+
+ .icon-container {
+ width: 3.25rem;
+ height: 3.25rem;
+ border-radius: 0.75rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 0.375rem;
+ box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12);
+ transition: all 0.2s ease;
+ position: relative;
+ overflow: hidden;
+ animation: fadeInScale 0.5s ease both;
+
+ &:hover {
+ transform: translateY(-0.1875rem) scale(1.02);
+ box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18);
+ }
+
+ &:active {
+ transform: scale(0.97);
+ box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18);
+ }
+ }
+
+ .item-label {
+ font-size: 0.8125rem;
+ margin-top: 0.25rem;
+ margin-bottom: 0.625rem;
+ }
+ .grid-text {
+ font-size: 0.875rem;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .common-module {
+ box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35);
+ }
+ .notice {
+ box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4);
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/knowledgeBase/detail.vue b/src/pages/managementMeetings/knowledgeBase/detail.vue
new file mode 100644
index 0000000..a79e4bc
--- /dev/null
+++ b/src/pages/managementMeetings/knowledgeBase/detail.vue
@@ -0,0 +1,500 @@
+<template>
+ <view class="client-visit-detail">
+ <PageHeader :title="detailType === 1 ? '鏂板鐭ヨ瘑搴�' : '鐭ヨ瘑搴撹鎯�'"
+ @back="goBack" />
+ <u-form ref="formRef"
+ label-width="90">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <!-- <u-cell-group title="鐭ヨ瘑淇℃伅"> -->
+ <u-form-item label="鐭ヨ瘑鏍囬"
+ prop="title"
+ required
+ border-bottom>
+ <u-input v-model="form.title"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ョ煡璇嗘爣棰�" />
+ </u-form-item>
+ <u-form-item label="鐭ヨ瘑绫诲瀷"
+ prop="type"
+ required
+ border-bottom>
+ <u-input v-model="equipmentname"
+ readonly
+ placeholder="璇烽�夋嫨鐭ヨ瘑绫诲瀷"
+ @click="showEquipmentSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="openEquipmentSheet"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="閫傜敤鍦烘櫙"
+ prop="scenario"
+ border-bottom>
+ <u-input v-model="form.scenario"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ラ�傜敤鍦烘櫙" />
+ </u-form-item>
+ <u-form-item label="瑙e喅鏁堢巼"
+ prop="status"
+ border-bottom>
+ <u-input v-model="statusname"
+ readonly
+ placeholder="璇烽�夋嫨瑙e喅鏁堢巼"
+ @click="showStatusSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="showStatusSheet = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="闂鎻忚堪"
+ required
+ prop="remark"
+ border-bottom>
+ <u-textarea v-model="form.problem"
+ type="textarea"
+ rows="4"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ラ棶棰樻弿杩�" />
+ </u-form-item>
+ <u-form-item label="瑙e喅鏂规"
+ prop="solution"
+ required
+ border-bottom>
+ <u-textarea v-model="form.solution"
+ type="textarea"
+ rows="4"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ヨВ鍐虫柟妗�" />
+ </u-form-item>
+ <u-form-item label="鍏抽敭瑕佺偣"
+ prop="keyPoints"
+ border-bottom>
+ <u-textarea v-model="form.keyPoints"
+ type="textarea"
+ rows="4"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ュ叧閿鐐癸紝鐢ㄩ�楀彿鍒嗛殧" />
+ </u-form-item>
+ <u-form-item label="鍒涘缓浜�"
+ prop="creator"
+ border-bottom>
+ <u-input v-model="form.creator"
+ readonly
+ placeholder="璇烽�夋嫨鍒涘缓浜�"
+ @click="openCreatorSheet" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="openCreatorSheet"></up-icon>
+ </template>
+ <!-- <u-input v-model="form.creator"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ュ垱寤轰汉" /> -->
+ </u-form-item>
+ <u-form-item label="浣跨敤娆℃暟"
+ prop="usageCount"
+ border-bottom>
+ <uni-number-box v-model="form.usageCount"
+ :min="0"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ヤ娇鐢ㄦ鏁�" />
+ </u-form-item>
+ <!-- </u-cell-group> -->
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view v-if="!readonly"
+ class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="sign-btn"
+ type="primary"
+ @click="handleSubmit"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+ <up-action-sheet :show="showEquipmentSheet"
+ :actions="equipmentOptions"
+ @select="handleEquipmentChange"
+ @close="showEquipmentSheet = false" />
+ <up-action-sheet :show="showCreatorSheet"
+ :actions="creatorOptions"
+ @select="handleCreatorChange"
+ @close="showCreatorSheet = false" />
+ <!-- <u-popup :show="showEquipmentSheet"
+ mode="bottom"
+ @close="showEquipmentSheet = false"
+ height="200px">
+ <view class="popup-content">
+ <view class="popup-body">
+ <u-checkbox-group v-model="form.equipment"
+ @change="handleEquipmentChange"
+ icon-placement="right"
+ placement="row">
+ <view style="width:100%;padding:10px;margin-top:20px;">
+ <u-checkbox v-for="option in equipmentOptions"
+ :key="option.value"
+ :name="option.value"
+ :label="option.name"
+ class="checkbox-item"></u-checkbox>
+ </view>
+ </u-checkbox-group>
+ </view>
+ </view>
+ </u-popup> -->
+ <!-- 鐘舵�侀�夋嫨鍣� -->
+ <up-action-sheet :show="showStatusSheet"
+ :actions="statusOptions"
+ @select="onStatusSelect"
+ @close="showStatusSheet = false" />
+ </view>
+</template>
+
+<script setup>
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "meeting-settings-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import { ref, onMounted, computed } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { useDict } from "@/utils/dict";
+ import { onLoad } from "@dcloudio/uni-app";
+ import {
+ addKnowledgeBase,
+ updateKnowledgeBase,
+ } from "@/api/managementMeetings/knowledgeBase";
+ import { userListNoPageByTenantId } from "@/api/system/user";
+
+ const userStore = useUserStore();
+
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ title: "",
+ type: "",
+ scenario: "",
+ efficiency: "",
+ problem: "",
+ solution: "",
+ keyPoints: "",
+ creator: "",
+ usageCount: 0,
+ });
+ const { knowledge_type } = useDict("knowledge_type");
+ const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+ const equipmentOptions = ref([]);
+ const statusOptions = ref([
+ { value: "high", name: "鏄捐憲鎻愬崌" },
+ { value: "medium", name: "涓�鑸彁鍗�" },
+ { value: "low", name: "杞诲井鎻愬崌" },
+ ]);
+ //// 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
+ const showEquipmentSheet = ref(false);
+ const showStatusSheet = ref(false);
+ const openEquipmentSheet = () => {
+ showEquipmentSheet.value = true;
+ };
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const statusname = ref("");
+ // 鐘舵�侀�夋嫨
+ const onStatusSelect = action => {
+ form.value.efficiency = action.value;
+ statusname.value = action.name;
+ showStatusSheet.value = false;
+ };
+ const showCreatorSheet = ref(false);
+ const creatorOptions = ref([]);
+ const openCreatorSheet = () => {
+ showCreatorSheet.value = true;
+ };
+ const getCreatorOptions = async () => {
+ try {
+ const res = await userListNoPageByTenantId();
+ if (res.code === 200) {
+ creatorOptions.value = res.data || [];
+ creatorOptions.value.forEach(item => {
+ item.name = item.nickName;
+ item.value = item.userId;
+ });
+ } else {
+ showToast("鑾峰彇鍒涘缓浜哄垪琛ㄥけ璐�");
+ }
+ } catch (e) {
+ console.error("鑾峰彇鍒涘缓浜哄垪琛ㄥけ璐�:", e);
+ showToast("鑾峰彇鍒涘缓浜哄垪琛ㄥけ璐�");
+ }
+ };
+ // 鍒涘缓浜洪�夋嫨
+ const handleCreatorChange = val => {
+ form.value.creator = val.name;
+ };
+ const equipmentname = ref("");
+ // 璁惧閰嶇疆閫夋嫨
+ const handleEquipmentChange = val => {
+ form.value.type = val.value;
+ equipmentname.value = val.name;
+ showEquipmentSheet.value = false;
+ };
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = async () => {
+ if (!form.value.title) {
+ showToast("璇疯緭鍏ユ爣棰�");
+ return;
+ }
+
+ if (!form.value.scenario) {
+ showToast("璇疯緭鍏ラ�傜敤鍦烘櫙");
+ return;
+ }
+
+ if (!form.value.problem) {
+ showToast("璇疯緭鍏ラ棶棰樻弿杩�");
+ return;
+ }
+ if (!form.value.solution) {
+ showToast("璇疯緭鍏ヨВ鍐虫柟妗�");
+ return;
+ }
+ try {
+ loading.value = true;
+ if (detailType.value === 1) {
+ addKnowledgeBase(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ } else if (detailType.value === 2) {
+ updateKnowledgeBase(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ }
+ } catch (e) {
+ loading.value = false;
+ console.error("淇濆瓨澶辫触:", e);
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ }
+ };
+
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const initPageData = () => {
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇浼氳 room 鏁版嵁
+ const meetingRoom = uni.getStorageSync("meetingRoom");
+ if (meetingRoom) {
+ form.value = JSON.parse(JSON.stringify(meetingRoom));
+ if (meetingRoom.equipment) {
+ if (Array.isArray(meetingRoom.equipment)) {
+ form.value.equipment = meetingRoom.equipment;
+ } else {
+ form.value.equipment = meetingRoom.equipment.split(",");
+ }
+ }
+ statusname.value = meetingRoom.status === 1 ? "鍚敤" : "绂佺敤";
+
+ // 娓呴櫎鏈湴瀛樺偍涓殑鏁版嵁锛岄伩鍏嶄笅娆℃墦寮�鏃朵粛鐒舵樉绀�
+ uni.removeStorageSync("meetingRoom");
+ }
+ };
+ const readonly = ref(false);
+ const detailType = ref(1);
+ const knowledgeId = ref("");
+
+ onLoad(options => {
+ detailType.value = Number(options.detailType);
+ knowledgeId.value = options.id || "";
+
+ // 濡傛灉鏄紪杈戞垨鏌ョ湅妯″紡锛岃幏鍙栫煡璇嗚鎯�
+ if (knowledgeId.value && (detailType.value === 2 || detailType.value === 3)) {
+ // getKnowledgeDetail(knowledgeId.value);
+ equipmentname.value =
+ equipmentOptions.value.find(item => item.value === form.value.type)
+ ?.name || "";
+ statusname.value =
+ statusOptions.value.find(item => item.value === form.value.efficiency)
+ ?.name || "";
+ }
+
+ // 鏌ョ湅妯″紡璁剧疆鍙
+ if (detailType.value === 3) {
+ readonly.value = true;
+ }
+ });
+
+ onMounted(() => {
+ getCreatorOptions();
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇鐭ヨ瘑鏁版嵁
+ const knowledgeBase = uni.getStorageSync("knowledgeBase");
+ if (knowledgeBase) {
+ form.value = JSON.parse(JSON.stringify(knowledgeBase));
+ }
+
+ initPageData();
+ equipmentOptions.value = knowledgeTypeOptions.value.map(item => ({
+ value: item.value,
+ name: item.label,
+ }));
+ if (detailType.value === 1) {
+ form.value = {
+ title: "",
+ type: "",
+ scenario: "",
+ efficiency: "",
+ problem: "",
+ solution: "",
+ keyPoints: "",
+ creator: "",
+ usageCount: 0,
+ };
+ equipmentname.value = "";
+ statusname.value = "";
+ }
+
+ if (detailType.value != 1) {
+ equipmentname.value =
+ equipmentOptions.value.find(item => item.value === form.value.type)
+ ?.name || "";
+ statusname.value =
+ statusOptions.value.find(item => item.value === form.value.efficiency)
+ ?.name || "";
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+ .client-visit {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
+
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #666;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .sign-btn {
+ font-weight: 500;
+ font-size: 1rem;
+ color: #fff;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border: none;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .location-icon {
+ color: #1989fa;
+ font-size: 1.2rem;
+ }
+
+ .selector-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ height: 100%;
+ }
+
+ .selector-text {
+ font-size: 14px;
+ color: #333;
+ }
+
+ .popup-content {
+ padding: 20rpx;
+ }
+
+ .popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+ }
+
+ .popup-title {
+ font-size: 16px;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .close-icon {
+ font-size: 20px;
+ color: #999;
+ }
+
+ .popup-body {
+ max-height: 60vh;
+ overflow-y: auto;
+ margin-bottom: 20rpx;
+ }
+
+ .checkbox-item {
+ margin-bottom: 15rpx;
+ font-size: 14px;
+ }
+
+ .popup-footer {
+ display: flex;
+ justify-content: space-between;
+ gap: 15rpx;
+ }
+
+ .cancel-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+
+ .confirm-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+ .checkbox-item {
+ margin-top: 40rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/knowledgeBase/index.vue b/src/pages/managementMeetings/knowledgeBase/index.vue
new file mode 100644
index 0000000..ff78fdb
--- /dev/null
+++ b/src/pages/managementMeetings/knowledgeBase/index.vue
@@ -0,0 +1,310 @@
+<template>
+ <view class="sales-accoun">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鐭ヨ瘑搴�"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ョ煡璇嗘爣棰�"
+ v-model="name"
+ @blur="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <u-icon name="search"
+ size="24"
+ color="#999"></u-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鎷滆璁板綍鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="visitList.length > 0">
+ <view v-for="(item, index) in visitList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">鐭ヨ瘑鏍囬锛歿{ item.title || '-' }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐭ヨ瘑绫诲瀷</text>
+ <text class="detail-value">{{ formatReceiptType(item.type) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">閫傜敤鍦烘櫙</text>
+ <text class="detail-value">{{ item.scenario || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙e喅鏁堢巼</text>
+ <u-tag size="mini"
+ :type="getTagClass(item.efficiency)">{{ formatReceiptType1(item.efficiency) }}</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浣跨敤娆℃暟</text>
+ <text class="detail-value">{{ item.usageCount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍒涘缓浜�</text>
+ <text class="detail-value">{{ item.creator }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍒涘缓鏃堕棿</text>
+ <text class="detail-value">{{ item.createTime }}</text>
+ </view>
+ </view>
+ <!-- 鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <u-button type="info"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item,3)">
+ 鏌ョ湅
+ </u-button>
+ <!-- <u-button type="error"
+ size="small"
+ class="action-btn"
+ @click="confirmDelete(item)">
+ 鍒犻櫎
+ </u-button>
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item,2)">
+ 缂栬緫
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鐭ヨ瘑璁板綍</text>
+ </view>
+ <!-- 娴姩鏂板鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="addVisit">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, computed } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { useDict } from "@/utils/dict";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ listKnowledgeBase,
+ delKnowledgeBase,
+ } from "@/api/managementMeetings/knowledgeBase";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-index" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+
+ // 鎼滅储鍏抽敭璇�
+ const name = ref("");
+
+ // 鎷滆璁板綍鏁版嵁
+ const visitList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const { knowledge_type } = useDict("knowledge_type");
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ return getKnowledgeTypeLabel(params);
+ };
+ const formatReceiptType1 = params => {
+ if (params == "high") {
+ return "鏄捐憲鎻愬崌";
+ } else if (params == "medium") {
+ return "涓�鑸彁鍗�";
+ } else if (params == "low") {
+ return "杞诲井鎻愬崌";
+ } else {
+ return "鏈煡";
+ }
+ };
+ const getTagClass = type => {
+ if (type == "high") {
+ return "success";
+ } else if (type == "medium") {
+ return "warning";
+ } else if (type == "low") {
+ return "info";
+ } else {
+ return "info";
+ }
+ };
+ const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+ // 鑾峰彇鐭ヨ瘑绫诲瀷鏍囩
+ const getKnowledgeTypeLabel = val => {
+ console.log(knowledgeTypeOptions, "knowledgeTypeOptions");
+ const item = knowledgeTypeOptions.value.find(
+ i => String(i.value) === String(val)
+ );
+ return item ? item.label : val;
+ };
+
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ title: name.value,
+ };
+ listKnowledgeBase(params)
+ .then(res => {
+ visitList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const addVisit = () => {
+ uni.navigateTo({
+ url: "/pages/managementMeetings/knowledgeBase/detail?detailType=1",
+ });
+ };
+
+ // 缂栬緫
+ const viewDetail = (item, detailType) => {
+ uni.setStorageSync("knowledgeBase", item);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/knowledgeBase/detail?detailType=" +
+ detailType +
+ "&id=" +
+ item.id,
+ });
+ };
+
+ // 鍒犻櫎纭
+ const confirmDelete = item => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄ょ煡璇� "${item.title}" 鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ deleteKnowledge(item.id);
+ }
+ },
+ });
+ };
+
+ // 鎵ц鍒犻櫎
+ const deleteKnowledge = id => {
+ showLoadingToast("鍒犻櫎涓�...");
+ delKnowledgeBase([id])
+ .then(res => {
+ closeToast();
+ if (res.code === 200) {
+ showToast("鍒犻櫎鎴愬姛");
+ getList(); // 閲嶆柊鑾峰彇鍒楄〃
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鍒犻櫎澶辫触");
+ });
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+ .sales-accoun {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ padding-bottom: 80px;
+ }
+
+ // 鐗瑰畾鐨勫浘鏍囨牱寮�
+ .document-icon {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ }
+
+ // 鐗规湁鏍峰紡
+ .visit-status {
+ display: flex;
+ align-items: center;
+ }
+
+ .detail-value {
+ word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+ color: #333; // 淇濇寔椤甸潰鐗规湁鐨勬枃鏈鑹�
+ }
+
+ // 鐘舵�佹牱寮�
+ .status-enabled {
+ color: #28a745; // 淇濇寔椤甸潰鐗规湁鐨勬垚鍔熼鑹�
+ }
+
+ .status-disabled {
+ color: #dc3545; // 淇濇寔椤甸潰鐗规湁鐨勯敊璇鑹�
+ }
+
+ // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+ .fab-button {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+ }
+</style>
+
diff --git a/src/pages/managementMeetings/meetApplication/index.vue b/src/pages/managementMeetings/meetApplication/index.vue
new file mode 100644
index 0000000..22bf041
--- /dev/null
+++ b/src/pages/managementMeetings/meetApplication/index.vue
@@ -0,0 +1,499 @@
+<template>
+ <view style="background-color: #fff;"
+ class="client-visit-detail">
+ <PageHeader title="浼氳鐢宠"
+ @back="goBack" />
+ <view>
+ <view v-for="item in applicationTypes"
+ :key="item.value"
+ class="application-type-item"
+ :class="{ active: meetingForm.applicationType === item.value }"
+ @click="selectApplicationType(item)">
+ <view class="application-type-info">
+ <view class="application-type-name">{{ item.name }}</view>
+ <view class="application-type-desc">{{ item.desc }}</view>
+ </view>
+ </view>
+ </view>
+ <u-form ref="formRef"
+ label-width="90">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <u-cell-group title="浼氳鐢宠">
+ <u-form-item label="浼氳涓婚"
+ prop="title"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.title"
+ placeholder="璇疯緭鍏ヤ細璁富棰�" />
+ </u-form-item>
+ <u-form-item label="浼氳瀹�"
+ prop="roomId"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.roomName"
+ placeholder="璇烽�夋嫨浼氳瀹�"
+ readonly
+ @click="showRoomPicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showRoomPicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="涓绘寔浜�"
+ prop="host"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.host"
+ placeholder="璇疯緭鍏ヤ富鎸佷汉濮撳悕" />
+ </u-form-item>
+ <u-form-item label="浼氳鏃ユ湡"
+ prop="meetingDate"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.meetingDate"
+ placeholder="璇烽�夋嫨浼氳鏃ユ湡"
+ readonly
+ @click="showDatePicker = true" />
+ <template #right>
+ <up-icon name="calendar"
+ @click="showDatePicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="寮�濮嬫椂闂�"
+ prop="startTime"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.startTime"
+ placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+ readonly
+ @click="showStartTimePicker = true" />
+ <template #right>
+ <up-icon name="clock"
+ @click="showStartTimePicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="缁撴潫鏃堕棿"
+ prop="endTime"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.endTime"
+ placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
+ readonly
+ @click="showEndTimePicker = true" />
+ <template #right>
+ <up-icon name="clock"
+ @click="showEndTimePicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鍙備細浜哄憳"
+ prop="participants"
+ required
+ border-bottom>
+ <u-input v-model="meetingForm.participantsNames"
+ placeholder="璇烽�夋嫨鍙備細浜哄憳"
+ readonly
+ @click="showEquipmentSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openParticipantPicker"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="浼氳璇存槑"
+ prop="description"
+ border-bottom>
+ <u-input v-model="meetingForm.description"
+ placeholder="璇疯緭鍏ヤ細璁鏄�" />
+ </u-form-item>
+ </u-cell-group>
+ <!-- 鎻愪氦鎸夐挳 -->
+ </u-form>
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="resetForm">閲嶇疆</u-button>
+ <u-button class="save-btn"
+ @click="handleSubmit">淇濆瓨</u-button>
+ </view>
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <up-datetime-picker v-model="meetingForm.meetingDate"
+ mode="date"
+ :show="showDatePicker"
+ @confirm="onDateSelect"
+ @cancel="showDatePicker = false"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ :min-date="minDate" />
+ <!-- 寮�濮嬫椂闂撮�夋嫨鍣� -->
+ <up-action-sheet :show="showStartTimePicker"
+ :actions="timeOptions"
+ @select="onStartTimeSelect"
+ @close="showStartTimePicker = false" />
+ <!-- 缁撴潫鏃堕棿閫夋嫨鍣� -->
+ <up-action-sheet :show="showEndTimePicker"
+ :actions="timeOptions"
+ @select="onEndTimeSelect"
+ @close="showEndTimePicker = false" />
+ <!-- 浼氳瀹ら�夋嫨鍣� -->
+ <up-action-sheet :show="showRoomPicker"
+ :actions="meetingRooms"
+ @select="onRoomSelect"
+ @close="showRoomPicker = false" />
+ <u-popup :show="showEquipmentSheet"
+ mode="bottom"
+ @close="showEquipmentSheet = false"
+ height="200px">
+ <view class="popup-content">
+ <view class="popup-body">
+ <u-checkbox-group v-model="meetingForm.participants"
+ @change="handleParticipantChange"
+ icon-placement="right"
+ placement="row">
+ <view style="width:100%;padding:10px;margin-top:20px;">
+ <u-checkbox v-for="option in employees"
+ :key="option.id"
+ :name="option.id"
+ :label="`${option.staffName} (${option.postName})`"
+ class="checkbox-item"></u-checkbox>
+ </view>
+ </u-checkbox-group>
+ </view>
+ </view>
+ </u-popup>
+ </view>
+</template>
+
+<script setup>
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "meeting-settings-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import { ref, reactive, onMounted, computed } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import {
+ saveMeetingApplication,
+ getRoomEnum,
+ } from "@/api/managementMeetings/meeting";
+ import { staffOnJobListPage } from "@/api/personnelManagement/onboarding";
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+
+ // 琛ㄥ崟鏁版嵁
+ const meetingForm = reactive({
+ title: "",
+ type: "",
+ roomId: "",
+ roomName: "",
+ host: "",
+ meetingDate: "",
+ startTime: "",
+ endTime: "",
+ participants: [],
+ description: "",
+ participantsNames: [],
+ applicationType: "department",
+ });
+ // 鐢宠绫诲瀷閫夐」
+ const applicationTypes = ref([
+ {
+ value: "approval",
+ name: "瀹℃壒娴佺▼浼氳",
+ desc: "闇�瑕佺粡杩囧绾у鎵圭殑浼氳鐢宠",
+ // icon: Document,
+ },
+ {
+ value: "department",
+ name: "閮ㄩ棬绾т細璁�",
+ desc: "閮ㄩ棬鍐呴儴浼氳鐢宠娴佺▼",
+ // icon: Promotion,
+ },
+ {
+ value: "notification",
+ name: "浼氳閫氱煡",
+ desc: "鏃犻渶瀹℃壒鐩存帴鍙戝竷鐨勪細璁�氱煡",
+ // icon: Bell,
+ },
+ ]);
+ // 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
+ const showDatePicker = ref(false);
+ const showStartTimePicker = ref(false);
+ const showEndTimePicker = ref(false);
+ const showRoomPicker = ref(false);
+
+ // 鏈�灏忔棩鏈燂紙浠婂ぉ锛�
+ const minDate = computed(() => {
+ return dayjs().format("YYYY-MM-DD");
+ });
+
+ // 閫夋嫨鐢宠绫诲瀷
+ const selectApplicationType = item => {
+ meetingForm.applicationType = item.value;
+ };
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const showEquipmentSheet = ref(false);
+ const openParticipantPicker = () => {
+ showEquipmentSheet.value = true;
+ };
+
+ // 閲嶇疆琛ㄥ崟
+ const resetForm = () => {
+ meetingForm.title = "";
+ meetingForm.type = "";
+ meetingForm.roomId = "";
+ meetingForm.roomName = "";
+ meetingForm.host = "";
+ meetingForm.meetingDate = "";
+ meetingForm.startTime = "";
+ meetingForm.endTime = "";
+ meetingForm.participants = [];
+ meetingForm.participantsNames = [];
+ meetingForm.description = "";
+ meetingForm.applicationType = "department";
+ };
+ const handleParticipantChange = val => {
+ console.log("val", val);
+
+ meetingForm.participants = val;
+ meetingForm.participantsNames = employees.value
+ .filter(employee => val.includes(employee.id))
+ .map(employee => employee.staffName);
+ };
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = async () => {
+ console.log("meetingForm", meetingForm);
+ if (!meetingForm.title) {
+ showToast("璇疯緭鍏ヤ細璁富棰�");
+ return;
+ }
+
+ if (!meetingForm.roomId) {
+ showToast("璇烽�夋嫨浼氳瀹�");
+ return;
+ }
+
+ if (!meetingForm.host) {
+ showToast("璇疯緭鍏ヤ富鎸佷汉");
+ return;
+ }
+
+ if (!meetingForm.meetingDate) {
+ showToast("璇烽�夋嫨浼氳鏃ユ湡");
+ return;
+ }
+
+ if (!meetingForm.startTime) {
+ showToast("璇烽�夋嫨寮�濮嬫椂闂�");
+ return;
+ }
+
+ if (!meetingForm.endTime) {
+ showToast("璇烽�夋嫨缁撴潫鏃堕棿");
+ return;
+ }
+
+ if (!meetingForm.participants) {
+ showToast("璇烽�夋嫨鍙備細浜哄憳");
+ return;
+ }
+
+ // 楠岃瘉寮�濮嬫椂闂村繀椤诲皬浜庣粨鏉熸椂闂�
+ if (meetingForm.startTime >= meetingForm.endTime) {
+ showToast("寮�濮嬫椂闂村繀椤诲皬浜庣粨鏉熸椂闂�");
+ return;
+ }
+
+ try {
+ loading.value = true;
+
+ let formData = { ...meetingForm };
+ formData.startTime = `${meetingForm.meetingDate} ${meetingForm.startTime}:00`;
+ formData.endTime = `${meetingForm.meetingDate} ${meetingForm.endTime}:00`;
+ formData.participants = JSON.stringify(meetingForm.participants);
+
+ console.log(formData);
+
+ // 璋冪敤瀹為檯鐨凙PI
+ const res = await saveMeetingApplication(formData);
+
+ if (res.code === 200) {
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ } else {
+ showToast(res.message || "淇濆瓨澶辫触锛岃閲嶈瘯");
+ }
+ } catch (e) {
+ console.error("淇濆瓨澶辫触:", e);
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ } finally {
+ loading.value = false;
+ }
+ };
+ // 鏃ユ湡閫夋嫨鍣ㄧ‘璁ゅ洖璋�
+ const onDateSelect = action => {
+ console.log(action.value);
+
+ if (action.value) {
+ meetingForm.meetingDate = dayjs(action.value).format("YYYY-MM-DD");
+ } else {
+ meetingForm.meetingDate = dayjs().format("YYYY-MM-DD");
+ }
+
+ showDatePicker.value = false;
+ };
+ const onStartTimeSelect = action => {
+ meetingForm.startTime = action.value;
+ showStartTimePicker.value = false;
+ };
+ const onEndTimeSelect = action => {
+ meetingForm.endTime = action.value;
+ showEndTimePicker.value = false;
+ };
+
+ // 浼氳瀹ら�夋嫨鍥炶皟
+ const onRoomSelect = action => {
+ meetingForm.roomId = action.id;
+ meetingForm.roomName = action.name;
+ showRoomPicker.value = false;
+ };
+ // 鏃堕棿閫夐」锛堜互鍗婂皬鏃朵负闂撮殧锛�
+ const timeOptions = ref([]);
+
+ // 鍒濆鍖栨椂闂撮�夐」
+ const initTimeOptions = () => {
+ const options = [];
+ for (let hour = 8; hour <= 18; hour++) {
+ // 姣忎釜灏忔椂娣诲姞涓や釜閫夐」锛氭暣鐐瑰拰鍗婄偣
+ options.push({
+ value: `${hour.toString().padStart(2, "0")}:00`,
+ name: `${hour.toString().padStart(2, "0")}:00`,
+ });
+
+ if (hour < 18) {
+ // 18:00涔嬪悗娌℃湁鍗婄偣閫夐」
+ options.push({
+ value: `${hour.toString().padStart(2, "0")}:30`,
+ name: `${hour.toString().padStart(2, "0")}:30`,
+ });
+ }
+ }
+ timeOptions.value = options;
+ };
+ // 浼氳瀹ゅ垪琛�
+ const employees = ref([]);
+ const meetingRooms = ref([]);
+ const getMeetingRooms = async () => {
+ try {
+ const res = await getRoomEnum();
+ if (res.code === 200) {
+ meetingRooms.value = res.data || [];
+ } else {
+ showToast(res.message || "鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐�");
+ }
+ } catch (e) {
+ console.error("鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐�:", e);
+ showToast("鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐ワ紝璇烽噸璇�");
+ }
+ };
+
+ onMounted(() => {
+ initPageData();
+ initTimeOptions();
+ getMeetingRooms();
+ staffOnJobListPage().then(res => {
+ console.log(res.data.records, "res.data.records");
+ employees.value = res.data.records.sort((a, b) =>
+ a.postName.localeCompare(b.postName)
+ );
+ console.log(employees.value, "employees.value");
+ });
+ });
+
+ const initPageData = () => {
+ // 鍒濆鍖栨暟鎹�
+ };
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+ .application-type-item {
+ width: 94%;
+ margin-left: 3%;
+ // height: 120rpx;
+ background-color: #f1f1f1;
+ border-radius: 10rpx;
+ margin-top: 20rpx;
+ padding: 20rpx;
+ box-shadow: 0 2rpx 12rpx 0 rgba(246, 244, 244, 0.1);
+ transition: box-shadow 0.3s ease;
+ }
+ .application-type-item.active {
+ box-shadow: 0 4rpx 16rpx 0 rgba(0, 0, 0, 0.15);
+ background-color: #fff;
+ border: 1rpx solid #0078a3;
+ }
+
+ .application-type-name {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #000000;
+ }
+ .application-type-item.active .application-type-name {
+ color: #0078a3;
+ }
+ .application-type-desc {
+ font-weight: 400;
+ font-size: 0.875rem;
+ margin-top: 0.5rem;
+ color: #757575;
+ }
+ .application-type-item.active .application-type-desc {
+ color: #0078a3;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetExamine/approve.vue b/src/pages/managementMeetings/meetExamine/approve.vue
new file mode 100644
index 0000000..3ef296d
--- /dev/null
+++ b/src/pages/managementMeetings/meetExamine/approve.vue
@@ -0,0 +1,470 @@
+<template>
+ <view class="approve-page">
+ <PageHeader title="瀹℃壒"
+ @back="goBack" />
+ <!-- 鐢宠淇℃伅 -->
+ <view class="application-info">
+ <view class="info-header">
+ <text class="info-title">浼氳淇℃伅</text>
+ </view>
+ <view class="info-content">
+ <view class="info-row">
+ <text class="info-label">浼氳涓婚</text>
+ <text class="info-value">{{ approvalData.title }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鐢宠浜�</text>
+ <text class="info-value">{{ approvalData.applicant }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">涓荤悊浜�</text>
+ <text class="info-value">{{ approvalData.host }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鏃堕棿</text>
+ <text class="info-value">{{ formatDateTime(approvalData.meetingTime) }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鍦扮偣</text>
+ <text class="info-value">{{ approvalData.location }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">瀹℃壒鐘舵��</text>
+ <text class="info-value tag"
+ :class="getTagClass(approvalData.approveNodeStatus)">
+ {{ formatReceiptType(approvalData.approveNodeStatus) }}
+ </text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜烘暟</text>
+ <text class="info-value">{{ approvalData.participants.length }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜哄憳</text>
+ <text class="info-value">{{ approvalData.participants.map(it => it.name).join("銆�") }}</text>
+ </view>
+ </view>
+ </view>
+ <!-- 搴曢儴鎿嶄綔鎸夐挳 -->
+ <view v-if="isEdit"
+ class="footer-actions">
+ <u-button class="reject-btn"
+ @click="handleReject">涓嶉�氳繃</u-button>
+ <u-button class="approve-btn"
+ @click="handleApprove">閫氳繃</u-button>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, computed } from "vue";
+ import { onLoad } from "@dcloudio/uni-app";
+ import { saveMeetingApplication } from "@/api/managementMeetings/meetExamine";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import PageHeader from "@/components/PageHeader.vue";
+
+ const approvalData = ref({});
+ const approvalSteps = ref([]);
+ const isEdit = ref(false);
+
+ onLoad(options => {
+ console.log(options, "options");
+ if (options.item) {
+ approvalData.value = JSON.parse(options.item);
+ }
+ if (options.edit) {
+ isEdit.value = options.edit === "true" ? true : false;
+ }
+ });
+
+ const goBack = () => {
+ uni.removeStorageSync("approveId");
+ uni.navigateBack();
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭鏍�";
+ } else if (params == 1) {
+ return "宸查�氳繃";
+ } else if (params == 2) {
+ return "鏈�氳繃";
+ } else if (params == 3) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "warning";
+ } else if (type == 3) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+ const submitForm = status => {
+ // 璋冪敤鍚庣
+ saveMeetingApplication({ id: approvalData.value.id, status: status })
+ .then(res => {
+ if (res.code === 200) {
+ showToast("瀹℃壒鎻愪氦鎴愬姛");
+ // 鎻愮ず鍚庤繑鍥炰笂涓�涓〉闈�
+ setTimeout(() => {
+ goBack(); // 鍐呴儴鏄� uni.navigateBack()
+ }, 800);
+ } else {
+ showToast(res.message || "瀹℃壒鎿嶄綔澶辫触锛岃閲嶈瘯");
+ }
+ })
+ .catch(error => {
+ console.error("瀹℃壒鎿嶄綔澶辫触:", error);
+ showToast("瀹℃壒鎿嶄綔澶辫触锛岃閲嶈瘯");
+ });
+ };
+
+ const handleApprove = () => {
+ uni.showModal({
+ title: "纭鎿嶄綔",
+ content: "纭畾瑕侀�氳繃璇ヤ細璁敵璇峰悧锛�",
+ success: res => {
+ if (res.confirm) submitForm(1);
+ },
+ });
+ };
+
+ const handleReject = () => {
+ uni.showModal({
+ title: "纭鎿嶄綔",
+ content: "纭畾涓嶉�氳繃璇ヤ細璁敵璇峰悧锛�",
+ success: res => {
+ if (res.confirm) submitForm(2);
+ },
+ });
+ };
+ // 鍘熷鑺傜偣鏁版嵁锛堢敤浜庢彁浜ら�昏緫锛�
+ const activities = ref([]);
+</script>
+
+<style scoped lang="scss">
+ .approve-page {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 80px;
+ }
+
+ .header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 16px 20px;
+ border-bottom: 1px solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ }
+
+ .title {
+ flex: 1;
+ text-align: center;
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .application-info {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .info-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .info-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .info-content {
+ padding: 16px;
+ }
+
+ .info-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 12px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .info-label {
+ font-size: 14px;
+ color: #666;
+ width: 80px;
+ flex-shrink: 0;
+ }
+
+ .info-value {
+ font-size: 14px;
+ color: #333;
+ flex: 1;
+ }
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .process-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .process-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .process-steps {
+ padding: 20px;
+ }
+
+ .process-step {
+ display: flex;
+ position: relative;
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+
+ .step-line {
+ display: none;
+ }
+ }
+ }
+
+ .step-indicator {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-right: 16px;
+ }
+
+ .step-dot {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ font-weight: 600;
+ position: relative;
+ z-index: 2;
+ }
+
+ .process-step.completed .step-dot {
+ background: #52c41a;
+ color: #fff;
+ }
+
+ .process-step.current .step-dot {
+ background: #1890ff;
+ color: #fff;
+ animation: pulse 2s infinite;
+ }
+
+ .process-step.pending .step-dot {
+ background: #d9d9d9;
+ color: #999;
+ }
+
+ .step-line {
+ width: 2px;
+ height: 40px;
+ background: #d9d9d9;
+ margin-top: 8px;
+ }
+
+ .process-step.completed .step-line {
+ background: #52c41a;
+ }
+
+ .process-step.rejected .step-dot {
+ background: #ff4d4f;
+ color: #fff;
+ }
+ .process-step.rejected .step-line {
+ background: #ff4d4f;
+ }
+
+ .step-content {
+ flex: 1;
+ padding-top: 4px;
+ }
+
+ .step-info {
+ margin-bottom: 8px;
+ }
+
+ .step-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-approver {
+ font-size: 14px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-time {
+ font-size: 12px;
+ color: #999;
+ display: block;
+ }
+
+ .step-opinion {
+ background: #f8f9fa;
+ padding: 12px;
+ border-radius: 8px;
+ border-left: 4px solid #52c41a;
+ }
+
+ .opinion-label {
+ font-size: 12px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .opinion-content {
+ font-size: 14px;
+ color: #333;
+ line-height: 1.5;
+ }
+
+ .approval-input {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .input-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .input-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .input-content {
+ padding: 16px;
+ }
+
+ .footer-actions {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 16px;
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1000;
+ }
+
+ .reject-btn {
+ width: 120px;
+ background: #ff4d4f;
+ color: #fff;
+ }
+
+ .approve-btn {
+ width: 120px;
+ background: #52c41a;
+ color: #fff;
+ }
+
+ /* 閫傞厤u-button鏍峰紡 */
+ :deep(.u-button) {
+ border-radius: 6px;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.7);
+ }
+ 70% {
+ box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+ }
+ 100% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+ }
+ }
+ .signature-section {
+ background: #fff;
+ padding: 12px 16px 16px;
+ border-top: 1px solid #f0f0f0;
+ }
+ .signature-header {
+ margin-bottom: 8px;
+ }
+ .signature-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ }
+ .signature-box {
+ width: 100%;
+ height: 180px;
+ background: #fff;
+ border: 1px dashed #d9d9d9;
+ border-radius: 8px;
+ overflow: hidden;
+ }
+ .signature-actions {
+ margin-top: 8px;
+ display: flex;
+ justify-content: flex-end;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetExamine/index.vue b/src/pages/managementMeetings/meetExamine/index.vue
new file mode 100644
index 0000000..0b39095
--- /dev/null
+++ b/src/pages/managementMeetings/meetExamine/index.vue
@@ -0,0 +1,352 @@
+// 瀹℃壒绠$悊涓婚〉闈�
+<template>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浼氳瀹℃壒"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ細璁富棰�"
+ v-model="searchForm.title"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 瀹℃壒鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.title }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.status)">{{ formatReceiptType(item.status) }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐢宠浜�</text>
+ <text class="detail-value">{{ item.applicant }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓荤悊浜�</text>
+ <text class="detail-value">{{ item.host }}</text>
+ </view>
+ <view class="detail-row-approveReason">
+ <text class="detail-label">浼氳鏃堕棿</text>
+ <text class="detail-value highlightBlue">{{ formatDateTime(item.meetingTime) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浼氳鍦扮偣</text>
+ <text class="detail-value">{{ item.location }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ item.participants.length }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="actions">
+ <u-button type="primary"
+ size="small"
+ class="action-btn view"
+ @click="viewDetail(item)">
+ 璇︽儏
+ </u-button>
+ <u-button type="success"
+ size="small"
+ class="action-btn approve"
+ :disabled="item.status != 0"
+ @click="approve(item)">
+ 瀹℃壒
+ </u-button>
+ </view>
+ <!-- <view class="detail-info"
+ style="align-items: flex-end;">
+ <view class="detail-row">
+
+ </view>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鏁版嵁</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, toRefs, reactive } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getExamineList,
+ getRoomEnum,
+ } from "@/api/managementMeetings/meetExamine";
+ import { staffOnJobListPage } from "@/api/personnelManagement/onboarding";
+ import { onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+ // 鏁版嵁
+ const ledgerList = ref([]);
+ const data = reactive({
+ searchForm: {
+ title: "",
+ },
+ });
+ const { searchForm } = toRefs(data);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鎴块棿鏋氫妇
+ const roomEnum = ref([]);
+ // 鎴块棿鏋氫妇鏌ヨ
+ const getRoomEnumList = () => {
+ return getRoomEnum()
+ .then(res => {
+ console.log(res.data, "res.data");
+ roomEnum.value = res.data;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鍛樺伐鍒楄〃
+ const staffList = ref([]);
+ // 鍛樺伐鍒楄〃鏌ヨ
+ const getStaffOnJobList = () => {
+ return staffOnJobListPage()
+ .then(res => {
+ console.log(res.data, "res.data");
+ staffList.value = res.data.records;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ getExamineList({
+ ...page,
+ ...searchForm.value,
+ })
+ .then(res => {
+ console.log(res.data.records, "res.data.records");
+ ledgerList.value = res.data.records.map(it => {
+ console.log(it, "it1");
+ 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.postName})`,
+ };
+ });
+ console.log(it, "it2");
+
+ return it;
+ });
+
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭鏍�";
+ } else if (params == 1) {
+ return "宸查�氳繃";
+ } else if (params == 2) {
+ return "鏈�氳繃";
+ } else if (params == 3) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "warning";
+ } else if (type == 3) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+
+ // 鐐瑰嚮瀹℃牳
+ const approve = item => {
+ // uni.setStorageSync("approveId", item.approveId);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetExamine/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=true",
+ });
+ };
+ // 鏌ョ湅璇︽儏
+ const viewDetail = item => {
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetExamine/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=false",
+ });
+ };
+
+ onShow(async () => {
+ // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+ try {
+ // 绛夊緟涓や釜寮傛鏂规硶鎵ц瀹屾垚
+ await Promise.all([getRoomEnumList(), getStaffOnJobList()]);
+ // 涓や釜鏂规硶鎵ц瀹屾垚鍚庡啀鎵ц getList()
+ getList();
+ } catch (error) {
+ console.error("鍒濆鍖栨暟鎹け璐�:", error);
+ // 鍗充娇鍑洪敊涔熸墽琛� getList()锛岀‘淇濋〉闈㈣兘姝e父鍔犺浇
+ getList();
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .document-icon {
+ background: #ed8d05;
+ }
+
+ // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .fab-button {
+ background: #ed8d05;
+ }
+
+ // 鐗规湁鏍峰紡
+ .detail-row-user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .detail-row-approveReason {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ }
+
+ .detail-value.highlightBlue {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.highlightYellow {
+ color: #ed8d05;
+ font-weight: 500;
+ }
+
+ .approver-value {
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ .approver-chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: #f0f6ff;
+ color: #2b7cff;
+ border: 1px solid #e0efff;
+ border-radius: 999px;
+ padding: 4px 10px;
+ max-width: 100%;
+ }
+
+ .approver-name {
+ font-size: 12px;
+ color: #2b7cff;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: flex-end;
+ margin-top: 18rpx;
+ }
+
+ .action-btn {
+ border-radius: 16px;
+ height: 28px;
+ line-height: 28px;
+ padding: 0 12px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetPublish/approve.vue b/src/pages/managementMeetings/meetPublish/approve.vue
new file mode 100644
index 0000000..50a6f52
--- /dev/null
+++ b/src/pages/managementMeetings/meetPublish/approve.vue
@@ -0,0 +1,497 @@
+<template>
+ <view class="approve-page">
+ <PageHeader title="鍙戝竷"
+ @back="goBack" />
+ <!-- 鐢宠淇℃伅 -->
+ <view class="application-info">
+ <view class="info-header">
+ <text class="info-title">浼氳淇℃伅</text>
+ </view>
+ <view class="info-content">
+ <view class="info-row">
+ <text class="info-label">浼氳涓婚</text>
+ <text class="info-value">{{ approvalData.title }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鐢宠浜�</text>
+ <text class="info-value">{{ approvalData.applicant }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">涓荤悊浜�</text>
+ <text class="info-value">{{ approvalData.host }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鏃堕棿</text>
+ <text class="info-value">{{ formatDateTime(approvalData.meetingTime) }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鍦扮偣</text>
+ <text class="info-value">{{ approvalData.location }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">瀹℃壒鐘舵��</text>
+ <text class="info-value tag"
+ :class="getTagClass(approvalData.approveNodeStatus)">
+ {{ formatReceiptType(approvalData.approveNodeStatus) }}
+ </text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳璇存槑</text>
+ <text class="info-value">{{ approvalData.description }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜烘暟</text>
+ <text class="info-value">{{ approvalData.participants.length }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜哄憳</text>
+ <text class="info-value">{{ approvalData.participants.map(it => it.name).join("銆�") }}</text>
+ </view>
+ </view>
+ </view>
+ <!-- 鍙戝竷鎰忚杈撳叆 -->
+ <view v-if="isEdit"
+ class="approval-input">
+ <view class="input-header">
+ <text class="input-title">鍙戝竷鎰忚</text>
+ </view>
+ <view class="input-content">
+ <u-textarea v-model="approvalOpinion"
+ rows="4"
+ placeholder="璇疯緭鍏ュ彂甯冩剰瑙�"
+ maxlength="200"
+ count />
+ </view>
+ </view>
+ <!-- 搴曢儴鎿嶄綔鎸夐挳 -->
+ <view v-if="isEdit"
+ class="footer-actions">
+ <!-- <u-button class="reject-btn"
+ @click="handleReject">涓嶉�氳繃</u-button> -->
+ <u-button class="approve-btn"
+ @click="handleApprove">鍙戝竷</u-button>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, computed } from "vue";
+ import { onLoad } from "@dcloudio/uni-app";
+ import { saveMeetingApplication } from "@/api/managementMeetings/meetExamine";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import PageHeader from "@/components/PageHeader.vue";
+
+ const approvalData = ref({});
+ const approvalSteps = ref([]);
+ const approvalOpinion = ref("");
+ const isEdit = ref(false);
+
+ onLoad(options => {
+ console.log(options, "options");
+ if (options.item) {
+ approvalData.value = JSON.parse(options.item);
+ }
+ // 缂栬緫妯″紡涓嬶紝榛樿鍙戝竷鎰忚涓哄綋鍓嶅鎵规剰瑙�
+ if (options.edit) {
+ isEdit.value = options.edit === "true" ? true : false;
+ }
+ console.log(approvalData.value, "approvalData.value");
+ });
+
+ const goBack = () => {
+ uni.removeStorageSync("approveId");
+ uni.navigateBack();
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭彂甯�";
+ } else if (params == 1) {
+ return "宸插彂甯�";
+ } else if (params == 2) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+ const submitForm = status => {
+ // 鏍¢獙鍙戝竷鎰忚
+ if (!approvalOpinion.value?.trim()) {
+ showToast("璇疯緭鍏ュ彂甯冩剰瑙�");
+ return;
+ }
+
+ // 璋冪敤鍚庣
+ saveMeetingApplication({
+ id: approvalData.value.id,
+ publishStatus: status,
+ publishComment: approvalOpinion.value, // 娣诲姞鍙戝竷鎰忚
+ })
+ .then(res => {
+ if (res.code === 200) {
+ showToast("鍙戝竷鎴愬姛");
+ // 鎻愮ず鍚庤繑鍥炰笂涓�涓〉闈�
+ setTimeout(() => {
+ goBack(); // 鍐呴儴鏄� uni.navigateBack()
+ }, 800);
+ } else {
+ showToast(res.message || "鍙戝竷鎿嶄綔澶辫触锛岃閲嶈瘯");
+ }
+ })
+ .catch(error => {
+ console.error("鍙戝竷鎿嶄綔澶辫触:", error);
+ showToast("鍙戝竷鎿嶄綔澶辫触锛岃閲嶈瘯");
+ });
+ };
+
+ const handleApprove = () => {
+ uni.showModal({
+ title: "纭鎿嶄綔",
+ content: "纭畾瑕佸彂甯冭浼氳鍚楋紵",
+ success: res => {
+ if (res.confirm) submitForm(1);
+ },
+ });
+ };
+
+ const handleReject = () => {
+ uni.showModal({
+ title: "纭鎿嶄綔",
+ content: "纭畾涓嶉�氳繃璇ヤ細璁敵璇峰悧锛�",
+ success: res => {
+ if (res.confirm) submitForm(2);
+ },
+ });
+ };
+ // 鍘熷鑺傜偣鏁版嵁锛堢敤浜庢彁浜ら�昏緫锛�
+ const activities = ref([]);
+</script>
+
+<style scoped lang="scss">
+ .approve-page {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 80px;
+ }
+
+ .header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 16px 20px;
+ border-bottom: 1px solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ }
+
+ .title {
+ flex: 1;
+ text-align: center;
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .application-info {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .info-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .info-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .info-content {
+ padding: 16px;
+ }
+
+ .info-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 12px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .info-label {
+ font-size: 14px;
+ color: #666;
+ width: 80px;
+ flex-shrink: 0;
+ }
+
+ .info-value {
+ font-size: 14px;
+ color: #333;
+ flex: 1;
+ }
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .process-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .process-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .process-steps {
+ padding: 20px;
+ }
+
+ .process-step {
+ display: flex;
+ position: relative;
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+
+ .step-line {
+ display: none;
+ }
+ }
+ }
+
+ .step-indicator {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-right: 16px;
+ }
+
+ .step-dot {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ font-weight: 600;
+ position: relative;
+ z-index: 2;
+ }
+
+ .process-step.completed .step-dot {
+ background: #52c41a;
+ color: #fff;
+ }
+
+ .process-step.current .step-dot {
+ background: #1890ff;
+ color: #fff;
+ animation: pulse 2s infinite;
+ }
+
+ .process-step.pending .step-dot {
+ background: #d9d9d9;
+ color: #999;
+ }
+
+ .step-line {
+ width: 2px;
+ height: 40px;
+ background: #d9d9d9;
+ margin-top: 8px;
+ }
+
+ .process-step.completed .step-line {
+ background: #52c41a;
+ }
+
+ .process-step.rejected .step-dot {
+ background: #ff4d4f;
+ color: #fff;
+ }
+ .process-step.rejected .step-line {
+ background: #ff4d4f;
+ }
+
+ .step-content {
+ flex: 1;
+ padding-top: 4px;
+ }
+
+ .step-info {
+ margin-bottom: 8px;
+ }
+
+ .step-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-approver {
+ font-size: 14px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-time {
+ font-size: 12px;
+ color: #999;
+ display: block;
+ }
+
+ .step-opinion {
+ background: #f8f9fa;
+ padding: 12px;
+ border-radius: 8px;
+ border-left: 4px solid #52c41a;
+ }
+
+ .opinion-label {
+ font-size: 12px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .opinion-content {
+ font-size: 14px;
+ color: #333;
+ line-height: 1.5;
+ }
+
+ .approval-input {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .input-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .input-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .input-content {
+ padding: 16px;
+ }
+
+ .footer-actions {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 16px;
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1000;
+ }
+
+ .reject-btn {
+ width: 120px;
+ background: #ff4d4f;
+ color: #fff;
+ }
+
+ .approve-btn {
+ width: 120px;
+ background: #52c41a;
+ color: #fff;
+ }
+
+ /* 閫傞厤u-button鏍峰紡 */
+ :deep(.u-button) {
+ border-radius: 6px;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.7);
+ }
+ 70% {
+ box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+ }
+ 100% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+ }
+ }
+ .signature-section {
+ background: #fff;
+ padding: 12px 16px 16px;
+ border-top: 1px solid #f0f0f0;
+ }
+ .signature-header {
+ margin-bottom: 8px;
+ }
+ .signature-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ }
+ .signature-box {
+ width: 100%;
+ height: 180px;
+ background: #fff;
+ border: 1px dashed #d9d9d9;
+ border-radius: 8px;
+ overflow: hidden;
+ }
+ .signature-actions {
+ margin-top: 8px;
+ display: flex;
+ justify-content: flex-end;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetPublish/index.vue b/src/pages/managementMeetings/meetPublish/index.vue
new file mode 100644
index 0000000..f4a1ad4
--- /dev/null
+++ b/src/pages/managementMeetings/meetPublish/index.vue
@@ -0,0 +1,348 @@
+// 瀹℃壒绠$悊涓婚〉闈�
+<template>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浼氳鍙戝竷"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ細璁富棰�"
+ v-model="searchForm.title"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 瀹℃壒鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.title }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.status)">{{ formatReceiptType(item.status) }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐢宠浜�</text>
+ <text class="detail-value">{{ item.applicant }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓荤悊浜�</text>
+ <text class="detail-value">{{ item.host }}</text>
+ </view>
+ <view class="detail-row-approveReason">
+ <text class="detail-label">浼氳鏃堕棿</text>
+ <text class="detail-value highlightBlue">{{ formatDateTime(item.meetingTime) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浼氳鍦扮偣</text>
+ <text class="detail-value">{{ item.location }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ item.participants.length }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="actions">
+ <u-button type="primary"
+ size="small"
+ class="action-btn view"
+ @click="viewDetail(item)">
+ 璇︽儏
+ </u-button>
+ <u-button type="success"
+ size="small"
+ class="action-btn approve"
+ :disabled="item.status != 0"
+ @click="approve(item)">
+ 鍙戝竷
+ </u-button>
+ </view>
+ <!-- <view class="detail-info"
+ style="align-items: flex-end;">
+ <view class="detail-row">
+
+ </view>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鏁版嵁</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, toRefs, reactive } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getMeetingPublish,
+ getRoomEnum,
+ } from "@/api/managementMeetings/meetExamine";
+ import { staffOnJobListPage } from "@/api/personnelManagement/onboarding";
+ import { onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+ // 鏁版嵁
+ const ledgerList = ref([]);
+ const data = reactive({
+ searchForm: {
+ title: "",
+ },
+ });
+ const { searchForm } = toRefs(data);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鎴块棿鏋氫妇
+ const roomEnum = ref([]);
+ // 鎴块棿鏋氫妇鏌ヨ
+ const getRoomEnumList = () => {
+ return getRoomEnum()
+ .then(res => {
+ console.log(res.data, "res.data");
+ roomEnum.value = res.data;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鍛樺伐鍒楄〃
+ const staffList = ref([]);
+ // 鍛樺伐鍒楄〃鏌ヨ
+ const getStaffOnJobList = () => {
+ return staffOnJobListPage()
+ .then(res => {
+ console.log(res.data, "res.data");
+ staffList.value = res.data.records;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ getMeetingPublish({
+ ...page,
+ ...searchForm.value,
+ })
+ .then(res => {
+ console.log(res.data.records, "res.data.records");
+ ledgerList.value = res.data.records.map(it => {
+ console.log(it, "it1");
+ 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.postName})`,
+ };
+ });
+ console.log(it, "it2");
+
+ return it;
+ });
+
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭彂甯�";
+ } else if (params == 1) {
+ return "宸插彂甯�";
+ } else if (params == 2) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+
+ // 鐐瑰嚮瀹℃牳
+ const approve = item => {
+ // uni.setStorageSync("approveId", item.approveId);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetPublish/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=true",
+ });
+ };
+ // 鏌ョ湅璇︽儏
+ const viewDetail = item => {
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetPublish/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=false",
+ });
+ };
+
+ onShow(async () => {
+ // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+ try {
+ // 绛夊緟涓や釜寮傛鏂规硶鎵ц瀹屾垚
+ await Promise.all([getRoomEnumList(), getStaffOnJobList()]);
+ // 涓や釜鏂规硶鎵ц瀹屾垚鍚庡啀鎵ц getList()
+ getList();
+ } catch (error) {
+ console.error("鍒濆鍖栨暟鎹け璐�:", error);
+ // 鍗充娇鍑洪敊涔熸墽琛� getList()锛岀‘淇濋〉闈㈣兘姝e父鍔犺浇
+ getList();
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .document-icon {
+ background: #ed8d05;
+ }
+
+ // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .fab-button {
+ background: #ed8d05;
+ }
+
+ // 鐗规湁鏍峰紡
+ .detail-row-user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .detail-row-approveReason {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ }
+
+ .detail-value.highlightBlue {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.highlightYellow {
+ color: #ed8d05;
+ font-weight: 500;
+ }
+
+ .approver-value {
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ .approver-chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: #f0f6ff;
+ color: #2b7cff;
+ border: 1px solid #e0efff;
+ border-radius: 999px;
+ padding: 4px 10px;
+ max-width: 100%;
+ }
+
+ .approver-name {
+ font-size: 12px;
+ color: #2b7cff;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: flex-end;
+ margin-top: 18rpx;
+ }
+
+ .action-btn {
+ border-radius: 16px;
+ height: 28px;
+ line-height: 28px;
+ padding: 0 12px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetSummary/approve.vue b/src/pages/managementMeetings/meetSummary/approve.vue
new file mode 100644
index 0000000..c30c8be
--- /dev/null
+++ b/src/pages/managementMeetings/meetSummary/approve.vue
@@ -0,0 +1,560 @@
+<template>
+ <view class="approve-page">
+ <PageHeader title="鎬荤粨"
+ @back="goBack" />
+ <!-- 鐢宠淇℃伅 -->
+ <view class="application-info">
+ <view class="info-header">
+ <text class="info-title">浼氳淇℃伅</text>
+ </view>
+ <view class="info-content">
+ <view class="info-row">
+ <text class="info-label">浼氳涓婚</text>
+ <text class="info-value">{{ approvalData.title }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鐢宠浜�</text>
+ <text class="info-value">{{ approvalData.applicant }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">涓荤悊浜�</text>
+ <text class="info-value">{{ approvalData.host }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鏃堕棿</text>
+ <text class="info-value">{{ formatDateTime(approvalData.meetingTime) }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳鍦扮偣</text>
+ <text class="info-value">{{ approvalData.location }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">瀹℃壒鐘舵��</text>
+ <text class="info-value tag"
+ :class="getTagClass(approvalData.approveNodeStatus)">
+ {{ formatReceiptType(approvalData.approveNodeStatus) }}
+ </text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">浼氳璇存槑</text>
+ <text class="info-value">{{ approvalData.description }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜烘暟</text>
+ <text class="info-value">{{ approvalData.participants.length }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙備細浜哄憳</text>
+ <text class="info-value">{{ approvalData.participants.map(it => it.name).join("銆�") }}</text>
+ </view>
+ </view>
+ </view>
+ <!-- 鎻愪氦鎰忚杈撳叆 -->
+ <view v-if="isEdit"
+ class="approval-input">
+ <view class="input-header">
+ <text class="input-title">浼氳绾</text>
+ </view>
+ <view class="input-content">
+ <Editor v-model:modelValue="minutesContent"
+ :height="300" />
+ </view>
+ </view>
+ <!-- 搴曢儴鎿嶄綔鎸夐挳 -->
+ <view v-if="isEdit"
+ class="footer-actions">
+ <u-button class="approve-btn"
+ @click="handleApprove">鎻愪氦</u-button>
+ </view>
+ </view>
+</template>
+<script setup>
+ import { ref, onMounted, nextTick } from "vue";
+ import { onLoad } from "@dcloudio/uni-app";
+ import {
+ saveMeetingMinutes,
+ getMeetingMinutesByMeetingId,
+ } from "@/api/managementMeetings/meetExamine";
+ import { getToken } from "@/utils/auth";
+ import PageHeader from "@/components/PageHeader.vue";
+ import Editor from "@/components/Editor/index.vue";
+
+ const approvalData = ref({});
+ const approvalSteps = ref([]);
+ const isEdit = ref(false);
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ onLoad(options => {
+ console.log(options, "options");
+ if (options.item) {
+ approvalData.value = JSON.parse(options.item);
+ }
+ // 缂栬緫妯″紡涓嬶紝榛樿鎻愪氦鎰忚涓哄綋鍓嶅鎵规剰瑙�
+ if (options.edit) {
+ isEdit.value = options.edit === "true" ? true : false;
+ }
+ getMeetingMinutes();
+ console.log(approvalData.value, "approvalData.value");
+ });
+ const goBack = () => {
+ uni.removeStorageSync("approveId");
+ uni.navigateBack();
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭鎵�";
+ } else if (params == 1) {
+ return "宸查�氳繃";
+ } else if (params == 2) {
+ return "鏈�氳繃";
+ } else if (params == 3) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "warning";
+ } else if (type == 3) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+ const minutesContent = ref("");
+ const minutesContentId = ref("");
+ const getMeetingMinutes = () => {
+ getMeetingMinutesByMeetingId(approvalData.value.id)
+ .then(res => {
+ console.log(res.data, "res.data");
+
+ if (res.data) {
+ minutesContent.value = res.data.content;
+ minutesContentId.value = res.data.id;
+ } else {
+ minutesContent.value = `<h2>${approvalData.value.title}浼氳绾</h2>
+ <p><strong>浼氳鏃堕棿锛�</strong>${
+ approvalData
+ .value
+ .meetingTime
+ }</p>
+ <p><strong>浼氳鍦扮偣锛�</strong>${
+ approvalData
+ .value
+ .location
+ }</p>
+ <p><strong>涓绘寔浜猴細</strong>${
+ approvalData
+ .value
+ .host
+ }</p>
+ <p><strong>鍙備細浜哄憳锛�</strong></p>
+ <ol>
+ ${approvalData.value.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>`;
+ }
+ })
+ .catch(error => {
+ console.error("鑾峰彇浼氳绾澶辫触:", error);
+ showToast("鑾峰彇浼氳绾澶辫触锛岃閲嶈瘯");
+ });
+ };
+ const submitForm = status => {
+ console.log(minutesContent.value, "瀵屾枃鏈�");
+ if (!minutesContent.value) {
+ ElMessage.warning("璇疯緭鍏ヤ細璁邯瑕佸唴瀹�");
+ return;
+ }
+
+ // 璋冪敤鍚庣
+ saveMeetingMinutes({
+ id: minutesContentId.value,
+ content: minutesContent.value,
+ meetingId: approvalData.value.id,
+ title: approvalData.value.title,
+ })
+ .then(res => {
+ if (res.code === 200) {
+ showToast("鎻愪氦鎴愬姛");
+ // 鎻愮ず鍚庤繑鍥炰笂涓�涓〉闈�
+ setTimeout(() => {
+ goBack(); // 鍐呴儴鏄� uni.navigateBack()
+ }, 800);
+ } else {
+ showToast(res.message || "鎻愪氦鎿嶄綔澶辫触锛岃閲嶈瘯");
+ }
+ })
+ .catch(error => {
+ console.error("鎻愪氦鎿嶄綔澶辫触:", error);
+ showToast("鎻愪氦鎿嶄綔澶辫触锛岃閲嶈瘯");
+ });
+ };
+
+ const handleApprove = () => {
+ uni.showModal({
+ title: "纭鎿嶄綔",
+ content: "纭畾瑕佹彁浜よ浼氳鎬荤粨鍚楋紵",
+ success: res => {
+ if (res.confirm) submitForm(1);
+ },
+ });
+ };
+ // 鍘熷鑺傜偣鏁版嵁锛堢敤浜庢彁浜ら�昏緫锛�
+ const activities = ref([]);
+</script>
+
+<style scoped lang="scss">
+ .approve-page {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 80px;
+ }
+
+ .header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 16px 20px;
+ border-bottom: 1px solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ }
+
+ .title {
+ flex: 1;
+ text-align: center;
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .application-info {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .info-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .info-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .info-content {
+ padding: 16px;
+ }
+
+ .info-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 12px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .info-label {
+ font-size: 14px;
+ color: #666;
+ width: 80px;
+ flex-shrink: 0;
+ }
+
+ .info-value {
+ font-size: 14px;
+ color: #333;
+ flex: 1;
+ }
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .process-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .process-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .process-steps {
+ padding: 20px;
+ }
+
+ .process-step {
+ display: flex;
+ position: relative;
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+
+ .step-line {
+ display: none;
+ }
+ }
+ }
+
+ .step-indicator {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-right: 16px;
+ }
+
+ .step-dot {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ font-weight: 600;
+ position: relative;
+ z-index: 2;
+ }
+
+ .process-step.completed .step-dot {
+ background: #52c41a;
+ color: #fff;
+ }
+
+ .process-step.current .step-dot {
+ background: #1890ff;
+ color: #fff;
+ animation: pulse 2s infinite;
+ }
+
+ .process-step.pending .step-dot {
+ background: #d9d9d9;
+ color: #999;
+ }
+
+ .step-line {
+ width: 2px;
+ height: 40px;
+ background: #d9d9d9;
+ margin-top: 8px;
+ }
+
+ .process-step.completed .step-line {
+ background: #52c41a;
+ }
+
+ .process-step.rejected .step-dot {
+ background: #ff4d4f;
+ color: #fff;
+ }
+ .process-step.rejected .step-line {
+ background: #ff4d4f;
+ }
+
+ .step-content {
+ flex: 1;
+ padding-top: 4px;
+ }
+
+ .step-info {
+ margin-bottom: 8px;
+ }
+
+ .step-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-approver {
+ font-size: 14px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .step-time {
+ font-size: 12px;
+ color: #999;
+ display: block;
+ }
+
+ .step-opinion {
+ background: #f8f9fa;
+ padding: 12px;
+ border-radius: 8px;
+ border-left: 4px solid #52c41a;
+ }
+
+ .opinion-label {
+ font-size: 12px;
+ color: #666;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .opinion-content {
+ font-size: 14px;
+ color: #333;
+ line-height: 1.5;
+ }
+
+ .approval-input {
+ background: #fff;
+ margin: 16px;
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .input-header {
+ padding: 16px;
+ border-bottom: 1px solid #f0f0f0;
+ background: #f8f9fa;
+ }
+
+ .input-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ .input-content {
+ padding: 16px;
+ }
+
+ .footer-actions {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 16px;
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1000;
+ }
+
+ .reject-btn {
+ width: 120px;
+ background: #ff4d4f;
+ color: #fff;
+ }
+
+ .approve-btn {
+ width: 120px;
+ background: #52c41a;
+ color: #fff;
+ }
+
+ /* 閫傞厤u-button鏍峰紡 */
+ :deep(.u-button) {
+ border-radius: 6px;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.7);
+ }
+ 70% {
+ box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+ }
+ 100% {
+ box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+ }
+ }
+ .signature-section {
+ background: #fff;
+ padding: 12px 16px 16px;
+ border-top: 1px solid #f0f0f0;
+ }
+ .signature-header {
+ margin-bottom: 8px;
+ }
+ .signature-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ }
+ .signature-box {
+ width: 100%;
+ height: 180px;
+ background: #fff;
+ border: 1px dashed #d9d9d9;
+ border-radius: 8px;
+ overflow: hidden;
+ }
+ .signature-actions {
+ margin-top: 8px;
+ display: flex;
+ justify-content: flex-end;
+ }
+ /* 宸ュ叿鏍忔寜閽牱寮� */
+ :deep(.ql-toolbar.ql-snow .ql-button) {
+ height: 28px;
+ width: 28px;
+ padding: 4px;
+ }
+ :deep(.ql-toolbar.ql-snow .ql-picker-label) {
+ height: 28px;
+ padding: 4px 8px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetSummary/index.vue b/src/pages/managementMeetings/meetSummary/index.vue
new file mode 100644
index 0000000..7db6649
--- /dev/null
+++ b/src/pages/managementMeetings/meetSummary/index.vue
@@ -0,0 +1,353 @@
+// 瀹℃壒绠$悊涓婚〉闈�
+<template>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浼氳鎬荤粨"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ細璁富棰�"
+ v-model="searchForm.title"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 瀹℃壒鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.title }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.status)">{{ formatReceiptType(item.status) }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐢宠浜�</text>
+ <text class="detail-value">{{ item.applicant }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓荤悊浜�</text>
+ <text class="detail-value">{{ item.host }}</text>
+ </view>
+ <view class="detail-row-approveReason">
+ <text class="detail-label">浼氳鏃堕棿</text>
+ <text class="detail-value highlightBlue">{{ formatDateTime(item.meetingTime) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浼氳鍦扮偣</text>
+ <text class="detail-value">{{ item.location }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ item.participants.length }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="actions">
+ <u-button type="primary"
+ size="small"
+ class="action-btn view"
+ @click="viewDetail(item)">
+ 璇︽儏
+ </u-button>
+ <u-button type="success"
+ size="small"
+ class="action-btn approve"
+ :disabled="item.status != 0"
+ @click="approve(item)">
+ 娣诲姞绾
+ </u-button>
+ </view>
+ <!-- <view class="detail-info"
+ style="align-items: flex-end;">
+ <view class="detail-row">
+
+ </view>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鏁版嵁</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, toRefs, reactive } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getMeetingPublish,
+ getRoomEnum,
+ } from "@/api/managementMeetings/meetExamine";
+ import { staffOnJobListPage } from "@/api/personnelManagement/onboarding";
+ import { onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+ // 鏁版嵁
+ const ledgerList = ref([]);
+ const data = reactive({
+ searchForm: {
+ title: "",
+ },
+ });
+ const { searchForm } = toRefs(data);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鎴块棿鏋氫妇
+ const roomEnum = ref([]);
+ // 鎴块棿鏋氫妇鏌ヨ
+ const getRoomEnumList = () => {
+ return getRoomEnum()
+ .then(res => {
+ console.log(res.data, "res.data");
+ roomEnum.value = res.data;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鍛樺伐鍒楄〃
+ const staffList = ref([]);
+ // 鍛樺伐鍒楄〃鏌ヨ
+ const getStaffOnJobList = () => {
+ return staffOnJobListPage()
+ .then(res => {
+ console.log(res.data, "res.data");
+ staffList.value = res.data.records;
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ getMeetingPublish({
+ ...page,
+ ...searchForm.value,
+ })
+ .then(res => {
+ console.log(res.data.records, "res.data.records");
+ ledgerList.value = res.data.records.map(it => {
+ console.log(it, "it1");
+ 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")}`;
+ console.log(staffList.value, "staffList.value");
+ it.participants = staffList.value
+ .filter(staff => staffs.some(id => id == staff.id))
+ .map(staff => {
+ return {
+ id: staff.id,
+ name: `${staff.staffName}(${staff.postName})`,
+ };
+ });
+ console.log(it, "it2");
+
+ return it;
+ });
+
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "寰呭鎵�";
+ } else if (params == 1) {
+ return "宸查�氳繃";
+ } else if (params == 2) {
+ return "鏈�氳繃";
+ } else if (params == 3) {
+ return "宸插彇娑�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "success";
+ } else if (type == 2) {
+ return "warning";
+ } else if (type == 3) {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+
+ // 鐐瑰嚮瀹℃牳
+ const approve = item => {
+ // uni.setStorageSync("approveId", item.approveId);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetSummary/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=true",
+ });
+ };
+ // 鏌ョ湅璇︽儏
+ const viewDetail = item => {
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/meetSummary/approve?item=" +
+ JSON.stringify(item) +
+ "&edit=false",
+ });
+ };
+
+ onShow(async () => {
+ // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+ try {
+ // 绛夊緟涓や釜寮傛鏂规硶鎵ц瀹屾垚
+ await Promise.all([getRoomEnumList(), getStaffOnJobList()]);
+ // 涓や釜鏂规硶鎵ц瀹屾垚鍚庡啀鎵ц getList()
+ getList();
+ } catch (error) {
+ console.error("鍒濆鍖栨暟鎹け璐�:", error);
+ // 鍗充娇鍑洪敊涔熸墽琛� getList()锛岀‘淇濋〉闈㈣兘姝e父鍔犺浇
+ getList();
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .document-icon {
+ background: #ed8d05;
+ }
+
+ // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .fab-button {
+ background: #ed8d05;
+ }
+
+ // 鐗规湁鏍峰紡
+ .detail-row-user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .detail-row-approveReason {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ }
+
+ .detail-value.highlightBlue {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.highlightYellow {
+ color: #ed8d05;
+ font-weight: 500;
+ }
+
+ .approver-value {
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ .approver-chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: #f0f6ff;
+ color: #2b7cff;
+ border: 1px solid #e0efff;
+ border-radius: 999px;
+ padding: 4px 10px;
+ max-width: 100%;
+ }
+
+ .approver-name {
+ font-size: 12px;
+ color: #2b7cff;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: flex-end;
+ margin-top: 18rpx;
+ }
+
+ .action-btn {
+ border-radius: 16px;
+ height: 28px;
+ line-height: 28px;
+ padding: 0 12px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingBoard/index.vue b/src/pages/managementMeetings/meetingBoard/index.vue
new file mode 100644
index 0000000..913ab9a
--- /dev/null
+++ b/src/pages/managementMeetings/meetingBoard/index.vue
@@ -0,0 +1,393 @@
+// 瀹℃壒绠$悊涓婚〉闈�
+<template>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浼氳鐪嬫澘"
+ @back="goBack" />
+ <!-- 瀹℃壒鍒楄〃 -->
+ <view class="topbox">
+ <view class="boxItem">
+ <view class="boxItem-num">
+ {{stats.total ? stats.total : 0}}
+ </view>
+ <view class="boxItem-title">
+ 鎬讳細璁暟
+ </view>
+ </view>
+ <view class="boxItem">
+ <view class="boxItem-num">
+ {{stats.underWay ? stats.underWay : 0}}
+ </view>
+ <view class="boxItem-title">
+ 杩涜涓�
+ </view>
+ </view>
+ <view class="boxItem">
+ <view class="boxItem-num">
+ {{stats.completed ? stats.completed : 0}}
+ </view>
+ <view class="boxItem-title">
+ 宸插畬鎴�
+ </view>
+ </view>
+ <view class="boxItem">
+ <view class="boxItem-num">
+ {{stats.toStart ? stats.toStart : 0}}
+ </view>
+ <view class="boxItem-title">
+ 鍗冲皢寮�濮�
+ </view>
+ </view>
+ </view>
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.title }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.status)">{{ formatReceiptType(item.status) }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">涓绘寔浜�</text>
+ <text class="detail-value">{{ item.host }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ item.participants.length }}</text>
+ </view>
+ <view class="detail-row-approveReason">
+ <text class="detail-label">浼氳鏃堕棿</text>
+ <text class="detail-value highlightBlue">{{dayjs(item.startTime).format("YYYY-MM-DD")}}
+ {{ formatTime(item.startTime) }} - {{ formatTime(item.endTime) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浼氳鍦扮偣</text>
+ <text class="detail-value">{{ item.location }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ item.participants.length }}</text>
+ </view>
+ <!-- <up-divider></up-divider> -->
+ <u-collapse @change="change"
+ @close="close"
+ @open="open"
+ accordion
+ border
+ :duration="300">
+ <u-collapse-item :title="`浼氳绾 ${item.content ? '' : '(鏃�)'}`"
+ :name="`meeting-${index}`">
+ <view class="meeting-content">
+ <view v-if="item.content"
+ class="content-html"><rich-text :nodes="item.content"></rich-text></view>
+ <view v-else
+ class="no-content">
+ <text>鏆傛棤浼氳绾鍐呭</text>
+ </view>
+ </view>
+ </u-collapse-item>
+ </u-collapse>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鏁版嵁</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, toRefs, reactive } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getMeetSummaryItems,
+ getMeetSummary,
+ } from "@/api/managementMeetings/meetExamine";
+ import { onShow } from "@dcloudio/uni-app";
+ import dayjs from "dayjs";
+ import useUserStore from "@/store/modules/user";
+ // 鏁版嵁
+ const ledgerList = ref([]);
+ const data = reactive({
+ searchForm: {
+ title: "",
+ },
+ });
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 缁熻鏁版嵁
+ const stats = ref({});
+ const getnum = () => {
+ getMeetSummary().then(res => {
+ stats.value = res.data;
+ });
+ };
+ // 鏍煎紡鍖栨椂闂�
+ const formatTime = timeStr => {
+ const date = new Date(timeStr);
+ return date.toLocaleTimeString("zh-CN", {
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+
+ getMeetSummaryItems()
+ .then(res => {
+ ledgerList.value = res.data.map(item => {
+ return {
+ ...item,
+ participants: JSON.parse(item.participants),
+ };
+ });
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const formatDateTime = dateTime => {
+ if (!dateTime) return "";
+ return dateTime.replace(" ", "\n");
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == 0) {
+ return "宸插畬鎴�";
+ } else if (params == 1) {
+ return "鍗冲皢寮�濮�";
+ } else if (params == 2) {
+ return "杩涜涓�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "info";
+ } else if (type == 1) {
+ return "warning";
+ } else if (type == 2) {
+ return "success";
+ } else {
+ return "info";
+ }
+ };
+
+ // u-collapse 浜嬩欢澶勭悊鍑芥暟
+ const change = name => {
+ console.log("灞曞紑鐨勯潰鏉垮悕:", name);
+ };
+
+ const close = name => {
+ console.log("鍏抽棴鐨勯潰鏉垮悕:", name);
+ };
+
+ const open = name => {
+ console.log("鎵撳紑鐨勯潰鏉垮悕:", name);
+ };
+
+ onShow(async () => {
+ // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+ try {
+ // 涓や釜鏂规硶鎵ц瀹屾垚鍚庡啀鎵ц getList()
+ getList();
+ getnum();
+ } catch (error) {
+ console.error("鍒濆鍖栨暟鎹け璐�:", error);
+ // 鍗充娇鍑洪敊涔熸墽琛� getList()锛岀‘淇濋〉闈㈣兘姝e父鍔犺浇
+ getList();
+ getnum();
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .document-icon {
+ background: #ed8d05;
+ }
+
+ // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+ .fab-button {
+ background: #ed8d05;
+ }
+
+ // 鐗规湁鏍峰紡
+ .detail-row-user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .detail-row-approveReason {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+ }
+
+ .detail-value.highlightBlue {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.highlightYellow {
+ color: #ed8d05;
+ font-weight: 500;
+ }
+
+ .approver-value {
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ .approver-chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: #f0f6ff;
+ color: #2b7cff;
+ border: 1px solid #e0efff;
+ border-radius: 999px;
+ padding: 4px 10px;
+ max-width: 100%;
+ }
+
+ .approver-name {
+ font-size: 12px;
+ color: #2b7cff;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .actions {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ justify-content: flex-end;
+ margin-top: 18rpx;
+ }
+
+ .action-btn {
+ border-radius: 16px;
+ height: 28px;
+ line-height: 28px;
+ padding: 0 12px;
+ }
+ .topbox {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-left: 20px;
+ margin-right: 20px;
+ margin-top: 10px;
+ }
+ .boxItem {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #fff;
+ width: 24%;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ border-radius: 6px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+ }
+ .boxItem-num {
+ margin-bottom: 5px;
+ font-weight: 500;
+ color: #2979ff;
+ }
+
+ // 浼氳绾鏍峰紡
+ .meeting-content {
+ padding: 15px;
+ line-height: 1.6;
+ font-size: 14px;
+ }
+
+ .content-html {
+ color: #333;
+ word-break: break-word;
+ }
+
+ .content-html :deep(p) {
+ margin-bottom: 10px;
+ }
+
+ .content-html :deep(ul),
+ .content-html :deep(ol) {
+ margin-bottom: 10px;
+ padding-left: 20px;
+ }
+
+ .content-html :deep(li) {
+ margin-bottom: 5px;
+ }
+
+ .no-content {
+ color: #999;
+ text-align: center;
+ padding: 20px 0;
+ font-size: 14px;
+ }
+
+ // u-collapse 鏍峰紡浼樺寲
+ :deep(.u-collapse) {
+ margin-top: 10px;
+ border-radius: 6px;
+ overflow: hidden;
+ }
+
+ :deep(.u-collapse-item__header) {
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ :deep(.u-collapse-item__content) {
+ background-color: #fafafa;
+ border-top: 1px solid #f0f0f0;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingList/index.vue b/src/pages/managementMeetings/meetingList/index.vue
new file mode 100644
index 0000000..ad8a0de
--- /dev/null
+++ b/src/pages/managementMeetings/meetingList/index.vue
@@ -0,0 +1,537 @@
+<template>
+ <view class="meeting-list">
+ <PageHeader title="浼氳鍒楄〃"
+ @back="goBack" />
+ <!-- 鏌ヨ琛ㄥ崟 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="鏌ヨ鏃ユ湡"
+ @click.stop="showDatePicker"
+ v-model="queryForm.meetingDate"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="clearDate">
+ <u-icon name="close-circle-fill"
+ size="24"
+ color="#999"></u-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <up-datetime-picker v-model="datePickerValue"
+ mode="date"
+ :show="showDatePickerDialog"
+ @confirm="handleDateConfirm"
+ @cancel="showDatePickerDialog = false"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD" />
+ <!-- 浼氳瀹や娇鐢ㄦ儏鍐� -->
+ <view class="table-container">
+ <scroll-view scroll-x="true"
+ style="width: 100%;">
+ <view class="time-table">
+ <!-- 琛ㄥご -->
+ <view class="table-header">
+ <view class="header-cell room-header">浼氳瀹�</view>
+ <view v-for="timeSlot in timeSlots"
+ :key="timeSlot.value"
+ class="header-cell time-header">
+ {{ timeSlot.label }}
+ </view>
+ </view>
+ <!-- 琛ㄦ牸鍐呭 -->
+ <view class="table-body">
+ <view v-for="room in roomUsage"
+ :key="room.id"
+ class="table-row">
+ <view class="cell room-cell">{{ room.name }}</view>
+ <view class="cells-container">
+ <template v-for="(cell, index) in generateMeetingCells(room)"
+ :key="index">
+ <view class="cell content-cell"
+ :class="[cell.type, `status-${cell.meeting?.status || '0'}`]"
+ :style="{ width: `${cell.span * 120}rpx` }"
+ @click="viewMeetingDetails(cell)">
+ <view v-if="cell.type === 'meeting'"
+ class="meeting-content">
+ <view class="meeting-title">{{ cell.meeting.title }}</view>
+ <view class="meeting-time">{{ cell.startTime }}-{{ cell.endTime }}</view>
+ </view>
+ <view v-else
+ class="free-content">
+ 绌洪棽
+ </view>
+ </view>
+ </template>
+ </view>
+ </view>
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+ <!-- 浼氳璇︽儏瀵硅瘽妗� -->
+ <u-popup :show="detailDialogVisible"
+ mode="center"
+ customStyle="width: 80%;"
+ :round="10">
+ <view class="dialog-content">
+ <view class="dialog-header">
+ <text class="dialog-title">浼氳璇︽儏</text>
+ <up-icon name="close"
+ @click="detailDialogVisible = false"
+ class="close-icon"></up-icon>
+ </view>
+ <view v-if="currentMeeting"
+ class="dialog-body">
+ <view class="detail-item">
+ <text class="detail-label">浼氳涓婚</text>
+ <text class="detail-value">{{ currentMeeting.title }}</text>
+ </view>
+ <view class="detail-item">
+ <text class="detail-label">浼氳瀹�</text>
+ <text class="detail-value">{{ currentMeeting.room }}</text>
+ </view>
+ <view class="detail-item">
+ <text class="detail-label">浼氳鏃堕棿</text>
+ <text class="detail-value">{{ currentMeeting.time }}</text>
+ </view>
+ <view class="detail-item">
+ <text class="detail-label">涓绘寔浜�</text>
+ <text class="detail-value">{{ currentMeeting.host }}</text>
+ </view>
+ <view class="detail-item">
+ <text class="detail-label">鍙備細浜烘暟</text>
+ <text class="detail-value">{{ currentMeeting.participants }}浜�</text>
+ </view>
+ <view class="detail-item">
+ <text class="detail-label">浼氳璇存槑</text>
+ <text class="detail-value">{{ currentMeeting.description }}</text>
+ </view>
+ </view>
+ <view class="dialog-footer">
+ <u-button @click="detailDialogVisible = false">鍏抽棴</u-button>
+ </view>
+ </view>
+ </u-popup>
+ </view>
+</template>
+
+<script setup>
+ import { ref, reactive, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getMeetingUseList } from "@/api/managementMeetings/meeting.js";
+ import dayjs from "dayjs";
+
+ // 鏌ヨ琛ㄥ崟
+ const queryForm = reactive({
+ meetingDate: dayjs().format("YYYY-MM-DD"),
+ });
+
+ const loading = ref(false);
+ const timeSlots = ref([]);
+ const roomUsage = ref([]);
+ const currentMeeting = ref(null);
+ const detailDialogVisible = ref(false);
+ const showDatePickerDialog = ref(false);
+ const datePickerValue = ref(Date.now());
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ // 娓呯┖鏃ユ湡
+ const clearDate = () => {
+ datePickerValue.value = Date.now();
+ queryForm.meetingDate = dayjs().format("YYYY-MM-DD");
+ getList();
+ };
+
+ // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+ const showDatePicker = () => {
+ if (queryForm.meetingDate) {
+ datePickerValue.value = new Date(queryForm.meetingDate).getTime();
+ } else {
+ datePickerValue.value = Date.now();
+ }
+ console.log(datePickerValue.value, "datePickerValue.value");
+ showDatePickerDialog.value = true;
+ };
+
+ // 澶勭悊鏃ユ湡閫夋嫨纭
+ const handleDateConfirm = value => {
+ // dayjs().format("YYYY-MM-DD")
+ console.log(value, "value");
+
+ queryForm.meetingDate = dayjs(value.value).format("YYYY-MM-DD");
+ showDatePickerDialog.value = false;
+ getList();
+ };
+
+ // 鑾峰彇鍒楄〃鏁版嵁
+ const getList = () => {
+ handleSearch();
+ };
+
+ // 鍒濆鍖栨椂闂存Ы锛堜互鍗婂皬鏃朵负闂撮殧锛屼粠8:00鍒�17:30锛�
+ const initTimeSlots = () => {
+ const slots = [];
+ // 鐢熸垚8:00鍒�17:00鐨勬椂闂存
+ for (let hour = 8; hour <= 17; hour++) {
+ // 娣诲姞鏁寸偣
+ slots.push({
+ label: `${hour.toString().padStart(2, "0")}:00`,
+ value: `${hour.toString().padStart(2, "0")}:00`,
+ });
+
+ // 娣诲姞鍗婄偣锛岀洿鍒�17:30
+ if (hour <= 17) {
+ slots.push({
+ label: `${hour.toString().padStart(2, "0")}:30`,
+ value: `${hour.toString().padStart(2, "0")}:30`,
+ });
+ }
+ }
+ // 绉婚櫎鏈�鍚庝竴涓�18:00鐨勬椂闂存
+ if (slots.length > 0 && slots[slots.length - 1].value === "18:00") {
+ slots.pop();
+ }
+ timeSlots.value = slots;
+ console.log(timeSlots.value, "timeSlots.value");
+ };
+
+ // 鐢熸垚浼氳瀹ょ殑鏃堕棿鍗曞厓鏍�
+ 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;
+ }
+
+ if (startIdx !== -1) {
+ // 鏍囪琚崰鐢ㄧ殑鏃堕棿娈�
+ for (let i = startIdx; i < endIdx; i++) {
+ if (timeSlots.value[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 => {
+ console.log(cell, "cell");
+
+ if (cell && cell.type === "meeting") {
+ currentMeeting.value = cell.meeting;
+ detailDialogVisible.value = true;
+ } else {
+ uni.showToast({
+ title: "璇ユ椂闂存浼氳瀹ょ┖闂�",
+ icon: "info",
+ });
+ }
+ };
+
+ // 鏌ヨ鎸夐挳鎿嶄綔
+ const handleSearch = async () => {
+ loading.value = true;
+ try {
+ const resp = await getMeetingUseList({ ...queryForm });
+ roomUsage.value = resp.data;
+ } catch (error) {
+ uni.showToast({
+ title: "鑾峰彇鏁版嵁澶辫触",
+ icon: "error",
+ });
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ // 閲嶇疆鎼滅储琛ㄥ崟
+ const resetSearch = () => {
+ queryForm.meetingDate = dayjs().format("YYYY-MM-DD");
+ };
+
+ // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
+ onMounted(() => {
+ // 鍒濆鍖栨椂闂存Ы
+ initTimeSlots();
+
+ // 榛樿鏌ヨ浠婂ぉ鐨勬暟鎹�
+ handleSearch();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+ .meeting-list {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding: 16rpx;
+ }
+
+ .search-section {
+ background: #fff;
+ padding: 16rpx;
+ border-radius: 8rpx;
+ margin-bottom: 16rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+ }
+
+ .search-bar {
+ display: flex;
+ align-items: center;
+ gap: 12rpx;
+ }
+
+ .search-input {
+ flex: 1;
+ }
+
+ .filter-button {
+ padding: 12rpx 16rpx;
+ background: #f5f7fa;
+ border-radius: 4rpx;
+ }
+
+ .form-buttons {
+ display: flex;
+ gap: 12rpx;
+ margin-top: 16rpx;
+ justify-content: center;
+ }
+
+ .table-container {
+ margin-top: 16rpx;
+ overflow-x: auto;
+ }
+
+ .time-table {
+ width: 100%;
+ }
+
+ .table-header {
+ display: flex;
+ border: 1rpx solid #e4e7ed;
+ background: #f5f7fa;
+ }
+
+ .header-cell {
+ padding: 12rpx 8rpx;
+ text-align: center;
+ font-weight: bold;
+ border-right: 1rpx solid #e4e7ed;
+ }
+
+ .room-header {
+ width: 120rpx;
+ flex-shrink: 0;
+ }
+
+ .time-header {
+ width: 120rpx;
+ flex-shrink: 0;
+ }
+
+ .table-body {
+ border: 1rpx solid #e4e7ed;
+ border-top: none;
+ }
+
+ .table-row {
+ display: flex;
+ border-top: 1rpx solid #e4e7ed;
+ }
+
+ .table-row:first-child {
+ border-top: none;
+ }
+
+ .cell {
+ padding: 16rpx 8rpx;
+ text-align: center;
+ border-right: 1rpx solid #e4e7ed;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ word-break: break-word;
+ line-height: 1.2;
+ }
+
+ .room-cell {
+ width: 120rpx;
+ font-weight: bold;
+ flex-shrink: 0;
+ background: #f9fafc;
+ }
+
+ .cells-container {
+ display: flex;
+ }
+
+ .content-cell {
+ min-height: 120rpx;
+ cursor: pointer;
+ transition: all 0.3s;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 16rpx;
+ box-sizing: border-box;
+ }
+
+ .content-cell:active {
+ 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: #ecf5ff;
+ color: #409eff;
+ }
+
+ .meeting-content {
+ width: 100%;
+ }
+
+ .meeting-title {
+ font-weight: bold;
+ margin-bottom: 8rpx;
+ font-size: 24rpx;
+ }
+
+ .meeting-time {
+ font-size: 20rpx;
+ opacity: 0.8;
+ }
+
+ .free-content {
+ color: #909399;
+ }
+
+ /* 瀵硅瘽妗嗘牱寮� */
+ .dialog-content {
+ padding: 24rpx;
+ }
+
+ .dialog-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 24rpx;
+ padding-bottom: 16rpx;
+ border-bottom: 1rpx solid #e4e7ed;
+ }
+
+ .dialog-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ color: #303133;
+ }
+
+ .close-icon {
+ font-size: 32rpx;
+ color: #909399;
+ }
+
+ .dialog-body {
+ margin-bottom: 24rpx;
+ }
+
+ .detail-item {
+ display: flex;
+ margin-bottom: 16rpx;
+ padding: 8rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+ }
+
+ .detail-label {
+ width: 140rpx;
+ font-weight: bold;
+ color: #606266;
+ }
+
+ .detail-value {
+ flex: 1;
+ color: #303133;
+ }
+
+ .dialog-footer {
+ display: flex;
+ justify-content: center;
+ margin-top: 16rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingSettings/detail.vue b/src/pages/managementMeetings/meetingSettings/detail.vue
new file mode 100644
index 0000000..8e83099
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/detail.vue
@@ -0,0 +1,344 @@
+<template>
+ <view class="client-visit-detail">
+ <PageHeader title="浼氳瀹よ鎯�"
+ @back="goBack" />
+ <u-form ref="formRef"
+ label-width="90">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <u-cell-group title="浼氳瀹や俊鎭�">
+ <u-form-item label="浼氳瀹ゅ悕绉�"
+ prop="name"
+ required
+ border-bottom>
+ <u-input v-model="form.name"
+ placeholder="璇疯緭鍏ヤ細璁鍚嶇О" />
+ </u-form-item>
+ <u-form-item label="浣嶇疆"
+ required
+ prop="location"
+ border-bottom>
+ <u-input v-model="form.location"
+ placeholder="璇疯緭鍏ヤ綅缃�" />
+ </u-form-item>
+ <u-form-item label="瀹圭撼浜烘暟"
+ required
+ prop="capacity"
+ border-bottom>
+ <u-input v-model="form.capacity"
+ placeholder="璇疯緭鍏ュ绾充汉鏁�" />
+ </u-form-item>
+ <u-form-item label="璁惧閰嶇疆"
+ prop="equipment"
+ border-bottom>
+ <u-input v-model="form.equipment"
+ readonly
+ placeholder="璇烽�夋嫨璁惧閰嶇疆"
+ @click="showEquipmentSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openEquipmentSheet"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鐘舵��"
+ prop="status"
+ border-bottom>
+ <u-input v-model="statusname"
+ readonly
+ placeholder="璇烽�夋嫨鐘舵��"
+ @click="showStatusSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showStatusSheet = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="澶囨敞"
+ prop="remark"
+ border-bottom>
+ <u-input v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉�" />
+ </u-form-item>
+ </u-cell-group>
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="sign-btn"
+ type="primary"
+ @click="handleSubmit"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+ <u-popup :show="showEquipmentSheet"
+ mode="bottom"
+ @close="showEquipmentSheet = false"
+ height="200px">
+ <view class="popup-content">
+ <view class="popup-body">
+ <u-checkbox-group v-model="form.equipment"
+ @change="handleEquipmentChange"
+ icon-placement="right"
+ placement="row">
+ <view style="width:100%;padding:10px;margin-top:20px;">
+ <u-checkbox v-for="option in equipmentOptions"
+ :key="option.value"
+ :name="option.value"
+ :label="option.name"
+ class="checkbox-item"></u-checkbox>
+ </view>
+ </u-checkbox-group>
+ </view>
+ </view>
+ </u-popup>
+ <!-- 鐘舵�侀�夋嫨鍣� -->
+ <up-action-sheet :show="showStatusSheet"
+ :actions="statusOptions"
+ @select="onStatusSelect"
+ @close="showStatusSheet = false" />
+ </view>
+</template>
+
+<script setup>
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "meeting-settings-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { saveRoom } from "@/api/managementMeetings/meetingSettings";
+
+ const userStore = useUserStore();
+
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ name: "",
+ location: "",
+ capacity: "",
+ equipment: [],
+ status: "",
+ remark: "",
+ });
+ const equipmentOptions = ref([
+ { value: "鎶曞奖浠�", name: "鎶曞奖浠�" },
+ { value: "鐢佃", name: "鐢佃" },
+ { value: "闊冲搷", name: "闊冲搷" },
+ { value: "鐢佃瘽", name: "鐢佃瘽" },
+ { value: "瑙嗛浼氳绯荤粺", name: "瑙嗛浼氳绯荤粺" },
+ { value: "鐧芥澘", name: "鐧芥澘" },
+ { value: "鍐欏瓧鏉�", name: "鍐欏瓧鏉�" },
+ { value: "鏃犵嚎缃戠粶", name: "鏃犵嚎缃戠粶" },
+ ]);
+ const statusOptions = ref([
+ { value: "1", name: "鍚敤" },
+ { value: "0", name: "绂佺敤" },
+ ]);
+ //// 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
+ const showEquipmentSheet = ref(false);
+ const showStatusSheet = ref(false);
+ const openEquipmentSheet = () => {
+ showEquipmentSheet.value = true;
+ };
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const statusname = ref("");
+ // 鐘舵�侀�夋嫨
+ const onStatusSelect = action => {
+ form.value.status = action.value;
+ statusname.value = action.name;
+ showStatusSheet.value = false;
+ };
+ // 璁惧閰嶇疆閫夋嫨
+ const handleEquipmentChange = val => {
+ form.value.equipment = val;
+ console.log("form.value.equipment", form.value.equipment);
+ };
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = async () => {
+ if (!form.value.name) {
+ showToast("璇疯緭鍏ヤ細璁鍚嶇О");
+ return;
+ }
+
+ if (!form.value.location) {
+ showToast("璇疯緭鍏ヤ綅缃�");
+ return;
+ }
+
+ if (!form.value.capacity) {
+ showToast("璇疯緭鍏ュ绾充汉鏁�");
+ return;
+ }
+ try {
+ loading.value = true;
+ form.value.equipment = form.value.equipment.join(",");
+ form.value.status = Number(form.value.status);
+ form.value.capacity = Number(form.value.capacity);
+ // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
+ console.log("form.value", form.value);
+ saveRoom(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ } catch (e) {
+ loading.value = false;
+ console.error("淇濆瓨澶辫触:", e);
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ }
+ };
+
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const initPageData = () => {
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇浼氳 room 鏁版嵁
+ const meetingRoom = uni.getStorageSync("meetingRoom");
+ if (meetingRoom) {
+ form.value = JSON.parse(JSON.stringify(meetingRoom));
+ if (meetingRoom.equipment) {
+ if (Array.isArray(meetingRoom.equipment)) {
+ form.value.equipment = meetingRoom.equipment;
+ } else {
+ form.value.equipment = meetingRoom.equipment.split(",");
+ }
+ }
+ statusname.value = meetingRoom.status === 1 ? "鍚敤" : "绂佺敤";
+
+ // 娓呴櫎鏈湴瀛樺偍涓殑鏁版嵁锛岄伩鍏嶄笅娆℃墦寮�鏃朵粛鐒舵樉绀�
+ uni.removeStorageSync("meetingRoom");
+ }
+ };
+
+ onMounted(() => {
+ initPageData();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+ .client-visit {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
+
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #666;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .sign-btn {
+ font-weight: 500;
+ font-size: 1rem;
+ color: #fff;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border: none;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .location-icon {
+ color: #1989fa;
+ font-size: 1.2rem;
+ }
+
+ .selector-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ height: 100%;
+ }
+
+ .selector-text {
+ font-size: 14px;
+ color: #333;
+ }
+
+ .popup-content {
+ padding: 20rpx;
+ }
+
+ .popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+ }
+
+ .popup-title {
+ font-size: 16px;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .close-icon {
+ font-size: 20px;
+ color: #999;
+ }
+
+ .popup-body {
+ max-height: 60vh;
+ overflow-y: auto;
+ margin-bottom: 20rpx;
+ }
+
+ .checkbox-item {
+ margin-bottom: 15rpx;
+ font-size: 14px;
+ }
+
+ .popup-footer {
+ display: flex;
+ justify-content: space-between;
+ gap: 15rpx;
+ }
+
+ .cancel-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+
+ .confirm-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+ .checkbox-item {
+ margin-top: 40rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingSettings/index.vue b/src/pages/managementMeetings/meetingSettings/index.vue
new file mode 100644
index 0000000..5b7fbd4
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/index.vue
@@ -0,0 +1,244 @@
+<template>
+ <view class="sales-accoun">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浼氳璁剧疆"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+ v-model="name"
+ @blur="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <u-icon name="search"
+ size="24"
+ color="#999"></u-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鎷滆璁板綍鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="visitList.length > 0">
+ <view v-for="(item, index) in visitList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">浼氳瀹ゅ悕绉帮細{{ item.name || '-' }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <!-- <view class="detail-row">
+ <text class="detail-label">浼氳瀹ゅ悕绉�</text>
+ <text class="detail-value">{{ item.name || '-' }}</text>
+ </view> -->
+ <view class="detail-row">
+ <text class="detail-label">浣嶇疆</text>
+ <text class="detail-value">{{ item.location || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瀹圭撼浜烘暟</text>
+ <text class="detail-value">{{ item.capacity || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">璁惧閰嶇疆</text>
+ <text class="detail-value">{{ item.equipment }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐘舵��</text>
+ <text class="detail-value"
+ :class="{'status-enabled': item.status == 1, 'status-disabled': item.status == 0}">{{ item.status == 1 ? '鍚敤' : '绂佺敤' }}</text>
+ </view>
+ </view>
+ <!-- 鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <!-- <u-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item)">
+ 缂栬緫
+ </u-button>
+ <u-button type="error"
+ size="small"
+ class="action-btn"
+ @click="confirmDelete(item)">
+ 鍒犻櫎
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤浼氳瀹よ褰�</text>
+ </view>
+ <!-- 娴姩鏂板鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="addVisit">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ getMeetingRoomList,
+ delRoom,
+ } from "@/api/managementMeetings/meetingSettings";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-index" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+
+ // 鎼滅储鍏抽敭璇�
+ const name = ref("");
+
+ // 鎷滆璁板綍鏁版嵁
+ const visitList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const confirmDelete = item => {
+ uni.showModal({
+ title: "纭鍒犻櫎",
+ content: `鏄惁纭鍒犻櫎浼氳瀹� ${item.name}锛焋,
+ success: res => {
+ if (res.confirm) {
+ delRoom(item.id)
+ .then(() => {
+ showToast("鍒犻櫎鎴愬姛");
+ getList();
+ })
+ .catch(() => {
+ showToast("鍒犻櫎澶辫触");
+ });
+ }
+ },
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ name: name.value,
+ };
+ getMeetingRoomList(params)
+ .then(res => {
+ visitList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const addVisit = () => {
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetingSettings/detail",
+ });
+ };
+
+ // 缂栬緫
+ const viewDetail = item => {
+ uni.setStorageSync("meetingRoom", item);
+ uni.navigateTo({
+ url: "/pages/managementMeetings/meetingSettings/detail",
+ });
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+ .sales-accoun {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ padding-bottom: 80px;
+ }
+
+ // 鐗瑰畾鐨勫浘鏍囨牱寮�
+ .document-icon {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ }
+
+ // 鐗规湁鏍峰紡
+ .visit-status {
+ display: flex;
+ align-items: center;
+ }
+
+ .detail-value {
+ word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+ color: #333; // 淇濇寔椤甸潰鐗规湁鐨勬枃鏈鑹�
+ }
+
+ // 鐘舵�佹牱寮�
+ .status-enabled {
+ color: #28a745; // 淇濇寔椤甸潰鐗规湁鐨勬垚鍔熼鑹�
+ }
+
+ .status-disabled {
+ color: #dc3545; // 淇濇寔椤甸潰鐗规湁鐨勯敊璇鑹�
+ }
+
+ // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+ .fab-button {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+ }
+</style>
+
diff --git a/src/pages/managementMeetings/meetingSettings/view.vue b/src/pages/managementMeetings/meetingSettings/view.vue
new file mode 100644
index 0000000..f56ddb2
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/view.vue
@@ -0,0 +1,178 @@
+<template>
+ <view class="client-visit-detail">
+ <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
+
+ <!-- 鍐呭瀹瑰櫒 -->
+ <view class="content-container">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <view class="section">
+ <view class="section-title">瀹㈡埛淇℃伅</view>
+ <view class="info-item">
+ <text class="info-label">瀹㈡埛鍚嶇О</text>
+ <text class="info-value">{{ form.customerName || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鑱旂郴浜�</text>
+ <text class="info-value">{{ form.contact || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鑱旂郴鐢佃瘽</text>
+ <text class="info-value">{{ form.contactPhone || '-' }}</text>
+ </view>
+ </view>
+
+ <!-- 鎷滆淇℃伅 -->
+ <view class="section">
+ <view class="section-title">鎷滆淇℃伅</view>
+ <view class="info-item">
+ <text class="info-label">鎷滆鐩殑</text>
+ <text class="info-value">{{ form.purposeVisit || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鎷滆鏃堕棿</text>
+ <text class="info-value">{{ form.purposeDate || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鎷滆鍦扮偣</text>
+ <text class="info-value multi-line">{{ form.visitAddress || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鎷滆浜�</text>
+ <text class="info-value">{{ form.visitingPeople || '-' }}</text>
+ </view>
+ <view class="info-item" v-if="form.latitude && form.longitude">
+ <text class="info-label">缁忕含搴�</text>
+ <text class="info-value">{{ form.latitude }}, {{ form.longitude }}</text>
+ </view>
+ </view>
+
+ <!-- 澶囨敞淇℃伅 -->
+ <view class="section">
+ <view class="section-title">澶囨敞淇℃伅</view>
+ <view class="info-item remark-item">
+ <text class="info-label">澶囨敞</text>
+ <text class="info-value multi-line">{{ form.remark }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script setup>
+// 鏇挎崲 toast 鏂规硶
+const showToast = (message) => {
+ uni.showToast({
+ title: message,
+ icon: 'none'
+ })
+}
+
+import { ref, onMounted } from 'vue'
+import PageHeader from '@/components/PageHeader.vue'
+import useUserStore from "@/store/modules/user"
+
+const userStore = useUserStore()
+
+// 琛ㄥ崟鏁版嵁
+const form = ref({
+ customerName: '',
+ contact: '',
+ contactPhone: '',
+ visitingPeople: '',
+ purposeVisit: '',
+ purposeDate: '',
+ visitAddress: '',
+ latitude: '',
+ longitude: '',
+ locationAddress: '',
+ remark: ''
+})
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+ // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+ uni.removeStorageSync('clientVisit')
+ uni.navigateBack()
+}
+
+// 鍒濆鍖栭〉闈㈡暟鎹�
+const initPageData = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
+ const row = uni.getStorageSync('clientVisit')
+ if (row) {
+ form.value = { ...row }
+ } else {
+ showToast('鏆傛棤鎷滆璁板綍鏁版嵁')
+ }
+}
+
+onMounted(() => {
+ initPageData()
+})
+</script>
+
+<style scoped lang="scss">
+@import '@/static/scss/form-common.scss';
+
+.client-visit-detail {
+ min-height: 100vh;
+ background-color: #f8f9fa;
+}
+
+.content-container {
+ padding: 16px;
+}
+
+.section {
+ background-color: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+}
+
+.section-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333333;
+ padding: 16px 16px 12px;
+ border-bottom: 1px solid #f0f0f0;
+}
+
+.info-item {
+ display: flex;
+ padding: 14px 16px;
+ border-bottom: 1px solid #f8f8f8;
+ align-items: flex-start;
+}
+
+.info-item:last-child {
+ border-bottom: none;
+}
+
+.info-label {
+ font-size: 14px;
+ color: #666666;
+ min-width: 80px;
+ flex-shrink: 0;
+ line-height: 22px;
+}
+
+.info-value {
+ font-size: 14px;
+ color: #333333;
+ flex: 1;
+ line-height: 22px;
+ text-align: right;
+}
+
+.multi-line {
+ text-align: left;
+ word-break: break-all;
+ line-height: 1.6;
+}
+
+.remark-item {
+ padding-bottom: 16px;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue b/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue
new file mode 100644
index 0000000..363d665
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue
@@ -0,0 +1,455 @@
+<template>
+ <view class="client-visit-detail">
+ <PageHeader :title="detailType === 1 ? '鍙戝竷鍒跺害' : '鍒跺害璇︽儏'"
+ @back="goBack" />
+ <u-form ref="formRef"
+ label-width="90">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <!-- <u-cell-group title="鐭ヨ瘑淇℃伅"> -->
+ <u-form-item label="鍒跺害缂栧彿"
+ prop="regulationNum"
+ required
+ border-bottom>
+ <u-input v-model="form.regulationNum"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
+ </u-form-item>
+ <u-form-item label="鍒跺害鏍囬"
+ prop="title"
+ required
+ border-bottom>
+ <u-input v-model="form.title"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
+ </u-form-item>
+ <u-form-item label="鍒跺害鍒嗙被"
+ prop="type"
+ required
+ border-bottom>
+ <u-input v-model="equipmentname"
+ readonly
+ placeholder="璇烽�夋嫨鍒跺害鍒嗙被"
+ @click="showEquipmentSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="openEquipmentSheet"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鍒跺害鍐呭"
+ prop="scenario"
+ required
+ border-bottom>
+ <u-textarea v-model="form.content"
+ type="textarea"
+ rows="4"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ュ埗搴﹀唴瀹�" />
+ </u-form-item>
+ <u-form-item label="鍒跺害鐗堟湰"
+ prop="title"
+ border-bottom>
+ <u-input v-model="form.version"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
+ </u-form-item>
+ <u-form-item label="鐢熸晥鏃堕棿"
+ prop="status"
+ required
+ border-bottom>
+ <u-input v-model="form.effectiveTime"
+ readonly
+ placeholder="璇烽�夋嫨鐢熸晥鏃堕棿"
+ @click="showEffectiveTimeSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="showEffectiveTimeSheet = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="閫傜敤鑼冨洿"
+ required
+ prop="remark"
+ border-bottom>
+ <up-checkbox-group v-model="form.scope"
+ :disabled="readonly"
+ placement="column"
+ @change="checkboxChange">
+ <up-checkbox :customStyle="{marginBottom: '8px'}"
+ v-for="(item, index) in checkboxList1"
+ :key="index"
+ :label="item.name"
+ :name="item.value">
+ </up-checkbox>
+ </up-checkbox-group>
+ </u-form-item>
+ <u-form-item label="闇�瑕佺‘璁�"
+ prop="solution"
+ border-bottom>
+ <up-switch :disabled="readonly"
+ v-model="form.requireConfirm"></up-switch>
+ </u-form-item>
+ <!-- </u-cell-group> -->
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view v-if="!readonly"
+ class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="sign-btn"
+ type="primary"
+ @click="handleSubmit"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+ <up-action-sheet :show="showEquipmentSheet"
+ :actions="equipmentOptions"
+ @select="handleEquipmentChange"
+ @close="showEquipmentSheet = false" />
+ <!-- 鐘舵�侀�夋嫨鍣� -->
+ <up-action-sheet :show="showStatusSheet"
+ :actions="statusOptions"
+ @select="onStatusSelect"
+ @close="showStatusSheet = false" />
+ <up-datetime-picker :show="showEffectiveTimeSheet"
+ @confirm="handleEffectiveTimeConfirm"
+ @cancel="showEffectiveTimeSheet = false"
+ v-model="effectiveTime"
+ mode="datetime"></up-datetime-picker>
+ </view>
+</template>
+
+<script setup>
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "meeting-settings-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import { ref, onMounted, computed } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { onLoad } from "@dcloudio/uni-app";
+ import {
+ addRuleManagement,
+ updateRuleManagement,
+ } from "@/api/managementMeetings/rulesRegulationsManagement";
+ import dayjs from "dayjs";
+ const userStore = useUserStore();
+ const showEffectiveTimeSheet = ref(false);
+ const effectiveTime = ref(new Date());
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ id: "",
+ regulationNum: "",
+ title: "",
+ category: "",
+ content: "",
+ version: "",
+ status: "active",
+ readCount: 0,
+ effectiveTime: "",
+ scope: [],
+ requireConfirm: false,
+ });
+ const checkboxList1 = ref([
+ { name: "鍏ㄤ綋鍛樺伐", value: "all" },
+ { name: "绠$悊灞�", value: "manager" },
+ { name: "浜轰簨閮ㄩ棬", value: "hr" },
+ { name: "璐㈠姟閮ㄩ棬", value: "finance" },
+ { name: "鎶�鏈儴闂�", value: "tech" },
+ ]);
+ const equipmentOptions = ref([
+ { value: "hr", name: "浜轰簨鍒跺害" },
+ { value: "finance", name: "璐㈠姟鍒跺害" },
+ { value: "safety", name: "瀹夊叏鍒跺害" },
+ { value: "tech", name: "鎶�鏈埗搴�" },
+ ]);
+ const statusOptions = ref([
+ { value: "high", name: "鏄捐憲鎻愬崌" },
+ { value: "medium", name: "涓�鑸彁鍗�" },
+ { value: "low", name: "杞诲井鎻愬崌" },
+ ]);
+ //// 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
+ const showEquipmentSheet = ref(false);
+ const showStatusSheet = ref(false);
+ const openEquipmentSheet = () => {
+ showEquipmentSheet.value = true;
+ };
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const statusname = ref("");
+ // 鐘舵�侀�夋嫨
+ const onStatusSelect = action => {
+ form.value.efficiency = action.value;
+ statusname.value = action.name;
+ showStatusSheet.value = false;
+ };
+ const equipmentname = ref("");
+ const handleEffectiveTimeConfirm = () => {
+ form.value.effectiveTime = dayjs(effectiveTime.value).format(
+ "YYYY-MM-DD HH:mm:ss"
+ );
+ showEffectiveTimeSheet.value = false;
+ };
+ // 鍒跺害鍒嗙被閫夋嫨
+ const handleEquipmentChange = val => {
+ form.value.category = val.value;
+ equipmentname.value = val.name;
+ showEquipmentSheet.value = false;
+ };
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = async () => {
+ if (!form.value.regulationNum) {
+ showToast("璇疯緭鍏ュ埗搴︾紪鍙�");
+ return;
+ }
+
+ if (!form.value.title) {
+ showToast("璇疯緭鍏ュ埗搴︽爣棰�");
+ return;
+ }
+
+ if (!form.value.category) {
+ showToast("璇烽�夋嫨鍒跺害鍒嗙被");
+ return;
+ }
+ if (!form.value.content) {
+ showToast("璇疯緭鍏ュ埗搴﹀唴瀹�");
+ return;
+ }
+ if (!form.value.effectiveTime) {
+ showToast("璇烽�夋嫨鐢熸晥鏃堕棿");
+ return;
+ }
+ if (!form.value.scope.length) {
+ showToast("璇烽�夋嫨鐢熸晥鑼冨洿");
+ return;
+ }
+ try {
+ loading.value = true;
+ if (detailType.value === 1) {
+ addRuleManagement(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ } else if (detailType.value === 2) {
+ updateRuleManagement(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ }
+ } catch (e) {
+ loading.value = false;
+ console.error("淇濆瓨澶辫触:", e);
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ }
+ };
+
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const initPageData = () => {
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇浼氳 room 鏁版嵁
+ const meetingRoom = uni.getStorageSync("meetingRoom");
+ if (meetingRoom) {
+ form.value = JSON.parse(JSON.stringify(meetingRoom));
+ if (meetingRoom.equipment) {
+ if (Array.isArray(meetingRoom.equipment)) {
+ form.value.equipment = meetingRoom.equipment;
+ } else {
+ form.value.equipment = meetingRoom.equipment.split(",");
+ }
+ }
+ statusname.value = meetingRoom.status === 1 ? "鍚敤" : "绂佺敤";
+
+ // 娓呴櫎鏈湴瀛樺偍涓殑鏁版嵁锛岄伩鍏嶄笅娆℃墦寮�鏃朵粛鐒舵樉绀�
+ uni.removeStorageSync("meetingRoom");
+ }
+ };
+ const readonly = ref(false);
+ const detailType = ref(1);
+ const knowledgeId = ref("");
+
+ onLoad(options => {
+ detailType.value = Number(options.detailType);
+ knowledgeId.value = options.id || "";
+
+ // 鏌ョ湅妯″紡璁剧疆鍙
+ if (detailType.value === 3) {
+ readonly.value = true;
+ }
+ });
+ // 閲嶇疆琛ㄥ崟
+ const resetForm = () => {
+ form.value = {
+ id: "",
+ regulationNum: "",
+ title: "",
+ category: "",
+ content: "",
+ version: "",
+ status: "active",
+ readCount: 0,
+ effectiveTime: "",
+ scope: [],
+ requireConfirm: false,
+ };
+ equipmentname.value = "";
+ statusname.value = "";
+ };
+ onMounted(() => {
+ console.log(effectiveTime.value, "鐢熸晥鏃堕棿");
+
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇鐭ヨ瘑鏁版嵁
+ const rulesRegulations = uni.getStorageSync("rulesRegulations");
+ initPageData();
+ if (rulesRegulations) {
+ form.value = JSON.parse(JSON.stringify(rulesRegulations));
+ }
+
+ if (detailType.value === 1) {
+ resetForm();
+ }
+
+ if (detailType.value != 1) {
+ equipmentname.value =
+ equipmentOptions.value.find(item => item.value == form.value.category)
+ ?.name || "";
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+ .client-visit {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
+
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #666;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .sign-btn {
+ font-weight: 500;
+ font-size: 1rem;
+ color: #fff;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border: none;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .location-icon {
+ color: #1989fa;
+ font-size: 1.2rem;
+ }
+
+ .selector-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ height: 100%;
+ }
+
+ .selector-text {
+ font-size: 14px;
+ color: #333;
+ }
+
+ .popup-content {
+ padding: 20rpx;
+ }
+
+ .popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+ }
+
+ .popup-title {
+ font-size: 16px;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .close-icon {
+ font-size: 20px;
+ color: #999;
+ }
+
+ .popup-body {
+ max-height: 60vh;
+ overflow-y: auto;
+ margin-bottom: 20rpx;
+ }
+
+ .checkbox-item {
+ margin-bottom: 15rpx;
+ font-size: 14px;
+ }
+
+ .popup-footer {
+ display: flex;
+ justify-content: space-between;
+ gap: 15rpx;
+ }
+
+ .cancel-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+
+ .confirm-btn-popup {
+ flex: 1;
+ border-radius: 8rpx;
+ }
+ .checkbox-item {
+ margin-top: 40rpx;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue b/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue
new file mode 100644
index 0000000..3105e4e
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue
@@ -0,0 +1,559 @@
+<template>
+ <view class="file-list-page">
+ <!-- 椤甸潰澶撮儴 -->
+ <PageHeader title="闄勪欢绠$悊"
+ @back="goBack" />
+ <!-- 闄勪欢鍒楄〃 -->
+ <view class="file-list-container">
+ <view v-if="fileList.length > 0"
+ class="file-list">
+ <view v-for="(file, index) in fileList"
+ :key="file.id || index"
+ class="file-item">
+ <!-- 鏂囦欢鍥炬爣 -->
+ <!-- <view class="file-icon"
+ :class="getFileIconClass(file.fileType)">
+ <up-icon :name="getFileIcon(file.fileType)"
+ size="24"
+ color="#ffffff" />
+ </view> -->
+ <!-- 鏂囦欢淇℃伅 -->
+ <view class="file-info">
+ <text class="file-name">{{ file.name }}</text>
+ <!-- <text class="file-meta">{{ formatFileSize(file.fileSize) }} 路 {{ file.uploadTime || file.createTime }}</text> -->
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="file-actions">
+ <!-- <u-button size="small"
+ type="primary"
+ plain
+ @click="previewFile(file)">棰勮</u-button> -->
+ <u-button size="small"
+ type="info"
+ plain
+ @click="downloadFile(file)">涓嬭浇骞堕瑙�</u-button>
+ <u-button size="small"
+ type="error"
+ plain
+ @click="confirmDelete(file, index)">鍒犻櫎</u-button>
+ </view>
+ </view>
+ </view>
+ <!-- 绌虹姸鎬� -->
+ <view v-else
+ class="empty-state">
+ <up-icon name="document"
+ size="64"
+ color="#c0c4cc" />
+ <text class="empty-text">鏆傛棤闄勪欢</text>
+ </view>
+ </view>
+ <!-- <a rel="nofollow"
+ id="downloadLink"
+ href="#"
+ style="display:none;">涓嬭浇鏂囨湰鏂囦欢</a> -->
+ <!-- 涓婁紶鎸夐挳 -->
+ <view class="upload-button"
+ @click="chooseFile">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff" />
+ <text class="upload-text">涓婁紶闄勪欢</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import config from "@/config";
+ import { getToken } from "@/utils/auth";
+ // import { saveAs } from "file-saver";
+ import {
+ listRuleFiles,
+ addRuleFile,
+ delRuleFile,
+ upload,
+ } from "@/api/managementMeetings/rulesRegulationsManagement";
+ import { blobValidate } from "@/utils/ruoyi";
+
+ // 闄勪欢鍒楄〃
+ const fileList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // const request = axios.create({
+ // baseURL: "URL.com",
+ // adapter: axiosAdapterUniapp,
+ // });
+ // 鑾峰彇鏂囦欢鍥炬爣
+ const getFileIcon = fileType => {
+ const iconMap = {
+ doc: "document",
+ docx: "document",
+ xls: "grid",
+ xlsx: "grid",
+ pdf: "document",
+ ppt: "copy",
+ pptx: "copy",
+ txt: "document",
+ jpg: "image",
+ jpeg: "image",
+ png: "image",
+ gif: "image",
+ zip: "folder",
+ rar: "folder",
+ };
+ return iconMap[fileType.toLowerCase()] || "document";
+ };
+
+ // 鑾峰彇鏂囦欢鍥炬爣鏍峰紡绫�
+ const getFileIconClass = fileType => {
+ const colorMap = {
+ doc: "blue",
+ docx: "blue",
+ xls: "green",
+ xlsx: "green",
+ pdf: "red",
+ ppt: "orange",
+ pptx: "orange",
+ txt: "gray",
+ jpg: "purple",
+ jpeg: "purple",
+ png: "purple",
+ gif: "purple",
+ zip: "yellow",
+ rar: "yellow",
+ };
+ return colorMap[fileType.toLowerCase()] || "gray";
+ };
+
+ // 鏍煎紡鍖栨枃浠跺ぇ灏�
+ 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 chooseFile = () => {
+ uni.chooseImage({
+ count: 9,
+ sizeType: ["original", "compressed"],
+ sourceType: ["album", "camera"],
+ success: res => {
+ console.log(res, "閫夋嫨鍥剧墖鎴愬姛");
+ uploadFiles(res.tempFiles);
+ },
+ fail: err => {
+ console.error("閫夋嫨鍥剧墖澶辫触:", err);
+ showToast("閫夋嫨鏂囦欢澶辫触");
+ },
+ });
+ // uni.chooseFile({
+ // count: 9,
+ // extension: [
+ // ".doc",
+ // ".docx",
+ // ".xls",
+ // ".xlsx",
+ // ".pdf",
+ // ".ppt",
+ // ".pptx",
+ // ".txt",
+ // ".jpg",
+ // ".jpeg",
+ // ".png",
+ // ".gif",
+ // ".zip",
+ // ".rar",
+ // ],
+ // success: res => {
+ // console.log(res, "閫夋嫨鏂囦欢鎴愬姛");
+ // uploadFiles(res.tempFiles);
+ // },
+ // fail: err => {
+ // showToast("閫夋嫨鏂囦欢澶辫触");
+ // },
+ // });
+ };
+
+ // 涓婁紶鏂囦欢
+ const uploadFiles = tempFiles => {
+ console.log(tempFiles, "涓婁紶鏂囦欢1");
+ tempFiles.forEach((tempFile, index) => {
+ // 鏄剧ず涓婁紶涓彁绀�
+ uni.showLoading({
+ title: "涓婁紶涓�...",
+ mask: true,
+ });
+ console.log(tempFile, "涓婁紶鏂囦欢2");
+ // 1. 鐩存帴浣跨敤 uni.uploadFile 涓婁紶鏂囦欢
+ uni.uploadFile({
+ url: config.baseUrl + "/file/upload",
+ filePath: tempFile.path,
+ name: "file",
+ header: {
+ Authorization: "Bearer " + getToken(),
+ },
+ success: uploadRes => {
+ uni.hideLoading();
+ console.log(uploadRes, "涓婁紶鏂囦欢3");
+
+ try {
+ const res = JSON.parse(uploadRes.data);
+ console.log(res, "涓婁紶鏂囦欢4");
+ if (res.code === 200) {
+ // 2. 鎻愬彇鏂囦欢淇℃伅
+ const fileName = tempFile.name
+ ? tempFile.name
+ : tempFile.path.split("/").pop();
+ // const fileType = fileName.split(".").pop();
+ // 3. 鏋勯�犱繚瀛樻枃浠朵俊鎭殑鍙傛暟
+ const saveData = {
+ name: fileName,
+ rulesRegulationsManagementId: rulesRegulationsManagementId.value,
+ url: res.data.tempPath || "",
+ };
+ console.log(saveData, "淇濆瓨鏂囦欢淇℃伅鍙傛暟");
+ // 4. 璋冪敤 addRuleFile 鎺ュ彛淇濆瓨鏂囦欢淇℃伅
+ addRuleFile(saveData)
+ .then(addRes => {
+ if (addRes.code === 200) {
+ // 5. 娣诲姞鍒版枃浠跺垪琛�
+ const newFile = {
+ ...addRes.data,
+ uploadTime: new Date().toLocaleString(),
+ };
+ // fileList.value.push(newFile);
+ getFileList();
+ showToast("涓婁紶鎴愬姛");
+ } else {
+ showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+ }
+ })
+ .catch(err => {
+ console.error("淇濆瓨鏂囦欢淇℃伅澶辫触:", err);
+ showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+ });
+ } else {
+ showToast("鏂囦欢涓婁紶澶辫触");
+ }
+ } catch (e) {
+ console.error("瑙f瀽涓婁紶缁撴灉澶辫触:", e);
+ showToast("涓婁紶澶辫触");
+ }
+ },
+ fail: err => {
+ uni.hideLoading();
+ console.error("涓婁紶澶辫触:", err);
+ showToast("涓婁紶澶辫触");
+ },
+ });
+ });
+ };
+ // 涓嬭浇鏂囦欢
+ const downloadFile = file => {
+ var url =
+ config.baseUrl +
+ "/common/download?fileName=" +
+ encodeURIComponent(file.url) +
+ "&delete=true";
+ console.log(url, "url");
+
+ uni
+ .downloadFile({
+ url: url,
+ responseType: "blob",
+ header: { Authorization: "Bearer " + getToken() },
+ })
+ .then(res => {
+ let osType = uni.getStorageSync("deviceInfo").osName;
+ let filePath = res.tempFilePath;
+ if (osType === "ios") {
+ uni.openDocument({
+ filePath: filePath,
+ showMenu: true,
+ success: res => {
+ resolve(res);
+ },
+ fail: err => {
+ console.log("uni.openDocument--fail");
+ reject(err);
+ },
+ });
+ } else {
+ uni.saveFile({
+ tempFilePath: filePath,
+ success: fileRes => {
+ uni.showToast({
+ icon: "none",
+ mask: true,
+ title:
+ "鏂囦欢宸蹭繚瀛橈細Android/data/uni.UNI720216F/apps/__UNI__720216F/" +
+ fileRes.savedFilePath, //淇濆瓨璺緞
+ duration: 3000,
+ });
+ setTimeout(() => {
+ //鎵撳紑鏂囨。鏌ョ湅
+ uni.openDocument({
+ filePath: fileRes.savedFilePath,
+ success: function (res) {
+ resolve(fileRes);
+ },
+ });
+ }, 3000);
+ },
+ fail: err => {
+ console.log("uni.save--fail");
+ reject(err);
+ },
+ });
+ }
+ // const isBlob = blobValidate(res.data);
+ // if (isBlob) {
+ // const blob = new Blob([res.data], { type: "text/plain" });
+ // const url = URL.createObjectURL(blob);
+ // const downloadLink = document.getElementById("downloadLink");
+ // downloadLink.href = url;
+ // downloadLink.download = file.name;
+ // downloadLink.click();
+ // showToast("涓嬭浇鎴愬姛");
+ // } else {
+ // showToast("涓嬭浇澶辫触");
+ // }
+ })
+ .catch(err => {
+ console.error("涓嬭浇澶辫触:", err);
+ showToast("涓嬭浇澶辫触");
+ });
+ };
+
+ // 纭鍒犻櫎
+ const confirmDelete = (file, index) => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄ら檮浠� "${file.name}" 鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ deleteFile(file.id, index);
+ }
+ },
+ });
+ };
+
+ // 鍒犻櫎鏂囦欢
+ const deleteFile = (fileId, index) => {
+ uni.showLoading({
+ title: "鍒犻櫎涓�...",
+ mask: true,
+ });
+
+ delRuleFile([fileId])
+ .then(res => {
+ uni.hideLoading();
+ if (res.code === 200) {
+ // fileList.value.splice(index, 1);
+ getFileList();
+ showToast("鍒犻櫎鎴愬姛");
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ })
+ .catch(err => {
+ uni.hideLoading();
+ showToast("鍒犻櫎澶辫触");
+ });
+ };
+
+ // 鏄剧ず鎻愮ず
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ const rulesRegulationsManagementId = ref("");
+ // 椤甸潰鍔犺浇鏃�
+ onMounted(() => {
+ // 浠� API 鑾峰彇闄勪欢鍒楄〃
+ getFileList();
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙� rulesRegulationsManagementId
+ rulesRegulationsManagementId.value = uni.getStorageSync(
+ "rulesRegulationsManagement"
+ );
+ });
+
+ // 鑾峰彇闄勪欢鍒楄〃
+ const getFileList = () => {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ mask: true,
+ });
+
+ listRuleFiles()
+ .then(res => {
+ uni.hideLoading();
+ if (res.code === 200) {
+ fileList.value = res.data.records || [];
+ } else {
+ showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+ }
+ })
+ .catch(err => {
+ uni.hideLoading();
+ showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+ });
+ };
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ .file-list-page {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 100rpx;
+ }
+
+ .file-list-container {
+ padding: 20rpx;
+ }
+
+ .file-list {
+ background: #ffffff;
+ border-radius: 8rpx;
+ overflow: hidden;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+ }
+
+ .file-item {
+ display: flex;
+ align-items: center;
+ padding: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+
+ .file-icon {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 8rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-right: 20rpx;
+
+ &.blue {
+ background: #409eff;
+ }
+
+ &.green {
+ background: #67c23a;
+ }
+
+ &.red {
+ background: #f56c6c;
+ }
+
+ &.orange {
+ background: #e6a23c;
+ }
+
+ &.gray {
+ background: #909399;
+ }
+
+ &.purple {
+ background: #909399;
+ }
+
+ &.yellow {
+ background: #e6a23c;
+ }
+ }
+
+ .file-info {
+ flex: 1;
+ min-width: 0;
+ }
+
+ .file-name {
+ display: block;
+ font-size: 16px;
+ color: #303133;
+ margin-bottom: 8rpx;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .file-meta {
+ display: block;
+ font-size: 12px;
+ color: #909399;
+ }
+
+ .file-actions {
+ display: flex;
+ gap: 12rpx;
+ }
+
+ .empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 100rpx 0;
+ background: #ffffff;
+ border-radius: 8rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+ }
+
+ .empty-text {
+ font-size: 14px;
+ color: #909399;
+ margin-top: 20rpx;
+ }
+
+ .upload-button {
+ position: fixed;
+ bottom: 40rpx;
+ right: 40rpx;
+ width: 130rpx;
+ height: 130rpx;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4);
+ z-index: 1000;
+ }
+
+ .upload-text {
+ font-size: 10px;
+ color: #ffffff;
+ margin-top: 4rpx;
+ }
+
+ .upload-progress {
+ padding: 40rpx 0;
+ }
+
+ .upload-progress-text {
+ display: block;
+ text-align: center;
+ margin-top: 20rpx;
+ font-size: 14px;
+ color: #606266;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/index.vue b/src/pages/managementMeetings/rulesRegulationsManagement/index.vue
new file mode 100644
index 0000000..e6cef23
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/index.vue
@@ -0,0 +1,451 @@
+<template>
+ <view class="sales-accoun">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="瑙勭珷鍒跺害绠$悊"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ埗搴︽爣棰�"
+ v-model="name"
+ @blur="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <u-icon name="search"
+ size="24"
+ color="#999"></u-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鎷滆璁板綍鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="visitList.length > 0">
+ <view v-for="(item, index) in visitList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">鍒跺害鏍囬锛歿{ item.title || '-' }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍒跺害缂栧彿</text>
+ <text class="detail-value">{{ item.regulationNum || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍒嗙被</text>
+ <u-tag size="mini">{{ formatReceiptType(item.category) }}</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐗堟湰</text>
+ <text class="detail-value">{{ item.version || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戝竷浜�</text>
+ <text class="detail-value">{{ item.createUserName || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戝竷鏃堕棿</text>
+ <text class="detail-value">{{ item.createTime || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐘舵��</text>
+ <u-tag size="mini"
+ :type="item.status === 'active' ? 'success' : 'info'">
+ {{ item.status === "active" ? '鐢熸晥涓�' : '宸插簾姝�' }}
+ </u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸茶浜烘暟</text>
+ <text class="detail-value">{{ item.readCount || '-' }}</text>
+ </view>
+ <u-collapse border="false"
+ accordion
+ @open="(value) => handleOpen(value, index)">
+ <u-collapse-item title="鐗堟湰鍘嗗彶"
+ border="false"
+ :name="item.category">
+ <view class="table-container">
+ <u-table2 :data="item.tableData1"
+ :columns="columns"
+ stripe
+ border />
+ </view>
+ </u-collapse-item>
+ <!-- <u-collapse-item title="闃呰鐘舵��"
+ border="false"
+ :name="item.id">
+ <view class="table-container">
+ <u-table2 :data="item.tableData2"
+ :columns="columns2"
+ stripe
+ border />
+ </view>
+ </u-collapse-item> -->
+ </u-collapse>
+ </view>
+ <!-- 鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <u-button type="info"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item,3)">
+ 鏌ョ湅
+ </u-button>
+ <!-- <u-button type="error"
+ size="small"
+ class="action-btn"
+ @click="handleAbrogate(item)">
+ 搴熷純
+ </u-button>
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item,2)">
+ 缂栬緫
+ </u-button> -->
+ <u-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="fileList(item,2)">
+ 闄勪欢
+ </u-button>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤瑙勭珷鍒跺害</text>
+ </view>
+ <!-- 娴姩鏂板鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="addVisit">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, computed } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { useDict } from "@/utils/dict";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ listRuleManagement,
+ getReadingStatusList,
+ getReadingStatusByRuleId,
+ updateRuleManagement,
+ // delKnowledgeBase,
+ } from "@/api/managementMeetings/rulesRegulationsManagement";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-index" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+ // 搴熷純瑙勭珷鍒跺害
+ const handleAbrogate = item => {
+ uni.showModal({
+ title: "搴熷純纭",
+ content: `纭畾瑕佸簾寮冭瑙勭珷鍒跺害鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ item.status = "repealed";
+ updateRuleManagement(item).then(() => {
+ showToast("搴熷純鎴愬姛");
+ getList();
+ });
+ }
+ },
+ });
+ };
+ // 闄勪欢鍒楄〃
+ const fileList = item => {
+ console.log(item.id, "item");
+ uni.setStorageSync("rulesRegulationsManagement", item.id);
+ // // 闄勪欢鍒楄〃璺宠浆鍒拌鎯呴〉闈�
+ uni.navigateTo({
+ url: "/pages/managementMeetings/rulesRegulationsManagement/fileList",
+ });
+ };
+ const columns = ref([
+ { title: "鐗堟湰鍙�", key: "version", width: 100 },
+ { title: "鏇存柊鏃堕棿", key: "updateTime", width: 200 },
+ { title: "鏇存柊浜�", key: "createUserName", width: 150 },
+ { title: "鍙樻洿璇存槑", key: "status", width: 100 },
+ ]);
+ const columns2 = ref([
+ { title: "鍛樺伐濮撳悕", key: "employee", width: 150 },
+ { title: "鎵�灞為儴闂�", key: "department", width: 150 },
+ { title: "闃呰鏃堕棿", key: "createTime", width: 200 },
+ { title: "纭鏃堕棿", key: "confirmTime", width: 200 },
+ { title: "鐘舵��", key: "status", width: 100 },
+ ]);
+ // 鎼滅储鍏抽敭璇�
+ const name = ref("");
+
+ // 鎷滆璁板綍鏁版嵁
+ const visitList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const { knowledge_type } = useDict("knowledge_type");
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == "hr") {
+ return "浜轰簨鍒跺害";
+ } else if (params == "finance") {
+ return "璐㈠姟鍒跺害";
+ } else if (params == "safety") {
+ return "瀹夊叏鍒跺害";
+ } else if (params == "tech") {
+ return "鎶�鏈埗搴�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ const getTagClass = type => {
+ if (type == "high") {
+ return "success";
+ } else if (type == "medium") {
+ return "warning";
+ } else if (type == "low") {
+ return "info";
+ } else {
+ return "info";
+ }
+ };
+ const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+ // 鑾峰彇鐭ヨ瘑绫诲瀷鏍囩
+ const getKnowledgeTypeLabel = val => {
+ console.log(knowledgeTypeOptions, "knowledgeTypeOptions");
+ const item = knowledgeTypeOptions.value.find(
+ i => String(i.value) === String(val)
+ );
+ return item ? item.label : val;
+ };
+ const handleOpen = (value, index) => {
+ if (
+ value == "hr" ||
+ value == "finance" ||
+ value == "safety" ||
+ value == "tech"
+ ) {
+ // 鍘嗗彶鐗堟湰
+ const params = {
+ current: -1,
+ size: -1,
+ category: value,
+ };
+ listRuleManagement(params)
+ .then(res => {
+ visitList.value[index].tableData1 = res.data.records;
+ visitList.value[index].tableData1.forEach(item => {
+ item.status = item.status == "active" ? "鐢熸晥涓�" : "宸插簾姝�";
+ });
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ } else {
+ // 闃呰鐘舵��
+ getReadingStatusByRuleId(value)
+ .then(res => {
+ visitList.value[index].tableData2 = res.data;
+ visitList.value[index].tableData2.forEach(item => {
+ item.status = item.status == "confirmed" ? "宸茬‘璁�" : "鏈‘璁�";
+ });
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ }
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ title: name.value,
+ };
+ listRuleManagement(params)
+ .then(res => {
+ visitList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const addVisit = () => {
+ uni.navigateTo({
+ url: "/pages/managementMeetings/rulesRegulationsManagement/detail?detailType=1",
+ });
+ };
+
+ // 缂栬緫
+ const viewDetail = (item, detailType) => {
+ uni.setStorageSync("rulesRegulations", item);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/rulesRegulationsManagement/detail?detailType=" +
+ detailType +
+ "&id=" +
+ item.id,
+ });
+ };
+
+ // 鍒犻櫎纭
+ const confirmDelete = item => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄ょ煡璇� "${item.title}" 鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ deleteKnowledge(item.id);
+ }
+ },
+ });
+ };
+
+ // 鎵ц鍒犻櫎
+ const deleteKnowledge = id => {
+ showLoadingToast("鍒犻櫎涓�...");
+ delKnowledgeBase([id])
+ .then(res => {
+ closeToast();
+ if (res.code === 200) {
+ showToast("鍒犻櫎鎴愬姛");
+ getList(); // 閲嶆柊鑾峰彇鍒楄〃
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鍒犻櫎澶辫触");
+ });
+ };
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+ .sales-accoun {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ padding-bottom: 80px;
+ }
+
+ // 鐗瑰畾鐨勫浘鏍囨牱寮�
+ .document-icon {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ }
+
+ // 鐗规湁鏍峰紡
+ .visit-status {
+ display: flex;
+ align-items: center;
+ }
+
+ .detail-value {
+ word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+ color: #333; // 淇濇寔椤甸潰鐗规湁鐨勬枃鏈鑹�
+ }
+
+ // 鐘舵�佹牱寮�
+ .status-enabled {
+ color: #28a745; // 淇濇寔椤甸潰鐗规湁鐨勬垚鍔熼鑹�
+ }
+
+ .status-disabled {
+ color: #dc3545; // 淇濇寔椤甸潰鐗规湁鐨勯敊璇鑹�
+ }
+
+ // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+ .fab-button {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+ }
+
+ // 琛ㄦ牸瀹瑰櫒锛屽疄鐜版í鍚戞粴鍔�
+ .table-container {
+ overflow-x: auto;
+ margin: 0 -20rpx;
+ padding: 0 20rpx;
+ }
+
+ .table-container::-webkit-scrollbar {
+ height: 6rpx;
+ }
+
+ .table-container::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 3rpx;
+ }
+
+ .table-container::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 3rpx;
+ }
+
+ .table-container::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+ }
+ // .u-table2 {
+ // width: 500px;
+ // }
+</style>
+
diff --git a/src/pages/managementMeetings/sealManagement/detail.vue b/src/pages/managementMeetings/sealManagement/detail.vue
new file mode 100644
index 0000000..b206f54
--- /dev/null
+++ b/src/pages/managementMeetings/sealManagement/detail.vue
@@ -0,0 +1,330 @@
+<template>
+ <view class="client-visit-detail">
+ <PageHeader :title="detailType === 1 ? '鏂板鐢ㄥ嵃' : '鐢ㄥ嵃璇︽儏'"
+ @back="goBack" />
+ <u-form ref="formRef"
+ label-width="90">
+ <!-- 瀹㈡埛淇℃伅 -->
+ <!-- <u-cell-group title="鐭ヨ瘑淇℃伅"> -->
+ <u-form-item label="鐢宠缂栧彿"
+ prop="applicationNum"
+ required
+ border-bottom>
+ <u-input v-model="form.applicationNum"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ョ敵璇风紪鍙�" />
+ </u-form-item>
+ <u-form-item label="鐢宠鏍囬"
+ prop="title"
+ required
+ border-bottom>
+ <u-input v-model="form.title"
+ :readonly="readonly"
+ placeholder="璇疯緭鍏ョ敵璇锋爣棰�" />
+ </u-form-item>
+ <u-form-item label="鐢ㄥ嵃绫诲瀷"
+ prop="sealType"
+ required
+ border-bottom>
+ <u-input v-model="equipmentname"
+ readonly
+ placeholder="璇烽�夋嫨鐢ㄥ嵃绫诲瀷"
+ @click="showEquipmentSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="openEquipmentSheet"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="鐢宠鍘熷洜"
+ prop="reason"
+ border-bottom>
+ <u-textarea v-model="form.reason"
+ type="textarea"
+ rows="4"
+ :disabled="readonly"
+ placeholder="璇疯緭鍏ョ敵璇峰師鍥�" />
+ </u-form-item>
+ <u-form-item label="瀹℃壒浜�"
+ prop="sealType"
+ required
+ border-bottom>
+ <u-input v-model="statusname"
+ readonly
+ placeholder="璇烽�夋嫨瀹℃壒浜�"
+ @click="showStatusSheet = true" />
+ <template v-if="!readonly"
+ #right>
+ <up-icon name="arrow-right"
+ @click="showStatusSheet = true"></up-icon>
+ </template>
+ </u-form-item>
+ <u-form-item label="绱ф�ョ▼搴�"
+ prop="urgency"
+ required
+ border-bottom>
+ <u-radio-group v-model="form.urgency"
+ :disabled="readonly">
+ <u-radio name="normal"
+ label="鏅��"
+ size="16" />
+ <u-radio name="urgent"
+ label="绱ф��"
+ size="16" />
+ <u-radio name="very-urgent"
+ label="鐗规��"
+ size="16" />
+ </u-radio-group>
+ </u-form-item>
+ <!-- </u-cell-group> -->
+ <!-- 鎻愪氦鎸夐挳 -->
+ <view v-if="!readonly"
+ class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="sign-btn"
+ type="primary"
+ @click="handleSubmit"
+ :loading="loading">淇濆瓨</u-button>
+ </view>
+ </u-form>
+ <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+ <up-action-sheet :show="showEquipmentSheet"
+ :actions="equipmentOptions"
+ @select="handleEquipmentChange"
+ @close="showEquipmentSheet = false" />
+ <!-- 鐘舵�侀�夋嫨鍣� -->
+ <up-action-sheet :show="showStatusSheet"
+ :actions="userList"
+ @select="onStatusSelect"
+ @close="showStatusSheet = false" />
+ </view>
+</template>
+
+<script setup>
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "meeting-settings-detail" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import { ref, onMounted, computed } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { useDict } from "@/utils/dict";
+ import { onLoad } from "@dcloudio/uni-app";
+ import { userListNoPageByTenantId } from "@/api/system/user";
+
+ import { addSealApplication } from "@/api/managementMeetings/sealManagement";
+
+ const userStore = useUserStore();
+
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ applicationNum: "",
+ title: "",
+ sealType: "",
+ reason: "",
+ approveUserId: "",
+ urgency: "normal",
+ status: "pending",
+ });
+ const { knowledge_type } = useDict("knowledge_type");
+ const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+ const equipmentOptions = ref([
+ { value: "official", name: "鍏珷" },
+ { value: "contract", name: "鍚堝悓涓撶敤绔�" },
+ { value: "finance", name: "璐㈠姟涓撶敤绔�" },
+ { value: "legal", name: "娉曚汉绔�" },
+ ]);
+ const statusOptions = ref([
+ { value: "high", name: "鏄捐憲鎻愬崌" },
+ { value: "medium", name: "涓�鑸彁鍗�" },
+ { value: "low", name: "杞诲井鎻愬崌" },
+ ]);
+ //// 椤甸潰鐘舵��
+ const loading = ref(false);
+ const formRef = ref(null);
+ const showEquipmentSheet = ref(false);
+ const showStatusSheet = ref(false);
+ const openEquipmentSheet = () => {
+ showEquipmentSheet.value = true;
+ };
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const statusname = ref("");
+ // 鐘舵�侀�夋嫨
+ const onStatusSelect = action => {
+ form.value.approveUserId = action.value;
+ statusname.value = action.name;
+ showStatusSheet.value = false;
+ };
+ const equipmentname = ref("");
+ // 璁惧閰嶇疆閫夋嫨
+ const handleEquipmentChange = val => {
+ form.value.sealType = val.value;
+ equipmentname.value = val.name;
+ showEquipmentSheet.value = false;
+ };
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = async () => {
+ if (!form.value.applicationNum) {
+ showToast("璇疯緭鍏ョ敵璇风紪鍙�");
+ return;
+ }
+
+ if (!form.value.title) {
+ showToast("璇疯緭鍏ユ爣棰�");
+ return;
+ }
+
+ if (!form.value.sealType) {
+ showToast("璇烽�夋嫨鐢ㄥ嵃绫诲瀷");
+ return;
+ }
+ if (!form.value.reason) {
+ showToast("璇疯緭鍏ョ敵璇风悊鐢�");
+ return;
+ }
+ if (!statusname.value) {
+ showToast("璇烽�夋嫨瀹℃壒浜�");
+ return;
+ }
+ try {
+ loading.value = true;
+ addSealApplication(form.value).then(res => {
+ if (res.code !== 200) {
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ return;
+ }
+ loading.value = false;
+ showToast("淇濆瓨鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ } catch (e) {
+ loading.value = false;
+ console.error("淇濆瓨澶辫触:", e);
+ showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+ }
+ };
+
+ // 鍒濆鍖栭〉闈㈡暟鎹�
+ const readonly = ref(false);
+ const detailType = ref(1);
+ const knowledgeId = ref("");
+ const userList = ref([]);
+ onLoad(options => {
+ detailType.value = Number(options.detailType);
+ knowledgeId.value = options.id || "";
+
+ // 鏌ョ湅妯″紡璁剧疆鍙
+ if (detailType.value === 3) {
+ readonly.value = true;
+ }
+ userListNoPageByTenantId().then(res => {
+ userList.value = res.data.map(item => ({
+ value: item.userId,
+ name: item.nickName,
+ }));
+ });
+ });
+
+ onMounted(() => {
+ // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇鐭ヨ瘑鏁版嵁
+ const knowledgeBase = uni.getStorageSync("knowledgeBase");
+ if (knowledgeBase) {
+ form.value = JSON.parse(JSON.stringify(knowledgeBase));
+ }
+
+ if (detailType.value === 1) {
+ form.value = {
+ applicationNum: "",
+ title: "",
+ sealType: "",
+ reason: "",
+ approveUserId: "",
+ urgency: "normal",
+ status: "pending",
+ };
+ statusname.value = "";
+ equipmentname.value = "";
+ }
+ console.log(form.value, "userList.value");
+
+ if (detailType.value != 1) {
+ equipmentname.value =
+ equipmentOptions.value.find(item => item.value === form.value.sealType)
+ ?.name || "";
+ statusname.value = form.value.approveUserName || "";
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+ .client-visit {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+ }
+
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #666;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .sign-btn {
+ font-weight: 500;
+ font-size: 1rem;
+ color: #fff;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border: none;
+ width: 45%;
+ height: 2.5rem;
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .location-icon {
+ color: #1989fa;
+ font-size: 1.2rem;
+ }
+
+ /* 绱ф�ョ▼搴﹀崟閫夋鏍峰紡 */
+ :deep(.u-radio-group) {
+ display: flex;
+ align-items: center;
+ gap: 40rpx;
+ }
+
+ :deep(.u-radio) {
+ display: flex;
+ align-items: center;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/sealManagement/index.vue b/src/pages/managementMeetings/sealManagement/index.vue
new file mode 100644
index 0000000..2979152
--- /dev/null
+++ b/src/pages/managementMeetings/sealManagement/index.vue
@@ -0,0 +1,348 @@
+<template>
+ <view class="sales-accoun">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鐢ㄥ嵃绠$悊"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ョ敵璇风紪鍙�"
+ v-model="name"
+ @blur="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <u-icon name="search"
+ size="24"
+ color="#999"></u-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鎷滆璁板綍鍒楄〃 -->
+ <view class="ledger-list"
+ v-if="visitList.length > 0">
+ <view v-for="(item, index) in visitList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">鐢宠鏍囬锛歿{ item.title || '-' }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鐢宠缂栧彿</text>
+ <text class="detail-value">{{ item.applicationNum || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢宠浜�</text>
+ <text class="detail-value">{{ item.createUserName || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鎵�灞為儴闂�</text>
+ <text class="detail-value">{{ item.department || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢ㄥ嵃绫诲瀷</text>
+ <text class="detail-value">{{ formatReceiptType(item.sealType) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢宠鏃堕棿</text>
+ <text class="detail-value">{{ item.createTime || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐘舵��</text>
+ <u-tag size="mini"
+ :type="getTagClass(item.status)">{{ formatReceiptType1(item.status) }}</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐢宠鍘熷洜</text>
+ <text class="detail-value"><span style="display: block;height: auto;word-break: break-word;">{{ item.reason || '-' }}</span></text>
+ </view>
+ </view>
+ <!-- 鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <u-button type="info"
+ size="small"
+ class="action-btn"
+ @click="viewDetail(item,3)">
+ 鏌ョ湅
+ </u-button>
+ <!-- <u-button type="primary"
+ size="small"
+ class="action-btn"
+ v-if="item.status === 'pending'"
+ @click="confirmApprove(item,true)">
+ 瀹℃壒
+ </u-button>
+ <u-button type="error"
+ size="small"
+ class="action-btn"
+ v-if="item.status === 'pending'"
+ @click="confirmApprove(item,false)">
+ 鎷掔粷
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鐢ㄥ嵃璁板綍</text>
+ </view>
+ <!-- 娴姩鏂板鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="addVisit">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, computed } from "vue";
+ import { onShow, onLoad } from "@dcloudio/uni-app";
+ import { useDict } from "@/utils/dict";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ listSealApplication,
+ updateSealApplication,
+ } from "@/api/managementMeetings/sealManagement";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ defineOptions({ name: "client-visit-index" });
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+
+ import dayjs from "dayjs";
+
+ const userStore = useUserStore();
+
+ // 鎼滅储鍏抽敭璇�
+ const name = ref("");
+
+ // 鎷滆璁板綍鏁版嵁
+ const visitList = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const { knowledge_type } = useDict("knowledge_type");
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = params => {
+ if (params == "official") {
+ return "鍏珷";
+ } else if (params == "contract") {
+ return "鍚堝悓涓撶敤绔�";
+ } else if (params == "finance") {
+ return "璐㈠姟涓撶敤绔�";
+ } else if (params == "tegal") {
+ return "娉曚汉绔�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ const formatReceiptType1 = params => {
+ if (params == "pending") {
+ return "寰呭鎵�";
+ } else if (params == "approved") {
+ return "宸查�氳繃";
+ } else if (params == "rejected") {
+ return "宸叉嫆缁�";
+ } else {
+ return "鏈煡";
+ }
+ };
+ const getTagClass = type => {
+ if (type == "pending") {
+ return "warning";
+ } else if (type == "approved") {
+ return "success";
+ } else if (type == "rejected") {
+ return "danger";
+ } else {
+ return "info";
+ }
+ };
+ const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+ // 鑾峰彇鐭ヨ瘑绫诲瀷鏍囩
+ const getKnowledgeTypeLabel = val => {
+ console.log(knowledgeTypeOptions, "knowledgeTypeOptions");
+ const item = knowledgeTypeOptions.value.find(
+ i => String(i.value) === String(val)
+ );
+ return item ? item.label : val;
+ };
+
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ current: -1,
+ size: -1,
+ applicationNum: name.value,
+ };
+ listSealApplication(params)
+ .then(res => {
+ // const currentFactoryName = userStore.currentFactoryName;
+ // if (currentFactoryName) {
+ // visitList.value = res.data.records.filter(
+ // item => item.department === currentFactoryName
+ // );
+ // } else {
+ visitList.value = res.data.records;
+ // }
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ });
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+ const addVisit = () => {
+ uni.navigateTo({
+ url: "/pages/managementMeetings/sealManagement/detail?detailType=1",
+ });
+ };
+ const confirmApprove = (item, isApprove) => {
+ if (isApprove) {
+ uni.showModal({
+ title: "瀹℃壒纭",
+ content: `纭畾瑕佸鎵硅鐢ㄥ嵃鐢宠鍚楋紵`,
+ success: res => {
+ item.status = "approved";
+ updateSealApplication(item).then(res => {
+ if (res.code == 200) {
+ showToast("瀹℃壒閫氳繃");
+ }
+ });
+ },
+ });
+ } else {
+ uni.showModal({
+ title: "瀹℃壒纭",
+ content: `纭畾瑕佹嫆缁濊鐢ㄥ嵃鐢宠鍚楋紵`,
+ success: res => {
+ item.status = "rejected";
+ updateSealApplication(item).then(res => {
+ if (res.code == 200) {
+ showToast("瀹℃壒鎷掔粷");
+ }
+ });
+ },
+ });
+ }
+ };
+ // 缂栬緫
+ const viewDetail = (item, detailType) => {
+ uni.setStorageSync("knowledgeBase", item);
+ uni.navigateTo({
+ url:
+ "/pages/managementMeetings/sealManagement/detail?detailType=" +
+ detailType +
+ "&id=" +
+ item.id,
+ });
+ };
+
+ // 鍒犻櫎纭
+ const confirmDelete = item => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: `纭畾瑕佸垹闄ょ煡璇� "${item.title}" 鍚楋紵`,
+ success: res => {
+ if (res.confirm) {
+ // deleteKnowledge(item.id);
+ }
+ },
+ });
+ };
+ onLoad(options => {
+ // 瑙f瀽applicationNum
+ if (options.applicationNum) {
+ name.value = options.applicationNum;
+ }
+ });
+
+ onMounted(() => {
+ getList();
+ });
+
+ onShow(() => {
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "../../../styles/sales-common.scss";
+
+ // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+ .sales-accoun {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ padding-bottom: 80px;
+ }
+
+ // 鐗瑰畾鐨勫浘鏍囨牱寮�
+ .document-icon {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ }
+
+ // 鐗规湁鏍峰紡
+ .visit-status {
+ display: flex;
+ align-items: center;
+ }
+
+ .detail-value {
+ word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+ color: #333; // 淇濇寔椤甸潰鐗规湁鐨勬枃鏈鑹�
+ }
+
+ // 鐘舵�佹牱寮�
+ .status-enabled {
+ color: #28a745; // 淇濇寔椤甸潰鐗规湁鐨勬垚鍔熼鑹�
+ }
+
+ .status-disabled {
+ color: #dc3545; // 淇濇寔椤甸潰鐗规湁鐨勯敊璇鑹�
+ }
+
+ // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+ .fab-button {
+ background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+ }
+</style>
+
diff --git a/src/pages/procurementManagement/invoiceEntry/add.vue b/src/pages/procurementManagement/invoiceEntry/add.vue
index a68d6fb..6bd8aa2 100644
--- a/src/pages/procurementManagement/invoiceEntry/add.vue
+++ b/src/pages/procurementManagement/invoiceEntry/add.vue
@@ -418,10 +418,10 @@
return
}
- const submitData = {
+ const submitData = [{
...form.value,
productData: productData.value
- }
+ }]
await addOrUpdateRegistration(submitData)
showToast('鎻愪氦鎴愬姛')
diff --git a/src/pages/procurementManagement/invoiceEntry/index.vue b/src/pages/procurementManagement/invoiceEntry/index.vue
index 6d50f85..f9315af 100644
--- a/src/pages/procurementManagement/invoiceEntry/index.vue
+++ b/src/pages/procurementManagement/invoiceEntry/index.vue
@@ -1,240 +1,247 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鏉ョエ鐧昏" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿/渚涘簲鍟嗗悕绉�"
- v-model="supplierName"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 閲囪喘鍙拌处鐎戝竷娴� -->
- <view class="ledger-list" v-if="ledgerList.length > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.purchaseContractNumber }}</text>
- </view>
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">閿�鍞悎鍚屽彿</text>
- <text class="detail-value">{{ item.salesContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
- <text class="detail-value">{{ item.supplierName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ item.contractAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">宸插紑绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value highlight">{{ item.receiptPaymentAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">寰呭紑绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value redlight">{{ item.unReceiptPaymentAmount }}</text>
- </view>
- </view>
-
- <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
- <view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- @click="handleAddInvoice(item)"
- class="action-btn"
- :disabled="item.unReceiptPaymentAmount == 0"
- >
- 鏂板寮�绁�
- </u-button>
- <u-button
- size="small"
- @click="handleViewDetail(item)"
- class="action-btn"
- >
- 鏌ョ湅璇︽儏
- </u-button>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤閲囪喘鍙拌处鏁版嵁</text>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鏉ョエ鐧昏"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿/渚涘簲鍟嗗悕绉�"
+ v-model="supplierName"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 閲囪喘鍙拌处鐎戝竷娴� -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸插紑绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value highlight">{{ item.receiptPaymentAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">寰呭紑绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value redlight">{{ item.unReceiptPaymentAmount }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <!-- <u-button type="primary"
+ size="small"
+ @click="handleAddInvoice(item)"
+ class="action-btn"
+ :disabled="item.unReceiptPaymentAmount == 0">
+ 鏂板寮�绁�
+ </u-button> -->
+ <u-button size="small"
+ @click="handleViewDetail(item)"
+ class="action-btn">
+ 鏌ョ湅璇︽儏
+ </u-button>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤閲囪喘鍙拌处鏁版嵁</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import useUserStore from "@/store/modules/user";
-import {gePurchaseListPage} from "@/api/procurementManagement/invoiceEntry";
-const userStore = useUserStore()
+ import { ref } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
+ import { gePurchaseListPage } from "@/api/procurementManagement/invoiceEntry";
+ const userStore = useUserStore();
-// 鎼滅储鍏抽敭璇�
-const supplierName = ref('');
+ // 鎼滅储鍏抽敭璇�
+ const supplierName = ref("");
-// 閲囪喘鍙拌处鏁版嵁
-const ledgerList = ref([]);
+ // 閲囪喘鍙拌处鏁版嵁
+ const ledgerList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1
- }
- gePurchaseListPage({...page, supplierName: supplierName.value}).then((res) => {
- ledgerList.value = res.data.records;
- closeToast()
- }).catch(() => {
- closeToast()
- });
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ gePurchaseListPage({
+ ...page,
+ supplierName: supplierName.value,
+ approvalStatus: 3,
+ })
+ .then(res => {
+ ledgerList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 澶勭悊鏂板鏉ョエ
-const handleAddInvoice = (item) => {
- try {
- // 瀛樺偍閫変腑鐨勫悎鍚屼俊鎭�
- uni.setStorageSync('editData', JSON.stringify(item));
- // 璺宠浆鍒版柊澧炴潵绁ㄩ〉闈�
- uni.navigateTo({
- url: '/pages/procurementManagement/invoiceEntry/add'
- });
- } catch (error) {
- console.error('澶勭悊鏂板鏉ョエ澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 澶勭悊鏂板鏉ョエ
+ const handleAddInvoice = item => {
+ try {
+ // 瀛樺偍閫変腑鐨勫悎鍚屼俊鎭�
+ uni.setStorageSync("editData", JSON.stringify(item));
+ // 璺宠浆鍒版柊澧炴潵绁ㄩ〉闈�
+ uni.navigateTo({
+ url: "/pages/procurementManagement/invoiceEntry/add",
+ });
+ } catch (error) {
+ console.error("澶勭悊鏂板鏉ョエ澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
-// 澶勭悊鏌ョ湅璇︽儏
-const handleViewDetail = (item) => {
- try {
- // 瀛樺偍鏁版嵁
- uni.setStorageSync('editData', JSON.stringify(item));
-
- // 璺宠浆鍒拌鎯呴〉闈�
- uni.navigateTo({
- url: '/pages/procurementManagement/invoiceEntry/view'
- });
- } catch (error) {
- console.error('澶勭悊鏌ョ湅璇︽儏澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 澶勭悊鏌ョ湅璇︽儏
+ const handleViewDetail = item => {
+ try {
+ // 瀛樺偍鏁版嵁
+ uni.setStorageSync("editData", JSON.stringify(item));
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 璺宠浆鍒拌鎯呴〉闈�
+ uni.navigateTo({
+ url: "/pages/procurementManagement/invoiceEntry/view",
+ });
+ } catch (error) {
+ console.error("澶勭悊鏌ョ湅璇︽儏澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/procurement-common.scss';
+ @import "@/styles/procurement-common.scss";
-// 鏉ョエ鐧昏鐗规湁鏍峰紡
-.nav-icon {
- width: 24px;
- height: 24px;
- background: #2979ff;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ // 鏉ョエ鐧昏鐗规湁鏍峰紡
+ .nav-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.nav-text {
- font-size: 14px;
- color: #2979ff;
- font-weight: 500;
-}
+ .nav-text {
+ font-size: 14px;
+ color: #2979ff;
+ font-weight: 500;
+ }
-.header-center {
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- position: absolute;
- left: 0;
- right: 0;
- pointer-events: none;
-}
+ .header-center {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ left: 0;
+ right: 0;
+ pointer-events: none;
+ }
-.page-title {
- font-size: 18px;
- font-weight: 600;
- color: #333;
- pointer-events: auto;
-}
+ .page-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ pointer-events: auto;
+ }
-.header-right {
- display: flex;
- align-items: center;
-}
+ .header-right {
+ display: flex;
+ align-items: center;
+ }
-.status-bar {
- display: flex;
- align-items: center;
- gap: 4px;
-}
+ .status-bar {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ }
-.signal, .wifi, .battery {
- width: 16px;
- height: 8px;
- background: #333;
- border-radius: 2px;
-}
+ .signal,
+ .wifi,
+ .battery {
+ width: 16px;
+ height: 8px;
+ background: #333;
+ border-radius: 2px;
+ }
-.fab-button {
- bottom: 30px; // 涓庡叾浠栭〉闈㈢殑 calc(30px + env(safe-area-inset-bottom)) 涓嶅悓
-}
+ .fab-button {
+ bottom: 30px; // 涓庡叾浠栭〉闈㈢殑 calc(30px + env(safe-area-inset-bottom)) 涓嶅悓
+ }
</style>
diff --git a/src/pages/procurementManagement/paymentEntry/add.vue b/src/pages/procurementManagement/paymentEntry/add.vue
index 9b77343..e9fde40 100644
--- a/src/pages/procurementManagement/paymentEntry/add.vue
+++ b/src/pages/procurementManagement/paymentEntry/add.vue
@@ -1,278 +1,285 @@
<template>
<view class="account-detail">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鏂板浠樻" @back="onClickLeft" />
-
+ <PageHeader title="鏂板浠樻"
+ @back="onClickLeft" />
<!-- 琛ㄥ崟鍐呭 -->
- <u-form @submit="onSubmit" ref="formRef" label-width="110" input-align="right" error-message-align="right">
+ <u-form @submit="onSubmit"
+ ref="formRef"
+ label-width="110"
+ input-align="right"
+ error-message-align="right">
<!-- 鍩烘湰淇℃伅 -->
- <u-cell-group title="鍩烘湰淇℃伅" class="form-section">
- <u-form-item label="閲囪喘鍚堝悓鍙�" class="form-item">
- <u-input
- v-model="form.purchaseContractNumber"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-cell-group title="鍩烘湰淇℃伅"
+ class="form-section">
+ <u-form-item label="閲囪喘鍚堝悓鍙�"
+ class="form-item">
+ <u-input v-model="form.purchaseContractNumber"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="閿�鍞悎鍚屽彿" class="form-item">
- <u-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="閿�鍞悎鍚屽彿"
+ class="form-item">
+ <u-input v-model="form.salesContractNo"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="渚涘簲鍟嗗悕绉�" class="form-item">
- <u-input
- v-model="form.supplierName"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="渚涘簲鍟嗗悕绉�"
+ class="form-item">
+ <u-input v-model="form.supplierName"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="鍙戠エ鍙�" class="form-item">
+ <!-- <u-form-item label="鍙戠エ鍙�" class="form-item">
<u-input
v-model="form.invoiceNumber"
placeholder="鑷姩濉厖"
readonly
/>
- </u-form-item>
- <u-form-item label="鍙戠エ閲戦(鍏�)" class="form-item">
+ </u-form-item> -->
+ <!-- <u-form-item label="鍙戠エ閲戦(鍏�)" class="form-item">
<u-input
v-model="form.invoiceAmount"
placeholder="鑷姩濉厖"
readonly
/>
- </u-form-item>
+ </u-form-item> -->
<view class="tip-text">寰呬粯娆鹃噾棰濓細{{ currentNoReceiptAmount }} 鍏�</view>
- <u-form-item label="鏈浠樻閲戦" prop="currentPaymentAmount" required class="form-item">
- <u-input
- v-model="form.currentPaymentAmount"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="changeNum"
- clearable
- />
+ <u-form-item label="鏈浠樻閲戦"
+ prop="currentPaymentAmount"
+ required
+ class="form-item">
+ <u-input v-model="form.currentPaymentAmount"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="changeNum"
+ clearable />
</u-form-item>
- <u-form-item label="浠樻褰㈠紡" prop="paymentMethod" required class="form-item">
- <u-input
- v-model="form.paymentMethod"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showPaymentTypePicker"
- />
+ <u-form-item label="浠樻褰㈠紡"
+ prop="paymentMethod"
+ required
+ class="form-item">
+ <u-input v-model="form.paymentMethod"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showPaymentTypePicker" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showPaymentTypePicker"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showPaymentTypePicker"></up-icon>
+ </template>
</u-form-item>
- <u-form-item label="浠樻鏃ユ湡" prop="paymentDate" required class="form-item">
- <u-input
- v-model="form.paymentDate"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showDatePicker"
- />
+ <u-form-item label="浠樻鏃ユ湡"
+ prop="paymentDate"
+ required
+ class="form-item">
+ <u-input v-model="form.paymentDate"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showDatePicker" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showDatePicker"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showDatePicker"></up-icon>
+ </template>
</u-form-item>
- <u-form-item label="鐧昏浜�" class="form-item">
- <u-input
- v-model="form.registrant"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="鐧昏浜�"
+ class="form-item">
+ <u-input v-model="form.registrant"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="鐧昏鏃ユ湡" prop="registrationtDate" required class="form-item">
- <u-input
- v-model="form.registrationtDate"
- placeholder="璇烽�夋嫨"
- readonly
- />
+ <u-form-item label="鐧昏鏃ユ湡"
+ prop="registrationtDate"
+ required
+ class="form-item">
+ <u-input v-model="form.registrationtDate"
+ placeholder="璇烽�夋嫨"
+ readonly />
</u-form-item>
</u-cell-group>
-
<!-- 鎻愪氦鎸夐挳 -->
- <FooterButtons
- :loading="loading"
- @cancel="onClickLeft"
- @confirm="onSubmit"
- />
+ <FooterButtons :loading="loading"
+ @cancel="onClickLeft"
+ @confirm="onSubmit" />
</u-form>
-
<!-- 浠樻鏂瑰紡閫夋嫨鍣� -->
- <up-action-sheet
- :show="showPaymentType"
- title="閫夋嫨浠樻鏂瑰紡"
- :actions="receipt_payment_type"
- @select="onPaymentTypeConfirm"
- @close="showPaymentType = false"
- />
-
+ <up-action-sheet :show="showPaymentType"
+ title="閫夋嫨浠樻鏂瑰紡"
+ :actions="receipt_payment_type"
+ @select="onPaymentTypeConfirm"
+ @close="showPaymentType = false" />
<!-- 鏃ユ湡閫夋嫨鍣� -->
- <up-datetime-picker
- :show="showDate"
- v-model="form.paymentDate"
- @confirm="onDateConfirm"
- @cancel="showDate = false"
- mode="date"
- />
+ <up-datetime-picker :show="showDate"
+ v-model="form.paymentDate"
+ @confirm="onDateConfirm"
+ @cancel="showDate = false"
+ mode="date" />
</view>
</template>
<script setup>
-import { ref, onMounted, computed } from 'vue'
-import FooterButtons from '@/components/FooterButtons.vue'
-import useUserStore from '@/store/modules/user'
-import { useDict } from '@/utils/dict'
-import {paymentRegistrationAdd} from "@/api/procurementManagement/paymentEntry";
-import { formatDateToYMD } from '@/utils/ruoyi'
+ import { ref, onMounted, computed } from "vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
+ import useUserStore from "@/store/modules/user";
+ import { useDict } from "@/utils/dict";
+ import { paymentRegistrationAdd } from "@/api/procurementManagement/paymentEntry";
+ import { formatDateToYMD } from "@/utils/ruoyi";
-// 鏇挎崲 toast 鍜� notify 鏂规硶
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏇挎崲 toast 鍜� notify 鏂规硶
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-const showNotify = ({ type, message }) => {
- uni.showToast({
- title: message,
- icon: type === 'warning' ? 'none' : 'success'
- })
-}
+ const showNotify = ({ type, message }) => {
+ uni.showToast({
+ title: message,
+ icon: type === "warning" ? "none" : "success",
+ });
+ };
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 琛ㄥ崟寮曠敤
-const formRef = ref()
+ // 琛ㄥ崟寮曠敤
+ const formRef = ref();
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const showPaymentType = ref(false)
-const showDate = ref(false)
+ // 鍝嶅簲寮忔暟鎹�
+ const loading = ref(false);
+ const showPaymentType = ref(false);
+ const showDate = ref(false);
-// 琛ㄥ崟鏁版嵁
-const form = ref({
- purchaseContractNumber: '',
- salesContractNo: '',
- supplierName: '',
- invoiceNumber: '',
- invoiceAmount: '',
- taxRate: '',
- currentPaymentAmount: '',
- receiptPaymentType: '',
- paymentMethod: '',
- registrant: '',
- paymentDate: '',
- registrationtDate: '',
- ticketRegistrationId: ''
-})
-const currentNoReceiptAmount = ref(0)
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ purchaseContractNumber: "",
+ salesContractNo: "",
+ supplierName: "",
+ invoiceNumber: "",
+ invoiceAmount: "",
+ taxRate: "",
+ currentPaymentAmount: "",
+ receiptPaymentType: "",
+ paymentMethod: "",
+ registrant: "",
+ paymentDate: "",
+ registrationtDate: "",
+ // ticketRegistrationId: "",
+ purchaseLedgerId: "",
+ salesLedgerProductId: "",
+ });
+ const currentNoReceiptAmount = ref(0);
-// 鑾峰彇瀛楀吀鏁版嵁
-const { receipt_payment_type: dictReceiptPaymentType } = useDict('receipt_payment_type')
+ // 鑾峰彇瀛楀吀鏁版嵁
+ const { receipt_payment_type: dictReceiptPaymentType } = useDict(
+ "receipt_payment_type"
+ );
-// 杞崲瀛楀吀鏁版嵁鏍煎紡涓洪�夋嫨鍣ㄩ渶瑕佺殑鏍煎紡
-const receipt_payment_type = computed(() => {
- return dictReceiptPaymentType.value.map(item => ({
- name: item.label,
- value: item.value
- }))
-})
+ // 杞崲瀛楀吀鏁版嵁鏍煎紡涓洪�夋嫨鍣ㄩ渶瑕佺殑鏍煎紡
+ const receipt_payment_type = computed(() => {
+ return dictReceiptPaymentType.value.map(item => ({
+ name: item.label,
+ value: item.value,
+ }));
+ });
-// 杩斿洖涓婁竴椤�
-const onClickLeft = () => {
- uni.removeStorageSync('invoiceLedgerEditRow');
- uni.navigateBack()
-}
+ // 杩斿洖涓婁竴椤�
+ const onClickLeft = () => {
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.navigateBack();
+ };
-// 鏄剧ず浠樻鏂瑰紡閫夋嫨鍣�
-const showPaymentTypePicker = () => {
- showPaymentType.value = true
-}
-const changeNum = () => {
- if (form.value.currentPaymentAmount > currentNoReceiptAmount.value) {
- form.value.currentPaymentAmount = currentNoReceiptAmount.value
- showToast('涓嶅彲澶т簬寰呬粯娆鹃噾棰�')
- }
-}
+ // 鏄剧ず浠樻鏂瑰紡閫夋嫨鍣�
+ const showPaymentTypePicker = () => {
+ showPaymentType.value = true;
+ };
+ const changeNum = () => {
+ if (form.value.currentPaymentAmount > currentNoReceiptAmount.value) {
+ form.value.currentPaymentAmount = currentNoReceiptAmount.value;
+ showToast("涓嶅彲澶т簬寰呬粯娆鹃噾棰�");
+ }
+ };
-// 纭浠樻鏂瑰紡閫夋嫨
-const onPaymentTypeConfirm = (item) => {
- form.value.receiptPaymentType = item.value
- form.value.paymentMethod = item.name
- showPaymentType.value = false
-}
+ // 纭浠樻鏂瑰紡閫夋嫨
+ const onPaymentTypeConfirm = item => {
+ form.value.receiptPaymentType = item.value;
+ form.value.paymentMethod = item.name;
+ showPaymentType.value = false;
+ };
-// 鏄剧ず鏃ユ湡閫夋嫨鍣�
-const showDatePicker = () => {
- showDate.value = true
-}
+ // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+ const showDatePicker = () => {
+ showDate.value = true;
+ };
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
- form.value.paymentDate = formatDateToYMD(e.value)
- showDate.value = false
-}
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.paymentDate = formatDateToYMD(e.value);
+ showDate.value = false;
+ };
-// 鎻愪氦琛ㄥ崟
-const onSubmit = () => {
- // 琛ㄥ崟楠岃瘉
- if (!form.value.currentPaymentAmount) {
- showNotify({ type: 'warning', message: '璇疯緭鍏ヤ粯娆鹃噾棰�' })
- return
+ // 鎻愪氦琛ㄥ崟
+ const onSubmit = () => {
+ // 琛ㄥ崟楠岃瘉
+ if (!form.value.currentPaymentAmount) {
+ showNotify({ type: "warning", message: "璇疯緭鍏ヤ粯娆鹃噾棰�" });
+ return;
+ }
+ if (!form.value.receiptPaymentType) {
+ showNotify({ type: "warning", message: "璇烽�夋嫨浠樻褰㈠紡" });
+ return;
+ }
+ if (!form.value.paymentDate) {
+ showNotify({ type: "warning", message: "璇烽�夋嫨浠樻鏃ユ湡" });
+ return;
+ }
+ loading.value = true;
+ paymentRegistrationAdd([form.value])
+ .then(() => {
+ showToast("鎻愪氦鎴愬姛");
+ onClickLeft();
+ })
+ .catch(error => {
+ loading.value = false;
+ });
+ };
+
+ // 鍒濆鍖栨暟鎹�
+ const initData = () => {
+ const rowStr = uni.getStorageSync("invoiceLedgerEditRow");
+ const row = JSON.parse(rowStr);
+ form.value = { ...row };
+ // form.value.ticketRegistrationId = row.id;
+ form.value.id = null;
+ form.value.id = "";
+ currentNoReceiptAmount.value = row.pendingTicketsTotal
+ ? parseFloat(row.pendingTicketsTotal).toFixed(2)
+ : "0";
+ form.value.registrant = userStore.nickName;
+ form.value.registrationtDate = getCurrentDate();
+ form.value.paymentDate = getCurrentDate();
+ form.value.salesLedgerProductId = row.id || "";
+
+ form.value.purchaseLedgerId = row.salesLedgerId || "";
+ };
+ // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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}`;
}
- if (!form.value.receiptPaymentType) {
- showNotify({ type: 'warning', message: '璇烽�夋嫨浠樻褰㈠紡' })
- return
- }
- if (!form.value.paymentDate) {
- showNotify({ type: 'warning', message: '璇烽�夋嫨浠樻鏃ユ湡' })
- return
- }
- loading.value = true
- paymentRegistrationAdd(form.value)
- .then(() => {
- showToast('鎻愪氦鎴愬姛')
- onClickLeft()
- })
- .catch((error) => {
- loading.value = false
- })
-}
-
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
- const rowStr = uni.getStorageSync('invoiceLedgerEditRow')
- const row = JSON.parse(rowStr)
- form.value = { ...row };
- form.value.ticketRegistrationId = row.id;
- form.value.id = null;
- form.value.id = "";
- currentNoReceiptAmount.value = row.unPaymentAmountTotal
- form.value.registrant = userStore.nickName
- form.value.registrationtDate = getCurrentDate();
- form.value.paymentDate = getCurrentDate();
-}
-// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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(() => {
- initData()
-})
+ onMounted(() => {
+ initData();
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
+ .tip-text {
+ font-size: 16px;
+ color: #383838;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ }
</style>
diff --git a/src/pages/procurementManagement/paymentEntry/index.vue b/src/pages/procurementManagement/paymentEntry/index.vue
index 39cd559..81462ac 100644
--- a/src/pages/procurementManagement/paymentEntry/index.vue
+++ b/src/pages/procurementManagement/paymentEntry/index.vue
@@ -1,189 +1,216 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="浠樻鐧昏" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О/鍚堝悓鍙锋悳绱�"
- v-model="searchForm.supplierNameOrContractNo"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
-
- <!-- 绛涢�夊紑鍏� -->
- <view class="switch-row">
- <text class="switch-label">涓嶆樉绀哄緟浠樻涓�0</text>
- <u-switch v-model="searchForm.status" @change="getList" active-color="#2979ff" inactive-color="#e5e5e5"/>
- </view>
- </view>
-
-
-
- <!-- 鍒楄〃鍖哄煙 -->
- <view class="ledger-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.purchaseContractNumber }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">閿�鍞悎鍚屽彿</text>
- <text class="detail-value">{{ item.salesContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
- <text class="detail-value">{{ item.supplierName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ鍙�</text>
- <text class="detail-value">{{ item.invoiceNumber }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
- <text class="detail-value">{{ item.invoiceAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">宸蹭粯娆鹃噾棰�(鍏�)</text>
- <text class="detail-value">{{ item.paymentAmountTotal || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">寰呬粯娆鹃噾棰�(鍏�)</text>
- <text class="detail-value highlight">{{ formatNumber(item.unPaymentAmountTotal) }}</text>
- </view>
- </view>
-
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="action-buttons">
- <u-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.unPaymentAmountTotal == 0"
- @click="openForm('add', item)"
- >
- 鏂板浠樻
- </u-button>
- </view>
- </view>
- </view>
- </view>
-
- <!-- 鏃犳暟鎹彁绀� -->
- <view class="no-data" v-else>
- <text>鏆傛棤浠樻鏁版嵁</text>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浠樻鐧昏"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О/鍚堝悓鍙锋悳绱�"
+ v-model="searchForm.supplierNameOrContractNo"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ <!-- 绛涢�夊紑鍏� -->
+ <view class="switch-row">
+ <text class="switch-label">涓嶆樉绀哄緟浠樻涓�0</text>
+ <u-switch v-model="searchForm.status"
+ @change="getList"
+ active-color="#2979ff"
+ inactive-color="#e5e5e5" />
+ </view>
+ </view>
+ <!-- 鍒楄〃鍖哄煙 -->
+ <view class="ledger-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.statusName)">{{ item.statusName || '--' }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <!-- <view class="detail-row">
+ <text class="detail-label">鍙戠エ鍙�</text>
+ <text class="detail-value">{{ item.invoiceNumber }}</text>
+ </view> -->
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.specificationModel }}</text>
+ </view>
+ <!-- <view class="detail-row">
+ <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
+ <text class="detail-value">{{ item.invoiceAmount }}</text>
+ </view> -->
+ <view class="detail-row">
+ <text class="detail-label">宸蹭粯娆鹃噾棰�(鍏�)</text>
+ <text class="detail-value">{{ item.ticketsTotal ? parseFloat(item.ticketsTotal).toFixed(2) : '0' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">寰呬粯娆鹃噾棰�(鍏�)</text>
+ <text class="detail-value highlight">{{ item.pendingTicketsTotal ? parseFloat(item.pendingTicketsTotal).toFixed(2) : '0' }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="action-buttons">
+ <!-- <u-button type="primary"
+ size="small"
+ class="action-btn"
+ :disabled="item.unPaymentAmountTotal == 0"
+ @click="openForm('add', item)">
+ 鏂板浠樻
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <!-- 鏃犳暟鎹彁绀� -->
+ <view class="no-data"
+ v-else>
+ <text>鏆傛棤浠樻鏁版嵁</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref } from 'vue'
-import useUserStore from '@/store/modules/user'
-// 鏇挎崲 toast 鏂规硶
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
-import {onShow} from "@dcloudio/uni-app";
-import {invoiceListPage} from "@/api/procurementManagement/procurementInvoiceLedger";
+ import { ref } from "vue";
+ import useUserStore from "@/store/modules/user";
+ // 鏇挎崲 toast 鏂规硶
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import { onShow } from "@dcloudio/uni-app";
+ import { invoiceListPage } from "@/api/procurementManagement/procurementInvoiceLedger";
-// 鍝嶅簲寮忔暟鎹�
-const tableData = ref([])
-const tableLoading = ref(false)
+ // 鍝嶅簲寮忔暟鎹�
+ const tableData = ref([]);
+ const tableLoading = ref(false);
-// 鏌ヨ鍙傛暟璁剧疆涓�-1鑾峰彇鍏ㄩ儴鏁版嵁
-const page = ref({
- current: -1,
- size: -1
-})
+ // 鏌ヨ鍙傛暟璁剧疆涓�-1鑾峰彇鍏ㄩ儴鏁版嵁
+ const page = ref({
+ current: -1,
+ size: -1,
+ });
-// 鎼滅储琛ㄥ崟
-const searchForm = ref({
- supplierNameOrContractNo: '',
- status: true,
- customerName: '',
- customerContractNo: '',
- projectName: ''
-})
+ // 鎼滅储琛ㄥ崟
+ const searchForm = ref({
+ supplierNameOrContractNo: "",
+ status: true,
+ customerName: "",
+ customerContractNo: "",
+ projectName: "",
+ });
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (!type) {
+ return "info";
+ }
+ if (type == "鏈畬鎴愪粯娆�") {
+ return "warning";
+ } else if (type == "宸插畬鎴愪粯娆�") {
+ return "success";
+ } else {
+ return "info";
+ }
+ };
+ // 鏍煎紡鍖栨暟瀛�
+ const formatNumber = value => {
+ return parseFloat(value || 0).toFixed(2);
+ };
-// 鏍煎紡鍖栨暟瀛�
-const formatNumber = (value) => {
- return parseFloat(value || 0).toFixed(2)
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 鑾峰彇鍒楄〃鏁版嵁
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ tableLoading.value = true;
+ invoiceListPage({ ...searchForm.value, ...page.value, approvalStatus: 3 })
+ .then(res => {
+ console.log(res.data);
+ tableLoading.value = false;
+ tableData.value = res.data.records || [];
+ closeToast();
+ })
+ .catch(() => {
+ tableLoading.value = false;
+ closeToast();
+ });
+ };
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- tableLoading.value = true
- invoiceListPage({ ...searchForm.value, ...page.value }).then((res) => {
- tableLoading.value = false
- tableData.value = res.records || []
- closeToast()
- }).catch(() => {
- tableLoading.value = false
- closeToast()
- })
-}
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鎵撳紑鏂板琛ㄥ崟
+ const openForm = (type, item) => {
+ if (item.unPaymentAmountTotal == 0) {
+ showToast("鏃犻渶鍐嶄粯娆�");
+ return;
+ }
+ uni.setStorageSync("operationType", type);
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+ uni.navigateTo({ url: "/pages/procurementManagement/paymentEntry/add" });
+ };
-// 鎵撳紑鏂板琛ㄥ崟
-const openForm = (type, item) => {
- if (item.unPaymentAmountTotal == 0) {
- showToast('鏃犻渶鍐嶄粯娆�')
- return
- }
- uni.setStorageSync('operationType', type);
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item))
- uni.navigateTo({ url: '/pages/procurementManagement/paymentEntry/add' })
-}
-
-onShow(() => {
- getList()
-})
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/procurement-common.scss';
+ @import "@/styles/procurement-common.scss";
-// 浠樻鐧昏鐗规湁鏍峰紡
-.detail-value {
- display: flex;
- align-items: center;
- justify-content: flex-end;
-}
+ // 浠樻鐧昏鐗规湁鏍峰紡
+ .detail-value {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/procurementManagement/paymentLedger/detail.vue b/src/pages/procurementManagement/paymentLedger/detail.vue
index 915ee5d..26f5cf5 100644
--- a/src/pages/procurementManagement/paymentLedger/detail.vue
+++ b/src/pages/procurementManagement/paymentLedger/detail.vue
@@ -1,294 +1,309 @@
<template>
- <view class="receipt-payment-detail">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="渚涘簲鍟嗗線鏉ヨ鎯�" @back="goBack" />
-
- <!-- 缁熻淇℃伅 -->
- <view class="summary-info" v-if="tableData.length > 0">
- <view class="summary-item">
- <text class="summary-label">鎬昏褰曟暟</text>
- <text class="summary-value">{{ tableData.length }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
- <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">鍥炴鎬婚噾棰�</text>
- <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">搴旀敹鎬婚噾棰�</text>
- <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
- </view>
- </view>
-
- <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
- <view class="detail-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index" class="detail-item">
- <view class="item-header">
- <view class="item-left">
- <view class="record-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-index">{{ index + 1 }}</text>
- </view>
- <view class="item-date">{{ item.happenTime }}</view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
- <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">搴斾粯閲戦(鍏�)</text>
- <text class="detail-value danger">{{ formatAmount(item.payableAmount) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤鍥炴璁板綍</text>
- </view>
- </view>
+ <view class="receipt-payment-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="渚涘簲鍟嗗線鏉ヨ鎯�"
+ @back="goBack" />
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info"
+ v-if="tableData.length > 0">
+ <view class="summary-item">
+ <text class="summary-label">鎬昏褰曟暟</text>
+ <text class="summary-value">{{ tableData.length }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
+ <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鍥炴鎬婚噾棰�</text>
+ <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">搴旀敹鎬婚噾棰�</text>
+ <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
+ <view class="detail-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index"
+ class="detail-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="record-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-index">{{ index + 1 }}</text>
+ </view>
+ <view class="item-date">{{ item.happenTime }}</view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
+ <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">搴斾粯閲戦(鍏�)</text>
+ <text class="detail-value danger">{{ formatAmount(item.payableAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戠敓鏃ユ湡</text>
+ <text class="detail-value">{{ item.paymentDate }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴璁板綍</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref, computed, onMounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {paymentLedgerList, paymentRecordList} from "@/api/procurementManagement/paymentLedger";
+ import { ref, computed, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import {
+ paymentLedgerList,
+ paymentRecordList,
+ } from "@/api/procurementManagement/paymentLedger";
-// 瀹㈡埛淇℃伅
-const supplierId = ref('');
+ // 瀹㈡埛淇℃伅
+ const supplierId = ref("");
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([]);
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
-const invoiceTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.invoiceAmount) || 0);
- }, 0);
-});
+ const invoiceTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.invoiceAmount) || 0);
+ }, 0);
+ });
-const receiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.receiptAmount) || 0);
- }, 0);
-});
+ const receiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.receiptAmount) || 0);
+ }, 0);
+ });
-const unReceiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.unReceiptAmount) || 0);
- }, 0);
-});
+ const unReceiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.unReceiptAmount) || 0);
+ }, 0);
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.removeStorageSync('supplierId')
- uni.navigateBack();
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("supplierId");
+ uni.navigateBack();
+ };
-// 鑾峰彇椤甸潰鍙傛暟
-const getPageParams = () => {
- // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
- const storedSupplierId = uni.getStorageSync('supplierId');
- if (storedSupplierId) {
- supplierId.value = storedSupplierId;
- }
-};
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
+ const storedSupplierId = uni.getStorageSync("supplierId");
+ if (storedSupplierId) {
+ supplierId.value = storedSupplierId;
+ }
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- if (!supplierId.value) {
- uni.showToast({
- title: '瀹㈡埛淇℃伅缂哄け',
- icon: 'error'
- });
- return;
- }
- showLoadingToast('鍔犺浇涓�...')
- paymentRecordList(supplierId.value).then((res) => {
- tableData.value = res.data;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ if (!supplierId.value) {
+ uni.showToast({
+ title: "瀹㈡埛淇℃伅缂哄け",
+ icon: "error",
+ });
+ return;
+ }
+ showLoadingToast("鍔犺浇涓�...");
+ paymentRecordList({ supplierId: supplierId.value })
+ .then(res => {
+ tableData.value = res.data;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-// 鏍煎紡鍖栭噾棰�
-const formatAmount = (amount) => {
- return amount ? parseFloat(amount).toFixed(2) : '0.00';
-};
+ // 鏍煎紡鍖栭噾棰�
+ const formatAmount = amount => {
+ return amount ? parseFloat(amount).toFixed(2) : "0.00";
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-onMounted(() => {
- // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
- getPageParams();
- getList();
-});
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ getList();
+ });
</script>
<style scoped lang="scss">
-.receipt-payment-detail {
- min-height: 100vh;
- background: #f8f9fa;
- position: relative;
-}
+ .receipt-payment-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
-.u-divider {
- margin: 0 !important;
-}
+ .u-divider {
+ margin: 0 !important;
+ }
-.summary-info {
- background: #ffffff;
- margin: 20px 20px 0 20px;
- border-radius: 12px;
- padding: 16px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-}
+ .summary-info {
+ background: #ffffff;
+ margin: 20px 20px 0 20px;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
-.summary-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .summary-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
-.summary-label {
- font-size: 14px;
- color: #666;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.summary-value {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .summary-label {
+ font-size: 14px;
+ color: #666;
+ }
-.summary-value.highlight {
- color: #2979ff;
- font-weight: 600;
-}
+ .summary-value {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.summary-value.danger {
- color: #ff4757;
- font-weight: 600;
-}
+ .summary-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
-.detail-list {
- padding: 20px;
-}
+ .summary-value.danger {
+ color: #ff4757;
+ font-weight: 600;
+ }
-.detail-item {
- background: #ffffff;
- border-radius: 12px;
- margin-bottom: 16px;
- overflow: hidden;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- padding: 0 16px;
-}
+ .detail-list {
+ padding: 20px;
+ }
-.item-header {
- padding: 10px 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
+ .detail-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+ }
-.item-left {
- display: flex;
- align-items: center;
- gap: 8px;
-}
+ .item-header {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
-.record-icon {
- width: 24px;
- height: 24px;
- background: #2979ff;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
-.item-index {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .record-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.item-date {
- font-size: 12px;
- color: #666;
-}
+ .item-index {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.item-details {
- padding: 16px 0;
-}
+ .item-date {
+ font-size: 12px;
+ color: #666;
+ }
-.detail-row {
- display: flex;
- align-items: flex-end;
- justify-content: space-between;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .item-details {
+ padding: 16px 0;
+ }
-.detail-label {
- font-size: 12px;
- color: #777777;
- min-width: 60px;
-}
+ .detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
-.detail-value {
- font-size: 12px;
- color: #000000;
- text-align: right;
- flex: 1;
- margin-left: 16px;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.detail-value.highlight {
- color: #2979ff;
- font-weight: 500;
-}
+ .detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+ }
-.detail-value.danger {
- color: #ff4757;
- font-weight: 500;
-}
+ .detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+ }
-.no-data {
- padding: 40px 0;
- text-align: center;
- color: #999;
-}
+ .detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.danger {
+ color: #ff4757;
+ font-weight: 500;
+ }
+
+ .no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+ }
</style>
diff --git a/src/pages/procurementManagement/paymentLedger/index.vue b/src/pages/procurementManagement/paymentLedger/index.vue
index f3e2771..8bd7c6e 100644
--- a/src/pages/procurementManagement/paymentLedger/index.vue
+++ b/src/pages/procurementManagement/paymentLedger/index.vue
@@ -44,12 +44,12 @@
<up-divider></up-divider>
<view class="item-details">
<view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
<text class="detail-value">{{ formattedNumber(item.invoiceAmount) }}</text>
</view>
<view class="detail-row">
<text class="detail-label">浠樻閲戦(鍏�)</text>
- <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text>
+ <text class="detail-value">{{ formattedNumber(item.paymentAmount) }}</text>
</view>
<view class="detail-row">
<text class="detail-label">搴斾粯閲戦(鍏�)</text>
diff --git a/src/pages/procurementManagement/procurementInvoiceLedger/detail.vue b/src/pages/procurementManagement/procurementInvoiceLedger/detail.vue
index ea9a233..3b0bea3 100644
--- a/src/pages/procurementManagement/procurementInvoiceLedger/detail.vue
+++ b/src/pages/procurementManagement/procurementInvoiceLedger/detail.vue
@@ -1,224 +1,335 @@
<template>
- <view class="account-detail">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="缂栬緫鏉ョエ鍙拌处" @back="goBack" />
-
- <up-form @submit="submitForm" ref="formRef" label-width="120" :model="form">
- <up-form-item label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber">
- <up-input v-model="form.purchaseContractNumber" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item label="閿�鍞悎鍚屽彿" prop="salesContractNo">
- <up-input v-model="form.salesContractNo" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice">
- <up-input v-model="form.taxInclusiveUnitPrice" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item label="鍒涘缓鏃堕棿" prop="createdAt">
- <up-input v-model="form.createdAt" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item label="鍙戠エ鍙�" prop="invoiceNumber">
- <up-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" disabled />
- </up-form-item>
- <up-form-item label="鏉ョエ鏁�" prop="ticketsNum" required :rules="rules.ticketsNum">
- <up-input
- v-model="form.ticketsNum"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="inputTicketsNum"
- />
- </up-form-item>
- <up-form-item label="鏈鏉ョエ閲戦(鍏�)" prop="ticketsAmount" required :rules="rules.ticketsAmount">
- <up-input
- v-model="form.ticketsAmount"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="inputTicketsAmount"
- />
- </up-form-item>
- <view class="tip-text">鏈潵绁ㄦ暟锛歿{ formatAmount(form.futureTickets) }} 鍏�</view>
-
- <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
- <FooterButtons
- show
- cancelText="鍙栨秷"
- confirmText="淇濆瓨"
- @cancel="goBack"
- @confirm="onSubmit"
- />
- </up-form>
- </view>
+ <view class="account-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="缂栬緫鏉ョエ鍙拌处"
+ @back="goBack" />
+ <up-form @submit="submitForm"
+ ref="formRef"
+ label-width="120"
+ :model="form">
+ <up-form-item label="閲囪喘鍚堝悓鍙�"
+ prop="purchaseContractNumber">
+ <up-input v-model="form.purchaseContractNumber"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo">
+ <up-input v-model="form.salesContractNo"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice">
+ <up-input v-model="form.taxInclusiveUnitPrice"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍒涘缓鏃堕棿"
+ prop="createdAt">
+ <up-input v-model="form.createdAt"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍙戠エ鍙�"
+ prop="invoiceNumber">
+ <up-input v-model="form.invoiceNumber"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鏉ョエ鏁�"
+ prop="ticketsNum"
+ required
+ :rules="rules.ticketsNum">
+ <up-input v-model="form.ticketsNum"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="inputTicketsNum" />
+ </up-form-item>
+ <up-form-item label="鏈鏉ョエ閲戦(鍏�)"
+ prop="ticketsAmount"
+ required
+ :rules="rules.ticketsAmount">
+ <up-input v-model="form.ticketsAmount"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="inputTicketsAmount" />
+ </up-form-item>
+ <view class="tip-text">鏈潵绁ㄦ暟锛歿{ formatAmount(form.futureTickets) }} </view>
+ <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
+ <FooterButtons show
+ cancelText="鍙栨秷"
+ confirmText="淇濆瓨"
+ @cancel="goBack"
+ @confirm="onSubmit" />
+ </up-form>
+ </view>
</template>
<script setup>
-import { ref, onMounted } from 'vue'
-import dayjs from 'dayjs'
-import useUserStore from '@/store/modules/user'
-import { getToken } from '@/utils/auth'
-import { invoiceLedgerSaveOrUpdate } from '@/api/salesManagement/invoiceLedger.js'
-import config from '@/config.js'
-import {getProductRecordById, updateRegistration} from "@/api/procurementManagement/procurementInvoiceLedger";
-import PageHeader from '@/components/PageHeader.vue';
-import FooterButtons from '@/components/FooterButtons.vue';
+ import { ref, onMounted } from "vue";
+ import dayjs from "dayjs";
+ import useUserStore from "@/store/modules/user";
+ import { getToken } from "@/utils/auth";
+ import { invoiceLedgerSaveOrUpdate } from "@/api/salesManagement/invoiceLedger.js";
+ import config from "@/config.js";
+ import {
+ getProductRecordById,
+ updateRegistration,
+ } from "@/api/procurementManagement/procurementInvoiceLedger";
+ import PageHeader from "@/components/PageHeader.vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-const formRef = ref()
-let form = ref({
- salesLedgerId: '',
- customerId: '',
- invoiceNo: '',
- invoiceTotal: '',
- taxRate: '',
- invoicePerson: '',
- invoiceDate: '',
- customerName: '',
- fileList: [],
- createTime: '',
- taxInclusiveTotalPrice: '',
- taxInclusiveUnitPrice: ''
-})
-const fileList = ref([])
-const currentId = ref('')
-const temFutureTickets = ref(0)
+ const formRef = ref();
+ let form = ref({
+ salesLedgerId: "",
+ customerId: "",
+ invoiceNo: "",
+ invoiceTotal: "",
+ taxRate: "",
+ invoicePerson: "",
+ invoiceDate: "",
+ customerName: "",
+ fileList: [],
+ createTime: "",
+ taxInclusiveTotalPrice: "",
+ taxInclusiveUnitPrice: "",
+ });
+ const fileList = ref([]);
+ const currentId = ref("");
+ const temFutureTickets = ref(0);
+ const originalTicketsNum = ref(0); // 淇濆瓨鍘熷鏉ョエ鏁�
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- ticketsNum: [
- { required: true, message: '璇疯緭鍏ユ潵绁ㄦ暟', trigger: 'blur' }
- ],
- ticketsAmount: [
- { required: true, message: '璇疯緭鍏ユ湰娆℃潵绁ㄩ噾棰�', trigger: 'blur' }
- ]
-};
+ // 琛ㄥ崟鏍¢獙瑙勫垯 - 浣跨敤绠�鍗曠殑 required 瑙勫垯
+ const rules = {
+ ticketsNum: [{ required: true, message: "璇疯緭鍏ユ潵绁ㄦ暟", trigger: "blur" }],
+ ticketsAmount: [
+ { required: true, message: "璇疯緭鍏ユ湰娆℃潵绁ㄩ噾棰�", trigger: "blur" },
+ ],
+ };
-const goBack = () => {
- uni.removeStorageSync('invoiceLedgerEditRow');
- uni.navigateBack()
-}
-const inputTicketsNum = () => {
- // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
- if (!form.value.taxInclusiveUnitPrice || Number(form.value.taxInclusiveUnitPrice) === 0) {
- uni.showToast({
- title: "鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟",
- icon: 'none'
- });
- return;
- }
- if (Number(form.value.ticketsNum) > Number(temFutureTickets.value)) {
- uni.showToast({
- title: "鏉ョエ鏁颁笉寰楀ぇ浜庢湭鏉ョエ鏁�",
- icon: 'none'
- });
- form.value.ticketsNum = temFutureTickets.value
- }
-
- // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsAmount = Number(form.value.ticketsNum) * Number(form.value.taxInclusiveUnitPrice);
- const futureTickets = Number(temFutureTickets.value) - Number(form.value.ticketsNum);
- form.value.futureTickets = Number(futureTickets.toFixed(2));
- form.value.ticketsAmount = Number(ticketsAmount.toFixed(2));
-};
-const inputTicketsAmount = () => {
- // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
- if (!form.value.taxInclusiveUnitPrice || Number(form.value.taxInclusiveUnitPrice) === 0) {
- uni.showToast({
- title: "鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟",
- icon: 'none'
- });
- return;
- }
-
- if (Number(form.value.ticketsAmount) > Number(form.value.futureTickets*form.value.taxInclusiveUnitPrice)) {
- uni.showToast({
- title: "鏈鏉ョエ閲戦涓嶅緱澶т簬鎬婚噾棰�",
- icon: 'none'
- });
- form.value.ticketsAmount = (form.value.futureTickets*form.value.taxInclusiveUnitPrice).toFixed(2)
- const ticketsNum = Number(form.value.ticketsAmount) / Number(form.value.taxInclusiveUnitPrice);
- form.value.ticketsNum = Number(ticketsNum.toFixed(2))
- return;
- }
-
- // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
- const ticketsNum = Number(form.value.ticketsAmount) / Number(form.value.taxInclusiveUnitPrice);
- form.value.ticketsNum = Number(ticketsNum.toFixed(2));
-};
-const formatAmount = (val) => {
- if (val === undefined || val === null || val === '') return '0.00'
- const num = Number(val)
- if (Number.isNaN(num)) return '0.00'
- return num.toFixed(2)
-}
+ const goBack = () => {
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.navigateBack();
+ };
+ const inputTicketsNum = () => {
+ // 澶勭悊绌哄�兼儏鍐�
+ if (!form.value.ticketsNum || form.value.ticketsNum === "") {
+ form.value.ticketsNum = 0;
+ return;
+ }
+
+ // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
+ if (
+ !form.value.taxInclusiveUnitPrice ||
+ Number(form.value.taxInclusiveUnitPrice) === 0
+ ) {
+ uni.showToast({
+ title: "鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟",
+ icon: "none",
+ });
+ return;
+ }
+
+ const newTicketsNum = Number(form.value.ticketsNum) || 0;
+ // 璁$畻鎬诲彲鐢ㄧエ鏁帮細鍘熷鏈潵绁ㄦ暟 + 鍘熷鏉ョエ鏁�
+ const totalAvailableTickets = Number(temFutureTickets.value) + Number(originalTicketsNum.value);
+
+ // 楠岃瘉鏉ョエ鏁颁笉鑳藉ぇ浜庢�诲彲鐢ㄧエ鏁�
+ if (newTicketsNum > totalAvailableTickets) {
+ uni.showToast({
+ title: "鏉ョエ鏁颁笉寰楀ぇ浜庢�诲彲鐢ㄧエ鏁�",
+ icon: "none",
+ });
+ form.value.ticketsNum = totalAvailableTickets;
+ // 閲嶆柊璁$畻鏈潵绁ㄦ暟
+ const futureTickets = totalAvailableTickets - totalAvailableTickets;
+ form.value.futureTickets = Number(futureTickets.toFixed(2));
+ form.value.ticketsAmount = Number((totalAvailableTickets * Number(form.value.taxInclusiveUnitPrice)).toFixed(2));
+ return;
+ }
-const loadDetail = async (id) => {
- try {
- uni.showLoading({
- title: '鍔犺浇涓�...'
- });
- const res = await getProductRecordById({ id })
- const data = res?.data || res
- form.value = { ...data }
- temFutureTickets.value = data.futureTickets;
- fileList.value = data?.fileList || []
- if (!form.value.invoicePerson) {
- form.value.invoicePerson = userStore.nickName
- }
- if (!form.value.invoiceDate) {
- form.value.invoiceDate = dayjs().format('YYYY-MM-DD')
- }
- uni.hideLoading();
- } catch (e) {
- uni.hideLoading();
- uni.showToast({
- title: '鍔犺浇澶辫触',
- icon: 'none'
- });
- }
-}
+ // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
+ const ticketsAmount =
+ newTicketsNum * Number(form.value.taxInclusiveUnitPrice);
+ // 璁$畻鏈潵绁ㄦ暟锛氭�诲彲鐢ㄧエ鏁� - 鏂版潵绁ㄦ暟
+ const futureTickets = totalAvailableTickets - newTicketsNum;
+ form.value.futureTickets = Number(futureTickets.toFixed(2));
+ form.value.ticketsAmount = Number(ticketsAmount.toFixed(2));
+ };
+ const inputTicketsAmount = () => {
+ // 澶勭悊绌哄�兼儏鍐�
+ if (!form.value.ticketsAmount || form.value.ticketsAmount === "") {
+ form.value.ticketsAmount = 0;
+ }
+
+ // 纭繚鍚◣鍗曚环瀛樺湪涓斾笉涓洪浂
+ if (
+ !form.value.taxInclusiveUnitPrice ||
+ Number(form.value.taxInclusiveUnitPrice) === 0
+ ) {
+ uni.showToast({
+ title: "鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟",
+ icon: "none",
+ });
+ return;
+ }
-const submitForm = async () => {
- try {
- // 鎻愪氦琛ㄥ崟鐨勫叿浣撻�昏緫
- await updateRegistration(form.value)
- uni.showToast({
- title: '鎻愪氦鎴愬姛',
- icon: 'success'
- });
- setTimeout(() => { goBack() }, 800)
- } catch (e) {
- uni.showToast({
- title: '鎻愪氦澶辫触锛岃閲嶈瘯',
- icon: 'none'
- });
- }
-}
+ const newTicketsAmount = Number(form.value.ticketsAmount) || 0;
+ // 璁$畻鎬诲彲鐢ㄩ噾棰濓細鍘熷鏈潵绁ㄦ暟 + 鍘熷鏉ョエ鏁�
+ const totalAvailableTickets = Number(temFutureTickets.value) + Number(originalTicketsNum.value);
+ const totalAvailableAmount = totalAvailableTickets * Number(form.value.taxInclusiveUnitPrice);
-// 琛ㄥ崟鎻愪氦
-const onSubmit = () => {
- formRef.value.validate().then(() => {
- // 琛ㄥ崟楠岃瘉閫氳繃锛屾彁浜よ〃鍗�
- submitForm();
- }).catch(error => {
- // 琛ㄥ崟楠岃瘉澶辫触
- console.log('琛ㄥ崟楠岃瘉澶辫触', error);
- });
-};
+ if (newTicketsAmount > totalAvailableAmount) {
+ uni.showToast({
+ title: "鏈鏉ョエ閲戦涓嶅緱澶т簬鎬婚噾棰�",
+ icon: "none",
+ });
+ form.value.ticketsAmount = totalAvailableAmount.toFixed(2);
+ const ticketsNum =
+ Number(form.value.ticketsAmount) /
+ Number(form.value.taxInclusiveUnitPrice);
+ form.value.ticketsNum = Number(ticketsNum.toFixed(2));
+ // 鏇存柊鏈潵绁ㄦ暟
+ const futureTickets = totalAvailableTickets - form.value.ticketsNum;
+ form.value.futureTickets = Number(futureTickets.toFixed(2));
+ return;
+ }
-onMounted(() => {
- const rowStr = uni.getStorageSync('invoiceLedgerEditRow')
- if (rowStr) {
- try {
- const row = JSON.parse(rowStr)
- currentId.value = row.id
- loadDetail(currentId.value)
- } catch (e) {
- // ignore
- }
- }
-});
+ // 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
+ const ticketsNum =
+ newTicketsAmount / Number(form.value.taxInclusiveUnitPrice);
+ form.value.ticketsNum = Number(ticketsNum.toFixed(2));
+ // 鏇存柊鏈潵绁ㄦ暟
+ const futureTickets = totalAvailableTickets - form.value.ticketsNum;
+ form.value.futureTickets = Number(futureTickets.toFixed(2));
+ };
+ const formatAmount = val => {
+ if (val === undefined || val === null || val === "") return "0.00";
+ const num = Number(val);
+ if (Number.isNaN(num)) return "0.00";
+ return num.toFixed(2);
+ };
+
+ const loadDetail = async (id, purchaseLedgerId, productModelId) => {
+ try {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ });
+ const res = await getProductRecordById({
+ id: id,
+ purchaseLedgerId: purchaseLedgerId,
+ productModelId: productModelId,
+ });
+ const data = res?.data || res;
+ form.value = { ...data };
+ temFutureTickets.value = data.futureTickets;
+ originalTicketsNum.value = Number(data.ticketsNum) || 0; // 淇濆瓨鍘熷鏉ョエ鏁�
+ fileList.value = data?.fileList || [];
+ if (!form.value.invoicePerson) {
+ form.value.invoicePerson = userStore.nickName;
+ }
+ if (!form.value.invoiceDate) {
+ form.value.invoiceDate = dayjs().format("YYYY-MM-DD");
+ }
+ uni.hideLoading();
+ } catch (e) {
+ uni.hideLoading();
+ uni.showToast({
+ title: "鍔犺浇澶辫触",
+ icon: "none",
+ });
+ }
+ };
+
+ const submitForm = async () => {
+ try {
+ // 鎻愪氦琛ㄥ崟鐨勫叿浣撻�昏緫
+ await updateRegistration(form.value);
+ uni.showToast({
+ title: "鎻愪氦鎴愬姛",
+ icon: "success",
+ });
+ setTimeout(() => {
+ goBack();
+ }, 800);
+ } catch (e) {
+ uni.showToast({
+ title: "鎻愪氦澶辫触锛岃閲嶈瘯",
+ icon: "none",
+ });
+ }
+ };
+
+ // 琛ㄥ崟鎻愪氦
+ const onSubmit = async () => {
+ // 鍦ㄩ獙璇佸墠锛岀‘淇濆繀濉瓧娈垫湁鍊�
+ if (!form.value.ticketsNum || form.value.ticketsNum === "" || form.value.ticketsNum === null || form.value.ticketsNum === undefined) {
+ uni.showToast({
+ title: "璇疯緭鍏ユ潵绁ㄦ暟",
+ icon: "none",
+ });
+ return;
+ }
+
+ if (!form.value.ticketsAmount || form.value.ticketsAmount === "" || form.value.ticketsAmount === null || form.value.ticketsAmount === undefined) {
+ uni.showToast({
+ title: "璇疯緭鍏ユ湰娆℃潵绁ㄩ噾棰�",
+ icon: "none",
+ });
+ return;
+ }
+
+ // 纭繚瀛楁鏄暟瀛楃被鍨嬶紝骞惰浆鎹负瀛楃涓诧紙鍥犱负琛ㄥ崟鍙兘闇�瑕佸瓧绗︿覆绫诲瀷锛�
+ const ticketsNum = Number(form.value.ticketsNum);
+ const ticketsAmount = Number(form.value.ticketsAmount);
+
+ // 濡傛灉鏉ョエ鏁颁负0鎴栨潵绁ㄩ噾棰濅负0锛屾彁绀虹敤鎴�
+ if (isNaN(ticketsNum) || ticketsNum <= 0) {
+ uni.showToast({
+ title: "鏉ョエ鏁板繀椤诲ぇ浜�0",
+ icon: "none",
+ });
+ return;
+ }
+
+ if (isNaN(ticketsAmount) || ticketsAmount <= 0) {
+ uni.showToast({
+ title: "鏈鏉ョエ閲戦蹇呴』澶т簬0",
+ icon: "none",
+ });
+ return;
+ }
+
+ // 鏇存柊琛ㄥ崟鍊硷紝纭繚鏄湁鏁堢殑鏁板瓧瀛楃涓�
+ form.value.ticketsNum = ticketsNum.toString();
+ form.value.ticketsAmount = ticketsAmount.toString();
+
+ // 鎵嬪姩楠岃瘉閫氳繃鍚庯紝鐩存帴鎻愪氦锛岃烦杩囪〃鍗曢獙璇侊紙閬垮厤鐪熸満涓婄殑楠岃瘉闂锛�
+ submitForm();
+ };
+ const purchaseLedgerId = ref("");
+ const productModelId = ref({});
+
+ onMounted(() => {
+ const rowStr = uni.getStorageSync("invoiceLedgerEditRow");
+ if (rowStr) {
+ try {
+ const row = JSON.parse(rowStr);
+ currentId.value = row.id;
+ purchaseLedgerId.value = row.purchaseLedgerId;
+ productModelId.value = row.productModelId;
+ loadDetail(currentId.value, purchaseLedgerId.value, productModelId.value);
+ } catch (e) {
+ // ignore
+ }
+ }
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
</style>
diff --git a/src/pages/procurementManagement/procurementInvoiceLedger/index.vue b/src/pages/procurementManagement/procurementInvoiceLedger/index.vue
index 4934371..cc35d42 100644
--- a/src/pages/procurementManagement/procurementInvoiceLedger/index.vue
+++ b/src/pages/procurementManagement/procurementInvoiceLedger/index.vue
@@ -1,95 +1,99 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鏉ョエ鍙拌处" @back="goBack" />
-
- <!-- 鎼滅储鍖哄煙 -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О鎼滅储"
- v-model="searchForm.supplierName"
- @change="handleQuery"
- clearable
- />
- </view>
- <view class="filter-button" @click="handleQuery">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 鍒楄〃鍖哄煙 -->
- <view class="ledger-list" v-if="total > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.purchaseContractNumber }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">閿�鍞悎鍚屽彿</text>
- <text class="detail-value">{{ item.salesContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
- <text class="detail-value">{{ item.supplierName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浜у搧澶х被</text>
- <text class="detail-value">{{ item.productCategory }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瑙勬牸鍨嬪彿</text>
- <text class="detail-value">{{ item.specificationModel }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ鍙�</text>
- <text class="detail-value">{{ item.invoiceNumber || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value">{{ item.taxInclusiveTotalPrice || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鏉ョエ鏃ユ湡</text>
- <text class="detail-value">{{ item.createdAt || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鏉ョエ閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.ticketsAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">涓嶅惈绋庨噾棰�(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.unTicketsPrice) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">澧炲�肩◣</text>
- <text class="detail-value">{{ item.invoiceAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆浜�</text>
- <text class="detail-value">{{ item.issUer }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆鏃ユ湡</text>
- <text class="detail-value">{{ item.createdAt }}</text>
- </view>
- </view>
- <view class="action-buttons">
- <u-button
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鏉ョエ鍙拌处"
+ @back="goBack" />
+ <!-- 鎼滅储鍖哄煙 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О鎼滅储"
+ v-model="searchForm.supplierName"
+ @change="handleQuery"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="handleQuery">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鍒楄〃鍖哄煙 -->
+ <view class="ledger-list"
+ v-if="total > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.specificationModel }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戠エ鍙�</text>
+ <text class="detail-value">{{ item.invoiceNumber || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value">{{ item.taxInclusiveTotalPrice || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鏉ョエ鏃ユ湡</text>
+ <text class="detail-value">{{ item.createdAt || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鏉ョエ閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.ticketsAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓嶅惈绋庨噾棰�(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.unTicketsPrice) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">澧炲�肩◣</text>
+ <text class="detail-value">{{ item.invoiceAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.issUer }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ item.createdAt }}</text>
+ </view>
+ </view>
+ <view class="action-buttons">
+ <!-- <u-button
type="primary"
size="small"
class="action-btn"
@@ -107,313 +111,330 @@
@click="handleDelete(item)"
>
鍒犻櫎
- </u-button>
-<!-- <u-button-->
-<!-- type="default"-->
-<!-- size="small"-->
-<!-- plain-->
-<!-- class="action-btn"-->
-<!-- v-if="item.invoiceFileName"-->
-<!-- @click="openFileActions(item.commonFiles || [])"-->
-<!-- >-->
-<!-- 鏌ョ湅闄勪欢-->
-<!-- </u-button>-->
-<!-- <u-button-->
-<!-- type="primary"-->
-<!-- size="small"-->
-<!-- class="action-btn"-->
-<!-- v-else-->
-<!-- :disabled="item.issUer !== userStore.nickName"-->
-<!-- @click="openUpload(item)"-->
-<!-- >-->
-<!-- 涓婁紶-->
-<!-- </u-button>-->
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤鏉ョエ鍙拌处鏁版嵁</text>
- </view>
-
- <!-- 鍗曡涓婁紶寮圭獥锛堟棤琛ㄥ崟锛� -->
- <u-popup v-model="showUpload" mode="bottom" border-radius="10">
- <view class="upload-container">
- <view class="popup-header">
- <text class="popup-title">涓婁紶闄勪欢锛堜粎鏀寔 pdf锛屾渶澶�10MB锛屾渶澶�10涓級</text>
- </view>
- <u-upload
- ref="uploadRef"
- accept="file"
- multiple
- :max-count="10"
- :show-progress="true"
- :before-upload="beforeReadPdf"
- :action="uploadUrl"
- :header="{ Authorization: 'Bearer ' + getToken() }"
- name="file"
- @on-success="onUploadSuccess"
- @on-error="onUploadError"
- />
- <view class="uploaded-list" v-if="fileList.length">
- <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">
- <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
- <u-button size="mini" type="error" plain @click="removeUploaded(idx)">绉婚櫎</u-button>
- </view>
- </view>
- <view class="filter-actions">
- <u-button @click="showUpload = false" type="default" size="default" style="width: 150px;">鍙栨秷</u-button>
- <u-button @click="confirmUpload" type="primary" size="default" style="width: 150px;">纭</u-button>
- </view>
- </view>
- </u-popup>
-
- <!-- 闄勪欢鍒楄〃閫夋嫨 -->
- <u-action-sheet v-model="showFileSheet" :list="fileActions" :cancel-btn="true" @click="onSelectFile" @close="showFileSheet = false" />
- </view>
+ </u-button> -->
+ <!-- <u-button-->
+ <!-- type="default"-->
+ <!-- size="small"-->
+ <!-- plain-->
+ <!-- class="action-btn"-->
+ <!-- v-if="item.invoiceFileName"-->
+ <!-- @click="openFileActions(item.commonFiles || [])"-->
+ <!-- >-->
+ <!-- 鏌ョ湅闄勪欢-->
+ <!-- </u-button>-->
+ <!-- <u-button-->
+ <!-- type="primary"-->
+ <!-- size="small"-->
+ <!-- class="action-btn"-->
+ <!-- v-else-->
+ <!-- :disabled="item.issUer !== userStore.nickName"-->
+ <!-- @click="openUpload(item)"-->
+ <!-- >-->
+ <!-- 涓婁紶-->
+ <!-- </u-button>-->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鏉ョエ鍙拌处鏁版嵁</text>
+ </view>
+ <!-- 鍗曡涓婁紶寮圭獥锛堟棤琛ㄥ崟锛� -->
+ <u-popup v-model="showUpload"
+ mode="bottom"
+ border-radius="10">
+ <view class="upload-container">
+ <view class="popup-header">
+ <text class="popup-title">涓婁紶闄勪欢锛堜粎鏀寔 pdf锛屾渶澶�10MB锛屾渶澶�10涓級</text>
+ </view>
+ <u-upload ref="uploadRef"
+ accept="file"
+ multiple
+ :max-count="10"
+ :show-progress="true"
+ :before-upload="beforeReadPdf"
+ :action="uploadUrl"
+ :header="{ Authorization: 'Bearer ' + getToken() }"
+ name="file"
+ @on-success="onUploadSuccess"
+ @on-error="onUploadError" />
+ <view class="uploaded-list"
+ v-if="fileList.length">
+ <view class="uploaded-item"
+ v-for="(f, idx) in fileList"
+ :key="idx">
+ <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
+ <u-button size="mini"
+ type="error"
+ plain
+ @click="removeUploaded(idx)">绉婚櫎</u-button>
+ </view>
+ </view>
+ <view class="filter-actions">
+ <u-button @click="showUpload = false"
+ type="default"
+ size="default"
+ style="width: 150px;">鍙栨秷</u-button>
+ <u-button @click="confirmUpload"
+ type="primary"
+ size="default"
+ style="width: 150px;">纭</u-button>
+ </view>
+ </view>
+ </u-popup>
+ <!-- 闄勪欢鍒楄〃閫夋嫨 -->
+ <u-action-sheet v-model="showFileSheet"
+ :list="fileActions"
+ :cancel-btn="true"
+ @click="onSelectFile"
+ @close="showFileSheet = false" />
+ </view>
</template>
<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import dayjs from 'dayjs'
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
-import useUserStore from '@/store/modules/user'
-import { getToken } from '@/utils/auth'
-import config from '@/config.js'
-import {
- registrationProductPage,
- commitFile,
- delInvoiceLedgerByRegProductId
-} from '@/api/salesManagement/invoiceLedger.js'
-import {onShow} from "@dcloudio/uni-app";
-import {productRecordPage} from "@/api/procurementManagement/procurementInvoiceLedger";
-import {delRegistration} from "@/api/procurementManagement/invoiceEntry";
-import PageHeader from '@/components/PageHeader.vue';
-import FooterButtons from '@/components/FooterButtons.vue';
+ import { ref, reactive, onMounted } from "vue";
+ import dayjs from "dayjs";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import useUserStore from "@/store/modules/user";
+ import { getToken } from "@/utils/auth";
+ import config from "@/config.js";
+ import {
+ registrationProductPage,
+ commitFile,
+ delInvoiceLedgerByRegProductId,
+ } from "@/api/salesManagement/invoiceLedger.js";
+ import { onShow } from "@dcloudio/uni-app";
+ import { productRecordPage } from "@/api/procurementManagement/procurementInvoiceLedger";
+ import { delRegistration } from "@/api/procurementManagement/invoiceEntry";
+ import PageHeader from "@/components/PageHeader.vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 鍒楄〃涓庢煡璇�
-const ledgerList = ref([])
-const total = ref(0)
-const page = reactive({ current: -1, size: -1 })
-const searchForm = reactive({
- supplierName: '',
-})
+ // 鍒楄〃涓庢煡璇�
+ const ledgerList = ref([]);
+ const total = ref(0);
+ const page = reactive({ current: -1, size: -1 });
+ const searchForm = reactive({
+ supplierName: "",
+ });
-const currentId = ref('')
-const fileList = ref([]) // 琛屼笂浼犳垨閫氱敤涓婁紶鍒楄〃
-const uploadRef = ref()
-const uploadUrl = config.baseUrl + '/invoiceLedger/uploadFile'
+ const currentId = ref("");
+ const fileList = ref([]); // 琛屼笂浼犳垨閫氱敤涓婁紶鍒楄〃
+ const uploadRef = ref();
+ const uploadUrl = config.baseUrl + "/invoiceLedger/uploadFile";
-// 琛屼笂浼犲脊绐�
-const showUpload = ref(false)
+ // 琛屼笂浼犲脊绐�
+ const showUpload = ref(false);
-// 闄勪欢鏌ョ湅
-const showFileSheet = ref(false)
-const fileActions = ref([])
-let currentFilesToOpen = []
+ // 闄勪欢鏌ョ湅
+ const showFileSheet = ref(false);
+ const fileActions = ref([]);
+ let currentFilesToOpen = [];
-const formatAmount = (val) => {
- if (val === undefined || val === null || val === '') return '0.00'
- const num = Number(val)
- if (Number.isNaN(num)) return '0.00'
- return num.toFixed(2)
-}
-const formatDateTime = (val) => {
- if (!val) return ''
- return dayjs(val).format('YYYY-MM-DD HH:mm:ss')
-}
+ const formatAmount = val => {
+ if (val === undefined || val === null || val === "") return "0.00";
+ const num = Number(val);
+ if (Number.isNaN(num)) return "0.00";
+ return num.toFixed(2);
+ };
+ const formatDateTime = val => {
+ if (!val) return "";
+ return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+ };
-const goBack = () => {
- uni.navigateBack()
-}
+ const goBack = () => {
+ uni.navigateBack();
+ };
-const handleQuery = () => {
- getList()
-}
+ const handleQuery = () => {
+ getList();
+ };
-const getList = async () => {
- try {
- uni.showLoading({
- title: '鍔犺浇涓�...'
- });
- const res = await productRecordPage({ ...searchForm, ...page })
- // 鍏煎涓嶅悓杩斿洖缁撴瀯
- const records = res?.data?.records || res?.records || res?.data || []
- const totalVal = res?.data?.total || res?.total || records.length || 0
- ledgerList.value = records
- total.value = totalVal
- uni.hideLoading();
- } catch (e) {
- uni.hideLoading();
- showToast('鑾峰彇鍒楄〃澶辫触')
- }
-}
+ const getList = async () => {
+ try {
+ uni.showLoading({
+ title: "鍔犺浇涓�...",
+ });
+ const res = await productRecordPage({ ...searchForm, ...page });
+ // 鍏煎涓嶅悓杩斿洖缁撴瀯
+ const records = res?.data?.records || res?.records || res?.data || [];
+ const totalVal = res?.data?.total || res?.total || records.length || 0;
+ ledgerList.value = records;
+ total.value = totalVal;
+ uni.hideLoading();
+ } catch (e) {
+ uni.hideLoading();
+ showToast("鑾峰彇鍒楄〃澶辫触");
+ }
+ };
-// 缂栬緫閫昏緫鏀逛负璺宠浆鏂伴〉闈�
-const openEdit = (row) => {
- try {
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(row))
- uni.navigateTo({ url: '/pages/procurementManagement/procurementInvoiceLedger/detail' })
- } catch (e) {
- showToast('璺宠浆澶辫触')
- }
-}
+ // 缂栬緫閫昏緫鏀逛负璺宠浆鏂伴〉闈�
+ const openEdit = row => {
+ try {
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/procurementManagement/procurementInvoiceLedger/detail",
+ });
+ } catch (e) {
+ showToast("璺宠浆澶辫触");
+ }
+ };
-// 鍒犻櫎
-const handleDelete = (row) => {
- let ids = [];
- ids.push(row.id);
- console.log(ids)
- uni.showModal({
- title: '鍒犻櫎纭',
- content: '璇ュ彂绁ㄥ彴璐﹀皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- success: async (res) => {
- if (res.confirm) {
- try {
- uni.showLoading({
- title: '澶勭悊涓�...'
- });
- await delRegistration(ids)
- uni.hideLoading();
- showToast('鍒犻櫎鎴愬姛')
- await getList()
- } catch (e) {
- uni.hideLoading();
- showToast('鍒犻櫎澶辫触锛岃閲嶈瘯')
- }
- }
- }
- })
-}
+ // 鍒犻櫎
+ const handleDelete = row => {
+ let ids = [];
+ ids.push(row.id);
+ console.log(ids);
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: "璇ュ彂绁ㄥ彴璐﹀皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
+ success: async res => {
+ if (res.confirm) {
+ try {
+ uni.showLoading({
+ title: "澶勭悊涓�...",
+ });
+ await delRegistration(ids);
+ uni.hideLoading();
+ showToast("鍒犻櫎鎴愬姛");
+ await getList();
+ } catch (e) {
+ uni.hideLoading();
+ showToast("鍒犻櫎澶辫触锛岃閲嶈瘯");
+ }
+ }
+ },
+ });
+ };
-// 琛屼笂浼�
-const openUpload = (row) => {
- currentId.value = row.id
- fileList.value = []
- showUpload.value = true
-}
-const confirmUpload = async () => {
- try {
- const payload = { fileList: fileList.value, id: currentId.value }
- uni.showLoading({
- title: '鎻愪氦涓�...'
- });
- await commitFile(payload)
- uni.hideLoading();
- showToast('鎻愪氦鎴愬姛')
- showUpload.value = false
- fileList.value = []
- currentId.value = ''
- getList()
- } catch (e) {
- uni.hideLoading();
- showToast('鎻愪氦澶辫触锛岃閲嶈瘯')
- }
-}
+ // 琛屼笂浼�
+ const openUpload = row => {
+ currentId.value = row.id;
+ fileList.value = [];
+ showUpload.value = true;
+ };
+ const confirmUpload = async () => {
+ try {
+ const payload = { fileList: fileList.value, id: currentId.value };
+ uni.showLoading({
+ title: "鎻愪氦涓�...",
+ });
+ await commitFile(payload);
+ uni.hideLoading();
+ showToast("鎻愪氦鎴愬姛");
+ showUpload.value = false;
+ fileList.value = [];
+ currentId.value = "";
+ getList();
+ } catch (e) {
+ uni.hideLoading();
+ showToast("鎻愪氦澶辫触锛岃閲嶈瘯");
+ }
+ };
-// 涓婁紶鐩稿叧
-const beforeReadPdf = (file) => {
- // 鍏煎澶氭枃浠�
- const files = Array.isArray(file) ? file : [file]
- for (const f of files) {
- const sizeOk = f.size <= 10 * 1024 * 1024
- const ext = (f.name || '').split('.').pop()?.toLowerCase()
- if (ext !== 'pdf') {
- showToast('浠呮敮鎸乸df鏂囦欢')
- return false
- }
- if (!sizeOk) {
- showToast('涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB')
- return false
- }
- }
- return true
-}
+ // 涓婁紶鐩稿叧
+ const beforeReadPdf = file => {
+ // 鍏煎澶氭枃浠�
+ const files = Array.isArray(file) ? file : [file];
+ for (const f of files) {
+ const sizeOk = f.size <= 10 * 1024 * 1024;
+ const ext = (f.name || "").split(".").pop()?.toLowerCase();
+ if (ext !== "pdf") {
+ showToast("浠呮敮鎸乸df鏂囦欢");
+ return false;
+ }
+ if (!sizeOk) {
+ showToast("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
+ return false;
+ }
+ }
+ return true;
+ };
-// uview-plus 鐨勪笂浼犳垚鍔熷洖璋�
-const onUploadSuccess = (res, file) => {
- try {
- const data = JSON.parse(res.data || '{}')
- if (data.code === 200) {
- fileList.value.push(data.data)
- showToast('涓婁紶鎴愬姛')
- } else {
- showToast('涓婁紶澶辫触: ' + (data.msg || '鏈煡閿欒'))
- }
- } catch (err) {
- showToast('涓婁紶澶辫触')
- }
-}
+ // uview-plus 鐨勪笂浼犳垚鍔熷洖璋�
+ const onUploadSuccess = (res, file) => {
+ try {
+ const data = JSON.parse(res.data || "{}");
+ if (data.code === 200) {
+ fileList.value.push(data.data);
+ showToast("涓婁紶鎴愬姛");
+ } else {
+ showToast("涓婁紶澶辫触: " + (data.msg || "鏈煡閿欒"));
+ }
+ } catch (err) {
+ showToast("涓婁紶澶辫触");
+ }
+ };
-// uview-plus 鐨勪笂浼犲け璐ュ洖璋�
-const onUploadError = (err) => {
- showToast('涓婁紶澶辫触')
-}
+ // uview-plus 鐨勪笂浼犲け璐ュ洖璋�
+ const onUploadError = err => {
+ showToast("涓婁紶澶辫触");
+ };
-const removeUploaded = (index) => {
- fileList.value.splice(index, 1)
-}
+ const removeUploaded = index => {
+ fileList.value.splice(index, 1);
+ };
-const getFileNameFromUrl = (url) => {
- try {
- if (!url) return ''
- return decodeURIComponent(url.split('/').pop())
- } catch (e) {
- return url
- }
-}
+ const getFileNameFromUrl = url => {
+ try {
+ if (!url) return "";
+ return decodeURIComponent(url.split("/").pop());
+ } catch (e) {
+ return url;
+ }
+ };
-// 闄勪欢鏌ョ湅
-const openFileActions = (commonFiles) => {
- currentFilesToOpen = commonFiles || []
- fileActions.value = (commonFiles || []).map((f, idx) => ({
- title: getFileNameFromUrl(f.url || ''),
- index: idx
- }))
- showFileSheet.value = true
-}
-const onSelectFile = async (action) => {
- try {
- const item = currentFilesToOpen[action.index]
- if (!item || !item.url) return
- uni.showLoading({
- title: '涓嬭浇涓�...'
- });
- uni.downloadFile({
- url: item.url,
- success: (res) => {
- uni.hideLoading();
- if (res.statusCode === 200) {
- uni.openDocument({ filePath: res.tempFilePath })
- } else {
- showToast('涓嬭浇澶辫触')
- }
- },
- fail: () => {
- uni.hideLoading();
- showToast('涓嬭浇澶辫触')
- }
- })
- } catch (e) {
- uni.hideLoading();
- showToast('鎵撳紑澶辫触')
- }
-}
+ // 闄勪欢鏌ョ湅
+ const openFileActions = commonFiles => {
+ currentFilesToOpen = commonFiles || [];
+ fileActions.value = (commonFiles || []).map((f, idx) => ({
+ title: getFileNameFromUrl(f.url || ""),
+ index: idx,
+ }));
+ showFileSheet.value = true;
+ };
+ const onSelectFile = async action => {
+ try {
+ const item = currentFilesToOpen[action.index];
+ if (!item || !item.url) return;
+ uni.showLoading({
+ title: "涓嬭浇涓�...",
+ });
+ uni.downloadFile({
+ url: item.url,
+ success: res => {
+ uni.hideLoading();
+ if (res.statusCode === 200) {
+ uni.openDocument({ filePath: res.tempFilePath });
+ } else {
+ showToast("涓嬭浇澶辫触");
+ }
+ },
+ fail: () => {
+ uni.hideLoading();
+ showToast("涓嬭浇澶辫触");
+ },
+ });
+ } catch (e) {
+ uni.hideLoading();
+ showToast("鎵撳紑澶辫触");
+ }
+ };
-onShow(() => {
- getList()
-})
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/procurement-common.scss';
+ @import "@/styles/procurement-common.scss";
-// 鏉ョエ鍙拌处鐗规湁鏍峰紡锛堟墍鏈夋牱寮忛兘宸插寘鍚湪鍏叡鏍峰紡涓級
+ // 鏉ョエ鍙拌处鐗规湁鏍峰紡锛堟墍鏈夋牱寮忛兘宸插寘鍚湪鍏叡鏍峰紡涓級
</style>
\ No newline at end of file
diff --git a/src/pages/procurementManagement/procurementLedger/detail.vue b/src/pages/procurementManagement/procurementLedger/detail.vue
index 995cf3d..d7693cc 100644
--- a/src/pages/procurementManagement/procurementLedger/detail.vue
+++ b/src/pages/procurementManagement/procurementLedger/detail.vue
@@ -1,875 +1,1553 @@
<template>
<view class="account-detail">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鍙拌处璇︽儏" @back="goBack" />
-
- <!-- 琛ㄥ崟鍖哄煙 -->
- <up-form @submit="onSubmit" label-width="110" ref="formRef" :rules="rules" :model="form">
- <up-form-item label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber">
- <up-input v-model="form.purchaseContractNumber" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item
- label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- required
- @click="showPicker = true"
- >
- <up-input
- v-model="form.salesContractNo"
- readonly=""
- @click="showPicker = true"
- placeholder="鐐瑰嚮閫夋嫨閿�鍞悎鍚屽彿"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- <up-form-item
- label="渚涘簲鍟嗗悕绉�"
- prop="supplierName"
- required
- @click="showCustomerPicker = true"
- >
- <up-input
- v-model="form.supplierName"
- readonly=""
- @click="showCustomerPicker = true"
- placeholder="鐐瑰嚮閫夋嫨渚涘簲鍟�"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showCustomerPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="椤圭洰鍚嶇О" prop="projectName" required >
- <up-input
- v-model="form.projectName"
- placeholder="璇疯緭鍏ラ」鐩悕绉�"
- />
- </up-form-item>
- <up-form-item label="浠樻鏂瑰紡" prop="paymentMethod" >
- <up-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
- </up-form-item>
- <up-form-item label="褰曞叆浜�" prop="recorderName" >
- <up-input v-model="form.recorderName" placeholder="璇疯緭鍏�" disabled />
- </up-form-item>
- <up-form-item label="褰曞叆鏃ユ湡" prop="entryDate" >
- <up-input v-model="form.entryDate" placeholder="璇疯緭鍏�" disabled />
- </up-form-item>
-
- <!-- 閿�鍞悎鍚屽彿閫夋嫨 -->
- <up-action-sheet
- :show="showPicker"
- :actions="salesContractActionList"
- title="閫夋嫨閿�鍞悎鍚屽彿"
- @select="onSalesmanSelect"
- @close="showPicker = false"
- />
-
- <!-- 渚涘簲鍟嗛�夋嫨 -->
- <up-action-sheet
- :show="showCustomerPicker"
- :actions="supplierActionList"
- title="閫夋嫨渚涘簲鍟�"
- @select="onCustomerSelect"
- @close="showCustomerPicker = false"
- />
-
- <!-- 浜у搧澶х被閫夋嫨鍣� -->
- <up-popup :show="showCategoryPicker" mode="bottom">
- <!-- 澶撮儴鎸夐挳鍖哄煙 -->
- <view class="popup-header">
- <view @click="showCategoryPicker = false" class="cancelButton">鍙栨秷</view>
- <view @click="confirmCategorySelection" class="confirmButton">纭畾</view>
- </view>
- <u-tree
- :data="productOptions"
- :props="defaultProps"
- show-checkbox
- default-expand-all
- check-strictly
- @check-change="onCategoryConfirm"
- />
- </up-popup>
-
- <!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
- <up-action-sheet
- :show="showSpecificationPicker"
- :actions="specificationActionList"
- title="閫夋嫨瑙勬牸鍨嬪彿"
- @select="onSpecificationSelect"
- @close="showSpecificationPicker = false"
- />
-
- <!-- 绋庣巼閫夋嫨鍣� -->
- <up-action-sheet
- :show="showTaxRatePicker"
- :actions="taxRateActionList"
- title="閫夋嫨绋庣巼"
- @select="onTaxRateSelect"
- @close="showTaxRatePicker = false"
- />
-
- <!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
- <up-action-sheet
- :show="showInvoiceTypePicker"
- :actions="invoiceTypeActionList"
- title="閫夋嫨鍙戠エ绫诲瀷"
- @select="onInvoiceTypeSelect"
- @close="showInvoiceTypePicker = false"
- />
- <!-- 浜у搧淇℃伅 -->
- <view class="product-section">
- <view class="section-header">
- <view>
- <text class="section-title">浜у搧淇℃伅</text>
- </view>
- <view>
- <up-button type="primary" size="small" @click="addProduct" class="add-btn" v-if="operationType !== 'view'">
- 鏂板
- </up-button>
- </view>
- </view>
- <view class="product-card" v-for="(product, idx) in productData" :key="idx">
- <!-- 浜у搧绫� -->
- <view class="product-header">
- <view class="product-title">
- <up-icon name="file-text" size="16" color="#2979ff"></up-icon>
- <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
- </view>
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="product-actions" v-if="operationType !== 'view'">
- <up-button type="error" size="mini" @click="removeProduct(idx)" class="del-btn">
- 鍒犻櫎
- </up-button>
- </view>
- </view>
-
- <!-- 浜у搧淇℃伅琛ㄥ崟 -->
- <view class="product-form">
- <!-- 浜у搧澶х被 -->
- <up-form-item
- label="浜у搧澶х被"
- prop="productCategory"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.productCategory"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openCategoryPicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showCategoryPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 瑙勬牸鍨嬪彿 -->
- <up-form-item
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.specificationModel"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openSpecificationPicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showSpecificationPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 鍗曚綅 -->
- <up-form-item
- label="鍗曚綅"
- prop="unit"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.unit"
- placeholder="璇疯緭鍏�"
- />
- </up-form-item>
-
- <!-- 绋庣巼 -->
- <up-form-item
- label="绋庣巼(%)"
- prop="taxRate"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.taxRate"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openTaxRatePicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showTaxRatePicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 鍚◣鍗曚环 -->
- <up-form-item
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.taxInclusiveUnitPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatTaxPrice(idx)"
- />
- </up-form-item>
-
- <!-- 鏁伴噺 -->
- <up-form-item
- label="鏁伴噺"
- prop="quantity"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.quantity"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatAmount(idx)"
- />
- </up-form-item>
-
- <!-- 鍚◣鎬讳环 -->
- <up-form-item
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.taxInclusiveTotalPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatTaxTotal(idx)"
- />
- </up-form-item>
-
- <!-- 涓嶅惈绋庢�讳环 -->
- <up-form-item
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.taxExclusiveTotalPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatNoTaxTotal(idx)"
- />
- </up-form-item>
-
- <!-- 鍙戠エ绫诲瀷 -->
- <up-form-item
- label="鍙戠エ绫诲瀷"
- prop="invoiceType"
- required
- :rules="productRules"
- >
- <up-input
- v-model="product.invoiceType"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openInvoiceTypePicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showInvoiceTypePicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- </view>
- </view>
- </view>
-
- <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
- <FooterButtons
- :show="operationType !== 'view'"
- cancelText="鍙栨秷"
- confirmText="淇濆瓨"
- @cancel="goBack"
- @confirm="onSubmit"
- />
- </up-form>
+ <PageHeader title="鍙拌处璇︽儏"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <up-form @submit="onSubmit"
+ label-width="110"
+ ref="formRef"
+ :rules="rules"
+ :model="form">
+ <up-form-item label="閲囪喘鍚堝悓鍙�"
+ prop="purchaseContractNumber">
+ <up-input v-model="form.purchaseContractNumber"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo"
+ required>
+ <up-input v-model="form.salesContractNo"
+ readonly
+ :disabled="isReadOnly"
+ @click="!isReadOnly && (showPicker = true)"
+ placeholder="鐐瑰嚮閫夋嫨閿�鍞悎鍚屽彿" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="!isReadOnly"
+ @click="showPicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="渚涘簲鍟嗗悕绉�"
+ prop="supplierName"
+ required
+ >
+ <up-input v-model="form.supplierName"
+ readonly
+ :disabled="isReadOnly"
+ @click="!isReadOnly && (showCustomerPicker = true)"
+ placeholder="鐐瑰嚮閫夋嫨渚涘簲鍟�" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="!isReadOnly"
+ @click="showCustomerPicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="椤圭洰鍚嶇О"
+ prop="projectName"
+ required>
+ <up-input v-model="form.projectName"
+ :disabled="isReadOnly"
+ placeholder="璇疯緭鍏ラ」鐩悕绉�" />
+ </up-form-item>
+ <up-form-item label="浠樻鏂瑰紡"
+ prop="paymentMethod">
+ <up-input v-model="form.paymentMethod"
+ :disabled="isReadOnly"
+ placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
+ </up-form-item>
+ <up-form-item label="绛捐鏃ユ湡"
+ required
+ prop="executionDate">
+ <up-input v-model="form.executionDate"
+ placeholder="璇烽�夋嫨"
+ readonly
+ :disabled="isReadOnly" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="!isReadOnly"
+ @click="showTimePicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="褰曞叆浜�"
+ prop="recorderName">
+ <up-input v-model="form.recorderName"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </up-form-item>
+ <up-form-item label="褰曞叆鏃ユ湡"
+ prop="entryDate">
+ <up-input v-model="form.entryDate"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </up-form-item>
+ <view class="approval-process">
+ <view class="approval-header">
+ <text class="approval-title">瀹℃牳娴佺▼</text>
+ <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
+ </view>
+ <view class="approval-steps">
+ <view v-for="(step, stepIndex) in approverNodes"
+ :key="stepIndex"
+ class="approval-step">
+ <view class="step-dot"></view>
+ <view class="step-title">
+ <text>瀹℃壒浜�</text>
+ </view>
+ <view class="approver-container">
+ <view v-if="step.nickName"
+ class="approver-item">
+ <view class="approver-avatar">
+ <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
+ <view class="status-dot"></view>
+ </view>
+ <view class="approver-info">
+ <text class="approver-name">{{ step.nickName }}</text>
+ </view>
+ <view class="delete-approver-btn"
+ v-if="!isReadOnly"
+ @click="removeApprover(stepIndex)">脳</view>
+ </view>
+ <view v-else-if="!isReadOnly"
+ class="add-approver-btn"
+ @click="addApprover(stepIndex)">
+ <view class="add-circle">+</view>
+ <text class="add-label">閫夋嫨瀹℃壒浜�</text>
+ </view>
+ </view>
+ <view class="step-line"
+ v-if="stepIndex < approverNodes.length - 1"></view>
+ <view class="delete-step-btn"
+ v-if="approverNodes.length > 1 && !isReadOnly"
+ @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
+ </view>
+ </view>
+ <view class="add-step-btn" v-if="!isReadOnly">
+ <u-button icon="plus"
+ plain
+ type="primary"
+ style="width: 100%"
+ @click="addApprovalStep">鏂板鑺傜偣</u-button>
+ </view>
+ </view>
+ <up-popup :show="showTimePicker"
+ mode="bottom"
+ @close="showTimePicker = false">
+ <up-datetime-picker :show="true"
+ v-model="currentDate"
+ @confirm="onDateConfirm"
+ @cancel="showTimePicker = false"
+ mode="date" />
+ </up-popup>
+ <!-- 閿�鍞悎鍚屽彿閫夋嫨 -->
+ <up-action-sheet :show="showPicker"
+ :actions="salesContractActionList"
+ title="閫夋嫨閿�鍞悎鍚屽彿"
+ @select="onSalesmanSelect"
+ @close="showPicker = false" />
+ <!-- 渚涘簲鍟嗛�夋嫨 -->
+ <up-action-sheet :show="showCustomerPicker"
+ :actions="supplierActionList"
+ title="閫夋嫨渚涘簲鍟�"
+ @select="onCustomerSelect"
+ @close="showCustomerPicker = false" />
+ <!-- 浜у搧澶х被閫夋嫨鍣� -->
+ <up-popup :show="showCategoryPicker"
+ mode="bottom">
+ <!-- 澶撮儴鎸夐挳鍖哄煙 -->
+ <view class="popup-header">
+ <view @click="showCategoryPicker = false"
+ class="cancelButton">鍙栨秷</view>
+ <view @click="confirmCategorySelection"
+ class="confirmButton">纭畾</view>
+ </view>
+ <u-tree :data="productOptions"
+ :props="defaultProps"
+ show-checkbox
+ default-expand-all
+ check-strictly
+ @check-change="onCategoryConfirm" />
+ </up-popup>
+ <!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
+ <up-action-sheet :show="showSpecificationPicker"
+ :actions="specificationActionList"
+ title="閫夋嫨瑙勬牸鍨嬪彿"
+ @select="onSpecificationSelect"
+ @close="showSpecificationPicker = false" />
+ <!-- 绋庣巼閫夋嫨鍣� -->
+ <up-action-sheet :show="showTaxRatePicker"
+ :actions="taxRateActionList"
+ title="閫夋嫨绋庣巼"
+ @select="onTaxRateSelect"
+ @close="showTaxRatePicker = false" />
+ <!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
+ <up-action-sheet :show="showInvoiceTypePicker"
+ :actions="invoiceTypeActionList"
+ title="閫夋嫨鍙戠エ绫诲瀷"
+ @select="onInvoiceTypeSelect"
+ @close="showInvoiceTypePicker = false" />
+ <!-- 浜у搧淇℃伅 -->
+ <view class="product-section">
+ <view class="section-header">
+ <view>
+ <text class="section-title">浜у搧淇℃伅</text>
+ </view>
+ <view>
+ <up-button type="primary"
+ size="small"
+ @click="addProduct"
+ class="add-btn"
+ v-if="canEditProducts">
+ 鏂板
+ </up-button>
+ </view>
+ </view>
+ <view class="product-card"
+ v-for="(product, idx) in productData"
+ :key="idx">
+ <!-- 浜у搧绫� -->
+ <view class="product-header">
+ <view class="product-title">
+ <up-icon name="file-text"
+ size="16"
+ color="#2979ff"></up-icon>
+ <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="product-actions"
+ v-if="canEditProducts">
+ <up-button type="error"
+ size="mini"
+ @click="removeProduct(idx)"
+ class="del-btn">
+ 鍒犻櫎
+ </up-button>
+ </view>
+ </view>
+ <!-- 浜у搧淇℃伅琛ㄥ崟 -->
+ <view class="product-form">
+ <!-- 浜у搧澶х被 -->
+ <up-form-item label="浜у搧澶х被"
+ prop="productCategory"
+ required
+ :rules="productRules">
+ <up-input v-model="product.productCategory"
+ readonly
+ placeholder="璇烽�夋嫨"
+ :disabled="!canEditProducts"
+ @click="openCategoryPicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="canEditProducts"
+ @click="openCategoryPicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 瑙勬牸鍨嬪彿 -->
+ <up-form-item label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ required
+ :rules="productRules">
+ <up-input v-model="product.specificationModel"
+ readonly
+ placeholder="璇烽�夋嫨"
+ :disabled="!canEditProducts"
+ @click="openSpecificationPicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="canEditProducts"
+ @click="openSpecificationPicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 鍗曚綅 -->
+ <up-form-item label="鍗曚綅"
+ prop="unit"
+ required
+ :rules="productRules">
+ <up-input v-model="product.unit"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�" />
+ </up-form-item>
+ <!-- 绋庣巼 -->
+ <up-form-item label="绋庣巼(%)"
+ prop="taxRate"
+ required
+ :rules="productRules">
+ <up-input v-model="product.taxRate"
+ readonly
+ placeholder="璇烽�夋嫨"
+ :disabled="!canEditProducts"
+ @click="openTaxRatePicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="canEditProducts"
+ @click="openTaxRatePicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 鍚◣鍗曚环 -->
+ <up-form-item label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ required
+ :rules="productRules">
+ <up-input v-model="product.taxInclusiveUnitPrice"
+ type="number"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxPrice(idx)" />
+ </up-form-item>
+ <!-- 鏁伴噺 -->
+ <up-form-item label="鏁伴噺"
+ prop="quantity"
+ required
+ :rules="productRules">
+ <up-input v-model="product.quantity"
+ type="number"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�"
+ @blur="formatAmount(idx)" />
+ </up-form-item>
+ <!-- 鍚◣鎬讳环 -->
+ <up-form-item label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ required
+ :rules="productRules">
+ <up-input v-model="product.taxInclusiveTotalPrice"
+ type="number"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxTotal(idx)" />
+ </up-form-item>
+ <!-- 涓嶅惈绋庢�讳环 -->
+ <up-form-item label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ required
+ :rules="productRules">
+ <up-input v-model="product.taxExclusiveTotalPrice"
+ type="number"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�"
+ @blur="formatNoTaxTotal(idx)" />
+ </up-form-item>
+ <!-- 鍙戠エ绫诲瀷 -->
+ <up-form-item label="鍙戠エ绫诲瀷"
+ prop="invoiceType"
+ required
+ :rules="productRules">
+ <up-input v-model="product.invoiceType"
+ readonly
+ placeholder="璇烽�夋嫨"
+ :disabled="!canEditProducts"
+ @click="openInvoiceTypePicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ v-if="canEditProducts"
+ @click="openInvoiceTypePicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 搴撳瓨棰勮鏁伴噺 -->
+ <up-form-item label="搴撳瓨棰勮鏁伴噺"
+ prop="warnNum"
+ required
+ :rules="productRules">
+ <up-input v-model="product.warnNum"
+ type="number"
+ :disabled="!canEditProducts"
+ placeholder="璇疯緭鍏�" />
+ </up-form-item>
+ <up-form-item label="鏄惁璐ㄦ"
+ prop="invoiceType"
+ required
+ :rules="productRules">
+ <u-radio-group v-model="product.isChecked"
+ :disabled="!canEditProducts"
+ placement="row"
+ @change="groupChange">
+ <u-radio :customStyle="{marginRight: '40rpx'}"
+ label="鏄�"
+ :disabled="!canEditProducts"
+ :name="true">
+ </u-radio>
+ <u-radio label="鍚�"
+ :disabled="!canEditProducts"
+ :name="false">
+ </u-radio>
+ </u-radio-group>
+ </up-form-item>
+ </view>
+ </view>
+ </view>
+ <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
+ <FooterButtons :show="operationType !== 'view' && !isApprovalPassed"
+ cancelText="鍙栨秷"
+ confirmText="淇濆瓨"
+ @cancel="goBack"
+ @confirm="onSubmit" />
+ </up-form>
</view>
</template>
<script setup>
-import {onMounted, ref, computed} from 'vue';
-import { modelList, productTreeList } from "@/api/basicData/product.js";
-import useUserStore from "@/store/modules/user";
-import {calculateTaxExclusiveTotalPrice} from "@/utils/summarizeTable";
-import {formatDateToYMD} from '@/utils/ruoyi'
-import {
- addOrEditPurchase, createPurchaseNo,
- getOptions,
- getPurchaseById,
- getSalesNo
-} from "@/api/procurementManagement/procurementLedger";
-import PageHeader from '@/components/PageHeader.vue';
-import FooterButtons from '@/components/FooterButtons.vue';
-
-// 鑾峰彇椤甸潰鍙傛暟
-const operationType = ref('');
-const editData = ref(null);
-const formRef = ref(null);
-
-const userStore = useUserStore()
-const form = ref({
- id: '',
- salesContractNo: '',
- purchaseContractNumber: '',
- supplierId: '',
- supplierName: '',
- projectName: '',
- paymentMethod: '',
- recorderId: '',
- recorderName: '',
- entryDate: '',
-});
-const showPicker = ref(false);
-const showCustomerPicker = ref(false);
-const salesContractList = ref([]);
-const supplierList = ref([]);
-const productData = ref([]);
-
-// 璁$畻閿�鍞悎鍚屽彿閫夋嫨鍒楄〃
-const salesContractActionList = computed(() => {
- return salesContractList.value.map(item => ({
- name: item.text,
- value: item.value
- }))
-})
-
-// 璁$畻渚涘簲鍟嗛�夋嫨鍒楄〃
-const supplierActionList = computed(() => {
- return supplierList.value.map(item => ({
- name: item.text,
- value: item.value
- }))
-})
-
-// 閫夋嫨鍣ㄧ浉鍏冲彉閲�
-const showCategoryPicker = ref(false);
-const showSpecificationPicker = ref(false);
-const showTaxRatePicker = ref(false);
-const showInvoiceTypePicker = ref(false);
-const currentProductIndex = ref(0);
-
-// 閫夐」鏁版嵁
-const productOptions = ref([]);
-const selectedCategoryNode = ref(null);
-const defaultProps = ref({
- children: 'children',
- label: 'label',
- nodeKey: 'id'
-});
-
-const modelOptions = ref([]);
-const taxRateOptions = ref([
- { text: '1', value: '1' },
- { text: '6', value: '6' },
- { text: '13', value: '13' },
-]);
-
-const invoiceTypeOptions = ref([
- { text: '澧炴櫘绁�', value: '澧炴櫘绁�' },
- { text: '澧炰笓绁�', value: '澧炰笓绁�' },
-]);
-
-// 璁$畻瑙勬牸鍨嬪彿閫夋嫨鍒楄〃
-const specificationActionList = computed(() => {
- return modelOptions.value.map(model => ({
- name: model.text,
- value: model.value,
- unit: model.unit
- }))
-})
-
-// 璁$畻绋庣巼閫夋嫨鍒楄〃
-const taxRateActionList = computed(() => {
- return taxRateOptions.value.map(rate => ({
- name: rate.text,
- value: rate.value
- }))
-})
-
-// 璁$畻鍙戠エ绫诲瀷閫夋嫨鍒楄〃
-const invoiceTypeActionList = computed(() => {
- return invoiceTypeOptions.value.map(type => ({
- name: type.text,
- value: type.value
- }))
-})
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- salesContractNo: [
- { required: true, message: '璇烽�夋嫨閿�鍞悎鍚屽彿', trigger: 'blur' }
- ],
- supplierName: [
- { required: true, message: '璇烽�夋嫨渚涘簲鍟嗗悕绉�', trigger: 'blur' }
- ],
- projectName: [
- { required: true, message: '璇疯緭鍏ラ」鐩悕绉�', trigger: 'blur' }
- ]
-};
-
-// 浜у搧淇℃伅鏍¢獙瑙勫垯
-const productRules = {
- productCategory: [
- { required: true, message: '璇烽�夋嫨浜у搧澶х被', trigger: 'blur' }
- ],
- specificationModel: [
- { required: true, message: '璇烽�夋嫨瑙勬牸鍨嬪彿', trigger: 'blur' }
- ],
- unit: [
- { required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }
- ],
- taxRate: [
- { required: true, message: '璇烽�夋嫨绋庣巼', trigger: 'blur' }
- ],
- taxInclusiveUnitPrice: [
- { required: true, message: '璇疯緭鍏ュ惈绋庡崟浠�', trigger: 'blur' },
- { type: 'number', min: 0, message: '鍚◣鍗曚环蹇呴』澶т簬0', trigger: 'blur' }
- ],
- quantity: [
- { required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' },
- { type: 'number', min: 0, message: '鏁伴噺蹇呴』澶т簬0', trigger: 'blur' }
- ],
- taxInclusiveTotalPrice: [
- { required: true, message: '璇疯緭鍏ュ惈绋庢�讳环', trigger: 'blur' },
- { type: 'number', min: 0, message: '鍚◣鎬讳环蹇呴』澶т簬0', trigger: 'blur' }
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: '璇疯緭鍏ヤ笉鍚◣鎬讳环', trigger: 'blur' },
- { type: 'number', min: 0, message: '涓嶅惈绋庢�讳环蹇呴』澶т簬0', trigger: 'blur' }
- ],
- invoiceType: [
- { required: true, message: '璇烽�夋嫨鍙戠エ绫诲瀷', trigger: 'blur' }
- ]
-};
-
-const addProduct = () => {
- if (productData.value === null) {
- productData.value = []
- }
- productData.value.push({
- productCategory: '',
- specificationModel: '',
- productModelId: '',
- unit: '',
- taxRate: '',
- taxInclusiveUnitPrice: '',
- quantity: '',
- taxInclusiveTotalPrice: '',
- taxExclusiveTotalPrice: '',
- invoiceType: ''
+ import { onMounted, ref, computed } from "vue";
+ import { modelList, productTreeList } from "@/api/basicData/product.js";
+ import useUserStore from "@/store/modules/user";
+ import { calculateTaxExclusiveTotalPrice } from "@/utils/summarizeTable";
+ import { formatDateToYMD } from "@/utils/ruoyi";
+ import {
+ addOrEditPurchase,
+ createPurchaseNo,
+ getOptions,
+ getPurchaseById,
+ getSalesNo,
+ approveProcessGetInfo,
+ } from "@/api/procurementManagement/procurementLedger";
+ import { delProduct } from "@/api/salesManagement/salesLedger";
+ import PageHeader from "@/components/PageHeader.vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
+ import { userListNoPageByTenantId } from "@/api/system/user";
+ // 鑾峰彇椤甸潰鍙傛暟
+ const operationType = ref("");
+ const editData = ref(null);
+ const formRef = ref(null);
+ // 瀹℃壒閫氳繃锛坅pprovalStatus === 3锛夊悗锛屾暣鍗曠姝㈢紪杈戯紙鍚骇鍝併�佸熀鏈俊鎭�佸鎵规祦绋嬶級
+ const isApprovalPassed = computed(() => {
+ const status = editData.value?.approvalStatus ?? form.value?.approvalStatus;
+ return Number(status) === 3;
});
-};
+ const canEditProducts = computed(() => {
+ return operationType.value !== "view" && !isApprovalPassed.value;
+ });
+ // 鏄惁鏁翠綋鍙锛氭煡鐪嬫ā寮� 鎴� 宸插鎵归�氳繃
+ const isReadOnly = computed(() => {
+ return operationType.value === "view" || isApprovalPassed.value;
+ });
-// 閿�鍞悎鍚屽彿閫夋嫨浜嬩欢
-const onSalesmanSelect = (item) => {
- form.value.salesContractNo = item.name
- // 鏌ユ壘瀵瑰簲鐨刬d
- const selectedItem = salesContractList.value.find(contract => contract.text === item.name);
- if (selectedItem) {
- form.value.salesLedgerId = selectedItem.value;
- }
- showPicker.value = false;
-}
+ const userStore = useUserStore();
+ const form = ref({
+ id: "",
+ salesContractNo: "",
+ // 鍏宠仈閿�鍞彴璐D锛堢紪杈戝洖鏄炬椂鍙兘缂哄け锛岄渶瑕佷粠鍚堝悓鍙峰弽鏌ヨˉ榻愶級
+ salesLedgerId: "",
+ purchaseContractNumber: "",
+ supplierId: "",
+ supplierName: "",
+ projectName: "",
+ paymentMethod: "",
+ recorderId: "",
+ recorderName: "",
+ entryDate: "",
+ approveUserIds: "",
+ executionDate: "",
+ });
+ const showTimePicker = ref(false);
+ const showPicker = ref(false);
+ const showCustomerPicker = ref(false);
+ const salesContractList = ref([]);
+ const supplierList = ref([]);
+ const productData = ref([]);
+ const currentDate = ref(Date.now());
+ // 璁$畻閿�鍞悎鍚屽彿閫夋嫨鍒楄〃
+ const salesContractActionList = computed(() => {
+ return salesContractList.value.map(item => ({
+ name: item.text,
+ value: item.value,
+ }));
+ });
-// 渚涘簲鍟嗛�夋嫨浜嬩欢
-const onCustomerSelect = (item) => {
- form.value.supplierName = item.name
- // 鏌ユ壘瀵瑰簲鐨刬d
- const selectedItem = supplierList.value.find(supplier => supplier.text === item.name);
- if (selectedItem) {
- form.value.supplierId = selectedItem.value;
- }
- showCustomerPicker.value = false;
-}
+ // 璁$畻渚涘簲鍟嗛�夋嫨鍒楄〃锛堝彧淇濈暀 isWhite === 0 鐨勪緵搴斿晢锛�
+ const supplierActionList = computed(() => {
+ return supplierList.value
+ .filter(item => item.isWhite === 0)
+ .map(item => ({
+ name: item.text,
+ value: item.value,
+ }));
+ });
-const removeProduct = (idx) => {
- productData.value.splice(idx, 1);
-};
+ // 閫夋嫨鍣ㄧ浉鍏冲彉閲�
+ const showCategoryPicker = ref(false);
+ const showSpecificationPicker = ref(false);
+ const showTaxRatePicker = ref(false);
+ const showInvoiceTypePicker = ref(false);
+ const currentProductIndex = ref(0);
-// 鏄剧ず閫夋嫨鍣�
-const openCategoryPicker = (idx) => {
- currentProductIndex.value = idx;
- showCategoryPicker.value = true;
-};
+ // 閫夐」鏁版嵁
+ const productOptions = ref([]);
+ const selectedCategoryNode = ref(null);
+ const defaultProps = ref({
+ children: "children",
+ label: "label",
+ nodeKey: "id",
+ });
-const openSpecificationPicker = (idx) => {
- currentProductIndex.value = idx;
- showSpecificationPicker.value = true;
-};
+ const modelOptions = ref([]);
+ const taxRateOptions = ref([
+ { text: "1", value: "1" },
+ { text: "6", value: "6" },
+ { text: "13", value: "13" },
+ ]);
-const openTaxRatePicker = (idx) => {
- currentProductIndex.value = idx;
- showTaxRatePicker.value = true;
-};
+ const invoiceTypeOptions = ref([
+ { text: "澧炴櫘绁�", value: "澧炴櫘绁�" },
+ { text: "澧炰笓绁�", value: "澧炰笓绁�" },
+ ]);
-const openInvoiceTypePicker = (idx) => {
- currentProductIndex.value = idx;
- showInvoiceTypePicker.value = true;
-};
+ // 璁$畻瑙勬牸鍨嬪彿閫夋嫨鍒楄〃
+ const specificationActionList = computed(() => {
+ return modelOptions.value.map(model => ({
+ name: model.text,
+ value: model.value,
+ unit: model.unit,
+ }));
+ });
-// 閫夋嫨鍣ㄧ‘璁や簨浠�
-const onCategoryConfirm = (node) => {
- // 鑾峰彇閫変腑鐨勮妭鐐逛俊鎭�
- console.log('selected node---', node);
- // 瀛樺偍閫変腑鐨勮妭鐐癸紝鐢ㄤ簬纭鏃惰幏鍙栨暟鎹�
- selectedCategoryNode.value = node;
-};
+ // 璁$畻绋庣巼閫夋嫨鍒楄〃
+ const taxRateActionList = computed(() => {
+ return taxRateOptions.value.map(rate => ({
+ name: rate.text,
+ value: rate.value,
+ }));
+ });
-// 纭浜у搧澶х被閫夋嫨
-const confirmCategorySelection = () => {
- if (selectedCategoryNode.value) {
- // 璁剧疆閫変腑鐨勪骇鍝佸ぇ绫�
- productData.value[currentProductIndex.value].productCategory = selectedCategoryNode.value.label;
- const id = selectedCategoryNode.value.id
- // 閲嶇疆閫変腑鐨勮妭鐐�
- selectedCategoryNode.value = null;
- productData.value[currentProductIndex.value].specificationModel = ''
- productData.value[currentProductIndex.value].productModelId = ''
- getModels(id)
- }
- showCategoryPicker.value = false;
-};
+ // 璁$畻鍙戠エ绫诲瀷閫夋嫨鍒楄〃
+ const invoiceTypeActionList = computed(() => {
+ return invoiceTypeOptions.value.map(type => ({
+ name: type.text,
+ value: type.value,
+ }));
+ });
-// 鑾峰彇瑙勬牸鍨嬪彿
-const getModels = (value) => {
- modelList({ id: value }).then((res) => {
- modelOptions.value = res.map(user => ({
- text: user.model,
- value: user.id,
- unit: user.unit,
- }));
- });
-};
+ // 琛ㄥ崟鏍¢獙瑙勫垯
+ const rules = {
+ salesContractNo: [
+ { required: true, message: "璇烽�夋嫨閿�鍞悎鍚屽彿", trigger: "blur" },
+ ],
+ supplierName: [
+ { required: true, message: "璇烽�夋嫨渚涘簲鍟嗗悕绉�", trigger: "blur" },
+ ],
+ projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+ executionDate: [
+ { required: true, message: "璇烽�夋嫨绛捐鏃ユ湡", trigger: "blur" },
+ ],
+ };
-// 瑙勬牸鍨嬪彿閫夋嫨浜嬩欢
-const onSpecificationSelect = (item) => {
- productData.value[currentProductIndex.value].specificationModel = item.name
- productData.value[currentProductIndex.value].productModelId = item.value
- productData.value[currentProductIndex.value].unit = item.unit
- showSpecificationPicker.value = false;
-};
+ // 浜у搧淇℃伅鏍¢獙瑙勫垯
+ const productRules = {
+ productCategory: [
+ { required: true, message: "璇烽�夋嫨浜у搧澶х被", trigger: "blur" },
+ ],
+ specificationModel: [
+ { required: true, message: "璇烽�夋嫨瑙勬牸鍨嬪彿", trigger: "blur" },
+ ],
+ unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+ taxRate: [{ required: true, message: "璇烽�夋嫨绋庣巼", trigger: "blur" }],
+ taxInclusiveUnitPrice: [
+ { required: true, message: "璇疯緭鍏ュ惈绋庡崟浠�", trigger: "blur" },
+ { type: "number", min: 0, message: "鍚◣鍗曚环蹇呴』澶т簬0", trigger: "blur" },
+ ],
+ quantity: [
+ { required: true, message: "璇疯緭鍏ユ暟閲�", trigger: "blur" },
+ { type: "number", min: 0, message: "鏁伴噺蹇呴』澶т簬0", trigger: "blur" },
+ ],
+ taxInclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏ュ惈绋庢�讳环", trigger: "blur" },
+ { type: "number", min: 0, message: "鍚◣鎬讳环蹇呴』澶т簬0", trigger: "blur" },
+ ],
+ taxExclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏ヤ笉鍚◣鎬讳环", trigger: "blur" },
+ { type: "number", min: 0, message: "涓嶅惈绋庢�讳环蹇呴』澶т簬0", trigger: "blur" },
+ ],
+ invoiceType: [{ required: true, message: "璇烽�夋嫨鍙戠エ绫诲瀷", trigger: "blur" }],
-// 绋庣巼閫夋嫨浜嬩欢
-const onTaxRateSelect = (item) => {
- productData.value[currentProductIndex.value].taxRate = item.value
- showTaxRatePicker.value = false;
- // 閲嶆柊璁$畻涓嶅惈绋庢�讳环
- const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice)
- const taxRate = parseFloat(item.value)
- if (inclusiveTotalPrice && taxRate) {
- productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate)
- }
-};
+ warnNum: [
+ { required: true, message: "璇疯緭鍏ュ簱瀛橀璀︽暟閲�", trigger: "blur" },
+ {
+ type: "number",
+ min: 0,
+ message: "搴撳瓨棰勮鏁伴噺蹇呴』澶т簬0",
+ trigger: "blur",
+ },
+ ],
+ };
-// 鍙戠エ绫诲瀷閫夋嫨浜嬩欢
-const onInvoiceTypeSelect = (item) => {
- productData.value[currentProductIndex.value].invoiceType = item.name
- showInvoiceTypePicker.value = false;
-};
-
-// 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
-const formatTaxPrice = (idx) => {
- if (productData.value[idx].taxInclusiveUnitPrice) {
- const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
+ const addProduct = () => {
+ if (!canEditProducts.value) return;
+ if (productData.value === null) {
+ productData.value = [];
}
- }
- if (!productData.value[currentProductIndex.value].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
- const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
- // 璁$畻鍚◣鎬讳环
- productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[currentProductIndex.value].taxRate) {
- productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
- productData.value[currentProductIndex.value].taxRate
- );
- }
-};
+ productData.value.push({
+ productCategory: "",
+ specificationModel: "",
+ productModelId: "",
+ unit: "",
+ taxRate: "",
+ taxInclusiveUnitPrice: "",
+ quantity: "",
+ taxInclusiveTotalPrice: "",
+ taxExclusiveTotalPrice: "",
+ invoiceType: "",
+ isChecked: false,
+ warnNum: "",
+ });
+ };
-// 鏁伴噺杈撳叆妗嗗け鐒�
-const formatAmount = (idx) => {
- if (productData.value[idx].quantity) {
- const value = parseFloat(productData.value[idx].quantity);
- if (!isNaN(value)) {
- productData.value[idx].quantity = value.toFixed(2);
+ // 閿�鍞悎鍚屽彿閫夋嫨浜嬩欢
+ const onSalesmanSelect = item => {
+ form.value.salesContractNo = item.name;
+ // 鏌ユ壘瀵瑰簲鐨刬d
+ const selectedItem = salesContractList.value.find(
+ contract => contract.text === item.name
+ );
+ if (selectedItem) {
+ form.value.salesLedgerId = selectedItem.value;
}
- }
- if (!productData.value[currentProductIndex.value].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
- const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
- // 璁$畻鍚◣鎬讳环
- productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[currentProductIndex.value].taxRate) {
- productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
- productData.value[currentProductIndex.value].taxRate
- );
- }
-};
+ showPicker.value = false;
+ };
-// 鍚◣鎬讳环澶辩劍锛屾牴鎹惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const formatTaxTotal = (idx) => {
- if (productData.value[idx].taxInclusiveTotalPrice) {
- const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
+ // 缂栬緫鍥炴樉鍦烘櫙锛氬彧鏈� salesContractNo锛屾病鏈� salesLedgerId 鏃讹紝灏濊瘯浠庡垪琛ㄥ弽鏌ヨˉ榻�
+ const syncSalesLedgerIdFromContractNo = () => {
+ if (form.value.salesLedgerId) return;
+ if (!form.value.salesContractNo) return;
+ const selectedItem = salesContractList.value.find(
+ contract => contract.text === form.value.salesContractNo
+ );
+ if (selectedItem) {
+ form.value.salesLedgerId = selectedItem.value;
}
- }
- const totalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice);
- const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
-
- if (!totalPrice || !quantity || quantity <= 0) {
- return;
- }
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[currentProductIndex.value].taxRate) {
- productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- totalPrice,
- productData.value[currentProductIndex.value].taxRate
- );
- }
-};
+ };
-// 涓嶅惈绋庢�讳环澶辩劍, 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const formatNoTaxTotal = (idx) => {
- if (productData.value[idx].taxExclusiveTotalPrice) {
- const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
+ // 渚涘簲鍟嗛�夋嫨浜嬩欢
+ const onCustomerSelect = item => {
+ form.value.supplierName = item.name;
+ // 鏌ユ壘瀵瑰簲鐨刬d
+ const selectedItem = supplierList.value.find(
+ supplier => supplier.text === item.name
+ );
+ if (selectedItem) {
+ form.value.supplierId = selectedItem.value;
}
- }
- if (!productData.value[currentProductIndex.value].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const exclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxExclusiveTotalPrice);
- const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
- const taxRate = parseFloat(productData.value[currentProductIndex.value].taxRate);
- if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
- return;
- }
- // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
- const taxRateDecimal = taxRate / 100;
- const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
- productData.value[currentProductIndex.value].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
-};
+ showCustomerPicker.value = false;
+ };
-const goBack = () => {
- // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
- uni.removeStorageSync('operationType');
- uni.removeStorageSync('editData');
- uni.navigateBack();
-};
+ const removeProduct = idx => {
+ if (!canEditProducts.value) return;
+ const row = productData.value[idx];
-const onSubmit = () => {
- if (productData.value !== null && productData.value.length > 0) {
- form.value.productData = JSON.parse(JSON.stringify(productData.value));
- } else {
- uni.showToast({
- title: '璇锋坊鍔犱骇鍝佷俊鎭�',
- icon: 'none'
- });
- return
- }
- form.value.type = 2;
- addOrEditPurchase(form.value).then((res) => {
- uni.showToast({
- title: '鎻愪氦鎴愬姛',
- icon: 'success',
- });
- goBack();
- });
-};
+ // 鏂板妯″紡鎴栬繕鏈惤搴撶殑浜у搧锛岀洿鎺ュ墠绔垹闄�
+ if (operationType.value === "add" || !row?.id) {
+ productData.value.splice(idx, 1);
+ return;
+ }
-const setUserInfo = () => {
- form.value.recorderId = userStore.id;
- form.value.recorderName = userStore.nickName;
- // 璁剧疆褰撳ぉ鏃ユ湡
- 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')
- form.value.entryDate = `${year}-${month}-${day}`
-};
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "閫変腑鐨勪骇鍝佸皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
+ confirmText: "纭",
+ cancelText: "鍙栨秷",
+ success: res => {
+ if (!res.confirm) {
+ uni.showToast({
+ title: "宸插彇娑�",
+ icon: "none",
+ });
+ return;
+ }
+ const ids = [row.id];
+ delProduct(ids).then(() => {
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ const currentId = form.value.id || editData.value?.id;
+ if (currentId) {
+ getPurchaseById({ id: currentId, type: 2 }).then(res2 => {
+ productData.value = res2.productData || [];
+ });
+ } else {
+ // 鍥為��澶勭悊锛氬鏋滄病鏈夊綋鍓岻D锛屽垯鏈湴鍒犻櫎
+ productData.value.splice(idx, 1);
+ }
+ });
+ },
+ });
+ };
-// 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
-const fillFormData = () => {
- if (!editData.value) return;
- getPurchaseById({ id: editData.value.id, type: 2 }).then((res) => {
- productData.value = res.productData;
- });
- console.log(editData.value)
- // 濉厖鍩烘湰淇℃伅
- form.value.salesContractNo = editData.value.salesContractNo || '';
- form.value.supplierName = editData.value.supplierName || '';
- form.value.projectName = editData.value.projectName || '';
- form.value.paymentMethod = editData.value.paymentMethod || '';
- form.value.salesLedgerId = editData.value.salesLedgerId || '';
- form.value.recorderId = editData.value.recorderId || '';
- form.value.recorderName = editData.value.recorderName || '';
- form.value.entryDate = editData.value.entryDate || '';
- form.value.id = editData.value.id || '';
- form.value.supplierId = editData.value.supplierId || '';
-};
+ // 鏄剧ず閫夋嫨鍣�
+ const openCategoryPicker = idx => {
+ if (!canEditProducts.value) return;
+ currentProductIndex.value = idx;
+ showCategoryPicker.value = true;
+ };
-const getSalesNoList = () => {
- getSalesNo().then((res) => {
- // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
- salesContractList.value = res.map(user => ({
- text: user.salesContractNo,
- value: user.id
- }));
- })
-};
+ const openSpecificationPicker = idx => {
+ if (!canEditProducts.value) return;
+ currentProductIndex.value = idx;
+ showSpecificationPicker.value = true;
+ };
-const getOptionsLIst = () => {
- getOptions().then((res) => {
- // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
- supplierList.value = res.data.map(item => ({
- text: item.supplierName,
- value: item.id
- }));
- })
-};
+ const openTaxRatePicker = idx => {
+ if (!canEditProducts.value) return;
+ currentProductIndex.value = idx;
+ showTaxRatePicker.value = true;
+ };
-const convertIdToValue = (data) => {
- // 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
- if (!Array.isArray(data)) {
- return [];
- }
- // 閫掑綊鏄犲皠鍑芥暟
- return data.map(item => {
- // 鍒涘缓鏂板璞★紝鏄犲皠瀛楁
- const mappedItem = {
- label: item.label, // 鍏抽敭锛氬皢 label 鏄犲皠涓� text
- id: item.id, // 淇濈暀 id
- };
- // 濡傛灉瀛樺湪 children 鏁扮粍锛屽垯閫掑綊澶勭悊
- if (item.children && Array.isArray(item.children) && item.children.length > 0) {
- mappedItem.children = convertIdToValue(item.children);
- }
- return mappedItem;
- });
-};
+ const openInvoiceTypePicker = idx => {
+ if (!canEditProducts.value) return;
+ currentProductIndex.value = idx;
+ showInvoiceTypePicker.value = true;
+ };
-// 鑾峰彇浜у搧澶х被tree鏁版嵁
-const getProductOptions = () => {
- productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- });
-};
+ // 閫夋嫨鍣ㄧ‘璁や簨浠�
+ const onCategoryConfirm = node => {
+ // 鑾峰彇閫変腑鐨勮妭鐐逛俊鎭�
+ console.log("selected node---", node);
+ // 瀛樺偍閫変腑鐨勮妭鐐癸紝鐢ㄤ簬纭鏃惰幏鍙栨暟鎹�
+ selectedCategoryNode.value = node;
+ };
-onMounted(() => {
- // 鑾峰彇椤甸潰鍙傛暟
- operationType.value = uni.getStorageSync('operationType') || '';
-
- // 鑾峰彇閿�鍞悎鍚屽彿鍒楄〃
- getSalesNoList()
- // 鑾峰彇渚涘簲鍟嗗垪琛�
- getOptionsLIst()
- // 鑾峰彇浜у搧澶х被tree鏁版嵁
- getProductOptions()
- // 璧嬪�奸粯璁や俊鎭�
- if (operationType.value === 'add') {
- setUserInfo()
- createPurchaseNo().then((res) => {
- form.value.purchaseContractNumber = res.data;
- });
- }
-
- // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
- const editDataStr = uni.getStorageSync('editData');
- if (editDataStr) {
- try {
- editData.value = JSON.parse(editDataStr);
- // 濡傛灉鏄紪杈戞ā寮忥紝绛夊緟鏁版嵁鍔犺浇瀹屾垚鍚庡~鍏呰〃鍗曟暟鎹�
- if (operationType.value !== 'add' && editData.value) {
- // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
- setTimeout(() => {
- fillFormData();
- }, 100);
- }
- } catch (error) {
- console.error('瑙f瀽缂栬緫鏁版嵁澶辫触:', error);
- }
- }
-});
+ // 纭浜у搧澶х被閫夋嫨
+ const confirmCategorySelection = () => {
+ if (selectedCategoryNode.value) {
+ // 璁剧疆閫変腑鐨勪骇鍝佸ぇ绫�
+ productData.value[currentProductIndex.value].productCategory =
+ selectedCategoryNode.value.label;
+ const id = selectedCategoryNode.value.id;
+ // 閲嶇疆閫変腑鐨勮妭鐐�
+ selectedCategoryNode.value = null;
+ productData.value[currentProductIndex.value].specificationModel = "";
+ productData.value[currentProductIndex.value].productModelId = "";
+ getModels(id);
+ }
+ showCategoryPicker.value = false;
+ };
+
+ // 鑾峰彇瑙勬牸鍨嬪彿
+ const getModels = value => {
+ modelList({ id: value }).then(res => {
+ modelOptions.value = res.map(user => ({
+ text: user.model,
+ value: user.id,
+ unit: user.unit,
+ }));
+ });
+ };
+
+ // 瑙勬牸鍨嬪彿閫夋嫨浜嬩欢
+ const onSpecificationSelect = item => {
+ productData.value[currentProductIndex.value].specificationModel = item.name;
+ productData.value[currentProductIndex.value].productModelId = item.value;
+ productData.value[currentProductIndex.value].unit = item.unit;
+ showSpecificationPicker.value = false;
+ };
+
+ // 绋庣巼閫夋嫨浜嬩欢
+ const onTaxRateSelect = item => {
+ productData.value[currentProductIndex.value].taxRate = item.value;
+ showTaxRatePicker.value = false;
+ // 閲嶆柊璁$畻涓嶅惈绋庢�讳环
+ const inclusiveTotalPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice
+ );
+ const taxRate = parseFloat(item.value);
+ if (inclusiveTotalPrice && taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
+ }
+ };
+
+ // 鍙戠エ绫诲瀷閫夋嫨浜嬩欢
+ const onInvoiceTypeSelect = item => {
+ productData.value[currentProductIndex.value].invoiceType = item.name;
+ showInvoiceTypePicker.value = false;
+ };
+
+ // 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
+ const formatTaxPrice = idx => {
+ if (productData.value[idx].taxInclusiveUnitPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const quantity = parseFloat(
+ productData.value[currentProductIndex.value].quantity
+ );
+ const unitPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice
+ );
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (
+ unitPrice * quantity
+ ).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+ };
+
+ // 鏁伴噺杈撳叆妗嗗け鐒�
+ const formatAmount = idx => {
+ if (productData.value[idx].quantity) {
+ const value = parseFloat(productData.value[idx].quantity);
+ if (!isNaN(value)) {
+ productData.value[idx].quantity = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const quantity = parseFloat(
+ productData.value[currentProductIndex.value].quantity
+ );
+ const unitPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice
+ );
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (
+ unitPrice * quantity
+ ).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+ };
+
+ // 鍚◣鎬讳环澶辩劍锛屾牴鎹惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+ const formatTaxTotal = idx => {
+ if (productData.value[idx].taxInclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ const totalPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice
+ );
+ const quantity = parseFloat(
+ productData.value[currentProductIndex.value].quantity
+ );
+
+ if (!totalPrice || !quantity || quantity <= 0) {
+ return;
+ }
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (
+ totalPrice / quantity
+ ).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ totalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+ };
+
+ // 涓嶅惈绋庢�讳环澶辩劍, 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+ const formatNoTaxTotal = idx => {
+ if (productData.value[idx].taxExclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const exclusiveTotalPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice
+ );
+ const quantity = parseFloat(
+ productData.value[currentProductIndex.value].quantity
+ );
+ const taxRate = parseFloat(
+ productData.value[currentProductIndex.value].taxRate
+ );
+ if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
+ return;
+ }
+ // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
+ const taxRateDecimal = taxRate / 100;
+ const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice =
+ inclusiveTotalPrice.toFixed(2);
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (
+ inclusiveTotalPrice / quantity
+ ).toFixed(2);
+ };
+
+ const goBack = () => {
+ // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("operationType");
+ uni.removeStorageSync("editData");
+ uni.navigateBack();
+ };
+
+ const onSubmit = () => {
+ // 瀹℃壒閫氳繃鐨勫彴璐︾姝㈠啀娆′慨鏀�
+ if (isApprovalPassed.value) {
+ uni.showToast({
+ title: "宸插鎵归�氳繃鐨勫彴璐︿笉鍏佽淇敼",
+ icon: "none",
+ });
+ return;
+ }
+ const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
+ if (hasEmptyApprover) {
+ uni.showToast({
+ title: "璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒",
+ icon: "none",
+ });
+ return;
+ }
+ const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
+
+ if (productData.value !== null && productData.value.length > 0) {
+ form.value.productData = JSON.parse(JSON.stringify(productData.value));
+ } else {
+ uni.showToast({
+ title: "璇锋坊鍔犱骇鍝佷俊鎭�",
+ icon: "none",
+ });
+ return;
+ }
+ // 缂栬緫鍥炴樉鏃跺彲鑳藉彧鏈夊悎鍚屽彿锛屾彁浜ゅ墠灏濊瘯琛ラ綈 salesLedgerId
+ syncSalesLedgerIdFromContractNo();
+ if (operationType.value == "add") {
+ delete form.value.id;
+ }
+ form.value.approveUserIds = approveUserIds;
+ form.value.type = 2;
+ addOrEditPurchase(form.value).then(res => {
+ uni.showToast({
+ title: "鎻愪氦鎴愬姛",
+ icon: "success",
+ });
+ goBack();
+ });
+ };
+
+ const setUserInfo = () => {
+ form.value.recorderId = userStore.id;
+ form.value.recorderName = userStore.nickName;
+ // 璁剧疆褰撳ぉ鏃ユ湡
+ 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");
+ form.value.entryDate = `${year}-${month}-${day}`;
+ };
+
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.executionDate = formatDateToYMD(e.value);
+ currentDate.value = e.value;
+ showTimePicker.value = false;
+ };
+
+ // 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
+ const fillFormData = () => {
+ if (!editData.value) return;
+ getPurchaseById({ id: editData.value.id, type: 2 }).then(res => {
+ productData.value = res.productData;
+ if (res && res.approveUserIds) {
+ const userIds = res.approveUserIds.split(",");
+ approverNodes.value = userIds.map((userId, idx) => {
+ const userIdNum = parseInt(userId.trim());
+ // 浠巙serList涓壘鍒板搴旂殑鐢ㄦ埛淇℃伅
+ console.log(userList.value, "userList.value");
+ const userInfo = userList.value.find(user => user.userId === userIdNum);
+ return {
+ id: idx + 1,
+ userId: userIdNum,
+ nickName: userInfo ? userInfo.nickName : null,
+ };
+ });
+ nextApproverId = userIds.length + 1;
+ } else {
+ // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
+ approverNodes.value = [{ id: 1, userId: null, nickName: null }];
+ nextApproverId = 2;
+ }
+ });
+ console.log(editData.value);
+ // 濉厖鍩烘湰淇℃伅
+ form.value.purchaseContractNumber =
+ editData.value.purchaseContractNumber || "";
+ form.value.salesContractNo = editData.value.salesContractNo || "";
+ form.value.supplierName = editData.value.supplierName || "";
+ form.value.projectName = editData.value.projectName || "";
+ form.value.paymentMethod = editData.value.paymentMethod || "";
+ form.value.salesLedgerId = editData.value.salesLedgerId || "";
+ form.value.recorderId = editData.value.recorderId || "";
+ form.value.recorderName = editData.value.recorderName || "";
+ form.value.entryDate = editData.value.entryDate || "";
+ form.value.id = editData.value.id || "";
+ form.value.supplierId = editData.value.supplierId || "";
+ form.value.executionDate = editData.value.executionDate || "";
+ };
+
+ const getSalesNoList = () => {
+ getSalesNo().then(res => {
+ // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
+ salesContractList.value = res.map(user => ({
+ text: user.salesContractNo,
+ value: user.id,
+ }));
+ // 鍒楄〃鍥炴潵鍚庯紝琛ラ綈缂栬緫鍥炴樉鐨� salesLedgerId
+ syncSalesLedgerIdFromContractNo();
+ });
+ };
+
+ const getOptionsLIst = () => {
+ getOptions().then(res => {
+ // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
+ supplierList.value = res.data.map(item => ({
+ text: item.supplierName,
+ value: item.id,
+ isWhite: item.isWhite,
+ }));
+ });
+ };
+
+ const convertIdToValue = data => {
+ // 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
+ if (!Array.isArray(data)) {
+ return [];
+ }
+ // 閫掑綊鏄犲皠鍑芥暟
+ return data.map(item => {
+ // 鍒涘缓鏂板璞★紝鏄犲皠瀛楁
+ const mappedItem = {
+ label: item.label, // 鍏抽敭锛氬皢 label 鏄犲皠涓� text
+ id: item.id, // 淇濈暀 id
+ };
+ // 濡傛灉瀛樺湪 children 鏁扮粍锛屽垯閫掑綊澶勭悊
+ if (
+ item.children &&
+ Array.isArray(item.children) &&
+ item.children.length > 0
+ ) {
+ mappedItem.children = convertIdToValue(item.children);
+ }
+ return mappedItem;
+ });
+ };
+
+ // 鑾峰彇浜у搧澶х被tree鏁版嵁
+ const getProductOptions = () => {
+ productTreeList().then(res => {
+ productOptions.value = convertIdToValue(res);
+ });
+ };
+ const approverNodes = ref([]);
+ let nextApproverId = 2;
+ const userList = ref([]);
+ onMounted(() => {
+ // 鑾峰彇椤甸潰鍙傛暟
+ operationType.value = uni.getStorageSync("operationType") || "";
+ userListNoPageByTenantId().then(res => {
+ userList.value = res.data;
+ });
+ // 鑾峰彇閿�鍞悎鍚屽彿鍒楄〃
+ getSalesNoList();
+ // 鑾峰彇渚涘簲鍟嗗垪琛�
+ getOptionsLIst();
+ // 鑾峰彇浜у搧澶х被tree鏁版嵁
+ getProductOptions();
+ // 璧嬪�奸粯璁や俊鎭�
+ if (operationType.value === "add") {
+ setUserInfo();
+ createPurchaseNo().then(res => {
+ form.value.purchaseContractNumber = res.data;
+ });
+ }
+
+ // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
+ uni.$on("selectContact", handleSelectContact);
+
+ // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
+ const editDataStr = uni.getStorageSync("editData");
+ if (editDataStr) {
+ try {
+ editData.value = JSON.parse(editDataStr);
+ // 濡傛灉鏄紪杈戞ā寮忥紝绛夊緟鏁版嵁鍔犺浇瀹屾垚鍚庡~鍏呰〃鍗曟暟鎹�
+ if (operationType.value !== "add" && editData.value) {
+ // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
+ setTimeout(() => {
+ fillFormData();
+ }, 100);
+ }
+ } catch (error) {
+ console.error("瑙f瀽缂栬緫鏁版嵁澶辫触:", error);
+ }
+ } else {
+ approverNodes.value = [{ id: 1, userId: null }];
+ }
+ });
+ // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
+ const handleSelectContact = data => {
+ const { stepIndex, contact } = data;
+ // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
+ console.log(contact);
+ console.log(stepIndex, "stepIndex");
+ console.log(approverNodes.value[stepIndex], "瀹℃壒浜�");
+ approverNodes.value[stepIndex].userId = contact.userId;
+ approverNodes.value[stepIndex].nickName = contact.nickName;
+ };
+
+ const addApprover = stepIndex => {
+ if (isReadOnly.value) return;
+ // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
+ uni.setStorageSync("stepIndex", stepIndex);
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
+ });
+ };
+
+ const addApprovalStep = () => {
+ if (isReadOnly.value) return;
+ // 娣诲姞鏂扮殑瀹℃壒姝ラ
+ approverNodes.value.push({ userId: null, nickName: null });
+ console.log(approverNodes.value, "approverNodes.value");
+ };
+
+ const removeApprover = stepIndex => {
+ if (isReadOnly.value) return;
+ // 绉婚櫎瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = null;
+ approverNodes.value[stepIndex].nickName = null;
+ };
+
+ const removeApprovalStep = stepIndex => {
+ if (isReadOnly.value) return;
+ // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
+ if (approverNodes.value.length > 1) {
+ approverNodes.value.splice(stepIndex, 1);
+ } else {
+ uni.showToast({
+ title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
+ icon: "none",
+ });
+ }
+ };
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-</style>
+ @import "@/static/scss/form-common.scss";
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 16px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+ }
+
+ .approval-header {
+ margin-bottom: 16px;
+ }
+
+ .approval-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .approval-desc {
+ font-size: 12px;
+ color: #999;
+ }
+
+ /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
+ .approval-steps {
+ padding-left: 22px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 11px;
+ top: 40px;
+ bottom: 40px;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ #e6f7ff 0%,
+ #bae7ff 50%,
+ #91d5ff 100%
+ );
+ border-radius: 1px;
+ }
+ }
+
+ .approval-step {
+ position: relative;
+ margin-bottom: 24px;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: -18px;
+ top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
+ width: 12px;
+ height: 12px;
+ background: #fff;
+ border: 3px solid #006cfb;
+ border-radius: 50%;
+ z-index: 2;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ .step-title {
+ top: 12px;
+ margin-bottom: 12px;
+ position: relative;
+ margin-left: 6px;
+ }
+
+ .step-title text {
+ font-size: 14px;
+ color: #666;
+ background: #f0f0f0;
+ padding: 4px 12px;
+ border-radius: 12px;
+ position: relative;
+ line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ padding: 16px;
+ gap: 12px;
+ position: relative;
+ border: 1px solid #e6f7ff;
+ box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
+ transition: all 0.3s ease;
+ }
+
+ .approver-avatar {
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+ }
+
+ .avatar-text {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+ }
+
+ .approver-info {
+ flex: 1;
+ position: relative;
+ }
+
+ .approver-name {
+ display: block;
+ font-size: 16px;
+ color: #333;
+ font-weight: 500;
+ position: relative;
+ }
+
+ .approver-dept {
+ font-size: 12px;
+ color: #999;
+ background: rgba(0, 108, 251, 0.05);
+ padding: 2px 8px;
+ border-radius: 8px;
+ display: inline-block;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 4px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 2px;
+ height: 2px;
+ background: #006cfb;
+ border-radius: 50%;
+ }
+ }
+
+ .delete-approver-btn {
+ font-size: 16px;
+ color: #ff4d4f;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s ease;
+ position: relative;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
+ border: 2px dashed #006cfb;
+ border-radius: 16px;
+ padding: 20px;
+ color: #006cfb;
+ font-size: 14px;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: 32px;
+ height: 32px;
+ border: 2px solid #006cfb;
+ border-radius: 50%;
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
+ }
+
+ .delete-step-btn {
+ color: #ff4d4f;
+ font-size: 12px;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ padding: 6px 12px;
+ border-radius: 12px;
+ display: inline-block;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 6px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 4px;
+ height: 4px;
+ background: #ff4d4f;
+ border-radius: 50%;
+ }
+ }
+
+ .step-line {
+ display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
+ }
+
+ .add-step-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ // 鍔ㄧ敾瀹氫箟
+ @keyframes pulse {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.7;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ }
+
+ @keyframes rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes ripple {
+ 0% {
+ transform: translate(-50%, -50%) scale(0.8);
+ opacity: 1;
+ }
+ 100% {
+ transform: translate(-50%, -50%) scale(1.6);
+ opacity: 0;
+ }
+ }
+
+ /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
+ .step-line {
+ position: absolute;
+ left: 4px;
+ top: 48px;
+ width: 2px;
+ height: calc(100% - 48px);
+ background: #e5e7eb;
+ }
+
+ .approver-container {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ gap: 12px;
+ padding: 10px 0;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 10px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ border-radius: 0;
+ }
+
+ .approver-avatar {
+ position: relative;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: #f3f4f6;
+ border: 2px solid #e5e7eb;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
+ }
+
+ .avatar-text {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 600;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ padding: 0;
+ }
+
+ .add-approver-btn .add-circle {
+ width: 40px;
+ height: 40px;
+ border: 2px dashed #a0aec0;
+ border-radius: 50%;
+ color: #6b7280;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ line-height: 1;
+ }
+
+ .add-approver-btn .add-label {
+ color: #3b82f6;
+ font-size: 14px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/procurementManagement/procurementLedger/index.vue b/src/pages/procurementManagement/procurementLedger/index.vue
index 458eac2..615a00d 100644
--- a/src/pages/procurementManagement/procurementLedger/index.vue
+++ b/src/pages/procurementManagement/procurementLedger/index.vue
@@ -1,193 +1,294 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="閲囪喘鍙拌处" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿鎼滅储"
- v-model="purchaseContractNumber"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 閲囪喘鍙拌处鐎戝竷娴� -->
- <view class="ledger-list" v-if="ledgerList.length > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item" @click="handleInfo('edit', item)">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.purchaseContractNumber }}</text>
- </view>
- <!-- <view class="item-tag">-->
- <!-- <text class="tag-text">{{ item.recorder }}</text>-->
- <!-- </view>-->
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">閿�鍞悎鍚屽彿</text>
- <text class="detail-value">{{ item.salesContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
- <text class="detail-value">{{ item.supplierName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻鏂瑰紡</text>
- <text class="detail-value">{{ item.paymentMethod }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ item.contractAmount }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row">
- <text class="detail-label">褰曞叆浜�</text>
- <text class="detail-value">{{ item.recorderName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆鏃ユ湡</text>
- <text class="detail-value">{{ item.entryDate }}</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤閲囪喘鍙拌处鏁版嵁</text>
- </view>
-
- <!-- 娴姩鎿嶄綔鎸夐挳 -->
- <view class="fab-button" @click="handleInfo('add')">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="閲囪喘鍙拌处"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿鎼滅储"
+ v-model="purchaseContractNumber"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 閲囪喘鍙拌处鐎戝竷娴� -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item"
+ @click="handleInfo('edit', item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getApprovalStatusType(item.approvalStatus)">
+ {{ approvalStatusText[item.approvalStatus] || '鏈煡鐘舵��' }}
+ </u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <!-- <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view> -->
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻鏂瑰紡</text>
+ <text class="detail-value">{{ item.paymentMethod }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.recorderName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ item.entryDate }}</text>
+ </view>
+ </view>
+ <!-- 浠呴潪鈥滃鎵归�氳繃鈥濈殑鍙拌处灞曠ず鍒犻櫎鎸夐挳 -->
+ <!-- <view class="detail-row"
+ v-if="item.approvalStatus !== 3"
+ style="justify-content: flex-end; margin-top: 8px;">
+ <up-button type="error"
+ size="small"
+ plain
+ @click.stop="handleDelete(item)">
+ 鍒犻櫎
+ </up-button>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤閲囪喘鍙拌处鏁版嵁</text>
+ </view>
+ <!-- 娴姩鎿嶄綔鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="handleInfo('add')">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
</template>
<script setup>
-import { ref } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import useUserStore from "@/store/modules/user";
-import PageHeader from "@/components/PageHeader.vue";
-import {purchaseListPage} from "@/api/procurementManagement/procurementLedger";
-const userStore = useUserStore()
+ import { ref } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import useUserStore from "@/store/modules/user";
+ import PageHeader from "@/components/PageHeader.vue";
+ import {
+ purchaseListPage,
+ delPurchase,
+ } from "@/api/procurementManagement/procurementLedger";
+ const userStore = useUserStore();
+ const approvalStatusText = {
+ 1: "寰呭鏍�",
+ 2: "瀹℃壒涓�",
+ 3: "瀹℃壒閫氳繃",
+ 4: "瀹℃壒澶辫触",
+ };
+ // 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
+ const getApprovalStatusType = status => {
+ const typeMap = {
+ 1: "info", // 寰呭鏍� - 鐏拌壊
+ 2: "warning", // 瀹℃壒涓� - 姗欒壊
+ 3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
+ 4: "error", // 瀹℃壒澶辫触 - 绾㈣壊
+ };
+ return typeMap[status] || "";
+ };
+ // 鎼滅储鍏抽敭璇�
+ const purchaseContractNumber = ref("");
-// 鎼滅储鍏抽敭璇�
-const purchaseContractNumber = ref('');
+ // 閲囪喘鍙拌处鏁版嵁
+ const ledgerList = ref([]);
-// 閲囪喘鍙拌处鏁版嵁
-const ledgerList = ref([]);
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ purchaseListPage({
+ ...page,
+ purchaseContractNumber: purchaseContractNumber.value,
+ })
+ .then(res => {
+ ledgerList.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1
- }
- purchaseListPage({...page, purchaseContractNumber: purchaseContractNumber.value}).then((res) => {
- ledgerList.value = res.data.records;
- closeToast()
- }).catch(() => {
- closeToast()
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
+ const handleInfo = (type, row) => {
+ try {
+ // 璁剧疆鎿嶄綔绫诲瀷
+ uni.setStorageSync("operationType", type);
+ uni.removeStorageSync("editData");
-// 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
-const handleInfo = (type, row) => {
- try {
- // 璁剧疆鎿嶄綔绫诲瀷
- uni.setStorageSync('operationType', type);
-
- // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
- if (type !== 'add') {
- // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
- if (!row) {
- uni.showToast({
- title: '鏁版嵁涓嶅瓨鍦�',
- icon: 'error'
- });
- return;
- }
-
- // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
- if (row.recorderName != userStore.nickName) {
- // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
- uni.setStorageSync('editData', JSON.stringify(row));
+ // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
+ if (type !== "add") {
+ // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
+ if (!row) {
+ uni.showToast({
+ title: "鏁版嵁涓嶅瓨鍦�",
+ icon: "error",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
+ if (row.recorderName != userStore.nickName) {
+ // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
+ uni.setStorageSync("editData", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/procurementManagement/procurementLedger/view",
+ });
+ return;
+ }
+
+ // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
+ uni.setStorageSync("editData", JSON.stringify(row));
uni.navigateTo({
- url: '/pages/procurementManagement/procurementLedger/view'
+ url: "/pages/procurementManagement/procurementLedger/detail",
});
return;
}
-
- // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
- uni.setStorageSync('editData', JSON.stringify(row));
+
+ // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
uni.navigateTo({
- url: '/pages/procurementManagement/procurementLedger/detail'
+ url: "/pages/procurementManagement/procurementLedger/detail",
+ });
+ } catch (error) {
+ console.error("澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ // 鍒犻櫎鍗曟潯閲囪喘鍙拌处
+ const handleDelete = row => {
+ if (!row || !row.id) {
+ uni.showToast({
+ title: "鏁版嵁鏈夎锛屾棤娉曞垹闄�",
+ icon: "none",
});
return;
}
-
- // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
- uni.navigateTo({
- url: '/pages/procurementManagement/procurementLedger/detail'
- });
-
- } catch (error) {
- console.error('澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
-onShow(() => {
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
+ confirmText: "纭",
+ cancelText: "鍙栨秷",
+ success: res => {
+ if (res.confirm) {
+ delPurchase([row.id])
+ .then(result => {
+ // 鎴愬姛锛歝ode === 200
+ if (result && result.code === 200) {
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ getList();
+ return;
+ }
+ // 涓氬姟澶辫触锛氫紭鍏堝睍绀哄悗绔繑鍥炵殑 msg锛堝 CG2026... 涓嶅厑璁稿垹闄わ級
+ uni.showToast({
+ title: (result && result.msg) || "鍒犻櫎澶辫触",
+ icon: "none",
+ });
+ })
+ .catch(error => {
+ // 瀵逛簬 request 灏佽杩斿洖鐨� '500' 鎴栧叾浠� code锛岄敊璇彁绀哄凡缁忓湪 request 閲� toast 杩囦簡锛岃繖閲屼笉鍐嶉噸澶嶈鐩�
+ if (error === "500" || typeof error === "number") {
+ return;
+ }
+ // 鍙湁鍦ㄧ湡姝e紓甯告椂锛屾墠鍦ㄨ繖閲屽厹搴曟彁绀�
+ const msg =
+ (error && error.msg) ||
+ (error &&
+ error.response &&
+ error.response.data &&
+ error.response.data.msg) ||
+ (error && error.message) ||
+ "鍒犻櫎澶辫触";
+ uni.showToast({
+ title: msg,
+ icon: "none",
+ });
+ });
+ }
+ },
+ });
+ };
+
+ onShow(() => {
// 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
getList();
-});
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/procurement-common.scss';
+ @import "@/styles/procurement-common.scss";
-// 閲囪喘鍙拌处鐗规湁鏍峰紡锛堝鏈夐渶瑕佸彲鍦ㄦ娣诲姞锛�
+ // 閲囪喘鍙拌处鐗规湁鏍峰紡锛堝鏈夐渶瑕佸彲鍦ㄦ娣诲姞锛�
</style>
diff --git a/src/pages/procurementManagement/receiptPaymentHistory/index.vue b/src/pages/procurementManagement/receiptPaymentHistory/index.vue
index 340f3b2..d2d463f 100644
--- a/src/pages/procurementManagement/receiptPaymentHistory/index.vue
+++ b/src/pages/procurementManagement/receiptPaymentHistory/index.vue
@@ -1,79 +1,86 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="浠樻娴佹按" @back="goBack" />
-
- <!-- 鎼滅储鍖哄煙 -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О"
- v-model="searchForm.searchText"
- @change="getList"
- clearable
- />
- </view>
- <view class="search-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
- <!-- 缁熻淇℃伅 -->
- <view class="summary-info" v-if="tableData.length > 0">
- <view class="summary-item">
- <text class="summary-label">鎬昏褰曟暟</text>
- <text class="summary-value">{{ tableData.length }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">鎬婚噾棰�</text>
- <text class="summary-value highlight">{{ formatAmount(totalAmount) }}</text>
- </view>
- </view>
- <!-- 浠樻鍘嗗彶鍒楄〃 -->
- <view class="history-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index">
- <view class="history-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.purchaseContractNumber }}</text>
- </view>
- <view class="item-tag" :class="getTagClass(item.paymentMethod)">
- <text class="tag-text">{{ item.paymentMethod }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
- <text class="detail-value">{{ item.supplierName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻鏃ユ湡</text>
- <text class="detail-value">{{ item.paymentDate }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row">
- <text class="detail-label">鐧昏浜�</text>
- <text class="detail-value">{{ item.registrant }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鐧昏鏃ユ湡</text>
- <text class="detail-value">{{ item.registrationtDate }}</text>
- </view>
- </view>
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="action-buttons">
- <u-button
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="浠樻娴佹按"
+ @back="goBack" />
+ <!-- 鎼滅储鍖哄煙 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О"
+ v-model="searchForm.searchText"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info"
+ v-if="tableData.length > 0">
+ <view class="summary-item">
+ <text class="summary-label">鎬昏褰曟暟</text>
+ <text class="summary-value">{{ tableData.length }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鎬婚噾棰�</text>
+ <text class="summary-value highlight">{{ formatAmount(totalAmount) }}</text>
+ </view>
+ </view>
+ <!-- 浠樻鍘嗗彶鍒楄〃 -->
+ <view class="history-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index">
+ <view class="history-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ <view class="item-tag"
+ :class="getTagClass(item.paymentMethod)">
+ <text class="tag-text">{{ item.paymentMethod }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.currentPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻鏃ユ湡</text>
+ <text class="detail-value">{{ item.paymentDate }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">鐧昏浜�</text>
+ <text class="detail-value">{{ item.registrant }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐧昏鏃ユ湡</text>
+ <text class="detail-value">{{ item.registrationtDate }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="action-buttons">
+ <!-- <u-button
type="primary"
size="small"
class="action-btn"
@@ -81,124 +88,160 @@
@click="openForm(item)"
>
缂栬緫浠樻
- </u-button>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤浠樻鍘嗗彶鏁版嵁</text>
- </view>
- </view>
+ </u-button> -->
+ <!-- <u-button type="error"
+ size="small"
+ class="action-btn"
+ :disabled="item.registrant !== userStore.nickName"
+ @click="deleteItem(item)">
+ 鍒犻櫎
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤浠樻鍘嗗彶鏁版嵁</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref, computed } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {paymentHistoryListPage} from "@/api/procurementManagement/paymentEntry";
-import useUserStore from "@/store/modules/user";
-const userStore = useUserStore()
+ import { ref, computed } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { paymentHistoryListPage } from "@/api/procurementManagement/paymentEntry";
+ import { delPaymentRegistration } from "@/api/procurementManagement/procurementInvoiceLedger";
+ import useUserStore from "@/store/modules/user";
+ const userStore = useUserStore();
-// 鎼滅储琛ㄥ崟
-const searchForm = ref({
- searchText: '',
-});
+ // 鎼滅储琛ㄥ崟
+ const searchForm = ref({
+ searchText: "",
+ });
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([]);
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
-// 鍒嗛〉鍙傛暟
-const page = ref({
- current: -1,
- size: -1,
-});
+ // 鍒嗛〉鍙傛暟
+ const page = ref({
+ current: -1,
+ size: -1,
+ });
-const totalAmount = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.receiptPaymentAmount) || 0);
- }, 0);
-});
+ const totalAmount = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.receiptPaymentAmount) || 0);
+ }, 0);
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const deleteItem = item => {
+ uni.showModal({
+ title: "纭鍒犻櫎",
+ content: `鏄惁纭鍒犻櫎璇ユ暟鎹悧锛焋,
+ success: res => {
+ if (res.confirm) {
+ // 璋冪敤鍒犻櫎鎺ュ彛
+ delPaymentRegistration([item.id])
+ .then(() => {
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ // 鍒锋柊鍒楄〃
+ getList();
+ })
+ .catch(() => {
+ uni.showToast({
+ title: "鍒犻櫎澶辫触",
+ icon: "error",
+ });
+ });
+ }
+ },
+ });
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ ...searchForm.value,
+ ...page.value,
+ };
+ paymentHistoryListPage(params)
+ .then(res => {
+ tableData.value = res.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const params = {
- ...searchForm.value,
- ...page.value
- };
- paymentHistoryListPage(params).then((res) => {
- tableData.value = res.records;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == "鐢垫眹") {
+ return "tag-electric";
+ } else if (type == "鎵垮厬") {
+ return "tag-acceptance";
+ } else {
+ return "tag-unknown";
+ }
+ };
-// 鑾峰彇鏍囩鏍峰紡绫�
-const getTagClass = (type) => {
- if (type == '鐢垫眹') {
- return "tag-electric";
- } else if (type == '鎵垮厬') {
- return "tag-acceptance";
- } else {
- return "tag-unknown";
- }
-};
+ // 鏍煎紡鍖栭噾棰�
+ const formatAmount = amount => {
+ return amount ? parseFloat(amount).toFixed(2) : "0.00";
+ };
-// 鏍煎紡鍖栭噾棰�
-const formatAmount = (amount) => {
- return amount ? parseFloat(amount).toFixed(2) : '0.00';
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
-
-// 鎵撳紑缂栬緫琛ㄥ崟
-const openForm = (item) => {
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item))
- uni.navigateTo({ url: '/pages/procurementManagement/paymentEntry/edit' })
-}
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 鎵撳紑缂栬緫琛ㄥ崟
+ const openForm = item => {
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+ uni.navigateTo({ url: "/pages/procurementManagement/paymentEntry/edit" });
+ };
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/procurement-common.scss';
+ @import "@/styles/procurement-common.scss";
-// 浠樻娴佹按鐗规湁鏍峰紡
-.action-buttons {
- padding: 12px 0 0 0; // 涓庡叕鍏辨牱寮忎腑鐨� 0 0 16px 0 涓嶅悓
-}
+ // 浠樻娴佹按鐗规湁鏍峰紡
+ .action-buttons {
+ padding: 12px 0 0 0; // 涓庡叕鍏辨牱寮忎腑鐨� 0 0 16px 0 涓嶅悓
+ }
-.item-tag {
- padding: 2px 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 2px 4px 涓嶅悓
-}
+ .item-tag {
+ padding: 2px 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 2px 4px 涓嶅悓
+ }
-.tag-text {
- font-size: 14px; // 涓庡叕鍏辨牱寮忎腑鐨� 11px 涓嶅悓
- color: #ffffff;
- font-weight: 500;
-}
+ .tag-text {
+ font-size: 14px; // 涓庡叕鍏辨牱寮忎腑鐨� 11px 涓嶅悓
+ color: #ffffff;
+ font-weight: 500;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/sales/deliveryLedger/index.vue b/src/pages/sales/deliveryLedger/index.vue
new file mode 100644
index 0000000..e968aa9
--- /dev/null
+++ b/src/pages/sales/deliveryLedger/index.vue
@@ -0,0 +1,785 @@
+<template>
+ <view class="delivery-ledger">
+ <!-- 椤甸潰澶撮儴 -->
+ <PageHeader title="鍙戣揣鍙拌处" @back="goBack" />
+
+ <!-- 鎼滅储鍖哄煙 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input
+ class="search-text"
+ placeholder="璇疯緭鍏ラ攢鍞鍗曞彿"
+ v-model="searchForm.salesContractNo"
+ @change="handleQuery"
+ clearable
+ />
+ </view>
+ <view class="search-input">
+ <up-input
+ class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+ v-model="searchForm.customerName"
+ @change="handleQuery"
+ clearable
+ />
+ </view>
+ <view class="filter-button" @click="handleQuery">
+ <up-icon name="search" size="24" color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鍙戣揣鍙拌处鍒楄〃 -->
+ <view class="ledger-list" v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData" :key="index">
+ <view class="ledger-item" @click="openDetail(item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ <u-tag
+ size="mini"
+ :type="getApprovalStatusType(item.status)"
+ >{{ getApprovalStatusText(item.status) }}</u-tag>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣璁㈠崟鍙�</text>
+ <text class="detail-value">{{ item.shippingNo || '--' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣杩涘害</text>
+ <view class="progress-wrapper">
+ <up-line-progress
+ :percentage="getShippingProgress(item)"
+ :active-color="getProgressColor(item)"
+ height="8"
+ ></up-line-progress>
+ <text class="progress-text">{{ getShippingProgress(item) }}%</text>
+ </view>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鎬诲彂璐ф暟閲�</text>
+ <text class="detail-value">{{ item.shippingTotal || 0 }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸插彂璐ф暟閲�</text>
+ <text class="detail-value success">{{ item.shippingSuccessTotal || 0 }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">寰呭彂璐ф暟閲�</text>
+ <text class="detail-value warning">{{ item.waitShippingTotal || 0 }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else class="no-data">
+ <up-empty mode="list" text="鏆傛棤鍙戣揣鍙拌处鏁版嵁"></up-empty>
+ </view>
+
+ <!-- 鍙戣揣璇︽儏寮圭獥 -->
+ <u-popup
+ :show="dialogFormVisible"
+ mode="bottom"
+ :round="16"
+ :closeable="true"
+ @close="closeDia"
+ >
+ <view class="popup-content">
+ <view class="popup-header">
+ <text class="popup-title">鍙戣揣鍙拌处璇︽儏</text>
+ </view>
+ <scroll-view scroll-y class="popup-body">
+ <view v-if="currentShippingOrder" class="shipping-container">
+ <!-- 璁㈠崟淇℃伅鍗$墖 -->
+ <view class="info-card">
+ <view class="card-header">
+ <text class="card-title">璁㈠崟淇℃伅</text>
+ <u-tag
+ size="mini"
+ :type="getProgressColor(currentShippingOrder) === '#67C23A' ? 'success' : 'warning'"
+ >{{ getShippingProgress(currentShippingOrder) }}%</u-tag>
+ </view>
+ <view class="card-body">
+ <view class="info-row">
+ <text class="info-label">閿�鍞鍗�</text>
+ <text class="info-value">{{ currentShippingOrder.salesContractNo || '--' }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">瀹㈡埛鍚嶇О</text>
+ <text class="info-value">{{ currentShippingOrder.customerName || '--' }}</text>
+ </view>
+ <view class="info-row">
+ <text class="info-label">鍙戣揣璁㈠崟鍙�</text>
+ <text class="info-value">{{ currentShippingOrder.shippingNo || '--' }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="quantity-summary">
+ <view class="summary-item">
+ <text class="summary-label">鎬诲彂璐ф暟閲�</text>
+ <text class="summary-value total">{{ currentShippingOrder.shippingTotal || 0 }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">宸插彂璐ф暟閲�</text>
+ <text class="summary-value shipped">{{ currentShippingOrder.shippingSuccessTotal || 0 }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">寰呭彂璐ф暟閲�</text>
+ <text class="summary-value waiting">{{ currentShippingOrder.waitShippingTotal || 0 }}</text>
+ </view>
+ </view>
+ <view class="progress-wrapper">
+ <up-line-progress
+ :percentage="getShippingProgress(currentShippingOrder)"
+ :active-color="getProgressColor(currentShippingOrder)"
+ height="12"
+ ></up-line-progress>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鍙戣揣璁板綍鍗$墖 -->
+ <view class="records-card">
+ <view class="card-header">
+ <text class="card-title">鍙戣揣璁板綍</text>
+ <text class="record-count">鍏� {{ shippingRecords.length }} 鏉¤褰�</text>
+ </view>
+ <view class="card-body">
+ <view v-if="shippingRecords.length === 0" class="empty-state">
+ <up-empty mode="list" text="鏆傛棤鍙戣揣璁板綍"></up-empty>
+ </view>
+ <view v-else class="records-list">
+ <view
+ v-for="(record, index) in shippingRecords"
+ :key="record.id || index"
+ class="record-item"
+ >
+ <view class="record-header">
+ <u-tag
+ size="mini"
+ :type="record.type === '璐ц溅' ? 'primary' : 'success'"
+ >{{ record.type }}</u-tag>
+ <text class="record-date">{{ record.shippingDate }}</text>
+ </view>
+ <view class="record-body">
+ <view class="record-info-row">
+ <text class="record-info-label">鍙戣揣鏁伴噺</text>
+ <text class="record-info-value quantity">{{ record.shippingNum }}</text>
+ </view>
+ <view class="record-info-row" v-if="record.type === '璐ц溅'">
+ <text class="record-info-label">杞︾墝鍙�</text>
+ <text class="record-info-value">{{ record.shippingCarNumber || '--' }}</text>
+ </view>
+ <view class="record-info-row" v-else>
+ <text class="record-info-label">蹇�掑叕鍙�</text>
+ <text class="record-info-value">{{ record.expressCompany || '--' }}</text>
+ </view>
+ <view class="record-info-row" v-if="record.type === '蹇��'">
+ <text class="record-info-label">蹇�掑崟鍙�</text>
+ <text class="record-info-value">{{ record.expressNumber || '--' }}</text>
+ </view>
+ <view class="record-info-row" v-if="record.commonFileList && record.commonFileList.length > 0">
+ <text class="record-info-label">鍙戣揣鍥剧墖</text>
+ <view class="record-images">
+ <image
+ v-for="(file, imgIndex) in record.commonFileList"
+ :key="imgIndex"
+ :src="normalizeFileUrl(file?.url)"
+ mode="aspectFill"
+ class="record-image"
+ @click="previewImage(record.commonFileList, imgIndex)"
+ />
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </scroll-view>
+ <view class="popup-footer">
+ <u-button @click="closeDia">鍏抽棴</u-button>
+ </view>
+ </view>
+ </u-popup>
+ </view>
+</template>
+
+<script setup>
+import { ref, reactive } from "vue";
+import { onShow } from "@dcloudio/uni-app";
+import PageHeader from "@/components/PageHeader.vue";
+import {
+ deliveryLedgerListPage,
+ shippingInfoDetailListPage,
+} from "@/api/salesManagement/deliveryLedger.js";
+
+// 琛ㄦ牸鏁版嵁
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+ current: 1,
+ size: 100,
+});
+const total = ref(0);
+const javaApi = import.meta.env.VITE_APP_BASE_API;
+
+// 鎼滅储琛ㄥ崟
+const searchForm = reactive({
+ salesContractNo: "",
+ customerName: "",
+});
+
+// 鍙戣揣璇︽儏寮规
+const dialogFormVisible = ref(false);
+const currentShippingOrder = ref(null);
+const shippingRecords = ref([]);
+const shippingRecordsLoading = ref(false);
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+ uni.navigateBack();
+};
+
+// 鏄剧ず鍔犺浇鎻愮ず
+const showLoadingToast = (message) => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+};
+
+// 鍏抽棴鎻愮ず
+const closeToast = () => {
+ uni.hideLoading();
+};
+
+// 鏌ヨ鍒楄〃
+const handleQuery = () => {
+ page.current = 1;
+ getList();
+};
+
+const getList = () => {
+ tableLoading.value = true;
+ showLoadingToast("鍔犺浇涓�...");
+ deliveryLedgerListPage({ ...searchForm, ...page })
+ .then((res) => {
+ tableData.value = res.data.records || [];
+ total.value = res.data.total || 0;
+ closeToast();
+ tableLoading.value = false;
+ })
+ .catch(() => {
+ closeToast();
+ tableLoading.value = false;
+ });
+};
+
+// 鎵撳紑璇︽儏寮规
+const openDetail = async (row) => {
+ currentShippingOrder.value = row;
+ await loadShippingRecords(row.id);
+ dialogFormVisible.value = true;
+};
+
+// 鍔犺浇鍙戣揣璁板綍
+const loadShippingRecords = async (shippingInfoId) => {
+ shippingRecordsLoading.value = true;
+ try {
+ const res = await shippingInfoDetailListPage({ shippingInfoId, current: 1, size: 100 });
+ shippingRecords.value = res.data.records || [];
+ } catch (error) {
+ shippingRecords.value = [];
+ } finally {
+ shippingRecordsLoading.value = false;
+ }
+};
+
+// 鍏抽棴寮规
+const closeDia = () => {
+ dialogFormVisible.value = false;
+ currentShippingOrder.value = null;
+ shippingRecords.value = [];
+};
+
+// 鏂囦欢URL澶勭悊
+const normalizeFileUrl = (rawUrl = '') => {
+ let fileUrl = rawUrl || '';
+ if (fileUrl && fileUrl.indexOf('\\') > -1) {
+ const uploadsIndex = fileUrl.toLowerCase().indexOf('uploads');
+ if (uploadsIndex > -1) {
+ const relativePath = fileUrl.substring(uploadsIndex).replace(/\\/g, '/');
+ fileUrl = '/' + relativePath;
+ } else {
+ const parts = fileUrl.split('\\');
+ const fileName = parts[parts.length - 1];
+ fileUrl = '/uploads/' + fileName;
+ }
+ }
+ if (fileUrl && !fileUrl.startsWith('http')) {
+ if (!fileUrl.startsWith('/')) fileUrl = '/' + fileUrl;
+ fileUrl = javaApi + fileUrl;
+ }
+ return fileUrl;
+};
+
+// 棰勮鍥剧墖
+const previewImage = (fileList, currentIndex) => {
+ const urls = fileList.map((f) => normalizeFileUrl(f?.url));
+ uni.previewImage({
+ urls: urls,
+ current: currentIndex,
+ });
+};
+
+// 鑾峰彇鍙戣揣杩涘害鐧惧垎姣�
+const getShippingProgress = (row) => {
+ const shipped = row.shippingSuccessTotal || 0;
+ const total = shipped + (row.waitShippingTotal || 0);
+ if (total === 0) return 0;
+ return Math.round((shipped / total) * 100);
+};
+
+// 鑾峰彇杩涘害鏉¢鑹�
+const getProgressColor = (row) => {
+ const progress = getShippingProgress(row);
+ if (progress === 100) return '#67C23A';
+ if (progress >= 50) return '#E6A23C';
+ return '#2979ff';
+};
+
+// 鑾峰彇瀹℃牳鐘舵�佹枃鏈�
+const getApprovalStatusText = (status) => {
+ if (status === null || status === undefined || status === '') {
+ return '寰呭鏍�';
+ }
+ if (typeof status === 'number') {
+ const statusMap = {
+ 0: '寰呭鏍�',
+ 1: '瀹℃牳涓�',
+ 2: '瀹℃牳鎷掔粷',
+ 3: '瀹℃牳閫氳繃'
+ };
+ return statusMap[status] || '寰呭鏍�';
+ }
+ const statusStr = String(status).trim();
+ const statusTextMap = {
+ '寰呭鏍�': '寰呭鏍�',
+ '瀹℃牳涓�': '瀹℃牳涓�',
+ '瀹℃牳鎷掔粷': '瀹℃牳鎷掔粷',
+ '瀹℃牳閫氳繃': '瀹℃牳閫氳繃',
+ '0': '寰呭鏍�',
+ '1': '瀹℃牳涓�',
+ '2': '瀹℃牳鎷掔粷',
+ '3': '瀹℃牳閫氳繃'
+ };
+ return statusTextMap[statusStr] || statusStr || '寰呭鏍�';
+};
+
+// 鑾峰彇瀹℃牳鐘舵�佹爣绛剧被鍨�
+const getApprovalStatusType = (status) => {
+ if (status === null || status === undefined || status === '') {
+ return 'info';
+ }
+ if (typeof status === 'number') {
+ const typeMap = {
+ 0: 'info',
+ 1: 'warning',
+ 2: 'error',
+ 3: 'success'
+ };
+ return typeMap[status] || 'info';
+ }
+ const statusStr = String(status).trim();
+ const typeTextMap = {
+ '寰呭鏍�': 'info',
+ '瀹℃牳涓�': 'warning',
+ '瀹℃牳鎷掔粷': 'error',
+ '瀹℃牳閫氳繃': 'success',
+ '0': 'info',
+ '1': 'warning',
+ '2': 'error',
+ '3': 'success'
+ };
+ return typeTextMap[statusStr] || 'info';
+};
+
+onShow(() => {
+ getList();
+});
+</script>
+
+<style scoped lang="scss">
+.delivery-ledger {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+}
+
+// 鎼滅储鍖哄煙
+.search-section {
+ padding: 10px 20px;
+ background: #ffffff;
+}
+
+.search-bar {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+
+.search-input {
+ flex: 1;
+ min-width: 140px;
+ background: #f5f5f5;
+ border-radius: 24px;
+ padding: 0 16px;
+ display: flex;
+ align-items: center;
+}
+
+.search-text {
+ flex: 1;
+ font-size: 14px;
+ color: #333;
+ background: transparent;
+ border: none;
+ outline: none;
+
+ &::placeholder {
+ color: #999;
+ }
+}
+
+.filter-button {
+ width: 40px;
+ height: 40px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f5f5f5;
+}
+
+// 鍒楄〃鍖哄煙
+.ledger-list {
+ padding: 20px;
+}
+
+.ledger-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+
+ &:active {
+ transform: scale(0.98);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
+ }
+}
+
+.item-header {
+ padding: 16px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.document-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.item-id {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+}
+
+.item-details {
+ padding: 16px 0;
+}
+
+.detail-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+}
+
+.detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+
+ &.success {
+ color: #67C23A;
+ font-weight: 500;
+ }
+
+ &.warning {
+ color: #E6A23C;
+ font-weight: 500;
+ }
+}
+
+.progress-wrapper {
+ flex: 1;
+ margin-left: 16px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ .progress-text {
+ font-size: 12px;
+ color: #666;
+ min-width: 36px;
+ text-align: right;
+ }
+}
+
+.no-data {
+ padding: 40px 20px;
+ text-align: center;
+ color: #999;
+}
+
+// 寮圭獥鏍峰紡
+.popup-content {
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.popup-header {
+ padding: 16px;
+ border-bottom: 1px solid #eee;
+ text-align: center;
+
+ .popup-title {
+ font-size: 16px;
+ font-weight: 500;
+ color: #333;
+ }
+}
+
+.popup-body {
+ flex: 1;
+ padding: 16px;
+ max-height: 60vh;
+}
+
+.popup-footer {
+ padding: 16px;
+ border-top: 1px solid #eee;
+ display: flex;
+ gap: 12px;
+
+ :deep(.u-button) {
+ flex: 1;
+ }
+}
+
+// 鍗$墖鏍峰紡
+.info-card,
+.records-card {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.card-header {
+ padding: 16px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ border-bottom: 1px solid #f5f5f5;
+
+ .card-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ }
+
+ .record-count {
+ font-size: 12px;
+ color: #999;
+ }
+}
+
+.card-body {
+ padding: 16px;
+}
+
+// 璁㈠崟淇℃伅
+.info-row {
+ display: flex;
+ justify-content: space-between;
+ padding: 8px 0;
+
+ .info-label {
+ color: #666;
+ font-size: 14px;
+ }
+
+ .info-value {
+ color: #333;
+ font-weight: 500;
+ font-size: 14px;
+ }
+}
+
+.quantity-summary {
+ display: flex;
+ justify-content: space-between;
+ margin: 16px 0;
+
+ .summary-item {
+ text-align: center;
+ flex: 1;
+
+ .summary-label {
+ font-size: 12px;
+ color: #999;
+ margin-bottom: 8px;
+ display: block;
+ }
+
+ .summary-value {
+ font-size: 20px;
+ font-weight: bold;
+
+ &.total {
+ color: #2979ff;
+ }
+
+ &.shipped {
+ color: #67C23A;
+ }
+
+ &.waiting {
+ color: #E6A23C;
+ }
+ }
+ }
+}
+
+// 鍙戣揣璁板綍
+.empty-state {
+ padding: 40px 0;
+}
+
+.records-list {
+ .record-item {
+ border: 1px solid #eee;
+ border-radius: 8px;
+ padding: 12px;
+ margin-bottom: 12px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .record-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid #f5f5f5;
+
+ .record-date {
+ font-size: 12px;
+ color: #999;
+ }
+ }
+
+ .record-body {
+ .record-info-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .record-info-label {
+ font-size: 12px;
+ color: #999;
+ }
+
+ .record-info-value {
+ font-size: 14px;
+ color: #333;
+
+ &.quantity {
+ font-weight: bold;
+ color: #2979ff;
+ font-size: 16px;
+ }
+ }
+ }
+
+ .record-images {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ margin-top: 8px;
+
+ .record-image {
+ width: 60px;
+ height: 60px;
+ border-radius: 4px;
+ }
+ }
+ }
+}
+
+// 闅愯棌uview-plus鐨勬煇浜涢粯璁ゆ牱寮�
+:deep(.u-divider) {
+ margin: 8px 0 !important;
+}
+</style>
diff --git a/src/pages/sales/invoiceLedger/detail.vue b/src/pages/sales/invoiceLedger/detail.vue
index 93e622a..2abb7d7 100644
--- a/src/pages/sales/invoiceLedger/detail.vue
+++ b/src/pages/sales/invoiceLedger/detail.vue
@@ -18,6 +18,9 @@
<u-form-item label="鍙戠エ閲戦(鍏�)" prop="invoiceTotal" required border-bottom>
<u-input v-model="form.invoiceTotal" type="number" placeholder="璇疯緭鍏�" />
</u-form-item>
+ <view class="tip-text" v-if="Number(maxInvoiceAmount) > 0">
+ 鍙紑绁ㄦ渶澶ч噾棰濓細{{ formatAmount(maxInvoiceAmount) }} 鍏�
+ </view>
<u-form-item label="寮�绁ㄤ汉" border-bottom>
<u-input v-model="form.invoicePerson" readonly />
</u-form-item>
@@ -110,6 +113,7 @@
})
const fileList = ref([])
const currentId = ref('')
+const maxInvoiceAmount = ref(0)
// 鏃ユ湡閫夋嫨
const showInvoiceDatePicker = ref(false)
@@ -245,6 +249,10 @@
const res = await invoiceLedgerProductInfo({ id })
const data = res?.data || res
form.value = { ...data }
+ // 璁$畻鍙戠エ閲戦鏈�澶у�硷細noInvoiceAmount + invoiceAmount
+ const noInvoiceAmount = parseFloat(data?.noInvoiceAmount || 0)
+ const invoiceAmount = parseFloat(data?.invoiceAmount || 0)
+ maxInvoiceAmount.value = (Number.isNaN(noInvoiceAmount) ? 0 : noInvoiceAmount) + (Number.isNaN(invoiceAmount) ? 0 : invoiceAmount)
fileList.value = data?.fileList || []
if (!form.value.invoicePerson) {
form.value.invoicePerson = userStore.nickName
@@ -264,6 +272,17 @@
if (!form.value.invoiceNo) { showToast('璇疯緭鍏ュ彂绁ㄥ彿'); return }
if (!form.value.invoiceTotal) { showToast('璇疯緭鍏ュ彂绁ㄩ噾棰�'); return }
if (!form.value.invoiceDate) { showToast('璇烽�夋嫨寮�绁ㄦ棩鏈�'); return }
+
+ // 鏍¢獙锛氬彂绁ㄩ噾棰濅笉鑳借秴杩囨渶澶у��
+ const invoiceTotal = parseFloat(form.value.invoiceTotal || 0)
+ if (Number.isNaN(invoiceTotal) || invoiceTotal <= 0) {
+ showToast('璇疯緭鍏ユ湁鏁堢殑鍙戠エ閲戦')
+ return
+ }
+ if (maxInvoiceAmount.value > 0 && invoiceTotal - maxInvoiceAmount.value > 1e-6) {
+ showToast(`鍙戠エ閲戦涓嶈兘瓒呰繃鏈�澶у�硷細${formatAmount(maxInvoiceAmount.value)}`)
+ return
+ }
showLoadingToast('鎻愪氦涓�...')
form.value.fileList = fileList.value
await invoiceLedgerSaveOrUpdate(form.value)
@@ -342,7 +361,7 @@
.uploaded-list { padding: 8px 16px 0 16px; }
.uploaded-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; }
.file-name { font-size: 12px; color: #333; margin-right: 8px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.tip-text { padding: 4px 16px 0 16px; font-size: 12px; color: #888; }
+.tip-text { padding: 4px 0; font-size: 12px; color: #888; }
.footer-btns {
position: fixed;
left: 0;
diff --git a/src/pages/sales/invoiceLedger/index.vue b/src/pages/sales/invoiceLedger/index.vue
index f4cf5c2..0788c4d 100644
--- a/src/pages/sales/invoiceLedger/index.vue
+++ b/src/pages/sales/invoiceLedger/index.vue
@@ -1,616 +1,623 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="寮�绁ㄥ彴璐�" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩燂紙淇濇寔涓庨攢鍞彴璐﹂鏍间竴鑷达級 -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�/鍚堝悓鍙锋悳绱�"
- v-model="searchForm.searchText"
- @change="handleQuery"
- clearable
- />
- </view>
- <!-- <view class="filter-button" @click="showFilter = true">-->
- <!-- <up-icon name="list" size="24" color="#999"></up-icon>-->
- <!-- </view>-->
- <view class="filter-button" @click="handleQuery">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 鍒楄〃鍖哄煙 -->
- <view class="ledger-list" v-if="ledgerList.length > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浜у搧澶х被</text>
- <text class="detail-value">{{ item.productCategory }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瑙勬牸鍨嬪彿</text>
- <text class="detail-value">{{ item.specificationModel }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ鍙�</text>
- <text class="detail-value">{{ item.invoiceNo || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.invoiceTotal) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">绋庣巼(%)</text>
- <text class="detail-value">{{ item.taxRate }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆浜�</text>
- <text class="detail-value">{{ item.invoicePerson }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆鏃ユ湡</text>
- <text class="detail-value">{{ formatDateTime(item.createTime) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">寮�绁ㄦ棩鏈�</text>
- <text class="detail-value">{{ item.invoiceDate || '-' }}</text>
- </view>
- </view>
- <view class="action-buttons">
- <up-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.invoicePerson !== userStore.nickName"
- @click="openEdit(item)"
- >
- 缂栬緫
- </up-button>
- <up-button
- type="error"
- size="small"
- plain
- class="action-btn"
- :disabled="item.invoicePerson !== userStore.nickName"
- @click="handleDelete(item)"
- >
- 鍒犻櫎
- </up-button>
-<!-- <up-button-->
-<!-- size="small"-->
-<!-- plain-->
-<!-- class="action-btn"-->
-<!-- v-if="item.invoiceFileName"-->
-<!-- @click="openFileActions(item.commonFiles || [])"-->
-<!-- >-->
-<!-- 鏌ョ湅闄勪欢-->
-<!-- </up-button>-->
-<!-- <up-button-->
-<!-- type="primary"-->
-<!-- size="small"-->
-<!-- class="action-btn"-->
-<!-- v-else-->
-<!-- :disabled="item.invoicePerson !== userStore.nickName"-->
-<!-- @click="openUpload(item)"-->
-<!-- >-->
-<!-- 涓婁紶-->
-<!-- </up-button>-->
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤寮�绁ㄥ彴璐︽暟鎹�</text>
- </view>
-
- <!-- 绛涢�夊脊绐� -->
- <up-popup v-model="showFilter" mode="bottom" round><up-transition>
- <view class="filter-popup">
- <up-cell-group title="绛涢�夋潯浠�" inset>
- <up-input
- label="寮�绁ㄦ棩鏈�"
- readonly
- placeholder="璇烽�夋嫨鏃ユ湡鑼冨洿"
- @click="showInvoiceRange = true"
- v-model="invoiceRangeLabel"
- />
- <up-input
- label="褰曞叆鏃ユ湡"
- readonly
- @click="showCreateDatePicker = true"
- v-model="searchForm.createTimeStart"
- />
- <view class="switch-row">
- <text class="switch-label">涓嶆樉绀烘湁鍙戠エ琛�</text>
- <up-switch v-model="searchForm.status" size="20" />
- </view>
- </up-cell-group>
- <view class="filter-actions">
- <up-button @click="resetFilter">閲嶇疆</up-button>
- <up-button type="primary" @click="confirmFilter">纭畾</up-button>
- </view>
- </view>
- </up-transition></up-popup>
-
- <!-- 鏃ュ巻锛氬紑绁ㄦ棩鏈熻寖鍥� -->
- <up-popup v-model="showInvoiceRange" mode="bottom"><up-transition>
- <up-datetime-picker
- mode="date"
- type="range"
- title="閫夋嫨寮�绁ㄦ棩鏈熻寖鍥�"
- @confirm="onInvoiceRangeConfirm"
- @cancel="showInvoiceRange = false"
- />
- </up-transition></up-popup>
-
- <!-- 鏃ユ湡锛氬綍鍏ユ棩鏈� -->
- <up-popup v-model="showCreateDatePicker" mode="bottom"><up-transition>
- <up-datetime-picker
- mode="date"
- type="selector"
- v-model="currentCreateDate"
- title="閫夋嫨褰曞叆鏃ユ湡"
- @confirm="onCreateDateConfirm"
- @cancel="showCreateDatePicker = false"
- />
- </up-transition></up-popup>
-
-
-
- <!-- 鍗曡涓婁紶寮圭獥锛堟棤琛ㄥ崟锛� -->
- <up-popup v-model="showUpload" mode="bottom" round><up-transition>
- <view class="upload-container">
- <up-cell-group title="涓婁紶闄勪欢锛堜粎鏀寔 pdf锛屾渶澶�10MB锛屾渶澶�10涓級" inset>
- <up-upload
- accept="pdf"
- multiple
- :maxCount="10"
- :afterRead="afterReadRowUpload"
- :beforeRead="beforeReadPdf"
- >
- <up-button type="primary">鐐瑰嚮涓婁紶</up-button>
- </up-upload>
- <view class="uploaded-list" v-if="fileList.length">
- <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">
- <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
- <up-button size="mini" type="error" plain @click="removeUploaded(idx)">绉婚櫎</up-button>
- </view>
- </view>
- </up-cell-group>
- <view class="filter-actions">
- <up-button @click="showUpload = false">鍙栨秷</up-button>
- <up-button type="primary" @click="confirmUpload">纭</up-button>
- </view>
- </view>
- </up-transition></up-popup>
-
- <!-- 闄勪欢鍒楄〃閫夋嫨 -->
- <up-action-sheet v-model="showFileSheet" :actions="fileActions" cancel-text="鍙栨秷" close-on-click-action @select="onSelectFile">
- <view class="up-action-sheet__cancel" @click="showFileSheet = false">
- 鍙栨秷
- </view>
- </up-action-sheet>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="寮�绁ㄥ彴璐�"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩燂紙淇濇寔涓庨攢鍞彴璐﹂鏍间竴鑷达級 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�/閿�鍞悎鍚屽彿鎼滅储"
+ v-model="searchForm.searchText"
+ @change="handleQuery"
+ clearable />
+ </view>
+ <!-- <view class="filter-button" @click="showFilter = true">-->
+ <!-- <up-icon name="list" size="24" color="#999"></up-icon>-->
+ <!-- </view>-->
+ <view class="filter-button"
+ @click="handleQuery">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 鍒楄〃鍖哄煙 -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.specificationModel }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戠エ鍙�</text>
+ <text class="detail-value">{{ item.invoiceNo || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.invoiceTotal) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绋庣巼(%)</text>
+ <text class="detail-value">{{ item.taxRate }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.invoicePerson }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ formatDateTime(item.createTime) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">寮�绁ㄦ棩鏈�</text>
+ <text class="detail-value">{{ item.invoiceDate || '-' }}</text>
+ </view>
+ </view>
+ <view class="action-buttons">
+ <!-- <up-button type="primary"
+ size="small"
+ class="action-btn"
+ @click="openEdit(item)">
+ 缂栬緫
+ </up-button>
+ <up-button type="error"
+ size="small"
+ plain
+ class="action-btn"
+ @click="handleDelete(item)">
+ 鍒犻櫎
+ </up-button> -->
+ <!-- <up-button-->
+ <!-- size="small"-->
+ <!-- plain-->
+ <!-- class="action-btn"-->
+ <!-- v-if="item.invoiceFileName"-->
+ <!-- @click="openFileActions(item.commonFiles || [])"-->
+ <!-- >-->
+ <!-- 鏌ョ湅闄勪欢-->
+ <!-- </up-button>-->
+ <!-- <up-button-->
+ <!-- type="primary"-->
+ <!-- size="small"-->
+ <!-- class="action-btn"-->
+ <!-- v-else-->
+ <!-- :disabled="item.invoicePerson !== userStore.nickName"-->
+ <!-- @click="openUpload(item)"-->
+ <!-- >-->
+ <!-- 涓婁紶-->
+ <!-- </up-button>-->
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤寮�绁ㄥ彴璐︽暟鎹�</text>
+ </view>
+ <!-- 绛涢�夊脊绐� -->
+ <up-popup v-model="showFilter"
+ mode="bottom"
+ round><up-transition>
+ <view class="filter-popup">
+ <up-cell-group title="绛涢�夋潯浠�"
+ inset>
+ <up-input label="寮�绁ㄦ棩鏈�"
+ readonly
+ placeholder="璇烽�夋嫨鏃ユ湡鑼冨洿"
+ @click="showInvoiceRange = true"
+ v-model="invoiceRangeLabel" />
+ <up-input label="褰曞叆鏃ユ湡"
+ readonly
+ @click="showCreateDatePicker = true"
+ v-model="searchForm.createTimeStart" />
+ <view class="switch-row">
+ <text class="switch-label">涓嶆樉绀烘湁鍙戠エ琛�</text>
+ <up-switch v-model="searchForm.status"
+ size="20" />
+ </view>
+ </up-cell-group>
+ <view class="filter-actions">
+ <up-button @click="resetFilter">閲嶇疆</up-button>
+ <up-button type="primary"
+ @click="confirmFilter">纭畾</up-button>
+ </view>
+ </view>
+ </up-transition></up-popup>
+ <!-- 鏃ュ巻锛氬紑绁ㄦ棩鏈熻寖鍥� -->
+ <up-popup v-model="showInvoiceRange"
+ mode="bottom"><up-transition>
+ <up-datetime-picker mode="date"
+ type="range"
+ title="閫夋嫨寮�绁ㄦ棩鏈熻寖鍥�"
+ @confirm="onInvoiceRangeConfirm"
+ @cancel="showInvoiceRange = false" />
+ </up-transition></up-popup>
+ <!-- 鏃ユ湡锛氬綍鍏ユ棩鏈� -->
+ <up-popup v-model="showCreateDatePicker"
+ mode="bottom"><up-transition>
+ <up-datetime-picker mode="date"
+ type="selector"
+ v-model="currentCreateDate"
+ title="閫夋嫨褰曞叆鏃ユ湡"
+ @confirm="onCreateDateConfirm"
+ @cancel="showCreateDatePicker = false" />
+ </up-transition></up-popup>
+ <!-- 鍗曡涓婁紶寮圭獥锛堟棤琛ㄥ崟锛� -->
+ <up-popup v-model="showUpload"
+ mode="bottom"
+ round><up-transition>
+ <view class="upload-container">
+ <up-cell-group title="涓婁紶闄勪欢锛堜粎鏀寔 pdf锛屾渶澶�10MB锛屾渶澶�10涓級"
+ inset>
+ <up-upload accept="pdf"
+ multiple
+ :maxCount="10"
+ :afterRead="afterReadRowUpload"
+ :beforeRead="beforeReadPdf">
+ <up-button type="primary">鐐瑰嚮涓婁紶</up-button>
+ </up-upload>
+ <view class="uploaded-list"
+ v-if="fileList.length">
+ <view class="uploaded-item"
+ v-for="(f, idx) in fileList"
+ :key="idx">
+ <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
+ <up-button size="mini"
+ type="error"
+ plain
+ @click="removeUploaded(idx)">绉婚櫎</up-button>
+ </view>
+ </view>
+ </up-cell-group>
+ <view class="filter-actions">
+ <up-button @click="showUpload = false">鍙栨秷</up-button>
+ <up-button type="primary"
+ @click="confirmUpload">纭</up-button>
+ </view>
+ </view>
+ </up-transition></up-popup>
+ <!-- 闄勪欢鍒楄〃閫夋嫨 -->
+ <up-action-sheet v-model="showFileSheet"
+ :actions="fileActions"
+ cancel-text="鍙栨秷"
+ close-on-click-action
+ @select="onSelectFile">
+ <view class="up-action-sheet__cancel"
+ @click="showFileSheet = false">
+ 鍙栨秷
+ </view>
+ </up-action-sheet>
+ </view>
</template>
<script setup>
-import {reactive, ref} from 'vue'
-import dayjs from 'dayjs'
-import PageHeader from '@/components/PageHeader.vue'
-import useUserStore from '@/store/modules/user'
-import {getToken} from '@/utils/auth'
-import config from '@/config.js'
-import {
- commitFile,
- delInvoiceLedgerByRegProductId,
- registrationProductPage
-} from '@/api/salesManagement/invoiceLedger.js'
-import {onShow} from "@dcloudio/uni-app";
+ import { reactive, ref } from "vue";
+ import dayjs from "dayjs";
+ import PageHeader from "@/components/PageHeader.vue";
+ import useUserStore from "@/store/modules/user";
+ import { getToken } from "@/utils/auth";
+ import config from "@/config.js";
+ import {
+ commitFile,
+ delInvoiceLedgerByRegProductId,
+ registrationProductPage,
+ } from "@/api/salesManagement/invoiceLedger.js";
+ import { onShow } from "@dcloudio/uni-app";
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- })
-}
-const closeToast = () => {
- uni.hideLoading()
-}
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-const userStore = useUserStore()
+ const userStore = useUserStore();
-// 鍒楄〃涓庢煡璇�
-const ledgerList = ref([])
-const page = reactive({ current: -1, size: -1 })
-const searchForm = reactive({
- searchText: '',
- status: false,
- createTimeStart: ''
-})
+ // 鍒楄〃涓庢煡璇�
+ const ledgerList = ref([]);
+ const page = reactive({ current: -1, size: -1 });
+ const searchForm = reactive({
+ searchText: "",
+ status: false,
+ createTimeStart: "",
+ });
-// 椤堕儴浜や簰
-const showFilter = ref(false)
-const showInvoiceRange = ref(false)
-const showCreateDatePicker = ref(false)
-const invoiceRangeLabel = ref('')
-const currentCreateDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()])
+ // 椤堕儴浜や簰
+ const showFilter = ref(false);
+ const showInvoiceRange = ref(false);
+ const showCreateDatePicker = ref(false);
+ const invoiceRangeLabel = ref("");
+ const currentCreateDate = ref([
+ new Date().getFullYear(),
+ new Date().getMonth() + 1,
+ new Date().getDate(),
+ ]);
-const currentId = ref('')
-const fileList = ref([]) // 琛屼笂浼犳垨閫氱敤涓婁紶鍒楄〃
+ const currentId = ref("");
+ const fileList = ref([]); // 琛屼笂浼犳垨閫氱敤涓婁紶鍒楄〃
-// 琛屼笂浼犲脊绐�
-const showUpload = ref(false)
+ // 琛屼笂浼犲脊绐�
+ const showUpload = ref(false);
-// 闄勪欢鏌ョ湅
-const showFileSheet = ref(false)
-const fileActions = ref([])
-let currentFilesToOpen = []
+ // 闄勪欢鏌ョ湅
+ const showFileSheet = ref(false);
+ const fileActions = ref([]);
+ let currentFilesToOpen = [];
-const formatAmount = (val) => {
- if (val === undefined || val === null || val === '') return '0.00'
- const num = Number(val)
- if (Number.isNaN(num)) return '0.00'
- return num.toFixed(2)
-}
-const formatDateTime = (val) => {
- if (!val) return ''
- return dayjs(val).format('YYYY-MM-DD HH:mm:ss')
-}
+ const formatAmount = val => {
+ if (val === undefined || val === null || val === "") return "0.00";
+ const num = Number(val);
+ if (Number.isNaN(num)) return "0.00";
+ return num.toFixed(2);
+ };
+ const formatDateTime = val => {
+ if (!val) return "";
+ return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+ };
-const goBack = () => {
- uni.navigateBack()
-}
+ const goBack = () => {
+ uni.navigateBack();
+ };
-const handleQuery = () => {
- getList()
-}
+ const handleQuery = () => {
+ getList();
+ };
-const getList = async () => {
- try {
- showLoadingToast('鍔犺浇涓�...')
- const { invoiceDate, ...rest } = searchForm
- const res = await registrationProductPage({ ...rest, ...page })
- // 鍏煎涓嶅悓杩斿洖缁撴瀯
- ledgerList.value = res?.data?.records || res?.records || res?.data || []
- closeToast()
- } catch (e) {
- closeToast()
- showToast('鑾峰彇鍒楄〃澶辫触')
- }
-}
+ const getList = async () => {
+ try {
+ showLoadingToast("鍔犺浇涓�...");
+ const { invoiceDate, ...rest } = searchForm;
+ const res = await registrationProductPage({ ...rest, ...page });
+ // 鍏煎涓嶅悓杩斿洖缁撴瀯
+ ledgerList.value = res?.data?.records || res?.records || res?.data || [];
+ closeToast();
+ } catch (e) {
+ closeToast();
+ showToast("鑾峰彇鍒楄〃澶辫触");
+ }
+ };
-// 绛涢�夐�昏緫
-const resetFilter = () => {
- searchForm.searchText = ''
- searchForm.status = false
- const start = dayjs().startOf('month').format('YYYY-MM-DD')
- const end = dayjs().endOf('month').format('YYYY-MM-DD')
- searchForm.invoiceDate = [start, end]
- searchForm.invoiceDateStart = start
- searchForm.invoiceDateEnd = end
- searchForm.createTimeStart = ''
- invoiceRangeLabel.value = ''
-}
-const confirmFilter = () => {
- showFilter.value = false
- getList()
-}
-const onInvoiceRangeConfirm = ({ selectedValues }) => {
- try {
- const start = dayjs(selectedValues[0]).format('YYYY-MM-DD')
- const end = dayjs(selectedValues[1]).format('YYYY-MM-DD')
- searchForm.invoiceDateStart = start
- searchForm.invoiceDateEnd = end
- invoiceRangeLabel.value = `${start} 鑷� ${end}`
- showInvoiceRange.value = false
- } catch (err) {
- showInvoiceRange.value = false
- }
-}
-const onCreateDateConfirm = ({ selectedValues }) => {
- try {
- searchForm.createTimeStart = selectedValues.join('-')
- currentCreateDate.value = selectedValues
- showCreateDatePicker.value = false
- } catch (err) {
- showCreateDatePicker.value = false
- }
-}
+ // 绛涢�夐�昏緫
+ const resetFilter = () => {
+ searchForm.searchText = "";
+ searchForm.status = false;
+ const start = dayjs().startOf("month").format("YYYY-MM-DD");
+ const end = dayjs().endOf("month").format("YYYY-MM-DD");
+ searchForm.invoiceDate = [start, end];
+ searchForm.invoiceDateStart = start;
+ searchForm.invoiceDateEnd = end;
+ searchForm.createTimeStart = "";
+ invoiceRangeLabel.value = "";
+ };
+ const confirmFilter = () => {
+ showFilter.value = false;
+ getList();
+ };
+ const onInvoiceRangeConfirm = ({ selectedValues }) => {
+ try {
+ const start = dayjs(selectedValues[0]).format("YYYY-MM-DD");
+ const end = dayjs(selectedValues[1]).format("YYYY-MM-DD");
+ searchForm.invoiceDateStart = start;
+ searchForm.invoiceDateEnd = end;
+ invoiceRangeLabel.value = `${start} 鑷� ${end}`;
+ showInvoiceRange.value = false;
+ } catch (err) {
+ showInvoiceRange.value = false;
+ }
+ };
+ const onCreateDateConfirm = ({ selectedValues }) => {
+ try {
+ searchForm.createTimeStart = selectedValues.join("-");
+ currentCreateDate.value = selectedValues;
+ showCreateDatePicker.value = false;
+ } catch (err) {
+ showCreateDatePicker.value = false;
+ }
+ };
-// 缂栬緫閫昏緫鏀逛负璺宠浆鏂伴〉闈�
-const openEdit = (row) => {
- try {
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(row))
- uni.navigateTo({ url: '/pages/sales/invoiceLedger/detail' })
- } catch (e) {
- showToast('璺宠浆澶辫触')
- }
-}
+ // 缂栬緫閫昏緫鏀逛负璺宠浆鏂伴〉闈�
+ const openEdit = row => {
+ try {
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(row));
+ uni.navigateTo({ url: "/pages/sales/invoiceLedger/detail" });
+ } catch (e) {
+ showToast("璺宠浆澶辫触");
+ }
+ };
-// 鍒犻櫎
-const handleDelete = (row) => {
- uni.showModal({
- title: '鍒犻櫎纭',
- content: '璇ュ彂绁ㄥ彴璐﹀皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�',
- success: async (res) => {
- if (res.confirm) {
- try {
- showLoadingToast('澶勭悊涓�...')
- await delInvoiceLedgerByRegProductId(row.id)
- closeToast()
- showToast('鍒犻櫎鎴愬姛')
- getList()
- } catch (e) {
- closeToast()
- showToast('鍒犻櫎澶辫触锛岃閲嶈瘯')
- }
- }
- }
- })
-}
+ // 鍒犻櫎
+ const handleDelete = row => {
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: "璇ュ彂绁ㄥ彴璐﹀皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
+ success: async res => {
+ if (res.confirm) {
+ try {
+ showLoadingToast("澶勭悊涓�...");
+ await delInvoiceLedgerByRegProductId(row.id);
+ closeToast();
+ showToast("鍒犻櫎鎴愬姛");
+ getList();
+ } catch (e) {
+ closeToast();
+ showToast("鍒犻櫎澶辫触锛岃閲嶈瘯");
+ }
+ }
+ },
+ });
+ };
-// 琛屼笂浼�
-const openUpload = (row) => {
- currentId.value = row.id
- fileList.value = []
- showUpload.value = true
-}
-const confirmUpload = async () => {
- try {
- const payload = { fileList: fileList.value, id: currentId.value }
- showLoadingToast('鎻愪氦涓�...')
- await commitFile(payload)
- closeToast()
- showToast('鎻愪氦鎴愬姛')
- showUpload.value = false
- fileList.value = []
- currentId.value = ''
- getList()
- } catch (e) {
- closeToast()
- showToast('鎻愪氦澶辫触锛岃閲嶈瘯')
- }
-}
+ // 琛屼笂浼�
+ const openUpload = row => {
+ currentId.value = row.id;
+ fileList.value = [];
+ showUpload.value = true;
+ };
+ const confirmUpload = async () => {
+ try {
+ const payload = { fileList: fileList.value, id: currentId.value };
+ showLoadingToast("鎻愪氦涓�...");
+ await commitFile(payload);
+ closeToast();
+ showToast("鎻愪氦鎴愬姛");
+ showUpload.value = false;
+ fileList.value = [];
+ currentId.value = "";
+ getList();
+ } catch (e) {
+ closeToast();
+ showToast("鎻愪氦澶辫触锛岃閲嶈瘯");
+ }
+ };
-// 涓婁紶鐩稿叧
-const beforeReadPdf = (file) => {
- // 鍏煎澶氭枃浠�
- const files = Array.isArray(file) ? file : [file]
- for (const f of files) {
- const sizeOk = f.size <= 10 * 1024 * 1024
- const ext = (f.name || '').split('.').pop()?.toLowerCase()
- if (ext !== 'pdf') {
- showToast('浠呮敮鎸乸df鏂囦欢')
- return false
- }
- if (!sizeOk) {
- showToast('涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB')
- return false
- }
- }
- return true
-}
+ // 涓婁紶鐩稿叧
+ const beforeReadPdf = file => {
+ // 鍏煎澶氭枃浠�
+ const files = Array.isArray(file) ? file : [file];
+ for (const f of files) {
+ const sizeOk = f.size <= 10 * 1024 * 1024;
+ const ext = (f.name || "").split(".").pop()?.toLowerCase();
+ if (ext !== "pdf") {
+ showToast("浠呮敮鎸乸df鏂囦欢");
+ return false;
+ }
+ if (!sizeOk) {
+ showToast("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
+ return false;
+ }
+ }
+ return true;
+ };
-const uploadSingleFile = async (fileObj) => {
- return new Promise((resolve, reject) => {
- showLoadingToast('姝e湪涓婁紶...')
- uni.uploadFile({
- url: config.baseUrl + '/invoiceLedger/uploadFile',
- filePath: fileObj.url || fileObj.file?.path || fileObj.tempFilePath,
- name: 'file',
- header: { Authorization: 'Bearer ' + getToken() },
- success: (res) => {
- closeToast()
- try {
- const data = JSON.parse(res.data || '{}')
- if (data.code === 200) {
- resolve(data.data)
- } else {
- reject(new Error(data.msg || '涓婁紶澶辫触'))
- }
- } catch (err) {
- reject(err)
- }
- },
- fail: (err) => {
- closeToast()
- reject(err)
- }
- })
- })
-}
+ const uploadSingleFile = async fileObj => {
+ return new Promise((resolve, reject) => {
+ showLoadingToast("姝e湪涓婁紶...");
+ uni.uploadFile({
+ url: config.baseUrl + "/invoiceLedger/uploadFile",
+ filePath: fileObj.url || fileObj.file?.path || fileObj.tempFilePath,
+ name: "file",
+ header: { Authorization: "Bearer " + getToken() },
+ success: res => {
+ closeToast();
+ try {
+ const data = JSON.parse(res.data || "{}");
+ if (data.code === 200) {
+ resolve(data.data);
+ } else {
+ reject(new Error(data.msg || "涓婁紶澶辫触"));
+ }
+ } catch (err) {
+ reject(err);
+ }
+ },
+ fail: err => {
+ closeToast();
+ reject(err);
+ },
+ });
+ });
+ };
-const afterReadEditUpload = async (file) => {
- try {
- const files = Array.isArray(file) ? file : file?.file ? [file] : [file]
- for (const f of files) {
- const uploaded = await uploadSingleFile(f)
- fileList.value.push(uploaded)
- }
- showToast('涓婁紶鎴愬姛')
- } catch (e) {
- showToast('涓婁紶澶辫触')
- }
-}
+ const afterReadEditUpload = async file => {
+ try {
+ const files = Array.isArray(file) ? file : file?.file ? [file] : [file];
+ for (const f of files) {
+ const uploaded = await uploadSingleFile(f);
+ fileList.value.push(uploaded);
+ }
+ showToast("涓婁紶鎴愬姛");
+ } catch (e) {
+ showToast("涓婁紶澶辫触");
+ }
+ };
-const afterReadRowUpload = async (file) => {
- try {
- const files = Array.isArray(file) ? file : file?.file ? [file] : [file]
- for (const f of files) {
- const uploaded = await uploadSingleFile(f)
- fileList.value.push(uploaded)
- }
- showToast('涓婁紶鎴愬姛')
- } catch (e) {
- showToast('涓婁紶澶辫触')
- }
-}
+ const afterReadRowUpload = async file => {
+ try {
+ const files = Array.isArray(file) ? file : file?.file ? [file] : [file];
+ for (const f of files) {
+ const uploaded = await uploadSingleFile(f);
+ fileList.value.push(uploaded);
+ }
+ showToast("涓婁紶鎴愬姛");
+ } catch (e) {
+ showToast("涓婁紶澶辫触");
+ }
+ };
-const removeUploaded = (index) => {
- fileList.value.splice(index, 1)
-}
+ const removeUploaded = index => {
+ fileList.value.splice(index, 1);
+ };
-const getFileNameFromUrl = (url) => {
- try {
- if (!url) return ''
- return decodeURIComponent(url.split('/').pop())
- } catch (e) {
- return url
- }
-}
+ const getFileNameFromUrl = url => {
+ try {
+ if (!url) return "";
+ return decodeURIComponent(url.split("/").pop());
+ } catch (e) {
+ return url;
+ }
+ };
-// 闄勪欢鏌ョ湅
-const openFileActions = (commonFiles) => {
- currentFilesToOpen = commonFiles || []
- fileActions.value = (commonFiles || []).map((f, idx) => ({ name: getFileNameFromUrl(f.url || ''), index: idx }))
- showFileSheet.value = true
-}
-const onSelectFile = async (action) => {
- try {
- const item = currentFilesToOpen[action.index]
- if (!item || !item.url) return
- showLoadingToast('涓嬭浇涓�...')
- uni.downloadFile({
- url: item.url,
- success: (res) => {
- closeToast()
- if (res.statusCode === 200) {
- uni.openDocument({ filePath: res.tempFilePath })
- } else {
- showToast('涓嬭浇澶辫触')
- }
- },
- fail: () => {
- closeToast()
- showToast('涓嬭浇澶辫触')
- }
- })
- } catch (e) {
- closeToast()
- showToast('鎵撳紑澶辫触')
- }
-}
+ // 闄勪欢鏌ョ湅
+ const openFileActions = commonFiles => {
+ currentFilesToOpen = commonFiles || [];
+ fileActions.value = (commonFiles || []).map((f, idx) => ({
+ name: getFileNameFromUrl(f.url || ""),
+ index: idx,
+ }));
+ showFileSheet.value = true;
+ };
+ const onSelectFile = async action => {
+ try {
+ const item = currentFilesToOpen[action.index];
+ if (!item || !item.url) return;
+ showLoadingToast("涓嬭浇涓�...");
+ uni.downloadFile({
+ url: item.url,
+ success: res => {
+ closeToast();
+ if (res.statusCode === 200) {
+ uni.openDocument({ filePath: res.tempFilePath });
+ } else {
+ showToast("涓嬭浇澶辫触");
+ }
+ },
+ fail: () => {
+ closeToast();
+ showToast("涓嬭浇澶辫触");
+ },
+ });
+ } catch (e) {
+ closeToast();
+ showToast("鎵撳紑澶辫触");
+ }
+ };
-onShow(() => {
- getList()
-})
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 寮�绁ㄥ彴璐︾壒鏈夋牱寮�
-.filter-popup {
- padding: 12px 12px 20px;
-}
+ // 寮�绁ㄥ彴璐︾壒鏈夋牱寮�
+ .filter-popup {
+ padding: 12px 12px 20px;
+ }
-.switch-row {
- padding: 12px 16px;
-}
+ .switch-row {
+ padding: 12px 16px;
+ }
-.filter-actions {
- display: flex;
- gap: 12px;
- padding: 12px 16px 16px;
- justify-content: space-between;
-}
+ .filter-actions {
+ display: flex;
+ gap: 12px;
+ padding: 12px 16px 16px;
+ justify-content: space-between;
+ }
-.edit-container {
- padding-bottom: 5rem;
-}
+ .edit-container {
+ padding-bottom: 5rem;
+ }
-.uploaded-list {
- padding: 8px 16px 0 16px;
-}
+ .uploaded-list {
+ padding: 8px 16px 0 16px;
+ }
-.uploaded-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 8px 0;
- border-bottom: 1px solid #f5f5f5;
-}
+ .uploaded-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 8px 0;
+ border-bottom: 1px solid #f5f5f5;
+ }
-.file-name {
- font-size: 12px;
- color: #333;
- margin-right: 8px;
- flex: 1;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
+ .file-name {
+ font-size: 12px;
+ color: #333;
+ margin-right: 8px;
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
-.tip-text {
- padding: 4px 16px 0 16px;
- font-size: 12px;
- color: #888;
-}
+ .tip-text {
+ padding: 4px 16px 0 16px;
+ font-size: 12px;
+ color: #888;
+ }
-.footer-btns {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background: #fff;
- display: flex;
- justify-content: space-around;
- align-items: center;
- padding: 0.75rem 0;
- box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
- z-index: 1000;
-}
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
-.cancel-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 6.375rem;
- background: #C7C9CC;
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
-.save-btn {
- font-weight: 400;
- font-size: 1rem;
- color: #FFFFFF;
- width: 14rem;
- background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
- box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
- border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/sales/invoicingRegistration/add.vue b/src/pages/sales/invoicingRegistration/add.vue
index 03be2cb..7a61fe7 100644
--- a/src/pages/sales/invoicingRegistration/add.vue
+++ b/src/pages/sales/invoicingRegistration/add.vue
@@ -386,10 +386,13 @@
return
}
- const submitData = {
- ...form.value,
- productList: productData.value
- }
+ // 鍚庣瑕佹眰浠ユ暟缁勫舰寮忔彁浜わ細淇濇寔鍘熸潵鐨勫璞$粨鏋勪笉鍙橈紝鍙湪鏈�澶栧眰鍖呬竴灞傛暟缁�
+ const submitData = [
+ {
+ ...form.value,
+ productList: productData.value
+ }
+ ]
await invoiceRegistrationSave(submitData)
showToast('鎻愪氦鎴愬姛')
diff --git a/src/pages/sales/invoicingRegistration/index.vue b/src/pages/sales/invoicingRegistration/index.vue
index 132da11..6b31c48 100644
--- a/src/pages/sales/invoicingRegistration/index.vue
+++ b/src/pages/sales/invoicingRegistration/index.vue
@@ -1,252 +1,252 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="寮�绁ㄧ櫥璁�" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
- v-model="customerName"
- clearable
- @change="getList"
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 閿�鍞彴璐︾�戝竷娴� -->
- <view class="ledger-list" v-if="total > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">涓氬姟鍛�</text>
- <text class="detail-value">{{ item.salesman }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ item.contractAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">宸插紑绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value highlight">{{ item.invoiceTotal }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鏈紑绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value redlight">{{ item.noInvoiceAmountTotal }}</text>
- </view>
- </view>
-
- <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
- <view class="action-buttons">
- <up-button
- type="primary"
- size="small"
- @click="handleAddInvoice(item)"
- class="action-btn"
- :disabled="item.noInvoiceAmountTotal == 0"
- >
- 鏂板寮�绁�
- </up-button>
- <up-button
- size="small"
- @click="handleViewDetail(item)"
- class="action-btn"
- >
- 鏌ョ湅璇︽儏
- </up-button>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="寮�绁ㄧ櫥璁�"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
+ v-model="customerName"
+ clearable
+ @change="getList" />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 閿�鍞彴璐︾�戝竷娴� -->
+ <view class="ledger-list"
+ v-if="total > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓氬姟鍛�</text>
+ <text class="detail-value">{{ item.salesman }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸插紑绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value highlight">{{ item.invoiceTotal }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鏈紑绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value redlight">{{ item.noInvoiceAmountTotal }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳鍖哄煙 -->
+ <view class="action-buttons">
+ <!-- <up-button type="primary"
+ size="small"
+ @click="handleAddInvoice(item)"
+ class="action-btn"
+ :disabled="item.noInvoiceAmountTotal == 0">
+ 鏂板寮�绁�
+ </up-button> -->
+ <up-button size="small"
+ @click="handleViewDetail(item)"
+ class="action-btn">
+ 鏌ョ湅璇︽儏
+ </up-button>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {ledgerListPage} from "@/api/salesManagement/salesLedger";
-import useUserStore from "@/store/modules/user";
-const userStore = useUserStore()
+ import { ref } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { ledgerListPage } from "@/api/salesManagement/salesLedger";
+ import useUserStore from "@/store/modules/user";
+ const userStore = useUserStore();
-// 鎼滅储鍏抽敭璇�
-const customerName = ref('');
+ // 鎼滅储鍏抽敭璇�
+ const customerName = ref("");
-// 閿�鍞彴璐︽暟鎹�
-const ledgerList = ref([]);
-const total = ref(0);
+ // 閿�鍞彴璐︽暟鎹�
+ const ledgerList = ref([]);
+ const total = ref(0);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1
- }
- ledgerListPage({...page, customerName: customerName.value}).then((res) => {
- ledgerList.value = res.records;
- total.value = res.total;
- closeToast()
- }).catch(() => {
- closeToast()
- });
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ ledgerListPage({ ...page, customerName: customerName.value })
+ .then(res => {
+ ledgerList.value = res.records;
+ // total.value = res.total;
+ total.value = 100;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 澶勭悊鏂板寮�绁�
-const handleAddInvoice = (item) => {
- try {
- // 瀛樺偍閫変腑鐨勫悎鍚屼俊鎭�
- uni.setStorageSync('editData', JSON.stringify(item));
-
- // 璺宠浆鍒版柊澧炲紑绁ㄩ〉闈�
- uni.navigateTo({
- url: '/pages/sales/invoicingRegistration/add'
- });
- } catch (error) {
- console.error('澶勭悊鏂板寮�绁ㄥけ璐�:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 澶勭悊鏂板寮�绁�
+ const handleAddInvoice = item => {
+ try {
+ // 瀛樺偍閫変腑鐨勫悎鍚屼俊鎭�
+ uni.setStorageSync("editData", JSON.stringify(item));
-// 澶勭悊鏌ョ湅璇︽儏
-const handleViewDetail = (item) => {
- try {
- // 瀛樺偍鏁版嵁
- uni.setStorageSync('editData', JSON.stringify(item));
-
- // 璺宠浆鍒拌鎯呴〉闈�
- uni.navigateTo({
- url: '/pages/sales/invoicingRegistration/view'
- });
- } catch (error) {
- console.error('澶勭悊鏌ョ湅璇︽儏澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 璺宠浆鍒版柊澧炲紑绁ㄩ〉闈�
+ uni.navigateTo({
+ url: "/pages/sales/invoicingRegistration/add",
+ });
+ } catch (error) {
+ console.error("澶勭悊鏂板寮�绁ㄥけ璐�:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 澶勭悊鏌ョ湅璇︽儏
+ const handleViewDetail = item => {
+ try {
+ // 瀛樺偍鏁版嵁
+ uni.setStorageSync("editData", JSON.stringify(item));
+
+ // 璺宠浆鍒拌鎯呴〉闈�
+ uni.navigateTo({
+ url: "/pages/sales/invoicingRegistration/view",
+ });
+ } catch (error) {
+ console.error("澶勭悊鏌ョ湅璇︽儏澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 寮�绁ㄧ櫥璁扮壒鏈夋牱寮�
-.nav-icon {
- width: 24px;
- height: 24px;
- background: #2979ff;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ // 寮�绁ㄧ櫥璁扮壒鏈夋牱寮�
+ .nav-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.nav-text {
- font-size: 14px;
- color: #2979ff;
- font-weight: 500;
-}
+ .nav-text {
+ font-size: 14px;
+ color: #2979ff;
+ font-weight: 500;
+ }
-.header-center {
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- position: absolute;
- left: 0;
- right: 0;
- pointer-events: none;
-}
+ .header-center {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ left: 0;
+ right: 0;
+ pointer-events: none;
+ }
-.page-title {
- font-size: 18px;
- font-weight: 600;
- color: #333;
- pointer-events: auto;
-}
+ .page-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ pointer-events: auto;
+ }
-.header-right {
- display: flex;
- align-items: center;
-}
+ .header-right {
+ display: flex;
+ align-items: center;
+ }
-.status-bar {
- display: flex;
- align-items: center;
- gap: 4px;
-}
+ .status-bar {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ }
-.signal, .wifi, .battery {
- width: 16px;
- height: 8px;
- background: #333;
- border-radius: 2px;
-}
+ .signal,
+ .wifi,
+ .battery {
+ width: 16px;
+ height: 8px;
+ background: #333;
+ border-radius: 2px;
+ }
-.detail-value.redlight {
- color: red;
- font-weight: 500;
-}
+ .detail-value.redlight {
+ color: red;
+ font-weight: 500;
+ }
-.fab-button {
- bottom: 30px; // 涓庡叾浠栭〉闈㈢殑 calc(30px + env(safe-area-inset-bottom)) 涓嶅悓
-}
+ .fab-button {
+ bottom: 30px; // 涓庡叾浠栭〉闈㈢殑 calc(30px + env(safe-area-inset-bottom)) 涓嶅悓
+ }
</style>
diff --git a/src/pages/sales/invoicingRegistration/view.vue b/src/pages/sales/invoicingRegistration/view.vue
index 85f1001..72828ff 100644
--- a/src/pages/sales/invoicingRegistration/view.vue
+++ b/src/pages/sales/invoicingRegistration/view.vue
@@ -12,10 +12,6 @@
<text class="info-value">{{ form.salesContractNo }}</text>
</view>
<view class="info-item">
- <text class="info-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="info-value highlight">{{ form.customerContractNo }}</text>
- </view>
- <view class="info-item">
<text class="info-label">瀹㈡埛鍚嶇О</text>
<text class="info-value">{{ form.customerName }}</text>
</view>
@@ -123,7 +119,6 @@
const form = ref({
id: '',
salesContractNo: '',
- customerContractNo: '',
customerId: '',
customerName: '',
projectName: '',
diff --git a/src/pages/sales/receiptPayment/add.vue b/src/pages/sales/receiptPayment/add.vue
index 3c88333..594ac23 100644
--- a/src/pages/sales/receiptPayment/add.vue
+++ b/src/pages/sales/receiptPayment/add.vue
@@ -1,27 +1,29 @@
<template>
<view class="account-detail">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鏂板鍥炴" @back="onClickLeft" />
-
+ <PageHeader title="鏂板鍥炴"
+ @back="onClickLeft" />
<!-- 琛ㄥ崟鍐呭 -->
- <u-form @submit="onSubmit" ref="formRef" label-width="110" input-align="right" error-message-align="right">
+ <u-form @submit="onSubmit"
+ ref="formRef"
+ label-width="110"
+ input-align="right"
+ error-message-align="right">
<!-- 鍩烘湰淇℃伅 -->
<u-cell-group title="鍩烘湰淇℃伅">
- <u-form-item label="閿�鍞悎鍚屽彿" border-bottom>
- <u-input
- v-model="form.salesContractNo"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="閿�鍞悎鍚屽彿"
+ border-bottom>
+ <u-input v-model="form.salesContractNo"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="瀹㈡埛鍚嶇О" border-bottom>
- <u-input
- v-model="form.customerName"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="瀹㈡埛鍚嶇О"
+ border-bottom>
+ <u-input v-model="form.customerName"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="鍙戠エ鍙�" border-bottom>
+ <!-- <u-form-item label="鍙戠エ鍙�" border-bottom>
<u-input
v-model="form.invoiceNo"
placeholder="鑷姩濉厖"
@@ -34,255 +36,270 @@
placeholder="鑷姩濉厖"
readonly
/>
+ </u-form-item> -->
+ <u-form-item label="绋庣巼"
+ border-bottom>
+ <u-input v-model="form.taxRate"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
- <u-form-item label="绋庣巼" border-bottom>
- <u-input
- v-model="form.taxRate"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <view class="tip-text">寰呭洖娆鹃噾棰濓細{{ form.pendingInvoiceTotal }} 鍏�</view>
+ <u-form-item label="鏈鍥炴閲戦"
+ prop="receiptPaymentAmount"
+ required
+ border-bottom>
+ <u-input v-model="form.receiptPaymentAmount"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="changeNum"
+ clearable />
</u-form-item>
- <view class="tip-text">寰呭洖娆鹃噾棰濓細{{ currentNoReceiptAmount }} 鍏�</view>
- <u-form-item label="鏈鍥炴閲戦" prop="receiptPaymentAmount" required border-bottom>
- <u-input
- v-model="form.receiptPaymentAmount"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="changeNum"
- clearable
- />
- </u-form-item>
- <u-form-item label="鍥炴褰㈠紡" prop="receiptPaymentTypeName" required border-bottom>
- <u-input
- v-model="form.receiptPaymentTypeName"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showPaymentTypePicker"
- />
+ <u-form-item label="鍥炴褰㈠紡"
+ prop="receiptPaymentTypeName"
+ required
+ border-bottom>
+ <u-input v-model="form.receiptPaymentTypeName"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showPaymentTypePicker" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showPaymentTypePicker"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showPaymentTypePicker"></up-icon>
+ </template>
</u-form-item>
- <u-form-item label="鏉ユ鏃ユ湡" prop="receiptPaymentDate" required border-bottom>
- <u-input
- v-model="form.receiptPaymentDate"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showDatePicker"
- />
+ <u-form-item label="鏉ユ鏃ユ湡"
+ prop="receiptPaymentDate"
+ required
+ border-bottom>
+ <u-input v-model="form.receiptPaymentDate"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showDatePicker" />
<template #right>
- <up-icon
- name="arrow-right"
- @click="showDatePicker"
- ></up-icon>
- </template>
+ <up-icon name="arrow-right"
+ @click="showDatePicker"></up-icon>
+ </template>
</u-form-item>
- <u-form-item label="鐧昏浜�" border-bottom>
- <u-input
- v-model="form.registrant"
- placeholder="鑷姩濉厖"
- readonly
- />
+ <u-form-item label="鐧昏浜�"
+ border-bottom>
+ <u-input v-model="form.registrant"
+ placeholder="鑷姩濉厖"
+ readonly />
</u-form-item>
</u-cell-group>
-
<!-- 鎻愪氦鎸夐挳 -->
- <FooterButtons
- cancelText="鍙栨秷"
- confirmText="淇濆瓨"
- :loading="loading"
- @cancel="onClickLeft"
- @confirm="onSubmit"
- />
+ <FooterButtons cancelText="鍙栨秷"
+ confirmText="淇濆瓨"
+ :loading="loading"
+ @cancel="onClickLeft"
+ @confirm="onSubmit" />
</u-form>
-
<!-- 鍥炴鏂瑰紡閫夋嫨鍣� -->
- <up-action-sheet
- :show="showPaymentType"
- :actions="receiptPaymentType"
- title="閫夋嫨鍥炴褰㈠紡"
- @select="onPaymentTypeConfirm"
- @close="showPaymentType = false"
- />
-
+ <up-action-sheet :show="showPaymentType"
+ :actions="receiptPaymentType"
+ title="閫夋嫨鍥炴褰㈠紡"
+ @select="onPaymentTypeConfirm"
+ @close="showPaymentType = false" />
<!-- 鏃ユ湡閫夋嫨鍣� -->
- <up-popup :show="showDate" mode="bottom" @close="showDate = false">
- <up-datetime-picker
- :show="true"
- v-model="currentDate"
- @confirm="onDateConfirm"
- @cancel="showDate = false"
- mode="date"
- />
+ <up-popup :show="showDate"
+ mode="bottom"
+ @close="showDate = false">
+ <up-datetime-picker :show="true"
+ v-model="currentDate"
+ @confirm="onDateConfirm"
+ @cancel="showDate = false"
+ mode="date" />
</up-popup>
</view>
</template>
<script setup>
-import { ref, onMounted, computed } from 'vue'
-import FooterButtons from '@/components/FooterButtons.vue'
-import { receiptPaymentSaveOrUpdate, invoiceInfo } from '@/api/salesManagement/receiptPayment'
-import useUserStore from '@/store/modules/user'
-import { useDict } from '@/utils/dict'
-import { formatDateToYMD } from '@/utils/ruoyi'
+ import { ref, onMounted, computed } from "vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
+ import {
+ receiptPaymentSaveOrUpdate,
+ invoiceInfo,
+ } from "@/api/salesManagement/receiptPayment";
+ import useUserStore from "@/store/modules/user";
+ import { useDict } from "@/utils/dict";
+ import { formatDateToYMD } from "@/utils/ruoyi";
-// 鏄剧ず鎻愮ず淇℃伅
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏄剧ず鎻愮ず淇℃伅
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鍔犺浇鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ const userStore = useUserStore();
+
+ // 琛ㄥ崟寮曠敤
+ const formRef = ref();
+
+ // 鍝嶅簲寮忔暟鎹�
+ const loading = ref(false);
+ const showPaymentType = ref(false);
+ const pickerValue = ref([]);
+ const showDate = ref(false);
+ const currentDate = ref([
+ new Date().getFullYear(),
+ new Date().getMonth() + 1,
+ new Date().getDate(),
+ ]);
+
+ // 琛ㄥ崟鏁版嵁
+ const form = ref({
+ salesContractNo: "",
+ customerName: "",
+ invoiceNo: "",
+ invoiceTotal: "",
+ taxRate: "",
+ receiptPaymentAmount: "",
+ receiptPaymentType: "",
+ receiptPaymentTypeName: "",
+ registrant: "",
+ receiptPaymentDate: "",
+ invoiceLedgerId: "",
+ salesLedgerProductId: "",
});
-};
+ const currentNoReceiptAmount = ref(0);
-// 鍏抽棴鍔犺浇鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鑾峰彇瀛楀吀鏁版嵁
+ const { receipt_payment_type: dictReceiptPaymentType } = useDict(
+ "receipt_payment_type"
+ );
-const userStore = useUserStore()
+ // 杞崲瀛楀吀鏁版嵁鏍煎紡涓洪�夋嫨鍣ㄩ渶瑕佺殑鏍煎紡
+ const receiptPaymentType = computed(() => {
+ return dictReceiptPaymentType.value.map(item => ({
+ name: item.label,
+ value: item.value,
+ }));
+ });
-// 琛ㄥ崟寮曠敤
-const formRef = ref()
+ // 杩斿洖涓婁竴椤�
+ const onClickLeft = () => {
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.navigateBack();
+ };
-// 鍝嶅簲寮忔暟鎹�
-const loading = ref(false)
-const showPaymentType = ref(false)
-const pickerValue = ref([])
-const showDate = ref(false)
-const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()])
+ // 鏄剧ず鍥炴鏂瑰紡閫夋嫨鍣�
+ const showPaymentTypePicker = () => {
+ showPaymentType.value = true;
+ };
+ const changeNum = () => {
+ if (form.value.receiptPaymentAmount > form.value.pendingInvoiceTotal) {
+ form.value.receiptPaymentAmount = form.value.pendingInvoiceTotal;
+ showToast("涓嶅彲澶т簬寰呭洖娆鹃噾棰�");
+ }
+ };
-// 琛ㄥ崟鏁版嵁
-const form = ref({
- salesContractNo: '',
- customerName: '',
- invoiceNo: '',
- invoiceTotal: '',
- taxRate: '',
- receiptPaymentAmount: '',
- receiptPaymentType: '',
- receiptPaymentTypeName: '',
- registrant: '',
- receiptPaymentDate: '',
- invoiceLedgerId: ''
-})
-const currentNoReceiptAmount = ref(0)
+ // 纭鍥炴鏂瑰紡閫夋嫨
+ const onPaymentTypeConfirm = action => {
+ form.value.receiptPaymentType = action.value;
+ form.value.receiptPaymentTypeName = action.name;
+ showPaymentType.value = false;
+ };
-// 鑾峰彇瀛楀吀鏁版嵁
-const { receipt_payment_type: dictReceiptPaymentType } = useDict('receipt_payment_type')
+ // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+ const showDatePicker = () => {
+ showDate.value = true;
+ };
-// 杞崲瀛楀吀鏁版嵁鏍煎紡涓洪�夋嫨鍣ㄩ渶瑕佺殑鏍煎紡
-const receiptPaymentType = computed(() => {
- return dictReceiptPaymentType.value.map(item => ({
- name: item.label,
- value: item.value
- }))
-})
+ // 纭鏃ユ湡閫夋嫨
+ const onDateConfirm = e => {
+ form.value.receiptPaymentDate = formatDateToYMD(e.value);
+ currentDate.value = formatDateToYMD(e.value);
+ showDate.value = false;
+ };
-// 杩斿洖涓婁竴椤�
-const onClickLeft = () => {
- uni.removeStorageSync('invoiceLedgerEditRow');
- uni.navigateBack()
-}
+ // 鎻愪氦琛ㄥ崟
+ const onSubmit = () => {
+ // 琛ㄥ崟楠岃瘉
+ if (!form.value.receiptPaymentAmount) {
+ showToast("璇疯緭鍏ュ洖娆鹃噾棰�");
+ return;
+ }
-// 鏄剧ず鍥炴鏂瑰紡閫夋嫨鍣�
-const showPaymentTypePicker = () => {
- showPaymentType.value = true
-}
-const changeNum = () => {
- if (form.value.receiptPaymentAmount > currentNoReceiptAmount.value) {
- form.value.receiptPaymentAmount = currentNoReceiptAmount.value
- showToast('涓嶅彲澶т簬寰呭洖娆鹃噾棰�')
- }
-}
+ if (!form.value.receiptPaymentType) {
+ showToast("璇烽�夋嫨鍥炴褰㈠紡");
+ return;
+ }
-// 纭鍥炴鏂瑰紡閫夋嫨
-const onPaymentTypeConfirm = (action) => {
- form.value.receiptPaymentType = action.value
- form.value.receiptPaymentTypeName = action.name
- showPaymentType.value = false
-}
+ if (!form.value.receiptPaymentDate) {
+ showToast("璇烽�夋嫨鏉ユ鏃ユ湡");
+ return;
+ }
-// 鏄剧ず鏃ユ湡閫夋嫨鍣�
-const showDatePicker = () => {
- showDate.value = true
-}
+ loading.value = true;
+ form.value.receiptPaymentAmount = Number(form.value.receiptPaymentAmount);
+ receiptPaymentSaveOrUpdate([form.value])
+ .then(() => {
+ showToast("鎻愪氦鎴愬姛");
+ // 閫氱煡涓婁竴椤靛埛鏂版暟鎹�
+ const pages = getCurrentPages();
+ const prevPage = pages[pages.length - 2];
+ if (prevPage && prevPage.$vm && prevPage.$vm.getList) {
+ prevPage.$vm.getList();
+ }
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.navigateBack();
+ })
+ .catch(error => {
+ loading.value = false;
+ });
+ };
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
- form.value.receiptPaymentDate = formatDateToYMD(e.value)
- currentDate.value = formatDateToYMD(e.value)
- showDate.value = false;
-}
+ // 鍒濆鍖栨暟鎹�
+ const initData = () => {
+ const rowStr = uni.getStorageSync("invoiceLedgerEditRow");
+ const row = JSON.parse(rowStr);
+ form.value = { ...row };
+ form.value.invoiceLedgerId = form.value.id;
+ form.value.salesLedgerProductId = form.value.id;
+ form.value.id = "";
+ currentNoReceiptAmount.value = row.noReceiptAmount;
+ form.value.registrant = userStore.nickName;
-// 鎻愪氦琛ㄥ崟
-const onSubmit = () => {
- // 琛ㄥ崟楠岃瘉
- if (!form.value.receiptPaymentAmount) {
- showToast('璇疯緭鍏ュ洖娆鹃噾棰�')
- return
- }
-
- if (!form.value.receiptPaymentType) {
- showToast('璇烽�夋嫨鍥炴褰㈠紡')
- return
- }
-
- if (!form.value.receiptPaymentDate) {
- showToast('璇烽�夋嫨鏉ユ鏃ユ湡')
- return
- }
+ // invoiceInfo({ id: row.id })
+ // .then(res => {
+ // const data = res.data;
+ // form.value = { ...data };
+ // form.value.invoiceLedgerId = form.value.id;
+ // form.value.id = "";
+ // currentNoReceiptAmount.value = row.noReceiptAmount;
+ // form.value.registrant = userStore.nickName;
+ // })
+ // .catch(() => {
+ // showToast("鑾峰彇鏁版嵁澶辫触");
+ // });
+ };
- loading.value = true
-
- receiptPaymentSaveOrUpdate(form.value)
- .then(() => {
- showToast('鎻愪氦鎴愬姛')
- // 閫氱煡涓婁竴椤靛埛鏂版暟鎹�
- const pages = getCurrentPages();
- const prevPage = pages[pages.length - 2];
- if (prevPage && prevPage.$vm && prevPage.$vm.getList) {
- prevPage.$vm.getList();
- }
- uni.removeStorageSync('invoiceLedgerEditRow');
- uni.navigateBack()
- })
- .catch((error) => {
- loading.value = false
- })
-}
-
-// 鍒濆鍖栨暟鎹�
-const initData = () => {
- const rowStr = uni.getStorageSync('invoiceLedgerEditRow')
- const row = JSON.parse(rowStr)
- invoiceInfo({ id: row.id }).then((res) => {
- const data = res.data
- form.value = { ...data}
- form.value.invoiceLedgerId = form.value.id;
- form.value.id = "";
- currentNoReceiptAmount.value = row.noReceiptAmount
- form.value.registrant = userStore.nickName
- }).catch(() => {
- showToast('鑾峰彇鏁版嵁澶辫触')
- })
-}
-
-onMounted(() => {
- initData()
-})
+ onMounted(() => {
+ initData();
+ });
</script>
<style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
+ .tip-text {
+ font-size: 14px;
+ color: #999;
+ margin-top: 20rpx;
+ margin-bottom: 20rpx;
+ }
</style>
diff --git a/src/pages/sales/receiptPayment/index.vue b/src/pages/sales/receiptPayment/index.vue
index a98b3db..407450f 100644
--- a/src/pages/sales/receiptPayment/index.vue
+++ b/src/pages/sales/receiptPayment/index.vue
@@ -1,204 +1,206 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鍥炴鐧昏" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
- v-model="searchForm.customerName"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
-
- <!-- 绛涢�夊紑鍏� -->
- <view class="switch-row">
- <text class="switch-label">涓嶆樉绀哄緟鍥炴涓�0</text>
- <up-switch v-model="searchForm.status" @change="getList" size="18"/>
- </view>
- </view>
-
-
-
- <!-- 鍒楄〃鍖哄煙 -->
- <view class="ledger-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index">
- <view class="ledger-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浜у搧澶х被</text>
- <text class="detail-value">{{ item.productCategory }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ鍙�</text>
- <text class="detail-value">{{ item.invoiceNo || '-' }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍙戠エ閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatNumber(item.invoiceTotal) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">绋庣巼(%)</text>
- <text class="detail-value">{{ item.taxRate }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍥炴閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatNumber(item.receiptPaymentAmountTotal) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">寰呭洖娆鹃噾棰�(鍏�)</text>
- <text class="detail-value danger">{{ formatNumber(item.noReceiptAmount) }}</text>
- </view>
- </view>
-
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="action-buttons">
- <up-button
- type="primary"
- size="small"
- class="action-btn"
- :disabled="item.noReceiptAmount == 0"
- @click="openForm(item)"
- >
- 鏂板鍥炴
- </up-button>
- </view>
- </view>
- </view>
- </view>
-
- <!-- 鏃犳暟鎹彁绀� -->
- <view class="no-data" v-else>
- <text>鏆傛棤鍥炴鏁版嵁</text>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍥炴鐧昏"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
+ v-model="searchForm.customerName"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ <!-- 绛涢�夊紑鍏� -->
+ <view class="switch-row">
+ <text class="switch-label">涓嶆樉绀哄緟鍥炴涓�0</text>
+ <up-switch v-model="searchForm.status"
+ @change="getList"
+ size="18" />
+ </view>
+ </view>
+ <!-- 鍒楄〃鍖哄煙 -->
+ <view class="ledger-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="item-tag">
+ <u-tag :type="getTagClass(item.statusName)">{{ item.statusName || '--' }}</u-tag>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绋庣巼(%)</text>
+ <text class="detail-value">{{ item.taxRate }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍥炴閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatNumber(item.invoiceTotal) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">寰呭洖娆鹃噾棰�(鍏�)</text>
+ <text class="detail-value danger">{{ formatNumber(item.pendingInvoiceTotal) }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <!-- <view class="action-buttons">
+ <up-button type="primary"
+ size="small"
+ class="action-btn"
+ :disabled="item.noReceiptAmount == 0"
+ @click="openForm(item)">
+ 鏂板鍥炴
+ </up-button>
+ </view> -->
+ </view>
+ </view>
+ </view>
+ <!-- 鏃犳暟鎹彁绀� -->
+ <view class="no-data"
+ v-else>
+ <text>鏆傛棤鍥炴鏁版嵁</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref } from 'vue'
-import {
- bindInvoiceNoRegPage,
-} from '@/api/salesManagement/receiptPayment'
-import useUserStore from '@/store/modules/user'
+ import { ref } from "vue";
+ import { bindInvoiceNoRegPage } from "@/api/salesManagement/receiptPayment";
+ import useUserStore from "@/store/modules/user";
-// 鏄剧ず鎻愮ず淇℃伅
-const showToast = (message) => {
- uni.showToast({
- title: message,
- icon: 'none'
- })
-}
+ // 鏄剧ず鎻愮ず淇℃伅
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鍔犺浇鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鍔犺浇鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-import {onShow} from "@dcloudio/uni-app";
+ import { onShow } from "@dcloudio/uni-app";
-// 鍝嶅簲寮忔暟鎹�
-const tableData = ref([])
-const tableLoading = ref(false)
+ // 鍝嶅簲寮忔暟鎹�
+ const tableData = ref([]);
+ const tableLoading = ref(false);
-// 鏌ヨ鍙傛暟璁剧疆涓�-1鑾峰彇鍏ㄩ儴鏁版嵁
-const page = ref({
- current: -1,
- size: -1
-})
+ // 鏌ヨ鍙傛暟璁剧疆涓�-1鑾峰彇鍏ㄩ儴鏁版嵁
+ const page = ref({
+ current: -1,
+ size: -1,
+ });
-// 鎼滅储琛ㄥ崟
-const searchForm = ref({
- customerName: '',
- status: true,
- customerContractNo: '',
- projectName: ''
-})
+ // 鎼滅储琛ㄥ崟
+ const searchForm = ref({
+ customerName: "",
+ status: true,
+ projectName: "",
+ });
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (!type) {
+ return "info";
+ }
+ if (type == "鏈畬鎴愪粯娆�") {
+ return "warning";
+ } else {
+ return "success";
+ }
+ };
+ // 鏍煎紡鍖栨暟瀛�
+ const formatNumber = value => {
+ return parseFloat(value || 0).toFixed(2);
+ };
-// 鏍煎紡鍖栨暟瀛�
-const formatNumber = (value) => {
- return parseFloat(value || 0).toFixed(2)
-}
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
+ // 鑾峰彇鍒楄〃鏁版嵁
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ bindInvoiceNoRegPage({ ...searchForm.value, ...page.value })
+ .then(res => {
+ tableData.value = res.data.records || [];
+ })
+ .catch(() => {
+ showToast("鑾峰彇鏁版嵁澶辫触");
+ })
+ .finally(() => {
+ closeToast();
+ });
+ };
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- bindInvoiceNoRegPage({ ...searchForm.value, ...page.value })
- .then((res) => {
- tableData.value = res.data.records || []
- })
- .catch(() => {
- showToast('鑾峰彇鏁版嵁澶辫触')
- })
- .finally(() => {
- closeToast()
- })
-}
+ // 鎵撳紑鏂板琛ㄥ崟
+ const openForm = item => {
+ if (item.noReceiptAmount == 0) {
+ showToast("鏃犻渶鍐嶅洖娆�");
+ return;
+ }
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+ uni.navigateTo({ url: "/pages/sales/receiptPayment/add" });
+ };
-// 鎵撳紑鏂板琛ㄥ崟
-const openForm = (item) => {
- if (item.noReceiptAmount == 0) {
- showToast('鏃犻渶鍐嶅洖娆�')
- return
- }
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item))
- uni.navigateTo({ url: '/pages/sales/receiptPayment/add' })
-}
-
-onShow(() => {
- getList()
-})
+ onShow(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 鍥炴鐧昏鐗规湁鏍峰紡
-.detail-value {
- display: flex;
- align-items: center;
- justify-content: flex-end;
-}
+ // 鍥炴鐧昏鐗规湁鏍峰紡
+ .detail-value {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/sales/receiptPaymentHistory/index.vue b/src/pages/sales/receiptPaymentHistory/index.vue
index a25e98d..5954b0f 100644
--- a/src/pages/sales/receiptPaymentHistory/index.vue
+++ b/src/pages/sales/receiptPaymentHistory/index.vue
@@ -1,87 +1,90 @@
<template>
- <view class="receipt-payment-history">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鍥炴娴佹按" @back="goBack" />
-
- <!-- 鎼滅储鍖哄煙 -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
- v-model="searchForm.searchText"
- @change="getList"
- clearable
- />
- </view>
- <view class="search-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
- <!-- 缁熻淇℃伅 -->
- <view class="summary-info" v-if="tableData.length > 0">
- <view class="summary-item">
- <text class="summary-label">鎬昏褰曟暟</text>
- <text class="summary-value">{{ tableData.length }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">鎬婚噾棰�</text>
- <text class="summary-value highlight">{{ formatAmount(totalAmount) }}</text>
- </view>
- </view>
- <!-- 鍥炴鍘嗗彶鍒楄〃 -->
- <view class="history-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index">
- <view class="history-item">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- <view class="item-tag" :class="getTagClass(item.receiptPaymentType)">
- <text class="tag-text">{{ formatReceiptType(item.receiptPaymentType) }}</text>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍥炴鏃ユ湡</text>
- <text class="detail-value">{{ item.receiptPaymentDate }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍥炴閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.receiptPaymentAmount) }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row">
- <text class="detail-label">鐧昏浜�</text>
- <text class="detail-value">{{ item.registrant }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鐧昏鏃ユ湡</text>
- <text class="detail-value">{{ item.createTime }}</text>
- </view>
- </view>
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="action-buttons">
- <u-button
+ <view class="receipt-payment-history">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍥炴娴佹按"
+ @back="goBack" />
+ <!-- 鎼滅储鍖哄煙 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉版悳绱�"
+ v-model="searchForm.searchText"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info"
+ v-if="tableData.length > 0">
+ <view class="summary-item">
+ <text class="summary-label">鎬昏褰曟暟</text>
+ <text class="summary-value">{{ tableData.length }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鎬婚噾棰�</text>
+ <text class="summary-value highlight">{{ formatAmount(totalAmount) }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴鍘嗗彶鍒楄〃 -->
+ <view class="history-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index">
+ <view class="history-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="item-tag"
+ :class="getTagClass(item.receiptPaymentType)">
+ <text class="tag-text">{{ formatReceiptType(item.receiptPaymentType) }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍥炴鏃ユ湡</text>
+ <text class="detail-value">{{ item.receiptPaymentDate }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍥炴閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.receiptPaymentAmount) }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">鐧昏浜�</text>
+ <text class="detail-value">{{ item.registrant }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鐧昏鏃ユ湡</text>
+ <text class="detail-value">{{ item.createTime }}</text>
+ </view>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="action-buttons">
+ <!-- <u-button
type="primary"
size="small"
class="action-btn"
@@ -89,152 +92,184 @@
@click="openForm(item)"
>
缂栬緫鍥炴
- </u-button>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤鍥炴鍘嗗彶鏁版嵁</text>
- </view>
- </view>
+ </u-button> -->
+ <!-- <u-button type="error"
+ size="small"
+ class="action-btn"
+ :disabled="item.registrant !== userStore.nickName"
+ @click="delitem(item)">
+ 鍒犻櫎
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴鍘嗗彶鏁版嵁</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref, computed } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import { receiptPaymentHistoryListPage } from "@/api/salesManagement/receiptPayment.js";
-import useUserStore from "@/store/modules/user";
-const userStore = useUserStore()
+ import { ref, computed } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import {
+ receiptPaymentHistoryListPage,
+ receiptPaymentDel,
+ } from "@/api/salesManagement/receiptPayment.js";
+ import useUserStore from "@/store/modules/user";
+ const userStore = useUserStore();
-// 鎼滅储琛ㄥ崟
-const searchForm = ref({
- searchText: '',
-});
+ // 鎼滅储琛ㄥ崟
+ const searchForm = ref({
+ searchText: "",
+ });
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([]);
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
-// 鍒嗛〉鍙傛暟
-const page = ref({
- current: -1,
- size: -1,
-});
+ // 鍒嗛〉鍙傛暟
+ const page = ref({
+ current: -1,
+ size: -1,
+ });
-const totalAmount = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.receiptPaymentAmount) || 0);
- }, 0);
-});
+ const totalAmount = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.receiptPaymentAmount) || 0);
+ }, 0);
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ const delitem = item => {
+ uni.showModal({
+ title: "纭鍒犻櫎",
+ content: `纭畾鍒犻櫎璇ュ洖娆捐褰曞悧锛焋,
+ success: res => {
+ if (res.confirm) {
+ // 璋冪敤鍒犻櫎鎺ュ彛
+ receiptPaymentDel([item.id]).then(() => {
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ // 鍒锋柊鍒楄〃
+ getList();
+ });
+ }
+ },
+ });
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const params = {
- ...searchForm.value,
- ...page.value
- };
- receiptPaymentHistoryListPage(params).then((res) => {
- tableData.value = res.records;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const params = {
+ ...searchForm.value,
+ ...page.value,
+ };
+ receiptPaymentHistoryListPage(params)
+ .then(res => {
+ tableData.value = res.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鏍煎紡鍖栧洖娆炬柟寮�
-const formatReceiptType = (type) => {
- if (type == 0) {
- return "鐢垫眹";
- } else if (type == 1) {
- return "鎵垮厬";
- } else {
- return "鏈煡";
- }
-};
+ // 鏍煎紡鍖栧洖娆炬柟寮�
+ const formatReceiptType = type => {
+ if (type == 0) {
+ return "鐢垫眹";
+ } else if (type == 1) {
+ return "鎵垮厬";
+ } else {
+ return "鏈煡";
+ }
+ };
-// 鑾峰彇鏍囩鏍峰紡绫�
-const getTagClass = (type) => {
- if (type == 0) {
- return "tag-electric";
- } else if (type == 1) {
- return "tag-acceptance";
- } else {
- return "tag-unknown";
- }
-};
+ // 鑾峰彇鏍囩鏍峰紡绫�
+ const getTagClass = type => {
+ if (type == 0) {
+ return "tag-electric";
+ } else if (type == 1) {
+ return "tag-acceptance";
+ } else {
+ return "tag-unknown";
+ }
+ };
-// 鏍煎紡鍖栭噾棰�
-const formatAmount = (amount) => {
- return amount ? parseFloat(amount).toFixed(2) : '0.00';
-};
-// 鎵撳紑缂栬緫琛ㄥ崟
-const openForm = (item) => {
- uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item))
- uni.navigateTo({ url: '/pages/sales/receiptPayment/edit' })
-}
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 鏍煎紡鍖栭噾棰�
+ const formatAmount = amount => {
+ return amount ? parseFloat(amount).toFixed(2) : "0.00";
+ };
+ // 鎵撳紑缂栬緫琛ㄥ崟
+ const openForm = item => {
+ uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+ uni.navigateTo({ url: "/pages/sales/receiptPayment/edit" });
+ };
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 鍥炴娴佹按鐗规湁鏍峰紡
-.receipt-payment-history {
- min-height: 100vh;
- background: #f8f9fa;
- position: relative;
-}
+ // 鍥炴娴佹按鐗规湁鏍峰紡
+ .receipt-payment-history {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
-.action-buttons {
- padding: 12px 0 0 0; // 涓庡叕鍏辨牱寮忎腑鐨� 0 0 16px 0 涓嶅悓
-}
+ .action-buttons {
+ padding: 12px 0 0 0; // 涓庡叕鍏辨牱寮忎腑鐨� 0 0 16px 0 涓嶅悓
+ }
-.item-tag {
- padding: 2px 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 2px 4px 涓嶅悓
-}
+ .item-tag {
+ padding: 2px 8px; // 涓庡叕鍏辨牱寮忎腑鐨� 2px 4px 涓嶅悓
+ }
-.tag-electric {
- background: #4caf50;
-}
+ .tag-electric {
+ background: #4caf50;
+ }
-.tag-acceptance {
- background: #ff9800;
-}
+ .tag-acceptance {
+ background: #ff9800;
+ }
-.tag-unknown {
- background: #9e9e9e;
-}
+ .tag-unknown {
+ background: #9e9e9e;
+ }
-.tag-text {
- font-size: 14px; // 涓庡叕鍏辨牱寮忎腑鐨� 11px 涓嶅悓
- color: #ffffff;
- font-weight: 500;
-}
+ .tag-text {
+ font-size: 14px; // 涓庡叕鍏辨牱寮忎腑鐨� 11px 涓嶅悓
+ color: #ffffff;
+ font-weight: 500;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/sales/receiptPaymentLedger/detail.vue b/src/pages/sales/receiptPaymentLedger/detail.vue
index 041be44..b494332 100644
--- a/src/pages/sales/receiptPaymentLedger/detail.vue
+++ b/src/pages/sales/receiptPaymentLedger/detail.vue
@@ -1,307 +1,319 @@
<template>
- <view class="receipt-payment-detail">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="瀹㈡埛寰�鏉ヨ鎯�" @back="goBack" />
-
- <!-- 缁熻淇℃伅 -->
- <view class="summary-info" v-if="tableData.length > 0">
- <view class="summary-item">
- <text class="summary-label">鎬昏褰曟暟</text>
- <text class="summary-value">{{ tableData.length }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
- <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">鍥炴鎬婚噾棰�</text>
- <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
- </view>
- <view class="summary-item">
- <text class="summary-label">搴旀敹鎬婚噾棰�</text>
- <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
- </view>
- </view>
-
- <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
- <view class="detail-list" v-if="tableData.length > 0">
- <view v-for="(item, index) in tableData" :key="index" class="detail-item">
- <view class="item-header">
- <view class="item-left">
- <view class="record-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-index">{{ index + 1 }}</text>
- </view>
- <view class="item-date">{{ item.happenTime }}</view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">寮�绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value">{{ formatAmount(item.invoiceAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍥炴閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.receiptAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">搴旀敹閲戦(鍏�)</text>
- <text class="detail-value danger">{{ formatAmount(item.unReceiptAmount) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤鍥炴璁板綍</text>
- </view>
- </view>
+ <view class="receipt-payment-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="瀹㈡埛寰�鏉ヨ鎯�"
+ @back="goBack" />
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info"
+ v-if="tableData.length > 0">
+ <view class="summary-item">
+ <text class="summary-label">鎬昏褰曟暟</text>
+ <text class="summary-value">{{ tableData.length }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">寮�绁ㄦ�婚噾棰�</text>
+ <text class="summary-value">{{ formatAmount(invoiceTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鍥炴鎬婚噾棰�</text>
+ <text class="summary-value highlight">{{ formatAmount(receiptTotal) }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">搴旀敹鎬婚噾棰�</text>
+ <text class="summary-value danger">{{ formatAmount(unReceiptTotal) }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
+ <view class="detail-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index"
+ class="detail-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="record-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-index">{{ index + 1 }}</text>
+ </view>
+ <view class="item-date">{{ item.happenTime }}</view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">寮�绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value">{{ formatAmount(item.invoiceTotal) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍥炴閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ formatAmount(item.receiptPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">搴旀敹閲戦(鍏�)</text>
+ <text class="detail-value danger">{{ formatAmount(item.unReceiptPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戠敓鏃ユ湡</text>
+ <text class="detail-value">{{ item.receiptPaymentDate }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴璁板綍</text>
+ </view>
+ </view>
</template>
<script setup>
-import { ref, computed, onMounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import { customerInteractions } from "@/api/salesManagement/receiptPayment.js";
+ import { ref, computed, onMounted } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { customerInteractions } from "@/api/salesManagement/receiptPayment.js";
-// 瀹㈡埛淇℃伅
-const customerId = ref('');
+ // 瀹㈡埛淇℃伅
+ const customerId = ref("");
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([]);
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
-const invoiceTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.invoiceAmount) || 0);
- }, 0);
-});
+ const invoiceTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.invoiceTotal) || 0);
+ }, 0);
+ });
-const receiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.receiptAmount) || 0);
- }, 0);
-});
+ const receiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.receiptPaymentAmount) || 0);
+ }, 0);
+ });
-const unReceiptTotal = computed(() => {
- return tableData.value.reduce((sum, item) => {
- return sum + (parseFloat(item.unReceiptAmount) || 0);
- }, 0);
-});
+ const unReceiptTotal = computed(() => {
+ return tableData.value.reduce((sum, item) => {
+ return sum + (parseFloat(item.unReceiptPaymentAmount) || 0);
+ }, 0);
+ });
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.removeStorageSync('customerId')
- uni.navigateBack();
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("customerId");
+ uni.navigateBack();
+ };
-// 鑾峰彇椤甸潰鍙傛暟
-const getPageParams = () => {
- // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧鎴稩D
- const storedCustomerId = uni.getStorageSync('customerId');
- if (storedCustomerId) {
- customerId.value = storedCustomerId;
- }
-};
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧鎴稩D
+ const storedCustomerId = uni.getStorageSync("customerId");
+ if (storedCustomerId) {
+ customerId.value = storedCustomerId;
+ }
+ };
-// 鏌ヨ鍒楄〃
-const getList = () => {
- if (!customerId.value) {
- uni.showToast({
- title: '瀹㈡埛淇℃伅缂哄け',
- icon: 'error'
- });
- return;
- }
-
- showLoadingToast('鍔犺浇涓�...')
- const param = {
- customerId: customerId.value,
- current: -1,
- size: -1
- };
-
- customerInteractions(param).then((res) => {
- tableData.value = res.data;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ if (!customerId.value) {
+ uni.showToast({
+ title: "瀹㈡埛淇℃伅缂哄け",
+ icon: "error",
+ });
+ return;
+ }
-// 鏍煎紡鍖栭噾棰�
-const formatAmount = (amount) => {
- return amount ? parseFloat(amount).toFixed(2) : '0.00';
-};
+ showLoadingToast("鍔犺浇涓�...");
+ const param = {
+ customerId: customerId.value,
+ current: -1,
+ size: -1,
+ };
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
+ customerInteractions(param)
+ .then(res => {
+ tableData.value = res.data;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
+ // 鏍煎紡鍖栭噾棰�
+ const formatAmount = amount => {
+ return amount ? parseFloat(amount).toFixed(2) : "0.00";
+ };
-onShow(() => {
- // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
- getPageParams();
- getList();
-});
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-onMounted(() => {
- // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
- getPageParams();
- getList();
-});
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ getList();
+ });
+
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ getList();
+ });
</script>
<style scoped lang="scss">
-.receipt-payment-detail {
- min-height: 100vh;
- background: #f8f9fa;
- position: relative;
-}
+ .receipt-payment-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
-.u-divider {
- margin: 0 !important;
-}
+ .u-divider {
+ margin: 0 !important;
+ }
-.summary-info {
- background: #ffffff;
- margin: 20px 20px 0 20px;
- border-radius: 12px;
- padding: 16px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-}
+ .summary-info {
+ background: #ffffff;
+ margin: 20px 20px 0 20px;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
-.summary-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .summary-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
-.summary-label {
- font-size: 14px;
- color: #666;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.summary-value {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .summary-label {
+ font-size: 14px;
+ color: #666;
+ }
-.summary-value.highlight {
- color: #2979ff;
- font-weight: 600;
-}
+ .summary-value {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.summary-value.danger {
- color: #ff4757;
- font-weight: 600;
-}
+ .summary-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
-.detail-list {
- padding: 20px;
-}
+ .summary-value.danger {
+ color: #ff4757;
+ font-weight: 600;
+ }
-.detail-item {
- background: #ffffff;
- border-radius: 12px;
- margin-bottom: 16px;
- overflow: hidden;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- padding: 0 16px;
-}
+ .detail-list {
+ padding: 20px;
+ }
-.item-header {
- padding: 10px 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
+ .detail-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+ }
-.item-left {
- display: flex;
- align-items: center;
- gap: 8px;
-}
+ .item-header {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
-.record-icon {
- width: 24px;
- height: 24px;
- background: #2979ff;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
-.item-index {
- font-size: 14px;
- color: #333;
- font-weight: 500;
-}
+ .record-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.item-date {
- font-size: 12px;
- color: #666;
-}
+ .item-index {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
-.item-details {
- padding: 16px 0;
-}
+ .item-date {
+ font-size: 12px;
+ color: #666;
+ }
-.detail-row {
- display: flex;
- align-items: flex-end;
- justify-content: space-between;
- margin-bottom: 8px;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
+ .item-details {
+ padding: 16px 0;
+ }
-.detail-label {
- font-size: 12px;
- color: #777777;
- min-width: 60px;
-}
+ .detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
-.detail-value {
- font-size: 12px;
- color: #000000;
- text-align: right;
- flex: 1;
- margin-left: 16px;
-}
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
-.detail-value.highlight {
- color: #2979ff;
- font-weight: 500;
-}
+ .detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+ }
-.detail-value.danger {
- color: #ff4757;
- font-weight: 500;
-}
+ .detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+ }
-.no-data {
- padding: 40px 0;
- text-align: center;
- color: #999;
-}
+ .detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.danger {
+ color: #ff4757;
+ font-weight: 500;
+ }
+
+ .no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+ }
</style>
diff --git a/src/pages/sales/receiptPaymentLedger/index.vue b/src/pages/sales/receiptPaymentLedger/index.vue
index 5dd054f..7daa076 100644
--- a/src/pages/sales/receiptPaymentLedger/index.vue
+++ b/src/pages/sales/receiptPaymentLedger/index.vue
@@ -1,160 +1,167 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="瀹㈡埛寰�鏉�" @back="goBack" />
-
- <!-- 鎼滅储鍖哄煙 -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- v-model="searchForm.customerName"
- @change="handleQuery"
- clearable
- />
- </view>
- <view class="search-button" @click="handleQuery">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 瀹㈡埛鍒楄〃 -->
- <view class="customer-list-container">
- <view class="customer-list" v-if="tableData.length > 0">
- <view
- v-for="(item, index) in tableData"
- :key="item.id"
- class="customer-item"
- @click="rowClickMethod(item)"
- >
- <view class="item-header">
- <view class="item-left">
- <view class="customer-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="customer-name">{{ item.customerName }}</text>
- </view>
- <view class="item-right">
- <up-icon name="arrow-right" size="16" color="#999"></up-icon>
- </view>
- </view>
- <up-divider></up-divider>
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">寮�绁ㄩ噾棰�(鍏�)</text>
- <text class="detail-value">{{ formattedNumber(item.invoiceTotal) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍥炴閲戦(鍏�)</text>
- <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">搴旀敹閲戦(鍏�)</text>
- <text class="detail-value highlight danger">{{ formattedNumber(item.unReceiptPaymentAmount) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤瀹㈡埛鏁版嵁</text>
- </view>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="瀹㈡埛寰�鏉�"
+ @back="goBack" />
+ <!-- 鎼滅储鍖哄煙 -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+ v-model="searchForm.searchText"
+ @change="searchChange"
+ clearable />
+ </view>
+ <view class="search-button"
+ @click="handleQuery">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 瀹㈡埛鍒楄〃 -->
+ <view class="customer-list-container">
+ <view class="customer-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="item.id"
+ class="customer-item"
+ @click="rowClickMethod(item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="customer-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="customer-name">{{ item.customerName }}</text>
+ </view>
+ <view class="item-right">
+ <up-icon name="arrow-right"
+ size="16"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">寮�绁ㄩ噾棰�(鍏�)</text>
+ <text class="detail-value">{{ formattedNumber(item.invoiceTotal) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍥炴閲戦(鍏�)</text>
+ <text class="detail-value">{{ formattedNumber(item.receiptPaymentAmount) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">搴旀敹閲戦(鍏�)</text>
+ <text class="detail-value highlight danger">{{ formattedNumber(item.unReceiptPaymentAmount) }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤瀹㈡埛鏁版嵁</text>
+ </view>
+ </view>
+ </view>
</template>
<script setup>
-import { onMounted, ref, reactive, toRefs } from "vue";
-import { onShow } from '@dcloudio/uni-app';
-import { invoiceLedgerSalesAccount } from "@/api/salesManagement/invoiceLedger";
+ import { onMounted, ref, reactive, toRefs } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import { invoiceLedgerSalesAccount } from "@/api/salesManagement/invoiceLedger";
+ const tableData = ref([]);
-const tableData = ref([]);
+ const page = reactive({
+ current: -1,
+ size: -1,
+ });
-const page = reactive({
- current: -1,
- size: -1,
-});
+ const data = reactive({
+ searchForm: {
+ searchText: "",
+ invoiceDate: "",
+ },
+ });
+ const { searchForm } = toRefs(data);
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鎼滅储妗嗗彉鍖栨椂瑙﹀彂
+ const searchChange = val => {
+ searchForm.value.searchText = val;
+ getList();
+ };
+ // 鏌ヨ鍒楄〃
+ const handleQuery = () => {
+ getList();
+ };
-const data = reactive({
- searchForm: {
- customerName: "",
- invoiceDate: "",
- },
-});
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ invoiceLedgerSalesAccount({ ...searchForm.value, ...page })
+ .then(res => {
+ tableData.value = res.data.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
-const { searchForm } = toRefs(data);
+ const formattedNumber = value => {
+ return parseFloat(value || 0).toFixed(2);
+ };
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
-// 鏌ヨ鍒楄〃
-const handleQuery = () => {
- getList();
-};
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- invoiceLedgerSalesAccount({ ...searchForm.value, ...page }).then((res) => {
- tableData.value = res.data.records;
- closeToast()
- }).catch(() => {
- closeToast()
- uni.showToast({
- title: '鏌ヨ澶辫触',
- icon: 'error'
- });
- });
-};
+ const rowClickMethod = row => {
+ // 浣跨敤 uni.setStorageSync 瀛樺偍瀹㈡埛淇℃伅
+ uni.setStorageSync("customerId", row.id);
+ // 璺宠浆鍒板洖娆捐褰曟槑缁嗛〉闈�
+ uni.navigateTo({
+ url: "/pages/sales/receiptPaymentLedger/detail",
+ });
+ };
-const formattedNumber = (value) => {
- return parseFloat(value || 0).toFixed(2);
-};
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- });
-};
-
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
- uni.hideLoading();
-};
-
-const rowClickMethod = (row) => {
- // 浣跨敤 uni.setStorageSync 瀛樺偍瀹㈡埛淇℃伅
- uni.setStorageSync('customerId', row.id);
- // 璺宠浆鍒板洖娆捐褰曟槑缁嗛〉闈�
- uni.navigateTo({
- url: '/pages/sales/receiptPaymentLedger/detail'
- });
-};
-
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
-
-onMounted(() => {
- getList();
-});
+ onMounted(() => {
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
-// 瀹㈡埛寰�鏉ョ壒鏈夋牱寮�
-.detail-value.danger {
- color: #ff4757; // 涓庡叕鍏辨牱寮忎腑鐨� #ee0a24 涓嶅悓
- font-weight: 500;
-}
+ // 瀹㈡埛寰�鏉ョ壒鏈夋牱寮�
+ .detail-value.danger {
+ color: #ff4757; // 涓庡叕鍏辨牱寮忎腑鐨� #ee0a24 涓嶅悓
+ font-weight: 500;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/sales/salesAccount/detail.vue b/src/pages/sales/salesAccount/detail.vue
index 62bff3d..f8a42ab 100644
--- a/src/pages/sales/salesAccount/detail.vue
+++ b/src/pages/sales/salesAccount/detail.vue
@@ -1,976 +1,935 @@
<template>
<view class="account-detail">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鍙拌处璇︽儏" @back="goBack" />
-
- <!-- 琛ㄥ崟鍖哄煙 -->
- <up-form @submit="onSubmit" label-width="110" ref="formRef" :rules="rules" :model="form">
-
- <up-form-item label="閿�鍞悎鍚屽彿" prop="salesContractNo" >
- <up-input v-model="form.salesContractNo" placeholder="鑷姩鐢熸垚" disabled />
- </up-form-item>
- <up-form-item
- label="涓氬姟鍛�"
- prop="salesman"
- required
- @click="showPicker = true"
- >
- <up-input
- v-model="form.salesman"
- readonly
- @click="showPicker = true"
- placeholder="鐐瑰嚮閫夋嫨涓氬姟鍛�"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="瀹㈡埛鍚堝悓鍙�" prop="customerContractNo" required >
- <up-input
- v-model="form.customerContractNo"
- placeholder="璇疯緭鍏ュ鎴峰悎鍚屽彿"
- />
- </up-form-item>
- <up-form-item
- label="瀹㈡埛鍚嶇О"
- prop="customerName"
- required
- >
- <up-input
- v-model="form.customerName"
- readonly
- placeholder="鐐瑰嚮閫夋嫨瀹㈡埛"
- @click="showCustomerPicker = true"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showCustomerPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="椤圭洰鍚嶇О" prop="projectName" required >
- <up-input v-model="form.projectName" placeholder="璇疯緭鍏ラ」鐩悕绉�" />
- </up-form-item>
- <up-form-item
- label="绛捐鏃ユ湡"
- prop="executionDate"
- required
- >
- <up-input
- v-model="form.executionDate"
- readonly
- placeholder="鐐瑰嚮閫夋嫨鏃堕棿"
- @click="showDatePicker = true"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showDatePicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="浠樻鏂瑰紡" prop="paymentMethod" >
- <up-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
- </up-form-item>
- <up-form-item label="褰曞叆浜�" prop="entryPersonName" >
- <up-input v-model="form.entryPersonName" placeholder="璇疯緭鍏�" disabled />
- </up-form-item>
- <up-form-item label="褰曞叆鏃ユ湡" prop="entryDate" >
- <up-input v-model="form.entryDate" placeholder="璇疯緭鍏�" disabled />
- </up-form-item>
- <!-- 涓氬姟鍛橀�夋嫨 -->
- <up-action-sheet
- :show="showPicker"
- :actions="userActionList"
- title="閫夋嫨涓氬姟鍛�"
- @select="onSalesmanSelect"
- @close="showPicker = false"
- />
-
- <!-- 鏃ユ湡閫夋嫨 -->
- <up-popup :show="showDatePicker" mode="bottom" @close="showDatePicker = false">
- <up-datetime-picker
- :show="true"
- v-model="pickerDateValue"
- @confirm="onDateConfirm"
- @cancel="showDatePicker = false"
- mode="date"
- />
- </up-popup>
- <!-- 瀹㈡埛閫夋嫨 -->
- <up-action-sheet
- :show="showCustomerPicker"
- :actions="customerActionList"
- title="閫夋嫨瀹㈡埛"
- @select="onCustomerSelect"
- @close="showCustomerPicker = false"
- />
-
- <!-- 浜у搧澶х被閫夋嫨鍣� -->
- <up-popup :show="showCategoryPicker" mode="bottom">
- <!-- 澶撮儴鎸夐挳鍖哄煙 -->
- <view class="popup-header">
- <view @click="showCategoryPicker = false" class="cancelButton">鍙栨秷</view>
- <view @click="confirmCategorySelection" class="confirmButton">纭畾</view>
- </view>
- <u-tree
- :data="productOptions"
- :props="defaultProps"
- show-checkbox
- default-expand-all
- check-strictly
- @check-change="onCategoryConfirm"
- />
- </up-popup>
-
- <!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
- <up-action-sheet
- :show="showSpecificationPicker"
- :actions="specificationActionList"
- title="閫夋嫨瑙勬牸鍨嬪彿"
- @select="onSpecificationSelect"
- @close="showSpecificationPicker = false"
- />
-
- <!-- 绋庣巼閫夋嫨鍣� -->
- <up-action-sheet
- :show="showTaxRatePicker"
- :actions="taxRateActionList"
- title="閫夋嫨绋庣巼"
- @select="onTaxRateSelect"
- @close="showTaxRatePicker = false"
- />
-
- <!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
- <up-action-sheet
- :show="showInvoiceTypePicker"
- :actions="invoiceTypeActionList"
- title="閫夋嫨鍙戠エ绫诲瀷"
- @select="onInvoiceTypeSelect"
- @close="showInvoiceTypePicker = false"
- />
- <!-- 浜у搧淇℃伅 -->
- <view class="product-section">
- <view class="section-header">
- <view>
- <text class="section-title">浜у搧淇℃伅</text>
- </view>
- <view>
- <up-button type="primary" size="small" @click="addProduct" class="add-btn" v-if="operationType !== 'view'">
- 鏂板
- </up-button>
- </view>
- </view>
- <view class="product-card" v-for="(product, idx) in productData" :key="idx">
- <!-- 浜у搧绫� -->
- <view class="product-header">
- <view class="product-title">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
- </view>
- <!-- 鎿嶄綔鎸夐挳 -->
- <view class="product-actions" v-if="operationType !== 'view'">
- <up-button type="error" size="mini" @click="removeProduct(idx)" class="del-btn">
- 鍒犻櫎
- </up-button>
- </view>
- </view>
-
- <!-- 浜у搧淇℃伅琛ㄥ崟 -->
- <view class="product-form">
- <!-- 浜у搧澶х被 -->
- <up-form-item
- label="浜у搧澶х被"
- prop="productCategory"
+ <PageHeader title="鍙拌处璇︽儏"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <up-form @submit="onSubmit"
+ label-width="110"
+ ref="formRef"
+ :rules="rules"
+ :model="form">
+ <up-form-item label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo">
+ <up-input v-model="form.salesContractNo"
+ placeholder="鑷姩鐢熸垚"
+ disabled />
+ </up-form-item>
+ <up-form-item label="涓氬姟鍛�"
+ prop="salesman"
+ required
+ @click="showPicker = true">
+ <up-input v-model="form.salesman"
+ readonly
+ @click="showPicker = true"
+ placeholder="鐐瑰嚮閫夋嫨涓氬姟鍛�" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click=" showPicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="瀹㈡埛鍚嶇О"
+ prop="customerName"
+ required>
+ <up-input v-model="form.customerName"
+ readonly
+ placeholder="鐐瑰嚮閫夋嫨瀹㈡埛"
+ @click="showCustomerPicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showCustomerPicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="椤圭洰鍚嶇О"
+ prop="projectName"
+ required>
+ <up-input v-model="form.projectName"
+ placeholder="璇疯緭鍏ラ」鐩悕绉�" />
+ </up-form-item>
+ <up-form-item label="绛捐鏃ユ湡"
+ prop="executionDate"
+ required>
+ <up-input v-model="form.executionDate"
+ readonly
+ placeholder="鐐瑰嚮閫夋嫨鏃堕棿"
+ @click="showDatePicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showDatePicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="浠樻鏂瑰紡"
+ prop="paymentMethod">
+ <up-input v-model="form.paymentMethod"
+ placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" />
+ </up-form-item>
+ <up-form-item label="褰曞叆浜�"
+ prop="entryPersonName">
+ <up-input v-model="form.entryPersonName"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </up-form-item>
+ <up-form-item label="褰曞叆鏃ユ湡"
+ prop="entryDate">
+ <up-input v-model="form.entryDate"
+ placeholder="璇疯緭鍏�"
+ disabled />
+ </up-form-item>
+ <!-- 涓氬姟鍛橀�夋嫨 -->
+ <up-action-sheet :show="showPicker"
+ :actions="userActionList"
+ title="閫夋嫨涓氬姟鍛�"
+ @select="onSalesmanSelect"
+ @close="showPicker = false" />
+ <!-- 鏃ユ湡閫夋嫨 -->
+ <up-popup :show="showDatePicker"
+ mode="bottom"
+ @close="showDatePicker = false">
+ <up-datetime-picker :show="true"
+ v-model="pickerDateValue"
+ @confirm="onDateConfirm"
+ @cancel="showDatePicker = false"
+ mode="date" />
+ </up-popup>
+ <!-- 瀹㈡埛閫夋嫨 -->
+ <up-action-sheet :show="showCustomerPicker"
+ :actions="customerActionList"
+ title="閫夋嫨瀹㈡埛"
+ @select="onCustomerSelect"
+ @close="showCustomerPicker = false" />
+ <!-- 浜у搧澶х被閫夋嫨鍣� -->
+ <up-popup :show="showCategoryPicker"
+ mode="bottom">
+ <!-- 澶撮儴鎸夐挳鍖哄煙 -->
+ <view class="popup-header">
+ <view @click="showCategoryPicker = false"
+ class="cancelButton">鍙栨秷</view>
+ <view @click="confirmCategorySelection"
+ class="confirmButton">纭畾</view>
+ </view>
+ <u-tree :data="productOptions"
+ :props="defaultProps"
+ show-checkbox
+ default-expand-all
+ check-strictly
+ @check-change="onCategoryConfirm" />
+ </up-popup>
+ <!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
+ <up-action-sheet :show="showSpecificationPicker"
+ :actions="specificationActionList"
+ title="閫夋嫨瑙勬牸鍨嬪彿"
+ @select="onSpecificationSelect"
+ @close="showSpecificationPicker = false" />
+ <!-- 绋庣巼閫夋嫨鍣� -->
+ <up-action-sheet :show="showTaxRatePicker"
+ :actions="taxRateActionList"
+ title="閫夋嫨绋庣巼"
+ @select="onTaxRateSelect"
+ @close="showTaxRatePicker = false" />
+ <!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
+ <up-action-sheet :show="showInvoiceTypePicker"
+ :actions="invoiceTypeActionList"
+ title="閫夋嫨鍙戠エ绫诲瀷"
+ @select="onInvoiceTypeSelect"
+ @close="showInvoiceTypePicker = false" />
+ <!-- 浜у搧淇℃伅 -->
+ <view class="product-section">
+ <view class="section-header">
+ <view>
+ <text class="section-title">浜у搧淇℃伅</text>
+ </view>
+ <view>
+ <up-button type="primary"
+ size="small"
+ @click="addProduct"
+ class="add-btn"
+ v-if="operationType !== 'view'">
+ 鏂板
+ </up-button>
+ </view>
+ </view>
+ <view class="product-card"
+ v-for="(product, idx) in productData"
+ :key="idx">
+ <!-- 浜у搧绫� -->
+ <view class="product-header">
+ <view class="product-title">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="product-actions"
+ v-if="operationType !== 'view'">
+ <up-button type="error"
+ size="mini"
+ @click="removeProduct(idx)"
+ class="del-btn">
+ 鍒犻櫎
+ </up-button>
+ </view>
+ </view>
+ <!-- 浜у搧淇℃伅琛ㄥ崟 -->
+ <view class="product-form">
+ <!-- 浜у搧澶х被 -->
+ <up-form-item label="浜у搧澶х被"
+ prop="productCategory"
+ required>
+ <up-input v-model="product.productCategory"
+ readonly
+ placeholder="璇烽�夋嫨"
+ @click="openCategoryPicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openCategoryPicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 瑙勬牸鍨嬪彿 -->
+ <up-form-item label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ required>
+ <up-input v-model="product.specificationModel"
+ readonly
+ placeholder="璇烽�夋嫨"
+ @click="openSpecificationPicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openSpecificationPicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 缁戝畾鏈哄櫒 -->
+ <!-- <up-form-item
+ label="缁戝畾鏈哄櫒"
+ prop="speculativeTradingName"
required
>
<up-input
- v-model="product.productCategory"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openCategoryPicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showCategoryPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 瑙勬牸鍨嬪彿 -->
- <up-form-item
- label="瑙勬牸鍨嬪彿"
- prop="specificationModel"
- required
- >
- <up-input
- v-model="product.specificationModel"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openSpecificationPicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showSpecificationPicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 鍗曚綅 -->
- <up-form-item
- label="鍗曚綅"
- prop="unit"
- required
- >
- <up-input
- v-model="product.unit"
+ disabled
+ v-model="product.speculativeTradingName"
placeholder="璇疯緭鍏�"
/>
- </up-form-item>
-
- <!-- 绋庣巼 -->
- <up-form-item
- label="绋庣巼(%)"
- prop="taxRate"
- required
- >
- <up-input
- v-model="product.taxRate"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openTaxRatePicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showTaxRatePicker = true"
- ></up-icon>
- </template>
- </up-form-item>
-
- <!-- 鍚◣鍗曚环 -->
- <up-form-item
- label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- required
- >
- <up-input
- v-model="product.taxInclusiveUnitPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatTaxPrice(idx)"
- />
- </up-form-item>
-
- <!-- 鏁伴噺 -->
- <up-form-item
- label="鏁伴噺"
- prop="quantity"
- required
- >
- <up-input
- v-model="product.quantity"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatAmount(idx)"
- />
- </up-form-item>
-
- <!-- 鍚◣鎬讳环 -->
- <up-form-item
- label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- required
- >
- <up-input
- v-model="product.taxInclusiveTotalPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatTaxTotal(idx)"
- />
- </up-form-item>
-
- <!-- 涓嶅惈绋庢�讳环 -->
- <up-form-item
- label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- required
- >
- <up-input
- v-model="product.taxExclusiveTotalPrice"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="formatNoTaxTotal(idx)"
- />
- </up-form-item>
-
- <!-- 鍙戠エ绫诲瀷 -->
- <up-form-item
- label="鍙戠エ绫诲瀷"
- prop="invoiceType"
- required
- >
- <up-input
- v-model="product.invoiceType"
- readonly
- placeholder="璇烽�夋嫨"
- @click="openInvoiceTypePicker(idx)"
- />
- <template #right>
- <up-icon
- name="arrow-right"
- @click="showInvoiceTypePicker = true"
- ></up-icon>
- </template>
- </up-form-item>
- </view>
- </view>
- </view>
- </up-form>
-
- <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
- <FooterButtons
- :show="operationType !== 'view'"
- cancelText="鍙栨秷"
- confirmText="淇濆瓨"
- @cancel="goBack"
- @confirm="onSubmit"
- />
+ </up-form-item> -->
+ <!-- 鍗曚綅 -->
+ <up-form-item label="鍗曚綅"
+ prop="unit"
+ required>
+ <up-input v-model="product.unit"
+ placeholder="璇疯緭鍏�" />
+ </up-form-item>
+ <!-- 绋庣巼 -->
+ <up-form-item label="绋庣巼(%)"
+ prop="taxRate"
+ required>
+ <up-input v-model="product.taxRate"
+ readonly
+ placeholder="璇烽�夋嫨"
+ @click="openTaxRatePicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openTaxRatePicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ <!-- 鍚◣鍗曚环 -->
+ <up-form-item label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ required>
+ <up-input v-model="product.taxInclusiveUnitPrice"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxPrice(idx)" />
+ </up-form-item>
+ <!-- 鏁伴噺 -->
+ <up-form-item label="鏁伴噺"
+ prop="quantity"
+ required>
+ <up-input v-model="product.quantity"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="formatAmount(idx)" />
+ </up-form-item>
+ <!-- 鍚◣鎬讳环 -->
+ <up-form-item label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ required>
+ <up-input v-model="product.taxInclusiveTotalPrice"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxTotal(idx)" />
+ </up-form-item>
+ <!-- 涓嶅惈绋庢�讳环 -->
+ <up-form-item label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ required>
+ <up-input v-model="product.taxExclusiveTotalPrice"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="formatNoTaxTotal(idx)" />
+ </up-form-item>
+ <!-- 鍙戠エ绫诲瀷 -->
+ <up-form-item label="鍙戠エ绫诲瀷"
+ prop="invoiceType"
+ required>
+ <up-input v-model="product.invoiceType"
+ readonly
+ placeholder="璇烽�夋嫨"
+ @click="openInvoiceTypePicker(idx)" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openInvoiceTypePicker(idx)"></up-icon>
+ </template>
+ </up-form-item>
+ </view>
+ </view>
+ </view>
+ </up-form>
+ <!-- 浣跨敤鍏叡搴曢儴鎸夐挳缁勪欢 -->
+ <FooterButtons :show="operationType !== 'view'"
+ cancelText="鍙栨秷"
+ confirmText="淇濆瓨"
+ @cancel="goBack"
+ @confirm="onSubmit" />
</view>
</template>
<script setup>
-import {onMounted, ref, computed} from 'vue';
-import {userListNoPage} from "@/api/system/user";
-import { formatDateToYMD } from '@/utils/ruoyi'
-import {
- addOrUpdateSalesLedger,
- customerList,
- getSalesLedgerWithProducts,
- modelList,
- productTreeList
-} from "@/api/salesManagement/salesLedger";
-import useUserStore from "@/store/modules/user";
-import {calculateTaxExclusiveTotalPrice} from "@/utils/summarizeTable";
-import PageHeader from '@/components/PageHeader.vue';
-import FooterButtons from '@/components/FooterButtons.vue';
+ import { onMounted, ref, computed } from "vue";
+ import { userListNoPage } from "@/api/system/user";
+ import { formatDateToYMD } from "@/utils/ruoyi";
+ import {
+ addOrUpdateSalesLedger,
+ customerList,
+ getSalesLedgerWithProducts,
+ modelList,
+ productTreeList,
+ } from "@/api/salesManagement/salesLedger";
+ import useUserStore from "@/store/modules/user";
+ import { calculateTaxExclusiveTotalPrice } from "@/utils/summarizeTable";
+ import PageHeader from "@/components/PageHeader.vue";
+ import FooterButtons from "@/components/FooterButtons.vue";
-// 鑾峰彇椤甸潰鍙傛暟
-const operationType = ref('');
-const editData = ref(null);
-const formRef = ref(null);
+ // 鑾峰彇椤甸潰鍙傛暟
+ const operationType = ref("");
+ const editData = ref(null);
+ const formRef = ref(null);
-const userStore = useUserStore()
-const form = ref({
- id: '',
- salesContractNo: '',
- customerContractNo: '',
- customerId: '',
- customerName: '',
- projectName: '',
- executionDate: '',
- paymentMethod: '',
- entryPerson: '',
- entryPersonName: '',
- entryDate: '',
-});
-const showPicker = ref(false);
-const showDatePicker = ref(false);
-const pickerDateValue = ref(Date.now());
-const showCustomerPicker = ref(false);
-const userList = ref([]);
-const customerOption = ref([]);
-const userActionList = computed(() => {
- return userList.value.map(user => ({
- name: user.text,
- value: user.value
- }))
-})
-const formatter = (type, value) => {
- if (type === 'year') {
- return `${value}`;
- }
- if (type === 'month') {
- return `${value}`;
- }
- if (type === 'day') {
- return `${value}`;
- }
- return value;
-};
-const customerActionList = computed(() => {
- return customerOption.value.map(customer => ({
- name: customer.text,
- value: customer.value
- }))
-})
-
-// 鏃ユ湡閫夋嫨鍒楄〃宸茬Щ闄わ紝鏀圭敤 up-datetime-picker
-
-// 浜у搧澶х被閫夋嫨鍒楄〃
-const categoryActionList = computed(() => {
- const flattenCategories = (categories, result = []) => {
- categories.forEach(category => {
- result.push({
- name: category.label,
- value: category.id
- })
- if (category.children && category.children.length > 0) {
- flattenCategories(category.children, result)
- }
- })
- return result
- }
- return flattenCategories(productOptions.value)
-})
-
-// 瑙勬牸鍨嬪彿閫夋嫨鍒楄〃
-const specificationActionList = computed(() => {
- return modelOptions.value.map(model => ({
- name: model.text,
- value: model.value,
- unit: model.unit
- }))
-})
-
-// 绋庣巼閫夋嫨鍒楄〃
-const taxRateActionList = computed(() => {
- return taxRateOptions.value.map(rate => ({
- name: rate.text,
- value: rate.value
- }))
-})
-
-// 鍙戠エ绫诲瀷閫夋嫨鍒楄〃
-const invoiceTypeActionList = computed(() => {
- return invoiceTypeOptions.value.map(type => ({
- name: type.text,
- value: type.value
- }))
-})
-const productData = ref([]);
-
-// 閫夋嫨鍣ㄧ浉鍏冲彉閲�
-const showCategoryPicker = ref(false);
-const showSpecificationPicker = ref(false);
-const showTaxRatePicker = ref(false);
-const showInvoiceTypePicker = ref(false);
-// 閫夋嫨鍣ㄦ樉绀虹姸鎬佸彉閲忓凡鍦ㄤ笂闈㈠畾涔�
-
-// 涓存椂鍙橀噺宸蹭笉鍐嶉渶瑕�
-const currentProductIndex = ref(0);
-
-// 閫夐」鏁版嵁
-const productOptions = ref([]);
-const selectedCategoryNode = ref(null);
-const defaultProps = ref({
- children: 'children',
- label: 'label',
- nodeKey: 'id'
-});
-
-const modelOptions = ref([]);
-// 闃叉寰幆璁$畻鐨勬爣蹇�
-// const isCalculating = ref(false);
-const taxRateOptions = ref([
- { text: '1', value: '1' },
- { text: '6', value: '6' },
- { text: '13', value: '13' },
-]);
-
-const invoiceTypeOptions = ref([
- { text: '澧炴櫘绁�', value: '澧炴櫘绁�' },
- { text: '澧炰笓绁�', value: '澧炰笓绁�' },
-]);
-
-// 琛ㄥ崟鏍¢獙瑙勫垯
-const rules = {
- salesman: [
- { required: true, message: '璇烽�夋嫨涓氬姟鍛�', trigger: 'change' }
- ],
- customerContractNo: [
- { required: true, message: '璇疯緭鍏ュ鎴峰悎鍚屽彿', trigger: 'blur' }
- ],
- customerName: [
- { required: true, message: '璇烽�夋嫨瀹㈡埛鍚嶇О', trigger: 'change' }
- ],
- projectName: [
- { required: true, message: '璇疯緭鍏ラ」鐩悕绉�', trigger: 'blur' }
- ],
- executionDate: [
- { required: true, message: '璇烽�夋嫨绛捐鏃ユ湡', trigger: 'change' }
- ]
-};
-
-
-
-const addProduct = () => {
- if (productData.value === null) {
- productData.value = []
- }
- productData.value.push({
- productCategory: '',
- specificationModel: '',
- productModelId: '',
- unit: '',
- taxRate: '',
- taxInclusiveUnitPrice: '',
- quantity: '',
- taxInclusiveTotalPrice: '',
- taxExclusiveTotalPrice: '',
- invoiceType: ''
+ const userStore = useUserStore();
+ const form = ref({
+ id: "",
+ salesContractNo: "",
+ customerId: "",
+ customerName: "",
+ projectName: "",
+ executionDate: "",
+ paymentMethod: "",
+ entryPerson: "",
+ entryPersonName: "",
+ entryDate: "",
});
-};
-// 涓氬姟鍛橀�夋嫨浜嬩欢
-const onSalesmanSelect = (item) => {
- form.value.salesman = item.name
-}
-
-// 鏃ユ湡纭浜嬩欢
-const onDateConfirm = (e) => {
- form.value.executionDate = formatDateToYMD(e.value)
- // 淇濇寔pickerDateValue涓烘椂闂存埑鏍煎紡锛岃�屼笉鏄牸寮忓寲鐨勫瓧绗︿覆
- pickerDateValue.value = e.value
- showDatePicker.value = false;
-}
-
-// 瀹㈡埛閫夋嫨浜嬩欢
-const onCustomerSelect = (item) => {
- form.value.customerName = item.name
- form.value.customerId = item.value
-}
-
-// 鍘熸湁鐨勭‘璁ゆ柟娉曞凡琚柊鐨刟ction-sheet閫夋嫨鏂规硶鏇夸唬
-const removeProduct = (idx) => {
- productData.value.splice(idx, 1);
-};
-
-// 鏄剧ず閫夋嫨鍣�
-const openCategoryPicker = (idx) => {
- currentProductIndex.value = idx;
- showCategoryPicker.value = true;
-};
-
-const openSpecificationPicker = (idx) => {
- currentProductIndex.value = idx;
- showSpecificationPicker.value = true;
-};
-
-const openTaxRatePicker = (idx) => {
- currentProductIndex.value = idx;
- showTaxRatePicker.value = true;
-};
-
-const openInvoiceTypePicker = (idx) => {
- currentProductIndex.value = idx;
- showInvoiceTypePicker.value = true;
-};
-
-// 閫夋嫨鍣ㄧ‘璁や簨浠�
-const onCategoryConfirm = (node) => {
- // 鑾峰彇閫変腑鐨勮妭鐐逛俊鎭�
- console.log('selected node---', node);
- // 瀛樺偍閫変腑鐨勮妭鐐癸紝鐢ㄤ簬纭鏃惰幏鍙栨暟鎹�
- selectedCategoryNode.value = node;
-};
-
-// 纭浜у搧澶х被閫夋嫨
-const confirmCategorySelection = () => {
- if (selectedCategoryNode.value) {
- // 璁剧疆閫変腑鐨勪骇鍝佸ぇ绫�
- productData.value[currentProductIndex.value].productCategory = selectedCategoryNode.value.label;
- const id = selectedCategoryNode.value.id
- // 閲嶇疆閫変腑鐨勮妭鐐�
- selectedCategoryNode.value = null;
- productData.value[currentProductIndex.value].specificationModel = ''
- productData.value[currentProductIndex.value].productModelId = ''
- getModels(id)
- }
- showCategoryPicker.value = false;
-};
-// 鑾峰彇瑙勬牸鍨嬪彿
-const getModels = (value) => {
- modelList({ id: value }).then((res) => {
- modelOptions.value = res.map(user => ({
- text: user.model,
- value: user.id,
- unit: user.unit,
- }));
- });
-};
-// 瑙勬牸鍨嬪彿閫夋嫨浜嬩欢
-const onSpecificationSelect = (item) => {
- productData.value[currentProductIndex.value].specificationModel = item.name
- productData.value[currentProductIndex.value].productModelId = item.value
- productData.value[currentProductIndex.value].unit = item.unit
-}
-// 绋庣巼閫夋嫨浜嬩欢
-const onTaxRateSelect = (item) => {
- productData.value[currentProductIndex.value].taxRate = item.value
- // 閲嶆柊璁$畻涓嶅惈绋庢�讳环
- const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice)
- const taxRate = parseFloat(item.value)
- if (inclusiveTotalPrice && taxRate) {
- productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate)
- }
-};
-
-// 鍙戠エ绫诲瀷閫夋嫨浜嬩欢
-const onInvoiceTypeSelect = (item) => {
- productData.value[currentProductIndex.value].invoiceType = item.name
-};
-
-// 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
-const formatTaxPrice = (idx) => {
- if (productData.value[idx].taxInclusiveUnitPrice) {
- const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
+ const showPicker = ref(false);
+ const showDatePicker = ref(false);
+ const pickerDateValue = ref(Date.now());
+ const showCustomerPicker = ref(false);
+ const userList = ref([]);
+ const customerOption = ref([]);
+ const userActionList = computed(() => {
+ return userList.value.map(user => ({
+ name: user.text,
+ value: user.value,
+ }));
+ });
+ const formatter = (type, value) => {
+ if (type === "year") {
+ return `${value}`;
}
- }
- if (!productData.value[idx].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const quantity = parseFloat(productData.value[idx].quantity);
- const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
- // 璁$畻鍚◣鎬讳环
- productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[idx].taxRate) {
- productData.value[idx].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- productData.value[idx].taxInclusiveTotalPrice,
- productData.value[idx].taxRate
- );
- }
-};
-// 鏁伴噺杈撳叆妗嗗け鐒�
-const formatAmount = (idx) => {
- if (productData.value[idx].quantity) {
- const value = parseFloat(productData.value[idx].quantity);
- if (!isNaN(value)) {
- productData.value[idx].quantity = value.toFixed(2);
+ if (type === "month") {
+ return `${value}`;
}
- }
- if (!productData.value[idx].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const quantity = parseFloat(productData.value[idx].quantity);
- const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
- // 璁$畻鍚◣鎬讳环
- productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[idx].taxRate) {
- productData.value[idx].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- productData.value[idx].taxInclusiveTotalPrice,
- productData.value[idx].taxRate
- );
- }
-};
-// 鍚◣鎬讳环澶辩劍锛屾牴鎹惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const formatTaxTotal = (idx) => {
- if (productData.value[idx].taxInclusiveTotalPrice) {
- const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
+ if (type === "day") {
+ return `${value}`;
}
- }
- const totalPrice = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
- const quantity = parseFloat(productData.value[idx].quantity);
-
- if (!totalPrice || !quantity || quantity <= 0) {
- return;
- }
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productData.value[idx].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productData.value[idx].taxRate) {
- productData.value[idx].taxExclusiveTotalPrice =
- calculateTaxExclusiveTotalPrice(
- totalPrice,
- productData.value[idx].taxRate
- );
- }
-};
-// 涓嶅惈绋庢�讳环澶辩劍, 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
-const formatNoTaxTotal = (idx) => {
- if (productData.value[idx].taxExclusiveTotalPrice) {
- const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
- if (!isNaN(value)) {
- productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
- }
- }
- if (!productData.value[idx].taxRate) {
- uni.showToast({
- title: '璇峰厛閫夋嫨绋庣巼',
- icon: 'none'
- });
- return;
- }
- const exclusiveTotalPrice = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
- const quantity = parseFloat(productData.value[idx].quantity);
- const taxRate = parseFloat(productData.value[idx].taxRate);
- if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
- return;
- }
- // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
- const taxRateDecimal = taxRate / 100;
- const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
- productData.value[idx].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productData.value[idx].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
-};
-const goBack = () => {
- // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
- uni.removeStorageSync('operationType');
- uni.removeStorageSync('editData');
- uni.navigateBack();
-};
-const onSubmit = async () => {
- // 棣栧厛鏍¢獙鍩烘湰琛ㄥ崟
- const formValid = await formRef.value.validate().catch(() => false);
- if (!formValid) {
- return;
- }
-
- // 鏍¢獙浜у搧淇℃伅
- if (!productData.value || productData.value.length === 0) {
- uni.showToast({
- title: '璇锋坊鍔犱骇鍝佷俊鎭�',
- icon: 'none'
- });
- return;
- }
-
- // 妫�鏌ユ瘡涓骇鍝佹槸鍚﹀~鍐欏畬鏁�
- for (let i = 0; i < productData.value.length; i++) {
- const product = productData.value[i];
- // 浼樺寲鏁板瓧瀛楁楠岃瘉锛屽鐞嗗彲鑳界殑瀛楃涓叉牸寮忔暟鍊�
- const taxInclusiveUnitPrice = parseFloat(product.taxInclusiveUnitPrice);
- const quantity = parseFloat(product.quantity);
- const taxInclusiveTotalPrice = parseFloat(product.taxInclusiveTotalPrice);
- const taxExclusiveTotalPrice = parseFloat(product.taxExclusiveTotalPrice);
-
- if (!product.productCategory) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳閫夋嫨浜у搧澶х被`,
- icon: 'none'
- });
- return;
- }
- if (!product.specificationModel) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳閫夋嫨瑙勬牸鍨嬪彿`,
- icon: 'none'
- });
- return;
- }
- if (!product.unit) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳杈撳叆鍗曚綅`,
- icon: 'none'
- });
- return;
- }
- if (!product.taxRate) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳閫夋嫨绋庣巼`,
- icon: 'none'
- });
- return;
- }
- if (isNaN(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庡崟浠穈,
- icon: 'none'
- });
- return;
- }
- if (isNaN(quantity) || quantity <= 0) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勬暟閲廯,
- icon: 'none'
- });
- return;
- }
- if (isNaN(taxInclusiveTotalPrice) || taxInclusiveTotalPrice <= 0) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庢�讳环`,
- icon: 'none'
- });
- return;
- }
- if (isNaN(taxExclusiveTotalPrice) || taxExclusiveTotalPrice <= 0) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勪笉鍚◣鎬讳环`,
- icon: 'none'
- });
- return;
- }
- if (!product.invoiceType) {
- uni.showToast({
- title: `浜у搧${i + 1}锛氳閫夋嫨鍙戠エ绫诲瀷`,
- icon: 'none'
- });
- return;
- }
- }
-
- // 琛ㄥ崟鏍¢獙閫氳繃锛屾彁浜ゆ暟鎹�
- form.value.productData = JSON.parse(JSON.stringify(productData.value));
- form.value.type = 1;
- addOrUpdateSalesLedger(form.value).then((res) => {
- uni.showToast({
- title: '鎻愪氦鎴愬姛',
- icon: 'success',
- });
- goBack();
- });
-};
-const setUserInfo = () => {
- form.value.entryPerson = userStore.id;
- form.value.entryPersonName = userStore.nickName;
- // 璁剧疆褰撳ぉ鏃ユ湡
- 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')
- form.value.entryDate = `${year}-${month}-${day}`
- // 璁剧疆鏃ユ湡閫夋嫨鍣ㄩ粯璁ゅ�间负浠婂ぉ
- pickerDateValue.value = `${year}-${month}-${day}`
-}
-// 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
-const fillFormData = () => {
- if (!editData.value) return;
- getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then((res) => {
- productData.value = res.productData;
- });
- console.log(editData.value)
- // 濉厖鍩烘湰淇℃伅
- form.value.salesContractNo = editData.value.salesContractNo || '';
- form.value.customerContractNo = editData.value.customerContractNo || '';
- form.value.customerName = editData.value.customerName || '';
- form.value.projectName = editData.value.projectName || '';
- form.value.executionDate = editData.value.executionDate || '';
- form.value.paymentMethod = editData.value.paymentMethod || '';
- form.value.salesman = editData.value.salesman || '';
- form.value.entryPerson = editData.value.entryPerson || '';
- form.value.entryPersonName = editData.value.entryPersonName || '';
- form.value.entryDate = editData.value.entryDate || '';
- form.value.id = editData.value.id || '';
- form.value.customerId = editData.value.customerId || '';
-
- // 璁剧疆鏃ユ湡閫夋嫨鍣ㄧ殑鍊�
- if (editData.value.executionDate) {
- pickerDateValue.value = editData.value.executionDate
- }
-};
-const getUserList = () => {
- userListNoPage().then((res) => {
- // 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
- userList.value = res.data.map(user => ({
- text: user.nickName,
- value: user.nickName
- }));
- })
-};
-const getCustomerList = () => {
- customerList().then((res) => {
- // 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
- customerOption.value = res.map(item => ({
- text: item.customerName,
- value: item.id
- }));
- })
-};
-const convertIdToValue = (data) => {
- // 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
- if (!Array.isArray(data)) {
- return [];
- }
- // 閫掑綊鏄犲皠鍑芥暟
- return data.map(item => {
- // 鍒涘缓鏂板璞★紝鏄犲皠瀛楁
- const mappedItem = {
- label: item.label, // 鍏抽敭锛氬皢 label 鏄犲皠涓� text
- id: item.id, // 淇濈暀 id
- };
- // 濡傛灉瀛樺湪 children 鏁扮粍锛屽垯閫掑綊澶勭悊
- if (item.children && Array.isArray(item.children) && item.children.length > 0) {
- mappedItem.children = convertIdToValue(item.children);
- }
- return mappedItem;
- });
-};
-// 鑾峰彇浜у搧澶х被tree鏁版嵁
-const getProductOptions = () => {
- productTreeList().then((res) => {
- productOptions.value = convertIdToValue(res);
- });
-};
+ return value;
+ };
+ const customerActionList = computed(() => {
+ return customerOption.value.map(customer => ({
+ name: customer.text,
+ value: customer.value,
+ }));
+ });
+ // 鏃ユ湡閫夋嫨鍒楄〃宸茬Щ闄わ紝鏀圭敤 up-datetime-picker
-onMounted(() => {
- // 鑾峰彇椤甸潰鍙傛暟
- operationType.value = uni.getStorageSync('operationType') || '';
-
- // 鑾峰彇浜哄憳鍒楄〃
- getUserList()
- // 鑾峰彇瀹㈡埛鍒楄〃
- getCustomerList()
- // 鑾峰彇浜у搧澶х被tree鏁版嵁
- getProductOptions()
- // 璧嬪�奸粯璁や俊鎭�
- if (operationType.value === 'add') {
- setUserInfo()
- }
-
- // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
- const editDataStr = uni.getStorageSync('editData');
- if (editDataStr) {
- try {
- editData.value = JSON.parse(editDataStr);
- // 濡傛灉鏄紪杈戞ā寮忥紝绛夊緟鏁版嵁鍔犺浇瀹屾垚鍚庡~鍏呰〃鍗曟暟鎹�
- if (operationType.value !== 'add' && editData.value) {
- // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
- setTimeout(() => {
- fillFormData();
- }, 100);
- }
- } catch (error) {
- console.error('瑙f瀽缂栬緫鏁版嵁澶辫触:', error);
- }
- }
-});
+ // 浜у搧澶х被閫夋嫨鍒楄〃
+ const categoryActionList = computed(() => {
+ const flattenCategories = (categories, result = []) => {
+ categories.forEach(category => {
+ result.push({
+ name: category.label,
+ value: category.id,
+ });
+ if (category.children && category.children.length > 0) {
+ flattenCategories(category.children, result);
+ }
+ });
+ return result;
+ };
+ return flattenCategories(productOptions.value);
+ });
+
+ // 瑙勬牸鍨嬪彿閫夋嫨鍒楄〃
+ const specificationActionList = computed(() => {
+ return modelOptions.value.map(model => ({
+ name: model.text,
+ value: model.value,
+ unit: model.unit,
+ speculativeTradingName: model.speculativeTradingName,
+ }));
+ });
+
+ // 绋庣巼閫夋嫨鍒楄〃
+ const taxRateActionList = computed(() => {
+ return taxRateOptions.value.map(rate => ({
+ name: rate.text,
+ value: rate.value,
+ }));
+ });
+
+ // 鍙戠エ绫诲瀷閫夋嫨鍒楄〃
+ const invoiceTypeActionList = computed(() => {
+ return invoiceTypeOptions.value.map(type => ({
+ name: type.text,
+ value: type.value,
+ }));
+ });
+ const productData = ref([]);
+
+ // 閫夋嫨鍣ㄧ浉鍏冲彉閲�
+ const showCategoryPicker = ref(false);
+ const showSpecificationPicker = ref(false);
+ const showTaxRatePicker = ref(false);
+ const showInvoiceTypePicker = ref(false);
+ // 閫夋嫨鍣ㄦ樉绀虹姸鎬佸彉閲忓凡鍦ㄤ笂闈㈠畾涔�
+
+ // 涓存椂鍙橀噺宸蹭笉鍐嶉渶瑕�
+ const currentProductIndex = ref(0);
+
+ // 閫夐」鏁版嵁
+ const productOptions = ref([]);
+ const selectedCategoryNode = ref(null);
+ const defaultProps = ref({
+ children: "children",
+ label: "label",
+ nodeKey: "id",
+ });
+
+ const modelOptions = ref([]);
+ // 闃叉寰幆璁$畻鐨勬爣蹇�
+ // const isCalculating = ref(false);
+ const taxRateOptions = ref([
+ { text: "1", value: "1" },
+ { text: "6", value: "6" },
+ { text: "13", value: "13" },
+ ]);
+
+ const invoiceTypeOptions = ref([
+ { text: "澧炴櫘绁�", value: "澧炴櫘绁�" },
+ { text: "澧炰笓绁�", value: "澧炰笓绁�" },
+ ]);
+
+ // 琛ㄥ崟鏍¢獙瑙勫垯
+ const rules = {
+ salesman: [{ required: true, message: "璇烽�夋嫨涓氬姟鍛�", trigger: "change" }],
+ customerName: [
+ { required: true, message: "璇烽�夋嫨瀹㈡埛鍚嶇О", trigger: "change" },
+ ],
+ projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+ executionDate: [
+ { required: true, message: "璇烽�夋嫨绛捐鏃ユ湡", trigger: "change" },
+ ],
+ };
+
+ const addProduct = () => {
+ if (productData.value === null) {
+ productData.value = [];
+ }
+ productData.value.push({
+ productCategory: "",
+ specificationModel: "",
+ productModelId: "",
+ unit: "",
+ speculativeTradingName: "",
+ taxRate: "",
+ taxInclusiveUnitPrice: "",
+ quantity: "",
+ taxInclusiveTotalPrice: "",
+ taxExclusiveTotalPrice: "",
+ invoiceType: "",
+ });
+ };
+ // 涓氬姟鍛橀�夋嫨浜嬩欢
+ const onSalesmanSelect = item => {
+ form.value.salesman = item.name;
+ };
+
+ // 鏃ユ湡纭浜嬩欢
+ const onDateConfirm = e => {
+ form.value.executionDate = formatDateToYMD(e.value);
+ // 淇濇寔pickerDateValue涓烘椂闂存埑鏍煎紡锛岃�屼笉鏄牸寮忓寲鐨勫瓧绗︿覆
+ pickerDateValue.value = e.value;
+ showDatePicker.value = false;
+ };
+
+ // 瀹㈡埛閫夋嫨浜嬩欢
+ const onCustomerSelect = item => {
+ form.value.customerName = item.name;
+ form.value.customerId = item.value;
+ };
+
+ // 鍘熸湁鐨勭‘璁ゆ柟娉曞凡琚柊鐨刟ction-sheet閫夋嫨鏂规硶鏇夸唬
+ const removeProduct = idx => {
+ productData.value.splice(idx, 1);
+ };
+
+ // 鏄剧ず閫夋嫨鍣�
+ const openCategoryPicker = idx => {
+ currentProductIndex.value = idx;
+ showCategoryPicker.value = true;
+ };
+
+ const openSpecificationPicker = idx => {
+ currentProductIndex.value = idx;
+ showSpecificationPicker.value = true;
+ };
+
+ const openTaxRatePicker = idx => {
+ currentProductIndex.value = idx;
+ showTaxRatePicker.value = true;
+ };
+
+ const openInvoiceTypePicker = idx => {
+ currentProductIndex.value = idx;
+ showInvoiceTypePicker.value = true;
+ };
+
+ // 閫夋嫨鍣ㄧ‘璁や簨浠�
+ const onCategoryConfirm = node => {
+ // 鑾峰彇閫変腑鐨勮妭鐐逛俊鎭�
+ console.log("selected node---", node);
+ // 瀛樺偍閫変腑鐨勮妭鐐癸紝鐢ㄤ簬纭鏃惰幏鍙栨暟鎹�
+ selectedCategoryNode.value = node;
+ };
+
+ // 纭浜у搧澶х被閫夋嫨
+ const confirmCategorySelection = () => {
+ if (selectedCategoryNode.value) {
+ // 璁剧疆閫変腑鐨勪骇鍝佸ぇ绫�
+ productData.value[currentProductIndex.value].productCategory =
+ selectedCategoryNode.value.label;
+ const id = selectedCategoryNode.value.id;
+ // 閲嶇疆閫変腑鐨勮妭鐐�
+ selectedCategoryNode.value = null;
+ productData.value[currentProductIndex.value].specificationModel = "";
+ productData.value[currentProductIndex.value].productModelId = "";
+ getModels(id);
+ }
+ showCategoryPicker.value = false;
+ };
+ // 鑾峰彇瑙勬牸鍨嬪彿
+ const getModels = value => {
+ modelList({ id: value }).then(res => {
+ modelOptions.value = res.map(user => ({
+ text: user.model,
+ value: user.id,
+ unit: user.unit,
+ speculativeTradingName: user.speculativeTradingName,
+ }));
+ });
+ };
+ // 瑙勬牸鍨嬪彿閫夋嫨浜嬩欢
+ const onSpecificationSelect = item => {
+ console.log("selected item---", item);
+ productData.value[currentProductIndex.value].specificationModel = item.name;
+ productData.value[currentProductIndex.value].productModelId = item.value;
+ productData.value[currentProductIndex.value].unit = item.unit;
+ productData.value[currentProductIndex.value].speculativeTradingName =
+ item.speculativeTradingName;
+ };
+ // 绋庣巼閫夋嫨浜嬩欢
+ const onTaxRateSelect = item => {
+ productData.value[currentProductIndex.value].taxRate = item.value;
+ // 閲嶆柊璁$畻涓嶅惈绋庢�讳环
+ const inclusiveTotalPrice = parseFloat(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice
+ );
+ const taxRate = parseFloat(item.value);
+ if (inclusiveTotalPrice && taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
+ }
+ };
+
+ // 鍙戠エ绫诲瀷閫夋嫨浜嬩欢
+ const onInvoiceTypeSelect = item => {
+ productData.value[currentProductIndex.value].invoiceType = item.name;
+ };
+
+ // 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
+ const formatTaxPrice = idx => {
+ if (productData.value[idx].taxInclusiveUnitPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[idx].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const quantity = parseFloat(productData.value[idx].quantity);
+ const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[idx].taxInclusiveTotalPrice = (
+ unitPrice * quantity
+ ).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[idx].taxRate) {
+ productData.value[idx].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[idx].taxInclusiveTotalPrice,
+ productData.value[idx].taxRate
+ );
+ }
+ };
+ // 鏁伴噺杈撳叆妗嗗け鐒�
+ const formatAmount = idx => {
+ if (productData.value[idx].quantity) {
+ const value = parseFloat(productData.value[idx].quantity);
+ if (!isNaN(value)) {
+ productData.value[idx].quantity = value.toFixed(2);
+ }
+ }
+ if (!productData.value[idx].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const quantity = parseFloat(productData.value[idx].quantity);
+ const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[idx].taxInclusiveTotalPrice = (
+ unitPrice * quantity
+ ).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[idx].taxRate) {
+ productData.value[idx].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[idx].taxInclusiveTotalPrice,
+ productData.value[idx].taxRate
+ );
+ }
+ };
+ // 鍚◣鎬讳环澶辩劍锛屾牴鎹惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+ const formatTaxTotal = idx => {
+ if (productData.value[idx].taxInclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ const totalPrice = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
+ const quantity = parseFloat(productData.value[idx].quantity);
+
+ if (!totalPrice || !quantity || quantity <= 0) {
+ return;
+ }
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[idx].taxInclusiveUnitPrice = (
+ totalPrice / quantity
+ ).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[idx].taxRate) {
+ productData.value[idx].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ totalPrice,
+ productData.value[idx].taxRate
+ );
+ }
+ };
+ // 涓嶅惈绋庢�讳环澶辩劍, 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+ const formatNoTaxTotal = idx => {
+ if (productData.value[idx].taxExclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[idx].taxRate) {
+ uni.showToast({
+ title: "璇峰厛閫夋嫨绋庣巼",
+ icon: "none",
+ });
+ return;
+ }
+ const exclusiveTotalPrice = parseFloat(
+ productData.value[idx].taxExclusiveTotalPrice
+ );
+ const quantity = parseFloat(productData.value[idx].quantity);
+ const taxRate = parseFloat(productData.value[idx].taxRate);
+ if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
+ return;
+ }
+ // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
+ const taxRateDecimal = taxRate / 100;
+ const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
+ productData.value[idx].taxInclusiveTotalPrice =
+ inclusiveTotalPrice.toFixed(2);
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[idx].taxInclusiveUnitPrice = (
+ inclusiveTotalPrice / quantity
+ ).toFixed(2);
+ };
+ const goBack = () => {
+ // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("operationType");
+ uni.removeStorageSync("editData");
+ uni.navigateBack();
+ };
+ const onSubmit = async () => {
+ // 棣栧厛鏍¢獙鍩烘湰琛ㄥ崟
+ const formValid = await formRef.value.validate().catch(() => false);
+ if (!formValid) {
+ return;
+ }
+
+ // 鏍¢獙浜у搧淇℃伅
+ if (!productData.value || productData.value.length === 0) {
+ uni.showToast({
+ title: "璇锋坊鍔犱骇鍝佷俊鎭�",
+ icon: "none",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ瘡涓骇鍝佹槸鍚﹀~鍐欏畬鏁�
+ for (let i = 0; i < productData.value.length; i++) {
+ const product = productData.value[i];
+ // 浼樺寲鏁板瓧瀛楁楠岃瘉锛屽鐞嗗彲鑳界殑瀛楃涓叉牸寮忔暟鍊�
+ const taxInclusiveUnitPrice = parseFloat(product.taxInclusiveUnitPrice);
+ const quantity = parseFloat(product.quantity);
+ const taxInclusiveTotalPrice = parseFloat(product.taxInclusiveTotalPrice);
+ const taxExclusiveTotalPrice = parseFloat(product.taxExclusiveTotalPrice);
+
+ if (!product.productCategory) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳閫夋嫨浜у搧澶х被`,
+ icon: "none",
+ });
+ return;
+ }
+ if (!product.specificationModel) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳閫夋嫨瑙勬牸鍨嬪彿`,
+ icon: "none",
+ });
+ return;
+ }
+ if (!product.unit) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳杈撳叆鍗曚綅`,
+ icon: "none",
+ });
+ return;
+ }
+ if (!product.taxRate) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳閫夋嫨绋庣巼`,
+ icon: "none",
+ });
+ return;
+ }
+ if (isNaN(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庡崟浠穈,
+ icon: "none",
+ });
+ return;
+ }
+ if (isNaN(quantity) || quantity <= 0) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勬暟閲廯,
+ icon: "none",
+ });
+ return;
+ }
+ if (isNaN(taxInclusiveTotalPrice) || taxInclusiveTotalPrice <= 0) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勫惈绋庢�讳环`,
+ icon: "none",
+ });
+ return;
+ }
+ if (isNaN(taxExclusiveTotalPrice) || taxExclusiveTotalPrice <= 0) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳杈撳叆鏈夋晥鐨勪笉鍚◣鎬讳环`,
+ icon: "none",
+ });
+ return;
+ }
+ if (!product.invoiceType) {
+ uni.showToast({
+ title: `浜у搧${i + 1}锛氳閫夋嫨鍙戠エ绫诲瀷`,
+ icon: "none",
+ });
+ return;
+ }
+ }
+
+ // 琛ㄥ崟鏍¢獙閫氳繃锛屾彁浜ゆ暟鎹�
+ form.value.productData = JSON.parse(JSON.stringify(productData.value));
+ form.value.type = 1;
+ addOrUpdateSalesLedger(form.value).then(res => {
+ uni.showToast({
+ title: "鎻愪氦鎴愬姛",
+ icon: "success",
+ });
+ goBack();
+ });
+ };
+ const setUserInfo = () => {
+ form.value.entryPerson = userStore.id;
+ form.value.entryPersonName = userStore.nickName;
+ // 璁剧疆褰撳ぉ鏃ユ湡
+ 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");
+ form.value.entryDate = `${year}-${month}-${day}`;
+ // 璁剧疆鏃ユ湡閫夋嫨鍣ㄩ粯璁ゅ�间负浠婂ぉ
+ pickerDateValue.value = `${year}-${month}-${day}`;
+ };
+ // 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
+ const fillFormData = () => {
+ if (!editData.value) return;
+ getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then(res => {
+ productData.value = res.productData;
+ });
+ console.log(editData.value);
+ // 濉厖鍩烘湰淇℃伅
+ form.value.salesContractNo = editData.value.salesContractNo || "";
+ form.value.customerName = editData.value.customerName || "";
+ form.value.projectName = editData.value.projectName || "";
+ form.value.executionDate = editData.value.executionDate || "";
+ form.value.paymentMethod = editData.value.paymentMethod || "";
+ form.value.salesman = editData.value.salesman || "";
+ form.value.entryPerson = editData.value.entryPerson || "";
+ form.value.entryPersonName = editData.value.entryPersonName || "";
+ form.value.entryDate = editData.value.entryDate || "";
+ form.value.id = editData.value.id || "";
+ form.value.customerId = editData.value.customerId || "";
+
+ // 璁剧疆鏃ユ湡閫夋嫨鍣ㄧ殑鍊�
+ if (editData.value.executionDate) {
+ pickerDateValue.value = editData.value.executionDate;
+ }
+ };
+ const getUserList = () => {
+ userListNoPage().then(res => {
+ // 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
+ userList.value = res.data.map(user => ({
+ text: user.nickName,
+ value: user.nickName,
+ }));
+ });
+ };
+ const getCustomerList = () => {
+ customerList().then(res => {
+ // 绉婚櫎澶氫綑鐨勬暟缁勫寘瑁�
+ customerOption.value = res.map(item => ({
+ text: item.customerName,
+ value: item.id,
+ }));
+ });
+ };
+ const convertIdToValue = data => {
+ // 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
+ if (!Array.isArray(data)) {
+ return [];
+ }
+ // 閫掑綊鏄犲皠鍑芥暟
+ return data.map(item => {
+ // 鍒涘缓鏂板璞★紝鏄犲皠瀛楁
+ const mappedItem = {
+ label: item.label, // 鍏抽敭锛氬皢 label 鏄犲皠涓� text
+ id: item.id, // 淇濈暀 id
+ };
+ // 濡傛灉瀛樺湪 children 鏁扮粍锛屽垯閫掑綊澶勭悊
+ if (
+ item.children &&
+ Array.isArray(item.children) &&
+ item.children.length > 0
+ ) {
+ mappedItem.children = convertIdToValue(item.children);
+ }
+ return mappedItem;
+ });
+ };
+ // 鑾峰彇浜у搧澶х被tree鏁版嵁
+ const getProductOptions = () => {
+ productTreeList().then(res => {
+ productOptions.value = convertIdToValue(res);
+ });
+ };
+
+ onMounted(() => {
+ // 鑾峰彇椤甸潰鍙傛暟
+ operationType.value = uni.getStorageSync("operationType") || "";
+
+ // 鑾峰彇浜哄憳鍒楄〃
+ getUserList();
+ // 鑾峰彇瀹㈡埛鍒楄〃
+ getCustomerList();
+ // 鑾峰彇浜у搧澶х被tree鏁版嵁
+ getProductOptions();
+ // 璧嬪�奸粯璁や俊鎭�
+ if (operationType.value === "add") {
+ setUserInfo();
+ }
+
+ // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
+ const editDataStr = uni.getStorageSync("editData");
+ if (editDataStr) {
+ try {
+ editData.value = JSON.parse(editDataStr);
+ // 濡傛灉鏄紪杈戞ā寮忥紝绛夊緟鏁版嵁鍔犺浇瀹屾垚鍚庡~鍏呰〃鍗曟暟鎹�
+ if (operationType.value !== "add" && editData.value) {
+ // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
+ setTimeout(() => {
+ fillFormData();
+ }, 100);
+ }
+ } catch (error) {
+ console.error("瑙f瀽缂栬緫鏁版嵁澶辫触:", error);
+ }
+ }
+ });
</script>
<style lang="scss">
-@import '@/static/scss/form-common.scss';
+ @import "@/static/scss/form-common.scss";
</style>
diff --git a/src/pages/sales/salesAccount/goOut.vue b/src/pages/sales/salesAccount/goOut.vue
new file mode 100644
index 0000000..9980e5f
--- /dev/null
+++ b/src/pages/sales/salesAccount/goOut.vue
@@ -0,0 +1,657 @@
+<template>
+ <view class="account-detail">
+ <PageHeader title="鍙戣揣"
+ @back="goBack" />
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <u-form ref="formRef"
+ @submit="submitForm"
+ :rules="rules"
+ :model="form"
+ label-width="140rpx">
+ <u-form-item prop="typeValue"
+ label="鍙戣揣绫诲瀷"
+ required>
+ <u-input v-model="typeValue"
+ readonly
+ placeholder="璇烽�夋嫨鍙戣揣鏂瑰紡"
+ @click="showPicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showPicker = true"></up-icon>
+ </template>
+ </u-form-item>
+ </u-form>
+ <!-- 閫夋嫨鍣ㄥ脊绐� -->
+ <up-action-sheet :show="showPicker"
+ :actions="productOptions"
+ title="鍙戣揣鏂瑰紡"
+ @select="onConfirm"
+ @close="showPicker = false" />
+ <!-- 瀹℃牳娴佺▼鍖哄煙 -->
+ <view class="approval-process">
+ <view class="approval-header">
+ <text class="approval-title">瀹℃牳娴佺▼</text>
+ <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
+ </view>
+ <view class="approval-steps">
+ <view v-for="(step, stepIndex) in approverNodes"
+ :key="stepIndex"
+ class="approval-step">
+ <view class="step-dot"></view>
+ <view class="step-title">
+ <text>瀹℃壒浜�</text>
+ </view>
+ <view class="approver-container">
+ <view v-if="step.nickName"
+ class="approver-item">
+ <view class="approver-avatar">
+ <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
+ <view class="status-dot"></view>
+ </view>
+ <view class="approver-info">
+ <text class="approver-name">{{ step.nickName }}</text>
+ </view>
+ <view class="delete-approver-btn"
+ @click="removeApprover(stepIndex)">脳</view>
+ </view>
+ <view v-else
+ class="add-approver-btn"
+ @click="addApprover(stepIndex)">
+ <view class="add-circle">+</view>
+ <text class="add-label">閫夋嫨瀹℃壒浜�</text>
+ </view>
+ </view>
+ <view class="step-line"
+ v-if="stepIndex < approverNodes.length - 1"></view>
+ <view class="delete-step-btn"
+ v-if="approverNodes.length > 1"
+ @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
+ </view>
+ </view>
+ <view class="add-step-btn">
+ <u-button icon="plus"
+ plain
+ type="primary"
+ style="width: 100%"
+ @click="addApprovalStep">鏂板鑺傜偣</u-button>
+ </view>
+ </view>
+ <!-- 搴曢儴鎸夐挳 -->
+ <view class="footer-btns">
+ <u-button class="cancel-btn"
+ @click="goBack">鍙栨秷</u-button>
+ <u-button class="save-btn"
+ @click="submitForm">鍙戣揣</u-button>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { addShippingInfo } from "@/api/salesManagement/salesLedger";
+ const showToast = message => {
+ uni.showToast({
+ title: message,
+ icon: "none",
+ });
+ };
+ import { userListNoPageByTenantId } from "@/api/system/user";
+
+ const data = reactive({
+ form: {
+ approveTime: "",
+ approveId: "",
+ approveUser: "",
+ approveUserName: "",
+ approveDeptName: "",
+ approveDeptId: "",
+ approveReason: "",
+ checkResult: "",
+ tempFileIds: [],
+ approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
+ startDate: "",
+ endDate: "",
+ location: "",
+ price: "",
+ },
+ rules: {
+ typeValue: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+ });
+ const { form, rules } = toRefs(data);
+ const showPicker = ref(false);
+ const productOptions = ref([
+ {
+ value: "璐ц溅",
+ name: "璐ц溅",
+ },
+ {
+ value: "蹇��",
+ name: "蹇��",
+ },
+ ]);
+ const operationType = ref("");
+ const currentApproveStatus = ref("");
+ const approverNodes = ref([]);
+ const userList = ref([]);
+ const formRef = ref(null);
+ const approveType = ref(0);
+ const goOutData = ref({});
+ onMounted(async () => {
+ try {
+ userListNoPageByTenantId().then(res => {
+ userList.value = res.data;
+ });
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧彂璐ц鎯�
+ goOutData.value = JSON.parse(uni.getStorageSync("goOutData"));
+ console.log(goOutData.value, "goOutData.value");
+
+ // 鍒濆鍖栧鎵规祦绋嬭妭鐐癸紝榛樿涓�涓妭鐐�
+ approverNodes.value = [{ id: 1, userId: null }];
+
+ // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
+ uni.$on("selectContact", handleSelectContact);
+ } catch (error) {
+ console.error("鑾峰彇澶辫触:", error);
+ }
+ });
+
+ onUnmounted(() => {
+ // 绉婚櫎浜嬩欢鐩戝惉
+ uni.$off("selectContact", handleSelectContact);
+ });
+ const typeValue = ref("璐ц溅");
+ const onConfirm = item => {
+ // 璁剧疆閫変腑鐨勯儴闂�
+ typeValue.value = item.name;
+ showPicker.value = false;
+ };
+
+ const goBack = () => {
+ // 娓呴櫎鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("operationType");
+ uni.removeStorageSync("invoiceLedgerEditRow");
+ uni.removeStorageSync("approveType");
+ uni.navigateBack();
+ };
+
+ const submitForm = () => {
+ // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
+ const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
+ if (hasEmptyStep) {
+ showToast("璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�");
+ return;
+ }
+ formRef.value
+ .validate()
+ .then(valid => {
+ if (valid) {
+ // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
+ // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
+ console.log("approverNodes---", approverNodes.value);
+ const approveUserIds = approverNodes.value
+ .map(node => node.userId)
+ .join(",");
+ const params = {
+ salesLedgerId: goOutData.value.salesLedgerId,
+ salesLedgerProductId: goOutData.value.id,
+ type: typeValue.value,
+ approveUserIds,
+ };
+ console.log(params, "params");
+
+ addShippingInfo(params).then(res => {
+ showToast("鍙戣揣鎴愬姛");
+ setTimeout(() => {
+ goBack();
+ }, 500);
+ });
+ }
+ })
+ .catch(error => {
+ console.error("琛ㄥ崟鏍¢獙澶辫触:", error);
+ // 灏濊瘯鑾峰彇鍏蜂綋鐨勯敊璇瓧娈�
+ if (error && error.errors) {
+ const firstError = error.errors[0];
+ if (firstError) {
+ uni.showToast({
+ title: firstError.message || "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ return;
+ }
+ }
+ // 鏄剧ず閫氱敤閿欒淇℃伅
+ uni.showToast({
+ title: "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
+ icon: "none",
+ });
+ });
+ };
+
+ // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
+ const handleSelectContact = data => {
+ const { stepIndex, contact } = data;
+ // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = contact.userId;
+ approverNodes.value[stepIndex].nickName = contact.nickName;
+ };
+
+ const addApprover = stepIndex => {
+ // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
+ uni.setStorageSync("stepIndex", stepIndex);
+ uni.navigateTo({
+ url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
+ });
+ };
+
+ const addApprovalStep = () => {
+ // 娣诲姞鏂扮殑瀹℃壒姝ラ
+ approverNodes.value.push({ userId: null, nickName: null });
+ };
+
+ const removeApprover = stepIndex => {
+ // 绉婚櫎瀹℃壒浜�
+ approverNodes.value[stepIndex].userId = null;
+ approverNodes.value[stepIndex].nickName = null;
+ };
+
+ const removeApprovalStep = stepIndex => {
+ // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
+ if (approverNodes.value.length > 1) {
+ approverNodes.value.splice(stepIndex, 1);
+ } else {
+ uni.showToast({
+ title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
+ icon: "none",
+ });
+ }
+ };
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+
+ .approval-process {
+ background: #fff;
+ margin: 16px;
+ border-radius: 16px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+ }
+
+ .approval-header {
+ margin-bottom: 16px;
+ }
+
+ .approval-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ display: block;
+ margin-bottom: 4px;
+ }
+
+ .approval-desc {
+ font-size: 12px;
+ color: #999;
+ }
+
+ /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
+ .approval-steps {
+ padding-left: 22px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 11px;
+ top: 40px;
+ bottom: 40px;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ #e6f7ff 0%,
+ #bae7ff 50%,
+ #91d5ff 100%
+ );
+ border-radius: 1px;
+ }
+ }
+
+ .approval-step {
+ position: relative;
+ margin-bottom: 24px;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: -18px;
+ top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
+ width: 12px;
+ height: 12px;
+ background: #fff;
+ border: 3px solid #006cfb;
+ border-radius: 50%;
+ z-index: 2;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ .step-title {
+ top: 12px;
+ margin-bottom: 12px;
+ position: relative;
+ margin-left: 6px;
+ }
+
+ .step-title text {
+ font-size: 14px;
+ color: #666;
+ background: #f0f0f0;
+ padding: 4px 12px;
+ border-radius: 12px;
+ position: relative;
+ line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ padding: 16px;
+ gap: 12px;
+ position: relative;
+ border: 1px solid #e6f7ff;
+ box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
+ transition: all 0.3s ease;
+ }
+
+ .approver-avatar {
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+ }
+
+ .avatar-text {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+ }
+
+ .approver-info {
+ flex: 1;
+ position: relative;
+ }
+
+ .approver-name {
+ display: block;
+ font-size: 16px;
+ color: #333;
+ font-weight: 500;
+ position: relative;
+ }
+
+ .approver-dept {
+ font-size: 12px;
+ color: #999;
+ background: rgba(0, 108, 251, 0.05);
+ padding: 2px 8px;
+ border-radius: 8px;
+ display: inline-block;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 4px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 2px;
+ height: 2px;
+ background: #006cfb;
+ border-radius: 50%;
+ }
+ }
+
+ .delete-approver-btn {
+ font-size: 16px;
+ color: #ff4d4f;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s ease;
+ position: relative;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
+ border: 2px dashed #006cfb;
+ border-radius: 16px;
+ padding: 20px;
+ color: #006cfb;
+ font-size: 14px;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: 32px;
+ height: 32px;
+ border: 2px solid #006cfb;
+ border-radius: 50%;
+ opacity: 0;
+ transition: all 0.3s ease;
+ }
+ }
+
+ .delete-step-btn {
+ color: #ff4d4f;
+ font-size: 12px;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 77, 79, 0.1) 0%,
+ rgba(255, 77, 79, 0.05) 100%
+ );
+ padding: 6px 12px;
+ border-radius: 12px;
+ display: inline-block;
+ position: relative;
+ transition: all 0.3s ease;
+
+ &::before {
+ content: "";
+ position: absolute;
+ left: 6px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 4px;
+ height: 4px;
+ background: #ff4d4f;
+ border-radius: 50%;
+ }
+ }
+
+ .step-line {
+ display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
+ }
+
+ .add-step-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ .footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+ z-index: 1000;
+ }
+
+ .cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 6.375rem;
+ background: #c7c9cc;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ .save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #ffffff;
+ width: 14rem;
+ background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+ }
+
+ // 鍔ㄧ敾瀹氫箟
+ @keyframes pulse {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.7;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ }
+
+ @keyframes rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes ripple {
+ 0% {
+ transform: translate(-50%, -50%) scale(0.8);
+ opacity: 1;
+ }
+ 100% {
+ transform: translate(-50%, -50%) scale(1.6);
+ opacity: 0;
+ }
+ }
+
+ /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
+ .step-line {
+ position: absolute;
+ left: 4px;
+ top: 48px;
+ width: 2px;
+ height: calc(100% - 48px);
+ background: #e5e7eb;
+ }
+
+ .approver-container {
+ display: flex;
+ align-items: center;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 16px;
+ gap: 12px;
+ padding: 10px 0;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ }
+
+ .approver-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 10px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ border-radius: 0;
+ }
+
+ .approver-avatar {
+ position: relative;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: #f3f4f6;
+ border: 2px solid #e5e7eb;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
+ }
+
+ .avatar-text {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 600;
+ }
+
+ .add-approver-btn {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ padding: 0;
+ }
+
+ .add-approver-btn .add-circle {
+ width: 40px;
+ height: 40px;
+ border: 2px dashed #a0aec0;
+ border-radius: 50%;
+ color: #6b7280;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ line-height: 1;
+ }
+
+ .add-approver-btn .add-label {
+ color: #3b82f6;
+ font-size: 14px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/sales/salesAccount/index.vue b/src/pages/sales/salesAccount/index.vue
index 83ed3dd..d6a3d8c 100644
--- a/src/pages/sales/salesAccount/index.vue
+++ b/src/pages/sales/salesAccount/index.vue
@@ -1,197 +1,305 @@
<template>
- <view class="sales-account">
- <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="閿�鍞彴璐�" @back="goBack" />
-
- <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
- <view class="search-section">
- <view class="search-bar">
- <view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
- v-model="salesContractNo"
- @change="getList"
- clearable
- />
- </view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
- </view>
- </view>
- </view>
-
- <!-- 閿�鍞彴璐︾�戝竷娴� -->
- <view class="ledger-list" v-if="total > 0">
- <view v-for="(item, index) in ledgerList" :key="index">
- <view class="ledger-item" @click="handleInfo('edit', item)">
- <view class="item-header">
- <view class="item-left">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="item-id">{{ item.salesContractNo }}</text>
- </view>
- <!-- <view class="item-tag">-->
- <!-- <text class="tag-text">{{ item.recorder }}</text>-->
- <!-- </view>-->
- </view>
- <up-divider></up-divider>
-
- <view class="item-details">
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚嶇О</text>
- <text class="detail-value">{{ item.customerName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="detail-value">{{ item.customerContractNo }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">涓氬姟鍛�</text>
- <text class="detail-value">{{ item.salesman }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">椤圭洰鍚嶇О</text>
- <text class="detail-value">{{ item.projectName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">浠樻鏂瑰紡</text>
- <text class="detail-value">{{ item.paymentMethod }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
- <text class="detail-value highlight">{{ item.contractAmount }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">绛捐鏃ユ湡</text>
- <text class="detail-value">{{ item.executionDate }}</text>
- </view>
- <up-divider></up-divider>
- <view class="detail-info">
- <view class="detail-row">
- <text class="detail-label">褰曞叆浜�</text>
- <text class="detail-value">{{ item.entryPersonName }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">褰曞叆鏃ユ湡</text>
- <text class="detail-value">{{ item.entryDate }}</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-else class="no-data">
- <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
- </view>
-
- <!-- 娴姩鎿嶄綔鎸夐挳 -->
- <view class="fab-button" @click="handleInfo('add')">
- <up-icon name="plus" size="24" color="#ffffff"></up-icon>
- </view>
- </view>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="閿�鍞彴璐�"
+ @back="goBack" />
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ラ攢鍞悎鍚屽彿鎼滅储"
+ v-model="salesContractNo"
+ @change="getList"
+ clearable />
+ </view>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <!-- 閿�鍞彴璐︾�戝竷娴� -->
+ <view class="ledger-list"
+ v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList"
+ :key="index">
+ <view class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.salesContractNo }}</text>
+ </view>
+ <!-- <view class="item-tag">-->
+ <!-- <text class="tag-text">{{ item.recorder }}</text>-->
+ <!-- </view>-->
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">瀹㈡埛鍚嶇О</text>
+ <text class="detail-value">{{ item.customerName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓氬姟鍛�</text>
+ <text class="detail-value">{{ item.salesman }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻鏂瑰紡</text>
+ <text class="detail-value">{{ item.paymentMethod }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绛捐鏃ユ湡</text>
+ <text class="detail-value">{{ item.executionDate }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.entryPersonName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ item.entryDate }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-buttons">
+ <u-button class="detail-button"
+ size="small"
+ type="primary"
+ plain
+ @click.stop="openOut(item)">
+ 鍙戣揣鐘舵��
+ </u-button>
+ <!-- <u-button class="detail-button"
+ size="small"
+ type="primary"
+ @click.stop="handleInfo('edit', item)">
+ 缂栬緫
+ </u-button>
+ <u-button class="detail-button"
+ size="small"
+ type="primary"
+ plain
+ @click.stop="openOut(item)">
+ 鍙戣揣鐘舵��
+ </u-button> -->
+ <!-- <u-button class="detail-button"
+ size="small"
+ type="error"
+ plain
+ @click.stop="handleDelete(item)">
+ 鍒犻櫎
+ </u-button> -->
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤閿�鍞彴璐︽暟鎹�</text>
+ </view>
+ <!-- 娴姩鎿嶄綔鎸夐挳 -->
+ <!-- <view class="fab-button"
+ @click="handleInfo('add')">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
+ </view> -->
+ </view>
</template>
<script setup>
-import { ref } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import {ledgerListPage} from "@/api/salesManagement/salesLedger";
-import useUserStore from "@/store/modules/user";
-import PageHeader from "@/components/PageHeader.vue";
-const userStore = useUserStore()
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- })
-}
-const closeToast = () => {
- uni.hideLoading()
-}
+ import { ref } from "vue";
+ import { onShow } from "@dcloudio/uni-app";
+ import {
+ ledgerListPage,
+ delLedger,
+ productList,
+ } from "@/api/salesManagement/salesLedger";
+ import useUserStore from "@/store/modules/user";
+ import PageHeader from "@/components/PageHeader.vue";
+ const userStore = useUserStore();
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+ const closeToast = () => {
+ uni.hideLoading();
+ };
-// 鎼滅储鍏抽敭璇�
-const salesContractNo = ref('');
+ // 鎼滅储鍏抽敭璇�
+ const salesContractNo = ref("");
-// 閿�鍞彴璐︽暟鎹�
-const ledgerList = ref([]);
-const total = ref(0);
+ // 閿�鍞彴璐︽暟鎹�
+ const ledgerList = ref([]);
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack();
-};
-// 鏌ヨ鍒楄〃
-const getList = () => {
- showLoadingToast('鍔犺浇涓�...')
- const page = {
- current: -1,
- size: -1
- }
- ledgerListPage({...page, salesContractNo: salesContractNo.value}).then((res) => {
- ledgerList.value = res.records;
- total.value = res.total;
- closeToast()
- }).catch(() => {
- closeToast()
- });
-};
+ // 鍒ゆ柇鏄惁瀛樺湪宸插彂璐�/鍙戣揣瀹屾垚鐨勪骇鍝�
+ const hasShippedProducts = products => {
+ if (!products || products.length === 0) return false;
+ return products.some(p => {
+ const statusStr = (p.shippingStatus ?? "").toString();
+ // 鍖呭惈鈥滃彂璐р�濇垨鏈夊彂璐ф棩鏈�/杞︾墝鍙疯涓哄凡鍙戣揣
+ return (
+ statusStr.includes("鍙戣揣") || !!p.shippingDate || !!p.shippingCarNumber
+ );
+ });
+ };
-// 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
-const handleInfo = (type, row) => {
- try {
- // 璁剧疆鎿嶄綔绫诲瀷
- uni.setStorageSync('operationType', type);
-
- // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
- if (type !== 'add') {
- // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
- if (!row) {
- uni.showToast({
- title: '鏁版嵁涓嶅瓨鍦�',
- icon: 'error'
- });
- return;
- }
-
- // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
- if (row.entryPerson != userStore.id) {
- // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
- uni.setStorageSync('editData', JSON.stringify(row));
- uni.navigateTo({
- url: '/pages/sales/salesAccount/view'
- });
- return;
- }
-
- // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
- uni.setStorageSync('editData', JSON.stringify(row));
- uni.navigateTo({
- url: '/pages/sales/salesAccount/detail'
- });
- return;
- }
-
- // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
- uni.navigateTo({
- url: '/pages/sales/salesAccount/detail'
- });
-
- } catch (error) {
- console.error('澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:', error);
- uni.showToast({
- title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
- icon: 'error'
- });
- }
-};
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ const page = {
+ current: -1,
+ size: -1,
+ };
+ ledgerListPage({ ...page, salesContractNo: salesContractNo.value })
+ .then(res => {
+ console.log("閿�鍞彴璐�----", res);
+ ledgerList.value = res.records;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ });
+ };
+ const openOut = item => {
+ uni.setStorageSync("outData", JSON.stringify(item));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/out",
+ });
+ };
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
- getList();
-});
+ // 鍒犻櫎鍗曟潯閿�鍞彴璐�
+ const handleDelete = async row => {
+ if (!row || !row.id) return;
+
+ // 鑾峰彇浜у搧鍒楄〃锛岀敤浜庡垽鏂槸鍚﹀凡鍙戣揣
+ let products = row.children && row.children.length > 0 ? row.children : null;
+ if (!products) {
+ try {
+ const res = await productList({ salesLedgerId: row.id, type: 1 });
+ products = res.data || res.records || [];
+ } catch (e) {
+ products = [];
+ }
+ }
+
+ if (hasShippedProducts(products)) {
+ uni.showToast({
+ title: "宸插彂璐�/鍙戣揣瀹屾垚鐨勯攢鍞鍗曚笉鑳藉垹闄�",
+ icon: "none",
+ });
+ return;
+ }
+
+ uni.showModal({
+ title: "鍒犻櫎纭",
+ content: "閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
+ success: async res => {
+ if (res.confirm) {
+ try {
+ showLoadingToast("澶勭悊涓�...");
+ await delLedger([row.id]);
+ closeToast();
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ getList();
+ } catch (e) {
+ closeToast();
+ uni.showToast({
+ title: "鍒犻櫎澶辫触锛岃閲嶈瘯",
+ icon: "none",
+ });
+ }
+ }
+ },
+ });
+ };
+ // 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
+ const handleInfo = (type, row) => {
+ try {
+ // 璁剧疆鎿嶄綔绫诲瀷
+ uni.setStorageSync("operationType", type);
+ uni.removeStorageSync("editData");
+
+ // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
+ if (type !== "add") {
+ // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
+ if (!row) {
+ uni.showToast({
+ title: "鏁版嵁涓嶅瓨鍦�",
+ icon: "error",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
+ if (row.entryPerson != userStore.id) {
+ // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
+ uni.setStorageSync("editData", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/view",
+ });
+ return;
+ }
+
+ // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
+ uni.setStorageSync("editData", JSON.stringify(row));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/detail",
+ });
+ return;
+ }
+
+ // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/detail",
+ });
+ } catch (error) {
+ console.error("澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:", error);
+ uni.showToast({
+ title: "鎿嶄綔澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+ });
</script>
<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
+ @import "@/styles/sales-common.scss";
+ .detail-buttons {
+ display: flex;
+ gap: 10px;
+ justify-content: space-between;
+ }
</style>
diff --git a/src/pages/sales/salesAccount/out.vue b/src/pages/sales/salesAccount/out.vue
new file mode 100644
index 0000000..d4fc5be
--- /dev/null
+++ b/src/pages/sales/salesAccount/out.vue
@@ -0,0 +1,407 @@
+<template>
+ <view class="receipt-payment-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍙戣揣鐘舵��"
+ @back="goBack" />
+ <!-- 缁熻淇℃伅 -->
+ <view class="summary-info">
+ <view class="summary-item">
+ <text class="summary-label">瀹㈡埛鍚嶇О</text>
+ <text class="summary-value">{{ outData.customerName }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">鍚堝悓閲戦</text>
+ <text class="summary-value">{{ outData.contractAmount }}</text>
+ </view>
+ <view class="summary-item">
+ <text class="summary-label">绛捐鏃ユ湡</text>
+ <text class="summary-value">{{ outData.executionDate }}</text>
+ </view>
+ </view>
+ <!-- 鍥炴璁板綍鏄庣粏鍒楄〃 -->
+ <view class="detail-list"
+ v-if="tableData.length > 0">
+ <view v-for="(item, index) in tableData"
+ :key="index"
+ class="detail-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="record-icon">
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-index">{{ item.productCategory }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">浜у搧澶х被</text>
+ <text class="detail-value">{{ item.productCategory }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">瑙勬牸鍨嬪彿</text>
+ <text class="detail-value">{{ item.specificationModel }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍗曚綅</text>
+ <text class="detail-value">{{ item.unit }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浜у搧鐘舵��</text>
+ <text v-if="item.approveStatus === 1"
+ class="detail-value highlight">鍏呰冻</text>
+ <text v-else
+ class="detail-value danger">涓嶈冻</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣鐘舵��</text>
+ <u-tag size="mini"
+ :type="getShippingStatusType(item)">{{ getShippingStatusText(item) }}</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">蹇�掑叕鍙�</text>
+ <text class="detail-value">{{ item.expressCompany }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">蹇�掑崟鍙�</text>
+ <text class="detail-value">{{ item.expressNumber }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣杞︾墝</text>
+ <u-tag size="mini"
+ v-if="item.shippingCarNumber"
+ type="success">{{ item.shippingCarNumber }}</u-tag>
+ <u-tag v-else
+ size="mini"
+ type="info">-</u-tag>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙戣揣鏃ユ湡</text>
+ <text class="detail-value">{{ item.shippingDate || '-' }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鏁伴噺</text>
+ <text class="detail-value">{{ item.quantity }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">绋庣巼锛�%锛�</text>
+ <text class="detail-value">{{ item.taxRate }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚◣鍗曚环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxInclusiveUnitPrice }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚◣鎬讳环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxInclusiveTotalPrice }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">涓嶅惈绋庢�讳环锛堝厓锛�</text>
+ <text class="detail-value">{{ item.taxExclusiveTotalPrice }}</text>
+ </view>
+ <up-divider></up-divider>
+ <u-button class="detail-button"
+ size="small"
+ type="primary"
+ :disabled="!canShip(item)"
+ @click="goout(item)">
+ 鍙戣揣
+ </u-button>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤鍥炴璁板綍</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, computed, onMounted } from "vue";
+ import { productList } from "@/api/salesManagement/salesLedger";
+
+ // 瀹㈡埛淇℃伅
+ const supplierId = ref("");
+
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.removeStorageSync("supplierId");
+ uni.navigateBack();
+ };
+ const getShippingStatusType = row => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀虹豢鑹�
+ if (row.shippingDate || row.shippingCarNumber) {
+ return "success";
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓虹伆鑹诧紙寰呭彂璐э級
+ if (status === null || status === undefined || status === "") {
+ return "info";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const typeTextMap = {
+ 寰呭彂璐�: "info",
+ 寰呭鏍�: "info",
+ 瀹℃牳涓�: "warning",
+ 瀹℃牳鎷掔粷: "danger",
+ 瀹℃牳閫氳繃: "success",
+ 宸插彂璐�: "success",
+ };
+ return typeTextMap[statusStr] || "info";
+ };
+ const getShippingStatusText = row => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀�"宸插彂璐�"
+ if (row.shippingDate || row.shippingCarNumber) {
+ return "宸插彂璐�";
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓�"寰呭彂璐�"
+ if (status === null || status === undefined || status === "") {
+ return "寰呭彂璐�";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const statusTextMap = {
+ 寰呭彂璐�: "寰呭彂璐�",
+ 寰呭鏍�: "寰呭鏍�",
+ 瀹℃牳涓�: "瀹℃牳涓�",
+ 瀹℃牳鎷掔粷: "瀹℃牳鎷掔粷",
+ 瀹℃牳閫氳繃: "瀹℃牳閫氳繃",
+ 宸插彂璐�: "宸插彂璐�",
+ };
+ return statusTextMap[statusStr] || "寰呭彂璐�";
+ };
+ // 鑾峰彇椤甸潰鍙傛暟
+ const getPageParams = () => {
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栦緵搴斿晢ID
+ const storedSupplierId = uni.getStorageSync("supplierId");
+ if (storedSupplierId) {
+ supplierId.value = storedSupplierId;
+ }
+ };
+ const goout = item => {
+ uni.setStorageSync("goOutData", JSON.stringify(item));
+ uni.navigateTo({
+ url: "/pages/sales/salesAccount/goOut",
+ });
+ };
+
+ // 鏌ヨ鍒楄〃
+ const getList = () => {
+ showLoadingToast("鍔犺浇涓�...");
+ productList({
+ salesLedgerId: outData.value.id,
+ type: 1,
+ })
+ .then(res => {
+ tableData.value = res.data;
+ closeToast();
+ })
+ .catch(() => {
+ closeToast();
+ uni.showToast({
+ title: "鏌ヨ澶辫触",
+ icon: "error",
+ });
+ });
+ };
+ const canShip = row => {
+ // 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
+ if (row.approveStatus !== 1) {
+ return false;
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵��
+ const shippingStatus = row.shippingStatus;
+
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
+ if (row.shippingDate || row.shippingCarNumber) {
+ return false;
+ }
+
+ // 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
+ const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
+ return statusStr === "寰呭彂璐�" || statusStr === "瀹℃牳鎷掔粷";
+ };
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ const showLoadingToast = message => {
+ uni.showLoading({
+ title: message,
+ mask: true,
+ });
+ };
+
+ // 鍏抽棴鎻愮ず
+ const closeToast = () => {
+ uni.hideLoading();
+ };
+ const outData = ref({});
+
+ onMounted(() => {
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧弬鏁板苟鍒锋柊鍒楄〃
+ getPageParams();
+ // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧彂璐х姸鎬佹暟鎹�
+ outData.value = JSON.parse(uni.getStorageSync("outData"));
+ getList();
+ });
+</script>
+
+<style scoped lang="scss">
+ .receipt-payment-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+ }
+
+ .u-divider {
+ margin: 0 !important;
+ }
+
+ .summary-info {
+ background: #ffffff;
+ margin: 20px 20px 0 20px;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
+
+ .summary-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .summary-label {
+ font-size: 14px;
+ color: #666;
+ }
+
+ .summary-value {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .summary-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
+
+ .summary-value.danger {
+ color: #ff4757;
+ font-weight: 600;
+ }
+
+ .detail-list {
+ padding: 20px;
+ }
+
+ .detail-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+ }
+
+ .item-header {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .record-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .item-index {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .item-date {
+ font-size: 12px;
+ color: #666;
+ }
+
+ .item-details {
+ padding: 16px 0;
+ }
+
+ .detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+ }
+
+ .detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+ }
+
+ .detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+ }
+
+ .detail-value.danger {
+ color: #ff4757;
+ font-weight: 500;
+ }
+
+ .no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+ }
+</style>
diff --git a/src/pages/sales/salesAccount/view.vue b/src/pages/sales/salesAccount/view.vue
index acfb6e0..53ffab5 100644
--- a/src/pages/sales/salesAccount/view.vue
+++ b/src/pages/sales/salesAccount/view.vue
@@ -1,8 +1,8 @@
<template>
<view class="account-view">
<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
- <PageHeader title="鍙拌处璇︽儏" @back="goBack" />
-
+ <PageHeader title="鍙拌处璇︽儏"
+ @back="goBack" />
<!-- 鍩烘湰淇℃伅灞曠ず -->
<view class="info-section">
<view class="section-title">鍩烘湰淇℃伅</view>
@@ -10,10 +10,6 @@
<view class="info-item">
<text class="info-label">閿�鍞悎鍚屽彿</text>
<text class="info-value">{{ form.salesContractNo }}</text>
- </view>
- <view class="info-item">
- <text class="info-label">瀹㈡埛鍚堝悓鍙�</text>
- <text class="info-value highlight">{{ form.customerContractNo }}</text>
</view>
<view class="info-item">
<text class="info-label">瀹㈡埛鍚嶇О</text>
@@ -45,19 +41,22 @@
</view>
</view>
</view>
-
<!-- 浜у搧淇℃伅灞曠ず -->
- <view class="product-section" v-if="productData && productData.length > 0">
+ <view class="product-section"
+ v-if="productData && productData.length > 0">
<view class="section-title">浜у搧淇℃伅</view>
- <view class="product-card" v-for="(product, idx) in productData" :key="idx">
+ <view class="product-card"
+ v-for="(product, idx) in productData"
+ :key="idx">
<view class="product-header">
<view class="product-title">
<!-- 鏇挎崲 van-icon 涓� u-icon -->
- <u-icon name="file-text" color="#2979ff" size="15" />
+ <u-icon name="file-text"
+ color="#2979ff"
+ size="15" />
<text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
</view>
</view>
-
<view class="product-info">
<view class="info-grid">
<view class="info-item">
@@ -68,6 +67,10 @@
<text class="info-label">瑙勬牸鍨嬪彿</text>
<text class="info-value">{{ product.specificationModel }}</text>
</view>
+ <!-- <view class="info-item">
+ <text class="info-label">缁戝畾鏈哄櫒</text>
+ <text class="info-value">{{ product.speculativeTradingName }}</text>
+ </view> -->
<view class="info-item">
<text class="info-label">鍗曚綅</text>
<text class="info-value">{{ product.unit }}</text>
@@ -100,192 +103,191 @@
</view>
</view>
</view>
-
- <view v-else class="no-product">
+ <view v-else
+ class="no-product">
<text>鏆傛棤浜у搧淇℃伅</text>
</view>
</view>
</template>
<script setup>
-import {onMounted, ref} from 'vue';
-import {getSalesLedgerWithProducts} from "@/api/salesManagement/salesLedger";
-import PageHeader from '@/components/PageHeader.vue';
+ import { onMounted, ref } from "vue";
+ import { getSalesLedgerWithProducts } from "@/api/salesManagement/salesLedger";
+ import PageHeader from "@/components/PageHeader.vue";
-// 鑾峰彇椤甸潰鍙傛暟
-const editData = ref(null);
+ // 鑾峰彇椤甸潰鍙傛暟
+ const editData = ref(null);
-const form = ref({
- id: '',
- salesContractNo: '',
- customerContractNo: '',
- customerId: '',
- customerName: '',
- projectName: '',
- executionDate: '',
- paymentMethod: '',
- entryPerson: '',
- entryPersonName: '',
- entryDate: '',
- salesman: ''
-});
-
-// 浜у搧鏁版嵁
-const productData = ref([]);
-
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
- uni.removeStorageSync('editData');
- uni.navigateBack();
-};
-
-// 濉厖琛ㄥ崟鏁版嵁
-const fillFormData = () => {
- if (!editData.value) return;
-
- // 鑾峰彇瀹屾暣鐨勪骇鍝佷俊鎭�
- getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then((res) => {
- productData.value = res.productData || [];
- form.value = {...res}
+ const form = ref({
+ id: "",
+ salesContractNo: "",
+ customerId: "",
+ customerName: "",
+ projectName: "",
+ executionDate: "",
+ paymentMethod: "",
+ entryPerson: "",
+ entryPersonName: "",
+ entryDate: "",
+ salesman: "",
});
-};
-onMounted(() => {
- // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
- const editDataStr = uni.getStorageSync('editData');
- if (editDataStr) {
- try {
- editData.value = JSON.parse(editDataStr);
- // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
- setTimeout(() => {
- fillFormData();
- }, 100);
- } catch (error) {
- console.error('瑙f瀽缂栬緫鏁版嵁澶辫触:', error);
+ // 浜у搧鏁版嵁
+ const productData = ref([]);
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync("editData");
+ uni.navigateBack();
+ };
+
+ // 濉厖琛ㄥ崟鏁版嵁
+ const fillFormData = () => {
+ if (!editData.value) return;
+
+ // 鑾峰彇瀹屾暣鐨勪骇鍝佷俊鎭�
+ getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then(res => {
+ productData.value = res.productData || [];
+ form.value = { ...res };
+ });
+ };
+
+ onMounted(() => {
+ // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
+ const editDataStr = uni.getStorageSync("editData");
+ if (editDataStr) {
+ try {
+ editData.value = JSON.parse(editDataStr);
+ // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
+ setTimeout(() => {
+ fillFormData();
+ }, 100);
+ } catch (error) {
+ console.error("瑙f瀽缂栬緫鏁版嵁澶辫触:", error);
+ }
}
- }
-});
+ });
</script>
<style scoped lang="scss">
-.account-view {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 2rem;
-}
+ .account-view {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 2rem;
+ }
-.header {
- display: flex;
- align-items: center;
- background: #fff;
- padding: 1rem 1.25rem;
- border-bottom: 0.0625rem solid #f0f0f0;
- position: sticky;
- top: 0;
- z-index: 100;
-}
+ .header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 1rem 1.25rem;
+ border-bottom: 0.0625rem solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ }
-.title {
- flex: 1;
- text-align: center;
- font-size: 1.125rem;
- font-weight: 600;
- color: #333;
-}
+ .title {
+ flex: 1;
+ text-align: center;
+ font-size: 1.125rem;
+ font-weight: 600;
+ color: #333;
+ }
-.info-section {
- background: #fff;
- margin: 1rem;
- padding: 1rem;
- border-radius: 0.5rem;
- box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
-}
+ .info-section {
+ background: #fff;
+ margin: 1rem;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
+ }
-.product-section {
- background: #fff;
- margin: 1rem;
- padding: 1rem;
- border-radius: 0.5rem;
- box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
-}
+ .product-section {
+ background: #fff;
+ margin: 1rem;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
+ }
-.section-title {
- font-size: 1rem;
- font-weight: 600;
- color: #333;
- margin-bottom: 1rem;
- padding-bottom: 0.5rem;
- border-bottom: 0.0625rem solid #e8e8e8;
-}
+ .section-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 1rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 0.0625rem solid #e8e8e8;
+ }
-.info-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 0.75rem;
-}
+ .info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0.75rem;
+ }
-.info-item {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
-}
+ .info-item {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ }
-.info-label {
- font-size: 0.75rem;
- color: #666;
- font-weight: 400;
-}
+ .info-label {
+ font-size: 0.75rem;
+ color: #666;
+ font-weight: 400;
+ }
-.info-value {
- font-size: 0.875rem;
- color: #333;
- font-weight: 500;
-}
+ .info-value {
+ font-size: 0.875rem;
+ color: #333;
+ font-weight: 500;
+ }
-.info-value.highlight {
- color: #2979ff;
- font-weight: 600;
-}
+ .info-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+ }
-.product-card {
- background: #f8f9fa;
- border-radius: 0.5rem;
- padding: 1rem;
- margin-bottom: 1rem;
- border: 0.0625rem solid #e8e8e8;
-}
+ .product-card {
+ background: #f8f9fa;
+ border-radius: 0.5rem;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ border: 0.0625rem solid #e8e8e8;
+ }
-.product-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 1rem;
- padding-bottom: 0.5rem;
- border-bottom: 0.0625rem solid #e8e8e8;
-}
+ .product-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 1rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 0.0625rem solid #e8e8e8;
+ }
-.product-title {
- display: flex;
- align-items: center;
- gap: 0.5rem;
-}
+ .product-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ }
-.product-productCategory {
- font-size: 0.875rem;
- font-weight: 500;
- color: #333;
-}
+ .product-productCategory {
+ font-size: 0.875rem;
+ font-weight: 500;
+ color: #333;
+ }
-.product-info .info-grid {
- grid-template-columns: 1fr 1fr;
- gap: 0.5rem;
-}
+ .product-info .info-grid {
+ grid-template-columns: 1fr 1fr;
+ gap: 0.5rem;
+ }
-.no-product {
- text-align: center;
- padding: 2rem;
- color: #999;
- font-size: 0.875rem;
-}
+ .no-product {
+ text-align: center;
+ padding: 2rem;
+ color: #999;
+ font-size: 0.875rem;
+ }
</style>
diff --git a/src/static/images/icon/baojiaguanli.png b/src/static/images/icon/baojiaguanli.png
new file mode 100644
index 0000000..cbd4af9
--- /dev/null
+++ b/src/static/images/icon/baojiaguanli.png
Binary files differ
diff --git a/src/static/images/icon/baoxiaoguanli.png b/src/static/images/icon/baoxiaoguanli.png
new file mode 100644
index 0000000..9179dc7
--- /dev/null
+++ b/src/static/images/icon/baoxiaoguanli.png
Binary files differ
diff --git a/src/static/images/icon/caigouguanli.png b/src/static/images/icon/caigouguanli.png
new file mode 100644
index 0000000..ac26944
--- /dev/null
+++ b/src/static/images/icon/caigouguanli.png
Binary files differ
diff --git a/src/static/images/icon/chuchaiguanli@2x.png b/src/static/images/icon/chuchaiguanli@2x.png
new file mode 100644
index 0000000..ea94f73
--- /dev/null
+++ b/src/static/images/icon/chuchaiguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/chukuguanli@2x.png b/src/static/images/icon/chukuguanli@2x.png
new file mode 100644
index 0000000..6667410
--- /dev/null
+++ b/src/static/images/icon/chukuguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/gongchuguanli@2x.png b/src/static/images/icon/gongchuguanli@2x.png
new file mode 100644
index 0000000..a05a03e
--- /dev/null
+++ b/src/static/images/icon/gongchuguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/guizhangzhidu@2x.png b/src/static/images/icon/guizhangzhidu@2x.png
new file mode 100644
index 0000000..98d8541
--- /dev/null
+++ b/src/static/images/icon/guizhangzhidu@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyifabu@2x.png b/src/static/images/icon/huiyifabu@2x.png
new file mode 100644
index 0000000..daad258
--- /dev/null
+++ b/src/static/images/icon/huiyifabu@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyikanban@2x.png b/src/static/images/icon/huiyikanban@2x.png
new file mode 100644
index 0000000..5624414
--- /dev/null
+++ b/src/static/images/icon/huiyikanban@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyiliebiao@2x.png b/src/static/images/icon/huiyiliebiao@2x.png
new file mode 100644
index 0000000..78ee9f3
--- /dev/null
+++ b/src/static/images/icon/huiyiliebiao@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyishenpi@2x.png b/src/static/images/icon/huiyishenpi@2x.png
new file mode 100644
index 0000000..9de3a97
--- /dev/null
+++ b/src/static/images/icon/huiyishenpi@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyishenqing@2x.png b/src/static/images/icon/huiyishenqing@2x.png
new file mode 100644
index 0000000..31a3496
--- /dev/null
+++ b/src/static/images/icon/huiyishenqing@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyishezhi@2x.png b/src/static/images/icon/huiyishezhi@2x.png
new file mode 100644
index 0000000..bef3d2f
--- /dev/null
+++ b/src/static/images/icon/huiyishezhi@2x.png
Binary files differ
diff --git a/src/static/images/icon/huiyizongjie@2x.png b/src/static/images/icon/huiyizongjie@2x.png
new file mode 100644
index 0000000..743c84b
--- /dev/null
+++ b/src/static/images/icon/huiyizongjie@2x.png
Binary files differ
diff --git a/src/static/images/icon/qingjiaguanli@2x.png b/src/static/images/icon/qingjiaguanli@2x.png
new file mode 100644
index 0000000..4655a22
--- /dev/null
+++ b/src/static/images/icon/qingjiaguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/rukuguanli@2x.png b/src/static/images/icon/rukuguanli@2x.png
new file mode 100644
index 0000000..aa278da
--- /dev/null
+++ b/src/static/images/icon/rukuguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/tongzhigonggao@2x.png b/src/static/images/icon/tongzhigonggao@2x.png
new file mode 100644
index 0000000..f3df25b
--- /dev/null
+++ b/src/static/images/icon/tongzhigonggao@2x.png
Binary files differ
diff --git a/src/static/images/icon/yongyinguanli@2x.png b/src/static/images/icon/yongyinguanli@2x.png
new file mode 100644
index 0000000..e23111d
--- /dev/null
+++ b/src/static/images/icon/yongyinguanli@2x.png
Binary files differ
diff --git a/src/static/images/icon/zhishiku@2x.png b/src/static/images/icon/zhishiku@2x.png
new file mode 100644
index 0000000..27c5f5c
--- /dev/null
+++ b/src/static/images/icon/zhishiku@2x.png
Binary files differ
diff --git a/src/static/images/icon/zidingyichuku.png b/src/static/images/icon/zidingyichuku.png
new file mode 100644
index 0000000..cd0b7db
--- /dev/null
+++ b/src/static/images/icon/zidingyichuku.png
Binary files differ
diff --git a/src/static/images/index/caigoushuju.png b/src/static/images/index/caigoushuju.png
new file mode 100644
index 0000000..09961d5
--- /dev/null
+++ b/src/static/images/index/caigoushuju.png
Binary files differ
diff --git a/src/static/images/index/kucunshuju.png b/src/static/images/index/kucunshuju.png
new file mode 100644
index 0000000..40fa18b
--- /dev/null
+++ b/src/static/images/index/kucunshuju.png
Binary files differ
diff --git a/src/static/images/index/num1.png b/src/static/images/index/num1.png
new file mode 100644
index 0000000..6d912e7
--- /dev/null
+++ b/src/static/images/index/num1.png
Binary files differ
diff --git a/src/static/images/index/num2.png b/src/static/images/index/num2.png
new file mode 100644
index 0000000..e47cac2
--- /dev/null
+++ b/src/static/images/index/num2.png
Binary files differ
diff --git a/src/static/images/index/num3.png b/src/static/images/index/num3.png
new file mode 100644
index 0000000..a80da29
--- /dev/null
+++ b/src/static/images/index/num3.png
Binary files differ
diff --git a/src/static/images/index/xiaoshoushuju.png b/src/static/images/index/xiaoshoushuju.png
new file mode 100644
index 0000000..799b3b5
--- /dev/null
+++ b/src/static/images/index/xiaoshoushuju.png
Binary files differ
diff --git a/src/static/images/tabbar/home.png b/src/static/images/tabbar/home.png
index 50acdfd..b051264 100644
--- a/src/static/images/tabbar/home.png
+++ b/src/static/images/tabbar/home.png
Binary files differ
diff --git a/src/static/images/tabbar/homeBlue.png b/src/static/images/tabbar/homeBlue.png
new file mode 100644
index 0000000..5e93119
--- /dev/null
+++ b/src/static/images/tabbar/homeBlue.png
Binary files differ
diff --git a/src/static/images/tabbar/home_.png b/src/static/images/tabbar/home_.png
deleted file mode 100644
index a408f71..0000000
--- a/src/static/images/tabbar/home_.png
+++ /dev/null
Binary files differ
diff --git a/src/static/images/tabbar/mine.png b/src/static/images/tabbar/mine.png
deleted file mode 100644
index f13fe44..0000000
--- a/src/static/images/tabbar/mine.png
+++ /dev/null
Binary files differ
diff --git a/src/static/images/tabbar/mine_.png b/src/static/images/tabbar/mine_.png
deleted file mode 100644
index 8a0a742..0000000
--- a/src/static/images/tabbar/mine_.png
+++ /dev/null
Binary files differ
diff --git a/src/static/images/tabbar/my.png b/src/static/images/tabbar/my.png
new file mode 100644
index 0000000..f1d0053
--- /dev/null
+++ b/src/static/images/tabbar/my.png
Binary files differ
diff --git a/src/static/images/tabbar/myBlue.png b/src/static/images/tabbar/myBlue.png
new file mode 100644
index 0000000..3cd72fe
--- /dev/null
+++ b/src/static/images/tabbar/myBlue.png
Binary files differ
diff --git a/src/static/images/tabbar/new.png b/src/static/images/tabbar/new.png
new file mode 100644
index 0000000..0e9d139
--- /dev/null
+++ b/src/static/images/tabbar/new.png
Binary files differ
diff --git a/src/static/images/tabbar/newBlue.png b/src/static/images/tabbar/newBlue.png
new file mode 100644
index 0000000..25b1e44
--- /dev/null
+++ b/src/static/images/tabbar/newBlue.png
Binary files differ
diff --git a/src/static/images/tabbar/work.png b/src/static/images/tabbar/work.png
index 21e130d..d143451 100644
--- a/src/static/images/tabbar/work.png
+++ b/src/static/images/tabbar/work.png
Binary files differ
diff --git a/src/static/images/tabbar/workBlue.png b/src/static/images/tabbar/workBlue.png
new file mode 100644
index 0000000..77d7a29
--- /dev/null
+++ b/src/static/images/tabbar/workBlue.png
Binary files differ
diff --git a/src/static/images/tabbar/work_.png b/src/static/images/tabbar/work_.png
deleted file mode 100644
index 80b979c..0000000
--- a/src/static/images/tabbar/work_.png
+++ /dev/null
Binary files differ
--
Gitblit v1.9.3